| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| example.js | 100% | (83 / 83) | 100% | (73 / 73) | 100% | (12 / 12) | 100% | (83 / 83) | |
| lib.npmtest_weex_devtool.js | 100% | (16 / 16) | 100% | (14 / 14) | 100% | (3 / 3) | 100% | (16 / 16) | |
| test.js | 100% | (54 / 54) | 100% | (39 / 39) | 100% | (13 / 13) | 100% | (54 / 54) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 1 2 1 1 1 1 1 1 1 1 1 2 1 1 1 1 2 2 3 3 3 3 1 3 3 3 1 3 1 1 1 1 1 1 1 1 1 1 1 1 6 6 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
example.js
quickstart example
instruction
1. save this script as example.js
2. run the shell command:
$ npm install npmtest-weex-devtool && PORT=8081 node example.js
3. play with the browser-demo on http://127.0.0.1:8081
*/
/* istanbul instrument in package npmtest_weex_devtool */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - init-before
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
// init utility2_rollup
local = local.global.utility2_rollup || (local.modeJs === 'browser'
? local.global.utility2_npmtest_weex_devtool
: global.utility2_moduleExports);
// export local
local.global.local = local;
}());
switch (local.modeJs) {
// init-after
// run browser js-env code - init-after
/* istanbul ignore next */
case 'browser':
local.testRunBrowser = function (event) {
Eif (!event || (event &&
event.currentTarget &&
event.currentTarget.className &&
event.currentTarget.className.includes &&
event.currentTarget.className.includes('onreset'))) {
// reset output
Array.from(
document.querySelectorAll('body > .resettable')
).forEach(function (element) {
switch (element.tagName) {
case 'INPUT':
case 'TEXTAREA':
element.value = '';
break;
default:
element.textContent = '';
}
});
}
switch (event && event.currentTarget && event.currentTarget.id) {
case 'testRunButton1':
// show tests
Eif (document.querySelector('#testReportDiv1').style.display === 'none') {
document.querySelector('#testReportDiv1').style.display = 'block';
document.querySelector('#testRunButton1').textContent =
'hide internal test';
local.modeTest = true;
local.testRunDefault(local);
// hide tests
} else {
document.querySelector('#testReportDiv1').style.display = 'none';
document.querySelector('#testRunButton1').textContent = 'run internal test';
}
break;
// custom-case
default:
break;
}
Iif (document.querySelector('#inputTextareaEval1') && (!event || (event &&
event.currentTarget &&
event.currentTarget.className &&
event.currentTarget.className.includes &&
event.currentTarget.className.includes('oneval')))) {
// try to eval input-code
try {
/*jslint evil: true*/
eval(document.querySelector('#inputTextareaEval1').value);
} catch (errorCaught) {
console.error(errorCaught);
}
}
};
// log stderr and stdout to #outputTextareaStdout1
['error', 'log'].forEach(function (key) {
console[key + '_original'] = console[key];
console[key] = function () {
var element;
console[key + '_original'].apply(console, arguments);
element = document.querySelector('#outputTextareaStdout1');
Iif (!element) {
return;
}
// append text to #outputTextareaStdout1
element.value += Array.from(arguments).map(function (arg) {
return typeof arg === 'string'
? arg
: JSON.stringify(arg, null, 4);
}).join(' ') + '\n';
// scroll textarea to bottom
element.scrollTop = element.scrollHeight;
};
});
// init event-handling
['change', 'click', 'keyup'].forEach(function (event) {
Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {
element.addEventListener(event, local.testRunBrowser);
});
});
// run tests
local.testRunBrowser();
break;
// run node js-env code - init-after
/* istanbul ignore next */
case 'node':
// export local
module.exports = local;
// require modules
local.fs = require('fs');
local.http = require('http');
local.url = require('url');
// init assets
local.assetsDict = local.assetsDict || {};
/* jslint-ignore-begin */
local.assetsDict['/assets.index.template.html'] = '\
<!doctype html>\n\
<html lang="en">\n\
<head>\n\
<meta charset="UTF-8">\n\
<meta name="viewport" content="width=device-width, initial-scale=1">\n\
<title>{{env.npm_package_name}} (v{{env.npm_package_version}})</title>\n\
<style>\n\
/*csslint\n\
box-sizing: false,\n\
universal-selector: false\n\
*/\n\
* {\n\
box-sizing: border-box;\n\
}\n\
body {\n\
background: #dde;\n\
font-family: Arial, Helvetica, sans-serif;\n\
margin: 2rem;\n\
}\n\
body > * {\n\
margin-bottom: 1rem;\n\
}\n\
.utility2FooterDiv {\n\
margin-top: 20px;\n\
text-align: center;\n\
}\n\
</style>\n\
<style>\n\
/*csslint\n\
*/\n\
textarea {\n\
font-family: monospace;\n\
height: 10rem;\n\
width: 100%;\n\
}\n\
textarea[readonly] {\n\
background: #ddd;\n\
}\n\
</style>\n\
</head>\n\
<body>\n\
<!-- utility2-comment\n\
<div id="ajaxProgressDiv1" style="background: #d00; height: 2px; left: 0; margin: 0; padding: 0; position: fixed; top: 0; transition: background 0.5s, width 1.5s; width: 25%;"></div>\n\
utility2-comment -->\n\
<h1>\n\
<!-- utility2-comment\n\
<a\n\
{{#if env.npm_package_homepage}}\n\
href="{{env.npm_package_homepage}}"\n\
{{/if env.npm_package_homepage}}\n\
target="_blank"\n\
>\n\
utility2-comment -->\n\
{{env.npm_package_name}} (v{{env.npm_package_version}})\n\
<!-- utility2-comment\n\
</a>\n\
utility2-comment -->\n\
</h1>\n\
<h3>{{env.npm_package_description}}</h3>\n\
<!-- utility2-comment\n\
<h4><a download href="assets.app.js">download standalone app</a></h4>\n\
<button class="onclick onreset" id="testRunButton1">run internal test</button><br>\n\
<div id="testReportDiv1" style="display: none;"></div>\n\
utility2-comment -->\n\
\n\
\n\
\n\
<label>stderr and stdout</label>\n\
<textarea class="resettable" id="outputTextareaStdout1" readonly></textarea>\n\
<!-- utility2-comment\n\
{{#if isRollup}}\n\
<script src="assets.app.js"></script>\n\
{{#unless isRollup}}\n\
utility2-comment -->\n\
<script src="assets.utility2.rollup.js"></script>\n\
<script src="jsonp.utility2._stateInit?callback=window.utility2._stateInit"></script>\n\
<script src="assets.npmtest_weex_devtool.rollup.js"></script>\n\
<script src="assets.example.js"></script>\n\
<script src="assets.test.js"></script>\n\
<!-- utility2-comment\n\
{{/if isRollup}}\n\
utility2-comment -->\n\
<div class="utility2FooterDiv">\n\
[ this app was created with\n\
<a href="https://github.com/kaizhu256/node-utility2" target="_blank">utility2</a>\n\
]\n\
</div>\n\
</body>\n\
</html>\n\
';
/* jslint-ignore-end */
Iif (local.templateRender) {
local.assetsDict['/'] = local.templateRender(
local.assetsDict['/assets.index.template.html'],
{
env: local.objectSetDefault(local.env, {
npm_package_description: 'the greatest app in the world!',
npm_package_name: 'my-app',
npm_package_nameAlias: 'my_app',
npm_package_version: '0.0.1'
})
}
);
} else {
local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']
.replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) {
// jslint-hack
String(match0);
switch (match1) {
case 'npm_package_description':
return 'the greatest app in the world!';
case 'npm_package_name':
return 'my-app';
case 'npm_package_nameAlias':
return 'my_app';
case 'npm_package_version':
return '0.0.1';
}
});
}
// run the cli
Eif (local.global.utility2_rollup || module !== require.main) {
break;
}
local.assetsDict['/assets.example.js'] =
local.assetsDict['/assets.example.js'] ||
local.fs.readFileSync(__filename, 'utf8');
// bug-workaround - long $npm_package_buildCustomOrg
/* jslint-ignore-begin */
local.assetsDict['/assets.npmtest_weex_devtool.rollup.js'] =
local.assetsDict['/assets.npmtest_weex_devtool.rollup.js'] ||
local.fs.readFileSync(
local.npmtest_weex_devtool.__dirname + '/lib.npmtest_weex_devtool.js',
'utf8'
).replace((/^#!/), '//');
/* jslint-ignore-end */
local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';
// if $npm_config_timeout_exit exists,
// then exit this process after $npm_config_timeout_exit ms
if (Number(process.env.npm_config_timeout_exit)) {
setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));
}
// start server
if (local.global.utility2_serverHttp1) {
break;
}
process.env.PORT = process.env.PORT || '8081';
console.error('server starting on port ' + process.env.PORT);
local.http.createServer(function (request, response) {
request.urlParsed = local.url.parse(request.url);
if (local.assetsDict[request.urlParsed.pathname] !== undefined) {
response.end(local.assetsDict[request.urlParsed.pathname]);
return;
}
response.statusCode = 404;
response.end();
}).listen(process.env.PORT);
break;
}
}());
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 2 2 2 2 2 2 2 1 2 2 2 2 1 1 1 1 | /* istanbul instrument in package npmtest_weex_devtool */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - init-before
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
// init utility2_rollup
local = local.global.utility2_rollup || local;
// init lib
local.local = local.npmtest_weex_devtool = local;
// init exports
if (local.modeJs === 'browser') {
local.global.utility2_npmtest_weex_devtool = local;
} else {
module.exports = local;
module.exports.__dirname = __dirname;
module.exports.module = module;
}
}());
}());
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | 2 2 2 2 2 2 2 1 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 1 2 2 1 1 1 1 1 | /* istanbul instrument in package npmtest_weex_devtool */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - init-before
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
switch (local.modeJs) {
// re-init local from window.local
case 'browser':
local = local.global.utility2.objectSetDefault(
local.global.utility2_rollup || local.global.local,
local.global.utility2
);
break;
// re-init local from example.js
case 'node':
local = (local.global.utility2_rollup || require('utility2'))
.requireReadme();
break;
}
// export local
local.global.local = local;
}());
// run shared js-env code - function
(function () {
return;
}());
switch (local.modeJs) {
// run browser js-env code - function
case 'browser':
break;
// run node js-env code - function
case 'node':
break;
}
// run shared js-env code - init-after
(function () {
return;
}());
switch (local.modeJs) {
// run browser js-env code - init-after
case 'browser':
local.testCase_browser_nullCase = local.testCase_browser_nullCase || function (
options,
onError
) {
/*
* this function will test browsers's null-case handling-behavior-behavior
*/
onError(null, options);
};
// run tests
local.nop(local.modeTest &&
document.querySelector('#testRunButton1') &&
document.querySelector('#testRunButton1').click());
break;
// run node js-env code - init-after
/* istanbul ignore next */
case 'node':
local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function (
options,
onError
) {
/*
* this function will test buildApidoc's default handling-behavior-behavior
*/
options = { modulePathList: module.paths };
local.buildApidoc(options, onError);
};
local.testCase_buildApp_default = local.testCase_buildApp_default || function (
options,
onError
) {
/*
* this function will test buildApp's default handling-behavior-behavior
*/
local.testCase_buildReadme_default(options, local.onErrorThrow);
local.testCase_buildLib_default(options, local.onErrorThrow);
local.testCase_buildTest_default(options, local.onErrorThrow);
local.testCase_buildCustomOrg_default(options, local.onErrorThrow);
options = [];
local.buildApp(options, onError);
};
local.testCase_buildCustomOrg_default = local.testCase_buildCustomOrg_default ||
function (options, onError) {
/*
* this function will test buildCustomOrg's default handling-behavior
*/
options = {};
local.buildCustomOrg(options, onError);
};
local.testCase_buildLib_default = local.testCase_buildLib_default || function (
options,
onError
) {
/*
* this function will test buildLib's default handling-behavior
*/
options = {};
local.buildLib(options, onError);
};
local.testCase_buildReadme_default = local.testCase_buildReadme_default || function (
options,
onError
) {
/*
* this function will test buildReadme's default handling-behavior-behavior
*/
options = {};
local.buildReadme(options, onError);
};
local.testCase_buildTest_default = local.testCase_buildTest_default || function (
options,
onError
) {
/*
* this function will test buildTest's default handling-behavior
*/
options = {};
local.buildTest(options, onError);
};
local.testCase_webpage_default = local.testCase_webpage_default || function (
options,
onError
) {
/*
* this function will test webpage's default handling-behavior
*/
options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };
local.browserTest(options, onError);
};
// run test-server
local.testRunServer(local);
break;
}
}());
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 35.29% | (12 / 34) | 0% | (0 / 14) | 50% | (1 / 2) | 35.29% | (12 / 34) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 1 1 1 1 1 1 1 1 1 1 1 1 | var Fs = require('fs');
var Path = require('path');
var IP = require('ip');
var fileList = Fs.readdirSync(Path.join(__dirname, './bin'));
var map = module.exports;
fileList.forEach(function (file) {
map[Path.basename(file, '.js')] = Path.join(__dirname, './bin', file);
});
var api = map['api'] = {};
var Config = require('./lib/components/Config');
var LogStyle = require('./common/LogStyle');
var DebugServer = require('./lib/DebugServer');
api.startServerAndLaunchDevtool = function startServerAndLaunchDevtool(entry, root, port, cb){
port = port || 8088; //Program.port;
var ip = IP.address();
Config.ip = ip;
Config.local=true;
console.info('start debugger server at ' + LogStyle.dressUp('http://' + ip + ':' + port, LogStyle.FG_YELLOW, LogStyle.BRIGHT));
if (entry) {
Config.entryBundleUrl = 'http://' + ip + ':' + port + Path.join('/' + Config.bundleDir, Path.basename(entry).replace(/\.we$/, '.js')).replace(/\\/g,'/');
console.log('\nYou can visit we file(s) use ' + Config.entryBundleUrl);
console.log('Also you can use Playground App to scan the qrcode on device list page.');
}
if (Config.entryBundleUrl) {
Config.entryBundleUrl = Config.entryBundleUrl.replace(/127\.0\.0\.1/g, Config.ip);
//fixme ugly 与具体耦合的逻辑 易变!
var urlObj = Url.parse(Config.entryBundleUrl, true);
if (!/wh_weex=true/.test(Config.entryBundleUrl)&&!urlObj.query['_wx_tpl']) {
urlObj.query['_wx_tpl'] = Config.entryBundleUrl;
urlObj.search = '';
Config.entryBundleUrl = Url.format(urlObj);
}
}
if(root) {
Config.root = root;
}
if (Config.root) {
console.log('\nDirectory[' + Program.file + '] has been mapped to http://' + ip + ':' + port + '/' + Config.bundleDir + '/');
}
console.info('\nThe websocket address for native is ' + LogStyle.dressUp('ws://' + ip + ':' + port + '/debugProxy/native', LogStyle.FG_YELLOW, LogStyle.BRIGHT));
DebugServer.start(port, cb);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| weex-devtool.js | 44.95% | (49 / 109) | 26.09% | (12 / 46) | 10% | (1 / 10) | 44.95% | (49 / 109) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | //#!/usr/bin/env node
/**
* 关于代码规范
* 所有模块、类库 引入后使用首字母大写的驼峰形式,
* 本地变量与函数使用首字母小写的驼峰形式
* module内的闭包变量(相当于module 作用域内的全局变量)如果用于储存信息,由于容易产生泄露,所以必须使用_开头的驼峰形式用于区分
* 像下面代码中的packageInfo由于是只读的所以不需要加_
*/
"use strict";
var Program = require('commander');
var DebugServer = require('../lib/DebugServer');
var Config = require('../lib/components/Config');
var Builder = require('../lib/components/Builder');
var LogStyle = require('../common/LogStyle');
var Url = require('url');
var Fs = require('fs');
var Exit = require('exit');
var Path = require('path');
var IP = require('ip');
var LaunchDevTool = require('../lib/util/LaunchDevTool');
var Del = require('del');
var Watch = require('node-watch');
var MessageBus = require('../lib/components/MessageBus');
var Hosts = require('../lib/util/Hosts');
var UpgradeNotice = require('../lib/util/UpgradeNotice');
var packageInfo = require('../package.json');
Program
.option('-h, --host [host]', 'set the host ip of debugger server')
.option('-H, --help', 'display help')
.option('-V, --verbose', 'display logs of debugger server')
.option('-v, --version', 'display version')
.option('-p, --port [port]', 'set debugger server port', '8088')
.option('-e, --entry [entry]', 'set the entry bundlejs path when you specific the bundle server root path')
.option('-w, --watch', 'watch we file changes auto build them and refresh debugger page![default enabled]', true)
.option('-m, --mode [mode]', 'set build mode [transformer|loader]', 'loader')
.option('-M, --manual', 'manual mode,this mode will not auto open chrome')
.option('--min', '')
.option('-l, --local', '');
//支持命令后跟一个file/directory参数
Program['arguments']('[file]')
.action(function (file) {
Program.file = file;
});
Program.parse(process.argv);
//默认watch功能开启
Program.watch = true;
//fix tj's commander bug overwrite --help
Iif (Program.help == undefined) {
Program.outputHelp();
Exit(0);
}
//fix tj's commander bug overwrite --version
Iif (Program.version == undefined) {
console.log(packageInfo.version);
Exit(0);
}
var supportMode = ['loader', 'transformer'];
Iif (Program.host && !Hosts.isValidLocalHost(Program.host)) {
console.log('[' + Program.host + '] is not your local address!');
Exit(0);
}
Config.verbose = Program.verbose;
Config.port = Program.port;
Config.local = Program.local;
Config.min = Program.min;
Iif (supportMode.indexOf(Program.mode) == -1) {
console.log('unsupported build mode:', Program.mode);
Exit(0);
}
else {
Config.buildMode = Program.mode;
}
//清空
try {
Del.sync(Path.join(__dirname, '../frontend/', Config.bundleDir, '/*'), {force: true});
} catch (e) {
}
Iif (Program.file) {
buildAndStart()
}
else {
startServerAndLaunchDevtool()
}
////////////////////////////////////////////////////////////////////////////
function buildAndStart() {
if (/^https?:\/\//.test(Program.file)) {
var url = Program.file.replace(/^(https?:\/\/)([^/:]+)(?=:\d+|\/)/, function (m, a, b) {
if (!/\d+\.\d+\.\d+\.\d+/.test(a)) {
return a + Hosts.findRealHost(b);
}
else {
return m;
}
});
Config.entryBundleUrl = url;
startServerAndLaunchDevtool();
}
else {
var filePath = Path.resolve(Program.file);
var ext = Path.extname(filePath);
if (!Fs.existsSync(filePath)) {
console.error(filePath + ': No such file or directory');
return Exit(0);
}
if (ext == '.we' || ext == '.vue') {
console.log('building...');
console.time('Build completed!');
buildFileAndWatchIt(Program.mode, filePath).then(function () {
console.timeEnd('Build completed!');
startServerAndLaunchDevtool(Program.file);
}, function (err) {
if (err) {
console.log(err, err.stack);
}
Exit(0);
})
}
else if (ext == '.js') {
buildFileAndWatchIt('copy', filePath).then(function () {
startServerAndLaunchDevtool(Program.file);
})
}
else if (!ext) {
//处理目录
if (Fs.statSync(filePath).isDirectory()) {
Config.root = filePath;
startServerAndLaunchDevtool(Program.entry)
}
else {
console.error(Program.file + ' is not a directory!');
Exit(0);
}
}
else {
console.error('Error:unsupported file type: ', ext);
return Exit(0);
}
}
}
function buildFileAndWatchIt(buildMode, filePath) {
if (Program.watch) {
Watch(filePath, function () {
console.time('Rebuild completed! ')
console.log(filePath + ' updated! rebuilding...')
Builder[buildMode](filePath).then(function () {
console.timeEnd('Rebuild completed! ')
MessageBus.emit('page.refresh');
});
})
}
return Builder[buildMode](filePath);
}
function startServerAndLaunchDevtool(entry) {
var port = Program.port;
var ip = Program.host || IP.address();
Config.ip = ip;
console.info('start debugger server at ' + LogStyle.dressUp('http://' + ip + ':' + port, LogStyle.FG_YELLOW, LogStyle.BRIGHT));
Iif (entry) {
Config.entryBundleUrl = 'http://' + ip + ':' + port + Path.join('/' + Config.bundleDir, Path.basename(entry).replace(/\.(we|vue)$/, '.js')).replace(/\\/g, '/');
console.log('\nYou can visit we file(s) use ' + Config.entryBundleUrl);
console.log('Also you can use Playground App to scan the qrcode on device list page.');
}
Iif (Config.entryBundleUrl) {
Config.entryBundleUrl = Config.entryBundleUrl.replace(/127\.0\.0\.1/g, Config.ip);
//fixme ugly 与具体耦合的逻辑 易变!
var urlObj = Url.parse(Config.entryBundleUrl, true);
if (!/wh_weex=true/.test(Config.entryBundleUrl) && !urlObj.query['_wx_tpl']) {
urlObj.query['_wx_tpl'] = Config.entryBundleUrl;
urlObj.search = '';
Config.entryBundleUrl = Url.format(urlObj);
}
}
Iif (Config.root) {
console.log('\nDirectory[' + Program.file + '] has been mapped to http://' + ip + ':' + port + '/' + Config.bundleDir + '/');
}
console.info('\nThe websocket address for native is ' + LogStyle.dressUp('ws://' + ip + ':' + port + '/debugProxy/native', LogStyle.FG_YELLOW, LogStyle.BRIGHT));
DebugServer.start(port);
Eif (!Program.manual) {
LaunchDevTool(ip, port);
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| LogStyle.js | 100% | (2 / 2) | 100% | (0 / 0) | 100% | (1 / 1) | 100% | (2 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 1 2 | module.exports = {
LEVEL_COLOR: {
"error": "\033[31;1;49m",
"debug": "\033[36;49m",
"log": "\033[32;49m",
"warn": "\033[33;49m",
"#underline": "\033[2;4m",
"#end": "\033[0m"
},
dressUp: function (text) {
return '\033[' + Array.prototype.slice.call(arguments, 1).join(';') + 'm' + text + '\033[0m';
},
BRIGHT: 1,
DARK: 2,
UNDERLINE: 4,
REVERSE: 7,
FG_BLACK: 30,
FG_RED: 31,
FG_GREEN: 32,
FG_YELLOW: 33,
FG_BLUE: 34,
FG_PURPLE: 35,
FG_CYAN: 36,
FG_WHITE: 37,
BG_BLACK: 40,
BG_RED: 41,
BG_GREEN: 42,
BG_YELLOW: 43,
BG_BLUE: 44,
BG_PURPLE: 45,
BG_CYAN: 46,
BG_WHITE: 47
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Runtime.js | 6.52% | (26 / 399) | 0% | (0 / 186) | 1.27% | (1 / 79) | 6.52% | (26 / 399) | |
| SupportedCSSProperties.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| devtools.js | 7.33% | (14 / 191) | 0% | (0 / 41) | 0% | (0 / 109) | 7.37% | (14 / 190) | |
| externs.js | 12.3% | (15 / 122) | 100% | (0 / 0) | 0% | (0 / 174) | 12.3% | (15 / 122) | |
| heap_snapshot_worker.js | 33.33% | (1 / 3) | 0% | (0 / 2) | 100% | (0 / 0) | 33.33% | (1 / 3) | |
| inspector.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| toolbox.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | 2 2 2 2 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This gets all concatenated module descriptors in the release mode.
var allDescriptors = [];
var applicationDescriptor;
var _loadedScripts = {};
// FIXME: This is a workaround to force Closure compiler provide
// the standard ES6 runtime for all modules. This should be removed
// once Closure provides standard externs for Map et al.
for (var k of []) {};
/**
* @param {string} url
* @return {!Promise.<string>}
*/
function loadResourcePromise(url)
{
return new Promise(load);
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
*/
function load(fulfill, reject)
{
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = onreadystatechange;
/**
* @param {Event} e
*/
function onreadystatechange(e)
{
if (xhr.readyState !== 4)
return;
if ([0, 200, 304].indexOf(xhr.status) === -1) // Testing harness file:/// results in 0.
reject(new Error("While loading from url " + url + " server responded with a status of " + xhr.status));
else
fulfill(e.target.response);
}
xhr.send(null);
}
}
/**
* http://tools.ietf.org/html/rfc3986#section-5.2.4
* @param {string} path
* @return {string}
*/
function normalizePath(path)
{
if (path.indexOf("..") === -1 && path.indexOf('.') === -1)
return path;
var normalizedSegments = [];
var segments = path.split("/");
for (var i = 0; i < segments.length; i++) {
var segment = segments[i];
if (segment === ".")
continue;
else if (segment === "..")
normalizedSegments.pop();
else if (segment)
normalizedSegments.push(segment);
}
var normalizedPath = normalizedSegments.join("/");
if (normalizedPath[normalizedPath.length - 1] === "/")
return normalizedPath;
if (path[0] === "/" && normalizedPath)
normalizedPath = "/" + normalizedPath;
if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ".") || (segments[segments.length - 1] === ".."))
normalizedPath = normalizedPath + "/";
return normalizedPath;
}
/**
* @param {!Array.<string>} scriptNames
* @param {string=} base
* @return {!Promise.<undefined>}
*/
function loadScriptsPromise(scriptNames, base)
{
/** @type {!Array<!Promise<undefined>>} */
var promises = [];
/** @type {!Array<string>} */
var urls = [];
var sources = new Array(scriptNames.length);
var scriptToEval = 0;
for (var i = 0; i < scriptNames.length; ++i) {
var scriptName = scriptNames[i];
var sourceURL = (base || self._importScriptPathPrefix) + scriptName;
var schemaIndex = sourceURL.indexOf("://") + 3;
sourceURL = sourceURL.substring(0, schemaIndex) + normalizePath(sourceURL.substring(schemaIndex));
if (_loadedScripts[sourceURL])
continue;
urls.push(sourceURL);
promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null, i), scriptSourceLoaded.bind(null, i, undefined)));
}
return Promise.all(promises).then(undefined);
/**
* @param {number} scriptNumber
* @param {string=} scriptSource
*/
function scriptSourceLoaded(scriptNumber, scriptSource)
{
sources[scriptNumber] = scriptSource || "";
// Eval scripts as fast as possible.
while (typeof sources[scriptToEval] !== "undefined") {
evaluateScript(urls[scriptToEval], sources[scriptToEval]);
++scriptToEval;
}
}
/**
* @param {string} sourceURL
* @param {string=} scriptSource
*/
function evaluateScript(sourceURL, scriptSource)
{
_loadedScripts[sourceURL] = true;
if (!scriptSource) {
// Do not reject, as this is normal in the hosted mode.
console.error("Empty response arrived for script '" + sourceURL + "'");
return;
}
self.eval(scriptSource + "\n//# sourceURL=" + sourceURL);
}
}
(function() {
var baseUrl = self.location ? self.location.origin + self.location.pathname : "";
self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1);
})();
/**
* @constructor
* @param {!Array.<!Runtime.ModuleDescriptor>} descriptors
* @param {!Array.<string>=} coreModuleNames
*/
function Runtime(descriptors, coreModuleNames)
{
/**
* @type {!Array.<!Runtime.Module>}
*/
this._modules = [];
/**
* @type {!Object.<string, !Runtime.Module>}
*/
this._modulesMap = {};
/**
* @type {!Array.<!Runtime.Extension>}
*/
this._extensions = [];
/**
* @type {!Object.<string, !function(new:Object)>}
*/
this._cachedTypeClasses = {};
/**
* @type {!Object.<string, !Runtime.ModuleDescriptor>}
*/
this._descriptorsMap = {};
for (var i = 0; i < descriptors.length; ++i)
this._registerModule(descriptors[i]);
if (coreModuleNames)
this._loadAutoStartModules(coreModuleNames);
}
/**
* @type {!Object.<string, string>}
*/
Runtime._queryParamsObject = { __proto__: null };
/**
* @type {!Object.<string, string>}
*/
Runtime.cachedResources = { __proto__: null };
/**
* @return {boolean}
*/
Runtime.isReleaseMode = function()
{
return !!allDescriptors.length;
}
/**
* @param {string} appName
*/
Runtime.startApplication = function(appName)
{
console.timeStamp("Runtime.startApplication");
var allDescriptorsByName = {};
for (var i = 0; Runtime.isReleaseMode() && i < allDescriptors.length; ++i) {
var d = allDescriptors[i];
allDescriptorsByName[d["name"]] = d;
}
var applicationPromise;
if (applicationDescriptor)
applicationPromise = Promise.resolve(applicationDescriptor);
else
applicationPromise = loadResourcePromise(appName + ".json").then(JSON.parse.bind(JSON));
applicationPromise.then(parseModuleDescriptors);
/**
* @param {!Array.<!Object>} configuration
*/
function parseModuleDescriptors(configuration)
{
var moduleJSONPromises = [];
var coreModuleNames = [];
for (var i = 0; i < configuration.length; ++i) {
var descriptor = configuration[i];
if (descriptor["type"] === "worker")
continue;
var name = descriptor["name"];
var moduleJSON = allDescriptorsByName[name];
if (moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));
else
moduleJSONPromises.push(loadResourcePromise(name + "/module.json").then(JSON.parse.bind(JSON)));
if (descriptor["type"] === "autostart")
coreModuleNames.push(name);
}
Promise.all(moduleJSONPromises).then(instantiateRuntime);
/**
* @param {!Array.<!Object>} moduleDescriptors
*/
function instantiateRuntime(moduleDescriptors)
{
for (var i = 0; !Runtime.isReleaseMode() && i < moduleDescriptors.length; ++i) {
moduleDescriptors[i]["name"] = configuration[i]["name"];
moduleDescriptors[i]["condition"] = configuration[i]["condition"];
}
self.runtime = new Runtime(moduleDescriptors, coreModuleNames);
}
}
}
/**
* @param {string} name
* @return {?string}
*/
Runtime.queryParam = function(name)
{
return Runtime._queryParamsObject[name] || null;
}
/**
* @param {!Array.<string>} banned
* @return {string}
*/
Runtime.constructQueryParams = function(banned)
{
var params = [];
for (var key in Runtime._queryParamsObject) {
if (!key || banned.indexOf(key) !== -1)
continue;
params.push(key + "=" + Runtime._queryParamsObject[key]);
}
return params.length ? "?" + params.join("&") : "";
}
/**
* @return {!Object}
*/
Runtime._experimentsSetting = function()
{
try {
return /** @type {!Object} */ (JSON.parse(self.localStorage && self.localStorage["experiments"] ? self.localStorage["experiments"] : "{}"));
} catch (e) {
console.error("Failed to parse localStorage['experiments']");
return {};
}
}
/**
* @param {!Array.<!Promise.<T, !Error>>} promises
* @return {!Promise.<!Array.<T>>}
* @template T
*/
Runtime._some = function(promises)
{
var all = [];
var wasRejected = [];
for (var i = 0; i < promises.length; ++i) {
// Workaround closure compiler bug.
var handlerFunction = /** @type {function()} */ (handler.bind(promises[i], i));
all.push(promises[i].catch(handlerFunction));
}
return Promise.all(all).then(filterOutFailuresResults);
/**
* @param {!Array.<T>} results
* @return {!Array.<T>}
* @template T
*/
function filterOutFailuresResults(results)
{
var filtered = [];
for (var i = 0; i < results.length; ++i) {
if (!wasRejected[i])
filtered.push(results[i]);
}
return filtered;
}
/**
* @this {!Promise}
* @param {number} index
* @param {!Error} e
*/
function handler(index, e)
{
wasRejected[index] = true;
console.error(e.stack);
}
}
Runtime._console = console;
Runtime._originalAssert = console.assert;
Runtime._assert = function(value, message)
{
if (value)
return;
Runtime._originalAssert.call(Runtime._console, value, message + " " + new Error().stack);
}
Runtime.prototype = {
useTestBase: function()
{
Runtime._remoteBase = "http://localhost:8000/inspector-sources/";
},
/**
* @param {!Runtime.ModuleDescriptor} descriptor
*/
_registerModule: function(descriptor)
{
var module = new Runtime.Module(this, descriptor);
this._modules.push(module);
this._modulesMap[descriptor["name"]] = module;
},
/**
* @param {string} moduleName
* @return {!Promise.<undefined>}
*/
loadModulePromise: function(moduleName)
{
return this._modulesMap[moduleName]._loadPromise();
},
/**
* @param {!Array.<string>} moduleNames
* @return {!Promise.<!Array.<*>>}
*/
_loadAutoStartModules: function(moduleNames)
{
var promises = [];
for (var i = 0; i < moduleNames.length; ++i) {
if (Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded = true;
else
promises.push(this.loadModulePromise(moduleNames[i]));
}
return Promise.all(promises);
},
/**
* @param {!Runtime.Extension} extension
* @param {?function(function(new:Object)):boolean} predicate
* @return {boolean}
*/
_checkExtensionApplicability: function(extension, predicate)
{
if (!predicate)
return false;
var contextTypes = /** @type {!Array.<string>|undefined} */ (extension.descriptor().contextTypes);
if (!contextTypes)
return true;
for (var i = 0; i < contextTypes.length; ++i) {
var contextType = this._resolve(contextTypes[i]);
var isMatching = !!contextType && predicate(contextType);
if (isMatching)
return true;
}
return false;
},
/**
* @param {!Runtime.Extension} extension
* @param {?Object} context
* @return {boolean}
*/
isExtensionApplicableToContext: function(extension, context)
{
if (!context)
return true;
return this._checkExtensionApplicability(extension, isInstanceOf);
/**
* @param {!Function} targetType
* @return {boolean}
*/
function isInstanceOf(targetType)
{
return context instanceof targetType;
}
},
/**
* @param {!Runtime.Extension} extension
* @param {!Set.<!Function>=} currentContextTypes
* @return {boolean}
*/
isExtensionApplicableToContextTypes: function(extension, currentContextTypes)
{
if (!extension.descriptor().contextTypes)
return true;
return this._checkExtensionApplicability(extension, currentContextTypes ? isContextTypeKnown : null);
/**
* @param {!Function} targetType
* @return {boolean}
*/
function isContextTypeKnown(targetType)
{
return currentContextTypes.has(targetType);
}
},
/**
* @param {*} type
* @param {?Object=} context
* @return {!Array.<!Runtime.Extension>}
*/
extensions: function(type, context)
{
return this._extensions.filter(filter).sort(orderComparator);
/**
* @param {!Runtime.Extension} extension
* @return {boolean}
*/
function filter(extension)
{
if (extension._type !== type && extension._typeClass() !== type)
return false;
if (!extension.enabled())
return false;
return !context || extension.isApplicable(context);
}
/**
* @param {!Runtime.Extension} extension1
* @param {!Runtime.Extension} extension2
* @return {number}
*/
function orderComparator(extension1, extension2)
{
var order1 = extension1.descriptor()["order"] || 0;
var order2 = extension2.descriptor()["order"] || 0;
return order1 - order2;
}
},
/**
* @param {*} type
* @param {?Object=} context
* @return {?Runtime.Extension}
*/
extension: function(type, context)
{
return this.extensions(type, context)[0] || null;
},
/**
* @param {*} type
* @param {?Object=} context
* @return {!Promise.<!Array.<!Object>>}
*/
instancesPromise: function(type, context)
{
var extensions = this.extensions(type, context);
var promises = [];
for (var i = 0; i < extensions.length; ++i)
promises.push(extensions[i].instancePromise());
return Runtime._some(promises);
},
/**
* @param {*} type
* @param {?Object=} context
* @return {!Promise.<!Object>}
*/
instancePromise: function(type, context)
{
var extension = this.extension(type, context);
if (!extension)
return Promise.reject(new Error("No such extension: " + type + " in given context."));
return extension.instancePromise();
},
/**
* @return {?function(new:Object)}
*/
_resolve: function(typeName)
{
if (!this._cachedTypeClasses[typeName]) {
var path = typeName.split(".");
var object = window;
for (var i = 0; object && (i < path.length); ++i)
object = object[path[i]];
if (object)
this._cachedTypeClasses[typeName] = /** @type function(new:Object) */(object);
}
return this._cachedTypeClasses[typeName] || null;
}
}
/**
* @constructor
*/
Runtime.ModuleDescriptor = function()
{
/**
* @type {string}
*/
this.name;
/**
* @type {!Array.<!Runtime.ExtensionDescriptor>}
*/
this.extensions;
/**
* @type {!Array.<string>|undefined}
*/
this.dependencies;
/**
* @type {!Array.<string>}
*/
this.scripts;
/**
* @type {boolean|undefined}
*/
this.remote;
}
/**
* @constructor
*/
Runtime.ExtensionDescriptor = function()
{
/**
* @type {string}
*/
this.type;
/**
* @type {string|undefined}
*/
this.className;
/**
* @type {!Array.<string>|undefined}
*/
this.contextTypes;
}
/**
* @constructor
* @param {!Runtime} manager
* @param {!Runtime.ModuleDescriptor} descriptor
*/
Runtime.Module = function(manager, descriptor)
{
this._manager = manager;
this._descriptor = descriptor;
this._name = descriptor.name;
/** @type {!Object.<string, ?Object>} */
this._instanceMap = {};
var extensions = /** @type {?Array.<!Runtime.ExtensionDescriptor>} */ (descriptor.extensions);
for (var i = 0; extensions && i < extensions.length; ++i)
this._manager._extensions.push(new Runtime.Extension(this, extensions[i]));
this._loaded = false;
}
Runtime.Module.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {boolean}
*/
enabled: function()
{
var activatorExperiment = this._descriptor["experiment"];
if (activatorExperiment && !Runtime.experiments.isEnabled(activatorExperiment))
return false;
var condition = this._descriptor["condition"];
if (condition && !Runtime.queryParam(condition))
return false;
return true;
},
/**
* @param {string} name
* @return {string}
*/
resource: function(name)
{
var fullName = this._name + "/" + name;
var content = Runtime.cachedResources[fullName];
if (!content)
throw new Error(fullName + " not preloaded. Check module.json");
return content;
},
/**
* @return {!Promise.<undefined>}
*/
_loadPromise: function()
{
if (this._loaded)
return Promise.resolve();
if (!this.enabled())
return Promise.reject(new Error("Module " + this._name + " is not enabled"));
if (this._pendingLoadPromise)
return this._pendingLoadPromise;
var dependencies = this._descriptor.dependencies;
var dependencyPromises = [];
for (var i = 0; dependencies && i < dependencies.length; ++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());
this._pendingLoadPromise = Promise.all(dependencyPromises)
.then(this._loadResources.bind(this))
.then(this._loadScripts.bind(this))
.then(markAsLoaded.bind(this));
return this._pendingLoadPromise;
/**
* @this {Runtime.Module}
*/
function markAsLoaded()
{
delete this._pendingLoadPromise;
this._loaded = true;
}
},
/**
* @return {!Promise.<undefined>}
* @this {Runtime.Module}
*/
_loadResources: function()
{
var resources = this._descriptor["resources"];
if (!resources)
return Promise.resolve();
var promises = [];
for (var i = 0; i < resources.length; ++i) {
var url = this._modularizeURL(resources[i]);
promises.push(loadResourcePromise(url).then(cacheResource.bind(this, url), cacheResource.bind(this, url, undefined)));
}
return Promise.all(promises).then(undefined);
/**
* @param {string} path
* @param {string=} content
*/
function cacheResource(path, content)
{
if (!content) {
console.error("Failed to load resource: " + path);
return;
}
Runtime.cachedResources[path] = content + Runtime.resolveSourceURL(path);
}
},
/**
* @return {!Promise.<undefined>}
*/
_loadScripts: function()
{
if (!this._descriptor.scripts)
return Promise.resolve();
if (Runtime.isReleaseMode())
return loadScriptsPromise([this._name + "_module.js"], this._remoteBase());
return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL, this));
},
/**
* @param {string} resourceName
*/
_modularizeURL: function(resourceName)
{
return normalizePath(this._name + "/" + resourceName);
},
/**
* @return {string|undefined}
*/
_remoteBase: function()
{
return this._descriptor.remote && Runtime._remoteBase || undefined;
},
/**
* @param {string} value
* @return {string}
*/
substituteURL: function(value)
{
var base = this._remoteBase() || "";
return value.replace(/@url\(([^\)]*?)\)/g, convertURL.bind(this));
function convertURL(match, url)
{
return base + this._modularizeURL(url);
}
},
/**
* @param {string} className
* @param {!Runtime.Extension} extension
* @return {?Object}
*/
_instance: function(className, extension)
{
if (className in this._instanceMap)
return this._instanceMap[className];
var constructorFunction = window.eval(className);
if (!(constructorFunction instanceof Function)) {
this._instanceMap[className] = null;
return null;
}
var instance = new constructorFunction(extension);
this._instanceMap[className] = instance;
return instance;
}
}
/**
* @constructor
* @param {!Runtime.Module} module
* @param {!Runtime.ExtensionDescriptor} descriptor
*/
Runtime.Extension = function(module, descriptor)
{
this._module = module;
this._descriptor = descriptor;
this._type = descriptor.type;
this._hasTypeClass = this._type.charAt(0) === "@";
/**
* @type {?string}
*/
this._className = descriptor.className || null;
}
Runtime.Extension.prototype = {
/**
* @return {!Object}
*/
descriptor: function()
{
return this._descriptor;
},
/**
* @return {!Runtime.Module}
*/
module: function()
{
return this._module;
},
/**
* @return {boolean}
*/
enabled: function()
{
var activatorExperiment = this.descriptor()["experiment"];
if (activatorExperiment && activatorExperiment.startsWith("!") && Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;
if (activatorExperiment && !activatorExperiment.startsWith("!") && !Runtime.experiments.isEnabled(activatorExperiment))
return false;
var condition = this.descriptor()["condition"];
if (condition && !Runtime.queryParam(condition))
return false;
return this._module.enabled();
},
/**
* @return {?function(new:Object)}
*/
_typeClass: function()
{
if (!this._hasTypeClass)
return null;
return this._module._manager._resolve(this._type.substring(1));
},
/**
* @param {?Object} context
* @return {boolean}
*/
isApplicable: function(context)
{
return this._module._manager.isExtensionApplicableToContext(this, context);
},
/**
* @return {!Promise.<!Object>}
*/
instancePromise: function()
{
if (!this._className)
return Promise.reject(new Error("No class name in extension"));
var className = this._className;
if (this._instance)
return Promise.resolve(this._instance);
return this._module._loadPromise().then(constructInstance.bind(this));
/**
* @return {!Object}
* @this {Runtime.Extension}
*/
function constructInstance()
{
var result = this._module._instance(className, this);
if (!result)
return Promise.reject("Could not instantiate: " + className);
return result;
}
},
/**
* @param {string} platform
* @return {string}
*/
title: function(platform)
{
// FIXME: should be WebInspector.UIString() but runtime is not l10n aware yet.
return this._descriptor["title-" + platform] || this._descriptor["title"];
}
}
/**
* @constructor
*/
Runtime.ExperimentsSupport = function()
{
this._supportEnabled = Runtime.queryParam("experiments") !== null;
this._experiments = [];
this._experimentNames = {};
this._enabledTransiently = {};
}
Runtime.ExperimentsSupport.prototype = {
/**
* @return {!Array.<!Runtime.Experiment>}
*/
allConfigurableExperiments: function()
{
var result = [];
for (var i = 0; i < this._experiments.length; i++) {
var experiment = this._experiments[i];
if (!this._enabledTransiently[experiment.name])
result.push(experiment);
}
return result;
},
/**
* @return {boolean}
*/
supportEnabled: function()
{
return this._supportEnabled;
},
/**
* @param {!Object} value
*/
_setExperimentsSetting: function(value)
{
if (!self.localStorage)
return;
self.localStorage["experiments"] = JSON.stringify(value);
},
/**
* @param {string} experimentName
* @param {string} experimentTitle
* @param {boolean=} hidden
*/
register: function(experimentName, experimentTitle, hidden)
{
Runtime._assert(!this._experimentNames[experimentName], "Duplicate registration of experiment " + experimentName);
this._experimentNames[experimentName] = true;
this._experiments.push(new Runtime.Experiment(this, experimentName, experimentTitle, !!hidden));
},
/**
* @param {string} experimentName
* @return {boolean}
*/
isEnabled: function(experimentName)
{
this._checkExperiment(experimentName);
if (this._enabledTransiently[experimentName])
return true;
if (!this.supportEnabled())
return false;
return !!Runtime._experimentsSetting()[experimentName];
},
/**
* @param {string} experimentName
* @param {boolean} enabled
*/
setEnabled: function(experimentName, enabled)
{
this._checkExperiment(experimentName);
var experimentsSetting = Runtime._experimentsSetting();
experimentsSetting[experimentName] = enabled;
this._setExperimentsSetting(experimentsSetting);
},
/**
* @param {!Array.<string>} experimentNames
*/
setDefaultExperiments: function(experimentNames)
{
for (var i = 0; i < experimentNames.length; ++i) {
this._checkExperiment(experimentNames[i]);
this._enabledTransiently[experimentNames[i]] = true;
}
},
/**
* @param {string} experimentName
*/
enableForTest: function(experimentName)
{
this._checkExperiment(experimentName);
this._enabledTransiently[experimentName] = true;
},
clearForTest: function()
{
this._experiments = [];
this._experimentNames = {};
this._enabledTransiently = {};
},
cleanUpStaleExperiments: function()
{
var experimentsSetting = Runtime._experimentsSetting();
var cleanedUpExperimentSetting = {};
for (var i = 0; i < this._experiments.length; ++i) {
var experimentName = this._experiments[i].name;
if (experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName] = true;
}
this._setExperimentsSetting(cleanedUpExperimentSetting);
},
/**
* @param {string} experimentName
*/
_checkExperiment: function(experimentName)
{
Runtime._assert(this._experimentNames[experimentName], "Unknown experiment " + experimentName);
}
}
/**
* @constructor
* @param {!Runtime.ExperimentsSupport} experiments
* @param {string} name
* @param {string} title
* @param {boolean} hidden
*/
Runtime.Experiment = function(experiments, name, title, hidden)
{
this.name = name;
this.title = title;
this.hidden = hidden;
this._experiments = experiments;
}
Runtime.Experiment.prototype = {
/**
* @return {boolean}
*/
isEnabled: function()
{
return this._experiments.isEnabled(this.name);
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._experiments.setEnabled(this.name, enabled);
}
}
{(function parseQueryParameters()
{
var queryParams = location.search;
if (!queryParams)
return;
var params = queryParams.substring(1).split("&");
for (var i = 0; i < params.length; ++i) {
var pair = params[i].split("=");
var name = pair.shift();
Runtime._queryParamsObject[name] = pair.join("=");
}
})();}
// This must be constructed after the query parameters have been parsed.
Runtime.experiments = new Runtime.ExperimentsSupport();
/**
* @type {?string}
*/
Runtime._remoteBase = Runtime.queryParam("remoteBase");
{(function validateRemoteBase()
{
if (Runtime._remoteBase && !Runtime._remoteBase.startsWith("https://chrome-devtools-frontend.appspot.com/"))
Runtime._remoteBase = null;
})();}
/**
* @param {string} path
* @return {string}
*/
Runtime.resolveSourceURL = function(path)
{
var sourceURL = window.location.href;
if (window.location.search)
sourceURL = sourceURL.replace(window.location.search, "");
sourceURL = sourceURL.substring(0, sourceURL.lastIndexOf("/") + 1) + path;
return "\n/*# sourceURL=" + sourceURL + " */";
}
/** @type {!Runtime} */
var runtime;
|
| 1 2 | 2 | WebInspector.CSSMetadata.initializeWithSupportedProperties([{"name":"color"},{"name":"direction"},{"name":"font-family"},{"name":"font-kerning"},{"name":"font-size"},{"name":"font-size-adjust"},{"name":"font-stretch"},{"name":"font-style"},{"name":"font-variant-ligatures"},{"name":"font-variant-caps"},{"name":"font-variant-numeric"},{"name":"font-weight"},{"name":"font-feature-settings"},{"name":"-webkit-font-smoothing"},{"name":"-webkit-locale"},{"name":"text-orientation"},{"name":"-webkit-text-orientation"},{"name":"writing-mode"},{"name":"-webkit-writing-mode"},{"name":"text-rendering"},{"name":"zoom"},{"name":"align-content"},{"name":"align-items"},{"name":"alignment-baseline"},{"name":"align-self"},{"name":"animation-delay"},{"name":"animation-direction"},{"name":"animation-duration"},{"name":"animation-fill-mode"},{"name":"animation-iteration-count"},{"name":"animation-name"},{"name":"animation-play-state"},{"name":"animation-timing-function"},{"name":"backdrop-filter"},{"name":"backface-visibility"},{"name":"background-attachment"},{"name":"background-blend-mode"},{"name":"background-clip"},{"name":"background-color"},{"name":"background-image"},{"name":"background-origin"},{"name":"background-position-x"},{"name":"background-position-y"},{"name":"background-repeat-x"},{"name":"background-repeat-y"},{"name":"background-size"},{"name":"baseline-shift"},{"name":"border-bottom-color"},{"name":"border-bottom-left-radius"},{"name":"border-bottom-right-radius"},{"name":"border-bottom-style"},{"name":"border-bottom-width"},{"name":"border-collapse"},{"name":"border-image-outset"},{"name":"border-image-repeat"},{"name":"border-image-slice"},{"name":"border-image-source"},{"name":"border-image-width"},{"name":"border-left-color"},{"name":"border-left-style"},{"name":"border-left-width"},{"name":"border-right-color"},{"name":"border-right-style"},{"name":"border-right-width"},{"name":"border-top-color"},{"name":"border-top-left-radius"},{"name":"border-top-right-radius"},{"name":"border-top-style"},{"name":"border-top-width"},{"name":"bottom"},{"name":"box-shadow"},{"name":"box-sizing"},{"name":"break-after"},{"name":"break-before"},{"name":"break-inside"},{"name":"buffered-rendering"},{"name":"caption-side"},{"name":"clear"},{"name":"clip"},{"name":"clip-path"},{"name":"clip-rule"},{"name":"color-interpolation"},{"name":"color-interpolation-filters"},{"name":"color-rendering"},{"name":"column-fill"},{"name":"contain"},{"name":"content"},{"name":"counter-increment"},{"name":"counter-reset"},{"name":"cursor"},{"name":"cx"},{"name":"cy"},{"name":"d"},{"name":"display"},{"name":"dominant-baseline"},{"name":"empty-cells"},{"name":"fill"},{"name":"fill-opacity"},{"name":"fill-rule"},{"name":"filter"},{"name":"flex-basis"},{"name":"flex-direction"},{"name":"flex-grow"},{"name":"flex-shrink"},{"name":"flex-wrap"},{"name":"float"},{"name":"flood-color"},{"name":"flood-opacity"},{"name":"grid-auto-columns"},{"name":"grid-auto-flow"},{"name":"grid-auto-rows"},{"name":"grid-column-end"},{"name":"grid-column-gap"},{"name":"grid-column-start"},{"name":"grid-row-end"},{"name":"grid-row-gap"},{"name":"grid-row-start"},{"name":"grid-template-areas"},{"name":"grid-template-columns"},{"name":"grid-template-rows"},{"name":"height"},{"name":"hyphens"},{"name":"image-rendering"},{"name":"image-orientation"},{"name":"isolation"},{"name":"justify-content"},{"name":"justify-items"},{"name":"justify-self"},{"name":"left"},{"name":"letter-spacing"},{"name":"lighting-color"},{"name":"line-height"},{"name":"list-style-image"},{"name":"list-style-position"},{"name":"list-style-type"},{"name":"margin-bottom"},{"name":"margin-left"},{"name":"margin-right"},{"name":"margin-top"},{"name":"marker-end"},{"name":"marker-mid"},{"name":"marker-start"},{"name":"mask"},{"name":"mask-source-type"},{"name":"mask-type"},{"name":"max-height"},{"name":"max-width"},{"name":"min-height"},{"name":"min-width"},{"name":"mix-blend-mode"},{"name":"motion-offset"},{"name":"motion-path"},{"name":"motion-rotation"},{"name":"object-fit"},{"name":"object-position"},{"name":"opacity"},{"name":"order"},{"name":"orphans"},{"name":"outline-color"},{"name":"outline-offset"},{"name":"outline-style"},{"name":"outline-width"},{"name":"overflow-wrap"},{"name":"overflow-x"},{"name":"overflow-y"},{"name":"padding-bottom"},{"name":"padding-left"},{"name":"padding-right"},{"name":"padding-top"},{"name":"paint-order"},{"name":"perspective"},{"name":"perspective-origin"},{"name":"pointer-events"},{"name":"position"},{"name":"quotes"},{"name":"resize"},{"name":"right"},{"name":"r"},{"name":"rx"},{"name":"ry"},{"name":"scroll-behavior"},{"name":"scroll-snap-type"},{"name":"scroll-snap-points-x"},{"name":"scroll-snap-points-y"},{"name":"scroll-snap-destination"},{"name":"scroll-snap-coordinate"},{"name":"shape-image-threshold"},{"name":"shape-margin"},{"name":"shape-outside"},{"name":"shape-rendering"},{"name":"size"},{"name":"snap-height"},{"name":"speak"},{"name":"stop-color"},{"name":"stop-opacity"},{"name":"stroke"},{"name":"stroke-dasharray"},{"name":"stroke-dashoffset"},{"name":"stroke-linecap"},{"name":"stroke-linejoin"},{"name":"stroke-miterlimit"},{"name":"stroke-opacity"},{"name":"stroke-width"},{"name":"table-layout"},{"name":"tab-size"},{"name":"text-align"},{"name":"text-align-last"},{"name":"text-anchor"},{"name":"text-combine-upright"},{"name":"text-decoration","longhands":["text-decoration-line","text-decoration-style","text-decoration-color"]},{"name":"text-decoration-color"},{"name":"text-decoration-line"},{"name":"text-decoration-style"},{"name":"text-indent"},{"name":"text-justify"},{"name":"text-overflow"},{"name":"text-shadow"},{"name":"text-transform"},{"name":"text-underline-position"},{"name":"top"},{"name":"touch-action"},{"name":"transform"},{"name":"transform-origin"},{"name":"transform-style"},{"name":"translate"},{"name":"rotate"},{"name":"scale"},{"name":"transition-delay"},{"name":"transition-duration"},{"name":"transition-property"},{"name":"transition-timing-function"},{"name":"unicode-bidi"},{"name":"vector-effect"},{"name":"vertical-align"},{"name":"visibility"},{"name":"x"},{"name":"y"},{"name":"-webkit-appearance"},{"name":"-webkit-app-region"},{"name":"-webkit-background-clip"},{"name":"-webkit-background-origin"},{"name":"-webkit-border-horizontal-spacing"},{"name":"-webkit-border-image"},{"name":"-webkit-border-vertical-spacing"},{"name":"-webkit-box-align"},{"name":"-webkit-box-decoration-break"},{"name":"-webkit-box-direction"},{"name":"-webkit-box-flex"},{"name":"-webkit-box-flex-group"},{"name":"-webkit-box-lines"},{"name":"-webkit-box-ordinal-group"},{"name":"-webkit-box-orient"},{"name":"-webkit-box-pack"},{"name":"-webkit-box-reflect"},{"name":"-webkit-clip-path"},{"name":"column-count"},{"name":"column-gap"},{"name":"column-rule-color"},{"name":"column-rule-style"},{"name":"column-rule-width"},{"name":"column-span"},{"name":"column-width"},{"name":"-webkit-highlight"},{"name":"-webkit-hyphenate-character"},{"name":"-webkit-line-break"},{"name":"-webkit-line-clamp"},{"name":"-webkit-margin-after-collapse"},{"name":"-webkit-margin-before-collapse"},{"name":"-webkit-margin-bottom-collapse"},{"name":"-webkit-margin-top-collapse"},{"name":"-webkit-mask-box-image-outset"},{"name":"-webkit-mask-box-image-repeat"},{"name":"-webkit-mask-box-image-slice"},{"name":"-webkit-mask-box-image-source"},{"name":"-webkit-mask-box-image-width"},{"name":"-webkit-mask-clip"},{"name":"-webkit-mask-composite"},{"name":"-webkit-mask-image"},{"name":"-webkit-mask-origin"},{"name":"-webkit-mask-position-x"},{"name":"-webkit-mask-position-y"},{"name":"-webkit-mask-repeat-x"},{"name":"-webkit-mask-repeat-y"},{"name":"-webkit-mask-size"},{"name":"-webkit-perspective-origin-x"},{"name":"-webkit-perspective-origin-y"},{"name":"-webkit-print-color-adjust"},{"name":"-webkit-rtl-ordering"},{"name":"-webkit-ruby-position"},{"name":"-webkit-tap-highlight-color"},{"name":"-webkit-text-combine"},{"name":"-webkit-text-emphasis-color"},{"name":"-webkit-text-emphasis-position"},{"name":"-webkit-text-emphasis-style"},{"name":"-webkit-text-fill-color"},{"name":"-webkit-text-security"},{"name":"-webkit-text-stroke-color"},{"name":"-webkit-text-stroke-width"},{"name":"-webkit-transform-origin-x"},{"name":"-webkit-transform-origin-y"},{"name":"-webkit-transform-origin-z"},{"name":"-webkit-user-drag"},{"name":"-webkit-user-modify"},{"name":"-webkit-user-select"},{"name":"white-space"},{"name":"widows"},{"name":"width"},{"name":"will-change"},{"name":"word-break"},{"name":"word-spacing"},{"name":"word-wrap"},{"name":"z-index"},{"name":"-webkit-border-end-color"},{"name":"-webkit-border-end-style"},{"name":"-webkit-border-end-width"},{"name":"-webkit-border-start-color"},{"name":"-webkit-border-start-style"},{"name":"-webkit-border-start-width"},{"name":"-webkit-border-before-color"},{"name":"-webkit-border-before-style"},{"name":"-webkit-border-before-width"},{"name":"-webkit-border-after-color"},{"name":"-webkit-border-after-style"},{"name":"-webkit-border-after-width"},{"name":"-webkit-margin-end"},{"name":"-webkit-margin-start"},{"name":"-webkit-margin-before"},{"name":"-webkit-margin-after"},{"name":"-webkit-padding-end"},{"name":"-webkit-padding-start"},{"name":"-webkit-padding-before"},{"name":"-webkit-padding-after"},{"name":"-webkit-logical-width"},{"name":"-webkit-logical-height"},{"name":"-webkit-min-logical-width"},{"name":"-webkit-min-logical-height"},{"name":"-webkit-max-logical-width"},{"name":"-webkit-max-logical-height"},{"name":"all"},{"name":"page"},{"name":"-webkit-font-size-delta"},{"name":"-webkit-text-decorations-in-effect"},{"name":"font-display"},{"name":"max-zoom"},{"name":"min-zoom"},{"name":"orientation"},{"name":"src"},{"name":"unicode-range"},{"name":"user-zoom"},{"name":"animation","longhands":["animation-name","animation-duration","animation-timing-function","animation-delay","animation-iteration-count","animation-direction","animation-fill-mode","animation-play-state"]},{"name":"background","longhands":["background-image","background-position-x","background-position-y","background-size","background-repeat-x","background-repeat-y","background-attachment","background-origin","background-clip","background-color"]},{"name":"background-position","longhands":["background-position-x","background-position-y"]},{"name":"background-repeat","longhands":["background-repeat-x","background-repeat-y"]},{"name":"border","longhands":["border-top-color","border-top-style","border-top-width","border-right-color","border-right-style","border-right-width","border-bottom-color","border-bottom-style","border-bottom-width","border-left-color","border-left-style","border-left-width","border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"]},{"name":"border-bottom","longhands":["border-bottom-width","border-bottom-style","border-bottom-color"]},{"name":"border-color","longhands":["border-top-color","border-right-color","border-bottom-color","border-left-color"]},{"name":"border-image","longhands":["border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"]},{"name":"border-left","longhands":["border-left-width","border-left-style","border-left-color"]},{"name":"border-radius","longhands":["border-top-left-radius","border-top-right-radius","border-bottom-right-radius","border-bottom-left-radius"]},{"name":"border-right","longhands":["border-right-width","border-right-style","border-right-color"]},{"name":"border-spacing","longhands":["-webkit-border-horizontal-spacing","-webkit-border-vertical-spacing"]},{"name":"border-style","longhands":["border-top-style","border-right-style","border-bottom-style","border-left-style"]},{"name":"border-top","longhands":["border-top-width","border-top-style","border-top-color"]},{"name":"border-width","longhands":["border-top-width","border-right-width","border-bottom-width","border-left-width"]},{"name":"flex","longhands":["flex-grow","flex-shrink","flex-basis"]},{"name":"flex-flow","longhands":["flex-direction","flex-wrap"]},{"name":"font","longhands":["font-style","font-variant-ligatures","font-variant-caps","font-variant-numeric","font-weight","font-stretch","font-size","line-height","font-family"]},{"name":"font-variant","longhands":["font-variant-ligatures","font-variant-caps","font-variant-numeric"]},{"name":"grid","longhands":["grid-template-rows","grid-template-columns","grid-template-areas","grid-auto-flow","grid-auto-rows","grid-auto-columns","grid-column-gap","grid-row-gap"]},{"name":"grid-area","longhands":["grid-row-start","grid-column-start","grid-row-end","grid-column-end"]},{"name":"grid-column","longhands":["grid-column-start","grid-column-end"]},{"name":"grid-gap","longhands":["grid-row-gap","grid-column-gap"]},{"name":"grid-row","longhands":["grid-row-start","grid-row-end"]},{"name":"grid-template","longhands":["grid-template-rows","grid-template-columns","grid-template-areas"]},{"name":"list-style","longhands":["list-style-type","list-style-position","list-style-image"]},{"name":"margin","longhands":["margin-top","margin-right","margin-bottom","margin-left"]},{"name":"marker","longhands":["marker-start","marker-mid","marker-end"]},{"name":"motion","longhands":["motion-path","motion-offset","motion-rotation"]},{"name":"outline","longhands":["outline-color","outline-style","outline-width"]},{"name":"overflow","longhands":["overflow-x","overflow-y"]},{"name":"padding","longhands":["padding-top","padding-right","padding-bottom","padding-left"]},{"name":"page-break-after","longhands":["break-after"]},{"name":"page-break-before","longhands":["break-before"]},{"name":"page-break-inside","longhands":["break-inside"]},{"name":"transition","longhands":["transition-property","transition-duration","transition-timing-function","transition-delay"]},{"name":"-webkit-border-after","longhands":["-webkit-border-after-width","-webkit-border-after-style","-webkit-border-after-color"]},{"name":"-webkit-border-before","longhands":["-webkit-border-before-width","-webkit-border-before-style","-webkit-border-before-color"]},{"name":"-webkit-border-end","longhands":["-webkit-border-end-width","-webkit-border-end-style","-webkit-border-end-color"]},{"name":"-webkit-border-start","longhands":["-webkit-border-start-width","-webkit-border-start-style","-webkit-border-start-color"]},{"name":"-webkit-column-break-after","longhands":["break-after"]},{"name":"-webkit-column-break-before","longhands":["break-before"]},{"name":"-webkit-column-break-inside","longhands":["break-inside"]},{"name":"column-rule","longhands":["column-rule-width","column-rule-style","column-rule-color"]},{"name":"columns","longhands":["column-width","column-count"]},{"name":"-webkit-margin-collapse","longhands":["-webkit-margin-before-collapse","-webkit-margin-after-collapse"]},{"name":"-webkit-mask","longhands":["-webkit-mask-image","-webkit-mask-position-x","-webkit-mask-position-y","-webkit-mask-size","-webkit-mask-repeat-x","-webkit-mask-repeat-y","-webkit-mask-origin","-webkit-mask-clip"]},{"name":"-webkit-mask-box-image","longhands":["-webkit-mask-box-image-source","-webkit-mask-box-image-slice","-webkit-mask-box-image-width","-webkit-mask-box-image-outset","-webkit-mask-box-image-repeat"]},{"name":"-webkit-mask-position","longhands":["-webkit-mask-position-x","-webkit-mask-position-y"]},{"name":"-webkit-mask-repeat","longhands":["-webkit-mask-repeat-x","-webkit-mask-repeat-y"]},{"name":"-webkit-text-emphasis","longhands":["-webkit-text-emphasis-style","-webkit-text-emphasis-color"]},{"name":"-webkit-text-stroke","longhands":["-webkit-text-stroke-width","-webkit-text-stroke-color"]}]);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. (function(window) { // DevToolsAPI ---------------------------------------------------------------- /** * @constructor */ function DevToolsAPIImpl() { /** * @type {number} */ this._lastCallId = 0; /** * @type {!Object.<number, function(?Object)>} */ this._callbacks = {}; } DevToolsAPIImpl.prototype = { /** * @param {number} id * @param {?Object} arg */ embedderMessageAck: function(id, arg) { var callback = this._callbacks[id]; delete this._callbacks[id]; if (callback) callback(arg); }, /** * @param {string} method * @param {!Array.<*>} args * @param {?function(?Object)} callback */ sendMessageToEmbedder: function(method, args, callback) { var callId = ++this._lastCallId; if (callback) this._callbacks[callId] = callback; var message = { "id": callId, "method": method }; if (args.length) message.params = args; DevToolsHost.sendMessageToEmbedder(JSON.stringify(message)); }, /** * @param {string} method * @param {!Array.<*>} args */ _dispatchOnInspectorFrontendAPI: function(method, args) { var api = window["InspectorFrontendAPI"]; api[method].apply(api, args); }, // API methods below this line -------------------------------------------- /** * @param {!Array.<!ExtensionDescriptor>} extensions */ addExtensions: function(extensions) { // Support for legacy front-ends (<M41). if (window["WebInspector"].addExtensions) window["WebInspector"].addExtensions(extensions); else this._dispatchOnInspectorFrontendAPI("addExtensions", [extensions]); }, /** * @param {string} url */ appendedToURL: function(url) { this._dispatchOnInspectorFrontendAPI("appendedToURL", [url]); }, /** * @param {string} url */ canceledSaveURL: function(url) { this._dispatchOnInspectorFrontendAPI("canceledSaveURL", [url]); }, contextMenuCleared: function() { this._dispatchOnInspectorFrontendAPI("contextMenuCleared", []); }, /** * @param {string} id */ contextMenuItemSelected: function(id) { this._dispatchOnInspectorFrontendAPI("contextMenuItemSelected", [id]); }, /** * @param {number} count */ deviceCountUpdated: function(count) { this._dispatchOnInspectorFrontendAPI("deviceCountUpdated", [count]); }, /** * @param {boolean} discoverUsbDevices * @param {boolean} portForwardingEnabled * @param {!Adb.PortForwardingConfig} portForwardingConfig */ devicesDiscoveryConfigChanged: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig) { this._dispatchOnInspectorFrontendAPI("devicesDiscoveryConfigChanged", [discoverUsbDevices, portForwardingEnabled, portForwardingConfig]); }, /** * @param {!Adb.PortForwardingStatus} status */ devicesPortForwardingStatusChanged: function(status) { this._dispatchOnInspectorFrontendAPI("devicesPortForwardingStatusChanged", [status]); }, /** * @param {!Array.<!Adb.Device>} devices */ devicesUpdated: function(devices) { this._dispatchOnInspectorFrontendAPI("devicesUpdated", [devices]); }, /** * @param {string} message */ dispatchMessage: function(message) { this._dispatchOnInspectorFrontendAPI("dispatchMessage", [message]); }, /** * @param {string} messageChunk * @param {number} messageSize */ dispatchMessageChunk: function(messageChunk, messageSize) { this._dispatchOnInspectorFrontendAPI("dispatchMessageChunk", [messageChunk, messageSize]); }, enterInspectElementMode: function() { this._dispatchOnInspectorFrontendAPI("enterInspectElementMode", []); }, /** * @param {number} callId * @param {string} script */ evaluateForTestInFrontend: function(callId, script) { this._dispatchOnInspectorFrontendAPI("evaluateForTestInFrontend", [callId, script]); }, /** * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems */ fileSystemsLoaded: function(fileSystems) { this._dispatchOnInspectorFrontendAPI("fileSystemsLoaded", [fileSystems]); }, /** * @param {string} fileSystemPath */ fileSystemRemoved: function(fileSystemPath) { this._dispatchOnInspectorFrontendAPI("fileSystemRemoved", [fileSystemPath]); }, /** * @param {!{fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem */ fileSystemAdded: function(fileSystem) { this._dispatchOnInspectorFrontendAPI("fileSystemAdded", ["", fileSystem]); }, fileSystemFilesChanged: function(path) { this._dispatchOnInspectorFrontendAPI("fileSystemFilesChanged", [path]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {number} totalWork */ indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork) { this._dispatchOnInspectorFrontendAPI("indexingTotalWorkCalculated", [requestId, fileSystemPath, totalWork]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {number} worked */ indexingWorked: function(requestId, fileSystemPath, worked) { this._dispatchOnInspectorFrontendAPI("indexingWorked", [requestId, fileSystemPath, worked]); }, /** * @param {number} requestId * @param {string} fileSystemPath */ indexingDone: function(requestId, fileSystemPath) { this._dispatchOnInspectorFrontendAPI("indexingDone", [requestId, fileSystemPath]); }, /** * @param {{type: string, keyIdentifier: string, keyCode: number, modifiers: number}} event */ keyEventUnhandled: function(event) { this._dispatchOnInspectorFrontendAPI("keyEventUnhandled", [event]); }, /** * @param {boolean} hard */ reloadInspectedPage: function(hard) { this._dispatchOnInspectorFrontendAPI("reloadInspectedPage", [hard]); }, /** * @param {string} url * @param {number} lineNumber * @param {number} columnNumber */ revealSourceLine: function(url, lineNumber, columnNumber) { this._dispatchOnInspectorFrontendAPI("revealSourceLine", [url, lineNumber, columnNumber]); }, /** * @param {string} url */ savedURL: function(url) { this._dispatchOnInspectorFrontendAPI("savedURL", [url]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {!Array.<string>} files */ searchCompleted: function(requestId, fileSystemPath, files) { this._dispatchOnInspectorFrontendAPI("searchCompleted", [requestId, fileSystemPath, files]); }, /** * @param {string} tabId */ setInspectedTabId: function(tabId) { // Support for legacy front-ends (<M41). if (window["WebInspector"].setInspectedTabId) window["WebInspector"].setInspectedTabId(tabId); else this._dispatchOnInspectorFrontendAPI("setInspectedTabId", [tabId]); }, /** * @param {boolean} useSoftMenu */ setUseSoftMenu: function(useSoftMenu) { this._dispatchOnInspectorFrontendAPI("setUseSoftMenu", [useSoftMenu]); }, /** * @param {string} panelName */ showPanel: function(panelName) { this._dispatchOnInspectorFrontendAPI("showPanel", [panelName]); }, /** * @param {number} id * @param {string} chunk */ streamWrite: function(id, chunk) { this._dispatchOnInspectorFrontendAPI("streamWrite", [id, chunk]); } } var DevToolsAPI = new DevToolsAPIImpl(); window.DevToolsAPI = DevToolsAPI; // InspectorFrontendHostImpl -------------------------------------------------- /** * @constructor * @implements {InspectorFrontendHostAPI} */ function InspectorFrontendHostImpl() { } InspectorFrontendHostImpl.prototype = { /** * @override * @return {string} */ getSelectionBackgroundColor: function() { return DevToolsHost.getSelectionBackgroundColor(); }, /** * @override * @return {string} */ getSelectionForegroundColor: function() { return DevToolsHost.getSelectionForegroundColor(); }, /** * @override * @return {string} */ platform: function() { return DevToolsHost.platform(); }, /** * @override */ loadCompleted: function() { DevToolsAPI.sendMessageToEmbedder("loadCompleted", [], null); }, /** * @override */ bringToFront: function() { DevToolsAPI.sendMessageToEmbedder("bringToFront", [], null); }, /** * @override */ closeWindow: function() { DevToolsAPI.sendMessageToEmbedder("closeWindow", [], null); }, /** * @override * @param {boolean} isDocked * @param {function()} callback */ setIsDocked: function(isDocked, callback) { DevToolsAPI.sendMessageToEmbedder("setIsDocked", [isDocked], callback); }, /** * Requests inspected page to be placed atop of the inspector frontend with specified bounds. * @override * @param {{x: number, y: number, width: number, height: number}} bounds */ setInspectedPageBounds: function(bounds) { DevToolsAPI.sendMessageToEmbedder("setInspectedPageBounds", [bounds], null); }, /** * @override */ inspectElementCompleted: function() { DevToolsAPI.sendMessageToEmbedder("inspectElementCompleted", [], null); }, /** * @override * @param {string} url * @param {string} headers * @param {number} streamId * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback */ loadNetworkResource: function(url, headers, streamId, callback) { DevToolsAPI.sendMessageToEmbedder("loadNetworkResource", [url, headers, streamId], /** @type {function(?Object)} */ (callback)); }, /** * @override * @param {function(!Object<string, string>)} callback */ getPreferences: function(callback) { DevToolsAPI.sendMessageToEmbedder("getPreferences", [], /** @type {function(?Object)} */ (callback)); }, /** * @override * @param {string} name * @param {string} value */ setPreference: function(name, value) { DevToolsAPI.sendMessageToEmbedder("setPreference", [name, value], null); }, /** * @override * @param {string} name */ removePreference: function(name) { DevToolsAPI.sendMessageToEmbedder("removePreference", [name], null); }, /** * @override */ clearPreferences: function() { DevToolsAPI.sendMessageToEmbedder("clearPreferences", [], null); }, /** * @override * @param {string} origin * @param {string} script */ setInjectedScriptForOrigin: function(origin, script) { DevToolsHost.setInjectedScriptForOrigin(origin, script); }, /** * @override * @param {string} url */ inspectedURLChanged: function(url) { DevToolsAPI.sendMessageToEmbedder("inspectedURLChanged", [url], null); }, /** * @override * @param {string} text */ copyText: function(text) { DevToolsHost.copyText(text); }, /** * @override * @param {string} url */ openInNewTab: function(url) { DevToolsAPI.sendMessageToEmbedder("openInNewTab", [url], null); }, /** * @override * @param {string} url * @param {string} content * @param {boolean} forceSaveAs */ save: function(url, content, forceSaveAs) { DevToolsAPI.sendMessageToEmbedder("save", [url, content, forceSaveAs], null); }, /** * @override * @param {string} url * @param {string} content */ append: function(url, content) { DevToolsAPI.sendMessageToEmbedder("append", [url, content], null); }, /** * @override * @param {string} message */ sendMessageToBackend: function(message) { DevToolsAPI.sendMessageToEmbedder("dispatchProtocolMessage", [message], null); }, /** * @override * @param {string} actionName * @param {number} actionCode * @param {number} bucketSize */ recordEnumeratedHistogram: function(actionName, actionCode, bucketSize) { // Support for M49 frontend. if (actionName === "DevTools.DrawerShown") return; DevToolsAPI.sendMessageToEmbedder("recordEnumeratedHistogram", [actionName, actionCode, bucketSize], null); }, /** * @override */ requestFileSystems: function() { DevToolsAPI.sendMessageToEmbedder("requestFileSystems", [], null); }, /** * @override * @param {string=} fileSystemPath */ addFileSystem: function(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("addFileSystem", [fileSystemPath || ""], null); }, /** * @override * @param {string} fileSystemPath */ removeFileSystem: function(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("removeFileSystem", [fileSystemPath], null); }, /** * @override * @param {string} fileSystemId * @param {string} registeredName * @return {?DOMFileSystem} */ isolatedFileSystem: function(fileSystemId, registeredName) { return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName); }, /** * @override * @param {!FileSystem} fileSystem */ upgradeDraggedFileSystemPermissions: function(fileSystem) { DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem); }, /** * @override * @param {number} requestId * @param {string} fileSystemPath */ indexPath: function(requestId, fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("indexPath", [requestId, fileSystemPath], null); }, /** * @override * @param {number} requestId */ stopIndexing: function(requestId) { DevToolsAPI.sendMessageToEmbedder("stopIndexing", [requestId], null); }, /** * @override * @param {number} requestId * @param {string} fileSystemPath * @param {string} query */ searchInPath: function(requestId, fileSystemPath, query) { DevToolsAPI.sendMessageToEmbedder("searchInPath", [requestId, fileSystemPath, query], null); }, /** * @override * @return {number} */ zoomFactor: function() { return DevToolsHost.zoomFactor(); }, /** * @override */ zoomIn: function() { DevToolsAPI.sendMessageToEmbedder("zoomIn", [], null); }, /** * @override */ zoomOut: function() { DevToolsAPI.sendMessageToEmbedder("zoomOut", [], null); }, /** * @override */ resetZoom: function() { DevToolsAPI.sendMessageToEmbedder("resetZoom", [], null); }, /** * @override * @param {string} shortcuts */ setWhitelistedShortcuts: function(shortcuts) { DevToolsAPI.sendMessageToEmbedder("setWhitelistedShortcuts", [shortcuts], null); }, /** * @override * @return {boolean} */ isUnderTest: function() { return DevToolsHost.isUnderTest(); }, /** * @override */ readyForTest: function() { DevToolsAPI.sendMessageToEmbedder("readyForTest", [], null); }, /** * @override * @param {boolean} discoverUsbDevices * @param {boolean} portForwardingEnabled * @param {!Adb.PortForwardingConfig} portForwardingConfig */ setDevicesDiscoveryConfig: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig) { DevToolsAPI.sendMessageToEmbedder("setDevicesDiscoveryConfig", [discoverUsbDevices, portForwardingEnabled, JSON.stringify(portForwardingConfig)], null); }, /** * @override * @param {boolean} enabled */ setDevicesUpdatesEnabled: function(enabled) { DevToolsAPI.sendMessageToEmbedder("setDevicesUpdatesEnabled", [enabled], null); }, /** * @override * @param {string} pageId * @param {string} action */ performActionOnRemotePage: function(pageId, action) { DevToolsAPI.sendMessageToEmbedder("performActionOnRemotePage", [pageId, action], null); }, /** * @override * @param {string} browserId * @param {string} url */ openRemotePage: function(browserId, url) { DevToolsAPI.sendMessageToEmbedder("openRemotePage", [browserId, url], null); }, /** * @override * @param {number} x * @param {number} y * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items * @param {!Document} document */ showContextMenuAtPoint: function(x, y, items, document) { DevToolsHost.showContextMenuAtPoint(x, y, items, document); }, /** * @override * @return {boolean} */ isHostedMode: function() { return DevToolsHost.isHostedMode(); }, // Backward-compatible methods below this line -------------------------------------------- /** * Support for legacy front-ends (<M50). * @param {string} message */ sendFrontendAPINotification: function(message) { }, /** * Support for legacy front-ends (<M41). * @return {string} */ port: function() { return "unknown"; }, /** * Support for legacy front-ends (<M38). * @param {number} zoomFactor */ setZoomFactor: function(zoomFactor) { }, /** * Support for legacy front-ends (<M34). */ sendMessageToEmbedder: function() { }, /** * Support for legacy front-ends (<M34). * @param {string} dockSide */ requestSetDockSide: function(dockSide) { DevToolsAPI.sendMessageToEmbedder("setIsDocked", [dockSide !== "undocked"], null); }, /** * Support for legacy front-ends (<M34). * @return {boolean} */ supportsFileSystems: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canInspectWorkers: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canSaveAs: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canSave: function() { return true; }, /** * Support for legacy front-ends (<M28). */ loaded: function() { }, /** * Support for legacy front-ends (<M28). * @return {string} */ hiddenPanels: function() { return ""; }, /** * Support for legacy front-ends (<M28). * @return {string} */ localizedStringsURL: function() { return ""; }, /** * Support for legacy front-ends (<M28). * @param {string} url */ close: function(url) { }, /** * Support for legacy front-ends (<M44). * @param {number} actionCode */ recordActionTaken: function(actionCode) { this.recordEnumeratedHistogram("DevTools.ActionTaken", actionCode, 100); }, /** * Support for legacy front-ends (<M44). * @param {number} panelCode */ recordPanelShown: function(panelCode) { this.recordEnumeratedHistogram("DevTools.PanelShown", panelCode, 20); } } window.InspectorFrontendHost = new InspectorFrontendHostImpl(); // DevToolsApp --------------------------------------------------------------- function installObjectObserve() { var properties = [ "advancedSearchConfig", "auditsPanelSplitViewState", "auditsSidebarWidth", "blockedURLs", "breakpoints", "cacheDisabled", "colorFormat", "consoleHistory", "consoleTimestampsEnabled", "cpuProfilerView", "cssSourceMapsEnabled", "currentDockState", "customColorPalette", "customDevicePresets", "customEmulatedDeviceList", "customFormatters", "customUserAgent", "databaseTableViewVisibleColumns", "dataGrid-cookiesTable", "dataGrid-DOMStorageItemsView", "debuggerSidebarHidden", "disableDataSaverInfobar", "disablePausedStateOverlay", "domBreakpoints", "domWordWrap", "elementsPanelSplitViewState", "elementsSidebarWidth", "emulation.deviceHeight", "emulation.deviceModeValue", "emulation.deviceOrientationOverride", "emulation.deviceScale", "emulation.deviceScaleFactor", "emulation.deviceUA", "emulation.deviceWidth", "emulation.geolocationOverride", "emulation.showDeviceMode", "emulation.showRulers", "enableAsyncStackTraces", "eventListenerBreakpoints", "fileMappingEntries", "fileSystemMapping", "FileSystemViewSidebarWidth", "fileSystemViewSplitViewState", "filterBar-consoleView", "filterBar-networkPanel", "filterBar-promisePane", "filterBar-timelinePanel", "frameViewerHideChromeWindow", "heapSnapshotRetainersViewSize", "heapSnapshotSplitViewState", "hideCollectedPromises", "hideNetworkMessages", "highlightNodeOnHoverInOverlay", "highResolutionCpuProfiling", "inlineVariableValues", "Inspector.drawerSplitView", "Inspector.drawerSplitViewState", "InspectorView.panelOrder", "InspectorView.screencastSplitView", "InspectorView.screencastSplitViewState", "InspectorView.splitView", "InspectorView.splitViewState", "javaScriptDisabled", "jsSourceMapsEnabled", "lastActivePanel", "lastDockState", "lastSelectedSourcesSidebarPaneTab", "lastSnippetEvaluationIndex", "layerDetailsSplitView", "layerDetailsSplitViewState", "layersPanelSplitViewState", "layersShowInternalLayers", "layersSidebarWidth", "messageLevelFilters", "messageURLFilters", "monitoringXHREnabled", "navigatorGroupByFolder", "navigatorHidden", "networkColorCodeResourceTypes", "networkConditions", "networkConditionsCustomProfiles", "networkHideDataURL", "networkLogColumnsVisibility", "networkLogLargeRows", "networkLogShowOverview", "networkPanelSplitViewState", "networkRecordFilmStripSetting", "networkResourceTypeFilters", "networkShowPrimaryLoadWaterfall", "networkSidebarWidth", "openLinkHandler", "pauseOnCaughtException", "pauseOnExceptionEnabled", "preserveConsoleLog", "prettyPrintInfobarDisabled", "previouslyViewedFiles", "profilesPanelSplitViewState", "profilesSidebarWidth", "promiseStatusFilters", "recordAllocationStacks", "requestHeaderFilterSetting", "request-info-formData-category-expanded", "request-info-general-category-expanded", "request-info-queryString-category-expanded", "request-info-requestHeaders-category-expanded", "request-info-requestPayload-category-expanded", "request-info-responseHeaders-category-expanded", "resources", "resourcesLastSelectedItem", "resourcesPanelSplitViewState", "resourcesSidebarWidth", "resourceViewTab", "savedURLs", "screencastEnabled", "scriptsPanelNavigatorSidebarWidth", "searchInContentScripts", "selectedAuditCategories", "selectedColorPalette", "selectedProfileType", "shortcutPanelSwitch", "showAdvancedHeapSnapshotProperties", "showEventListenersForAncestors", "showFrameowkrListeners", "showHeaSnapshotObjectsHiddenProperties", "showInheritedComputedStyleProperties", "showMediaQueryInspector", "showNativeFunctionsInJSProfile", "showUAShadowDOM", "showWhitespacesInEditor", "sidebarPosition", "skipContentScripts", "skipStackFramesPattern", "sourceMapInfobarDisabled", "sourcesPanelDebuggerSidebarSplitViewState", "sourcesPanelNavigatorSplitViewState", "sourcesPanelSplitSidebarRatio", "sourcesPanelSplitViewState", "sourcesSidebarWidth", "standardEmulatedDeviceList", "StylesPaneSplitRatio", "stylesPaneSplitViewState", "textEditorAutocompletion", "textEditorAutoDetectIndent", "textEditorBracketMatching", "textEditorIndent", "timelineCaptureFilmStrip", "timelineCaptureLayersAndPictures", "timelineCaptureMemory", "timelineCaptureNetwork", "timeline-details", "timelineEnableJSSampling", "timelineOverviewMode", "timelinePanelDetailsSplitViewState", "timelinePanelRecorsSplitViewState", "timelinePanelTimelineStackSplitViewState", "timelinePerspective", "timeline-split", "timelineTreeGroupBy", "timeline-view", "timelineViewMode", "uiTheme", "watchExpressions", "WebInspector.Drawer.lastSelectedView", "WebInspector.Drawer.showOnLoad", "workspaceExcludedFolders", "workspaceFolderExcludePattern", "workspaceInfobarDisabled", "workspaceMappingInfobarDisabled", "xhrBreakpoints"]; /** * @this {!{_storage: Object, _name: string}} */ function settingRemove() { this._storage[this._name] = undefined; } function objectObserve(object, observer) { if (window["WebInspector"]) { var settingPrototype = window["WebInspector"]["Setting"]["prototype"]; if (typeof settingPrototype["remove"] === "function") settingPrototype["remove"] = settingRemove; } var changedProperties = new Set(); var scheduled = false; function scheduleObserver() { if (!scheduled) { scheduled = true; setImmediate(callObserver); } } function callObserver() { scheduled = false; var changes = []; changedProperties.forEach(function(name) { changes.push({name: name}); }); changedProperties.clear(); observer.call(null, changes); } var storage = new Map(); function defineProperty(property) { if (property in object) { storage.set(property, object[property]); delete object[property]; } Object.defineProperty(object, property, { get: function() { return storage.get(property); }, set: function(value) { storage.set(property, value); changedProperties.add(property); scheduleObserver(); } }); } for (var i = 0; i < properties.length; ++i) defineProperty(properties[i]); } window.Object.observe = objectObserve; } /** * @suppressGlobalPropertiesCheck */ function sanitizeRemoteFrontendUrl() { var queryParams = location.search; if (!queryParams) return; var params = queryParams.substring(1).split("&"); for (var i = 0; i < params.length; ++i) { var pair = params[i].split("="); var name = pair.shift(); var value = pair.join("="); if (name === "remoteFrontendUrl" && !value.startsWith("https://chrome-devtools-frontend.appspot.com/")) location.search = ""; } } /** * @suppressGlobalPropertiesCheck */ function installBackwardsCompatibility() { sanitizeRemoteFrontendUrl(); if (window.location.search.indexOf("remoteFrontend") === -1) return; // Support for legacy (<M50) frontends. installObjectObserve(); /** * @this {CSSStyleDeclaration} */ function getValue(property) { // Note that |property| comes from another context, so we can't use === here. if (property == "padding-left") { return { /** * @suppressReceiverCheck * @this {Object} */ getFloatValue: function() { return this.__paddingLeft; }, __paddingLeft: parseFloat(this.paddingLeft) }; } throw new Error("getPropertyCSSValue is undefined"); } // Support for legacy (<M41) frontends. Remove in M45. window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue; function CSSPrimitiveValue() { } CSSPrimitiveValue.CSS_PX = 5; window.CSSPrimitiveValue = CSSPrimitiveValue; // Support for legacy (<M44) frontends. Remove in M48. var styleElement = window.document.createElement("style"); styleElement.type = "text/css"; styleElement.textContent = "html /deep/ * { min-width: 0; min-height: 0; }"; // Support for quirky border-image behavior (<M51), see: // https://bugs.chromium.org/p/chromium/issues/detail?id=559258 styleElement.textContent += "\nhtml /deep/ .cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }"; styleElement.textContent += "\nhtml /deep/ .cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }"; window.document.head.appendChild(styleElement); // Support for legacy (<M49) frontends. Remove in M52. Event.prototype.deepPath = undefined; } function windowLoaded() { window.removeEventListener("DOMContentLoaded", windowLoaded, false); installBackwardsCompatibility(); } sanitizeRemoteFrontendUrl(); if (window.document.head && (window.document.readyState === "complete" || window.document.readyState === "interactive")) installBackwardsCompatibility(); else window.addEventListener("DOMContentLoaded", windowLoaded, false); })(window); if (!DOMTokenList.prototype.__originalDOMTokenListToggle) { DOMTokenList.prototype.__originalDOMTokenListToggle = DOMTokenList.prototype.toggle; DOMTokenList.prototype.toggle = function(token, force) { if (arguments.length === 1) force = !this.contains(token); return this.__originalDOMTokenListToggle(token, !!force); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// WebKit Web Facing API
/**
* @param {!Object} object
* @param {!Function} callback
*/
Object.observe = function(object, callback) {}
/** @type {boolean} */
Event.prototype.isMetaOrCtrlForTest;
/** @type {string} */
Event.prototype.code;
/**
* @type {number}
*/
KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
/**
* @param {!T} value
* @param {boolean=} onlyFirst
* @this {Array.<T>}
* @template T
*/
Array.prototype.remove = function(value, onlyFirst) {}
/**
* @param {!Array.<!T>} array
* @this {Array.<!T>}
* @template T
*/
Array.prototype.pushAll = function(array) {}
/**
* @return {!Object.<string, boolean>}
* @this {Array.<T>}
* @template T
*/
Array.prototype.keySet = function() {}
/**
* @param {number} index
* @return {!Array.<!T>}
* @this {Array.<T>}
* @template T
*/
Array.prototype.rotate = function(index) {}
/**
* @this {Array.<number>}
*/
Array.prototype.sortNumbers = function() {}
/**
* @param {!S} object
* @param {function(!S,!T):number=} comparator
* @return {number}
* @this {Array.<T>}
* @template S
*/
Array.prototype.lowerBound = function(object, comparator) {}
/**
* @param {!S} object
* @param {function(!S,!T):number=} comparator
* @return {number}
* @this {Array.<T>}
* @template S
*/
Array.prototype.upperBound = function(object, comparator) {}
/**
* @param {!S} value
* @param {function(!S,!T):number} comparator
* @return {number}
* @this {Array.<T>}
* @template S
*/
Array.prototype.binaryIndexOf = function(value, comparator) {}
/**
* @param {function(number, number): number} comparator
* @param {number} leftBound
* @param {number} rightBound
* @param {number} sortWindowLeft
* @param {number} sortWindowRight
* @return {!Array.<number>}
* @this {Array.<number>}
*/
Array.prototype.sortRange = function(comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight) {}
/**
* @param {function(!T,!T): number=} comparator
* @return {!Array.<T>}
* @this {Array.<T>}
* @template T
*/
Array.prototype.stableSort = function(comparator) {}
/**
* @this {Array.<number>}
* @param {function(number,number):boolean} comparator
* @param {number} left
* @param {number} right
* @param {number} pivotIndex
* @return {number}
*/
Array.prototype.partition = function(comparator, left, right, pivotIndex) {}
/**
* @this {Array.<number>}
* @param {number} k
* @param {function(number,number):boolean=} comparator
* @return {number}
*/
Array.prototype.qselect = function(k, comparator) {}
/**
* @param {string} field
* @return {!Array.<!T>}
* @this {Array.<!Object.<string,T>>}
* @template T
*/
Array.prototype.select = function(field) {}
/**
* @return {!T|undefined}
* @this {Array.<T>}
* @template T
*/
Array.prototype.peekLast = function() {}
/**
* @param {!Array.<T>} array
* @param {function(T,T):number} comparator
* @return {!Array.<T>}
* @this {!Array.<T>}
* @template T
*/
Array.prototype.intersectOrdered = function(array, comparator) {}
/**
* @param {!Array.<T>} array
* @param {function(T,T):number} comparator
* @return {!Array.<T>}
* @this {!Array.<T>}
* @template T
*/
Array.prototype.mergeOrdered = function(array, comparator) {}
// File System API
/**
* @constructor
*/
function DOMFileSystem() {}
/**
* @type {DirectoryEntry}
*/
DOMFileSystem.prototype.root = null;
/**
* @type {*}
*/
window.domAutomationController;
var DevToolsHost = function() {};
/** @typedef {{type:string, id:(number|undefined),
label:(string|undefined), enabled:(boolean|undefined), checked:(boolean|undefined),
subItems:(!Array.<!DevToolsHost.ContextMenuDescriptor>|undefined)}} */
DevToolsHost.ContextMenuDescriptor;
/**
* @return {number}
*/
DevToolsHost.zoomFactor = function() { }
/**
* @param {string} origin
* @param {string} script
*/
DevToolsHost.setInjectedScriptForOrigin = function(origin, script) { }
/**
* @param {string} text
*/
DevToolsHost.copyText = function(text) { }
/**
* @return {string}
*/
DevToolsHost.platform = function() { }
/**
* @param {number} x
* @param {number} y
* @param {!Array.<!DevToolsHost.ContextMenuDescriptor>} items
* @param {!Document} document
*/
DevToolsHost.showContextMenuAtPoint = function(x, y, items, document) { }
/**
* @param {string} message
*/
DevToolsHost.sendMessageToEmbedder = function(message) { }
/**
* @return {string}
*/
DevToolsHost.getSelectionBackgroundColor = function() { }
/**
* @return {string}
*/
DevToolsHost.getSelectionForegroundColor = function() { }
/**
* @return {boolean}
*/
DevToolsHost.isUnderTest = function() { }
/**
* @return {boolean}
*/
DevToolsHost.isHostedMode = function() { }
/**
* @param {string} fileSystemId
* @param {string} registeredName
* @return {?DOMFileSystem}
*/
DevToolsHost.isolatedFileSystem = function(fileSystemId, registeredName) { }
/**
* @param {!FileSystem} fileSystem
*/
DevToolsHost.upgradeDraggedFileSystemPermissions = function(fileSystem) { }
var WebInspector = function() {}
/** Extensions API */
/** @constructor */
function AuditCategory() {}
/** @constructor */
function AuditResult() {}
/** @constructor */
function EventSink() {}
/** @constructor */
function ExtensionSidebarPane() {}
/** @constructor */
function Panel() {}
/** @constructor */
function PanelWithSidebar() {}
/** @constructor */
function Resource() {}
/** @constructor */
function Timeline() {}
var extensionServer;
/**
* @constructor
*/
function ExtensionDescriptor() {
this.startPage = "";
this.name = "";
}
/**
* @constructor
*/
function ExtensionReloadOptions() {
this.ignoreCache = false;
this.injectedScript = "";
this.userAgent = "";
}
var Adb = {};
/** @typedef {{id: string, name: string, url: string, adbAttachedForeign: boolean}} */
Adb.Page;
/** @typedef {{id: string, adbBrowserChromeVersion: string, compatibleVersion: boolean, adbBrowserName: string, source: string, adbBrowserVersion: string, pages: !Array<!Adb.Page>}} */
Adb.Browser;
/** @typedef {{id: string, adbModel: string, adbSerial: string, browsers: !Array.<!Adb.Browser>, adbPortStatus: !Array.<number>, adbConnected: boolean}} */
Adb.Device;
/** @typedef {!Object.<string, string>} */
Adb.PortForwardingConfig;
/** @typedef {!{port: string, address: string}} */
Adb.PortForwardingRule;
/** @typedef {{ports: !Object<string, number>, browserId: string}} */
Adb.DevicePortForwardingStatus;
/** @typedef {!Object<string, !Adb.DevicePortForwardingStatus>} */
Adb.PortForwardingStatus;
/**
* @constructor
*/
function diff_match_patch()
{
}
diff_match_patch.prototype = {
/**
* @param {string} text1
* @param {string} text2
* @return {!Array.<!{0: number, 1: string}>}
*/
diff_main: function(text1, text2) { }
}
/** @constructor */
function Path2D() {}
Path2D.prototype = {
/**
* @param {number} x
* @param {number} y
* @param {number} w
* @param {number} h
*/
rect: function(x, y, w, h) { },
/**
* @param {number} x
* @param {number} y
*/
moveTo: function(x, y) { },
/**
* @param {number} x
* @param {number} y
*/
lineTo: function(x, y) { }
}
/** @constructor */
var Doc = function() { }
Doc.prototype = {
/** @type {number} */
scrollLeft: 0,
/** @type {number} */
scrollTop: 0
}
/** @constructor */
var CodeMirror = function(element, config) { }
CodeMirror.on = function(obj, type, handler) { }
CodeMirror.prototype = {
/** @type {!Doc} */
doc: null,
addKeyMap: function(map) { },
addLineClass: function(handle, where, cls) { },
/** @param {?Object=} options */
addLineWidget: function(handle, node, options) { },
/**
* @param {string|!Object} spec
* @param {!Object=} options
*/
addOverlay: function(spec, options) { },
addWidget: function(pos, node, scroll, vert, horiz) { },
charCoords: function(pos, mode) { },
clearGutter: function(gutterID) { },
clearHistory: function() { },
clipPos: function(pos) { },
/** @param {string=} mode */
coordsChar: function(coords, mode) { },
/** @param {string=} mode */
cursorCoords: function(start, mode) { },
defaultCharWidth: function() { },
defaultTextHeight: function() { },
deleteH: function(dir, unit) { },
/**
* @param {*=} to
* @param {*=} op
*/
eachLine: function(from, to, op) { },
execCommand: function(cmd) { },
extendSelection: function(from, to) { },
findMarksAt: function(pos) { },
/**
* @param {!CodeMirror.Pos} from
* @param {boolean=} strict
* @param {Object=} config
*/
findMatchingBracket: function(from, strict, config) { },
findPosH: function(from, amount, unit, visually) { },
findPosV: function(from, amount, unit, goalColumn) { },
firstLine: function() { },
focus: function() { },
getAllMarks: function() { },
/** @param {string=} start */
getCursor: function(start) { },
getDoc: function() { },
getGutterElement: function() { },
getHistory: function() { },
getInputField: function(){ },
getLine: function(line) { },
/**
* @return {!{wrapClass: string, height: number}}
*/
getLineHandle: function(line) { },
getLineNumber: function(line) { },
/**
* @return {!{token: function(CodeMirror.StringStream, Object):string}}
*/
getMode: function() { },
getOption: function(option) { },
/** @param {*=} lineSep */
getRange: function(from, to, lineSep) { },
/**
* @return {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}}
*/
getScrollInfo: function() { },
getScrollerElement: function() { },
getSelection: function() { },
getSelections: function() { },
getStateAfter: function(line) { },
getTokenAt: function(pos) { },
/** @param {*=} lineSep */
getValue: function(lineSep) { },
getViewport: function() { },
getWrapperElement: function() { },
hasFocus: function() { },
historySize: function() { },
indentLine: function(n, dir, aggressive) { },
indentSelection: function(how) { },
indexFromPos: function(coords) { },
isClean: function() { },
iterLinkedDocs: function(f) { },
lastLine: function() { },
lineCount: function() { },
lineInfo: function(line) { },
/**
* @param {number} height
* @param {string=} mode
*/
lineAtHeight: function(height, mode) { },
linkedDoc: function(options) { },
listSelections: function() { },
markClean: function() { },
markText: function(from, to, options) { },
moveH: function(dir, unit) { },
moveV: function(dir, unit) { },
off: function(type, f) { },
on: function(type, f) { },
operation: function(f) { },
posFromIndex: function(off) { },
redo: function() { },
refresh: function() { },
removeKeyMap: function(map) { },
removeLine: function(line) { },
removeLineClass: function(handle, where, cls) { },
removeLineWidget: function(widget) { },
removeOverlay: function(spec) { },
/** @param {*=} origin */
replaceRange: function(code, from, to, origin) { },
/**
* @param {string} replacement
* @param {string=} select
*/
replaceSelection: function(replacement, select) { },
/**
* @param {!Array.<string>} textPerSelection
*/
replaceSelections: function(textPerSelection) { },
/** @param {*=} margin */
scrollIntoView: function(pos, margin) { },
scrollTo: function(x, y) { },
setBookmark: function(pos, options) { },
setCursor: function(line, ch, extend) { },
setExtending: function(val) { },
setGutterMarker: function(line, gutterID, value) { },
setHistory: function(histData) { },
setLine: function(line, text) { },
setOption: function(option, value) { },
setSelection: function(anchor, head) { },
/**
* @param {number=} primaryIndex
* @param {?Object=} config
*/
setSelections: function(selections, primaryIndex, config) { },
setSize: function(width, height) { },
setValue: function(code) { },
somethingSelected: function() { },
swapDoc: function(doc) { },
undo: function() { },
unlinkDoc: function(other) { }
}
/** @type {!{cursorDiv: Element}} */
CodeMirror.prototype.display;
/** @type {!Object} */
CodeMirror.Pass;
CodeMirror.showHint = function(codeMirror, hintintFunction) { };
CodeMirror.commands = {};
CodeMirror.modes = {};
CodeMirror.mimeModes = {};
CodeMirror.getMode = function(options, spec) { };
CodeMirror.overlayMode = function(mode1, mode2, squashSpans) { };
CodeMirror.defineMode = function(modeName, modeConstructor) { };
CodeMirror.startState = function(mode) { };
/** @typedef {{canceled: boolean, from: !CodeMirror.Pos, to: !CodeMirror.Pos, text: string, origin: string, cancel: function()}} */
CodeMirror.BeforeChangeObject;
/** @typedef {{from: !CodeMirror.Pos, to: !CodeMirror.Pos, origin: string, text: !Array.<string>, removed: !Array.<string>}} */
CodeMirror.ChangeObject;
/** @constructor */
CodeMirror.Pos = function(line, ch) { }
/** @type {number} */
CodeMirror.Pos.prototype.line;
/** @type {number} */
CodeMirror.Pos.prototype.ch;
/**
* @param {!CodeMirror.Pos} pos1
* @param {!CodeMirror.Pos} pos2
* @return {number}
*/
CodeMirror.cmpPos = function(pos1, pos2) { };
/**
* @param {string} mode
* @param {?} definition
*/
CodeMirror.defineSimpleMode = function(mode, definition) {};
/** @constructor */
CodeMirror.StringStream = function(line)
{
this.pos = 0;
this.start = 0;
}
CodeMirror.StringStream.prototype = {
backUp: function(n) { },
column: function() { },
current: function() { },
eat: function(match) { },
eatSpace: function() { },
eatWhile: function(match) { },
eol: function() { },
indentation: function() { },
/**
* @param {!RegExp|string} pattern
* @param {boolean=} consume
* @param {boolean=} caseInsensitive
*/
match: function(pattern, consume, caseInsensitive) { },
next: function() { },
peek: function() { },
skipTo: function(ch) { },
skipToEnd: function() { },
sol: function() { }
}
/** @type {Object.<string, !Object.<string, string>>} */
CodeMirror.keyMap;
/** @type {{scrollLeft: number, scrollTop: number}} */
CodeMirror.doc;
/** @type {boolean} */
window.dispatchStandaloneTestRunnerMessages;
/**
* @param {*} obj
* @return {boolean}
*/
ArrayBuffer.isView = function(obj) { }
/**
* @param {Array.<Object>} keyframes
* @param {number|Object} timing
* @return {Object}
*/
Element.prototype.animate = function(keyframes, timing) { }
var acorn = {
/**
* @param {string} text
* @param {Object.<string, boolean>} options
* @return {!ESTree.Node}
*/
parse: function(text, options) {},
/**
* @param {string} text
* @param {Object.<string, boolean>} options
* @return {!Acorn.Tokenizer}
*/
tokenizer: function(text, options) {},
tokTypes: {
_true: new Acorn.TokenType(),
_false: new Acorn.TokenType(),
num: new Acorn.TokenType(),
regexp: new Acorn.TokenType(),
string: new Acorn.TokenType(),
name: new Acorn.TokenType(),
eof: new Acorn.TokenType()
}
};
var Acorn = {};
/**
* @constructor
*/
Acorn.Tokenizer = function() {
/** @type {function():!Acorn.Token} */
this.getToken;
}
/**
* @constructor
*/
Acorn.TokenType = function() {
/** @type {string} */
this.label;
/** @type {(string|undefined)} */
this.keyword;
}
/**
* @typedef {{type: !Acorn.TokenType, value: string, start: number, end: number}}
*/
Acorn.Token;
/**
* @typedef {{type: string, value: string, start: number, end: number}}
*/
Acorn.Comment;
/**
* @typedef {(!Acorn.Token|!Acorn.Comment)}
*/
Acorn.TokenOrComment;
var ESTree = {};
/**
* @constructor
*/
ESTree.Node = function()
{
/** @type {number} */
this.start;
/** @type {number} */
this.end;
/** @type {string} */
this.type;
/** @type {(!ESTree.Node|undefined)} */
this.body;
/** @type {(!Array.<!ESTree.Node>|undefined)} */
this.declarations;
/** @type {(!Array.<!ESTree.Node>|undefined)} */
this.properties;
/** @type {(!ESTree.Node|undefined)} */
this.init;
/** @type {(!Array.<!ESTree.Node>|undefined)} */
this.params;
/** @type {(string|undefined)} */
this.name;
/** @type {(?ESTree.Node|undefined)} */
this.id;
}
/**
* @extends {ESTree.Node}
* @constructor
*/
ESTree.TemplateLiteralNode = function()
{
/** @type {!Array.<!ESTree.Node>} */
this.quasis;
/** @type {!Array.<!ESTree.Node>} */
this.expressions;
}
|
| 1 2 3 4 5 6 7 8 9 10 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Release build has Runtime.js bundled. if (!self.Runtime) self.importScripts("Runtime.js"); Runtime.startWorker("heap_snapshot_worker"); |
| 1 2 3 4 5 6 7 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Runtime.startApplication("inspector");
|
| 1 2 3 4 5 6 7 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Runtime.startApplication("toolbox");
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AccessibilityModel.js | 14.29% | (2 / 14) | 0% | (0 / 6) | 0% | (0 / 4) | 14.29% | (2 / 14) | |
| AccessibilityNodeView.js | 1.32% | (4 / 303) | 0% | (0 / 108) | 0% | (0 / 30) | 1.33% | (4 / 301) | |
| AccessibilitySidebarView.js | 2.75% | (3 / 109) | 0% | (0 / 40) | 0% | (0 / 18) | 2.75% | (3 / 109) | |
| AccessibilityStrings.js | 25% | (1 / 4) | 100% | (0 / 0) | 100% | (0 / 0) | 25% | (1 / 4) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 2 1 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.AccessibilityModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target);
this._agent = target.accessibilityAgent();
};
WebInspector.AccessibilityModel.prototype = {
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {!Promise.<?AccessibilityAgent.AXNode>}
*/
getAXNode: function(nodeId)
{
/**
* @param {?string} error
* @param {!AccessibilityAgent.AXNode=} value
*/
function parsePayload(error, value)
{
if (error)
console.error("AccessibilityAgent.getAXNode(): " + error);
return value || null;
}
return this._agent.getAXNode(nodeId, parsePayload);
},
__proto__: WebInspector.SDKModel.prototype
}
WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel");
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.AccessibilityModel}
*/
WebInspector.AccessibilityModel.fromTarget = function(target)
{
if (!target[WebInspector.AccessibilityModel._symbol])
target[WebInspector.AccessibilityModel._symbol] = new WebInspector.AccessibilityModel(target);
return target[WebInspector.AccessibilityModel._symbol];
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | 2 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.AccessibilitySubPane}
*/
WebInspector.AXNodeSubPane = function()
{
WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("Accessibility Node"));
this._noNodeInfo = this.createInfo(WebInspector.UIString("No accessibility node"));
this._ignoredInfo = this.createInfo(WebInspector.UIString("Accessibility node not exposed"), "ax-ignored-info hidden");
this._treeOutline = this.createTreeOutline();
this._ignoredReasonsTree = this.createTreeOutline();
};
WebInspector.AXNodeSubPane.prototype = {
/**
* @param {?AccessibilityAgent.AXNode} axNode
* @override
*/
setAXNode: function(axNode)
{
if (this._axNode === axNode)
return;
this._axNode = axNode;
var treeOutline = this._treeOutline;
treeOutline.removeChildren();
var ignoredReasons = this._ignoredReasonsTree;
ignoredReasons.removeChildren();
var target = this.node().target();
if (!axNode) {
treeOutline.element.classList.add("hidden");
this._ignoredInfo.classList.add("hidden");
ignoredReasons.element.classList.add("hidden");
this._noNodeInfo.classList.remove("hidden");
this.element.classList.add("ax-ignored-node-pane");
return;
} else if (axNode.ignored) {
this._noNodeInfo.classList.add("hidden");
treeOutline.element.classList.add("hidden");
this.element.classList.add("ax-ignored-node-pane");
this._ignoredInfo.classList.remove("hidden");
ignoredReasons.element.classList.remove("hidden");
/**
* @param {!AccessibilityAgent.AXProperty} property
*/
function addIgnoredReason(property)
{
ignoredReasons.appendChild(new WebInspector.AXNodeIgnoredReasonTreeElement(property, axNode, target));
}
var ignoredReasonsArray = /** @type {!Array<!AccessibilityAgent.AXProperty>} */(axNode.ignoredReasons);
for (var reason of ignoredReasonsArray)
addIgnoredReason(reason);
if (!ignoredReasons.firstChild())
ignoredReasons.element.classList.add("hidden");
return;
}
this.element.classList.remove("ax-ignored-node-pane");
this._ignoredInfo.classList.add("hidden");
ignoredReasons.element.classList.add("hidden");
this._noNodeInfo.classList.add("hidden");
treeOutline.element.classList.remove("hidden");
/**
* @param {!AccessibilityAgent.AXProperty} property
*/
function addProperty(property)
{
treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property, target));
}
for (var propertyName of ["name", "description", "help", "value"]) {
if (propertyName in axNode) {
var defaultProperty = /** @type {!AccessibilityAgent.AXProperty} */ ({name: propertyName, value: axNode[propertyName]});
addProperty(defaultProperty);
}
}
var roleProperty = /** @type {!AccessibilityAgent.AXProperty} */ ({name: "role", value: axNode.role});
addProperty(roleProperty);
var propertyMap = {};
var propertiesArray = /** @type {!Array.<!AccessibilityAgent.AXProperty>} */ (axNode.properties);
for (var property of propertiesArray)
propertyMap[property.name] = property;
for (var propertySet of [AccessibilityAgent.AXWidgetAttributes, AccessibilityAgent.AXWidgetStates, AccessibilityAgent.AXGlobalStates, AccessibilityAgent.AXLiveRegionAttributes, AccessibilityAgent.AXRelationshipAttributes]) {
for (var propertyKey in propertySet) {
var property = propertySet[propertyKey];
if (property in propertyMap)
addProperty(propertyMap[property]);
}
}
},
__proto__: WebInspector.AccessibilitySubPane.prototype
};
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.Target} target
*/
WebInspector.AXNodePropertyTreeElement = function(target)
{
this._target = target;
// Pass an empty title, the title gets made later in onattach.
TreeElement.call(this, "");
};
/**
* @param {?AccessibilityAgent.AXValueType} type
* @param {string} value
* @return {!Element}
*/
WebInspector.AXNodePropertyTreeElement.createSimpleValueElement = function(type, value)
{
var valueElement;
var AXValueType = AccessibilityAgent.AXValueType;
if (!type || type === AXValueType.ValueUndefined || type === AXValueType.ComputedString)
valueElement = createElement("span");
else
valueElement = createElementWithClass("span", "monospace");
var valueText;
if (type === AXValueType.String || type === AXValueType.ComputedString || type === AXValueType.IdrefList || type === AXValueType.Idref) {
// Render \n as a nice unicode cr symbol.
valueText = value.replace(/\n/g, "\u21B5");
valueElement._originalTextContent = value;
} else {
valueText = String(value);
}
if (type && type in WebInspector.AXNodePropertyTreeElement.TypeStyles)
valueElement.classList.add(WebInspector.AXNodePropertyTreeElement.TypeStyles[type]);
valueElement.setTextContentTruncatedIfNeeded(valueText || "");
valueElement.title = String(value) || "";
return valueElement;
};
/**
* @param {string} tooltip
* @return {!Element}
*/
WebInspector.AXNodePropertyTreeElement.createExclamationMark = function(tooltip)
{
var exclamationElement = createElement("label", "dt-icon-label");
exclamationElement.type = "warning-icon";
exclamationElement.title = tooltip;
return exclamationElement;
};
/** @type {!Object<string, string>} */
WebInspector.AXNodePropertyTreeElement.TypeStyles = {
attribute: "ax-value-string",
boolean: "object-value-boolean",
booleanOrUndefined: "object-value-boolean",
computedString: "ax-readable-string",
idref: "ax-value-string",
idrefList: "ax-value-string",
integer: "object-value-number",
internalRole: "ax-internal-role",
number: "ax-value-number",
role: "ax-role",
string: "ax-value-string",
tristate: "object-value-boolean",
valueUndefined: "ax-value-undefined"
};
/** @type {!Set.<!AccessibilityAgent.AXValueType>} */
WebInspector.AXNodePropertyTreeElement.StringProperties = new Set([
AccessibilityAgent.AXValueType.String,
AccessibilityAgent.AXValueType.ComputedString,
AccessibilityAgent.AXValueType.IdrefList,
AccessibilityAgent.AXValueType.Idref
]);
WebInspector.AXNodePropertyTreeElement.prototype = {
/**
* @param {string} name
*/
appendNameElement: function(name)
{
var nameElement = createElement("span");
var AXAttributes = WebInspector.AccessibilityStrings.AXAttributes;
if (name in AXAttributes) {
nameElement.textContent = WebInspector.UIString(AXAttributes[name].name);
nameElement.title = AXAttributes[name].description;
nameElement.classList.add("ax-readable-name");
} else {
nameElement.textContent = name;
nameElement.classList.add("ax-name");
nameElement.classList.add("monospace");
}
this.listItemElement.appendChild(nameElement);
},
/**
* @param {!AccessibilityAgent.AXValue} value
*/
appendValueElement: function(value)
{
var AXValueType = AccessibilityAgent.AXValueType;
if (value.type === AXValueType.Idref || value.type === AXValueType.Node ||
value.type === AXValueType.IdrefList || value.type === AXValueType.NodeList) {
this.appendRelatedNodeListValueElement(value);
return;
} else if (value.sources) {
var sources = value.sources;
for (var i = 0; i < sources.length; i++) {
var source = sources[i];
var child = new WebInspector.AXValueSourceTreeElement(source, this._target);
this.appendChild(child);
}
this.expand();
}
var isStringProperty = WebInspector.AXNodePropertyTreeElement.StringProperties.has(value.type);
if (isStringProperty)
this.listItemElement.createTextChild("\"");
this.listItemElement.appendChild(WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(value.type, String(value.value)));
if (isStringProperty)
this.listItemElement.createTextChild("\"");
},
/**
* @param {!AccessibilityAgent.AXRelatedNode} relatedNode
* @param {number} index
*/
appendRelatedNode: function(relatedNode, index)
{
if (index > 0)
this.listItemElement.createTextChild(",\u00a0");
var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNode.backendNodeId);
var linkedNode = new WebInspector.AXRelatedNodeElement({ deferredNode: deferredNode }, relatedNode);
this.listItemElement.appendChild(linkedNode.render());
},
/**
* @param {!AccessibilityAgent.AXValue} value
*/
appendRelatedNodeListValueElement: function(value)
{
value.relatedNodes.forEach(this.appendRelatedNode, this);
},
__proto__: TreeElement.prototype
};
/**
* @constructor
* @extends {WebInspector.AXNodePropertyTreeElement}
* @param {!AccessibilityAgent.AXProperty} property
* @param {!WebInspector.Target} target
*/
WebInspector.AXNodePropertyTreePropertyElement = function(property, target)
{
this._property = property;
this.toggleOnClick = true;
this.selectable = false;
WebInspector.AXNodePropertyTreeElement.call(this, target);
this.listItemElement.classList.add("property");
}
WebInspector.AXNodePropertyTreePropertyElement.prototype = {
/**
* @override
*/
onattach: function()
{
this._update();
},
_update: function()
{
this.listItemElement.removeChildren();
this.appendNameElement(this._property.name);
this.listItemElement.createChild("span", "separator").textContent = ":\u00A0";
this.appendValueElement(this._property.value);
},
__proto__: WebInspector.AXNodePropertyTreeElement.prototype
};
/**
* @constructor
* @extends {WebInspector.AXNodePropertyTreeElement}
* @param {!AccessibilityAgent.AXValueSource} source
* @param {!WebInspector.Target} target
*/
WebInspector.AXValueSourceTreeElement = function(source, target)
{
this._source = source;
WebInspector.AXNodePropertyTreeElement.call(this, target);
this.selectable = false;
}
WebInspector.AXValueSourceTreeElement.prototype = {
/**
* @override
*/
onattach: function()
{
this._update();
},
/**
* @param {!AccessibilityAgent.AXRelatedNode} relatedNode
* @param {number} index
* @override
*/
appendRelatedNode: function(relatedNode, index)
{
var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNode.backendNodeId);
var nodeTreeElement = new WebInspector.AXRelatedNodeSourceTreeElement({ deferredNode: deferredNode }, relatedNode);
this.appendChild(nodeTreeElement);
},
/**
* @param {!AccessibilityAgent.AXRelatedNode} relatedNode
* @param {number} index
* @param {string} idref
*/
appendRelatedNodeWithIdref: function(relatedNode, index, idref)
{
var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNode.backendNodeId);
var nodeTreeElement = new WebInspector.AXRelatedNodeSourceTreeElement({ deferredNode: deferredNode, idref: idref }, relatedNode);
this.appendChild(nodeTreeElement);
},
/**
* @param {!AccessibilityAgent.AXValue} value
*/
appendIDRefValueElement: function(value)
{
var relatedNodes = value.relatedNodes;
var numNodes = relatedNodes.length;
var valueElement;
var idrefs = value.value.trim().split(/\s+/);
if (idrefs.length === 1) {
var idref = idrefs[0];
var matchingNode = relatedNodes.find(node => node.idref === idref);
if (matchingNode) {
this.appendRelatedNodeWithIdref(matchingNode, 0, idref);
} else {
this.listItemElement.appendChild(new WebInspector.AXRelatedNodeElement({ idref: idref }).render());
}
} else {
// TODO(aboxhall): exclamation mark if not idreflist type
for (var i = 0; i < idrefs.length; ++i) {
var idref = idrefs[i];
var matchingNode = relatedNodes.find(node => node.idref === idref);
if (matchingNode) {
this.appendRelatedNodeWithIdref(matchingNode, i, idref);
} else {
this.appendChild(new WebInspector.AXRelatedNodeSourceTreeElement({ idref: idref }));
}
}
}
},
/**
* @param {!AccessibilityAgent.AXValue} value
* @override
*/
appendRelatedNodeListValueElement: function(value)
{
var relatedNodes = value.relatedNodes;
var numNodes = relatedNodes.length;
if (value.type === AccessibilityAgent.AXValueType.IdrefList ||
value.type === AccessibilityAgent.AXValueType.Idref) {
this.appendIDRefValueElement(value);
} else {
WebInspector.AXNodePropertyTreeElement.prototype.appendRelatedNodeListValueElement.call(this, value);
}
if (numNodes <= 3)
this.expand();
else
this.collapse();
},
/**
* @param {!AccessibilityAgent.AXValueSource} source
*/
appendSourceNameElement: function(source)
{
var nameElement = createElement("span");
var AXValueSourceType = AccessibilityAgent.AXValueSourceType;
var type = source.type;
var name;
switch (type) {
case AXValueSourceType.Attribute:
case AXValueSourceType.Placeholder:
case AXValueSourceType.RelatedElement:
if (source.nativeSource) {
var AXNativeSourceTypes = WebInspector.AccessibilityStrings.AXNativeSourceTypes;
var nativeSource = source.nativeSource;
nameElement.textContent = WebInspector.UIString(AXNativeSourceTypes[nativeSource].name);
nameElement.title = WebInspector.UIString(AXNativeSourceTypes[nativeSource].description);
nameElement.classList.add("ax-readable-name");
break;
}
nameElement.textContent = source.attribute;
nameElement.classList.add("ax-name");
nameElement.classList.add("monospace");
break;
default:
var AXSourceTypes = WebInspector.AccessibilityStrings.AXSourceTypes;
if (type in AXSourceTypes) {
nameElement.textContent = WebInspector.UIString(AXSourceTypes[type].name);
nameElement.title = WebInspector.UIString(AXSourceTypes[type].description);
nameElement.classList.add("ax-readable-name");
} else {
console.warn(type, "not in AXSourceTypes");
nameElement.textContent = WebInspector.UIString(type);
}
}
this.listItemElement.appendChild(nameElement);
},
_update: function()
{
this.listItemElement.removeChildren();
if (this._source.invalid) {
var exclamationMark = WebInspector.AXNodePropertyTreeElement.createExclamationMark(WebInspector.UIString("Invalid source."));
this.listItemElement.appendChild(exclamationMark);
this.listItemElement.classList.add("ax-value-source-invalid");
} else if (this._source.superseded) {
this.listItemElement.classList.add("ax-value-source-unused");
}
this.appendSourceNameElement(this._source);
this.listItemElement.createChild("span", "separator").textContent = ":\u00a0";
if (this._source.attributeValue) {
this.appendValueElement(this._source.attributeValue);
this.listItemElement.createTextChild("\u00a0");
} else if (this._source.nativeSourceValue) {
this.appendValueElement(this._source.nativeSourceValue);
this.listItemElement.createTextChild("\u00a0");
}
if (this._source.value) {
this.appendValueElement(this._source.value);
if (this._source.superseded)
this.listItemElement.classList.add("ax-value-source-superseded");
} else {
var valueElement = WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(AccessibilityAgent.AXValueType.ValueUndefined, WebInspector.UIString("Not specified"));
this.listItemElement.appendChild(valueElement);
this.listItemElement.classList.add("ax-value-source-unused");
}
},
__proto__: WebInspector.AXNodePropertyTreeElement.prototype
};
/**
* @constructor
* @param {{deferredNode: (!WebInspector.DeferredDOMNode|undefined), idref: (string|undefined)}} node
* @param {!AccessibilityAgent.AXRelatedNode=} value
* @extends {TreeElement}
*/
WebInspector.AXRelatedNodeSourceTreeElement = function(node, value)
{
this._value = value;
this._axRelatedNodeElement = new WebInspector.AXRelatedNodeElement(node, value);
TreeElement.call(this, "");
this.selectable = false;
};
WebInspector.AXRelatedNodeSourceTreeElement.prototype = {
/**
* @override
*/
onattach: function()
{
this.listItemElement.appendChild(this._axRelatedNodeElement.render());
if (!this._value)
return;
this.listItemElement.createTextChild("\u00a0\"");
if (this._value.text)
this.listItemElement.appendChild(WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString, this._value.text));
this.listItemElement.createTextChild("\"");
},
__proto__: TreeElement.prototype
};
/**
* @constructor
* @param {{deferredNode: (!WebInspector.DeferredDOMNode|undefined), idref: (string|undefined)}} node
* @param {!AccessibilityAgent.AXRelatedNode=} value
*/
WebInspector.AXRelatedNodeElement = function(node, value)
{
this._deferredNode = node.deferredNode;
this._idref = node.idref;
this._value = value;
};
WebInspector.AXRelatedNodeElement.prototype = {
/**
* @return {!Element}
*/
render: function()
{
var element = createElement("span");
var valueElement;
/**
* @param {?WebInspector.DOMNode} node
* @this {!WebInspector.AXRelatedNodeElement}
*/
function onNodeResolved(node)
{
valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node, this._idref));
}
if (this._deferredNode) {
valueElement = createElement("span");
element.appendChild(valueElement);
this._deferredNode.resolve(onNodeResolved.bind(this));
} else if (this._idref) {
element.classList.add("invalid");
valueElement = WebInspector.AXNodePropertyTreeElement.createExclamationMark(WebInspector.UIString("No node with this ID."));
valueElement.createTextChild(this._idref);
element.appendChild(valueElement);
}
return element;
}
};
/**
* @constructor
* @extends {WebInspector.AXNodePropertyTreeElement}
* @param {!AccessibilityAgent.AXProperty} property
* @param {?AccessibilityAgent.AXNode} axNode
* @param {!WebInspector.Target} target
*/
WebInspector.AXNodeIgnoredReasonTreeElement = function(property, axNode, target)
{
this._property = property;
this._axNode = axNode;
WebInspector.AXNodePropertyTreeElement.call(this, target);
this.toggleOnClick = true;
this.selectable = false;
}
WebInspector.AXNodeIgnoredReasonTreeElement.prototype = {
/**
* @override
*/
onattach: function()
{
this.listItemElement.removeChildren();
this._reasonElement = WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement(this._property.name, this._axNode);
this.listItemElement.appendChild(this._reasonElement);
var value = this._property.value;
if (value.type === AccessibilityAgent.AXValueType.Idref)
this.appendRelatedNodeListValueElement(value);
},
__proto__: WebInspector.AXNodePropertyTreeElement.prototype
};
/**
* @param {?string} reason
* @param {?AccessibilityAgent.AXNode} axNode
* @return {?Element}
*/
WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement = function(reason, axNode)
{
var reasonElement = null;
switch(reason) {
case "activeModalDialog":
reasonElement = WebInspector.formatLocalized("Element is hidden by active modal dialog:\u00a0", []);
break;
case "ancestorDisallowsChild":
reasonElement = WebInspector.formatLocalized("Element is not permitted as child of ", []);
break;
// http://www.w3.org/TR/wai-aria/roles#childrenArePresentational
case "ancestorIsLeafNode":
reasonElement = WebInspector.formatLocalized("Ancestor's children are all presentational:\u00a0", []);
break;
case "ariaHidden":
var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
reasonElement = WebInspector.formatLocalized("Element is %s.", [ ariaHiddenSpan ]);
break;
case "ariaHiddenRoot":
var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
var trueSpan = createElement("span", "source-code").textContent = "true";
reasonElement = WebInspector.formatLocalized("%s is %s on ancestor:\u00a0", [ ariaHiddenSpan, trueSpan ]);
break;
case "emptyAlt":
reasonElement = WebInspector.formatLocalized("Element has empty alt text.", []);
break;
case "emptyText":
reasonElement = WebInspector.formatLocalized("No text content.", []);
break;
case "inert":
reasonElement = WebInspector.formatLocalized("Element is inert.", []);
break;
case "inheritsPresentation":
reasonElement = WebInspector.formatLocalized("Element inherits presentational role from\u00a0", []);
break;
case "labelContainer":
reasonElement = WebInspector.formatLocalized("Part of label element:\u00a0", []);
break;
case "labelFor":
reasonElement = WebInspector.formatLocalized("Label for\u00a0", []);
break;
case "notRendered":
reasonElement = WebInspector.formatLocalized("Element is not rendered.", []);
break;
case "notVisible":
reasonElement = WebInspector.formatLocalized("Element is not visible.", []);
break;
case "presentationalRole":
var rolePresentationSpan = createElement("span", "source-code").textContent = "role=" + axNode.role.value;
reasonElement = WebInspector.formatLocalized("Element has %s.", [ rolePresentationSpan ]);
break;
case "probablyPresentational":
reasonElement = WebInspector.formatLocalized("Element is presentational.", []);
break;
case "staticTextUsedAsNameFor":
reasonElement = WebInspector.formatLocalized("Static text node is used as name for\u00a0", []);
break;
case "uninteresting":
reasonElement = WebInspector.formatLocalized("Element not interesting for accessibility.", []);
break;
}
if (reasonElement)
reasonElement.classList.add("ax-reason");
return reasonElement;
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | 2 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
*/
WebInspector.AccessibilitySidebarView = function()
{
WebInspector.ThrottledWidget.call(this);
this._computedTextSubPane = null;
this._axNodeSubPane = null;
this._node = null;
this._sidebarPaneStack = null;
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._pullNode, this);
this._pullNode();
}
WebInspector.AccessibilitySidebarView.prototype = {
/**
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @override
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
/**
* @param {?AccessibilityAgent.AXNode} accessibilityNode
* @this {WebInspector.AccessibilitySidebarView}
*/
function accessibilityNodeCallback(accessibilityNode)
{
if (this._computedTextSubPane)
this._computedTextSubPane.setAXNode(accessibilityNode);
if (this._axNodeSubPane)
this._axNodeSubPane.setAXNode(accessibilityNode);
}
var node = this.node();
return WebInspector.AccessibilityModel.fromTarget(node.target()).getAXNode(node.id)
.then(accessibilityNodeCallback.bind(this))
},
/**
* @override
*/
wasShown: function()
{
WebInspector.ThrottledWidget.prototype.wasShown.call(this);
if (!this._sidebarPaneStack) {
this._computedTextSubPane = new WebInspector.AXComputedTextSubPane();
this._computedTextSubPane.setNode(this.node());
this._computedTextSubPane.show(this.element);
this._computedTextSubPane.expand();
this._axNodeSubPane = new WebInspector.AXNodeSubPane();
this._axNodeSubPane.setNode(this.node());
this._axNodeSubPane.show(this.element);
this._axNodeSubPane.expand();
this._sidebarPaneStack = new WebInspector.SidebarPaneStack();
this._sidebarPaneStack.element.classList.add("flex-auto");
this._sidebarPaneStack.show(this.element);
this._sidebarPaneStack.addPane(this._computedTextSubPane);
this._sidebarPaneStack.addPane(this._axNodeSubPane);
}
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrModified, this._onAttrChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrRemoved, this._onAttrChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
},
/**
* @override
*/
willHide: function()
{
WebInspector.targetManager.removeModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrModified, this._onAttrChange, this);
WebInspector.targetManager.removeModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrRemoved, this._onAttrChange, this);
WebInspector.targetManager.removeModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
WebInspector.targetManager.removeModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
},
_pullNode: function()
{
this._node = WebInspector.context.flavor(WebInspector.DOMNode);
if (this._computedTextSubPane)
this._computedTextSubPane.setNode(this._node);
if (this._axNodeSubPane)
this._axNodeSubPane.setNode(this._node);
this.update();
},
/**
* @param {!WebInspector.Event} event
*/
_onAttrChange: function(event)
{
if (!this.node())
return;
var node = event.data.node;
if (this.node() !== node)
return;
this.update();
},
/**
* @param {!WebInspector.Event} event
*/
_onNodeChange: function(event)
{
if (!this.node())
return;
var node = event.data;
if (this.node() !== node)
return;
this.update();
},
__proto__: WebInspector.ThrottledWidget.prototype
};
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {string} name
*/
WebInspector.AccessibilitySubPane = function(name)
{
WebInspector.SidebarPane.call(this, name);
this._axNode = null;
this.registerRequiredCSS("accessibility/accessibilityNode.css");
}
WebInspector.AccessibilitySubPane.prototype = {
/**
* @param {?AccessibilityAgent.AXNode} axNode
* @protected
*/
setAXNode: function(axNode)
{
},
/**
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @param {?WebInspector.DOMNode} node
*/
setNode: function(node)
{
this._node = node;
},
/**
* @param {string} textContent
* @param {string=} className
* @return {!Element}
*/
createInfo: function(textContent, className)
{
var classNameOrDefault = className || "info";
var info = this.element.createChild("div", classNameOrDefault);
info.textContent = textContent;
return info;
},
/**
* @return {!TreeOutline}
*/
createTreeOutline: function()
{
var treeOutline = new TreeOutlineInShadow();
treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css");
treeOutline.registerRequiredCSS("components/objectValue.css");
treeOutline.element.classList.add("hidden");
this.element.appendChild(treeOutline.element);
return treeOutline;
},
__proto__: WebInspector.SidebarPane.prototype
}
/**
* @constructor
* @extends {WebInspector.AccessibilitySubPane}
*/
WebInspector.AXComputedTextSubPane = function()
{
WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("Computed Text"));
this._computedTextElement = this.element.createChild("div", "ax-computed-text hidden");
this._noTextInfo = this.createInfo(WebInspector.UIString("Node has no text alternative."));
this._treeOutline = this.createTreeOutline();
};
WebInspector.AXComputedTextSubPane.prototype = {
/**
* @param {?AccessibilityAgent.AXNode} axNode
* @override
*/
setAXNode: function(axNode)
{
if (this._axNode === axNode)
return;
this._axNode = axNode;
var treeOutline = this._treeOutline;
treeOutline.removeChildren();
var target = this.node().target();
if (!axNode || axNode.ignored) {
this._computedTextElement.classList.add("hidden");
treeOutline.element.classList.add("hidden");
this._noTextInfo.classList.remove("hidden");
return;
}
this._computedTextElement.removeChildren();
// TODO(aboxhall): include contents where appropriate (requires protocol change)
this._computedTextElement.classList.toggle("hidden", !axNode.name || !axNode.name.value);
if (axNode.name && axNode.name.value)
this._computedTextElement.createChild("div").textContent = axNode.name.value;
var foundProperty = false;
/**
* @param {!AccessibilityAgent.AXProperty} property
*/
function addProperty(property)
{
foundProperty = true;
treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property, target));
}
if (axNode.value && axNode.value.type === AccessibilityAgent.AXValueType.String)
addProperty(/** @type {!AccessibilityAgent.AXProperty} */ ({name: "value", value: axNode.value}));
var propertiesArray = /** @type {!Array.<!AccessibilityAgent.AXProperty> } */ (axNode.properties);
for (var property of propertiesArray) {
if (property.name == AccessibilityAgent.AXWidgetAttributes.Valuetext) {
addProperty(property);
break;
}
}
treeOutline.element.classList.toggle("hidden", !foundProperty)
this._noTextInfo.classList.toggle("hidden", !treeOutline.element.classList.contains("hidden") || !this._computedTextElement.classList.contains("hidden"));
},
__proto__: WebInspector.AccessibilitySubPane.prototype
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.AccessibilityStrings = {};
WebInspector.AccessibilityStrings.AXAttributes = {
"disabled" : {
name : "Disabled",
description : "If true, this element currently cannot be interacted with.",
group : "AXGlobalStates"
},
"invalid" : {
name : "Invalid user entry",
description : "If true, this element's user-entered value does not conform to validation requirement.",
group : "AXGlobalStates"
},
"live" : {
name : "Live region",
description : "Whether and what priority of live updates may be expected for this element.",
group : "AXLiveRegionAttributes"
},
"atomic" : {
name : "Atomic (live regions)",
description : "If this element may receive live updates, whether the entire live region should be presented to the user on changes, or only changed nodes.",
group : "AXLiveRegionAttributes"
},
"relevant" : {
name : "Relevant (live regions)",
description : "If this element may receive live updates, what type of updates should trigger a notification.",
group : "AXLiveRegionAttributes"
},
"busy" : {
name : "Busy (live regions)",
description : "Whether this element or its subtree are currently being updated (and thus may be in an inconsistent state).",
group : "AXLiveRegionAttributes"
},
"root" : {
name : "Live region root",
description : "If this element may receive live updates, the root element of the containing live region.",
group : "AXLiveRegionAttributes"
},
"autocomplete" : {
name : "Has autocomplete",
description : "Whether and what type of autocomplete suggestions are currently provided by this element.",
group : "AXWidgetAttributes"
},
"haspopup" : {
name : "Has popup",
description : "Whether this element has caused some kind of pop-up (such as a menu) to appear.",
group : "AXWidgetAttributes"
},
"level" : {
name : "Level",
description : "The hierarchical level of this element.",
group : "AXWidgetAttributes"
},
"multiselectable" : {
name : "Multi-selectable",
description : "Whether a user may select more than one option from this widget.",
group : "AXWidgetAttributes"
},
"orientation" : {
name : "Orientation",
description : "Whether this linear element's orientation is horizontal or vertical.",
group : "AXWidgetAttributes"
},
"multiline" : {
name : "Multi-line",
description : "Whether this textbox may have more than one line.",
group : "AXWidgetAttributes"
},
"readonly" : {
name : "Read-only",
description : "If true, this element may be interacted with, but its value cannot be changed.",
group : "AXWidgetAttributes"
},
"required" : {
name : "Required",
description : "Whether this element is a required field in a form.",
group : "AXWidgetAttributes"
},
"valuemin" : {
name : "Minimum value",
description : "For a range widget, the minimum allowed value.",
group : "AXWidgetAttributes"
},
"valuemax" : {
name : "Maximum value",
description : "For a range widget, the maximum allowed value.",
group : "AXWidgetAttributes"
},
"valuetext" : {
name : "Value description",
description : "A human-readable version of the value of a range widget (where necessary).",
group : "AXWidgetAttributes"
},
"checked" : {
name : "Checked",
description : "Whether this checkbox, radio button or tree item is checked, unchecked, or mixed (e.g. has both checked and un-checked children).",
group : "AXWidgetStates"
},
"expanded" : {
name : "Expanded",
description : "Whether this element, or another grouping element it controls, is expanded.",
group : "AXWidgetStates"
},
"pressed" : {
name : "Pressed",
description : "Whether this toggle button is currently in a pressed state.",
group : "AXWidgetStates"
},
"selected" : {
name : "Selected",
description : "Whether the option represented by this element is currently selected.",
group : "AXWidgetStates"
},
"activedescendant" : {
name : "Active descendant",
description : "The descendant of this element which is active; i.e. the element to which focus should be delegated.",
group : "AXRelationshipAttributes"
},
"flowto" : {
name : "Flows to",
description : "Element to which the user may choose to navigate after this one, instead of the next element in the DOM order.",
group : "AXRelationshipAttributes"
},
"controls" : {
name : "Controls",
description : "Element or elements whose content or presence is/are controlled by this widget.",
group : "AXRelationshipAttributes"
},
"describedby" : {
name : "Described by",
description : "Element or elements which form the description of this element.",
group : "AXRelationshipAttributes"
},
"labelledby" : {
name : "Labeled by",
description : "Element or elements which may form the name of this element.",
group : "AXRelationshipAttributes"
},
"owns" : {
name : "Owns",
description : "Element or elements which should be considered descendants of this element, despite not being descendants in the DOM.",
group : "AXRelationshipAttributes"
},
"name": {
name : "Name",
description : "The computed name of this element.",
group : "Default"
},
"role": {
name: "Role",
description: "Indicates the purpose of this element, such as a user interface idiom for a widget, or structural role within a document.",
group: "Default"
},
"value": {
name: "Value",
description: "The value of this element; this may be user-provided or developer-provided, depending on the element.",
group: "Default"
},
"help": {
name: "Help",
description: "The computed help text for this element.",
group: "Default"
},
"description": {
name: "Description",
description: "The accessible description for this element.",
group: "Default"
}
};
WebInspector.AccessibilityStrings.AXSourceTypes = {
"attribute": {
name: "From attribute",
description: "Value from attribute."
},
"implicit": {
name: "Implicit",
description: "Implicit value.",
},
"style": {
name: "From style",
description: "Value from style."
},
"contents": {
name: "Contents",
description: "Value from element contents."
},
"placeholder": {
name: "From placeholder attribute",
description: "Value from placeholder attribute."
},
"relatedElement": {
name: "Related element",
description: "Value from related element."
}
}
WebInspector.AccessibilityStrings.AXNativeSourceTypes = {
"figcaption": {
name: "From caption",
description: "Value from figcaption element."
},
"label": {
name: "From label",
description: "Value from label element."
},
"labelfor": {
name: "From label (for)",
description: "Value from label element with for= attribute."
},
"labelwrapped": {
name: "From label (wrapped)",
description: "Value from label element wrapped."
},
"tablecaption": {
name: "From caption",
description: "Value from table caption."
},
"other": {
name: "From native HTML",
description: "Value from native HTML (unknown source)."
},
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| acorn.js | 19.3% | (387 / 2005) | 1.82% | (23 / 1267) | 15.08% | (30 / 199) | 21.4% | (368 / 1720) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 | 46 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 1 1 1 1 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 74 1 74 74 74 74 74 74 74 74 74 74 74 74 1 1 11 1 1 1 1 1 1 37 37 37 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | (function(f){Eif(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){Iif(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
// A recursive descent parser operates by defining functions for all
// syntactic elements, and recursively calling those, each function
// advancing the input stream and returning an AST node. Precedence
// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
// instead of `(!x)[1]` is handled by the fact that the parser
// function that parses unary prefix operators is called first, and
// in turn calls the function that parses `[]` subscripts — that
// way, it'll receive the node for `x[1]` already parsed, and wraps
// *that* in the unary operator node.
//
// Acorn uses an [operator precedence parser][opp] to handle binary
// operator precedence, because it is much more compact than using
// the technique outlined above, which uses different, nesting
// functions to specify precedence, for all of the ten binary
// precedence levels that JavaScript defines.
//
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
"use strict";
var _tokentype = _dereq_("./tokentype");
var _state = _dereq_("./state");
var pp = _state.Parser.prototype;
// Check if property name clashes with already added.
// Object/class getters and setters are not allowed to clash —
// either with each other or with an init property — and in
// strict mode, init properties are also not allowed to be repeated.
pp.checkPropClash = function (prop, propHash) {
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) return;
var key = prop.key;var name = undefined;
switch (key.type) {
case "Identifier":
name = key.name;break;
case "Literal":
name = String(key.value);break;
default:
return;
}
var kind = prop.kind;
if (this.options.ecmaVersion >= 6) {
if (name === "__proto__" && kind === "init") {
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
propHash.proto = true;
}
return;
}
name = "$" + name;
var other = propHash[name];
if (other) {
var isGetSet = kind !== "init";
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
} else {
other = propHash[name] = {
init: false,
get: false,
set: false
};
}
other[kind] = true;
};
// ### Expression parsing
// These nest, from the most general expression type at the top to
// 'atomic', nondivisible expression types at the bottom. Most of
// the functions will simply let the function(s) below them parse,
// and, *if* the syntactic construct they handle is present, wrap
// the AST node that the inner parser gave them in another node.
// Parse a full expression. The optional arguments are used to
// forbid the `in` operator (in for loops initalization expressions)
// and provide reference for storing '=' operator inside shorthand
// property assignment in contexts where both object expression
// and object pattern might appear (so it's possible to raise
// delayed syntax error at correct position).
pp.parseExpression = function (noIn, refShorthandDefaultPos) {
var startPos = this.start,
startLoc = this.startLoc;
var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
if (this.type === _tokentype.types.comma) {
var node = this.startNodeAt(startPos, startLoc);
node.expressions = [expr];
while (this.eat(_tokentype.types.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
return this.finishNode(node, "SequenceExpression");
}
return expr;
};
// Parse an assignment expression. This includes applications of
// operators like `+=`.
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
if (this.type == _tokentype.types._yield && this.inGenerator) return this.parseYield();
var failOnShorthandAssign = undefined;
if (!refShorthandDefaultPos) {
refShorthandDefaultPos = { start: 0 };
failOnShorthandAssign = true;
} else {
failOnShorthandAssign = false;
}
var startPos = this.start,
startLoc = this.startLoc;
if (this.type == _tokentype.types.parenL || this.type == _tokentype.types.name) this.potentialArrowAt = this.start;
var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
if (this.type.isAssign) {
var node = this.startNodeAt(startPos, startLoc);
node.operator = this.value;
node.left = this.type === _tokentype.types.eq ? this.toAssignable(left) : left;
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
this.checkLVal(left);
this.next();
node.right = this.parseMaybeAssign(noIn);
return this.finishNode(node, "AssignmentExpression");
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start);
}
return left;
};
// Parse a ternary conditional (`?:`) operator.
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
var startPos = this.start,
startLoc = this.startLoc;
var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
if (this.eat(_tokentype.types.question)) {
var node = this.startNodeAt(startPos, startLoc);
node.test = expr;
node.consequent = this.parseMaybeAssign();
this.expect(_tokentype.types.colon);
node.alternate = this.parseMaybeAssign(noIn);
return this.finishNode(node, "ConditionalExpression");
}
return expr;
};
// Start the precedence parser.
pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
var startPos = this.start,
startLoc = this.startLoc;
var expr = this.parseMaybeUnary(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
};
// Parse binary operators with the operator precedence parsing
// algorithm. `left` is the left-hand side of the operator.
// `minPrec` provides context that allows the function to stop and
// defer further parser to one of its callers when it encounters an
// operator that has a lower precedence than the set it is parsing.
pp.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
var prec = this.type.binop;
if (prec != null && (!noIn || this.type !== _tokentype.types._in)) {
if (prec > minPrec) {
var node = this.startNodeAt(leftStartPos, leftStartLoc);
node.left = left;
node.operator = this.value;
var op = this.type;
this.next();
var startPos = this.start,
startLoc = this.startLoc;
node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn);
this.finishNode(node, op === _tokentype.types.logicalOR || op === _tokentype.types.logicalAND ? "LogicalExpression" : "BinaryExpression");
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
}
}
return left;
};
// Parse unary operators, both prefix and postfix.
pp.parseMaybeUnary = function (refShorthandDefaultPos) {
if (this.type.prefix) {
var node = this.startNode(),
update = this.type === _tokentype.types.incDec;
node.operator = this.value;
node.prefix = true;
this.next();
node.argument = this.parseMaybeUnary();
if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
}
var startPos = this.start,
startLoc = this.startLoc;
var expr = this.parseExprSubscripts(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
while (this.type.postfix && !this.canInsertSemicolon()) {
var node = this.startNodeAt(startPos, startLoc);
node.operator = this.value;
node.prefix = false;
node.argument = expr;
this.checkLVal(expr);
this.next();
expr = this.finishNode(node, "UpdateExpression");
}
return expr;
};
// Parse call, dot, and `[]`-subscript expressions.
pp.parseExprSubscripts = function (refShorthandDefaultPos) {
var startPos = this.start,
startLoc = this.startLoc;
var expr = this.parseExprAtom(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
return this.parseSubscripts(expr, startPos, startLoc);
};
pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
for (;;) {
if (this.eat(_tokentype.types.dot)) {
var node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseIdent(true);
node.computed = false;
base = this.finishNode(node, "MemberExpression");
} else if (this.eat(_tokentype.types.bracketL)) {
var node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseExpression();
node.computed = true;
this.expect(_tokentype.types.bracketR);
base = this.finishNode(node, "MemberExpression");
} else if (!noCalls && this.eat(_tokentype.types.parenL)) {
var node = this.startNodeAt(startPos, startLoc);
node.callee = base;
node.arguments = this.parseExprList(_tokentype.types.parenR, false);
base = this.finishNode(node, "CallExpression");
} else if (this.type === _tokentype.types.backQuote) {
var node = this.startNodeAt(startPos, startLoc);
node.tag = base;
node.quasi = this.parseTemplate();
base = this.finishNode(node, "TaggedTemplateExpression");
} else {
return base;
}
}
};
// Parse an atomic expression — either a single token that is an
// expression, an expression started by a keyword like `function` or
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
// or `{}`.
pp.parseExprAtom = function (refShorthandDefaultPos) {
var node = undefined,
canBeArrow = this.potentialArrowAt == this.start;
switch (this.type) {
case _tokentype.types._super:
if (!this.inFunction) this.raise(this.start, "'super' outside of function or class");
case _tokentype.types._this:
var type = this.type === _tokentype.types._this ? "ThisExpression" : "Super";
node = this.startNode();
this.next();
return this.finishNode(node, type);
case _tokentype.types._yield:
if (this.inGenerator) this.unexpected();
case _tokentype.types.name:
var startPos = this.start,
startLoc = this.startLoc;
var id = this.parseIdent(this.type !== _tokentype.types.name);
if (canBeArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]);
return id;
case _tokentype.types.regexp:
var value = this.value;
node = this.parseLiteral(value.value);
node.regex = { pattern: value.pattern, flags: value.flags };
return node;
case _tokentype.types.num:case _tokentype.types.string:
return this.parseLiteral(this.value);
case _tokentype.types._null:case _tokentype.types._true:case _tokentype.types._false:
node = this.startNode();
node.value = this.type === _tokentype.types._null ? null : this.type === _tokentype.types._true;
node.raw = this.type.keyword;
this.next();
return this.finishNode(node, "Literal");
case _tokentype.types.parenL:
return this.parseParenAndDistinguishExpression(canBeArrow);
case _tokentype.types.bracketL:
node = this.startNode();
this.next();
// check whether this is array comprehension or regular array
if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
return this.parseComprehension(node, false);
}
node.elements = this.parseExprList(_tokentype.types.bracketR, true, true, refShorthandDefaultPos);
return this.finishNode(node, "ArrayExpression");
case _tokentype.types.braceL:
return this.parseObj(false, refShorthandDefaultPos);
case _tokentype.types._function:
node = this.startNode();
this.next();
return this.parseFunction(node, false);
case _tokentype.types._class:
return this.parseClass(this.startNode(), false);
case _tokentype.types._new:
return this.parseNew();
case _tokentype.types.backQuote:
return this.parseTemplate();
default:
this.unexpected();
}
};
pp.parseLiteral = function (value) {
var node = this.startNode();
node.value = value;
node.raw = this.input.slice(this.start, this.end);
this.next();
return this.finishNode(node, "Literal");
};
pp.parseParenExpression = function () {
this.expect(_tokentype.types.parenL);
var val = this.parseExpression();
this.expect(_tokentype.types.parenR);
return val;
};
pp.parseParenAndDistinguishExpression = function (canBeArrow) {
var startPos = this.start,
startLoc = this.startLoc,
val = undefined;
if (this.options.ecmaVersion >= 6) {
this.next();
if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
}
var innerStartPos = this.start,
innerStartLoc = this.startLoc;
var exprList = [],
first = true;
var refShorthandDefaultPos = { start: 0 },
spreadStart = undefined,
innerParenStart = undefined;
while (this.type !== _tokentype.types.parenR) {
first ? first = false : this.expect(_tokentype.types.comma);
if (this.type === _tokentype.types.ellipsis) {
spreadStart = this.start;
exprList.push(this.parseParenItem(this.parseRest()));
break;
} else {
if (this.type === _tokentype.types.parenL && !innerParenStart) {
innerParenStart = this.start;
}
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
}
}
var innerEndPos = this.start,
innerEndLoc = this.startLoc;
this.expect(_tokentype.types.parenR);
if (canBeArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) {
if (innerParenStart) this.unexpected(innerParenStart);
return this.parseParenArrowList(startPos, startLoc, exprList);
}
if (!exprList.length) this.unexpected(this.lastTokStart);
if (spreadStart) this.unexpected(spreadStart);
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
if (exprList.length > 1) {
val = this.startNodeAt(innerStartPos, innerStartLoc);
val.expressions = exprList;
this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
} else {
val = exprList[0];
}
} else {
val = this.parseParenExpression();
}
if (this.options.preserveParens) {
var par = this.startNodeAt(startPos, startLoc);
par.expression = val;
return this.finishNode(par, "ParenthesizedExpression");
} else {
return val;
}
};
pp.parseParenItem = function (item) {
return item;
};
pp.parseParenArrowList = function (startPos, startLoc, exprList) {
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList);
};
// New's precedence is slightly tricky. It must allow its argument
// to be a `[]` or dot subscript expression, but not a call — at
// least, not without wrapping it in parentheses. Thus, it uses the
var empty = [];
pp.parseNew = function () {
var node = this.startNode();
var meta = this.parseIdent(true);
if (this.options.ecmaVersion >= 6 && this.eat(_tokentype.types.dot)) {
node.meta = meta;
node.property = this.parseIdent(true);
if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
if (!this.inFunction) this.raise(node.start, "new.target can only be used in functions");
return this.finishNode(node, "MetaProperty");
}
var startPos = this.start,
startLoc = this.startLoc;
node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
if (this.eat(_tokentype.types.parenL)) node.arguments = this.parseExprList(_tokentype.types.parenR, false);else node.arguments = empty;
return this.finishNode(node, "NewExpression");
};
// Parse template expression.
pp.parseTemplateElement = function () {
var elem = this.startNode();
elem.value = {
raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'),
cooked: this.value
};
this.next();
elem.tail = this.type === _tokentype.types.backQuote;
return this.finishNode(elem, "TemplateElement");
};
pp.parseTemplate = function () {
var node = this.startNode();
this.next();
node.expressions = [];
var curElt = this.parseTemplateElement();
node.quasis = [curElt];
while (!curElt.tail) {
this.expect(_tokentype.types.dollarBraceL);
node.expressions.push(this.parseExpression());
this.expect(_tokentype.types.braceR);
node.quasis.push(curElt = this.parseTemplateElement());
}
this.next();
return this.finishNode(node, "TemplateLiteral");
};
// Parse an object literal or binding pattern.
pp.parseObj = function (isPattern, refShorthandDefaultPos) {
var node = this.startNode(),
first = true,
propHash = {};
node.properties = [];
this.next();
while (!this.eat(_tokentype.types.braceR)) {
if (!first) {
this.expect(_tokentype.types.comma);
if (this.afterTrailingComma(_tokentype.types.braceR)) break;
} else first = false;
var prop = this.startNode(),
isGenerator = undefined,
startPos = undefined,
startLoc = undefined;
if (this.options.ecmaVersion >= 6) {
prop.method = false;
prop.shorthand = false;
if (isPattern || refShorthandDefaultPos) {
startPos = this.start;
startLoc = this.startLoc;
}
if (!isPattern) isGenerator = this.eat(_tokentype.types.star);
}
this.parsePropertyName(prop);
this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos);
this.checkPropClash(prop, propHash);
node.properties.push(this.finishNode(prop, "Property"));
}
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
};
pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) {
if (this.eat(_tokentype.types.colon)) {
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
prop.kind = "init";
} else if (this.options.ecmaVersion >= 6 && this.type === _tokentype.types.parenL) {
if (isPattern) this.unexpected();
prop.kind = "init";
prop.method = true;
prop.value = this.parseMethod(isGenerator);
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != _tokentype.types.comma && this.type != _tokentype.types.braceR)) {
if (isGenerator || isPattern) this.unexpected();
prop.kind = prop.key.name;
this.parsePropertyName(prop);
prop.value = this.parseMethod(false);
var paramCount = prop.kind === "get" ? 0 : 1;
if (prop.value.params.length !== paramCount) {
var start = prop.value.start;
if (prop.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
}
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
prop.kind = "init";
if (isPattern) {
if (this.keywords.test(prop.key.name) || (this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
} else if (this.type === _tokentype.types.eq && refShorthandDefaultPos) {
if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
} else {
prop.value = prop.key;
}
prop.shorthand = true;
} else this.unexpected();
};
pp.parsePropertyName = function (prop) {
if (this.options.ecmaVersion >= 6) {
if (this.eat(_tokentype.types.bracketL)) {
prop.computed = true;
prop.key = this.parseMaybeAssign();
this.expect(_tokentype.types.bracketR);
return prop.key;
} else {
prop.computed = false;
}
}
return prop.key = this.type === _tokentype.types.num || this.type === _tokentype.types.string ? this.parseExprAtom() : this.parseIdent(true);
};
// Initialize empty function node.
pp.initFunction = function (node) {
node.id = null;
if (this.options.ecmaVersion >= 6) {
node.generator = false;
node.expression = false;
}
};
// Parse object or class method.
pp.parseMethod = function (isGenerator) {
var node = this.startNode();
this.initFunction(node);
this.expect(_tokentype.types.parenL);
node.params = this.parseBindingList(_tokentype.types.parenR, false, false);
if (this.options.ecmaVersion >= 6) node.generator = isGenerator;
this.parseFunctionBody(node, false);
return this.finishNode(node, "FunctionExpression");
};
// Parse arrow function expression with given parameters.
pp.parseArrowExpression = function (node, params) {
this.initFunction(node);
node.params = this.toAssignableList(params, true);
this.parseFunctionBody(node, true);
return this.finishNode(node, "ArrowFunctionExpression");
};
// Parse function body and check parameters.
pp.parseFunctionBody = function (node, isArrowFunction) {
var isExpression = isArrowFunction && this.type !== _tokentype.types.braceL;
if (isExpression) {
node.body = this.parseMaybeAssign();
node.expression = true;
} else {
// Start a new scope with regard to labels and the `inFunction`
// flag (restore them to their old value afterwards).
var oldInFunc = this.inFunction,
oldInGen = this.inGenerator,
oldLabels = this.labels;
this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
node.body = this.parseBlock(true);
node.expression = false;
this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
}
// If this is a strict mode function, verify that argument names
// are not repeated, and it does not try to bind the words `eval`
// or `arguments`.
if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
var oldStrict = this.strict;
this.strict = true;
if (node.id) this.checkLVal(node.id, true);
this.checkParams(node);
this.strict = oldStrict;
} else if (isArrowFunction) {
this.checkParams(node);
}
};
// Checks function params for various disallowed patterns such as using "eval"
// or "arguments" and duplicate parameters.
pp.checkParams = function (node) {
var nameHash = {};
for (var i = 0; i < node.params.length; i++) {
this.checkLVal(node.params[i], true, nameHash);
}
};
// Parses a comma-separated list of expressions, and returns them as
// an array. `close` is the token type that ends the list, and
// `allowEmpty` can be turned on to allow subsequent commas with
// nothing in between them to be parsed as `null` (which is needed
// for array literals).
pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
var elts = [],
first = true;
while (!this.eat(close)) {
if (!first) {
this.expect(_tokentype.types.comma);
if (allowTrailingComma && this.afterTrailingComma(close)) break;
} else first = false;
var elt = undefined;
if (allowEmpty && this.type === _tokentype.types.comma) elt = null;else if (this.type === _tokentype.types.ellipsis) elt = this.parseSpread(refShorthandDefaultPos);else elt = this.parseMaybeAssign(false, refShorthandDefaultPos);
elts.push(elt);
}
return elts;
};
// Parse the next token as an identifier. If `liberal` is true (used
// when parsing properties), it will also convert keywords into
// identifiers.
pp.parseIdent = function (liberal) {
var node = this.startNode();
if (liberal && this.options.allowReserved == "never") liberal = false;
if (this.type === _tokentype.types.name) {
if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1)) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
node.name = this.value;
} else if (liberal && this.type.keyword) {
node.name = this.type.keyword;
} else {
this.unexpected();
}
this.next();
return this.finishNode(node, "Identifier");
};
// Parses yield expression inside generator.
pp.parseYield = function () {
var node = this.startNode();
this.next();
if (this.type == _tokentype.types.semi || this.canInsertSemicolon() || this.type != _tokentype.types.star && !this.type.startsExpr) {
node.delegate = false;
node.argument = null;
} else {
node.delegate = this.eat(_tokentype.types.star);
node.argument = this.parseMaybeAssign();
}
return this.finishNode(node, "YieldExpression");
};
// Parses array and generator comprehensions.
pp.parseComprehension = function (node, isGenerator) {
node.blocks = [];
while (this.type === _tokentype.types._for) {
var block = this.startNode();
this.next();
this.expect(_tokentype.types.parenL);
block.left = this.parseBindingAtom();
this.checkLVal(block.left, true);
this.expectContextual("of");
block.right = this.parseExpression();
this.expect(_tokentype.types.parenR);
node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
}
node.filter = this.eat(_tokentype.types._if) ? this.parseParenExpression() : null;
node.body = this.parseExpression();
this.expect(isGenerator ? _tokentype.types.parenR : _tokentype.types.bracketR);
node.generator = isGenerator;
return this.finishNode(node, "ComprehensionExpression");
};
},{"./state":10,"./tokentype":14}],2:[function(_dereq_,module,exports){
// This is a trick taken from Esprima. It turns out that, on
// non-Chrome browsers, to check whether a string is in a set, a
// predicate containing a big ugly `switch` statement is faster than
// a regular expression, and on Chrome the two are about on par.
// This function uses `eval` (non-lexical) to produce such a
// predicate from a space-separated string of words.
//
// It starts by sorting the words by length.
// Reserved word lists for various dialects of the language
"use strict";
exports.__esModule = true;
exports.isIdentifierStart = isIdentifierStart;
exports.isIdentifierChar = isIdentifierChar;
var reservedWords = {
3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
5: "class enum extends super const export import",
6: "enum",
strict: "implements interface let package private protected public static yield",
strictBind: "eval arguments"
};
exports.reservedWords = reservedWords;
// And the keywords
var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
var keywords = {
5: ecma5AndLessKeywords,
6: ecma5AndLessKeywords + " let const class extends export import yield super"
};
exports.keywords = keywords;
// ## Character categories
// Big ugly regular expressions that match characters in the
// whitespace, identifier, and identifier-start categories. These
// are only applied when a character is found to actually have a
// code point above 128.
// Generated by `tools/generate-identifier-regex.js`.
var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
var nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
// These are a run-length and offset encoded representation of the
// >0xffff code points that are a valid part of identifiers. The
// offset starts at 0x10000, and each pair of numbers represents an
// offset to the next range, and then a size of the range. They were
// generated by tools/generate-identifier-regex.js
var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 1340, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 16355, 541];
var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 4305, 6, 792618, 239];
// This has a complexity linear to the value of the code. The
// assumption is that looking up astral identifier characters is
// rare.
function isInAstralSet(code, set) {
var pos = 0x10000;
for (var i = 0; i < set.length; i += 2) {
pos += set[i];
if (pos > code) return false;
pos += set[i + 1];
if (pos >= code) return true;
}
}
// Test whether a given character code starts an identifier.
function isIdentifierStart(code, astral) {
if (code < 65) return code === 36;
if (code < 91) return true;
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes);
}
// Test whether a given character is part of an identifier.
function isIdentifierChar(code, astral) {
if (code < 48) return code === 36;
if (code < 58) return true;
if (code < 65) return false;
if (code < 91) return true;
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
}
},{}],3:[function(_dereq_,module,exports){
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
//
// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
// various contributors and released under an MIT license.
//
// Git repositories for Acorn are available at
//
// http://marijnhaverbeke.nl/git/acorn
// https://github.com/marijnh/acorn.git
//
// Please use the [github bug tracker][ghbt] to report issues.
//
// [ghbt]: https://github.com/marijnh/acorn/issues
//
// This file defines the main parser interface. The library also comes
// with a [error-tolerant parser][dammit] and an
// [abstract syntax tree walker][walk], defined in other files.
//
// [dammit]: acorn_loose.js
// [walk]: util/walk.js
"use strict";
exports.__esModule = true;
exports.parse = parse;
exports.parseExpressionAt = parseExpressionAt;
exports.tokenizer = tokenizer;
var _state = _dereq_("./state");
_dereq_("./parseutil");
_dereq_("./statement");
_dereq_("./lval");
_dereq_("./expression");
_dereq_("./location");
exports.Parser = _state.Parser;
exports.plugins = _state.plugins;
var _options = _dereq_("./options");
exports.defaultOptions = _options.defaultOptions;
var _locutil = _dereq_("./locutil");
exports.Position = _locutil.Position;
exports.SourceLocation = _locutil.SourceLocation;
exports.getLineInfo = _locutil.getLineInfo;
var _node = _dereq_("./node");
exports.Node = _node.Node;
var _tokentype = _dereq_("./tokentype");
exports.TokenType = _tokentype.TokenType;
exports.tokTypes = _tokentype.types;
var _tokencontext = _dereq_("./tokencontext");
exports.TokContext = _tokencontext.TokContext;
exports.tokContexts = _tokencontext.types;
var _identifier = _dereq_("./identifier");
exports.isIdentifierChar = _identifier.isIdentifierChar;
exports.isIdentifierStart = _identifier.isIdentifierStart;
var _tokenize = _dereq_("./tokenize");
exports.Token = _tokenize.Token;
var _whitespace = _dereq_("./whitespace");
exports.isNewLine = _whitespace.isNewLine;
exports.lineBreak = _whitespace.lineBreak;
exports.lineBreakG = _whitespace.lineBreakG;
var version = "2.4.1";
exports.version = version;
// The main exported interface (under `self.acorn` when in the
// browser) is a `parse` function that takes a code string and
// returns an abstract syntax tree as specified by [Mozilla parser
// API][api].
//
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
function parse(input, options) {
return new _state.Parser(options, input).parse();
}
// This function tries to parse a single expression at a given
// offset in a string. Useful for parsing mixed-language formats
// that embed JavaScript expressions.
function parseExpressionAt(input, pos, options) {
var p = new _state.Parser(options, input, pos);
p.nextToken();
return p.parseExpression();
}
// Acorn is organized as a tokenizer and a recursive-descent parser.
// The `tokenizer` export provides an interface to the tokenizer.
function tokenizer(input, options) {
return new _state.Parser(options, input);
}
},{"./expression":1,"./identifier":2,"./location":4,"./locutil":5,"./lval":6,"./node":7,"./options":8,"./parseutil":9,"./state":10,"./statement":11,"./tokencontext":12,"./tokenize":13,"./tokentype":14,"./whitespace":16}],4:[function(_dereq_,module,exports){
"use strict";
var _state = _dereq_("./state");
var _locutil = _dereq_("./locutil");
var pp = _state.Parser.prototype;
// This function is used to raise exceptions on parse errors. It
// takes an offset integer (into the current `input`) to indicate
// the location of the error, attaches the position to the end
// of the error message, and then raises a `SyntaxError` with that
// message.
pp.raise = function (pos, message) {
var loc = _locutil.getLineInfo(this.input, pos);
message += " (" + loc.line + ":" + loc.column + ")";
var err = new SyntaxError(message);
err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
throw err;
};
pp.curPosition = function () {
if (this.options.locations) {
return new _locutil.Position(this.curLine, this.pos - this.lineStart);
}
};
},{"./locutil":5,"./state":10}],5:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
exports.getLineInfo = getLineInfo;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _whitespace = _dereq_("./whitespace");
// These are used when `options.locations` is on, for the
// `startLoc` and `endLoc` properties.
var Position = (function () {
function Position(line, col) {
_classCallCheck(this, Position);
this.line = line;
this.column = col;
}
Position.prototype.offset = function offset(n) {
return new Position(this.line, this.column + n);
};
return Position;
})();
exports.Position = Position;
var SourceLocation = function SourceLocation(p, start, end) {
_classCallCheck(this, SourceLocation);
this.start = start;
this.end = end;
if (p.sourceFile !== null) this.source = p.sourceFile;
}
// The `getLineInfo` function is mostly useful when the
// `locations` option is off (for performance reasons) and you
// want to find the line/column position for a given character
// offset. `input` should be the code string that the offset refers
// into.
;
exports.SourceLocation = SourceLocation;
function getLineInfo(input, offset) {
for (var line = 1, cur = 0;;) {
_whitespace.lineBreakG.lastIndex = cur;
var match = _whitespace.lineBreakG.exec(input);
if (match && match.index < offset) {
++line;
cur = match.index + match[0].length;
} else {
return new Position(line, offset - cur);
}
}
}
},{"./whitespace":16}],6:[function(_dereq_,module,exports){
"use strict";
var _tokentype = _dereq_("./tokentype");
var _state = _dereq_("./state");
var _util = _dereq_("./util");
var pp = _state.Parser.prototype;
// Convert existing expression atom to assignable pattern
// if possible.
pp.toAssignable = function (node, isBinding) {
if (this.options.ecmaVersion >= 6 && node) {
switch (node.type) {
case "Identifier":
case "ObjectPattern":
case "ArrayPattern":
case "AssignmentPattern":
break;
case "ObjectExpression":
node.type = "ObjectPattern";
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
this.toAssignable(prop.value, isBinding);
}
break;
case "ArrayExpression":
node.type = "ArrayPattern";
this.toAssignableList(node.elements, isBinding);
break;
case "AssignmentExpression":
if (node.operator === "=") {
node.type = "AssignmentPattern";
delete node.operator;
} else {
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
}
break;
case "ParenthesizedExpression":
node.expression = this.toAssignable(node.expression, isBinding);
break;
case "MemberExpression":
if (!isBinding) break;
default:
this.raise(node.start, "Assigning to rvalue");
}
}
return node;
};
// Convert list of expression atoms to binding list.
pp.toAssignableList = function (exprList, isBinding) {
var end = exprList.length;
if (end) {
var last = exprList[end - 1];
if (last && last.type == "RestElement") {
--end;
} else if (last && last.type == "SpreadElement") {
last.type = "RestElement";
var arg = last.argument;
this.toAssignable(arg, isBinding);
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
--end;
}
if (isBinding && last.type === "RestElement" && last.argument.type !== "Identifier") this.unexpected(last.argument.start);
}
for (var i = 0; i < end; i++) {
var elt = exprList[i];
if (elt) this.toAssignable(elt, isBinding);
}
return exprList;
};
// Parses spread element.
pp.parseSpread = function (refShorthandDefaultPos) {
var node = this.startNode();
this.next();
node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
return this.finishNode(node, "SpreadElement");
};
pp.parseRest = function (allowNonIdent) {
var node = this.startNode();
this.next();
// RestElement inside of a function parameter must be an identifier
if (allowNonIdent) node.argument = this.type === _tokentype.types.name ? this.parseIdent() : this.unexpected();else node.argument = this.type === _tokentype.types.name || this.type === _tokentype.types.bracketL ? this.parseBindingAtom() : this.unexpected();
return this.finishNode(node, "RestElement");
};
// Parses lvalue (assignable) atom.
pp.parseBindingAtom = function () {
if (this.options.ecmaVersion < 6) return this.parseIdent();
switch (this.type) {
case _tokentype.types.name:
return this.parseIdent();
case _tokentype.types.bracketL:
var node = this.startNode();
this.next();
node.elements = this.parseBindingList(_tokentype.types.bracketR, true, true);
return this.finishNode(node, "ArrayPattern");
case _tokentype.types.braceL:
return this.parseObj(true);
default:
this.unexpected();
}
};
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma, allowNonIdent) {
var elts = [],
first = true;
while (!this.eat(close)) {
if (first) first = false;else this.expect(_tokentype.types.comma);
if (allowEmpty && this.type === _tokentype.types.comma) {
elts.push(null);
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
break;
} else if (this.type === _tokentype.types.ellipsis) {
var rest = this.parseRest(allowNonIdent);
this.parseBindingListItem(rest);
elts.push(rest);
this.expect(close);
break;
} else {
var elem = this.parseMaybeDefault(this.start, this.startLoc);
this.parseBindingListItem(elem);
elts.push(elem);
}
}
return elts;
};
pp.parseBindingListItem = function (param) {
return param;
};
// Parses assignment pattern around given atom if possible.
pp.parseMaybeDefault = function (startPos, startLoc, left) {
left = left || this.parseBindingAtom();
if (this.options.ecmaVersion < 6 || !this.eat(_tokentype.types.eq)) return left;
var node = this.startNodeAt(startPos, startLoc);
node.left = left;
node.right = this.parseMaybeAssign();
return this.finishNode(node, "AssignmentPattern");
};
// Verify that a node is an lval — something that can be assigned
// to.
pp.checkLVal = function (expr, isBinding, checkClashes) {
switch (expr.type) {
case "Identifier":
if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
if (checkClashes) {
if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash");
checkClashes[expr.name] = true;
}
break;
case "MemberExpression":
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
break;
case "ObjectPattern":
for (var i = 0; i < expr.properties.length; i++) {
this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
}break;
case "ArrayPattern":
for (var i = 0; i < expr.elements.length; i++) {
var elem = expr.elements[i];
if (elem) this.checkLVal(elem, isBinding, checkClashes);
}
break;
case "AssignmentPattern":
this.checkLVal(expr.left, isBinding, checkClashes);
break;
case "RestElement":
this.checkLVal(expr.argument, isBinding, checkClashes);
break;
case "ParenthesizedExpression":
this.checkLVal(expr.expression, isBinding, checkClashes);
break;
default:
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
}
};
},{"./state":10,"./tokentype":14,"./util":15}],7:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _state = _dereq_("./state");
var _locutil = _dereq_("./locutil");
var Node = function Node(parser, pos, loc) {
_classCallCheck(this, Node);
this.type = "";
this.start = pos;
this.end = 0;
if (parser.options.locations) this.loc = new _locutil.SourceLocation(parser, loc);
if (parser.options.directSourceFile) this.sourceFile = parser.options.directSourceFile;
if (parser.options.ranges) this.range = [pos, 0];
}
// Start an AST node, attaching a start offset.
;
exports.Node = Node;
var pp = _state.Parser.prototype;
pp.startNode = function () {
return new Node(this, this.start, this.startLoc);
};
pp.startNodeAt = function (pos, loc) {
return new Node(this, pos, loc);
};
// Finish an AST node, adding `type` and `end` properties.
function finishNodeAt(node, type, pos, loc) {
node.type = type;
node.end = pos;
if (this.options.locations) node.loc.end = loc;
if (this.options.ranges) node.range[1] = pos;
return node;
}
pp.finishNode = function (node, type) {
return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc);
};
// Finish node at given position
pp.finishNodeAt = function (node, type, pos, loc) {
return finishNodeAt.call(this, node, type, pos, loc);
};
},{"./locutil":5,"./state":10}],8:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
exports.getOptions = getOptions;
var _util = _dereq_("./util");
var _locutil = _dereq_("./locutil");
// A second optional argument can be given to further configure
// the parser process. These options are recognized:
var defaultOptions = {
// `ecmaVersion` indicates the ECMAScript version to parse. Must
// be either 3, or 5, or 6. This influences support for strict
// mode, the set of reserved words, support for getters and
// setters and other features.
ecmaVersion: 5,
// Source type ("script" or "module") for different semantics
sourceType: "script",
// `onInsertedSemicolon` can be a callback that will be called
// when a semicolon is automatically inserted. It will be passed
// th position of the comma as an offset, and if `locations` is
// enabled, it is given the location as a `{line, column}` object
// as second argument.
onInsertedSemicolon: null,
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
// trailing commas.
onTrailingComma: null,
// By default, reserved words are only enforced if ecmaVersion >= 5.
// Set `allowReserved` to a boolean value to explicitly turn this on
// an off. When this option has the value "never", reserved words
// and keywords can also not be used as property names.
allowReserved: null,
// When enabled, a return at the top level is not considered an
// error.
allowReturnOutsideFunction: false,
// When enabled, import/export statements are not constrained to
// appearing at the top of the program.
allowImportExportEverywhere: false,
// When enabled, hashbang directive in the beginning of file
// is allowed and treated as a line comment.
allowHashBang: false,
// When `locations` is on, `loc` properties holding objects with
// `start` and `end` properties in `{line, column}` form (with
// line being 1-based and column 0-based) will be attached to the
// nodes.
locations: false,
// A function can be passed as `onToken` option, which will
// cause Acorn to call that function with object in the same
// format as tokens returned from `tokenizer().getToken()`. Note
// that you are not allowed to call the parser from the
// callback—that will corrupt its internal state.
onToken: null,
// A function can be passed as `onComment` option, which will
// cause Acorn to call that function with `(block, text, start,
// end)` parameters whenever a comment is skipped. `block` is a
// boolean indicating whether this is a block (`/* */`) comment,
// `text` is the content of the comment, and `start` and `end` are
// character offsets that denote the start and end of the comment.
// When the `locations` option is on, two more parameters are
// passed, the full `{line, column}` locations of the start and
// end of the comments. Note that you are not allowed to call the
// parser from the callback—that will corrupt its internal state.
onComment: null,
// Nodes have their start and end characters offsets recorded in
// `start` and `end` properties (directly on the node, rather than
// the `loc` object, which holds line/column data. To also add a
// [semi-standardized][range] `range` property holding a `[start,
// end]` array with the same numbers, set the `ranges` option to
// `true`.
//
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
ranges: false,
// It is possible to parse multiple files into a single AST by
// passing the tree produced by parsing the first file as
// `program` option in subsequent parses. This will add the
// toplevel forms of the parsed file to the `Program` (top) node
// of an existing parse tree.
program: null,
// When `locations` is on, you can pass this to record the source
// file in every node's `loc` object.
sourceFile: null,
// This value, if given, is stored in every node, whether
// `locations` is on or off.
directSourceFile: null,
// When enabled, parenthesized expressions are represented by
// (non-standard) ParenthesizedExpression nodes
preserveParens: false,
plugins: {}
};
exports.defaultOptions = defaultOptions;
// Interpret and default an options object
function getOptions(opts) {
var options = {};
for (var opt in defaultOptions) {
options[opt] = opts && _util.has(opts, opt) ? opts[opt] : defaultOptions[opt];
}if (options.allowReserved == null) options.allowReserved = options.ecmaVersion >= 5;
if (_util.isArray(options.onToken)) {
(function () {
var tokens = options.onToken;
options.onToken = function (token) {
return tokens.push(token);
};
})();
}
if (_util.isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
return options;
}
function pushComment(options, array) {
return function (block, text, start, end, startLoc, endLoc) {
var comment = {
type: block ? 'Block' : 'Line',
value: text,
start: start,
end: end
};
if (options.locations) comment.loc = new _locutil.SourceLocation(this, startLoc, endLoc);
if (options.ranges) comment.range = [start, end];
array.push(comment);
};
}
},{"./locutil":5,"./util":15}],9:[function(_dereq_,module,exports){
"use strict";
var _tokentype = _dereq_("./tokentype");
var _state = _dereq_("./state");
var _whitespace = _dereq_("./whitespace");
var pp = _state.Parser.prototype;
// ## Parser utilities
// Test whether a statement node is the string literal `"use strict"`.
pp.isUseStrict = function (stmt) {
return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.raw.slice(1, -1) === "use strict";
};
// Predicate that tests whether the next token is of the given
// type, and if yes, consumes it as a side effect.
pp.eat = function (type) {
if (this.type === type) {
this.next();
return true;
} else {
return false;
}
};
// Tests whether parsed token is a contextual keyword.
pp.isContextual = function (name) {
return this.type === _tokentype.types.name && this.value === name;
};
// Consumes contextual keyword if possible.
pp.eatContextual = function (name) {
return this.value === name && this.eat(_tokentype.types.name);
};
// Asserts that following token is given contextual keyword.
pp.expectContextual = function (name) {
if (!this.eatContextual(name)) this.unexpected();
};
// Test whether a semicolon can be inserted at the current position.
pp.canInsertSemicolon = function () {
return this.type === _tokentype.types.eof || this.type === _tokentype.types.braceR || _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
};
pp.insertSemicolon = function () {
if (this.canInsertSemicolon()) {
if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
return true;
}
};
// Consume a semicolon, or, failing that, see if we are allowed to
// pretend that there is a semicolon at this position.
pp.semicolon = function () {
if (!this.eat(_tokentype.types.semi) && !this.insertSemicolon()) this.unexpected();
};
pp.afterTrailingComma = function (tokType) {
if (this.type == tokType) {
if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
this.next();
return true;
}
};
// Expect a token of a given type. If found, consume it, otherwise,
// raise an unexpected token error.
pp.expect = function (type) {
this.eat(type) || this.unexpected();
};
// Raise an unexpected token error.
pp.unexpected = function (pos) {
this.raise(pos != null ? pos : this.start, "Unexpected token");
};
},{"./state":10,"./tokentype":14,"./whitespace":16}],10:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _identifier = _dereq_("./identifier");
var _tokentype = _dereq_("./tokentype");
var _whitespace = _dereq_("./whitespace");
var _options = _dereq_("./options");
// Registered plugins
var plugins = {};
exports.plugins = plugins;
function keywordRegexp(words) {
return new RegExp("^(" + words.replace(/ /g, "|") + ")$");
}
var Parser = (function () {
function Parser(options, input, startPos) {
_classCallCheck(this, Parser);
this.options = _options.getOptions(options);
this.sourceFile = this.options.sourceFile;
this.keywords = keywordRegexp(_identifier.keywords[this.options.ecmaVersion >= 6 ? 6 : 5]);
var reserved = this.options.allowReserved ? "" : _identifier.reservedWords[this.options.ecmaVersion] + (options.sourceType == "module" ? " await" : "");
this.reservedWords = keywordRegexp(reserved);
var reservedStrict = (reserved ? reserved + " " : "") + _identifier.reservedWords.strict;
this.reservedWordsStrict = keywordRegexp(reservedStrict);
this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + _identifier.reservedWords.strictBind);
this.input = String(input);
// Used to signal to callers of `readWord1` whether the word
// contained any escape sequences. This is needed because words with
// escape sequences must not be interpreted as keywords.
this.containsEsc = false;
// Load plugins
this.loadPlugins(this.options.plugins);
// Set up token state
// The current position of the tokenizer in the input.
if (startPos) {
this.pos = startPos;
this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
this.curLine = this.input.slice(0, this.lineStart).split(_whitespace.lineBreak).length;
} else {
this.pos = this.lineStart = 0;
this.curLine = 1;
}
// Properties of the current token:
// Its type
this.type = _tokentype.types.eof;
// For tokens that include more information than their type, the value
this.value = null;
// Its start and end offset
this.start = this.end = this.pos;
// And, if locations are used, the {line, column} object
// corresponding to those offsets
this.startLoc = this.endLoc = this.curPosition();
// Position information for the previous token
this.lastTokEndLoc = this.lastTokStartLoc = null;
this.lastTokStart = this.lastTokEnd = this.pos;
// The context stack is used to superficially track syntactic
// context to predict whether a regular expression is allowed in a
// given position.
this.context = this.initialContext();
this.exprAllowed = true;
// Figure out if it's a module code.
this.strict = this.inModule = this.options.sourceType === "module";
// Used to signify the start of a potential arrow function
this.potentialArrowAt = -1;
// Flags to track whether we are in a function, a generator.
this.inFunction = this.inGenerator = false;
// Labels in scope.
this.labels = [];
// If enabled, skip leading hashbang line.
if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === '#!') this.skipLineComment(2);
}
// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
Parser.prototype.isKeyword = function isKeyword(word) {
return this.keywords.test(word);
};
Parser.prototype.isReservedWord = function isReservedWord(word) {
return this.reservedWords.test(word);
};
Parser.prototype.extend = function extend(name, f) {
this[name] = f(this[name]);
};
Parser.prototype.loadPlugins = function loadPlugins(pluginConfigs) {
for (var _name in pluginConfigs) {
var plugin = plugins[_name];
if (!plugin) throw new Error("Plugin '" + _name + "' not found");
plugin(this, pluginConfigs[_name]);
}
};
Parser.prototype.parse = function parse() {
var node = this.options.program || this.startNode();
this.nextToken();
return this.parseTopLevel(node);
};
return Parser;
})();
exports.Parser = Parser;
},{"./identifier":2,"./options":8,"./tokentype":14,"./whitespace":16}],11:[function(_dereq_,module,exports){
"use strict";
var _tokentype = _dereq_("./tokentype");
var _state = _dereq_("./state");
var _whitespace = _dereq_("./whitespace");
var pp = _state.Parser.prototype;
// ### Statement parsing
// Parse a program. Initializes the parser, reads any number of
// statements, and wraps them in a Program node. Optionally takes a
// `program` argument. If present, the statements will be appended
// to its body instead of creating a new node.
pp.parseTopLevel = function (node) {
var first = true;
if (!node.body) node.body = [];
while (this.type !== _tokentype.types.eof) {
var stmt = this.parseStatement(true, true);
node.body.push(stmt);
if (first) {
if (this.isUseStrict(stmt)) this.setStrict(true);
first = false;
}
}
this.next();
if (this.options.ecmaVersion >= 6) {
node.sourceType = this.options.sourceType;
}
return this.finishNode(node, "Program");
};
var loopLabel = { kind: "loop" },
switchLabel = { kind: "switch" };
// Parse a single statement.
//
// If expecting a statement and finding a slash operator, parse a
// regular expression literal. This is to handle cases like
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
// does not help.
pp.parseStatement = function (declaration, topLevel) {
var starttype = this.type,
node = this.startNode();
// Most types of statements are recognized by the keyword they
// start with. Many are trivial to parse, some require a bit of
// complexity.
switch (starttype) {
case _tokentype.types._break:case _tokentype.types._continue:
return this.parseBreakContinueStatement(node, starttype.keyword);
case _tokentype.types._debugger:
return this.parseDebuggerStatement(node);
case _tokentype.types._do:
return this.parseDoStatement(node);
case _tokentype.types._for:
return this.parseForStatement(node);
case _tokentype.types._function:
if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
return this.parseFunctionStatement(node);
case _tokentype.types._class:
if (!declaration) this.unexpected();
return this.parseClass(node, true);
case _tokentype.types._if:
return this.parseIfStatement(node);
case _tokentype.types._return:
return this.parseReturnStatement(node);
case _tokentype.types._switch:
return this.parseSwitchStatement(node);
case _tokentype.types._throw:
return this.parseThrowStatement(node);
case _tokentype.types._try:
return this.parseTryStatement(node);
case _tokentype.types._let:case _tokentype.types._const:
if (!declaration) this.unexpected(); // NOTE: falls through to _var
case _tokentype.types._var:
return this.parseVarStatement(node, starttype);
case _tokentype.types._while:
return this.parseWhileStatement(node);
case _tokentype.types._with:
return this.parseWithStatement(node);
case _tokentype.types.braceL:
return this.parseBlock();
case _tokentype.types.semi:
return this.parseEmptyStatement(node);
case _tokentype.types._export:
case _tokentype.types._import:
if (!this.options.allowImportExportEverywhere) {
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
}
return starttype === _tokentype.types._import ? this.parseImport(node) : this.parseExport(node);
// If the statement does not start with a statement keyword or a
// brace, it's an ExpressionStatement or LabeledStatement. We
// simply start parsing an expression, and afterwards, if the
// next token is a colon and the expression was a simple
// Identifier node, we switch to interpreting it as a label.
default:
var maybeName = this.value,
expr = this.parseExpression();
if (starttype === _tokentype.types.name && expr.type === "Identifier" && this.eat(_tokentype.types.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
}
};
pp.parseBreakContinueStatement = function (node, keyword) {
var isBreak = keyword == "break";
this.next();
if (this.eat(_tokentype.types.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== _tokentype.types.name) this.unexpected();else {
node.label = this.parseIdent();
this.semicolon();
}
// Verify that there is an actual destination to break or
// continue to.
for (var i = 0; i < this.labels.length; ++i) {
var lab = this.labels[i];
if (node.label == null || lab.name === node.label.name) {
if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
if (node.label && isBreak) break;
}
}
if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
};
pp.parseDebuggerStatement = function (node) {
this.next();
this.semicolon();
return this.finishNode(node, "DebuggerStatement");
};
pp.parseDoStatement = function (node) {
this.next();
this.labels.push(loopLabel);
node.body = this.parseStatement(false);
this.labels.pop();
this.expect(_tokentype.types._while);
node.test = this.parseParenExpression();
if (this.options.ecmaVersion >= 6) this.eat(_tokentype.types.semi);else this.semicolon();
return this.finishNode(node, "DoWhileStatement");
};
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
// loop is non-trivial. Basically, we have to parse the init `var`
// statement or expression, disallowing the `in` operator (see
// the second parameter to `parseExpression`), and then check
// whether the next token is `in` or `of`. When there is no init
// part (semicolon immediately after the opening parenthesis), it
// is a regular `for` loop.
pp.parseForStatement = function (node) {
this.next();
this.labels.push(loopLabel);
this.expect(_tokentype.types.parenL);
if (this.type === _tokentype.types.semi) return this.parseFor(node, null);
if (this.type === _tokentype.types._var || this.type === _tokentype.types._let || this.type === _tokentype.types._const) {
var _init = this.startNode(),
varKind = this.type;
this.next();
this.parseVar(_init, true, varKind);
this.finishNode(_init, "VariableDeclaration");
if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== _tokentype.types._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
return this.parseFor(node, _init);
}
var refShorthandDefaultPos = { start: 0 };
var init = this.parseExpression(true, refShorthandDefaultPos);
if (this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
this.toAssignable(init);
this.checkLVal(init);
return this.parseForIn(node, init);
} else if (refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start);
}
return this.parseFor(node, init);
};
pp.parseFunctionStatement = function (node) {
this.next();
return this.parseFunction(node, true);
};
pp.parseIfStatement = function (node) {
this.next();
node.test = this.parseParenExpression();
node.consequent = this.parseStatement(false);
node.alternate = this.eat(_tokentype.types._else) ? this.parseStatement(false) : null;
return this.finishNode(node, "IfStatement");
};
pp.parseReturnStatement = function (node) {
if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
this.next();
// In `return` (and `break`/`continue`), the keywords with
// optional arguments, we eagerly look for a semicolon or the
// possibility to insert one.
if (this.eat(_tokentype.types.semi) || this.insertSemicolon()) node.argument = null;else {
node.argument = this.parseExpression();this.semicolon();
}
return this.finishNode(node, "ReturnStatement");
};
pp.parseSwitchStatement = function (node) {
this.next();
node.discriminant = this.parseParenExpression();
node.cases = [];
this.expect(_tokentype.types.braceL);
this.labels.push(switchLabel);
// Statements under must be grouped (by label) in SwitchCase
// nodes. `cur` is used to keep the node that we are currently
// adding statements to.
for (var cur, sawDefault = false; this.type != _tokentype.types.braceR;) {
if (this.type === _tokentype.types._case || this.type === _tokentype.types._default) {
var isCase = this.type === _tokentype.types._case;
if (cur) this.finishNode(cur, "SwitchCase");
node.cases.push(cur = this.startNode());
cur.consequent = [];
this.next();
if (isCase) {
cur.test = this.parseExpression();
} else {
if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
sawDefault = true;
cur.test = null;
}
this.expect(_tokentype.types.colon);
} else {
if (!cur) this.unexpected();
cur.consequent.push(this.parseStatement(true));
}
}
if (cur) this.finishNode(cur, "SwitchCase");
this.next(); // Closing brace
this.labels.pop();
return this.finishNode(node, "SwitchStatement");
};
pp.parseThrowStatement = function (node) {
this.next();
if (_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
node.argument = this.parseExpression();
this.semicolon();
return this.finishNode(node, "ThrowStatement");
};
// Reused empty array added for node fields that are always empty.
var empty = [];
pp.parseTryStatement = function (node) {
this.next();
node.block = this.parseBlock();
node.handler = null;
if (this.type === _tokentype.types._catch) {
var clause = this.startNode();
this.next();
this.expect(_tokentype.types.parenL);
clause.param = this.parseBindingAtom();
this.checkLVal(clause.param, true);
this.expect(_tokentype.types.parenR);
clause.body = this.parseBlock();
node.handler = this.finishNode(clause, "CatchClause");
}
node.finalizer = this.eat(_tokentype.types._finally) ? this.parseBlock() : null;
if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
return this.finishNode(node, "TryStatement");
};
pp.parseVarStatement = function (node, kind) {
this.next();
this.parseVar(node, false, kind);
this.semicolon();
return this.finishNode(node, "VariableDeclaration");
};
pp.parseWhileStatement = function (node) {
this.next();
node.test = this.parseParenExpression();
this.labels.push(loopLabel);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, "WhileStatement");
};
pp.parseWithStatement = function (node) {
if (this.strict) this.raise(this.start, "'with' in strict mode");
this.next();
node.object = this.parseParenExpression();
node.body = this.parseStatement(false);
return this.finishNode(node, "WithStatement");
};
pp.parseEmptyStatement = function (node) {
this.next();
return this.finishNode(node, "EmptyStatement");
};
pp.parseLabeledStatement = function (node, maybeName, expr) {
for (var i = 0; i < this.labels.length; ++i) {
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
}var kind = this.type.isLoop ? "loop" : this.type === _tokentype.types._switch ? "switch" : null;
for (var i = this.labels.length - 1; i >= 0; i--) {
var label = this.labels[i];
if (label.statementStart == node.start) {
label.statementStart = this.start;
label.kind = kind;
} else break;
}
this.labels.push({ name: maybeName, kind: kind, statementStart: this.start });
node.body = this.parseStatement(true);
this.labels.pop();
node.label = expr;
return this.finishNode(node, "LabeledStatement");
};
pp.parseExpressionStatement = function (node, expr) {
node.expression = expr;
this.semicolon();
return this.finishNode(node, "ExpressionStatement");
};
// Parse a semicolon-enclosed block of statements, handling `"use
// strict"` declarations when `allowStrict` is true (used for
// function bodies).
pp.parseBlock = function (allowStrict) {
var node = this.startNode(),
first = true,
oldStrict = undefined;
node.body = [];
this.expect(_tokentype.types.braceL);
while (!this.eat(_tokentype.types.braceR)) {
var stmt = this.parseStatement(true);
node.body.push(stmt);
if (first && allowStrict && this.isUseStrict(stmt)) {
oldStrict = this.strict;
this.setStrict(this.strict = true);
}
first = false;
}
if (oldStrict === false) this.setStrict(false);
return this.finishNode(node, "BlockStatement");
};
// Parse a regular `for` loop. The disambiguation code in
// `parseStatement` will already have parsed the init statement or
// expression.
pp.parseFor = function (node, init) {
node.init = init;
this.expect(_tokentype.types.semi);
node.test = this.type === _tokentype.types.semi ? null : this.parseExpression();
this.expect(_tokentype.types.semi);
node.update = this.type === _tokentype.types.parenR ? null : this.parseExpression();
this.expect(_tokentype.types.parenR);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, "ForStatement");
};
// Parse a `for`/`in` and `for`/`of` loop, which are almost
// same from parser's perspective.
pp.parseForIn = function (node, init) {
var type = this.type === _tokentype.types._in ? "ForInStatement" : "ForOfStatement";
this.next();
node.left = init;
node.right = this.parseExpression();
this.expect(_tokentype.types.parenR);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, type);
};
// Parse a list of variable declarations.
pp.parseVar = function (node, isFor, kind) {
node.declarations = [];
node.kind = kind.keyword;
for (;;) {
var decl = this.startNode();
this.parseVarId(decl);
if (this.eat(_tokentype.types.eq)) {
decl.init = this.parseMaybeAssign(isFor);
} else if (kind === _tokentype.types._const && !(this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
this.unexpected();
} else if (decl.id.type != "Identifier" && !(isFor && (this.type === _tokentype.types._in || this.isContextual("of")))) {
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
} else {
decl.init = null;
}
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
if (!this.eat(_tokentype.types.comma)) break;
}
return node;
};
pp.parseVarId = function (decl) {
decl.id = this.parseBindingAtom();
this.checkLVal(decl.id, true);
};
// Parse a function declaration or literal (depending on the
// `isStatement` parameter).
pp.parseFunction = function (node, isStatement, allowExpressionBody) {
this.initFunction(node);
if (this.options.ecmaVersion >= 6) node.generator = this.eat(_tokentype.types.star);
if (isStatement || this.type === _tokentype.types.name) node.id = this.parseIdent();
this.parseFunctionParams(node);
this.parseFunctionBody(node, allowExpressionBody);
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
};
pp.parseFunctionParams = function (node) {
this.expect(_tokentype.types.parenL);
node.params = this.parseBindingList(_tokentype.types.parenR, false, false, true);
};
// Parse a class declaration or literal (depending on the
// `isStatement` parameter).
pp.parseClass = function (node, isStatement) {
this.next();
this.parseClassId(node, isStatement);
this.parseClassSuper(node);
var classBody = this.startNode();
var hadConstructor = false;
classBody.body = [];
this.expect(_tokentype.types.braceL);
while (!this.eat(_tokentype.types.braceR)) {
if (this.eat(_tokentype.types.semi)) continue;
var method = this.startNode();
var isGenerator = this.eat(_tokentype.types.star);
var isMaybeStatic = this.type === _tokentype.types.name && this.value === "static";
this.parsePropertyName(method);
method["static"] = isMaybeStatic && this.type !== _tokentype.types.parenL;
if (method["static"]) {
if (isGenerator) this.unexpected();
isGenerator = this.eat(_tokentype.types.star);
this.parsePropertyName(method);
}
method.kind = "method";
var isGetSet = false;
if (!method.computed) {
var key = method.key;
if (!isGenerator && key.type === "Identifier" && this.type !== _tokentype.types.parenL && (key.name === "get" || key.name === "set")) {
isGetSet = true;
method.kind = key.name;
key = this.parsePropertyName(method);
}
if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
method.kind = "constructor";
hadConstructor = true;
}
}
this.parseClassMethod(classBody, method, isGenerator);
if (isGetSet) {
var paramCount = method.kind === "get" ? 0 : 1;
if (method.value.params.length !== paramCount) {
var start = method.value.start;
if (method.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
}
}
}
node.body = this.finishNode(classBody, "ClassBody");
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
};
pp.parseClassMethod = function (classBody, method, isGenerator) {
method.value = this.parseMethod(isGenerator);
classBody.body.push(this.finishNode(method, "MethodDefinition"));
};
pp.parseClassId = function (node, isStatement) {
node.id = this.type === _tokentype.types.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
};
pp.parseClassSuper = function (node) {
node.superClass = this.eat(_tokentype.types._extends) ? this.parseExprSubscripts() : null;
};
// Parses module export declaration.
pp.parseExport = function (node) {
this.next();
// export * from '...'
if (this.eat(_tokentype.types.star)) {
this.expectContextual("from");
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
this.semicolon();
return this.finishNode(node, "ExportAllDeclaration");
}
if (this.eat(_tokentype.types._default)) {
// export default ...
var expr = this.parseMaybeAssign();
var needsSemi = true;
if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
needsSemi = false;
if (expr.id) {
expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
}
}
node.declaration = expr;
if (needsSemi) this.semicolon();
return this.finishNode(node, "ExportDefaultDeclaration");
}
// export var|const|let|function|class ...
if (this.shouldParseExportStatement()) {
node.declaration = this.parseStatement(true);
node.specifiers = [];
node.source = null;
} else {
// export { x, y as z } [from '...']
node.declaration = null;
node.specifiers = this.parseExportSpecifiers();
if (this.eatContextual("from")) {
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
} else {
// check for keywords used as local names
for (var i = 0; i < node.specifiers.length; i++) {
if (this.keywords.test(node.specifiers[i].local.name) || this.reservedWords.test(node.specifiers[i].local.name)) {
this.unexpected(node.specifiers[i].local.start);
}
}
node.source = null;
}
this.semicolon();
}
return this.finishNode(node, "ExportNamedDeclaration");
};
pp.shouldParseExportStatement = function () {
return this.type.keyword;
};
// Parses a comma-separated list of module exports.
pp.parseExportSpecifiers = function () {
var nodes = [],
first = true;
// export { x, y as z } [from '...']
this.expect(_tokentype.types.braceL);
while (!this.eat(_tokentype.types.braceR)) {
if (!first) {
this.expect(_tokentype.types.comma);
if (this.afterTrailingComma(_tokentype.types.braceR)) break;
} else first = false;
var node = this.startNode();
node.local = this.parseIdent(this.type === _tokentype.types._default);
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
nodes.push(this.finishNode(node, "ExportSpecifier"));
}
return nodes;
};
// Parses import declaration.
pp.parseImport = function (node) {
this.next();
// import '...'
if (this.type === _tokentype.types.string) {
node.specifiers = empty;
node.source = this.parseExprAtom();
} else {
node.specifiers = this.parseImportSpecifiers();
this.expectContextual("from");
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
}
this.semicolon();
return this.finishNode(node, "ImportDeclaration");
};
// Parses a comma-separated list of module imports.
pp.parseImportSpecifiers = function () {
var nodes = [],
first = true;
if (this.type === _tokentype.types.name) {
// import defaultObj, { x, y as z } from '...'
var node = this.startNode();
node.local = this.parseIdent();
this.checkLVal(node.local, true);
nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
if (!this.eat(_tokentype.types.comma)) return nodes;
}
if (this.type === _tokentype.types.star) {
var node = this.startNode();
this.next();
this.expectContextual("as");
node.local = this.parseIdent();
this.checkLVal(node.local, true);
nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
return nodes;
}
this.expect(_tokentype.types.braceL);
while (!this.eat(_tokentype.types.braceR)) {
if (!first) {
this.expect(_tokentype.types.comma);
if (this.afterTrailingComma(_tokentype.types.braceR)) break;
} else first = false;
var node = this.startNode();
node.imported = this.parseIdent(true);
node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
this.checkLVal(node.local, true);
nodes.push(this.finishNode(node, "ImportSpecifier"));
}
return nodes;
};
},{"./state":10,"./tokentype":14,"./whitespace":16}],12:[function(_dereq_,module,exports){
// The algorithm used to determine whether a regexp can appear at a
// given point in the program is loosely based on sweet.js' approach.
// See https://github.com/mozilla/sweet.js/wiki/design
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _state = _dereq_("./state");
var _tokentype = _dereq_("./tokentype");
var _whitespace = _dereq_("./whitespace");
var TokContext = function TokContext(token, isExpr, preserveSpace, override) {
_classCallCheck(this, TokContext);
this.token = token;
this.isExpr = !!isExpr;
this.preserveSpace = !!preserveSpace;
this.override = override;
};
exports.TokContext = TokContext;
var types = {
b_stat: new TokContext("{", false),
b_expr: new TokContext("{", true),
b_tmpl: new TokContext("${", true),
p_stat: new TokContext("(", false),
p_expr: new TokContext("(", true),
q_tmpl: new TokContext("`", true, true, function (p) {
return p.readTmplToken();
}),
f_expr: new TokContext("function", true)
};
exports.types = types;
var pp = _state.Parser.prototype;
pp.initialContext = function () {
return [types.b_stat];
};
pp.braceIsBlock = function (prevType) {
if (prevType === _tokentype.types.colon) {
var _parent = this.curContext();
if (_parent === types.b_stat || _parent === types.b_expr) return !_parent.isExpr;
}
if (prevType === _tokentype.types._return) return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
if (prevType === _tokentype.types._else || prevType === _tokentype.types.semi || prevType === _tokentype.types.eof || prevType === _tokentype.types.parenR) return true;
if (prevType == _tokentype.types.braceL) return this.curContext() === types.b_stat;
return !this.exprAllowed;
};
pp.updateContext = function (prevType) {
var update = undefined,
type = this.type;
if (type.keyword && prevType == _tokentype.types.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
};
// Token-specific context update code
_tokentype.types.parenR.updateContext = _tokentype.types.braceR.updateContext = function () {
if (this.context.length == 1) {
this.exprAllowed = true;
return;
}
var out = this.context.pop();
if (out === types.b_stat && this.curContext() === types.f_expr) {
this.context.pop();
this.exprAllowed = false;
} else if (out === types.b_tmpl) {
this.exprAllowed = true;
} else {
this.exprAllowed = !out.isExpr;
}
};
_tokentype.types.braceL.updateContext = function (prevType) {
this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
this.exprAllowed = true;
};
_tokentype.types.dollarBraceL.updateContext = function () {
this.context.push(types.b_tmpl);
this.exprAllowed = true;
};
_tokentype.types.parenL.updateContext = function (prevType) {
var statementParens = prevType === _tokentype.types._if || prevType === _tokentype.types._for || prevType === _tokentype.types._with || prevType === _tokentype.types._while;
this.context.push(statementParens ? types.p_stat : types.p_expr);
this.exprAllowed = true;
};
_tokentype.types.incDec.updateContext = function () {
// tokExprAllowed stays unchanged
};
_tokentype.types._function.updateContext = function () {
if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
this.exprAllowed = false;
};
_tokentype.types.backQuote.updateContext = function () {
if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
this.exprAllowed = false;
};
},{"./state":10,"./tokentype":14,"./whitespace":16}],13:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _identifier = _dereq_("./identifier");
var _tokentype = _dereq_("./tokentype");
var _state = _dereq_("./state");
var _locutil = _dereq_("./locutil");
var _whitespace = _dereq_("./whitespace");
// Object type used to represent tokens. Note that normally, tokens
// simply exist as properties on the parser object. This is only
// used for the onToken callback and the external tokenizer.
var Token = function Token(p) {
_classCallCheck(this, Token);
this.type = p.type;
this.value = p.value;
this.start = p.start;
this.end = p.end;
if (p.options.locations) this.loc = new _locutil.SourceLocation(p, p.startLoc, p.endLoc);
if (p.options.ranges) this.range = [p.start, p.end];
}
// ## Tokenizer
;
exports.Token = Token;
var pp = _state.Parser.prototype;
// Are we running under Rhino?
var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]";
// Move to the next token
pp.next = function () {
if (this.options.onToken) this.options.onToken(new Token(this));
this.lastTokEnd = this.end;
this.lastTokStart = this.start;
this.lastTokEndLoc = this.endLoc;
this.lastTokStartLoc = this.startLoc;
this.nextToken();
};
pp.getToken = function () {
this.next();
return new Token(this);
};
// If we're in an ES6 environment, make parsers iterable
Eif (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
var self = this;
return { next: function next() {
var token = self.getToken();
return {
done: token.type === _tokentype.types.eof,
value: token
};
} };
};
// Toggle strict mode. Re-reads the next number or string to please
// pedantic tests (`"use strict"; 010;` should fail).
pp.setStrict = function (strict) {
this.strict = strict;
if (this.type !== _tokentype.types.num && this.type !== _tokentype.types.string) return;
this.pos = this.start;
if (this.options.locations) {
while (this.pos < this.lineStart) {
this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
--this.curLine;
}
}
this.nextToken();
};
pp.curContext = function () {
return this.context[this.context.length - 1];
};
// Read a single token, updating the parser object's token-related
// properties.
pp.nextToken = function () {
var curContext = this.curContext();
if (!curContext || !curContext.preserveSpace) this.skipSpace();
this.start = this.pos;
if (this.options.locations) this.startLoc = this.curPosition();
if (this.pos >= this.input.length) return this.finishToken(_tokentype.types.eof);
if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
};
pp.readToken = function (code) {
// Identifier or keyword. '\uXXXX' sequences are allowed in
// identifiers, so '\' also dispatches to that.
if (_identifier.isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
return this.getTokenFromCode(code);
};
pp.fullCharCodeAtPos = function () {
var code = this.input.charCodeAt(this.pos);
if (code <= 0xd7ff || code >= 0xe000) return code;
var next = this.input.charCodeAt(this.pos + 1);
return (code << 10) + next - 0x35fdc00;
};
pp.skipBlockComment = function () {
var startLoc = this.options.onComment && this.curPosition();
var start = this.pos,
end = this.input.indexOf("*/", this.pos += 2);
if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
this.pos = end + 2;
if (this.options.locations) {
_whitespace.lineBreakG.lastIndex = start;
var match = undefined;
while ((match = _whitespace.lineBreakG.exec(this.input)) && match.index < this.pos) {
++this.curLine;
this.lineStart = match.index + match[0].length;
}
}
if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.curPosition());
};
pp.skipLineComment = function (startSkip) {
var start = this.pos;
var startLoc = this.options.onComment && this.curPosition();
var ch = this.input.charCodeAt(this.pos += startSkip);
while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
++this.pos;
ch = this.input.charCodeAt(this.pos);
}
if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.curPosition());
};
// Called at the start of the parse and after every token. Skips
// whitespace and comments, and.
pp.skipSpace = function () {
loop: while (this.pos < this.input.length) {
var ch = this.input.charCodeAt(this.pos);
switch (ch) {
case 32:case 160:
// ' '
++this.pos;
break;
case 13:
if (this.input.charCodeAt(this.pos + 1) === 10) {
++this.pos;
}
case 10:case 8232:case 8233:
++this.pos;
if (this.options.locations) {
++this.curLine;
this.lineStart = this.pos;
}
break;
case 47:
// '/'
switch (this.input.charCodeAt(this.pos + 1)) {
case 42:
// '*'
this.skipBlockComment();
break;
case 47:
this.skipLineComment(2);
break;
default:
break loop;
}
break;
default:
if (ch > 8 && ch < 14 || ch >= 5760 && _whitespace.nonASCIIwhitespace.test(String.fromCharCode(ch))) {
++this.pos;
} else {
break loop;
}
}
}
};
// Called at the end of every token. Sets `end`, `val`, and
// maintains `context` and `exprAllowed`, and skips the space after
// the token, so that the next one's `start` will point at the
// right position.
pp.finishToken = function (type, val) {
this.end = this.pos;
if (this.options.locations) this.endLoc = this.curPosition();
var prevType = this.type;
this.type = type;
this.value = val;
this.updateContext(prevType);
};
// ### Token reading
// This is the function that is called to fetch the next token. It
// is somewhat obscure, because it works in character codes rather
// than characters, and because operator parsing has been inlined
// into it.
//
// All in the name of speed.
//
pp.readToken_dot = function () {
var next = this.input.charCodeAt(this.pos + 1);
if (next >= 48 && next <= 57) return this.readNumber(true);
var next2 = this.input.charCodeAt(this.pos + 2);
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
// 46 = dot '.'
this.pos += 3;
return this.finishToken(_tokentype.types.ellipsis);
} else {
++this.pos;
return this.finishToken(_tokentype.types.dot);
}
};
pp.readToken_slash = function () {
// '/'
var next = this.input.charCodeAt(this.pos + 1);
if (this.exprAllowed) {
++this.pos;return this.readRegexp();
}
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
return this.finishOp(_tokentype.types.slash, 1);
};
pp.readToken_mult_modulo = function (code) {
// '%*'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
return this.finishOp(code === 42 ? _tokentype.types.star : _tokentype.types.modulo, 1);
};
pp.readToken_pipe_amp = function (code) {
// '|&'
var next = this.input.charCodeAt(this.pos + 1);
if (next === code) return this.finishOp(code === 124 ? _tokentype.types.logicalOR : _tokentype.types.logicalAND, 2);
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
return this.finishOp(code === 124 ? _tokentype.types.bitwiseOR : _tokentype.types.bitwiseAND, 1);
};
pp.readToken_caret = function () {
// '^'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
return this.finishOp(_tokentype.types.bitwiseXOR, 1);
};
pp.readToken_plus_min = function (code) {
// '+-'
var next = this.input.charCodeAt(this.pos + 1);
if (next === code) {
if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
// A `-->` line comment
this.skipLineComment(3);
this.skipSpace();
return this.nextToken();
}
return this.finishOp(_tokentype.types.incDec, 2);
}
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
return this.finishOp(_tokentype.types.plusMin, 1);
};
pp.readToken_lt_gt = function (code) {
// '<>'
var next = this.input.charCodeAt(this.pos + 1);
var size = 1;
if (next === code) {
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(_tokentype.types.assign, size + 1);
return this.finishOp(_tokentype.types.bitShift, size);
}
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
if (this.inModule) this.unexpected();
// `<!--`, an XML-style comment that should be interpreted as a line comment
this.skipLineComment(4);
this.skipSpace();
return this.nextToken();
}
if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
return this.finishOp(_tokentype.types.relational, size);
};
pp.readToken_eq_excl = function (code) {
// '=!'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 61) return this.finishOp(_tokentype.types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
// '=>'
this.pos += 2;
return this.finishToken(_tokentype.types.arrow);
}
return this.finishOp(code === 61 ? _tokentype.types.eq : _tokentype.types.prefix, 1);
};
pp.getTokenFromCode = function (code) {
switch (code) {
// The interpretation of a dot depends on whether it is followed
// by a digit or another two dots.
case 46:
// '.'
return this.readToken_dot();
// Punctuation tokens.
case 40:
++this.pos;return this.finishToken(_tokentype.types.parenL);
case 41:
++this.pos;return this.finishToken(_tokentype.types.parenR);
case 59:
++this.pos;return this.finishToken(_tokentype.types.semi);
case 44:
++this.pos;return this.finishToken(_tokentype.types.comma);
case 91:
++this.pos;return this.finishToken(_tokentype.types.bracketL);
case 93:
++this.pos;return this.finishToken(_tokentype.types.bracketR);
case 123:
++this.pos;return this.finishToken(_tokentype.types.braceL);
case 125:
++this.pos;return this.finishToken(_tokentype.types.braceR);
case 58:
++this.pos;return this.finishToken(_tokentype.types.colon);
case 63:
++this.pos;return this.finishToken(_tokentype.types.question);
case 96:
// '`'
if (this.options.ecmaVersion < 6) break;
++this.pos;
return this.finishToken(_tokentype.types.backQuote);
case 48:
// '0'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
if (this.options.ecmaVersion >= 6) {
if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
}
// Anything else beginning with a digit is an integer, octal
// number, or float.
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
// 1-9
return this.readNumber(false);
// Quotes produce strings.
case 34:case 39:
// '"', "'"
return this.readString(code);
// Operators are parsed inline in tiny state machines. '=' (61) is
// often referred to. `finishOp` simply skips the amount of
// characters it is given as second argument, and returns a token
// of the type given by its first argument.
case 47:
// '/'
return this.readToken_slash();
case 37:case 42:
// '%*'
return this.readToken_mult_modulo(code);
case 124:case 38:
// '|&'
return this.readToken_pipe_amp(code);
case 94:
// '^'
return this.readToken_caret();
case 43:case 45:
// '+-'
return this.readToken_plus_min(code);
case 60:case 62:
// '<>'
return this.readToken_lt_gt(code);
case 61:case 33:
// '=!'
return this.readToken_eq_excl(code);
case 126:
// '~'
return this.finishOp(_tokentype.types.prefix, 1);
}
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
};
pp.finishOp = function (type, size) {
var str = this.input.slice(this.pos, this.pos + size);
this.pos += size;
return this.finishToken(type, str);
};
// Parse a regular expression. Some context-awareness is necessary,
// since a '/' inside a '[]' set does not end the expression.
function tryCreateRegexp(src, flags, throwErrorAt, parser) {
try {
return new RegExp(src, flags);
} catch (e) {
if (throwErrorAt !== undefined) {
if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message);
throw e;
}
}
}
var regexpUnicodeSupport = !!tryCreateRegexp("", "u");
pp.readRegexp = function () {
var _this = this;
var escaped = undefined,
inClass = undefined,
start = this.pos;
for (;;) {
if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
var ch = this.input.charAt(this.pos);
if (_whitespace.lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
if (!escaped) {
if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
escaped = ch === "\\";
} else escaped = false;
++this.pos;
}
var content = this.input.slice(start, this.pos);
++this.pos;
// Need to use `readWord1` because '\uXXXX' sequences are allowed
// here (don't ask).
var mods = this.readWord1();
var tmp = content;
if (mods) {
var validFlags = /^[gmsiy]*$/;
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
if (mods.indexOf('u') >= 0 && !regexpUnicodeSupport) {
// Replace each astral symbol and every Unicode escape sequence that
// possibly represents an astral symbol or a paired surrogate with a
// single ASCII symbol to avoid throwing on regular expressions that
// are only valid in combination with the `/u` flag.
// Note: replacing with the ASCII symbol `x` might cause false
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
// be replaced by `[x-b]` which throws an error.
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
code = Number("0x" + code);
if (code > 0x10FFFF) _this.raise(start + offset + 3, "Code point out of bounds");
return "x";
});
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
}
}
// Detect invalid regular expressions.
var value = null;
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
// so don't do detection if we are running under Rhino
if (!isRhino) {
tryCreateRegexp(tmp, undefined, start, this);
// Get a regular expression object for this pattern-flag pair, or `null` in
// case the current environment doesn't support the flags it uses.
value = tryCreateRegexp(content, mods);
}
return this.finishToken(_tokentype.types.regexp, { pattern: content, flags: mods, value: value });
};
// Read an integer in the given radix. Return null if zero digits
// were read, the integer value otherwise. When `len` is given, this
// will return `null` unless the integer has exactly `len` digits.
pp.readInt = function (radix, len) {
var start = this.pos,
total = 0;
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
var code = this.input.charCodeAt(this.pos),
val = undefined;
if (code >= 97) val = code - 97 + 10; // a
else if (code >= 65) val = code - 65 + 10; // A
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
else val = Infinity;
if (val >= radix) break;
++this.pos;
total = total * radix + val;
}
if (this.pos === start || len != null && this.pos - start !== len) return null;
return total;
};
pp.readRadixNumber = function (radix) {
this.pos += 2; // 0x
var val = this.readInt(radix);
if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
if (_identifier.isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
return this.finishToken(_tokentype.types.num, val);
};
// Read an integer, octal integer, or floating-point number.
pp.readNumber = function (startsWithDot) {
var start = this.pos,
isFloat = false,
octal = this.input.charCodeAt(this.pos) === 48;
if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
var next = this.input.charCodeAt(this.pos);
if (next === 46) {
// '.'
++this.pos;
this.readInt(10);
isFloat = true;
next = this.input.charCodeAt(this.pos);
}
if (next === 69 || next === 101) {
// 'eE'
next = this.input.charCodeAt(++this.pos);
if (next === 43 || next === 45) ++this.pos; // '+-'
if (this.readInt(10) === null) this.raise(start, "Invalid number");
isFloat = true;
}
if (_identifier.isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
var str = this.input.slice(start, this.pos),
val = undefined;
if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
return this.finishToken(_tokentype.types.num, val);
};
// Read a string value, interpreting backslash-escapes.
pp.readCodePoint = function () {
var ch = this.input.charCodeAt(this.pos),
code = undefined;
if (ch === 123) {
if (this.options.ecmaVersion < 6) this.unexpected();
var codePos = ++this.pos;
code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos);
++this.pos;
if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds");
} else {
code = this.readHexChar(4);
}
return code;
};
function codePointToString(code) {
// UTF-16 Decoding
if (code <= 0xFFFF) return String.fromCharCode(code);
code -= 0x10000;
return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00);
}
pp.readString = function (quote) {
var out = "",
chunkStart = ++this.pos;
for (;;) {
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
var ch = this.input.charCodeAt(this.pos);
if (ch === quote) break;
if (ch === 92) {
// '\'
out += this.input.slice(chunkStart, this.pos);
out += this.readEscapedChar(false);
chunkStart = this.pos;
} else {
if (_whitespace.isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
++this.pos;
}
}
out += this.input.slice(chunkStart, this.pos++);
return this.finishToken(_tokentype.types.string, out);
};
// Reads template string tokens.
pp.readTmplToken = function () {
var out = "",
chunkStart = this.pos;
for (;;) {
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
var ch = this.input.charCodeAt(this.pos);
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
// '`', '${'
if (this.pos === this.start && this.type === _tokentype.types.template) {
if (ch === 36) {
this.pos += 2;
return this.finishToken(_tokentype.types.dollarBraceL);
} else {
++this.pos;
return this.finishToken(_tokentype.types.backQuote);
}
}
out += this.input.slice(chunkStart, this.pos);
return this.finishToken(_tokentype.types.template, out);
}
if (ch === 92) {
// '\'
out += this.input.slice(chunkStart, this.pos);
out += this.readEscapedChar(true);
chunkStart = this.pos;
} else if (_whitespace.isNewLine(ch)) {
out += this.input.slice(chunkStart, this.pos);
++this.pos;
switch (ch) {
case 13:
if (this.input.charCodeAt(this.pos) === 10) ++this.pos;
case 10:
out += "\n";
break;
default:
out += String.fromCharCode(ch);
break;
}
if (this.options.locations) {
++this.curLine;
this.lineStart = this.pos;
}
chunkStart = this.pos;
} else {
++this.pos;
}
}
};
// Used to read escaped characters
pp.readEscapedChar = function (inTemplate) {
var ch = this.input.charCodeAt(++this.pos);
++this.pos;
switch (ch) {
case 110:
return "\n"; // 'n' -> '\n'
case 114:
return "\r"; // 'r' -> '\r'
case 120:
return String.fromCharCode(this.readHexChar(2)); // 'x'
case 117:
return codePointToString(this.readCodePoint()); // 'u'
case 116:
return "\t"; // 't' -> '\t'
case 98:
return "\b"; // 'b' -> '\b'
case 118:
return "\u000b"; // 'v' -> '\u000b'
case 102:
return "\f"; // 'f' -> '\f'
case 13:
if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
case 10:
// ' \n'
if (this.options.locations) {
this.lineStart = this.pos;++this.curLine;
}
return "";
default:
if (ch >= 48 && ch <= 55) {
var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
var octal = parseInt(octalStr, 8);
if (octal > 255) {
octalStr = octalStr.slice(0, -1);
octal = parseInt(octalStr, 8);
}
if (octal > 0 && (this.strict || inTemplate)) {
this.raise(this.pos - 2, "Octal literal in strict mode");
}
this.pos += octalStr.length - 1;
return String.fromCharCode(octal);
}
return String.fromCharCode(ch);
}
};
// Used to read character escape sequences ('\x', '\u', '\U').
pp.readHexChar = function (len) {
var codePos = this.pos;
var n = this.readInt(16, len);
if (n === null) this.raise(codePos, "Bad character escape sequence");
return n;
};
// Read an identifier, and return it as a string. Sets `this.containsEsc`
// to whether the word contained a '\u' escape.
//
// Incrementally adds only escaped chars, adding other chunks as-is
// as a micro-optimization.
pp.readWord1 = function () {
this.containsEsc = false;
var word = "",
first = true,
chunkStart = this.pos;
var astral = this.options.ecmaVersion >= 6;
while (this.pos < this.input.length) {
var ch = this.fullCharCodeAtPos();
if (_identifier.isIdentifierChar(ch, astral)) {
this.pos += ch <= 0xffff ? 1 : 2;
} else if (ch === 92) {
// "\"
this.containsEsc = true;
word += this.input.slice(chunkStart, this.pos);
var escStart = this.pos;
if (this.input.charCodeAt(++this.pos) != 117) // "u"
this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
++this.pos;
var esc = this.readCodePoint();
if (!(first ? _identifier.isIdentifierStart : _identifier.isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
word += codePointToString(esc);
chunkStart = this.pos;
} else {
break;
}
first = false;
}
return word + this.input.slice(chunkStart, this.pos);
};
// Read an identifier or keyword token. Will check for reserved
// words when necessary.
pp.readWord = function () {
var word = this.readWord1();
var type = _tokentype.types.name;
if ((this.options.ecmaVersion >= 6 || !this.containsEsc) && this.keywords.test(word)) type = _tokentype.keywords[word];
return this.finishToken(type, word);
};
},{"./identifier":2,"./locutil":5,"./state":10,"./tokentype":14,"./whitespace":16}],14:[function(_dereq_,module,exports){
// ## Token types
// The assignment of fine-grained, information-carrying type objects
// allows the tokenizer to store the information it has about a
// token in a way that is very cheap for the parser to look up.
// All token type variables start with an underscore, to make them
// easy to recognize.
// The `beforeExpr` property is used to disambiguate between regular
// expressions and divisions. It is set on all token types that can
// be followed by an expression (thus, a slash after them would be a
// regular expression).
//
// The `startsExpr` property is used to check if the token ends a
// `yield` expression. It is set on all token types that either can
// directly start an expression (like a quotation mark) or can
// continue an expression (like the body of a string).
//
// `isLoop` marks a keyword as starting a loop, which is important
// to know when parsing a label, in order to allow or disallow
// continue jumps to that label.
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var TokenType = function TokenType(label) {
var conf = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
_classCallCheck(this, TokenType);
this.label = label;
this.keyword = conf.keyword;
this.beforeExpr = !!conf.beforeExpr;
this.startsExpr = !!conf.startsExpr;
this.isLoop = !!conf.isLoop;
this.isAssign = !!conf.isAssign;
this.prefix = !!conf.prefix;
this.postfix = !!conf.postfix;
this.binop = conf.binop || null;
this.updateContext = null;
};
exports.TokenType = TokenType;
function binop(name, prec) {
return new TokenType(name, { beforeExpr: true, binop: prec });
}
var beforeExpr = { beforeExpr: true },
startsExpr = { startsExpr: true };
var types = {
num: new TokenType("num", startsExpr),
regexp: new TokenType("regexp", startsExpr),
string: new TokenType("string", startsExpr),
name: new TokenType("name", startsExpr),
eof: new TokenType("eof"),
// Punctuation token types.
bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
bracketR: new TokenType("]"),
braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
braceR: new TokenType("}"),
parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
parenR: new TokenType(")"),
comma: new TokenType(",", beforeExpr),
semi: new TokenType(";", beforeExpr),
colon: new TokenType(":", beforeExpr),
dot: new TokenType("."),
question: new TokenType("?", beforeExpr),
arrow: new TokenType("=>", beforeExpr),
template: new TokenType("template"),
ellipsis: new TokenType("...", beforeExpr),
backQuote: new TokenType("`", startsExpr),
dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
// Operators. These carry several kinds of properties to help the
// parser use them properly (the presence of these properties is
// what categorizes them as operators).
//
// `binop`, when present, specifies that this operator is a binary
// operator, and will refer to its precedence.
//
// `prefix` and `postfix` mark the operator as a prefix or postfix
// unary operator.
//
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
// binary operators with a very low precedence, that should result
// in AssignmentExpression nodes.
eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
logicalOR: binop("||", 1),
logicalAND: binop("&&", 2),
bitwiseOR: binop("|", 3),
bitwiseXOR: binop("^", 4),
bitwiseAND: binop("&", 5),
equality: binop("==/!=", 6),
relational: binop("</>", 7),
bitShift: binop("<</>>", 8),
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
modulo: binop("%", 10),
star: binop("*", 10),
slash: binop("/", 10)
};
exports.types = types;
// Map keyword names to token types.
var keywords = {};
exports.keywords = keywords;
// Succinct definitions of keyword token types
function kw(name) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
options.keyword = name;
keywords[name] = types["_" + name] = new TokenType(name, options);
}
kw("break");
kw("case", beforeExpr);
kw("catch");
kw("continue");
kw("debugger");
kw("default", beforeExpr);
kw("do", { isLoop: true, beforeExpr: true });
kw("else", beforeExpr);
kw("finally");
kw("for", { isLoop: true });
kw("function", startsExpr);
kw("if");
kw("return", beforeExpr);
kw("switch");
kw("throw", beforeExpr);
kw("try");
kw("var");
kw("let");
kw("const");
kw("while", { isLoop: true });
kw("with");
kw("new", { beforeExpr: true, startsExpr: true });
kw("this", startsExpr);
kw("super", startsExpr);
kw("class");
kw("extends", beforeExpr);
kw("export");
kw("import");
kw("yield", { beforeExpr: true, startsExpr: true });
kw("null", startsExpr);
kw("true", startsExpr);
kw("false", startsExpr);
kw("in", { beforeExpr: true, binop: 7 });
kw("instanceof", { beforeExpr: true, binop: 7 });
kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
},{}],15:[function(_dereq_,module,exports){
"use strict";
exports.__esModule = true;
exports.isArray = isArray;
exports.has = has;
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
}
// Checks if an object has a property.
function has(obj, propName) {
return Object.prototype.hasOwnProperty.call(obj, propName);
}
},{}],16:[function(_dereq_,module,exports){
// Matches a whole line break (where CRLF is considered a single
// line break). Used to count lines.
"use strict";
exports.__esModule = true;
exports.isNewLine = isNewLine;
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
exports.lineBreak = lineBreak;
var lineBreakG = new RegExp(lineBreak.source, "g");
exports.lineBreakG = lineBreakG;
function isNewLine(code) {
return code === 10 || code === 13 || code === 0x2028 || code == 0x2029;
}
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
exports.nonASCIIwhitespace = nonASCIIwhitespace;
},{}]},{},[3])(3)
});
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AnimationGroupPreviewUI.js | 2.7% | (1 / 37) | 0% | (0 / 2) | 0% | (0 / 5) | 2.7% | (1 / 37) | |
| AnimationModel.js | 2.67% | (7 / 262) | 0% | (0 / 81) | 0% | (0 / 88) | 2.67% | (7 / 262) | |
| AnimationScreenshotPopover.js | 3.33% | (1 / 30) | 0% | (0 / 6) | 0% | (0 / 4) | 3.33% | (1 / 30) | |
| AnimationTimeline.js | 1.42% | (5 / 353) | 0% | (0 / 103) | 0% | (0 / 59) | 1.42% | (5 / 353) | |
| AnimationUI.js | 1.64% | (3 / 183) | 0% | (0 / 75) | 0% | (0 / 21) | 1.64% | (3 / 183) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.AnimationModel.AnimationGroup} model
*/
WebInspector.AnimationGroupPreviewUI = function(model)
{
this._model = model;
this.element = createElementWithClass("div", "animation-buffer-preview");
this.element.createChild("div", "animation-paused fill");
this._removeButton = this.element.createChild("div", "animation-remove-button");
this._removeButton.textContent = "\u2715";
this._replayOverlayElement = this.element.createChild("div", "animation-buffer-preview-animation");
this._svg = this.element.createSVGChild("svg");
this._svg.setAttribute("width", "100%");
this._svg.setAttribute("preserveAspectRatio", "none");
this._svg.setAttribute("height", "100%");
this._viewBoxHeight = 32;
this._svg.setAttribute("viewBox", "0 0 100 " + this._viewBoxHeight);
this._svg.setAttribute("shape-rendering", "crispEdges");
this._render();
}
WebInspector.AnimationGroupPreviewUI.prototype = {
/**
* @return {number}
*/
_groupDuration: function()
{
var duration = 0;
for (var anim of this._model.animations()) {
var animDuration = anim.source().delay() + anim.source().duration();
if (animDuration > duration)
duration = animDuration;
}
return duration;
},
/**
* @return {!Element}
*/
removeButton: function()
{
return this._removeButton;
},
replay: function()
{
this._replayOverlayElement.animate([
{ offset: 0, width: "0%", opacity: 1 },
{ offset: 0.9, width: "100%", opacity: 1 },
{ offset: 1, width: "100%", opacity: 0 }
], { duration : 200, easing: "cubic-bezier(0, 0, 0.2, 1)" });
},
_render: function()
{
this._svg.removeChildren();
var maxToShow = 10;
var numberOfAnimations = Math.min(this._model.animations().length, maxToShow);
var timeToPixelRatio = 100 / Math.max(this._groupDuration(), 750);
for (var i = 0; i < numberOfAnimations; i++) {
var effect = this._model.animations()[i].source();
var line = this._svg.createSVGChild("line");
line.setAttribute("x1", effect.delay() * timeToPixelRatio);
line.setAttribute("x2", (effect.delay() + effect.duration()) * timeToPixelRatio);
var y = Math.floor(this._viewBoxHeight / Math.max(6, numberOfAnimations) * i + 1);
line.setAttribute("y1", y);
line.setAttribute("y2", y);
line.style.stroke = WebInspector.AnimationUI.Color(this._model.animations()[i]);
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | 2 1 1 1 1 1 1 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.AnimationModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.AnimationModel, target);
this._agent = target.animationAgent();
target.registerAnimationDispatcher(new WebInspector.AnimationDispatcher(this));
/** @type {!Map.<string, !WebInspector.AnimationModel.Animation>} */
this._animationsById = new Map();
/** @type {!Map.<string, !WebInspector.AnimationModel.AnimationGroup>} */
this._animationGroups = new Map();
/** @type {!Array.<string>} */
this._pendingAnimations = [];
this._playbackRate = 1;
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._reset, this);
this._screenshotCapture = new WebInspector.AnimationModel.ScreenshotCapture(target, this);
}
WebInspector.AnimationModel.Events = {
AnimationGroupStarted: "AnimationGroupStarted",
ModelReset: "ModelReset"
}
WebInspector.AnimationModel.prototype = {
_reset: function()
{
this._animationsById.clear();
this._animationGroups.clear();
this._pendingAnimations = [];
this.dispatchEventToListeners(WebInspector.AnimationModel.Events.ModelReset);
},
/**
* @param {string} id
*/
animationCreated: function(id)
{
this._pendingAnimations.push(id);
},
/**
* @param {string} id
*/
_animationCanceled: function(id)
{
this._pendingAnimations.remove(id);
this._flushPendingAnimationsIfNeeded();
},
/**
* @param {!AnimationAgent.Animation} payload
*/
animationStarted: function(payload)
{
var animation = WebInspector.AnimationModel.Animation.parsePayload(this.target(), payload);
// Ignore Web Animations custom effects & groups.
if (animation.type() === "WebAnimation" && animation.source().keyframesRule().keyframes().length === 0) {
this._pendingAnimations.remove(animation.id());
} else {
this._animationsById.set(animation.id(), animation);
if (this._pendingAnimations.indexOf(animation.id()) === -1)
this._pendingAnimations.push(animation.id());
}
this._flushPendingAnimationsIfNeeded();
},
_flushPendingAnimationsIfNeeded: function()
{
for (var id of this._pendingAnimations) {
if (!this._animationsById.get(id))
return;
}
while (this._pendingAnimations.length)
this._matchExistingGroups(this._createGroupFromPendingAnimations());
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} incomingGroup
* @return {boolean}
*/
_matchExistingGroups: function(incomingGroup)
{
var matchedGroup = null;
for (var group of this._animationGroups.values()) {
if (group._matches(incomingGroup)) {
matchedGroup = group;
group._update(incomingGroup);
break;
}
}
if (!matchedGroup) {
this._animationGroups.set(incomingGroup.id(), incomingGroup);
this._screenshotCapture.captureScreenshots(incomingGroup.finiteDuration(), incomingGroup._screenshots);
}
this.dispatchEventToListeners(WebInspector.AnimationModel.Events.AnimationGroupStarted, matchedGroup || incomingGroup);
return !!matchedGroup;
},
/**
* @return {!WebInspector.AnimationModel.AnimationGroup}
*/
_createGroupFromPendingAnimations: function()
{
console.assert(this._pendingAnimations.length);
var groupedAnimations = [this._animationsById.get(this._pendingAnimations.shift())];
var remainingAnimations = [];
for (var id of this._pendingAnimations) {
var anim = this._animationsById.get(id);
if (anim.startTime() === groupedAnimations[0].startTime())
groupedAnimations.push(anim);
else
remainingAnimations.push(id);
}
this._pendingAnimations = remainingAnimations;
return new WebInspector.AnimationModel.AnimationGroup(this, groupedAnimations[0].id(), groupedAnimations);
},
/**
* @return {!Promise.<number>}
*/
playbackRatePromise: function()
{
/**
* @param {?Protocol.Error} error
* @param {number} playbackRate
* @return {number}
* @this {!WebInspector.AnimationModel}
*/
function callback(error, playbackRate)
{
if (error)
return 1;
this._playbackRate = playbackRate;
return playbackRate;
}
return this._agent.getPlaybackRate(callback.bind(this)).catchException(1);
},
/**
* @param {number} playbackRate
*/
setPlaybackRate: function(playbackRate)
{
this._playbackRate = playbackRate;
this._agent.setPlaybackRate(playbackRate);
},
/**
* @param {!Array.<string>} animations
*/
_releaseAnimations: function(animations)
{
this.target().animationAgent().releaseAnimations(animations);
},
/**
* @override
* @return {!Promise}
*/
suspendModel: function()
{
this._reset();
return this._agent.disable();
},
/**
* @override
* @return {!Promise}
*/
resumeModel: function()
{
if (!this._enabled)
return Promise.resolve();
return this._agent.enable();
},
ensureEnabled: function()
{
if (this._enabled)
return;
this._agent.enable();
this._enabled = true;
},
__proto__: WebInspector.SDKModel.prototype
}
WebInspector.AnimationModel._symbol = Symbol("AnimationModel");
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.AnimationModel}
*/
WebInspector.AnimationModel.fromTarget = function(target)
{
if (!target[WebInspector.AnimationModel._symbol])
target[WebInspector.AnimationModel._symbol] = new WebInspector.AnimationModel(target);
return target[WebInspector.AnimationModel._symbol];
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {!AnimationAgent.Animation} payload
*/
WebInspector.AnimationModel.Animation = function(target, payload)
{
WebInspector.SDKObject.call(this, target);
this._payload = payload;
this._source = new WebInspector.AnimationModel.AnimationEffect(this.target(), this._payload.source);
}
/**
* @param {!WebInspector.Target} target
* @param {!AnimationAgent.Animation} payload
* @return {!WebInspector.AnimationModel.Animation}
*/
WebInspector.AnimationModel.Animation.parsePayload = function(target, payload)
{
return new WebInspector.AnimationModel.Animation(target, payload);
}
/** @enum {string} */
WebInspector.AnimationModel.Animation.Type = {
CSSTransition: "CSSTransition",
CSSAnimation: "CSSAnimation",
WebAnimation: "WebAnimation"
}
WebInspector.AnimationModel.Animation.prototype = {
/**
* @return {!AnimationAgent.Animation}
*/
payload: function()
{
return this._payload;
},
/**
* @return {string}
*/
id: function()
{
return this._payload.id;
},
/**
* @return {string}
*/
name: function()
{
return this._payload.name;
},
/**
* @return {boolean}
*/
paused: function()
{
return this._payload.pausedState;
},
/**
* @return {string}
*/
playState: function()
{
return this._playState || this._payload.playState;
},
/**
* @param {string} playState
*/
setPlayState: function(playState)
{
this._playState = playState;
},
/**
* @return {number}
*/
playbackRate: function()
{
return this._payload.playbackRate;
},
/**
* @return {number}
*/
startTime: function()
{
return this._payload.startTime;
},
/**
* @return {number}
*/
endTime: function()
{
if (!this.source().iterations)
return Infinity;
return this.startTime() + this.source().delay() + this.source().duration() * this.source().iterations() + this.source().endDelay();
},
/**
* @return {number}
*/
_finiteDuration: function()
{
var iterations = Math.min(this.source().iterations(), 3);
return this.source().delay() + this.source().duration() * iterations;
},
/**
* @return {number}
*/
currentTime: function()
{
return this._payload.currentTime;
},
/**
* @return {!WebInspector.AnimationModel.AnimationEffect}
*/
source: function()
{
return this._source;
},
/**
* @return {!WebInspector.AnimationModel.Animation.Type}
*/
type: function()
{
return /** @type {!WebInspector.AnimationModel.Animation.Type} */(this._payload.type);
},
/**
* @param {!WebInspector.AnimationModel.Animation} animation
* @return {boolean}
*/
overlaps: function(animation)
{
// Infinite animations
if (!this.source().iterations() || !animation.source().iterations())
return true;
var firstAnimation = this.startTime() < animation.startTime() ? this : animation;
var secondAnimation = firstAnimation === this ? animation : this;
return firstAnimation.endTime() >= secondAnimation.startTime();
},
/**
* @param {number} duration
* @param {number} delay
*/
setTiming: function(duration, delay)
{
this._source.node().then(this._updateNodeStyle.bind(this, duration, delay));
this._source._duration = duration;
this._source._delay = delay;
this.target().animationAgent().setTiming(this.id(), duration, delay);
},
/**
* @param {number} duration
* @param {number} delay
* @param {!WebInspector.DOMNode} node
*/
_updateNodeStyle: function(duration, delay, node)
{
var animationPrefix;
if (this.type() == WebInspector.AnimationModel.Animation.Type.CSSTransition)
animationPrefix = "transition-";
else if (this.type() == WebInspector.AnimationModel.Animation.Type.CSSAnimation)
animationPrefix = "animation-";
else
return;
var cssModel = WebInspector.CSSModel.fromTarget(node.target());
if (!cssModel)
return;
cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + "duration", duration + "ms");
cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + "delay", delay + "ms");
},
/**
* @return {!Promise.<?WebInspector.RemoteObject>}
*/
remoteObjectPromise: function()
{
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} payload
* @return {?WebInspector.RemoteObject}
* @this {!WebInspector.AnimationModel.Animation}
*/
function callback(error, payload)
{
return !error ? this.target().runtimeModel.createRemoteObject(payload) : null;
}
return this.target().animationAgent().resolveAnimation(this.id(), callback.bind(this));
},
/**
* @return {string}
*/
_cssId: function()
{
return this._payload.cssId || "";
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {!AnimationAgent.AnimationEffect} payload
*/
WebInspector.AnimationModel.AnimationEffect = function(target, payload)
{
WebInspector.SDKObject.call(this, target);
this._payload = payload;
if (payload.keyframesRule)
this._keyframesRule = new WebInspector.AnimationModel.KeyframesRule(target, payload.keyframesRule);
this._delay = this._payload.delay;
this._duration = this._payload.duration;
}
WebInspector.AnimationModel.AnimationEffect.prototype = {
/**
* @return {number}
*/
delay: function()
{
return this._delay;
},
/**
* @return {number}
*/
endDelay: function()
{
return this._payload.endDelay;
},
/**
* @return {number}
*/
playbackRate: function()
{
return this._payload.playbackRate;
},
/**
* @return {number}
*/
iterationStart: function()
{
return this._payload.iterationStart;
},
/**
* @return {number}
*/
iterations: function()
{
// Animations with zero duration, zero delays and infinite iterations can't be shown.
if (!this.delay() && !this.endDelay() && !this.duration())
return 0;
return this._payload.iterations || Infinity;
},
/**
* @return {number}
*/
duration: function()
{
return this._duration;
},
/**
* @return {string}
*/
direction: function()
{
return this._payload.direction;
},
/**
* @return {string}
*/
fill: function()
{
return this._payload.fill;
},
/**
* @return {!Promise.<!WebInspector.DOMNode>}
*/
node: function()
{
if (!this._deferredNode)
this._deferredNode = new WebInspector.DeferredDOMNode(this.target(), this.backendNodeId());
return this._deferredNode.resolvePromise();
},
/**
* @return {!WebInspector.DeferredDOMNode}
*/
deferredNode: function()
{
return new WebInspector.DeferredDOMNode(this.target(), this.backendNodeId());
},
/**
* @return {number}
*/
backendNodeId: function()
{
return this._payload.backendNodeId;
},
/**
* @return {?WebInspector.AnimationModel.KeyframesRule}
*/
keyframesRule: function()
{
return this._keyframesRule;
},
/**
* @return {string}
*/
easing: function()
{
return this._payload.easing;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {!AnimationAgent.KeyframesRule} payload
*/
WebInspector.AnimationModel.KeyframesRule = function(target, payload)
{
WebInspector.SDKObject.call(this, target);
this._payload = payload;
this._keyframes = this._payload.keyframes.map(function (keyframeStyle) {
return new WebInspector.AnimationModel.KeyframeStyle(target, keyframeStyle);
});
}
WebInspector.AnimationModel.KeyframesRule.prototype = {
/**
* @param {!Array.<!AnimationAgent.KeyframeStyle>} payload
*/
_setKeyframesPayload: function(payload)
{
this._keyframes = payload.map(function (keyframeStyle) {
return new WebInspector.AnimationModel.KeyframeStyle(this._target, keyframeStyle);
});
},
/**
* @return {string|undefined}
*/
name: function()
{
return this._payload.name;
},
/**
* @return {!Array.<!WebInspector.AnimationModel.KeyframeStyle>}
*/
keyframes: function()
{
return this._keyframes;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {!AnimationAgent.KeyframeStyle} payload
*/
WebInspector.AnimationModel.KeyframeStyle = function(target, payload)
{
WebInspector.SDKObject.call(this, target);
this._payload = payload;
this._offset = this._payload.offset;
}
WebInspector.AnimationModel.KeyframeStyle.prototype = {
/**
* @return {string}
*/
offset: function()
{
return this._offset;
},
/**
* @param {number} offset
*/
setOffset: function(offset)
{
this._offset = offset * 100 + "%";
},
/**
* @return {number}
*/
offsetAsNumber: function()
{
return parseFloat(this._offset) / 100;
},
/**
* @return {string}
*/
easing: function()
{
return this._payload.easing;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.AnimationModel} model
* @param {string} id
* @param {!Array.<!WebInspector.AnimationModel.Animation>} animations
*/
WebInspector.AnimationModel.AnimationGroup = function(model, id, animations)
{
WebInspector.SDKObject.call(this, model.target());
this._model = model;
this._id = id;
this._animations = animations;
this._paused = false;
this._screenshots = [];
this._screenshotImages = [];
}
WebInspector.AnimationModel.AnimationGroup.prototype = {
/**
* @return {string}
*/
id: function()
{
return this._id;
},
/**
* @return {!Array.<!WebInspector.AnimationModel.Animation>}
*/
animations: function()
{
return this._animations;
},
release: function()
{
this._model._animationGroups.remove(this.id());
this._model._releaseAnimations(this._animationIds());
},
/**
* @return {!Array.<string>}
*/
_animationIds: function()
{
/**
* @param {!WebInspector.AnimationModel.Animation} animation
* @return {string}
*/
function extractId(animation)
{
return animation.id();
}
return this._animations.map(extractId);
},
/**
* @return {number}
*/
startTime: function()
{
return this._animations[0].startTime();
},
/**
* @return {number}
*/
finiteDuration: function()
{
var maxDuration = 0;
for (var i = 0; i < this._animations.length; ++i)
maxDuration = Math.max(maxDuration, this._animations[i]._finiteDuration());
return maxDuration;
},
/**
* @param {number} currentTime
*/
seekTo: function(currentTime)
{
this.target().animationAgent().seekAnimations(this._animationIds(), currentTime);
},
/**
* @return {boolean}
*/
paused: function()
{
return this._paused;
},
/**
* @param {boolean} paused
*/
togglePause: function(paused)
{
if (paused === this._paused)
return;
this._paused = paused;
this.target().animationAgent().setPaused(this._animationIds(), paused);
},
/**
* @return {!Promise.<number>}
*/
currentTimePromise: function()
{
/**
* @param {?Protocol.Error} error
* @param {number} currentTime
* @return {number}
*/
function callback(error, currentTime)
{
return !error ? currentTime : 0;
}
var longestAnim = null;
for (var anim of this._animations) {
if (!longestAnim || anim.endTime() > longestAnim.endTime())
longestAnim = anim;
}
return this.target().animationAgent().getCurrentTime(longestAnim.id(), callback).catchException(0);
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} group
* @return {boolean}
*/
_matches: function(group)
{
/**
* @param {!WebInspector.AnimationModel.Animation} anim
* @return {string}
*/
function extractId(anim)
{
if (anim.type() === WebInspector.AnimationModel.Animation.Type.WebAnimation)
return anim.type() + anim.id();
else
return anim._cssId();
}
if (this._animations.length !== group._animations.length)
return false;
var left = this._animations.map(extractId).sort();
var right = group._animations.map(extractId).sort();
for (var i = 0; i < left.length; i++) {
if (left[i] !== right[i])
return false;
}
return true;
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} group
*/
_update: function(group)
{
this._model._releaseAnimations(this._animationIds());
this._animations = group._animations;
},
/**
* @return {!Array.<!Image>}
*/
screenshots: function()
{
for (var i = 0; i < this._screenshots.length; ++i) {
var image = new Image();
image.src = "data:image/jpeg;base64," + this._screenshots[i];
this._screenshotImages.push(image);
}
this._screenshots = [];
return this._screenshotImages;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @implements {AnimationAgent.Dispatcher}
*/
WebInspector.AnimationDispatcher = function(animationModel)
{
this._animationModel = animationModel;
}
WebInspector.AnimationDispatcher.prototype = {
/**
* @override
* @param {string} id
*/
animationCreated: function(id)
{
this._animationModel.animationCreated(id);
},
/**
* @override
* @param {string} id
*/
animationCanceled: function(id)
{
this._animationModel._animationCanceled(id);
},
/**
* @override
* @param {!AnimationAgent.Animation} payload
*/
animationStarted: function(payload)
{
this._animationModel.animationStarted(payload);
}
}
/**
* @constructor
* @param {!WebInspector.Target} target
* @param {!WebInspector.AnimationModel} model
*/
WebInspector.AnimationModel.ScreenshotCapture = function(target, model)
{
this._target = target;
/** @type {!Array<!WebInspector.AnimationModel.ScreenshotCapture.Request>} */
this._requests = [];
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, this._screencastFrame, this);
this._model = model;
this._model.addEventListener(WebInspector.AnimationModel.Events.ModelReset, this._stopScreencast, this);
}
/** @typedef {{ endTime: number, screenshots: !Array.<string>}} */
WebInspector.AnimationModel.ScreenshotCapture.Request;
WebInspector.AnimationModel.ScreenshotCapture.prototype = {
/**
* @param {number} duration
* @param {!Array<string>} screenshots
*/
captureScreenshots: function(duration, screenshots)
{
var screencastDuration = Math.min(duration / this._model._playbackRate, 3000);
var endTime = screencastDuration + window.performance.now();
this._requests.push({ endTime: endTime, screenshots: screenshots });
if (!this._endTime || endTime > this._endTime) {
clearTimeout(this._stopTimer);
this._stopTimer = setTimeout(this._stopScreencast.bind(this), screencastDuration);
this._endTime = endTime;
}
if (this._capturing)
return;
this._capturing = true;
this._target.pageAgent().startScreencast("jpeg", 80, undefined, 300, 2);
},
/**
* @param {!WebInspector.Event} event
*/
_screencastFrame: function(event)
{
/**
* @param {!WebInspector.AnimationModel.ScreenshotCapture.Request} request
* @return {boolean}
*/
function isAnimating(request)
{
return request.endTime >= now;
}
if (!this._capturing)
return;
var base64Data = /** type {string} */(event.data["data"]);
var now = window.performance.now();
this._requests = this._requests.filter(isAnimating);
for (var request of this._requests)
request.screenshots.push(base64Data);
},
_stopScreencast: function()
{
if (!this._capturing)
return;
delete this._stopTimer;
delete this._endTime;
this._requests = [];
this._capturing = false;
this._target.pageAgent().stopScreencast();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!Array.<!Image>} images
*/
WebInspector.AnimationScreenshotPopover = function(images)
{
WebInspector.VBox.call(this, true);
console.assert(images.length);
this.registerRequiredCSS("animation/animationScreenshotPopover.css");
this.contentElement.classList.add("animation-screenshot-popover");
this._frames = images;
for (var image of images) {
this.contentElement.appendChild(image);
image.style.display = "none";
}
this._currentFrame = 0;
this._frames[0].style.display = "block";
this._progressBar = this.contentElement.createChild("div", "animation-progress");
}
WebInspector.AnimationScreenshotPopover.prototype = {
wasShown: function()
{
this._rafId = this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));
},
willHide: function()
{
this.contentElement.window().cancelAnimationFrame(this._rafId);
delete this._endDelay;
},
_changeFrame: function()
{
this._rafId = this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));
if (this._endDelay) {
this._endDelay--;
return;
}
this._showFrame = !this._showFrame;
if (!this._showFrame)
return;
var numFrames = this._frames.length;
this._frames[this._currentFrame % numFrames].style.display = "none";
this._currentFrame++;
this._frames[(this._currentFrame) % numFrames].style.display = "block";
if (this._currentFrame % numFrames === numFrames - 1)
this._endDelay = 50;
this._progressBar.style.width = (this._currentFrame % numFrames + 1) / numFrames * 100 + "%";
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | 2 1 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.AnimationTimeline = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("animation/animationTimeline.css");
this.element.classList.add("animations-timeline");
this._grid = this.contentElement.createSVGChild("svg", "animation-timeline-grid");
this._underlyingPlaybackRate = 1;
this._createHeader();
this._animationsContainer = this.contentElement.createChild("div", "animation-timeline-rows");
var timelineHint = this.contentElement.createChild("div", "animation-timeline-rows-hint");
timelineHint.textContent = WebInspector.UIString("Select an effect above to inspect and modify.");
/** @const */ this._defaultDuration = 100;
this._duration = this._defaultDuration;
/** @const */ this._timelineControlsWidth = 150;
/** @type {!Map.<!DOMAgent.BackendNodeId, !WebInspector.AnimationTimeline.NodeUI>} */
this._nodesMap = new Map();
this._uiAnimations = [];
this._groupBuffer = [];
/** @type {!Map.<!WebInspector.AnimationModel.AnimationGroup, !WebInspector.AnimationGroupPreviewUI>} */
this._previewMap = new Map();
this._symbol = Symbol("animationTimeline");
/** @type {!Map.<string, !WebInspector.AnimationModel.Animation>} */
this._animationsMap = new Map();
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
}
WebInspector.AnimationTimeline.GlobalPlaybackRates = [1, 0.25, 0.1];
/** @enum {string} */
WebInspector.AnimationTimeline._ControlState = {
Play: "play-outline",
Replay: "replay-outline",
Pause: "pause-outline"
}
WebInspector.AnimationTimeline.prototype = {
wasShown: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
this._addEventListeners(target);
},
willHide: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
this._removeEventListeners(target);
this._popoverHelper.hidePopover();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (this.isShowing())
this._addEventListeners(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
this._removeEventListeners(target);
},
/**
* @param {!WebInspector.Target} target
*/
_addEventListeners: function(target)
{
var animationModel = WebInspector.AnimationModel.fromTarget(target);
animationModel.ensureEnabled();
animationModel.addEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this);
animationModel.addEventListener(WebInspector.AnimationModel.Events.ModelReset, this._reset, this);
},
/**
* @param {!WebInspector.Target} target
*/
_removeEventListeners: function(target)
{
var animationModel = WebInspector.AnimationModel.fromTarget(target);
animationModel.removeEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this);
animationModel.removeEventListener(WebInspector.AnimationModel.Events.ModelReset, this._reset, this);
},
_nodeChanged: function()
{
for (var nodeUI of this._nodesMap.values())
nodeUI._nodeChanged();
},
/**
* @return {!Element} element
*/
_createScrubber: function() {
this._timelineScrubber = createElementWithClass("div", "animation-scrubber hidden");
this._timelineScrubberLine = this._timelineScrubber.createChild("div", "animation-scrubber-line");
this._timelineScrubberLine.createChild("div", "animation-scrubber-head");
this._timelineScrubber.createChild("div", "animation-time-overlay");
return this._timelineScrubber;
},
_createHeader: function()
{
var toolbarContainer = this.contentElement.createChild("div", "animation-timeline-toolbar-container");
var topToolbar = new WebInspector.Toolbar("animation-timeline-toolbar", toolbarContainer);
var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear all"), "clear-toolbar-item");
clearButton.addEventListener("click", this._reset.bind(this));
topToolbar.appendToolbarItem(clearButton);
topToolbar.appendSeparator();
var playbackRateControl = toolbarContainer.createChild("div", "animation-playback-rate-control");
this._playbackRateButtons = [];
for (var playbackRate of WebInspector.AnimationTimeline.GlobalPlaybackRates) {
var button = playbackRateControl.createChild("div", "animation-playback-rate-button");
button.textContent = WebInspector.UIString(playbackRate * 100 + "%");
button.playbackRate = playbackRate;
button.addEventListener("click", this._setPlaybackRate.bind(this, playbackRate));
button.title = WebInspector.UIString("Set speed to ") + button.textContent;
this._playbackRateButtons.push(button);
}
this._updatePlaybackControls();
this._previewContainer = this.contentElement.createChild("div", "animation-timeline-buffer");
this._popoverHelper = new WebInspector.PopoverHelper(this._previewContainer, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), this._onHidePopover.bind(this), true);
this._popoverHelper.setTimeout(0);
var emptyBufferHint = this.contentElement.createChild("div", "animation-timeline-buffer-hint");
emptyBufferHint.textContent = WebInspector.UIString("Listening for animations...");
var container = this.contentElement.createChild("div", "animation-timeline-header");
var controls = container.createChild("div", "animation-controls");
this._currentTime = controls.createChild("div", "animation-timeline-current-time monospace");
var toolbar = new WebInspector.Toolbar("animation-controls-toolbar", controls);
this._controlButton = new WebInspector.ToolbarButton(WebInspector.UIString("Replay timeline"), "animation-control-toolbar-item");
this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Replay);
this._controlButton.addEventListener("click", this._controlButtonToggle.bind(this));
toolbar.appendToolbarItem(this._controlButton);
var gridHeader = container.createChild("div", "animation-grid-header");
WebInspector.installDragHandle(gridHeader, this._repositionScrubber.bind(this), this._scrubberDragMove.bind(this), this._scrubberDragEnd.bind(this), "text");
container.appendChild(this._createScrubber());
WebInspector.installDragHandle(this._timelineScrubberLine, this._scrubberDragStart.bind(this), this._scrubberDragMove.bind(this), this._scrubberDragEnd.bind(this), "col-resize");
this._currentTime.textContent = "";
return container;
},
/**
* @param {!Element} element
* @param {!Event} event
* @return {!Element|!AnchorBox|undefined}
*/
_getPopoverAnchor: function(element, event)
{
if (element.isDescendant(this._previewContainer))
return element;
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showPopover: function(anchor, popover)
{
var animGroup;
for (var group of this._previewMap.keysArray()) {
if (this._previewMap.get(group).element === anchor.parentElement)
animGroup = group;
}
console.assert(animGroup);
var screenshots = animGroup.screenshots();
if (!screenshots.length)
return;
var content = new WebInspector.AnimationScreenshotPopover(screenshots);
popover.setNoMargins(true);
popover.showView(content, anchor);
},
_onHidePopover: function()
{
},
/**
* @param {number} playbackRate
*/
_setPlaybackRate: function(playbackRate)
{
this._underlyingPlaybackRate = playbackRate;
var target = WebInspector.targetManager.mainTarget();
if (target)
WebInspector.AnimationModel.fromTarget(target).setPlaybackRate(this._underlyingPlaybackRate);
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.AnimationsPlaybackRateChanged);
if (this._scrubberPlayer)
this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
this._updatePlaybackControls();
},
_updatePlaybackControls: function()
{
for (var button of this._playbackRateButtons) {
var selected = this._underlyingPlaybackRate === button.playbackRate;
button.classList.toggle("selected", selected);
}
},
_controlButtonToggle: function()
{
if (this._controlButton.state() === WebInspector.AnimationTimeline._ControlState.Play)
this._togglePause(false);
else if (this._controlButton.state() === WebInspector.AnimationTimeline._ControlState.Replay)
this._replay();
else
this._togglePause(true);
},
_updateControlButton: function()
{
this._controlButton.setEnabled(!!this._selectedGroup);
if (this._selectedGroup && this._selectedGroup.paused()) {
this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Play);
this._controlButton.setTitle(WebInspector.UIString("Play timeline"));
} else if (!this._scrubberPlayer || this._scrubberPlayer.currentTime >= this.duration()) {
this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Replay);
this._controlButton.setTitle(WebInspector.UIString("Replay timeline"));
} else {
this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Pause);
this._controlButton.setTitle(WebInspector.UIString("Pause timeline"));
}
},
_updateAnimationsPlaybackRate: function()
{
/**
* @param {number} playbackRate
* @this {WebInspector.AnimationTimeline}
*/
function syncPlaybackRate(playbackRate)
{
this._underlyingPlaybackRate = playbackRate || 1;
this._updatePlaybackControls();
}
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
WebInspector.AnimationModel.fromTarget(target).playbackRatePromise().then(syncPlaybackRate.bind(this));
},
/**
* @return {number}
*/
_effectivePlaybackRate: function()
{
return this._selectedGroup && this._selectedGroup.paused() ? 0 : this._underlyingPlaybackRate;
},
/**
* @param {boolean} pause
*/
_togglePause: function(pause)
{
this._selectedGroup.togglePause(pause);
if (this._scrubberPlayer)
this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
this._previewMap.get(this._selectedGroup).element.classList.toggle("paused", pause);
this._updateControlButton();
},
_replay: function()
{
if (!this._selectedGroup)
return;
this._selectedGroup.seekTo(0);
this._animateTime(0);
this._updateControlButton();
},
/**
* @return {number}
*/
duration: function()
{
return this._duration;
},
/**
* @param {number} duration
*/
setDuration: function(duration)
{
this._duration = duration;
this.scheduleRedraw();
},
_clearTimeline: function()
{
this._uiAnimations = [];
this._nodesMap.clear();
this._animationsMap.clear();
this._animationsContainer.removeChildren();
this._duration = this._defaultDuration;
this._timelineScrubber.classList.add("hidden");
delete this._selectedGroup;
if (this._scrubberPlayer)
this._scrubberPlayer.cancel();
delete this._scrubberPlayer;
this._currentTime.textContent = "";
this._updateControlButton();
},
_reset: function()
{
this._clearTimeline();
this._updateAnimationsPlaybackRate();
for (var group of this._groupBuffer)
group.release();
this._groupBuffer = [];
this._previewMap.clear();
this._previewContainer.removeChildren();
this._popoverHelper.hidePopover();
this._renderGrid();
},
/**
* @param {!WebInspector.Event} event
*/
_animationGroupStarted: function(event)
{
this._addAnimationGroup(/** @type {!WebInspector.AnimationModel.AnimationGroup} */(event.data));
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} group
*/
_addAnimationGroup: function(group)
{
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} left
* @param {!WebInspector.AnimationModel.AnimationGroup} right
*/
function startTimeComparator(left, right)
{
return left.startTime() > right.startTime();
}
if (this._previewMap.get(group)) {
if (this._selectedGroup === group)
this._syncScrubber();
else
this._previewMap.get(group).replay();
return;
}
this._groupBuffer.sort(startTimeComparator);
// Discard oldest groups from buffer if necessary
var groupsToDiscard = [];
var bufferSize = this.width() / 50;
while (this._groupBuffer.length > bufferSize) {
var toDiscard = this._groupBuffer.splice(this._groupBuffer[0] === this._selectedGroup ? 1 : 0, 1);
groupsToDiscard.push(toDiscard[0]);
}
for (var g of groupsToDiscard) {
this._previewMap.get(g).element.remove();
this._previewMap.delete(g);
g.release();
}
// Generate preview
var preview = new WebInspector.AnimationGroupPreviewUI(group);
this._groupBuffer.push(group);
this._previewMap.set(group, preview);
this._previewContainer.appendChild(preview.element);
preview.removeButton().addEventListener("click", this._removeAnimationGroup.bind(this, group));
preview.element.addEventListener("click", this._selectAnimationGroup.bind(this, group));
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} group
* @param {!Event} event
*/
_removeAnimationGroup: function(group, event)
{
this._groupBuffer.remove(group);
this._previewMap.get(group).element.remove();
this._previewMap.delete(group);
group.release();
event.consume(true);
if (this._selectedGroup === group) {
this._clearTimeline();
this._renderGrid();
}
},
/**
* @param {!WebInspector.AnimationModel.AnimationGroup} group
*/
_selectAnimationGroup: function(group)
{
/**
* @param {!WebInspector.AnimationGroupPreviewUI} ui
* @param {!WebInspector.AnimationModel.AnimationGroup} group
* @this {!WebInspector.AnimationTimeline}
*/
function applySelectionClass(ui, group)
{
ui.element.classList.toggle("selected", this._selectedGroup === group);
}
if (this._selectedGroup === group) {
this._togglePause(false);
this._replay();
return;
}
this._clearTimeline();
this._selectedGroup = group;
this._previewMap.forEach(applySelectionClass, this);
this.setDuration(Math.max(500, group.finiteDuration() + 100));
for (var anim of group.animations())
this._addAnimation(anim);
this.scheduleRedraw();
this._timelineScrubber.classList.remove("hidden");
this._togglePause(false);
this._replay();
},
/**
* @param {!WebInspector.AnimationModel.Animation} animation
*/
_addAnimation: function(animation)
{
/**
* @param {?WebInspector.DOMNode} node
* @this {WebInspector.AnimationTimeline}
*/
function nodeResolved(node)
{
nodeUI.nodeResolved(node);
uiAnimation.setNode(node);
if (node)
node[this._symbol] = nodeUI;
}
var nodeUI = this._nodesMap.get(animation.source().backendNodeId());
if (!nodeUI) {
nodeUI = new WebInspector.AnimationTimeline.NodeUI(animation.source());
this._animationsContainer.appendChild(nodeUI.element);
this._nodesMap.set(animation.source().backendNodeId(), nodeUI);
}
var nodeRow = nodeUI.createNewRow();
var uiAnimation = new WebInspector.AnimationUI(animation, this, nodeRow);
animation.source().deferredNode().resolve(nodeResolved.bind(this));
this._uiAnimations.push(uiAnimation);
this._animationsMap.set(animation.id(), animation);
},
/**
* @param {!WebInspector.Event} event
*/
_nodeRemoved: function(event)
{
var node = event.data.node;
if (node[this._symbol])
node[this._symbol].nodeRemoved();
},
_renderGrid: function()
{
/** @const */ var gridSize = 250;
this._grid.setAttribute("width", this.width() + 10);
this._grid.setAttribute("height", this._cachedTimelineHeight + 30);
this._grid.setAttribute("shape-rendering", "crispEdges");
this._grid.removeChildren();
var lastDraw = undefined;
for (var time = 0; time < this.duration(); time += gridSize) {
var line = this._grid.createSVGChild("rect", "animation-timeline-grid-line");
line.setAttribute("x", time * this.pixelMsRatio() + 10);
line.setAttribute("y", 23);
line.setAttribute("height", "100%");
line.setAttribute("width", 1);
}
for (var time = 0; time < this.duration(); time += gridSize) {
var gridWidth = time * this.pixelMsRatio();
if (lastDraw === undefined || gridWidth - lastDraw > 50) {
lastDraw = gridWidth;
var label = this._grid.createSVGChild("text", "animation-timeline-grid-label");
label.textContent = WebInspector.UIString(Number.millisToString(time));
label.setAttribute("x", gridWidth + 10);
label.setAttribute("y", 16);
}
}
},
scheduleRedraw: function()
{
this._renderQueue = [];
for (var ui of this._uiAnimations)
this._renderQueue.push(ui);
if (this._redrawing)
return;
this._redrawing = true;
this._renderGrid();
this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));
},
/**
* @param {number=} timestamp
*/
_render: function(timestamp)
{
while (this._renderQueue.length && (!timestamp || window.performance.now() - timestamp < 50))
this._renderQueue.shift().redraw();
if (this._renderQueue.length)
this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));
else
delete this._redrawing;
},
onResize: function()
{
this._cachedTimelineWidth = Math.max(0, this._animationsContainer.offsetWidth - this._timelineControlsWidth) || 0;
this._cachedTimelineHeight = this._animationsContainer.offsetHeight;
this.scheduleRedraw();
if (this._scrubberPlayer)
this._syncScrubber();
delete this._gridOffsetLeft;
},
/**
* @return {number}
*/
width: function()
{
return this._cachedTimelineWidth || 0;
},
/**
* @param {!WebInspector.AnimationModel.Animation} animation
* @return {boolean}
*/
_resizeWindow: function(animation)
{
var resized = false;
// This shows at most 3 iterations
var duration = animation.source().duration() * Math.min(2, animation.source().iterations());
var requiredDuration = animation.source().delay() + duration + animation.source().endDelay();
if (requiredDuration > this._duration) {
resized = true;
this._duration = requiredDuration + 200;
}
return resized;
},
_syncScrubber: function()
{
if (!this._selectedGroup)
return;
this._selectedGroup.currentTimePromise()
.then(this._animateTime.bind(this))
.then(this._updateControlButton.bind(this));
},
/**
* @param {number} currentTime
*/
_animateTime: function(currentTime)
{
if (this._scrubberPlayer)
this._scrubberPlayer.cancel();
this._scrubberPlayer = this._timelineScrubber.animate([
{ transform: "translateX(0px)" },
{ transform: "translateX(" + this.width() + "px)" }
], { duration: this.duration(), fill: "forwards" });
this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
this._scrubberPlayer.onfinish = this._updateControlButton.bind(this);
this._scrubberPlayer.currentTime = currentTime;
this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));
},
/**
* @return {number}
*/
pixelMsRatio: function()
{
return this.width() / this.duration() || 0;
},
/**
* @param {number} timestamp
*/
_updateScrubber: function(timestamp)
{
if (!this._scrubberPlayer)
return;
this._currentTime.textContent = WebInspector.UIString(Number.millisToString(this._scrubberPlayer.currentTime));
if (this._scrubberPlayer.playState === "pending" || this._scrubberPlayer.playState === "running") {
this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));
} else if (this._scrubberPlayer.playState === "finished") {
this._currentTime.textContent = "";
}
},
/**
* @param {!Event} event
* @return {boolean}
*/
_repositionScrubber: function(event)
{
if (!this._selectedGroup)
return false;
// Seek to current mouse position.
if (!this._gridOffsetLeft)
this._gridOffsetLeft = this._grid.totalOffsetLeft() + 10;
var seekTime = Math.max(0, event.x - this._gridOffsetLeft) / this.pixelMsRatio();
this._selectedGroup.seekTo(seekTime);
this._togglePause(true);
this._animateTime(seekTime);
// Interface with scrubber drag.
this._originalScrubberTime = seekTime;
this._originalMousePosition = event.x;
return true;
},
/**
* @param {!Event} event
* @return {boolean}
*/
_scrubberDragStart: function(event)
{
if (!this._scrubberPlayer || !this._selectedGroup)
return false;
this._originalScrubberTime = this._scrubberPlayer.currentTime;
this._timelineScrubber.classList.remove("animation-timeline-end");
this._scrubberPlayer.pause();
this._originalMousePosition = event.x;
this._togglePause(true);
return true;
},
/**
* @param {!Event} event
*/
_scrubberDragMove: function(event)
{
var delta = event.x - this._originalMousePosition;
var currentTime = Math.max(0, Math.min(this._originalScrubberTime + delta / this.pixelMsRatio(), this.duration()));
this._scrubberPlayer.currentTime = currentTime;
this._currentTime.textContent = WebInspector.UIString(Number.millisToString(Math.round(currentTime)));
this._selectedGroup.seekTo(currentTime);
},
/**
* @param {!Event} event
*/
_scrubberDragEnd: function(event)
{
var currentTime = Math.max(0, this._scrubberPlayer.currentTime);
this._scrubberPlayer.play();
this._scrubberPlayer.currentTime = currentTime;
this._currentTime.window().requestAnimationFrame(this._updateScrubber.bind(this));
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {!WebInspector.AnimationModel.AnimationEffect} animationEffect
*/
WebInspector.AnimationTimeline.NodeUI = function(animationEffect)
{
this.element = createElementWithClass("div", "animation-node-row");
this._description = this.element.createChild("div", "animation-node-description");
this._timelineElement = this.element.createChild("div", "animation-node-timeline");
}
WebInspector.AnimationTimeline.NodeUI.prototype = {
/**
* @param {?WebInspector.DOMNode} node
*/
nodeResolved: function(node)
{
if (!node) {
this._description.createTextChild(WebInspector.UIString("<node>"));
return;
}
this._node = node;
this._nodeChanged();
this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
if (!node.ownerDocument)
this.nodeRemoved();
},
/**
* @return {!Element}
*/
createNewRow: function()
{
return this._timelineElement.createChild("div", "animation-timeline-row");
},
nodeRemoved: function()
{
this.element.classList.add("animation-node-removed");
this._node = null;
},
_nodeChanged: function()
{
this.element.classList.toggle("animation-node-selected", this._node && this._node === WebInspector.context.flavor(WebInspector.DOMNode));
}
}
/**
* @constructor
* @param {number} steps
* @param {string} stepAtPosition
*/
WebInspector.AnimationTimeline.StepTimingFunction = function(steps, stepAtPosition)
{
this.steps = steps;
this.stepAtPosition = stepAtPosition;
}
/**
* @param {string} text
* @return {?WebInspector.AnimationTimeline.StepTimingFunction}
*/
WebInspector.AnimationTimeline.StepTimingFunction.parse = function(text) {
var match = text.match(/^step-(start|middle|end)$/);
if (match)
return new WebInspector.AnimationTimeline.StepTimingFunction(1, match[1]);
match = text.match(/^steps\((\d+), (start|middle|end)\)$/);
if (match)
return new WebInspector.AnimationTimeline.StepTimingFunction(parseInt(match[1], 10), match[2]);
return null;
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.AnimationTimeline.ButtonProvider = function()
{
this._button = new WebInspector.ToolbarButton(WebInspector.UIString("Animations"), "animation-toolbar-item");
this._button.addEventListener("click", this._clicked, this);
}
WebInspector.AnimationTimeline.ButtonProvider.prototype = {
_clicked: function()
{
WebInspector.inspectorView.showViewInDrawer("animations");
},
/**
* @override
* @return {!WebInspector.ToolbarItem}
*/
item: function()
{
return this._button;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.AnimationModel.Animation} animation
* @param {!WebInspector.AnimationTimeline} timeline
* @param {!Element} parentElement
*/
WebInspector.AnimationUI = function(animation, timeline, parentElement) {
this._animation = animation;
this._timeline = timeline;
this._parentElement = parentElement;
if (this._animation.source().keyframesRule())
this._keyframes = this._animation.source().keyframesRule().keyframes();
this._nameElement = parentElement.createChild("div", "animation-name");
this._nameElement.textContent = this._animation.name();
this._svg = parentElement.createSVGChild("svg", "animation-ui");
this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationSVGHeight);
this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.AnimationMargin + "px";
this._svg.addEventListener("contextmenu", this._onContextMenu.bind(this));
this._activeIntervalGroup = this._svg.createSVGChild("g");
WebInspector.installDragHandle(this._activeIntervalGroup, this._mouseDown.bind(this, WebInspector.AnimationUI.MouseEvents.AnimationDrag, null), this._mouseMove.bind(this), this._mouseUp.bind(this), "-webkit-grabbing", "-webkit-grab");
/** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints: !Object.<number, !Element>, keyframeRender: !Object.<number, !Element>}>} */
this._cachedElements = [];
this._movementInMs = 0;
this._color = WebInspector.AnimationUI.Color(this._animation);
}
/**
* @enum {string}
*/
WebInspector.AnimationUI.MouseEvents = {
AnimationDrag: "AnimationDrag",
KeyframeMove: "KeyframeMove",
StartEndpointMove: "StartEndpointMove",
FinishEndpointMove: "FinishEndpointMove"
}
WebInspector.AnimationUI.prototype = {
/**
* @return {!WebInspector.AnimationModel.Animation}
*/
animation: function()
{
return this._animation;
},
/**
* @param {?WebInspector.DOMNode} node
*/
setNode: function(node)
{
this._node = node;
},
/**
* @param {!Element} parentElement
* @param {string} className
*/
_createLine: function(parentElement, className)
{
var line = parentElement.createSVGChild("line", className);
line.setAttribute("x1", WebInspector.AnimationUI.Options.AnimationMargin);
line.setAttribute("y1", WebInspector.AnimationUI.Options.AnimationHeight);
line.setAttribute("y2", WebInspector.AnimationUI.Options.AnimationHeight);
line.style.stroke = this._color;
return line;
},
/**
* @param {number} iteration
* @param {!Element} parentElement
*/
_drawAnimationLine: function(iteration, parentElement)
{
var cache = this._cachedElements[iteration];
if (!cache.animationLine)
cache.animationLine = this._createLine(parentElement, "animation-line");
cache.animationLine.setAttribute("x2", (this._duration() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2));
},
/**
* @param {!Element} parentElement
*/
_drawDelayLine: function(parentElement)
{
if (!this._delayLine) {
this._delayLine = this._createLine(parentElement, "animation-delay-line");
this._endDelayLine = this._createLine(parentElement, "animation-delay-line");
}
var fill = this._animation.source().fill();
this._delayLine.classList.toggle("animation-fill", fill === "backwards" || fill === "both");
var margin = WebInspector.AnimationUI.Options.AnimationMargin;
this._delayLine.setAttribute("x1", margin);
this._delayLine.setAttribute("x2", (this._delay() * this._timeline.pixelMsRatio() + margin).toFixed(2));
var forwardsFill = fill === "forwards" || fill === "both";
this._endDelayLine.classList.toggle("animation-fill", forwardsFill);
var leftMargin = Math.min(this._timeline.width(), (this._delay() + this._duration() * this._animation.source().iterations()) * this._timeline.pixelMsRatio());
this._endDelayLine.style.transform = "translateX(" + leftMargin.toFixed(2) + "px)";
this._endDelayLine.setAttribute("x1", margin);
this._endDelayLine.setAttribute("x2", forwardsFill
? (this._timeline.width() - leftMargin + margin).toFixed(2)
: (this._animation.source().endDelay() * this._timeline.pixelMsRatio() + margin).toFixed(2));
},
/**
* @param {number} iteration
* @param {!Element} parentElement
* @param {number} x
* @param {number} keyframeIndex
* @param {boolean} attachEvents
*/
_drawPoint: function(iteration, parentElement, x, keyframeIndex, attachEvents)
{
if (this._cachedElements[iteration].keyframePoints[keyframeIndex]) {
this._cachedElements[iteration].keyframePoints[keyframeIndex].setAttribute("cx", x.toFixed(2));
return;
}
var circle = parentElement.createSVGChild("circle", keyframeIndex <= 0 ? "animation-endpoint" : "animation-keyframe-point");
circle.setAttribute("cx", x.toFixed(2));
circle.setAttribute("cy", WebInspector.AnimationUI.Options.AnimationHeight);
circle.style.stroke = this._color;
circle.setAttribute("r", WebInspector.AnimationUI.Options.AnimationMargin / 2);
if (keyframeIndex <= 0)
circle.style.fill = this._color;
this._cachedElements[iteration].keyframePoints[keyframeIndex] = circle;
if (!attachEvents)
return;
var eventType;
if (keyframeIndex === 0)
eventType = WebInspector.AnimationUI.MouseEvents.StartEndpointMove;
else if (keyframeIndex === -1)
eventType = WebInspector.AnimationUI.MouseEvents.FinishEndpointMove;
else
eventType = WebInspector.AnimationUI.MouseEvents.KeyframeMove;
WebInspector.installDragHandle(circle, this._mouseDown.bind(this, eventType, keyframeIndex), this._mouseMove.bind(this), this._mouseUp.bind(this), "ew-resize");
},
/**
* @param {number} iteration
* @param {number} keyframeIndex
* @param {!Element} parentElement
* @param {number} leftDistance
* @param {number} width
* @param {string} easing
*/
_renderKeyframe: function(iteration, keyframeIndex, parentElement, leftDistance, width, easing)
{
/**
* @param {!Element} parentElement
* @param {number} x
* @param {string} strokeColor
*/
function createStepLine(parentElement, x, strokeColor)
{
var line = parentElement.createSVGChild("line");
line.setAttribute("x1", x);
line.setAttribute("x2", x);
line.setAttribute("y1", WebInspector.AnimationUI.Options.AnimationMargin);
line.setAttribute("y2", WebInspector.AnimationUI.Options.AnimationHeight);
line.style.stroke = strokeColor;
}
var bezier = WebInspector.Geometry.CubicBezier.parse(easing);
var cache = this._cachedElements[iteration].keyframeRender;
if (!cache[keyframeIndex])
cache[keyframeIndex] = bezier ? parentElement.createSVGChild("path", "animation-keyframe") : parentElement.createSVGChild("g", "animation-keyframe-step");
var group = cache[keyframeIndex];
group.style.transform = "translateX(" + leftDistance.toFixed(2) + "px)";
if (easing === "linear") {
group.style.fill = this._color;
var height = WebInspector.BezierUI.Height;
group.setAttribute("d", ["M", 0, height, "L", 0, 5, "L", width.toFixed(2), 5, "L", width.toFixed(2), height, "Z"].join(" "));
} else if (bezier) {
group.style.fill = this._color;
WebInspector.BezierUI.drawVelocityChart(bezier, group, width);
} else {
var stepFunction = WebInspector.AnimationTimeline.StepTimingFunction.parse(easing);
group.removeChildren();
/** @const */ var offsetMap = {"start": 0, "middle": 0.5, "end": 1};
/** @const */ var offsetWeight = offsetMap[stepFunction.stepAtPosition];
for (var i = 0; i < stepFunction.steps; i++)
createStepLine(group, (i + offsetWeight) * width / stepFunction.steps, this._color);
}
},
redraw: function()
{
var durationWithDelay = this._delay() + this._duration() * this._animation.source().iterations() + this._animation.source().endDelay();
var maxWidth = this._timeline.width() - WebInspector.AnimationUI.Options.AnimationMargin;
this._svg.setAttribute("width", (maxWidth + 2 * WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2));
this._activeIntervalGroup.style.transform = "translateX(" + (this._delay() * this._timeline.pixelMsRatio()).toFixed(2) + "px)";
this._nameElement.style.transform = "translateX(" + (this._delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2) + "px)";
this._nameElement.style.width = (this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + "px";
this._drawDelayLine(this._svg);
if (this._animation.type() === "CSSTransition") {
this._renderTransition();
return;
}
this._renderIteration(this._activeIntervalGroup, 0);
if (!this._tailGroup)
this._tailGroup = this._activeIntervalGroup.createSVGChild("g", "animation-tail-iterations");
var iterationWidth = this._duration() * this._timeline.pixelMsRatio();
for (var iteration = 1; iteration < this._animation.source().iterations() && iterationWidth * (iteration - 1) < this._timeline.width(); iteration++)
this._renderIteration(this._tailGroup, iteration);
while (iteration < this._cachedElements.length)
this._cachedElements.pop().group.remove();
},
_renderTransition: function()
{
if (!this._cachedElements[0])
this._cachedElements[0] = { animationLine: null, keyframePoints: {}, keyframeRender: {}, group: null };
this._drawAnimationLine(0, this._activeIntervalGroup);
this._renderKeyframe(0, 0, this._activeIntervalGroup, WebInspector.AnimationUI.Options.AnimationMargin, this._duration() * this._timeline.pixelMsRatio(), this._animation.source().easing());
this._drawPoint(0, this._activeIntervalGroup, WebInspector.AnimationUI.Options.AnimationMargin, 0, true);
this._drawPoint(0, this._activeIntervalGroup, this._duration() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, true);
},
/**
* @param {!Element} parentElement
* @param {number} iteration
*/
_renderIteration: function(parentElement, iteration)
{
if (!this._cachedElements[iteration])
this._cachedElements[iteration] = { animationLine: null, keyframePoints: {}, keyframeRender: {}, group: parentElement.createSVGChild("g") };
var group = this._cachedElements[iteration].group;
group.style.transform = "translateX(" + (iteration * this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + "px)";
this._drawAnimationLine(iteration, group);
console.assert(this._keyframes.length > 1);
for (var i = 0; i < this._keyframes.length - 1; i++) {
var leftDistance = this._offset(i) * this._duration() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin;
var width = this._duration() * (this._offset(i + 1) - this._offset(i)) * this._timeline.pixelMsRatio();
this._renderKeyframe(iteration, i, group, leftDistance, width, this._keyframes[i].easing());
if (i || (!i && iteration === 0))
this._drawPoint(iteration, group, leftDistance, i, iteration === 0);
}
this._drawPoint(iteration, group, this._duration() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, iteration === 0);
},
/**
* @return {number}
*/
_delay: function()
{
var delay = this._animation.source().delay();
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.AnimationDrag || this._mouseEventType === WebInspector.AnimationUI.MouseEvents.StartEndpointMove)
delay += this._movementInMs;
// FIXME: add support for negative start delay
return Math.max(0, delay);
},
/**
* @return {number}
*/
_duration: function()
{
var duration = this._animation.source().duration();
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.FinishEndpointMove)
duration += this._movementInMs;
else if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.StartEndpointMove)
duration -= Math.max(this._movementInMs, -this._animation.source().delay()); // Cannot have negative delay
return Math.max(0, duration);
},
/**
* @param {number} i
* @return {number} offset
*/
_offset: function(i)
{
var offset = this._keyframes[i].offsetAsNumber();
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.KeyframeMove && i === this._keyframeMoved) {
console.assert(i > 0 && i < this._keyframes.length - 1, "First and last keyframe cannot be moved");
offset += this._movementInMs / this._animation.source().duration();
offset = Math.max(offset, this._keyframes[i - 1].offsetAsNumber());
offset = Math.min(offset, this._keyframes[i + 1].offsetAsNumber());
}
return offset;
},
/**
* @param {!WebInspector.AnimationUI.MouseEvents} mouseEventType
* @param {?number} keyframeIndex
* @param {!Event} event
*/
_mouseDown: function(mouseEventType, keyframeIndex, event)
{
if (event.buttons == 2)
return false;
if (this._svg.enclosingNodeOrSelfWithClass("animation-node-removed"))
return false;
this._mouseEventType = mouseEventType;
this._keyframeMoved = keyframeIndex;
this._downMouseX = event.clientX;
event.consume(true);
if (this._node)
WebInspector.Revealer.reveal(this._node);
return true;
},
/**
* @param {!Event} event
*/
_mouseMove: function (event)
{
this._movementInMs = (event.clientX - this._downMouseX) / this._timeline.pixelMsRatio();
if (this._delay() + this._duration() > this._timeline.duration() * 0.8)
this._timeline.setDuration(this._timeline.duration() * 1.2);
this.redraw();
},
/**
* @param {!Event} event
*/
_mouseUp: function(event)
{
this._movementInMs = (event.clientX - this._downMouseX) / this._timeline.pixelMsRatio();
// Commit changes
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.KeyframeMove)
this._keyframes[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));
else
this._animation.setTiming(this._duration(), this._delay());
this._movementInMs = 0;
this.redraw();
delete this._mouseEventType;
delete this._downMouseX;
delete this._keyframeMoved;
},
/**
* @param {!Event} event
*/
_onContextMenu: function(event)
{
/**
* @param {?WebInspector.RemoteObject} remoteObject
*/
function showContextMenu(remoteObject)
{
if (!remoteObject)
return;
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(remoteObject);
contextMenu.show();
}
this._animation.remoteObjectPromise().then(showContextMenu);
event.consume(true);
}
}
WebInspector.AnimationUI.Options = {
AnimationHeight: 26,
AnimationSVGHeight: 50,
AnimationMargin: 7,
EndpointsClickRegionSize: 10,
GridCanvasHeight: 40
}
WebInspector.AnimationUI.Colors = {
"Purple": WebInspector.Color.parse("#9C27B0"),
"Light Blue": WebInspector.Color.parse("#03A9F4"),
"Deep Orange": WebInspector.Color.parse("#FF5722"),
"Blue": WebInspector.Color.parse("#5677FC"),
"Lime": WebInspector.Color.parse("#CDDC39"),
"Blue Grey": WebInspector.Color.parse("#607D8B"),
"Pink": WebInspector.Color.parse("#E91E63"),
"Green": WebInspector.Color.parse("#0F9D58"),
"Brown": WebInspector.Color.parse("#795548"),
"Cyan": WebInspector.Color.parse("#00BCD4")
}
/**
* @param {!WebInspector.AnimationModel.Animation} animation
* @return {string}
*/
WebInspector.AnimationUI.Color = function(animation)
{
var names = Object.keys(WebInspector.AnimationUI.Colors);
var color = WebInspector.AnimationUI.Colors[names[String.hashCode(animation.name() || animation.id()) % names.length]];
return color.asString(WebInspector.Color.Format.RGB);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AuditCategories.js | 5% | (1 / 20) | 100% | (0 / 0) | 0% | (0 / 4) | 5% | (1 / 20) | |
| AuditCategory.js | 50% | (1 / 2) | 100% | (0 / 0) | 0% | (0 / 4) | 50% | (1 / 2) | |
| AuditController.js | 5.26% | (3 / 57) | 0% | (0 / 26) | 0% | (0 / 11) | 5.26% | (3 / 57) | |
| AuditExtensionCategory.js | 7.58% | (5 / 66) | 0% | (0 / 12) | 0% | (0 / 18) | 7.58% | (5 / 66) | |
| AuditFormatters.js | 2.63% | (1 / 38) | 0% | (0 / 21) | 0% | (0 / 8) | 2.63% | (1 / 38) | |
| AuditLauncherView.js | 2.94% | (4 / 136) | 0% | (0 / 30) | 0% | (0 / 20) | 2.94% | (4 / 136) | |
| AuditResultView.js | 5.45% | (3 / 55) | 0% | (0 / 28) | 0% | (0 / 5) | 5.45% | (3 / 55) | |
| AuditRules.js | 3.79% | (24 / 633) | 0% | (0 / 300) | 0% | (0 / 92) | 3.79% | (24 / 633) | |
| AuditsPanel.js | 1.76% | (3 / 170) | 0% | (0 / 32) | 0% | (0 / 49) | 1.76% | (3 / 170) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 2 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.AuditCategoryImpl}
*/
WebInspector.AuditCategories.PagePerformance = function() {
WebInspector.AuditCategoryImpl.call(this, WebInspector.AuditCategories.PagePerformance.AuditCategoryName);
}
WebInspector.AuditCategories.PagePerformance.AuditCategoryName = WebInspector.UIString("Web Page Performance");
WebInspector.AuditCategories.PagePerformance.prototype = {
initialize: function()
{
this.addRule(new WebInspector.AuditRules.UnusedCssRule(), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CssInHeadRule(), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.StylesScriptsOrderRule(), WebInspector.AuditRule.Severity.Severe);
},
__proto__: WebInspector.AuditCategoryImpl.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditCategoryImpl}
*/
WebInspector.AuditCategories.NetworkUtilization = function() {
WebInspector.AuditCategoryImpl.call(this, WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);
}
WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName = WebInspector.UIString("Network Utilization");
WebInspector.AuditCategories.NetworkUtilization.prototype = {
initialize: function()
{
this.addRule(new WebInspector.AuditRules.GzipRule(), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.ImageDimensionsRule(), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CookieSizeRule(400), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.StaticCookielessRule(5), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CombineJsResourcesRule(2), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.CombineCssResourcesRule(2), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.MinimizeDnsLookupsRule(4), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.ParallelizeDownloadRule(4, 10, 0.5), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.BrowserCacheControlRule(), WebInspector.AuditRule.Severity.Severe);
},
__proto__: WebInspector.AuditCategoryImpl.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 2 | /* * Copyright (C) 2014 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.AuditCategory = function() { } WebInspector.AuditCategory.prototype = { /** * @return {string} */ get id() { }, /** * @return {string} */ get displayName() { }, /** * @param {!WebInspector.Target} target * @param {!Array.<!WebInspector.NetworkRequest>} requests * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback * @param {!WebInspector.Progress} progress */ run: function(target, requests, ruleResultCallback, progress) { } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.AuditsPanel} auditsPanel
*/
WebInspector.AuditController = function(auditsPanel)
{
this._auditsPanel = auditsPanel;
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.Load, this._didMainResourceLoad, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._didLoadResource, this);
}
WebInspector.AuditController.prototype = {
/**
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.AuditCategory>} categories
* @param {function(string, !Array.<!WebInspector.AuditCategoryResult>)} resultCallback
*/
_executeAudit: function(target, categories, resultCallback)
{
this._progress.setTitle(WebInspector.UIString("Running audit"));
/**
* @param {!WebInspector.AuditCategoryResult} categoryResult
* @param {!WebInspector.AuditRuleResult} ruleResult
*/
function ruleResultReadyCallback(categoryResult, ruleResult)
{
if (ruleResult && ruleResult.children)
categoryResult.addRuleResult(ruleResult);
}
var results = [];
var mainResourceURL = target.resourceTreeModel.inspectedPageURL();
var categoriesDone = 0;
function categoryDoneCallback()
{
if (++categoriesDone !== categories.length)
return;
resultCallback(mainResourceURL, results);
}
var requests = target.networkLog.requests().slice();
var compositeProgress = new WebInspector.CompositeProgress(this._progress);
var subprogresses = [];
for (var i = 0; i < categories.length; ++i)
subprogresses.push(new WebInspector.ProgressProxy(compositeProgress.createSubProgress(), categoryDoneCallback));
for (var i = 0; i < categories.length; ++i) {
if (this._progress.isCanceled()) {
subprogresses[i].done();
continue;
}
var category = categories[i];
var result = new WebInspector.AuditCategoryResult(category);
results.push(result);
category.run(target, requests, ruleResultReadyCallback.bind(null, result), subprogresses[i]);
}
},
/**
* @param {string} mainResourceURL
* @param {!Array.<!WebInspector.AuditCategoryResult>} results
*/
_auditFinishedCallback: function(mainResourceURL, results)
{
if (!this._progress.isCanceled())
this._auditsPanel.auditFinishedCallback(mainResourceURL, results);
this._progress.done();
},
/**
* @param {!Array.<string>} categoryIds
* @param {!WebInspector.Progress} progress
* @param {boolean} runImmediately
* @param {function()} startedCallback
*/
initiateAudit: function(categoryIds, progress, runImmediately, startedCallback)
{
var target = WebInspector.targetManager.mainTarget();
if (!categoryIds || !categoryIds.length || !target)
return;
this._progress = progress;
var categories = [];
for (var i = 0; i < categoryIds.length; ++i)
categories.push(this._auditsPanel.categoriesById[categoryIds[i]]);
if (runImmediately)
this._startAuditWhenResourcesReady(target, categories, startedCallback);
else
this._reloadResources(this._startAuditWhenResourcesReady.bind(this, target, categories, startedCallback));
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.AuditsStarted);
},
/**
* @param {!WebInspector.Target} target
* @param {!Array<!WebInspector.AuditCategory>} categories
* @param {function()} startedCallback
*/
_startAuditWhenResourcesReady: function(target, categories, startedCallback)
{
if (this._progress.isCanceled()) {
this._progress.done();
return;
}
startedCallback();
this._executeAudit(target, categories, this._auditFinishedCallback.bind(this));
},
/**
* @param {function()=} callback
*/
_reloadResources: function(callback)
{
this._pageReloadCallback = callback;
WebInspector.targetManager.reloadPage();
},
_didLoadResource: function()
{
if (this._pageReloadCallback && this._progress && this._progress.isCanceled())
this._pageReloadCallback();
},
_didMainResourceLoad: function()
{
if (this._pageReloadCallback) {
var callback = this._pageReloadCallback;
delete this._pageReloadCallback;
callback();
}
},
clearResults: function()
{
this._auditsPanel.clearResults();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | 2 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.AuditCategory}
* @param {string} extensionOrigin
* @param {string} id
* @param {string} displayName
* @param {number=} ruleCount
*/
WebInspector.AuditExtensionCategory = function(extensionOrigin, id, displayName, ruleCount)
{
this._extensionOrigin = extensionOrigin;
this._id = id;
this._displayName = displayName;
this._ruleCount = ruleCount;
}
WebInspector.AuditExtensionCategory.prototype = {
/**
* @override
*/
get id()
{
return this._id;
},
/**
* @override
*/
get displayName()
{
return this._displayName;
},
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {!WebInspector.Progress} progress
*/
run: function(target, requests, ruleResultCallback, progress)
{
var results = new WebInspector.AuditExtensionCategoryResults(this, target, ruleResultCallback, progress);
WebInspector.extensionServer.startAuditRun(this.id, results);
}
}
/**
* @constructor
* @implements {WebInspector.ExtensionAuditCategoryResults}
* @param {!WebInspector.AuditExtensionCategory} category
* @param {!WebInspector.Target} target
* @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {!WebInspector.Progress} progress
*/
WebInspector.AuditExtensionCategoryResults = function(category, target, ruleResultCallback, progress)
{
this._target = target;
this._category = category;
this._ruleResultCallback = ruleResultCallback;
this._progress = progress;
this._progress.setTotalWork(1);
this._expectedResults = category._ruleCount;
this._actualResults = 0;
this._id = category.id + "-" + ++WebInspector.AuditExtensionCategoryResults._lastId;
}
WebInspector.AuditExtensionCategoryResults.prototype = {
/**
* @override
* @return {string}
*/
id: function()
{
return this._id;
},
/**
* @override
*/
done: function()
{
WebInspector.extensionServer.stopAuditRun(this);
this._progress.done();
},
/**
* @override
* @param {string} displayName
* @param {string} description
* @param {string} severity
* @param {!Object} details
*/
addResult: function(displayName, description, severity, details)
{
var result = new WebInspector.AuditRuleResult(displayName);
if (description)
result.addChild(description);
result.severity = severity;
if (details)
this._addNode(result, details);
this._addResult(result);
},
_addNode: function(parent, node)
{
var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.AuditExtensionFormatters, this, node.contents);
var addedNode = parent.addChild(contents, node.expanded);
if (node.children) {
for (var i = 0; i < node.children.length; ++i)
this._addNode(addedNode, node.children[i]);
}
},
_addResult: function(result)
{
this._ruleResultCallback(result);
++this._actualResults;
if (typeof this._expectedResults === "number") {
this._progress.setWorked(this._actualResults / this._expectedResults);
if (this._actualResults === this._expectedResults)
this.done();
}
},
/**
* @override
* @param {number} progress
*/
updateProgress: function(progress)
{
this._progress.setWorked(progress);
},
/**
* @param {string} expression
* @param {?Object} evaluateOptions
* @param {function(!WebInspector.RemoteObject)} callback
*/
evaluate: function(expression, evaluateOptions, callback)
{
/**
* @param {?string} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @this {WebInspector.AuditExtensionCategoryResults}
*/
function onEvaluate(error, result, wasThrown)
{
if (wasThrown)
return;
var object = this._target.runtimeModel.createRemoteObject(result);
callback(object);
}
var evaluateCallback = /** @type {function(?string, ?WebInspector.RemoteObject, boolean=)} */ (onEvaluate.bind(this));
WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, evaluateCallback);
}
}
WebInspector.AuditExtensionFormatters = {
/**
* @this {WebInspector.AuditExtensionCategoryResults}
* @param {string} expression
* @param {string} title
* @param {?Object} evaluateOptions
* @return {!Element}
*/
object: function(expression, title, evaluateOptions)
{
var parentElement = createElement("div");
function onEvaluate(remoteObject)
{
var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
section.expand();
section.editable = false;
parentElement.appendChild(section.element);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
},
/**
* @this {WebInspector.AuditExtensionCategoryResults}
* @param {string} expression
* @param {?Object} evaluateOptions
* @return {!Element}
*/
node: function(expression, evaluateOptions)
{
var parentElement = createElement("div");
this.evaluate(expression, evaluateOptions, onEvaluate);
/**
* @param {!WebInspector.RemoteObject} remoteObject
*/
function onEvaluate(remoteObject)
{
WebInspector.Renderer.renderPromise(remoteObject).then(appendRenderer).then(remoteObject.release.bind(remoteObject));
/**
* @param {!Element} element
*/
function appendRenderer(element)
{
parentElement.appendChild(element);
}
}
return parentElement;
}
}
WebInspector.AuditExtensionCategoryResults._lastId = 0;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 2 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.AuditFormatters = function() { } WebInspector.AuditFormatters.Registry = { /** * @param {string} text * @return {!Text} */ text: function(text) { return createTextNode(text); }, /** * @param {string} snippetText * @return {!Element} */ snippet: function(snippetText) { var div = createElement("div"); div.textContent = snippetText; div.className = "source-code"; return div; }, /** * @return {!Element} */ concat: function() { var parent = createElement("span"); for (var arg = 0; arg < arguments.length; ++arg) parent.appendChild(WebInspector.auditFormatters.apply(arguments[arg])); return parent; }, /** * @param {string} url * @param {string=} displayText * @return {!Element} */ url: function(url, displayText) { return WebInspector.linkifyURLAsNode(url, displayText, undefined, true); }, /** * @param {string} url * @param {number=} line * @return {!Element} */ resourceLink: function(url, line) { // FIXME: use WebInspector.Linkifier return WebInspector.linkifyResourceAsNode(url, line, undefined, "resource-url webkit-html-resource-link"); } }; WebInspector.AuditFormatters.prototype = { /** * @param {string|boolean|number|!Object} value * @return {!Node} */ apply: function(value) { var formatter; var type = typeof value; var args; switch (type) { case "string": case "boolean": case "number": formatter = WebInspector.AuditFormatters.Registry.text; args = [value.toString()]; break; case "object": if (value instanceof Node) return value; if (Array.isArray(value)) { formatter = WebInspector.AuditFormatters.Registry.concat; args = value; } else if (value.type && value.arguments) { formatter = WebInspector.AuditFormatters.Registry[value.type]; args = value.arguments; } } if (!formatter) throw "Invalid value or formatter: " + type + JSON.stringify(value); return formatter.apply(null, args); }, /** * @param {!Object} formatters * @param {?Object} thisArgument * @param {string|boolean|number|!Object} value * @return {*} */ partiallyApply: function(formatters, thisArgument, value) { if (Array.isArray(value)) return value.map(this.partiallyApply.bind(this, formatters, thisArgument)); if (typeof value === "object" && typeof formatters[value.type] === "function" && value.arguments) return formatters[value.type].apply(thisArgument, value.arguments); return value; } } WebInspector.auditFormatters = new WebInspector.AuditFormatters(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | 2 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.AuditController} auditController
* @extends {WebInspector.VBox}
*/
WebInspector.AuditLauncherView = function(auditController)
{
WebInspector.VBox.call(this);
this.setMinimumSize(100, 25);
this._auditController = auditController;
this._categoryIdPrefix = "audit-category-item-";
this._auditRunning = false;
this.element.classList.add("audit-launcher-view");
this.element.classList.add("panel-enabler-view");
this._contentElement = createElement("div");
this._contentElement.className = "audit-launcher-view-content";
this.element.appendChild(this._contentElement);
this._boundCategoryClickListener = this._categoryClicked.bind(this);
this._resetResourceCount();
this._sortedCategories = [];
this._headerElement = createElement("h1");
this._headerElement.className = "no-audits";
this._headerElement.textContent = WebInspector.UIString("No audits to run");
this._contentElement.appendChild(this._headerElement);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
var defaultSelectedAuditCategory = {};
defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey] = true;
this._selectedCategoriesSetting = WebInspector.settings.createSetting("selectedAuditCategories", defaultSelectedAuditCategory);
}
WebInspector.AuditLauncherView.AllCategoriesKey = "__AllCategories";
WebInspector.AuditLauncherView.prototype = {
_resetResourceCount: function()
{
this._loadedResources = 0;
this._totalResources = 0;
},
_onRequestStarted: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
// Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
if (request.resourceType() === WebInspector.resourceTypes.WebSocket)
return;
++this._totalResources;
this._updateResourceProgress();
},
_onRequestFinished: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
// See resorceStarted for details.
if (request.resourceType() === WebInspector.resourceTypes.WebSocket)
return;
++this._loadedResources;
this._updateResourceProgress();
},
/**
* @param {!WebInspector.AuditCategory} category
*/
addCategory: function(category)
{
if (!this._sortedCategories.length)
this._createLauncherUI();
var selectedCategories = this._selectedCategoriesSetting.get();
var categoryElement = this._createCategoryElement(category.displayName, category.id);
category._checkboxElement = categoryElement.checkboxElement;
if (this._selectAllCheckboxElement.checked || selectedCategories[category.displayName]) {
category._checkboxElement.checked = true;
++this._currentCategoriesCount;
}
/**
* @param {!WebInspector.AuditCategory} a
* @param {!WebInspector.AuditCategory} b
* @return {number}
*/
function compareCategories(a, b)
{
var aTitle = a.displayName || "";
var bTitle = b.displayName || "";
return aTitle.localeCompare(bTitle);
}
var insertBefore = this._sortedCategories.lowerBound(category, compareCategories);
this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
this._sortedCategories.splice(insertBefore, 0, category);
this._selectedCategoriesUpdated();
},
_startAudit: function()
{
this._auditRunning = true;
this._updateButton();
this._toggleUIComponents(this._auditRunning);
var catIds = [];
for (var category = 0; category < this._sortedCategories.length; ++category) {
if (this._sortedCategories[category]._checkboxElement.checked)
catIds.push(this._sortedCategories[category].id);
}
this._resetResourceCount();
this._progressIndicator = new WebInspector.ProgressIndicator();
this._buttonContainerElement.appendChild(this._progressIndicator.element);
this._displayResourceLoadingProgress = true;
/**
* @this {WebInspector.AuditLauncherView}
*/
function onAuditStarted()
{
this._displayResourceLoadingProgress = false;
}
this._auditController.initiateAudit(catIds, new WebInspector.ProgressProxy(this._progressIndicator, this._auditsDone.bind(this)), this._auditPresentStateElement.checked, onAuditStarted.bind(this));
},
_auditsDone: function()
{
this._displayResourceLoadingProgress = false;
delete this._progressIndicator;
this._launchButton.disabled = false;
this._auditRunning = false;
this._updateButton();
this._toggleUIComponents(this._auditRunning);
},
/**
* @param {boolean} disable
*/
_toggleUIComponents: function(disable)
{
this._selectAllCheckboxElement.disabled = disable;
for (var child = this._categoriesElement.firstChild; child; child = child.nextSibling)
child.checkboxElement.disabled = disable;
this._auditPresentStateElement.disabled = disable;
this._auditReloadedStateElement.disabled = disable;
},
_launchButtonClicked: function(event)
{
if (this._auditRunning) {
this._launchButton.disabled = true;
this._progressIndicator.cancel();
return;
}
this._startAudit();
},
_clearButtonClicked: function()
{
this._auditController.clearResults();
},
/**
* @param {boolean} checkCategories
* @param {boolean=} userGesture
*/
_selectAllClicked: function(checkCategories, userGesture)
{
var childNodes = this._categoriesElement.childNodes;
for (var i = 0, length = childNodes.length; i < length; ++i)
childNodes[i].checkboxElement.checked = checkCategories;
this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
this._selectedCategoriesUpdated(userGesture);
},
_categoryClicked: function(event)
{
this._currentCategoriesCount += event.target.checked ? 1 : -1;
this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
this._selectedCategoriesUpdated(true);
},
/**
* @param {string} title
* @param {string=} id
*/
_createCategoryElement: function(title, id)
{
var labelElement = createCheckboxLabel(title);
if (id) {
labelElement.id = this._categoryIdPrefix + id;
labelElement.checkboxElement.addEventListener("click", this._boundCategoryClickListener, false);
}
labelElement.__displayName = title;
return labelElement;
},
_createLauncherUI: function()
{
this._headerElement = createElement("h1");
this._headerElement.textContent = WebInspector.UIString("Select audits to run");
this._contentElement.removeChildren();
this._contentElement.appendChild(this._headerElement);
/**
* @param {!Event} event
* @this {WebInspector.AuditLauncherView}
*/
function handleSelectAllClick(event)
{
this._selectAllClicked(event.target.checked, true);
}
var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
categoryElement.id = "audit-launcher-selectall";
this._selectAllCheckboxElement = categoryElement.checkboxElement;
this._selectAllCheckboxElement.checked = this._selectedCategoriesSetting.get()[WebInspector.AuditLauncherView.AllCategoriesKey];
this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
this._contentElement.appendChild(categoryElement);
this._categoriesElement = this._contentElement.createChild("fieldset", "audit-categories-container");
this._currentCategoriesCount = 0;
this._contentElement.createChild("div", "flexible-space");
this._buttonContainerElement = this._contentElement.createChild("div", "button-container");
var radio = createRadioLabel("audit-mode", WebInspector.UIString("Audit Present State"), true);
this._buttonContainerElement.appendChild(radio);
this._auditPresentStateElement = radio.radioElement;
radio = createRadioLabel("audit-mode", WebInspector.UIString("Reload Page and Audit on Load"));
this._buttonContainerElement.appendChild(radio);
this._auditReloadedStateElement = radio.radioElement;
this._launchButton = createTextButton(WebInspector.UIString("Run"), this._launchButtonClicked.bind(this));
this._buttonContainerElement.appendChild(this._launchButton);
this._clearButton = createTextButton(WebInspector.UIString("Clear"), this._clearButtonClicked.bind(this));
this._buttonContainerElement.appendChild(this._clearButton);
this._selectAllClicked(this._selectAllCheckboxElement.checked);
},
_updateResourceProgress: function()
{
if (this._displayResourceLoadingProgress)
this._progressIndicator.setTitle(WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources));
},
/**
* @param {boolean=} userGesture
*/
_selectedCategoriesUpdated: function(userGesture)
{
// Save present categories only upon user gesture to clean up junk from past versions and removed extensions.
// Do not remove old categories if not handling a user gesture, as there's chance categories will be added
// later during start-up.
var selectedCategories = userGesture ? {} : this._selectedCategoriesSetting.get();
var childNodes = this._categoriesElement.childNodes;
for (var i = 0, length = childNodes.length; i < length; ++i)
selectedCategories[childNodes[i].__displayName] = childNodes[i].checkboxElement.checked;
selectedCategories[WebInspector.AuditLauncherView.AllCategoriesKey] = this._selectAllCheckboxElement.checked;
this._selectedCategoriesSetting.set(selectedCategories);
this._updateButton();
},
_updateButton: function()
{
this._launchButton.textContent = this._auditRunning ? WebInspector.UIString("Stop") : WebInspector.UIString("Run");
this._launchButton.disabled = !this._currentCategoriesCount;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 2 1 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SidebarPaneStack}
* @param {!Array.<!WebInspector.AuditCategoryResult>} categoryResults
*/
WebInspector.AuditResultView = function(categoryResults)
{
WebInspector.SidebarPaneStack.call(this);
this.setMinimumSize(100, 25);
this.element.classList.add("audit-result-view");
function categorySorter(a, b) {
return (a.title || "").localeCompare(b.title || "");
}
categoryResults.sort(categorySorter);
for (var i = 0; i < categoryResults.length; ++i)
this.addPane(new WebInspector.AuditCategoryResultPane(categoryResults[i]));
}
WebInspector.AuditResultView.prototype = {
__proto__: WebInspector.SidebarPaneStack.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {!WebInspector.AuditCategoryResult} categoryResult
*/
WebInspector.AuditCategoryResultPane = function(categoryResult)
{
WebInspector.SidebarPane.call(this, categoryResult.title);
this._treeOutline = new TreeOutlineInShadow();
this._treeOutline.registerRequiredCSS("audits/auditResultTree.css");
this._treeOutline.element.classList.add("audit-result-tree");
this.element.appendChild(this._treeOutline.element);
this._treeOutline.expandTreeElementsWhenArrowing = true;
function ruleSorter(a, b)
{
var result = WebInspector.AuditRule.SeverityOrder[a.severity || 0] - WebInspector.AuditRule.SeverityOrder[b.severity || 0];
if (!result)
result = (a.value || "").localeCompare(b.value || "");
return result;
}
categoryResult.ruleResults.sort(ruleSorter);
for (var i = 0; i < categoryResult.ruleResults.length; ++i) {
var ruleResult = categoryResult.ruleResults[i];
var treeElement = this._appendResult(this._treeOutline.rootElement(), ruleResult, ruleResult.severity);
treeElement.listItemElement.classList.add("audit-result");
}
this.expand();
}
WebInspector.AuditCategoryResultPane.prototype = {
/**
* @param {!TreeElement} parentTreeNode
* @param {!WebInspector.AuditRuleResult} result
* @param {?WebInspector.AuditRule.Severity=} severity
*/
_appendResult: function(parentTreeNode, result, severity)
{
var title = "";
if (typeof result.value === "string") {
title = result.value;
if (result.violationCount)
title = String.sprintf("%s (%d)", title, result.violationCount);
}
var titleFragment = createDocumentFragment();
if (severity) {
var severityElement = createElement("div");
severityElement.classList.add("severity", severity);
titleFragment.appendChild(severityElement);
}
titleFragment.createTextChild(title);
var treeElement = new TreeElement(titleFragment, !!result.children);
treeElement.selectable = false;
parentTreeNode.appendChild(treeElement);
if (result.className)
treeElement.listItemElement.classList.add(result.className);
if (typeof result.value !== "string")
treeElement.listItemElement.appendChild(WebInspector.auditFormatters.apply(result.value));
if (result.children) {
for (var i = 0; i < result.children.length; ++i)
this._appendResult(treeElement, result.children[i]);
}
if (result.expanded) {
treeElement.listItemElement.classList.remove("parent");
treeElement.listItemElement.classList.add("parent-expanded");
treeElement.expand();
}
return treeElement;
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
WebInspector.AuditRules.CacheableResponseCodes =
{
200: true,
203: true,
206: true,
300: true,
301: true,
410: true,
304: true // Underlying request is cacheable
}
/**
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {?Array.<!WebInspector.ResourceType>} types
* @param {boolean} needFullResources
* @return {!Object.<string, !Array.<!WebInspector.NetworkRequest|string>>}
*/
WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, needFullResources)
{
var domainToResourcesMap = {};
for (var i = 0, size = requests.length; i < size; ++i) {
var request = requests[i];
if (types && types.indexOf(request.resourceType()) === -1)
continue;
var parsedURL = request.url.asParsedURL();
if (!parsedURL)
continue;
var domain = parsedURL.host;
var domainResources = domainToResourcesMap[domain];
if (domainResources === undefined) {
domainResources = [];
domainToResourcesMap[domain] = domainResources;
}
domainResources.push(needFullResources ? request : request.url);
}
return domainToResourcesMap;
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.GzipRule = function()
{
WebInspector.AuditRule.call(this, "network-gzip", WebInspector.UIString("Enable gzip compression"));
}
WebInspector.AuditRules.GzipRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var totalSavings = 0;
var compressedSize = 0;
var candidateSize = 0;
var summary = result.addChild("", true);
for (var i = 0, length = requests.length; i < length; ++i) {
var request = requests[i];
if (request.cached() || request.statusCode === 304)
continue; // Do not test cached resources.
if (this._shouldCompress(request)) {
var size = request.resourceSize;
candidateSize += size;
if (this._isCompressed(request)) {
compressedSize += size;
continue;
}
var savings = 2 * size / 3;
totalSavings += savings;
summary.addFormatted("%r could save ~%s", request.url, Number.bytesToString(savings));
result.violationCount++;
}
}
if (!totalSavings) {
callback(null);
return;
}
summary.value = WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings));
callback(result);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_isCompressed: function(request)
{
var encodingHeader = request.responseHeaderValue("Content-Encoding");
if (!encodingHeader)
return false;
return /\b(?:gzip|deflate)\b/.test(encodingHeader);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_shouldCompress: function(request)
{
return request.resourceType().isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150;
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
* @param {string} id
* @param {string} name
* @param {!WebInspector.ResourceType} type
* @param {string} resourceTypeName
* @param {boolean} allowedPerDomain
*/
WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type, resourceTypeName, allowedPerDomain)
{
WebInspector.AuditRule.call(this, id, name);
this._type = type;
this._resourceTypeName = resourceTypeName;
this._allowedPerDomain = allowedPerDomain;
}
WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, [this._type], false);
var penalizedResourceCount = 0;
// TODO: refactor according to the chosen i18n approach
var summary = result.addChild("", true);
for (var domain in domainToResourcesMap) {
var domainResources = domainToResourcesMap[domain];
var extraResourceCount = domainResources.length - this._allowedPerDomain;
if (extraResourceCount <= 0)
continue;
penalizedResourceCount += extraResourceCount - 1;
summary.addChild(WebInspector.UIString("%d %s resources served from %s.", domainResources.length, this._resourceTypeName, WebInspector.AuditRuleResult.resourceDomain(domain)));
result.violationCount += domainResources.length;
}
if (!penalizedResourceCount) {
callback(null);
return;
}
summary.value = WebInspector.UIString("There are multiple resources served from same domain. Consider combining them into as few files as possible.");
callback(result);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRules.CombineExternalResourcesRule}
*/
WebInspector.AuditRules.CombineJsResourcesRule = function(allowedPerDomain) {
WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externaljs", WebInspector.UIString("Combine external JavaScript"), WebInspector.resourceTypes.Script, "JavaScript", allowedPerDomain);
}
WebInspector.AuditRules.CombineJsResourcesRule.prototype = {
__proto__: WebInspector.AuditRules.CombineExternalResourcesRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRules.CombineExternalResourcesRule}
*/
WebInspector.AuditRules.CombineCssResourcesRule = function(allowedPerDomain) {
WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externalcss", WebInspector.UIString("Combine external CSS"), WebInspector.resourceTypes.Stylesheet, "CSS", allowedPerDomain);
}
WebInspector.AuditRules.CombineCssResourcesRule.prototype = {
__proto__: WebInspector.AuditRules.CombineExternalResourcesRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.MinimizeDnsLookupsRule = function(hostCountThreshold) {
WebInspector.AuditRule.call(this, "network-minimizelookups", WebInspector.UIString("Minimize DNS lookups"));
this._hostCountThreshold = hostCountThreshold;
}
WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var summary = result.addChild("");
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, null, false);
for (var domain in domainToResourcesMap) {
if (domainToResourcesMap[domain].length > 1)
continue;
var parsedURL = domain.asParsedURL();
if (!parsedURL)
continue;
if (!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp))
continue; // an IP address
summary.addSnippet(domain);
result.violationCount++;
}
if (!summary.children || summary.children.length <= this._hostCountThreshold) {
callback(null);
return;
}
summary.value = WebInspector.UIString("The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.");
callback(result);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.ParallelizeDownloadRule = function(optimalHostnameCount, minRequestThreshold, minBalanceThreshold)
{
WebInspector.AuditRule.call(this, "network-parallelizehosts", WebInspector.UIString("Parallelize downloads across hostnames"));
this._optimalHostnameCount = optimalHostnameCount;
this._minRequestThreshold = minRequestThreshold;
this._minBalanceThreshold = minBalanceThreshold;
}
WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
/**
* @param {string} a
* @param {string} b
*/
function hostSorter(a, b)
{
var aCount = domainToResourcesMap[a].length;
var bCount = domainToResourcesMap[b].length;
return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1;
}
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(
requests,
[WebInspector.resourceTypes.Stylesheet, WebInspector.resourceTypes.Image],
true);
var hosts = [];
for (var url in domainToResourcesMap)
hosts.push(url);
if (!hosts.length) {
callback(null); // no hosts (local file or something)
return;
}
hosts.sort(hostSorter);
var optimalHostnameCount = this._optimalHostnameCount;
if (hosts.length > optimalHostnameCount)
hosts.splice(optimalHostnameCount);
var busiestHostResourceCount = domainToResourcesMap[hosts[0]].length;
var requestCountAboveThreshold = busiestHostResourceCount - this._minRequestThreshold;
if (requestCountAboveThreshold <= 0) {
callback(null);
return;
}
var avgResourcesPerHost = 0;
for (var i = 0, size = hosts.length; i < size; ++i)
avgResourcesPerHost += domainToResourcesMap[hosts[i]].length;
// Assume optimal parallelization.
avgResourcesPerHost /= optimalHostnameCount;
avgResourcesPerHost = Math.max(avgResourcesPerHost, 1);
var pctAboveAvg = (requestCountAboveThreshold / avgResourcesPerHost) - 1.0;
var minBalanceThreshold = this._minBalanceThreshold;
if (pctAboveAvg < minBalanceThreshold) {
callback(null);
return;
}
var requestsOnBusiestHost = domainToResourcesMap[hosts[0]];
var entry = result.addChild(WebInspector.UIString("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.", busiestHostResourceCount, hosts[0]), true);
for (var i = 0; i < requestsOnBusiestHost.length; ++i)
entry.addURL(requestsOnBusiestHost[i].url);
result.violationCount = requestsOnBusiestHost.length;
callback(result);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* The reported CSS rule size is incorrect (parsed != original in WebKit),
* so use percentages instead, which gives a better approximation.
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.UnusedCssRule = function()
{
WebInspector.AuditRule.call(this, "page-unusedcss", WebInspector.UIString("Remove unused CSS rules"));
}
WebInspector.AuditRules.UnusedCssRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (!domModel || !cssModel) {
callback(null);
return;
}
/**
* @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
*/
function evalCallback(styleSheets) {
if (!styleSheets.length)
return callback(null);
var selectors = [];
var testedSelectors = {};
for (var i = 0; i < styleSheets.length; ++i) {
var styleSheet = styleSheets[i];
for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
var selectorText = styleSheet.rules[curRule].selectorText;
if (testedSelectors[selectorText])
continue;
selectors.push(selectorText);
testedSelectors[selectorText] = 1;
}
}
var foundSelectors = {};
/**
* @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
*/
function selectorsCallback(styleSheets)
{
if (progress.isCanceled()) {
callback(null);
return;
}
var inlineBlockOrdinal = 0;
var totalStylesheetSize = 0;
var totalUnusedStylesheetSize = 0;
var summary;
for (var i = 0; i < styleSheets.length; ++i) {
var styleSheet = styleSheets[i];
var unusedRules = [];
for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
var rule = styleSheet.rules[curRule];
if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selectorText])
continue;
unusedRules.push(rule.selectorText);
}
totalStylesheetSize += styleSheet.rules.length;
totalUnusedStylesheetSize += unusedRules.length;
if (!unusedRules.length)
continue;
var resource = WebInspector.resourceForURL(styleSheet.sourceURL);
var isInlineBlock = resource && resource.request && resource.request.resourceType() === WebInspector.resourceTypes.Document;
var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : WebInspector.UIString("Inline block #%d", ++inlineBlockOrdinal);
var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules.length);
if (!summary)
summary = result.addChild("", true);
var entry = summary.addFormatted("%s: %d% is not used by the current page.", url, pctUnused);
for (var j = 0; j < unusedRules.length; ++j)
entry.addSnippet(unusedRules[j]);
result.violationCount += unusedRules.length;
}
if (!totalUnusedStylesheetSize)
return callback(null);
var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / totalStylesheetSize);
summary.value = WebInspector.UIString("%s rules (%d%) of CSS not used by the current page.", totalUnusedStylesheetSize, totalUnusedPercent);
callback(result);
}
/**
* @param {?function()} boundSelectorsCallback
* @param {string} selector
* @param {?DOMAgent.NodeId} nodeId
*/
function queryCallback(boundSelectorsCallback, selector, nodeId)
{
if (nodeId)
foundSelectors[selector] = true;
if (boundSelectorsCallback)
boundSelectorsCallback();
}
/**
* @param {!Array.<string>} selectors
* @param {!WebInspector.DOMDocument} document
*/
function documentLoaded(selectors, document) {
var pseudoSelectorRegexp = /::?(?:[\w-]+)(?:\(.*?\))?/g;
if (!selectors.length) {
selectorsCallback([]);
return;
}
for (var i = 0; i < selectors.length; ++i) {
if (progress.isCanceled()) {
callback(null);
return;
}
var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, "");
domModel.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i]));
}
}
domModel.requestDocument(documentLoaded.bind(null, selectors));
}
var styleSheetInfos = cssModel.allStyleSheets();
if (!styleSheetInfos || !styleSheetInfos.length) {
evalCallback([]);
return;
}
var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos, progress, evalCallback);
styleSheetProcessor.run();
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @typedef {!{sourceURL: string, rules: !Array.<!WebInspector.CSSParser.StyleRule>}}
*/
WebInspector.AuditRules.ParsedStyleSheet;
/**
* @constructor
* @param {!Array.<!WebInspector.CSSStyleSheetHeader>} styleSheetHeaders
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<!WebInspector.AuditRules.ParsedStyleSheet>)} styleSheetsParsedCallback
*/
WebInspector.AuditRules.StyleSheetProcessor = function(styleSheetHeaders, progress, styleSheetsParsedCallback)
{
this._styleSheetHeaders = styleSheetHeaders;
this._progress = progress;
this._styleSheets = [];
this._styleSheetsParsedCallback = styleSheetsParsedCallback;
}
WebInspector.AuditRules.StyleSheetProcessor.prototype = {
run: function()
{
this._parser = new WebInspector.CSSParser();
this._processNextStyleSheet();
},
_terminateWorker: function()
{
if (this._parser) {
this._parser.dispose();
delete this._parser;
}
},
_finish: function()
{
this._terminateWorker();
this._styleSheetsParsedCallback(this._styleSheets);
},
_processNextStyleSheet: function()
{
if (!this._styleSheetHeaders.length) {
this._finish();
return;
}
this._currentStyleSheetHeader = this._styleSheetHeaders.shift();
this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheetParsed.bind(this));
},
/**
* @param {!Array.<!WebInspector.CSSParser.Rule>} rules
*/
_onStyleSheetParsed: function(rules)
{
if (this._progress.isCanceled()) {
this._finish();
return;
}
var styleRules = [];
for (var i = 0; i < rules.length; ++i) {
var rule = rules[i];
if (rule.selectorText)
styleRules.push(rule);
}
this._styleSheets.push({
sourceURL: this._currentStyleSheetHeader.sourceURL,
rules: styleRules
});
this._processNextStyleSheet();
},
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.CacheControlRule = function(id, name)
{
WebInspector.AuditRule.call(this, id, name);
}
WebInspector.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 * 30;
WebInspector.AuditRules.CacheControlRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResources(requests);
if (cacheableAndNonCacheableResources[0].length)
this.runChecks(cacheableAndNonCacheableResources[0], result);
this.handleNonCacheableResources(cacheableAndNonCacheableResources[1], result);
callback(result);
},
handleNonCacheableResources: function(requests, result)
{
},
_cacheableAndNonCacheableResources: function(requests)
{
var processedResources = [[], []];
for (var i = 0; i < requests.length; ++i) {
var request = requests[i];
if (!this.isCacheableResource(request))
continue;
if (this._isExplicitlyNonCacheable(request))
processedResources[1].push(request);
else
processedResources[0].push(request);
}
return processedResources;
},
execCheck: function(messageText, requestCheckFunction, requests, result)
{
var requestCount = requests.length;
var urls = [];
for (var i = 0; i < requestCount; ++i) {
if (requestCheckFunction.call(this, requests[i]))
urls.push(requests[i].url);
}
if (urls.length) {
var entry = result.addChild(messageText, true);
entry.addURLs(urls);
result.violationCount += urls.length;
}
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {number} timeMs
* @return {boolean}
*/
freshnessLifetimeGreaterThan: function(request, timeMs)
{
var dateHeader = this.responseHeader(request, "Date");
if (!dateHeader)
return false;
var dateHeaderMs = Date.parse(dateHeader);
if (isNaN(dateHeaderMs))
return false;
var freshnessLifetimeMs;
var maxAgeMatch = this.responseHeaderMatch(request, "Cache-Control", "max-age=(\\d+)");
if (maxAgeMatch)
freshnessLifetimeMs = (maxAgeMatch[1]) ? 1000 * maxAgeMatch[1] : 0;
else {
var expiresHeader = this.responseHeader(request, "Expires");
if (expiresHeader) {
var expDate = Date.parse(expiresHeader);
if (!isNaN(expDate))
freshnessLifetimeMs = expDate - dateHeaderMs;
}
}
return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {string} header
* @return {string|undefined}
*/
responseHeader: function(request, header)
{
return request.responseHeaderValue(header);
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {string} header
* @return {boolean}
*/
hasResponseHeader: function(request, header)
{
return request.responseHeaderValue(header) !== undefined;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
isCompressible: function(request)
{
return request.resourceType().isTextType();
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
isPubliclyCacheable: function(request)
{
if (this._isExplicitlyNonCacheable(request))
return false;
if (this.responseHeaderMatch(request, "Cache-Control", "public"))
return true;
return request.url.indexOf("?") === -1 && !this.responseHeaderMatch(request, "Cache-Control", "private");
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {string} header
* @param {string} regexp
* @return {?Array.<string>}
*/
responseHeaderMatch: function(request, header, regexp)
{
return request.responseHeaderValue(header)
? request.responseHeaderValue(header).match(new RegExp(regexp, "im"))
: null;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
hasExplicitExpiration: function(request)
{
return this.hasResponseHeader(request, "Date") &&
(this.hasResponseHeader(request, "Expires") || !!this.responseHeaderMatch(request, "Cache-Control", "max-age"));
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
_isExplicitlyNonCacheable: function(request)
{
var hasExplicitExp = this.hasExplicitExpiration(request);
return !!this.responseHeaderMatch(request, "Cache-Control", "(no-cache|no-store)") ||
!!this.responseHeaderMatch(request, "Pragma", "no-cache") ||
(hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) ||
(!hasExplicitExp && !!request.url && request.url.indexOf("?") >= 0) ||
(!hasExplicitExp && !this.isCacheableResource(request));
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
isCacheableResource: function(request)
{
return request.statusCode !== undefined && WebInspector.AuditRules.CacheableResponseCodes[request.statusCode];
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRules.CacheControlRule}
*/
WebInspector.AuditRules.BrowserCacheControlRule = function()
{
WebInspector.AuditRules.CacheControlRule.call(this, "http-browsercache", WebInspector.UIString("Leverage browser caching"));
}
WebInspector.AuditRules.BrowserCacheControlRule.prototype = {
handleNonCacheableResources: function(requests, result)
{
if (requests.length) {
var entry = result.addChild(WebInspector.UIString("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:"), true);
result.violationCount += requests.length;
for (var i = 0; i < requests.length; ++i)
entry.addURL(requests[i].url);
}
},
runChecks: function(requests, result, callback)
{
this.execCheck(WebInspector.UIString("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:"),
this._missingExpirationCheck, requests, result);
this.execCheck(WebInspector.UIString("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:"),
this._varyCheck, requests, result);
this.execCheck(WebInspector.UIString("The following cacheable resources have a short freshness lifetime:"),
this._oneMonthExpirationCheck, requests, result);
// Unable to implement the favicon check due to the WebKit limitations.
this.execCheck(WebInspector.UIString("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:"),
this._oneYearExpirationCheck, requests, result);
},
_missingExpirationCheck: function(request)
{
return this.isCacheableResource(request) && !this.hasResponseHeader(request, "Set-Cookie") && !this.hasExplicitExpiration(request);
},
_varyCheck: function(request)
{
var varyHeader = this.responseHeader(request, "Vary");
if (varyHeader) {
varyHeader = varyHeader.replace(/User-Agent/gi, "");
varyHeader = varyHeader.replace(/Accept-Encoding/gi, "");
varyHeader = varyHeader.replace(/[, ]*/g, "");
}
return varyHeader && varyHeader.length && this.isCacheableResource(request) && this.freshnessLifetimeGreaterThan(request, 0);
},
_oneMonthExpirationCheck: function(request)
{
return this.isCacheableResource(request) &&
!this.hasResponseHeader(request, "Set-Cookie") &&
!this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.CacheControlRule.MillisPerMonth) &&
this.freshnessLifetimeGreaterThan(request, 0);
},
_oneYearExpirationCheck: function(request)
{
return this.isCacheableResource(request) &&
!this.hasResponseHeader(request, "Set-Cookie") &&
!this.freshnessLifetimeGreaterThan(request, 11 * WebInspector.AuditRules.CacheControlRule.MillisPerMonth) &&
this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.CacheControlRule.MillisPerMonth);
},
__proto__: WebInspector.AuditRules.CacheControlRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.ImageDimensionsRule = function()
{
WebInspector.AuditRule.call(this, "page-imagedims", WebInspector.UIString("Specify image dimensions"));
}
WebInspector.AuditRules.ImageDimensionsRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (!domModel || !cssModel) {
callback(null);
return;
}
var urlToNoDimensionCount = {};
function doneCallback()
{
for (var url in urlToNoDimensionCount) {
var entry = entry || result.addChild(WebInspector.UIString("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:"), true);
var format = "%r";
if (urlToNoDimensionCount[url] > 1)
format += " (%d uses)";
entry.addFormatted(format, url, urlToNoDimensionCount[url]);
result.violationCount++;
}
callback(entry ? result : null);
}
function imageStylesReady(imageId, styles)
{
if (progress.isCanceled()) {
callback(null);
return;
}
const node = domModel.nodeForId(imageId);
var src = node.getAttribute("src");
if (!src.asParsedURL()) {
for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
if (frameOwnerCandidate.baseURL) {
var completeSrc = WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, src);
break;
}
}
}
if (completeSrc)
src = completeSrc;
if (styles.computedStyle.get("position") === "absolute")
return;
var widthFound = false;
var heightFound = false;
for (var i = 0; !(widthFound && heightFound) && i < styles.nodeStyles.length; ++i) {
var style = styles.nodeStyles[i];
if (style.getPropertyValue("width") !== "")
widthFound = true;
if (style.getPropertyValue("height") !== "")
heightFound = true;
}
if (!widthFound || !heightFound) {
if (src in urlToNoDimensionCount)
++urlToNoDimensionCount[src];
else
urlToNoDimensionCount[src] = 1;
}
}
/**
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function getStyles(nodeIds)
{
if (progress.isCanceled()) {
callback(null);
return;
}
var targetResult = {};
/**
* @param {?WebInspector.CSSMatchedStyles} matchedStyleResult
*/
function matchedCallback(matchedStyleResult)
{
if (!matchedStyleResult)
return;
targetResult.nodeStyles = matchedStyleResult.nodeStyles();
}
/**
* @param {?Map.<string, string>} computedStyle
*/
function computedCallback(computedStyle)
{
targetResult.computedStyle = computedStyle;
}
if (!nodeIds || !nodeIds.length)
doneCallback();
var nodePromises = [];
for (var i = 0; nodeIds && i < nodeIds.length; ++i) {
var stylePromises = [
cssModel.matchedStylesPromise(nodeIds[i]).then(matchedCallback),
cssModel.computedStylePromise(nodeIds[i]).then(computedCallback)
];
var nodePromise = Promise.all(stylePromises).then(imageStylesReady.bind(null, nodeIds[i], targetResult));
nodePromises.push(nodePromise);
}
Promise.all(nodePromises)
.catchException(null)
.then(doneCallback);
}
function onDocumentAvailable(root)
{
if (progress.isCanceled()) {
callback(null);
return;
}
domModel.querySelectorAll(root.id, "img[src]", getStyles);
}
if (progress.isCanceled()) {
callback(null);
return;
}
domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.CssInHeadRule = function()
{
WebInspector.AuditRule.call(this, "page-cssinhead", WebInspector.UIString("Put CSS in the document head"));
}
WebInspector.AuditRules.CssInHeadRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (!domModel) {
callback(null);
return;
}
function evalCallback(evalResult)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!evalResult)
return callback(null);
var summary = result.addChild("");
for (var url in evalResult) {
var urlViolations = evalResult[url];
if (urlViolations[0]) {
result.addFormatted("%s style block(s) in the %r body should be moved to the document head.", urlViolations[0], url);
result.violationCount += urlViolations[0];
}
for (var i = 0; i < urlViolations[1].length; ++i)
result.addFormatted("Link node %r should be moved to the document head in %r", urlViolations[1][i], url);
result.violationCount += urlViolations[1].length;
}
summary.value = WebInspector.UIString("CSS in the document body adversely impacts rendering performance.");
callback(result);
}
/**
* @param {!WebInspector.DOMNode} root
* @param {!Array.<!DOMAgent.NodeId>=} inlineStyleNodeIds
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!nodeIds)
return;
var externalStylesheetNodeIds = nodeIds;
var result = null;
if (inlineStyleNodeIds.length || externalStylesheetNodeIds.length) {
var urlToViolationsArray = {};
var externalStylesheetHrefs = [];
for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
var linkNode = domModel.nodeForId(externalStylesheetNodeIds[j]);
var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute("href"));
externalStylesheetHrefs.push(completeHref || "<empty>");
}
urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, externalStylesheetHrefs];
result = urlToViolationsArray;
}
evalCallback(result);
}
/**
* @param {!WebInspector.DOMNode} root
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function inlineStylesReceived(root, nodeIds)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!nodeIds)
return;
domModel.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
}
/**
* @param {!WebInspector.DOMNode} root
*/
function onDocumentAvailable(root)
{
if (progress.isCanceled()) {
callback(null);
return;
}
domModel.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
}
domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.StylesScriptsOrderRule = function()
{
WebInspector.AuditRule.call(this, "page-stylescriptorder", WebInspector.UIString("Optimize the order of styles and scripts"));
}
WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (!domModel) {
callback(null);
return;
}
function evalCallback(resultValue)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!resultValue)
return callback(null);
var lateCssUrls = resultValue[0];
var cssBeforeInlineCount = resultValue[1];
if (lateCssUrls.length) {
var entry = result.addChild(WebInspector.UIString("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript."), true);
entry.addURLs(lateCssUrls);
result.violationCount += lateCssUrls.length;
}
if (cssBeforeInlineCount) {
result.addChild(WebInspector.UIString(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.", cssBeforeInlineCount, cssBeforeInlineCount > 1 ? "s were" : " was"));
result.violationCount += cssBeforeInlineCount;
}
callback(result);
}
/**
* @param {!Array.<!DOMAgent.NodeId>} lateStyleIds
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function cssBeforeInlineReceived(lateStyleIds, nodeIds)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!nodeIds)
return;
var cssBeforeInlineCount = nodeIds.length;
var result = null;
if (lateStyleIds.length || cssBeforeInlineCount) {
var lateStyleUrls = [];
for (var i = 0; i < lateStyleIds.length; ++i) {
var lateStyleNode = domModel.nodeForId(lateStyleIds[i]);
var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute("href"));
lateStyleUrls.push(completeHref || "<empty>");
}
result = [ lateStyleUrls, cssBeforeInlineCount ];
}
evalCallback(result);
}
/**
* @param {!WebInspector.DOMDocument} root
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function lateStylesReceived(root, nodeIds)
{
if (progress.isCanceled()) {
callback(null);
return;
}
if (!nodeIds)
return;
domModel.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
}
/**
* @param {!WebInspector.DOMDocument} root
*/
function onDocumentAvailable(root)
{
if (progress.isCanceled()) {
callback(null);
return;
}
domModel.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
}
domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.CSSRuleBase = function(id, name)
{
WebInspector.AuditRule.call(this, id, name);
}
WebInspector.AuditRules.CSSRuleBase.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (!cssModel) {
callback(null);
return;
}
var headers = cssModel.allStyleSheets();
if (!headers.length) {
callback(null);
return;
}
var activeHeaders = [];
for (var i = 0; i < headers.length; ++i) {
if (!headers[i].disabled)
activeHeaders.push(headers[i]);
}
var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, callback, progress));
styleSheetProcessor.run();
},
/**
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
* @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
*/
_styleSheetsLoaded: function(result, callback, progress, styleSheets)
{
for (var i = 0; i < styleSheets.length; ++i)
this._visitStyleSheet(styleSheets[i], result);
callback(result);
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.AuditRuleResult} result
*/
_visitStyleSheet: function(styleSheet, result)
{
this.visitStyleSheet(styleSheet, result);
for (var i = 0; i < styleSheet.rules.length; ++i)
this._visitRule(styleSheet, styleSheet.rules[i], result);
this.didVisitStyleSheet(styleSheet, result);
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.CSSParser.StyleRule} rule
* @param {!WebInspector.AuditRuleResult} result
*/
_visitRule: function(styleSheet, rule, result)
{
this.visitRule(styleSheet, rule, result);
var allProperties = rule.properties;
for (var i = 0; i < allProperties.length; ++i)
this.visitProperty(styleSheet, rule, allProperties[i], result);
this.didVisitRule(styleSheet, rule, result);
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.AuditRuleResult} result
*/
visitStyleSheet: function(styleSheet, result)
{
// Subclasses can implement.
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.AuditRuleResult} result
*/
didVisitStyleSheet: function(styleSheet, result)
{
// Subclasses can implement.
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.CSSParser.StyleRule} rule
* @param {!WebInspector.AuditRuleResult} result
*/
visitRule: function(styleSheet, rule, result)
{
// Subclasses can implement.
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.CSSParser.StyleRule} rule
* @param {!WebInspector.AuditRuleResult} result
*/
didVisitRule: function(styleSheet, rule, result)
{
// Subclasses can implement.
},
/**
* @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
* @param {!WebInspector.CSSParser.StyleRule} rule
* @param {!WebInspector.CSSParser.Property} property
* @param {!WebInspector.AuditRuleResult} result
*/
visitProperty: function(styleSheet, rule, property, result)
{
// Subclasses can implement.
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.CookieRuleBase = function(id, name)
{
WebInspector.AuditRule.call(this, id, name);
}
WebInspector.AuditRules.CookieRuleBase.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
var self = this;
function resultCallback(receivedCookies)
{
if (progress.isCanceled()) {
callback(result);
return;
}
self.processCookies(receivedCookies, requests, result);
callback(result);
}
WebInspector.Cookies.getCookiesAsync(resultCallback);
},
mapResourceCookies: function(requestsByDomain, allCookies, callback)
{
for (var i = 0; i < allCookies.length; ++i) {
for (var requestDomain in requestsByDomain) {
if (WebInspector.Cookies.cookieDomainMatchesResourceDomain(allCookies[i].domain(), requestDomain))
this._callbackForResourceCookiePairs(requestsByDomain[requestDomain], allCookies[i], callback);
}
}
},
_callbackForResourceCookiePairs: function(requests, cookie, callback)
{
if (!requests)
return;
for (var i = 0; i < requests.length; ++i) {
if (WebInspector.Cookies.cookieMatchesResourceURL(cookie, requests[i].url))
callback(requests[i], cookie);
}
},
__proto__: WebInspector.AuditRule.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRules.CookieRuleBase}
*/
WebInspector.AuditRules.CookieSizeRule = function(avgBytesThreshold)
{
WebInspector.AuditRules.CookieRuleBase.call(this, "http-cookiesize", WebInspector.UIString("Minimize cookie size"));
this._avgBytesThreshold = avgBytesThreshold;
this._maxBytesThreshold = 1000;
}
WebInspector.AuditRules.CookieSizeRule.prototype = {
_average: function(cookieArray)
{
var total = 0;
for (var i = 0; i < cookieArray.length; ++i)
total += cookieArray[i].size();
return cookieArray.length ? Math.round(total / cookieArray.length) : 0;
},
_max: function(cookieArray)
{
var result = 0;
for (var i = 0; i < cookieArray.length; ++i)
result = Math.max(cookieArray[i].size(), result);
return result;
},
processCookies: function(allCookies, requests, result)
{
function maxSizeSorter(a, b)
{
return b.maxCookieSize - a.maxCookieSize;
}
function avgSizeSorter(a, b)
{
return b.avgCookieSize - a.avgCookieSize;
}
var cookiesPerResourceDomain = {};
function collectorCallback(request, cookie)
{
var cookies = cookiesPerResourceDomain[request.parsedURL.host];
if (!cookies) {
cookies = [];
cookiesPerResourceDomain[request.parsedURL.host] = cookies;
}
cookies.push(cookie);
}
if (!allCookies.length)
return;
var sortedCookieSizes = [];
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests,
null,
true);
this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback);
for (var requestDomain in cookiesPerResourceDomain) {
var cookies = cookiesPerResourceDomain[requestDomain];
sortedCookieSizes.push({
domain: requestDomain,
avgCookieSize: this._average(cookies),
maxCookieSize: this._max(cookies)
});
}
var avgAllCookiesSize = this._average(allCookies);
var hugeCookieDomains = [];
sortedCookieSizes.sort(maxSizeSorter);
for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
var maxCookieSize = sortedCookieSizes[i].maxCookieSize;
if (maxCookieSize > this._maxBytesThreshold)
hugeCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(sortedCookieSizes[i].domain) + ": " + Number.bytesToString(maxCookieSize));
}
var bigAvgCookieDomains = [];
sortedCookieSizes.sort(avgSizeSorter);
for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
var domain = sortedCookieSizes[i].domain;
var avgCookieSize = sortedCookieSizes[i].avgCookieSize;
if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBytesThreshold)
bigAvgCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(domain) + ": " + Number.bytesToString(avgCookieSize));
}
result.addChild(WebInspector.UIString("The average cookie size for all requests on this page is %s", Number.bytesToString(avgAllCookiesSize)));
if (hugeCookieDomains.length) {
var entry = result.addChild(WebInspector.UIString("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet."), true);
entry.addURLs(hugeCookieDomains);
result.violationCount += hugeCookieDomains.length;
}
if (bigAvgCookieDomains.length) {
var entry = result.addChild(WebInspector.UIString("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.", this._avgBytesThreshold), true);
entry.addURLs(bigAvgCookieDomains);
result.violationCount += bigAvgCookieDomains.length;
}
},
__proto__: WebInspector.AuditRules.CookieRuleBase.prototype
}
/**
* @constructor
* @extends {WebInspector.AuditRules.CookieRuleBase}
*/
WebInspector.AuditRules.StaticCookielessRule = function(minResources)
{
WebInspector.AuditRules.CookieRuleBase.call(this, "http-staticcookieless", WebInspector.UIString("Serve static content from a cookieless domain"));
this._minResources = minResources;
}
WebInspector.AuditRules.StaticCookielessRule.prototype = {
processCookies: function(allCookies, requests, result)
{
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests,
[WebInspector.resourceTypes.Stylesheet,
WebInspector.resourceTypes.Image],
true);
var totalStaticResources = 0;
for (var domain in domainToResourcesMap)
totalStaticResources += domainToResourcesMap[domain].length;
if (totalStaticResources < this._minResources)
return;
var matchingResourceData = {};
this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCallback.bind(this, matchingResourceData));
var badUrls = [];
var cookieBytes = 0;
for (var url in matchingResourceData) {
badUrls.push(url);
cookieBytes += matchingResourceData[url];
}
if (badUrls.length < this._minResources)
return;
var entry = result.addChild(WebInspector.UIString("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:", Number.bytesToString(cookieBytes)), true);
entry.addURLs(badUrls);
result.violationCount = badUrls.length;
},
_collectorCallback: function(matchingResourceData, request, cookie)
{
matchingResourceData[request.url] = (matchingResourceData[request.url] || 0) + cookie.size();
},
__proto__: WebInspector.AuditRules.CookieRuleBase.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.PanelWithSidebar}
*/
WebInspector.AuditsPanel = function()
{
WebInspector.PanelWithSidebar.call(this, "audits");
this.registerRequiredCSS("ui/panelEnablerView.css");
this.registerRequiredCSS("audits/auditsPanel.css");
var sidebarTree = new TreeOutline();
sidebarTree.element.classList.add("sidebar-tree");
this.panelSidebarElement().appendChild(sidebarTree.element);
this.setDefaultFocusedElement(sidebarTree.element);
this.auditsTreeElement = new WebInspector.SidebarSectionTreeElement("");
sidebarTree.appendChild(this.auditsTreeElement);
this.auditsTreeElement.listItemElement.classList.add("hidden");
this.auditsItemTreeElement = new WebInspector.AuditsSidebarTreeElement(this);
this.auditsTreeElement.appendChild(this.auditsItemTreeElement);
this.auditResultsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RESULTS"));
sidebarTree.appendChild(this.auditResultsTreeElement);
this.auditResultsTreeElement.expand();
this._constructCategories();
this._auditController = new WebInspector.AuditController(this);
this._launcherView = new WebInspector.AuditLauncherView(this._auditController);
for (var id in this.categoriesById)
this._launcherView.addCategory(this.categoriesById[id]);
var extensionCategories = WebInspector.extensionServer.auditCategories();
for (var i = 0; i < extensionCategories.length; ++i) {
var category = extensionCategories[i];
this.addCategory(new WebInspector.AuditExtensionCategory(category.extensionOrigin, category.id, category.displayName, category.ruleCount));
}
WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.AuditCategoryAdded, this._extensionAuditCategoryAdded, this);
}
WebInspector.AuditsPanel.prototype = {
/**
* @return {!Object.<string, !WebInspector.AuditCategory>}
*/
get categoriesById()
{
return this._auditCategoriesById;
},
/**
* @param {!WebInspector.AuditCategory} category
*/
addCategory: function(category)
{
this.categoriesById[category.id] = category;
this._launcherView.addCategory(category);
},
/**
* @param {string} id
* @return {!WebInspector.AuditCategory}
*/
getCategory: function(id)
{
return this.categoriesById[id];
},
_constructCategories: function()
{
this._auditCategoriesById = {};
for (var categoryCtorID in WebInspector.AuditCategories) {
var auditCategory = new WebInspector.AuditCategories[categoryCtorID]();
auditCategory._id = categoryCtorID;
this.categoriesById[categoryCtorID] = auditCategory;
}
},
/**
* @param {string} mainResourceURL
* @param {!Array.<!WebInspector.AuditCategoryResult>} results
*/
auditFinishedCallback: function(mainResourceURL, results)
{
var ordinal = 1;
for (var child of this.auditResultsTreeElement.children()) {
if (child.mainResourceURL === mainResourceURL)
ordinal++;
}
var resultTreeElement = new WebInspector.AuditResultSidebarTreeElement(this, results, mainResourceURL, ordinal);
this.auditResultsTreeElement.appendChild(resultTreeElement);
resultTreeElement.revealAndSelect();
},
/**
* @param {!Array.<!WebInspector.AuditCategoryResult>} categoryResults
*/
showResults: function(categoryResults)
{
if (!categoryResults._resultView)
categoryResults._resultView = new WebInspector.AuditResultView(categoryResults);
this.visibleView = categoryResults._resultView;
},
showLauncherView: function()
{
this.visibleView = this._launcherView;
},
get visibleView()
{
return this._visibleView;
},
set visibleView(x)
{
if (this._visibleView === x)
return;
if (this._visibleView)
this._visibleView.detach();
this._visibleView = x;
if (x)
this.splitWidget().setMainWidget(x);
},
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (!this._visibleView)
this.auditsItemTreeElement.select();
},
clearResults: function()
{
this.auditsItemTreeElement.revealAndSelect();
this.auditResultsTreeElement.removeChildren();
},
/**
* @param {!WebInspector.Event} event
*/
_extensionAuditCategoryAdded: function(event)
{
var category = /** @type {!WebInspector.ExtensionAuditCategory} */ (event.data);
this.addCategory(new WebInspector.AuditExtensionCategory(category.extensionOrigin, category.id, category.displayName, category.ruleCount));
},
__proto__: WebInspector.PanelWithSidebar.prototype
}
/**
* @constructor
* @implements {WebInspector.AuditCategory}
* @param {string} displayName
*/
WebInspector.AuditCategoryImpl = function(displayName)
{
this._displayName = displayName;
this._rules = [];
}
WebInspector.AuditCategoryImpl.prototype = {
/**
* @override
* @return {string}
*/
get id()
{
// this._id value is injected at construction time.
return this._id;
},
/**
* @override
* @return {string}
*/
get displayName()
{
return this._displayName;
},
/**
* @param {!WebInspector.AuditRule} rule
* @param {!WebInspector.AuditRule.Severity} severity
*/
addRule: function(rule, severity)
{
rule.severity = severity;
this._rules.push(rule);
},
/**
* @override
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {!WebInspector.Progress} progress
*/
run: function(target, requests, ruleResultCallback, progress)
{
this._ensureInitialized();
var remainingRulesCount = this._rules.length;
progress.setTotalWork(remainingRulesCount);
function callbackWrapper(result)
{
ruleResultCallback(result);
progress.worked();
if (!--remainingRulesCount)
progress.done();
}
for (var i = 0; i < this._rules.length; ++i) {
if (!progress.isCanceled())
this._rules[i].run(target, requests, callbackWrapper, progress);
else
callbackWrapper(null);
}
},
_ensureInitialized: function()
{
if (!this._initialized) {
if ("initialize" in this)
this.initialize();
this._initialized = true;
}
}
}
/**
* @constructor
* @param {string} id
* @param {string} displayName
*/
WebInspector.AuditRule = function(id, displayName)
{
this._id = id;
this._displayName = displayName;
}
/**
* @enum {string}
*/
WebInspector.AuditRule.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
}
WebInspector.AuditRule.SeverityOrder = {
"info": 3,
"warning": 2,
"severe": 1
}
WebInspector.AuditRule.prototype = {
get id()
{
return this._id;
},
get displayName()
{
return this._displayName;
},
/**
* @param {!WebInspector.AuditRule.Severity} severity
*/
set severity(severity)
{
this._severity = severity;
},
/**
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
run: function(target, requests, callback, progress)
{
if (progress.isCanceled())
return;
var result = new WebInspector.AuditRuleResult(this.displayName);
result.severity = this._severity;
this.doRun(target, requests, result, callback, progress);
},
/**
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
doRun: function(target, requests, result, callback, progress)
{
throw new Error("doRun() not implemented");
}
}
/**
* @constructor
* @param {!WebInspector.AuditCategory} category
*/
WebInspector.AuditCategoryResult = function(category)
{
this.title = category.displayName;
this.ruleResults = [];
}
WebInspector.AuditCategoryResult.prototype = {
/**
* @param {!WebInspector.AuditRuleResult} ruleResult
*/
addRuleResult: function(ruleResult)
{
this.ruleResults.push(ruleResult);
}
}
/**
* @constructor
* @param {(string|boolean|number|!Object)} value
* @param {boolean=} expanded
* @param {string=} className
*/
WebInspector.AuditRuleResult = function(value, expanded, className)
{
this.value = value;
this.className = className;
this.expanded = expanded;
this.violationCount = 0;
this._formatters = {
r: WebInspector.AuditRuleResult.linkifyDisplayName
};
var standardFormatters = Object.keys(String.standardFormatters);
for (var i = 0; i < standardFormatters.length; ++i)
this._formatters[standardFormatters[i]] = String.standardFormatters[standardFormatters[i]];
}
/**
* @param {string} url
* @return {!Element}
*/
WebInspector.AuditRuleResult.linkifyDisplayName = function(url)
{
return WebInspector.linkifyURLAsNode(url, WebInspector.displayNameForURL(url));
}
/**
* @param {string} domain
* @return {string}
*/
WebInspector.AuditRuleResult.resourceDomain = function(domain)
{
return domain || WebInspector.UIString("[empty domain]");
}
WebInspector.AuditRuleResult.prototype = {
/**
* @param {(string|boolean|number|!Object)} value
* @param {boolean=} expanded
* @param {string=} className
* @return {!WebInspector.AuditRuleResult}
*/
addChild: function(value, expanded, className)
{
if (!this.children)
this.children = [];
var entry = new WebInspector.AuditRuleResult(value, expanded, className);
this.children.push(entry);
return entry;
},
/**
* @param {string} url
*/
addURL: function(url)
{
this.addChild(WebInspector.AuditRuleResult.linkifyDisplayName(url));
},
/**
* @param {!Array.<string>} urls
*/
addURLs: function(urls)
{
for (var i = 0; i < urls.length; ++i)
this.addURL(urls[i]);
},
/**
* @param {string} snippet
*/
addSnippet: function(snippet)
{
this.addChild(snippet, false, "source-code");
},
/**
* @param {string} format
* @param {...*} vararg
* @return {!WebInspector.AuditRuleResult}
*/
addFormatted: function(format, vararg)
{
var substitutions = Array.prototype.slice.call(arguments, 1);
var fragment = createDocumentFragment();
function append(a, b)
{
if (!(b instanceof Node))
b = createTextNode(b);
a.appendChild(b);
return a;
}
var formattedResult = String.format(format, substitutions, this._formatters, fragment, append).formattedResult;
if (formattedResult instanceof Node)
formattedResult.normalize();
return this.addChild(formattedResult);
}
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {!WebInspector.AuditsPanel} panel
*/
WebInspector.AuditsSidebarTreeElement = function(panel)
{
this._panel = panel;
this.small = false;
WebInspector.SidebarTreeElement.call(this, "audits-sidebar-tree-item", WebInspector.UIString("Audits"));
}
WebInspector.AuditsSidebarTreeElement.prototype = {
onattach: function()
{
WebInspector.SidebarTreeElement.prototype.onattach.call(this);
},
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._panel.showLauncherView();
return true;
},
get selectable()
{
return true;
},
refresh: function()
{
this.refreshTitles();
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {!WebInspector.AuditsPanel} panel
* @param {!Array.<!WebInspector.AuditCategoryResult>} results
* @param {string} mainResourceURL
* @param {number} ordinal
*/
WebInspector.AuditResultSidebarTreeElement = function(panel, results, mainResourceURL, ordinal)
{
this._panel = panel;
this.results = results;
this.mainResourceURL = mainResourceURL;
WebInspector.SidebarTreeElement.call(this, "audit-result-sidebar-tree-item", String.sprintf("%s (%d)", mainResourceURL, ordinal));
}
WebInspector.AuditResultSidebarTreeElement.prototype = {
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._panel.showResults(this.results);
return true;
},
get selectable()
{
return true;
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
WebInspector.AuditsPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.AuditsPanel.instance());
}
/**
* @return {!WebInspector.AuditsPanel}
*/
WebInspector.AuditsPanel.instance = function()
{
if (!WebInspector.AuditsPanel._instanceObject)
WebInspector.AuditsPanel._instanceObject = new WebInspector.AuditsPanel();
return WebInspector.AuditsPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.AuditsPanelFactory = function()
{
}
WebInspector.AuditsPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.AuditsPanel.instance();
}
}
// Contributed audit rules should go into this namespace.
WebInspector.AuditRules = {};
/**
* Contributed audit categories should go into this namespace.
* @type {!Object.<string, function(new:WebInspector.AuditCategory)>}
*/
WebInspector.AuditCategories = {};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| BlackboxManager.js | 2.86% | (5 / 175) | 0% | (0 / 113) | 0% | (0 / 30) | 2.86% | (5 / 175) | |
| BreakpointManager.js | 0.22% | (1 / 450) | 0% | (0 / 190) | 0% | (0 / 74) | 0.22% | (1 / 450) | |
| CSSWorkspaceBinding.js | 0.7% | (1 / 142) | 0% | (0 / 59) | 0% | (0 / 39) | 0.7% | (1 / 142) | |
| CompilerScriptMapping.js | 1.9% | (3 / 158) | 0% | (0 / 76) | 0% | (0 / 21) | 1.9% | (3 / 158) | |
| ContentProviderBasedProject.js | 9.86% | (7 / 71) | 0% | (0 / 14) | 0% | (0 / 26) | 9.86% | (7 / 71) | |
| DebuggerWorkspaceBinding.js | 0.49% | (1 / 205) | 0% | (0 / 52) | 0% | (0 / 57) | 0.49% | (1 / 204) | |
| DefaultScriptMapping.js | 2.33% | (1 / 43) | 0% | (0 / 17) | 0% | (0 / 10) | 2.33% | (1 / 43) | |
| FileSystemWorkspaceBinding.js | 4.71% | (8 / 170) | 0% | (0 / 44) | 0% | (0 / 39) | 4.71% | (8 / 170) | |
| FileUtils.js | 3.7% | (3 / 81) | 0% | (0 / 20) | 0% | (0 / 26) | 3.7% | (3 / 81) | |
| LiveLocation.js | 5.26% | (1 / 19) | 100% | (0 / 0) | 0% | (0 / 14) | 5.26% | (1 / 19) | |
| NetworkMapping.js | 2.41% | (2 / 83) | 0% | (0 / 29) | 0% | (0 / 20) | 2.41% | (2 / 83) | |
| NetworkProject.js | 1.18% | (2 / 169) | 0% | (0 / 109) | 0% | (0 / 28) | 1.18% | (2 / 169) | |
| PresentationConsoleMessageHelper.js | 1.37% | (1 / 73) | 0% | (0 / 46) | 0% | (0 / 12) | 1.37% | (1 / 73) | |
| ResourceScriptMapping.js | 1.72% | (3 / 174) | 0% | (0 / 103) | 0% | (0 / 36) | 1.72% | (3 / 174) | |
| ResourceUtils.js | 3.03% | (1 / 33) | 0% | (0 / 22) | 0% | (0 / 3) | 3.03% | (1 / 33) | |
| SASSSourceMapping.js | 1.89% | (1 / 53) | 0% | (0 / 20) | 0% | (0 / 11) | 1.89% | (1 / 53) | |
| StylesSourceMapping.js | 2.1% | (3 / 143) | 0% | (0 / 60) | 0% | (0 / 27) | 2.1% | (3 / 143) | |
| TempFile.js | 8.33% | (18 / 216) | 0% | (0 / 78) | 0% | (0 / 51) | 8.33% | (18 / 216) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | 2 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.BlackboxManager = function(debuggerWorkspaceBinding, networkMapping)
{
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
this._networkMapping = networkMapping;
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._patternChanged.bind(this));
WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._patternChanged.bind(this));
/** @type {!Map<!WebInspector.DebuggerModel, !Map<string, !Array<!DebuggerAgent.ScriptPosition>>>} */
this._debuggerModelData = new Map();
/** @type {!Map<string, boolean>} */
this._isBlackboxedURLCache = new Map();
}
WebInspector.BlackboxManager.prototype = {
/**
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
addChangeListener: function(listener, thisObject)
{
WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(listener, thisObject);
},
/**
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeChangeListener: function(listener, thisObject)
{
WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListener(listener, thisObject);
},
/**
* @param {!WebInspector.DebuggerModel.Location} location
* @return {boolean}
*/
isBlackboxedRawLocation: function(location)
{
var positions = this._scriptPositions(location.script());
if (!positions)
return this._isBlackboxedScript(location.script());
var index = positions.lowerBound(location, comparator);
return !!(index % 2);
/**
* @param {!WebInspector.DebuggerModel.Location} a
* @param {!DebuggerAgent.ScriptPosition} b
* @return {number}
*/
function comparator(a, b)
{
if (a.lineNumber !== b.line)
return a.lineNumber - b.line;
return a.columnNumber - b.column;
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
isBlackboxedUISourceCode: function(uiSourceCode)
{
var projectType = uiSourceCode.project().type();
var isContentScript = projectType === WebInspector.projectTypes.ContentScripts;
if (isContentScript && WebInspector.moduleSetting("skipContentScripts").get())
return true;
var url = this._uiSourceCodeURL(uiSourceCode);
return url ? this.isBlackboxedURL(url) : false;
},
/**
* @param {string} url
* @param {boolean=} isContentScript
* @return {boolean}
*/
isBlackboxedURL: function(url, isContentScript)
{
if (this._isBlackboxedURLCache.has(url))
return !!this._isBlackboxedURLCache.get(url);
if (isContentScript && WebInspector.moduleSetting("skipContentScripts").get())
return true;
var regex = WebInspector.moduleSetting("skipStackFramesPattern").asRegExp();
var isBlackboxed = regex && regex.test(url);
this._isBlackboxedURLCache.set(url, isBlackboxed);
return isBlackboxed;
},
/**
* @param {!WebInspector.Script} script
* @param {?WebInspector.TextSourceMap} sourceMap
* @return {!Promise<undefined>}
*/
sourceMapLoaded: function(script, sourceMap)
{
if (!sourceMap)
return Promise.resolve();
var previousScriptState = this._scriptPositions(script);
if (!previousScriptState)
return Promise.resolve();
var mappings = sourceMap.mappings().slice();
mappings.sort(mappingComparator);
if (!mappings.length) {
if (previousScriptState.length > 0)
return this._setScriptState(script, []);
return Promise.resolve();
}
var currentBlackboxed = false;
var isBlackboxed = false;
var positions = [];
// If content in script file begin is not mapped and one or more ranges are blackboxed then blackbox it.
if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) {
positions.push({ line: 0, column: 0});
currentBlackboxed = true;
}
for (var mapping of mappings) {
if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) {
positions.push({ line: mapping.lineNumber, column: mapping.columnNumber });
currentBlackboxed = !currentBlackboxed;
}
isBlackboxed = currentBlackboxed || isBlackboxed;
}
return this._setScriptState(script, !isBlackboxed ? [] : positions);
/**
* @param {!WebInspector.SourceMapEntry} a
* @param {!WebInspector.SourceMapEntry} b
* @return {number}
*/
function mappingComparator(a, b)
{
if (a.lineNumber !== b.lineNumber)
return a.lineNumber - b.lineNumber;
return a.columnNumber - b.columnNumber;
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?string}
*/
_uiSourceCodeURL: function(uiSourceCode)
{
var networkURL = this._networkMapping.networkURL(uiSourceCode);
var projectType = uiSourceCode.project().type();
if (projectType === WebInspector.projectTypes.Debugger)
return null;
var url = projectType === WebInspector.projectTypes.Formatter ? uiSourceCode.url() : networkURL;
return url ? url : null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
canBlackboxUISourceCode: function(uiSourceCode)
{
var url = this._uiSourceCodeURL(uiSourceCode);
return url ? !!this._urlToRegExpString(url) : false;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
blackboxUISourceCode: function(uiSourceCode)
{
var url = this._uiSourceCodeURL(uiSourceCode);
if (url)
this._blackboxURL(url);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
unblackboxUISourceCode: function(uiSourceCode)
{
var url = this._uiSourceCodeURL(uiSourceCode);
if (url)
this._unblackboxURL(url);
},
blackboxContentScripts: function()
{
WebInspector.moduleSetting("skipContentScripts").set(true);
},
unblackboxContentScripts: function()
{
WebInspector.moduleSetting("skipContentScripts").set(false);
},
/**
* @param {string} url
*/
_blackboxURL: function(url)
{
var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();
var regexValue = this._urlToRegExpString(url);
if (!regexValue)
return;
var found = false;
for (var i = 0; i < regexPatterns.length; ++i) {
var item = regexPatterns[i];
if (item.pattern === regexValue) {
item.disabled = false;
found = true;
break;
}
}
if (!found)
regexPatterns.push({ pattern: regexValue });
WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);
},
/**
* @param {string} url
*/
_unblackboxURL: function(url)
{
var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();
var regexValue = WebInspector.blackboxManager._urlToRegExpString(url);
if (!regexValue)
return;
regexPatterns = regexPatterns.filter(function(item) {
return item.pattern !== regexValue;
});
for (var i = 0; i < regexPatterns.length; ++i) {
var item = regexPatterns[i];
if (item.disabled)
continue;
try {
var regex = new RegExp(item.pattern);
if (regex.test(url))
item.disabled = true;
} catch (e) {
}
}
WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);
},
_patternChanged: function()
{
this._isBlackboxedURLCache.clear();
var promises = [];
for (var debuggerModel of WebInspector.DebuggerModel.instances()) {
for (var scriptId in debuggerModel.scripts) {
var script = debuggerModel.scripts[scriptId];
promises.push(this._addScript(script)
.then(loadSourceMap.bind(this, script)));
}
}
Promise.all(promises).then(this._patternChangeFinishedForTests.bind(this));
/**
* @param {!WebInspector.Script} script
* @return {!Promise<undefined>}
* @this {WebInspector.BlackboxManager}
*/
function loadSourceMap(script)
{
return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceMapForScript(script));
}
},
_patternChangeFinishedForTests: function()
{
// This method is sniffed in tests.
},
/**
* @param {!WebInspector.Event} event
*/
_globalObjectCleared: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
this._debuggerModelData.delete(debuggerModel);
this._isBlackboxedURLCache.clear();
},
/**
* @param {!WebInspector.Event} event
*/
_parsedScriptSource: function(event)
{
var script = /** @type {!WebInspector.Script} */ (event.data);
this._addScript(script);
},
/**
* @param {!WebInspector.Script} script
* @return {!Promise<undefined>}
*/
_addScript: function(script)
{
var blackboxed = this._isBlackboxedScript(script);
return this._setScriptState(script, blackboxed ? [ { line: 0, column: 0 } ] : []);
},
/**
* @param {!WebInspector.Script} script
* @return {boolean}
*/
_isBlackboxedScript: function(script)
{
return this.isBlackboxedURL(script.sourceURL, script.isContentScript());
},
/**
* @param {!WebInspector.Script} script
* @return {?Array<!DebuggerAgent.ScriptPosition>}
*/
_scriptPositions: function(script)
{
if (this._debuggerModelData.has(script.debuggerModel))
return this._debuggerModelData.get(script.debuggerModel).get(script.scriptId) || null;
return null;
},
/**
* @param {!WebInspector.Script} script
* @param {!Array<!DebuggerAgent.ScriptPosition>} positions
*/
_setScriptPositions: function(script, positions)
{
var debuggerModel = script.debuggerModel;
if (!this._debuggerModelData.has(debuggerModel))
this._debuggerModelData.set(debuggerModel, new Map());
this._debuggerModelData.get(debuggerModel).set(script.scriptId, positions);
},
/**
* @param {!WebInspector.Script} script
* @param {!Array<!DebuggerAgent.ScriptPosition>} positions
* @return {!Promise<undefined>}
*/
_setScriptState: function(script, positions)
{
var previousScriptState = this._scriptPositions(script);
if (previousScriptState) {
var hasChanged = false;
hasChanged = previousScriptState.length !== positions.length;
for (var i = 0; !hasChanged && i < positions.length; ++i)
hasChanged = positions[i].line !== previousScriptState[i].line || positions[i].column !== previousScriptState[i].column;
if (!hasChanged)
return Promise.resolve();
} else {
if (positions.length === 0)
return Promise.resolve().then(updateState.bind(this, false));
}
return script.setBlackboxedRanges(positions).then(updateState.bind(this));
/**
* @param {boolean} success
* @this {WebInspector.BlackboxManager}
*/
function updateState(success)
{
if (success) {
this._setScriptPositions(script, positions);
this._debuggerWorkspaceBinding.updateLocations(script);
var isBlackboxed = positions.length !== 0;
if (!isBlackboxed && script.sourceMapURL)
this._debuggerWorkspaceBinding.maybeLoadSourceMap(script);
} else {
var hasPositions = !!this._scriptPositions(script);
if (!hasPositions)
this._setScriptPositions(script, []);
}
}
},
/**
* @param {string} url
* @return {string}
*/
_urlToRegExpString: function(url)
{
var parsedURL = new WebInspector.ParsedURL(url);
if (parsedURL.isAboutBlank() || parsedURL.isDataURL())
return "";
if (!parsedURL.isValid)
return "^" + url.escapeForRegExp() + "$";
var name = parsedURL.lastPathComponent;
if (name)
name = "/" + name;
else if (parsedURL.folderPathComponents)
name = parsedURL.folderPathComponents + "/";
if (!name)
name = parsedURL.host;
if (!name)
return "";
var scheme = parsedURL.scheme;
var prefix = "";
if (scheme && scheme !== "http" && scheme !== "https") {
prefix = "^" + scheme + "://";
if (scheme === "chrome-extension")
prefix += parsedURL.host + "\\b";
prefix += ".*";
}
return prefix + name.escapeForRegExp() + (url.endsWith(name) ? "$" : "\\b");
}
}
/** @type {!WebInspector.BlackboxManager} */
WebInspector.blackboxManager;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TargetManager.Observer}
* @param {?WebInspector.Setting} breakpointsSetting
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.BreakpointManager = function(breakpointsSetting, workspace, networkMapping, targetManager, debuggerWorkspaceBinding)
{
this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointsSetting);
this._workspace = workspace;
this._networkMapping = networkMapping;
this._targetManager = targetManager;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
this._breakpointsActive = true;
this._breakpointsForUISourceCode = new Map();
this._breakpointsForPrimaryUISourceCode = new Map();
/** @type {!Multimap.<string, !WebInspector.BreakpointManager.Breakpoint>} */
this._provisionalBreakpoints = new Multimap();
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
}
WebInspector.BreakpointManager.Events = {
BreakpointAdded: "breakpoint-added",
BreakpointRemoved: "breakpoint-removed",
BreakpointsActiveStateChanged: "BreakpointsActiveStateChanged"
}
/**
* @param {string} sourceFileId
* @param {number} lineNumber
* @param {number} columnNumber
* @return {string}
*/
WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lineNumber, columnNumber)
{
if (!sourceFileId)
return "";
return sourceFileId + ":" + lineNumber + ":" + columnNumber;
}
WebInspector.BreakpointManager.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
_sourceFileId: function(uiSourceCode)
{
var networkURL = this._networkMapping.networkURL(uiSourceCode)
if (!networkURL)
return "";
return uiSourceCode.url();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel && !this._breakpointsActive)
debuggerModel.setBreakpointsActive(this._breakpointsActive);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target) { },
/**
* @param {string} sourceFileId
* @return {!Map.<string, !WebInspector.BreakpointManager.Breakpoint>}
*/
_provisionalBreakpointsForSourceFileId: function(sourceFileId)
{
var result = new Map();
var breakpoints = this._provisionalBreakpoints.get(sourceFileId).valuesArray();
for (var i = 0; i < breakpoints.length; ++i)
result.set(breakpoints[i]._breakpointStorageId(), breakpoints[i]);
return result;
},
removeProvisionalBreakpointsForTest: function()
{
var breakpoints = this._provisionalBreakpoints.valuesArray();
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();
this._provisionalBreakpoints.clear();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_restoreBreakpoints: function(uiSourceCode)
{
var sourceFileId = this._sourceFileId(uiSourceCode);
if (!sourceFileId)
return;
this._storage.mute();
var breakpointItems = this._storage.breakpointItems(this._sourceFileId(uiSourceCode));
var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId(sourceFileId);
for (var i = 0; i < breakpointItems.length; ++i) {
var breakpointItem = breakpointItems[i];
var itemStorageId = WebInspector.BreakpointManager._breakpointStorageId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.columnNumber);
var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId);
if (provisionalBreakpoint) {
if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []);
this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(provisionalBreakpoint);
provisionalBreakpoint._updateBreakpoint();
} else {
this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber, breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled);
}
}
this._provisionalBreakpoints.removeAll(sourceFileId);
this._storage.unmute();
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._restoreBreakpoints(uiSourceCode);
if (uiSourceCode.contentType().hasScripts())
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._removeUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeMappingChanged: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
var isIdentity = /** @type {boolean} */ (event.data.isIdentity);
var target = /** @type {!WebInspector.Target} */ (event.data.target);
if (isIdentity)
return;
var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [];
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i]._updateInDebuggerForTarget(target);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeUISourceCode: function(uiSourceCode)
{
var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [];
var sourceFileId = this._sourceFileId(uiSourceCode);
for (var i = 0; i < breakpoints.length; ++i) {
breakpoints[i]._resetLocations();
if (breakpoints[i].enabled())
this._provisionalBreakpoints.set(sourceFileId, breakpoints[i]);
}
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this);
this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @return {!WebInspector.BreakpointManager.Breakpoint}
*/
setBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, enabled)
{
var uiLocation = new WebInspector.UILocation(uiSourceCode, lineNumber, columnNumber);
var normalizedLocation = this._debuggerWorkspaceBinding.normalizeUILocation(uiLocation);
if (normalizedLocation.id() !== uiLocation.id()) {
WebInspector.Revealer.reveal(normalizedLocation);
uiLocation = normalizedLocation;
}
this.setBreakpointsActive(true);
return this._innerSetBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, condition, enabled);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @return {!WebInspector.BreakpointManager.Breakpoint}
*/
_innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, enabled)
{
var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNumber);
if (breakpoint) {
breakpoint._updateState(condition, enabled);
return breakpoint;
}
var projectId = uiSourceCode.project().id();
var path = uiSourceCode.url();
var sourceFileId = this._sourceFileId(uiSourceCode);
breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, projectId, path, sourceFileId, lineNumber, columnNumber, condition, enabled);
if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []);
this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoint);
return breakpoint;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.BreakpointManager.Breakpoint}
*/
findBreakpoint: function(uiSourceCode, lineNumber, columnNumber)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
var columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(String(columnNumber)) : null;
return columnBreakpoints ? columnBreakpoints[0] : null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {?WebInspector.BreakpointManager.Breakpoint}
*/
findBreakpointOnLine: function(uiSourceCode, lineNumber)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
return lineBreakpoints ? lineBreakpoints.valuesArray()[0][0] : null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>}
*/
breakpointsForUISourceCode: function(uiSourceCode)
{
var result = [];
var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesArray() : [];
for (var i = 0; i < breakpoints.length; ++i) {
var lineBreakpoints = breakpoints[i];
var columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray() : [];
result = result.concat.apply(result, columnBreakpointArrays);
}
return result;
},
/**
* @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>}
*/
allBreakpoints: function()
{
var result = [];
var uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
for (var i = 0; i < uiSourceCodes.length; ++i)
result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i]));
return result;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
breakpointLocationsForUISourceCode: function(uiSourceCode)
{
var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArray() : [];
var result = [];
for (var i = 0; i < lineNumbers.length; ++i) {
var lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]);
var columnNumbers = lineBreakpoints.keysArray();
for (var j = 0; j < columnNumbers.length; ++j) {
var columnBreakpoints = lineBreakpoints.get(columnNumbers[j]);
var lineNumber = parseInt(lineNumbers[i], 10);
var columnNumber = parseInt(columnNumbers[j], 10);
for (var k = 0; k < columnBreakpoints.length; ++k) {
var breakpoint = columnBreakpoints[k];
var uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber);
result.push({breakpoint: breakpoint, uiLocation: uiLocation});
}
}
}
return result;
},
/**
* @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
allBreakpointLocations: function()
{
var result = [];
var uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
for (var i = 0; i < uiSourceCodes.length; ++i)
result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i]));
return result;
},
/**
* @param {boolean} toggleState
*/
toggleAllBreakpoints: function(toggleState)
{
var breakpoints = this.allBreakpoints();
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].setEnabled(toggleState);
},
removeAllBreakpoints: function()
{
var breakpoints = this.allBreakpoints();
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();
},
_projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
this._removeUISourceCode(uiSourceCodes[i]);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {boolean} removeFromStorage
*/
_removeBreakpoint: function(breakpoint, removeFromStorage)
{
var uiSourceCode = breakpoint.uiSourceCode();
var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [] : [];
breakpoints.remove(breakpoint);
if (removeFromStorage)
this._storage._removeBreakpoint(breakpoint);
this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!WebInspector.UILocation} uiLocation
*/
_uiLocationAdded: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints) {
breakpoints = new Map();
this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints);
}
var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
if (!lineBreakpoints) {
lineBreakpoints = new Map();
breakpoints.set(String(uiLocation.lineNumber), lineBreakpoints);
}
var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber));
if (!columnBreakpoints) {
columnBreakpoints = [];
lineBreakpoints.set(String(uiLocation.columnNumber), columnBreakpoints);
}
columnBreakpoints.push(breakpoint);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!WebInspector.UILocation} uiLocation
*/
_uiLocationRemoved: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints)
return;
var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
if (!lineBreakpoints)
return;
var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber));
if (!columnBreakpoints)
return;
columnBreakpoints.remove(breakpoint);
if (!columnBreakpoints.length)
lineBreakpoints.remove(String(uiLocation.columnNumber));
if (!lineBreakpoints.size)
breakpoints.remove(String(uiLocation.lineNumber));
if (!breakpoints.size)
this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
},
/**
* @param {boolean} active
*/
setBreakpointsActive: function(active)
{
if (this._breakpointsActive === active)
return;
this._breakpointsActive = active;
var debuggerModels = WebInspector.DebuggerModel.instances();
for (var i = 0; i < debuggerModels.length; ++i)
debuggerModels[i].setBreakpointsActive(active);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged, active);
},
/**
* @return {boolean}
*/
breakpointsActive: function()
{
return this._breakpointsActive;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.BreakpointManager} breakpointManager
* @param {string} projectId
* @param {string} path
* @param {string} sourceFileId
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
*/
WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectId, path, sourceFileId, lineNumber, columnNumber, condition, enabled)
{
this._breakpointManager = breakpointManager;
this._projectId = projectId;
this._path = path;
this._lineNumber = lineNumber;
this._columnNumber = columnNumber;
this._sourceFileId = sourceFileId;
/** @type {!Object.<string, number>} */
this._numberOfDebuggerLocationForUILocation = {};
// Force breakpoint update.
/** @type {string} */ this._condition;
/** @type {boolean} */ this._enabled;
/** @type {boolean} */ this._isRemoved;
/** @type {!WebInspector.UILocation|undefined} */ this._fakePrimaryLocation;
this._currentState = null;
/** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.TargetBreakpoint>}*/
this._targetBreakpoints = new Map();
this._updateState(condition, enabled);
this._breakpointManager._targetManager.observeTargets(this);
}
WebInspector.BreakpointManager.Breakpoint.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return;
var networkMapping = this._breakpointManager._networkMapping;
var debuggerWorkspaceBinding = this._breakpointManager._debuggerWorkspaceBinding;
this._targetBreakpoints.set(target, new WebInspector.BreakpointManager.TargetBreakpoint(debuggerModel, this, networkMapping, debuggerWorkspaceBinding));
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return;
var targetBreakpoint = this._targetBreakpoints.remove(target);
targetBreakpoint._cleanUpAfterDebuggerIsGone();
targetBreakpoint._removeEventListeners();
},
/**
* @return {string}
*/
projectId: function()
{
return this._projectId;
},
/**
* @return {string}
*/
path: function()
{
return this._path;
},
/**
* @return {number}
*/
lineNumber: function()
{
return this._lineNumber;
},
/**
* @return {number}
*/
columnNumber: function()
{
return this._columnNumber;
},
/**
* @return {?WebInspector.UISourceCode}
*/
uiSourceCode: function()
{
return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
},
/**
* @param {?WebInspector.UILocation} oldUILocation
* @param {!WebInspector.UILocation} newUILocation
*/
_replaceUILocation: function(oldUILocation, newUILocation)
{
if (this._isRemoved)
return;
this._removeUILocation(oldUILocation, true);
this._removeFakeBreakpointAtPrimaryLocation();
if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0;
if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] === 1)
this._breakpointManager._uiLocationAdded(this, newUILocation);
},
/**
* @param {?WebInspector.UILocation} uiLocation
* @param {boolean=} muteCreationFakeBreakpoint
*/
_removeUILocation: function(uiLocation, muteCreationFakeBreakpoint)
{
if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocation.id()] !== 0)
return;
delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];
this._breakpointManager._uiLocationRemoved(this, uiLocation);
if (!muteCreationFakeBreakpoint)
this._fakeBreakpointAtPrimaryLocation();
},
/**
* @return {boolean}
*/
enabled: function()
{
return this._enabled;
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._updateState(this._condition, enabled);
},
/**
* @return {string}
*/
condition: function()
{
return this._condition;
},
/**
* @param {string} condition
*/
setCondition: function(condition)
{
this._updateState(condition, this._enabled);
},
/**
* @param {string} condition
* @param {boolean} enabled
*/
_updateState: function(condition, enabled)
{
if (this._enabled === enabled && this._condition === condition)
return;
this._enabled = enabled;
this._condition = condition;
this._breakpointManager._storage._updateBreakpoint(this);
this._updateBreakpoint();
},
_updateBreakpoint: function()
{
this._removeFakeBreakpointAtPrimaryLocation();
this._fakeBreakpointAtPrimaryLocation();
var targetBreakpoints = this._targetBreakpoints.valuesArray();
for (var i = 0; i < targetBreakpoints.length; ++i)
targetBreakpoints[i]._scheduleUpdateInDebugger();
},
/**
* @param {boolean=} keepInStorage
*/
remove: function(keepInStorage)
{
this._isRemoved = true;
var removeFromStorage = !keepInStorage;
this._removeFakeBreakpointAtPrimaryLocation();
var targetBreakpoints = this._targetBreakpoints.valuesArray();
for (var i = 0; i < targetBreakpoints.length; ++i) {
targetBreakpoints[i]._scheduleUpdateInDebugger();
targetBreakpoints[i]._removeEventListeners();
}
this._breakpointManager._removeBreakpoint(this, removeFromStorage);
this._breakpointManager._targetManager.unobserveTargets(this);
},
/**
* @param {!WebInspector.Target} target
*/
_updateInDebuggerForTarget: function(target)
{
this._targetBreakpoints.get(target)._scheduleUpdateInDebugger();
},
/**
* @return {string}
*/
_breakpointStorageId: function()
{
return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId, this._lineNumber, this._columnNumber);
},
_fakeBreakpointAtPrimaryLocation: function()
{
if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationForUILocation) || this._fakePrimaryLocation)
return;
var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
if (!uiSourceCode)
return;
this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnNumber);
if (this._fakePrimaryLocation)
this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation);
},
_removeFakeBreakpointAtPrimaryLocation: function()
{
if (this._fakePrimaryLocation) {
this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation);
delete this._fakePrimaryLocation;
}
},
_resetLocations: function()
{
this._removeFakeBreakpointAtPrimaryLocation();
var targetBreakpoints = this._targetBreakpoints.valuesArray();
for (var i = 0; i < targetBreakpoints.length; ++i)
targetBreakpoints[i]._resetLocations();
}
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!WebInspector.NetworkMapping} networkMapping
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.BreakpointManager.TargetBreakpoint = function(debuggerModel, breakpoint, networkMapping, debuggerWorkspaceBinding)
{
WebInspector.SDKObject.call(this, debuggerModel.target());
this._debuggerModel = debuggerModel;
this._breakpoint = breakpoint;
this._networkMapping = networkMapping;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
this._liveLocations = new WebInspector.LiveLocationPool();
/** @type {!Object.<string, !WebInspector.UILocation>} */
this._uiLocations = {};
this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this);
this._hasPendingUpdate = false;
this._isUpdating = false;
this._cancelCallback = false;
this._currentState = null;
if (this._debuggerModel.debuggerEnabled())
this._scheduleUpdateInDebugger();
}
WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
_resetLocations: function()
{
var uiLocations = Object.values(this._uiLocations);
for (var i = 0; i < uiLocations.length; ++i)
this._breakpoint._removeUILocation(uiLocations[i]);
this._uiLocations = {};
this._liveLocations.disposeAll();
},
_scheduleUpdateInDebugger: function()
{
if (this._isUpdating) {
this._hasPendingUpdate = true;
return;
}
this._isUpdating = true;
this._updateInDebugger(this._didUpdateInDebugger.bind(this));
},
_didUpdateInDebugger: function()
{
this._isUpdating = false;
if (this._hasPendingUpdate) {
this._hasPendingUpdate = false;
this._scheduleUpdateInDebugger();
}
},
/**
* @return {boolean}
*/
_scriptDiverged: function()
{
var uiSourceCode = this._breakpoint.uiSourceCode();
if (!uiSourceCode)
return false;
var scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, this.target());
return !!scriptFile && scriptFile.hasDivergedFromVM();
},
/**
* @param {function()} callback
*/
_updateInDebugger: function(callback)
{
if (this.target().isDetached()) {
this._cleanUpAfterDebuggerIsGone();
callback();
return;
}
var uiSourceCode = this._breakpoint.uiSourceCode();
var lineNumber = this._breakpoint._lineNumber;
var columnNumber = this._breakpoint._columnNumber;
var condition = this._breakpoint.condition();
var debuggerLocation = uiSourceCode ? this._debuggerWorkspaceBinding.uiLocationToRawLocation(this.target(), uiSourceCode, lineNumber, columnNumber) : null;
var newState;
if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._scriptDiverged())
newState = null;
else if (debuggerLocation) {
var script = debuggerLocation.script();
if (script.sourceURL)
newState = new WebInspector.BreakpointManager.Breakpoint.State(script.sourceURL, null, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition);
else
newState = new WebInspector.BreakpointManager.Breakpoint.State(null, debuggerLocation.scriptId, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition);
} else if (this._breakpoint._currentState && this._breakpoint._currentState.url) {
var position = this._breakpoint._currentState;
newState = new WebInspector.BreakpointManager.Breakpoint.State(position.url, null, position.lineNumber, position.columnNumber, condition);
} else if (uiSourceCode) {
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (networkURL)
newState = new WebInspector.BreakpointManager.Breakpoint.State(networkURL, null, lineNumber, columnNumber, condition);
}
if (this._debuggerId && WebInspector.BreakpointManager.Breakpoint.State.equals(newState, this._currentState)) {
callback();
return;
}
this._breakpoint._currentState = newState;
if (this._debuggerId) {
this._resetLocations();
this._debuggerModel.removeBreakpoint(this._debuggerId, this._didRemoveFromDebugger.bind(this, callback));
this._scheduleUpdateInDebugger();
this._currentState = null;
return;
}
if (!newState) {
callback();
return;
}
var updateCallback = this._didSetBreakpointInDebugger.bind(this, callback);
if (newState.url)
this._debuggerModel.setBreakpointByURL(newState.url, newState.lineNumber, newState.columnNumber, this._breakpoint.condition(), updateCallback);
else if (newState.scriptId)
this._debuggerModel.setBreakpointBySourceId(/** @type {!WebInspector.DebuggerModel.Location} */ (debuggerLocation), condition, updateCallback);
this._currentState = newState;
},
/**
* @param {function()} callback
* @param {?DebuggerAgent.BreakpointId} breakpointId
* @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
*/
_didSetBreakpointInDebugger: function(callback, breakpointId, locations)
{
if (this._cancelCallback) {
this._cancelCallback = false;
callback();
return;
}
if (!breakpointId) {
this._breakpoint.remove(true);
callback();
return;
}
this._debuggerId = breakpointId;
this._debuggerModel.addBreakpointListener(this._debuggerId, this._breakpointResolved, this);
for (var i = 0; i < locations.length; ++i) {
if (!this._addResolvedLocation(locations[i]))
break;
}
callback();
},
/**
* @param {function()} callback
*/
_didRemoveFromDebugger: function(callback)
{
if (this._cancelCallback) {
this._cancelCallback = false;
callback();
return;
}
this._resetLocations();
this._debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpointResolved, this);
delete this._debuggerId;
callback();
},
/**
* @param {!WebInspector.Event} event
*/
_breakpointResolved: function(event)
{
this._addResolvedLocation(/** @type {!WebInspector.DebuggerModel.Location}*/ (event.data));
},
/**
* @param {!WebInspector.DebuggerModel.Location} location
* @param {!WebInspector.LiveLocation} liveLocation
*/
_locationUpdated: function(location, liveLocation)
{
var uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
var oldUILocation = this._uiLocations[location.id()] || null;
this._uiLocations[location.id()] = uiLocation;
this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
},
/**
* @param {!WebInspector.DebuggerModel.Location} location
* @return {boolean}
*/
_addResolvedLocation: function(location)
{
var uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(location);
var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
if (breakpoint && breakpoint !== this._breakpoint) {
// location clash
this._breakpoint.remove();
return false;
}
this._debuggerWorkspaceBinding.createLiveLocation(location, this._locationUpdated.bind(this, location), this._liveLocations);
return true;
},
_cleanUpAfterDebuggerIsGone: function()
{
if (this._isUpdating)
this._cancelCallback = true;
this._resetLocations();
this._currentState = null;
if (this._debuggerId)
this._didRemoveFromDebugger(function() {});
},
_removeEventListeners: function()
{
this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this);
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @param {?string} url
* @param {?string} scriptId
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
*/
WebInspector.BreakpointManager.Breakpoint.State = function(url, scriptId, lineNumber, columnNumber, condition)
{
this.url = url;
this.scriptId = scriptId;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.condition = condition;
}
/**
* @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateA
* @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateB
* @return {boolean}
*/
WebInspector.BreakpointManager.Breakpoint.State.equals = function(stateA, stateB)
{
if (!stateA || !stateB)
return false;
if (stateA.scriptId || stateB.scriptId)
return false;
return stateA.url === stateB.url && stateA.lineNumber === stateB.lineNumber && stateA.columnNumber === stateB.columnNumber && stateA.condition === stateB.condition;
}
/**
* @constructor
* @param {!WebInspector.BreakpointManager} breakpointManager
* @param {?WebInspector.Setting} setting
*/
WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
{
this._breakpointManager = breakpointManager;
this._setting = setting || WebInspector.settings.createLocalSetting("breakpoints", []);
var breakpoints = this._setting.get();
/** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} */
this._breakpoints = {};
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = /** @type {!WebInspector.BreakpointManager.Storage.Item} */ (breakpoints[i]);
breakpoint.columnNumber = breakpoint.columnNumber || 0;
this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber + ":" + breakpoint.columnNumber] = breakpoint;
}
}
WebInspector.BreakpointManager.Storage.prototype = {
mute: function()
{
this._muted = true;
},
unmute: function()
{
delete this._muted;
},
/**
* @param {string} sourceFileId
* @return {!Array.<!WebInspector.BreakpointManager.Storage.Item>}
*/
breakpointItems: function(sourceFileId)
{
var result = [];
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
if (breakpoint.sourceFileId === sourceFileId)
result.push(breakpoint);
}
return result;
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
*/
_updateBreakpoint: function(breakpoint)
{
if (this._muted || !breakpoint._breakpointStorageId())
return;
this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.BreakpointManager.Storage.Item(breakpoint);
this._save();
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
*/
_removeBreakpoint: function(breakpoint)
{
if (this._muted)
return;
delete this._breakpoints[breakpoint._breakpointStorageId()];
this._save();
},
_save: function()
{
var breakpointsArray = [];
for (var id in this._breakpoints)
breakpointsArray.push(this._breakpoints[id]);
this._setting.set(breakpointsArray);
}
}
/**
* @constructor
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
*/
WebInspector.BreakpointManager.Storage.Item = function(breakpoint)
{
this.sourceFileId = breakpoint._sourceFileId;
this.lineNumber = breakpoint.lineNumber();
this.columnNumber = breakpoint.columnNumber();
this.condition = breakpoint.condition();
this.enabled = breakpoint.enabled();
}
/** @type {!WebInspector.BreakpointManager} */
WebInspector.breakpointManager;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.CSSWorkspaceBinding = function(targetManager, workspace, networkMapping)
{
this._workspace = workspace;
this._networkMapping = networkMapping;
/** @type {!Map.<!WebInspector.CSSModel, !WebInspector.CSSWorkspaceBinding.TargetInfo>} */
this._modelToTargetInfo = new Map();
targetManager.observeTargets(this);
targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameCreatedOrNavigated, this);
}
WebInspector.CSSWorkspaceBinding.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel)
this._modelToTargetInfo.set(cssModel, new WebInspector.CSSWorkspaceBinding.TargetInfo(cssModel, this._workspace, this._networkMapping));
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel)
this._modelToTargetInfo.remove(cssModel)._dispose();
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @param {!WebInspector.CSSSourceMapping} mapping
*/
pushSourceMapping: function(header, mapping)
{
this._ensureInfoForHeader(header)._pushSourceMapping(mapping);
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {?WebInspector.CSSWorkspaceBinding.HeaderInfo}
*/
_headerInfo: function(header)
{
var map = this._modelToTargetInfo.get(header.cssModel());
return map._headerInfo(header.id) || null;
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo}
*/
_ensureInfoForHeader: function(header)
{
var targetInfo = this._modelToTargetInfo.get(header.cssModel());
if (!targetInfo) {
targetInfo = new WebInspector.CSSWorkspaceBinding.TargetInfo(header.cssModel(), this._workspace, this._networkMapping);
this._modelToTargetInfo.set(header.cssModel(), targetInfo);
}
return targetInfo._ensureInfoForHeader(header);
},
/**
* @param {!WebInspector.Event} event
*/
_mainFrameCreatedOrNavigated: function(event)
{
var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.target).target();
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel)
this._modelToTargetInfo.get(cssModel)._reset();
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
updateLocations: function(header)
{
var info = this._headerInfo(header);
if (info)
info._updateLocations();
},
/**
* @param {!WebInspector.CSSLocation} rawLocation
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.CSSWorkspaceBinding.LiveLocation}
*/
createLiveLocation: function(rawLocation, updateDelegate, locationPool)
{
var header = rawLocation.styleSheetId ? rawLocation.cssModel().styleSheetHeaderForId(rawLocation.styleSheetId) : null;
return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.cssModel(), header, rawLocation, this, updateDelegate, locationPool);
},
/**
* @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
*/
_addLiveLocation: function(location)
{
this._ensureInfoForHeader(location._header)._addLocation(location);
},
/**
* @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
*/
_removeLiveLocation: function(location)
{
var info = this._headerInfo(location._header);
if (info)
info._removeLocation(location);
},
/**
* @param {!WebInspector.CSSProperty} cssProperty
* @param {boolean} forName
* @return {?WebInspector.UILocation}
*/
propertyUILocation: function(cssProperty, forName)
{
var style = cssProperty.ownerStyle;
if (!style || !style.parentRule || !style.styleSheetId)
return null;
var range = cssProperty.range;
if (!range)
return null;
var header = style.cssModel().styleSheetHeaderForId(style.styleSheetId);
if (!header)
return null;
var line = forName ? range.startLine : range.endLine;
// End of range is exclusive, so subtract 1 from the end offset.
var column = forName ? range.startColumn : range.endColumn - (cssProperty.text && cssProperty.text.endsWith(";") ? 2 : 1);
var rawLocation = new WebInspector.CSSLocation(header, header.lineNumberInSource(line), header.columnNumberInSource(line, column));
return this.rawLocationToUILocation(rawLocation);
},
/**
* @param {?WebInspector.CSSLocation} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
if (!rawLocation)
return null;
var header = rawLocation.cssModel().styleSheetHeaderForId(rawLocation.styleSheetId);
if (!header)
return null;
var info = this._headerInfo(header);
return info ? info._rawLocationToUILocation(rawLocation.lineNumber, rawLocation.columnNumber) : null;
}
}
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.CSSWorkspaceBinding.TargetInfo = function(cssModel, workspace, networkMapping)
{
this._cssModel = cssModel;
this._stylesSourceMapping = new WebInspector.StylesSourceMapping(cssModel, workspace, networkMapping);
this._sassSourceMapping = new WebInspector.SASSSourceMapping(cssModel, networkMapping, WebInspector.NetworkProject.forTarget(cssModel.target()));
/** @type {!Map.<string, !WebInspector.CSSWorkspaceBinding.HeaderInfo>} */
this._headerInfoById = new Map();
cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
}
WebInspector.CSSWorkspaceBinding.TargetInfo.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_styleSheetAdded: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
this._stylesSourceMapping.addHeader(header);
this._sassSourceMapping.addHeader(header);
},
/**
* @param {!WebInspector.Event} event
*/
_styleSheetRemoved: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
this._stylesSourceMapping.removeHeader(header);
this._sassSourceMapping.removeHeader(header);
this._headerInfoById.remove(header.id);
},
/**
* @param {!CSSAgent.StyleSheetId} id
*/
_headerInfo: function(id)
{
return this._headerInfoById.get(id);
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo}
*/
_ensureInfoForHeader: function(header)
{
var info = this._headerInfoById.get(header.id);
if (!info) {
info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header);
this._headerInfoById.set(header.id, info);
}
return info;
},
_dispose: function()
{
this._reset();
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
},
_reset: function()
{
this._headerInfoById.clear();
}
}
/**
* @constructor
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header)
{
this._header = header;
/** @type {!Array.<!WebInspector.CSSSourceMapping>} */
this._sourceMappings = [];
/** @type {!Set.<!WebInspector.LiveLocation>} */
this._locations = new Set();
}
WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = {
/**
* @param {!WebInspector.LiveLocation} location
*/
_addLocation: function(location)
{
this._locations.add(location);
location.update();
},
/**
* @param {!WebInspector.LiveLocation} location
*/
_removeLocation: function(location)
{
this._locations.delete(location);
},
_updateLocations: function()
{
var items = this._locations.valuesArray();
for (var i = 0; i < items.length; ++i)
items[i].update();
},
/**
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {?WebInspector.UILocation}
*/
_rawLocationToUILocation: function(lineNumber, columnNumber)
{
var uiLocation = null;
var rawLocation = new WebInspector.CSSLocation(this._header, lineNumber, columnNumber);
for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
return uiLocation;
},
/**
* @param {!WebInspector.CSSSourceMapping} sourceMapping
*/
_pushSourceMapping: function(sourceMapping)
{
if (this._sourceMappings.indexOf(sourceMapping) !== -1)
return;
this._sourceMappings.push(sourceMapping);
this._updateLocations();
}
}
/**
* @constructor
* @extends {WebInspector.LiveLocationWithPool}
* @param {!WebInspector.CSSModel} cssModel
* @param {?WebInspector.CSSStyleSheetHeader} header
* @param {!WebInspector.CSSLocation} rawLocation
* @param {!WebInspector.CSSWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
*/
WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLocation, binding, updateDelegate, locationPool)
{
WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._cssModel = cssModel;
this._rawLocation = rawLocation;
this._binding = binding;
if (!header)
this._clearStyleSheet();
else
this._setStyleSheet(header);
}
WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_styleSheetAdded: function(event)
{
console.assert(!this._header);
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
if (header.sourceURL && header.sourceURL === this._rawLocation.url)
this._setStyleSheet(header);
},
/**
* @param {!WebInspector.Event} event
*/
_styleSheetRemoved: function(event)
{
console.assert(this._header);
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
if (this._header !== header)
return;
this._binding._removeLiveLocation(this);
this._clearStyleSheet();
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
_setStyleSheet: function(header)
{
this._header = header;
this._binding._addLiveLocation(this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
},
_clearStyleSheet: function()
{
delete this._header;
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
},
/**
* @override
* @return {?WebInspector.UILocation}
*/
uiLocation: function()
{
var cssLocation = this._rawLocation;
if (this._header) {
var headerInfo = this._binding._headerInfo(this._header);
return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, cssLocation.columnNumber);
}
var uiSourceCode = this._binding._networkMapping.uiSourceCodeForStyleURL(cssLocation.url, cssLocation.header());
if (!uiSourceCode)
return null;
return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.columnNumber);
},
/**
* @override
*/
dispose: function()
{
WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
if (this._header)
this._binding._removeLiveLocation(this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
},
/**
* @override
* @return {boolean}
*/
isBlackboxed: function()
{
return false;
},
__proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
* @interface
*/
WebInspector.CSSSourceMapping = function()
{
}
WebInspector.CSSSourceMapping.prototype = {
/**
* @param {!WebInspector.CSSLocation} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation) { },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.CSSLocation}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { },
/**
* @return {boolean}
*/
isIdentity: function() { },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber) { }
}
/**
* @type {!WebInspector.CSSWorkspaceBinding}
*/
WebInspector.cssWorkspaceBinding;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.DebuggerSourceMapping}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
* @param {!WebInspector.NetworkProject} networkProject
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.CompilerScriptMapping = function(debuggerModel, workspace, networkMapping, networkProject, debuggerWorkspaceBinding)
{
this._target = debuggerModel.target();
this._debuggerModel = debuggerModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
this._networkMapping = networkMapping;
this._networkProject = networkProject;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
/** @type {!Map<string, !Promise<?WebInspector.TextSourceMap>>} */
this._sourceMapLoadingPromises = new Map();
/** @type {!Map<string, !WebInspector.TextSourceMap>} */
this._sourceMapForScriptId = new Map();
/** @type {!Map.<!WebInspector.TextSourceMap, !WebInspector.Script>} */
this._scriptForSourceMap = new Map();
/** @type {!Map.<string, !WebInspector.TextSourceMap>} */
this._sourceMapForURL = new Map();
/** @type {!Map.<string, !WebInspector.UISourceCode>} */
this._stubUISourceCodes = new Map();
this._stubProjectID = "compiler-script-project";
this._stubProject = new WebInspector.ContentProviderBasedProject(this._workspace, this._stubProjectID, WebInspector.projectTypes.Service, "");
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}
WebInspector.CompilerScriptMapping.StubProjectID = "compiler-script-project";
WebInspector.CompilerScriptMapping._originSymbol = Symbol("origin");
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?string}
*/
WebInspector.CompilerScriptMapping.uiSourceCodeOrigin = function(uiSourceCode)
{
return uiSourceCode[WebInspector.CompilerScriptMapping._originSymbol] || null;
}
WebInspector.CompilerScriptMapping.prototype = {
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {boolean}
*/
mapsToSourceCode: function (rawLocation) {
var sourceMap = this._sourceMapForScriptId.get(rawLocation.scriptId);
if (!sourceMap) {
return true;
}
return !!sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber);
},
/**
* @override
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
var stubUISourceCode = this._stubUISourceCodes.get(debuggerModelLocation.scriptId);
if (stubUISourceCode)
return new WebInspector.UILocation(stubUISourceCode, rawLocation.lineNumber, rawLocation.columnNumber);
var sourceMap = this._sourceMapForScriptId.get(debuggerModelLocation.scriptId);
if (!sourceMap)
return null;
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
var entry = sourceMap.findEntry(lineNumber, columnNumber);
if (!entry || !entry.sourceURL)
return null;
var uiSourceCode = this._networkMapping.uiSourceCodeForScriptURL(/** @type {string} */ (entry.sourceURL), rawLocation.script());
if (!uiSourceCode)
return null;
return uiSourceCode.uiLocation(/** @type {number} */ (entry.sourceLineNumber), /** @type {number} */ (entry.sourceColumnNumber));
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
if (uiSourceCode.project().type() === WebInspector.projectTypes.Service)
return null;
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (!networkURL)
return null;
var sourceMap = this._sourceMapForURL.get(networkURL);
if (!sourceMap)
return null;
var script = /** @type {!WebInspector.Script} */ (this._scriptForSourceMap.get(sourceMap));
console.assert(script);
var entry = sourceMap.firstSourceLineMapping(networkURL, lineNumber);
if (!entry)
return null;
return this._debuggerModel.createRawLocation(script, entry.lineNumber, entry.columnNumber);
},
/**
* @param {!WebInspector.Script} script
*/
addScript: function(script)
{
if (!script.sourceMapURL) {
script.addEventListener(WebInspector.Script.Events.SourceMapURLAdded, this._sourceMapURLAdded.bind(this));
return;
}
this._processScript(script);
},
/**
* @param {!WebInspector.Script} script
* @return {?WebInspector.TextSourceMap}
*/
sourceMapForScript: function(script)
{
return this._sourceMapForScriptId.get(script.scriptId) || null;
},
/**
* @param {!WebInspector.Script} script
*/
maybeLoadSourceMap: function(script)
{
if (!script.sourceMapURL)
return;
if (this._sourceMapLoadingPromises.has(script.sourceMapURL))
return;
if (this._sourceMapForScriptId.has(script.scriptId))
return;
this._processScript(script);
},
/**
* @param {!WebInspector.Event} event
*/
_sourceMapURLAdded: function(event)
{
var script = /** @type {!WebInspector.Script} */ (event.target);
if (!script.sourceMapURL)
return;
this._processScript(script);
},
/**
* @param {!WebInspector.Script} script
*/
_processScript: function(script)
{
if (WebInspector.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
return;
// Create stub UISourceCode for the time source mapping is being loaded.
var stubUISourceCode = this._stubProject.addContentProvider(script.sourceURL, new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!", script.sourceURL));
this._stubUISourceCodes.set(script.scriptId, stubUISourceCode);
this._debuggerWorkspaceBinding.pushSourceMapping(script, this);
this._loadSourceMapForScript(script).then(this._sourceMapLoaded.bind(this, script, stubUISourceCode.url()));
},
/**
* @param {!WebInspector.Script} script
* @param {string} uiSourceCodePath
* @param {?WebInspector.TextSourceMap} sourceMap
*/
_sourceMapLoaded: function(script, uiSourceCodePath, sourceMap)
{
WebInspector.blackboxManager.sourceMapLoaded(script, sourceMap);
this._stubUISourceCodes.delete(script.scriptId);
this._stubProject.removeFile(uiSourceCodePath);
if (!sourceMap) {
this._debuggerWorkspaceBinding.updateLocations(script);
return;
}
if (this._scriptForSourceMap.get(sourceMap)) {
this._sourceMapForScriptId.set(script.scriptId, sourceMap);
this._debuggerWorkspaceBinding.updateLocations(script);
return;
}
this._sourceMapForScriptId.set(script.scriptId, sourceMap);
this._scriptForSourceMap.set(sourceMap, script);
// Report sources.
var sourceURLs = sourceMap.sourceURLs();
var missingSources = [];
for (var i = 0; i < sourceURLs.length; ++i) {
var sourceURL = sourceURLs[i];
if (this._sourceMapForURL.get(sourceURL))
continue;
this._sourceMapForURL.set(sourceURL, sourceMap);
var uiSourceCode = this._networkMapping.uiSourceCodeForScriptURL(sourceURL, script);
if (!uiSourceCode && !this._networkMapping.hasMappingForNetworkURL(sourceURL)) {
var contentProvider = sourceMap.sourceContentProvider(sourceURL, WebInspector.resourceTypes.SourceMapScript);
uiSourceCode = this._networkProject.addFileForURL(sourceURL, contentProvider, WebInspector.ResourceTreeFrame.fromScript(script), script.isContentScript());
uiSourceCode[WebInspector.CompilerScriptMapping._originSymbol] = script.sourceURL;
}
if (uiSourceCode) {
this._bindUISourceCode(uiSourceCode);
} else {
if (missingSources.length < 3)
missingSources.push(sourceURL);
else if (missingSources.peekLast() !== "\u2026")
missingSources.push("\u2026");
}
}
if (missingSources.length) {
WebInspector.console.warn(
WebInspector.UIString("Source map %s points to the files missing from the workspace: [%s]",
sourceMap.url(), missingSources.join(", ")));
}
this._debuggerWorkspaceBinding.updateLocations(script);
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (!networkURL)
return true;
var sourceMap = this._sourceMapForURL.get(networkURL);
if (!sourceMap)
return true;
return !!sourceMap.firstSourceLineMapping(networkURL, lineNumber);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_bindUISourceCode: function(uiSourceCode)
{
this._debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, this);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_unbindUISourceCode: function(uiSourceCode)
{
this._debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, null);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (!networkURL || !this._sourceMapForURL.get(networkURL))
return;
this._bindUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.Script} script
* @return {!Promise<?WebInspector.TextSourceMap>}
*/
_loadSourceMapForScript: function(script)
{
// script.sourceURL can be a random string, but is generally an absolute path -> complete it to inspected page url for
// relative links.
var scriptURL = WebInspector.ParsedURL.completeURL(this._target.resourceTreeModel.inspectedPageURL(), script.sourceURL);
if (!scriptURL)
return Promise.resolve(/** @type {?WebInspector.TextSourceMap} */(null));
console.assert(script.sourceMapURL);
var scriptSourceMapURL = /** @type {string} */ (script.sourceMapURL);
var sourceMapURL = WebInspector.ParsedURL.completeURL(scriptURL, scriptSourceMapURL);
if (!sourceMapURL)
return Promise.resolve(/** @type {?WebInspector.TextSourceMap} */(null));
var loadingPromise = this._sourceMapLoadingPromises.get(sourceMapURL);
if (!loadingPromise) {
loadingPromise = WebInspector.TextSourceMap.load(sourceMapURL, scriptURL).then(sourceMapLoaded.bind(this, sourceMapURL));
this._sourceMapLoadingPromises.set(sourceMapURL, loadingPromise);
}
return loadingPromise;
/**
* @param {string} url
* @param {?WebInspector.TextSourceMap} sourceMap
* @this {WebInspector.CompilerScriptMapping}
*/
function sourceMapLoaded(url, sourceMap)
{
if (!sourceMap) {
this._sourceMapLoadingPromises.delete(url);
return null;
}
return sourceMap;
}
},
_debuggerReset: function()
{
/**
* @param {!WebInspector.TextSourceMap} sourceMap
* @this {WebInspector.CompilerScriptMapping}
*/
function unbindSourceMapSources(sourceMap)
{
var script = this._scriptForSourceMap.get(sourceMap);
if (!script)
return;
var sourceURLs = sourceMap.sourceURLs();
for (var i = 0; i < sourceURLs.length; ++i) {
var uiSourceCode = this._networkMapping.uiSourceCodeForScriptURL(sourceURLs[i], script);
if (uiSourceCode)
this._unbindUISourceCode(uiSourceCode);
}
}
this._sourceMapForURL.valuesArray().forEach(unbindSourceMapSources.bind(this));
this._sourceMapLoadingPromises.clear();
this._sourceMapForScriptId.clear()
this._scriptForSourceMap.clear();
this._sourceMapForURL.clear();
},
dispose: function()
{
this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ProjectStore}
* @implements {WebInspector.Project}
* @param {!WebInspector.Workspace} workspace
* @param {string} id
* @param {!WebInspector.projectTypes} type
* @param {string} displayName
*/
WebInspector.ContentProviderBasedProject = function(workspace, id, type, displayName)
{
WebInspector.ProjectStore.call(this, workspace, id, type, displayName);
/** @type {!Object.<string, !WebInspector.ContentProvider>} */
this._contentProviders = {};
workspace.addProject(this);
}
WebInspector.ContentProviderBasedProject.prototype = {
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(?string)} callback
*/
requestFileContent: function(uiSourceCode, callback)
{
var contentProvider = this._contentProviders[uiSourceCode.url()];
contentProvider.requestContent().then(callback);
},
/**
* @override
* @return {boolean}
*/
canSetFileContent: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} newContent
* @param {function(?string)} callback
*/
setFileContent: function(uiSourceCode, newContent, callback)
{
callback(null);
},
/**
* @override
* @return {boolean}
*/
canRename: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} newName
* @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback
*/
rename: function(uiSourceCode, newName, callback)
{
var path = uiSourceCode.url();
this.performRename(path, newName, innerCallback.bind(this));
/**
* @param {boolean} success
* @param {string=} newName
* @this {WebInspector.ContentProviderBasedProject}
*/
function innerCallback(success, newName)
{
if (success && newName) {
var copyOfPath = path.split("/");
copyOfPath[copyOfPath.length - 1] = newName;
var newPath = copyOfPath.join("/");
this._contentProviders[newPath] = this._contentProviders[path];
delete this._contentProviders[path];
this.renameUISourceCode(uiSourceCode, newName);
}
callback(success, newName);
}
},
/**
* @override
* @param {string} path
* @param {function()=} callback
*/
refresh: function(path, callback)
{
if (callback)
callback();
},
/**
* @override
* @param {string} path
*/
excludeFolder: function(path)
{
},
/**
* @override
* @param {string} path
* @param {?string} name
* @param {string} content
* @param {function(?WebInspector.UISourceCode)} callback
*/
createFile: function(path, name, content, callback)
{
},
/**
* @override
* @param {string} path
*/
deleteFile: function(path)
{
},
/**
* @override
*/
remove: function()
{
},
/**
* @param {string} path
* @param {string} newName
* @param {function(boolean, string=)} callback
*/
performRename: function(path, newName, callback)
{
callback(false);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback)
{
var contentProvider = this._contentProviders[uiSourceCode.url()];
contentProvider.searchInContent(query, caseSensitive, isRegex, callback);
},
/**
* @override
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!Array.<string>} filesMathingFileQuery
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery, progress, callback)
{
var result = [];
var paths = filesMathingFileQuery;
var totalCount = paths.length;
if (totalCount === 0) {
// searchInContent should call back later.
setTimeout(doneCallback, 0);
return;
}
var barrier = new CallbackBarrier();
progress.setTotalWork(paths.length);
for (var i = 0; i < paths.length; ++i)
searchInContent.call(this, paths[i], barrier.createCallback(searchInContentCallback.bind(null, paths[i])));
barrier.callWhenDone(doneCallback);
/**
* @param {string} path
* @param {function(boolean)} callback
* @this {WebInspector.ContentProviderBasedProject}
*/
function searchInContent(path, callback)
{
var queriesToRun = searchConfig.queries().slice();
searchNextQuery.call(this);
/**
* @this {WebInspector.ContentProviderBasedProject}
*/
function searchNextQuery()
{
if (!queriesToRun.length) {
callback(true);
return;
}
var query = queriesToRun.shift();
this._contentProviders[path].searchInContent(query, !searchConfig.ignoreCase(), searchConfig.isRegex(), contentCallback.bind(this));
}
/**
* @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searchMatches
* @this {WebInspector.ContentProviderBasedProject}
*/
function contentCallback(searchMatches)
{
if (!searchMatches.length) {
callback(false);
return;
}
searchNextQuery.call(this);
}
}
/**
* @param {string} path
* @param {boolean} matches
*/
function searchInContentCallback(path, matches)
{
if (matches)
result.push(path);
progress.worked(1);
}
function doneCallback()
{
callback(result);
progress.done();
}
},
/**
* @override
* @param {!WebInspector.Progress} progress
*/
indexContent: function(progress)
{
setImmediate(progress.done.bind(progress));
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.ContentProvider} contentProvider
*/
addUISourceCodeWithProvider: function(uiSourceCode, contentProvider)
{
this._contentProviders[uiSourceCode.url()] = contentProvider;
this.addUISourceCode(uiSourceCode, true);
},
/**
* @param {string} url
* @param {!WebInspector.ContentProvider} contentProvider
* @return {!WebInspector.UISourceCode}
*/
addContentProvider: function(url, contentProvider)
{
var uiSourceCode = this.createUISourceCode(url, contentProvider.contentType());
this.addUISourceCodeWithProvider(uiSourceCode, contentProvider);
return uiSourceCode;
},
/**
* @param {string} path
*/
removeFile: function(path)
{
delete this._contentProviders[path];
this.removeUISourceCode(path);
},
reset: function()
{
this._contentProviders = {};
this.removeProject();
this.workspace().addProject(this);
},
dispose: function()
{
this._contentProviders = {};
this.removeProject();
},
__proto__: WebInspector.ProjectStore.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.DebuggerWorkspaceBinding = function(targetManager, workspace, networkMapping)
{
this._workspace = workspace;
this._networkMapping = networkMapping;
// FIXME: Migrate from _targetToData to _debuggerModelToData.
/** @type {!Map.<!WebInspector.Target, !WebInspector.DebuggerWorkspaceBinding.TargetData>} */
this._targetToData = new Map();
targetManager.observeTargets(this);
targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.BeforeDebuggerPaused, this._beforeDebuggerPaused, this);
targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
}
WebInspector.DebuggerWorkspaceBinding.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel)
this._targetToData.set(target, new WebInspector.DebuggerWorkspaceBinding.TargetData(debuggerModel, this));
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (!WebInspector.DebuggerModel.fromTarget(target))
return;
var targetData = this._targetToData.get(target);
targetData._dispose();
this._targetToData.remove(target);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
var targetDatas = this._targetToData.valuesArray();
for (var i = 0; i < targetDatas.length; ++i)
targetDatas[i]._uiSourceCodeRemoved(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var targetDatas = this._targetToData.valuesArray();
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < targetDatas.length; ++i) {
for (var j = 0; j < uiSourceCodes.length; ++j)
targetDatas[i]._uiSourceCodeRemoved(uiSourceCodes[j]);
}
},
/**
* @param {!WebInspector.Script} script
* @param {!WebInspector.DebuggerSourceMapping} sourceMapping
*/
pushSourceMapping: function(script, sourceMapping)
{
var info = this._ensureInfoForScript(script);
info._pushSourceMapping(sourceMapping);
},
/**
* @param {!WebInspector.Script} script
* @return {!WebInspector.DebuggerSourceMapping}
*/
popSourceMapping: function(script)
{
var info = this._infoForScript(script.target(), script.scriptId);
console.assert(info);
return info._popSourceMapping();
},
/**
* @param {!WebInspector.Target} target
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?WebInspector.DebuggerSourceMapping} sourceMapping
*/
setSourceMapping: function(target, uiSourceCode, sourceMapping)
{
var data = this._targetToData.get(target);
if (data)
data._setSourceMapping(uiSourceCode, sourceMapping);
},
/**
* @param {!WebInspector.Script} script
*/
updateLocations: function(script)
{
var info = this._infoForScript(script.target(), script.scriptId);
if (info)
info._updateLocations();
},
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.DebuggerWorkspaceBinding.Location}
*/
createLiveLocation: function(rawLocation, updateDelegate, locationPool)
{
var info = this._infoForScript(rawLocation.target(), rawLocation.scriptId);
console.assert(info);
var location = new WebInspector.DebuggerWorkspaceBinding.Location(info._script, rawLocation, this, updateDelegate, locationPool);
info._addLocation(location);
return location;
},
/**
* @param {!Array<!WebInspector.DebuggerModel.Location>} rawLocations
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.LiveLocation}
*/
createStackTraceTopFrameLiveLocation: function(rawLocations, updateDelegate, locationPool)
{
console.assert(rawLocations.length);
var location = new WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation(rawLocations, this, updateDelegate, locationPool);
location.update();
return location;
},
/**
* @param {!WebInspector.DebuggerModel.Location} location
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.DebuggerWorkspaceBinding.Location}
*/
createCallFrameLiveLocation: function(location, updateDelegate, locationPool)
{
var target = location.target();
this._ensureInfoForScript(location.script());
var liveLocation = this.createLiveLocation(location, updateDelegate, locationPool);
this._registerCallFrameLiveLocation(target, liveLocation);
return liveLocation;
},
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {!WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var info = this._infoForScript(rawLocation.target(), rawLocation.scriptId);
console.assert(info);
return info._rawLocationToUILocation(rawLocation);
},
/**
* @param {!WebInspector.Target} target
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(target, uiSourceCode, lineNumber, columnNumber)
{
var targetData = this._targetToData.get(target);
return targetData ? /** @type {?WebInspector.DebuggerModel.Location} */ (targetData._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber)) : null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Array.<!WebInspector.DebuggerModel.Location>}
*/
uiLocationToRawLocations: function(uiSourceCode, lineNumber, columnNumber)
{
var result = [];
var targetDatas = this._targetToData.valuesArray();
for (var i = 0; i < targetDatas.length; ++i) {
var rawLocation = targetDatas[i]._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
if (rawLocation)
result.push(rawLocation);
}
return result;
},
/**
* @param {!WebInspector.UILocation} uiLocation
* @return {!WebInspector.UILocation}
*/
normalizeUILocation: function(uiLocation)
{
var target = WebInspector.NetworkProject.targetForUISourceCode(uiLocation.uiSourceCode);
if (target) {
var rawLocation = this.uiLocationToRawLocation(target, uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
if (rawLocation)
return this.rawLocationToUILocation(rawLocation);
}
return uiLocation;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
var targetDatas = this._targetToData.valuesArray();
for (var i = 0; i < targetDatas.length; ++i) {
if (!targetDatas[i]._uiLineHasMapping(uiSourceCode, lineNumber))
return false;
}
return true;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.Target} target
* @return {?WebInspector.ResourceScriptFile}
*/
scriptFile: function(uiSourceCode, target)
{
var targetData = this._targetToData.get(target);
return targetData ? targetData._resourceMapping.scriptFile(uiSourceCode) : null;
},
/**
* @param {!WebInspector.Script} script
* @return {?WebInspector.TextSourceMap}
*/
sourceMapForScript: function(script)
{
var targetData = this._targetToData.get(script.target());
if (!targetData)
return null;
return targetData._compilerMapping.sourceMapForScript(script);
},
/**
* @param {!WebInspector.Script} script
*/
maybeLoadSourceMap: function(script)
{
var targetData = this._targetToData.get(script.target());
if (!targetData)
return;
targetData._compilerMapping.maybeLoadSourceMap(script);
},
/**
* @param {!WebInspector.Event} event
*/
_globalObjectCleared: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
this._reset(debuggerModel.target());
},
/**
* @param {!WebInspector.Target} target
*/
_reset: function(target)
{
var targetData = this._targetToData.get(target);
targetData.callFrameLocations.valuesArray().forEach((location) => this._removeLiveLocation(location));
targetData.callFrameLocations.clear();
},
/**
* @param {!WebInspector.Script} script
* @return {!WebInspector.DebuggerWorkspaceBinding.ScriptInfo}
*/
_ensureInfoForScript: function(script)
{
var scriptDataMap = this._targetToData.get(script.target()).scriptDataMap;
var info = scriptDataMap.get(script.scriptId);
if (!info) {
info = new WebInspector.DebuggerWorkspaceBinding.ScriptInfo(script);
scriptDataMap.set(script.scriptId, info);
}
return info;
},
/**
* @param {!WebInspector.Target} target
* @param {string} scriptId
* @return {?WebInspector.DebuggerWorkspaceBinding.ScriptInfo}
*/
_infoForScript: function(target, scriptId)
{
var data = this._targetToData.get(target);
if (!data)
return null;
return data.scriptDataMap.get(scriptId) || null;
},
/**
* @param {!WebInspector.Target} target
* @param {!WebInspector.DebuggerWorkspaceBinding.Location} location
*/
_registerCallFrameLiveLocation: function(target, location)
{
var locations = this._targetToData.get(target).callFrameLocations;
locations.add(location);
},
/**
* @param {!WebInspector.DebuggerWorkspaceBinding.Location} location
*/
_removeLiveLocation: function(location)
{
var info = this._infoForScript(location._script.target(), location._script.scriptId);
if (info)
info._removeLocation(location);
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerResumed: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
this._reset(debuggerModel.target());
},
/**
* @param {!WebInspector.Event} event
*/
_beforeDebuggerPaused: function(event)
{
var rawLocation = event.data.callFrames[0].location();
var targetData = this._targetToData.get(rawLocation.target());
if (!targetData._compilerMapping.mapsToSourceCode(rawLocation)) {
event.stopPropagation();
event.preventDefault();
}
}
}
/**
* @constructor
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.DebuggerWorkspaceBinding.TargetData = function(debuggerModel, debuggerWorkspaceBinding)
{
this._target = debuggerModel.target();
/** @type {!Map.<string, !WebInspector.DebuggerWorkspaceBinding.ScriptInfo>} */
this.scriptDataMap = new Map();
/** @type {!Set.<!WebInspector.DebuggerWorkspaceBinding.Location>} */
this.callFrameLocations = new Set();
var workspace = debuggerWorkspaceBinding._workspace;
var networkMapping = debuggerWorkspaceBinding._networkMapping;
this._defaultMapping = new WebInspector.DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
this._resourceMapping = new WebInspector.ResourceScriptMapping(debuggerModel, workspace, networkMapping, debuggerWorkspaceBinding);
this._compilerMapping = new WebInspector.CompilerScriptMapping(debuggerModel, workspace, networkMapping, WebInspector.NetworkProject.forTarget(this._target), debuggerWorkspaceBinding);
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.DebuggerSourceMapping>} */
this._uiSourceCodeToSourceMapping = new Map();
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}
WebInspector.DebuggerWorkspaceBinding.TargetData.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_parsedScriptSource: function(event)
{
var script = /** @type {!WebInspector.Script} */ (event.data);
this._defaultMapping.addScript(script);
this._resourceMapping.addScript(script);
if (WebInspector.moduleSetting("jsSourceMapsEnabled").get())
this._compilerMapping.addScript(script);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?WebInspector.DebuggerSourceMapping} sourceMapping
*/
_setSourceMapping: function(uiSourceCode, sourceMapping)
{
if (this._uiSourceCodeToSourceMapping.get(uiSourceCode) === sourceMapping)
return;
if (sourceMapping)
this._uiSourceCodeToSourceMapping.set(uiSourceCode, sourceMapping);
else
this._uiSourceCodeToSourceMapping.remove(uiSourceCode);
uiSourceCode.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged, {target: this._target, isIdentity: sourceMapping ? sourceMapping.isIdentity() : false});
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
_uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var sourceMapping = this._uiSourceCodeToSourceMapping.get(uiSourceCode);
return sourceMapping ? sourceMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) : null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
_uiLineHasMapping: function(uiSourceCode, lineNumber)
{
var sourceMapping = this._uiSourceCodeToSourceMapping.get(uiSourceCode);
return sourceMapping ? sourceMapping.uiLineHasMapping(uiSourceCode, lineNumber) : true;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_uiSourceCodeRemoved: function(uiSourceCode)
{
this._uiSourceCodeToSourceMapping.remove(uiSourceCode);
},
_dispose: function()
{
this._compilerMapping.dispose();
this._resourceMapping.dispose();
this._defaultMapping.dispose();
this._uiSourceCodeToSourceMapping.clear();
}
}
/**
* @constructor
* @param {!WebInspector.Script} script
*/
WebInspector.DebuggerWorkspaceBinding.ScriptInfo = function(script)
{
this._script = script;
/** @type {!Array.<!WebInspector.DebuggerSourceMapping>} */
this._sourceMappings = [];
/** @type {!Set<!WebInspector.LiveLocation>} */
this._locations = new Set();
}
WebInspector.DebuggerWorkspaceBinding.ScriptInfo.prototype = {
/**
* @param {!WebInspector.DebuggerSourceMapping} sourceMapping
*/
_pushSourceMapping: function(sourceMapping)
{
this._sourceMappings.push(sourceMapping);
this._updateLocations();
},
/**
* @return {!WebInspector.DebuggerSourceMapping}
*/
_popSourceMapping: function()
{
var sourceMapping = this._sourceMappings.pop();
this._updateLocations();
return sourceMapping;
},
/**
* @param {!WebInspector.LiveLocation} location
*/
_addLocation: function(location)
{
this._locations.add(location);
location.update();
},
/**
* @param {!WebInspector.LiveLocation} location
*/
_removeLocation: function(location)
{
this._locations.delete(location);
},
_updateLocations: function()
{
for (var location of this._locations)
location.update();
},
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {!WebInspector.UILocation}
*/
_rawLocationToUILocation: function(rawLocation)
{
var uiLocation;
for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
console.assert(uiLocation, "Script raw location cannot be mapped to any UI location.");
return /** @type {!WebInspector.UILocation} */ (uiLocation);
}
}
/**
* @constructor
* @extends {WebInspector.LiveLocationWithPool}
* @param {!WebInspector.Script} script
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {!WebInspector.DebuggerWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
*/
WebInspector.DebuggerWorkspaceBinding.Location = function(script, rawLocation, binding, updateDelegate, locationPool)
{
WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._script = script;
this._rawLocation = rawLocation;
this._binding = binding;
}
WebInspector.DebuggerWorkspaceBinding.Location.prototype = {
/**
* @override
* @return {!WebInspector.UILocation}
*/
uiLocation: function()
{
var debuggerModelLocation = this._rawLocation;
return this._binding.rawLocationToUILocation(debuggerModelLocation);
},
/**
* @override
*/
dispose: function()
{
WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
this._binding._removeLiveLocation(this);
},
/**
* @override
* @return {boolean}
*/
isBlackboxed: function()
{
return WebInspector.blackboxManager.isBlackboxedRawLocation(this._rawLocation);
},
__proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
* @constructor
* @extends {WebInspector.LiveLocationWithPool}
* @param {!Array<!WebInspector.DebuggerModel.Location>} rawLocations
* @param {!WebInspector.DebuggerWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
* @param {!WebInspector.LiveLocationPool} locationPool
*/
WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation = function(rawLocations, binding, updateDelegate, locationPool)
{
WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._updateScheduled = true;
/** @type {!Set<!WebInspector.LiveLocation>} */
this._locations = new Set();
for (var location of rawLocations)
this._locations.add(binding.createCallFrameLiveLocation(location, this._scheduleUpdate.bind(this), locationPool));
this._updateLocation();
}
WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation.prototype = {
/**
* @override
* @return {!WebInspector.UILocation}
*/
uiLocation: function()
{
return this._current.uiLocation();
},
/**
* @override
* @return {boolean}
*/
isBlackboxed: function()
{
return this._current.isBlackboxed();
},
/**
* @override
*/
dispose: function()
{
WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
for (var location of this._locations)
location.dispose();
},
_scheduleUpdate: function()
{
if (!this._updateScheduled) {
this._updateScheduled = true;
setImmediate(this._updateLocation.bind(this));
}
},
_updateLocation: function()
{
this._updateScheduled = false;
this._current = this._locations.values().next().value;
for (var current of this._locations) {
if (!current.isBlackboxed()) {
this._current = current;
break;
}
}
this.update();
},
__proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
* @interface
*/
WebInspector.DebuggerSourceMapping = function()
{
}
WebInspector.DebuggerSourceMapping.prototype = {
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation) { },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { },
/**
* @return {boolean}
*/
isIdentity: function() { },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber) { }
}
/**
* @type {!WebInspector.DebuggerWorkspaceBinding}
*/
WebInspector.debuggerWorkspaceBinding;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.DebuggerSourceMapping}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.DefaultScriptMapping = function(debuggerModel, workspace, debuggerWorkspaceBinding)
{
this._debuggerModel = debuggerModel;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
this._workspace = workspace;
this._projectId = WebInspector.DefaultScriptMapping.projectIdForTarget(debuggerModel.target());
this._project = new WebInspector.ContentProviderBasedProject(this._workspace, this._projectId, WebInspector.projectTypes.Debugger, "");
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._debuggerReset();
}
WebInspector.DefaultScriptMapping._scriptSymbol = Symbol("symbol");
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?WebInspector.Script}
*/
WebInspector.DefaultScriptMapping.scriptForUISourceCode = function(uiSourceCode)
{
return uiSourceCode[WebInspector.DefaultScriptMapping._scriptSymbol] || null;
}
WebInspector.DefaultScriptMapping.prototype = {
/**
* @override
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {!WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
var script = debuggerModelLocation.script();
var uiSourceCode = this._uiSourceCodeForScriptId.get(script.scriptId);
var lineNumber = debuggerModelLocation.lineNumber - (script.isInlineScriptWithSourceURL() ? script.lineOffset : 0);
var columnNumber = debuggerModelLocation.columnNumber || 0;
if (script.isInlineScriptWithSourceURL() && !lineNumber && columnNumber)
columnNumber -= script.columnOffset;
return uiSourceCode.uiLocation(lineNumber, columnNumber);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scriptId = this._scriptIdForUISourceCode.get(uiSourceCode);
var script = this._debuggerModel.scriptForId(scriptId);
if (script.isInlineScriptWithSourceURL())
return this._debuggerModel.createRawLocation(script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
/**
* @param {!WebInspector.Script} script
*/
addScript: function(script)
{
var splitURL = WebInspector.ParsedURL.splitURLIntoPathComponents(script.sourceURL);
var url = splitURL[splitURL.length - 1];
url = "debugger:///VM" + script.scriptId + (url ? " " + url: "");
var uiSourceCode = this._project.createUISourceCode(url, WebInspector.resourceTypes.Script);
uiSourceCode[WebInspector.DefaultScriptMapping._scriptSymbol] = script;
this._uiSourceCodeForScriptId.set(script.scriptId, uiSourceCode);
this._scriptIdForUISourceCode.set(uiSourceCode, script.scriptId);
this._project.addUISourceCodeWithProvider(uiSourceCode, script);
this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel.target(), uiSourceCode, this);
this._debuggerWorkspaceBinding.pushSourceMapping(script, this);
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
},
_debuggerReset: function()
{
/** @type {!Map.<string, !WebInspector.UISourceCode>} */
this._uiSourceCodeForScriptId = new Map();
this._scriptIdForUISourceCode = new Map();
this._project.reset();
},
dispose: function()
{
this._project.dispose();
}
}
/**
* @param {!WebInspector.Target} target
* @return {string}
*/
WebInspector.DefaultScriptMapping.projectIdForTarget = function(target)
{
return "debugger:" + target.id();
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | 2 1 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.IsolatedFileSystemManager} isolatedFileSystemManager
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.FileSystemWorkspaceBinding = function(isolatedFileSystemManager, workspace)
{
this._isolatedFileSystemManager = isolatedFileSystemManager;
this._workspace = workspace;
this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemFilesChanged, this._fileSystemFilesChanged, this);
/** @type {!Map.<string, !WebInspector.FileSystemWorkspaceBinding.FileSystem>} */
this._boundFileSystems = new Map();
}
WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(["css", "scss", "sass", "less"]);
WebInspector.FileSystemWorkspaceBinding._documentExtensions = new Set(["htm", "html", "asp", "aspx", "phtml", "jsp"]);
WebInspector.FileSystemWorkspaceBinding._scriptExtensions = new Set(["asp", "aspx", "c", "cc", "cljs", "coffee", "cpp", "cs", "dart", "java", "js", "jsp", "jsx", "h", "m", "mm", "py", "sh", "ts", "tsx"]);
WebInspector.FileSystemWorkspaceBinding._imageExtensions = WebInspector.IsolatedFileSystem.ImageExtensions;
/**
* @param {string} fileSystemPath
* @return {string}
*/
WebInspector.FileSystemWorkspaceBinding.projectId = function(fileSystemPath)
{
return fileSystemPath;
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array<string>}
*/
WebInspector.FileSystemWorkspaceBinding.relativePath = function(uiSourceCode)
{
var baseURL = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSystem}*/(uiSourceCode.project())._fileSystemBaseURL;
return uiSourceCode.url().substring(baseURL.length).split("/");
}
/**
* @param {!WebInspector.Project} project
* @param {string} relativePath
* @return {string}
*/
WebInspector.FileSystemWorkspaceBinding.completeURL = function(project, relativePath)
{
var fsProject = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSystem}*/(project);
return fsProject._fileSystemBaseURL + relativePath;
}
/**
* @param {string} extension
* @return {!WebInspector.ResourceType}
*/
WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension = function(extension)
{
if (WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions.has(extension))
return WebInspector.resourceTypes.Stylesheet;
if (WebInspector.FileSystemWorkspaceBinding._documentExtensions.has(extension))
return WebInspector.resourceTypes.Document;
if (WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(extension))
return WebInspector.resourceTypes.Image;
if (WebInspector.FileSystemWorkspaceBinding._scriptExtensions.has(extension))
return WebInspector.resourceTypes.Script;
return WebInspector.resourceTypes.Other;
}
WebInspector.FileSystemWorkspaceBinding.prototype = {
/**
* @return {!WebInspector.IsolatedFileSystemManager}
*/
fileSystemManager: function()
{
return this._isolatedFileSystemManager;
},
/**
* @param {!WebInspector.Event} event
*/
_fileSystemAdded: function(event)
{
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
var boundFileSystem = new WebInspector.FileSystemWorkspaceBinding.FileSystem(this, fileSystem, this._workspace);
this._boundFileSystems.set(fileSystem.path(), boundFileSystem);
},
/**
* @param {!WebInspector.Event} event
*/
_fileSystemRemoved: function(event)
{
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
var boundFileSystem = this._boundFileSystems.get(fileSystem.path());
boundFileSystem.dispose();
this._boundFileSystems.remove(fileSystem.path());
},
/**
* @param {!WebInspector.Event} event
*/
_fileSystemFilesChanged: function(event)
{
var paths = /** @type {!Array<string>} */ (event.data);
for (var path of paths) {
for (var key of this._boundFileSystems.keys()) {
if (!path.startsWith(key))
continue;
this._boundFileSystems.get(key)._fileChanged(path);
}
}
},
/**
* @param {string} projectId
* @return {string}
*/
fileSystemPath: function(projectId)
{
return projectId;
},
dispose: function()
{
this._isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
this._isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
this._isolatedFileSystemManager.dispose();
for (var fileSystem of this._boundFileSystems.values()) {
fileSystem.dispose();
this._boundFileSystems.remove(fileSystem._fileSystem.path());
}
}
}
/**
* @constructor
* @extends {WebInspector.ProjectStore}
* @implements {WebInspector.Project}
* @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
* @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.FileSystemWorkspaceBinding.FileSystem = function(fileSystemWorkspaceBinding, isolatedFileSystem, workspace)
{
this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding;
this._fileSystem = isolatedFileSystem;
this._fileSystemBaseURL = this._fileSystem.path() + "/";
this._fileSystemPath = this._fileSystem.path();
var id = WebInspector.FileSystemWorkspaceBinding.projectId(this._fileSystemPath);
console.assert(!workspace.project(id));
var displayName = this._fileSystemPath.substr(this._fileSystemPath.lastIndexOf("/") + 1);
WebInspector.ProjectStore.call(this, workspace, id, WebInspector.projectTypes.FileSystem, displayName);
workspace.addProject(this);
this.populate();
}
WebInspector.FileSystemWorkspaceBinding.FileSystem.prototype = {
/**
* @return {string}
*/
fileSystemPath: function()
{
return this._fileSystemPath;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
_filePathForUISourceCode: function(uiSourceCode)
{
return uiSourceCode.url().substring(this._fileSystemPath.length);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(?string)} callback
*/
requestFileContent: function(uiSourceCode, callback)
{
var filePath = this._filePathForUISourceCode(uiSourceCode);
var isImage = WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(WebInspector.TextUtils.extension(filePath));
this._fileSystem.requestFileContent(filePath, isImage ? base64CallbackWrapper : callback);
/**
* @param {?string} result
*/
function base64CallbackWrapper(result)
{
if (!result) {
callback(result);
return;
}
var index = result.indexOf(",");
callback(result.substring(index + 1));
}
},
/**
* @override
* @return {boolean}
*/
canSetFileContent: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} newContent
* @param {function(?string)} callback
*/
setFileContent: function(uiSourceCode, newContent, callback)
{
var filePath = this._filePathForUISourceCode(uiSourceCode);
this._fileSystem.setFileContent(filePath, newContent, callback.bind(this, ""));
},
/**
* @override
* @return {boolean}
*/
canRename: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} newName
* @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback
*/
rename: function(uiSourceCode, newName, callback)
{
if (newName === uiSourceCode.name()) {
callback(true, uiSourceCode.name(), uiSourceCode.url(), uiSourceCode.contentType());
return;
}
var filePath = this._filePathForUISourceCode(uiSourceCode);
this._fileSystem.renameFile(filePath, newName, innerCallback.bind(this));
/**
* @param {boolean} success
* @param {string=} newName
* @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(success, newName)
{
if (!success || !newName) {
callback(false, newName);
return;
}
console.assert(newName);
var slash = filePath.lastIndexOf("/");
var parentPath = filePath.substring(0, slash);
filePath = parentPath + "/" + newName;
filePath = filePath.substr(1);
var extension = this._extensionForPath(newName);
var newURL = this._fileSystemBaseURL + filePath;
var newContentType = WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
this.renameUISourceCode(uiSourceCode, newName);
callback(true, newName, newURL, newContentType);
}
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback)
{
var filePath = this._filePathForUISourceCode(uiSourceCode);
this._fileSystem.requestFileContent(filePath, contentCallback);
/**
* @param {?string} content
*/
function contentCallback(content)
{
var result = [];
if (content !== null)
result = WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
callback(result);
}
},
/**
* @override
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!Array.<string>} filesMathingFileQuery
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery, progress, callback)
{
var result = filesMathingFileQuery;
var queriesToRun = searchConfig.queries().slice();
if (!queriesToRun.length)
queriesToRun.push("");
progress.setTotalWork(queriesToRun.length);
searchNextQuery.call(this);
/**
* @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function searchNextQuery()
{
if (!queriesToRun.length) {
progress.done();
callback(result);
return;
}
var query = queriesToRun.shift();
this._fileSystem.searchInPath(searchConfig.isRegex() ? "" : query, progress, innerCallback.bind(this));
}
/**
* @param {!Array.<string>} files
* @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(files)
{
files = files.sort();
progress.worked(1);
result = result.intersectOrdered(files, String.naturalOrderComparator);
searchNextQuery.call(this);
}
},
/**
* @override
* @param {!WebInspector.Progress} progress
*/
indexContent: function(progress)
{
this._fileSystem.indexContent(progress);
},
/**
* @param {string} path
* @return {string}
*/
_extensionForPath: function(path)
{
var extensionIndex = path.lastIndexOf(".");
if (extensionIndex === -1)
return "";
return path.substring(extensionIndex + 1).toLowerCase();
},
populate: function()
{
this._fileSystem.requestFilesRecursive("", this._addFile.bind(this));
},
/**
* @override
* @param {string} path
* @param {function()=} callback
*/
refresh: function(path, callback)
{
this._fileSystem.requestFilesRecursive(path, this._addFile.bind(this), callback);
},
/**
* @override
* @param {string} url
*/
excludeFolder: function(url)
{
var relativeFolder = url.substring(this._fileSystemBaseURL.length);
if (!relativeFolder.startsWith("/"))
relativeFolder = "/" + relativeFolder;
if (!relativeFolder.endsWith("/"))
relativeFolder += "/";
this._fileSystem.addExcludedFolder(relativeFolder);
var uiSourceCodes = this.uiSourceCodes().slice();
for (var i = 0; i < uiSourceCodes.length; ++i) {
var uiSourceCode = uiSourceCodes[i];
if (uiSourceCode.url().startsWith(url))
this.removeUISourceCode(uiSourceCode.url());
}
},
/**
* @override
* @param {string} path
* @param {?string} name
* @param {string} content
* @param {function(?WebInspector.UISourceCode)} callback
*/
createFile: function(path, name, content, callback)
{
this._fileSystem.createFile(path, name, innerCallback.bind(this));
var createFilePath;
/**
* @param {?string} filePath
* @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(filePath)
{
if (!filePath) {
callback(null);
return;
}
createFilePath = filePath;
if (!content) {
contentSet.call(this);
return;
}
this._fileSystem.setFileContent(filePath, content, contentSet.bind(this));
}
/**
* @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function contentSet()
{
callback(this._addFile(createFilePath));
}
},
/**
* @override
* @param {string} path
*/
deleteFile: function(path)
{
this._fileSystem.deleteFile(path);
this.removeUISourceCode(path);
},
/**
* @override
*/
remove: function()
{
this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSystem(this._fileSystem);
},
/**
* @param {string} filePath
* @return {!WebInspector.UISourceCode}
*/
_addFile: function(filePath)
{
if (!filePath)
console.assert(false);
var extension = this._extensionForPath(filePath);
var contentType = WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
var uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + filePath, contentType);
this.addUISourceCode(uiSourceCode);
return uiSourceCode;
},
/**
* @param {string} path
*/
_fileChanged: function(path)
{
var uiSourceCode = this.uiSourceCodeForURL(path);
if (!uiSourceCode) {
var contentType = WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(this._extensionForPath(path));
this.addUISourceCode(this.createUISourceCode(path, contentType));
return;
}
uiSourceCode.checkContentUpdated();
},
dispose: function()
{
this.removeProject();
},
__proto__: WebInspector.ProjectStore.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | 2 1 1 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.OutputStreamDelegate = function() { } WebInspector.OutputStreamDelegate.prototype = { onTransferStarted: function() { }, onTransferFinished: function() { }, /** * @param {!WebInspector.ChunkedReader} reader */ onChunkTransferred: function(reader) { }, /** * @param {!WebInspector.ChunkedReader} reader * @param {!Event} event */ onError: function(reader, event) { }, } /** * @interface */ WebInspector.ChunkedReader = function() { } WebInspector.ChunkedReader.prototype = { /** * @return {number} */ fileSize: function() { }, /** * @return {number} */ loadedSize: function() { }, /** * @return {string} */ fileName: function() { }, cancel: function() { } } /** * @constructor * @implements {WebInspector.ChunkedReader} * @param {!File} file * @param {number} chunkSize * @param {!WebInspector.OutputStreamDelegate} delegate */ WebInspector.ChunkedFileReader = function(file, chunkSize, delegate) { this._file = file; this._fileSize = file.size; this._loadedSize = 0; this._chunkSize = chunkSize; this._delegate = delegate; this._decoder = new TextDecoder(); this._isCanceled = false; } WebInspector.ChunkedFileReader.prototype = { /** * @param {!WebInspector.OutputStream} output */ start: function(output) { this._output = output; this._reader = new FileReader(); this._reader.onload = this._onChunkLoaded.bind(this); this._reader.onerror = this._delegate.onError.bind(this._delegate, this); this._delegate.onTransferStarted(); this._loadChunk(); }, /** * @override */ cancel: function() { this._isCanceled = true; }, /** * @override * @return {number} */ loadedSize: function() { return this._loadedSize; }, /** * @override * @return {number} */ fileSize: function() { return this._fileSize; }, /** * @override * @return {string} */ fileName: function() { return this._file.name; }, /** * @param {!Event} event */ _onChunkLoaded: function(event) { if (this._isCanceled) return; if (event.target.readyState !== FileReader.DONE) return; var buffer = event.target.result; this._loadedSize += buffer.byteLength; var endOfFile = this._loadedSize === this._fileSize; var decodedString = this._decoder.decode(buffer, {stream: !endOfFile}); this._output.write(decodedString); if (this._isCanceled) return; this._delegate.onChunkTransferred(this); if (endOfFile) { this._file = null; this._reader = null; this._output.close(); this._delegate.onTransferFinished(); return; } this._loadChunk(); }, _loadChunk: function() { var chunkStart = this._loadedSize; var chunkEnd = Math.min(this._fileSize, chunkStart + this._chunkSize); var nextPart = this._file.slice(chunkStart, chunkEnd); this._reader.readAsArrayBuffer(nextPart); } } /** * @param {function(!File)} callback * @return {!Node} */ WebInspector.createFileSelectorElement = function(callback) { var fileSelectorElement = createElement("input"); fileSelectorElement.type = "file"; fileSelectorElement.style.display = "none"; fileSelectorElement.setAttribute("tabindex", -1); fileSelectorElement.onchange = onChange; function onChange(event) { callback(fileSelectorElement.files[0]); }; return fileSelectorElement; } /** * @constructor * @implements {WebInspector.OutputStream} */ WebInspector.FileOutputStream = function() { } WebInspector.FileOutputStream.prototype = { /** * @param {string} fileName * @param {function(boolean)} callback */ open: function(fileName, callback) { this._closed = false; this._writeCallbacks = []; this._fileName = fileName; /** * @param {boolean} accepted * @this {WebInspector.FileOutputStream} */ function callbackWrapper(accepted) { if (accepted) WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this); callback(accepted); } WebInspector.fileManager.save(this._fileName, "", true, callbackWrapper.bind(this)); }, /** * @override * @param {string} data * @param {function(!WebInspector.OutputStream)=} callback */ write: function(data, callback) { this._writeCallbacks.push(callback); WebInspector.fileManager.append(this._fileName, data); }, /** * @override */ close: function() { this._closed = true; if (this._writeCallbacks.length) return; WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this); WebInspector.fileManager.close(this._fileName); }, /** * @param {!WebInspector.Event} event */ _onAppendDone: function(event) { if (event.data !== this._fileName) return; var callback = this._writeCallbacks.shift(); if (callback) callback(this); if (!this._writeCallbacks.length) { if (this._closed) { WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this); WebInspector.fileManager.close(this._fileName); } } } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** @interface */ WebInspector.LiveLocation = function() {} WebInspector.LiveLocation.prototype = { update: function() {}, /** * @return {?WebInspector.UILocation} */ uiLocation: function() {}, dispose: function() {}, /** * @return {boolean} */ isBlackboxed: function() {} } /** * @constructor * @implements {WebInspector.LiveLocation} * @param {function(!WebInspector.LiveLocation)} updateDelegate * @param {!WebInspector.LiveLocationPool} locationPool */ WebInspector.LiveLocationWithPool = function(updateDelegate, locationPool) { this._updateDelegate = updateDelegate; this._locationPool = locationPool; this._locationPool._add(this); } WebInspector.LiveLocationWithPool.prototype = { /** * @override */ update: function() { this._updateDelegate(this); }, /** * @override * @return {?WebInspector.UILocation} */ uiLocation: function() { throw "Not implemented"; }, /** * @override */ dispose: function() { this._locationPool._delete(this); this._updateDelegate = null; }, /** * @override * @return {boolean} */ isBlackboxed: function() { throw "Not implemented"; } } /** * @constructor */ WebInspector.LiveLocationPool = function() { this._locations = new Set(); } WebInspector.LiveLocationPool.prototype = { /** * @param {!WebInspector.LiveLocation} location */ _add: function(location) { this._locations.add(location); }, /** * @param {!WebInspector.LiveLocation} location */ _delete: function(location) { this._locations.delete(location); }, disposeAll: function() { for (var location of this._locations) location.dispose(); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
* @param {!WebInspector.FileSystemMapping} fileSystemMapping
*/
WebInspector.NetworkMapping = function(targetManager, workspace, fileSystemWorkspaceBinding, fileSystemMapping)
{
this._targetManager = targetManager;
this._workspace = workspace;
this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding;
this._fileSystemMapping = fileSystemMapping;
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this);
// For now, following block is here primarily for testing since in the real life, network manager is created early enough to capture those events.
var fileSystemManager = fileSystemWorkspaceBinding.fileSystemManager();
for (var path of fileSystemManager.fileSystemPaths()) {
var fileSystem = fileSystemManager.fileSystem(path);
this._fileSystemAdded(new WebInspector.Event(fileSystemManager, WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, fileSystem));
}
if (fileSystemManager.fileSystemsLoaded())
this._fileSystemsLoaded();
fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemsLoaded, this._fileSystemsLoaded, this);
this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded, this._fileSystemMappingChanged, this);
this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved, this._fileSystemMappingChanged, this);
}
WebInspector.NetworkMapping.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_fileSystemAdded: function(event)
{
this._addingFileSystem = true;
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
this._fileSystemMapping.addFileSystem(fileSystem.path());
var mappings = fileSystem.projectProperty("mappings");
for (var i = 0; Array.isArray(mappings) && i < mappings.length; ++i) {
var mapping = mappings[i];
if (!mapping || typeof mapping !== "object")
continue;
var folder = mapping["folder"];
var url = mapping["url"];
if (typeof folder !== "string" || typeof url !== "string")
continue;
this._fileSystemMapping.addNonConfigurableFileMapping(fileSystem.path(), url, folder);
}
this._addingFileSystem = false;
this._fileSystemMappingChanged();
},
/**
* @param {!WebInspector.Event} event
*/
_fileSystemRemoved: function(event)
{
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
this._fileSystemMapping.removeFileSystem(fileSystem.path());
this._fileSystemMappingChanged();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
networkURL: function(uiSourceCode)
{
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var fileSystemPath = this._fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());
return this._networkURLForFileSystemURL(fileSystemPath, uiSourceCode.url());
}
return uiSourceCode.url();
},
/**
* @param {string} url
* @return {boolean}
*/
hasMappingForNetworkURL: function(url)
{
return this._fileSystemMapping.hasMappingForNetworkURL(url);
},
/**
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} url
* @return {?WebInspector.UISourceCode}
*/
_networkUISourceCodeForURL: function(target, frame, url)
{
return this._workspace.uiSourceCode(WebInspector.NetworkProject.projectId(target, frame, false), url);
},
/**
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} url
* @return {?WebInspector.UISourceCode}
*/
_contentScriptUISourceCodeForURL: function(target, frame, url)
{
return this._workspace.uiSourceCode(WebInspector.NetworkProject.projectId(target, frame, true), url);
},
/**
* @param {string} url
* @return {?WebInspector.UISourceCode}
*/
_fileSystemUISourceCodeForURL: function(url)
{
var file = this._fileSystemMapping.fileForURL(url);
if (file) {
var projectId = WebInspector.FileSystemWorkspaceBinding.projectId(file.fileSystemPath);
return this._workspace.uiSourceCode(projectId, file.fileURL);
}
return null;
},
/**
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} url
* @return {?WebInspector.UISourceCode}
*/
_uiSourceCodeForURL: function(target, frame, url)
{
return this._fileSystemUISourceCodeForURL(url) || this._networkUISourceCodeForURL(target, frame, url) || this._contentScriptUISourceCodeForURL(target, frame, url);
},
/**
* @param {string} url
* @param {!WebInspector.Script} script
* @return {?WebInspector.UISourceCode}
*/
uiSourceCodeForScriptURL: function(url, script)
{
var frame = WebInspector.ResourceTreeFrame.fromScript(script);
return this._uiSourceCodeForURL(script.target(), frame, url);
},
/**
* @param {string} url
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {?WebInspector.UISourceCode}
*/
uiSourceCodeForStyleURL: function(url, header)
{
var frame = WebInspector.ResourceTreeFrame.fromStyleSheet(header);
return this._uiSourceCodeForURL(header.target(), frame, url);
},
/**
* @param {string} url
* @return {?WebInspector.UISourceCode}
*/
uiSourceCodeForURLForAnyTarget: function(url)
{
return this._fileSystemUISourceCodeForURL(url) || WebInspector.workspace.uiSourceCodeForURL(url);
},
/**
* @param {string} fileSystemPath
* @param {string} filePath
* @return {string}
*/
_networkURLForFileSystemURL: function(fileSystemPath, filePath)
{
return this._fileSystemMapping.networkURLForFileSystemURL(fileSystemPath, filePath);
},
/**
* @param {!WebInspector.UISourceCode} networkUISourceCode
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
addMapping: function(networkUISourceCode, uiSourceCode)
{
var url = this.networkURL(networkUISourceCode);
var path = uiSourceCode.url();
var fileSystemPath = this._fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());
this._fileSystemMapping.addMappingForResource(url, fileSystemPath, path);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
removeMapping: function(uiSourceCode)
{
var networkURL = this.networkURL(uiSourceCode);
this._fileSystemMapping.removeMappingForURL(networkURL);
},
/**
* @param {!WebInspector.Event} event
*/
_revealSourceLine: function(event)
{
var url = /** @type {string} */ (event.data["url"]);
var lineNumber = /** @type {number} */ (event.data["lineNumber"]);
var columnNumber = /** @type {number} */ (event.data["columnNumber"]);
var uiSourceCode = this.uiSourceCodeForURLForAnyTarget(url);
if (uiSourceCode) {
WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
return;
}
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.NetworkMapping}
*/
function listener(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (this.networkURL(uiSourceCode) === url) {
WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, listener, this);
}
}
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, listener, this);
},
_fileSystemsLoaded: function()
{
this._fileSystemsReady = true;
},
_fileSystemMappingChanged: function()
{
if (!this._fileSystemsReady || this._addingFileSystem)
return;
this._targetManager.suspendAndResumeAllTargets();
},
dispose: function()
{
this._fileSystemWorkspaceBinding.fileSystemManager().removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
this._fileSystemWorkspaceBinding.fileSystemManager().removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
this._fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded, this._fileSystemMappingChanged, this);
this._fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved, this._fileSystemMappingChanged, this);
}
}
/**
* @type {!WebInspector.NetworkMapping}
*/
WebInspector.networkMapping;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | 2 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.NetworkProjectManager = function(targetManager, workspace, networkMapping)
{
this._workspace = workspace;
this._networkMapping = networkMapping;
targetManager.observeTargets(this);
}
WebInspector.NetworkProjectManager.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
new WebInspector.NetworkProject(target, this._workspace, this._networkMapping);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
WebInspector.NetworkProject.forTarget(target)._dispose();
}
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.NetworkProject = function(target, workspace, networkMapping)
{
WebInspector.SDKObject.call(this, target);
this._workspace = workspace;
this._networkMapping = networkMapping;
/** @type {!Map<string, !WebInspector.ContentProviderBasedProject>} */
this._workspaceProjects = new Map();
target[WebInspector.NetworkProject._networkProjectSymbol] = this;
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameWillNavigate, this._frameWillNavigate, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel) {
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel) {
cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
}
target.targetManager().addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
}
WebInspector.NetworkProject._networkProjectSymbol = Symbol("networkProject");
WebInspector.NetworkProject._resourceSymbol = Symbol("resource");
WebInspector.NetworkProject._scriptSymbol = Symbol("script");
WebInspector.NetworkProject._styleSheetSymbol = Symbol("styleSheet");
WebInspector.NetworkProject._targetSymbol = Symbol("target");
WebInspector.NetworkProject._frameSymbol = Symbol("frame");
/**
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {boolean} isContentScripts
* @return {string}
*/
WebInspector.NetworkProject.projectId = function(target, frame, isContentScripts)
{
return target.id() + ":" + (frame ? frame.id : "") + ":" + (isContentScripts ? "contentscripts" : "");
}
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.NetworkProject}
*/
WebInspector.NetworkProject.forTarget = function(target)
{
return target[WebInspector.NetworkProject._networkProjectSymbol];
}
/**
* @param {!WebInspector.Project} project
* @return {?WebInspector.Target} target
*/
WebInspector.NetworkProject.targetForProject = function(project)
{
return project[WebInspector.NetworkProject._targetSymbol] || null;
}
/**
* @param {!WebInspector.Project} project
* @return {?WebInspector.ResourceTreeFrame}
*/
WebInspector.NetworkProject.frameForProject = function(project)
{
return project[WebInspector.NetworkProject._frameSymbol] || null;
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?WebInspector.Target} target
*/
WebInspector.NetworkProject.targetForUISourceCode = function(uiSourceCode)
{
return uiSourceCode[WebInspector.NetworkProject._targetSymbol] || null;
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
WebInspector.NetworkProject.uiSourceCodeMimeType = function(uiSourceCode)
{
if (uiSourceCode[WebInspector.NetworkProject._scriptSymbol] ||
uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol]) {
return uiSourceCode.contentType().canonicalMimeType();
}
var resource = uiSourceCode[WebInspector.NetworkProject._resourceSymbol];
if (resource)
return resource.mimeType;
var mimeType = WebInspector.ResourceType.mimeFromURL(uiSourceCode.url());
return mimeType || uiSourceCode.contentType().canonicalMimeType();
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?WebInspector.ResourceTreeFrame}
*/
WebInspector.NetworkProject.uiSourceCodeFrame = function(uiSourceCode)
{
var target = uiSourceCode[WebInspector.NetworkProject._targetSymbol];
if (!target)
return null;
var frameId;
var script = uiSourceCode[WebInspector.NetworkProject._scriptSymbol];
if (script) {
var executionContext = script.executionContext();
if (executionContext)
frameId = executionContext.frameId;
}
if (!frameId) {
var header = uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol];
if (header)
frameId = header.frameId;
}
if (!frameId) {
var resource = uiSourceCode[WebInspector.NetworkProject._resourceSymbol];
if (resource)
frameId = resource.frameId;
}
return frameId ? target.resourceTreeModel.frameForId(frameId) : null;
}
WebInspector.NetworkProject.prototype = {
/**
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {boolean} isContentScripts
* @return {!WebInspector.ContentProviderBasedProject}
*/
_workspaceProject: function(frame, isContentScripts)
{
var projectId = WebInspector.NetworkProject.projectId(this.target(), frame, isContentScripts);
var projectType = isContentScripts ? WebInspector.projectTypes.ContentScripts : WebInspector.projectTypes.Network;
var project = this._workspaceProjects.get(projectId);
if (project)
return project;
project = new WebInspector.ContentProviderBasedProject(this._workspace, projectId, projectType, "");
project[WebInspector.NetworkProject._targetSymbol] = this.target();
project[WebInspector.NetworkProject._frameSymbol] = frame;
this._workspaceProjects.set(projectId, project);
return project;
},
/**
* @param {string} url
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {!WebInspector.ContentProvider} contentProvider
* @param {boolean=} isContentScript
* @return {?WebInspector.UISourceCode}
*/
addFileForURL: function(url, contentProvider, frame, isContentScript)
{
return this._createFile(url, contentProvider, frame, isContentScript || false, true);
},
/**
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} url
*/
_removeFileForURL: function(frame, url)
{
var project = this._workspaceProjects.get(WebInspector.NetworkProject.projectId(this.target(), frame, false));
if (!project)
return;
project.removeFile(url);
},
_populate: function()
{
/**
* @param {!WebInspector.ResourceTreeFrame} frame
* @this {WebInspector.NetworkProject}
*/
function populateFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);
var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._addResource(resources[i]);
}
var mainFrame = this.target().resourceTreeModel.mainFrame;
if (mainFrame)
populateFrame.call(this, mainFrame);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.ContentProvider} contentProvider
*/
_addUISourceCodeWithProvider: function(uiSourceCode, contentProvider)
{
/** @type {!WebInspector.ContentProviderBasedProject} */ (uiSourceCode.project()).addUISourceCodeWithProvider(uiSourceCode, contentProvider);
},
/**
* @param {!WebInspector.Event} event
*/
_parsedScriptSource: function(event)
{
var script = /** @type {!WebInspector.Script} */ (event.data);
if (!script.sourceURL || script.isLiveEdit() || (script.isInlineScript() && !script.hasSourceURL))
return;
// Filter out embedder injected content scripts.
if (script.isContentScript() && !script.hasSourceURL) {
var parsedURL = new WebInspector.ParsedURL(script.sourceURL);
if (!parsedURL.isValid)
return;
}
var uiSourceCode = this._createFile(script.sourceURL, script, WebInspector.ResourceTreeFrame.fromScript(script), script.isContentScript(), false);
if (uiSourceCode) {
uiSourceCode[WebInspector.NetworkProject._scriptSymbol] = script;
this._addUISourceCodeWithProvider(uiSourceCode, script);
}
},
/**
* @param {!WebInspector.Event} event
*/
_styleSheetAdded: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
if (header.isInline && !header.hasSourceURL && header.origin !== "inspector")
return;
var uiSourceCode = this._createFile(header.resourceURL(), header, WebInspector.ResourceTreeFrame.fromStyleSheet(header), false, false);
if (uiSourceCode) {
uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol] = header;
this._addUISourceCodeWithProvider(uiSourceCode, header);
}
},
/**
* @param {!WebInspector.Event} event
*/
_styleSheetRemoved: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
if (header.isInline && !header.hasSourceURL && header.origin !== "inspector")
return;
this._removeFileForURL(WebInspector.ResourceTreeFrame.fromStyleSheet(header), header.resourceURL());
},
/**
* @param {!WebInspector.Event} event
*/
_resourceAdded: function(event)
{
var resource = /** @type {!WebInspector.Resource} */ (event.data);
this._addResource(resource);
},
/**
* @param {!WebInspector.Resource} resource
*/
_addResource: function(resource)
{
var resourceType = resource.resourceType();
// Only load selected resource types from resources.
if (resourceType !== WebInspector.resourceTypes.Image &&
resourceType !== WebInspector.resourceTypes.Font &&
resourceType !== WebInspector.resourceTypes.Document &&
resourceType !== WebInspector.resourceTypes.Manifest) {
return;
}
// Ignore non-images and non-fonts.
if (resourceType === WebInspector.resourceTypes.Image && resource.mimeType && !resource.mimeType.startsWith("image"))
return;
if (resourceType === WebInspector.resourceTypes.Font && resource.mimeType && !resource.mimeType.includes("font"))
return;
if ((resourceType === WebInspector.resourceTypes.Image || resourceType === WebInspector.resourceTypes.Font) && resource.contentURL().startsWith("data:"))
return;
// Never load document twice.
if (this._workspace.uiSourceCodeForURL(resource.url))
return;
var uiSourceCode = this._createFile(resource.url, resource, WebInspector.ResourceTreeFrame.fromResource(resource), false, false);
if (uiSourceCode) {
uiSourceCode[WebInspector.NetworkProject._resourceSymbol] = resource;
this._addUISourceCodeWithProvider(uiSourceCode, resource);
}
},
/**
* @param {!WebInspector.Event} event
*/
_frameWillNavigate: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
var project = this._workspaceProject(frame, false);
for (var resource of frame.resources())
project.removeUISourceCode(resource.url);
project = this._workspaceProject(frame, true);
for (var resource of frame.resources())
project.removeUISourceCode(resource.url);
},
/**
* @param {!WebInspector.Event} event
*/
_mainFrameNavigated: function(event)
{
this._reset();
this._populate();
},
_suspendStateChanged: function()
{
if (this.target().targetManager().allTargetsSuspended())
this._reset();
else
this._populate();
},
/**
* @param {string} url
* @param {!WebInspector.ContentProvider} contentProvider
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {boolean} isContentScript
* @param {boolean} addIntoProject
* @return {?WebInspector.UISourceCode}
*/
_createFile: function(url, contentProvider, frame, isContentScript, addIntoProject)
{
if (this._networkMapping.hasMappingForNetworkURL(url))
return null;
var project = this._workspaceProject(frame, isContentScript);
var uiSourceCode = project.createUISourceCode(url, contentProvider.contentType());
uiSourceCode[WebInspector.NetworkProject._targetSymbol] = this.target();
if (addIntoProject)
project.addUISourceCodeWithProvider(uiSourceCode, contentProvider);
return uiSourceCode;
},
_dispose: function()
{
this._reset();
var target = this.target();
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel) {
debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel) {
cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
}
delete target[WebInspector.NetworkProject._networkProjectSymbol];
},
_reset: function()
{
for (var project of this._workspaceProjects.values())
project.reset();
this._workspaceProjects.clear();
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.PresentationConsoleMessageHelper = function(workspace)
{
this._workspace = workspace;
/** @type {!Object.<string, !Array.<!WebInspector.ConsoleMessage>>} */
this._pendingConsoleMessages = {};
/** @type {!Array.<!WebInspector.PresentationConsoleMessage>} */
this._presentationConsoleMessages = [];
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
WebInspector.multitargetConsoleModel.messages().forEach(this._consoleMessageAdded, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._locationPool = new WebInspector.LiveLocationPool();
}
WebInspector.PresentationConsoleMessageHelper.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_onConsoleMessageAdded: function(event)
{
var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
this._consoleMessageAdded(message);
},
/**
* @param {!WebInspector.ConsoleMessage} message
*/
_consoleMessageAdded: function(message)
{
if (!message.url || !message.isErrorOrWarning())
return;
var rawLocation = this._rawLocation(message);
if (rawLocation)
this._addConsoleMessageToScript(message, rawLocation);
else
this._addPendingConsoleMessage(message);
},
/**
* @param {!WebInspector.ConsoleMessage} message
* @return {?WebInspector.DebuggerModel.Location}
*/
_rawLocation: function(message)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(message.target());
if (!debuggerModel)
return null;
var callFrame = message.stackTrace && message.stackTrace.callFrames ? message.stackTrace.callFrames[0] : null;
// FIXME(62725): stack trace line/column numbers are one-based.
var lineNumber = callFrame ? callFrame.lineNumber - 1 : message.line - 1;
var columnNumber = message.column ? message.column - 1 : 0;
if (callFrame && callFrame.columnNumber)
columnNumber = callFrame.columnNumber - 1;
if (message.scriptId)
return debuggerModel.createRawLocationByScriptId(message.scriptId, lineNumber, columnNumber);
return debuggerModel.createRawLocationByURL(message.url || "", lineNumber, columnNumber);
},
/**
* @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.DebuggerModel.Location} rawLocation
*/
_addConsoleMessageToScript: function(message, rawLocation)
{
this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation, this._locationPool));
},
/**
* @param {!WebInspector.ConsoleMessage} message
*/
_addPendingConsoleMessage: function(message)
{
if (!message.url)
return;
if (!this._pendingConsoleMessages[message.url])
this._pendingConsoleMessages[message.url] = [];
this._pendingConsoleMessages[message.url].push(message);
},
/**
* @param {!WebInspector.Event} event
*/
_parsedScriptSource: function(event)
{
var script = /** @type {!WebInspector.Script} */ (event.data);
var messages = this._pendingConsoleMessages[script.sourceURL];
if (!messages)
return;
var pendingMessages = [];
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
var rawLocation = this._rawLocation(message);
if (!rawLocation)
continue;
if (script.target() === message.target() && script.scriptId === rawLocation.scriptId)
this._addConsoleMessageToScript(message, rawLocation);
else
pendingMessages.push(message);
}
if (pendingMessages.length)
this._pendingConsoleMessages[script.sourceURL] = pendingMessages;
else
delete this._pendingConsoleMessages[script.sourceURL];
},
_consoleCleared: function()
{
this._pendingConsoleMessages = {};
for (var i = 0; i < this._presentationConsoleMessages.length; ++i)
this._presentationConsoleMessages[i].dispose();
this._presentationConsoleMessages = [];
this._locationPool.disposeAll();
},
_debuggerReset: function()
{
this._consoleCleared();
}
}
/**
* @constructor
* @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {!WebInspector.LiveLocationPool} locationPool
*/
WebInspector.PresentationConsoleMessage = function(message, rawLocation, locationPool)
{
this._text = message.messageText;
this._level = message.level === WebInspector.ConsoleMessage.MessageLevel.Error ? WebInspector.UISourceCode.Message.Level.Error : WebInspector.UISourceCode.Message.Level.Warning;
WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this), locationPool);
}
WebInspector.PresentationConsoleMessage.prototype = {
/**
* @param {!WebInspector.LiveLocation} liveLocation
*/
_updateLocation: function(liveLocation)
{
if (this._uiMessage)
this._uiMessage.remove();
var uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
this._uiMessage = uiLocation.uiSourceCode.addLineMessage(this._level, this._text, uiLocation.lineNumber, uiLocation.columnNumber);
},
dispose: function()
{
if (this._uiMessage)
this._uiMessage.remove();
}
}
/** @type {!WebInspector.PresentationConsoleMessageHelper} */
WebInspector.presentationConsoleMessageHelper;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.DebuggerSourceMapping}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
* @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
*/
WebInspector.ResourceScriptMapping = function(debuggerModel, workspace, networkMapping, debuggerWorkspaceBinding)
{
this._target = debuggerModel.target();
this._debuggerModel = debuggerModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
this._networkMapping = networkMapping;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
/** @type {!Array.<!WebInspector.UISourceCode>} */
this._boundUISourceCodes = [];
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.ResourceScriptFile>} */
this._uiSourceCodeToScriptFile = new Map();
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}
WebInspector.ResourceScriptMapping.prototype = {
/**
* @override
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
var script = debuggerModelLocation.script();
var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return null;
var scriptFile = this.scriptFile(uiSourceCode);
if (scriptFile && ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM()))
return null;
var lineNumber = debuggerModelLocation.lineNumber - (script.isInlineScriptWithSourceURL() ? script.lineOffset : 0);
var columnNumber = debuggerModelLocation.columnNumber || 0;
if (script.isInlineScriptWithSourceURL() && !lineNumber && columnNumber)
columnNumber -= script.columnOffset;
return uiSourceCode.uiLocation(lineNumber, columnNumber);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
console.assert(scripts.length);
var script = scripts[0];
if (script.isInlineScriptWithSourceURL())
return this._debuggerModel.createRawLocation(script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
/**
* @param {!WebInspector.Script} script
*/
addScript: function(script)
{
if (script.isAnonymousScript())
return;
this._debuggerWorkspaceBinding.pushSourceMapping(script, this);
var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return;
this._bindUISourceCodeToScripts(uiSourceCode, [script]);
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?WebInspector.ResourceScriptFile}
*/
scriptFile: function(uiSourceCode)
{
return this._uiSourceCodeToScriptFile.get(uiSourceCode) || null;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?WebInspector.ResourceScriptFile} scriptFile
*/
_setScriptFile: function(uiSourceCode, scriptFile)
{
if (scriptFile)
this._uiSourceCodeToScriptFile.set(uiSourceCode, scriptFile);
else
this._uiSourceCodeToScriptFile.remove(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (!this._networkMapping.networkURL(uiSourceCode))
return;
if (uiSourceCode.isFromServiceProject())
return;
var scripts = this._scriptsForUISourceCode(uiSourceCode);
if (!scripts.length)
return;
this._bindUISourceCodeToScripts(uiSourceCode, scripts);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (!this._networkMapping.networkURL(uiSourceCode))
return;
if (uiSourceCode.isFromServiceProject())
return;
this._unbindUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_updateLocations: function(uiSourceCode)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
if (!scripts.length)
return;
for (var i = 0; i < scripts.length; ++i)
this._debuggerWorkspaceBinding.updateLocations(scripts[i]);
},
/**
* @param {!WebInspector.Script} script
* @return {?WebInspector.UISourceCode}
*/
_workspaceUISourceCodeForScript: function(script)
{
if (script.isAnonymousScript())
return null;
return this._networkMapping.uiSourceCodeForScriptURL(script.sourceURL, script);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array.<!WebInspector.Script>}
*/
_scriptsForUISourceCode: function(uiSourceCode)
{
var target = WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);
if (target && target !== this._debuggerModel.target())
return [];
if (!this._networkMapping.networkURL(uiSourceCode))
return [];
return this._debuggerModel.scriptsForSourceURL(this._networkMapping.networkURL(uiSourceCode));
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!Array.<!WebInspector.Script>} scripts
*/
_bindUISourceCodeToScripts: function(uiSourceCode, scripts)
{
console.assert(scripts.length);
// Due to different listeners order, a script file could be created just before uiSourceCode
// for the corresponding script was created. Check that we don't create scriptFile twice.
var boundScriptFile = this.scriptFile(uiSourceCode);
if (boundScriptFile && boundScriptFile._hasScripts(scripts))
return;
var scriptFile = new WebInspector.ResourceScriptFile(this, uiSourceCode, scripts);
this._setScriptFile(uiSourceCode, scriptFile);
for (var i = 0; i < scripts.length; ++i)
this._debuggerWorkspaceBinding.updateLocations(scripts[i]);
this._debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, this);
this._boundUISourceCodes.push(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_unbindUISourceCode: function(uiSourceCode)
{
var scriptFile = this.scriptFile(uiSourceCode);
if (scriptFile) {
scriptFile.dispose();
this._setScriptFile(uiSourceCode, null);
}
this._debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, null);
this._boundUISourceCodes.remove(uiSourceCode);
},
_debuggerReset: function()
{
var sourceCodes = this._boundUISourceCodes;
this._boundUISourceCodes = [];
sourceCodes.forEach(this._unbindUISourceCode.bind(this));
console.assert(!this._uiSourceCodeToScriptFile.size);
},
dispose: function()
{
this._debuggerReset();
this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
}
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.ResourceScriptMapping} resourceScriptMapping
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!Array.<!WebInspector.Script>} scripts
*/
WebInspector.ResourceScriptFile = function(resourceScriptMapping, uiSourceCode, scripts)
{
console.assert(scripts.length);
this._resourceScriptMapping = resourceScriptMapping;
this._uiSourceCode = uiSourceCode;
this._uiSourceCode.forceLoadOnCheckContent();
if (this._uiSourceCode.contentType().isScript())
this._script = scripts[0];
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
}
WebInspector.ResourceScriptFile.Events = {
DidMergeToVM: "DidMergeToVM",
DidDivergeFromVM: "DidDivergeFromVM",
}
WebInspector.ResourceScriptFile.prototype = {
/**
* @param {!Array.<!WebInspector.Script>} scripts
* @return {boolean}
*/
_hasScripts: function(scripts)
{
return this._script && this._script === scripts[0];
},
/**
* @return {boolean}
*/
_isDiverged: function()
{
if (this._uiSourceCode.isDirty())
return true;
if (!this._script)
return false;
if (typeof this._scriptSource === "undefined")
return false;
if (!this._uiSourceCode.workingCopy().startsWith(this._scriptSource.trimRight()))
return true;
var suffix = this._uiSourceCode.workingCopy().substr(this._scriptSource.length);
return !!suffix.length && !suffix.match(WebInspector.Script.sourceURLRegex);
},
/**
* @param {!WebInspector.Event} event
*/
_workingCopyChanged: function(event)
{
this._update();
},
_workingCopyCommitted: function(event)
{
if (this._uiSourceCode.project().type() === WebInspector.projectTypes.Snippets)
return;
if (!this._script)
return;
var debuggerModel = this._resourceScriptMapping._debuggerModel;
var source = this._uiSourceCode.workingCopy();
debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
/**
* @param {?string} error
* @param {!DebuggerAgent.SetScriptSourceError=} errorData
* @this {WebInspector.ResourceScriptFile}
*/
function scriptSourceWasSet(error, errorData)
{
if (!error && !errorData)
this._scriptSource = source;
this._update();
if (!error && !errorData)
return;
var warningLevel = WebInspector.Console.MessageLevel.Warning;
if (!errorData) {
WebInspector.console.addMessage(WebInspector.UIString("LiveEdit failed: %s", error), warningLevel);
return;
}
if (errorData) {
var messageText = WebInspector.UIString("LiveEdit compile failed: %s", errorData.message);
this._uiSourceCode.addLineMessage(WebInspector.UISourceCode.Message.Level.Error, messageText, errorData.lineNumber - 1, errorData.columnNumber + 1);
} else {
WebInspector.console.addMessage(WebInspector.UIString("Unknown LiveEdit error: %s; %s", JSON.stringify(errorData), error), warningLevel);
}
}
},
_update: function()
{
if (this._isDiverged() && !this._hasDivergedFromVM)
this._divergeFromVM();
else if (!this._isDiverged() && this._hasDivergedFromVM)
this._mergeToVM();
},
_divergeFromVM: function()
{
this._isDivergingFromVM = true;
this._resourceScriptMapping._updateLocations(this._uiSourceCode);
delete this._isDivergingFromVM;
this._hasDivergedFromVM = true;
this.dispatchEventToListeners(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM, this._uiSourceCode);
},
_mergeToVM: function()
{
delete this._hasDivergedFromVM;
this._isMergingToVM = true;
this._resourceScriptMapping._updateLocations(this._uiSourceCode);
delete this._isMergingToVM;
this.dispatchEventToListeners(WebInspector.ResourceScriptFile.Events.DidMergeToVM, this._uiSourceCode);
},
/**
* @return {boolean}
*/
hasDivergedFromVM: function()
{
return this._hasDivergedFromVM;
},
/**
* @return {boolean}
*/
isDivergingFromVM: function()
{
return this._isDivergingFromVM;
},
/**
* @return {boolean}
*/
isMergingToVM: function()
{
return this._isMergingToVM;
},
checkMapping: function()
{
if (!this._script || typeof this._scriptSource !== "undefined") {
this._mappingCheckedForTest();
return;
}
this._script.requestContent().then(callback.bind(this));
/**
* @param {?string} source
* @this {WebInspector.ResourceScriptFile}
*/
function callback(source)
{
this._scriptSource = source;
this._update();
this._mappingCheckedForTest();
}
},
_mappingCheckedForTest: function() { },
/**
* @return {?WebInspector.Target}
*/
target: function()
{
if (!this._script)
return null;
return this._script.target();
},
dispose: function()
{
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
},
/**
* @param {string} sourceMapURL
*/
addSourceMapURL: function(sourceMapURL)
{
if (!this._script)
return;
this._script.addSourceMapURL(sourceMapURL);
},
/**
* @return {boolean}
*/
hasSourceMapURL: function()
{
return this._script && !!this._script.sourceMapURL;
},
__proto__: WebInspector.Object.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 2 | /*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @param {string} url
* @return {?WebInspector.Resource}
*/
WebInspector.resourceForURL = function(url)
{
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i) {
var resource = targets[i].resourceTreeModel.resourceForURL(url);
if (resource)
return resource;
}
return null;
}
/**
* @param {function(!WebInspector.Resource)} callback
*/
WebInspector.forAllResources = function(callback)
{
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i)
targets[i].resourceTreeModel.forAllResources(callback);
}
/**
* @param {string} url
* @return {string}
*/
WebInspector.displayNameForURL = function(url)
{
if (!url)
return "";
var resource = WebInspector.resourceForURL(url);
if (resource)
return resource.displayName;
var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);
if (uiSourceCode)
return uiSourceCode.displayName();
if (!WebInspector.targetManager.inspectedPageURL())
return url.trimURL("");
var parsedURL = WebInspector.targetManager.inspectedPageURL().asParsedURL();
var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
var index = WebInspector.targetManager.inspectedPageURL().indexOf(lastPathComponent);
if (index !== -1 && index + lastPathComponent.length === WebInspector.targetManager.inspectedPageURL().length) {
var baseURL = WebInspector.targetManager.inspectedPageURL().substring(0, index);
if (url.startsWith(baseURL))
return url.substring(index);
}
if (!parsedURL)
return url;
var displayName = url.trimURL(parsedURL.host);
return displayName === "/" ? parsedURL.host + "/" : displayName;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.CSSSourceMapping}
* @param {!WebInspector.CSSModel} cssModel
* @param {!WebInspector.NetworkMapping} networkMapping
* @param {!WebInspector.NetworkProject} networkProject
*/
WebInspector.SASSSourceMapping = function(cssModel, networkMapping, networkProject)
{
this._cssModel = cssModel;
this._networkProject = networkProject;
this._networkMapping = networkMapping;
this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapAttached, this._sourceMapAttached, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapDetached, this._sourceMapDetached, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapChanged, this._sourceMapChanged, this);
}
WebInspector.SASSSourceMapping.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_sourceMapAttached: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
var sourceMap = this._cssModel.sourceMapForHeader(header);
for (var sassURL of sourceMap.sourceURLs()) {
if (!this._networkMapping.hasMappingForNetworkURL(sassURL)) {
var contentProvider = sourceMap.sourceContentProvider(sassURL, WebInspector.resourceTypes.SourceMapStyleSheet);
this._networkProject.addFileForURL(sassURL, contentProvider, WebInspector.ResourceTreeFrame.fromStyleSheet(header));
}
}
WebInspector.cssWorkspaceBinding.updateLocations(header);
},
/**
* @param {!WebInspector.Event} event
*/
_sourceMapDetached: function(event)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */(event.data);
WebInspector.cssWorkspaceBinding.updateLocations(header);
},
/**
* @param {!WebInspector.Event} event
*/
_sourceMapChanged: function(event)
{
var sourceMap = /** @type {!WebInspector.SourceMap} */(event.data.sourceMap);
var newSources = /** @type {!Map<string, string>} */(event.data.newSources);
var headers = this._cssModel.headersForSourceMap(sourceMap);
var handledUISourceCodes = new Set();
for (var header of headers) {
WebInspector.cssWorkspaceBinding.updateLocations(header);
for (var sourceURL of newSources.keys()) {
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(sourceURL, header);
if (!uiSourceCode) {
console.error("Failed to update source for " + sourceURL);
continue;
}
if (handledUISourceCodes.has(uiSourceCode))
continue;
handledUISourceCodes.add(uiSourceCode);
var sassText = /** @type {string} */(newSources.get(sourceURL));
uiSourceCode.addRevision(sassText);
}
}
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
addHeader: function(header)
{
if (!header.sourceMapURL)
return;
WebInspector.cssWorkspaceBinding.pushSourceMapping(header, this);
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
removeHeader: function(header)
{
if (!header.sourceMapURL)
return;
WebInspector.cssWorkspaceBinding.updateLocations(header);
},
/**
* @override
* @param {!WebInspector.CSSLocation} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var sourceMap = this._cssModel.sourceMapForHeader(rawLocation.header());
if (!sourceMap)
return null;
var entry = sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber);
if (!entry || !entry.sourceURL)
return null;
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(entry.sourceURL, rawLocation.header());
if (!uiSourceCode)
return null;
return uiSourceCode.uiLocation(entry.sourceLineNumber || 0, entry.sourceColumnNumber);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.CSSLocation}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return null;
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._cssModel.target();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.CSSSourceMapping}
* @param {!WebInspector.CSSModel} cssModel
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.NetworkMapping} networkMapping
*/
WebInspector.StylesSourceMapping = function(cssModel, workspace, networkMapping)
{
this._cssModel = cssModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
this._networkMapping = networkMapping;
cssModel.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._unbindAllUISourceCodes, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
/** @type {!Map<string, !Map<string, !Map<string, !WebInspector.CSSStyleSheetHeader>>>} */
this._urlToHeadersByFrameId = new Map();
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.StyleFile>} */
this._styleFiles = new Map();
}
WebInspector.StylesSourceMapping.ChangeUpdateTimeoutMs = 200;
WebInspector.StylesSourceMapping.prototype = {
/**
* @override
* @param {!WebInspector.CSSLocation} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(rawLocation.url, rawLocation.header());
if (!uiSourceCode)
return null;
var lineNumber = rawLocation.lineNumber;
var columnNumber = rawLocation.columnNumber;
var header = this._cssModel.styleSheetHeaderForId(rawLocation.styleSheetId);
if (header && header.isInline && header.hasSourceURL) {
lineNumber -= header.lineNumberInSource(0);
columnNumber -= header.columnNumberInSource(lineNumber, 0);
}
return uiSourceCode.uiLocation(lineNumber, columnNumber);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.CSSLocation}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return null;
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._cssModel.target();
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
addHeader: function(header)
{
var url = header.resourceURL();
if (!url)
return;
WebInspector.cssWorkspaceBinding.pushSourceMapping(header, this);
var map = this._urlToHeadersByFrameId.get(url);
if (!map) {
map = /** @type {!Map.<string, !Map.<string, !WebInspector.CSSStyleSheetHeader>>} */ (new Map());
this._urlToHeadersByFrameId.set(url, map);
}
var headersById = map.get(header.frameId);
if (!headersById) {
headersById = /** @type {!Map.<string, !WebInspector.CSSStyleSheetHeader>} */ (new Map());
map.set(header.frameId, headersById);
}
headersById.set(header.id, header);
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(url, header);
if (uiSourceCode)
this._bindUISourceCode(uiSourceCode, header);
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
removeHeader: function(header)
{
var url = header.resourceURL();
if (!url)
return;
var map = this._urlToHeadersByFrameId.get(url);
console.assert(map);
var headersById = map.get(header.frameId);
console.assert(headersById);
headersById.delete(header.id);
if (!headersById.size) {
map.delete(header.frameId);
if (!map.size) {
this._urlToHeadersByFrameId.delete(url);
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(url, header);
if (uiSourceCode)
this._unbindUISourceCode(uiSourceCode);
}
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_unbindUISourceCode: function(uiSourceCode)
{
var styleFile = this._styleFiles.get(uiSourceCode);
if (!styleFile)
return;
styleFile.dispose();
this._styleFiles.delete(uiSourceCode);
},
_unbindAllUISourceCodes: function()
{
for (var styleFile of this._styleFiles.values())
styleFile.dispose();
this._styleFiles.clear();
this._urlToHeadersByFrameId = new Map();
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (!networkURL || !this._urlToHeadersByFrameId.has(networkURL))
return;
this._bindUISourceCode(uiSourceCode, this._urlToHeadersByFrameId.get(networkURL).valuesArray()[0].valuesArray()[0]);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
_bindUISourceCode: function(uiSourceCode, header)
{
if (this._styleFiles.get(uiSourceCode) || (header.isInline && !header.hasSourceURL))
return;
this._styleFiles.set(uiSourceCode, new WebInspector.StyleFile(uiSourceCode, this));
WebInspector.cssWorkspaceBinding.updateLocations(header);
},
/**
* @param {!WebInspector.Event} event
*/
_projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
this._unbindUISourceCode(uiSourceCodes[i]);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._unbindUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} content
* @param {boolean} majorChange
* @return {!Promise<?string>}
*/
_setStyleContent: function(uiSourceCode, content, majorChange)
{
var networkURL = this._networkMapping.networkURL(uiSourceCode);
var styleSheetIds = this._cssModel.styleSheetIdsForURL(networkURL);
if (!styleSheetIds.length)
return Promise.resolve(/** @type {?string} */("No stylesheet found: " + networkURL));
this._isSettingContent = true;
/**
* @param {?string} error
* @this {WebInspector.StylesSourceMapping}
* @return {?string}
*/
function callback(error)
{
delete this._isSettingContent;
return error || null;
}
var promises = [];
for (var i = 0; i < styleSheetIds.length; ++i)
promises.push(this._cssModel.setStyleSheetText(styleSheetIds[i], content, majorChange));
return Promise.all(promises).spread(callback.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_styleSheetChanged: function(event)
{
if (this._isSettingContent)
return;
this._updateStyleSheetTextSoon(event.data.styleSheetId);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
*/
_updateStyleSheetTextSoon: function(styleSheetId)
{
if (this._updateStyleSheetTextTimer)
clearTimeout(this._updateStyleSheetTextTimer);
this._updateStyleSheetTextTimer = setTimeout(this._updateStyleSheetText.bind(this, styleSheetId), WebInspector.StylesSourceMapping.ChangeUpdateTimeoutMs);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
*/
_updateStyleSheetText: function(styleSheetId)
{
if (this._updateStyleSheetTextTimer) {
clearTimeout(this._updateStyleSheetTextTimer);
delete this._updateStyleSheetTextTimer;
}
var header = this._cssModel.styleSheetHeaderForId(styleSheetId);
if (!header)
return;
var styleSheetURL = header.resourceURL();
if (!styleSheetURL)
return;
var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(styleSheetURL, header);
if (!uiSourceCode)
return;
header.requestContent().then(callback.bind(this, uiSourceCode));
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?string} content
* @this {WebInspector.StylesSourceMapping}
*/
function callback(uiSourceCode, content)
{
var styleFile = this._styleFiles.get(uiSourceCode);
if (styleFile)
styleFile.addRevision(content || "");
}
}
}
/**
* @constructor
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.StylesSourceMapping} mapping
*/
WebInspector.StyleFile = function(uiSourceCode, mapping)
{
this._uiSourceCode = uiSourceCode;
this._mapping = mapping;
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.forceLoadOnCheckContent();
this._commitThrottler = new WebInspector.Throttler(WebInspector.StyleFile.updateTimeout);
}
WebInspector.StyleFile.updateTimeout = 200;
WebInspector.StyleFile.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_workingCopyCommitted: function(event)
{
if (this._isAddingRevision)
return;
this._isMajorChangePending = true;
this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), true);
},
/**
* @param {!WebInspector.Event} event
*/
_workingCopyChanged: function(event)
{
if (this._isAddingRevision)
return;
this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), false);
},
_commitIncrementalEdit: function()
{
var promise = this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.workingCopy(), this._isMajorChangePending)
.then(this._styleContentSet.bind(this))
this._isMajorChangePending = false;
return promise;
},
/**
* @param {?string} error
*/
_styleContentSet: function(error)
{
if (error)
WebInspector.console.error(error);
},
/**
* @param {string} content
*/
addRevision: function(content)
{
this._isAddingRevision = true;
this._uiSourceCode.addRevision(content);
delete this._isAddingRevision;
},
dispose: function()
{
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; /** * @constructor */ WebInspector.TempFile = function() { this._fileEntry = null; this._writer = null; } /** * @param {string} dirPath * @param {string} name * @return {!Promise.<!WebInspector.TempFile>} */ WebInspector.TempFile.create = function(dirPath, name) { var file = new WebInspector.TempFile(); function requestTempFileSystem() { return new Promise(window.requestFileSystem.bind(window, window.TEMPORARY, 10)); } /** * @param {!FileSystem} fs */ function getDirectoryEntry(fs) { return new Promise(fs.root.getDirectory.bind(fs.root, dirPath, { create: true })); } /** * @param {!DirectoryEntry} dir */ function getFileEntry(dir) { return new Promise(dir.getFile.bind(dir, name, { create: true })); } /** * @param {!FileEntry} fileEntry */ function createFileWriter(fileEntry) { file._fileEntry = fileEntry; return new Promise(fileEntry.createWriter.bind(fileEntry)); } /** * @param {!FileWriter} writer */ function truncateFile(writer) { if (!writer.length) { file._writer = writer; return Promise.resolve(file); } /** * @param {function(?)} fulfill * @param {function(*)} reject */ function truncate(fulfill, reject) { writer.onwriteend = fulfill; writer.onerror = reject; writer.truncate(0); } function didTruncate() { file._writer = writer; writer.onwriteend = null; writer.onerror = null; return Promise.resolve(file); } function onTruncateError(e) { writer.onwriteend = null; writer.onerror = null; throw e; } return new Promise(truncate).then(didTruncate, onTruncateError); } return WebInspector.TempFile.ensureTempStorageCleared() .then(requestTempFileSystem) .then(getDirectoryEntry) .then(getFileEntry) .then(createFileWriter) .then(truncateFile); } WebInspector.TempFile.prototype = { /** * @param {!Array.<string>} strings * @param {function(number)} callback */ write: function(strings, callback) { var blob = new Blob(strings, {type: 'text/plain'}); this._writer.onerror = function(e) { WebInspector.console.error("Failed to write into a temp file: " + e.target.error.message); callback(-1); } this._writer.onwriteend = function(e) { callback(e.target.length); } this._writer.write(blob); }, finishWriting: function() { this._writer = null; }, /** * @param {function(?string)} callback */ read: function(callback) { this.readRange(undefined, undefined, callback); }, /** * @param {number|undefined} startOffset * @param {number|undefined} endOffset * @param {function(?string)} callback */ readRange: function(startOffset, endOffset, callback) { /** * @param {!Blob} file */ function didGetFile(file) { var reader = new FileReader(); if (typeof startOffset === "number" || typeof endOffset === "number") file = file.slice(/** @type {number} */ (startOffset), /** @type {number} */ (endOffset)); /** * @this {FileReader} */ reader.onloadend = function(e) { callback(/** @type {?string} */ (this.result)); }; reader.onerror = function(error) { WebInspector.console.error("Failed to read from temp file: " + error.message); }; reader.readAsText(file); } function didFailToGetFile(error) { WebInspector.console.error("Failed to load temp file: " + error.message); callback(null); } this._fileEntry.file(didGetFile, didFailToGetFile); }, /** * @param {!WebInspector.OutputStream} outputStream * @param {!WebInspector.OutputStreamDelegate} delegate */ copyToOutputStream: function(outputStream, delegate) { /** * @param {!File} file */ function didGetFile(file) { var reader = new WebInspector.ChunkedFileReader(file, 10*1000*1000, delegate); reader.start(outputStream); } function didFailToGetFile(error) { WebInspector.console.error("Failed to load temp file: " + error.message); outputStream.close(); } this._fileEntry.file(didGetFile, didFailToGetFile); }, remove: function() { if (this._fileEntry) this._fileEntry.remove(function() {}); } } /** * @constructor * @param {string} dirPath * @param {string} name */ WebInspector.DeferredTempFile = function(dirPath, name) { /** @type {!Array.<!{strings: !Array.<string>, callback: ?function(number)}>} */ this._chunks = []; this._tempFile = null; this._isWriting = false; this._finishCallback = null; this._finishedWriting = false; this._callsPendingOpen = []; this._pendingReads = []; WebInspector.TempFile.create(dirPath, name) .then(this._didCreateTempFile.bind(this), this._failedToCreateTempFile.bind(this)); } WebInspector.DeferredTempFile.prototype = { /** * @param {!Array.<string>} strings * @param {function(number)=} callback */ write: function(strings, callback) { if (this._finishCallback) throw new Error("No writes are allowed after close."); this._chunks.push({strings: strings, callback: callback || null}); if (this._tempFile && !this._isWriting) this._writeNextChunk(); }, /** * @param {function(?WebInspector.TempFile)} callback */ finishWriting: function(callback) { this._finishCallback = callback; if (this._finishedWriting) callback(this._tempFile); else if (!this._isWriting && !this._chunks.length) this._notifyFinished(); }, /** * @param {*} e */ _failedToCreateTempFile: function(e) { WebInspector.console.error("Failed to create temp file " + e.code + " : " + e.message); this._notifyFinished(); }, /** * @param {!WebInspector.TempFile} tempFile */ _didCreateTempFile: function(tempFile) { this._tempFile = tempFile; var callsPendingOpen = this._callsPendingOpen; this._callsPendingOpen = null; for (var i = 0; i < callsPendingOpen.length; ++i) callsPendingOpen[i](); if (this._chunks.length) this._writeNextChunk(); }, _writeNextChunk: function() { // File was deleted while create or write was in-flight. if (!this._tempFile) return; var chunk = this._chunks.shift(); this._isWriting = true; this._tempFile.write(/** @type {!Array.<string>} */(chunk.strings), this._didWriteChunk.bind(this, chunk.callback)); }, /** * @param {?function(number)} callback * @param {number} size */ _didWriteChunk: function(callback, size) { this._isWriting = false; if (size === -1) { this._tempFile = null; this._notifyFinished(); return; } if (callback) callback(size); if (this._chunks.length) this._writeNextChunk(); else if (this._finishCallback) this._notifyFinished(); }, _notifyFinished: function() { this._finishedWriting = true; if (this._tempFile) this._tempFile.finishWriting(); var chunks = this._chunks; this._chunks = []; for (var i = 0; i < chunks.length; ++i) { if (chunks[i].callback) chunks[i].callback(-1); } if (this._finishCallback) this._finishCallback(this._tempFile); var pendingReads = this._pendingReads; this._pendingReads = []; for (var i = 0; i < pendingReads.length; ++i) pendingReads[i](); }, /** * @param {number|undefined} startOffset * @param {number|undefined} endOffset * @param {function(string?)} callback */ readRange: function(startOffset, endOffset, callback) { if (!this._finishedWriting) { this._pendingReads.push(this.readRange.bind(this, startOffset, endOffset, callback)); return; } if (!this._tempFile) { callback(null); return; } this._tempFile.readRange(startOffset, endOffset, callback); }, /** * @param {!WebInspector.OutputStream} outputStream * @param {!WebInspector.OutputStreamDelegate} delegate */ copyToOutputStream: function(outputStream, delegate) { if (!this._finishedWriting) { this._pendingReads.push(this.copyToOutputStream.bind(this, outputStream, delegate)); return; } if (this._tempFile) this._tempFile.copyToOutputStream(outputStream, delegate); }, remove: function() { if (this._callsPendingOpen) { this._callsPendingOpen.push(this.remove.bind(this)); return; } if (this._tempFile) this._tempFile.remove(); this._tempFile = null; } } /** * @param {function(?)} fulfill * @param {function(*)} reject */ WebInspector.TempFile._clearTempStorage = function(fulfill, reject) { /** * @param {!Event} event */ function handleError(event) { WebInspector.console.error(WebInspector.UIString("Failed to clear temp storage: %s", event.data)); reject(event.data); } /** * @param {!Event} event */ function handleMessage(event) { if (event.data.type === "tempStorageCleared") { if (event.data.error) WebInspector.console.error(event.data.error); else fulfill(undefined); return; } reject(event.data); } try { var worker = new WorkerRuntime.Worker("temp_storage_shared_worker", "TempStorageCleaner"); worker.onerror = handleError; worker.port.onmessage = handleMessage; worker.port.onerror = handleError; } catch (e) { if (e.name === "URLMismatchError") console.log("Shared worker wasn't started due to url difference. " + e); else throw e; } } /** * @return {!Promise.<undefined>} */ WebInspector.TempFile.ensureTempStorageCleared = function() { if (!WebInspector.TempFile._storageCleanerPromise) WebInspector.TempFile._storageCleanerPromise = new Promise(WebInspector.TempFile._clearTempStorage); return WebInspector.TempFile._storageCleanerPromise; } /** * @constructor * @implements {WebInspector.BackingStorage} * @param {string} dirName */ WebInspector.TempFileBackingStorage = function(dirName) { this._dirName = dirName; this.reset(); } /** * @typedef {{ * string: ?string, * startOffset: number, * endOffset: number * }} */ WebInspector.TempFileBackingStorage.Chunk; WebInspector.TempFileBackingStorage.prototype = { /** * @override * @param {string} string */ appendString: function(string) { this._strings.push(string); this._stringsLength += string.length; var flushStringLength = 10 * 1024 * 1024; if (this._stringsLength > flushStringLength) this._flush(false); }, /** * @override * @param {string} string * @return {function():!Promise.<?string>} */ appendAccessibleString: function(string) { this._flush(false); this._strings.push(string); var chunk = /** @type {!WebInspector.TempFileBackingStorage.Chunk} */ (this._flush(true)); /** * @param {!WebInspector.TempFileBackingStorage.Chunk} chunk * @param {!WebInspector.DeferredTempFile} file * @return {!Promise.<?string>} */ function readString(chunk, file) { if (chunk.string) return /** @type {!Promise.<?string>} */ (Promise.resolve(chunk.string)); console.assert(chunk.endOffset); if (!chunk.endOffset) return Promise.reject("Nor string nor offset to the string in the file were found."); /** * @param {function(?string)} fulfill * @param {function(*)} reject */ function readRange(fulfill, reject) { // FIXME: call reject for null strings. file.readRange(chunk.startOffset, chunk.endOffset, fulfill); } return new Promise(readRange); } return readString.bind(null, chunk, this._file); }, /** * @param {boolean} createChunk * @return {?WebInspector.TempFileBackingStorage.Chunk} */ _flush: function(createChunk) { if (!this._strings.length) return null; var chunk = null; if (createChunk) { console.assert(this._strings.length === 1); chunk = { string: this._strings[0], startOffset: 0, endOffset: 0 }; } /** * @this {WebInspector.TempFileBackingStorage} * @param {?WebInspector.TempFileBackingStorage.Chunk} chunk * @param {number} fileSize */ function didWrite(chunk, fileSize) { if (fileSize === -1) return; if (chunk) { chunk.startOffset = this._fileSize; chunk.endOffset = fileSize; chunk.string = null; } this._fileSize = fileSize; } this._file.write(this._strings, didWrite.bind(this, chunk)); this._strings = []; this._stringsLength = 0; return chunk; }, /** * @override */ finishWriting: function() { this._flush(false); this._file.finishWriting(function() {}); }, /** * @override */ reset: function() { if (this._file) this._file.remove(); this._file = new WebInspector.DeferredTempFile(this._dirName, String(Date.now())); /** * @type {!Array.<string>} */ this._strings = []; this._stringsLength = 0; this._fileSize = 0; }, /** * @param {!WebInspector.OutputStream} outputStream * @param {!WebInspector.OutputStreamDelegate} delegate */ writeToStream: function(outputStream, delegate) { this._file.copyToOutputStream(outputStream, delegate); } } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| activeline.js | 14.58% | (7 / 48) | 10.71% | (3 / 28) | 12.5% | (1 / 8) | 16.28% | (7 / 43) | |
| closebrackets.js | 5% | (6 / 120) | 3.19% | (3 / 94) | 7.69% | (1 / 13) | 5.83% | (6 / 103) | |
| codemirror.js | 6.21% | (356 / 5735) | 0.07% | (3 / 4200) | 0.26% | (2 / 767) | 7.35% | (356 / 4844) | |
| comment.js | 2.58% | (4 / 155) | 1.72% | (3 / 174) | 9.09% | (1 / 11) | 3.13% | (4 / 128) | |
| css.js | 3.89% | (15 / 386) | 0.82% | (3 / 366) | 2.27% | (1 / 44) | 4.37% | (15 / 343) | |
| headlesscodemirror.js | 5.56% | (7 / 126) | 0% | (0 / 69) | 6.9% | (2 / 29) | 6.54% | (7 / 107) | |
| htmlembedded.js | 13.89% | (5 / 36) | 10.71% | (3 / 28) | 10% | (1 / 10) | 14.29% | (5 / 35) | |
| htmlmixed.js | 9.33% | (7 / 75) | 4.84% | (3 / 62) | 8.33% | (1 / 12) | 10% | (7 / 70) | |
| javascript.js | 11.98% | (78 / 651) | 0.54% | (3 / 558) | 1.15% | (1 / 87) | 15.69% | (78 / 497) | |
| markselection.js | 10.84% | (9 / 83) | 5.66% | (3 / 53) | 9.09% | (1 / 11) | 12.16% | (9 / 74) | |
| matchbrackets.js | 8.14% | (7 / 86) | 2.97% | (3 / 101) | 7.69% | (1 / 13) | 9.72% | (7 / 72) | |
| overlay.js | 9.38% | (3 / 32) | 9.68% | (3 / 31) | 11.11% | (1 / 9) | 10.34% | (3 / 29) | |
| simple.js | 7.36% | (12 / 163) | 1.71% | (3 / 175) | 5.26% | (1 / 19) | 8.51% | (12 / 141) | |
| xml.js | 8.47% | (21 / 248) | 1.53% | (3 / 196) | 3.57% | (1 / 28) | 9.01% | (21 / 233) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2 2 2 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Because sometimes you need to style the cursor's line.
//
// Adds an option 'styleActiveLine' which, when enabled, gives the
// active line's wrapping <div> the CSS class "CodeMirror-activeline",
// and gives its background <div> the class "CodeMirror-activeline-background".
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var WRAP_CLASS = "CodeMirror-activeline";
var BACK_CLASS = "CodeMirror-activeline-background";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.state.activeLines = [];
updateActiveLines(cm, cm.listSelections());
cm.on("beforeSelectionChange", selectionChange);
} else if (!val && prev) {
cm.off("beforeSelectionChange", selectionChange);
clearActiveLines(cm);
delete cm.state.activeLines;
}
});
function clearActiveLines(cm) {
for (var i = 0; i < cm.state.activeLines.length; i++) {
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
}
}
function sameArray(a, b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++)
if (a[i] != b[i]) return false;
return true;
}
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty()) continue;
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;
cm.operation(function() {
clearActiveLines(cm);
for (var i = 0; i < active.length; i++) {
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
cm.addLineClass(active[i], "background", BACK_CLASS);
}
cm.state.activeLines = active;
});
}
function selectionChange(cm, sel) {
updateActiveLines(cm, sel.ranges);
}
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | 2 2 2 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var DEFAULT_BRACKETS = "()[]{}''\"\"";
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
var SPACE_CHAR_REGEX = /\s/;
var Pos = CodeMirror.Pos;
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseBrackets");
if (!val) return;
var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
if (typeof val == "string") pairs = val;
else if (typeof val == "object") {
if (val.pairs != null) pairs = val.pairs;
if (val.explode != null) explode = val.explode;
}
var map = buildKeymap(pairs);
if (explode) map.Enter = buildExplodeHandler(explode);
cm.addKeyMap(map);
});
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null;
}
function buildKeymap(pairs) {
var map = {
name : "autoCloseBrackets",
Backspace: function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
}
}
};
var closingBrackets = "";
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
if (left != right) closingBrackets += right;
map["'" + left + "'"] = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), type, next;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
return CodeMirror.Pass;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (!range.empty())
curType = "surround";
else if (left == right && next == right) {
if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
curType = "skipThree";
else
curType = "skip";
} else if (left == right && cur.ch > 1 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left))
curType = "addFour";
else if (left == right && CodeMirror.isWordChar(next))
return CodeMirror.Pass;
else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
curType = "both";
else
return CodeMirror.Pass;
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
};
if (left != right) map["'" + right + "'"] = function(cm) {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty() ||
cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
return CodeMirror.Pass;
}
cm.execCommand("goCharRight");
};
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
}
function buildExplodeHandler(pairs) {
return function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
};
}
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 | 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// This is CodeMirror (http://codemirror.net), a code editor
// implemented in JavaScript on top of the browser's DOM.
//
// You can find some technical background for some of the code below
// at http://marijnhaverbeke.nl/blog/#cm-internals .
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
module.exports = mod();
else if (typeof define == "function" && define.amd) // AMD
return define([], mod);
else // Plain browser env
this.CodeMirror = mod();
})(function() {
"use strict";
// BROWSER SNIFFING
// Kludges for bugs and behavior differences that can't be feature
// detected are enabled based on userAgent etc sniffing.
var gecko = /gecko\/\d/i.test(navigator.userAgent);
// ie_uptoN means Internet Explorer version N or lower
var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
var ie = ie_upto10 || ie_11up;
var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
var webkit = /WebKit\//.test(navigator.userAgent);
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
var chrome = /Chrome\//.test(navigator.userAgent);
var presto = /Opera\//.test(navigator.userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
var khtml = /KHTML\//.test(navigator.userAgent);
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
var phantom = /PhantomJS/.test(navigator.userAgent);
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
// This is woefully incomplete. Suggestions for alternative methods welcome.
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
var mac = ios || /Mac/.test(navigator.platform);
var windows = /win/i.test(navigator.platform);
var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
if (presto_version) presto_version = Number(presto_version[1]);
if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
var captureRightClick = gecko || (ie && ie_version >= 9);
// Optimize some code when these features are not used.
var sawReadOnlySpans = false, sawCollapsedSpans = false;
// EDITOR CONSTRUCTOR
// A CodeMirror instance represents an editor. This is the object
// that user code is usually dealing with.
function CodeMirror(place, options) {
if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
this.options = options = options ? copyObj(options) : {};
// Determine effective options based on given values and defaults.
copyObj(defaults, options, false);
setGuttersForLineNumbers(options);
var doc = options.value;
if (typeof doc == "string") doc = new Doc(doc, options.mode);
this.doc = doc;
var display = this.display = new Display(place, doc);
display.wrapper.CodeMirror = this;
updateGutters(this);
themeChanged(this);
if (options.lineWrapping)
this.display.wrapper.className += " CodeMirror-wrap";
if (options.autofocus && !mobile) focusInput(this);
initScrollbars(this);
this.state = {
keyMaps: [], // stores maps added by addKeyMap
overlays: [], // highlighting overlays, as added by addOverlay
modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
overwrite: false, focused: false,
suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
draggingText: false,
highlight: new Delayed(), // stores highlight worker timeout
keySeq: null // Unfinished key sequence
};
// Override magic textarea content restore that IE sometimes does
// on our hidden textarea on reload
if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);
registerEventHandlers(this);
ensureGlobalHandlers();
startOperation(this);
this.curOp.forceUpdate = true;
attachDoc(this, doc);
if ((options.autofocus && !mobile) || activeElt() == display.input)
setTimeout(bind(onFocus, this), 20);
else
onBlur(this);
for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
optionHandlers[opt](this, options[opt], Init);
maybeUpdateLineNumberWidth(this);
for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
endOperation(this);
// Suppress optimizelegibility in Webkit, since it breaks text
// measuring on line wrapping boundaries.
if (webkit && options.lineWrapping &&
getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
display.lineDiv.style.textRendering = "auto";
}
// DISPLAY CONSTRUCTOR
// The display handles the DOM integration, both for input reading
// and content drawing. It holds references to DOM nodes and
// display-related state.
function Display(place, doc) {
var d = this;
// The semihidden textarea that is focused when the editor is
// focused, and receives input.
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
// The textarea is kept positioned near the cursor to prevent the
// fact that it'll be scrolled into view on input from scrolling
// our fake cursor out of view. On webkit, when wrap=off, paste is
// very slow. So make the area wide instead.
if (webkit) input.style.width = "1000px";
else input.setAttribute("wrap", "off");
// If border: 0; -- iOS fails to open keyboard (issue #1287)
if (ios) input.style.border = "1px solid black";
input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
// Wraps and hides input textarea
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
// Covers bottom-right square when both scrollbars are present.
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
d.scrollbarFiller.setAttribute("not-content", "true");
// Covers bottom of gutter when coverGutterNextToScrollbar is on
// and h scrollbar is present.
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
d.gutterFiller.setAttribute("not-content", "true");
// Will contain the actual code, positioned to cover the viewport.
d.lineDiv = elt("div", null, "CodeMirror-code");
// Elements are added to these to represent selection and cursors.
d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
d.cursorDiv = elt("div", null, "CodeMirror-cursors");
// A visibility: hidden element used to find the size of things.
d.measure = elt("div", null, "CodeMirror-measure");
// When lines outside of the viewport are measured, they are drawn in this.
d.lineMeasure = elt("div", null, "CodeMirror-measure");
// Wraps everything that needs to exist inside the vertically-padded coordinate system
d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
null, "position: relative; outline: none");
// Moved around its parent to cover visible view.
d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
// Set to the height of the document, allowing scrolling.
d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
d.sizerWidth = null;
// Behavior of elts with overflow: auto and padding is
// inconsistent across browsers. This is used to ensure the
// scrollable area is big enough.
d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
// Will contain the gutters, if any.
d.gutters = elt("div", null, "CodeMirror-gutters");
d.lineGutter = null;
// Actual scrollable element.
d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
d.scroller.setAttribute("tabIndex", "-1");
// The element in which the editor lives.
d.wrapper = elt("div", [d.inputDiv, d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
// Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
// Needed to hide big blue blinking cursor on Mobile Safari
if (ios) input.style.width = "0px";
if (!webkit) d.scroller.draggable = true;
// Needed to handle Tab key in KHTML
if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
if (place) {
if (place.appendChild) place.appendChild(d.wrapper);
else place(d.wrapper);
}
// Current rendered range (may be bigger than the view window).
d.viewFrom = d.viewTo = doc.first;
d.reportedViewFrom = d.reportedViewTo = doc.first;
// Information about the rendered lines.
d.view = [];
d.renderedView = null;
// Holds info about a single rendered line when it was rendered
// for measurement, while not in view.
d.externalMeasured = null;
// Empty space (in pixels) above the view
d.viewOffset = 0;
d.lastWrapHeight = d.lastWrapWidth = 0;
d.updateLineNumbers = null;
d.nativeBarWidth = d.barHeight = d.barWidth = 0;
d.scrollbarsClipped = false;
// Used to only resize the line number gutter when necessary (when
// the amount of lines crosses a boundary that makes its width change)
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
// See readInput and resetInput
d.prevInput = "";
// Set to true when a non-horizontal-scrolling line widget is
// added. As an optimization, line widget aligning is skipped when
// this is false.
d.alignWidgets = false;
// Flag that indicates whether we expect input to appear real soon
// now (after some event like 'keypress' or 'input') and are
// polling intensively.
d.pollingFast = false;
// Self-resetting timeout for the poller
d.poll = new Delayed();
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
// Tracks when resetInput has punted to just putting a short
// string into the textarea instead of the full selection.
d.inaccurateSelection = false;
// Tracks the maximum line length so that the horizontal scrollbar
// can be kept static when scrolling.
d.maxLine = null;
d.maxLineLength = 0;
d.maxLineChanged = false;
// Used for measuring wheel scrolling granularity
d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
// True when shift is held down.
d.shift = false;
// Used to track whether anything happened since the context menu
// was opened.
d.selForContextMenu = null;
}
// STATE UPDATES
// Used to get the editor into a consistent state again when options change.
function loadMode(cm) {
cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
resetModeState(cm);
}
function resetModeState(cm) {
cm.doc.iter(function(line) {
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
});
cm.doc.frontier = cm.doc.first;
startWorker(cm, 100);
cm.state.modeGen++;
if (cm.curOp) regChange(cm);
}
function wrappingChanged(cm) {
if (cm.options.lineWrapping) {
addClass(cm.display.wrapper, "CodeMirror-wrap");
cm.display.sizer.style.minWidth = "";
cm.display.sizerWidth = null;
} else {
rmClass(cm.display.wrapper, "CodeMirror-wrap");
findMaxLine(cm);
}
estimateLineHeights(cm);
regChange(cm);
clearCaches(cm);
setTimeout(function(){updateScrollbars(cm);}, 100);
}
// Returns a function that estimates the height of a line, to use as
// first approximation until the line becomes visible (and is thus
// properly measurable).
function estimateHeight(cm) {
var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
return function(line) {
if (lineIsHidden(cm.doc, line)) return 0;
var widgetsHeight = 0;
if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
}
if (wrapping)
return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
else
return widgetsHeight + th;
};
}
function estimateLineHeights(cm) {
var doc = cm.doc, est = estimateHeight(cm);
doc.iter(function(line) {
var estHeight = est(line);
if (estHeight != line.height) updateLineHeight(line, estHeight);
});
}
function themeChanged(cm) {
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
clearCaches(cm);
}
function guttersChanged(cm) {
updateGutters(cm);
regChange(cm);
setTimeout(function(){alignHorizontally(cm);}, 20);
}
// Rebuild the gutter elements, ensure the margin to the left of the
// code matches their width.
function updateGutters(cm) {
var gutters = cm.display.gutters, specs = cm.options.gutters;
removeChildren(gutters);
for (var i = 0; i < specs.length; ++i) {
var gutterClass = specs[i];
var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
if (gutterClass == "CodeMirror-linenumbers") {
cm.display.lineGutter = gElt;
gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
}
}
gutters.style.display = i ? "" : "none";
updateGutterSpace(cm);
}
function updateGutterSpace(cm) {
var width = cm.display.gutters.offsetWidth;
cm.display.sizer.style.marginLeft = width + "px";
}
// Compute the character length of a line, taking into account
// collapsed ranges (see markText) that might hide parts, and join
// other lines onto it.
function lineLength(line) {
if (line.height == 0) return 0;
var len = line.text.length, merged, cur = line;
while (merged = collapsedSpanAtStart(cur)) {
var found = merged.find(0, true);
cur = found.from.line;
len += found.from.ch - found.to.ch;
}
cur = line;
while (merged = collapsedSpanAtEnd(cur)) {
var found = merged.find(0, true);
len -= cur.text.length - found.from.ch;
cur = found.to.line;
len += cur.text.length - found.to.ch;
}
return len;
}
// Find the longest line in the document.
function findMaxLine(cm) {
var d = cm.display, doc = cm.doc;
d.maxLine = getLine(doc, doc.first);
d.maxLineLength = lineLength(d.maxLine);
d.maxLineChanged = true;
doc.iter(function(line) {
var len = lineLength(line);
if (len > d.maxLineLength) {
d.maxLineLength = len;
d.maxLine = line;
}
});
}
// Make sure the gutters options contains the element
// "CodeMirror-linenumbers" when the lineNumbers option is true.
function setGuttersForLineNumbers(options) {
var found = indexOf(options.gutters, "CodeMirror-linenumbers");
if (found == -1 && options.lineNumbers) {
options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
} else if (found > -1 && !options.lineNumbers) {
options.gutters = options.gutters.slice(0);
options.gutters.splice(found, 1);
}
}
// SCROLLBARS
// Prepare DOM reads needed to update the scrollbars. Done in one
// shot to minimize update/measure roundtrips.
function measureForScrollbars(cm) {
var d = cm.display, gutterW = d.gutters.offsetWidth;
var docH = Math.round(cm.doc.height + paddingVert(cm.display));
return {
clientHeight: d.scroller.clientHeight,
viewHeight: d.wrapper.clientHeight,
scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
viewWidth: d.wrapper.clientWidth,
barLeft: cm.options.fixedGutter ? gutterW : 0,
docHeight: docH,
scrollHeight: docH + scrollGap(cm) + d.barHeight,
nativeBarWidth: d.nativeBarWidth,
gutterWidth: gutterW
};
}
function NativeScrollbars(place, scroll, cm) {
this.cm = cm;
var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
place(vert); place(horiz);
on(vert, "scroll", function() {
if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
});
on(horiz, "scroll", function() {
if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
});
this.checkedOverlay = false;
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
}
NativeScrollbars.prototype = copyObj({
update: function(measure) {
var needsH = measure.scrollWidth > measure.clientWidth + 1;
var needsV = measure.scrollHeight > measure.clientHeight + 1;
var sWidth = measure.nativeBarWidth;
if (needsV) {
this.vert.style.display = "block";
this.vert.style.bottom = needsH ? sWidth + "px" : "0";
var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
// A bug in IE8 can cause this value to be negative, so guard it.
this.vert.firstChild.style.height =
Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
} else {
this.vert.style.display = "";
this.vert.firstChild.style.height = "0";
}
if (needsH) {
this.horiz.style.display = "block";
this.horiz.style.right = needsV ? sWidth + "px" : "0";
this.horiz.style.left = measure.barLeft + "px";
var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
this.horiz.firstChild.style.width =
(measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
} else {
this.horiz.style.display = "";
this.horiz.firstChild.style.width = "0";
}
if (!this.checkedOverlay && measure.clientHeight > 0) {
if (sWidth == 0) this.overlayHack();
this.checkedOverlay = true;
}
return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
},
setScrollLeft: function(pos) {
if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
},
setScrollTop: function(pos) {
if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
},
overlayHack: function() {
var w = mac && !mac_geMountainLion ? "12px" : "18px";
this.horiz.style.minHeight = this.vert.style.minWidth = w;
var self = this;
var barMouseDown = function(e) {
if (e_target(e) != self.vert && e_target(e) != self.horiz)
operation(self.cm, onMouseDown)(e);
};
on(this.vert, "mousedown", barMouseDown);
on(this.horiz, "mousedown", barMouseDown);
},
clear: function() {
var parent = this.horiz.parentNode;
parent.removeChild(this.horiz);
parent.removeChild(this.vert);
}
}, NativeScrollbars.prototype);
function NullScrollbars() {}
NullScrollbars.prototype = copyObj({
update: function() { return {bottom: 0, right: 0}; },
setScrollLeft: function() {},
setScrollTop: function() {},
clear: function() {}
}, NullScrollbars.prototype);
CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
function initScrollbars(cm) {
if (cm.display.scrollbars) {
cm.display.scrollbars.clear();
if (cm.display.scrollbars.addClass)
rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
}
cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
on(node, "mousedown", function() {
if (cm.state.focused) setTimeout(bind(focusInput, cm), 0);
});
node.setAttribute("not-content", "true");
}, function(pos, axis) {
if (axis == "horizontal") setScrollLeft(cm, pos);
else setScrollTop(cm, pos);
}, cm);
if (cm.display.scrollbars.addClass)
addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
}
function updateScrollbars(cm, measure) {
if (!measure) measure = measureForScrollbars(cm);
var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
updateScrollbarsInner(cm, measure);
for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
updateHeightsInViewport(cm);
updateScrollbarsInner(cm, measureForScrollbars(cm));
startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
}
}
// Re-synchronize the fake scrollbars with the actual size of the
// content.
function updateScrollbarsInner(cm, measure) {
var d = cm.display;
var sizes = d.scrollbars.update(measure);
d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
if (sizes.right && sizes.bottom) {
d.scrollbarFiller.style.display = "block";
d.scrollbarFiller.style.height = sizes.bottom + "px";
d.scrollbarFiller.style.width = sizes.right + "px";
} else d.scrollbarFiller.style.display = "";
if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
d.gutterFiller.style.display = "block";
d.gutterFiller.style.height = sizes.bottom + "px";
d.gutterFiller.style.width = measure.gutterWidth + "px";
} else d.gutterFiller.style.display = "";
}
// Compute the lines that are visible in a given viewport (defaults
// the the current scroll position). viewport may contain top,
// height, and ensure (see op.scrollToPos) properties.
function visibleLines(display, doc, viewport) {
var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
top = Math.floor(top - paddingTop(display));
var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
// Ensure is a {from: {line, ch}, to: {line, ch}} object, and
// forces those lines into the viewport (if possible).
if (viewport && viewport.ensure) {
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
if (ensureFrom < from) {
from = ensureFrom;
to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
} else if (Math.min(ensureTo, doc.lastLine()) >= to) {
from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
to = ensureTo;
}
}
return {from: from, to: Math.max(to, from + 1)};
}
// LINE NUMBERS
// Re-align line numbers and gutter marks to compensate for
// horizontal scrolling.
function alignHorizontally(cm) {
var display = cm.display, view = display.view;
if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
var gutterW = display.gutters.offsetWidth, left = comp + "px";
for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
if (cm.options.fixedGutter && view[i].gutter)
view[i].gutter.style.left = left;
var align = view[i].alignable;
if (align) for (var j = 0; j < align.length; j++)
align[j].style.left = left;
}
if (cm.options.fixedGutter)
display.gutters.style.left = (comp + gutterW) + "px";
}
// Used to ensure that the line number gutter is still the right
// size for the current document size. Returns true when an update
// is needed.
function maybeUpdateLineNumberWidth(cm) {
if (!cm.options.lineNumbers) return false;
var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
if (last.length != display.lineNumChars) {
var test = display.measure.appendChild(elt("div", [elt("div", last)],
"CodeMirror-linenumber CodeMirror-gutter-elt"));
var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
display.lineGutter.style.width = "";
display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
display.lineNumWidth = display.lineNumInnerWidth + padding;
display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
display.lineGutter.style.width = display.lineNumWidth + "px";
updateGutterSpace(cm);
return true;
}
return false;
}
function lineNumberFor(options, i) {
return String(options.lineNumberFormatter(i + options.firstLineNumber));
}
// Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
// but using getBoundingClientRect to get a sub-pixel-accurate
// result.
function compensateForHScroll(display) {
return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
}
// DISPLAY DRAWING
function DisplayUpdate(cm, viewport, force) {
var display = cm.display;
this.viewport = viewport;
// Store some values that we'll need later (but don't want to force a relayout for)
this.visible = visibleLines(display, cm.doc, viewport);
this.editorIsHidden = !display.wrapper.offsetWidth;
this.wrapperHeight = display.wrapper.clientHeight;
this.wrapperWidth = display.wrapper.clientWidth;
this.oldDisplayWidth = displayWidth(cm);
this.force = force;
this.dims = getDimensions(cm);
}
function maybeClipScrollbars(cm) {
var display = cm.display;
if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
display.heightForcer.style.height = scrollGap(cm) + "px";
display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
display.scrollbarsClipped = true;
}
}
// Does the actual updating of the line display. Bails out
// (returning false) when there is nothing to be done and forced is
// false.
function updateDisplayIfNeeded(cm, update) {
var display = cm.display, doc = cm.doc;
if (update.editorIsHidden) {
resetView(cm);
return false;
}
// Bail out if the visible area is already rendered and nothing changed.
if (!update.force &&
update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
display.renderedView == display.view && countDirtyView(cm) == 0)
return false;
if (maybeUpdateLineNumberWidth(cm)) {
resetView(cm);
update.dims = getDimensions(cm);
}
// Compute a suitable new viewport (from & to)
var end = doc.first + doc.size;
var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
if (sawCollapsedSpans) {
from = visualLineNo(cm.doc, from);
to = visualLineEndNo(cm.doc, to);
}
var different = from != display.viewFrom || to != display.viewTo ||
display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
adjustView(cm, from, to);
display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
// Position the mover div to align with the current scroll position
cm.display.mover.style.top = display.viewOffset + "px";
var toUpdate = countDirtyView(cm);
if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
return false;
// For big changes, we hide the enclosing element during the
// update, since that speeds up the operations on most browsers.
var focused = activeElt();
if (toUpdate > 4) display.lineDiv.style.display = "none";
patchDisplay(cm, display.updateLineNumbers, update.dims);
if (toUpdate > 4) display.lineDiv.style.display = "";
display.renderedView = display.view;
// There might have been a widget with a focused element that got
// hidden or updated, if so re-focus it.
if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
// Prevent selection and cursors from interfering with the scroll
// width and height.
removeChildren(display.cursorDiv);
removeChildren(display.selectionDiv);
display.gutters.style.height = 0;
if (different) {
display.lastWrapHeight = update.wrapperHeight;
display.lastWrapWidth = update.wrapperWidth;
startWorker(cm, 400);
}
display.updateLineNumbers = null;
return true;
}
function postUpdateDisplay(cm, update) {
var force = update.force, viewport = update.viewport;
for (var first = true;; first = false) {
if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {
force = true;
} else {
force = false;
// Clip forced viewport to actual scrollable area.
if (viewport && viewport.top != null)
viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
// Updated line heights might result in the drawn area not
// actually covering the viewport. Keep looping until it does.
update.visible = visibleLines(cm.display, cm.doc, viewport);
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
break;
}
if (!updateDisplayIfNeeded(cm, update)) break;
updateHeightsInViewport(cm);
var barMeasure = measureForScrollbars(cm);
updateSelection(cm);
setDocumentHeight(cm, barMeasure);
updateScrollbars(cm, barMeasure);
}
signalLater(cm, "update", cm);
if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
}
}
function updateDisplaySimple(cm, viewport) {
var update = new DisplayUpdate(cm, viewport);
if (updateDisplayIfNeeded(cm, update)) {
updateHeightsInViewport(cm);
postUpdateDisplay(cm, update);
var barMeasure = measureForScrollbars(cm);
updateSelection(cm);
setDocumentHeight(cm, barMeasure);
updateScrollbars(cm, barMeasure);
}
}
function setDocumentHeight(cm, measure) {
cm.display.sizer.style.minHeight = measure.docHeight + "px";
var total = measure.docHeight + cm.display.barHeight;
cm.display.heightForcer.style.top = total + "px";
cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
}
// Read the actual heights of the rendered lines, and update their
// stored heights to match.
function updateHeightsInViewport(cm) {
var display = cm.display;
var prevBottom = display.lineDiv.offsetTop;
for (var i = 0; i < display.view.length; i++) {
var cur = display.view[i], height;
if (cur.hidden) continue;
if (ie && ie_version < 8) {
var bot = cur.node.offsetTop + cur.node.offsetHeight;
height = bot - prevBottom;
prevBottom = bot;
} else {
var box = cur.node.getBoundingClientRect();
height = box.bottom - box.top;
}
var diff = cur.line.height - height;
if (height < 2) height = textHeight(display);
if (diff > .001 || diff < -.001) {
updateLineHeight(cur.line, height);
updateWidgetHeight(cur.line);
if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
updateWidgetHeight(cur.rest[j]);
}
}
}
// Read and store the height of line widgets associated with the
// given line.
function updateWidgetHeight(line) {
if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
line.widgets[i].height = line.widgets[i].node.offsetHeight;
}
// Do a bulk-read of the DOM positions and sizes needed to draw the
// view, so that we don't interleave reading and writing to the DOM.
function getDimensions(cm) {
var d = cm.display, left = {}, width = {};
var gutterLeft = d.gutters.clientLeft;
for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
width[cm.options.gutters[i]] = n.clientWidth;
}
return {fixedPos: compensateForHScroll(d),
gutterTotalWidth: d.gutters.offsetWidth,
gutterLeft: left,
gutterWidth: width,
wrapperWidth: d.wrapper.clientWidth};
}
// Sync the actual display DOM structure with display.view, removing
// nodes for lines that are no longer in view, and creating the ones
// that are not there yet, and updating the ones that are out of
// date.
function patchDisplay(cm, updateNumbersFrom, dims) {
var display = cm.display, lineNumbers = cm.options.lineNumbers;
var container = display.lineDiv, cur = container.firstChild;
function rm(node) {
var next = node.nextSibling;
// Works around a throw-scroll bug in OS X Webkit
if (webkit && mac && cm.display.currentWheelTarget == node)
node.style.display = "none";
else
node.parentNode.removeChild(node);
return next;
}
var view = display.view, lineN = display.viewFrom;
// Loop over the elements in the view, syncing cur (the DOM nodes
// in display.lineDiv) with the view as we go.
for (var i = 0; i < view.length; i++) {
var lineView = view[i];
if (lineView.hidden) {
} else if (!lineView.node) { // Not drawn yet
var node = buildLineElement(cm, lineView, lineN, dims);
container.insertBefore(node, cur);
} else { // Already drawn
while (cur != lineView.node) cur = rm(cur);
var updateNumber = lineNumbers && updateNumbersFrom != null &&
updateNumbersFrom <= lineN && lineView.lineNumber;
if (lineView.changes) {
if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
updateLineForChanges(cm, lineView, lineN, dims);
}
if (updateNumber) {
removeChildren(lineView.lineNumber);
lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
}
cur = lineView.node.nextSibling;
}
lineN += lineView.size;
}
while (cur) cur = rm(cur);
}
// When an aspect of a line changes, a string is added to
// lineView.changes. This updates the relevant part of the line's
// DOM structure.
function updateLineForChanges(cm, lineView, lineN, dims) {
for (var j = 0; j < lineView.changes.length; j++) {
var type = lineView.changes[j];
if (type == "text") updateLineText(cm, lineView);
else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
else if (type == "class") updateLineClasses(lineView);
else if (type == "widget") updateLineWidgets(lineView, dims);
}
lineView.changes = null;
}
// Lines with gutter elements, widgets or a background class need to
// be wrapped, and have the extra elements added to the wrapper div
function ensureLineWrapped(lineView) {
if (lineView.node == lineView.text) {
lineView.node = elt("div", null, null, "position: relative");
if (lineView.text.parentNode)
lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
lineView.node.appendChild(lineView.text);
if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
}
return lineView.node;
}
function updateLineBackground(lineView) {
var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
if (cls) cls += " CodeMirror-linebackground";
if (lineView.background) {
if (cls) lineView.background.className = cls;
else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
} else if (cls) {
var wrap = ensureLineWrapped(lineView);
lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
}
}
// Wrapper around buildLineContent which will reuse the structure
// in display.externalMeasured when possible.
function getLineContent(cm, lineView) {
var ext = cm.display.externalMeasured;
if (ext && ext.line == lineView.line) {
cm.display.externalMeasured = null;
lineView.measure = ext.measure;
return ext.built;
}
return buildLineContent(cm, lineView);
}
// Redraw the line's text. Interacts with the background and text
// classes because the mode may output tokens that influence these
// classes.
function updateLineText(cm, lineView) {
var cls = lineView.text.className;
var built = getLineContent(cm, lineView);
if (lineView.text == lineView.node) lineView.node = built.pre;
lineView.text.parentNode.replaceChild(built.pre, lineView.text);
lineView.text = built.pre;
if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
lineView.bgClass = built.bgClass;
lineView.textClass = built.textClass;
updateLineClasses(lineView);
} else if (cls) {
lineView.text.className = cls;
}
}
function updateLineClasses(lineView) {
updateLineBackground(lineView);
if (lineView.line.wrapClass)
ensureLineWrapped(lineView).className = lineView.line.wrapClass;
else if (lineView.node != lineView.text)
lineView.node.className = "";
var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
lineView.text.className = textClass || "";
}
function updateLineGutter(cm, lineView, lineN, dims) {
if (lineView.gutter) {
lineView.node.removeChild(lineView.gutter);
lineView.gutter = null;
}
var markers = lineView.line.gutterMarkers;
if (cm.options.lineNumbers || markers) {
var wrap = ensureLineWrapped(lineView);
var gutterWrap = lineView.gutter =
wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
"px; width: " + dims.gutterTotalWidth + "px"),
lineView.text);
if (lineView.line.gutterClass)
gutterWrap.className += " " + lineView.line.gutterClass;
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
lineView.lineNumber = gutterWrap.appendChild(
elt("div", lineNumberFor(cm.options, lineN),
"CodeMirror-linenumber CodeMirror-gutter-elt",
"left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
+ cm.display.lineNumInnerWidth + "px"));
if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
if (found)
gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
}
}
}
function updateLineWidgets(lineView, dims) {
if (lineView.alignable) lineView.alignable = null;
for (var node = lineView.node.firstChild, next; node; node = next) {
var next = node.nextSibling;
if (node.className == "CodeMirror-linewidget")
lineView.node.removeChild(node);
}
insertLineWidgets(lineView, dims);
}
// Build a line's DOM representation from scratch
function buildLineElement(cm, lineView, lineN, dims) {
var built = getLineContent(cm, lineView);
lineView.text = lineView.node = built.pre;
if (built.bgClass) lineView.bgClass = built.bgClass;
if (built.textClass) lineView.textClass = built.textClass;
updateLineClasses(lineView);
updateLineGutter(cm, lineView, lineN, dims);
insertLineWidgets(lineView, dims);
return lineView.node;
}
// A lineView may contain multiple logical lines (when merged by
// collapsed spans). The widgets for all of them need to be drawn.
function insertLineWidgets(lineView, dims) {
insertLineWidgetsFor(lineView.line, lineView, dims, true);
if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
}
function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
if (!line.widgets) return;
var wrap = ensureLineWrapped(lineView);
for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
positionLineWidget(widget, node, lineView, dims);
if (allowAbove && widget.above)
wrap.insertBefore(node, lineView.gutter || lineView.text);
else
wrap.appendChild(node);
signalLater(widget, "redraw");
}
}
function positionLineWidget(widget, node, lineView, dims) {
if (widget.noHScroll) {
(lineView.alignable || (lineView.alignable = [])).push(node);
var width = dims.wrapperWidth;
node.style.left = dims.fixedPos + "px";
if (!widget.coverGutter) {
width -= dims.gutterTotalWidth;
node.style.paddingLeft = dims.gutterTotalWidth + "px";
}
node.style.width = width + "px";
}
if (widget.coverGutter) {
node.style.zIndex = 5;
node.style.position = "relative";
if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
}
}
// POSITION OBJECT
// A Pos instance represents a position within the text.
var Pos = CodeMirror.Pos = function(line, ch) {
if (!(this instanceof Pos)) return new Pos(line, ch);
this.line = line; this.ch = ch;
};
// Compare two positions, return 0 if they are the same, a negative
// number when a is less, and a positive number otherwise.
var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
function copyPos(x) {return Pos(x.line, x.ch);}
function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
// SELECTION / CURSOR
// Selection objects are immutable. A new one is created every time
// the selection changes. A selection is one or more non-overlapping
// (and non-touching) ranges, sorted, and an integer that indicates
// which one is the primary selection (the one that's scrolled into
// view, that getCursor returns, etc).
function Selection(ranges, primIndex) {
this.ranges = ranges;
this.primIndex = primIndex;
}
Selection.prototype = {
primary: function() { return this.ranges[this.primIndex]; },
equals: function(other) {
if (other == this) return true;
if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
for (var i = 0; i < this.ranges.length; i++) {
var here = this.ranges[i], there = other.ranges[i];
if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
}
return true;
},
deepCopy: function() {
for (var out = [], i = 0; i < this.ranges.length; i++)
out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
return new Selection(out, this.primIndex);
},
somethingSelected: function() {
for (var i = 0; i < this.ranges.length; i++)
if (!this.ranges[i].empty()) return true;
return false;
},
contains: function(pos, end) {
if (!end) end = pos;
for (var i = 0; i < this.ranges.length; i++) {
var range = this.ranges[i];
if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
return i;
}
return -1;
}
};
function Range(anchor, head) {
this.anchor = anchor; this.head = head;
}
Range.prototype = {
from: function() { return minPos(this.anchor, this.head); },
to: function() { return maxPos(this.anchor, this.head); },
empty: function() {
return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
}
};
// Take an unsorted, potentially overlapping set of ranges, and
// build a selection out of it. 'Consumes' ranges array (modifying
// it).
function normalizeSelection(ranges, primIndex) {
var prim = ranges[primIndex];
ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
primIndex = indexOf(ranges, prim);
for (var i = 1; i < ranges.length; i++) {
var cur = ranges[i], prev = ranges[i - 1];
if (cmp(prev.to(), cur.from()) >= 0) {
var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
if (i <= primIndex) --primIndex;
ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
}
}
return new Selection(ranges, primIndex);
}
function simpleSelection(anchor, head) {
return new Selection([new Range(anchor, head || anchor)], 0);
}
// Most of the external API clips given positions to make sure they
// actually exist within the document.
function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
function clipPos(doc, pos) {
if (pos.line < doc.first) return Pos(doc.first, 0);
var last = doc.first + doc.size - 1;
if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
return clipToLen(pos, getLine(doc, pos.line).text.length);
}
function clipToLen(pos, linelen) {
var ch = pos.ch;
if (ch == null || ch > linelen) return Pos(pos.line, linelen);
else if (ch < 0) return Pos(pos.line, 0);
else return pos;
}
function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
function clipPosArray(doc, array) {
for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
return out;
}
// SELECTION UPDATES
// The 'scroll' parameter given to many of these indicated whether
// the new cursor position should be scrolled into view after
// modifying the selection.
// If shift is held or the extend flag is set, extends a range to
// include a given position (and optionally a second position).
// Otherwise, simply returns the range between the given positions.
// Used for cursor motion and such.
function extendRange(doc, range, head, other) {
if (doc.cm && doc.cm.display.shift || doc.extend) {
var anchor = range.anchor;
if (other) {
var posBefore = cmp(head, anchor) < 0;
if (posBefore != (cmp(other, anchor) < 0)) {
anchor = head;
head = other;
} else if (posBefore != (cmp(head, other) < 0)) {
head = other;
}
}
return new Range(anchor, head);
} else {
return new Range(other || head, head);
}
}
// Extend the primary selection range, discard the rest.
function extendSelection(doc, head, other, options) {
setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
}
// Extend all selections (pos is an array of selections with length
// equal the number of selections)
function extendSelections(doc, heads, options) {
for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
var newSel = normalizeSelection(out, doc.sel.primIndex);
setSelection(doc, newSel, options);
}
// Updates a single range in the selection.
function replaceOneSelection(doc, i, range, options) {
var ranges = doc.sel.ranges.slice(0);
ranges[i] = range;
setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
}
// Reset the selection to a single range.
function setSimpleSelection(doc, anchor, head, options) {
setSelection(doc, simpleSelection(anchor, head), options);
}
// Give beforeSelectionChange handlers a change to influence a
// selection update.
function filterSelectionChange(doc, sel) {
var obj = {
ranges: sel.ranges,
update: function(ranges) {
this.ranges = [];
for (var i = 0; i < ranges.length; i++)
this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
clipPos(doc, ranges[i].head));
}
};
signal(doc, "beforeSelectionChange", doc, obj);
if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
else return sel;
}
function setSelectionReplaceHistory(doc, sel, options) {
var done = doc.history.done, last = lst(done);
if (last && last.ranges) {
done[done.length - 1] = sel;
setSelectionNoUndo(doc, sel, options);
} else {
setSelection(doc, sel, options);
}
}
// Set a new selection.
function setSelection(doc, sel, options) {
setSelectionNoUndo(doc, sel, options);
addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
}
function setSelectionNoUndo(doc, sel, options) {
if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
sel = filterSelectionChange(doc, sel);
var bias = options && options.bias ||
(cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
if (!(options && options.scroll === false) && doc.cm)
ensureCursorVisible(doc.cm);
}
function setSelectionInner(doc, sel) {
if (sel.equals(doc.sel)) return;
doc.sel = sel;
if (doc.cm) {
doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
signalCursorActivity(doc.cm);
}
signalLater(doc, "cursorActivity", doc);
}
// Verify that the selection does not partially select any atomic
// marked ranges.
function reCheckSelection(doc) {
setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
}
// Return a selection that does not partially select any atomic
// ranges.
function skipAtomicInSelection(doc, sel, bias, mayClear) {
var out;
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
var newHead = skipAtomic(doc, range.head, bias, mayClear);
if (out || newAnchor != range.anchor || newHead != range.head) {
if (!out) out = sel.ranges.slice(0, i);
out[i] = new Range(newAnchor, newHead);
}
}
return out ? normalizeSelection(out, sel.primIndex) : sel;
}
// Ensure a given position is not inside an atomic range.
function skipAtomic(doc, pos, bias, mayClear) {
var flipped = false, curPos = pos;
var dir = bias || 1;
doc.cantEdit = false;
search: for (;;) {
var line = getLine(doc, curPos.line);
if (line.markedSpans) {
for (var i = 0; i < line.markedSpans.length; ++i) {
var sp = line.markedSpans[i], m = sp.marker;
if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
(sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
if (mayClear) {
signal(m, "beforeCursorEnter");
if (m.explicitlyCleared) {
if (!line.markedSpans) break;
else {--i; continue;}
}
}
if (!m.atomic) continue;
var newPos = m.find(dir < 0 ? -1 : 1);
if (cmp(newPos, curPos) == 0) {
newPos.ch += dir;
if (newPos.ch < 0) {
if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
else newPos = null;
} else if (newPos.ch > line.text.length) {
if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
else newPos = null;
}
if (!newPos) {
if (flipped) {
// Driven in a corner -- no valid cursor position found at all
// -- try again *with* clearing, if we didn't already
if (!mayClear) return skipAtomic(doc, pos, bias, true);
// Otherwise, turn off editing until further notice, and return the start of the doc
doc.cantEdit = true;
return Pos(doc.first, 0);
}
flipped = true; newPos = pos; dir = -dir;
}
}
curPos = newPos;
continue search;
}
}
}
return curPos;
}
}
// SELECTION DRAWING
// Redraw the selection and/or cursor
function drawSelection(cm) {
var display = cm.display, doc = cm.doc, result = {};
var curFragment = result.cursors = document.createDocumentFragment();
var selFragment = result.selection = document.createDocumentFragment();
for (var i = 0; i < doc.sel.ranges.length; i++) {
var range = doc.sel.ranges[i];
var collapsed = range.empty();
if (collapsed || cm.options.showCursorWhenSelecting)
drawSelectionCursor(cm, range, curFragment);
if (!collapsed)
drawSelectionRange(cm, range, selFragment);
}
// Move the hidden textarea near the cursor to prevent scrolling artifacts
if (cm.options.moveInputWithCursor) {
var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
headPos.top + lineOff.top - wrapOff.top));
result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
headPos.left + lineOff.left - wrapOff.left));
}
return result;
}
function showSelection(cm, drawn) {
removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
if (drawn.teTop != null) {
cm.display.inputDiv.style.top = drawn.teTop + "px";
cm.display.inputDiv.style.left = drawn.teLeft + "px";
}
}
function updateSelection(cm) {
showSelection(cm, drawSelection(cm));
}
// Draws a cursor for the given range
function drawSelectionCursor(cm, range, output) {
var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
cursor.style.left = pos.left + "px";
cursor.style.top = pos.top + "px";
cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
if (pos.other) {
// Secondary cursor, shown when on a 'jump' in bi-directional text
var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
otherCursor.style.display = "";
otherCursor.style.left = pos.other.left + "px";
otherCursor.style.top = pos.other.top + "px";
otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
}
}
// Draws the given range as a highlighted selection
function drawSelectionRange(cm, range, output) {
var display = cm.display, doc = cm.doc;
var fragment = document.createDocumentFragment();
var padding = paddingH(cm.display), leftSide = padding.left;
var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
function add(left, top, width, bottom) {
if (top < 0) top = 0;
top = Math.round(top);
bottom = Math.round(bottom);
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
"px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
"px; height: " + (bottom - top) + "px"));
}
function drawForLine(line, fromArg, toArg) {
var lineObj = getLine(doc, line);
var lineLen = lineObj.text.length;
var start, end;
function coords(ch, bias) {
return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
}
iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
var leftPos = coords(from, "left"), rightPos, left, right;
if (from == to) {
rightPos = leftPos;
left = right = leftPos.left;
} else {
rightPos = coords(to - 1, "right");
if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
left = leftPos.left;
right = rightPos.right;
}
if (fromArg == null && from == 0) left = leftSide;
if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
add(left, leftPos.top, null, leftPos.bottom);
left = leftSide;
if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
}
if (toArg == null && to == lineLen) right = rightSide;
if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
start = leftPos;
if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
end = rightPos;
if (left < leftSide + 1) left = leftSide;
add(left, rightPos.top, right - left, rightPos.bottom);
});
return {start: start, end: end};
}
var sFrom = range.from(), sTo = range.to();
if (sFrom.line == sTo.line) {
drawForLine(sFrom.line, sFrom.ch, sTo.ch);
} else {
var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
var singleVLine = visualLine(fromLine) == visualLine(toLine);
var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
if (singleVLine) {
if (leftEnd.top < rightStart.top - 2) {
add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
} else {
add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
}
}
if (leftEnd.bottom < rightStart.top)
add(leftSide, leftEnd.bottom, null, rightStart.top);
}
output.appendChild(fragment);
}
// Cursor-blinking
function restartBlink(cm) {
if (!cm.state.focused) return;
var display = cm.display;
clearInterval(display.blinker);
var on = true;
display.cursorDiv.style.visibility = "";
if (cm.options.cursorBlinkRate > 0)
display.blinker = setInterval(function() {
display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
}, cm.options.cursorBlinkRate);
else if (cm.options.cursorBlinkRate < 0)
display.cursorDiv.style.visibility = "hidden";
}
// HIGHLIGHT WORKER
function startWorker(cm, time) {
if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
cm.state.highlight.set(time, bind(highlightWorker, cm));
}
function highlightWorker(cm) {
var doc = cm.doc;
if (doc.frontier < doc.first) doc.frontier = doc.first;
if (doc.frontier >= cm.display.viewTo) return;
var end = +new Date + cm.options.workTime;
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
var changedLines = [];
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
if (doc.frontier >= cm.display.viewFrom) { // Visible
var oldStyles = line.styles;
var highlighted = highlightLine(cm, line, state, true);
line.styles = highlighted.styles;
var oldCls = line.styleClasses, newCls = highlighted.classes;
if (newCls) line.styleClasses = newCls;
else if (oldCls) line.styleClasses = null;
var ischange = !oldStyles || oldStyles.length != line.styles.length ||
oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
if (ischange) changedLines.push(doc.frontier);
line.stateAfter = copyState(doc.mode, state);
} else {
processLine(cm, line.text, state);
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
}
++doc.frontier;
if (+new Date > end) {
startWorker(cm, cm.options.workDelay);
return true;
}
});
if (changedLines.length) runInOp(cm, function() {
for (var i = 0; i < changedLines.length; i++)
regLineChange(cm, changedLines[i], "text");
});
}
// Finds the line to start with when starting a parse. Tries to
// find a line with a stateAfter, so that it can start with a
// valid state. If that fails, it returns the line with the
// smallest indentation, which tends to need the least context to
// parse correctly.
function findStartLine(cm, n, precise) {
var minindent, minline, doc = cm.doc;
var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
for (var search = n; search > lim; --search) {
if (search <= doc.first) return doc.first;
var line = getLine(doc, search - 1);
if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
var indented = countColumn(line.text, null, cm.options.tabSize);
if (minline == null || minindent > indented) {
minline = search - 1;
minindent = indented;
}
}
return minline;
}
function getStateBefore(cm, n, precise) {
var doc = cm.doc, display = cm.display;
if (!doc.mode.startState) return true;
var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
if (!state) state = startState(doc.mode);
else state = copyState(doc.mode, state);
doc.iter(pos, n, function(line) {
processLine(cm, line.text, state);
var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
line.stateAfter = save ? copyState(doc.mode, state) : null;
++pos;
});
if (precise) doc.frontier = pos;
return state;
}
// POSITION MEASUREMENT
function paddingTop(display) {return display.lineSpace.offsetTop;}
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
function paddingH(display) {
if (display.cachedPaddingH) return display.cachedPaddingH;
var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
return data;
}
function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }
function displayWidth(cm) {
return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;
}
function displayHeight(cm) {
return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;
}
// Ensure the lineView.wrapping.heights array is populated. This is
// an array of bottom offsets for the lines that make up a drawn
// line. When lineWrapping is on, there might be more than one
// height.
function ensureLineHeights(cm, lineView, rect) {
var wrapping = cm.options.lineWrapping;
var curWidth = wrapping && displayWidth(cm);
if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
var heights = lineView.measure.heights = [];
if (wrapping) {
lineView.measure.width = curWidth;
var rects = lineView.text.firstChild.getClientRects();
for (var i = 0; i < rects.length - 1; i++) {
var cur = rects[i], next = rects[i + 1];
if (Math.abs(cur.bottom - next.bottom) > 2)
heights.push((cur.bottom + next.top) / 2 - rect.top);
}
}
heights.push(rect.bottom - rect.top);
}
}
// Find a line map (mapping character offsets to text nodes) and a
// measurement cache for the given line number. (A line view might
// contain multiple lines when collapsed ranges are present.)
function mapFromLineView(lineView, line, lineN) {
if (lineView.line == line)
return {map: lineView.measure.map, cache: lineView.measure.cache};
for (var i = 0; i < lineView.rest.length; i++)
if (lineView.rest[i] == line)
return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
for (var i = 0; i < lineView.rest.length; i++)
if (lineNo(lineView.rest[i]) > lineN)
return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
}
// Render a line into the hidden node display.externalMeasured. Used
// when measurement is needed for a line that's not in the viewport.
function updateExternalMeasurement(cm, line) {
line = visualLine(line);
var lineN = lineNo(line);
var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
view.lineN = lineN;
var built = view.built = buildLineContent(cm, view);
view.text = built.pre;
removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
return view;
}
// Get a {top, bottom, left, right} box (in line-local coordinates)
// for a given character.
function measureChar(cm, line, ch, bias) {
return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
}
// Find a line view that corresponds to the given line number.
function findViewForLine(cm, lineN) {
if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
return cm.display.view[findViewIndex(cm, lineN)];
var ext = cm.display.externalMeasured;
if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
return ext;
}
// Measurement can be split in two steps, the set-up work that
// applies to the whole line, and the measurement of the actual
// character. Functions like coordsChar, that need to do a lot of
// measurements in a row, can thus ensure that the set-up work is
// only done once.
function prepareMeasureForLine(cm, line) {
var lineN = lineNo(line);
var view = findViewForLine(cm, lineN);
if (view && !view.text)
view = null;
else if (view && view.changes)
updateLineForChanges(cm, view, lineN, getDimensions(cm));
if (!view)
view = updateExternalMeasurement(cm, line);
var info = mapFromLineView(view, line, lineN);
return {
line: line, view: view, rect: null,
map: info.map, cache: info.cache, before: info.before,
hasHeights: false
};
}
// Given a prepared measurement object, measures the position of an
// actual character (or fetches it from the cache).
function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
if (prepared.before) ch = -1;
var key = ch + (bias || ""), found;
if (prepared.cache.hasOwnProperty(key)) {
found = prepared.cache[key];
} else {
if (!prepared.rect)
prepared.rect = prepared.view.text.getBoundingClientRect();
if (!prepared.hasHeights) {
ensureLineHeights(cm, prepared.view, prepared.rect);
prepared.hasHeights = true;
}
found = measureCharInner(cm, prepared, ch, bias);
if (!found.bogus) prepared.cache[key] = found;
}
return {left: found.left, right: found.right,
top: varHeight ? found.rtop : found.top,
bottom: varHeight ? found.rbottom : found.bottom};
}
var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
function measureCharInner(cm, prepared, ch, bias) {
var map = prepared.map;
var node, start, end, collapse;
// First, search the line map for the text node corresponding to,
// or closest to, the target character.
for (var i = 0; i < map.length; i += 3) {
var mStart = map[i], mEnd = map[i + 1];
if (ch < mStart) {
start = 0; end = 1;
collapse = "left";
} else if (ch < mEnd) {
start = ch - mStart;
end = start + 1;
} else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
end = mEnd - mStart;
start = end - 1;
if (ch >= mEnd) collapse = "right";
}
if (start != null) {
node = map[i + 2];
if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
collapse = bias;
if (bias == "left" && start == 0)
while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
node = map[(i -= 3) + 2];
collapse = "left";
}
if (bias == "right" && start == mEnd - mStart)
while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
node = map[(i += 3) + 2];
collapse = "right";
}
break;
}
}
var rect;
if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
rect = node.parentNode.getBoundingClientRect();
} else if (ie && cm.options.lineWrapping) {
var rects = range(node, start, end).getClientRects();
if (rects.length)
rect = rects[bias == "right" ? rects.length - 1 : 0];
else
rect = nullRect;
} else {
rect = range(node, start, end).getBoundingClientRect() || nullRect;
}
if (rect.left || rect.right || start == 0) break;
end = start;
start = start - 1;
collapse = "right";
}
if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
} else { // If it is a widget, simply get the box for the whole widget.
if (start > 0) collapse = bias = "right";
var rects;
if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
rect = rects[bias == "right" ? rects.length - 1 : 0];
else
rect = node.getBoundingClientRect();
}
if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
var rSpan = node.parentNode.getClientRects()[0];
if (rSpan)
rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
else
rect = nullRect;
}
var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
var mid = (rtop + rbot) / 2;
var heights = prepared.view.measure.heights;
for (var i = 0; i < heights.length - 1; i++)
if (mid < heights[i]) break;
var top = i ? heights[i - 1] : 0, bot = heights[i];
var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
top: top, bottom: bot};
if (!rect.left && !rect.right) result.bogus = true;
if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
return result;
}
// Work around problem with bounding client rects on ranges being
// returned incorrectly when zoomed on IE10 and below.
function maybeUpdateRectForZooming(measure, rect) {
if (!window.screen || screen.logicalXDPI == null ||
screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
return rect;
var scaleX = screen.logicalXDPI / screen.deviceXDPI;
var scaleY = screen.logicalYDPI / screen.deviceYDPI;
return {left: rect.left * scaleX, right: rect.right * scaleX,
top: rect.top * scaleY, bottom: rect.bottom * scaleY};
}
function clearLineMeasurementCacheFor(lineView) {
if (lineView.measure) {
lineView.measure.cache = {};
lineView.measure.heights = null;
if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
lineView.measure.caches[i] = {};
}
}
function clearLineMeasurementCache(cm) {
cm.display.externalMeasure = null;
removeChildren(cm.display.lineMeasure);
for (var i = 0; i < cm.display.view.length; i++)
clearLineMeasurementCacheFor(cm.display.view[i]);
}
function clearCaches(cm) {
clearLineMeasurementCache(cm);
cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
cm.display.lineNumChars = null;
}
function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
// Converts a {top, bottom, left, right} box from line-local
// coordinates into another coordinate system. Context may be one of
// "line", "div" (display.lineDiv), "local"/null (editor), "window",
// or "page".
function intoCoordSystem(cm, lineObj, rect, context) {
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
var size = widgetHeight(lineObj.widgets[i]);
rect.top += size; rect.bottom += size;
}
if (context == "line") return rect;
if (!context) context = "local";
var yOff = heightAtLine(lineObj);
if (context == "local") yOff += paddingTop(cm.display);
else yOff -= cm.display.viewOffset;
if (context == "page" || context == "window") {
var lOff = cm.display.lineSpace.getBoundingClientRect();
yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
rect.left += xOff; rect.right += xOff;
}
rect.top += yOff; rect.bottom += yOff;
return rect;
}
// Coverts a box from "div" coords to another coordinate system.
// Context may be "window", "page", "div", or "local"/null.
function fromCoordSystem(cm, coords, context) {
if (context == "div") return coords;
var left = coords.left, top = coords.top;
// First move into "page" coordinate system
if (context == "page") {
left -= pageScrollX();
top -= pageScrollY();
} else if (context == "local" || !context) {
var localBox = cm.display.sizer.getBoundingClientRect();
left += localBox.left;
top += localBox.top;
}
var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
}
function charCoords(cm, pos, context, lineObj, bias) {
if (!lineObj) lineObj = getLine(cm.doc, pos.line);
return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
}
// Returns a box for a given cursor position, which may have an
// 'other' property containing the position of the secondary cursor
// on a bidi boundary.
function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
lineObj = lineObj || getLine(cm.doc, pos.line);
if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
function get(ch, right) {
var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
if (right) m.left = m.right; else m.right = m.left;
return intoCoordSystem(cm, lineObj, m, context);
}
function getBidi(ch, partPos) {
var part = order[partPos], right = part.level % 2;
if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
part = order[--partPos];
ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
right = true;
} else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
part = order[++partPos];
ch = bidiLeft(part) - part.level % 2;
right = false;
}
if (right && ch == part.to && ch > part.from) return get(ch - 1);
return get(ch, right);
}
var order = getOrder(lineObj), ch = pos.ch;
if (!order) return get(ch);
var partPos = getBidiPartAt(order, ch);
var val = getBidi(ch, partPos);
if (bidiOther != null) val.other = getBidi(ch, bidiOther);
return val;
}
// Used to cheaply estimate the coordinates for a position. Used for
// intermediate scroll updates.
function estimateCoords(cm, pos) {
var left = 0, pos = clipPos(cm.doc, pos);
if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
var lineObj = getLine(cm.doc, pos.line);
var top = heightAtLine(lineObj) + paddingTop(cm.display);
return {left: left, right: left, top: top, bottom: top + lineObj.height};
}
// Positions returned by coordsChar contain some extra information.
// xRel is the relative x position of the input coordinates compared
// to the found position (so xRel > 0 means the coordinates are to
// the right of the character position, for example). When outside
// is true, that means the coordinates lie outside the line's
// vertical range.
function PosWithInfo(line, ch, outside, xRel) {
var pos = Pos(line, ch);
pos.xRel = xRel;
if (outside) pos.outside = true;
return pos;
}
// Compute the character position closest to the given coordinates.
// Input must be lineSpace-local ("div" coordinate system).
function coordsChar(cm, x, y) {
var doc = cm.doc;
y += cm.display.viewOffset;
if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
if (lineN > last)
return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
if (x < 0) x = 0;
var lineObj = getLine(doc, lineN);
for (;;) {
var found = coordsCharInner(cm, lineObj, lineN, x, y);
var merged = collapsedSpanAtEnd(lineObj);
var mergedPos = merged && merged.find(0, true);
if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
lineN = lineNo(lineObj = mergedPos.to.line);
else
return found;
}
}
function coordsCharInner(cm, lineObj, lineNo, x, y) {
var innerOff = y - heightAtLine(lineObj);
var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
var preparedMeasure = prepareMeasureForLine(cm, lineObj);
function getX(ch) {
var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
wrongLine = true;
if (innerOff > sp.bottom) return sp.left - adjust;
else if (innerOff < sp.top) return sp.left + adjust;
else wrongLine = false;
return sp.left;
}
var bidi = getOrder(lineObj), dist = lineObj.text.length;
var from = lineLeft(lineObj), to = lineRight(lineObj);
var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
// Do a binary search between these bounds.
for (;;) {
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
var ch = x < fromX || x - fromX <= toX - x ? from : to;
var xDiff = x - (ch == from ? fromX : toX);
while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
return pos;
}
var step = Math.ceil(dist / 2), middle = from + step;
if (bidi) {
middle = from;
for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
}
var middleX = getX(middle);
if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
}
}
var measureText;
// Compute the default text height.
function textHeight(display) {
if (display.cachedTextHeight != null) return display.cachedTextHeight;
if (measureText == null) {
measureText = elt("pre");
// Measure a bunch of lines, for browsers that compute
// fractional heights.
for (var i = 0; i < 49; ++i) {
measureText.appendChild(document.createTextNode("x"));
measureText.appendChild(elt("br"));
}
measureText.appendChild(document.createTextNode("x"));
}
removeChildrenAndAdd(display.measure, measureText);
var height = measureText.offsetHeight / 50;
if (height > 3) display.cachedTextHeight = height;
removeChildren(display.measure);
return height || 1;
}
// Compute the default character width.
function charWidth(display) {
if (display.cachedCharWidth != null) return display.cachedCharWidth;
var anchor = elt("span", "xxxxxxxxxx");
var pre = elt("pre", [anchor]);
removeChildrenAndAdd(display.measure, pre);
var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
if (width > 2) display.cachedCharWidth = width;
return width || 10;
}
// OPERATIONS
// Operations are used to wrap a series of changes to the editor
// state in such a way that each change won't have to update the
// cursor and display (which would be awkward, slow, and
// error-prone). Instead, display updates are batched and then all
// combined and executed at once.
var operationGroup = null;
var nextOpId = 0;
// Start a new operation.
function startOperation(cm) {
cm.curOp = {
cm: cm,
viewChanged: false, // Flag that indicates that lines might need to be redrawn
startHeight: cm.doc.height, // Used to detect need to update scrollbar
forceUpdate: false, // Used to force a redraw
updateInput: null, // Whether to reset the input textarea
typing: false, // Whether this reset should be careful to leave existing text (for compositing)
changeObjs: null, // Accumulated changes, for firing change events
cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
selectionChanged: false, // Whether the selection needs to be redrawn
updateMaxLine: false, // Set when the widest line needs to be determined anew
scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
scrollToPos: null, // Used to scroll to a specific position
id: ++nextOpId // Unique ID
};
if (operationGroup) {
operationGroup.ops.push(cm.curOp);
} else {
cm.curOp.ownsGroup = operationGroup = {
ops: [cm.curOp],
delayedCallbacks: []
};
}
}
function fireCallbacksForOps(group) {
// Calls delayed callbacks and cursorActivity handlers until no
// new ones appear
var callbacks = group.delayedCallbacks, i = 0;
do {
for (; i < callbacks.length; i++)
callbacks[i]();
for (var j = 0; j < group.ops.length; j++) {
var op = group.ops[j];
if (op.cursorActivityHandlers)
while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
}
} while (i < callbacks.length);
}
// Finish an operation, updating the display and signalling delayed events
function endOperation(cm) {
var op = cm.curOp, group = op.ownsGroup;
if (!group) return;
try { fireCallbacksForOps(group); }
finally {
operationGroup = null;
for (var i = 0; i < group.ops.length; i++)
group.ops[i].cm.curOp = null;
endOperations(group);
}
}
// The DOM updates done when an operation finishes are batched so
// that the minimum number of relayouts are required.
function endOperations(group) {
var ops = group.ops;
for (var i = 0; i < ops.length; i++) // Read DOM
endOperation_R1(ops[i]);
for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
endOperation_W1(ops[i]);
for (var i = 0; i < ops.length; i++) // Read DOM
endOperation_R2(ops[i]);
for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
endOperation_W2(ops[i]);
for (var i = 0; i < ops.length; i++) // Read DOM
endOperation_finish(ops[i]);
}
function endOperation_R1(op) {
var cm = op.cm, display = cm.display;
maybeClipScrollbars(cm);
if (op.updateMaxLine) findMaxLine(cm);
op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
op.scrollToPos.to.line >= display.viewTo) ||
display.maxLineChanged && cm.options.lineWrapping;
op.update = op.mustUpdate &&
new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
}
function endOperation_W1(op) {
op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
}
function endOperation_R2(op) {
var cm = op.cm, display = cm.display;
if (op.updatedDisplay) updateHeightsInViewport(cm);
op.barMeasure = measureForScrollbars(cm);
// If the max line changed since it was last measured, measure it,
// and ensure the document's width matches it.
// updateDisplay_W2 will use these properties to do the actual resizing
if (display.maxLineChanged && !cm.options.lineWrapping) {
op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
cm.display.sizerWidth = op.adjustWidthTo;
op.barMeasure.scrollWidth =
Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
}
if (op.updatedDisplay || op.selectionChanged)
op.newSelectionNodes = drawSelection(cm);
}
function endOperation_W2(op) {
var cm = op.cm;
if (op.adjustWidthTo != null) {
cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
if (op.maxScrollLeft < cm.doc.scrollLeft)
setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
cm.display.maxLineChanged = false;
}
if (op.newSelectionNodes)
showSelection(cm, op.newSelectionNodes);
if (op.updatedDisplay)
setDocumentHeight(cm, op.barMeasure);
if (op.updatedDisplay || op.startHeight != cm.doc.height)
updateScrollbars(cm, op.barMeasure);
if (op.selectionChanged) restartBlink(cm);
if (cm.state.focused && op.updateInput)
resetInput(cm, op.typing);
}
function endOperation_finish(op) {
var cm = op.cm, display = cm.display, doc = cm.doc;
if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
// Abort mouse wheel delta measurement, when scrolling explicitly
if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
display.wheelStartX = display.wheelStartY = null;
// Propagate the scroll position to the actual DOM scroller
if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
display.scrollbars.setScrollTop(doc.scrollTop);
display.scroller.scrollTop = doc.scrollTop;
}
if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));
display.scrollbars.setScrollLeft(doc.scrollLeft);
display.scroller.scrollLeft = doc.scrollLeft;
alignHorizontally(cm);
}
// If we need to scroll a specific position into view, do so.
if (op.scrollToPos) {
var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
}
// Fire events for markers that are hidden/unidden by editing or
// undoing
var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
if (hidden) for (var i = 0; i < hidden.length; ++i)
if (!hidden[i].lines.length) signal(hidden[i], "hide");
if (unhidden) for (var i = 0; i < unhidden.length; ++i)
if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
if (display.wrapper.offsetHeight)
doc.scrollTop = cm.display.scroller.scrollTop;
// Fire change events, and delayed event handlers
if (op.changeObjs)
signal(cm, "changes", cm, op.changeObjs);
}
// Run the given function in an operation
function runInOp(cm, f) {
if (cm.curOp) return f();
startOperation(cm);
try { return f(); }
finally { endOperation(cm); }
}
// Wraps a function in an operation. Returns the wrapped function.
function operation(cm, f) {
return function() {
if (cm.curOp) return f.apply(cm, arguments);
startOperation(cm);
try { return f.apply(cm, arguments); }
finally { endOperation(cm); }
};
}
// Used to add methods to editor and doc instances, wrapping them in
// operations.
function methodOp(f) {
return function() {
if (this.curOp) return f.apply(this, arguments);
startOperation(this);
try { return f.apply(this, arguments); }
finally { endOperation(this); }
};
}
function docMethodOp(f) {
return function() {
var cm = this.cm;
if (!cm || cm.curOp) return f.apply(this, arguments);
startOperation(cm);
try { return f.apply(this, arguments); }
finally { endOperation(cm); }
};
}
// VIEW TRACKING
// These objects are used to represent the visible (currently drawn)
// part of the document. A LineView may correspond to multiple
// logical lines, if those are connected by collapsed ranges.
function LineView(doc, line, lineN) {
// The starting line
this.line = line;
// Continuing lines, if any
this.rest = visualLineContinued(line);
// Number of logical lines in this visual line
this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
this.node = this.text = null;
this.hidden = lineIsHidden(doc, line);
}
// Create a range of LineView objects for the given lines.
function buildViewArray(cm, from, to) {
var array = [], nextPos;
for (var pos = from; pos < to; pos = nextPos) {
var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
nextPos = pos + view.size;
array.push(view);
}
return array;
}
// Updates the display.view data structure for a given change to the
// document. From and to are in pre-change coordinates. Lendiff is
// the amount of lines added or subtracted by the change. This is
// used for changes that span multiple lines, or change the way
// lines are divided into visual lines. regLineChange (below)
// registers single-line changes.
function regChange(cm, from, to, lendiff) {
if (from == null) from = cm.doc.first;
if (to == null) to = cm.doc.first + cm.doc.size;
if (!lendiff) lendiff = 0;
var display = cm.display;
if (lendiff && to < display.viewTo &&
(display.updateLineNumbers == null || display.updateLineNumbers > from))
display.updateLineNumbers = from;
cm.curOp.viewChanged = true;
if (from >= display.viewTo) { // Change after
if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
resetView(cm);
} else if (to <= display.viewFrom) { // Change before
if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
resetView(cm);
} else {
display.viewFrom += lendiff;
display.viewTo += lendiff;
}
} else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
resetView(cm);
} else if (from <= display.viewFrom) { // Top overlap
var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
if (cut) {
display.view = display.view.slice(cut.index);
display.viewFrom = cut.lineN;
display.viewTo += lendiff;
} else {
resetView(cm);
}
} else if (to >= display.viewTo) { // Bottom overlap
var cut = viewCuttingPoint(cm, from, from, -1);
if (cut) {
display.view = display.view.slice(0, cut.index);
display.viewTo = cut.lineN;
} else {
resetView(cm);
}
} else { // Gap in the middle
var cutTop = viewCuttingPoint(cm, from, from, -1);
var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
if (cutTop && cutBot) {
display.view = display.view.slice(0, cutTop.index)
.concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
.concat(display.view.slice(cutBot.index));
display.viewTo += lendiff;
} else {
resetView(cm);
}
}
var ext = display.externalMeasured;
if (ext) {
if (to < ext.lineN)
ext.lineN += lendiff;
else if (from < ext.lineN + ext.size)
display.externalMeasured = null;
}
}
// Register a change to a single line. Type must be one of "text",
// "gutter", "class", "widget"
function regLineChange(cm, line, type) {
cm.curOp.viewChanged = true;
var display = cm.display, ext = cm.display.externalMeasured;
if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
display.externalMeasured = null;
if (line < display.viewFrom || line >= display.viewTo) return;
var lineView = display.view[findViewIndex(cm, line)];
if (lineView.node == null) return;
var arr = lineView.changes || (lineView.changes = []);
if (indexOf(arr, type) == -1) arr.push(type);
}
// Clear the view.
function resetView(cm) {
cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
cm.display.view = [];
cm.display.viewOffset = 0;
}
// Find the view element corresponding to a given line. Return null
// when the line isn't visible.
function findViewIndex(cm, n) {
if (n >= cm.display.viewTo) return null;
n -= cm.display.viewFrom;
if (n < 0) return null;
var view = cm.display.view;
for (var i = 0; i < view.length; i++) {
n -= view[i].size;
if (n < 0) return i;
}
}
function viewCuttingPoint(cm, oldN, newN, dir) {
var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
return {index: index, lineN: newN};
for (var i = 0, n = cm.display.viewFrom; i < index; i++)
n += view[i].size;
if (n != oldN) {
if (dir > 0) {
if (index == view.length - 1) return null;
diff = (n + view[index].size) - oldN;
index++;
} else {
diff = n - oldN;
}
oldN += diff; newN += diff;
}
while (visualLineNo(cm.doc, newN) != newN) {
if (index == (dir < 0 ? 0 : view.length - 1)) return null;
newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
index += dir;
}
return {index: index, lineN: newN};
}
// Force the view to cover a given range, adding empty view element
// or clipping off existing ones as needed.
function adjustView(cm, from, to) {
var display = cm.display, view = display.view;
if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
display.view = buildViewArray(cm, from, to);
display.viewFrom = from;
} else {
if (display.viewFrom > from)
display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
else if (display.viewFrom < from)
display.view = display.view.slice(findViewIndex(cm, from));
display.viewFrom = from;
if (display.viewTo < to)
display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
else if (display.viewTo > to)
display.view = display.view.slice(0, findViewIndex(cm, to));
}
display.viewTo = to;
}
// Count the number of lines in the view whose DOM representation is
// out of date (or nonexistent).
function countDirtyView(cm) {
var view = cm.display.view, dirty = 0;
for (var i = 0; i < view.length; i++) {
var lineView = view[i];
if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
}
return dirty;
}
// INPUT HANDLING
// Poll for input changes, using the normal rate of polling. This
// runs as long as the editor is focused.
function slowPoll(cm) {
if (cm.display.pollingFast) return;
cm.display.poll.set(cm.options.pollInterval, function() {
readInput(cm);
if (cm.state.focused) slowPoll(cm);
});
}
// When an event has just come in that is likely to add or change
// something in the input textarea, we poll faster, to ensure that
// the change appears on the screen quickly.
function fastPoll(cm) {
var missed = false;
cm.display.pollingFast = true;
function p() {
var changed = readInput(cm);
if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
else {cm.display.pollingFast = false; slowPoll(cm);}
}
cm.display.poll.set(20, p);
}
// This will be set to an array of strings when copying, so that,
// when pasting, we know what kind of selections the copied text
// was made out of.
var lastCopied = null;
// Read input from the textarea, and update the document to match.
// When something is selected, it is present in the textarea, and
// selected (unless it is huge, in which case a placeholder is
// used). When nothing is selected, the cursor sits after previously
// seen text (can be empty), which is stored in prevInput (we must
// not reset the textarea when typing, because that breaks IME).
function readInput(cm) {
var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
// Since this is called a *lot*, try to bail out as cheaply as
// possible when it is clear that nothing happened. hasSelection
// will be the case when there is a lot of text in the textarea,
// in which case reading its value would be expensive.
if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
return false;
// See paste handler for more on the fakedLastChar kludge
if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
input.value = input.value.substring(0, input.value.length - 1);
cm.state.fakedLastChar = false;
}
var text = input.value;
// If nothing changed, bail.
if (text == prevInput && !cm.somethingSelected()) return false;
// Work around nonsensical selection resetting in IE9/10, and
// inexplicable appearance of private area unicode characters on
// some key combos in Mac (#2689).
if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||
mac && /[\uf700-\uf7ff]/.test(text)) {
resetInput(cm);
return false;
}
var withOp = !cm.curOp;
if (withOp) startOperation(cm);
cm.display.shift = false;
if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
prevInput = "\u200b";
// Find the part of the input that is actually new
var same = 0, l = Math.min(prevInput.length, text.length);
while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
var inserted = text.slice(same), textLines = splitLines(inserted);
// When pasing N lines into N selections, insert one line per selection
var multiPaste = null;
if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {
if (lastCopied && lastCopied.join("\n") == inserted)
multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
else if (textLines.length == doc.sel.ranges.length)
multiPaste = map(textLines, function(l) { return [l]; });
}
// Normal behavior is to insert the new text into every selection
for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
var range = doc.sel.ranges[i];
var from = range.from(), to = range.to();
// Handle deletion
if (same < prevInput.length)
from = Pos(from.line, from.ch - (prevInput.length - same));
// Handle overwrite
else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
var updateInput = cm.curOp.updateInput;
var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
makeChange(cm.doc, changeEvent);
signalLater(cm, "inputRead", cm, changeEvent);
// When an 'electric' character is inserted, immediately trigger a reindent
if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
cm.options.smartIndent && range.head.ch < 100 &&
(!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
var mode = cm.getModeAt(range.head);
var end = changeEnd(changeEvent);
if (mode.electricChars) {
for (var j = 0; j < mode.electricChars.length; j++)
if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
indentLine(cm, end.line, "smart");
break;
}
} else if (mode.electricInput) {
if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
indentLine(cm, end.line, "smart");
}
}
}
ensureCursorVisible(cm);
cm.curOp.updateInput = updateInput;
cm.curOp.typing = true;
// Don't leave long text in the textarea, since it makes further polling slow
if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
else cm.display.prevInput = text;
if (withOp) endOperation(cm);
cm.state.pasteIncoming = cm.state.cutIncoming = false;
return true;
}
// Reset the input to correspond to the selection (or to be empty,
// when not typing and nothing is selected)
function resetInput(cm, typing) {
if (cm.display.contextMenuPending) return;
var minimal, selected, doc = cm.doc;
if (cm.somethingSelected()) {
cm.display.prevInput = "";
var range = doc.sel.primary();
minimal = hasCopyEvent &&
(range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
var content = minimal ? "-" : selected || cm.getSelection();
cm.display.input.value = content;
if (cm.state.focused) selectInput(cm.display.input);
if (ie && ie_version >= 9) cm.display.inputHasSelection = content;
} else if (!typing) {
cm.display.prevInput = cm.display.input.value = "";
if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
}
cm.display.inaccurateSelection = minimal;
}
function focusInput(cm) {
if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
cm.display.input.focus();
}
function ensureFocus(cm) {
if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
}
function isReadOnly(cm) {
return cm.options.readOnly || cm.doc.cantEdit;
}
// EVENT HANDLERS
// Attach the necessary event handlers when initializing the editor
function registerEventHandlers(cm) {
var d = cm.display;
on(d.scroller, "mousedown", operation(cm, onMouseDown));
// Older IE's will not fire a second mousedown for a double click
if (ie && ie_version < 11)
on(d.scroller, "dblclick", operation(cm, function(e) {
if (signalDOMEvent(cm, e)) return;
var pos = posFromMouse(cm, e);
if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
e_preventDefault(e);
var word = cm.findWordAt(pos);
extendSelection(cm.doc, word.anchor, word.head);
}));
else
on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
// Prevent normal selection in the editor (we handle our own)
on(d.lineSpace, "selectstart", function(e) {
if (!eventInWidget(d, e)) e_preventDefault(e);
});
// Some browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for these browsers.
if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
// Sync scrolling between fake scrollbars and real scrollable
// area, ensure viewport is updated when scrolling.
on(d.scroller, "scroll", function() {
if (d.scroller.clientHeight) {
setScrollTop(cm, d.scroller.scrollTop);
setScrollLeft(cm, d.scroller.scrollLeft, true);
signal(cm, "scroll", cm);
}
});
// Listen to wheel events in order to try and update the viewport on time.
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
// Prevent wrapper from ever scrolling
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
on(d.input, "input", function() {
if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
readInput(cm);
});
on(d.input, "keydown", operation(cm, onKeyDown));
on(d.input, "keypress", operation(cm, onKeyPress));
on(d.input, "focus", bind(onFocus, cm));
on(d.input, "blur", bind(onBlur, cm));
function drag_(e) {
if (!signalDOMEvent(cm, e)) e_stop(e);
}
if (cm.options.dragDrop) {
on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
on(d.scroller, "dragenter", drag_);
on(d.scroller, "dragover", drag_);
on(d.scroller, "drop", operation(cm, onDrop));
}
on(d.scroller, "paste", function(e) {
if (eventInWidget(d, e)) return;
cm.state.pasteIncoming = true;
focusInput(cm);
fastPoll(cm);
});
on(d.input, "paste", function() {
// Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
// Add a char to the end of textarea before paste occur so that
// selection doesn't span to the end of textarea.
if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
var start = d.input.selectionStart, end = d.input.selectionEnd;
d.input.value += "$";
// The selection end needs to be set before the start, otherwise there
// can be an intermediate non-empty selection between the two, which
// can override the middle-click paste buffer on linux and cause the
// wrong thing to get pasted.
d.input.selectionEnd = end;
d.input.selectionStart = start;
cm.state.fakedLastChar = true;
}
cm.state.pasteIncoming = true;
fastPoll(cm);
});
function prepareCopyCut(e) {
if (cm.somethingSelected()) {
lastCopied = cm.getSelections();
if (d.inaccurateSelection) {
d.prevInput = "";
d.inaccurateSelection = false;
d.input.value = lastCopied.join("\n");
selectInput(d.input);
}
} else {
var text = [], ranges = [];
for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
var line = cm.doc.sel.ranges[i].head.line;
var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
ranges.push(lineRange);
text.push(cm.getRange(lineRange.anchor, lineRange.head));
}
if (e.type == "cut") {
cm.setSelections(ranges, null, sel_dontScroll);
} else {
d.prevInput = "";
d.input.value = text.join("\n");
selectInput(d.input);
}
lastCopied = text;
}
if (e.type == "cut") cm.state.cutIncoming = true;
}
on(d.input, "cut", prepareCopyCut);
on(d.input, "copy", prepareCopyCut);
// Needed to handle Tab key in KHTML
if (khtml) on(d.sizer, "mouseup", function() {
if (activeElt() == d.input) d.input.blur();
focusInput(cm);
});
}
// Called when the window resizes
function onResize(cm) {
var d = cm.display;
if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
return;
// Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
d.scrollbarsClipped = false;
cm.setSize();
}
// MOUSE EVENTS
// Return true when the given mouse event happened in a widget
function eventInWidget(display, e) {
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
(n.parentNode == display.sizer && n != display.mover))
return true;
}
}
// Given a mouse event, find the corresponding position. If liberal
// is false, it checks whether a gutter or scrollbar was clicked,
// and returns null if it was. forRect is used by rectangular
// selections, and tries to estimate a character position even for
// coordinates beyond the right of the text.
function posFromMouse(cm, e, liberal, forRect) {
var display = cm.display;
if (!liberal && e_target(e).getAttribute("not-content") == "true") return null;
var x, y, space = display.lineSpace.getBoundingClientRect();
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
try { x = e.clientX - space.left; y = e.clientY - space.top; }
catch (e) { return null; }
var coords = coordsChar(cm, x, y), line;
if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
}
return coords;
}
// A mouse down can be a single click, double click, triple click,
// start of selection drag, start of text drag, new cursor
// (ctrl-click), rectangle drag (alt-drag), or xwin
// middle-click-paste. Or it might be a click on something we should
// not interfere with, such as a scrollbar or widget.
function onMouseDown(e) {
if (signalDOMEvent(this, e)) return;
var cm = this, display = cm.display;
display.shift = e.shiftKey;
if (eventInWidget(display, e)) {
if (!webkit) {
// Briefly turn off draggability, to allow widgets to do
// normal dragging things.
display.scroller.draggable = false;
setTimeout(function(){display.scroller.draggable = true;}, 100);
}
return;
}
if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
window.focus();
switch (e_button(e)) {
case 1:
if (start)
leftButtonDown(cm, e, start);
else if (e_target(e) == display.scroller)
e_preventDefault(e);
break;
case 2:
if (webkit) cm.state.lastMiddleDown = +new Date;
if (start) extendSelection(cm.doc, start);
setTimeout(bind(focusInput, cm), 20);
e_preventDefault(e);
break;
case 3:
if (captureRightClick) onContextMenu(cm, e);
break;
}
}
var lastClick, lastDoubleClick;
function leftButtonDown(cm, e, start) {
setTimeout(bind(ensureFocus, cm), 0);
var now = +new Date, type;
if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
type = "triple";
} else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
type = "double";
lastDoubleClick = {time: now, pos: start};
} else {
type = "single";
lastClick = {time: now, pos: start};
}
var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
type == "single" && (contained = sel.contains(start)) > -1 &&
!sel.ranges[contained].empty())
leftButtonStartDrag(cm, e, start, modifier);
else
leftButtonSelect(cm, e, start, type, modifier);
}
// Start a text drag. When it ends, see if any dragging actually
// happen, and treat as a click if it didn't.
function leftButtonStartDrag(cm, e, start, modifier) {
var display = cm.display;
var dragEnd = operation(cm, function(e2) {
if (webkit) display.scroller.draggable = false;
cm.state.draggingText = false;
off(document, "mouseup", dragEnd);
off(display.scroller, "drop", dragEnd);
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
e_preventDefault(e2);
if (!modifier)
extendSelection(cm.doc, start);
focusInput(cm);
// Work around unexplainable focus problem in IE9 (#2127)
if (ie && ie_version == 9)
setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
}
});
// Let the drag handler handle this.
if (webkit) display.scroller.draggable = true;
cm.state.draggingText = dragEnd;
// IE's approach to draggable
if (display.scroller.dragDrop) display.scroller.dragDrop();
on(document, "mouseup", dragEnd);
on(display.scroller, "drop", dragEnd);
}
// Normal selection, as opposed to text dragging.
function leftButtonSelect(cm, e, start, type, addNew) {
var display = cm.display, doc = cm.doc;
e_preventDefault(e);
var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
if (addNew && !e.shiftKey) {
ourIndex = doc.sel.contains(start);
if (ourIndex > -1)
ourRange = ranges[ourIndex];
else
ourRange = new Range(start, start);
} else {
ourRange = doc.sel.primary();
}
if (e.altKey) {
type = "rect";
if (!addNew) ourRange = new Range(start, start);
start = posFromMouse(cm, e, true, true);
ourIndex = -1;
} else if (type == "double") {
var word = cm.findWordAt(start);
if (cm.display.shift || doc.extend)
ourRange = extendRange(doc, ourRange, word.anchor, word.head);
else
ourRange = word;
} else if (type == "triple") {
var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
if (cm.display.shift || doc.extend)
ourRange = extendRange(doc, ourRange, line.anchor, line.head);
else
ourRange = line;
} else {
ourRange = extendRange(doc, ourRange, start);
}
if (!addNew) {
ourIndex = 0;
setSelection(doc, new Selection([ourRange], 0), sel_mouse);
startSel = doc.sel;
} else if (ourIndex == -1) {
ourIndex = ranges.length;
setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
{scroll: false, origin: "*mouse"});
} else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single") {
setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));
startSel = doc.sel;
} else {
replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
}
var lastPos = start;
function extendTo(pos) {
if (cmp(lastPos, pos) == 0) return;
lastPos = pos;
if (type == "rect") {
var ranges = [], tabSize = cm.options.tabSize;
var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
line <= end; line++) {
var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
if (left == right)
ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
else if (text.length > leftPos)
ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
}
if (!ranges.length) ranges.push(new Range(start, start));
setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
{origin: "*mouse", scroll: false});
cm.scrollIntoView(pos);
} else {
var oldRange = ourRange;
var anchor = oldRange.anchor, head = pos;
if (type != "single") {
if (type == "double")
var range = cm.findWordAt(pos);
else
var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
if (cmp(range.anchor, anchor) > 0) {
head = range.head;
anchor = minPos(oldRange.from(), range.anchor);
} else {
head = range.anchor;
anchor = maxPos(oldRange.to(), range.head);
}
}
var ranges = startSel.ranges.slice(0);
ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
}
}
var editorSize = display.wrapper.getBoundingClientRect();
// Used to ensure timeout re-tries don't fire when another extend
// happened in the meantime (clearTimeout isn't reliable -- at
// least on Chrome, the timeouts still happen even when cleared,
// if the clear happens after their scheduled firing time).
var counter = 0;
function extend(e) {
var curCount = ++counter;
var cur = posFromMouse(cm, e, true, type == "rect");
if (!cur) return;
if (cmp(cur, lastPos) != 0) {
ensureFocus(cm);
extendTo(cur);
var visible = visibleLines(display, doc);
if (cur.line >= visible.to || cur.line < visible.from)
setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
} else {
var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
if (outside) setTimeout(operation(cm, function() {
if (counter != curCount) return;
display.scroller.scrollTop += outside;
extend(e);
}), 50);
}
}
function done(e) {
counter = Infinity;
e_preventDefault(e);
focusInput(cm);
off(document, "mousemove", move);
off(document, "mouseup", up);
doc.history.lastSelOrigin = null;
}
var move = operation(cm, function(e) {
if (!e_button(e)) done(e);
else extend(e);
});
var up = operation(cm, done);
on(document, "mousemove", move);
on(document, "mouseup", up);
}
// Determines whether an event happened in the gutter, and fires the
// handlers for the corresponding event.
function gutterEvent(cm, e, type, prevent, signalfn) {
try { var mX = e.clientX, mY = e.clientY; }
catch(e) { return false; }
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
if (prevent) e_preventDefault(e);
var display = cm.display;
var lineBox = display.lineDiv.getBoundingClientRect();
if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
mY -= lineBox.top - display.viewOffset;
for (var i = 0; i < cm.options.gutters.length; ++i) {
var g = display.gutters.childNodes[i];
if (g && g.getBoundingClientRect().right >= mX) {
var line = lineAtHeight(cm.doc, mY);
var gutter = cm.options.gutters[i];
signalfn(cm, type, cm, line, gutter, e);
return e_defaultPrevented(e);
}
}
}
function clickInGutter(cm, e) {
return gutterEvent(cm, e, "gutterClick", true, signalLater);
}
// Kludge to work around strange IE behavior where it'll sometimes
// re-fire a series of drag-related events right after the drop (#1551)
var lastDrop = 0;
function onDrop(e) {
var cm = this;
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
return;
e_preventDefault(e);
if (ie) lastDrop = +new Date;
var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
if (!pos || isReadOnly(cm)) return;
// Might be a file drop, in which case we simply extract the text
// and insert it.
if (files && files.length && window.FileReader && window.File) {
var n = files.length, text = Array(n), read = 0;
var loadFile = function(file, i) {
var reader = new FileReader;
reader.onload = operation(cm, function() {
text[i] = reader.result;
if (++read == n) {
pos = clipPos(cm.doc, pos);
var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
makeChange(cm.doc, change);
setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
}
});
reader.readAsText(file);
};
for (var i = 0; i < n; ++i) loadFile(files[i], i);
} else { // Normal drop
// Don't do a replace if the drop happened inside of the selected text.
if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
cm.state.draggingText(e);
// Ensure the editor is re-focused
setTimeout(bind(focusInput, cm), 20);
return;
}
try {
var text = e.dataTransfer.getData("Text");
if (text) {
if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
var selected = cm.listSelections();
setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
if (selected) for (var i = 0; i < selected.length; ++i)
replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
cm.replaceSelection(text, "around", "paste");
focusInput(cm);
}
}
catch(e){}
}
}
function onDragStart(cm, e) {
if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
e.dataTransfer.setData("Text", cm.getSelection());
// Use dummy image instead of default browsers image.
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
if (e.dataTransfer.setDragImage && !safari) {
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
if (presto) {
img.width = img.height = 1;
cm.display.wrapper.appendChild(img);
// Force a relayout, or Opera won't use our image for some obscure reason
img._top = img.offsetTop;
}
e.dataTransfer.setDragImage(img, 0, 0);
if (presto) img.parentNode.removeChild(img);
}
}
// SCROLL EVENTS
// Sync the scrollable area and scrollbars, ensure the viewport
// covers the visible area.
function setScrollTop(cm, val) {
if (Math.abs(cm.doc.scrollTop - val) < 2) return;
cm.doc.scrollTop = val;
if (!gecko) updateDisplaySimple(cm, {top: val});
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
cm.display.scrollbars.setScrollTop(val);
if (gecko) updateDisplaySimple(cm);
startWorker(cm, 100);
}
// Sync scroller and scrollbar, ensure the gutter elements are
// aligned.
function setScrollLeft(cm, val, isScroller) {
if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
cm.doc.scrollLeft = val;
alignHorizontally(cm);
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
cm.display.scrollbars.setScrollLeft(val);
}
// Since the delta values reported on mouse wheel events are
// unstandardized between browsers and even browser versions, and
// generally horribly unpredictable, this code starts by measuring
// the scroll effect that the first few mouse wheel events have,
// and, from that, detects the way it can convert deltas to pixel
// offsets afterwards.
//
// The reason we want to know the amount a wheel event will scroll
// is that it gives us a chance to update the display before the
// actual scrolling happens, reducing flickering.
var wheelSamples = 0, wheelPixelsPerUnit = null;
// Fill in a browser-detected starting value on browsers where we
// know one. These don't have to be accurate -- the result of them
// being wrong would just be a slight flicker on the first wheel
// scroll (if it is large enough).
if (ie) wheelPixelsPerUnit = -.53;
else if (gecko) wheelPixelsPerUnit = 15;
else if (chrome) wheelPixelsPerUnit = -.7;
else if (safari) wheelPixelsPerUnit = -1/3;
var wheelEventDelta = function(e) {
var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
else if (dy == null) dy = e.wheelDelta;
return {x: dx, y: dy};
};
CodeMirror.wheelEventPixels = function(e) {
var delta = wheelEventDelta(e);
delta.x *= wheelPixelsPerUnit;
delta.y *= wheelPixelsPerUnit;
return delta;
};
function onScrollWheel(cm, e) {
var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
var display = cm.display, scroll = display.scroller;
// Quit if there's nothing to scroll here
if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
dy && scroll.scrollHeight > scroll.clientHeight)) return;
// Webkit browsers on OS X abort momentum scrolls when the target
// of the scroll event is removed from the scrollable element.
// This hack (see related code in patchDisplay) makes sure the
// element is kept around.
if (dy && mac && webkit) {
outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
for (var i = 0; i < view.length; i++) {
if (view[i].node == cur) {
cm.display.currentWheelTarget = cur;
break outer;
}
}
}
}
// On some browsers, horizontal scrolling will cause redraws to
// happen before the gutter has been realigned, causing it to
// wriggle around in a most unseemly way. When we have an
// estimated pixels/delta value, we just handle horizontal
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
if (dy)
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
e_preventDefault(e);
display.wheelStartX = null; // Abort measurement, if in progress
return;
}
// 'Project' the visible viewport to cover the area that is being
// scrolled into view (if we know enough to estimate it).
if (dy && wheelPixelsPerUnit != null) {
var pixels = dy * wheelPixelsPerUnit;
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
if (pixels < 0) top = Math.max(0, top + pixels - 50);
else bot = Math.min(cm.doc.height, bot + pixels + 50);
updateDisplaySimple(cm, {top: top, bottom: bot});
}
if (wheelSamples < 20) {
if (display.wheelStartX == null) {
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
display.wheelDX = dx; display.wheelDY = dy;
setTimeout(function() {
if (display.wheelStartX == null) return;
var movedX = scroll.scrollLeft - display.wheelStartX;
var movedY = scroll.scrollTop - display.wheelStartY;
var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
(movedX && display.wheelDX && movedX / display.wheelDX);
display.wheelStartX = display.wheelStartY = null;
if (!sample) return;
wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
++wheelSamples;
}, 200);
} else {
display.wheelDX += dx; display.wheelDY += dy;
}
}
}
// KEY EVENTS
// Run a handler that was bound to a key.
function doHandleBinding(cm, bound, dropShift) {
if (typeof bound == "string") {
bound = commands[bound];
if (!bound) return false;
}
// Ensure previous input has been read, so that the handler sees a
// consistent view of the document
if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
var prevShift = cm.display.shift, done = false;
try {
if (isReadOnly(cm)) cm.state.suppressEdits = true;
if (dropShift) cm.display.shift = false;
done = bound(cm) != Pass;
} finally {
cm.display.shift = prevShift;
cm.state.suppressEdits = false;
}
return done;
}
function lookupKeyForEditor(cm, name, handle) {
for (var i = 0; i < cm.state.keyMaps.length; i++) {
var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
if (result) return result;
}
return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
|| lookupKey(name, cm.options.keyMap, handle, cm);
}
var stopSeq = new Delayed;
function dispatchKey(cm, name, e, handle) {
var seq = cm.state.keySeq;
if (seq) {
if (isModifierKey(name)) return "handled";
stopSeq.set(50, function() {
if (cm.state.keySeq == seq) {
cm.state.keySeq = null;
resetInput(cm);
}
});
name = seq + " " + name;
}
var result = lookupKeyForEditor(cm, name, handle);
if (result == "multi")
cm.state.keySeq = name;
if (result == "handled")
signalLater(cm, "keyHandled", cm, name, e);
if (result == "handled" || result == "multi") {
e_preventDefault(e);
restartBlink(cm);
}
if (seq && !result && /\'$/.test(name)) {
e_preventDefault(e);
return true;
}
return !!result;
}
// Handle a key from the keydown event.
function handleKeyBinding(cm, e) {
var name = keyName(e, true);
if (!name) return false;
if (e.shiftKey && !cm.state.keySeq) {
// First try to resolve full name (including 'Shift-'). Failing
// that, see if there is a cursor-motion command (starting with
// 'go') bound to the keyname without 'Shift-'.
return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);})
|| dispatchKey(cm, name, e, function(b) {
if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
return doHandleBinding(cm, b);
});
} else {
return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });
}
}
// Handle a key from the keypress event
function handleCharBinding(cm, e, ch) {
return dispatchKey(cm, "'" + ch + "'", e,
function(b) { return doHandleBinding(cm, b, true); });
}
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
ensureFocus(cm);
if (signalDOMEvent(cm, e)) return;
// IE does strange things with escape.
if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
var code = e.keyCode;
cm.display.shift = code == 16 || e.shiftKey;
var handled = handleKeyBinding(cm, e);
if (presto) {
lastStoppedKey = handled ? code : null;
// Opera has no cut event... we try to at least catch the key combo
if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
cm.replaceSelection("", null, "cut");
}
// Turn mouse into crosshair when Alt is held on Mac.
if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
showCrossHair(cm);
}
function showCrossHair(cm) {
var lineDiv = cm.display.lineDiv;
addClass(lineDiv, "CodeMirror-crosshair");
function up(e) {
if (e.keyCode == 18 || !e.altKey) {
rmClass(lineDiv, "CodeMirror-crosshair");
off(document, "keyup", up);
off(document, "mouseover", up);
}
}
on(document, "keyup", up);
on(document, "mouseover", up);
}
function onKeyUp(e) {
if (e.keyCode == 16) this.doc.sel.shift = false;
signalDOMEvent(this, e);
}
function onKeyPress(e) {
var cm = this;
if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
var keyCode = e.keyCode, charCode = e.charCode;
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
if (handleCharBinding(cm, e, ch)) return;
if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
fastPoll(cm);
}
// FOCUS/BLUR EVENTS
function onFocus(cm) {
if (cm.options.readOnly == "nocursor") return;
if (!cm.state.focused) {
signal(cm, "focus", cm);
cm.state.focused = true;
addClass(cm.display.wrapper, "CodeMirror-focused");
// The prevInput test prevents this from firing when a context
// menu is closed (since the resetInput would kill the
// select-all detection hack)
if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
resetInput(cm);
if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
}
}
slowPoll(cm);
restartBlink(cm);
}
function onBlur(cm) {
if (cm.state.focused) {
signal(cm, "blur", cm);
cm.state.focused = false;
rmClass(cm.display.wrapper, "CodeMirror-focused");
}
clearInterval(cm.display.blinker);
setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
}
// CONTEXT MENU HANDLING
// To make the context menu work, we need to briefly unhide the
// textarea (making it as unobtrusive as possible) to let the
// right-click take effect on it.
function onContextMenu(cm, e) {
if (signalDOMEvent(cm, e, "contextmenu")) return;
var display = cm.display;
if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
if (!pos || presto) return; // Opera is difficult.
// Reset the current text selection only if the click is done outside of the selection
// and 'resetSelectionOnContextMenu' option is true.
var reset = cm.options.resetSelectionOnContextMenu;
if (reset && cm.doc.sel.contains(pos) == -1)
operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
var oldCSS = display.input.style.cssText;
display.inputDiv.style.position = "absolute";
display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
(ie ? "rgba(255, 255, 255, .05)" : "transparent") +
"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
focusInput(cm);
if (webkit) window.scrollTo(null, oldScrollY);
resetInput(cm);
// Adds "Select all" to context menu in FF
if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
display.contextMenuPending = true;
display.selForContextMenu = cm.doc.sel;
clearTimeout(display.detectingSelectAll);
// Select-all will be greyed out if there's nothing to select, so
// this adds a zero-width space so that we can later check whether
// it got selected.
function prepareSelectAllHack() {
if (display.input.selectionStart != null) {
var selected = cm.somethingSelected();
var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
display.prevInput = selected ? "" : "\u200b";
display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
// Re-set this, in case some other handler touched the
// selection in the meantime.
display.selForContextMenu = cm.doc.sel;
}
}
function rehide() {
display.contextMenuPending = false;
display.inputDiv.style.position = "relative";
display.input.style.cssText = oldCSS;
if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
slowPoll(cm);
// Try to detect the user choosing select-all
if (display.input.selectionStart != null) {
if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
var i = 0, poll = function() {
if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
operation(cm, commands.selectAll)(cm);
else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
else resetInput(cm);
};
display.detectingSelectAll = setTimeout(poll, 200);
}
}
if (ie && ie_version >= 9) prepareSelectAllHack();
if (captureRightClick) {
e_stop(e);
var mouseup = function() {
off(window, "mouseup", mouseup);
setTimeout(rehide, 20);
};
on(window, "mouseup", mouseup);
} else {
setTimeout(rehide, 50);
}
}
function contextMenuInGutter(cm, e) {
if (!hasHandler(cm, "gutterContextMenu")) return false;
return gutterEvent(cm, e, "gutterContextMenu", false, signal);
}
// UPDATING
// Compute the position of the end of a change (its 'to' property
// refers to the pre-change end).
var changeEnd = CodeMirror.changeEnd = function(change) {
if (!change.text) return change.to;
return Pos(change.from.line + change.text.length - 1,
lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
};
// Adjust a position to refer to the post-change position of the
// same text, or the end of the change if the change covers it.
function adjustForChange(pos, change) {
if (cmp(pos, change.from) < 0) return pos;
if (cmp(pos, change.to) <= 0) return changeEnd(change);
var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
return Pos(line, ch);
}
function computeSelAfterChange(doc, change) {
var out = [];
for (var i = 0; i < doc.sel.ranges.length; i++) {
var range = doc.sel.ranges[i];
out.push(new Range(adjustForChange(range.anchor, change),
adjustForChange(range.head, change)));
}
return normalizeSelection(out, doc.sel.primIndex);
}
function offsetPos(pos, old, nw) {
if (pos.line == old.line)
return Pos(nw.line, pos.ch - old.ch + nw.ch);
else
return Pos(nw.line + (pos.line - old.line), pos.ch);
}
// Used by replaceSelections to allow moving the selection to the
// start or around the replaced test. Hint may be "start" or "around".
function computeReplacedSel(doc, changes, hint) {
var out = [];
var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
for (var i = 0; i < changes.length; i++) {
var change = changes[i];
var from = offsetPos(change.from, oldPrev, newPrev);
var to = offsetPos(changeEnd(change), oldPrev, newPrev);
oldPrev = change.to;
newPrev = to;
if (hint == "around") {
var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
out[i] = new Range(inv ? to : from, inv ? from : to);
} else {
out[i] = new Range(from, from);
}
}
return new Selection(out, doc.sel.primIndex);
}
// Allow "beforeChange" event handlers to influence a change
function filterChange(doc, change, update) {
var obj = {
canceled: false,
from: change.from,
to: change.to,
text: change.text,
origin: change.origin,
cancel: function() { this.canceled = true; }
};
if (update) obj.update = function(from, to, text, origin) {
if (from) this.from = clipPos(doc, from);
if (to) this.to = clipPos(doc, to);
if (text) this.text = text;
if (origin !== undefined) this.origin = origin;
};
signal(doc, "beforeChange", doc, obj);
if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
if (obj.canceled) return null;
return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
}
// Apply a change to a document, and add it to the document's
// history, and propagating it to all linked documents.
function makeChange(doc, change, ignoreReadOnly) {
if (doc.cm) {
if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
if (doc.cm.state.suppressEdits) return;
}
if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
change = filterChange(doc, change, true);
if (!change) return;
}
// Possibly split or suppress the update based on the presence
// of read-only spans in its range.
var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
if (split) {
for (var i = split.length - 1; i >= 0; --i)
makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
} else {
makeChangeInner(doc, change);
}
}
function makeChangeInner(doc, change) {
if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
var selAfter = computeSelAfterChange(doc, change);
addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
var rebased = [];
linkedDocs(doc, function(doc, sharedHist) {
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
rebaseHist(doc.history, change);
rebased.push(doc.history);
}
makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
});
}
// Revert a change stored in a document's history.
function makeChangeFromHistory(doc, type, allowSelectionOnly) {
if (doc.cm && doc.cm.state.suppressEdits) return;
var hist = doc.history, event, selAfter = doc.sel;
var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
// Verify that there is a useable event (so that ctrl-z won't
// needlessly clear selection events)
for (var i = 0; i < source.length; i++) {
event = source[i];
if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
break;
}
if (i == source.length) return;
hist.lastOrigin = hist.lastSelOrigin = null;
for (;;) {
event = source.pop();
if (event.ranges) {
pushSelectionToHistory(event, dest);
if (allowSelectionOnly && !event.equals(doc.sel)) {
setSelection(doc, event, {clearRedo: false});
return;
}
selAfter = event;
}
else break;
}
// Build up a reverse change object to add to the opposite history
// stack (redo when undoing, and vice versa).
var antiChanges = [];
pushSelectionToHistory(selAfter, dest);
dest.push({changes: antiChanges, generation: hist.generation});
hist.generation = event.generation || ++hist.maxGeneration;
var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
for (var i = event.changes.length - 1; i >= 0; --i) {
var change = event.changes[i];
change.origin = type;
if (filter && !filterChange(doc, change, false)) {
source.length = 0;
return;
}
antiChanges.push(historyChangeFromChange(doc, change));
var after = i ? computeSelAfterChange(doc, change) : lst(source);
makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
var rebased = [];
// Propagate to the linked documents
linkedDocs(doc, function(doc, sharedHist) {
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
rebaseHist(doc.history, change);
rebased.push(doc.history);
}
makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
});
}
}
// Sub-views need their line numbers shifted when text is added
// above or below them in the parent document.
function shiftDoc(doc, distance) {
if (distance == 0) return;
doc.first += distance;
doc.sel = new Selection(map(doc.sel.ranges, function(range) {
return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
Pos(range.head.line + distance, range.head.ch));
}), doc.sel.primIndex);
if (doc.cm) {
regChange(doc.cm, doc.first, doc.first - distance, distance);
for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
regLineChange(doc.cm, l, "gutter");
}
}
// More lower-level change function, handling only a single document
// (not linked ones).
function makeChangeSingleDoc(doc, change, selAfter, spans) {
if (doc.cm && !doc.cm.curOp)
return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
if (change.to.line < doc.first) {
shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
return;
}
if (change.from.line > doc.lastLine()) return;
// Clip the change to the size of this doc
if (change.from.line < doc.first) {
var shift = change.text.length - 1 - (doc.first - change.from.line);
shiftDoc(doc, shift);
change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
text: [lst(change.text)], origin: change.origin};
}
var last = doc.lastLine();
if (change.to.line > last) {
change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
text: [change.text[0]], origin: change.origin};
}
change.removed = getBetween(doc, change.from, change.to);
if (!selAfter) selAfter = computeSelAfterChange(doc, change);
if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
else updateDoc(doc, change, spans);
setSelectionNoUndo(doc, selAfter, sel_dontScroll);
}
// Handle the interaction of a change to a document with the editor
// that this document is part of.
function makeChangeSingleDocInEditor(cm, change, spans) {
var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
var recomputeMaxLength = false, checkWidthStart = from.line;
if (!cm.options.lineWrapping) {
checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
doc.iter(checkWidthStart, to.line + 1, function(line) {
if (line == display.maxLine) {
recomputeMaxLength = true;
return true;
}
});
}
if (doc.sel.contains(change.from, change.to) > -1)
signalCursorActivity(cm);
updateDoc(doc, change, spans, estimateHeight(cm));
if (!cm.options.lineWrapping) {
doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
var len = lineLength(line);
if (len > display.maxLineLength) {
display.maxLine = line;
display.maxLineLength = len;
display.maxLineChanged = true;
recomputeMaxLength = false;
}
});
if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
}
// Adjust frontier, schedule worker
doc.frontier = Math.min(doc.frontier, from.line);
startWorker(cm, 400);
var lendiff = change.text.length - (to.line - from.line) - 1;
// Remember that these lines changed, for updating the display
if (change.full)
regChange(cm);
else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
regLineChange(cm, from.line, "text");
else
regChange(cm, from.line, to.line + 1, lendiff);
var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
if (changeHandler || changesHandler) {
var obj = {
from: from, to: to,
text: change.text,
removed: change.removed,
origin: change.origin
};
if (changeHandler) signalLater(cm, "change", cm, obj);
if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
}
cm.display.selForContextMenu = null;
}
function replaceRange(doc, code, from, to, origin) {
if (!to) to = from;
if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
if (typeof code == "string") code = splitLines(code);
makeChange(doc, {from: from, to: to, text: code, origin: origin});
}
// SCROLLING THINGS INTO VIEW
// If an editor sits on the top or bottom of the window, partially
// scrolled out of view, this ensures that the cursor is visible.
function maybeScrollWindow(cm, coords) {
if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
if (doScroll != null && !phantom) {
var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
(coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
(coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
coords.left + "px; width: 2px;");
cm.display.lineSpace.appendChild(scrollNode);
scrollNode.scrollIntoView(doScroll);
cm.display.lineSpace.removeChild(scrollNode);
}
}
// Scroll a given position into view (immediately), verifying that
// it actually became visible (as line heights are accurately
// measured, the position of something may 'drift' during drawing).
function scrollPosIntoView(cm, pos, end, margin) {
if (margin == null) margin = 0;
for (var limit = 0; limit < 5; limit++) {
var changed = false, coords = cursorCoords(cm, pos);
var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
Math.min(coords.top, endCoords.top) - margin,
Math.max(coords.left, endCoords.left),
Math.max(coords.bottom, endCoords.bottom) + margin);
var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
if (scrollPos.scrollTop != null) {
setScrollTop(cm, scrollPos.scrollTop);
if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
}
if (scrollPos.scrollLeft != null) {
setScrollLeft(cm, scrollPos.scrollLeft);
if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
}
if (!changed) break;
}
return coords;
}
// Scroll a given set of coordinates into view (immediately).
function scrollIntoView(cm, x1, y1, x2, y2) {
var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
}
// Calculate a new scroll position needed to scroll the given
// rectangle into view. Returns an object with scrollTop and
// scrollLeft properties. When these are undefined, the
// vertical/horizontal position does not need to be adjusted.
function calculateScrollPos(cm, x1, y1, x2, y2) {
var display = cm.display, snapMargin = textHeight(cm.display);
if (y1 < 0) y1 = 0;
var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
var screen = displayHeight(cm), result = {};
if (y2 - y1 > screen) y2 = y1 + screen;
var docBottom = cm.doc.height + paddingVert(display);
var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
if (y1 < screentop) {
result.scrollTop = atTop ? 0 : y1;
} else if (y2 > screentop + screen) {
var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
if (newTop != screentop) result.scrollTop = newTop;
}
var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
var tooWide = x2 - x1 > screenw;
if (tooWide) x2 = x1 + screenw;
if (x1 < 10)
result.scrollLeft = 0;
else if (x1 < screenleft)
result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
else if (x2 > screenw + screenleft - 3)
result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
return result;
}
// Store a relative adjustment to the scroll position in the current
// operation (to be applied when the operation finishes).
function addToScrollPos(cm, left, top) {
if (left != null || top != null) resolveScrollToPos(cm);
if (left != null)
cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
if (top != null)
cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
}
// Make sure that at the end of the operation the current cursor is
// shown.
function ensureCursorVisible(cm) {
resolveScrollToPos(cm);
var cur = cm.getCursor(), from = cur, to = cur;
if (!cm.options.lineWrapping) {
from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
to = Pos(cur.line, cur.ch + 1);
}
cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
}
// When an operation has its scrollToPos property set, and another
// scroll action is applied before the end of the operation, this
// 'simulates' scrolling that position into view in a cheap way, so
// that the effect of intermediate scroll commands is not ignored.
function resolveScrollToPos(cm) {
var range = cm.curOp.scrollToPos;
if (range) {
cm.curOp.scrollToPos = null;
var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
Math.min(from.top, to.top) - range.margin,
Math.max(from.right, to.right),
Math.max(from.bottom, to.bottom) + range.margin);
cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
}
}
// API UTILITIES
// Indent the given line. The how parameter can be "smart",
// "add"/null, "subtract", or "prev". When aggressive is false
// (typically set to true for forced single-line indents), empty
// lines are not indented, and places where the mode returns Pass
// are left alone.
function indentLine(cm, n, how, aggressive) {
var doc = cm.doc, state;
if (how == null) how = "add";
if (how == "smart") {
// Fall back to "prev" when the mode doesn't have an indentation
// method.
if (!doc.mode.indent) how = "prev";
else state = getStateBefore(cm, n);
}
var tabSize = cm.options.tabSize;
var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
if (line.stateAfter) line.stateAfter = null;
var curSpaceString = line.text.match(/^\s*/)[0], indentation;
if (!aggressive && !/\S/.test(line.text)) {
indentation = 0;
how = "not";
} else if (how == "smart") {
indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
if (indentation == Pass || indentation > 150) {
if (!aggressive) return;
how = "prev";
}
}
if (how == "prev") {
if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
else indentation = 0;
} else if (how == "add") {
indentation = curSpace + cm.options.indentUnit;
} else if (how == "subtract") {
indentation = curSpace - cm.options.indentUnit;
} else if (typeof how == "number") {
indentation = curSpace + how;
}
indentation = Math.max(0, indentation);
var indentString = "", pos = 0;
if (cm.options.indentWithTabs)
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
if (pos < indentation) indentString += spaceStr(indentation - pos);
if (indentString != curSpaceString) {
replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
} else {
// Ensure that, if the cursor was in the whitespace at the start
// of the line, it is moved to the end of that space.
for (var i = 0; i < doc.sel.ranges.length; i++) {
var range = doc.sel.ranges[i];
if (range.head.line == n && range.head.ch < curSpaceString.length) {
var pos = Pos(n, curSpaceString.length);
replaceOneSelection(doc, i, new Range(pos, pos));
break;
}
}
}
line.stateAfter = null;
}
// Utility for applying a change to a line by handle or number,
// returning the number and optionally registering the line as
// changed.
function changeLine(doc, handle, changeType, op) {
var no = handle, line = handle;
if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
else no = lineNo(handle);
if (no == null) return null;
if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);
return line;
}
// Helper for deleting text near the selection(s), used to implement
// backspace, delete, and similar functionality.
function deleteNearSelection(cm, compute) {
var ranges = cm.doc.sel.ranges, kill = [];
// Build up a set of ranges to kill first, merging overlapping
// ranges.
for (var i = 0; i < ranges.length; i++) {
var toKill = compute(ranges[i]);
while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
var replaced = kill.pop();
if (cmp(replaced.from, toKill.from) < 0) {
toKill.from = replaced.from;
break;
}
}
kill.push(toKill);
}
// Next, remove those actual ranges.
runInOp(cm, function() {
for (var i = kill.length - 1; i >= 0; i--)
replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
ensureCursorVisible(cm);
});
}
// Used for horizontal relative motion. Dir is -1 or 1 (left or
// right), unit can be "char", "column" (like char, but doesn't
// cross line boundaries), "word" (across next word), or "group" (to
// the start of next group of word or non-word-non-whitespace
// chars). The visually param controls whether, in right-to-left
// text, direction 1 means to move towards the next index in the
// string, or towards the character to the right of the current
// position. The resulting position will have a hitSide=true
// property if it reached the end of the document.
function findPosH(doc, pos, dir, unit, visually) {
var line = pos.line, ch = pos.ch, origDir = dir;
var lineObj = getLine(doc, line);
var possible = true;
function findNextLine() {
var l = line + dir;
if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
line = l;
return lineObj = getLine(doc, l);
}
function moveOnce(boundToLine) {
var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
if (next == null) {
if (!boundToLine && findNextLine()) {
if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
else ch = dir < 0 ? lineObj.text.length : 0;
} else return (possible = false);
} else ch = next;
return true;
}
if (unit == "char") moveOnce();
else if (unit == "column") moveOnce(true);
else if (unit == "word" || unit == "group") {
var sawType = null, group = unit == "group";
var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
for (var first = true;; first = false) {
if (dir < 0 && !moveOnce(!first)) break;
var cur = lineObj.text.charAt(ch) || "\n";
var type = isWordChar(cur, helper) ? "w"
: group && cur == "\n" ? "n"
: !group || /\s/.test(cur) ? null
: "p";
if (group && !first && !type) type = "s";
if (sawType && sawType != type) {
if (dir < 0) {dir = 1; moveOnce();}
break;
}
if (type) sawType = type;
if (dir > 0 && !moveOnce(!first)) break;
}
}
var result = skipAtomic(doc, Pos(line, ch), origDir, true);
if (!possible) result.hitSide = true;
return result;
}
// For relative vertical movement. Dir may be -1 or 1. Unit can be
// "page" or "line". The resulting position will have a hitSide=true
// property if it reached the end of the document.
function findPosV(cm, pos, dir, unit) {
var doc = cm.doc, x = pos.left, y;
if (unit == "page") {
var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
} else if (unit == "line") {
y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
}
for (;;) {
var target = coordsChar(cm, x, y);
if (!target.outside) break;
if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
y += dir * 5;
}
return target;
}
// EDITOR METHODS
// The publicly visible API. Note that methodOp(f) means
// 'wrap f in an operation, performed on its `this` parameter'.
// This is not the complete set of editor methods. Most of the
// methods defined on the Doc type are also injected into
// CodeMirror.prototype, for backwards compatibility and
// convenience.
CodeMirror.prototype = {
constructor: CodeMirror,
focus: function(){window.focus(); focusInput(this); fastPoll(this);},
setOption: function(option, value) {
var options = this.options, old = options[option];
if (options[option] == value && option != "mode") return;
options[option] = value;
if (optionHandlers.hasOwnProperty(option))
operation(this, optionHandlers[option])(this, value, old);
},
getOption: function(option) {return this.options[option];},
getDoc: function() {return this.doc;},
addKeyMap: function(map, bottom) {
this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
},
removeKeyMap: function(map) {
var maps = this.state.keyMaps;
for (var i = 0; i < maps.length; ++i)
if (maps[i] == map || maps[i].name == map) {
maps.splice(i, 1);
return true;
}
},
addOverlay: methodOp(function(spec, options) {
var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
if (mode.startState) throw new Error("Overlays may not be stateful.");
this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
this.state.modeGen++;
regChange(this);
}),
removeOverlay: methodOp(function(spec) {
var overlays = this.state.overlays;
for (var i = 0; i < overlays.length; ++i) {
var cur = overlays[i].modeSpec;
if (cur == spec || typeof spec == "string" && cur.name == spec) {
overlays.splice(i, 1);
this.state.modeGen++;
regChange(this);
return;
}
}
}),
indentLine: methodOp(function(n, dir, aggressive) {
if (typeof dir != "string" && typeof dir != "number") {
if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
else dir = dir ? "add" : "subtract";
}
if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
}),
indentSelection: methodOp(function(how) {
var ranges = this.doc.sel.ranges, end = -1;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty()) {
var from = range.from(), to = range.to();
var start = Math.max(end, from.line);
end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
for (var j = start; j < end; ++j)
indentLine(this, j, how);
var newRanges = this.doc.sel.ranges;
if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
} else if (range.head.line > end) {
indentLine(this, range.head.line, how, true);
end = range.head.line;
if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
}
}
}),
// Fetch the parser token for a given character. Useful for hacks
// that want to inspect the mode state (say, for completion).
getTokenAt: function(pos, precise) {
return takeToken(this, pos, precise);
},
getLineTokens: function(line, precise) {
return takeToken(this, Pos(line), precise, true);
},
getTokenTypeAt: function(pos) {
pos = clipPos(this.doc, pos);
var styles = getLineStyles(this, getLine(this.doc, pos.line));
var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
var type;
if (ch == 0) type = styles[2];
else for (;;) {
var mid = (before + after) >> 1;
if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
else if (styles[mid * 2 + 1] < ch) before = mid + 1;
else { type = styles[mid * 2 + 2]; break; }
}
var cut = type ? type.indexOf("cm-overlay ") : -1;
return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
},
getModeAt: function(pos) {
var mode = this.doc.mode;
if (!mode.innerMode) return mode;
return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
},
getHelper: function(pos, type) {
return this.getHelpers(pos, type)[0];
},
getHelpers: function(pos, type) {
var found = [];
if (!helpers.hasOwnProperty(type)) return helpers;
var help = helpers[type], mode = this.getModeAt(pos);
if (typeof mode[type] == "string") {
if (help[mode[type]]) found.push(help[mode[type]]);
} else if (mode[type]) {
for (var i = 0; i < mode[type].length; i++) {
var val = help[mode[type][i]];
if (val) found.push(val);
}
} else if (mode.helperType && help[mode.helperType]) {
found.push(help[mode.helperType]);
} else if (help[mode.name]) {
found.push(help[mode.name]);
}
for (var i = 0; i < help._global.length; i++) {
var cur = help._global[i];
if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
found.push(cur.val);
}
return found;
},
getStateAfter: function(line, precise) {
var doc = this.doc;
line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
return getStateBefore(this, line + 1, precise);
},
cursorCoords: function(start, mode) {
var pos, range = this.doc.sel.primary();
if (start == null) pos = range.head;
else if (typeof start == "object") pos = clipPos(this.doc, start);
else pos = start ? range.from() : range.to();
return cursorCoords(this, pos, mode || "page");
},
charCoords: function(pos, mode) {
return charCoords(this, clipPos(this.doc, pos), mode || "page");
},
coordsChar: function(coords, mode) {
coords = fromCoordSystem(this, coords, mode || "page");
return coordsChar(this, coords.left, coords.top);
},
lineAtHeight: function(height, mode) {
height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
return lineAtHeight(this.doc, height + this.display.viewOffset);
},
heightAtLine: function(line, mode) {
var end = false, last = this.doc.first + this.doc.size - 1;
if (line < this.doc.first) line = this.doc.first;
else if (line > last) { line = last; end = true; }
var lineObj = getLine(this.doc, line);
return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
(end ? this.doc.height - heightAtLine(lineObj) : 0);
},
defaultTextHeight: function() { return textHeight(this.display); },
defaultCharWidth: function() { return charWidth(this.display); },
setGutterMarker: methodOp(function(line, gutterID, value) {
return changeLine(this.doc, line, "gutter", function(line) {
var markers = line.gutterMarkers || (line.gutterMarkers = {});
markers[gutterID] = value;
if (!value && isEmpty(markers)) line.gutterMarkers = null;
return true;
});
}),
clearGutter: methodOp(function(gutterID) {
var cm = this, doc = cm.doc, i = doc.first;
doc.iter(function(line) {
if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
line.gutterMarkers[gutterID] = null;
regLineChange(cm, i, "gutter");
if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
}
++i;
});
}),
addLineWidget: methodOp(function(handle, node, options) {
return addLineWidget(this, handle, node, options);
}),
removeLineWidget: function(widget) { widget.clear(); },
lineInfo: function(line) {
if (typeof line == "number") {
if (!isLine(this.doc, line)) return null;
var n = line;
line = getLine(this.doc, line);
if (!line) return null;
} else {
var n = lineNo(line);
if (n == null) return null;
}
return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
widgets: line.widgets};
},
getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
addWidget: function(pos, node, scroll, vert, horiz) {
var display = this.display;
pos = cursorCoords(this, clipPos(this.doc, pos));
var top = pos.bottom, left = pos.left;
node.style.position = "absolute";
node.setAttribute("cm-ignore-events", "true");
display.sizer.appendChild(node);
if (vert == "over") {
top = pos.top;
} else if (vert == "above" || vert == "near") {
var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
// Default to positioning above (if specified and possible); otherwise default to positioning below
if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
top = pos.top - node.offsetHeight;
else if (pos.bottom + node.offsetHeight <= vspace)
top = pos.bottom;
if (left + node.offsetWidth > hspace)
left = hspace - node.offsetWidth;
}
node.style.top = top + "px";
node.style.left = node.style.right = "";
if (horiz == "right") {
left = display.sizer.clientWidth - node.offsetWidth;
node.style.right = "0px";
} else {
if (horiz == "left") left = 0;
else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
node.style.left = left + "px";
}
if (scroll)
scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
},
triggerOnKeyDown: methodOp(onKeyDown),
triggerOnKeyPress: methodOp(onKeyPress),
triggerOnKeyUp: onKeyUp,
execCommand: function(cmd) {
if (commands.hasOwnProperty(cmd))
return commands[cmd](this);
},
findPosH: function(from, amount, unit, visually) {
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
cur = findPosH(this.doc, cur, dir, unit, visually);
if (cur.hitSide) break;
}
return cur;
},
moveH: methodOp(function(dir, unit) {
var cm = this;
cm.extendSelectionsBy(function(range) {
if (cm.display.shift || cm.doc.extend || range.empty())
return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
else
return dir < 0 ? range.from() : range.to();
}, sel_move);
}),
deleteH: methodOp(function(dir, unit) {
var sel = this.doc.sel, doc = this.doc;
if (sel.somethingSelected())
doc.replaceSelection("", null, "+delete");
else
deleteNearSelection(this, function(range) {
var other = findPosH(doc, range.head, dir, unit, false);
return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
});
}),
findPosV: function(from, amount, unit, goalColumn) {
var dir = 1, x = goalColumn;
if (amount < 0) { dir = -1; amount = -amount; }
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
var coords = cursorCoords(this, cur, "div");
if (x == null) x = coords.left;
else coords.left = x;
cur = findPosV(this, coords, dir, unit);
if (cur.hitSide) break;
}
return cur;
},
moveV: methodOp(function(dir, unit) {
var cm = this, doc = this.doc, goals = [];
var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
doc.extendSelectionsBy(function(range) {
if (collapse)
return dir < 0 ? range.from() : range.to();
var headPos = cursorCoords(cm, range.head, "div");
if (range.goalColumn != null) headPos.left = range.goalColumn;
goals.push(headPos.left);
var pos = findPosV(cm, headPos, dir, unit);
if (unit == "page" && range == doc.sel.primary())
addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
return pos;
}, sel_move);
if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
doc.sel.ranges[i].goalColumn = goals[i];
}),
// Find the word at the given position (as returned by coordsChar).
findWordAt: function(pos) {
var doc = this.doc, line = getLine(doc, pos.line).text;
var start = pos.ch, end = pos.ch;
if (line) {
var helper = this.getHelper(pos, "wordChars");
if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
var startChar = line.charAt(start);
var check = isWordChar(startChar, helper)
? function(ch) { return isWordChar(ch, helper); }
: /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
: function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
while (start > 0 && check(line.charAt(start - 1))) --start;
while (end < line.length && check(line.charAt(end))) ++end;
}
return new Range(Pos(pos.line, start), Pos(pos.line, end));
},
toggleOverwrite: function(value) {
if (value != null && value == this.state.overwrite) return;
if (this.state.overwrite = !this.state.overwrite)
addClass(this.display.cursorDiv, "CodeMirror-overwrite");
else
rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
signal(this, "overwriteToggle", this, this.state.overwrite);
},
hasFocus: function() { return activeElt() == this.display.input; },
scrollTo: methodOp(function(x, y) {
if (x != null || y != null) resolveScrollToPos(this);
if (x != null) this.curOp.scrollLeft = x;
if (y != null) this.curOp.scrollTop = y;
}),
getScrollInfo: function() {
var scroller = this.display.scroller;
return {left: scroller.scrollLeft, top: scroller.scrollTop,
height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
clientHeight: displayHeight(this), clientWidth: displayWidth(this)};
},
scrollIntoView: methodOp(function(range, margin) {
if (range == null) {
range = {from: this.doc.sel.primary().head, to: null};
if (margin == null) margin = this.options.cursorScrollMargin;
} else if (typeof range == "number") {
range = {from: Pos(range, 0), to: null};
} else if (range.from == null) {
range = {from: range, to: null};
}
if (!range.to) range.to = range.from;
range.margin = margin || 0;
if (range.from.line != null) {
resolveScrollToPos(this);
this.curOp.scrollToPos = range;
} else {
var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
Math.min(range.from.top, range.to.top) - range.margin,
Math.max(range.from.right, range.to.right),
Math.max(range.from.bottom, range.to.bottom) + range.margin);
this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
}
}),
setSize: methodOp(function(width, height) {
var cm = this;
function interpret(val) {
return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
}
if (width != null) cm.display.wrapper.style.width = interpret(width);
if (height != null) cm.display.wrapper.style.height = interpret(height);
if (cm.options.lineWrapping) clearLineMeasurementCache(this);
var lineNo = cm.display.viewFrom;
cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
++lineNo;
});
cm.curOp.forceUpdate = true;
signal(cm, "refresh", this);
}),
operation: function(f){return runInOp(this, f);},
refresh: methodOp(function() {
var oldHeight = this.display.cachedTextHeight;
regChange(this);
this.curOp.forceUpdate = true;
clearCaches(this);
this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
updateGutterSpace(this);
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
estimateLineHeights(this);
signal(this, "refresh", this);
}),
swapDoc: methodOp(function(doc) {
var old = this.doc;
old.cm = null;
attachDoc(this, doc);
clearCaches(this);
resetInput(this);
this.scrollTo(doc.scrollLeft, doc.scrollTop);
this.curOp.forceScroll = true;
signalLater(this, "swapDoc", this, old);
return old;
}),
getInputField: function(){return this.display.input;},
getWrapperElement: function(){return this.display.wrapper;},
getScrollerElement: function(){return this.display.scroller;},
getGutterElement: function(){return this.display.gutters;}
};
eventMixin(CodeMirror);
// OPTION DEFAULTS
// The default configuration options.
var defaults = CodeMirror.defaults = {};
// Functions to run when options are changed.
var optionHandlers = CodeMirror.optionHandlers = {};
function option(name, deflt, handle, notOnInit) {
CodeMirror.defaults[name] = deflt;
if (handle) optionHandlers[name] =
notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
}
// Passed to option handlers when there is no old value.
var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
// These two are, on init, called from the constructor because they
// have to be initialized before the editor can start at all.
option("value", "", function(cm, val) {
cm.setValue(val);
}, true);
option("mode", null, function(cm, val) {
cm.doc.modeOption = val;
loadMode(cm);
}, true);
option("indentUnit", 2, loadMode, true);
option("indentWithTabs", false);
option("smartIndent", true);
option("tabSize", 4, function(cm) {
resetModeState(cm);
clearCaches(cm);
regChange(cm);
}, true);
option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val) {
cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
cm.refresh();
}, true);
option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
option("electricChars", true);
option("rtlMoveVisually", !windows);
option("wholeLineUpdateBefore", true);
option("theme", "default", function(cm) {
themeChanged(cm);
guttersChanged(cm);
}, true);
option("keyMap", "default", function(cm, val, old) {
var next = getKeyMap(val);
var prev = old != CodeMirror.Init && getKeyMap(old);
if (prev && prev.detach) prev.detach(cm, next);
if (next.attach) next.attach(cm, prev || null);
});
option("extraKeys", null);
option("lineWrapping", false, wrappingChanged, true);
option("gutters", [], function(cm) {
setGuttersForLineNumbers(cm.options);
guttersChanged(cm);
}, true);
option("fixedGutter", true, function(cm, val) {
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
cm.refresh();
}, true);
option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true);
option("scrollbarStyle", "native", function(cm) {
initScrollbars(cm);
updateScrollbars(cm);
cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
}, true);
option("lineNumbers", false, function(cm) {
setGuttersForLineNumbers(cm.options);
guttersChanged(cm);
}, true);
option("firstLineNumber", 1, guttersChanged, true);
option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
option("showCursorWhenSelecting", false, updateSelection, true);
option("resetSelectionOnContextMenu", true);
option("readOnly", false, function(cm, val) {
if (val == "nocursor") {
onBlur(cm);
cm.display.input.blur();
cm.display.disabled = true;
} else {
cm.display.disabled = false;
if (!val) resetInput(cm);
}
});
option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
option("dragDrop", true);
option("cursorBlinkRate", 530);
option("cursorScrollMargin", 0);
option("cursorHeight", 1, updateSelection, true);
option("singleCursorHeightPerLine", true, updateSelection, true);
option("workTime", 100);
option("workDelay", 100);
option("flattenSpans", true, resetModeState, true);
option("addModeClass", false, resetModeState, true);
option("pollInterval", 100);
option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
option("historyEventDelay", 1250);
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
option("maxHighlightLength", 10000, resetModeState, true);
option("moveInputWithCursor", true, function(cm, val) {
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
});
option("tabindex", null, function(cm, val) {
cm.display.input.tabIndex = val || "";
});
option("autofocus", null);
// MODE DEFINITION AND QUERYING
// Known modes, by name and by MIME
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
// Extra arguments are stored as the mode's dependencies, which is
// used by (legacy) mechanisms like loadmode.js to automatically
// load a mode. (Preferred mechanism is the require/define calls.)
CodeMirror.defineMode = function(name, mode) {
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function(mime, spec) {
mimeModes[mime] = spec;
};
// Given a MIME type, a {name, ...options} config object, or a name
// string, return a mode config object.
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
var found = mimeModes[spec.name];
if (typeof found == "string") found = {name: found};
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
return CodeMirror.resolveMode("application/xml");
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
// Given a mode spec (anything that resolveMode accepts), find and
// initialize an actual mode object.
CodeMirror.getMode = function(options, spec) {
var spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) continue;
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
if (spec.helperType) modeObj.helperType = spec.helperType;
if (spec.modeProps) for (var prop in spec.modeProps)
modeObj[prop] = spec.modeProps[prop];
return modeObj;
};
// Minimal default mode.
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = CodeMirror.modeExtensions = {};
CodeMirror.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
};
// EXTENSIONS
CodeMirror.defineExtension = function(name, func) {
CodeMirror.prototype[name] = func;
};
CodeMirror.defineDocExtension = function(name, func) {
Doc.prototype[name] = func;
};
CodeMirror.defineOption = option;
var initHooks = [];
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
var helpers = CodeMirror.helpers = {};
CodeMirror.registerHelper = function(type, name, value) {
if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
helpers[type][name] = value;
};
CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
CodeMirror.registerHelper(type, name, value);
helpers[type]._global.push({pred: predicate, val: value});
};
// MODE STATE HANDLING
// Utility functions for working with state. Exported because nested
// modes need to do this for their inner modes.
var copyState = CodeMirror.copyState = function(mode, state) {
if (state === true) return state;
if (mode.copyState) return mode.copyState(state);
var nstate = {};
for (var n in state) {
var val = state[n];
if (val instanceof Array) val = val.concat([]);
nstate[n] = val;
}
return nstate;
};
var startState = CodeMirror.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
// Given a mode and a state (for that mode), find the inner mode and
// state at the position that the state refers to.
CodeMirror.innerMode = function(mode, state) {
while (mode.innerMode) {
var info = mode.innerMode(state);
if (!info || info.mode == mode) break;
state = info.state;
mode = info.mode;
}
return info || {mode: mode, state: state};
};
// STANDARD COMMANDS
// Commands are parameter-less actions that can be performed on an
// editor, mostly used for keybindings.
var commands = CodeMirror.commands = {
selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
singleSelection: function(cm) {
cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
},
killLine: function(cm) {
deleteNearSelection(cm, function(range) {
if (range.empty()) {
var len = getLine(cm.doc, range.head.line).text.length;
if (range.head.ch == len && range.head.line < cm.lastLine())
return {from: range.head, to: Pos(range.head.line + 1, 0)};
else
return {from: range.head, to: Pos(range.head.line, len)};
} else {
return {from: range.from(), to: range.to()};
}
});
},
deleteLine: function(cm) {
deleteNearSelection(cm, function(range) {
return {from: Pos(range.from().line, 0),
to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
});
},
delLineLeft: function(cm) {
deleteNearSelection(cm, function(range) {
return {from: Pos(range.from().line, 0), to: range.from()};
});
},
delWrappedLineLeft: function(cm) {
deleteNearSelection(cm, function(range) {
var top = cm.charCoords(range.head, "div").top + 5;
var leftPos = cm.coordsChar({left: 0, top: top}, "div");
return {from: leftPos, to: range.from()};
});
},
delWrappedLineRight: function(cm) {
deleteNearSelection(cm, function(range) {
var top = cm.charCoords(range.head, "div").top + 5;
var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
return {from: range.from(), to: rightPos };
});
},
undo: function(cm) {cm.undo();},
redo: function(cm) {cm.redo();},
undoSelection: function(cm) {cm.undoSelection();},
redoSelection: function(cm) {cm.redoSelection();},
goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
goLineStart: function(cm) {
cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
{origin: "+move", bias: 1});
},
goLineStartSmart: function(cm) {
cm.extendSelectionsBy(function(range) {
return lineStartSmart(cm, range.head);
}, {origin: "+move", bias: 1});
},
goLineEnd: function(cm) {
cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
{origin: "+move", bias: -1});
},
goLineRight: function(cm) {
cm.extendSelectionsBy(function(range) {
var top = cm.charCoords(range.head, "div").top + 5;
return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
}, sel_move);
},
goLineLeft: function(cm) {
cm.extendSelectionsBy(function(range) {
var top = cm.charCoords(range.head, "div").top + 5;
return cm.coordsChar({left: 0, top: top}, "div");
}, sel_move);
},
goLineLeftSmart: function(cm) {
cm.extendSelectionsBy(function(range) {
var top = cm.charCoords(range.head, "div").top + 5;
var pos = cm.coordsChar({left: 0, top: top}, "div");
if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
return pos;
}, sel_move);
},
goLineUp: function(cm) {cm.moveV(-1, "line");},
goLineDown: function(cm) {cm.moveV(1, "line");},
goPageUp: function(cm) {cm.moveV(-1, "page");},
goPageDown: function(cm) {cm.moveV(1, "page");},
goCharLeft: function(cm) {cm.moveH(-1, "char");},
goCharRight: function(cm) {cm.moveH(1, "char");},
goColumnLeft: function(cm) {cm.moveH(-1, "column");},
goColumnRight: function(cm) {cm.moveH(1, "column");},
goWordLeft: function(cm) {cm.moveH(-1, "word");},
goGroupRight: function(cm) {cm.moveH(1, "group");},
goGroupLeft: function(cm) {cm.moveH(-1, "group");},
goWordRight: function(cm) {cm.moveH(1, "word");},
delCharBefore: function(cm) {cm.deleteH(-1, "char");},
delCharAfter: function(cm) {cm.deleteH(1, "char");},
delWordBefore: function(cm) {cm.deleteH(-1, "word");},
delWordAfter: function(cm) {cm.deleteH(1, "word");},
delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
delGroupAfter: function(cm) {cm.deleteH(1, "group");},
indentAuto: function(cm) {cm.indentSelection("smart");},
indentMore: function(cm) {cm.indentSelection("add");},
indentLess: function(cm) {cm.indentSelection("subtract");},
insertTab: function(cm) {cm.replaceSelection("\t");},
insertSoftTab: function(cm) {
var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].from();
var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
}
cm.replaceSelections(spaces);
},
defaultTab: function(cm) {
if (cm.somethingSelected()) cm.indentSelection("add");
else cm.execCommand("insertTab");
},
transposeChars: function(cm) {
runInOp(cm, function() {
var ranges = cm.listSelections(), newSel = [];
for (var i = 0; i < ranges.length; i++) {
var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
if (line) {
if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
if (cur.ch > 0) {
cur = new Pos(cur.line, cur.ch + 1);
cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
Pos(cur.line, cur.ch - 2), cur, "+transpose");
} else if (cur.line > cm.doc.first) {
var prev = getLine(cm.doc, cur.line - 1).text;
if (prev)
cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
}
}
newSel.push(new Range(cur, cur));
}
cm.setSelections(newSel);
});
},
newlineAndIndent: function(cm) {
runInOp(cm, function() {
var len = cm.listSelections().length;
for (var i = 0; i < len; i++) {
var range = cm.listSelections()[i];
cm.replaceRange("\n", range.anchor, range.head, "+input");
cm.indentLine(range.from().line + 1, null, true);
ensureCursorVisible(cm);
}
});
},
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
};
// STANDARD KEYMAPS
var keyMap = CodeMirror.keyMap = {};
keyMap.basic = {
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
"Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
"Tab": "defaultTab", "Shift-Tab": "indentAuto",
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
"Esc": "singleSelection"
};
// Note that the save and find-related commands aren't defined by
// default. User code or addons can define them. Unknown commands
// are simply ignored.
keyMap.pcDefault = {
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
"Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
"Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
fallthrough: "basic"
};
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
"Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
"Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
};
keyMap.macDefault = {
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
"Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
"Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
"Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
"Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
fallthrough: ["basic", "emacsy"]
};
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
// KEYMAP DISPATCH
function normalizeKeyName(name) {
var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];
var alt, ctrl, shift, cmd;
for (var i = 0; i < parts.length - 1; i++) {
var mod = parts[i];
if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;
else if (/^a(lt)?$/i.test(mod)) alt = true;
else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
else if (/^s(hift)$/i.test(mod)) shift = true;
else throw new Error("Unrecognized modifier name: " + mod);
}
if (alt) name = "Alt-" + name;
if (ctrl) name = "Ctrl-" + name;
if (cmd) name = "Cmd-" + name;
if (shift) name = "Shift-" + name;
return name;
}
// This is a kludge to keep keymaps mostly working as raw objects
// (backwards compatibility) while at the same time support features
// like normalization and multi-stroke key bindings. It compiles a
// new normalized keymap, and then updates the old object to reflect
// this.
CodeMirror.normalizeKeyMap = function(keymap) {
var copy = {};
for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {
var value = keymap[keyname];
if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;
if (value == "...") { delete keymap[keyname]; continue; }
var keys = map(keyname.split(" "), normalizeKeyName);
for (var i = 0; i < keys.length; i++) {
var val, name;
if (i == keys.length - 1) {
name = keyname;
val = value;
} else {
name = keys.slice(0, i + 1).join(" ");
val = "...";
}
var prev = copy[name];
if (!prev) copy[name] = val;
else if (prev != val) throw new Error("Inconsistent bindings for " + name);
}
delete keymap[keyname];
}
for (var prop in copy) keymap[prop] = copy[prop];
return keymap;
};
var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
map = getKeyMap(map);
var found = map.call ? map.call(key, context) : map[key];
if (found === false) return "nothing";
if (found === "...") return "multi";
if (found != null && handle(found)) return "handled";
if (map.fallthrough) {
if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
return lookupKey(key, map.fallthrough, handle, context);
for (var i = 0; i < map.fallthrough.length; i++) {
var result = lookupKey(key, map.fallthrough[i], handle, context);
if (result) return result;
}
}
};
// Modifier key presses don't count as 'real' key presses for the
// purpose of keymap fallthrough.
var isModifierKey = CodeMirror.isModifierKey = function(value) {
var name = typeof value == "string" ? value : keyNames[value.keyCode];
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
};
// Look up the name of a key as indicated by an event object.
var keyName = CodeMirror.keyName = function(event, noShift) {
if (presto && event.keyCode == 34 && event["char"]) return false;
var base = keyNames[event.keyCode], name = base;
if (name == null || event.altGraphKey) return false;
if (event.altKey && base != "Alt") name = "Alt-" + name;
if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name;
if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name;
if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name;
return name;
};
function getKeyMap(val) {
return typeof val == "string" ? keyMap[val] : val;
}
// FROMTEXTAREA
CodeMirror.fromTextArea = function(textarea, options) {
if (!options) options = {};
options.value = textarea.value;
if (!options.tabindex && textarea.tabindex)
options.tabindex = textarea.tabindex;
if (!options.placeholder && textarea.placeholder)
options.placeholder = textarea.placeholder;
// Set autofocus to true if this textarea is focused, or if it has
// autofocus and no other element is focused.
if (options.autofocus == null) {
var hasFocus = activeElt();
options.autofocus = hasFocus == textarea ||
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
}
function save() {textarea.value = cm.getValue();}
if (textarea.form) {
on(textarea.form, "submit", save);
// Deplorable hack to make the submit method do the right thing.
if (!options.leaveSubmitMethodAlone) {
var form = textarea.form, realSubmit = form.submit;
try {
var wrappedSubmit = form.submit = function() {
save();
form.submit = realSubmit;
form.submit();
form.submit = wrappedSubmit;
};
} catch(e) {}
}
}
textarea.style.display = "none";
var cm = CodeMirror(function(node) {
textarea.parentNode.insertBefore(node, textarea.nextSibling);
}, options);
cm.save = save;
cm.getTextArea = function() { return textarea; };
cm.toTextArea = function() {
cm.toTextArea = isNaN; // Prevent this from being ran twice
save();
textarea.parentNode.removeChild(cm.getWrapperElement());
textarea.style.display = "";
if (textarea.form) {
off(textarea.form, "submit", save);
if (typeof textarea.form.submit == "function")
textarea.form.submit = realSubmit;
}
};
return cm;
};
// STRING STREAM
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
var StringStream = CodeMirror.StringStream = function(string, tabSize) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
};
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
indentation: function() {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
}
};
// TEXTMARKERS
// Created with markText and setBookmark methods. A TextMarker is a
// handle that can be used to clear or find a marked position in the
// document. Line objects hold arrays (markedSpans) containing
// {from, to, marker} object pointing to such marker objects, and
// indicating that such a marker is present on that line. Multiple
// lines may point to the same marker when it spans across lines.
// The spans will have null for their from/to properties when the
// marker continues beyond the start/end of the line. Markers have
// links back to the lines they currently touch.
var TextMarker = CodeMirror.TextMarker = function(doc, type) {
this.lines = [];
this.type = type;
this.doc = doc;
};
eventMixin(TextMarker);
// Clear the marker.
TextMarker.prototype.clear = function() {
if (this.explicitlyCleared) return;
var cm = this.doc.cm, withOp = cm && !cm.curOp;
if (withOp) startOperation(cm);
if (hasHandler(this, "clear")) {
var found = this.find();
if (found) signalLater(this, "clear", found.from, found.to);
}
var min = null, max = null;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
else if (cm) {
if (span.to != null) max = lineNo(line);
if (span.from != null) min = lineNo(line);
}
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
updateLineHeight(line, textHeight(cm.display));
}
if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
var visual = visualLine(this.lines[i]), len = lineLength(visual);
if (len > cm.display.maxLineLength) {
cm.display.maxLine = visual;
cm.display.maxLineLength = len;
cm.display.maxLineChanged = true;
}
}
if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
this.lines.length = 0;
this.explicitlyCleared = true;
if (this.atomic && this.doc.cantEdit) {
this.doc.cantEdit = false;
if (cm) reCheckSelection(cm.doc);
}
if (cm) signalLater(cm, "markerCleared", cm, this);
if (withOp) endOperation(cm);
if (this.parent) this.parent.clear();
};
// Find the position of the marker in the document. Returns a {from,
// to} object by default. Side can be passed to get a specific side
// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
// Pos objects returned contain a line object, rather than a line
// number (used to prevent looking up the same line twice).
TextMarker.prototype.find = function(side, lineObj) {
if (side == null && this.type == "bookmark") side = 1;
var from, to;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
if (span.from != null) {
from = Pos(lineObj ? line : lineNo(line), span.from);
if (side == -1) return from;
}
if (span.to != null) {
to = Pos(lineObj ? line : lineNo(line), span.to);
if (side == 1) return to;
}
}
return from && {from: from, to: to};
};
// Signals that the marker's widget changed, and surrounding layout
// should be recomputed.
TextMarker.prototype.changed = function() {
var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
if (!pos || !cm) return;
runInOp(cm, function() {
var line = pos.line, lineN = lineNo(pos.line);
var view = findViewForLine(cm, lineN);
if (view) {
clearLineMeasurementCacheFor(view);
cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
}
cm.curOp.updateMaxLine = true;
if (!lineIsHidden(widget.doc, line) && widget.height != null) {
var oldHeight = widget.height;
widget.height = null;
var dHeight = widgetHeight(widget) - oldHeight;
if (dHeight)
updateLineHeight(line, line.height + dHeight);
}
});
};
TextMarker.prototype.attachLine = function(line) {
if (!this.lines.length && this.doc.cm) {
var op = this.doc.cm.curOp;
if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
(op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
}
this.lines.push(line);
};
TextMarker.prototype.detachLine = function(line) {
this.lines.splice(indexOf(this.lines, line), 1);
if (!this.lines.length && this.doc.cm) {
var op = this.doc.cm.curOp;
(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
}
};
// Collapsed markers have unique ids, in order to be able to order
// them, which is needed for uniquely determining an outer marker
// when they overlap (they may nest, but not partially overlap).
var nextMarkerId = 0;
// Create a marker, wire it up to the right lines, and
function markText(doc, from, to, options, type) {
// Shared markers (across linked documents) are handled separately
// (markTextShared will call out to this again, once per
// document).
if (options && options.shared) return markTextShared(doc, from, to, options, type);
// Ensure we are in an operation.
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
var marker = new TextMarker(doc, type), diff = cmp(from, to);
if (options) copyObj(options, marker, false);
// Don't connect empty markers unless clearWhenEmpty is false
if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
return marker;
if (marker.replacedWith) {
// Showing up as a widget implies collapsed (widget replaces text)
marker.collapsed = true;
marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
if (options.insertLeft) marker.widgetNode.insertLeft = true;
}
if (marker.collapsed) {
if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
throw new Error("Inserting collapsed marker partially overlapping an existing one");
sawCollapsedSpans = true;
}
if (marker.addToHistory)
addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
var curLine = from.line, cm = doc.cm, updateMaxLine;
doc.iter(curLine, to.line + 1, function(line) {
if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
updateMaxLine = true;
if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
addMarkedSpan(line, new MarkedSpan(marker,
curLine == from.line ? from.ch : null,
curLine == to.line ? to.ch : null));
++curLine;
});
// lineIsHidden depends on the presence of the spans, so needs a second pass
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
});
if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
if (marker.readOnly) {
sawReadOnlySpans = true;
if (doc.history.done.length || doc.history.undone.length)
doc.clearHistory();
}
if (marker.collapsed) {
marker.id = ++nextMarkerId;
marker.atomic = true;
}
if (cm) {
// Sync editor state
if (updateMaxLine) cm.curOp.updateMaxLine = true;
if (marker.collapsed)
regChange(cm, from.line, to.line + 1);
else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
if (marker.atomic) reCheckSelection(cm.doc);
signalLater(cm, "markerAdded", cm, marker);
}
return marker;
}
// SHARED TEXTMARKERS
// A shared marker spans multiple linked documents. It is
// implemented as a meta-marker-object controlling multiple normal
// markers.
var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
this.markers = markers;
this.primary = primary;
for (var i = 0; i < markers.length; ++i)
markers[i].parent = this;
};
eventMixin(SharedTextMarker);
SharedTextMarker.prototype.clear = function() {
if (this.explicitlyCleared) return;
this.explicitlyCleared = true;
for (var i = 0; i < this.markers.length; ++i)
this.markers[i].clear();
signalLater(this, "clear");
};
SharedTextMarker.prototype.find = function(side, lineObj) {
return this.primary.find(side, lineObj);
};
function markTextShared(doc, from, to, options, type) {
options = copyObj(options);
options.shared = false;
var markers = [markText(doc, from, to, options, type)], primary = markers[0];
var widget = options.widgetNode;
linkedDocs(doc, function(doc) {
if (widget) options.widgetNode = widget.cloneNode(true);
markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
for (var i = 0; i < doc.linked.length; ++i)
if (doc.linked[i].isParent) return;
primary = lst(markers);
});
return new SharedTextMarker(markers, primary);
}
function findSharedMarkers(doc) {
return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
function(m) { return m.parent; });
}
function copySharedMarkers(doc, markers) {
for (var i = 0; i < markers.length; i++) {
var marker = markers[i], pos = marker.find();
var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
if (cmp(mFrom, mTo)) {
var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
marker.markers.push(subMark);
subMark.parent = marker;
}
}
}
function detachSharedMarkers(markers) {
for (var i = 0; i < markers.length; i++) {
var marker = markers[i], linked = [marker.primary.doc];;
linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
for (var j = 0; j < marker.markers.length; j++) {
var subMarker = marker.markers[j];
if (indexOf(linked, subMarker.doc) == -1) {
subMarker.parent = null;
marker.markers.splice(j--, 1);
}
}
}
}
// TEXTMARKER SPANS
function MarkedSpan(marker, from, to) {
this.marker = marker;
this.from = from; this.to = to;
}
// Search an array of spans for a span matching the given marker.
function getMarkedSpanFor(spans, marker) {
if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
if (span.marker == marker) return span;
}
}
// Remove a span from an array, returning undefined if no spans are
// left (we don't store arrays for lines without spans).
function removeMarkedSpan(spans, span) {
for (var r, i = 0; i < spans.length; ++i)
if (spans[i] != span) (r || (r = [])).push(spans[i]);
return r;
}
// Add a span to a line.
function addMarkedSpan(line, span) {
line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
span.marker.attachLine(line);
}
// Used for the algorithm that adjusts markers for a change in the
// document. These functions cut an array of spans at a given
// character position, returning an array of remaining chunks (or
// undefined if nothing remains).
function markedSpansBefore(old, startCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
}
}
return nw;
}
function markedSpansAfter(old, endCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
span.to == null ? null : span.to - endCh));
}
}
return nw;
}
// Given a change object, compute the new set of marker spans that
// cover the line in which the change took place. Removes spans
// entirely within the change, reconnects spans belonging to the
// same marker that appear on both sides of the change, and cuts off
// spans partially within the change. Returns an array of span
// arrays with one element for each line in (after) the change.
function stretchSpansOverChange(doc, change) {
if (change.full) return null;
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
if (!oldFirst && !oldLast) return null;
var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
// Get the spans that 'stick out' on both sides
var first = markedSpansBefore(oldFirst, startCh, isInsert);
var last = markedSpansAfter(oldLast, endCh, isInsert);
// Next, merge those two ends
var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
if (first) {
// Fix up .to properties of first
for (var i = 0; i < first.length; ++i) {
var span = first[i];
if (span.to == null) {
var found = getMarkedSpanFor(last, span.marker);
if (!found) span.to = startCh;
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
}
}
}
if (last) {
// Fix up .from in last (or move them into first in case of sameLine)
for (var i = 0; i < last.length; ++i) {
var span = last[i];
if (span.to != null) span.to += offset;
if (span.from == null) {
var found = getMarkedSpanFor(first, span.marker);
if (!found) {
span.from = offset;
if (sameLine) (first || (first = [])).push(span);
}
} else {
span.from += offset;
if (sameLine) (first || (first = [])).push(span);
}
}
}
// Make sure we didn't create any zero-length spans
if (first) first = clearEmptySpans(first);
if (last && last != first) last = clearEmptySpans(last);
var newMarkers = [first];
if (!sameLine) {
// Fill gap with whole-line-spans
var gap = change.text.length - 2, gapMarkers;
if (gap > 0 && first)
for (var i = 0; i < first.length; ++i)
if (first[i].to == null)
(gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
for (var i = 0; i < gap; ++i)
newMarkers.push(gapMarkers);
newMarkers.push(last);
}
return newMarkers;
}
// Remove spans that are empty and don't have a clearWhenEmpty
// option of false.
function clearEmptySpans(spans) {
for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
spans.splice(i--, 1);
}
if (!spans.length) return null;
return spans;
}
// Used for un/re-doing changes from the history. Combines the
// result of computing the existing spans with the set of spans that
// existed in the history (so that deleting around a span and then
// undoing brings back the span).
function mergeOldSpans(doc, change) {
var old = getOldSpans(doc, change);
var stretched = stretchSpansOverChange(doc, change);
if (!old) return stretched;
if (!stretched) return old;
for (var i = 0; i < old.length; ++i) {
var oldCur = old[i], stretchCur = stretched[i];
if (oldCur && stretchCur) {
spans: for (var j = 0; j < stretchCur.length; ++j) {
var span = stretchCur[j];
for (var k = 0; k < oldCur.length; ++k)
if (oldCur[k].marker == span.marker) continue spans;
oldCur.push(span);
}
} else if (stretchCur) {
old[i] = stretchCur;
}
}
return old;
}
// Used to 'clip' out readOnly ranges when making a change.
function removeReadOnlyRanges(doc, from, to) {
var markers = null;
doc.iter(from.line, to.line + 1, function(line) {
if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
var mark = line.markedSpans[i].marker;
if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
(markers || (markers = [])).push(mark);
}
});
if (!markers) return null;
var parts = [{from: from, to: to}];
for (var i = 0; i < markers.length; ++i) {
var mk = markers[i], m = mk.find(0);
for (var j = 0; j < parts.length; ++j) {
var p = parts[j];
if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
newParts.push({from: p.from, to: m.from});
if (dto > 0 || !mk.inclusiveRight && !dto)
newParts.push({from: m.to, to: p.to});
parts.splice.apply(parts, newParts);
j += newParts.length - 1;
}
}
return parts;
}
// Connect or disconnect spans from a line.
function detachMarkedSpans(line) {
var spans = line.markedSpans;
if (!spans) return;
for (var i = 0; i < spans.length; ++i)
spans[i].marker.detachLine(line);
line.markedSpans = null;
}
function attachMarkedSpans(line, spans) {
if (!spans) return;
for (var i = 0; i < spans.length; ++i)
spans[i].marker.attachLine(line);
line.markedSpans = spans;
}
// Helpers used when computing which overlapping collapsed span
// counts as the larger one.
function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
// Returns a number indicating which of two overlapping collapsed
// spans is larger (and thus includes the other). Falls back to
// comparing ids when the spans cover exactly the same range.
function compareCollapsedMarkers(a, b) {
var lenDiff = a.lines.length - b.lines.length;
if (lenDiff != 0) return lenDiff;
var aPos = a.find(), bPos = b.find();
var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
if (fromCmp) return -fromCmp;
var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
if (toCmp) return toCmp;
return b.id - a.id;
}
// Find out whether a line ends or starts in a collapsed span. If
// so, return the marker for that span.
function collapsedSpanAtSide(line, start) {
var sps = sawCollapsedSpans && line.markedSpans, found;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
(!found || compareCollapsedMarkers(found, sp.marker) < 0))
found = sp.marker;
}
return found;
}
function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
// Test whether there exists a collapsed span that partially
// overlaps (covers the start or end, but not both) of a new span.
// Such overlap is not allowed.
function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
var line = getLine(doc, lineNo);
var sps = sawCollapsedSpans && line.markedSpans;
if (sps) for (var i = 0; i < sps.length; ++i) {
var sp = sps[i];
if (!sp.marker.collapsed) continue;
var found = sp.marker.find(0);
var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||
fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))
return true;
}
}
// A visual line is a line as drawn on the screen. Folding, for
// example, can cause multiple logical lines to appear on the same
// visual line. This finds the start of the visual line that the
// given line is part of (usually that is the line itself).
function visualLine(line) {
var merged;
while (merged = collapsedSpanAtStart(line))
line = merged.find(-1, true).line;
return line;
}
// Returns an array of logical lines that continue the visual line
// started by the argument, or undefined if there are no such lines.
function visualLineContinued(line) {
var merged, lines;
while (merged = collapsedSpanAtEnd(line)) {
line = merged.find(1, true).line;
(lines || (lines = [])).push(line);
}
return lines;
}
// Get the line number of the start of the visual line that the
// given line number is part of.
function visualLineNo(doc, lineN) {
var line = getLine(doc, lineN), vis = visualLine(line);
if (line == vis) return lineN;
return lineNo(vis);
}
// Get the line number of the start of the next visual line after
// the given line.
function visualLineEndNo(doc, lineN) {
if (lineN > doc.lastLine()) return lineN;
var line = getLine(doc, lineN), merged;
if (!lineIsHidden(doc, line)) return lineN;
while (merged = collapsedSpanAtEnd(line))
line = merged.find(1, true).line;
return lineNo(line) + 1;
}
// Compute whether a line is hidden. Lines count as hidden when they
// are part of a visual line that starts with another line, or when
// they are entirely covered by collapsed, non-widget span.
function lineIsHidden(doc, line) {
var sps = sawCollapsedSpans && line.markedSpans;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
if (!sp.marker.collapsed) continue;
if (sp.from == null) return true;
if (sp.marker.widgetNode) continue;
if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
return true;
}
}
function lineIsHiddenInner(doc, line, span) {
if (span.to == null) {
var end = span.marker.find(1, true);
return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
}
if (span.marker.inclusiveRight && span.to == line.text.length)
return true;
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
sp = line.markedSpans[i];
if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
(sp.to == null || sp.to != span.from) &&
(sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
lineIsHiddenInner(doc, line, sp)) return true;
}
}
// LINE WIDGETS
// Line widgets are block elements displayed above or below a line.
var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
this[opt] = options[opt];
this.cm = cm;
this.node = node;
};
eventMixin(LineWidget);
function adjustScrollWhenAboveVisible(cm, line, diff) {
if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
addToScrollPos(cm, null, diff);
}
LineWidget.prototype.clear = function() {
var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
if (no == null || !ws) return;
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
if (!ws.length) line.widgets = null;
var height = widgetHeight(this);
runInOp(cm, function() {
adjustScrollWhenAboveVisible(cm, line, -height);
regLineChange(cm, no, "widget");
updateLineHeight(line, Math.max(0, line.height - height));
});
};
LineWidget.prototype.changed = function() {
var oldH = this.height, cm = this.cm, line = this.line;
this.height = null;
var diff = widgetHeight(this) - oldH;
if (!diff) return;
runInOp(cm, function() {
cm.curOp.forceUpdate = true;
adjustScrollWhenAboveVisible(cm, line, diff);
updateLineHeight(line, line.height + diff);
});
};
function widgetHeight(widget) {
if (widget.height != null) return widget.height;
if (!contains(document.body, widget.node)) {
var parentStyle = "position: relative;";
if (widget.coverGutter)
parentStyle += "margin-left: -" + widget.cm.display.gutters.offsetWidth + "px;";
if (widget.noHScroll)
parentStyle += "width: " + widget.cm.display.wrapper.clientWidth + "px;";
removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle));
}
return widget.height = widget.node.offsetHeight;
}
function addLineWidget(cm, handle, node, options) {
var widget = new LineWidget(cm, node, options);
if (widget.noHScroll) cm.display.alignWidgets = true;
changeLine(cm.doc, handle, "widget", function(line) {
var widgets = line.widgets || (line.widgets = []);
if (widget.insertAt == null) widgets.push(widget);
else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
widget.line = line;
if (!lineIsHidden(cm.doc, line)) {
var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
updateLineHeight(line, line.height + widgetHeight(widget));
if (aboveVisible) addToScrollPos(cm, null, widget.height);
cm.curOp.forceUpdate = true;
}
return true;
});
return widget;
}
// LINE DATA STRUCTURE
// Line objects. These hold state related to a line, including
// highlighting info (the styles array).
var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
this.text = text;
attachMarkedSpans(this, markedSpans);
this.height = estimateHeight ? estimateHeight(this) : 1;
};
eventMixin(Line);
Line.prototype.lineNo = function() { return lineNo(this); };
// Change the content (text, markers) of a line. Automatically
// invalidates cached information and tries to re-estimate the
// line's height.
function updateLine(line, text, markedSpans, estimateHeight) {
line.text = text;
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
if (line.order != null) line.order = null;
detachMarkedSpans(line);
attachMarkedSpans(line, markedSpans);
var estHeight = estimateHeight ? estimateHeight(line) : 1;
if (estHeight != line.height) updateLineHeight(line, estHeight);
}
// Detach a line from the document tree and its markers.
function cleanUpLine(line) {
line.parent = null;
detachMarkedSpans(line);
}
function extractLineClasses(type, output) {
if (type) for (;;) {
var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
if (!lineClass) break;
type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
var prop = lineClass[1] ? "bgClass" : "textClass";
if (output[prop] == null)
output[prop] = lineClass[2];
else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
output[prop] += " " + lineClass[2];
}
return type;
}
function callBlankLine(mode, state) {
if (mode.blankLine) return mode.blankLine(state);
if (!mode.innerMode) return;
var inner = CodeMirror.innerMode(mode, state);
if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
}
function readToken(mode, stream, state, inner) {
for (var i = 0; i < 10; i++) {
if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;
var style = mode.token(stream, state);
if (stream.pos > stream.start) return style;
}
throw new Error("Mode " + mode.name + " failed to advance stream.");
}
// Utility for getTokenAt and getLineTokens
function takeToken(cm, pos, precise, asArray) {
function getObj(copy) {
return {start: stream.start, end: stream.pos,
string: stream.current(),
type: style || null,
state: copy ? copyState(doc.mode, state) : state};
}
var doc = cm.doc, mode = doc.mode, style;
pos = clipPos(doc, pos);
var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
var stream = new StringStream(line.text, cm.options.tabSize), tokens;
if (asArray) tokens = [];
while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
stream.start = stream.pos;
style = readToken(mode, stream, state);
if (asArray) tokens.push(getObj(true));
}
return asArray ? tokens : getObj();
}
// Run the given mode's parser over a line, calling f for each token.
function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
var flattenSpans = mode.flattenSpans;
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
var curStart = 0, curStyle = null;
var stream = new StringStream(text, cm.options.tabSize), style;
var inner = cm.options.addModeClass && [null];
if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
while (!stream.eol()) {
if (stream.pos > cm.options.maxHighlightLength) {
flattenSpans = false;
if (forceToEnd) processLine(cm, text, state, stream.pos);
stream.pos = text.length;
style = null;
} else {
style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);
}
if (inner) {
var mName = inner[0].name;
if (mName) style = "m-" + (style ? mName + " " + style : mName);
}
if (!flattenSpans || curStyle != style) {
while (curStart < stream.start) {
curStart = Math.min(stream.start, curStart + 50000);
f(curStart, curStyle);
}
curStyle = style;
}
stream.start = stream.pos;
}
while (curStart < stream.pos) {
// Webkit seems to refuse to render text nodes longer than 57444 characters
var pos = Math.min(stream.pos, curStart + 50000);
f(pos, curStyle);
curStart = pos;
}
}
// Compute a style array (an array starting with a mode generation
// -- for invalidation -- followed by pairs of end positions and
// style strings), which is used to highlight the tokens on the
// line.
function highlightLine(cm, line, state, forceToEnd) {
// A styles array always starts with a number identifying the
// mode/overlays that it is based on (for easy invalidation).
var st = [cm.state.modeGen], lineClasses = {};
// Compute the base array of styles
runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
st.push(end, style);
}, lineClasses, forceToEnd);
// Run overlays, adjust style array.
for (var o = 0; o < cm.state.overlays.length; ++o) {
var overlay = cm.state.overlays[o], i = 1, at = 0;
runMode(cm, line.text, overlay.mode, true, function(end, style) {
var start = i;
// Ensure there's a token end at the current position, and that i points at it
while (at < end) {
var i_end = st[i];
if (i_end > end)
st.splice(i, 1, end, st[i+1], i_end);
i += 2;
at = Math.min(end, i_end);
}
if (!style) return;
if (overlay.opaque) {
st.splice(start, i - start, end, "cm-overlay " + style);
i = start + 2;
} else {
for (; start < i; start += 2) {
var cur = st[start+1];
st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
}
}
}, lineClasses);
}
return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
}
function getLineStyles(cm, line, updateFrontier) {
if (!line.styles || line.styles[0] != cm.state.modeGen) {
var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
line.styles = result.styles;
if (result.classes) line.styleClasses = result.classes;
else if (line.styleClasses) line.styleClasses = null;
if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
}
return line.styles;
}
// Lightweight form of highlight -- proceed over this line and
// update state, but don't save a style array. Used for lines that
// aren't currently visible.
function processLine(cm, text, state, startAt) {
var mode = cm.doc.mode;
var stream = new StringStream(text, cm.options.tabSize);
stream.start = stream.pos = startAt || 0;
if (text == "") callBlankLine(mode, state);
while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
readToken(mode, stream, state);
stream.start = stream.pos;
}
}
// Convert a style as returned by a mode (either null, or a string
// containing one or more styles) to a CSS style. This is cached,
// and also looks for line-wide styles.
var styleToClassCache = {}, styleToClassCacheWithMode = {};
function interpretTokenStyle(style, options) {
if (!style || /^\s*$/.test(style)) return null;
var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
return cache[style] ||
(cache[style] = style.replace(/\S+/g, "cm-$&"));
}
// Render the DOM representation of the text of a line. Also builds
// up a 'line map', which points at the DOM nodes that represent
// specific stretches of text, and is used by the measuring code.
// The returned object contains the DOM node, this map, and
// information about line-wide styles that were set by the mode.
function buildLineContent(cm, lineView) {
// The padding-right forces the element to have a 'border', which
// is needed on Webkit to be able to get line-level bounding
// rectangles for it (in measureChar).
var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
lineView.measure = {};
// Iterate over the logical lines that make up this visual line.
for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
var line = i ? lineView.rest[i - 1] : lineView.line, order;
builder.pos = 0;
builder.addToken = buildToken;
// Optionally wire in some hacks into the token-rendering
// algorithm, to deal with browser quirks.
if ((ie || webkit) && cm.getOption("lineWrapping"))
builder.addToken = buildTokenSplitSpaces(builder.addToken);
if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
builder.addToken = buildTokenBadBidi(builder.addToken, order);
builder.map = [];
var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
if (line.styleClasses) {
if (line.styleClasses.bgClass)
builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
if (line.styleClasses.textClass)
builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
}
// Ensure at least a single node is present, for measuring.
if (builder.map.length == 0)
builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
// Store the map and a cache object for the current logical line
if (i == 0) {
lineView.measure.map = builder.map;
lineView.measure.cache = {};
} else {
(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
(lineView.measure.caches || (lineView.measure.caches = [])).push({});
}
}
// See issue #2901
if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
builder.content.className = "cm-tab-wrap-hack";
signal(cm, "renderLine", cm, lineView.line, builder.pre);
if (builder.pre.className)
builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
return builder;
}
function defaultSpecialCharPlaceholder(ch) {
var token = elt("span", "\u2022", "cm-invalidchar");
token.title = "\\u" + ch.charCodeAt(0).toString(16);
return token;
}
// Build up the DOM representation for a single token, and add it to
// the line map. Takes care to render special characters separately.
function buildToken(builder, text, style, startStyle, endStyle, title, css) {
if (!text) return;
var special = builder.cm.options.specialChars, mustWrap = false;
if (!special.test(text)) {
builder.col += text.length;
var content = document.createTextNode(text);
builder.map.push(builder.pos, builder.pos + text.length, content);
if (ie && ie_version < 9) mustWrap = true;
builder.pos += text.length;
} else {
var content = document.createDocumentFragment(), pos = 0;
while (true) {
special.lastIndex = pos;
var m = special.exec(text);
var skipped = m ? m.index - pos : text.length - pos;
if (skipped) {
var txt = document.createTextNode(text.slice(pos, pos + skipped));
if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
else content.appendChild(txt);
builder.map.push(builder.pos, builder.pos + skipped, txt);
builder.col += skipped;
builder.pos += skipped;
}
if (!m) break;
pos += skipped + 1;
if (m[0] == "\t") {
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
builder.col += tabWidth;
} else {
var txt = builder.cm.options.specialCharPlaceholder(m[0]);
if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
else content.appendChild(txt);
builder.col += 1;
}
builder.map.push(builder.pos, builder.pos + 1, txt);
builder.pos++;
}
}
if (style || startStyle || endStyle || mustWrap || css) {
var fullStyle = style || "";
if (startStyle) fullStyle += startStyle;
if (endStyle) fullStyle += endStyle;
var token = elt("span", [content], fullStyle, css);
if (title) token.title = title;
return builder.content.appendChild(token);
}
builder.content.appendChild(content);
}
function buildTokenSplitSpaces(inner) {
function split(old) {
var out = " ";
for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
out += " ";
return out;
}
return function(builder, text, style, startStyle, endStyle, title) {
inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
};
}
// Work around nonsense dimensions being reported for stretches of
// right-to-left text.
function buildTokenBadBidi(inner, order) {
return function(builder, text, style, startStyle, endStyle, title) {
style = style ? style + " cm-force-border" : "cm-force-border";
var start = builder.pos, end = start + text.length;
for (;;) {
// Find the part that overlaps with the start of this text
for (var i = 0; i < order.length; i++) {
var part = order[i];
if (part.to > start && part.from <= start) break;
}
if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
startStyle = null;
text = text.slice(part.to - start);
start = part.to;
}
};
}
function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
var widget = !ignoreWidget && marker.widgetNode;
if (widget) {
builder.map.push(builder.pos, builder.pos + size, widget);
builder.content.appendChild(widget);
}
builder.pos += size;
}
// Outputs a number of spans to make up a line, taking highlighting
// and marked text into account.
function insertLineContent(line, builder, styles) {
var spans = line.markedSpans, allText = line.text, at = 0;
if (!spans) {
for (var i = 1; i < styles.length; i+=2)
builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
return;
}
var len = allText.length, pos = 0, i = 1, text = "", style, css;
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
for (;;) {
if (nextChange == pos) { // Update current marker set
spanStyle = spanEndStyle = spanStartStyle = title = css = "";
collapsed = null; nextChange = Infinity;
var foundBookmarks = [];
for (var j = 0; j < spans.length; ++j) {
var sp = spans[j], m = sp.marker;
if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
if (m.className) spanStyle += " " + m.className;
if (m.css) css = m.css;
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
if (m.title && !title) title = m.title;
if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
collapsed = sp;
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
}
if (collapsed && (collapsed.from || 0) == pos) {
buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
collapsed.marker, collapsed.from == null);
if (collapsed.to == null) return;
}
if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
buildCollapsedSpan(builder, 0, foundBookmarks[j]);
}
if (pos >= len) break;
var upto = Math.min(len, nextChange);
while (true) {
if (text) {
var end = pos + text.length;
if (!collapsed) {
var tokenText = end > upto ? text.slice(0, upto - pos) : text;
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
}
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
pos = end;
spanStartStyle = "";
}
text = allText.slice(at, at = styles[i++]);
style = interpretTokenStyle(styles[i++], builder.cm.options);
}
}
}
// DOCUMENT DATA STRUCTURE
// By default, updates that start and end at the beginning of a line
// are treated specially, in order to make the association of line
// widgets and marker elements with the text behave more intuitive.
function isWholeLineUpdate(doc, change) {
return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
(!doc.cm || doc.cm.options.wholeLineUpdateBefore);
}
// Perform a change on the document data structure.
function updateDoc(doc, change, markedSpans, estimateHeight) {
function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
function update(line, text, spans) {
updateLine(line, text, spans, estimateHeight);
signalLater(line, "change", line, change);
}
function linesFor(start, end) {
for (var i = start, result = []; i < end; ++i)
result.push(new Line(text[i], spansFor(i), estimateHeight));
return result;
}
var from = change.from, to = change.to, text = change.text;
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
// Adjust the line structure
if (change.full) {
doc.insert(0, linesFor(0, text.length));
doc.remove(text.length, doc.size - text.length);
} else if (isWholeLineUpdate(doc, change)) {
// This is a whole-line replace. Treated specially to make
// sure line objects move the way they are supposed to.
var added = linesFor(0, text.length - 1);
update(lastLine, lastLine.text, lastSpans);
if (nlines) doc.remove(from.line, nlines);
if (added.length) doc.insert(from.line, added);
} else if (firstLine == lastLine) {
if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
} else {
var added = linesFor(1, text.length - 1);
added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
doc.insert(from.line + 1, added);
}
} else if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
doc.remove(from.line + 1, nlines);
} else {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
var added = linesFor(1, text.length - 1);
if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
doc.insert(from.line + 1, added);
}
signalLater(doc, "change", doc, change);
}
// The document is represented as a BTree consisting of leaves, with
// chunk of lines in them, and branches, with up to ten leaves or
// other branch nodes below them. The top node is always a branch
// node, and is the document object itself (meaning it has
// additional methods and properties).
//
// All nodes have parent links. The tree is used both to go from
// line numbers to line objects, and to go from objects to numbers.
// It also indexes by height, and is used to convert between height
// and line object, and to find the total height of the document.
//
// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
function LeafChunk(lines) {
this.lines = lines;
this.parent = null;
for (var i = 0, height = 0; i < lines.length; ++i) {
lines[i].parent = this;
height += lines[i].height;
}
this.height = height;
}
LeafChunk.prototype = {
chunkSize: function() { return this.lines.length; },
// Remove the n lines at offset 'at'.
removeInner: function(at, n) {
for (var i = at, e = at + n; i < e; ++i) {
var line = this.lines[i];
this.height -= line.height;
cleanUpLine(line);
signalLater(line, "delete");
}
this.lines.splice(at, n);
},
// Helper used to collapse a small branch into a single leaf.
collapse: function(lines) {
lines.push.apply(lines, this.lines);
},
// Insert the given array of lines at offset 'at', count them as
// having the given height.
insertInner: function(at, lines, height) {
this.height += height;
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
},
// Used to iterate over a part of the tree.
iterN: function(at, n, op) {
for (var e = at + n; at < e; ++at)
if (op(this.lines[at])) return true;
}
};
function BranchChunk(children) {
this.children = children;
var size = 0, height = 0;
for (var i = 0; i < children.length; ++i) {
var ch = children[i];
size += ch.chunkSize(); height += ch.height;
ch.parent = this;
}
this.size = size;
this.height = height;
this.parent = null;
}
BranchChunk.prototype = {
chunkSize: function() { return this.size; },
removeInner: function(at, n) {
this.size -= n;
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var rm = Math.min(n, sz - at), oldHeight = child.height;
child.removeInner(at, rm);
this.height -= oldHeight - child.height;
if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
if ((n -= rm) == 0) break;
at = 0;
} else at -= sz;
}
// If the result is smaller than 25 lines, ensure that it is a
// single leaf node.
if (this.size - n < 25 &&
(this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
var lines = [];
this.collapse(lines);
this.children = [new LeafChunk(lines)];
this.children[0].parent = this;
}
},
collapse: function(lines) {
for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
},
insertInner: function(at, lines, height) {
this.size += lines.length;
this.height += height;
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at <= sz) {
child.insertInner(at, lines, height);
if (child.lines && child.lines.length > 50) {
while (child.lines.length > 50) {
var spilled = child.lines.splice(child.lines.length - 25, 25);
var newleaf = new LeafChunk(spilled);
child.height -= newleaf.height;
this.children.splice(i + 1, 0, newleaf);
newleaf.parent = this;
}
this.maybeSpill();
}
break;
}
at -= sz;
}
},
// When a node has grown, check whether it should be split.
maybeSpill: function() {
if (this.children.length <= 10) return;
var me = this;
do {
var spilled = me.children.splice(me.children.length - 5, 5);
var sibling = new BranchChunk(spilled);
if (!me.parent) { // Become the parent node
var copy = new BranchChunk(me.children);
copy.parent = me;
me.children = [copy, sibling];
me = copy;
} else {
me.size -= sibling.size;
me.height -= sibling.height;
var myIndex = indexOf(me.parent.children, me);
me.parent.children.splice(myIndex + 1, 0, sibling);
}
sibling.parent = me.parent;
} while (me.children.length > 10);
me.parent.maybeSpill();
},
iterN: function(at, n, op) {
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var used = Math.min(n, sz - at);
if (child.iterN(at, used, op)) return true;
if ((n -= used) == 0) break;
at = 0;
} else at -= sz;
}
}
};
var nextDocId = 0;
var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
if (firstLine == null) firstLine = 0;
BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
this.first = firstLine;
this.scrollTop = this.scrollLeft = 0;
this.cantEdit = false;
this.cleanGeneration = 1;
this.frontier = firstLine;
var start = Pos(firstLine, 0);
this.sel = simpleSelection(start);
this.history = new History(null);
this.id = ++nextDocId;
this.modeOption = mode;
if (typeof text == "string") text = splitLines(text);
updateDoc(this, {from: start, to: start, text: text});
setSelection(this, simpleSelection(start), sel_dontScroll);
};
Doc.prototype = createObj(BranchChunk.prototype, {
constructor: Doc,
// Iterate over the document. Supports two forms -- with only one
// argument, it calls that for each line in the document. With
// three, it iterates over the range given by the first two (with
// the second being non-inclusive).
iter: function(from, to, op) {
if (op) this.iterN(from - this.first, to - from, op);
else this.iterN(this.first, this.first + this.size, from);
},
// Non-public interface for adding and removing lines.
insert: function(at, lines) {
var height = 0;
for (var i = 0; i < lines.length; ++i) height += lines[i].height;
this.insertInner(at - this.first, lines, height);
},
remove: function(at, n) { this.removeInner(at - this.first, n); },
// From here, the methods are part of the public interface. Most
// are also available from CodeMirror (editor) instances.
getValue: function(lineSep) {
var lines = getLines(this, this.first, this.first + this.size);
if (lineSep === false) return lines;
return lines.join(lineSep || "\n");
},
setValue: docMethodOp(function(code) {
var top = Pos(this.first, 0), last = this.first + this.size - 1;
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
text: splitLines(code), origin: "setValue", full: true}, true);
setSelection(this, simpleSelection(top));
}),
replaceRange: function(code, from, to, origin) {
from = clipPos(this, from);
to = to ? clipPos(this, to) : from;
replaceRange(this, code, from, to, origin);
},
getRange: function(from, to, lineSep) {
var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
if (lineSep === false) return lines;
return lines.join(lineSep || "\n");
},
getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
getLineNumber: function(line) {return lineNo(line);},
getLineHandleVisualStart: function(line) {
if (typeof line == "number") line = getLine(this, line);
return visualLine(line);
},
lineCount: function() {return this.size;},
firstLine: function() {return this.first;},
lastLine: function() {return this.first + this.size - 1;},
clipPos: function(pos) {return clipPos(this, pos);},
getCursor: function(start) {
var range = this.sel.primary(), pos;
if (start == null || start == "head") pos = range.head;
else if (start == "anchor") pos = range.anchor;
else if (start == "end" || start == "to" || start === false) pos = range.to();
else pos = range.from();
return pos;
},
listSelections: function() { return this.sel.ranges; },
somethingSelected: function() {return this.sel.somethingSelected();},
setCursor: docMethodOp(function(line, ch, options) {
setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
}),
setSelection: docMethodOp(function(anchor, head, options) {
setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
}),
extendSelection: docMethodOp(function(head, other, options) {
extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
}),
extendSelections: docMethodOp(function(heads, options) {
extendSelections(this, clipPosArray(this, heads, options));
}),
extendSelectionsBy: docMethodOp(function(f, options) {
extendSelections(this, map(this.sel.ranges, f), options);
}),
setSelections: docMethodOp(function(ranges, primary, options) {
if (!ranges.length) return;
for (var i = 0, out = []; i < ranges.length; i++)
out[i] = new Range(clipPos(this, ranges[i].anchor),
clipPos(this, ranges[i].head));
if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
setSelection(this, normalizeSelection(out, primary), options);
}),
addSelection: docMethodOp(function(anchor, head, options) {
var ranges = this.sel.ranges.slice(0);
ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
}),
getSelection: function(lineSep) {
var ranges = this.sel.ranges, lines;
for (var i = 0; i < ranges.length; i++) {
var sel = getBetween(this, ranges[i].from(), ranges[i].to());
lines = lines ? lines.concat(sel) : sel;
}
if (lineSep === false) return lines;
else return lines.join(lineSep || "\n");
},
getSelections: function(lineSep) {
var parts = [], ranges = this.sel.ranges;
for (var i = 0; i < ranges.length; i++) {
var sel = getBetween(this, ranges[i].from(), ranges[i].to());
if (lineSep !== false) sel = sel.join(lineSep || "\n");
parts[i] = sel;
}
return parts;
},
replaceSelection: function(code, collapse, origin) {
var dup = [];
for (var i = 0; i < this.sel.ranges.length; i++)
dup[i] = code;
this.replaceSelections(dup, collapse, origin || "+input");
},
replaceSelections: docMethodOp(function(code, collapse, origin) {
var changes = [], sel = this.sel;
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
}
var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
for (var i = changes.length - 1; i >= 0; i--)
makeChange(this, changes[i]);
if (newSel) setSelectionReplaceHistory(this, newSel);
else if (this.cm) ensureCursorVisible(this.cm);
}),
undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
setExtending: function(val) {this.extend = val;},
getExtending: function() {return this.extend;},
historySize: function() {
var hist = this.history, done = 0, undone = 0;
for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
return {undo: done, redo: undone};
},
clearHistory: function() {this.history = new History(this.history.maxGeneration);},
markClean: function() {
this.cleanGeneration = this.changeGeneration(true);
},
changeGeneration: function(forceSplit) {
if (forceSplit)
this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
return this.history.generation;
},
isClean: function (gen) {
return this.history.generation == (gen || this.cleanGeneration);
},
getHistory: function() {
return {done: copyHistoryArray(this.history.done),
undone: copyHistoryArray(this.history.undone)};
},
setHistory: function(histData) {
var hist = this.history = new History(this.history.maxGeneration);
hist.done = copyHistoryArray(histData.done.slice(0), null, true);
hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
},
addLineClass: docMethodOp(function(handle, where, cls) {
return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
var prop = where == "text" ? "textClass"
: where == "background" ? "bgClass"
: where == "gutter" ? "gutterClass" : "wrapClass";
if (!line[prop]) line[prop] = cls;
else if (classTest(cls).test(line[prop])) return false;
else line[prop] += " " + cls;
return true;
});
}),
removeLineClass: docMethodOp(function(handle, where, cls) {
return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
var prop = where == "text" ? "textClass"
: where == "background" ? "bgClass"
: where == "gutter" ? "gutterClass" : "wrapClass";
var cur = line[prop];
if (!cur) return false;
else if (cls == null) line[prop] = null;
else {
var found = cur.match(classTest(cls));
if (!found) return false;
var end = found.index + found[0].length;
line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
}
return true;
});
}),
markText: function(from, to, options) {
return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
},
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
insertLeft: options && options.insertLeft,
clearWhenEmpty: false, shared: options && options.shared};
pos = clipPos(this, pos);
return markText(this, pos, pos, realOpts, "bookmark");
},
findMarksAt: function(pos) {
pos = clipPos(this, pos);
var markers = [], spans = getLine(this, pos.line).markedSpans;
if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
if ((span.from == null || span.from <= pos.ch) &&
(span.to == null || span.to >= pos.ch))
markers.push(span.marker.parent || span.marker);
}
return markers;
},
findMarks: function(from, to, filter) {
from = clipPos(this, from); to = clipPos(this, to);
var found = [], lineNo = from.line;
this.iter(from.line, to.line + 1, function(line) {
var spans = line.markedSpans;
if (spans) for (var i = 0; i < spans.length; i++) {
var span = spans[i];
if (!(lineNo == from.line && from.ch > span.to ||
span.from == null && lineNo != from.line||
lineNo == to.line && span.from > to.ch) &&
(!filter || filter(span.marker)))
found.push(span.marker.parent || span.marker);
}
++lineNo;
});
return found;
},
getAllMarks: function() {
var markers = [];
this.iter(function(line) {
var sps = line.markedSpans;
if (sps) for (var i = 0; i < sps.length; ++i)
if (sps[i].from != null) markers.push(sps[i].marker);
});
return markers;
},
posFromIndex: function(off) {
var ch, lineNo = this.first;
this.iter(function(line) {
var sz = line.text.length + 1;
if (sz > off) { ch = off; return true; }
off -= sz;
++lineNo;
});
return clipPos(this, Pos(lineNo, ch));
},
indexFromPos: function (coords) {
coords = clipPos(this, coords);
var index = coords.ch;
if (coords.line < this.first || coords.ch < 0) return 0;
this.iter(this.first, coords.line, function (line) {
index += line.text.length + 1;
});
return index;
},
copy: function(copyHistory) {
var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
doc.sel = this.sel;
doc.extend = false;
if (copyHistory) {
doc.history.undoDepth = this.history.undoDepth;
doc.setHistory(this.getHistory());
}
return doc;
},
linkedDoc: function(options) {
if (!options) options = {};
var from = this.first, to = this.first + this.size;
if (options.from != null && options.from > from) from = options.from;
if (options.to != null && options.to < to) to = options.to;
var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
if (options.sharedHist) copy.history = this.history;
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
copySharedMarkers(copy, findSharedMarkers(this));
return copy;
},
unlinkDoc: function(other) {
if (other instanceof CodeMirror) other = other.doc;
if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
var link = this.linked[i];
if (link.doc != other) continue;
this.linked.splice(i, 1);
other.unlinkDoc(this);
detachSharedMarkers(findSharedMarkers(this));
break;
}
// If the histories were shared, split them again
if (other.history == this.history) {
var splitIds = [other.id];
linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
other.history = new History(null);
other.history.done = copyHistoryArray(this.history.done, splitIds);
other.history.undone = copyHistoryArray(this.history.undone, splitIds);
}
},
iterLinkedDocs: function(f) {linkedDocs(this, f);},
getMode: function() {return this.mode;},
getEditor: function() {return this.cm;}
});
// Public alias.
Doc.prototype.eachLine = Doc.prototype.iter;
// Set up methods on CodeMirror's prototype to redirect to the editor's document.
var dontDelegate = "iter insert remove copy getEditor".split(" ");
for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
CodeMirror.prototype[prop] = (function(method) {
return function() {return method.apply(this.doc, arguments);};
})(Doc.prototype[prop]);
eventMixin(Doc);
// Call f for all linked documents.
function linkedDocs(doc, f, sharedHistOnly) {
function propagate(doc, skip, sharedHist) {
if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
var rel = doc.linked[i];
if (rel.doc == skip) continue;
var shared = sharedHist && rel.sharedHist;
if (sharedHistOnly && !shared) continue;
f(rel.doc, shared);
propagate(rel.doc, doc, shared);
}
}
propagate(doc, null, true);
}
// Attach a document to an editor.
function attachDoc(cm, doc) {
if (doc.cm) throw new Error("This document is already in use.");
cm.doc = doc;
doc.cm = cm;
estimateLineHeights(cm);
loadMode(cm);
if (!cm.options.lineWrapping) findMaxLine(cm);
cm.options.mode = doc.modeOption;
regChange(cm);
}
// LINE UTILITIES
// Find the line object corresponding to the given line number.
function getLine(doc, n) {
n -= doc.first;
if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
for (var chunk = doc; !chunk.lines;) {
for (var i = 0;; ++i) {
var child = chunk.children[i], sz = child.chunkSize();
if (n < sz) { chunk = child; break; }
n -= sz;
}
}
return chunk.lines[n];
}
// Get the part of a document between two positions, as an array of
// strings.
function getBetween(doc, start, end) {
var out = [], n = start.line;
doc.iter(start.line, end.line + 1, function(line) {
var text = line.text;
if (n == end.line) text = text.slice(0, end.ch);
if (n == start.line) text = text.slice(start.ch);
out.push(text);
++n;
});
return out;
}
// Get the lines between from and to, as array of strings.
function getLines(doc, from, to) {
var out = [];
doc.iter(from, to, function(line) { out.push(line.text); });
return out;
}
// Update the height of a line, propagating the height change
// upwards to parent nodes.
function updateLineHeight(line, height) {
var diff = height - line.height;
if (diff) for (var n = line; n; n = n.parent) n.height += diff;
}
// Given a line object, find its line number by walking up through
// its parent links.
function lineNo(line) {
if (line.parent == null) return null;
var cur = line.parent, no = indexOf(cur.lines, line);
for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
for (var i = 0;; ++i) {
if (chunk.children[i] == cur) break;
no += chunk.children[i].chunkSize();
}
}
return no + cur.first;
}
// Find the line at the given vertical position, using the height
// information in the document tree.
function lineAtHeight(chunk, h) {
var n = chunk.first;
outer: do {
for (var i = 0; i < chunk.children.length; ++i) {
var child = chunk.children[i], ch = child.height;
if (h < ch) { chunk = child; continue outer; }
h -= ch;
n += child.chunkSize();
}
return n;
} while (!chunk.lines);
for (var i = 0; i < chunk.lines.length; ++i) {
var line = chunk.lines[i], lh = line.height;
if (h < lh) break;
h -= lh;
}
return n + i;
}
// Find the height above the given line.
function heightAtLine(lineObj) {
lineObj = visualLine(lineObj);
var h = 0, chunk = lineObj.parent;
for (var i = 0; i < chunk.lines.length; ++i) {
var line = chunk.lines[i];
if (line == lineObj) break;
else h += line.height;
}
for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
for (var i = 0; i < p.children.length; ++i) {
var cur = p.children[i];
if (cur == chunk) break;
else h += cur.height;
}
}
return h;
}
// Get the bidi ordering for the given line (and cache it). Returns
// false for lines that are fully left-to-right, and an array of
// BidiSpan objects otherwise.
function getOrder(line) {
var order = line.order;
if (order == null) order = line.order = bidiOrdering(line.text);
return order;
}
// HISTORY
function History(startGen) {
// Arrays of change events and selections. Doing something adds an
// event to done and clears undo. Undoing moves events from done
// to undone, redoing moves them in the other direction.
this.done = []; this.undone = [];
this.undoDepth = Infinity;
// Used to track when changes can be merged into a single undo
// event
this.lastModTime = this.lastSelTime = 0;
this.lastOp = this.lastSelOp = null;
this.lastOrigin = this.lastSelOrigin = null;
// Used by the isClean() method
this.generation = this.maxGeneration = startGen || 1;
}
// Create a history change event from an updateDoc-style change
// object.
function historyChangeFromChange(doc, change) {
var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
return histChange;
}
// Pop all selection events off the end of a history array. Stop at
// a change event.
function clearSelectionEvents(array) {
while (array.length) {
var last = lst(array);
if (last.ranges) array.pop();
else break;
}
}
// Find the top change event in the history. Pop off selection
// events that are in the way.
function lastChangeEvent(hist, force) {
if (force) {
clearSelectionEvents(hist.done);
return lst(hist.done);
} else if (hist.done.length && !lst(hist.done).ranges) {
return lst(hist.done);
} else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
hist.done.pop();
return lst(hist.done);
}
}
// Register a change in the history. Merges changes that are within
// a single operation, ore are close together with an origin that
// allows merging (starting with "+") into a single event.
function addChangeToHistory(doc, change, selAfter, opId) {
var hist = doc.history;
hist.undone.length = 0;
var time = +new Date, cur;
if ((hist.lastOp == opId ||
hist.lastOrigin == change.origin && change.origin &&
((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
change.origin.charAt(0) == "*")) &&
(cur = lastChangeEvent(hist, hist.lastOp == opId))) {
// Merge this change into the last event
var last = lst(cur.changes);
if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
// Optimized case for simple insertion -- don't want to add
// new changesets for every character typed
last.to = changeEnd(change);
} else {
// Add new sub-event
cur.changes.push(historyChangeFromChange(doc, change));
}
} else {
// Can not be merged, start a new event.
var before = lst(hist.done);
if (!before || !before.ranges)
pushSelectionToHistory(doc.sel, hist.done);
cur = {changes: [historyChangeFromChange(doc, change)],
generation: hist.generation};
hist.done.push(cur);
while (hist.done.length > hist.undoDepth) {
hist.done.shift();
if (!hist.done[0].ranges) hist.done.shift();
}
}
hist.done.push(selAfter);
hist.generation = ++hist.maxGeneration;
hist.lastModTime = hist.lastSelTime = time;
hist.lastOp = hist.lastSelOp = opId;
hist.lastOrigin = hist.lastSelOrigin = change.origin;
if (!last) signal(doc, "historyAdded");
}
function selectionEventCanBeMerged(doc, origin, prev, sel) {
var ch = origin.charAt(0);
return ch == "*" ||
ch == "+" &&
prev.ranges.length == sel.ranges.length &&
prev.somethingSelected() == sel.somethingSelected() &&
new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
}
// Called whenever the selection changes, sets the new selection as
// the pending selection in the history, and pushes the old pending
// selection into the 'done' array when it was significantly
// different (in number of selected ranges, emptiness, or time).
function addSelectionToHistory(doc, sel, opId, options) {
var hist = doc.history, origin = options && options.origin;
// A new event is started when the previous origin does not match
// the current, or the origins don't allow matching. Origins
// starting with * are always merged, those starting with + are
// merged when similar and close together in time.
if (opId == hist.lastSelOp ||
(origin && hist.lastSelOrigin == origin &&
(hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
hist.done[hist.done.length - 1] = sel;
else
pushSelectionToHistory(sel, hist.done);
hist.lastSelTime = +new Date;
hist.lastSelOrigin = origin;
hist.lastSelOp = opId;
if (options && options.clearRedo !== false)
clearSelectionEvents(hist.undone);
}
function pushSelectionToHistory(sel, dest) {
var top = lst(dest);
if (!(top && top.ranges && top.equals(sel)))
dest.push(sel);
}
// Used to store marked span information in the history.
function attachLocalSpans(doc, change, from, to) {
var existing = change["spans_" + doc.id], n = 0;
doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
if (line.markedSpans)
(existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
++n;
});
}
// When un/re-doing restores text containing marked spans, those
// that have been explicitly cleared should not be restored.
function removeClearedSpans(spans) {
if (!spans) return null;
for (var i = 0, out; i < spans.length; ++i) {
if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
else if (out) out.push(spans[i]);
}
return !out ? spans : out.length ? out : null;
}
// Retrieve and filter the old marked spans stored in a change event.
function getOldSpans(doc, change) {
var found = change["spans_" + doc.id];
if (!found) return null;
for (var i = 0, nw = []; i < change.text.length; ++i)
nw.push(removeClearedSpans(found[i]));
return nw;
}
// Used both to provide a JSON-safe object in .getHistory, and, when
// detaching a document, to split the history in two
function copyHistoryArray(events, newGroup, instantiateSel) {
for (var i = 0, copy = []; i < events.length; ++i) {
var event = events[i];
if (event.ranges) {
copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
continue;
}
var changes = event.changes, newChanges = [];
copy.push({changes: newChanges});
for (var j = 0; j < changes.length; ++j) {
var change = changes[j], m;
newChanges.push({from: change.from, to: change.to, text: change.text});
if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
if (indexOf(newGroup, Number(m[1])) > -1) {
lst(newChanges)[prop] = change[prop];
delete change[prop];
}
}
}
}
return copy;
}
// Rebasing/resetting history to deal with externally-sourced changes
function rebaseHistSelSingle(pos, from, to, diff) {
if (to < pos.line) {
pos.line += diff;
} else if (from < pos.line) {
pos.line = from;
pos.ch = 0;
}
}
// Tries to rebase an array of history events given a change in the
// document. If the change touches the same lines as the event, the
// event, and everything 'behind' it, is discarded. If the change is
// before the event, the event's positions are updated. Uses a
// copy-on-write scheme for the positions, to avoid having to
// reallocate them all on every rebase, but also avoid problems with
// shared position objects being unsafely updated.
function rebaseHistArray(array, from, to, diff) {
for (var i = 0; i < array.length; ++i) {
var sub = array[i], ok = true;
if (sub.ranges) {
if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
for (var j = 0; j < sub.ranges.length; j++) {
rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
}
continue;
}
for (var j = 0; j < sub.changes.length; ++j) {
var cur = sub.changes[j];
if (to < cur.from.line) {
cur.from = Pos(cur.from.line + diff, cur.from.ch);
cur.to = Pos(cur.to.line + diff, cur.to.ch);
} else if (from <= cur.to.line) {
ok = false;
break;
}
}
if (!ok) {
array.splice(0, i + 1);
i = 0;
}
}
}
function rebaseHist(hist, change) {
var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
rebaseHistArray(hist.done, from, to, diff);
rebaseHistArray(hist.undone, from, to, diff);
}
// EVENT UTILITIES
// Due to the fact that we still support jurassic IE versions, some
// compatibility wrappers are needed.
var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
if (e.preventDefault) e.preventDefault();
else e.returnValue = false;
};
var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true;
};
function e_defaultPrevented(e) {
return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
}
var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
function e_target(e) {return e.target || e.srcElement;}
function e_button(e) {
var b = e.which;
if (b == null) {
if (e.button & 1) b = 1;
else if (e.button & 2) b = 3;
else if (e.button & 4) b = 2;
}
if (mac && e.ctrlKey && b == 1) b = 3;
return b;
}
// EVENT HANDLING
// Lightweight event framework. on/off also work on DOM nodes,
// registering native DOM handlers.
var on = CodeMirror.on = function(emitter, type, f) {
if (emitter.addEventListener)
emitter.addEventListener(type, f, false);
else if (emitter.attachEvent)
emitter.attachEvent("on" + type, f);
else {
var map = emitter._handlers || (emitter._handlers = {});
var arr = map[type] || (map[type] = []);
arr.push(f);
}
};
var off = CodeMirror.off = function(emitter, type, f) {
if (emitter.removeEventListener)
emitter.removeEventListener(type, f, false);
else if (emitter.detachEvent)
emitter.detachEvent("on" + type, f);
else {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
for (var i = 0; i < arr.length; ++i)
if (arr[i] == f) { arr.splice(i, 1); break; }
}
};
var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
var args = Array.prototype.slice.call(arguments, 2);
for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
};
var orphanDelayedCallbacks = null;
// Often, we want to signal events at a point where we are in the
// middle of some work, but don't want the handler to start calling
// other methods on the editor, which might be in an inconsistent
// state or simply not expect any other events to happen.
// signalLater looks whether there are any handlers, and schedules
// them to be executed when the last operation ends, or, if no
// operation is active, when a timeout fires.
function signalLater(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
var args = Array.prototype.slice.call(arguments, 2), list;
if (operationGroup) {
list = operationGroup.delayedCallbacks;
} else if (orphanDelayedCallbacks) {
list = orphanDelayedCallbacks;
} else {
list = orphanDelayedCallbacks = [];
setTimeout(fireOrphanDelayed, 0);
}
function bnd(f) {return function(){f.apply(null, args);};};
for (var i = 0; i < arr.length; ++i)
list.push(bnd(arr[i]));
}
function fireOrphanDelayed() {
var delayed = orphanDelayedCallbacks;
orphanDelayedCallbacks = null;
for (var i = 0; i < delayed.length; ++i) delayed[i]();
}
// The DOM events that CodeMirror handles can be overridden by
// registering a (non-DOM) handler on the editor for the event name,
// and preventDefault-ing the event in that handler.
function signalDOMEvent(cm, e, override) {
if (typeof e == "string")
e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
signal(cm, override || e.type, cm, e);
return e_defaultPrevented(e) || e.codemirrorIgnore;
}
function signalCursorActivity(cm) {
var arr = cm._handlers && cm._handlers.cursorActivity;
if (!arr) return;
var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
set.push(arr[i]);
}
function hasHandler(emitter, type) {
var arr = emitter._handlers && emitter._handlers[type];
return arr && arr.length > 0;
}
// Add on and off methods to a constructor's prototype, to make
// registering events on such objects more convenient.
function eventMixin(ctor) {
ctor.prototype.on = function(type, f) {on(this, type, f);};
ctor.prototype.off = function(type, f) {off(this, type, f);};
}
// MISC UTILITIES
// Number of pixels added to scroller and sizer to hide scrollbar
var scrollerGap = 30;
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
// Reused option objects for setSelection & friends
var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
function Delayed() {this.id = null;}
Delayed.prototype.set = function(ms, f) {
clearTimeout(this.id);
this.id = setTimeout(f, ms);
};
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
return n + (end - i);
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
};
// The inverse of countColumn -- find the offset that corresponds to
// a particular column.
function findColumn(string, goal, tabSize) {
for (var pos = 0, col = 0;;) {
var nextTab = string.indexOf("\t", pos);
if (nextTab == -1) nextTab = string.length;
var skipped = nextTab - pos;
if (nextTab == string.length || col + skipped >= goal)
return pos + Math.min(skipped, goal - col);
col += nextTab - pos;
col += tabSize - (col % tabSize);
pos = nextTab + 1;
if (col >= goal) return pos;
}
}
var spaceStrs = [""];
function spaceStr(n) {
while (spaceStrs.length <= n)
spaceStrs.push(lst(spaceStrs) + " ");
return spaceStrs[n];
}
function lst(arr) { return arr[arr.length-1]; }
var selectInput = function(node) { node.select(); };
if (ios) // Mobile Safari apparently has a bug where select() is broken.
selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
else if (ie) // Suppress mysterious IE10 errors
selectInput = function(node) { try { node.select(); } catch(_e) {} };
function indexOf(array, elt) {
for (var i = 0; i < array.length; ++i)
if (array[i] == elt) return i;
return -1;
}
function map(array, f) {
var out = [];
for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
return out;
}
function createObj(base, props) {
var inst;
if (Object.create) {
inst = Object.create(base);
} else {
var ctor = function() {};
ctor.prototype = base;
inst = new ctor();
}
if (props) copyObj(props, inst);
return inst;
};
function copyObj(obj, target, overwrite) {
if (!target) target = {};
for (var prop in obj)
if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
target[prop] = obj[prop];
return target;
}
function bind(f) {
var args = Array.prototype.slice.call(arguments, 1);
return function(){return f.apply(null, args);};
}
var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
return /\w/.test(ch) || ch > "\x80" &&
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
};
function isWordChar(ch, helper) {
if (!helper) return isWordCharBasic(ch);
if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
return helper.test(ch);
}
function isEmpty(obj) {
for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
return true;
}
// Extending unicode characters. A series of a non-extending char +
// any number of extending chars is treated as a single unit as far
// as editing and measuring is concerned. This is not fully correct,
// since some scripts/fonts/browsers also treat other configurations
// of code points as a group.
var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
// DOM UTILITIES
function elt(tag, content, className, style) {
var e = document.createElement(tag);
if (className) e.className = className;
if (style) e.style.cssText = style;
if (typeof content == "string") e.appendChild(document.createTextNode(content));
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
return e;
}
var range;
if (document.createRange) range = function(node, start, end) {
var r = document.createRange();
r.setEnd(node, end);
r.setStart(node, start);
return r;
};
else range = function(node, start, end) {
var r = document.body.createTextRange();
try { r.moveToElementText(node.parentNode); }
catch(e) { return r; }
r.collapse(true);
r.moveEnd("character", end);
r.moveStart("character", start);
return r;
};
function removeChildren(e) {
for (var count = e.childNodes.length; count > 0; --count)
e.removeChild(e.firstChild);
return e;
}
function removeChildrenAndAdd(parent, e) {
return removeChildren(parent).appendChild(e);
}
function contains(parent, child) {
if (parent.contains)
return parent.contains(child);
while (child = child.parentNode)
if (child == parent) return true;
}
function activeElt() { return document.activeElement; }
// Older versions of IE throws unspecified error when touching
// document.activeElement in some cases (during loading, in iframe)
if (ie && ie_version < 11) activeElt = function() {
try { return document.activeElement; }
catch(e) { return document.body; }
};
function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
var rmClass = CodeMirror.rmClass = function(node, cls) {
var current = node.className;
var match = classTest(cls).exec(current);
if (match) {
var after = current.slice(match.index + match[0].length);
node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
}
};
var addClass = CodeMirror.addClass = function(node, cls) {
var current = node.className;
if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls;
};
function joinClasses(a, b) {
var as = a.split(" ");
for (var i = 0; i < as.length; i++)
if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
return b;
}
// WINDOW-WIDE EVENTS
// These must be handled carefully, because naively registering a
// handler for each editor will cause the editors to never be
// garbage collected.
function forEachCodeMirror(f) {
if (!document.body.getElementsByClassName) return;
var byClass = document.body.getElementsByClassName("CodeMirror");
for (var i = 0; i < byClass.length; i++) {
var cm = byClass[i].CodeMirror;
if (cm) f(cm);
}
}
var globalsRegistered = false;
function ensureGlobalHandlers() {
if (globalsRegistered) return;
registerGlobalHandlers();
globalsRegistered = true;
}
function registerGlobalHandlers() {
// When the window resizes, we need to refresh active editors.
var resizeTimer;
on(window, "resize", function() {
if (resizeTimer == null) resizeTimer = setTimeout(function() {
resizeTimer = null;
forEachCodeMirror(onResize);
}, 100);
});
// When the window loses focus, we want to show the editor as blurred
on(window, "blur", function() {
forEachCodeMirror(onBlur);
});
}
// FEATURE DETECTION
// Detect drag-and-drop
var dragAndDrop = function() {
// There is *some* kind of drag-and-drop support in IE6-8, but I
// couldn't get it to work yet.
if (ie && ie_version < 9) return false;
var div = elt('div');
return "draggable" in div || "dragDrop" in div;
}();
var zwspSupported;
function zeroWidthElement(measure) {
if (zwspSupported == null) {
var test = elt("span", "\u200b");
removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
if (measure.firstChild.offsetHeight != 0)
zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
}
if (zwspSupported) return elt("span", "\u200b");
else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
}
// Feature-detect IE's crummy client rect reporting for bidi text
var badBidiRects;
function hasBadBidiRects(measure) {
if (badBidiRects != null) return badBidiRects;
var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
var r0 = range(txt, 0, 1).getBoundingClientRect();
if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
var r1 = range(txt, 1, 2).getBoundingClientRect();
return badBidiRects = (r1.right - r0.right < 3);
}
// See if "".split is the broken IE version, if so, provide an
// alternative way to split lines.
var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
var pos = 0, result = [], l = string.length;
while (pos <= l) {
var nl = string.indexOf("\n", pos);
if (nl == -1) nl = string.length;
var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
var rt = line.indexOf("\r");
if (rt != -1) {
result.push(line.slice(0, rt));
pos += rt + 1;
} else {
result.push(line);
pos = nl + 1;
}
}
return result;
} : function(string){return string.split(/\r\n?|\n/);};
var hasSelection = window.getSelection ? function(te) {
try { return te.selectionStart != te.selectionEnd; }
catch(e) { return false; }
} : function(te) {
try {var range = te.ownerDocument.selection.createRange();}
catch(e) {}
if (!range || range.parentElement() != te) return false;
return range.compareEndPoints("StartToEnd", range) != 0;
};
var hasCopyEvent = (function() {
var e = elt("div");
if ("oncopy" in e) return true;
e.setAttribute("oncopy", "return;");
return typeof e.oncopy == "function";
})();
var badZoomedRects = null;
function hasBadZoomedRects(measure) {
if (badZoomedRects != null) return badZoomedRects;
var node = removeChildrenAndAdd(measure, elt("span", "x"));
var normal = node.getBoundingClientRect();
var fromRange = range(node, 0, 1).getBoundingClientRect();
return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
}
// KEY NAMES
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
CodeMirror.keyNames = keyNames;
(function() {
// Number keys
for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
// Alphabetic keys
for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
// Function keys
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
})();
// BIDI HELPERS
function iterateBidiSections(order, from, to, f) {
if (!order) return f(from, to, "ltr");
var found = false;
for (var i = 0; i < order.length; ++i) {
var part = order[i];
if (part.from < to && part.to > from || from == to && part.to == from) {
f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
found = true;
}
}
if (!found) f(from, to, "ltr");
}
function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
function lineRight(line) {
var order = getOrder(line);
if (!order) return line.text.length;
return bidiRight(lst(order));
}
function lineStart(cm, lineN) {
var line = getLine(cm.doc, lineN);
var visual = visualLine(line);
if (visual != line) lineN = lineNo(visual);
var order = getOrder(visual);
var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
return Pos(lineN, ch);
}
function lineEnd(cm, lineN) {
var merged, line = getLine(cm.doc, lineN);
while (merged = collapsedSpanAtEnd(line)) {
line = merged.find(1, true).line;
lineN = null;
}
var order = getOrder(line);
var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
return Pos(lineN == null ? lineNo(line) : lineN, ch);
}
function lineStartSmart(cm, pos) {
var start = lineStart(cm, pos.line);
var line = getLine(cm.doc, start.line);
var order = getOrder(line);
if (!order || order[0].level == 0) {
var firstNonWS = Math.max(0, line.text.search(/\S/));
var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
return Pos(start.line, inWS ? 0 : firstNonWS);
}
return start;
}
function compareBidiLevel(order, a, b) {
var linedir = order[0].level;
if (a == linedir) return true;
if (b == linedir) return false;
return a < b;
}
var bidiOther;
function getBidiPartAt(order, pos) {
bidiOther = null;
for (var i = 0, found; i < order.length; ++i) {
var cur = order[i];
if (cur.from < pos && cur.to > pos) return i;
if ((cur.from == pos || cur.to == pos)) {
if (found == null) {
found = i;
} else if (compareBidiLevel(order, cur.level, order[found].level)) {
if (cur.from != cur.to) bidiOther = found;
return i;
} else {
if (cur.from != cur.to) bidiOther = i;
return found;
}
}
}
return found;
}
function moveInLine(line, pos, dir, byUnit) {
if (!byUnit) return pos + dir;
do pos += dir;
while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
return pos;
}
// This is needed in order to move 'visually' through bi-directional
// text -- i.e., pressing left should make the cursor go left, even
// when in RTL text. The tricky part is the 'jumps', where RTL and
// LTR text touch each other. This often requires the cursor offset
// to move more than one unit, in order to visually move one unit.
function moveVisually(line, start, dir, byUnit) {
var bidi = getOrder(line);
if (!bidi) return moveLogically(line, start, dir, byUnit);
var pos = getBidiPartAt(bidi, start), part = bidi[pos];
var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
for (;;) {
if (target > part.from && target < part.to) return target;
if (target == part.from || target == part.to) {
if (getBidiPartAt(bidi, target) == pos) return target;
part = bidi[pos += dir];
return (dir > 0) == part.level % 2 ? part.to : part.from;
} else {
part = bidi[pos += dir];
if (!part) return null;
if ((dir > 0) == part.level % 2)
target = moveInLine(line, part.to, -1, byUnit);
else
target = moveInLine(line, part.from, 1, byUnit);
}
}
}
function moveLogically(line, start, dir, byUnit) {
var target = start + dir;
if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
return target < 0 || target > line.text.length ? null : target;
}
// Bidirectional ordering algorithm
// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
// that this (partially) implements.
// One-char codes used for character types:
// L (L): Left-to-Right
// R (R): Right-to-Left
// r (AL): Right-to-Left Arabic
// 1 (EN): European Number
// + (ES): European Number Separator
// % (ET): European Number Terminator
// n (AN): Arabic Number
// , (CS): Common Number Separator
// m (NSM): Non-Spacing Mark
// b (BN): Boundary Neutral
// s (B): Paragraph Separator
// t (S): Segment Separator
// w (WS): Whitespace
// N (ON): Other Neutrals
// Returns null if characters are ordered as they appear
// (left-to-right), or an array of sections ({from, to, level}
// objects) in the order in which they occur visually.
var bidiOrdering = (function() {
// Character types for codepoints 0 to 0xff
var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
// Character types for codepoints 0x600 to 0x6ff
var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
function charType(code) {
if (code <= 0xf7) return lowTypes.charAt(code);
else if (0x590 <= code && code <= 0x5f4) return "R";
else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
else if (0x6ee <= code && code <= 0x8ac) return "r";
else if (0x2000 <= code && code <= 0x200b) return "w";
else if (code == 0x200c) return "b";
else return "L";
}
var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
// Browsers seem to always treat the boundaries of block elements as being L.
var outerType = "L";
function BidiSpan(level, from, to) {
this.level = level;
this.from = from; this.to = to;
}
return function(str) {
if (!bidiRE.test(str)) return false;
var len = str.length, types = [];
for (var i = 0, type; i < len; ++i)
types.push(type = charType(str.charCodeAt(i)));
// W1. Examine each non-spacing mark (NSM) in the level run, and
// change the type of the NSM to the type of the previous
// character. If the NSM is at the start of the level run, it will
// get the type of sor.
for (var i = 0, prev = outerType; i < len; ++i) {
var type = types[i];
if (type == "m") types[i] = prev;
else prev = type;
}
// W2. Search backwards from each instance of a European number
// until the first strong type (R, L, AL, or sor) is found. If an
// AL is found, change the type of the European number to Arabic
// number.
// W3. Change all ALs to R.
for (var i = 0, cur = outerType; i < len; ++i) {
var type = types[i];
if (type == "1" && cur == "r") types[i] = "n";
else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
}
// W4. A single European separator between two European numbers
// changes to a European number. A single common separator between
// two numbers of the same type changes to that type.
for (var i = 1, prev = types[0]; i < len - 1; ++i) {
var type = types[i];
if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
else if (type == "," && prev == types[i+1] &&
(prev == "1" || prev == "n")) types[i] = prev;
prev = type;
}
// W5. A sequence of European terminators adjacent to European
// numbers changes to all European numbers.
// W6. Otherwise, separators and terminators change to Other
// Neutral.
for (var i = 0; i < len; ++i) {
var type = types[i];
if (type == ",") types[i] = "N";
else if (type == "%") {
for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
// W7. Search backwards from each instance of a European number
// until the first strong type (R, L, or sor) is found. If an L is
// found, then change the type of the European number to L.
for (var i = 0, cur = outerType; i < len; ++i) {
var type = types[i];
if (cur == "L" && type == "1") types[i] = "L";
else if (isStrong.test(type)) cur = type;
}
// N1. A sequence of neutrals takes the direction of the
// surrounding strong text if the text on both sides has the same
// direction. European and Arabic numbers act as if they were R in
// terms of their influence on neutrals. Start-of-level-run (sor)
// and end-of-level-run (eor) are used at level run boundaries.
// N2. Any remaining neutrals take the embedding direction.
for (var i = 0; i < len; ++i) {
if (isNeutral.test(types[i])) {
for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
var before = (i ? types[i-1] : outerType) == "L";
var after = (end < len ? types[end] : outerType) == "L";
var replace = before || after ? "L" : "R";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
// Here we depart from the documented algorithm, in order to avoid
// building up an actual levels array. Since there are only three
// levels (0, 1, 2) in an implementation that doesn't take
// explicit embedding into account, we can build up the order on
// the fly, without following the level-based algorithm.
var order = [], m;
for (var i = 0; i < len;) {
if (countsAsLeft.test(types[i])) {
var start = i;
for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
order.push(new BidiSpan(0, start, i));
} else {
var pos = i, at = order.length;
for (++i; i < len && types[i] != "L"; ++i) {}
for (var j = pos; j < i;) {
if (countsAsNum.test(types[j])) {
if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
var nstart = j;
for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
order.splice(at, 0, new BidiSpan(2, nstart, j));
pos = j;
} else ++j;
}
if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
}
}
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length;
order.unshift(new BidiSpan(0, 0, m[0].length));
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length;
order.push(new BidiSpan(0, len - m[0].length, len));
}
if (order[0].level != lst(order).level)
order.push(new BidiSpan(order[0].level, len, len));
return order;
};
})();
// THE END
CodeMirror.version = "4.12.0";
return CodeMirror;
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | 2 2 2 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var noOptions = {};
var nonWS = /[^\s\u00a0]/;
var Pos = CodeMirror.Pos;
function firstNonWS(str) {
var found = str.search(nonWS);
return found == -1 ? 0 : found;
}
CodeMirror.commands.toggleComment = function(cm) {
var minLine = Infinity, ranges = cm.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
if (cm.uncomment(from, to)) mode = "un";
else { cm.lineComment(from, to); mode = "line"; }
} else if (mode == "un") {
cm.uncomment(from, to);
} else {
cm.lineComment(from, to);
}
}
};
CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from);
var commentString = options.lineComment || mode.lineComment;
if (!commentString) {
if (options.blockCommentStart || mode.blockCommentStart) {
options.fullLines = true;
self.blockComment(from, to, options);
}
return;
}
var firstLine = self.getLine(from.line);
if (firstLine == null) return;
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
var pad = options.padding == null ? " " : options.padding;
var blankLines = options.commentBlankLines || from.line == to.line;
self.operation(function() {
if (options.indent) {
var baseString = firstLine.slice(0, firstNonWS(firstLine));
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue;
if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
}
} else {
for (var i = from.line; i < end; ++i) {
if (blankLines || nonWS.test(self.getLine(i)))
self.replaceRange(commentString + pad, Pos(i, 0));
}
}
});
});
CodeMirror.defineExtension("blockComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from);
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) {
if ((options.lineComment || mode.lineComment) && options.fullLines != false)
self.lineComment(from, to, options);
return;
}
var end = Math.min(to.line, self.lastLine());
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
var pad = options.padding == null ? " " : options.padding;
if (from.line > end) return;
self.operation(function() {
if (options.fullLines != false) {
var lastLineHasText = nonWS.test(self.getLine(end));
self.replaceRange(pad + endString, Pos(end));
self.replaceRange(startString + pad, Pos(from.line, 0));
var lead = options.blockCommentLead || mode.blockCommentLead;
if (lead != null) for (var i = from.line + 1; i <= end; ++i)
if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0));
} else {
self.replaceRange(endString, to);
self.replaceRange(startString, from);
}
});
});
CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from);
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments
var lineString = options.lineComment || mode.lineComment, lines = [];
var pad = options.padding == null ? " " : options.padding, didSomething;
lineComment: {
if (!lineString) break lineComment;
for (var i = start; i <= end; ++i) {
var line = self.getLine(i);
var found = line.indexOf(lineString);
if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment;
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
lines.push(line);
}
self.operation(function() {
for (var i = start; i <= end; ++i) {
var line = lines[i - start];
var pos = line.indexOf(lineString), endPos = pos + lineString.length;
if (pos < 0) continue;
if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
didSomething = true;
self.replaceRange("", Pos(i, pos), Pos(i, endPos));
}
});
if (didSomething) return true;
}
// Try block comments
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) return false;
var lead = options.blockCommentLead || mode.blockCommentLead;
var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end);
var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString);
if (close == -1 && start != end) {
endLine = self.getLine(--end);
close = endLine.lastIndexOf(endString);
}
if (open == -1 || close == -1 ||
!/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
return false;
// Avoid killing block comments completely outside the selection.
// Positions of the last startString before the start of the selection, and the first endString after it.
var lastStart = startLine.lastIndexOf(startString, from.ch);
var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
// Positions of the first endString after the end of the selection, and the last startString before it.
firstEnd = endLine.indexOf(endString, to.ch);
var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
self.operation(function() {
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
Pos(end, close + endString.length));
var openEnd = open + startString.length;
if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
self.replaceRange("", Pos(start, open), Pos(start, openEnd));
if (lead) for (var i = start + 1; i <= end; ++i) {
var line = self.getLine(i), found = line.indexOf(lead);
if (found == -1 || nonWS.test(line.slice(0, found))) continue;
var foundEnd = found + lead.length;
if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
}
});
return true;
});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("css", function(config, parserConfig) {
var inline = parserConfig.inline
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
var indentUnit = config.indentUnit,
tokenHooks = parserConfig.tokenHooks,
documentTypes = parserConfig.documentTypes || {},
mediaTypes = parserConfig.mediaTypes || {},
mediaFeatures = parserConfig.mediaFeatures || {},
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
propertyKeywords = parserConfig.propertyKeywords || {},
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
fontProperties = parserConfig.fontProperties || {},
counterDescriptors = parserConfig.counterDescriptors || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested,
supportsAtComponent = parserConfig.supportsAtComponent === true;
var type, override;
function ret(style, tp) { type = tp; return style; }
// Tokenizers
function tokenBase(stream, state) {
var ch = stream.next();
if (tokenHooks[ch]) {
var result = tokenHooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == "@") {
stream.eatWhile(/[\w\\\-]/);
return ret("def", stream.current());
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
return ret(null, "compare");
} else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
} else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (ch === "-") {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]+/)) {
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition");
return ret("variable-2", "variable");
} else if (stream.match(/^\w+-/)) {
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
} else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
(ch == "d" && stream.match("omain(")) ||
(ch == "r" && stream.match("egexp("))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
} else {
return ret(null, null);
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
if (quote == ")") stream.backUp(1);
break;
}
escaped = !escaped && ch == "\\";
}
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
return ret("string", "string");
};
}
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
return ret(null, "(");
}
// Context management
function Context(type, indent, prev) {
this.type = type;
this.indent = indent;
this.prev = prev;
}
function pushContext(state, stream, type, indent) {
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
return type;
}
function popContext(state) {
if (state.context.prev)
state.context = state.context.prev;
return state.context.type;
}
function pass(type, stream, state) {
return states[state.context.type](type, stream, state);
}
function popAndPass(type, stream, state, n) {
for (var i = n || 1; i > 0; i--)
state.context = state.context.prev;
return pass(type, stream, state);
}
// Parser
function wordAsValue(stream) {
var word = stream.current().toLowerCase();
if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "variable";
}
var states = {};
states.top = function(type, stream, state) {
if (type == "{") {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
} else if (supportsAtComponent && /@component/.test(type)) {
return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/.test(type)) {
return pushContext(state, stream, "documentTypes");
} else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
return pushContext(state, stream, "atBlock");
} else if (/^@(font-face|counter-style)/.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
} else if (type == "hash") {
override = "builtin";
} else if (type == "word") {
override = "tag";
} else if (type == "variable-definition") {
return "maybeprop";
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
} else if (type == ":") {
return "pseudo";
} else if (allowNested && type == "(") {
return pushContext(state, stream, "parens");
}
return state.context.type;
};
states.block = function(type, stream, state) {
if (type == "word") {
var word = stream.current().toLowerCase();
if (propertyKeywords.hasOwnProperty(word)) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = "string-2";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
return "block";
} else {
override += " error";
return "maybeprop";
}
} else if (type == "meta") {
return "block";
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
override = "error";
return "block";
} else {
return states.top(type, stream, state);
}
};
states.maybeprop = function(type, stream, state) {
if (type == ":") return pushContext(state, stream, "prop");
return pass(type, stream, state);
};
states.prop = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
if (type == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
override += " error";
} else if (type == "word") {
wordAsValue(stream);
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
}
return "prop";
};
states.propBlock = function(type, _stream, state) {
if (type == "}") return popContext(state);
if (type == "word") { override = "property"; return "maybeprop"; }
return state.context.type;
};
states.parens = function(type, stream, state) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") wordAsValue(stream);
return "parens";
};
states.pseudo = function(type, stream, state) {
if (type == "word") {
override = "variable-3";
return state.context.type;
}
return pass(type, stream, state);
};
states.documentTypes = function(type, stream, state) {
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
override = "tag";
return state.context.type;
} else {
return states.atBlock(type, stream, state);
}
};
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
if (type == "}" || type == ";") return popAndPass(type, stream, state);
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") {
var word = stream.current().toLowerCase();
if (word == "only" || word == "not" || word == "and" || word == "or")
override = "keyword";
else if (mediaTypes.hasOwnProperty(word))
override = "attribute";
else if (mediaFeatures.hasOwnProperty(word))
override = "property";
else if (mediaValueKeywords.hasOwnProperty(word))
override = "keyword";
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "error";
}
return state.context.type;
};
states.atComponentBlock = function(type, stream, state) {
if (type == "}")
return popAndPass(type, stream, state);
if (type == "{")
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
if (type == "word")
override = "error";
return state.context.type;
};
states.atBlock_parens = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
return states.atBlock(type, stream, state);
};
states.restricted_atBlock_before = function(type, stream, state) {
if (type == "{")
return pushContext(state, stream, "restricted_atBlock");
if (type == "word" && state.stateArg == "@counter-style") {
override = "variable";
return "restricted_atBlock_before";
}
return pass(type, stream, state);
};
states.restricted_atBlock = function(type, stream, state) {
if (type == "}") {
state.stateArg = null;
return popContext(state);
}
if (type == "word") {
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override = "error";
else
override = "property";
return "maybeprop";
}
return "restricted_atBlock";
};
states.keyframes = function(type, stream, state) {
if (type == "word") { override = "variable"; return "keyframes"; }
if (type == "{") return pushContext(state, stream, "top");
return pass(type, stream, state);
};
states.at = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == "word") override = "tag";
else if (type == "hash") override = "builtin";
return "at";
};
states.interpolation = function(type, stream, state) {
if (type == "}") return popContext(state);
if (type == "{" || type == ";") return popAndPass(type, stream, state);
if (type == "word") override = "variable";
else if (type != "variable" && type != "(" && type != ")") override = "error";
return "interpolation";
};
return {
startState: function(base) {
return {tokenize: null,
state: inline ? "block" : "top",
stateArg: null,
context: new Context(inline ? "block" : "top", base || 0, null)};
},
token: function(stream, state) {
if (!state.tokenize && stream.eatSpace()) return null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style && typeof style == "object") {
type = style[1];
style = style[0];
}
override = style;
state.state = states[state.state](type, stream, state);
return override;
},
indent: function(state, textAfter) {
var cx = state.context, ch = textAfter && textAfter.charAt(0);
var indent = cx.indent;
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
if (cx.prev) {
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
// Resume indentation from parent context.
cx = cx.prev;
indent = cx.indent;
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
cx = cx.prev;
}
}
return indent;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
fold: "brace"
};
});
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) {
keys[array[i]] = true;
}
return keys;
}
var documentTypes_ = [
"domain", "regexp", "url", "url-prefix"
], documentTypes = keySet(documentTypes_);
var mediaTypes_ = [
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
], mediaTypes = keySet(mediaTypes_);
var mediaFeatures_ = [
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
"pointer", "any-pointer", "hover", "any-hover"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
"background", "background-attachment", "background-blend-mode", "background-clip",
"background-color", "background-image", "background-origin", "background-position",
"background-repeat", "background-size", "baseline-shift", "binding",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
"bookmark-target", "border", "border-bottom", "border-bottom-color",
"border-bottom-left-radius", "border-bottom-right-radius",
"border-bottom-style", "border-bottom-width", "border-collapse",
"border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color",
"border-left-style", "border-left-width", "border-radius", "border-right",
"border-right-color", "border-right-style", "border-right-width",
"border-spacing", "border-style", "border-top", "border-top-color",
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
"cue-after", "cue-before", "cursor", "direction", "display",
"dominant-baseline", "drop-initial-after-adjust",
"drop-initial-after-align", "drop-initial-before-adjust",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
"grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
"grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
"grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
"inline-box-align", "justify-content", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top",
"marker-offset", "marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
"opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
"shape-outside", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode"
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
"font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
"speak-as", "suffix", "symbols", "system"
], counterDescriptors = keySet(counterDescriptors_);
var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
var valueKeywords_ = [
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
"compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider",
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeating-linear-gradient",
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal",
"translate", "translate3d", "translateX", "translateY", "translateZ",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
], valueKeywords = keySet(valueKeywords_);
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
.concat(valueKeywords_);
CodeMirror.registerHelper("hintWords", "css", allWords);
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
CodeMirror.defineMIME("text/css", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
":": function(stream) {
if (stream.match(/\s*\{/))
return [null, "{"];
return false;
},
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"#": function(stream) {
if (!stream.eat("{")) return false;
return [null, "interpolation"];
}
},
name: "css",
helperType: "scss"
});
CodeMirror.defineMIME("text/x-less", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"&": function() {
return ["atom", "atom"];
}
},
name: "css",
helperType: "less"
});
CodeMirror.defineMIME("text/x-gss", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
supportsAtComponent: true,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css",
helperType: "gss"
});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 2 2 2 1 1 2 2 | // Content of the function is equal to runmode-standalone.js file
// from CodeMirror distribution
(function(window) {
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
window.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
}
};
CodeMirror.StringStream = StringStream;
CodeMirror.startState = function (mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
CodeMirror.defineMode = function (name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
CodeMirror.getMode = function (options, spec) {
spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, spec);
};
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || 4;
var node = callback, col = 0;
node.innerHTML = "";
callback = function (text, style) {
if (text == "\n") {
node.appendChild(document.createElement("br"));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0; ;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
})();
}(this))
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 2 2 2 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
//config settings
var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;
//inner modes
var scriptingMode, htmlMixedMode;
//tokenizer when in html mode
function htmlDispatch(stream, state) {
if (stream.match(scriptStartRegex, false)) {
state.token=scriptingDispatch;
return scriptingMode.token(stream, state.scriptState);
}
else
return htmlMixedMode.token(stream, state.htmlState);
}
//tokenizer when in scripting mode
function scriptingDispatch(stream, state) {
if (stream.match(scriptEndRegex, false)) {
state.token=htmlDispatch;
return htmlMixedMode.token(stream, state.htmlState);
}
else
return scriptingMode.token(stream, state.scriptState);
}
return {
startState: function() {
scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
return {
token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
htmlState : CodeMirror.startState(htmlMixedMode),
scriptState : CodeMirror.startState(scriptingMode)
};
},
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (state.token == htmlDispatch)
return htmlMixedMode.indent(state.htmlState, textAfter);
else if (scriptingMode.indent)
return scriptingMode.indent(state.scriptState, textAfter);
},
copyState: function(state) {
return {
token : state.token,
htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
};
},
innerMode: function(state) {
if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
else return {state: state.htmlState, mode: htmlMixedMode};
}
};
}, "htmlmixed");
CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 2 2 2 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
var cssMode = CodeMirror.getMode(config, "css");
var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
mode: CodeMirror.getMode(config, "javascript")});
if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
var conf = scriptTypesConf[i];
scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
}
scriptTypes.push({matches: /./,
mode: CodeMirror.getMode(config, "text/plain")});
function html(stream, state) {
var tagName = state.htmlState.tagName;
if (tagName) tagName = tagName.toLowerCase();
var style = htmlMode.token(stream, state.htmlState);
if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
// Script block: mode to change to depends on type attribute
var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
scriptType = scriptType ? scriptType[1] : "";
if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
for (var i = 0; i < scriptTypes.length; ++i) {
var tp = scriptTypes[i];
if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
if (tp.mode) {
state.token = script;
state.localMode = tp.mode;
state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
}
break;
}
}
} else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
state.token = css;
state.localMode = cssMode;
state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
}
return style;
}
function maybeBackup(stream, pat, style) {
var cur = stream.current();
var close = cur.search(pat), m;
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
function script(stream, state) {
if (stream.match(/^<\/\s*script\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*script\s*>/,
state.localMode.token(stream, state.localState));
}
function css(stream, state) {
if (stream.match(/^<\/\s*style\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*style\s*>/,
cssMode.token(stream, state.localState));
}
return {
startState: function() {
var state = htmlMode.startState();
return {token: html, localMode: null, localState: null, htmlState: state};
},
copyState: function(state) {
if (state.localState)
var local = CodeMirror.copyState(state.localMode, state.localState);
return {token: state.token, localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter);
else
return CodeMirror.Pass;
},
innerMode: function(state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
CodeMirror.defineMIME("text/html", "htmlmixed");
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// TODO actually recognize syntax of TypeScript constructs
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function expressionAllowed(stream, state, backUp) {
return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
};
// Extend the 'normal' keywords with the TypeScript language extensions
if (isTS) {
var type = {type: "variable", style: "variable-3"};
var tsKeywords = {
// object-like things
"interface": kw("class"),
"implements": C,
"namespace": C,
"module": kw("module"),
"enum": kw("module"),
// scope modifiers
"public": kw("modifier"),
"private": kw("modifier"),
"protected": kw("modifier"),
"abstract": kw("modifier"),
// operators
"as": operator,
// types
"string": type, "number": type, "boolean": type, "any": type
};
for (var attr in tsKeywords) {
jsKeywords[attr] = tsKeywords[attr];
}
}
return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
if (!escaped) {
if (next == "/" && !inSet) return;
if (next == "[") inSet = true;
else if (inSet && next == "]") inSet = false;
}
escaped = !escaped && next == "\\";
}
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
return ret("number", "number");
} else if (ch == "." && stream.match("..")) {
return ret("spread", "meta");
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
} else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/o/i)) {
stream.eatWhile(/[0-7]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/b/i)) {
stream.eatWhile(/[01]/i);
return ret("number", "number");
} else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
} else if (ch == "#") {
stream.skipToEnd();
return ret("error", "error");
} else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
ret("variable", "variable", word);
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next;
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
state.tokenize = tokenBase;
return ret("jsonld-keyword", "meta");
}
while ((next = stream.next()) != null) {
if (next == quote && !escaped) break;
escaped = !escaped && next == "\\";
}
if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
function tokenQuasi(stream, state) {
var escaped = false, next;
while ((next = stream.next()) != null) {
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && next == "\\";
}
return ret("quasi", "string-2", stream.current());
}
var brackets = "([{}])";
// This is a crude lookahead trick to try and notice that we're
// parsing the argument patterns for a fat-arrow function before we
// actually hit the arrow token. It only works if the arrow is on
// the same line as the arguments and there's no strange noise
// (comments) in between. Fallback is to only notice when we hit the
// arrow, and not declare the arguments as locals for the arrow
// body.
function findFatArrow(stream, state) {
if (state.fatArrowAt) state.fatArrowAt = null;
var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return;
var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; }
if (--depth == 0) break;
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (wordRE.test(ch)) {
sawSomething = true;
} else if (/["'\/]/.test(ch)) {
return;
} else if (sawSomething && !depth) {
++pos;
break;
}
}
if (sawSomething && !depth) state.fatArrowAt = pos;
}
// Parser
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
this.prev = prev;
this.info = info;
if (align != null) this.align = align;
}
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
for (var v = cx.vars; v; v = v.next)
if (v.name == varname) return true;
}
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
while(true) {
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
if (combinator(type, content)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
if (cx.marked) return cx.marked;
if (type == "variable" && inScope(state, content)) return "variable-2";
return style;
}
}
}
// Combinator utils
var cx = {state: null, column: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function register(varname) {
function inList(list) {
for (var v = list; v; v = v.next)
if (v.name == varname) return true;
return false;
}
var state = cx.state;
cx.marked = "def";
if (state.context) {
if (inList(state.localVars)) return;
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
if (parserConfig.globalVars)
state.globalVars = {name: varname, next: state.globalVars};
}
}
// Combinators
var defaultVars = {name: "this", next: {name: "arguments"}};
function pushcontext() {
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
cx.state.localVars = defaultVars;
}
function popcontext() {
cx.state.localVars = cx.state.context.vars;
cx.state.context = cx.state.context.prev;
}
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
if (state.lexical.type == "stat") indent = state.lexical.indented;
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
indent = outer.indented;
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == ")")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
poplex.lex = true;
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
else if (wanted == ";") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), expression, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel);
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
return expressionInner(type, false);
}
function expressionNoComma(type) {
return expressionInner(type, true);
}
function expressionInner(type, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == "quasi") { return pass(quasi, me); }
if (type == ";") return;
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
}
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(expression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasi);
}
}
function arrowBody(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expression);
}
function arrowBodyNoComma(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expressionNoComma);
}
function maybeTarget(noComma) {
return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target);
else return pass(noComma ? expressionNoComma : expression);
};
}
function target(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
}
function targetNoComma(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
}
function property(type) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
} else if (type == "modifier") {
return cont(objprop)
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expression);
}
}
function getterSetter(type) {
if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
function afterprop(type) {
if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef);
}
function commasep(what, end) {
function proceed(type) {
if (type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
return cont(what, proceed);
}
if (type == end) return cont();
return cont(expect(end));
}
return function(type) {
if (type == end) return cont();
return pass(what, proceed);
};
}
function contCommasep(what, end, info) {
for (var i = 3; i < arguments.length; i++)
cx.cc.push(arguments[i]);
return cont(pushlex(end, info), commasep(what, end), poplex);
}
function block(type) {
if (type == "}") return cont();
return pass(statement, block);
}
function maybetype(type) {
if (isTS && type == ":") return cont(typedef);
}
function maybedefault(_, value) {
if (value == "=") return cont(expressionNoComma);
}
function typedef(type) {
if (type == "variable") {cx.marked = "variable-3"; return cont();}
}
function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
if (type == "modifier") return cont(pattern)
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
return cont(maybeAssign);
}
if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern);
if (type == "}") return pass();
return cont(expect(":"), pattern, maybeAssign);
}
function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma);
}
function vardefCont(type) {
if (type == ",") return cont(vardef);
}
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
function forspec(type) {
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef, expect(";"), forspec2);
if (type == ";") return cont(forspec2);
if (type == "variable") return cont(formaybeinof);
return pass(expression, expect(";"), forspec2);
}
function formaybeinof(_type, value) {
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
}
function forspec2(type, value) {
if (type == ";") return cont(forspec3);
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return pass(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type != ")") cont(expression);
}
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
}
function funarg(type) {
if (type == "spread") return cont(funarg);
return pass(pattern, maybetype, maybedefault);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(type, value) {
if (value == "extends") return cont(expression, classNameAfter);
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
if (type == "variable" || cx.style == "keyword") {
if (value == "static") {
cx.marked = "keyword";
return cont(classBody);
}
cx.marked = "property";
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
return cont(functiondef, classBody);
}
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
}
function classGetterSetter(type) {
if (type != "variable") return pass();
cx.marked = "property";
return cont();
}
function afterExport(_type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
return pass(statement);
}
function afterImport(type) {
if (type == "string") return cont();
return pass(importSpec, maybeFrom);
}
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
if (type == "variable") register(value);
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
function maybeFrom(_type, value) {
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
}
function arrayLiteral(type) {
if (type == "]") return cont();
return pass(expressionNoComma, maybeArrayComprehension);
}
function maybeArrayComprehension(type) {
if (type == "for") return pass(comprehension, expect("]"));
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
return pass(commasep(expressionNoComma, "]"));
}
function comprehension(type) {
if (type == "for") return cont(forspec, comprehension);
if (type == "if") return cont(expression, comprehension);
}
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
isOperatorChar.test(textAfter.charAt(0)) ||
/[,.]/.test(textAfter.charAt(0));
}
// Interface
return {
startState: function(basecolumn) {
var state = {
tokenize: tokenBase,
lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
state.globalVars = parserConfig.globalVars;
return state;
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
findFatArrow(stream, state);
}
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize == tokenComment) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse) break;
}
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
jsonMode: jsonMode,
expressionAllowed: expressionAllowed,
skipExpression: function(state) {
var top = state.cc[state.cc.length - 1]
if (top == expression || top == expressionNoComma) state.cc.pop()
}
};
});
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 2 2 2 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*.
//
// Adds an option 'styleSelectedText' which, when enabled, gives
// selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string.
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.state.markedSelection = [];
cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
reset(cm);
cm.on("cursorActivity", onCursorActivity);
cm.on("change", onChange);
} else if (!val && prev) {
cm.off("cursorActivity", onCursorActivity);
cm.off("change", onChange);
clear(cm);
cm.state.markedSelection = cm.state.markedSelectionStyle = null;
}
});
function onCursorActivity(cm) {
cm.operation(function() { update(cm); });
}
function onChange(cm) {
if (cm.state.markedSelection.length)
cm.operation(function() { clear(cm); });
}
var CHUNK_SIZE = 8;
var Pos = CodeMirror.Pos;
var cmp = CodeMirror.cmpPos;
function coverRange(cm, from, to, addAt) {
if (cmp(from, to) == 0) return;
var array = cm.state.markedSelection;
var cls = cm.state.markedSelectionStyle;
for (var line = from.line;;) {
var start = line == from.line ? from : Pos(line, 0);
var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
var end = atEnd ? to : Pos(endLine, 0);
var mark = cm.markText(start, end, {className: cls});
if (addAt == null) array.push(mark);
else array.splice(addAt++, 0, mark);
if (atEnd) break;
line = endLine;
}
}
function clear(cm) {
var array = cm.state.markedSelection;
for (var i = 0; i < array.length; ++i) array[i].clear();
array.length = 0;
}
function reset(cm) {
clear(cm);
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++)
coverRange(cm, ranges[i].from(), ranges[i].to());
}
function update(cm) {
if (!cm.somethingSelected()) return clear(cm);
if (cm.listSelections().length > 1) return reset(cm);
var from = cm.getCursor("start"), to = cm.getCursor("end");
var array = cm.state.markedSelection;
if (!array.length) return coverRange(cm, from, to);
var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE ||
cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
return reset(cm);
while (cmp(from, coverStart.from) > 0) {
array.shift().clear();
coverStart = array[0].find();
}
if (cmp(from, coverStart.from) < 0) {
if (coverStart.to.line - from.line < CHUNK_SIZE) {
array.shift().clear();
coverRange(cm, from, coverStart.to, 0);
} else {
coverRange(cm, from, coverStart.from, 0);
}
}
while (cmp(to, coverEnd.to) < 0) {
array.pop().clear();
coverEnd = array[array.length - 1].find();
}
if (cmp(to, coverEnd.to) > 0) {
if (to.line - coverEnd.from.line < CHUNK_SIZE) {
array.pop().clear();
coverRange(cm, coverEnd.from, to);
} else {
coverRange(cm, coverEnd.to, to);
}
}
}
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 2 2 2 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
function findMatchingBracket(cm, where, strict, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
if (strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
if (found == null) return null;
return {from: Pos(where.line, pos), to: found && found.pos,
match: found && found.ch == match.charAt(0), forward: dir > 0};
}
// bracketRegex is used to specify which type of bracket to scan
// should be a regexp, e.g. /[[\]]/
//
// Note: If "where" is on an open bracket, then this bracket is ignored.
//
// Returns false when no bracket was found, null when it reached
// maxScanLines and gave up
function scanForBracket(cm, where, dir, style, config) {
var maxScanLen = (config && config.maxScanLineLength) || 10000;
var maxScanLines = (config && config.maxScanLines) || 1000;
var stack = [];
var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
var line = cm.getLine(lineNo);
if (!line) continue;
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
if (line.length > maxScanLen) continue;
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch];
if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
else stack.pop();
}
}
}
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
}
function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
}
}
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
// input stops going to the textare whever this fires.
if (ie_lt8 && cm.state.focused) cm.display.input.focus();
var clear = function() {
cm.operation(function() {
for (var i = 0; i < marks.length; i++) marks[i].clear();
});
};
if (autoclear) setTimeout(clear, 800);
else return clear;
}
}
var currentlyHighlighted = null;
function doMatchBrackets(cm) {
cm.operation(function() {
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init)
cm.off("cursorActivity", doMatchBrackets);
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
}
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
return findMatchingBracket(this, pos, strict, config);
});
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 2 2 2 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.overlayMode = function(base, overlay, combine) {
return {
startState: function() {
return {
base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null,
lineSeen: null
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(base, state.base),
overlay: CodeMirror.copyState(overlay, state.overlay),
basePos: state.basePos, baseCur: null,
overlayPos: state.overlayPos, overlayCur: null
};
},
token: function(stream, state) {
if (stream.sol() || stream.string != state.lineSeen ||
Math.min(state.basePos, state.overlayPos) < stream.start) {
state.lineSeen = stream.string;
state.basePos = state.overlayPos = stream.start;
}
if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos;
}
if (stream.start == state.overlayPos) {
stream.pos = stream.start;
state.overlayCur = overlay.token(stream, state.overlay);
state.overlayPos = stream.pos;
}
stream.pos = Math.min(state.basePos, state.overlayPos);
// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur;
else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},
indent: base.indent && function(state, textAfter) {
return base.indent(state.base, textAfter);
},
electricChars: base.electricChars,
innerMode: function(state) { return {state: state.base, mode: base}; },
blankLine: function(state) {
if (base.blankLine) base.blankLine(state.base);
if (overlay.blankLine) overlay.blankLine(state.overlay);
}
};
};
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | 2 2 2 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineSimpleMode = function(name, states) {
CodeMirror.defineMode(name, function(config) {
return CodeMirror.simpleMode(config, states);
});
};
CodeMirror.simpleMode = function(config, states) {
ensureState(states, "start");
var states_ = {}, meta = states.meta || {}, hasIndentation = false;
for (var state in states) if (state != meta && states.hasOwnProperty(state)) {
var list = states_[state] = [], orig = states[state];
for (var i = 0; i < orig.length; i++) {
var data = orig[i];
list.push(new Rule(data, states));
if (data.indent || data.dedent) hasIndentation = true;
}
}
var mode = {
startState: function() {
return {state: "start", pending: null,
local: null, localState: null,
indent: hasIndentation ? [] : null};
},
copyState: function(state) {
var s = {state: state.state, pending: state.pending,
local: state.local, localState: null,
indent: state.indent && state.indent.slice(0)};
if (state.localState)
s.localState = CodeMirror.copyState(state.local.mode, state.localState);
if (state.stack)
s.stack = state.stack.slice(0);
for (var pers = state.persistentStates; pers; pers = pers.next)
s.persistentStates = {mode: pers.mode,
spec: pers.spec,
state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state),
next: s.persistentStates};
return s;
},
token: tokenFunction(states_, config),
innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; },
indent: indentFunction(states_, meta)
};
if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop))
mode[prop] = meta[prop];
return mode;
};
function ensureState(states, name) {
if (!states.hasOwnProperty(name))
throw new Error("Undefined state " + name + "in simple mode");
}
function toRegex(val, caret) {
if (!val) return /(?:)/;
var flags = "";
if (val instanceof RegExp) {
if (val.ignoreCase) flags = "i";
val = val.source;
} else {
val = String(val);
}
return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags);
}
function asToken(val) {
if (!val) return null;
if (typeof val == "string") return val.replace(/\./g, " ");
var result = [];
for (var i = 0; i < val.length; i++)
result.push(val[i] && val[i].replace(/\./g, " "));
return result;
}
function Rule(data, states) {
if (data.next || data.push) ensureState(states, data.next || data.push);
this.regex = toRegex(data.regex);
this.token = asToken(data.token);
this.data = data;
}
function tokenFunction(states, config) {
return function(stream, state) {
if (state.pending) {
var pend = state.pending.shift();
if (state.pending.length == 0) state.pending = null;
stream.pos += pend.text.length;
return pend.token;
}
if (state.local) {
if (state.local.end && stream.match(state.local.end)) {
var tok = state.local.endToken || null;
state.local = state.localState = null;
return tok;
} else {
var tok = state.local.mode.token(stream, state.localState), m;
if (state.local.endScan && (m = state.local.endScan.exec(stream.current())))
stream.pos = stream.start + m.index;
return tok;
}
}
var curState = states[state.state];
for (var i = 0; i < curState.length; i++) {
var rule = curState[i];
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
if (matches) {
if (rule.data.next) {
state.state = rule.data.next;
} else if (rule.data.push) {
(state.stack || (state.stack = [])).push(state.state);
state.state = rule.data.push;
} else if (rule.data.pop && state.stack && state.stack.length) {
state.state = state.stack.pop();
}
if (rule.data.mode)
enterLocalMode(config, state, rule.data.mode, rule.token);
if (rule.data.indent)
state.indent.push(stream.indentation() + config.indentUnit);
if (rule.data.dedent)
state.indent.pop();
if (matches.length > 2) {
state.pending = [];
for (var j = 2; j < matches.length; j++)
if (matches[j])
state.pending.push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
return rule.token[0];
} else if (rule.token && rule.token.join) {
return rule.token[0];
} else {
return rule.token;
}
}
}
stream.next();
return null;
};
}
function cmp(a, b) {
if (a === b) return true;
if (!a || typeof a != "object" || !b || typeof b != "object") return false;
var props = 0;
for (var prop in a) if (a.hasOwnProperty(prop)) {
if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false;
props++;
}
for (var prop in b) if (b.hasOwnProperty(prop)) props--;
return props == 0;
}
function enterLocalMode(config, state, spec, token) {
var pers;
if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next)
if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p;
var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec);
var lState = pers ? pers.state : CodeMirror.startState(mode);
if (spec.persistent && !pers)
state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates};
state.localState = lState;
state.local = {mode: mode,
end: spec.end && toRegex(spec.end),
endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false),
endToken: token && token.join ? token[token.length - 1] : token};
}
function indexOf(val, arr) {
for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true;
}
function indentFunction(states, meta) {
return function(state, textAfter, line) {
if (state.local && state.local.mode.indent)
return state.local.mode.indent(state.localState, textAfter, line);
if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1)
return CodeMirror.Pass;
var pos = state.indent.length - 1, rules = states[state.state];
scan: for (;;) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule.data.dedent && rule.data.dedentIfLineStart !== false) {
var m = rule.regex.exec(textAfter);
if (m && m[0]) {
pos--;
if (rule.next || rule.push) rules = states[rule.next || rule.push];
textAfter = textAfter.slice(m[0].length);
continue scan;
}
}
}
break;
}
return pos < 0 ? 0 : state.indent[pos];
};
}
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var htmlConfig = {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true,
caseFold: true
}
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
for (var prop in config_) config[prop] = config_[prop]
// Return variables for tokenizers
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag bracket";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
inText.isInText = true;
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
};
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName;
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
this.noIndent = true;
}
function popContext(state) {
if (state.context) state.context = state.context.prev;
}
function maybePopContext(state, nextTagName) {
var parentTagName;
while (true) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
}
popContext(state);
}
}
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(tagName)) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
}
setStyle = "error";
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!config.allowMissing) setStyle = "error";
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function(baseIndent) {
var state = {tokenize: inText,
state: baseState,
indented: baseIndent || 0,
tagName: null, tagStart: null,
context: null}
if (baseIndent != null) state.baseIndent = baseIndent
return state
},
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
}
return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (config.multilineTagIndentPastTag !== false)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
}
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = config.contextGrabbers[context.tagName];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
context = context.prev;
else
break;
}
}
while (context && context.prev && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return state.baseIndent || 0;
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: config.htmlMode ? "html" : "xml",
helperType: config.htmlMode ? "html" : "xml",
skipAttribute: function(state) {
if (state.state == attrValueState)
state.state = attrState
}
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
});
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| DefaultCodeMirrorMimeMode.js | 20% | (1 / 5) | 100% | (0 / 0) | 0% | (0 / 2) | 20% | (1 / 5) | |
| clike.js | 7.51% | (16 / 213) | 1.73% | (3 / 173) | 4.35% | (1 / 23) | 8.65% | (16 / 185) | |
| clojure.js | 7.83% | (9 / 115) | 2.86% | (3 / 105) | 8.33% | (1 / 12) | 8.04% | (9 / 112) | |
| coffeescript.js | 4.85% | (10 / 206) | 1.73% | (3 / 173) | 7.14% | (1 / 14) | 5.05% | (10 / 198) | |
| jsx.js | 9.52% | (4 / 42) | 8.11% | (3 / 37) | 11.11% | (1 / 9) | 9.76% | (4 / 41) | |
| livescript.js | 5.56% | (3 / 54) | 8.82% | (3 / 34) | 14.29% | (1 / 7) | 5.56% | (3 / 54) | |
| php.js | 6.06% | (8 / 132) | 2.88% | (3 / 104) | 4.76% | (1 / 21) | 6.72% | (8 / 119) | |
| python.js | 5.85% | (12 / 205) | 1.58% | (3 / 190) | 6.25% | (1 / 16) | 6.28% | (12 / 191) | |
| shell.js | 8.14% | (7 / 86) | 4.17% | (3 / 72) | 9.09% | (1 / 11) | 8.54% | (7 / 82) | |
| stylus.js | 6% | (26 / 433) | 0.64% | (3 / 472) | 2.44% | (1 / 41) | 6.47% | (26 / 402) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.CodeMirrorMimeMode}
*/
WebInspector.DefaultCodeMirrorMimeMode = function()
{
}
WebInspector.DefaultCodeMirrorMimeMode.prototype = {
/**
* @param {!Runtime.Extension} extension
* @override
*/
install: function(extension)
{
var modeFileName = extension.descriptor()["fileName"];
var modeContent = extension.module().resource(modeFileName);
self.eval(modeContent + "\n//# sourceURL=" + modeFileName);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("clike", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
dontAlignCalls = parserConfig.dontAlignCalls,
keywords = parserConfig.keywords || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "keyword";
}
if (builtin.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "builtin";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
else return ctx.indented + (closing ? 0 : indentUnit);
},
electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
fold: "brace"
};
});
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
"double static else struct entry switch extern typedef float union for unsigned " +
"goto while enum void const signed volatile";
function cppHook(stream, state) {
if (!state.startOfLine) return false;
for (;;) {
if (stream.skipTo("\\")) {
stream.next();
if (stream.eol()) {
state.tokenize = cppHook;
break;
}
} else {
stream.skipToEnd();
state.tokenize = null;
break;
}
}
return "meta";
}
function cpp11StringHook(stream, state) {
stream.backUp(1);
// Raw strings.
if (stream.match(/(R|u8R|uR|UR|LR)/)) {
var match = stream.match(/"([^\s\\()]{0,16})\(/);
if (!match) {
return false;
}
state.cpp11RawStringDelim = match[1];
state.tokenize = tokenRawString;
return tokenRawString(stream, state);
}
// Unicode strings/chars.
if (stream.match(/(u8|u|U|L)/)) {
if (stream.match(/["']/, /* eat */ false)) {
return "string";
}
return false;
}
// Ignore this hook.
stream.next();
return false;
}
// C#-style strings where "" escapes a quote.
function tokenAtString(stream, state) {
var next;
while ((next = stream.next()) != null) {
if (next == '"' && !stream.eat('"')) {
state.tokenize = null;
break;
}
}
return "string";
}
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
// <delim> can be a string up to 16 characters long.
function tokenRawString(stream, state) {
// Escape characters that have special regex meanings.
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
if (match)
state.tokenize = null;
else
stream.skipToEnd();
return "string";
}
function def(mimes, mode) {
if (typeof mimes == "string") mimes = [mimes];
var words = [];
function add(obj) {
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
words.push(prop);
}
add(mode.keywords);
add(mode.builtin);
add(mode.atoms);
if (words.length) {
mode.helperType = mimes[0];
CodeMirror.registerHelper("hintWords", mimes[0], words);
}
for (var i = 0; i < mimes.length; ++i)
CodeMirror.defineMIME(mimes[i], mode);
}
def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
name: "clike",
keywords: words(cKeywords),
blockKeywords: words("case do else for if switch while struct"),
atoms: words("null"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
"static_cast typeid catch operator template typename class friend private " +
"this using const_cast inline public throw virtual delete mutable protected " +
"wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
"static_assert override"),
blockKeywords: words("catch class do else finally for if struct switch try while"),
atoms: words("true false null"),
hooks: {
"#": cppHook,
"u": cpp11StringHook,
"U": cpp11StringHook,
"L": cpp11StringHook,
"R": cpp11StringHook
},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-java", {
name: "clike",
keywords: words("abstract assert boolean break byte case catch char class const continue default " +
"do double else enum extends final finally float for goto if implements import " +
"instanceof int interface long native new package private protected public " +
"return short static strictfp super switch synchronized this throw throws transient " +
"try void volatile while"),
blockKeywords: words("catch class do else finally for if switch try while"),
atoms: words("true false null"),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}
},
modeProps: {fold: ["brace", "import"]}
});
def("text/x-csharp", {
name: "clike",
keywords: words("abstract as base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
atoms: words("true false null"),
hooks: {
"@": function(stream, state) {
if (stream.eat('"')) {
state.tokenize = tokenAtString;
return tokenAtString(stream, state);
}
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
def("text/x-scala", {
name: "clike",
keywords: words(
/* scala */
"abstract case catch class def do else extends false final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
"<% >: # @ " +
/* package scala */
"assert assume require print println printf readLine readBoolean readByte readShort " +
"readChar readInt readLong readFloat readDouble " +
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
blockKeywords: words("catch class do else finally for forSome if match switch try while"),
atoms: words("true false null"),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
name: "clike",
keywords: words("float int bool void " +
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
"mat2 mat3 mat4 " +
"sampler1D sampler2D sampler3D samplerCube " +
"sampler1DShadow sampler2DShadow" +
"const attribute uniform varying " +
"break continue discard return " +
"for while do if else struct " +
"in out inout"),
blockKeywords: words("for while do if else struct"),
builtin: words("radians degrees sin cos tan asin acos atan " +
"pow exp log exp2 sqrt inversesqrt " +
"abs sign floor ceil fract mod min max clamp mix step smootstep " +
"length distance dot cross normalize ftransform faceforward " +
"reflect refract matrixCompMult " +
"lessThan lessThanEqual greaterThan greaterThanEqual " +
"equal notEqual any all not " +
"texture1D texture1DProj texture1DLod texture1DProjLod " +
"texture2D texture2DProj texture2DLod texture2DProjLod " +
"texture3D texture3DProj texture3DLod texture3DProjLod " +
"textureCube textureCubeLod " +
"shadow1D shadow2D shadow1DProj shadow2DProj " +
"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
"dFdx dFdy fwidth " +
"noise1 noise2 noise3 noise4"),
atoms: words("true false " +
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
"gl_FogCoord " +
"gl_Position gl_PointSize gl_ClipVertex " +
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
"gl_TexCoord gl_FogFragCoord " +
"gl_FragCoord gl_FrontFacing " +
"gl_FragColor gl_FragData gl_FragDepth " +
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
"gl_ProjectionMatrixInverseTranspose " +
"gl_ModelViewProjectionMatrixInverseTranspose " +
"gl_TextureMatrixInverseTranspose " +
"gl_NormalScale gl_DepthRange gl_ClipPlane " +
"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
"gl_FrontLightModelProduct gl_BackLightModelProduct " +
"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
"gl_FogParameters " +
"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
"gl_MaxDrawBuffers"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | 2 2 2 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/**
* Author: Hans Engel
* Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
*/
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("clojure", function (options) {
var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
var INDENT_WORD_SKIP = options.indentUnit || 2;
var NORMAL_INDENT_UNIT = options.indentUnit || 2;
function makeKeywords(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var atoms = makeKeywords("true false nil");
var keywords = makeKeywords(
"defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
var builtins = makeKeywords(
"* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> ->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? declare default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int rand-nth range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap *default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! set-agent-send-off-executor! some-> some->>");
var indentKeys = makeKeywords(
// Built-ins
"ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch " +
// Binding forms
"let letfn binding loop for doseq dotimes when-let if-let " +
// Data structures
"defstruct struct-map assoc " +
// clojure.test
"testing deftest " +
// contrib
"handler-case handle dotrace deftrace");
var tests = {
digit: /\d/,
digit_or_colon: /[\d:]/,
hex: /[0-9a-f]/i,
sign: /[+-]/,
exponent: /e/i,
keyword_char: /[^\s\(\[\;\)\]]/,
symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/
};
function stateStack(indent, type, prev) { // represents a state stack object
this.indent = indent;
this.type = type;
this.prev = prev;
}
function pushStack(state, indent, type) {
state.indentStack = new stateStack(indent, type, state.indentStack);
}
function popStack(state) {
state.indentStack = state.indentStack.prev;
}
function isNumber(ch, stream){
// hex
if ( ch === '0' && stream.eat(/x/i) ) {
stream.eatWhile(tests.hex);
return true;
}
// leading sign
if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
stream.eat(tests.sign);
ch = stream.next();
}
if ( tests.digit.test(ch) ) {
stream.eat(ch);
stream.eatWhile(tests.digit);
if ( '.' == stream.peek() ) {
stream.eat('.');
stream.eatWhile(tests.digit);
}
if ( stream.eat(tests.exponent) ) {
stream.eat(tests.sign);
stream.eatWhile(tests.digit);
}
return true;
}
return false;
}
// Eat character that starts after backslash \
function eatCharacter(stream) {
var first = stream.next();
// Read special literals: backspace, newline, space, return.
// Just read all lowercase letters.
if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
return;
}
// Read unicode character: \u1000 \uA0a1
if (first === "u") {
stream.match(/[0-9a-z]{4}/i, true);
}
}
return {
startState: function () {
return {
indentStack: null,
indentation: 0,
mode: false
};
},
token: function (stream, state) {
if (state.indentStack == null && stream.sol()) {
// update indentation, but only if indentStack is empty
state.indentation = stream.indentation();
}
// skip spaces
if (stream.eatSpace()) {
return null;
}
var returnType = null;
switch(state.mode){
case "string": // multi-line string parsing mode
var next, escaped = false;
while ((next = stream.next()) != null) {
if (next == "\"" && !escaped) {
state.mode = false;
break;
}
escaped = !escaped && next == "\\";
}
returnType = STRING; // continue on in string mode
break;
default: // default parsing mode
var ch = stream.next();
if (ch == "\"") {
state.mode = "string";
returnType = STRING;
} else if (ch == "\\") {
eatCharacter(stream);
returnType = CHARACTER;
} else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
returnType = ATOM;
} else if (ch == ";") { // comment
stream.skipToEnd(); // rest of the line is a comment
returnType = COMMENT;
} else if (isNumber(ch,stream)){
returnType = NUMBER;
} else if (ch == "(" || ch == "[" || ch == "{" ) {
var keyWord = '', indentTemp = stream.column(), letter;
/**
Either
(indent-word ..
(non-indent-word ..
(;something else, bracket, etc.
*/
if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
keyWord += letter;
}
if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
/^(?:def|with)/.test(keyWord))) { // indent-word
pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
} else { // non-indent word
// we continue eating the spaces
stream.eatSpace();
if (stream.eol() || stream.peek() == ";") {
// nothing significant after
// we restart indentation the user defined spaces after
pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
} else {
pushStack(state, indentTemp + stream.current().length, ch); // else we match
}
}
stream.backUp(stream.current().length - 1); // undo all the eating
returnType = BRACKET;
} else if (ch == ")" || ch == "]" || ch == "}") {
returnType = BRACKET;
if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
popStack(state);
}
} else if ( ch == ":" ) {
stream.eatWhile(tests.symbol);
return ATOM;
} else {
stream.eatWhile(tests.symbol);
if (keywords && keywords.propertyIsEnumerable(stream.current())) {
returnType = KEYWORD;
} else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
returnType = BUILTIN;
} else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
returnType = ATOM;
} else {
returnType = VAR;
}
}
}
return returnType;
},
indent: function (state) {
if (state.indentStack == null) return state.indentation;
return state.indentStack.indent;
},
closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
});
CodeMirror.defineMIME("text/x-clojure", "clojure");
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | 2 2 2 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
* https://github.com/pickhardt/coffeescript-codemirror-mode
*/
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("coffeescript", function(conf) {
var ERRORCLASS = "error";
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/;
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
var wordOperators = wordRegexp(["and", "or", "not",
"is", "isnt", "in",
"instanceof", "typeof"]);
var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
"switch", "try", "catch", "finally", "class"];
var commonKeywords = ["break", "by", "continue", "debugger", "delete",
"do", "in", "of", "new", "return", "then",
"this", "throw", "when", "until"];
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
indentKeywords = wordRegexp(indentKeywords);
var stringPrefixes = /^('{3}|\"{3}|['\"])/;
var regexPrefixes = /^(\/{3}|\/)/;
var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
var constants = wordRegexp(commonConstants);
// Tokenizers
function tokenBase(stream, state) {
// Handle scope changes
if (stream.sol()) {
if (state.scope.align === null) state.scope.align = false;
var scopeOffset = state.scope.offset;
if (stream.eatSpace()) {
var lineOffset = stream.indentation();
if (lineOffset > scopeOffset && state.scope.type == "coffee") {
return "indent";
} else if (lineOffset < scopeOffset) {
return "dedent";
}
return null;
} else {
if (scopeOffset > 0) {
dedent(stream, state);
}
}
}
if (stream.eatSpace()) {
return null;
}
var ch = stream.peek();
// Handle docco title comment (single line)
if (stream.match("####")) {
stream.skipToEnd();
return "comment";
}
// Handle multi line comments
if (stream.match("###")) {
state.tokenize = longComment;
return state.tokenize(stream, state);
}
// Single line comment
if (ch === "#") {
stream.skipToEnd();
return "comment";
}
// Handle number literals
if (stream.match(/^-?[0-9\.]/, false)) {
var floatLiteral = false;
// Floats
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
floatLiteral = true;
}
if (stream.match(/^-?\d+\.\d*/)) {
floatLiteral = true;
}
if (stream.match(/^-?\.\d+/)) {
floatLiteral = true;
}
if (floatLiteral) {
// prevent from getting extra . on 1..
if (stream.peek() == "."){
stream.backUp(1);
}
return "number";
}
// Integers
var intLiteral = false;
// Hex
if (stream.match(/^-?0x[0-9a-f]+/i)) {
intLiteral = true;
}
// Decimal
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
intLiteral = true;
}
// Zero by itself with no other piece of number.
if (stream.match(/^-?0(?![\dx])/i)) {
intLiteral = true;
}
if (intLiteral) {
return "number";
}
}
// Handle strings
if (stream.match(stringPrefixes)) {
state.tokenize = tokenFactory(stream.current(), false, "string");
return state.tokenize(stream, state);
}
// Handle regex literals
if (stream.match(regexPrefixes)) {
if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
state.tokenize = tokenFactory(stream.current(), true, "string-2");
return state.tokenize(stream, state);
} else {
stream.backUp(1);
}
}
// Handle operators and delimiters
if (stream.match(operators) || stream.match(wordOperators)) {
return "operator";
}
if (stream.match(delimiters)) {
return "punctuation";
}
if (stream.match(constants)) {
return "atom";
}
if (stream.match(keywords)) {
return "keyword";
}
if (stream.match(identifiers)) {
return "variable";
}
if (stream.match(properties)) {
return "property";
}
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
function tokenFactory(delimiter, singleline, outclass) {
return function(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\/\\]/);
if (stream.eat("\\")) {
stream.next();
if (singleline && stream.eol()) {
return outclass;
}
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
return outclass;
} else {
stream.eat(/['"\/]/);
}
}
if (singleline) {
if (conf.mode.singleLineStringErrors) {
outclass = ERRORCLASS;
} else {
state.tokenize = tokenBase;
}
}
return outclass;
};
}
function longComment(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^#]/);
if (stream.match("###")) {
state.tokenize = tokenBase;
break;
}
stream.eatWhile("#");
}
return "comment";
}
function indent(stream, state, type) {
type = type || "coffee";
var offset = 0, align = false, alignOffset = null;
for (var scope = state.scope; scope; scope = scope.prev) {
if (scope.type === "coffee") {
offset = scope.offset + conf.indentUnit;
break;
}
}
if (type !== "coffee") {
align = null;
alignOffset = stream.column() + stream.current().length;
} else if (state.scope.align) {
state.scope.align = false;
}
state.scope = {
offset: offset,
type: type,
prev: state.scope,
align: align,
alignOffset: alignOffset
};
}
function dedent(stream, state) {
if (!state.scope.prev) return;
if (state.scope.type === "coffee") {
var _indent = stream.indentation();
var matched = false;
for (var scope = state.scope; scope; scope = scope.prev) {
if (_indent === scope.offset) {
matched = true;
break;
}
}
if (!matched) {
return true;
}
while (state.scope.prev && state.scope.offset !== _indent) {
state.scope = state.scope.prev;
}
return false;
} else {
state.scope = state.scope.prev;
return false;
}
}
function tokenLexer(stream, state) {
var style = state.tokenize(stream, state);
var current = stream.current();
// Handle "." connected identifiers
if (current === ".") {
style = state.tokenize(stream, state);
current = stream.current();
if (/^\.[\w$]+$/.test(current)) {
return "variable";
} else {
return ERRORCLASS;
}
}
// Handle scope changes.
if (current === "return") {
state.dedent += 1;
}
if (((current === "->" || current === "=>") &&
!state.lambda &&
!stream.peek())
|| style === "indent") {
indent(stream, state);
}
var delimiter_index = "[({".indexOf(current);
if (delimiter_index !== -1) {
indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
}
if (indentKeywords.exec(current)){
indent(stream, state);
}
if (current == "then"){
dedent(stream, state);
}
if (style === "dedent") {
if (dedent(stream, state)) {
return ERRORCLASS;
}
}
delimiter_index = "])}".indexOf(current);
if (delimiter_index !== -1) {
while (state.scope.type == "coffee" && state.scope.prev)
state.scope = state.scope.prev;
if (state.scope.type == current)
state.scope = state.scope.prev;
}
if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") {
if (state.scope.prev) state.scope = state.scope.prev;
state.dedent -= 1;
}
return style;
}
var external = {
startState: function(basecolumn) {
return {
tokenize: tokenBase,
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
lastToken: null,
lambda: false,
dedent: 0
};
},
token: function(stream, state) {
var fillAlign = state.scope.align === null && state.scope;
if (fillAlign && stream.sol()) fillAlign.align = false;
var style = tokenLexer(stream, state);
if (fillAlign && style && style != "comment") fillAlign.align = true;
state.lastToken = {style:style, content: stream.current()};
if (stream.eol() && stream.lambda) {
state.lambda = false;
}
return style;
},
indent: function(state, text) {
if (state.tokenize != tokenBase) return 0;
var scope = state.scope;
var closer = text && "])}".indexOf(text.charAt(0)) > -1;
if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
var closes = closer && scope.type === text.charAt(0);
if (scope.align)
return scope.alignOffset - (closes ? 1 : 0);
else
return (closes ? scope.prev : scope).offset;
},
lineComment: "#",
fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 2 2 2 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
else // Plain browser env
mod(CodeMirror)
})(function(CodeMirror) {
"use strict"
function copyContext(context) {
return {state: CodeMirror.copyState(context.mode, context.state),
mode: context.mode,
depth: context.depth,
prev: context.prev && copyContext(context.prev)}
}
CodeMirror.defineMode("jsx", function(config) {
var xmlMode = CodeMirror.getMode(config, "xml")
var jsMode = CodeMirror.getMode(config, "javascript")
return {
startState: function() {
return {context: {state: CodeMirror.startState(jsMode), mode: jsMode}}
},
copyState: function(state) {
return {context: copyContext(state.context)}
},
token: function(stream, state) {
var cx = state.context
if (cx.mode == xmlMode) {
if (stream.peek() == "{") {
xmlMode.skipAttribute(cx.state)
state.context = {state: CodeMirror.startState(jsMode, xmlMode.indent(cx.state, "")),
mode: jsMode,
depth: 1,
prev: state.context}
return jsMode.token(stream, state.context.state)
} else { // FIXME skip attribute
var style = xmlMode.token(stream, cx.state), cur, brace
if (/\btag\b/.test(style) && !cx.state.context && /^\/?>$/.test(stream.current()))
state.context = state.context.prev
else if (!style && (brace = (cur = stream.current()).indexOf("{")) > -1)
stream.backUp(cur.length - brace)
return style
}
} else { // jsMode
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
jsMode.skipExpression(cx.state)
state.context = {state: CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
mode: xmlMode,
prev: state.context}
return xmlMode.token(stream, state.context.state)
} else {
var style = jsMode.token(stream, cx.state)
if (!style && cx.depth != null) {
var cur = stream.current()
if (cur == "{") {
cx.depth++
} else if (cur == "}") {
if (--cx.depth == 0) state.context = state.context.prev
}
}
return style
}
}
},
indent: function(state, textAfter, fullLine) {
return state.context.mode.indent(state.context.state, textAfter, fullLine)
},
innerMode: function(state) {
return state.context[state.context.length - 1]
}
}
}, "xml", "javascript")
CodeMirror.defineMIME("text/jsx", "jsx")
})
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | 2 2 2 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
* https://github.com/duralog/CodeMirror
*/
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode('livescript', function(){
var tokenBase = function(stream, state) {
var next_rule = state.next || "start";
if (next_rule) {
state.next = state.next;
var nr = Rules[next_rule];
if (nr.splice) {
for (var i$ = 0; i$ < nr.length; ++i$) {
var r = nr[i$];
if (r.regex && stream.match(r.regex)) {
state.next = r.next || state.next;
return r.token;
}
}
stream.next();
return 'error';
}
if (stream.match(r = Rules[next_rule])) {
if (r.regex && stream.match(r.regex)) {
state.next = r.next;
return r.token;
} else {
stream.next();
return 'error';
}
}
}
stream.next();
return 'error';
};
var external = {
startState: function(){
return {
next: 'start',
lastToken: null
};
},
token: function(stream, state){
while (stream.pos == stream.start)
var style = tokenBase(stream, state);
state.lastToken = {
style: style,
indent: stream.indentation(),
content: stream.current()
};
return style.replace(/\./g, ' ');
},
indent: function(state){
var indentation = state.lastToken.indent;
if (state.lastToken.content.match(indenter)) {
indentation += 2;
}
return indentation;
}
};
return external;
});
var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
var stringfill = {
token: 'string',
regex: '.+'
};
var Rules = {
start: [
{
token: 'comment.doc',
regex: '/\\*',
next: 'comment'
}, {
token: 'comment',
regex: '#.*'
}, {
token: 'keyword',
regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
}, {
token: 'constant.language',
regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
}, {
token: 'invalid.illegal',
regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
}, {
token: 'language.support.class',
regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
}, {
token: 'language.support.function',
regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
}, {
token: 'variable.language',
regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
}, {
token: 'identifier',
regex: identifier + '\\s*:(?![:=])'
}, {
token: 'variable',
regex: identifier
}, {
token: 'keyword.operator',
regex: '(?:\\.{3}|\\s+\\?)'
}, {
token: 'keyword.variable',
regex: '(?:@+|::|\\.\\.)',
next: 'key'
}, {
token: 'keyword.operator',
regex: '\\.\\s*',
next: 'key'
}, {
token: 'string',
regex: '\\\\\\S[^\\s,;)}\\]]*'
}, {
token: 'string.doc',
regex: '\'\'\'',
next: 'qdoc'
}, {
token: 'string.doc',
regex: '"""',
next: 'qqdoc'
}, {
token: 'string',
regex: '\'',
next: 'qstring'
}, {
token: 'string',
regex: '"',
next: 'qqstring'
}, {
token: 'string',
regex: '`',
next: 'js'
}, {
token: 'string',
regex: '<\\[',
next: 'words'
}, {
token: 'string.regex',
regex: '//',
next: 'heregex'
}, {
token: 'string.regex',
regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
next: 'key'
}, {
token: 'constant.numeric',
regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
}, {
token: 'lparen',
regex: '[({[]'
}, {
token: 'rparen',
regex: '[)}\\]]',
next: 'key'
}, {
token: 'keyword.operator',
regex: '\\S+'
}, {
token: 'text',
regex: '\\s+'
}
],
heregex: [
{
token: 'string.regex',
regex: '.*?//[gimy$?]{0,4}',
next: 'start'
}, {
token: 'string.regex',
regex: '\\s*#{'
}, {
token: 'comment.regex',
regex: '\\s+(?:#.*)?'
}, {
token: 'string.regex',
regex: '\\S+'
}
],
key: [
{
token: 'keyword.operator',
regex: '[.?@!]+'
}, {
token: 'identifier',
regex: identifier,
next: 'start'
}, {
token: 'text',
regex: '',
next: 'start'
}
],
comment: [
{
token: 'comment.doc',
regex: '.*?\\*/',
next: 'start'
}, {
token: 'comment.doc',
regex: '.+'
}
],
qdoc: [
{
token: 'string',
regex: ".*?'''",
next: 'key'
}, stringfill
],
qqdoc: [
{
token: 'string',
regex: '.*?"""',
next: 'key'
}, stringfill
],
qstring: [
{
token: 'string',
regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
next: 'key'
}, stringfill
],
qqstring: [
{
token: 'string',
regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
next: 'key'
}, stringfill
],
js: [
{
token: 'string',
regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
next: 'key'
}, stringfill
],
words: [
{
token: 'string',
regex: '.*?\\]>',
next: 'key'
}, stringfill
]
};
for (var idx in Rules) {
var r = Rules[idx];
if (r.splice) {
for (var i = 0, len = r.length; i < len; ++i) {
var rr = r[i];
if (typeof rr.regex === 'string') {
Rules[idx][i].regex = new RegExp('^' + rr.regex);
}
}
} else if (typeof rr.regex === 'string') {
Rules[idx].regex = new RegExp('^' + r.regex);
}
}
CodeMirror.defineMIME('text/x-livescript', 'livescript');
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 2 2 2 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function keywords(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
function heredoc(delim) {
return function(stream, state) {
if (stream.match(delim)) state.tokenize = null;
else stream.skipToEnd();
return "string";
};
}
// Helper for stringWithEscapes
function matchSequence(list) {
if (list.length == 0) return stringWithEscapes;
return function (stream, state) {
var patterns = list[0];
for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
state.tokenize = matchSequence(list.slice(1));
return patterns[i][1];
}
state.tokenize = stringWithEscapes;
return "string";
};
}
function stringWithEscapes(stream, state) {
var escaped = false, next, end = false;
if (stream.current() == '"') return "string";
// "Complex" syntax
if (stream.match("${", false) || stream.match("{$", false)) {
state.tokenize = null;
return "string";
}
// Simple syntax
if (stream.match(/\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
// After the variable name there may appear array or object operator.
if (stream.match("[", false)) {
// Match array operator
state.tokenize = matchSequence([
[["[", null]],
[[/\d[\w\.]*/, "number"],
[/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
[/[\w\$]+/, "variable"]],
[["]", null]]
]);
}
if (stream.match(/\-\>\w/, false)) {
// Match object operator
state.tokenize = matchSequence([
[["->", null]],
[[/[\w]+/, "variable"]]
]);
}
return "variable-2";
}
// Normal string
while (
!stream.eol() &&
(!stream.match("{$", false)) &&
(!stream.match(/(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false) || escaped)
) {
next = stream.next();
if (!escaped && next == '"') { end = true; break; }
escaped = !escaped && next == "\\";
}
if (end) {
state.tokenize = null;
state.phpEncapsStack.pop();
}
return "string";
}
var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
"do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
"for foreach function global goto if implements interface instanceof namespace " +
"new or private protected public static switch throw trait try use var while xor " +
"die echo empty exit eval include include_once isset list require require_once return " +
"print unset __halt_compiler self static parent yield insteadof finally";
var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once";
CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
CodeMirror.registerHelper("wordChars", "php", /[\\w$]/);
var phpConfig = {
name: "clike",
helperType: "php",
keywords: keywords(phpKeywords),
blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
atoms: keywords(phpAtoms),
builtin: keywords(phpBuiltin),
multiLineStrings: true,
hooks: {
"$": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "variable-2";
},
"<": function(stream, state) {
if (stream.match(/<</)) {
stream.eatWhile(/[\w\.]/);
state.tokenize = heredoc(stream.current().slice(3));
return state.tokenize(stream, state);
}
return false;
},
"#": function(stream) {
while (!stream.eol() && !stream.match("?>", false)) stream.next();
return "comment";
},
"/": function(stream) {
if (stream.eat("/")) {
while (!stream.eol() && !stream.match("?>", false)) stream.next();
return "comment";
}
return false;
},
'"': function(stream, state) {
if (!state.phpEncapsStack)
state.phpEncapsStack = [];
state.phpEncapsStack.push(0);
state.tokenize = stringWithEscapes;
return state.tokenize(stream, state);
},
"{": function(_stream, state) {
if (state.phpEncapsStack && state.phpEncapsStack.length > 0)
state.phpEncapsStack[state.phpEncapsStack.length - 1]++;
return false;
},
"}": function(_stream, state) {
if (state.phpEncapsStack && state.phpEncapsStack.length > 0)
if (--state.phpEncapsStack[state.phpEncapsStack.length - 1] == 0)
state.tokenize = stringWithEscapes;
return false;
}
}
};
CodeMirror.defineMode("php", function(config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, "text/html");
var phpMode = CodeMirror.getMode(config, phpConfig);
function dispatch(stream, state) {
var isPHP = state.curMode == phpMode;
if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
if (!isPHP) {
if (stream.match(/^<\?\w*/)) {
state.curMode = phpMode;
state.curState = state.php;
return "meta";
}
if (state.pending == '"' || state.pending == "'") {
while (!stream.eol() && stream.next() != state.pending) {}
var style = "string";
} else if (state.pending && stream.pos < state.pending.end) {
stream.pos = state.pending.end;
var style = state.pending.style;
} else {
var style = htmlMode.token(stream, state.curState);
}
if (state.pending) state.pending = null;
var cur = stream.current(), openPHP = cur.search(/<\?/), m;
if (openPHP != -1) {
if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
else state.pending = {end: stream.pos, style: style};
stream.backUp(cur.length - openPHP);
}
return style;
} else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
state.curMode = htmlMode;
state.curState = state.html;
return "meta";
} else {
return phpMode.token(stream, state.curState);
}
}
return {
startState: function() {
var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
return {html: html,
php: php,
curMode: parserConfig.startOpen ? phpMode : htmlMode,
curState: parserConfig.startOpen ? php : html,
pending: null};
},
copyState: function(state) {
var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
if (state.curMode == htmlMode) cur = htmlNew;
else cur = phpNew;
return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
pending: state.pending};
},
token: dispatch,
indent: function(state, textAfter) {
if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
(state.curMode == phpMode && /^\?>/.test(textAfter)))
return htmlMode.indent(state.html, textAfter);
return state.curMode.indent(state.curState, textAfter);
},
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
};
}, "htmlmixed", "clike");
CodeMirror.defineMIME("application/x-httpd-php", "php");
CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
CodeMirror.defineMIME("text/x-php", phpConfig);
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | 2 2 2 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
var wordOperators = wordRegexp(["and", "or", "not", "is", "in"]);
var commonKeywords = ["as", "assert", "break", "class", "continue",
"def", "del", "elif", "else", "except", "finally",
"for", "from", "global", "if", "import",
"lambda", "pass", "raise", "return",
"try", "while", "with", "yield"];
var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
"classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
"enumerate", "eval", "filter", "float", "format", "frozenset",
"getattr", "globals", "hasattr", "hash", "help", "hex", "id",
"input", "int", "isinstance", "issubclass", "iter", "len",
"list", "locals", "map", "max", "memoryview", "min", "next",
"object", "oct", "open", "ord", "pow", "property", "range",
"repr", "reversed", "round", "set", "setattr", "slice",
"sorted", "staticmethod", "str", "sum", "super", "tuple",
"type", "vars", "zip", "__import__", "NotImplemented",
"Ellipsis", "__debug__"];
var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
"file", "intern", "long", "raw_input", "reduce", "reload",
"unichr", "unicode", "xrange", "False", "True", "None"],
keywords: ["exec", "print"]};
var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
keywords: ["nonlocal", "False", "True", "None"]};
CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
function top(state) {
return state.scopes[state.scopes.length - 1];
}
CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = "error";
var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
if(parserConf.extra_keywords != undefined){
myKeywords = myKeywords.concat(parserConf.extra_keywords);
}
if(parserConf.extra_builtins != undefined){
myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
}
if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
myKeywords = myKeywords.concat(py3.keywords);
myBuiltins = myBuiltins.concat(py3.builtins);
var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
} else {
myKeywords = myKeywords.concat(py2.keywords);
myBuiltins = myBuiltins.concat(py2.builtins);
var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
}
var keywords = wordRegexp(myKeywords);
var builtins = wordRegexp(myBuiltins);
// tokenizers
function tokenBase(stream, state) {
// Handle scope changes
if (stream.sol() && top(state).type == "py") {
var scopeOffset = top(state).offset;
if (stream.eatSpace()) {
var lineOffset = stream.indentation();
if (lineOffset > scopeOffset)
pushScope(stream, state, "py");
else if (lineOffset < scopeOffset && dedent(stream, state))
state.errorToken = true;
return null;
} else {
var style = tokenBaseInner(stream, state);
if (scopeOffset > 0 && dedent(stream, state))
style += " " + ERRORCLASS;
return style;
}
}
return tokenBaseInner(stream, state);
}
function tokenBaseInner(stream, state) {
if (stream.eatSpace()) return null;
var ch = stream.peek();
// Handle Comments
if (ch == "#") {
stream.skipToEnd();
return "comment";
}
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
var floatLiteral = false;
// Floats
if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
if (stream.match(/^\.\d+/)) { floatLiteral = true; }
if (floatLiteral) {
// Float literals may be "imaginary"
stream.eat(/J/i);
return "number";
}
// Integers
var intLiteral = false;
// Hex
if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
// Binary
if (stream.match(/^0b[01]+/i)) intLiteral = true;
// Octal
if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
// Decimal
if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
// Decimal literals may be "imaginary"
stream.eat(/J/i);
// TODO - Can you have imaginary longs?
intLiteral = true;
}
// Zero by itself with no other piece of number.
if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
if (intLiteral) {
// Integer literals may be "long"
stream.eat(/L/i);
return "number";
}
}
// Handle Strings
if (stream.match(stringPrefixes)) {
state.tokenize = tokenStringFactory(stream.current());
return state.tokenize(stream, state);
}
// Handle operators and Delimiters
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
return null;
if (stream.match(doubleOperators)
|| stream.match(singleOperators)
|| stream.match(wordOperators))
return "operator";
if (stream.match(singleDelimiters))
return null;
if (stream.match(keywords))
return "keyword";
if (stream.match(builtins))
return "builtin";
if (stream.match(/^(self|cls)\b/))
return "variable-2";
if (stream.match(identifiers)) {
if (state.lastToken == "def" || state.lastToken == "class")
return "def";
return "variable";
}
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
function tokenStringFactory(delimiter) {
while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
delimiter = delimiter.substr(1);
var singleline = delimiter.length == 1;
var OUTCLASS = "string";
function tokenString(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\\]/);
if (stream.eat("\\")) {
stream.next();
if (singleline && stream.eol())
return OUTCLASS;
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
return OUTCLASS;
} else {
stream.eat(/['"]/);
}
}
if (singleline) {
if (parserConf.singleLineStringErrors)
return ERRORCLASS;
else
state.tokenize = tokenBase;
}
return OUTCLASS;
}
tokenString.isString = true;
return tokenString;
}
function pushScope(stream, state, type) {
var offset = 0, align = null;
if (type == "py") {
while (top(state).type != "py")
state.scopes.pop();
}
offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent);
if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
align = stream.column() + 1;
state.scopes.push({offset: offset, type: type, align: align});
}
function dedent(stream, state) {
var indented = stream.indentation();
while (top(state).offset > indented) {
if (top(state).type != "py") return true;
state.scopes.pop();
}
return top(state).offset != indented;
}
function tokenLexer(stream, state) {
var style = state.tokenize(stream, state);
var current = stream.current();
// Handle '.' connected identifiers
if (current == ".") {
style = stream.match(identifiers, false) ? null : ERRORCLASS;
if (style == null && state.lastStyle == "meta") {
// Apply 'meta' style to '.' connected identifiers when
// appropriate.
style = "meta";
}
return style;
}
// Handle decorators
if (current == "@")
return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
if ((style == "variable" || style == "builtin")
&& state.lastStyle == "meta")
style = "meta";
// Handle scope changes.
if (current == "pass" || current == "return")
state.dedent += 1;
if (current == "lambda") state.lambda = true;
if (current == ":" && !state.lambda && top(state).type == "py")
pushScope(stream, state, "py");
var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
if (delimiter_index != -1)
pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
delimiter_index = "])}".indexOf(current);
if (delimiter_index != -1) {
if (top(state).type == current) state.scopes.pop();
else return ERRORCLASS;
}
if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
if (state.scopes.length > 1) state.scopes.pop();
state.dedent -= 1;
}
return style;
}
var external = {
startState: function(basecolumn) {
return {
tokenize: tokenBase,
scopes: [{offset: basecolumn || 0, type: "py", align: null}],
lastStyle: null,
lastToken: null,
lambda: false,
dedent: 0
};
},
token: function(stream, state) {
var addErr = state.errorToken;
if (addErr) state.errorToken = false;
var style = tokenLexer(stream, state);
state.lastStyle = style;
var current = stream.current();
if (current && style)
state.lastToken = current;
if (stream.eol() && state.lambda)
state.lambda = false;
return addErr ? style + " " + ERRORCLASS : style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase)
return state.tokenize.isString ? CodeMirror.Pass : 0;
var scope = top(state);
var closing = textAfter && textAfter.charAt(0) == scope.type;
if (scope.align != null)
return scope.align - (closing ? 1 : 0);
else if (closing && state.scopes.length > 1)
return state.scopes[state.scopes.length - 2].offset;
else
return scope.offset;
},
lineComment: "#",
fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-python", "python");
var words = function(str) { return str.split(" "); };
CodeMirror.defineMIME("text/x-cython", {
name: "python",
extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
"extern gil include nogil property public"+
"readonly struct union DEF IF ELIF ELSE")
});
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 2 2 2 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode('shell', function() {
var words = {};
function define(style, string) {
var split = string.split(' ');
for(var i = 0; i < split.length; i++) {
words[split[i]] = style;
}
};
// Atoms
define('atom', 'true false');
// Keywords
define('keyword', 'if then do else elif while until for in esac fi fin ' +
'fil done exit set unset export function');
// Commands
define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
'touch vi vim wall wc wget who write yes zsh');
function tokenBase(stream, state) {
if (stream.eatSpace()) return null;
var sol = stream.sol();
var ch = stream.next();
if (ch === '\\') {
stream.next();
return null;
}
if (ch === '\'' || ch === '"' || ch === '`') {
state.tokens.unshift(tokenString(ch));
return tokenize(stream, state);
}
if (ch === '#') {
if (sol && stream.eat('!')) {
stream.skipToEnd();
return 'meta'; // 'comment'?
}
stream.skipToEnd();
return 'comment';
}
if (ch === '$') {
state.tokens.unshift(tokenDollar);
return tokenize(stream, state);
}
if (ch === '+' || ch === '=') {
return 'operator';
}
if (ch === '-') {
stream.eat('-');
stream.eatWhile(/\w/);
return 'attribute';
}
if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
if(stream.eol() || !/\w/.test(stream.peek())) {
return 'number';
}
}
stream.eatWhile(/[\w-]/);
var cur = stream.current();
if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
return words.hasOwnProperty(cur) ? words[cur] : null;
}
function tokenString(quote) {
return function(stream, state) {
var next, end = false, escaped = false;
while ((next = stream.next()) != null) {
if (next === quote && !escaped) {
end = true;
break;
}
if (next === '$' && !escaped && quote !== '\'') {
escaped = true;
stream.backUp(1);
state.tokens.unshift(tokenDollar);
break;
}
escaped = !escaped && next === '\\';
}
if (end || !escaped) {
state.tokens.shift();
}
return (quote === '`' || quote === ')' ? 'quote' : 'string');
};
};
var tokenDollar = function(stream, state) {
if (state.tokens.length > 1) stream.eat('$');
var ch = stream.next(), hungry = /\w/;
if (ch === '{') hungry = /[^}]/;
if (ch === '(') {
state.tokens[0] = tokenString(')');
return tokenize(stream, state);
}
if (!/\d/.test(ch)) {
stream.eatWhile(hungry);
stream.eat('}');
}
state.tokens.shift();
return 'def';
};
function tokenize(stream, state) {
return (state.tokens[0] || tokenBase) (stream, state);
};
return {
startState: function() {return {tokens:[]};},
token: function(stream, state) {
return tokenize(stream, state);
}
};
});
CodeMirror.defineMIME('text/x-sh', 'shell');
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB
(function(mod) {
Eif (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("stylus", function(config) {
var indentUnit = config.indentUnit,
tagKeywords = keySet(tagKeywords_),
tagVariablesRegexp = /^(a|b|i|s|col|em)$/i,
propertyKeywords = keySet(propertyKeywords_),
nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_),
valueKeywords = keySet(valueKeywords_),
colorKeywords = keySet(colorKeywords_),
documentTypes = keySet(documentTypes_),
documentTypesRegexp = wordRegexp(documentTypes_),
mediaFeatures = keySet(mediaFeatures_),
mediaTypes = keySet(mediaTypes_),
fontProperties = keySet(fontProperties_),
operatorsRegexp = /^\s*([.]{2,3}|&&|\|\||\*\*|[?!=:]?=|[-+*\/%<>]=?|\?:|\~)/,
wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_),
blockKeywords = keySet(blockKeywords_),
vendorPrefixesRegexp = new RegExp(/^\-(moz|ms|o|webkit)-/i),
commonAtoms = keySet(commonAtoms_),
firstWordMatch = "",
states = {},
ch,
style,
type,
override;
/**
* Tokenizers
*/
function tokenBase(stream, state) {
firstWordMatch = stream.string.match(/(^[\w-]+\s*=\s*$)|(^\s*[\w-]+\s*=\s*[\w-])|(^\s*(\.|#|@|\$|\&|\[|\d|\+|::?|\{|\>|~|\/)?\s*[\w-]*([a-z0-9-]|\*|\/\*)(\(|,)?)/);
state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(/^\s*/, "") : "";
state.context.line.indent = stream.indentation();
ch = stream.peek();
// Line comment
if (stream.match("//")) {
stream.skipToEnd();
return ["comment", "comment"];
}
// Block comment
if (stream.match("/*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
// String
if (ch == "\"" || ch == "'") {
stream.next();
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
// Def
if (ch == "@") {
stream.next();
stream.eatWhile(/[\w\\-]/);
return ["def", stream.current()];
}
// ID selector or Hex color
if (ch == "#") {
stream.next();
// Hex color
if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) {
return ["atom", "atom"];
}
// ID selector
if (stream.match(/^[a-z][\w-]*/i)) {
return ["builtin", "hash"];
}
}
// Vendor prefixes
if (stream.match(vendorPrefixesRegexp)) {
return ["meta", "vendor-prefixes"];
}
// Numbers
if (stream.match(/^-?[0-9]?\.?[0-9]/)) {
stream.eatWhile(/[a-z%]/i);
return ["number", "unit"];
}
// !important|optional
if (ch == "!") {
stream.next();
return [stream.match(/^(important|optional)/i) ? "keyword": "operator", "important"];
}
// Class
if (ch == "." && stream.match(/^\.[a-z][\w-]*/i)) {
return ["qualifier", "qualifier"];
}
// url url-prefix domain regexp
if (stream.match(documentTypesRegexp)) {
if (stream.peek() == "(") state.tokenize = tokenParenthesized;
return ["property", "word"];
}
// Mixins / Functions
if (stream.match(/^[a-z][\w-]*\(/i)) {
stream.backUp(1);
return ["keyword", "mixin"];
}
// Block mixins
if (stream.match(/^(\+|-)[a-z][\w-]*\(/i)) {
stream.backUp(1);
return ["keyword", "block-mixin"];
}
// Parent Reference BEM naming
if (stream.string.match(/^\s*&/) && stream.match(/^[-_]+[a-z][\w-]*/)) {
return ["qualifier", "qualifier"];
}
// / Root Reference & Parent Reference
if (stream.match(/^(\/|&)(-|_|:|\.|#|[a-z])/)) {
stream.backUp(1);
return ["variable-3", "reference"];
}
if (stream.match(/^&{1}\s*$/)) {
return ["variable-3", "reference"];
}
// Word operator
if (stream.match(wordOperatorKeywordsRegexp)) {
return ["operator", "operator"];
}
// Word
if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) {
// Variable
if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
if (!wordIsTag(stream.current())) {
stream.match(/\./);
return ["variable-2", "variable-name"];
}
}
return ["variable-2", "word"];
}
// Operators
if (stream.match(operatorsRegexp)) {
return ["operator", stream.current()];
}
// Delimiters
if (/[:;,{}\[\]\(\)]/.test(ch)) {
stream.next();
return [null, ch];
}
// Non-detected items
stream.next();
return [null, null];
}
/**
* Token comment
*/
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
/**
* Token string
*/
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
if (quote == ")") stream.backUp(1);
break;
}
escaped = !escaped && ch == "\\";
}
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
return ["string", "string"];
};
}
/**
* Token parenthesized
*/
function tokenParenthesized(stream, state) {
stream.next(); // Must be "("
if (!stream.match(/\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
return [null, "("];
}
/**
* Context management
*/
function Context(type, indent, prev, line) {
this.type = type;
this.indent = indent;
this.prev = prev;
this.line = line || {firstWord: "", indent: 0};
}
function pushContext(state, stream, type, indent) {
indent = indent >= 0 ? indent : indentUnit;
state.context = new Context(type, stream.indentation() + indent, state.context);
return type;
}
function popContext(state, currentIndent) {
var contextIndent = state.context.indent - indentUnit;
currentIndent = currentIndent || false;
state.context = state.context.prev;
if (currentIndent) state.context.indent = contextIndent;
return state.context.type;
}
function pass(type, stream, state) {
return states[state.context.type](type, stream, state);
}
function popAndPass(type, stream, state, n) {
for (var i = n || 1; i > 0; i--)
state.context = state.context.prev;
return pass(type, stream, state);
}
/**
* Parser
*/
function wordIsTag(word) {
return word.toLowerCase() in tagKeywords;
}
function wordIsProperty(word) {
word = word.toLowerCase();
return word in propertyKeywords || word in fontProperties;
}
function wordIsBlock(word) {
return word.toLowerCase() in blockKeywords;
}
function wordIsVendorPrefix(word) {
return word.toLowerCase().match(vendorPrefixesRegexp);
}
function wordAsValue(word) {
var wordLC = word.toLowerCase();
var override = "variable-2";
if (wordIsTag(word)) override = "tag";
else if (wordIsBlock(word)) override = "block-keyword";
else if (wordIsProperty(word)) override = "property";
else if (wordLC in valueKeywords || wordLC in commonAtoms) override = "atom";
else if (wordLC == "return" || wordLC in colorKeywords) override = "keyword";
// Font family
else if (word.match(/^[A-Z]/)) override = "string";
return override;
}
function typeIsBlock(type, stream) {
return ((endOfLine(stream) && (type == "{" || type == "]" || type == "hash" || type == "qualifier")) || type == "block-mixin");
}
function typeIsInterpolation(type, stream) {
return type == "{" && stream.match(/^\s*\$?[\w-]+/i, false);
}
function typeIsPseudo(type, stream) {
return type == ":" && stream.match(/^[a-z-]+/, false);
}
function startOfLine(stream) {
return stream.sol() || stream.string.match(new RegExp("^\\s*" + escapeRegExp(stream.current())));
}
function endOfLine(stream) {
return stream.eol() || stream.match(/^\s*$/, false);
}
function firstWordOfLine(line) {
var re = /^\s*[-_]*[a-z0-9]+[\w-]*/i;
var result = typeof line == "string" ? line.match(re) : line.string.match(re);
return result ? result[0].replace(/^\s*/, "") : "";
}
/**
* Block
*/
states.block = function(type, stream, state) {
if ((type == "comment" && startOfLine(stream)) ||
(type == "," && endOfLine(stream)) ||
type == "mixin") {
return pushContext(state, stream, "block", 0);
}
if (typeIsInterpolation(type, stream)) {
return pushContext(state, stream, "interpolation");
}
if (endOfLine(stream) && type == "]") {
if (!/^\s*(\.|#|:|\[|\*|&)/.test(stream.string) && !wordIsTag(firstWordOfLine(stream))) {
return pushContext(state, stream, "block", 0);
}
}
if (typeIsBlock(type, stream, state)) {
return pushContext(state, stream, "block");
}
if (type == "}" && endOfLine(stream)) {
return pushContext(state, stream, "block", 0);
}
if (type == "variable-name") {
if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstWordOfLine(stream))) {
return pushContext(state, stream, "variableName");
}
else {
return pushContext(state, stream, "variableName", 0);
}
}
if (type == "=") {
if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) {
return pushContext(state, stream, "block", 0);
}
return pushContext(state, stream, "block");
}
if (type == "*") {
if (endOfLine(stream) || stream.match(/\s*(,|\.|#|\[|:|{)/,false)) {
override = "tag";
return pushContext(state, stream, "block");
}
}
if (typeIsPseudo(type, stream)) {
return pushContext(state, stream, "pseudo");
}
if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
}
if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
return pushContext(state, stream, "keyframes");
}
if (/@extends?/.test(type)) {
return pushContext(state, stream, "extend", 0);
}
if (type && type.charAt(0) == "@") {
// Property Lookup
if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1))) {
override = "variable-2";
return "block";
}
if (/(@import|@require|@charset)/.test(type)) {
return pushContext(state, stream, "block", 0);
}
return pushContext(state, stream, "block");
}
if (type == "reference" && endOfLine(stream)) {
return pushContext(state, stream, "block");
}
if (type == "(") {
return pushContext(state, stream, "parens");
}
if (type == "vendor-prefixes") {
return pushContext(state, stream, "vendorPrefixes");
}
if (type == "word") {
var word = stream.current();
override = wordAsValue(word);
if (override == "property") {
if (startOfLine(stream)) {
return pushContext(state, stream, "block", 0);
} else {
override = "atom";
return "block";
}
}
if (override == "tag") {
// tag is a css value
if (/embed|menu|pre|progress|sub|table/.test(word)) {
if (wordIsProperty(firstWordOfLine(stream))) {
override = "atom";
return "block";
}
}
// tag is an attribute
if (stream.string.match(new RegExp("\\[\\s*" + word + "|" + word +"\\s*\\]"))) {
override = "atom";
return "block";
}
// tag is a variable
if (tagVariablesRegexp.test(word)) {
if ((startOfLine(stream) && stream.string.match(/=/)) ||
(!startOfLine(stream) &&
!stream.string.match(/^(\s*\.|#|\&|\[|\/|>|\*)/) &&
!wordIsTag(firstWordOfLine(stream)))) {
override = "variable-2";
if (wordIsBlock(firstWordOfLine(stream))) return "block";
return pushContext(state, stream, "block", 0);
}
}
if (endOfLine(stream)) return pushContext(state, stream, "block");
}
if (override == "block-keyword") {
override = "keyword";
// Postfix conditionals
if (stream.current(/(if|unless)/) && !startOfLine(stream)) {
return "block";
}
return pushContext(state, stream, "block");
}
if (word == "return") return pushContext(state, stream, "block", 0);
// Placeholder selector
if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/)) {
return pushContext(state, stream, "block");
}
}
return state.context.type;
};
/**
* Parens
*/
states.parens = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "parens");
if (type == ")") {
if (state.context.prev.type == "parens") {
return popContext(state);
}
if ((stream.string.match(/^[a-z][\w-]*\(/i) && endOfLine(stream)) ||
wordIsBlock(firstWordOfLine(stream)) ||
/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(firstWordOfLine(stream)) ||
(!stream.string.match(/^-?[a-z][\w-\.\[\]\'\"]*\s*=/) &&
wordIsTag(firstWordOfLine(stream)))) {
return pushContext(state, stream, "block");
}
if (stream.string.match(/^[\$-]?[a-z][\w-\.\[\]\'\"]*\s*=/) ||
stream.string.match(/^\s*(\(|\)|[0-9])/) ||
stream.string.match(/^\s+[a-z][\w-]*\(/i) ||
stream.string.match(/^\s+[\$-]?[a-z]/i)) {
return pushContext(state, stream, "block", 0);
}
if (endOfLine(stream)) return pushContext(state, stream, "block");
else return pushContext(state, stream, "block", 0);
}
if (type && type.charAt(0) == "@" && wordIsProperty(stream.current().slice(1))) {
override = "variable-2";
}
if (type == "word") {
var word = stream.current();
override = wordAsValue(word);
if (override == "tag" && tagVariablesRegexp.test(word)) {
override = "variable-2";
}
if (override == "property" || word == "to") override = "atom";
}
if (type == "variable-name") {
return pushContext(state, stream, "variableName");
}
if (typeIsPseudo(type, stream)) {
return pushContext(state, stream, "pseudo");
}
return state.context.type;
};
/**
* Vendor prefixes
*/
states.vendorPrefixes = function(type, stream, state) {
if (type == "word") {
override = "property";
return pushContext(state, stream, "block", 0);
}
return popContext(state);
};
/**
* Pseudo
*/
states.pseudo = function(type, stream, state) {
if (!wordIsProperty(firstWordOfLine(stream.string))) {
stream.match(/^[a-z-]+/);
override = "variable-3";
if (endOfLine(stream)) return pushContext(state, stream, "block");
return popContext(state);
}
return popAndPass(type, stream, state);
};
/**
* atBlock
*/
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
if (typeIsBlock(type, stream, state)) {
return pushContext(state, stream, "block");
}
if (typeIsInterpolation(type, stream)) {
return pushContext(state, stream, "interpolation");
}
if (type == "word") {
var word = stream.current().toLowerCase();
if (/^(only|not|and|or)$/.test(word))
override = "keyword";
else if (documentTypes.hasOwnProperty(word))
override = "tag";
else if (mediaTypes.hasOwnProperty(word))
override = "attribute";
else if (mediaFeatures.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2";
else override = wordAsValue(stream.current());
if (override == "tag" && endOfLine(stream)) {
return pushContext(state, stream, "block");
}
}
if (type == "operator" && /^(not|and|or)$/.test(stream.current())) {
override = "keyword";
}
return state.context.type;
};
states.atBlock_parens = function(type, stream, state) {
if (type == "{" || type == "}") return state.context.type;
if (type == ")") {
if (endOfLine(stream)) return pushContext(state, stream, "block");
else return pushContext(state, stream, "atBlock");
}
if (type == "word") {
var word = stream.current().toLowerCase();
override = wordAsValue(word);
if (/^(max|min)/.test(word)) override = "property";
if (override == "tag") {
tagVariablesRegexp.test(word) ? override = "variable-2" : override = "atom";
}
return state.context.type;
}
return states.atBlock(type, stream, state);
};
/**
* Keyframes
*/
states.keyframes = function(type, stream, state) {
if (stream.indentation() == "0" && ((type == "}" && startOfLine(stream)) || type == "]" || type == "hash"
|| type == "qualifier" || wordIsTag(stream.current()))) {
return popAndPass(type, stream, state);
}
if (type == "{") return pushContext(state, stream, "keyframes");
if (type == "}") {
if (startOfLine(stream)) return popContext(state, true);
else return pushContext(state, stream, "keyframes");
}
if (type == "unit" && /^[0-9]+\%$/.test(stream.current())) {
return pushContext(state, stream, "keyframes");
}
if (type == "word") {
override = wordAsValue(stream.current());
if (override == "block-keyword") {
override = "keyword";
return pushContext(state, stream, "keyframes");
}
}
if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
}
if (type == "mixin") {
return pushContext(state, stream, "block", 0);
}
return state.context.type;
};
/**
* Interpolation
*/
states.interpolation = function(type, stream, state) {
if (type == "{") popContext(state) && pushContext(state, stream, "block");
if (type == "}") {
if (stream.string.match(/^\s*(\.|#|:|\[|\*|&|>|~|\+|\/)/i) ||
(stream.string.match(/^\s*[a-z]/i) && wordIsTag(firstWordOfLine(stream)))) {
return pushContext(state, stream, "block");
}
if (!stream.string.match(/^(\{|\s*\&)/) ||
stream.match(/\s*[\w-]/,false)) {
return pushContext(state, stream, "block", 0);
}
return pushContext(state, stream, "block");
}
if (type == "variable-name") {
return pushContext(state, stream, "variableName", 0);
}
if (type == "word") {
override = wordAsValue(stream.current());
if (override == "tag") override = "atom";
}
return state.context.type;
};
/**
* Extend/s
*/
states.extend = function(type, stream, state) {
if (type == "[" || type == "=") return "extend";
if (type == "]") return popContext(state);
if (type == "word") {
override = wordAsValue(stream.current());
return "extend";
}
return popContext(state);
};
/**
* Variable name
*/
states.variableName = function(type, stream, state) {
if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) {
if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2";
return "variableName";
}
return popAndPass(type, stream, state);
};
return {
startState: function(base) {
return {
tokenize: null,
state: "block",
context: new Context("block", base || 0, null)
};
},
token: function(stream, state) {
if (!state.tokenize && stream.eatSpace()) return null;
style = (state.tokenize || tokenBase)(stream, state);
if (style && typeof style == "object") {
type = style[1];
style = style[0];
}
override = style;
state.state = states[state.state](type, stream, state);
return override;
},
indent: function(state, textAfter, line) {
var cx = state.context,
ch = textAfter && textAfter.charAt(0),
indent = cx.indent,
lineFirstWord = firstWordOfLine(textAfter),
lineIndent = line.length - line.replace(/^\s*/, "").length,
prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : "",
prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent;
if (cx.prev &&
(ch == "}" && (cx.type == "block" || cx.type == "atBlock" || cx.type == "keyframes") ||
ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at"))) {
indent = cx.indent - indentUnit;
cx = cx.prev;
} else if (!(/(\})/.test(ch))) {
if (/@|\$|\d/.test(ch) ||
/^\{/.test(textAfter) ||
/^\s*\/(\/|\*)/.test(textAfter) ||
/^\s*\/\*/.test(prevLineFirstWord) ||
/^\s*[\w-\.\[\]\'\"]+\s*(\?|:|\+)?=/i.test(textAfter) ||
/^(\+|-)?[a-z][\w-]*\(/i.test(textAfter) ||
/^return/.test(textAfter) ||
wordIsBlock(lineFirstWord)) {
indent = lineIndent;
} else if (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(ch) || wordIsTag(lineFirstWord)) {
if (/\,\s*$/.test(prevLineFirstWord)) {
indent = prevLineIndent;
} else if (/^\s+/.test(line) && (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(prevLineFirstWord) || wordIsTag(prevLineFirstWord))) {
indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
} else {
indent = lineIndent;
}
} else if (!/,\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) || wordIsProperty(lineFirstWord))) {
if (wordIsBlock(prevLineFirstWord)) {
indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
} else if (/^\{/.test(prevLineFirstWord)) {
indent = lineIndent <= prevLineIndent ? lineIndent : prevLineIndent + indentUnit;
} else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(prevLineFirstWord)) {
indent = lineIndent >= prevLineIndent ? prevLineIndent : lineIndent;
} else if (/^(\.|#|:|\[|\*|&|@|\+|\-|>|~|\/)/.test(prevLineFirstWord) ||
/=\s*$/.test(prevLineFirstWord) ||
wordIsTag(prevLineFirstWord) ||
/^\$[\w-\.\[\]\'\"]/.test(prevLineFirstWord)) {
indent = prevLineIndent + indentUnit;
} else {
indent = lineIndent;
}
}
}
return indent;
},
electricChars: "}",
lineComment: "//",
fold: "indent"
};
});
// developer.mozilla.org/en-US/docs/Web/HTML/Element
var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"];
// github.com/codemirror/CodeMirror/blob/master/mode/css/css.js
var documentTypes_ = ["domain", "regexp", "url", "url-prefix"];
var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"];
var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"];
var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"];
var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around"];
var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
blockKeywords_ = ["for","if","else","unless", "from", "to"],
commonAtoms_ = ["null","true","false","href","title","type","not-allowed","readonly","disabled"],
commonDef_ = ["@font-face", "@keyframes", "@media", "@viewport", "@page", "@host", "@supports", "@block", "@css"];
var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_,
propertyKeywords_,nonStandardPropertyKeywords_,
colorKeywords_,valueKeywords_,fontProperties_,
wordOperatorKeywords_,blockKeywords_,
commonAtoms_,commonDef_);
function wordRegexp(words) {
words = words.sort(function(a,b){return b > a;});
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) keys[array[i]] = true;
return keys;
}
function escapeRegExp(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
CodeMirror.registerHelper("hintWords", "stylus", hintWords);
CodeMirror.defineMIME("text/x-styl", "stylus");
});
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Color.js | 2.13% | (6 / 282) | 0% | (0 / 134) | 0% | (0 / 34) | 2.13% | (6 / 282) | |
| Console.js | 4% | (1 / 25) | 0% | (0 / 8) | 0% | (0 / 12) | 4% | (1 / 25) | |
| ContentProvider.js | 6.67% | (1 / 15) | 0% | (0 / 2) | 0% | (0 / 7) | 6.67% | (1 / 15) | |
| Geometry.js | 3.33% | (5 / 150) | 0% | (0 / 58) | 0% | (0 / 38) | 3.33% | (5 / 150) | |
| ModuleExtensionInterfaces.js | 11.11% | (3 / 27) | 0% | (0 / 4) | 0% | (0 / 15) | 11.11% | (3 / 27) | |
| NotificationService.js | 25% | (1 / 4) | 100% | (0 / 0) | 0% | (0 / 1) | 25% | (1 / 4) | |
| Object.js | 1.82% | (1 / 55) | 0% | (0 / 28) | 0% | (0 / 18) | 1.82% | (1 / 55) | |
| OutputStream.js | 14.29% | (1 / 7) | 100% | (0 / 0) | 0% | (0 / 7) | 14.29% | (1 / 7) | |
| ParsedURL.js | 0.65% | (1 / 155) | 0% | (0 / 95) | 0% | (0 / 14) | 0.65% | (1 / 155) | |
| Progress.js | 1.75% | (1 / 57) | 0% | (0 / 24) | 0% | (0 / 25) | 1.75% | (1 / 57) | |
| ResourceType.js | 2.7% | (1 / 37) | 0% | (0 / 17) | 0% | (0 / 15) | 2.7% | (1 / 37) | |
| SegmentedRange.js | 2.22% | (1 / 45) | 0% | (0 / 24) | 0% | (0 / 7) | 2.33% | (1 / 43) | |
| Settings.js | 0.69% | (2 / 290) | 0% | (0 / 118) | 0% | (0 / 58) | 0.69% | (2 / 290) | |
| StaticContentProvider.js | 15.38% | (2 / 13) | 0% | (0 / 2) | 0% | (0 / 7) | 15.38% | (2 / 13) | |
| Text.js | 2.7% | (1 / 37) | 0% | (0 / 14) | 0% | (0 / 14) | 2.7% | (1 / 37) | |
| TextDictionary.js | 5.26% | (1 / 19) | 0% | (0 / 10) | 0% | (0 / 7) | 5.26% | (1 / 19) | |
| TextRange.js | 1.87% | (2 / 107) | 0% | (0 / 63) | 0% | (0 / 28) | 1.87% | (2 / 107) | |
| TextUtils.js | 1.37% | (1 / 73) | 0% | (0 / 50) | 0% | (0 / 20) | 1.37% | (1 / 73) | |
| Throttler.js | 3.13% | (1 / 32) | 0% | (0 / 20) | 0% | (0 / 8) | 3.13% | (1 / 32) | |
| UIString.js | 4.35% | (1 / 23) | 0% | (0 / 4) | 0% | (0 / 8) | 4.55% | (1 / 22) | |
| WebInspector.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| WorkerRuntime.js | 21.95% | (18 / 82) | 0% | (0 / 18) | 0% | (0 / 26) | 21.95% | (18 / 82) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | 2 1 1 1 1 1 | /*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @param {!Array.<number>} rgba
* @param {!WebInspector.Color.Format} format
* @param {string=} originalText
* @constructor
*/
WebInspector.Color = function(rgba, format, originalText)
{
this._rgba = rgba;
this._originalText = originalText || null;
this._originalTextIsValid = !!this._originalText;
this._format = format;
if (typeof this._rgba[3] === "undefined")
this._rgba[3] = 1;
for (var i = 0; i < 4; ++i) {
if (this._rgba[i] < 0) {
this._rgba[i] = 0;
this._originalTextIsValid = false;
}
if (this._rgba[i] > 1) {
this._rgba[i] = 1;
this._originalTextIsValid = false;
}
}
}
/**
* @enum {string}
*/
WebInspector.Color.Format = {
Original: "original",
Nickname: "nickname",
HEX: "hex",
ShortHEX: "shorthex",
RGB: "rgb",
RGBA: "rgba",
HSL: "hsl",
HSLA: "hsla"
}
/**
* @param {string} text
* @return {?WebInspector.Color}
*/
WebInspector.Color.parse = function(text)
{
// Simple - #hex, rgb(), nickname, hsl()
var value = text.toLowerCase().replace(/\s+/g, "");
var simple = /^(?:#([0-9a-f]{3}|[0-9a-f]{6})|rgb\(((?:-?\d+%?,){2}-?\d+%?)\)|(\w+)|hsl\((-?\d+\.?\d*(?:,-?\d+\.?\d*%){2})\))$/i;
var match = value.match(simple);
if (match) {
if (match[1]) { // hex
var hex = match[1].toLowerCase();
var format;
if (hex.length === 3) {
format = WebInspector.Color.Format.ShortHEX;
hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
} else
format = WebInspector.Color.Format.HEX;
var r = parseInt(hex.substring(0,2), 16);
var g = parseInt(hex.substring(2,4), 16);
var b = parseInt(hex.substring(4,6), 16);
return new WebInspector.Color([r / 255, g / 255, b / 255, 1], format, text);
}
if (match[2]) { // rgb
var rgbString = match[2].split(/\s*,\s*/);
var rgba = [ WebInspector.Color._parseRgbNumeric(rgbString[0]),
WebInspector.Color._parseRgbNumeric(rgbString[1]),
WebInspector.Color._parseRgbNumeric(rgbString[2]), 1 ];
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGB, text);
}
if (match[3]) { // nickname
var nickname = match[3].toLowerCase();
if (nickname in WebInspector.Color.Nicknames) {
var rgba = WebInspector.Color.Nicknames[nickname];
var color = WebInspector.Color.fromRGBA(rgba);
color._format = WebInspector.Color.Format.Nickname;
color._originalText = text;
return color;
}
return null;
}
if (match[4]) { // hsl
var hslString = match[4].replace(/%/g, "").split(/\s*,\s*/);
var hsla = [ WebInspector.Color._parseHueNumeric(hslString[0]),
WebInspector.Color._parseSatLightNumeric(hslString[1]),
WebInspector.Color._parseSatLightNumeric(hslString[2]), 1 ];
var rgba = [];
WebInspector.Color.hsl2rgb(hsla, rgba);
return new WebInspector.Color(rgba, WebInspector.Color.Format.HSL, text);
}
return null;
}
// Advanced - rgba(), hsla()
var advanced = /^(?:rgba\(((?:-?\d+%?,){3}-?(?:\d+|\d*\.\d+))\)|hsla\((-?(?:\d+|\d*\.\d+)(?:,-?(?:\d+|\d*\.\d+)*%){2},-?(?:\d+|\d*\.\d+))\))$/;
match = value.match(advanced);
if (match) {
if (match[1]) { // rgba
var rgbaString = match[1].split(/\s*,\s*/);
var rgba = [ WebInspector.Color._parseRgbNumeric(rgbaString[0]),
WebInspector.Color._parseRgbNumeric(rgbaString[1]),
WebInspector.Color._parseRgbNumeric(rgbaString[2]),
WebInspector.Color._parseAlphaNumeric(rgbaString[3]) ];
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGBA, text);
}
if (match[2]) { // hsla
var hslaString = match[2].replace(/%/g, "").split(/\s*,\s*/);
var hsla = [ WebInspector.Color._parseHueNumeric(hslaString[0]),
WebInspector.Color._parseSatLightNumeric(hslaString[1]),
WebInspector.Color._parseSatLightNumeric(hslaString[2]),
WebInspector.Color._parseAlphaNumeric(hslaString[3]) ];
var rgba = [];
WebInspector.Color.hsl2rgb(hsla, rgba);
return new WebInspector.Color(rgba, WebInspector.Color.Format.HSLA, text);
}
}
return null;
}
/**
* @param {!Array.<number>} rgba
* @return {!WebInspector.Color}
*/
WebInspector.Color.fromRGBA = function(rgba)
{
return new WebInspector.Color([rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]], WebInspector.Color.Format.RGBA);
}
/**
* @param {!Array.<number>} hsva
* @return {!WebInspector.Color}
*/
WebInspector.Color.fromHSVA = function(hsva)
{
var rgba = [];
WebInspector.Color.hsva2rgba(hsva, rgba);
return new WebInspector.Color(rgba, WebInspector.Color.Format.HSLA);
}
WebInspector.Color.prototype = {
/**
* @return {!WebInspector.Color.Format}
*/
format: function()
{
return this._format;
},
/**
* @return {!Array.<number>} HSLA with components within [0..1]
*/
hsla: function()
{
if (this._hsla)
return this._hsla;
var r = this._rgba[0];
var g = this._rgba[1];
var b = this._rgba[2];
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var add = max + min;
if (min === max)
var h = 0;
else if (r === max)
var h = ((1/6 * (g - b) / diff) + 1) % 1;
else if (g === max)
var h = (1/6 * (b - r) / diff) + 1/3;
else
var h = (1/6 * (r - g) / diff) + 2/3;
var l = 0.5 * add;
if (l === 0)
var s = 0;
else if (l === 1)
var s = 0;
else if (l <= 0.5)
var s = diff / add;
else
var s = diff / (2 - add);
this._hsla = [h, s, l, this._rgba[3]];
return this._hsla;
},
/**
* @return {!Array.<number>}
*/
canonicalHSLA: function()
{
var hsla = this.hsla();
return [Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100), hsla[3]];
},
/**
* @return {!Array.<number>} HSVA with components within [0..1]
*/
hsva: function()
{
var hsla = this.hsla();
var h = hsla[0];
var s = hsla[1];
var l = hsla[2];
s *= l < 0.5 ? l : 1 - l;
return [h, s !== 0 ? 2 * s / (l + s) : 0, (l + s), hsla[3]];
},
/**
* @return {boolean}
*/
hasAlpha: function()
{
return this._rgba[3] !== 1;
},
/**
* @return {boolean}
*/
canBeShortHex: function()
{
if (this.hasAlpha())
return false;
for (var i = 0; i < 3; ++i) {
var c = Math.round(this._rgba[i] * 255);
if (c % 17)
return false;
}
return true;
},
/**
* @return {?string}
*/
asString: function(format)
{
if (format === this._format && this._originalTextIsValid)
return this._originalText;
if (!format)
format = this._format;
/**
* @param {number} value
* @return {number}
*/
function toRgbValue(value)
{
return Math.round(value * 255);
}
/**
* @param {number} value
* @return {string}
*/
function toHexValue(value)
{
var hex = Math.round(value * 255).toString(16);
return hex.length === 1 ? "0" + hex : hex;
}
/**
* @param {number} value
* @return {string}
*/
function toShortHexValue(value)
{
return (Math.round(value * 255) / 17).toString(16);
}
switch (format) {
case WebInspector.Color.Format.Original:
return this._originalText;
case WebInspector.Color.Format.RGB:
if (this.hasAlpha())
return null;
return String.sprintf("rgb(%d, %d, %d)", toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]));
case WebInspector.Color.Format.RGBA:
return String.sprintf("rgba(%d, %d, %d, %f)", toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]), this._rgba[3]);
case WebInspector.Color.Format.HSL:
if (this.hasAlpha())
return null;
var hsl = this.hsla();
return String.sprintf("hsl(%d, %d%, %d%)", Math.round(hsl[0] * 360), Math.round(hsl[1] * 100), Math.round(hsl[2] * 100));
case WebInspector.Color.Format.HSLA:
var hsla = this.hsla();
return String.sprintf("hsla(%d, %d%, %d%, %f)", Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100), hsla[3]);
case WebInspector.Color.Format.HEX:
if (this.hasAlpha())
return null;
return String.sprintf("#%s%s%s", toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2])).toLowerCase();;
case WebInspector.Color.Format.ShortHEX:
if (!this.canBeShortHex())
return null;
return String.sprintf("#%s%s%s", toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]), toShortHexValue(this._rgba[2])).toLowerCase();;
case WebInspector.Color.Format.Nickname:
return this.nickname();
}
return this._originalText;
},
/**
* @return {!Array<number>}
*/
rgba: function()
{
return this._rgba.slice();
},
/**
* @return {!Array.<number>}
*/
canonicalRGBA: function()
{
var rgba = new Array(4);
for (var i = 0; i < 3; ++i)
rgba[i] = Math.round(this._rgba[i] * 255);
rgba[3] = this._rgba[3];
return rgba;
},
/**
* @return {?string} nickname
*/
nickname: function()
{
if (!WebInspector.Color._rgbaToNickname) {
WebInspector.Color._rgbaToNickname = {};
for (var nickname in WebInspector.Color.Nicknames) {
var rgba = WebInspector.Color.Nicknames[nickname];
if (rgba.length !== 4)
rgba = rgba.concat(1);
WebInspector.Color._rgbaToNickname[rgba] = nickname;
}
}
return WebInspector.Color._rgbaToNickname[this.canonicalRGBA()] || null;
},
/**
* @return {!DOMAgent.RGBA}
*/
toProtocolRGBA: function()
{
var rgba = this.canonicalRGBA();
var result = { r: rgba[0], g: rgba[1], b: rgba[2] };
if (rgba[3] !== 1)
result.a = rgba[3];
return result;
},
/**
* @return {!WebInspector.Color}
*/
invert: function()
{
var rgba = [];
rgba[0] = 1 - this._rgba[0];
rgba[1] = 1 - this._rgba[1];
rgba[2] = 1 - this._rgba[2];
rgba[3] = this._rgba[3];
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGBA);
},
/**
* @param {number} alpha
* @return {!WebInspector.Color}
*/
setAlpha: function(alpha)
{
var rgba = this._rgba.slice();
rgba[3] = alpha;
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGBA);
}
}
/**
* @param {string} value
* return {number}
*/
WebInspector.Color._parseRgbNumeric = function(value)
{
var parsed = parseInt(value, 10);
if (value.indexOf("%") !== -1)
parsed /= 100;
else
parsed /= 255;
return parsed;
}
/**
* @param {string} value
* return {number}
*/
WebInspector.Color._parseHueNumeric = function(value)
{
return isNaN(value) ? 0 : (parseFloat(value) / 360) % 1;
}
/**
* @param {string} value
* return {number}
*/
WebInspector.Color._parseSatLightNumeric = function(value)
{
return Math.min(1, parseFloat(value) / 100);
}
/**
* @param {string} value
* return {number}
*/
WebInspector.Color._parseAlphaNumeric = function(value)
{
return isNaN(value) ? 0 : parseFloat(value);
}
/**
* @param {!Array.<number>} hsva
* @param {!Array.<number>} out_hsla
*/
WebInspector.Color._hsva2hsla = function(hsva, out_hsla)
{
var h = hsva[0];
var s = hsva[1];
var v = hsva[2];
var t = (2 - s) * v;
if (v === 0 || s === 0)
s = 0;
else
s *= v / (t < 1 ? t : 2 - t);
out_hsla[0] = h;
out_hsla[1] = s;
out_hsla[2] = t/2;
out_hsla[3] = hsva[3];
}
/**
* @param {!Array.<number>} hsl
* @param {!Array.<number>} out_rgb
*/
WebInspector.Color.hsl2rgb = function(hsl, out_rgb)
{
var h = hsl[0];
var s = hsl[1];
var l = hsl[2];
function hue2rgb(p, q, h)
{
if (h < 0)
h += 1;
else if (h > 1)
h -= 1;
if ((h * 6) < 1)
return p + (q - p) * h * 6;
else if ((h * 2) < 1)
return q;
else if ((h * 3) < 2)
return p + (q - p) * ((2 / 3) - h) * 6;
else
return p;
}
if (s < 0)
s = 0;
if (l <= 0.5)
var q = l * (1 + s);
else
var q = l + s - (l * s);
var p = 2 * l - q;
var tr = h + (1 / 3);
var tg = h;
var tb = h - (1 / 3);
out_rgb[0] = hue2rgb(p, q, tr);
out_rgb[1] = hue2rgb(p, q, tg);
out_rgb[2] = hue2rgb(p, q, tb);
out_rgb[3] = hsl[3];
}
/**
* @param {!Array<number>} hsva
* @param {!Array<number>} out_rgba
*/
WebInspector.Color.hsva2rgba = function(hsva, out_rgba)
{
WebInspector.Color._hsva2hsla(hsva, WebInspector.Color.hsva2rgba._tmpHSLA);
WebInspector.Color.hsl2rgb(WebInspector.Color.hsva2rgba._tmpHSLA, out_rgba);
for (var i = 0; i < WebInspector.Color.hsva2rgba._tmpHSLA.length; i++)
WebInspector.Color.hsva2rgba._tmpHSLA[i] = 0;
};
/** @type {!Array<number>} */
WebInspector.Color.hsva2rgba._tmpHSLA = [0, 0, 0, 0];
/**
* Calculate the luminance of this color using the WCAG algorithm.
* See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
* @param {!Array<number>} rgba
* @return {number}
*/
WebInspector.Color.luminance = function(rgba)
{
var rSRGB = rgba[0];
var gSRGB = rgba[1];
var bSRGB = rgba[2];
var r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055)/1.055), 2.4);
var g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055)/1.055), 2.4);
var b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055)/1.055), 2.4);
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
/**
* Combine the two given color according to alpha blending.
* @param {!Array<number>} fgRGBA
* @param {!Array<number>} bgRGBA
* @param {!Array<number>} out_blended
*/
WebInspector.Color.blendColors = function(fgRGBA, bgRGBA, out_blended)
{
var alpha = fgRGBA[3];
out_blended[0] = ((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]);
out_blended[1] = ((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]);
out_blended[2] = ((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]);
out_blended[3] = alpha + (bgRGBA[3] * (1 - alpha));
}
/**
* Calculate the contrast ratio between a foreground and a background color.
* Returns the ratio to 1, for example for two two colors with a contrast ratio of 21:1, this function will return 21.
* See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
* @param {!Array<number>} fgRGBA
* @param {!Array<number>} bgRGBA
* @return {number}
*/
WebInspector.Color.calculateContrastRatio = function(fgRGBA, bgRGBA)
{
WebInspector.Color.blendColors(fgRGBA, bgRGBA, WebInspector.Color.calculateContrastRatio._blendedFg);
var fgLuminance = WebInspector.Color.luminance(WebInspector.Color.calculateContrastRatio._blendedFg);
var bgLuminance = WebInspector.Color.luminance(bgRGBA);
var contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) /
(Math.min(fgLuminance, bgLuminance) + 0.05);
for (var i = 0; i < WebInspector.Color.calculateContrastRatio._blendedFg.length; i++)
WebInspector.Color.calculateContrastRatio._blendedFg[i] = 0;
return contrastRatio;
}
WebInspector.Color.calculateContrastRatio._blendedFg = [0, 0, 0, 0];
/**
* Compute a desired luminance given a given luminance and a desired contrast
* ratio.
* @param {number} luminance The given luminance.
* @param {number} contrast The desired contrast ratio.
* @param {boolean} lighter Whether the desired luminance is lighter or darker
* than the given luminance. If no luminance can be found which meets this
* requirement, a luminance which meets the inverse requirement will be
* returned.
* @return {number} The desired luminance.
*/
WebInspector.Color.desiredLuminance = function(luminance, contrast, lighter)
{
function computeLuminance()
{
if (lighter)
return (luminance + 0.05) * contrast - 0.05;
else
return (luminance + 0.05) / contrast - 0.05;
}
var desiredLuminance = computeLuminance();
if (desiredLuminance < 0 || desiredLuminance > 1) {
lighter = !lighter;
desiredLuminance = computeLuminance();
}
return desiredLuminance;
};
WebInspector.Color.Nicknames = {
"aliceblue": [240,248,255],
"antiquewhite": [250,235,215],
"aqua": [0,255,255],
"aquamarine": [127,255,212],
"azure": [240,255,255],
"beige": [245,245,220],
"bisque": [255,228,196],
"black": [0,0,0],
"blanchedalmond": [255,235,205],
"blue": [0,0,255],
"blueviolet": [138,43,226],
"brown": [165,42,42],
"burlywood": [222,184,135],
"cadetblue": [95,158,160],
"chartreuse": [127,255,0],
"chocolate": [210,105,30],
"coral": [255,127,80],
"cornflowerblue": [100,149,237],
"cornsilk": [255,248,220],
"crimson": [237,20,61],
"cyan": [0,255,255],
"darkblue": [0,0,139],
"darkcyan": [0,139,139],
"darkgoldenrod": [184,134,11],
"darkgray": [169,169,169],
"darkgrey": [169,169,169],
"darkgreen": [0,100,0],
"darkkhaki": [189,183,107],
"darkmagenta": [139,0,139],
"darkolivegreen": [85,107,47],
"darkorange": [255,140,0],
"darkorchid": [153,50,204],
"darkred": [139,0,0],
"darksalmon": [233,150,122],
"darkseagreen": [143,188,143],
"darkslateblue": [72,61,139],
"darkslategray": [47,79,79],
"darkslategrey": [47,79,79],
"darkturquoise": [0,206,209],
"darkviolet": [148,0,211],
"deeppink": [255,20,147],
"deepskyblue": [0,191,255],
"dimgray": [105,105,105],
"dimgrey": [105,105,105],
"dodgerblue": [30,144,255],
"firebrick": [178,34,34],
"floralwhite": [255,250,240],
"forestgreen": [34,139,34],
"fuchsia": [255,0,255],
"gainsboro": [220,220,220],
"ghostwhite": [248,248,255],
"gold": [255,215,0],
"goldenrod": [218,165,32],
"gray": [128,128,128],
"grey": [128,128,128],
"green": [0,128,0],
"greenyellow": [173,255,47],
"honeydew": [240,255,240],
"hotpink": [255,105,180],
"indianred": [205,92,92],
"indigo": [75,0,130],
"ivory": [255,255,240],
"khaki": [240,230,140],
"lavender": [230,230,250],
"lavenderblush": [255,240,245],
"lawngreen": [124,252,0],
"lemonchiffon": [255,250,205],
"lightblue": [173,216,230],
"lightcoral": [240,128,128],
"lightcyan": [224,255,255],
"lightgoldenrodyellow":[250,250,210],
"lightgreen": [144,238,144],
"lightgray": [211,211,211],
"lightgrey": [211,211,211],
"lightpink": [255,182,193],
"lightsalmon": [255,160,122],
"lightseagreen": [32,178,170],
"lightskyblue": [135,206,250],
"lightslategray": [119,136,153],
"lightslategrey": [119,136,153],
"lightsteelblue": [176,196,222],
"lightyellow": [255,255,224],
"lime": [0,255,0],
"limegreen": [50,205,50],
"linen": [250,240,230],
"magenta": [255,0,255],
"maroon": [128,0,0],
"mediumaquamarine": [102,205,170],
"mediumblue": [0,0,205],
"mediumorchid": [186,85,211],
"mediumpurple": [147,112,219],
"mediumseagreen": [60,179,113],
"mediumslateblue": [123,104,238],
"mediumspringgreen": [0,250,154],
"mediumturquoise": [72,209,204],
"mediumvioletred": [199,21,133],
"midnightblue": [25,25,112],
"mintcream": [245,255,250],
"mistyrose": [255,228,225],
"moccasin": [255,228,181],
"navajowhite": [255,222,173],
"navy": [0,0,128],
"oldlace": [253,245,230],
"olive": [128,128,0],
"olivedrab": [107,142,35],
"orange": [255,165,0],
"orangered": [255,69,0],
"orchid": [218,112,214],
"palegoldenrod": [238,232,170],
"palegreen": [152,251,152],
"paleturquoise": [175,238,238],
"palevioletred": [219,112,147],
"papayawhip": [255,239,213],
"peachpuff": [255,218,185],
"peru": [205,133,63],
"pink": [255,192,203],
"plum": [221,160,221],
"powderblue": [176,224,230],
"purple": [128,0,128],
"rebeccapurple": [102,51,153],
"red": [255,0,0],
"rosybrown": [188,143,143],
"royalblue": [65,105,225],
"saddlebrown": [139,69,19],
"salmon": [250,128,114],
"sandybrown": [244,164,96],
"seagreen": [46,139,87],
"seashell": [255,245,238],
"sienna": [160,82,45],
"silver": [192,192,192],
"skyblue": [135,206,235],
"slateblue": [106,90,205],
"slategray": [112,128,144],
"slategrey": [112,128,144],
"snow": [255,250,250],
"springgreen": [0,255,127],
"steelblue": [70,130,180],
"tan": [210,180,140],
"teal": [0,128,128],
"thistle": [216,191,216],
"tomato": [255,99,71],
"turquoise": [64,224,208],
"violet": [238,130,238],
"wheat": [245,222,179],
"white": [255,255,255],
"whitesmoke": [245,245,245],
"yellow": [255,255,0],
"yellowgreen": [154,205,50],
"transparent": [0, 0, 0, 0],
};
WebInspector.Color.PageHighlight = {
Content: WebInspector.Color.fromRGBA([111, 168, 220, .66]),
ContentLight: WebInspector.Color.fromRGBA([111, 168, 220, .5]),
ContentOutline: WebInspector.Color.fromRGBA([9, 83, 148]),
Padding: WebInspector.Color.fromRGBA([147, 196, 125, .55]),
PaddingLight: WebInspector.Color.fromRGBA([147, 196, 125, .4]),
Border: WebInspector.Color.fromRGBA([255, 229, 153, .66]),
BorderLight: WebInspector.Color.fromRGBA([255, 229, 153, .5]),
Margin: WebInspector.Color.fromRGBA([246, 178, 107, .66]),
MarginLight: WebInspector.Color.fromRGBA([246, 178, 107, .5]),
EventTarget: WebInspector.Color.fromRGBA([255, 196, 196, .66]),
Shape: WebInspector.Color.fromRGBA([96, 82, 177, 0.8]),
ShapeMargin: WebInspector.Color.fromRGBA([96, 82, 127, .6])
}
/**
* @param {!WebInspector.Color} color
* @return {!WebInspector.Color.Format}
*/
WebInspector.Color.detectColorFormat = function(color)
{
const cf = WebInspector.Color.Format;
var format;
var formatSetting = WebInspector.moduleSetting("colorFormat").get();
if (formatSetting === cf.Original)
format = cf.Original;
else if (formatSetting === cf.RGB)
format = (color.hasAlpha() ? cf.RGBA : cf.RGB);
else if (formatSetting === cf.HSL)
format = (color.hasAlpha() ? cf.HSLA : cf.HSL);
else if (!color.hasAlpha())
format = (color.canBeShortHex() ? cf.ShortHEX : cf.HEX);
else
format = cf.RGBA;
return format;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.Console = function()
{
/** @type {!Array.<!WebInspector.Console.Message>} */
this._messages = [];
}
/**
* @enum {string}
*/
WebInspector.Console.Events = {
MessageAdded: "messageAdded"
}
/**
* @enum {string}
*/
WebInspector.Console.MessageLevel = {
Log: "log",
Warning: "warning",
Error: "error"
}
/**
* @constructor
* @param {string} text
* @param {!WebInspector.Console.MessageLevel} level
* @param {number} timestamp
* @param {boolean} show
*/
WebInspector.Console.Message = function(text, level, timestamp, show)
{
this.text = text;
this.level = level;
this.timestamp = (typeof timestamp === "number") ? timestamp : Date.now();
this.show = show;
}
/**
* @interface
*/
WebInspector.Console.UIDelegate = function()
{
}
WebInspector.Console.UIDelegate.prototype = {
/**
* @return {!Promise.<undefined>}
*/
showConsole: function() { }
}
WebInspector.Console.prototype = {
/**
* @param {!WebInspector.Console.UIDelegate} uiDelegate
*/
setUIDelegate: function(uiDelegate)
{
this._uiDelegate = uiDelegate;
},
/**
* @param {string} text
* @param {!WebInspector.Console.MessageLevel} level
* @param {boolean=} show
*/
addMessage: function(text, level, show)
{
var message = new WebInspector.Console.Message(text, level || WebInspector.Console.MessageLevel.Log, Date.now(), show || false);
this._messages.push(message);
this.dispatchEventToListeners(WebInspector.Console.Events.MessageAdded, message);
},
/**
* @param {string} text
*/
log: function(text)
{
this.addMessage(text, WebInspector.Console.MessageLevel.Log);
},
/**
* @param {string} text
*/
warn: function(text)
{
this.addMessage(text, WebInspector.Console.MessageLevel.Warning);
},
/**
* @param {string} text
*/
error: function(text)
{
this.addMessage(text, WebInspector.Console.MessageLevel.Error, true);
},
/**
* @return {!Array.<!WebInspector.Console.Message>}
*/
messages: function()
{
return this._messages;
},
show: function()
{
this.showPromise();
},
/**
* @return {!Promise.<undefined>}
*/
showPromise: function()
{
if (this._uiDelegate)
return this._uiDelegate.showConsole();
return Promise.reject();
},
__proto__: WebInspector.Object.prototype
}
WebInspector.console = new WebInspector.Console();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 2 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.ContentProvider = function() { } WebInspector.ContentProvider.prototype = { /** * @return {string} */ contentURL: function() { }, /** * @return {!WebInspector.ResourceType} */ contentType: function() { }, /** * @return {!Promise<?string>} */ requestContent: function() { }, /** * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback */ searchInContent: function(query, caseSensitive, isRegex, callback) { } } /** * @constructor * @param {number} lineNumber * @param {string} lineContent */ WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) { this.lineNumber = lineNumber; this.lineContent = lineContent; } /** * @param {string} content * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @return {!Array.<!WebInspector.ContentProvider.SearchMatch>} */ WebInspector.ContentProvider.performSearchInContent = function(content, query, caseSensitive, isRegex) { var regex = createSearchRegex(query, caseSensitive, isRegex); var text = new WebInspector.Text(content); var result = []; for (var i = 0; i < text.lineCount(); ++i) { var lineContent = text.lineAt(i); regex.lastIndex = 0; if (regex.exec(lineContent)) result.push(new WebInspector.ContentProvider.SearchMatch(i, lineContent)); } return result; } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | 2 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.Geometry = {};
/**
* @type {number}
*/
WebInspector.Geometry._Eps = 1e-5;
/**
* @constructor
* @param {number} x
* @param {number} y
* @param {number} z
*/
WebInspector.Geometry.Vector = function(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
WebInspector.Geometry.Vector.prototype = {
/**
* @return {number}
*/
length: function()
{
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
},
normalize: function()
{
var length = this.length();
if (length <= WebInspector.Geometry._Eps)
return;
this.x /= length;
this.y /= length;
this.z /= length;
}
}
/**
* @constructor
* @param {number} x
* @param {number} y
*/
WebInspector.Geometry.Point = function(x, y) {
this.x = x;
this.y = y;
}
WebInspector.Geometry.Point.prototype = {
/**
* @param {!WebInspector.Geometry.Point} p
* @return {number}
*/
distanceTo: function(p)
{
return Math.sqrt(Math.pow(p.x - this.x, 2) + Math.pow(p.y - this.y, 2));
},
/**
* @override
* @return {string}
*/
toString: function()
{
return Math.round(this.x * 100) / 100 + ", " + Math.round(this.y * 100) / 100;
}
}
/**
* @constructor
* @param {!WebInspector.Geometry.Point} point1
* @param {!WebInspector.Geometry.Point} point2
*/
WebInspector.Geometry.CubicBezier = function(point1, point2)
{
this.controlPoints = [point1, point2];
}
WebInspector.Geometry.CubicBezier.KeywordValues = {
"linear": "cubic-bezier(0, 0, 1, 1)",
"ease": "cubic-bezier(0.25, 0.1, 0.25, 1)",
"ease-in": "cubic-bezier(0.42, 0, 1, 1)",
"ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)",
"ease-out": "cubic-bezier(0, 0, 0.58, 1)"
}
/**
* @param {string} text
* @return {?WebInspector.Geometry.CubicBezier}
*/
WebInspector.Geometry.CubicBezier.parse = function(text)
{
var keywordValues = WebInspector.Geometry.CubicBezier.KeywordValues;
var value = text.toLowerCase().replace(/\s+/g, "");
if (Object.keys(keywordValues).indexOf(value) != -1)
return WebInspector.Geometry.CubicBezier.parse(keywordValues[value]);
var bezierRegex = /^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;
var match = value.match(bezierRegex);
if (match) {
var control1 = new WebInspector.Geometry.Point(parseFloat(match[1]), parseFloat(match[2]));
var control2 = new WebInspector.Geometry.Point(parseFloat(match[3]), parseFloat(match[4]));
return new WebInspector.Geometry.CubicBezier(control1, control2);
}
return null;
}
WebInspector.Geometry.CubicBezier.prototype = {
/**
* @param {number} t
* @return {!WebInspector.Geometry.Point}
*/
evaluateAt: function(t)
{
/**
* @param {number} v1
* @param {number} v2
* @param {number} t
*/
function evaluate(v1, v2, t)
{
return 3 * (1 - t) * (1 - t) * t * v1 + 3 * (1 - t) * t * t * v2 + Math.pow(t, 3);
}
var x = evaluate(this.controlPoints[0].x, this.controlPoints[1].x, t);
var y = evaluate(this.controlPoints[0].y, this.controlPoints[1].y, t);
return new WebInspector.Geometry.Point(x, y);
},
/**
* @return {string}
*/
asCSSText: function()
{
var raw = "cubic-bezier(" + this.controlPoints.join(", ") + ")";
var keywordValues = WebInspector.Geometry.CubicBezier.KeywordValues;
for (var keyword in keywordValues) {
if (raw === keywordValues[keyword])
return keyword;
}
return raw;
}
}
/**
* @constructor
* @param {number} alpha
* @param {number} beta
* @param {number} gamma
*/
WebInspector.Geometry.EulerAngles = function(alpha, beta, gamma)
{
this.alpha = alpha;
this.beta = beta;
this.gamma = gamma;
}
/**
* @param {!CSSMatrix} rotationMatrix
* @return {!WebInspector.Geometry.EulerAngles}
*/
WebInspector.Geometry.EulerAngles.fromRotationMatrix = function(rotationMatrix)
{
var beta = Math.atan2(rotationMatrix.m23, rotationMatrix.m33);
var gamma = Math.atan2(-rotationMatrix.m13, Math.sqrt(rotationMatrix.m11 * rotationMatrix.m11 + rotationMatrix.m12 * rotationMatrix.m12));
var alpha = Math.atan2(rotationMatrix.m12, rotationMatrix.m11);
return new WebInspector.Geometry.EulerAngles(WebInspector.Geometry.radToDeg(alpha), WebInspector.Geometry.radToDeg(beta), WebInspector.Geometry.radToDeg(gamma));
}
/**
* @param {!WebInspector.Geometry.Vector} u
* @param {!WebInspector.Geometry.Vector} v
* @return {number}
*/
WebInspector.Geometry.scalarProduct = function(u, v)
{
return u.x * v.x + u.y * v.y + u.z * v.z;
}
/**
* @param {!WebInspector.Geometry.Vector} u
* @param {!WebInspector.Geometry.Vector} v
* @return {!WebInspector.Geometry.Vector}
*/
WebInspector.Geometry.crossProduct = function(u, v)
{
var x = u.y * v.z - u.z * v.y;
var y = u.z * v.x - u.x * v.z;
var z = u.x * v.y - u.y * v.x;
return new WebInspector.Geometry.Vector(x, y, z);
}
/**
* @param {!WebInspector.Geometry.Vector} u
* @param {!WebInspector.Geometry.Vector} v
* @return {!WebInspector.Geometry.Vector}
*/
WebInspector.Geometry.subtract = function(u, v)
{
var x = u.x - v.x;
var y = u.y - v.y;
var z = u.z - v.z;
return new WebInspector.Geometry.Vector(x, y, z);
}
/**
* @param {!WebInspector.Geometry.Vector} v
* @param {!CSSMatrix} m
* @return {!WebInspector.Geometry.Vector}
*/
WebInspector.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m)
{
var t = v.x * m.m14 + v.y * m.m24 + v.z * m.m34 + m.m44;
var x = (v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41) / t;
var y = (v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42) / t;
var z = (v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43) / t;
return new WebInspector.Geometry.Vector(x, y, z);
}
/**
* @param {!WebInspector.Geometry.Vector} u
* @param {!WebInspector.Geometry.Vector} v
* @return {number}
*/
WebInspector.Geometry.calculateAngle = function(u, v)
{
var uLength = u.length();
var vLength = v.length();
if (uLength <= WebInspector.Geometry._Eps || vLength <= WebInspector.Geometry._Eps)
return 0;
var cos = WebInspector.Geometry.scalarProduct(u, v) / uLength / vLength;
if (Math.abs(cos) > 1)
return 0;
return WebInspector.Geometry.radToDeg(Math.acos(cos));
}
/**
* @param {number} rad
* @return {number}
*/
WebInspector.Geometry.radToDeg = function(rad)
{
return rad * 180 / Math.PI;
}
/**
* @param {!CSSMatrix} matrix
* @param {!Array.<number>} points
* @param {{minX: number, maxX: number, minY: number, maxY: number}=} aggregateBounds
* @return {!{minX: number, maxX: number, minY: number, maxY: number}}
*/
WebInspector.Geometry.boundsForTransformedPoints = function(matrix, points, aggregateBounds)
{
if (!aggregateBounds)
aggregateBounds = {minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity};
if (points.length % 3)
console.assert("Invalid size of points array");
for (var p = 0; p < points.length; p += 3) {
var vector = new WebInspector.Geometry.Vector(points[p], points[p + 1], points[p + 2]);
vector = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(vector, matrix);
aggregateBounds.minX = Math.min(aggregateBounds.minX, vector.x);
aggregateBounds.maxX = Math.max(aggregateBounds.maxX, vector.x);
aggregateBounds.minY = Math.min(aggregateBounds.minY, vector.y);
aggregateBounds.maxY = Math.max(aggregateBounds.maxY, vector.y);
}
return aggregateBounds;
}
/**
* @constructor
* @param {number} width
* @param {number} height
*/
function Size(width, height)
{
this.width = width;
this.height = height;
}
/**
* @param {?Size} size
* @return {boolean}
*/
Size.prototype.isEqual = function(size)
{
return !!size && this.width === size.width && this.height === size.height;
};
/**
* @param {!Size|number} size
* @return {!Size}
*/
Size.prototype.widthToMax = function(size)
{
return new Size(Math.max(this.width, (typeof size === "number" ? size : size.width)), this.height);
};
/**
* @param {!Size|number} size
* @return {!Size}
*/
Size.prototype.addWidth = function(size)
{
return new Size(this.width + (typeof size === "number" ? size : size.width), this.height);
};
/**
* @param {!Size|number} size
* @return {!Size}
*/
Size.prototype.heightToMax = function(size)
{
return new Size(this.width, Math.max(this.height, (typeof size === "number" ? size : size.height)));
};
/**
* @param {!Size|number} size
* @return {!Size}
*/
Size.prototype.addHeight = function(size)
{
return new Size(this.width, this.height + (typeof size === "number" ? size : size.height));
};
/**
* @constructor
* @param {number} left
* @param {number} top
* @param {number} right
* @param {number} bottom
*/
function Insets(left, top, right, bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
Insets.prototype = {
/**
* @param {?Insets} insets
* @return {boolean}
*/
isEqual: function(insets)
{
return !!insets && this.left === insets.left && this.top === insets.top && this.right == insets.right && this.bottom == insets.bottom;
}
}
/**
* @constructor
* @param {number} left
* @param {number} top
* @param {number} width
* @param {number} height
*/
WebInspector.Rect = function(left, top, width, height)
{
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
WebInspector.Rect.prototype = {
/**
* @param {?WebInspector.Rect} rect
* @return {boolean}
*/
isEqual: function(rect)
{
return !!rect && this.left === rect.left && this.top === rect.top && this.width == rect.width && this.height == rect.height;
},
/**
* @param {number} scale
* @return {!WebInspector.Rect}
*/
scale: function(scale)
{
return new WebInspector.Rect(this.left * scale, this.top * scale, this.width * scale, this.height * scale);
},
/**
* @return {!Size}
*/
size: function()
{
return new Size(this.width, this.height);
}
}
/**
* @constructor
* @param {!Size=} minimum
* @param {?Size=} preferred
*/
function Constraints(minimum, preferred)
{
/**
* @type {!Size}
*/
this.minimum = minimum || new Size(0, 0);
/**
* @type {!Size}
*/
this.preferred = preferred || this.minimum;
if (this.minimum.width > this.preferred.width || this.minimum.height > this.preferred.height)
throw new Error("Minimum size is greater than preferred.");
}
/**
* @param {?Constraints} constraints
* @return {boolean}
*/
Constraints.prototype.isEqual = function(constraints)
{
return !!constraints && this.minimum.isEqual(constraints.minimum) && this.preferred.isEqual(constraints.preferred);
}
/**
* @param {!Constraints|number} value
* @return {!Constraints}
*/
Constraints.prototype.widthToMax = function(value)
{
if (typeof value === "number")
return new Constraints(this.minimum.widthToMax(value), this.preferred.widthToMax(value));
return new Constraints(this.minimum.widthToMax(value.minimum), this.preferred.widthToMax(value.preferred));
}
/**
* @param {!Constraints|number} value
* @return {!Constraints}
*/
Constraints.prototype.addWidth = function(value)
{
if (typeof value === "number")
return new Constraints(this.minimum.addWidth(value), this.preferred.addWidth(value));
return new Constraints(this.minimum.addWidth(value.minimum), this.preferred.addWidth(value.preferred));
}
/**
* @param {!Constraints|number} value
* @return {!Constraints}
*/
Constraints.prototype.heightToMax = function(value)
{
if (typeof value === "number")
return new Constraints(this.minimum.heightToMax(value), this.preferred.heightToMax(value));
return new Constraints(this.minimum.heightToMax(value.minimum), this.preferred.heightToMax(value.preferred));
}
/**
* @param {!Constraints|number} value
* @return {!Constraints}
*/
Constraints.prototype.addHeight = function(value)
{
if (typeof value === "number")
return new Constraints(this.minimum.addHeight(value), this.preferred.addHeight(value));
return new Constraints(this.minimum.addHeight(value.minimum), this.preferred.addHeight(value.preferred));
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 2 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @interface */ WebInspector.Renderer = function() { } WebInspector.Renderer.prototype = { /** * @param {!Object} object * @return {!Promise.<!Element>} */ render: function(object) {} } /** * @param {!Object} object * @return {!Promise.<!Element>} */ WebInspector.Renderer.renderPromise = function(object) { if (!object) return Promise.reject(new Error("Can't render " + object)); return self.runtime.instancePromise(WebInspector.Renderer, object).then(render); /** * @param {!WebInspector.Renderer} renderer */ function render(renderer) { return renderer.render(object); } } /** * @interface */ WebInspector.Revealer = function() { } /** * @param {?Object} revealable * @param {number=} lineNumber */ WebInspector.Revealer.reveal = function(revealable, lineNumber) { WebInspector.Revealer.revealPromise(revealable, lineNumber); } /** * @param {?Object} revealable * @param {number=} lineNumber * @return {!Promise.<undefined>} */ WebInspector.Revealer.revealPromise = function(revealable, lineNumber) { if (!revealable) return Promise.reject(new Error("Can't reveal " + revealable)); return self.runtime.instancesPromise(WebInspector.Revealer, revealable).then(reveal); /** * @param {!Array.<!WebInspector.Revealer>} revealers * @return {!Promise.<undefined>} */ function reveal(revealers) { var promises = []; for (var i = 0; i < revealers.length; ++i) promises.push(revealers[i].reveal(/** @type {!Object} */ (revealable), lineNumber)); return Promise.race(promises); } } WebInspector.Revealer.prototype = { /** * @param {!Object} object * @param {number=} lineNumber * @return {!Promise} */ reveal: function(object, lineNumber) {} } /** * @interface */ WebInspector.App = function() { } WebInspector.App.prototype = { /** * @param {!Document} document */ presentUI: function(document) { } } /** * @interface */ WebInspector.AppProvider = function() { } WebInspector.AppProvider.prototype = { /** * @return {!WebInspector.App} */ createApp: function() { } } /** * @interface */ WebInspector.QueryParamHandler = function() { } WebInspector.QueryParamHandler.prototype = { /** * @param {string} value */ handleQueryParam: function(value) { } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 2 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.NotificationService = function() { }
WebInspector.NotificationService.prototype = {
__proto__: WebInspector.Object.prototype
}
WebInspector.NotificationService.Events = {
SelectedNodeChanged: "SelectedNodeChanged"
}
WebInspector.notifications = new WebInspector.NotificationService();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.EventTarget}
*/
WebInspector.Object = function() {
}
WebInspector.Object.prototype = {
/**
* @override
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
* @return {!WebInspector.EventTarget.EventDescriptor}
*/
addEventListener: function(eventType, listener, thisObject)
{
if (!listener)
console.assert(false);
if (!this._listeners)
this._listeners = new Map();
if (!this._listeners.has(eventType))
this._listeners.set(eventType, []);
this._listeners.get(eventType).push({ thisObject: thisObject, listener: listener });
return new WebInspector.EventTarget.EventDescriptor(this, eventType, thisObject, listener);
},
/**
* @override
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);
if (!this._listeners || !this._listeners.has(eventType))
return;
var listeners = this._listeners.get(eventType);
for (var i = 0; i < listeners.length; ++i) {
if (listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i--, 1);
}
if (!listeners.length)
this._listeners.delete(eventType);
},
/**
* @override
*/
removeAllListeners: function()
{
delete this._listeners;
},
/**
* @override
* @param {string} eventType
* @return {boolean}
*/
hasEventListeners: function(eventType)
{
if (!this._listeners || !this._listeners.has(eventType))
return false;
return true;
},
/**
* @override
* @param {string} eventType
* @param {*=} eventData
* @return {boolean}
*/
dispatchEventToListeners: function(eventType, eventData)
{
if (!this._listeners || !this._listeners.has(eventType))
return false;
var event = new WebInspector.Event(this, eventType, eventData);
var listeners = this._listeners.get(eventType).slice(0);
for (var i = 0; i < listeners.length; ++i) {
listeners[i].listener.call(listeners[i].thisObject, event);
if (event._stoppedPropagation)
break;
}
return event.defaultPrevented;
}
}
/**
* @constructor
* @param {!WebInspector.EventTarget} target
* @param {string} type
* @param {*=} data
*/
WebInspector.Event = function(target, type, data)
{
this.target = target;
this.type = type;
this.data = data;
this.defaultPrevented = false;
this._stoppedPropagation = false;
}
WebInspector.Event.prototype = {
stopPropagation: function()
{
this._stoppedPropagation = true;
},
preventDefault: function()
{
this.defaultPrevented = true;
},
/**
* @param {boolean=} preventDefault
*/
consume: function(preventDefault)
{
this.stopPropagation();
if (preventDefault)
this.preventDefault();
}
}
/**
* @interface
*/
WebInspector.EventTarget = function()
{
}
/**
* @param {!Array<!WebInspector.EventTarget.EventDescriptor>} eventList
*/
WebInspector.EventTarget.removeEventListeners = function(eventList)
{
for (var i = 0; i < eventList.length; ++i) {
var eventInfo = eventList[i];
eventInfo.eventTarget.removeEventListener(eventInfo.eventType, eventInfo.method, eventInfo.receiver);
}
}
WebInspector.EventTarget.prototype = {
/**
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
* @return {!WebInspector.EventTarget.EventDescriptor}
*/
addEventListener: function(eventType, listener, thisObject) { },
/**
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeEventListener: function(eventType, listener, thisObject) { },
removeAllListeners: function() { },
/**
* @param {string} eventType
* @return {boolean}
*/
hasEventListeners: function(eventType) { },
/**
* @param {string} eventType
* @param {*=} eventData
* @return {boolean}
*/
dispatchEventToListeners: function(eventType, eventData) { },
}
/**
* @constructor
* @param {!WebInspector.EventTarget} eventTarget
* @param {string} eventType
* @param {(!Object|undefined)} receiver
* @param {function(?):?} method
*/
WebInspector.EventTarget.EventDescriptor = function(eventTarget, eventType, receiver, method)
{
this.eventTarget = eventTarget;
this.eventType = eventType;
this.receiver = receiver;
this.method = method;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @interface */ WebInspector.OutputStream = function() { } WebInspector.OutputStream.prototype = { /** * @param {string} data * @param {function(!WebInspector.OutputStream)=} callback */ write: function(data, callback) { }, close: function() { } } /** * @constructor * @implements {WebInspector.OutputStream} */ WebInspector.StringOutputStream = function() { this._data = ""; } WebInspector.StringOutputStream.prototype = { /** * @override * @param {string} chunk * @param {function(!WebInspector.OutputStream)=} callback */ write: function(chunk, callback) { this._data += chunk; }, /** * @override */ close: function() { }, /** * @return {string} */ data: function() { return this._data; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} url
*/
WebInspector.ParsedURL = function(url)
{
this.isValid = false;
this.url = url;
this.scheme = "";
this.host = "";
this.port = "";
this.path = "";
this.queryParams = "";
this.fragment = "";
this.folderPathComponents = "";
this.lastPathComponent = "";
// RegExp groups:
// 1 - scheme (using the RFC3986 grammar)
// 2 - hostname
// 3 - ?port
// 4 - ?path
// 5 - ?fragment
var match = url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\s\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
if (match) {
this.isValid = true;
this.scheme = match[1].toLowerCase();
this.host = match[2];
this.port = match[3];
this.path = match[4] || "/";
this.fragment = match[5];
} else {
if (this.url.startsWith("data:")) {
this.scheme = "data";
return;
}
if (this.url === "about:blank") {
this.scheme = "about";
return;
}
this.path = this.url;
}
// First cut the query params.
var path = this.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1) {
this.queryParams = path.substring(indexOfQuery + 1);
path = path.substring(0, indexOfQuery);
}
// Then take last path component.
var lastSlashIndex = path.lastIndexOf("/");
if (lastSlashIndex !== -1) {
this.folderPathComponents = path.substring(0, lastSlashIndex);
this.lastPathComponent = path.substring(lastSlashIndex + 1);
} else
this.lastPathComponent = path;
}
/**
* @param {string} url
* @return {!Array.<string>}
*/
WebInspector.ParsedURL.splitURLIntoPathComponents = function(url)
{
var parsedURL = new WebInspector.ParsedURL(url);
var origin;
var folderPath;
var name;
if (parsedURL.isValid) {
origin = parsedURL.scheme + "://" + parsedURL.host;
if (parsedURL.port)
origin += ":" + parsedURL.port;
folderPath = parsedURL.folderPathComponents;
name = parsedURL.lastPathComponent;
if (parsedURL.queryParams)
name += "?" + parsedURL.queryParams;
} else {
origin = "";
folderPath = "";
name = url;
}
var result = [origin];
var splittedPath = folderPath.split("/");
for (var i = 1; i < splittedPath.length; ++i) {
if (!splittedPath[i])
continue;
result.push(splittedPath[i]);
}
result.push(name);
return result;
}
/**
* @param {string} url
* @return {string}
*/
WebInspector.ParsedURL.extractOrigin = function(url)
{
var parsedURL = new WebInspector.ParsedURL(url);
if (!parsedURL.isValid)
return "";
var origin = parsedURL.scheme + "://" + parsedURL.host;
if (parsedURL.port)
origin += ":" + parsedURL.port;
return origin;
}
/**
* @param {string} baseURL
* @param {string} href
* @return {?string}
*/
WebInspector.ParsedURL.completeURL = function(baseURL, href)
{
if (href) {
// Return special URLs as-is.
var trimmedHref = href.trim();
if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
return href;
// Return absolute URLs as-is.
var parsedHref = trimmedHref.asParsedURL();
if (parsedHref && parsedHref.scheme)
return trimmedHref;
} else {
return baseURL;
}
var parsedURL = baseURL.asParsedURL();
if (parsedURL) {
if (parsedURL.isDataURL())
return href;
var path = href;
var query = path.indexOf("?");
var postfix = "";
if (query !== -1) {
postfix = path.substring(query);
path = path.substring(0, query);
} else {
var fragment = path.indexOf("#");
if (fragment !== -1) {
postfix = path.substring(fragment);
path = path.substring(0, fragment);
}
}
if (!path) { // empty path, must be postfix
var basePath = parsedURL.path;
if (postfix.charAt(0) === "?") {
// A href of "?foo=bar" implies "basePath?foo=bar".
// With "basePath?a=b" and "?foo=bar" we should get "basePath?foo=bar".
var baseQuery = parsedURL.path.indexOf("?");
if (baseQuery !== -1)
basePath = basePath.substring(0, baseQuery);
} // else it must be a fragment
return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + basePath + postfix;
} else if (path.charAt(0) !== "/") { // relative path
var prefix = parsedURL.path;
var prefixQuery = prefix.indexOf("?");
if (prefixQuery !== -1)
prefix = prefix.substring(0, prefixQuery);
prefix = prefix.substring(0, prefix.lastIndexOf("/")) + "/";
path = prefix + path;
} else if (path.length > 1 && path.charAt(1) === "/") {
// href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol).
return parsedURL.scheme + ":" + path + postfix;
} // else absolute path
return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + normalizePath(path) + postfix;
}
return null;
}
WebInspector.ParsedURL.prototype = {
get displayName()
{
if (this._displayName)
return this._displayName;
if (this.isDataURL())
return this.dataURLDisplayName();
if (this.isAboutBlank())
return this.url;
this._displayName = this.lastPathComponent;
if (!this._displayName)
this._displayName = (this.host || "") + "/";
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
},
/**
* @return {string}
*/
dataURLDisplayName: function()
{
if (this._dataURLDisplayName)
return this._dataURLDisplayName;
if (!this.isDataURL())
return "";
this._dataURLDisplayName = this.url.trimEnd(20);
return this._dataURLDisplayName;
},
/**
* @return {boolean}
*/
isAboutBlank: function()
{
return this.url === "about:blank";
},
/**
* @return {boolean}
*/
isDataURL: function()
{
return this.scheme === "data";
},
/**
* @return {string}
*/
lastPathComponentWithFragment: function()
{
return this.lastPathComponent + (this.fragment ? "#" + this.fragment : "");
},
/**
* @return {string}
*/
domain: function()
{
return this.host + (this.port ? ":" + this.port : "");
},
/**
* @return {string}
*/
urlWithoutScheme: function()
{
if (this.scheme && this.url.startsWith(this.scheme + "://"))
return this.url.substring(this.scheme.length + 3);
return this.url;
},
}
/**
* @param {string} string
* @return {!{url: string, lineNumber: (number|undefined), columnNumber: (number|undefined)}}
*/
WebInspector.ParsedURL.splitLineAndColumn = function(string)
{
var lineColumnRegEx = /(?::(\d+))?(?::(\d+))?$/;
var lineColumnMatch = lineColumnRegEx.exec(string);
var lineNumber;
var columnNumber;
console.assert(lineColumnMatch);
if (typeof(lineColumnMatch[1]) === "string") {
lineNumber = parseInt(lineColumnMatch[1], 10);
// Immediately convert line and column to 0-based numbers.
lineNumber = isNaN(lineNumber) ? undefined : lineNumber - 1;
}
if (typeof(lineColumnMatch[2]) === "string") {
columnNumber = parseInt(lineColumnMatch[2], 10);
columnNumber = isNaN(columnNumber) ? undefined : columnNumber - 1;
}
return {url: string.substring(0, string.length - lineColumnMatch[0].length), lineNumber: lineNumber, columnNumber: columnNumber};
}
/**
* @param {string} url
* @return {boolean}
*/
WebInspector.ParsedURL.isRelativeURL = function(url)
{
return !(/^[A-Za-z][A-Za-z0-9+.-]*:/.test(url));
}
/**
* @return {?WebInspector.ParsedURL}
*/
String.prototype.asParsedURL = function()
{
var parsedURL = new WebInspector.ParsedURL(this.toString());
if (parsedURL.isValid)
return parsedURL;
return null;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | 2 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.Progress = function() { } WebInspector.Progress.prototype = { /** * @param {number} totalWork */ setTotalWork: function(totalWork) { }, /** * @param {string} title */ setTitle: function(title) { }, /** * @param {number} worked * @param {string=} title */ setWorked: function(worked, title) { }, /** * @param {number=} worked */ worked: function(worked) { }, done: function() { }, /** * @return {boolean} */ isCanceled: function() { return false; }, } /** * @constructor * @param {!WebInspector.Progress} parent */ WebInspector.CompositeProgress = function(parent) { this._parent = parent; this._children = []; this._childrenDone = 0; this._parent.setTotalWork(1); this._parent.setWorked(0); } WebInspector.CompositeProgress.prototype = { _childDone: function() { if (++this._childrenDone !== this._children.length) return; this._parent.done(); }, /** * @param {number=} weight * @return {!WebInspector.SubProgress} */ createSubProgress: function(weight) { var child = new WebInspector.SubProgress(this, weight); this._children.push(child); return child; }, _update: function() { var totalWeights = 0; var done = 0; for (var i = 0; i < this._children.length; ++i) { var child = this._children[i]; if (child._totalWork) done += child._weight * child._worked / child._totalWork; totalWeights += child._weight; } this._parent.setWorked(done / totalWeights); } } /** * @constructor * @implements {WebInspector.Progress} * @param {!WebInspector.CompositeProgress} composite * @param {number=} weight */ WebInspector.SubProgress = function(composite, weight) { this._composite = composite; this._weight = weight || 1; this._worked = 0; } WebInspector.SubProgress.prototype = { /** * @override * @return {boolean} */ isCanceled: function() { return this._composite._parent.isCanceled(); }, /** * @override * @param {string} title */ setTitle: function(title) { this._composite._parent.setTitle(title); }, /** * @override */ done: function() { this.setWorked(this._totalWork); this._composite._childDone(); }, /** * @override * @param {number} totalWork */ setTotalWork: function(totalWork) { this._totalWork = totalWork; this._composite._update(); }, /** * @override * @param {number} worked * @param {string=} title */ setWorked: function(worked, title) { this._worked = worked; if (typeof title !== "undefined") this.setTitle(title); this._composite._update(); }, /** * @override * @param {number=} worked */ worked: function(worked) { this.setWorked(this._worked + (worked || 1)); } } /** * @constructor * @implements {WebInspector.Progress} * @param {?WebInspector.Progress} delegate * @param {function()=} doneCallback */ WebInspector.ProgressProxy = function(delegate, doneCallback) { this._delegate = delegate; this._doneCallback = doneCallback; } WebInspector.ProgressProxy.prototype = { /** * @override * @return {boolean} */ isCanceled: function() { return this._delegate ? this._delegate.isCanceled() : false; }, /** * @override * @param {string} title */ setTitle: function(title) { if (this._delegate) this._delegate.setTitle(title); }, /** * @override */ done: function() { if (this._delegate) this._delegate.done(); if (this._doneCallback) this._doneCallback(); }, /** * @override * @param {number} totalWork */ setTotalWork: function(totalWork) { if (this._delegate) this._delegate.setTotalWork(totalWork); }, /** * @override * @param {number} worked * @param {string=} title */ setWorked: function(worked, title) { if (this._delegate) this._delegate.setWorked(worked, title); }, /** * @override * @param {number=} worked */ worked: function(worked) { if (this._delegate) this._delegate.worked(worked); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} name
* @param {string} title
* @param {!WebInspector.ResourceCategory} category
* @param {boolean} isTextType
*/
WebInspector.ResourceType = function(name, title, category, isTextType)
{
this._name = name;
this._title = title;
this._category = category;
this._isTextType = isTextType;
}
WebInspector.ResourceType.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @return {!WebInspector.ResourceCategory}
*/
category: function()
{
return this._category;
},
/**
* @return {boolean}
*/
isTextType: function()
{
return this._isTextType;
},
/**
* @return {boolean}
*/
isScript: function()
{
return this._name === "script" || this._name === "sm-script";
},
/**
* @return {boolean}
*/
hasScripts: function()
{
return this.isScript() || this.isDocument();
},
/**
* @return {boolean}
*/
isStyleSheet: function()
{
return this._name === "stylesheet" || this._name === "sm-stylesheet";
},
/**
* @return {boolean}
*/
isDocument: function()
{
return this._name === "document";
},
/**
* @return {boolean}
*/
isDocumentOrScriptOrStyleSheet: function()
{
return this.isDocument() || this.isScript() || this.isStyleSheet();
},
/**
* @return {boolean}
*/
isFromSourceMap: function()
{
return this._name.startsWith("sm-");
},
/**
* @override
* @return {string}
*/
toString: function()
{
return this._name;
},
/**
* @return {string}
*/
canonicalMimeType: function()
{
if (this.isDocument())
return "text/html";
if (this.isScript())
return "text/javascript";
if (this.isStyleSheet())
return "text/css";
return "";
}
}
/**
* @constructor
* @param {string} title
* @param {string} shortTitle
*/
WebInspector.ResourceCategory = function(title, shortTitle)
{
this.title = title;
this.shortTitle = shortTitle;
}
WebInspector.resourceCategories = {
XHR: new WebInspector.ResourceCategory("XHR and Fetch", "XHR"),
Script: new WebInspector.ResourceCategory("Scripts", "JS"),
Stylesheet: new WebInspector.ResourceCategory("Stylesheets", "CSS"),
Image: new WebInspector.ResourceCategory("Images", "Img"),
Media: new WebInspector.ResourceCategory("Media", "Media"),
Font: new WebInspector.ResourceCategory("Fonts", "Font"),
Document: new WebInspector.ResourceCategory("Documents", "Doc"),
WebSocket: new WebInspector.ResourceCategory("WebSockets", "WS"),
Manifest: new WebInspector.ResourceCategory("Manifest", "Manifest"),
Other: new WebInspector.ResourceCategory("Other", "Other")
}
/**
* Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
* @enum {!WebInspector.ResourceType}
*/
WebInspector.resourceTypes = {
XHR: new WebInspector.ResourceType("xhr", "XHR", WebInspector.resourceCategories.XHR, true),
Fetch: new WebInspector.ResourceType("fetch", "Fetch", WebInspector.resourceCategories.XHR, true),
EventSource: new WebInspector.ResourceType("eventsource", "EventSource", WebInspector.resourceCategories.XHR, true),
Script: new WebInspector.ResourceType("script", "Script", WebInspector.resourceCategories.Script, true),
Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", WebInspector.resourceCategories.Stylesheet, true),
Image: new WebInspector.ResourceType("image", "Image", WebInspector.resourceCategories.Image, false),
Media: new WebInspector.ResourceType("media", "Media", WebInspector.resourceCategories.Media, false),
Font: new WebInspector.ResourceType("font", "Font", WebInspector.resourceCategories.Font, false),
Document: new WebInspector.ResourceType("document", "Document", WebInspector.resourceCategories.Document, true),
TextTrack: new WebInspector.ResourceType("texttrack", "TextTrack", WebInspector.resourceCategories.Other, true),
WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", WebInspector.resourceCategories.WebSocket, false),
Other: new WebInspector.ResourceType("other", "Other", WebInspector.resourceCategories.Other, false),
SourceMapScript: new WebInspector.ResourceType("sm-script", "Script", WebInspector.resourceCategories.Script, false),
SourceMapStyleSheet: new WebInspector.ResourceType("sm-stylesheet", "Stylesheet", WebInspector.resourceCategories.Stylesheet, false),
Manifest: new WebInspector.ResourceType("manifest", "Manifest", WebInspector.resourceCategories.Manifest, true),
}
/**
* @param {string} url
* @return {string}
*/
WebInspector.ResourceType.mimeFromURL = function(url)
{
var name = WebInspector.TextUtils.fileName(url);
if (WebInspector.ResourceType.mimeTypeByName[name]) {
return WebInspector.ResourceType.mimeTypeByName[name];
}
var ext = WebInspector.TextUtils.extension(url).toLowerCase();
return WebInspector.ResourceType.mimeTypeByExtension[ext];
}
WebInspector.ResourceType.mimeTypeByName = {
// CoffeeScript
"Cakefile": "text/x-coffeescript"
}
WebInspector.ResourceType.mimeTypeByExtension = {
// Web extensions
"js": "text/javascript",
"css": "text/css",
"html": "text/html",
"htm": "text/html",
"xml": "application/xml",
"xsl": "application/xml",
// HTML Embedded Scripts: ASP, JSP
"asp": "application/x-aspx",
"aspx": "application/x-aspx",
"jsp": "application/x-jsp",
// C/C++
"c": "text/x-c++src",
"cc": "text/x-c++src",
"cpp": "text/x-c++src",
"h": "text/x-c++src",
"m": "text/x-c++src",
"mm": "text/x-c++src",
// CoffeeScript
"coffee": "text/x-coffeescript",
// Dart
"dart": "text/javascript",
// TypeScript
"ts": "text/typescript",
"tsx": "text/typescript",
// JSON
"json": "application/json",
"gyp": "application/json",
"gypi": "application/json",
// C#
"cs": "text/x-csharp",
// Java
"java": "text/x-java",
// Less
"less": "text/x-less",
// PHP
"php": "text/x-php",
"phtml": "application/x-httpd-php",
// Python
"py": "text/x-python",
// Shell
"sh": "text/x-sh",
// SCSS
"scss": "text/x-scss",
// Video Text Tracks.
"vtt": "text/vtt",
// LiveScript
"ls": "text/x-livescript",
// ClojureScript
"cljs": "text/x-clojure",
"cljc": "text/x-clojure",
"cljx": "text/x-clojure",
// Stylus
"styl": "text/x-styl",
// JSX
"jsx": "text/jsx",
// Image
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"svg": "image/svg",
"gif": "image/gif",
"webp": "image/webp",
"png": "image/png",
"ico": "image/ico",
"tiff": "image/tiff",
"tif": "image/tif",
"bmp": "image/bmp",
// Font
"ttf": "font/opentype",
"otf": "font/opentype",
"ttc": "font/opentype",
"woff": "application/font-woff"
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {number} begin
* @param {number} end
* @param {*} data
*/
WebInspector.Segment = function(begin, end, data)
{
if (begin > end)
console.assert(false, "Invalid segment");
this.begin = begin;
this.end = end;
this.data = data;
}
WebInspector.Segment.prototype = {
/**
* @param {!WebInspector.Segment} that
* @return {boolean}
*/
intersects: function(that)
{
return this.begin < that.end && that.begin < this.end;
}
};
/**
* @constructor
* @param {(function(!WebInspector.Segment, !WebInspector.Segment): ?WebInspector.Segment)=} mergeCallback
*/
WebInspector.SegmentedRange = function(mergeCallback)
{
/** @type {!Array<!WebInspector.Segment>} */
this._segments = [];
this._mergeCallback = mergeCallback;
}
WebInspector.SegmentedRange.prototype = {
/**
* @param {!WebInspector.Segment} newSegment
*/
append: function(newSegment)
{
// 1. Find the proper insertion point for new segment
var startIndex = this._segments.lowerBound(newSegment, (a, b) => a.begin - b.begin);
var endIndex = startIndex;
var merged = null;
if (startIndex > 0) {
// 2. Try mering the preceding segment
var precedingSegment = this._segments[startIndex - 1];
merged = this._tryMerge(precedingSegment, newSegment);
if (merged) {
--startIndex;
newSegment = merged;
} else if (this._segments[startIndex - 1].end >= newSegment.begin) {
// 2a. If merge failed and segments overlap, adjust preceding segment.
// If an old segment entirely contains new one, split it in two.
if (newSegment.end < precedingSegment.end)
this._segments.splice(startIndex, 0, new WebInspector.Segment(newSegment.end, precedingSegment.end, precedingSegment.data));
precedingSegment.end = newSegment.begin;
}
}
// 3. Consume all segments that are entirely covered by the new one.
while (endIndex < this._segments.length && this._segments[endIndex].end <= newSegment.end)
++endIndex;
// 4. Merge or adjust the succeeding segment if it overlaps.
if (endIndex < this._segments.length) {
merged = this._tryMerge(newSegment, this._segments[endIndex]);
if (merged) {
endIndex++;
newSegment = merged;
} else if (newSegment.intersects(this._segments[endIndex]))
this._segments[endIndex].begin = newSegment.end;
}
this._segments.splice(startIndex, endIndex - startIndex, newSegment);
},
/**
* @param {!WebInspector.SegmentedRange} that
*/
appendRange: function(that)
{
that.segments().forEach(segment => this.append(segment));
},
/**
* @return {!Array<!WebInspector.Segment>}
*/
segments: function()
{
return this._segments;
},
/**
* @param {!WebInspector.Segment} first
* @param {!WebInspector.Segment} second
* @return {?WebInspector.Segment}
*/
_tryMerge: function(first, second)
{
var merged = this._mergeCallback && this._mergeCallback(first, second);
if (!merged)
return null;
merged.begin = first.begin;
merged.end = Math.max(first.end, second.end);
return merged;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 | 2 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.SettingsStorage} storage
*/
WebInspector.Settings = function(storage)
{
this._settingsStorage = storage;
var clearLocalStorage = window.localStorage ? window.localStorage.clear.bind(window.localStorage) : undefined;
this._localStorage = new WebInspector.SettingsStorage(window.localStorage || {}, undefined, undefined, clearLocalStorage);
this._eventSupport = new WebInspector.Object();
/** @type {!Map<string, !WebInspector.Setting>} */
this._registry = new Map();
/** @type {!Map<string, !WebInspector.Setting>} */
this._moduleSettings = new Map();
self.runtime.extensions("setting").forEach(this._registerModuleSetting.bind(this));
}
WebInspector.Settings.prototype = {
/**
* @param {!Runtime.Extension} extension
*/
_registerModuleSetting: function(extension)
{
var descriptor = extension.descriptor();
var settingName = descriptor["settingName"];
var settingType = descriptor["settingType"];
var defaultValue = descriptor["defaultValue"];
var isLocal = !!descriptor["local"];
var setting = settingType === "regex" ? this.createRegExpSetting(settingName, defaultValue, undefined, isLocal) : this.createSetting(settingName, defaultValue, isLocal);
this._moduleSettings.set(settingName, setting);
},
/**
* @param {string} settingName
* @return {!WebInspector.Setting}
*/
moduleSetting: function(settingName)
{
var setting = this._moduleSettings.get(settingName);
if (!setting)
throw new Error("No setting registered: " + settingName);
return setting;
},
/**
* @param {string} settingName
* @return {!WebInspector.Setting}
*/
settingForTest: function(settingName)
{
var setting = this._registry.get(settingName);
if (!setting)
throw new Error("No setting registered: " + settingName);
return setting;
},
/**
* @param {string} key
* @param {*} defaultValue
* @param {boolean=} isLocal
* @return {!WebInspector.Setting}
*/
createSetting: function(key, defaultValue, isLocal)
{
if (!this._registry.get(key))
this._registry.set(key, new WebInspector.Setting(this, key, defaultValue, this._eventSupport, isLocal ? this._localStorage : this._settingsStorage));
return /** @type {!WebInspector.Setting} */ (this._registry.get(key));
},
/**
* @param {string} key
* @param {*} defaultValue
* @return {!WebInspector.Setting}
*/
createLocalSetting: function(key, defaultValue)
{
return this.createSetting(key, defaultValue, true);
},
/**
* @param {string} key
* @param {string} defaultValue
* @param {string=} regexFlags
* @param {boolean=} isLocal
* @return {!WebInspector.RegExpSetting}
*/
createRegExpSetting: function(key, defaultValue, regexFlags, isLocal)
{
if (!this._registry.get(key))
this._registry.set(key, new WebInspector.RegExpSetting(this, key, defaultValue, this._eventSupport, isLocal ? this._localStorage : this._settingsStorage, regexFlags));
return /** @type {!WebInspector.RegExpSetting} */ (this._registry.get(key));
},
clearAll: function()
{
this._settingsStorage.removeAll();
this._localStorage.removeAll();
var versionSetting = WebInspector.settings.createSetting(WebInspector.VersionController._currentVersionName, 0);
versionSetting.set(WebInspector.VersionController.currentVersion);
}
}
/**
* @constructor
* @param {!Object} object
* @param {function(string, string)=} setCallback
* @param {function(string)=} removeCallback
* @param {function(string)=} removeAllCallback
*/
WebInspector.SettingsStorage = function(object, setCallback, removeCallback, removeAllCallback)
{
this._object = object;
this._setCallback = setCallback || function() {};
this._removeCallback = removeCallback || function() {};
this._removeAllCallback = removeAllCallback || function() {};
}
WebInspector.SettingsStorage.prototype = {
/**
* @param {string} name
* @param {string} value
*/
set: function(name, value)
{
this._object[name] = value;
this._setCallback(name, value);
},
/**
* @param {string} name
* @return {boolean}
*/
has: function(name)
{
return name in this._object;
},
/**
* @param {string} name
* @return {string}
*/
get: function(name)
{
return this._object[name];
},
/**
* @param {string} name
*/
remove: function(name)
{
delete this._object[name];
this._removeCallback(name);
},
removeAll: function()
{
this._object = {};
this._removeAllCallback();
},
_dumpSizes: function()
{
WebInspector.console.log("Ten largest settings: ");
var sizes = { __proto__: null };
for (var key in this._object)
sizes[key] = this._object[key].length;
var keys = Object.keys(sizes);
function comparator(key1, key2)
{
return sizes[key2] - sizes[key1];
}
keys.sort(comparator);
for (var i = 0; i < 10 && i < keys.length; ++i)
WebInspector.console.log("Setting: '" + keys[i] + "', size: " + sizes[keys[i]]);
}
}
/**
* @constructor
* @param {!WebInspector.Settings} settings
* @param {string} name
* @param {V} defaultValue
* @param {!WebInspector.Object} eventSupport
* @param {!WebInspector.SettingsStorage} storage
* @template V
*/
WebInspector.Setting = function(settings, name, defaultValue, eventSupport, storage)
{
this._settings = settings;
this._name = name;
this._defaultValue = defaultValue;
this._eventSupport = eventSupport;
this._storage = storage;
}
WebInspector.Setting.prototype = {
/**
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
addChangeListener: function(listener, thisObject)
{
this._eventSupport.addEventListener(this._name, listener, thisObject);
},
/**
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeChangeListener: function(listener, thisObject)
{
this._eventSupport.removeEventListener(this._name, listener, thisObject);
},
get name()
{
return this._name;
},
/**
* @return {V}
*/
get: function()
{
if (typeof this._value !== "undefined")
return this._value;
this._value = this._defaultValue;
if (this._storage.has(this._name)) {
try {
this._value = JSON.parse(this._storage.get(this._name));
} catch(e) {
this._storage.remove(this._name);
}
}
return this._value;
},
/**
* @param {V} value
*/
set: function(value)
{
this._value = value;
try {
var settingString = JSON.stringify(value);
try {
this._storage.set(this._name, settingString);
} catch(e) {
this._printSettingsSavingError(e.message, this._name, settingString);
}
} catch(e) {
WebInspector.console.error("Cannot stringify setting with name: " + this._name + ", error: " + e.message);
}
this._eventSupport.dispatchEventToListeners(this._name, value);
},
remove: function()
{
this._settings._registry.delete(this._name);
this._settings._moduleSettings.delete(this._name);
this._storage.remove(this._name);
},
/**
* @param {string} message
* @param {string} name
* @param {string} value
*/
_printSettingsSavingError: function(message, name, value)
{
var errorMessage = "Error saving setting with name: " + this._name + ", value length: " + value.length + ". Error: " + message;
console.error(errorMessage);
WebInspector.console.error(errorMessage);
this._storage._dumpSizes();
}
}
/**
* @constructor
* @extends {WebInspector.Setting}
* @param {!WebInspector.Settings} settings
* @param {string} name
* @param {string} defaultValue
* @param {!WebInspector.Object} eventSupport
* @param {!WebInspector.SettingsStorage} storage
* @param {string=} regexFlags
*/
WebInspector.RegExpSetting = function(settings, name, defaultValue, eventSupport, storage, regexFlags)
{
WebInspector.Setting.call(this, settings, name, defaultValue ? [{ pattern: defaultValue }] : [], eventSupport, storage);
this._regexFlags = regexFlags;
}
WebInspector.RegExpSetting.prototype = {
/**
* @override
* @return {string}
*/
get: function()
{
var result = [];
var items = this.getAsArray();
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item.pattern && !item.disabled)
result.push(item.pattern);
}
return result.join("|");
},
/**
* @return {!Array.<{pattern: string, disabled: (boolean|undefined)}>}
*/
getAsArray: function()
{
return WebInspector.Setting.prototype.get.call(this);
},
/**
* @override
* @param {string} value
*/
set: function(value)
{
this.setAsArray([{ pattern: value }]);
},
/**
* @param {!Array.<{pattern: string, disabled: (boolean|undefined)}>} value
*/
setAsArray: function(value)
{
delete this._regex;
WebInspector.Setting.prototype.set.call(this, value);
},
/**
* @return {?RegExp}
*/
asRegExp: function()
{
if (typeof this._regex !== "undefined")
return this._regex;
this._regex = null;
try {
var pattern = this.get();
if (pattern)
this._regex = new RegExp(pattern, this._regexFlags || "");
} catch (e) {
}
return this._regex;
},
__proto__: WebInspector.Setting.prototype
}
/**
* @constructor
*/
WebInspector.VersionController = function()
{
}
WebInspector.VersionController._currentVersionName = "inspectorVersion";
WebInspector.VersionController.currentVersion = 18;
WebInspector.VersionController.prototype = {
updateVersion: function()
{
var localStorageVersion = window.localStorage ? window.localStorage[WebInspector.VersionController._currentVersionName] : 0;
var versionSetting = WebInspector.settings.createSetting(WebInspector.VersionController._currentVersionName, 0);
var currentVersion = WebInspector.VersionController.currentVersion;
// While localStorage version exists, treat it as the main one. It'll be erased once migrated to prefs.
var oldVersion = parseInt(localStorageVersion || "0", 10) || versionSetting.get();
if (oldVersion === 0) {
// First run, no need to do anything.
versionSetting.set(currentVersion);
return;
}
var methodsToRun = this._methodsToRunToUpdateVersion(oldVersion, currentVersion);
for (var i = 0; i < methodsToRun.length; ++i)
this[methodsToRun[i]].call(this);
versionSetting.set(currentVersion);
},
/**
* @param {number} oldVersion
* @param {number} currentVersion
*/
_methodsToRunToUpdateVersion: function(oldVersion, currentVersion)
{
var result = [];
for (var i = oldVersion; i < currentVersion; ++i)
result.push("_updateVersionFrom" + i + "To" + (i + 1));
return result;
},
_updateVersionFrom0To1: function()
{
this._clearBreakpointsWhenTooMany(WebInspector.settings.createLocalSetting("breakpoints", []), 500000);
},
_updateVersionFrom1To2: function()
{
WebInspector.settings.createSetting("previouslyViewedFiles", []).set([]);
},
_updateVersionFrom2To3: function()
{
WebInspector.settings.createSetting("fileSystemMapping", {}).set({});
WebInspector.settings.createSetting("fileMappingEntries", []).remove();
},
_updateVersionFrom3To4: function()
{
var advancedMode = WebInspector.settings.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
WebInspector.moduleSetting("showAdvancedHeapSnapshotProperties").set(advancedMode.get());
advancedMode.remove();
},
_updateVersionFrom4To5: function()
{
var settingNames = {
"FileSystemViewSidebarWidth": "fileSystemViewSplitViewState",
"elementsSidebarWidth": "elementsPanelSplitViewState",
"StylesPaneSplitRatio": "stylesPaneSplitViewState",
"heapSnapshotRetainersViewSize": "heapSnapshotSplitViewState",
"InspectorView.splitView": "InspectorView.splitViewState",
"InspectorView.screencastSplitView": "InspectorView.screencastSplitViewState",
"Inspector.drawerSplitView": "Inspector.drawerSplitViewState",
"layerDetailsSplitView": "layerDetailsSplitViewState",
"networkSidebarWidth": "networkPanelSplitViewState",
"sourcesSidebarWidth": "sourcesPanelSplitViewState",
"scriptsPanelNavigatorSidebarWidth": "sourcesPanelNavigatorSplitViewState",
"sourcesPanelSplitSidebarRatio": "sourcesPanelDebuggerSidebarSplitViewState",
"timeline-details": "timelinePanelDetailsSplitViewState",
"timeline-split": "timelinePanelRecorsSplitViewState",
"timeline-view": "timelinePanelTimelineStackSplitViewState",
"auditsSidebarWidth": "auditsPanelSplitViewState",
"layersSidebarWidth": "layersPanelSplitViewState",
"profilesSidebarWidth": "profilesPanelSplitViewState",
"resourcesSidebarWidth": "resourcesPanelSplitViewState"
};
var empty = {};
for (var oldName in settingNames) {
var newName = settingNames[oldName];
var oldNameH = oldName + "H";
var newValue = null;
var oldSetting = WebInspector.settings.createSetting(oldName, empty);
if (oldSetting.get() !== empty) {
newValue = newValue || {};
newValue.vertical = {};
newValue.vertical.size = oldSetting.get();
oldSetting.remove();
}
var oldSettingH = WebInspector.settings.createSetting(oldNameH, empty);
if (oldSettingH.get() !== empty) {
newValue = newValue || {};
newValue.horizontal = {};
newValue.horizontal.size = oldSettingH.get();
oldSettingH.remove();
}
if (newValue)
WebInspector.settings.createSetting(newName, {}).set(newValue);
}
},
_updateVersionFrom5To6: function()
{
var settingNames = {
"debuggerSidebarHidden": "sourcesPanelSplitViewState",
"navigatorHidden": "sourcesPanelNavigatorSplitViewState",
"WebInspector.Drawer.showOnLoad": "Inspector.drawerSplitViewState"
};
for (var oldName in settingNames) {
var oldSetting = WebInspector.settings.createSetting(oldName, null);
if (oldSetting.get() === null) {
oldSetting.remove();
continue;
}
var newName = settingNames[oldName];
var invert = "WebInspector.Drawer.showOnLoad" === oldName;
var hidden = oldSetting.get() !== invert;
oldSetting.remove();
var showMode = hidden ? "OnlyMain" : "Both";
var newSetting = WebInspector.settings.createSetting(newName, {});
var newValue = newSetting.get() || {};
newValue.vertical = newValue.vertical || {};
newValue.vertical.showMode = showMode;
newValue.horizontal = newValue.horizontal || {};
newValue.horizontal.showMode = showMode;
newSetting.set(newValue);
}
},
_updateVersionFrom6To7: function()
{
var settingNames = {
"sourcesPanelNavigatorSplitViewState": "sourcesPanelNavigatorSplitViewState",
"elementsPanelSplitViewState": "elementsPanelSplitViewState",
"stylesPaneSplitViewState": "stylesPaneSplitViewState",
"sourcesPanelDebuggerSidebarSplitViewState": "sourcesPanelDebuggerSidebarSplitViewState"
};
var empty = {};
for (var name in settingNames) {
var setting = WebInspector.settings.createSetting(name, empty);
var value = setting.get();
if (value === empty)
continue;
// Zero out saved percentage sizes, and they will be restored to defaults.
if (value.vertical && value.vertical.size && value.vertical.size < 1)
value.vertical.size = 0;
if (value.horizontal && value.horizontal.size && value.horizontal.size < 1)
value.horizontal.size = 0;
setting.set(value);
}
},
_updateVersionFrom7To8: function()
{
},
_updateVersionFrom8To9: function()
{
var settingNames = [
"skipStackFramesPattern",
"workspaceFolderExcludePattern"
];
for (var i = 0; i < settingNames.length; ++i) {
var setting = WebInspector.settings.createSetting(settingNames[i], "");
var value = setting.get();
if (!value)
return;
if (typeof value === "string")
value = [value];
for (var j = 0; j < value.length; ++j) {
if (typeof value[j] === "string")
value[j] = { pattern: value[j] };
}
setting.set(value);
}
},
_updateVersionFrom9To10: function()
{
// This one is localStorage specific, which is fine.
if (!window.localStorage)
return;
for (var key in window.localStorage) {
if (key.startsWith("revision-history"))
window.localStorage.removeItem(key);
}
},
_updateVersionFrom10To11: function()
{
var oldSettingName = "customDevicePresets";
var newSettingName = "customEmulatedDeviceList";
var oldSetting = WebInspector.settings.createSetting(oldSettingName, undefined);
var list = oldSetting.get();
if (!Array.isArray(list))
return;
var newList = [];
for (var i = 0; i < list.length; ++i) {
var value = list[i];
var device = {};
device["title"] = value["title"];
device["type"] = "unknown";
device["user-agent"] = value["userAgent"];
device["capabilities"] = [];
if (value["touch"])
device["capabilities"].push("touch");
if (value["mobile"])
device["capabilities"].push("mobile");
device["screen"] = {};
device["screen"]["vertical"] = {width: value["width"], height: value["height"]};
device["screen"]["horizontal"] = {width: value["height"], height: value["width"]};
device["screen"]["device-pixel-ratio"] = value["deviceScaleFactor"];
device["modes"] = [];
device["show-by-default"] = true;
device["show"] = "Default";
newList.push(device);
}
if (newList.length)
WebInspector.settings.createSetting(newSettingName, []).set(newList);
oldSetting.remove();
},
_updateVersionFrom11To12: function()
{
this._migrateSettingsFromLocalStorage();
},
_updateVersionFrom12To13: function()
{
this._migrateSettingsFromLocalStorage();
WebInspector.settings.createSetting("timelineOverviewMode", "").remove();
},
_updateVersionFrom13To14: function()
{
var defaultValue = { "throughput": -1, "latency": 0 };
WebInspector.settings.createSetting("networkConditions", defaultValue).set(defaultValue);
},
_updateVersionFrom14To15: function()
{
var setting = WebInspector.settings.createLocalSetting("workspaceExcludedFolders", {});
var oldValue = setting.get();
var newValue = {};
for (var fileSystemPath in oldValue) {
newValue[fileSystemPath] = [];
for (var entry of oldValue[fileSystemPath])
newValue[fileSystemPath].push(entry.path);
}
setting.set(newValue);
},
_updateVersionFrom15To16: function()
{
var setting = WebInspector.settings.createSetting("InspectorView.panelOrder", {});
var tabOrders = setting.get();
for (var key of Object.keys(tabOrders))
tabOrders[key] = (tabOrders[key] + 1) * 10;
setting.set(tabOrders);
},
_updateVersionFrom16To17: function()
{
var setting = WebInspector.settings.createSetting("networkConditionsCustomProfiles", []);
var oldValue = setting.get();
var newValue = [];
if (Array.isArray(oldValue)) {
for (var preset of oldValue) {
if (typeof preset.title === "string" && typeof preset.value === "object" && typeof preset.value.throughput === "number" && typeof preset.value.latency === "number")
newValue.push({title: preset.title, value: {download: preset.value.throughput, upload: preset.value.throughput, latency: preset.value.latency}});
}
}
setting.set(newValue);
},
_updateVersionFrom17To18: function()
{
var setting = WebInspector.settings.createLocalSetting("workspaceExcludedFolders", {});
var oldValue = setting.get();
var newValue = {};
for (var oldKey in oldValue) {
var newKey = oldKey.replace(/\\/g, "/");
if (!newKey.startsWith("file://")) {
if (newKey.startsWith("/"))
newKey = "file://" + newKey;
else
newKey = "file:///" + newKey;
}
newValue[newKey] = oldValue[oldKey];
}
setting.set(newValue);
},
_migrateSettingsFromLocalStorage: function()
{
// This step migrates all the settings except for the ones below into the browser profile.
var localSettings = [ "advancedSearchConfig", "breakpoints", "consoleHistory", "domBreakpoints", "eventListenerBreakpoints",
"fileSystemMapping", "lastSelectedSourcesSidebarPaneTab", "previouslyViewedFiles",
"savedURLs", "watchExpressions", "workspaceExcludedFolders", "xhrBreakpoints" ].keySet();
if (!window.localStorage)
return;
for (var key in window.localStorage) {
if (key in localSettings)
continue;
var value = window.localStorage[key];
window.localStorage.removeItem(key);
WebInspector.settings._settingsStorage[key] = value;
}
},
/**
* @param {!WebInspector.Setting} breakpointsSetting
* @param {number} maxBreakpointsCount
*/
_clearBreakpointsWhenTooMany: function(breakpointsSetting, maxBreakpointsCount)
{
// If there are too many breakpoints in a storage, it is likely due to a recent bug that caused
// periodical breakpoints duplication leading to inspector slowness.
if (breakpointsSetting.get().length > maxBreakpointsCount)
breakpointsSetting.set([]);
}
}
/**
* @type {!WebInspector.Settings}
*/
WebInspector.settings;
/**
* @param {string} settingName
* @return {!WebInspector.Setting}
*/
WebInspector.moduleSetting = function(settingName)
{
return WebInspector.settings.moduleSetting(settingName);
}
/**
* @param {string} settingName
* @return {!WebInspector.Setting}
*/
WebInspector.settingForTest = function(settingName)
{
return WebInspector.settings.settingForTest(settingName);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.ResourceType} contentType
* @param {string} content
* @param {string=} contentURL
*/
WebInspector.StaticContentProvider = function(contentType, content, contentURL)
{
this._content = content;
this._contentType = contentType;
this._contentURL = contentURL || "";
}
/**
* @param {string} content
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
WebInspector.StaticContentProvider.searchInContent = function(content, query, caseSensitive, isRegex, callback)
{
function performSearch()
{
callback(WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
}
// searchInContent should call back later.
setTimeout(performSearch.bind(null), 0);
}
WebInspector.StaticContentProvider.prototype = {
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._contentURL;
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._contentType;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
return Promise.resolve(/** @type {?string} */(this._content));
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
WebInspector.StaticContentProvider.searchInContent(this._content, query, caseSensitive, isRegex, callback);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {string} value
*/
WebInspector.Text = function(value)
{
this._value = value;
}
WebInspector.Text.prototype = {
/**
* @return {!Array<number>}
*/
lineEndings: function()
{
if (!this._lineEndings)
this._lineEndings = this._value.computeLineEndings();
return this._lineEndings;
},
/**
* @return {string}
*/
value: function()
{
return this._value;
},
/**
* @return {number}
*/
lineCount: function()
{
var lineEndings = this.lineEndings();
return lineEndings.length;
},
/**
* @param {number} lineNumber
* @param {number} columNumber
* @return {number}
*/
offsetFromPosition: function(lineNumber, columNumber)
{
return (lineNumber ? this.lineEndings()[lineNumber - 1] + 1 : 0) + columNumber;
},
/**
* @return {string}
*/
lineAt: function(lineNumber)
{
var lineEndings = this.lineEndings();
var lineStart = lineNumber > 0 ? lineEndings[lineNumber - 1] + 1 : 0;
var lineEnd = lineEndings[lineNumber];
var lineContent = this._value.substring(lineStart, lineEnd);
if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === "\r")
lineContent = lineContent.substring(0, lineContent.length - 1);
return lineContent;
},
/**
* @param {!WebInspector.TextRange} range
* @return {!WebInspector.SourceRange}
*/
toSourceRange: function(range)
{
var start = this.offsetFromPosition(range.startLine, range.startColumn);
var end = this.offsetFromPosition(range.endLine, range.endColumn);
return new WebInspector.SourceRange(start, end - start);
},
/**
* @param {!WebInspector.TextRange} range
* @param {string} replacement
* @return {string}
*/
replaceRange: function(range, replacement)
{
var sourceRange = this.toSourceRange(range);
return this._value.substring(0, sourceRange.offset) + replacement + this._value.substring(sourceRange.offset + sourceRange.length);
},
/**
* @param {!WebInspector.TextRange} range
* @return {string}
*/
extract: function(range)
{
var sourceRange = this.toSourceRange(range);
return this._value.substr(sourceRange.offset, sourceRange.length);
},
}
/**
* @constructor
* @param {!Array<number>} lineEndings
*/
WebInspector.TextCursor = function(lineEndings)
{
this._lineEndings = lineEndings;
this._offset = 0;
this._lineNumber = 0;
this._columnNumber = 0;
}
WebInspector.TextCursor.prototype = {
/**
* @param {number} offset
*/
advance: function(offset)
{
this._offset = offset;
while (this._lineNumber < this._lineEndings.length && this._lineEndings[this._lineNumber] < this._offset)
++this._lineNumber;
this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[this._lineNumber - 1] - 1 : this._offset;
},
/**
* @return {number}
*/
offset: function()
{
return this._offset;
},
/**
* @return {number}
*/
lineNumber: function()
{
return this._lineNumber;
},
/**
* @return {number}
*/
columnNumber: function()
{
return this._columnNumber;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 2 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.TextDictionary = function() { this._words = {}; } WebInspector.TextDictionary.prototype = { /** * @param {string} word */ addWord: function(word) { if (!this._words[word]) this._words[word] = 1; else ++this._words[word]; }, /** * @param {string} word */ removeWord: function(word) { if (!this._words[word]) return; if (this._words[word] === 1) delete this._words[word]; else --this._words[word]; }, /** * @param {string} prefix * @return {!Array.<string>} */ wordsWithPrefix: function(prefix) { var words = []; for(var i in this._words) { if (i.startsWith(prefix)) words.push(i); } return words; }, /** * @param {string} word * @return {boolean} */ hasWord: function(word) { return !!this._words[word]; }, /** * @param {string} word * @return {number} */ wordCount: function(word) { return this._words[word] ? this._words[word] : 0; }, reset: function() { this._words = {}; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | 2 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {number} startLine
* @param {number} startColumn
* @param {number} endLine
* @param {number} endColumn
*/
WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
{
this.startLine = startLine;
this.startColumn = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
}
/**
* @param {number} line
* @param {number} column
* @return {!WebInspector.TextRange}
*/
WebInspector.TextRange.createFromLocation = function(line, column)
{
return new WebInspector.TextRange(line, column, line, column);
}
/**
* @param {!Object} serializedTextRange
* @return {!WebInspector.TextRange}
*/
WebInspector.TextRange.fromObject = function(serializedTextRange)
{
return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
}
/**
* @param {!WebInspector.TextRange} range1
* @param {!WebInspector.TextRange} range2
* @return {number}
*/
WebInspector.TextRange.comparator = function(range1, range2)
{
return range1.compareTo(range2);
}
WebInspector.TextRange.prototype = {
/**
* @return {boolean}
*/
isEmpty: function()
{
return this.startLine === this.endLine && this.startColumn === this.endColumn;
},
/**
* @param {!WebInspector.TextRange} range
* @return {boolean}
*/
immediatelyPrecedes: function(range)
{
if (!range)
return false;
return this.endLine === range.startLine && this.endColumn === range.startColumn;
},
/**
* @param {!WebInspector.TextRange} range
* @return {boolean}
*/
immediatelyFollows: function(range)
{
if (!range)
return false;
return range.immediatelyPrecedes(this);
},
/**
* @param {!WebInspector.TextRange} range
* @return {boolean}
*/
follows: function(range)
{
return (range.endLine === this.startLine && range.endColumn <= this.startColumn)
|| range.endLine < this.startLine;
},
/**
* @return {number}
*/
get linesCount()
{
return this.endLine - this.startLine;
},
/**
* @return {!WebInspector.TextRange}
*/
collapseToEnd: function()
{
return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
},
/**
* @return {!WebInspector.TextRange}
*/
collapseToStart: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.startLine, this.startColumn);
},
/**
* @return {!WebInspector.TextRange}
*/
normalize: function()
{
if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
else
return this.clone();
},
/**
* @return {!WebInspector.TextRange}
*/
clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
},
/**
* @return {!{startLine: number, startColumn: number, endLine: number, endColumn: number}}
*/
serializeToObject: function()
{
var serializedTextRange = {};
serializedTextRange.startLine = this.startLine;
serializedTextRange.startColumn = this.startColumn;
serializedTextRange.endLine = this.endLine;
serializedTextRange.endColumn = this.endColumn;
return serializedTextRange;
},
/**
* @param {!WebInspector.TextRange} other
* @return {number}
*/
compareTo: function(other)
{
if (this.startLine > other.startLine)
return 1;
if (this.startLine < other.startLine)
return -1;
if (this.startColumn > other.startColumn)
return 1;
if (this.startColumn < other.startColumn)
return -1;
return 0;
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @return {number}
*/
compareToPosition: function(lineNumber, columnNumber)
{
if (lineNumber < this.startLine || (lineNumber === this.startLine && columnNumber < this.startColumn))
return -1;
if (lineNumber > this.endLine || (lineNumber === this.endLine && columnNumber > this.endColumn))
return 1;
return 0;
},
/**
* @param {!WebInspector.TextRange} other
* @return {boolean}
*/
equal: function(other)
{
return this.startLine === other.startLine && this.endLine === other.endLine &&
this.startColumn === other.startColumn && this.endColumn === other.endColumn;
},
/**
* @param {number} line
* @param {number} column
* @return {!WebInspector.TextRange}
*/
relativeTo: function(line, column)
{
var relative = this.clone();
if (this.startLine == line)
relative.startColumn -= column;
if (this.endLine == line)
relative.endColumn -= column;
relative.startLine -= line;
relative.endLine -= line;
return relative;
},
/**
* @param {!WebInspector.TextRange} originalRange
* @param {!WebInspector.TextRange} editedRange
* @return {!WebInspector.TextRange}
*/
rebaseAfterTextEdit: function(originalRange, editedRange)
{
console.assert(originalRange.startLine === editedRange.startLine);
console.assert(originalRange.startColumn === editedRange.startColumn);
var rebase = this.clone();
if (!this.follows(originalRange))
return rebase;
var lineDelta = editedRange.endLine - originalRange.endLine;
var columnDelta = editedRange.endColumn - originalRange.endColumn;
rebase.startLine += lineDelta;
rebase.endLine += lineDelta;
if (rebase.startLine === editedRange.endLine)
rebase.startColumn += columnDelta;
if (rebase.endLine === editedRange.endLine)
rebase.endColumn += columnDelta;
return rebase;
},
/**
* @override
* @return {string}
*/
toString: function()
{
return JSON.stringify(this);
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @return {boolean}
*/
containsLocation: function(lineNumber, columnNumber)
{
if (this.startLine === this.endLine)
return this.startLine === lineNumber && this.startColumn <= columnNumber && columnNumber <= this.endColumn;
if (this.startLine === lineNumber)
return this.startColumn <= columnNumber;
if (this.endLine === lineNumber)
return columnNumber <= this.endColumn;
return this.startLine < lineNumber && lineNumber < this.endLine;
}
}
/**
* @param {!WebInspector.TextRange} oldRange
* @param {string} newText
* @return {!WebInspector.TextRange}
*/
WebInspector.TextRange.fromEdit = function(oldRange, newText)
{
var endLine = oldRange.startLine;
var endColumn = oldRange.startColumn + newText.length;
var lineEndings = newText.computeLineEndings();
if (lineEndings.length > 1) {
endLine = oldRange.startLine + lineEndings.length - 1;
var len = lineEndings.length;
endColumn = lineEndings[len - 1] - lineEndings[len - 2] - 1;
}
return new WebInspector.TextRange(
oldRange.startLine,
oldRange.startColumn,
endLine,
endColumn);
}
/**
* @constructor
* @param {number} offset
* @param {number} length
*/
WebInspector.SourceRange = function(offset, length)
{
this.offset = offset;
this.length = length;
}
WebInspector.SourceRange.prototype = {
/**
* @param {!WebInspector.Text} text
* @return {!WebInspector.TextRange}
*/
toTextRange: function(text)
{
var p1 = fromOffset(text, this.offset);
var p2 = fromOffset(text, this.offset + this.length);
return new WebInspector.TextRange(p1.lineNumber, p1.columnNumber, p2.lineNumber, p2.columnNumber);
/**
* @param {!WebInspector.Text} text
* @param {number} offset
* @return {!{lineNumber: number, columnNumber: number}}
*/
function fromOffset(text, offset)
{
var lineEndings = text.lineEndings();
var lineNumber = lineEndings.lowerBound(offset);
var columnNumber = lineNumber === 0 ? offset : offset - lineEndings[lineNumber - 1] - 1;
return {lineNumber: lineNumber, columnNumber: columnNumber};
}
}
}
/**
* @constructor
* @param {string} sourceURL
* @param {!WebInspector.TextRange} oldRange
* @param {string} newText
*/
WebInspector.SourceEdit = function(sourceURL, oldRange, newText)
{
this.sourceURL = sourceURL;
this.oldRange = oldRange;
this.newText = newText;
}
WebInspector.SourceEdit.prototype = {
/**
* @return {!WebInspector.TextRange}
*/
newRange: function()
{
return WebInspector.TextRange.fromEdit(this.oldRange, this.newText);
},
}
/**
* @param {!WebInspector.SourceEdit} edit1
* @param {!WebInspector.SourceEdit} edit2
* @return {number}
*/
WebInspector.SourceEdit.comparator = function(edit1, edit2)
{
return WebInspector.TextRange.comparator(edit1.oldRange, edit2.oldRange);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.TextUtils = {
/**
* @param {string} char
* @return {boolean}
*/
isStopChar: function(char)
{
return (char > " " && char < "0") ||
(char > "9" && char < "A") ||
(char > "Z" && char < "_") ||
(char > "_" && char < "a") ||
(char > "z" && char <= "~");
},
/**
* @param {string} char
* @return {boolean}
*/
isWordChar: function(char)
{
return !WebInspector.TextUtils.isStopChar(char) && !WebInspector.TextUtils.isSpaceChar(char);
},
/**
* @param {string} char
* @return {boolean}
*/
isSpaceChar: function(char)
{
return WebInspector.TextUtils._SpaceCharRegex.test(char);
},
/**
* @param {string} word
* @return {boolean}
*/
isWord: function(word)
{
for (var i = 0; i < word.length; ++i) {
if (!WebInspector.TextUtils.isWordChar(word.charAt(i)))
return false;
}
return true;
},
/**
* @param {string} char
* @return {boolean}
*/
isOpeningBraceChar: function(char)
{
return char === "(" || char === "{";
},
/**
* @param {string} char
* @return {boolean}
*/
isClosingBraceChar: function(char)
{
return char === ")" || char === "}";
},
/**
* @param {string} char
* @return {boolean}
*/
isBraceChar: function(char)
{
return WebInspector.TextUtils.isOpeningBraceChar(char) || WebInspector.TextUtils.isClosingBraceChar(char);
},
/**
* @param {string} text
* @param {function(string):boolean} isWordChar
* @param {function(string)} wordCallback
*/
textToWords: function(text, isWordChar, wordCallback)
{
var startWord = -1;
for(var i = 0; i < text.length; ++i) {
if (!isWordChar(text.charAt(i))) {
if (startWord !== -1)
wordCallback(text.substring(startWord, i));
startWord = -1;
} else if (startWord === -1)
startWord = i;
}
if (startWord !== -1)
wordCallback(text.substring(startWord));
},
/**
* @param {string} line
* @return {string}
*/
lineIndent: function(line)
{
var indentation = 0;
while (indentation < line.length && WebInspector.TextUtils.isSpaceChar(line.charAt(indentation)))
++indentation;
return line.substr(0, indentation);
},
/**
* @param {string} text
* @return {boolean}
*/
isUpperCase: function(text)
{
return text === text.toUpperCase();
},
/**
* @param {string} text
* @return {boolean}
*/
isLowerCase: function(text)
{
return text === text.toLowerCase();
},
/**
* @param {string} text
* @param {string} delimiter
* @return {string}
*/
_lastSectionBeforeQuery: function(text, delimiter)
{
var lastIndexOfDot = text.lastIndexOf(delimiter);
var extension = lastIndexOfDot !== -1 ? text.substr(lastIndexOfDot + 1) : "";
var indexOfQuestionMark = extension.indexOf("?");
if (indexOfQuestionMark !== -1)
extension = extension.substr(0, indexOfQuestionMark);
return extension;
},
/**
* @param {string} text
* @return {string}
*/
extension: function(text)
{
return WebInspector.TextUtils._lastSectionBeforeQuery(text, ".");
},
/**
* @param {string} text
* @return {string}
*/
fileName: function(text)
{
return WebInspector.TextUtils._lastSectionBeforeQuery(text, "/");
}
}
WebInspector.TextUtils._SpaceCharRegex = /\s/;
/**
* @enum {string}
*/
WebInspector.TextUtils.Indent = {
TwoSpaces: " ",
FourSpaces: " ",
EightSpaces: " ",
TabCharacter: "\t"
}
/**
* @constructor
* @param {function(string)} callback
* @param {boolean=} findMultiple
*/
WebInspector.TextUtils.BalancedJSONTokenizer = function(callback, findMultiple)
{
this._callback = callback;
this._index = 0;
this._balance = 0;
this._buffer = "";
this._findMultiple = findMultiple || false;
this._closingDoubleQuoteRegex = /[^\\](?:\\\\)*"/g;
}
WebInspector.TextUtils.BalancedJSONTokenizer.prototype = {
/**
* @param {string} chunk
*/
write: function(chunk)
{
this._buffer += chunk;
var lastIndex = this._buffer.length;
var buffer = this._buffer;
for (var index = this._index; index < lastIndex; ++index) {
var character = buffer[index];
if (character === "\"") {
this._closingDoubleQuoteRegex.lastIndex = index;
if (!this._closingDoubleQuoteRegex.test(buffer))
break;
index = this._closingDoubleQuoteRegex.lastIndex - 1;
} else if (character === "{") {
++this._balance;
} else if (character === "}") {
if (--this._balance === 0) {
this._lastBalancedIndex = index + 1;
if (!this._findMultiple)
break;
}
}
}
this._index = index;
this._reportBalanced();
},
_reportBalanced: function()
{
if (!this._lastBalancedIndex)
return;
this._callback(this._buffer.slice(0, this._lastBalancedIndex));
this._buffer = this._buffer.slice(this._lastBalancedIndex);
this._index -= this._lastBalancedIndex;
this._lastBalancedIndex = 0;
},
/**
* @return {string}
*/
remainder: function()
{
return this._buffer;
}
}
/**
* @interface
*/
WebInspector.TokenizerFactory = function() { }
WebInspector.TokenizerFactory.prototype = {
/**
* @param {string} mimeType
* @return {function(string, function(string, ?string, number, number))}
*/
createTokenizer: function(mimeType) { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {number} timeout
*/
WebInspector.Throttler = function(timeout)
{
this._timeout = timeout;
this._isRunningProcess = false;
this._asSoonAsPossible = false;
/** @type {?function():(!Promise.<?>)} */
this._process = null;
}
WebInspector.Throttler.prototype = {
_processCompleted: function()
{
this._isRunningProcess = false;
if (this._process)
this._innerSchedule(false);
this._processCompletedForTests();
},
_processCompletedForTests: function()
{
// For sniffing in tests.
},
_onTimeout: function()
{
delete this._processTimeout;
this._asSoonAsPossible = false;
this._isRunningProcess = true;
Promise.resolve()
.then(this._process)
.catch(console.error.bind(console))
.then(this._processCompleted.bind(this));
this._process = null;
},
/**
* @param {function():(!Promise.<?>)} process
* @param {boolean=} asSoonAsPossible
*/
schedule: function(process, asSoonAsPossible)
{
// Deliberately skip previous process.
this._process = process;
// Run the first scheduled task instantly.
var hasScheduledTasks = !!this._processTimeout || this._isRunningProcess;
asSoonAsPossible = !!asSoonAsPossible || !hasScheduledTasks;
var forceTimerUpdate = asSoonAsPossible && !this._asSoonAsPossible;
this._asSoonAsPossible = this._asSoonAsPossible || asSoonAsPossible;
this._innerSchedule(forceTimerUpdate);
},
/**
* @param {boolean} forceTimerUpdate
*/
_innerSchedule: function(forceTimerUpdate)
{
if (this._isRunningProcess)
return;
if (this._processTimeout && !forceTimerUpdate)
return;
if (this._processTimeout)
this._clearTimeout(this._processTimeout);
var timeout = this._asSoonAsPossible ? 0 : this._timeout;
this._processTimeout = this._setTimeout(this._onTimeout.bind(this), timeout);
},
/**
* @param {number} timeoutId
*/
_clearTimeout: function(timeoutId)
{
clearTimeout(timeoutId);
},
/**
* @param {function()} operation
* @param {number} timeout
* @return {number}
*/
_setTimeout: function(operation, timeout)
{
return setTimeout(operation, timeout);
}
}
/** @typedef {function(!Error=)} */
WebInspector.Throttler.FinishCallback;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @param {string} string
* @param {...*} vararg
* @return {string}
*/
WebInspector.UIString = function(string, vararg)
{
return String.vsprintf(WebInspector.localize(string), Array.prototype.slice.call(arguments, 1));
}
/**
* @param {string} string
* @param {...*} vararg
* @return {string}
*/
WebInspector.UIString.capitalize = function(string, vararg)
{
if (WebInspector._useLowerCaseMenuTitles === undefined)
throw "WebInspector.setLocalizationPlatform() has not been called";
var localized = WebInspector.localize(string);
var capitalized;
if (WebInspector._useLowerCaseMenuTitles)
capitalized = localized.replace(/\^(.)/g, "$1");
else
capitalized = localized.replace(/\^(.)/g, function(str, char) { return char.toUpperCase(); });
return String.vsprintf(capitalized, Array.prototype.slice.call(arguments, 1));
}
/**
* @param {string} platform
*/
WebInspector.setLocalizationPlatform = function(platform)
{
WebInspector._useLowerCaseMenuTitles = platform === "windows";
}
/**
* @param {string} string
* @return {string}
*/
WebInspector.localize = function(string)
{
return string;
}
/**
* @constructor
* @param {string} format
*/
WebInspector.UIStringFormat = function(format)
{
/** @type {string} */
this._localizedFormat = WebInspector.localize(format);
/** @type {!Array.<!Object>} */
this._tokenizedFormat = String.tokenizeFormatString(this._localizedFormat, String.standardFormatters);
}
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
WebInspector.UIStringFormat._append = function(a, b)
{
return a + b;
}
WebInspector.UIStringFormat.prototype = {
/**
* @param {...*} vararg
* @return {string}
*/
format: function(vararg)
{
return String.format(this._localizedFormat, arguments,
String.standardFormatters, "", WebInspector.UIStringFormat._append, this._tokenizedFormat).formattedResult;
}
}
|
| 1 2 3 4 5 6 7 8 9 | 2 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
self.WebInspector = {}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var WorkerRuntime = {};
/**
* @param {string} moduleName
* @param {string} workerName
* @return {!Promise.<!SharedWorker>}
*/
WorkerRuntime.startSharedWorker = function(moduleName, workerName)
{
if (Runtime.isReleaseMode()) {
try {
var worker = new SharedWorker(moduleName + "_module.js", workerName);
return Promise.resolve(worker);
} catch (e) {
return Promise.reject(e);
}
}
return loadResourcePromise(moduleName + "/module.json").then(start, start.bind(null, undefined));
/**
* @param {string=} content
* @return {!SharedWorker}
*/
function start(content)
{
if (!content)
throw new Error("Worker is not defined: " + moduleName + " " + new Error().stack);
var scripts = JSON.parse(content)["scripts"];
if (scripts.length !== 1)
throw new Error("WorkerRuntime.startSharedWorker supports modules with only one script!");
return new SharedWorker(moduleName + "/" + scripts[0], workerName);
}
}
/**
* @param {string} moduleName
* @return {!Promise.<!Worker>}
*/
WorkerRuntime.startWorker = function(moduleName)
{
if (Runtime.isReleaseMode())
return Promise.resolve(new Worker(moduleName + "_module.js"));
/**
* @suppress {checkTypes}
*/
var loader = function() {
self.onmessage = function(event) {
self.onmessage = null;
var scripts = event.data;
for (var i = 0; i < scripts.length; ++i) {
var source = scripts[i]["source"];
self.eval(source + "\n//# sourceURL=" + scripts[i]["url"]);
}
};
};
return loadResourcePromise(moduleName + "/module.json").then(start, start.bind(null, undefined));
/**
* @param {string=} content
*/
function start(content)
{
if (!content)
throw new Error("Worker is not defined: " + moduleName + " " + new Error().stack);
var message = [];
var scripts = JSON.parse(content)["scripts"];
var promise = Promise.resolve();
for (var i = 0; i < scripts.length; ++i) {
var url = self._importScriptPathPrefix + moduleName + "/" + scripts[i];
var parts = url.split("://");
url = parts.length === 1 ? url : parts[0] + "://" + normalizePath(parts[1]);
promise = promise.then(promiseGetter(loadResourcePromise(moduleName + "/" + scripts[i]))).then(pushSource.bind(null, url), pushSource.bind(null, null, null));
}
return promise.then(createWorker);
function promiseGetter(promise)
{
return function() {
return promise;
};
}
/**
* @param {?string} url
* @param {?string} source
*/
function pushSource(url, source)
{
if (!url) {
console.error("Failed to load " + url);
return;
}
message.push({ source: source, url: url });
}
/**
* @return {!Worker}
*/
function createWorker()
{
var blob = new Blob(["(" + loader.toString() + ")()\n//# sourceURL=" + moduleName], { type: "text/javascript" });
var workerURL = window.URL.createObjectURL(blob);
try {
var worker = new Worker(workerURL);
worker.postMessage(message);
return worker;
} finally {
window.URL.revokeObjectURL(workerURL);
}
}
}
}
/**
* @constructor
* @param {string} moduleName
* @param {string=} workerName
*/
WorkerRuntime.Worker = function(moduleName, workerName)
{
this._workerPromise = workerName ? WorkerRuntime.startSharedWorker(moduleName, /** @type {string} */ (workerName)) : WorkerRuntime.startWorker(moduleName);
}
WorkerRuntime.Worker.prototype = {
/**
* @param {*} message
*/
postMessage: function(message)
{
this._workerPromise.then(postToWorker.bind(this));
/**
* @param {!Worker|!SharedWorker} worker
* @this {WorkerRuntime.Worker}
*/
function postToWorker(worker)
{
if (!this._disposed)
worker.postMessage(message);
}
},
dispose: function()
{
this._disposed = true;
this._workerPromise.then(terminate);
/**
* @param {!Worker|!SharedWorker} worker
*/
function terminate(worker)
{
worker.terminate();
}
},
terminate: function()
{
this.dispose();
},
/**
* @param {?function(!MessageEvent.<*>)} listener
*/
set onmessage(listener)
{
this._workerPromise.then(setOnMessage);
/**
* @param {!Worker|!SharedWorker} worker
*/
function setOnMessage(worker)
{
worker.onmessage = listener;
}
},
/**
* @param {?function(!Event)} listener
*/
set onerror(listener)
{
this._workerPromise.then(setOnError);
/**
* @param {!Worker|!SharedWorker} worker
*/
function setOnError(worker)
{
worker.onerror = listener;
}
},
get port()
{
return new WorkerRuntime.Worker.FuturePort(this);
}
}
/**
* @constructor
* @param {!WorkerRuntime.Worker} worker
*/
WorkerRuntime.Worker.FuturePort = function(worker)
{
this._worker = worker;
}
WorkerRuntime.Worker.FuturePort.prototype = {
/**
* @param {?function(!MessageEvent.<?>)} listener
*/
set onmessage(listener)
{
this._worker._workerPromise.then(setOnMessage);
/**
* @param {!SharedWorker} worker
*/
function setOnMessage(worker)
{
worker.port.onmessage = listener;
}
},
/**
* @param {?function(!Event)} listener
*/
set onerror(listener)
{
this._worker._workerPromise.then(setOnError);
/**
* @param {!SharedWorker} worker
*/
function setOnError(worker)
{
worker.port.onerror = listener;
}
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| BreakpointsSidebarPaneBase.js | 4.17% | (1 / 24) | 0% | (0 / 8) | 0% | (0 / 4) | 4.17% | (1 / 24) | |
| CustomPreviewSection.js | 3.6% | (4 / 111) | 0% | (0 / 47) | 0% | (0 / 16) | 3.6% | (4 / 111) | |
| DOMBreakpointsSidebarPane.js | 2.43% | (5 / 206) | 0% | (0 / 68) | 0% | (0 / 31) | 2.43% | (5 / 206) | |
| DOMPresentationUtils.js | 4.31% | (14 / 325) | 0% | (0 / 197) | 0% | (0 / 34) | 4.31% | (14 / 325) | |
| DataSaverInfobar.js | 6.67% | (1 / 15) | 0% | (0 / 2) | 0% | (0 / 3) | 6.67% | (1 / 15) | |
| DockController.js | 1.45% | (1 / 69) | 0% | (0 / 21) | 0% | (0 / 14) | 1.45% | (1 / 69) | |
| EventListenersUtils.js | 15.9% | (31 / 195) | 0% | (0 / 114) | 0% | (0 / 31) | 15.9% | (31 / 195) | |
| EventListenersView.js | 6.38% | (9 / 141) | 0% | (0 / 46) | 0% | (0 / 25) | 6.38% | (9 / 141) | |
| ExecutionContextModel.js | 3.03% | (2 / 66) | 0% | (0 / 28) | 0% | (0 / 14) | 3.03% | (2 / 66) | |
| ExecutionContextSelector.js | 2.82% | (2 / 71) | 0% | (0 / 44) | 0% | (0 / 11) | 2.82% | (2 / 71) | |
| HandlerRegistry.js | 4.63% | (5 / 108) | 0% | (0 / 47) | 0% | (0 / 24) | 4.63% | (5 / 108) | |
| Linkifier.js | 1.81% | (4 / 221) | 0% | (0 / 98) | 0% | (0 / 35) | 1.81% | (4 / 221) | |
| NetworkConditionsSelector.js | 4.72% | (10 / 212) | 0% | (0 / 64) | 0% | (0 / 29) | 4.72% | (10 / 212) | |
| ObjectPopoverHelper.js | 5.26% | (5 / 95) | 0% | (0 / 50) | 0% | (0 / 8) | 5.26% | (5 / 95) | |
| ObjectPropertiesSection.js | 3.47% | (21 / 606) | 0% | (0 / 318) | 0% | (0 / 78) | 3.47% | (21 / 606) | |
| Reload.js | 25% | (1 / 4) | 0% | (0 / 4) | 0% | (0 / 2) | 25% | (1 / 4) | |
| RemoteObjectPreviewFormatter.js | 3.7% | (3 / 81) | 0% | (0 / 64) | 0% | (0 / 9) | 3.7% | (3 / 81) | |
| RequestAppBannerActionDelegate.js | 14.29% | (1 / 7) | 0% | (0 / 4) | 0% | (0 / 2) | 14.29% | (1 / 7) | |
| ShortcutsScreen.js | 1.56% | (2 / 128) | 0% | (0 / 6) | 0% | (0 / 15) | 1.56% | (2 / 128) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {string} title
*/
WebInspector.BreakpointsSidebarPaneBase = function(title)
{
WebInspector.SidebarPane.call(this, title);
this.registerRequiredCSS("components/breakpointsList.css");
this.listElement = createElement("ol");
this.listElement.className = "breakpoint-list";
this.emptyElement = createElement("div");
this.emptyElement.className = "info";
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
this.element.appendChild(this.emptyElement);
}
WebInspector.BreakpointsSidebarPaneBase.prototype = {
/**
* @param {!Element} element
* @param {?Node=} beforeNode
* @protected
*/
addListElement: function(element, beforeNode)
{
if (beforeNode) {
this.listElement.insertBefore(element, beforeNode);
} else {
if (!this.listElement.firstChild) {
this.element.removeChild(this.emptyElement);
this.element.appendChild(this.listElement);
}
this.listElement.appendChild(element);
}
},
/**
* @param {!Element} element
* @protected
*/
removeListElement: function(element)
{
this.listElement.removeChild(element);
if (!this.listElement.firstChild) {
this.element.removeChild(this.listElement);
this.element.appendChild(this.emptyElement);
}
},
/**
* @protected
*/
reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.element.removeChild(this.listElement);
this.element.appendChild(this.emptyElement);
}
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | 2 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.RemoteObject} object
*/
WebInspector.CustomPreviewSection = function(object)
{
this._sectionElement = createElementWithClass("span", "custom-expandable-section");
this._object = object;
this._expanded = false;
this._cachedContent = null;
var customPreview = object.customPreview();
try {
var headerJSON = JSON.parse(customPreview.header);
} catch (e) {
WebInspector.console.error("Broken formatter: header is invalid json " + e);
return;
}
this._header = this._renderJSONMLTag(headerJSON);
if (this._header.nodeType === Node.TEXT_NODE) {
WebInspector.console.error("Broken formatter: header should be an element node.");
return;
}
if (customPreview.hasBody) {
this._header.classList.add("custom-expandable-section-header");
this._header.addEventListener("click", this._onClick.bind(this), false);
}
this._sectionElement.appendChild(this._header);
}
/**
* @constructor
* @param {!WebInspector.RemoteObject} object
*/
WebInspector.CustomPreviewComponent = function(object)
{
this._object = object;
this._customPreviewSection = new WebInspector.CustomPreviewSection(object);
this.element = createElementWithClass("span", "source-code");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "components/customPreviewSection.css");
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false);
shadowRoot.appendChild(this._customPreviewSection.element());
}
WebInspector.CustomPreviewComponent.prototype = {
expandIfPossible: function()
{
if (this._object.customPreview().hasBody && this._customPreviewSection)
this._customPreviewSection._loadBody();
},
/**
* @param {!Event} event
*/
_contextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
if (this._customPreviewSection)
contextMenu.appendItem(WebInspector.UIString.capitalize("Show as Javascript ^object" ), this._disassemble.bind(this));
contextMenu.appendApplicableItems(this._object);
contextMenu.show();
},
_disassemble: function()
{
this.element.shadowRoot.textContent = "";
this._customPreviewSection = null;
this.element.shadowRoot.appendChild(WebInspector.ObjectPropertiesSection.defaultObjectPresentation(this._object));
}
}
WebInspector.CustomPreviewSection._tagsWhiteList = new Set(["span", "div", "ol", "li","table", "tr", "td"]);
WebInspector.CustomPreviewSection.prototype = {
/**
* @return {!Element}
*/
element: function()
{
return this._sectionElement;
},
/**
* @param {*} jsonML
* @return {!Node}
*/
_renderJSONMLTag: function(jsonML)
{
if (!Array.isArray(jsonML))
return createTextNode(jsonML + "");
var array = /** @type {!Array.<*>} */(jsonML);
if (array[0] === "object")
return this._layoutObjectTag(array);
else
return this._renderElement(array);
},
/**
*
* @param {!Array.<*>} object
* @return {!Node}
*/
_renderElement: function(object)
{
var tagName = object.shift();
if (!WebInspector.CustomPreviewSection._tagsWhiteList.has(tagName)) {
WebInspector.console.error("Broken formatter: element " + tagName + " is not allowed!");
return createElement("span");
}
var element = createElement(/** @type {string} */ (tagName));
if ((typeof object[0] == "object") && !Array.isArray(object[0])) {
var attributes = object.shift();
for (var key in attributes) {
var value = attributes[key];
if ((key !== "style") || (typeof value !== "string"))
continue;
element.setAttribute(key, value);
}
}
this._appendJsonMLTags(element, object);
return element;
},
/**
* @param {!Array.<*>} objectTag
* @return {!Node}
*/
_layoutObjectTag: function(objectTag)
{
objectTag.shift();
var attributes = objectTag.shift();
var remoteObject = this._object.target().runtimeModel.createRemoteObject(/** @type {!RuntimeAgent.RemoteObject} */ (attributes));
if (remoteObject.customPreview())
return (new WebInspector.CustomPreviewSection(remoteObject)).element();
var sectionElement = WebInspector.ObjectPropertiesSection.defaultObjectPresentation(remoteObject);
sectionElement.classList.toggle("custom-expandable-section-standard-section", remoteObject.hasChildren);
return sectionElement;
},
/**
* @param {!Node} parentElement
* @param {!Array.<*>} jsonMLTags
*/
_appendJsonMLTags: function(parentElement, jsonMLTags)
{
for (var i = 0; i < jsonMLTags.length; ++i)
parentElement.appendChild(this._renderJSONMLTag(jsonMLTags[i]));
},
/**
* @param {!Event} event
*/
_onClick: function(event)
{
event.consume(true);
if (this._cachedContent)
this._toggleExpand();
else
this._loadBody();
},
_toggleExpand: function()
{
this._expanded = !this._expanded;
this._header.classList.toggle("expanded", this._expanded);
this._cachedContent.classList.toggle("hidden", !this._expanded);
},
_loadBody: function()
{
/**
* @suppressReceiverCheck
* @suppressGlobalPropertiesCheck
* @suppress {undefinedVars}
* @this {Object}
* @param {*=} formatter
* @param {*=} config
*/
function load(formatter, config)
{
/**
* @param {*} jsonMLObject
* @throws {string} error message
*/
function substituteObjectTagsInCustomPreview(jsonMLObject)
{
if (!jsonMLObject || (typeof jsonMLObject !== "object") || (typeof jsonMLObject.splice !== "function"))
return;
var obj = jsonMLObject.length;
if (!(typeof obj === "number" && obj >>> 0 === obj && (obj > 0 || 1 / obj > 0)))
return;
var startIndex = 1;
if (jsonMLObject[0] === "object") {
var attributes = jsonMLObject[1];
var originObject = attributes["object"];
var config = attributes["config"];
if (typeof originObject === "undefined")
throw "Illegal format: obligatory attribute \"object\" isn't specified";
jsonMLObject[1] = bindRemoteObject(originObject, false, false, null, false, config);
startIndex = 2;
}
for (var i = startIndex; i < jsonMLObject.length; ++i)
substituteObjectTagsInCustomPreview(jsonMLObject[i]);
}
try {
var body = formatter.body(this, config);
substituteObjectTagsInCustomPreview(body);
return body;
} catch (e) {
console.error("Custom Formatter Failed: " + e);
return null;
}
}
var customPreview = this._object.customPreview();
var args = [{objectId: customPreview.formatterObjectId}];
if (customPreview.configObjectId)
args.push({objectId: customPreview.configObjectId});
this._object.callFunctionJSON(load, args, onBodyLoaded.bind(this));
/**
* @param {*} bodyJsonML
* @this {WebInspector.CustomPreviewSection}
*/
function onBodyLoaded(bodyJsonML)
{
if (!bodyJsonML)
return;
this._cachedContent = this._renderJSONMLTag(bodyJsonML);
this._sectionElement.appendChild(this._cachedContent);
this._toggleExpand();
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | 2 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.BreakpointsSidebarPaneBase}
*/
WebInspector.DOMBreakpointsSidebarPane = function()
{
WebInspector.BreakpointsSidebarPaneBase.call(this, WebInspector.UIString("DOM Breakpoints"));
this._domBreakpointsSetting = WebInspector.settings.createLocalSetting("domBreakpoints", []);
this.listElement.classList.add("dom-breakpoints-list");
this._breakpointElements = {};
this._breakpointTypes = {
SubtreeModified: "subtree-modified",
AttributeModified: "attribute-modified",
NodeRemoved: "node-removed"
};
this._breakpointTypeLabels = {};
this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
this._contextMenuLabels = {};
this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString.capitalize("Subtree ^modifications");
this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString.capitalize("Attributes ^modifications");
this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString.capitalize("Node ^removal");
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
}
WebInspector.DOMBreakpointsSidebarPane.Marker = "breakpoint-marker";
WebInspector.DOMBreakpointsSidebarPane.prototype = {
_inspectedURLChanged: function(event)
{
this._breakpointElements = {};
this.reset();
var url = /** @type {string} */ (event.data);
this._inspectedURL = url.removeURLFragment();
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!WebInspector.ContextMenu} contextMenu
* @param {boolean} createSubMenu
*/
populateNodeContextMenu: function(node, contextMenu, createSubMenu)
{
if (node.pseudoType())
return;
var nodeBreakpoints = this._nodeBreakpoints(node);
/**
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
* @this {WebInspector.DOMBreakpointsSidebarPane}
*/
function toggleBreakpoint(type)
{
if (!nodeBreakpoints[type])
this._setBreakpoint(node, type, true);
else
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
var breakpointsMenu = createSubMenu ? contextMenu.appendSubMenuItem(WebInspector.UIString("Break on...")) : contextMenu;
for (var key in this._breakpointTypes) {
var type = this._breakpointTypes[key];
var label = this._contextMenuLabels[type];
breakpointsMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
}
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!Object<string, boolean>}
*/
_nodeBreakpoints: function(node)
{
var nodeBreakpoints = {};
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node && element._checkboxElement.checked)
nodeBreakpoints[element._type] = true;
}
return nodeBreakpoints;
},
/**
* @param {!WebInspector.DOMNode} node
* @return {boolean}
*/
hasBreakpoints: function(node)
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node && element._checkboxElement.checked)
return true;
}
return false;
},
/**
* @param {!WebInspector.DebuggerPausedDetails} details
* @param {function(!Element)} callback
*/
createBreakpointHitStatusMessage: function(details, callback)
{
var auxData = /** @type {!Object} */ (details.auxData);
var domModel = WebInspector.DOMModel.fromTarget(details.target());
if (!domModel)
return;
if (auxData.type === this._breakpointTypes.SubtreeModified) {
var targetNodeObject = details.target().runtimeModel.createRemoteObject(auxData["targetNode"]);
domModel.pushObjectAsNodeToFrontend(targetNodeObject, didPushNodeToFrontend.bind(this));
} else {
this._doCreateBreakpointHitStatusMessage(auxData, domModel.nodeForId(auxData.nodeId), null, callback);
}
/**
* @param {?WebInspector.DOMNode} targetNode
* @this {WebInspector.DOMBreakpointsSidebarPane}
*/
function didPushNodeToFrontend(targetNode)
{
if (targetNode)
targetNodeObject.release();
this._doCreateBreakpointHitStatusMessage(auxData, domModel.nodeForId(auxData.nodeId), targetNode, callback);
}
},
/**
* @param {!Object} auxData
* @param {?WebInspector.DOMNode} node
* @param {?WebInspector.DOMNode} targetNode
* @param {function(!Element)} callback
*/
_doCreateBreakpointHitStatusMessage: function(auxData, node, targetNode, callback)
{
var message;
var typeLabel = this._breakpointTypeLabels[auxData.type];
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
var substitutions = [typeLabel, linkifiedNode];
var targetNodeLink = "";
if (targetNode)
targetNodeLink = WebInspector.DOMPresentationUtils.linkifyNodeReference(targetNode);
if (auxData.type === this._breakpointTypes.SubtreeModified) {
if (auxData.insertion) {
if (targetNode !== node) {
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
substitutions.push(targetNodeLink);
} else
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
} else {
message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
substitutions.push(targetNodeLink);
}
} else
message = "Paused on a \"%s\" breakpoint set on %s.";
var element = WebInspector.formatLocalized(message, substitutions);
callback(element);
},
_nodeRemoved: function(event)
{
var node = event.data.node;
this._removeBreakpointsForNode(event.data.node);
var children = node.children();
if (!children)
return;
for (var i = 0; i < children.length; ++i)
this._removeBreakpointsForNode(children[i]);
this._saveBreakpoints();
},
/**
* @param {!WebInspector.DOMNode} node
*/
_removeBreakpointsForNode: function(node)
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
this._removeBreakpoint(element._node, element._type);
}
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
* @param {boolean} enabled
*/
_setBreakpoint: function(node, type, enabled)
{
var breakpointId = this._createBreakpointId(node.id, type);
var breakpointElement = this._breakpointElements[breakpointId];
if (!breakpointElement) {
breakpointElement = this._createBreakpointElement(node, type, enabled);
this._breakpointElements[breakpointId] = breakpointElement;
} else {
breakpointElement._checkboxElement.checked = enabled;
}
if (enabled)
node.target().domdebuggerAgent().setDOMBreakpoint(node.id, type);
node.setMarker(WebInspector.DOMBreakpointsSidebarPane.Marker, true);
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
* @param {boolean} enabled
*/
_createBreakpointElement: function(node, type, enabled)
{
var element = createElement("li");
element._node = node;
element._type = type;
element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);
var checkboxLabel = createCheckboxLabel("", enabled);
checkboxLabel.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
element._checkboxElement = checkboxLabel.checkboxElement;
element.appendChild(checkboxLabel);
var labelElement = createElementWithClass("div", "dom-breakpoint");
element.appendChild(labelElement);
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
linkifiedNode.classList.add("monospace");
linkifiedNode.style.display = "block";
labelElement.appendChild(linkifiedNode);
var description = createElement("div");
description.textContent = this._breakpointTypeLabels[type];
labelElement.appendChild(description);
var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._type && currentElement._type < element._type)
break;
currentElement = currentElement.nextSibling;
}
this.addListElement(element, currentElement);
return element;
},
_removeAllBreakpoints: function()
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
this._removeBreakpoint(element._node, element._type);
}
this._saveBreakpoints();
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
*/
_removeBreakpoint: function(node, type)
{
var breakpointId = this._createBreakpointId(node.id, type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this.removeListElement(element);
delete this._breakpointElements[breakpointId];
if (element._checkboxElement.checked)
node.target().domdebuggerAgent().removeDOMBreakpoint(node.id, type);
node.setMarker(WebInspector.DOMBreakpointsSidebarPane.Marker, this.hasBreakpoints(node) ? true : null);
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
* @param {!Event} event
*/
_contextMenu: function(node, type, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
/**
* @this {WebInspector.DOMBreakpointsSidebarPane}
*/
function removeBreakpoint()
{
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"), removeBreakpoint.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all DOM breakpoints"), this._removeAllBreakpoints.bind(this));
contextMenu.show();
},
/**
* @param {!WebInspector.DOMNode} node
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
* @param {!Event} event
*/
_checkboxClicked: function(node, type, event)
{
if (event.target.checked)
node.target().domdebuggerAgent().setDOMBreakpoint(node.id, type);
else
node.target().domdebuggerAgent().removeDOMBreakpoint(node.id, type);
this._saveBreakpoints();
},
highlightBreakpoint: function(auxData)
{
var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this.expand();
element.classList.add("breakpoint-hit");
this._highlightedElement = element;
},
clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.classList.remove("breakpoint-hit");
delete this._highlightedElement;
}
},
/**
* @param {number} nodeId
* @param {!DOMDebuggerAgent.DOMBreakpointType} type
*/
_createBreakpointId: function(nodeId, type)
{
return nodeId + ":" + type;
},
_saveBreakpoints: function()
{
var breakpoints = [];
var storedBreakpoints = this._domBreakpointsSetting.get();
for (var i = 0; i < storedBreakpoints.length; ++i) {
var breakpoint = storedBreakpoints[i];
if (breakpoint.url !== this._inspectedURL)
breakpoints.push(breakpoint);
}
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
}
this._domBreakpointsSetting.set(breakpoints);
},
/**
* @param {!WebInspector.DOMModel} domModel
*/
restoreBreakpoints: function(domModel)
{
var pathToBreakpoints = {};
/**
* @param {string} path
* @param {?DOMAgent.NodeId} nodeId
* @this {WebInspector.DOMBreakpointsSidebarPane}
*/
function didPushNodeByPathToFrontend(path, nodeId)
{
var node = nodeId ? domModel.nodeForId(nodeId) : null;
if (!node)
return;
var breakpoints = pathToBreakpoints[path];
for (var i = 0; i < breakpoints.length; ++i)
this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
}
var breakpoints = this._domBreakpointsSetting.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint.url !== this._inspectedURL)
continue;
var path = breakpoint.path;
if (!pathToBreakpoints[path]) {
pathToBreakpoints[path] = [];
domModel.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
pathToBreakpoints[path].push(breakpoint);
}
},
/**
* @param {!WebInspector.Panel} panel
* @return {!WebInspector.DOMBreakpointsSidebarPane.Proxy}
*/
createProxy: function(panel)
{
var proxy = new WebInspector.DOMBreakpointsSidebarPane.Proxy(this, panel);
if (!this._proxies)
this._proxies = [];
this._proxies.push(proxy);
return proxy;
},
onContentReady: function()
{
for (var i = 0; i != this._proxies.length; i++)
this._proxies[i].onContentReady();
},
__proto__: WebInspector.BreakpointsSidebarPaneBase.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {!WebInspector.DOMBreakpointsSidebarPane} pane
* @param {!WebInspector.Panel} panel
*/
WebInspector.DOMBreakpointsSidebarPane.Proxy = function(pane, panel)
{
WebInspector.SidebarPane.call(this, pane.title());
this.registerRequiredCSS("components/breakpointsList.css");
this._wrappedPane = pane;
this._panel = panel;
}
WebInspector.DOMBreakpointsSidebarPane.Proxy.prototype = {
expand: function()
{
this._wrappedPane.expand();
},
onContentReady: function()
{
if (this._panel.isShowing())
this._reattachBody();
WebInspector.SidebarPane.prototype.onContentReady.call(this);
},
wasShown: function()
{
WebInspector.SidebarPane.prototype.wasShown.call(this);
this._reattachBody();
},
_reattachBody: function()
{
if (this._wrappedPane.element.parentNode !== this.element)
this._wrappedPane.show(this.element);
},
__proto__: WebInspector.SidebarPane.prototype
}
/**
* @type {!WebInspector.DOMBreakpointsSidebarPane}
*/
WebInspector.domBreakpointsSidebarPane;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.DOMPresentationUtils = {}
/**
* @param {!WebInspector.DOMNode} node
* @param {!Element} parentElement
*/
WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
{
var originalNode = node;
var isPseudo = node.nodeType() === Node.ELEMENT_NODE && node.pseudoType();
if (isPseudo && node.parentNode)
node = node.parentNode;
var title = node.nodeNameInCorrectCase();
var nameElement = parentElement.createChild("span", "node-label-name");
nameElement.textContent = title;
var idAttribute = node.getAttribute("id");
if (idAttribute) {
var idElement = parentElement.createChild("span", "node-label-id");
var part = "#" + idAttribute;
title += part;
idElement.createTextChild(part);
// Mark the name as extra, since the ID is more important.
nameElement.classList.add("extra");
}
var classAttribute = node.getAttribute("class");
if (classAttribute) {
var classes = classAttribute.split(/\s+/);
var foundClasses = {};
if (classes.length) {
var classesElement = parentElement.createChild("span", "extra node-label-class");
for (var i = 0; i < classes.length; ++i) {
var className = classes[i];
if (className && !(className in foundClasses)) {
var part = "." + className;
title += part;
classesElement.createTextChild(part);
foundClasses[className] = true;
}
}
}
}
if (isPseudo) {
var pseudoElement = parentElement.createChild("span", "extra node-label-pseudo");
var pseudoText = "::" + originalNode.pseudoType();
pseudoElement.createTextChild(pseudoText);
title += pseudoText;
}
parentElement.title = title;
}
/**
* @param {!Element} container
* @param {string} nodeTitle
*/
WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle)
{
var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
container.createChild("span", "webkit-html-tag-name").textContent = match[1];
if (match[2])
container.createChild("span", "webkit-html-attribute-value").textContent = match[2];
if (match[3])
container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
}
/**
* @param {?WebInspector.DOMNode} node
* @param {string=} idref
* @return {!Node}
*/
WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node, idref)
{
if (!node)
return createTextNode(WebInspector.UIString("<node>"));
var root = createElementWithClass("span", "monospace");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, "components/domUtils.css");
var link = shadowRoot.createChild("div", "node-link");
if (idref)
link.createChild("span", "node-label-id").createTextChild("#" + idref);
else
WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
link.addEventListener("click", WebInspector.Revealer.reveal.bind(WebInspector.Revealer, node, undefined), false);
link.addEventListener("mouseover", node.highlight.bind(node, undefined, undefined), false);
link.addEventListener("mouseleave", WebInspector.DOMModel.hideDOMNodeHighlight.bind(WebInspector.DOMModel), false);
return root;
}
/**
* @param {!WebInspector.DeferredDOMNode} deferredNode
* @return {!Node}
*/
WebInspector.DOMPresentationUtils.linkifyDeferredNodeReference = function(deferredNode)
{
var root = createElement("div");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, "components/domUtils.css");
var link = shadowRoot.createChild("div", "node-link");
link.createChild("content");
link.addEventListener("click", deferredNode.resolve.bind(deferredNode, onDeferredNodeResolved), false);
link.addEventListener("mousedown", consumeEvent, false);
/**
* @param {?WebInspector.DOMNode} node
*/
function onDeferredNodeResolved(node)
{
WebInspector.Revealer.reveal(node);
}
return root;
}
/**
* @param {!WebInspector.Target} target
* @param {string} originalImageURL
* @param {boolean} showDimensions
* @param {function(!Element=)} userCallback
* @param {!Object=} precomputedFeatures
*/
WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(target, originalImageURL, showDimensions, userCallback, precomputedFeatures)
{
var resource = target.resourceTreeModel.resourceForURL(originalImageURL);
var imageURL = originalImageURL;
if (!isImageResource(resource) && precomputedFeatures && precomputedFeatures.currentSrc) {
imageURL = precomputedFeatures.currentSrc;
resource = target.resourceTreeModel.resourceForURL(imageURL);
}
if (!isImageResource(resource)) {
userCallback();
return;
}
var imageElement = createElement("img");
imageElement.addEventListener("load", buildContent, false);
imageElement.addEventListener("error", errorCallback, false);
resource.populateImageSource(imageElement);
function errorCallback()
{
// Drop the event parameter when invoking userCallback.
userCallback();
}
/**
* @param {?WebInspector.Resource} resource
* @return {boolean}
*/
function isImageResource(resource)
{
return !!resource && resource.resourceType() === WebInspector.resourceTypes.Image;
}
function buildContent()
{
var container = createElement("table");
container.className = "image-preview-container";
var naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth;
var naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight;
var offsetWidth = precomputedFeatures ? precomputedFeatures.offsetWidth : naturalWidth;
var offsetHeight = precomputedFeatures ? precomputedFeatures.offsetHeight : naturalHeight;
var description;
if (showDimensions) {
if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
else
description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
}
container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
if (description)
container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
if (imageURL !== originalImageURL)
container.createChild("tr").createChild("td").createChild("span", "description").textContent = String.sprintf("currentSrc: %s", imageURL.trimMiddle(100));
userCallback(container);
}
}
/**
* @param {!WebInspector.Target} target
* @param {!WebInspector.Linkifier} linkifier
* @param {!RuntimeAgent.StackTrace=} stackTrace
* @return {!Element}
*/
WebInspector.DOMPresentationUtils.buildStackTracePreviewContents = function(target, linkifier, stackTrace)
{
var element = createElement("span");
element.style.display = "inline-block";
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(element, "components/domUtils.css");
var contentElement = shadowRoot.createChild("table", "stack-preview-container");
/**
* @param {!RuntimeAgent.StackTrace} stackTrace
*/
function appendStackTrace(stackTrace)
{
for (var stackFrame of stackTrace.callFrames) {
var row = createElement("tr");
row.createChild("td", "function-name").textContent = WebInspector.beautifyFunctionName(stackFrame.functionName);
row.createChild("td").textContent = " @ ";
row.createChild("td").appendChild(linkifier.linkifyConsoleCallFrame(target, stackFrame));
contentElement.appendChild(row);
}
}
if (!stackTrace)
return element;
appendStackTrace(stackTrace);
var asyncStackTrace = stackTrace.parent;
while (asyncStackTrace) {
if (!asyncStackTrace.callFrames.length) {
asyncStackTrace = asyncStackTrace.parent;
continue;
}
var row = contentElement.createChild("tr");
row.createChild("td", "stack-preview-async-description").textContent = WebInspector.asyncStackTraceLabel(asyncStackTrace.description);
row.createChild("td");
row.createChild("td");
appendStackTrace(asyncStackTrace);
asyncStackTrace = asyncStackTrace.parent;
}
return element;
}
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} justSelector
* @return {string}
*/
WebInspector.DOMPresentationUtils.fullQualifiedSelector = function(node, justSelector)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return node.localName() || node.nodeName().toLowerCase();
return WebInspector.DOMPresentationUtils.cssPath(node, justSelector);
}
/**
* @param {!WebInspector.DOMNode} node
* @return {string}
*/
WebInspector.DOMPresentationUtils.simpleSelector = function(node)
{
var lowerCaseName = node.localName() || node.nodeName().toLowerCase();
if (node.nodeType() !== Node.ELEMENT_NODE)
return lowerCaseName;
if (lowerCaseName === "input" && node.getAttribute("type") && !node.getAttribute("id") && !node.getAttribute("class"))
return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
if (node.getAttribute("id"))
return lowerCaseName + "#" + node.getAttribute("id");
if (node.getAttribute("class"))
return (lowerCaseName === "div" ? "" : lowerCaseName) + "." + node.getAttribute("class").trim().replace(/\s+/g, ".");
return lowerCaseName;
}
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} optimized
* @return {string}
*/
WebInspector.DOMPresentationUtils.cssPath = function(node, optimized)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return "";
var steps = [];
var contextNode = node;
while (contextNode) {
var step = WebInspector.DOMPresentationUtils._cssPathStep(contextNode, !!optimized, contextNode === node);
if (!step)
break; // Error - bail out early.
steps.push(step);
if (step.optimized)
break;
contextNode = contextNode.parentNode;
}
steps.reverse();
return steps.join(" > ");
}
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean} optimized
* @param {boolean} isTargetNode
* @return {?WebInspector.DOMNodePathStep}
*/
WebInspector.DOMPresentationUtils._cssPathStep = function(node, optimized, isTargetNode)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
var id = node.getAttribute("id");
if (optimized) {
if (id)
return new WebInspector.DOMNodePathStep(idSelector(id), true);
var nodeNameLower = node.nodeName().toLowerCase();
if (nodeNameLower === "body" || nodeNameLower === "head" || nodeNameLower === "html")
return new WebInspector.DOMNodePathStep(node.nodeNameInCorrectCase(), true);
}
var nodeName = node.nodeNameInCorrectCase();
if (id)
return new WebInspector.DOMNodePathStep(nodeName + idSelector(id), true);
var parent = node.parentNode;
if (!parent || parent.nodeType() === Node.DOCUMENT_NODE)
return new WebInspector.DOMNodePathStep(nodeName, true);
/**
* @param {!WebInspector.DOMNode} node
* @return {!Array.<string>}
*/
function prefixedElementClassNames(node)
{
var classAttribute = node.getAttribute("class");
if (!classAttribute)
return [];
return classAttribute.split(/\s+/g).filter(Boolean).map(function(name) {
// The prefix is required to store "__proto__" in a object-based map.
return "$" + name;
});
}
/**
* @param {string} id
* @return {string}
*/
function idSelector(id)
{
return "#" + escapeIdentifierIfNeeded(id);
}
/**
* @param {string} ident
* @return {string}
*/
function escapeIdentifierIfNeeded(ident)
{
if (isCSSIdentifier(ident))
return ident;
var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);
var lastIndex = ident.length - 1;
return ident.replace(/./g, function(c, i) {
return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? escapeAsciiChar(c, i === lastIndex) : c;
});
}
/**
* @param {string} c
* @param {boolean} isLast
* @return {string}
*/
function escapeAsciiChar(c, isLast)
{
return "\\" + toHexByte(c) + (isLast ? "" : " ");
}
/**
* @param {string} c
*/
function toHexByte(c)
{
var hexByte = c.charCodeAt(0).toString(16);
if (hexByte.length === 1)
hexByte = "0" + hexByte;
return hexByte;
}
/**
* @param {string} c
* @return {boolean}
*/
function isCSSIdentChar(c)
{
if (/[a-zA-Z0-9_-]/.test(c))
return true;
return c.charCodeAt(0) >= 0xA0;
}
/**
* @param {string} value
* @return {boolean}
*/
function isCSSIdentifier(value)
{
return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);
}
var prefixedOwnClassNamesArray = prefixedElementClassNames(node);
var needsClassNames = false;
var needsNthChild = false;
var ownIndex = -1;
var elementIndex = -1;
var siblings = parent.children();
for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {
var sibling = siblings[i];
if (sibling.nodeType() !== Node.ELEMENT_NODE)
continue;
elementIndex += 1;
if (sibling === node) {
ownIndex = elementIndex;
continue;
}
if (needsNthChild)
continue;
if (sibling.nodeNameInCorrectCase() !== nodeName)
continue;
needsClassNames = true;
var ownClassNames = prefixedOwnClassNamesArray.keySet();
var ownClassNameCount = 0;
for (var name in ownClassNames)
++ownClassNameCount;
if (ownClassNameCount === 0) {
needsNthChild = true;
continue;
}
var siblingClassNamesArray = prefixedElementClassNames(sibling);
for (var j = 0; j < siblingClassNamesArray.length; ++j) {
var siblingClass = siblingClassNamesArray[j];
if (!ownClassNames.hasOwnProperty(siblingClass))
continue;
delete ownClassNames[siblingClass];
if (!--ownClassNameCount) {
needsNthChild = true;
break;
}
}
}
var result = nodeName;
if (isTargetNode && nodeName.toLowerCase() === "input" && node.getAttribute("type") && !node.getAttribute("id") && !node.getAttribute("class"))
result += "[type=\"" + node.getAttribute("type") + "\"]";
if (needsNthChild) {
result += ":nth-child(" + (ownIndex + 1) + ")";
} else if (needsClassNames) {
for (var prefixedName in prefixedOwnClassNamesArray.keySet())
result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));
}
return new WebInspector.DOMNodePathStep(result, false);
}
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} optimized
* @return {string}
*/
WebInspector.DOMPresentationUtils.xPath = function(node, optimized)
{
if (node.nodeType() === Node.DOCUMENT_NODE)
return "/";
var steps = [];
var contextNode = node;
while (contextNode) {
var step = WebInspector.DOMPresentationUtils._xPathValue(contextNode, optimized);
if (!step)
break; // Error - bail out early.
steps.push(step);
if (step.optimized)
break;
contextNode = contextNode.parentNode;
}
steps.reverse();
return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/");
}
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} optimized
* @return {?WebInspector.DOMNodePathStep}
*/
WebInspector.DOMPresentationUtils._xPathValue = function(node, optimized)
{
var ownValue;
var ownIndex = WebInspector.DOMPresentationUtils._xPathIndex(node);
if (ownIndex === -1)
return null; // Error.
switch (node.nodeType()) {
case Node.ELEMENT_NODE:
if (optimized && node.getAttribute("id"))
return new WebInspector.DOMNodePathStep("//*[@id=\"" + node.getAttribute("id") + "\"]", true);
ownValue = node.localName();
break;
case Node.ATTRIBUTE_NODE:
ownValue = "@" + node.nodeName();
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
ownValue = "text()";
break;
case Node.PROCESSING_INSTRUCTION_NODE:
ownValue = "processing-instruction()";
break;
case Node.COMMENT_NODE:
ownValue = "comment()";
break;
case Node.DOCUMENT_NODE:
ownValue = "";
break;
default:
ownValue = "";
break;
}
if (ownIndex > 0)
ownValue += "[" + ownIndex + "]";
return new WebInspector.DOMNodePathStep(ownValue, node.nodeType() === Node.DOCUMENT_NODE);
}
/**
* @param {!WebInspector.DOMNode} node
* @return {number}
*/
WebInspector.DOMPresentationUtils._xPathIndex = function(node)
{
// Returns -1 in case of error, 0 if no siblings matching the same expression, <XPath index among the same expression-matching sibling nodes> otherwise.
function areNodesSimilar(left, right)
{
if (left === right)
return true;
if (left.nodeType() === Node.ELEMENT_NODE && right.nodeType() === Node.ELEMENT_NODE)
return left.localName() === right.localName();
if (left.nodeType() === right.nodeType())
return true;
// XPath treats CDATA as text nodes.
var leftType = left.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left.nodeType();
var rightType = right.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right.nodeType();
return leftType === rightType;
}
var siblings = node.parentNode ? node.parentNode.children() : null;
if (!siblings)
return 0; // Root node - no siblings.
var hasSameNamedElements;
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) {
hasSameNamedElements = true;
break;
}
}
if (!hasSameNamedElements)
return 0;
var ownIndex = 1; // XPath indices start with 1.
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(node, siblings[i])) {
if (siblings[i] === node)
return ownIndex;
++ownIndex;
}
}
return -1; // An error occurred: |node| not found in parent's children.
}
/**
* @constructor
* @param {string} value
* @param {boolean} optimized
*/
WebInspector.DOMNodePathStep = function(value, optimized)
{
this.value = value;
this.optimized = optimized || false;
}
WebInspector.DOMNodePathStep.prototype = {
/**
* @override
* @return {string}
*/
toString: function()
{
return this.value;
}
}
/**
* @interface
*/
WebInspector.DOMPresentationUtils.MarkerDecorator = function()
{
}
WebInspector.DOMPresentationUtils.MarkerDecorator.prototype = {
/**
* @param {!WebInspector.DOMNode} node
* @return {?{title: string, color: string}}
*/
decorate: function(node) { }
}
/**
* @constructor
* @implements {WebInspector.DOMPresentationUtils.MarkerDecorator}
* @param {!Runtime.Extension} extension
*/
WebInspector.DOMPresentationUtils.GenericDecorator = function(extension)
{
this._title = WebInspector.UIString(extension.title(WebInspector.platform()));
this._color = extension.descriptor()['color'];
}
WebInspector.DOMPresentationUtils.GenericDecorator.prototype = {
/**
* @override
* @param {!WebInspector.DOMNode} node
* @return {?{title: string, color: string}}
*/
decorate: function(node)
{
return { title: this._title, color: this._color };
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Infobar}
*/
WebInspector.DataSaverInfobar = function()
{
WebInspector.Infobar.call(this, WebInspector.Infobar.Type.Warning, WebInspector.UIString("Consider disabling Chrome Data Saver while debugging."), WebInspector.settings.moduleSetting("disableDataSaverInfobar"));
var message = this.createDetailsRowMessage();
message.createTextChild("More information about ");
message.appendChild(WebInspector.linkifyURLAsNode("https://support.google.com/chrome/answer/2392284?hl=en", "Chrome Data Saver", undefined, true));
message.createTextChild(".");
}
WebInspector.DataSaverInfobar._infobars = [];
/**
* @param {!WebInspector.Panel} panel
*/
WebInspector.DataSaverInfobar.maybeShowInPanel = function(panel)
{
if (Runtime.queryParam("remoteFrontend")) {
var infobar = new WebInspector.DataSaverInfobar();
WebInspector.DataSaverInfobar._infobars.push(infobar);
panel.showInfobar(infobar);
}
}
WebInspector.DataSaverInfobar.prototype = {
/**
* @override
*/
dispose: function()
{
for (var infobar of WebInspector.DataSaverInfobar._infobars)
WebInspector.Infobar.prototype.dispose.call(infobar);
},
__proto__: WebInspector.Infobar.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {boolean} canDock
*/
WebInspector.DockController = function(canDock)
{
this._canDock = canDock;
this._closeButton = new WebInspector.ToolbarButton(WebInspector.UIString("Close"), "delete-toolbar-item");
this._closeButton.addEventListener("click", InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost));
if (!canDock) {
this._dockSide = WebInspector.DockController.State.Undocked;
this._updateUI();
return;
}
this._states = [WebInspector.DockController.State.DockedToRight, WebInspector.DockController.State.DockedToBottom, WebInspector.DockController.State.Undocked];
this._currentDockStateSetting = WebInspector.settings.moduleSetting("currentDockState");
this._currentDockStateSetting.addChangeListener(this._dockSideChanged, this);
this._lastDockStateSetting = WebInspector.settings.createSetting("lastDockState", "bottom");
if (this._states.indexOf(this._currentDockStateSetting.get()) === -1)
this._currentDockStateSetting.set("right");
if (this._states.indexOf(this._lastDockStateSetting.get()) === -1)
this._currentDockStateSetting.set("bottom");
}
WebInspector.DockController.State = {
DockedToBottom: "bottom",
DockedToRight: "right",
Undocked: "undocked"
}
// Use BeforeDockSideChanged to do something before all the UI bits are updated,
// DockSideChanged to update UI, and AfterDockSideChanged to perform actions
// after frontend is docked/undocked in the browser.
WebInspector.DockController.Events = {
BeforeDockSideChanged: "BeforeDockSideChanged",
DockSideChanged: "DockSideChanged",
AfterDockSideChanged: "AfterDockSideChanged"
}
WebInspector.DockController.prototype = {
initialize: function()
{
if (!this._canDock)
return;
this._titles = [WebInspector.UIString("Dock to right"), WebInspector.UIString("Dock to bottom"), WebInspector.UIString("Undock into separate window")];
this._dockSideChanged();
},
_dockSideChanged: function()
{
this.setDockSide(this._currentDockStateSetting.get());
},
/**
* @return {string}
*/
dockSide: function()
{
return this._dockSide;
},
/**
* @return {boolean}
*/
canDock: function()
{
return this._canDock;
},
/**
* @return {boolean}
*/
isVertical: function()
{
return this._dockSide === WebInspector.DockController.State.DockedToRight;
},
/**
* @param {string} dockSide
*/
setDockSide: function(dockSide)
{
if (this._states.indexOf(dockSide) === -1)
dockSide = this._states[0];
if (this._dockSide === dockSide)
return;
if (this._dockSide)
this._lastDockStateSetting.set(this._dockSide);
var eventData = { from: this._dockSide, to: dockSide };
this.dispatchEventToListeners(WebInspector.DockController.Events.BeforeDockSideChanged, eventData);
console.timeStamp("DockController.setIsDocked");
this._dockSide = dockSide;
this._currentDockStateSetting.set(dockSide);
InspectorFrontendHost.setIsDocked(dockSide !== WebInspector.DockController.State.Undocked, this._setIsDockedResponse.bind(this, eventData));
this._updateUI();
this.dispatchEventToListeners(WebInspector.DockController.Events.DockSideChanged, eventData);
},
/**
* @param {{from: string, to: string}} eventData
*/
_setIsDockedResponse: function(eventData)
{
this.dispatchEventToListeners(WebInspector.DockController.Events.AfterDockSideChanged, eventData);
},
/**
* @suppressGlobalPropertiesCheck
*/
_updateUI: function()
{
var body = document.body; // Only for main window.
switch (this._dockSide) {
case WebInspector.DockController.State.DockedToBottom:
body.classList.remove("undocked");
body.classList.remove("dock-to-right");
body.classList.add("dock-to-bottom");
break;
case WebInspector.DockController.State.DockedToRight:
body.classList.remove("undocked");
body.classList.add("dock-to-right");
body.classList.remove("dock-to-bottom");
break;
case WebInspector.DockController.State.Undocked:
body.classList.add("undocked");
body.classList.remove("dock-to-right");
body.classList.remove("dock-to-bottom");
break;
}
this._closeButton.setVisible(this._dockSide !== WebInspector.DockController.State.Undocked);
},
_toggleDockSide: function()
{
if (this._lastDockStateSetting.get() === this._currentDockStateSetting.get()) {
var index = this._states.indexOf(this._currentDockStateSetting.get()) || 0;
this._lastDockStateSetting.set(this._states[(index + 1) % this._states.length]);
}
this.setDockSide(this._lastDockStateSetting.get());
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.DockController.ToggleDockActionDelegate = function()
{
}
WebInspector.DockController.ToggleDockActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
WebInspector.dockController._toggleDockSide();
return true;
}
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.DockController.CloseButtonProvider = function()
{
}
WebInspector.DockController.CloseButtonProvider.prototype = {
/**
* @override
* @return {?WebInspector.ToolbarItem}
*/
item: function()
{
return WebInspector.dockController._closeButton;
}
}
/**
* @type {!WebInspector.DockController}
*/
WebInspector.dockController;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** @typedef {{eventListeners:!Array<!WebInspector.EventListener>, internalHandlers:?WebInspector.RemoteArray}} */
WebInspector.FrameworkEventListenersObject;
/** @typedef {{type: string, useCapture: boolean, passive: boolean, handler: function()}} */
WebInspector.EventListenerObjectInInspectedPage;
/**
* @param {!WebInspector.RemoteObject} object
* @return {!Promise<!WebInspector.FrameworkEventListenersObject>}
*/
WebInspector.EventListener.frameworkEventListeners = function(object)
{
if (!object.target().isPage()) {
// TODO(kozyatinskiy): figure out how this should work for |window|.
return Promise.resolve(/** @type {!WebInspector.FrameworkEventListenersObject} */ ({eventListeners: [], internalHandlers: null}));
}
var listenersResult = /** @type {!WebInspector.FrameworkEventListenersObject} */({eventListeners: []});
return object.callFunctionPromise(frameworkEventListeners, undefined)
.then(assertCallFunctionResult)
.then(getOwnProperties)
.then(createEventListeners)
.then(returnResult)
.catchException(listenersResult);
/**
* @param {!WebInspector.RemoteObject} object
* @return {!Promise<!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}>}
*/
function getOwnProperties(object)
{
return object.getOwnPropertiesPromise();
}
/**
* @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}} result
* @return {!Promise<undefined>}
*/
function createEventListeners(result)
{
if (!result.properties)
throw new Error("Object properties is empty");
var promises = [];
for (var property of result.properties) {
if (property.name === "eventListeners" && property.value)
promises.push(convertToEventListeners(property.value).then(storeEventListeners));
if (property.name === "internalHandlers" && property.value)
promises.push(convertToInternalHandlers(property.value).then(storeInternalHandlers));
if (property.name === "errorString" && property.value)
printErrorString(property.value);
}
return /** @type {!Promise<undefined>} */(Promise.all(promises));
}
/**
* @param {!WebInspector.RemoteObject} pageEventListenersObject
* @return {!Promise<!Array<!WebInspector.EventListener>>}
*/
function convertToEventListeners(pageEventListenersObject)
{
return WebInspector.RemoteArray.objectAsArray(pageEventListenersObject).map(toEventListener).then(filterOutEmptyObjects);
/**
* @param {!WebInspector.RemoteObject} listenerObject
* @return {!Promise<?WebInspector.EventListener>}
*/
function toEventListener(listenerObject)
{
/** @type {string} */
var type;
/** @type {boolean} */
var useCapture;
/** @type {boolean} */
var passive;
/** @type {?WebInspector.RemoteObject} */
var handler = null;
/** @type {?WebInspector.RemoteObject} */
var originalHandler = null;
/** @type {?WebInspector.DebuggerModel.Location} */
var location = null;
/** @type {?WebInspector.RemoteObject} */
var removeFunctionObject = null;
var promises = [];
promises.push(listenerObject.callFunctionJSONPromise(truncatePageEventListener, undefined).then(storeTruncatedListener));
/**
* @suppressReceiverCheck
* @this {WebInspector.EventListenerObjectInInspectedPage}
* @return {!{type:string, useCapture:boolean, passive:boolean}}
*/
function truncatePageEventListener()
{
return {type: this.type, useCapture: this.useCapture, passive: this.passive};
}
/**
* @param {!{type:string, useCapture: boolean, passive: boolean}} truncatedListener
*/
function storeTruncatedListener(truncatedListener)
{
type = truncatedListener.type;
useCapture = truncatedListener.useCapture;
passive = truncatedListener.passive;
}
promises.push(listenerObject.callFunctionPromise(handlerFunction).then(assertCallFunctionResult).then(storeOriginalHandler).then(toTargetFunction).then(storeFunctionWithDetails));
/**
* @suppressReceiverCheck
* @return {function()}
* @this {WebInspector.EventListenerObjectInInspectedPage}
*/
function handlerFunction()
{
return this.handler;
}
/**
* @param {!WebInspector.RemoteObject} functionObject
* @return {!WebInspector.RemoteObject}
*/
function storeOriginalHandler(functionObject)
{
originalHandler = functionObject;
return originalHandler;
}
/**
* @param {!WebInspector.RemoteObject} functionObject
* @return {!Promise<undefined>}
*/
function storeFunctionWithDetails(functionObject)
{
handler = functionObject;
return /** @type {!Promise<undefined>} */(functionObject.functionDetailsPromise().then(storeFunctionDetails));
}
/**
* @param {?WebInspector.DebuggerModel.FunctionDetails} functionDetails
*/
function storeFunctionDetails(functionDetails)
{
location = functionDetails ? functionDetails.location : null;
}
promises.push(listenerObject.callFunctionPromise(getRemoveFunction).then(assertCallFunctionResult).then(storeRemoveFunction));
/**
* @suppressReceiverCheck
* @return {function()}
* @this {WebInspector.EventListenerObjectInInspectedPage}
*/
function getRemoveFunction()
{
return this.remove;
}
/**
* @param {!WebInspector.RemoteObject} functionObject
*/
function storeRemoveFunction(functionObject)
{
if (functionObject.type !== "function")
return;
removeFunctionObject = functionObject;
}
return Promise.all(promises).then(createEventListener).catchException(/** @type {?WebInspector.EventListener} */(null));
/**
* @return {!WebInspector.EventListener}
*/
function createEventListener()
{
if (!location)
throw new Error("Empty event listener's location");
return new WebInspector.EventListener(handler._target, type, useCapture, passive, handler, originalHandler, location, removeFunctionObject, "frameworkUser");
}
}
}
/**
* @param {!WebInspector.RemoteObject} pageInternalHandlersObject
* @return {!Promise<!WebInspector.RemoteArray>}
*/
function convertToInternalHandlers(pageInternalHandlersObject)
{
return WebInspector.RemoteArray.objectAsArray(pageInternalHandlersObject).map(toTargetFunction)
.then(WebInspector.RemoteArray.createFromRemoteObjects);
}
/**
* @param {!WebInspector.RemoteObject} functionObject
* @return {!Promise<!WebInspector.RemoteObject>}
*/
function toTargetFunction(functionObject)
{
return WebInspector.RemoteFunction.objectAsFunction(functionObject).targetFunction();
}
/**
* @param {!Array<!WebInspector.EventListener>} eventListeners
*/
function storeEventListeners(eventListeners)
{
listenersResult.eventListeners = eventListeners;
}
/**
* @param {!WebInspector.RemoteArray} internalHandlers
*/
function storeInternalHandlers(internalHandlers)
{
listenersResult.internalHandlers = internalHandlers;
}
/**
* @param {!WebInspector.RemoteObject} errorString
*/
function printErrorString(errorString)
{
WebInspector.console.error(errorString.value);
}
/**
* @return {!WebInspector.FrameworkEventListenersObject}
*/
function returnResult()
{
return listenersResult;
}
/**
* @param {!WebInspector.CallFunctionResult} result
* @return {!WebInspector.RemoteObject}
*/
function assertCallFunctionResult(result)
{
if (result.wasThrown || !result.object)
throw new Error("Exception in callFunction or empty result");
return result.object;
}
/**
* @param {!Array<?T>} objects
* @return {!Array<!T>}
* @template T
*/
function filterOutEmptyObjects(objects)
{
return objects.filter(filterOutEmpty);
/**
* @param {?T} object
* @return {boolean}
* @template T
*/
function filterOutEmpty(object)
{
return !!object;
}
}
/*
frameworkEventListeners fetcher functions should produce following output:
{
// framework event listeners
"eventListeners": [
{
"handler": function(),
"useCapture": true,
"passive": false,
"type": "change",
"remove": function(type, handler, useCapture, passive)
},
...
],
// internal framework event handlers
"internalHandlers": [
function(),
function(),
...
]
}
*/
/**
* @suppressReceiverCheck
* @return {!{eventListeners:!Array<!WebInspector.EventListenerObjectInInspectedPage>, internalHandlers:?Array<function()>}}
* @this {Object}
*/
function frameworkEventListeners()
{
var errorLines = [];
var eventListeners = [];
var internalHandlers = [];
var fetchers = [jQueryFetcher];
try {
if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtoolsFrameworkEventListeners))
fetchers = fetchers.concat(self.devtoolsFrameworkEventListeners);
} catch (e) {
errorLines.push("devtoolsFrameworkEventListeners call produced error: " + toString(e));
}
for (var i = 0; i < fetchers.length; ++i) {
try {
var fetcherResult = fetchers[i](this);
if (fetcherResult.eventListeners && isArrayLike(fetcherResult.eventListeners)) {
eventListeners = eventListeners.concat(fetcherResult.eventListeners.map(checkEventListener).filter(nonEmptyObject));
}
if (fetcherResult.internalHandlers && isArrayLike(fetcherResult.internalHandlers))
internalHandlers = internalHandlers.concat(fetcherResult.internalHandlers.map(checkInternalHandler).filter(nonEmptyObject));
} catch (e) {
errorLines.push("fetcher call produced error: " + toString(e));
}
}
var result = {eventListeners: eventListeners};
if (internalHandlers.length)
result.internalHandlers = internalHandlers;
if (errorLines.length) {
var errorString = "Framework Event Listeners API Errors:\n\t" + errorLines.join("\n\t");
errorString = errorString.substr(0, errorString.length - 1);
result.errorString = errorString;
}
return result;
/**
* @param {?Object} obj
* @return {boolean}
*/
function isArrayLike(obj)
{
if (!obj || typeof obj !== "object")
return false;
try {
if (typeof obj.splice === "function") {
var len = obj.length;
return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0));
}
} catch (e) {
}
return false;
}
/**
* @param {*} eventListener
* @return {?WebInspector.EventListenerObjectInInspectedPage}
*/
function checkEventListener(eventListener)
{
try {
var errorString = "";
if (!eventListener)
errorString += "empty event listener, ";
var type = eventListener.type;
if (!type || (typeof type !== "string"))
errorString += "event listener's type isn't string or empty, ";
var useCapture = eventListener.useCapture;
if (typeof useCapture !== "boolean")
errorString += "event listener's useCapture isn't boolean or undefined, ";
var passive = eventListener.passive;
if (typeof passive !== "boolean")
errorString += "event listener's passive isn't boolean or undefined, ";
var handler = eventListener.handler;
if (!handler || (typeof handler !== "function"))
errorString += "event listener's handler isn't a function or empty, ";
var remove = eventListener.remove;
if (remove && (typeof remove !== "function"))
errorString += "event listener's remove isn't a function, ";
if (!errorString){
return {type: type, useCapture: useCapture, passive: passive, handler: handler, remove: remove};
} else {
errorLines.push(errorString.substr(0, errorString.length - 2));
return null;
}
} catch (e) {
errorLines.push(toString(e));
return null;
}
}
/**
* @param {*} handler
* @return {function()|null}
*/
function checkInternalHandler(handler)
{
if (handler && (typeof handler === "function"))
return handler;
errorLines.push("internal handler isn't a function or empty");
return null;
}
/**
* @param {*} obj
* @return {string}
* @suppress {uselessCode}
*/
function toString(obj)
{
try {
return "" + obj;
} catch (e) {
return "<error>";
}
}
/**
* @param {*} obj
* @return {boolean}
*/
function nonEmptyObject(obj)
{
return !!obj;
}
function jQueryFetcher(node)
{
if (!node || !(node instanceof Node))
return {eventListeners: []};
var jQuery = /** @type {?{fn,data,_data}}*/(window["jQuery"]);
if (!jQuery || !jQuery.fn)
return {eventListeners: []};
var jQueryFunction = /** @type {function(!Node)} */(jQuery);
var data = jQuery._data || jQuery.data;
var eventListeners = [];
var internalHandlers = [];
if (typeof data === "function") {
var events = data(node, "events");
for (var type in events) {
for (var key in events[type]) {
var frameworkListener = events[type][key];
if (typeof frameworkListener === "object" || typeof frameworkListener === "function") {
var listener = {
handler: frameworkListener.handler || frameworkListener,
useCapture: true,
passive: false,
type: type
};
listener.remove = jQueryRemove.bind(node, frameworkListener.selector);
eventListeners.push(listener);
}
}
}
var nodeData = data(node);
if (nodeData && typeof nodeData.handle === "function")
internalHandlers.push(nodeData.handle);
}
var entry = jQueryFunction(node)[0];
if (entry) {
var entryEvents = entry["$events"];
for (var type in entryEvents) {
var events = entryEvents[type];
for (var key in events) {
if (typeof events[key] === "function") {
var listener = {
handler: events[key],
useCapture: true,
passive: false,
type: type
};
// We don't support removing for old version < 1.4 of jQuery because it doesn't provide API for getting "selector".
eventListeners.push(listener);
}
}
}
if (entry && entry["$handle"])
internalHandlers.push(entry["$handle"]);
}
return {eventListeners: eventListeners, internalHandlers: internalHandlers};
}
/**
* @param {string} selector
* @param {string} type
* @param {function()} handler
* @this {?Object}
*/
function jQueryRemove(selector, type, handler)
{
if (!this || !(this instanceof Node))
return;
var node = /** @type {!Node} */(this);
var jQuery = /** @type {?{fn,data,_data}}*/(window["jQuery"]);
if (!jQuery || !jQuery.fn)
return;
var jQueryFunction = /** @type {function(!Node)} */(jQuery);
jQueryFunction(node).off(type, selector, handler);
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | 2 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @typedef {Array<{object: !WebInspector.RemoteObject, eventListeners: ?Array<!WebInspector.EventListener>, frameworkEventListeners: ?{eventListeners: ?Array<!WebInspector.EventListener>, internalHandlers: ?WebInspector.RemoteArray}, isInternal: ?Array<boolean>}>}
*/
WebInspector.EventListenersResult;
/**
* @constructor
* @param {!Element} element
*/
WebInspector.EventListenersView = function(element)
{
this._element = element;
this._treeOutline = new TreeOutlineInShadow();
this._treeOutline.hideOverflow();
this._treeOutline.registerRequiredCSS("components/objectValue.css");
this._treeOutline.registerRequiredCSS("components/eventListenersView.css");
this._treeOutline.setComparator(WebInspector.EventListenersTreeElement.comparator);
this._treeOutline.element.classList.add("monospace");
this._element.appendChild(this._treeOutline.element)
this._emptyHolder = createElementWithClass("div", "info");
this._emptyHolder.textContent = WebInspector.UIString("No Event Listeners");
this._linkifier = new WebInspector.Linkifier();
/** @type {!Map<string, !WebInspector.EventListenersTreeElement>} */
this._treeItemMap = new Map();
}
WebInspector.EventListenersView.prototype = {
/**
* @param {!Array<!WebInspector.RemoteObject>} objects
* @return {!Promise<undefined>}
*/
addObjects: function(objects)
{
this.reset();
var promises = [];
for (var object of objects)
promises.push(this._addObject(object));
return Promise.all(promises).then(this.addEmptyHolderIfNeeded.bind(this)).then(this._eventListenersArrivedForTest.bind(this));
},
/**
* @param {!WebInspector.RemoteObject} object
* @return {!Promise<undefined>}
*/
_addObject: function(object)
{
/** @type {?Array<!WebInspector.EventListener>} */
var eventListeners = null;
/** @type {?WebInspector.FrameworkEventListenersObject}*/
var frameworkEventListenersObject = null;
var promises = [];
promises.push(object.eventListeners().then(storeEventListeners));
promises.push(WebInspector.EventListener.frameworkEventListeners(object).then(storeFrameworkEventListenersObject));
return Promise.all(promises).then(markInternalEventListeners).then(addEventListeners.bind(this));
/**
* @param {?Array<!WebInspector.EventListener>} result
*/
function storeEventListeners(result)
{
eventListeners = result;
}
/**
* @param {?WebInspector.FrameworkEventListenersObject} result
*/
function storeFrameworkEventListenersObject(result)
{
frameworkEventListenersObject = result;
}
/**
* @return {!Promise<undefined>}
*/
function markInternalEventListeners()
{
if (!eventListeners || !frameworkEventListenersObject.internalHandlers)
return Promise.resolve(undefined);
return frameworkEventListenersObject.internalHandlers.object().callFunctionJSONPromise(isInternalEventListener, eventListeners.map(handlerArgument)).then(setIsInternal);
/**
* @param {!WebInspector.EventListener} listener
* @return {!RuntimeAgent.CallArgument}
*/
function handlerArgument(listener)
{
return WebInspector.RemoteObject.toCallArgument(listener.handler());
}
/**
* @suppressReceiverCheck
* @return {!Array<boolean>}
* @this {Array<*>}
*/
function isInternalEventListener()
{
var isInternal = [];
var internalHandlersSet = new Set(this);
for (var handler of arguments)
isInternal.push(internalHandlersSet.has(handler));
return isInternal;
}
/**
* @param {!Array<boolean>} isInternal
*/
function setIsInternal(isInternal)
{
for (var i = 0; i < eventListeners.length; ++i) {
if (isInternal[i])
eventListeners[i].setListenerType("frameworkInternal");
}
}
}
/**
* @this {WebInspector.EventListenersView}
*/
function addEventListeners()
{
this._addObjectEventListeners(object, eventListeners);
this._addObjectEventListeners(object, frameworkEventListenersObject.eventListeners);
}
},
/**
* @param {!WebInspector.RemoteObject} object
* @param {?Array<!WebInspector.EventListener>} eventListeners
*/
_addObjectEventListeners: function(object, eventListeners)
{
if (!eventListeners)
return;
for (var eventListener of eventListeners) {
var treeItem = this._getOrCreateTreeElementForType(eventListener.type());
treeItem.addObjectEventListener(eventListener, object);
}
},
/**
* @param {boolean} showFramework
* @param {boolean} showPassive
* @param {boolean} showBlocking
*/
showFrameworkListeners: function(showFramework, showPassive, showBlocking)
{
var eventTypes = this._treeOutline.rootElement().children();
for (var eventType of eventTypes) {
var hiddenEventType = true;
for (var listenerElement of eventType.children()) {
var listenerType = listenerElement.eventListener().listenerType();
var hidden = false;
if (listenerType === "frameworkUser" && !showFramework)
hidden = true;
if (listenerType === "frameworkInternal" && showFramework)
hidden = true;
if (!showPassive && listenerElement.eventListener().passive())
hidden = true;
if (!showBlocking && !listenerElement.eventListener().passive())
hidden = true;
listenerElement.hidden = hidden;
hiddenEventType = hiddenEventType && hidden;
}
eventType.hidden = hiddenEventType;
}
},
/**
* @param {string} type
* @return {!WebInspector.EventListenersTreeElement}
*/
_getOrCreateTreeElementForType: function(type)
{
var treeItem = this._treeItemMap.get(type);
if (!treeItem) {
treeItem = new WebInspector.EventListenersTreeElement(type, this._linkifier);
this._treeItemMap.set(type, treeItem);
treeItem.hidden = true;
this._treeOutline.appendChild(treeItem);
}
this._emptyHolder.remove();
return treeItem;
},
addEmptyHolderIfNeeded: function()
{
var allHidden = true;
for (var eventType of this._treeOutline.rootElement().children()) {
eventType.hidden = !eventType.firstChild();
allHidden = allHidden && eventType.hidden;
}
if (allHidden && !this._emptyHolder.parentNode)
this._element.appendChild(this._emptyHolder);
},
reset: function()
{
var eventTypes = this._treeOutline.rootElement().children();
for (var eventType of eventTypes)
eventType.removeChildren();
this._linkifier.reset();
},
_eventListenersArrivedForTest: function()
{
}
}
/**
* @constructor
* @extends {TreeElement}
* @param {string} type
* @param {!WebInspector.Linkifier} linkifier
*/
WebInspector.EventListenersTreeElement = function(type, linkifier)
{
TreeElement.call(this, type);
this.toggleOnClick = true;
this.selectable = false;
this._linkifier = linkifier;
}
/**
* @param {!TreeElement} element1
* @param {!TreeElement} element2
* @return {number}
*/
WebInspector.EventListenersTreeElement.comparator = function(element1, element2) {
if (element1.title === element2.title)
return 0;
return element1.title > element2.title ? 1 : -1;
}
WebInspector.EventListenersTreeElement.prototype = {
/**
* @param {!WebInspector.EventListener} eventListener
* @param {!WebInspector.RemoteObject} object
*/
addObjectEventListener: function(eventListener, object)
{
var treeElement = new WebInspector.ObjectEventListenerBar(eventListener, object, this._linkifier);
this.appendChild(/** @type {!TreeElement} */ (treeElement));
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.EventListener} eventListener
* @param {!WebInspector.RemoteObject} object
* @param {!WebInspector.Linkifier} linkifier
*/
WebInspector.ObjectEventListenerBar = function(eventListener, object, linkifier)
{
TreeElement.call(this, "", true);
this._eventListener = eventListener;
this.editable = false;
this.selectable = false;
this._setTitle(object, linkifier);
}
WebInspector.ObjectEventListenerBar.prototype = {
onpopulate: function()
{
var properties = [];
var eventListener = this._eventListener;
var runtimeModel = eventListener.target().runtimeModel;
properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("useCapture", eventListener.useCapture()));
properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("passive", eventListener.passive()));
if (typeof eventListener.handler() !== "undefined")
properties.push(new WebInspector.RemoteObjectProperty("handler", eventListener.handler()));
WebInspector.ObjectPropertyTreeElement.populateWithProperties(this, properties, [], true, null);
},
/**
* @param {!WebInspector.RemoteObject} object
* @param {!WebInspector.Linkifier} linkifier
*/
_setTitle: function(object, linkifier)
{
var title = this.listItemElement.createChild("span");
var subtitle = this.listItemElement.createChild("span", "event-listener-tree-subtitle");
subtitle.appendChild(linkifier.linkifyRawLocation(this._eventListener.location(), this._eventListener.sourceURL()));
title.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(object, false));
if (this._eventListener.removeFunction()) {
var deleteButton = title.createChild("span", "event-listener-delete-button");
deleteButton.textContent = WebInspector.UIString("Remove");
deleteButton.title = WebInspector.UIString("Delete event listener");
deleteButton.addEventListener("click", removeListener.bind(this), false);
title.appendChild(deleteButton);
}
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ObjectEventListenerBar}
*/
function removeListener(event)
{
event.consume();
this._removeListenerBar();
this._eventListener.remove();
}
},
_removeListenerBar: function()
{
var parent = this.parent;
parent.removeChild(this);
if (!parent.childCount()) {
parent.parent.removeChild(parent);
return;
}
var allHidden = true;
for (var i = 0; i < parent.childCount(); ++i)
if (!parent.childAt(i).hidden)
allHidden = false;
parent.hidden = allHidden;
},
/**
* @return {!WebInspector.EventListener}
*/
eventListener: function()
{
return this._eventListener;
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | 2 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!Element} selectElement
*/
WebInspector.ExecutionContextModel = function(selectElement)
{
this._selectElement = selectElement;
/**
* @type {!Map.<!WebInspector.ExecutionContext, !Element>}
*/
this._optionByExecutionContext = new Map();
WebInspector.targetManager.observeTargets(this);
WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._onFrameNavigated, this);
this._selectElement.addEventListener("change", this._executionContextChanged.bind(this), false);
WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChangedExternally, this);
}
WebInspector.ExecutionContextModel.prototype = {
/**
* @param {!WebInspector.ExecutionContext} executionContext
* @return {string}
*/
_titleFor: function(executionContext)
{
var result;
if (executionContext.isDefault) {
if (executionContext.frameId) {
var frame = executionContext.target().resourceTreeModel.frameForId(executionContext.frameId);
result = frame ? frame.displayName() : (executionContext.origin || executionContext.name);
} else {
var parsedUrl = executionContext.origin.asParsedURL();
var name = parsedUrl? parsedUrl.lastPathComponentWithFragment() : executionContext.name;
result = executionContext.target().decorateLabel(name);
}
} else {
result = "\u00a0\u00a0\u00a0\u00a0" + (executionContext.name || executionContext.origin);
}
var maxLength = 50;
return result.trimMiddle(maxLength);
},
/**
* @param {!WebInspector.ExecutionContext} executionContext
*/
_executionContextCreated: function(executionContext)
{
// FIXME(413886): We never want to show execution context for the main thread of shadow page in service/shared worker frontend.
// This check could be removed once we do not send this context to frontend.
if (executionContext.target().isServiceWorker())
return;
var newOption = createElement("option");
newOption.__executionContext = executionContext;
newOption.text = this._titleFor(executionContext);
this._optionByExecutionContext.set(executionContext, newOption);
var options = this._selectElement.options;
var contexts = Array.prototype.map.call(options, mapping);
var index = contexts.lowerBound(executionContext, WebInspector.ExecutionContext.comparator)
this._selectElement.insertBefore(newOption, options[index]);
if (executionContext === WebInspector.context.flavor(WebInspector.ExecutionContext))
this._select(newOption);
/**
* @param {!Element} option
* @return {!WebInspector.ExecutionContext}
*/
function mapping(option)
{
return option.__executionContext;
}
},
/**
* @param {!WebInspector.Event} event
*/
_onExecutionContextCreated: function(event)
{
var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data);
this._executionContextCreated(executionContext);
},
/**
* @param {!WebInspector.ExecutionContext} executionContext
*/
_executionContextDestroyed: function(executionContext)
{
var option = this._optionByExecutionContext.remove(executionContext);
option.remove();
},
/**
* @param {!WebInspector.Event} event
*/
_onExecutionContextDestroyed: function(event)
{
var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data);
this._executionContextDestroyed(executionContext);
},
/**
* @param {!WebInspector.Event} event
*/
_onFrameNavigated: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
var executionContexts = this._optionByExecutionContext.keysArray();
for (var i = 0; i < executionContexts.length; ++i) {
var context = executionContexts[i];
if (context.frameId === frame.id)
this._optionByExecutionContext.get(context).text = this._titleFor(context);
}
},
/**
* @param {!WebInspector.Event} event
*/
_executionContextChangedExternally: function(event)
{
var executionContext = /** @type {?WebInspector.ExecutionContext} */ (event.data);
if (!executionContext)
return;
var options = this._selectElement.options;
for (var i = 0; i < options.length; ++i) {
if (options[i].__executionContext === executionContext)
this._select(options[i]);
}
},
_executionContextChanged: function()
{
var option = this._selectedOption();
var newContext = option ? option.__executionContext : null;
WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
target.runtimeModel.executionContexts().forEach(this._executionContextCreated, this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var executionContexts = this._optionByExecutionContext.keysArray();
for (var i = 0; i < executionContexts.length; ++i) {
if (executionContexts[i].target() === target)
this._executionContextDestroyed(executionContexts[i]);
}
},
/**
* @param {!Element} option
*/
_select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
},
/**
* @return {?Element}
*/
_selectedOption: function()
{
if (this._selectElement.selectedIndex >= 0)
return this._selectElement[this._selectElement.selectedIndex];
return null;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.TargetManager} targetManager
* @param {!WebInspector.Context} context
*/
WebInspector.ExecutionContextSelector = function(targetManager, context)
{
targetManager.observeTargets(this);
context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this);
context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this);
targetManager.addModelListener(WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
targetManager.addModelListener(WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
this._targetManager = targetManager;
this._context = context;
}
WebInspector.ExecutionContextSelector.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (!target.hasJSContext())
return;
// Defer selecting default target since we need all clients to get their
// targetAdded notifications first.
setImmediate(deferred.bind(this));
/**
* @this {WebInspector.ExecutionContextSelector}
*/
function deferred()
{
// We always want the second context for the service worker targets.
if (!this._context.flavor(WebInspector.Target))
this._context.setFlavor(WebInspector.Target, target);
}
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (!target.hasJSContext())
return;
var currentExecutionContext = this._context.flavor(WebInspector.ExecutionContext);
if (currentExecutionContext && currentExecutionContext.target() === target)
this._currentExecutionContextGone();
var targets = this._targetManager.targetsWithJSContext();
if (this._context.flavor(WebInspector.Target) === target && targets.length)
this._context.setFlavor(WebInspector.Target, targets[0]);
},
/**
* @param {!WebInspector.Event} event
*/
_executionContextChanged: function(event)
{
var newContext = /** @type {?WebInspector.ExecutionContext} */ (event.data);
if (newContext) {
this._context.setFlavor(WebInspector.Target, newContext.target());
if (!this._contextIsGoingAway)
this._lastSelectedContextId = this._contextPersistentId(newContext);
}
},
/**
* @param {!WebInspector.ExecutionContext} executionContext
* @return {string}
*/
_contextPersistentId: function(executionContext)
{
return executionContext.isDefault ? executionContext.target().name() + ":" + executionContext.frameId : "";
},
/**
* @param {!WebInspector.Event} event
*/
_targetChanged: function(event)
{
var newTarget = /** @type {?WebInspector.Target} */(event.data);
var currentContext = this._context.flavor(WebInspector.ExecutionContext);
if (!newTarget || (currentContext && currentContext.target() === newTarget))
return;
var executionContexts = newTarget.runtimeModel.executionContexts();
if (!executionContexts.length)
return;
var newContext = executionContexts[0];
for (var i = 1; i < executionContexts.length; ++i) {
if (executionContexts[i].isDefault)
newContext = executionContexts[i];
}
this._context.setFlavor(WebInspector.ExecutionContext, newContext);
},
/**
* @param {!WebInspector.Event} event
*/
_onExecutionContextCreated: function(event)
{
var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data);
if (!this._context.flavor(WebInspector.ExecutionContext) || (this._lastSelectedContextId && this._lastSelectedContextId === this._contextPersistentId(executionContext)))
this._context.setFlavor(WebInspector.ExecutionContext, executionContext);
},
/**
* @param {!WebInspector.Event} event
*/
_onExecutionContextDestroyed: function(event)
{
var executionContext = /** @type {!WebInspector.ExecutionContext}*/ (event.data);
if (this._context.flavor(WebInspector.ExecutionContext) === executionContext)
this._currentExecutionContextGone();
},
_currentExecutionContextGone: function()
{
var targets = this._targetManager.targetsWithJSContext();
var newContext = null;
for (var i = 0; i < targets.length; ++i) {
if (targets[i].isServiceWorker())
continue;
var executionContexts = targets[i].runtimeModel.executionContexts();
if (executionContexts.length) {
newContext = executionContexts[0];
break;
}
}
this._contextIsGoingAway = true;
this._context.setFlavor(WebInspector.ExecutionContext, newContext);
this._contextIsGoingAway = false;
}
}
/**
* @param {!Element} proxyElement
* @param {string} text
* @param {number} cursorOffset
* @param {!Range} wordRange
* @param {boolean} force
* @param {function(!Array.<string>, number=)} completionsReadyCallback
*/
WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext = function(proxyElement, text, cursorOffset, wordRange, force, completionsReadyCallback)
{
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!executionContext) {
completionsReadyCallback([]);
return;
}
// Pass less stop characters to rangeOfWord so the range will be a more complete expression.
var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, " =:({;,!+-*/&|^<>", proxyElement, "backward");
var expressionString = expressionRange.toString();
// The "[" is also a stop character, except when it's the last character of the expression.
var pos = expressionString.lastIndexOf("[", expressionString.length - 2);
if (pos !== -1)
expressionString = expressionString.substr(pos + 1);
var prefix = wordRange.toString();
executionContext.completionsForExpression(expressionString, text, cursorOffset, prefix, force, completionsReadyCallback);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | 2 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.HandlerRegistry = function(setting)
{
WebInspector.Object.call(this);
this._handlers = {};
this._setting = setting;
this._activeHandler = this._setting.get();
}
WebInspector.HandlerRegistry.prototype = {
get handlerNames()
{
return Object.getOwnPropertyNames(this._handlers);
},
get activeHandler()
{
return this._activeHandler;
},
set activeHandler(value)
{
this._activeHandler = value;
this._setting.set(value);
},
/**
* @param {!Object} data
* @return {boolean}
*/
dispatch: function(data)
{
return this.dispatchToHandler(this._activeHandler, data);
},
/**
* @param {string} name
* @param {!Object} data
* @return {boolean}
*/
dispatchToHandler: function(name, data)
{
var handler = this._handlers[name];
var result = handler && handler(data);
return !!result;
},
registerHandler: function(name, handler)
{
this._handlers[name] = handler;
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},
unregisterHandler: function(name)
{
delete this._handlers[name];
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},
/**
* @param {string} url
*/
_openInNewTab: function(url)
{
InspectorFrontendHost.openInNewTab(url);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
_appendContentProviderItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest))
return;
var contentProvider = /** @type {!WebInspector.ContentProvider} */ (target);
if (!contentProvider.contentURL())
return;
contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, contentProvider.contentURL()));
// Skip 0th handler, as it's 'Use default panel' one.
for (var i = 1; i < this.handlerNames.length; ++i) {
var handler = this.handlerNames[i];
contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^using %s", handler),
this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() }));
}
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL()));
if (!contentProvider.contentURL())
return;
if (!contentProvider.contentType().isDocumentOrScriptOrStyleSheet())
return;
/**
* @param {boolean} forceSaveAs
* @param {?string} content
*/
function doSave(forceSaveAs, content)
{
var url = contentProvider.contentURL();
WebInspector.fileManager.save(url, /** @type {string} */ (content), forceSaveAs);
WebInspector.fileManager.close(url);
}
/**
* @param {boolean} forceSaveAs
*/
function save(forceSaveAs)
{
if (contentProvider instanceof WebInspector.UISourceCode) {
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (contentProvider);
if (forceSaveAs)
uiSourceCode.saveAs();
else
uiSourceCode.commitWorkingCopy();
return;
}
contentProvider.requestContent().then(doSave.bind(null, forceSaveAs));
}
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(null, false));
if (contentProvider instanceof WebInspector.UISourceCode) {
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (contentProvider);
if (uiSourceCode.project().type() !== WebInspector.projectTypes.FileSystem && uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
contextMenu.appendItem(WebInspector.UIString.capitalize("Save ^as..."), save.bind(null, true));
}
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
_appendHrefItems: function(contextMenu, target)
{
if (!(target instanceof Node))
return;
var targetNode = /** @type {!Node} */ (target);
var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
if (!anchorElement)
return;
var uiLocation = WebInspector.Linkifier.uiLocationByAnchor(anchorElement);
var resourceURL = uiLocation ? uiLocation.uiSourceCode.contentURL() : anchorElement.href;
var uiSourceCode = uiLocation ? uiLocation.uiSourceCode : (resourceURL ? WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(resourceURL) : null);
function open()
{
WebInspector.Revealer.reveal(uiSourceCode);
}
if (uiSourceCode)
contextMenu.appendItem("Open", open);
if (!resourceURL)
return;
// Add resource-related actions.
contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, resourceURL));
/**
* @param {string} resourceURL
*/
function openInResourcesPanel(resourceURL)
{
var resource = WebInspector.resourceForURL(resourceURL);
if (resource)
WebInspector.Revealer.reveal(resource);
else
InspectorFrontendHost.openInNewTab(resourceURL);
}
if (!targetNode.enclosingNodeOrSelfWithClassList(["resources", "panel"]) && WebInspector.resourceForURL(resourceURL))
contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^link in Resources ^panel"), openInResourcesPanel.bind(null, resourceURL));
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
},
__proto__: WebInspector.Object.prototype
}
WebInspector.HandlerRegistry.EventTypes = {
HandlersUpdated: "HandlersUpdated"
}
/**
* @constructor
*/
WebInspector.HandlerSelector = function(handlerRegistry)
{
this._handlerRegistry = handlerRegistry;
this.element = createElementWithClass("select", "chrome-select");
this.element.addEventListener("change", this._onChange.bind(this), false);
this._update();
this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
}
WebInspector.HandlerSelector.prototype =
{
_update: function()
{
this.element.removeChildren();
var names = this._handlerRegistry.handlerNames;
var activeHandler = this._handlerRegistry.activeHandler;
for (var i = 0; i < names.length; ++i) {
var option = createElement("option");
option.textContent = names[i];
option.selected = activeHandler === names[i];
this.element.appendChild(option);
}
this.element.disabled = names.length <= 1;
},
_onChange: function(event)
{
var value = event.target.value;
this._handlerRegistry.activeHandler = value;
}
}
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.HandlerRegistry.ContextMenuProvider = function()
{
}
WebInspector.HandlerRegistry.ContextMenuProvider.prototype = {
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
WebInspector.openAnchorLocationRegistry._appendContentProviderItems(contextMenu, target);
WebInspector.openAnchorLocationRegistry._appendHrefItems(contextMenu, target);
}
}
/**
* @constructor
* @implements {WebInspector.Linkifier.LinkHandler}
*/
WebInspector.HandlerRegistry.LinkHandler = function()
{
}
WebInspector.HandlerRegistry.LinkHandler.prototype = {
/**
* @override
* @param {string} url
* @param {number=} lineNumber
* @return {boolean}
*/
handleLink: function(url, lineNumber)
{
return WebInspector.openAnchorLocationRegistry.dispatch({ url: url, lineNumber: lineNumber});
}
}
/**
* @constructor
* @implements {WebInspector.SettingUI}
*/
WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI = function()
{
}
WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI.prototype = {
/**
* @override
* @return {?Element}
*/
settingElement: function()
{
if (!WebInspector.openAnchorLocationRegistry.handlerNames.length)
return null;
var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
return WebInspector.SettingsUI.createCustomSetting(WebInspector.UIString("Link handling:"), handlerSelector.element);
}
}
/**
* @type {!WebInspector.HandlerRegistry}
*/
WebInspector.openAnchorLocationRegistry;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | 2 1 1 1 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.LinkifierFormatter = function() { } WebInspector.LinkifierFormatter.prototype = { /** * @param {!Element} anchor * @param {!WebInspector.UILocation} uiLocation * @param {boolean} isBlackboxed */ formatLiveAnchor: function(anchor, uiLocation, isBlackboxed) { } } /** * @constructor * @implements {WebInspector.TargetManager.Observer} * @param {!WebInspector.LinkifierFormatter=} formatter */ WebInspector.Linkifier = function(formatter) { this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter(WebInspector.Linkifier.MaxLengthForDisplayedURLs); /** @type {!Map<!WebInspector.Target, !Array<!Element>>} */ this._anchorsByTarget = new Map(); /** @type {!Map<!WebInspector.Target, !WebInspector.LiveLocationPool>} */ this._locationPoolByTarget = new Map(); WebInspector.targetManager.observeTargets(this); } /** * @param {?WebInspector.Linkifier.LinkHandler} handler */ WebInspector.Linkifier.setLinkHandler = function(handler) { WebInspector.Linkifier._linkHandler = handler; } /** * @param {string} url * @param {number=} lineNumber * @return {boolean} */ WebInspector.Linkifier.handleLink = function(url, lineNumber) { if (!WebInspector.Linkifier._linkHandler) return false; return WebInspector.Linkifier._linkHandler.handleLink(url, lineNumber); } /** * @param {!Object} revealable * @param {string} text * @param {string=} fallbackHref * @param {number=} fallbackLineNumber * @param {string=} title * @param {string=} classes * @return {!Element} */ WebInspector.Linkifier.linkifyUsingRevealer = function(revealable, text, fallbackHref, fallbackLineNumber, title, classes) { var a = createElement("a"); a.className = (classes || "") + " webkit-html-resource-link"; a.textContent = text.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs); a.title = title || text; if (fallbackHref) { a.href = fallbackHref; a.lineNumber = fallbackLineNumber; } /** * @param {!Event} event * @this {Object} */ function clickHandler(event) { event.stopImmediatePropagation(); event.preventDefault(); if (fallbackHref && WebInspector.Linkifier.handleLink(fallbackHref, fallbackLineNumber)) return; WebInspector.Revealer.reveal(this); } a.addEventListener("click", clickHandler.bind(revealable), false); return a; } WebInspector.Linkifier._uiLocationSymbol = Symbol("uiLocation"); WebInspector.Linkifier._fallbackAnchorSymbol = Symbol("fallbackAnchor"); WebInspector.Linkifier._liveLocationSymbol = Symbol("liveLocation"); WebInspector.Linkifier.prototype = { /** * @override * @param {!WebInspector.Target} target */ targetAdded: function(target) { this._anchorsByTarget.set(target, []); this._locationPoolByTarget.set(target, new WebInspector.LiveLocationPool()); }, /** * @override * @param {!WebInspector.Target} target */ targetRemoved: function(target) { var locationPool = /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.remove(target)); locationPool.disposeAll(); var anchors = this._anchorsByTarget.remove(target); for (var anchor of anchors) { delete anchor[WebInspector.Linkifier._liveLocationSymbol]; var fallbackAnchor = anchor[WebInspector.Linkifier._fallbackAnchorSymbol]; if (fallbackAnchor) { anchor.href = fallbackAnchor.href; anchor.lineNumber = fallbackAnchor.lineNumber; anchor.title = fallbackAnchor.title; anchor.className = fallbackAnchor.className; anchor.textContent = fallbackAnchor.textContent; delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol]; } } }, /** * @param {?WebInspector.Target} target * @param {?string} scriptId * @param {string} sourceURL * @param {number} lineNumber * @param {number=} columnNumber * @param {string=} classes * @return {!Element} */ linkifyScriptLocation: function(target, scriptId, sourceURL, lineNumber, columnNumber, classes) { var fallbackAnchor = WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, columnNumber, classes); if (!target || target.isDetached()) return fallbackAnchor; var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); if (!debuggerModel) return fallbackAnchor; var rawLocation = scriptId ? debuggerModel.createRawLocationByScriptId(scriptId, lineNumber, columnNumber || 0) : debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0); if (!rawLocation) return fallbackAnchor; var anchor = this._createAnchor(classes); var liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(rawLocation.target()))); var anchors = /** @type {!Array<!Element>} */(this._anchorsByTarget.get(rawLocation.target())); anchors.push(anchor); anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation; anchor[WebInspector.Linkifier._fallbackAnchorSymbol] = fallbackAnchor; return anchor; }, /** * @param {!WebInspector.DebuggerModel.Location} rawLocation * @param {string} fallbackUrl * @param {string=} classes * @return {!Element} */ linkifyRawLocation: function(rawLocation, fallbackUrl, classes) { return this.linkifyScriptLocation(rawLocation.target(), rawLocation.scriptId, fallbackUrl, rawLocation.lineNumber, rawLocation.columnNumber, classes); }, /** * @param {?WebInspector.Target} target * @param {!RuntimeAgent.CallFrame} callFrame * @param {string=} classes * @return {!Element} */ linkifyConsoleCallFrame: function(target, callFrame, classes) { return this.linkifyScriptLocation(target, callFrame.scriptId, callFrame.url, WebInspector.DebuggerModel.fromOneBased(callFrame.lineNumber), WebInspector.DebuggerModel.fromOneBased(callFrame.columnNumber), classes); }, /** * @param {!WebInspector.Target} target * @param {!RuntimeAgent.StackTrace} stackTrace * @param {string=} classes * @return {!Element} */ linkifyStackTraceTopFrame: function(target, stackTrace, classes) { console.assert(stackTrace.callFrames && stackTrace.callFrames.length); var topFrame = stackTrace.callFrames[0]; var fallbackAnchor = WebInspector.linkifyResourceAsNode(topFrame.url, WebInspector.DebuggerModel.fromOneBased(topFrame.lineNumber), WebInspector.DebuggerModel.fromOneBased(topFrame.columnNumber), classes); if (target.isDetached()) return fallbackAnchor; var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); var rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace); if (rawLocations.length === 0) return fallbackAnchor; var anchor = this._createAnchor(classes); var liveLocation = WebInspector.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(rawLocations, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(target))); var anchors = /** @type {!Array<!Element>} */(this._anchorsByTarget.get(target)); anchors.push(anchor); anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation; anchor[WebInspector.Linkifier._fallbackAnchorSymbol] = fallbackAnchor; return anchor; }, /** * @param {!WebInspector.CSSLocation} rawLocation * @param {string=} classes * @return {!Element} */ linkifyCSSLocation: function(rawLocation, classes) { var anchor = this._createAnchor(classes); var liveLocation = WebInspector.cssWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(rawLocation.target()))); var anchors = /** @type {!Array<!Element>} */(this._anchorsByTarget.get(rawLocation.target())); anchors.push(anchor); anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation; return anchor; }, /** * @param {!WebInspector.Target} target * @param {!Element} anchor */ disposeAnchor: function(target, anchor) { delete anchor[WebInspector.Linkifier._uiLocationSymbol]; delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol]; var liveLocation = anchor[WebInspector.Linkifier._liveLocationSymbol]; if (liveLocation) liveLocation.dispose(); delete anchor[WebInspector.Linkifier._liveLocationSymbol]; }, /** * @param {string=} classes * @return {!Element} */ _createAnchor: function(classes) { var anchor = createElement("a"); anchor.className = (classes || "") + " webkit-html-resource-link"; /** * @param {!Event} event */ function clickHandler(event) { var uiLocation = anchor[WebInspector.Linkifier._uiLocationSymbol]; if (!uiLocation) return; event.consume(true); var networkURL = WebInspector.networkMapping.networkURL(uiLocation.uiSourceCode); if (WebInspector.Linkifier.handleLink(networkURL, uiLocation.lineNumber)) return; WebInspector.Revealer.reveal(uiLocation); } anchor.addEventListener("click", clickHandler, false); return anchor; }, reset: function() { for (var target of this._anchorsByTarget.keysArray()) { this.targetRemoved(target); this.targetAdded(target); } }, dispose: function() { for (var target of this._anchorsByTarget.keysArray()) this.targetRemoved(target); WebInspector.targetManager.unobserveTargets(this); }, /** * @param {!Element} anchor * @param {!WebInspector.LiveLocation} liveLocation */ _updateAnchor: function(anchor, liveLocation) { var uiLocation = liveLocation.uiLocation(); if (!uiLocation) return; anchor[WebInspector.Linkifier._uiLocationSymbol] = uiLocation; this._formatter.formatLiveAnchor(anchor, uiLocation, liveLocation.isBlackboxed()); } } /** * @param {!Element} anchor * @return {?WebInspector.UILocation} uiLocation */ WebInspector.Linkifier.uiLocationByAnchor = function(anchor) { return anchor[WebInspector.Linkifier._uiLocationSymbol]; } /** * @constructor * @implements {WebInspector.LinkifierFormatter} * @param {number=} maxLength */ WebInspector.Linkifier.DefaultFormatter = function(maxLength) { this._maxLength = maxLength; } WebInspector.Linkifier.DefaultFormatter.prototype = { /** * @override * @param {!Element} anchor * @param {!WebInspector.UILocation} uiLocation * @param {boolean} isBlackboxed */ formatLiveAnchor: function(anchor, uiLocation, isBlackboxed) { var text = uiLocation.linkText(); text = text.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, "$1\u2026"); if (this._maxLength) text = text.trimMiddle(this._maxLength); anchor.textContent = text; var titleText = uiLocation.uiSourceCode.url(); if (typeof uiLocation.lineNumber === "number") titleText += ":" + (uiLocation.lineNumber + 1); anchor.title = titleText; anchor.classList.toggle("webkit-html-blackbox-link", isBlackboxed); } } /** * @constructor * @extends {WebInspector.Linkifier.DefaultFormatter} */ WebInspector.Linkifier.DefaultCSSFormatter = function() { WebInspector.Linkifier.DefaultFormatter.call(this, WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs); } WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs = 30; WebInspector.Linkifier.DefaultCSSFormatter.prototype = { /** * @override * @param {!Element} anchor * @param {!WebInspector.UILocation} uiLocation * @param {boolean} isBlackboxed */ formatLiveAnchor: function(anchor, uiLocation, isBlackboxed) { WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call(this, anchor, uiLocation, isBlackboxed); anchor.classList.add("webkit-html-resource-link"); anchor.setAttribute("data-uncopyable", anchor.textContent); anchor.textContent = ""; }, __proto__: WebInspector.Linkifier.DefaultFormatter.prototype } /** * The maximum number of characters to display in a URL. * @const * @type {number} */ WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150; /** * @interface */ WebInspector.Linkifier.LinkHandler = function() { } WebInspector.Linkifier.LinkHandler.prototype = { /** * @param {string} url * @param {number=} lineNumber * @return {boolean} */ handleLink: function(url, lineNumber) {} } /** * @param {!WebInspector.Target} target * @param {string} scriptId * @param {number} lineNumber * @param {number=} columnNumber * @return {string} */ WebInspector.Linkifier.liveLocationText = function(target, scriptId, lineNumber, columnNumber) { var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); if (!debuggerModel) return ""; var script = debuggerModel.scriptForId(scriptId); if (!script) return ""; var location = /** @type {!WebInspector.DebuggerModel.Location} */ (debuggerModel.createRawLocation(script, lineNumber, columnNumber || 0)); var uiLocation = /** @type {!WebInspector.UILocation} */ (WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location)); return uiLocation.linkText(); } /** * @param {string} string * @param {function(string,string,number=,number=):!Node} linkifier * @return {!DocumentFragment} */ WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier) { var container = createDocumentFragment(); var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|data:|www\.)[\w$\-_+*'=\|\/\\(){}[\]^%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({^%@&#~]/; while (string && string.length < 10000) { var linkString = linkStringRegEx.exec(string); if (!linkString) break; linkString = linkString[0]; var linkIndex = string.indexOf(linkString); var nonLink = string.substring(0, linkIndex); container.appendChild(createTextNode(nonLink)); var title = linkString; var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString); var splitResult = WebInspector.ParsedURL.splitLineAndColumn(realURL); var linkNode; if (splitResult) linkNode = linkifier(title, splitResult.url, splitResult.lineNumber, splitResult.columnNumber); else linkNode = linkifier(title, realURL); container.appendChild(linkNode); string = string.substring(linkIndex + linkString.length, string.length); } if (string) container.appendChild(createTextNode(string)); return container; } /** * @param {string} string * @return {!DocumentFragment} */ WebInspector.linkifyStringAsFragment = function(string) { /** * @param {string} title * @param {string} url * @param {number=} lineNumber * @param {number=} columnNumber * @return {!Node} */ function linkifier(title, url, lineNumber, columnNumber) { var isExternal = !WebInspector.resourceForURL(url) && !WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url); var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal); if (typeof lineNumber !== "undefined") { urlNode.lineNumber = lineNumber; if (typeof columnNumber !== "undefined") urlNode.columnNumber = columnNumber; } return urlNode; } return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier); } /** * @param {string} url * @param {string=} linkText * @param {string=} classes * @param {boolean=} isExternal * @param {string=} tooltipText * @return {!Element} */ WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText) { if (!linkText) linkText = url; var a = createElementWithClass("a", classes); var href = url; if (url.trim().toLowerCase().startsWith("javascript:")) href = null; if (isExternal && WebInspector.ParsedURL.isRelativeURL(url)) href = null; if (href !== null) { a.href = href; a.classList.add(isExternal ? "webkit-html-external-link" : "webkit-html-resource-link"); } if (!tooltipText && linkText !== url) a.title = url; else if (tooltipText) a.title = tooltipText; a.textContent = linkText.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs); if (isExternal) a.setAttribute("target", "_blank"); return a; } /** * @param {string} article * @param {string} title * @return {!Element} */ WebInspector.linkifyDocumentationURLAsNode = function(article, title) { return WebInspector.linkifyURLAsNode("https://developers.google.com/web/tools/chrome-devtools/" + article, title, undefined, true); } /** * @param {string} url * @param {number=} lineNumber * @param {number=} columnNumber * @param {string=} classes * @param {string=} tooltipText * @param {string=} urlDisplayName * @return {!Element} */ WebInspector.linkifyResourceAsNode = function(url, lineNumber, columnNumber, classes, tooltipText, urlDisplayName) { var linkText = urlDisplayName ? urlDisplayName : url ? WebInspector.displayNameForURL(url) : WebInspector.UIString("(program)"); if (typeof lineNumber === "number") linkText += ":" + (lineNumber + 1); var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText); anchor.lineNumber = lineNumber; anchor.columnNumber = columnNumber; return anchor; } /** * @param {!WebInspector.NetworkRequest} request * @return {!Element} */ WebInspector.linkifyRequestAsNode = function(request) { var anchor = WebInspector.linkifyURLAsNode(request.url); anchor.requestId = request.requestId; return anchor; } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | 2 1 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {function(!Array<!WebInspector.NetworkConditionsGroup>):!Array<?WebInspector.NetworkManager.Conditions>} populateCallback
* @param {function(number)} selectCallback
*/
WebInspector.NetworkConditionsSelector = function(populateCallback, selectCallback)
{
this._populateCallback = populateCallback;
this._selectCallback = selectCallback;
this._customSetting = WebInspector.moduleSetting("customNetworkConditions");
this._customSetting.addChangeListener(this._populateOptions, this);
this._manager = WebInspector.multitargetNetworkManager;
this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged, this._conditionsChanged, this);
this._populateOptions();
}
/** @typedef {!{title: string, items: !Array<!WebInspector.NetworkManager.Conditions>}} */
WebInspector.NetworkConditionsGroup;
/**
* @param {number} throughput
* @param {boolean=} plainText
* @return {string}
*/
WebInspector.NetworkConditionsSelector._throughputText = function(throughput, plainText)
{
if (throughput < 0)
return "";
var throughputInKbps = throughput / (1024 / 8);
var delimiter = plainText ? "" : " ";
if (throughputInKbps < 1024)
return WebInspector.UIString("%d%skb/s", throughputInKbps, delimiter);
if (throughputInKbps < 1024 * 10)
return WebInspector.UIString("%.1f%sMb/s", throughputInKbps / 1024, delimiter);
return WebInspector.UIString("%d%sMb/s", (throughputInKbps / 1024) | 0, delimiter);
}
/** @type {!Array.<!WebInspector.NetworkManager.Conditions>} */
WebInspector.NetworkConditionsSelector._presets = [
WebInspector.NetworkManager.OfflineConditions,
{title: "GPRS", download: 50 * 1024 / 8, upload: 20 * 1024 / 8, latency: 500},
{title: "Regular 2G", download: 250 * 1024 / 8, upload: 50 * 1024 / 8, latency: 300},
{title: "Good 2G", download: 450 * 1024 / 8, upload: 150 * 1024 / 8, latency: 150},
{title: "Regular 3G", download: 750 * 1024 / 8, upload: 250 * 1024 / 8, latency: 100},
{title: "Good 3G", download: 1.5 * 1024 * 1024 / 8, upload: 750 * 1024 / 8, latency: 40},
{title: "Regular 4G", download: 4 * 1024 * 1024 / 8, upload: 3 * 1024 * 1024 / 8, latency: 20},
{title: "DSL", download: 2 * 1024 * 1024 / 8, upload: 1 * 1024 * 1024 / 8, latency: 5},
{title: "WiFi", download: 30 * 1024 * 1024 / 8, upload: 15 * 1024 * 1024 / 8, latency: 2}
];
/**
* @param {!WebInspector.NetworkManager.Conditions} conditions
* @param {boolean=} plainText
* @return {!{text: string, title: string}}
*/
WebInspector.NetworkConditionsSelector._conditionsTitle = function(conditions, plainText)
{
var downloadInKbps = conditions.download / (1024 / 8);
var uploadInKbps = conditions.upload / (1024 / 8);
var isThrottling = (downloadInKbps >= 0) || (uploadInKbps >= 0) || (conditions.latency > 0);
var conditionTitle = WebInspector.UIString(conditions.title);
if (!isThrottling)
return {text: conditionTitle, title: conditionTitle};
var downloadText = WebInspector.NetworkConditionsSelector._throughputText(conditions.download, plainText);
var uploadText = WebInspector.NetworkConditionsSelector._throughputText(conditions.upload, plainText);
var pattern = plainText ? "%s (%dms, %s, %s)" : "%s (%dms RTT, %s\u2b07, %s\u2b06)";
var title = WebInspector.UIString(pattern, conditionTitle, conditions.latency, downloadText, uploadText);
return {text: title, title: WebInspector.UIString("Maximum download throughput: %s.\r\nMaximum upload throughput: %s.\r\nMinimum round-trip time: %dms.", downloadText, uploadText, conditions.latency)};
}
WebInspector.NetworkConditionsSelector.prototype = {
_populateOptions: function()
{
var customGroup = {title: WebInspector.UIString("Custom"), items: this._customSetting.get()};
var presetsGroup = {title: WebInspector.UIString("Presets"), items: WebInspector.NetworkConditionsSelector._presets};
var disabledGroup = {title: WebInspector.UIString("Disabled"), items: [WebInspector.NetworkManager.NoThrottlingConditions]};
this._options = this._populateCallback([customGroup, presetsGroup, disabledGroup]);
if (!this._conditionsChanged()) {
for (var i = this._options.length - 1; i >= 0; i--) {
if (this._options[i]) {
this.optionSelected(/** @type {!WebInspector.NetworkManager.Conditions} */ (this._options[i]));
break;
}
}
}
},
revealAndUpdate: function()
{
WebInspector.Revealer.reveal(this._customSetting);
this._conditionsChanged();
},
/**
* @param {!WebInspector.NetworkManager.Conditions} conditions
*/
optionSelected: function(conditions)
{
this._manager.setNetworkConditions(conditions);
},
/**
* @return {boolean}
*/
_conditionsChanged: function()
{
var value = this._manager.networkConditions();
for (var index = 0; index < this._options.length; ++index) {
var option = this._options[index];
if (option && option.download === value.download && option.upload === value.upload && option.latency === value.latency && option.title === value.title) {
this._selectCallback(index);
return true;
}
}
return false;
}
}
/**
* @param {!HTMLSelectElement} selectElement
*/
WebInspector.NetworkConditionsSelector.decorateSelect = function(selectElement)
{
var options = [];
var selector = new WebInspector.NetworkConditionsSelector(populate, select);
selectElement.addEventListener("change", optionSelected, false);
/**
* @param {!Array.<!WebInspector.NetworkConditionsGroup>} groups
* @return {!Array<?WebInspector.NetworkManager.Conditions>}
*/
function populate(groups)
{
selectElement.removeChildren();
options = [];
for (var i = 0; i < groups.length; ++i) {
var group = groups[i];
var groupElement = selectElement.createChild("optgroup");
groupElement.label = group.title;
if (!i) {
groupElement.appendChild(new Option(WebInspector.UIString("Add\u2026"), WebInspector.UIString("Add\u2026")));
options.push(null);
}
for (var conditions of group.items) {
var title = WebInspector.NetworkConditionsSelector._conditionsTitle(conditions, true);
var option = new Option(title.text, title.text);
option.title = title.title;
groupElement.appendChild(option);
options.push(conditions);
}
}
return options;
}
function optionSelected()
{
if (selectElement.selectedIndex === 0)
selector.revealAndUpdate();
else
selector.optionSelected(options[selectElement.selectedIndex]);
}
/**
* @param {number} index
*/
function select(index)
{
if (selectElement.selectedIndex !== index)
selectElement.selectedIndex = index;
}
}
/**
* @return {!WebInspector.ToolbarMenuButton}
*/
WebInspector.NetworkConditionsSelector.createToolbarMenuButton = function()
{
var button = new WebInspector.ToolbarMenuButton(appendItems);
button.setGlyph("");
button.turnIntoSelect();
/** @type {!Array<?WebInspector.NetworkManager.Conditions>} */
var options = [];
var selectedIndex = -1;
var selector = new WebInspector.NetworkConditionsSelector(populate, select);
return button;
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
function appendItems(contextMenu)
{
for (var index = 0; index < options.length; ++index) {
var conditions = options[index];
if (!conditions)
contextMenu.appendSeparator();
else
contextMenu.appendCheckboxItem(WebInspector.NetworkConditionsSelector._conditionsTitle(conditions, true).text, selector.optionSelected.bind(selector, conditions), selectedIndex === index);
}
contextMenu.appendItem(WebInspector.UIString("Edit\u2026"), selector.revealAndUpdate.bind(selector));
}
/**
* @param {!Array.<!WebInspector.NetworkConditionsGroup>} groups
* @return {!Array<?WebInspector.NetworkManager.Conditions>}
*/
function populate(groups)
{
options = [];
for (var group of groups) {
for (var conditions of group.items)
options.push(conditions);
options.push(null);
}
return options;
}
/**
* @param {number} index
*/
function select(index)
{
selectedIndex = index;
button.setText(options[index].title);
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ListWidget.Delegate}
*/
WebInspector.NetworkConditionsSettingsTab = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("components/networkConditionsSettingsTab.css");
this.contentElement.createChild("div", "header").textContent = WebInspector.UIString("Network Throttling Profiles");
var addButton = createTextButton(WebInspector.UIString("Add custom profile..."), this._addButtonClicked.bind(this), "add-conditions-button");
this.contentElement.appendChild(addButton);
this._list = new WebInspector.ListWidget(this);
this._list.element.classList.add("conditions-list");
this._list.registerRequiredCSS("components/networkConditionsSettingsTab.css");
this._list.show(this.contentElement);
this._customSetting = WebInspector.moduleSetting("customNetworkConditions");
this._customSetting.addChangeListener(this._conditionsUpdated, this);
this.setDefaultFocusedElement(addButton);
this.contentElement.tabIndex = 0;
}
WebInspector.NetworkConditionsSettingsTab.prototype = {
wasShown: function()
{
WebInspector.VBox.prototype.wasShown.call(this);
this._conditionsUpdated();
},
_conditionsUpdated: function()
{
this._list.clear();
var conditions = this._customSetting.get();
for (var i = 0; i < conditions.length; ++i)
this._list.appendItem(conditions[i], true);
this._list.appendSeparator();
conditions = WebInspector.NetworkConditionsSelector._presets;
for (var i = 0; i < conditions.length; ++i)
this._list.appendItem(conditions[i], false);
},
_addButtonClicked: function()
{
this._list.addNewItem(this._customSetting.get().length, {title: "", download: -1, upload: -1, latency: 0});
},
/**
* @override
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable)
{
var conditions = /** @type {!WebInspector.NetworkManager.Conditions} */ (item);
var element = createElementWithClass("div", "conditions-list-item");
var title = element.createChild("div", "conditions-list-text conditions-list-title");
var titleText = title.createChild("div", "conditions-list-title-text");
titleText.textContent = conditions.title;
titleText.title = conditions.title;
element.createChild("div", "conditions-list-separator");
element.createChild("div", "conditions-list-text").textContent = WebInspector.NetworkConditionsSelector._throughputText(conditions.download);
element.createChild("div", "conditions-list-separator");
element.createChild("div", "conditions-list-text").textContent = WebInspector.NetworkConditionsSelector._throughputText(conditions.upload);
element.createChild("div", "conditions-list-separator");
element.createChild("div", "conditions-list-text").textContent = WebInspector.UIString("%dms", conditions.latency);
return element;
},
/**
* @override
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index)
{
var list = this._customSetting.get();
list.splice(index, 1);
this._customSetting.set(list);
},
/**
* @override
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew)
{
var conditions = /** @type {?WebInspector.NetworkManager.Conditions} */ (item);
conditions.title = editor.control("title").value.trim();
var download = editor.control("download").value.trim();
conditions.download = download ? parseInt(download, 10) * (1024 / 8) : -1;
var upload = editor.control("upload").value.trim();
conditions.upload = upload ? parseInt(upload, 10) * (1024 / 8) : -1;
var latency = editor.control("latency").value.trim();
conditions.latency = latency ? parseInt(latency, 10) : 0;
var list = this._customSetting.get();
if (isNew)
list.push(conditions);
this._customSetting.set(list);
},
/**
* @override
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item)
{
var conditions = /** @type {?WebInspector.NetworkManager.Conditions} */ (item);
var editor = this._createEditor();
editor.control("title").value = conditions.title;
editor.control("download").value = conditions.download <= 0 ? "" : String(conditions.download / (1024 / 8));
editor.control("upload").value = conditions.upload <= 0 ? "" : String(conditions.upload / (1024 / 8));
editor.control("latency").value = conditions.latency ? String(conditions.latency) : "";
return editor;
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createEditor: function()
{
if (this._editor)
return this._editor;
var editor = new WebInspector.ListWidget.Editor();
this._editor = editor;
var content = editor.contentElement();
var titles = content.createChild("div", "conditions-edit-row");
titles.createChild("div", "conditions-list-text conditions-list-title").textContent = WebInspector.UIString("Profile Name");
titles.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
titles.createChild("div", "conditions-list-text").textContent = WebInspector.UIString("Download");
titles.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
titles.createChild("div", "conditions-list-text").textContent = WebInspector.UIString("Upload");
titles.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
titles.createChild("div", "conditions-list-text").textContent = WebInspector.UIString("Latency");
var fields = content.createChild("div", "conditions-edit-row");
fields.createChild("div", "conditions-list-text conditions-list-title").appendChild(editor.createInput("title", "text", "", titleValidator));
fields.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
var cell = fields.createChild("div", "conditions-list-text");
cell.appendChild(editor.createInput("download", "text", WebInspector.UIString("kb/s"), throughputValidator));
cell.createChild("div", "conditions-edit-optional").textContent = WebInspector.UIString("optional");
fields.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
cell = fields.createChild("div", "conditions-list-text");
cell.appendChild(editor.createInput("upload", "text", WebInspector.UIString("kb/s"), throughputValidator));
cell.createChild("div", "conditions-edit-optional").textContent = WebInspector.UIString("optional");
fields.createChild("div", "conditions-list-separator conditions-list-separator-invisible");
cell = fields.createChild("div", "conditions-list-text");
cell.appendChild(editor.createInput("latency", "text", WebInspector.UIString("ms"), latencyValidator));
cell.createChild("div", "conditions-edit-optional").textContent = WebInspector.UIString("optional");
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function titleValidator(item, index, input)
{
var value = input.value.trim();
return value.length > 0 && value.length < 50;
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function throughputValidator(item, index, input)
{
var value = input.value.trim();
return !value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10000000);
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function latencyValidator(item, index, input)
{
var value = input.value.trim();
return !value || (/^[\d]+$/.test(value) && value >= 0 && value <= 1000000);
}
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.NetworkConditionsActionDelegate = function()
{
}
WebInspector.NetworkConditionsActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
if (actionId === "components.network-online") {
WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.NoThrottlingConditions);
return true;
}
if (actionId === "components.network-offline") {
WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.OfflineConditions);
return true;
}
return false;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | 2 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.PopoverHelper}
* @param {!Element} panelElement
* @param {function(!Element, !Event):(!Element|!AnchorBox|undefined)} getAnchor
* @param {function(!Element, function(!WebInspector.RemoteObject, boolean, !Element=):undefined, string):undefined} queryObject
* @param {function()=} onHide
* @param {boolean=} disableOnClick
*/
WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick)
{
WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
this._queryObject = queryObject;
this._onHideCallback = onHide;
this._popoverObjectGroup = "popover";
panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
};
WebInspector.ObjectPopoverHelper.MaxPopoverTextLength = 10000;
WebInspector.ObjectPopoverHelper.prototype = {
/**
* @param {!Element} element
* @param {!WebInspector.Popover} popover
*/
_showObjectPopover: function(element, popover)
{
/**
* @param {!WebInspector.RemoteObject} funcObject
* @param {!Element} popoverContentElement
* @param {!Element} popoverValueElement
* @param {!Element} anchorElement
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
* @this {WebInspector.ObjectPopoverHelper}
*/
function didGetFunctionProperties(funcObject, popoverContentElement, popoverValueElement, anchorElement, properties, internalProperties)
{
if (internalProperties) {
for (var i = 0; i < internalProperties.length; i++) {
if (internalProperties[i].name === "[[TargetFunction]]") {
funcObject = internalProperties[i].value;
break;
}
}
}
WebInspector.ObjectPropertiesSection.formatObjectAsFunction(funcObject, popoverValueElement, true);
funcObject.functionDetails(didGetFunctionDetails.bind(this, popoverContentElement, anchorElement));
}
/**
* @param {!Element} popoverContentElement
* @param {!Element} anchorElement
* @param {?WebInspector.DebuggerModel.FunctionDetails} response
* @this {WebInspector.ObjectPopoverHelper}
*/
function didGetFunctionDetails(popoverContentElement, anchorElement, response)
{
if (!response || popover.disposed)
return;
var container = createElementWithClass("div", "object-popover-container");
var title = container.createChild("div", "function-popover-title source-code");
var functionName = title.createChild("span", "function-name");
functionName.textContent = WebInspector.beautifyFunctionName(response.functionName);
var rawLocation = response.location;
var sourceURL = response.sourceURL;
if (rawLocation && sourceURL) {
var link = this._lazyLinkifier().linkifyRawLocation(rawLocation, sourceURL, "function-location-link");
title.appendChild(link);
}
container.appendChild(popoverContentElement);
popover.showForAnchor(container, anchorElement);
}
/**
* @param {?WebInspector.DebuggerModel.GeneratorObjectDetails} response
* @this {WebInspector.ObjectPopoverHelper}
*/
function didGetGeneratorObjectDetails(response)
{
if (!response || popover.disposed)
return;
var rawLocation = response.location;
var sourceURL = response.sourceURL;
if (rawLocation && sourceURL) {
var link = this._lazyLinkifier().linkifyRawLocation(rawLocation, sourceURL, "function-location-link");
this._titleElement.appendChild(link);
}
}
/**
* @param {!WebInspector.RemoteObject} result
* @param {boolean} wasThrown
* @param {!Element=} anchorOverride
* @this {WebInspector.ObjectPopoverHelper}
*/
function didQueryObject(result, wasThrown, anchorOverride)
{
if (popover.disposed)
return;
if (wasThrown) {
this.hidePopover();
return;
}
this._objectTarget = result.target();
var anchorElement = anchorOverride || element;
var description = result.description.trimEnd(WebInspector.ObjectPopoverHelper.MaxPopoverTextLength);
var popoverContentElement = null;
if (result.type !== "object") {
popoverContentElement = createElement("span");
WebInspector.appendStyle(popoverContentElement, "components/objectValue.css");
var valueElement = popoverContentElement.createChild("span", "monospace object-value-" + result.type);
valueElement.style.whiteSpace = "pre";
if (result.type === "string")
valueElement.createTextChildren("\"", description, "\"");
else if (result.type !== "function")
valueElement.textContent = description;
if (result.type === "function") {
result.getOwnProperties(didGetFunctionProperties.bind(this, result, popoverContentElement, valueElement, anchorElement));
return;
}
popover.showForAnchor(popoverContentElement, anchorElement);
} else {
if (result.subtype === "node") {
WebInspector.DOMModel.highlightObjectAsDOMNode(result);
this._resultHighlightedAsDOM = true;
}
if (result.customPreview()) {
var customPreviewComponent = new WebInspector.CustomPreviewComponent(result);
customPreviewComponent.expandIfPossible();
popoverContentElement = customPreviewComponent.element;
} else {
popoverContentElement = createElement("div");
this._titleElement = popoverContentElement.createChild("div", "monospace");
this._titleElement.createChild("span", "source-frame-popover-title").textContent = description;
var section = new WebInspector.ObjectPropertiesSection(result, "");
section.element.classList.add("source-frame-popover-tree");
section.titleLessMode();
popoverContentElement.appendChild(section.element);
if (result.subtype === "generator")
result.generatorObjectDetails(didGetGeneratorObjectDetails.bind(this));
}
var popoverWidth = 300;
var popoverHeight = 250;
popover.showForAnchor(popoverContentElement, anchorElement, popoverWidth, popoverHeight);
}
}
this._queryObject(element, didQueryObject.bind(this), this._popoverObjectGroup);
},
_onHideObjectPopover: function()
{
if (this._resultHighlightedAsDOM) {
WebInspector.DOMModel.hideDOMNodeHighlight();
delete this._resultHighlightedAsDOM;
}
if (this._linkifier) {
this._linkifier.dispose();
delete this._linkifier;
}
if (this._onHideCallback)
this._onHideCallback();
if (this._objectTarget) {
this._objectTarget.runtimeAgent().releaseObjectGroup(this._popoverObjectGroup);
delete this._objectTarget;
}
},
/**
* @return {!WebInspector.Linkifier}
*/
_lazyLinkifier: function()
{
if (!this._linkifier)
this._linkifier = new WebInspector.Linkifier();
return this._linkifier;
},
__proto__: WebInspector.PopoverHelper.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {TreeOutlineInShadow}
* @param {!WebInspector.RemoteObject} object
* @param {?string|!Element=} title
* @param {?string=} emptyPlaceholder
* @param {boolean=} ignoreHasOwnProperty
* @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties
*/
WebInspector.ObjectPropertiesSection = function(object, title, emptyPlaceholder, ignoreHasOwnProperty, extraProperties)
{
this._object = object;
this._editable = true;
TreeOutlineInShadow.call(this);
this.hideOverflow();
this.setFocusable(false);
this._objectTreeElement = new WebInspector.ObjectPropertiesSection.RootElement(object, emptyPlaceholder, ignoreHasOwnProperty, extraProperties);
this.appendChild(this._objectTreeElement);
if (typeof title === "string" || !title)
this.element.createChild("span").textContent = title || "";
else
this.element.appendChild(title);
this.element._section = this;
this.registerRequiredCSS("components/objectValue.css");
this.registerRequiredCSS("components/objectPropertiesSection.css");
this.rootElement().childrenListElement.classList.add("source-code", "object-properties-section");
}
/** @const */
WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;
/**
* @param {!WebInspector.RemoteObject} object
* @param {boolean=} skipProto
* @return {!Element}
*/
WebInspector.ObjectPropertiesSection.defaultObjectPresentation = function(object, skipProto)
{
var componentRoot = createElementWithClass("span", "source-code");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(componentRoot, "components/objectValue.css");
shadowRoot.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(object, false));
if (!object.hasChildren)
return componentRoot;
var objectPropertiesSection = new WebInspector.ObjectPropertiesSection(object, componentRoot);
objectPropertiesSection.editable = false;
if (skipProto)
objectPropertiesSection.skipProto();
return objectPropertiesSection.element;
}
WebInspector.ObjectPropertiesSection.prototype = {
skipProto: function()
{
this._skipProto = true;
},
expand: function()
{
this._objectTreeElement.expand();
},
/**
* @return {!TreeElement}
*/
objectTreeElement: function()
{
return this._objectTreeElement;
},
enableContextMenu: function()
{
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false);
},
_contextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(this._object);
contextMenu.show();
},
titleLessMode: function()
{
this._objectTreeElement.listItemElement.classList.add("hidden");
this._objectTreeElement.childrenListElement.classList.add("title-less-mode");
this._objectTreeElement.expand();
},
__proto__: TreeOutlineInShadow.prototype
}
/**
* @param {!WebInspector.RemoteObjectProperty} propertyA
* @param {!WebInspector.RemoteObjectProperty} propertyB
* @return {number}
*/
WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB)
{
var a = propertyA.name;
var b = propertyB.name;
if (a === "__proto__")
return 1;
if (b === "__proto__")
return -1;
if (propertyA.symbol && !propertyB.symbol)
return 1;
if (propertyB.symbol && !propertyA.symbol)
return -1;
return String.naturalOrderComparator(a, b);
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.RemoteObject} object
* @param {?string=} emptyPlaceholder
* @param {boolean=} ignoreHasOwnProperty
* @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties
*/
WebInspector.ObjectPropertiesSection.RootElement = function(object, emptyPlaceholder, ignoreHasOwnProperty, extraProperties)
{
this._object = object;
this._extraProperties = extraProperties || [];
this._ignoreHasOwnProperty = !!ignoreHasOwnProperty;
this._emptyPlaceholder = emptyPlaceholder;
var contentElement = createElement("content");
TreeElement.call(this, contentElement);
this.setExpandable(true);
this.selectable = false;
this.toggleOnClick = true;
this.listItemElement.classList.add("object-properties-section-root-element");
}
WebInspector.ObjectPropertiesSection.RootElement.prototype = {
onexpand: function()
{
if (this.treeOutline)
this.treeOutline.element.classList.add("expanded");
},
oncollapse: function()
{
if (this.treeOutline)
this.treeOutline.element.classList.remove("expanded");
},
/**
* @override
* @param {!Event} e
* @return {boolean}
*/
ondblclick: function(e)
{
return true;
},
onpopulate: function()
{
WebInspector.ObjectPropertyTreeElement._populate(this, this._object, !!this.treeOutline._skipProto, this._emptyPlaceholder, this._ignoreHasOwnProperty, this._extraProperties);
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.RemoteObjectProperty} property
*/
WebInspector.ObjectPropertyTreeElement = function(property)
{
this.property = property;
// Pass an empty title, the title gets made later in onattach.
TreeElement.call(this);
this.toggleOnClick = true;
this.selectable = false;
}
WebInspector.ObjectPropertyTreeElement.prototype = {
onpopulate: function()
{
var propertyValue = /** @type {!WebInspector.RemoteObject} */ (this.property.value);
console.assert(propertyValue);
var skipProto = this.treeOutline ? this.treeOutline._skipProto : true;
var targetValue = this.property.name !== '__proto__' ? propertyValue : this.property.parentObject;
WebInspector.ObjectPropertyTreeElement._populate(this, propertyValue, skipProto, undefined, undefined, undefined, targetValue);
},
/**
* @override
* @return {boolean}
*/
ondblclick: function(event)
{
var editableElement = this.valueElement;
if (!this.property.value.customPreview() && (this.property.writable || this.property.setter) && event.target.isSelfOrDescendant(editableElement))
this._startEditing();
return false;
},
/**
* @override
*/
onattach: function()
{
this.update();
this._updateExpandable();
},
update: function()
{
this.nameElement = WebInspector.ObjectPropertiesSection.createNameElement(this.property.name);
if (!this.property.enumerable)
this.nameElement.classList.add("object-properties-section-dimmed");
if (this.property.isAccessorProperty())
this.nameElement.classList.add("properties-accessor-property-name");
if (this.property.synthetic)
this.nameElement.classList.add("synthetic-property");
if (this.property.symbol)
this.nameElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.symbol), false);
var separatorElement = createElementWithClass("span", "object-properties-section-separator");
separatorElement.textContent = ": ";
if (this.property.value) {
this.valueElement = WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(this.property.value, this.property.wasThrown, this.listItemElement);
this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false);
} else if (this.property.getter) {
this.valueElement = WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(this.property.parentObject, [this.property.name], this._onInvokeGetterClick.bind(this));
} else {
this.valueElement = createElementWithClass("span", "object-value-undefined");
this.valueElement.textContent = WebInspector.UIString("<unreadable>");
this.valueElement.title = WebInspector.UIString("No property getter");
}
this.listItemElement.removeChildren();
this.listItemElement.appendChildren(this.nameElement, separatorElement, this.valueElement);
},
_contextMenuFired: function(value, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(value);
contextMenu.show();
},
_startEditing: function()
{
if (this._prompt || !this.treeOutline._editable || this._readOnly)
return;
this._editableDiv = this.listItemElement.createChild("span");
var text = this.property.value.description;
if (this.property.value.type === "string" && typeof text === "string")
text = "\"" + text + "\"";
this._editableDiv.setTextContentTruncatedIfNeeded(text, WebInspector.UIString("<string is too large to edit>"));
var originalContent = this._editableDiv.textContent;
this.valueElement.classList.add("hidden");
// Lie about our children to prevent expanding on double click and to collapse subproperties.
this.setExpandable(false);
this.listItemElement.classList.add("editing-sub-part");
this._prompt = new WebInspector.ObjectPropertyPrompt();
var proxyElement = this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent));
this.listItemElement.getComponentSelection().setBaseAndExtent(this._editableDiv, 0, this._editableDiv, 1);
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, originalContent), false);
},
_editingEnded: function()
{
this._prompt.detach();
delete this._prompt;
this._editableDiv.remove();
this._updateExpandable();
this.listItemElement.scrollLeft = 0;
this.listItemElement.classList.remove("editing-sub-part");
},
_editingCancelled: function()
{
this.valueElement.classList.remove("hidden");
this._editingEnded();
},
/**
* @param {string} originalContent
*/
_editingCommitted: function(originalContent)
{
var userInput = this._prompt.text();
if (userInput === originalContent) {
this._editingCancelled(); // nothing changed, so cancel
return;
}
this._editingEnded();
this._applyExpression(userInput);
},
/**
* @param {string} originalContent
* @param {!Event} event
*/
_promptKeyDown: function(originalContent, event)
{
if (isEnterKey(event)) {
event.consume(true);
this._editingCommitted(originalContent);
return;
}
if (event.keyIdentifier === "U+001B") { // Esc
event.consume();
this._editingCancelled();
return;
}
},
/**
* @param {string} expression
*/
_applyExpression: function(expression)
{
var property = WebInspector.RemoteObject.toCallArgument(this.property.symbol || this.property.name);
expression = expression.trim();
if (expression)
this.property.parentObject.setPropertyValue(property, expression, callback.bind(this));
else
this.property.parentObject.deleteProperty(property, callback.bind(this));
/**
* @param {?Protocol.Error} error
* @this {WebInspector.ObjectPropertyTreeElement}
*/
function callback(error)
{
if (error) {
this.update();
return;
}
if (!expression) {
// The property was deleted, so remove this tree element.
this.parent.removeChild(this);
} else {
// Call updateSiblings since their value might be based on the value that just changed.
var parent = this.parent;
parent.invalidateChildren();
parent.expand();
}
};
},
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean=} wasThrown
*/
_onInvokeGetterClick: function(result, wasThrown)
{
if (!result)
return;
this.property.value = result;
this.property.wasThrown = wasThrown;
this.update();
this.invalidateChildren();
this._updateExpandable();
},
_updateExpandable: function()
{
if (this.property.value)
this.setExpandable(!this.property.value.customPreview() && this.property.value.hasChildren && !this.property.wasThrown);
else
this.setExpandable(false);
},
__proto__: TreeElement.prototype
}
/**
* @param {!TreeElement} treeElement
* @param {!WebInspector.RemoteObject} value
* @param {boolean} skipProto
* @param {?string=} emptyPlaceholder
* @param {boolean=} flattenProtoChain
* @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties
* @param {!WebInspector.RemoteObject=} targetValue
*/
WebInspector.ObjectPropertyTreeElement._populate = function(treeElement, value, skipProto, emptyPlaceholder, flattenProtoChain, extraProperties, targetValue)
{
if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
treeElement.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
return;
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
*/
function callback(properties, internalProperties)
{
treeElement.removeChildren();
if (!properties)
return;
extraProperties = extraProperties || [];
for (var i = 0; i < extraProperties.length; ++i)
properties.push(extraProperties[i]);
WebInspector.ObjectPropertyTreeElement.populateWithProperties(treeElement, properties, internalProperties,
skipProto, targetValue || value, emptyPlaceholder);
}
if (flattenProtoChain)
value.getAllProperties(false, callback);
else
WebInspector.RemoteObject.loadFromObjectPerProto(value, callback);
}
/**
* @param {!TreeElement} treeNode
* @param {!Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
* @param {boolean} skipProto
* @param {?WebInspector.RemoteObject} value
* @param {?string=} emptyPlaceholder
*/
WebInspector.ObjectPropertyTreeElement.populateWithProperties = function(treeNode, properties, internalProperties, skipProto, value, emptyPlaceholder) {
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (skipProto && property.name === "__proto__")
continue;
if (property.isAccessorProperty()) {
if (property.name !== "__proto__" && property.getter) {
property.parentObject = value;
treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(property));
}
if (property.isOwn) {
if (property.getter) {
var getterProperty = new WebInspector.RemoteObjectProperty("get " + property.name, property.getter);
getterProperty.parentObject = value;
treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(getterProperty));
}
if (property.setter) {
var setterProperty = new WebInspector.RemoteObjectProperty("set " + property.name, property.setter);
setterProperty.parentObject = value;
treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(setterProperty));
}
}
} else {
property.parentObject = value;
treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(property));
}
}
if (internalProperties) {
for (var i = 0; i < internalProperties.length; i++) {
internalProperties[i].parentObject = value;
treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(internalProperties[i]));
}
}
if (value && value.type === "function") {
// Whether function has TargetFunction internal property.
// This is a simple way to tell that the function is actually a bound function (we are not told).
// Bound function never has inner scope and doesn't need corresponding UI node.
var hasTargetFunction = false;
if (internalProperties) {
for (var i = 0; i < internalProperties.length; i++) {
if (internalProperties[i].name == "[[TargetFunction]]") {
hasTargetFunction = true;
break;
}
}
}
if (!hasTargetFunction)
treeNode.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
}
if (value && value.type === "object" && (value.subtype === "map" || value.subtype === "set" || value.subtype === "iterator"))
treeNode.appendChild(new WebInspector.CollectionEntriesMainTreeElement(value));
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(treeNode, emptyPlaceholder);
}
/**
* @param {!TreeElement} treeNode
* @param {?string=} emptyPlaceholder
*/
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded = function(treeNode, emptyPlaceholder)
{
if (treeNode.childCount())
return;
var title = createElementWithClass("div", "info");
title.textContent = emptyPlaceholder || WebInspector.UIString("No Properties");
var infoElement = new TreeElement(title);
treeNode.appendChild(infoElement);
}
/**
* @param {?WebInspector.RemoteObject} object
* @param {!Array.<string>} propertyPath
* @param {function(?WebInspector.RemoteObject, boolean=)} callback
* @return {!Element}
*/
WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan = function(object, propertyPath, callback)
{
var rootElement = createElement("span");
var element = rootElement.createChild("span");
element.textContent = WebInspector.UIString("(...)");
if (!object)
return rootElement;
element.classList.add("object-value-calculate-value-button");
element.title = WebInspector.UIString("Invoke property getter");
element.addEventListener("click", onInvokeGetterClick, false);
function onInvokeGetterClick(event)
{
event.consume();
object.getProperty(propertyPath, callback);
}
return rootElement;
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.RemoteObject} remoteObject
*/
WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
{
TreeElement.call(this, "<function scope>", true);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
}
WebInspector.FunctionScopeMainTreeElement.prototype = {
onpopulate: function()
{
/**
* @param {?WebInspector.DebuggerModel.FunctionDetails} response
* @this {WebInspector.FunctionScopeMainTreeElement}
*/
function didGetDetails(response)
{
if (!response)
return;
this.removeChildren();
var scopeChain = response.scopeChain || [];
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
var isTrueObject = false;
switch (scope.type) {
case DebuggerAgent.ScopeType.Local:
// Not really expecting this scope type here.
title = WebInspector.UIString("Local");
break;
case DebuggerAgent.ScopeType.Closure:
title = WebInspector.UIString("Closure");
break;
case DebuggerAgent.ScopeType.Catch:
title = WebInspector.UIString("Catch");
break;
case DebuggerAgent.ScopeType.Block:
title = WebInspector.UIString("Block");
break;
case DebuggerAgent.ScopeType.Script:
title = WebInspector.UIString("Script");
break;
case DebuggerAgent.ScopeType.With:
title = WebInspector.UIString("With Block");
isTrueObject = true;
break;
case DebuggerAgent.ScopeType.Global:
title = WebInspector.UIString("Global");
isTrueObject = true;
break;
default:
console.error("Unknown scope type: " + scope.type);
continue;
}
var runtimeModel = this._remoteObject.target().runtimeModel;
if (isTrueObject) {
var remoteObject = runtimeModel.createRemoteObject(scope.object);
var property = new WebInspector.RemoteObjectProperty(title, remoteObject);
property.writable = false;
property.parentObject = null;
this.appendChild(new WebInspector.ObjectPropertyTreeElement(property));
} else {
var scopeRef = new WebInspector.ScopeRef(i, undefined);
var remoteObject = runtimeModel.createScopeRemoteObject(scope.object, scopeRef);
var scopeTreeElement = new WebInspector.ScopeTreeElement(title, remoteObject);
this.appendChild(scopeTreeElement);
}
}
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(this, WebInspector.UIString("No Scopes"));
}
this._remoteObject.functionDetails(didGetDetails.bind(this));
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.RemoteObject} remoteObject
*/
WebInspector.CollectionEntriesMainTreeElement = function(remoteObject)
{
TreeElement.call(this, "<entries>", true);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.expand();
}
WebInspector.CollectionEntriesMainTreeElement.prototype = {
onpopulate: function()
{
/**
* @param {?Array.<!DebuggerAgent.CollectionEntry>} entries
* @this {WebInspector.CollectionEntriesMainTreeElement}
*/
function didGetCollectionEntries(entries)
{
if (!entries)
return;
this.removeChildren();
var entriesLocalObject = [];
var runtimeModel = this._remoteObject.target().runtimeModel;
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.key) {
entriesLocalObject.push(new WebInspector.MapEntryLocalJSONObject({
key: runtimeModel.createRemoteObject(entry.key),
value: runtimeModel.createRemoteObject(entry.value)
}));
} else {
entriesLocalObject.push(runtimeModel.createRemoteObject(entry.value));
}
}
WebInspector.ObjectPropertyTreeElement._populate(this, WebInspector.RemoteObject.fromLocalObject(entriesLocalObject), true, WebInspector.UIString("No Entries"));
this.title = "<entries>[" + entriesLocalObject.length + "]";
}
this._remoteObject.collectionEntries(didGetCollectionEntries.bind(this));
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {string} title
* @param {!WebInspector.RemoteObject} remoteObject
*/
WebInspector.ScopeTreeElement = function(title, remoteObject)
{
TreeElement.call(this, title, true);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
}
WebInspector.ScopeTreeElement.prototype = {
onpopulate: function()
{
WebInspector.ObjectPropertyTreeElement._populate(this, this._remoteObject, false);
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.RemoteObject} object
* @param {number} fromIndex
* @param {number} toIndex
* @param {number} propertyCount
*/
WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount)
{
TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), true);
this.toggleOnClick = true;
this.selectable = false;
this._fromIndex = fromIndex;
this._toIndex = toIndex;
this._object = object;
this._readOnly = true;
this._propertyCount = propertyCount;
}
WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100;
WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold = 250000;
WebInspector.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold = 500000;
/**
* @param {!TreeElement} treeNode
* @param {!WebInspector.RemoteObject} object
* @param {number} fromIndex
* @param {number} toIndex
*/
WebInspector.ArrayGroupingTreeElement._populateArray = function(treeNode, object, fromIndex, toIndex)
{
WebInspector.ArrayGroupingTreeElement._populateRanges(treeNode, object, fromIndex, toIndex, true);
}
/**
* @param {!TreeElement} treeNode
* @param {!WebInspector.RemoteObject} object
* @param {number} fromIndex
* @param {number} toIndex
* @param {boolean} topLevel
* @this {WebInspector.ArrayGroupingTreeElement}
*/
WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeNode, object, fromIndex, toIndex, topLevel)
{
object.callFunctionJSON(packRanges, [
{ value: fromIndex },
{ value: toIndex },
{ value: WebInspector.ArrayGroupingTreeElement._bucketThreshold },
{ value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold },
{ value: WebInspector.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold }
], callback);
/**
* Note: must declare params as optional.
* @param {number=} fromIndex
* @param {number=} toIndex
* @param {number=} bucketThreshold
* @param {number=} sparseIterationThreshold
* @param {number=} getOwnPropertyNamesThreshold
* @suppressReceiverCheck
* @this {Object}
*/
function packRanges(fromIndex, toIndex, bucketThreshold, sparseIterationThreshold, getOwnPropertyNamesThreshold)
{
var ownPropertyNames = null;
var consecutiveRange = (toIndex - fromIndex >= sparseIterationThreshold) && ArrayBuffer.isView(this);
var skipGetOwnPropertyNames = consecutiveRange && (toIndex - fromIndex >= getOwnPropertyNamesThreshold);
function* arrayIndexes(object)
{
if (toIndex - fromIndex < sparseIterationThreshold) {
for (var i = fromIndex; i <= toIndex; ++i) {
if (i in object)
yield i;
}
} else {
ownPropertyNames = ownPropertyNames || Object.getOwnPropertyNames(object);
for (var i = 0; i < ownPropertyNames.length; ++i) {
var name = ownPropertyNames[i];
var index = name >>> 0;
if (("" + index) === name && fromIndex <= index && index <= toIndex)
yield index;
}
}
}
var count = 0;
if (consecutiveRange) {
count = toIndex - fromIndex + 1;
} else {
for (var i of arrayIndexes(this))
++count;
}
var bucketSize = count;
if (count <= bucketThreshold)
bucketSize = count;
else
bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);
var ranges = [];
if (consecutiveRange) {
for (var i = fromIndex; i <= toIndex; i += bucketSize) {
var groupStart = i;
var groupEnd = groupStart + bucketSize - 1;
if (groupEnd > toIndex)
groupEnd = toIndex;
ranges.push([groupStart, groupEnd, groupEnd - groupStart + 1]);
}
} else {
count = 0;
var groupStart = -1;
var groupEnd = 0;
for (var i of arrayIndexes(this)) {
if (groupStart === -1)
groupStart = i;
groupEnd = i;
if (++count === bucketSize) {
ranges.push([groupStart, groupEnd, count]);
count = 0;
groupStart = -1;
}
}
if (count > 0)
ranges.push([groupStart, groupEnd, count]);
}
return { ranges: ranges, skipGetOwnPropertyNames: skipGetOwnPropertyNames };
}
function callback(result)
{
if (!result)
return;
var ranges = /** @type {!Array.<!Array.<number>>} */ (result.ranges);
if (ranges.length == 1) {
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, ranges[0][0], ranges[0][1]);
} else {
for (var i = 0; i < ranges.length; ++i) {
var fromIndex = ranges[i][0];
var toIndex = ranges[i][1];
var count = ranges[i][2];
if (fromIndex == toIndex)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, fromIndex, toIndex);
else
treeNode.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
}
}
if (topLevel)
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeNode, object, result.skipGetOwnPropertyNames);
}
}
/**
* @param {!TreeElement} treeNode
* @param {!WebInspector.RemoteObject} object
* @param {number} fromIndex
* @param {number} toIndex
* @this {WebInspector.ArrayGroupingTreeElement}
*/
WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeNode, object, fromIndex, toIndex)
{
object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], processArrayFragment.bind(this));
/**
* @suppressReceiverCheck
* @this {Object}
* @param {number=} fromIndex // must declare optional
* @param {number=} toIndex // must declare optional
* @param {number=} sparseIterationThreshold // must declare optional
*/
function buildArrayFragment(fromIndex, toIndex, sparseIterationThreshold)
{
var result = Object.create(null);
if (toIndex - fromIndex < sparseIterationThreshold) {
for (var i = fromIndex; i <= toIndex; ++i) {
if (i in this)
result[i] = this[i];
}
} else {
var ownPropertyNames = Object.getOwnPropertyNames(this);
for (var i = 0; i < ownPropertyNames.length; ++i) {
var name = ownPropertyNames[i];
var index = name >>> 0;
if (String(index) === name && fromIndex <= index && index <= toIndex)
result[index] = this[index];
}
}
return result;
}
/**
* @param {?WebInspector.RemoteObject} arrayFragment
* @param {boolean=} wasThrown
* @this {WebInspector.ArrayGroupingTreeElement}
*/
function processArrayFragment(arrayFragment, wasThrown)
{
if (!arrayFragment || wasThrown)
return;
arrayFragment.getAllProperties(false, processProperties.bind(this));
}
/** @this {WebInspector.ArrayGroupingTreeElement} */
function processProperties(properties, internalProperties)
{
if (!properties)
return;
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new WebInspector.ObjectPropertyTreeElement(properties[i]);
childTreeElement._readOnly = true;
treeNode.appendChild(childTreeElement);
}
}
}
/**
* @param {!TreeElement} treeNode
* @param {!WebInspector.RemoteObject} object
* @param {boolean} skipGetOwnPropertyNames
* @this {WebInspector.ArrayGroupingTreeElement}
*/
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeNode, object, skipGetOwnPropertyNames)
{
object.callFunction(buildObjectFragment, [{value: skipGetOwnPropertyNames}], processObjectFragment.bind(this));
/**
* @param {boolean=} skipGetOwnPropertyNames
* @suppressReceiverCheck
* @this {Object}
*/
function buildObjectFragment(skipGetOwnPropertyNames)
{
var result = { __proto__: this.__proto__ };
if (skipGetOwnPropertyNames)
return result;
var names = Object.getOwnPropertyNames(this);
for (var i = 0; i < names.length; ++i) {
var name = names[i];
// Array index check according to the ES5-15.4.
if (String(name >>> 0) === name && name >>> 0 !== 0xffffffff)
continue;
var descriptor = Object.getOwnPropertyDescriptor(this, name);
if (descriptor)
Object.defineProperty(result, name, descriptor);
}
return result;
}
/**
* @param {?WebInspector.RemoteObject} arrayFragment
* @param {boolean=} wasThrown
* @this {WebInspector.ArrayGroupingTreeElement}
*/
function processObjectFragment(arrayFragment, wasThrown)
{
if (!arrayFragment || wasThrown)
return;
arrayFragment.getOwnProperties(processProperties.bind(this));
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>=} internalProperties
* @this {WebInspector.ArrayGroupingTreeElement}
*/
function processProperties(properties, internalProperties)
{
if (!properties)
return;
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new WebInspector.ObjectPropertyTreeElement(properties[i]);
childTreeElement._readOnly = true;
treeNode.appendChild(childTreeElement);
}
}
}
WebInspector.ArrayGroupingTreeElement.prototype = {
onpopulate: function()
{
if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {
WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false);
return;
}
WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex);
},
onattach: function()
{
this.listItemElement.classList.add("object-properties-section-name");
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.TextPrompt}
*/
WebInspector.ObjectPropertyPrompt = function()
{
WebInspector.TextPrompt.call(this, WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);
this.setSuggestBoxEnabled(true);
}
WebInspector.ObjectPropertyPrompt.prototype = {
__proto__: WebInspector.TextPrompt.prototype
}
/**
* @param {?string} name
* @return {!Element}
*/
WebInspector.ObjectPropertiesSection.createNameElement = function(name)
{
var nameElement = createElementWithClass("span", "name");
if (/^\s|\s$|^$|\n/.test(name))
nameElement.createTextChildren("\"", name.replace(/\n/g, "\u21B5"), "\"");
else
nameElement.textContent = name;
return nameElement;
}
/**
* @param {?string=} description
* @return {string} valueText
*/
WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription = function(description)
{
var text = description.replace(/^function [gs]et /, "function ");
var matches = /function\s([^)]*)/.exec(text);
if (!matches) {
// process shorthand methods
matches = /[^(]*(\([^)]*)/.exec(text);
}
var match = matches ? matches[1] : null;
return match ? match.replace(/\n/g, " ") + ")" : (text || "");
}
/**
* @param {!WebInspector.RemoteObject} value
* @param {boolean} wasThrown
* @param {!Element=} parentElement
* @return {!Element}
*/
WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport = function(value, wasThrown, parentElement)
{
if (value.customPreview()) {
var result = (new WebInspector.CustomPreviewComponent(value)).element;
result.classList.add("object-properties-section-custom-section");
return result
}
return WebInspector.ObjectPropertiesSection.createValueElement(value, wasThrown, parentElement);
}
/**
* @param {!WebInspector.RemoteObject} value
* @param {boolean} wasThrown
* @param {!Element=} parentElement
* @return {!Element}
*/
WebInspector.ObjectPropertiesSection.createValueElement = function(value, wasThrown, parentElement)
{
var valueElement = createElementWithClass("span", "value");
var type = value.type;
var subtype = value.subtype;
var description = value.description;
var prefix;
var valueText;
var suffix;
if (wasThrown) {
prefix = "[Exception: ";
valueText = description;
suffix = "]";
} else if (type === "string" && typeof description === "string") {
// Render \n as a nice unicode cr symbol.
prefix = "\"";
valueText = description.replace(/\n/g, "\u21B5");
suffix = "\"";
} else if (type === "function") {
valueText = WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription(description);
} else if (type !== "object" || subtype !== "node") {
valueText = description;
}
if (type !== "number" || valueText.indexOf("e") === -1) {
valueElement.setTextContentTruncatedIfNeeded(valueText || "");
if (prefix)
valueElement.insertBefore(createTextNode(prefix), valueElement.firstChild);
if (suffix)
valueElement.createTextChild(suffix);
} else {
var numberParts = valueText.split("e");
var mantissa = valueElement.createChild("span", "object-value-scientific-notation-mantissa");
mantissa.textContent = numberParts[0];
var exponent = valueElement.createChild("span", "object-value-scientific-notation-exponent");
exponent.textContent = "e" + numberParts[1];
valueElement.classList.add("object-value-scientific-notation-number");
if (parentElement) // FIXME: do it in the caller.
parentElement.classList.add("hbox");
}
if (wasThrown)
valueElement.classList.add("error");
if (subtype || type)
valueElement.classList.add("object-value-" + (subtype || type));
if (type === "object" && subtype === "node" && description) {
WebInspector.DOMPresentationUtils.createSpansForNodeTitle(valueElement, description);
valueElement.addEventListener("click", mouseClick, false);
valueElement.addEventListener("mousemove", mouseMove, false);
valueElement.addEventListener("mouseleave", mouseLeave, false);
} else {
valueElement.title = description || "";
}
function mouseMove()
{
WebInspector.DOMModel.highlightObjectAsDOMNode(value);
}
function mouseLeave()
{
WebInspector.DOMModel.hideDOMNodeHighlight();
}
/**
* @param {!Event} event
*/
function mouseClick(event)
{
WebInspector.Revealer.reveal(value);
event.consume(true);
}
return valueElement;
}
/**
* @param {!WebInspector.RemoteObject} func
* @param {!Element} element
* @param {boolean} linkify
* @param {boolean=} includePreview
*/
WebInspector.ObjectPropertiesSection.formatObjectAsFunction = function(func, element, linkify, includePreview)
{
func.functionDetails(didGetDetails);
/**
* @param {?WebInspector.DebuggerModel.FunctionDetails} response
*/
function didGetDetails(response)
{
if (!response) {
var valueText = WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription(func.description);
element.createTextChild(valueText);
return;
}
if (linkify && response && response.location) {
var anchor = createElement("span");
element.classList.add("linkified");
element.appendChild(anchor);
element.addEventListener("click", WebInspector.Revealer.reveal.bind(WebInspector.Revealer, response.location, undefined));
element = anchor;
}
var text = func.description.substring(0, 200);
if (includePreview) {
element.textContent = text.replace(/^function /, "") + (func.description.length > 200 ? "\u2026" : "");
return;
}
// Now parse description and get the real params and title.
self.runtime.instancePromise(WebInspector.TokenizerFactory).then(processTokens);
var params = null;
var functionName = response ? response.functionName : "";
/**
* @param {!WebInspector.TokenizerFactory} tokenizerFactory
*/
function processTokens(tokenizerFactory)
{
var tokenize = tokenizerFactory.createTokenizer("text/javascript");
tokenize(text, processToken);
element.textContent = (functionName || "anonymous") + "(" + (params || []).join(", ") + ")";
}
var doneProcessing = false;
/**
* @param {string} token
* @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
*/
function processToken(token, tokenType, column, newColumn)
{
if (!params && tokenType === "js-def" && !functionName)
functionName = token;
doneProcessing = doneProcessing || token === ")";
if (doneProcessing)
return;
if (token === "(") {
params = [];
return;
}
if (params && tokenType === "js-def")
params.push(token);
}
}
}
/**
* @constructor
*/
WebInspector.ObjectPropertiesSectionExpandController = function()
{
/** @type {!Set.<string>} */
this._expandedProperties = new Set();
}
WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol = Symbol("cachedPath");
WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId = Symbol("treeOutlineId");
WebInspector.ObjectPropertiesSectionExpandController.prototype = {
/**
* @param {string} id
* @param {!WebInspector.ObjectPropertiesSection} section
*/
watchSection: function(id, section)
{
section.addEventListener(TreeOutline.Events.ElementAttached, this._elementAttached, this);
section.addEventListener(TreeOutline.Events.ElementExpanded, this._elementExpanded, this);
section.addEventListener(TreeOutline.Events.ElementCollapsed, this._elementCollapsed, this);
section[WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId] = id;
if (this._expandedProperties.has(id))
section.expand();
},
/**
* @param {string} id
*/
stopWatchSectionsWithId: function(id)
{
for (var property of this._expandedProperties) {
if (property.startsWith(id + ":"))
this._expandedProperties.delete(property);
}
},
/**
* @param {!WebInspector.Event} event
*/
_elementAttached: function(event)
{
var element = /** @type {!TreeElement} */ (event.data);
if (element.isExpandable() && this._expandedProperties.has(this._propertyPath(element)))
element.expand();
},
/**
* @param {!WebInspector.Event} event
*/
_elementExpanded: function(event)
{
var element = /** @type {!TreeElement} */ (event.data);
this._expandedProperties.add(this._propertyPath(element));
},
/**
* @param {!WebInspector.Event} event
*/
_elementCollapsed: function(event)
{
var element = /** @type {!TreeElement} */ (event.data);
this._expandedProperties.delete(this._propertyPath(element));
},
/**
* @param {!TreeElement} treeElement
* @return {string}
*/
_propertyPath: function(treeElement)
{
var cachedPropertyPath = treeElement[WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol];
if (cachedPropertyPath)
return cachedPropertyPath;
var current = treeElement;
var rootElement = treeElement.treeOutline.objectTreeElement();
var result;
while (current !== rootElement) {
var currentName = "";
if (current.property)
currentName = current.property.name;
else
currentName = typeof current.title === "string" ? current.title : current.title.textContent;
result = currentName + (result ? "." + result : "");
current = current.parent;
}
var treeOutlineId = treeElement.treeOutline[WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId];
result = treeOutlineId + (result ? ":" + result : "");
treeElement[WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol] = result;
return result;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. WebInspector.reload = function() { if (WebInspector.dockController.canDock() && WebInspector.dockController.dockSide() === WebInspector.DockController.State.Undocked) InspectorFrontendHost.setIsDocked(true, function() {}); window.location.reload(); } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.RemoteObjectPreviewFormatter = function() { } WebInspector.RemoteObjectPreviewFormatter.prototype = { /** * @param {!Element} parentElement * @param {!RuntimeAgent.ObjectPreview} preview * @return {boolean} true iff preview captured all information. */ appendObjectPreview: function(parentElement, preview) { var description = preview.description; if (preview.type !== "object" || preview.subtype === "null") { parentElement.appendChild(this.renderPropertyPreview(preview.type, preview.subtype, description)); return true; } if (description && preview.subtype !== "array") { var text = preview.subtype ? description : this._abbreviateFullQualifiedClassName(description); parentElement.createTextChildren(text, " "); } if (preview.entries) return this._appendEntriesPreview(parentElement, preview); return this._appendPropertiesPreview(parentElement, preview); }, /** * @param {string} description * @return {string} */ _abbreviateFullQualifiedClassName: function(description) { var abbreviatedDescription = description.split("."); for (var i = 0; i < abbreviatedDescription.length - 1; ++i) abbreviatedDescription[i] = abbreviatedDescription[i].trimMiddle(3); return abbreviatedDescription.join("."); }, /** * @param {!Element} parentElement * @param {!RuntimeAgent.ObjectPreview} preview * @return {boolean} true iff preview captured all information. */ _appendPropertiesPreview: function(parentElement, preview) { var isArray = preview.subtype === "array"; var arrayLength = WebInspector.RemoteObject.arrayLength(preview); var properties = preview.properties; if (isArray) properties = properties.slice().stableSort(compareIndexesFirst); /** * @param {!RuntimeAgent.PropertyPreview} a * @param {!RuntimeAgent.PropertyPreview} b */ function compareIndexesFirst(a, b) { var index1 = toArrayIndex(a.name); var index2 = toArrayIndex(b.name); if (index1 < 0) return index2 < 0 ? 0 : 1; return index2 < 0 ? -1 : index1 - index2; } /** * @param {string} name * @return {number} */ function toArrayIndex(name) { var index = name >>> 0; if (String(index) === name && index < arrayLength) return index; return -1; } parentElement.createTextChild(isArray ? "[" : "{"); for (var i = 0; i < properties.length; ++i) { if (i > 0) parentElement.createTextChild(", "); var property = properties[i]; var name = property.name; if (!isArray || name != i || i >= arrayLength) { if (/^\s|\s$|^$|\n/.test(name)) parentElement.createChild("span", "name").createTextChildren("\"", name.replace(/\n/g, "\u21B5"), "\""); else parentElement.createChild("span", "name").textContent = name; parentElement.createTextChild(": "); } parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property])); } if (preview.overflow) parentElement.createChild("span").textContent = "\u2026"; parentElement.createTextChild(isArray ? "]" : "}"); return preview.lossless; }, /** * @param {!Element} parentElement * @param {!RuntimeAgent.ObjectPreview} preview * @return {boolean} true iff preview captured all information. */ _appendEntriesPreview: function(parentElement, preview) { var lossless = preview.lossless && !preview.properties.length; parentElement.createTextChild("{"); for (var i = 0; i < preview.entries.length; ++i) { if (i > 0) parentElement.createTextChild(", "); var entry = preview.entries[i]; if (entry.key) { this.appendObjectPreview(parentElement, entry.key); parentElement.createTextChild(" => "); } this.appendObjectPreview(parentElement, entry.value); } if (preview.overflow) parentElement.createChild("span").textContent = "\u2026"; parentElement.createTextChild("}"); return lossless; }, /** * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath * @return {!Element} */ _renderPropertyPreviewOrAccessor: function(propertyPath) { var property = propertyPath.peekLast(); return this.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value); }, /** * @param {string} type * @param {string=} subtype * @param {string=} description * @return {!Element} */ renderPropertyPreview: function(type, subtype, description) { var span = createElementWithClass("span", "object-value-" + (subtype || type)); description = description || ""; if (type === "function") { span.textContent = "function"; return span; } if (type === "object" && subtype === "node" && description) { span.classList.add("object-value-preview-node"); WebInspector.DOMPresentationUtils.createSpansForNodeTitle(span, description); return span; } if (type === "string") { span.createTextChildren("\"", description.replace(/\n/g, "\u21B5"), "\""); return span; } if (type === "object" && !subtype) { span.textContent = this._abbreviateFullQualifiedClassName(description); return span; } span.textContent = description; return span; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.RequestAppBannerActionDelegate = function()
{
}
WebInspector.RequestAppBannerActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var target = WebInspector.targetManager.mainTarget();
if (target && target.isPage()) {
target.pageAgent().requestAppBanner();
WebInspector.console.show();
}
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | 2 1 | /* * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.ShortcutsScreen = function() { /** @type {!Object.<string, !WebInspector.ShortcutsSection>} */ this._sections = {}; } WebInspector.ShortcutsScreen.prototype = { /** * @param {string} name * @return {!WebInspector.ShortcutsSection} */ section: function(name) { var section = this._sections[name]; if (!section) this._sections[name] = section = new WebInspector.ShortcutsSection(name); return section; }, /** * @return {!WebInspector.Widget} */ createShortcutsTabView: function() { var orderedSections = []; for (var section in this._sections) orderedSections.push(this._sections[section]); function compareSections(a, b) { return a.order - b.order; } orderedSections.sort(compareSections); var widget = new WebInspector.Widget(); widget.element.className = "settings-tab-container"; // Override widget.element.createChild("header").createChild("h3").createTextChild(WebInspector.UIString("Shortcuts")); var scrollPane = widget.element.createChild("div", "help-container-wrapper"); var container = scrollPane.createChild("div"); container.className = "help-content help-container"; for (var i = 0; i < orderedSections.length; ++i) orderedSections[i].renderSection(container); var note = scrollPane.createChild("p", "help-footnote"); note.appendChild(WebInspector.linkifyDocumentationURLAsNode("iterate/inspect-styles/shortcuts", WebInspector.UIString("Full list of DevTools keyboard shortcuts and gestures"))); return widget; } } /** * We cannot initialize it here as localized strings are not loaded yet. * @type {!WebInspector.ShortcutsScreen} */ WebInspector.shortcutsScreen; /** * @constructor * @param {string} name */ WebInspector.ShortcutsSection = function(name) { this.name = name; this._lines = /** @type {!Array.<!{key: !Node, text: string}>} */ ([]); this.order = ++WebInspector.ShortcutsSection._sequenceNumber; }; WebInspector.ShortcutsSection._sequenceNumber = 0; WebInspector.ShortcutsSection.prototype = { /** * @param {!WebInspector.KeyboardShortcut.Descriptor} key * @param {string} description */ addKey: function(key, description) { this._addLine(this._renderKey(key), description); }, /** * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys * @param {string} description */ addRelatedKeys: function(keys, description) { this._addLine(this._renderSequence(keys, "/"), description); }, /** * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys * @param {string} description */ addAlternateKeys: function(keys, description) { this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description); }, /** * @param {!Node} keyElement * @param {string} description */ _addLine: function(keyElement, description) { this._lines.push({ key: keyElement, text: description }); }, /** * @param {!Element} container */ renderSection: function(container) { var parent = container.createChild("div", "help-block"); var headLine = parent.createChild("div", "help-line"); headLine.createChild("div", "help-key-cell"); headLine.createChild("div", "help-section-title help-cell").textContent = this.name; for (var i = 0; i < this._lines.length; ++i) { var line = parent.createChild("div", "help-line"); var keyCell = line.createChild("div", "help-key-cell"); keyCell.appendChild(this._lines[i].key); keyCell.appendChild(this._createSpan("help-key-delimiter", ":")); line.createChild("div", "help-cell").textContent = this._lines[i].text; } }, /** * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} sequence * @param {string} delimiter * @return {!Node} */ _renderSequence: function(sequence, delimiter) { var delimiterSpan = this._createSpan("help-key-delimiter", delimiter); return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan); }, /** * @param {!WebInspector.KeyboardShortcut.Descriptor} key * @return {!Node} */ _renderKey: function(key) { var keyName = key.name; var plus = this._createSpan("help-combine-keys", "+"); return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this, "help-key")), plus); }, /** * @param {string} className * @param {string} textContent * @return {!Element} */ _createSpan: function(className, textContent) { var node = createElement("span"); node.className = className; node.textContent = textContent; return node; }, /** * @param {!Array.<!Element>} nodes * @param {!Element} delimiter * @return {!Node} */ _joinNodes: function(nodes, delimiter) { var result = createDocumentFragment(); for (var i = 0; i < nodes.length; ++i) { if (i > 0) result.appendChild(delimiter.cloneNode(true)); result.appendChild(nodes[i]); } return result; } } WebInspector.ShortcutsScreen.registerShortcuts = function() { // Elements panel var elementsSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel")); var navigate = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateUp.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateDown); elementsSection.addRelatedKeys(navigate, WebInspector.UIString("Navigate elements")); var expandCollapse = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Expand.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Collapse); elementsSection.addRelatedKeys(expandCollapse, WebInspector.UIString("Expand/collapse")); elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.EditAttribute, WebInspector.UIString("Edit attribute")); elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.HideElement, WebInspector.UIString("Hide element")); elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.ToggleEditAsHTML, WebInspector.UIString("Toggle edit as HTML")); var stylesPaneSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane")); var nextPreviousProperty = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NextProperty.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.PreviousProperty); stylesPaneSection.addRelatedKeys(nextPreviousProperty, WebInspector.UIString("Next/previous property")); stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementValue, WebInspector.UIString("Increment value")); stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementValue, WebInspector.UIString("Decrement value")); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy10, WebInspector.UIString("Increment by %f", 10)); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy10, WebInspector.UIString("Decrement by %f", 10)); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy100, WebInspector.UIString("Increment by %f", 100)); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy100, WebInspector.UIString("Decrement by %f", 100)); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy01, WebInspector.UIString("Increment by %f", 0.1)); stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy01, WebInspector.UIString("Decrement by %f", 0.1)); // Debugger var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Debugger")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.toggle-pause"), WebInspector.UIString("Pause/ Continue")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-over"), WebInspector.UIString("Step over")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-into"), WebInspector.UIString("Step into")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-out"), WebInspector.UIString("Step out")); var nextAndPrevFrameKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame.concat(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame); section.addRelatedKeys(nextAndPrevFrameKeys, WebInspector.UIString("Next/previous call frame")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.EvaluateSelectionInConsole, WebInspector.UIString("Evaluate selection in console")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.AddSelectionToWatch, WebInspector.UIString("Add selection to watch")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, WebInspector.UIString("Toggle breakpoint")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.toggle-breakpoints-active"), WebInspector.UIString("Toggle all breakpoints")); // Editing section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Text Editor")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, WebInspector.UIString("Go to member")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleAutocompletion, WebInspector.UIString("Autocompletion")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, WebInspector.UIString("Go to line")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation, WebInspector.UIString("Jump to previous editing location")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation, WebInspector.UIString("Jump to next editing location")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment, WebInspector.UIString("Toggle comment")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByOne, WebInspector.UIString("Increment CSS unit by 1")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByOne, WebInspector.UIString("Decrement CSS unit by 1")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByTen, WebInspector.UIString("Increment CSS unit by 10")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByTen, WebInspector.UIString("Decrement CSS unit by 10")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SelectNextOccurrence, WebInspector.UIString("Select next occurrence")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SoftUndo, WebInspector.UIString("Soft undo")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GotoMatchingBracket, WebInspector.UIString("Go to matching bracket")); section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab, WebInspector.UIString("Close editor tab")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("sources.switch-file"), WebInspector.UIString("Switch between files with the same name and different extensions.")); // Timeline panel section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Timeline Panel")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.toggle-recording"), WebInspector.UIString("Start/stop recording")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload"), WebInspector.UIString("Record page reload")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.save-to-file"), WebInspector.UIString("Save timeline data")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.load-from-file"), WebInspector.UIString("Load timeline data")); section.addRelatedKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.jump-to-previous-frame").concat(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.jump-to-next-frame")), WebInspector.UIString("Jump to previous/next frame")); // Profiles panel section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Profiles Panel")); section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("profiler.toggle-recording"), WebInspector.UIString("Start/stop recording")); // Layers panel if (Runtime.experiments.isEnabled("layersPanel")) { section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Layers Panel")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView, WebInspector.UIString("Reset view")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanMode, WebInspector.UIString("Switch to pan mode")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateMode, WebInspector.UIString("Switch to rotate mode")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.TogglePanRotate, WebInspector.UIString("Temporarily toggle pan/rotate mode while held")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, WebInspector.UIString("Zoom in")); section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, WebInspector.UIString("Zoom out")); section.addRelatedKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Up.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Down), WebInspector.UIString("Pan or rotate up/down")); section.addRelatedKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Left.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Right), WebInspector.UIString("Pan or rotate left/right")); } } WebInspector.ShortcutsScreen.ElementsPanelShortcuts = { NavigateUp: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up) ], NavigateDown: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down) ], Expand: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right) ], Collapse: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left) ], EditAttribute: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter) ], HideElement: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.H) ], ToggleEditAsHTML: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F2) ], NextProperty: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab) ], PreviousProperty: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab, WebInspector.KeyboardShortcut.Modifiers.Shift) ], IncrementValue: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up) ], DecrementValue: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down) ], IncrementBy10: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp), WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Shift) ], DecrementBy10: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown), WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Shift) ], IncrementBy100: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Shift) ], DecrementBy100: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Shift) ], IncrementBy01: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Alt) ], DecrementBy01: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Alt) ] }; WebInspector.ShortcutsScreen.SourcesPanelShortcuts = { SelectNextOccurrence: [ WebInspector.KeyboardShortcut.makeDescriptor("d", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta) ], SoftUndo: [ WebInspector.KeyboardShortcut.makeDescriptor("u", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta) ], GotoMatchingBracket: [ WebInspector.KeyboardShortcut.makeDescriptor("m", WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], ToggleAutocompletion: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Space, WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], IncreaseCSSUnitByOne: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Alt) ], DecreaseCSSUnitByOne: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Alt) ], IncreaseCSSUnitByTen: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt) ], DecreaseCSSUnitByTen: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt) ], EvaluateSelectionInConsole: [ WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], AddSelectionToWatch: [ WebInspector.KeyboardShortcut.makeDescriptor("a", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], GoToMember: [ WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift) ], GoToLine: [ WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], ToggleBreakpoint: [ WebInspector.KeyboardShortcut.makeDescriptor("b", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta) ], NextCallFrame: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period, WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], PrevCallFrame: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma, WebInspector.KeyboardShortcut.Modifiers.Ctrl) ], ToggleComment: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta) ], JumpToPreviousLocation: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus, WebInspector.KeyboardShortcut.Modifiers.Alt) ], JumpToNextLocation: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus, WebInspector.KeyboardShortcut.Modifiers.Alt) ], CloseEditorTab: [ WebInspector.KeyboardShortcut.makeDescriptor("w", WebInspector.KeyboardShortcut.Modifiers.Alt) ], Save: [ WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta) ], SaveAll: [ WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.ShiftOrOption) ], }; WebInspector.ShortcutsScreen.LayersPanelShortcuts = { ResetView: [ WebInspector.KeyboardShortcut.makeDescriptor("0") ], PanMode: [ WebInspector.KeyboardShortcut.makeDescriptor("x") ], RotateMode: [ WebInspector.KeyboardShortcut.makeDescriptor("v") ], TogglePanRotate: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Shift) ], ZoomIn: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus, WebInspector.KeyboardShortcut.Modifiers.Shift), WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadPlus) ], ZoomOut: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus, WebInspector.KeyboardShortcut.Modifiers.Shift), WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadMinus) ], Up: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up), WebInspector.KeyboardShortcut.makeDescriptor("w") ], Down: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down), WebInspector.KeyboardShortcut.makeDescriptor("s") ], Left: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left), WebInspector.KeyboardShortcut.makeDescriptor("a") ], Right: [ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right), WebInspector.KeyboardShortcut.makeDescriptor("d") ] } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CookiesTable.js | 3.05% | (4 / 131) | 0% | (0 / 78) | 0% | (0 / 17) | 3.28% | (4 / 122) | |
| FilmStripModel.js | 2% | (1 / 50) | 0% | (0 / 22) | 0% | (0 / 9) | 2.04% | (1 / 49) | |
| FilmStripView.js | 4.62% | (6 / 130) | 0% | (0 / 34) | 0% | (0 / 25) | 4.62% | (6 / 130) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | 2 1 1 1 | /*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {boolean} expandable
* @param {function()=} refreshCallback
* @param {function()=} selectedCallback
*/
WebInspector.CookiesTable = function(expandable, refreshCallback, selectedCallback)
{
WebInspector.VBox.call(this);
var readOnly = expandable;
this._refreshCallback = refreshCallback;
var columns = [
{id: "name", title: WebInspector.UIString("Name"), sortable: true, disclosure: expandable, sort: WebInspector.DataGrid.Order.Ascending, longText: true, weight: 24},
{id: "value", title: WebInspector.UIString("Value"), sortable: true, longText: true, weight: 34},
{id: "domain", title: WebInspector.UIString("Domain"), sortable: true, weight: 7},
{id: "path", title: WebInspector.UIString("Path"), sortable: true, weight: 7},
{id: "expires", title: WebInspector.UIString("Expires / Max-Age"), sortable: true, weight: 7},
{id: "size", title: WebInspector.UIString("Size"), sortable: true, align: WebInspector.DataGrid.Align.Right, weight: 7},
{id: "httpOnly", title: WebInspector.UIString("HTTP"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
{id: "secure", title: WebInspector.UIString("Secure"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
{id: "sameSite", title: WebInspector.UIString("SameSite"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7}
];
if (readOnly)
this._dataGrid = new WebInspector.DataGrid(columns);
else
this._dataGrid = new WebInspector.DataGrid(columns, undefined, this._onDeleteCookie.bind(this), refreshCallback, this._onContextMenu.bind(this));
this._dataGrid.setName("cookiesTable");
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._rebuildTable, this);
if (selectedCallback)
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, selectedCallback, this);
this._nextSelectedCookie = /** @type {?WebInspector.Cookie} */ (null);
this._dataGrid.asWidget().show(this.element);
this._data = [];
}
WebInspector.CookiesTable.prototype = {
/**
* @param {?string} domain
*/
_clearAndRefresh: function(domain)
{
this.clear(domain);
this._refresh();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!WebInspector.DataGridNode} node
*/
_onContextMenu: function(contextMenu, node)
{
if (node === this._dataGrid.creationNode)
return;
var cookie = node.cookie;
var domain = cookie.domain();
if (domain)
contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all from \"%s\"", domain), this._clearAndRefresh.bind(this, domain));
contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all"), this._clearAndRefresh.bind(this, null));
},
/**
* @param {!Array.<!WebInspector.Cookie>} cookies
*/
setCookies: function(cookies)
{
this.setCookieFolders([{cookies: cookies}]);
},
/**
* @param {!Array.<!{folderName: ?string, cookies: !Array.<!WebInspector.Cookie>}>} cookieFolders
*/
setCookieFolders: function(cookieFolders)
{
this._data = cookieFolders;
this._rebuildTable();
},
/**
* @return {?WebInspector.Cookie}
*/
selectedCookie: function()
{
var node = this._dataGrid.selectedNode;
return node ? node.cookie : null;
},
/**
* @param {?string=} domain
*/
clear: function(domain)
{
for (var i = 0, length = this._data.length; i < length; ++i) {
var cookies = this._data[i].cookies;
for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
if (!domain || cookies[j].domain() === domain)
cookies[j].remove();
}
}
},
_rebuildTable: function()
{
var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
this._nextSelectedCookie = null;
this._dataGrid.rootNode().removeChildren();
for (var i = 0; i < this._data.length; ++i) {
var item = this._data[i];
if (item.folderName) {
var groupData = {name: item.folderName, value: "", domain: "", path: "", expires: "", size: this._totalSize(item.cookies), httpOnly: "", secure: "", sameSite: ""};
var groupNode = new WebInspector.DataGridNode(groupData);
groupNode.selectable = true;
this._dataGrid.rootNode().appendChild(groupNode);
groupNode.element().classList.add("row-group");
this._populateNode(groupNode, item.cookies, selectedCookie);
groupNode.expand();
} else
this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCookie);
}
},
/**
* @param {!WebInspector.DataGridNode} parentNode
* @param {?Array.<!WebInspector.Cookie>} cookies
* @param {?WebInspector.Cookie} selectedCookie
*/
_populateNode: function(parentNode, cookies, selectedCookie)
{
parentNode.removeChildren();
if (!cookies)
return;
this._sortCookies(cookies);
for (var i = 0; i < cookies.length; ++i) {
var cookie = cookies[i];
var cookieNode = this._createGridNode(cookie);
parentNode.appendChild(cookieNode);
if (selectedCookie && selectedCookie.name() === cookie.name() && selectedCookie.domain() === cookie.domain() && selectedCookie.path() === cookie.path())
cookieNode.select();
}
},
_totalSize: function(cookies)
{
var totalSize = 0;
for (var i = 0; cookies && i < cookies.length; ++i)
totalSize += cookies[i].size();
return totalSize;
},
/**
* @param {!Array.<!WebInspector.Cookie>} cookies
*/
_sortCookies: function(cookies)
{
var sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
function compareTo(getter, cookie1, cookie2)
{
return sortDirection * (getter.apply(cookie1) + "").compareTo(getter.apply(cookie2) + "");
}
function numberCompare(getter, cookie1, cookie2)
{
return sortDirection * (getter.apply(cookie1) - getter.apply(cookie2));
}
function expiresCompare(cookie1, cookie2)
{
if (cookie1.session() !== cookie2.session())
return sortDirection * (cookie1.session() ? 1 : -1);
if (cookie1.session())
return 0;
if (cookie1.maxAge() && cookie2.maxAge())
return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
if (cookie1.expires() && cookie2.expires())
return sortDirection * (cookie1.expires() - cookie2.expires());
return sortDirection * (cookie1.expires() ? 1 : -1);
}
var comparator;
switch (this._dataGrid.sortColumnIdentifier()) {
case "name": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.name); break;
case "value": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.value); break;
case "domain": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.domain); break;
case "path": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.path); break;
case "expires": comparator = expiresCompare; break;
case "size": comparator = numberCompare.bind(null, WebInspector.Cookie.prototype.size); break;
case "httpOnly": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.httpOnly); break;
case "secure": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.secure); break;
case "sameSite": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.sameSite); break;
default: compareTo.bind(null, WebInspector.Cookie.prototype.name);
}
cookies.sort(comparator);
},
/**
* @param {!WebInspector.Cookie} cookie
* @return {!WebInspector.DataGridNode}
*/
_createGridNode: function(cookie)
{
var data = {};
data.name = cookie.name();
data.value = cookie.value();
if (cookie.type() === WebInspector.Cookie.Type.Request) {
data.domain = WebInspector.UIString("N/A");
data.path = WebInspector.UIString("N/A");
data.expires = WebInspector.UIString("N/A");
} else {
data.domain = cookie.domain() || "";
data.path = cookie.path() || "";
if (cookie.maxAge())
data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
else if (cookie.expires())
data.expires = new Date(cookie.expires()).toISOString();
else
data.expires = WebInspector.UIString("Session");
}
data.size = cookie.size();
const checkmark = "\u2713";
data.httpOnly = (cookie.httpOnly() ? checkmark : "");
data.secure = (cookie.secure() ? checkmark : "");
data.sameSite = cookie.sameSite() || "";
var node = new WebInspector.DataGridNode(data);
node.cookie = cookie;
node.selectable = true;
return node;
},
_onDeleteCookie: function(node)
{
var cookie = node.cookie;
var neighbour = node.traverseNextNode() || node.traversePreviousNode();
if (neighbour)
this._nextSelectedCookie = neighbour.cookie;
cookie.remove();
this._refresh();
},
_refresh: function()
{
if (this._refreshCallback)
this._refreshCallback();
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 2 | /*
* Copyright 2015 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @param {!WebInspector.TracingModel} tracingModel
* @param {number=} zeroTime
*/
WebInspector.FilmStripModel = function(tracingModel, zeroTime)
{
this._tracingModel = tracingModel;
this._zeroTime = zeroTime || tracingModel.minimumRecordTime();
/** @type {!Array<!WebInspector.FilmStripModel.Frame>} */
this._frames = [];
var browserProcess = tracingModel.processByName("Browser");
if (!browserProcess)
return;
var mainThread = browserProcess.threadByName("CrBrowserMain");
if (!mainThread)
return;
var events = mainThread.events();
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (event.startTime < this._zeroTime)
continue;
if (!event.hasCategory(WebInspector.FilmStripModel._category))
continue;
if (event.name === WebInspector.FilmStripModel.TraceEvents.CaptureFrame) {
var data = event.args["data"];
if (data)
this._frames.push(WebInspector.FilmStripModel.Frame._fromEvent(this, event, this._frames.length));
} else if (event.name === WebInspector.FilmStripModel.TraceEvents.Screenshot) {
this._frames.push(WebInspector.FilmStripModel.Frame._fromSnapshot(this, /** @type {!WebInspector.TracingModel.ObjectSnapshot} */ (event), this._frames.length));
}
}
}
WebInspector.FilmStripModel._category = "disabled-by-default-devtools.screenshot";
WebInspector.FilmStripModel.TraceEvents = {
CaptureFrame: "CaptureFrame",
Screenshot: "Screenshot"
}
WebInspector.FilmStripModel.prototype = {
/**
* @return {!Array<!WebInspector.FilmStripModel.Frame>}
*/
frames: function()
{
return this._frames;
},
/**
* @return {number}
*/
zeroTime: function()
{
return this._zeroTime;
},
/**
* @param {number} timestamp
* @return {?WebInspector.FilmStripModel.Frame}
*/
frameByTimestamp: function(timestamp)
{
var index = this._frames.upperBound(timestamp, (timestamp, frame) => timestamp - frame.timestamp) - 1;
return index >= 0 ? this._frames[index] : null;
}
}
/**
* @constructor
* @param {!WebInspector.FilmStripModel} model
* @param {number} timestamp
* @param {number} index
*/
WebInspector.FilmStripModel.Frame = function(model, timestamp, index)
{
this._model = model;
this.timestamp = timestamp;
this.index = index;
/** @type {?string} */
this._imageData = null;
/** @type {?WebInspector.TracingModel.ObjectSnapshot} */
this._snapshot = null;
}
/**
* @param {!WebInspector.FilmStripModel} model
* @param {!WebInspector.TracingModel.Event} event
* @param {number} index
* @return {!WebInspector.FilmStripModel.Frame}
*/
WebInspector.FilmStripModel.Frame._fromEvent = function(model, event, index)
{
var frame = new WebInspector.FilmStripModel.Frame(model, event.startTime, index);
frame._imageData = event.args["data"];
return frame;
}
/**
* @param {!WebInspector.FilmStripModel} model
* @param {!WebInspector.TracingModel.ObjectSnapshot} snapshot
* @param {number} index
* @return {!WebInspector.FilmStripModel.Frame}
*/
WebInspector.FilmStripModel.Frame._fromSnapshot = function(model, snapshot, index)
{
var frame = new WebInspector.FilmStripModel.Frame(model, snapshot.startTime, index);
frame._snapshot = snapshot;
return frame;
}
WebInspector.FilmStripModel.Frame.prototype = {
/**
* @return {!WebInspector.FilmStripModel}
*/
model: function()
{
return this._model;
},
/**
* @return {!Promise<?string>}
*/
imageDataPromise: function()
{
if (this._imageData || !this._snapshot)
return Promise.resolve(this._imageData);
return /** @type {!Promise<?string>} */ (this._snapshot.objectPromise());
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | 2 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.HBox}
*/
WebInspector.FilmStripView = function()
{
WebInspector.HBox.call(this, true);
this.registerRequiredCSS("components_lazy/filmStripView.css");
this.contentElement.classList.add("film-strip-view");
this._statusLabel = this.contentElement.createChild("div", "label");
this.reset();
this.setMode(WebInspector.FilmStripView.Modes.TimeBased);
}
WebInspector.FilmStripView.Events = {
FrameSelected: "FrameSelected",
FrameEnter: "FrameEnter",
FrameExit: "FrameExit",
}
WebInspector.FilmStripView.Modes = {
TimeBased: "TimeBased",
FrameBased: "FrameBased"
}
WebInspector.FilmStripView.prototype = {
/**
* @param {string} mode
*/
setMode: function(mode)
{
this._mode = mode;
this.contentElement.classList.toggle("time-based", mode === WebInspector.FilmStripView.Modes.TimeBased);
this.update();
},
/**
* @param {!WebInspector.FilmStripModel} filmStripModel
* @param {number} zeroTime
* @param {number} spanTime
*/
setModel: function(filmStripModel, zeroTime, spanTime)
{
this._model = filmStripModel;
this._zeroTime = zeroTime;
this._spanTime = spanTime;
var frames = filmStripModel.frames();
if (!frames.length) {
this.reset();
return;
}
this.update();
},
/**
* @param {!WebInspector.FilmStripModel.Frame} frame
* @return {!Promise<!Element>}
*/
createFrameElement: function(frame)
{
var time = frame.timestamp;
var element = createElementWithClass("div", "frame");
element.title = WebInspector.UIString("Doubleclick to zoom image. Click to view preceding requests.");
element.createChild("div", "time").textContent = Number.millisToString(time - this._zeroTime);
var imageElement = element.createChild("div", "thumbnail").createChild("img");
element.addEventListener("mousedown", this._onMouseEvent.bind(this, WebInspector.FilmStripView.Events.FrameSelected, time), false);
element.addEventListener("mouseenter", this._onMouseEvent.bind(this, WebInspector.FilmStripView.Events.FrameEnter, time), false);
element.addEventListener("mouseout", this._onMouseEvent.bind(this, WebInspector.FilmStripView.Events.FrameExit, time), false);
element.addEventListener("dblclick", this._onDoubleClick.bind(this, frame), false);
return frame.imageDataPromise().then(WebInspector.FilmStripView._setImageData.bind(null, imageElement)).then(returnElement);
/**
* @return {!Element}
*/
function returnElement()
{
return element;
}
},
/**
* @param {number} time
* @return {!WebInspector.FilmStripModel.Frame}
*/
frameByTime: function(time)
{
/**
* @param {number} time
* @param {!WebInspector.FilmStripModel.Frame} frame
* @return {number}
*/
function comparator(time, frame)
{
return time - frame.timestamp;
}
// Using the first frame to fill the interval between recording start
// and a moment the frame is taken.
var frames = this._model.frames();
var index = Math.max(frames.upperBound(time, comparator) - 1, 0);
return frames[index];
},
update: function()
{
if (!this._model)
return;
var frames = this._model.frames();
if (!frames.length)
return;
if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) {
Promise.all(frames.map(this.createFrameElement.bind(this))).then(appendElements.bind(this));
return;
}
var width = this.contentElement.clientWidth;
var scale = this._spanTime / width;
this.createFrameElement(frames[0]).then(continueWhenFrameImageLoaded.bind(this)); // Calculate frame width basing on the first frame.
/**
* @this {WebInspector.FilmStripView}
* @param {!Element} element0
*/
function continueWhenFrameImageLoaded(element0)
{
var frameWidth = Math.ceil(WebInspector.measurePreferredSize(element0, this.contentElement).width);
if (!frameWidth)
return;
var promises = [];
for (var pos = frameWidth; pos < width; pos += frameWidth) {
var time = pos * scale + this._zeroTime;
promises.push(this.createFrameElement(this.frameByTime(time)).then(fixWidth));
}
Promise.all(promises).then(appendElements.bind(this));
/**
* @param {!Element} element
* @return {!Element}
*/
function fixWidth(element)
{
element.style.width = frameWidth + "px";
return element;
}
}
/**
* @param {!Array.<!Element>} elements
* @this {WebInspector.FilmStripView}
*/
function appendElements(elements)
{
this.contentElement.removeChildren();
for (var i = 0; i < elements.length; ++i)
this.contentElement.appendChild(elements[i]);
}
},
/**
* @override
*/
onResize: function()
{
if (this._mode === WebInspector.FilmStripView.Modes.FrameBased)
return;
this.update();
},
/**
* @param {string} eventName
* @param {number} timestamp
*/
_onMouseEvent: function(eventName, timestamp)
{
this.dispatchEventToListeners(eventName, timestamp);
},
/**
* @param {!WebInspector.FilmStripModel.Frame} filmStripFrame
*/
_onDoubleClick: function(filmStripFrame)
{
new WebInspector.FilmStripView.Dialog(filmStripFrame, this._zeroTime);
},
reset: function()
{
this._zeroTime = 0;
this.contentElement.removeChildren();
this.contentElement.appendChild(this._statusLabel);
},
/**
* @param {string} text
*/
setStatusText: function(text)
{
this._statusLabel.textContent = text;
},
__proto__: WebInspector.HBox.prototype
}
/**
* @param {!Element} imageElement
* @param {?string} data
*/
WebInspector.FilmStripView._setImageData = function(imageElement, data)
{
if (data)
imageElement.src = "data:image/jpg;base64," + data;
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.FilmStripModel.Frame} filmStripFrame
* @param {number=} zeroTime
*/
WebInspector.FilmStripView.Dialog = function(filmStripFrame, zeroTime)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("components_lazy/filmStripDialog.css");
this.contentElement.classList.add("filmstrip-dialog");
this.contentElement.tabIndex = 0;
this._frames = filmStripFrame.model().frames();
this._index = filmStripFrame.index;
this._zeroTime = zeroTime || filmStripFrame.model().zeroTime();
this._imageElement = this.contentElement.createChild("img");
var footerElement = this.contentElement.createChild("div", "filmstrip-dialog-footer");
footerElement.createChild("div", "flex-auto");
var prevButton = createTextButton("\u25C0", this._onPrevFrame.bind(this), undefined, WebInspector.UIString("Previous frame"));
footerElement.appendChild(prevButton);
this._timeLabel = footerElement.createChild("div", "filmstrip-dialog-label");
var nextButton = createTextButton("\u25B6", this._onNextFrame.bind(this), undefined, WebInspector.UIString("Next frame"));
footerElement.appendChild(nextButton);
footerElement.createChild("div", "flex-auto");
this.contentElement.addEventListener("keydown", this._keyDown.bind(this), false);
this.setDefaultFocusedElement(this.contentElement);
this._render();
}
WebInspector.FilmStripView.Dialog.prototype = {
_resize: function()
{
if (!this._dialog) {
this._dialog = new WebInspector.Dialog();
this.show(this._dialog.element);
this._dialog.setWrapsContent(true);
this._dialog.show();
}
this._dialog.contentResized();
},
/**
* @param {!Event} event
*/
_keyDown: function(event)
{
switch (event.keyIdentifier) {
case "Left":
if (WebInspector.isMac() && event.metaKey)
this._onFirstFrame();
else
this._onPrevFrame();
break;
case "Right":
if (WebInspector.isMac() && event.metaKey)
this._onLastFrame();
else
this._onNextFrame();
break;
case "Home":
this._onFirstFrame();
break;
case "End":
this._onLastFrame();
break;
}
},
_onPrevFrame: function()
{
if (this._index > 0)
--this._index;
this._render();
},
_onNextFrame: function()
{
if (this._index < this._frames.length - 1)
++this._index;
this._render();
},
_onFirstFrame: function()
{
this._index = 0;
this._render();
},
_onLastFrame: function()
{
this._index = this._frames.length - 1;
this._render();
},
/**
* @return {!Promise<undefined>}
*/
_render: function()
{
var frame = this._frames[this._index];
this._timeLabel.textContent = Number.millisToString(frame.timestamp - this._zeroTime);
return frame.imageDataPromise().then(WebInspector.FilmStripView._setImageData.bind(null, this._imageElement)).then(this._resize.bind(this));
},
__proto__: WebInspector.VBox.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ConsolePanel.js | 2.17% | (1 / 46) | 0% | (0 / 14) | 0% | (0 / 18) | 2.17% | (1 / 46) | |
| ConsoleView.js | 1.3% | (7 / 540) | 0% | (0 / 204) | 0% | (0 / 92) | 1.3% | (7 / 539) | |
| ConsoleViewMessage.js | 2.9% | (18 / 621) | 0% | (0 / 346) | 0% | (0 / 73) | 2.9% | (18 / 620) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 2 | /*
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Panel}
*/
WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");
this._view = WebInspector.ConsoleView.instance();
}
WebInspector.ConsolePanel.prototype = {
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._view.defaultFocusedElement();
},
/**
* @override
*/
focus: function()
{
this._view.focus();
},
/**
* @override
*/
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
var wrapper = WebInspector.ConsolePanel.WrapperView._instance;
if (wrapper && wrapper.isShowing())
WebInspector.inspectorView.setDrawerMinimized(true);
this._view.show(this.element);
},
/**
* @override
*/
willHide: function()
{
WebInspector.Panel.prototype.willHide.call(this);
if (WebInspector.ConsolePanel.WrapperView._instance)
WebInspector.ConsolePanel.WrapperView._instance._showViewInWrapper();
WebInspector.inspectorView.setDrawerMinimized(false);
},
/**
* @override
* @return {?WebInspector.SearchableView}
*/
searchableView: function()
{
return WebInspector.ConsoleView.instance().searchableView();
},
__proto__: WebInspector.Panel.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.ConsolePanel.WrapperView = function()
{
WebInspector.VBox.call(this);
this.element.classList.add("console-view-wrapper");
WebInspector.ConsolePanel.WrapperView._instance = this;
this._view = WebInspector.ConsoleView.instance();
}
WebInspector.ConsolePanel.WrapperView.prototype = {
wasShown: function()
{
if (!WebInspector.inspectorView.currentPanel() || WebInspector.inspectorView.currentPanel().name !== "console")
this._showViewInWrapper();
else
WebInspector.inspectorView.setDrawerMinimized(true);
},
willHide: function()
{
WebInspector.inspectorView.setDrawerMinimized(false);
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._view.defaultFocusedElement();
},
focus: function()
{
this._view.focus();
},
_showViewInWrapper: function()
{
this._view.show(this.element);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.ConsolePanel.ConsoleRevealer = function()
{
}
WebInspector.ConsolePanel.ConsoleRevealer.prototype = {
/**
* @override
* @param {!Object} object
* @return {!Promise}
*/
reveal: function(object)
{
var consoleView = WebInspector.ConsoleView.instance();
if (consoleView.isShowing()) {
consoleView.focus();
return Promise.resolve();
}
WebInspector.inspectorView.showViewInDrawer("console");
return Promise.resolve();
}
}
WebInspector.ConsolePanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.ConsolePanel._instance());
}
/**
* @return {!WebInspector.ConsolePanel}
*/
WebInspector.ConsolePanel._instance = function()
{
if (!WebInspector.ConsolePanel._instanceObject)
WebInspector.ConsolePanel._instanceObject = new WebInspector.ConsolePanel();
return WebInspector.ConsolePanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.ConsolePanelFactory = function()
{
}
WebInspector.ConsolePanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.ConsolePanel._instance();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.Searchable}
* @implements {WebInspector.TargetManager.Observer}
* @implements {WebInspector.ViewportControl.Provider}
*/
WebInspector.ConsoleView = function()
{
WebInspector.VBox.call(this);
this.setMinimumSize(0, 35);
this.registerRequiredCSS("console/consoleView.css");
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.setPlaceholder(WebInspector.UIString("Find string in logs"));
this._searchableView.setMinimalSearchQuerySize(0);
this._searchableView.show(this.element);
this._contentsElement = this._searchableView.element;
this._contentsElement.classList.add("console-view");
/** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
this._visibleViewMessages = [];
this._urlToMessageCount = {};
this._hiddenByFilterCount = 0;
/**
* @type {!Array.<!WebInspector.ConsoleView.RegexMatchRange>}
*/
this._regexMatchRanges = [];
this._executionContextComboBox = new WebInspector.ToolbarComboBox(null, "console-context");
this._executionContextComboBox.setMaxWidth(200);
this._executionContextModel = new WebInspector.ExecutionContextModel(this._executionContextComboBox.selectElement());
this._filter = new WebInspector.ConsoleViewFilter(this);
this._filter.addEventListener(WebInspector.ConsoleViewFilter.Events.FilterChanged, this._updateMessageList.bind(this));
this._filterBar = new WebInspector.FilterBar("consoleView");
this._preserveLogCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Preserve log"), WebInspector.UIString("Do not clear log on page reload / navigation"), WebInspector.moduleSetting("preserveConsoleLog"));
this._progressToolbarItem = new WebInspector.ToolbarItem(createElement("div"));
var toolbar = new WebInspector.Toolbar("", this._contentsElement);
toolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(WebInspector.actionRegistry.action("console.clear")));
toolbar.appendToolbarItem(this._filterBar.filterButton());
toolbar.appendToolbarItem(this._executionContextComboBox);
toolbar.appendToolbarItem(this._preserveLogCheckbox);
toolbar.appendToolbarItem(this._progressToolbarItem);
this._filterBar.show(this._contentsElement);
this._filter.addFilters(this._filterBar);
this._viewport = new WebInspector.ViewportControl(this);
this._viewport.setStickToBottom(true);
this._viewport.contentElement().classList.add("console-group", "console-group-messages");
this._contentsElement.appendChild(this._viewport.element);
this._messagesElement = this._viewport.element;
this._messagesElement.id = "console-messages";
this._messagesElement.classList.add("monospace");
this._messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
this._viewportThrottler = new WebInspector.Throttler(50);
this._filterStatusMessageElement = createElementWithClass("div", "console-message");
this._messagesElement.insertBefore(this._filterStatusMessageElement, this._messagesElement.firstChild);
this._filterStatusTextElement = this._filterStatusMessageElement.createChild("span", "console-info");
this._filterStatusMessageElement.createTextChild(" ");
var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "console-info link");
resetFiltersLink.textContent = WebInspector.UIString("Show all messages.");
resetFiltersLink.addEventListener("click", this._filter.reset.bind(this._filter), true);
this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
this._currentGroup = this._topGroup;
this._promptElement = this._messagesElement.createChild("div", "source-code");
this._promptElement.id = "console-prompt";
this._promptElement.spellcheck = false;
this._searchableView.setDefaultFocusedElement(this._promptElement);
// FIXME: This is a workaround for the selection machinery bug. See crbug.com/410899
var selectAllFixer = this._messagesElement.createChild("div", "console-view-fix-select-all");
selectAllFixer.textContent = ".";
this._showAllMessagesCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Show all messages"));
this._showAllMessagesCheckbox.inputElement.checked = true;
this._showAllMessagesCheckbox.inputElement.addEventListener("change", this._updateMessageList.bind(this), false);
this._showAllMessagesCheckbox.element.classList.add("hidden");
toolbar.appendToolbarItem(this._showAllMessagesCheckbox);
this._registerShortcuts();
this._messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
WebInspector.moduleSetting("monitoringXHREnabled").addChangeListener(this._monitoringXHREnabledSettingChanged, this);
this._linkifier = new WebInspector.Linkifier();
/** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
this._consoleMessages = [];
this._viewMessageSymbol = Symbol("viewMessage");
this._prompt = new WebInspector.TextPromptWithHistory(WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);
this._prompt.setSuggestBoxEnabled(true);
this._prompt.setAutocompletionTimeout(0);
this._prompt.renderAsBlock();
var proxyElement = this._prompt.attach(this._promptElement);
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
this._consoleHistorySetting = WebInspector.settings.createLocalSetting("consoleHistory", []);
var historyData = this._consoleHistorySetting.get();
this._prompt.setHistoryData(historyData);
this._consoleHistoryAutocompleteSetting = WebInspector.moduleSetting("consoleHistoryAutocomplete");
this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHistoryAutocompleteChanged, this);
this._consoleHistoryAutocompleteChanged();
this._updateFilterStatus();
WebInspector.moduleSetting("consoleTimestampsEnabled").addChangeListener(this._consoleTimestampsSettingChanged, this);
this._registerWithMessageSink();
WebInspector.targetManager.observeTargets(this);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
this._initConsoleMessages();
WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this);
}
WebInspector.ConsoleView.persistedHistorySize = 300;
WebInspector.ConsoleView.prototype = {
/**
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
_clearHistory: function()
{
this._consoleHistorySetting.set([]);
this._prompt.setHistoryData([]);
},
_consoleHistoryAutocompleteChanged: function()
{
this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSetting.get());
},
/**
* @param {!WebInspector.Event} event
*/
_onMainFrameNavigated: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */(event.data);
WebInspector.console.log(WebInspector.UIString("Navigated to %s", frame.url));
},
_initConsoleMessages: function()
{
var mainTarget = WebInspector.targetManager.mainTarget();
if (!mainTarget || !mainTarget.resourceTreeModel.cachedResourcesLoaded()) {
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this);
return;
}
this._fetchMultitargetMessages();
},
/**
* @param {!WebInspector.Event} event
*/
_onResourceTreeModelLoaded: function(event)
{
var resourceTreeModel = event.target;
if (resourceTreeModel.target() !== WebInspector.targetManager.mainTarget())
return;
WebInspector.targetManager.removeModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this);
this._fetchMultitargetMessages();
},
_fetchMultitargetMessages: function()
{
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageUpdated, this._onConsoleMessageUpdated, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
WebInspector.multitargetConsoleModel.messages().forEach(this._addConsoleMessage, this);
},
/**
* @override
* @return {number}
*/
itemCount: function()
{
return this._visibleViewMessages.length;
},
/**
* @override
* @param {number} index
* @return {?WebInspector.ViewportElement}
*/
itemElement: function(index)
{
return this._visibleViewMessages[index];
},
/**
* @override
* @param {number} index
* @return {number}
*/
fastHeight: function(index)
{
return this._visibleViewMessages[index].fastHeight();
},
/**
* @override
* @return {number}
*/
minimumRowHeight: function()
{
return 16;
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._viewport.invalidate();
if (WebInspector.targetManager.targets().length > 1 && WebInspector.targetManager.mainTarget().isPage())
this._showAllMessagesCheckbox.element.classList.toggle("hidden", false);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
},
_registerWithMessageSink: function()
{
WebInspector.console.messages().forEach(this._addSinkMessage, this);
WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded, messageAdded, this);
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ConsoleView}
*/
function messageAdded(event)
{
this._addSinkMessage(/** @type {!WebInspector.Console.Message} */ (event.data));
}
},
/**
* @param {!WebInspector.Console.Message} message
*/
_addSinkMessage: function(message)
{
var level = WebInspector.ConsoleMessage.MessageLevel.Debug;
switch (message.level) {
case WebInspector.Console.MessageLevel.Error:
level = WebInspector.ConsoleMessage.MessageLevel.Error;
break;
case WebInspector.Console.MessageLevel.Warning:
level = WebInspector.ConsoleMessage.MessageLevel.Warning;
break;
}
var consoleMessage = new WebInspector.ConsoleMessage(null, WebInspector.ConsoleMessage.MessageSource.Other, level, message.text,
undefined, undefined, undefined, undefined, undefined, undefined, undefined, message.timestamp);
this._addConsoleMessage(consoleMessage);
},
/**
* @param {!WebInspector.Event} event
*/
_consoleTimestampsSettingChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
this._updateMessageList();
this._consoleMessages.forEach(function(viewMessage) {
viewMessage.updateTimestamp(enabled);
});
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._promptElement;
},
_executionContextChanged: function()
{
this._prompt.clearAutoComplete(true);
if (!this._showAllMessagesCheckbox.checked())
this._updateMessageList();
},
willHide: function()
{
this._hidePromptSuggestBox();
},
wasShown: function()
{
this._viewport.refresh();
if (!this._prompt.isCaretInsidePrompt())
this._prompt.moveCaretToEndOfPrompt();
},
focus: function()
{
if (this._promptElement === WebInspector.currentFocusElement())
return;
// Set caret position before setting focus in order to avoid scrolling
// by focus().
this._prompt.moveCaretToEndOfPrompt();
WebInspector.setCurrentFocusElement(this._promptElement);
},
restoreScrollPositions: function()
{
if (this._viewport.scrolledToBottom())
this._immediatelyScrollToBottom();
else
WebInspector.Widget.prototype.restoreScrollPositions.call(this);
},
onResize: function()
{
this._scheduleViewportRefresh();
this._hidePromptSuggestBox();
if (this._viewport.scrolledToBottom())
this._immediatelyScrollToBottom();
for (var i = 0; i < this._visibleViewMessages.length; ++i)
this._visibleViewMessages[i].onResize();
},
_hidePromptSuggestBox: function()
{
this._prompt.hideSuggestBox();
this._prompt.clearAutoComplete(true);
},
_scheduleViewportRefresh: function()
{
/**
* @this {WebInspector.ConsoleView}
* @return {!Promise.<undefined>}
*/
function invalidateViewport()
{
if (this._needsFullUpdate) {
this._updateMessageList();
delete this._needsFullUpdate;
} else {
this._viewport.invalidate();
}
return Promise.resolve();
}
this._viewportThrottler.schedule(invalidateViewport.bind(this));
},
_immediatelyScrollToBottom: function()
{
// This will scroll viewport and trigger its refresh.
this._promptElement.scrollIntoView(true);
},
_updateFilterStatus: function()
{
this._filterStatusTextElement.textContent = WebInspector.UIString(this._hiddenByFilterCount === 1 ? "%d message is hidden by filters." : "%d messages are hidden by filters.", this._hiddenByFilterCount);
this._filterStatusMessageElement.style.display = this._hiddenByFilterCount ? "" : "none";
},
/**
* @param {!WebInspector.Event} event
*/
_onConsoleMessageAdded: function(event)
{
var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
this._addConsoleMessage(message);
},
/**
* @param {!WebInspector.ConsoleMessage} message
*/
_addConsoleMessage: function(message)
{
/**
* @param {!WebInspector.ConsoleViewMessage} viewMessage1
* @param {!WebInspector.ConsoleViewMessage} viewMessage2
* @return {number}
*/
function compareTimestamps(viewMessage1, viewMessage2)
{
return WebInspector.ConsoleMessage.timestampComparator(viewMessage1.consoleMessage(), viewMessage2.consoleMessage());
}
if (message.type === WebInspector.ConsoleMessage.MessageType.Command || message.type === WebInspector.ConsoleMessage.MessageType.Result)
message.timestamp = this._consoleMessages.length ? this._consoleMessages.peekLast().consoleMessage().timestamp : 0;
var viewMessage = this._createViewMessage(message);
message[this._viewMessageSymbol] = viewMessage;
var insertAt = this._consoleMessages.upperBound(viewMessage, compareTimestamps)
var insertedInMiddle = insertAt < this._consoleMessages.length;
this._consoleMessages.splice(insertAt, 0, viewMessage);
if (this._urlToMessageCount[message.url])
++this._urlToMessageCount[message.url];
else
this._urlToMessageCount[message.url] = 1;
if (!insertedInMiddle) {
this._appendMessageToEnd(viewMessage);
this._updateFilterStatus();
this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
} else {
this._needsFullUpdate = true;
}
this._scheduleViewportRefresh();
this._consoleMessageAddedForTest(viewMessage);
},
/**
* @param {!WebInspector.Event} event
*/
_onConsoleMessageUpdated: function(event)
{
var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
var viewMessage = message[this._viewMessageSymbol];
if (viewMessage) {
viewMessage.updateMessageElement();
this._updateMessageList();
}
},
/**
* @param {!WebInspector.ConsoleViewMessage} viewMessage
*/
_consoleMessageAddedForTest: function(viewMessage) { },
/**
* @param {!WebInspector.ConsoleViewMessage} viewMessage
*/
_appendMessageToEnd: function(viewMessage)
{
if (!this._filter.shouldBeVisible(viewMessage)) {
this._hiddenByFilterCount++;
return;
}
if (this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.peekLast()))
return;
var lastMessage = this._visibleViewMessages.peekLast();
if (viewMessage.consoleMessage().type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
if (lastMessage && !this._currentGroup.messagesHidden())
lastMessage.incrementCloseGroupDecorationCount();
this._currentGroup = this._currentGroup.parentGroup();
return;
}
if (!this._currentGroup.messagesHidden()) {
var originatingMessage = viewMessage.consoleMessage().originatingMessage();
if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage)
lastMessage.toMessageElement().classList.add("console-adjacent-user-command-result");
this._visibleViewMessages.push(viewMessage);
this._searchMessage(this._visibleViewMessages.length - 1);
}
if (viewMessage.consoleMessage().isGroupStartMessage())
this._currentGroup = new WebInspector.ConsoleGroup(this._currentGroup, viewMessage);
this._messageAppendedForTests();
},
_messageAppendedForTests: function()
{
// This method is sniffed in tests.
},
/**
* @param {!WebInspector.ConsoleMessage} message
* @return {!WebInspector.ConsoleViewMessage}
*/
_createViewMessage: function(message)
{
var nestingLevel = this._currentGroup.nestingLevel();
switch (message.type) {
case WebInspector.ConsoleMessage.MessageType.Command:
return new WebInspector.ConsoleCommand(message, this._linkifier, nestingLevel);
case WebInspector.ConsoleMessage.MessageType.Result:
return new WebInspector.ConsoleCommandResult(message, this._linkifier, nestingLevel);
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
return new WebInspector.ConsoleGroupViewMessage(message, this._linkifier, nestingLevel);
default:
return new WebInspector.ConsoleViewMessage(message, this._linkifier, nestingLevel);
}
},
_consoleCleared: function()
{
this._currentMatchRangeIndex = -1;
this._consoleMessages = [];
this._updateMessageList();
this._hidePromptSuggestBox();
this._linkifier.reset();
},
_handleContextMenuEvent: function(event)
{
if (event.target.enclosingNodeOrSelfWithNodeName("a"))
return;
var contextMenu = new WebInspector.ContextMenu(event);
if (event.target.isSelfOrDescendant(this._promptElement)) {
contextMenu.show()
return;
}
function monitoringXHRItemAction()
{
WebInspector.moduleSetting("monitoringXHREnabled").set(!WebInspector.moduleSetting("monitoringXHREnabled").get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction, WebInspector.moduleSetting("monitoringXHREnabled").get());
var sourceElement = event.target.enclosingNodeOrSelfWithClass("console-message-wrapper");
var consoleMessage = sourceElement ? sourceElement.message.consoleMessage() : null;
var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Filter"));
if (consoleMessage && consoleMessage.url) {
var menuTitle = WebInspector.UIString.capitalize("Hide ^messages from %s", new WebInspector.ParsedURL(consoleMessage.url).displayName);
filterSubMenu.appendItem(menuTitle, this._filter.addMessageURLFilter.bind(this._filter, consoleMessage.url));
}
filterSubMenu.appendSeparator();
var unhideAll = filterSubMenu.appendItem(WebInspector.UIString.capitalize("Unhide ^all"), this._filter.removeMessageURLFilter.bind(this._filter));
filterSubMenu.appendSeparator();
var hasFilters = false;
for (var url in this._filter.messageURLFilters) {
filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)", new WebInspector.ParsedURL(url).displayName, this._urlToMessageCount[url]), this._filter.removeMessageURLFilter.bind(this._filter, url), true);
hasFilters = true;
}
filterSubMenu.setEnabled(hasFilters || (consoleMessage && consoleMessage.url));
unhideAll.setEnabled(hasFilters);
contextMenu.appendSeparator();
contextMenu.appendAction("console.clear");
contextMenu.appendAction("console.clear.history");
contextMenu.appendItem(WebInspector.UIString("Save as..."), this._saveConsole.bind(this));
var request = consoleMessage ? consoleMessage.request : null;
if (request && request.resourceType() === WebInspector.resourceTypes.XHR) {
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Replay XHR"), request.replayXHR.bind(request));
}
contextMenu.show();
},
_saveConsole: function()
{
var filename = String.sprintf("%s-%d.log", WebInspector.targetManager.inspectedPageDomain(), Date.now());
var stream = new WebInspector.FileOutputStream();
var progressIndicator = new WebInspector.ProgressIndicator();
progressIndicator.setTitle(WebInspector.UIString("Writing file…"));
progressIndicator.setTotalWork(this.itemCount());
/** @const */
var chunkSize = 350;
var messageIndex = 0;
stream.open(filename, openCallback.bind(this));
/**
* @param {boolean} accepted
* @this {WebInspector.ConsoleView}
*/
function openCallback(accepted)
{
if (!accepted)
return;
this._progressToolbarItem.element.appendChild(progressIndicator.element);
writeNextChunk.call(this, stream);
}
/**
* @param {!WebInspector.OutputStream} stream
* @param {string=} error
* @this {WebInspector.ConsoleView}
*/
function writeNextChunk(stream, error)
{
if (messageIndex >= this.itemCount() || error) {
stream.close();
progressIndicator.done();
return;
}
var lines = [];
for (var i = 0; i < chunkSize && i + messageIndex < this.itemCount(); ++i) {
var message = this.itemElement(messageIndex + i);
lines.push(message.searchableElement().deepTextContent());
}
messageIndex += i;
stream.write(lines.join("\n") + "\n", writeNextChunk.bind(this));
progressIndicator.setWorked(messageIndex);
}
},
/**
* @param {!WebInspector.ConsoleViewMessage} lastMessage
* @param {?WebInspector.ConsoleViewMessage=} viewMessage
* @return {boolean}
*/
_tryToCollapseMessages: function(lastMessage, viewMessage)
{
if (!WebInspector.moduleSetting("consoleTimestampsEnabled").get() && viewMessage && !lastMessage.consoleMessage().isGroupMessage() && lastMessage.consoleMessage().isEqual(viewMessage.consoleMessage())) {
viewMessage.incrementRepeatCount();
return true;
}
return false;
},
_updateMessageList: function()
{
this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
this._currentGroup = this._topGroup;
this._regexMatchRanges = [];
this._hiddenByFilterCount = 0;
for (var i = 0; i < this._visibleViewMessages.length; ++i) {
this._visibleViewMessages[i].resetCloseGroupDecorationCount();
this._visibleViewMessages[i].resetIncrementRepeatCount();
}
this._visibleViewMessages = [];
for (var i = 0; i < this._consoleMessages.length; ++i)
this._appendMessageToEnd(this._consoleMessages[i]);
this._updateFilterStatus();
this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
this._viewport.invalidate();
},
/**
* @param {!WebInspector.Event} event
*/
_monitoringXHREnabledSettingChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
WebInspector.targetManager.targets().forEach(function(target) {target.networkAgent().setMonitoringXHREnabled(enabled);});
},
/**
* @param {!Event} event
*/
_messagesClicked: function(event)
{
var targetElement = event.deepElementFromPoint();
if (!this._prompt.isCaretInsidePrompt() && (!targetElement || targetElement.isComponentSelectionCollapsed()))
this._prompt.moveCaretToEndOfPrompt();
var groupMessage = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (!groupMessage)
return;
var consoleGroupViewMessage = groupMessage.parentElement.message;
consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed());
this._updateMessageList();
},
_registerShortcuts: function()
{
this._shortcuts = {};
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
var keys = [shortcutL];
if (WebInspector.isMac()) {
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
keys.unshift(shortcutK);
}
section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector.UIString("Autocomplete common prefix"));
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
var shortcutU = shortcut.makeDescriptor("u", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
section.addAlternateKeys([shortcutU], WebInspector.UIString("Clear console prompt"));
keys = [
shortcut.makeDescriptor(shortcut.Keys.Down),
shortcut.makeDescriptor(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
if (WebInspector.isMac()) {
keys = [
shortcut.makeDescriptor("N", shortcut.Modifiers.Alt),
shortcut.makeDescriptor("P", shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
}
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},
_clearPromptBackwards: function()
{
this._prompt.setText("");
},
_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}
var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler();
event.preventDefault();
}
},
_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;
event.consume(true);
this._prompt.clearAutoComplete(true);
var str = this._prompt.text();
if (!str.length)
return;
this._appendCommand(str, true);
},
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean} wasThrown
* @param {!WebInspector.ConsoleMessage} originatingConsoleMessage
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
_printResult: function(result, wasThrown, originatingConsoleMessage, exceptionDetails)
{
if (!result)
return;
var level = wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
var message;
if (!wasThrown)
message = new WebInspector.ConsoleMessage(result.target(), WebInspector.ConsoleMessage.MessageSource.JS, level, "", WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, undefined, [result]);
else
message = new WebInspector.ConsoleMessage(result.target(), WebInspector.ConsoleMessage.MessageSource.JS, level, exceptionDetails.text, WebInspector.ConsoleMessage.MessageType.Result, exceptionDetails.url, exceptionDetails.line, exceptionDetails.column, undefined, [WebInspector.UIString("Uncaught"), result], exceptionDetails.stack, undefined, undefined, exceptionDetails.scriptId);
message.setOriginatingMessage(originatingConsoleMessage);
result.target().consoleModel.addMessage(message);
},
/**
* @param {string} text
* @param {boolean} useCommandLineAPI
*/
_appendCommand: function(text, useCommandLineAPI)
{
this._prompt.setText("");
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (currentExecutionContext) {
WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, text, useCommandLineAPI);
if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().name === "console")
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.CommandEvaluatedInConsolePanel);
}
},
/**
* @param {!WebInspector.Event} event
*/
_commandEvaluated: function(event)
{
var data = /**{{result: ?WebInspector.RemoteObject, wasThrown: boolean, text: string, commandMessage: !WebInspector.ConsoleMessage}} */ (event.data);
this._prompt.pushHistoryItem(data.text);
this._consoleHistorySetting.set(this._prompt.historyData().slice(-WebInspector.ConsoleView.persistedHistorySize));
this._printResult(data.result, data.wasThrown, data.commandMessage, data.exceptionDetails);
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [this._messagesElement];
},
/**
* @override
*/
searchCanceled: function()
{
this._cleanupAfterSearch();
for (var i = 0; i < this._visibleViewMessages.length; ++i) {
var message = this._visibleViewMessages[i];
message.setSearchRegex(null);
}
this._currentMatchRangeIndex = -1;
this._regexMatchRanges = [];
delete this._searchRegex;
this._viewport.refresh();
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
this.searchCanceled();
this._searchableView.updateSearchMatchesCount(0);
this._searchRegex = searchConfig.toSearchRegex(true);
this._regexMatchRanges = [];
this._currentMatchRangeIndex = -1;
if (shouldJump)
this._searchShouldJumpBackwards = !!jumpBackwards;
this._searchProgressIndicator = new WebInspector.ProgressIndicator();
this._searchProgressIndicator.setTitle(WebInspector.UIString("Searching…"));
this._searchProgressIndicator.setTotalWork(this._visibleViewMessages.length);
this._progressToolbarItem.element.appendChild(this._searchProgressIndicator.element);
this._innerSearch(0);
},
_cleanupAfterSearch: function()
{
delete this._searchShouldJumpBackwards;
if (this._innerSearchTimeoutId) {
clearTimeout(this._innerSearchTimeoutId);
delete this._innerSearchTimeoutId;
}
if (this._searchProgressIndicator) {
this._searchProgressIndicator.done();
delete this._searchProgressIndicator;
}
},
_searchFinishedForTests: function()
{
// This method is sniffed in tests.
},
/**
* @param {number} index
*/
_innerSearch: function(index)
{
delete this._innerSearchTimeoutId;
if (this._searchProgressIndicator.isCanceled()) {
this._cleanupAfterSearch();
return;
}
var startTime = Date.now();
for (; index < this._visibleViewMessages.length && Date.now() - startTime < 100; ++index)
this._searchMessage(index);
this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
if (typeof this._searchShouldJumpBackwards !== "undefined" && this._regexMatchRanges.length) {
this._jumpToMatch(this._searchShouldJumpBackwards ? -1 : 0);
delete this._searchShouldJumpBackwards;
}
if (index === this._visibleViewMessages.length) {
this._cleanupAfterSearch();
setTimeout(this._searchFinishedForTests.bind(this), 0);
return;
}
this._innerSearchTimeoutId = setTimeout(this._innerSearch.bind(this, index), 100);
this._searchProgressIndicator.setWorked(index);
},
/**
* @param {number} index
*/
_searchMessage: function(index)
{
var message = this._visibleViewMessages[index];
message.setSearchRegex(this._searchRegex);
for (var i = 0; i < message.searchCount(); ++i) {
this._regexMatchRanges.push({
messageIndex: index,
matchIndex: i
});
}
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
this._jumpToMatch(this._currentMatchRangeIndex + 1);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
this._jumpToMatch(this._currentMatchRangeIndex - 1);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return true;
},
/**
* @param {number} index
*/
_jumpToMatch: function(index)
{
if (!this._regexMatchRanges.length)
return;
var currentSearchResultClassName = "current-search-result";
var matchRange;
if (this._currentMatchRangeIndex >= 0) {
matchRange = this._regexMatchRanges[this._currentMatchRangeIndex];
var message = this._visibleViewMessages[matchRange.messageIndex];
message.searchHighlightNode(matchRange.matchIndex).classList.remove(currentSearchResultClassName);
}
index = mod(index, this._regexMatchRanges.length);
this._currentMatchRangeIndex = index;
this._searchableView.updateCurrentMatchIndex(index);
matchRange = this._regexMatchRanges[index];
var message = this._visibleViewMessages[matchRange.messageIndex];
var highlightNode = message.searchHighlightNode(matchRange.matchIndex);
highlightNode.classList.add(currentSearchResultClassName);
this._viewport.scrollItemIntoView(matchRange.messageIndex);
highlightNode.scrollIntoViewIfNeeded();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.ConsoleView} view
*/
WebInspector.ConsoleViewFilter = function(view)
{
this._messageURLFiltersSetting = WebInspector.settings.createSetting("messageURLFilters", {});
this._messageLevelFiltersSetting = WebInspector.settings.createSetting("messageLevelFilters", {});
this._view = view;
this._messageURLFilters = this._messageURLFiltersSetting.get();
this._filterChanged = this.dispatchEventToListeners.bind(this, WebInspector.ConsoleViewFilter.Events.FilterChanged);
};
WebInspector.ConsoleViewFilter.Events = {
FilterChanged: "FilterChanged"
};
WebInspector.ConsoleViewFilter.prototype = {
addFilters: function(filterBar)
{
this._textFilterUI = new WebInspector.TextFilterUI(true);
this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._textFilterChanged, this);
filterBar.addFilter(this._textFilterUI);
this._hideNetworkMessagesCheckbox = new WebInspector.CheckboxFilterUI("hide-network-messages", WebInspector.UIString("Hide network messages"), true, WebInspector.moduleSetting("hideNetworkMessages"));
this._hideNetworkMessagesCheckbox.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
filterBar.addFilter(this._hideNetworkMessagesCheckbox);
var levels = [
{name: WebInspector.ConsoleMessage.MessageLevel.Error, label: WebInspector.UIString("Errors")},
{name: WebInspector.ConsoleMessage.MessageLevel.Warning, label: WebInspector.UIString("Warnings")},
{name: WebInspector.ConsoleMessage.MessageLevel.Info, label: WebInspector.UIString("Info")},
{name: WebInspector.ConsoleMessage.MessageLevel.Log, label: WebInspector.UIString("Logs")},
{name: WebInspector.ConsoleMessage.MessageLevel.Debug, label: WebInspector.UIString("Debug")},
{name: WebInspector.ConsoleMessage.MessageLevel.RevokedError, label: WebInspector.UIString("Handled")}
];
this._levelFilterUI = new WebInspector.NamedBitSetFilterUI(levels, this._messageLevelFiltersSetting);
this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
filterBar.addFilter(this._levelFilterUI);
},
_textFilterChanged: function(event)
{
this._filterRegex = this._textFilterUI.regex();
this._filterChanged();
},
/**
* @param {string} url
*/
addMessageURLFilter: function(url)
{
this._messageURLFilters[url] = true;
this._messageURLFiltersSetting.set(this._messageURLFilters);
this._filterChanged();
},
/**
* @param {string} url
*/
removeMessageURLFilter: function(url)
{
if (!url)
this._messageURLFilters = {};
else
delete this._messageURLFilters[url];
this._messageURLFiltersSetting.set(this._messageURLFilters);
this._filterChanged();
},
/**
* @returns {!Object}
*/
get messageURLFilters()
{
return this._messageURLFilters;
},
/**
* @param {!WebInspector.ConsoleViewMessage} viewMessage
* @return {boolean}
*/
shouldBeVisible: function(viewMessage)
{
var message = viewMessage.consoleMessage();
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!message.target())
return true;
if (!this._view._showAllMessagesCheckbox.checked() && executionContext) {
if (message.target() !== executionContext.target())
return false;
if (message.executionContextId && message.executionContextId !== executionContext.id) {
return false;
}
}
if (WebInspector.moduleSetting("hideNetworkMessages").get() && viewMessage.consoleMessage().source === WebInspector.ConsoleMessage.MessageSource.Network)
return false;
if (viewMessage.consoleMessage().isGroupMessage())
return true;
if (message.type === WebInspector.ConsoleMessage.MessageType.Result || message.type === WebInspector.ConsoleMessage.MessageType.Command)
return true;
if (message.url && this._messageURLFilters[message.url])
return false;
if (message.level && !this._levelFilterUI.accept(message.level))
return false;
if (this._filterRegex) {
this._filterRegex.lastIndex = 0;
if (!viewMessage.matchesFilterRegex(this._filterRegex))
return false;
}
return true;
},
reset: function()
{
this._messageURLFilters = {};
this._messageURLFiltersSetting.set(this._messageURLFilters);
this._messageLevelFiltersSetting.set({});
this._view._showAllMessagesCheckbox.inputElement.checked = true;
WebInspector.moduleSetting("hideNetworkMessages").set(false);
this._textFilterUI.setValue("");
this._filterChanged();
},
__proto__: WebInspector.Object.prototype
};
/**
* @constructor
* @extends {WebInspector.ConsoleViewMessage}
* @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.Linkifier} linkifier
* @param {number} nestingLevel
*/
WebInspector.ConsoleCommand = function(message, linkifier, nestingLevel)
{
WebInspector.ConsoleViewMessage.call(this, message, linkifier, nestingLevel);
}
WebInspector.ConsoleCommand.prototype = {
/**
* @override
* @return {!Element})
*/
searchableElement: function()
{
return this.contentElement();
},
/**
* @override
* @return {!Element}
*/
contentElement: function()
{
if (!this._element) {
this._element = createElementWithClass("div", "console-user-command");
this._element.message = this;
this._formattedCommand = createElementWithClass("span", "console-message-text source-code");
this._formattedCommand.textContent = this.text.replaceControlCharacters();
this._element.appendChild(this._formattedCommand);
var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this))
}
return this._element;
},
_updateSearch: function()
{
this.setSearchRegex(this.searchRegex());
},
__proto__: WebInspector.ConsoleViewMessage.prototype
}
/**
* @constructor
* @extends {WebInspector.ConsoleViewMessage}
* @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.Linkifier} linkifier
* @param {number} nestingLevel
*/
WebInspector.ConsoleCommandResult = function(message, linkifier, nestingLevel)
{
WebInspector.ConsoleViewMessage.call(this, message, linkifier, nestingLevel);
}
WebInspector.ConsoleCommandResult.prototype = {
/**
* @override
* @param {!WebInspector.RemoteObject} array
* @return {boolean}
*/
useArrayPreviewInFormatter: function(array)
{
return false;
},
/**
* @override
* @return {!Element}
*/
contentElement: function()
{
var element = WebInspector.ConsoleViewMessage.prototype.contentElement.call(this);
element.classList.add("console-user-command-result");
this.updateTimestamp(false);
return element;
},
__proto__: WebInspector.ConsoleViewMessage.prototype
}
/**
* @constructor
* @param {?WebInspector.ConsoleGroup} parentGroup
* @param {?WebInspector.ConsoleViewMessage} groupMessage
*/
WebInspector.ConsoleGroup = function(parentGroup, groupMessage)
{
this._parentGroup = parentGroup;
this._nestingLevel = parentGroup ? parentGroup.nestingLevel() + 1 : 0;
this._messagesHidden = groupMessage && groupMessage.collapsed() || this._parentGroup && this._parentGroup.messagesHidden();
}
/**
* @return {!WebInspector.ConsoleGroup}
*/
WebInspector.ConsoleGroup.createTopGroup = function()
{
return new WebInspector.ConsoleGroup(null, null);
}
WebInspector.ConsoleGroup.prototype = {
/**
* @return {boolean}
*/
messagesHidden: function()
{
return this._messagesHidden;
},
/**
* @return {number}
*/
nestingLevel: function()
{
return this._nestingLevel;
},
/**
* @return {?WebInspector.ConsoleGroup}
*/
parentGroup: function()
{
return this._parentGroup || this;
},
}
/**
* @return {!WebInspector.ConsoleView}
*/
WebInspector.ConsoleView.instance = function()
{
if (!WebInspector.ConsoleView._instance)
WebInspector.ConsoleView._instance = new WebInspector.ConsoleView();
return WebInspector.ConsoleView._instance;
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.ConsoleView.ActionDelegate = function()
{
}
WebInspector.ConsoleView.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
switch (actionId) {
case "console.show":
WebInspector.console.show();
return true;
case "console.clear":
WebInspector.ConsoleModel.clearConsole();
return true;
case "console.clear.history":
WebInspector.ConsoleView.instance()._clearHistory();
return true;
}
return false;
}
}
/**
* @typedef {{messageIndex: number, matchIndex: number}}
*/
WebInspector.ConsoleView.RegexMatchRange;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.ViewportElement}
* @param {!WebInspector.ConsoleMessage} consoleMessage
* @param {!WebInspector.Linkifier} linkifier
* @param {number} nestingLevel
*/
WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLevel)
{
this._message = consoleMessage;
this._linkifier = linkifier;
this._repeatCount = 1;
this._closeGroupDecorationCount = 0;
this._nestingLevel = nestingLevel;
/** @type {!Array.<!WebInspector.DataGrid>} */
this._dataGrids = [];
/** @type {!Object.<string, function(!WebInspector.RemoteObject, !Element, boolean=)>} */
this._customFormatters = {
"array": this._formatParameterAsArray,
"error": this._formatParameterAsError,
"function": this._formatParameterAsFunction,
"generator": this._formatParameterAsObject,
"iterator": this._formatParameterAsObject,
"map": this._formatParameterAsObject,
"node": this._formatParameterAsNode,
"object": this._formatParameterAsObject,
"set": this._formatParameterAsObject,
"string": this._formatParameterAsString
};
this._previewFormatter = new WebInspector.RemoteObjectPreviewFormatter();
this._searchRegex = null;
}
WebInspector.ConsoleViewMessage.prototype = {
/**
* @return {?WebInspector.Target}
*/
_target: function()
{
return this.consoleMessage().target();
},
/**
* @override
* @return {!Element}
*/
element: function()
{
return this.toMessageElement();
},
/**
* @override
*/
wasShown: function()
{
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i)
this._dataGrids[i].updateWidths();
this._isVisible = true;
},
onResize: function()
{
if (!this._isVisible)
return;
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i)
this._dataGrids[i].onResize();
},
/**
* @override
*/
willHide: function()
{
this._isVisible = false;
this._cachedHeight = this.contentElement().offsetHeight;
},
/**
* @return {number}
*/
fastHeight: function()
{
if (this._cachedHeight)
return this._cachedHeight;
const defaultConsoleRowHeight = 18; // Sync with consoleView.css
if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
var table = this._message.parameters[0];
if (table && table.preview)
return defaultConsoleRowHeight * table.preview.properties.length;
}
return defaultConsoleRowHeight;
},
/**
* @return {!WebInspector.ConsoleMessage}
*/
consoleMessage: function()
{
return this._message;
},
_formatMessage: function()
{
this._formattedMessage = createElement("span");
WebInspector.appendStyle(this._formattedMessage, "components/objectValue.css");
this._formattedMessage.className = "console-message-text source-code";
/**
* @param {string} title
* @return {!Element}
* @this {WebInspector.ConsoleMessage}
*/
function linkifyRequest(title)
{
return WebInspector.Linkifier.linkifyUsingRevealer(/** @type {!WebInspector.NetworkRequest} */ (this.request), title, this.request.url);
}
var consoleMessage = this._message;
if (!this._messageElement) {
if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
switch (consoleMessage.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
this._messageElement = this._format(consoleMessage.parameters || ["console.trace()"]);
break;
case WebInspector.ConsoleMessage.MessageType.Clear:
this._messageElement = createTextNode(WebInspector.UIString("Console was cleared"));
this._formattedMessage.classList.add("console-info");
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
var args = [WebInspector.UIString("Assertion failed:")];
if (consoleMessage.parameters)
args = args.concat(consoleMessage.parameters);
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined;
var args = ["%O", obj];
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Profile:
case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
this._messageElement = this._format([consoleMessage.messageText]);
break;
default:
if (consoleMessage.parameters && consoleMessage.parameters.length === 1 && consoleMessage.parameters[0].type === "string")
this._messageElement = this._tryFormatAsError(/**@type {string} */(consoleMessage.parameters[0].value));
var args = consoleMessage.parameters || [consoleMessage.messageText];
this._messageElement = this._messageElement || this._format(args);
}
} else if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network) {
if (consoleMessage.request) {
this._messageElement = createElement("span");
if (consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError) {
this._messageElement.createTextChildren(consoleMessage.request.requestMethod, " ");
this._messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(consoleMessage.request, consoleMessage.request.url, consoleMessage.request.url));
if (consoleMessage.request.failed)
this._messageElement.createTextChildren(" ", consoleMessage.request.localizedFailDescription);
else
this._messageElement.createTextChildren(" ", String(consoleMessage.request.statusCode), " (", consoleMessage.request.statusText, ")");
} else {
var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(consoleMessage.messageText, linkifyRequest.bind(consoleMessage));
this._messageElement.appendChild(fragment);
}
} else {
var url = consoleMessage.url;
if (url) {
var isExternal = !WebInspector.resourceForURL(url) && !WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);
this._anchorElement = WebInspector.linkifyURLAsNode(url, url, "console-message-url", isExternal);
}
this._messageElement = this._format([consoleMessage.messageText]);
}
} else {
var args = consoleMessage.parameters || [consoleMessage.messageText];
this._messageElement = this._format(args);
}
}
if (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.request) {
if (consoleMessage.scriptId) {
this._anchorElement = this._linkifyScriptId(consoleMessage.scriptId, consoleMessage.url || "", consoleMessage.line, consoleMessage.column);
} else {
if (consoleMessage.stackTrace && consoleMessage.stackTrace.callFrames.length)
this._anchorElement = this._linkifyStackTraceTopFrame(consoleMessage.stackTrace);
else if (consoleMessage.url && consoleMessage.url !== "undefined")
this._anchorElement = this._linkifyLocation(consoleMessage.url, consoleMessage.line, consoleMessage.column);
}
}
this._formattedMessage.appendChild(this._messageElement);
if (this._anchorElement) {
// Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
this._anchorElement.appendChild(createTextNode(" "));
this._formattedMessage.insertBefore(this._anchorElement, this._formattedMessage.firstChild);
}
var dumpStackTrace = !!consoleMessage.stackTrace && (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError || consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace);
if (dumpStackTrace) {
var treeOutline = new TreeOutline();
treeOutline.element.classList.add("outline-disclosure", "outline-disclosure-no-padding");
var content = this._formattedMessage;
var root = new TreeElement(content);
root.toggleOnClick = true;
root.selectable = false;
content.treeElementForTest = root;
treeOutline.appendChild(root);
if (consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();
this._populateStackTraceTreeElement(root);
this._formattedMessage = treeOutline.element;
}
},
/**
* @return {!Element}
*/
formattedMessage: function()
{
if (!this._formattedMessage)
this._formatMessage();
return this._formattedMessage;
},
/**
* @param {string} url
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?Element}
*/
_linkifyLocation: function(url, lineNumber, columnNumber)
{
var target = this._target();
if (!target)
return null;
// FIXME(62725): stack trace line/column numbers are one-based.
lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
return this._linkifier.linkifyScriptLocation(target, null, url, lineNumber, columnNumber, "console-message-url");
},
/**
* @param {!RuntimeAgent.StackTrace} stackTrace
* @return {?Element}
*/
_linkifyStackTraceTopFrame: function(stackTrace)
{
var target = this._target();
if (!target)
return null;
return this._linkifier.linkifyStackTraceTopFrame(target, stackTrace, "console-message-url");
},
/**
* @param {string} scriptId
* @param {string} url
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?Element}
*/
_linkifyScriptId: function(scriptId, url, lineNumber, columnNumber)
{
var target = this._target();
if (!target)
return null;
// FIXME(62725): stack trace line/column numbers are one-based.
lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
return this._linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber, columnNumber, "console-message-url");
},
_format: function(parameters)
{
// This node is used like a Builder. Values are continually appended onto it.
var formattedResult = createElement("span");
if (!parameters.length)
return formattedResult;
var target = this._target();
// Formatting code below assumes that parameters are all wrappers whereas frontend console
// API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
for (var i = 0; i < parameters.length; ++i) {
// FIXME: Only pass runtime wrappers here.
if (parameters[i] instanceof WebInspector.RemoteObject)
continue;
if (!target) {
parameters[i] = WebInspector.RemoteObject.fromLocalObject(parameters[i]);
continue;
}
if (typeof parameters[i] === "object")
parameters[i] = target.runtimeModel.createRemoteObject(parameters[i]);
else
parameters[i] = target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameters[i]);
}
// There can be string log and string eval result. We distinguish between them based on message type.
var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && (this._message.type !== WebInspector.ConsoleMessage.MessageType.Result || this._message.level === WebInspector.ConsoleMessage.MessageLevel.Error || this._message.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError);
// Multiple parameters with the first being a format string. Save unused substitutions.
if (shouldFormatMessage) {
// Multiple parameters with the first being a format string. Save unused substitutions.
var result = this._formatWithSubstitutionString(parameters[0].description, parameters.slice(1), formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.createTextChild(" ");
}
if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
formattedResult.appendChild(this._formatParameterAsTable(parameters));
return formattedResult;
}
// Single parameter, or unused substitutions from above.
for (var i = 0; i < parameters.length; ++i) {
// Inline strings when formatting.
if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description));
else
formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
if (i < parameters.length - 1)
formattedResult.createTextChild(" ");
}
return formattedResult;
},
/**
* @param {!WebInspector.RemoteObject} output
* @param {boolean=} forceObjectFormat
* @param {boolean=} includePreview
* @return {!Element}
*/
_formatParameter: function(output, forceObjectFormat, includePreview)
{
if (output.customPreview()) {
return (new WebInspector.CustomPreviewComponent(output)).element;
}
var type = forceObjectFormat ? "object" : (output.subtype || output.type);
var formatter = this._customFormatters[type] || this._formatParameterAsValue;
var span = createElement("span");
span.className = "object-value-" + type + " source-code";
formatter.call(this, output, span, includePreview);
return span;
},
/**
* @param {!WebInspector.RemoteObject} obj
* @param {!Element} elem
*/
_formatParameterAsValue: function(obj, elem)
{
elem.createTextChild(obj.description || "");
if (obj.objectId)
elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
},
/**
* @param {!WebInspector.RemoteObject} obj
* @param {!Element} elem
* @param {boolean=} includePreview
*/
_formatParameterAsObject: function(obj, elem, includePreview)
{
this._formatParameterAsArrayOrObject(obj, elem, includePreview);
},
/**
* @param {!WebInspector.RemoteObject} obj
* @param {!Element} elem
* @param {boolean=} includePreview
*/
_formatParameterAsArrayOrObject: function(obj, elem, includePreview)
{
var titleElement = createElement("span");
if (includePreview && obj.preview) {
titleElement.classList.add("console-object-preview");
var lossless = this._previewFormatter.appendObjectPreview(titleElement, obj.preview);
if (lossless) {
elem.appendChild(titleElement);
titleElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
return;
}
} else {
if (obj.type === "function") {
WebInspector.ObjectPropertiesSection.formatObjectAsFunction(obj, titleElement, false);
titleElement.classList.add("object-value-function");
} else {
titleElement.createTextChild(obj.description || "");
}
}
var note = titleElement.createChild("span", "object-info-state-note");
note.title = WebInspector.UIString("Object value at left was snapshotted when logged, value below was evaluated just now.");
var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
section.enableContextMenu();
elem.appendChild(section.element);
section.element.classList.add("console-view-object-properties-section");
},
/**
* @param {!WebInspector.RemoteObject} func
* @param {!Element} element
* @param {boolean=} includePreview
*/
_formatParameterAsFunction: function(func, element, includePreview)
{
WebInspector.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
/**
* @param {!WebInspector.RemoteObject} targetFunction
* @this {WebInspector.ConsoleViewMessage}
*/
function formatTargetFunction(targetFunction)
{
var functionElement = createElement("span")
WebInspector.ObjectPropertiesSection.formatObjectAsFunction(targetFunction, functionElement, true, includePreview);
element.appendChild(functionElement);
if (targetFunction !== func) {
var note = element.createChild("span", "object-info-state-note");
note.title = WebInspector.UIString("Function was resolved from bound function.");
}
element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, targetFunction), false);
}
},
/**
* @param {!WebInspector.RemoteObject} obj
* @param {!Event} event
*/
_contextMenuEventFired: function(obj, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(obj);
contextMenu.show();
},
/**
* @param {?WebInspector.RemoteObject} object
* @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath
* @return {!Element}
*/
_renderPropertyPreviewOrAccessor: function(object, propertyPath)
{
var property = propertyPath.peekLast();
if (property.type === "accessor")
return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
return this._previewFormatter.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value);
},
/**
* @param {!WebInspector.RemoteObject} object
* @param {!Element} elem
*/
_formatParameterAsNode: function(object, elem)
{
WebInspector.Renderer.renderPromise(object).then(appendRenderer, failedToRender.bind(this));
/**
* @param {!Element} rendererElement
*/
function appendRenderer(rendererElement)
{
elem.appendChild(rendererElement);
}
/**
* @this {WebInspector.ConsoleViewMessage}
*/
function failedToRender()
{
this._formatParameterAsObject(object, elem, false);
}
},
/**
* @param {!WebInspector.RemoteObject} array
* @return {boolean}
*/
useArrayPreviewInFormatter: function(array)
{
return this._message.type !== WebInspector.ConsoleMessage.MessageType.DirXML;
},
/**
* @param {!WebInspector.RemoteObject} array
* @param {!Element} elem
*/
_formatParameterAsArray: function(array, elem)
{
var maxFlatArrayLength = 100;
if (this.useArrayPreviewInFormatter(array) || array.arrayLength() > maxFlatArrayLength)
this._formatParameterAsArrayOrObject(array, elem, this.useArrayPreviewInFormatter(array) || array.arrayLength() <= maxFlatArrayLength);
else
array.getAllProperties(false, this._printArray.bind(this, array, elem));
},
/**
* @param {!Array.<!WebInspector.RemoteObject>} parameters
* @return {!Element}
*/
_formatParameterAsTable: function(parameters)
{
var element = createElementWithClass("div", "console-message-formatted-table");
var table = parameters[0];
if (!table || !table.preview)
return element;
var columnNames = [];
var preview = table.preview;
var rows = [];
for (var i = 0; i < preview.properties.length; ++i) {
var rowProperty = preview.properties[i];
var rowPreview = rowProperty.valuePreview;
if (!rowPreview)
continue;
var rowValue = {};
const maxColumnsToRender = 20;
for (var j = 0; j < rowPreview.properties.length; ++j) {
var cellProperty = rowPreview.properties[j];
var columnRendered = columnNames.indexOf(cellProperty.name) != -1;
if (!columnRendered) {
if (columnNames.length === maxColumnsToRender)
continue;
columnRendered = true;
columnNames.push(cellProperty.name);
}
if (columnRendered) {
var cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
cellElement.classList.add("console-message-nowrap-below");
rowValue[cellProperty.name] = cellElement;
}
}
rows.push([rowProperty.name, rowValue]);
}
var flatValues = [];
for (var i = 0; i < rows.length; ++i) {
var rowName = rows[i][0];
var rowValue = rows[i][1];
flatValues.push(rowName);
for (var j = 0; j < columnNames.length; ++j)
flatValues.push(rowValue[columnNames[j]]);
}
var dataGridContainer = element.createChild("span");
if (!preview.lossless || !flatValues.length) {
element.appendChild(this._formatParameter(table, true, false));
if (!flatValues.length)
return element;
}
columnNames.unshift(WebInspector.UIString("(index)"));
var dataGrid = WebInspector.SortableDataGrid.create(columnNames, flatValues);
dataGrid.renderInline();
dataGridContainer.appendChild(dataGrid.element);
this._dataGrids.push(dataGrid);
return element;
},
/**
* @param {!WebInspector.RemoteObject} output
* @param {!Element} elem
*/
_formatParameterAsString: function(output, elem)
{
var span = createElement("span");
span.className = "object-value-string source-code";
span.appendChild(WebInspector.linkifyStringAsFragment(output.description || ""));
// Make black quotes.
elem.classList.remove("object-value-string");
elem.createTextChild("\"");
elem.appendChild(span);
elem.createTextChild("\"");
},
/**
* @param {!WebInspector.RemoteObject} output
* @param {!Element} elem
*/
_formatParameterAsError: function(output, elem)
{
var span = elem.createChild("span", "object-value-error source-code");
var text = output.description || "";
var lines = text.split("\n", 2);
span.appendChild(WebInspector.linkifyStringAsFragment(lines[0]));
if (lines.length > 1) {
var detailedLink = elem.createChild("a");
detailedLink.textContent = "(\u2026)";
function showDetailed(event)
{
span.removeChildren();
detailedLink.remove();
span.appendChild(WebInspector.linkifyStringAsFragment(text));
event.consume(true);
}
detailedLink._showDetailedForTest = showDetailed.bind(null, new MouseEvent('click'));
detailedLink.addEventListener("click", showDetailed, false);
}
},
/**
* @param {!WebInspector.RemoteObject} array
* @param {!Element} elem
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
*/
_printArray: function(array, elem, properties)
{
if (!properties) {
this._formatParameterAsObject(array, elem, false);
return;
}
var elements = {};
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
var name = property.name;
if (isNaN(name))
continue;
if (property.getter)
elements[name] = this._formatAsAccessorProperty(array, [name], true);
else if (property.value)
elements[name] = this._formatAsArrayEntry(property.value);
}
elem.createTextChild("[");
var lastNonEmptyIndex = -1;
function appendUndefined(elem, index)
{
if (index - lastNonEmptyIndex <= 1)
return;
var span = elem.createChild("span", "object-value-undefined");
span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
}
var length = array.arrayLength();
for (var i = 0; i < length; ++i) {
var element = elements[i];
if (!element)
continue;
if (i - lastNonEmptyIndex > 1) {
appendUndefined(elem, i);
elem.createTextChild(", ");
}
elem.appendChild(element);
lastNonEmptyIndex = i;
if (i < length - 1)
elem.createTextChild(", ");
}
appendUndefined(elem, length);
elem.createTextChild("]");
elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, array), false);
},
/**
* @param {!WebInspector.RemoteObject} output
* @return {!Element}
*/
_formatAsArrayEntry: function(output)
{
// Prevent infinite expansion of cross-referencing arrays.
return this._formatParameter(output, output.subtype === "array", false);
},
/**
* @param {?WebInspector.RemoteObject} object
* @param {!Array.<string>} propertyPath
* @param {boolean} isArrayEntry
* @return {!Element}
*/
_formatAsAccessorProperty: function(object, propertyPath, isArrayEntry)
{
var rootElement = WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(object, propertyPath, onInvokeGetterClick.bind(this));
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean=} wasThrown
* @this {WebInspector.ConsoleViewMessage}
*/
function onInvokeGetterClick(result, wasThrown)
{
if (!result)
return;
rootElement.removeChildren();
if (wasThrown) {
var element = rootElement.createChild("span", "error-message");
element.textContent = WebInspector.UIString("<exception>");
element.title = /** @type {string} */ (result.description);
} else if (isArrayEntry) {
rootElement.appendChild(this._formatAsArrayEntry(result));
} else {
// Make a PropertyPreview from the RemoteObject similar to the backend logic.
const maxLength = 100;
var type = result.type;
var subtype = result.subtype;
var description = "";
if (type !== "function" && result.description) {
if (type === "string" || subtype === "regexp")
description = result.description.trimMiddle(maxLength);
else
description = result.description.trimEnd(maxLength);
}
rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
}
}
return rootElement;
},
/**
* @param {string} format
* @param {!Array.<string>} parameters
* @param {!Element} formattedResult
*/
_formatWithSubstitutionString: function(format, parameters, formattedResult)
{
var formatters = {};
/**
* @param {boolean} force
* @param {!WebInspector.RemoteObject} obj
* @return {!Element}
* @this {WebInspector.ConsoleViewMessage}
*/
function parameterFormatter(force, obj)
{
return this._formatParameter(obj, force, false);
}
function stringFormatter(obj)
{
return obj.description;
}
function floatFormatter(obj)
{
if (typeof obj.value !== "number")
return "NaN";
return obj.value;
}
function integerFormatter(obj)
{
if (typeof obj.value !== "number")
return "NaN";
return Math.floor(obj.value);
}
function bypassFormatter(obj)
{
return (obj instanceof Node) ? obj : "";
}
var currentStyle = null;
function styleFormatter(obj)
{
currentStyle = {};
var buffer = createElement("span");
buffer.setAttribute("style", obj.description);
for (var i = 0; i < buffer.style.length; i++) {
var property = buffer.style[i];
var value = buffer.style.getPropertyValue(property);
if (!value.startsWith("url(") && isWhitelistedProperty(property))
currentStyle[property] = buffer.style[property];
}
}
function isWhitelistedProperty(property)
{
var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"];
for (var i = 0; i < prefixes.length; i++) {
if (property.startsWith(prefixes[i]))
return true;
}
return false;
}
// Firebug uses %o for formatting objects.
formatters.o = parameterFormatter.bind(this, false);
formatters.s = stringFormatter;
formatters.f = floatFormatter;
// Firebug allows both %i and %d for formatting integers.
formatters.i = integerFormatter;
formatters.d = integerFormatter;
// Firebug uses %c for styling the message.
formatters.c = styleFormatter;
// Support %O to force object formatting, instead of the type-based %o formatting.
formatters.O = parameterFormatter.bind(this, true);
formatters._ = bypassFormatter;
function append(a, b)
{
if (b instanceof Node)
a.appendChild(b);
else if (typeof b !== "undefined") {
var toAppend = WebInspector.linkifyStringAsFragment(String(b));
if (currentStyle) {
var wrapper = createElement('span');
wrapper.appendChild(toAppend);
applyCurrentStyle(wrapper);
for (var i = 0; i < wrapper.children.length; ++i)
applyCurrentStyle(wrapper.children[i]);
toAppend = wrapper;
}
a.appendChild(toAppend);
}
return a;
}
/**
* @param {!Element} element
*/
function applyCurrentStyle(element)
{
for (var key in currentStyle)
element.style[key] = currentStyle[key];
}
// String.format does treat formattedResult like a Builder, result is an object.
return String.format(format, parameters, formatters, formattedResult, append);
},
/**
* @return {boolean}
*/
matchesFilterRegex: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.searchableElement().deepTextContent();
if (this._anchorElement)
text += " " + this._anchorElement.textContent;
return regexObject.test(text);
},
/**
* @param {boolean} show
*/
updateTimestamp: function(show)
{
if (!this._formattedMessage)
return;
if (show && !this.timestampElement) {
this.timestampElement = createElementWithClass("span", "console-timestamp");
this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime() + " ";
var afterRepeatCountChild = this._repeatCountElement && this._repeatCountElement.nextSibling;
this._formattedMessage.insertBefore(this.timestampElement, this._formattedMessage.firstChild);
return;
}
if (!show && this.timestampElement) {
this.timestampElement.remove();
delete this.timestampElement;
}
},
/**
* @return {number}
*/
nestingLevel: function()
{
return this._nestingLevel;
},
resetCloseGroupDecorationCount: function()
{
if (!this._closeGroupDecorationCount)
return;
this._closeGroupDecorationCount = 0;
this._updateCloseGroupDecorations();
},
incrementCloseGroupDecorationCount: function()
{
++this._closeGroupDecorationCount;
this._updateCloseGroupDecorations();
},
_updateCloseGroupDecorations: function()
{
if (!this._nestingLevelMarkers)
return;
for (var i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
var marker = this._nestingLevelMarkers[i];
marker.classList.toggle("group-closed", n - i <= this._closeGroupDecorationCount);
}
},
/**
* @return {!Element}
*/
contentElement: function()
{
if (this._element)
return this._element;
var element = createElementWithClass("div", "console-message");
this._element = element;
if (this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.classList.add("console-group-title");
element.appendChild(this.formattedMessage());
if (this._repeatCount > 1)
this._showRepeatCountElement();
this.updateTimestamp(WebInspector.moduleSetting("consoleTimestampsEnabled").get());
return this._element;
},
/**
* @return {!Element}
*/
toMessageElement: function()
{
if (this._wrapperElement)
return this._wrapperElement;
this._wrapperElement = createElement("div");
this.updateMessageElement();
return this._wrapperElement;
},
updateMessageElement: function()
{
if (!this._wrapperElement)
return;
this._wrapperElement.className = "console-message-wrapper";
this._wrapperElement.removeChildren();
this._nestingLevelMarkers = [];
for (var i = 0; i < this._nestingLevel; ++i)
this._nestingLevelMarkers.push(this._wrapperElement.createChild("div", "nesting-level-marker"));
this._updateCloseGroupDecorations();
this._wrapperElement.message = this;
switch (this._message.level) {
case WebInspector.ConsoleMessage.MessageLevel.Log:
this._wrapperElement.classList.add("console-log-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
this._wrapperElement.classList.add("console-debug-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
this._wrapperElement.classList.add("console-warning-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
this._wrapperElement.classList.add("console-error-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
this._wrapperElement.classList.add("console-revokedError-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Info:
this._wrapperElement.classList.add("console-info-level");
break;
}
this._wrapperElement.appendChild(this.contentElement());
},
/**
* @param {!TreeElement} parentTreeElement
*/
_populateStackTraceTreeElement: function(parentTreeElement)
{
var target = this._target();
if (!target)
return;
var content = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(target, this._linkifier, this._message.stackTrace);
var treeElement = new TreeElement(content);
treeElement.selectable = false;
parentTreeElement.appendChild(treeElement);
},
resetIncrementRepeatCount: function()
{
this._repeatCount = 1;
if (!this._repeatCountElement)
return;
this._repeatCountElement.remove();
delete this._repeatCountElement;
},
incrementRepeatCount: function()
{
this._repeatCount++;
this._showRepeatCountElement();
},
_showRepeatCountElement: function()
{
if (!this._element)
return;
if (!this._repeatCountElement) {
this._repeatCountElement = createElement("span");
this._repeatCountElement.className = "bubble-repeat-count";
this._element.insertBefore(this._repeatCountElement, this._element.firstChild);
this._element.classList.add("repeated-message");
}
this._repeatCountElement.textContent = this._repeatCount;
},
/**
* @override
* @return {string}
*/
toString: function()
{
var sourceString;
switch (this._message.source) {
case WebInspector.ConsoleMessage.MessageSource.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
sourceString = "JavaScript";
break;
case WebInspector.ConsoleMessage.MessageSource.Network:
sourceString = "Network";
break;
case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
sourceString = "ConsoleAPI";
break;
case WebInspector.ConsoleMessage.MessageSource.Storage:
sourceString = "Storage";
break;
case WebInspector.ConsoleMessage.MessageSource.AppCache:
sourceString = "AppCache";
break;
case WebInspector.ConsoleMessage.MessageSource.Rendering:
sourceString = "Rendering";
break;
case WebInspector.ConsoleMessage.MessageSource.CSS:
sourceString = "CSS";
break;
case WebInspector.ConsoleMessage.MessageSource.Security:
sourceString = "Security";
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
sourceString = "Other";
break;
}
var typeString;
switch (this._message.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
typeString = "Dir";
break;
case WebInspector.ConsoleMessage.MessageType.DirXML:
typeString = "Dir XML";
break;
case WebInspector.ConsoleMessage.MessageType.Trace:
typeString = "Trace";
break;
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
typeString = "Start Group";
break;
case WebInspector.ConsoleMessage.MessageType.EndGroup:
typeString = "End Group";
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
typeString = "Assert";
break;
case WebInspector.ConsoleMessage.MessageType.Result:
typeString = "Result";
break;
case WebInspector.ConsoleMessage.MessageType.Profile:
case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
typeString = "Profiling";
break;
}
var levelString;
switch (this._message.level) {
case WebInspector.ConsoleMessage.MessageLevel.Log:
levelString = "Log";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
levelString = "Warning";
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
levelString = "Debug";
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
levelString = "RevokedError";
break;
case WebInspector.ConsoleMessage.MessageLevel.Info:
levelString = "Info";
break;
}
return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage().textContent + "\n" + this._message.url + " line " + this._message.line;
},
get text()
{
return this._message.messageText;
},
/**
* @param {?RegExp} regex
*/
setSearchRegex: function(regex)
{
if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length)
WebInspector.revertDomChanges(this._searchHiglightNodeChanges);
this._searchRegex = regex;
this._searchHighlightNodes = [];
this._searchHiglightNodeChanges = [];
if (!this._searchRegex)
return;
var text = this.searchableElement().deepTextContent();
var match;
this._searchRegex.lastIndex = 0;
var sourceRanges = [];
while ((match = this._searchRegex.exec(text)) && match[0])
sourceRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
if (sourceRanges.length && this.searchableElement())
this._searchHighlightNodes = WebInspector.highlightSearchResults(this.searchableElement(), sourceRanges, this._searchHiglightNodeChanges);
},
/**
* @return {?RegExp}
*/
searchRegex: function()
{
return this._searchRegex;
},
/**
* @return {number}
*/
searchCount: function()
{
return this._searchHighlightNodes.length;
},
/**
* @return {!Element}
*/
searchHighlightNode: function(index)
{
return this._searchHighlightNodes[index];
},
/**
* @return {!Element}
*/
searchableElement: function()
{
this.formattedMessage();
return this._messageElement;
},
/**
* @param {string} string
* @return {?Element}
*/
_tryFormatAsError: function(string)
{
/**
* @param {string} prefix
*/
function startsWith(prefix)
{
return string.startsWith(prefix);
}
var errorPrefixes = ["EvalError", "ReferenceError", "SyntaxError", "TypeError", "RangeError", "Error", "URIError"];
var target = this._target();
if (!target || !errorPrefixes.some(startsWith))
return null;
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return null;
var lines = string.split("\n");
var links = [];
var position = 0;
for (var i = 0; i < lines.length; ++i) {
position += i > 0 ? lines[i - 1].length + 1 : 0;
var isCallFrameLine = /^\s*at\s/.test(lines[i]);
if (!isCallFrameLine && links.length)
return null;
if (!isCallFrameLine)
continue;
var openBracketIndex = -1;
var closeBracketIndex = -1;
var match = /\([^\)\(]+\)/.exec(lines[i]);
if (match) {
openBracketIndex = match.index;
closeBracketIndex = match.index + match[0].length - 1;
}
var hasOpenBracket = openBracketIndex !== -1;
var left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf("at") + 3;
var right = hasOpenBracket ? closeBracketIndex : lines[i].length;
var linkCandidate = lines[i].substring(left, right);
var splitResult = WebInspector.ParsedURL.splitLineAndColumn(linkCandidate);
if (!splitResult)
return null;
var parsed = splitResult.url.asParsedURL();
var url;
if (parsed)
url = parsed.url;
else if (debuggerModel.scriptsForSourceURL(splitResult.url).length)
url = splitResult.url;
else if (splitResult.url === "<anonymous>")
continue;
else
return null;
links.push({url: url, positionLeft: position + left, positionRight: position + right, lineNumber: splitResult.lineNumber, columnNumber: splitResult.columnNumber});
}
if (!links.length)
return null;
var formattedResult = createElement("span");
var start = 0;
for (var i = 0; i < links.length; ++i) {
formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
formattedResult.appendChild(this._linkifier.linkifyScriptLocation(target, null, links[i].url, links[i].lineNumber, links[i].columnNumber));
start = links[i].positionRight;
}
if (start != string.length)
formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));
return formattedResult;
}
}
/**
* @constructor
* @extends {WebInspector.ConsoleViewMessage}
* @param {!WebInspector.ConsoleMessage} consoleMessage
* @param {!WebInspector.Linkifier} linkifier
* @param {number} nestingLevel
*/
WebInspector.ConsoleGroupViewMessage = function(consoleMessage, linkifier, nestingLevel)
{
console.assert(consoleMessage.isGroupStartMessage());
WebInspector.ConsoleViewMessage.call(this, consoleMessage, linkifier, nestingLevel);
this.setCollapsed(consoleMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed);
}
WebInspector.ConsoleGroupViewMessage.prototype = {
/**
* @param {boolean} collapsed
*/
setCollapsed: function(collapsed)
{
this._collapsed = collapsed;
if (this._wrapperElement)
this._wrapperElement.classList.toggle("collapsed", this._collapsed);
},
/**
* @return {boolean}
*/
collapsed: function()
{
return this._collapsed;
},
/**
* @override
* @return {!Element}
*/
toMessageElement: function()
{
if (!this._wrapperElement) {
WebInspector.ConsoleViewMessage.prototype.toMessageElement.call(this);
this._wrapperElement.classList.toggle("collapsed", this._collapsed);
}
return this._wrapperElement;
},
__proto__: WebInspector.ConsoleViewMessage.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| DevicesDialog.js | 7.14% | (1 / 14) | 0% | (0 / 4) | 0% | (0 / 3) | 7.14% | (1 / 14) | |
| DevicesView.js | 2.53% | (9 / 356) | 0% | (0 / 113) | 0% | (0 / 34) | 2.54% | (9 / 355) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.DevicesDialog = function() { } /** * @constructor * @implements {WebInspector.ActionDelegate} */ WebInspector.DevicesDialog.ActionDelegate = function() { /** @type {?WebInspector.DevicesView} */ this._view = null; } WebInspector.DevicesDialog.ActionDelegate.prototype = { /** * @override * @param {!WebInspector.Context} context * @param {string} actionId * @return {boolean} */ handleAction: function(context, actionId) { if (actionId === "devices.dialog.show") { if (!this._view) this._view = new WebInspector.DevicesView(); var dialog = new WebInspector.Dialog(); dialog.addCloseButton(); this._view.show(dialog.element); dialog.setMaxSize(new Size(700, 500)); dialog.show(); return true; } return false; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | 2 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DevicesView = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("devices/devicesView.css");
this.contentElement.classList.add("devices-view");
var hbox = this.contentElement.createChild("div", "hbox devices-container");
var sidebar = hbox.createChild("div", "devices-sidebar");
sidebar.createChild("div", "devices-view-title").createTextChild(WebInspector.UIString("Devices"));
this._sidebarList = sidebar.createChild("div", "devices-sidebar-list");
this._discoveryView = new WebInspector.DevicesView.DiscoveryView();
this._sidebarListSpacer = this._sidebarList.createChild("div", "devices-sidebar-spacer");
this._discoveryListItem = this._sidebarList.createChild("div", "devices-sidebar-item");
this._discoveryListItem.textContent = WebInspector.UIString("Settings");
this._discoveryListItem.addEventListener("click", this._selectSidebarListItem.bind(this, this._discoveryListItem, this._discoveryView));
/** @type {!Map<string, !WebInspector.DevicesView.DeviceView>} */
this._viewById = new Map();
/** @type {!Array<!Adb.Device>} */
this._devices = [];
/** @type {!Map<string, !Element>} */
this._listItemById = new Map();
this._viewContainer = hbox.createChild("div", "flex-auto vbox");
var discoveryFooter = this.contentElement.createChild("div", "devices-footer");
this._deviceCountSpan = discoveryFooter.createChild("span");
discoveryFooter.createChild("span").textContent = WebInspector.UIString(" Read ");
discoveryFooter.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/chrome-developer-tools/docs/remote-debugging", WebInspector.UIString("remote debugging documentation"), undefined, true));
discoveryFooter.createChild("span").textContent = WebInspector.UIString(" for more information.");
this._updateFooter();
this._selectSidebarListItem(this._discoveryListItem, this._discoveryView);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesUpdated, this._devicesUpdated, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, this._devicesPortForwardingStatusChanged, this);
this.contentElement.tabIndex = 0;
this.setDefaultFocusedElement(this.contentElement);
}
WebInspector.DevicesView.prototype = {
/**
* @param {!Element} listItem
* @param {!WebInspector.Widget} view
*/
_selectSidebarListItem: function(listItem, view)
{
if (this._selectedListItem === listItem)
return;
if (this._selectedListItem) {
this._selectedListItem.classList.remove("selected");
this._visibleView.detach();
}
this._visibleView = view;
this._selectedListItem = listItem;
this._visibleView.show(this._viewContainer);
this._selectedListItem.classList.add("selected");
},
/**
* @param {!WebInspector.Event} event
*/
_devicesUpdated: function(event)
{
this._devices = /** @type {!Array.<!Adb.Device>} */ (event.data).slice().filter(d => d.adbSerial.toUpperCase() !== "WEBRTC");
for (var device of this._devices) {
if (!device.adbConnected)
device.adbModel = WebInspector.UIString("Unknown");
}
var ids = new Set();
for (var device of this._devices)
ids.add(device.id);
var selectedRemoved = false;
for (var deviceId of this._viewById.keys()) {
if (!ids.has(deviceId)) {
var listItem = /** @type {!Element} */ (this._listItemById.get(deviceId));
this._listItemById.remove(deviceId);
this._viewById.remove(deviceId);
listItem.remove();
if (listItem === this._selectedListItem)
selectedRemoved = true;
}
}
for (var device of this._devices) {
var view = this._viewById.get(device.id);
var listItem = this._listItemById.get(device.id);
if (!view) {
view = new WebInspector.DevicesView.DeviceView();
this._viewById.set(device.id, view);
listItem = this._createSidebarListItem(view);
this._listItemById.set(device.id, listItem);
this._sidebarList.insertBefore(listItem, this._sidebarListSpacer);
}
listItem._title.textContent = device.adbModel;
listItem._status.textContent = device.adbConnected ? WebInspector.UIString("Connected") : WebInspector.UIString("Pending Authorization");
listItem.classList.toggle("device-connected", device.adbConnected);
view.update(device);
}
if (selectedRemoved)
this._selectSidebarListItem(this._discoveryListItem, this._discoveryView);
this._updateFooter();
},
/**
* @param {!WebInspector.Widget} view
* @return {!Element}
*/
_createSidebarListItem: function(view)
{
var listItem = createElementWithClass("div", "devices-sidebar-item");
listItem.addEventListener("click", this._selectSidebarListItem.bind(this, listItem, view));
listItem._title = listItem.createChild("div", "devices-sidebar-item-title");
listItem._status = listItem.createChild("div", "devices-sidebar-item-status");
return listItem;
},
/**
* @param {!WebInspector.Event} event
*/
_devicesDiscoveryConfigChanged: function(event)
{
var discoverUsbDevices = /** @type {boolean} */ (event.data["discoverUsbDevices"]);
var portForwardingEnabled = /** @type {boolean} */ (event.data["portForwardingEnabled"]);
var portForwardingConfig = /** @type {!Adb.PortForwardingConfig} */ (event.data["portForwardingConfig"]);
this._discoveryView.discoveryConfigChanged(discoverUsbDevices, portForwardingEnabled, portForwardingConfig);
},
/**
* @param {!WebInspector.Event} event
*/
_devicesPortForwardingStatusChanged: function(event)
{
var status = /** @type {!Adb.PortForwardingStatus} */ (event.data);
for (var deviceId in status) {
var view = this._viewById.get(deviceId);
if (view)
view.portForwardingStatusChanged(status[deviceId]);
}
for (var deviceId of this._viewById.keys()) {
var view = this._viewById.get(deviceId);
if (view && !(deviceId in status))
view.portForwardingStatusChanged({ports: {}, browserId: ""});
}
},
_updateFooter: function()
{
this._deviceCountSpan.textContent =
!this._devices.length ? WebInspector.UIString("No devices detected.") :
this._devices.length === 1 ? WebInspector.UIString("1 device detected.") : WebInspector.UIString("%d devices detected.", this._devices.length);
},
/**
* @override
*/
wasShown: function()
{
WebInspector.PanelWithSidebar.prototype.wasShown.call(this);
InspectorFrontendHost.setDevicesUpdatesEnabled(true);
},
/**
* @override
*/
willHide: function()
{
WebInspector.PanelWithSidebar.prototype.wasShown.call(this);
InspectorFrontendHost.setDevicesUpdatesEnabled(false);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @return {!WebInspector.DevicesView}
*/
WebInspector.DevicesView._instance = function()
{
if (!WebInspector.DevicesView._instanceObject)
WebInspector.DevicesView._instanceObject = new WebInspector.DevicesView();
return WebInspector.DevicesView._instanceObject;
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ListWidget.Delegate}
*/
WebInspector.DevicesView.DiscoveryView = function()
{
WebInspector.VBox.call(this);
this.setMinimumSize(100, 100);
this.element.classList.add("discovery-view");
this.contentElement.createChild("div", "hbox device-text-row").createChild("div", "view-title").textContent = WebInspector.UIString("Settings");
var discoverUsbDevicesCheckbox = createCheckboxLabel(WebInspector.UIString("Discover USB devices"));
discoverUsbDevicesCheckbox.classList.add("usb-checkbox");
this.element.appendChild(discoverUsbDevicesCheckbox);
this._discoverUsbDevicesCheckbox = discoverUsbDevicesCheckbox.checkboxElement;
this._discoverUsbDevicesCheckbox.addEventListener("click", this._updateDiscoveryConfig.bind(this), false);
var help = this.element.createChild("div", "discovery-help");
help.createChild("span").textContent = WebInspector.UIString("Need help? Read Chrome ");
help.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/chrome-developer-tools/docs/remote-debugging", WebInspector.UIString("remote debugging documentation."), undefined, true));
var portForwardingHeader = this.element.createChild("div", "port-forwarding-header");
var portForwardingEnabledCheckbox = createCheckboxLabel(WebInspector.UIString("Port forwarding"));
portForwardingEnabledCheckbox.classList.add("port-forwarding-checkbox");
portForwardingHeader.appendChild(portForwardingEnabledCheckbox);
this._portForwardingEnabledCheckbox = portForwardingEnabledCheckbox.checkboxElement;
this._portForwardingEnabledCheckbox.addEventListener("click", this._updateDiscoveryConfig.bind(this), false);
var portForwardingFooter = this.element.createChild("div", "port-forwarding-footer");
portForwardingFooter.createChild("span").textContent = WebInspector.UIString("Define the listening port on your device that maps to a port accessible from your development machine. ");
portForwardingFooter.appendChild(WebInspector.linkifyURLAsNode("https://developer.chrome.com/devtools/docs/remote-debugging#port-forwarding", WebInspector.UIString("Learn more"), undefined, true));
this._list = new WebInspector.ListWidget(this);
this._list.registerRequiredCSS("devices/devicesView.css");
this._list.element.classList.add("port-forwarding-list");
var placeholder = createElementWithClass("div", "port-forwarding-list-empty");
placeholder.textContent = WebInspector.UIString("No rules");
this._list.setEmptyPlaceholder(placeholder);
this._list.show(this.element);
this.element.appendChild(createTextButton(WebInspector.UIString("Add rule"), this._addRuleButtonClicked.bind(this), "add-rule-button"));
/** @type {!Array<!Adb.PortForwardingRule>} */
this._portForwardingConfig = [];
}
WebInspector.DevicesView.DiscoveryView.prototype = {
_addRuleButtonClicked: function()
{
this._list.addNewItem(this._portForwardingConfig.length, {port: "", address: ""});
},
/**
* @param {boolean} discoverUsbDevices
* @param {boolean} portForwardingEnabled
* @param {!Adb.PortForwardingConfig} portForwardingConfig
*/
discoveryConfigChanged: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig)
{
this._discoverUsbDevicesCheckbox.checked = discoverUsbDevices;
this._portForwardingEnabledCheckbox.checked = portForwardingEnabled;
this._portForwardingConfig = [];
this._list.clear();
for (var key of Object.keys(portForwardingConfig)) {
var rule = /** @type {!Adb.PortForwardingRule} */ ({port: key, address: portForwardingConfig[key]});
this._portForwardingConfig.push(rule);
this._list.appendItem(rule, true);
}
},
/**
* @override
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable)
{
var rule = /** @type {!Adb.PortForwardingRule} */ (item);
var element = createElementWithClass("div", "port-forwarding-list-item");
var port = element.createChild("div", "port-forwarding-value port-forwarding-port");
port.createChild("span", "port-localhost").textContent = WebInspector.UIString("localhost:");
port.createTextChild(rule.port);
element.createChild("div", "port-forwarding-separator");
element.createChild("div", "port-forwarding-value").textContent = rule.address;
return element;
},
/**
* @override
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index)
{
this._portForwardingConfig.splice(index, 1);
this._list.removeItem(index);
this._updateDiscoveryConfig();
},
/**
* @override
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew)
{
var rule = /** @type {!Adb.PortForwardingRule} */ (item);
rule.port = editor.control("port").value.trim();
rule.address = editor.control("address").value.trim();
if (isNew)
this._portForwardingConfig.push(rule);
this._updateDiscoveryConfig();
},
/**
* @override
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item)
{
var rule = /** @type {!Adb.PortForwardingRule} */ (item);
var editor = this._createEditor();
editor.control("port").value = rule.port;
editor.control("address").value = rule.address;
return editor;
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createEditor: function()
{
if (this._editor)
return this._editor;
var editor = new WebInspector.ListWidget.Editor();
this._editor = editor;
var content = editor.contentElement();
var fields = content.createChild("div", "port-forwarding-edit-row");
fields.createChild("div", "port-forwarding-value port-forwarding-port").appendChild(editor.createInput("port", "text", "Device port (3333)", portValidator.bind(this)));
fields.createChild("div", "port-forwarding-separator port-forwarding-separator-invisible");
fields.createChild("div", "port-forwarding-value").appendChild(editor.createInput("address", "text", "Local address (dev.example.corp:3333)", addressValidator));
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @this {WebInspector.DevicesView.DiscoveryView}
* @return {boolean}
*/
function portValidator(item, index, input)
{
var value = input.value.trim();
var match = value.match(/^(\d+)$/);
if (!match)
return false;
var port = parseInt(match[1], 10);
if (port < 1024 || port > 65535)
return false;
for (var i = 0; i < this._portForwardingConfig.length; ++i) {
if (i !== index && this._portForwardingConfig[i].port === value)
return false;
}
return true;
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function addressValidator(item, index, input)
{
var match = input.value.trim().match(/^([a-zA-Z0-9\.\-_]+):(\d+)$/);
if (!match)
return false;
var port = parseInt(match[2], 10);
return port <= 65535;
}
},
_updateDiscoveryConfig: function()
{
var configMap = /** @type {!Adb.PortForwardingConfig} */ ({});
for (var rule of this._portForwardingConfig)
configMap[rule.port] = rule.address;
InspectorFrontendHost.setDevicesDiscoveryConfig(this._discoverUsbDevicesCheckbox.checked, this._portForwardingEnabledCheckbox.checked, configMap);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DevicesView.DeviceView = function()
{
WebInspector.VBox.call(this);
this.setMinimumSize(100, 100);
this.contentElement.classList.add("device-view");
var topRow = this.contentElement.createChild("div", "hbox device-text-row");
this._deviceTitle = topRow.createChild("div", "view-title");
this._deviceSerial = topRow.createChild("div", "device-serial");
this._portStatus = this.contentElement.createChild("div", "device-port-status hidden");
this._deviceOffline = this.contentElement.createChild("div");
this._deviceOffline.textContent = WebInspector.UIString("Pending authentication: please accept debugging session on the device.");
this._noBrowsers = this.contentElement.createChild("div");
this._noBrowsers.textContent = WebInspector.UIString("No browsers detected.");
this._browsers = this.contentElement.createChild("div", "device-browser-list vbox");
/** @type {!Map<string, !WebInspector.DevicesView.BrowserSection>} */
this._browserById = new Map();
this._device = null;
}
/** @typedef {!{browser: ?Adb.Browser, element: !Element, title: !Element, pages: !Element, viewMore: !Element, newTab: !Element, pageSections: !Map<string, !WebInspector.DevicesView.PageSection>}} */
WebInspector.DevicesView.BrowserSection;
/** @typedef {!{page: ?Adb.Page, element: !Element, title: !Element, url: !Element, inspect: !Element}} */
WebInspector.DevicesView.PageSection;
WebInspector.DevicesView.DeviceView.prototype = {
/**
* @param {!Adb.Device} device
*/
update: function(device)
{
if (!this._device || this._device.adbModel !== device.adbModel)
this._deviceTitle.textContent = device.adbModel;
if (!this._device || this._device.adbSerial !== device.adbSerial)
this._deviceSerial.textContent = "#" + device.adbSerial;
this._deviceOffline.classList.toggle("hidden", device.adbConnected);
this._noBrowsers.classList.toggle("hidden", !device.adbConnected || !!device.browsers.length);
this._browsers.classList.toggle("hidden", !device.adbConnected || !device.browsers.length);
var browserIds = new Set();
for (var browser of device.browsers)
browserIds.add(browser.id);
for (var browserId of this._browserById.keys()) {
if (!browserIds.has(browserId)) {
this._browserById.get(browserId).element.remove();
this._browserById.remove(browserId);
}
}
for (var browser of device.browsers) {
var section = this._browserById.get(browser.id);
if (!section) {
section = this._createBrowserSection();
this._browserById.set(browser.id, section);
this._browsers.appendChild(section.element);
}
this._updateBrowserSection(section, browser);
}
this._device = device;
},
/**
* @return {!WebInspector.DevicesView.BrowserSection}
*/
_createBrowserSection: function()
{
var element = createElementWithClass("div", "vbox flex-none");
var topRow = element.createChild("div", "");
var title = topRow.createChild("div", "device-browser-title");
var newTabRow = element.createChild("div", "device-browser-new-tab");
newTabRow.createChild("div", "").textContent = WebInspector.UIString("New tab:");
var newTabInput = newTabRow.createChild("input", "");
newTabInput.type = "text";
newTabInput.placeholder = WebInspector.UIString("Enter URL");
newTabInput.addEventListener("keydown", newTabKeyDown, false);
var newTabButton = createTextButton(WebInspector.UIString("Open"), openNewTab);
newTabRow.appendChild(newTabButton);
var pages = element.createChild("div", "device-page-list vbox");
var viewMore = element.createChild("div", "device-view-more");
viewMore.addEventListener("click", viewMoreClick, false);
updateViewMoreTitle();
var section = {browser: null, element: element, title: title, pages: pages, viewMore: viewMore, newTab: newTabRow, pageSections: new Map()};
return section;
function viewMoreClick()
{
pages.classList.toggle("device-view-more-toggled");
updateViewMoreTitle();
}
function updateViewMoreTitle()
{
viewMore.textContent = pages.classList.contains("device-view-more-toggled") ? WebInspector.UIString("View less tabs\u2026") : WebInspector.UIString("View more tabs\u2026");
}
/**
* @param {!Event} event
*/
function newTabKeyDown(event)
{
if (event.keyIdentifier === "Enter") {
event.consume(true);
openNewTab();
}
}
function openNewTab()
{
if (section.browser) {
InspectorFrontendHost.openRemotePage(section.browser.id, newTabInput.value.trim() || "about:blank");
newTabInput.value = "";
}
}
},
/**
* @param {!WebInspector.DevicesView.BrowserSection} section
* @param {!Adb.Browser} browser
*/
_updateBrowserSection: function(section, browser)
{
if (!section.browser || section.browser.adbBrowserName !== browser.adbBrowserName || section.browser.adbBrowserVersion !== browser.adbBrowserVersion) {
if (browser.adbBrowserVersion)
section.title.textContent = String.sprintf("%s (%s)", browser.adbBrowserName, browser.adbBrowserVersion);
else
section.title.textContent = browser.adbBrowserName;
}
var pageIds = new Set();
for (var page of browser.pages)
pageIds.add(page.id);
for (var pageId of section.pageSections.keys()) {
if (!pageIds.has(pageId)) {
section.pageSections.get(pageId).element.remove();
section.pageSections.remove(pageId);
}
}
for (var index = 0; index < browser.pages.length; ++index) {
var page = browser.pages[index];
var pageSection = section.pageSections.get(page.id);
if (!pageSection) {
pageSection = this._createPageSection();
section.pageSections.set(page.id, pageSection);
section.pages.appendChild(pageSection.element);
}
this._updatePageSection(pageSection, page);
if (!index && section.pages.firstChild !== pageSection.element)
section.pages.insertBefore(pageSection.element, section.pages.firstChild);
}
var kViewMoreCount = 3;
for (var index = 0, element = section.pages.firstChild; element; element = element.nextSibling, ++index)
element.classList.toggle("device-view-more-page", index >= kViewMoreCount);
section.viewMore.classList.toggle("device-needs-view-more", browser.pages.length > kViewMoreCount);
section.newTab.classList.toggle("hidden", !browser.adbBrowserChromeVersion);
section.browser = browser;
},
/**
* @return {!WebInspector.DevicesView.PageSection}
*/
_createPageSection: function()
{
var element = createElementWithClass("div", "vbox");
var titleRow = element.createChild("div", "device-page-title-row");
var title = titleRow.createChild("div", "device-page-title");
var inspect = createTextButton(WebInspector.UIString("Inspect"), doAction.bind(null, "inspect"), "device-inspect-button");
titleRow.appendChild(inspect);
var toolbar = new WebInspector.Toolbar("");
toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(appendActions));
titleRow.appendChild(toolbar.element);
var url = element.createChild("div", "device-page-url");
var section = {page: null, element: element, title: title, url: url, inspect: inspect};
return section;
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
function appendActions(contextMenu)
{
contextMenu.appendItem(WebInspector.UIString("Reload"), doAction.bind(null, "reload"));
contextMenu.appendItem(WebInspector.UIString("Focus"), doAction.bind(null, "activate"));
contextMenu.appendItem(WebInspector.UIString("Close"), doAction.bind(null, "close"));
}
/**
* @param {string} action
*/
function doAction(action)
{
if (section.page)
InspectorFrontendHost.performActionOnRemotePage(section.page.id, action);
}
},
/**
* @param {!WebInspector.DevicesView.PageSection} section
* @param {!Adb.Page} page
*/
_updatePageSection: function(section, page)
{
if (!section.page || section.page.name !== page.name) {
section.title.textContent = page.name;
section.title.title = page.name;
}
if (!section.page || section.page.url !== page.url) {
section.url.textContent = "";
section.url.appendChild(WebInspector.linkifyURLAsNode(page.url, undefined, undefined, true));
}
section.inspect.disabled = page.adbAttachedForeign;
section.page = page;
},
/**
* @param {!Adb.DevicePortForwardingStatus} status
*/
portForwardingStatusChanged: function(status)
{
var json = JSON.stringify(status);
if (json === this._cachedPortStatus)
return;
this._cachedPortStatus = json;
this._portStatus.removeChildren();
this._portStatus.createChild("div", "device-port-status-text").textContent = WebInspector.UIString("Port Forwarding:");
var connected = [];
var transient = [];
var error = [];
var empty = true;
for (var port in status.ports) {
if (!status.ports.hasOwnProperty(port))
continue;
empty = false;
var portStatus = status.ports[port];
var portNumber = createElementWithClass("div", "device-view-port-number monospace");
portNumber.textContent = ":" + port;
if (portStatus >= 0)
this._portStatus.appendChild(portNumber);
else
this._portStatus.insertBefore(portNumber, this._portStatus.firstChild);
var portIcon = createElementWithClass("div", "device-view-port-icon");
if (portStatus >= 0) {
connected.push(port);
} else if (portStatus === -1 || portStatus === -2) {
portIcon.classList.add("device-view-port-icon-transient");
transient.push(port);
} else if (portStatus < 0) {
portIcon.classList.add("device-view-port-icon-error");
error.push(port);
}
this._portStatus.insertBefore(portIcon, portNumber);
}
var title = [];
if (connected.length)
title.push(WebInspector.UIString("Connected: %s", connected.join(", ")));
if (transient.length)
title.push(WebInspector.UIString("Transient: %s", transient.join(", ")));
if (error.length)
title.push(WebInspector.UIString("Error: %s", error.join(", ")));
this._portStatus.title = title.join("; ");
this._portStatus.classList.toggle("hidden", empty);
},
__proto__: WebInspector.VBox.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Diff.js | 6.82% | (3 / 44) | 0% | (0 / 16) | 0% | (0 / 5) | 6.82% | (3 / 44) | |
| diff_match_patch.js | 9.73% | (50 / 514) | 0% | (0 / 517) | 2.44% | (1 / 41) | 72.92% | (35 / 48) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 2 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.Diff = {
/**
* @param {string} text1
* @param {string} text2
* @return {!Array.<!{0: number, 1: string}>}
*/
charDiff: function(text1, text2)
{
var differ = new diff_match_patch();
return differ.diff_main(text1, text2);
},
/**
* @param {!Array.<string>} lines1
* @param {!Array.<string>} lines2
* @return {!Array.<!{0: number, 1: string}>}
*/
lineDiff: function(lines1, lines2)
{
var lineToChar = new Map();
var charCode = 33;
var text1 = encode(lines1);
var text2 = encode(lines2);
return WebInspector.Diff.charDiff(text1, text2);
/**
* @param {!Array.<string>} lines
* @return {string}
*/
function encode(lines)
{
var text = "";
for (var i = 0; i < lines.length; ++i) {
var line = lines[i];
var character = lineToChar.get(line);
if (!character) {
character = String.fromCharCode(charCode++);
lineToChar.set(line, character);
}
text += character;
}
return text;
}
},
/**
* @param {!Array.<!{0: number, 1: string}>} diff
* @return {!Array<!Array<number>>}
*/
convertToEditDiff: function(diff)
{
var normalized = [];
var added = 0;
var removed = 0;
for (var i = 0; i < diff.length; ++i) {
var token = diff[i];
if (token[0] === WebInspector.Diff.Operation.Equal) {
flush();
normalized.push([WebInspector.Diff.Operation.Equal, token[1].length]);
} else if (token[0] === WebInspector.Diff.Operation.Delete) {
removed += token[1].length;
} else {
added += token[1].length;
}
}
flush();
return normalized;
function flush()
{
if (added && removed) {
var min = Math.min(added, removed);
normalized.push([WebInspector.Diff.Operation.Edit, min]);
added -= min;
removed -= min;
}
if (added || removed) {
var balance = added - removed;
var type = balance < 0 ? WebInspector.Diff.Operation.Delete : WebInspector.Diff.Operation.Insert;
normalized.push([type, Math.abs(balance)]);
added = 0;
removed = 0;
}
}
}
}
WebInspector.Diff.Operation = {
Equal: 0,
Insert: 1,
Delete: -1,
Edit: 2
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | (function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
d):this.diff_bisect_(a,b,d)};
diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&").replace(d,"<").replace(e,">").replace(f,"¶<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
c.length+d.length;a.length2+=c.length+d.length}};
diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| BezierEditor.js | 0.88% | (1 / 113) | 0% | (0 / 18) | 0% | (0 / 16) | 0.88% | (1 / 113) | |
| BezierUI.js | 2.04% | (1 / 49) | 0% | (0 / 4) | 0% | (0 / 7) | 2.04% | (1 / 49) | |
| ClassesPaneWidget.js | 1.96% | (2 / 102) | 0% | (0 / 30) | 0% | (0 / 14) | 1.96% | (2 / 102) | |
| ComputedStyleWidget.js | 2.53% | (4 / 158) | 0% | (0 / 43) | 0% | (0 / 14) | 2.53% | (4 / 158) | |
| ElementStatePaneWidget.js | 4.62% | (3 / 65) | 0% | (0 / 18) | 0% | (0 / 11) | 4.62% | (3 / 65) | |
| ElementsBreadcrumbs.js | 3.54% | (8 / 226) | 0% | (0 / 124) | 0% | (0 / 15) | 3.54% | (8 / 226) | |
| ElementsPanel.js | 2.36% | (13 / 551) | 0% | (0 / 246) | 0% | (0 / 82) | 2.36% | (13 / 550) | |
| ElementsSidebarPane.js | 5.77% | (3 / 52) | 0% | (0 / 25) | 0% | (0 / 19) | 5.77% | (3 / 52) | |
| ElementsSidebarView.js | 25% | (1 / 4) | 100% | (0 / 0) | 0% | (0 / 1) | 25% | (1 / 4) | |
| ElementsTreeElement.js | 4.25% | (32 / 753) | 0% | (0 / 412) | 0% | (0 / 96) | 4.26% | (32 / 752) | |
| ElementsTreeElementHighlighter.js | 4.44% | (2 / 45) | 0% | (0 / 19) | 0% | (0 / 5) | 4.44% | (2 / 45) | |
| ElementsTreeOutline.js | 1.75% | (13 / 741) | 0% | (0 / 430) | 0% | (0 / 118) | 1.75% | (13 / 741) | |
| EventListenersWidget.js | 4.35% | (3 / 69) | 0% | (0 / 18) | 0% | (0 / 9) | 4.35% | (3 / 69) | |
| InspectElementModeController.js | 1.92% | (1 / 52) | 0% | (0 / 30) | 0% | (0 / 14) | 1.92% | (1 / 52) | |
| MetricsSidebarPane.js | 4.48% | (9 / 201) | 0% | (0 / 126) | 0% | (0 / 23) | 4.48% | (9 / 201) | |
| PlatformFontsWidget.js | 2.63% | (1 / 38) | 0% | (0 / 14) | 0% | (0 / 5) | 2.63% | (1 / 38) | |
| PropertiesWidget.js | 6.67% | (5 / 75) | 0% | (0 / 26) | 0% | (0 / 10) | 6.67% | (5 / 75) | |
| PropertyChangeHighlighter.js | 1.64% | (1 / 61) | 0% | (0 / 41) | 0% | (0 / 5) | 1.64% | (1 / 61) | |
| SharedSidebarModel.js | 4.55% | (2 / 44) | 0% | (0 / 31) | 0% | (0 / 11) | 4.55% | (2 / 44) | |
| Spectrum.js | 2.12% | (11 / 520) | 0% | (0 / 201) | 0% | (0 / 50) | 2.12% | (11 / 520) | |
| StylesPopoverHelper.js | 0.68% | (1 / 148) | 0% | (0 / 40) | 0% | (0 / 22) | 0.68% | (1 / 148) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.BezierEditor = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("elements/bezierEditor.css");
this.contentElement.tabIndex = 0;
// Preview UI
this._previewElement = this.contentElement.createChild("div", "bezier-preview-container");
this._previewElement.createChild("div", "bezier-preview-animation");
this._previewElement.addEventListener("click", this._startPreviewAnimation.bind(this));
this._previewOnion = this.contentElement.createChild("div", "bezier-preview-onion");
this._previewOnion.addEventListener("click", this._startPreviewAnimation.bind(this));
this._outerContainer = this.contentElement.createChild("div", "bezier-container");
// Presets UI
this._presetsContainer = this._outerContainer.createChild("div", "bezier-presets");
this._presetUI = new WebInspector.BezierUI(40, 40, 0, 2, false);
this._presetCategories = [];
for (var i = 0; i < WebInspector.BezierEditor.Presets.length; i++) {
this._presetCategories[i] = this._createCategory(WebInspector.BezierEditor.Presets[i]);
this._presetsContainer.appendChild(this._presetCategories[i].icon);
}
// Curve UI
this._curveUI = new WebInspector.BezierUI(150, 250, 50, 7, true);
this._curve = this._outerContainer.createSVGChild("svg", "bezier-curve");
WebInspector.installDragHandle(this._curve, this._dragStart.bind(this), this._dragMove.bind(this), this._dragEnd.bind(this), "default");
this._header = this.contentElement.createChild("div", "bezier-header");
var minus = this._createPresetModifyIcon(this._header, "bezier-preset-minus", "M 12 6 L 8 10 L 12 14");
var plus = this._createPresetModifyIcon(this._header, "bezier-preset-plus", "M 8 6 L 12 10 L 8 14");
minus.addEventListener("click", this._presetModifyClicked.bind(this, false));
plus.addEventListener("click", this._presetModifyClicked.bind(this, true));
this._label = this._header.createChild("span", "source-code bezier-display-value");
}
WebInspector.BezierEditor.Events = {
BezierChanged: "BezierChanged"
}
WebInspector.BezierEditor.Presets = [
[
{ name: "ease-in-out", value: "ease-in-out" },
{ name: "In Out · Sine", value: "cubic-bezier(0.45, 0.05, 0.55, 0.95)" },
{ name: "In Out · Quadratic", value: "cubic-bezier(0.46, 0.03, 0.52, 0.96)" },
{ name: "In Out · Cubic", value: "cubic-bezier(0.65, 0.05, 0.36, 1)" },
{ name: "Fast Out, Slow In", value: "cubic-bezier(0.4, 0, 0.2, 1)" },
{ name: "In Out · Back", value: "cubic-bezier(0.68, -0.55, 0.27, 1.55)" }
],
[
{ name: "Fast Out, Linear In", value: "cubic-bezier(0.4, 0, 1, 1)" },
{ name: "ease-in", value: "ease-in" },
{ name: "In · Sine", value: "cubic-bezier(0.47, 0, 0.75, 0.72)" },
{ name: "In · Quadratic", value: "cubic-bezier(0.55, 0.09, 0.68, 0.53)" },
{ name: "In · Cubic", value: "cubic-bezier(0.55, 0.06, 0.68, 0.19)" },
{ name: "In · Back", value: "cubic-bezier(0.6, -0.28, 0.74, 0.05)" }
],
[
{ name: "ease-out", value: "ease-out" },
{ name: "Out · Sine", value: "cubic-bezier(0.39, 0.58, 0.57, 1)" },
{ name: "Out · Quadratic", value: "cubic-bezier(0.25, 0.46, 0.45, 0.94)" },
{ name: "Out · Cubic", value: "cubic-bezier(0.22, 0.61, 0.36, 1)" },
{ name: "Linear Out, Slow In", value: "cubic-bezier(0, 0, 0.2, 1)" },
{ name: "Out · Back", value: "cubic-bezier(0.18, 0.89, 0.32, 1.28)" }
]
]
/** @typedef {{presets: !Array.<{name: string, value: string}>, icon: !Element, presetIndex: number}} */
WebInspector.BezierEditor.PresetCategory;
WebInspector.BezierEditor.prototype = {
/**
* @param {?WebInspector.Geometry.CubicBezier} bezier
*/
setBezier: function(bezier)
{
if (!bezier)
return;
this._bezier = bezier;
this._updateUI();
},
/**
* @return {!WebInspector.Geometry.CubicBezier}
*/
bezier: function()
{
return this._bezier;
},
wasShown: function()
{
this._unselectPresets();
// Check if bezier matches a preset
for (var category of this._presetCategories) {
for (var i = 0; i < category.presets.length; i++) {
if (this._bezier.asCSSText() === category.presets[i].value) {
category.presetIndex = i;
this._presetCategorySelected(category);
}
}
}
this._updateUI();
this._startPreviewAnimation();
},
_onchange: function()
{
this._updateUI();
this.dispatchEventToListeners(WebInspector.BezierEditor.Events.BezierChanged, this._bezier.asCSSText());
},
_updateUI: function()
{
var labelText = this._selectedCategory ? this._selectedCategory.presets[this._selectedCategory.presetIndex].name : this._bezier.asCSSText().replace(/\s(-\d\.\d)/g, "$1");
this._label.textContent = WebInspector.UIString(labelText);
this._curveUI.drawCurve(this._bezier, this._curve);
this._previewOnion.removeChildren();
},
/**
* @param {!Event} event
* @return {boolean}
*/
_dragStart: function(event)
{
this._mouseDownPosition = new WebInspector.Geometry.Point(event.x, event.y);
var ui = this._curveUI;
this._controlPosition = new WebInspector.Geometry.Point(
Number.constrain((event.offsetX - ui.radius) / ui.curveWidth(), 0, 1),
(ui.curveHeight() + ui.marginTop + ui.radius - event.offsetY) / ui.curveHeight());
var firstControlPointIsCloser = this._controlPosition.distanceTo(this._bezier.controlPoints[0]) < this._controlPosition.distanceTo(this._bezier.controlPoints[1]);
this._selectedPoint = firstControlPointIsCloser ? 0 : 1;
this._bezier.controlPoints[this._selectedPoint] = this._controlPosition;
this._unselectPresets();
this._onchange();
event.consume(true);
return true;
},
/**
* @param {number} mouseX
* @param {number} mouseY
*/
_updateControlPosition: function(mouseX, mouseY)
{
var deltaX = (mouseX - this._mouseDownPosition.x) / this._curveUI.curveWidth();
var deltaY = (mouseY - this._mouseDownPosition.y) / this._curveUI.curveHeight();
var newPosition = new WebInspector.Geometry.Point(Number.constrain(this._controlPosition.x + deltaX, 0, 1), this._controlPosition.y - deltaY);
this._bezier.controlPoints[this._selectedPoint] = newPosition;
},
/**
* @param {!Event} event
*/
_dragMove: function(event)
{
this._updateControlPosition(event.x, event.y);
this._onchange();
},
/**
* @param {!Event} event
*/
_dragEnd: function(event)
{
this._updateControlPosition(event.x, event.y);
this._onchange();
this._startPreviewAnimation();
},
/**
* @param {!Array<{name: string, value: string}>} presetGroup
* @return {!WebInspector.BezierEditor.PresetCategory}
*/
_createCategory: function(presetGroup)
{
var presetElement = createElementWithClass("div", "bezier-preset-category");
var iconElement = presetElement.createSVGChild("svg", "bezier-preset monospace");
var category = { presets: presetGroup, presetIndex: 0, icon: presetElement };
this._presetUI.drawCurve(WebInspector.Geometry.CubicBezier.parse(category.presets[0].value), iconElement);
iconElement.addEventListener("click", this._presetCategorySelected.bind(this, category));
return category;
},
/**
* @param {!Element} parentElement
* @param {string} className
* @param {string} drawPath
* @return {!Element}
*/
_createPresetModifyIcon: function (parentElement, className, drawPath)
{
var icon = parentElement.createSVGChild("svg", "bezier-preset-modify " + className);
icon.setAttribute("width", 20);
icon.setAttribute("height", 20);
var path = icon.createSVGChild("path");
path.setAttribute("d", drawPath);
return icon;
},
_unselectPresets: function()
{
for (var category of this._presetCategories)
category.icon.classList.remove("bezier-preset-selected");
delete this._selectedCategory;
this._header.classList.remove("bezier-header-active");
},
/**
* @param {!WebInspector.BezierEditor.PresetCategory} category
* @param {!Event=} event
*/
_presetCategorySelected: function(category, event)
{
if (this._selectedCategory === category)
return;
this._unselectPresets();
this._header.classList.add("bezier-header-active");
this._selectedCategory = category;
this._selectedCategory.icon.classList.add("bezier-preset-selected");
this.setBezier(WebInspector.Geometry.CubicBezier.parse(category.presets[category.presetIndex].value));
this._onchange();
this._startPreviewAnimation();
if (event)
event.consume(true);
},
/**
* @param {boolean} intensify
* @param {!Event} event
*/
_presetModifyClicked: function(intensify, event)
{
if (!this._selectedCategory)
return;
var length = this._selectedCategory.presets.length;
this._selectedCategory.presetIndex = (this._selectedCategory.presetIndex + (intensify ? 1 : -1) + length) % length;
this.setBezier(WebInspector.Geometry.CubicBezier.parse(this._selectedCategory.presets[this._selectedCategory.presetIndex].value));
this._onchange();
this._startPreviewAnimation();
},
_startPreviewAnimation: function()
{
if (this._previewAnimation)
this._previewAnimation.cancel();
const animationDuration = 1600;
const numberOnionSlices = 20;
var keyframes = [{ offset: 0, transform: "translateX(0px)", easing: this._bezier.asCSSText(), opacity: 1 },
{ offset: 0.9, transform: "translateX(218px)", opacity: 1 },
{ offset: 1, transform: "translateX(218px)", opacity: 0 }];
this._previewAnimation = this._previewElement.animate(keyframes, animationDuration);
this._previewOnion.removeChildren();
for (var i = 0; i <= numberOnionSlices; i++) {
var slice = this._previewOnion.createChild("div", "bezier-preview-animation");
var player = slice.animate([{ transform: "translateX(0px)", easing: this._bezier.asCSSText() }, { transform: "translateX(218px)" }],
{ duration: animationDuration, fill: "forwards" });
player.pause();
player.currentTime = animationDuration * i / numberOnionSlices;
}
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {number} width
* @param {number} height
* @param {number} marginTop
* @param {number} controlPointRadius
* @param {boolean} linearLine
*/
WebInspector.BezierUI = function(width, height, marginTop, controlPointRadius, linearLine)
{
this.width = width;
this.height = height;
this.marginTop = marginTop;
this.radius = controlPointRadius;
this.linearLine = linearLine;
}
WebInspector.BezierUI.prototype = {
/**
* @return {number}
*/
curveWidth: function()
{
return this.width - this.radius * 2;
},
/**
* @return {number}
*/
curveHeight: function()
{
return this.height - this.radius * 2 - this.marginTop * 2;
},
/**
* @param {!Element} parentElement
* @param {string} className
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
*/
_drawLine: function(parentElement, className, x1, y1, x2, y2)
{
var line = parentElement.createSVGChild("line", className);
line.setAttribute("x1", x1 + this.radius);
line.setAttribute("y1", y1 + this.radius + this.marginTop);
line.setAttribute("x2", x2 + this.radius);
line.setAttribute("y2", y2 + this.radius + this.marginTop);
},
/**
* @param {!Element} parentElement
* @param {number} startX
* @param {number} startY
* @param {number} controlX
* @param {number} controlY
*/
_drawControlPoints: function(parentElement, startX, startY, controlX, controlY)
{
this._drawLine(parentElement, "bezier-control-line", startX, startY, controlX, controlY);
var circle = parentElement.createSVGChild("circle", "bezier-control-circle");
circle.setAttribute("cx", controlX + this.radius);
circle.setAttribute("cy", controlY + this.radius + this.marginTop);
circle.setAttribute("r", this.radius);
},
/**
* @param {?WebInspector.Geometry.CubicBezier} bezier
* @param {!Element} svg
*/
drawCurve: function(bezier, svg)
{
if (!bezier)
return;
var width = this.curveWidth();
var height = this.curveHeight();
svg.setAttribute("width", this.width);
svg.setAttribute("height", this.height);
svg.removeChildren();
var group = svg.createSVGChild("g");
if (this.linearLine)
this._drawLine(group, "linear-line", 0, height, width, 0);
var curve = group.createSVGChild("path", "bezier-path");
var curvePoints = [
new WebInspector.Geometry.Point(bezier.controlPoints[0].x * width + this.radius, (1 - bezier.controlPoints[0].y) * height + this.radius + this.marginTop),
new WebInspector.Geometry.Point(bezier.controlPoints[1].x * width + this.radius, (1 - bezier.controlPoints[1].y) * height + this.radius + this.marginTop),
new WebInspector.Geometry.Point(width + this.radius, this.marginTop + this.radius)
];
curve.setAttribute("d", "M" + this.radius + "," + (height + this.radius + this.marginTop) + " C" + curvePoints.join(" "));
this._drawControlPoints(group, 0, height, bezier.controlPoints[0].x * width, (1 - bezier.controlPoints[0].y) * height);
this._drawControlPoints(group, width, 0, bezier.controlPoints[1].x * width, (1 - bezier.controlPoints[1].y) * height);
}
}
WebInspector.BezierUI.Height = 26;
/**
* @param {!WebInspector.Geometry.CubicBezier} bezier
* @param {!Element} path
* @param {number} width
*/
WebInspector.BezierUI.drawVelocityChart = function(bezier, path, width)
{
var height = WebInspector.BezierUI.Height;
var pathBuilder = ["M", 0, height];
/** @const */ var sampleSize = 1 / 40;
var prev = bezier.evaluateAt(0);
for (var t = sampleSize; t < 1 + sampleSize; t += sampleSize) {
var current = bezier.evaluateAt(t);
var slope = (current.y - prev.y) / (current.x - prev.x);
var weightedX = prev.x * (1 - t) + current.x * t;
slope = Math.tanh(slope / 1.5); // Normalise slope
pathBuilder = pathBuilder.concat(["L", (weightedX * width).toFixed(2), (height - slope * height).toFixed(2) ]);
prev = current;
}
pathBuilder = pathBuilder.concat(["L", width.toFixed(2), height, "Z"]);
path.setAttribute("d", pathBuilder.join(" "));
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | 2 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.ElementsPanel.BaseToolbarPaneWidget}
* @param {!WebInspector.ToolbarItem} toolbarItem
*/
WebInspector.ClassesPaneWidget = function(toolbarItem)
{
WebInspector.ElementsPanel.BaseToolbarPaneWidget.call(this, toolbarItem);
this.element.className = "styles-element-classes-pane";
var container = this.element.createChild("div", "title-container");
var input = container.createChild("input", "new-class-input monospace");
input.placeholder = WebInspector.UIString("Add new class");
input.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.setDefaultFocusedElement(input);
this._classesContainer = this.element.createChild("div", "source-code");
this._classesContainer.classList.add("styles-element-classes-container");
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.DOMMutated, this._onDOMMutated, this);
/** @type {!Set<!WebInspector.DOMNode>} */
this._mutatingNodes = new Set();
}
WebInspector.ClassesPaneWidget._classesSymbol = Symbol("WebInspector.ClassesPaneWidget._classesSymbol");
WebInspector.ClassesPaneWidget.prototype = {
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
var text = event.target.value;
if (isEscKey(event)) {
event.target.value = "";
if (!text.isWhitespace())
event.consume(true);
return;
}
if (!isEnterKey(event))
return;
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (!node)
return;
event.target.value = "";
var classNames = text.split(/[.,\s]/);
for (var className of classNames) {
var className = className.trim();
if (!className.length)
continue;
this._toggleClass(node, className, true);
}
this._installNodeClasses(node);
this.update();
event.consume(true);
},
/**
* @param {!WebInspector.Event} event
*/
_onDOMMutated: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */(event.data);
if (this._mutatingNodes.has(node))
return;
delete node[WebInspector.ClassesPaneWidget._classesSymbol];
this.update();
},
/**
* @override
* @return {!Promise.<?>}
*/
doUpdate: function()
{
this._classesContainer.removeChildren();
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (!node)
return Promise.resolve();
var classes = this._nodeClasses(node);
var keys = classes.keysArray();
keys.sort(String.caseInsensetiveComparator);
for (var i = 0; i < keys.length; ++i) {
var className = keys[i];
var label = createCheckboxLabel(className, classes.get(className));
label.classList.add("monospace");
label.checkboxElement.addEventListener("click", this._onClick.bind(this, className), false);
this._classesContainer.appendChild(label);
}
return Promise.resolve();
},
/**
* @param {string} className
* @param {!Event} event
*/
_onClick: function(className, event)
{
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (!node)
return;
var enabled = event.target.checked;
this._toggleClass(node, className, enabled);
this._installNodeClasses(node);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!Map<string, boolean>}
*/
_nodeClasses: function(node)
{
var result = node[WebInspector.ClassesPaneWidget._classesSymbol];
if (!result) {
var classAttribute = node.getAttribute("class") || "";
var classes = classAttribute.split(/\s/);
result = new Map();
for (var i = 0; i < classes.length; ++i) {
var className = classes[i].trim();
if (!className.length)
continue;
result.set(className, true);
}
node[WebInspector.ClassesPaneWidget._classesSymbol] = result;
}
return result;
},
/**
* @param {!WebInspector.DOMNode} node
* @param {string} className
* @param {boolean} enabled
*/
_toggleClass: function(node, className, enabled)
{
var classes = this._nodeClasses(node);
classes.set(className, enabled);
},
/**
* @param {!WebInspector.DOMNode} node
*/
_installNodeClasses: function(node)
{
var classes = this._nodeClasses(node);
var activeClasses = new Set();
for (var className of classes.keys()) {
if (classes.get(className))
activeClasses.add(className);
}
var newClasses = activeClasses.valuesArray();
newClasses.sort();
this._mutatingNodes.add(node);
node.setAttributeValue("class", newClasses.join(" "), onClassNameUpdated.bind(this));
/**
* @this {WebInspector.ClassesPaneWidget}
*/
function onClassNameUpdated()
{
this._mutatingNodes.delete(node);
}
},
/**
* @override
* @param {?WebInspector.DOMNode} newNode
*/
onNodeChanged: function(newNode)
{
this.update();
},
__proto__: WebInspector.ElementsPanel.BaseToolbarPaneWidget.prototype
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.ClassesPaneWidget.ButtonProvider = function()
{
this._button = new WebInspector.ToolbarToggle(WebInspector.UIString("Element Classes"), "");
this._button.setText(".cls");
this._button.element.classList.add("monospace");
this._button.addEventListener("click", this._clicked, this);
this._view = new WebInspector.ClassesPaneWidget(this.item());
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
this._nodeChanged();
}
WebInspector.ClassesPaneWidget.ButtonProvider.prototype = {
_clicked: function()
{
WebInspector.ElementsPanel.instance().showToolbarPane(!this._view.isShowing() ? this._view : null);
},
/**
* @override
* @return {!WebInspector.ToolbarItem}
*/
item: function()
{
return this._button;
},
_nodeChanged: function()
{
var node = WebInspector.context.flavor(WebInspector.DOMNode);
var enabled = !!node;
this._button.setEnabled(enabled);
if (!enabled && this._button.toggled())
WebInspector.ElementsPanel.instance().showToolbarPane(null);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | 2 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
* @param {!WebInspector.StylesSidebarPane} stylesSidebarPane
* @param {!WebInspector.SharedSidebarModel} sharedModel
* @param {function(!WebInspector.CSSProperty)} revealCallback
*/
WebInspector.ComputedStyleWidget = function(stylesSidebarPane, sharedModel, revealCallback)
{
WebInspector.ThrottledWidget.call(this);
this.element.classList.add("computed-style-sidebar-pane");
this.registerRequiredCSS("elements/computedStyleSidebarPane.css");
this._alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
this._sharedModel = sharedModel;
this._sharedModel.addEventListener(WebInspector.SharedSidebarModel.Events.ComputedStyleChanged, this.update, this);
this._showInheritedComputedStylePropertiesSetting = WebInspector.settings.createSetting("showInheritedComputedStyleProperties", false);
this._showInheritedComputedStylePropertiesSetting.addChangeListener(this._showInheritedComputedStyleChanged.bind(this));
var hbox = this.element.createChild("div", "hbox styles-sidebar-pane-toolbar");
var filterContainerElement = hbox.createChild("div", "styles-sidebar-pane-filter-box");
var filterInput = WebInspector.StylesSidebarPane.createPropertyFilterElement(WebInspector.UIString("Filter"), hbox, filterCallback.bind(this));
filterContainerElement.appendChild(filterInput);
var toolbar = new WebInspector.Toolbar("styles-pane-toolbar", hbox);
toolbar.appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Show all"), undefined, this._showInheritedComputedStylePropertiesSetting));
this._propertiesOutline = new TreeOutlineInShadow();
this._propertiesOutline.hideOverflow();
this._propertiesOutline.registerRequiredCSS("elements/computedStyleSidebarPane.css");
this._propertiesOutline.element.classList.add("monospace", "computed-properties");
this.element.appendChild(this._propertiesOutline.element);
this._stylesSidebarPane = stylesSidebarPane;
this._linkifier = new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultCSSFormatter());
this._revealCallback = revealCallback;
/**
* @param {?RegExp} regex
* @this {WebInspector.ComputedStyleWidget}
*/
function filterCallback(regex)
{
this._filterRegex = regex;
this._updateFilter(regex);
}
}
/**
* @param {!WebInspector.StylesSidebarPane} stylesSidebarPane
* @param {!WebInspector.SharedSidebarModel} sharedModel
* @param {function(!WebInspector.CSSProperty)} revealCallback
* @return {!WebInspector.ElementsSidebarViewWrapperPane}
*/
WebInspector.ComputedStyleWidget.createSidebarWrapper = function(stylesSidebarPane, sharedModel, revealCallback)
{
var widget = new WebInspector.ComputedStyleWidget(stylesSidebarPane, sharedModel, revealCallback);
return new WebInspector.ElementsSidebarViewWrapperPane(WebInspector.UIString("Computed Style"), widget)
}
WebInspector.ComputedStyleWidget._propertySymbol = Symbol("property");
WebInspector.ComputedStyleWidget.prototype = {
_showInheritedComputedStyleChanged: function()
{
this.update();
},
/**
* @override
* @return {!Promise.<?>}
*/
doUpdate: function()
{
var promises = [
this._sharedModel.fetchComputedStyle(),
this._stylesSidebarPane.fetchMatchedCascade()
];
return Promise.all(promises)
.spread(this._innerRebuildUpdate.bind(this));
},
/**
* @param {string} text
* @return {!Node}
*/
_processColor: function(text)
{
var color = WebInspector.Color.parse(text);
if (!color)
return createTextNode(text);
var swatch = WebInspector.ColorSwatch.create();
swatch.setColorText(text);
swatch.setFormat(WebInspector.Color.detectColorFormat(color));
return swatch;
},
/**
* @param {?WebInspector.SharedSidebarModel.ComputedStyle} nodeStyle
* @param {?WebInspector.CSSMatchedStyles} matchedStyles
*/
_innerRebuildUpdate: function(nodeStyle, matchedStyles)
{
this._propertiesOutline.removeChildren();
this._linkifier.reset();
var cssModel = this._sharedModel.cssModel();
if (!nodeStyle || !matchedStyles || !cssModel)
return;
var uniqueProperties = nodeStyle.computedStyle.keysArray();
uniqueProperties.sort(propertySorter);
var propertyTraces = this._computePropertyTraces(matchedStyles);
var inhertiedProperties = this._computeInheritedProperties(matchedStyles);
var showInherited = this._showInheritedComputedStylePropertiesSetting.get();
for (var i = 0; i < uniqueProperties.length; ++i) {
var propertyName = uniqueProperties[i];
var propertyValue = nodeStyle.computedStyle.get(propertyName);
var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(propertyName);
var inherited = !inhertiedProperties.has(canonicalName);
if (!showInherited && inherited && !(propertyName in this._alwaysShowComputedProperties))
continue;
if (propertyName !== canonicalName && propertyValue === nodeStyle.computedStyle.get(canonicalName))
continue;
var propertyElement = createElement("div");
propertyElement.classList.add("computed-style-property");
propertyElement.classList.toggle("computed-style-property-inherited", inherited);
var renderer = new WebInspector.StylesSidebarPropertyRenderer(null, nodeStyle.node, propertyName, /** @type {string} */(propertyValue));
renderer.setColorHandler(this._processColor.bind(this));
var propertyNameElement = renderer.renderName();
propertyNameElement.classList.add("property-name");
propertyElement.appendChild(propertyNameElement);
var colon = createElementWithClass("span", "delimeter");
colon.textContent = ":";
propertyNameElement.appendChild(colon);
var propertyValueElement = propertyElement.createChild("span", "property-value");
var propertyValueText = renderer.renderValue();
propertyValueText.classList.add("property-value-text");
propertyValueElement.appendChild(propertyValueText);
var semicolon = createElementWithClass("span", "delimeter");
semicolon.textContent = ";";
propertyValueElement.appendChild(semicolon);
var treeElement = new TreeElement();
treeElement.selectable = false;
treeElement.title = propertyElement;
treeElement[WebInspector.ComputedStyleWidget._propertySymbol] = {
name: propertyName,
value: propertyValue
};
var isOdd = this._propertiesOutline.rootElement().children().length % 2 === 0;
treeElement.listItemElement.classList.toggle("odd-row", isOdd);
this._propertiesOutline.appendChild(treeElement);
var trace = propertyTraces.get(propertyName);
if (trace) {
var activeProperty = this._renderPropertyTrace(cssModel, matchedStyles, nodeStyle.node, treeElement, trace);
treeElement.listItemElement.addEventListener("mousedown", consumeEvent, false);
treeElement.listItemElement.addEventListener("dblclick", consumeEvent, false);
treeElement.listItemElement.addEventListener("click", handleClick.bind(null, treeElement), false);
var gotoSourceElement = propertyValueElement.createChild("div", "goto-source-icon");
gotoSourceElement.addEventListener("click", this._navigateToSource.bind(this, activeProperty));
}
}
this._updateFilter(this._filterRegex);
/**
* @param {string} a
* @param {string} b
* @return {number}
*/
function propertySorter(a, b)
{
if (a.startsWith("-webkit") ^ b.startsWith("-webkit"))
return a.startsWith("-webkit") ? 1 : -1;
var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName;
return canonicalName(a).compareTo(canonicalName(b));
}
/**
* @param {!TreeElement} treeElement
* @param {!Event} event
*/
function handleClick(treeElement, event)
{
if (!treeElement.expanded)
treeElement.expand();
else
treeElement.collapse();
consumeEvent(event);
}
},
/**
* @param {!WebInspector.CSSProperty} cssProperty
* @param {!Event} event
*/
_navigateToSource: function(cssProperty, event)
{
if (this._revealCallback)
this._revealCallback.call(null, cssProperty);
event.consume(true);
},
/**
* @param {!WebInspector.CSSModel} cssModel
* @param {!WebInspector.CSSMatchedStyles} matchedStyles
* @param {!WebInspector.DOMNode} node
* @param {!TreeElement} rootTreeElement
* @param {!Array<!WebInspector.CSSProperty>} tracedProperties
* @return {!WebInspector.CSSProperty}
*/
_renderPropertyTrace: function(cssModel, matchedStyles, node, rootTreeElement, tracedProperties)
{
var activeProperty = null;
for (var property of tracedProperties) {
var trace = createElement("div");
trace.classList.add("property-trace");
if (matchedStyles.propertyState(property) === WebInspector.CSSMatchedStyles.PropertyState.Overloaded)
trace.classList.add("property-trace-inactive");
else
activeProperty = property;
var renderer = new WebInspector.StylesSidebarPropertyRenderer(null, node, property.name, /** @type {string} */(property.value));
renderer.setColorHandler(this._processColor.bind(this));
var valueElement = renderer.renderValue();
valueElement.classList.add("property-trace-value");
valueElement.addEventListener("click", this._navigateToSource.bind(this, property), false);
var gotoSourceElement = createElement("div");
gotoSourceElement.classList.add("goto-source-icon");
gotoSourceElement.addEventListener("click", this._navigateToSource.bind(this, property));
valueElement.insertBefore(gotoSourceElement, valueElement.firstChild);
trace.appendChild(valueElement);
var rule = property.ownerStyle.parentRule;
if (rule) {
var linkSpan = trace.createChild("span", "trace-link");
linkSpan.appendChild(WebInspector.StylePropertiesSection.createRuleOriginNode(matchedStyles, this._linkifier, rule));
}
var selectorElement = trace.createChild("span", "property-trace-selector");
selectorElement.textContent = rule ? rule.selectorText() : "element.style";
selectorElement.title = selectorElement.textContent;
var traceTreeElement = new TreeElement();
traceTreeElement.title = trace;
traceTreeElement.selectable = false;
rootTreeElement.appendChild(traceTreeElement);
}
return /** @type {!WebInspector.CSSProperty} */(activeProperty);
},
/**
* @param {!WebInspector.CSSMatchedStyles} matchedStyles
* @return {!Map<string, !Array<!WebInspector.CSSProperty>>}
*/
_computePropertyTraces: function(matchedStyles)
{
var result = new Map();
for (var style of matchedStyles.nodeStyles()) {
var allProperties = style.allProperties;
for (var property of allProperties) {
if (!property.activeInStyle() || !matchedStyles.propertyState(property))
continue;
if (!result.has(property.name))
result.set(property.name, []);
result.get(property.name).push(property);
}
}
return result;
},
/**
* @param {!WebInspector.CSSMatchedStyles} matchedStyles
* @return {!Set<string>}
*/
_computeInheritedProperties: function(matchedStyles)
{
var result = new Set();
for (var style of matchedStyles.nodeStyles()) {
for (var property of style.allProperties) {
if (!matchedStyles.propertyState(property))
continue;
result.add(WebInspector.CSSMetadata.canonicalPropertyName(property.name));
}
}
return result;
},
/**
* @param {?RegExp} regex
*/
_updateFilter: function(regex)
{
var children = this._propertiesOutline.rootElement().children();
for (var child of children) {
var property = child[WebInspector.ComputedStyleWidget._propertySymbol];
var matched = !regex || regex.test(property.name) || regex.test(property.value);
child.hidden = !matched;
}
},
__proto__: WebInspector.ThrottledWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.ElementsPanel.BaseToolbarPaneWidget}
* @param {!WebInspector.ToolbarItem} toolbarItem
*/
WebInspector.ElementStatePaneWidget = function(toolbarItem)
{
WebInspector.ElementsPanel.BaseToolbarPaneWidget.call(this, toolbarItem);
this.element.className = "styles-element-state-pane";
this.element.createChild("div").createTextChild(WebInspector.UIString("Force element state"));
var table = createElementWithClass("table", "source-code");
var inputs = [];
this._inputs = inputs;
/**
* @param {!Event} event
*/
function clickListener(event)
{
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (!node)
return;
WebInspector.CSSModel.fromNode(node).forcePseudoState(node, event.target.state, event.target.checked);
}
/**
* @param {string} state
* @return {!Element}
*/
function createCheckbox(state)
{
var td = createElement("td");
var label = createCheckboxLabel(":" + state);
var input = label.checkboxElement;
input.state = state;
input.addEventListener("click", clickListener, false);
inputs.push(input);
td.appendChild(label);
return td;
}
var tr = table.createChild("tr");
tr.appendChild(createCheckbox.call(null, "active"));
tr.appendChild(createCheckbox.call(null, "hover"));
tr = table.createChild("tr");
tr.appendChild(createCheckbox.call(null, "focus"));
tr.appendChild(createCheckbox.call(null, "visited"));
this.element.appendChild(table);
}
WebInspector.ElementStatePaneWidget.prototype = {
/**
* @param {?WebInspector.Target} target
*/
_updateTarget: function(target)
{
if (this._target === target)
return;
if (this._target) {
var cssModel = WebInspector.CSSModel.fromTarget(this._target);
cssModel.removeEventListener(WebInspector.CSSModel.Events.PseudoStateForced, this._pseudoStateForced, this)
}
this._target = target;
if (target) {
var cssModel = WebInspector.CSSModel.fromTarget(target);
cssModel.addEventListener(WebInspector.CSSModel.Events.PseudoStateForced, this._pseudoStateForced, this)
}
},
/**
* @param {!WebInspector.Event} event
*/
_pseudoStateForced: function(event)
{
this.update();
},
/**
* @override
* @param {?WebInspector.DOMNode} newNode
*/
onNodeChanged: function(newNode)
{
this._updateTarget(newNode? newNode.target() : null);
this.update();
},
/**
* @override
* @return {!Promise.<?>}
*/
doUpdate: function()
{
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (node) {
var nodePseudoState = WebInspector.CSSModel.fromNode(node).pseudoState(node);
for (var input of this._inputs) {
input.disabled = !!node.pseudoType();
input.checked = nodePseudoState.indexOf(input.state) >= 0;
}
} else {
for (var input of this._inputs) {
input.disabled = true;
input.checked = false;
}
}
return Promise.resolve();
},
__proto__: WebInspector.ElementsPanel.BaseToolbarPaneWidget.prototype
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.ElementStatePaneWidget.ButtonProvider = function()
{
this._button = new WebInspector.ToolbarToggle(WebInspector.UIString("Toggle Element State"), "", WebInspector.UIString(":hov"));
this._button.addEventListener("click", this._clicked, this);
this._button.element.classList.add("monospace");
this._view = new WebInspector.ElementStatePaneWidget(this.item());
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
this._nodeChanged();
}
WebInspector.ElementStatePaneWidget.ButtonProvider.prototype = {
_clicked: function()
{
WebInspector.ElementsPanel.instance().showToolbarPane(!this._view.isShowing() ? this._view : null);
},
/**
* @override
* @return {!WebInspector.ToolbarItem}
*/
item: function()
{
return this._button;
},
_nodeChanged: function()
{
var enabled = !!WebInspector.context.flavor(WebInspector.DOMNode);
this._button.setEnabled(enabled);
if (!enabled && this._button.toggled())
WebInspector.ElementsPanel.instance().showToolbarPane(null);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | 2 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.HBox}
*/
WebInspector.ElementsBreadcrumbs = function()
{
WebInspector.HBox.call(this, true);
this.registerRequiredCSS("elements/breadcrumbs.css");
this.crumbsElement = this.contentElement.createChild("div", "crumbs");
this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bind(this), false);
this.crumbsElement.addEventListener("mouseleave", this._mouseMovedOutOfCrumbs.bind(this), false);
this._nodeSymbol = Symbol("node");
}
/** @enum {string} */
WebInspector.ElementsBreadcrumbs.Events = {
NodeSelected: "NodeSelected"
}
WebInspector.ElementsBreadcrumbs.prototype = {
wasShown: function()
{
this.update();
},
/**
* @param {!Array.<!WebInspector.DOMNode>} nodes
*/
updateNodes: function(nodes)
{
if (!nodes.length)
return;
var crumbs = this.crumbsElement;
for (var crumb = crumbs.firstChild; crumb; crumb = crumb.nextSibling) {
if (nodes.indexOf(crumb[this._nodeSymbol]) !== -1) {
this.update(true);
return;
}
}
},
/**
* @param {?WebInspector.DOMNode} node
*/
setSelectedNode: function(node)
{
this._currentDOMNode = node;
this.update();
},
_mouseMovedInCrumbs: function(event)
{
var nodeUnderMouse = event.target;
var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb");
var node = /** @type {?WebInspector.DOMNode} */ (crumbElement ? crumbElement[this._nodeSymbol] : null);
if (node)
node.highlight();
},
_mouseMovedOutOfCrumbs: function(event)
{
if (this._currentDOMNode)
WebInspector.DOMModel.hideDOMNodeHighlight();
},
/**
* @param {boolean=} force
*/
update: function(force)
{
if (!this.isShowing())
return;
var currentDOMNode = this._currentDOMNode;
var crumbs = this.crumbsElement;
var handled = false;
var crumb = crumbs.firstChild;
while (crumb) {
if (crumb[this._nodeSymbol] === currentDOMNode) {
crumb.classList.add("selected");
handled = true;
} else {
crumb.classList.remove("selected");
}
crumb = crumb.nextSibling;
}
if (handled && !force) {
// We don't need to rebuild the crumbs, but we need to adjust sizes
// to reflect the new focused or root node.
this.updateSizes();
return;
}
crumbs.removeChildren();
var panel = this;
/**
* @param {!Event} event
* @this {WebInspector.ElementsBreadcrumbs}
*/
function selectCrumb(event)
{
event.preventDefault();
var crumb = /** @type {!Element} */ (event.currentTarget);
if (!crumb.classList.contains("collapsed")) {
this.dispatchEventToListeners(WebInspector.ElementsBreadcrumbs.Events.NodeSelected, crumb[this._nodeSymbol]);
return;
}
// Clicking a collapsed crumb will expose the hidden crumbs.
if (crumb === panel.crumbsElement.firstChild) {
// If the focused crumb is the first child, pick the farthest crumb
// that is still hidden. This allows the user to expose every crumb.
var currentCrumb = crumb;
while (currentCrumb) {
var hidden = currentCrumb.classList.contains("hidden");
var collapsed = currentCrumb.classList.contains("collapsed");
if (!hidden && !collapsed)
break;
crumb = currentCrumb;
currentCrumb = currentCrumb.nextSiblingElement;
}
}
this.updateSizes(crumb);
}
var boundSelectCrumb = selectCrumb.bind(this);
for (var current = currentDOMNode; current; current = current.parentNode) {
if (current.nodeType() === Node.DOCUMENT_NODE)
continue;
crumb = createElementWithClass("span", "crumb");
crumb[this._nodeSymbol] = current;
crumb.addEventListener("mousedown", boundSelectCrumb, false);
var crumbTitle = "";
switch (current.nodeType()) {
case Node.ELEMENT_NODE:
if (current.pseudoType())
crumbTitle = "::" + current.pseudoType();
else
WebInspector.DOMPresentationUtils.decorateNodeLabel(current, crumb);
break;
case Node.TEXT_NODE:
crumbTitle = WebInspector.UIString("(text)");
break;
case Node.COMMENT_NODE:
crumbTitle = "<!-->";
break;
case Node.DOCUMENT_TYPE_NODE:
crumbTitle = "<!DOCTYPE>";
break;
case Node.DOCUMENT_FRAGMENT_NODE:
crumbTitle = current.shadowRootType() ? "#shadow-root" : current.nodeNameInCorrectCase();
break;
default:
crumbTitle = current.nodeNameInCorrectCase();
}
if (!crumb.childNodes.length) {
var nameElement = createElement("span");
nameElement.textContent = crumbTitle;
crumb.appendChild(nameElement);
crumb.title = crumbTitle;
}
if (current === currentDOMNode)
crumb.classList.add("selected");
crumbs.insertBefore(crumb, crumbs.firstChild);
}
this.updateSizes();
},
/**
* @param {!Element=} focusedCrumb
*/
updateSizes: function(focusedCrumb)
{
if (!this.isShowing())
return;
var crumbs = this.crumbsElement;
if (!crumbs.firstChild)
return;
var selectedIndex = 0;
var focusedIndex = 0;
var selectedCrumb;
// Reset crumb styles.
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.children[i];
// Find the selected crumb and index.
if (!selectedCrumb && crumb.classList.contains("selected")) {
selectedCrumb = crumb;
selectedIndex = i;
}
// Find the focused crumb index.
if (crumb === focusedCrumb)
focusedIndex = i;
crumb.classList.remove("compact", "collapsed", "hidden");
}
// Layout 1: Measure total and normal crumb sizes
var contentElementWidth = this.contentElement.offsetWidth;
var normalSizes = [];
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.childNodes[i];
normalSizes[i] = crumb.offsetWidth;
}
// Layout 2: Measure collapsed crumb sizes
var compactSizes = [];
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.childNodes[i];
crumb.classList.add("compact");
}
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.childNodes[i];
compactSizes[i] = crumb.offsetWidth;
}
// Layout 3: Measure collapsed crumb size
crumbs.firstChild.classList.add("collapsed");
var collapsedSize = crumbs.firstChild.offsetWidth;
// Clean up.
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.childNodes[i];
crumb.classList.remove("compact", "collapsed");
}
function crumbsAreSmallerThanContainer()
{
var totalSize = 0;
for (var i = 0; i < crumbs.childNodes.length; ++i) {
var crumb = crumbs.childNodes[i];
if (crumb.classList.contains("hidden"))
continue;
if (crumb.classList.contains("collapsed")) {
totalSize += collapsedSize;
continue;
}
totalSize += crumb.classList.contains("compact") ? compactSizes[i] : normalSizes[i];
}
const rightPadding = 10;
return totalSize + rightPadding < contentElementWidth;
}
if (crumbsAreSmallerThanContainer())
return; // No need to compact the crumbs, they all fit at full size.
var BothSides = 0;
var AncestorSide = -1;
var ChildSide = 1;
/**
* @param {function(!Element)} shrinkingFunction
* @param {number} direction
*/
function makeCrumbsSmaller(shrinkingFunction, direction)
{
var significantCrumb = focusedCrumb || selectedCrumb;
var significantIndex = significantCrumb === selectedCrumb ? selectedIndex : focusedIndex;
function shrinkCrumbAtIndex(index)
{
var shrinkCrumb = crumbs.children[index];
if (shrinkCrumb && shrinkCrumb !== significantCrumb)
shrinkingFunction(shrinkCrumb);
if (crumbsAreSmallerThanContainer())
return true; // No need to compact the crumbs more.
return false;
}
// Shrink crumbs one at a time by applying the shrinkingFunction until the crumbs
// fit in the container or we run out of crumbs to shrink.
if (direction) {
// Crumbs are shrunk on only one side (based on direction) of the signifcant crumb.
var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
while (index !== significantIndex) {
if (shrinkCrumbAtIndex(index))
return true;
index += (direction > 0 ? 1 : -1);
}
} else {
// Crumbs are shrunk in order of descending distance from the signifcant crumb,
// with a tie going to child crumbs.
var startIndex = 0;
var endIndex = crumbs.childNodes.length - 1;
while (startIndex != significantIndex || endIndex != significantIndex) {
var startDistance = significantIndex - startIndex;
var endDistance = endIndex - significantIndex;
if (startDistance >= endDistance)
var index = startIndex++;
else
var index = endIndex--;
if (shrinkCrumbAtIndex(index))
return true;
}
}
// We are not small enough yet, return false so the caller knows.
return false;
}
function coalesceCollapsedCrumbs()
{
var crumb = crumbs.firstChild;
var collapsedRun = false;
var newStartNeeded = false;
var newEndNeeded = false;
while (crumb) {
var hidden = crumb.classList.contains("hidden");
if (!hidden) {
var collapsed = crumb.classList.contains("collapsed");
if (collapsedRun && collapsed) {
crumb.classList.add("hidden");
crumb.classList.remove("compact");
crumb.classList.remove("collapsed");
if (crumb.classList.contains("start")) {
crumb.classList.remove("start");
newStartNeeded = true;
}
if (crumb.classList.contains("end")) {
crumb.classList.remove("end");
newEndNeeded = true;
}
continue;
}
collapsedRun = collapsed;
if (newEndNeeded) {
newEndNeeded = false;
crumb.classList.add("end");
}
} else {
collapsedRun = true;
}
crumb = crumb.nextSibling;
}
if (newStartNeeded) {
crumb = crumbs.lastChild;
while (crumb) {
if (!crumb.classList.contains("hidden")) {
crumb.classList.add("start");
break;
}
crumb = crumb.previousSibling;
}
}
}
/**
* @param {!Element} crumb
*/
function compact(crumb)
{
if (crumb.classList.contains("hidden"))
return;
crumb.classList.add("compact");
}
/**
* @param {!Element} crumb
* @param {boolean=} dontCoalesce
*/
function collapse(crumb, dontCoalesce)
{
if (crumb.classList.contains("hidden"))
return;
crumb.classList.add("collapsed");
crumb.classList.remove("compact");
if (!dontCoalesce)
coalesceCollapsedCrumbs();
}
if (!focusedCrumb) {
// When not focused on a crumb we can be biased and collapse less important
// crumbs that the user might not care much about.
// Compact child crumbs.
if (makeCrumbsSmaller(compact, ChildSide))
return;
// Collapse child crumbs.
if (makeCrumbsSmaller(collapse, ChildSide))
return;
}
// Compact ancestor crumbs, or from both sides if focused.
if (makeCrumbsSmaller(compact, focusedCrumb ? BothSides : AncestorSide))
return;
// Collapse ancestor crumbs, or from both sides if focused.
if (makeCrumbsSmaller(collapse, focusedCrumb ? BothSides : AncestorSide))
return;
if (!selectedCrumb)
return;
// Compact the selected crumb.
compact(selectedCrumb);
if (crumbsAreSmallerThanContainer())
return;
// Collapse the selected crumb as a last resort. Pass true to prevent coalescing.
collapse(selectedCrumb, true);
},
__proto__: WebInspector.HBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | 2 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.Searchable}
* @implements {WebInspector.TargetManager.Observer}
* @extends {WebInspector.Panel}
*/
WebInspector.ElementsPanel = function()
{
WebInspector.Panel.call(this, "elements");
this.registerRequiredCSS("elements/elementsPanel.css");
this._splitWidget = new WebInspector.SplitWidget(true, true, "elementsPanelSplitViewState", 325, 325);
this._splitWidget.addEventListener(WebInspector.SplitWidget.Events.SidebarSizeChanged, this._updateTreeOutlineVisibleWidth.bind(this));
this._splitWidget.show(this.element);
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.setMinimumSize(25, 28);
this._searchableView.setPlaceholder(WebInspector.UIString("Find by string, selector, or XPath"));
var stackElement = this._searchableView.element;
this._contentElement = createElement("div");
var crumbsContainer = createElement("div");
stackElement.appendChild(this._contentElement);
stackElement.appendChild(crumbsContainer);
this._splitWidget.setMainWidget(this._searchableView);
this._contentElement.id = "elements-content";
// FIXME: crbug.com/425984
if (WebInspector.moduleSetting("domWordWrap").get())
this._contentElement.classList.add("elements-wrap");
WebInspector.moduleSetting("domWordWrap").addChangeListener(this._domWordWrapSettingChanged.bind(this));
crumbsContainer.id = "elements-crumbs";
this._breadcrumbs = new WebInspector.ElementsBreadcrumbs();
this._breadcrumbs.show(crumbsContainer);
this._breadcrumbs.addEventListener(WebInspector.ElementsBreadcrumbs.Events.NodeSelected, this._crumbNodeSelected, this);
this.sidebarPanes = {};
/** @type !Array<!WebInspector.ElementsSidebarViewWrapperPane> */
this._elementsSidebarViewWrappers = [];
this._currentToolbarPane = null;
var sharedSidebarModel = new WebInspector.SharedSidebarModel();
this.sidebarPanes.platformFonts = WebInspector.PlatformFontsWidget.createSidebarWrapper(sharedSidebarModel);
this.sidebarPanes.styles = new WebInspector.StylesSidebarPane();
this.sidebarPanes.computedStyle = WebInspector.ComputedStyleWidget.createSidebarWrapper(this.sidebarPanes.styles, sharedSidebarModel, this._revealProperty.bind(this));
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = WebInspector.PropertiesWidget.createSidebarWrapper();
this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
this.sidebarPanes.eventListeners = WebInspector.EventListenersWidget.createSidebarWrapper();
this._stylesSidebarToolbar = this._createStylesSidebarToolbar(this.sidebarPanes.styles);
WebInspector.moduleSetting("sidebarPosition").addChangeListener(this._updateSidebarPosition.bind(this));
this._updateSidebarPosition();
this._loadSidebarViews();
/** @type {!Array.<!WebInspector.ElementsTreeOutline>} */
this._treeOutlines = [];
/** @type {!Map.<!WebInspector.DOMModel, !WebInspector.ElementsTreeOutline>} */
this._modelToTreeOutline = new Map();
WebInspector.targetManager.observeTargets(this);
WebInspector.moduleSetting("showUAShadowDOM").addChangeListener(this._showUAShadowDOMChanged.bind(this));
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this);
WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
}
WebInspector.ElementsPanel._elementsSidebarViewTitleSymbol = Symbol("title");
WebInspector.ElementsPanel.prototype = {
/**
* @param {!WebInspector.CSSProperty} cssProperty
*/
_revealProperty: function(cssProperty)
{
var stylesSidebarPane = this.sidebarPanes.styles;
this.sidebarPaneView.selectTab(stylesSidebarPane.title());
stylesSidebarPane.revealProperty(/** @type {!WebInspector.CSSProperty} */(cssProperty));
return Promise.resolve();
},
/**
* @param {!WebInspector.StylesSidebarPane} ssp
* @return {!Element}
*/
_createStylesSidebarToolbar: function(ssp)
{
var container = createElementWithClass("div", "styles-sidebar-pane-toolbar-container");
var hbox = container.createChild("div", "hbox styles-sidebar-pane-toolbar");
var filterContainerElement = hbox.createChild("div", "styles-sidebar-pane-filter-box");
var filterInput = WebInspector.StylesSidebarPane.createPropertyFilterElement(WebInspector.UIString("Filter"), hbox, ssp.onFilterChanged.bind(ssp));
filterContainerElement.appendChild(filterInput);
var toolbar = new WebInspector.ExtensibleToolbar("styles-sidebarpane-toolbar", hbox);
toolbar.onLoad().then(() => toolbar.appendToolbarItem(WebInspector.StylesSidebarPane.createAddNewRuleButton(ssp)));
toolbar.element.classList.add("styles-pane-toolbar");
toolbar.makeToggledGray();
var toolbarPaneContainer = container.createChild("div", "styles-sidebar-toolbar-pane-container");
this._toolbarPaneElement = createElementWithClass("div", "styles-sidebar-toolbar-pane");
toolbarPaneContainer.appendChild(this._toolbarPaneElement);
return container;
},
/**
* @param {?WebInspector.Widget} widget
*/
showToolbarPane: function(widget)
{
if (this._animatedToolbarPane !== undefined)
this._pendingWidget = widget;
else
this._startToolbarPaneAnimation(widget);
},
/**
* @param {?WebInspector.Widget} widget
*/
_startToolbarPaneAnimation: function(widget)
{
if (widget === this._currentToolbarPane)
return;
if (widget && this._currentToolbarPane) {
this._currentToolbarPane.detach();
widget.show(this._toolbarPaneElement);
this._currentToolbarPane = widget;
this._currentToolbarPane.focus();
return;
}
this._animatedToolbarPane = widget;
if (this._currentToolbarPane)
this._toolbarPaneElement.style.animationName = 'styles-element-state-pane-slideout';
else if (widget)
this._toolbarPaneElement.style.animationName = 'styles-element-state-pane-slidein';
if (widget)
widget.show(this._toolbarPaneElement);
var listener = onAnimationEnd.bind(this);
this._toolbarPaneElement.addEventListener("animationend", listener, false);
/**
* @this {WebInspector.ElementsPanel}
*/
function onAnimationEnd()
{
this._toolbarPaneElement.style.removeProperty('animation-name');
this._toolbarPaneElement.removeEventListener("animationend", listener, false);
if (this._currentToolbarPane)
this._currentToolbarPane.detach();
this._currentToolbarPane = this._animatedToolbarPane;
if (this._currentToolbarPane)
this._currentToolbarPane.focus();
delete this._animatedToolbarPane;
if (this._pendingWidget !== undefined) {
this._startToolbarPaneAnimation(this._pendingWidget);
delete this._pendingWidget;
}
}
},
_toggleHideElement: function()
{
var node = this.selectedDOMNode();
var treeOutline = this._treeOutlineForNode(node);
if (!node || !treeOutline)
return;
treeOutline.toggleHideElement(node);
},
_toggleEditAsHTML: function()
{
var node = this.selectedDOMNode();
var treeOutline = this._treeOutlineForNode(node);
if (!node || !treeOutline)
return;
treeOutline.toggleEditAsHTML(node);
},
_loadSidebarViews: function()
{
var extensions = self.runtime.extensions("@WebInspector.Widget");
for (var i = 0; i < extensions.length; ++i) {
var descriptor = extensions[i].descriptor();
if (descriptor["location"] !== "elements-panel")
continue;
var title = WebInspector.UIString(descriptor["title"]);
extensions[i].instancePromise().then(addSidebarView.bind(this, title));
}
/**
* @param {string} title
* @param {!Object} object
* @this {WebInspector.ElementsPanel}
*/
function addSidebarView(title, object)
{
var widget = /** @type {!WebInspector.Widget} */ (object);
var elementsSidebarViewWrapperPane = new WebInspector.ElementsSidebarViewWrapperPane(title, widget);
this._elementsSidebarViewWrappers.push(elementsSidebarViewWrapperPane);
if (this.sidebarPaneView)
this.sidebarPaneView.addPane(elementsSidebarViewWrapperPane);
}
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (!domModel)
return;
var treeOutline = new WebInspector.ElementsTreeOutline(domModel, true, true);
treeOutline.setWordWrap(WebInspector.moduleSetting("domWordWrap").get());
treeOutline.wireToDOMModel();
treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.ElementsTreeUpdated, this._updateBreadcrumbIfNeeded, this);
new WebInspector.ElementsTreeElementHighlighter(treeOutline);
this._treeOutlines.push(treeOutline);
this._modelToTreeOutline.set(domModel, treeOutline);
// Perform attach if necessary.
if (this.isShowing())
this.wasShown();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (!domModel)
return;
var treeOutline = this._modelToTreeOutline.remove(domModel);
treeOutline.unwireFromDOMModel();
this._treeOutlines.remove(treeOutline);
treeOutline.element.remove();
},
_updateTreeOutlineVisibleWidth: function()
{
if (!this._treeOutlines.length)
return;
var width = this._splitWidget.element.offsetWidth;
if (this._splitWidget.isVertical())
width -= this._splitWidget.sidebarSize();
for (var i = 0; i < this._treeOutlines.length; ++i) {
this._treeOutlines[i].setVisibleWidth(width);
this._treeOutlines[i].updateSelection();
}
this._breadcrumbs.updateSizes();
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._treeOutlines.length ? this._treeOutlines[0].element : this.element;
},
/**
* @override
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
wasShown: function()
{
WebInspector.context.setFlavor(WebInspector.ElementsPanel, this);
for (var i = 0; i < this._treeOutlines.length; ++i) {
var treeOutline = this._treeOutlines[i];
// Attach heavy component lazily
if (treeOutline.element.parentElement !== this._contentElement)
this._contentElement.appendChild(treeOutline.element);
}
WebInspector.Panel.prototype.wasShown.call(this);
this._breadcrumbs.update();
for (var i = 0; i < this._treeOutlines.length; ++i) {
var treeOutline = this._treeOutlines[i];
treeOutline.updateSelection();
treeOutline.setVisible(true);
if (!treeOutline.rootDOMNode)
if (treeOutline.domModel().existingDocument())
this._documentUpdated(treeOutline.domModel(), treeOutline.domModel().existingDocument());
else
treeOutline.domModel().requestDocument();
}
},
willHide: function()
{
WebInspector.context.setFlavor(WebInspector.ElementsPanel, null);
WebInspector.DOMModel.hideDOMNodeHighlight();
for (var i = 0; i < this._treeOutlines.length; ++i) {
var treeOutline = this._treeOutlines[i];
treeOutline.setVisible(false);
// Detach heavy component on hide
this._contentElement.removeChild(treeOutline.element);
}
if (this._popoverHelper)
this._popoverHelper.hidePopover();
WebInspector.Panel.prototype.willHide.call(this);
},
onResize: function()
{
if (WebInspector.moduleSetting("sidebarPosition").get() === "auto")
this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this)); // Do not force layout.
this._updateTreeOutlineVisibleWidth();
},
/**
* @param {!WebInspector.Event} event
*/
_selectedNodeChanged: function(event)
{
var selectedNode = /** @type {?WebInspector.DOMNode} */ (event.data);
for (var i = 0; i < this._treeOutlines.length; ++i) {
if (!selectedNode || selectedNode.domModel() !== this._treeOutlines[i].domModel())
this._treeOutlines[i].selectDOMNode(null);
}
if (!selectedNode && this._lastValidSelectedNode)
this._selectedPathOnReset = this._lastValidSelectedNode.path();
this._breadcrumbs.setSelectedNode(selectedNode);
WebInspector.context.setFlavor(WebInspector.DOMNode, selectedNode);
if (selectedNode) {
selectedNode.setAsInspectedNode();
this._lastValidSelectedNode = selectedNode;
var executionContexts = selectedNode.target().runtimeModel.executionContexts();
var nodeFrameId = selectedNode.frameId();
for (var context of executionContexts) {
if (context.frameId == nodeFrameId) {
WebInspector.context.setFlavor(WebInspector.ExecutionContext, context);
break;
}
}
}
WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.SelectedNodeChanged);
this._selectedNodeChangedForTest();
},
_selectedNodeChangedForTest: function() { },
_reset: function()
{
delete this.currentQuery;
},
/**
* @param {!WebInspector.Event} event
*/
_documentUpdatedEvent: function(event)
{
this._documentUpdated(/** @type {!WebInspector.DOMModel} */ (event.target), /** @type {?WebInspector.DOMDocument} */ (event.data));
},
/**
* @param {!WebInspector.DOMModel} domModel
* @param {?WebInspector.DOMDocument} inspectedRootDocument
*/
_documentUpdated: function(domModel, inspectedRootDocument)
{
this._reset();
this.searchCanceled();
var treeOutline = this._modelToTreeOutline.get(domModel);
treeOutline.rootDOMNode = inspectedRootDocument;
if (!inspectedRootDocument) {
if (this.isShowing())
domModel.requestDocument();
return;
}
WebInspector.domBreakpointsSidebarPane.restoreBreakpoints(domModel);
/**
* @this {WebInspector.ElementsPanel}
* @param {?WebInspector.DOMNode} candidateFocusNode
*/
function selectNode(candidateFocusNode)
{
if (!candidateFocusNode)
candidateFocusNode = inspectedRootDocument.body || inspectedRootDocument.documentElement;
if (!candidateFocusNode)
return;
if (!this._pendingNodeReveal) {
this.selectDOMNode(candidateFocusNode);
if (treeOutline.selectedTreeElement)
treeOutline.selectedTreeElement.expand();
}
}
/**
* @param {?DOMAgent.NodeId} nodeId
* @this {WebInspector.ElementsPanel}
*/
function selectLastSelectedNode(nodeId)
{
if (this.selectedDOMNode()) {
// Focused node has been explicitly set while reaching out for the last selected node.
return;
}
var node = nodeId ? domModel.nodeForId(nodeId) : null;
selectNode.call(this, node);
}
if (this._omitDefaultSelection)
return;
if (this._selectedPathOnReset)
domModel.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
else
selectNode.call(this, null);
delete this._selectedPathOnReset;
},
/**
* @override
*/
searchCanceled: function()
{
delete this._searchQuery;
this._hideSearchHighlights();
this._searchableView.updateSearchMatchesCount(0);
delete this._currentSearchResultIndex;
delete this._searchResults;
WebInspector.DOMModel.cancelSearch();
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var query = searchConfig.query;
// Call searchCanceled since it will reset everything we need before doing a new search.
this.searchCanceled();
const whitespaceTrimmedQuery = query.trim();
if (!whitespaceTrimmedQuery.length)
return;
this._searchQuery = query;
var promises = [];
var domModels = WebInspector.DOMModel.instances();
for (var domModel of domModels)
promises.push(domModel.performSearchPromise(whitespaceTrimmedQuery, WebInspector.moduleSetting("showUAShadowDOM").get()));
Promise.all(promises).then(resultCountCallback.bind(this));
/**
* @param {!Array.<number>} resultCounts
* @this {WebInspector.ElementsPanel}
*/
function resultCountCallback(resultCounts)
{
/**
* @type {!Array.<{domModel: !WebInspector.DOMModel, index: number, node: (?WebInspector.DOMNode|undefined)}>}
*/
this._searchResults = [];
for (var i = 0; i < resultCounts.length; ++i) {
var resultCount = resultCounts[i];
for (var j = 0; j < resultCount; ++j)
this._searchResults.push({domModel: domModels[i], index: j, node: undefined});
}
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = -1;
if (shouldJump)
this._jumpToSearchResult(jumpBackwards ? -1 : 0);
}
},
_domWordWrapSettingChanged: function(event)
{
// FIXME: crbug.com/425984
this._contentElement.classList.toggle("elements-wrap", event.data);
for (var i = 0; i < this._treeOutlines.length; ++i)
this._treeOutlines[i].setWordWrap(/** @type {boolean} */ (event.data));
var selectedNode = this.selectedDOMNode();
if (!selectedNode)
return;
var treeElement = this._treeElementForNode(selectedNode);
if (treeElement)
treeElement.updateSelection(); // Recalculate selection highlight dimensions.
},
switchToAndFocus: function(node)
{
// Reset search restore.
this._searchableView.cancelSearch();
WebInspector.inspectorView.setCurrentPanel(this);
this.selectDOMNode(node, true);
},
/**
* @param {!Element} element
* @param {!Event} event
* @return {!Element|!AnchorBox|undefined}
*/
_getPopoverAnchor: function(element, event)
{
var anchor = element.enclosingNodeOrSelfWithClass("webkit-html-resource-link");
if (!anchor || !anchor.href)
return;
return anchor;
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showPopover: function(anchor, popover)
{
var node = this.selectedDOMNode();
if (node)
WebInspector.DOMPresentationUtils.buildImagePreviewContents(node.target(), anchor.href, true, showPopover);
/**
* @param {!Element=} contents
*/
function showPopover(contents)
{
if (!contents)
return;
popover.setCanShrink(false);
popover.showForAnchor(contents, anchor);
}
},
_jumpToSearchResult: function(index)
{
this._hideSearchHighlights();
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
this._highlightCurrentSearchResult();
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._searchResults)
return;
this._jumpToSearchResult(this._currentSearchResultIndex + 1);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._searchResults)
return;
this._jumpToSearchResult(this._currentSearchResultIndex - 1);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
_highlightCurrentSearchResult: function()
{
var index = this._currentSearchResultIndex;
var searchResults = this._searchResults;
var searchResult = searchResults[index];
if (searchResult.node === null) {
this._searchableView.updateCurrentMatchIndex(index);
return;
}
/**
* @param {?WebInspector.DOMNode} node
* @this {WebInspector.ElementsPanel}
*/
function searchCallback(node)
{
searchResult.node = node;
this._highlightCurrentSearchResult();
}
if (typeof searchResult.node === "undefined") {
// No data for slot, request it.
searchResult.domModel.searchResult(searchResult.index, searchCallback.bind(this));
return;
}
this._searchableView.updateCurrentMatchIndex(index);
var treeElement = this._treeElementForNode(searchResult.node);
if (treeElement) {
treeElement.highlightSearchResults(this._searchQuery);
treeElement.reveal();
var matches = treeElement.listItemElement.getElementsByClassName(WebInspector.highlightedSearchResultClassName);
if (matches.length)
matches[0].scrollIntoViewIfNeeded(false);
}
},
_hideSearchHighlights: function()
{
if (!this._searchResults || !this._searchResults.length || this._currentSearchResultIndex < 0)
return;
var searchResult = this._searchResults[this._currentSearchResultIndex];
if (!searchResult.node)
return;
var treeOutline = this._modelToTreeOutline.get(searchResult.node.domModel());
var treeElement = treeOutline.findTreeElement(searchResult.node);
if (treeElement)
treeElement.hideSearchHighlights();
},
/**
* @return {?WebInspector.DOMNode}
*/
selectedDOMNode: function()
{
for (var i = 0; i < this._treeOutlines.length; ++i) {
var treeOutline = this._treeOutlines[i];
if (treeOutline.selectedDOMNode())
return treeOutline.selectedDOMNode();
}
return null;
},
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} focus
*/
selectDOMNode: function(node, focus)
{
for (var i = 0; i < this._treeOutlines.length; ++i) {
var treeOutline = this._treeOutlines[i];
if (treeOutline.domModel() === node.domModel())
treeOutline.selectDOMNode(node, focus);
else
treeOutline.selectDOMNode(null);
}
},
/**
* @param {!WebInspector.Event} event
*/
_updateBreadcrumbIfNeeded: function(event)
{
var nodes = /** @type {!Array.<!WebInspector.DOMNode>} */ (event.data);
this._breadcrumbs.updateNodes(nodes);
},
/**
* @param {!WebInspector.Event} event
*/
_crumbNodeSelected: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this.selectDOMNode(node, true);
},
/**
* @override
* @param {!KeyboardEvent} event
*/
handleShortcut: function(event)
{
/**
* @param {!WebInspector.ElementsTreeOutline} treeOutline
*/
function handleUndoRedo(treeOutline)
{
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && event.keyIdentifier === "U+005A") { // Z key
treeOutline.domModel().undo();
event.handled = true;
return;
}
var isRedoKey = WebInspector.isMac() ? event.metaKey && event.shiftKey && event.keyIdentifier === "U+005A" : // Z key
event.ctrlKey && event.keyIdentifier === "U+0059"; // Y key
if (isRedoKey) {
treeOutline.domModel().redo();
event.handled = true;
}
}
if (WebInspector.isEditing() && event.keyCode !== WebInspector.KeyboardShortcut.Keys.F2.code)
return;
var treeOutline = null;
for (var i = 0; i < this._treeOutlines.length; ++i) {
if (this._treeOutlines[i].selectedDOMNode() === this._lastValidSelectedNode)
treeOutline = this._treeOutlines[i];
}
if (!treeOutline)
return;
if (!treeOutline.editing()) {
handleUndoRedo.call(null, treeOutline);
if (event.handled) {
this.sidebarPanes.styles.onUndoOrRedoHappened();
return;
}
}
treeOutline.handleShortcut(event);
if (event.handled)
return;
WebInspector.Panel.prototype.handleShortcut.call(this, event);
},
/**
* @param {?WebInspector.DOMNode} node
* @return {?WebInspector.ElementsTreeOutline}
*/
_treeOutlineForNode: function(node)
{
if (!node)
return null;
return this._modelToTreeOutline.get(node.domModel()) || null;
},
/**
* @return {?WebInspector.ElementsTreeOutline}
*/
_focusedTreeOutline: function()
{
for (var i = 0; i < this._treeOutlines.length; ++i) {
if (this._treeOutlines[i].hasFocus())
return this._treeOutlines[i];
}
return null;
},
/**
* @param {!WebInspector.DOMNode} node
* @return {?WebInspector.ElementsTreeElement}
*/
_treeElementForNode: function(node)
{
var treeOutline = this._treeOutlineForNode(node);
return /** @type {?WebInspector.ElementsTreeElement} */ (treeOutline.findTreeElement(node));
},
/**
* @param {!Event} event
*/
handleCopyEvent: function(event)
{
var treeOutline = this._focusedTreeOutline();
if (treeOutline)
treeOutline.handleCopyOrCutKeyboardEvent(false, event);
},
/**
* @param {!Event} event
*/
handleCutEvent: function(event)
{
var treeOutline = this._focusedTreeOutline();
if (treeOutline)
treeOutline.handleCopyOrCutKeyboardEvent(true, event);
},
/**
* @param {!Event} event
*/
handlePasteEvent: function(event)
{
var treeOutline = this._focusedTreeOutline();
if (treeOutline)
treeOutline.handlePasteKeyboardEvent(event);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!WebInspector.DOMNode}
*/
_leaveUserAgentShadowDOM: function(node)
{
var userAgentShadowRoot = node.ancestorUserAgentShadowRoot();
return userAgentShadowRoot ? /** @type {!WebInspector.DOMNode} */ (userAgentShadowRoot.parentNode) : node;
},
/**
* @param {!WebInspector.DOMNode} node
*/
revealAndSelectNode: function(node)
{
if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.isInInspectElementMode())
WebInspector.inspectElementModeController.stopInspection();
this._omitDefaultSelection = true;
var showLayoutEditor = !!WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.isInLayoutEditorMode();
WebInspector.inspectorView.setCurrentPanel(this, showLayoutEditor);
node = WebInspector.moduleSetting("showUAShadowDOM").get() ? node : this._leaveUserAgentShadowDOM(node);
if (!showLayoutEditor)
node.highlightForTwoSeconds();
this.selectDOMNode(node, true);
delete this._omitDefaultSelection;
if (!this._notFirstInspectElement)
InspectorFrontendHost.inspectElementCompleted();
this._notFirstInspectElement = true;
},
/**
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} object
*/
appendApplicableItems: function(event, contextMenu, object)
{
if (!(object instanceof WebInspector.RemoteObject && (/** @type {!WebInspector.RemoteObject} */ (object)).isNode())
&& !(object instanceof WebInspector.DOMNode)
&& !(object instanceof WebInspector.DeferredDOMNode)) {
return;
}
// Add debbuging-related actions
if (object instanceof WebInspector.DOMNode) {
contextMenu.appendSeparator();
WebInspector.domBreakpointsSidebarPane.populateNodeContextMenu(object, contextMenu, true);
}
// Skip adding "Reveal..." menu item for our own tree outline.
if (this.element.isAncestor(/** @type {!Node} */ (event.target)))
return;
var commandCallback = WebInspector.Revealer.reveal.bind(WebInspector.Revealer, object);
contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Elements ^panel"), commandCallback);
},
_sidebarContextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(/** @type {!Object} */ (event.deepElementFromPoint()));
contextMenu.show();
},
_showUAShadowDOMChanged: function()
{
for (var i = 0; i < this._treeOutlines.length; ++i)
this._treeOutlines[i].update();
},
_updateSidebarPosition: function()
{
var horizontally;
var position = WebInspector.moduleSetting("sidebarPosition").get();
if (position === "right")
horizontally = false;
else if (position === "bottom")
horizontally = true;
else
horizontally = WebInspector.inspectorView.element.offsetWidth < 680;
if (this.sidebarPaneView && horizontally === !this._splitWidget.isVertical())
return;
if (this.sidebarPaneView && this.sidebarPaneView.shouldHideOnDetach())
return; // We can't reparent extension iframes.
var selectedTabId = this.sidebarPaneView ? this.sidebarPaneView.selectedTabId : null;
var extensionSidebarPanes = WebInspector.extensionServer.sidebarPanes();
if (this.sidebarPaneView) {
this.sidebarPaneView.detach();
this._splitWidget.uninstallResizer(this.sidebarPaneView.headerElement());
}
this._splitWidget.setVertical(!horizontally);
this.showToolbarPane(null);
var computedPane = new WebInspector.SidebarPane(WebInspector.UIString("Computed"));
computedPane.element.classList.add("composite");
computedPane.element.classList.add("fill");
computedPane.element.classList.add("metrics-and-computed");
var matchedStylesContainer = new WebInspector.VBox();
matchedStylesContainer.element.appendChild(this._stylesSidebarToolbar);
var matchedStylePanesWrapper = new WebInspector.VBox();
matchedStylePanesWrapper.element.classList.add("style-panes-wrapper");
matchedStylePanesWrapper.show(matchedStylesContainer.element);
var computedStylePanesWrapper = new WebInspector.VBox();
computedStylePanesWrapper.element.classList.add("style-panes-wrapper");
/**
* @param {boolean} inComputedStyle
* @this {WebInspector.ElementsPanel}
*/
function showMetrics(inComputedStyle)
{
if (inComputedStyle)
this.sidebarPanes.metrics.show(computedStylePanesWrapper.element, this.sidebarPanes.computedStyle.element);
else
this.sidebarPanes.metrics.show(matchedStylePanesWrapper.element);
}
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ElementsPanel}
*/
function tabSelected(event)
{
var tabId = /** @type {string} */ (event.data.tabId);
if (tabId === computedPane.title())
showMetrics.call(this, true);
else if (tabId === stylesPane.title())
showMetrics.call(this, false);
}
this.sidebarPaneView = new WebInspector.SidebarTabbedPane();
this.sidebarPaneView.element.addEventListener("contextmenu", this._sidebarContextMenuEventFired.bind(this), false);
if (this._popoverHelper)
this._popoverHelper.hidePopover();
this._popoverHelper = new WebInspector.PopoverHelper(this.sidebarPaneView.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
this._popoverHelper.setTimeout(0);
if (horizontally) {
this._splitWidget.installResizer(this.sidebarPaneView.headerElement());
var compositePane = new WebInspector.SidebarPane(this.sidebarPanes.styles.title());
compositePane.element.classList.add("composite");
compositePane.element.classList.add("fill");
var splitWidget = new WebInspector.SplitWidget(true, true, "stylesPaneSplitViewState", 215);
splitWidget.show(compositePane.element);
splitWidget.setMainWidget(matchedStylesContainer);
splitWidget.setSidebarWidget(computedStylePanesWrapper);
computedPane.show(computedStylePanesWrapper.element);
this.sidebarPaneView.addPane(compositePane);
} else {
var stylesPane = new WebInspector.SidebarPane(this.sidebarPanes.styles.title());
stylesPane.element.classList.add("composite", "fill", "metrics-and-styles");
matchedStylesContainer.show(stylesPane.element);
computedStylePanesWrapper.show(computedPane.element);
this.sidebarPaneView.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, tabSelected, this);
this.sidebarPaneView.addPane(stylesPane);
this.sidebarPaneView.addPane(computedPane);
}
this.sidebarPanes.styles.show(matchedStylePanesWrapper.element);
this.sidebarPanes.computedStyle.show(computedStylePanesWrapper.element);
showMetrics.call(this, horizontally);
this.sidebarPanes.platformFonts.show(computedStylePanesWrapper.element);
this.sidebarPaneView.addPane(this.sidebarPanes.eventListeners);
this.sidebarPaneView.addPane(this.sidebarPanes.domBreakpoints);
this.sidebarPaneView.addPane(this.sidebarPanes.properties);
for (var sidebarViewWrapper of this._elementsSidebarViewWrappers)
this.sidebarPaneView.addPane(sidebarViewWrapper);
this._extensionSidebarPanesContainer = this.sidebarPaneView;
for (var i = 0; i < extensionSidebarPanes.length; ++i)
this._addExtensionSidebarPane(extensionSidebarPanes[i]);
this._splitWidget.setSidebarWidget(this.sidebarPaneView);
this.sidebarPanes.styles.expand();
if (selectedTabId)
this.sidebarPaneView.selectTab(selectedTabId);
},
/**
* @param {!WebInspector.Event} event
*/
_extensionSidebarPaneAdded: function(event)
{
var pane = /** @type {!WebInspector.ExtensionSidebarPane} */ (event.data);
this._addExtensionSidebarPane(pane);
},
/**
* @param {!WebInspector.ExtensionSidebarPane} pane
*/
_addExtensionSidebarPane: function(pane)
{
if (pane.panelName() === this.name)
this._extensionSidebarPanesContainer.addPane(pane);
},
__proto__: WebInspector.Panel.prototype
}
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.ElementsPanel.ContextMenuProvider = function()
{
}
WebInspector.ElementsPanel.ContextMenuProvider.prototype = {
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
WebInspector.ElementsPanel.instance().appendApplicableItems(event, contextMenu, target);
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.ElementsPanel.DOMNodeRevealer = function()
{
}
WebInspector.ElementsPanel.DOMNodeRevealer.prototype = {
/**
* @override
* @param {!Object} node
* @return {!Promise}
*/
reveal: function(node)
{
var panel = WebInspector.ElementsPanel.instance();
panel._pendingNodeReveal = true;
return new Promise(revealPromise);
/**
* @param {function(undefined)} resolve
* @param {function(!Error)} reject
*/
function revealPromise(resolve, reject)
{
if (node instanceof WebInspector.DOMNode) {
onNodeResolved(/** @type {!WebInspector.DOMNode} */ (node));
} else if (node instanceof WebInspector.DeferredDOMNode) {
(/** @type {!WebInspector.DeferredDOMNode} */ (node)).resolve(onNodeResolved);
} else if (node instanceof WebInspector.RemoteObject) {
var domModel = WebInspector.DOMModel.fromTarget(/** @type {!WebInspector.RemoteObject} */ (node).target());
if (domModel)
domModel.pushObjectAsNodeToFrontend(node, onNodeResolved);
else
reject(new Error("Could not resolve a node to reveal."));
} else {
reject(new Error("Can't reveal a non-node."));
panel._pendingNodeReveal = false;
}
/**
* @param {?WebInspector.DOMNode} resolvedNode
*/
function onNodeResolved(resolvedNode)
{
panel._pendingNodeReveal = false;
if (resolvedNode) {
panel.revealAndSelectNode(resolvedNode);
resolve(undefined);
return;
}
reject(new Error("Could not resolve node to reveal."));
}
}
}
}
WebInspector.ElementsPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.ElementsPanel.instance());
}
/**
* @return {!WebInspector.ElementsPanel}
*/
WebInspector.ElementsPanel.instance = function()
{
if (!WebInspector.ElementsPanel._instanceObject)
WebInspector.ElementsPanel._instanceObject = new WebInspector.ElementsPanel();
return WebInspector.ElementsPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.ElementsPanelFactory = function()
{
}
WebInspector.ElementsPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.ElementsPanel.instance();
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.ElementsActionDelegate = function() { }
WebInspector.ElementsActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
switch (actionId) {
case "elements.hide-element":
WebInspector.ElementsPanel.instance()._toggleHideElement();
return true;
case "elements.edit-as-html":
WebInspector.ElementsPanel.instance()._toggleEditAsHTML();
return true;
}
return false;
}
}
/**
* @constructor
* @implements {WebInspector.DOMPresentationUtils.MarkerDecorator}
*/
WebInspector.ElementsPanel.PseudoStateMarkerDecorator = function()
{
}
WebInspector.ElementsPanel.PseudoStateMarkerDecorator.prototype = {
/**
* @override
* @param {!WebInspector.DOMNode} node
* @return {?{title: string, color: string}}
*/
decorate: function(node)
{
return { color: "orange", title: WebInspector.UIString("Element state: %s", ":" + WebInspector.CSSModel.fromNode(node).pseudoState(node).join(", :")) };
}
}
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
* @param {!WebInspector.ToolbarItem} toolbarItem
*/
WebInspector.ElementsPanel.BaseToolbarPaneWidget = function(toolbarItem)
{
WebInspector.ThrottledWidget.call(this);
this._toolbarItem = toolbarItem;
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
}
WebInspector.ElementsPanel.BaseToolbarPaneWidget.prototype = {
_nodeChanged: function()
{
if (!this.isShowing())
return;
var elementNode = WebInspector.SharedSidebarModel.elementNode(WebInspector.context.flavor(WebInspector.DOMNode));
this.onNodeChanged(elementNode);
},
/**
* @param {?WebInspector.DOMNode} newNode
* @protected
*/
onNodeChanged: function(newNode)
{
},
/**
* @override
*/
willHide: function()
{
this._toolbarItem.setToggled(false);
WebInspector.ThrottledWidget.prototype.willHide.call(this);
},
/**
* @override
*/
wasShown: function()
{
this._toolbarItem.setToggled(true);
this._nodeChanged();
WebInspector.ThrottledWidget.prototype.wasShown.call(this);
},
__proto__: WebInspector.ThrottledWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | 2 1 1 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {string} title
*/
WebInspector.ElementsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);
this._node = null;
this._updateController = new WebInspector.ElementsSidebarPane._UpdateController(this, this.doUpdate.bind(this));
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
}
WebInspector.ElementsSidebarPane.prototype = {
/**
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @return {?WebInspector.CSSModel}
*/
cssModel: function()
{
return this._cssModel && this._cssModel.isEnabled() ? this._cssModel : null;
},
/**
* @param {!WebInspector.Event} event
*/
_nodeChanged: function(event)
{
this.setNode(/** @type {?WebInspector.DOMNode} */ (event.data));
},
/**
* @param {?WebInspector.DOMNode} node
*/
setNode: function(node)
{
this._node = node;
this._updateTarget(node ? node.target() : null);
this.update();
},
/**
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
return Promise.resolve();
},
update: function()
{
this._updateController.update();
},
wasShown: function()
{
WebInspector.SidebarPane.prototype.wasShown.call(this);
this._updateController.viewWasShown();
},
/**
* @param {?WebInspector.Target} target
*/
_updateTarget: function(target)
{
if (this._target === target)
return;
if (this._targetEvents) {
WebInspector.EventTarget.removeEventListeners(this._targetEvents);
this._targetEvents = null;
}
this._target = target;
var domModel = null;
var resourceTreeModel = null;
if (target) {
this._cssModel = WebInspector.CSSModel.fromTarget(target);
domModel = WebInspector.DOMModel.fromTarget(target);
resourceTreeModel = target.resourceTreeModel;
}
if (this._cssModel && domModel && resourceTreeModel) {
this._targetEvents = [
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this.onCSSModelChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this.onCSSModelChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged, this.onCSSModelChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged, this.onCSSModelChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.PseudoStateForced, this.onCSSModelChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.ModelWasEnabled, this.onCSSModelChanged, this),
domModel.addEventListener(WebInspector.DOMModel.Events.DOMMutated, this._domModelChanged, this),
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._onFrameResized, this),
];
}
},
/**
* @param {!WebInspector.Event} event
*/
_onFrameResized: function(event)
{
/**
* @this {WebInspector.ElementsSidebarPane}
*/
function refreshContents()
{
this.onFrameResizedThrottled();
delete this._frameResizedTimer;
}
if (this._frameResizedTimer)
clearTimeout(this._frameResizedTimer);
this._frameResizedTimer = setTimeout(refreshContents.bind(this), 100);
},
/**
* @param {!WebInspector.Event} event
*/
_domModelChanged: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this.onDOMModelChanged(node)
},
/**
* @param {!WebInspector.DOMNode} node
*/
onDOMModelChanged: function(node) { },
/**
* @param {!WebInspector.Event} event
*/
onCSSModelChanged: function(event) { },
onFrameResizedThrottled: function() { },
__proto__: WebInspector.SidebarPane.prototype
}
/**
* @constructor
* @param {!WebInspector.Widget} view
* @param {function():!Promise.<?>} doUpdate
*/
WebInspector.ElementsSidebarPane._UpdateController = function(view, doUpdate)
{
this._view = view;
this._updateThrottler = new WebInspector.Throttler(100);
this._updateWhenVisible = false;
this._doUpdate = doUpdate;
}
WebInspector.ElementsSidebarPane._UpdateController.prototype = {
update: function()
{
this._updateWhenVisible = !this._view.isShowing();
if (this._updateWhenVisible)
return;
this._updateThrottler.schedule(innerUpdate.bind(this));
/**
* @this {WebInspector.ElementsSidebarPane._UpdateController}
* @return {!Promise.<?>}
*/
function innerUpdate()
{
return this._view.isShowing() ? this._doUpdate.call(null) : Promise.resolve();
}
},
viewWasShown: function()
{
if (this._updateWhenVisible)
this.update();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {string} title
* @param {!WebInspector.Widget} widget
*/
WebInspector.ElementsSidebarViewWrapperPane = function(title, widget)
{
WebInspector.SidebarPane.call(this, title);
widget.show(this.element);
}
WebInspector.ElementsSidebarViewWrapperPane.prototype = {
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.DOMNode} node
* @param {boolean=} elementCloseTag
*/
WebInspector.ElementsTreeElement = function(node, elementCloseTag)
{
// The title will be updated in onattach.
TreeElement.call(this);
this._node = node;
this._gutterContainer = this.listItemElement.createChild("div", "gutter-container");
this._gutterContainer.addEventListener("click", this._showContextMenu.bind(this));
this._decorationsElement = this._gutterContainer.createChild("div", "hidden");
this._elementCloseTag = elementCloseTag;
if (this._node.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
this._canAddAttributes = true;
this._searchQuery = null;
this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
}
WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
// A union of HTML4 and HTML5-Draft elements that explicitly
// or implicitly (for HTML5) forbid the closing tag.
WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
"area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
"hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr"
].keySet();
// These tags we do not allow editing their tag name.
WebInspector.ElementsTreeElement.EditTagBlacklist = [
"html", "head", "body"
].keySet();
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
*/
WebInspector.ElementsTreeElement.animateOnDOMUpdate = function(treeElement)
{
var tagName = treeElement.listItemElement.querySelector(".webkit-html-tag-name");
WebInspector.runCSSAnimationOnce(tagName || treeElement.listItemElement, "dom-update-highlight");
}
/**
* @param {!WebInspector.DOMNode} node
* @return {!Array<!WebInspector.DOMNode>}
*/
WebInspector.ElementsTreeElement.visibleShadowRoots = function(node)
{
var roots = node.shadowRoots();
if (roots.length && !WebInspector.moduleSetting("showUAShadowDOM").get())
roots = roots.filter(filter);
/**
* @param {!WebInspector.DOMNode} root
*/
function filter(root)
{
return root.shadowRootType() !== WebInspector.DOMNode.ShadowRootTypes.UserAgent;
}
return roots;
}
/**
* @param {!WebInspector.DOMNode} node
* @return {boolean}
*/
WebInspector.ElementsTreeElement.canShowInlineText = function(node)
{
if (node.importedDocument() || node.templateContent() || WebInspector.ElementsTreeElement.visibleShadowRoots(node).length || node.hasPseudoElements())
return false;
if (node.nodeType() !== Node.ELEMENT_NODE)
return false;
if (!node.firstChild || node.firstChild !== node.lastChild || node.firstChild.nodeType() !== Node.TEXT_NODE)
return false;
var textChild = node.firstChild;
var maxInlineTextChildLength = 80;
if (textChild.nodeValue().length < maxInlineTextChildLength)
return true;
return false;
}
/**
* @param {!WebInspector.ContextSubMenuItem} subMenu
* @param {!WebInspector.DOMNode} node
*/
WebInspector.ElementsTreeElement.populateForcedPseudoStateItems = function(subMenu, node)
{
const pseudoClasses = ["active", "hover", "focus", "visited"];
var forcedPseudoState = WebInspector.CSSModel.fromNode(node).pseudoState(node);
for (var i = 0; i < pseudoClasses.length; ++i) {
var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
subMenu.appendCheckboxItem(":" + pseudoClasses[i], setPseudoStateCallback.bind(null, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
}
/**
* @param {string} pseudoState
* @param {boolean} enabled
*/
function setPseudoStateCallback(pseudoState, enabled)
{
WebInspector.CSSModel.fromNode(node).forcePseudoState(node, pseudoState, enabled);
}
}
WebInspector.ElementsTreeElement.prototype = {
/**
* @return {boolean}
*/
isClosingTag: function()
{
return !!this._elementCloseTag;
},
/**
* @return {!WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @return {boolean}
*/
isEditing: function()
{
return !!this._editing;
},
/**
* @param {string} searchQuery
*/
highlightSearchResults: function(searchQuery)
{
if (this._searchQuery !== searchQuery)
this._hideSearchHighlight();
this._searchQuery = searchQuery;
this._searchHighlightsVisible = true;
this.updateTitle(null, true);
},
hideSearchHighlights: function()
{
delete this._searchHighlightsVisible;
this._hideSearchHighlight();
},
_hideSearchHighlight: function()
{
if (!this._highlightResult)
return;
function updateEntryHide(entry)
{
switch (entry.type) {
case "added":
entry.node.remove();
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
for (var i = (this._highlightResult.length - 1); i >= 0; --i)
updateEntryHide(this._highlightResult[i]);
delete this._highlightResult;
},
/**
* @param {boolean} inClipboard
*/
setInClipboard: function(inClipboard)
{
if (this._inClipboard === inClipboard)
return;
this._inClipboard = inClipboard;
this.listItemElement.classList.toggle("in-clipboard", inClipboard);
},
get hovered()
{
return this._hovered;
},
set hovered(x)
{
if (this._hovered === x)
return;
this._hovered = x;
if (this.listItemElement) {
if (x) {
this.updateSelection();
this.listItemElement.classList.add("hovered");
} else {
this.listItemElement.classList.remove("hovered");
}
}
},
/**
* @return {number}
*/
expandedChildrenLimit: function()
{
return this._expandedChildrenLimit;
},
/**
* @param {number} expandedChildrenLimit
*/
setExpandedChildrenLimit: function(expandedChildrenLimit)
{
this._expandedChildrenLimit = expandedChildrenLimit;
},
updateSelection: function()
{
var listItemElement = this.listItemElement;
if (!listItemElement)
return;
if (!this.selectionElement) {
this.selectionElement = createElement("div");
this.selectionElement.className = "selection fill";
listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
}
},
/**
* @override
*/
onbind: function()
{
if (!this._elementCloseTag)
this._node[this.treeOutline.treeElementSymbol()] = this;
},
/**
* @override
*/
onunbind: function()
{
if (this._node[this.treeOutline.treeElementSymbol()] === this)
this._node[this.treeOutline.treeElementSymbol()] = null;
},
/**
* @override
*/
onattach: function()
{
if (this._hovered) {
this.updateSelection();
this.listItemElement.classList.add("hovered");
}
this.updateTitle();
this._preventFollowingLinksOnDoubleClick();
this.listItemElement.draggable = true;
},
_preventFollowingLinksOnDoubleClick: function()
{
var links = this.listItemElement.querySelectorAll("li .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
if (!links)
return;
for (var i = 0; i < links.length; ++i)
links[i].preventFollowOnDoubleClick = true;
},
onpopulate: function()
{
this.populated = true;
this.treeOutline.populateTreeElement(this);
},
expandRecursively: function()
{
/**
* @this {WebInspector.ElementsTreeElement}
*/
function callback()
{
TreeElement.prototype.expandRecursively.call(this, Number.MAX_VALUE);
}
this._node.getSubtree(-1, callback.bind(this));
},
/**
* @override
*/
onexpand: function()
{
if (this._elementCloseTag)
return;
this.updateTitle();
this.treeOutline.updateSelection();
},
oncollapse: function()
{
if (this._elementCloseTag)
return;
this.updateTitle();
this.treeOutline.updateSelection();
},
/**
* @override
* @param {boolean=} omitFocus
* @param {boolean=} selectedByUser
* @return {boolean}
*/
select: function(omitFocus, selectedByUser)
{
if (this._editing)
return false;
return TreeElement.prototype.select.call(this, omitFocus, selectedByUser);
},
/**
* @override
* @param {boolean=} selectedByUser
* @return {boolean}
*/
onselect: function(selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.selectDOMNode(this._node, selectedByUser);
if (selectedByUser)
this._node.highlight();
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
return true;
},
/**
* @override
* @return {boolean}
*/
ondelete: function()
{
var startTagTreeElement = this.treeOutline.findTreeElement(this._node);
startTagTreeElement ? startTagTreeElement.remove() : this.remove();
return true;
},
/**
* @override
* @return {boolean}
*/
onenter: function()
{
// On Enter or Return start editing the first attribute
// or create a new attribute on the selected element.
if (this._editing)
return false;
this._startEditing();
// prevent a newline from being immediately inserted
return true;
},
selectOnMouseDown: function(event)
{
TreeElement.prototype.selectOnMouseDown.call(this, event);
if (this._editing)
return;
// Prevent selecting the nearest word on double click.
if (event.detail >= 2)
event.preventDefault();
},
/**
* @override
* @return {boolean}
*/
ondblclick: function(event)
{
if (this._editing || this._elementCloseTag)
return false;
if (this._startEditingTarget(/** @type {!Element} */(event.target)))
return false;
if (this.isExpandable() && !this.expanded)
this.expand();
return false;
},
/**
* @return {boolean}
*/
hasEditableNode: function()
{
return !this._node.isShadowRoot() && !this._node.ancestorUserAgentShadowRoot();
},
_insertInLastAttributePosition: function(tag, node)
{
if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
tag.insertBefore(node, tag.lastChild);
else {
var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
tag.textContent = '';
tag.createTextChild('<' + nodeName);
tag.appendChild(node);
tag.createTextChild('>');
}
this.updateSelection();
},
/**
* @param {!Element} eventTarget
* @return {boolean}
*/
_startEditingTarget: function(eventTarget)
{
if (this.treeOutline.selectedDOMNode() != this._node)
return false;
if (this._node.nodeType() != Node.ELEMENT_NODE && this._node.nodeType() != Node.TEXT_NODE)
return false;
var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode)
return this._startEditingTextNode(textNode);
var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
if (attribute)
return this._startEditingAttribute(attribute, eventTarget);
var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
if (tagName)
return this._startEditingTagName(tagName);
var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
if (newAttribute)
return this._addNewAttribute();
return false;
},
/**
* @param {!Event} event
*/
_showContextMenu: function(event)
{
this.treeOutline.showContextMenu(this, event);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Event} event
*/
populateTagContextMenu: function(contextMenu, event)
{
// Add attribute-related actions.
var treeElement = this._elementCloseTag ? this.treeOutline.findTreeElement(this._node) : this;
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^attribute"), treeElement._addNewAttribute.bind(treeElement));
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
if (attribute && !newAttribute)
contextMenu.appendItem(WebInspector.UIString.capitalize("Edit ^attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
this.populateNodeContextMenu(contextMenu);
WebInspector.ElementsTreeElement.populateForcedPseudoStateItems(contextMenu, treeElement.node());
contextMenu.appendSeparator();
this.populateScrollIntoView(contextMenu);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
populateScrollIntoView: function(contextMenu)
{
contextMenu.appendItem(WebInspector.UIString.capitalize("Scroll into ^view"), this._scrollIntoView.bind(this));
},
populateTextContextMenu: function(contextMenu, textNode)
{
if (!this._editing)
contextMenu.appendItem(WebInspector.UIString.capitalize("Edit ^text"), this._startEditingTextNode.bind(this, textNode));
this.populateNodeContextMenu(contextMenu);
},
populateNodeContextMenu: function(contextMenu)
{
// Add free-form node-related actions.
var openTagElement = this._node[this.treeOutline.treeElementSymbol()] || this;
var isEditable = this.hasEditableNode();
if (isEditable && !this._editing)
contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
var isShadowRoot = this._node.isShadowRoot();
// Place it here so that all "Copy"-ing items stick together.
var copyMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Copy"));
var createShortcut = WebInspector.KeyboardShortcut.shortcutToString;
var modifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
var menuItem;
if (!isShadowRoot)
menuItem = copyMenu.appendItem(WebInspector.UIString("Copy outerHTML"), this.treeOutline.performCopyOrCut.bind(this.treeOutline, false, this._node));
menuItem.setShortcut(createShortcut("V", modifier));
if (this._node.nodeType() === Node.ELEMENT_NODE)
copyMenu.appendItem(WebInspector.UIString.capitalize("Copy selector"), this._copyCSSPath.bind(this));
if (!isShadowRoot)
copyMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
if (!isShadowRoot) {
var treeOutline = this.treeOutline;
menuItem = copyMenu.appendItem(WebInspector.UIString("Cut element"), treeOutline.performCopyOrCut.bind(treeOutline, true, this._node), !this.hasEditableNode());
menuItem.setShortcut(createShortcut("X", modifier));
menuItem = copyMenu.appendItem(WebInspector.UIString("Copy element"), treeOutline.performCopyOrCut.bind(treeOutline, false, this._node));
menuItem.setShortcut(createShortcut("C", modifier));
menuItem = copyMenu.appendItem(WebInspector.UIString("Paste element"), treeOutline.pasteNode.bind(treeOutline, this._node), !treeOutline.canPaste(this._node));
menuItem.setShortcut(createShortcut("V", modifier));
}
contextMenu.appendSeparator();
menuItem = contextMenu.appendCheckboxItem(WebInspector.UIString("Hide element"), this.treeOutline.toggleHideElement.bind(this.treeOutline, this._node), this.treeOutline.isToggledToHidden(this._node));
menuItem.setShortcut(WebInspector.shortcutRegistry.shortcutTitleForAction("elements.hide-element"));
if (isEditable)
contextMenu.appendItem(WebInspector.UIString("Delete element"), this.remove.bind(this));
contextMenu.appendSeparator();
},
_startEditing: function()
{
if (this.treeOutline.selectedDOMNode() !== this._node)
return;
var listItem = this._listItemNode;
if (this._canAddAttributes) {
var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
if (attribute)
return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);
return this._addNewAttribute();
}
if (this._node.nodeType() === Node.TEXT_NODE) {
var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
if (textNode)
return this._startEditingTextNode(textNode);
return;
}
},
_addNewAttribute: function()
{
// Cannot just convert the textual html into an element without
// a parent node. Use a temporary span container for the HTML.
var container = createElement("span");
this._buildAttributeDOM(container, " ", "", null);
var attr = container.firstElementChild;
attr.style.marginLeft = "2px"; // overrides the .editing margin rule
attr.style.marginRight = "2px"; // overrides the .editing margin rule
var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
this._insertInLastAttributePosition(tag, attr);
attr.scrollIntoViewIfNeeded(true);
return this._startEditingAttribute(attr, attr);
},
_triggerEditAttribute: function(attributeName)
{
var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
for (var i = 0, len = attributeElements.length; i < len; ++i) {
if (attributeElements[i].textContent === attributeName) {
for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
if (elem.nodeType !== Node.ELEMENT_NODE)
continue;
if (elem.classList.contains("webkit-html-attribute-value"))
return this._startEditingAttribute(elem.parentNode, elem);
}
}
}
},
_startEditingAttribute: function(attribute, elementForSelection)
{
console.assert(this.listItemElement.isAncestor(attribute));
if (WebInspector.isBeingEdited(attribute))
return true;
var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
if (!attributeNameElement)
return false;
var attributeName = attributeNameElement.textContent;
var attributeValueElement = attribute.getElementsByClassName("webkit-html-attribute-value")[0];
// Make sure elementForSelection is not a child of attributeValueElement.
elementForSelection = attributeValueElement.isAncestor(elementForSelection) ? attributeValueElement : elementForSelection;
function removeZeroWidthSpaceRecursive(node)
{
if (node.nodeType === Node.TEXT_NODE) {
node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
return;
}
if (node.nodeType !== Node.ELEMENT_NODE)
return;
for (var child = node.firstChild; child; child = child.nextSibling)
removeZeroWidthSpaceRecursive(child);
}
var attributeValue = attributeName && attributeValueElement ? this._node.getAttribute(attributeName) : undefined;
if (attributeValue !== undefined)
attributeValueElement.setTextContentTruncatedIfNeeded(attributeValue, WebInspector.UIString("<value is too large to edit>"));
// Remove zero-width spaces that were added by nodeTitleInfo.
removeZeroWidthSpaceRecursive(attribute);
var config = new WebInspector.InplaceEditor.Config(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
/**
* @param {!Event} event
* @return {string}
*/
function postKeyDownFinishHandler(event)
{
WebInspector.handleElementValueModifications(event, attribute);
return "";
}
config.setPostKeydownFinishHandler(postKeyDownFinishHandler);
this._editing = WebInspector.InplaceEditor.startEditing(attribute, config);
this.listItemElement.getComponentSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
return true;
},
/**
* @param {!Element} textNodeElement
*/
_startEditingTextNode: function(textNodeElement)
{
if (WebInspector.isBeingEdited(textNodeElement))
return true;
var textNode = this._node;
// We only show text nodes inline in elements if the element only
// has a single child, and that child is a text node.
if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild)
textNode = textNode.firstChild;
var container = textNodeElement.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (container)
container.textContent = textNode.nodeValue(); // Strip the CSS or JS highlighting if present.
var config = new WebInspector.InplaceEditor.Config(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
this._editing = WebInspector.InplaceEditor.startEditing(textNodeElement, config);
this.listItemElement.getComponentSelection().setBaseAndExtent(textNodeElement, 0, textNodeElement, 1);
return true;
},
/**
* @param {!Element=} tagNameElement
*/
_startEditingTagName: function(tagNameElement)
{
if (!tagNameElement) {
tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
if (!tagNameElement)
return false;
}
var tagName = tagNameElement.textContent;
if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
return false;
if (WebInspector.isBeingEdited(tagNameElement))
return true;
var closingTagElement = this._distinctClosingTagElement();
/**
* @param {!Event} event
*/
function keyupListener(event)
{
if (closingTagElement)
closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
}
/**
* @param {!Element} element
* @param {string} newTagName
* @this {WebInspector.ElementsTreeElement}
*/
function editingComitted(element, newTagName)
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._tagNameEditingCommitted.apply(this, arguments);
}
/**
* @this {WebInspector.ElementsTreeElement}
*/
function editingCancelled()
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._editingCancelled.apply(this, arguments);
}
tagNameElement.addEventListener('keyup', keyupListener, false);
var config = new WebInspector.InplaceEditor.Config(editingComitted.bind(this), editingCancelled.bind(this), tagName);
this._editing = WebInspector.InplaceEditor.startEditing(tagNameElement, config);
this.listItemElement.getComponentSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},
/**
* @param {function(string, string)} commitCallback
* @param {function()} disposeCallback
* @param {?Protocol.Error} error
* @param {string} initialValue
*/
_startEditingAsHTML: function(commitCallback, disposeCallback, error, initialValue)
{
if (error)
return;
if (this._editing)
return;
function consume(event)
{
if (event.eventPhase === Event.AT_TARGET)
event.consume(true);
}
initialValue = this._convertWhitespaceToEntities(initialValue).text;
this._htmlEditElement = createElement("div");
this._htmlEditElement.className = "source-code elements-tree-editor";
// Hide header items.
var child = this.listItemElement.firstChild;
while (child) {
child.style.display = "none";
child = child.nextSibling;
}
// Hide children item.
if (this._childrenListNode)
this._childrenListNode.style.display = "none";
// Append editor.
this.listItemElement.appendChild(this._htmlEditElement);
this.treeOutline.element.addEventListener("mousedown", consume, false);
this.updateSelection();
/**
* @param {!Element} element
* @param {string} newValue
* @this {WebInspector.ElementsTreeElement}
*/
function commit(element, newValue)
{
commitCallback(initialValue, newValue);
dispose.call(this);
}
/**
* @this {WebInspector.ElementsTreeElement}
*/
function dispose()
{
disposeCallback();
delete this._editing;
this.treeOutline.setMultilineEditing(null);
// Remove editor.
this.listItemElement.removeChild(this._htmlEditElement);
delete this._htmlEditElement;
// Unhide children item.
if (this._childrenListNode)
this._childrenListNode.style.removeProperty("display");
// Unhide header items.
var child = this.listItemElement.firstChild;
while (child) {
child.style.removeProperty("display");
child = child.nextSibling;
}
this.treeOutline.element.removeEventListener("mousedown", consume, false);
this.updateSelection();
this.treeOutline.focus();
}
var config = new WebInspector.InplaceEditor.Config(commit.bind(this), dispose.bind(this));
config.setMultilineOptions(initialValue, { name: "xml", htmlMode: true }, "web-inspector-html", WebInspector.moduleSetting("domWordWrap").get(), true);
WebInspector.InplaceEditor.startMultilineEditing(this._htmlEditElement, config).then(markAsBeingEdited.bind(this));
/**
* @param {!Object} controller
* @this {WebInspector.ElementsTreeElement}
*/
function markAsBeingEdited(controller)
{
this._editing = /** @type {!WebInspector.InplaceEditor.Controller} */ (controller);
this._editing.setWidth(this.treeOutline.visibleWidth());
this.treeOutline.setMultilineEditing(this._editing);
}
},
_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
delete this._editing;
var treeOutline = this.treeOutline;
/**
* @param {?Protocol.Error=} error
* @this {WebInspector.ElementsTreeElement}
*/
function moveToNextAttributeIfNeeded(error)
{
if (error)
this._editingCancelled(element, attributeName);
if (!moveDirection)
return;
treeOutline.runPendingUpdates();
// Search for the attribute's position, and then decide where to move to.
var attributes = this._node.attributes();
for (var i = 0; i < attributes.length; ++i) {
if (attributes[i].name !== attributeName)
continue;
if (moveDirection === "backward") {
if (i === 0)
this._startEditingTagName();
else
this._triggerEditAttribute(attributes[i - 1].name);
} else {
if (i === attributes.length - 1)
this._addNewAttribute();
else
this._triggerEditAttribute(attributes[i + 1].name);
}
return;
}
// Moving From the "New Attribute" position.
if (moveDirection === "backward") {
if (newText === " ") {
// Moving from "New Attribute" that was not edited
if (attributes.length > 0)
this._triggerEditAttribute(attributes[attributes.length - 1].name);
} else {
// Moving from "New Attribute" that holds new value
if (attributes.length > 1)
this._triggerEditAttribute(attributes[attributes.length - 2].name);
}
} else if (moveDirection === "forward") {
if (!newText.isWhitespace())
this._addNewAttribute();
else
this._startEditingTagName();
}
}
if ((attributeName.trim() || newText.trim()) && oldText !== newText) {
this._node.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
return;
}
this.updateTitle();
moveToNextAttributeIfNeeded.call(this);
},
_tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
{
delete this._editing;
var self = this;
function cancel()
{
var closingTagElement = self._distinctClosingTagElement();
if (closingTagElement)
closingTagElement.textContent = "</" + tagName + ">";
self._editingCancelled(element, tagName);
moveToNextAttributeIfNeeded.call(self);
}
/**
* @this {WebInspector.ElementsTreeElement}
*/
function moveToNextAttributeIfNeeded()
{
if (moveDirection !== "forward") {
this._addNewAttribute();
return;
}
var attributes = this._node.attributes();
if (attributes.length > 0)
this._triggerEditAttribute(attributes[0].name);
else
this._addNewAttribute();
}
newText = newText.trim();
if (newText === oldText) {
cancel();
return;
}
var treeOutline = this.treeOutline;
var wasExpanded = this.expanded;
function changeTagNameCallback(error, nodeId)
{
if (error || !nodeId) {
cancel();
return;
}
var newTreeItem = treeOutline.selectNodeAfterEdit(wasExpanded, error, nodeId);
moveToNextAttributeIfNeeded.call(newTreeItem);
}
this._node.setNodeName(newText, changeTagNameCallback);
},
/**
* @param {!WebInspector.DOMNode} textNode
* @param {!Element} element
* @param {string} newText
*/
_textNodeEditingCommitted: function(textNode, element, newText)
{
delete this._editing;
/**
* @this {WebInspector.ElementsTreeElement}
*/
function callback()
{
this.updateTitle();
}
textNode.setNodeValue(newText, callback.bind(this));
},
/**
* @param {!Element} element
* @param {*} context
*/
_editingCancelled: function(element, context)
{
delete this._editing;
// Need to restore attributes structure.
this.updateTitle();
},
/**
* @return {!Element}
*/
_distinctClosingTagElement: function()
{
// FIXME: Improve the Tree Element / Outline Abstraction to prevent crawling the DOM
// For an expanded element, it will be the last element with class "close"
// in the child element list.
if (this.expanded) {
var closers = this._childrenListNode.querySelectorAll(".close");
return closers[closers.length-1];
}
// Remaining cases are single line non-expanded elements with a closing
// tag, or HTML elements without a closing tag (such as <br>). Return
// null in the case where there isn't a closing tag.
var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
return (tags.length === 1 ? null : tags[tags.length-1]);
},
/**
* @param {?WebInspector.ElementsTreeOutline.UpdateRecord=} updateRecord
* @param {boolean=} onlySearchQueryChanged
*/
updateTitle: function(updateRecord, onlySearchQueryChanged)
{
// If we are editing, return early to prevent canceling the edit.
// After editing is committed updateTitle will be called.
if (this._editing)
return;
if (onlySearchQueryChanged) {
this._hideSearchHighlight();
} else {
var nodeInfo = this._nodeTitleInfo(updateRecord || null);
if (this._node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE && this._node.isInShadowTree() && this._node.shadowRootType()) {
this.childrenListElement.classList.add("shadow-root");
var depth = 4;
for (var node = this._node; depth && node; node = node.parentNode) {
if (node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE)
depth--;
}
if (!depth)
this.childrenListElement.classList.add("shadow-root-deep");
else
this.childrenListElement.classList.add("shadow-root-depth-" + depth);
}
var highlightElement = createElement("span");
highlightElement.className = "highlight";
highlightElement.appendChild(nodeInfo);
this.title = highlightElement;
this.updateDecorations();
this.listItemElement.insertBefore(this._gutterContainer, this.listItemElement.firstChild);
delete this._highlightResult;
}
delete this.selectionElement;
if (this.selected)
this.updateSelection();
this._preventFollowingLinksOnDoubleClick();
this._highlightSearchResults();
},
updateDecorations: function()
{
var treeElement = this.parent;
var depth = 0;
while (treeElement != null) {
depth++;
treeElement = treeElement.parent;
}
/** Keep it in sync with elementsTreeOutline.css **/
if (Runtime.experiments.isEnabled("reducedIndentation"))
this._gutterContainer.style.left = (-8 * (depth - 2) - (this.isExpandable() ? -2 : 8)) + "px";
else
this._gutterContainer.style.left = (-12 * (depth - 2) - (this.isExpandable() ? 1 : 12)) + "px";
if (this.isClosingTag())
return;
var node = this._node;
if (node.nodeType() !== Node.ELEMENT_NODE)
return;
if (!this.treeOutline._decoratorExtensions)
/** @type {!Array.<!Runtime.Extension>} */
this.treeOutline._decoratorExtensions = runtime.extensions(WebInspector.DOMPresentationUtils.MarkerDecorator);
var markerToExtension = new Map();
for (var i = 0; i < this.treeOutline._decoratorExtensions.length; ++i)
markerToExtension.set(this.treeOutline._decoratorExtensions[i].descriptor()["marker"], this.treeOutline._decoratorExtensions[i]);
var promises = [];
var decorations = [];
var descendantDecorations = [];
node.traverseMarkers(visitor);
/**
* @param {!WebInspector.DOMNode} n
* @param {string} marker
*/
function visitor(n, marker)
{
var extension = markerToExtension.get(marker);
if (!extension)
return;
promises.push(extension.instancePromise().then(collectDecoration.bind(null, n)));
}
/**
* @param {!WebInspector.DOMNode} n
* @param {!WebInspector.DOMPresentationUtils.MarkerDecorator} decorator
*/
function collectDecoration(n, decorator)
{
var decoration = decorator.decorate(n);
if (!decoration)
return;
(n === node ? decorations : descendantDecorations).push(decoration);
}
Promise.all(promises).then(updateDecorationsUI.bind(this));
/**
* @this {WebInspector.ElementsTreeElement}
*/
function updateDecorationsUI()
{
this._decorationsElement.removeChildren();
this._decorationsElement.classList.add("hidden");
this._gutterContainer.classList.toggle("has-decorations", decorations.length || descendantDecorations.length);
if (!decorations.length && !descendantDecorations.length)
return;
var colors = new Set();
var titles = createElement("div");
for (var decoration of decorations) {
var titleElement = titles.createChild("div");
titleElement.textContent = decoration.title;
colors.add(decoration.color);
}
if (this.expanded && !decorations.length)
return;
var descendantColors = new Set();
if (descendantDecorations.length) {
var element = titles.createChild("div");
element.textContent = WebInspector.UIString("Children:");
for (var decoration of descendantDecorations) {
element = titles.createChild("div");
element.style.marginLeft = "15px";
element.textContent = decoration.title;
descendantColors.add(decoration.color);
}
}
var offset = 0;
processColors.call(this, colors, "elements-gutter-decoration");
if (!this.expanded)
processColors.call(this, descendantColors, "elements-gutter-decoration elements-has-decorated-children");
WebInspector.Tooltip.install(this._decorationsElement, titles);
/**
* @param {!Set<string>} colors
* @param {string} className
* @this {WebInspector.ElementsTreeElement}
*/
function processColors(colors, className)
{
for (var color of colors) {
var child = this._decorationsElement.createChild("div", className);
this._decorationsElement.classList.remove("hidden");
child.style.backgroundColor = color;
child.style.borderColor = color;
if (offset)
child.style.marginLeft = offset + "px";
offset += 3;
}
}
}
},
/**
* @param {!Node} parentElement
* @param {string} name
* @param {string} value
* @param {?WebInspector.ElementsTreeOutline.UpdateRecord} updateRecord
* @param {boolean=} forceValue
* @param {!WebInspector.DOMNode=} node
*/
_buildAttributeDOM: function(parentElement, name, value, updateRecord, forceValue, node)
{
var closingPunctuationRegex = /[\/;:\)\]\}]/g;
var highlightIndex = 0;
var highlightCount;
var additionalHighlightOffset = 0;
var result;
/**
* @param {string} match
* @param {number} replaceOffset
* @return {string}
*/
function replacer(match, replaceOffset) {
while (highlightIndex < highlightCount && result.entityRanges[highlightIndex].offset < replaceOffset) {
result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
++highlightIndex;
}
additionalHighlightOffset += 1;
return match + "\u200B";
}
/**
* @param {!Element} element
* @param {string} value
* @this {WebInspector.ElementsTreeElement}
*/
function setValueWithEntities(element, value)
{
result = this._convertWhitespaceToEntities(value);
highlightCount = result.entityRanges.length;
value = result.text.replace(closingPunctuationRegex, replacer);
while (highlightIndex < highlightCount) {
result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
++highlightIndex;
}
element.setTextContentTruncatedIfNeeded(value);
WebInspector.highlightRangesWithStyleClass(element, result.entityRanges, "webkit-html-entity-value");
}
var hasText = (forceValue || value.length > 0);
var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
attrNameElement.textContent = name;
if (hasText)
attrSpanElement.createTextChild("=\u200B\"");
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
if (updateRecord && updateRecord.isAttributeModified(name))
WebInspector.runCSSAnimationOnce(hasText ? attrValueElement : attrNameElement, "dom-update-highlight");
/**
* @this {WebInspector.ElementsTreeElement}
* @param {string} value
* @return {!Element}
*/
function linkifyValue(value)
{
var rewrittenHref = node.resolveURL(value);
if (rewrittenHref === null) {
var span = createElement("span");
setValueWithEntities.call(this, span, value);
return span;
}
value = value.replace(closingPunctuationRegex, "$&\u200B");
if (value.startsWith("data:"))
value = value.trimMiddle(60);
var anchor = WebInspector.linkifyURLAsNode(rewrittenHref, value, "", node.nodeName().toLowerCase() === "a");
anchor.preventFollow = true;
return anchor;
}
if (node && name === "src" || name === "href") {
attrValueElement.appendChild(linkifyValue.call(this, value));
} else if (node && node.nodeName().toLowerCase() === "img" && name === "srcset") {
var sources = value.split(",");
for (var i = 0; i < sources.length; ++i) {
if (i > 0)
attrValueElement.createTextChild(", ");
var source = sources[i].trim();
var indexOfSpace = source.indexOf(" ");
var url = source.substring(0, indexOfSpace);
var tail = source.substring(indexOfSpace);
attrValueElement.appendChild(linkifyValue.call(this, url));
attrValueElement.createTextChild(tail);
}
} else {
setValueWithEntities.call(this, attrValueElement, value);
}
if (hasText)
attrSpanElement.createTextChild("\"");
},
/**
* @param {!Node} parentElement
* @param {string} pseudoElementName
*/
_buildPseudoElementDOM: function(parentElement, pseudoElementName)
{
var pseudoElement = parentElement.createChild("span", "webkit-html-pseudo-element");
pseudoElement.textContent = "::" + pseudoElementName;
parentElement.createTextChild("\u200B");
},
/**
* @param {!Node} parentElement
* @param {string} tagName
* @param {boolean} isClosingTag
* @param {boolean} isDistinctTreeElement
* @param {?WebInspector.ElementsTreeOutline.UpdateRecord} updateRecord
*/
_buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, updateRecord)
{
var node = this._node;
var classes = [ "webkit-html-tag" ];
if (isClosingTag && isDistinctTreeElement)
classes.push("close");
var tagElement = parentElement.createChild("span", classes.join(" "));
tagElement.createTextChild("<");
var tagNameElement = tagElement.createChild("span", isClosingTag ? "webkit-html-close-tag-name" : "webkit-html-tag-name");
tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
if (!isClosingTag) {
if (node.hasAttributes()) {
var attributes = node.attributes();
for (var i = 0; i < attributes.length; ++i) {
var attr = attributes[i];
tagElement.createTextChild(" ");
this._buildAttributeDOM(tagElement, attr.name, attr.value, updateRecord, false, node);
}
}
if (updateRecord) {
var hasUpdates = updateRecord.hasRemovedAttributes() || updateRecord.hasRemovedChildren();
hasUpdates |= !this.expanded && updateRecord.hasChangedChildren();
if (hasUpdates)
WebInspector.runCSSAnimationOnce(tagNameElement, "dom-update-highlight");
}
}
tagElement.createTextChild(">");
parentElement.createTextChild("\u200B");
},
/**
* @param {string} text
* @return {!{text: string, entityRanges: !Array.<!WebInspector.SourceRange>}}
*/
_convertWhitespaceToEntities: function(text)
{
var result = "";
var lastIndexAfterEntity = 0;
var entityRanges = [];
var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
for (var i = 0, size = text.length; i < size; ++i) {
var char = text.charAt(i);
if (charToEntity[char]) {
result += text.substring(lastIndexAfterEntity, i);
var entityValue = "&" + charToEntity[char] + ";";
entityRanges.push({offset: result.length, length: entityValue.length});
result += entityValue;
lastIndexAfterEntity = i + 1;
}
}
if (result)
result += text.substring(lastIndexAfterEntity);
return {text: result || text, entityRanges: entityRanges};
},
/**
* @param {?WebInspector.ElementsTreeOutline.UpdateRecord} updateRecord
* @return {!DocumentFragment} result
*/
_nodeTitleInfo: function(updateRecord)
{
var node = this._node;
var titleDOM = createDocumentFragment();
switch (node.nodeType()) {
case Node.ATTRIBUTE_NODE:
this._buildAttributeDOM(titleDOM, /** @type {string} */ (node.name), /** @type {string} */ (node.value), updateRecord, true);
break;
case Node.ELEMENT_NODE:
var pseudoType = node.pseudoType();
if (pseudoType) {
this._buildPseudoElementDOM(titleDOM, pseudoType);
break;
}
var tagName = node.nodeNameInCorrectCase();
if (this._elementCloseTag) {
this._buildTagDOM(titleDOM, tagName, true, true, updateRecord);
break;
}
this._buildTagDOM(titleDOM, tagName, false, false, updateRecord);
if (this.isExpandable()) {
if (!this.expanded) {
var textNodeElement = titleDOM.createChild("span", "webkit-html-text-node bogus");
textNodeElement.textContent = "\u2026";
titleDOM.createTextChild("\u200B");
this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
}
break;
}
if (WebInspector.ElementsTreeElement.canShowInlineText(node)) {
var textNodeElement = titleDOM.createChild("span", "webkit-html-text-node");
var result = this._convertWhitespaceToEntities(node.firstChild.nodeValue());
textNodeElement.textContent = result.text;
WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
titleDOM.createTextChild("\u200B");
this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
if (updateRecord && updateRecord.hasChangedChildren())
WebInspector.runCSSAnimationOnce(textNodeElement, "dom-update-highlight");
if (updateRecord && updateRecord.isCharDataModified())
WebInspector.runCSSAnimationOnce(textNodeElement, "dom-update-highlight");
break;
}
if (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName])
this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
break;
case Node.TEXT_NODE:
if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
var newNode = titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node");
newNode.textContent = node.nodeValue();
var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
javascriptSyntaxHighlighter.syntaxHighlightNode(newNode).then(updateSearchHighlight.bind(this));
} else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") {
var newNode = titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node");
newNode.textContent = node.nodeValue();
var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true);
cssSyntaxHighlighter.syntaxHighlightNode(newNode).then(updateSearchHighlight.bind(this));
} else {
titleDOM.createTextChild("\"");
var textNodeElement = titleDOM.createChild("span", "webkit-html-text-node");
var result = this._convertWhitespaceToEntities(node.nodeValue());
textNodeElement.textContent = result.text;
WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
titleDOM.createTextChild("\"");
if (updateRecord && updateRecord.isCharDataModified())
WebInspector.runCSSAnimationOnce(textNodeElement, "dom-update-highlight");
}
break;
case Node.COMMENT_NODE:
var commentElement = titleDOM.createChild("span", "webkit-html-comment");
commentElement.createTextChild("<!--" + node.nodeValue() + "-->");
break;
case Node.DOCUMENT_TYPE_NODE:
var docTypeElement = titleDOM.createChild("span", "webkit-html-doctype");
docTypeElement.createTextChild("<!DOCTYPE " + node.nodeName());
if (node.publicId) {
docTypeElement.createTextChild(" PUBLIC \"" + node.publicId + "\"");
if (node.systemId)
docTypeElement.createTextChild(" \"" + node.systemId + "\"");
} else if (node.systemId)
docTypeElement.createTextChild(" SYSTEM \"" + node.systemId + "\"");
if (node.internalSubset)
docTypeElement.createTextChild(" [" + node.internalSubset + "]");
docTypeElement.createTextChild(">");
break;
case Node.CDATA_SECTION_NODE:
var cdataElement = titleDOM.createChild("span", "webkit-html-text-node");
cdataElement.createTextChild("<![CDATA[" + node.nodeValue() + "]]>");
break;
case Node.DOCUMENT_FRAGMENT_NODE:
var fragmentElement = titleDOM.createChild("span", "webkit-html-fragment");
fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
break;
default:
titleDOM.createTextChild(node.nodeNameInCorrectCase().collapseWhitespace());
}
/**
* @this {WebInspector.ElementsTreeElement}
*/
function updateSearchHighlight()
{
delete this._highlightResult;
this._highlightSearchResults();
}
return titleDOM;
},
remove: function()
{
if (this._node.pseudoType())
return;
var parentElement = this.parent;
if (!parentElement)
return;
if (!this._node.parentNode || this._node.parentNode.nodeType() === Node.DOCUMENT_NODE)
return;
this._node.removeNode();
},
/**
* @param {function(boolean)=} callback
* @param {boolean=} startEditing
*/
toggleEditAsHTML: function(callback, startEditing)
{
if (this._editing && this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement)) {
this._editing.commit();
return;
}
if (startEditing === false)
return;
/**
* @param {?Protocol.Error} error
*/
function selectNode(error)
{
if (callback)
callback(!error);
}
/**
* @param {string} initialValue
* @param {string} value
*/
function commitChange(initialValue, value)
{
if (initialValue !== value)
node.setOuterHTML(value, selectNode);
}
function disposeCallback()
{
if (callback)
callback(false);
}
var node = this._node;
node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange, disposeCallback));
},
_copyCSSPath: function()
{
InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath(this._node, true));
},
_copyXPath: function()
{
InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(this._node, true));
},
_highlightSearchResults: function()
{
if (!this._searchQuery || !this._searchHighlightsVisible)
return;
this._hideSearchHighlight();
var text = this.listItemElement.textContent;
var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi");
var match = regexObject.exec(text);
var matchRanges = [];
while (match) {
matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
match = regexObject.exec(text);
}
// Fall back for XPath, etc. matches.
if (!matchRanges.length)
matchRanges.push(new WebInspector.SourceRange(0, text.length));
this._highlightResult = [];
WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
},
_scrollIntoView: function()
{
function scrollIntoViewCallback(object)
{
/**
* @suppressReceiverCheck
* @this {!Element}
*/
function scrollIntoView()
{
this.scrollIntoViewIfNeeded(true);
}
if (object)
object.callFunction(scrollIntoView);
}
this._node.resolveToObject("", scrollIntoViewCallback);
},
_editAsHTML: function ()
{
var promise = WebInspector.Revealer.revealPromise(this.node());
promise.then(() => WebInspector.actionRegistry.action("elements.edit-as-html").execute());
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 2 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.ElementsTreeOutline} treeOutline
*/
WebInspector.ElementsTreeElementHighlighter = function(treeOutline)
{
this._throttler = new WebInspector.Throttler(100);
this._treeOutline = treeOutline;
this._treeOutline.addEventListener(TreeOutline.Events.ElementExpanded, this._clearState, this);
this._treeOutline.addEventListener(TreeOutline.Events.ElementCollapsed, this._clearState, this);
this._treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._clearState, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeHighlightedInOverlay, this._highlightNode, this);
this._treeOutline.domModel().addEventListener(WebInspector.DOMModel.Events.InspectModeWillBeToggled, this._clearState, this);
}
WebInspector.ElementsTreeElementHighlighter.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_highlightNode: function(event)
{
if (!WebInspector.moduleSetting("highlightNodeOnHoverInOverlay").get())
return;
var domNode = /** @type {!WebInspector.DOMNode} */ (event.data);
this._throttler.schedule(callback.bind(this));
this._pendingHighlightNode = this._treeOutline.domModel() === domNode.domModel() ? domNode : null;
/**
* @this {WebInspector.ElementsTreeElementHighlighter}
*/
function callback()
{
this._highlightNodeInternal(this._pendingHighlightNode);
delete this._pendingHighlightNode;
return Promise.resolve();
}
},
/**
* @param {?WebInspector.DOMNode} node
*/
_highlightNodeInternal: function(node)
{
this._isModifyingTreeOutline = true;
var treeElement = null;
if (this._currentHighlightedElement) {
var currentTreeElement = this._currentHighlightedElement;
while (currentTreeElement !== this._alreadyExpandedParentElement) {
if (currentTreeElement.expanded)
currentTreeElement.collapse();
currentTreeElement = currentTreeElement.parent;
}
}
delete this._currentHighlightedElement;
delete this._alreadyExpandedParentElement;
if (node) {
var deepestExpandedParent = node;
var treeElementSymbol = this._treeOutline.treeElementSymbol();
while (deepestExpandedParent && (!deepestExpandedParent[treeElementSymbol] || !deepestExpandedParent[treeElementSymbol].expanded))
deepestExpandedParent = deepestExpandedParent.parentNode;
this._alreadyExpandedParentElement = deepestExpandedParent ? deepestExpandedParent[treeElementSymbol] : this._treeOutline.rootElement();
treeElement = this._treeOutline.createTreeElementFor(node);
}
this._currentHighlightedElement = treeElement;
this._treeOutline.setHoverEffect(treeElement);
if (treeElement)
treeElement.reveal();
this._isModifyingTreeOutline = false;
},
_clearState: function()
{
if (this._isModifyingTreeOutline)
return;
delete this._currentHighlightedElement;
delete this._alreadyExpandedParentElement;
delete this._pendingHighlightNode;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 | 2 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {TreeOutline}
* @param {!WebInspector.DOMModel} domModel
* @param {boolean=} omitRootDOMNode
* @param {boolean=} selectEnabled
*/
WebInspector.ElementsTreeOutline = function(domModel, omitRootDOMNode, selectEnabled)
{
this._domModel = domModel;
this._treeElementSymbol = Symbol("treeElement");
var element = createElement("div");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(element, "elements/elementsTreeOutline.css");
var outlineDisclosureElement = this._shadowRoot.createChild("div", "elements-disclosure");
if (Runtime.experiments.isEnabled("reducedIndentation"))
outlineDisclosureElement.classList.add("elements-reduced-indentation");
TreeOutline.call(this);
this._element = this.element;
this._element.classList.add("elements-tree-outline", "source-code");
this._element.addEventListener("mousedown", this._onmousedown.bind(this), false);
this._element.addEventListener("mousemove", this._onmousemove.bind(this), false);
this._element.addEventListener("mouseleave", this._onmouseleave.bind(this), false);
this._element.addEventListener("dragstart", this._ondragstart.bind(this), false);
this._element.addEventListener("dragover", this._ondragover.bind(this), false);
this._element.addEventListener("dragleave", this._ondragleave.bind(this), false);
this._element.addEventListener("drop", this._ondrop.bind(this), false);
this._element.addEventListener("dragend", this._ondragend.bind(this), false);
this._element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false);
outlineDisclosureElement.appendChild(this._element);
this.element = element;
this._includeRootDOMNode = !omitRootDOMNode;
this._selectEnabled = selectEnabled;
/** @type {?WebInspector.DOMNode} */
this._rootDOMNode = null;
/** @type {?WebInspector.DOMNode} */
this._selectedDOMNode = null;
this._visible = false;
this._popoverHelper = new WebInspector.PopoverHelper(this._element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
this._popoverHelper.setTimeout(0, 100);
/** @type {!Map<!WebInspector.DOMNode, !WebInspector.ElementsTreeOutline.UpdateRecord>} */
this._updateRecords = new Map();
/** @type {!Set<!WebInspector.ElementsTreeElement>} */
this._treeElementsBeingUpdated = new Set();
this._domModel.addEventListener(WebInspector.DOMModel.Events.MarkersChanged, this._markersChanged, this);
}
/** @typedef {{node: !WebInspector.DOMNode, isCut: boolean}} */
WebInspector.ElementsTreeOutline.ClipboardData;
/**
* @enum {string}
*/
WebInspector.ElementsTreeOutline.Events = {
SelectedNodeChanged: "SelectedNodeChanged",
ElementsTreeUpdated: "ElementsTreeUpdated"
}
/**
* @const
* @type {!Object.<string, string>}
*/
WebInspector.ElementsTreeOutline.MappedCharToEntity = {
"\u00a0": "nbsp",
"\u0093": "#147", // <control>
"\u00ad": "shy",
"\u2002": "ensp",
"\u2003": "emsp",
"\u2009": "thinsp",
"\u200a": "#8202", // Hairspace
"\u200b": "#8203", // ZWSP
"\u200c": "zwnj",
"\u200d": "zwj",
"\u200e": "lrm",
"\u200f": "rlm",
"\u202a": "#8234", // LRE
"\u202b": "#8235", // RLE
"\u202c": "#8236", // PDF
"\u202d": "#8237", // LRO
"\u202e": "#8238", // RLO
"\ufeff": "#65279" // BOM
}
WebInspector.ElementsTreeOutline.prototype = {
/**
* @return {symbol}
*/
treeElementSymbol: function()
{
return this._treeElementSymbol;
},
focus: function()
{
this._element.focus();
},
/**
* @return {boolean}
*/
hasFocus: function()
{
return this._element === WebInspector.currentFocusElement();
},
/**
* @param {boolean} wrap
*/
setWordWrap: function(wrap)
{
this._element.classList.toggle("elements-tree-nowrap", !wrap);
},
/**
* @return {!WebInspector.DOMModel}
*/
domModel: function()
{
return this._domModel;
},
/**
* @param {?WebInspector.InplaceEditor.Controller} multilineEditing
*/
setMultilineEditing: function(multilineEditing)
{
this._multilineEditing = multilineEditing;
},
/**
* @return {number}
*/
visibleWidth: function()
{
return this._visibleWidth;
},
/**
* @param {number} width
*/
setVisibleWidth: function(width)
{
this._visibleWidth = width;
if (this._multilineEditing)
this._multilineEditing.setWidth(this._visibleWidth);
},
/**
* @param {?WebInspector.ElementsTreeOutline.ClipboardData} data
*/
_setClipboardData: function(data)
{
if (this._clipboardNodeData) {
var treeElement = this.findTreeElement(this._clipboardNodeData.node);
if (treeElement)
treeElement.setInClipboard(false);
delete this._clipboardNodeData;
}
if (data) {
var treeElement = this.findTreeElement(data.node);
if (treeElement)
treeElement.setInClipboard(true);
this._clipboardNodeData = data;
}
},
/**
* @param {!WebInspector.DOMNode} removedNode
*/
resetClipboardIfNeeded: function(removedNode)
{
if (this._clipboardNodeData && this._clipboardNodeData.node === removedNode)
this._setClipboardData(null);
},
/**
* @param {boolean} isCut
* @param {!Event} event
*/
handleCopyOrCutKeyboardEvent: function(isCut, event)
{
this._setClipboardData(null);
// Don't prevent the normal copy if the user has a selection.
if (!event.target.isComponentSelectionCollapsed())
return;
// Do not interfere with text editing.
if (WebInspector.isEditing())
return;
var targetNode = this.selectedDOMNode();
if (!targetNode)
return;
event.clipboardData.clearData();
event.preventDefault();
this.performCopyOrCut(isCut, targetNode);
},
/**
* @param {boolean} isCut
* @param {?WebInspector.DOMNode} node
*/
performCopyOrCut: function(isCut, node)
{
if (isCut && (node.isShadowRoot() || node.ancestorUserAgentShadowRoot()))
return;
node.copyNode();
this._setClipboardData({ node: node, isCut: isCut });
},
/**
* @param {!WebInspector.DOMNode} targetNode
* @return {boolean}
*/
canPaste: function(targetNode)
{
if (targetNode.isShadowRoot() || targetNode.ancestorUserAgentShadowRoot())
return false;
if (!this._clipboardNodeData)
return false;
var node = this._clipboardNodeData.node;
if (this._clipboardNodeData.isCut && (node === targetNode || node.isAncestor(targetNode)))
return false;
if (targetNode.target() !== node.target())
return false;
return true;
},
/**
* @param {!WebInspector.DOMNode} targetNode
*/
pasteNode: function(targetNode)
{
if (this.canPaste(targetNode))
this._performPaste(targetNode);
},
/**
* @param {!Event} event
*/
handlePasteKeyboardEvent: function(event)
{
// Do not interfere with text editing.
if (WebInspector.isEditing())
return;
var targetNode = this.selectedDOMNode();
if (!targetNode || !this.canPaste(targetNode))
return;
event.preventDefault();
this._performPaste(targetNode);
},
/**
* @param {!WebInspector.DOMNode} targetNode
*/
_performPaste: function(targetNode)
{
if (this._clipboardNodeData.isCut) {
this._clipboardNodeData.node.moveTo(targetNode, null, expandCallback.bind(this));
this._setClipboardData(null);
} else {
this._clipboardNodeData.node.copyTo(targetNode, null, expandCallback.bind(this));
}
/**
* @param {?Protocol.Error} error
* @param {!DOMAgent.NodeId} nodeId
* @this {WebInspector.ElementsTreeOutline}
*/
function expandCallback(error, nodeId)
{
if (error)
return;
var pastedNode = this._domModel.nodeForId(nodeId);
if (!pastedNode)
return;
this.selectDOMNode(pastedNode);
}
},
/**
* @param {boolean} visible
*/
setVisible: function(visible)
{
this._visible = visible;
if (!this._visible) {
this._popoverHelper.hidePopover();
if (this._multilineEditing)
this._multilineEditing.cancel();
return;
}
this.runPendingUpdates();
if (this._selectedDOMNode)
this._revealAndSelectNode(this._selectedDOMNode, false);
},
get rootDOMNode()
{
return this._rootDOMNode;
},
set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;
this._rootDOMNode = x;
this._isXMLMimeType = x && x.isXMLNode();
this.update();
},
get isXMLMimeType()
{
return this._isXMLMimeType;
},
/**
* @return {?WebInspector.DOMNode}
*/
selectedDOMNode: function()
{
return this._selectedDOMNode;
},
/**
* @param {?WebInspector.DOMNode} node
* @param {boolean=} focus
*/
selectDOMNode: function(node, focus)
{
if (this._selectedDOMNode === node) {
this._revealAndSelectNode(node, !focus);
return;
}
this._selectedDOMNode = node;
this._revealAndSelectNode(node, !focus);
// The _revealAndSelectNode() method might find a different element if there is inlined text,
// and the select() call would change the selectedDOMNode and reenter this setter. So to
// avoid calling _selectedNodeChanged() twice, first check if _selectedDOMNode is the same
// node as the one passed in.
if (this._selectedDOMNode === node)
this._selectedNodeChanged();
},
/**
* @return {boolean}
*/
editing: function()
{
var node = this.selectedDOMNode();
if (!node)
return false;
var treeElement = this.findTreeElement(node);
if (!treeElement)
return false;
return treeElement.isEditing() || false;
},
update: function()
{
var selectedTreeElement = this.selectedTreeElement;
if (!(selectedTreeElement instanceof WebInspector.ElementsTreeElement))
selectedTreeElement = null;
var selectedNode = selectedTreeElement ? selectedTreeElement.node() : null;
this.removeChildren();
if (!this.rootDOMNode)
return;
var treeElement;
if (this._includeRootDOMNode) {
treeElement = this._createElementTreeElement(this.rootDOMNode);
this.appendChild(treeElement);
} else {
// FIXME: this could use findTreeElement to reuse a tree element if it already exists
var node = this.rootDOMNode.firstChild;
while (node) {
treeElement = this._createElementTreeElement(node);
this.appendChild(treeElement);
node = node.nextSibling;
}
}
if (selectedNode)
this._revealAndSelectNode(selectedNode, true);
},
updateSelection: function()
{
if (!this.selectedTreeElement)
return;
var element = this.selectedTreeElement;
element.updateSelection();
},
_selectedNodeChanged: function()
{
this.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode);
},
/**
* @param {!Array.<!WebInspector.DOMNode>} nodes
*/
_fireElementsTreeUpdated: function(nodes)
{
this.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.ElementsTreeUpdated, nodes);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {?WebInspector.ElementsTreeElement}
*/
findTreeElement: function(node)
{
var treeElement = this._lookUpTreeElement(node);
if (!treeElement && node.nodeType() === Node.TEXT_NODE) {
// The text node might have been inlined if it was short, so try to find the parent element.
treeElement = this._lookUpTreeElement(node.parentNode);
}
return /** @type {?WebInspector.ElementsTreeElement} */ (treeElement);
},
/**
* @param {?WebInspector.DOMNode} node
* @return {?TreeElement}
*/
_lookUpTreeElement: function(node)
{
if (!node)
return null;
var cachedElement = node[this._treeElementSymbol];
if (cachedElement)
return cachedElement;
// Walk up the parent pointers from the desired node
var ancestors = [];
for (var currentNode = node.parentNode; currentNode; currentNode = currentNode.parentNode) {
ancestors.push(currentNode);
if (currentNode[this._treeElementSymbol]) // stop climbing as soon as we hit
break;
}
if (!currentNode)
return null;
// Walk down to populate each ancestor's children, to fill in the tree and the cache.
for (var i = ancestors.length - 1; i >= 0; --i) {
var treeElement = ancestors[i][this._treeElementSymbol];
if (treeElement)
treeElement.onpopulate(); // fill the cache with the children of treeElement
}
return node[this._treeElementSymbol];
},
/**
* @param {!WebInspector.DOMNode} node
* @return {?WebInspector.ElementsTreeElement}
*/
createTreeElementFor: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
return treeElement;
if (!node.parentNode)
return null;
treeElement = this.createTreeElementFor(node.parentNode);
return treeElement ? this._showChild(treeElement, node) : null;
},
set suppressRevealAndSelect(x)
{
if (this._suppressRevealAndSelect === x)
return;
this._suppressRevealAndSelect = x;
},
/**
* @param {?WebInspector.DOMNode} node
* @param {boolean} omitFocus
*/
_revealAndSelectNode: function(node, omitFocus)
{
if (this._suppressRevealAndSelect)
return;
if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootDOMNode)
node = this.rootDOMNode.firstChild;
if (!node)
return;
var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;
treeElement.revealAndSelect(omitFocus);
},
/**
* @return {?TreeElement}
*/
_treeElementFromEvent: function(event)
{
var scrollContainer = this.element.parentElement;
// We choose this X coordinate based on the knowledge that our list
// items extend at least to the right edge of the outer <ol> container.
// In the no-word-wrap mode the outer <ol> may be wider than the tree container
// (and partially hidden), in which case we are left to use only its right boundary.
var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;
var y = event.pageY;
// Our list items have 1-pixel cracks between them vertically. We avoid
// the cracks by checking slightly above and slightly below the mouse
// and seeing if we hit the same element each time.
var elementUnderMouse = this.treeElementFromPoint(x, y);
var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
var element;
if (elementUnderMouse === elementAboveMouse)
element = elementUnderMouse;
else
element = this.treeElementFromPoint(x, y + 2);
return element;
},
/**
* @param {!Element} element
* @param {!Event} event
* @return {!Element|!AnchorBox|undefined}
*/
_getPopoverAnchor: function(element, event)
{
var anchor = element.enclosingNodeOrSelfWithClass("webkit-html-resource-link");
if (!anchor || !anchor.href)
return;
return anchor;
},
/**
* @param {!WebInspector.DOMNode} node
* @param {function()} callback
*/
_loadDimensionsForNode: function(node, callback)
{
if (!node.nodeName() || node.nodeName().toLowerCase() !== "img") {
callback();
return;
}
node.resolveToObject("", resolvedNode);
function resolvedNode(object)
{
if (!object) {
callback();
return;
}
object.callFunctionJSON(features, undefined, callback);
object.release();
/**
* @return {!{offsetWidth: number, offsetHeight: number, naturalWidth: number, naturalHeight: number, currentSrc: (string|undefined)}}
* @suppressReceiverCheck
* @this {!Element}
*/
function features()
{
return { offsetWidth: this.offsetWidth, offsetHeight: this.offsetHeight, naturalWidth: this.naturalWidth, naturalHeight: this.naturalHeight, currentSrc: this.currentSrc };
}
}
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showPopover: function(anchor, popover)
{
var listItem = anchor.enclosingNodeOrSelfWithNodeName("li");
var node = /** @type {!WebInspector.ElementsTreeElement} */ (listItem.treeElement).node();
this._loadDimensionsForNode(node, WebInspector.DOMPresentationUtils.buildImagePreviewContents.bind(WebInspector.DOMPresentationUtils, node.target(), anchor.href, true, showPopover));
/**
* @param {!Element=} contents
*/
function showPopover(contents)
{
if (!contents)
return;
popover.setCanShrink(false);
popover.showForAnchor(contents, anchor);
}
},
_onmousedown: function(event)
{
var element = this._treeElementFromEvent(event);
if (!element || element.isEventWithinDisclosureTriangle(event))
return;
element.select();
},
/**
* @param {?TreeElement} treeElement
*/
setHoverEffect: function (treeElement)
{
if (this._previousHoveredElement === treeElement)
return;
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
if (treeElement) {
treeElement.hovered = true;
this._previousHoveredElement = treeElement;
}
},
_onmousemove: function(event)
{
var element = this._treeElementFromEvent(event);
if (element && this._previousHoveredElement === element)
return;
this.setHoverEffect(element);
if (element instanceof WebInspector.ElementsTreeElement) {
this._domModel.highlightDOMNodeWithConfig(element.node().id, { mode: "all", showInfo: !WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) });
return;
}
if (element instanceof WebInspector.ElementsTreeOutline.ShortcutTreeElement)
this._domModel.highlightDOMNodeWithConfig(undefined, { mode: "all", showInfo: !WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) }, element.backendNodeId());
},
_onmouseleave: function(event)
{
this.setHoverEffect(null);
WebInspector.DOMModel.hideDOMNodeHighlight();
},
_ondragstart: function(event)
{
if (!event.target.isComponentSelectionCollapsed())
return false;
if (event.target.nodeName === "A")
return false;
var treeElement = this._treeElementFromEvent(event);
if (!this._isValidDragSourceOrTarget(treeElement))
return false;
if (treeElement.node().nodeName() === "BODY" || treeElement.node().nodeName() === "HEAD")
return false;
event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent.replace(/\u200b/g, ""));
event.dataTransfer.effectAllowed = "copyMove";
this._treeElementBeingDragged = treeElement;
WebInspector.DOMModel.hideDOMNodeHighlight();
return true;
},
_ondragover: function(event)
{
if (!this._treeElementBeingDragged)
return false;
var treeElement = this._treeElementFromEvent(event);
if (!this._isValidDragSourceOrTarget(treeElement))
return false;
var node = treeElement.node();
while (node) {
if (node === this._treeElementBeingDragged._node)
return false;
node = node.parentNode;
}
treeElement.updateSelection();
treeElement.listItemElement.classList.add("elements-drag-over");
this._dragOverTreeElement = treeElement;
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
return false;
},
_ondragleave: function(event)
{
this._clearDragOverTreeElementMarker();
event.preventDefault();
return false;
},
/**
* @param {?TreeElement} treeElement
* @return {boolean}
*/
_isValidDragSourceOrTarget: function(treeElement)
{
if (!treeElement)
return false;
if (!(treeElement instanceof WebInspector.ElementsTreeElement))
return false;
var elementsTreeElement = /** @type {!WebInspector.ElementsTreeElement} */ (treeElement);
var node = elementsTreeElement.node();
if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
return false;
return true;
},
_ondrop: function(event)
{
event.preventDefault();
var treeElement = this._treeElementFromEvent(event);
if (treeElement)
this._doMove(treeElement);
},
/**
* @param {!TreeElement} treeElement
*/
_doMove: function(treeElement)
{
if (!this._treeElementBeingDragged)
return;
var parentNode;
var anchorNode;
if (treeElement.isClosingTag()) {
// Drop onto closing tag -> insert as last child.
parentNode = treeElement.node();
} else {
var dragTargetNode = treeElement.node();
parentNode = dragTargetNode.parentNode;
anchorNode = dragTargetNode;
}
var wasExpanded = this._treeElementBeingDragged.expanded;
this._treeElementBeingDragged._node.moveTo(parentNode, anchorNode, this.selectNodeAfterEdit.bind(this, wasExpanded));
delete this._treeElementBeingDragged;
},
_ondragend: function(event)
{
event.preventDefault();
this._clearDragOverTreeElementMarker();
delete this._treeElementBeingDragged;
},
_clearDragOverTreeElementMarker: function()
{
if (this._dragOverTreeElement) {
this._dragOverTreeElement.updateSelection();
this._dragOverTreeElement.listItemElement.classList.remove("elements-drag-over");
delete this._dragOverTreeElement;
}
},
_contextMenuEventFired: function(event)
{
var treeElement = this._treeElementFromEvent(event);
if (treeElement instanceof WebInspector.ElementsTreeElement)
this.showContextMenu(treeElement, event);
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
* @param {!Event} event
*/
showContextMenu: function(treeElement, event)
{
if (WebInspector.isEditing())
return;
var contextMenu = new WebInspector.ContextMenu(event);
var isPseudoElement = !!treeElement.node().pseudoType();
var isTag = treeElement.node().nodeType() === Node.ELEMENT_NODE && !isPseudoElement;
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode && textNode.classList.contains("bogus"))
textNode = null;
var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
contextMenu.appendApplicableItems(event.target);
if (textNode) {
contextMenu.appendSeparator();
treeElement.populateTextContextMenu(contextMenu, textNode);
} else if (isTag) {
contextMenu.appendSeparator();
treeElement.populateTagContextMenu(contextMenu, event);
} else if (commentNode) {
contextMenu.appendSeparator();
treeElement.populateNodeContextMenu(contextMenu);
} else if (isPseudoElement) {
treeElement.populateScrollIntoView(contextMenu);
}
contextMenu.appendApplicableItems(treeElement.node());
contextMenu.show();
},
runPendingUpdates: function()
{
this._updateModifiedNodes();
},
handleShortcut: function(event)
{
var node = this.selectedDOMNode();
if (!node)
return;
var treeElement = node[this._treeElementSymbol];
if (!treeElement)
return;
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
if (event.keyIdentifier === "Up" && node.previousSibling) {
node.moveTo(node.parentNode, node.previousSibling, this.selectNodeAfterEdit.bind(this, treeElement.expanded));
event.handled = true;
return;
}
if (event.keyIdentifier === "Down" && node.nextSibling) {
node.moveTo(node.parentNode, node.nextSibling.nextSibling, this.selectNodeAfterEdit.bind(this, treeElement.expanded));
event.handled = true;
return;
}
}
},
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} startEditing
* @param {function()=} callback
*/
toggleEditAsHTML: function(node, startEditing, callback)
{
var treeElement = node[this._treeElementSymbol];
if (!treeElement || !treeElement.hasEditableNode())
return;
if (node.pseudoType())
return;
var parentNode = node.parentNode;
var index = node.index;
var wasExpanded = treeElement.expanded;
treeElement.toggleEditAsHTML(editingFinished.bind(this), startEditing);
/**
* @this {WebInspector.ElementsTreeOutline}
* @param {boolean} success
*/
function editingFinished(success)
{
if (callback)
callback();
if (!success)
return;
// Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
this.runPendingUpdates();
var newNode = parentNode ? parentNode.children()[index] || parentNode : null;
if (!newNode)
return;
this.selectDOMNode(newNode, true);
if (wasExpanded) {
var newTreeItem = this.findTreeElement(newNode);
if (newTreeItem)
newTreeItem.expand();
}
}
},
/**
* @param {boolean} wasExpanded
* @param {?Protocol.Error} error
* @param {!DOMAgent.NodeId=} nodeId
* @return {?WebInspector.ElementsTreeElement} nodeId
*/
selectNodeAfterEdit: function(wasExpanded, error, nodeId)
{
if (error)
return null;
// Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
this.runPendingUpdates();
var newNode = nodeId ? this._domModel.nodeForId(nodeId) : null;
if (!newNode)
return null;
this.selectDOMNode(newNode, true);
var newTreeItem = this.findTreeElement(newNode);
if (wasExpanded) {
if (newTreeItem)
newTreeItem.expand();
}
return newTreeItem;
},
/**
* Runs a script on the node's remote object that toggles a class name on
* the node and injects a stylesheet into the head of the node's document
* containing a rule to set "visibility: hidden" on the class and all it's
* ancestors.
*
* @param {!WebInspector.DOMNode} node
* @param {function(?WebInspector.RemoteObject, boolean=)=} userCallback
*/
toggleHideElement: function(node, userCallback)
{
var pseudoType = node.pseudoType();
var effectiveNode = pseudoType ? node.parentNode : node;
if (!effectiveNode)
return;
var hidden = node.marker("hidden-marker");
function resolvedNode(object)
{
if (!object)
return;
/**
* @param {?string} pseudoType
* @param {boolean} hidden
* @suppressGlobalPropertiesCheck
* @suppressReceiverCheck
* @this {!Element}
*/
function toggleClassAndInjectStyleRule(pseudoType, hidden)
{
const classNamePrefix = "__web-inspector-hide";
const classNameSuffix = "-shortcut__";
const styleTagId = "__web-inspector-hide-shortcut-style__";
var selectors = [];
selectors.push(".__web-inspector-hide-shortcut__");
selectors.push(".__web-inspector-hide-shortcut__ *");
selectors.push(".__web-inspector-hidebefore-shortcut__::before");
selectors.push(".__web-inspector-hideafter-shortcut__::after");
var selector = selectors.join(", ");
var ruleBody = " visibility: hidden !important;";
var rule = "\n" + selector + "\n{\n" + ruleBody + "\n}\n";
var className = classNamePrefix + (pseudoType || "") + classNameSuffix;
this.classList.toggle(className, hidden);
var localRoot = this;
while (localRoot.parentNode)
localRoot = localRoot.parentNode;
if (localRoot.nodeType === Node.DOCUMENT_NODE)
localRoot = document.head;
var style = localRoot.querySelector("style#" + styleTagId);
if (style)
return;
style = document.createElement("style");
style.id = styleTagId;
style.type = "text/css";
style.textContent = rule;
localRoot.appendChild(style);
}
object.callFunction(toggleClassAndInjectStyleRule, [{ value: pseudoType }, { value: !hidden}], userCallback);
object.release();
node.setMarker("hidden-marker", hidden ? null : true);
}
effectiveNode.resolveToObject("", resolvedNode);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {boolean}
*/
isToggledToHidden: function(node)
{
return !!node.marker("hidden-marker");
},
_reset: function()
{
this.rootDOMNode = null;
this.selectDOMNode(null, false);
this._popoverHelper.hidePopover();
delete this._clipboardNodeData;
WebInspector.DOMModel.hideDOMNodeHighlight();
this._updateRecords.clear();
},
wireToDOMModel: function()
{
this._domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._nodeInserted, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributeModified, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributeRemoved, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
this._domModel.addEventListener(WebInspector.DOMModel.Events.DistributedNodesChanged, this._distributedNodesChanged, this);
},
unwireFromDOMModel: function()
{
this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInserted, this._nodeInserted, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributeModified, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributeRemoved, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
this._domModel.removeEventListener(WebInspector.DOMModel.Events.DistributedNodesChanged, this._distributedNodesChanged, this);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!WebInspector.ElementsTreeOutline.UpdateRecord}
*/
_addUpdateRecord: function(node)
{
var record = this._updateRecords.get(node);
if (!record) {
record = new WebInspector.ElementsTreeOutline.UpdateRecord();
this._updateRecords.set(node, record);
}
return record;
},
/**
* @param {!WebInspector.DOMNode} node
* @return {?WebInspector.ElementsTreeOutline.UpdateRecord}
*/
_updateRecordForHighlight: function(node)
{
if (!this._visible)
return null;
return this._updateRecords.get(node) || null;
},
/**
* @param {!WebInspector.Event} event
*/
_documentUpdated: function(event)
{
var inspectedRootDocument = event.data;
this._reset();
if (!inspectedRootDocument)
return;
this.rootDOMNode = inspectedRootDocument;
},
/**
* @param {!WebInspector.Event} event
*/
_attributeModified: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
this._addUpdateRecord(node).attributeModified(event.data.name);
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_attributeRemoved: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
this._addUpdateRecord(node).attributeRemoved(event.data.name);
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_characterDataModified: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this._addUpdateRecord(node).charDataModified();
// Text could be large and force us to render itself as the child in the tree outline.
if (node.parentNode && node.parentNode.firstChild === node.parentNode.lastChild)
this._addUpdateRecord(node.parentNode).childrenModified();
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_nodeInserted: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this._addUpdateRecord(/** @type {!WebInspector.DOMNode} */ (node.parentNode)).nodeInserted(node);
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_nodeRemoved: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
var parentNode = /** @type {!WebInspector.DOMNode} */ (event.data.parent);
this.resetClipboardIfNeeded(node);
this._addUpdateRecord(parentNode).nodeRemoved(node);
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_childNodeCountUpdated: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this._addUpdateRecord(node).childrenModified();
this._updateModifiedNodesSoon();
},
/**
* @param {!WebInspector.Event} event
*/
_distributedNodesChanged: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
this._addUpdateRecord(node).childrenModified();
this._updateModifiedNodesSoon();
},
_updateModifiedNodesSoon: function()
{
if (!this._updateRecords.size)
return;
if (this._updateModifiedNodesTimeout)
return;
this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
},
_updateModifiedNodes: function()
{
if (this._updateModifiedNodesTimeout) {
clearTimeout(this._updateModifiedNodesTimeout);
delete this._updateModifiedNodesTimeout;
}
var updatedNodes = this._updateRecords.keysArray();
var hidePanelWhileUpdating = updatedNodes.length > 10;
if (hidePanelWhileUpdating) {
var treeOutlineContainerElement = this.element.parentNode;
var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
this._element.classList.add("hidden");
}
if (this._rootDOMNode && this._updateRecords.get(this._rootDOMNode) && this._updateRecords.get(this._rootDOMNode).hasChangedChildren()) {
// Document's children have changed, perform total update.
this.update();
} else {
for (var node of this._updateRecords.keys()) {
if (this._updateRecords.get(node).hasChangedChildren())
this._updateModifiedParentNode(node);
else
this._updateModifiedNode(node);
}
}
if (hidePanelWhileUpdating) {
this._element.classList.remove("hidden");
if (originalScrollTop)
treeOutlineContainerElement.scrollTop = originalScrollTop;
this.updateSelection();
}
this._updateRecords.clear();
this._fireElementsTreeUpdated(updatedNodes);
},
_updateModifiedNode: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
treeElement.updateTitle(this._updateRecordForHighlight(node));
},
_updateModifiedParentNode: function(node)
{
var parentTreeElement = this.findTreeElement(node);
if (parentTreeElement) {
parentTreeElement.setExpandable(this._hasVisibleChildren(node));
parentTreeElement.updateTitle(this._updateRecordForHighlight(node));
if (parentTreeElement.populated)
this._updateChildren(parentTreeElement);
}
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
*/
populateTreeElement: function(treeElement)
{
if (treeElement.childCount() || !treeElement.isExpandable())
return;
this._updateModifiedParentNode(treeElement.node());
},
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean=} closingTag
* @return {!WebInspector.ElementsTreeElement}
*/
_createElementTreeElement: function(node, closingTag)
{
var treeElement = new WebInspector.ElementsTreeElement(node, closingTag);
treeElement.setExpandable(!closingTag && this._hasVisibleChildren(node));
if (node.nodeType() === Node.ELEMENT_NODE && node.parentNode && node.parentNode.nodeType() === Node.DOCUMENT_NODE && !node.parentNode.parentNode)
treeElement.setCollapsible(false);
treeElement.selectable = this._selectEnabled;
return treeElement;
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
* @param {!WebInspector.DOMNode} child
* @return {?WebInspector.ElementsTreeElement}
*/
_showChild: function(treeElement, child)
{
if (treeElement.isClosingTag())
return null;
var index = this._visibleChildren(treeElement.node()).indexOf(child);
if (index === -1)
return null;
if (index >= treeElement.expandedChildrenLimit())
this.setExpandedChildrenLimit(treeElement, index + 1);
return /** @type {!WebInspector.ElementsTreeElement} */ (treeElement.childAt(index));
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!Array.<!WebInspector.DOMNode>} visibleChildren
*/
_visibleChildren: function(node)
{
var visibleChildren = WebInspector.ElementsTreeElement.visibleShadowRoots(node);
var importedDocument = node.importedDocument();
if (importedDocument)
visibleChildren.push(importedDocument);
var templateContent = node.templateContent();
if (templateContent)
visibleChildren.push(templateContent);
var beforePseudoElement = node.beforePseudoElement();
if (beforePseudoElement)
visibleChildren.push(beforePseudoElement);
if (node.childNodeCount())
visibleChildren = visibleChildren.concat(node.children());
var afterPseudoElement = node.afterPseudoElement();
if (afterPseudoElement)
visibleChildren.push(afterPseudoElement);
return visibleChildren;
},
/**
* @param {!WebInspector.DOMNode} node
* @return {boolean}
*/
_hasVisibleChildren: function(node)
{
if (node.importedDocument())
return true;
if (node.templateContent())
return true;
if (WebInspector.ElementsTreeElement.visibleShadowRoots(node).length)
return true;
if (node.hasPseudoElements())
return true;
if (node.isInsertionPoint())
return true;
return !!node.childNodeCount() && !WebInspector.ElementsTreeElement.canShowInlineText(node);
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
*/
_createExpandAllButtonTreeElement: function(treeElement)
{
var button = createTextButton("", handleLoadAllChildren.bind(this));
button.value = "";
var expandAllButtonElement = new TreeElement(button);
expandAllButtonElement.selectable = false;
expandAllButtonElement.expandAllButton = true;
expandAllButtonElement.button = button;
return expandAllButtonElement;
/**
* @this {WebInspector.ElementsTreeOutline}
* @param {!Event} event
*/
function handleLoadAllChildren(event)
{
var visibleChildCount = this._visibleChildren(treeElement.node()).length;
this.setExpandedChildrenLimit(treeElement, Math.max(visibleChildCount, treeElement.expandedChildrenLimit() + WebInspector.ElementsTreeElement.InitialChildrenLimit));
event.consume();
}
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
* @param {number} expandedChildrenLimit
*/
setExpandedChildrenLimit: function(treeElement, expandedChildrenLimit)
{
if (treeElement.expandedChildrenLimit() === expandedChildrenLimit)
return;
treeElement.setExpandedChildrenLimit(expandedChildrenLimit);
if (treeElement.treeOutline && !this._treeElementsBeingUpdated.has(treeElement))
this._updateModifiedParentNode(treeElement.node());
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
*/
_updateChildren: function(treeElement)
{
if (!treeElement.isExpandable()) {
var selectedTreeElement = treeElement.treeOutline.selectedTreeElement;
if (selectedTreeElement && selectedTreeElement.hasAncestor(treeElement))
treeElement.select(true);
treeElement.removeChildren();
return;
}
console.assert(!treeElement.isClosingTag());
treeElement.node().getChildNodes(childNodesLoaded.bind(this));
/**
* @param {?Array.<!WebInspector.DOMNode>} children
* @this {WebInspector.ElementsTreeOutline}
*/
function childNodesLoaded(children)
{
// FIXME: sort this out, it should not happen.
if (!children)
return;
this._innerUpdateChildren(treeElement);
}
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
* @param {!WebInspector.DOMNode} child
* @param {number} index
* @param {boolean=} closingTag
* @return {!WebInspector.ElementsTreeElement}
*/
insertChildElement: function(treeElement, child, index, closingTag)
{
var newElement = this._createElementTreeElement(child, closingTag);
treeElement.insertChild(newElement, index);
return newElement;
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
* @param {!WebInspector.ElementsTreeElement} child
* @param {number} targetIndex
*/
_moveChild: function(treeElement, child, targetIndex)
{
if (treeElement.indexOfChild(child) === targetIndex)
return;
var wasSelected = child.selected;
if (child.parent)
child.parent.removeChild(child);
treeElement.insertChild(child, targetIndex);
if (wasSelected)
child.select();
},
/**
* @param {!WebInspector.ElementsTreeElement} treeElement
*/
_innerUpdateChildren: function(treeElement)
{
if (this._treeElementsBeingUpdated.has(treeElement))
return;
this._treeElementsBeingUpdated.add(treeElement);
var node = treeElement.node();
var visibleChildren = this._visibleChildren(node);
var visibleChildrenSet = new Set(visibleChildren);
// Remove any tree elements that no longer have this node as their parent and save
// all existing elements that could be reused. This also removes closing tag element.
var existingTreeElements = new Map();
for (var i = treeElement.childCount() - 1; i >= 0; --i) {
var existingTreeElement = treeElement.childAt(i);
if (!(existingTreeElement instanceof WebInspector.ElementsTreeElement)) {
// Remove expand all button and shadow host toolbar.
treeElement.removeChildAtIndex(i);
continue;
}
var elementsTreeElement = /** @type {!WebInspector.ElementsTreeElement} */ (existingTreeElement);
var existingNode = elementsTreeElement.node();
if (visibleChildrenSet.has(existingNode)) {
existingTreeElements.set(existingNode, existingTreeElement);
continue;
}
treeElement.removeChildAtIndex(i);
}
for (var i = 0; i < visibleChildren.length && i < treeElement.expandedChildrenLimit(); ++i) {
var child = visibleChildren[i];
var existingTreeElement = existingTreeElements.get(child) || this.findTreeElement(child);
if (existingTreeElement && existingTreeElement !== treeElement) {
// If an existing element was found, just move it.
this._moveChild(treeElement, existingTreeElement, i);
} else {
// No existing element found, insert a new element.
var newElement = this.insertChildElement(treeElement, child, i);
if (this._updateRecordForHighlight(node) && treeElement.expanded)
WebInspector.ElementsTreeElement.animateOnDOMUpdate(newElement);
// If a node was inserted in the middle of existing list dynamically we might need to increase the limit.
if (treeElement.childCount() > treeElement.expandedChildrenLimit())
this.setExpandedChildrenLimit(treeElement, treeElement.expandedChildrenLimit() + 1);
}
}
// Update expand all button.
var expandedChildCount = treeElement.childCount();
if (visibleChildren.length > expandedChildCount) {
var targetButtonIndex = expandedChildCount;
if (!treeElement.expandAllButtonElement)
treeElement.expandAllButtonElement = this._createExpandAllButtonTreeElement(treeElement);
treeElement.insertChild(treeElement.expandAllButtonElement, targetButtonIndex);
treeElement.expandAllButtonElement.button.textContent = WebInspector.UIString("Show All Nodes (%d More)", visibleChildren.length - expandedChildCount);
} else if (treeElement.expandAllButtonElement) {
delete treeElement.expandAllButtonElement;
}
// Insert shortcuts to distrubuted children.
if (node.isInsertionPoint()) {
for (var distributedNode of node.distributedNodes())
treeElement.appendChild(new WebInspector.ElementsTreeOutline.ShortcutTreeElement(distributedNode));
}
// Insert close tag.
if (node.nodeType() === Node.ELEMENT_NODE && treeElement.isExpandable())
this.insertChildElement(treeElement, node, treeElement.childCount(), true);
this._treeElementsBeingUpdated.delete(treeElement);
},
/**
* @param {!WebInspector.Event} event
*/
_markersChanged: function(event)
{
var node = /** @type {!WebInspector.DOMNode} */ (event.data);
var treeElement = node[this._treeElementSymbol];
if (treeElement)
treeElement.updateDecorations();
},
__proto__: TreeOutline.prototype
}
/**
* @constructor
*/
WebInspector.ElementsTreeOutline.UpdateRecord = function()
{
}
WebInspector.ElementsTreeOutline.UpdateRecord.prototype = {
/**
* @param {string} attrName
*/
attributeModified: function(attrName)
{
if (this._removedAttributes && this._removedAttributes.has(attrName))
this._removedAttributes.delete(attrName);
if (!this._modifiedAttributes)
this._modifiedAttributes = /** @type {!Set.<string>} */ (new Set());
this._modifiedAttributes.add(attrName);
},
/**
* @param {string} attrName
*/
attributeRemoved: function(attrName)
{
if (this._modifiedAttributes && this._modifiedAttributes.has(attrName))
this._modifiedAttributes.delete(attrName);
if (!this._removedAttributes)
this._removedAttributes = /** @type {!Set.<string>} */ (new Set());
this._removedAttributes.add(attrName);
},
/**
* @param {!WebInspector.DOMNode} node
*/
nodeInserted: function(node)
{
this._hasChangedChildren = true;
},
nodeRemoved: function(node)
{
this._hasChangedChildren = true;
this._hasRemovedChildren = true;
},
charDataModified: function()
{
this._charDataModified = true;
},
childrenModified: function()
{
this._hasChangedChildren = true;
},
/**
* @param {string} attributeName
* @return {boolean}
*/
isAttributeModified: function(attributeName)
{
return this._modifiedAttributes && this._modifiedAttributes.has(attributeName);
},
/**
* @return {boolean}
*/
hasRemovedAttributes: function()
{
return !!this._removedAttributes && !!this._removedAttributes.size;
},
/**
* @return {boolean}
*/
isCharDataModified: function()
{
return !!this._charDataModified;
},
/**
* @return {boolean}
*/
hasChangedChildren: function()
{
return !!this._hasChangedChildren;
},
/**
* @return {boolean}
*/
hasRemovedChildren: function()
{
return !!this._hasRemovedChildren;
}
}
/**
* @constructor
* @implements {WebInspector.Renderer}
*/
WebInspector.ElementsTreeOutline.Renderer = function()
{
}
WebInspector.ElementsTreeOutline.Renderer.prototype = {
/**
* @override
* @param {!Object} object
* @return {!Promise.<!Element>}
*/
render: function(object)
{
return new Promise(renderPromise);
/**
* @param {function(!Element)} resolve
* @param {function(!Error)} reject
*/
function renderPromise(resolve, reject)
{
if (object instanceof WebInspector.DOMNode) {
onNodeResolved(/** @type {!WebInspector.DOMNode} */ (object));
} else if (object instanceof WebInspector.DeferredDOMNode) {
(/** @type {!WebInspector.DeferredDOMNode} */ (object)).resolve(onNodeResolved);
} else if (object instanceof WebInspector.RemoteObject) {
var domModel = WebInspector.DOMModel.fromTarget((/** @type {!WebInspector.RemoteObject} */ (object)).target());
if (domModel)
domModel.pushObjectAsNodeToFrontend(object, onNodeResolved);
else
reject(new Error("No dom model for given JS object target found."));
} else {
reject(new Error("Can't reveal not a node."));
}
/**
* @param {?WebInspector.DOMNode} node
*/
function onNodeResolved(node)
{
if (!node) {
reject(new Error("Could not resolve node."));
return;
}
var treeOutline = new WebInspector.ElementsTreeOutline(node.domModel(), false, false);
treeOutline.rootDOMNode = node;
if (!treeOutline.firstChild().isExpandable())
treeOutline._element.classList.add("single-node");
treeOutline.setVisible(true);
treeOutline.element.treeElementForTest = treeOutline.firstChild();
resolve(treeOutline.element);
}
}
}
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.DOMNodeShortcut} nodeShortcut
*/
WebInspector.ElementsTreeOutline.ShortcutTreeElement = function(nodeShortcut)
{
TreeElement.call(this, "");
this.listItemElement.createChild("div", "selection fill");
var title = this.listItemElement.createChild("span", "elements-tree-shortcut-title");
var text = nodeShortcut.nodeName.toLowerCase();
if (nodeShortcut.nodeType === Node.ELEMENT_NODE)
text = "<" + text + ">";
title.textContent = "\u21AA " + text;
var link = WebInspector.DOMPresentationUtils.linkifyDeferredNodeReference(nodeShortcut.deferredNode);
this.listItemElement.createTextChild(" ");
link.classList.add("elements-tree-shortcut-link");
link.textContent = WebInspector.UIString("reveal");
this.listItemElement.appendChild(link);
this._nodeShortcut = nodeShortcut;
}
WebInspector.ElementsTreeOutline.ShortcutTreeElement.prototype = {
/**
* @return {boolean}
*/
get hovered()
{
return this._hovered;
},
set hovered(x)
{
if (this._hovered === x)
return;
this._hovered = x;
this.listItemElement.classList.toggle("hovered", x);
},
updateSelection: function()
{
},
/**
* @return {number}
*/
backendNodeId: function()
{
return this._nodeShortcut.deferredNode.backendNodeId();
},
/**
* @override
* @param {boolean=} selectedByUser
* @return {boolean}
*/
onselect: function(selectedByUser)
{
if (!selectedByUser)
return true;
this._nodeShortcut.deferredNode.highlight();
this._nodeShortcut.deferredNode.resolve(resolved.bind(this));
/**
* @param {?WebInspector.DOMNode} node
* @this {WebInspector.ElementsTreeOutline.ShortcutTreeElement}
*/
function resolved(node)
{
if (node) {
this.treeOutline._selectedDOMNode = node;
this.treeOutline._selectedNodeChanged();
}
}
return true;
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | 2 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
*/
WebInspector.EventListenersWidget = function()
{
WebInspector.ThrottledWidget.call(this);
this.element.classList.add("events-pane");
this._showForAncestorsSetting = WebInspector.settings.createSetting("showEventListenersForAncestors", true);
this._showForAncestorsSetting.addChangeListener(this.update.bind(this));
this._dispatchFilterBySetting = WebInspector.settings.createSetting("eventListenerDispatchFilterType", WebInspector.EventListenersWidget.DispatchFilterBy.All);
this._dispatchFilterBySetting.addChangeListener(this.update.bind(this));
this._showFrameworkListenersSetting = WebInspector.settings.createSetting("showFrameowkrListeners", true);
this._showFrameworkListenersSetting.addChangeListener(this._showFrameworkListenersChanged.bind(this));
this._eventListenersView = new WebInspector.EventListenersView(this.element);
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this.update, this);
}
WebInspector.EventListenersWidget.DispatchFilterBy = {
All : "All",
Blocking : "Blocking",
Passive : "Passive"
}
/**
* @return {!WebInspector.ElementsSidebarViewWrapperPane}
*/
WebInspector.EventListenersWidget.createSidebarWrapper = function()
{
var widget = new WebInspector.EventListenersWidget();
var result = new WebInspector.ElementsSidebarViewWrapperPane(WebInspector.UIString("Event Listeners"), widget);
var refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
refreshButton.addEventListener("click", widget.update.bind(widget));
result.toolbar().appendToolbarItem(refreshButton);
result.toolbar().appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Ancestors"), WebInspector.UIString("Show listeners on the ancestors"), widget._showForAncestorsSetting));
var dispatchFilter = new WebInspector.ToolbarComboBox(widget._onDispatchFilterTypeChanged.bind(widget));
/**
* @param {string} name
* @param {string} value
*/
function addDispatchFilterOption(name, value)
{
var option = dispatchFilter.createOption(name, "", value);
if (value === widget._dispatchFilterBySetting.get())
dispatchFilter.select(option);
}
addDispatchFilterOption(WebInspector.UIString("All"), WebInspector.EventListenersWidget.DispatchFilterBy.All);
addDispatchFilterOption(WebInspector.UIString("Passive"), WebInspector.EventListenersWidget.DispatchFilterBy.Passive);
addDispatchFilterOption(WebInspector.UIString("Blocking"), WebInspector.EventListenersWidget.DispatchFilterBy.Blocking);
dispatchFilter.setMaxWidth(200);
result.toolbar().appendToolbarItem(dispatchFilter);
result.toolbar().appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Framework listeners"), WebInspector.UIString("Resolve event listeners bound with framework"), widget._showFrameworkListenersSetting));
return result;
}
WebInspector.EventListenersWidget._objectGroupName = "event-listeners-panel";
WebInspector.EventListenersWidget.prototype = {
/**
* @override
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
if (this._lastRequestedNode) {
this._lastRequestedNode.target().runtimeAgent().releaseObjectGroup(WebInspector.EventListenersWidget._objectGroupName);
delete this._lastRequestedNode;
}
var node = WebInspector.context.flavor(WebInspector.DOMNode);
if (!node) {
this._eventListenersView.reset();
this._eventListenersView.addEmptyHolderIfNeeded();
return Promise.resolve();
}
this._lastRequestedNode = node;
var selectedNodeOnly = !this._showForAncestorsSetting.get();
var promises = [];
var listenersView = this._eventListenersView;
promises.push(node.resolveToObjectPromise(WebInspector.EventListenersWidget._objectGroupName));
if (!selectedNodeOnly) {
var currentNode = node.parentNode;
while (currentNode) {
promises.push(currentNode.resolveToObjectPromise(WebInspector.EventListenersWidget._objectGroupName));
currentNode = currentNode.parentNode;
}
promises.push(this._windowObjectInNodeContext(node));
}
return Promise.all(promises).then(this._eventListenersView.addObjects.bind(this._eventListenersView)).then(this._showFrameworkListenersChanged.bind(this));
},
/**
* @param {!Event} event
*/
_onDispatchFilterTypeChanged: function(event)
{
this._dispatchFilterBySetting.set(event.target.value);
},
_showFrameworkListenersChanged: function()
{
var dispatchFilter = this._dispatchFilterBySetting.get();
var showPassive = dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.Passive;
var showBlocking = dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.Blocking;
this._eventListenersView.showFrameworkListeners(this._showFrameworkListenersSetting.get(), showPassive, showBlocking);
},
/**
* @param {!WebInspector.DOMNode} node
* @return {!Promise<!WebInspector.RemoteObject>}
*/
_windowObjectInNodeContext: function(node)
{
return new Promise(windowObjectInNodeContext);
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
*/
function windowObjectInNodeContext(fulfill, reject)
{
var executionContexts = node.target().runtimeModel.executionContexts();
var context = null;
if (node.frameId()) {
for (var i = 0; i < executionContexts.length; ++i) {
var executionContext = executionContexts[i];
if (executionContext.frameId === node.frameId() && executionContext.isDefault)
context = executionContext;
}
} else {
context = executionContexts[0];
}
context.evaluate("self", WebInspector.EventListenersWidget._objectGroupName, false, true, false, false, false, fulfill);
}
},
_eventListenersArrivedForTest: function()
{
},
__proto__: WebInspector.ThrottledWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.InspectElementModeController = function()
{
this._toggleSearchAction = WebInspector.actionRegistry.action("elements.toggle-element-search");
if (Runtime.experiments.isEnabled("layoutEditor")) {
this._layoutEditorButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Toggle Layout Editor"), "layout-editor-toolbar-item");
this._layoutEditorButton.addEventListener("click", this._toggleLayoutEditor, this);
}
this._mode = DOMAgent.InspectMode.None;
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.InspectElementModeController.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
// When DevTools are opening in the inspect element mode, the first target comes in
// much later than the InspectorFrontendAPI.enterInspectElementMode event.
if (this._mode === DOMAgent.InspectMode.None)
return;
var domModel = WebInspector.DOMModel.fromTarget(target);
domModel.setInspectMode(this._mode);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
},
/**
* @return {boolean}
*/
isInInspectElementMode: function()
{
return this._mode === DOMAgent.InspectMode.SearchForNode || this._mode === DOMAgent.InspectMode.SearchForUAShadowDOM;
},
/**
* @return {boolean}
*/
isInLayoutEditorMode: function()
{
return this._mode === DOMAgent.InspectMode.ShowLayoutEditor;
},
stopInspection: function()
{
if (this._mode && this._mode !== DOMAgent.InspectMode.None)
this._toggleInspectMode();
},
_toggleLayoutEditor: function()
{
var mode = this.isInLayoutEditorMode() ? DOMAgent.InspectMode.None : DOMAgent.InspectMode.ShowLayoutEditor;
this._setMode(mode);
},
_toggleInspectMode: function()
{
if (WebInspector.targetManager.allTargetsSuspended())
return;
var mode;
if (this.isInInspectElementMode())
mode = DOMAgent.InspectMode.None;
else
mode = WebInspector.moduleSetting("showUAShadowDOM").get() ? DOMAgent.InspectMode.SearchForUAShadowDOM : DOMAgent.InspectMode.SearchForNode;
this._setMode(mode);
},
/**
* @param {!DOMAgent.InspectMode} mode
*/
_setMode: function(mode)
{
this._mode = mode;
for (var domModel of WebInspector.DOMModel.instances())
domModel.setInspectMode(mode);
if (this._layoutEditorButton) {
this._layoutEditorButton.setEnabled(!this.isInInspectElementMode());
this._layoutEditorButton.setToggled(this.isInLayoutEditorMode());
}
this._toggleSearchAction.setEnabled(!this.isInLayoutEditorMode());
this._toggleSearchAction.setToggled(this.isInInspectElementMode());
},
_suspendStateChanged: function()
{
if (!WebInspector.targetManager.allTargetsSuspended())
return;
this._mode = DOMAgent.InspectMode.None;
this._toggleSearchAction.setToggled(false);
if (this._layoutEditorButton)
this._layoutEditorButton.setToggled(false);
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.InspectElementModeController.ToggleSearchActionDelegate = function()
{
}
WebInspector.InspectElementModeController.ToggleSearchActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
if (!WebInspector.inspectElementModeController)
return false;
WebInspector.inspectElementModeController._toggleInspectMode();
return true;
}
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.InspectElementModeController.LayoutEditorButtonProvider = function()
{
}
WebInspector.InspectElementModeController.LayoutEditorButtonProvider.prototype = {
/**
* @override
* @return {?WebInspector.ToolbarItem}
*/
item: function()
{
if (!WebInspector.inspectElementModeController)
return null;
return WebInspector.inspectElementModeController._layoutEditorButton;
}
}
/** @type {?WebInspector.InspectElementModeController} */
WebInspector.inspectElementModeController = Runtime.queryParam("isSharedWorker") ? null : new WebInspector.InspectElementModeController();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | 2 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ElementsSidebarPane}
*/
WebInspector.MetricsSidebarPane = function()
{
WebInspector.ElementsSidebarPane.call(this, WebInspector.UIString("Metrics"));
}
WebInspector.MetricsSidebarPane.prototype = {
/**
* @override
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
// "style" attribute might have changed. Update metrics unless they are being edited
// (if a CSS property is added, a StyleSheetChanged event is dispatched).
if (this._isEditingMetrics)
return Promise.resolve();
// FIXME: avoid updates of a collapsed pane.
var node = this.node();
var cssModel = this.cssModel();
if (!node || node.nodeType() !== Node.ELEMENT_NODE || !cssModel) {
this.element.removeChildren();
return Promise.resolve();
}
/**
* @param {?Map.<string, string>} style
* @this {WebInspector.MetricsSidebarPane}
*/
function callback(style)
{
if (!style || this.node() !== node)
return;
this._updateMetrics(style);
}
/**
* @param {?WebInspector.CSSModel.InlineStyleResult} inlineStyleResult
* @this {WebInspector.MetricsSidebarPane}
*/
function inlineStyleCallback(inlineStyleResult)
{
if (inlineStyleResult && this.node() === node)
this.inlineStyle = inlineStyleResult.inlineStyle;
}
var promises = [
cssModel.computedStylePromise(node.id).then(callback.bind(this)),
cssModel.inlineStylesPromise(node.id).then(inlineStyleCallback.bind(this))
];
return Promise.all(promises);
},
/**
* @override
*/
onDOMModelChanged: function()
{
this.update();
},
/**
* @override
*/
onCSSModelChanged: function()
{
this.update();
},
/**
* @override
*/
onFrameResizedThrottled: function()
{
this.update();
},
/**
* @param {!Map.<string, string>} style
* @param {string} propertyName
* @return {number}
*/
_getPropertyValueAsPx: function(style, propertyName)
{
return Number(style.get(propertyName).replace(/px$/, "") || 0);
},
/**
* @param {!Map.<string, string>} computedStyle
* @param {string} componentName
*/
_getBox: function(computedStyle, componentName)
{
var suffix = componentName === "border" ? "-width" : "";
var left = this._getPropertyValueAsPx(computedStyle, componentName + "-left" + suffix);
var top = this._getPropertyValueAsPx(computedStyle, componentName + "-top" + suffix);
var right = this._getPropertyValueAsPx(computedStyle, componentName + "-right" + suffix);
var bottom = this._getPropertyValueAsPx(computedStyle, componentName + "-bottom" + suffix);
return { left: left, top: top, right: right, bottom: bottom };
},
/**
* @param {boolean} showHighlight
* @param {string} mode
* @param {!Event} event
*/
_highlightDOMNode: function(showHighlight, mode, event)
{
event.consume();
if (showHighlight && this.node()) {
if (this._highlightMode === mode)
return;
this._highlightMode = mode;
this.node().highlight(mode);
} else {
delete this._highlightMode;
WebInspector.DOMModel.hideDOMNodeHighlight();
}
for (var i = 0; this._boxElements && i < this._boxElements.length; ++i) {
var element = this._boxElements[i];
if (!this.node() || mode === "all" || element._name === mode)
element.style.backgroundColor = element._backgroundColor;
else
element.style.backgroundColor = "";
}
},
/**
* @param {!Map.<string, string>} style
*/
_updateMetrics: function(style)
{
// Updating with computed style.
var metricsElement = createElement("div");
metricsElement.className = "metrics";
var self = this;
/**
* @param {!Map.<string, string>} style
* @param {string} name
* @param {string} side
* @param {string} suffix
* @this {WebInspector.MetricsSidebarPane}
*/
function createBoxPartElement(style, name, side, suffix)
{
var propertyName = (name !== "position" ? name + "-" : "") + side + suffix;
var value = style.get(propertyName);
if (value === "" || (name !== "position" && value === "0px"))
value = "\u2012";
else if (name === "position" && value === "auto")
value = "\u2012";
value = value.replace(/px$/, "");
value = Number.toFixedIfFloating(value);
var element = createElement("div");
element.className = side;
element.textContent = value;
element.addEventListener("dblclick", this.startEditing.bind(this, element, name, propertyName, style), false);
return element;
}
/**
* @param {!Map.<string, string>} style
* @return {string}
*/
function getContentAreaWidthPx(style)
{
var width = style.get("width").replace(/px$/, "");
if (!isNaN(width) && style.get("box-sizing") === "border-box") {
var borderBox = self._getBox(style, "border");
var paddingBox = self._getBox(style, "padding");
width = width - borderBox.left - borderBox.right - paddingBox.left - paddingBox.right;
}
return Number.toFixedIfFloating(width.toString());
}
/**
* @param {!Map.<string, string>} style
* @return {string}
*/
function getContentAreaHeightPx(style)
{
var height = style.get("height").replace(/px$/, "");
if (!isNaN(height) && style.get("box-sizing") === "border-box") {
var borderBox = self._getBox(style, "border");
var paddingBox = self._getBox(style, "padding");
height = height - borderBox.top - borderBox.bottom - paddingBox.top - paddingBox.bottom;
}
return Number.toFixedIfFloating(height.toString());
}
// Display types for which margin is ignored.
var noMarginDisplayType = {
"table-cell": true,
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};
// Display types for which padding is ignored.
var noPaddingDisplayType = {
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};
// Position types for which top, left, bottom and right are ignored.
var noPositionType = {
"static": true
};
var boxes = ["content", "padding", "border", "margin", "position"];
var boxColors = [
WebInspector.Color.PageHighlight.Content,
WebInspector.Color.PageHighlight.Padding,
WebInspector.Color.PageHighlight.Border,
WebInspector.Color.PageHighlight.Margin,
WebInspector.Color.fromRGBA([0, 0, 0, 0])
];
var boxLabels = [WebInspector.UIString("content"), WebInspector.UIString("padding"), WebInspector.UIString("border"), WebInspector.UIString("margin"), WebInspector.UIString("position")];
var previousBox = null;
this._boxElements = [];
for (var i = 0; i < boxes.length; ++i) {
var name = boxes[i];
if (name === "margin" && noMarginDisplayType[style.get("display")])
continue;
if (name === "padding" && noPaddingDisplayType[style.get("display")])
continue;
if (name === "position" && noPositionType[style.get("position")])
continue;
var boxElement = createElement("div");
boxElement.className = name;
boxElement._backgroundColor = boxColors[i].asString(WebInspector.Color.Format.RGBA);
boxElement._name = name;
boxElement.style.backgroundColor = boxElement._backgroundColor;
boxElement.addEventListener("mouseover", this._highlightDOMNode.bind(this, true, name === "position" ? "all" : name), false);
this._boxElements.push(boxElement);
if (name === "content") {
var widthElement = createElement("span");
widthElement.textContent = getContentAreaWidthPx(style);
widthElement.addEventListener("dblclick", this.startEditing.bind(this, widthElement, "width", "width", style), false);
var heightElement = createElement("span");
heightElement.textContent = getContentAreaHeightPx(style);
heightElement.addEventListener("dblclick", this.startEditing.bind(this, heightElement, "height", "height", style), false);
boxElement.appendChild(widthElement);
boxElement.createTextChild(" \u00D7 ");
boxElement.appendChild(heightElement);
} else {
var suffix = (name === "border" ? "-width" : "");
var labelElement = createElement("div");
labelElement.className = "label";
labelElement.textContent = boxLabels[i];
boxElement.appendChild(labelElement);
boxElement.appendChild(createBoxPartElement.call(this, style, name, "top", suffix));
boxElement.appendChild(createElement("br"));
boxElement.appendChild(createBoxPartElement.call(this, style, name, "left", suffix));
if (previousBox)
boxElement.appendChild(previousBox);
boxElement.appendChild(createBoxPartElement.call(this, style, name, "right", suffix));
boxElement.appendChild(createElement("br"));
boxElement.appendChild(createBoxPartElement.call(this, style, name, "bottom", suffix));
}
previousBox = boxElement;
}
metricsElement.appendChild(previousBox);
metricsElement.addEventListener("mouseover", this._highlightDOMNode.bind(this, false, "all"), false);
this.element.removeChildren();
this.element.appendChild(metricsElement);
},
/**
* @param {!Element} targetElement
* @param {string} box
* @param {string} styleProperty
* @param {!Map.<string, string>} computedStyle
*/
startEditing: function(targetElement, box, styleProperty, computedStyle)
{
if (WebInspector.isBeingEdited(targetElement))
return;
var context = { box: box, styleProperty: styleProperty, computedStyle: computedStyle };
var boundKeyDown = this._handleKeyDown.bind(this, context, styleProperty);
context.keyDownHandler = boundKeyDown;
targetElement.addEventListener("keydown", boundKeyDown, false);
this._isEditingMetrics = true;
var config = new WebInspector.InplaceEditor.Config(this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
WebInspector.InplaceEditor.startEditing(targetElement, config);
targetElement.getComponentSelection().setBaseAndExtent(targetElement, 0, targetElement, 1);
},
_handleKeyDown: function(context, styleProperty, event)
{
var element = event.currentTarget;
/**
* @param {string} originalValue
* @param {string} replacementString
* @this {WebInspector.MetricsSidebarPane}
*/
function finishHandler(originalValue, replacementString)
{
this._applyUserInput(element, replacementString, originalValue, context, false);
}
/**
* @param {string} prefix
* @param {number} number
* @param {string} suffix
* @return {string}
*/
function customNumberHandler(prefix, number, suffix)
{
if (styleProperty !== "margin" && number < 0)
number = 0;
return prefix + number + suffix;
}
WebInspector.handleElementValueModifications(event, element, finishHandler.bind(this), undefined, customNumberHandler);
},
editingEnded: function(element, context)
{
delete this.originalPropertyData;
delete this.previousPropertyDataCandidate;
element.removeEventListener("keydown", context.keyDownHandler, false);
delete this._isEditingMetrics;
},
editingCancelled: function(element, context)
{
if ("originalPropertyData" in this && this.inlineStyle) {
if (!this.originalPropertyData) {
// An added property, remove the last property in the style.
var pastLastSourcePropertyIndex = this.inlineStyle.pastLastSourcePropertyIndex();
if (pastLastSourcePropertyIndex)
this.inlineStyle.allProperties[pastLastSourcePropertyIndex - 1].setText("", false);
} else
this.inlineStyle.allProperties[this.originalPropertyData.index].setText(this.originalPropertyData.propertyText, false);
}
this.editingEnded(element, context);
this.update();
},
_applyUserInput: function(element, userInput, previousContent, context, commitEditor)
{
if (!this.inlineStyle) {
// Element has no renderer.
return this.editingCancelled(element, context); // nothing changed, so cancel
}
if (commitEditor && userInput === previousContent)
return this.editingCancelled(element, context); // nothing changed, so cancel
if (context.box !== "position" && (!userInput || userInput === "\u2012"))
userInput = "0px";
else if (context.box === "position" && (!userInput || userInput === "\u2012"))
userInput = "auto";
userInput = userInput.toLowerCase();
// Append a "px" unit if the user input was just a number.
if (/^\d+$/.test(userInput))
userInput += "px";
var styleProperty = context.styleProperty;
var computedStyle = context.computedStyle;
if (computedStyle.get("box-sizing") === "border-box" && (styleProperty === "width" || styleProperty === "height")) {
if (!userInput.match(/px$/)) {
WebInspector.console.error("For elements with box-sizing: border-box, only absolute content area dimensions can be applied");
return;
}
var borderBox = this._getBox(computedStyle, "border");
var paddingBox = this._getBox(computedStyle, "padding");
var userValuePx = Number(userInput.replace(/px$/, ""));
if (isNaN(userValuePx))
return;
if (styleProperty === "width")
userValuePx += borderBox.left + borderBox.right + paddingBox.left + paddingBox.right;
else
userValuePx += borderBox.top + borderBox.bottom + paddingBox.top + paddingBox.bottom;
userInput = userValuePx + "px";
}
this.previousPropertyDataCandidate = null;
var allProperties = this.inlineStyle.allProperties;
for (var i = 0; i < allProperties.length; ++i) {
var property = allProperties[i];
if (property.name !== context.styleProperty || !property.activeInStyle())
continue;
this.previousPropertyDataCandidate = property;
property.setValue(userInput, commitEditor, true, callback.bind(this));
return;
}
this.inlineStyle.appendProperty(context.styleProperty, userInput, callback.bind(this));
/**
* @param {boolean} success
* @this {WebInspector.MetricsSidebarPane}
*/
function callback(success)
{
if (!success)
return;
if (!("originalPropertyData" in this))
this.originalPropertyData = this.previousPropertyDataCandidate;
if (typeof this._highlightMode !== "undefined")
this._node.highlight(this._highlightMode);
if (commitEditor)
this.update();
}
},
editingCommitted: function(element, userInput, previousContent, context)
{
this.editingEnded(element, context);
this._applyUserInput(element, userInput, previousContent, context, true);
},
__proto__: WebInspector.ElementsSidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
* @param {!WebInspector.SharedSidebarModel} sharedModel
*/
WebInspector.PlatformFontsWidget = function(sharedModel)
{
WebInspector.ThrottledWidget.call(this, true);
this.registerRequiredCSS("elements/platformFontsWidget.css");
this._sharedModel = sharedModel;
this._sharedModel.addEventListener(WebInspector.SharedSidebarModel.Events.ComputedStyleChanged, this.update, this);
this._sectionTitle = createElementWithClass("div", "title");
this.contentElement.appendChild(this._sectionTitle);
this._sectionTitle.textContent = WebInspector.UIString("Rendered Fonts");
this._fontStatsSection = this.contentElement.createChild("div", "stats-section");
}
/**
* @param {!WebInspector.SharedSidebarModel} sharedModel
* @return {!WebInspector.ElementsSidebarViewWrapperPane}
*/
WebInspector.PlatformFontsWidget.createSidebarWrapper = function(sharedModel)
{
var widget = new WebInspector.PlatformFontsWidget(sharedModel);
return new WebInspector.ElementsSidebarViewWrapperPane(WebInspector.UIString("Fonts"), widget)
}
WebInspector.PlatformFontsWidget.prototype = {
/**
* @override
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
var cssModel = this._sharedModel.cssModel();
var node = this._sharedModel.node();
if (!node || !cssModel)
return Promise.resolve();
return cssModel.platformFontsPromise(node.id)
.then(this._refreshUI.bind(this, node))
},
/**
* @param {!WebInspector.DOMNode} node
* @param {?Array.<!CSSAgent.PlatformFontUsage>} platformFonts
*/
_refreshUI: function(node, platformFonts)
{
if (this._sharedModel.node() !== node)
return;
this._fontStatsSection.removeChildren();
var isEmptySection = !platformFonts || !platformFonts.length;
this._sectionTitle.classList.toggle("hidden", isEmptySection);
if (isEmptySection)
return;
platformFonts.sort(function (a, b) {
return b.glyphCount - a.glyphCount;
});
for (var i = 0; i < platformFonts.length; ++i) {
var fontStatElement = this._fontStatsSection.createChild("div", "font-stats-item");
var fontNameElement = fontStatElement.createChild("span", "font-name");
fontNameElement.textContent = platformFonts[i].familyName;
var fontDelimeterElement = fontStatElement.createChild("span", "font-delimeter");
fontDelimeterElement.textContent = "\u2014";
var fontOrigin = fontStatElement.createChild("span");
fontOrigin.textContent = platformFonts[i].isCustomFont? WebInspector.UIString("Network resource") : WebInspector.UIString("Local file");
var fontUsageElement = fontStatElement.createChild("span", "font-usage");
var usage = platformFonts[i].glyphCount;
fontUsageElement.textContent = usage === 1 ? WebInspector.UIString("(%d glyph)", usage) : WebInspector.UIString("(%d glyphs)", usage);
}
},
__proto__: WebInspector.ThrottledWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | 2 1 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ThrottledWidget}
*/
WebInspector.PropertiesWidget = function()
{
WebInspector.ThrottledWidget.call(this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrModified, this._onNodeChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.AttrRemoved, this._onNodeChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._setNode, this);
}
/**
* @return {!WebInspector.ElementsSidebarViewWrapperPane}
*/
WebInspector.PropertiesWidget.createSidebarWrapper = function()
{
return new WebInspector.ElementsSidebarViewWrapperPane(WebInspector.UIString("Properties"), new WebInspector.PropertiesWidget());
}
WebInspector.PropertiesWidget._objectGroupName = "properties-sidebar-pane";
WebInspector.PropertiesWidget.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_setNode: function(event)
{
this._node = /** @type {?WebInspector.DOMNode} */(event.data);
this.update();
},
/**
* @override
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
if (this._lastRequestedNode) {
this._lastRequestedNode.target().runtimeAgent().releaseObjectGroup(WebInspector.PropertiesWidget._objectGroupName);
delete this._lastRequestedNode;
}
if (!this._node) {
this.element.removeChildren();
this.sections = [];
return Promise.resolve();
}
this._lastRequestedNode = this._node;
return this._node.resolveToObjectPromise(WebInspector.PropertiesWidget._objectGroupName)
.then(nodeResolved.bind(this))
/**
* @param {?WebInspector.RemoteObject} object
* @this {WebInspector.PropertiesWidget}
*/
function nodeResolved(object)
{
if (!object)
return;
/**
* @suppressReceiverCheck
* @this {*}
*/
function protoList()
{
var proto = this;
var result = { __proto__: null };
var counter = 1;
while (proto) {
result[counter++] = proto;
proto = proto.__proto__;
}
return result;
}
var promise = object.callFunctionPromise(protoList).then(nodePrototypesReady.bind(this));
object.release();
return promise;
}
/**
* @param {!{object: ?WebInspector.RemoteObject, wasThrown: (boolean|undefined)}} result
* @this {WebInspector.PropertiesWidget}
*/
function nodePrototypesReady(result)
{
if (!result.object || result.wasThrown)
return;
var promise = result.object.getOwnPropertiesPromise().then(fillSection.bind(this));
result.object.release();
return promise;
}
/**
* @param {!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}} result
* @this {WebInspector.PropertiesWidget}
*/
function fillSection(result)
{
if (!result || !result.properties)
return;
var properties = result.properties;
var expanded = [];
var sections = this.sections || [];
for (var i = 0; i < sections.length; ++i)
expanded.push(sections[i].expanded);
this.element.removeChildren();
this.sections = [];
// Get array of property user-friendly names.
for (var i = 0; i < properties.length; ++i) {
if (!parseInt(properties[i].name, 10))
continue;
var property = properties[i].value;
var title = property.description;
title = title.replace(/Prototype$/, "");
var section = new WebInspector.ObjectPropertiesSection(property, title);
section.element.classList.add("properties-widget-section");
this.sections.push(section);
this.element.appendChild(section.element);
if (expanded[this.sections.length - 1])
section.expand();
section.addEventListener(TreeOutline.Events.ElementExpanded, this._propertyExpanded, this);
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_propertyExpanded: function(event)
{
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.DOMPropertiesExpanded);
for (var section of this.sections) {
section.removeEventListener(TreeOutline.Events.ElementExpanded, this._propertyExpanded, this);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onNodeChange: function(event)
{
if (!this._node)
return;
var data = event.data;
var node = /** @type {!WebInspector.DOMNode} */ (data instanceof WebInspector.DOMNode ? data : data.node);
if (this._node !== node)
return;
this.update();
},
__proto__: WebInspector.ThrottledWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.StylesSidebarPane} ssp
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.TextRange} range
*/
WebInspector.PropertyChangeHighlighter = function(ssp, cssModel, styleSheetId, range)
{
this._styleSidebarPane = ssp;
this._target = cssModel.target();
this._styleSheetId = styleSheetId;
this._range = range;
}
WebInspector.PropertyChangeHighlighter.prototype = {
/**
*/
perform: function()
{
var node = this._styleSidebarPane.node();
if (!node || this._target !== node.target())
return;
var foundSection = null;
for (var section of this._styleSidebarPane.allSections()) {
var declaration = section.style();
if (declaration.styleSheetId !== this._styleSheetId)
continue;
var parentRule = declaration.parentRule;
var isInlineSelector = this._range.isEmpty();
var isMatchingRule = parentRule && parentRule.selectorRange() && this._range.compareTo(parentRule.selectorRange()) === 0;
if (isInlineSelector || isMatchingRule) {
section.element.animate([
{ offset: 0, backgroundColor: "rgba(255, 227, 199, 1)" },
{ offset: 0.5, backgroundColor: "rgba(255, 227, 199, 1)" },
{ offset: 0.9, backgroundColor: "rgba(255, 227, 199, 0)" },
{ offset: 1, backgroundColor: "white" }
], { duration : 400, easing: "cubic-bezier(0, 0, 0.2, 1)" });
return;
}
if (this._checkRanges(declaration.range, this._range)) {
foundSection = section;
break;
}
}
if (!foundSection)
return;
var highlightElement;
var treeElement = foundSection.propertiesTreeOutline.firstChild();
var foundTreeElement = null;
while (!highlightElement && treeElement) {
if (treeElement.property.range && this._checkRanges(treeElement.property.range, this._range)) {
highlightElement = treeElement.valueElement;
break;
}
treeElement = treeElement.traverseNextTreeElement(false, null, true);
}
if (highlightElement) {
highlightElement.animate([
{ offset: 0, backgroundColor: "rgba(158, 54, 153, 1)", color: "white" },
{ offset: 0.5, backgroundColor: "rgba(158, 54, 153, 1)", color: "white" },
{ offset: 0.9, backgroundColor: "rgba(158, 54, 153, 0)", color: "initial" },
{ offset: 1, backgroundColor: "white", color: "initial" }
], { duration : 400, easing: "cubic-bezier(0, 0, 0.2, 1)" });
}
},
/**
*
* @param {!WebInspector.TextRange} outterRange
* @param {!WebInspector.TextRange} innerRange
* @return {boolean}
*/
_checkRanges: function(outterRange, innerRange)
{
var startsBefore = outterRange.startLine < innerRange.startLine || (outterRange.startLine === innerRange.startLine && outterRange.startColumn <= innerRange.startColumn);
// SSP might be outdated, so inner range will a bit bigger than outter. E.g.; "padding-left: 9px" -> "padding-left: 10px"
var eps = 5;
var endsAfter = outterRange.endLine > innerRange.endLine || (outterRange.endLine === innerRange.endLine && outterRange.endColumn + eps >= innerRange.endColumn);
return startsBefore && endsAfter;
}
}
/**
* @constructor
* @param {!WebInspector.StylesSidebarPane} ssp
* @param {!WebInspector.CSSProperty} cssProperty
*/
WebInspector.PropertyRevealHighlighter = function(ssp, cssProperty)
{
this._styleSidebarPane = ssp;
this._cssProperty = cssProperty;
}
WebInspector.PropertyRevealHighlighter.prototype = {
perform: function()
{
// Expand all shorthands.
for (var section of this._styleSidebarPane.allSections()) {
for (var treeElement = section.propertiesTreeOutline.firstChild(); treeElement; treeElement = treeElement.nextSibling)
treeElement.onpopulate();
}
var highlightTreeElement = null;
for (var section of this._styleSidebarPane.allSections()) {
var treeElement = section.propertiesTreeOutline.firstChild();
while (treeElement && !highlightTreeElement) {
if (treeElement.property === this._cssProperty) {
highlightTreeElement = treeElement;
break;
}
treeElement = treeElement.traverseNextTreeElement(false, null, true);
}
if (highlightTreeElement)
break;
}
if (!highlightTreeElement)
return;
highlightTreeElement.parent.expand();
highlightTreeElement.listItemElement.scrollIntoViewIfNeeded();
highlightTreeElement.listItemElement.animate([
{ offset: 0, backgroundColor: "rgba(255, 255, 0, 0.2)"},
{ offset: 0.1, backgroundColor: "rgba(255, 255, 0, 0.7)"},
{ offset: 1, backgroundColor: "transparent"}
], { duration : 2000, easing: "cubic-bezier(0, 0, 0.2, 1)" });
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 2 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @extends {WebInspector.Object}
* @constructor
*/
WebInspector.SharedSidebarModel = function()
{
WebInspector.Object.call(this);
this._node = WebInspector.context.flavor(WebInspector.DOMNode);
WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._onNodeChanged, this);
}
/**
* @param {?WebInspector.DOMNode} node
* @return {?WebInspector.DOMNode}
*/
WebInspector.SharedSidebarModel.elementNode = function(node)
{
if (node && node.nodeType() === Node.TEXT_NODE && node.parentNode)
node = node.parentNode;
if (node && node.nodeType() !== Node.ELEMENT_NODE)
node = null;
return node;
}
WebInspector.SharedSidebarModel.Events = {
ComputedStyleChanged: "ComputedStyleChanged"
}
WebInspector.SharedSidebarModel.prototype = {
/**
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @return {?WebInspector.CSSModel}
*/
cssModel: function()
{
return this._cssModel;
},
/**
* @param {!WebInspector.Event} event
*/
_onNodeChanged: function(event)
{
this._node = /** @type {?WebInspector.DOMNode} */(event.data);
this._updateTarget(this._node ? this._node.target() : null);
this._onComputedStyleChanged();
},
/**
* @param {?WebInspector.Target} target
*/
_updateTarget: function(target)
{
if (this._target === target)
return;
if (this._targetEvents) {
WebInspector.EventTarget.removeEventListeners(this._targetEvents);
this._targetEvents = null;
}
this._target = target;
var domModel = null;
if (target) {
this._cssModel = WebInspector.CSSModel.fromTarget(target);
domModel = WebInspector.DOMModel.fromTarget(target);
}
if (domModel && this._cssModel) {
this._targetEvents = [
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._onComputedStyleChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._onComputedStyleChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged, this._onComputedStyleChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged, this._onComputedStyleChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.PseudoStateForced, this._onComputedStyleChanged, this),
this._cssModel.addEventListener(WebInspector.CSSModel.Events.ModelWasEnabled, this._onComputedStyleChanged, this),
domModel.addEventListener(WebInspector.DOMModel.Events.DOMMutated, this._onComputedStyleChanged, this)
];
}
},
/**
* @return {?WebInspector.DOMNode}
*/
_elementNode: function()
{
return WebInspector.SharedSidebarModel.elementNode(this.node());
},
/**
* @return {!Promise.<?WebInspector.SharedSidebarModel.ComputedStyle>}
*/
fetchComputedStyle: function()
{
var elementNode = this._elementNode();
var cssModel = this.cssModel();
if (!elementNode || !cssModel)
return Promise.resolve(/** @type {?WebInspector.SharedSidebarModel.ComputedStyle} */(null));
if (!this._computedStylePromise)
this._computedStylePromise = cssModel.computedStylePromise(elementNode.id).then(verifyOutdated.bind(this, elementNode));
return this._computedStylePromise;
/**
* @param {!WebInspector.DOMNode} elementNode
* @param {?Map.<string, string>} style
* @return {?WebInspector.SharedSidebarModel.ComputedStyle}
* @this {WebInspector.SharedSidebarModel}
*/
function verifyOutdated(elementNode, style)
{
return elementNode === this._elementNode() && style ? new WebInspector.SharedSidebarModel.ComputedStyle(elementNode, style) : /** @type {?WebInspector.SharedSidebarModel.ComputedStyle} */(null);
}
},
_onComputedStyleChanged: function()
{
delete this._computedStylePromise;
this.dispatchEventToListeners(WebInspector.SharedSidebarModel.Events.ComputedStyleChanged);
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {!WebInspector.DOMNode} node
* @param {!Map.<string, string>} computedStyle
*/
WebInspector.SharedSidebarModel.ComputedStyle = function(node, computedStyle)
{
this.node = node;
this.computedStyle = computedStyle;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | 2 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Brian Grinstead All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.Spectrum = function()
{
/**
* @param {!Element} parentElement
*/
function appendSwitcherIcon(parentElement)
{
var icon = parentElement.createSVGChild("svg");
icon.setAttribute("height", 16);
icon.setAttribute("width", 16);
var path = icon.createSVGChild("path");
path.setAttribute("d", "M5,6 L11,6 L8,2 Z M5,10 L11,10 L8,14 Z");
return icon;
}
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("elements/spectrum.css");
this.contentElement.tabIndex = 0;
this._colorElement = this.contentElement.createChild("div", "spectrum-color");
this._colorDragElement = this._colorElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");
var contrastRatioSVG = this._colorElement.createSVGChild("svg", "spectrum-contrast-container fill");
this._contrastRatioLine = contrastRatioSVG.createSVGChild("path", "spectrum-contrast-line");
var toolbar = new WebInspector.Toolbar("spectrum-eye-dropper", this.contentElement);
this._colorPickerButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Toggle color picker"), "eyedropper-toolbar-item");
this._colorPickerButton.setToggled(true);
this._colorPickerButton.addEventListener("click", this._toggleColorPicker.bind(this, undefined));
toolbar.appendToolbarItem(this._colorPickerButton);
var swatchElement = this.contentElement.createChild("span", "swatch");
this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");
this._hueElement = this.contentElement.createChild("div", "spectrum-hue");
this._hueSlider = this._hueElement.createChild("div", "spectrum-slider");
this._alphaElement = this.contentElement.createChild("div", "spectrum-alpha");
this._alphaElementBackground = this._alphaElement.createChild("div", "spectrum-alpha-background");
this._alphaSlider = this._alphaElement.createChild("div", "spectrum-slider");
var displaySwitcher = this.contentElement.createChild("div", "spectrum-display-switcher spectrum-switcher");
appendSwitcherIcon(displaySwitcher);
displaySwitcher.addEventListener("click", this._formatViewSwitch.bind(this));
// RGBA/HSLA display.
this._displayContainer = this.contentElement.createChild("div", "spectrum-text source-code");
this._textValues = [];
for (var i = 0; i < 4; ++i) {
var inputValue = this._displayContainer.createChild("input", "spectrum-text-value");
inputValue.maxLength = 4;
this._textValues.push(inputValue);
inputValue.addEventListener("keydown", this._inputChanged.bind(this), false);
inputValue.addEventListener("input", this._inputChanged.bind(this), false);
inputValue.addEventListener("mousewheel", this._inputChanged.bind(this), false);
}
this._textLabels = this._displayContainer.createChild("div", "spectrum-text-label");
// HEX display.
this._hexContainer = this.contentElement.createChild("div", "spectrum-text spectrum-text-hex source-code");
this._hexValue = this._hexContainer.createChild("input", "spectrum-text-value");
this._hexValue.maxLength = 7;
this._hexValue.addEventListener("keydown", this._inputChanged.bind(this), false);
this._hexValue.addEventListener("input", this._inputChanged.bind(this), false);
this._hexValue.addEventListener("mousewheel", this._inputChanged.bind(this), false);
var label = this._hexContainer.createChild("div", "spectrum-text-label");
label.textContent = "HEX";
WebInspector.installDragHandle(this._hueElement, dragStart.bind(this, positionHue.bind(this)), positionHue.bind(this), null, "default");
WebInspector.installDragHandle(this._alphaElement, dragStart.bind(this, positionAlpha.bind(this)), positionAlpha.bind(this), null, "default");
WebInspector.installDragHandle(this._colorElement, dragStart.bind(this, positionColor.bind(this)), positionColor.bind(this), null, "default");
this.element.classList.add("palettes-enabled");
/** @type {!Map.<string, !WebInspector.Spectrum.Palette>} */
this._palettes = new Map();
this._palettePanel = this.contentElement.createChild("div", "palette-panel");
this._palettePanelShowing = false;
this._paletteContainer = this.contentElement.createChild("div", "spectrum-palette");
this._paletteContainer.addEventListener("contextmenu", this._showPaletteColorContextMenu.bind(this, -1));
this._shadesContainer = this.contentElement.createChild("div", "palette-color-shades hidden");
WebInspector.installDragHandle(this._paletteContainer, this._paletteDragStart.bind(this), this._paletteDrag.bind(this), this._paletteDragEnd.bind(this), "default");
var paletteSwitcher = this.contentElement.createChild("div", "spectrum-palette-switcher spectrum-switcher");
appendSwitcherIcon(paletteSwitcher);
paletteSwitcher.addEventListener("click", this._togglePalettePanel.bind(this, true));
this._deleteIconToolbar = new WebInspector.Toolbar("delete-color-toolbar");
this._deleteButton = new WebInspector.ToolbarButton("", "garbage-collect-toolbar-item");
this._deleteIconToolbar.appendToolbarItem(this._deleteButton);
var overlay = this.contentElement.createChild("div", "spectrum-overlay fill");
overlay.addEventListener("click", this._togglePalettePanel.bind(this, false));
this._addColorToolbar = new WebInspector.Toolbar("add-color-toolbar");
var addColorButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add to palette"), "add-toolbar-item");
addColorButton.addEventListener("click", this._addColorToCustomPalette.bind(this));
this._addColorToolbar.appendToolbarItem(addColorButton);
this._loadPalettes();
new WebInspector.Spectrum.PaletteGenerator(this._generatedPaletteLoaded.bind(this));
/**
* @param {function(!Event)} callback
* @param {!Event} event
* @return {boolean}
* @this {WebInspector.Spectrum}
*/
function dragStart(callback, event)
{
this._hueAlphaLeft = this._hueElement.totalOffsetLeft();
this._colorOffset = this._colorElement.totalOffset();
callback(event);
return true;
}
/**
* @param {!Event} event
* @this {WebInspector.Spectrum}
*/
function positionHue(event)
{
var hsva = this._hsv.slice();
hsva[0] = Number.constrain(1 - (event.x - this._hueAlphaLeft) / this._hueAlphaWidth, 0, 1);
this._innerSetColor(hsva, "", undefined, WebInspector.Spectrum._ChangeSource.Other);
}
/**
* @param {!Event} event
* @this {WebInspector.Spectrum}
*/
function positionAlpha(event)
{
var newAlpha = Math.round((event.x - this._hueAlphaLeft) / this._hueAlphaWidth * 100) / 100;
var hsva = this._hsv.slice();
hsva[3] = Number.constrain(newAlpha, 0, 1);
var colorFormat = undefined;
if (hsva[3] !== 1 && (this._colorFormat === WebInspector.Color.Format.ShortHEX || this._colorFormat === WebInspector.Color.Format.HEX || this._colorFormat === WebInspector.Color.Format.Nickname))
colorFormat = WebInspector.Color.Format.RGB;
this._innerSetColor(hsva, "", colorFormat, WebInspector.Spectrum._ChangeSource.Other);
}
/**
* @param {!Event} event
* @this {WebInspector.Spectrum}
*/
function positionColor(event)
{
var hsva = this._hsv.slice();
hsva[1] = Number.constrain((event.x - this._colorOffset.left) / this.dragWidth, 0, 1);
hsva[2] = Number.constrain(1 - (event.y - this._colorOffset.top) / this.dragHeight, 0, 1);
this._innerSetColor(hsva, "", undefined, WebInspector.Spectrum._ChangeSource.Other);
}
}
WebInspector.Spectrum._ChangeSource = {
Input: "Input",
Model: "Model",
Other: "Other"
}
WebInspector.Spectrum.Events = {
ColorChanged: "ColorChanged",
SizeChanged: "SizeChanged"
};
WebInspector.Spectrum._colorChipSize = 24;
WebInspector.Spectrum._itemsPerPaletteRow = 8;
WebInspector.Spectrum.prototype = {
_updatePalettePanel: function()
{
this._palettePanel.removeChildren();
var title = this._palettePanel.createChild("div", "palette-title");
title.textContent = WebInspector.UIString("Color Palettes");
var toolbar = new WebInspector.Toolbar("", this._palettePanel);
var closeButton = new WebInspector.ToolbarButton("Return to color picker", "delete-toolbar-item");
closeButton.addEventListener("click", this._togglePalettePanel.bind(this, false));
toolbar.appendToolbarItem(closeButton);
for (var palette of this._palettes.values())
this._palettePanel.appendChild(this._createPreviewPaletteElement(palette));
},
/**
* @param {boolean} show
*/
_togglePalettePanel: function(show)
{
if (this._palettePanelShowing === show)
return;
if (show)
this._updatePalettePanel();
this._focus();
this._palettePanelShowing = show;
this.contentElement.classList.toggle("palette-panel-showing", show);
},
_focus: function()
{
if (this.isShowing() && WebInspector.currentFocusElement() !== this.contentElement)
WebInspector.setCurrentFocusElement(this.contentElement);
},
/**
* @param {string} colorText
* @param {number=} animationDelay
* @return {!Element}
*/
_createPaletteColor: function(colorText, animationDelay)
{
var element = createElementWithClass("div", "spectrum-palette-color");
element.style.background = String.sprintf("linear-gradient(%s, %s), url(Images/checker.png)", colorText, colorText);
if (animationDelay)
element.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 100, delay: animationDelay, fill: "backwards" });
element.title = colorText;
return element;
},
/**
* @param {!WebInspector.Spectrum.Palette} palette
* @param {boolean} animate
* @param {!Event=} event
*/
_showPalette: function(palette, animate, event)
{
this._resizeForSelectedPalette();
this._paletteContainer.removeChildren();
for (var i = 0; i < palette.colors.length; i++) {
var animationDelay = animate ? i * 100 / palette.colors.length : 0;
var colorElement = this._createPaletteColor(palette.colors[i], animationDelay);
colorElement.addEventListener("mousedown", this._paletteColorSelected.bind(this, palette.colors[i], palette.matchUserFormat));
if (palette.mutable) {
colorElement.__mutable = true;
colorElement.__color = palette.colors[i];
colorElement.addEventListener("contextmenu", this._showPaletteColorContextMenu.bind(this, i));
} else if (palette === WebInspector.Spectrum.MaterialPalette) {
colorElement.classList.add("has-material-shades");
var shadow = colorElement.createChild("div", "spectrum-palette-color spectrum-palette-color-shadow");
shadow.style.background = palette.colors[i];
shadow = colorElement.createChild("div", "spectrum-palette-color spectrum-palette-color-shadow");
shadow.style.background = palette.colors[i];
colorElement.title = WebInspector.UIString(palette.colors[i] + ". Long-click to show alternate shades.");
new WebInspector.LongClickController(colorElement, this._showLightnessShades.bind(this, colorElement, palette.colors[i]));
}
this._paletteContainer.appendChild(colorElement);
}
this._paletteContainerMutable = palette.mutable;
var numItems = palette.colors.length;
if (palette.mutable)
numItems++;
if (palette.mutable) {
this._paletteContainer.appendChild(this._addColorToolbar.element);
this._paletteContainer.appendChild(this._deleteIconToolbar.element);
} else {
this._addColorToolbar.element.remove();
this._deleteIconToolbar.element.remove();
}
this._togglePalettePanel(false);
this._focus();
},
/**
* @param {!Element} colorElement
* @param {string} colorText
* @param {!Event} event
*/
_showLightnessShades: function(colorElement, colorText, event)
{
/**
* @param {!Element} element
* @this {!WebInspector.Spectrum}
*/
function closeLightnessShades(element)
{
this._shadesContainer.classList.add("hidden");
element.classList.remove("spectrum-shades-shown");
this._shadesContainer.ownerDocument.removeEventListener("mousedown", this._shadesCloseHandler, true);
delete this._shadesCloseHandler;
}
if (this._shadesCloseHandler)
this._shadesCloseHandler();
this._shadesContainer.classList.remove("hidden");
this._shadesContainer.removeChildren();
this._shadesContainer.animate([{ transform: "scaleY(0)", opacity: "0" }, { transform: "scaleY(1)", opacity: "1" }], { duration: 200, easing: "cubic-bezier(0.4, 0, 0.2, 1)" });
this._shadesContainer.style.top = colorElement.offsetTop + colorElement.parentElement.offsetTop + "px";
this._shadesContainer.style.left = colorElement.offsetLeft + "px";
colorElement.classList.add("spectrum-shades-shown");
var shades = WebInspector.Spectrum.MaterialPaletteShades[colorText];
for (var i = shades.length - 1; i >= 0; i--) {
var shadeElement = this._createPaletteColor(shades[i], i * 200 / shades.length + 100);
shadeElement.addEventListener("mousedown", this._paletteColorSelected.bind(this, shades[i], false));
this._shadesContainer.appendChild(shadeElement);
}
WebInspector.setCurrentFocusElement(this._shadesContainer);
this._shadesCloseHandler = closeLightnessShades.bind(this, colorElement);
this._shadesContainer.ownerDocument.addEventListener("mousedown", this._shadesCloseHandler, true);
},
/**
* @param {!Event} e
* @return {number}
*/
_slotIndexForEvent: function(e)
{
var localX = e.pageX - this._paletteContainer.totalOffsetLeft();
var localY = e.pageY - this._paletteContainer.totalOffsetTop();
var col = Math.min(localX / WebInspector.Spectrum._colorChipSize | 0, WebInspector.Spectrum._itemsPerPaletteRow - 1);
var row = (localY / WebInspector.Spectrum._colorChipSize) | 0;
return Math.min(row * WebInspector.Spectrum._itemsPerPaletteRow + col, this._customPaletteSetting.get().colors.length - 1);
},
/**
* @param {!Event} e
* @return {boolean}
*/
_isDraggingToBin: function(e)
{
return e.pageX > this._deleteIconToolbar.element.totalOffsetLeft();
},
/**
* @param {!Event} e
* @return {boolean}
*/
_paletteDragStart: function(e)
{
var element = e.deepElementFromPoint();
if (!element || !element.__mutable)
return false;
var index = this._slotIndexForEvent(e);
this._dragElement = element;
this._dragHotSpotX = e.pageX - (index % WebInspector.Spectrum._itemsPerPaletteRow) * WebInspector.Spectrum._colorChipSize;
this._dragHotSpotY = e.pageY - (index / WebInspector.Spectrum._itemsPerPaletteRow | 0) * WebInspector.Spectrum._colorChipSize;
return true;
},
/**
* @param {!Event} e
*/
_paletteDrag: function(e)
{
if (e.pageX < this._paletteContainer.totalOffsetLeft() || e.pageY < this._paletteContainer.totalOffsetTop())
return;
var newIndex = this._slotIndexForEvent(e);
var offsetX = e.pageX - (newIndex % WebInspector.Spectrum._itemsPerPaletteRow) * WebInspector.Spectrum._colorChipSize;
var offsetY = e.pageY - (newIndex / WebInspector.Spectrum._itemsPerPaletteRow | 0) * WebInspector.Spectrum._colorChipSize;
var isDeleting = this._isDraggingToBin(e);
this._deleteIconToolbar.element.classList.add("dragging");
this._deleteIconToolbar.element.classList.toggle("delete-color-toolbar-active", isDeleting);
var dragElementTransform = "translateX(" + (offsetX - this._dragHotSpotX) + "px) translateY(" + (offsetY - this._dragHotSpotY) + "px)";
this._dragElement.style.transform = isDeleting ? dragElementTransform + " scale(0.8)" : dragElementTransform;
var children = Array.prototype.slice.call(this._paletteContainer.children);
var index = children.indexOf(this._dragElement);
/** @type {!Map.<!Element, {left: number, top: number}>} */
var swatchOffsets = new Map();
for (var swatch of children)
swatchOffsets.set(swatch, swatch.totalOffset());
if (index !== newIndex)
this._paletteContainer.insertBefore(this._dragElement, children[newIndex > index ? newIndex + 1 : newIndex]);
for (var swatch of children) {
if (swatch === this._dragElement)
continue;
var before = swatchOffsets.get(swatch);
var after = swatch.totalOffset();
if (before.left !== after.left || before.top !== after.top) {
swatch.animate([
{ transform: "translateX(" + (before.left - after.left) + "px) translateY(" + (before.top - after.top) + "px)" },
{ transform: "none" }], { duration: 100, easing: "cubic-bezier(0, 0, 0.2, 1)" });
}
}
},
/**
* @param {!Event} e
*/
_paletteDragEnd: function(e)
{
if (this._isDraggingToBin(e))
this._dragElement.remove();
this._dragElement.style.removeProperty("transform");
var children = this._paletteContainer.children;
var colors = [];
for (var i = 0; i < children.length; ++i) {
if (children[i].__color)
colors.push(children[i].__color);
}
var palette = this._customPaletteSetting.get();
palette.colors = colors;
this._customPaletteSetting.set(palette);
this._showPalette(this._customPaletteSetting.get(), false);
this._deleteIconToolbar.element.classList.remove("dragging");
this._deleteIconToolbar.element.classList.remove("delete-color-toolbar-active");
},
_loadPalettes: function()
{
this._palettes.set(WebInspector.Spectrum.MaterialPalette.title, WebInspector.Spectrum.MaterialPalette);
/** @type {!WebInspector.Spectrum.Palette} */
var defaultCustomPalette = { title: "Custom", colors: [], mutable: true };
this._customPaletteSetting = WebInspector.settings.createSetting("customColorPalette", defaultCustomPalette);
this._palettes.set(this._customPaletteSetting.get().title, this._customPaletteSetting.get());
this._selectedColorPalette = WebInspector.settings.createSetting("selectedColorPalette", WebInspector.Spectrum.GeneratedPaletteTitle);
var palette = this._palettes.get(this._selectedColorPalette.get());
if (palette)
this._showPalette(palette, true);
},
/**
* @param {!WebInspector.Spectrum.Palette} generatedPalette
*/
_generatedPaletteLoaded: function(generatedPalette)
{
if (generatedPalette.colors.length)
this._palettes.set(generatedPalette.title, generatedPalette);
if (this._selectedColorPalette.get() !== generatedPalette.title) {
return;
} else if (!generatedPalette.colors.length) {
this._paletteSelected(WebInspector.Spectrum.MaterialPalette);
return;
}
this._showPalette(generatedPalette, true);
},
/**
* @param {!WebInspector.Spectrum.Palette} palette
* @return {!Element}
*/
_createPreviewPaletteElement: function(palette)
{
var colorsPerPreviewRow = 5;
var previewElement = createElementWithClass("div", "palette-preview");
var titleElement = previewElement.createChild("div", "palette-preview-title");
titleElement.textContent = palette.title;
for (var i = 0; i < colorsPerPreviewRow && i < palette.colors.length; i++)
previewElement.appendChild(this._createPaletteColor(palette.colors[i]));
for (; i < colorsPerPreviewRow; i++)
previewElement.createChild("div", "spectrum-palette-color empty-color");
previewElement.addEventListener("click", this._paletteSelected.bind(this, palette));
return previewElement;
},
/**
* @param {!WebInspector.Spectrum.Palette} palette
*/
_paletteSelected: function(palette)
{
this._selectedColorPalette.set(palette.title);
this._showPalette(palette, true);
},
_resizeForSelectedPalette: function()
{
var palette = this._palettes.get(this._selectedColorPalette.get());
if (!palette)
return;
var numColors = palette.colors.length;
if (palette === this._customPaletteSetting.get())
numColors++;
var rowsNeeded = Math.max(1, Math.ceil(numColors / WebInspector.Spectrum._itemsPerPaletteRow));
if (this._numPaletteRowsShown === rowsNeeded)
return;
this._numPaletteRowsShown = rowsNeeded;
var paletteColorHeight = 12;
var paletteMargin = 12;
var paletteTop = 235;
this.element.style.height = (paletteTop + paletteMargin + (paletteColorHeight + paletteMargin) * rowsNeeded) + "px";
this.dispatchEventToListeners(WebInspector.Spectrum.Events.SizeChanged);
},
/**
* @param {string} colorText
* @param {boolean} matchUserFormat
*/
_paletteColorSelected: function(colorText, matchUserFormat)
{
var color = WebInspector.Color.parse(colorText);
if (!color)
return;
this._innerSetColor(color.hsva(), colorText, matchUserFormat ? this._colorFormat : color.format(), WebInspector.Spectrum._ChangeSource.Other);
},
_addColorToCustomPalette: function()
{
var palette = this._customPaletteSetting.get();
palette.colors.push(this.colorString());
this._customPaletteSetting.set(palette);
this._showPalette(this._customPaletteSetting.get(), false);
},
/**
* @param {number} colorIndex
* @param {!Event} event
*/
_showPaletteColorContextMenu: function(colorIndex, event)
{
if (!this._paletteContainerMutable)
return;
var contextMenu = new WebInspector.ContextMenu(event);
if (colorIndex !== -1) {
contextMenu.appendItem(WebInspector.UIString("Remove color"), this._deletePaletteColors.bind(this, colorIndex, false));
contextMenu.appendItem(WebInspector.UIString("Remove all to the right"), this._deletePaletteColors.bind(this, colorIndex, true));
}
contextMenu.appendItem(WebInspector.UIString("Clear palette"), this._deletePaletteColors.bind(this, -1, true));
contextMenu.show();
},
/**
* @param {number} colorIndex
* @param {boolean} toRight
*/
_deletePaletteColors: function(colorIndex, toRight)
{
var palette = this._customPaletteSetting.get();
if (toRight)
palette.colors.splice(colorIndex + 1, palette.colors.length - colorIndex - 1);
else
palette.colors.splice(colorIndex, 1);
this._customPaletteSetting.set(palette);
this._showPalette(this._customPaletteSetting.get(), false);
},
/**
* @param {!WebInspector.Color} color
* @param {string} colorFormat
*/
setColor: function(color, colorFormat)
{
this._originalFormat = colorFormat;
this._innerSetColor(color.hsva(), "", colorFormat, WebInspector.Spectrum._ChangeSource.Model);
},
/**
* @param {!Array<number>|undefined} hsva
* @param {string|undefined} colorString
* @param {string|undefined} colorFormat
* @param {string} changeSource
*/
_innerSetColor: function(hsva, colorString, colorFormat, changeSource)
{
if (hsva !== undefined)
this._hsv = hsva;
if (colorString !== undefined)
this._colorString = colorString;
if (colorFormat !== undefined) {
console.assert(colorFormat !== WebInspector.Color.Format.Original, "Spectrum's color format cannot be Original");
if (colorFormat === WebInspector.Color.Format.RGBA)
colorFormat = WebInspector.Color.Format.RGB;
else if (colorFormat === WebInspector.Color.Format.HSLA)
colorFormat = WebInspector.Color.Format.HSL;
this._colorFormat = colorFormat;
}
this._updateHelperLocations();
this._updateUI();
if (changeSource !== WebInspector.Spectrum._ChangeSource.Input)
this._updateInput();
if (changeSource !== WebInspector.Spectrum._ChangeSource.Model)
this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.colorString());
},
/**
* @param {!WebInspector.Color} color
*/
setContrastColor: function(color)
{
this._contrastColor = color;
this._updateUI();
},
/**
* @return {!WebInspector.Color}
*/
_color: function()
{
return WebInspector.Color.fromHSVA(this._hsv);
},
/**
* @return {string}
*/
colorString: function()
{
if (this._colorString)
return this._colorString;
var cf = WebInspector.Color.Format;
var color = this._color();
var colorString = color.asString(this._colorFormat);
if (colorString)
return colorString;
if (this._colorFormat === cf.Nickname || this._colorFormat === cf.ShortHEX) {
colorString = color.asString(cf.HEX);
if (colorString)
return colorString;
}
console.assert(color.hasAlpha());
return this._colorFormat === cf.HSL ? /** @type {string} */(color.asString(cf.HSLA)) : /** @type {string} */(color.asString(cf.RGBA));
},
_updateHelperLocations: function()
{
var h = this._hsv[0];
var s = this._hsv[1];
var v = this._hsv[2];
var alpha = this._hsv[3];
// Where to show the little circle that displays your current selected color.
var dragX = s * this.dragWidth;
var dragY = this.dragHeight - (v * this.dragHeight);
dragX = Math.max(-this._colorDragElementHeight,
Math.min(this.dragWidth - this._colorDragElementHeight, dragX - this._colorDragElementHeight));
dragY = Math.max(-this._colorDragElementHeight,
Math.min(this.dragHeight - this._colorDragElementHeight, dragY - this._colorDragElementHeight));
this._colorDragElement.positionAt(dragX, dragY);
// Where to show the bar that displays your current selected hue.
var hueSlideX = (1 - h) * this._hueAlphaWidth - this.slideHelperWidth;
this._hueSlider.style.left = hueSlideX + "px";
var alphaSlideX = alpha * this._hueAlphaWidth - this.slideHelperWidth;
this._alphaSlider.style.left = alphaSlideX + "px";
},
_updateInput: function()
{
var cf = WebInspector.Color.Format;
if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX || this._colorFormat === cf.Nickname) {
this._hexContainer.hidden = false;
this._displayContainer.hidden = true;
if (this._colorFormat === cf.ShortHEX && this._color().canBeShortHex())
this._hexValue.value = this._color().asString(cf.ShortHEX);
else
this._hexValue.value = this._color().asString(cf.HEX);
} else {
// RGBA, HSLA display.
this._hexContainer.hidden = true;
this._displayContainer.hidden = false;
var isRgb = this._colorFormat === cf.RGB;
this._textLabels.textContent = isRgb ? "RGBA" : "HSLA";
var colorValues = isRgb ? this._color().canonicalRGBA() : this._color().canonicalHSLA();
for (var i = 0; i < 3; ++i) {
this._textValues[i].value = colorValues[i];
if (!isRgb && (i === 1 || i === 2))
this._textValues[i].value += "%";
}
this._textValues[3].value= Math.round(colorValues[3] * 100) / 100;
}
},
/**
* @param {number} requiredContrast
*/
_drawContrastRatioLine: function(requiredContrast)
{
if (!this._contrastColor || !this.dragWidth || !this.dragHeight)
return;
/** const */ var width = this.dragWidth;
/** const */ var height = this.dragHeight;
/** const */ var dS = 0.02;
/** const */ var epsilon = 0.002;
/** const */ var H = 0;
/** const */ var S = 1;
/** const */ var V = 2;
/** const */ var A = 3;
var fgRGBA = [];
WebInspector.Color.hsva2rgba(this._hsv, fgRGBA);
var fgLuminance = WebInspector.Color.luminance(fgRGBA);
var bgRGBA = this._contrastColor.rgba();
var bgLuminance = WebInspector.Color.luminance(bgRGBA);
var fgIsLighter = fgLuminance > bgLuminance;
var desiredLuminance = WebInspector.Color.desiredLuminance(bgLuminance, requiredContrast, fgIsLighter);
var lastV = this._hsv[V];
var currentSlope = 0;
var candidateHSVA = [this._hsv[H], 0, 0, this._hsv[A]];
var pathBuilder = [];
var candidateRGBA = [];
WebInspector.Color.hsva2rgba(candidateHSVA, candidateRGBA);
var blendedRGBA = [];
WebInspector.Color.blendColors(candidateRGBA, bgRGBA, blendedRGBA);
/**
* Approach the desired contrast ratio by modifying the given component
* from the given starting value.
* @param {number} index
* @param {number} x
* @param {boolean} onAxis
* @return {?number}
*/
function approach(index, x, onAxis)
{
while (0 <= x && x <= 1) {
candidateHSVA[index] = x;
WebInspector.Color.hsva2rgba(candidateHSVA, candidateRGBA);
WebInspector.Color.blendColors(candidateRGBA, bgRGBA, blendedRGBA);
var fgLuminance = WebInspector.Color.luminance(blendedRGBA);
var dLuminance = fgLuminance - desiredLuminance;
if (Math.abs(dLuminance) < (onAxis ? epsilon / 10 : epsilon))
return x;
else
x += (index === V ? -dLuminance : dLuminance);
}
return null;
}
for (var s = 0; s < 1 + dS; s += dS) {
s = Math.min(1, s);
candidateHSVA[S] = s;
var v = lastV;
v = lastV + currentSlope * dS;
v = approach(V, v, s == 0);
if (v === null)
break;
currentSlope = (v - lastV) / dS;
pathBuilder.push(pathBuilder.length ? "L" : "M");
pathBuilder.push(s * width);
pathBuilder.push((1 - v) * height);
}
if (s < 1 + dS) {
s -= dS;
candidateHSVA[V] = 1;
s = approach(S, s, true);
if (s !== null)
pathBuilder = pathBuilder.concat(["L", s * width, -1])
}
this._contrastRatioLine.setAttribute("d", pathBuilder.join(" "));
},
_updateUI: function()
{
var h = WebInspector.Color.fromHSVA([this._hsv[0], 1, 1, 1]);
this._colorElement.style.backgroundColor = /** @type {string} */ (h.asString(WebInspector.Color.Format.RGB));
if (Runtime.experiments.isEnabled("colorContrastRatio")) {
// TODO(samli): Determine size of text and switch between AA/AAA ratings.
this._drawContrastRatioLine(4.5);
}
this._swatchInnerElement.style.backgroundColor = /** @type {string} */ (this._color().asString(WebInspector.Color.Format.RGBA));
// Show border if the swatch is white.
this._swatchInnerElement.classList.toggle("swatch-inner-white", this._color().hsla()[2] > 0.9);
this._colorDragElement.style.backgroundColor = /** @type {string} */ (this._color().asString(WebInspector.Color.Format.RGBA));
var noAlpha = WebInspector.Color.fromHSVA(this._hsv.slice(0,3).concat(1));
this._alphaElementBackground.style.backgroundImage = String.sprintf("linear-gradient(to right, rgba(0,0,0,0), %s)", noAlpha.asString(WebInspector.Color.Format.RGB));
},
_formatViewSwitch: function()
{
var cf = WebInspector.Color.Format;
var format = cf.RGB;
if (this._colorFormat === cf.RGB)
format = cf.HSL;
else if (this._colorFormat === cf.HSL && !this._color().hasAlpha())
format = this._originalFormat === cf.ShortHEX ? cf.ShortHEX : cf.HEX;
this._innerSetColor(undefined, "", format, WebInspector.Spectrum._ChangeSource.Other);
},
/**
* @param {!Event} event
*/
_inputChanged: function(event)
{
/**
* @param {!Element} element
* @return {string}
*/
function elementValue(element)
{
return element.value;
}
var inputElement = /** @type {!Element} */(event.currentTarget);
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (arrowKeyOrMouseWheelEvent || pageKeyPressed) {
var newValue = WebInspector.createReplacementString(inputElement.value, event);
if (newValue) {
inputElement.value = newValue;
inputElement.selectionStart = 0;
inputElement.selectionEnd = newValue.length;
}
event.consume(true);
}
const cf = WebInspector.Color.Format;
var colorString;
if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX) {
colorString = this._hexValue.value;
} else {
var format = this._colorFormat === cf.RGB ? "rgba" : "hsla";
var values = this._textValues.map(elementValue).join(",");
colorString = String.sprintf("%s(%s)", format, values);
}
var color = WebInspector.Color.parse(colorString);
if (!color)
return;
var hsv = color.hsva();
if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX)
this._colorFormat = color.canBeShortHex() ? cf.ShortHEX : cf.HEX;
this._innerSetColor(hsv, colorString, undefined, WebInspector.Spectrum._ChangeSource.Input);
},
wasShown: function()
{
this._hueAlphaWidth = this._hueElement.offsetWidth;
this.slideHelperWidth = this._hueSlider.offsetWidth / 2;
this.dragWidth = this._colorElement.offsetWidth;
this.dragHeight = this._colorElement.offsetHeight;
this._colorDragElementHeight = this._colorDragElement.offsetHeight / 2;
this._innerSetColor(undefined, undefined, undefined, WebInspector.Spectrum._ChangeSource.Model);
this._toggleColorPicker(true);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.ColorPicked, this._colorPicked, this);
},
willHide: function()
{
this._toggleColorPicker(false);
WebInspector.targetManager.removeModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.ColorPicked, this._colorPicked, this);
},
/**
* @param {boolean=} enabled
* @param {!WebInspector.Event=} event
*/
_toggleColorPicker: function(enabled, event)
{
if (enabled === undefined)
enabled = !this._colorPickerButton.toggled();
this._colorPickerButton.setToggled(enabled);
for (var target of WebInspector.targetManager.targets())
target.pageAgent().setColorPickerEnabled(enabled);
},
/**
* @param {!WebInspector.Event} event
*/
_colorPicked: function(event)
{
var rgbColor = /** @type {!DOMAgent.RGBA} */ (event.data);
var rgba = [rgbColor.r, rgbColor.g, rgbColor.b, (rgbColor.a / 2.55 | 0) / 100];
var color = WebInspector.Color.fromRGBA(rgba);
this._innerSetColor(color.hsva(), "", undefined, WebInspector.Spectrum._ChangeSource.Other);
InspectorFrontendHost.bringToFront();
},
__proto__: WebInspector.VBox.prototype
}
/** @typedef {{ title: string, colors: !Array.<string>, mutable: boolean }} */
WebInspector.Spectrum.Palette;
WebInspector.Spectrum.GeneratedPaletteTitle = "Page colors";
/**
* @constructor
* @param {function(!WebInspector.Spectrum.Palette)} callback
*/
WebInspector.Spectrum.PaletteGenerator = function(callback)
{
this._callback = callback;
/** @type {!Map.<string, number>} */
this._frequencyMap = new Map();
var stylesheetPromises = [];
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)) {
var cssModel = WebInspector.CSSModel.fromTarget(target);
for (var stylesheet of cssModel.allStyleSheets())
stylesheetPromises.push(new Promise(this._processStylesheet.bind(this, stylesheet)));
}
Promise.all(stylesheetPromises)
.catchException(null)
.then(this._finish.bind(this));
}
WebInspector.Spectrum.PaletteGenerator.prototype = {
/**
* @param {string} a
* @param {string} b
* @return {number}
*/
_frequencyComparator: function(a, b)
{
return this._frequencyMap.get(b) - this._frequencyMap.get(a);
},
_finish: function()
{
/**
* @param {string} a
* @param {string} b
* @return {number}
*/
function hueComparator(a, b)
{
var hsva = paletteColors.get(a).hsva();
var hsvb = paletteColors.get(b).hsva();
// First trim the shades of gray
if (hsvb[1] < 0.12 && hsva[1] < 0.12)
return hsvb[2]*hsvb[3] - hsva[2]*hsva[3];
if (hsvb[1] < 0.12)
return -1;
if (hsva[1] < 0.12)
return 1;
// Equal hue -> sort by sat
if (hsvb[0] === hsva[0])
return hsvb[1]*hsvb[3] - hsva[1]*hsva[3];
return (hsvb[0] + 0.94) % 1 - (hsva[0] + 0.94) % 1;
}
var colors = this._frequencyMap.keysArray();
colors = colors.sort(this._frequencyComparator.bind(this));
/** @type {!Map.<string, !WebInspector.Color>} */
var paletteColors = new Map();
var colorsPerRow = 24;
while (paletteColors.size < colorsPerRow && colors.length) {
var colorText = colors.shift();
var color = WebInspector.Color.parse(colorText);
if (!color || color.nickname() === "white" || color.nickname() === "black")
continue;
paletteColors.set(colorText, color);
}
this._callback({ title: WebInspector.Spectrum.GeneratedPaletteTitle, colors: paletteColors.keysArray().sort(hueComparator), mutable: false });
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} stylesheet
* @param {function(?)} resolve
* @this {WebInspector.Spectrum.PaletteGenerator}
*/
_processStylesheet: function(stylesheet, resolve)
{
/**
* @param {?string} text
* @this {WebInspector.Spectrum.PaletteGenerator}
*/
function parseContent(text)
{
text = text.toLowerCase();
var regexResult = text.match(/((?:rgb|hsl)a?\([^)]+\)|#[0-9a-f]{6}|#[0-9a-f]{3})/g) || [];
for (var c of regexResult) {
var frequency = this._frequencyMap.get(c) || 0;
this._frequencyMap.set(c, ++frequency);
}
resolve(null);
}
stylesheet.requestContent().then(parseContent.bind(this));
}
}
WebInspector.Spectrum.MaterialPaletteShades = {
"#F44336": ["#FFEBEE", "#FFCDD2", "#EF9A9A", "#E57373", "#EF5350", "#F44336", "#E53935", "#D32F2F", "#C62828", "#B71C1C"],
"#E91E63": ["#FCE4EC", "#F8BBD0", "#F48FB1", "#F06292", "#EC407A", "#E91E63", "#D81B60", "#C2185B", "#AD1457", "#880E4F"],
"#9C27B0": ["#F3E5F5", "#E1BEE7", "#CE93D8", "#BA68C8", "#AB47BC", "#9C27B0", "#8E24AA", "#7B1FA2", "#6A1B9A", "#4A148C"],
"#673AB7": ["#EDE7F6", "#D1C4E9", "#B39DDB", "#9575CD", "#7E57C2", "#673AB7", "#5E35B1", "#512DA8", "#4527A0", "#311B92"],
"#3F51B5": ["#E8EAF6", "#C5CAE9", "#9FA8DA", "#7986CB", "#5C6BC0", "#3F51B5", "#3949AB", "#303F9F", "#283593", "#1A237E"],
"#2196F3": ["#E3F2FD", "#BBDEFB", "#90CAF9", "#64B5F6", "#42A5F5", "#2196F3", "#1E88E5", "#1976D2", "#1565C0", "#0D47A1"],
"#03A9F4": ["#E1F5FE", "#B3E5FC", "#81D4FA", "#4FC3F7", "#29B6F6", "#03A9F4", "#039BE5", "#0288D1", "#0277BD", "#01579B"],
"#00BCD4": ["#E0F7FA", "#B2EBF2", "#80DEEA", "#4DD0E1", "#26C6DA", "#00BCD4", "#00ACC1", "#0097A7", "#00838F", "#006064"],
"#009688": ["#E0F2F1", "#B2DFDB", "#80CBC4", "#4DB6AC", "#26A69A", "#009688", "#00897B", "#00796B", "#00695C", "#004D40"],
"#4CAF50": ["#E8F5E9", "#C8E6C9", "#A5D6A7", "#81C784", "#66BB6A", "#4CAF50", "#43A047", "#388E3C", "#2E7D32", "#1B5E20"],
"#8BC34A": ["#F1F8E9", "#DCEDC8", "#C5E1A5", "#AED581", "#9CCC65", "#8BC34A", "#7CB342", "#689F38", "#558B2F", "#33691E"],
"#CDDC39": ["#F9FBE7", "#F0F4C3", "#E6EE9C", "#DCE775", "#D4E157", "#CDDC39", "#C0CA33", "#AFB42B", "#9E9D24", "#827717"],
"#FFEB3B": ["#FFFDE7", "#FFF9C4", "#FFF59D", "#FFF176", "#FFEE58", "#FFEB3B", "#FDD835", "#FBC02D", "#F9A825", "#F57F17"],
"#FFC107": ["#FFF8E1", "#FFECB3", "#FFE082", "#FFD54F", "#FFCA28", "#FFC107", "#FFB300", "#FFA000", "#FF8F00", "#FF6F00"],
"#FF9800": ["#FFF3E0", "#FFE0B2", "#FFCC80", "#FFB74D", "#FFA726", "#FF9800", "#FB8C00", "#F57C00", "#EF6C00", "#E65100"],
"#FF5722": ["#FBE9E7", "#FFCCBC", "#FFAB91", "#FF8A65", "#FF7043", "#FF5722", "#F4511E", "#E64A19", "#D84315", "#BF360C"],
"#795548": ["#EFEBE9", "#D7CCC8", "#BCAAA4", "#A1887F", "#8D6E63", "#795548", "#6D4C41", "#5D4037", "#4E342E", "#3E2723"],
"#9E9E9E": ["#FAFAFA", "#F5F5F5", "#EEEEEE", "#E0E0E0", "#BDBDBD", "#9E9E9E", "#757575", "#616161", "#424242", "#212121"],
"#607D8B": ["#ECEFF1", "#CFD8DC", "#B0BEC5", "#90A4AE", "#78909C", "#607D8B", "#546E7A", "#455A64", "#37474F", "#263238"]
};
WebInspector.Spectrum.MaterialPalette = { title: "Material", mutable: false, matchUserFormat: true, colors: Object.keys(WebInspector.Spectrum.MaterialPaletteShades) };
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.StylesPopoverHelper = function()
{
this._popover = new WebInspector.Popover();
this._popover.setCanShrink(false);
this._popover.setNoMargins(true);
this._popover.element.addEventListener("mousedown", consumeEvent, false);
this._hideProxy = this.hide.bind(this, true);
this._boundOnKeyDown = this._onKeyDown.bind(this);
this._repositionBound = this.reposition.bind(this);
this._boundFocusOut = this._onFocusOut.bind(this);
}
WebInspector.StylesPopoverHelper.prototype = {
/**
* @param {!Event} event
*/
_onFocusOut: function(event)
{
if (!event.relatedTarget || event.relatedTarget.isSelfOrDescendant(this._view.contentElement))
return;
this._hideProxy();
},
/**
* @return {boolean}
*/
isShowing: function()
{
return this._popover.isShowing();
},
/**
* @param {!WebInspector.Widget} view
* @param {!Element} anchorElement
* @param {function(boolean)=} hiddenCallback
*/
show: function(view, anchorElement, hiddenCallback)
{
if (this._popover.isShowing()) {
if (this._anchorElement === anchorElement)
return;
// Reopen the picker for another anchor element.
this.hide(true);
}
delete this._isHidden;
this._anchorElement = anchorElement;
this._view = view;
this._hiddenCallback = hiddenCallback;
this.reposition();
var document = this._popover.element.ownerDocument;
document.addEventListener("mousedown", this._hideProxy, false);
document.defaultView.addEventListener("resize", this._hideProxy, false);
this._view.contentElement.addEventListener("keydown", this._boundOnKeyDown, false);
this._scrollerElement = anchorElement.enclosingNodeOrSelfWithClass("style-panes-wrapper");
if (this._scrollerElement)
this._scrollerElement.addEventListener("scroll", this._repositionBound, false);
},
/**
* @param {!Event=} event
*/
reposition: function(event)
{
if (!this._previousFocusElement)
this._previousFocusElement = WebInspector.currentFocusElement();
// Unbind "blur" listener to avoid reenterability: |popover.showView| will hide the popover and trigger it synchronously.
this._view.contentElement.removeEventListener("focusout", this._boundFocusOut, false);
this._popover.showView(this._view, this._anchorElement);
this._view.contentElement.addEventListener("focusout", this._boundFocusOut, false);
WebInspector.setCurrentFocusElement(this._view.contentElement);
},
/**
* @param {boolean=} commitEdit
*/
hide: function(commitEdit)
{
if (this._isHidden)
return;
var document = this._popover.element.ownerDocument;
this._isHidden = true;
this._popover.hide();
if (this._scrollerElement)
this._scrollerElement.removeEventListener("scroll", this._repositionBound, false);
document.removeEventListener("mousedown", this._hideProxy, false);
document.defaultView.removeEventListener("resize", this._hideProxy, false);
if (this._hiddenCallback)
this._hiddenCallback.call(null, !!commitEdit);
WebInspector.setCurrentFocusElement(this._previousFocusElement);
delete this._previousFocusElement;
delete this._anchorElement;
if (this._view) {
this._view.detach();
this._view.contentElement.removeEventListener("keydown", this._boundOnKeyDown, false);
this._view.contentElement.removeEventListener("focusout", this._boundFocusOut, false);
delete this._view;
}
},
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
if (event.keyIdentifier === "Enter") {
this.hide(true);
event.consume(true);
return;
}
if (event.keyIdentifier === "U+001B") { // Escape key
this.hide(false);
event.consume(true);
}
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {!WebInspector.StylePropertyTreeElement} treeElement
* @param {!WebInspector.StylesPopoverHelper} stylesPopoverHelper
* @param {string} text
*/
WebInspector.BezierPopoverIcon = function(treeElement, stylesPopoverHelper, text)
{
this._treeElement = treeElement;
this._stylesPopoverHelper = stylesPopoverHelper;
this._createDOM(text);
this._boundBezierChanged = this._bezierChanged.bind(this);
}
WebInspector.BezierPopoverIcon.prototype = {
/**
* @return {!Element}
*/
element: function()
{
return this._element;
},
/**
* @param {string} text
*/
_createDOM: function(text)
{
this._element = createElement("nobr");
this._element.title = WebInspector.UIString("Open cubic bezier editor");
this._iconElement = this._element.createChild("div", "popover-icon bezier-icon");
var svg = this._iconElement.createSVGChild("svg");
svg.setAttribute("height", 10);
svg.setAttribute("width", 10);
this._iconElement.addEventListener("click", this._iconClick.bind(this), false);
var g = svg.createSVGChild("g");
var path = g.createSVGChild("path");
path.setAttribute("d", "M2,8 C2,3 8,7 8,2");
this._bezierValueElement = this._element.createChild("span");
this._bezierValueElement.textContent = text;
},
/**
* @param {!Event} event
*/
_iconClick: function(event)
{
event.consume(true);
if (this._stylesPopoverHelper.isShowing()) {
this._stylesPopoverHelper.hide(true);
return;
}
this._bezierEditor = new WebInspector.BezierEditor();
var geometry = WebInspector.Geometry.CubicBezier.parse(this._bezierValueElement.textContent);
this._bezierEditor.setBezier(geometry);
this._bezierEditor.addEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
this._stylesPopoverHelper.show(this._bezierEditor, this._iconElement, this._onPopoverHidden.bind(this));
this._originalPropertyText = this._treeElement.property.propertyText;
this._treeElement.parentPane().setEditingStyle(true);
},
/**
* @param {!WebInspector.Event} event
*/
_bezierChanged: function(event)
{
this._bezierValueElement.textContent = /** @type {string} */ (event.data);
this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
},
/**
* @param {boolean} commitEdit
*/
_onPopoverHidden: function(commitEdit)
{
this._bezierEditor.removeEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
delete this._bezierEditor;
var propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
this._treeElement.applyStyleText(propertyText, true);
this._treeElement.parentPane().setEditingStyle(false);
delete this._originalPropertyText;
}
}
/**
* @constructor
* @param {!WebInspector.StylePropertyTreeElement} treeElement
* @param {!WebInspector.StylesPopoverHelper} stylesPopoverHelper
* @param {string} colorText
*/
WebInspector.ColorSwatchPopoverIcon = function(treeElement, stylesPopoverHelper, colorText)
{
this._treeElement = treeElement;
this._treeElement[WebInspector.ColorSwatchPopoverIcon._treeElementSymbol] = this;
this._stylesPopoverHelper = stylesPopoverHelper;
this._swatch = WebInspector.ColorSwatch.create();
this._swatch.setColorText(colorText);
this._swatch.setFormat(WebInspector.Color.detectColorFormat(this._swatch.color()));
var shiftClickMessage = WebInspector.UIString("Shift + Click to change color format.");
this._swatch.iconElement().title = WebInspector.UIString("Open color picker. %s", shiftClickMessage);
this._swatch.iconElement().addEventListener("click", this._iconClick.bind(this));
this._contrastColor = null;
this._boundSpectrumChanged = this._spectrumChanged.bind(this);
}
WebInspector.ColorSwatchPopoverIcon._treeElementSymbol = Symbol("WebInspector.ColorSwatchPopoverIcon._treeElementSymbol");
/**
* @param {!WebInspector.StylePropertyTreeElement} treeElement
* @return {?WebInspector.ColorSwatchPopoverIcon}
*/
WebInspector.ColorSwatchPopoverIcon.forTreeElement = function(treeElement)
{
return treeElement[WebInspector.ColorSwatchPopoverIcon._treeElementSymbol] || null;
}
WebInspector.ColorSwatchPopoverIcon.prototype = {
/**
* @return {!Element}
*/
element: function()
{
return this._swatch;
},
/**
* @param {!WebInspector.Color} color
*/
setContrastColor: function(color)
{
this._contrastColor = color;
if (this._spectrum)
this._spectrum.setContrastColor(this._contrastColor);
},
/**
* @param {!Event} event
*/
_iconClick: function(event)
{
event.consume(true);
this.showPopover();
},
showPopover: function()
{
if (this._stylesPopoverHelper.isShowing()) {
this._stylesPopoverHelper.hide(true);
return;
}
var color = this._swatch.color();
var format = this._swatch.format();
if (format === WebInspector.Color.Format.Original)
format = color.format();
this._spectrum = new WebInspector.Spectrum();
this._spectrum.setColor(color, format);
if (this._contrastColor)
this._spectrum.setContrastColor(this._contrastColor);
this._spectrum.addEventListener(WebInspector.Spectrum.Events.SizeChanged, this._spectrumResized, this);
this._spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
this._stylesPopoverHelper.show(this._spectrum, this._swatch.iconElement(), this._onPopoverHidden.bind(this));
this._originalPropertyText = this._treeElement.property.propertyText;
this._treeElement.parentPane().setEditingStyle(true);
},
/**
* @param {!WebInspector.Event} event
*/
_spectrumResized: function(event)
{
this._stylesPopoverHelper.reposition();
},
/**
* @param {!WebInspector.Event} event
*/
_spectrumChanged: function(event)
{
var colorString = /** @type {string} */ (event.data);
this._swatch.setColorText(colorString);
this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
},
/**
* @param {boolean} commitEdit
*/
_onPopoverHidden: function(commitEdit)
{
this._spectrum.removeEventListener(WebInspector.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
delete this._spectrum;
var propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
this._treeElement.applyStyleText(propertyText, true);
this._treeElement.parentPane().setEditingStyle(false);
delete this._originalPropertyText;
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AdvancedApp.js | 1.27% | (1 / 79) | 0% | (0 / 37) | 0% | (0 / 15) | 1.27% | (1 / 79) | |
| DeviceModeModel.js | 1.02% | (2 / 196) | 0% | (0 / 119) | 0% | (0 / 43) | 1.02% | (2 / 196) | |
| DeviceModeToolbar.js | 4.15% | (11 / 265) | 0% | (0 / 74) | 0% | (0 / 43) | 4.17% | (11 / 264) | |
| DeviceModeView.js | 1.74% | (5 / 287) | 0% | (0 / 100) | 0% | (0 / 27) | 1.75% | (5 / 286) | |
| DeviceModeWrapper.js | 2.5% | (1 / 40) | 0% | (0 / 20) | 0% | (0 / 6) | 2.5% | (1 / 40) | |
| DeviceOrientation.js | 3.45% | (1 / 29) | 0% | (0 / 20) | 0% | (0 / 7) | 3.45% | (1 / 29) | |
| DevicesSettingsTab.js | 4% | (5 / 125) | 0% | (0 / 32) | 0% | (0 / 15) | 4.07% | (5 / 123) | |
| EmulatedDevices.js | 2.33% | (5 / 215) | 0% | (0 / 93) | 0% | (0 / 33) | 2.35% | (5 / 213) | |
| Geolocation.js | 2.94% | (1 / 34) | 0% | (0 / 35) | 0% | (0 / 8) | 2.94% | (1 / 34) | |
| InspectedPagePlaceholder.js | 2.13% | (1 / 47) | 0% | (0 / 17) | 0% | (0 / 8) | 2.13% | (1 / 47) | |
| MediaQueryInspector.js | 1.34% | (3 / 224) | 0% | (0 / 135) | 0% | (0 / 28) | 1.34% | (3 / 224) | |
| SensorsView.js | 1.16% | (2 / 172) | 0% | (0 / 32) | 0% | (0 / 24) | 1.16% | (2 / 172) | |
| TouchModel.js | 3.57% | (2 / 56) | 0% | (0 / 31) | 0% | (0 / 11) | 3.57% | (2 / 56) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.App}
*/
WebInspector.AdvancedApp = function()
{
WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged, this._openToolboxWindow, this);
};
WebInspector.AdvancedApp.prototype = {
/**
* @override
* @param {!Document} document
*/
presentUI: function(document)
{
var rootView = new WebInspector.RootView();
this._rootSplitWidget = new WebInspector.SplitWidget(false, true, "InspectorView.splitViewState", 555, 300, true);
this._rootSplitWidget.show(rootView.element);
this._rootSplitWidget.setSidebarWidget(WebInspector.inspectorView);
this._inspectedPagePlaceholder = new WebInspector.InspectedPagePlaceholder();
this._inspectedPagePlaceholder.addEventListener(WebInspector.InspectedPagePlaceholder.Events.Update, this._onSetInspectedPageBounds.bind(this), this);
this._deviceModeView = new WebInspector.DeviceModeWrapper(this._inspectedPagePlaceholder);
WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged, this._onBeforeDockSideChange, this);
WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._onDockSideChange, this);
WebInspector.dockController.addEventListener(WebInspector.DockController.Events.AfterDockSideChanged, this._onAfterDockSideChange, this);
this._onDockSideChange();
WebInspector.inspectorView.showInitialPanel();
console.timeStamp("AdvancedApp.attachToBody");
rootView.attachToDocument(document);
this._inspectedPagePlaceholder.update();
},
/**
* @param {!WebInspector.Event} event
*/
_openToolboxWindow: function(event)
{
if (/** @type {string} */ (event.data.to) !== WebInspector.DockController.State.Undocked)
return;
if (this._toolboxWindow)
return;
var url = window.location.href.replace("inspector.html", "toolbox.html");
this._toolboxWindow = window.open(url, undefined);
},
/**
* @param {!Document} toolboxDocument
*/
toolboxLoaded: function(toolboxDocument)
{
WebInspector.initializeUIUtils(toolboxDocument, WebInspector.settings.createSetting("uiTheme", "default"));
WebInspector.installComponentRootStyles(/** @type {!Element} */ (toolboxDocument.body));
WebInspector.ContextMenu.installHandler(toolboxDocument);
WebInspector.Tooltip.installHandler(toolboxDocument);
this._toolboxRootView = new WebInspector.RootView();
this._toolboxRootView.attachToDocument(toolboxDocument);
this._updateDeviceModeView();
},
_updateDeviceModeView: function()
{
if (this._isDocked())
this._rootSplitWidget.setMainWidget(this._deviceModeView);
else if (this._toolboxRootView)
this._deviceModeView.show(this._toolboxRootView.element);
},
/**
* @param {!WebInspector.Event} event
*/
_onBeforeDockSideChange: function(event)
{
if (/** @type {string} */ (event.data.to) === WebInspector.DockController.State.Undocked && this._toolboxRootView) {
// Hide inspectorView and force layout to mimic the undocked state.
this._rootSplitWidget.hideSidebar();
this._inspectedPagePlaceholder.update();
}
this._changingDockSide = true;
},
/**
* @param {!WebInspector.Event=} event
*/
_onDockSideChange: function(event)
{
this._updateDeviceModeView();
var toDockSide = event ? /** @type {string} */ (event.data.to) : WebInspector.dockController.dockSide();
if (toDockSide === WebInspector.DockController.State.Undocked) {
this._updateForUndocked();
} else if (this._toolboxRootView && event && /** @type {string} */ (event.data.from) === WebInspector.DockController.State.Undocked) {
// Don't update yet for smooth transition.
this._rootSplitWidget.hideSidebar();
} else {
this._updateForDocked(toDockSide);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onAfterDockSideChange: function(event)
{
// We may get here on the first dock side change while loading without BeforeDockSideChange.
if (!this._changingDockSide)
return;
if (/** @type {string} */ (event.data.from) === WebInspector.DockController.State.Undocked) {
// Restore docked layout in case of smooth transition.
this._updateForDocked(/** @type {string} */ (event.data.to));
}
this._changingDockSide = false;
this._inspectedPagePlaceholder.update();
},
/**
* @param {string} dockSide
*/
_updateForDocked: function(dockSide)
{
this._rootSplitWidget.setVertical(dockSide === WebInspector.DockController.State.DockedToRight);
this._rootSplitWidget.setSecondIsSidebar(dockSide === WebInspector.DockController.State.DockedToRight || dockSide === WebInspector.DockController.State.DockedToBottom);
this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), true);
this._rootSplitWidget.toggleResizer(WebInspector.inspectorView.topResizerElement(), dockSide === WebInspector.DockController.State.DockedToBottom);
this._rootSplitWidget.showBoth();
},
_updateForUndocked: function()
{
this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), false);
this._rootSplitWidget.toggleResizer(WebInspector.inspectorView.topResizerElement(), false);
this._rootSplitWidget.hideMain();
},
_isDocked: function()
{
return WebInspector.dockController.dockSide() !== WebInspector.DockController.State.Undocked;
},
/**
* @param {!WebInspector.Event} event
*/
_onSetInspectedPageBounds: function(event)
{
if (this._changingDockSide)
return;
var window = this._inspectedPagePlaceholder.element.window();
if (!window.innerWidth || !window.innerHeight)
return;
if (!this._inspectedPagePlaceholder.isShowing())
return;
var bounds = /** @type {{x: number, y: number, width: number, height: number}} */ (event.data);
console.timeStamp("AdvancedApp.setInspectedPageBounds");
InspectorFrontendHost.setInspectedPageBounds(bounds);
}
};
/** @type {!WebInspector.AdvancedApp} */
WebInspector.AdvancedApp._appInstance;
/**
* @return {!WebInspector.AdvancedApp}
*/
WebInspector.AdvancedApp._instance = function()
{
if (!WebInspector.AdvancedApp._appInstance)
WebInspector.AdvancedApp._appInstance = new WebInspector.AdvancedApp();
return WebInspector.AdvancedApp._appInstance;
};
/**
* @constructor
* @implements {WebInspector.AppProvider}
*/
WebInspector.AdvancedAppProvider = function()
{
};
WebInspector.AdvancedAppProvider.prototype = {
/**
* @override
* @return {!WebInspector.App}
*/
createApp: function()
{
return WebInspector.AdvancedApp._instance();
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | 2 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {function()} updateCallback
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.DeviceModeModel = function(updateCallback)
{
this._updateCallback = updateCallback;
this._screenRect = new WebInspector.Rect(0, 0, 1, 1);
this._visiblePageRect = new WebInspector.Rect(0, 0, 1, 1);
this._availableSize = new Size(1, 1);
this._preferredSize = new Size(1, 1);
this._initialized = false;
this._deviceMetricsThrottler = new WebInspector.Throttler(0);
this._appliedDeviceSize = new Size(1, 1);
this._appliedDeviceScaleFactor = window.devicePixelRatio;
this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop;
this._scaleSetting = WebInspector.settings.createSetting("emulation.deviceScale", 1);
// We've used to allow zero before.
if (!this._scaleSetting.get())
this._scaleSetting.set(1);
this._scaleSetting.addChangeListener(this._scaleSettingChanged, this);
this._widthSetting = WebInspector.settings.createSetting("emulation.deviceWidth", 400);
if (this._widthSetting.get() < WebInspector.DeviceModeModel.MinDeviceSize)
this._widthSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);
if (this._widthSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize)
this._widthSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);
this._widthSetting.addChangeListener(this._widthSettingChanged, this);
this._heightSetting = WebInspector.settings.createSetting("emulation.deviceHeight", 0);
if (this._heightSetting.get() && this._heightSetting.get() < WebInspector.DeviceModeModel.MinDeviceSize)
this._heightSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);
if (this._heightSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize)
this._heightSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);
this._heightSetting.addChangeListener(this._heightSettingChanged, this);
this._uaSetting = WebInspector.settings.createSetting("emulation.deviceUA", WebInspector.DeviceModeModel.UA.Mobile);
this._uaSetting.addChangeListener(this._uaSettingChanged, this);
this._deviceScaleFactorSetting = WebInspector.settings.createSetting("emulation.deviceScaleFactor", 0);
this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSettingChanged, this);
/** @type {!WebInspector.DeviceModeModel.Type} */
this._type = WebInspector.DeviceModeModel.Type.None;
/** @type {?WebInspector.EmulatedDevice} */
this._device = null;
/** @type {?WebInspector.EmulatedDevice.Mode} */
this._mode = null;
/** @type {number} */
this._fitScale = 1;
/** @type {?WebInspector.Target} */
this._target = null;
/** @type {?function()} */
this._onTargetAvailable = null;
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
/** @enum {string} */
WebInspector.DeviceModeModel.Type = {
None: "None",
Responsive: "Responsive",
Device: "Device"
}
/** @enum {string} */
WebInspector.DeviceModeModel.UA = {
Mobile: WebInspector.UIString("Mobile"),
MobileNoTouch: WebInspector.UIString("Mobile (no touch)"),
Desktop: WebInspector.UIString("Desktop"),
DesktopTouch: WebInspector.UIString("Desktop (touch)")
}
WebInspector.DeviceModeModel.MinDeviceSize = 50;
WebInspector.DeviceModeModel.MaxDeviceSize = 9999;
/**
* @param {string} value
* @return {boolean}
*/
WebInspector.DeviceModeModel.deviceSizeValidator = function(value)
{
if (/^[\d]+$/.test(value) && value >= WebInspector.DeviceModeModel.MinDeviceSize && value <= WebInspector.DeviceModeModel.MaxDeviceSize)
return true;
return false;
}
/**
* @param {string} value
* @return {boolean}
*/
WebInspector.DeviceModeModel.deviceScaleFactorValidator = function(value)
{
if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
return true;
return false;
}
WebInspector.DeviceModeModel._defaultMobileUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36";
WebInspector.DeviceModeModel.defaultMobileScaleFactor = 2;
WebInspector.DeviceModeModel.prototype = {
/**
* @param {!Size} availableSize
* @param {!Size} preferredSize
*/
setAvailableSize: function(availableSize, preferredSize)
{
this._availableSize = availableSize;
this._preferredSize = preferredSize;
this._initialized = true;
this._calculateAndEmulate(false);
},
/**
* @param {!WebInspector.DeviceModeModel.Type} type
* @param {?WebInspector.EmulatedDevice} device
* @param {?WebInspector.EmulatedDevice.Mode} mode
*/
emulate: function(type, device, mode)
{
var resetPageScaleFactor = this._type !== type || this._device !== device || this._mode !== mode;
this._type = type;
if (type === WebInspector.DeviceModeModel.Type.Device) {
console.assert(device && mode, "Must pass device and mode for device emulation");
this._device = device;
this._mode = mode;
if (this._initialized) {
var orientation = device.orientationByName(mode.orientation);
this._scaleSetting.set(this._calculateFitScale(orientation.width, orientation.height));
}
} else {
this._device = null;
this._mode = null;
}
if (type !== WebInspector.DeviceModeModel.Type.None)
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.DeviceModeEnabled);
this._calculateAndEmulate(resetPageScaleFactor);
},
/**
* @param {number} width
*/
setWidth: function(width)
{
var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._preferredScaledWidth());
width = Math.max(Math.min(width, max), 1);
this._widthSetting.set(width);
},
/**
* @param {number} width
*/
setWidthAndScaleToFit: function(width)
{
width = Math.max(Math.min(width, WebInspector.DeviceModeModel.MaxDeviceSize), 1);
this._scaleSetting.set(this._calculateFitScale(width, this._heightSetting.get()));
this._widthSetting.set(width);
},
/**
* @param {number} height
*/
setHeight: function(height)
{
var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._preferredScaledHeight());
height = Math.max(Math.min(height, max), 0);
if (height === this._preferredScaledHeight())
height = 0;
this._heightSetting.set(height);
},
/**
* @param {number} height
*/
setHeightAndScaleToFit: function(height)
{
height = Math.max(Math.min(height, WebInspector.DeviceModeModel.MaxDeviceSize), 0);
this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(), height));
this._heightSetting.set(height);
},
/**
* @param {number} scale
*/
setScale: function(scale)
{
this._scaleSetting.set(scale);
},
/**
* @return {?WebInspector.EmulatedDevice}
*/
device: function()
{
return this._device;
},
/**
* @return {?WebInspector.EmulatedDevice.Mode}
*/
mode: function()
{
return this._mode;
},
/**
* @return {!WebInspector.DeviceModeModel.Type}
*/
type: function()
{
return this._type;
},
/**
* @return {string}
*/
screenImage: function()
{
return (this._device && this._mode) ? this._device.modeImage(this._mode) : "";
},
/**
* @return {!WebInspector.Rect}
*/
screenRect: function()
{
return this._screenRect;
},
/**
* @return {!WebInspector.Rect}
*/
visiblePageRect: function()
{
return this._visiblePageRect;
},
/**
* @return {number}
*/
scale: function()
{
return this._scale;
},
/**
* @return {number}
*/
fitScale: function()
{
return this._fitScale;
},
/**
* @return {!Size}
*/
appliedDeviceSize: function()
{
return this._appliedDeviceSize;
},
/**
* @return {number}
*/
appliedDeviceScaleFactor: function()
{
return this._appliedDeviceScaleFactor;
},
/**
* @return {!WebInspector.DeviceModeModel.UA}
*/
appliedUserAgentType: function()
{
return this._appliedUserAgentType;
},
/**
* @return {boolean}
*/
isFullHeight: function()
{
return !this._heightSetting.get();
},
/**
* @return {!WebInspector.Setting}
*/
scaleSetting: function()
{
return this._scaleSetting;
},
/**
* @return {!WebInspector.Setting}
*/
uaSetting: function()
{
return this._uaSetting;
},
/**
* @return {!WebInspector.Setting}
*/
deviceScaleFactorSetting: function()
{
return this._deviceScaleFactorSetting;
},
reset: function()
{
this._deviceScaleFactorSetting.set(0);
this._scaleSetting.set(1);
this.setWidth(400);
this.setHeight(0);
this._uaSetting.set(WebInspector.DeviceModeModel.UA.Mobile);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (!this._target) {
this._target = target;
if (this._onTargetAvailable) {
var callback = this._onTargetAvailable;
this._onTargetAvailable = null;
callback();
}
}
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (this._target === target)
this._target = null;
},
_scaleSettingChanged: function()
{
this._calculateAndEmulate(false);
},
_widthSettingChanged: function()
{
this._calculateAndEmulate(false);
},
_heightSettingChanged: function()
{
this._calculateAndEmulate(false);
},
_uaSettingChanged: function()
{
this._calculateAndEmulate(true);
},
_deviceScaleFactorSettingChanged: function()
{
this._calculateAndEmulate(false);
},
/**
* @return {number}
*/
_preferredScaledWidth: function()
{
return Math.floor(this._preferredSize.width / (this._scaleSetting.get() || 1));
},
/**
* @return {number}
*/
_preferredScaledHeight: function()
{
return Math.floor(this._preferredSize.height / (this._scaleSetting.get() || 1));
},
/**
* @param {boolean} resetPageScaleFactor
*/
_calculateAndEmulate: function(resetPageScaleFactor)
{
if (!this._target)
this._onTargetAvailable = this._calculateAndEmulate.bind(this, resetPageScaleFactor);
if (this._type === WebInspector.DeviceModeModel.Type.Device) {
var orientation = this._device.orientationByName(this._mode.orientation);
this._fitScale = this._calculateFitScale(orientation.width, orientation.height);
if (this._device.mobile())
this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceModeModel.UA.Mobile : WebInspector.DeviceModeModel.UA.MobileNoTouch;
else
this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceModeModel.UA.DesktopTouch : WebInspector.DeviceModeModel.UA.Desktop;
this._applyDeviceMetrics(new Size(orientation.width, orientation.height), this._mode.insets, this._scaleSetting.get(), this._device.deviceScaleFactor, this._device.mobile(), this._mode.orientation == WebInspector.EmulatedDevice.Horizontal ? "landscapePrimary" : "portraitPrimary", resetPageScaleFactor);
this._applyUserAgent(this._device.userAgent);
this._applyTouch(this._device.touch(), this._device.mobile());
} else if (this._type === WebInspector.DeviceModeModel.Type.None) {
this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height);
this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop;
this._applyDeviceMetrics(this._availableSize, new Insets(0, 0, 0, 0), 1, 0, false, "", resetPageScaleFactor);
this._applyUserAgent("");
this._applyTouch(false, false);
} else if (this._type === WebInspector.DeviceModeModel.Type.Responsive) {
var screenWidth = this._widthSetting.get();
if (!screenWidth || screenWidth > this._preferredScaledWidth())
screenWidth = this._preferredScaledWidth();
var screenHeight = this._heightSetting.get();
if (!screenHeight || screenHeight > this._preferredScaledHeight())
screenHeight = this._preferredScaledHeight();
var mobile = this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile || this._uaSetting.get() === WebInspector.DeviceModeModel.UA.MobileNoTouch;
var defaultDeviceScaleFactor = mobile ? WebInspector.DeviceModeModel.defaultMobileScaleFactor : 0;
this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._heightSetting.get());
this._appliedUserAgentType = this._uaSetting.get();
this._applyDeviceMetrics(new Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= screenWidth ? "portraitPrimary" : "landscapePrimary", resetPageScaleFactor);
this._applyUserAgent(mobile ? WebInspector.DeviceModeModel._defaultMobileUserAgent : "");
this._applyTouch(this._uaSetting.get() === WebInspector.DeviceModeModel.UA.DesktopTouch || this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile, this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile);
}
if (this._target)
this._target.renderingAgent().setShowViewportSizeOnResize(this._type === WebInspector.DeviceModeModel.Type.None);
this._updateCallback.call(null);
},
/**
* @param {number} screenWidth
* @param {number} screenHeight
* @return {number}
*/
_calculateFitScale: function(screenWidth, screenHeight)
{
var scale = Math.min(screenWidth ? this._preferredSize.width / screenWidth: 1, screenHeight ? this._preferredSize.height / screenHeight : 1);
return Math.min(scale, 1);
},
/**
* @param {number} width
* @param {number} height
*/
setSizeAndScaleToFit: function(width, height)
{
this._scaleSetting.set(this._calculateFitScale(width, height));
this.setWidth(width);
},
/**
* @param {string} userAgent
*/
_applyUserAgent: function(userAgent)
{
WebInspector.multitargetNetworkManager.setUserAgentOverride(userAgent);
},
/**
* @param {!Size} screenSize
* @param {!Insets} insets
* @param {number} scale
* @param {number} deviceScaleFactor
* @param {boolean} mobile
* @param {string} screenOrientation
* @param {boolean} resetPageScaleFactor
*/
_applyDeviceMetrics: function(screenSize, insets, scale, deviceScaleFactor, mobile, screenOrientation, resetPageScaleFactor)
{
screenSize.width = Math.max(1, Math.floor(screenSize.width));
screenSize.height = Math.max(1, Math.floor(screenSize.height));
var pageWidth = screenSize.width - insets.left - insets.right;
var pageHeight = screenSize.height - insets.top - insets.bottom;
var positionX = insets.left;
var positionY = insets.top;
var screenOrientationAngle = screenOrientation === "landscapePrimary" ? 90 : 0;
this._appliedDeviceSize = screenSize;
this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
this._screenRect = new WebInspector.Rect(
Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2),
0,
screenSize.width * scale,
screenSize.height * scale);
this._visiblePageRect = new WebInspector.Rect(
positionX * scale,
positionY * scale,
Math.min(pageWidth * scale, this._availableSize.width - this._screenRect.left - positionX * scale),
Math.min(pageHeight * scale, this._availableSize.height - this._screenRect.top - positionY * scale));
this._scale = scale;
if (scale === 1 && this._availableSize.width >= screenSize.width && this._availableSize.height >= screenSize.height) {
// When we have enough space, no page size override is required. This will speed things up and remove lag.
pageWidth = 0;
pageHeight = 0;
}
if (this._visiblePageRect.width === pageWidth * scale && this._visiblePageRect.height === pageHeight * scale) {
// When we only have to apply scale, do not resize the page. This will speed things up and remove lag.
pageWidth = 0;
pageHeight = 0;
}
this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this));
/**
* @this {WebInspector.DeviceModeModel}
* @return {!Promise.<?>}
*/
function setDeviceMetricsOverride()
{
if (!this._target)
return Promise.resolve();
var clear = !pageWidth && !pageHeight && !mobile && !deviceScaleFactor && scale === 1 && !screenOrientation;
var allPromises = [];
if (resetPageScaleFactor)
allPromises.push(this._target.emulationAgent().resetPageScaleFactor());
var setDevicePromise;
if (clear) {
setDevicePromise = this._target.emulationAgent().clearDeviceMetricsOverride(this._deviceMetricsOverrideAppliedForTest.bind(this));
} else {
var params = {width: pageWidth, height: pageHeight, deviceScaleFactor: deviceScaleFactor, mobile: mobile, fitWindow: false, scale: scale, screenWidth: screenSize.width, screenHeight: screenSize.height, positionX: positionX, positionY: positionY};
if (screenOrientation)
params.screenOrientation = {type: screenOrientation, angle: screenOrientationAngle};
setDevicePromise = this._target.emulationAgent().invoke_setDeviceMetricsOverride(params, this._deviceMetricsOverrideAppliedForTest.bind(this));
}
allPromises.push(setDevicePromise);
return Promise.all(allPromises);
}
},
_deviceMetricsOverrideAppliedForTest: function()
{
// Used for sniffing in tests.
},
/**
* @param {boolean} touchEnabled
* @param {boolean} mobile
*/
_applyTouch: function(touchEnabled, mobile)
{
WebInspector.MultitargetTouchModel.instance().setTouchEnabled(touchEnabled, mobile);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | 2 1 1 1 1 1 1 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @param {!WebInspector.DeviceModeModel} model
* @param {!WebInspector.Setting} showMediaInspectorSetting
* @param {!WebInspector.Setting} showRulersSetting
* @constructor
*/
WebInspector.DeviceModeToolbar = function(model, showMediaInspectorSetting, showRulersSetting)
{
this._model = model;
this._showMediaInspectorSetting = showMediaInspectorSetting;
this._showRulersSetting = showRulersSetting;
this._showDeviceScaleFactorSetting = WebInspector.settings.createSetting("emulation.showDeviceScaleFactor", false);
this._showDeviceScaleFactorSetting.addChangeListener(this._updateDeviceScaleFactorVisibility, this);
this._showUserAgentTypeSetting = WebInspector.settings.createSetting("emulation.showUserAgentType", false);
this._showUserAgentTypeSetting.addChangeListener(this._updateUserAgentTypeVisibility, this);
this._showNetworkConditionsSetting = WebInspector.settings.createSetting("emulation.showNetworkConditions", false);
this._showNetworkConditionsSetting.addChangeListener(this._updateNetworkConditionsVisibility, this);
/** @type {!Map<!WebInspector.EmulatedDevice, !WebInspector.EmulatedDevice.Mode>} */
this._lastMode = new Map();
this._element = createElementWithClass("div", "device-mode-toolbar");
var leftContainer = this._element.createChild("div", "device-mode-toolbar-spacer");
leftContainer.createChild("div", "device-mode-toolbar-spacer");
var leftToolbar = new WebInspector.Toolbar("", leftContainer);
leftToolbar.makeWrappable();
this._fillLeftToolbar(leftToolbar);
var mainToolbar = new WebInspector.Toolbar("", this._element);
mainToolbar.makeWrappable();
this._fillMainToolbar(mainToolbar);
var rightContainer = this._element.createChild("div", "device-mode-toolbar-spacer");
var rightToolbar = new WebInspector.Toolbar("device-mode-toolbar-fixed-size", rightContainer);
rightToolbar.makeWrappable();
this._fillRightToolbar(rightToolbar);
var modeToolbar = new WebInspector.Toolbar("device-mode-toolbar-fixed-size", rightContainer);
modeToolbar.makeWrappable();
this._fillModeToolbar(modeToolbar);
rightContainer.createChild("div", "device-mode-toolbar-spacer");
var optionsToolbar = new WebInspector.Toolbar("", rightContainer);
optionsToolbar.makeWrappable(true);
this._fillOptionsToolbar(optionsToolbar);
this._emulatedDevicesList = WebInspector.EmulatedDevicesList.instance();
this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated, this._deviceListChanged, this);
this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated, this._deviceListChanged, this);
this._persistenceSetting = WebInspector.settings.createSetting("emulation.deviceModeValue", {device: "", orientation: "", mode: ""});
}
WebInspector.DeviceModeToolbar.prototype = {
/**
* @param {!WebInspector.Toolbar} toolbar
*/
_fillLeftToolbar: function(toolbar)
{
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
this._deviceSelectItem = new WebInspector.ToolbarMenuButton(this._appendDeviceMenuItems.bind(this));
this._deviceSelectItem.setGlyph("");
this._deviceSelectItem.turnIntoSelect(95);
toolbar.appendToolbarItem(this._deviceSelectItem);
},
/**
* @param {!WebInspector.Toolbar} toolbar
*/
_fillMainToolbar: function(toolbar)
{
var widthInput = createElementWithClass("input", "device-mode-size-input");
widthInput.maxLength = 4;
widthInput.type = "text";
widthInput.title = WebInspector.UIString("Width");
this._updateWidthInput = WebInspector.bindInput(widthInput, applyWidth.bind(this), WebInspector.DeviceModeModel.deviceSizeValidator, true);
this._widthInput = widthInput;
this._widthItem = this._wrapToolbarItem(widthInput);
toolbar.appendToolbarItem(this._widthItem);
var xElement = createElementWithClass("div", "device-mode-x");
xElement.textContent = "\u00D7";
this._xItem = this._wrapToolbarItem(xElement);
toolbar.appendToolbarItem(this._xItem);
var heightInput = createElementWithClass("input", "device-mode-size-input");
heightInput.maxLength = 4;
heightInput.type = "text";
heightInput.title = WebInspector.UIString("Height (leave empty for full)");
this._updateHeightInput = WebInspector.bindInput(heightInput, applyHeight.bind(this), validateHeight, true);
this._heightInput = heightInput;
this._heightItem = this._wrapToolbarItem(heightInput);
toolbar.appendToolbarItem(this._heightItem);
/**
* @param {string} value
* @return {boolean}
*/
function validateHeight(value)
{
return !value || WebInspector.DeviceModeModel.deviceSizeValidator(value);
}
/**
* @param {string} value
* @this {WebInspector.DeviceModeToolbar}
*/
function applyWidth(value)
{
var width = value ? Number(value) : 0;
this._model.setWidthAndScaleToFit(width);
}
/**
* @param {string} value
* @this {WebInspector.DeviceModeToolbar}
*/
function applyHeight(value)
{
var height = value ? Number(value) : 0;
this._model.setHeightAndScaleToFit(height);
}
},
/**
* @param {!WebInspector.Toolbar} toolbar
*/
_fillRightToolbar: function(toolbar)
{
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
this._scaleItem = new WebInspector.ToolbarMenuButton(this._appendScaleMenuItems.bind(this));
this._scaleItem.setTitle(WebInspector.UIString("Zoom"));
this._scaleItem.setGlyph("");
this._scaleItem.turnIntoSelect();
toolbar.appendToolbarItem(this._scaleItem);
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
this._deviceScaleItem = new WebInspector.ToolbarMenuButton(this._appendDeviceScaleMenuItems.bind(this));
this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());
this._deviceScaleItem.setTitle(WebInspector.UIString("Device pixel ratio"));
this._deviceScaleItem.setGlyph("");
this._deviceScaleItem.turnIntoSelect();
this._deviceScaleItem.element.style.padding = "0 5px";
toolbar.appendToolbarItem(this._deviceScaleItem);
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
this._uaItem = new WebInspector.ToolbarMenuButton(this._appendUserAgentMenuItems.bind(this));
this._uaItem.setVisible(this._showUserAgentTypeSetting.get());
this._uaItem.setTitle(WebInspector.UIString("Device type"));
this._uaItem.setGlyph("");
this._uaItem.turnIntoSelect();
this._uaItem.element.style.padding = "0 5px";
toolbar.appendToolbarItem(this._uaItem);
},
/**
* @param {!WebInspector.Toolbar} toolbar
*/
_fillModeToolbar: function(toolbar)
{
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
this._modeButton = new WebInspector.ToolbarButton("", "rotate-screen-toolbar-item");
this._modeButton.addEventListener("click", this._modeMenuClicked, this);
toolbar.appendToolbarItem(this._modeButton);
},
/**
* @param {!WebInspector.Toolbar} toolbar
*/
_fillOptionsToolbar: function(toolbar)
{
this._networkConditionsItem = WebInspector.NetworkConditionsSelector.createToolbarMenuButton();
this._networkConditionsItem.setVisible(this._showNetworkConditionsSetting.get());
this._networkConditionsItem.setTitle(WebInspector.UIString("Network throttling"));
this._networkConditionsItem.element.style.padding = "0 5px";
this._networkConditionsItem.element.style.maxWidth = "140px";
toolbar.appendToolbarItem(this._networkConditionsItem);
var moreOptionsButton = new WebInspector.ToolbarMenuButton(this._appendOptionsMenuItems.bind(this));
moreOptionsButton.setTitle(WebInspector.UIString("More options"));
toolbar.appendToolbarItem(moreOptionsButton);
toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div", "device-mode-empty-toolbar-element")));
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendScaleMenuItems: function(contextMenu)
{
var scaleSetting = this._model.scaleSetting();
if (this._model.type() === WebInspector.DeviceModeModel.Type.Device) {
contextMenu.appendItem(WebInspector.UIString("Fit to window (%.0f%%)", this._model.fitScale() * 100), scaleSetting.set.bind(scaleSetting, this._model.fitScale()), false);
contextMenu.appendSeparator();
}
appendScaleItem(WebInspector.UIString("50%"), 0.5);
appendScaleItem(WebInspector.UIString("75%"), 0.75);
appendScaleItem(WebInspector.UIString("100%"), 1);
appendScaleItem(WebInspector.UIString("125%"), 1.25);
appendScaleItem(WebInspector.UIString("150%"), 1.5);
/**
* @param {string} title
* @param {number} value
*/
function appendScaleItem(title, value)
{
contextMenu.appendCheckboxItem(title, scaleSetting.set.bind(scaleSetting, value), scaleSetting.get() === value, false);
}
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendDeviceScaleMenuItems: function(contextMenu)
{
var deviceScaleFactorSetting = this._model.deviceScaleFactorSetting();
var defaultValue = this._model.uaSetting().get() === WebInspector.DeviceModeModel.UA.Mobile || this._model.uaSetting().get() === WebInspector.DeviceModeModel.UA.MobileNoTouch ? WebInspector.DeviceModeModel.defaultMobileScaleFactor : window.devicePixelRatio;
appendDeviceScaleFactorItem(WebInspector.UIString("Default: %.1f", defaultValue), 0);
contextMenu.appendSeparator();
appendDeviceScaleFactorItem(WebInspector.UIString("1"), 1);
appendDeviceScaleFactorItem(WebInspector.UIString("2"), 2);
appendDeviceScaleFactorItem(WebInspector.UIString("3"), 3);
/**
* @param {string} title
* @param {number} value
*/
function appendDeviceScaleFactorItem(title, value)
{
contextMenu.appendCheckboxItem(title, deviceScaleFactorSetting.set.bind(deviceScaleFactorSetting, value), deviceScaleFactorSetting.get() === value);
}
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendUserAgentMenuItems: function(contextMenu)
{
var uaSetting = this._model.uaSetting();
appendUAItem(WebInspector.DeviceModeModel.UA.Mobile, WebInspector.DeviceModeModel.UA.Mobile);
appendUAItem(WebInspector.DeviceModeModel.UA.MobileNoTouch, WebInspector.DeviceModeModel.UA.MobileNoTouch);
appendUAItem(WebInspector.DeviceModeModel.UA.Desktop, WebInspector.DeviceModeModel.UA.Desktop);
appendUAItem(WebInspector.DeviceModeModel.UA.DesktopTouch, WebInspector.DeviceModeModel.UA.DesktopTouch);
/**
* @param {string} title
* @param {!WebInspector.DeviceModeModel.UA} value
*/
function appendUAItem(title, value)
{
contextMenu.appendCheckboxItem(title, uaSetting.set.bind(uaSetting, value), uaSetting.get() === value);
}
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendOptionsMenuItems: function(contextMenu)
{
contextMenu.appendCheckboxItem(WebInspector.UIString("Show device pixel ratio"), this._toggleDeviceScaleFactor.bind(this), this._showDeviceScaleFactorSetting.get(), this._model.type() === WebInspector.DeviceModeModel.Type.None);
contextMenu.appendCheckboxItem(WebInspector.UIString("Show device type"), this._toggleUserAgentType.bind(this), this._showUserAgentTypeSetting.get(), this._model.type() === WebInspector.DeviceModeModel.Type.None);
contextMenu.appendCheckboxItem(WebInspector.UIString("Show throttling"), this._toggleNetworkConditions.bind(this), this._showNetworkConditionsSetting.get(), this._model.type() === WebInspector.DeviceModeModel.Type.None);
contextMenu.appendCheckboxItem(WebInspector.UIString("Show media queries"), this._toggleMediaInspector.bind(this), this._showMediaInspectorSetting.get(), this._model.type() === WebInspector.DeviceModeModel.Type.None);
contextMenu.appendCheckboxItem(WebInspector.UIString("Show rulers"), this._toggleRulers.bind(this), this._showRulersSetting.get(), this._model.type() === WebInspector.DeviceModeModel.Type.None);
contextMenu.appendSeparator();
contextMenu.appendItemsAtLocation("deviceModeMenu");
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Reset to defaults"), this._reset.bind(this));
},
_toggleDeviceScaleFactor: function()
{
this._showDeviceScaleFactorSetting.set(!this._showDeviceScaleFactorSetting.get());
},
_toggleUserAgentType: function()
{
this._showUserAgentTypeSetting.set(!this._showUserAgentTypeSetting.get());
},
_toggleMediaInspector: function()
{
this._showMediaInspectorSetting.set(!this._showMediaInspectorSetting.get());
},
_toggleRulers: function()
{
this._showRulersSetting.set(!this._showRulersSetting.get());
},
_toggleNetworkConditions: function()
{
this._showNetworkConditionsSetting.set(!this._showNetworkConditionsSetting.get());
},
_reset: function()
{
this._showDeviceScaleFactorSetting.set(false);
this._showUserAgentTypeSetting.set(false);
this._showMediaInspectorSetting.set(false);
this._showRulersSetting.set(false);
this._showNetworkConditionsSetting.set(false);
this._model.reset();
},
/**
* @param {!Element} element
* @return {!WebInspector.ToolbarItem}
*/
_wrapToolbarItem: function(element)
{
var container = createElement("div");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(container, "emulation/deviceModeToolbar.css");
shadowRoot.appendChild(element);
return new WebInspector.ToolbarItem(container);
},
/**
* @param {!WebInspector.EmulatedDevice} device
*/
_emulateDevice: function(device)
{
this._model.emulate(WebInspector.DeviceModeModel.Type.Device, device, this._lastMode.get(device) || device.modes[0]);
},
_switchToResponsive: function()
{
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, null, null);
},
/**
* @param {!Array<!WebInspector.EmulatedDevice>} devices
* @return {!Array<!WebInspector.EmulatedDevice>}
*/
_filterDevices: function(devices)
{
devices = devices.filter(function(d) { return d.show(); });
devices.sort(WebInspector.EmulatedDevice.deviceComparator);
return devices;
},
/**
* @return {!Array<!WebInspector.EmulatedDevice>}
*/
_standardDevices: function()
{
return this._filterDevices(this._emulatedDevicesList.standard());
},
/**
* @return {!Array<!WebInspector.EmulatedDevice>}
*/
_customDevices: function()
{
return this._filterDevices(this._emulatedDevicesList.custom());
},
/**
* @return {!Array<!WebInspector.EmulatedDevice>}
*/
_allDevices: function()
{
return this._standardDevices().concat(this._customDevices());
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendDeviceMenuItems: function(contextMenu)
{
contextMenu.appendCheckboxItem(WebInspector.UIString("Responsive"), this._switchToResponsive.bind(this), this._model.type() === WebInspector.DeviceModeModel.Type.Responsive, false);
appendGroup.call(this, this._standardDevices());
appendGroup.call(this, this._customDevices());
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Edit\u2026"), this._emulatedDevicesList.revealCustomSetting.bind(this._emulatedDevicesList), false);
/**
* @param {!Array<!WebInspector.EmulatedDevice>} devices
* @this {WebInspector.DeviceModeToolbar}
*/
function appendGroup(devices)
{
if (!devices.length)
return;
contextMenu.appendSeparator();
for (var device of devices)
contextMenu.appendCheckboxItem(device.title, this._emulateDevice.bind(this, device), this._model.device() === device, false);
}
},
/**
* @this {WebInspector.DeviceModeToolbar}
*/
_deviceListChanged: function()
{
var device = this._model.device();
if (!device)
return;
var devices = this._allDevices();
if (devices.indexOf(device) === -1) {
if (devices.length)
this._emulateDevice(devices[0]);
else
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, null, null);
}
},
_updateDeviceScaleFactorVisibility: function()
{
this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());
},
_updateUserAgentTypeVisibility: function()
{
this._uaItem.setVisible(this._showUserAgentTypeSetting.get());
},
_updateNetworkConditionsVisibility: function()
{
this._networkConditionsItem.setVisible(this._showNetworkConditionsSetting.get());
},
/**
* @param {!WebInspector.Event} event
*/
_modeMenuClicked: function(event)
{
var device = this._model.device();
var model = this._model;
if (device.modes.length === 2 && device.modes[0].orientation !== device.modes[1].orientation) {
model.emulate(model.type(), model.device(), model.mode() === device.modes[0] ? device.modes[1] : device.modes[0]);
return;
}
var contextMenu = new WebInspector.ContextMenu(/** @type {!Event} */ (event.data),
false,
event.target.element.totalOffsetLeft(),
event.target.element.totalOffsetTop() + event.target.element.offsetHeight);
addOrientation(WebInspector.EmulatedDevice.Vertical, WebInspector.UIString("Portrait"));
addOrientation(WebInspector.EmulatedDevice.Horizontal, WebInspector.UIString("Landscape"));
contextMenu.show();
/**
* @param {string} orientation
* @param {string} title
*/
function addOrientation(orientation, title)
{
var modes = device.modesForOrientation(orientation);
if (!modes.length)
return;
if (modes.length === 1) {
addMode(modes[0], title);
} else {
for (var index = 0; index < modes.length; index++)
addMode(modes[index], title + " \u2013 " + modes[index].title);
}
}
/**
* @param {!WebInspector.EmulatedDevice.Mode} mode
* @param {string} title
*/
function addMode(mode, title)
{
contextMenu.appendCheckboxItem(title, applyMode.bind(null, mode), model.mode() === mode, false);
}
/**
* @param {!WebInspector.EmulatedDevice.Mode} mode
*/
function applyMode(mode)
{
model.emulate(model.type(), model.device(), mode);
}
},
/**
* @return {!Element}
*/
element: function()
{
return this._element;
},
update: function()
{
if (this._model.type() !== this._cachedModelType) {
this._cachedModelType = this._model.type();
this._widthInput.disabled = this._model.type() !== WebInspector.DeviceModeModel.Type.Responsive;
this._heightInput.disabled = this._model.type() !== WebInspector.DeviceModeModel.Type.Responsive;
this._deviceScaleItem.setEnabled(this._model.type() === WebInspector.DeviceModeModel.Type.Responsive);
this._uaItem.setEnabled(this._model.type() === WebInspector.DeviceModeModel.Type.Responsive);
}
var size = this._model.appliedDeviceSize();
this._updateHeightInput(this._model.type() === WebInspector.DeviceModeModel.Type.Responsive && this._model.isFullHeight() ? "" : String(size.height));
this._updateWidthInput(String(size.width));
this._heightInput.placeholder = size.height;
if (this._model.scale() !== this._cachedScale) {
this._scaleItem.setText(WebInspector.UIString("%.0f%%", this._model.scale() * 100));
this._cachedScale = this._model.scale();
}
var deviceScale = this._model.appliedDeviceScaleFactor();
if (deviceScale !== this._cachedDeviceScale) {
this._deviceScaleItem.setText(WebInspector.UIString("DPR: %.1f", deviceScale));
this._cachedDeviceScale = deviceScale;
}
var uaType = this._model.appliedUserAgentType();
if (uaType !== this._cachedUaType) {
this._uaItem.setText(uaType);
this._cachedUaType = uaType;
}
var deviceItemTitle = WebInspector.UIString("None");
if (this._model.type() === WebInspector.DeviceModeModel.Type.Responsive)
deviceItemTitle = WebInspector.UIString("Responsive");
if (this._model.type() === WebInspector.DeviceModeModel.Type.Device)
deviceItemTitle = this._model.device().title;
this._deviceSelectItem.setText(deviceItemTitle);
if (this._model.device() !== this._cachedModelDevice) {
var device = this._model.device();
this._modeButton.setVisible(!!device);
if (device) {
var modeCount = device ? device.modes.length : 0;
this._modeButton.setEnabled(modeCount >= 2);
this._modeButton.setTitle(modeCount === 2 ? WebInspector.UIString("Rotate") : WebInspector.UIString("Screen options"));
}
this._cachedModelDevice = device;
}
if (this._model.type() === WebInspector.DeviceModeModel.Type.Device)
this._lastMode.set(/** @type {!WebInspector.EmulatedDevice} */ (this._model.device()), /** @type {!WebInspector.EmulatedDevice.Mode} */ (this._model.mode()));
if (this._model.mode() !== this._cachedModelMode && this._model.type() !== WebInspector.DeviceModeModel.Type.None) {
this._cachedModelMode = this._model.mode();
var value = this._persistenceSetting.get();
if (this._model.device()) {
value.device = this._model.device().title;
value.orientation = this._model.mode() ? this._model.mode().orientation : "";
value.mode = this._model.mode() ? this._model.mode().title : "";
} else {
value.device = "";
value.orientation = "";
value.mode = "";
}
this._persistenceSetting.set(value);
}
},
restore: function()
{
for (var device of this._allDevices()) {
if (device.title === this._persistenceSetting.get().device) {
for (var mode of device.modes) {
if (mode.orientation === this._persistenceSetting.get().orientation && mode.title === this._persistenceSetting.get().mode) {
this._lastMode.set(device, mode);
this._emulateDevice(device);
return;
}
}
}
}
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, null, null);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | 2 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DeviceModeView = function()
{
WebInspector.VBox.call(this, true);
this.setMinimumSize(150, 150);
this.element.classList.add("device-mode-view");
this.registerRequiredCSS("emulation/deviceModeView.css");
WebInspector.Tooltip.addNativeOverrideContainer(this.contentElement);
this._model = new WebInspector.DeviceModeModel(this._updateUI.bind(this));
this._mediaInspector = new WebInspector.MediaQueryInspector(() => this._model.appliedDeviceSize().width, this._model.setWidth.bind(this._model));
this._showMediaInspectorSetting = WebInspector.settings.moduleSetting("showMediaQueryInspector");
this._showMediaInspectorSetting.addChangeListener(this._updateUI, this);
this._showRulersSetting = WebInspector.settings.moduleSetting("emulation.showRulers");
this._showRulersSetting.addChangeListener(this._updateUI, this);
this._topRuler = new WebInspector.DeviceModeView.Ruler(true, this._model.setWidthAndScaleToFit.bind(this._model));
this._topRuler.element.classList.add("device-mode-ruler-top");
this._leftRuler = new WebInspector.DeviceModeView.Ruler(false, this._model.setHeightAndScaleToFit.bind(this._model));
this._leftRuler.element.classList.add("device-mode-ruler-left");
this._createUI();
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
};
WebInspector.DeviceModeView.prototype = {
_createUI: function()
{
this._toolbar = new WebInspector.DeviceModeToolbar(this._model, this._showMediaInspectorSetting, this._showRulersSetting);
this.contentElement.appendChild(this._toolbar.element());
this._contentClip = this.contentElement.createChild("div", "device-mode-content-clip vbox");
this._responsivePresetsContainer = this._contentClip.createChild("div", "device-mode-presets-container");
this._populatePresetsContainer();
this._mediaInspectorContainer = this._contentClip.createChild("div", "device-mode-media-container");
this._contentArea = this._contentClip.createChild("div", "device-mode-content-area");
this._screenArea = this._contentArea.createChild("div", "device-mode-screen-area");
this._screenImage = this._screenArea.createChild("img", "device-mode-screen-image hidden");
this._screenImage.addEventListener("load", this._onScreenImageLoaded.bind(this, true), false);
this._screenImage.addEventListener("error", this._onScreenImageLoaded.bind(this, false), false);
this._bottomRightResizerElement = this._screenArea.createChild("div", "device-mode-resizer device-mode-bottom-right-resizer");
this._bottomRightResizerElement.createChild("div", "");
this._createResizer(this._bottomRightResizerElement, 2, 1);
this._bottomLeftResizerElement = this._screenArea.createChild("div", "device-mode-resizer device-mode-bottom-left-resizer");
this._bottomLeftResizerElement.createChild("div", "");
this._createResizer(this._bottomLeftResizerElement, -2, 1);
this._rightResizerElement = this._screenArea.createChild("div", "device-mode-resizer device-mode-right-resizer");
this._rightResizerElement.createChild("div", "");
this._createResizer(this._rightResizerElement, 2, 0);
this._leftResizerElement = this._screenArea.createChild("div", "device-mode-resizer device-mode-left-resizer");
this._leftResizerElement.createChild("div", "");
this._createResizer(this._leftResizerElement, -2, 0);
this._bottomResizerElement = this._screenArea.createChild("div", "device-mode-resizer device-mode-bottom-resizer");
this._bottomResizerElement.createChild("div", "");
this._createResizer(this._bottomResizerElement, 0, 1);
this._bottomResizerElement.addEventListener("dblclick", this._model.setHeight.bind(this._model, 0), false);
this._bottomResizerElement.title = WebInspector.UIString("Double-click for full height");
this._pageArea = this._screenArea.createChild("div", "device-mode-page-area");
this._pageArea.createChild("content");
},
_populatePresetsContainer: function()
{
var sizes = [320, 375, 425, 768, 1024, 1440, 2560];
var titles = [WebInspector.UIString("Mobile S"),
WebInspector.UIString("Mobile M"),
WebInspector.UIString("Mobile L"),
WebInspector.UIString("Tablet"),
WebInspector.UIString("Laptop"),
WebInspector.UIString("Laptop L"),
WebInspector.UIString("4K")]
this._presetBlocks = [];
var inner = this._responsivePresetsContainer.createChild("div", "device-mode-presets-container-inner")
for (var i = sizes.length - 1; i >= 0; --i) {
var outer = inner.createChild("div", "fill device-mode-preset-bar-outer");
var block = outer.createChild("div", "device-mode-preset-bar");
block.createChild("span").textContent = titles[i] + " \u2013 " + sizes[i] + "px";
block.addEventListener("click", applySize.bind(this, sizes[i]), false);
block.__width = sizes[i];
this._presetBlocks.push(block);
}
/**
* @param {number} width
* @param {!Event} e
* @this {WebInspector.DeviceModeView}
*/
function applySize(width, e)
{
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, null, null);
this._model.setSizeAndScaleToFit(width, 0);
e.consume();
}
},
toggleDeviceMode: function()
{
this._toolbar.toggleDeviceMode();
},
/**
* @param {!Element} element
* @param {number} widthFactor
* @param {number} heightFactor
* @return {!WebInspector.ResizerWidget}
*/
_createResizer: function(element, widthFactor, heightFactor)
{
var resizer = new WebInspector.ResizerWidget();
resizer.addElement(element);
var cursor = widthFactor ? "ew-resize" : "ns-resize";
if (widthFactor * heightFactor > 0)
cursor = "nwse-resize";
if (widthFactor * heightFactor < 0)
cursor = "nesw-resize";
resizer.setCursor(cursor);
resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate.bind(this, widthFactor, heightFactor));
resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
return resizer;
},
/**
* @param {!WebInspector.Event} event
*/
_onResizeStart: function(event)
{
this._slowPositionStart = null;
/** @type {!Size} */
this._resizeStart = this._model.screenRect().size();
},
/**
* @param {number} widthFactor
* @param {number} heightFactor
* @param {!WebInspector.Event} event
*/
_onResizeUpdate: function(widthFactor, heightFactor, event)
{
if (event.data.shiftKey !== !!this._slowPositionStart)
this._slowPositionStart = event.data.shiftKey ? {x: event.data.currentX, y: event.data.currentY} : null;
var cssOffsetX = event.data.currentX - event.data.startX;
var cssOffsetY = event.data.currentY - event.data.startY;
if (this._slowPositionStart) {
cssOffsetX = (event.data.currentX - this._slowPositionStart.x) / 10 + this._slowPositionStart.x - event.data.startX;
cssOffsetY = (event.data.currentY - this._slowPositionStart.y) / 10 + this._slowPositionStart.y - event.data.startY;
}
if (widthFactor) {
var dipOffsetX = cssOffsetX * WebInspector.zoomManager.zoomFactor();
var newWidth = this._resizeStart.width + dipOffsetX * widthFactor;
newWidth = Math.round(newWidth / this._model.scale());
if (newWidth >= WebInspector.DeviceModeModel.MinDeviceSize && newWidth <= WebInspector.DeviceModeModel.MaxDeviceSize)
this._model.setWidth(newWidth);
}
if (heightFactor) {
var dipOffsetY = cssOffsetY * WebInspector.zoomManager.zoomFactor();
var newHeight = this._resizeStart.height + dipOffsetY * heightFactor;
newHeight = Math.round(newHeight / this._model.scale());
if (newHeight >= WebInspector.DeviceModeModel.MinDeviceSize && newHeight <= WebInspector.DeviceModeModel.MaxDeviceSize)
this._model.setHeight(newHeight);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onResizeEnd: function(event)
{
delete this._resizeStart;
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ResizedViewInResponsiveMode);
},
_updateUI: function()
{
if (!this.isShowing())
return;
var zoomFactor = WebInspector.zoomManager.zoomFactor();
var callDoResize = false;
var showRulers = this._showRulersSetting.get() && this._model.type() !== WebInspector.DeviceModeModel.Type.None;
var contentAreaResized = false;
var updateRulers = false;
var cssScreenRect = this._model.screenRect().scale(1 / zoomFactor);
if (!cssScreenRect.isEqual(this._cachedCssScreenRect)) {
this._screenArea.style.left = cssScreenRect.left + "px";
this._screenArea.style.top = cssScreenRect.top + "px";
this._screenArea.style.width = cssScreenRect.width + "px";
this._screenArea.style.height = cssScreenRect.height + "px";
this._leftRuler.element.style.left = cssScreenRect.left + "px";
updateRulers = true;
callDoResize = true;
this._cachedCssScreenRect = cssScreenRect;
}
var cssVisiblePageRect = this._model.visiblePageRect().scale(1 / zoomFactor);
if (!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)) {
this._pageArea.style.left = cssVisiblePageRect.left + "px";
this._pageArea.style.top = cssVisiblePageRect.top + "px";
this._pageArea.style.width = cssVisiblePageRect.width + "px";
this._pageArea.style.height = cssVisiblePageRect.height + "px";
callDoResize = true;
this._cachedCssVisiblePageRect = cssVisiblePageRect;
}
var resizable = this._model.type() === WebInspector.DeviceModeModel.Type.Responsive;
if (resizable !== this._cachedResizable) {
this._rightResizerElement.classList.toggle("hidden", !resizable);
this._leftResizerElement.classList.toggle("hidden", !resizable);
this._bottomResizerElement.classList.toggle("hidden", !resizable);
this._bottomRightResizerElement.classList.toggle("hidden", !resizable);
this._bottomLeftResizerElement.classList.toggle("hidden", !resizable);
this._cachedResizable = resizable;
}
var mediaInspectorVisible = this._showMediaInspectorSetting.get() && this._model.type() !== WebInspector.DeviceModeModel.Type.None;
if (mediaInspectorVisible !== this._cachedMediaInspectorVisible) {
if (mediaInspectorVisible)
this._mediaInspector.show(this._mediaInspectorContainer);
else
this._mediaInspector.detach();
contentAreaResized = true;
callDoResize = true;
this._cachedMediaInspectorVisible = mediaInspectorVisible;
}
if (showRulers !== this._cachedShowRulers) {
this._contentClip.classList.toggle("device-mode-rulers-visible", showRulers);
if (showRulers) {
this._topRuler.show(this._contentClip, this._contentArea);
this._leftRuler.show(this._contentArea);
} else {
this._topRuler.detach();
this._leftRuler.detach();
}
contentAreaResized = true;
callDoResize = true;
this._cachedShowRulers = showRulers;
}
if (this._model.scale() !== this._cachedScale) {
updateRulers = true;
callDoResize = true;
for (var block of this._presetBlocks)
block.style.width = block.__width * this._model.scale() + "px";
this._cachedScale = this._model.scale();
}
this._toolbar.update();
this._loadScreenImage(this._model.screenImage());
this._mediaInspector.setAxisTransform(this._model.scale());
if (callDoResize)
this.doResize();
if (updateRulers) {
this._topRuler.render(this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0, this._model.scale());
this._leftRuler.render(0, this._model.scale());
}
if (contentAreaResized)
this._contentAreaResized();
},
/**
* @param {string} srcset
*/
_loadScreenImage: function(srcset)
{
if (this._screenImage.getAttribute("srcset") === srcset)
return;
this._screenImage.setAttribute("srcset", srcset);
if (!srcset)
this._screenImage.classList.toggle("hidden", true);
},
/**
* @param {boolean} success
*/
_onScreenImageLoaded: function(success)
{
this._screenImage.classList.toggle("hidden", !success);
},
_contentAreaResized: function()
{
var zoomFactor = WebInspector.zoomManager.zoomFactor();
var rect = this._contentArea.getBoundingClientRect();
var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
var preferredSize = new Size(Math.max((rect.width - 2 * this._handleWidth) * zoomFactor, 1), Math.max((rect.height - this._handleHeight) * zoomFactor, 1));
this._model.setAvailableSize(availableSize, preferredSize);
},
_measureHandles: function()
{
var hidden = this._rightResizerElement.classList.contains("hidden");
this._rightResizerElement.classList.toggle("hidden", false);
this._bottomResizerElement.classList.toggle("hidden", false);
this._handleWidth = this._rightResizerElement.offsetWidth;
this._handleHeight = this._bottomResizerElement.offsetHeight;
this._rightResizerElement.classList.toggle("hidden", hidden);
this._bottomResizerElement.classList.toggle("hidden", hidden);
},
_zoomChanged: function()
{
delete this._handleWidth;
delete this._handleHeight;
if (this.isShowing()) {
this._measureHandles();
this._contentAreaResized();
}
},
/**
* @override
*/
onResize: function()
{
if (this.isShowing())
this._contentAreaResized();
},
/**
* @override
*/
wasShown: function()
{
this._measureHandles();
this._toolbar.restore();
},
/**
* @override
*/
willHide: function()
{
this._model.emulate(WebInspector.DeviceModeModel.Type.None, null, null);
},
captureScreenshot: function()
{
var mainTarget = WebInspector.targetManager.mainTarget();
if (!mainTarget)
return;
mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this));
/**
* @param {?Protocol.Error} error
* @param {string} content
* @this {WebInspector.DeviceModeView}
*/
function screenshotCaptured(error, content)
{
if (error)
return;
// Create a canvas to splice the images together.
var canvas = createElement("canvas");
var ctx = canvas.getContext("2d");
var screenRect = this._model.screenRect();
var dpr = window.devicePixelRatio;
canvas.width = screenRect.width * dpr;
canvas.height = screenRect.height * dpr;
// Add any available screen images.
if (this._model.screenImage()) {
var screenImage = new Image();
screenImage.crossOrigin = "Anonymous";
screenImage.srcset = this._model.screenImage();
screenImage.onload = onImageLoad.bind(this);
screenImage.onerror = paintScreenshot.bind(this);
} else {
paintScreenshot.call(this);
}
/**
* @this {WebInspector.DeviceModeView}
*/
function onImageLoad()
{
ctx.drawImage(screenImage, 0, 0, screenRect.width * dpr, screenRect.height * dpr);
paintScreenshot.call(this);
}
/**
* @this {WebInspector.DeviceModeView}
*/
function paintScreenshot()
{
var pageImage = new Image();
pageImage.src = "data:image/png;base64," + content;
var visiblePageRect = this._model.visiblePageRect().scale(dpr);
ctx.drawImage(pageImage,
visiblePageRect.left,
visiblePageRect.top,
visiblePageRect.width,
visiblePageRect.height);
var mainFrame = mainTarget.resourceTreeModel.mainFrame;
var fileName = mainFrame ? mainFrame.url.trimURL().removeURLFragment() : "";
if (this._model.type() === WebInspector.DeviceModeModel.Type.Device)
fileName += WebInspector.UIString("(%s)", this._model.device().title);
// Trigger download.
var link = createElement("a");
link.download = fileName + ".png";
link.href = canvas.toDataURL("image/png");
link.click();
}
}
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {boolean} horizontal
* @param {function(number)} applyCallback
*/
WebInspector.DeviceModeView.Ruler = function(horizontal, applyCallback)
{
WebInspector.VBox.call(this);
this._contentElement = this.element.createChild("div", "device-mode-ruler flex-auto");
this._horizontal = horizontal;
this._scale = 1;
this._offset = 0;
this._count = 0;
this._throttler = new WebInspector.Throttler(0);
this._applyCallback = applyCallback;
}
WebInspector.DeviceModeView.Ruler.prototype = {
/**
* @param {number} offset
* @param {number} scale
*/
render: function(offset, scale)
{
this._scale = scale;
this._offset = offset;
if (this._horizontal)
this.element.style.paddingLeft = this._offset + "px";
else
this.element.style.paddingTop = this._offset + "px";
this._throttler.schedule(this._update.bind(this));
},
/**
* @override
*/
onResize: function()
{
this._throttler.schedule(this._update.bind(this));
},
/**
* @return {!Promise.<?>}
*/
_update: function()
{
var zoomFactor = WebInspector.zoomManager.zoomFactor();
var size = this._horizontal ? this._contentElement.offsetWidth : this._contentElement.offsetHeight;
if (this._scale !== this._renderedScale || zoomFactor !== this._renderedZoomFactor) {
this._contentElement.removeChildren();
this._count = 0;
this._renderedScale = this._scale;
this._renderedZoomFactor = zoomFactor;
}
var dipSize = size * zoomFactor / this._scale;
var count = Math.ceil(dipSize / 5);
var step = 1;
if (this._scale < 0.8)
step = 2;
if (this._scale < 0.6)
step = 4;
if (this._scale < 0.4)
step = 8;
for (var i = count; i < this._count; i++) {
if (!(i % step))
this._contentElement.lastChild.remove();
}
for (var i = this._count; i < count; i++) {
if (i % step)
continue;
var marker = this._contentElement.createChild("div", "device-mode-ruler-marker");
if (i) {
if (this._horizontal)
marker.style.left = (5 * i) * this._scale / zoomFactor + "px";
else
marker.style.top = (5 * i) * this._scale / zoomFactor + "px";
if (!(i % 20)) {
var text = marker.createChild("div", "device-mode-ruler-text");
text.textContent = i * 5;
text.addEventListener("click", this._onMarkerClick.bind(this, i * 5), false);
}
}
if (!(i % 10))
marker.classList.add("device-mode-ruler-marker-large");
else if (!(i % 5))
marker.classList.add("device-mode-ruler-marker-medium");
}
this._count = count;
return Promise.resolve();
},
/**
* @param {number} size
*/
_onMarkerClick: function(size)
{
this._applyCallback.call(null, size);
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @extends {WebInspector.VBox}
* @param {!WebInspector.InspectedPagePlaceholder} inspectedPagePlaceholder
* @constructor
*/
WebInspector.DeviceModeWrapper = function(inspectedPagePlaceholder)
{
WebInspector.VBox.call(this);
WebInspector.DeviceModeView._wrapperInstance = this;
this._inspectedPagePlaceholder = inspectedPagePlaceholder;
/** @type {?WebInspector.DeviceModeView} */
this._deviceModeView = null;
this._toggleDeviceModeAction = WebInspector.actionRegistry.action("emulation.toggle-device-mode");
this._showDeviceModeSetting = WebInspector.settings.createSetting("emulation.showDeviceMode", false);
this._showDeviceModeSetting.addChangeListener(this._update.bind(this, false));
this._update(true);
}
/** @type {!WebInspector.DeviceModeWrapper} */
WebInspector.DeviceModeView._wrapperInstance;
WebInspector.DeviceModeWrapper.prototype = {
_toggleDeviceMode: function()
{
this._showDeviceModeSetting.set(!this._showDeviceModeSetting.get());
},
/**
* @return {boolean}
*/
_captureScreenshot: function()
{
if (!this._deviceModeView)
return false;
this._deviceModeView.captureScreenshot();
return true;
},
/**
* @param {boolean} force
*/
_update: function(force)
{
this._toggleDeviceModeAction.setToggled(this._showDeviceModeSetting.get());
if (!force) {
var showing = this._deviceModeView && this._deviceModeView.isShowing();
if (this._showDeviceModeSetting.get() === showing)
return;
}
if (this._showDeviceModeSetting.get()) {
if (!this._deviceModeView)
this._deviceModeView = new WebInspector.DeviceModeView();
this._deviceModeView.show(this.element);
this._inspectedPagePlaceholder.clearMinimumSizeAndMargins();
this._inspectedPagePlaceholder.show(this._deviceModeView.element);
} else {
if (this._deviceModeView)
this._deviceModeView.detach();
this._inspectedPagePlaceholder.restoreMinimumSizeAndMargins();
this._inspectedPagePlaceholder.show(this.element);
}
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.DeviceModeWrapper.ActionDelegate = function()
{
}
WebInspector.DeviceModeWrapper.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
if (WebInspector.DeviceModeView._wrapperInstance) {
if (actionId === "emulation.toggle-device-mode") {
WebInspector.DeviceModeView._wrapperInstance._toggleDeviceMode();
return true;
}
if (actionId === "emulation.capture-screenshot")
return WebInspector.DeviceModeView._wrapperInstance._captureScreenshot();
}
return false;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {number} alpha
* @param {number} beta
* @param {number} gamma
*/
WebInspector.DeviceOrientation = function(alpha, beta, gamma)
{
this.alpha = alpha;
this.beta = beta;
this.gamma = gamma;
}
WebInspector.DeviceOrientation.prototype = {
/**
* @return {string}
*/
toSetting: function()
{
return JSON.stringify(this);
},
apply: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.deviceOrientationAgent().setDeviceOrientationOverride(this.alpha, this.beta, this.gamma);
},
clear: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.deviceOrientationAgent().clearDeviceOrientationOverride();
}
}
/**
* @return {!WebInspector.DeviceOrientation}
*/
WebInspector.DeviceOrientation.parseSetting = function(value)
{
if (value) {
var jsonObject = JSON.parse(value);
return new WebInspector.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
}
return new WebInspector.DeviceOrientation(0, 0, 0);
}
/**
* @return {?WebInspector.DeviceOrientation}
*/
WebInspector.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
{
if (!alphaString && !betaString && !gammaString)
return null;
var isAlphaValid = WebInspector.DeviceOrientation.validator(alphaString);
var isBetaValid = WebInspector.DeviceOrientation.validator(betaString);
var isGammaValid = WebInspector.DeviceOrientation.validator(gammaString);
if (!isAlphaValid && !isBetaValid && !isGammaValid)
return null;
var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
var beta = isBetaValid ? parseFloat(betaString) : -1;
var gamma = isGammaValid ? parseFloat(gammaString) : -1;
return new WebInspector.DeviceOrientation(alpha, beta, gamma);
}
/**
* @param {string} value
* @return {boolean}
*/
WebInspector.DeviceOrientation.validator = function(value)
{
return !value || /^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | 2 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ListWidget.Delegate}
*/
WebInspector.DevicesSettingsTab = function()
{
WebInspector.VBox.call(this);
this.element.classList.add("settings-tab-container");
this.element.classList.add("devices-settings-tab");
this.registerRequiredCSS("emulation/devicesSettingsTab.css");
var header = this.element.createChild("header");
header.createChild("h3").createTextChild(WebInspector.UIString("Emulated Devices"));
this.containerElement = this.element.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
var buttonsRow = this.containerElement.createChild("div", "devices-button-row");
this._addCustomButton = createTextButton(WebInspector.UIString("Add custom device..."), this._addCustomDevice.bind(this));
buttonsRow.appendChild(this._addCustomButton);
this._list = new WebInspector.ListWidget(this);
this._list.registerRequiredCSS("emulation/devicesSettingsTab.css");
this._list.element.classList.add("devices-list");
this._list.show(this.containerElement);
this._muteUpdate = false;
this._emulatedDevicesList = WebInspector.EmulatedDevicesList.instance();
this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated, this._devicesUpdated, this);
this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated, this._devicesUpdated, this);
this.setDefaultFocusedElement(this._addCustomButton);
}
WebInspector.DevicesSettingsTab.prototype = {
wasShown: function()
{
WebInspector.VBox.prototype.wasShown.call(this);
this._devicesUpdated();
},
_devicesUpdated: function()
{
if (this._muteUpdate)
return;
this._list.clear();
var devices = this._emulatedDevicesList.custom().slice();
for (var i = 0; i < devices.length; ++i)
this._list.appendItem(devices[i], true);
this._list.appendSeparator();
devices = this._emulatedDevicesList.standard().slice();
devices.sort(WebInspector.EmulatedDevice.deviceComparator);
for (var i = 0; i < devices.length; ++i)
this._list.appendItem(devices[i], false);
},
/**
* @param {boolean} custom
*/
_muteAndSaveDeviceList: function(custom)
{
this._muteUpdate = true;
if (custom)
this._emulatedDevicesList.saveCustomDevices();
else
this._emulatedDevicesList.saveStandardDevices();
this._muteUpdate = false;
},
_addCustomDevice: function()
{
var device = new WebInspector.EmulatedDevice();
device.deviceScaleFactor = 0;
device.horizontal.width = 700;
device.horizontal.height = 400;
device.vertical.width = 400;
device.vertical.height = 700;
this._list.addNewItem(this._emulatedDevicesList.custom().length, device);
},
/**
* @param {number} value
* @return {string}
*/
_toNumericInputValue: function(value)
{
return value ? String(value) : "";
},
/**
* @override
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable)
{
var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
var element = createElementWithClass("div", "devices-list-item");
var checkbox = element.createChild("input", "devices-list-checkbox");
checkbox.type = "checkbox";
checkbox.checked = device.show();
element.createChild("div", "devices-list-title").textContent = device.title;
element.addEventListener("click", onItemClicked.bind(this), false);
return element;
/**
* @param {!Event} event
* @this {WebInspector.DevicesSettingsTab}
*/
function onItemClicked(event)
{
var show = !checkbox.checked;
device.setShow(show);
this._muteAndSaveDeviceList(editable);
checkbox.checked = show;
event.consume();
}
},
/**
* @override
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index)
{
this._emulatedDevicesList.removeCustomDevice(/** @type {!WebInspector.EmulatedDevice} */ (item));
},
/**
* @override
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew)
{
var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
device.title = editor.control("title").value.trim();
device.vertical.width = editor.control("width").value ? parseInt(editor.control("width").value, 10) : 0;
device.vertical.height = editor.control("height").value ? parseInt(editor.control("height").value, 10) : 0;
device.horizontal.width = device.vertical.height;
device.horizontal.height = device.vertical.width;
device.deviceScaleFactor = editor.control("scale").value ? parseFloat(editor.control("scale").value) : 0;
device.userAgent = editor.control("user-agent").value;
device.modes = [];
device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.Vertical, insets: new Insets(0, 0, 0, 0), image: null});
device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.Horizontal, insets: new Insets(0, 0, 0, 0), image: null});
device.capabilities = [];
var uaType = editor.control("ua-type").value;
if (uaType === WebInspector.DeviceModeModel.UA.Mobile || uaType === WebInspector.DeviceModeModel.UA.MobileNoTouch)
device.capabilities.push(WebInspector.EmulatedDevice.Capability.Mobile);
if (uaType === WebInspector.DeviceModeModel.UA.Mobile || uaType === WebInspector.DeviceModeModel.UA.DesktopTouch)
device.capabilities.push(WebInspector.EmulatedDevice.Capability.Touch);
if (isNew)
this._emulatedDevicesList.addCustomDevice(device);
else
this._emulatedDevicesList.saveCustomDevices();
this._addCustomButton.scrollIntoViewIfNeeded();
this._addCustomButton.focus();
},
/**
* @override
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item)
{
var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
var editor = this._createEditor();
editor.control("title").value = device.title;
editor.control("width").value = this._toNumericInputValue(device.vertical.width);
editor.control("height").value = this._toNumericInputValue(device.vertical.height);
editor.control("scale").value = this._toNumericInputValue(device.deviceScaleFactor);
editor.control("user-agent").value = device.userAgent;
var uaType;
if (device.mobile())
uaType = device.touch() ? WebInspector.DeviceModeModel.UA.Mobile : WebInspector.DeviceModeModel.UA.MobileNoTouch;
else
uaType = device.touch() ? WebInspector.DeviceModeModel.UA.DesktopTouch : WebInspector.DeviceModeModel.UA.Desktop;
editor.control("ua-type").value = uaType;
return editor;
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createEditor: function()
{
if (this._editor)
return this._editor;
var editor = new WebInspector.ListWidget.Editor();
this._editor = editor;
var content = editor.contentElement();
var fields = content.createChild("div", "devices-edit-fields");
fields.createChild("div", "hbox").appendChild(editor.createInput("title", "text", WebInspector.UIString("Device name"), titleValidator));
var screen = fields.createChild("div", "hbox");
screen.appendChild(editor.createInput("width", "text", WebInspector.UIString("Width"), sizeValidator));
screen.appendChild(editor.createInput("height", "text", WebInspector.UIString("height"), sizeValidator));
var dpr = editor.createInput("scale", "text", WebInspector.UIString("Device pixel ratio"), scaleValidator);
dpr.classList.add("device-edit-fixed");
screen.appendChild(dpr);
var ua = fields.createChild("div", "hbox");
ua.appendChild(editor.createInput("user-agent", "text", WebInspector.UIString("User agent string"), () => true));
var uaType = editor.createSelect("ua-type", [WebInspector.DeviceModeModel.UA.Mobile, WebInspector.DeviceModeModel.UA.MobileNoTouch, WebInspector.DeviceModeModel.UA.Desktop, WebInspector.DeviceModeModel.UA.DesktopTouch], () => true);
uaType.classList.add("device-edit-fixed");
ua.appendChild(uaType);
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function titleValidator(item, index, input)
{
var value = input.value.trim();
return value.length > 0 && value.length < 50;
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function sizeValidator(item, index, input)
{
return WebInspector.DeviceModeModel.deviceSizeValidator(input.value);
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function scaleValidator(item, index, input)
{
return WebInspector.DeviceModeModel.deviceScaleFactorValidator(input.value);
}
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | 2 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.EmulatedDevice = function() { /** @type {string} */ this.title = ""; /** @type {string} */ this.type = WebInspector.EmulatedDevice.Type.Unknown; /** @type {!WebInspector.EmulatedDevice.Orientation} */ this.vertical = {width: 0, height: 0, outlineInsets: null, outlineImage: null}; /** @type {!WebInspector.EmulatedDevice.Orientation} */ this.horizontal = {width: 0, height: 0, outlineInsets: null, outlineImage: null}; /** @type {number} */ this.deviceScaleFactor = 1; /** @type {!Array.<string>} */ this.capabilities = [WebInspector.EmulatedDevice.Capability.Touch, WebInspector.EmulatedDevice.Capability.Mobile]; /** @type {string} */ this.userAgent = ""; /** @type {!Array.<!WebInspector.EmulatedDevice.Mode>} */ this.modes = []; /** @type {string} */ this._show = WebInspector.EmulatedDevice._Show.Default; /** @type {boolean} */ this._showByDefault = true; /** @type {?Runtime.Extension} */ this._extension = null; } /** @typedef {!{title: string, orientation: string, insets: !Insets, image: ?string}} */ WebInspector.EmulatedDevice.Mode; /** @typedef {!{width: number, height: number, outlineInsets: ?Insets, outlineImage: ?string}} */ WebInspector.EmulatedDevice.Orientation; WebInspector.EmulatedDevice.Horizontal = "horizontal"; WebInspector.EmulatedDevice.Vertical = "vertical"; WebInspector.EmulatedDevice.Type = { Phone: "phone", Tablet: "tablet", Notebook: "notebook", Desktop: "desktop", Unknown: "unknown" } WebInspector.EmulatedDevice.Capability = { Touch: "touch", Mobile: "mobile" } WebInspector.EmulatedDevice._Show = { Always: "Always", Default: "Default", Never: "Never" } /** * @param {*} json * @return {?WebInspector.EmulatedDevice} */ WebInspector.EmulatedDevice.fromJSONV1 = function(json) { try { /** * @param {*} object * @param {string} key * @param {string} type * @param {*=} defaultValue * @return {*} */ function parseValue(object, key, type, defaultValue) { if (typeof object !== "object" || object === null || !object.hasOwnProperty(key)) { if (typeof defaultValue !== "undefined") return defaultValue; throw new Error("Emulated device is missing required property '" + key + "'"); } var value = object[key]; if (typeof value !== type || value === null) throw new Error("Emulated device property '" + key + "' has wrong type '" + typeof value + "'"); return value; } /** * @param {*} object * @param {string} key * @return {number} */ function parseIntValue(object, key) { var value = /** @type {number} */ (parseValue(object, key, "number")); if (value !== Math.abs(value)) throw new Error("Emulated device value '" + key + "' must be integer"); return value; } /** * @param {*} json * @return {!Insets} */ function parseInsets(json) { return new Insets(parseIntValue(json, "left"), parseIntValue(json, "top"), parseIntValue(json, "right"), parseIntValue(json, "bottom")); } /** * @param {*} json * @return {!WebInspector.EmulatedDevice.Orientation} */ function parseOrientation(json) { var result = {}; result.width = parseIntValue(json, "width"); if (result.width < 0 || result.width > WebInspector.DeviceModeModel.MaxDeviceSize || result.width < WebInspector.DeviceModeModel.MinDeviceSize) throw new Error("Emulated device has wrong width: " + result.width); result.height = parseIntValue(json, "height"); if (result.height < 0 || result.height > WebInspector.DeviceModeModel.MaxDeviceSize || result.height < WebInspector.DeviceModeModel.MinDeviceSize) throw new Error("Emulated device has wrong height: " + result.height); var outlineInsets = parseValue(json["outline"], "insets", "object", null); if (outlineInsets) { result.outlineInsets = parseInsets(outlineInsets); if (result.outlineInsets.left < 0 || result.outlineInsets.top < 0) throw new Error("Emulated device has wrong outline insets"); result.outlineImage = /** @type {string} */ (parseValue(json["outline"], "image", "string")); } return /** @type {!WebInspector.EmulatedDevice.Orientation} */ (result); } var result = new WebInspector.EmulatedDevice(); result.title = /** @type {string} */ (parseValue(json, "title", "string")); result.type = /** @type {string} */ (parseValue(json, "type", "string")); result.userAgent = /** @type {string} */ (parseValue(json, "user-agent", "string")); var capabilities = parseValue(json, "capabilities", "object", []); if (!Array.isArray(capabilities)) throw new Error("Emulated device capabilities must be an array"); result.capabilities = []; for (var i = 0; i < capabilities.length; ++i) { if (typeof capabilities[i] !== "string") throw new Error("Emulated device capability must be a string"); result.capabilities.push(capabilities[i]); } result.deviceScaleFactor = /** @type {number} */ (parseValue(json["screen"], "device-pixel-ratio", "number")); if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100) throw new Error("Emulated device has wrong deviceScaleFactor: " + result.deviceScaleFactor); result.vertical = parseOrientation(parseValue(json["screen"], "vertical", "object")); result.horizontal = parseOrientation(parseValue(json["screen"], "horizontal", "object")); var modes = parseValue(json, "modes", "object", []); if (!Array.isArray(modes)) throw new Error("Emulated device modes must be an array"); result.modes = []; for (var i = 0; i < modes.length; ++i) { var mode = {}; mode.title = /** @type {string} */ (parseValue(modes[i], "title", "string")); mode.orientation = /** @type {string} */ (parseValue(modes[i], "orientation", "string")); if (mode.orientation !== WebInspector.EmulatedDevice.Vertical && mode.orientation !== WebInspector.EmulatedDevice.Horizontal) throw new Error("Emulated device mode has wrong orientation '" + mode.orientation + "'"); var orientation = result.orientationByName(mode.orientation); mode.insets = parseInsets(parseValue(modes[i], "insets", "object")); if (mode.insets.top < 0 || mode.insets.left < 0 || mode.insets.right < 0 || mode.insets.bottom < 0 || mode.insets.top + mode.insets.bottom > orientation.height || mode.insets.left + mode.insets.right > orientation.width) { throw new Error("Emulated device mode '" + mode.title + "'has wrong mode insets"); } mode.image = /** @type {string} */ (parseValue(modes[i], "image", "string", null)); result.modes.push(mode); } result._showByDefault = /** @type {boolean} */ (parseValue(json, "show-by-default", "boolean", undefined)); result._show = /** @type {string} */ (parseValue(json, "show", "string", WebInspector.EmulatedDevice._Show.Default)); return result; } catch (e) { return null; } } /** * @param {!WebInspector.EmulatedDevice} device1 * @param {!WebInspector.EmulatedDevice} device2 * @return {number} */ WebInspector.EmulatedDevice.deviceComparator = function(device1, device2) { var order1 = (device1._extension && device1._extension.descriptor()["order"]) || -1; var order2 = (device2._extension && device2._extension.descriptor()["order"]) || -1; if (order1 > order2) return 1; if (order2 > order1) return -1; return device1.title < device2.title ? -1 : (device1.title > device2.title ? 1 : 0); } WebInspector.EmulatedDevice.prototype = { /** * @return {?Runtime.Extension} */ extension: function() { return this._extension; }, /** * @param {?Runtime.Extension} extension */ setExtension: function(extension) { this._extension = extension; }, /** * @param {string} orientation * @return {!Array.<!WebInspector.EmulatedDevice.Mode>} */ modesForOrientation: function(orientation) { var result = []; for (var index = 0; index < this.modes.length; index++) { if (this.modes[index].orientation === orientation) result.push(this.modes[index]); } return result; }, /** * @return {*} */ _toJSON: function() { var json = {}; json["title"] = this.title; json["type"] = this.type; json["user-agent"] = this.userAgent; json["capabilities"] = this.capabilities; json["screen"] = {}; json["screen"]["device-pixel-ratio"] = this.deviceScaleFactor; json["screen"]["vertical"] = this._orientationToJSON(this.vertical); json["screen"]["horizontal"] = this._orientationToJSON(this.horizontal); json["modes"] = []; for (var i = 0; i < this.modes.length; ++i) { var mode = {}; mode["title"] = this.modes[i].title; mode["orientation"] = this.modes[i].orientation; mode["insets"] = {}; mode["insets"]["left"] = this.modes[i].insets.left; mode["insets"]["top"] = this.modes[i].insets.top; mode["insets"]["right"] = this.modes[i].insets.right; mode["insets"]["bottom"] = this.modes[i].insets.bottom; if (this.modes[i].image) mode["image"] = this.modes[i].image; json["modes"].push(mode); } json["show-by-default"] = this._showByDefault; json["show"] = this._show; return json; }, /** * @param {!WebInspector.EmulatedDevice.Orientation} orientation * @return {*} */ _orientationToJSON: function(orientation) { var json = {}; json["width"] = orientation.width; json["height"] = orientation.height; if (orientation.outlineInsets) { json["outline"] = {}; json["outline"]["insets"] = {}; json["outline"]["insets"]["left"] = orientation.outlineInsets.left; json["outline"]["insets"]["top"] = orientation.outlineInsets.top; json["outline"]["insets"]["right"] = orientation.outlineInsets.right; json["outline"]["insets"]["bottom"] = orientation.outlineInsets.bottom; json["outline"]["image"] = orientation.outlineImage; } return json; }, /** * @param {!WebInspector.EmulatedDevice.Mode} mode * @return {string} */ modeImage: function(mode) { if (!mode.image) return ""; if (!this._extension) return mode.image; return this._extension.module().substituteURL(mode.image); }, /** * @param {string} name * @return {!WebInspector.EmulatedDevice.Orientation} */ orientationByName: function(name) { return name === WebInspector.EmulatedDevice.Vertical ? this.vertical : this.horizontal; }, /** * @return {boolean} */ show: function() { if (this._show === WebInspector.EmulatedDevice._Show.Default) return this._showByDefault; return this._show === WebInspector.EmulatedDevice._Show.Always; }, /** * @param {boolean} show */ setShow: function(show) { this._show = show ? WebInspector.EmulatedDevice._Show.Always : WebInspector.EmulatedDevice._Show.Never; }, /** * @param {!WebInspector.EmulatedDevice} other */ copyShowFrom: function(other) { this._show = other._show; }, /** * @return {boolean} */ touch: function() { return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Touch) !== -1; }, /** * @return {boolean} */ mobile: function() { return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Mobile) !== -1; } } /** * @constructor * @extends {WebInspector.Object} */ WebInspector.EmulatedDevicesList = function() { WebInspector.Object.call(this); /** @type {!WebInspector.Setting} */ this._standardSetting = WebInspector.settings.createSetting("standardEmulatedDeviceList", []); /** @type {!Array.<!WebInspector.EmulatedDevice>} */ this._standard = []; this._listFromJSONV1(this._standardSetting.get(), this._standard); this._updateStandardDevices(); /** @type {!WebInspector.Setting} */ this._customSetting = WebInspector.settings.createSetting("customEmulatedDeviceList", []); /** @type {!Array.<!WebInspector.EmulatedDevice>} */ this._custom = []; if (!this._listFromJSONV1(this._customSetting.get(), this._custom)) this.saveCustomDevices(); } WebInspector.EmulatedDevicesList.Events = { CustomDevicesUpdated: "CustomDevicesUpdated", StandardDevicesUpdated: "StandardDevicesUpdated" } WebInspector.EmulatedDevicesList.prototype = { _updateStandardDevices: function() { var devices = []; var extensions = self.runtime.extensions("emulated-device"); for (var i = 0; i < extensions.length; ++i) { var device = WebInspector.EmulatedDevice.fromJSONV1(extensions[i].descriptor()["device"]); device.setExtension(extensions[i]); devices.push(device); } this._copyShowValues(this._standard, devices); this._standard = devices; this.saveStandardDevices(); }, /** * @param {!Array.<*>} jsonArray * @param {!Array.<!WebInspector.EmulatedDevice>} result * @return {boolean} */ _listFromJSONV1: function(jsonArray, result) { if (!Array.isArray(jsonArray)) return false; var success = true; for (var i = 0; i < jsonArray.length; ++i) { var device = WebInspector.EmulatedDevice.fromJSONV1(jsonArray[i]); if (device) { result.push(device); if (!device.modes.length) { device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.Horizontal, insets: new Insets(0, 0, 0, 0), image: null}); device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.Vertical, insets: new Insets(0, 0, 0, 0), image: null}); } } else { success = false; } } return success; }, /** * @return {!Array.<!WebInspector.EmulatedDevice>} */ standard: function() { return this._standard; }, /** * @return {!Array.<!WebInspector.EmulatedDevice>} */ custom: function() { return this._custom; }, revealCustomSetting: function() { WebInspector.Revealer.reveal(this._customSetting); }, /** * @param {!WebInspector.EmulatedDevice} device */ addCustomDevice: function(device) { this._custom.push(device); this.saveCustomDevices(); }, /** * @param {!WebInspector.EmulatedDevice} device */ removeCustomDevice: function(device) { this._custom.remove(device); this.saveCustomDevices(); }, saveCustomDevices: function() { var json = this._custom.map(/** @param {!WebInspector.EmulatedDevice} device */ function(device) { return device._toJSON(); }); this._customSetting.set(json); this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated); }, saveStandardDevices: function() { var json = this._standard.map(/** @param {!WebInspector.EmulatedDevice} device */ function(device) { return device._toJSON(); }); this._standardSetting.set(json); this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated); }, /** * @param {!Array.<!WebInspector.EmulatedDevice>} from * @param {!Array.<!WebInspector.EmulatedDevice>} to */ _copyShowValues: function(from, to) { var deviceById = new Map(); for (var i = 0; i < from.length; ++i) deviceById.set(from[i].title, from[i]); for (var i = 0; i < to.length; ++i) { var title = to[i].title; if (deviceById.has(title)) to[i].copyShowFrom(/** @type {!WebInspector.EmulatedDevice} */ (deviceById.get(title))); } }, __proto__: WebInspector.Object.prototype } /** @type {?WebInspector.EmulatedDevicesList} */ WebInspector.EmulatedDevicesList._instance; /** * @return {!WebInspector.EmulatedDevicesList} */ WebInspector.EmulatedDevicesList.instance = function() { if (!WebInspector.EmulatedDevicesList._instance) WebInspector.EmulatedDevicesList._instance = new WebInspector.EmulatedDevicesList(); return /** @type {!WebInspector.EmulatedDevicesList} */ (WebInspector.EmulatedDevicesList._instance); } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {number} latitude
* @param {number} longitude
* @param {string} error
*/
WebInspector.Geolocation = function(latitude, longitude, error)
{
this.latitude = latitude;
this.longitude = longitude;
this.error = error;
}
WebInspector.Geolocation.prototype = {
/**
* @return {string}
*/
toSetting: function()
{
return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
},
apply: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)) {
if (this.error)
target.emulationAgent().setGeolocationOverride();
else
target.emulationAgent().setGeolocationOverride(this.latitude, this.longitude, 150);
}
},
clear: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.emulationAgent().clearGeolocationOverride();
}
}
/**
* @return {!WebInspector.Geolocation}
*/
WebInspector.Geolocation.parseSetting = function(value)
{
if (value) {
var splitError = value.split(":");
if (splitError.length === 2) {
var splitPosition = splitError[0].split("@");
if (splitPosition.length === 2)
return new WebInspector.Geolocation(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
}
}
return new WebInspector.Geolocation(0, 0, "");
}
/**
* @return {?WebInspector.Geolocation}
*/
WebInspector.Geolocation.parseUserInput = function(latitudeString, longitudeString, errorStatus)
{
if (!latitudeString && !longitudeString)
return null;
var isLatitudeValid = WebInspector.Geolocation.latitudeValidator(latitudeString);
var isLongitudeValid = WebInspector.Geolocation.longitudeValidator(longitudeString);
if (!isLatitudeValid && !isLongitudeValid)
return null;
var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
return new WebInspector.Geolocation(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
}
/**
* @param {string} value
* @return {boolean}
*/
WebInspector.Geolocation.latitudeValidator = function(value)
{
return !value || (/^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value) && value >= -90 && value <= 90);
}
/**
* @param {string} value
* @return {boolean}
*/
WebInspector.Geolocation.longitudeValidator = function(value)
{
return !value || (/^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value) && value >= -180 && value <= 180);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Widget}
*/
WebInspector.InspectedPagePlaceholder = function()
{
WebInspector.Widget.call(this);
this.element.classList.add("inspected-page-placeholder");
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._scheduleUpdate, this);
this._margins = { top: 0, right: 0, bottom: 0, left: 0 };
this.restoreMinimumSizeAndMargins();
};
WebInspector.InspectedPagePlaceholder.Events = {
Update: "Update"
};
WebInspector.InspectedPagePlaceholder.MarginValue = 3;
WebInspector.InspectedPagePlaceholder.prototype = {
_findMargins: function()
{
var margins = { top: 0, right: 0, bottom: 0, left: 0 };
if (this._useMargins) {
var adjacent = { top: true, right: true, bottom: true, left: true };
var widget = this;
while (widget.parentWidget()) {
var parent = widget.parentWidget();
// This view assumes it's always inside the main split widget element, not a sidebar.
// Every parent which is not a split widget, must be of the same size as this widget.
if (parent instanceof WebInspector.SplitWidget) {
var side = parent.sidebarSide();
if (adjacent[side] && !parent.hasCustomResizer() && parent.isResizable())
margins[side] = WebInspector.InspectedPagePlaceholder.MarginValue;
adjacent[side] = false;
}
widget = parent;
}
}
if (this._margins.top !== margins.top || this._margins.left !== margins.left || this._margins.right !== margins.right || this._margins.bottom !== margins.bottom) {
this._margins = margins;
this._scheduleUpdate();
}
},
onResize: function()
{
this._findMargins();
this._scheduleUpdate();
},
_scheduleUpdate: function()
{
if (this._updateId)
this.element.window().cancelAnimationFrame(this._updateId);
this._updateId = this.element.window().requestAnimationFrame(this.update.bind(this));
},
restoreMinimumSizeAndMargins: function()
{
this._useMargins = true;
this.setMinimumSize(150, 150);
this._findMargins();
},
clearMinimumSizeAndMargins: function()
{
this._useMargins = false;
this.setMinimumSize(1, 1);
this._findMargins();
},
_dipPageRect: function()
{
var zoomFactor = WebInspector.zoomManager.zoomFactor();
var rect = this.element.getBoundingClientRect();
var bodyRect = this.element.ownerDocument.body.getBoundingClientRect();
var left = Math.max(rect.left * zoomFactor + this._margins.left, bodyRect.left * zoomFactor);
var top = Math.max(rect.top * zoomFactor + this._margins.top, bodyRect.top * zoomFactor);
var bottom = Math.min(rect.bottom * zoomFactor - this._margins.bottom, bodyRect.bottom * zoomFactor);
var right = Math.min(rect.right * zoomFactor - this._margins.right, bodyRect.right * zoomFactor);
return { x: left, y: top, width: right - left, height: bottom - top };
},
update: function()
{
delete this._updateId;
var rect = this._dipPageRect();
var bounds = { x: Math.round(rect.x), y: Math.round(rect.y), height: Math.max(1, Math.round(rect.height)), width: Math.max(1, Math.round(rect.width)) };
this.dispatchEventToListeners(WebInspector.InspectedPagePlaceholder.Events.Update, bounds);
},
__proto__: WebInspector.Widget.prototype
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | 2 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Widget}
* @implements {WebInspector.TargetManager.Observer}
* @param {function():number} getWidthCallback
* @param {function(number)} setWidthCallback
*/
WebInspector.MediaQueryInspector = function(getWidthCallback, setWidthCallback)
{
WebInspector.Widget.call(this, true);
this.registerRequiredCSS("emulation/mediaQueryInspector.css");
this.contentElement.classList.add("media-inspector-view");
this.contentElement.addEventListener("click", this._onMediaQueryClicked.bind(this), false);
this.contentElement.addEventListener("contextmenu", this._onContextMenu.bind(this), false);
this._mediaThrottler = new WebInspector.Throttler(0);
this._getWidthCallback = getWidthCallback;
this._setWidthCallback = setWidthCallback;
this._scale = 1;
WebInspector.targetManager.observeTargets(this);
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._renderMediaQueries.bind(this), this);
}
/**
* @enum {number}
*/
WebInspector.MediaQueryInspector.Section = {
Max: 0,
MinMax: 1,
Min: 2
}
WebInspector.MediaQueryInspector.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
// FIXME: adapt this to multiple targets.
if (this._cssModel)
return;
this._cssModel = WebInspector.CSSModel.fromTarget(target);
if (!this._cssModel)
return;
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._scheduleMediaQueriesUpdate, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._scheduleMediaQueriesUpdate, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged, this._scheduleMediaQueriesUpdate, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged, this._scheduleMediaQueriesUpdate, this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (WebInspector.CSSModel.fromTarget(target) !== this._cssModel)
return;
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._scheduleMediaQueriesUpdate, this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved, this._scheduleMediaQueriesUpdate, this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetChanged, this._scheduleMediaQueriesUpdate, this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged, this._scheduleMediaQueriesUpdate, this);
delete this._cssModel;
},
/**
* @param {number} scale
*/
setAxisTransform: function(scale)
{
if (Math.abs(this._scale - scale) < 1e-8)
return;
this._scale = scale;
this._renderMediaQueries();
},
/**
* @param {!Event} event
*/
_onMediaQueryClicked: function(event)
{
var mediaQueryMarker = event.target.enclosingNodeOrSelfWithClass("media-inspector-bar");
if (!mediaQueryMarker)
return;
var model = mediaQueryMarker._model;
if (model.section() === WebInspector.MediaQueryInspector.Section.Max) {
this._setWidthCallback(model.maxWidthExpression().computedLength());
return;
}
if (model.section() === WebInspector.MediaQueryInspector.Section.Min) {
this._setWidthCallback(model.minWidthExpression().computedLength());
return;
}
var currentWidth = this._getWidthCallback();
if (currentWidth !== model.minWidthExpression().computedLength())
this._setWidthCallback(model.minWidthExpression().computedLength());
else
this._setWidthCallback(model.maxWidthExpression().computedLength());
},
/**
* @param {!Event} event
*/
_onContextMenu: function(event)
{
if (!this._cssModel || !this._cssModel.isEnabled())
return;
var mediaQueryMarker = event.target.enclosingNodeOrSelfWithClass("media-inspector-bar");
if (!mediaQueryMarker)
return;
var locations = mediaQueryMarker._locations;
var uiLocations = new Map();
for (var i = 0; i < locations.length; ++i) {
var uiLocation = WebInspector.cssWorkspaceBinding.rawLocationToUILocation(locations[i]);
if (!uiLocation)
continue;
var descriptor = String.sprintf("%s:%d:%d", uiLocation.uiSourceCode.url(), uiLocation.lineNumber + 1, uiLocation.columnNumber + 1);
uiLocations.set(descriptor, uiLocation);
}
var contextMenuItems = uiLocations.keysArray().sort();
var contextMenu = new WebInspector.ContextMenu(event);
var subMenuItem = contextMenu.appendSubMenuItem(WebInspector.UIString.capitalize("Reveal in ^source ^code"));
for (var i = 0; i < contextMenuItems.length; ++i) {
var title = contextMenuItems[i];
subMenuItem.appendItem(title, this._revealSourceLocation.bind(this, /** @type {!WebInspector.UILocation} */(uiLocations.get(title))));
}
contextMenu.show();
},
/**
* @param {!WebInspector.UILocation} location
*/
_revealSourceLocation: function(location)
{
WebInspector.Revealer.reveal(location);
},
_scheduleMediaQueriesUpdate: function()
{
if (!this.isShowing())
return;
this._mediaThrottler.schedule(this._refetchMediaQueries.bind(this));
},
_refetchMediaQueries: function()
{
if (!this.isShowing() || !this._cssModel)
return Promise.resolve();
return this._cssModel.mediaQueriesPromise()
.then(this._rebuildMediaQueries.bind(this))
},
/**
* @param {!Array.<!WebInspector.MediaQueryInspector.MediaQueryUIModel>} models
* @return {!Array.<!WebInspector.MediaQueryInspector.MediaQueryUIModel>}
*/
_squashAdjacentEqual: function(models)
{
var filtered = [];
for (var i = 0; i < models.length; ++i) {
var last = filtered.peekLast();
if (!last || !last.equals(models[i]))
filtered.push(models[i]);
}
return filtered;
},
/**
* @param {!Array.<!WebInspector.CSSMedia>} cssMedias
*/
_rebuildMediaQueries: function(cssMedias)
{
var queryModels = [];
for (var i = 0; i < cssMedias.length; ++i) {
var cssMedia = cssMedias[i];
if (!cssMedia.mediaList)
continue;
for (var j = 0; j < cssMedia.mediaList.length; ++j) {
var mediaQuery = cssMedia.mediaList[j];
var queryModel = WebInspector.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery(cssMedia, mediaQuery);
if (queryModel && queryModel.rawLocation())
queryModels.push(queryModel);
}
}
queryModels.sort(compareModels);
queryModels = this._squashAdjacentEqual(queryModels);
var allEqual = this._cachedQueryModels && this._cachedQueryModels.length == queryModels.length;
for (var i = 0; allEqual && i < queryModels.length; ++i)
allEqual = allEqual && this._cachedQueryModels[i].equals(queryModels[i]);
if (allEqual)
return;
this._cachedQueryModels = queryModels;
this._renderMediaQueries();
/**
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model1
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model2
* @return {number}
*/
function compareModels(model1, model2)
{
return model1.compareTo(model2);
}
},
_renderMediaQueries: function()
{
if (!this._cachedQueryModels || !this.isShowing())
return;
var markers = [];
var lastMarker = null;
for (var i = 0; i < this._cachedQueryModels.length; ++i) {
var model = this._cachedQueryModels[i];
if (lastMarker && lastMarker.model.dimensionsEqual(model)) {
lastMarker.locations.push(model.rawLocation());
lastMarker.active = lastMarker.active || model.active();
} else {
lastMarker = {
active: model.active(),
model: model,
locations: [ model.rawLocation() ]
};
markers.push(lastMarker);
}
}
this.contentElement.removeChildren();
var container = null;
for (var i = 0; i < markers.length; ++i) {
if (!i || markers[i].model.section() !== markers[i - 1].model.section())
container = this.contentElement.createChild("div", "media-inspector-marker-container");
var marker = markers[i];
var bar = this._createElementFromMediaQueryModel(marker.model);
bar._model = marker.model;
bar._locations = marker.locations;
bar.classList.toggle("media-inspector-marker-inactive", !marker.active);
container.appendChild(bar);
}
},
/**
* @return {number}
*/
_zoomFactor: function()
{
return WebInspector.zoomManager.zoomFactor() / this._scale;
},
wasShown: function()
{
this._scheduleMediaQueriesUpdate();
},
/**
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model
* @return {!Element}
*/
_createElementFromMediaQueryModel: function(model)
{
var zoomFactor = this._zoomFactor();
var minWidthValue = model.minWidthExpression() ? model.minWidthExpression().computedLength() / zoomFactor : 0;
var maxWidthValue = model.maxWidthExpression() ? model.maxWidthExpression().computedLength() / zoomFactor : 0;
var result = createElementWithClass("div", "media-inspector-bar");
if (model.section() === WebInspector.MediaQueryInspector.Section.Max) {
result.createChild("div", "media-inspector-marker-spacer");
var markerElement = result.createChild("div", "media-inspector-marker media-inspector-marker-max-width");
markerElement.style.width = maxWidthValue + "px";
markerElement.title = model.mediaText();
appendLabel(markerElement, model.maxWidthExpression(), false, false);
appendLabel(markerElement, model.maxWidthExpression(), true, true);
result.createChild("div", "media-inspector-marker-spacer");
}
if (model.section() === WebInspector.MediaQueryInspector.Section.MinMax) {
result.createChild("div", "media-inspector-marker-spacer");
var leftElement = result.createChild("div", "media-inspector-marker media-inspector-marker-min-max-width");
leftElement.style.width = (maxWidthValue - minWidthValue) * 0.5 + "px";
leftElement.title = model.mediaText();
appendLabel(leftElement, model.minWidthExpression(), true, false);
appendLabel(leftElement, model.maxWidthExpression(), false, true);
result.createChild("div", "media-inspector-marker-spacer").style.flex = "0 0 " + minWidthValue + "px";
var rightElement = result.createChild("div", "media-inspector-marker media-inspector-marker-min-max-width");
rightElement.style.width = (maxWidthValue - minWidthValue) * 0.5 + "px";
rightElement.title = model.mediaText();
appendLabel(rightElement, model.minWidthExpression(), true, false);
appendLabel(rightElement, model.maxWidthExpression(), false, true);
result.createChild("div", "media-inspector-marker-spacer");
}
if (model.section() === WebInspector.MediaQueryInspector.Section.Min) {
var leftElement = result.createChild("div", "media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-left");
leftElement.title = model.mediaText();
appendLabel(leftElement, model.minWidthExpression(), false, false);
result.createChild("div", "media-inspector-marker-spacer").style.flex = "0 0 " + minWidthValue + "px";
var rightElement = result.createChild("div", "media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-right");
rightElement.title = model.mediaText();
appendLabel(rightElement, model.minWidthExpression(), true, true);
}
function appendLabel(marker, expression, atLeft, leftAlign)
{
marker.createChild("div", "media-inspector-marker-label-container " + (atLeft ? "media-inspector-marker-label-container-left" : "media-inspector-marker-label-container-right"))
.createChild("span", "media-inspector-marker-label " + (leftAlign ? "media-inspector-label-left" : "media-inspector-label-right"))
.textContent = expression.value() + expression.unit();
}
return result;
},
__proto__: WebInspector.Widget.prototype
};
/**
* @constructor
* @param {!WebInspector.CSSMedia} cssMedia
* @param {?WebInspector.CSSMediaQueryExpression} minWidthExpression
* @param {?WebInspector.CSSMediaQueryExpression} maxWidthExpression
* @param {boolean} active
*/
WebInspector.MediaQueryInspector.MediaQueryUIModel = function(cssMedia, minWidthExpression, maxWidthExpression, active)
{
this._cssMedia = cssMedia;
this._minWidthExpression = minWidthExpression;
this._maxWidthExpression = maxWidthExpression;
this._active = active;
if (maxWidthExpression && !minWidthExpression)
this._section = WebInspector.MediaQueryInspector.Section.Max;
else if (minWidthExpression && maxWidthExpression)
this._section = WebInspector.MediaQueryInspector.Section.MinMax;
else
this._section = WebInspector.MediaQueryInspector.Section.Min;
}
/**
* @param {!WebInspector.CSSMedia} cssMedia
* @param {!WebInspector.CSSMediaQuery} mediaQuery
* @return {?WebInspector.MediaQueryInspector.MediaQueryUIModel}
*/
WebInspector.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery = function(cssMedia, mediaQuery)
{
var maxWidthExpression = null;
var maxWidthPixels = Number.MAX_VALUE;
var minWidthExpression = null;
var minWidthPixels = Number.MIN_VALUE;
var expressions = mediaQuery.expressions();
for (var i = 0; i < expressions.length; ++i) {
var expression = expressions[i];
var feature = expression.feature();
if (feature.indexOf("width") === -1)
continue;
var pixels = expression.computedLength();
if (feature.startsWith("max-") && pixels < maxWidthPixels) {
maxWidthExpression = expression;
maxWidthPixels = pixels;
} else if (feature.startsWith("min-") && pixels > minWidthPixels) {
minWidthExpression = expression;
minWidthPixels = pixels;
}
}
if (minWidthPixels > maxWidthPixels || (!maxWidthExpression && !minWidthExpression))
return null;
return new WebInspector.MediaQueryInspector.MediaQueryUIModel(cssMedia, minWidthExpression, maxWidthExpression, mediaQuery.active());
}
WebInspector.MediaQueryInspector.MediaQueryUIModel.prototype = {
/**
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} other
* @return {boolean}
*/
equals: function(other)
{
return this.compareTo(other) === 0;
},
/**
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} other
* @return {boolean}
*/
dimensionsEqual: function(other)
{
return this.section() === other.section()
&& (!this.minWidthExpression() || (this.minWidthExpression().computedLength() === other.minWidthExpression().computedLength()))
&& (!this.maxWidthExpression() || (this.maxWidthExpression().computedLength() === other.maxWidthExpression().computedLength()));
},
/**
* @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} other
* @return {number}
*/
compareTo: function(other)
{
if (this.section() !== other.section())
return this.section() - other.section();
if (this.dimensionsEqual(other)) {
var myLocation = this.rawLocation();
var otherLocation = other.rawLocation();
if (!myLocation && !otherLocation)
return this.mediaText().compareTo(other.mediaText());
if (myLocation && !otherLocation)
return 1;
if (!myLocation && otherLocation)
return -1;
if (this.active() !== other.active())
return this.active() ? -1 : 1;
return myLocation.url.compareTo(otherLocation.url) || myLocation.lineNumber - otherLocation.lineNumber || myLocation.columnNumber - otherLocation.columnNumber;
}
if (this.section() === WebInspector.MediaQueryInspector.Section.Max)
return other.maxWidthExpression().computedLength() - this.maxWidthExpression().computedLength();
if (this.section() === WebInspector.MediaQueryInspector.Section.Min)
return this.minWidthExpression().computedLength() - other.minWidthExpression().computedLength();
return this.minWidthExpression().computedLength() - other.minWidthExpression().computedLength() || other.maxWidthExpression().computedLength() - this.maxWidthExpression().computedLength();
},
/**
* @return {!WebInspector.MediaQueryInspector.Section}
*/
section: function()
{
return this._section;
},
/**
* @return {string}
*/
mediaText: function()
{
return this._cssMedia.text;
},
/**
* @return {?WebInspector.CSSLocation}
*/
rawLocation: function()
{
if (!this._rawLocation)
this._rawLocation = this._cssMedia.rawLocation();
return this._rawLocation;
},
/**
* @return {?WebInspector.CSSMediaQueryExpression}
*/
minWidthExpression: function()
{
return this._minWidthExpression;
},
/**
* @return {?WebInspector.CSSMediaQueryExpression}
*/
maxWidthExpression: function()
{
return this._maxWidthExpression;
},
/**
* @return {boolean}
*/
active: function()
{
return this._active;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | 2 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.SensorsView = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("emulation/sensors.css");
this.contentElement.classList.add("sensors-view");
this._geolocationSetting = WebInspector.settings.createSetting("emulation.geolocationOverride", "");
this._geolocation = WebInspector.Geolocation.parseSetting(this._geolocationSetting.get());
this._geolocationEnabled = false;
this._appendGeolocationOverrideControl();
this._deviceOrientationSetting = WebInspector.settings.createSetting("emulation.deviceOrientationOverride", "");
this._deviceOrientation = WebInspector.DeviceOrientation.parseSetting(this._deviceOrientationSetting.get());
this._deviceOrientationEnabled = false;
this._appendDeviceOrientationOverrideControl();
this._appendTouchControl();
}
WebInspector.SensorsView.prototype = {
_appendGeolocationOverrideControl: function()
{
var checkboxLabel = createCheckboxLabel(WebInspector.UIString("Emulate geolocation coordinates"));
this._geolocationOverrideCheckbox = checkboxLabel.checkboxElement;
this._geolocationOverrideCheckbox.addEventListener("click", this._geolocationOverrideCheckboxClicked.bind(this));
this.contentElement.appendChild(checkboxLabel);
this._geolocationFieldset = this._createGeolocationOverrideElement(this._geolocation);
this._geolocationFieldset.disabled = true;
this.contentElement.appendChild(this._geolocationFieldset);
},
_geolocationOverrideCheckboxClicked: function()
{
var enabled = this._geolocationOverrideCheckbox.checked;
this._geolocationEnabled = enabled;
this._applyGeolocation();
if (enabled && !this._latitudeElement.value)
this._latitudeElement.focus();
this._geolocationFieldset.disabled = !enabled;
},
_applyGeolocationUserInput: function()
{
var geolocation = WebInspector.Geolocation.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked);
if (!geolocation)
return;
this._geolocation = geolocation;
this._applyGeolocation();
},
_applyGeolocation: function()
{
if (this._geolocationEnabled) {
this._geolocationSetting.set(this._geolocation.toSetting());
this._geolocation.apply();
} else {
this._geolocation.clear();
}
},
/**
* @param {!WebInspector.Geolocation} geolocation
* @return {!Element}
*/
_createGeolocationOverrideElement: function(geolocation)
{
var fieldsetElement = createElement("fieldset");
fieldsetElement.id = "geolocation-override-section";
var tableElement = fieldsetElement.createChild("table");
var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement = rowElement.createChild("td");
cellElement.createTextChild(WebInspector.UIString("Lat = "));
this._latitudeElement = cellElement.createChild("input");
this._latitudeElement.type = "text";
WebInspector.bindInput(this._latitudeElement, this._applyGeolocationUserInput.bind(this), WebInspector.Geolocation.latitudeValidator, true)(String(geolocation.latitude));
cellElement.createTextChild(" , ");
cellElement.createTextChild(WebInspector.UIString("Lon = "));
this._longitudeElement = cellElement.createChild("input");
this._longitudeElement.type = "text";
WebInspector.bindInput(this._longitudeElement, this._applyGeolocationUserInput.bind(this), WebInspector.Geolocation.longitudeValidator, true)(String(geolocation.longitude));
rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.colSpan = 2;
var geolocationErrorLabelElement = createCheckboxLabel(WebInspector.UIString("Emulate position unavailable"), !geolocation || !!geolocation.error);
var geolocationErrorCheckboxElement = geolocationErrorLabelElement.checkboxElement;
geolocationErrorCheckboxElement.id = "geolocation-error";
geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
this._geolocationErrorElement = geolocationErrorCheckboxElement;
cellElement.appendChild(geolocationErrorLabelElement);
return fieldsetElement;
},
_appendDeviceOrientationOverrideControl: function()
{
var checkboxLabel = createCheckboxLabel(WebInspector.UIString("Emulate device orientation"));
this._overrideDeviceOrientationCheckbox = checkboxLabel.checkboxElement;
this._overrideDeviceOrientationCheckbox.addEventListener("click", this._deviceOrientationOverrideCheckboxClicked.bind(this));
this.contentElement.appendChild(checkboxLabel);
this._deviceOrientationFieldset = this._createDeviceOrientationOverrideElement(this._deviceOrientation);
this._deviceOrientationFieldset.disabled = true;
this.contentElement.appendChild(this._deviceOrientationFieldset);
},
_deviceOrientationOverrideCheckboxClicked: function()
{
var enabled = this._overrideDeviceOrientationCheckbox.checked;
this._deviceOrientationEnabled = enabled;
this._applyDeviceOrientation();
if (enabled && !this._alphaElement.value)
this._alphaElement.focus();
this._deviceOrientationFieldset.disabled = !enabled;
},
_applyDeviceOrientation: function()
{
if (this._deviceOrientationEnabled) {
this._deviceOrientationSetting.set(this._deviceOrientation.toSetting());
this._deviceOrientation.apply();
} else {
this._deviceOrientation.clear();
}
},
_applyDeviceOrientationUserInput: function()
{
this._setDeviceOrientation(WebInspector.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput);
},
_resetDeviceOrientation: function()
{
this._setDeviceOrientation(new WebInspector.DeviceOrientation(0, 0, 0), WebInspector.SensorsView.DeviceOrientationModificationSource.ResetButton);
},
/**
* @param {?WebInspector.DeviceOrientation} deviceOrientation
* @param {!WebInspector.SensorsView.DeviceOrientationModificationSource} modificationSource
*/
_setDeviceOrientation: function(deviceOrientation, modificationSource)
{
if (!deviceOrientation)
return;
if (modificationSource != WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput) {
this._alphaSetter(deviceOrientation.alpha);
this._betaSetter(deviceOrientation.beta);
this._gammaSetter(deviceOrientation.gamma);
}
if (modificationSource != WebInspector.SensorsView.DeviceOrientationModificationSource.UserDrag)
this._setBoxOrientation(deviceOrientation);
this._deviceOrientation = deviceOrientation;
this._applyDeviceOrientation();
},
/**
* @param {!Element} parentElement
* @param {!Element} input
* @param {string} label
* @return {function(string)}
*/
_createAxisInput: function(parentElement, input, label)
{
var div = parentElement.createChild("div", "accelerometer-axis-input-container");
div.createTextChild(label);
div.appendChild(input);
input.type = "text";
return WebInspector.bindInput(input, this._applyDeviceOrientationUserInput.bind(this), WebInspector.DeviceOrientation.validator, true);
},
/**
* @param {!WebInspector.DeviceOrientation} deviceOrientation
*/
_createDeviceOrientationOverrideElement: function(deviceOrientation)
{
var fieldsetElement = createElement("fieldset");
fieldsetElement.classList.add("device-orientation-override-section");
var tableElement = fieldsetElement.createChild("table");
var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td", "accelerometer-inputs-cell");
this._alphaElement = createElement("input");
this._alphaSetter = this._createAxisInput(cellElement, this._alphaElement, "\u03B1: ");
this._alphaSetter(String(deviceOrientation.alpha));
this._betaElement = createElement("input");
this._betaSetter = this._createAxisInput(cellElement, this._betaElement, "\u03B2: ");
this._betaSetter(String(deviceOrientation.beta));
this._gammaElement = createElement("input");
this._gammaSetter = this._createAxisInput(cellElement, this._gammaElement, "\u03B3: ");
this._gammaSetter(String(deviceOrientation.gamma));
cellElement.appendChild(createTextButton(WebInspector.UIString("Reset"), this._resetDeviceOrientation.bind(this), "accelerometer-reset-button"));
this._stageElement = rowElement.createChild("td","accelerometer-stage");
this._boxElement = this._stageElement.createChild("section", "accelerometer-box");
this._boxElement.createChild("section", "front");
this._boxElement.createChild("section", "top");
this._boxElement.createChild("section", "back");
this._boxElement.createChild("section", "left");
this._boxElement.createChild("section", "right");
this._boxElement.createChild("section", "bottom");
WebInspector.installDragHandle(this._stageElement, this._onBoxDragStart.bind(this), this._onBoxDrag.bind(this), this._onBoxDragEnd.bind(this), "move");
this._setBoxOrientation(deviceOrientation);
return fieldsetElement;
},
/**
* @param {!WebInspector.DeviceOrientation} deviceOrientation
*/
_setBoxOrientation: function(deviceOrientation)
{
var matrix = new WebKitCSSMatrix();
this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
this._boxElement.style.webkitTransform = this._boxMatrix.toString();
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_onBoxDrag: function(event)
{
var mouseMoveVector = this._calculateRadiusVector(event.x, event.y);
if (!mouseMoveVector)
return true;
event.consume(true);
var axis = WebInspector.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
axis.normalize();
var angle = WebInspector.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
var matrix = new WebKitCSSMatrix();
var rotationMatrix = matrix.rotateAxisAngle(axis.x, axis.y, axis.z, angle);
this._currentMatrix = rotationMatrix.multiply(this._boxMatrix);
this._boxElement.style.webkitTransform = this._currentMatrix;
var eulerAngles = WebInspector.Geometry.EulerAngles.fromRotationMatrix(this._currentMatrix);
var newOrientation = new WebInspector.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
this._setDeviceOrientation(newOrientation, WebInspector.SensorsView.DeviceOrientationModificationSource.UserDrag);
return false;
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_onBoxDragStart: function(event)
{
if (!this._overrideDeviceOrientationCheckbox.checked)
return false;
this._mouseDownVector = this._calculateRadiusVector(event.x, event.y);
if (!this._mouseDownVector)
return false;
event.consume(true);
return true;
},
_onBoxDragEnd: function()
{
this._boxMatrix = this._currentMatrix;
},
/**
* @param {number} x
* @param {number} y
* @return {?WebInspector.Geometry.Vector}
*/
_calculateRadiusVector: function(x, y)
{
var rect = this._stageElement.getBoundingClientRect();
var radius = Math.max(rect.width, rect.height) / 2;
var sphereX = (x - rect.left - rect.width / 2) / radius;
var sphereY = (y - rect.top - rect.height / 2) / radius;
var sqrSum = sphereX * sphereX + sphereY * sphereY;
if (sqrSum > 0.5)
return new WebInspector.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
return new WebInspector.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
},
_appendTouchControl: function()
{
var label = this.contentElement.createChild("label", "touch-label");
label.createChild("span", "").textContent = WebInspector.UIString("Touch");
var select = label.createChild("select", "chrome-select");
select.appendChild(new Option(WebInspector.UIString("Device-based"), "auto"));
select.appendChild(new Option(WebInspector.UIString("Force enabled"), "enabled"));
select.addEventListener("change", applyTouch, false);
function applyTouch()
{
WebInspector.MultitargetTouchModel.instance().setCustomTouchEnabled(select.value === "enabled");
}
},
__proto__ : WebInspector.VBox.prototype
}
/** @enum {string} */
WebInspector.SensorsView.DeviceOrientationModificationSource = {
UserInput: "userInput",
UserDrag: "userDrag",
ResetButton: "resetButton"
}
/**
* @return {!WebInspector.SensorsView}
*/
WebInspector.SensorsView.instance = function()
{
if (!WebInspector.SensorsView._instanceObject)
WebInspector.SensorsView._instanceObject = new WebInspector.SensorsView();
return WebInspector.SensorsView._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.SensorsView.ShowActionDelegate = function()
{
}
WebInspector.SensorsView.ShowActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
WebInspector.inspectorView.showViewInDrawer("sensors");
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.MultitargetTouchModel = function()
{
this._touchEnabled = false;
this._touchMobile = false;
this._customTouchEnabled = false;
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.MultitargetTouchModel._symbol = Symbol("MultitargetTouchModel.symbol");
WebInspector.MultitargetTouchModel.prototype = {
/**
* @param {boolean} enabled
* @param {boolean} mobile
*/
setTouchEnabled: function(enabled, mobile)
{
this._touchEnabled = enabled;
this._touchMobile = mobile;
this._updateAllTargets();
},
/**
* @param {boolean} enabled
*/
setCustomTouchEnabled: function(enabled)
{
this._customTouchEnabled = enabled;
this._updateAllTargets();
},
_updateAllTargets: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
this._applyToTarget(target);
},
/**
* @param {!WebInspector.Target} target
*/
_applyToTarget: function(target)
{
var current = {enabled: this._touchEnabled, configuration : this._touchMobile ? "mobile" : "desktop"};
if (this._customTouchEnabled)
current = {enabled: true, configuration: "mobile"};
var domModel = WebInspector.DOMModel.fromTarget(target);
var inspectModeEnabled = domModel ? domModel.inspectModeEnabled() : false;
if (inspectModeEnabled)
current = {enabled: false, configuration: "mobile"};
/**
* @suppressGlobalPropertiesCheck
*/
const injectedFunction = function() {
const touchEvents = ["ontouchstart", "ontouchend", "ontouchmove", "ontouchcancel"];
var recepients = [window.__proto__, document.__proto__];
for (var i = 0; i < touchEvents.length; ++i) {
for (var j = 0; j < recepients.length; ++j) {
if (!(touchEvents[i] in recepients[j]))
Object.defineProperty(recepients[j], touchEvents[i], { value: null, writable: true, configurable: true, enumerable: true });
}
}
};
var symbol = WebInspector.MultitargetTouchModel._symbol;
var previous = target[symbol] || {enabled: false, configuration: "mobile", scriptId: ""};
if (previous.enabled === current.enabled && (!current.enabled || previous.configuration === current.configuration))
return;
if (previous.scriptId) {
target.pageAgent().removeScriptToEvaluateOnLoad(previous.scriptId);
target[symbol].scriptId = "";
}
target[symbol] = current;
target[symbol].scriptId = "";
if (current.enabled)
target.pageAgent().addScriptToEvaluateOnLoad("(" + injectedFunction.toString() + ")()", scriptAddedCallback);
/**
* @param {?Protocol.Error} error
* @param {string} scriptId
*/
function scriptAddedCallback(error, scriptId)
{
(target[symbol] || {}).scriptId = error ? "" : scriptId;
}
target.emulationAgent().setTouchEmulationEnabled(current.enabled, current.configuration);
},
/**
* @param {!WebInspector.Event} event
*/
_inspectModeToggled: function(event)
{
var domModel = /** @type {!WebInspector.DOMModel} */ (event.target);
this._applyToTarget(domModel.target());
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (domModel)
domModel.addEventListener(WebInspector.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
this._applyToTarget(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var domModel = WebInspector.DOMModel.fromTarget(target);
if (domModel)
domModel.removeEventListener(WebInspector.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
}
}
/** @type {?WebInspector.MultitargetTouchModel} */
WebInspector.MultitargetTouchModel._instance = null;
/**
* @return {!WebInspector.MultitargetTouchModel}
*/
WebInspector.MultitargetTouchModel.instance = function()
{
if (!WebInspector.MultitargetTouchModel._instance)
WebInspector.MultitargetTouchModel._instance = new WebInspector.MultitargetTouchModel();
return /** @type {!WebInspector.MultitargetTouchModel} */ (WebInspector.MultitargetTouchModel._instance);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AcornTokenizer.js | 2.44% | (1 / 41) | 0% | (0 / 28) | 0% | (0 / 13) | 2.44% | (1 / 41) | |
| ESTreeWalker.js | 3.45% | (1 / 29) | 0% | (0 / 8) | 0% | (0 / 4) | 3.45% | (1 / 29) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 2 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {string} content
*/
WebInspector.AcornTokenizer = function(content)
{
this._content = content;
this._comments = [];
this._tokenizer = acorn.tokenizer(this._content, { ecmaVersion: 6, onComment: this._comments });
this._lineEndings = this._content.computeLineEndings();
this._lineNumber = 0;
this._tokenLineStart = 0;
this._tokenLineEnd = 0;
this._nextTokenInternal();
}
/**
* @param {!Acorn.TokenOrComment} token
* @param {string=} values
* @return {boolean}
*/
WebInspector.AcornTokenizer.punctuator = function(token, values)
{
return token.type !== acorn.tokTypes.num &&
token.type !== acorn.tokTypes.regexp &&
token.type !== acorn.tokTypes.string &&
token.type !== acorn.tokTypes.name &&
!token.type.keyword &&
(!values || (token.type.label.length === 1 && values.indexOf(token.type.label) !== -1));
}
/**
* @param {!Acorn.TokenOrComment} token
* @param {string=} keyword
* @return {boolean}
*/
WebInspector.AcornTokenizer.keyword = function(token, keyword)
{
return !!token.type.keyword && token.type !== acorn.tokTypes._true && token.type !== acorn.tokTypes._false &&
(!keyword || token.type.keyword === keyword);
}
/**
* @param {!Acorn.TokenOrComment} token
* @param {string=} identifier
* @return {boolean}
*/
WebInspector.AcornTokenizer.identifier = function(token, identifier)
{
return token.type === acorn.tokTypes.name && (!identifier || token.value === identifier);
}
/**
* @param {!Acorn.TokenOrComment} token
* @return {boolean}
*/
WebInspector.AcornTokenizer.lineComment = function(token)
{
return token.type === "Line";
}
/**
* @param {!Acorn.TokenOrComment} token
* @return {boolean}
*/
WebInspector.AcornTokenizer.blockComment = function(token)
{
return token.type === "Block";
}
WebInspector.AcornTokenizer.prototype = {
/**
* @return {!Acorn.TokenOrComment}
*/
_nextTokenInternal: function()
{
if (this._comments.length)
return this._comments.shift();
var token = this._bufferedToken;
this._bufferedToken = this._tokenizer.getToken();
return token;
},
/**
* @param {number} position
* @return {number}
*/
_rollLineNumberToPosition: function(position)
{
while (this._lineNumber + 1 < this._lineEndings.length && position > this._lineEndings[this._lineNumber])
++this._lineNumber;
return this._lineNumber;
},
/**
* @return {?Acorn.TokenOrComment}
*/
nextToken: function()
{
var token = this._nextTokenInternal();
if (token.type === acorn.tokTypes.eof)
return null;
this._tokenLineStart = this._rollLineNumberToPosition(token.start);
this._tokenLineEnd = this._rollLineNumberToPosition(token.end);
this._tokenColumnStart = this._tokenLineStart > 0 ? token.start - this._lineEndings[this._tokenLineStart - 1] - 1 : token.start;
return token;
},
/**
* @return {?Acorn.TokenOrComment}
*/
peekToken: function()
{
if (this._comments.length)
return this._comments[0];
return this._bufferedToken.type !== acorn.tokTypes.eof ? this._bufferedToken : null;
},
/**
* @return {number}
*/
tokenLineStart: function()
{
return this._tokenLineStart;
},
/**
* @return {number}
*/
tokenLineEnd: function()
{
return this._tokenLineEnd;
},
/**
* @return {number}
*/
tokenColumnStart: function()
{
return this._tokenColumnStart;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 2 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {function(!ESTree.Node)} beforeVisit
* @param {function(!ESTree.Node)} afterVisit
*/
WebInspector.ESTreeWalker = function(beforeVisit, afterVisit)
{
this._beforeVisit = beforeVisit;
this._afterVisit = afterVisit;
}
WebInspector.ESTreeWalker.prototype = {
/**
* @param {!ESTree.Node} ast
*/
walk: function(ast)
{
this._innerWalk(ast, null);
},
/**
* @param {!ESTree.Node} node
* @param {?ESTree.Node} parent
*/
_innerWalk: function(node, parent)
{
if (!node)
return;
node.parent = parent;
this._beforeVisit.call(null, node);
var walkOrder = WebInspector.ESTreeWalker._walkOrder[node.type];
if (!walkOrder) {
console.error("Walk order not defined for " + node.type);
return;
}
if (node.type === "TemplateLiteral") {
var templateLiteral = /** @type {!ESTree.TemplateLiteralNode} */ (node);
var expressionsLength = templateLiteral.expressions.length;
for (var i = 0; i < expressionsLength; ++i) {
this._innerWalk(templateLiteral.quasis[i], templateLiteral);
this._innerWalk(templateLiteral.expressions[i], templateLiteral);
}
this._innerWalk(templateLiteral.quasis[expressionsLength], templateLiteral);
} else {
for (var i = 0; i < walkOrder.length; ++i) {
var entity = node[walkOrder[i]];
if (Array.isArray(entity))
this._walkArray(entity, node);
else
this._innerWalk(entity, node);
}
}
this._afterVisit.call(null, node);
},
/**
* @param {!Array.<!ESTree.Node>} nodeArray
* @param {?ESTree.Node} parentNode
*/
_walkArray: function(nodeArray, parentNode)
{
for (var i = 0; i < nodeArray.length; ++i)
this._innerWalk(nodeArray[i], parentNode);
},
}
/** @enum {!Array.<string>} */
WebInspector.ESTreeWalker._walkOrder = {
"ArrayExpression": ["elements"],
"ArrowFunctionExpression": ["params", "body"],
"AssignmentExpression": ["left", "right"],
"BinaryExpression": ["left", "right"],
"BlockStatement": ["body"],
"BreakStatement": ["label"],
"CallExpression": ["callee", "arguments"],
"CatchClause": ["param", "body"],
"ClassBody": ["body"],
"ClassDeclaration": ["id", "superClass", "body"],
"ConditionalExpression": ["test", "consequent", "alternate"],
"ContinueStatement": ["label"],
"DebuggerStatement": [],
"DoWhileStatement": ["body", "test"],
"EmptyStatement": [],
"ExpressionStatement": ["expression"],
"ForInStatement": ["left", "right", "body"],
"ForOfStatement": ["left", "right", "body"],
"ForStatement": ["init", "test", "update", "body"],
"FunctionDeclaration": ["id", "params", "body"],
"FunctionExpression": ["id", "params", "body"],
"Identifier": [],
"IfStatement": ["test", "consequent", "alternate"],
"LabeledStatement": ["label", "body"],
"Literal": [],
"LogicalExpression": ["left", "right"],
"MemberExpression": ["object", "property"],
"MethodDefinition": ["key", "value"],
"NewExpression": ["callee", "arguments"],
"ObjectExpression": ["properties"],
"Program": ["body"],
"Property": ["key", "value"],
"ReturnStatement": ["argument"],
"SequenceExpression": ["expressions"],
"Super": [],
"SwitchCase": ["test", "consequent"],
"SwitchStatement": ["discriminant", "cases"],
"TaggedTemplateExpression": ["tag", "quasi"],
"TemplateElement": [],
"TemplateLiteral": ["quasis", "expressions"],
"ThisExpression": [],
"ThrowStatement": ["argument"],
"TryStatement": ["block", "handler", "finalizer"],
"UnaryExpression": ["argument"],
"UpdateExpression": ["argument"],
"VariableDeclaration": ["declarations"],
"VariableDeclarator": ["id", "init"],
"WhileStatement": ["test", "body"],
"WithStatement": ["object", "body"],
"YieldExpression": ["argument"]
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ExtensionAPI.js | 13.37% | (46 / 344) | 0% | (0 / 108) | 0% | (0 / 91) | 13.41% | (46 / 343) | |
| ExtensionAuditCategory.js | 14.29% | (1 / 7) | 100% | (0 / 0) | 0% | (0 / 6) | 14.29% | (1 / 7) | |
| ExtensionPanel.js | 1.25% | (1 / 80) | 0% | (0 / 22) | 0% | (0 / 23) | 1.25% | (1 / 80) | |
| ExtensionRegistryStub.js | 25% | (1 / 4) | 0% | (0 / 2) | 0% | (0 / 2) | 25% | (1 / 4) | |
| ExtensionServer.js | 3.76% | (17 / 452) | 0% | (0 / 196) | 0% | (0 / 86) | 3.76% | (17 / 452) | |
| ExtensionView.js | 3.57% | (1 / 28) | 0% | (0 / 6) | 0% | (0 / 7) | 3.57% | (1 / 28) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ function defineCommonExtensionSymbols(apiPrivate) { if (!apiPrivate.audits) apiPrivate.audits = {}; apiPrivate.audits.Severity = { Info: "info", Warning: "warning", Severe: "severe" }; if (!apiPrivate.panels) apiPrivate.panels = {}; apiPrivate.panels.SearchAction = { CancelSearch: "cancelSearch", PerformSearch: "performSearch", NextSearchResult: "nextSearchResult", PreviousSearchResult: "previousSearchResult" }; apiPrivate.Events = { AuditStarted: "audit-started-", ButtonClicked: "button-clicked-", PanelObjectSelected: "panel-objectSelected-", NetworkRequestFinished: "network-request-finished", OpenResource: "open-resource", PanelSearch: "panel-search-", ResourceAdded: "resource-added", ResourceContentCommitted: "resource-content-committed", ViewShown: "view-shown-", ViewHidden: "view-hidden-" }; apiPrivate.Commands = { AddAuditCategory: "addAuditCategory", AddAuditResult: "addAuditResult", AddRequestHeaders: "addRequestHeaders", ApplyStyleSheet: "applyStyleSheet", CreatePanel: "createPanel", CreateSidebarPane: "createSidebarPane", CreateToolbarButton: "createToolbarButton", EvaluateOnInspectedPage: "evaluateOnInspectedPage", ForwardKeyboardEvent: "_forwardKeyboardEvent", GetHAR: "getHAR", GetPageResources: "getPageResources", GetRequestContent: "getRequestContent", GetResourceContent: "getResourceContent", InspectedURLChanged: "inspectedURLChanged", OpenResource: "openResource", Reload: "Reload", Subscribe: "subscribe", SetOpenResourceHandler: "setOpenResourceHandler", SetResourceContent: "setResourceContent", SetSidebarContent: "setSidebarContent", SetSidebarHeight: "setSidebarHeight", SetSidebarPage: "setSidebarPage", ShowPanel: "showPanel", StopAuditCategoryRun: "stopAuditCategoryRun", Unsubscribe: "unsubscribe", UpdateAuditProgress: "updateAuditProgress", UpdateButton: "updateButton" }; } /** * @param {number} injectedScriptId * @return {!Object} * @suppressGlobalPropertiesCheck */ function injectedExtensionAPI(injectedScriptId) { var apiPrivate = {}; defineCommonExtensionSymbols(apiPrivate); var commands = apiPrivate.Commands; var events = apiPrivate.Events; var userAction = false; // Here and below, all constructors are private to API implementation. // For a public type Foo, if internal fields are present, these are on // a private FooImpl type, an instance of FooImpl is used in a closure // by Foo consutrctor to re-bind publicly exported members to an instance // of Foo. /** * @constructor */ function EventSinkImpl(type, customDispatch) { this._type = type; this._listeners = []; this._customDispatch = customDispatch; } EventSinkImpl.prototype = { addListener: function(callback) { if (typeof callback !== "function") throw "addListener: callback is not a function"; if (this._listeners.length === 0) extensionServer.sendRequest({ command: commands.Subscribe, type: this._type }); this._listeners.push(callback); extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this)); }, removeListener: function(callback) { var listeners = this._listeners; for (var i = 0; i < listeners.length; ++i) { if (listeners[i] === callback) { listeners.splice(i, 1); break; } } if (this._listeners.length === 0) extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type }); }, /** * @param {...} vararg */ _fire: function(vararg) { var listeners = this._listeners.slice(); for (var i = 0; i < listeners.length; ++i) listeners[i].apply(null, arguments); }, _dispatch: function(request) { if (this._customDispatch) this._customDispatch.call(this, request); else this._fire.apply(this, request.arguments); } } /** * @constructor */ function InspectorExtensionAPI() { this.audits = new Audits(); this.inspectedWindow = new InspectedWindow(); this.panels = new Panels(); this.network = new Network(); defineDeprecatedProperty(this, "webInspector", "resources", "network"); } /** * @constructor */ function Network() { /** * @this {EventSinkImpl} */ function dispatchRequestEvent(message) { var request = message.arguments[1]; request.__proto__ = new Request(message.arguments[0]); this._fire(request); } this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent); defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished"); this.onNavigated = new EventSink(events.InspectedURLChanged); } Network.prototype = { getHAR: function(callback) { function callbackWrapper(result) { var entries = (result && result.entries) || []; for (var i = 0; i < entries.length; ++i) { entries[i].__proto__ = new Request(entries[i]._requestId); delete entries[i]._requestId; } callback(result); } extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper); }, addRequestHeaders: function(headers) { extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname }); } } /** * @constructor */ function RequestImpl(id) { this._id = id; } RequestImpl.prototype = { getContent: function(callback) { function callbackWrapper(response) { callback(response.content, response.encoding); } extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper); } } /** * @constructor */ function Panels() { var panels = { elements: new ElementsPanel(), sources: new SourcesPanel(), }; function panelGetter(name) { return panels[name]; } for (var panel in panels) this.__defineGetter__(panel, panelGetter.bind(null, panel)); this.applyStyleSheet = function(styleSheet) { extensionServer.sendRequest({ command: commands.ApplyStyleSheet, styleSheet: styleSheet }); }; } Panels.prototype = { create: function(title, icon, page, callback) { var id = "extension-panel-" + extensionServer.nextObjectId(); var request = { command: commands.CreatePanel, id: id, title: title, icon: icon, page: page }; extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id))); }, setOpenResourceHandler: function(callback) { var hadHandler = extensionServer.hasHandler(events.OpenResource); function callbackWrapper(message) { // Allow the panel to show itself when handling the event. userAction = true; try { callback.call(null, new Resource(message.resource), message.lineNumber); } finally { userAction = false; } } if (!callback) extensionServer.unregisterHandler(events.OpenResource); else extensionServer.registerHandler(events.OpenResource, callbackWrapper); // Only send command if we either removed an existing handler or added handler and had none before. if (hadHandler === !callback) extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback }); }, openResource: function(url, lineNumber, callback) { extensionServer.sendRequest({ command: commands.OpenResource, "url": url, "lineNumber": lineNumber }, callback); }, get SearchAction() { return apiPrivate.panels.SearchAction; } } /** * @constructor */ function ExtensionViewImpl(id) { this._id = id; /** * @this {EventSinkImpl} */ function dispatchShowEvent(message) { var frameIndex = message.arguments[0]; if (typeof frameIndex === "number") this._fire(window.parent.frames[frameIndex]); else this._fire(); } if (id) { this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent); this.onHidden = new EventSink(events.ViewHidden + id); } } /** * @constructor * @extends {ExtensionViewImpl} * @param {string} hostPanelName */ function PanelWithSidebarImpl(hostPanelName) { ExtensionViewImpl.call(this, null); this._hostPanelName = hostPanelName; this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPanelName); } PanelWithSidebarImpl.prototype = { createSidebarPane: function(title, callback) { var id = "extension-sidebar-" + extensionServer.nextObjectId(); var request = { command: commands.CreateSidebarPane, panel: this._hostPanelName, id: id, title: title }; function callbackWrapper() { callback(new ExtensionSidebarPane(id)); } extensionServer.sendRequest(request, callback && callbackWrapper); }, __proto__: ExtensionViewImpl.prototype } function declareInterfaceClass(implConstructor) { return function() { var impl = { __proto__: implConstructor.prototype }; implConstructor.apply(impl, arguments); populateInterfaceClass(this, impl); }; } function defineDeprecatedProperty(object, className, oldName, newName) { var warningGiven = false; function getter() { if (!warningGiven) { console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead"); warningGiven = true; } return object[newName]; } object.__defineGetter__(oldName, getter); } function extractCallbackArgument(args) { var lastArgument = args[args.length - 1]; return typeof lastArgument === "function" ? lastArgument : undefined; } var AuditCategory = declareInterfaceClass(AuditCategoryImpl); var AuditResult = declareInterfaceClass(AuditResultImpl); var Button = declareInterfaceClass(ButtonImpl); var EventSink = declareInterfaceClass(EventSinkImpl); var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl); var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl); var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl); var Request = declareInterfaceClass(RequestImpl); var Resource = declareInterfaceClass(ResourceImpl); /** * @constructor * @extends {PanelWithSidebar} */ function ElementsPanel() { PanelWithSidebar.call(this, "elements"); } ElementsPanel.prototype = { __proto__: PanelWithSidebar.prototype } /** * @constructor * @extends {PanelWithSidebar} */ function SourcesPanel() { PanelWithSidebar.call(this, "sources"); } SourcesPanel.prototype = { __proto__: PanelWithSidebar.prototype } /** * @constructor * @extends {ExtensionViewImpl} */ function ExtensionPanelImpl(id) { ExtensionViewImpl.call(this, id); this.onSearch = new EventSink(events.PanelSearch + id); } ExtensionPanelImpl.prototype = { /** * @return {!Object} */ createStatusBarButton: function(iconPath, tooltipText, disabled) { var id = "button-" + extensionServer.nextObjectId(); var request = { command: commands.CreateToolbarButton, panel: this._id, id: id, icon: iconPath, tooltip: tooltipText, disabled: !!disabled }; extensionServer.sendRequest(request); return new Button(id); }, show: function() { if (!userAction) return; var request = { command: commands.ShowPanel, id: this._id }; extensionServer.sendRequest(request); }, __proto__: ExtensionViewImpl.prototype } /** * @constructor * @extends {ExtensionViewImpl} */ function ExtensionSidebarPaneImpl(id) { ExtensionViewImpl.call(this, id); } ExtensionSidebarPaneImpl.prototype = { setHeight: function(height) { extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height }); }, setExpression: function(expression, rootTitle, evaluateOptions) { var request = { command: commands.SetSidebarContent, id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true, }; if (typeof evaluateOptions === "object") request.evaluateOptions = evaluateOptions; extensionServer.sendRequest(request, extractCallbackArgument(arguments)); }, setObject: function(jsonObject, rootTitle, callback) { extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback); }, setPage: function(page) { extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page }); }, __proto__: ExtensionViewImpl.prototype } /** * @constructor */ function ButtonImpl(id) { this._id = id; this.onClicked = new EventSink(events.ButtonClicked + id); } ButtonImpl.prototype = { update: function(iconPath, tooltipText, disabled) { var request = { command: commands.UpdateButton, id: this._id, icon: iconPath, tooltip: tooltipText, disabled: !!disabled }; extensionServer.sendRequest(request); } }; /** * @constructor */ function Audits() { } Audits.prototype = { /** * @return {!AuditCategory} */ addCategory: function(displayName, resultCount) { var id = "extension-audit-category-" + extensionServer.nextObjectId(); if (typeof resultCount !== "undefined") console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead."); extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount }); return new AuditCategory(id); } } /** * @constructor */ function AuditCategoryImpl(id) { /** * @this {EventSinkImpl} */ function dispatchAuditEvent(request) { var auditResult = new AuditResult(request.arguments[0]); try { this._fire(auditResult); } catch (e) { console.error("Uncaught exception in extension audit event handler: " + e); auditResult.done(); } } this._id = id; this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent); } /** * @constructor */ function AuditResultImpl(id) { this._id = id; this.createURL = this._nodeFactory.bind(this, "url"); this.createSnippet = this._nodeFactory.bind(this, "snippet"); this.createText = this._nodeFactory.bind(this, "text"); this.createObject = this._nodeFactory.bind(this, "object"); this.createNode = this._nodeFactory.bind(this, "node"); } AuditResultImpl.prototype = { addResult: function(displayName, description, severity, details) { // shorthand for specifying details directly in addResult(). if (details && !(details instanceof AuditResultNode)) details = new AuditResultNode(Array.isArray(details) ? details : [details]); var request = { command: commands.AddAuditResult, resultId: this._id, displayName: displayName, description: description, severity: severity, details: details }; extensionServer.sendRequest(request); }, /** * @return {!Object} */ createResult: function() { return new AuditResultNode(Array.prototype.slice.call(arguments)); }, updateProgress: function(worked, totalWork) { extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork }); }, done: function() { extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id }); }, /** * @type {!Object.<string, string>} */ get Severity() { return apiPrivate.audits.Severity; }, /** * @return {!{type: string, arguments: !Array.<string|number>}} */ createResourceLink: function(url, lineNumber) { return { type: "resourceLink", arguments: [url, lineNumber && lineNumber - 1] }; }, /** * @return {!{type: string, arguments: !Array.<string|number>}} */ _nodeFactory: function(type) { return { type: type, arguments: Array.prototype.slice.call(arguments, 1) }; } } /** * @constructor */ function AuditResultNode(contents) { this.contents = contents; this.children = []; this.expanded = false; } AuditResultNode.prototype = { /** * @return {!Object} */ addChild: function() { var node = new AuditResultNode(Array.prototype.slice.call(arguments)); this.children.push(node); return node; } }; /** * @constructor */ function InspectedWindow() { /** * @this {EventSinkImpl} */ function dispatchResourceEvent(message) { this._fire(new Resource(message.arguments[0])); } /** * @this {EventSinkImpl} */ function dispatchResourceContentEvent(message) { this._fire(new Resource(message.arguments[0]), message.arguments[1]); } this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent); this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent); } InspectedWindow.prototype = { reload: function(optionsOrUserAgent) { var options = null; if (typeof optionsOrUserAgent === "object") { options = optionsOrUserAgent; } else if (typeof optionsOrUserAgent === "string") { options = { userAgent: optionsOrUserAgent }; console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " + "Use inspectedWindow.reload({ userAgent: value}) instead."); } extensionServer.sendRequest({ command: commands.Reload, options: options }); }, /** * @return {?Object} */ eval: function(expression, evaluateOptions) { var callback = extractCallbackArgument(arguments); function callbackWrapper(result) { if (result.isError || result.isException) callback(undefined, result); else callback(result.value); } var request = { command: commands.EvaluateOnInspectedPage, expression: expression }; if (typeof evaluateOptions === "object") request.evaluateOptions = evaluateOptions; extensionServer.sendRequest(request, callback && callbackWrapper); return null; }, getResources: function(callback) { function wrapResource(resourceData) { return new Resource(resourceData); } function callbackWrapper(resources) { callback(resources.map(wrapResource)); } extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper); } } /** * @constructor */ function ResourceImpl(resourceData) { this._url = resourceData.url; this._type = resourceData.type; } ResourceImpl.prototype = { get url() { return this._url; }, get type() { return this._type; }, getContent: function(callback) { function callbackWrapper(response) { callback(response.content, response.encoding); } extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper); }, setContent: function(content, commit, callback) { extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback); } } var keyboardEventRequestQueue = []; var forwardTimer = null; function forwardKeyboardEvent(event) { const Esc = "U+001B"; // We only care about global hotkeys, not about random text if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.keyIdentifier) && event.keyIdentifier !== Esc) return; var requestPayload = { eventType: event.type, ctrlKey: event.ctrlKey, altKey: event.altKey, metaKey: event.metaKey, keyIdentifier: event.keyIdentifier, location: event.location, keyCode: event.keyCode }; keyboardEventRequestQueue.push(requestPayload); if (!forwardTimer) forwardTimer = setTimeout(forwardEventQueue, 0); } function forwardEventQueue() { forwardTimer = null; var request = { command: commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue }; extensionServer.sendRequest(request); keyboardEventRequestQueue = []; } document.addEventListener("keydown", forwardKeyboardEvent, false); document.addEventListener("keypress", forwardKeyboardEvent, false); /** * @constructor */ function ExtensionServerClient() { this._callbacks = {}; this._handlers = {}; this._lastRequestId = 0; this._lastObjectId = 0; this.registerHandler("callback", this._onCallback.bind(this)); var channel = new MessageChannel(); this._port = channel.port1; this._port.addEventListener("message", this._onMessage.bind(this), false); this._port.start(); window.parent.postMessage("registerExtension", [ channel.port2 ], "*"); } ExtensionServerClient.prototype = { /** * @param {!Object} message * @param {function()=} callback */ sendRequest: function(message, callback) { if (typeof callback === "function") message.requestId = this._registerCallback(callback); this._port.postMessage(message); }, /** * @return {boolean} */ hasHandler: function(command) { return !!this._handlers[command]; }, registerHandler: function(command, handler) { this._handlers[command] = handler; }, unregisterHandler: function(command) { delete this._handlers[command]; }, /** * @return {string} */ nextObjectId: function() { return injectedScriptId.toString() + "_" + ++this._lastObjectId; }, _registerCallback: function(callback) { var id = ++this._lastRequestId; this._callbacks[id] = callback; return id; }, _onCallback: function(request) { if (request.requestId in this._callbacks) { var callback = this._callbacks[request.requestId]; delete this._callbacks[request.requestId]; callback(request.result); } }, _onMessage: function(event) { var request = event.data; var handler = this._handlers[request.command]; if (handler) handler.call(this, request); } } function populateInterfaceClass(interfaze, implementation) { for (var member in implementation) { if (member.charAt(0) === "_") continue; var descriptor = null; // Traverse prototype chain until we find the owner. for (var owner = implementation; owner && !descriptor; owner = owner.__proto__) descriptor = Object.getOwnPropertyDescriptor(owner, member); if (!descriptor) continue; if (typeof descriptor.value === "function") interfaze[member] = descriptor.value.bind(implementation); else if (typeof descriptor.get === "function") interfaze.__defineGetter__(member, descriptor.get.bind(implementation)); else Object.defineProperty(interfaze, member, descriptor); } } // extensionServer is a closure variable defined by the glue below -- make sure we fail if it's not there. if (!extensionServer) extensionServer = new ExtensionServerClient(); return new InspectorExtensionAPI(); } /** * @suppress {checkVars, checkTypes} */ function platformExtensionAPI(coreAPI) { function getTabId() { return tabId; } var chrome = window.chrome || {}; // Override chrome.devtools as a workaround for a error-throwing getter being exposed // in extension pages loaded into a non-extension process (only happens for remote client // extensions) var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools"); if (!devtools_descriptor || devtools_descriptor.get) Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true }); // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow. chrome.devtools.inspectedWindow = {}; chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId); chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow; chrome.devtools.network = coreAPI.network; chrome.devtools.panels = coreAPI.panels; // default to expose experimental APIs for now. if (extensionInfo.exposeExperimentalAPIs !== false) { chrome.experimental = chrome.experimental || {}; chrome.experimental.devtools = chrome.experimental.devtools || {}; var properties = Object.getOwnPropertyNames(coreAPI); for (var i = 0; i < properties.length; ++i) { var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]); Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor); } chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow; } if (extensionInfo.exposeWebInspectorNamespace) window.webInspector = coreAPI; } /** * @param {!ExtensionDescriptor} extensionInfo * @param {string} inspectedTabId * @return {string} */ function buildPlatformExtensionAPI(extensionInfo, inspectedTabId) { return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" + "var tabId = " + inspectedTabId + ";" + platformExtensionAPI.toString(); } /** * @param {!ExtensionDescriptor} extensionInfo * @param {string} inspectedTabId * @return {string} */ function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId) { return "(function(injectedScriptId){ " + "var extensionServer;" + defineCommonExtensionSymbols.toString() + ";" + injectedExtensionAPI.toString() + ";" + buildPlatformExtensionAPI(extensionInfo, inspectedTabId) + ";" + "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" + "return {};" + "})"; } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} extensionOrigin
* @param {string} id
* @param {string} displayName
* @param {number=} ruleCount
*/
WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
{
this.extensionOrigin = extensionOrigin;
this.id = id;
this.displayName = displayName;
this.ruleCount = ruleCount;
}
/**
* @interface
*/
WebInspector.ExtensionAuditCategoryResults = function()
{
}
WebInspector.ExtensionAuditCategoryResults.prototype = {
/**
* @return {string}
*/
id: function() { },
/**
* @param {string} displayName
* @param {string} description
* @param {string} severity
* @param {!Object} details
*/
addResult: function(displayName, description, severity, details) { },
/**
* @param {number} progress
*/
updateProgress: function(progress) { },
done: function() { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.Searchable}
* @extends {WebInspector.Panel}
* @param {!WebInspector.ExtensionServer} server
* @param {string} panelName
* @param {string} id
* @param {string} pageURL
*/
WebInspector.ExtensionPanel = function(server, panelName, id, pageURL)
{
WebInspector.Panel.call(this, panelName);
this._server = server;
this._id = id;
this.setHideOnDetach();
this._panelToolbar = new WebInspector.Toolbar("hidden", this.element);
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.show(this.element);
var extensionView = new WebInspector.ExtensionView(server, this._id, pageURL, "extension");
extensionView.show(this._searchableView.element);
this.setDefaultFocusedElement(extensionView.defaultFocusedElement());
}
WebInspector.ExtensionPanel.prototype = {
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return WebInspector.Widget.prototype.defaultFocusedElement.call(this);
},
/**
* @param {!WebInspector.ToolbarItem} item
*/
addToolbarItem: function(item)
{
this._panelToolbar.element.classList.remove("hidden");
this._panelToolbar.appendToolbarItem(item);
},
/**
* @override
*/
searchCanceled: function()
{
this._server.notifySearchAction(this._id, WebInspector.extensionAPI.panels.SearchAction.CancelSearch);
this._searchableView.updateSearchMatchesCount(0);
},
/**
* @override
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var query = searchConfig.query;
this._server.notifySearchAction(this._id, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
this._server.notifySearchAction(this._id, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
this._server.notifySearchAction(this._id, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
__proto__: WebInspector.Panel.prototype
}
/**
* @constructor
* @param {!WebInspector.ExtensionServer} server
* @param {string} id
* @param {string} iconURL
* @param {string=} tooltip
* @param {boolean=} disabled
*/
WebInspector.ExtensionButton = function(server, id, iconURL, tooltip, disabled)
{
this._id = id;
this._toolbarButton = new WebInspector.ToolbarButton("", "");
this._toolbarButton.addEventListener("click", server.notifyButtonClicked.bind(server, this._id));
this.update(iconURL, tooltip, disabled);
}
WebInspector.ExtensionButton.prototype = {
/**
* @param {string} iconURL
* @param {string=} tooltip
* @param {boolean=} disabled
*/
update: function(iconURL, tooltip, disabled)
{
if (typeof iconURL === "string")
this._toolbarButton.setBackgroundImage(iconURL);
if (typeof tooltip === "string")
this._toolbarButton.setTitle(tooltip);
if (typeof disabled === "boolean")
this._toolbarButton.setEnabled(!disabled);
},
/**
* @return {!WebInspector.ToolbarButton}
*/
toolbarButton: function()
{
return this._toolbarButton;
}
}
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {!WebInspector.ExtensionServer} server
* @param {string} panelName
* @param {string} title
* @param {string} id
*/
WebInspector.ExtensionSidebarPane = function(server, panelName, title, id)
{
WebInspector.SidebarPane.call(this, title);
this._panelName = panelName;
this._server = server;
this._id = id;
}
WebInspector.ExtensionSidebarPane.prototype = {
/**
* @return {string}
*/
id: function()
{
return this._id;
},
/**
* @return {string}
*/
panelName: function()
{
return this._panelName;
},
/**
* @param {!Object} object
* @param {string} title
* @param {function(?string=)} callback
*/
setObject: function(object, title, callback)
{
this._createObjectPropertiesView();
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback);
},
/**
* @param {string} expression
* @param {string} title
* @param {!Object} evaluateOptions
* @param {string} securityOrigin
* @param {function(?string=)} callback
*/
setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
{
this._createObjectPropertiesView();
this._server.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
},
/**
* @param {string} url
*/
setPage: function(url)
{
if (this._objectPropertiesView) {
this._objectPropertiesView.detach();
delete this._objectPropertiesView;
}
if (this._extensionView)
this._extensionView.detach(true);
this._extensionView = new WebInspector.ExtensionView(this._server, this._id, url, "extension fill");
this._extensionView.show(this.element);
if (!this.element.style.height)
this.setHeight("150px");
},
/**
* @param {string} height
*/
setHeight: function(height)
{
this.element.style.height = height;
},
/**
* @param {string} title
* @param {function(?string=)} callback
* @param {?Protocol.Error} error
* @param {?WebInspector.RemoteObject} result
* @param {boolean=} wasThrown
*/
_onEvaluate: function(title, callback, error, result, wasThrown)
{
if (error)
callback(error.toString());
else
this._setObject(/** @type {!WebInspector.RemoteObject} */ (result), title, callback);
},
_createObjectPropertiesView: function()
{
if (this._objectPropertiesView)
return;
if (this._extensionView) {
this._extensionView.detach(true);
delete this._extensionView;
}
this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._server, this._id);
this._objectPropertiesView.show(this.element);
},
/**
* @param {!WebInspector.RemoteObject} object
* @param {string} title
* @param {function(?string=)} callback
*/
_setObject: function(object, title, callback)
{
// This may only happen if setPage() was called while we were evaluating the expression.
if (!this._objectPropertiesView) {
callback("operation cancelled");
return;
}
this._objectPropertiesView.element.removeChildren();
var section = new WebInspector.ObjectPropertiesSection(object, title);
if (!title)
section.titleLessMode();
section.expand();
section.editable = false;
this._objectPropertiesView.element.appendChild(section.element);
callback();
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 2 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
if (!window.InspectorExtensionRegistry) {
/**
* @constructor
*/
WebInspector.InspectorExtensionRegistryStub = function()
{
}
WebInspector.InspectorExtensionRegistryStub.prototype = {
getExtensionsAsync: function()
{
}
}
var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @suppressGlobalPropertiesCheck
*/
WebInspector.ExtensionServer = function()
{
this._clientObjects = {};
this._handlers = {};
this._subscribers = {};
this._subscriptionStartHandlers = {};
this._subscriptionStopHandlers = {};
this._extraHeaders = {};
this._requests = {};
this._lastRequestId = 0;
this._registeredExtensions = {};
this._status = new WebInspector.ExtensionStatus();
/** @type {!Array.<!WebInspector.ExtensionSidebarPane>} */
this._sidebarPanes = [];
/** @type {!Array.<!WebInspector.ExtensionAuditCategory>} */
this._auditCategories = [];
var commands = WebInspector.extensionAPI.Commands;
this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this));
this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this));
this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
this._registerHandler(commands.ApplyStyleSheet, this._onApplyStyleSheet.bind(this));
this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
this._registerHandler(commands.CreateToolbarButton, this._onCreateToolbarButton.bind(this));
this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
this._registerHandler(commands.ForwardKeyboardEvent, this._onForwardKeyboardEvent.bind(this));
this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
this._registerHandler(commands.Reload, this._onReload.bind(this));
this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this));
this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
this._registerHandler(commands.OpenResource, this._onOpenResource.bind(this));
this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));
window.addEventListener("message", this._onWindowMessage.bind(this), false); // Only for main window.
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.AddExtensions, this._addExtensions, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this);
this._initExtensions();
}
WebInspector.ExtensionServer.Events = {
SidebarPaneAdded: "SidebarPaneAdded",
AuditCategoryAdded: "AuditCategoryAdded"
}
WebInspector.ExtensionServer.prototype = {
initializeExtensions: function()
{
this._initializeCommandIssued = true;
if (this._pendingExtensionInfos) {
this._pendingExtensionInfos.forEach(this._addExtension, this);
delete this._pendingExtensionInfos;
}
},
/**
* @return {boolean}
*/
hasExtensions: function()
{
return !!Object.keys(this._registeredExtensions).length;
},
/**
* @param {string} panelId
* @param {string} action
* @param {string=} searchString
*/
notifySearchAction: function(panelId, action, searchString)
{
this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
},
/**
* @param {string} identifier
* @param {number=} frameIndex
*/
notifyViewShown: function(identifier, frameIndex)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
},
/**
* @param {string} identifier
*/
notifyViewHidden: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
},
/**
* @param {string} identifier
*/
notifyButtonClicked: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
},
_inspectedURLChanged: function(event)
{
this._requests = {};
var url = event.data;
this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
},
/**
* @param {string} categoryId
* @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
*/
startAuditRun: function(categoryId, auditResults)
{
this._clientObjects[auditResults.id()] = auditResults;
this._postNotification("audit-started-" + categoryId, auditResults.id());
},
/**
* @param {!WebInspector.ExtensionAuditCategoryResults} auditResults
*/
stopAuditRun: function(auditResults)
{
delete this._clientObjects[auditResults.id()];
},
/**
* @param {string} type
* @return {boolean}
*/
hasSubscribers: function(type)
{
return !!this._subscribers[type];
},
/**
* @param {string} type
* @param {...*} vararg
*/
_postNotification: function(type, vararg)
{
var subscribers = this._subscribers[type];
if (!subscribers)
return;
var message = {
command: "notify-" + type,
arguments: Array.prototype.slice.call(arguments, 1)
};
for (var i = 0; i < subscribers.length; ++i)
subscribers[i].postMessage(message);
},
_onSubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (subscribers)
subscribers.push(port);
else {
this._subscribers[message.type] = [ port ];
if (this._subscriptionStartHandlers[message.type])
this._subscriptionStartHandlers[message.type]();
}
},
_onUnsubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (!subscribers)
return;
subscribers.remove(port);
if (!subscribers.length) {
delete this._subscribers[message.type];
if (this._subscriptionStopHandlers[message.type])
this._subscriptionStopHandlers[message.type]();
}
},
_onAddRequestHeaders: function(message)
{
var id = message.extensionId;
if (typeof id !== "string")
return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
var extensionHeaders = this._extraHeaders[id];
if (!extensionHeaders) {
extensionHeaders = {};
this._extraHeaders[id] = extensionHeaders;
}
for (var name in message.headers)
extensionHeaders[name] = message.headers[name];
var allHeaders = /** @type {!NetworkAgent.Headers} */ ({});
for (var extension in this._extraHeaders) {
var headers = this._extraHeaders[extension];
for (name in headers) {
if (typeof headers[name] === "string")
allHeaders[name] = headers[name];
}
}
WebInspector.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);
},
/**
* @param {*} message
* @suppressGlobalPropertiesCheck
*/
_onApplyStyleSheet: function(message)
{
if (!Runtime.experiments.isEnabled("applyCustomStylesheet"))
return;
var styleSheet = createElement("style");
styleSheet.textContent = message.styleSheet;
document.head.appendChild(styleSheet);
},
_onCreatePanel: function(message, port)
{
var id = message.id;
// The ids are generated on the client API side and must be unique, so the check below
// shouldn't be hit unless someone is bypassing the API.
if (id in this._clientObjects || WebInspector.inspectorView.hasPanel(id))
return this._status.E_EXISTS(id);
var page = this._expandResourcePath(port._extensionOrigin, message.page);
var persistentId = port._extensionOrigin + message.title;
persistentId = persistentId.replace(/\s/g, "");
var panelDescriptor = new WebInspector.ExtensionServerPanelDescriptor(persistentId, message.title, new WebInspector.ExtensionPanel(this, persistentId, id, page));
this._clientObjects[id] = panelDescriptor;
WebInspector.inspectorView.addPanel(panelDescriptor);
return this._status.OK();
},
_onShowPanel: function(message)
{
var panelName = message.id;
var panelDescriptor = this._clientObjects[message.id];
if (panelDescriptor && panelDescriptor instanceof WebInspector.ExtensionServerPanelDescriptor)
panelName = panelDescriptor.name();
WebInspector.inspectorView.showPanel(panelName);
},
_onCreateToolbarButton: function(message, port)
{
var panelDescriptor = this._clientObjects[message.panel];
if (!panelDescriptor || !(panelDescriptor instanceof WebInspector.ExtensionServerPanelDescriptor))
return this._status.E_NOTFOUND(message.panel);
var button = new WebInspector.ExtensionButton(this, message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
this._clientObjects[message.id] = button;
panelDescriptor.panel().then(appendButton);
/**
* @param {!WebInspector.Panel} panel
*/
function appendButton(panel)
{
/** @type {!WebInspector.ExtensionPanel} panel*/ (panel).addToolbarItem(button.toolbarButton());
}
return this._status.OK();
},
_onUpdateButton: function(message, port)
{
var button = this._clientObjects[message.id];
if (!button || !(button instanceof WebInspector.ExtensionButton))
return this._status.E_NOTFOUND(message.id);
button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
return this._status.OK();
},
_onCreateSidebarPane: function(message)
{
if (message.panel !== "elements" && message.panel !== "sources")
return this._status.E_NOTFOUND(message.panel);
var id = message.id;
var sidebar = new WebInspector.ExtensionSidebarPane(this, message.panel, message.title, id);
this._sidebarPanes.push(sidebar);
this._clientObjects[id] = sidebar;
this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.SidebarPaneAdded, sidebar);
return this._status.OK();
},
/**
* @return {!Array.<!WebInspector.ExtensionSidebarPane>}
*/
sidebarPanes: function()
{
return this._sidebarPanes;
},
_onSetSidebarHeight: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setHeight(message.height);
return this._status.OK();
},
_onSetSidebarContent: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
/**
* @this {WebInspector.ExtensionServer}
*/
function callback(error)
{
var result = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, result);
}
if (message.evaluateOnPage)
return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
},
_onSetSidebarPage: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
},
_onOpenResource: function(message)
{
var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(message.url);
if (uiSourceCode) {
WebInspector.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
return this._status.OK();
}
var resource = WebInspector.resourceForURL(message.url);
if (resource) {
WebInspector.Revealer.reveal(resource, message.lineNumber);
return this._status.OK();
}
var request = WebInspector.NetworkLog.requestForURL(message.url);
if (request) {
WebInspector.Revealer.reveal(request);
return this._status.OK();
}
return this._status.E_NOTFOUND(message.url);
},
_onSetOpenResourceHandler: function(message, port)
{
var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
if (message.handlerPresent)
WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
else
WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
},
_handleOpenURL: function(port, details)
{
var url = /** @type {string} */ (details.url);
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return false;
var lineNumber = details.lineNumber;
if (typeof lineNumber === "number")
lineNumber += 1;
port.postMessage({
command: "open-resource",
resource: this._makeResource(contentProvider),
lineNumber: lineNumber
});
return true;
},
_onReload: function(message)
{
var options = /** @type {!ExtensionReloadOptions} */ (message.options || {});
WebInspector.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
var injectedScript;
if (options.injectedScript)
injectedScript = "(function(){" + options.injectedScript + "})()";
WebInspector.targetManager.reloadPage(!!options.ignoreCache, injectedScript);
return this._status.OK();
},
_onEvaluateOnInspectedPage: function(message, port)
{
/**
* @param {?Protocol.Error} error
* @param {?WebInspector.RemoteObject} remoteObject
* @param {boolean=} wasThrown
* @this {WebInspector.ExtensionServer}
*/
function callback(error, remoteObject, wasThrown)
{
var result;
if (error || !remoteObject)
result = this._status.E_PROTOCOLERROR(error.toString());
else if (wasThrown)
result = { isException: true, value: remoteObject.description };
else
result = { value: remoteObject.value };
this._dispatchCallback(message.requestId, port, result);
}
return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
},
_onGetHAR: function()
{
var requests = WebInspector.NetworkLog.requests();
var harLog = (new WebInspector.HARLog(requests)).build();
for (var i = 0; i < harLog.entries.length; ++i)
harLog.entries[i]._requestId = this._requestId(requests[i]);
return harLog;
},
/**
* @param {!WebInspector.ContentProvider} contentProvider
*/
_makeResource: function(contentProvider)
{
return {
url: contentProvider.contentURL(),
type: contentProvider.contentType().name()
};
},
/**
* @return {!Array.<!WebInspector.ContentProvider>}
*/
_onGetPageResources: function()
{
var resources = {};
/**
* @this {WebInspector.ExtensionServer}
*/
function pushResourceData(contentProvider)
{
if (!resources[contentProvider.contentURL()])
resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
}
var uiSourceCodes = WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);
uiSourceCodes = uiSourceCodes.concat(WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.ContentScripts));
uiSourceCodes.forEach(pushResourceData.bind(this));
for (var target of WebInspector.targetManager.targets())
target.resourceTreeModel.forAllResources(pushResourceData.bind(this));
return Object.values(resources);
},
/**
* @param {!WebInspector.ContentProvider} contentProvider
* @param {!Object} message
* @param {!MessagePort} port
*/
_getResourceContent: function(contentProvider, message, port)
{
/**
* @param {?string} content
* @this {WebInspector.ExtensionServer}
*/
function onContentAvailable(content)
{
var contentEncoded = false;
if (contentProvider instanceof WebInspector.Resource)
contentEncoded = contentProvider.contentEncoded;
if (contentProvider instanceof WebInspector.NetworkRequest)
contentEncoded = contentProvider.contentEncoded;
var response = {
encoding: contentEncoded && content ? "base64" : "",
content: content
};
this._dispatchCallback(message.requestId, port, response);
}
contentProvider.requestContent().then(onContentAvailable.bind(this));
},
_onGetRequestContent: function(message, port)
{
var request = this._requestById(message.id);
if (!request)
return this._status.E_NOTFOUND(message.id);
this._getResourceContent(request, message, port);
},
_onGetResourceContent: function(message, port)
{
var url = /** @type {string} */ (message.url);
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return this._status.E_NOTFOUND(url);
this._getResourceContent(contentProvider, message, port);
},
_onSetResourceContent: function(message, port)
{
/**
* @param {?Protocol.Error} error
* @this {WebInspector.ExtensionServer}
*/
function callbackWrapper(error)
{
var response = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, response);
}
var url = /** @type {string} */ (message.url);
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
if (!uiSourceCode || !uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()) {
var resource = WebInspector.ResourceTreeModel.resourceForURL(url);
if (!resource)
return this._status.E_NOTFOUND(url);
return this._status.E_NOTSUPPORTED("Resource is not editable");
}
uiSourceCode.setWorkingCopy(message.content);
if (message.commit)
uiSourceCode.commitWorkingCopy();
callbackWrapper.call(this, null);
},
_requestId: function(request)
{
if (!request._extensionRequestId) {
request._extensionRequestId = ++this._lastRequestId;
this._requests[request._extensionRequestId] = request;
}
return request._extensionRequestId;
},
_requestById: function(id)
{
return this._requests[id];
},
_onAddAuditCategory: function(message, port)
{
var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
this._clientObjects[message.id] = category;
this._auditCategories.push(category);
this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.AuditCategoryAdded, category);
},
/**
* @return {!Array.<!WebInspector.ExtensionAuditCategory>}
*/
auditCategories: function()
{
return this._auditCategories;
},
_onAddAuditResult: function(message)
{
var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
try {
auditResult.addResult(message.displayName, message.description, message.severity, message.details);
} catch (e) {
return e;
}
return this._status.OK();
},
_onUpdateAuditProgress: function(message)
{
var auditResult = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
},
_onStopAuditCategoryRun: function(message)
{
var auditRun = /** {!WebInspector.ExtensionAuditCategoryResults} */ (this._clientObjects[message.resultId]);
if (!auditRun)
return this._status.E_NOTFOUND(message.resultId);
auditRun.done();
},
_onForwardKeyboardEvent: function(message)
{
const Esc = "U+001B";
message.entries.forEach(handleEventEntry);
/**
* @param {*} entry
* @suppressGlobalPropertiesCheck
*/
function handleEventEntry(entry)
{
if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.keyIdentifier) && entry.keyIdentifier !== Esc)
return;
// Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
// and initKeyboardEvent methods and overriding these in externs.js does not have effect.
var event = new window.KeyboardEvent(entry.eventType, {
keyIdentifier: entry.keyIdentifier,
location: entry.location,
ctrlKey: entry.ctrlKey,
altKey: entry.altKey,
shiftKey: entry.shiftKey,
metaKey: entry.metaKey
});
event.__keyCode = keyCodeForEntry(entry);
document.dispatchEvent(event);
}
function keyCodeForEntry(entry)
{
var keyCode = entry.keyCode;
if (!keyCode) {
// This is required only for synthetic events (e.g. dispatched in tests).
var match = entry.keyIdentifier.match(/^U\+([\dA-Fa-f]+)$/);
if (match)
keyCode = parseInt(match[1], 16);
}
return keyCode || 0;
}
},
_dispatchCallback: function(requestId, port, result)
{
if (requestId)
port.postMessage({ command: "callback", requestId: requestId, result: result });
},
_initExtensions: function()
{
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
WebInspector.workspace, WebInspector.Workspace.Events.UISourceCodeAdded, this._notifyResourceAdded);
this._registerAutosubscriptionTargetManagerHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished);
/**
* @this {WebInspector.ExtensionServer}
*/
function onElementsSubscriptionStarted()
{
WebInspector.notifications.addEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, this._notifyElementsSelectionChanged, this);
}
/**
* @this {WebInspector.ExtensionServer}
*/
function onElementsSubscriptionStopped()
{
WebInspector.notifications.removeEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, this._notifyElementsSelectionChanged, this);
}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements",
onElementsSubscriptionStarted.bind(this), onElementsSubscriptionStopped.bind(this));
this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,
this._inspectedURLChanged, this);
InspectorExtensionRegistry.getExtensionsAsync();
},
_notifyResourceAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
},
_notifyUISourceCodeContentCommitted: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
var content = /** @type {string} */ (event.data.content);
this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
},
_notifyRequestFinished: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
},
_notifyElementsSelectionChanged: function()
{
this._postNotification(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements");
},
/**
* @param {!WebInspector.Event} event
*/
_addExtensions: function(event)
{
if (WebInspector.extensionServer._overridePlatformExtensionAPIForTest)
window.buildPlatformExtensionAPI = WebInspector.extensionServer._overridePlatformExtensionAPIForTest;
var extensionInfos = /** @type {!Array.<!ExtensionDescriptor>} */ (event.data);
if (this._initializeCommandIssued)
extensionInfos.forEach(this._addExtension, this);
else
this._pendingExtensionInfos = extensionInfos;
},
/**
* @param {!WebInspector.Event} event
*/
_setInspectedTabId: function(event)
{
this._inspectedTabId = /** @type {string} */ (event.data);
},
/**
* @param {!ExtensionDescriptor} extensionInfo
* @suppressGlobalPropertiesCheck
*/
_addExtension: function(extensionInfo)
{
const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); // Can't use regexp literal here, MinJS chokes on it.
var startPage = extensionInfo.startPage;
var name = extensionInfo.name;
try {
var originMatch = urlOriginRegExp.exec(startPage);
if (!originMatch) {
console.error("Skipping extension with invalid URL: " + startPage);
return false;
}
var extensionOrigin = originMatch[1];
if (!this._registeredExtensions[extensionOrigin]) {
// See ExtensionAPI.js for details.
InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo, this._inspectedTabId));
this._registeredExtensions[extensionOrigin] = { name: name };
}
var iframe = createElement("iframe");
iframe.src = startPage;
iframe.style.display = "none";
document.body.appendChild(iframe); // Only for main window.
} catch (e) {
console.error("Failed to initialize extension " + startPage + ":" + e);
return false;
}
return true;
},
_registerExtension: function(origin, port)
{
if (!this._registeredExtensions.hasOwnProperty(origin)) {
if (origin !== window.location.origin) // Just ignore inspector frames.
console.error("Ignoring unauthorized client request from " + origin);
return;
}
port._extensionOrigin = origin;
port.addEventListener("message", this._onmessage.bind(this), false);
port.start();
},
_onWindowMessage: function(event)
{
if (event.data === "registerExtension")
this._registerExtension(event.origin, event.ports[0]);
},
_onmessage: function(event)
{
var message = event.data;
var result;
if (message.command in this._handlers)
result = this._handlers[message.command](message, event.target);
else
result = this._status.E_NOTSUPPORTED(message.command);
if (result && message.requestId)
this._dispatchCallback(message.requestId, event.target, result);
},
_registerHandler: function(command, callback)
{
console.assert(command);
this._handlers[command] = callback;
},
_registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
{
this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
},
/**
* @param {string} eventTopic
* @param {!Object} eventTarget
* @param {string} frontendEventType
* @param {function(!WebInspector.Event)} handler
*/
_registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
{
this._registerSubscriptionHandler(eventTopic,
eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
},
/**
* @param {string} eventTopic
* @param {!Function} modelClass
* @param {string} frontendEventType
* @param {function(!WebInspector.Event)} handler
*/
_registerAutosubscriptionTargetManagerHandler: function(eventTopic, modelClass, frontendEventType, handler)
{
this._registerSubscriptionHandler(eventTopic,
WebInspector.targetManager.addModelListener.bind(WebInspector.targetManager, modelClass, frontendEventType, handler, this),
WebInspector.targetManager.removeModelListener.bind(WebInspector.targetManager, modelClass, frontendEventType, handler, this));
},
_registerResourceContentCommittedHandler: function(handler)
{
/**
* @this {WebInspector.ExtensionServer}
*/
function addFirstEventListener()
{
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
WebInspector.workspace.setHasResourceContentTrackingExtensions(true);
}
/**
* @this {WebInspector.ExtensionServer}
*/
function removeLastEventListener()
{
WebInspector.workspace.setHasResourceContentTrackingExtensions(false);
WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
addFirstEventListener.bind(this),
removeLastEventListener.bind(this));
},
_expandResourcePath: function(extensionPath, resourcePath)
{
if (!resourcePath)
return;
return extensionPath + this._normalizePath(resourcePath);
},
_normalizePath: function(path)
{
var source = path.split("/");
var result = [];
for (var i = 0; i < source.length; ++i) {
if (source[i] === ".")
continue;
// Ignore empty path components resulting from //, as well as a leading and traling slashes.
if (source[i] === "")
continue;
if (source[i] === "..")
result.pop();
else
result.push(source[i]);
}
return "/" + result.join("/");
},
/**
* @param {string} expression
* @param {boolean} exposeCommandLineAPI
* @param {boolean} returnByValue
* @param {?Object} options
* @param {string} securityOrigin
* @param {function(?string, ?WebInspector.RemoteObject, boolean=)} callback
* @return {!WebInspector.ExtensionStatus.Record|undefined}
*/
evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback)
{
var contextId;
/**
* @param {string} url
* @return {boolean}
*/
function resolveURLToFrame(url)
{
var found;
function hasMatchingURL(frame)
{
found = (frame.url === url) ? frame : null;
return found;
}
WebInspector.ResourceTreeModel.frames().some(hasMatchingURL);
return found;
}
if (typeof options === "object") {
var frame = options.frameURL ? resolveURLToFrame(options.frameURL) : WebInspector.targetManager.mainTarget().resourceTreeModel.mainFrame;
if (!frame) {
if (options.frameURL)
console.warn("evaluate: there is no frame with URL " + options.frameURL);
else
console.warn("evaluate: the main frame is not yet available");
return this._status.E_NOTFOUND(options.frameURL || "<top>");
}
var contextSecurityOrigin;
if (options.useContentScriptContext)
contextSecurityOrigin = securityOrigin;
else if (options.scriptExecutionContext)
contextSecurityOrigin = options.scriptExecutionContext;
var context;
var executionContexts = frame.target().runtimeModel.executionContexts();
if (contextSecurityOrigin) {
for (var i = 0; i < executionContexts.length; ++i) {
var executionContext = executionContexts[i];
if (executionContext.frameId === frame.id && executionContext.origin === contextSecurityOrigin && !executionContext.isDefault)
context = executionContext;
}
if (!context) {
console.warn("The JavaScript context " + contextSecurityOrigin + " was not found in the frame " + frame.url)
return this._status.E_NOTFOUND(contextSecurityOrigin)
}
} else {
for (var i = 0; i < executionContexts.length; ++i) {
var executionContext = executionContexts[i];
if (executionContext.frameId === frame.id && executionContext.isDefault)
context = executionContext;
}
if (!context)
return this._status.E_FAILED(frame.url + " has no execution context");
}
contextId = context.id;
}
var target = target ? target : WebInspector.targetManager.mainTarget();
if (!target)
return;
target.runtimeAgent().evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, false, false, onEvalute);
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
*/
function onEvalute(error, result, wasThrown)
{
if (error) {
callback(error, null, wasThrown);
return;
}
callback(error, target.runtimeModel.createRemoteObject(result), wasThrown);
}
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {string} name
* @param {string} title
* @param {!WebInspector.Panel} panel
* @implements {WebInspector.PanelDescriptor}
*/
WebInspector.ExtensionServerPanelDescriptor = function(name, title, panel)
{
this._name = name;
this._title = title;
this._panel = panel;
}
WebInspector.ExtensionServerPanelDescriptor.prototype = {
/**
* @override
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @override
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @override
* @return {!Promise.<!WebInspector.Panel>}
*/
panel: function()
{
return Promise.resolve(this._panel);
}
}
/**
* @constructor
*/
WebInspector.ExtensionStatus = function()
{
/**
* @param {string} code
* @param {string} description
* @return {!WebInspector.ExtensionStatus.Record}
*/
function makeStatus(code, description)
{
var details = Array.prototype.slice.call(arguments, 2);
var status = { code: code, description: description, details: details };
if (code !== "OK") {
status.isError = true;
console.log("Extension server error: " + String.vsprintf(description, details));
}
return status;
}
this.OK = makeStatus.bind(null, "OK", "OK");
this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
this.E_PROTOCOLERROR = makeStatus.bind(null, "E_PROTOCOLERROR", "Inspector protocol error: %s");
this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
}
/**
* @typedef {{code: string, description: string, details: !Array.<*>}}
*/
WebInspector.ExtensionStatus.Record;
WebInspector.extensionAPI = {};
defineCommonExtensionSymbols(WebInspector.extensionAPI);
/** @type {!WebInspector.ExtensionServer} */
WebInspector.extensionServer;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {!WebInspector.ExtensionServer} server
* @param {string} id
* @param {string} src
* @param {string} className
*/
WebInspector.ExtensionView = function(server, id, src, className)
{
WebInspector.Widget.call(this);
this.setHideOnDetach();
this.element.className = "vbox flex-auto"; // Override
this._server = server;
this._id = id;
this._iframe = createElement("iframe");
this._iframe.addEventListener("load", this._onLoad.bind(this), false);
this._iframe.src = src;
this._iframe.className = className;
this.setDefaultFocusedElement(this._iframe);
this.element.appendChild(this._iframe);
}
WebInspector.ExtensionView.prototype = {
wasShown: function()
{
if (typeof this._frameIndex === "number")
this._server.notifyViewShown(this._id, this._frameIndex);
},
willHide: function()
{
if (typeof this._frameIndex === "number")
this._server.notifyViewHidden(this._id);
},
_onLoad: function()
{
var frames = /** @type {!Array.<!Window>} */ (window.frames);
this._frameIndex = Array.prototype.indexOf.call(frames, this._iframe.contentWindow);
if (this.isShowing())
this._server.notifyViewShown(this._id, this._frameIndex);
},
__proto__: WebInspector.Widget.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ExtensionServer} server
* @param {string} id
*/
WebInspector.ExtensionNotifierView = function(server, id)
{
WebInspector.VBox.call(this);
this._server = server;
this._id = id;
}
WebInspector.ExtensionNotifierView.prototype = {
wasShown: function()
{
this._server.notifyViewShown(this._id);
},
willHide: function()
{
this._server.notifyViewHidden(this._id);
},
__proto__: WebInspector.VBox.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CSSFormatter.js | 1.72% | (1 / 58) | 0% | (0 / 38) | 0% | (0 / 3) | 1.72% | (1 / 58) | |
| CSSRuleParser.js | 3.67% | (4 / 109) | 0% | (0 / 62) | 0% | (0 / 5) | 3.67% | (4 / 109) | |
| FormattedContentBuilder.js | 1.56% | (1 / 64) | 0% | (0 / 28) | 0% | (0 / 14) | 1.56% | (1 / 64) | |
| FormatterWorker.js | 4.84% | (6 / 124) | 0% | (0 / 51) | 0% | (0 / 10) | 4.88% | (6 / 123) | |
| HTMLFormatter.js | 6.25% | (2 / 32) | 0% | (0 / 17) | 0% | (0 / 4) | 6.25% | (2 / 32) | |
| IdentityFormatter.js | 20% | (1 / 5) | 100% | (0 / 0) | 0% | (0 / 2) | 20% | (1 / 5) | |
| JavaScriptFormatter.js | 0.5% | (1 / 201) | 0% | (0 / 309) | 0% | (0 / 8) | 0.5% | (1 / 201) | |
| JavaScriptOutline.js | 2% | (1 / 50) | 0% | (0 / 42) | 0% | (0 / 1) | 2% | (1 / 50) | |
| RelaxedJSONParser.js | 7.95% | (7 / 88) | 0% | (0 / 48) | 0% | (0 / 7) | 7.95% | (7 / 88) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.FormattedContentBuilder} builder
*/
WebInspector.CSSFormatter = function(builder)
{
this._builder = builder;
}
WebInspector.CSSFormatter.prototype = {
/**
* @param {string} text
* @param {!Array.<number>} lineEndings
* @param {number} fromOffset
* @param {number} toOffset
*/
format: function(text, lineEndings, fromOffset, toOffset)
{
this._lineEndings = lineEndings;
this._fromOffset = fromOffset;
this._toOffset = toOffset;
this._lastLine = -1;
this._state = {};
var tokenize = WebInspector.createTokenizer("text/css");
var oldEnforce = this._builder.setEnforceSpaceBetweenWords(false);
tokenize(text.substring(this._fromOffset, this._toOffset), this._tokenCallback.bind(this));
this._builder.setEnforceSpaceBetweenWords(oldEnforce);
},
/**
* @param {string} token
* @param {?string} type
* @param {number} startPosition
*/
_tokenCallback: function(token, type, startPosition)
{
startPosition += this._fromOffset;
var startLine = this._lineEndings.lowerBound(startPosition);
if (startLine !== this._lastLine)
this._state.eatWhitespace = true;
if (/^property/.test(type) && !this._state.inPropertyValue)
this._state.seenProperty = true;
this._lastLine = startLine;
var isWhitespace = /^\s+$/.test(token);
if (isWhitespace) {
if (!this._state.eatWhitespace)
this._builder.addSoftSpace();
return;
}
this._state.eatWhitespace = false;
if (token === "\n")
return;
if (token !== "}") {
if (this._state.afterClosingBrace)
this._builder.addNewLine(true);
this._state.afterClosingBrace = false;
}
if (token === "}") {
if (this._state.inPropertyValue)
this._builder.addNewLine();
this._builder.decreaseNestingLevel();
this._state.afterClosingBrace = true;
this._state.inPropertyValue = false;
} else if (token === ":" && !this._state.inPropertyValue && this._state.seenProperty) {
this._builder.addToken(token, startPosition);
this._builder.addSoftSpace();
this._state.eatWhitespace = true;
this._state.inPropertyValue = true;
this._state.seenProperty = false;
return;
} else if (token === "{") {
this._builder.addSoftSpace();
this._builder.addToken(token, startPosition);
this._builder.addNewLine();
this._builder.increaseNestingLevel();
return;
}
this._builder.addToken(token, startPosition);
if (type === "comment" && !this._state.inPropertyValue && !this._state.seenProperty)
this._builder.addNewLine();
if (token === ";" && this._state.inPropertyValue) {
this._state.inPropertyValue = false;
this._builder.addNewLine();
} else if (token === "}") {
this._builder.addNewLine();
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | 2 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.CSSParserStates = {
Initial: "Initial",
Selector: "Selector",
Style: "Style",
PropertyName: "PropertyName",
PropertyValue: "PropertyValue",
AtRule: "AtRule"
};
/**
* @param {string} text
*/
WebInspector.parseCSS = function(text)
{
WebInspector._innerParseCSS(text, postMessage);
}
/**
* @param {string} text
* @param {function(*)} chunkCallback
*/
WebInspector._innerParseCSS = function(text, chunkCallback)
{
var chunkSize = 100000; // characters per data chunk
var lines = text.split("\n");
var rules = [];
var processedChunkCharacters = 0;
var state = WebInspector.CSSParserStates.Initial;
var rule;
var property;
var UndefTokenType = {};
var disabledRules = [];
function disabledRulesCallback(chunk)
{
disabledRules = disabledRules.concat(chunk.chunk);
}
/**
* @param {string} tokenValue
* @param {?string} tokenTypes
* @param {number} column
* @param {number} newColumn
*/
function processToken(tokenValue, tokenTypes, column, newColumn)
{
var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType;
switch (state) {
case WebInspector.CSSParserStates.Initial:
if (tokenType["qualifier"] || tokenType["builtin"] || tokenType["tag"]) {
rule = {
selectorText: tokenValue,
lineNumber: lineNumber,
columnNumber: column,
properties: [],
};
state = WebInspector.CSSParserStates.Selector;
} else if (tokenType["def"]) {
rule = {
atRule: tokenValue,
lineNumber: lineNumber,
columnNumber: column,
};
state = WebInspector.CSSParserStates.AtRule;
}
break;
case WebInspector.CSSParserStates.Selector:
if (tokenValue === "{" && tokenType === UndefTokenType) {
rule.selectorText = rule.selectorText.trim();
rule.styleRange = createRange(lineNumber, newColumn);
state = WebInspector.CSSParserStates.Style;
} else {
rule.selectorText += tokenValue;
}
break;
case WebInspector.CSSParserStates.AtRule:
if ((tokenValue === ";" || tokenValue === "{") && tokenType === UndefTokenType) {
rule.atRule = rule.atRule.trim();
rules.push(rule);
state = WebInspector.CSSParserStates.Initial;
} else {
rule.atRule += tokenValue;
}
break;
case WebInspector.CSSParserStates.Style:
if (tokenType["meta"] || tokenType["property"]) {
property = {
name: tokenValue,
value: "",
range: createRange(lineNumber, column),
nameRange: createRange(lineNumber, column)
};
state = WebInspector.CSSParserStates.PropertyName;
} else if (tokenValue === "}" && tokenType === UndefTokenType) {
rule.styleRange.endLine = lineNumber;
rule.styleRange.endColumn = column;
rules.push(rule);
state = WebInspector.CSSParserStates.Initial;
} else if (tokenType["comment"]) {
// The |processToken| is called per-line, so no token spans more then one line.
// Support only a one-line comments.
if (tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/")
break;
var uncommentedText = tokenValue.substring(2, tokenValue.length - 2);
var fakeRule = "a{\n" + uncommentedText + "}";
disabledRules = [];
WebInspector._innerParseCSS(fakeRule, disabledRulesCallback);
if (disabledRules.length === 1 && disabledRules[0].properties.length === 1) {
var disabledProperty = disabledRules[0].properties[0];
disabledProperty.disabled = true;
disabledProperty.range = createRange(lineNumber, column);
disabledProperty.range.endColumn = newColumn;
var lineOffset = lineNumber - 1;
var columnOffset = column + 2;
disabledProperty.nameRange.startLine += lineOffset;
disabledProperty.nameRange.startColumn += columnOffset;
disabledProperty.nameRange.endLine += lineOffset;
disabledProperty.nameRange.endColumn += columnOffset;
disabledProperty.valueRange.startLine += lineOffset;
disabledProperty.valueRange.startColumn += columnOffset;
disabledProperty.valueRange.endLine += lineOffset;
disabledProperty.valueRange.endColumn += columnOffset;
rule.properties.push(disabledProperty);
}
}
break;
case WebInspector.CSSParserStates.PropertyName:
if (tokenValue === ":" && tokenType === UndefTokenType) {
property.name = property.name;
property.nameRange.endLine = lineNumber;
property.nameRange.endColumn = column;
property.valueRange = createRange(lineNumber, newColumn);
state = WebInspector.CSSParserStates.PropertyValue;
} else if (tokenType["property"]) {
property.name += tokenValue;
}
break;
case WebInspector.CSSParserStates.PropertyValue:
if ((tokenValue === ";" || tokenValue === "}") && tokenType === UndefTokenType) {
property.value = property.value;
property.valueRange.endLine = lineNumber;
property.valueRange.endColumn = column;
property.range.endLine = lineNumber;
property.range.endColumn = tokenValue === ";" ? newColumn : column;
rule.properties.push(property);
if (tokenValue === "}") {
rule.styleRange.endLine = lineNumber;
rule.styleRange.endColumn = column;
rules.push(rule);
state = WebInspector.CSSParserStates.Initial;
} else {
state = WebInspector.CSSParserStates.Style;
}
} else if (!tokenType["comment"]) {
property.value += tokenValue;
}
break;
default:
console.assert(false, "Unknown CSS parser state.");
}
processedChunkCharacters += newColumn - column;
if (processedChunkCharacters > chunkSize) {
chunkCallback({ chunk: rules, isLastChunk: false });
rules = [];
processedChunkCharacters = 0;
}
}
var tokenizer = WebInspector.createTokenizer("text/css");
var lineNumber;
for (lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
var line = lines[lineNumber];
tokenizer(line, processToken);
processToken("\n", null, line.length, line.length + 1);
}
chunkCallback({ chunk: rules, isLastChunk: true });
/**
* @return {!{startLine: number, startColumn: number, endLine: number, endColumn: number}}
*/
function createRange(lineNumber, columnNumber)
{
return {
startLine: lineNumber,
startColumn: columnNumber,
endLine: lineNumber,
endColumn: columnNumber
};
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {string} indentString
*/
WebInspector.FormattedContentBuilder = function(indentString)
{
this._lastOriginalPosition = 0;
this._formattedContent = [];
this._formattedContentLength = 0;
this._lastFormattedPosition = 0;
/** @type {!{original: !Array.<number>, formatted: !Array.<number>}} */
this._mapping = { original: [0], formatted: [0] };
this._nestingLevel = 0;
this._indentString = indentString;
/** @type {!Map<number, string>} */
this._cachedIndents = new Map();
this._newLines = 0;
this._softSpace = false;
this._hardSpaces = 0;
this._enforceSpaceBetweenWords = true;
}
WebInspector.FormattedContentBuilder.prototype = {
/**
* @param {boolean} value
* @return {boolean}
*/
setEnforceSpaceBetweenWords: function(value)
{
var oldValue = this._enforceSpaceBetweenWords;
this._enforceSpaceBetweenWords = value;
return oldValue;
},
/**
* @param {string} token
* @param {number} offset
*/
addToken: function(token, offset)
{
var last = this._formattedContent.peekLast();
if (this._enforceSpaceBetweenWords && last && /\w/.test(last[last.length - 1]) && /\w/.test(token))
this.addSoftSpace();
this._appendFormatting();
// Insert token.
this._addMappingIfNeeded(offset);
this._addText(token);
},
addSoftSpace: function()
{
if (!this._hardSpaces)
this._softSpace = true;
},
addHardSpace: function()
{
this._softSpace = false;
++this._hardSpaces;
},
/**
* @param {boolean=} noSquash
*/
addNewLine: function(noSquash)
{
if (noSquash)
++this._newLines;
else
this._newLines = this._newLines || 1;
},
increaseNestingLevel: function()
{
this._nestingLevel += 1;
},
decreaseNestingLevel: function()
{
if (this._nestingLevel > 0)
this._nestingLevel -= 1;
},
_appendFormatting: function()
{
if (this._newLines) {
for (var i = 0; i < this._newLines; ++i)
this._addText("\n");
this._addText(this._indent());
} else if (this._softSpace) {
this._addText(" ");
}
if (this._hardSpaces) {
for (var i = 0; i < this._hardSpaces; ++i)
this._addText(" ");
}
this._newLines = 0;
this._softSpace = false;
this._hardSpaces = 0;
},
/**
* @return {string}
*/
content: function()
{
return this._formattedContent.join("") + (this._newLines ? "\n" : "");
},
/**
* @return {!{original: !Array.<number>, formatted: !Array.<number>}}
*/
mapping: function()
{
return this._mapping;
},
/**
* @return {string}
*/
_indent: function()
{
var cachedValue = this._cachedIndents.get(this._nestingLevel)
if (cachedValue)
return cachedValue;
var fullIndent = "";
for (var i = 0; i < this._nestingLevel; ++i)
fullIndent += this._indentString;
// Cache a maximum of 20 nesting level indents.
if (this._nestingLevel <= 20)
this._cachedIndents.set(this._nestingLevel, fullIndent);
return fullIndent;
},
/**
* @param {string} text
*/
_addText: function(text)
{
this._formattedContent.push(text);
this._formattedContentLength += text.length;
},
/**
* @param {number} originalPosition
*/
_addMappingIfNeeded: function(originalPosition)
{
if (originalPosition - this._lastOriginalPosition === this._formattedContentLength - this._lastFormattedPosition)
return;
this._mapping.original.push(originalPosition);
this._lastOriginalPosition = originalPosition;
this._mapping.formatted.push(this._formattedContentLength);
this._lastFormattedPosition = this._formattedContentLength;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | 2 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @param {string} mimeType
* @return {function(string, function(string, ?string, number, number):(!Object|undefined))}
*/
WebInspector.createTokenizer = function(mimeType)
{
var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
var state = CodeMirror.startState(mode);
/**
* @param {string} line
* @param {function(string, ?string, number, number):?} callback
*/
function tokenize(line, callback)
{
var stream = new CodeMirror.StringStream(line);
while (!stream.eol()) {
var style = mode.token(stream, state);
var value = stream.current();
if (callback(value, style, stream.start, stream.start + value.length) === WebInspector.AbortTokenization)
return;
stream.start = stream.pos;
}
}
return tokenize;
}
WebInspector.AbortTokenization = {};
self.onmessage = function(event) {
var method = /** @type {string} */(event.data.method);
var params = /** @type !{indentString: string, content: string, mimeType: string} */ (event.data.params);
if (!method)
return;
switch (method) {
case "format":
WebInspector.format(params.mimeType, params.content, params.indentString);
break;
case "parseCSS":
WebInspector.parseCSS(params.content);
break;
case "javaScriptOutline":
WebInspector.javaScriptOutline(params.content);
break;
case "javaScriptIdentifiers":
WebInspector.javaScriptIdentifiers(params.content);
break;
case "evaluatableJavaScriptSubstring":
WebInspector.evaluatableJavaScriptSubstring(params.content);
break;
default:
console.error("Unsupport method name: " + method);
}
};
/**
* @param {string} content
*/
WebInspector.evaluatableJavaScriptSubstring = function(content)
{
var tokenizer = acorn.tokenizer(content, {ecmaVersion: 6});
var result = "";
try {
var token = tokenizer.getToken();
while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokenizer.punctuator(token))
token = tokenizer.getToken();
var startIndex = token.start;
var endIndex = token.end;
var openBracketsCounter = 0;
while (token.type !== acorn.tokTypes.eof) {
var isIdentifier = WebInspector.AcornTokenizer.identifier(token);
var isThis = WebInspector.AcornTokenizer.keyword(token, "this");
var isString = token.type === acorn.tokTypes.string;
if (!isThis && !isIdentifier && !isString)
break;
endIndex = token.end;
token = tokenizer.getToken();
while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) {
if (WebInspector.AcornTokenizer.punctuator(token, "["))
openBracketsCounter++;
if (WebInspector.AcornTokenizer.punctuator(token, "]")) {
endIndex = openBracketsCounter > 0 ? token.end : endIndex;
openBracketsCounter--;
}
token = tokenizer.getToken();
}
}
result = content.substring(startIndex, endIndex);
} catch (e) {
console.error(e);
}
postMessage(result);
}
/**
* @param {string} content
*/
WebInspector.javaScriptIdentifiers = function(content)
{
var root = acorn.parse(content, {});
/** @type {!Array<!ESTree.Node>} */
var identifiers = [];
var functionDeclarationCounter = 0;
var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
/**
* @param {!ESTree.Node} node
* @return {boolean}
*/
function isFunction(node)
{
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
}
/**
* @param {!ESTree.Node} node
*/
function beforeVisit(node)
{
if (isFunction(node))
functionDeclarationCounter++;
if (functionDeclarationCounter > 1)
return;
if (isFunction(node) && node.params)
identifiers.pushAll(node.params);
if (node.type === "VariableDeclarator")
identifiers.push(/** @type {!ESTree.Node} */(node.id));
}
/**
* @param {!ESTree.Node} node
*/
function afterVisit(node)
{
if (isFunction(node))
functionDeclarationCounter--;
}
walker.walk(root);
var reduced = identifiers.map(id => ({name: id.name, offset: id.start}));
postMessage(reduced);
}
/**
* @param {string} mimeType
* @param {string} text
* @param {string=} indentString
*/
WebInspector.format = function(mimeType, text, indentString)
{
// Default to a 4-space indent.
indentString = indentString || " ";
var result = {};
var builder = new WebInspector.FormattedContentBuilder(indentString);
var lineEndings = text.computeLineEndings();
try {
switch (mimeType) {
case "text/html":
formatMixedHTML(builder, text, lineEndings);
break;
case "text/css":
var formatter = new WebInspector.CSSFormatter(builder);
formatter.format(text, lineEndings, 0, text.length);
break;
case "text/javascript":
var formatter = new WebInspector.JavaScriptFormatter(builder);
formatter.format(text, lineEndings, 0, text.length);
break;
default:
var formatter = new WebInspector.IdentityFormatter(builder);
formatter.format(text, lineEndings, 0, text.length);
}
result.mapping = builder.mapping();
result.content = builder.content();
} catch (e) {
console.error(e);
result.mapping = { original: [0], formatted: [0] };
result.content = text;
}
postMessage(result);
}
/**
* @param {!WebInspector.FormattedContentBuilder} builder
* @param {string} text
* @param {!Array<number>} lineEndings
*/
function formatMixedHTML(builder, text, lineEndings)
{
var htmlFormatter = new WebInspector.HTMLFormatter(builder);
var jsFormatter = new WebInspector.JavaScriptFormatter(builder);
var cssFormatter = new WebInspector.CSSFormatter(builder);
var identityFormatter = new WebInspector.IdentityFormatter(builder);
var offset = 0;
while (offset < text.length) {
var result = htmlFormatter.format(text, lineEndings, offset);
if (result.offset >= text.length)
break;
builder.addNewLine();
var closeTag = "</" + result.tagName;
offset = text.indexOf(closeTag, result.offset);
if (offset === -1)
offset = text.length;
if (result.tagName === "script")
jsFormatter.format(text, lineEndings, result.offset, offset);
else if (result.tagName === "style")
cssFormatter.format(text, lineEndings, result.offset, offset);
else
identityFormatter.format(text, lineEndings, result.offset, offset);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.FormattedContentBuilder} builder
*/
WebInspector.HTMLFormatter = function(builder)
{
this._builder = builder;
}
/**
* @constructor
* @param {string} tagName
* @param {number} offset
*/
WebInspector.HTMLFormatter.Result = function(tagName, offset)
{
this.tagName = tagName;
this.offset = offset;
}
WebInspector.HTMLFormatter.prototype = {
/**
* @param {string} text
* @param {!Array<number>} lineEndings
* @param {number} fromOffset
* @return {!WebInspector.HTMLFormatter.Result}
*/
format: function(text, lineEndings, fromOffset)
{
var content = text.substring(fromOffset);
var tagName = "";
var accumulatedTokenValue = "";
var lastOffset = fromOffset;
/**
* @param {string} tokenValue
* @param {?string} type
* @param {number} tokenStart
* @param {number} tokenEnd
* @return {(!Object|undefined)}
* @this {WebInspector.HTMLFormatter}
*/
function processToken(tokenValue, type, tokenStart, tokenEnd)
{
tokenStart += fromOffset;
tokenEnd += fromOffset;
lastOffset = tokenEnd;
this._builder.addToken(tokenValue, tokenStart);
if (!type)
return;
var tokenType = type.split(" ").keySet();
if (!tokenType["tag"])
return;
if (tokenType["bracket"] && (tokenValue === "<" || tokenValue === "</")) {
accumulatedTokenValue = tokenValue;
return;
}
if (tagName && tokenValue === ">")
return WebInspector.AbortTokenization;
accumulatedTokenValue = accumulatedTokenValue + tokenValue.toLowerCase();
if (accumulatedTokenValue === "<script" || accumulatedTokenValue === "<style")
tagName = accumulatedTokenValue.substring(1);
accumulatedTokenValue = "";
}
var tokenizer = WebInspector.createTokenizer("text/html");
tokenizer(content, processToken.bind(this));
return new WebInspector.HTMLFormatter.Result(tagName, lastOffset);
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.FormattedContentBuilder} builder
*/
WebInspector.IdentityFormatter = function(builder)
{
this._builder = builder;
}
WebInspector.IdentityFormatter.prototype = {
/**
* @param {string} text
* @param {!Array<number>} lineEndings
* @param {number} fromOffset
* @param {number} toOffset
*/
format: function(text, lineEndings, fromOffset, toOffset)
{
var content = text.substring(fromOffset, toOffset);
this._builder.addToken(content, fromOffset);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.FormattedContentBuilder} builder
*/
WebInspector.JavaScriptFormatter = function(builder)
{
this._builder = builder;
}
WebInspector.JavaScriptFormatter.prototype = {
/**
* @param {string} text
* @param {!Array<number>} lineEndings
* @param {number} fromOffset
* @param {number} toOffset
*/
format: function(text, lineEndings, fromOffset, toOffset)
{
this._fromOffset = fromOffset;
this._toOffset = toOffset;
this._content = text.substring(this._fromOffset, this._toOffset);
this._tokenizer = new WebInspector.AcornTokenizer(this._content);
var ast = acorn.parse(this._content, { ranges: false, ecmaVersion: 6 });
var walker = new WebInspector.ESTreeWalker(this._beforeVisit.bind(this), this._afterVisit.bind(this));
walker.walk(ast);
},
/**
* @param {?Acorn.TokenOrComment} token
* @param {string} format
*/
_push: function(token, format)
{
for (var i = 0; i < format.length; ++i) {
if (format[i] === "s")
this._builder.addSoftSpace();
else if (format[i] === "S")
this._builder.addHardSpace();
else if (format[i] === "n")
this._builder.addNewLine();
else if (format[i] === ">")
this._builder.increaseNestingLevel();
else if (format[i] === "<")
this._builder.decreaseNestingLevel();
else if (format[i] === "t")
this._builder.addToken(this._content.substring(token.start, token.end), this._fromOffset + token.start);
}
},
/**
* @param {!ESTree.Node} node
*/
_beforeVisit: function(node)
{
if (!node.parent)
return;
while (this._tokenizer.peekToken() && this._tokenizer.peekToken().start < node.start) {
var token = /** @type {!Acorn.TokenOrComment} */(this._tokenizer.nextToken());
var format = this._formatToken(node.parent, token);
this._push(token, format);
}
},
/**
* @param {!ESTree.Node} node
*/
_afterVisit: function(node)
{
while (this._tokenizer.peekToken() && this._tokenizer.peekToken().start < node.end) {
var token = /** @type {!Acorn.TokenOrComment} */(this._tokenizer.nextToken());
var format = this._formatToken(node, token);
this._push(token, format);
}
this._push(null, this._finishNode(node));
},
/**
* @param {!ESTree.Node} node
* @return {boolean}
*/
_inForLoopHeader: function(node)
{
var parent = node.parent;
if (!parent)
return false;
if (parent.type === "ForStatement")
return node === parent.init || node === parent.test || node === parent.update;
if (parent.type === "ForInStatement" || parent.type === "ForOfStatement")
return node === parent.left || parent.right;
return false;
},
/**
* @param {!ESTree.Node} node
* @param {!Acorn.TokenOrComment} token
* @return {string}
*/
_formatToken: function(node, token)
{
var AT = WebInspector.AcornTokenizer;
if (AT.lineComment(token))
return "tn";
if (AT.blockComment(token))
return "tn";
if (node.type === "ContinueStatement" || node.type === "BreakStatement") {
return node.label && AT.keyword(token) ? "ts" : "t";
} else if (node.type === "Identifier") {
return "t";
} else if (node.type === "ReturnStatement") {
if (AT.punctuator(token, ";"))
return "t";
return node.argument ? "ts" : "t";
} else if (node.type === "Property") {
if (AT.punctuator(token, ":"))
return "ts";
return "t";
} else if (node.type === "ArrayExpression") {
if (AT.punctuator(token, ","))
return "ts";
return "t";
} else if (node.type === "LabeledStatement") {
if (AT.punctuator(token, ":"))
return "ts";
} else if (node.type === "LogicalExpression" || node.type === "AssignmentExpression" || node.type === "BinaryExpression") {
if (AT.punctuator(token) && !AT.punctuator(token, "()"))
return "sts";
} else if (node.type === "ConditionalExpression") {
if (AT.punctuator(token, "?:"))
return "sts";
} else if (node.type === "VariableDeclarator") {
if (AT.punctuator(token, "="))
return "sts";
} else if (node.type === "FunctionDeclaration") {
if (AT.punctuator(token, ",)"))
return "ts";
} else if (node.type === "FunctionExpression") {
if (AT.punctuator(token, ",)"))
return "ts";
if (AT.keyword(token, "function"))
return node.id ? "ts" : "t";
} else if (node.type === "WithStatement") {
if (AT.punctuator(token, ")"))
return node.body && node.body.type === "BlockStatement" ? "ts" : "tn>";
} else if (node.type === "SwitchStatement") {
if (AT.punctuator(token, "{"))
return "tn>";
if (AT.punctuator(token, "}"))
return "n<tn";
if (AT.punctuator(token, ")"))
return "ts";
} else if (node.type === "SwitchCase") {
if (AT.keyword(token, "case"))
return "n<ts";
if (AT.keyword(token, "default"))
return "n<t";
if (AT.punctuator(token, ":"))
return "tn>";
} else if (node.type === "VariableDeclaration") {
if (AT.punctuator(token, ",")) {
var allVariablesInitialized = true;
var declarations = /** @type {!Array.<!ESTree.Node>} */(node.declarations);
for (var i = 0; i < declarations.length; ++i)
allVariablesInitialized = allVariablesInitialized && !!declarations[i].init;
return !this._inForLoopHeader(node) && allVariablesInitialized ? "nSSts" : "ts";
}
} else if (node.type === "BlockStatement") {
if (AT.punctuator(token, "{"))
return node.body.length ? "tn>" : "t";
if (AT.punctuator(token, "}"))
return node.body.length ? "n<t" : "t";
} else if (node.type === "CatchClause") {
if (AT.punctuator(token, ")"))
return "ts";
} else if (node.type === "ObjectExpression") {
if (!node.properties.length)
return "t";
if (AT.punctuator(token, "{"))
return "tn>";
if (AT.punctuator(token, "}"))
return "n<t";
if (AT.punctuator(token, ","))
return "tn";
} else if (node.type === "IfStatement") {
if (AT.punctuator(token, ")"))
return node.consequent && node.consequent.type === "BlockStatement" ? "ts" : "tn>";
if (AT.keyword(token, "else")) {
var preFormat = node.consequent && node.consequent.type === "BlockStatement" ? "st" : "n<t";
var postFormat = "n>";
if (node.alternate && (node.alternate.type === "BlockStatement" || node.alternate.type === "IfStatement"))
postFormat = "s";
return preFormat + postFormat;
}
} else if (node.type === "CallExpression") {
if (AT.punctuator(token, ","))
return "ts";
} else if (node.type === "SequenceExpression" && AT.punctuator(token, ",")) {
return node.parent && node.parent.type === "SwitchCase" ? "ts" : "tn";
} else if (node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement") {
if (AT.punctuator(token, ";"))
return "ts";
if (AT.keyword(token, "in") || AT.identifier(token, "of"))
return "sts";
if (AT.punctuator(token, ")"))
return node.body && node.body.type === "BlockStatement" ? "ts" : "tn>";
} else if (node.type === "WhileStatement") {
if (AT.punctuator(token, ")"))
return node.body && node.body.type === "BlockStatement" ? "ts" : "tn>";
} else if (node.type === "DoWhileStatement") {
var blockBody = node.body && node.body.type === "BlockStatement";
if (AT.keyword(token, "do"))
return blockBody ? "ts" : "tn>";
if (AT.keyword(token, "while"))
return blockBody ? "sts" : "n<ts";
} else if (node.type === "ClassBody") {
if (AT.punctuator(token, "{"))
return "stn>";
if (AT.punctuator(token, "}"))
return "<ntn";
return "t";
} else if (node.type === "YieldExpression") {
return "t";
} else if (node.type === "Super") {
return "t";
}
return AT.keyword(token) && !AT.keyword(token, "this") ? "ts" : "t";
},
/**
* @param {!ESTree.Node} node
* @return {string}
*/
_finishNode: function(node)
{
if (node.type === "WithStatement") {
if (node.body && node.body.type !== "BlockStatement")
return "n<";
} else if (node.type === "VariableDeclaration") {
if (!this._inForLoopHeader(node))
return "n";
} else if (node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement") {
if (node.body && node.body.type !== "BlockStatement")
return "n<";
} else if (node.type === "BlockStatement") {
if (node.parent && node.parent.type === "IfStatement" && node.parent.alternate && node.parent.consequent === node)
return "";
if (node.parent && node.parent.type === "FunctionExpression" && node.parent.parent && node.parent.parent.type === "Property")
return "";
if (node.parent && node.parent.type === "FunctionExpression" && node.parent.parent && node.parent.parent.type === "CallExpression")
return "";
if (node.parent && node.parent.type === "DoWhileStatement")
return "";
if (node.parent && node.parent.type === "TryStatement" && node.parent.block == node)
return "s";
if (node.parent && node.parent.type === "CatchClause" && node.parent.parent.finalizer)
return "s";
return "n";
} else if (node.type === "WhileStatement") {
if (node.body && node.body.type !== "BlockStatement")
return "n<";
} else if (node.type === "IfStatement") {
if (node.alternate) {
if (node.alternate.type !== "BlockStatement" && node.alternate.type !== "IfStatement")
return "<";
} else if (node.consequent) {
if (node.consequent.type !== "BlockStatement")
return "<";
}
} else if (node.type === "BreakStatement" || node.type === "ThrowStatement" || node.type === "ReturnStatement" || node.type === "ExpressionStatement") {
return "n";
}
return "";
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @param {string} content
*/
WebInspector.javaScriptOutline = function(content)
{
var chunkSize = 100000; // characters per data chunk
var outlineChunk = [];
var previousIdentifier = null;
var previousToken = null;
var processedChunkCharacters = 0;
var addedFunction = false;
var isReadingArguments = false;
var argumentsText = "";
var currentFunction = null;
var tokenizer = new WebInspector.AcornTokenizer(content);
var AT = WebInspector.AcornTokenizer;
while (tokenizer.peekToken()) {
var token = /** @type {!Acorn.TokenOrComment} */(tokenizer.nextToken());
if (AT.lineComment(token) || AT.blockComment(token))
continue;
var tokenValue = content.substring(token.start, token.end);
if (AT.identifier(token) && previousToken && (AT.identifier(previousToken, "get") || AT.identifier(previousToken, "set"))) {
currentFunction = {
line: tokenizer.tokenLineStart(),
column: tokenizer.tokenColumnStart(),
name : previousToken.value + " " + tokenValue
};
addedFunction = true;
previousIdentifier = null;
} else if (AT.identifier(token)) {
previousIdentifier = tokenValue;
if (tokenValue && previousToken && AT.keyword(previousToken, "function")) {
// A named function: "function f...".
currentFunction = {
line: tokenizer.tokenLineStart(),
column: tokenizer.tokenColumnStart(),
name: tokenValue
};
addedFunction = true;
previousIdentifier = null;
}
} else if (AT.keyword(token, "function") && previousIdentifier && previousToken && AT.punctuator(previousToken, ":=")) {
// Anonymous function assigned to an identifier: "...f = function..."
// or "funcName: function...".
currentFunction = {
line: tokenizer.tokenLineStart(),
column: tokenizer.tokenColumnStart(),
name: previousIdentifier
};
addedFunction = true;
previousIdentifier = null;
} else if (AT.punctuator(token, ".") && previousToken && AT.identifier(previousToken))
previousIdentifier += ".";
else if (AT.punctuator(token, "(") && addedFunction)
isReadingArguments = true;
if (isReadingArguments && tokenValue)
argumentsText += tokenValue;
if (AT.punctuator(token, ")") && isReadingArguments) {
addedFunction = false;
isReadingArguments = false;
currentFunction.arguments = argumentsText.replace(/,[\r\n\s]*/g, ", ").replace(/([^,])[\r\n\s]+/g, "$1");
argumentsText = "";
outlineChunk.push(currentFunction);
}
previousToken = token;
processedChunkCharacters += token.end - token.start;
if (processedChunkCharacters >= chunkSize) {
postMessage({ chunk: outlineChunk, isLastChunk: false });
outlineChunk = [];
processedChunkCharacters = 0;
}
}
postMessage({ chunk: outlineChunk, isLastChunk: true });
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | 2 1 1 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.RelaxedJSONParser = {};
/** @enum {string} */
WebInspector.RelaxedJSONParser.States = {
ExpectKey: "ExpectKey",
ExpectValue: "ExpectValue"
};
/** @enum {*} */
WebInspector.RelaxedJSONParser.Keywords = {
"NaN": NaN,
"true": true,
"false": false,
"Infinity": Infinity,
"undefined": undefined,
"null": null
};
/**
* @param {string} content
* @return {*}
*/
WebInspector.RelaxedJSONParser.parse = function(content)
{
var Keywords = WebInspector.RelaxedJSONParser.Keywords;
var States = WebInspector.RelaxedJSONParser.States;
content = "(" + content + ")";
try {
var root = acorn.parse(content, {});
} catch (e) {
return null;
}
var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
var rootTip = [];
/** @type {!Array.<!WebInspector.RelaxedJSONParser.Context>} */
var stack = [];
var stackData = /** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
key: 0,
tip: rootTip,
state: States.ExpectValue,
parentIsArray: true
});
walker.setWalkNulls(true);
var hasExpression = false;
walker.walk(root);
if (hasExpression)
return null;
return rootTip.length ? rootTip[0] : null;
/**
* @param {!WebInspector.RelaxedJSONParser.Context} newStack
*/
function pushStack(newStack)
{
stack.push(stackData);
stackData = newStack;
}
function popStack()
{
stackData = stack.pop();
}
/**
* @param {*} value
*/
function applyValue(value)
{
stackData.tip[stackData.key] = value;
if (stackData.parentIsArray)
stackData.key++;
else
stackData.state = null;
}
/**
* @param {!ESTree.Node} node
* @return {!Object|undefined}
*/
function beforeVisit(node)
{
switch (node.type) {
case "ObjectExpression":
var newTip = {};
applyValue(newTip);
pushStack(/** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
key: null,
tip: newTip,
state: null,
parentIsArray: false
}));
break;
case "ArrayExpression":
var newTip = [];
applyValue(newTip);
pushStack(/** @type {!WebInspector.RelaxedJSONParser.Context} */ ({
key: 0,
tip: newTip,
state: States.ExpectValue,
parentIsArray: true
}));
break;
case "Property":
stackData.state = States.ExpectKey;
break;
case "Literal":
if (stackData.state === States.ExpectKey) {
stackData.key = node.value;
stackData.state = States.ExpectValue;
} else if (stackData.state === States.ExpectValue) {
applyValue(extractValue(node));
return WebInspector.ESTreeWalker.SkipSubtree;
}
break;
case "Identifier":
if (stackData.state === States.ExpectKey) {
stackData.key = /** @type {string} */ (node.name);
stackData.state = States.ExpectValue;
} else if (stackData.state === States.ExpectValue) {
applyValue(extractValue(node));
return WebInspector.ESTreeWalker.SkipSubtree;
}
break;
case "UnaryExpression":
if (stackData.state === States.ExpectValue) {
applyValue(extractValue(node));
return WebInspector.ESTreeWalker.SkipSubtree;
}
break;
case "Program":
case "ExpressionStatement":
break;
default:
if (stackData.state === States.ExpectValue)
applyValue(extractValue(node));
return WebInspector.ESTreeWalker.SkipSubtree;
}
}
/**
* @param {!ESTree.Node} node
*/
function afterVisit(node)
{
if (node.type === "ObjectExpression" || node.type === "ArrayExpression")
popStack();
}
/**
* @param {!ESTree.Node} node
* @return {*}
*/
function extractValue(node)
{
var isNegative = false;
var originalNode = node;
var value;
if (node.type === "UnaryExpression" && (node.operator === "-" || node.operator === "+")) {
if (node.operator === "-")
isNegative = true;
node = /** @type {!ESTree.Node} */ (node.argument);
}
if (node.type === "Literal") {
value = node.value;
} else if (node.type === "Identifier" && Keywords.hasOwnProperty(node.name)) {
value = Keywords[node.name];
} else {
hasExpression = true;
return content.substring(originalNode.start, originalNode.end);
}
if (isNegative) {
if (typeof value !== "number") {
hasExpression = true;
return content.substring(originalNode.start, originalNode.end);
}
value = -(value);
}
return value;
}
}
/**
* @typedef {!{key: (number|string), tip: (!Array|!Object), state: ?WebInspector.RelaxedJSONParser.States, parentIsArray: boolean}}
*/
WebInspector.RelaxedJSONParser.Context;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AllocationProfile.js | 1.19% | (2 / 168) | 0% | (0 / 22) | 0% | (0 / 21) | 1.19% | (2 / 168) | |
| HeapSnapshot.js | 1.45% | (15 / 1037) | 0% | (0 / 320) | 0% | (0 / 175) | 1.45% | (15 / 1035) | |
| HeapSnapshotLoader.js | 0.52% | (1 / 193) | 0% | (0 / 80) | 0% | (0 / 9) | 0.52% | (1 / 193) | |
| HeapSnapshotWorker.js | 50% | (3 / 6) | 100% | (0 / 0) | 0% | (0 / 2) | 50% | (3 / 6) | |
| HeapSnapshotWorkerDispatcher.js | 2.38% | (1 / 42) | 0% | (0 / 10) | 0% | (0 / 4) | 2.38% | (1 / 42) | |
| JSHeapSnapshot.js | 1.98% | (7 / 354) | 0% | (0 / 140) | 0% | (0 / 60) | 1.98% | (7 / 354) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | 2 1 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.AllocationProfile = function(profile, liveObjectStats) { this._strings = profile.strings; this._liveObjectStats = liveObjectStats; this._nextNodeId = 1; this._functionInfos = []; this._idToNode = {}; this._idToTopDownNode = {}; this._collapsedTopNodeIdToFunctionInfo = {}; this._traceTops = null; this._buildFunctionAllocationInfos(profile); this._traceTree = this._buildAllocationTree(profile, liveObjectStats); } WebInspector.AllocationProfile.prototype = { _buildFunctionAllocationInfos: function(profile) { var strings = this._strings; var functionInfoFields = profile.snapshot.meta.trace_function_info_fields; var functionNameOffset = functionInfoFields.indexOf("name"); var scriptNameOffset = functionInfoFields.indexOf("script_name"); var scriptIdOffset = functionInfoFields.indexOf("script_id"); var lineOffset = functionInfoFields.indexOf("line"); var columnOffset = functionInfoFields.indexOf("column"); var functionInfoFieldCount = functionInfoFields.length; var rawInfos = profile.trace_function_infos; var infoLength = rawInfos.length; var functionInfos = this._functionInfos = new Array(infoLength / functionInfoFieldCount); var index = 0; for (var i = 0; i < infoLength; i += functionInfoFieldCount) { functionInfos[index++] = new WebInspector.FunctionAllocationInfo( strings[rawInfos[i + functionNameOffset]], strings[rawInfos[i + scriptNameOffset]], rawInfos[i + scriptIdOffset], rawInfos[i + lineOffset], rawInfos[i + columnOffset]); } }, _buildAllocationTree: function(profile, liveObjectStats) { var traceTreeRaw = profile.trace_tree; var functionInfos = this._functionInfos; var idToTopDownNode = this._idToTopDownNode; var traceNodeFields = profile.snapshot.meta.trace_node_fields; var nodeIdOffset = traceNodeFields.indexOf("id"); var functionInfoIndexOffset = traceNodeFields.indexOf("function_info_index"); var allocationCountOffset = traceNodeFields.indexOf("count"); var allocationSizeOffset = traceNodeFields.indexOf("size"); var childrenOffset = traceNodeFields.indexOf("children"); var nodeFieldCount = traceNodeFields.length; function traverseNode(rawNodeArray, nodeOffset, parent) { var functionInfo = functionInfos[rawNodeArray[nodeOffset + functionInfoIndexOffset]]; var id = rawNodeArray[nodeOffset + nodeIdOffset]; var stats = liveObjectStats[id]; var liveCount = stats ? stats.count : 0; var liveSize = stats ? stats.size : 0; var result = new WebInspector.TopDownAllocationNode( id, functionInfo, rawNodeArray[nodeOffset + allocationCountOffset], rawNodeArray[nodeOffset + allocationSizeOffset], liveCount, liveSize, parent); idToTopDownNode[id] = result; functionInfo.addTraceTopNode(result); var rawChildren = rawNodeArray[nodeOffset + childrenOffset]; for (var i = 0; i < rawChildren.length; i += nodeFieldCount) { result.children.push(traverseNode(rawChildren, i, result)); } return result; } return traverseNode(traceTreeRaw, 0, null); }, /** * @return {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */ serializeTraceTops: function() { if (this._traceTops) return this._traceTops; var result = this._traceTops = []; var functionInfos = this._functionInfos; for (var i = 0; i < functionInfos.length; i++) { var info = functionInfos[i]; if (info.totalCount === 0) continue; var nodeId = this._nextNodeId++; var isRoot = i == 0; result.push(this._serializeNode( nodeId, info, info.totalCount, info.totalSize, info.totalLiveCount, info.totalLiveSize, !isRoot)); this._collapsedTopNodeIdToFunctionInfo[nodeId] = info; } result.sort(function(a, b) { return b.size - a.size; }); return result; }, /** * @param {number} nodeId * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} */ serializeCallers: function(nodeId) { var node = this._ensureBottomUpNode(nodeId); var nodesWithSingleCaller = []; while (node.callers().length === 1) { node = node.callers()[0]; nodesWithSingleCaller.push(this._serializeCaller(node)); } var branchingCallers = []; var callers = node.callers(); for (var i = 0; i < callers.length; i++) { branchingCallers.push(this._serializeCaller(callers[i])); } return new WebInspector.HeapSnapshotCommon.AllocationNodeCallers(nodesWithSingleCaller, branchingCallers); }, /** * @param {number} traceNodeId * @return {!Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} */ serializeAllocationStack: function(traceNodeId) { var node = this._idToTopDownNode[traceNodeId]; var result = []; while (node) { var functionInfo = node.functionInfo; result.push(new WebInspector.HeapSnapshotCommon.AllocationStackFrame( functionInfo.functionName, functionInfo.scriptName, functionInfo.scriptId, functionInfo.line, functionInfo.column )); node = node.parent; } return result; }, /** * @param {number} allocationNodeId * @return {!Array.<number>} */ traceIds: function(allocationNodeId) { return this._ensureBottomUpNode(allocationNodeId).traceTopIds; }, /** * @param {number} nodeId * @return {!WebInspector.BottomUpAllocationNode} */ _ensureBottomUpNode: function(nodeId) { var node = this._idToNode[nodeId]; if (!node) { var functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId]; node = functionInfo.bottomUpRoot(); delete this._collapsedTopNodeIdToFunctionInfo[nodeId]; this._idToNode[nodeId] = node; } return node; }, /** * @param {!WebInspector.BottomUpAllocationNode} node * @return {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode} */ _serializeCaller: function(node) { var callerId = this._nextNodeId++; this._idToNode[callerId] = node; return this._serializeNode( callerId, node.functionInfo, node.allocationCount, node.allocationSize, node.liveCount, node.liveSize, node.hasCallers()); }, /** * @param {number} nodeId * @param {!WebInspector.FunctionAllocationInfo} functionInfo * @param {number} count * @param {number} size * @param {number} liveCount * @param {number} liveSize * @param {boolean} hasChildren * @return {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode} */ _serializeNode: function(nodeId, functionInfo, count, size, liveCount, liveSize, hasChildren) { return new WebInspector.HeapSnapshotCommon.SerializedAllocationNode( nodeId, functionInfo.functionName, functionInfo.scriptName, functionInfo.scriptId, functionInfo.line, functionInfo.column, count, size, liveCount, liveSize, hasChildren ); } } /** * @constructor * @param {number} id * @param {!WebInspector.FunctionAllocationInfo} functionInfo * @param {number} count * @param {number} size * @param {number} liveCount * @param {number} liveSize * @param {?WebInspector.TopDownAllocationNode} parent */ WebInspector.TopDownAllocationNode = function(id, functionInfo, count, size, liveCount, liveSize, parent) { this.id = id; this.functionInfo = functionInfo; this.allocationCount = count; this.allocationSize = size; this.liveCount = liveCount; this.liveSize = liveSize; this.parent = parent; this.children = []; } /** * @constructor * @param {!WebInspector.FunctionAllocationInfo} functionInfo */ WebInspector.BottomUpAllocationNode = function(functionInfo) { this.functionInfo = functionInfo; this.allocationCount = 0; this.allocationSize = 0; this.liveCount = 0; this.liveSize = 0; this.traceTopIds = []; this._callers = []; } WebInspector.BottomUpAllocationNode.prototype = { /** * @param {!WebInspector.TopDownAllocationNode} traceNode * @return {!WebInspector.BottomUpAllocationNode} */ addCaller: function(traceNode) { var functionInfo = traceNode.functionInfo; var result; for (var i = 0; i < this._callers.length; i++) { var caller = this._callers[i]; if (caller.functionInfo === functionInfo) { result = caller; break; } } if (!result) { result = new WebInspector.BottomUpAllocationNode(functionInfo); this._callers.push(result); } return result; }, /** * @return {!Array.<!WebInspector.BottomUpAllocationNode>} */ callers: function() { return this._callers; }, /** * @return {boolean} */ hasCallers: function() { return this._callers.length > 0; } } /** * @constructor * @param {string} functionName * @param {string} scriptName * @param {number} scriptId * @param {number} line * @param {number} column */ WebInspector.FunctionAllocationInfo = function(functionName, scriptName, scriptId, line, column) { this.functionName = functionName; this.scriptName = scriptName; this.scriptId = scriptId; this.line = line; this.column = column; this.totalCount = 0; this.totalSize = 0; this.totalLiveCount = 0; this.totalLiveSize = 0; this._traceTops = []; } WebInspector.FunctionAllocationInfo.prototype = { /** * @param {!WebInspector.TopDownAllocationNode} node */ addTraceTopNode: function(node) { if (node.allocationCount === 0) return; this._traceTops.push(node); this.totalCount += node.allocationCount; this.totalSize += node.allocationSize; this.totalLiveCount += node.liveCount; this.totalLiveSize += node.liveSize; }, /** * @return {?WebInspector.BottomUpAllocationNode} */ bottomUpRoot: function() { if (!this._traceTops.length) return null; if (!this._bottomUpTree) this._buildAllocationTraceTree(); return this._bottomUpTree; }, _buildAllocationTraceTree: function() { this._bottomUpTree = new WebInspector.BottomUpAllocationNode(this); for (var i = 0; i < this._traceTops.length; i++) { var node = this._traceTops[i]; var bottomUpNode = this._bottomUpTree; var count = node.allocationCount; var size = node.allocationSize; var liveCount = node.liveCount; var liveSize = node.liveSize; var traceId = node.id; while (true) { bottomUpNode.allocationCount += count; bottomUpNode.allocationSize += size; bottomUpNode.liveCount += liveCount; bottomUpNode.liveSize += liveSize; bottomUpNode.traceTopIds.push(traceId); node = node.parent; if (node === null) { break; } bottomUpNode = bottomUpNode.addCaller(node); } } } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.HeapSnapshotItem = function() { } WebInspector.HeapSnapshotItem.prototype = { /** * @return {number} */ itemIndex: function() { }, /** * @return {!Object} */ serialize: function() { } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItem} * @param {!WebInspector.HeapSnapshot} snapshot * @param {number=} edgeIndex */ WebInspector.HeapSnapshotEdge = function(snapshot, edgeIndex) { this._snapshot = snapshot; this._edges = snapshot.containmentEdges; this.edgeIndex = edgeIndex || 0; } WebInspector.HeapSnapshotEdge.prototype = { /** * @return {!WebInspector.HeapSnapshotEdge} */ clone: function() { return new WebInspector.HeapSnapshotEdge(this._snapshot, this.edgeIndex); }, /** * @return {boolean} */ hasStringName: function() { throw new Error("Not implemented"); }, /** * @return {string} */ name: function() { throw new Error("Not implemented"); }, /** * @return {!WebInspector.HeapSnapshotNode} */ node: function() { return this._snapshot.createNode(this.nodeIndex()); }, /** * @return {number} */ nodeIndex: function() { return this._edges[this.edgeIndex + this._snapshot._edgeToNodeOffset]; }, /** * @override * @return {string} */ toString: function() { return "HeapSnapshotEdge: " + this.name(); }, /** * @return {string} */ type: function() { return this._snapshot._edgeTypes[this._type()]; }, /** * @override * @return {number} */ itemIndex: function() { return this.edgeIndex; }, /** * @override * @return {!WebInspector.HeapSnapshotCommon.Edge} */ serialize: function() { return new WebInspector.HeapSnapshotCommon.Edge(this.name(), this.node().serialize(), this.type(), this.edgeIndex); }, _type: function() { return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset]; } }; /** * @interface */ WebInspector.HeapSnapshotItemIterator = function() { } WebInspector.HeapSnapshotItemIterator.prototype = { /** * @return {boolean} */ hasNext: function() { }, /** * @return {!WebInspector.HeapSnapshotItem} */ item: function() { }, next: function() { } }; /** * @interface */ WebInspector.HeapSnapshotItemIndexProvider = function() { } WebInspector.HeapSnapshotItemIndexProvider.prototype = { /** * @param {number} newIndex * @return {!WebInspector.HeapSnapshotItem} */ itemForIndex: function(newIndex) { }, }; /** * @constructor * @implements {WebInspector.HeapSnapshotItemIndexProvider} * @param {!WebInspector.HeapSnapshot} snapshot */ WebInspector.HeapSnapshotNodeIndexProvider = function(snapshot) { this._node = snapshot.createNode(); } WebInspector.HeapSnapshotNodeIndexProvider.prototype = { /** * @override * @param {number} index * @return {!WebInspector.HeapSnapshotNode} */ itemForIndex: function(index) { this._node.nodeIndex = index; return this._node; } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItemIndexProvider} * @param {!WebInspector.HeapSnapshot} snapshot */ WebInspector.HeapSnapshotEdgeIndexProvider = function(snapshot) { this._edge = snapshot.createEdge(0); } WebInspector.HeapSnapshotEdgeIndexProvider.prototype = { /** * @override * @param {number} index * @return {!WebInspector.HeapSnapshotEdge} */ itemForIndex: function(index) { this._edge.edgeIndex = index; return this._edge; } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItemIndexProvider} * @param {!WebInspector.HeapSnapshot} snapshot */ WebInspector.HeapSnapshotRetainerEdgeIndexProvider = function(snapshot) { this._retainerEdge = snapshot.createRetainingEdge(0); } WebInspector.HeapSnapshotRetainerEdgeIndexProvider.prototype = { /** * @override * @param {number} index * @return {!WebInspector.HeapSnapshotRetainerEdge} */ itemForIndex: function(index) { this._retainerEdge.setRetainerIndex(index); return this._retainerEdge; } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItemIterator} * @param {!WebInspector.HeapSnapshotNode} node */ WebInspector.HeapSnapshotEdgeIterator = function(node) { this._sourceNode = node; this.edge = node._snapshot.createEdge(node.edgeIndexesStart()); } WebInspector.HeapSnapshotEdgeIterator.prototype = { /** * @override * @return {boolean} */ hasNext: function() { return this.edge.edgeIndex < this._sourceNode.edgeIndexesEnd(); }, /** * @override * @return {!WebInspector.HeapSnapshotEdge} */ item: function() { return this.edge; }, /** * @override */ next: function() { this.edge.edgeIndex += this.edge._snapshot._edgeFieldsCount; } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItem} * @param {!WebInspector.HeapSnapshot} snapshot * @param {number} retainerIndex */ WebInspector.HeapSnapshotRetainerEdge = function(snapshot, retainerIndex) { this._snapshot = snapshot; this.setRetainerIndex(retainerIndex); } WebInspector.HeapSnapshotRetainerEdge.prototype = { /** * @return {!WebInspector.HeapSnapshotRetainerEdge} */ clone: function() { return new WebInspector.HeapSnapshotRetainerEdge(this._snapshot, this.retainerIndex()); }, /** * @return {boolean} */ hasStringName: function() { return this._edge().hasStringName(); }, /** * @return {string} */ name: function() { return this._edge().name(); }, /** * @return {!WebInspector.HeapSnapshotNode} */ node: function() { return this._node(); }, /** * @return {number} */ nodeIndex: function() { return this._retainingNodeIndex; }, /** * @return {number} */ retainerIndex: function() { return this._retainerIndex; }, /** * @param {number} retainerIndex */ setRetainerIndex: function(retainerIndex) { if (retainerIndex === this._retainerIndex) return; this._retainerIndex = retainerIndex; this._globalEdgeIndex = this._snapshot._retainingEdges[retainerIndex]; this._retainingNodeIndex = this._snapshot._retainingNodes[retainerIndex]; this._edgeInstance = null; this._nodeInstance = null; }, /** * @param {number} edgeIndex */ set edgeIndex(edgeIndex) { this.setRetainerIndex(edgeIndex); }, _node: function() { if (!this._nodeInstance) this._nodeInstance = this._snapshot.createNode(this._retainingNodeIndex); return this._nodeInstance; }, _edge: function() { if (!this._edgeInstance) this._edgeInstance = this._snapshot.createEdge(this._globalEdgeIndex); return this._edgeInstance; }, /** * @override * @return {string} */ toString: function() { return this._edge().toString(); }, /** * @override * @return {number} */ itemIndex: function() { return this._retainerIndex; }, /** * @override * @return {!WebInspector.HeapSnapshotCommon.Edge} */ serialize: function() { return new WebInspector.HeapSnapshotCommon.Edge(this.name(), this.node().serialize(), this.type(), this._globalEdgeIndex); }, /** * @return {string} */ type: function() { return this._edge().type(); } } /** * @constructor * @implements {WebInspector.HeapSnapshotItemIterator} * @param {!WebInspector.HeapSnapshotNode} retainedNode */ WebInspector.HeapSnapshotRetainerEdgeIterator = function(retainedNode) { var snapshot = retainedNode._snapshot; var retainedNodeOrdinal = retainedNode.ordinal(); var retainerIndex = snapshot._firstRetainerIndex[retainedNodeOrdinal]; this._retainersEnd = snapshot._firstRetainerIndex[retainedNodeOrdinal + 1]; this.retainer = snapshot.createRetainingEdge(retainerIndex); } WebInspector.HeapSnapshotRetainerEdgeIterator.prototype = { /** * @override * @return {boolean} */ hasNext: function() { return this.retainer.retainerIndex() < this._retainersEnd; }, /** * @override * @return {!WebInspector.HeapSnapshotRetainerEdge} */ item: function() { return this.retainer; }, /** * @override */ next: function() { this.retainer.setRetainerIndex(this.retainer.retainerIndex() + 1); } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItem} * @param {!WebInspector.HeapSnapshot} snapshot * @param {number=} nodeIndex */ WebInspector.HeapSnapshotNode = function(snapshot, nodeIndex) { this._snapshot = snapshot; this.nodeIndex = nodeIndex || 0; } WebInspector.HeapSnapshotNode.prototype = { /** * @return {number} */ distance: function() { return this._snapshot._nodeDistances[this.nodeIndex / this._snapshot._nodeFieldCount]; }, /** * @return {string} */ className: function() { throw new Error("Not implemented"); }, /** * @return {number} */ classIndex: function() { throw new Error("Not implemented"); }, /** * @return {number} */ dominatorIndex: function() { var nodeFieldCount = this._snapshot._nodeFieldCount; return this._snapshot._dominatorsTree[this.nodeIndex / this._snapshot._nodeFieldCount] * nodeFieldCount; }, /** * @return {!WebInspector.HeapSnapshotEdgeIterator} */ edges: function() { return new WebInspector.HeapSnapshotEdgeIterator(this); }, /** * @return {number} */ edgesCount: function() { return (this.edgeIndexesEnd() - this.edgeIndexesStart()) / this._snapshot._edgeFieldsCount; }, /** * @return {number} */ id: function() { throw new Error("Not implemented"); }, /** * @return {boolean} */ isRoot: function() { return this.nodeIndex === this._snapshot._rootNodeIndex; }, /** * @return {string} */ name: function() { return this._snapshot.strings[this._name()]; }, /** * @return {number} */ retainedSize: function() { return this._snapshot._retainedSizes[this.ordinal()]; }, /** * @return {!WebInspector.HeapSnapshotRetainerEdgeIterator} */ retainers: function() { return new WebInspector.HeapSnapshotRetainerEdgeIterator(this); }, /** * @return {number} */ retainersCount: function() { var snapshot = this._snapshot; var ordinal = this.ordinal(); return snapshot._firstRetainerIndex[ordinal + 1] - snapshot._firstRetainerIndex[ordinal]; }, /** * @return {number} */ selfSize: function() { var snapshot = this._snapshot; return snapshot.nodes[this.nodeIndex + snapshot._nodeSelfSizeOffset]; }, /** * @return {string} */ type: function() { return this._snapshot._nodeTypes[this._type()]; }, /** * @return {number} */ traceNodeId: function() { var snapshot = this._snapshot; return snapshot.nodes[this.nodeIndex + snapshot._nodeTraceNodeIdOffset]; }, /** * @override * @return {number} */ itemIndex: function() { return this.nodeIndex; }, /** * @override * @return {!WebInspector.HeapSnapshotCommon.Node} */ serialize: function() { return new WebInspector.HeapSnapshotCommon.Node(this.id(), this.name(), this.distance(), this.nodeIndex, this.retainedSize(), this.selfSize(), this.type()); }, /** * @return {number} */ _name: function() { var snapshot = this._snapshot; return snapshot.nodes[this.nodeIndex + snapshot._nodeNameOffset]; }, /** * @return {number} */ edgeIndexesStart: function() { return this._snapshot._firstEdgeIndexes[this.ordinal()]; }, /** * @return {number} */ edgeIndexesEnd: function() { return this._snapshot._firstEdgeIndexes[this.ordinal() + 1]; }, /** * @return {number} */ ordinal: function() { return this.nodeIndex / this._snapshot._nodeFieldCount; }, /** * @return {number} */ _nextNodeIndex: function() { return this.nodeIndex + this._snapshot._nodeFieldCount; }, /** * @return {number} */ _type: function() { var snapshot = this._snapshot; return snapshot.nodes[this.nodeIndex + snapshot._nodeTypeOffset]; } }; /** * @constructor * @implements {WebInspector.HeapSnapshotItemIterator} * @param {!WebInspector.HeapSnapshotNode} node */ WebInspector.HeapSnapshotNodeIterator = function(node) { this.node = node; this._nodesLength = node._snapshot.nodes.length; } WebInspector.HeapSnapshotNodeIterator.prototype = { /** * @override * @return {boolean} */ hasNext: function() { return this.node.nodeIndex < this._nodesLength; }, /** * @override * @return {!WebInspector.HeapSnapshotNode} */ item: function() { return this.node; }, /** * @override */ next: function() { this.node.nodeIndex = this.node._nextNodeIndex(); } } /** * @constructor * @implements {WebInspector.HeapSnapshotItemIterator} * @param {!WebInspector.HeapSnapshotItemIndexProvider} itemProvider * @param {!Array.<number>|!Uint32Array} indexes */ WebInspector.HeapSnapshotIndexRangeIterator = function(itemProvider, indexes) { this._itemProvider = itemProvider; this._indexes = indexes; this._position = 0; } WebInspector.HeapSnapshotIndexRangeIterator.prototype = { /** * @override * @return {boolean} */ hasNext: function() { return this._position < this._indexes.length; }, /** * @override * @return {!WebInspector.HeapSnapshotItem} */ item: function() { var index = this._indexes[this._position]; return this._itemProvider.itemForIndex(index); }, /** * @override */ next: function() { ++this._position; } } /** * @constructor * @implements {WebInspector.HeapSnapshotItemIterator} * @param {!WebInspector.HeapSnapshotItemIterator} iterator * @param {function(!WebInspector.HeapSnapshotItem):boolean=} filter */ WebInspector.HeapSnapshotFilteredIterator = function(iterator, filter) { this._iterator = iterator; this._filter = filter; this._skipFilteredItems(); } WebInspector.HeapSnapshotFilteredIterator.prototype = { /** * @override * @return {boolean} */ hasNext: function() { return this._iterator.hasNext(); }, /** * @override * @return {!WebInspector.HeapSnapshotItem} */ item: function() { return this._iterator.item(); }, /** * @override */ next: function() { this._iterator.next(); this._skipFilteredItems(); }, _skipFilteredItems: function() { while (this._iterator.hasNext() && !this._filter(this._iterator.item())) { this._iterator.next(); } } } /** * @param {!WebInspector.HeapSnapshotWorkerDispatcher=} dispatcher * @constructor */ WebInspector.HeapSnapshotProgress = function(dispatcher) { this._dispatcher = dispatcher; } WebInspector.HeapSnapshotProgress.prototype = { /** * @param {string} status */ updateStatus: function(status) { this._sendUpdateEvent(WebInspector.UIString(status)); }, /** * @param {string} title * @param {number} value * @param {number} total */ updateProgress: function(title, value, total) { var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0); this._sendUpdateEvent(WebInspector.UIString(title, percentValue)); }, /** * @param {string} error */ reportProblem: function(error) { // May be undefined in tests. if (this._dispatcher) this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot, error); }, /** * @param {string} text */ _sendUpdateEvent: function(text) { // May be undefined in tests. if (this._dispatcher) this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgressEvent.Update, text); } } /** * @param {string} title * @constructor */ WebInspector.HeapSnapshotProblemReport = function(title) { this._errors = [title]; } WebInspector.HeapSnapshotProblemReport.prototype = { /** * @param {string} error */ addError: function(error) { if (this._errors.length > 100) return; this._errors.push(error); }, /** * @override * @return {string} */ toString: function() { return this._errors.join("\n "); } } /** * @param {!Object} profile * @param {!WebInspector.HeapSnapshotProgress} progress * @constructor */ WebInspector.HeapSnapshot = function(profile, progress) { /** @type {!Uint32Array} */ this.nodes = profile.nodes; /** @type {!Uint32Array} */ this.containmentEdges = profile.edges; /** @type {!HeapSnapshotMetainfo} */ this._metaNode = profile.snapshot.meta; /** @type {!Array.<number>} */ this._rawSamples = profile.samples; /** @type {?WebInspector.HeapSnapshotCommon.Samples} */ this._samples = null; /** @type {!Array.<string>} */ this.strings = profile.strings; this._progress = progress; this._noDistance = -5; this._rootNodeIndex = 0; if (profile.snapshot.root_index) this._rootNodeIndex = profile.snapshot.root_index; this._snapshotDiffs = {}; this._aggregatesForDiff = null; this._aggregates = {}; this._aggregatesSortedFlags = {}; this._init(); if (profile.snapshot.trace_function_count) { this._progress.updateStatus("Building allocation statistics\u2026"); var nodes = this.nodes; var nodesLength = nodes.length; var nodeFieldCount = this._nodeFieldCount; var node = this.rootNode(); var liveObjects = {}; for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) { node.nodeIndex = nodeIndex; var traceNodeId = node.traceNodeId(); var stats = liveObjects[traceNodeId]; if (!stats) liveObjects[traceNodeId] = stats = { count: 0, size: 0, ids: [] }; stats.count++; stats.size += node.selfSize(); stats.ids.push(node.id()); } this._allocationProfile = new WebInspector.AllocationProfile(profile, liveObjects); this._progress.updateStatus("Done"); } } /** * @constructor */ function HeapSnapshotMetainfo() { // New format. this.node_fields = []; this.node_types = []; this.edge_fields = []; this.edge_types = []; this.trace_function_info_fields = []; this.trace_node_fields = []; this.sample_fields = []; this.type_strings = {}; } /** * @constructor */ function HeapSnapshotHeader() { // New format. this.title = ""; this.meta = new HeapSnapshotMetainfo(); this.node_count = 0; this.edge_count = 0; this.trace_function_count = 0; } WebInspector.HeapSnapshot.prototype = { _init: function() { var meta = this._metaNode; this._nodeTypeOffset = meta.node_fields.indexOf("type"); this._nodeNameOffset = meta.node_fields.indexOf("name"); this._nodeIdOffset = meta.node_fields.indexOf("id"); this._nodeSelfSizeOffset = meta.node_fields.indexOf("self_size"); this._nodeEdgeCountOffset = meta.node_fields.indexOf("edge_count"); this._nodeTraceNodeIdOffset = meta.node_fields.indexOf("trace_node_id"); this._nodeFieldCount = meta.node_fields.length; this._nodeTypes = meta.node_types[this._nodeTypeOffset]; this._nodeArrayType = this._nodeTypes.indexOf("array"); this._nodeHiddenType = this._nodeTypes.indexOf("hidden"); this._nodeObjectType = this._nodeTypes.indexOf("object"); this._nodeNativeType = this._nodeTypes.indexOf("native"); this._nodeConsStringType = this._nodeTypes.indexOf("concatenated string"); this._nodeSlicedStringType = this._nodeTypes.indexOf("sliced string"); this._nodeCodeType = this._nodeTypes.indexOf("code"); this._nodeSyntheticType = this._nodeTypes.indexOf("synthetic"); this._edgeFieldsCount = meta.edge_fields.length; this._edgeTypeOffset = meta.edge_fields.indexOf("type"); this._edgeNameOffset = meta.edge_fields.indexOf("name_or_index"); this._edgeToNodeOffset = meta.edge_fields.indexOf("to_node"); this._edgeTypes = meta.edge_types[this._edgeTypeOffset]; this._edgeTypes.push("invisible"); this._edgeElementType = this._edgeTypes.indexOf("element"); this._edgeHiddenType = this._edgeTypes.indexOf("hidden"); this._edgeInternalType = this._edgeTypes.indexOf("internal"); this._edgeShortcutType = this._edgeTypes.indexOf("shortcut"); this._edgeWeakType = this._edgeTypes.indexOf("weak"); this._edgeInvisibleType = this._edgeTypes.indexOf("invisible"); this.nodeCount = this.nodes.length / this._nodeFieldCount; this._edgeCount = this.containmentEdges.length / this._edgeFieldsCount; this._retainedSizes = new Float64Array(this.nodeCount); this._firstEdgeIndexes = new Uint32Array(this.nodeCount + 1); this._retainingNodes = new Uint32Array(this._edgeCount); this._retainingEdges = new Uint32Array(this._edgeCount); this._firstRetainerIndex = new Uint32Array(this.nodeCount + 1); this._nodeDistances = new Int32Array(this.nodeCount); this._firstDominatedNodeIndex = new Uint32Array(this.nodeCount + 1); this._dominatedNodes = new Uint32Array(this.nodeCount - 1); this._progress.updateStatus("Building edge indexes\u2026"); this._buildEdgeIndexes(); this._progress.updateStatus("Building retainers\u2026"); this._buildRetainers(); this._progress.updateStatus("Calculating node flags\u2026"); this._calculateFlags(); this._progress.updateStatus("Calculating distances\u2026"); this.calculateDistances(); this._progress.updateStatus("Building postorder index\u2026"); var result = this._buildPostOrderIndex(); // Actually it is array that maps node ordinal number to dominator node ordinal number. this._progress.updateStatus("Building dominator tree\u2026"); this._dominatorsTree = this._buildDominatorTree(result.postOrderIndex2NodeOrdinal, result.nodeOrdinal2PostOrderIndex); this._progress.updateStatus("Calculating retained sizes\u2026"); this._calculateRetainedSizes(result.postOrderIndex2NodeOrdinal); this._progress.updateStatus("Buiding dominated nodes\u2026"); this._buildDominatedNodes(); this._progress.updateStatus("Calculating statistics\u2026"); this._calculateStatistics(); this._progress.updateStatus("Calculating samples\u2026"); this._buildSamples(); this._progress.updateStatus("Finished processing."); }, _buildEdgeIndexes: function() { var nodes = this.nodes; var nodeCount = this.nodeCount; var firstEdgeIndexes = this._firstEdgeIndexes; var nodeFieldCount = this._nodeFieldCount; var edgeFieldsCount = this._edgeFieldsCount; var nodeEdgeCountOffset = this._nodeEdgeCountOffset; firstEdgeIndexes[nodeCount] = this.containmentEdges.length; for (var nodeOrdinal = 0, edgeIndex = 0; nodeOrdinal < nodeCount; ++nodeOrdinal) { firstEdgeIndexes[nodeOrdinal] = edgeIndex; edgeIndex += nodes[nodeOrdinal * nodeFieldCount + nodeEdgeCountOffset] * edgeFieldsCount; } }, _buildRetainers: function() { var retainingNodes = this._retainingNodes; var retainingEdges = this._retainingEdges; // Index of the first retainer in the _retainingNodes and _retainingEdges // arrays. Addressed by retained node index. var firstRetainerIndex = this._firstRetainerIndex; var containmentEdges = this.containmentEdges; var edgeFieldsCount = this._edgeFieldsCount; var nodeFieldCount = this._nodeFieldCount; var edgeToNodeOffset = this._edgeToNodeOffset; var firstEdgeIndexes = this._firstEdgeIndexes; var nodeCount = this.nodeCount; for (var toNodeFieldIndex = edgeToNodeOffset, l = containmentEdges.length; toNodeFieldIndex < l; toNodeFieldIndex += edgeFieldsCount) { var toNodeIndex = containmentEdges[toNodeFieldIndex]; if (toNodeIndex % nodeFieldCount) throw new Error("Invalid toNodeIndex " + toNodeIndex); ++firstRetainerIndex[toNodeIndex / nodeFieldCount]; } for (var i = 0, firstUnusedRetainerSlot = 0; i < nodeCount; i++) { var retainersCount = firstRetainerIndex[i]; firstRetainerIndex[i] = firstUnusedRetainerSlot; retainingNodes[firstUnusedRetainerSlot] = retainersCount; firstUnusedRetainerSlot += retainersCount; } firstRetainerIndex[nodeCount] = retainingNodes.length; var nextNodeFirstEdgeIndex = firstEdgeIndexes[0]; for (var srcNodeOrdinal = 0; srcNodeOrdinal < nodeCount; ++srcNodeOrdinal) { var firstEdgeIndex = nextNodeFirstEdgeIndex; nextNodeFirstEdgeIndex = firstEdgeIndexes[srcNodeOrdinal + 1]; var srcNodeIndex = srcNodeOrdinal * nodeFieldCount; for (var edgeIndex = firstEdgeIndex; edgeIndex < nextNodeFirstEdgeIndex; edgeIndex += edgeFieldsCount) { var toNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset]; if (toNodeIndex % nodeFieldCount) throw new Error("Invalid toNodeIndex " + toNodeIndex); var firstRetainerSlotIndex = firstRetainerIndex[toNodeIndex / nodeFieldCount]; var nextUnusedRetainerSlotIndex = firstRetainerSlotIndex + (--retainingNodes[firstRetainerSlotIndex]); retainingNodes[nextUnusedRetainerSlotIndex] = srcNodeIndex; retainingEdges[nextUnusedRetainerSlotIndex] = edgeIndex; } } }, /** * @param {number=} nodeIndex */ createNode: function(nodeIndex) { throw new Error("Not implemented"); }, /** * @param {number} edgeIndex * @return {!WebInspector.JSHeapSnapshotEdge} */ createEdge: function(edgeIndex) { throw new Error("Not implemented"); }, /** * @param {number} retainerIndex * @return {!WebInspector.JSHeapSnapshotRetainerEdge} */ createRetainingEdge: function(retainerIndex) { throw new Error("Not implemented"); }, _allNodes: function() { return new WebInspector.HeapSnapshotNodeIterator(this.rootNode()); }, /** * @return {!WebInspector.HeapSnapshotNode} */ rootNode: function() { return this.createNode(this._rootNodeIndex); }, get rootNodeIndex() { return this._rootNodeIndex; }, get totalSize() { return this.rootNode().retainedSize(); }, _getDominatedIndex: function(nodeIndex) { if (nodeIndex % this._nodeFieldCount) throw new Error("Invalid nodeIndex: " + nodeIndex); return this._firstDominatedNodeIndex[nodeIndex / this._nodeFieldCount]; }, /** * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter * @return {undefined|function(!WebInspector.HeapSnapshotNode):boolean} */ _createFilter: function(nodeFilter) { var minNodeId = nodeFilter.minNodeId; var maxNodeId = nodeFilter.maxNodeId; var allocationNodeId = nodeFilter.allocationNodeId; var filter; if (typeof allocationNodeId === "number") { filter = this._createAllocationStackFilter(allocationNodeId); filter.key = "AllocationNodeId: " + allocationNodeId; } else if (typeof minNodeId === "number" && typeof maxNodeId === "number") { filter = this._createNodeIdFilter(minNodeId, maxNodeId); filter.key = "NodeIdRange: " + minNodeId + ".." + maxNodeId; } return filter; }, /** * @param {!WebInspector.HeapSnapshotCommon.SearchConfig} searchConfig * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter * @return {!Array.<number>} */ search: function(searchConfig, nodeFilter) { var query = searchConfig.query; function filterString(matchedStringIndexes, string, index) { if (string.indexOf(query) !== -1) matchedStringIndexes.add(index); return matchedStringIndexes; } var regexp = searchConfig.isRegex ? new RegExp(query) : createPlainTextSearchRegex(query, "i"); function filterRegexp(matchedStringIndexes, string, index) { if (regexp.test(string)) matchedStringIndexes.add(index); return matchedStringIndexes; } var stringFilter = (searchConfig.isRegex || !searchConfig.caseSensitive) ? filterRegexp : filterString; var stringIndexes = this.strings.reduce(stringFilter, new Set()); if (!stringIndexes.size) return []; var filter = this._createFilter(nodeFilter); var nodeIds = []; var nodesLength = this.nodes.length; var nodes = this.nodes; var nodeNameOffset = this._nodeNameOffset; var nodeIdOffset = this._nodeIdOffset; var nodeFieldCount = this._nodeFieldCount; var node = this.rootNode(); for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) { node.nodeIndex = nodeIndex; if (filter && !filter(node)) continue; if (stringIndexes.has(nodes[nodeIndex + nodeNameOffset])) nodeIds.push(nodes[nodeIndex + nodeIdOffset]); } return nodeIds; }, /** * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>} */ aggregatesWithFilter: function(nodeFilter) { var filter = this._createFilter(nodeFilter); var key = filter ? filter.key : "allObjects"; return this.aggregates(false, key, filter); }, /** * @param {number} minNodeId * @param {number} maxNodeId * @return {function(!WebInspector.HeapSnapshotNode):boolean} */ _createNodeIdFilter: function(minNodeId, maxNodeId) { /** * @param {!WebInspector.HeapSnapshotNode} node * @return {boolean} */ function nodeIdFilter(node) { var id = node.id(); return id > minNodeId && id <= maxNodeId; } return nodeIdFilter; }, /** * @param {number} bottomUpAllocationNodeId * @return {function(!WebInspector.HeapSnapshotNode):boolean|undefined} */ _createAllocationStackFilter: function(bottomUpAllocationNodeId) { var traceIds = this._allocationProfile.traceIds(bottomUpAllocationNodeId); if (!traceIds.length) return undefined; var set = {}; for (var i = 0; i < traceIds.length; i++) set[traceIds[i]] = true; /** * @param {!WebInspector.HeapSnapshotNode} node * @return {boolean} */ function traceIdFilter(node) { return !!set[node.traceNodeId()]; }; return traceIdFilter; }, /** * @param {boolean} sortedIndexes * @param {string=} key * @param {function(!WebInspector.HeapSnapshotNode):boolean=} filter * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>} */ aggregates: function(sortedIndexes, key, filter) { var aggregatesByClassName = key && this._aggregates[key]; if (!aggregatesByClassName) { var aggregates = this._buildAggregates(filter); this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex, filter); aggregatesByClassName = aggregates.aggregatesByClassName; if (key) this._aggregates[key] = aggregatesByClassName; } if (sortedIndexes && (!key || !this._aggregatesSortedFlags[key])) { this._sortAggregateIndexes(aggregatesByClassName); if (key) this._aggregatesSortedFlags[key] = sortedIndexes; } return aggregatesByClassName; }, /** * @return {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */ allocationTracesTops: function() { return this._allocationProfile.serializeTraceTops(); }, /** * @param {number} nodeId * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} */ allocationNodeCallers: function(nodeId) { return this._allocationProfile.serializeCallers(nodeId); }, /** * @param {number} nodeIndex * @return {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} */ allocationStack: function(nodeIndex) { var node = this.createNode(nodeIndex); var allocationNodeId = node.traceNodeId(); if (!allocationNodeId) return null; return this._allocationProfile.serializeAllocationStack(allocationNodeId); }, /** * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.AggregateForDiff>} */ aggregatesForDiff: function() { if (this._aggregatesForDiff) return this._aggregatesForDiff; var aggregatesByClassName = this.aggregates(true, "allObjects"); this._aggregatesForDiff = {}; var node = this.createNode(); for (var className in aggregatesByClassName) { var aggregate = aggregatesByClassName[className]; var indexes = aggregate.idxs; var ids = new Array(indexes.length); var selfSizes = new Array(indexes.length); for (var i = 0; i < indexes.length; i++) { node.nodeIndex = indexes[i]; ids[i] = node.id(); selfSizes[i] = node.selfSize(); } this._aggregatesForDiff[className] = { indexes: indexes, ids: ids, selfSizes: selfSizes }; } return this._aggregatesForDiff; }, /** * @protected * @param {!WebInspector.HeapSnapshotNode} node * @return {boolean} */ isUserRoot: function(node) { return true; }, /** * @param {function(!WebInspector.HeapSnapshotNode)} action * @param {boolean=} userRootsOnly */ forEachRoot: function(action, userRootsOnly) { for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { var node = iter.edge.node(); if (!userRootsOnly || this.isUserRoot(node)) action(node); } }, /** * @param {function(!WebInspector.HeapSnapshotNode,!WebInspector.HeapSnapshotEdge):boolean=} filter */ calculateDistances: function(filter) { var nodeCount = this.nodeCount; var distances = this._nodeDistances; var noDistance = this._noDistance; for (var i = 0; i < nodeCount; ++i) distances[i] = noDistance; var nodesToVisit = new Uint32Array(this.nodeCount); var nodesToVisitLength = 0; /** * @param {number} distance * @param {!WebInspector.HeapSnapshotNode} node */ function enqueueNode(distance, node) { var ordinal = node.ordinal(); if (distances[ordinal] !== noDistance) return; distances[ordinal] = distance; nodesToVisit[nodesToVisitLength++] = node.nodeIndex; } this.forEachRoot(enqueueNode.bind(null, 1), true); this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); // bfs for the rest of objects nodesToVisitLength = 0; this.forEachRoot(enqueueNode.bind(null, WebInspector.HeapSnapshotCommon.baseSystemDistance), false); this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); }, /** * @param {!Uint32Array} nodesToVisit * @param {number} nodesToVisitLength * @param {!Int32Array} distances * @param {function(!WebInspector.HeapSnapshotNode,!WebInspector.HeapSnapshotEdge):boolean=} filter */ _bfs: function(nodesToVisit, nodesToVisitLength, distances, filter) { // Preload fields into local variables for better performance. var edgeFieldsCount = this._edgeFieldsCount; var nodeFieldCount = this._nodeFieldCount; var containmentEdges = this.containmentEdges; var firstEdgeIndexes = this._firstEdgeIndexes; var edgeToNodeOffset = this._edgeToNodeOffset; var edgeTypeOffset = this._edgeTypeOffset; var nodeCount = this.nodeCount; var edgeWeakType = this._edgeWeakType; var noDistance = this._noDistance; var index = 0; var edge = this.createEdge(0); var node = this.createNode(0); while (index < nodesToVisitLength) { var nodeIndex = nodesToVisit[index++]; // shift generates too much garbage. var nodeOrdinal = nodeIndex / nodeFieldCount; var distance = distances[nodeOrdinal] + 1; var firstEdgeIndex = firstEdgeIndexes[nodeOrdinal]; var edgesEnd = firstEdgeIndexes[nodeOrdinal + 1]; node.nodeIndex = nodeIndex; for (var edgeIndex = firstEdgeIndex; edgeIndex < edgesEnd; edgeIndex += edgeFieldsCount) { var edgeType = containmentEdges[edgeIndex + edgeTypeOffset]; if (edgeType === edgeWeakType) continue; var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset]; var childNodeOrdinal = childNodeIndex / nodeFieldCount; if (distances[childNodeOrdinal] !== noDistance) continue; edge.edgeIndex = edgeIndex; if (filter && !filter(node, edge)) continue; distances[childNodeOrdinal] = distance; nodesToVisit[nodesToVisitLength++] = childNodeIndex; } } if (nodesToVisitLength > nodeCount) throw new Error("BFS failed. Nodes to visit (" + nodesToVisitLength + ") is more than nodes count (" + nodeCount + ")"); }, _buildAggregates: function(filter) { var aggregates = {}; var aggregatesByClassName = {}; var classIndexes = []; var nodes = this.nodes; var mapAndFlag = this.userObjectsMapAndFlag(); var flags = mapAndFlag ? mapAndFlag.map : null; var flag = mapAndFlag ? mapAndFlag.flag : 0; var nodesLength = nodes.length; var nodeNativeType = this._nodeNativeType; var nodeFieldCount = this._nodeFieldCount; var selfSizeOffset = this._nodeSelfSizeOffset; var nodeTypeOffset = this._nodeTypeOffset; var node = this.rootNode(); var nodeDistances = this._nodeDistances; for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) { var nodeOrdinal = nodeIndex / nodeFieldCount; if (flags && !(flags[nodeOrdinal] & flag)) continue; node.nodeIndex = nodeIndex; if (filter && !filter(node)) continue; var selfSize = nodes[nodeIndex + selfSizeOffset]; if (!selfSize && nodes[nodeIndex + nodeTypeOffset] !== nodeNativeType) continue; var classIndex = node.classIndex(); if (!(classIndex in aggregates)) { var nodeType = node.type(); var nameMatters = nodeType === "object" || nodeType === "native"; var value = { count: 1, distance: nodeDistances[nodeOrdinal], self: selfSize, maxRet: 0, type: nodeType, name: nameMatters ? node.name() : null, idxs: [nodeIndex] }; aggregates[classIndex] = value; classIndexes.push(classIndex); aggregatesByClassName[node.className()] = value; } else { var clss = aggregates[classIndex]; clss.distance = Math.min(clss.distance, nodeDistances[nodeOrdinal]); ++clss.count; clss.self += selfSize; clss.idxs.push(nodeIndex); } } // Shave off provisionally allocated space. for (var i = 0, l = classIndexes.length; i < l; ++i) { var classIndex = classIndexes[i]; aggregates[classIndex].idxs = aggregates[classIndex].idxs.slice(); } return {aggregatesByClassName: aggregatesByClassName, aggregatesByClassIndex: aggregates}; }, _calculateClassesRetainedSize: function(aggregates, filter) { var rootNodeIndex = this._rootNodeIndex; var node = this.createNode(rootNodeIndex); var list = [rootNodeIndex]; var sizes = [-1]; var classes = []; var seenClassNameIndexes = {}; var nodeFieldCount = this._nodeFieldCount; var nodeTypeOffset = this._nodeTypeOffset; var nodeNativeType = this._nodeNativeType; var dominatedNodes = this._dominatedNodes; var nodes = this.nodes; var mapAndFlag = this.userObjectsMapAndFlag(); var flags = mapAndFlag ? mapAndFlag.map : null; var flag = mapAndFlag ? mapAndFlag.flag : 0; var firstDominatedNodeIndex = this._firstDominatedNodeIndex; while (list.length) { var nodeIndex = list.pop(); node.nodeIndex = nodeIndex; var classIndex = node.classIndex(); var seen = !!seenClassNameIndexes[classIndex]; var nodeOrdinal = nodeIndex / nodeFieldCount; var dominatedIndexFrom = firstDominatedNodeIndex[nodeOrdinal]; var dominatedIndexTo = firstDominatedNodeIndex[nodeOrdinal + 1]; if (!seen && (!flags || (flags[nodeOrdinal] & flag)) && (!filter || filter(node)) && (node.selfSize() || nodes[nodeIndex + nodeTypeOffset] === nodeNativeType) ) { aggregates[classIndex].maxRet += node.retainedSize(); if (dominatedIndexFrom !== dominatedIndexTo) { seenClassNameIndexes[classIndex] = true; sizes.push(list.length); classes.push(classIndex); } } for (var i = dominatedIndexFrom; i < dominatedIndexTo; i++) list.push(dominatedNodes[i]); var l = list.length; while (sizes[sizes.length - 1] === l) { sizes.pop(); classIndex = classes.pop(); seenClassNameIndexes[classIndex] = false; } } }, _sortAggregateIndexes: function(aggregates) { var nodeA = this.createNode(); var nodeB = this.createNode(); for (var clss in aggregates) aggregates[clss].idxs.sort( function(idxA, idxB) { nodeA.nodeIndex = idxA; nodeB.nodeIndex = idxB; return nodeA.id() < nodeB.id() ? -1 : 1; }); }, _buildPostOrderIndex: function() { var nodeFieldCount = this._nodeFieldCount; var nodeCount = this.nodeCount; var rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount; var edgeFieldsCount = this._edgeFieldsCount; var edgeTypeOffset = this._edgeTypeOffset; var edgeToNodeOffset = this._edgeToNodeOffset; var edgeShortcutType = this._edgeShortcutType; var edgeWeakType = this._edgeWeakType; var firstEdgeIndexes = this._firstEdgeIndexes; var containmentEdges = this.containmentEdges; var mapAndFlag = this.userObjectsMapAndFlag(); var flags = mapAndFlag ? mapAndFlag.map : null; var flag = mapAndFlag ? mapAndFlag.flag : 0; var stackNodes = new Uint32Array(nodeCount); var stackCurrentEdge = new Uint32Array(nodeCount); var postOrderIndex2NodeOrdinal = new Uint32Array(nodeCount); var nodeOrdinal2PostOrderIndex = new Uint32Array(nodeCount); var visited = new Uint8Array(nodeCount); var postOrderIndex = 0; var stackTop = 0; stackNodes[0] = rootNodeOrdinal; stackCurrentEdge[0] = firstEdgeIndexes[rootNodeOrdinal]; visited[rootNodeOrdinal] = 1; var iteration = 0; while (true) { ++iteration; while (stackTop >= 0) { var nodeOrdinal = stackNodes[stackTop]; var edgeIndex = stackCurrentEdge[stackTop]; var edgesEnd = firstEdgeIndexes[nodeOrdinal + 1]; if (edgeIndex < edgesEnd) { stackCurrentEdge[stackTop] += edgeFieldsCount; var edgeType = containmentEdges[edgeIndex + edgeTypeOffset]; if (edgeType === edgeWeakType || edgeType === edgeShortcutType) continue; var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset]; var childNodeOrdinal = childNodeIndex / nodeFieldCount; if (visited[childNodeOrdinal]) continue; var nodeFlag = !flags || (flags[nodeOrdinal] & flag); var childNodeFlag = !flags || (flags[childNodeOrdinal] & flag); // We are skipping the edges from non-page-owned nodes to page-owned nodes. // Otherwise the dominators for the objects that also were retained by debugger would be affected. if (nodeOrdinal !== rootNodeOrdinal && childNodeFlag && !nodeFlag) continue; ++stackTop; stackNodes[stackTop] = childNodeOrdinal; stackCurrentEdge[stackTop] = firstEdgeIndexes[childNodeOrdinal]; visited[childNodeOrdinal] = 1; } else { // Done with all the node children nodeOrdinal2PostOrderIndex[nodeOrdinal] = postOrderIndex; postOrderIndex2NodeOrdinal[postOrderIndex++] = nodeOrdinal; --stackTop; } } if (postOrderIndex === nodeCount || iteration > 1) break; var errors = new WebInspector.HeapSnapshotProblemReport("Heap snapshot: " + (nodeCount - postOrderIndex) + " nodes are unreachable from the root. Following nodes have only weak retainers:"); var dumpNode = this.rootNode(); // Remove root from the result (last node in the array) and put it at the bottom of the stack so that it is // visited after all orphan nodes and their subgraphs. --postOrderIndex; stackTop = 0; stackNodes[0] = rootNodeOrdinal; stackCurrentEdge[0] = firstEdgeIndexes[rootNodeOrdinal + 1]; // no need to reiterate its edges for (var i = 0; i < nodeCount; ++i) { if (!visited[i]) { dumpNode.nodeIndex = i * nodeFieldCount; // Add all nodes that have only weak retainers to traverse their subgraphs. if (this._hasOnlyWeakRetainers(i)) { stackNodes[++stackTop] = i; stackCurrentEdge[stackTop] = firstEdgeIndexes[i]; visited[i] = 1; errors.addError(dumpNode.name() + " @" + dumpNode.id()); } } } console.warn(errors.toString()); } // If we already processed all orphan nodes that have only weak retainers and still have some orphans... if (postOrderIndex !== nodeCount) { var errors = new WebInspector.HeapSnapshotProblemReport("Still found " + (nodeCount - postOrderIndex) + " unreachable nodes in heap snapshot:"); var dumpNode = this.rootNode(); // Remove root from the result (last node in the array) and put it at the bottom of the stack so that it is // visited after all orphan nodes and their subgraphs. --postOrderIndex; for (var i = 0; i < nodeCount; ++i) { if (visited[i]) continue; dumpNode.nodeIndex = i * nodeFieldCount; errors.addError(dumpNode.name() + " @" + dumpNode.id()); // Fix it by giving the node a postorder index anyway. nodeOrdinal2PostOrderIndex[i] = postOrderIndex; postOrderIndex2NodeOrdinal[postOrderIndex++] = i; } nodeOrdinal2PostOrderIndex[rootNodeOrdinal] = postOrderIndex; postOrderIndex2NodeOrdinal[postOrderIndex++] = rootNodeOrdinal; console.warn(errors.toString()); } return {postOrderIndex2NodeOrdinal: postOrderIndex2NodeOrdinal, nodeOrdinal2PostOrderIndex: nodeOrdinal2PostOrderIndex}; }, /** * @param {number} nodeOrdinal * @return {boolean} */ _hasOnlyWeakRetainers: function(nodeOrdinal) { var edgeTypeOffset = this._edgeTypeOffset; var edgeWeakType = this._edgeWeakType; var edgeShortcutType = this._edgeShortcutType; var containmentEdges = this.containmentEdges; var retainingEdges = this._retainingEdges; var beginRetainerIndex = this._firstRetainerIndex[nodeOrdinal]; var endRetainerIndex = this._firstRetainerIndex[nodeOrdinal + 1]; for (var retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) { var retainerEdgeIndex = retainingEdges[retainerIndex]; var retainerEdgeType = containmentEdges[retainerEdgeIndex + edgeTypeOffset]; if (retainerEdgeType !== edgeWeakType && retainerEdgeType !== edgeShortcutType) return false; } return true; }, // The algorithm is based on the article: // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm" // Softw. Pract. Exper. 4 (2001), pp. 1-10. /** * @param {!Array.<number>} postOrderIndex2NodeOrdinal * @param {!Array.<number>} nodeOrdinal2PostOrderIndex */ _buildDominatorTree: function(postOrderIndex2NodeOrdinal, nodeOrdinal2PostOrderIndex) { var nodeFieldCount = this._nodeFieldCount; var firstRetainerIndex = this._firstRetainerIndex; var retainingNodes = this._retainingNodes; var retainingEdges = this._retainingEdges; var edgeFieldsCount = this._edgeFieldsCount; var edgeTypeOffset = this._edgeTypeOffset; var edgeToNodeOffset = this._edgeToNodeOffset; var edgeShortcutType = this._edgeShortcutType; var edgeWeakType = this._edgeWeakType; var firstEdgeIndexes = this._firstEdgeIndexes; var containmentEdges = this.containmentEdges; var rootNodeIndex = this._rootNodeIndex; var mapAndFlag = this.userObjectsMapAndFlag(); var flags = mapAndFlag ? mapAndFlag.map : null; var flag = mapAndFlag ? mapAndFlag.flag : 0; var nodesCount = postOrderIndex2NodeOrdinal.length; var rootPostOrderedIndex = nodesCount - 1; var noEntry = nodesCount; var dominators = new Uint32Array(nodesCount); for (var i = 0; i < rootPostOrderedIndex; ++i) dominators[i] = noEntry; dominators[rootPostOrderedIndex] = rootPostOrderedIndex; // The affected array is used to mark entries which dominators // have to be racalculated because of changes in their retainers. var affected = new Uint8Array(nodesCount); var nodeOrdinal; { // Mark the root direct children as affected. nodeOrdinal = this._rootNodeIndex / nodeFieldCount; var endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1]; for (var edgeIndex = firstEdgeIndexes[nodeOrdinal]; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) { var edgeType = containmentEdges[edgeIndex + edgeTypeOffset]; if (edgeType === edgeWeakType || edgeType === edgeShortcutType) continue; var childNodeOrdinal = containmentEdges[edgeIndex + edgeToNodeOffset] / nodeFieldCount; affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]] = 1; } } var changed = true; while (changed) { changed = false; for (var postOrderIndex = rootPostOrderedIndex - 1; postOrderIndex >= 0; --postOrderIndex) { if (affected[postOrderIndex] === 0) continue; affected[postOrderIndex] = 0; // If dominator of the entry has already been set to root, // then it can't propagate any further. if (dominators[postOrderIndex] === rootPostOrderedIndex) continue; nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex]; var nodeFlag = !flags || (flags[nodeOrdinal] & flag); var newDominatorIndex = noEntry; var beginRetainerIndex = firstRetainerIndex[nodeOrdinal]; var endRetainerIndex = firstRetainerIndex[nodeOrdinal + 1]; var orphanNode = true; for (var retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) { var retainerEdgeIndex = retainingEdges[retainerIndex]; var retainerEdgeType = containmentEdges[retainerEdgeIndex + edgeTypeOffset]; if (retainerEdgeType === edgeWeakType || retainerEdgeType === edgeShortcutType) continue; orphanNode = false; var retainerNodeIndex = retainingNodes[retainerIndex]; var retainerNodeOrdinal = retainerNodeIndex / nodeFieldCount; var retainerNodeFlag = !flags || (flags[retainerNodeOrdinal] & flag); // We are skipping the edges from non-page-owned nodes to page-owned nodes. // Otherwise the dominators for the objects that also were retained by debugger would be affected. if (retainerNodeIndex !== rootNodeIndex && nodeFlag && !retainerNodeFlag) continue; var retanerPostOrderIndex = nodeOrdinal2PostOrderIndex[retainerNodeOrdinal]; if (dominators[retanerPostOrderIndex] !== noEntry) { if (newDominatorIndex === noEntry) newDominatorIndex = retanerPostOrderIndex; else { while (retanerPostOrderIndex !== newDominatorIndex) { while (retanerPostOrderIndex < newDominatorIndex) retanerPostOrderIndex = dominators[retanerPostOrderIndex]; while (newDominatorIndex < retanerPostOrderIndex) newDominatorIndex = dominators[newDominatorIndex]; } } // If idom has already reached the root, it doesn't make sense // to check other retainers. if (newDominatorIndex === rootPostOrderedIndex) break; } } // Make root dominator of orphans. if (orphanNode) newDominatorIndex = rootPostOrderedIndex; if (newDominatorIndex !== noEntry && dominators[postOrderIndex] !== newDominatorIndex) { dominators[postOrderIndex] = newDominatorIndex; changed = true; nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex]; var beginEdgeToNodeFieldIndex = firstEdgeIndexes[nodeOrdinal] + edgeToNodeOffset; var endEdgeToNodeFieldIndex = firstEdgeIndexes[nodeOrdinal + 1]; for (var toNodeFieldIndex = beginEdgeToNodeFieldIndex; toNodeFieldIndex < endEdgeToNodeFieldIndex; toNodeFieldIndex += edgeFieldsCount) { var childNodeOrdinal = containmentEdges[toNodeFieldIndex] / nodeFieldCount; affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]] = 1; } } } } var dominatorsTree = new Uint32Array(nodesCount); for (var postOrderIndex = 0, l = dominators.length; postOrderIndex < l; ++postOrderIndex) { nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex]; dominatorsTree[nodeOrdinal] = postOrderIndex2NodeOrdinal[dominators[postOrderIndex]]; } return dominatorsTree; }, _calculateRetainedSizes: function(postOrderIndex2NodeOrdinal) { var nodeCount = this.nodeCount; var nodes = this.nodes; var nodeSelfSizeOffset = this._nodeSelfSizeOffset; var nodeFieldCount = this._nodeFieldCount; var dominatorsTree = this._dominatorsTree; var retainedSizes = this._retainedSizes; for (var nodeOrdinal = 0; nodeOrdinal < nodeCount; ++nodeOrdinal) retainedSizes[nodeOrdinal] = nodes[nodeOrdinal * nodeFieldCount + nodeSelfSizeOffset]; // Propagate retained sizes for each node excluding root. for (var postOrderIndex = 0; postOrderIndex < nodeCount - 1; ++postOrderIndex) { var nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex]; var dominatorOrdinal = dominatorsTree[nodeOrdinal]; retainedSizes[dominatorOrdinal] += retainedSizes[nodeOrdinal]; } }, _buildDominatedNodes: function() { // Builds up two arrays: // - "dominatedNodes" is a continuous array, where each node owns an // interval (can be empty) with corresponding dominated nodes. // - "indexArray" is an array of indexes in the "dominatedNodes" // with the same positions as in the _nodeIndex. var indexArray = this._firstDominatedNodeIndex; // All nodes except the root have dominators. var dominatedNodes = this._dominatedNodes; // Count the number of dominated nodes for each node. Skip the root (node at // index 0) as it is the only node that dominates itself. var nodeFieldCount = this._nodeFieldCount; var dominatorsTree = this._dominatorsTree; var fromNodeOrdinal = 0; var toNodeOrdinal = this.nodeCount; var rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount; if (rootNodeOrdinal === fromNodeOrdinal) fromNodeOrdinal = 1; else if (rootNodeOrdinal === toNodeOrdinal - 1) toNodeOrdinal = toNodeOrdinal - 1; else throw new Error("Root node is expected to be either first or last"); for (var nodeOrdinal = fromNodeOrdinal; nodeOrdinal < toNodeOrdinal; ++nodeOrdinal) ++indexArray[dominatorsTree[nodeOrdinal]]; // Put in the first slot of each dominatedNodes slice the count of entries // that will be filled. var firstDominatedNodeIndex = 0; for (var i = 0, l = this.nodeCount; i < l; ++i) { var dominatedCount = dominatedNodes[firstDominatedNodeIndex] = indexArray[i]; indexArray[i] = firstDominatedNodeIndex; firstDominatedNodeIndex += dominatedCount; } indexArray[this.nodeCount] = dominatedNodes.length; // Fill up the dominatedNodes array with indexes of dominated nodes. Skip the root (node at // index 0) as it is the only node that dominates itself. for (var nodeOrdinal = fromNodeOrdinal; nodeOrdinal < toNodeOrdinal; ++nodeOrdinal) { var dominatorOrdinal = dominatorsTree[nodeOrdinal]; var dominatedRefIndex = indexArray[dominatorOrdinal]; dominatedRefIndex += (--dominatedNodes[dominatedRefIndex]); dominatedNodes[dominatedRefIndex] = nodeOrdinal * nodeFieldCount; } }, _buildSamples: function() { var samples = this._rawSamples; if (!samples || !samples.length) return; var sampleCount = samples.length / 2; var sizeForRange = new Array(sampleCount); var timestamps = new Array(sampleCount); var lastAssignedIds = new Array(sampleCount); var timestampOffset = this._metaNode.sample_fields.indexOf("timestamp_us"); var lastAssignedIdOffset = this._metaNode.sample_fields.indexOf("last_assigned_id"); for (var i = 0; i < sampleCount; i++) { sizeForRange[i] = 0; timestamps[i] = (samples[2 * i + timestampOffset]) / 1000; lastAssignedIds[i] = samples[2 * i + lastAssignedIdOffset]; } var nodes = this.nodes; var nodesLength = nodes.length; var nodeFieldCount = this._nodeFieldCount; var node = this.rootNode(); for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) { node.nodeIndex = nodeIndex; var nodeId = node.id(); // JS objects have odd ids, skip native objects. if (nodeId % 2 === 0) continue; var rangeIndex = lastAssignedIds.lowerBound(nodeId); if (rangeIndex === sampleCount) { // TODO: make heap profiler not allocate while taking snapshot continue; } sizeForRange[rangeIndex] += node.selfSize(); } this._samples = new WebInspector.HeapSnapshotCommon.Samples(timestamps, lastAssignedIds, sizeForRange); }, /** * @return {?WebInspector.HeapSnapshotCommon.Samples} */ getSamples: function() { return this._samples; }, _calculateFlags: function() { throw new Error("Not implemented"); }, _calculateStatistics: function() { throw new Error("Not implemented"); }, userObjectsMapAndFlag: function() { throw new Error("Not implemented"); }, /** * @param {string} baseSnapshotId * @param {!Object.<string, !WebInspector.HeapSnapshotCommon.AggregateForDiff>} baseSnapshotAggregates * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Diff>} */ calculateSnapshotDiff: function(baseSnapshotId, baseSnapshotAggregates) { var snapshotDiff = this._snapshotDiffs[baseSnapshotId]; if (snapshotDiff) return snapshotDiff; snapshotDiff = {}; var aggregates = this.aggregates(true, "allObjects"); for (var className in baseSnapshotAggregates) { var baseAggregate = baseSnapshotAggregates[className]; var diff = this._calculateDiffForClass(baseAggregate, aggregates[className]); if (diff) snapshotDiff[className] = diff; } var emptyBaseAggregate = new WebInspector.HeapSnapshotCommon.AggregateForDiff(); for (var className in aggregates) { if (className in baseSnapshotAggregates) continue; snapshotDiff[className] = this._calculateDiffForClass(emptyBaseAggregate, aggregates[className]); } this._snapshotDiffs[baseSnapshotId] = snapshotDiff; return snapshotDiff; }, /** * @param {!WebInspector.HeapSnapshotCommon.AggregateForDiff} baseAggregate * @param {!WebInspector.HeapSnapshotCommon.Aggregate} aggregate * @return {?WebInspector.HeapSnapshotCommon.Diff} */ _calculateDiffForClass: function(baseAggregate, aggregate) { var baseIds = baseAggregate.ids; var baseIndexes = baseAggregate.indexes; var baseSelfSizes = baseAggregate.selfSizes; var indexes = aggregate ? aggregate.idxs : []; var i = 0, l = baseIds.length; var j = 0, m = indexes.length; var diff = new WebInspector.HeapSnapshotCommon.Diff(); var nodeB = this.createNode(indexes[j]); while (i < l && j < m) { var nodeAId = baseIds[i]; if (nodeAId < nodeB.id()) { diff.deletedIndexes.push(baseIndexes[i]); diff.removedCount++; diff.removedSize += baseSelfSizes[i]; ++i; } else if (nodeAId > nodeB.id()) { // Native nodes(e.g. dom groups) may have ids less than max JS object id in the base snapshot diff.addedIndexes.push(indexes[j]); diff.addedCount++; diff.addedSize += nodeB.selfSize(); nodeB.nodeIndex = indexes[++j]; } else { // nodeAId === nodeB.id() ++i; nodeB.nodeIndex = indexes[++j]; } } while (i < l) { diff.deletedIndexes.push(baseIndexes[i]); diff.removedCount++; diff.removedSize += baseSelfSizes[i]; ++i; } while (j < m) { diff.addedIndexes.push(indexes[j]); diff.addedCount++; diff.addedSize += nodeB.selfSize(); nodeB.nodeIndex = indexes[++j]; } diff.countDelta = diff.addedCount - diff.removedCount; diff.sizeDelta = diff.addedSize - diff.removedSize; if (!diff.addedCount && !diff.removedCount) return null; return diff; }, _nodeForSnapshotObjectId: function(snapshotObjectId) { for (var it = this._allNodes(); it.hasNext(); it.next()) { if (it.node.id() === snapshotObjectId) return it.node; } return null; }, /** * @param {string} snapshotObjectId * @return {?string} */ nodeClassName: function(snapshotObjectId) { var node = this._nodeForSnapshotObjectId(snapshotObjectId); if (node) return node.className(); return null; }, /** * @param {string} name * @return {!Array.<number>} */ idsOfObjectsWithName: function(name) { var ids = []; for (var it = this._allNodes(); it.hasNext(); it.next()) { if (it.item().name() === name) ids.push(it.item().id()); } return ids; }, /** * @param {number} nodeIndex * @return {!WebInspector.HeapSnapshotEdgesProvider} */ createEdgesProvider: function(nodeIndex) { var node = this.createNode(nodeIndex); var filter = this.containmentEdgesFilter(); var indexProvider = new WebInspector.HeapSnapshotEdgeIndexProvider(this); return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider); }, /** * @param {number} nodeIndex * @param {?function(!WebInspector.HeapSnapshotEdge):boolean} filter * @return {!WebInspector.HeapSnapshotEdgesProvider} */ createEdgesProviderForTest: function(nodeIndex, filter) { var node = this.createNode(nodeIndex); var indexProvider = new WebInspector.HeapSnapshotEdgeIndexProvider(this); return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider); }, /** * @return {?function(!WebInspector.HeapSnapshotEdge):boolean} */ retainingEdgesFilter: function() { return null; }, /** * @return {?function(!WebInspector.HeapSnapshotEdge):boolean} */ containmentEdgesFilter: function() { return null; }, /** * @param {number} nodeIndex * @return {!WebInspector.HeapSnapshotEdgesProvider} */ createRetainingEdgesProvider: function(nodeIndex) { var node = this.createNode(nodeIndex); var filter = this.retainingEdgesFilter(); var indexProvider = new WebInspector.HeapSnapshotRetainerEdgeIndexProvider(this); return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider); }, /** * @param {string} baseSnapshotId * @param {string} className * @return {!WebInspector.HeapSnapshotNodesProvider} */ createAddedNodesProvider: function(baseSnapshotId, className) { var snapshotDiff = this._snapshotDiffs[baseSnapshotId]; var diffForClass = snapshotDiff[className]; return new WebInspector.HeapSnapshotNodesProvider(this, null, diffForClass.addedIndexes); }, /** * @param {!Array.<number>} nodeIndexes * @return {!WebInspector.HeapSnapshotNodesProvider} */ createDeletedNodesProvider: function(nodeIndexes) { return new WebInspector.HeapSnapshotNodesProvider(this, null, nodeIndexes); }, /** * @return {?function(!WebInspector.HeapSnapshotNode):boolean} */ classNodesFilter: function() { return null; }, /** * @param {string} className * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter * @return {!WebInspector.HeapSnapshotNodesProvider} */ createNodesProviderForClass: function(className, nodeFilter) { return new WebInspector.HeapSnapshotNodesProvider(this, this.classNodesFilter(), this.aggregatesWithFilter(nodeFilter)[className].idxs); }, /** * @return {number} */ _maxJsNodeId: function() { var nodeFieldCount = this._nodeFieldCount; var nodes = this.nodes; var nodesLength = nodes.length; var id = 0; for (var nodeIndex = this._nodeIdOffset; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) { var nextId = nodes[nodeIndex]; // JS objects have odd ids, skip native objects. if (nextId % 2 === 0) continue; if (id < nextId) id = nextId; } return id; }, /** * @return {!WebInspector.HeapSnapshotCommon.StaticData} */ updateStaticData: function() { return new WebInspector.HeapSnapshotCommon.StaticData(this.nodeCount, this._rootNodeIndex, this.totalSize, this._maxJsNodeId()); } }; /** * @constructor * @param {!WebInspector.HeapSnapshotItemIterator} iterator * @param {!WebInspector.HeapSnapshotItemIndexProvider} indexProvider */ WebInspector.HeapSnapshotItemProvider = function(iterator, indexProvider) { this._iterator = iterator; this._indexProvider = indexProvider; this._isEmpty = !iterator.hasNext(); /** @type {?Array.<number>} */ this._iterationOrder = null; this._currentComparator = null; this._sortedPrefixLength = 0; this._sortedSuffixLength = 0; } WebInspector.HeapSnapshotItemProvider.prototype = { _createIterationOrder: function() { if (this._iterationOrder) return; this._iterationOrder = []; for (var iterator = this._iterator; iterator.hasNext(); iterator.next()) this._iterationOrder.push(iterator.item().itemIndex()); }, /** * @return {boolean} */ isEmpty: function() { return this._isEmpty; }, /** * @param {number} begin * @param {number} end * @return {!WebInspector.HeapSnapshotCommon.ItemsRange} */ serializeItemsRange: function(begin, end) { this._createIterationOrder(); if (begin > end) throw new Error("Start position > end position: " + begin + " > " + end); if (end > this._iterationOrder.length) end = this._iterationOrder.length; if (this._sortedPrefixLength < end && begin < this._iterationOrder.length - this._sortedSuffixLength) { this.sort(this._currentComparator, this._sortedPrefixLength, this._iterationOrder.length - 1 - this._sortedSuffixLength, begin, end - 1); if (begin <= this._sortedPrefixLength) this._sortedPrefixLength = end; if (end >= this._iterationOrder.length - this._sortedSuffixLength) this._sortedSuffixLength = this._iterationOrder.length - begin; } var position = begin; var count = end - begin; var result = new Array(count); for (var i = 0 ; i < count; ++i) { var itemIndex = this._iterationOrder[position++]; var item = this._indexProvider.itemForIndex(itemIndex); result[i] = item.serialize(); } return new WebInspector.HeapSnapshotCommon.ItemsRange(begin, end, this._iterationOrder.length, result); }, sortAndRewind: function(comparator) { this._currentComparator = comparator; this._sortedPrefixLength = 0; this._sortedSuffixLength = 0; } } /** * @constructor * @extends {WebInspector.HeapSnapshotItemProvider} * @param {!WebInspector.HeapSnapshot} snapshot * @param {?function(!WebInspector.HeapSnapshotEdge):boolean} filter * @param {!WebInspector.HeapSnapshotEdgeIterator} edgesIter * @param {!WebInspector.HeapSnapshotItemIndexProvider} indexProvider */ WebInspector.HeapSnapshotEdgesProvider = function(snapshot, filter, edgesIter, indexProvider) { this.snapshot = snapshot; var iter = filter ? new WebInspector.HeapSnapshotFilteredIterator(edgesIter, /** @type {function(!WebInspector.HeapSnapshotItem):boolean} */ (filter)) : edgesIter; WebInspector.HeapSnapshotItemProvider.call(this, iter, indexProvider); } WebInspector.HeapSnapshotEdgesProvider.prototype = { /** * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator * @param {number} leftBound * @param {number} rightBound * @param {number} windowLeft * @param {number} windowRight */ sort: function(comparator, leftBound, rightBound, windowLeft, windowRight) { var fieldName1 = comparator.fieldName1; var fieldName2 = comparator.fieldName2; var ascending1 = comparator.ascending1; var ascending2 = comparator.ascending2; var edgeA = this._iterator.item().clone(); var edgeB = edgeA.clone(); var nodeA = this.snapshot.createNode(); var nodeB = this.snapshot.createNode(); function compareEdgeFieldName(ascending, indexA, indexB) { edgeA.edgeIndex = indexA; edgeB.edgeIndex = indexB; if (edgeB.name() === "__proto__") return -1; if (edgeA.name() === "__proto__") return 1; var result = edgeA.hasStringName() === edgeB.hasStringName() ? (edgeA.name() < edgeB.name() ? -1 : (edgeA.name() > edgeB.name() ? 1 : 0)) : (edgeA.hasStringName() ? -1 : 1); return ascending ? result : -result; } function compareNodeField(fieldName, ascending, indexA, indexB) { edgeA.edgeIndex = indexA; nodeA.nodeIndex = edgeA.nodeIndex(); var valueA = nodeA[fieldName](); edgeB.edgeIndex = indexB; nodeB.nodeIndex = edgeB.nodeIndex(); var valueB = nodeB[fieldName](); var result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0); return ascending ? result : -result; } function compareEdgeAndNode(indexA, indexB) { var result = compareEdgeFieldName(ascending1, indexA, indexB); if (result === 0) result = compareNodeField(fieldName2, ascending2, indexA, indexB); if (result === 0) return indexA - indexB; return result; } function compareNodeAndEdge(indexA, indexB) { var result = compareNodeField(fieldName1, ascending1, indexA, indexB); if (result === 0) result = compareEdgeFieldName(ascending2, indexA, indexB); if (result === 0) return indexA - indexB; return result; } function compareNodeAndNode(indexA, indexB) { var result = compareNodeField(fieldName1, ascending1, indexA, indexB); if (result === 0) result = compareNodeField(fieldName2, ascending2, indexA, indexB); if (result === 0) return indexA - indexB; return result; } if (fieldName1 === "!edgeName") this._iterationOrder.sortRange(compareEdgeAndNode, leftBound, rightBound, windowLeft, windowRight); else if (fieldName2 === "!edgeName") this._iterationOrder.sortRange(compareNodeAndEdge, leftBound, rightBound, windowLeft, windowRight); else this._iterationOrder.sortRange(compareNodeAndNode, leftBound, rightBound, windowLeft, windowRight); }, __proto__: WebInspector.HeapSnapshotItemProvider.prototype } /** * @constructor * @extends {WebInspector.HeapSnapshotItemProvider} * @param {!WebInspector.HeapSnapshot} snapshot * @param {?function(!WebInspector.HeapSnapshotNode):boolean} filter * @param {(!Array.<number>|!Uint32Array)} nodeIndexes */ WebInspector.HeapSnapshotNodesProvider = function(snapshot, filter, nodeIndexes) { this.snapshot = snapshot; var indexProvider = new WebInspector.HeapSnapshotNodeIndexProvider(snapshot); var it = new WebInspector.HeapSnapshotIndexRangeIterator(indexProvider, nodeIndexes); if (filter) it = new WebInspector.HeapSnapshotFilteredIterator(it, /** @type {function(!WebInspector.HeapSnapshotItem):boolean} */ (filter)); WebInspector.HeapSnapshotItemProvider.call(this, it, indexProvider); } WebInspector.HeapSnapshotNodesProvider.prototype = { /** * @param {string} snapshotObjectId * @return {number} */ nodePosition: function(snapshotObjectId) { this._createIterationOrder(); var node = this.snapshot.createNode(); for (var i = 0; i < this._iterationOrder.length; i++) { node.nodeIndex = this._iterationOrder[i]; if (node.id() === snapshotObjectId) break; } if (i === this._iterationOrder.length) return -1; var targetNodeIndex = this._iterationOrder[i]; var smallerCount = 0; var compare = this._buildCompareFunction(this._currentComparator); for (var i = 0; i < this._iterationOrder.length; i++) { if (compare(this._iterationOrder[i], targetNodeIndex) < 0) ++smallerCount; } return smallerCount; }, /** * @return {function(number,number):number} */ _buildCompareFunction: function(comparator) { var nodeA = this.snapshot.createNode(); var nodeB = this.snapshot.createNode(); var fieldAccessor1 = nodeA[comparator.fieldName1]; var fieldAccessor2 = nodeA[comparator.fieldName2]; var ascending1 = comparator.ascending1 ? 1 : -1; var ascending2 = comparator.ascending2 ? 1 : -1; /** * @param {function():*} fieldAccessor * @param {number} ascending * @return {number} */ function sortByNodeField(fieldAccessor, ascending) { var valueA = fieldAccessor.call(nodeA); var valueB = fieldAccessor.call(nodeB); return valueA < valueB ? -ascending : (valueA > valueB ? ascending : 0); } /** * @param {number} indexA * @param {number} indexB * @return {number} */ function sortByComparator(indexA, indexB) { nodeA.nodeIndex = indexA; nodeB.nodeIndex = indexB; var result = sortByNodeField(fieldAccessor1, ascending1); if (result === 0) result = sortByNodeField(fieldAccessor2, ascending2); return result || indexA - indexB; } return sortByComparator; }, /** * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator * @param {number} leftBound * @param {number} rightBound * @param {number} windowLeft * @param {number} windowRight */ sort: function(comparator, leftBound, rightBound, windowLeft, windowRight) { this._iterationOrder.sortRange(this._buildCompareFunction(comparator), leftBound, rightBound, windowLeft, windowRight); }, __proto__: WebInspector.HeapSnapshotItemProvider.prototype } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.HeapSnapshotWorkerDispatcher} dispatcher
*/
WebInspector.HeapSnapshotLoader = function(dispatcher)
{
this._reset();
this._progress = new WebInspector.HeapSnapshotProgress(dispatcher);
}
WebInspector.HeapSnapshotLoader.prototype = {
dispose: function()
{
this._reset();
},
_reset: function()
{
this._json = "";
this._state = "find-snapshot-info";
this._snapshot = {};
},
close: function()
{
if (this._json)
this._parseStringsArray();
},
/**
* @param {boolean} showHiddenData
* @return {!WebInspector.JSHeapSnapshot}
*/
buildSnapshot: function(showHiddenData)
{
this._progress.updateStatus("Processing snapshot\u2026");
var result = new WebInspector.JSHeapSnapshot(this._snapshot, this._progress, showHiddenData);
this._reset();
return result;
},
_parseUintArray: function()
{
var index = 0;
var char0 = "0".charCodeAt(0), char9 = "9".charCodeAt(0), closingBracket = "]".charCodeAt(0);
var length = this._json.length;
while (true) {
while (index < length) {
var code = this._json.charCodeAt(index);
if (char0 <= code && code <= char9)
break;
else if (code === closingBracket) {
this._json = this._json.slice(index + 1);
return false;
}
++index;
}
if (index === length) {
this._json = "";
return true;
}
var nextNumber = 0;
var startIndex = index;
while (index < length) {
var code = this._json.charCodeAt(index);
if (char0 > code || code > char9)
break;
nextNumber *= 10;
nextNumber += (code - char0);
++index;
}
if (index === length) {
this._json = this._json.slice(startIndex);
return true;
}
this._array[this._arrayIndex++] = nextNumber;
}
},
_parseStringsArray: function()
{
this._progress.updateStatus("Parsing strings\u2026");
var closingBracketIndex = this._json.lastIndexOf("]");
if (closingBracketIndex === -1)
throw new Error("Incomplete JSON");
this._json = this._json.slice(0, closingBracketIndex + 1);
this._snapshot.strings = JSON.parse(this._json);
},
/**
* @param {string} chunk
*/
write: function(chunk)
{
if (this._json !== null)
this._json += chunk;
while (true) {
switch (this._state) {
case "find-snapshot-info": {
var snapshotToken = "\"snapshot\"";
var snapshotTokenIndex = this._json.indexOf(snapshotToken);
if (snapshotTokenIndex === -1)
throw new Error("Snapshot token not found");
var json = this._json.slice(snapshotTokenIndex + snapshotToken.length + 1);
this._state = "parse-snapshot-info";
this._progress.updateStatus("Loading snapshot info\u2026");
this._json = null; // tokenizer takes over input.
this._jsonTokenizer = new WebInspector.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this));
// Fall through with adjusted payload.
chunk = json;
}
case "parse-snapshot-info": {
this._jsonTokenizer.write(chunk);
if (this._jsonTokenizer)
return; // no remainder to process.
break;
}
case "find-nodes": {
var nodesToken = "\"nodes\"";
var nodesTokenIndex = this._json.indexOf(nodesToken);
if (nodesTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", nodesTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex + 1);
var node_fields_count = this._snapshot.snapshot.meta.node_fields.length;
var nodes_length = this._snapshot.snapshot.node_count * node_fields_count;
this._array = new Uint32Array(nodes_length);
this._arrayIndex = 0;
this._state = "parse-nodes";
break;
}
case "parse-nodes": {
var hasMoreData = this._parseUintArray();
this._progress.updateProgress("Loading nodes\u2026 %d%%", this._arrayIndex, this._array.length);
if (hasMoreData)
return;
this._snapshot.nodes = this._array;
this._state = "find-edges";
this._array = null;
break;
}
case "find-edges": {
var edgesToken = "\"edges\"";
var edgesTokenIndex = this._json.indexOf(edgesToken);
if (edgesTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", edgesTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex + 1);
var edge_fields_count = this._snapshot.snapshot.meta.edge_fields.length;
var edges_length = this._snapshot.snapshot.edge_count * edge_fields_count;
this._array = new Uint32Array(edges_length);
this._arrayIndex = 0;
this._state = "parse-edges";
break;
}
case "parse-edges": {
var hasMoreData = this._parseUintArray();
this._progress.updateProgress("Loading edges\u2026 %d%%", this._arrayIndex, this._array.length);
if (hasMoreData)
return;
this._snapshot.edges = this._array;
this._array = null;
// If there is allocation info parse it, otherwise jump straight to strings.
if (this._snapshot.snapshot.trace_function_count) {
this._state = "find-trace-function-infos";
this._progress.updateStatus("Loading allocation traces\u2026");
} else if (this._snapshot.snapshot.meta.sample_fields) {
this._state = "find-samples";
this._progress.updateStatus("Loading samples\u2026");
} else {
this._state = "find-strings";
}
break;
}
case "find-trace-function-infos": {
var tracesToken = "\"trace_function_infos\"";
var tracesTokenIndex = this._json.indexOf(tracesToken);
if (tracesTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", tracesTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex + 1);
var trace_function_info_field_count = this._snapshot.snapshot.meta.trace_function_info_fields.length;
var trace_function_info_length = this._snapshot.snapshot.trace_function_count * trace_function_info_field_count;
this._array = new Uint32Array(trace_function_info_length);
this._arrayIndex = 0;
this._state = "parse-trace-function-infos";
break;
}
case "parse-trace-function-infos": {
if (this._parseUintArray())
return;
this._snapshot.trace_function_infos = this._array;
this._array = null;
this._state = "find-trace-tree";
break;
}
case "find-trace-tree": {
var tracesToken = "\"trace_tree\"";
var tracesTokenIndex = this._json.indexOf(tracesToken);
if (tracesTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", tracesTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex);
this._state = "parse-trace-tree";
break;
}
case "parse-trace-tree": {
// If there is samples array parse it, otherwise jump straight to strings.
var nextToken = this._snapshot.snapshot.meta.sample_fields ? "\"samples\"" : "\"strings\"";
var nextTokenIndex = this._json.indexOf(nextToken);
if (nextTokenIndex === -1)
return;
var bracketIndex = this._json.lastIndexOf("]", nextTokenIndex);
this._snapshot.trace_tree = JSON.parse(this._json.substring(0, bracketIndex + 1));
this._json = this._json.slice(bracketIndex + 1);
if (this._snapshot.snapshot.meta.sample_fields) {
this._state = "find-samples";
this._progress.updateStatus("Loading samples\u2026");
} else {
this._state = "find-strings";
this._progress.updateStatus("Loading strings\u2026");
}
break;
}
case "find-samples": {
var samplesToken = "\"samples\"";
var samplesTokenIndex = this._json.indexOf(samplesToken);
if (samplesTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", samplesTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex + 1);
this._array = [];
this._arrayIndex = 0;
this._state = "parse-samples";
break;
}
case "parse-samples": {
if (this._parseUintArray())
return;
this._snapshot.samples = this._array;
this._array = null;
this._state = "find-strings";
this._progress.updateStatus("Loading strings\u2026");
break;
}
case "find-strings": {
var stringsToken = "\"strings\"";
var stringsTokenIndex = this._json.indexOf(stringsToken);
if (stringsTokenIndex === -1)
return;
var bracketIndex = this._json.indexOf("[", stringsTokenIndex);
if (bracketIndex === -1)
return;
this._json = this._json.slice(bracketIndex);
this._state = "accumulate-strings";
break;
}
case "accumulate-strings":
return;
}
}
},
/**
* @param {string} data
*/
_writeBalancedJSON: function(data)
{
this._json = this._jsonTokenizer.remainder(); // tokenizer releases input.
this._jsonTokenizer = null;
this._state = "find-nodes";
this._snapshot.snapshot = /** @type {!HeapSnapshotHeader} */ (JSON.parse(data));
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 1 2 1 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ function postMessageWrapper(message) { postMessage(message); } var dispatcher = new WebInspector.HeapSnapshotWorkerDispatcher(this, postMessageWrapper); /** * @param {function(!Event)} listener * @suppressGlobalPropertiesCheck */ function installMessageEventListener(listener) { self.addEventListener("message", listener, false); } installMessageEventListener(dispatcher.dispatchMessage.bind(dispatcher)); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 2 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.HeapSnapshotWorkerDispatcher = function(globalObject, postMessage) { this._objects = []; this._global = globalObject; this._postMessage = postMessage; } WebInspector.HeapSnapshotWorkerDispatcher.prototype = { _findFunction: function(name) { var path = name.split("."); var result = this._global; for (var i = 0; i < path.length; ++i) result = result[path[i]]; return result; }, /** * @param {string} name * @param {*} data */ sendEvent: function(name, data) { this._postMessage({eventName: name, data: data}); }, dispatchMessage: function(event) { var data = /** @type {!WebInspector.HeapSnapshotCommon.WorkerCommand } */(event.data); var response = {callId: data.callId}; try { switch (data.disposition) { case "create": { var constructorFunction = this._findFunction(data.methodName); this._objects[data.objectId] = new constructorFunction(this); break; } case "dispose": { delete this._objects[data.objectId]; break; } case "getter": { var object = this._objects[data.objectId]; var result = object[data.methodName]; response.result = result; break; } case "factory": { var object = this._objects[data.objectId]; var result = object[data.methodName].apply(object, data.methodArguments); if (result) this._objects[data.newObjectId] = result; response.result = !!result; break; } case "method": { var object = this._objects[data.objectId]; response.result = object[data.methodName].apply(object, data.methodArguments); break; } case "evaluateForTest": { try { response.result = eval(data.source); } catch (e) { response.result = e.toString(); } break; } } } catch (e) { response.error = e.toString(); response.errorCallStack = e.stack; if (data.methodName) response.errorMethodName = data.methodName; } this._postMessage(response); } }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.HeapSnapshot}
* @param {!Object} profile
* @param {!WebInspector.HeapSnapshotProgress} progress
* @param {boolean} showHiddenData
*/
WebInspector.JSHeapSnapshot = function(profile, progress, showHiddenData)
{
this._nodeFlags = { // bit flags
canBeQueried: 1,
detachedDOMTreeNode: 2,
pageObject: 4, // The idea is to track separately the objects owned by the page and the objects owned by debugger.
visitedMarkerMask: 0x0ffff,
visitedMarker: 0x10000
};
this._lazyStringCache = { };
this._showHiddenData = showHiddenData;
WebInspector.HeapSnapshot.call(this, profile, progress);
}
WebInspector.JSHeapSnapshot.prototype = {
/**
* @override
* @param {number=} nodeIndex
* @return {!WebInspector.JSHeapSnapshotNode}
*/
createNode: function(nodeIndex)
{
return new WebInspector.JSHeapSnapshotNode(this, nodeIndex === undefined ? -1 : nodeIndex);
},
/**
* @override
* @param {number} edgeIndex
* @return {!WebInspector.JSHeapSnapshotEdge}
*/
createEdge: function(edgeIndex)
{
return new WebInspector.JSHeapSnapshotEdge(this, edgeIndex);
},
/**
* @override
* @param {number} retainerIndex
* @return {!WebInspector.JSHeapSnapshotRetainerEdge}
*/
createRetainingEdge: function(retainerIndex)
{
return new WebInspector.JSHeapSnapshotRetainerEdge(this, retainerIndex);
},
/**
* @override
* @return {?function(!WebInspector.HeapSnapshotNode):boolean}
*/
classNodesFilter: function()
{
var mapAndFlag = this.userObjectsMapAndFlag();
if (!mapAndFlag)
return null;
var map = mapAndFlag.map;
var flag = mapAndFlag.flag;
/**
* @param {!WebInspector.HeapSnapshotNode} node
* @return {boolean}
*/
function filter(node)
{
return !!(map[node.ordinal()] & flag);
}
return filter;
},
/**
* @override
* @return {function(!WebInspector.HeapSnapshotEdge):boolean}
*/
containmentEdgesFilter: function()
{
var showHiddenData = this._showHiddenData;
function filter(edge)
{
if (edge.isInvisible())
return false;
if (showHiddenData)
return true;
return !edge.isHidden() && !edge.node().isHidden();
}
return filter;
},
/**
* @override
* @return {function(!WebInspector.HeapSnapshotEdge):boolean}
*/
retainingEdgesFilter: function()
{
var containmentEdgesFilter = this.containmentEdgesFilter();
function filter(edge)
{
return containmentEdgesFilter(edge) && !edge.node().isRoot() && !edge.isWeak();
}
return filter;
},
_calculateFlags: function()
{
this._flags = new Uint32Array(this.nodeCount);
this._markDetachedDOMTreeNodes();
this._markQueriableHeapObjects();
this._markPageOwnedNodes();
},
calculateDistances: function()
{
/**
* @param {!WebInspector.HeapSnapshotNode} node
* @param {!WebInspector.HeapSnapshotEdge} edge
* @return {boolean}
*/
function filter(node, edge)
{
if (node.isHidden())
return edge.name() !== "sloppy_function_map" || node.rawName() !== "system / NativeContext";
if (node.isArray()) {
// DescriptorArrays are fixed arrays used to hold instance descriptors.
// The format of the these objects is:
// [0]: Number of descriptors
// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
// [0]: pointer to fixed array with enum cache
// [1]: either Smi(0) or pointer to fixed array with indices
// [i*3+2]: i-th key
// [i*3+3]: i-th type
// [i*3+4]: i-th descriptor
// As long as maps may share descriptor arrays some of the descriptor
// links may not be valid for all the maps. We just skip
// all the descriptor links when calculating distances.
// For more details see http://crbug.com/413608
if (node.rawName() !== "(map descriptors)")
return true;
var index = edge.name();
return index < 2 || (index % 3) !== 1;
}
return true;
}
WebInspector.HeapSnapshot.prototype.calculateDistances.call(this, filter);
},
/**
* @override
* @protected
* @param {!WebInspector.HeapSnapshotNode} node
* @return {boolean}
*/
isUserRoot: function(node)
{
return node.isUserRoot() || node.isDocumentDOMTreesRoot();
},
/**
* @override
* @param {function(!WebInspector.HeapSnapshotNode)} action
* @param {boolean=} userRootsOnly
*/
forEachRoot: function(action, userRootsOnly)
{
/**
* @param {!WebInspector.HeapSnapshotNode} node
* @param {string} name
* @return {?WebInspector.HeapSnapshotNode}
*/
function getChildNodeByName(node, name)
{
for (var iter = node.edges(); iter.hasNext(); iter.next()) {
var child = iter.edge.node();
if (child.name() === name)
return child;
}
return null;
}
var visitedNodes = {};
/**
* @param {!WebInspector.HeapSnapshotNode} node
*/
function doAction(node)
{
var ordinal = node.ordinal();
if (!visitedNodes[ordinal]) {
action(node);
visitedNodes[ordinal] = true;
}
}
var gcRoots = getChildNodeByName(this.rootNode(), "(GC roots)");
if (!gcRoots)
return;
if (userRootsOnly) {
for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
var node = iter.edge.node();
if (this.isUserRoot(node))
doAction(node);
}
} else {
for (var iter = gcRoots.edges(); iter.hasNext(); iter.next()) {
var subRoot = iter.edge.node();
for (var iter2 = subRoot.edges(); iter2.hasNext(); iter2.next())
doAction(iter2.edge.node());
doAction(subRoot);
}
for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next())
doAction(iter.edge.node());
}
},
/**
* @return {?{map: !Uint32Array, flag: number}}
*/
userObjectsMapAndFlag: function()
{
return this._showHiddenData ? null : {
map: this._flags,
flag: this._nodeFlags.pageObject
};
},
_flagsOfNode: function(node)
{
return this._flags[node.nodeIndex / this._nodeFieldCount];
},
_markDetachedDOMTreeNodes: function()
{
var flag = this._nodeFlags.detachedDOMTreeNode;
var detachedDOMTreesRoot;
for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
var node = iter.edge.node();
if (node.name() === "(Detached DOM trees)") {
detachedDOMTreesRoot = node;
break;
}
}
if (!detachedDOMTreesRoot)
return;
var detachedDOMTreeRE = /^Detached DOM tree/;
for (var iter = detachedDOMTreesRoot.edges(); iter.hasNext(); iter.next()) {
var node = iter.edge.node();
if (detachedDOMTreeRE.test(node.className())) {
for (var edgesIter = node.edges(); edgesIter.hasNext(); edgesIter.next())
this._flags[edgesIter.edge.node().nodeIndex / this._nodeFieldCount] |= flag;
}
}
},
_markQueriableHeapObjects: function()
{
// Allow runtime properties query for objects accessible from Window objects
// via regular properties, and for DOM wrappers. Trying to access random objects
// can cause a crash due to insonsistent state of internal properties of wrappers.
var flag = this._nodeFlags.canBeQueried;
var hiddenEdgeType = this._edgeHiddenType;
var internalEdgeType = this._edgeInternalType;
var invisibleEdgeType = this._edgeInvisibleType;
var weakEdgeType = this._edgeWeakType;
var edgeToNodeOffset = this._edgeToNodeOffset;
var edgeTypeOffset = this._edgeTypeOffset;
var edgeFieldsCount = this._edgeFieldsCount;
var containmentEdges = this.containmentEdges;
var nodeFieldCount = this._nodeFieldCount;
var firstEdgeIndexes = this._firstEdgeIndexes;
var flags = this._flags;
var list = [];
for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
if (iter.edge.node().isUserRoot())
list.push(iter.edge.node().nodeIndex / nodeFieldCount);
}
while (list.length) {
var nodeOrdinal = list.pop();
if (flags[nodeOrdinal] & flag)
continue;
flags[nodeOrdinal] |= flag;
var beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
var endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
var childNodeOrdinal = childNodeIndex / nodeFieldCount;
if (flags[childNodeOrdinal] & flag)
continue;
var type = containmentEdges[edgeIndex + edgeTypeOffset];
if (type === hiddenEdgeType || type === invisibleEdgeType || type === internalEdgeType || type === weakEdgeType)
continue;
list.push(childNodeOrdinal);
}
}
},
_markPageOwnedNodes: function()
{
var edgeShortcutType = this._edgeShortcutType;
var edgeElementType = this._edgeElementType;
var edgeToNodeOffset = this._edgeToNodeOffset;
var edgeTypeOffset = this._edgeTypeOffset;
var edgeFieldsCount = this._edgeFieldsCount;
var edgeWeakType = this._edgeWeakType;
var firstEdgeIndexes = this._firstEdgeIndexes;
var containmentEdges = this.containmentEdges;
var nodeFieldCount = this._nodeFieldCount;
var nodesCount = this.nodeCount;
var flags = this._flags;
var flag = this._nodeFlags.pageObject;
var visitedMarker = this._nodeFlags.visitedMarker;
var visitedMarkerMask = this._nodeFlags.visitedMarkerMask;
var markerAndFlag = visitedMarker | flag;
var nodesToVisit = new Uint32Array(nodesCount);
var nodesToVisitLength = 0;
var rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount;
var node = this.rootNode();
for (var edgeIndex = firstEdgeIndexes[rootNodeOrdinal], endEdgeIndex = firstEdgeIndexes[rootNodeOrdinal + 1];
edgeIndex < endEdgeIndex;
edgeIndex += edgeFieldsCount) {
var edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
var nodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
if (edgeType === edgeElementType) {
node.nodeIndex = nodeIndex;
if (!node.isDocumentDOMTreesRoot())
continue;
} else if (edgeType !== edgeShortcutType)
continue;
var nodeOrdinal = nodeIndex / nodeFieldCount;
nodesToVisit[nodesToVisitLength++] = nodeOrdinal;
flags[nodeOrdinal] |= visitedMarker;
}
while (nodesToVisitLength) {
var nodeOrdinal = nodesToVisit[--nodesToVisitLength];
flags[nodeOrdinal] |= flag;
flags[nodeOrdinal] &= visitedMarkerMask;
var beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
var endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
var childNodeOrdinal = childNodeIndex / nodeFieldCount;
if (flags[childNodeOrdinal] & markerAndFlag)
continue;
var type = containmentEdges[edgeIndex + edgeTypeOffset];
if (type === edgeWeakType)
continue;
nodesToVisit[nodesToVisitLength++] = childNodeOrdinal;
flags[childNodeOrdinal] |= visitedMarker;
}
}
},
/**
* @override
*/
_calculateStatistics: function()
{
var nodeFieldCount = this._nodeFieldCount;
var nodes = this.nodes;
var nodesLength = nodes.length;
var nodeTypeOffset = this._nodeTypeOffset;
var nodeSizeOffset = this._nodeSelfSizeOffset;;
var nodeNativeType = this._nodeNativeType;
var nodeCodeType = this._nodeCodeType;
var nodeConsStringType = this._nodeConsStringType;
var nodeSlicedStringType = this._nodeSlicedStringType;
var distances = this._nodeDistances;
var sizeNative = 0;
var sizeCode = 0;
var sizeStrings = 0;
var sizeJSArrays = 0;
var sizeSystem = 0;
var node = this.rootNode();
for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
var nodeSize = nodes[nodeIndex + nodeSizeOffset];
var ordinal = nodeIndex / nodeFieldCount;
if (distances[ordinal] >= WebInspector.HeapSnapshotCommon.baseSystemDistance) {
sizeSystem += nodeSize;
continue;
}
var nodeType = nodes[nodeIndex + nodeTypeOffset];
node.nodeIndex = nodeIndex;
if (nodeType === nodeNativeType)
sizeNative += nodeSize;
else if (nodeType === nodeCodeType)
sizeCode += nodeSize;
else if (nodeType === nodeConsStringType || nodeType === nodeSlicedStringType || node.type() === "string")
sizeStrings += nodeSize;
else if (node.name() === "Array")
sizeJSArrays += this._calculateArraySize(node);
}
this._statistics = new WebInspector.HeapSnapshotCommon.Statistics();
this._statistics.total = this.totalSize;
this._statistics.v8heap = this.totalSize - sizeNative;
this._statistics.native = sizeNative;
this._statistics.code = sizeCode;
this._statistics.jsArrays = sizeJSArrays;
this._statistics.strings = sizeStrings;
this._statistics.system = sizeSystem;
},
/**
* @param {!WebInspector.HeapSnapshotNode} node
* @return {number}
*/
_calculateArraySize: function(node)
{
var size = node.selfSize();
var beginEdgeIndex = node.edgeIndexesStart();
var endEdgeIndex = node.edgeIndexesEnd();
var containmentEdges = this.containmentEdges;
var strings = this.strings;
var edgeToNodeOffset = this._edgeToNodeOffset;
var edgeTypeOffset = this._edgeTypeOffset;
var edgeNameOffset = this._edgeNameOffset;
var edgeFieldsCount = this._edgeFieldsCount;
var edgeInternalType = this._edgeInternalType;
for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
var edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
if (edgeType !== edgeInternalType)
continue;
var edgeName = strings[containmentEdges[edgeIndex + edgeNameOffset]];
if (edgeName !== "elements")
continue;
var elementsNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
node.nodeIndex = elementsNodeIndex;
if (node.retainersCount() === 1)
size += node.selfSize();
break;
}
return size;
},
/**
* @return {!WebInspector.HeapSnapshotCommon.Statistics}
*/
getStatistics: function()
{
return this._statistics;
},
__proto__: WebInspector.HeapSnapshot.prototype
};
/**
* @constructor
* @extends {WebInspector.HeapSnapshotNode}
* @param {!WebInspector.JSHeapSnapshot} snapshot
* @param {number=} nodeIndex
*/
WebInspector.JSHeapSnapshotNode = function(snapshot, nodeIndex)
{
WebInspector.HeapSnapshotNode.call(this, snapshot, nodeIndex);
}
WebInspector.JSHeapSnapshotNode.prototype = {
/**
* @return {boolean}
*/
canBeQueried: function()
{
var flags = this._snapshot._flagsOfNode(this);
return !!(flags & this._snapshot._nodeFlags.canBeQueried);
},
/**
* @return {string}
*/
rawName: WebInspector.HeapSnapshotNode.prototype.name,
/**
* @override
* @return {string}
*/
name: function()
{
var snapshot = this._snapshot;
if (this._type() === snapshot._nodeConsStringType) {
var string = snapshot._lazyStringCache[this.nodeIndex];
if (typeof string === "undefined") {
string = this._consStringName();
snapshot._lazyStringCache[this.nodeIndex] = string;
}
return string;
}
return this.rawName();
},
/**
* @return {string}
*/
_consStringName: function()
{
var snapshot = this._snapshot;
var consStringType = snapshot._nodeConsStringType;
var edgeInternalType = snapshot._edgeInternalType;
var edgeFieldsCount = snapshot._edgeFieldsCount;
var edgeToNodeOffset = snapshot._edgeToNodeOffset;
var edgeTypeOffset = snapshot._edgeTypeOffset;
var edgeNameOffset = snapshot._edgeNameOffset;
var strings = snapshot.strings;
var edges = snapshot.containmentEdges;
var firstEdgeIndexes = snapshot._firstEdgeIndexes;
var nodeFieldCount = snapshot._nodeFieldCount;
var nodeTypeOffset = snapshot._nodeTypeOffset;
var nodeNameOffset = snapshot._nodeNameOffset;
var nodes = snapshot.nodes;
var nodesStack = [];
nodesStack.push(this.nodeIndex);
var name = "";
while (nodesStack.length && name.length < 1024) {
var nodeIndex = nodesStack.pop();
if (nodes[nodeIndex + nodeTypeOffset] !== consStringType) {
name += strings[nodes[nodeIndex + nodeNameOffset]];
continue;
}
var nodeOrdinal = nodeIndex / nodeFieldCount;
var beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
var endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
var firstNodeIndex = 0;
var secondNodeIndex = 0;
for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex && (!firstNodeIndex || !secondNodeIndex); edgeIndex += edgeFieldsCount) {
var edgeType = edges[edgeIndex + edgeTypeOffset];
if (edgeType === edgeInternalType) {
var edgeName = strings[edges[edgeIndex + edgeNameOffset]];
if (edgeName === "first")
firstNodeIndex = edges[edgeIndex + edgeToNodeOffset];
else if (edgeName === "second")
secondNodeIndex = edges[edgeIndex + edgeToNodeOffset];
}
}
nodesStack.push(secondNodeIndex);
nodesStack.push(firstNodeIndex);
}
return name;
},
/**
* @override
* @return {string}
*/
className: function()
{
var type = this.type();
switch (type) {
case "hidden":
return "(system)";
case "object":
case "native":
return this.name();
case "code":
return "(compiled code)";
default:
return "(" + type + ")";
}
},
/**
* @override
* @return {number}
*/
classIndex: function()
{
var snapshot = this._snapshot;
var nodes = snapshot.nodes;
var type = nodes[this.nodeIndex + snapshot._nodeTypeOffset];;
if (type === snapshot._nodeObjectType || type === snapshot._nodeNativeType)
return nodes[this.nodeIndex + snapshot._nodeNameOffset];
return -1 - type;
},
/**
* @override
* @return {number}
*/
id: function()
{
var snapshot = this._snapshot;
return snapshot.nodes[this.nodeIndex + snapshot._nodeIdOffset];
},
/**
* @return {boolean}
*/
isHidden: function()
{
return this._type() === this._snapshot._nodeHiddenType;
},
/**
* @return {boolean}
*/
isArray: function()
{
return this._type() === this._snapshot._nodeArrayType;
},
/**
* @return {boolean}
*/
isSynthetic: function()
{
return this._type() === this._snapshot._nodeSyntheticType;
},
/**
* @return {boolean}
*/
isUserRoot: function()
{
return !this.isSynthetic();
},
/**
* @return {boolean}
*/
isDocumentDOMTreesRoot: function()
{
return this.isSynthetic() && this.name() === "(Document DOM trees)";
},
/**
* @override
* @return {!WebInspector.HeapSnapshotCommon.Node}
*/
serialize: function()
{
var result = WebInspector.HeapSnapshotNode.prototype.serialize.call(this);
var flags = this._snapshot._flagsOfNode(this);
if (flags & this._snapshot._nodeFlags.canBeQueried)
result.canBeQueried = true;
if (flags & this._snapshot._nodeFlags.detachedDOMTreeNode)
result.detachedDOMTreeNode = true;
return result;
},
__proto__: WebInspector.HeapSnapshotNode.prototype
};
/**
* @constructor
* @extends {WebInspector.HeapSnapshotEdge}
* @param {!WebInspector.JSHeapSnapshot} snapshot
* @param {number=} edgeIndex
*/
WebInspector.JSHeapSnapshotEdge = function(snapshot, edgeIndex)
{
WebInspector.HeapSnapshotEdge.call(this, snapshot, edgeIndex);
}
WebInspector.JSHeapSnapshotEdge.prototype = {
/**
* @override
* @return {!WebInspector.JSHeapSnapshotEdge}
*/
clone: function()
{
var snapshot = /** @type {!WebInspector.JSHeapSnapshot} */ (this._snapshot);
return new WebInspector.JSHeapSnapshotEdge(snapshot, this.edgeIndex);
},
/**
* @override
* @return {boolean}
*/
hasStringName: function()
{
if (!this.isShortcut())
return this._hasStringName();
return isNaN(parseInt(this._name(), 10));
},
/**
* @return {boolean}
*/
isElement: function()
{
return this._type() === this._snapshot._edgeElementType;
},
/**
* @return {boolean}
*/
isHidden: function()
{
return this._type() === this._snapshot._edgeHiddenType;
},
/**
* @return {boolean}
*/
isWeak: function()
{
return this._type() === this._snapshot._edgeWeakType;
},
/**
* @return {boolean}
*/
isInternal: function()
{
return this._type() === this._snapshot._edgeInternalType;
},
/**
* @return {boolean}
*/
isInvisible: function()
{
return this._type() === this._snapshot._edgeInvisibleType;
},
/**
* @return {boolean}
*/
isShortcut: function()
{
return this._type() === this._snapshot._edgeShortcutType;
},
/**
* @override
* @return {string}
*/
name: function()
{
var name = this._name();
if (!this.isShortcut())
return String(name);
var numName = parseInt(name, 10);
return String(isNaN(numName) ? name : numName);
},
/**
* @override
* @return {string}
*/
toString: function()
{
var name = this.name();
switch (this.type()) {
case "context": return "->" + name;
case "element": return "[" + name + "]";
case "weak": return "[[" + name + "]]";
case "property":
return name.indexOf(" ") === -1 ? "." + name : "[\"" + name + "\"]";
case "shortcut":
if (typeof name === "string")
return name.indexOf(" ") === -1 ? "." + name : "[\"" + name + "\"]";
else
return "[" + name + "]";
case "internal":
case "hidden":
case "invisible":
return "{" + name + "}";
};
return "?" + name + "?";
},
/**
* @return {boolean}
*/
_hasStringName: function()
{
var type = this._type();
var snapshot = this._snapshot;
return type !== snapshot._edgeElementType && type !== snapshot._edgeHiddenType;
},
/**
* @return {string|number}
*/
_name: function()
{
return this._hasStringName() ? this._snapshot.strings[this._nameOrIndex()] : this._nameOrIndex();
},
/**
* @return {number}
*/
_nameOrIndex: function()
{
return this._edges[this.edgeIndex + this._snapshot._edgeNameOffset];
},
/**
* @return {number}
*/
_type: function()
{
return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset];
},
__proto__: WebInspector.HeapSnapshotEdge.prototype
};
/**
* @constructor
* @extends {WebInspector.HeapSnapshotRetainerEdge}
* @param {!WebInspector.JSHeapSnapshot} snapshot
* @param {number} retainerIndex
*/
WebInspector.JSHeapSnapshotRetainerEdge = function(snapshot, retainerIndex)
{
WebInspector.HeapSnapshotRetainerEdge.call(this, snapshot, retainerIndex);
}
WebInspector.JSHeapSnapshotRetainerEdge.prototype = {
/**
* @override
* @return {!WebInspector.JSHeapSnapshotRetainerEdge}
*/
clone: function()
{
var snapshot = /** @type {!WebInspector.JSHeapSnapshot} */ (this._snapshot);
return new WebInspector.JSHeapSnapshotRetainerEdge(snapshot, this.retainerIndex());
},
/**
* @return {boolean}
*/
isHidden: function()
{
return this._edge().isHidden();
},
/**
* @return {boolean}
*/
isInternal: function()
{
return this._edge().isInternal();
},
/**
* @return {boolean}
*/
isInvisible: function()
{
return this._edge().isInvisible();
},
/**
* @return {boolean}
*/
isShortcut: function()
{
return this._edge().isShortcut();
},
/**
* @return {boolean}
*/
isWeak: function()
{
return this._edge().isWeak();
},
__proto__: WebInspector.HeapSnapshotRetainerEdge.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| InspectorFrontendHost.js | 7.06% | (6 / 85) | 0% | (0 / 26) | 0% | (0 / 54) | 7.06% | (6 / 85) | |
| InspectorFrontendHostAPI.js | 100% | (6 / 6) | 100% | (0 / 0) | 0% | (0 / 44) | 100% | (6 / 6) | |
| Platform.js | 2.94% | (1 / 34) | 0% | (0 / 16) | 0% | (0 / 5) | 2.94% | (1 / 34) | |
| ResourceLoader.js | 13.89% | (5 / 36) | 0% | (0 / 8) | 0% | (0 / 9) | 13.89% | (5 / 36) | |
| UserMetrics.js | 9.09% | (1 / 11) | 0% | (0 / 2) | 0% | (0 / 4) | 9.09% | (1 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | 2 1 1 1 1 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {InspectorFrontendHostAPI}
* @suppressGlobalPropertiesCheck
*/
WebInspector.InspectorFrontendHostStub = function()
{
/**
* @param {!Event} event
*/
function stopEventPropagation(event)
{
// Let browser handle Ctrl+/Ctrl- shortcuts in hosted mode.
var zoomModifier = WebInspector.isMac() ? event.metaKey : event.ctrlKey;
if (zoomModifier && (event.keyCode === 187 || event.keyCode === 189))
event.stopPropagation();
}
document.addEventListener("keydown", stopEventPropagation, true);
}
WebInspector.InspectorFrontendHostStub.prototype = {
/**
* @override
* @return {string}
*/
getSelectionBackgroundColor: function()
{
return "#6e86ff";
},
/**
* @override
* @return {string}
*/
getSelectionForegroundColor: function()
{
return "#ffffff";
},
/**
* @override
* @return {string}
*/
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},
/**
* @override
*/
loadCompleted: function()
{
},
/**
* @override
*/
bringToFront: function()
{
this._windowVisible = true;
},
/**
* @override
*/
closeWindow: function()
{
this._windowVisible = false;
},
/**
* @override
* @param {boolean} isDocked
* @param {function()} callback
*/
setIsDocked: function(isDocked, callback)
{
setTimeout(callback, 0);
},
/**
* Requests inspected page to be placed atop of the inspector frontend with specified bounds.
* @override
* @param {{x: number, y: number, width: number, height: number}} bounds
*/
setInspectedPageBounds: function(bounds)
{
},
/**
* @override
*/
inspectElementCompleted: function()
{
},
/**
* @override
* @param {string} origin
* @param {string} script
*/
setInjectedScriptForOrigin: function(origin, script)
{
},
/**
* @override
* @param {string} url
* @suppressGlobalPropertiesCheck
*/
inspectedURLChanged: function(url)
{
document.title = WebInspector.UIString("Developer Tools - %s", url);
},
/**
* @override
* @param {string} text
*/
copyText: function(text)
{
WebInspector.console.error("Clipboard is not enabled in hosted mode. Please inspect using chrome://inspect");
},
/**
* @override
* @param {string} url
*/
openInNewTab: function(url)
{
window.open(url, "_blank");
},
/**
* @override
* @param {string} url
* @param {string} content
* @param {boolean} forceSaveAs
*/
save: function(url, content, forceSaveAs)
{
WebInspector.console.error("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect");
this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.CanceledSaveURL, url);
},
/**
* @override
* @param {string} url
* @param {string} content
*/
append: function(url, content)
{
WebInspector.console.error("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect");
},
/**
* @override
* @param {string} message
*/
sendMessageToBackend: function(message)
{
},
/**
* @override
* @param {string} actionName
* @param {number} actionCode
* @param {number} bucketSize
*/
recordEnumeratedHistogram: function(actionName, actionCode, bucketSize)
{
},
/**
* @override
*/
requestFileSystems: function()
{
this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemsLoaded, []);
},
/**
* @override
* @param {string=} fileSystemPath
*/
addFileSystem: function(fileSystemPath)
{
},
/**
* @override
* @param {string} fileSystemPath
*/
removeFileSystem: function(fileSystemPath)
{
},
/**
* @override
* @param {string} fileSystemId
* @param {string} registeredName
* @return {?DOMFileSystem}
*/
isolatedFileSystem: function(fileSystemId, registeredName)
{
return null;
},
/**
* @override
* @param {string} url
* @param {string} headers
* @param {number} streamId
* @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
*/
loadNetworkResource: function(url, headers, streamId, callback)
{
loadResourcePromise(url).then(function(text) {
WebInspector.ResourceLoader.streamWrite(streamId, text);
callback({statusCode : 200});
}).catch(function() {
callback({statusCode : 404});
});
},
/**
* @override
* @param {function(!Object<string, string>)} callback
*/
getPreferences: function(callback)
{
var prefs = {};
for (var name in window.localStorage)
prefs[name] = window.localStorage[name];
callback(prefs);
},
/**
* @override
* @param {string} name
* @param {string} value
*/
setPreference: function(name, value)
{
window.localStorage[name] = value;
},
/**
* @override
* @param {string} name
*/
removePreference: function(name)
{
delete window.localStorage[name];
},
/**
* @override
*/
clearPreferences: function()
{
window.localStorage.clear();
},
/**
* @override
* @param {!FileSystem} fileSystem
*/
upgradeDraggedFileSystemPermissions: function(fileSystem)
{
},
/**
* @override
* @param {number} requestId
* @param {string} fileSystemPath
*/
indexPath: function(requestId, fileSystemPath)
{
},
/**
* @override
* @param {number} requestId
*/
stopIndexing: function(requestId)
{
},
/**
* @override
* @param {number} requestId
* @param {string} fileSystemPath
* @param {string} query
*/
searchInPath: function(requestId, fileSystemPath, query)
{
},
/**
* @override
* @return {number}
*/
zoomFactor: function()
{
return 1;
},
/**
* @override
*/
zoomIn: function()
{
},
/**
* @override
*/
zoomOut: function()
{
},
/**
* @override
*/
resetZoom: function()
{
},
/**
* @override
* @param {string} shortcuts
*/
setWhitelistedShortcuts: function(shortcuts)
{
},
/**
* @override
* @return {boolean}
*/
isUnderTest: function()
{
return false;
},
/**
* @override
*/
readyForTest: function()
{
},
/**
* @override
* @param {boolean} discoverUsbDevices
* @param {boolean} portForwardingEnabled
* @param {!Adb.PortForwardingConfig} portForwardingConfig
*/
setDevicesDiscoveryConfig: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig)
{
},
/**
* @override
* @param {boolean} enabled
*/
setDevicesUpdatesEnabled: function(enabled)
{
},
/**
* @override
* @param {string} pageId
* @param {string} action
*/
performActionOnRemotePage: function(pageId, action)
{
},
/**
* @override
* @param {string} browserId
* @param {string} url
*/
openRemotePage: function(browserId, url)
{
},
/**
* @override
* @param {number} x
* @param {number} y
* @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
* @param {!Document} document
*/
showContextMenuAtPoint: function(x, y, items, document)
{
throw "Soft context menu should be used";
},
/**
* @override
* @return {boolean}
*/
isHostedMode: function()
{
return true;
}
};
/**
* @type {!InspectorFrontendHostAPI}
*/
var InspectorFrontendHost = window.InspectorFrontendHost || null;
(function(){
function initializeInspectorFrontendHost()
{
if (!InspectorFrontendHost) {
// Instantiate stub for web-hosted mode if necessary.
InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
} else {
// Otherwise add stubs for missing methods that are declared in the interface.
var proto = WebInspector.InspectorFrontendHostStub.prototype;
for (var name in proto) {
var value = proto[name];
if (typeof value !== "function" || InspectorFrontendHost[name])
continue;
InspectorFrontendHost[name] = stub.bind(null, name);
}
}
/**
* @param {string} name
* @return {?}
*/
function stub(name)
{
console.error("Incompatible embedder: method InspectorFrontendHost." + name + " is missing. Using stub instead.");
var args = Array.prototype.slice.call(arguments, 1);
return proto[name].apply(InspectorFrontendHost, args);
}
// Attach the events object.
InspectorFrontendHost.events = new WebInspector.Object();
}
/**
* @constructor
*/
function InspectorFrontendAPIImpl()
{
this._debugFrontend = !!Runtime.queryParam("debugFrontend") || (window["InspectorTest"] && window["InspectorTest"]["debugTest"]);
var descriptors = InspectorFrontendHostAPI.EventDescriptors;
for (var i = 0; i < descriptors.length; ++i)
this[descriptors[i][0]] = this._dispatch.bind(this, descriptors[i][0], descriptors[i][1], descriptors[i][2]);
}
InspectorFrontendAPIImpl.prototype = {
/**
* @param {string} name
* @param {!Array.<string>} signature
* @param {boolean} runOnceLoaded
*/
_dispatch: function(name, signature, runOnceLoaded)
{
var params = Array.prototype.slice.call(arguments, 3);
if (this._debugFrontend)
setImmediate(innerDispatch);
else
innerDispatch();
function innerDispatch()
{
// Single argument methods get dispatched with the param.
if (signature.length < 2) {
try {
InspectorFrontendHost.events.dispatchEventToListeners(name, params[0]);
} catch(e) {
console.error(e + " " + e.stack);
}
return;
}
var data = {};
for (var i = 0; i < signature.length; ++i)
data[signature[i]] = params[i];
try {
InspectorFrontendHost.events.dispatchEventToListeners(name, data);
} catch(e) {
console.error(e + " " + e.stack);
}
}
},
/**
* @param {number} id
* @param {string} chunk
*/
streamWrite: function(id, chunk)
{
WebInspector.ResourceLoader.streamWrite(id, chunk);
}
}
// FIXME: This file is included into both apps, since the devtools_app needs the InspectorFrontendHostAPI only,
// so the host instance should not initialized there.
initializeInspectorFrontendHost();
window.InspectorFrontendAPI = new InspectorFrontendAPIImpl();
WebInspector.setLocalizationPlatform(InspectorFrontendHost.platform());
})();
/**
* @type {!WebInspector.EventTarget}
*/
InspectorFrontendHost.events;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | 1 1 1 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** @interface */ function InspectorFrontendHostAPI() { } /** @typedef {{ type: string, id: (number|undefined), label: (string|undefined), enabled: (boolean|undefined), checked: (boolean|undefined), subItems: (!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>|undefined) }} */ InspectorFrontendHostAPI.ContextMenuDescriptor; /** @typedef {{ statusCode: number, headers: (!Object.<string, string>|undefined) }} */ InspectorFrontendHostAPI.LoadNetworkResourceResult; InspectorFrontendHostAPI.Events = { AddExtensions: "addExtensions", AppendedToURL: "appendedToURL", CanceledSaveURL: "canceledSaveURL", ContextMenuCleared: "contextMenuCleared", ContextMenuItemSelected: "contextMenuItemSelected", DeviceCountUpdated: "deviceCountUpdated", DevicesDiscoveryConfigChanged: "devicesDiscoveryConfigChanged", DevicesPortForwardingStatusChanged: "devicesPortForwardingStatusChanged", DevicesUpdated: "devicesUpdated", DispatchMessage: "dispatchMessage", DispatchMessageChunk: "dispatchMessageChunk", EnterInspectElementMode: "enterInspectElementMode", EvaluateForTestInFrontend: "evaluateForTestInFrontend", FileSystemsLoaded: "fileSystemsLoaded", FileSystemRemoved: "fileSystemRemoved", FileSystemAdded: "fileSystemAdded", FileSystemFilesChanged: "fileSystemFilesChanged", IndexingTotalWorkCalculated: "indexingTotalWorkCalculated", IndexingWorked: "indexingWorked", IndexingDone: "indexingDone", KeyEventUnhandled: "keyEventUnhandled", ReloadInspectedPage: "reloadInspectedPage", RevealSourceLine: "revealSourceLine", SavedURL: "savedURL", SearchCompleted: "searchCompleted", SetInspectedTabId: "setInspectedTabId", SetUseSoftMenu: "setUseSoftMenu", ShowPanel: "showPanel" } InspectorFrontendHostAPI.EventDescriptors = [ [InspectorFrontendHostAPI.Events.AddExtensions, ["extensions"]], [InspectorFrontendHostAPI.Events.AppendedToURL, ["url"]], [InspectorFrontendHostAPI.Events.CanceledSaveURL, ["url"]], [InspectorFrontendHostAPI.Events.ContextMenuCleared, []], [InspectorFrontendHostAPI.Events.ContextMenuItemSelected, ["id"]], [InspectorFrontendHostAPI.Events.DeviceCountUpdated, ["count"]], [InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, ["discoverUsbDevices", "portForwardingEnabled", "portForwardingConfig"]], [InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, ["status"]], [InspectorFrontendHostAPI.Events.DevicesUpdated, ["devices"]], [InspectorFrontendHostAPI.Events.DispatchMessage, ["messageObject"]], [InspectorFrontendHostAPI.Events.DispatchMessageChunk, ["messageChunk", "messageSize"]], [InspectorFrontendHostAPI.Events.EnterInspectElementMode, []], [InspectorFrontendHostAPI.Events.EvaluateForTestInFrontend, ["callId", "script"]], [InspectorFrontendHostAPI.Events.FileSystemsLoaded, ["fileSystems"]], [InspectorFrontendHostAPI.Events.FileSystemRemoved, ["fileSystemPath"]], [InspectorFrontendHostAPI.Events.FileSystemAdded, ["errorMessage", "fileSystem"]], [InspectorFrontendHostAPI.Events.FileSystemFilesChanged, ["paths"]], [InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, ["requestId", "fileSystemPath", "totalWork"]], [InspectorFrontendHostAPI.Events.IndexingWorked, ["requestId", "fileSystemPath", "worked"]], [InspectorFrontendHostAPI.Events.IndexingDone, ["requestId", "fileSystemPath"]], [InspectorFrontendHostAPI.Events.KeyEventUnhandled, ["event"]], [InspectorFrontendHostAPI.Events.ReloadInspectedPage, ["hard"]], [InspectorFrontendHostAPI.Events.RevealSourceLine, ["url", "lineNumber", "columnNumber"]], [InspectorFrontendHostAPI.Events.SavedURL, ["url"]], [InspectorFrontendHostAPI.Events.SearchCompleted, ["requestId", "fileSystemPath", "files"]], [InspectorFrontendHostAPI.Events.SetInspectedTabId, ["tabId"]], [InspectorFrontendHostAPI.Events.SetUseSoftMenu, ["useSoftMenu"]], [InspectorFrontendHostAPI.Events.ShowPanel, ["panelName"]] ]; InspectorFrontendHostAPI.prototype = { /** * @param {string=} fileSystemPath */ addFileSystem: function(fileSystemPath) { }, /** * @param {string} url * @param {string} content */ append: function(url, content) { }, loadCompleted: function() { }, /** * @param {number} requestId * @param {string} fileSystemPath */ indexPath: function(requestId, fileSystemPath) { }, /** * @return {string} */ getSelectionBackgroundColor: function() { }, /** * @return {string} */ getSelectionForegroundColor: function() { }, /** * Requests inspected page to be placed atop of the inspector frontend with specified bounds. * @param {{x: number, y: number, width: number, height: number}} bounds */ setInspectedPageBounds: function(bounds) { }, /** * @param {string} shortcuts */ setWhitelistedShortcuts: function(shortcuts) { }, inspectElementCompleted: function() { }, /** * @param {string} url */ openInNewTab: function(url) { }, /** * @param {string} fileSystemPath */ removeFileSystem: function(fileSystemPath) { }, requestFileSystems: function() { }, /** * @param {string} url * @param {string} content * @param {boolean} forceSaveAs */ save: function(url, content, forceSaveAs) { }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {string} query */ searchInPath: function(requestId, fileSystemPath, query) { }, /** * @param {number} requestId */ stopIndexing: function(requestId) { }, bringToFront: function() { }, closeWindow: function() { }, copyText: function(text) { }, /** * @param {string} url */ inspectedURLChanged: function(url) { }, /** * @param {string} fileSystemId * @param {string} registeredName * @return {?DOMFileSystem} */ isolatedFileSystem: function(fileSystemId, registeredName) { }, /** * @param {string} url * @param {string} headers * @param {number} streamId * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback */ loadNetworkResource: function(url, headers, streamId, callback) { }, /** * @param {function(!Object<string, string>)} callback */ getPreferences: function(callback) { }, /** * @param {string} name * @param {string} value */ setPreference: function(name, value) { }, /** * @param {string} name */ removePreference: function(name) { }, clearPreferences: function() { }, /** * @param {!FileSystem} fileSystem */ upgradeDraggedFileSystemPermissions: function(fileSystem) { }, /** * @return {string} */ platform: function() { }, /** * @param {string} actionName * @param {number} actionCode * @param {number} bucketSize */ recordEnumeratedHistogram: function(actionName, actionCode, bucketSize) { }, /** * @param {string} message */ sendMessageToBackend: function(message) { }, /** * @param {boolean} discoverUsbDevices * @param {boolean} portForwardingEnabled * @param {!Adb.PortForwardingConfig} portForwardingConfig */ setDevicesDiscoveryConfig: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig) { }, /** * @param {boolean} enabled */ setDevicesUpdatesEnabled: function(enabled) { }, /** * @param {string} pageId * @param {string} action */ performActionOnRemotePage: function(pageId, action) { }, /** * @param {string} browserId * @param {string} url */ openRemotePage: function(browserId, url) { }, /** * @param {string} origin * @param {string} script */ setInjectedScriptForOrigin: function(origin, script) { }, /** * @param {boolean} isDocked * @param {function()} callback */ setIsDocked: function(isDocked, callback) { }, /** * @return {number} */ zoomFactor: function() { }, zoomIn: function() { }, zoomOut: function() { }, resetZoom: function() { }, /** * @param {number} x * @param {number} y * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items * @param {!Document} document */ showContextMenuAtPoint: function(x, y, items, document) { }, /** * @return {boolean} */ isUnderTest: function() { }, readyForTest: function() { }, /** * @return {boolean} */ isHostedMode: function() { } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 2 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @return {string}
*/
WebInspector.platform = function()
{
if (!WebInspector._platform)
WebInspector._platform = InspectorFrontendHost.platform();
return WebInspector._platform;
}
/**
* @return {boolean}
*/
WebInspector.isMac = function()
{
if (typeof WebInspector._isMac === "undefined")
WebInspector._isMac = WebInspector.platform() === "mac";
return WebInspector._isMac;
}
/**
* @return {boolean}
*/
WebInspector.isWin = function()
{
if (typeof WebInspector._isWin === "undefined")
WebInspector._isWin = WebInspector.platform() === "windows";
return WebInspector._isWin;
}
/**
* @return {string}
*/
WebInspector.fontFamily = function()
{
if (WebInspector._fontFamily)
return WebInspector._fontFamily;
switch (WebInspector.platform()) {
case "linux":
WebInspector._fontFamily = "Ubuntu, Arial, sans-serif";
break;
case "mac":
WebInspector._fontFamily = "'Lucida Grande', sans-serif";
break;
case "windows":
WebInspector._fontFamily = "'Segoe UI', Tahoma, sans-serif";
break;
}
return WebInspector._fontFamily;
}
/**
* @return {string}
*/
WebInspector.monospaceFontFamily = function()
{
if (WebInspector._monospaceFontFamily)
return WebInspector._monospaceFontFamily;
switch (WebInspector.platform()) {
case "linux":
WebInspector._monospaceFontFamily = "dejavu sans mono, monospace";
break;
case "mac":
WebInspector._monospaceFontFamily = "Menlo, monospace";
break;
case "windows":
WebInspector._monospaceFontFamily = "Consolas, monospace";
break;
}
return WebInspector._monospaceFontFamily;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 2 1 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.ResourceLoader = {}
WebInspector.ResourceLoader._lastStreamId = 0;
/** @type {!Object.<number, !WebInspector.OutputStream>} */
WebInspector.ResourceLoader._boundStreams = {};
/**
* @param {!WebInspector.OutputStream} stream
* @return {number}
*/
WebInspector.ResourceLoader._bindOutputStream = function(stream)
{
WebInspector.ResourceLoader._boundStreams[++WebInspector.ResourceLoader._lastStreamId] = stream;
return WebInspector.ResourceLoader._lastStreamId;
}
/**
* @param {number} id
*/
WebInspector.ResourceLoader._discardOutputStream = function(id)
{
WebInspector.ResourceLoader._boundStreams[id].close();
delete WebInspector.ResourceLoader._boundStreams[id];
}
/**
* @param {number} id
* @param {string} chunk
*/
WebInspector.ResourceLoader.streamWrite = function(id, chunk)
{
WebInspector.ResourceLoader._boundStreams[id].write(chunk);
}
/**
* @param {string} url
* @param {?Object.<string, string>} headers
* @param {function(number, !Object.<string, string>, string)} callback
*/
WebInspector.ResourceLoader.load = function(url, headers, callback)
{
var stream = new WebInspector.StringOutputStream();
WebInspector.ResourceLoader.loadAsStream(url, headers, stream, mycallback);
/**
* @param {number} statusCode
* @param {!Object.<string, string>} headers
*/
function mycallback(statusCode, headers)
{
callback(statusCode, headers, stream.data());
}
}
/**
* @param {string} url
* @param {?Object.<string, string>} headers
* @param {!WebInspector.OutputStream} stream
* @param {function(number, !Object.<string, string>)=} callback
*/
WebInspector.ResourceLoader.loadAsStream = function(url, headers, stream, callback)
{
var streamId = WebInspector.ResourceLoader._bindOutputStream(stream);
var parsedURL = new WebInspector.ParsedURL(url);
if (parsedURL.isDataURL()) {
loadXHR(url)
.then(dataURLDecodeSuccessful)
.catch(dataURLDecodeFailed);
return;
}
var rawHeaders = [];
if (headers) {
for (var key in headers)
rawHeaders.push(key + ": " + headers[key]);
}
InspectorFrontendHost.loadNetworkResource(url, rawHeaders.join("\r\n"), streamId, finishedCallback);
/**
* @param {!InspectorFrontendHostAPI.LoadNetworkResourceResult} response
*/
function finishedCallback(response)
{
if (callback)
callback(response.statusCode, response.headers || {});
WebInspector.ResourceLoader._discardOutputStream(streamId);
}
/**
* @param {string} text
*/
function dataURLDecodeSuccessful(text)
{
WebInspector.ResourceLoader.streamWrite(streamId, text);
finishedCallback(/** @type {!InspectorFrontendHostAPI.LoadNetworkResourceResult} */ ({statusCode : 200}));
}
function dataURLDecodeFailed()
{
finishedCallback(/** @type {!InspectorFrontendHostAPI.LoadNetworkResourceResult} */ ({statusCode : 404}));
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 2 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.UserMetrics = function() { } // Codes below are used to collect UMA histograms in the Chromium port. // Do not change the values below, additional actions are needed on the Chromium side // in order to add more codes. /** @enum {number} */ WebInspector.UserMetrics.Action = { WindowDocked: 1, WindowUndocked: 2, ScriptsBreakpointSet: 3, TimelineStarted: 4, ProfilesCPUProfileTaken: 5, ProfilesHeapProfileTaken: 6, AuditsStarted: 7, ConsoleEvaluated: 8, FileSavedInWorkspace: 9, DeviceModeEnabled: 10, AnimationsPlaybackRateChanged: 11, RevisionApplied: 12, FileSystemDirectoryContentReceived: 13, StyleRuleEdited: 14, CommandEvaluatedInConsolePanel: 15, DOMPropertiesExpanded: 16, ResizedViewInResponsiveMode: 17 } WebInspector.UserMetrics._PanelCodes = { elements: 1, resources: 2, network: 3, sources: 4, timeline: 5, profiles: 6, audits: 7, console: 8, layers: 9, "drawer-console": 10, "drawer-animations": 11, "drawer-network.config": 12, "drawer-rendering": 13, "drawer-sensors": 14, "drawer-sources.search": 15, security: 16 } WebInspector.UserMetrics.prototype = { /** * @param {string} panelName */ panelShown: function(panelName) { var code = WebInspector.UserMetrics._PanelCodes[panelName] || 0; var size = Object.keys(WebInspector.UserMetrics._PanelCodes).length + 1; InspectorFrontendHost.recordEnumeratedHistogram("DevTools.PanelShown", code, size); }, /** * @param {string} drawerId */ drawerShown: function(drawerId) { this.panelShown("drawer-" + drawerId); }, /** * @param {!WebInspector.UserMetrics.Action} action */ actionTaken: function(action) { var size = Object.keys(WebInspector.UserMetrics.Action).length + 1; InspectorFrontendHost.recordEnumeratedHistogram("DevTools.ActionTaken", action, size); } } /** @type {!WebInspector.UserMetrics} */ WebInspector.userMetrics = new WebInspector.UserMetrics(); |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| LayerPaintProfilerView.js | 14.29% | (3 / 21) | 0% | (0 / 6) | 0% | (0 / 6) | 14.29% | (3 / 21) | |
| LayersPanel.js | 1.41% | (1 / 71) | 0% | (0 / 26) | 0% | (0 / 15) | 1.41% | (1 / 71) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {function(!WebInspector.Layer, string=)} showImageForLayerCallback
* @extends {WebInspector.SplitWidget}
*/
WebInspector.LayerPaintProfilerView = function(showImageForLayerCallback)
{
WebInspector.SplitWidget.call(this, true, false);
this._showImageForLayerCallback = showImageForLayerCallback;
this._logTreeView = new WebInspector.PaintProfilerCommandLogView();
this.setSidebarWidget(this._logTreeView);
this._paintProfilerView = new WebInspector.PaintProfilerView(this._showImage.bind(this));
this.setMainWidget(this._paintProfilerView);
this._paintProfilerView.addEventListener(WebInspector.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this);
}
WebInspector.LayerPaintProfilerView.prototype = {
/**
* @param {!WebInspector.Layer} layer
*/
profileLayer: function(layer)
{
this._logTreeView.setCommandLog(null, []);
this._paintProfilerView.setSnapshotAndLog(null, [], null);
/** @type {!WebInspector.AgentLayer} */ (layer).requestSnapshot(onSnapshotDone.bind(this));
/**
* @param {!WebInspector.PaintProfilerSnapshot=} snapshot
* @this {WebInspector.LayerPaintProfilerView}
*/
function onSnapshotDone(snapshot)
{
this._layer = layer;
snapshot.commandLog(onCommandLogDone.bind(this, snapshot));
}
/**
* @param {!WebInspector.PaintProfilerSnapshot=} snapshot
* @param {!Array.<!Object>=} log
* @this {WebInspector.LayerPaintProfilerView}
*/
function onCommandLogDone(snapshot, log)
{
this._logTreeView.setCommandLog(snapshot.target(), log || []);
this._paintProfilerView.setSnapshotAndLog(snapshot || null, log || [], null);
}
},
_onWindowChanged: function()
{
var window = this._paintProfilerView.windowBoundaries();
this._logTreeView.updateWindow(window.left, window.right);
},
/**
* @param {string=} imageURL
*/
_showImage: function(imageURL)
{
this._showImageForLayerCallback(this._layer, imageURL);
},
__proto__: WebInspector.SplitWidget.prototype
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.PanelWithSidebar}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.LayersPanel = function()
{
WebInspector.PanelWithSidebar.call(this, "layers", 225);
this.registerRequiredCSS("timeline/timelinePanel.css");
/** @type {?WebInspector.LayerTreeModel} */
this._model = null;
WebInspector.targetManager.observeTargets(this);
this._layerViewHost = new WebInspector.LayerViewHost();
this._layerTreeOutline = new WebInspector.LayerTreeOutline(this._layerViewHost);
this.panelSidebarElement().appendChild(this._layerTreeOutline.element);
this.setDefaultFocusedElement(this._layerTreeOutline.element);
this._rightSplitWidget = new WebInspector.SplitWidget(false, true, "layerDetailsSplitViewState");
this.splitWidget().setMainWidget(this._rightSplitWidget);
this._layers3DView = new WebInspector.Layers3DView(this._layerViewHost);
this._rightSplitWidget.setMainWidget(this._layers3DView);
this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerSnapshotRequested, this._onSnapshotRequested, this);
this._tabbedPane = new WebInspector.TabbedPane();
this._rightSplitWidget.setSidebarWidget(this._tabbedPane);
this._layerDetailsView = new WebInspector.LayerDetailsView(this._layerViewHost);
this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Details, WebInspector.UIString("Details"), this._layerDetailsView);
this._paintProfilerView = new WebInspector.LayerPaintProfilerView(this._layers3DView.showImageForLayer.bind(this._layers3DView));
this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler, WebInspector.UIString("Profiler"), this._paintProfilerView);
}
WebInspector.LayersPanel.DetailsViewTabs = {
Details: "details",
Profiler: "profiler"
};
WebInspector.LayersPanel.prototype = {
focus: function()
{
this._layerTreeOutline.focus();
},
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (this._model)
this._model.enable();
this._layerTreeOutline.focus();
},
willHide: function()
{
if (this._model)
this._model.disable();
WebInspector.Panel.prototype.willHide.call(this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (this._model)
return;
this._model = WebInspector.LayerTreeModel.fromTarget(target);
if (!this._model)
return;
this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
if (this.isShowing())
this._model.enable();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (!this._model || this._model.target() !== target)
return;
this._model.removeEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
this._model.removeEventListener(WebInspector.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
this._model.disable();
this._model = null;
},
/**
* @param {!WebInspector.DeferredLayerTree} deferredLayerTree
*/
_showLayerTree: function(deferredLayerTree)
{
deferredLayerTree.resolve(this._layerViewHost.setLayerTree.bind(this._layerViewHost));
},
_onLayerTreeUpdated: function()
{
if (this._model)
this._layerViewHost.setLayerTree(this._model.layerTree());
},
/**
* @param {!WebInspector.Event} event
*/
_onLayerPainted: function(event)
{
if (!this._model)
return;
this._layers3DView.setLayerTree(this._model.layerTree());
if (this._layerViewHost.selection() && this._layerViewHost.selection().layer() === event.data)
this._layerDetailsView.update();
},
/**
* @param {!WebInspector.Event} event
*/
_onSnapshotRequested: function(event)
{
var layer = /** @type {!WebInspector.Layer} */ (event.data);
this._tabbedPane.selectTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler);
this._paintProfilerView.profileLayer(layer);
},
__proto__: WebInspector.PanelWithSidebar.prototype
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.LayersPanel.LayerTreeRevealer = function()
{
}
WebInspector.LayersPanel.LayerTreeRevealer.prototype = {
/**
* @override
* @param {!Object} snapshotData
* @return {!Promise}
*/
reveal: function(snapshotData)
{
if (!(snapshotData instanceof WebInspector.DeferredLayerTree))
return Promise.reject(new Error("Internal error: not a WebInspector.DeferredLayerTree"));
var panel = WebInspector.LayersPanel._instance();
WebInspector.inspectorView.setCurrentPanel(panel);
panel._showLayerTree(/** @type {!WebInspector.DeferredLayerTree} */ (snapshotData));
return Promise.resolve();
}
}
/**
* @return {!WebInspector.LayersPanel}
*/
WebInspector.LayersPanel._instance = function()
{
if (!WebInspector.LayersPanel._instanceObject)
WebInspector.LayersPanel._instanceObject = new WebInspector.LayersPanel();
return WebInspector.LayersPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.LayersPanelFactory = function()
{
}
WebInspector.LayersPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.LayersPanel._instance();
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Connections.js | 2.56% | (1 / 39) | 0% | (0 / 4) | 0% | (0 / 12) | 2.56% | (1 / 39) | |
| Main.js | 2.44% | (12 / 492) | 0% | (0 / 157) | 0% | (0 / 72) | 2.44% | (12 / 491) | |
| OverlayController.js | 11.11% | (1 / 9) | 0% | (0 / 4) | 0% | (0 / 2) | 11.11% | (1 / 9) | |
| RenderingOptions.js | 1.92% | (1 / 52) | 0% | (0 / 12) | 0% | (0 / 10) | 1.92% | (1 / 52) | |
| SimpleApp.js | 11.11% | (1 / 9) | 100% | (0 / 0) | 0% | (0 / 4) | 11.11% | (1 / 9) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {InspectorBackendClass.Connection}
*/
WebInspector.MainConnection = function()
{
InspectorBackendClass.Connection.call(this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DispatchMessage, this._dispatchMessage, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DispatchMessageChunk, this._dispatchMessageChunk, this);
}
WebInspector.MainConnection.prototype = {
/**
* @override
* @param {!Object} messageObject
*/
sendMessage: function(messageObject)
{
var message = JSON.stringify(messageObject);
InspectorFrontendHost.sendMessageToBackend(message);
},
/**
* @param {!WebInspector.Event} event
*/
_dispatchMessage: function(event)
{
this.dispatch(/** @type {string} */ (event.data));
},
/**
* @param {!WebInspector.Event} event
*/
_dispatchMessageChunk: function(event)
{
var messageChunk = /** @type {string} */ (event.data["messageChunk"]);
var messageSize = /** @type {number} */ (event.data["messageSize"]);
if (messageSize) {
this._messageBuffer = "";
this._messageSize = messageSize;
}
this._messageBuffer += messageChunk;
if (this._messageBuffer.length === this._messageSize) {
this.dispatch(this._messageBuffer);
this._messageBuffer = "";
this._messageSize = 0;
}
},
__proto__: InspectorBackendClass.Connection.prototype
}
/**
* @constructor
* @extends {InspectorBackendClass.Connection}
* @param {string} url
* @param {function(!InspectorBackendClass.Connection)} onConnectionReady
*/
WebInspector.WebSocketConnection = function(url, onConnectionReady)
{
InspectorBackendClass.Connection.call(this);
this._socket = new WebSocket(url);
this._socket.onmessage = this._onMessage.bind(this);
this._socket.onerror = this._onError.bind(this);
this._socket.onopen = onConnectionReady.bind(null, this);
this._socket.onclose = this.connectionClosed.bind(this, "websocket_closed");
}
/**
* @param {string} url
* @param {function(!InspectorBackendClass.Connection)} onConnectionReady
*/
WebInspector.WebSocketConnection.Create = function(url, onConnectionReady)
{
new WebInspector.WebSocketConnection(url, onConnectionReady);
}
WebInspector.WebSocketConnection.prototype = {
/**
* @param {!MessageEvent} message
*/
_onMessage: function(message)
{
var data = /** @type {string} */ (message.data);
this.dispatch(data);
},
/**
* @param {!Event} error
*/
_onError: function(error)
{
console.error(error);
},
/**
* @override
* @param {!Object} messageObject
*/
sendMessage: function(messageObject)
{
var message = JSON.stringify(messageObject);
this._socket.send(message);
},
__proto__: InspectorBackendClass.Connection.prototype
}
/**
* @constructor
* @extends {InspectorBackendClass.Connection}
*/
WebInspector.StubConnection = function()
{
InspectorBackendClass.Connection.call(this);
}
WebInspector.StubConnection.prototype = {
/**
* @override
* @param {!Object} messageObject
*/
sendMessage: function(messageObject)
{
setTimeout(this._respondWithError.bind(this, messageObject), 0);
},
/**
* @param {!Object} messageObject
*/
_respondWithError: function(messageObject)
{
var error = { message: "This is a stub connection, can't dispatch message.", code: InspectorBackendClass.DevToolsStubErrorCode, data: messageObject };
this.dispatch({ id: messageObject.id, error: error });
},
__proto__: InspectorBackendClass.Connection.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | 2 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {InspectorAgent.Dispatcher}
* @implements {WebInspector.Console.UIDelegate}
* @suppressGlobalPropertiesCheck
*/
WebInspector.Main = function()
{
WebInspector.console.setUIDelegate(this);
WebInspector.Main._instanceForTest = this;
runOnWindowLoad(this._loaded.bind(this));
}
WebInspector.Main.prototype = {
/**
* @override
* @return {!Promise.<undefined>}
*/
showConsole: function()
{
return WebInspector.Revealer.revealPromise(WebInspector.console);
},
_loaded: function()
{
console.timeStamp("Main._loaded");
if (InspectorFrontendHost.isUnderTest())
self.runtime.useTestBase();
InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));
},
/**
* @param {!Object<string, string>} prefs
*/
_gotPreferences: function(prefs)
{
console.timeStamp("Main._gotPreferences");
this._createSettings(prefs);
this._createAppUI();
},
/**
* @param {!Object<string, string>} prefs
* Note: this function is called from testSettings in Tests.js.
*/
_createSettings: function(prefs)
{
// Patch settings from the URL param (for tests).
var settingsParam = Runtime.queryParam("settings");
if (settingsParam) {
try {
var settings = JSON.parse(window.decodeURI(settingsParam));
for (var key in settings)
prefs[key] = settings[key];
} catch(e) {
// Ignore malformed settings.
}
}
this._initializeExperiments(prefs);
WebInspector.settings = new WebInspector.Settings(new WebInspector.SettingsStorage(prefs,
InspectorFrontendHost.setPreference, InspectorFrontendHost.removePreference, InspectorFrontendHost.clearPreferences));
if (!InspectorFrontendHost.isUnderTest())
new WebInspector.VersionController().updateVersion();
},
/**
* @param {!Object<string, string>} prefs
*/
_initializeExperiments: function(prefs)
{
Runtime.experiments.register("accessibilityInspection", "Accessibility Inspection");
Runtime.experiments.register("applyCustomStylesheet", "Allow custom UI themes");
Runtime.experiments.register("blackboxJSFramesOnTimeline", "Blackbox JavaScript frames on Timeline", true);
Runtime.experiments.register("colorContrastRatio", "Contrast ratio line in color picker", true);
Runtime.experiments.register("cpuThrottling", "CPU throttling", true);
Runtime.experiments.register("emptySourceMapAutoStepping", "Empty sourcemap auto-stepping");
Runtime.experiments.register("inputEventsOnTimelineOverview", "Input events on Timeline overview", true);
Runtime.experiments.register("layersPanel", "Layers panel");
Runtime.experiments.register("layoutEditor", "Layout editor", true);
Runtime.experiments.register("inspectTooltip", "Dark inspect element tooltip");
Runtime.experiments.register("liveSASS", "Live SASS", true);
Runtime.experiments.register("multipleTimelineViews", "Multiple main views on Timeline", true);
Runtime.experiments.register("networkRequestHeadersFilterInDetailsView", "Network request headers filter in details view", true);
Runtime.experiments.register("networkRequestsOnTimeline", "Network requests on Timeline", true);
Runtime.experiments.register("privateScriptInspection", "Private script inspection");
Runtime.experiments.register("reducedIndentation", "Reduced indentation in Elements DOM tree");
Runtime.experiments.register("requestBlocking", "Request blocking", true);
Runtime.experiments.register("resolveVariableNames", "Resolve variable names", true);
Runtime.experiments.register("timelineShowAllEvents", "Show all events on Timeline", true);
Runtime.experiments.register("timelineLatencyInfo", "Show input latency events on the Timeline", true);
Runtime.experiments.register("securityPanel", "Security panel");
Runtime.experiments.register("timelineFlowEvents", "Timeline flow events", true);
Runtime.experiments.register("timelineInvalidationTracking", "Timeline invalidation tracking", true);
Runtime.experiments.register("timelineRecordingPerspectives", "Timeline recording perspectives UI");
Runtime.experiments.register("timelineTracingJSProfile", "Timeline tracing based JS profiler", true);
Runtime.experiments.cleanUpStaleExperiments();
if (InspectorFrontendHost.isUnderTest()) {
var testPath = JSON.parse(prefs["testPath"] || "\"\"");
// Enable experiments for testing.
if (testPath.indexOf("layers/") !== -1)
Runtime.experiments.enableForTest("layersPanel");
if (testPath.indexOf("timeline/") !== -1 || testPath.indexOf("layers/") !== -1)
Runtime.experiments.enableForTest("layersPanel");
if (testPath.indexOf("security/") !== -1)
Runtime.experiments.enableForTest("securityPanel");
}
Runtime.experiments.setDefaultExperiments([
"inspectTooltip",
"securityPanel"
]);
},
/**
* @suppressGlobalPropertiesCheck
*/
_createAppUI: function()
{
console.timeStamp("Main._createApp");
// Request filesystems early, we won't create connections until callback is fired. Things will happen in parallel.
WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
WebInspector.isolatedFileSystemManager.initialize(this._didInitializeFileSystemManager.bind(this));
var themeSetting = WebInspector.settings.createSetting("uiTheme", "default");
WebInspector.initializeUIUtils(document, themeSetting);
themeSetting.addChangeListener(WebInspector.reload.bind(WebInspector));
WebInspector.installComponentRootStyles(/** @type {!Element} */ (document.body));
this._addMainEventListeners(document);
var canDock = !!Runtime.queryParam("can_dock");
WebInspector.zoomManager = new WebInspector.ZoomManager(window, InspectorFrontendHost);
WebInspector.inspectorView = new WebInspector.InspectorView();
WebInspector.ContextMenu.initialize();
WebInspector.ContextMenu.installHandler(document);
WebInspector.Tooltip.installHandler(document);
WebInspector.dockController = new WebInspector.DockController(canDock);
WebInspector.multitargetConsoleModel = new WebInspector.MultitargetConsoleModel();
WebInspector.multitargetNetworkManager = new WebInspector.MultitargetNetworkManager();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged.bind(this));
WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
// set order of some sections explicitly
WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));
WebInspector.shortcutsScreen.section(WebInspector.UIString("Debugger"));
WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
WebInspector.fileManager = new WebInspector.FileManager();
WebInspector.workspace = new WebInspector.Workspace();
WebInspector.fileSystemMapping = new WebInspector.FileSystemMapping();
var fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, WebInspector.workspace);
WebInspector.networkMapping = new WebInspector.NetworkMapping(WebInspector.targetManager, WebInspector.workspace, fileSystemWorkspaceBinding, WebInspector.fileSystemMapping);
WebInspector.networkProjectManager = new WebInspector.NetworkProjectManager(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
WebInspector.presentationConsoleMessageHelper = new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);
WebInspector.cssWorkspaceBinding = new WebInspector.CSSWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
WebInspector.debuggerWorkspaceBinding = new WebInspector.DebuggerWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
WebInspector.breakpointManager = new WebInspector.BreakpointManager(null, WebInspector.workspace, WebInspector.networkMapping, WebInspector.targetManager, WebInspector.debuggerWorkspaceBinding);
WebInspector.extensionServer = new WebInspector.ExtensionServer();
new WebInspector.OverlayController();
new WebInspector.ExecutionContextSelector(WebInspector.targetManager, WebInspector.context);
WebInspector.blackboxManager = new WebInspector.BlackboxManager(WebInspector.debuggerWorkspaceBinding, WebInspector.networkMapping);
var autoselectPanel = WebInspector.UIString("auto");
var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());
new WebInspector.Main.PauseListener();
new WebInspector.Main.InspectedNodeRevealer();
new WebInspector.NetworkPanelIndicator();
new WebInspector.SourcesPanelIndicator();
new WebInspector.BackendSettingsSync();
WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
WebInspector.actionRegistry = new WebInspector.ActionRegistry();
WebInspector.shortcutRegistry = new WebInspector.ShortcutRegistry(WebInspector.actionRegistry, document);
WebInspector.ShortcutsScreen.registerShortcuts();
this._registerForwardedShortcuts();
this._registerMessageSinkListener();
var appExtension = self.runtime.extensions(WebInspector.AppProvider)[0];
appExtension.instancePromise().then(this._showAppUI.bind(this));
},
/**
* @param {!Object} appProvider
* @suppressGlobalPropertiesCheck
*/
_showAppUI: function(appProvider)
{
var app = /** @type {!WebInspector.AppProvider} */ (appProvider).createApp();
// It is important to kick controller lifetime after apps are instantiated.
WebInspector.dockController.initialize();
console.timeStamp("Main._presentUI");
app.presentUI(document);
var toggleSearchNodeAction = WebInspector.actionRegistry.action("elements.toggle-element-search");
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.EnterInspectElementMode, toggleSearchNodeAction.execute.bind(toggleSearchNodeAction), this);
WebInspector.inspectorView.createToolbars();
InspectorFrontendHost.loadCompleted();
var extensions = self.runtime.extensions(WebInspector.QueryParamHandler);
for (var extension of extensions) {
var value = Runtime.queryParam(extension.descriptor()["name"]);
if (value !== null)
extension.instancePromise().then(handleQueryParam.bind(null, value));
}
/**
* @param {string} value
* @param {!WebInspector.QueryParamHandler} handler
*/
function handleQueryParam(value, handler)
{
handler.handleQueryParam(value);
}
this._appUIShown = true;
if (this._fileSystemManagerInitialized) {
// Allow UI cycles to repaint prior to creating connection.
setTimeout(this._createConnection.bind(this), 0);
}
},
_didInitializeFileSystemManager: function()
{
this._fileSystemManagerInitialized = true;
if (this._appUIShown)
this._createConnection();
},
_createConnection: function()
{
console.timeStamp("Main._createConnection");
if (Runtime.queryParam("ws")) {
var ws = "ws://" + Runtime.queryParam("ws");
WebInspector.WebSocketConnection.Create(ws, this._connectionEstablished.bind(this));
return;
}
if (!InspectorFrontendHost.isHostedMode()) {
this._connectionEstablished(new WebInspector.MainConnection());
return;
}
this._connectionEstablished(new WebInspector.StubConnection());
},
/**
* @param {!InspectorBackendClass.Connection} connection
*/
_connectionEstablished: function(connection)
{
console.timeStamp("Main._connectionEstablished");
this._mainConnection = connection;
connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected);
/**
* @param {!WebInspector.Event} event
*/
function onDisconnected(event)
{
if (WebInspector._disconnectedScreenWithReasonWasShown)
return;
WebInspector.RemoteDebuggingTerminatedScreen.show(event.data.reason);
}
var targetType = Runtime.queryParam("isSharedWorker") ? WebInspector.Target.Type.ServiceWorker : WebInspector.Target.Type.Page;
this._mainTarget = WebInspector.targetManager.createTarget(WebInspector.UIString("Main"), targetType, connection, null);
console.timeStamp("Main._mainTargetCreated");
this._registerShortcuts();
this._mainTarget.registerInspectorDispatcher(this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ReloadInspectedPage, this._reloadInspectedPage, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.EvaluateForTestInFrontend, this._evaluateForTestInFrontend, this);
if (this._mainTarget.isServiceWorker() || this._mainTarget.isPage())
this._mainTarget.runtimeAgent().run();
this._mainTarget.inspectorAgent().enable();
InspectorFrontendHost.readyForTest();
// Asynchronously run the extensions.
setTimeout(lateInitialization, 0);
function lateInitialization()
{
console.timeStamp("Main.lateInitialization");
WebInspector.extensionServer.initializeExtensions();
}
},
_registerForwardedShortcuts: function()
{
/** @const */ var forwardedActions = ["main.toggle-dock", "debugger.toggle-breakpoints-active", "debugger.toggle-pause", "commandMenu.show"];
var actionKeys = WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey);
InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
},
_registerMessageSinkListener: function()
{
WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded, messageAdded);
/**
* @param {!WebInspector.Event} event
*/
function messageAdded(event)
{
var message = /** @type {!WebInspector.Console.Message} */ (event.data);
if (message.show)
WebInspector.console.show();
}
},
_documentClick: function(event)
{
var target = event.target;
if (target.shadowRoot)
target = event.deepElementFromPoint();
if (!target)
return;
var anchor = target.enclosingNodeOrSelfWithNodeName("a");
if (!anchor || !anchor.href)
return;
// Prevent the link from navigating, since we don't do any navigation by following links normally.
event.consume(true);
if (anchor.preventFollow)
return;
function followLink()
{
if (WebInspector.isBeingEdited(target))
return;
if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
return;
var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(anchor.href);
if (uiSourceCode) {
WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber || 0, anchor.columnNumber || 0));
return;
}
var resource = WebInspector.resourceForURL(anchor.href);
if (resource) {
WebInspector.Revealer.reveal(resource);
return;
}
var request = WebInspector.NetworkLog.requestForURL(anchor.href);
if (request) {
WebInspector.Revealer.reveal(request);
return;
}
InspectorFrontendHost.openInNewTab(anchor.href);
}
if (WebInspector.followLinkTimeout)
clearTimeout(WebInspector.followLinkTimeout);
if (anchor.preventFollowOnDoubleClick) {
// Start a timeout if this is the first click, if the timeout is canceled
// before it fires, then a double clicked happened or another link was clicked.
if (event.detail === 1)
WebInspector.followLinkTimeout = setTimeout(followLink, 333);
return;
}
if (!anchor.classList.contains("webkit-html-external-link"))
followLink();
else
InspectorFrontendHost.openInNewTab(anchor.href);
},
_registerShortcuts: function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
var keys = [
shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
keys = [
shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
var toggleConsoleLabel = WebInspector.UIString("Show console");
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle drawer"));
if (WebInspector.dockController.canDock()) {
section.addKey(shortcut.makeDescriptor("M", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle device mode"));
section.addKey(shortcut.makeDescriptor("D", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle dock side"));
}
section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
var advancedSearchShortcutModifier = WebInspector.isMac()
? WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt
: WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift;
var advancedSearchShortcut = shortcut.makeDescriptor("f", advancedSearchShortcutModifier);
section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
var inspectElementModeShortcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction("elements.toggle-element-search");
section.addKey(inspectElementModeShortcuts[0], WebInspector.UIString("Select node to inspect"));
var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
if (WebInspector.isMac()) {
keys = [
shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
}
},
_postDocumentKeyDown: function(event)
{
if (event.handled)
return;
var target = event.deepActiveElement();
if (target) {
var anchor = target.enclosingNodeOrSelfWithNodeName("a");
if (anchor && anchor.preventFollow)
event.preventDefault();
}
if (!WebInspector.Dialog.hasInstance() && WebInspector.inspectorView.currentPanel()) {
WebInspector.inspectorView.currentPanel().handleShortcut(event);
if (event.handled) {
event.consume(true);
return;
}
}
WebInspector.shortcutRegistry.handleShortcut(event);
},
_documentCanCopy: function(event)
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel["handleCopyEvent"])
event.preventDefault();
},
_documentCopy: function(event)
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel["handleCopyEvent"])
panel["handleCopyEvent"](event);
},
_documentCut: function(event)
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel["handleCutEvent"])
panel["handleCutEvent"](event);
},
_documentPaste: function(event)
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel["handlePasteEvent"])
panel["handlePasteEvent"](event);
},
_contextMenuEventFired: function(event)
{
if (event.handled || event.target.classList.contains("popup-glasspane"))
event.preventDefault();
},
/**
* @param {!Document} document
*/
_addMainEventListeners: function(document)
{
document.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false);
document.addEventListener("beforecopy", this._documentCanCopy.bind(this), true);
document.addEventListener("copy", this._documentCopy.bind(this), false);
document.addEventListener("cut", this._documentCut.bind(this), false);
document.addEventListener("paste", this._documentPaste.bind(this), false);
document.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
document.addEventListener("click", this._documentClick.bind(this), false);
},
/**
* @param {!WebInspector.Event} event
*/
_reloadInspectedPage: function(event)
{
var hard = /** @type {boolean} */ (event.data);
WebInspector.Main._reloadPage(hard);
},
/**
* @override
* @param {string} reason
*/
detached: function(reason)
{
WebInspector._disconnectedScreenWithReasonWasShown = true;
WebInspector.RemoteDebuggingTerminatedScreen.show(reason);
},
/**
* @override
*/
targetCrashed: function()
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(this._mainTarget);
if (debuggerModel)
WebInspector.TargetCrashedScreen.show(debuggerModel);
},
_onSuspendStateChanged: function()
{
var suspended = WebInspector.targetManager.allTargetsSuspended();
WebInspector.inspectorView.onSuspendStateChanged(suspended);
},
/**
* @param {!WebInspector.Event} event
*/
_evaluateForTestInFrontend: function(event)
{
if (!InspectorFrontendHost.isUnderTest())
return;
var callId = /** @type {number} */ (event.data["callId"]);
var script = /** @type {number} */ (event.data["script"]);
/**
* @suppressGlobalPropertiesCheck
*/
function invokeMethod()
{
try {
script = script + "//# sourceURL=evaluateInWebInspector" + callId + ".js";
window.eval(script);
} catch (e) {
console.error(e.stack);
}
}
this._mainConnection.runAfterPendingDispatches(invokeMethod);
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.Main.ReloadActionDelegate = function()
{
}
WebInspector.Main.ReloadActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
switch (actionId) {
case "main.reload":
WebInspector.Main._reloadPage(false);
return true;
case "main.hard-reload":
WebInspector.Main._reloadPage(true);
return true;
case "main.debug-reload":
WebInspector.reload();
return true;
}
return false;
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.Main.ZoomActionDelegate = function()
{
}
WebInspector.Main.ZoomActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
if (InspectorFrontendHost.isHostedMode())
return false;
switch (actionId) {
case "main.zoom-in":
InspectorFrontendHost.zoomIn();
return true;
case "main.zoom-out":
InspectorFrontendHost.zoomOut();
return true;
case "main.zoom-reset":
InspectorFrontendHost.resetZoom();
return true;
}
return false;
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.Main.SearchActionDelegate = function()
{
}
WebInspector.Main.SearchActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var searchableView = WebInspector.SearchableView.fromElement(WebInspector.currentFocusElement()) || WebInspector.inspectorView.currentPanel().searchableView();
if (!searchableView)
return false;
switch (actionId) {
case "main.search-in-panel.find":
return searchableView.handleFindShortcut();
case "main.search-in-panel.cancel":
return searchableView.handleCancelSearchShortcut();
case "main.search-in-panel.find-next":
return searchableView.handleFindNextShortcut();
case "main.search-in-panel.find-previous":
return searchableView.handleFindPreviousShortcut();
}
return false;
}
}
/**
* @param {boolean} hard
*/
WebInspector.Main._reloadPage = function(hard)
{
if (!WebInspector.targetManager.hasTargets())
return;
if (WebInspector.targetManager.mainTarget().isServiceWorker())
return;
WebInspector.targetManager.reloadPage(hard);
}
/**
* @param {string} ws
*/
WebInspector.Main._addWebSocketTarget = function(ws)
{
/**
* @param {!InspectorBackendClass.Connection} connection
*/
function callback(connection)
{
WebInspector.targetManager.createTarget(ws, WebInspector.Target.Type.Page, connection, null);
}
new WebInspector.WebSocketConnection(ws, callback);
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.Main.WarningErrorCounter = function()
{
WebInspector.Main.WarningErrorCounter._instanceForTest = this;
this._counter = createElement("div");
this._counter.addEventListener("click", WebInspector.console.show.bind(WebInspector.console), false);
this._toolbarItem = new WebInspector.ToolbarItem(this._counter);
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(this._counter, "main/errorWarningCounter.css");
this._errors = this._createItem(shadowRoot, "error-icon");
this._revokedErrors = this._createItem(shadowRoot, "revokedError-icon");
this._warnings = this._createItem(shadowRoot, "warning-icon");
this._titles = [];
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._update, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._update, this);
WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageUpdated, this._update, this);
this._update();
}
WebInspector.Main.WarningErrorCounter.prototype = {
/**
* @param {!Node} shadowRoot
* @param {string} iconType
* @return {!{item: !Element, text: !Element}}
*/
_createItem: function(shadowRoot, iconType)
{
var item = createElementWithClass("span", "counter-item");
var icon = item.createChild("label", "", "dt-icon-label");
icon.type = iconType;
var text = icon.createChild("span");
shadowRoot.appendChild(item);
return {item: item, text: text};
},
/**
* @param {!{item: !Element, text: !Element}} item
* @param {number} count
* @param {boolean} first
* @param {string} title
*/
_updateItem: function(item, count, first, title)
{
item.item.classList.toggle("hidden", !count);
item.item.classList.toggle("counter-item-first", first);
item.text.textContent = count;
if (count)
this._titles.push(title);
},
_update: function()
{
var errors = 0;
var revokedErrors = 0;
var warnings = 0;
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i) {
errors += targets[i].consoleModel.errors();
revokedErrors += targets[i].consoleModel.revokedErrors();
warnings += targets[i].consoleModel.warnings();
}
this._titles = [];
this._toolbarItem.setVisible(!!(errors || revokedErrors || warnings));
this._updateItem(this._errors, errors, false, WebInspector.UIString(errors === 1 ? "%d error" : "%d errors", errors));
this._updateItem(this._revokedErrors, revokedErrors, !errors, WebInspector.UIString(revokedErrors === 1 ? "%d handled promise rejection" : "%d handled promise rejections", revokedErrors));
this._updateItem(this._warnings, warnings, !errors && !revokedErrors, WebInspector.UIString(warnings === 1 ? "%d warning" : "%d warnings", warnings));
this._counter.title = this._titles.join(", ");
WebInspector.inspectorView.toolbarItemResized();
},
/**
* @override
* @return {?WebInspector.ToolbarItem}
*/
item: function()
{
return this._toolbarItem;
}
}
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.Main.MainMenuItem = function()
{
this._item = new WebInspector.ToolbarButton(WebInspector.UIString("Customize and control DevTools"), "menu-toolbar-item");
this._item.addEventListener("mousedown", this._mouseDown, this);
}
WebInspector.Main.MainMenuItem.prototype = {
/**
* @override
* @return {?WebInspector.ToolbarItem}
*/
item: function()
{
return this._item;
},
/**
* @param {!WebInspector.Event} event
*/
_mouseDown: function(event)
{
var contextMenu = new WebInspector.ContextMenu(/** @type {!Event} */(event.data),
true,
this._item.element.totalOffsetLeft(),
this._item.element.totalOffsetTop() + this._item.element.offsetHeight);
if (WebInspector.dockController.canDock()) {
var dockItemElement = createElementWithClass("div", "flex-centered flex-auto");
var titleElement = dockItemElement.createChild("span", "flex-auto");
titleElement.textContent = WebInspector.UIString("Dock side");
var toggleDockSideShorcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.toggle-dock");
titleElement.title = WebInspector.UIString("Placement of DevTools relative to the page. (%s to restore last position)", toggleDockSideShorcuts[0].name);
dockItemElement.appendChild(titleElement);
var dockItemToolbar = new WebInspector.Toolbar("", dockItemElement);
dockItemToolbar.makeBlueOnHover();
var undock = new WebInspector.ToolbarToggle(WebInspector.UIString("Undock into separate window"), "dock-toolbar-item-undock");
var bottom = new WebInspector.ToolbarToggle(WebInspector.UIString("Dock to bottom"), "dock-toolbar-item-bottom");
var right = new WebInspector.ToolbarToggle(WebInspector.UIString("Dock to right"), "dock-toolbar-item-right");
undock.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.Undocked));
bottom.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.DockedToBottom));
right.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.DockedToRight));
undock.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.Undocked);
bottom.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.DockedToBottom);
right.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.DockedToRight);
dockItemToolbar.appendToolbarItem(undock);
dockItemToolbar.appendToolbarItem(bottom);
dockItemToolbar.appendToolbarItem(right);
contextMenu.appendCustomItem(dockItemElement);
contextMenu.appendSeparator();
}
/**
* @param {string} side
*/
function setDockSide(side)
{
WebInspector.dockController.setDockSide(side);
contextMenu.discard();
}
contextMenu.appendAction("main.toggle-drawer", WebInspector.inspectorView.drawerVisible() ? WebInspector.UIString("Hide console") : WebInspector.UIString("Show console"));
contextMenu.appendItemsAtLocation("mainMenu");
contextMenu.show();
}
}
/**
* @constructor
*/
WebInspector.NetworkPanelIndicator = function()
{
var manager = WebInspector.multitargetNetworkManager;
manager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged, updateVisibility);
var blockedURLsSetting = WebInspector.moduleSetting("blockedURLs");
blockedURLsSetting.addChangeListener(updateVisibility);
updateVisibility();
function updateVisibility()
{
if (manager.isThrottling()) {
WebInspector.inspectorView.setPanelIcon("network", "warning-icon", WebInspector.UIString("Network throttling is enabled"));
} else if (blockedURLsSetting.get().length) {
WebInspector.inspectorView.setPanelIcon("network", "warning-icon", WebInspector.UIString("Requests may be blocked"));
} else {
WebInspector.inspectorView.setPanelIcon("network", "", "");
}
}
}
/**
* @constructor
*/
WebInspector.SourcesPanelIndicator = function()
{
WebInspector.moduleSetting("javaScriptDisabled").addChangeListener(javaScriptDisabledChanged);
javaScriptDisabledChanged();
function javaScriptDisabledChanged()
{
var javaScriptDisabled = WebInspector.moduleSetting("javaScriptDisabled").get();
if (javaScriptDisabled) {
WebInspector.inspectorView.setPanelIcon("sources", "warning-icon", WebInspector.UIString("JavaScript is disabled"));
} else {
WebInspector.inspectorView.setPanelIcon("sources", "", "");
}
}
}
/**
* @constructor
*/
WebInspector.Main.PauseListener = function()
{
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
}
WebInspector.Main.PauseListener.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_debuggerPaused: function(event)
{
WebInspector.targetManager.removeModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
var debuggerPausedDetails = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data);
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
WebInspector.context.setFlavor(WebInspector.Target, debuggerModel.target());
WebInspector.Revealer.reveal(debuggerPausedDetails);
}
}
/**
* @constructor
*/
WebInspector.Main.InspectedNodeRevealer = function()
{
WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeInspected, this._inspectNode, this);
}
WebInspector.Main.InspectedNodeRevealer.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_inspectNode: function(event)
{
var deferredNode = /** @type {!WebInspector.DeferredDOMNode} */ (event.data);
WebInspector.Revealer.reveal(deferredNode);
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {string} reason
*/
WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("main/remoteDebuggingTerminatedScreen.css");
var message = this.contentElement.createChild("div", "message");
message.createChild("span").textContent = WebInspector.UIString("Debugging connection was closed. Reason: ");
message.createChild("span", "reason").textContent = reason;
this.contentElement.createChild("div", "message").textContent = WebInspector.UIString("Reconnect when ready by reopening DevTools.");
}
/**
* @param {string} reason
*/
WebInspector.RemoteDebuggingTerminatedScreen.show = function(reason)
{
var dialog = new WebInspector.Dialog();
dialog.setWrapsContent(true);
dialog.addCloseButton();
dialog.setDimmed(true);
new WebInspector.RemoteDebuggingTerminatedScreen(reason).show(dialog.element);
dialog.show();
}
WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {function()} hideCallback
* @extends {WebInspector.VBox}
*/
WebInspector.TargetCrashedScreen = function(hideCallback)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("main/targetCrashedScreen.css");
this.contentElement.createChild("div", "message").textContent = WebInspector.UIString("DevTools was disconnected from the page.");
this.contentElement.createChild("div", "message").textContent = WebInspector.UIString("Once page is reloaded, DevTools will automatically reconnect.");
this._hideCallback = hideCallback;
}
/**
* @param {!WebInspector.DebuggerModel} debuggerModel
*/
WebInspector.TargetCrashedScreen.show = function(debuggerModel)
{
var dialog = new WebInspector.Dialog();
dialog.setWrapsContent(true);
dialog.addCloseButton();
dialog.setDimmed(true);
var hideBound = dialog.detach.bind(dialog, false);
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, hideBound);
new WebInspector.TargetCrashedScreen(onHide).show(dialog.element);
dialog.show();
function onHide()
{
debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, hideBound);
}
}
WebInspector.TargetCrashedScreen.prototype = {
/**
* @override
*/
willHide: function()
{
this._hideCallback.call(null);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.BackendSettingsSync = function()
{
this._autoAttachSetting = WebInspector.settings.moduleSetting("autoAttachToCreatedPages");
this._autoAttachSetting.addChangeListener(this._update, this);
this._disableJavascriptSetting = WebInspector.settings.moduleSetting("javaScriptDisabled");
this._disableJavascriptSetting.addChangeListener(this._update, this);
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.BackendSettingsSync.prototype = {
_update: function()
{
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)) {
target.pageAgent().setAutoAttachToCreatedPages(this._autoAttachSetting.get());
target.emulationAgent().setScriptExecutionDisabled(this._disableJavascriptSetting.get());
}
},
/**
* @param {!WebInspector.Target} target
* @override
*/
targetAdded: function(target)
{
target.pageAgent().setAutoAttachToCreatedPages(this._autoAttachSetting.get());
target.emulationAgent().setScriptExecutionDisabled(this._disableJavascriptSetting.get());
target.renderingAgent().setShowViewportSizeOnResize(true);
},
/**
* @param {!WebInspector.Target} target
* @override
*/
targetRemoved: function(target)
{
}
}
/**
* @constructor
* @implements {WebInspector.SettingUI}
*/
WebInspector.ShowMetricsRulersSettingUI = function()
{
}
WebInspector.ShowMetricsRulersSettingUI.prototype = {
/**
* @override
* @return {?Element}
*/
settingElement: function()
{
return WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show rulers"), WebInspector.moduleSetting("showMetricsRulers"));
}
}
new WebInspector.Main();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.OverlayController = function() { WebInspector.moduleSetting("disablePausedStateOverlay").addChangeListener(this._updateOverlayMessage, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._updateOverlayMessage, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._updateOverlayMessage, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._updateOverlayMessage, this); } WebInspector.OverlayController.prototype = { /** * @param {!WebInspector.Event} event */ _updateOverlayMessage: function(event) { var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target); var message = debuggerModel.isPaused() && !WebInspector.moduleSetting("disablePausedStateOverlay").get() ? WebInspector.UIString("Paused in debugger") : undefined; debuggerModel.target().pageAgent().setOverlayMessage(message); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.RenderingOptionsView = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("main/renderingOptions.css");
/** @type {!Map.<string, !Element>} */
this._settings = new Map();
this._appendCheckbox(WebInspector.UIString("Enable paint flashing"), "setShowPaintRects");
this._appendCheckbox(WebInspector.UIString("Show layer borders"), "setShowDebugBorders");
this._appendCheckbox(WebInspector.UIString("Show FPS meter"), "setShowFPSCounter");
var scrollingTitle = WebInspector.UIString("Shows areas of the page that slow down scrolling:\nTouch and mousewheel event listeners can delay scrolling.\nSome areas need to repaint their content when scrolled.");
this._appendCheckbox(WebInspector.UIString("Show scrolling perf issues"), "setShowScrollBottleneckRects", scrollingTitle);
// CSS media.
var mediaRow = this.contentElement.createChild("div", "media-row");
var checkboxLabel = createCheckboxLabel(WebInspector.UIString("Emulate media"), false);
this._mediaCheckbox = checkboxLabel.checkboxElement;
this._mediaCheckbox.addEventListener("click", this._mediaToggled.bind(this), false);
mediaRow.appendChild(checkboxLabel);
this._mediaSelect = mediaRow.createChild("select", "chrome-select");
this._mediaSelect.appendChild(new Option(WebInspector.UIString("print"), "print"));
this._mediaSelect.appendChild(new Option(WebInspector.UIString("screen"), "screen"));
this._mediaSelect.addEventListener("change", this._mediaToggled.bind(this), false);
this._mediaSelect.disabled = true;
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.RenderingOptionsView.prototype = {
/**
* @param {string} label
* @param {string} setterName
* @param {string=} title
*/
_appendCheckbox: function(label, setterName, title)
{
var checkboxLabel = createCheckboxLabel(label, false);
this._settings.set(setterName, checkboxLabel.checkboxElement);
checkboxLabel.checkboxElement.addEventListener("click", this._settingToggled.bind(this, setterName));
if (title)
checkboxLabel.title = title;
this.contentElement.appendChild(checkboxLabel);
},
/**
* @param {string} setterName
*/
_settingToggled: function(setterName)
{
var enabled = this._settings.get(setterName).checked;
var targets = WebInspector.targetManager.targets(WebInspector.Target.Type.Page);
for (var i = 0; i < targets.length; ++i)
targets[i].renderingAgent()[setterName](enabled);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
for (var setterName of this._settings.keysArray()) {
if (this._settings.get(setterName).checked)
target.renderingAgent()[setterName](true);
}
if (this._mediaCheckbox.checked)
this._applyPrintMediaOverride(target);
},
_mediaToggled: function()
{
this._mediaSelect.disabled = !this._mediaCheckbox.checked;
var targets = WebInspector.targetManager.targets(WebInspector.Target.Type.Page);
for (var target of targets)
this._applyPrintMediaOverride(target);
},
/**
* @param {!WebInspector.Target} target
*/
_applyPrintMediaOverride: function(target)
{
target.emulationAgent().setEmulatedMedia(this._mediaCheckbox.checked ? this._mediaSelect.value : "");
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (cssModel)
cssModel.mediaQueryResultChanged();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
},
__proto__: WebInspector.VBox.prototype
}
/**
* @return {!WebInspector.RenderingOptionsView}
*/
WebInspector.RenderingOptionsView.instance = function()
{
if (!WebInspector.RenderingOptionsView._instanceObject)
WebInspector.RenderingOptionsView._instanceObject = new WebInspector.RenderingOptionsView();
return WebInspector.RenderingOptionsView._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.RenderingOptionsView.ShowActionDelegate = function()
{
}
WebInspector.RenderingOptionsView.ShowActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
WebInspector.inspectorView.showViewInDrawer("rendering");
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.App}
*/
WebInspector.SimpleApp = function()
{
};
WebInspector.SimpleApp.prototype = {
/**
* @override
* @param {!Document} document
*/
presentUI: function(document)
{
var rootView = new WebInspector.RootView();
WebInspector.inspectorView.show(rootView.element);
WebInspector.inspectorView.showInitialPanel();
rootView.attachToDocument(document);
}
};
/**
* @constructor
* @implements {WebInspector.AppProvider}
*/
WebInspector.SimpleAppProvider = function()
{
};
WebInspector.SimpleAppProvider.prototype = {
/**
* @override
* @return {!WebInspector.App}
*/
createApp: function()
{
return new WebInspector.SimpleApp();
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| BlockedURLsPane.js | 3.01% | (4 / 133) | 0% | (0 / 28) | 0% | (0 / 21) | 3.01% | (4 / 133) | |
| EventSourceMessagesView.js | 2.33% | (1 / 43) | 0% | (0 / 8) | 0% | (0 / 7) | 2.33% | (1 / 43) | |
| FilterSuggestionBuilder.js | 1.11% | (1 / 90) | 0% | (0 / 38) | 0% | (0 / 7) | 1.11% | (1 / 90) | |
| HARWriter.js | 2.22% | (1 / 45) | 0% | (0 / 20) | 0% | (0 / 6) | 2.22% | (1 / 45) | |
| JSONView.js | 1.04% | (1 / 96) | 0% | (0 / 83) | 0% | (0 / 9) | 1.04% | (1 / 96) | |
| NetworkConfigView.js | 6% | (6 / 100) | 0% | (0 / 20) | 0% | (0 / 15) | 6% | (6 / 100) | |
| NetworkDataGridNode.js | 0.27% | (1 / 375) | 0% | (0 / 204) | 0% | (0 / 37) | 0.28% | (1 / 358) | |
| NetworkItemView.js | 4.35% | (2 / 46) | 0% | (0 / 16) | 0% | (0 / 12) | 4.35% | (2 / 46) | |
| NetworkLogView.js | 1.16% | (11 / 947) | 0% | (0 / 351) | 0% | (0 / 123) | 1.16% | (11 / 945) | |
| NetworkOverview.js | 1.91% | (3 / 157) | 0% | (0 / 40) | 0% | (0 / 15) | 1.91% | (3 / 157) | |
| NetworkPanel.js | 1.76% | (5 / 284) | 0% | (0 / 83) | 0% | (0 / 64) | 1.76% | (5 / 284) | |
| NetworkTimeCalculator.js | 1.8% | (2 / 111) | 0% | (0 / 68) | 0% | (0 / 34) | 1.8% | (2 / 111) | |
| RequestCookiesView.js | 3.85% | (1 / 26) | 0% | (0 / 14) | 0% | (0 / 6) | 3.85% | (1 / 26) | |
| RequestHTMLView.js | 8.33% | (1 / 12) | 100% | (0 / 0) | 0% | (0 / 4) | 8.33% | (1 / 12) | |
| RequestHeadersView.js | 1.13% | (3 / 265) | 0% | (0 / 76) | 0% | (0 / 36) | 1.15% | (3 / 262) | |
| RequestPreviewView.js | 1.61% | (1 / 62) | 0% | (0 / 52) | 0% | (0 / 9) | 1.61% | (1 / 62) | |
| RequestResponseView.js | 5.71% | (2 / 35) | 0% | (0 / 25) | 0% | (0 / 10) | 5.71% | (2 / 35) | |
| RequestTimingView.js | 3.05% | (4 / 131) | 0% | (0 / 57) | 0% | (0 / 10) | 3.05% | (4 / 131) | |
| RequestView.js | 6.25% | (1 / 16) | 0% | (0 / 11) | 0% | (0 / 3) | 6.25% | (1 / 16) | |
| ResourceWebSocketFrameView.js | 1.3% | (1 / 77) | 0% | (0 / 10) | 0% | (0 / 16) | 1.3% | (1 / 77) | |
| XMLView.js | 1.41% | (1 / 71) | 0% | (0 / 28) | 0% | (0 / 10) | 1.41% | (1 / 71) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | 2 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.BlockedURLsPane = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("network/blockedURLsPane.css");
this.contentElement.classList.add("blocked-urls-pane");
WebInspector.BlockedURLsPane._instance = this;
this._blockedURLsSetting = WebInspector.moduleSetting("blockedURLs");
this._blockedURLsSetting.addChangeListener(this._update, this);
this._toolbar = new WebInspector.Toolbar("", this.contentElement);
this._toolbar.element.addEventListener("click", consumeEvent);
var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add pattern"), "add-toolbar-item");
addButton.addEventListener("click", this._addButtonClicked.bind(this));
this._toolbar.appendToolbarItem(addButton);
var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Remove all"), "clear-toolbar-item");
clearButton.addEventListener("click", this._removeAll.bind(this));
this._toolbar.appendToolbarItem(clearButton);
this._emptyElement = this.contentElement.createChild("div", "no-blocked-urls");
this._emptyElement.createChild("span").textContent = WebInspector.UIString("Requests are not blocked. ");
var addLink = this._emptyElement.createChild("span", "link");
addLink.textContent = WebInspector.UIString("Add pattern.");
addLink.href = "";
addLink.addEventListener("click", this._addButtonClicked.bind(this), false);
this._emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true);
this._listElement = this.contentElement.createChild("div", "blocked-urls-list");
/** @type {!Map<string, number>} */
this._blockedCountForUrl = new Map();
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
this._updateThrottler = new WebInspector.Throttler(200);
this._update();
}
WebInspector.BlockedURLsPane.prototype = {
/**
* @param {!Event} event
*/
_emptyElementContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^pattern"), this._addButtonClicked.bind(this));
contextMenu.show();
},
_addButtonClicked: function()
{
this._emptyElement.classList.add("hidden");
var element = this._createElement("", this._blockedURLsSetting.get().length);
this._listElement.appendChild(element);
element.scrollIntoViewIfNeeded();
this._edit("", element, this._addBlockedURL.bind(this));
},
/**
* @param {string} content
* @param {!Element} element
* @param {function(string)} onAccept
* @private
*/
_edit: function(content, element, onAccept)
{
this._editing = true;
element.classList.add("blocked-url-editing");
var input = element.createChild("input");
input.setAttribute("type", "text");
input.value = content;
input.placeholder = WebInspector.UIString("Text pattern to block matching requests; use * for wildcard");
input.addEventListener("blur", commit.bind(this), false);
input.addEventListener("keydown", keydown.bind(this), false);
input.focus();
/**
* @this {WebInspector.BlockedURLsPane}
*/
function finish()
{
this._editing = false;
element.removeChild(input);
element.classList.remove("blocked-url-editing");
}
/**
* @this {WebInspector.BlockedURLsPane}
*/
function commit()
{
if (!this._editing)
return;
var text = input.value.trim();
finish.call(this);
if (text)
onAccept(text);
else
this._update();
}
/**
* @this {WebInspector.BlockedURLsPane}
* @param {!Event} event
*/
function keydown(event)
{
if (isEnterKey(event)) {
event.consume();
commit.call(this);
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") {
event.consume();
finish.call(this);
this._update();
}
}
},
/**
* @param {string} url
*/
_addBlockedURL: function(url)
{
var blocked = this._blockedURLsSetting.get();
blocked.push(url);
this._blockedURLsSetting.set(blocked);
},
/**
* @param {number} index
*/
_removeBlockedURL: function(index)
{
var blocked = this._blockedURLsSetting.get();
blocked.splice(index, 1);
this._blockedURLsSetting.set(blocked);
},
/**
* @param {number} index
* @param {string} url
*/
_changeBlockedURL: function(index, url)
{
var blocked = this._blockedURLsSetting.get();
blocked.splice(index, 1, url);
this._blockedURLsSetting.set(blocked);
},
_removeAll: function()
{
this._blockedURLsSetting.set([]);
},
/**
* @param {number} index
* @param {!Event} event
*/
_contextMenu: function(index, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^pattern"), this._addButtonClicked.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^pattern"), this._removeBlockedURL.bind(this, index));
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all"), this._removeAll.bind(this));
contextMenu.show();
},
/**
* @return {!Promise<?>}
*/
_update: function()
{
if (this._editing)
return Promise.resolve();
this._listElement.removeChildren();
var blocked = this._blockedURLsSetting.get();
for (var index = 0; index < blocked.length; index++)
this._listElement.appendChild(this._createElement(blocked[index], index));
this._emptyElement.classList.toggle("hidden", !!blocked.length);
return Promise.resolve();
},
/**
* @param {string} url
* @param {number} index
* @return {!Element}
*/
_createElement: function(url, index)
{
var element = createElementWithClass("div", "blocked-url");
var label = element.createChild("div", "blocked-url-text");
label.textContent = url;
var count = this._blockedRequestsCount(url);
var countElement = element.createChild("div", "blocked-count monospace");
countElement.textContent = String.sprintf("[%d]", count);
countElement.title = WebInspector.UIString(count === 1 ? "%d request blocked by this pattern" : "%d requests blocked by this pattern", count);
var removeButton = element.createChild("div", "remove-button");
removeButton.title = WebInspector.UIString("Remove");
removeButton.addEventListener("click", this._removeBlockedURL.bind(this, index), false);
element.addEventListener("contextmenu", this._contextMenu.bind(this, index), true);
element.addEventListener("dblclick", this._edit.bind(this, url, element, this._changeBlockedURL.bind(this, index)), false);
return element;
},
/**
* @param {string} url
* @return {number}
*/
_blockedRequestsCount: function(url)
{
if (!url)
return 0;
var result = 0;
for (var blockedUrl of this._blockedCountForUrl.keys()) {
if (this._matches(url, blockedUrl))
result += this._blockedCountForUrl.get(blockedUrl);
}
return result;
},
/**
* @param {string} pattern
* @param {string} url
* @return {boolean}
*/
_matches: function(pattern, url)
{
var pos = 0;
var parts = pattern.split("*");
for (var index = 0; index < parts.length; index++) {
var part = parts[index];
if (!part.length)
continue;
pos = url.indexOf(part, pos);
if (pos === -1)
return false;
pos += part.length;
}
return true;
},
reset: function()
{
this._blockedCountForUrl.clear();
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestFinished: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
if (request.wasBlocked()) {
var count = this._blockedCountForUrl.get(request.url) || 0;
this._blockedCountForUrl.set(request.url, count + 1);
this._updateThrottler.schedule(this._update.bind(this));
}
},
__proto__: WebInspector.VBox.prototype
}
/** @type {?WebInspector.BlockedURLsPane} */
WebInspector.BlockedURLsPane._instance = null;
WebInspector.BlockedURLsPane.reset = function()
{
if (WebInspector.BlockedURLsPane._instance)
WebInspector.BlockedURLsPane._instance.reset();
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.BlockedURLsPane.ActionDelegate = function()
{
}
WebInspector.BlockedURLsPane.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
WebInspector.inspectorView.showViewInDrawer("network.blocked-urls");
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.EventSourceMessagesView = function(request)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("network/eventSourceMessagesView.css");
this.element.classList.add("event-source-messages-view");
this._request = request;
var columns = [
{id: "id", title: WebInspector.UIString("Id"), sortable: true, weight: 8},
{id: "type", title: WebInspector.UIString("Type"), sortable: true, weight: 8},
{id: "data", title: WebInspector.UIString("Data"), sortable: false, weight: 88},
{id: "time", title: WebInspector.UIString("Time"), sortable: true, weight: 8}
];
this._dataGrid = new WebInspector.SortableDataGrid(columns);
this._dataGrid.setStickToBottom(true);
this._dataGrid.markColumnAsSortedBy("time", WebInspector.DataGrid.Order.Ascending);
this._sortItems();
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortItems, this);
this._dataGrid.setName("EventSourceMessagesView");
this._dataGrid.asWidget().show(this.element);
}
WebInspector.EventSourceMessagesView.prototype = {
wasShown: function()
{
this._dataGrid.rootNode().removeChildren();
var messages = this._request.eventSourceMessages();
for (var i = 0; i < messages.length; ++i)
this._dataGrid.insertChild(new WebInspector.EventSourceMessageNode(messages[i]));
this._request.addEventListener(WebInspector.NetworkRequest.Events.EventSourceMessageAdded, this._messageAdded, this);
},
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.EventSourceMessageAdded, this._messageAdded, this);
},
/**
* @param {!WebInspector.Event} event
*/
_messageAdded: function(event)
{
var message = /** @type {!WebInspector.NetworkRequest.EventSourceMessage} */ (event.data);
this._dataGrid.insertChild(new WebInspector.EventSourceMessageNode(message));
},
_sortItems: function()
{
var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
if (!sortColumnIdentifier)
return;
var comparator = WebInspector.EventSourceMessageNode.Comparators[sortColumnIdentifier];
if (!comparator)
return;
this._dataGrid.sortNodes(comparator, !this._dataGrid.isSortOrderAscending());
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.SortableDataGridNode}
* @param {!WebInspector.NetworkRequest.EventSourceMessage} message
*/
WebInspector.EventSourceMessageNode = function(message)
{
this._message = message;
var time = new Date(message.time * 1000);
var timeText = ("0" + time.getHours()).substr(-2) + ":" + ("0" + time.getMinutes()).substr(-2)+ ":" + ("0" + time.getSeconds()).substr(-2) + "." + ("00" + time.getMilliseconds()).substr(-3);
var timeNode = createElement("div");
timeNode.createTextChild(timeText);
timeNode.title = time.toLocaleString();
WebInspector.SortableDataGridNode.call(this, {id: message.eventId, type: message.eventName, data: message.data, time: timeNode});
}
WebInspector.EventSourceMessageNode.prototype = {
__proto__: WebInspector.SortableDataGridNode.prototype
}
/**
* @param {string} field
* @param {!WebInspector.EventSourceMessageNode} a
* @param {!WebInspector.EventSourceMessageNode} b
* @return {number}
*/
WebInspector.EventSourceMessageNodeComparator = function(field, a, b)
{
var aValue = a._message[field];
var bValue = b._message[field];
return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
}
/** @type {!Object.<string, !WebInspector.SortableDataGrid.NodeComparator>} */
WebInspector.EventSourceMessageNode.Comparators = {
"id": WebInspector.EventSourceMessageNodeComparator.bind(null, "eventId"),
"type": WebInspector.EventSourceMessageNodeComparator.bind(null, "eventName"),
"time": WebInspector.EventSourceMessageNodeComparator.bind(null, "time")
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.TextFilterUI.SuggestionBuilder}
* @param {!Array.<string>} keys
*/
WebInspector.FilterSuggestionBuilder = function(keys)
{
this._keys = keys;
this._valueSets = {};
this._valueLists = {};
}
/** @typedef {{type: string, data: string, negative: boolean}} */
WebInspector.FilterSuggestionBuilder.Filter;
WebInspector.FilterSuggestionBuilder.prototype = {
/**
* @override
* @param {!HTMLInputElement} input
* @return {?Array.<string>}
*/
buildSuggestions: function(input)
{
var text = input.value;
var end = input.selectionEnd;
if (end != text.length)
return null;
var start = input.selectionStart;
text = text.substring(0, start);
var prefixIndex = text.lastIndexOf(" ") + 1;
var prefix = text.substring(prefixIndex);
if (!prefix)
return [];
var negative = prefix.startsWith("-");
if (negative)
prefix = prefix.substring(1);
var modifier = negative ? "-" : "";
var valueDelimiterIndex = prefix.indexOf(":");
var suggestions = [];
if (valueDelimiterIndex === -1) {
var matcher = new RegExp("^" + prefix.escapeForRegExp(), "i");
for (var j = 0; j < this._keys.length; ++j) {
if (this._keys[j].match(matcher))
suggestions.push(modifier + this._keys[j] + ":");
}
} else {
var key = prefix.substring(0, valueDelimiterIndex).toLowerCase();
var value = prefix.substring(valueDelimiterIndex + 1);
var matcher = new RegExp("^" + value.escapeForRegExp(), "i");
var items = this._values(key);
for (var i = 0; i < items.length; ++i) {
if (items[i].match(matcher) && (items[i] !== value))
suggestions.push(modifier + key + ":" + items[i]);
}
}
return suggestions;
},
/**
* @override
* @param {!HTMLInputElement} input
* @param {string} suggestion
* @param {boolean} isIntermediate
*/
applySuggestion: function(input, suggestion, isIntermediate)
{
var text = input.value;
var start = input.selectionStart;
text = text.substring(0, start);
var prefixIndex = text.lastIndexOf(" ") + 1;
if (isIntermediate) {
text = text + suggestion.substring(text.length - prefixIndex);
input.value = text;
} else {
text = text.substring(0, prefixIndex) + suggestion;
input.value = text;
start = text.length;
}
input.setSelectionRange(start, text.length);
},
/**
* @override
* @param {!HTMLInputElement} input
*/
unapplySuggestion: function(input)
{
var start = input.selectionStart;
var end = input.selectionEnd;
var text = input.value;
if (start !== end && end === text.length)
input.value = text.substring(0, start);
},
/**
* @param {string} key
* @return {!Array.<string>}
*/
_values: function(key)
{
var result = this._valueLists[key];
if (!result)
return [];
result.sort();
return result;
},
/**
* @param {string} key
* @param {?string=} value
*/
addItem: function(key, value)
{
if (!value)
return;
var set = this._valueSets[key];
var list = this._valueLists[key];
if (!set) {
set = {};
this._valueSets[key] = set;
list = [];
this._valueLists[key] = list;
}
if (set[value])
return;
set[value] = true;
list.push(value);
},
/**
* @param {string} query
* @return {{text: !Array.<string>, filters: !Array.<!WebInspector.FilterSuggestionBuilder.Filter>}}
*/
parseQuery: function(query)
{
var filters = [];
var text = [];
var parts = query.split(/\s+/);
for (var i = 0; i < parts.length; ++i) {
var part = parts[i];
if (!part)
continue;
var colonIndex = part.indexOf(":");
if (colonIndex === -1) {
text.push(part);
continue;
}
var key = part.substring(0, colonIndex);
var negative = key.startsWith("-");
if (negative)
key = key.substring(1);
if (this._keys.indexOf(key) == -1) {
text.push(part);
continue;
}
var value = part.substring(colonIndex + 1);
filters.push({type: key, data: value, negative: negative});
}
return {text: text, filters: filters};
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
*/
WebInspector.HARWriter = function()
{
}
WebInspector.HARWriter.prototype = {
/**
* @param {!WebInspector.OutputStream} stream
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.Progress} progress
*/
write: function(stream, requests, progress)
{
this._stream = stream;
this._harLog = (new WebInspector.HARLog(requests)).build();
this._pendingRequests = 1; // Guard against completing resource transfer before all requests are made.
var entries = this._harLog.entries;
for (var i = 0; i < entries.length; ++i) {
var content = requests[i].content;
if (typeof content === "undefined" && requests[i].finished) {
++this._pendingRequests;
requests[i].requestContent().then(this._onContentAvailable.bind(this, entries[i], requests[i]));
} else if (content !== null)
this._setEntryContent(entries[i], requests[i]);
}
var compositeProgress = new WebInspector.CompositeProgress(progress);
this._writeProgress = compositeProgress.createSubProgress();
if (--this._pendingRequests) {
this._requestsProgress = compositeProgress.createSubProgress();
this._requestsProgress.setTitle(WebInspector.UIString("Collecting content…"));
this._requestsProgress.setTotalWork(this._pendingRequests);
} else
this._beginWrite();
},
/**
* @param {!Object} entry
* @param {!WebInspector.NetworkRequest} request
*/
_setEntryContent: function(entry, request)
{
if (request.content !== null)
entry.response.content.text = request.content;
if (request.contentEncoded)
entry.response.content.encoding = "base64";
},
/**
* @param {!Object} entry
* @param {!WebInspector.NetworkRequest} request
* @param {?string} content
*/
_onContentAvailable: function(entry, request, content)
{
this._setEntryContent(entry, request);
if (this._requestsProgress)
this._requestsProgress.worked();
if (!--this._pendingRequests) {
this._requestsProgress.done();
this._beginWrite();
}
},
_beginWrite: function()
{
const jsonIndent = 2;
this._text = JSON.stringify({log: this._harLog}, null, jsonIndent);
this._writeProgress.setTitle(WebInspector.UIString("Writing file…"));
this._writeProgress.setTotalWork(this._text.length);
this._bytesWritten = 0;
this._writeNextChunk(this._stream);
},
/**
* @param {!WebInspector.OutputStream} stream
* @param {string=} error
*/
_writeNextChunk: function(stream, error)
{
if (this._bytesWritten >= this._text.length || error) {
stream.close();
this._writeProgress.done();
return;
}
const chunkSize = 100000;
var text = this._text.substring(this._bytesWritten, this._bytesWritten + chunkSize);
this._bytesWritten += text.length;
stream.write(text, this._writeNextChunk.bind(this));
this._writeProgress.setWorked(this._bytesWritten);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ParsedJSON} parsedJSON
*/
WebInspector.JSONView = function(parsedJSON)
{
WebInspector.VBox.call(this);
this._parsedJSON = parsedJSON;
this.element.classList.add("json-view");
}
// "false", "true", "null", ",", "{", "}", "[", "]", number, double-quoted string.
WebInspector.JSONView._jsonToken = new RegExp('(?:false|true|null|[/*&\\|;=\\(\\),\\{\\}\\[\\]]|(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)|(?:\"(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))*\"))', 'g');
// Escaped unicode char.
WebInspector.JSONView._escapedUnicode = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
// Map from escaped char to its literal value.
WebInspector.JSONView._standardEscapes = {'"': '"', '/': '/', '\\': '\\', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t'};
/**
* @param {string} full
* @param {string} standard
* @param {string} unicode
* @return {string}
*/
WebInspector.JSONView._unescape = function(full, standard, unicode)
{
return standard ? WebInspector.JSONView._standardEscapes[standard] : String.fromCharCode(parseInt(unicode, 16));
}
/**
* @param {string} text
* @return {string}
*/
WebInspector.JSONView._unescapeString = function(text)
{
return text.indexOf("\\") === -1 ? text : text.replace(WebInspector.JSONView._escapedUnicode, WebInspector.JSONView._unescape);
}
/**
* @return {*}
*/
WebInspector.JSONView._buildObjectFromJSON = function(text)
{
var regExp = WebInspector.JSONView._jsonToken;
regExp.lastIndex = 0;
var result = [];
var tip = result;
var stack = [];
var key = undefined;
var token = undefined;
var lastToken = undefined;
while (true) {
var match = regExp.exec(text);
if (match === null)
break;
lastToken = token;
token = match[0];
var code = token.charCodeAt(0);
if ((code === 0x5b) || (code === 0x7b)) { // [ or {
var newTip = (code === 0x5b) ? [] : {};
tip[key || tip.length] = newTip;
stack.push(tip);
tip = newTip;
} else if ((code === 0x5d) || (code === 0x7d)) { // ] or }
tip = stack.pop();
if (!tip)
break;
} else if (code === 0x2C) { // ,
if (Array.isArray(tip) && (lastToken === undefined || lastToken === "[" || lastToken === ","))
tip[tip.length] = undefined;
} else if (code === 0x22) { // "
token = WebInspector.JSONView._unescapeString(token.substring(1, token.length - 1));
if (!key) {
if (Array.isArray(tip)) {
key = tip.length;
} else {
key = token || "";
continue;
}
}
tip[key] = token;
} else if (code === 0x66) { // f
tip[key || tip.length] = false;
} else if (code === 0x6e) { // n
tip[key || tip.length] = null;
} else if (code === 0x74) { // t
tip[key || tip.length] = true;
} else if (code === 0x2f || code === 0x2a || code === 0x26 || code === 0x7c || code === 0x3b || code === 0x3d || code === 0x28 || code === 0x29) { // /*&|;=()
// Looks like JavaScript
throw "Invalid JSON";
} else { // sign or digit
tip[key || tip.length] = +(token);
}
key = undefined;
}
return (result.length > 1) ? result : result[0];
}
/**
* @param {string} text
* @return {?WebInspector.ParsedJSON}
*/
WebInspector.JSONView.parseJSON = function(text)
{
// Do not treat HTML as JSON.
if (text.startsWith("<"))
return null;
var inner = WebInspector.JSONView._findBrackets(text, "{", "}");
var inner2 = WebInspector.JSONView._findBrackets(text, "[", "]");
inner = inner2.length > inner.length ? inner2 : inner;
// Return on blank payloads or on payloads significantly smaller than original text.
if (inner.length === -1 || text.length - inner.length > 80)
return null;
var prefix = text.substring(0, inner.start);
var suffix = text.substring(inner.end + 1);
text = text.substring(inner.start, inner.end + 1);
// Only process valid JSONP.
if (suffix.trim().length && !(suffix.trim().startsWith(")") && prefix.trim().endsWith("(")))
return null;
try {
return new WebInspector.ParsedJSON(WebInspector.JSONView._buildObjectFromJSON(text), prefix, suffix);
} catch (e) {
return null;
}
}
/**
* @param {string} text
* @param {string} open
* @param {string} close
* @return {{start: number, end: number, length: number}}
*/
WebInspector.JSONView._findBrackets = function(text, open, close)
{
var start = text.indexOf(open);
var end = text.lastIndexOf(close);
var length = end - start - 1;
if (start == -1 || end == -1 || end < start)
length = -1;
return {start: start, end: end, length: length};
}
WebInspector.JSONView.prototype = {
wasShown: function()
{
this._initialize();
},
_initialize: function()
{
if (this._initialized)
return;
this._initialized = true;
var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.data);
var title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix;
var section = new WebInspector.ObjectPropertiesSection(obj, title);
section.expand();
section.editable = false;
this.element.appendChild(section.element);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {*} data
* @param {string} prefix
* @param {string} suffix
*/
WebInspector.ParsedJSON = function(data, prefix, suffix)
{
this.data = data;
this.prefix = prefix;
this.suffix = suffix;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 2 1 1 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.NetworkConfigView = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("network/networkConfigView.css");
this.contentElement.classList.add("network-config");
this._createCacheSection();
this._createNetworkThrottlingSection();
this._createUserAgentSection();
}
WebInspector.NetworkConfigView.prototype = {
/**
* @param {string} title
* @param {string=} className
* @return {!Element}
*/
_createSection: function(title, className)
{
var section = this.contentElement.createChild("section", "network-config-group");
if (className)
section.classList.add(className);
section.createChild("div", "network-config-title").textContent = title;
return section.createChild("div", "network-config-fields");
},
_createCacheSection: function()
{
var section = this._createSection(WebInspector.UIString("Disk cache"), "network-config-disable-cache");
section.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Disable cache"), WebInspector.moduleSetting("cacheDisabled"), true));
},
_createNetworkThrottlingSection: function()
{
var section = this._createSection(WebInspector.UIString("Network throttling"), "network-config-throttling");
WebInspector.NetworkConditionsSelector.decorateSelect(/** @type {!HTMLSelectElement} */(section.createChild("select", "chrome-select")));
},
_createUserAgentSection: function()
{
var section = this._createSection(WebInspector.UIString("User agent"), "network-config-ua");
var checkboxLabel = createCheckboxLabel(WebInspector.UIString("Select automatically"), true);
section.appendChild(checkboxLabel);
this._autoCheckbox = checkboxLabel.checkboxElement;
this._autoCheckbox.addEventListener("change", this._userAgentTypeChanged.bind(this));
this._customUserAgentSetting = WebInspector.settings.createSetting("customUserAgent", "");
this._customUserAgentSetting.addChangeListener(this._customUserAgentChanged, this);
this._customUserAgent = section.createChild("div", "network-config-ua-custom");
this._customSelectAndInput = WebInspector.NetworkConfigView.createUserAgentSelectAndInput();
this._customSelectAndInput.select.classList.add("chrome-select");
this._customUserAgent.appendChild(this._customSelectAndInput.select);
this._customUserAgent.appendChild(this._customSelectAndInput.input);
this._userAgentTypeChanged();
},
_customUserAgentChanged: function()
{
if (this._autoCheckbox.checked)
return;
WebInspector.multitargetNetworkManager.setCustomUserAgentOverride(this._customUserAgentSetting.get());
},
_userAgentTypeChanged: function()
{
var useCustomUA = !this._autoCheckbox.checked;
this._customUserAgent.classList.toggle("checked", useCustomUA);
this._customSelectAndInput.select.disabled = !useCustomUA;
this._customSelectAndInput.input.disabled = !useCustomUA;
var customUA = useCustomUA ? this._customUserAgentSetting.get() : "";
WebInspector.multitargetNetworkManager.setCustomUserAgentOverride(customUA);
},
__proto__ : WebInspector.VBox.prototype
}
/**
* @return {{select: !Element, input: !Element}}
*/
WebInspector.NetworkConfigView.createUserAgentSelectAndInput = function()
{
var userAgentSetting = WebInspector.settings.createSetting("customUserAgent", "");
const noOverride = {title: WebInspector.UIString("No override"), value: ""};
const customOverride = {title: WebInspector.UIString("Other"), value: "Other"};
var userAgents = [noOverride].concat(WebInspector.NetworkConfigView._userAgents).concat([customOverride]);
var userAgentSelectElement = createElement("select");
for (var i = 0; i < userAgents.length; ++i)
userAgentSelectElement.add(new Option(userAgents[i].title, userAgents[i].value));
userAgentSelectElement.selectedIndex = 0;
var otherUserAgentElement = createElement("input");
otherUserAgentElement.type = "text";
otherUserAgentElement.value = userAgentSetting.get();
otherUserAgentElement.title = userAgentSetting.get();
settingChanged();
userAgentSelectElement.addEventListener("change", userAgentSelected, false);
otherUserAgentElement.addEventListener("dblclick", textDoubleClicked, true);
otherUserAgentElement.addEventListener("blur", textChanged, false);
otherUserAgentElement.addEventListener("keydown", textKeyDown, false);
function userAgentSelected()
{
var value = userAgentSelectElement.options[userAgentSelectElement.selectedIndex].value;
if (value !== customOverride.value) {
userAgentSetting.set(value);
otherUserAgentElement.value = value;
otherUserAgentElement.title = value;
otherUserAgentElement.readOnly = true;
} else {
otherUserAgentElement.readOnly = false;
otherUserAgentElement.value = "";
otherUserAgentElement.focus();
}
}
function settingChanged()
{
var value = userAgentSetting.get();
var options = userAgentSelectElement.options;
var selectionRestored = false;
for (var i = 0; i < options.length; ++i) {
if (options[i].value === value) {
userAgentSelectElement.selectedIndex = i;
selectionRestored = true;
break;
}
}
otherUserAgentElement.readOnly = selectionRestored;
if (!selectionRestored)
userAgentSelectElement.selectedIndex = options.length - 1;
if (otherUserAgentElement.value !== value) {
otherUserAgentElement.value = value;
otherUserAgentElement.title = value;
}
}
function textKeyDown(event)
{
if (isEnterKey(event))
textChanged();
}
function textDoubleClicked()
{
if (userAgentSelectElement.selectedIndex === userAgents.length - 1)
return;
userAgentSelectElement.selectedIndex = userAgents.length - 1;
userAgentSelected();
}
function textChanged()
{
if (userAgentSetting.get() !== otherUserAgentElement.value) {
userAgentSetting.set(otherUserAgentElement.value);
settingChanged();
}
}
return { select: userAgentSelectElement, input: otherUserAgentElement };
}
/** @type {!Array.<{title: string, value: string}>} */
WebInspector.NetworkConfigView._userAgents = [
{title: "Android (4.0.2) Browser \u2014 Galaxy Nexus", value: "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"},
{title: "Android (2.3) Browser \u2014 Nexus S", value: "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"},
{title: "BlackBerry \u2014 BB10", value: "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+"},
{title: "BlackBerry \u2014 PlayBook 2.1", value: "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+"},
{title: "BlackBerry \u2014 9900", value: "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+"},
{title: "Chrome 47 \u2014 Mac", value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"},
{title: "Chrome 47 \u2014 Windows", value: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"},
{title: "Chrome 47 \u2014 Android Tablet", value: "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.76 Safari/537.36"},
{title: "Chrome 47 \u2014 Android Mobile", value: "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.76 Mobile Safari/537.36"},
{title: "Chrome 47 \u2014 iPad", value: "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13B143 Safari/601.1.46"},
{title: "Chrome 47 \u2014 iPhone", value: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13B143 Safari/601.1.46"},
{title: "Firefox 42 \u2014 Android Mobile", value: "Mozilla/5.0 (Android 4.4; Mobile; rv:42.0) Gecko/42.0 Firefox/42.0"},
{title: "Firefox 42 \u2014 Android Tablet", value: "Mozilla/5.0 (Android 4.4; Tablet; rv:42.0) Gecko/42.0 Firefox/42.0"},
{title: "Firefox 42 \u2014 Mac", value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0"},
{title: "Firefox 42 \u2014 Windows", value: "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0"},
{title: "Googlebot", value: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"},
{title: "Googlebot Smartphone", value: "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"},
{title: "Microsoft Edge", value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"},
{title: "Internet Explorer 11", value: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"},
{title: "Internet Explorer 10", value: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"},
{title: "Internet Explorer 8", value: "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"},
{title: "Internet Explorer 9", value: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"},
{title: "Internet Explorer 7", value: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"},
{title: "iPad \u2014 iOS 9", value: "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1"},
{title: "iPhone \u2014 iOS 9", value: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1"},
{title: "MeeGo \u2014 Nokia N9", value: "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13"},
{title: "Opera 33 \u2014 Mac", value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36 OPR/33.0.1990.115"},
{title: "Opera 33 \u2014 Windows", value: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 OPR/33.0.1990.43"},
{title: "Opera 12 \u2014 Mac", value: "Opera/9.80 (Macintosh; Intel Mac OS X 10.9.1) Presto/2.12.388 Version/12.16"},
{title: "Opera 12 \u2014 Windows", value: "Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16"},
{title: "Silk \u2014 Kindle Fire (Desktop view)", value: "Mozilla/5.0 (Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true"},
{title: "Silk \u2014 Kindle Fire (Mobile view)", value: "Mozilla/5.0 (Linux; U; Android 4.2.2; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Mobile Safari/535.19 Silk-Accelerated=true"}
];
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.NetworkConfigView.ShowActionDelegate = function()
{
}
WebInspector.NetworkConfigView.ShowActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
WebInspector.inspectorView.showViewInDrawer("network.config");
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SortableDataGridNode}
* @param {!WebInspector.NetworkLogView} parentView
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.NetworkDataGridNode = function(parentView, request)
{
WebInspector.SortableDataGridNode.call(this, {});
this._parentView = parentView;
this._request = request;
this._staleGraph = true;
this._isNavigationRequest = false;
this.selectable = true;
}
WebInspector.NetworkDataGridNode._hoveredRowSymbol = Symbol("hoveredRow");
WebInspector.NetworkDataGridNode.prototype = {
/**
* @return {string}
*/
displayType: function()
{
var mimeType = this._request.mimeType || this._request.requestContentType() || "";
var resourceType = this._request.resourceType();
var simpleType = resourceType.name();
if (resourceType == WebInspector.resourceTypes.Other || resourceType == WebInspector.resourceTypes.Image)
simpleType = mimeType.replace(/^(application|image)\//, "");
return simpleType;
},
/**
* @return {!WebInspector.NetworkRequest}
*/
request: function()
{
return this._request;
},
markAsNavigationRequest: function()
{
this._isNavigationRequest = true;
this.refresh();
},
/**
* @override
* @return {number}
*/
nodeSelfHeight: function()
{
return this._parentView.rowHeight();
},
/**
* @override
*/
createCells: function()
{
this._showTiming = !WebInspector.moduleSetting("networkColorCodeResourceTypes").get() && !this._parentView.calculator().startAtZero;
this._nameCell = null;
this._timelineCell = null;
this._initiatorCell = null;
this._element.classList.toggle("network-error-row", this._isFailed());
this._element.classList.toggle("network-navigation-row", this._isNavigationRequest);
WebInspector.SortableDataGridNode.prototype.createCells.call(this);
this._updateGraph();
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = this.createTD(columnIdentifier);
switch (columnIdentifier) {
case "name": this._renderNameCell(cell); break;
case "timeline": this._createTimelineBar(cell); break;
case "method": cell.setTextAndTitle(this._request.requestMethod); break;
case "status": this._renderStatusCell(cell); break;
case "protocol": cell.setTextAndTitle(this._request.protocol); break;
case "scheme": cell.setTextAndTitle(this._request.scheme); break;
case "domain": cell.setTextAndTitle(this._request.domain); break;
case "remoteAddress": cell.setTextAndTitle(this._request.remoteAddress()); break;
case "cookies": cell.setTextAndTitle(this._arrayLength(this._request.requestCookies)); break;
case "setCookies": cell.setTextAndTitle(this._arrayLength(this._request.responseCookies)); break;
case "priority": cell.setTextAndTitle(WebInspector.uiLabelForPriority(this._request.initialPriority())); break;
case "connectionId": cell.setTextAndTitle(this._request.connectionId); break;
case "type": this._renderTypeCell(cell); break;
case "initiator": this._renderInitiatorCell(cell); break;
case "size": this._renderSizeCell(cell); break;
case "time": this._renderTimeCell(cell); break;
default: cell.setTextAndTitle(this._request.responseHeaderValue(columnIdentifier) || ""); break;
}
return cell;
},
/**
* @param {?Array} array
* @return {string}
*/
_arrayLength: function(array)
{
return array ? "" + array.length : "";
},
/**
* @override
* @protected
*/
willAttach: function()
{
if (this._staleGraph)
this._updateGraph();
if (this._initiatorCell && this._request.initiatorInfo().type === WebInspector.NetworkRequest.InitiatorType.Script)
this._initiatorCell.insertBefore(this._linkifiedInitiatorAnchor, this._initiatorCell.firstChild);
},
wasDetached: function()
{
if (this._linkifiedInitiatorAnchor)
this._linkifiedInitiatorAnchor.remove();
},
dispose: function()
{
if (this._linkifiedInitiatorAnchor)
this._parentView.linkifier.disposeAnchor(this._request.target(), this._linkifiedInitiatorAnchor);
},
select: function()
{
WebInspector.SortableDataGridNode.prototype.select.apply(this, arguments);
this._parentView.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RequestSelected, this._request);
},
/**
* @param {!RegExp=} regexp
* @return {!Array.<!Object>}
*/
highlightMatchedSubstring: function(regexp)
{
// Ensure element is created.
this.element();
var domChanges = [];
var matchInfo = this._nameCell.textContent.match(regexp);
if (matchInfo)
WebInspector.highlightSearchResult(this._nameCell, matchInfo.index, matchInfo[0].length, domChanges);
return domChanges;
},
_openInNewTab: function()
{
InspectorFrontendHost.openInNewTab(this._request.url);
},
/**
* @param {!Element} cell
*/
_createTimelineBar: function(cell)
{
cell = cell.createChild("div");
this._timelineCell = cell;
cell.className = "network-graph-side";
this._barAreaElement = cell.createChild("div", "network-graph-bar-area");
this._barAreaElement.request = this._request;
if (this._showTiming)
return;
var type = this._request.resourceType().name();
var cached = this._request.cached();
this._barLeftElement = this._barAreaElement.createChild("div", "network-graph-bar");
this._barLeftElement.classList.add(type, "waiting");
this._barLeftElement.classList.toggle("cached", cached);
this._barRightElement = this._barAreaElement.createChild("div", "network-graph-bar");
this._barRightElement.classList.add(type);
this._barRightElement.classList.toggle("cached", cached);
this._labelLeftElement = this._barAreaElement.createChild("div", "network-graph-label");
this._labelLeftElement.classList.add("waiting");
this._labelRightElement = this._barAreaElement.createChild("div", "network-graph-label");
cell.addEventListener("mouseover", this._onMouseOver.bind(this), false);
},
/**
* @param {!Event} event
*/
_onMouseOver: function(event)
{
this._refreshLabelPositions();
this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol] = this;
},
/**
* @return {boolean}
*/
_isFailed: function()
{
return (this._request.failed && !this._request.statusCode) || (this._request.statusCode >= 400);
},
/**
* @param {!Element} cell
*/
_renderNameCell: function(cell)
{
this._nameCell = cell;
cell.addEventListener("dblclick", this._openInNewTab.bind(this), false);
var iconElement;
if (this._request.resourceType() === WebInspector.resourceTypes.Image) {
var previewImage = createElementWithClass("img", "image-network-icon-preview");
this._request.populateImageSource(previewImage);
iconElement = createElementWithClass("div", "icon");
iconElement.appendChild(previewImage);
} else {
iconElement = createElementWithClass("img", "icon");
}
iconElement.classList.add(this._request.resourceType().name());
cell.appendChild(iconElement);
cell.createTextChild(this._request.target().decorateLabel(this._request.name()));
this._appendSubtitle(cell, this._request.path());
cell.title = this._request.url;
},
/**
* @param {!Element} cell
*/
_renderStatusCell: function(cell)
{
cell.classList.toggle("network-dim-cell", !this._isFailed() && (this._request.cached() || !this._request.statusCode));
if (this._request.failed && !this._request.canceled && !this._request.wasBlocked()) {
var failText = WebInspector.UIString("(failed)");
if (this._request.localizedFailDescription) {
cell.createTextChild(failText);
this._appendSubtitle(cell, this._request.localizedFailDescription);
cell.title = failText + " " + this._request.localizedFailDescription;
} else
cell.setTextAndTitle(failText);
} else if (this._request.statusCode) {
cell.createTextChild("" + this._request.statusCode);
this._appendSubtitle(cell, this._request.statusText);
cell.title = this._request.statusCode + " " + this._request.statusText;
} else if (this._request.parsedURL.isDataURL()) {
cell.setTextAndTitle(WebInspector.UIString("(data)"));
} else if (this._request.canceled) {
cell.setTextAndTitle(WebInspector.UIString("(canceled)"));
} else if (this._request.wasBlocked()) {
var reason = WebInspector.UIString("other");
switch (this._request.blockedReason()) {
case NetworkAgent.BlockedReason.Csp:
reason = WebInspector.UIString("csp");
break;
case NetworkAgent.BlockedReason.MixedContent:
reason = WebInspector.UIString("mixed-content");
break;
case NetworkAgent.BlockedReason.Origin:
reason = WebInspector.UIString("origin");
break;
case NetworkAgent.BlockedReason.Inspector:
reason = WebInspector.UIString("devtools");
break;
case NetworkAgent.BlockedReason.Other:
reason = WebInspector.UIString("other");
break;
}
cell.setTextAndTitle(WebInspector.UIString("(blocked:%s)", reason));
} else if (this._request.finished) {
cell.setTextAndTitle(WebInspector.UIString("Finished"));
} else {
cell.setTextAndTitle(WebInspector.UIString("(pending)"));
}
},
/**
* @param {!Element} cell
*/
_renderTypeCell: function(cell)
{
cell.setTextAndTitle(this.displayType());
},
/**
* @param {!Element} cell
*/
_renderInitiatorCell: function(cell)
{
this._initiatorCell = cell;
var request = this._request;
var initiator = request.initiatorInfo();
switch (initiator.type) {
case WebInspector.NetworkRequest.InitiatorType.Parser:
cell.title = initiator.url + ":" + initiator.lineNumber;
var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(initiator.url);
cell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url, initiator.lineNumber - 1, initiator.columnNumber - 1, undefined, undefined, uiSourceCode ? uiSourceCode.displayName() : undefined));
this._appendSubtitle(cell, WebInspector.UIString("Parser"));
break;
case WebInspector.NetworkRequest.InitiatorType.Redirect:
cell.title = initiator.url;
console.assert(request.redirectSource);
var redirectSource = /** @type {!WebInspector.NetworkRequest} */ (request.redirectSource);
cell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));
this._appendSubtitle(cell, WebInspector.UIString("Redirect"));
break;
case WebInspector.NetworkRequest.InitiatorType.Script:
if (!this._linkifiedInitiatorAnchor) {
this._linkifiedInitiatorAnchor = this._parentView.linkifier.linkifyScriptLocation(request.target(), initiator.scriptId, initiator.url, initiator.lineNumber - 1, initiator.columnNumber - 1);
this._linkifiedInitiatorAnchor.title = "";
}
cell.appendChild(this._linkifiedInitiatorAnchor);
this._appendSubtitle(cell, WebInspector.UIString("Script"));
cell.classList.add("network-script-initiated");
cell.request = request;
break;
default:
cell.title = "";
cell.classList.add("network-dim-cell");
cell.setTextAndTitle(WebInspector.UIString("Other"));
}
},
/**
* @param {!Element} cell
*/
_renderSizeCell: function(cell)
{
if (this._request.fetchedViaServiceWorker) {
cell.setTextAndTitle(WebInspector.UIString("(from ServiceWorker)"));
cell.classList.add("network-dim-cell");
} else if (this._request.cached()) {
cell.setTextAndTitle(WebInspector.UIString("(from cache)"));
cell.classList.add("network-dim-cell");
} else {
var resourceSize = Number.bytesToString(this._request.resourceSize);
var transferSize = Number.bytesToString(this._request.transferSize);
cell.setTextAndTitle(transferSize);
this._appendSubtitle(cell, resourceSize);
}
},
/**
* @param {!Element} cell
*/
_renderTimeCell: function(cell)
{
if (this._request.duration > 0) {
cell.setTextAndTitle(Number.secondsToString(this._request.duration));
this._appendSubtitle(cell, Number.secondsToString(this._request.latency));
} else {
cell.classList.add("network-dim-cell");
cell.setTextAndTitle(WebInspector.UIString("Pending"));
}
},
/**
* @param {!Element} cellElement
* @param {string} subtitleText
*/
_appendSubtitle: function(cellElement, subtitleText)
{
var subtitleElement = createElement("div");
subtitleElement.className = "network-cell-subtitle";
subtitleElement.textContent = subtitleText;
cellElement.appendChild(subtitleElement);
},
refreshGraph: function()
{
if (!this._timelineCell)
return;
this._staleGraph = true;
if (this.attached())
this.dataGrid.scheduleUpdate();
},
_updateTimingGraph: function()
{
var calculator = this._parentView.calculator();
var timeRanges = WebInspector.RequestTimingView.calculateRequestTimeRanges(this._request);
var right = timeRanges[0].end;
var container = this._barAreaElement;
var nextBar = container.firstChild;
for (var i = 0; i < timeRanges.length; ++i) {
var range = timeRanges[i];
var start = calculator.computePercentageFromEventTime(range.start);
var end = (range.end !== Number.MAX_VALUE) ? calculator.computePercentageFromEventTime(range.end) : 100;
if (!nextBar)
nextBar = container.createChild("div");
nextBar.className = "network-graph-bar request-timing";
nextBar.classList.add(range.name);
nextBar.style.setProperty("left", start + "%");
nextBar.style.setProperty("right", (100 - end) + "%");
nextBar = nextBar.nextSibling;
}
while (nextBar) {
var nextSibling = nextBar.nextSibling;
nextBar.remove();
nextBar = nextSibling;
}
},
_updateGraph: function()
{
this._staleGraph = false;
if (!this._timelineCell)
return;
if (this._showTiming) {
this._updateTimingGraph();
return;
}
var calculator = this._parentView.calculator();
var percentages = calculator.computeBarGraphPercentages(this._request);
this._percentages = percentages;
this._barAreaElement.classList.remove("hidden");
this._barLeftElement.style.setProperty("left", percentages.start + "%");
this._barLeftElement.style.setProperty("right", (100 - percentages.middle) + "%");
this._barRightElement.style.setProperty("left", percentages.middle + "%");
this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
var labels = calculator.computeBarGraphLabels(this._request);
this._labelLeftElement.textContent = labels.left;
this._labelRightElement.textContent = labels.right;
var tooltip = (labels.tooltip || "");
this._barLeftElement.title = tooltip;
this._labelLeftElement.title = tooltip;
this._labelRightElement.title = tooltip;
this._barRightElement.title = tooltip;
if (this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol] === this)
this._refreshLabelPositions();
},
_refreshLabelPositions: function()
{
if (!this._percentages)
return;
this._labelLeftElement.style.removeProperty("left");
this._labelLeftElement.style.removeProperty("right");
this._labelLeftElement.classList.remove("before");
this._labelLeftElement.classList.remove("hidden");
this._labelRightElement.style.removeProperty("left");
this._labelRightElement.style.removeProperty("right");
this._labelRightElement.classList.remove("after");
this._labelRightElement.classList.remove("hidden");
const labelPadding = 10;
const barRightElementOffsetWidth = this._barRightElement.offsetWidth;
const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth;
if (this._barLeftElement) {
var leftBarWidth = barLeftElementOffsetWidth - labelPadding;
var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffsetWidth) - labelPadding;
} else {
var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffsetWidth) - labelPadding;
var rightBarWidth = barRightElementOffsetWidth - labelPadding;
}
const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth;
const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth;
const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth);
const labelAfter = (labelRightElementOffsetWidth > rightBarWidth);
const graphElementOffsetWidth = this._timelineCell.offsetWidth;
if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10))
var leftHidden = true;
if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10))
var rightHidden = true;
if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {
// The left/right label data are the same, so a before/after label can be replaced by an on-bar label.
if (labelBefore && !labelAfter)
leftHidden = true;
else if (labelAfter && !labelBefore)
rightHidden = true;
}
if (labelBefore) {
if (leftHidden)
this._labelLeftElement.classList.add("hidden");
this._labelLeftElement.style.setProperty("right", (100 - this._percentages.start) + "%");
this._labelLeftElement.classList.add("before");
} else {
this._labelLeftElement.style.setProperty("left", this._percentages.start + "%");
this._labelLeftElement.style.setProperty("right", (100 - this._percentages.middle) + "%");
}
if (labelAfter) {
if (rightHidden)
this._labelRightElement.classList.add("hidden");
this._labelRightElement.style.setProperty("left", this._percentages.end + "%");
this._labelRightElement.classList.add("after");
} else {
this._labelRightElement.style.setProperty("left", this._percentages.middle + "%");
this._labelRightElement.style.setProperty("right", (100 - this._percentages.end) + "%");
}
},
__proto__: WebInspector.SortableDataGridNode.prototype
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
{
var aFileName = a._request.name();
var bFileName = b._request.name();
if (aFileName > bFileName)
return 1;
if (bFileName > aFileName)
return -1;
return a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.RemoteAddressComparator = function(a, b)
{
var aRemoteAddress = a._request.remoteAddress();
var bRemoteAddress = b._request.remoteAddress();
if (aRemoteAddress > bRemoteAddress)
return 1;
if (bRemoteAddress > aRemoteAddress)
return -1;
return a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
{
if (b._request.cached() && !a._request.cached())
return 1;
if (a._request.cached() && !b._request.cached())
return -1;
return (a._request.transferSize - b._request.transferSize) || a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.TypeComparator = function(a, b)
{
var aSimpleType = a.displayType();
var bSimpleType = b.displayType();
if (aSimpleType > bSimpleType)
return 1;
if (bSimpleType > aSimpleType)
return -1;
return a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
{
var aInitiator = a._request.initiatorInfo();
var bInitiator = b._request.initiatorInfo();
if (aInitiator.type < bInitiator.type)
return -1;
if (aInitiator.type > bInitiator.type)
return 1;
if (typeof aInitiator.__source === "undefined")
aInitiator.__source = WebInspector.displayNameForURL(aInitiator.url);
if (typeof bInitiator.__source === "undefined")
bInitiator.__source = WebInspector.displayNameForURL(bInitiator.url);
if (aInitiator.__source < bInitiator.__source)
return -1;
if (aInitiator.__source > bInitiator.__source)
return 1;
if (aInitiator.lineNumber < bInitiator.lineNumber)
return -1;
if (aInitiator.lineNumber > bInitiator.lineNumber)
return 1;
if (aInitiator.columnNumber < bInitiator.columnNumber)
return -1;
if (aInitiator.columnNumber > bInitiator.columnNumber)
return 1;
return a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.RequestCookiesCountComparator = function(a, b)
{
var aScore = a._request.requestCookies ? a._request.requestCookies.length : 0;
var bScore = b._request.requestCookies ? b._request.requestCookies.length : 0;
return (aScore - bScore) || a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator = function(a, b)
{
var aScore = a._request.responseCookies ? a._request.responseCookies.length : 0;
var bScore = b._request.responseCookies ? b._request.responseCookies.length : 0;
return (aScore - bScore) || a._request.indentityCompare(b._request);
}
/**
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.InitialPriorityComparator = function(a, b)
{
var priorityMap = WebInspector.NetworkDataGridNode._symbolicToNumericPriority;
if (!priorityMap) {
WebInspector.NetworkDataGridNode._symbolicToNumericPriority = new Map();
priorityMap = WebInspector.NetworkDataGridNode._symbolicToNumericPriority;
priorityMap.set(NetworkAgent.ResourcePriority.VeryLow, 1);
priorityMap.set(NetworkAgent.ResourcePriority.Low, 2);
priorityMap.set(NetworkAgent.ResourcePriority.Medium, 3);
priorityMap.set(NetworkAgent.ResourcePriority.High, 4);
priorityMap.set(NetworkAgent.ResourcePriority.VeryHigh, 5);
}
var aScore = priorityMap.get(a._request.initialPriority()) || 0;
var bScore = priorityMap.get(b._request.initialPriority()) || 0;
return aScore - bScore || a._request.indentityCompare(b._request);
}
/**
* @param {string} propertyName
* @param {boolean} revert
* @param {!WebInspector.NetworkDataGridNode} a
* @param {!WebInspector.NetworkDataGridNode} b
* @return {number}
*/
WebInspector.NetworkDataGridNode.RequestPropertyComparator = function(propertyName, revert, a, b)
{
var aValue = a._request[propertyName];
var bValue = b._request[propertyName];
if (aValue > bValue)
return revert ? -1 : 1;
if (bValue > aValue)
return revert ? 1 : -1;
return a._request.indentityCompare(b._request);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | 2 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.TabbedPane}
* @param {!WebInspector.NetworkRequest} request
* @param {!WebInspector.NetworkTimeCalculator} calculator
*/
WebInspector.NetworkItemView = function(request, calculator)
{
WebInspector.TabbedPane.call(this);
this.renderWithNoHeaderBackground();
this.element.classList.add("network-item-view");
this._resourceViewTabSetting = WebInspector.settings.createSetting("resourceViewTab", "preview");
var headersView = new WebInspector.RequestHeadersView(request);
this.appendTab("headers", WebInspector.UIString("Headers"), headersView);
this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
if (request.resourceType() === WebInspector.resourceTypes.WebSocket) {
var frameView = new WebInspector.ResourceWebSocketFrameView(request);
this.appendTab("webSocketFrames", WebInspector.UIString("Frames"), frameView);
} else if (request.mimeType === "text/event-stream") {
this.appendTab("eventSource", WebInspector.UIString("EventStream"), new WebInspector.EventSourceMessagesView(request));
} else {
var responseView = new WebInspector.RequestResponseView(request);
var previewView = new WebInspector.RequestPreviewView(request, responseView);
this.appendTab("preview", WebInspector.UIString("Preview"), previewView);
this.appendTab("response", WebInspector.UIString("Response"), responseView);
}
if (request.requestCookies || request.responseCookies) {
this._cookiesView = new WebInspector.RequestCookiesView(request);
this.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView);
}
this.appendTab("timing", WebInspector.UIString("Timing"), new WebInspector.RequestTimingView(request, calculator));
this._request = request;
}
WebInspector.NetworkItemView.prototype = {
wasShown: function()
{
WebInspector.TabbedPane.prototype.wasShown.call(this);
this._selectTab();
},
/**
* @param {string=} tabId
*/
_selectTab: function(tabId)
{
if (!tabId)
tabId = this._resourceViewTabSetting.get();
if (!this.selectTab(tabId))
this.selectTab("headers");
},
_tabSelected: function(event)
{
if (!event.data.isUserGesture)
return;
this._resourceViewTabSetting.set(event.data.tabId);
},
/**
* @return {!WebInspector.NetworkRequest}
*/
request: function()
{
return this._request;
},
__proto__: WebInspector.TabbedPane.prototype
}
/**
* @constructor
* @extends {WebInspector.RequestView}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestContentView = function(request)
{
WebInspector.RequestView.call(this, request);
}
WebInspector.RequestContentView.prototype = {
/**
* @return {!WebInspector.Widget}
*/
get innerView()
{
return this._innerView;
},
set innerView(innerView)
{
this._innerView = innerView;
},
wasShown: function()
{
this._ensureInnerViewShown();
},
_ensureInnerViewShown: function()
{
if (this._innerViewShowRequested)
return;
this._innerViewShowRequested = true;
/**
* @param {?string} content
* @this {WebInspector.RequestContentView}
*/
function callback(content)
{
this._innerViewShowRequested = false;
this.contentLoaded();
}
this.request.requestContent().then(callback.bind(this));
},
contentLoaded: function()
{
// Should be implemented by subclasses.
},
__proto__: WebInspector.RequestView.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 | 2 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.Searchable}
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.FilterBar} filterBar
* @param {!Element} progressBarContainer
* @param {!WebInspector.Setting} networkLogLargeRowsSetting
*/
WebInspector.NetworkLogView = function(filterBar, progressBarContainer, networkLogLargeRowsSetting)
{
WebInspector.VBox.call(this);
this.setMinimumSize(50, 64);
this.registerRequiredCSS("network/networkLogView.css");
this._networkHideDataURLSetting = WebInspector.settings.createSetting("networkHideDataURL", false);
this._networkResourceTypeFiltersSetting = WebInspector.settings.createSetting("networkResourceTypeFilters", {});
this._networkShowPrimaryLoadWaterfallSetting = WebInspector.settings.createSetting("networkShowPrimaryLoadWaterfall", false);
this._filterBar = filterBar;
this._progressBarContainer = progressBarContainer;
this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
var defaultColumnsVisibility = WebInspector.NetworkLogView._defaultColumnsVisibility;
this._columnsVisibilitySetting = WebInspector.settings.createSetting("networkLogColumnsVisibility", defaultColumnsVisibility);
var savedColumnsVisibility = this._columnsVisibilitySetting.get();
var columnsVisibility = {};
for (var columnId in defaultColumnsVisibility)
columnsVisibility[columnId] = savedColumnsVisibility.hasOwnProperty(columnId) ? savedColumnsVisibility[columnId] : defaultColumnsVisibility[columnId];
this._columnsVisibilitySetting.set(columnsVisibility);
/** @type {!Map.<string, !WebInspector.NetworkDataGridNode>} */
this._nodesByRequestId = new Map();
/** @type {!Object.<string, boolean>} */
this._staleRequestIds = {};
/** @type {number} */
this._mainRequestLoadTime = -1;
/** @type {number} */
this._mainRequestDOMContentLoadedTime = -1;
this._matchedRequestCount = 0;
/** @type {!Array<{time: number, element: !Element}>} */
this._eventDividers = [];
this._highlightedSubstringChanges = [];
/** @type {!Array.<!WebInspector.NetworkLogView.Filter>} */
this._filters = [];
/** @type {?WebInspector.NetworkLogView.Filter} */
this._timeFilter = null;
this._currentMatchedRequestNode = null;
this._currentMatchedRequestIndex = -1;
/** @type {!WebInspector.Linkifier} */
this._popupLinkifier = new WebInspector.Linkifier();
/** @type {!WebInspector.Linkifier} */
this.linkifier = new WebInspector.Linkifier();
this._gridMode = true;
this._recording = false;
this._preserveLog = false;
/** @type {number} */
this._rowHeight = 0;
this._addFilters();
this._resetSuggestionBuilder();
this._initializeView();
WebInspector.moduleSetting("networkColorCodeResourceTypes").addChangeListener(this._invalidateAllItems, this);
this._networkLogLargeRowsSetting.addChangeListener(this._updateRowsSize, this);
WebInspector.targetManager.observeTargets(this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, this);
}
WebInspector.NetworkLogView._isFilteredOutSymbol = Symbol("isFilteredOut");
WebInspector.NetworkLogView._isMatchingSearchQuerySymbol = Symbol("isMatchingSearchQuery");
WebInspector.NetworkLogView.HTTPSchemas = {"http": true, "https": true, "ws": true, "wss": true};
WebInspector.NetworkLogView._responseHeaderColumns = ["Cache-Control", "Connection", "Content-Encoding", "Content-Length", "ETag", "Keep-Alive", "Last-Modified", "Server", "Vary"];
WebInspector.NetworkLogView._defaultColumnsVisibility = {
method: false, status: true, protocol: false, scheme: false, domain: false, remoteAddress: false, type: true, initiator: true, cookies: false, setCookies: false, size: true, time: true, priority: false, connectionId: false,
"Cache-Control": false, "Connection": false, "Content-Encoding": false, "Content-Length": false, "ETag": false, "Keep-Alive": false, "Last-Modified": false, "Server": false, "Vary": false
};
WebInspector.NetworkLogView._defaultRefreshDelay = 200;
WebInspector.NetworkLogView._waterfallMinOvertime = 1;
WebInspector.NetworkLogView._waterfallMaxOvertime = 3;
/** @enum {string} */
WebInspector.NetworkLogView.FilterType = {
Domain: "domain",
HasResponseHeader: "has-response-header",
Is: "is",
LargerThan: "larger-than",
Method: "method",
MimeType: "mime-type",
MixedContent: "mixed-content",
Scheme: "scheme",
SetCookieDomain: "set-cookie-domain",
SetCookieName: "set-cookie-name",
SetCookieValue: "set-cookie-value",
StatusCode: "status-code"
};
/** @enum {string} */
WebInspector.NetworkLogView.MixedContentFilterValues = {
All: "all",
Displayed: "displayed",
Blocked: "blocked",
BlockOverridden: "block-overridden"
}
/** @enum {string} */
WebInspector.NetworkLogView.IsFilterType = {
Running: "running"
};
/** @type {!Array.<string>} */
WebInspector.NetworkLogView._searchKeys = Object.values(WebInspector.NetworkLogView.FilterType);
/** @type {!Object.<string, string>} */
WebInspector.NetworkLogView._columnTitles = {
"name": WebInspector.UIString("Name"),
"method": WebInspector.UIString("Method"),
"status": WebInspector.UIString("Status"),
"protocol": WebInspector.UIString("Protocol"),
"scheme": WebInspector.UIString("Scheme"),
"domain": WebInspector.UIString("Domain"),
"remoteAddress": WebInspector.UIString("Remote Address"),
"type": WebInspector.UIString("Type"),
"initiator": WebInspector.UIString("Initiator"),
"cookies": WebInspector.UIString("Cookies"),
"setCookies": WebInspector.UIString("Set-Cookies"),
"size": WebInspector.UIString("Size"),
"time": WebInspector.UIString("Time"),
"connectionId": WebInspector.UIString("Connection Id"),
"priority": WebInspector.UIString("Priority"),
"timeline": WebInspector.UIString("Timeline"),
// Response header columns
"Cache-Control": WebInspector.UIString("Cache-Control"),
"Connection": WebInspector.UIString("Connection"),
"Content-Encoding": WebInspector.UIString("Content-Encoding"),
"Content-Length": WebInspector.UIString("Content-Length"),
"ETag": WebInspector.UIString("ETag"),
"Keep-Alive": WebInspector.UIString("Keep-Alive"),
"Last-Modified": WebInspector.UIString("Last-Modified"),
"Server": WebInspector.UIString("Server"),
"Vary": WebInspector.UIString("Vary")
};
WebInspector.NetworkLogView.prototype = {
/**
* @param {boolean} recording
*/
setRecording: function(recording)
{
this._recording = recording;
this._updateSummaryBar();
},
/**
* @param {boolean} preserveLog
*/
setPreserveLog: function(preserveLog)
{
this._preserveLog = preserveLog;
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (!target.parentTarget()) {
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
}
target.networkLog.requests().forEach(this._appendRequest.bind(this));
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (!target.parentTarget()) {
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
}
},
/**
* @param {number} start
* @param {number} end
*/
setWindow: function(start, end)
{
if (!start && !end) {
this._timeFilter = null;
this._timeCalculator.setWindow(null);
} else {
this._timeFilter = WebInspector.NetworkLogView._requestTimeFilter.bind(null, start, end);
this._timeCalculator.setWindow(new WebInspector.NetworkTimeBoundary(start, end));
}
this._updateDividersIfNeeded();
this._filterRequests();
},
clearSelection: function()
{
if (this._dataGrid.selectedNode)
this._dataGrid.selectedNode.deselect();
},
_addFilters: function()
{
this._textFilterUI = new WebInspector.TextFilterUI(true);
this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
this._filterBar.addFilter(this._textFilterUI);
var dataURLSetting = this._networkHideDataURLSetting;
this._dataURLFilterUI = new WebInspector.CheckboxFilterUI("hide-data-url", WebInspector.UIString("Hide data URLs"), true, dataURLSetting);
this._dataURLFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
this._filterBar.addFilter(this._dataURLFilterUI);
var filterItems = [];
for (var categoryId in WebInspector.resourceCategories) {
var category = WebInspector.resourceCategories[categoryId];
filterItems.push({name: category.title, label: category.shortTitle, title: category.title});
}
this._resourceCategoryFilterUI = new WebInspector.NamedBitSetFilterUI(filterItems, this._networkResourceTypeFiltersSetting);
this._resourceCategoryFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
this._filterBar.addFilter(this._resourceCategoryFilterUI);
},
_resetSuggestionBuilder: function()
{
this._suggestionBuilder = new WebInspector.FilterSuggestionBuilder(WebInspector.NetworkLogView._searchKeys);
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Is, WebInspector.NetworkLogView.IsFilterType.Running);
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan, "100");
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan, "10k");
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan, "1M");
this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);
},
/**
* @param {!WebInspector.Event} event
*/
_filterChanged: function(event)
{
this._removeAllNodeHighlights();
this._parseFilterQuery(this._textFilterUI.value());
this._filterRequests();
},
_initializeView: function()
{
this.element.id = "network-container";
this._createSortingFunctions();
this._createCalculators();
this._createTable();
this._createTimelineGrid();
this._summaryBarElement = this.element.createChild("div", "network-summary-bar");
this._updateRowsSize();
this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), this._onHidePopover.bind(this));
this.switchViewMode(true);
},
_showRecordingHint: function()
{
this._hideRecordingHint();
this._recordingHint = this.element.createChild("div", "network-status-pane fill");
var hintText = this._recordingHint.createChild("div", "recording-hint");
var reloadShortcutNode = this._recordingHint.createChild("b");
reloadShortcutNode.textContent = WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name;
if (this._recording) {
var recordingText = hintText.createChild("span");
recordingText.textContent = WebInspector.UIString("Recording network activity\u2026");
hintText.createChild("br");
hintText.appendChild(WebInspector.formatLocalized("Perform a request or hit %s to record the reload.", [reloadShortcutNode]));
} else {
var recordNode = hintText.createChild("b");
recordNode.textContent = WebInspector.shortcutRegistry.shortcutTitleForAction("network.toggle-recording");
hintText.appendChild(WebInspector.formatLocalized("Record (%s) or reload (%s) to display network activity.", [recordNode, reloadShortcutNode]));
}
},
_hideRecordingHint: function()
{
if (this._recordingHint)
this._recordingHint.remove();
delete this._recordingHint;
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
if (!this._dataGrid) // Not initialized yet.
return [];
return [this._dataGrid.scrollContainer];
},
_createTimelineGrid: function()
{
this._timelineGrid = new WebInspector.TimelineGrid();
this._timelineGrid.element.classList.add("network-timeline-grid");
this._dataGrid.element.appendChild(this._timelineGrid.element);
},
_createTable: function()
{
var columns = [];
columns.push({
id: "name",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Name"), WebInspector.UIString("Path")),
title: WebInspector.NetworkLogView._columnTitles["name"],
weight: 20
});
columns.push({
id: "method",
title: WebInspector.NetworkLogView._columnTitles["method"],
weight: 6
});
columns.push({
id: "status",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Status"), WebInspector.UIString("Text")),
title: WebInspector.NetworkLogView._columnTitles["status"],
weight: 6
});
columns.push({
id: "protocol",
title: WebInspector.NetworkLogView._columnTitles["protocol"],
weight: 6
});
columns.push({
id: "scheme",
title: WebInspector.NetworkLogView._columnTitles["scheme"],
weight: 6
});
columns.push({
id: "domain",
title: WebInspector.NetworkLogView._columnTitles["domain"],
weight: 6
});
columns.push({
id: "remoteAddress",
title: WebInspector.NetworkLogView._columnTitles["remoteAddress"],
weight: 10,
align: WebInspector.DataGrid.Align.Right
});
columns.push({
id: "type",
title: WebInspector.NetworkLogView._columnTitles["type"],
weight: 6
});
columns.push({
id: "initiator",
title: WebInspector.NetworkLogView._columnTitles["initiator"],
weight: 10
});
columns.push({
id: "cookies",
title: WebInspector.NetworkLogView._columnTitles["cookies"],
weight: 6,
align: WebInspector.DataGrid.Align.Right
});
columns.push({
id: "setCookies",
title: WebInspector.NetworkLogView._columnTitles["setCookies"],
weight: 6,
align: WebInspector.DataGrid.Align.Right
});
columns.push({
id: "size",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Size"), WebInspector.UIString("Content")),
title: WebInspector.NetworkLogView._columnTitles["size"],
weight: 6,
align: WebInspector.DataGrid.Align.Right
});
columns.push({
id: "time",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Latency")),
title: WebInspector.NetworkLogView._columnTitles["time"],
weight: 6,
align: WebInspector.DataGrid.Align.Right
});
columns.push({
id: "priority",
title: WebInspector.NetworkLogView._columnTitles["priority"],
weight: 6
});
columns.push({
id: "connectionId",
title: WebInspector.NetworkLogView._columnTitles["connectionId"],
weight: 6
});
var responseHeaderColumns = WebInspector.NetworkLogView._responseHeaderColumns;
for (var i = 0; i < responseHeaderColumns.length; ++i) {
var headerName = responseHeaderColumns[i];
var descriptor = {
id: headerName,
title: WebInspector.NetworkLogView._columnTitles[headerName],
weight: 6
};
if (headerName === "Content-Length")
descriptor.align = WebInspector.DataGrid.Align.Right;
columns.push(descriptor);
}
columns.push({
id: "timeline",
title: WebInspector.NetworkLogView._columnTitles["timeline"],
sortable: false,
weight: 40,
sort: WebInspector.DataGrid.Order.Ascending
});
for (var column of columns) {
column.sortable = column.id !== "timeline";
column.nonSelectable = column.id !== "name";
}
this._dataGrid = new WebInspector.SortableDataGrid(columns);
this._dataGrid.setStickToBottom(true);
this._updateColumns();
this._dataGrid.setName("networkLog");
this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
this._dataGrid.element.classList.add("network-log-grid");
this._dataGrid.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
this._dataGrid.element.addEventListener("mousedown", this._dataGridMouseDown.bind(this), true);
this._dataGrid.element.addEventListener("mousemove", this._dataGridMouseMove.bind(this), true);
this._dataGrid.element.addEventListener("mouseleave", this._highlightInitiatorChain.bind(this, null), true);
this._dataGrid.asWidget().show(this.element);
// Event listeners need to be added _after_ we attach to the document, so that owner document is properly update.
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortItems, this);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.ColumnsResized, this._updateDividersIfNeeded, this);
this._patchTimelineHeader();
this._dataGrid.sortNodes(this._sortingFunctions.startTime, false);
},
/**
* @param {!Event} event
*/
_dataGridMouseDown: function(event)
{
if ((!this._dataGrid.selectedNode && event.button) || event.target.enclosingNodeOrSelfWithNodeName("a"))
event.consume();
},
/**
* @param {!Event} event
*/
_dataGridMouseMove: function(event)
{
var node = event.shiftKey ? this._dataGrid.dataGridNodeFromNode(event.target) : null;
this._highlightInitiatorChain(node ? node.request() : null);
},
/**
* @param {?WebInspector.NetworkRequest} request
*/
_highlightInitiatorChain: function(request)
{
if (this._requestWithHighlightedInitiators === request)
return;
this._requestWithHighlightedInitiators = request;
if (!request) {
for (var node of this._nodesByRequestId.values()) {
if (!node.dataGrid)
continue;
node.element().classList.remove("network-node-on-initiator-path", "network-node-on-initiated-path");
}
return;
}
var initiators = request.initiatorChain();
var initiated = new Set();
for (var node of this._nodesByRequestId.values()) {
if (!node.dataGrid)
continue;
var localInitiators = node.request().initiatorChain();
if (localInitiators.has(request))
initiated.add(node.request());
}
for (var node of this._nodesByRequestId.values()) {
if (!node.dataGrid)
continue;
node.element().classList.toggle("network-node-on-initiator-path", node.request() !== request && initiators.has(node.request()));
node.element().classList.toggle("network-node-on-initiated-path", node.request() !== request && initiated.has(node.request()));
}
},
/**
* @param {string} title
* @param {string} subtitle
* @return {!DocumentFragment}
*/
_makeHeaderFragment: function(title, subtitle)
{
var fragment = createDocumentFragment();
fragment.createTextChild(title);
var subtitleDiv = fragment.createChild("div", "network-header-subtitle");
subtitleDiv.createTextChild(subtitle);
return fragment;
},
_patchTimelineHeader: function()
{
var timelineSorting = createElement("select");
var option = createElement("option");
option.value = "startTime";
option.label = WebInspector.UIString("Timeline");
option.disabled = true;
timelineSorting.appendChild(option);
option = createElement("option");
option.value = "startTime";
option.label = WebInspector.UIString("Timeline \u2013 Start Time");
option.sortOrder = WebInspector.DataGrid.Order.Ascending;
timelineSorting.appendChild(option);
option = createElement("option");
option.value = "responseTime";
option.label = WebInspector.UIString("Timeline \u2013 Response Time");
option.sortOrder = WebInspector.DataGrid.Order.Ascending;
timelineSorting.appendChild(option);
option = createElement("option");
option.value = "endTime";
option.label = WebInspector.UIString("Timeline \u2013 End Time");
option.sortOrder = WebInspector.DataGrid.Order.Ascending;
timelineSorting.appendChild(option);
option = createElement("option");
option.value = "duration";
option.label = WebInspector.UIString("Timeline \u2013 Total Duration");
option.sortOrder = WebInspector.DataGrid.Order.Descending;
timelineSorting.appendChild(option);
option = createElement("option");
option.value = "latency";
option.label = WebInspector.UIString("Timeline \u2013 Latency");
option.sortOrder = WebInspector.DataGrid.Order.Descending;
timelineSorting.appendChild(option);
var header = this._dataGrid.headerTableHeader("timeline");
header.replaceChild(timelineSorting, header.firstChild);
header.createChild("div", "sort-order-icon-container").createChild("div", "sort-order-icon");
timelineSorting.selectedIndex = 1;
timelineSorting.addEventListener("click", function(event) { event.consume(); }, false);
timelineSorting.addEventListener("change", this._sortByTimeline.bind(this), false);
this._timelineSortSelector = timelineSorting;
},
_createSortingFunctions: function()
{
this._sortingFunctions = {};
this._sortingFunctions.name = WebInspector.NetworkDataGridNode.NameComparator;
this._sortingFunctions.method = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "requestMethod", false);
this._sortingFunctions.status = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "statusCode", false);
this._sortingFunctions.protocol = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "protocol", false);
this._sortingFunctions.scheme = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "scheme", false);
this._sortingFunctions.domain = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "domain", false);
this._sortingFunctions.remoteAddress = WebInspector.NetworkDataGridNode.RemoteAddressComparator;
this._sortingFunctions.type = WebInspector.NetworkDataGridNode.TypeComparator;
this._sortingFunctions.initiator = WebInspector.NetworkDataGridNode.InitiatorComparator;
this._sortingFunctions.cookies = WebInspector.NetworkDataGridNode.RequestCookiesCountComparator;
this._sortingFunctions.setCookies = WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator;
this._sortingFunctions.size = WebInspector.NetworkDataGridNode.SizeComparator;
this._sortingFunctions.time = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "duration", false);
this._sortingFunctions.connectionId = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "connectionId", false);
this._sortingFunctions.priority = WebInspector.NetworkDataGridNode.InitialPriorityComparator;
this._sortingFunctions.timeline = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "startTime", false);
this._sortingFunctions.startTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "startTime", false);
this._sortingFunctions.endTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "endTime", false);
this._sortingFunctions.responseTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "responseReceivedTime", false);
this._sortingFunctions.duration = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "duration", true);
this._sortingFunctions.latency = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "latency", true);
},
_createCalculators: function()
{
/** @type {!WebInspector.NetworkTransferTimeCalculator} */
this._timeCalculator = new WebInspector.NetworkTransferTimeCalculator();
/** @type {!WebInspector.NetworkTransferDurationCalculator} */
this._durationCalculator = new WebInspector.NetworkTransferDurationCalculator();
/** @type {!Object.<string, !WebInspector.NetworkTimeCalculator>} */
this._calculators = {};
this._calculators.timeline = this._timeCalculator;
this._calculators.startTime = this._timeCalculator;
this._calculators.endTime = this._timeCalculator;
this._calculators.responseTime = this._timeCalculator;
this._calculators.duration = this._durationCalculator;
this._calculators.latency = this._durationCalculator;
this._calculator = this._timeCalculator;
},
_sortItems: function()
{
this._removeAllNodeHighlights();
var columnIdentifier = this._dataGrid.sortColumnIdentifier();
if (columnIdentifier === "timeline") {
this._sortByTimeline();
return;
}
var sortingFunction = this._sortingFunctions[columnIdentifier];
if (!sortingFunction)
return;
this._dataGrid.sortNodes(sortingFunction, !this._dataGrid.isSortOrderAscending());
this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode), false);
this._timelineSortSelector.selectedIndex = 0;
},
_sortByTimeline: function()
{
this._removeAllNodeHighlights();
var selectedIndex = this._timelineSortSelector.selectedIndex;
if (!selectedIndex)
selectedIndex = 1; // Sort by start time by default.
var selectedOption = this._timelineSortSelector[selectedIndex];
var value = selectedOption.value;
this._setCalculator(this._calculators[value]);
var sortingFunction = this._sortingFunctions[value];
this._dataGrid.sortNodes(sortingFunction);
this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode), false);
this._dataGrid.markColumnAsSortedBy("timeline", selectedOption.sortOrder);
},
_updateSummaryBar: function()
{
var requestsNumber = this._nodesByRequestId.size;
if (!requestsNumber) {
this._showRecordingHint();
return;
}
this._hideRecordingHint();
var transferSize = 0;
var selectedRequestsNumber = 0;
var selectedTransferSize = 0;
var baseTime = -1;
var maxTime = -1;
var nodes = this._nodesByRequestId.valuesArray();
for (var i = 0; i < nodes.length; ++i) {
var request = nodes[i].request();
var requestTransferSize = request.transferSize;
transferSize += requestTransferSize;
if (!nodes[i][WebInspector.NetworkLogView._isFilteredOutSymbol]) {
selectedRequestsNumber++;
selectedTransferSize += requestTransferSize;
}
if (request.url === request.target().resourceTreeModel.inspectedPageURL() && request.resourceType() === WebInspector.resourceTypes.Document)
baseTime = request.startTime;
if (request.endTime > maxTime)
maxTime = request.endTime;
}
var summaryBar = this._summaryBarElement;
summaryBar.removeChildren();
var separator = "\u2002\u2758\u2002";
var text = "";
/**
* @param {string} chunk
* @return {!Element}
*/
function appendChunk(chunk)
{
var span = summaryBar.createChild("span");
span.textContent = chunk;
text += chunk;
return span;
}
if (selectedRequestsNumber !== requestsNumber) {
appendChunk(WebInspector.UIString("%d / %d requests", selectedRequestsNumber, requestsNumber));
appendChunk(separator);
appendChunk(WebInspector.UIString("%s / %s transferred", Number.bytesToString(selectedTransferSize), Number.bytesToString(transferSize)));
} else {
appendChunk(WebInspector.UIString("%d requests", requestsNumber));
appendChunk(separator);
appendChunk(WebInspector.UIString("%s transferred", Number.bytesToString(transferSize)));
}
if (baseTime !== -1) {
appendChunk(separator);
appendChunk(WebInspector.UIString("Finish: %s", Number.secondsToString(maxTime - baseTime)));
if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
appendChunk(separator);
var domContentLoadedText = WebInspector.UIString("DOMContentLoaded: %s", Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime));
appendChunk(domContentLoadedText).classList.add("summary-blue");
}
if (this._mainRequestLoadTime !== -1) {
appendChunk(separator);
var loadText = WebInspector.UIString("Load: %s", Number.secondsToString(this._mainRequestLoadTime - baseTime));
appendChunk(loadText).classList.add("summary-red");
}
}
summaryBar.title = text;
},
_scheduleRefresh: function()
{
if (this._needsRefresh)
return;
this._needsRefresh = true;
if (this.isShowing() && !this._refreshTimeout)
this._refreshTimeout = setTimeout(this.refresh.bind(this), WebInspector.NetworkLogView._defaultRefreshDelay);
},
_updateDividersIfNeeded: function()
{
if (!this.isShowing()) {
this._scheduleRefresh();
return;
}
var timelineOffset = this._dataGrid.columnOffset("timeline");
// Position timline grid location.
if (timelineOffset)
this._timelineGrid.element.style.left = timelineOffset + "px";
var calculator = this.calculator();
calculator.setDisplayWindow(this._timelineGrid.dividersElement.clientWidth);
this._timelineGrid.updateDividers(calculator, 75);
if (calculator.startAtZero) {
// If our current sorting method starts at zero, that means it shows all
// requests starting at the same point, and so onLoad event and DOMContent
// event lines really wouldn't make much sense here, so don't render them.
return;
}
this._updateEventDividers();
},
/**
* @param {!Array<number>} times
*/
addFilmStripFrames: function(times)
{
this._addEventDividers(times, "network-frame-divider");
},
/**
* @param {number} time
*/
selectFilmStripFrame: function(time)
{
for (var divider of this._eventDividers)
divider.element.classList.toggle("network-frame-divider-selected", divider.time === time);
},
clearFilmStripFrame: function()
{
for (var divider of this._eventDividers)
divider.element.classList.toggle("network-frame-divider-selected", false);
},
/**
* @param {!Array<number>} times
* @param {string} className
*/
_addEventDividers: function(times, className)
{
for (var i = 0; i < times.length; ++i) {
var element = createElementWithClass("div", "network-event-divider " + className);
this._timelineGrid.addEventDivider(element);
this._eventDividers.push({time: times[i], element: element});
}
// Update event dividers immediately
this._updateEventDividers();
// Schedule refresh in case dividers change the calculator span.
this._scheduleRefresh();
},
_updateEventDividers: function()
{
var calculator = this.calculator();
for (var divider of this._eventDividers) {
var timePercent = calculator.computePercentageFromEventTime(divider.time);
divider.element.classList.toggle("invisible", timePercent < 0);
divider.element.style.left = timePercent + "%";
}
},
_refreshIfNeeded: function()
{
if (this._needsRefresh)
this.refresh();
},
_invalidateAllItems: function()
{
var requestIds = this._nodesByRequestId.keysArray();
for (var i = 0; i < requestIds.length; ++i)
this._staleRequestIds[requestIds[i]] = true;
this.refresh();
},
/**
* @return {!WebInspector.NetworkTimeCalculator}
*/
timeCalculator: function()
{
return this._timeCalculator;
},
/**
* @return {!WebInspector.NetworkTimeCalculator}
*/
calculator: function()
{
return this._calculator;
},
/**
* @param {!WebInspector.NetworkTimeCalculator} x
*/
_setCalculator: function(x)
{
if (!x || this._calculator === x)
return;
this._calculator = x;
this._calculator.reset();
if (this._calculator.startAtZero)
this._timelineGrid.hideEventDividers();
else
this._timelineGrid.showEventDividers();
this._invalidateAllItems();
},
/**
* @param {!WebInspector.Event} event
*/
_loadEventFired: function(event)
{
if (!this._recording)
return;
var data = /** @type {number} */ (event.data);
if (data) {
this._mainRequestLoadTime = data;
this._addEventDividers([data], "network-red-divider");
}
},
/**
* @param {!WebInspector.Event} event
*/
_domContentLoadedEventFired: function(event)
{
if (!this._recording)
return;
var data = /** @type {number} */ (event.data);
if (data) {
this._mainRequestDOMContentLoadedTime = data;
this._addEventDividers([data], "network-blue-divider");
}
},
wasShown: function()
{
this._refreshIfNeeded();
},
willHide: function()
{
this._popoverHelper.hidePopover();
},
refresh: function()
{
this._needsRefresh = false;
if (this._refreshTimeout) {
clearTimeout(this._refreshTimeout);
delete this._refreshTimeout;
}
this._removeAllNodeHighlights();
var oldBoundary = this.calculator().boundary();
this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
var dataGrid = this._dataGrid;
var rootNode = dataGrid.rootNode();
/** @type {!Array<!WebInspector.NetworkDataGridNode> } */
var nodesToInsert = [];
/** @type {!Array<!WebInspector.NetworkDataGridNode> } */
var nodesToRefresh = [];
for (var requestId in this._staleRequestIds) {
var node = this._nodesByRequestId.get(requestId);
if (!node)
continue;
var isFilteredOut = !this._applyFilter(node);
if (node[WebInspector.NetworkLogView._isFilteredOutSymbol] !== isFilteredOut) {
if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
rootNode.removeChild(node);
node[WebInspector.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
nodesToInsert.push(node);
}
if (!isFilteredOut)
nodesToRefresh.push(node);
var request = node.request();
this._timeCalculator.updateBoundaries(request);
this._durationCalculator.updateBoundaries(request);
}
for (var i = 0; i < nodesToInsert.length; ++i) {
var node = nodesToInsert[i];
var request = node.request();
dataGrid.insertChild(node);
node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = this._matchRequest(request);
}
for (var node of nodesToRefresh)
node.refresh();
this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode), false);
if (!this.calculator().boundary().equals(oldBoundary)) {
// The boundaries changed, so all item graphs are stale.
this._updateDividersIfNeeded();
var nodes = this._nodesByRequestId.valuesArray();
for (var i = 0; i < nodes.length; ++i)
nodes[i].refreshGraph();
}
this._staleRequestIds = {};
this._updateSummaryBar();
},
reset: function()
{
this._requestWithHighlightedInitiators = null;
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RequestSelected, null);
this._clearSearchMatchedList();
if (this._popoverHelper)
this._popoverHelper.hidePopover();
this._timeFilter = null;
this._calculator.reset();
this._timeCalculator.setWindow(null);
var nodes = this._nodesByRequestId.valuesArray();
for (var i = 0; i < nodes.length; ++i)
nodes[i].dispose();
this._nodesByRequestId.clear();
this._staleRequestIds = {};
this._resetSuggestionBuilder();
this._mainRequestLoadTime = -1;
this._mainRequestDOMContentLoadedTime = -1;
this._eventDividers = [];
this._timelineGrid.removeEventDividers();
if (this._dataGrid) {
this._dataGrid.rootNode().removeChildren();
this._updateDividersIfNeeded();
this._updateSummaryBar();
}
},
/**
* @param {string} filterString
*/
setTextFilterValue: function(filterString)
{
this._textFilterUI.setValue(filterString);
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestStarted: function(event)
{
if (!this._recording)
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._appendRequest(request);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_appendRequest: function(request)
{
var node = new WebInspector.NetworkDataGridNode(this, request);
node[WebInspector.NetworkLogView._isFilteredOutSymbol] = true;
node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = false;
// In case of redirect request id is reassigned to a redirected
// request and we need to update _nodesByRequestId and search results.
var originalRequestNode = this._nodesByRequestId.get(request.requestId);
if (originalRequestNode)
this._nodesByRequestId.set(originalRequestNode.request().requestId, originalRequestNode);
this._nodesByRequestId.set(request.requestId, node);
// Pull all the redirects of the main request upon commit load.
if (request.redirects) {
for (var i = 0; i < request.redirects.length; ++i)
this._refreshRequest(request.redirects[i]);
}
this._refreshRequest(request);
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestUpdated: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._refreshRequest(request);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_refreshRequest: function(request)
{
if (!this._nodesByRequestId.get(request.requestId))
return;
WebInspector.NetworkLogView._subdomains(request.domain).forEach(this._suggestionBuilder.addItem.bind(this._suggestionBuilder, WebInspector.NetworkLogView.FilterType.Domain));
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Method, request.requestMethod);
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MimeType, request.mimeType);
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Scheme, "" + request.scheme);
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.StatusCode, "" + request.statusCode);
if (request.mixedContentType !== "none") {
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.All);
}
if (request.mixedContentType === "optionally-blockable") {
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.Displayed);
}
if (request.mixedContentType === "blockable") {
var suggestion = request.wasBlocked() ? WebInspector.NetworkLogView.MixedContentFilterValues.Blocked : WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden;
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent, suggestion);
}
var responseHeaders = request.responseHeaders;
for (var i = 0, l = responseHeaders.length; i < l; ++i)
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.HasResponseHeader, responseHeaders[i].name);
var cookies = request.responseCookies;
for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
var cookie = cookies[i];
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieDomain, cookie.domain());
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieName, cookie.name());
this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieValue, cookie.value());
}
this._staleRequestIds[request.requestId] = true;
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.UpdateRequest, request);
this._scheduleRefresh();
},
/**
* @param {!WebInspector.Event} event
*/
_mainFrameNavigated: function(event)
{
if (!this._recording)
return;
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
var loaderId = frame.loaderId;
// Pick provisional load requests.
var requestsToPick = [];
var requests = frame.target().networkLog.requests();
for (var i = 0; i < requests.length; ++i) {
var request = requests[i];
if (request.loaderId === loaderId)
requestsToPick.push(request);
}
if (!this._preserveLog) {
this.reset();
for (var i = 0; i < requestsToPick.length; ++i)
this._appendRequest(requestsToPick[i]);
}
for (var i = 0; i < requestsToPick.length; ++i) {
var request = requestsToPick[i];
var node = this._nodesByRequestId.get(request.requestId);
if (node) {
node.markAsNavigationRequest();
break;
}
}
},
/**
* @param {boolean} gridMode
*/
switchViewMode: function(gridMode)
{
if (this._gridMode === gridMode)
return;
this._gridMode = gridMode;
if (gridMode) {
if (this._dataGrid.selectedNode)
this._dataGrid.selectedNode.selected = false;
} else {
this._removeAllNodeHighlights();
this._popoverHelper.hidePopover();
}
this.element.classList.toggle("brief-mode", !gridMode);
this._updateColumns();
},
/**
* @return {number}
*/
rowHeight: function()
{
return this._rowHeight;
},
_updateRowsSize: function()
{
var largeRows = !!this._networkLogLargeRowsSetting.get();
this._rowHeight = largeRows ? 41 : 21;
this._dataGrid.element.classList.toggle("small", !largeRows);
this._timelineGrid.element.classList.toggle("small", !largeRows);
this._dataGrid.scheduleUpdate();
},
/**
* @param {!Element} element
* @param {!Event} event
* @return {!Element|!AnchorBox|undefined}
*/
_getPopoverAnchor: function(element, event)
{
if (!this._gridMode)
return;
var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") || element.enclosingNodeOrSelfWithClass("network-graph-label");
if (anchor && anchor.parentElement.request && anchor.parentElement.request.timing)
return anchor;
anchor = element.enclosingNodeOrSelfWithClass("network-script-initiated");
if (anchor && anchor.request) {
var initiator = /** @type {!WebInspector.NetworkRequest} */ (anchor.request).initiator();
if (initiator && initiator.stack)
return anchor;
}
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showPopover: function(anchor, popover)
{
var content;
if (anchor.classList.contains("network-script-initiated")) {
var request = /** @type {!WebInspector.NetworkRequest} */ (anchor.request);
var initiator = /** @type {!NetworkAgent.Initiator} */ (request.initiator());
content = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(request.target(), this._popupLinkifier, initiator.stack);
popover.setCanShrink(true);
} else {
content = WebInspector.RequestTimingView.createTimingTable(anchor.parentElement.request, this._timeCalculator.minimumBoundary());
popover.setCanShrink(false);
}
popover.showForAnchor(content, anchor);
},
_onHidePopover: function()
{
this._popupLinkifier.reset();
},
_updateColumns: function()
{
if (!this._dataGrid)
return;
var gridMode = this._gridMode;
var visibleColumns = {"name": true};
if (gridMode)
visibleColumns["timeline"] = true;
if (gridMode) {
var columnsVisibility = this._columnsVisibilitySetting.get();
for (var columnIdentifier in columnsVisibility)
visibleColumns[columnIdentifier] = columnsVisibility[columnIdentifier];
}
this._dataGrid.setColumnsVisiblity(visibleColumns);
},
/**
* @param {string} columnIdentifier
*/
_toggleColumnVisibility: function(columnIdentifier)
{
var columnsVisibility = this._columnsVisibilitySetting.get();
columnsVisibility[columnIdentifier] = !columnsVisibility[columnIdentifier];
this._columnsVisibilitySetting.set(columnsVisibility);
this._updateColumns();
},
/**
* @return {!Array.<string>}
*/
_getConfigurableColumnIDs: function()
{
if (this._configurableColumnIDs)
return this._configurableColumnIDs;
var columnTitles = WebInspector.NetworkLogView._columnTitles;
function compare(id1, id2)
{
return columnTitles[id1].compareTo(columnTitles[id2]);
}
var columnIDs = Object.keys(this._columnsVisibilitySetting.get());
this._configurableColumnIDs = columnIDs.sort(compare);
return this._configurableColumnIDs;
},
/**
* @param {!Event} event
*/
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
if (this._gridMode && event.target.isSelfOrDescendant(this._dataGrid.headerTableBody)) {
var columnsVisibility = this._columnsVisibilitySetting.get();
var columnIDs = this._getConfigurableColumnIDs();
var columnTitles = WebInspector.NetworkLogView._columnTitles;
for (var i = 0; i < columnIDs.length; ++i) {
var columnIdentifier = columnIDs[i];
contextMenu.appendCheckboxItem(columnTitles[columnIdentifier], this._toggleColumnVisibility.bind(this, columnIdentifier), !!columnsVisibility[columnIdentifier]);
}
contextMenu.show();
return;
}
var gridNode = this._dataGrid.dataGridNodeFromNode(event.target);
var request = gridNode && gridNode.request();
/**
* @param {string} url
*/
function openResourceInNewTab(url)
{
InspectorFrontendHost.openInNewTab(url);
}
if (request) {
contextMenu.appendApplicableItems(request);
if (request.requestHeadersText())
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^request ^headers"), this._copyRequestHeaders.bind(this, request));
if (request.responseHeadersText)
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^response ^headers"), this._copyResponseHeaders.bind(this, request));
if (request.finished)
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^response"), this._copyResponse.bind(this, request));
if (WebInspector.isWin()) {
contextMenu.appendItem(WebInspector.UIString("Copy as cURL (cmd)"), this._copyCurlCommand.bind(this, request, "win"));
contextMenu.appendItem(WebInspector.UIString("Copy as cURL (bash)"), this._copyCurlCommand.bind(this, request, "unix"));
} else {
contextMenu.appendItem(WebInspector.UIString("Copy as cURL"), this._copyCurlCommand.bind(this, request, "unix"));
}
}
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^all as HAR"), this._copyAll.bind(this));
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString.capitalize("Save as HAR with ^content"), this._exportAll.bind(this));
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cache"), this._clearBrowserCache.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cookies"), this._clearBrowserCookies.bind(this));
var blockedSetting = WebInspector.moduleSetting("blockedURLs");
if (request && Runtime.experiments.isEnabled("requestBlocking")) { // Disabled until ready.
contextMenu.appendSeparator();
var urlWithoutScheme = request.parsedURL.urlWithoutScheme();
if (urlWithoutScheme && blockedSetting.get().indexOf(urlWithoutScheme) === -1)
contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^request URL"), addBlockedURL.bind(null, urlWithoutScheme));
var domain = request.parsedURL.domain();
if (domain && blockedSetting.get().indexOf(domain) === -1)
contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^request ^domain"), addBlockedURL.bind(null, domain));
function addBlockedURL(url)
{
var list = blockedSetting.get();
list.push(url);
blockedSetting.set(list);
WebInspector.inspectorView.showViewInDrawer("network.blocked-urls");
}
}
if (request && request.resourceType() === WebInspector.resourceTypes.XHR) {
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Replay XHR"), request.replayXHR.bind(request));
contextMenu.appendSeparator();
}
contextMenu.show();
},
_harRequests: function()
{
var requests = this._nodesByRequestId.valuesArray().map(function(node) { return node.request(); });
var httpRequests = requests.filter(WebInspector.NetworkLogView.HTTPRequestsFilter);
return httpRequests.filter(WebInspector.NetworkLogView.FinishedRequestsFilter);
},
_copyAll: function()
{
var harArchive = {
log: (new WebInspector.HARLog(this._harRequests())).build()
};
InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_copyRequestHeaders: function(request)
{
InspectorFrontendHost.copyText(request.requestHeadersText());
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_copyResponse: function(request)
{
/**
* @param {?string} content
*/
function callback(content)
{
if (request.contentEncoded)
content = request.asDataURL();
InspectorFrontendHost.copyText(content || "");
}
request.requestContent().then(callback);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_copyResponseHeaders: function(request)
{
InspectorFrontendHost.copyText(request.responseHeadersText);
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {string} platform
*/
_copyCurlCommand: function(request, platform)
{
InspectorFrontendHost.copyText(this._generateCurlCommand(request, platform));
},
_exportAll: function()
{
var filename = WebInspector.targetManager.inspectedPageDomain() + ".har";
var stream = new WebInspector.FileOutputStream();
stream.open(filename, openCallback.bind(this));
/**
* @param {boolean} accepted
* @this {WebInspector.NetworkLogView}
*/
function openCallback(accepted)
{
if (!accepted)
return;
var progressIndicator = new WebInspector.ProgressIndicator();
this._progressBarContainer.appendChild(progressIndicator.element);
var harWriter = new WebInspector.HARWriter();
harWriter.write(stream, this._harRequests(), progressIndicator);
}
},
_clearBrowserCache: function()
{
if (confirm(WebInspector.UIString("Are you sure you want to clear browser cache?")))
WebInspector.multitargetNetworkManager.clearBrowserCache();
},
_clearBrowserCookies: function()
{
if (confirm(WebInspector.UIString("Are you sure you want to clear browser cookies?")))
WebInspector.multitargetNetworkManager.clearBrowserCookies();
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
_matchRequest: function(request)
{
var re = this._searchRegExp;
if (!re)
return false;
return re.test(request.name()) || (this._networkLogLargeRowsSetting.get() && re.test(request.path()));
},
_clearSearchMatchedList: function()
{
this._matchedRequestCount = -1;
this._currentMatchedRequestNode = null;
this._removeAllHighlights();
},
_removeAllHighlights: function()
{
this._removeAllNodeHighlights();
for (var i = 0; i < this._highlightedSubstringChanges.length; ++i)
WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);
this._highlightedSubstringChanges = [];
},
/**
* @param {number} n
* @param {boolean} reveal
*/
_highlightNthMatchedRequestForSearch: function(n, reveal)
{
this._removeAllHighlights();
/** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
var nodes = this._dataGrid.rootNode().children;
var matchCount = 0;
var node = null;
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]) {
if (matchCount === n) {
node = nodes[i];
break;
}
matchCount++;
}
}
if (!node) {
this._currentMatchedRequestNode = null;
return;
}
var request = node.request();
if (reveal)
WebInspector.Revealer.reveal(request);
var highlightedSubstringChanges = node.highlightMatchedSubstring(this._searchRegExp);
this._highlightedSubstringChanges.push(highlightedSubstringChanges);
this._currentMatchedRequestNode = node;
this._currentMatchedRequestIndex = n;
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated, n);
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var query = searchConfig.query;
var currentMatchedRequestNode = this._currentMatchedRequestNode;
this._clearSearchMatchedList();
this._searchRegExp = createPlainTextSearchRegex(query, "i");
/** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
var nodes = this._dataGrid.rootNode().children;
for (var i = 0; i < nodes.length; ++i)
nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol] = this._matchRequest(nodes[i].request());
var newMatchedRequestIndex = this._updateMatchCountAndFindMatchIndex(currentMatchedRequestNode);
if (!newMatchedRequestIndex && jumpBackwards)
newMatchedRequestIndex = this._matchedRequestCount - 1;
this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, shouldJump);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return true;
},
/**
* @param {?WebInspector.NetworkDataGridNode} node
* @return {number}
*/
_updateMatchCountAndFindMatchIndex: function(node)
{
/** @type {!Array.<!WebInspector.NetworkDataGridNode>} */
var nodes = this._dataGrid.rootNode().children;
var matchCount = 0;
var matchIndex = 0;
for (var i = 0; i < nodes.length; ++i) {
if (!nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol])
continue;
if (node === nodes[i])
matchIndex = matchCount;
matchCount++;
}
if (this._matchedRequestCount !== matchCount) {
this._matchedRequestCount = matchCount;
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, matchCount);
}
return matchIndex;
},
/**
* @param {number} index
* @return {number}
*/
_normalizeSearchResultIndex: function(index)
{
return (index + this._matchedRequestCount) % this._matchedRequestCount;
},
/**
* @param {!WebInspector.NetworkDataGridNode} node
* @return {boolean}
*/
_applyFilter: function(node)
{
var request = node.request();
if (this._timeFilter && !this._timeFilter(request))
return false;
var categoryName = request.resourceType().category().title;
if (!this._resourceCategoryFilterUI.accept(categoryName))
return false;
if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
return false;
if (request.statusText === "Service Worker Fallback Required")
return false;
for (var i = 0; i < this._filters.length; ++i) {
if (!this._filters[i](request))
return false;
}
return true;
},
/**
* @param {string} query
*/
_parseFilterQuery: function(query)
{
var parsedQuery;
if (this._textFilterUI.isRegexChecked() && query !== "")
parsedQuery = {text: [query], filters: []};
else
parsedQuery = this._suggestionBuilder.parseQuery(query);
this._filters = parsedQuery.text.map(this._createTextFilter, this);
var n = parsedQuery.filters.length;
for (var i = 0; i < n; ++i) {
var filter = parsedQuery.filters[i];
var filterType = /** @type {!WebInspector.NetworkLogView.FilterType} */ (filter.type.toLowerCase());
this._filters.push(this._createFilter(filterType, filter.data, filter.negative));
}
},
/**
* @param {string} text
* @return {!WebInspector.NetworkLogView.Filter}
*/
_createTextFilter: function(text)
{
var negative = false;
if (!this._textFilterUI.isRegexChecked() && text[0] === "-" && text.length > 1) {
negative = true;
text = text.substring(1);
}
var regexp = this._textFilterUI.regex();
var filter = WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null, regexp);
if (negative)
filter = WebInspector.NetworkLogView._negativeFilter.bind(null, filter);
return filter;
},
/**
* @param {!WebInspector.NetworkLogView.FilterType} type
* @param {string} value
* @param {boolean} negative
* @return {!WebInspector.NetworkLogView.Filter}
*/
_createFilter: function(type, value, negative)
{
var filter = this._createSpecialFilter(type, value);
if (!filter)
return this._createTextFilter((negative ? "-" : "") + type + ":" + value);
if (negative)
return WebInspector.NetworkLogView._negativeFilter.bind(null, filter);
return filter;
},
/**
* @param {!WebInspector.NetworkLogView.FilterType} type
* @param {string} value
* @return {?WebInspector.NetworkLogView.Filter}
*/
_createSpecialFilter: function(type, value)
{
switch (type) {
case WebInspector.NetworkLogView.FilterType.Domain:
return WebInspector.NetworkLogView._createRequestDomainFilter(value);
case WebInspector.NetworkLogView.FilterType.HasResponseHeader:
return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.Is:
if (value.toLowerCase() === WebInspector.NetworkLogView.IsFilterType.Running)
return WebInspector.NetworkLogView._runningRequestFilter;
break;
case WebInspector.NetworkLogView.FilterType.LargerThan:
return this._createSizeFilter(value.toLowerCase());
case WebInspector.NetworkLogView.FilterType.Method:
return WebInspector.NetworkLogView._requestMethodFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.MimeType:
return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.MixedContent:
return WebInspector.NetworkLogView._requestMixedContentFilter.bind(null, /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */ (value));
case WebInspector.NetworkLogView.FilterType.Scheme:
return WebInspector.NetworkLogView._requestSchemeFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.SetCookieDomain:
return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.SetCookieName:
return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.SetCookieValue:
return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind(null, value);
case WebInspector.NetworkLogView.FilterType.StatusCode:
return WebInspector.NetworkLogView._statusCodeFilter.bind(null, value);
}
return null;
},
/**
* @param {string} value
* @return {?WebInspector.NetworkLogView.Filter}
*/
_createSizeFilter: function(value)
{
var multiplier = 1;
if (value.endsWith("k")) {
multiplier = 1024;
value = value.substring(0, value.length - 1);
} else if (value.endsWith("m")) {
multiplier = 1024 * 1024;
value = value.substring(0, value.length - 1);
}
var quantity = Number(value);
if (isNaN(quantity))
return null;
return WebInspector.NetworkLogView._requestSizeLargerThanFilter.bind(null, quantity * multiplier);
},
_filterRequests: function()
{
this._removeAllHighlights();
this._invalidateAllItems();
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._matchedRequestCount)
return;
var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex - 1);
this._highlightNthMatchedRequestForSearch(index, true);
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._matchedRequestCount)
return;
var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex + 1);
this._highlightNthMatchedRequestForSearch(index, true);
},
/**
* @override
*/
searchCanceled: function()
{
delete this._searchRegExp;
this._clearSearchMatchedList();
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, 0);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
revealAndHighlightRequest: function(request)
{
this._removeAllNodeHighlights();
var node = this._nodesByRequestId.get(request.requestId);
if (node) {
node.reveal();
this._highlightNode(node);
}
},
_removeAllNodeHighlights: function()
{
if (this._highlightedNode) {
this._highlightedNode.element().classList.remove("highlighted-row");
delete this._highlightedNode;
}
},
/**
* @param {!WebInspector.NetworkDataGridNode} node
*/
_highlightNode: function(node)
{
WebInspector.runCSSAnimationOnce(node.element(), "highlighted-row");
this._highlightedNode = node;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @param {string} platform
* @return {string}
*/
_generateCurlCommand: function(request, platform)
{
var command = ["curl"];
// These headers are derived from URL (except "version") and would be added by cURL anyway.
var ignoredHeaders = {"host": 1, "method": 1, "path": 1, "scheme": 1, "version": 1};
function escapeStringWin(str)
{
/* Replace quote by double quote (but not by \") because it is
recognized by both cmd.exe and MS Crt arguments parser.
Replace % by "%" because it could be expanded to an environment
variable value. So %% becomes "%""%". Even if an env variable ""
(2 doublequotes) is declared, the cmd.exe will not
substitute it with its value.
Replace each backslash with double backslash to make sure
MS Crt arguments parser won't collapse them.
Replace new line outside of quotes since cmd.exe doesn't let
to do it inside.
*/
return "\"" + str.replace(/"/g, "\"\"")
.replace(/%/g, "\"%\"")
.replace(/\\/g, "\\\\")
.replace(/[\r\n]+/g, "\"^$&\"") + "\"";
}
function escapeStringPosix(str)
{
function escapeCharacter(x)
{
var code = x.charCodeAt(0);
if (code < 256) {
// Add leading zero when needed to not care about the next character.
return code < 16 ? "\\x0" + code.toString(16) : "\\x" + code.toString(16);
}
code = code.toString(16);
return "\\u" + ("0000" + code).substr(code.length, 4);
}
if (/[^\x20-\x7E]|\'/.test(str)) {
// Use ANSI-C quoting syntax.
return "$\'" + str.replace(/\\/g, "\\\\")
.replace(/\'/g, "\\\'")
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/[^\x20-\x7E]/g, escapeCharacter) + "'";
} else {
// Use single quote syntax.
return "'" + str + "'";
}
}
// cURL command expected to run on the same platform that DevTools run
// (it may be different from the inspected page platform).
var escapeString = platform === "win" ? escapeStringWin : escapeStringPosix;
command.push(escapeString(request.url).replace(/[[{}\]]/g, "\\$&"));
var inferredMethod = "GET";
var data = [];
var requestContentType = request.requestContentType();
if (requestContentType && requestContentType.startsWith("application/x-www-form-urlencoded") && request.requestFormData) {
data.push("--data");
data.push(escapeString(request.requestFormData));
ignoredHeaders["content-length"] = true;
inferredMethod = "POST";
} else if (request.requestFormData) {
data.push("--data-binary");
data.push(escapeString(request.requestFormData));
ignoredHeaders["content-length"] = true;
inferredMethod = "POST";
}
if (request.requestMethod !== inferredMethod) {
command.push("-X");
command.push(request.requestMethod);
}
var requestHeaders = request.requestHeaders();
for (var i = 0; i < requestHeaders.length; i++) {
var header = requestHeaders[i];
var name = header.name.replace(/^:/, ""); // Translate SPDY v3 headers to HTTP headers.
if (name.toLowerCase() in ignoredHeaders)
continue;
command.push("-H");
command.push(escapeString(name + ": " + header.value));
}
command = command.concat(data);
command.push("--compressed");
if (request.securityState() === SecurityAgent.SecurityState.Insecure)
command.push("--insecure");
return command.join(" ");
},
__proto__: WebInspector.VBox.prototype
}
/** @typedef {function(!WebInspector.NetworkRequest): boolean} */
WebInspector.NetworkLogView.Filter;
/**
* @param {!WebInspector.NetworkLogView.Filter} filter
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._negativeFilter = function(filter, request)
{
return !filter(request);
}
/**
* @param {?RegExp} regex
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestNameOrPathFilter = function(regex, request)
{
if (!regex)
return false;
return regex.test(request.name()) || regex.test(request.path());
}
/**
* @param {string} domain
* @return {!Array.<string>}
*/
WebInspector.NetworkLogView._subdomains = function(domain)
{
var result = [domain];
var indexOfPeriod = domain.indexOf(".");
while (indexOfPeriod !== -1) {
result.push("*" + domain.substring(indexOfPeriod));
indexOfPeriod = domain.indexOf(".", indexOfPeriod + 1);
}
return result;
}
/**
* @param {string} value
* @return {!WebInspector.NetworkLogView.Filter}
*/
WebInspector.NetworkLogView._createRequestDomainFilter = function(value)
{
/**
* @param {string} string
* @return {string}
*/
function escapeForRegExp(string)
{
return string.escapeForRegExp();
}
var escapedPattern = value.split("*").map(escapeForRegExp).join(".*");
return WebInspector.NetworkLogView._requestDomainFilter.bind(null, new RegExp("^" + escapedPattern + "$", "i"));
}
/**
* @param {!RegExp} regex
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestDomainFilter = function(regex, request)
{
return regex.test(request.domain);
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._runningRequestFilter = function(request)
{
return !request.finished;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestResponseHeaderFilter = function(value, request)
{
return request.responseHeaderValue(value) !== undefined;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestMethodFilter = function(value, request)
{
return request.requestMethod === value;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestMimeTypeFilter = function(value, request)
{
return request.mimeType === value;
}
/**
* @param {!WebInspector.NetworkLogView.MixedContentFilterValues} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestMixedContentFilter = function(value, request)
{
if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Displayed) {
return request.mixedContentType === "optionally-blockable";
} else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.Blocked) {
return request.mixedContentType === "blockable" && request.wasBlocked();
} else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden) {
return request.mixedContentType === "blockable" && !request.wasBlocked();
} else if (value === WebInspector.NetworkLogView.MixedContentFilterValues.All) {
return request.mixedContentType !== "none";
}
return false;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestSchemeFilter = function(value, request)
{
return request.scheme === value;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestSetCookieDomainFilter = function(value, request)
{
var cookies = request.responseCookies;
for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
if (cookies[i].domain() === value)
return true;
}
return false;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestSetCookieNameFilter = function(value, request)
{
var cookies = request.responseCookies;
for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
if (cookies[i].name() === value)
return true;
}
return false;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestSetCookieValueFilter = function(value, request)
{
var cookies = request.responseCookies;
for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
if (cookies[i].value() === value)
return true;
}
return false;
}
/**
* @param {number} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestSizeLargerThanFilter = function(value, request)
{
return request.transferSize >= value;
}
/**
* @param {string} value
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._statusCodeFilter = function(value, request)
{
return ("" + request.statusCode) === value;
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView.HTTPRequestsFilter = function(request)
{
return request.parsedURL.isValid && (request.scheme in WebInspector.NetworkLogView.HTTPSchemas);
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView.FinishedRequestsFilter = function(request)
{
return request.finished;
}
/**
* @param {number} windowStart
* @param {number} windowEnd
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestTimeFilter = function(windowStart, windowEnd, request)
{
if (request.issueTime() > windowEnd)
return false;
if (request.endTime !== -1 && request.endTime < windowStart)
return false;
return true;
}
WebInspector.NetworkLogView.EventTypes = {
RequestSelected: "RequestSelected",
SearchCountUpdated: "SearchCountUpdated",
SearchIndexUpdated: "SearchIndexUpdated",
UpdateRequest: "UpdateRequest"
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | 2 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
*/
WebInspector.NetworkOverview = function()
{
WebInspector.TimelineOverviewBase.call(this);
this.element.classList.add("network-overview");
/** @type {number} */
this._numBands = 1;
/** @type {number} */
this._windowStart = 0;
/** @type {number} */
this._windowEnd = 0;
/** @type {boolean} */
this._restoringWindow = false;
/** @type {boolean} */
this._updateScheduled = false;
/** @type {number} */
this._canvasWidth = 0;
/** @type {number} */
this._canvasHeight = 0;
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
this.reset();
}
/** @type {number} */
WebInspector.NetworkOverview._bandHeight = 3;
/** @typedef {{start: number, end: number}} */
WebInspector.NetworkOverview.Window;
WebInspector.NetworkOverview.prototype = {
/**
* @param {?WebInspector.FilmStripModel} filmStripModel
*/
setFilmStripModel: function(filmStripModel)
{
this._filmStripModel = filmStripModel;
this.scheduleUpdate();
},
/**
* @param {number} time
*/
selectFilmStripFrame: function(time)
{
this._selectedFilmStripTime = time;
this.scheduleUpdate();
},
clearFilmStripFrame: function()
{
this._selectedFilmStripTime = -1;
this.scheduleUpdate();
},
/**
* @param {!WebInspector.Event} event
*/
_loadEventFired: function(event)
{
var data = /** @type {number} */ (event.data);
if (data)
this._loadEvents.push(data * 1000);
this.scheduleUpdate();
},
/**
* @param {!WebInspector.Event} event
*/
_domContentLoadedEventFired: function(event)
{
var data = /** @type {number} */ (event.data);
if (data)
this._domContentLoadedEvents.push(data * 1000);
this.scheduleUpdate();
},
/**
* @param {string} connectionId
* @return {number}
*/
_bandId: function(connectionId)
{
if (!connectionId || connectionId === "0")
return -1;
if (this._bandMap.has(connectionId))
return /** @type {number} */ (this._bandMap.get(connectionId));
var result = this._nextBand++;
this._bandMap.set(connectionId, result);
return result;
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
updateRequest: function(request)
{
if (!this._requestsSet.has(request)) {
this._requestsSet.add(request);
this._requestsList.push(request);
}
this.scheduleUpdate();
},
/**
* @override
*/
wasShown: function()
{
this.onResize();
},
/**
* @override
*/
onResize: function()
{
var width = this.element.offsetWidth;
var height = this.element.offsetHeight;
this._calculator.setDisplayWindow(width);
this.resetCanvas();
var numBands = (((height - 1) / WebInspector.NetworkOverview._bandHeight) - 1) | 0;
this._numBands = (numBands > 0) ? numBands : 1;
this.scheduleUpdate();
},
/**
* @override
*/
reset: function()
{
this._windowStart = 0;
this._windowEnd = 0;
/** @type {?WebInspector.FilmStripModel} */
this._filmStripModel = null;
/** @type {number} */
this._span = 1;
/** @type {?WebInspector.NetworkTimeBoundary} */
this._lastBoundary = null;
/** @type {number} */
this._nextBand = 0;
/** @type {!Map.<string, number>} */
this._bandMap = new Map();
/** @type {!Array.<!WebInspector.NetworkRequest>} */
this._requestsList = [];
/** @type {!Set.<!WebInspector.NetworkRequest>} */
this._requestsSet = new Set();
/** @type {!Array.<number>} */
this._loadEvents = [];
/** @type {!Array.<number>} */
this._domContentLoadedEvents = [];
// Clear screen.
this.resetCanvas();
},
/**
* @protected
*/
scheduleUpdate: function()
{
if (this._updateScheduled || !this.isShowing())
return;
this._updateScheduled = true;
this.element.window().requestAnimationFrame(this.update.bind(this));
},
/**
* @override
*/
update: function()
{
this._updateScheduled = false;
var newBoundary = new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(), this._calculator.maximumBoundary());
if (!this._lastBoundary || !newBoundary.equals(this._lastBoundary)) {
var span = this._calculator.boundarySpan();
while (this._span < span)
this._span *= 1.25;
this._calculator.setBounds(this._calculator.minimumBoundary(), this._calculator.minimumBoundary() + this._span);
this._lastBoundary = new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(), this._calculator.maximumBoundary());
if (this._windowStart || this._windowEnd) {
this._restoringWindow = true;
var startTime = this._calculator.minimumBoundary();
var totalTime = this._calculator.boundarySpan();
var left = (this._windowStart - startTime) / totalTime;
var right = (this._windowEnd - startTime) / totalTime;
this._restoringWindow = false;
}
}
var context = this._canvas.getContext("2d");
var calculator = this._calculator;
var linesByType = {};
var paddingTop = 2;
/**
* @param {string} type
* @param {string} strokeStyle
*/
function drawLines(type, strokeStyle)
{
var lines = linesByType[type];
if (!lines)
return;
var n = lines.length;
context.beginPath();
context.strokeStyle = strokeStyle;
for (var i = 0; i < n;) {
var y = lines[i++] * WebInspector.NetworkOverview._bandHeight + paddingTop;
var startTime = lines[i++];
var endTime = lines[i++];
if (endTime === Number.MAX_VALUE)
endTime = calculator.maximumBoundary();
context.moveTo(calculator.computePosition(startTime), y);
context.lineTo(calculator.computePosition(endTime) + 1, y);
}
context.stroke();
}
/**
* @param {string} type
* @param {number} y
* @param {number} start
* @param {number} end
*/
function addLine(type, y, start, end)
{
var lines = linesByType[type];
if (!lines) {
lines = [];
linesByType[type] = lines;
}
lines.push(y, start, end);
}
var requests = this._requestsList;
var n = requests.length;
for (var i = 0; i < n; ++i) {
var request = requests[i];
var band = this._bandId(request.connectionId);
var y = (band === -1) ? 0 : (band % this._numBands + 1);
var timeRanges = WebInspector.RequestTimingView.calculateRequestTimeRanges(request);
for (var j = 0; j < timeRanges.length; ++j) {
var type = timeRanges[j].name;
if (band !== -1 || type === WebInspector.RequestTimeRangeNames.Total)
addLine(type, y, timeRanges[j].start * 1000, timeRanges[j].end * 1000);
}
}
context.clearRect(0, 0, this._canvas.width, this._canvas.height);
context.save();
context.scale(window.devicePixelRatio, window.devicePixelRatio);
context.lineWidth = 2;
drawLines(WebInspector.RequestTimeRangeNames.Total, "#CCCCCC");
drawLines(WebInspector.RequestTimeRangeNames.Blocking, "#AAAAAA");
drawLines(WebInspector.RequestTimeRangeNames.Connecting, "#FF9800");
drawLines(WebInspector.RequestTimeRangeNames.ServiceWorker, "#FF9800");
drawLines(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation, "#FF9800");
drawLines(WebInspector.RequestTimeRangeNames.Proxy, "#A1887F");
drawLines(WebInspector.RequestTimeRangeNames.DNS, "#009688");
drawLines(WebInspector.RequestTimeRangeNames.SSL, "#9C27B0");
drawLines(WebInspector.RequestTimeRangeNames.Sending, "#B0BEC5");
drawLines(WebInspector.RequestTimeRangeNames.Waiting, "#00C853");
drawLines(WebInspector.RequestTimeRangeNames.Receiving, "#03A9F4");
var height = this.element.offsetHeight;
context.lineWidth = 1;
context.beginPath();
context.strokeStyle = "#8080FF"; // Keep in sync with .network-blue-divider CSS rule.
for (var i = this._domContentLoadedEvents.length - 1; i >= 0; --i) {
var x = Math.round(calculator.computePosition(this._domContentLoadedEvents[i])) + 0.5;
context.moveTo(x, 0);
context.lineTo(x, height);
}
context.stroke();
context.beginPath();
context.strokeStyle = "#FF8080"; // Keep in sync with .network-red-divider CSS rule.
for (var i = this._loadEvents.length - 1; i >= 0; --i) {
var x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5;
context.moveTo(x, 0);
context.lineTo(x, height);
}
context.stroke();
if (this._selectedFilmStripTime !== -1) {
context.lineWidth = 2;
context.beginPath();
context.strokeStyle = "#FCCC49"; // Keep in sync with .network-frame-divider CSS rule.
var x = Math.round(calculator.computePosition(this._selectedFilmStripTime));
context.moveTo(x, 0);
context.lineTo(x, height);
context.stroke();
}
context.restore();
},
__proto__: WebInspector.TimelineOverviewBase.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 | 2 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
* @implements {WebInspector.Searchable}
* @extends {WebInspector.Panel}
*/
WebInspector.NetworkPanel = function()
{
WebInspector.Panel.call(this, "network");
this.registerRequiredCSS("network/networkPanel.css");
this._networkLogShowOverviewSetting = WebInspector.settings.createSetting("networkLogShowOverview", true);
this._networkLogLargeRowsSetting = WebInspector.settings.createSetting("networkLogLargeRows", false);
this._networkRecordFilmStripSetting = WebInspector.settings.createSetting("networkRecordFilmStripSetting", false);
this._toggleRecordAction = WebInspector.actionRegistry.action("network.toggle-recording");
/** @type {?WebInspector.FilmStripView} */
this._filmStripView = null;
/** @type {?WebInspector.NetworkPanel.FilmStripRecorder} */
this._filmStripRecorder = null;
this._panelToolbar = new WebInspector.Toolbar("", this.element);
this._filterBar = new WebInspector.FilterBar("networkPanel", true);
this._filterBar.show(this.element);
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.setPlaceholder(WebInspector.UIString("Find by filename or path"));
this._searchableView.show(this.element);
// Create top overview component.
this._overviewPane = new WebInspector.TimelineOverviewPane("network");
this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
this._overviewPane.element.id = "network-overview-panel";
this._networkOverview = new WebInspector.NetworkOverview();
this._overviewPane.setOverviewControls([this._networkOverview]);
this._calculator = new WebInspector.NetworkTransferTimeCalculator();
this._splitWidget = new WebInspector.SplitWidget(true, false, "networkPanelSplitViewState");
this._splitWidget.hideMain();
this._splitWidget.show(this._searchableView.element);
this._progressBarContainer = createElement("div");
this._createToolbarButtons();
/** @type {!WebInspector.NetworkLogView} */
this._networkLogView = new WebInspector.NetworkLogView(this._filterBar, this._progressBarContainer, this._networkLogLargeRowsSetting);
this._splitWidget.setSidebarWidget(this._networkLogView);
this._detailsWidget = new WebInspector.VBox();
this._detailsWidget.element.classList.add("network-details-view");
this._splitWidget.setMainWidget(this._detailsWidget);
this._closeButtonElement = createElementWithClass("div", "network-close-button", "dt-close-button");
this._closeButtonElement.addEventListener("click", this._showRequest.bind(this, null), false);
this._networkLogShowOverviewSetting.addChangeListener(this._toggleShowOverview, this);
this._networkLogLargeRowsSetting.addChangeListener(this._toggleLargerRequests, this);
this._networkRecordFilmStripSetting.addChangeListener(this._toggleRecordFilmStrip, this);
this._toggleRecord(true);
this._toggleShowOverview();
this._toggleLargerRequests();
this._toggleRecordFilmStrip();
this._updateUI();
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.Load, this._load, this);
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.RequestSelected, this._onRequestSelected, this);
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._onSearchCountUpdated, this);
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated, this._onSearchIndexUpdated, this);
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.UpdateRequest, this._onUpdateRequest, this);
WebInspector.DataSaverInfobar.maybeShowInPanel(this);
}
WebInspector.NetworkPanel.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_onWindowChanged: function(event)
{
var startTime = Math.max(this._calculator.minimumBoundary(), event.data.startTime / 1000);
var endTime = Math.min(this._calculator.maximumBoundary(), event.data.endTime / 1000);
this._networkLogView.setWindow(startTime, endTime);
},
_createToolbarButtons: function()
{
this._panelToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleRecordAction));
this._clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear"), "clear-toolbar-item");
this._clearButton.addEventListener("click", this._onClearButtonClicked, this);
this._panelToolbar.appendToolbarItem(this._clearButton);
this._panelToolbar.appendSeparator();
var recordFilmStripButton = new WebInspector.ToolbarSettingToggle(this._networkRecordFilmStripSetting, "camera-toolbar-item", WebInspector.UIString("Capture screenshots"));
this._panelToolbar.appendToolbarItem(recordFilmStripButton);
this._panelToolbar.appendToolbarItem(this._filterBar.filterButton());
this._panelToolbar.appendSeparator();
this._panelToolbar.appendText(WebInspector.UIString("View:"));
var largerRequestsButton = new WebInspector.ToolbarSettingToggle(this._networkLogLargeRowsSetting, "large-list-toolbar-item", WebInspector.UIString("Use large request rows"), WebInspector.UIString("Use small request rows"));
this._panelToolbar.appendToolbarItem(largerRequestsButton);
var showOverviewButton = new WebInspector.ToolbarSettingToggle(this._networkLogShowOverviewSetting, "waterfall-toolbar-item", WebInspector.UIString("Show overview"), WebInspector.UIString("Hide overview"));
this._panelToolbar.appendToolbarItem(showOverviewButton);
this._panelToolbar.appendSeparator();
this._preserveLogCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Preserve log"), WebInspector.UIString("Do not clear log on page reload / navigation"));
this._preserveLogCheckbox.inputElement.addEventListener("change", this._onPreserveLogCheckboxChanged.bind(this), false);
this._panelToolbar.appendToolbarItem(this._preserveLogCheckbox);
this._disableCacheCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Disable cache"), WebInspector.UIString("Disable cache (while DevTools is open)"), WebInspector.moduleSetting("cacheDisabled"));
this._panelToolbar.appendToolbarItem(this._disableCacheCheckbox);
this._panelToolbar.appendSeparator();
this._panelToolbar.appendToolbarItem(this._createBlockedURLsButton());
this._panelToolbar.appendToolbarItem(this._createNetworkConditionsSelect());
this._panelToolbar.appendToolbarItem(new WebInspector.ToolbarItem(this._progressBarContainer));
},
/**
* @return {!WebInspector.ToolbarItem}
*/
_createBlockedURLsButton: function()
{
var setting = WebInspector.moduleSetting("blockedURLs");
setting.addChangeListener(updateAction);
var action = WebInspector.actionRegistry.action("network.blocked-urls.show");
var button = WebInspector.Toolbar.createActionButton(action);
button.setVisible(Runtime.experiments.isEnabled("requestBlocking"));
updateAction();
return button;
function updateAction()
{
action.setState(setting.get().length ? "active" : "inactive");
}
},
/**
* @return {!WebInspector.ToolbarComboBox}
*/
_createNetworkConditionsSelect: function()
{
var toolbarItem = new WebInspector.ToolbarComboBox(null);
toolbarItem.setMaxWidth(140);
WebInspector.NetworkConditionsSelector.decorateSelect(toolbarItem.selectElement());
return toolbarItem;
},
_toggleRecording: function()
{
if (!this._preserveLogCheckbox.checked() && !this._toggleRecordAction.toggled())
this._reset();
this._toggleRecord(!this._toggleRecordAction.toggled());
},
/**
* @param {boolean} toggled
*/
_toggleRecord: function(toggled)
{
this._toggleRecordAction.setToggled(toggled);
this._toggleRecordAction.setTitle(toggled ? WebInspector.UIString("Stop recording network log") : WebInspector.UIString("Record network log"));
this._networkLogView.setRecording(toggled);
if (!toggled && this._filmStripRecorder)
this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
},
/**
* @param {?WebInspector.FilmStripModel} filmStripModel
*/
_filmStripAvailable: function(filmStripModel)
{
if (!filmStripModel)
return;
var calculator = this._networkLogView.timeCalculator();
this._filmStripView.setModel(filmStripModel, calculator.minimumBoundary() * 1000, calculator.boundarySpan() * 1000);
this._networkOverview.setFilmStripModel(filmStripModel);
var timestamps = filmStripModel.frames().map(mapTimestamp);
/**
* @param {!WebInspector.FilmStripModel.Frame} frame
* @return {number}
*/
function mapTimestamp(frame)
{
return frame.timestamp / 1000;
}
this._networkLogView.addFilmStripFrames(timestamps);
},
/**
* @param {!Event} event
*/
_onPreserveLogCheckboxChanged: function(event)
{
this._networkLogView.setPreserveLog(this._preserveLogCheckbox.checked());
},
/**
* @param {!WebInspector.Event} event
*/
_onClearButtonClicked: function(event)
{
this._reset();
},
_reset: function()
{
this._calculator.reset();
this._overviewPane.reset();
this._networkLogView.reset();
WebInspector.BlockedURLsPane.reset();
if (this._filmStripView)
this._resetFilmStripView();
},
/**
* @param {!WebInspector.Event} event
*/
_willReloadPage: function(event)
{
if (!this._preserveLogCheckbox.checked())
this._reset();
this._toggleRecord(true);
if (this._pendingStopTimer) {
clearTimeout(this._pendingStopTimer);
delete this._pendingStopTimer;
}
if (this.isShowing() && this._filmStripRecorder)
this._filmStripRecorder.startRecording();
},
/**
* @param {!WebInspector.Event} event
*/
_load: function(event)
{
if (this._filmStripRecorder && this._filmStripRecorder.isRecording())
this._pendingStopTimer = setTimeout(this._toggleRecord.bind(this, false), 1000);
},
_toggleLargerRequests: function()
{
this._updateUI();
},
_toggleShowOverview: function()
{
var toggled = this._networkLogShowOverviewSetting.get();
if (toggled)
this._overviewPane.show(this._searchableView.element, this._splitWidget.element);
else
this._overviewPane.detach();
this.doResize();
},
_toggleRecordFilmStrip: function()
{
var toggled = this._networkRecordFilmStripSetting.get();
if (toggled && !this._filmStripRecorder) {
this._filmStripView = new WebInspector.FilmStripView();
this._filmStripView.setMode(WebInspector.FilmStripView.Modes.FrameBased);
this._filmStripView.element.classList.add("network-film-strip");
this._filmStripRecorder = new WebInspector.NetworkPanel.FilmStripRecorder(this._networkLogView.timeCalculator(), this._filmStripView);
this._filmStripView.show(this._searchableView.element, this._searchableView.element.firstElementChild);
this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameSelected, this._onFilmFrameSelected, this);
this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameEnter, this._onFilmFrameEnter, this);
this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameExit, this._onFilmFrameExit, this);
this._resetFilmStripView();
}
if (!toggled && this._filmStripRecorder) {
this._filmStripView.detach();
this._filmStripView = null;
this._filmStripRecorder = null;
}
},
_resetFilmStripView: function()
{
this._filmStripView.reset();
this._filmStripView.setStatusText(WebInspector.UIString("Hit %s to reload and capture filmstrip.", WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name));
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return this._networkLogView.elementsToRestoreScrollPositionsFor();
},
/**
* @override
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
/**
* @override
* @param {!KeyboardEvent} event
*/
handleShortcut: function(event)
{
if (this._networkItemView && event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
this._showRequest(null);
event.handled = true;
return;
}
WebInspector.Panel.prototype.handleShortcut.call(this, event);
},
wasShown: function()
{
WebInspector.context.setFlavor(WebInspector.NetworkPanel, this);
},
willHide: function()
{
WebInspector.context.setFlavor(WebInspector.NetworkPanel, null);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
revealAndHighlightRequest: function(request)
{
this._showRequest(null);
if (request)
this._networkLogView.revealAndHighlightRequest(request);
},
/**
* @param {!WebInspector.Event} event
*/
_onRowSizeChanged: function(event)
{
this._updateUI();
},
/**
* @param {!WebInspector.Event} event
*/
_onSearchCountUpdated: function(event)
{
var count = /** @type {number} */ (event.data);
this._searchableView.updateSearchMatchesCount(count);
},
/**
* @param {!WebInspector.Event} event
*/
_onSearchIndexUpdated: function(event)
{
var index = /** @type {number} */ (event.data);
this._searchableView.updateCurrentMatchIndex(index);
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestSelected: function(event)
{
var request = /** @type {?WebInspector.NetworkRequest} */ (event.data);
this._showRequest(request);
},
/**
* @param {?WebInspector.NetworkRequest} request
*/
_showRequest: function(request)
{
if (this._networkItemView) {
this._networkItemView.detach();
this._networkItemView = null;
}
if (request) {
this._networkItemView = new WebInspector.NetworkItemView(request, this._networkLogView.timeCalculator());
this._networkItemView.insertBeforeTabStrip(this._closeButtonElement);
this._networkItemView.show(this._detailsWidget.element);
this._splitWidget.showBoth();
} else {
this._splitWidget.hideMain();
this._networkLogView.clearSelection();
}
this._updateUI();
},
_updateUI: function()
{
this._detailsWidget.element.classList.toggle("network-details-view-tall-header", this._networkLogLargeRowsSetting.get());
this._networkLogView.switchViewMode(!this._splitWidget.isResizable());
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
this._networkLogView.performSearch(searchConfig, shouldJump, jumpBackwards);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
this._networkLogView.jumpToPreviousSearchResult();
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
this._networkLogView.jumpToNextSearchResult();
},
/**
* @override
*/
searchCanceled: function()
{
this._networkLogView.searchCanceled();
},
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
* @this {WebInspector.NetworkPanel}
*/
appendApplicableItems: function(event, contextMenu, target)
{
/**
* @this {WebInspector.NetworkPanel}
*/
function reveal(request)
{
WebInspector.inspectorView.setCurrentPanel(this);
this.revealAndHighlightRequest(request);
}
/**
* @this {WebInspector.NetworkPanel}
*/
function appendRevealItem(request)
{
contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Network ^panel"), reveal.bind(this, request));
}
if (event.target.isSelfOrDescendant(this.element))
return;
if (target instanceof WebInspector.Resource) {
var resource = /** @type {!WebInspector.Resource} */ (target);
if (resource.request)
appendRevealItem.call(this, resource.request);
return;
}
if (target instanceof WebInspector.UISourceCode) {
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target);
var resource = WebInspector.resourceForURL(WebInspector.networkMapping.networkURL(uiSourceCode));
if (resource && resource.request)
appendRevealItem.call(this, resource.request);
return;
}
if (!(target instanceof WebInspector.NetworkRequest))
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (target);
if (this._networkItemView && this._networkItemView.isShowing() && this._networkItemView.request() === request)
return;
appendRevealItem.call(this, request);
},
/**
* @param {!WebInspector.Event} event
*/
_onFilmFrameSelected: function(event)
{
var timestamp = /** @type {number} */ (event.data);
this._overviewPane.requestWindowTimes(0, timestamp);
},
/**
* @param {!WebInspector.Event} event
*/
_onFilmFrameEnter: function(event)
{
var timestamp = /** @type {number} */ (event.data);
this._networkOverview.selectFilmStripFrame(timestamp);
this._networkLogView.selectFilmStripFrame(timestamp / 1000);
},
/**
* @param {!WebInspector.Event} event
*/
_onFilmFrameExit: function(event)
{
this._networkOverview.clearFilmStripFrame();
this._networkLogView.clearFilmStripFrame();
},
/**
* @param {!WebInspector.Event} event
*/
_onUpdateRequest: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._calculator.updateBoundaries(request);
// FIXME: Unify all time units across the frontend!
this._overviewPane.setBounds(this._calculator.minimumBoundary() * 1000, this._calculator.maximumBoundary() * 1000);
this._networkOverview.updateRequest(request);
this._overviewPane.scheduleUpdate();
},
__proto__: WebInspector.Panel.prototype
}
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.NetworkPanel.ContextMenuProvider = function()
{
}
WebInspector.NetworkPanel.ContextMenuProvider.prototype = {
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
WebInspector.NetworkPanel._instance().appendApplicableItems(event, contextMenu, target);
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.NetworkPanel.RequestRevealer = function()
{
}
WebInspector.NetworkPanel.RequestRevealer.prototype = {
/**
* @override
* @param {!Object} request
* @param {number=} lineNumber
* @return {!Promise}
*/
reveal: function(request, lineNumber)
{
if (!(request instanceof WebInspector.NetworkRequest))
return Promise.reject(new Error("Internal error: not a network request"));
var panel = WebInspector.NetworkPanel._instance();
WebInspector.inspectorView.setCurrentPanel(panel);
panel.revealAndHighlightRequest(request);
return Promise.resolve();
}
}
WebInspector.NetworkPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.NetworkPanel._instance());
}
/**
* @param {!Array<{filterType: !WebInspector.NetworkLogView.FilterType, filterValue: string}>} filters
*/
WebInspector.NetworkPanel.revealAndFilter = function(filters)
{
var panel = WebInspector.NetworkPanel._instance();
var filterString = '';
for (var filter of filters)
filterString += filter.filterType + ':' + filter.filterValue + ' ';
panel._networkLogView.setTextFilterValue(filterString);
WebInspector.inspectorView.setCurrentPanel(panel);
}
/**
* @return {!WebInspector.NetworkPanel}
*/
WebInspector.NetworkPanel._instance = function()
{
if (!WebInspector.NetworkPanel._instanceObject)
WebInspector.NetworkPanel._instanceObject = new WebInspector.NetworkPanel();
return WebInspector.NetworkPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.NetworkPanelFactory = function()
{
}
WebInspector.NetworkPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.NetworkPanel._instance();
}
}
/**
* @constructor
* @implements {WebInspector.TracingManagerClient}
* @param {!WebInspector.NetworkTimeCalculator} timeCalculator
* @param {!WebInspector.FilmStripView} filmStripView
*/
WebInspector.NetworkPanel.FilmStripRecorder = function(timeCalculator, filmStripView)
{
this._timeCalculator = timeCalculator;
this._filmStripView = filmStripView;
}
WebInspector.NetworkPanel.FilmStripRecorder.prototype = {
/**
* @override
*/
tracingStarted: function()
{
},
/**
* @override
* @param {!Array.<!WebInspector.TracingManager.EventPayload>} events
*/
traceEventsCollected: function(events)
{
if (this._tracingModel)
this._tracingModel.addEvents(events);
},
/**
* @override
*/
tracingComplete: function()
{
if (!this._tracingModel)
return;
this._tracingModel.tracingComplete();
var resourceTreeModel = this._target.resourceTreeModel;
this._target = null;
setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel));
this._callback(new WebInspector.FilmStripModel(this._tracingModel, this._timeCalculator.minimumBoundary() * 1000));
delete this._callback;
},
/**
* @override
*/
tracingBufferUsage: function()
{
},
/**
* @override
* @param {number} progress
*/
eventsRetrievalProgress: function(progress)
{
},
startRecording: function()
{
this._filmStripView.reset();
this._filmStripView.setStatusText(WebInspector.UIString("Recording frames..."));
if (this._target)
return;
this._target = WebInspector.targetManager.mainTarget();
if (this._tracingModel)
this._tracingModel.reset();
else
this._tracingModel = new WebInspector.TracingModel(new WebInspector.TempFileBackingStorage("tracing"));
this._target.tracingManager.start(this, "-*,disabled-by-default-devtools.screenshot", "");
},
/**
* @return {boolean}
*/
isRecording: function()
{
return !!this._target;
},
/**
* @param {function(?WebInspector.FilmStripModel)} callback
*/
stopRecording: function(callback)
{
if (!this._target)
return;
this._target.tracingManager.stop();
this._target.resourceTreeModel.suspendReload();
this._callback = callback;
this._filmStripView.setStatusText(WebInspector.UIString("Fetching frames..."));
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.NetworkPanel.RecordActionDelegate = function()
{
}
WebInspector.NetworkPanel.RecordActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var panel = WebInspector.context.flavor(WebInspector.NetworkPanel);
console.assert(panel && panel instanceof WebInspector.NetworkPanel);
panel._toggleRecording();
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | 2 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {number} minimum
* @param {number} maximum
*/
WebInspector.NetworkTimeBoundary = function(minimum, maximum)
{
this.minimum = minimum;
this.maximum = maximum;
}
WebInspector.NetworkTimeBoundary.prototype = {
/**
* @param {!WebInspector.NetworkTimeBoundary} other
* @return {boolean}
*/
equals: function(other)
{
return (this.minimum === other.minimum) && (this.maximum === other.maximum);
}
}
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.NetworkTimeCalculator = function(startAtZero)
{
this.startAtZero = startAtZero;
this._boundryChangedEventThrottler = new WebInspector.Throttler(0);
/** @type {?WebInspector.NetworkTimeBoundary} */
this._window = null;
}
/** @enum {string} */
WebInspector.NetworkTimeCalculator.Events = {
BoundariesChanged: "BoundariesChanged"
}
/** @type {!WebInspector.UIStringFormat} */
WebInspector.NetworkTimeCalculator._latencyDownloadTotalFormat = new WebInspector.UIStringFormat("%s latency, %s download (%s total)");
/** @type {!WebInspector.UIStringFormat} */
WebInspector.NetworkTimeCalculator._latencyFormat = new WebInspector.UIStringFormat("%s latency");
/** @type {!WebInspector.UIStringFormat} */
WebInspector.NetworkTimeCalculator._downloadFormat = new WebInspector.UIStringFormat("%s download");
/** @type {!WebInspector.UIStringFormat} */
WebInspector.NetworkTimeCalculator._fromServiceWorkerFormat = new WebInspector.UIStringFormat("%s (from ServiceWorker)");
/** @type {!WebInspector.UIStringFormat} */
WebInspector.NetworkTimeCalculator._fromCacheFormat = new WebInspector.UIStringFormat("%s (from cache)");
WebInspector.NetworkTimeCalculator.prototype = {
/**
* @param {?WebInspector.NetworkTimeBoundary} window
*/
setWindow: function(window)
{
this._window = window;
this._boundaryChanged();
},
setInitialUserFriendlyBoundaries: function()
{
this._minimumBoundary = 0;
this._maximumBoundary = 1;
},
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return 0;
},
/**
* @override
* @param {number} time
* @return {number}
*/
computePosition: function(time)
{
return (time - this.minimumBoundary()) / this.boundarySpan() * this._workingArea;
},
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.secondsToString(value, !!precision);
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._window ? this._window.minimum : this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
zeroTime: function()
{
return this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
maximumBoundary: function()
{
return this._window ? this._window.maximum : this._maximumBoundary;
},
/**
* @return {!WebInspector.NetworkTimeBoundary}
*/
boundary: function()
{
return new WebInspector.NetworkTimeBoundary(this.minimumBoundary(), this.maximumBoundary());
},
/**
* @override
* @return {number}
*/
boundarySpan: function()
{
return this.maximumBoundary() - this.minimumBoundary();
},
reset: function()
{
delete this._minimumBoundary;
delete this._maximumBoundary;
this._boundaryChanged();
},
/**
* @return {number}
*/
_value: function(item)
{
return 0;
},
/**
* @param {number} clientWidth
*/
setDisplayWindow: function(clientWidth)
{
this._workingArea = clientWidth;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!{start: number, middle: number, end: number}}
*/
computeBarGraphPercentages: function(request)
{
if (request.startTime !== -1)
var start = ((request.startTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
else
var start = 0;
if (request.responseReceivedTime !== -1)
var middle = ((request.responseReceivedTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
else
var middle = (this.startAtZero ? start : 100);
if (request.endTime !== -1)
var end = ((request.endTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
else
var end = (this.startAtZero ? middle : 100);
if (this.startAtZero) {
end -= start;
middle -= start;
start = 0;
}
return {start: start, middle: middle, end: end};
},
/**
* @param {number} eventTime
* @return {number}
*/
computePercentageFromEventTime: function(eventTime)
{
// This function computes a percentage in terms of the total loading time
// of a specific event. If startAtZero is set, then this is useless, and we
// want to return 0.
if (eventTime !== -1 && !this.startAtZero)
return ((eventTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
return 0;
},
/**
* @param {number} percentage
* @return {number}
*/
percentageToTime: function(percentage)
{
return percentage * this.boundarySpan() / 100 + this.minimumBoundary();
},
_boundaryChanged: function()
{
this._boundryChangedEventThrottler.schedule(dispatchEvent.bind(this));
/**
* @return {!Promise.<undefined>}
* @this {WebInspector.NetworkTimeCalculator}
*/
function dispatchEvent()
{
this.dispatchEventToListeners(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged);
return Promise.resolve();
}
},
/**
* @param {number} eventTime
*/
updateBoundariesForEventTime: function(eventTime)
{
if (eventTime === -1 || this.startAtZero)
return;
if (this._maximumBoundary === undefined || eventTime > this._maximumBoundary) {
this._maximumBoundary = eventTime;
this._boundaryChanged();
}
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!{left: string, right: string, tooltip: (string|undefined)}}
*/
computeBarGraphLabels: function(request)
{
var rightLabel = "";
if (request.responseReceivedTime !== -1 && request.endTime !== -1)
rightLabel = Number.secondsToString(request.endTime - request.responseReceivedTime);
var hasLatency = request.latency > 0;
if (hasLatency)
var leftLabel = Number.secondsToString(request.latency);
else
var leftLabel = rightLabel;
if (request.timing)
return {left: leftLabel, right: rightLabel};
if (hasLatency && rightLabel) {
var total = Number.secondsToString(request.duration);
var tooltip = WebInspector.NetworkTimeCalculator._latencyDownloadTotalFormat.format(leftLabel, rightLabel, total);
} else if (hasLatency) {
var tooltip = WebInspector.NetworkTimeCalculator._latencyFormat.format(leftLabel);
} else if (rightLabel) {
var tooltip = WebInspector.NetworkTimeCalculator._downloadFormat.format(rightLabel);
}
if (request.fetchedViaServiceWorker)
tooltip = WebInspector.NetworkTimeCalculator._fromServiceWorkerFormat.format(tooltip);
else if (request.cached())
tooltip = WebInspector.NetworkTimeCalculator._fromCacheFormat.format(tooltip);
return {left: leftLabel, right: rightLabel, tooltip: tooltip};
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
updateBoundaries: function(request)
{
var lowerBound = this._lowerBound(request);
var upperBound = this._upperBound(request);
var changed = false;
if (lowerBound !== -1 || this.startAtZero)
changed = this._extendBoundariesToIncludeTimestamp(this.startAtZero ? 0 : lowerBound);
if (upperBound !== -1)
changed = this._extendBoundariesToIncludeTimestamp(upperBound) || changed;
if (changed)
this._boundaryChanged();
},
/**
* @param {number} timestamp
* @return {boolean}
*/
_extendBoundariesToIncludeTimestamp: function(timestamp)
{
var previousMinimumBoundary = this._minimumBoundary;
var previousMaximumBoundary = this._maximumBoundary;
if (typeof this._minimumBoundary === "undefined" || typeof this._maximumBoundary === "undefined") {
this._minimumBoundary = timestamp;
this._maximumBoundary = timestamp + 1;
} else {
this._minimumBoundary = Math.min(timestamp, this._minimumBoundary);
this._maximumBoundary = Math.max(timestamp, this._minimumBoundary + 1, this._maximumBoundary);
}
return previousMinimumBoundary !== this._minimumBoundary || previousMaximumBoundary !== this._maximumBoundary;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {number}
*/
_lowerBound: function(request)
{
return 0;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {number}
*/
_upperBound: function(request)
{
return 0;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.NetworkTimeCalculator}
*/
WebInspector.NetworkTransferTimeCalculator = function()
{
WebInspector.NetworkTimeCalculator.call(this, false);
}
WebInspector.NetworkTransferTimeCalculator.prototype = {
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.secondsToString(value - this.zeroTime(), !!precision);
},
/**
* @override
* @param {!WebInspector.NetworkRequest} request
* @return {number}
*/
_lowerBound: function(request)
{
return request.issueTime();
},
/**
* @override
* @param {!WebInspector.NetworkRequest} request
* @return {number}
*/
_upperBound: function(request)
{
return request.endTime;
},
__proto__: WebInspector.NetworkTimeCalculator.prototype
}
/**
* @constructor
* @extends {WebInspector.NetworkTimeCalculator}
*/
WebInspector.NetworkTransferDurationCalculator = function()
{
WebInspector.NetworkTimeCalculator.call(this, true);
}
WebInspector.NetworkTransferDurationCalculator.prototype = {
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.secondsToString(value, !!precision);
},
/**
* @override
* @param {!WebInspector.NetworkRequest} request
* @return {number}
*/
_upperBound: function(request)
{
return request.duration;
},
__proto__: WebInspector.NetworkTimeCalculator.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestCookiesView = function(request)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("network/requestCookiesView.css");
this.element.classList.add("request-cookies-view");
this._request = request;
}
WebInspector.RequestCookiesView.prototype = {
wasShown: function()
{
this._request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshCookies, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshCookies, this);
if (!this._gotCookies) {
if (!this._emptyWidget) {
this._emptyWidget = new WebInspector.EmptyWidget(WebInspector.UIString("This request has no cookies."));
this._emptyWidget.show(this.element);
}
return;
}
if (!this._cookiesTable)
this._buildCookiesTable();
},
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshCookies, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshCookies, this);
},
get _gotCookies()
{
return (this._request.requestCookies && this._request.requestCookies.length) || (this._request.responseCookies && this._request.responseCookies.length);
},
_buildCookiesTable: function()
{
this.detachChildWidgets();
this._cookiesTable = new WebInspector.CookiesTable(true);
this._cookiesTable.setCookieFolders([
{folderName: WebInspector.UIString("Request Cookies"), cookies: this._request.requestCookies},
{folderName: WebInspector.UIString("Response Cookies"), cookies: this._request.responseCookies}
]);
this._cookiesTable.show(this.element);
},
_refreshCookies: function()
{
delete this._cookiesTable;
if (!this._gotCookies || !this.isShowing())
return;
this._buildCookiesTable();
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.RequestView}
* @param {!WebInspector.NetworkRequest} request
* @param {string} dataURL
*/
WebInspector.RequestHTMLView = function(request, dataURL)
{
WebInspector.RequestView.call(this, request);
this._dataURL = dataURL;
this.element.classList.add("html");
}
WebInspector.RequestHTMLView.prototype = {
wasShown: function()
{
this._createIFrame();
},
willHide: function(parentElement)
{
this.element.removeChildren();
},
_createIFrame: function()
{
// We need to create iframe again each time because contentDocument
// is deleted when iframe is removed from its parent.
this.element.removeChildren();
var iframe = createElement("iframe");
iframe.setAttribute("sandbox", ""); // Forbid to run JavaScript and set unique origin.
iframe.setAttribute("src", this._dataURL);
this.element.appendChild(iframe);
},
__proto__: WebInspector.RequestView.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | 2 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) IBM Corp. 2009 All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestHeadersView = function(request)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("network/requestHeadersView.css");
this.element.classList.add("request-headers-view");
this._request = request;
this._decodeRequestParameters = true;
this._showRequestHeadersText = false;
this._showResponseHeadersText = false;
this._requestHeaderFilterSetting = WebInspector.settings.createSetting("requestHeaderFilterSetting", "");
/** @type {?RegExp} */
this._filterRegex = null;
if (Runtime.experiments.isEnabled("networkRequestHeadersFilterInDetailsView")) {
this._filterInput = this.element.createChild("input", "filter-input");
this._filterInput.type = "text";
this._filterInput.placeholder = WebInspector.UIString("Filter headers");
this._filterInput.addEventListener("input", this._updateFilter.bind(this), false);
this._filterInput.addEventListener("keydown", this._onFilterKeyDown.bind(this), false);
this._filterInput.value = this._requestHeaderFilterSetting.get() || "";
}
var root = new TreeOutline(true);
root.element.classList.add("outline-disclosure");
root.expandTreeElementsWhenArrowing = true;
this.element.appendChild(root.element);
var generalCategory = new WebInspector.RequestHeadersView.Category(root, "general", WebInspector.UIString("General"));
generalCategory.hidden = false;
this._urlItem = generalCategory.createLeaf();
this._requestMethodItem = generalCategory.createLeaf();
this._statusCodeItem = generalCategory.createLeaf();
this._remoteAddressItem = generalCategory.createLeaf();
this._remoteAddressItem.hidden = true;
this._responseHeadersCategory = new WebInspector.RequestHeadersView.Category(root, "responseHeaders", "");
this._requestHeadersCategory = new WebInspector.RequestHeadersView.Category(root, "requestHeaders", "");
this._queryStringCategory = new WebInspector.RequestHeadersView.Category(root, "queryString", "");
this._formDataCategory = new WebInspector.RequestHeadersView.Category(root, "formData", "");
this._requestPayloadCategory = new WebInspector.RequestHeadersView.Category(root, "requestPayload", WebInspector.UIString("Request Payload"));
if (Runtime.experiments.isEnabled("networkRequestHeadersFilterInDetailsView")) {
this._updateFilter();
}
}
WebInspector.RequestHeadersView.prototype = {
_updateFilter: function()
{
var text = this._filterInput.value;
this._requestHeaderFilterSetting.set(text);
this._filterRegex = text ? new RegExp(text.escapeForRegExp(), "i") : null;
this._updateHeaders();
},
/**
* @param {!Event} event
*/
_onFilterKeyDown: function(event)
{
var text = this._filterInput.value;
if (!text)
return;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") {
event.consume(true);
this._filterInput.value = "";
this._updateFilter();
}
},
_updateHeaders: function()
{
this._refreshRequestHeaders();
this._refreshResponseHeaders();
},
wasShown: function()
{
this._request.addEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
this._refreshURL();
this._refreshQueryString();
this._updateHeaders();
this._refreshHTTPInformation();
this._refreshRemoteAddress();
},
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
},
/**
* @param {string} name
* @param {string} value
* @return {!DocumentFragment}
*/
_formatHeader: function(name, value)
{
var fragment = createDocumentFragment();
fragment.createChild("div", "header-name").textContent = name + ":";
fragment.createChild("div", "header-value source-code").textContent = value;
return fragment;
},
/**
* @param {string} value
* @param {string} className
* @param {boolean} decodeParameters
* @return {!Element}
*/
_formatParameter: function(value, className, decodeParameters)
{
var errorDecoding = false;
if (decodeParameters) {
value = value.replace(/\+/g, " ");
if (value.indexOf("%") >= 0) {
try {
value = decodeURIComponent(value);
} catch (e) {
errorDecoding = true;
}
}
}
var div = createElementWithClass("div", className);
if (errorDecoding)
div.createChild("span", "error-message").textContent = WebInspector.UIString("(unable to decode value)");
else
div.textContent = value;
return div;
},
_refreshURL: function()
{
this._urlItem.title = this._formatHeader(WebInspector.UIString("Request URL"), this._request.url);
},
_refreshQueryString: function()
{
var queryString = this._request.queryString();
var queryParameters = this._request.queryParameters;
this._queryStringCategory.hidden = !queryParameters;
if (queryParameters)
this._refreshParams(WebInspector.UIString("Query String Parameters"), queryParameters, queryString, this._queryStringCategory);
},
_refreshFormData: function()
{
this._formDataCategory.hidden = true;
this._requestPayloadCategory.hidden = true;
var formData = this._request.requestFormData;
if (!formData)
return;
var formParameters = this._request.formParameters;
if (formParameters) {
this._formDataCategory.hidden = false;
this._refreshParams(WebInspector.UIString("Form Data"), formParameters, formData, this._formDataCategory);
} else {
this._requestPayloadCategory.hidden = false;
try {
var json = JSON.parse(formData);
this._refreshRequestJSONPayload(json, formData);
} catch (e) {
this._populateTreeElementWithSourceText(this._requestPayloadCategory, formData);
}
}
},
/**
* @param {!TreeElement} treeElement
* @param {?string} sourceText
*/
_populateTreeElementWithSourceText: function(treeElement, sourceText)
{
var sourceTextElement = createElementWithClass("span", "header-value source-code");
sourceTextElement.textContent = String(sourceText || "").trim();
var sourceTreeElement = new TreeElement(sourceTextElement);
sourceTreeElement.selectable = false;
treeElement.removeChildren();
treeElement.appendChild(sourceTreeElement);
},
/**
* @param {string} title
* @param {?Array.<!WebInspector.NetworkRequest.NameValue>} params
* @param {?string} sourceText
* @param {!TreeElement} paramsTreeElement
*/
_refreshParams: function(title, params, sourceText, paramsTreeElement)
{
paramsTreeElement.removeChildren();
paramsTreeElement.listItemElement.removeChildren();
paramsTreeElement.listItemElement.createTextChild(title);
var headerCount = createElementWithClass("span", "header-count");
headerCount.textContent = WebInspector.UIString("\u00A0(%d)", params.length);
paramsTreeElement.listItemElement.appendChild(headerCount);
/**
* @param {!Event} event
* @this {WebInspector.RequestHeadersView}
*/
function toggleViewSource(event)
{
paramsTreeElement._viewSource = !paramsTreeElement._viewSource;
this._refreshParams(title, params, sourceText, paramsTreeElement);
event.consume();
}
paramsTreeElement.listItemElement.appendChild(this._createViewSourceToggle(paramsTreeElement._viewSource, toggleViewSource.bind(this)));
if (paramsTreeElement._viewSource) {
this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);
return;
}
var toggleTitle = this._decodeRequestParameters ? WebInspector.UIString("view URL encoded") : WebInspector.UIString("view decoded");
var toggleButton = this._createToggleButton(toggleTitle);
toggleButton.addEventListener("click", this._toggleURLDecoding.bind(this), false);
paramsTreeElement.listItemElement.appendChild(toggleButton);
for (var i = 0; i < params.length; ++i) {
var paramNameValue = createDocumentFragment();
var name = this._formatParameter(params[i].name + ":", "header-name", this._decodeRequestParameters);
var value = this._formatParameter(params[i].value, "header-value source-code", this._decodeRequestParameters);
paramNameValue.appendChild(name);
paramNameValue.appendChild(value);
var parmTreeElement = new TreeElement(paramNameValue);
parmTreeElement.selectable = false;
paramsTreeElement.appendChild(parmTreeElement);
}
},
/**
* @param {*} parsedObject
* @param {string} sourceText
*/
_refreshRequestJSONPayload: function(parsedObject, sourceText)
{
var treeElement = this._requestPayloadCategory;
treeElement.removeChildren();
var listItem = this._requestPayloadCategory.listItemElement;
listItem.removeChildren();
listItem.createTextChild(this._requestPayloadCategory.title);
/**
* @param {!Event} event
* @this {WebInspector.RequestHeadersView}
*/
function toggleViewSource(event)
{
treeElement._viewSource = !treeElement._viewSource;
this._refreshRequestJSONPayload(parsedObject, sourceText);
event.consume();
}
listItem.appendChild(this._createViewSourceToggle(treeElement._viewSource, toggleViewSource.bind(this)));
if (treeElement._viewSource) {
this._populateTreeElementWithSourceText(this._requestPayloadCategory, sourceText);
} else {
var object = WebInspector.RemoteObject.fromLocalObject(parsedObject);
var section = new WebInspector.ObjectPropertiesSection(object, object.description);
section.expand();
section.editable = false;
treeElement.appendChild(new TreeElement(section.element));
}
},
/**
* @param {boolean} viewSource
* @param {function(!Event)} handler
* @return {!Element}
*/
_createViewSourceToggle: function(viewSource, handler)
{
var viewSourceToggleTitle = viewSource ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
var viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
viewSourceToggleButton.addEventListener("click", handler, false);
return viewSourceToggleButton;
},
/**
* @param {!Event} event
*/
_toggleURLDecoding: function(event)
{
this._decodeRequestParameters = !this._decodeRequestParameters;
this._refreshQueryString();
this._refreshFormData();
event.consume();
},
_refreshRequestHeaders: function()
{
var treeElement = this._requestHeadersCategory;
var headers = this._request.requestHeaders().slice();
var filterRegex = this._filterRegex;
if (filterRegex)
headers = headers.filter(function(header) { return filterRegex.test(header.name) || filterRegex.test(header.value);});
headers.sort(function(a, b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); });
var headersText = this._request.requestHeadersText();
if (this._showRequestHeadersText && headersText)
this._refreshHeadersText(WebInspector.UIString("Request Headers"), headers.length, headersText, treeElement);
else
this._refreshHeaders(WebInspector.UIString("Request Headers"), headers, treeElement, headersText === undefined);
if (headersText) {
var toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
toggleButton.addEventListener("click", this._toggleRequestHeadersText.bind(this), false);
treeElement.listItemElement.appendChild(toggleButton);
}
this._refreshFormData();
},
_refreshResponseHeaders: function()
{
var treeElement = this._responseHeadersCategory;
var headers = this._request.sortedResponseHeaders.slice();
var filterRegex = this._filterRegex;
if (filterRegex)
headers = headers.filter(function(header) { return filterRegex.test(header.name) || filterRegex.test(header.value);});
var headersText = this._request.responseHeadersText;
if (this._showResponseHeadersText)
this._refreshHeadersText(WebInspector.UIString("Response Headers"), headers.length, headersText, treeElement);
else
this._refreshHeaders(WebInspector.UIString("Response Headers"), headers, treeElement);
if (headersText) {
var toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
toggleButton.addEventListener("click", this._toggleResponseHeadersText.bind(this), false);
treeElement.listItemElement.appendChild(toggleButton);
}
},
_refreshHTTPInformation: function()
{
var requestMethodElement = this._requestMethodItem;
requestMethodElement.hidden = !this._request.statusCode;
var statusCodeElement = this._statusCodeItem;
statusCodeElement.hidden = !this._request.statusCode;
if (this._request.statusCode) {
var statusCodeFragment = createDocumentFragment();
statusCodeFragment.createChild("div", "header-name").textContent = WebInspector.UIString("Status Code") + ":";
var statusCodeImage = statusCodeFragment.createChild("label", "resource-status-image", "dt-icon-label");
statusCodeImage.title = this._request.statusCode + " " + this._request.statusText;
if (this._request.statusCode < 300 || this._request.statusCode === 304)
statusCodeImage.type = "green-ball";
else if (this._request.statusCode < 400)
statusCodeImage.type = "orange-ball";
else
statusCodeImage.type = "red-ball";
requestMethodElement.title = this._formatHeader(WebInspector.UIString("Request Method"), this._request.requestMethod);
var statusTextElement = statusCodeFragment.createChild("div", "header-value source-code");
var statusText = this._request.statusCode + " " + this._request.statusText;
if (this._request.fetchedViaServiceWorker) {
statusText += " " + WebInspector.UIString("(from ServiceWorker)");
statusTextElement.classList.add("status-from-cache");
} else if (this._request.cached()) {
statusText += " " + WebInspector.UIString("(from cache)");
statusTextElement.classList.add("status-from-cache");
}
statusTextElement.textContent = statusText;
statusCodeElement.title = statusCodeFragment;
}
},
/**
* @param {string} title
* @param {!TreeElement} headersTreeElement
* @param {number} headersLength
*/
_refreshHeadersTitle: function(title, headersTreeElement, headersLength)
{
headersTreeElement.listItemElement.removeChildren();
headersTreeElement.listItemElement.createTextChild(title);
var headerCount = WebInspector.UIString("\u00A0(%d)", headersLength);
headersTreeElement.listItemElement.createChild("span", "header-count").textContent = headerCount;
},
/**
* @param {string} title
* @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers
* @param {!TreeElement} headersTreeElement
* @param {boolean=} provisionalHeaders
*/
_refreshHeaders: function(title, headers, headersTreeElement, provisionalHeaders)
{
headersTreeElement.removeChildren();
var length = headers.length;
this._refreshHeadersTitle(title, headersTreeElement, length);
if (provisionalHeaders) {
var cautionText = WebInspector.UIString("Provisional headers are shown");
var cautionFragment = createDocumentFragment();
cautionFragment.createChild("label", "", "dt-icon-label").type = "warning-icon";
cautionFragment.createChild("div", "caution").textContent = cautionText;
var cautionTreeElement = new TreeElement(cautionFragment);
cautionTreeElement.selectable = false;
headersTreeElement.appendChild(cautionTreeElement);
}
headersTreeElement.hidden = !length && !provisionalHeaders;
for (var i = 0; i < length; ++i) {
var headerTreeElement = new TreeElement(this._formatHeader(headers[i].name, headers[i].value));
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}
},
/**
* @param {string} title
* @param {number} count
* @param {string} headersText
* @param {!TreeElement} headersTreeElement
*/
_refreshHeadersText: function(title, count, headersText, headersTreeElement)
{
this._populateTreeElementWithSourceText(headersTreeElement, headersText);
this._refreshHeadersTitle(title, headersTreeElement, count);
},
_refreshRemoteAddress: function()
{
var remoteAddress = this._request.remoteAddress();
var treeElement = this._remoteAddressItem;
treeElement.hidden = !remoteAddress;
if (remoteAddress)
treeElement.title = this._formatHeader(WebInspector.UIString("Remote Address"), remoteAddress);
},
/**
* @param {!Event} event
*/
_toggleRequestHeadersText: function(event)
{
this._showRequestHeadersText = !this._showRequestHeadersText;
this._refreshRequestHeaders();
event.consume();
},
/**
* @param {!Event} event
*/
_toggleResponseHeadersText: function(event)
{
this._showResponseHeadersText = !this._showResponseHeadersText;
this._refreshResponseHeaders();
event.consume();
},
/**
* @param {string} title
* @return {!Element}
*/
_createToggleButton: function(title)
{
var button = createElementWithClass("span", "header-toggle");
button.textContent = title;
return button;
},
/**
* @param {boolean} isHeadersTextShown
* @return {!Element}
*/
_createHeadersToggleButton: function(isHeadersTextShown)
{
var toggleTitle = isHeadersTextShown ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
return this._createToggleButton(toggleTitle);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!TreeOutline} root
* @param {string} name
* @param {string=} title
*/
WebInspector.RequestHeadersView.Category = function(root, name, title)
{
TreeElement.call(this, title || "", true);
this.selectable = false;
this.toggleOnClick = true;
this.hidden = true;
this._expandedSetting = WebInspector.settings.createSetting("request-info-" + name + "-category-expanded", true);
this.expanded = this._expandedSetting.get();
root.appendChild(this);
}
WebInspector.RequestHeadersView.Category.prototype = {
/**
* @return {!TreeElement}
*/
createLeaf: function()
{
var leaf = new TreeElement();
leaf.selectable = false;
this.appendChild(leaf);
return leaf;
},
onexpand: function()
{
this._expandedSetting.set(true);
},
oncollapse: function()
{
this._expandedSetting.set(false);
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.RequestContentView}
* @param {!WebInspector.NetworkRequest} request
* @param {!WebInspector.Widget} responseView
*/
WebInspector.RequestPreviewView = function(request, responseView)
{
WebInspector.RequestContentView.call(this, request);
this._responseView = responseView;
}
WebInspector.RequestPreviewView.prototype = {
contentLoaded: function()
{
if (!this.request.content && !this.request.contentError()) {
if (!this._emptyWidget) {
this._emptyWidget = this._createEmptyWidget();
this._emptyWidget.show(this.element);
this.innerView = this._emptyWidget;
}
} else {
if (this._emptyWidget) {
this._emptyWidget.detach();
delete this._emptyWidget;
}
if (!this._previewView) {
this._previewView = this._createPreviewView();
this._previewView.show(this.element);
if (this._previewView instanceof WebInspector.VBoxWithToolbarItems) {
var toolbar = new WebInspector.Toolbar("network-item-preview-toolbar", this.element);
for (var item of /** @type {!WebInspector.VBoxWithToolbarItems} */ (this._previewView).toolbarItems())
toolbar.appendToolbarItem(item);
}
}
this.innerView = this._previewView;
}
},
_createEmptyWidget: function()
{
return this._createMessageView(WebInspector.UIString("This request has no preview available."));
},
/**
* @param {string} message
* @return {!WebInspector.EmptyWidget}
*/
_createMessageView: function(message)
{
return new WebInspector.EmptyWidget(message);
},
/**
* @return {string}
*/
_requestContent: function()
{
var content = this.request.content;
return this.request.contentEncoded ? window.atob(content || "") : (content || "");
},
/**
* @return {?WebInspector.JSONView}
*/
_jsonView: function()
{
var parsedJSON = WebInspector.JSONView.parseJSON(this._requestContent());
return parsedJSON && new WebInspector.JSONView(parsedJSON);
},
/**
* @return {?WebInspector.XMLView}
*/
_xmlView: function()
{
var content = this._requestContent();
var parsedXML = WebInspector.XMLView.parseXML(content, this.request.mimeType);
return parsedXML ? new WebInspector.XMLView(parsedXML) : null;
},
/**
* @return {?WebInspector.RequestHTMLView}
*/
_htmlErrorPreview: function()
{
var whitelist = ["text/html", "text/plain", "application/xhtml+xml"];
if (whitelist.indexOf(this.request.mimeType) === -1)
return null;
var dataURL = this.request.asDataURL();
if (dataURL === null)
return null;
return new WebInspector.RequestHTMLView(this.request, dataURL);
},
_createPreviewView: function()
{
if (this.request.contentError())
return this._createMessageView(WebInspector.UIString("Failed to load response data"));
var mimeType = this.request.mimeType || "";
if (mimeType.endsWith("json") || mimeType.endsWith("javascript")) {
var jsonView = this._jsonView();
if (jsonView)
return jsonView;
}
if (this.request.hasErrorStatusCode()) {
var htmlErrorPreview = this._htmlErrorPreview();
if (htmlErrorPreview)
return htmlErrorPreview;
}
var xmlView = this._xmlView();
if (xmlView)
return xmlView;
if (this.request.resourceType() === WebInspector.resourceTypes.XHR) {
var jsonView = this._jsonView();
if (jsonView)
return jsonView;
var htmlErrorPreview = this._htmlErrorPreview();
if (htmlErrorPreview)
return htmlErrorPreview;
}
if (this._responseView.sourceView)
return this._responseView.sourceView;
if (this.request.resourceType() === WebInspector.resourceTypes.Other)
return this._createEmptyWidget();
return WebInspector.RequestView.nonSourceViewForRequest(this.request);
},
__proto__: WebInspector.RequestContentView.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | 2 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.RequestContentView}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestResponseView = function(request)
{
WebInspector.RequestContentView.call(this, request);
}
WebInspector.RequestResponseView.prototype = {
get sourceView()
{
if (this._sourceView || !WebInspector.RequestView.hasTextContent(this.request))
return this._sourceView;
var contentProvider = new WebInspector.RequestResponseView.ContentProvider(this.request);
var sourceFrame = new WebInspector.ResourceSourceFrame(contentProvider);
sourceFrame.setHighlighterType(this.request.resourceType().canonicalMimeType() || this.request.mimeType);
this._sourceView = sourceFrame;
return this._sourceView;
},
/**
* @param {string} message
* @return {!WebInspector.EmptyWidget}
*/
_createMessageView: function(message)
{
return new WebInspector.EmptyWidget(message);
},
contentLoaded: function()
{
if ((!this.request.content || !this.sourceView) && !this.request.contentError()) {
if (!this._emptyWidget) {
this._emptyWidget = this._createMessageView(WebInspector.UIString("This request has no response data available."));
this._emptyWidget.show(this.element);
this.innerView = this._emptyWidget;
}
} else {
if (this._emptyWidget) {
this._emptyWidget.detach();
delete this._emptyWidget;
}
if (this.request.content && this.sourceView) {
this.sourceView.show(this.element);
this.innerView = this.sourceView;
} else {
if (!this._errorView)
this._errorView = this._createMessageView(WebInspector.UIString("Failed to load response data"));
this._errorView.show(this.element);
this.innerView = this._errorView;
}
}
},
__proto__: WebInspector.RequestContentView.prototype
}
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestResponseView.ContentProvider = function(request) {
this._request = request;
}
WebInspector.RequestResponseView.ContentProvider.prototype = {
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._request.contentURL();
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._request.resourceType();
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
/**
* @param {?string} content
* @this {WebInspector.RequestResponseView.ContentProvider}
*/
function decodeContent(content)
{
return this._request.contentEncoded ? window.atob(content || "") : content;
}
return this._request.requestContent()
.then(decodeContent.bind(this));
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
this._request.searchInContent(query, caseSensitive, isRegex, callback);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | 2 1 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
* @param {!WebInspector.NetworkTimeCalculator} calculator
*/
WebInspector.RequestTimingView = function(request, calculator)
{
WebInspector.VBox.call(this);
this.element.classList.add("resource-timing-view");
this._request = request;
this._calculator = calculator;
}
WebInspector.RequestTimingView.prototype = {
wasShown: function()
{
this._request.addEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this);
this._calculator.addEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this);
this._refresh();
},
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this);
this._calculator.removeEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this);
},
_refresh: function()
{
if (this._tableElement)
this._tableElement.remove();
this._tableElement = WebInspector.RequestTimingView.createTimingTable(this._request, this._calculator.minimumBoundary());
this.element.appendChild(this._tableElement);
},
__proto__: WebInspector.VBox.prototype
}
/** @enum {string} */
WebInspector.RequestTimeRangeNames = {
Queueing: "queueing",
Blocking: "blocking",
Connecting: "connecting",
DNS: "dns",
Proxy: "proxy",
Receiving: "receiving",
Sending: "sending",
ServiceWorker: "serviceworker",
ServiceWorkerPreparation: "serviceworker-preparation",
SSL: "ssl",
Total: "total",
Waiting: "waiting"
};
WebInspector.RequestTimingView.ConnectionSetupRangeNames = [
WebInspector.RequestTimeRangeNames.Queueing,
WebInspector.RequestTimeRangeNames.Blocking,
WebInspector.RequestTimeRangeNames.Connecting,
WebInspector.RequestTimeRangeNames.DNS,
WebInspector.RequestTimeRangeNames.Proxy,
WebInspector.RequestTimeRangeNames.SSL
].keySet();
/** @typedef {{name: !WebInspector.RequestTimeRangeNames, start: number, end: number}} */
WebInspector.RequestTimeRange;
/**
* @param {!WebInspector.RequestTimeRangeNames} name
* @return {string}
*/
WebInspector.RequestTimingView._timeRangeTitle = function(name)
{
switch (name) {
case WebInspector.RequestTimeRangeNames.Queueing: return WebInspector.UIString("Queueing");
case WebInspector.RequestTimeRangeNames.Blocking: return WebInspector.UIString("Stalled");
case WebInspector.RequestTimeRangeNames.Connecting: return WebInspector.UIString("Initial connection");
case WebInspector.RequestTimeRangeNames.DNS: return WebInspector.UIString("DNS Lookup");
case WebInspector.RequestTimeRangeNames.Proxy: return WebInspector.UIString("Proxy negotiation");
case WebInspector.RequestTimeRangeNames.Receiving: return WebInspector.UIString("Content Download");
case WebInspector.RequestTimeRangeNames.Sending: return WebInspector.UIString("Request sent");
case WebInspector.RequestTimeRangeNames.ServiceWorker: return WebInspector.UIString("Request to ServiceWorker");
case WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation: return WebInspector.UIString("ServiceWorker Preparation");
case WebInspector.RequestTimeRangeNames.SSL: return WebInspector.UIString("SSL");
case WebInspector.RequestTimeRangeNames.Total: return WebInspector.UIString("Total");
case WebInspector.RequestTimeRangeNames.Waiting: return WebInspector.UIString("Waiting (TTFB)");
default: return WebInspector.UIString(name);
}
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!Array.<!WebInspector.RequestTimeRange>}
*/
WebInspector.RequestTimingView.calculateRequestTimeRanges = function(request)
{
var result = [];
/**
* @param {!WebInspector.RequestTimeRangeNames} name
* @param {number} start
* @param {number} end
*/
function addRange(name, start, end)
{
if (start < Number.MAX_VALUE && start <= end)
result.push({name: name, start: start, end: end});
}
/**
* @param {!Array.<number>} numbers
* @return {number|undefined}
*/
function firstPositive(numbers)
{
for (var i = 0; i < numbers.length; ++i) {
if (numbers[i] > 0)
return numbers[i];
}
return undefined;
}
/**
* @param {!WebInspector.RequestTimeRangeNames} name
* @param {number} start
* @param {number} end
*/
function addOffsetRange(name, start, end)
{
if (start >= 0 && end >= 0)
addRange(name, startTime + (start / 1000), startTime + (end / 1000));
}
var timing = request.timing;
if (!timing) {
var start = request.issueTime() !== -1 ? request.issueTime() : request.startTime !== -1 ? request.startTime : 0;
var middle = (request.responseReceivedTime === -1) ? Number.MAX_VALUE : request.responseReceivedTime;
var end = (request.endTime === -1) ? Number.MAX_VALUE : request.endTime;
addRange(WebInspector.RequestTimeRangeNames.Total, start, end);
addRange(WebInspector.RequestTimeRangeNames.Blocking, start, middle);
addRange(WebInspector.RequestTimeRangeNames.Receiving, middle, end);
return result;
}
var issueTime = request.issueTime();
var startTime = timing.requestTime;
var endTime = firstPositive([request.endTime, request.responseReceivedTime]) || startTime;
addRange(WebInspector.RequestTimeRangeNames.Total, issueTime < startTime ? issueTime : startTime, endTime);
if (issueTime < startTime)
addRange(WebInspector.RequestTimeRangeNames.Queueing, issueTime, startTime);
if (request.fetchedViaServiceWorker) {
addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking, 0, timing.workerStart);
addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation, timing.workerStart, timing.workerReady);
addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorker, timing.workerReady, timing.sendEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting, timing.sendEnd, timing.receiveHeadersEnd);
} else {
var blocking = firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart]) || 0;
addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking, 0, blocking);
addOffsetRange(WebInspector.RequestTimeRangeNames.Proxy, timing.proxyStart, timing.proxyEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.DNS, timing.dnsStart, timing.dnsEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.Connecting, timing.connectStart, timing.connectEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.SSL, timing.sslStart, timing.sslEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.Sending, timing.sendStart, timing.sendEnd);
addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting, timing.sendEnd, timing.receiveHeadersEnd);
}
if (request.endTime !== -1)
addRange(WebInspector.RequestTimeRangeNames.Receiving, request.responseReceivedTime, endTime);
return result;
}
/**
* @param {!WebInspector.NetworkRequest} request
* @param {number} navigationStart
* @return {!Element}
*/
WebInspector.RequestTimingView.createTimingTable = function(request, navigationStart)
{
var tableElement = createElementWithClass("table", "network-timing-table");
var colgroup = tableElement.createChild("colgroup");
colgroup.createChild("col", "labels");
colgroup.createChild("col", "bars");
colgroup.createChild("col", "duration");
var timeRanges = WebInspector.RequestTimingView.calculateRequestTimeRanges(request);
var startTime = timeRanges[0].start;
var endTime = timeRanges[0].end;
var scale = 100 / (endTime - startTime);
var connectionHeader;
var dataHeader;
var totalDuration = 0;
for (var i = 0; i < timeRanges.length; ++i) {
var range = timeRanges[i];
var rangeName = range.name;
if (rangeName === WebInspector.RequestTimeRangeNames.Total) {
totalDuration = range.end - range.start;
continue;
}
if (WebInspector.RequestTimingView.ConnectionSetupRangeNames[rangeName]) {
if (!connectionHeader) {
connectionHeader = tableElement.createChild("tr", "network-timing-table-header");
connectionHeader.createChild("td").createTextChild(WebInspector.UIString("Connection Setup"));
connectionHeader.createChild("td").createTextChild("");
connectionHeader.createChild("td").createTextChild(WebInspector.UIString("TIME"));
}
} else {
if (!dataHeader) {
dataHeader = tableElement.createChild("tr", "network-timing-table-header");
dataHeader.createChild("td").createTextChild(WebInspector.UIString("Request/Response"));
dataHeader.createChild("td").createTextChild("");
dataHeader.createChild("td").createTextChild(WebInspector.UIString("TIME"));
}
}
var left = (scale * (range.start - startTime));
var right = (scale * (endTime - range.end));
var duration = range.end - range.start;
var tr = tableElement.createChild("tr");
tr.createChild("td").createTextChild(WebInspector.RequestTimingView._timeRangeTitle(rangeName));
var row = tr.createChild("td").createChild("div", "network-timing-row");
var bar = row.createChild("span", "network-timing-bar " + rangeName);
bar.style.left = left + "%";
bar.style.right = right + "%";
bar.textContent = "\u200B"; // Important for 0-time items to have 0 width.
var label = tr.createChild("td").createChild("div", "network-timing-bar-title");
label.textContent = Number.secondsToString(duration, true);
}
if (!request.finished) {
var cell = tableElement.createChild("tr").createChild("td", "caution");
cell.colSpan = 3;
cell.createTextChild(WebInspector.UIString("CAUTION: request is not finished yet!"));
}
var footer = tableElement.createChild("tr", "network-timing-footer");
var note = footer.createChild("td");
note.colSpan = 2;
note.appendChild(WebInspector.linkifyDocumentationURLAsNode("profile/network-performance/resource-loading#view-network-timing-details-for-a-specific-resource", WebInspector.UIString("Explanation")));
footer.createChild("td").createTextChild(Number.secondsToString(totalDuration, true));
return tableElement;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestView = function(request)
{
WebInspector.VBox.call(this);
this.element.classList.add("request-view");
this.request = request;
}
WebInspector.RequestView.prototype = {
__proto__: WebInspector.VBox.prototype
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.RequestView.hasTextContent = function(request)
{
if (request.resourceType().isTextType())
return true;
if (request.resourceType() === WebInspector.resourceTypes.Other || request.hasErrorStatusCode())
return !!request.content && !request.contentEncoded;
return false;
}
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!WebInspector.Widget}
*/
WebInspector.RequestView.nonSourceViewForRequest = function(request)
{
switch (request.resourceType()) {
case WebInspector.resourceTypes.Image:
return new WebInspector.ImageView(request.mimeType, request);
case WebInspector.resourceTypes.Font:
return new WebInspector.FontView(request.mimeType, request);
default:
return new WebInspector.RequestView(request);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | 2 | /*
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.ResourceWebSocketFrameView = function(request)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("network/webSocketFrameView.css");
this.element.classList.add("websocket-frame-view");
this._request = request;
this._splitWidget = new WebInspector.SplitWidget(false, true, "resourceWebSocketFrameSplitViewState");
this._splitWidget.show(this.element);
var columns = [
{id: "data", title: WebInspector.UIString("Data"), sortable: false, weight: 88},
{id: "length", title: WebInspector.UIString("Length"), sortable: false, align: WebInspector.DataGrid.Align.Right, weight: 5},
{id: "time", title: WebInspector.UIString("Time"), sortable: true, weight: 7}
];
this._dataGrid = new WebInspector.SortableDataGrid(columns, undefined, undefined, undefined, this._onContextMenu.bind(this));
this._dataGrid.setStickToBottom(true);
this._dataGrid.setCellClass("websocket-frame-view-td");
this._timeComparator = /** @type {!WebInspector.SortableDataGrid.NodeComparator} */ (WebInspector.ResourceWebSocketFrameNodeTimeComparator);
this._dataGrid.sortNodes(this._timeComparator, false);
this._dataGrid.markColumnAsSortedBy("time", WebInspector.DataGrid.Order.Ascending);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortItems, this);
this._dataGrid.setName("ResourceWebSocketFrameView");
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._onFrameSelected, this);
this._splitWidget.setMainWidget(this._dataGrid.asWidget());
var view = new WebInspector.EmptyWidget("Select frame to browse its content.");
this._splitWidget.setSidebarWidget(view);
}
/** @enum {number} */
WebInspector.ResourceWebSocketFrameView.OpCodes = {
ContinuationFrame: 0,
TextFrame: 1,
BinaryFrame: 2,
ConnectionCloseFrame: 8,
PingFrame: 9,
PongFrame: 10
};
/** @type {!Array.<string> } */
WebInspector.ResourceWebSocketFrameView.opCodeDescriptions = (function()
{
var opCodes = WebInspector.ResourceWebSocketFrameView.OpCodes;
var map = [];
map[opCodes.ContinuationFrame] = "Continuation Frame";
map[opCodes.TextFrame] = "Text Frame";
map[opCodes.BinaryFrame] = "Binary Frame";
map[opCodes.ContinuationFrame] = "Connection Close Frame";
map[opCodes.PingFrame] = "Ping Frame";
map[opCodes.PongFrame] = "Pong Frame";
return map;
})();
/**
* @param {number} opCode
* @param {boolean} mask
* @return {string}
*/
WebInspector.ResourceWebSocketFrameView.opCodeDescription = function(opCode, mask)
{
var rawDescription = WebInspector.ResourceWebSocketFrameView.opCodeDescriptions[opCode] || "";
var localizedDescription = WebInspector.UIString(rawDescription);
return WebInspector.UIString("%s (Opcode %d%s)", localizedDescription, opCode, (mask ? ", mask" : ""));
}
WebInspector.ResourceWebSocketFrameView.prototype = {
wasShown: function()
{
this.refresh();
this._request.addEventListener(WebInspector.NetworkRequest.Events.WebsocketFrameAdded, this._frameAdded, this);
},
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.WebsocketFrameAdded, this._frameAdded, this);
},
/**
* @param {!WebInspector.Event} event
*/
_frameAdded: function(event)
{
var frame = /** @type {!WebInspector.NetworkRequest.WebSocketFrame} */ (event.data);
this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(frame));
},
/**
* @param {!WebInspector.Event} event
*/
_onFrameSelected: function(event)
{
var selectedNode = /** @type {!WebInspector.ResourceWebSocketFrameNode} */ (event.target.selectedNode);
var contentProvider = selectedNode.contentProvider();
contentProvider.requestContent().then(content => {
var parsedJSON = content ? WebInspector.JSONView.parseJSON(content) : null;
var view = parsedJSON ? new WebInspector.JSONView(parsedJSON) : new WebInspector.ResourceSourceFrame(contentProvider);
this._splitWidget.setSidebarWidget(view);
});
},
refresh: function()
{
this._dataGrid.rootNode().removeChildren();
var frames = this._request.frames();
for (var i = 0; i < frames.length; ++i)
this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(frames[i]));
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!WebInspector.DataGridNode} node
*/
_onContextMenu: function(contextMenu, node)
{
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^message"), this._copyMessage.bind(this, node.data));
},
/**
* @param {!Object} row
*/
_copyMessage: function(row)
{
InspectorFrontendHost.copyText(row.data);
},
_sortItems: function()
{
this._dataGrid.sortNodes(this._timeComparator, !this._dataGrid.isSortOrderAscending());
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.SortableDataGridNode}
* @param {!WebInspector.NetworkRequest.WebSocketFrame} frame
*/
WebInspector.ResourceWebSocketFrameNode = function(frame)
{
this._frame = frame;
this._dataText = frame.text;
var length = frame.text.length;
var time = new Date(frame.time * 1000);
var timeText = ("0" + time.getHours()).substr(-2) + ":" + ("0" + time.getMinutes()).substr(-2)+ ":" + ("0" + time.getSeconds()).substr(-2) + "." + ("00" + time.getMilliseconds()).substr(-3);
var timeNode = createElement("div");
timeNode.createTextChild(timeText);
timeNode.title = time.toLocaleString();
this._isTextFrame = frame.opCode === WebInspector.ResourceWebSocketFrameView.OpCodes.TextFrame;
if (!this._isTextFrame)
this._dataText = WebInspector.ResourceWebSocketFrameView.opCodeDescription(frame.opCode, frame.mask);
WebInspector.SortableDataGridNode.call(this, {data: this._dataText, length: length, time: timeNode});
}
WebInspector.ResourceWebSocketFrameNode.prototype = {
/**
* @override
*/
createCells: function()
{
var element = this._element;
element.classList.toggle("websocket-frame-view-row-error", this._frame.type === WebInspector.NetworkRequest.WebSocketFrameType.Error);
element.classList.toggle("websocket-frame-view-row-outcoming", this._frame.type === WebInspector.NetworkRequest.WebSocketFrameType.Send);
element.classList.toggle("websocket-frame-view-row-opcode", !this._isTextFrame);
WebInspector.SortableDataGridNode.prototype.createCells.call(this);
},
/**
* @override
* @return {number}
*/
nodeSelfHeight: function()
{
return 17;
},
/**
* @return {!WebInspector.ContentProvider}
*/
contentProvider: function()
{
return new WebInspector.StaticContentProvider(WebInspector.resourceTypes.WebSocket, this._dataText);
},
__proto__: WebInspector.SortableDataGridNode.prototype
}
/**
* @param {!WebInspector.ResourceWebSocketFrameNode} a
* @param {!WebInspector.ResourceWebSocketFrameNode} b
* @return {number}
*/
WebInspector.ResourceWebSocketFrameNodeTimeComparator = function(a, b)
{
return a._frame.time - b._frame.time;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {!Document} parsedXML
*/
WebInspector.XMLView = function(parsedXML)
{
WebInspector.Widget.call(this, true);
this.registerRequiredCSS("network/xmlView.css");
this.contentElement.classList.add("shadow-xml-view", "source-code");
var treeOutline = new TreeOutline();
this.contentElement.appendChild(treeOutline.element);
WebInspector.XMLView.Node.populate(treeOutline, parsedXML);
}
/**
* @param {string} text
* @param {string} mimeType
* @return {?Document}
*/
WebInspector.XMLView.parseXML = function(text, mimeType)
{
var parsedXML;
try {
parsedXML = (new DOMParser()).parseFromString(text, mimeType);
} catch (e) {
return null;
}
if (parsedXML.body)
return null;
return parsedXML;
}
WebInspector.XMLView.prototype = {
__proto__: WebInspector.Widget.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!Node} node
* @param {boolean} closeTag
*/
WebInspector.XMLView.Node = function(node, closeTag)
{
TreeElement.call(this, "", !closeTag && !!node.childElementCount);
this._node = node;
this._closeTag = closeTag;
this.selectable = false;
this._updateTitle();
}
/**
* @param {!TreeOutline|!TreeElement} root
* @param {!Node} xmlNode
*/
WebInspector.XMLView.Node.populate = function(root, xmlNode)
{
var node = xmlNode.firstChild;
while (node) {
var currentNode = node;
node = node.nextSibling;
var nodeType = currentNode.nodeType;
// ignore empty TEXT
if (nodeType === 3 && currentNode.nodeValue.match(/\s+/))
continue;
// ignore ATTRIBUTE, ENTITY_REFERENCE, ENTITY, DOCUMENT, DOCUMENT_TYPE, DOCUMENT_FRAGMENT, NOTATION
if ((nodeType !== 1) && (nodeType !== 3) && (nodeType !== 4) && (nodeType !== 7) && (nodeType !== 8))
continue;
root.appendChild(new WebInspector.XMLView.Node(currentNode, false));
}
}
WebInspector.XMLView.Node.prototype = {
_updateTitle: function()
{
var node = this._node;
switch (node.nodeType) {
case 1: // ELEMENT
var tag = node.tagName;
if (this._closeTag) {
this._setTitle(["</" + tag + ">", "shadow-xml-view-tag"]);
return;
}
var titleItems = ["<" + tag, "shadow-xml-view-tag"];
var attributes = node.attributes;
for (var i = 0; i < attributes.length; ++i) {
var attributeNode = attributes.item(i);
titleItems.push(
"\u00a0", "shadow-xml-view-tag",
attributeNode.name, "shadow-xml-view-attribute-name",
"=\"", "shadow-xml-view-tag",
attributeNode.value, "shadow-xml-view-attribute-value",
"\"", "shadow-xml-view-tag")
}
if (!this.expanded) {
if (node.childElementCount) {
titleItems.push(
">", "shadow-xml-view-tag",
"\u2026", "shadow-xml-view-comment",
"</" + tag, "shadow-xml-view-tag");
} else if (this._node.textContent) {
titleItems.push(
">", "shadow-xml-view-tag",
node.textContent, "shadow-xml-view-text",
"</" + tag, "shadow-xml-view-tag");
} else {
titleItems.push(" /", "shadow-xml-view-tag");
}
}
titleItems.push(">", "shadow-xml-view-tag");
this._setTitle(titleItems);
return;
case 3: // TEXT
this._setTitle([node.nodeValue, "shadow-xml-view-text"]);
return;
case 4: // CDATA
this._setTitle([
"<![CDATA[", "shadow-xml-view-cdata",
node.nodeValue, "shadow-xml-view-text",
"]]>", "shadow-xml-view-cdata"]);
return;
case 7: // PROCESSING_INSTRUCTION
this._setTitle(["<?" + node.nodeName + " " + node.nodeValue + "?>", "shadow-xml-view-processing-instruction"]);
return;
case 8: // COMMENT
this._setTitle(["<!--" + node.nodeValue + "-->", "shadow-xml-view-comment"]);
return;
}
},
/**
* @param {!Array.<string>} items
*/
_setTitle: function(items)
{
var titleFragment = createDocumentFragment();
for (var i = 0; i < items.length; i += 2)
titleFragment.createChild("span", items[i + 1]).textContent = items[i];
this.title = titleFragment;
},
onattach: function()
{
this.listItemElement.classList.toggle("shadow-xml-view-close-tag", this._closeTag);
},
onexpand: function()
{
this._updateTitle();
},
oncollapse: function()
{
this._updateTitle();
},
onpopulate: function()
{
WebInspector.XMLView.Node.populate(this, this._node);
this.appendChild(new WebInspector.XMLView.Node(this._node, true));
},
__proto__: TreeElement.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| DOMExtension.js | 4.64% | (18 / 388) | 0% | (0 / 235) | 0% | (0 / 70) | 4.65% | (18 / 387) | |
| utilities.js | 18.45% | (105 / 569) | 0.38% | (1 / 265) | 2.7% | (3 / 111) | 18.52% | (105 / 567) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contains diff method based on Javascript Diff Algorithm By John Resig
* http://ejohn.org/files/jsdiff.js (released under the MIT license).
*/
/**
* @param {number} offset
* @param {string} stopCharacters
* @param {!Node} stayWithinNode
* @param {string=} direction
* @return {!Range}
*/
Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
{
var startNode;
var startOffset = 0;
var endNode;
var endOffset = 0;
if (!stayWithinNode)
stayWithinNode = this;
if (!direction || direction === "backward" || direction === "both") {
var node = this;
while (node) {
if (node === stayWithinNode) {
if (!startNode)
startNode = stayWithinNode;
break;
}
if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
for (var i = start; i >= 0; --i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
startNode = node;
startOffset = i + 1;
break;
}
}
}
if (startNode)
break;
node = node.traversePreviousNode(stayWithinNode);
}
if (!startNode) {
startNode = stayWithinNode;
startOffset = 0;
}
} else {
startNode = this;
startOffset = offset;
}
if (!direction || direction === "forward" || direction === "both") {
node = this;
while (node) {
if (node === stayWithinNode) {
if (!endNode)
endNode = stayWithinNode;
break;
}
if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? offset : 0);
for (var i = start; i < node.nodeValue.length; ++i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
endNode = node;
endOffset = i;
break;
}
}
}
if (endNode)
break;
node = node.traverseNextNode(stayWithinNode);
}
if (!endNode) {
endNode = stayWithinNode;
endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
}
} else {
endNode = this;
endOffset = offset;
}
var result = this.ownerDocument.createRange();
result.setStart(startNode, startOffset);
result.setEnd(endNode, endOffset);
return result;
}
/**
* @param {!Node=} stayWithin
* @return {?Node}
*/
Node.prototype.traverseNextTextNode = function(stayWithin)
{
var node = this.traverseNextNode(stayWithin);
if (!node)
return null;
var nonTextTags = { "STYLE": 1, "SCRIPT": 1 };
while (node && (node.nodeType !== Node.TEXT_NODE || nonTextTags[node.parentElement.nodeName]))
node = node.traverseNextNode(stayWithin);
return node;
}
/**
* @param {number|undefined} x
* @param {number|undefined} y
* @param {!Element=} relativeTo
*/
Element.prototype.positionAt = function(x, y, relativeTo)
{
var shift = {x: 0, y: 0};
if (relativeTo)
shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
if (typeof x === "number")
this.style.setProperty("left", (shift.x + x) + "px");
else
this.style.removeProperty("left");
if (typeof y === "number")
this.style.setProperty("top", (shift.y + y) + "px");
else
this.style.removeProperty("top");
if (typeof x === "number" || typeof y === "number")
this.style.setProperty("position", "absolute");
else
this.style.removeProperty("position");
}
/**
* @return {boolean}
*/
Element.prototype.isScrolledToBottom = function()
{
// This code works only for 0-width border.
// The scrollTop, clientHeight and scrollHeight are computed in double values internally.
// However, they are exposed to javascript differently, each being either rounded (via
// round, ceil or floor functions) or left intouch.
// This adds up a total error up to 2.
return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 2;
}
/**
* @param {!Node} fromNode
* @param {!Node} toNode
*/
function removeSubsequentNodes(fromNode, toNode)
{
for (var node = fromNode; node && node !== toNode; ) {
var nodeToRemove = node;
node = node.nextSibling;
nodeToRemove.remove();
}
}
/**
* @param {!Event} event
* @return {boolean}
*/
Element.prototype.containsEventPoint = function(event)
{
var box = this.getBoundingClientRect();
return box.left < event.x && event.x < box.right &&
box.top < event.y && event.y < box.bottom;
}
/**
* @param {!Array.<string>} nameArray
* @return {?Node}
*/
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNodeOrShadowHost()) {
for (var i = 0; i < nameArray.length; ++i) {
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
}
}
return null;
}
/**
* @param {string} nodeName
* @return {?Node}
*/
Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
}
/**
* @param {string} className
* @param {!Element=} stayWithin
* @return {?Element}
*/
Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin)
{
return this.enclosingNodeOrSelfWithClassList([className], stayWithin);
}
/**
* @param {!Array.<string>} classNames
* @param {!Element=} stayWithin
* @return {?Element}
*/
Node.prototype.enclosingNodeOrSelfWithClassList = function(classNames, stayWithin)
{
for (var node = this; node && node !== stayWithin && node !== this.ownerDocument; node = node.parentNodeOrShadowHost()) {
if (node.nodeType === Node.ELEMENT_NODE) {
var containsAll = true;
for (var i = 0; i < classNames.length && containsAll; ++i) {
if (!node.classList.contains(classNames[i]))
containsAll = false;
}
if (containsAll)
return /** @type {!Element} */ (node);
}
}
return null;
}
/**
* @return {?Element}
*/
Node.prototype.parentElementOrShadowHost = function()
{
var node = this.parentNode;
if (!node)
return null;
if (node.nodeType === Node.ELEMENT_NODE)
return /** @type {!Element} */ (node);
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
return /** @type {!Element} */ (node.host);
return null;
}
/**
* @return {?Node}
*/
Node.prototype.parentNodeOrShadowHost = function()
{
return this.parentNode || this.host || null;
}
/**
* @return {?Selection}
*/
Node.prototype.getComponentSelection = function()
{
var parent = this.parentNode;
while (parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE)
parent = parent.parentNode;
return parent instanceof ShadowRoot ? parent.getSelection() : this.window().getSelection();
}
/**
* @return {boolean}
*/
Node.prototype.isComponentSelectionCollapsed = function()
{
// FIXME: crbug.com/447523, use selection.isCollapsed when it is fixed for shadow dom.
var selection = this.getComponentSelection();
return selection && selection.rangeCount ? selection.getRangeAt(0).collapsed : true;
}
/**
* @return {!Selection}
*/
Node.prototype.getDeepSelection = function()
{
var activeElement = this.ownerDocument.activeElement;
var shadowRoot = null;
while (activeElement && activeElement.shadowRoot) {
shadowRoot = activeElement.shadowRoot;
activeElement = shadowRoot.activeElement;
}
return shadowRoot ? shadowRoot.getSelection() : this.window().getSelection();
}
/**
* @return {!Window}
*/
Node.prototype.window = function()
{
return this.ownerDocument.defaultView;
}
/**
* @param {string} query
* @return {?Node}
*/
Element.prototype.query = function(query)
{
return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
Element.prototype.removeChildren = function()
{
if (this.firstChild)
this.textContent = "";
}
/**
* @return {boolean}
*/
Element.prototype.isInsertionCaretInside = function()
{
var selection = this.getComponentSelection();
// @see crbug.com/602541
var selectionRange = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
if (!selectionRange || !selection.isCollapsed)
return false;
return selectionRange.startContainer.isSelfOrDescendant(this);
}
/**
* @param {string} tagName
* @param {string=} customElementType
* @return {!Element}
* @suppressGlobalPropertiesCheck
*/
function createElement(tagName, customElementType)
{
return document.createElement(tagName, customElementType || "");
}
/**
* @param {string} type
* @param {boolean} bubbles
* @param {boolean} cancelable
* @return {!Event}
* @suppressGlobalPropertiesCheck
*/
function createEvent(type, bubbles, cancelable)
{
var event = document.createEvent("Event");
event.initEvent(type, bubbles, cancelable);
return event;
}
/**
* @param {number|string} data
* @return {!Text}
* @suppressGlobalPropertiesCheck
*/
function createTextNode(data)
{
return document.createTextNode(data);
}
/**
* @param {string} elementName
* @param {string=} className
* @param {string=} customElementType
* @return {!Element}
*/
Document.prototype.createElementWithClass = function(elementName, className, customElementType)
{
var element = this.createElement(elementName, customElementType || "");
if (className)
element.className = className;
return element;
}
/**
* @param {string} elementName
* @param {string=} className
* @param {string=} customElementType
* @return {!Element}
* @suppressGlobalPropertiesCheck
*/
function createElementWithClass(elementName, className, customElementType)
{
return document.createElementWithClass(elementName, className, customElementType);
}
/**
* @param {string} childType
* @param {string=} className
* @return {!Element}
*/
Document.prototype.createSVGElement = function(childType, className)
{
var element = this.createElementNS("http://www.w3.org/2000/svg", childType);
if (className)
element.setAttribute("class", className);
return element;
}
/**
* @param {string} childType
* @param {string=} className
* @return {!Element}
* @suppressGlobalPropertiesCheck
*/
function createSVGElement(childType, className)
{
return document.createSVGElement(childType, className);
}
/**
* @return {!DocumentFragment}
* @suppressGlobalPropertiesCheck
*/
function createDocumentFragment()
{
return document.createDocumentFragment();
}
/**
* @param {string} elementName
* @param {string=} className
* @param {string=} customElementType
* @return {!Element}
*/
Element.prototype.createChild = function(elementName, className, customElementType)
{
var element = this.ownerDocument.createElementWithClass(elementName, className, customElementType);
this.appendChild(element);
return element;
}
DocumentFragment.prototype.createChild = Element.prototype.createChild;
/**
* @param {string} text
* @return {!Text}
*/
Element.prototype.createTextChild = function(text)
{
var element = this.ownerDocument.createTextNode(text);
this.appendChild(element);
return element;
}
DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
/**
* @param {...string} var_args
*/
Element.prototype.createTextChildren = function(var_args)
{
for (var i = 0, n = arguments.length; i < n; ++i)
this.createTextChild(arguments[i]);
}
DocumentFragment.prototype.createTextChildren = Element.prototype.createTextChildren;
/**
* @return {number}
*/
Element.prototype.totalOffsetLeft = function()
{
return this.totalOffset().left;
}
/**
* @return {number}
*/
Element.prototype.totalOffsetTop = function()
{
return this.totalOffset().top;
}
/**
* @return {!{left: number, top: number}}
*/
Element.prototype.totalOffset = function()
{
var rect = this.getBoundingClientRect();
return { left: rect.left, top: rect.top };
}
/**
* @return {!{left: number, top: number}}
*/
Element.prototype.scrollOffset = function()
{
var curLeft = 0;
var curTop = 0;
for (var element = this; element; element = element.scrollParent) {
curLeft += element.scrollLeft;
curTop += element.scrollTop;
}
return { left: curLeft, top: curTop };
}
/**
* @param {string} childType
* @param {string=} className
* @return {!Element}
*/
Element.prototype.createSVGChild = function(childType, className)
{
var child = this.ownerDocument.createSVGElement(childType, className);
this.appendChild(child);
return child;
}
/**
* @constructor
* @param {number=} x
* @param {number=} y
* @param {number=} width
* @param {number=} height
*/
function AnchorBox(x, y, width, height)
{
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
}
/**
* @param {!AnchorBox} box
* @return {!AnchorBox}
*/
AnchorBox.prototype.relativeTo = function(box)
{
return new AnchorBox(
this.x - box.x, this.y - box.y, this.width, this.height);
}
/**
* @param {!Element} element
* @return {!AnchorBox}
*/
AnchorBox.prototype.relativeToElement = function(element)
{
return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView));
}
/**
* @param {?AnchorBox} anchorBox
* @return {boolean}
*/
AnchorBox.prototype.equals = function(anchorBox)
{
return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && this.width === anchorBox.width && this.height === anchorBox.height;
}
/**
* @param {!Window} targetWindow
* @return {!AnchorBox}
*/
Element.prototype.offsetRelativeToWindow = function(targetWindow)
{
var elementOffset = new AnchorBox();
var curElement = this;
var curWindow = this.ownerDocument.defaultView;
while (curWindow && curElement) {
elementOffset.x += curElement.totalOffsetLeft();
elementOffset.y += curElement.totalOffsetTop();
if (curWindow === targetWindow)
break;
curElement = curWindow.frameElement;
curWindow = curWindow.parent;
}
return elementOffset;
}
/**
* @param {!Window=} targetWindow
* @return {!AnchorBox}
*/
Element.prototype.boxInWindow = function(targetWindow)
{
targetWindow = targetWindow || this.ownerDocument.defaultView;
var anchorBox = this.offsetRelativeToWindow(window);
anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);
return anchorBox;
}
/**
* @param {string} text
*/
Element.prototype.setTextAndTitle = function(text)
{
this.textContent = text;
this.title = text;
}
KeyboardEvent.prototype.__defineGetter__("data", function()
{
// Emulate "data" attribute from DOM 3 TextInput event.
// See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data
switch (this.type) {
case "keypress":
if (!this.ctrlKey && !this.metaKey)
return String.fromCharCode(this.charCode);
else
return "";
case "keydown":
case "keyup":
if (!this.ctrlKey && !this.metaKey && !this.altKey)
return String.fromCharCode(this.which);
else
return "";
}
});
/**
* @param {boolean=} preventDefault
*/
Event.prototype.consume = function(preventDefault)
{
this.stopImmediatePropagation();
if (preventDefault)
this.preventDefault();
this.handled = true;
}
/**
* @param {number=} start
* @param {number=} end
* @return {!Text}
*/
Text.prototype.select = function(start, end)
{
start = start || 0;
end = end || this.textContent.length;
if (start < 0)
start = end + start;
var selection = this.getComponentSelection();
selection.removeAllRanges();
var range = this.ownerDocument.createRange();
range.setStart(this, start);
range.setEnd(this, end);
selection.addRange(range);
return this;
}
/**
* @return {?number}
*/
Element.prototype.selectionLeftOffset = function()
{
// Calculate selection offset relative to the current element.
var selection = this.getComponentSelection();
if (!selection.containsNode(this, true))
return null;
var leftOffset = selection.anchorOffset;
var node = selection.anchorNode;
while (node !== this) {
while (node.previousSibling) {
node = node.previousSibling;
leftOffset += node.textContent.length;
}
node = node.parentNodeOrShadowHost();
}
return leftOffset;
}
/**
* @this {!HTMLImageElement} element
* @return {!Promise<!HTMLImageElement>}
*/
HTMLImageElement.prototype.completePromise = function()
{
var element = this;
if (element.complete)
return Promise.resolve(element);
return new Promise(promiseBody);
/**
* @param {function(!HTMLImageElement)} resolve
*/
function promiseBody(resolve)
{
element.addEventListener("load", oncomplete);
element.addEventListener("error", oncomplete);
function oncomplete()
{
resolve(element);
}
}
}
/**
* @param {...!Node} var_args
*/
Node.prototype.appendChildren = function(var_args)
{
for (var i = 0, n = arguments.length; i < n; ++i)
this.appendChild(arguments[i]);
}
/**
* @return {string}
*/
Node.prototype.deepTextContent = function()
{
return this.childTextNodes().map(function (node) { return node.textContent; }).join("");
}
/**
* @return {!Array.<!Node>}
*/
Node.prototype.childTextNodes = function()
{
var node = this.traverseNextTextNode(this);
var result = [];
var nonTextTags = { "STYLE": 1, "SCRIPT": 1 };
while (node) {
if (!nonTextTags[node.parentElement.nodeName])
result.push(node);
node = node.traverseNextTextNode(this);
}
return result;
}
/**
* @param {?Node} node
* @return {boolean}
*/
Node.prototype.isAncestor = function(node)
{
if (!node)
return false;
var currentNode = node.parentNodeOrShadowHost();
while (currentNode) {
if (this === currentNode)
return true;
currentNode = currentNode.parentNodeOrShadowHost();
}
return false;
}
/**
* @param {?Node} descendant
* @return {boolean}
*/
Node.prototype.isDescendant = function(descendant)
{
return !!descendant && descendant.isAncestor(this);
}
/**
* @param {?Node} node
* @return {boolean}
*/
Node.prototype.isSelfOrAncestor = function(node)
{
return !!node && (node === this || this.isAncestor(node));
}
/**
* @param {?Node} node
* @return {boolean}
*/
Node.prototype.isSelfOrDescendant = function(node)
{
return !!node && (node === this || this.isDescendant(node));
}
/**
* @param {!Node=} stayWithin
* @return {?Node}
*/
Node.prototype.traverseNextNode = function(stayWithin)
{
if (this.shadowRoot)
return this.shadowRoot;
var distributedNodes = this.getDistributedNodes ? this.getDistributedNodes() : [];
if (distributedNodes.length)
return distributedNodes[0];
if (this.firstChild)
return this.firstChild;
var node = this;
while (node) {
if (stayWithin && node === stayWithin)
return null;
var sibling = nextSibling(node);
if (sibling)
return sibling;
node = insertionPoint(node) || node.parentNodeOrShadowHost();
}
/**
* @param {!Node} node
* @return {?Node}
*/
function nextSibling(node)
{
var parent = insertionPoint(node);
if (!parent)
return node.nextSibling;
var distributedNodes = parent.getDistributedNodes ? parent.getDistributedNodes() : [];
var position = Array.prototype.indexOf.call(distributedNodes, node);
if (position + 1 < distributedNodes.length)
return distributedNodes[position + 1];
return null;
}
/**
* @param {!Node} node
* @return {?Node}
*/
function insertionPoint(node)
{
var insertionPoints = node.getDestinationInsertionPoints ? node.getDestinationInsertionPoints() : [];
return insertionPoints.length > 0 ? insertionPoints[insertionPoints.length - 1] : null;
}
return null;
}
/**
* @param {!Node=} stayWithin
* @return {?Node}
*/
Node.prototype.traversePreviousNode = function(stayWithin)
{
if (stayWithin && this === stayWithin)
return null;
var node = this.previousSibling;
while (node && node.lastChild)
node = node.lastChild;
if (node)
return node;
return this.parentNodeOrShadowHost();
}
/**
* @param {*} text
* @param {string=} placeholder
* @return {boolean} true if was truncated
*/
Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder)
{
// Huge texts in the UI reduce rendering performance drastically.
// Moreover, Blink/WebKit uses <unsigned short> internally for storing text content
// length, so texts longer than 65535 are inherently displayed incorrectly.
const maxTextContentLength = 10000;
if (typeof text === "string" && text.length > maxTextContentLength) {
this.textContent = typeof placeholder === "string" ? placeholder : text.trimMiddle(maxTextContentLength);
return true;
}
this.textContent = text;
return false;
}
/**
* @return {?Node}
*/
Event.prototype.deepElementFromPoint = function()
{
// 1. climb to the component root.
var node = this.target;
while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeType !== Node.DOCUMENT_NODE)
node = node.parentNode;
if (!node)
return null;
// 2. Find deepest node by coordinates.
node = node.elementFromPoint(this.pageX, this.pageY);
while (node && node.shadowRoot)
node = node.shadowRoot.elementFromPoint(this.pageX, this.pageY);
return node;
}
/**
* @return {?Element}
*/
Event.prototype.deepActiveElement = function()
{
var activeElement = this.target && this.target.ownerDocument ? this.target.ownerDocument.activeElement : null;
while (activeElement && activeElement.shadowRoot)
activeElement = activeElement.shadowRoot.activeElement;
return activeElement;
}
/**
* @param {number} x
* @param {number} y
* @return {?Node}
*/
Document.prototype.deepElementFromPoint = function(x, y)
{
var node = this.elementFromPoint(x, y);
while (node && node.shadowRoot)
node = node.shadowRoot.elementFromPoint(x, y);
return node;
}
/**
* @param {!Event} event
* @return {boolean}
*/
function isEnterKey(event)
{
// Check if in IME.
return event.keyCode !== 229 && event.keyIdentifier === "Enter";
}
/**
* @param {!Event} event
* @return {boolean}
*/
function isEscKey(event)
{
return event.keyCode === 27;
}
function consumeEvent(e)
{
e.consume();
}
/**
* @param {function()} callback
* @suppressGlobalPropertiesCheck
*/
function runOnWindowLoad(callback)
{
/**
* @suppressGlobalPropertiesCheck
*/
function windowLoaded()
{
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
callback();
}
if (document.readyState === "complete" || document.readyState === "interactive")
callback();
else
window.addEventListener("DOMContentLoaded", windowLoaded, false);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 | 2 2 2 19 19 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// FIXME: This performance optimization should be moved to blink so that all developers could enjoy it.
// console is retrieved with V8Window.getAttribute method which is slow. Here we copy it to a js variable for faster access.
console = console;
console.__originalAssert = console.assert;
console.assert = function(value, message)
{
Eif (value)
return;
console.__originalAssert(value, message);
}
/** @typedef {Array|NodeList|Arguments|{length: number}} */
var ArrayLike;
/**
* @param {!Object} obj
* @return {boolean}
*/
Object.isEmpty = function(obj)
{
for (var i in obj)
return false;
return true;
}
/**
* @param {!Object.<string,!T>} obj
* @return {!Array.<!T>}
* @template T
*/
Object.values = function(obj)
{
var result = Object.keys(obj);
var length = result.length;
for (var i = 0; i < length; ++i)
result[i] = obj[result[i]];
return result;
}
/**
* @param {number} m
* @param {number} n
* @return {number}
*/
function mod(m, n)
{
return ((m % n) + n) % n;
}
/**
* @param {string} string
* @return {!Array.<number>}
*/
String.prototype.findAll = function(string)
{
var matches = [];
var i = this.indexOf(string);
while (i !== -1) {
matches.push(i);
i = this.indexOf(string, i + string.length);
}
return matches;
}
/**
* @return {string}
*/
String.prototype.replaceControlCharacters = function()
{
// Replace C0 and C1 control character sets with printable character.
// Do not replace '\t', \n' and '\r'.
return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g, "�");
}
/**
* @return {boolean}
*/
String.prototype.isWhitespace = function()
{
return /^\s*$/.test(this);
}
/**
* @return {!Array.<number>}
*/
String.prototype.computeLineEndings = function()
{
var endings = this.findAll("\n");
endings.push(this.length);
return endings;
}
/**
* @param {string} chars
* @return {string}
*/
String.prototype.escapeCharacters = function(chars)
{
var foundChar = false;
for (var i = 0; i < chars.length; ++i) {
if (this.indexOf(chars.charAt(i)) !== -1) {
foundChar = true;
break;
}
}
if (!foundChar)
return String(this);
var result = "";
for (var i = 0; i < this.length; ++i) {
if (chars.indexOf(this.charAt(i)) !== -1)
result += "\\";
result += this.charAt(i);
}
return result;
}
/**
* @return {string}
*/
String.regexSpecialCharacters = function()
{
return "^[]{}()\\.^$*+?|-,";
}
/**
* @return {string}
*/
String.prototype.escapeForRegExp = function()
{
return this.escapeCharacters(String.regexSpecialCharacters());
}
/**
* @return {string}
*/
String.prototype.escapeHTML = function()
{
return this.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); //" doublequotes just for editor
}
/**
* @return {string}
*/
String.prototype.unescapeHTML = function()
{
return this.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/:/g, ":")
.replace(/"/g, "\"")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/&/g, "&");
}
/**
* @return {string}
*/
String.prototype.collapseWhitespace = function()
{
return this.replace(/[\s\xA0]+/g, " ");
}
/**
* @param {number} maxLength
* @return {string}
*/
String.prototype.trimMiddle = function(maxLength)
{
if (this.length <= maxLength)
return String(this);
var leftHalf = maxLength >> 1;
var rightHalf = maxLength - leftHalf - 1;
return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
}
/**
* @param {number} maxLength
* @return {string}
*/
String.prototype.trimEnd = function(maxLength)
{
if (this.length <= maxLength)
return String(this);
return this.substr(0, maxLength - 1) + "\u2026";
}
/**
* @param {?string=} baseURLDomain
* @return {string}
*/
String.prototype.trimURL = function(baseURLDomain)
{
var result = this.replace(/^(https|http|file):\/\//i, "");
if (baseURLDomain) {
if (result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
result = result.substr(baseURLDomain.length);
}
return result;
}
/**
* @return {string}
*/
String.prototype.toTitleCase = function()
{
return this.substring(0, 1).toUpperCase() + this.substring(1);
}
/**
* @param {string} other
* @return {number}
*/
String.prototype.compareTo = function(other)
{
if (this > other)
return 1;
if (this < other)
return -1;
return 0;
}
/**
* @return {string}
*/
String.prototype.removeURLFragment = function()
{
var fragmentIndex = this.indexOf("#");
if (fragmentIndex == -1)
fragmentIndex = this.length;
return this.substring(0, fragmentIndex);
}
/**
* @param {string|undefined} string
* @return {number}
*/
String.hashCode = function(string)
{
if (!string)
return 0;
// Hash algorithm for substrings is described in "Über die Komplexität der Multiplikation in
// eingeschränkten Branchingprogrammmodellen" by Woelfe.
// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
var p = ((1 << 30) * 4 - 5); // prime: 2^32 - 5
var z = 0x5033d967; // 32 bits from random.org
var z2 = 0x59d2f15d; // random odd 32 bit number
var s = 0;
var zi = 1;
for (var i = 0; i < string.length; i++) {
var xi = string.charCodeAt(i) * z2;
s = (s + zi * xi) % p;
zi = (zi * z) % p;
}
s = (s + zi * (p - 1)) % p;
return Math.abs(s|0);
}
/**
* @param {string} string
* @param {number} index
* @return {boolean}
*/
String.isDigitAt = function(string, index)
{
var c = string.charCodeAt(index);
return 48 <= c && c <= 57;
}
/**
* @return {string}
*/
String.prototype.toBase64 = function()
{
/**
* @param {number} b
* @return {number}
*/
function encodeBits(b)
{
return b < 26 ? b + 65 : b < 52 ? b + 71 : b < 62 ? b - 4 : b === 62 ? 43 : b === 63 ? 47 : 65;
}
var encoder = new TextEncoder();
var data = encoder.encode(this.toString());
var n = data.length;
var encoded = "";
if (n === 0)
return encoded;
var shift;
var v = 0;
for (var i = 0; i < n; i++) {
shift = i % 3;
v |= data[i] << (16 >>> shift & 24);
if (shift === 2) {
encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), encodeBits(v & 63));
v = 0;
}
}
if (shift === 0)
encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), 61, 61);
else if (shift === 1)
encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), 61);
return encoded;
}
/**
* @param {string} a
* @param {string} b
* @return {number}
*/
String.naturalOrderComparator = function(a, b)
{
var chunk = /^\d+|^\D+/;
var chunka, chunkb, anum, bnum;
while (1) {
if (a) {
if (!b)
return 1;
} else {
if (b)
return -1;
else
return 0;
}
chunka = a.match(chunk)[0];
chunkb = b.match(chunk)[0];
anum = !isNaN(chunka);
bnum = !isNaN(chunkb);
if (anum && !bnum)
return -1;
if (bnum && !anum)
return 1;
if (anum && bnum) {
var diff = chunka - chunkb;
if (diff)
return diff;
if (chunka.length !== chunkb.length) {
if (!+chunka && !+chunkb) // chunks are strings of all 0s (special case)
return chunka.length - chunkb.length;
else
return chunkb.length - chunka.length;
}
} else if (chunka !== chunkb)
return (chunka < chunkb) ? -1 : 1;
a = a.substring(chunka.length);
b = b.substring(chunkb.length);
}
}
/**
* @param {string} a
* @param {string} b
* @return {number}
*/
String.caseInsensetiveComparator = function(a, b)
{
a = a.toUpperCase();
b = b.toUpperCase();
if (a === b)
return 0;
return a > b ? 1 : -1;
}
/**
* @param {number} num
* @param {number} min
* @param {number} max
* @return {number}
*/
Number.constrain = function(num, min, max)
{
if (num < min)
num = min;
else if (num > max)
num = max;
return num;
}
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
Number.gcd = function(a, b)
{
if (b === 0)
return a;
else
return Number.gcd(b, a % b);
}
/**
* @param {string} value
* @return {string}
*/
Number.toFixedIfFloating = function(value)
{
if (!value || isNaN(value))
return value;
var number = Number(value);
return number % 1 ? number.toFixed(3) : String(number);
}
/**
* @return {string}
*/
Date.prototype.toISO8601Compact = function()
{
/**
* @param {number} x
* @return {string}
*/
function leadZero(x)
{
return (x > 9 ? "" : "0") + x;
}
return this.getFullYear() +
leadZero(this.getMonth() + 1) +
leadZero(this.getDate()) + "T" +
leadZero(this.getHours()) +
leadZero(this.getMinutes()) +
leadZero(this.getSeconds());
}
/**
* @return {string}
*/
Date.prototype.toConsoleTime = function()
{
/**
* @param {number} x
* @return {string}
*/
function leadZero2(x)
{
return (x > 9 ? "" : "0") + x;
}
/**
* @param {number} x
* @return {string}
*/
function leadZero3(x)
{
return "0".repeat(3 - x.toString().length) + x;
}
return this.getFullYear() + "-" +
leadZero2(this.getMonth() + 1) + "-" +
leadZero2(this.getDate()) + " " +
leadZero2(this.getHours()) + ":" +
leadZero2(this.getMinutes()) + ":" +
leadZero2(this.getSeconds()) + "." +
leadZero3(this.getMilliseconds());
}
Object.defineProperty(Array.prototype, "remove",
{
/**
* @param {!T} value
* @param {boolean=} firstOnly
* @return {boolean}
* @this {Array.<!T>}
* @template T
*/
value: function(value, firstOnly)
{
var index = this.indexOf(value);
if (index === -1)
return false;
if (firstOnly) {
this.splice(index, 1);
return true;
}
for (var i = index + 1, n = this.length; i < n; ++i) {
if (this[i] !== value)
this[index++] = this[i];
}
this.length = index;
return true;
}
});
Object.defineProperty(Array.prototype, "keySet",
{
/**
* @return {!Object.<string, boolean>}
* @this {Array.<*>}
*/
value: function()
{
var keys = {};
for (var i = 0; i < this.length; ++i)
keys[this[i]] = true;
return keys;
}
});
Object.defineProperty(Array.prototype, "pushAll",
{
/**
* @param {!Array.<!T>} array
* @this {Array.<!T>}
* @template T
*/
value: function(array)
{
Array.prototype.push.apply(this, array);
}
});
Object.defineProperty(Array.prototype, "rotate",
{
/**
* @param {number} index
* @return {!Array.<!T>}
* @this {Array.<!T>}
* @template T
*/
value: function(index)
{
var result = [];
for (var i = index; i < index + this.length; ++i)
result.push(this[i % this.length]);
return result;
}
});
Object.defineProperty(Array.prototype, "sortNumbers",
{
/**
* @this {Array.<number>}
*/
value: function()
{
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
function numericComparator(a, b)
{
return a - b;
}
this.sort(numericComparator);
}
});
Object.defineProperty(Uint32Array.prototype, "sort", {
value: Array.prototype.sort
});
(function() {
var partition = {
/**
* @this {Array.<number>}
* @param {function(number, number): number} comparator
* @param {number} left
* @param {number} right
* @param {number} pivotIndex
*/
value: function(comparator, left, right, pivotIndex)
{
function swap(array, i1, i2)
{
var temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
var pivotValue = this[pivotIndex];
swap(this, right, pivotIndex);
var storeIndex = left;
for (var i = left; i < right; ++i) {
if (comparator(this[i], pivotValue) < 0) {
swap(this, storeIndex, i);
++storeIndex;
}
}
swap(this, right, storeIndex);
return storeIndex;
}
};
Object.defineProperty(Array.prototype, "partition", partition);
Object.defineProperty(Uint32Array.prototype, "partition", partition);
var sortRange = {
/**
* @param {function(number, number): number} comparator
* @param {number} leftBound
* @param {number} rightBound
* @param {number} sortWindowLeft
* @param {number} sortWindowRight
* @return {!Array.<number>}
* @this {Array.<number>}
*/
value: function(comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight)
{
function quickSortRange(array, comparator, left, right, sortWindowLeft, sortWindowRight)
{
if (right <= left)
return;
var pivotIndex = Math.floor(Math.random() * (right - left)) + left;
var pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
if (sortWindowLeft < pivotNewIndex)
quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);
if (pivotNewIndex < sortWindowRight)
quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);
}
if (leftBound === 0 && rightBound === (this.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound)
this.sort(comparator);
else
quickSortRange(this, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);
return this;
}
}
Object.defineProperty(Array.prototype, "sortRange", sortRange);
Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange);
})();
Object.defineProperty(Array.prototype, "stableSort",
{
/**
* @param {function(?T, ?T): number=} comparator
* @return {!Array.<?T>}
* @this {Array.<?T>}
* @template T
*/
value: function(comparator)
{
function defaultComparator(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
}
comparator = comparator || defaultComparator;
var indices = new Array(this.length);
for (var i = 0; i < this.length; ++i)
indices[i] = i;
var self = this;
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
function indexComparator(a, b)
{
var result = comparator(self[a], self[b]);
return result ? result : a - b;
}
indices.sort(indexComparator);
for (var i = 0; i < this.length; ++i) {
if (indices[i] < 0 || i === indices[i])
continue;
var cyclical = i;
var saved = this[i];
while (true) {
var next = indices[cyclical];
indices[cyclical] = -1;
if (next === i) {
this[cyclical] = saved;
break;
} else {
this[cyclical] = this[next];
cyclical = next;
}
}
}
return this;
}
});
Object.defineProperty(Array.prototype, "qselect",
{
/**
* @param {number} k
* @param {function(number, number): number=} comparator
* @return {number|undefined}
* @this {Array.<number>}
*/
value: function(k, comparator)
{
if (k < 0 || k >= this.length)
return;
if (!comparator)
comparator = function(a, b) { return a - b; }
var low = 0;
var high = this.length - 1;
for (;;) {
var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
if (pivotPosition === k)
return this[k];
else if (pivotPosition > k)
high = pivotPosition - 1;
else
low = pivotPosition + 1;
}
}
});
Object.defineProperty(Array.prototype, "lowerBound",
{
/**
* Return index of the leftmost element that is equal or greater
* than the specimen object. If there's no such element (i.e. all
* elements are smaller than the specimen) returns right bound.
* The function works for sorted array.
* When specified, |left| (inclusive) and |right| (exclusive) indices
* define the search window.
*
* @param {!T} object
* @param {function(!T,!S):number=} comparator
* @param {number=} left
* @param {number=} right
* @return {number}
* @this {Array.<!S>}
* @template T,S
*/
value: function(object, comparator, left, right)
{
function defaultComparator(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
}
comparator = comparator || defaultComparator;
var l = left || 0;
var r = right !== undefined ? right : this.length;
while (l < r) {
var m = (l + r) >> 1;
if (comparator(object, this[m]) > 0)
l = m + 1;
else
r = m;
}
return r;
}
});
Object.defineProperty(Array.prototype, "upperBound",
{
/**
* Return index of the leftmost element that is greater
* than the specimen object. If there's no such element (i.e. all
* elements are smaller or equal to the specimen) returns right bound.
* The function works for sorted array.
* When specified, |left| (inclusive) and |right| (exclusive) indices
* define the search window.
*
* @param {!T} object
* @param {function(!T,!S):number=} comparator
* @param {number=} left
* @param {number=} right
* @return {number}
* @this {Array.<!S>}
* @template T,S
*/
value: function(object, comparator, left, right)
{
function defaultComparator(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
}
comparator = comparator || defaultComparator;
var l = left || 0;
var r = right !== undefined ? right : this.length;
while (l < r) {
var m = (l + r) >> 1;
if (comparator(object, this[m]) >= 0)
l = m + 1;
else
r = m;
}
return r;
}
});
Object.defineProperty(Uint32Array.prototype, "lowerBound", {
value: Array.prototype.lowerBound
});
Object.defineProperty(Uint32Array.prototype, "upperBound", {
value: Array.prototype.upperBound
});
Object.defineProperty(Float64Array.prototype, "lowerBound", {
value: Array.prototype.lowerBound
});
Object.defineProperty(Array.prototype, "binaryIndexOf",
{
/**
* @param {!T} value
* @param {function(!T,!S):number} comparator
* @return {number}
* @this {Array.<!S>}
* @template T,S
*/
value: function(value, comparator)
{
var index = this.lowerBound(value, comparator);
return index < this.length && comparator(value, this[index]) === 0 ? index : -1;
}
});
Object.defineProperty(Array.prototype, "select",
{
/**
* @param {string} field
* @return {!Array.<!T>}
* @this {Array.<!Object.<string,!T>>}
* @template T
*/
value: function(field)
{
var result = new Array(this.length);
for (var i = 0; i < this.length; ++i)
result[i] = this[i][field];
return result;
}
});
Object.defineProperty(Array.prototype, "peekLast",
{
/**
* @return {!T|undefined}
* @this {Array.<!T>}
* @template T
*/
value: function()
{
return this[this.length - 1];
}
});
(function(){
/**
* @param {!Array.<T>} array1
* @param {!Array.<T>} array2
* @param {function(T,T):number} comparator
* @param {boolean} mergeNotIntersect
* @return {!Array.<T>}
* @template T
*/
function mergeOrIntersect(array1, array2, comparator, mergeNotIntersect)
{
var result = [];
var i = 0;
var j = 0;
while (i < array1.length && j < array2.length) {
var compareValue = comparator(array1[i], array2[j]);
if (mergeNotIntersect || !compareValue)
result.push(compareValue <= 0 ? array1[i] : array2[j]);
if (compareValue <= 0)
i++;
if (compareValue >= 0)
j++;
}
if (mergeNotIntersect) {
while (i < array1.length)
result.push(array1[i++]);
while (j < array2.length)
result.push(array2[j++]);
}
return result;
}
Object.defineProperty(Array.prototype, "intersectOrdered",
{
/**
* @param {!Array.<T>} array
* @param {function(T,T):number} comparator
* @return {!Array.<T>}
* @this {!Array.<T>}
* @template T
*/
value: function(array, comparator)
{
return mergeOrIntersect(this, array, comparator, false);
}
});
Object.defineProperty(Array.prototype, "mergeOrdered",
{
/**
* @param {!Array.<T>} array
* @param {function(T,T):number} comparator
* @return {!Array.<T>}
* @this {!Array.<T>}
* @template T
*/
value: function(array, comparator)
{
return mergeOrIntersect(this, array, comparator, true);
}
});
}());
/**
* @param {string} format
* @param {...*} var_arg
* @return {string}
*/
String.sprintf = function(format, var_arg)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
}
/**
* @param {string} format
* @param {!Object.<string, function(string, ...):*>} formatters
* @return {!Array.<!Object>}
*/
String.tokenizeFormatString = function(format, formatters)
{
var tokens = [];
var substitutionIndex = 0;
function addStringToken(str)
{
if (tokens.length && tokens[tokens.length - 1].type === "string")
tokens[tokens.length - 1].value += str;
else
tokens.push({ type: "string", value: str });
}
function addSpecifierToken(specifier, precision, substitutionIndex)
{
tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
}
var index = 0;
for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
if (format.length === index) // unescaped % sign at the end of the format string.
break;
addStringToken(format.substring(index, precentIndex));
index = precentIndex + 1;
if (format[index] === "%") {
// %% escape sequence.
addStringToken("%");
++index;
continue;
}
if (String.isDigitAt(format, index)) {
// The first character is a number, it might be a substitution index.
var number = parseInt(format.substring(index), 10);
while (String.isDigitAt(format, index))
++index;
// If the number is greater than zero and ends with a "$",
// then this is a substitution index.
if (number > 0 && format[index] === "$") {
substitutionIndex = (number - 1);
++index;
}
}
var precision = -1;
if (format[index] === ".") {
// This is a precision specifier. If no digit follows the ".",
// then the precision should be zero.
++index;
precision = parseInt(format.substring(index), 10);
if (isNaN(precision))
precision = 0;
while (String.isDigitAt(format, index))
++index;
}
if (!(format[index] in formatters)) {
addStringToken(format.substring(precentIndex, index + 1));
++index;
continue;
}
addSpecifierToken(format[index], precision, substitutionIndex);
++substitutionIndex;
++index;
}
addStringToken(format.substring(index));
return tokens;
}
String.standardFormatters = {
/**
* @return {number}
*/
d: function(substitution)
{
return !isNaN(substitution) ? substitution : 0;
},
/**
* @return {number}
*/
f: function(substitution, token)
{
if (substitution && token.precision > -1)
substitution = substitution.toFixed(token.precision);
return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
},
/**
* @return {string}
*/
s: function(substitution)
{
return substitution;
}
}
/**
* @param {string} format
* @param {!Array.<*>} substitutions
* @return {string}
*/
String.vsprintf = function(format, substitutions)
{
return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
}
/**
* @param {string} format
* @param {?ArrayLike} substitutions
* @param {!Object.<string, function(string, ...):Q>} formatters
* @param {!T} initialValue
* @param {function(T, Q): T|undefined} append
* @param {!Array.<!Object>=} tokenizedFormat
* @return {!{formattedResult: T, unusedSubstitutions: ?ArrayLike}};
* @template T, Q
*/
String.format = function(format, substitutions, formatters, initialValue, append, tokenizedFormat)
{
if (!format || !substitutions || !substitutions.length)
return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };
function prettyFunctionName()
{
return "String.format(\"" + format + "\", \"" + Array.prototype.join.call(substitutions, "\", \"") + "\")";
}
function warn(msg)
{
console.warn(prettyFunctionName() + ": " + msg);
}
function error(msg)
{
console.error(prettyFunctionName() + ": " + msg);
}
var result = initialValue;
var tokens = tokenizedFormat || String.tokenizeFormatString(format, formatters);
var usedSubstitutionIndexes = {};
for (var i = 0; i < tokens.length; ++i) {
var token = tokens[i];
if (token.type === "string") {
result = append(result, token.value);
continue;
}
if (token.type !== "specifier") {
error("Unknown token type \"" + token.type + "\" found.");
continue;
}
if (token.substitutionIndex >= substitutions.length) {
// If there are not enough substitutions for the current substitutionIndex
// just output the format specifier literally and move on.
error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
continue;
}
usedSubstitutionIndexes[token.substitutionIndex] = true;
if (!(token.specifier in formatters)) {
// Encountered an unsupported format character, treat as a string.
warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
result = append(result, substitutions[token.substitutionIndex]);
continue;
}
result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
}
var unusedSubstitutions = [];
for (var i = 0; i < substitutions.length; ++i) {
if (i in usedSubstitutionIndexes)
continue;
unusedSubstitutions.push(substitutions[i]);
}
return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
}
/**
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @return {!RegExp}
*/
function createSearchRegex(query, caseSensitive, isRegex)
{
var regexFlags = caseSensitive ? "g" : "gi";
var regexObject;
if (isRegex) {
try {
regexObject = new RegExp(query, regexFlags);
} catch (e) {
// Silent catch.
}
}
if (!regexObject)
regexObject = createPlainTextSearchRegex(query, regexFlags);
return regexObject;
}
/**
* @param {string} query
* @param {string=} flags
* @return {!RegExp}
*/
function createPlainTextSearchRegex(query, flags)
{
// This should be kept the same as the one in V8StringUtil.cpp.
var regexSpecialCharacters = String.regexSpecialCharacters();
var regex = "";
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (regexSpecialCharacters.indexOf(c) != -1)
regex += "\\";
regex += c;
}
return new RegExp(regex, flags || "");
}
/**
* @param {!RegExp} regex
* @param {string} content
* @return {number}
*/
function countRegexMatches(regex, content)
{
var text = content;
var result = 0;
var match;
while (text && (match = regex.exec(text))) {
if (match[0].length > 0)
++result;
text = text.substring(match.index + 1);
}
return result;
}
/**
* @param {number} spacesCount
* @return {string}
*/
function spacesPadding(spacesCount)
{
return "\u00a0".repeat(spacesCount);
}
/**
* @param {number} value
* @param {number} symbolsCount
* @return {string}
*/
function numberToStringWithSpacesPadding(value, symbolsCount)
{
var numberString = value.toString();
var paddingLength = Math.max(0, symbolsCount - numberString.length);
return spacesPadding(paddingLength) + numberString;
}
/**
* @return {!Array.<T>}
* @template T
*/
Set.prototype.valuesArray = function()
{
return Array.from(this.values());
}
/**
* @param {!Iterable<T>|!Array<!T>} iterable
* @template T
*/
Set.prototype.addAll = function(iterable)
{
for (var e of iterable)
this.add(e);
}
/**
* @param {!Iterable<T>|!Array<!T>} iterable
* @return {boolean}
* @template T
*/
Set.prototype.containsAll = function(iterable)
{
for (var e of iterable) {
if (!this.has(e))
return false;
}
return true;
}
/**
* @return {T}
* @template T
*/
Map.prototype.remove = function(key)
{
var value = this.get(key);
this.delete(key);
return value;
}
/**
* @return {!Array<!VALUE>}
*/
Map.prototype.valuesArray = function()
{
return Array.from(this.values());
}
/**
* @return {!Array<!KEY>}
*/
Map.prototype.keysArray = function()
{
return Array.from(this.keys());
}
/**
* @constructor
* @template K, V
*/
var Multimap = function()
{
/** @type {!Map.<K, !Set.<!V>>} */
this._map = new Map();
}
Multimap.prototype = {
/**
* @param {K} key
* @param {V} value
*/
set: function(key, value)
{
var set = this._map.get(key);
if (!set) {
set = new Set();
this._map.set(key, set);
}
set.add(value);
},
/**
* @param {K} key
* @return {!Set.<!V>}
*/
get: function(key)
{
var result = this._map.get(key);
if (!result)
result = new Set();
return result;
},
/**
* @param {K} key
* @return {boolean}
*/
has: function(key)
{
return this._map.has(key);
},
/**
* @param {K} key
* @param {V} value
* @return {boolean}
*/
hasValue: function(key, value)
{
var set = this._map.get(key);
if (!set)
return false;
return set.has(value);
},
/**
* @return {number}
*/
get size()
{
return this._map.size;
},
/**
* @param {K} key
* @param {V} value
*/
remove: function(key, value)
{
var values = this.get(key);
values.delete(value);
if (!values.size)
this._map.delete(key);
},
/**
* @param {K} key
*/
removeAll: function(key)
{
this._map.delete(key);
},
/**
* @return {!Array.<K>}
*/
keysArray: function()
{
return this._map.keysArray();
},
/**
* @return {!Array.<!V>}
*/
valuesArray: function()
{
var result = [];
var keys = this.keysArray();
for (var i = 0; i < keys.length; ++i)
result.pushAll(this.get(keys[i]).valuesArray());
return result;
},
clear: function()
{
this._map.clear();
}
}
/**
* @param {string} url
* @return {!Promise.<string>}
*/
function loadXHR(url)
{
return new Promise(load);
function load(successCallback, failureCallback)
{
function onReadyStateChanged()
{
if (xhr.readyState !== XMLHttpRequest.DONE)
return;
if (xhr.status !== 200) {
xhr.onreadystatechange = null;
failureCallback(new Error(xhr.status));
return;
}
xhr.onreadystatechange = null;
successCallback(xhr.responseText);
}
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open("GET", url, true);
xhr.onreadystatechange = onReadyStateChanged;
xhr.send(null);
}
}
/**
* @constructor
*/
function CallbackBarrier()
{
this._pendingIncomingCallbacksCount = 0;
}
CallbackBarrier.prototype = {
/**
* @param {function(...)=} userCallback
* @return {function(...)}
*/
createCallback: function(userCallback)
{
console.assert(!this._outgoingCallback, "CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");
++this._pendingIncomingCallbacksCount;
return this._incomingCallback.bind(this, userCallback);
},
/**
* @param {function()} callback
*/
callWhenDone: function(callback)
{
console.assert(!this._outgoingCallback, "CallbackBarrier.callWhenDone() is called multiple times");
this._outgoingCallback = callback;
if (!this._pendingIncomingCallbacksCount)
this._outgoingCallback();
},
/**
* @return {!Promise.<undefined>}
*/
donePromise: function()
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function()} success
* @this {CallbackBarrier}
*/
function promiseConstructor(success)
{
this.callWhenDone(success);
}
},
/**
* @param {function(...)=} userCallback
*/
_incomingCallback: function(userCallback)
{
console.assert(this._pendingIncomingCallbacksCount > 0);
if (userCallback) {
var args = Array.prototype.slice.call(arguments, 1);
userCallback.apply(null, args);
}
if (!--this._pendingIncomingCallbacksCount && this._outgoingCallback)
this._outgoingCallback();
}
}
/**
* @param {*} value
*/
function suppressUnused(value)
{
}
/**
* @param {function()} callback
* @return {number}
*/
self.setImmediate = function(callback)
{
Promise.resolve().then(callback);
return 0;
}
/**
* @param {function(...?)} callback
* @return {!Promise.<T>}
* @template T
*/
Promise.prototype.spread = function(callback)
{
return this.then(spreadPromise);
function spreadPromise(arg)
{
return callback.apply(null, arg);
}
}
/**
* @param {T} defaultValue
* @return {!Promise.<T>}
* @template T
*/
Promise.prototype.catchException = function(defaultValue) {
return this.catch(function (error) {
console.error(error);
return defaultValue;
});
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CPUProfileBottomUpDataGrid.js | 0.82% | (1 / 122) | 0% | (0 / 46) | 0% | (0 / 14) | 0.82% | (1 / 122) | |
| CPUProfileDataGrid.js | 0.77% | (2 / 259) | 0% | (0 / 157) | 0% | (0 / 41) | 0.77% | (2 / 259) | |
| CPUProfileFlameChart.js | 2.12% | (5 / 236) | 0% | (0 / 40) | 0% | (0 / 60) | 2.12% | (5 / 236) | |
| CPUProfileTopDownDataGrid.js | 2.22% | (1 / 45) | 0% | (0 / 14) | 0% | (0 / 9) | 2.22% | (1 / 45) | |
| CPUProfileView.js | 2.42% | (7 / 289) | 0% | (0 / 96) | 0% | (0 / 66) | 2.42% | (7 / 289) | |
| HeapSnapshotCommon.js | 0.88% | (1 / 114) | 0% | (0 / 3) | 0% | (0 / 18) | 0.88% | (1 / 114) | |
| HeapSnapshotDataGrids.js | 2.56% | (9 / 352) | 0% | (0 / 128) | 0% | (0 / 85) | 2.56% | (9 / 352) | |
| HeapSnapshotGridNodes.js | 3.61% | (19 / 526) | 0% | (0 / 178) | 0% | (0 / 108) | 3.61% | (19 / 526) | |
| HeapSnapshotProxy.js | 4.58% | (6 / 131) | 0% | (0 / 24) | 0% | (0 / 56) | 4.58% | (6 / 131) | |
| HeapSnapshotView.js | 1.72% | (15 / 871) | 0% | (0 / 264) | 0% | (0 / 174) | 1.72% | (15 / 870) | |
| ProfileLauncherView.js | 1.05% | (1 / 95) | 0% | (0 / 18) | 0% | (0 / 20) | 1.05% | (1 / 95) | |
| ProfileTypeRegistry.js | 8.33% | (1 / 12) | 100% | (0 / 0) | 0% | (0 / 3) | 8.33% | (1 / 12) | |
| ProfilesPanel.js | 1.49% | (7 / 471) | 0% | (0 / 148) | 0% | (0 / 104) | 1.49% | (7 / 471) | |
| TargetsComboBoxController.js | 2.94% | (1 / 34) | 0% | (0 / 10) | 0% | (0 / 7) | 2.94% | (1 / 34) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | 2 | /*
* Copyright (C) 2009 280 North Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Bottom Up Profiling shows the entire callstack backwards:
// The root node is a representation of each individual function called, and each child of that node represents
// a reverse-callstack showing how many of those calls came from it. So, unlike top-down, the statistics in
// each child still represent the root node. We have to be particularly careful of recursion with this mode
// because a root node can represent itself AND an ancestor.
/**
* @constructor
* @extends {WebInspector.ProfileDataGridNode}
* @param {!ProfilerAgent.CPUProfileNode} profileNode
* @param {!WebInspector.TopDownProfileDataGridTree} owningTree
*/
WebInspector.BottomUpProfileDataGridNode = function(profileNode, owningTree)
{
WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, this._willHaveChildren(profileNode));
this._remainingNodeInfos = [];
}
WebInspector.BottomUpProfileDataGridNode.prototype = {
/**
* @param {!WebInspector.ProfileDataGridNode} profileDataGridNode
*/
_takePropertiesFromProfileDataGridNode: function(profileDataGridNode)
{
this.save();
this.selfTime = profileDataGridNode.selfTime;
this.totalTime = profileDataGridNode.totalTime;
},
/**
* When focusing, we keep just the members of the callstack.
* @param {!WebInspector.ProfileDataGridNode} child
*/
_keepOnlyChild: function(child)
{
this.save();
this.removeChildren();
this.appendChild(child);
},
/**
* @param {number} aCallUID
*/
_exclude: function(aCallUID)
{
if (this._remainingNodeInfos)
this.populate();
this.save();
var children = this.children;
var index = this.children.length;
while (index--)
children[index]._exclude(aCallUID);
var child = this.childrenByCallUID[aCallUID];
if (child)
this.merge(child, true);
},
/**
* @override
*/
restore: function()
{
WebInspector.ProfileDataGridNode.prototype.restore.call(this);
if (!this.children.length)
this.hasChildren = this._willHaveChildren(this.profileNode);
},
/**
* @override
* @param {!WebInspector.ProfileDataGridNode} child
* @param {boolean} shouldAbsorb
*/
merge: function(child, shouldAbsorb)
{
this.selfTime -= child.selfTime;
WebInspector.ProfileDataGridNode.prototype.merge.call(this, child, shouldAbsorb);
},
/**
* @override
*/
populateChildren: function()
{
WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this);
},
_willHaveChildren: function(profileNode)
{
// In bottom up mode, our parents are our children since we display an inverted tree.
// However, we don't want to show the very top parent since it is redundant.
return !!(profileNode.parent && profileNode.parent.parent);
},
__proto__: WebInspector.ProfileDataGridNode.prototype
}
/**
* @param {!WebInspector.BottomUpProfileDataGridNode|!WebInspector.BottomUpProfileDataGridTree} container
*/
WebInspector.BottomUpProfileDataGridNode._sharedPopulate = function(container)
{
var remainingNodeInfos = container._remainingNodeInfos;
var count = remainingNodeInfos.length;
for (var index = 0; index < count; ++index) {
var nodeInfo = remainingNodeInfos[index];
var ancestor = nodeInfo.ancestor;
var focusNode = nodeInfo.focusNode;
var child = container.findChild(ancestor);
// If we already have this child, then merge the data together.
if (child) {
var totalTimeAccountedFor = nodeInfo.totalTimeAccountedFor;
child.selfTime += focusNode.selfTime;
if (!totalTimeAccountedFor)
child.totalTime += focusNode.totalTime;
} else {
// If not, add it as a true ancestor.
// In heavy mode, we take our visual identity from ancestor node...
child = new WebInspector.BottomUpProfileDataGridNode(ancestor, /** @type {!WebInspector.TopDownProfileDataGridTree} */ (container.tree));
if (ancestor !== focusNode) {
// But the actual statistics from the "root" node (bottom of the callstack).
child.selfTime = focusNode.selfTime;
child.totalTime = focusNode.totalTime;
}
container.appendChild(child);
}
var parent = ancestor.parent;
if (parent && parent.parent) {
nodeInfo.ancestor = parent;
child._remainingNodeInfos.push(nodeInfo);
}
}
delete container._remainingNodeInfos;
}
/**
* @constructor
* @extends {WebInspector.ProfileDataGridTree}
* @param {!WebInspector.ProfileDataGridNode.Formatter} formatter
* @param {!WebInspector.SearchableView} searchableView
* @param {!ProfilerAgent.CPUProfileNode} rootProfileNode
* @param {number} totalTime
*/
WebInspector.BottomUpProfileDataGridTree = function(formatter, searchableView, rootProfileNode, totalTime)
{
WebInspector.ProfileDataGridTree.call(this, formatter, searchableView, totalTime);
// Iterate each node in pre-order.
var profileNodeUIDs = 0;
var profileNodeGroups = [[], [rootProfileNode]];
var visitedProfileNodesForCallUID = {};
this._remainingNodeInfos = [];
for (var profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) {
var parentProfileNodes = profileNodeGroups[profileNodeGroupIndex];
var profileNodes = profileNodeGroups[++profileNodeGroupIndex];
var count = profileNodes.length;
for (var index = 0; index < count; ++index) {
var profileNode = profileNodes[index];
if (!profileNode.UID)
profileNode.UID = ++profileNodeUIDs;
if (profileNode.parent) {
// The total time of this ancestor is accounted for if we're in any form of recursive cycle.
var visitedNodes = visitedProfileNodesForCallUID[profileNode.callUID];
var totalTimeAccountedFor = false;
if (!visitedNodes) {
visitedNodes = {};
visitedProfileNodesForCallUID[profileNode.callUID] = visitedNodes;
} else {
// The total time for this node has already been accounted for iff one of it's parents has already been visited.
// We can do this check in this style because we are traversing the tree in pre-order.
var parentCount = parentProfileNodes.length;
for (var parentIndex = 0; parentIndex < parentCount; ++parentIndex) {
if (visitedNodes[parentProfileNodes[parentIndex].UID]) {
totalTimeAccountedFor = true;
break;
}
}
}
visitedNodes[profileNode.UID] = true;
this._remainingNodeInfos.push({ ancestor:profileNode, focusNode:profileNode, totalTimeAccountedFor:totalTimeAccountedFor });
}
var children = profileNode.children;
if (children.length) {
profileNodeGroups.push(parentProfileNodes.concat([profileNode]));
profileNodeGroups.push(children);
}
}
}
// Populate the top level nodes.
WebInspector.ProfileDataGridNode.populate(this);
return this;
}
WebInspector.BottomUpProfileDataGridTree.prototype = {
/**
* When focusing, we keep the entire callstack up to this ancestor.
* @param {!WebInspector.ProfileDataGridNode} profileDataGridNode
*/
focus: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this.save();
var currentNode = profileDataGridNode;
var focusNode = profileDataGridNode;
while (currentNode.parent && (currentNode instanceof WebInspector.ProfileDataGridNode)) {
currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);
focusNode = currentNode;
currentNode = currentNode.parent;
if (currentNode instanceof WebInspector.ProfileDataGridNode)
currentNode._keepOnlyChild(focusNode);
}
this.children = [focusNode];
this.totalTime = profileDataGridNode.totalTime;
},
/**
* @param {!WebInspector.ProfileDataGridNode} profileDataGridNode
*/
exclude: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this.save();
var excludedCallUID = profileDataGridNode.callUID;
var excludedTopLevelChild = this.childrenByCallUID[excludedCallUID];
// If we have a top level node that is excluded, get rid of it completely (not keeping children),
// since bottom up data relies entirely on the root node.
if (excludedTopLevelChild)
this.children.remove(excludedTopLevelChild);
var children = this.children;
var count = children.length;
for (var index = 0; index < count; ++index)
children[index]._exclude(excludedCallUID);
if (this.lastComparator)
this.sort(this.lastComparator, true);
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
this.searchCanceled();
var matchesQuery = this._matchFunction(searchConfig);
if (!matchesQuery)
return;
this._searchResults = [];
for (var current = this.children[0]; current; current = current.traverseNextNode(true, null, true)) {
if (matchesQuery(current))
this._searchResults.push({ profileNode: current });
}
this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1;
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
},
/**
* @override
*/
populateChildren: function()
{
WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this);
},
__proto__: WebInspector.ProfileDataGridTree.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | 2 1 | /*
* Copyright (C) 2009 280 North Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.DataGridNode}
* @param {!ProfilerAgent.CPUProfileNode} profileNode
* @param {!WebInspector.ProfileDataGridTree} owningTree
* @param {boolean} hasChildren
*/
WebInspector.ProfileDataGridNode = function(profileNode, owningTree, hasChildren)
{
this.profileNode = profileNode;
WebInspector.DataGridNode.call(this, null, hasChildren);
this.tree = owningTree;
this.childrenByCallUID = {};
this.lastComparator = null;
this.callUID = profileNode.callUID;
this.selfTime = profileNode.selfTime;
this.totalTime = profileNode.totalTime;
this.functionName = WebInspector.beautifyFunctionName(profileNode.functionName);
this._deoptReason = profileNode.deoptReason && profileNode.deoptReason !== "no reason" ? profileNode.deoptReason : "";
this.url = profileNode.url;
}
WebInspector.ProfileDataGridNode.prototype = {
/**
* @override
* @param {string} columnId
* @return {!Element}
*/
createCell: function(columnId)
{
var cell;
switch (columnId) {
case "self":
cell = this._createValueCell(this.selfTime, this.selfPercent);
cell.classList.toggle("highlight", this._searchMatchedSelfColumn);
break;
case "total":
cell = this._createValueCell(this.totalTime, this.totalPercent);
cell.classList.toggle("highlight", this._searchMatchedTotalColumn);
break;
case "function":
cell = this.createTD(columnId);
cell.classList.toggle("highlight", this._searchMatchedFunctionColumn);
if (this._deoptReason) {
cell.classList.add("not-optimized");
cell.createChild("span", "profile-warn-marker").title = WebInspector.UIString("Not optimized: %s", this._deoptReason);
}
cell.createTextChild(this.functionName);
if (this.profileNode.scriptId === "0")
break;
var urlElement = this.tree._formatter.linkifyNode(this);
urlElement.style.maxWidth = "75%";
cell.appendChild(urlElement);
break;
default:
cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnId);
break;
}
return cell;
},
/**
* @param {number} value
* @param {number} percent
* @return {!Element}
*/
_createValueCell: function(value, percent)
{
var cell = createElementWithClass("td", "numeric-column");
var div = cell.createChild("div", "profile-multiple-values");
div.createChild("span").textContent = this.tree._formatter.formatValue(value, this);
div.createChild("span", "percent-column").textContent = this.tree._formatter.formatPercent(percent, this);
return cell;
},
/**
* @param {function(!T, !T)} comparator
* @param {boolean} force
* @template T
*/
sort: function(comparator, force)
{
var gridNodeGroups = [[this]];
for (var gridNodeGroupIndex = 0; gridNodeGroupIndex < gridNodeGroups.length; ++gridNodeGroupIndex) {
var gridNodes = gridNodeGroups[gridNodeGroupIndex];
var count = gridNodes.length;
for (var index = 0; index < count; ++index) {
var gridNode = gridNodes[index];
// If the grid node is collapsed, then don't sort children (save operation for later).
// If the grid node has the same sorting as previously, then there is no point in sorting it again.
if (!force && (!gridNode.expanded || gridNode.lastComparator === comparator)) {
if (gridNode.children.length)
gridNode.shouldRefreshChildren = true;
continue;
}
gridNode.lastComparator = comparator;
var children = gridNode.children;
var childCount = children.length;
if (childCount) {
children.sort(comparator);
for (var childIndex = 0; childIndex < childCount; ++childIndex)
children[childIndex].recalculateSiblings(childIndex);
gridNodeGroups.push(children);
}
}
}
},
/**
* @override
* @param {!WebInspector.DataGridNode} profileDataGridNode
* @param {number} index
*/
insertChild: function(profileDataGridNode, index)
{
WebInspector.DataGridNode.prototype.insertChild.call(this, profileDataGridNode, index);
this.childrenByCallUID[profileDataGridNode.callUID] = /** @type {!WebInspector.ProfileDataGridNode} */ (profileDataGridNode);
},
/**
* @override
* @param {!WebInspector.DataGridNode} profileDataGridNode
*/
removeChild: function(profileDataGridNode)
{
WebInspector.DataGridNode.prototype.removeChild.call(this, profileDataGridNode);
delete this.childrenByCallUID[/** @type {!WebInspector.ProfileDataGridNode} */ (profileDataGridNode).callUID];
},
removeChildren: function()
{
WebInspector.DataGridNode.prototype.removeChildren.call(this);
this.childrenByCallUID = {};
},
/**
* @param {!WebInspector.ProfileDataGridNode} node
* @return {?WebInspector.ProfileDataGridNode}
*/
findChild: function(node)
{
if (!node)
return null;
return this.childrenByCallUID[node.callUID];
},
get selfPercent()
{
return this.selfTime / this.tree.totalTime * 100.0;
},
get totalPercent()
{
return this.totalTime / this.tree.totalTime * 100.0;
},
populate: function()
{
WebInspector.ProfileDataGridNode.populate(this);
},
/**
* @protected
*/
populateChildren: function()
{
},
// When focusing and collapsing we modify lots of nodes in the tree.
// This allows us to restore them all to their original state when we revert.
save: function()
{
if (this._savedChildren)
return;
this._savedSelfTime = this.selfTime;
this._savedTotalTime = this.totalTime;
this._savedChildren = this.children.slice();
},
/**
* When focusing and collapsing we modify lots of nodes in the tree.
* This allows us to restore them all to their original state when we revert.
* @protected
*/
restore: function()
{
if (!this._savedChildren)
return;
this.selfTime = this._savedSelfTime;
this.totalTime = this._savedTotalTime;
this.removeChildren();
var children = this._savedChildren;
var count = children.length;
for (var index = 0; index < count; ++index) {
children[index].restore();
this.appendChild(children[index]);
}
},
/**
* @param {!WebInspector.ProfileDataGridNode} child
* @param {boolean} shouldAbsorb
*/
merge: function(child, shouldAbsorb)
{
WebInspector.ProfileDataGridNode.merge(this, child, shouldAbsorb);
},
__proto__: WebInspector.DataGridNode.prototype
}
/**
* @param {!WebInspector.ProfileDataGridNode|!WebInspector.ProfileDataGridTree} container
* @param {!WebInspector.ProfileDataGridNode} child
* @param {boolean} shouldAbsorb
*/
WebInspector.ProfileDataGridNode.merge = function(container, child, shouldAbsorb)
{
container.selfTime += child.selfTime;
if (!shouldAbsorb)
container.totalTime += child.totalTime;
var children = container.children.slice();
container.removeChildren();
var count = children.length;
for (var index = 0; index < count; ++index) {
if (!shouldAbsorb || children[index] !== child)
container.appendChild(children[index]);
}
children = child.children.slice();
count = children.length;
for (var index = 0; index < count; ++index) {
var orphanedChild = children[index];
var existingChild = container.childrenByCallUID[orphanedChild.callUID];
if (existingChild)
existingChild.merge(orphanedChild, false);
else
container.appendChild(orphanedChild);
}
}
/**
* @param {!WebInspector.ProfileDataGridNode|!WebInspector.ProfileDataGridTree} container
*/
WebInspector.ProfileDataGridNode.populate = function(container)
{
if (container._populated)
return;
container._populated = true;
container.populateChildren();
var currentComparator = container.tree.lastComparator;
if (currentComparator)
container.sort(currentComparator, true);
}
/**
* @constructor
* @implements {WebInspector.Searchable}
* @param {!WebInspector.ProfileDataGridNode.Formatter} formatter
* @param {!WebInspector.SearchableView} searchableView
* @param {number} totalTime
*/
WebInspector.ProfileDataGridTree = function(formatter, searchableView, totalTime)
{
this.tree = this;
this.children = [];
this._formatter = formatter;
this._searchableView = searchableView;
this.totalTime = totalTime;
this.lastComparator = null;
this.childrenByCallUID = {};
}
WebInspector.ProfileDataGridTree.prototype = {
get expanded()
{
return true;
},
appendChild: function(child)
{
this.insertChild(child, this.children.length);
},
insertChild: function(child, index)
{
this.children.splice(index, 0, child);
this.childrenByCallUID[child.callUID] = child;
},
removeChildren: function()
{
this.children = [];
this.childrenByCallUID = {};
},
populateChildren: function()
{
},
findChild: WebInspector.ProfileDataGridNode.prototype.findChild,
sort: WebInspector.ProfileDataGridNode.prototype.sort,
/**
* @protected
*/
save: function()
{
if (this._savedChildren)
return;
this._savedTotalTime = this.totalTime;
this._savedChildren = this.children.slice();
},
restore: function()
{
if (!this._savedChildren)
return;
this.children = this._savedChildren;
this.totalTime = this._savedTotalTime;
var children = this.children;
var count = children.length;
for (var index = 0; index < count; ++index)
children[index].restore();
this._savedChildren = null;
},
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @return {?function(!WebInspector.ProfileDataGridNode):boolean}
*/
_matchFunction: function(searchConfig)
{
var query = searchConfig.query.trim();
if (!query.length)
return null;
var greaterThan = (query.startsWith(">"));
var lessThan = (query.startsWith("<"));
var equalTo = (query.startsWith("=") || ((greaterThan || lessThan) && query.indexOf("=") === 1));
var percentUnits = (query.endsWith("%"));
var millisecondsUnits = (query.length > 2 && query.endsWith("ms"));
var secondsUnits = (!millisecondsUnits && query.endsWith("s"));
var queryNumber = parseFloat(query);
if (greaterThan || lessThan || equalTo) {
if (equalTo && (greaterThan || lessThan))
queryNumber = parseFloat(query.substring(2));
else
queryNumber = parseFloat(query.substring(1));
}
var queryNumberMilliseconds = (secondsUnits ? (queryNumber * 1000) : queryNumber);
// Make equalTo implicitly true if it wasn't specified there is no other operator.
if (!isNaN(queryNumber) && !(greaterThan || lessThan))
equalTo = true;
var matcher = createPlainTextSearchRegex(query, "i");
function matchesQuery(/*ProfileDataGridNode*/ profileDataGridNode)
{
delete profileDataGridNode._searchMatchedSelfColumn;
delete profileDataGridNode._searchMatchedTotalColumn;
delete profileDataGridNode._searchMatchedFunctionColumn;
if (percentUnits) {
if (lessThan) {
if (profileDataGridNode.selfPercent < queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent < queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
} else if (greaterThan) {
if (profileDataGridNode.selfPercent > queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent > queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
}
if (equalTo) {
if (profileDataGridNode.selfPercent == queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent == queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
}
} else if (millisecondsUnits || secondsUnits) {
if (lessThan) {
if (profileDataGridNode.selfTime < queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime < queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
} else if (greaterThan) {
if (profileDataGridNode.selfTime > queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime > queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
}
if (equalTo) {
if (profileDataGridNode.selfTime == queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime == queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
}
}
if (profileDataGridNode.functionName.match(matcher) || (profileDataGridNode.url && profileDataGridNode.url.match(matcher)))
profileDataGridNode._searchMatchedFunctionColumn = true;
if (profileDataGridNode._searchMatchedSelfColumn ||
profileDataGridNode._searchMatchedTotalColumn ||
profileDataGridNode._searchMatchedFunctionColumn) {
profileDataGridNode.refresh();
return true;
}
return false;
}
return matchesQuery;
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
this.searchCanceled();
var matchesQuery = this._matchFunction(searchConfig);
if (!matchesQuery)
return;
this._searchResults = [];
for (var current = this.children[0]; current; current = current.traverseNextNode(false, null, false)) {
if (matchesQuery(current))
this._searchResults.push({ profileNode: current });
}
this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1;
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
},
/**
* @override
*/
searchCanceled: function()
{
if (this._searchResults) {
for (var i = 0; i < this._searchResults.length; ++i) {
var profileNode = this._searchResults[i].profileNode;
delete profileNode._searchMatchedSelfColumn;
delete profileNode._searchMatchedTotalColumn;
delete profileNode._searchMatchedFunctionColumn;
profileNode.refresh();
}
}
this._searchResults = [];
this._searchResultIndex = -1;
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._searchResultIndex = (this._searchResultIndex + 1) % this._searchResults.length;
this._jumpToSearchResult(this._searchResultIndex);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._searchResultIndex = (this._searchResultIndex - 1 + this._searchResults.length) % this._searchResults.length;
this._jumpToSearchResult(this._searchResultIndex);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
/**
* @param {number} index
*/
_jumpToSearchResult: function(index)
{
var searchResult = this._searchResults[index];
if (!searchResult)
return;
var profileNode = searchResult.profileNode;
profileNode.revealAndSelect();
this._searchableView.updateCurrentMatchIndex(index);
}
}
WebInspector.ProfileDataGridTree.propertyComparators = [{}, {}];
/**
* @param {string} property
* @param {boolean} isAscending
* @return {function(!Object.<string, *>, !Object.<string, *>)}
*/
WebInspector.ProfileDataGridTree.propertyComparator = function(property, isAscending)
{
var comparator = WebInspector.ProfileDataGridTree.propertyComparators[(isAscending ? 1 : 0)][property];
if (!comparator) {
if (isAscending) {
comparator = function(lhs, rhs)
{
if (lhs[property] < rhs[property])
return -1;
if (lhs[property] > rhs[property])
return 1;
return 0;
};
} else {
comparator = function(lhs, rhs)
{
if (lhs[property] > rhs[property])
return -1;
if (lhs[property] < rhs[property])
return 1;
return 0;
};
}
WebInspector.ProfileDataGridTree.propertyComparators[(isAscending ? 1 : 0)][property] = comparator;
}
return comparator;
}
/**
* @interface
*/
WebInspector.ProfileDataGridNode.Formatter = function() { }
WebInspector.ProfileDataGridNode.Formatter.prototype = {
/**
* @param {number} value
* @param {!WebInspector.ProfileDataGridNode} node
* @return {string}
*/
formatValue: function(value, node) { },
/**
* @param {number} value
* @param {!WebInspector.ProfileDataGridNode} node
* @return {string}
*/
formatPercent: function(value, node) { },
/**
* @param {!WebInspector.ProfileDataGridNode} node
* @return {!Element}
*/
linkifyNode: function(node) { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 | 2 1 1 1 1 | /**
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.FlameChartDataProvider}
* @param {!WebInspector.CPUProfileDataModel} cpuProfile
* @param {?WebInspector.Target} target
*/
WebInspector.CPUFlameChartDataProvider = function(cpuProfile, target)
{
WebInspector.FlameChartDataProvider.call(this);
this._cpuProfile = cpuProfile;
this._target = target;
this._colorGenerator = WebInspector.CPUFlameChartDataProvider.colorGenerator();
}
WebInspector.CPUFlameChartDataProvider.prototype = {
/**
* @override
* @return {number}
*/
barHeight: function()
{
return 15;
},
/**
* @override
* @return {number}
*/
textBaseline: function()
{
return 4;
},
/**
* @override
* @return {number}
*/
textPadding: function()
{
return 2;
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
* @return {?Array.<number>}
*/
dividerOffsets: function(startTime, endTime)
{
return null;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._cpuProfile.profileStartTime;
},
/**
* @override
* @return {number}
*/
totalTime: function()
{
return this._cpuProfile.profileHead.totalTime;
},
/**
* @override
* @return {number}
*/
maxStackDepth: function()
{
return this._maxStackDepth;
},
/**
* @override
* @return {?WebInspector.FlameChart.TimelineData}
*/
timelineData: function()
{
return this._timelineData || this._calculateTimelineData();
},
/**
* @return {!WebInspector.FlameChart.TimelineData}
*/
_calculateTimelineData: function()
{
/**
* @constructor
* @param {number} depth
* @param {number} duration
* @param {number} startTime
* @param {number} selfTime
* @param {!ProfilerAgent.CPUProfileNode} node
*/
function ChartEntry(depth, duration, startTime, selfTime, node)
{
this.depth = depth;
this.duration = duration;
this.startTime = startTime;
this.selfTime = selfTime;
this.node = node;
}
/** @type {!Array.<?ChartEntry>} */
var entries = [];
/** @type {!Array.<number>} */
var stack = [];
var maxDepth = 5;
function onOpenFrame()
{
stack.push(entries.length);
// Reserve space for the entry, as they have to be ordered by startTime.
// The entry itself will be put there in onCloseFrame.
entries.push(null);
}
function onCloseFrame(depth, node, startTime, totalTime, selfTime)
{
var index = stack.pop();
entries[index] = new ChartEntry(depth, totalTime, startTime, selfTime, node);
maxDepth = Math.max(maxDepth, depth);
}
this._cpuProfile.forEachFrame(onOpenFrame, onCloseFrame);
/** @type {!Array.<!ProfilerAgent.CPUProfileNode>} */
var entryNodes = new Array(entries.length);
var entryLevels = new Uint8Array(entries.length);
var entryTotalTimes = new Float32Array(entries.length);
var entrySelfTimes = new Float32Array(entries.length);
var entryStartTimes = new Float64Array(entries.length);
var minimumBoundary = this.minimumBoundary();
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
entryNodes[i] = entry.node;
entryLevels[i] = entry.depth;
entryTotalTimes[i] = entry.duration;
entryStartTimes[i] = entry.startTime;
entrySelfTimes[i] = entry.selfTime;
}
this._maxStackDepth = maxDepth;
this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
/** @type {!Array.<!ProfilerAgent.CPUProfileNode>} */
this._entryNodes = entryNodes;
this._entrySelfTimes = entrySelfTimes;
return this._timelineData;
},
/**
* @param {number} ms
* @return {string}
*/
_millisecondsToString: function(ms)
{
if (ms === 0)
return "0";
if (ms < 1000)
return WebInspector.UIString("%.1f\u2009ms", ms);
return Number.secondsToString(ms / 1000, true);
},
/**
* @override
* @param {number} entryIndex
* @return {?Array<!{title: string, value: (string|!Element)}>}
*/
prepareHighlightedEntryInfo: function(entryIndex)
{
var timelineData = this._timelineData;
var node = this._entryNodes[entryIndex];
if (!node)
return null;
var entryInfo = [];
/**
* @param {string} title
* @param {string} value
*/
function pushEntryInfoRow(title, value)
{
entryInfo.push({ title: title, value: value });
}
var name = WebInspector.beautifyFunctionName(node.functionName);
pushEntryInfoRow(WebInspector.UIString("Name"), name);
var selfTime = this._millisecondsToString(this._entrySelfTimes[entryIndex]);
var totalTime = this._millisecondsToString(timelineData.entryTotalTimes[entryIndex]);
pushEntryInfoRow(WebInspector.UIString("Self time"), selfTime);
pushEntryInfoRow(WebInspector.UIString("Total time"), totalTime);
var callFrame = /** @type {!RuntimeAgent.CallFrame} */ (node);
var text = (new WebInspector.Linkifier()).linkifyConsoleCallFrame(this._target, callFrame).textContent;
pushEntryInfoRow(WebInspector.UIString("URL"), text);
pushEntryInfoRow(WebInspector.UIString("Aggregated self time"), Number.secondsToString(node.selfTime / 1000, true));
pushEntryInfoRow(WebInspector.UIString("Aggregated total time"), Number.secondsToString(node.totalTime / 1000, true));
if (node.deoptReason && node.deoptReason !== "no reason")
pushEntryInfoRow(WebInspector.UIString("Not optimized"), node.deoptReason);
return entryInfo;
},
/**
* @override
* @param {number} entryIndex
* @return {boolean}
*/
canJumpToEntry: function(entryIndex)
{
return this._entryNodes[entryIndex].scriptId !== "0";
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
entryTitle: function(entryIndex)
{
var node = this._entryNodes[entryIndex];
return WebInspector.beautifyFunctionName(node.functionName);
},
/**
* @override
* @param {number} entryIndex
* @return {?string}
*/
entryFont: function(entryIndex)
{
if (!this._font) {
this._font = (this.barHeight() - 4) + "px " + WebInspector.fontFamily();
this._boldFont = "bold " + this._font;
}
var node = this._entryNodes[entryIndex];
var reason = node.deoptReason;
return (reason && reason !== "no reason") ? this._boldFont : this._font;
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
entryColor: function(entryIndex)
{
var node = this._entryNodes[entryIndex];
// For idle and program, we want different 'shades of gray', so we fallback to functionName as scriptId = 0
// For rest of nodes e.g eval scripts, if url is empty then scriptId will be guaranteed to be non-zero
return this._colorGenerator.colorForID(node.url || (node.scriptId !== "0" ? node.scriptId : node.functionName));
},
/**
* @override
* @param {number} entryIndex
* @param {!CanvasRenderingContext2D} context
* @param {?string} text
* @param {number} barX
* @param {number} barY
* @param {number} barWidth
* @param {number} barHeight
* @return {boolean}
*/
decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight)
{
return false;
},
/**
* @override
* @param {number} entryIndex
* @return {boolean}
*/
forceDecoration: function(entryIndex)
{
return false;
},
/**
* @override
* @param {number} entryIndex
* @return {!{startTime: number, endTime: number}}
*/
highlightTimeRange: function(entryIndex)
{
var startTime = this._timelineData.entryStartTimes[entryIndex];
return {
startTime: startTime,
endTime: startTime + this._timelineData.entryTotalTimes[entryIndex]
};
},
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return 15;
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
textColor: function(entryIndex)
{
return "#333";
}
}
/**
* @return {!WebInspector.FlameChart.ColorGenerator}
*/
WebInspector.CPUFlameChartDataProvider.colorGenerator = function()
{
if (!WebInspector.CPUFlameChartDataProvider._colorGenerator) {
var colorGenerator = new WebInspector.FlameChart.ColorGenerator(
{ min: 30, max: 330 },
{ min: 50, max: 80, count: 5 },
{ min: 80, max: 90, count: 3 });
colorGenerator.setColorForID("(idle)", "hsl(0, 0%, 94%)");
colorGenerator.setColorForID("(program)", "hsl(0, 0%, 80%)");
colorGenerator.setColorForID("(garbage collector)", "hsl(0, 0%, 80%)");
WebInspector.CPUFlameChartDataProvider._colorGenerator = colorGenerator;
}
return WebInspector.CPUFlameChartDataProvider._colorGenerator;
}
/**
* @constructor
* @implements {WebInspector.Searchable}
* @extends {WebInspector.VBox}
* @param {!WebInspector.SearchableView} searchableView
* @param {!WebInspector.FlameChartDataProvider} dataProvider
*/
WebInspector.CPUProfileFlameChart = function(searchableView, dataProvider)
{
WebInspector.VBox.call(this);
this.element.id = "cpu-flame-chart";
this._searchableView = searchableView;
this._overviewPane = new WebInspector.CPUProfileFlameChart.OverviewPane(dataProvider);
this._overviewPane.show(this.element);
this._mainPane = new WebInspector.FlameChart(dataProvider, this._overviewPane);
this._mainPane.show(this.element);
this._mainPane.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
this._overviewPane.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
this._dataProvider = dataProvider;
this._searchResults = [];
}
WebInspector.CPUProfileFlameChart.prototype = {
focus: function()
{
this._mainPane.focus();
},
/**
* @param {!WebInspector.Event} event
*/
_onWindowChanged: function(event)
{
var windowLeft = event.data.windowTimeLeft;
var windowRight = event.data.windowTimeRight;
this._mainPane.setWindowTimes(windowLeft, windowRight);
},
/**
* @param {number} timeLeft
* @param {number} timeRight
*/
selectRange: function(timeLeft, timeRight)
{
this._overviewPane._selectRange(timeLeft, timeRight);
},
/**
* @param {!WebInspector.Event} event
*/
_onEntrySelected: function(event)
{
this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, event.data);
},
update: function()
{
this._overviewPane.update();
this._mainPane.update();
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var matcher = createPlainTextSearchRegex(searchConfig.query, searchConfig.caseSensitive ? "": "i");
var selectedEntryIndex = this._searchResultIndex !== -1 ? this._searchResults[this._searchResultIndex] : -1;
this._searchResults = [];
var entriesCount = this._dataProvider._entryNodes.length;
for (var index = 0; index < entriesCount; ++index) {
if (this._dataProvider.entryTitle(index).match(matcher))
this._searchResults.push(index);
}
if (this._searchResults.length) {
this._searchResultIndex = this._searchResults.indexOf(selectedEntryIndex);
if (this._searchResultIndex === -1)
this._searchResultIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
} else {
this.searchCanceled();
}
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
},
/**
* @override
*/
searchCanceled: function()
{
this._mainPane.setSelectedEntry(-1);
this._searchResults = [];
this._searchResultIndex = -1;
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
this._searchResultIndex = (this._searchResultIndex + 1) % this._searchResults.length;
this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
this._searchResultIndex = (this._searchResultIndex - 1 + this._searchResults.length) % this._searchResults.length;
this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
__proto__: WebInspector.VBox.prototype
};
/**
* @constructor
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.CPUProfileFlameChart.OverviewCalculator = function()
{
}
WebInspector.CPUProfileFlameChart.OverviewCalculator.prototype = {
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return 0;
},
/**
* @param {!WebInspector.CPUProfileFlameChart.OverviewPane} overviewPane
*/
_updateBoundaries: function(overviewPane)
{
this._minimumBoundaries = overviewPane._dataProvider.minimumBoundary();
var totalTime = overviewPane._dataProvider.totalTime();
this._maximumBoundaries = this._minimumBoundaries + totalTime;
this._xScaleFactor = overviewPane._overviewContainer.clientWidth / totalTime;
},
/**
* @override
* @param {number} time
* @return {number}
*/
computePosition: function(time)
{
return (time - this._minimumBoundaries) * this._xScaleFactor;
},
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.secondsToString((value - this._minimumBoundaries) / 1000, !!precision);
},
/**
* @override
* @return {number}
*/
maximumBoundary: function()
{
return this._maximumBoundaries;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._minimumBoundaries;
},
/**
* @override
* @return {number}
*/
zeroTime: function()
{
return this._minimumBoundaries;
},
/**
* @override
* @return {number}
*/
boundarySpan: function()
{
return this._maximumBoundaries - this._minimumBoundaries;
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.FlameChartDelegate}
* @param {!WebInspector.FlameChartDataProvider} dataProvider
*/
WebInspector.CPUProfileFlameChart.OverviewPane = function(dataProvider)
{
WebInspector.VBox.call(this);
this.element.classList.add("cpu-profile-flame-chart-overview-pane");
this._overviewContainer = this.element.createChild("div", "cpu-profile-flame-chart-overview-container");
this._overviewGrid = new WebInspector.OverviewGrid("cpu-profile-flame-chart");
this._overviewGrid.element.classList.add("fill");
this._overviewCanvas = this._overviewContainer.createChild("canvas", "cpu-profile-flame-chart-overview-canvas");
this._overviewContainer.appendChild(this._overviewGrid.element);
this._overviewCalculator = new WebInspector.CPUProfileFlameChart.OverviewCalculator();
this._dataProvider = dataProvider;
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
}
WebInspector.CPUProfileFlameChart.OverviewPane.prototype = {
/**
* @override
* @param {number} windowStartTime
* @param {number} windowEndTime
*/
requestWindowTimes: function(windowStartTime, windowEndTime)
{
this._selectRange(windowStartTime, windowEndTime);
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
*/
updateRangeSelection: function(startTime, endTime)
{
},
/**
* @override
*/
endRangeSelection: function()
{
},
/**
* @param {number} timeLeft
* @param {number} timeRight
*/
_selectRange: function(timeLeft, timeRight)
{
var startTime = this._dataProvider.minimumBoundary();
var totalTime = this._dataProvider.totalTime();
this._overviewGrid.setWindow((timeLeft - startTime) / totalTime, (timeRight - startTime) / totalTime);
},
/**
* @param {!WebInspector.Event} event
*/
_onWindowChanged: function(event)
{
var startTime = this._dataProvider.minimumBoundary();
var totalTime = this._dataProvider.totalTime();
var data = {
windowTimeLeft: startTime + this._overviewGrid.windowLeft() * totalTime,
windowTimeRight: startTime + this._overviewGrid.windowRight() * totalTime
};
this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged, data);
},
/**
* @return {?WebInspector.FlameChart.TimelineData}
*/
_timelineData: function()
{
return this._dataProvider.timelineData();
},
onResize: function()
{
this._scheduleUpdate();
},
_scheduleUpdate: function()
{
if (this._updateTimerId)
return;
this._updateTimerId = this.element.window().requestAnimationFrame(this.update.bind(this));
},
update: function()
{
this._updateTimerId = 0;
var timelineData = this._timelineData();
if (!timelineData)
return;
this._resetCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - WebInspector.FlameChart.DividersBarHeight);
this._overviewCalculator._updateBoundaries(this);
this._overviewGrid.updateDividers(this._overviewCalculator);
this._drawOverviewCanvas();
},
_drawOverviewCanvas: function()
{
var canvasWidth = this._overviewCanvas.width;
var canvasHeight = this._overviewCanvas.height;
var drawData = this._calculateDrawData(canvasWidth);
var context = this._overviewCanvas.getContext("2d");
var ratio = window.devicePixelRatio;
var offsetFromBottom = ratio;
var lineWidth = 1;
var yScaleFactor = canvasHeight / (this._dataProvider.maxStackDepth() * 1.1);
context.lineWidth = lineWidth;
context.translate(0.5, 0.5);
context.strokeStyle = "rgba(20,0,0,0.4)";
context.fillStyle = "rgba(214,225,254,0.8)";
context.moveTo(-lineWidth, canvasHeight + lineWidth);
context.lineTo(-lineWidth, Math.round(canvasHeight - drawData[0] * yScaleFactor - offsetFromBottom));
var value;
for (var x = 0; x < canvasWidth; ++x) {
value = Math.round(canvasHeight - drawData[x] * yScaleFactor - offsetFromBottom);
context.lineTo(x, value);
}
context.lineTo(canvasWidth + lineWidth, value);
context.lineTo(canvasWidth + lineWidth, canvasHeight + lineWidth);
context.fill();
context.stroke();
context.closePath();
},
/**
* @param {number} width
* @return {!Uint8Array}
*/
_calculateDrawData: function(width)
{
var dataProvider = this._dataProvider;
var timelineData = this._timelineData();
var entryStartTimes = timelineData.entryStartTimes;
var entryTotalTimes = timelineData.entryTotalTimes;
var entryLevels = timelineData.entryLevels;
var length = entryStartTimes.length;
var minimumBoundary = this._dataProvider.minimumBoundary();
var drawData = new Uint8Array(width);
var scaleFactor = width / dataProvider.totalTime();
for (var entryIndex = 0; entryIndex < length; ++entryIndex) {
var start = Math.floor((entryStartTimes[entryIndex] - minimumBoundary) * scaleFactor);
var finish = Math.floor((entryStartTimes[entryIndex] - minimumBoundary + entryTotalTimes[entryIndex]) * scaleFactor);
for (var x = start; x <= finish; ++x)
drawData[x] = Math.max(drawData[x], entryLevels[entryIndex] + 1);
}
return drawData;
},
/**
* @param {number} width
* @param {number} height
*/
_resetCanvas: function(width, height)
{
var ratio = window.devicePixelRatio;
this._overviewCanvas.width = width * ratio;
this._overviewCanvas.height = height * ratio;
this._overviewCanvas.style.width = width + "px";
this._overviewCanvas.style.height = height + "px";
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | 2 | /*
* Copyright (C) 2009 280 North Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.ProfileDataGridNode}
* @param {!ProfilerAgent.CPUProfileNode} profileNode
* @param {!WebInspector.TopDownProfileDataGridTree} owningTree
*/
WebInspector.TopDownProfileDataGridNode = function(profileNode, owningTree)
{
var hasChildren = !!(profileNode.children && profileNode.children.length);
WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, hasChildren);
this._remainingChildren = profileNode.children;
}
WebInspector.TopDownProfileDataGridNode.prototype = {
/**
* @override
*/
populateChildren: function()
{
WebInspector.TopDownProfileDataGridNode._sharedPopulate(this);
},
__proto__: WebInspector.ProfileDataGridNode.prototype
}
/**
* @param {!WebInspector.TopDownProfileDataGridNode|!WebInspector.TopDownProfileDataGridTree} container
*/
WebInspector.TopDownProfileDataGridNode._sharedPopulate = function(container)
{
var children = container._remainingChildren;
var childrenLength = children.length;
for (var i = 0; i < childrenLength; ++i)
container.appendChild(new WebInspector.TopDownProfileDataGridNode(children[i], /** @type {!WebInspector.TopDownProfileDataGridTree} */(container.tree)));
container._remainingChildren = null;
}
/**
* @param {!WebInspector.TopDownProfileDataGridNode|!WebInspector.TopDownProfileDataGridTree} container
* @param {number} aCallUID
*/
WebInspector.TopDownProfileDataGridNode._excludeRecursively = function(container, aCallUID)
{
if (container._remainingChildren)
container.populate();
container.save();
var children = container.children;
var index = container.children.length;
while (index--)
WebInspector.TopDownProfileDataGridNode._excludeRecursively(children[index], aCallUID);
var child = container.childrenByCallUID[aCallUID];
if (child)
WebInspector.ProfileDataGridNode.merge(container, child, true);
}
/**
* @constructor
* @extends {WebInspector.ProfileDataGridTree}
* @param {!WebInspector.ProfileDataGridNode.Formatter} formatter
* @param {!WebInspector.SearchableView} searchableView
* @param {!ProfilerAgent.CPUProfileNode} rootProfileNode
* @param {number} totalTime
*/
WebInspector.TopDownProfileDataGridTree = function(formatter, searchableView, rootProfileNode, totalTime)
{
WebInspector.ProfileDataGridTree.call(this, formatter, searchableView, totalTime);
this._remainingChildren = rootProfileNode.children;
WebInspector.ProfileDataGridNode.populate(this);
}
WebInspector.TopDownProfileDataGridTree.prototype = {
/**
* @param {!WebInspector.ProfileDataGridNode} profileDataGridNode
*/
focus: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this.save();
profileDataGridNode.savePosition();
this.children = [profileDataGridNode];
this.totalTime = profileDataGridNode.totalTime;
},
/**
* @param {!WebInspector.ProfileDataGridNode} profileDataGridNode
*/
exclude: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this.save();
WebInspector.TopDownProfileDataGridNode._excludeRecursively(this, profileDataGridNode.callUID);
if (this.lastComparator)
this.sort(this.lastComparator, true);
},
restore: function()
{
if (!this._savedChildren)
return;
this.children[0].restorePosition();
WebInspector.ProfileDataGridTree.prototype.restore.call(this);
},
/**
* @override
*/
populateChildren: function()
{
WebInspector.TopDownProfileDataGridNode._sharedPopulate(this);
},
__proto__: WebInspector.ProfileDataGridTree.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.Searchable}
* @extends {WebInspector.VBox}
* @param {!WebInspector.CPUProfileHeader} profileHeader
*/
WebInspector.CPUProfileView = function(profileHeader)
{
WebInspector.VBox.call(this);
this.element.classList.add("cpu-profile-view");
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.setPlaceholder(WebInspector.UIString("Find by cost (>50ms), name or file"));
this._searchableView.show(this.element);
this._viewType = WebInspector.settings.createSetting("cpuProfilerView", WebInspector.CPUProfileView._TypeHeavy);
this._nodeFormatter = new WebInspector.CPUProfileView.NodeFormatter(this);
var columns = [];
columns.push({id: "self", title: WebInspector.UIString("Self"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true});
columns.push({id: "total", title: WebInspector.UIString("Total"), width: "120px", sortable: true});
columns.push({id: "function", title: WebInspector.UIString("Function"), disclosure: true, sortable: true});
this.dataGrid = new WebInspector.DataGrid(columns);
this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortProfile, this);
this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._nodeSelected.bind(this, true));
this.dataGrid.addEventListener(WebInspector.DataGrid.Events.DeselectedNode, this._nodeSelected.bind(this, false));
this.viewSelectComboBox = new WebInspector.ToolbarComboBox(this._changeView.bind(this));
var options = {};
options[WebInspector.CPUProfileView._TypeFlame] = this.viewSelectComboBox.createOption(WebInspector.UIString("Chart"), "", WebInspector.CPUProfileView._TypeFlame);
options[WebInspector.CPUProfileView._TypeHeavy] = this.viewSelectComboBox.createOption(WebInspector.UIString("Heavy (Bottom Up)"), "", WebInspector.CPUProfileView._TypeHeavy);
options[WebInspector.CPUProfileView._TypeTree] = this.viewSelectComboBox.createOption(WebInspector.UIString("Tree (Top Down)"), "", WebInspector.CPUProfileView._TypeTree);
var optionName = this._viewType.get() || WebInspector.CPUProfileView._TypeFlame;
var option = options[optionName] || options[WebInspector.CPUProfileView._TypeFlame];
this.viewSelectComboBox.select(option);
this.focusButton = new WebInspector.ToolbarButton(WebInspector.UIString("Focus selected function"), "visibility-toolbar-item");
this.focusButton.setEnabled(false);
this.focusButton.addEventListener("click", this._focusClicked, this);
this.excludeButton = new WebInspector.ToolbarButton(WebInspector.UIString("Exclude selected function"), "delete-toolbar-item");
this.excludeButton.setEnabled(false);
this.excludeButton.addEventListener("click", this._excludeClicked, this);
this.resetButton = new WebInspector.ToolbarButton(WebInspector.UIString("Restore all functions"), "refresh-toolbar-item");
this.resetButton.setEnabled(false);
this.resetButton.addEventListener("click", this._resetClicked, this);
this._profileHeader = profileHeader;
this._linkifier = new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultFormatter(30));
this.profile = new WebInspector.CPUProfileDataModel(profileHeader._profile || profileHeader.protocolProfile());
this.totalCpuTime = this.profile.profileHead.totalTime;
this.totalCpuTime -= this.profile.idleNode ? this.profile.idleNode.totalTime : 0;
this._changeView();
if (this._flameChart)
this._flameChart.update();
}
WebInspector.CPUProfileView._TypeFlame = "Flame";
WebInspector.CPUProfileView._TypeTree = "Tree";
WebInspector.CPUProfileView._TypeHeavy = "Heavy";
WebInspector.CPUProfileView.prototype = {
focus: function()
{
if (this._flameChart)
this._flameChart.focus();
else
WebInspector.Widget.prototype.focus.call(this);
},
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._profileHeader.target();
},
/**
* @param {number} timeLeft
* @param {number} timeRight
*/
selectRange: function(timeLeft, timeRight)
{
if (!this._flameChart)
return;
this._flameChart.selectRange(timeLeft, timeRight);
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this.viewSelectComboBox, this.focusButton, this.excludeButton, this.resetButton];
},
/**
* @return {!WebInspector.ProfileDataGridTree}
*/
_getBottomUpProfileDataGridTree: function()
{
if (!this._bottomUpProfileDataGridTree)
this._bottomUpProfileDataGridTree = new WebInspector.BottomUpProfileDataGridTree(this._nodeFormatter, this._searchableView, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profile.profileHead), this.totalCpuTime);
return this._bottomUpProfileDataGridTree;
},
/**
* @return {!WebInspector.ProfileDataGridTree}
*/
_getTopDownProfileDataGridTree: function()
{
if (!this._topDownProfileDataGridTree)
this._topDownProfileDataGridTree = new WebInspector.TopDownProfileDataGridTree(this._nodeFormatter, this._searchableView, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profile.profileHead), this.totalCpuTime);
return this._topDownProfileDataGridTree;
},
willHide: function()
{
this._currentSearchResultIndex = -1;
},
refresh: function()
{
var selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null;
this.dataGrid.rootNode().removeChildren();
var children = this.profileDataGridTree.children;
var count = children.length;
for (var index = 0; index < count; ++index)
this.dataGrid.rootNode().appendChild(children[index]);
if (selectedProfileNode)
selectedProfileNode.selected = true;
},
refreshVisibleData: function()
{
var child = this.dataGrid.rootNode().children[0];
while (child) {
child.refresh();
child = child.traverseNextNode(false, null, true);
}
},
/**
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
/**
* @override
*/
searchCanceled: function()
{
this._searchableElement.searchCanceled();
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
this._searchableElement.performSearch(searchConfig, shouldJump, jumpBackwards);
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
this._searchableElement.jumpToNextSearchResult();
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
this._searchableElement.jumpToPreviousSearchResult();
},
_ensureFlameChartCreated: function()
{
if (this._flameChart)
return;
this._dataProvider = new WebInspector.CPUFlameChartDataProvider(this.profile, this._profileHeader.target());
this._flameChart = new WebInspector.CPUProfileFlameChart(this._searchableView, this._dataProvider);
this._flameChart.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_onEntrySelected: function(event)
{
var entryIndex = event.data;
var node = this._dataProvider._entryNodes[entryIndex];
var debuggerModel = this._profileHeader._debuggerModel;
if (!node || !node.scriptId || !debuggerModel)
return;
var script = debuggerModel.scriptForId(node.scriptId);
if (!script)
return;
var location = /** @type {!WebInspector.DebuggerModel.Location} */ (debuggerModel.createRawLocation(script, node.lineNumber - 1, node.columnNumber ? node.columnNumber - 1 : node.columnNumber));
WebInspector.Revealer.reveal(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location));
},
_changeView: function()
{
if (!this.profile)
return;
this._searchableView.closeSearch();
if (this._visibleView)
this._visibleView.detach();
this._viewType.set(this.viewSelectComboBox.selectedOption().value);
switch (this._viewType.get()) {
case WebInspector.CPUProfileView._TypeFlame:
this._ensureFlameChartCreated();
this._visibleView = this._flameChart;
this._searchableElement = this._flameChart;
break;
case WebInspector.CPUProfileView._TypeTree:
this.profileDataGridTree = this._getTopDownProfileDataGridTree();
this._sortProfile();
this._visibleView = this.dataGrid.asWidget();
this._searchableElement = this.profileDataGridTree;
break;
case WebInspector.CPUProfileView._TypeHeavy:
this.profileDataGridTree = this._getBottomUpProfileDataGridTree();
this._sortProfile();
this._visibleView = this.dataGrid.asWidget();
this._searchableElement = this.profileDataGridTree;
break;
}
var isFlame = this._viewType.get() === WebInspector.CPUProfileView._TypeFlame;
this.focusButton.setVisible(!isFlame);
this.excludeButton.setVisible(!isFlame);
this.resetButton.setVisible(!isFlame);
this._visibleView.show(this._searchableView.element);
},
/**
* @param {boolean} selected
*/
_nodeSelected: function(selected)
{
this.focusButton.setEnabled(selected);
this.excludeButton.setEnabled(selected);
},
_focusClicked: function(event)
{
if (!this.dataGrid.selectedNode)
return;
this.resetButton.setEnabled(true);
this.profileDataGridTree.focus(this.dataGrid.selectedNode);
this.refresh();
this.refreshVisibleData();
},
_excludeClicked: function(event)
{
var selectedNode = this.dataGrid.selectedNode;
if (!selectedNode)
return;
selectedNode.deselect();
this.resetButton.setEnabled(true);
this.profileDataGridTree.exclude(selectedNode);
this.refresh();
this.refreshVisibleData();
},
_resetClicked: function(event)
{
this.resetButton.setEnabled(false);
this.profileDataGridTree.restore();
this._linkifier.reset();
this.refresh();
this.refreshVisibleData();
},
_sortProfile: function()
{
var sortAscending = this.dataGrid.isSortOrderAscending();
var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier();
var sortProperty = {
"self": "selfTime",
"total": "totalTime",
"function": "functionName"
}[sortColumnIdentifier];
this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyComparator(sortProperty, sortAscending));
this.refresh();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileType}
*/
WebInspector.CPUProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.CPUProfileType.TypeId, WebInspector.UIString("Collect JavaScript CPU Profile"));
this._recording = false;
this._nextAnonymousConsoleProfileNumber = 1;
this._anonymousConsoleProfileIdToTitle = {};
WebInspector.CPUProfileType.instance = this;
WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel, WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileStarted, this._consoleProfileStarted, this);
WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel, WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileFinished, this._consoleProfileFinished, this);
}
WebInspector.CPUProfileType.TypeId = "CPU";
WebInspector.CPUProfileType.prototype = {
/**
* @override
* @return {string}
*/
fileExtension: function()
{
return ".cpuprofile";
},
get buttonTooltip()
{
return this._recording ? WebInspector.UIString("Stop CPU profiling") : WebInspector.UIString("Start CPU profiling");
},
/**
* @override
* @return {boolean}
*/
buttonClicked: function()
{
if (this._recording) {
this.stopRecordingProfile();
return false;
} else {
this.startRecordingProfile();
return true;
}
},
get treeItemTitle()
{
return WebInspector.UIString("CPU PROFILES");
},
get description()
{
return WebInspector.UIString("CPU profiles show where the execution time is spent in your page's JavaScript functions.");
},
/**
* @param {!WebInspector.Event} event
*/
_consoleProfileStarted: function(event)
{
var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (event.data);
var resolvedTitle = data.title;
if (!resolvedTitle) {
resolvedTitle = WebInspector.UIString("Profile %s", this._nextAnonymousConsoleProfileNumber++);
this._anonymousConsoleProfileIdToTitle[data.id] = resolvedTitle;
}
this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profile, data.scriptLocation, WebInspector.UIString("Profile '%s' started.", resolvedTitle));
},
/**
* @param {!WebInspector.Event} event
*/
_consoleProfileFinished: function(event)
{
var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (event.data);
var cpuProfile = /** @type {!ProfilerAgent.CPUProfile} */ (data.cpuProfile);
var resolvedTitle = data.title;
if (typeof resolvedTitle === "undefined") {
resolvedTitle = this._anonymousConsoleProfileIdToTitle[data.id];
delete this._anonymousConsoleProfileIdToTitle[data.id];
}
var profile = new WebInspector.CPUProfileHeader(data.scriptLocation.target(), this, resolvedTitle);
profile.setProtocolProfile(cpuProfile);
this.addProfile(profile);
this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation, WebInspector.UIString("Profile '%s' finished.", resolvedTitle));
},
/**
* @param {string} type
* @param {!WebInspector.DebuggerModel.Location} scriptLocation
* @param {string} messageText
*/
_addMessageToConsole: function(type, scriptLocation, messageText)
{
var script = scriptLocation.script();
var target = scriptLocation.target();
var message = new WebInspector.ConsoleMessage(
target,
WebInspector.ConsoleMessage.MessageSource.ConsoleAPI,
WebInspector.ConsoleMessage.MessageLevel.Debug,
messageText,
type,
undefined,
undefined,
undefined,
undefined,
[{
functionName: "",
scriptId: scriptLocation.scriptId,
url: script ? script.contentURL() : "",
lineNumber: scriptLocation.lineNumber,
columnNumber: scriptLocation.columnNumber || 0
}]);
target.consoleModel.addMessage(message);
},
startRecordingProfile: function()
{
var target = WebInspector.context.flavor(WebInspector.Target);
if (this._profileBeingRecorded || !target)
return;
var profile = new WebInspector.CPUProfileHeader(target, this);
this.setProfileBeingRecorded(profile);
WebInspector.targetManager.suspendAllTargets();
this.addProfile(profile);
profile.updateStatus(WebInspector.UIString("Recording\u2026"));
this._recording = true;
target.cpuProfilerModel.startRecording();
},
stopRecordingProfile: function()
{
this._recording = false;
if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
return;
var recordedProfile;
/**
* @param {?ProfilerAgent.CPUProfile} profile
* @this {WebInspector.CPUProfileType}
*/
function didStopProfiling(profile)
{
if (!this._profileBeingRecorded)
return;
console.assert(profile);
this._profileBeingRecorded.setProtocolProfile(profile);
this._profileBeingRecorded.updateStatus("");
recordedProfile = this._profileBeingRecorded;
this.setProfileBeingRecorded(null);
}
/**
* @this {WebInspector.CPUProfileType}
*/
function fireEvent()
{
this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, recordedProfile);
}
this._profileBeingRecorded.target().cpuProfilerModel.stopRecording()
.then(didStopProfiling.bind(this))
.then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targetManager))
.then(fireEvent.bind(this));
},
/**
* @override
* @param {string} title
* @return {!WebInspector.ProfileHeader}
*/
createProfileLoadedFromFile: function(title)
{
return new WebInspector.CPUProfileHeader(null, this, title);
},
/**
* @override
*/
profileBeingRecordedRemoved: function()
{
this.stopRecordingProfile();
},
__proto__: WebInspector.ProfileType.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileHeader}
* @implements {WebInspector.OutputStream}
* @implements {WebInspector.OutputStreamDelegate}
* @param {?WebInspector.Target} target
* @param {!WebInspector.CPUProfileType} type
* @param {string=} title
*/
WebInspector.CPUProfileHeader = function(target, type, title)
{
WebInspector.ProfileHeader.call(this, target, type, title || WebInspector.UIString("Profile %d", type.nextProfileUid()));
this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
this._tempFile = null;
}
WebInspector.CPUProfileHeader.prototype = {
/**
* @override
*/
onTransferStarted: function()
{
this._jsonifiedProfile = "";
this.updateStatus(WebInspector.UIString("Loading\u2026 %s", Number.bytesToString(this._jsonifiedProfile.length)), true);
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader)
{
this.updateStatus(WebInspector.UIString("Loading\u2026 %d%%", Number.bytesToString(this._jsonifiedProfile.length)));
},
/**
* @override
*/
onTransferFinished: function()
{
this.updateStatus(WebInspector.UIString("Parsing\u2026"), true);
this._profile = JSON.parse(this._jsonifiedProfile);
this._jsonifiedProfile = null;
this.updateStatus(WebInspector.UIString("Loaded"), false);
if (this._profileType.profileBeingRecorded() === this)
this._profileType.setProfileBeingRecorded(null);
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
* @param {!Event} e
*/
onError: function(reader, e)
{
var subtitle;
switch(e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
break;
case e.target.error.NOT_READABLE_ERR:
subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
break;
case e.target.error.ABORT_ERR:
return;
default:
subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
}
this.updateStatus(subtitle);
},
/**
* @override
* @param {string} text
*/
write: function(text)
{
this._jsonifiedProfile += text;
},
/**
* @override
*/
close: function() { },
/**
* @override
*/
dispose: function()
{
this.removeTempFile();
},
/**
* @override
* @param {!WebInspector.ProfileType.DataDisplayDelegate} panel
* @return {!WebInspector.ProfileSidebarTreeElement}
*/
createSidebarTreeElement: function(panel)
{
return new WebInspector.ProfileSidebarTreeElement(panel, this, "profile-sidebar-tree-item");
},
/**
* @override
* @return {!WebInspector.CPUProfileView}
*/
createView: function()
{
return new WebInspector.CPUProfileView(this);
},
/**
* @override
* @return {boolean}
*/
canSaveToFile: function()
{
return !this.fromFile() && this._protocolProfile;
},
saveToFile: function()
{
var fileOutputStream = new WebInspector.FileOutputStream();
/**
* @param {boolean} accepted
* @this {WebInspector.CPUProfileHeader}
*/
function onOpenForSave(accepted)
{
if (!accepted)
return;
function didRead(data)
{
if (data)
fileOutputStream.write(data, fileOutputStream.close.bind(fileOutputStream));
else
fileOutputStream.close();
}
if (this._failedToCreateTempFile) {
WebInspector.console.error("Failed to open temp file with heap snapshot");
fileOutputStream.close();
} else if (this._tempFile) {
this._tempFile.read(didRead);
} else {
this._onTempFileReady = onOpenForSave.bind(this, accepted);
}
}
this._fileName = this._fileName || "CPU-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
fileOutputStream.open(this._fileName, onOpenForSave.bind(this));
},
/**
* @override
* @param {!File} file
*/
loadFromFile: function(file)
{
this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
var fileReader = new WebInspector.ChunkedFileReader(file, 10000000, this);
fileReader.start(this);
},
/**
* @return {?ProfilerAgent.CPUProfile}
*/
protocolProfile: function()
{
return this._protocolProfile;
},
/**
* @param {!ProfilerAgent.CPUProfile} cpuProfile
*/
setProtocolProfile: function(cpuProfile)
{
this._protocolProfile = cpuProfile;
this._saveProfileDataToTempFile(cpuProfile);
if (this.canSaveToFile())
this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);
},
/**
* @param {!ProfilerAgent.CPUProfile} data
*/
_saveProfileDataToTempFile: function(data)
{
var serializedData = JSON.stringify(data);
/**
* @this {WebInspector.CPUProfileHeader}
*/
function didCreateTempFile(tempFile)
{
this._writeToTempFile(tempFile, serializedData);
}
WebInspector.TempFile.create("cpu-profiler", String(this.uid))
.then(didCreateTempFile.bind(this));
},
/**
* @param {?WebInspector.TempFile} tempFile
* @param {string} serializedData
*/
_writeToTempFile: function(tempFile, serializedData)
{
this._tempFile = tempFile;
if (!tempFile) {
this._failedToCreateTempFile = true;
this._notifyTempFileReady();
return;
}
/**
* @param {number} fileSize
* @this {WebInspector.CPUProfileHeader}
*/
function didWriteToTempFile(fileSize)
{
if (!fileSize)
this._failedToCreateTempFile = true;
tempFile.finishWriting();
this._notifyTempFileReady();
}
tempFile.write([serializedData], didWriteToTempFile.bind(this));
},
_notifyTempFileReady: function()
{
if (this._onTempFileReady) {
this._onTempFileReady();
this._onTempFileReady = null;
}
},
__proto__: WebInspector.ProfileHeader.prototype
}
/**
* @implements {WebInspector.ProfileDataGridNode.Formatter}
* @constructor
*/
WebInspector.CPUProfileView.NodeFormatter = function(profileView)
{
this._profileView = profileView;
}
WebInspector.CPUProfileView.NodeFormatter.prototype = {
/**
* @override
* @param {number} value
* @return {string}
*/
formatValue: function(value)
{
return WebInspector.UIString("%.1f\u2009ms", value);
},
/**
* @override
* @param {number} value
* @param {!WebInspector.ProfileDataGridNode} node
* @return {string}
*/
formatPercent: function(value, node)
{
return node.profileNode === this._profileView.profile.idleNode ? "" : WebInspector.UIString("%.2f\u2009%%", value);
},
/**
* @override
* @param {!WebInspector.ProfileDataGridNode} node
* @return {!Element}
*/
linkifyNode: function(node)
{
var callFrame = /** @type {!RuntimeAgent.CallFrame} */ (node.profileNode);
return this._profileView._linkifier.linkifyConsoleCallFrame(this._profileView.target(), callFrame, "profile-node-file");
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | 2 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.HeapSnapshotProgressEvent = {
Update: "ProgressUpdate",
BrokenSnapshot: "BrokenSnapshot"
};
WebInspector.HeapSnapshotCommon = {
}
WebInspector.HeapSnapshotCommon.baseSystemDistance = 100000000;
/**
* @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} nodesWithSingleCaller
* @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} branchingCallers
* @constructor
*/
WebInspector.HeapSnapshotCommon.AllocationNodeCallers = function(nodesWithSingleCaller, branchingCallers)
{
/** @type {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */
this.nodesWithSingleCaller = nodesWithSingleCaller;
/** @type {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */
this.branchingCallers = branchingCallers;
}
/**
* @param {number} nodeId
* @param {string} functionName
* @param {string} scriptName
* @param {number} scriptId
* @param {number} line
* @param {number} column
* @param {number} count
* @param {number} size
* @param {number} liveCount
* @param {number} liveSize
* @param {boolean} hasChildren
* @constructor
*/
WebInspector.HeapSnapshotCommon.SerializedAllocationNode = function(nodeId, functionName, scriptName, scriptId, line, column, count, size, liveCount, liveSize, hasChildren)
{
/** @type {number} */
this.id = nodeId;
/** @type {string} */
this.name = functionName;
/** @type {string} */
this.scriptName = scriptName;
/** @type {number} */
this.scriptId = scriptId;
/** @type {number} */
this.line = line;
/** @type {number} */
this.column = column;
/** @type {number} */
this.count = count;
/** @type {number} */
this.size = size;
/** @type {number} */
this.liveCount = liveCount;
/** @type {number} */
this.liveSize = liveSize;
/** @type {boolean} */
this.hasChildren = hasChildren;
}
/**
* @param {string} functionName
* @param {string} scriptName
* @param {number} scriptId
* @param {number} line
* @param {number} column
* @constructor
*/
WebInspector.HeapSnapshotCommon.AllocationStackFrame = function(functionName, scriptName, scriptId, line, column)
{
/** @type {string} */
this.functionName = functionName;
/** @type {string} */
this.scriptName = scriptName;
/** @type {number} */
this.scriptId = scriptId;
/** @type {number} */
this.line = line;
/** @type {number} */
this.column = column;
}
/**
* @constructor
* @param {number} id
* @param {string} name
* @param {number} distance
* @param {number} nodeIndex
* @param {number} retainedSize
* @param {number} selfSize
* @param {string} type
*/
WebInspector.HeapSnapshotCommon.Node = function(id, name, distance, nodeIndex, retainedSize, selfSize, type)
{
this.id = id;
this.name = name;
this.distance = distance;
this.nodeIndex = nodeIndex;
this.retainedSize = retainedSize;
this.selfSize = selfSize;
this.type = type;
this.canBeQueried = false;
this.detachedDOMTreeNode = false;
}
/**
* @constructor
* @param {string} name
* @param {!WebInspector.HeapSnapshotCommon.Node} node
* @param {string} type
* @param {number} edgeIndex
*/
WebInspector.HeapSnapshotCommon.Edge = function(name, node, type, edgeIndex)
{
this.name = name;
this.node = node;
this.type = type;
this.edgeIndex = edgeIndex;
};
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.Aggregate = function()
{
/** @type {number} */
this.count;
/** @type {number} */
this.distance;
/** @type {number} */
this.self;
/** @type {number} */
this.maxRet;
/** @type {number} */
this.type;
/** @type {string} */
this.name;
/** @type {!Array.<number>} */
this.idxs;
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.AggregateForDiff = function() {
/** @type {!Array.<number>} */
this.indexes = [];
/** @type {!Array.<string>} */
this.ids = [];
/** @type {!Array.<number>} */
this.selfSizes = [];
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.Diff = function()
{
/** @type {number} */
this.addedCount = 0;
/** @type {number} */
this.removedCount = 0;
/** @type {number} */
this.addedSize = 0;
/** @type {number} */
this.removedSize = 0;
/** @type {!Array.<number>} */
this.deletedIndexes = [];
/** @type {!Array.<number>} */
this.addedIndexes = [];
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.DiffForClass = function()
{
/** @type {number} */
this.addedCount;
/** @type {number} */
this.removedCount;
/** @type {number} */
this.addedSize;
/** @type {number} */
this.removedSize;
/** @type {!Array.<number>} */
this.deletedIndexes;
/** @type {!Array.<number>} */
this.addedIndexes;
/** @type {number} */
this.countDelta;
/** @type {number} */
this.sizeDelta;
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.ComparatorConfig = function()
{
/** @type {string} */
this.fieldName1;
/** @type {boolean} */
this.ascending1;
/** @type {string} */
this.fieldName2;
/** @type {boolean} */
this.ascending2;
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.WorkerCommand = function()
{
/** @type {number} */
this.callId;
/** @type {string} */
this.disposition;
/** @type {number} */
this.objectId;
/** @type {number} */
this.newObjectId;
/** @type {string} */
this.methodName;
/** @type {!Array.<*>} */
this.methodArguments;
/** @type {string} */
this.source;
}
/**
* @constructor
* @param {number} startPosition
* @param {number} endPosition
* @param {number} totalLength
* @param {!Array.<*>} items
*/
WebInspector.HeapSnapshotCommon.ItemsRange = function(startPosition, endPosition, totalLength, items)
{
/** @type {number} */
this.startPosition = startPosition;
/** @type {number} */
this.endPosition = endPosition;
/** @type {number} */
this.totalLength = totalLength;
/** @type {!Array.<*>} */
this.items = items;
}
/**
* @param {number} nodeCount
* @param {number} rootNodeIndex
* @param {number} totalSize
* @param {number} maxJSObjectId
* @constructor
*/
WebInspector.HeapSnapshotCommon.StaticData = function(nodeCount, rootNodeIndex, totalSize, maxJSObjectId)
{
/** @type {number} */
this.nodeCount = nodeCount;
/** @type {number} */
this.rootNodeIndex = rootNodeIndex;
/** @type {number} */
this.totalSize = totalSize;
/** @type {number} */
this.maxJSObjectId = maxJSObjectId;
}
/**
* @constructor
*/
WebInspector.HeapSnapshotCommon.Statistics = function()
{
/** @type {number} */
this.total;
/** @type {number} */
this.v8heap;
/** @type {number} */
this.native;
/** @type {number} */
this.code;
/** @type {number} */
this.jsArrays;
/** @type {number} */
this.strings;
/** @type {number} */
this.system;
}
/**
* @param {number=} minNodeId
* @param {number=} maxNodeId
* @constructor
*/
WebInspector.HeapSnapshotCommon.NodeFilter = function(minNodeId, maxNodeId)
{
/** @type {number|undefined} */
this.minNodeId = minNodeId;
/** @type {number|undefined} */
this.maxNodeId = maxNodeId;
/** @type {number|undefined} */
this.allocationNodeId;
}
WebInspector.HeapSnapshotCommon.NodeFilter.prototype =
{
/**
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} o
* @return {boolean}
*/
equals: function(o)
{
return this.minNodeId === o.minNodeId && this.maxNodeId === o.maxNodeId && this.allocationNodeId === o.allocationNodeId;
}
}
/**
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {boolean} shouldJump
* @param {boolean} jumpBackward
* @constructor
*/
WebInspector.HeapSnapshotCommon.SearchConfig = function(query, caseSensitive, isRegex, shouldJump, jumpBackward)
{
this.query = query;
this.caseSensitive = caseSensitive;
this.isRegex = isRegex;
this.shouldJump = shouldJump;
this.jumpBackward = jumpBackward;
}
/**
* @constructor
* @param {!Array.<number>} timestamps
* @param {!Array.<number>} lastAssignedIds
* @param {!Array.<number>} sizes
*/
WebInspector.HeapSnapshotCommon.Samples = function(timestamps, lastAssignedIds, sizes)
{
this.timestamps = timestamps;
this.lastAssignedIds = lastAssignedIds;
this.sizes = sizes;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | 2 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.DataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
WebInspector.HeapSnapshotSortableDataGrid = function(dataDisplayDelegate, columns)
{
WebInspector.DataGrid.call(this, columns);
this._dataDisplayDelegate = dataDisplayDelegate;
/**
* @type {number}
*/
this._recursiveSortingDepth = 0;
/**
* @type {?WebInspector.HeapSnapshotGridNode}
*/
this._highlightedNode = null;
/**
* @type {boolean}
*/
this._populatedAndSorted = false;
/**
* @type {?WebInspector.ToolbarInput}
*/
this._nameFilter = null;
this._nodeFilter = new WebInspector.HeapSnapshotCommon.NodeFilter();
this.addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
this.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this.sortingChanged, this);
}
WebInspector.HeapSnapshotSortableDataGrid.Events = {
ContentShown: "ContentShown",
SortingComplete: "SortingComplete"
}
WebInspector.HeapSnapshotSortableDataGrid.prototype = {
/**
* @return {!WebInspector.HeapSnapshotCommon.NodeFilter}
*/
nodeFilter: function()
{
return this._nodeFilter;
},
/**
* @param {!WebInspector.ToolbarInput} nameFilter
*/
setNameFilter: function(nameFilter)
{
this._nameFilter = nameFilter;
},
/**
* @return {number}
*/
defaultPopulateCount: function()
{
return 100;
},
_disposeAllNodes: function()
{
var children = this.topLevelNodes();
for (var i = 0, l = children.length; i < l; ++i)
children[i].dispose();
},
/**
* @override
*/
wasShown: function()
{
if (this._nameFilter) {
this._nameFilter.addEventListener(WebInspector.ToolbarInput.Event.TextChanged, this._onNameFilterChanged, this);
this.updateVisibleNodes(true);
}
if (this._populatedAndSorted)
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
},
_sortingComplete: function()
{
this.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
this._populatedAndSorted = true;
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
},
/**
* @override
*/
willHide: function()
{
if (this._nameFilter)
this._nameFilter.removeEventListener(WebInspector.ToolbarInput.Event.TextChanged, this._onNameFilterChanged, this);
this._clearCurrentHighlight();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Event} event
*/
populateContextMenu: function(contextMenu, event)
{
var td = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!td)
return;
var node = td.heapSnapshotNode;
/**
* @this {WebInspector.HeapSnapshotSortableDataGrid}
*/
function revealInSummaryView()
{
this._dataDisplayDelegate.showObject(node.snapshotNodeId, "Summary");
}
if (node instanceof WebInspector.HeapSnapshotRetainingObjectNode)
contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Summary ^view"), revealInSummaryView.bind(this));
},
resetSortingCache: function()
{
delete this._lastSortColumnIdentifier;
delete this._lastSortAscending;
},
/**
* @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
*/
topLevelNodes: function()
{
return this.rootNode().children;
},
/**
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} heapSnapshotObjectId
* @return {!Promise<?WebInspector.HeapSnapshotGridNode>}
*/
revealObjectByHeapSnapshotId: function(heapSnapshotObjectId)
{
return Promise.resolve(/** @type {?WebInspector.HeapSnapshotGridNode} */ (null));
},
/**
* @param {!WebInspector.HeapSnapshotGridNode} node
*/
highlightNode: function(node)
{
this._clearCurrentHighlight();
this._highlightedNode = node;
WebInspector.runCSSAnimationOnce(this._highlightedNode.element(), "highlighted-row");
},
nodeWasDetached: function(node)
{
if (this._highlightedNode === node)
this._clearCurrentHighlight();
},
_clearCurrentHighlight: function()
{
if (!this._highlightedNode)
return
this._highlightedNode.element().classList.remove("highlighted-row");
this._highlightedNode = null;
},
resetNameFilter: function()
{
this._nameFilter.setValue("");
},
_onNameFilterChanged: function()
{
this.updateVisibleNodes(true);
},
sortingChanged: function()
{
var sortAscending = this.isSortOrderAscending();
var sortColumnIdentifier = this.sortColumnIdentifier();
if (this._lastSortColumnIdentifier === sortColumnIdentifier && this._lastSortAscending === sortAscending)
return;
this._lastSortColumnIdentifier = sortColumnIdentifier;
this._lastSortAscending = sortAscending;
var sortFields = this._sortFields(sortColumnIdentifier, sortAscending);
function SortByTwoFields(nodeA, nodeB)
{
var field1 = nodeA[sortFields[0]];
var field2 = nodeB[sortFields[0]];
var result = field1 < field2 ? -1 : (field1 > field2 ? 1 : 0);
if (!sortFields[1])
result = -result;
if (result !== 0)
return result;
field1 = nodeA[sortFields[2]];
field2 = nodeB[sortFields[2]];
result = field1 < field2 ? -1 : (field1 > field2 ? 1 : 0);
if (!sortFields[3])
result = -result;
return result;
}
this._performSorting(SortByTwoFields);
},
_performSorting: function(sortFunction)
{
this.recursiveSortingEnter();
var children = this.allChildren(this.rootNode());
this.rootNode().removeChildren();
children.sort(sortFunction);
for (var i = 0, l = children.length; i < l; ++i) {
var child = children[i];
this.appendChildAfterSorting(child);
if (child.expanded)
child.sort();
}
this.recursiveSortingLeave();
},
appendChildAfterSorting: function(child)
{
var revealed = child.revealed;
this.rootNode().appendChild(child);
child.revealed = revealed;
},
recursiveSortingEnter: function()
{
++this._recursiveSortingDepth;
},
recursiveSortingLeave: function()
{
if (!this._recursiveSortingDepth)
return;
if (--this._recursiveSortingDepth)
return;
this.updateVisibleNodes(true);
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);
},
/**
* @param {boolean} force
*/
updateVisibleNodes: function(force)
{
},
/**
* @param {!WebInspector.DataGridNode} parent
* @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
*/
allChildren: function(parent)
{
return parent.children;
},
/**
* @param {!WebInspector.DataGridNode} parent
* @param {!WebInspector.DataGridNode} node
* @param {number} index
*/
insertChild: function(parent, node, index)
{
parent.insertChild(node, index);
},
/**
* @param {!WebInspector.HeapSnapshotGridNode} parent
* @param {number} index
*/
removeChildByIndex: function(parent, index)
{
parent.removeChild(parent.children[index]);
},
/**
* @param {!WebInspector.HeapSnapshotGridNode} parent
*/
removeAllChildren: function(parent)
{
parent.removeChildren();
},
__proto__: WebInspector.DataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotSortableDataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
WebInspector.HeapSnapshotViewportDataGrid = function(dataDisplayDelegate, columns)
{
WebInspector.HeapSnapshotSortableDataGrid.call(this, dataDisplayDelegate, columns);
this.scrollContainer.addEventListener("scroll", this._onScroll.bind(this), true);
this._topPaddingHeight = 0;
this._bottomPaddingHeight = 0;
}
WebInspector.HeapSnapshotViewportDataGrid.prototype = {
/**
* @override
* @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
*/
topLevelNodes: function()
{
return this.allChildren(this.rootNode());
},
appendChildAfterSorting: function(child)
{
// Do nothing here, it will be added in updateVisibleNodes.
},
/**
* @override
* @param {boolean} force
*/
updateVisibleNodes: function(force)
{
// Guard zone is used to ensure there are always some extra items
// above and below the viewport to support keyboard navigation.
var guardZoneHeight = 40;
var scrollHeight = this.scrollContainer.scrollHeight;
var scrollTop = this.scrollContainer.scrollTop;
var scrollBottom = scrollHeight - scrollTop - this.scrollContainer.offsetHeight;
scrollTop = Math.max(0, scrollTop - guardZoneHeight);
scrollBottom = Math.max(0, scrollBottom - guardZoneHeight);
var viewPortHeight = scrollHeight - scrollTop - scrollBottom;
// Do nothing if populated nodes still fit the viewport.
if (!force && scrollTop >= this._topPaddingHeight && scrollBottom >= this._bottomPaddingHeight)
return;
var hysteresisHeight = 500;
scrollTop -= hysteresisHeight;
viewPortHeight += 2 * hysteresisHeight;
var selectedNode = this.selectedNode;
this.rootNode().removeChildren();
this._topPaddingHeight = 0;
this._bottomPaddingHeight = 0;
this._addVisibleNodes(this.rootNode(), scrollTop, scrollTop + viewPortHeight);
this.setVerticalPadding(this._topPaddingHeight, this._bottomPaddingHeight);
if (selectedNode) {
// Keep selection even if the node is not in the current viewport.
if (selectedNode.parent)
selectedNode.select(true);
else
this.selectedNode = selectedNode;
}
},
/**
* @param {!WebInspector.DataGridNode} parentNode
* @param {number} topBound
* @param {number} bottomBound
* @return {number}
*/
_addVisibleNodes: function(parentNode, topBound, bottomBound)
{
if (!parentNode.expanded)
return 0;
var children = this.allChildren(parentNode);
var topPadding = 0;
var nameFilterValue = this._nameFilter ? this._nameFilter.value().toLowerCase() : "";
// Iterate over invisible nodes beyond the upper bound of viewport.
// Do not insert them into the grid, but count their total height.
for (var i = 0; i < children.length; ++i) {
var child = children[i];
if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
continue;
var newTop = topPadding + this._nodeHeight(child);
if (newTop > topBound)
break;
topPadding = newTop;
}
// Put visible nodes into the data grid.
var position = topPadding;
for (; i < children.length && position < bottomBound; ++i) {
var child = children[i];
if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
continue;
var hasChildren = child.hasChildren;
child.removeChildren();
child.hasChildren = hasChildren;
child.revealed = true;
parentNode.appendChild(child);
position += child.nodeSelfHeight();
position += this._addVisibleNodes(child, topBound - position, bottomBound - position);
}
// Count the invisible nodes beyond the bottom bound of the viewport.
var bottomPadding = 0;
for (; i < children.length; ++i) {
var child = children[i];
if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
continue;
bottomPadding += this._nodeHeight(child);
}
this._topPaddingHeight += topPadding;
this._bottomPaddingHeight += bottomPadding;
return position + bottomPadding;
},
/**
* @param {!WebInspector.HeapSnapshotGridNode} node
* @return {number}
*/
_nodeHeight: function(node)
{
if (!node.revealed)
return 0;
var result = node.nodeSelfHeight();
if (!node.expanded)
return result;
var children = this.allChildren(node);
for (var i = 0; i < children.length; i++)
result += this._nodeHeight(children[i]);
return result;
},
/**
* @param {!Array.<!WebInspector.HeapSnapshotGridNode>} pathToReveal
* @return {!Promise.<!WebInspector.HeapSnapshotGridNode>}
*/
revealTreeNode: function(pathToReveal)
{
var height = this._calculateOffset(pathToReveal);
var node = /** @type {!WebInspector.HeapSnapshotGridNode} */(pathToReveal.peekLast());
var scrollTop = this.scrollContainer.scrollTop;
var scrollBottom = scrollTop + this.scrollContainer.offsetHeight;
if (height >= scrollTop && height < scrollBottom)
return Promise.resolve(node);
var scrollGap = 40;
this.scrollContainer.scrollTop = Math.max(0, height - scrollGap);
return new Promise(this._scrollTo.bind(this, node));
},
/**
* @param {!WebInspector.HeapSnapshotGridNode} node
* @param {function(!WebInspector.HeapSnapshotGridNode)} fulfill
*/
_scrollTo: function(node, fulfill)
{
console.assert(!this._scrollToResolveCallback);
this._scrollToResolveCallback = fulfill.bind(null, node);
},
/**
* @param {!Array.<!WebInspector.HeapSnapshotGridNode>} pathToReveal
* @return {number}
*/
_calculateOffset: function(pathToReveal)
{
var parentNode = this.rootNode();
var height = 0;
for (var i = 0; i < pathToReveal.length; ++i) {
var node = pathToReveal[i];
var children = this.allChildren(parentNode);
for (var j = 0; j < children.length; ++j) {
var child = children[j];
if (node === child) {
height += node.nodeSelfHeight();
break;
}
height += this._nodeHeight(child);
}
parentNode = node;
}
return height - pathToReveal.peekLast().nodeSelfHeight();
},
/**
* @override
* @param {!WebInspector.DataGridNode} parent
* @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
*/
allChildren: function(parent)
{
return parent._allChildren || (parent._allChildren = []);
},
/**
* @param {!WebInspector.DataGridNode} parent
* @param {!WebInspector.HeapSnapshotGridNode} node
*/
appendNode: function(parent, node)
{
this.allChildren(parent).push(node);
},
/**
* @override
* @param {!WebInspector.DataGridNode} parent
* @param {!WebInspector.DataGridNode} node
* @param {number} index
*/
insertChild: function(parent, node, index)
{
this.allChildren(parent).splice(index, 0, /** @type {!WebInspector.HeapSnapshotGridNode} */(node));
},
removeChildByIndex: function(parent, index)
{
this.allChildren(parent).splice(index, 1);
},
removeAllChildren: function(parent)
{
parent._allChildren = [];
},
removeTopLevelNodes: function()
{
this._disposeAllNodes();
this.rootNode().removeChildren();
this.rootNode()._allChildren = [];
},
/**
* @param {!Element} element
* @return {boolean}
*/
_isScrolledIntoView: function(element)
{
var viewportTop = this.scrollContainer.scrollTop;
var viewportBottom = viewportTop + this.scrollContainer.clientHeight;
var elemTop = element.offsetTop;
var elemBottom = elemTop + element.offsetHeight;
return elemBottom <= viewportBottom && elemTop >= viewportTop;
},
onResize: function()
{
WebInspector.HeapSnapshotSortableDataGrid.prototype.onResize.call(this);
this.updateVisibleNodes(false);
},
_onScroll: function(event)
{
this.updateVisibleNodes(false);
if (this._scrollToResolveCallback) {
this._scrollToResolveCallback();
this._scrollToResolveCallback = null;
}
},
__proto__: WebInspector.HeapSnapshotSortableDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotSortableDataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>=} columns
*/
WebInspector.HeapSnapshotContainmentDataGrid = function(dataDisplayDelegate, columns)
{
columns = columns || [
{id: "object", title: WebInspector.UIString("Object"), disclosure: true, sortable: true},
{id: "distance", title: WebInspector.UIString("Distance"), width: "80px", sortable: true},
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sortable: true, sort: WebInspector.DataGrid.Order.Descending}
];
WebInspector.HeapSnapshotSortableDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotContainmentDataGrid.prototype = {
/**
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {number} nodeIndex
*/
setDataSource: function(snapshot, nodeIndex)
{
this.snapshot = snapshot;
var node = { nodeIndex: nodeIndex || snapshot.rootNodeIndex };
var fakeEdge = { node: node };
this.setRootNode(this._createRootNode(snapshot, fakeEdge));
this.rootNode().sort();
},
_createRootNode: function(snapshot, fakeEdge)
{
return new WebInspector.HeapSnapshotObjectNode(this, snapshot, fakeEdge, null);
},
sortingChanged: function()
{
var rootNode = this.rootNode();
if (rootNode.hasChildren)
rootNode.sort();
},
__proto__: WebInspector.HeapSnapshotSortableDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotContainmentDataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
WebInspector.HeapSnapshotRetainmentDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Object"), disclosure: true, sortable: true},
{id: "distance", title: WebInspector.UIString("Distance"), width: "80px", sortable: true, sort: WebInspector.DataGrid.Order.Ascending},
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sortable: true}
];
WebInspector.HeapSnapshotContainmentDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotRetainmentDataGrid.Events = {
ExpandRetainersComplete: "ExpandRetainersComplete"
}
WebInspector.HeapSnapshotRetainmentDataGrid.prototype = {
_createRootNode: function(snapshot, fakeEdge)
{
return new WebInspector.HeapSnapshotRetainingObjectNode(this, snapshot, fakeEdge, null);
},
_sortFields: function(sortColumn, sortAscending)
{
return {
object: ["_name", sortAscending, "_count", false],
count: ["_count", sortAscending, "_name", true],
shallowSize: ["_shallowSize", sortAscending, "_name", true],
retainedSize: ["_retainedSize", sortAscending, "_name", true],
distance: ["_distance", sortAscending, "_name", true]
}[sortColumn];
},
reset: function()
{
this.rootNode().removeChildren();
this.resetSortingCache();
},
/**
* @override
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {number} nodeIndex
*/
setDataSource: function(snapshot, nodeIndex)
{
WebInspector.HeapSnapshotContainmentDataGrid.prototype.setDataSource.call(this, snapshot, nodeIndex);
this.rootNode().expand();
},
__proto__: WebInspector.HeapSnapshotContainmentDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotViewportDataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
WebInspector.HeapSnapshotConstructorsDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true},
{id: "distance", title: WebInspector.UIString("Distance"), width: "90px", sortable: true},
{id: "count", title: WebInspector.UIString("Objects Count"), width: "90px", sortable: true},
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true}
];
WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
this._profileIndex = -1;
this._objectIdToSelect = null;
}
WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
_sortFields: function(sortColumn, sortAscending)
{
return {
object: ["_name", sortAscending, "_count", false],
distance: ["_distance", sortAscending, "_retainedSize", true],
count: ["_count", sortAscending, "_name", true],
shallowSize: ["_shallowSize", sortAscending, "_name", true],
retainedSize: ["_retainedSize", sortAscending, "_name", true]
}[sortColumn];
},
/**
* @override
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} id
* @return {!Promise<?WebInspector.HeapSnapshotGridNode>}
*/
revealObjectByHeapSnapshotId: function(id)
{
if (!this.snapshot) {
this._objectIdToSelect = id;
return Promise.resolve(/** @type {?WebInspector.HeapSnapshotGridNode} */ (null));
}
/**
* @param {!Array<!WebInspector.HeapSnapshotGridNode>} nodes
* @return {?Promise<!WebInspector.HeapSnapshotGridNode>}
* @this {WebInspector.HeapSnapshotConstructorsDataGrid}
*/
function didPopulateNode(nodes)
{
return nodes.length ? this.revealTreeNode(nodes) : null;
}
/**
* @param {?string} className
* @return {?Promise<?WebInspector.HeapSnapshotGridNode>}
* @this {WebInspector.HeapSnapshotConstructorsDataGrid}
*/
function didGetClassName(className)
{
if (!className)
return null;
var constructorNodes = this.topLevelNodes();
for (var i = 0; i < constructorNodes.length; i++) {
var parent = constructorNodes[i];
if (parent._name === className)
return parent.populateNodeBySnapshotObjectId(parseInt(id, 10)).then(didPopulateNode.bind(this));
}
// There are no visible top level nodes with such className.
return null;
}
return this.snapshot.nodeClassName(parseInt(id, 10)).then(didGetClassName.bind(this));
},
clear: function()
{
this._nextRequestedFilter = null;
this._lastFilter = null;
this.removeTopLevelNodes();
},
/**
* @param {!WebInspector.HeapSnapshotProxy} snapshot
*/
setDataSource: function(snapshot)
{
this.snapshot = snapshot;
if (this._profileIndex === -1)
this._populateChildren();
if (this._objectIdToSelect) {
this.revealObjectByHeapSnapshotId(this._objectIdToSelect);
this._objectIdToSelect = null;
}
},
/**
* @param {number} minNodeId
* @param {number} maxNodeId
*/
setSelectionRange: function(minNodeId, maxNodeId)
{
this._nodeFilter = new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId, maxNodeId);
this._populateChildren(this._nodeFilter);
},
/**
* @param {number} allocationNodeId
*/
setAllocationNodeId: function(allocationNodeId)
{
this._nodeFilter = new WebInspector.HeapSnapshotCommon.NodeFilter();
this._nodeFilter.allocationNodeId = allocationNodeId;
this._populateChildren(this._nodeFilter);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
* @param {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>} aggregates
*/
_aggregatesReceived: function(nodeFilter, aggregates)
{
this._filterInProgress = null;
if (this._nextRequestedFilter) {
this.snapshot.aggregatesWithFilter(this._nextRequestedFilter, this._aggregatesReceived.bind(this, this._nextRequestedFilter));
this._filterInProgress = this._nextRequestedFilter;
this._nextRequestedFilter = null;
}
this.removeTopLevelNodes();
this.resetSortingCache();
for (var constructor in aggregates)
this.appendNode(this.rootNode(), new WebInspector.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor], nodeFilter));
this.sortingChanged();
this._lastFilter = nodeFilter;
},
/**
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter=} nodeFilter
*/
_populateChildren: function(nodeFilter)
{
nodeFilter = nodeFilter || new WebInspector.HeapSnapshotCommon.NodeFilter();
if (this._filterInProgress) {
this._nextRequestedFilter = this._filterInProgress.equals(nodeFilter) ? null : nodeFilter;
return;
}
if (this._lastFilter && this._lastFilter.equals(nodeFilter))
return;
this._filterInProgress = nodeFilter;
this.snapshot.aggregatesWithFilter(nodeFilter, this._aggregatesReceived.bind(this, nodeFilter));
},
filterSelectIndexChanged: function(profiles, profileIndex)
{
this._profileIndex = profileIndex;
this._nodeFilter = undefined;
if (profileIndex !== -1) {
var minNodeId = profileIndex > 0 ? profiles[profileIndex - 1].maxJSObjectId : 0;
var maxNodeId = profiles[profileIndex].maxJSObjectId;
this._nodeFilter = new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId, maxNodeId);
}
this._populateChildren(this._nodeFilter);
},
__proto__: WebInspector.HeapSnapshotViewportDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotViewportDataGrid}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
WebInspector.HeapSnapshotDiffDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true},
{id: "addedCount", title: WebInspector.UIString("# New"), width: "72px", sortable: true},
{id: "removedCount", title: WebInspector.UIString("# Deleted"), width: "72px", sortable: true},
{id: "countDelta", title: WebInspector.UIString("# Delta"), width: "64px", sortable: true},
{id: "addedSize", title: WebInspector.UIString("Alloc. Size"), width: "72px", sortable: true, sort: WebInspector.DataGrid.Order.Descending},
{id: "removedSize", title: WebInspector.UIString("Freed Size"), width: "72px", sortable: true},
{id: "sizeDelta", title: WebInspector.UIString("Size Delta"), width: "72px", sortable: true}
];
WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotDiffDataGrid.prototype = {
/**
* @override
* @return {number}
*/
defaultPopulateCount: function()
{
return 50;
},
_sortFields: function(sortColumn, sortAscending)
{
return {
object: ["_name", sortAscending, "_count", false],
addedCount: ["_addedCount", sortAscending, "_name", true],
removedCount: ["_removedCount", sortAscending, "_name", true],
countDelta: ["_countDelta", sortAscending, "_name", true],
addedSize: ["_addedSize", sortAscending, "_name", true],
removedSize: ["_removedSize", sortAscending, "_name", true],
sizeDelta: ["_sizeDelta", sortAscending, "_name", true]
}[sortColumn];
},
setDataSource: function(snapshot)
{
this.snapshot = snapshot;
},
/**
* @param {!WebInspector.HeapSnapshotProxy} baseSnapshot
*/
setBaseDataSource: function(baseSnapshot)
{
this.baseSnapshot = baseSnapshot;
this.removeTopLevelNodes();
this.resetSortingCache();
if (this.baseSnapshot === this.snapshot) {
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);
return;
}
this._populateChildren();
},
_populateChildren: function()
{
/**
* @this {WebInspector.HeapSnapshotDiffDataGrid}
*/
function aggregatesForDiffReceived(aggregatesForDiff)
{
this.snapshot.calculateSnapshotDiff(this.baseSnapshot.uid, aggregatesForDiff, didCalculateSnapshotDiff.bind(this));
/**
* @this {WebInspector.HeapSnapshotDiffDataGrid}
*/
function didCalculateSnapshotDiff(diffByClassName)
{
for (var className in diffByClassName) {
var diff = diffByClassName[className];
this.appendNode(this.rootNode(), new WebInspector.HeapSnapshotDiffNode(this, className, diff));
}
this.sortingChanged();
}
}
// Two snapshots live in different workers isolated from each other. That is why
// we first need to collect information about the nodes in the first snapshot and
// then pass it to the second snapshot to calclulate the diff.
this.baseSnapshot.aggregatesForDiff(aggregatesForDiffReceived.bind(this));
},
__proto__: WebInspector.HeapSnapshotViewportDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotViewportDataGrid}
* @param {?WebInspector.Target} target
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
WebInspector.AllocationDataGrid = function(target, dataDisplayDelegate)
{
var columns = [
{id: "liveCount", title: WebInspector.UIString("Live Count"), width: "72px", sortable: true},
{id: "count", title: WebInspector.UIString("Count"), width: "72px", sortable: true},
{id: "liveSize", title: WebInspector.UIString("Live Size"), width: "72px", sortable: true},
{id: "size", title: WebInspector.UIString("Size"), width: "72px", sortable: true, sort: WebInspector.DataGrid.Order.Descending},
{id: "name", title: WebInspector.UIString("Function"), disclosure: true, sortable: true},
];
WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
this._target = target;
this._linkifier = new WebInspector.Linkifier();
}
WebInspector.AllocationDataGrid.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
},
dispose: function()
{
this._linkifier.reset();
},
setDataSource: function(snapshot)
{
this.snapshot = snapshot;
this.snapshot.allocationTracesTops(didReceiveAllocationTracesTops.bind(this));
/**
* @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} tops
* @this {WebInspector.AllocationDataGrid}
*/
function didReceiveAllocationTracesTops(tops)
{
this._topNodes = tops;
this._populateChildren();
}
},
_populateChildren: function()
{
this.removeTopLevelNodes();
var root = this.rootNode();
var tops = this._topNodes;
for (var i = 0; i < tops.length; i++)
this.appendNode(root, new WebInspector.AllocationGridNode(this, tops[i]));
this.updateVisibleNodes(true);
},
sortingChanged: function()
{
this._topNodes.sort(this._createComparator());
this.rootNode().removeChildren();
this._populateChildren();
},
/**
* @return {function(!Object, !Object):number}
*/
_createComparator: function()
{
var fieldName = this.sortColumnIdentifier();
var compareResult = (this.sortOrder() === WebInspector.DataGrid.Order.Ascending) ? +1 : -1;
/**
* @param {!Object} a
* @param {!Object} b
* @return {number}
*/
function compare(a, b)
{
if (a[fieldName] > b[fieldName])
return compareResult;
if (a[fieldName] < b[fieldName])
return -compareResult;
return 0;
}
return compare;
},
__proto__: WebInspector.HeapSnapshotViewportDataGrid.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.DataGridNode}
* @param {!WebInspector.HeapSnapshotSortableDataGrid} tree
* @param {boolean} hasChildren
*/
WebInspector.HeapSnapshotGridNode = function(tree, hasChildren)
{
WebInspector.DataGridNode.call(this, null, hasChildren);
this._dataGrid = tree;
this._instanceCount = 0;
this._savedChildren = null;
/**
* List of position ranges for all visible nodes: [startPos1, endPos1),...,[startPosN, endPosN)
* Position is an item position in the provider.
*/
this._retrievedChildrenRanges = [];
/**
* @type {?WebInspector.HeapSnapshotGridNode.ChildrenProvider}
*/
this._providerObject = null;
}
WebInspector.HeapSnapshotGridNode.Events = {
PopulateComplete: "PopulateComplete"
}
/**
* @param {!Array.<string>} fieldNames
* @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
*/
WebInspector.HeapSnapshotGridNode.createComparator = function(fieldNames)
{
return /** @type {!WebInspector.HeapSnapshotCommon.ComparatorConfig} */ ({fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]});
}
/**
* @interface
*/
WebInspector.HeapSnapshotGridNode.ChildrenProvider = function() { }
WebInspector.HeapSnapshotGridNode.ChildrenProvider.prototype = {
dispose: function() { },
/**
* @param {number} snapshotObjectId
* @return {!Promise<number>}
*/
nodePosition: function(snapshotObjectId) { },
/**
* @param {function(boolean)} callback
*/
isEmpty: function(callback) { },
/**
* @param {number} startPosition
* @param {number} endPosition
* @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
*/
serializeItemsRange: function(startPosition, endPosition, callback) { },
/**
* @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
* @return {!Promise<?>}
*/
sortAndRewind: function(comparator) { }
}
WebInspector.HeapSnapshotGridNode.prototype = {
/**
* @return {!WebInspector.HeapSnapshotSortableDataGrid}
*/
heapSnapshotDataGrid: function()
{
return this._dataGrid;
},
/**
* @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
*/
createProvider: function()
{
throw new Error("Not implemented.");
},
/**
* @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
*/
retainersDataSource: function()
{
return null;
},
/**
* @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
*/
_provider: function()
{
if (!this._providerObject)
this._providerObject = this.createProvider();
return this._providerObject;
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
if (this._searchMatched)
cell.classList.add("highlight");
return cell;
},
/**
* @override
*/
collapse: function()
{
WebInspector.DataGridNode.prototype.collapse.call(this);
this._dataGrid.updateVisibleNodes(true);
},
/**
* @override
*/
expand: function()
{
WebInspector.DataGridNode.prototype.expand.call(this);
this._dataGrid.updateVisibleNodes(true);
},
dispose: function()
{
if (this._providerObject)
this._providerObject.dispose();
for (var node = this.children[0]; node; node = node.traverseNextNode(true, this, true))
if (node.dispose)
node.dispose();
},
_reachableFromWindow: false,
queryObjectContent: function(callback)
{
},
/**
* @override
*/
wasDetached: function()
{
this._dataGrid.nodeWasDetached(this);
},
/**
* @param {number} num
* @return {string}
*/
_toPercentString: function(num)
{
return num.toFixed(0) + "\u2009%"; // \u2009 is a thin space.
},
/**
* @param {number} distance
* @return {string}
*/
_toUIDistance: function(distance)
{
var baseSystemDistance = WebInspector.HeapSnapshotCommon.baseSystemDistance;
return distance >= 0 && distance < baseSystemDistance ? WebInspector.UIString("%d", distance) : WebInspector.UIString("\u2212");
},
/**
* @return {!Array.<!WebInspector.DataGridNode>}
*/
allChildren: function()
{
return this._dataGrid.allChildren(this);
},
/**
* @param {number} index
*/
removeChildByIndex: function(index)
{
this._dataGrid.removeChildByIndex(this, index);
},
/**
* @param {number} nodePosition
* @return {?WebInspector.DataGridNode}
*/
childForPosition: function(nodePosition)
{
var indexOfFirstChildInRange = 0;
for (var i = 0; i < this._retrievedChildrenRanges.length; i++) {
var range = this._retrievedChildrenRanges[i];
if (range.from <= nodePosition && nodePosition < range.to) {
var childIndex = indexOfFirstChildInRange + nodePosition - range.from;
return this.allChildren()[childIndex];
}
indexOfFirstChildInRange += range.to - range.from + 1;
}
return null;
},
/**
* @param {string} columnIdentifier
* @return {!Element}
*/
_createValueCell: function(columnIdentifier)
{
var cell = createElement("td");
cell.className = "numeric-column";
if (this.dataGrid.snapshot.totalSize !== 0) {
var div = createElement("div");
var valueSpan = createElement("span");
valueSpan.textContent = this.data[columnIdentifier];
div.appendChild(valueSpan);
var percentColumn = columnIdentifier + "-percent";
if (percentColumn in this.data) {
var percentSpan = createElement("span");
percentSpan.className = "percent-column";
percentSpan.textContent = this.data[percentColumn];
div.appendChild(percentSpan);
div.classList.add("profile-multiple-values");
}
cell.appendChild(div);
}
return cell;
},
populate: function(event)
{
if (this._populated)
return;
this._populated = true;
this._provider().sortAndRewind(this.comparator()).then(this._populateChildren.bind(this));
},
/**
* @return {!Promise<?>}
*/
expandWithoutPopulate: function()
{
// Make sure default populate won't take action.
this._populated = true;
this.expand();
return this._provider().sortAndRewind(this.comparator());
},
/**
* @param {?number=} fromPosition
* @param {?number=} toPosition
* @param {function()=} afterPopulate
*/
_populateChildren: function(fromPosition, toPosition, afterPopulate)
{
fromPosition = fromPosition || 0;
toPosition = toPosition || fromPosition + this._dataGrid.defaultPopulateCount();
var firstNotSerializedPosition = fromPosition;
/**
* @this {WebInspector.HeapSnapshotGridNode}
*/
function serializeNextChunk()
{
if (firstNotSerializedPosition >= toPosition)
return;
var end = Math.min(firstNotSerializedPosition + this._dataGrid.defaultPopulateCount(), toPosition);
this._provider().serializeItemsRange(firstNotSerializedPosition, end, childrenRetrieved.bind(this));
firstNotSerializedPosition = end;
}
/**
* @this {WebInspector.HeapSnapshotGridNode}
*/
function insertRetrievedChild(item, insertionIndex)
{
if (this._savedChildren) {
var hash = this._childHashForEntity(item);
if (hash in this._savedChildren) {
this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
return;
}
}
this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
}
/**
* @this {WebInspector.HeapSnapshotGridNode}
*/
function insertShowMoreButton(from, to, insertionIndex)
{
var button = new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
this._dataGrid.insertChild(this, button, insertionIndex);
}
/**
* @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotGridNode}
*/
function childrenRetrieved(itemsRange)
{
var itemIndex = 0;
var itemPosition = itemsRange.startPosition;
var items = itemsRange.items;
var insertionIndex = 0;
if (!this._retrievedChildrenRanges.length) {
if (itemsRange.startPosition > 0) {
this._retrievedChildrenRanges.push({from: 0, to: 0});
insertShowMoreButton.call(this, 0, itemsRange.startPosition, insertionIndex++);
}
this._retrievedChildrenRanges.push({from: itemsRange.startPosition, to: itemsRange.endPosition});
for (var i = 0, l = items.length; i < l; ++i)
insertRetrievedChild.call(this, items[i], insertionIndex++);
if (itemsRange.endPosition < itemsRange.totalLength)
insertShowMoreButton.call(this, itemsRange.endPosition, itemsRange.totalLength, insertionIndex++);
} else {
var rangeIndex = 0;
var found = false;
var range;
while (rangeIndex < this._retrievedChildrenRanges.length) {
range = this._retrievedChildrenRanges[rangeIndex];
if (range.to >= itemPosition) {
found = true;
break;
}
insertionIndex += range.to - range.from;
// Skip the button if there is one.
if (range.to < itemsRange.totalLength)
insertionIndex += 1;
++rangeIndex;
}
if (!found || itemsRange.startPosition < range.from) {
// Update previous button.
this.allChildren()[insertionIndex - 1].setEndPosition(itemsRange.startPosition);
insertShowMoreButton.call(this, itemsRange.startPosition, found ? range.from : itemsRange.totalLength, insertionIndex);
range = {from: itemsRange.startPosition, to: itemsRange.startPosition};
if (!found)
rangeIndex = this._retrievedChildrenRanges.length;
this._retrievedChildrenRanges.splice(rangeIndex, 0, range);
} else {
insertionIndex += itemPosition - range.from;
}
// At this point insertionIndex is always an index before button or between nodes.
// Also it is always true here that range.from <= itemPosition <= range.to
// Stretch the range right bound to include all new items.
while (range.to < itemsRange.endPosition) {
// Skip already added nodes.
var skipCount = range.to - itemPosition;
insertionIndex += skipCount;
itemIndex += skipCount;
itemPosition = range.to;
// We're at the position before button: ...<?node>x<button>
var nextRange = this._retrievedChildrenRanges[rangeIndex + 1];
var newEndOfRange = nextRange ? nextRange.from : itemsRange.totalLength;
if (newEndOfRange > itemsRange.endPosition)
newEndOfRange = itemsRange.endPosition;
while (itemPosition < newEndOfRange) {
insertRetrievedChild.call(this, items[itemIndex++], insertionIndex++);
++itemPosition;
}
// Merge with the next range.
if (nextRange && newEndOfRange === nextRange.from) {
range.to = nextRange.to;
// Remove "show next" button if there is one.
this.removeChildByIndex(insertionIndex);
this._retrievedChildrenRanges.splice(rangeIndex + 1, 1);
} else {
range.to = newEndOfRange;
// Remove or update next button.
if (newEndOfRange === itemsRange.totalLength)
this.removeChildByIndex(insertionIndex);
else
this.allChildren()[insertionIndex].setStartPosition(itemsRange.endPosition);
}
}
}
// TODO: fix this.
this._instanceCount += items.length;
if (firstNotSerializedPosition < toPosition) {
serializeNextChunk.call(this);
return;
}
if (this.expanded)
this._dataGrid.updateVisibleNodes(true);
if (afterPopulate)
afterPopulate();
this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete);
}
serializeNextChunk.call(this);
},
_saveChildren: function()
{
this._savedChildren = null;
var children = this.allChildren();
for (var i = 0, l = children.length; i < l; ++i) {
var child = children[i];
if (!child.expanded)
continue;
if (!this._savedChildren)
this._savedChildren = {};
this._savedChildren[this._childHashForNode(child)] = child;
}
},
sort: function()
{
this._dataGrid.recursiveSortingEnter();
/**
* @this {WebInspector.HeapSnapshotGridNode}
*/
function afterSort()
{
this._saveChildren();
this._dataGrid.removeAllChildren(this);
this._retrievedChildrenRanges = [];
/**
* @this {WebInspector.HeapSnapshotGridNode}
*/
function afterPopulate()
{
var children = this.allChildren();
for (var i = 0, l = children.length; i < l; ++i) {
var child = children[i];
if (child.expanded)
child.sort();
}
this._dataGrid.recursiveSortingLeave();
}
var instanceCount = this._instanceCount;
this._instanceCount = 0;
this._populateChildren(0, instanceCount, afterPopulate.bind(this));
}
this._provider().sortAndRewind(this.comparator()).then(afterSort.bind(this));
},
__proto__: WebInspector.DataGridNode.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGridNode}
* @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
* @param {!WebInspector.HeapSnapshotCommon.Node} node
*/
WebInspector.HeapSnapshotGenericObjectNode = function(dataGrid, node)
{
WebInspector.HeapSnapshotGridNode.call(this, dataGrid, false);
// node is null for DataGrid root nodes.
if (!node)
return;
this._name = node.name;
this._type = node.type;
this._distance = node.distance;
this._shallowSize = node.selfSize;
this._retainedSize = node.retainedSize;
this.snapshotNodeId = node.id;
this.snapshotNodeIndex = node.nodeIndex;
if (this._type === "string")
this._reachableFromWindow = true;
else if (this._type === "object" && this._name.startsWith("Window")) {
this._name = this.shortenWindowURL(this._name, false);
this._reachableFromWindow = true;
} else if (node.canBeQueried)
this._reachableFromWindow = true;
if (node.detachedDOMTreeNode)
this.detachedDOMTreeNode = true;
var snapshot = dataGrid.snapshot;
var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
this.data = {
"distance": this._toUIDistance(this._distance),
"shallowSize": Number.withThousandsSeparator(this._shallowSize),
"retainedSize": Number.withThousandsSeparator(this._retainedSize),
"shallowSize-percent": this._toPercentString(shallowSizePercent),
"retainedSize-percent": this._toPercentString(retainedSizePercent)
};
};
WebInspector.HeapSnapshotGenericObjectNode.prototype = {
/**
* @override
* @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
*/
retainersDataSource: function()
{
return {snapshot: this._dataGrid.snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : this._createObjectCell();
if (this._searchMatched)
cell.classList.add("highlight");
return cell;
},
/**
* @return {!Element}
*/
_createObjectCell: function()
{
var value = this._name;
var valueStyle = "object";
switch (this._type) {
case "concatenated string":
case "string":
value = "\"" + value + "\"";
valueStyle = "string";
break;
case "regexp":
value = "/" + value + "/";
valueStyle = "string";
break;
case "closure":
value = value + "()";
valueStyle = "function";
break;
case "number":
valueStyle = "number";
break;
case "hidden":
valueStyle = "null";
break;
case "array":
value = (value || "") + "[]";
break;
};
if (this._reachableFromWindow)
valueStyle += " highlight";
if (value === "Object")
value = "";
if (this.detachedDOMTreeNode)
valueStyle += " detached-dom-tree-node";
return this._createObjectCellWithValue(valueStyle, value);
},
_createObjectCellWithValue: function(valueStyle, value)
{
var cell = createElement("td");
cell.className = "object-column";
var div = createElement("div");
div.className = "source-code event-properties";
div.style.overflow = "visible";
this._prefixObjectCell(div);
var valueSpan = createElement("span");
valueSpan.className = "value object-value-" + valueStyle;
valueSpan.textContent = value;
div.appendChild(valueSpan);
var idSpan = createElement("span");
idSpan.className = "object-value-id";
idSpan.textContent = " @" + this.snapshotNodeId;
div.appendChild(idSpan);
cell.appendChild(div);
cell.classList.add("disclosure");
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
cell.heapSnapshotNode = this;
return cell;
},
_prefixObjectCell: function(div)
{
},
/**
* @param {!WebInspector.Target} target
* @param {function(!WebInspector.RemoteObject)} callback
* @param {string} objectGroupName
*/
queryObjectContent: function(target, callback, objectGroupName)
{
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} object
*/
function formatResult(error, object)
{
if (!error && object.type)
callback(target.runtimeModel.createRemoteObject(object));
else
callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(WebInspector.UIString("Preview is not available")));
}
if (this._type === "string")
callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(this._name));
else
target.heapProfilerAgent().getObjectByHeapObjectId(String(this.snapshotNodeId), objectGroupName, formatResult);
},
updateHasChildren: function()
{
/**
* @this {WebInspector.HeapSnapshotGenericObjectNode}
*/
function isEmptyCallback(isEmpty)
{
this.hasChildren = !isEmpty;
}
this._provider().isEmpty(isEmptyCallback.bind(this));
},
/**
* @param {string} fullName
* @param {boolean} hasObjectId
* @return {string}
*/
shortenWindowURL: function(fullName, hasObjectId)
{
var startPos = fullName.indexOf("/");
var endPos = hasObjectId ? fullName.indexOf("@") : fullName.length;
if (startPos !== -1 && endPos !== -1) {
var fullURL = fullName.substring(startPos + 1, endPos).trimLeft();
var url = fullURL.trimURL();
if (url.length > 40)
url = url.trimMiddle(40);
return fullName.substr(0, startPos + 2) + url + fullName.substr(endPos);
} else
return fullName;
},
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGenericObjectNode}
* @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {!WebInspector.HeapSnapshotCommon.Edge} edge
* @param {?WebInspector.HeapSnapshotObjectNode} parentObjectNode
*/
WebInspector.HeapSnapshotObjectNode = function(dataGrid, snapshot, edge, parentObjectNode)
{
WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, edge.node);
this._referenceName = edge.name;
this._referenceType = edge.type;
this._edgeIndex = edge.edgeIndex;
this._snapshot = snapshot;
this._parentObjectNode = parentObjectNode;
this._cycledWithAncestorGridNode = this._findAncestorWithSameSnapshotNodeId();
if (!this._cycledWithAncestorGridNode)
this.updateHasChildren();
var data = this.data;
data["count"] = "";
data["addedCount"] = "";
data["removedCount"] = "";
data["countDelta"] = "";
data["addedSize"] = "";
data["removedSize"] = "";
data["sizeDelta"] = "";
}
WebInspector.HeapSnapshotObjectNode.prototype = {
/**
* @override
* @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
*/
retainersDataSource: function()
{
return {snapshot: this._snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
},
/**
* @override
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createProvider: function()
{
return this._snapshot.createEdgesProvider(this.snapshotNodeIndex);
},
_findAncestorWithSameSnapshotNodeId: function()
{
var ancestor = this._parentObjectNode;
while (ancestor) {
if (ancestor.snapshotNodeId === this.snapshotNodeId)
return ancestor;
ancestor = ancestor._parentObjectNode;
}
return null;
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Edge} item
* @return {!WebInspector.HeapSnapshotObjectNode}
*/
_createChildNode: function(item)
{
return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._snapshot, item, this);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Edge} edge
* @return {number}
*/
_childHashForEntity: function(edge)
{
return edge.edgeIndex;
},
/**
* @param {!WebInspector.HeapSnapshotObjectNode} childNode
* @return {number}
*/
_childHashForNode: function(childNode)
{
return childNode._edgeIndex;
},
/**
* @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
*/
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
var sortFields = {
object: ["!edgeName", sortAscending, "retainedSize", false],
count: ["!edgeName", true, "retainedSize", false],
shallowSize: ["selfSize", sortAscending, "!edgeName", true],
retainedSize: ["retainedSize", sortAscending, "!edgeName", true],
distance: ["distance", sortAscending, "_name", true]
}[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
_prefixObjectCell: function(div)
{
var name = this._referenceName || "(empty)";
var nameClass = "name";
switch (this._referenceType) {
case "context":
nameClass = "object-value-number";
break;
case "internal":
case "hidden":
case "weak":
nameClass = "object-value-null";
break;
case "element":
name = "[" + name + "]";
break;
}
if (this._cycledWithAncestorGridNode)
div.className += " cycled-ancessor-node";
var nameSpan = createElement("span");
nameSpan.className = nameClass;
nameSpan.textContent = name;
div.appendChild(nameSpan);
var separatorSpan = createElement("span");
separatorSpan.className = "grayed";
separatorSpan.textContent = this._edgeNodeSeparator();
div.appendChild(separatorSpan);
},
/**
* @return {string}
*/
_edgeNodeSeparator: function()
{
return " :: ";
},
__proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotObjectNode}
* @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {!WebInspector.HeapSnapshotCommon.Edge} edge
* @param {?WebInspector.HeapSnapshotRetainingObjectNode} parentRetainingObjectNode
*/
WebInspector.HeapSnapshotRetainingObjectNode = function(dataGrid, snapshot, edge, parentRetainingObjectNode)
{
WebInspector.HeapSnapshotObjectNode.call(this, dataGrid, snapshot, edge, parentRetainingObjectNode);
}
WebInspector.HeapSnapshotRetainingObjectNode.prototype = {
/**
* @override
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createProvider: function()
{
return this._snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotCommon.Edge} item
* @return {!WebInspector.HeapSnapshotRetainingObjectNode}
*/
_createChildNode: function(item)
{
return new WebInspector.HeapSnapshotRetainingObjectNode(this._dataGrid, this._snapshot, item, this);
},
/**
* @override
* @return {string}
*/
_edgeNodeSeparator: function()
{
return " in ";
},
expand: function()
{
this._expandRetainersChain(20);
},
/**
* @param {number} maxExpandLevels
*/
_expandRetainersChain: function(maxExpandLevels)
{
/**
* @this {!WebInspector.HeapSnapshotRetainingObjectNode}
*/
function populateComplete()
{
this.removeEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
this._expandRetainersChain(maxExpandLevels);
}
if (!this._populated) {
this.addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
this.populate();
return;
}
WebInspector.HeapSnapshotGenericObjectNode.prototype.expand.call(this);
if (--maxExpandLevels > 0 && this.children.length > 0) {
var retainer = this.children[0];
if (retainer._distance > 1) {
retainer._expandRetainersChain(maxExpandLevels);
return;
}
}
this._dataGrid.dispatchEventToListeners(WebInspector.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);
},
__proto__: WebInspector.HeapSnapshotObjectNode.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGenericObjectNode}
* @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {!WebInspector.HeapSnapshotCommon.Node} node
* @param {boolean} isDeletedNode
*/
WebInspector.HeapSnapshotInstanceNode = function(dataGrid, snapshot, node, isDeletedNode)
{
WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, node);
this._baseSnapshotOrSnapshot = snapshot;
this._isDeletedNode = isDeletedNode;
this.updateHasChildren();
var data = this.data;
data["count"] = "";
data["countDelta"] = "";
data["sizeDelta"] = "";
if (this._isDeletedNode) {
data["addedCount"] = "";
data["addedSize"] = "";
data["removedCount"] = "\u2022";
data["removedSize"] = Number.withThousandsSeparator(this._shallowSize);
} else {
data["addedCount"] = "\u2022";
data["addedSize"] = Number.withThousandsSeparator(this._shallowSize);
data["removedCount"] = "";
data["removedSize"] = "";
}
};
WebInspector.HeapSnapshotInstanceNode.prototype = {
/**
* @override
* @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
*/
retainersDataSource: function()
{
return {snapshot: this._baseSnapshotOrSnapshot, snapshotNodeIndex: this.snapshotNodeIndex};
},
/**
* @override
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createProvider: function()
{
return this._baseSnapshotOrSnapshot.createEdgesProvider(this.snapshotNodeIndex);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Edge} item
* @return {!WebInspector.HeapSnapshotObjectNode}
*/
_createChildNode: function(item)
{
return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._baseSnapshotOrSnapshot, item, null);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Edge} edge
* @return {number}
*/
_childHashForEntity: function(edge)
{
return edge.edgeIndex;
},
/**
* @param {!WebInspector.HeapSnapshotObjectNode} childNode
* @return {number}
*/
_childHashForNode: function(childNode)
{
return childNode._edgeIndex;
},
/**
* @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
*/
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
var sortFields = {
object: ["!edgeName", sortAscending, "retainedSize", false],
distance: ["distance", sortAscending, "retainedSize", false],
count: ["!edgeName", true, "retainedSize", false],
addedSize: ["selfSize", sortAscending, "!edgeName", true],
removedSize: ["selfSize", sortAscending, "!edgeName", true],
shallowSize: ["selfSize", sortAscending, "!edgeName", true],
retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
}[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
__proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
}
/**
* @constructor
* @param {!WebInspector.HeapSnapshotConstructorsDataGrid} dataGrid
* @param {string} className
* @param {!WebInspector.HeapSnapshotCommon.Aggregate} aggregate
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
* @extends {WebInspector.HeapSnapshotGridNode}
*/
WebInspector.HeapSnapshotConstructorNode = function(dataGrid, className, aggregate, nodeFilter)
{
WebInspector.HeapSnapshotGridNode.call(this, dataGrid, aggregate.count > 0);
this._name = className;
this._nodeFilter = nodeFilter;
this._distance = aggregate.distance;
this._count = aggregate.count;
this._shallowSize = aggregate.self;
this._retainedSize = aggregate.maxRet;
var snapshot = dataGrid.snapshot;
var countPercent = this._count / snapshot.nodeCount * 100.0;
var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
this.data = {
"object": className,
"count": Number.withThousandsSeparator(this._count),
"distance": this._toUIDistance(this._distance),
"shallowSize": Number.withThousandsSeparator(this._shallowSize),
"retainedSize": Number.withThousandsSeparator(this._retainedSize),
"count-percent": this._toPercentString(countPercent),
"shallowSize-percent": this._toPercentString(shallowSizePercent),
"retainedSize-percent": this._toPercentString(retainedSizePercent)
};
}
WebInspector.HeapSnapshotConstructorNode.prototype = {
/**
* @override
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createProvider: function()
{
return this._dataGrid.snapshot.createNodesProviderForClass(this._name, this._nodeFilter)
},
/**
* @param {number} snapshotObjectId
* @return {!Promise<!Array<!WebInspector.HeapSnapshotGridNode>>}
*/
populateNodeBySnapshotObjectId: function(snapshotObjectId)
{
/**
* @this {WebInspector.HeapSnapshotConstructorNode}
*/
function didExpand()
{
return this._provider().nodePosition(snapshotObjectId).then(didGetNodePosition.bind(this));
}
/**
* @this {WebInspector.HeapSnapshotConstructorNode}
* @param {number} nodePosition
* @return {!Promise<!Array<!WebInspector.HeapSnapshotGridNode>>}
*/
function didGetNodePosition(nodePosition)
{
if (nodePosition === -1) {
this.collapse();
return Promise.resolve([]);
} else {
/**
* @param {function(!Array<!WebInspector.HeapSnapshotGridNode>)} fulfill
* @this {WebInspector.HeapSnapshotConstructorNode}
*/
function action(fulfill)
{
this._populateChildren(nodePosition, null, didPopulateChildren.bind(this, nodePosition, fulfill));
}
return new Promise(action.bind(this));
}
}
/**
* @this {WebInspector.HeapSnapshotConstructorNode}
* @param {number} nodePosition
* @param {function(!Array<!WebInspector.HeapSnapshotGridNode>)} callback
*/
function didPopulateChildren(nodePosition, callback)
{
var node = /** @type {?WebInspector.HeapSnapshotGridNode} */ (this.childForPosition(nodePosition));
callback(node ? [this, node] : []);
}
this._dataGrid.resetNameFilter();
return this.expandWithoutPopulate().then(didExpand.bind(this));
},
/**
* @param {string} filterValue
* @return {boolean}
*/
filteredOut: function(filterValue)
{
return this._name.toLowerCase().indexOf(filterValue) === -1;
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
if (this._searchMatched)
cell.classList.add("highlight");
return cell;
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Node} item
* @return {!WebInspector.HeapSnapshotInstanceNode}
*/
_createChildNode: function(item)
{
return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
},
/**
* @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
*/
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
var sortFields = {
object: ["name", sortAscending, "id", true],
distance: ["distance", sortAscending, "retainedSize", false],
count: ["name", true, "id", true],
shallowSize: ["selfSize", sortAscending, "id", true],
retainedSize: ["retainedSize", sortAscending, "id", true]
}[sortColumnIdentifier];
return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Node} node
* @return {number}
*/
_childHashForEntity: function(node)
{
return node.id;
},
/**
* @param {!WebInspector.HeapSnapshotInstanceNode} childNode
* @return {number}
*/
_childHashForNode: function(childNode)
{
return childNode.snapshotNodeId;
},
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
/**
* @constructor
* @implements {WebInspector.HeapSnapshotGridNode.ChildrenProvider}
* @param {!WebInspector.HeapSnapshotProviderProxy} addedNodesProvider
* @param {!WebInspector.HeapSnapshotProviderProxy} deletedNodesProvider
* @param {number} addedCount
* @param {number} removedCount
*/
WebInspector.HeapSnapshotDiffNodesProvider = function(addedNodesProvider, deletedNodesProvider, addedCount, removedCount)
{
this._addedNodesProvider = addedNodesProvider;
this._deletedNodesProvider = deletedNodesProvider;
this._addedCount = addedCount;
this._removedCount = removedCount;
}
WebInspector.HeapSnapshotDiffNodesProvider.prototype = {
/**
* @override
*/
dispose: function()
{
this._addedNodesProvider.dispose();
this._deletedNodesProvider.dispose();
},
/**
* @override
* @param {number} snapshotObjectId
* @return {!Promise<number>}
*/
nodePosition: function(snapshotObjectId)
{
throw new Error("Unreachable");
},
/**
* @override
* @param {function(boolean)} callback
*/
isEmpty: function(callback)
{
callback(false);
},
/**
* @override
* @param {number} beginPosition
* @param {number} endPosition
* @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
*/
serializeItemsRange: function(beginPosition, endPosition, callback)
{
/**
* @param {!WebInspector.HeapSnapshotCommon.ItemsRange} items
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
function didReceiveAllItems(items)
{
items.totalLength = this._addedCount + this._removedCount;
callback(items);
}
/**
* @param {!WebInspector.HeapSnapshotCommon.ItemsRange} addedItems
* @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
function didReceiveDeletedItems(addedItems, itemsRange)
{
var items = itemsRange.items;
if (!addedItems.items.length)
addedItems.startPosition = this._addedCount + itemsRange.startPosition;
for (var i = 0; i < items.length; i++) {
items[i].isAddedNotRemoved = false;
addedItems.items.push(items[i]);
}
addedItems.endPosition = this._addedCount + itemsRange.endPosition;
didReceiveAllItems.call(this, addedItems);
}
/**
* @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
function didReceiveAddedItems(itemsRange)
{
var items = itemsRange.items;
for (var i = 0; i < items.length; i++)
items[i].isAddedNotRemoved = true;
if (itemsRange.endPosition < endPosition)
return this._deletedNodesProvider.serializeItemsRange(0, endPosition - itemsRange.endPosition, didReceiveDeletedItems.bind(this, itemsRange));
itemsRange.totalLength = this._addedCount + this._removedCount;
didReceiveAllItems.call(this, itemsRange);
}
if (beginPosition < this._addedCount) {
this._addedNodesProvider.serializeItemsRange(beginPosition, endPosition, didReceiveAddedItems.bind(this));
} else {
var emptyRange = new WebInspector.HeapSnapshotCommon.ItemsRange(0, 0, 0, []);
this._deletedNodesProvider.serializeItemsRange(beginPosition - this._addedCount, endPosition - this._addedCount, didReceiveDeletedItems.bind(this, emptyRange));
}
},
/**
* @override
* @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
* @return {!Promise<?>}
*/
sortAndRewind: function(comparator)
{
/**
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
* @return {!Promise<?>}
*/
function afterSort()
{
return this._deletedNodesProvider.sortAndRewind(comparator);
}
return this._addedNodesProvider.sortAndRewind(comparator).then(afterSort.bind(this));
}
};
/**
* @constructor
* @param {!WebInspector.HeapSnapshotDiffDataGrid} dataGrid
* @param {string} className
* @param {!WebInspector.HeapSnapshotCommon.DiffForClass} diffForClass
* @extends {WebInspector.HeapSnapshotGridNode}
*/
WebInspector.HeapSnapshotDiffNode = function(dataGrid, className, diffForClass)
{
WebInspector.HeapSnapshotGridNode.call(this, dataGrid, true);
this._name = className;
this._addedCount = diffForClass.addedCount;
this._removedCount = diffForClass.removedCount;
this._countDelta = diffForClass.countDelta;
this._addedSize = diffForClass.addedSize;
this._removedSize = diffForClass.removedSize;
this._sizeDelta = diffForClass.sizeDelta;
this._deletedIndexes = diffForClass.deletedIndexes;
this.data = {
"object": className,
"addedCount": Number.withThousandsSeparator(this._addedCount),
"removedCount": Number.withThousandsSeparator(this._removedCount),
"countDelta": this._signForDelta(this._countDelta) + Number.withThousandsSeparator(Math.abs(this._countDelta)),
"addedSize": Number.withThousandsSeparator(this._addedSize),
"removedSize": Number.withThousandsSeparator(this._removedSize),
"sizeDelta": this._signForDelta(this._sizeDelta) + Number.withThousandsSeparator(Math.abs(this._sizeDelta))
};
}
WebInspector.HeapSnapshotDiffNode.prototype = {
/**
* @override
* @return {!WebInspector.HeapSnapshotDiffNodesProvider}
*/
createProvider: function()
{
var tree = this._dataGrid;
return new WebInspector.HeapSnapshotDiffNodesProvider(
tree.snapshot.createAddedNodesProvider(tree.baseSnapshot.uid, this._name),
tree.baseSnapshot.createDeletedNodesProvider(this._deletedIndexes),
this._addedCount,
this._removedCount);
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
if (columnIdentifier !== "object")
cell.classList.add("numeric-column");
return cell;
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Node} item
* @return {!WebInspector.HeapSnapshotInstanceNode}
*/
_createChildNode: function(item)
{
if (item.isAddedNotRemoved)
return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
else
return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.baseSnapshot, item, true);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Node} node
* @return {number}
*/
_childHashForEntity: function(node)
{
return node.id;
},
/**
* @param {!WebInspector.HeapSnapshotInstanceNode} childNode
* @return {number}
*/
_childHashForNode: function(childNode)
{
return childNode.snapshotNodeId;
},
/**
* @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
*/
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
var sortFields = {
object: ["name", sortAscending, "id", true],
addedCount: ["name", true, "id", true],
removedCount: ["name", true, "id", true],
countDelta: ["name", true, "id", true],
addedSize: ["selfSize", sortAscending, "id", true],
removedSize: ["selfSize", sortAscending, "id", true],
sizeDelta: ["selfSize", sortAscending, "id", true]
}[sortColumnIdentifier];
return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
/**
* @param {string} filterValue
* @return {boolean}
*/
filteredOut: function(filterValue)
{
return this._name.toLowerCase().indexOf(filterValue) === -1;
},
_signForDelta: function(delta)
{
if (delta === 0)
return "";
if (delta > 0)
return "+";
else
return "\u2212"; // Math minus sign, same width as plus.
},
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGridNode}
* @param {!WebInspector.AllocationDataGrid} dataGrid
* @param {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode} data
*/
WebInspector.AllocationGridNode = function(dataGrid, data)
{
WebInspector.HeapSnapshotGridNode.call(this, dataGrid, data.hasChildren);
this._populated = false;
this._allocationNode = data;
this.data = {
"liveCount": Number.withThousandsSeparator(data.liveCount),
"count": Number.withThousandsSeparator(data.count),
"liveSize": Number.withThousandsSeparator(data.liveSize),
"size": Number.withThousandsSeparator(data.size),
"name": data.name
};
}
WebInspector.AllocationGridNode.prototype = {
populate: function()
{
if (this._populated)
return;
this._populated = true;
this._dataGrid.snapshot.allocationNodeCallers(this._allocationNode.id, didReceiveCallers.bind(this));
/**
* @param {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} callers
* @this {WebInspector.AllocationGridNode}
*/
function didReceiveCallers(callers)
{
var callersChain = callers.nodesWithSingleCaller;
var parentNode = this;
var dataGrid = /** @type {!WebInspector.AllocationDataGrid} */ (this._dataGrid);
for (var i = 0; i < callersChain.length; i++) {
var child = new WebInspector.AllocationGridNode(dataGrid, callersChain[i]);
dataGrid.appendNode(parentNode, child);
parentNode = child;
parentNode._populated = true;
if (this.expanded)
parentNode.expand();
}
var callersBranch = callers.branchingCallers;
callersBranch.sort(this._dataGrid._createComparator());
for (var i = 0; i < callersBranch.length; i++)
dataGrid.appendNode(parentNode, new WebInspector.AllocationGridNode(dataGrid, callersBranch[i]));
dataGrid.updateVisibleNodes(true);
}
},
/**
* @override
*/
expand: function()
{
WebInspector.HeapSnapshotGridNode.prototype.expand.call(this);
if (this.children.length === 1)
this.children[0].expand();
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
if (columnIdentifier !== "name")
return this._createValueCell(columnIdentifier);
var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
var allocationNode = this._allocationNode;
var target = this._dataGrid.target();
if (allocationNode.scriptId) {
var linkifier = this._dataGrid._linkifier;
var urlElement = linkifier.linkifyScriptLocation(target, String(allocationNode.scriptId), allocationNode.scriptName, allocationNode.line - 1, allocationNode.column - 1, "profile-node-file");
urlElement.style.maxWidth = "75%";
cell.insertBefore(urlElement, cell.firstChild);
}
return cell;
},
/**
* @return {number}
*/
allocationNodeId: function()
{
return this._allocationNode.id;
},
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | 2 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyrightdd
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {function(string, *)} eventHandler
* @extends {WebInspector.Object}
*/
WebInspector.HeapSnapshotWorkerProxy = function(eventHandler)
{
this._eventHandler = eventHandler;
this._nextObjectId = 1;
this._nextCallId = 1;
/** @type {!Map<number, function(*)>} */
this._callbacks = new Map();
/** @type {!Set<number>} */
this._previousCallbacks = new Set();
this._worker = new WorkerRuntime.Worker("heap_snapshot_worker");
this._worker.onmessage = this._messageReceived.bind(this);
}
WebInspector.HeapSnapshotWorkerProxy.prototype = {
/**
* @param {number} profileUid
* @param {function(!WebInspector.HeapSnapshotProxy)} snapshotReceivedCallback
* @return {!WebInspector.HeapSnapshotLoaderProxy}
*/
createLoader: function(profileUid, snapshotReceivedCallback)
{
var objectId = this._nextObjectId++;
var proxy = new WebInspector.HeapSnapshotLoaderProxy(this, objectId, profileUid, snapshotReceivedCallback);
this._postMessage({callId: this._nextCallId++, disposition: "create", objectId: objectId, methodName: "WebInspector.HeapSnapshotLoader"});
return proxy;
},
dispose: function()
{
this._worker.terminate();
if (this._interval)
clearInterval(this._interval);
},
disposeObject: function(objectId)
{
this._postMessage({callId: this._nextCallId++, disposition: "dispose", objectId: objectId});
},
evaluateForTest: function(script, callback)
{
var callId = this._nextCallId++;
this._callbacks.set(callId, callback);
this._postMessage({callId: callId, disposition: "evaluateForTest", source: script});
},
/**
* @param {?function(...?)} callback
* @param {string} objectId
* @param {string} methodName
* @param {function(new:T, ...?)} proxyConstructor
* @return {?Object}
* @template T
*/
callFactoryMethod: function(callback, objectId, methodName, proxyConstructor)
{
var callId = this._nextCallId++;
var methodArguments = Array.prototype.slice.call(arguments, 4);
var newObjectId = this._nextObjectId++;
/**
* @this {WebInspector.HeapSnapshotWorkerProxy}
*/
function wrapCallback(remoteResult)
{
callback(remoteResult ? new proxyConstructor(this, newObjectId) : null);
}
if (callback) {
this._callbacks.set(callId, wrapCallback.bind(this));
this._postMessage({callId: callId, disposition: "factory", objectId: objectId, methodName: methodName, methodArguments: methodArguments, newObjectId: newObjectId});
return null;
} else {
this._postMessage({callId: callId, disposition: "factory", objectId: objectId, methodName: methodName, methodArguments: methodArguments, newObjectId: newObjectId});
return new proxyConstructor(this, newObjectId);
}
},
/**
* @param {function(*)} callback
* @param {string} objectId
* @param {string} methodName
*/
callMethod: function(callback, objectId, methodName)
{
var callId = this._nextCallId++;
var methodArguments = Array.prototype.slice.call(arguments, 3);
if (callback)
this._callbacks.set(callId, callback);
this._postMessage({callId: callId, disposition: "method", objectId: objectId, methodName: methodName, methodArguments: methodArguments});
},
startCheckingForLongRunningCalls: function()
{
if (this._interval)
return;
this._checkLongRunningCalls();
this._interval = setInterval(this._checkLongRunningCalls.bind(this), 300);
},
_checkLongRunningCalls: function()
{
for (var callId of this._previousCallbacks)
if (!this._callbacks.has(callId))
this._previousCallbacks.delete(callId);
var hasLongRunningCalls = !!this._previousCallbacks.size;
this.dispatchEventToListeners("wait", hasLongRunningCalls);
for (var callId of this._callbacks.keysArray())
this._previousCallbacks.add(callId);
},
/**
* @param {!MessageEvent} event
*/
_messageReceived: function(event)
{
var data = event.data;
if (data.eventName) {
if (this._eventHandler)
this._eventHandler(data.eventName, data.data);
return;
}
if (data.error) {
if (data.errorMethodName)
WebInspector.console.error(WebInspector.UIString("An error occurred when a call to method '%s' was requested", data.errorMethodName));
WebInspector.console.error(data["errorCallStack"]);
this._callbacks.delete(data.callId);
return;
}
if (!this._callbacks.has(data.callId))
return;
var callback = this._callbacks.get(data.callId);
this._callbacks.delete(data.callId);
callback(data.result);
},
_postMessage: function(message)
{
this._worker.postMessage(message);
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {!WebInspector.HeapSnapshotWorkerProxy} worker
* @param {number} objectId
*/
WebInspector.HeapSnapshotProxyObject = function(worker, objectId)
{
this._worker = worker;
this._objectId = objectId;
}
WebInspector.HeapSnapshotProxyObject.prototype = {
/**
* @param {string} workerMethodName
* @param {!Array.<*>} args
*/
_callWorker: function(workerMethodName, args)
{
args.splice(1, 0, this._objectId);
return this._worker[workerMethodName].apply(this._worker, args);
},
dispose: function()
{
this._worker.disposeObject(this._objectId);
},
disposeWorker: function()
{
this._worker.dispose();
},
/**
* @param {?function(...?)} callback
* @param {string} methodName
* @param {function (new:T, ...?)} proxyConstructor
* @param {...*} var_args
* @return {!T}
* @template T
*/
callFactoryMethod: function(callback, methodName, proxyConstructor, var_args)
{
return this._callWorker("callFactoryMethod", Array.prototype.slice.call(arguments, 0));
},
/**
* @param {function(T)|undefined} callback
* @param {string} methodName
* @param {...*} var_args
* @return {*}
* @template T
*/
callMethod: function(callback, methodName, var_args)
{
return this._callWorker("callMethod", Array.prototype.slice.call(arguments, 0));
},
/**
* @param {string} methodName
* @param {...*} var_args
* @return {!Promise.<?T>}
* @template T
*/
_callMethodPromise: function(methodName, var_args)
{
/**
* @param {!Array.<*>} args
* @param {function(?T)} fulfill
* @this {WebInspector.HeapSnapshotProxyObject}
* @template T
*/
function action(args, fulfill)
{
this._callWorker("callMethod", [fulfill].concat(args));
}
return new Promise(action.bind(this, Array.prototype.slice.call(arguments)));
}
};
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
* @implements {WebInspector.OutputStream}
* @param {!WebInspector.HeapSnapshotWorkerProxy} worker
* @param {number} objectId
* @param {number} profileUid
* @param {function(!WebInspector.HeapSnapshotProxy)} snapshotReceivedCallback
*/
WebInspector.HeapSnapshotLoaderProxy = function(worker, objectId, profileUid, snapshotReceivedCallback)
{
WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId);
this._profileUid = profileUid;
this._snapshotReceivedCallback = snapshotReceivedCallback;
}
WebInspector.HeapSnapshotLoaderProxy.prototype = {
/**
* @override
* @param {string} chunk
* @param {function(!WebInspector.OutputStream)=} callback
*/
write: function(chunk, callback)
{
this.callMethod(callback, "write", chunk);
},
/**
* @override
* @param {function()=} callback
*/
close: function(callback)
{
/**
* @this {WebInspector.HeapSnapshotLoaderProxy}
*/
function buildSnapshot()
{
if (callback)
callback();
var showHiddenData = WebInspector.moduleSetting("showAdvancedHeapSnapshotProperties").get();
this.callFactoryMethod(updateStaticData.bind(this), "buildSnapshot", WebInspector.HeapSnapshotProxy, showHiddenData);
}
/**
* @param {!WebInspector.HeapSnapshotProxy} snapshotProxy
* @this {WebInspector.HeapSnapshotLoaderProxy}
*/
function updateStaticData(snapshotProxy)
{
this.dispose();
snapshotProxy.setProfileUid(this._profileUid);
snapshotProxy.updateStaticData(this._snapshotReceivedCallback.bind(this));
}
this.callMethod(buildSnapshot.bind(this), "close");
},
__proto__: WebInspector.HeapSnapshotProxyObject.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
* @param {!WebInspector.HeapSnapshotWorkerProxy} worker
* @param {number} objectId
*/
WebInspector.HeapSnapshotProxy = function(worker, objectId)
{
WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId);
/** @type {?WebInspector.HeapSnapshotCommon.StaticData} */
this._staticData = null;
}
WebInspector.HeapSnapshotProxy.prototype = {
/**
* @param {!WebInspector.HeapSnapshotCommon.SearchConfig} searchConfig
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} filter
* @return {!Promise<!Array<number>>}
*/
search: function(searchConfig, filter)
{
return this._callMethodPromise("search", searchConfig, filter);
},
/**
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} filter
* @param {function(!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>)} callback
*/
aggregatesWithFilter: function(filter, callback)
{
this.callMethod(callback, "aggregatesWithFilter", filter);
},
aggregatesForDiff: function(callback)
{
this.callMethod(callback, "aggregatesForDiff");
},
calculateSnapshotDiff: function(baseSnapshotId, baseSnapshotAggregates, callback)
{
this.callMethod(callback, "calculateSnapshotDiff", baseSnapshotId, baseSnapshotAggregates);
},
/**
* @param {number} snapshotObjectId
* @return {!Promise<?string>}
*/
nodeClassName: function(snapshotObjectId)
{
return this._callMethodPromise("nodeClassName", snapshotObjectId);
},
/**
* @param {number} nodeIndex
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createEdgesProvider: function(nodeIndex)
{
return this.callFactoryMethod(null, "createEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex);
},
/**
* @param {number} nodeIndex
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createRetainingEdgesProvider: function(nodeIndex)
{
return this.callFactoryMethod(null, "createRetainingEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex);
},
/**
* @param {string} baseSnapshotId
* @param {string} className
* @return {?WebInspector.HeapSnapshotProviderProxy}
*/
createAddedNodesProvider: function(baseSnapshotId, className)
{
return this.callFactoryMethod(null, "createAddedNodesProvider", WebInspector.HeapSnapshotProviderProxy, baseSnapshotId, className);
},
/**
* @param {!Array.<number>} nodeIndexes
* @return {?WebInspector.HeapSnapshotProviderProxy}
*/
createDeletedNodesProvider: function(nodeIndexes)
{
return this.callFactoryMethod(null, "createDeletedNodesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndexes);
},
/**
* @param {function(*):boolean} filter
* @return {?WebInspector.HeapSnapshotProviderProxy}
*/
createNodesProvider: function(filter)
{
return this.callFactoryMethod(null, "createNodesProvider", WebInspector.HeapSnapshotProviderProxy, filter);
},
/**
* @param {string} className
* @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
* @return {?WebInspector.HeapSnapshotProviderProxy}
*/
createNodesProviderForClass: function(className, nodeFilter)
{
return this.callFactoryMethod(null, "createNodesProviderForClass", WebInspector.HeapSnapshotProviderProxy, className, nodeFilter);
},
allocationTracesTops: function(callback)
{
this.callMethod(callback, "allocationTracesTops");
},
/**
* @param {number} nodeId
* @param {function(!WebInspector.HeapSnapshotCommon.AllocationNodeCallers)} callback
*/
allocationNodeCallers: function(nodeId, callback)
{
this.callMethod(callback, "allocationNodeCallers", nodeId);
},
/**
* @param {number} nodeIndex
* @param {function(?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>)} callback
*/
allocationStack: function(nodeIndex, callback)
{
this.callMethod(callback, "allocationStack", nodeIndex);
},
dispose: function()
{
throw new Error("Should never be called");
},
get nodeCount()
{
return this._staticData.nodeCount;
},
get rootNodeIndex()
{
return this._staticData.rootNodeIndex;
},
updateStaticData: function(callback)
{
/**
* @param {!WebInspector.HeapSnapshotCommon.StaticData} staticData
* @this {WebInspector.HeapSnapshotProxy}
*/
function dataReceived(staticData)
{
this._staticData = staticData;
callback(this);
}
this.callMethod(dataReceived.bind(this), "updateStaticData");
},
/**
* @return {!Promise.<!WebInspector.HeapSnapshotCommon.Statistics>}
*/
getStatistics: function()
{
return this._callMethodPromise("getStatistics");
},
/**
* @return {!Promise.<?WebInspector.HeapSnapshotCommon.Samples>}
*/
getSamples: function()
{
return this._callMethodPromise("getSamples");
},
get totalSize()
{
return this._staticData.totalSize;
},
get uid()
{
return this._profileUid;
},
setProfileUid: function(profileUid)
{
this._profileUid = profileUid;
},
/**
* @return {number}
*/
maxJSObjectId: function()
{
return this._staticData.maxJSObjectId;
},
__proto__: WebInspector.HeapSnapshotProxyObject.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
* @implements {WebInspector.HeapSnapshotGridNode.ChildrenProvider}
* @param {!WebInspector.HeapSnapshotWorkerProxy} worker
* @param {number} objectId
*/
WebInspector.HeapSnapshotProviderProxy = function(worker, objectId)
{
WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId);
}
WebInspector.HeapSnapshotProviderProxy.prototype = {
/**
* @override
* @param {number} snapshotObjectId
* @return {!Promise<number>}
*/
nodePosition: function(snapshotObjectId)
{
return this._callMethodPromise("nodePosition", snapshotObjectId);
},
/**
* @override
* @param {function(boolean)} callback
*/
isEmpty: function(callback)
{
this.callMethod(callback, "isEmpty");
},
/**
* @override
* @param {number} startPosition
* @param {number} endPosition
* @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
*/
serializeItemsRange: function(startPosition, endPosition, callback)
{
this.callMethod(callback, "serializeItemsRange", startPosition, endPosition);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
* @return {!Promise<?>}
*/
sortAndRewind: function(comparator)
{
return this._callMethodPromise("sortAndRewind", comparator);
},
__proto__: WebInspector.HeapSnapshotProxyObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.ProfileType.DataDisplayDelegate}
* @implements {WebInspector.Searchable}
* @extends {WebInspector.VBox}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!WebInspector.HeapProfileHeader} profile
*/
WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile)
{
WebInspector.VBox.call(this);
this.element.classList.add("heap-snapshot-view");
profile.profileType().addEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
profile.profileType().addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
var isHeapTimeline = profile.profileType().id === WebInspector.TrackingHeapSnapshotProfileType.TypeId;
if (isHeapTimeline) {
this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile);
this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
}
this._parentDataDisplayDelegate = dataDisplayDelegate;
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.show(this.element);
this._splitWidget = new WebInspector.SplitWidget(false, true, "heapSnapshotSplitViewState", 200, 200);
this._splitWidget.show(this._searchableView.element);
this._containmentDataGrid = new WebInspector.HeapSnapshotContainmentDataGrid(this);
this._containmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
this._containmentWidget = this._containmentDataGrid.asWidget();
this._containmentWidget.setMinimumSize(50, 25);
this._statisticsView = new WebInspector.HeapSnapshotStatisticsView();
this._constructorsDataGrid = new WebInspector.HeapSnapshotConstructorsDataGrid(this);
this._constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
this._constructorsWidget = this._constructorsDataGrid.asWidget();
this._constructorsWidget.setMinimumSize(50, 25);
this._diffDataGrid = new WebInspector.HeapSnapshotDiffDataGrid(this);
this._diffDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
this._diffWidget = this._diffDataGrid.asWidget();
this._diffWidget.setMinimumSize(50, 25);
if (isHeapTimeline && WebInspector.moduleSetting("recordAllocationStacks").get()) {
this._allocationDataGrid = new WebInspector.AllocationDataGrid(profile.target() , this);
this._allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this);
this._allocationWidget = this._allocationDataGrid.asWidget();
this._allocationWidget.setMinimumSize(50, 25);
this._allocationStackView = new WebInspector.HeapAllocationStackView(profile.target());
this._allocationStackView.setMinimumSize(50, 25);
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.headerElement().classList.add("heap-object-details-header");
}
this._retainmentDataGrid = new WebInspector.HeapSnapshotRetainmentDataGrid(this);
this._retainmentWidget = this._retainmentDataGrid.asWidget();
this._retainmentWidget.setMinimumSize(50, 21);
this._retainmentWidget.element.classList.add("retaining-paths-view");
var splitWidgetResizer;
if (this._allocationStackView) {
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.headerElement().classList.add("heap-object-details-header");
this._tabbedPane.appendTab("retainers", WebInspector.UIString("Retainers"), this._retainmentWidget);
this._tabbedPane.appendTab("allocation-stack", WebInspector.UIString("Allocation stack"), this._allocationStackView);
splitWidgetResizer = this._tabbedPane.headerElement();
this._objectDetailsView = this._tabbedPane;
} else {
var retainmentViewHeader = createElementWithClass("div", "heap-snapshot-view-resizer");
var retainingPathsTitleDiv = retainmentViewHeader.createChild("div", "title");
var retainingPathsTitle = retainingPathsTitleDiv.createChild("span");
retainingPathsTitle.textContent = WebInspector.UIString("Retainers");
splitWidgetResizer = retainmentViewHeader;
this._objectDetailsView = new WebInspector.VBox();
this._objectDetailsView.element.appendChild(retainmentViewHeader);
this._retainmentWidget.show(this._objectDetailsView.element);
}
this._splitWidget.hideDefaultResizer();
this._splitWidget.installResizer(splitWidgetResizer);
this._retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
this._retainmentDataGrid.reset();
this._perspectives = [];
this._perspectives.push(new WebInspector.HeapSnapshotView.SummaryPerspective());
if (profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
this._perspectives.push(new WebInspector.HeapSnapshotView.ComparisonPerspective());
this._perspectives.push(new WebInspector.HeapSnapshotView.ContainmentPerspective());
if (this._allocationWidget)
this._perspectives.push(new WebInspector.HeapSnapshotView.AllocationPerspective());
this._perspectives.push(new WebInspector.HeapSnapshotView.StatisticsPerspective());
this._perspectiveSelect = new WebInspector.ToolbarComboBox(this._onSelectedPerspectiveChanged.bind(this));
for (var i = 0; i < this._perspectives.length; ++i)
this._perspectiveSelect.createOption(this._perspectives[i].title());
this._profile = profile;
this._baseSelect = new WebInspector.ToolbarComboBox(this._changeBase.bind(this));
this._baseSelect.setVisible(false);
this._updateBaseOptions();
this._filterSelect = new WebInspector.ToolbarComboBox(this._changeFilter.bind(this));
this._filterSelect.setVisible(false);
this._updateFilterOptions();
this._classNameFilter = new WebInspector.ToolbarInput("Class filter");
this._classNameFilter.setVisible(false);
this._constructorsDataGrid.setNameFilter(this._classNameFilter);
this._diffDataGrid.setNameFilter(this._classNameFilter);
this._selectedSizeText = new WebInspector.ToolbarText();
this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true);
this._currentPerspectiveIndex = 0;
this._currentPerspective = this._perspectives[0];
this._currentPerspective.activate(this);
this._dataGrid = this._currentPerspective.masterGrid(this);
this._populate();
this._searchThrottler = new WebInspector.Throttler(0);
}
/**
* @constructor
* @param {string} title
*/
WebInspector.HeapSnapshotView.Perspective = function(title)
{
this._title = title;
}
WebInspector.HeapSnapshotView.Perspective.prototype = {
/**
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView) { },
/**
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
deactivate: function(heapSnapshotView)
{
heapSnapshotView._baseSelect.setVisible(false);
heapSnapshotView._filterSelect.setVisible(false);
heapSnapshotView._classNameFilter.setVisible(false);
if (heapSnapshotView._trackingOverviewGrid)
heapSnapshotView._trackingOverviewGrid.detach();
if (heapSnapshotView._allocationWidget)
heapSnapshotView._allocationWidget.detach();
if (heapSnapshotView._statisticsView)
heapSnapshotView._statisticsView.detach();
heapSnapshotView._splitWidget.detach();
heapSnapshotView._splitWidget.detachChildWidgets();
},
/**
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return null;
},
/**
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @return {boolean}
*/
supportsSearch: function()
{
return false;
}
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotView.Perspective}
*/
WebInspector.HeapSnapshotView.SummaryPerspective = function()
{
WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Summary"));
}
WebInspector.HeapSnapshotView.SummaryPerspective.prototype = {
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView)
{
heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
heapSnapshotView._filterSelect.setVisible(true);
heapSnapshotView._classNameFilter.setVisible(true);
if (heapSnapshotView._trackingOverviewGrid) {
heapSnapshotView._trackingOverviewGrid.show(heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element);
heapSnapshotView._trackingOverviewGrid.update();
heapSnapshotView._trackingOverviewGrid._updateGrid();
}
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return heapSnapshotView._constructorsDataGrid;
},
/**
* @override
* @return {boolean}
*/
supportsSearch: function()
{
return true;
},
__proto__: WebInspector.HeapSnapshotView.Perspective.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotView.Perspective}
*/
WebInspector.HeapSnapshotView.ComparisonPerspective = function()
{
WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Comparison"));
}
WebInspector.HeapSnapshotView.ComparisonPerspective.prototype = {
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView)
{
heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget);
heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
heapSnapshotView._baseSelect.setVisible(true);
heapSnapshotView._classNameFilter.setVisible(true);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return heapSnapshotView._diffDataGrid;
},
/**
* @override
* @return {boolean}
*/
supportsSearch: function()
{
return true;
},
__proto__: WebInspector.HeapSnapshotView.Perspective.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotView.Perspective}
*/
WebInspector.HeapSnapshotView.ContainmentPerspective = function()
{
WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Containment"));
}
WebInspector.HeapSnapshotView.ContainmentPerspective.prototype = {
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView)
{
heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget);
heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return heapSnapshotView._containmentDataGrid;
},
__proto__: WebInspector.HeapSnapshotView.Perspective.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotView.Perspective}
*/
WebInspector.HeapSnapshotView.AllocationPerspective = function()
{
WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Allocation"));
this._allocationSplitWidget = new WebInspector.SplitWidget(false, true, "heapSnapshotAllocationSplitViewState", 200, 200);
this._allocationSplitWidget.setSidebarWidget(new WebInspector.VBox());
}
WebInspector.HeapSnapshotView.AllocationPerspective.prototype = {
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView)
{
this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget);
heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
var allocatedObjectsView = new WebInspector.VBox();
var resizer = createElementWithClass("div", "heap-snapshot-view-resizer");
var title = resizer.createChild("div", "title").createChild("span");
title.textContent = WebInspector.UIString("Live objects");
this._allocationSplitWidget.hideDefaultResizer();
this._allocationSplitWidget.installResizer(resizer);
allocatedObjectsView.element.appendChild(resizer);
heapSnapshotView._splitWidget.show(allocatedObjectsView.element);
this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView);
this._allocationSplitWidget.show(heapSnapshotView._searchableView.element);
heapSnapshotView._constructorsDataGrid.clear();
var selectedNode = heapSnapshotView._allocationDataGrid.selectedNode;
if (selectedNode)
heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
deactivate: function(heapSnapshotView)
{
this._allocationSplitWidget.detach();
WebInspector.HeapSnapshotView.Perspective.prototype.deactivate.call(this, heapSnapshotView);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return heapSnapshotView._allocationDataGrid;
},
__proto__: WebInspector.HeapSnapshotView.Perspective.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotView.Perspective}
*/
WebInspector.HeapSnapshotView.StatisticsPerspective = function()
{
WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Statistics"));
}
WebInspector.HeapSnapshotView.StatisticsPerspective.prototype = {
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
*/
activate: function(heapSnapshotView)
{
heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element);
},
/**
* @override
* @param {!WebInspector.HeapSnapshotView} heapSnapshotView
* @return {?WebInspector.DataGrid}
*/
masterGrid: function(heapSnapshotView)
{
return null;
},
__proto__: WebInspector.HeapSnapshotView.Perspective.prototype
}
WebInspector.HeapSnapshotView.prototype = {
/**
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
/**
* @override
* @param {?WebInspector.ProfileHeader} profile
* @return {?WebInspector.Widget}
*/
showProfile: function(profile)
{
return this._parentDataDisplayDelegate.showProfile(profile);
},
/**
* @override
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
* @param {string} perspectiveName
*/
showObject: function(snapshotObjectId, perspectiveName)
{
if (snapshotObjectId <= this._profile.maxJSObjectId)
this.selectLiveObject(perspectiveName, snapshotObjectId);
else
this._parentDataDisplayDelegate.showObject(snapshotObjectId, perspectiveName);
},
_populate: function()
{
this._profile._loadPromise.then(heapSnapshotProxy => {
heapSnapshotProxy.getStatistics().then(this._gotStatistics.bind(this));
this._dataGrid.setDataSource(heapSnapshotProxy);
if (this._profile.profileType().id === WebInspector.TrackingHeapSnapshotProfileType.TypeId && this._profile.fromFile())
return heapSnapshotProxy.getSamples().then(samples => this._trackingOverviewGrid._setSamples(samples));
}).then(_ => {
var list = this._profiles();
var profileIndex = list.indexOf(this._profile);
this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
if (this._trackingOverviewGrid)
this._trackingOverviewGrid._updateGrid();
});
},
/**
* @param {!WebInspector.HeapSnapshotCommon.Statistics} statistics
*/
_gotStatistics: function(statistics)
{
this._statisticsView.setTotal(statistics.total);
this._statisticsView.addRecord(statistics.code, WebInspector.UIString("Code"), "#f77");
this._statisticsView.addRecord(statistics.strings, WebInspector.UIString("Strings"), "#5e5");
this._statisticsView.addRecord(statistics.jsArrays, WebInspector.UIString("JS Arrays"), "#7af");
this._statisticsView.addRecord(statistics.native, WebInspector.UIString("Typed Arrays"), "#fc5");
this._statisticsView.addRecord(statistics.system, WebInspector.UIString("System Objects"), "#98f");
this._statisticsView.addRecord(statistics.total, WebInspector.UIString("Total"));
},
/**
* @param {!WebInspector.Event} event
*/
_onIdsRangeChanged: function(event)
{
var minId = event.data.minId;
var maxId = event.data.maxId;
this._selectedSizeText.setText(WebInspector.UIString("Selected size: %s", Number.bytesToString(event.data.size)));
if (this._constructorsDataGrid.snapshot)
this._constructorsDataGrid.setSelectionRange(minId, maxId);
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
var result = [this._perspectiveSelect, this._classNameFilter];
if (this._profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
result.push(this._baseSelect, this._filterSelect);
result.push(this._selectedSizeText);
return result;
},
/**
* @override
*/
wasShown: function()
{
this._profile._loadPromise.then(this._profile._wasShown.bind(this._profile));
},
/**
* @override
*/
willHide: function()
{
this._currentSearchResultIndex = -1;
this._popoverHelper.hidePopover();
if (this.helpPopover && this.helpPopover.isShowing())
this.helpPopover.hide();
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
/**
* @override
*/
searchCanceled: function()
{
this._currentSearchResultIndex = -1;
this._searchResults = [];
},
/**
* @param {?WebInspector.HeapSnapshotGridNode} node
*/
_selectRevealedNode: function(node)
{
if (node)
node.select();
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var nextQuery = new WebInspector.HeapSnapshotCommon.SearchConfig(
searchConfig.query.trim(),
searchConfig.caseSensitive,
searchConfig.isRegex,
shouldJump,
jumpBackwards || false
);
this._searchThrottler.schedule(this._performSearch.bind(this, nextQuery));
},
/**
* @param {!WebInspector.HeapSnapshotCommon.SearchConfig} nextQuery
* @return {!Promise<?>}
*/
_performSearch: function(nextQuery)
{
// Call searchCanceled since it will reset everything we need before doing a new search.
this.searchCanceled();
if (!this._currentPerspective.supportsSearch())
return Promise.resolve();
this.currentQuery = nextQuery;
var query = nextQuery.query.trim();
if (!query)
return Promise.resolve();
if (query.charAt(0) === "@") {
var snapshotNodeId = parseInt(query.substring(1), 10);
if (isNaN(snapshotNodeId))
return Promise.resolve();
return this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId)).then(this._selectRevealedNode.bind(this));
}
/**
* @param {!Array<number>} entryIds
* @return {!Promise<?>}
* @this {WebInspector.HeapSnapshotView}
*/
function didSearch(entryIds)
{
this._searchResults = entryIds;
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
if (this._searchResults.length)
this._currentSearchResultIndex = nextQuery.jumpBackwards ? this._searchResults.length - 1 : 0;
return this._jumpToSearchResult(this._currentSearchResultIndex);
}
return this._profile._snapshotProxy.search(this.currentQuery, this._dataGrid.nodeFilter()).then(didSearch.bind(this));
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = (this._currentSearchResultIndex + 1) % this._searchResults.length;
this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = (this._currentSearchResultIndex + this._searchResults.length - 1) % this._searchResults.length;
this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
},
/**
* @param {number} searchResultIndex
* @return {!Promise<undefined>}
*/
_jumpToSearchResult: function(searchResultIndex)
{
this._searchableView.updateCurrentMatchIndex(searchResultIndex);
return this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex])).then(this._selectRevealedNode.bind(this));
},
refreshVisibleData: function()
{
if (!this._dataGrid)
return;
var child = this._dataGrid.rootNode().children[0];
while (child) {
child.refresh();
child = child.traverseNextNode(false, null, true);
}
},
_changeBase: function()
{
if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()])
return;
this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this._dataGrid);
// Change set base data source only if main data source is already set.
if (dataGrid.snapshot)
this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid));
if (!this.currentQuery || !this._searchResults)
return;
// The current search needs to be performed again. First negate out previous match
// count by calling the search finished callback with a negative number of matches.
// Then perform the search again with the same query and callback.
this.performSearch(this.currentQuery, false);
},
_changeFilter: function()
{
var profileIndex = this._filterSelect.selectedIndex() - 1;
this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);
if (!this.currentQuery || !this._searchResults)
return;
// The current search needs to be performed again. First negate out previous match
// count by calling the search finished callback with a negative number of matches.
// Then perform the search again with the same query and callback.
this.performSearch(this.currentQuery, false);
},
/**
* @return {!Array.<!WebInspector.ProfileHeader>}
*/
_profiles: function()
{
return this._profile.profileType().getProfiles();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Event} event
*/
populateContextMenu: function(contextMenu, event)
{
if (this._dataGrid)
this._dataGrid.populateContextMenu(contextMenu, event);
},
_selectionChanged: function(event)
{
var selectedNode = event.target.selectedNode;
this._setSelectedNodeForDetailsView(selectedNode);
this._inspectedObjectChanged(event);
},
_onSelectAllocationNode: function(event)
{
var selectedNode = event.target.selectedNode;
this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
this._setSelectedNodeForDetailsView(null);
},
_inspectedObjectChanged: function(event)
{
var selectedNode = event.target.selectedNode;
var target = this._profile.target();
if (target && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode)
target.heapProfilerAgent().addInspectedHeapObject(String(selectedNode.snapshotNodeId));
},
/**
* @param {?WebInspector.HeapSnapshotGridNode} nodeItem
*/
_setSelectedNodeForDetailsView: function(nodeItem)
{
var dataSource = nodeItem && nodeItem.retainersDataSource();
if (dataSource) {
this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex);
if (this._allocationStackView)
this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex);
} else {
if (this._allocationStackView)
this._allocationStackView.clear();
this._retainmentDataGrid.reset();
}
},
/**
* @param {string} perspectiveTitle
* @param {function()} callback
*/
_changePerspectiveAndWait: function(perspectiveTitle, callback)
{
var perspectiveIndex = null;
for (var i = 0; i < this._perspectives.length; ++i) {
if (this._perspectives[i].title() === perspectiveTitle) {
perspectiveIndex = i;
break;
}
}
if (this._currentPerspectiveIndex === perspectiveIndex || perspectiveIndex === null) {
setTimeout(callback, 0);
return;
}
/**
* @this {WebInspector.HeapSnapshotView}
*/
function dataGridContentShown(event)
{
var dataGrid = event.data;
dataGrid.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
if (dataGrid === this._dataGrid)
callback();
}
this._perspectives[perspectiveIndex].masterGrid(this).addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
this._perspectiveSelect.setSelectedIndex(perspectiveIndex);
this._changePerspective(perspectiveIndex);
},
_updateDataSourceAndView: function()
{
var dataGrid = this._dataGrid;
if (!dataGrid || dataGrid.snapshot)
return;
this._profile._loadPromise.then(didLoadSnapshot.bind(this));
/**
* @this {WebInspector.HeapSnapshotView}
*/
function didLoadSnapshot(snapshotProxy)
{
if (this._dataGrid !== dataGrid)
return;
if (dataGrid.snapshot !== snapshotProxy)
dataGrid.setDataSource(snapshotProxy);
if (dataGrid === this._diffDataGrid) {
if (!this._baseProfile)
this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
this._baseProfile._loadPromise.then(didLoadBaseSnaphot.bind(this));
}
}
/**
* @this {WebInspector.HeapSnapshotView}
*/
function didLoadBaseSnaphot(baseSnapshotProxy)
{
if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy)
this._diffDataGrid.setBaseDataSource(baseSnapshotProxy);
}
},
_onSelectedPerspectiveChanged: function(event)
{
this._changePerspective(event.target.selectedIndex);
},
/**
* @param {number} selectedIndex
*/
_changePerspective: function(selectedIndex)
{
if (selectedIndex === this._currentPerspectiveIndex)
return;
this._currentPerspectiveIndex = selectedIndex;
this._currentPerspective.deactivate(this);
var perspective = this._perspectives[selectedIndex];
this._currentPerspective = perspective;
this._dataGrid = perspective.masterGrid(this);
perspective.activate(this);
this.refreshVisibleData();
if (this._dataGrid)
this._dataGrid.updateWidths();
this._updateDataSourceAndView();
if (!this.currentQuery || !this._searchResults)
return;
// The current search needs to be performed again. First negate out previous match
// count by calling the search finished callback with a negative number of matches.
// Then perform the search again the with same query and callback.
this.performSearch(this.currentQuery, false);
},
/**
* @param {string} perspectiveName
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
*/
selectLiveObject: function(perspectiveName, snapshotObjectId)
{
this._changePerspectiveAndWait(perspectiveName, didChangePerspective.bind(this));
/**
* @this {WebInspector.HeapSnapshotView}
*/
function didChangePerspective()
{
this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId, didRevealObject);
}
/**
* @param {?WebInspector.HeapSnapshotGridNode} node
*/
function didRevealObject(node)
{
if (node)
node.select();
else
WebInspector.console.error("Cannot find corresponding heap snapshot node");
}
},
_getHoverAnchor: function(target)
{
var span = target.enclosingNodeOrSelfWithNodeName("span");
if (!span)
return;
var row = target.enclosingNodeOrSelfWithNodeName("tr");
if (!row)
return;
span.node = row._dataGridNode;
return span;
},
_resolveObjectForPopover: function(element, showCallback, objectGroupName)
{
if (!this._profile.target())
return;
if (!element.node)
return;
element.node.queryObjectContent(this._profile.target(), showCallback, objectGroupName);
},
_updateBaseOptions: function()
{
var list = this._profiles();
// We're assuming that snapshots can only be added.
if (this._baseSelect.size() === list.length)
return;
for (var i = this._baseSelect.size(), n = list.length; i < n; ++i) {
var title = list[i].title;
this._baseSelect.createOption(title);
}
},
_updateFilterOptions: function()
{
var list = this._profiles();
// We're assuming that snapshots can only be added.
if (this._filterSelect.size() - 1 === list.length)
return;
if (!this._filterSelect.size())
this._filterSelect.createOption(WebInspector.UIString("All objects"));
for (var i = this._filterSelect.size() - 1, n = list.length; i < n; ++i) {
var title = list[i].title;
if (!i)
title = WebInspector.UIString("Objects allocated before %s", title);
else
title = WebInspector.UIString("Objects allocated between %s and %s", list[i - 1].title, title);
this._filterSelect.createOption(title);
}
},
_updateControls: function()
{
this._updateBaseOptions();
this._updateFilterOptions();
},
/**
* @param {!WebInspector.Event} event
*/
_onReceiveSnapshot: function(event)
{
this._updateControls();
},
/**
* @param {!WebInspector.Event} event
*/
_onProfileHeaderRemoved: function(event)
{
var profile = event.data;
if (this._profile === profile) {
this.detach();
this._profile.profileType().removeEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
this.dispose();
} else {
this._updateControls();
}
},
dispose: function()
{
if (this._allocationStackView) {
this._allocationStackView.clear();
this._allocationDataGrid.dispose();
}
if (this._trackingOverviewGrid)
this._trackingOverviewGrid.dispose();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileType}
* @implements {WebInspector.TargetManager.Observer}
* @param {string=} id
* @param {string=} title
*/
WebInspector.HeapSnapshotProfileType = function(id, title)
{
WebInspector.ProfileType.call(this, id || WebInspector.HeapSnapshotProfileType.TypeId, title || WebInspector.UIString("Take Heap Snapshot"));
WebInspector.targetManager.observeTargets(this);
WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ResetProfiles, this._resetProfiles, this);
WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk, this._addHeapSnapshotChunk, this);
WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress, this._reportHeapSnapshotProgress, this);
}
WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
WebInspector.HeapSnapshotProfileType.SnapshotReceived = "SnapshotReceived";
WebInspector.HeapSnapshotProfileType.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
target.heapProfilerModel.enable();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
},
/**
* @override
* @return {string}
*/
fileExtension: function()
{
return ".heapsnapshot";
},
get buttonTooltip()
{
return WebInspector.UIString("Take heap snapshot.");
},
/**
* @override
* @return {boolean}
*/
isInstantProfile: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
buttonClicked: function()
{
this._takeHeapSnapshot(function() {});
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesHeapProfileTaken);
return false;
},
get treeItemTitle()
{
return WebInspector.UIString("HEAP SNAPSHOTS");
},
get description()
{
return WebInspector.UIString("Heap snapshot profiles show memory distribution among your page's JavaScript objects and related DOM nodes.");
},
/**
* @override
* @param {string} title
* @return {!WebInspector.ProfileHeader}
*/
createProfileLoadedFromFile: function(title)
{
return new WebInspector.HeapProfileHeader(null, this, title);
},
_takeHeapSnapshot: function(callback)
{
if (this.profileBeingRecorded())
return;
var target = /** @type {!WebInspector.Target} */ (WebInspector.context.flavor(WebInspector.Target));
var profile = new WebInspector.HeapProfileHeader(target, this);
this.setProfileBeingRecorded(profile);
this.addProfile(profile);
profile.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
/**
* @param {?string} error
* @this {WebInspector.HeapSnapshotProfileType}
*/
function didTakeHeapSnapshot(error)
{
var profile = this._profileBeingRecorded;
profile.title = WebInspector.UIString("Snapshot %d", profile.uid);
profile._finishLoad();
this.setProfileBeingRecorded(null);
this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile);
callback();
}
target.heapProfilerAgent().takeHeapSnapshot(true, didTakeHeapSnapshot.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_addHeapSnapshotChunk: function(event)
{
if (!this.profileBeingRecorded())
return;
var chunk = /** @type {string} */(event.data);
this.profileBeingRecorded().transferChunk(chunk);
},
/**
* @param {!WebInspector.Event} event
*/
_reportHeapSnapshotProgress: function(event)
{
var profile = this.profileBeingRecorded();
if (!profile)
return;
var data = /** @type {{done: number, total: number, finished: boolean}} */ (event.data);
profile.updateStatus(WebInspector.UIString("%.0f%%", (data.done / data.total) * 100), true);
if (data.finished)
profile._prepareToLoad();
},
_resetProfiles: function()
{
this._reset();
},
_snapshotReceived: function(profile)
{
if (this._profileBeingRecorded === profile)
this.setProfileBeingRecorded(null);
this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile);
},
__proto__: WebInspector.ProfileType.prototype
}
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProfileType}
*/
WebInspector.TrackingHeapSnapshotProfileType = function()
{
WebInspector.HeapSnapshotProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Heap Allocations"));
}
WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate = "HeapStatsUpdate";
WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted = "TrackingStarted";
WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped = "TrackingStopped";
/**
* @constructor
*/
WebInspector.TrackingHeapSnapshotProfileType.Samples = function()
{
/** @type {!Array.<number>} */
this.sizes = [];
/** @type {!Array.<number>} */
this.ids = [];
/** @type {!Array.<number>} */
this.timestamps = [];
/** @type {!Array.<number>} */
this.max = [];
/** @type {number} */
this.totalTime = 30000;
}
WebInspector.TrackingHeapSnapshotProfileType.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
WebInspector.HeapSnapshotProfileType.prototype.targetAdded.call(this, target);
target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
WebInspector.HeapSnapshotProfileType.prototype.targetRemoved.call(this, target);
target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
},
/**
* @param {!WebInspector.Event} event
*/
_heapStatsUpdate: function(event)
{
if (!this._profileSamples)
return;
var samples = /** @type {!Array.<number>} */ (event.data);
var index;
for (var i = 0; i < samples.length; i += 3) {
index = samples[i];
var size = samples[i+2];
this._profileSamples.sizes[index] = size;
if (!this._profileSamples.max[index])
this._profileSamples.max[index] = size;
}
},
/**
* @param {!WebInspector.Event} event
*/
_lastSeenObjectId: function(event)
{
var profileSamples = this._profileSamples;
if (!profileSamples)
return;
var data = /** @type {{lastSeenObjectId: number, timestamp: number}} */ (event.data);
var currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1);
profileSamples.ids[currentIndex] = data.lastSeenObjectId;
if (!profileSamples.max[currentIndex]) {
profileSamples.max[currentIndex] = 0;
profileSamples.sizes[currentIndex] = 0;
}
profileSamples.timestamps[currentIndex] = data.timestamp;
if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0])
profileSamples.totalTime *= 2;
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
this._profileBeingRecorded.updateStatus(null, true);
},
/**
* @override
* @return {boolean}
*/
hasTemporaryView: function()
{
return true;
},
get buttonTooltip()
{
return this._recording ? WebInspector.UIString("Stop recording heap profile.") : WebInspector.UIString("Start recording heap profile.");
},
/**
* @override
* @return {boolean}
*/
isInstantProfile: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
buttonClicked: function()
{
return this._toggleRecording();
},
_startRecordingProfile: function()
{
if (this.profileBeingRecorded())
return;
this._addNewProfile();
var recordAllocationStacks = WebInspector.moduleSetting("recordAllocationStacks").get();
this.profileBeingRecorded().target().heapProfilerAgent().startTrackingHeapObjects(recordAllocationStacks);
},
_addNewProfile: function()
{
var target = WebInspector.context.flavor(WebInspector.Target);
this.setProfileBeingRecorded(new WebInspector.HeapProfileHeader(target, this, undefined));
this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples();
this._profileBeingRecorded._profileSamples = this._profileSamples;
this._recording = true;
this.addProfile(this._profileBeingRecorded);
this._profileBeingRecorded.updateStatus(WebInspector.UIString("Recording\u2026"));
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted);
},
_stopRecordingProfile: function()
{
this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
/**
* @param {?string} error
* @this {WebInspector.HeapSnapshotProfileType}
*/
function didTakeHeapSnapshot(error)
{
var profile = this.profileBeingRecorded();
if (!profile)
return;
profile._finishLoad();
this._profileSamples = null;
this.setProfileBeingRecorded(null);
this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile);
}
this._profileBeingRecorded.target().heapProfilerAgent().stopTrackingHeapObjects(true, didTakeHeapSnapshot.bind(this));
this._recording = false;
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped);
},
_toggleRecording: function()
{
if (this._recording)
this._stopRecordingProfile();
else
this._startRecordingProfile();
return this._recording;
},
/**
* @override
* @return {string}
*/
fileExtension: function()
{
return ".heaptimeline";
},
get treeItemTitle()
{
return WebInspector.UIString("HEAP TIMELINES");
},
get description()
{
return WebInspector.UIString("Record JavaScript object allocations over time. Use this profile type to isolate memory leaks.");
},
/**
* @override
*/
_resetProfiles: function()
{
var wasRecording = this._recording;
// Clear current profile to avoid stopping backend.
this.setProfileBeingRecorded(null);
WebInspector.HeapSnapshotProfileType.prototype._resetProfiles.call(this);
this._profileSamples = null;
if (wasRecording)
this._addNewProfile();
},
/**
* @override
*/
profileBeingRecordedRemoved: function()
{
this._stopRecordingProfile();
this._profileSamples = null;
},
__proto__: WebInspector.HeapSnapshotProfileType.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileHeader}
* @param {?WebInspector.Target} target
* @param {!WebInspector.HeapSnapshotProfileType} type
* @param {string=} title
*/
WebInspector.HeapProfileHeader = function(target, type, title)
{
WebInspector.ProfileHeader.call(this, target, type, title || WebInspector.UIString("Snapshot %d", type.nextProfileUid()));
this.maxJSObjectId = -1;
/**
* @type {?WebInspector.HeapSnapshotWorkerProxy}
*/
this._workerProxy = null;
/**
* @type {?WebInspector.OutputStream}
*/
this._receiver = null;
/**
* @type {?WebInspector.HeapSnapshotProxy}
*/
this._snapshotProxy = null;
/**
* @type {!Promise.<!WebInspector.HeapSnapshotProxy>}
*/
this._loadPromise = new Promise(loadResolver.bind(this));
this._totalNumberOfChunks = 0;
this._bufferedWriter = null;
/**
* @param {function(!WebInspector.HeapSnapshotProxy)} fulfill
* @this {WebInspector.HeapProfileHeader}
*/
function loadResolver(fulfill)
{
this._fulfillLoad = fulfill;
}
}
WebInspector.HeapProfileHeader.prototype = {
/**
* @override
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!WebInspector.ProfileSidebarTreeElement}
*/
createSidebarTreeElement: function(dataDisplayDelegate)
{
return new WebInspector.ProfileSidebarTreeElement(dataDisplayDelegate, this, "heap-snapshot-sidebar-tree-item");
},
/**
* @override
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!WebInspector.HeapSnapshotView}
*/
createView: function(dataDisplayDelegate)
{
return new WebInspector.HeapSnapshotView(dataDisplayDelegate, this);
},
_prepareToLoad: function()
{
console.assert(!this._receiver, "Already loading");
this._setupWorker();
this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
},
_finishLoad: function()
{
if (!this._wasDisposed)
this._receiver.close();
if (this._bufferedWriter) {
this._bufferedWriter.finishWriting(this._didWriteToTempFile.bind(this));
this._bufferedWriter = null;
}
},
_didWriteToTempFile: function(tempFile)
{
if (this._wasDisposed) {
if (tempFile)
tempFile.remove();
return;
}
this._tempFile = tempFile;
if (!tempFile)
this._failedToCreateTempFile = true;
if (this._onTempFileReady) {
this._onTempFileReady();
this._onTempFileReady = null;
}
},
_setupWorker: function()
{
/**
* @this {WebInspector.HeapProfileHeader}
*/
function setProfileWait(event)
{
this.updateStatus(null, event.data);
}
console.assert(!this._workerProxy, "HeapSnapshotWorkerProxy already exists");
this._workerProxy = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
this._workerProxy.addEventListener("wait", setProfileWait, this);
this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
},
/**
* @param {string} eventName
* @param {*} data
*/
_handleWorkerEvent: function(eventName, data)
{
if (WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) {
var error = /** @type {string} */ (data);
WebInspector.console.error(error);
return;
}
if (WebInspector.HeapSnapshotProgressEvent.Update !== eventName)
return;
var subtitle = /** @type {string} */ (data);
this.updateStatus(subtitle);
},
/**
* @override
*/
dispose: function()
{
if (this._workerProxy)
this._workerProxy.dispose();
this.removeTempFile();
this._wasDisposed = true;
},
_didCompleteSnapshotTransfer: function()
{
if (!this._snapshotProxy)
return;
this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false);
},
/**
* @param {string} chunk
*/
transferChunk: function(chunk)
{
if (!this._bufferedWriter)
this._bufferedWriter = new WebInspector.DeferredTempFile("heap-profiler", String(this.uid));
this._bufferedWriter.write([chunk]);
++this._totalNumberOfChunks;
this._receiver.write(chunk);
},
_snapshotReceived: function(snapshotProxy)
{
if (this._wasDisposed)
return;
this._receiver = null;
this._snapshotProxy = snapshotProxy;
this.maxJSObjectId = snapshotProxy.maxJSObjectId();
this._didCompleteSnapshotTransfer();
this._workerProxy.startCheckingForLongRunningCalls();
this.notifySnapshotReceived();
},
notifySnapshotReceived: function()
{
this._fulfillLoad(this._snapshotProxy);
this._profileType._snapshotReceived(this);
if (this.canSaveToFile())
this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);
},
// Hook point for tests.
_wasShown: function()
{
},
/**
* @override
* @return {boolean}
*/
canSaveToFile: function()
{
return !this.fromFile() && !!this._snapshotProxy;
},
/**
* @override
*/
saveToFile: function()
{
var fileOutputStream = new WebInspector.FileOutputStream();
/**
* @param {boolean} accepted
* @this {WebInspector.HeapProfileHeader}
*/
function onOpen(accepted)
{
if (!accepted)
return;
if (this._failedToCreateTempFile) {
WebInspector.console.error("Failed to open temp file with heap snapshot");
fileOutputStream.close();
} else if (this._tempFile) {
var delegate = new WebInspector.SaveSnapshotOutputStreamDelegate(this);
this._tempFile.copyToOutputStream(fileOutputStream, delegate);
} else {
this._onTempFileReady = onOpen.bind(this, accepted);
this._updateSaveProgress(0, 1);
}
}
this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
fileOutputStream.open(this._fileName, onOpen.bind(this));
},
_updateSaveProgress: function(value, total)
{
var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
this.updateStatus(WebInspector.UIString("Saving\u2026 %d%%", percentValue));
},
/**
* @override
* @param {!File} file
*/
loadFromFile: function(file)
{
this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
this._setupWorker();
var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this);
var fileReader = this._createFileReader(file, delegate);
fileReader.start(this._receiver);
},
_createFileReader: function(file, delegate)
{
return new WebInspector.ChunkedFileReader(file, 10000000, delegate);
},
__proto__: WebInspector.ProfileHeader.prototype
}
/**
* @constructor
* @implements {WebInspector.OutputStreamDelegate}
*/
WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader)
{
this._snapshotHeader = snapshotHeader;
}
WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = {
/**
* @override
*/
onTransferStarted: function()
{
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader)
{
},
/**
* @override
*/
onTransferFinished: function()
{
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
* @param {!Event} e
*/
onError: function(reader, e)
{
var subtitle;
switch(e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
break;
case e.target.error.NOT_READABLE_ERR:
subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
break;
case e.target.error.ABORT_ERR:
return;
default:
subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
}
this._snapshotHeader.updateStatus(subtitle);
}
}
/**
* @constructor
* @implements {WebInspector.OutputStreamDelegate}
* @param {!WebInspector.HeapProfileHeader} profileHeader
*/
WebInspector.SaveSnapshotOutputStreamDelegate = function(profileHeader)
{
this._profileHeader = profileHeader;
}
WebInspector.SaveSnapshotOutputStreamDelegate.prototype = {
/**
* @override
*/
onTransferStarted: function()
{
this._profileHeader._updateSaveProgress(0, 1);
},
/**
* @override
*/
onTransferFinished: function()
{
this._profileHeader._didCompleteSnapshotTransfer();
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader)
{
this._profileHeader._updateSaveProgress(reader.loadedSize(), reader.fileSize());
},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
* @param {!Event} event
*/
onError: function(reader, event)
{
WebInspector.console.error("Failed to read heap snapshot from temp file: " + /** @type {!ErrorEvent} */ (event).message);
this.onTransferFinished();
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.HeapProfileHeader} heapProfileHeader
*/
WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader)
{
WebInspector.VBox.call(this);
this.element.id = "heap-recording-view";
this.element.classList.add("heap-tracking-overview");
this._overviewContainer = this.element.createChild("div", "heap-overview-container");
this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
this._overviewGrid.element.classList.add("fill");
this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-recording-overview-canvas");
this._overviewContainer.appendChild(this._overviewGrid.element);
this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator();
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
this._profileSamples = heapProfileHeader.fromFile() ? new WebInspector.TrackingHeapSnapshotProfileType.Samples() : heapProfileHeader._profileSamples;
this._profileType = heapProfileHeader.profileType();
if (!heapProfileHeader.fromFile() && heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) {
this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
}
this._windowLeft = 0.0;
this._windowRight = 1.0;
this._overviewGrid.setWindow(this._windowLeft, this._windowRight);
this._yScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
this._xScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
}
WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged";
WebInspector.HeapTrackingOverviewGrid.prototype = {
dispose: function()
{
this._onStopTracking();
},
_onStopTracking: function()
{
this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
},
_onHeapStatsUpdate: function(event)
{
this._profileSamples = event.data;
this._scheduleUpdate();
},
/**
* @param {?WebInspector.HeapSnapshotCommon.Samples} samples
*/
_setSamples: function(samples)
{
if (!samples)
return;
console.assert(!this._profileSamples.timestamps.length, "Should only call this method when loading from file.");
console.assert(samples.timestamps.length);
this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples();
this._profileSamples.sizes = samples.sizes;
this._profileSamples.ids = samples.lastAssignedIds;
this._profileSamples.timestamps = samples.timestamps;
this._profileSamples.max = samples.sizes;
this._profileSamples.totalTime = /** @type{number} */(samples.timestamps.peekLast());
this.update();
},
/**
* @param {number} width
* @param {number} height
*/
_drawOverviewCanvas: function(width, height)
{
if (!this._profileSamples)
return;
var profileSamples = this._profileSamples;
var sizes = profileSamples.sizes;
var topSizes = profileSamples.max;
var timestamps = profileSamples.timestamps;
var startTime = timestamps[0];
var endTime = timestamps[timestamps.length - 1];
var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
var maxSize = 0;
/**
* @param {!Array.<number>} sizes
* @param {function(number, number):void} callback
*/
function aggregateAndCall(sizes, callback)
{
var size = 0;
var currentX = 0;
for (var i = 1; i < timestamps.length; ++i) {
var x = Math.floor((timestamps[i] - startTime) * scaleFactor);
if (x !== currentX) {
if (size)
callback(currentX, size);
size = 0;
currentX = x;
}
size += sizes[i];
}
callback(currentX, size);
}
/**
* @param {number} x
* @param {number} size
*/
function maxSizeCallback(x, size)
{
maxSize = Math.max(maxSize, size);
}
aggregateAndCall(sizes, maxSizeCallback);
var yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0);
this._overviewCanvas.width = width * window.devicePixelRatio;
this._overviewCanvas.height = height * window.devicePixelRatio;
this._overviewCanvas.style.width = width + "px";
this._overviewCanvas.style.height = height + "px";
var context = this._overviewCanvas.getContext("2d");
context.scale(window.devicePixelRatio, window.devicePixelRatio);
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = "rgba(192, 192, 192, 0.6)";
var currentX = (endTime - startTime) * scaleFactor;
context.moveTo(currentX, height - 1);
context.lineTo(currentX, 0);
context.stroke();
context.closePath();
var gridY;
var gridValue;
var gridLabelHeight = 14;
if (yScaleFactor) {
const maxGridValue = (height - gridLabelHeight) / yScaleFactor;
// The round value calculation is a bit tricky, because
// it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer,
// e.g. a round value 10KB is 10240 bytes.
gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024)));
gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10));
if (gridValue * 5 <= maxGridValue)
gridValue *= 5;
gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5;
context.beginPath();
context.lineWidth = 1;
context.strokeStyle = "rgba(0, 0, 0, 0.2)";
context.moveTo(0, gridY);
context.lineTo(width, gridY);
context.stroke();
context.closePath();
}
/**
* @param {number} x
* @param {number} size
*/
function drawBarCallback(x, size)
{
context.moveTo(x, height - 1);
context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
}
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = "rgba(192, 192, 192, 0.6)";
aggregateAndCall(topSizes, drawBarCallback);
context.stroke();
context.closePath();
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = "rgba(0, 0, 192, 0.8)";
aggregateAndCall(sizes, drawBarCallback);
context.stroke();
context.closePath();
if (gridValue) {
var label = Number.bytesToString(gridValue);
var labelPadding = 4;
var labelX = 0;
var labelY = gridY - 0.5;
var labelWidth = 2 * labelPadding + context.measureText(label).width;
context.beginPath();
context.textBaseline = "bottom";
context.font = "10px " + window.getComputedStyle(this.element, null).getPropertyValue("font-family");
context.fillStyle = "rgba(255, 255, 255, 0.75)";
context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight);
context.fillStyle = "rgb(64, 64, 64)";
context.fillText(label, labelX + labelPadding, labelY);
context.fill();
context.closePath();
}
},
onResize: function()
{
this._updateOverviewCanvas = true;
this._scheduleUpdate();
},
_onWindowChanged: function()
{
if (!this._updateGridTimerId)
this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10);
},
_scheduleUpdate: function()
{
if (this._updateTimerId)
return;
this._updateTimerId = setTimeout(this.update.bind(this), 10);
},
_updateBoundaries: function()
{
this._windowLeft = this._overviewGrid.windowLeft();
this._windowRight = this._overviewGrid.windowRight();
this._windowWidth = this._windowRight - this._windowLeft;
},
update: function()
{
this._updateTimerId = null;
if (!this.isShowing())
return;
this._updateBoundaries();
this._overviewCalculator._updateBoundaries(this);
this._overviewGrid.updateDividers(this._overviewCalculator);
this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
},
_updateGrid: function()
{
this._updateGridTimerId = 0;
this._updateBoundaries();
var ids = this._profileSamples.ids;
var timestamps = this._profileSamples.timestamps;
var sizes = this._profileSamples.sizes;
var startTime = timestamps[0];
var totalTime = this._profileSamples.totalTime;
var timeLeft = startTime + totalTime * this._windowLeft;
var timeRight = startTime + totalTime * this._windowRight;
var minId = 0;
var maxId = ids[ids.length - 1] + 1;
var size = 0;
for (var i = 0; i < timestamps.length; ++i) {
if (!timestamps[i])
continue;
if (timestamps[i] > timeRight)
break;
maxId = ids[i];
if (timestamps[i] < timeLeft) {
minId = ids[i];
continue;
}
size += sizes[i];
}
this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
*/
WebInspector.HeapTrackingOverviewGrid.SmoothScale = function()
{
this._lastUpdate = 0;
this._currentScale = 0.0;
}
WebInspector.HeapTrackingOverviewGrid.SmoothScale.prototype = {
/**
* @param {number} target
* @return {number}
*/
nextScale: function(target) {
target = target || this._currentScale;
if (this._currentScale) {
var now = Date.now();
var timeDeltaMs = now - this._lastUpdate;
this._lastUpdate = now;
var maxChangePerSec = 20;
var maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000);
var scaleChange = target / this._currentScale;
this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta);
} else {
this._currentScale = target;
}
return this._currentScale;
}
}
/**
* @constructor
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = function()
{
}
WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = {
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return 0;
},
/**
* @param {!WebInspector.HeapTrackingOverviewGrid} chart
*/
_updateBoundaries: function(chart)
{
this._minimumBoundaries = 0;
this._maximumBoundaries = chart._profileSamples.totalTime;
this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries;
},
/**
* @override
* @param {number} time
* @return {number}
*/
computePosition: function(time)
{
return (time - this._minimumBoundaries) * this._xScaleFactor;
},
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.secondsToString(value / 1000, !!precision);
},
/**
* @override
* @return {number}
*/
maximumBoundary: function()
{
return this._maximumBoundaries;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._minimumBoundaries;
},
/**
* @override
* @return {number}
*/
zeroTime: function()
{
return this._minimumBoundaries;
},
/**
* @override
* @return {number}
*/
boundarySpan: function()
{
return this._maximumBoundaries - this._minimumBoundaries;
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.HeapSnapshotStatisticsView = function()
{
WebInspector.VBox.call(this);
this.setMinimumSize(50, 25);
this._pieChart = new WebInspector.PieChart(150, WebInspector.HeapSnapshotStatisticsView._valueFormatter, true);
this._pieChart.element.classList.add("heap-snapshot-stats-pie-chart");
this.element.appendChild(this._pieChart.element);
this._labels = this.element.createChild("div", "heap-snapshot-stats-legend");
}
/**
* @param {number} value
* @return {string}
*/
WebInspector.HeapSnapshotStatisticsView._valueFormatter = function(value)
{
return WebInspector.UIString("%s KB", Number.withThousandsSeparator(Math.round(value / 1024)));
}
WebInspector.HeapSnapshotStatisticsView.prototype = {
/**
* @param {number} value
*/
setTotal: function(value)
{
this._pieChart.setTotal(value);
},
/**
* @param {number} value
* @param {string} name
* @param {string=} color
*/
addRecord: function(value, name, color)
{
if (color)
this._pieChart.addSlice(value, color);
var node = this._labels.createChild("div");
var swatchDiv = node.createChild("div", "heap-snapshot-stats-swatch");
var nameDiv = node.createChild("div", "heap-snapshot-stats-name");
var sizeDiv = node.createChild("div", "heap-snapshot-stats-size");
if (color)
swatchDiv.style.backgroundColor = color;
else
swatchDiv.classList.add("heap-snapshot-stats-empty-swatch");
nameDiv.textContent = name;
sizeDiv.textContent = WebInspector.HeapSnapshotStatisticsView._valueFormatter(value);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {?WebInspector.Target} target
*/
WebInspector.HeapAllocationStackView = function(target)
{
WebInspector.Widget.call(this);
this._target = target;;
this._linkifier = new WebInspector.Linkifier();
}
WebInspector.HeapAllocationStackView.prototype = {
/**
* @param {!WebInspector.HeapSnapshotProxy} snapshot
* @param {number} snapshotNodeIndex
*/
setAllocatedObject: function(snapshot, snapshotNodeIndex)
{
this.clear();
snapshot.allocationStack(snapshotNodeIndex, this._didReceiveAllocationStack.bind(this));
},
clear: function()
{
this.element.removeChildren();
this._linkifier.reset();
},
/**
* @param {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} frames
*/
_didReceiveAllocationStack: function(frames)
{
if (!frames) {
var stackDiv = this.element.createChild("div", "no-heap-allocation-stack");
stackDiv.createTextChild(WebInspector.UIString("Stack was not recorded for this object because it had been allocated before this profile recording started."));
return;
}
var stackDiv = this.element.createChild("div", "heap-allocation-stack");
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
var frameDiv = stackDiv.createChild("div", "stack-frame");
var name = frameDiv.createChild("div");
name.textContent = WebInspector.beautifyFunctionName(frame.functionName);
if (frame.scriptId) {
var urlElement = this._linkifier.linkifyScriptLocation(this._target, String(frame.scriptId), frame.scriptName, frame.line - 1, frame.column - 1);
frameDiv.appendChild(urlElement);
}
}
},
__proto__: WebInspector.Widget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.ProfilesPanel} profilesPanel
*/
WebInspector.ProfileLauncherView = function(profilesPanel)
{
WebInspector.VBox.call(this);
this._panel = profilesPanel;
this.element.classList.add("profile-launcher-view");
this.element.classList.add("panel-enabler-view");
this._contentElement = this.element.createChild("div", "profile-launcher-view-content");
this._innerContentElement = this._contentElement.createChild("div");
var targetSpan = this._contentElement.createChild("span");
var selectTargetText = targetSpan.createChild("span");
selectTargetText.textContent = WebInspector.UIString("Target:");
var targetsSelect = targetSpan.createChild("select", "chrome-select");
new WebInspector.TargetsComboBoxController(targetsSelect, targetSpan);
this._controlButton = createTextButton("", this._controlButtonClicked.bind(this), "control-profiling");
this._contentElement.appendChild(this._controlButton);
this._recordButtonEnabled = true;
this._loadButton = createTextButton(WebInspector.UIString("Load"), this._loadButtonClicked.bind(this), "load-profile");
this._contentElement.appendChild(this._loadButton);
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ProfileLauncherView.prototype = {
/**
* @return {?WebInspector.SearchableView}
*/
searchableView: function()
{
return null;
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._updateLoadButtonLayout();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
this._updateLoadButtonLayout();
},
_updateLoadButtonLayout: function()
{
this._loadButton.classList.toggle("multi-target", WebInspector.targetManager.targetsWithJSContext().length > 1);
},
/**
* @param {!WebInspector.ProfileType} profileType
*/
addProfileType: function(profileType)
{
var descriptionElement = this._innerContentElement.createChild("h1");
descriptionElement.textContent = profileType.description;
var decorationElement = profileType.decorationElement();
if (decorationElement)
this._innerContentElement.appendChild(decorationElement);
this._isInstantProfile = profileType.isInstantProfile();
this._isEnabled = profileType.isEnabled();
},
_controlButtonClicked: function()
{
this._panel.toggleRecord();
},
_loadButtonClicked: function()
{
this._panel.showLoadFromFileDialog();
},
_updateControls: function()
{
if (this._isEnabled && this._recordButtonEnabled)
this._controlButton.removeAttribute("disabled");
else
this._controlButton.setAttribute("disabled", "");
this._controlButton.title = this._recordButtonEnabled ? "" : WebInspector.anotherProfilerActiveLabel();
if (this._isInstantProfile) {
this._controlButton.classList.remove("running");
this._controlButton.textContent = WebInspector.UIString("Take Snapshot");
} else if (this._isProfiling) {
this._controlButton.classList.add("running");
this._controlButton.textContent = WebInspector.UIString("Stop");
} else {
this._controlButton.classList.remove("running");
this._controlButton.textContent = WebInspector.UIString("Start");
}
},
profileStarted: function()
{
this._isProfiling = true;
this._updateControls();
},
profileFinished: function()
{
this._isProfiling = false;
this._updateControls();
},
/**
* @param {!WebInspector.ProfileType} profileType
* @param {boolean} recordButtonEnabled
*/
updateProfileType: function(profileType, recordButtonEnabled)
{
this._isInstantProfile = profileType.isInstantProfile();
this._recordButtonEnabled = recordButtonEnabled;
this._isEnabled = profileType.isEnabled();
this._updateControls();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileLauncherView}
* @param {!WebInspector.ProfilesPanel} profilesPanel
*/
WebInspector.MultiProfileLauncherView = function(profilesPanel)
{
WebInspector.ProfileLauncherView.call(this, profilesPanel);
this._selectedProfileTypeSetting = WebInspector.settings.createSetting("selectedProfileType", "CPU");
var header = this._innerContentElement.createChild("h1");
header.textContent = WebInspector.UIString("Select profiling type");
this._profileTypeSelectorForm = this._innerContentElement.createChild("form");
this._innerContentElement.createChild("div", "flexible-space");
this._typeIdToOptionElement = {};
}
WebInspector.MultiProfileLauncherView.EventTypes = {
ProfileTypeSelected: "profile-type-selected"
}
WebInspector.MultiProfileLauncherView.prototype = {
/**
* @override
* @param {!WebInspector.ProfileType} profileType
*/
addProfileType: function(profileType)
{
var labelElement = createRadioLabel("profile-type", profileType.name);
this._profileTypeSelectorForm.appendChild(labelElement);
var optionElement = labelElement.radioElement;
this._typeIdToOptionElement[profileType.id] = optionElement;
optionElement._profileType = profileType;
optionElement.style.hidden = true;
optionElement.addEventListener("change", this._profileTypeChanged.bind(this, profileType), false);
var descriptionElement = labelElement.createChild("p");
descriptionElement.textContent = profileType.description;
var decorationElement = profileType.decorationElement();
if (decorationElement)
labelElement.appendChild(decorationElement);
},
restoreSelectedProfileType: function()
{
var typeId = this._selectedProfileTypeSetting.get();
if (!(typeId in this._typeIdToOptionElement))
typeId = Object.keys(this._typeIdToOptionElement)[0];
this._typeIdToOptionElement[typeId].checked = true;
var type = this._typeIdToOptionElement[typeId]._profileType;
this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, type);
},
_controlButtonClicked: function()
{
this._panel.toggleRecord();
},
_updateControls: function()
{
WebInspector.ProfileLauncherView.prototype._updateControls.call(this);
var items = this._profileTypeSelectorForm.elements;
for (var i = 0; i < items.length; ++i) {
if (items[i].type === "radio")
items[i].disabled = this._isProfiling;
}
},
/**
* @param {!WebInspector.ProfileType} profileType
*/
_profileTypeChanged: function(profileType)
{
this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, profileType);
this._isInstantProfile = profileType.isInstantProfile();
this._isEnabled = profileType.isEnabled();
this._updateControls();
this._selectedProfileTypeSetting.set(profileType.id);
},
profileStarted: function()
{
this._isProfiling = true;
this._updateControls();
},
profileFinished: function()
{
this._isProfiling = false;
this._updateControls();
},
__proto__: WebInspector.ProfileLauncherView.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.ProfileTypeRegistry = function() { this._profileTypes = []; this.cpuProfileType = new WebInspector.CPUProfileType(); this._addProfileType(this.cpuProfileType); this.heapSnapshotProfileType = new WebInspector.HeapSnapshotProfileType(); this._addProfileType(this.heapSnapshotProfileType); this.trackingHeapSnapshotProfileType = new WebInspector.TrackingHeapSnapshotProfileType(); this._addProfileType(this.trackingHeapSnapshotProfileType); } WebInspector.ProfileTypeRegistry.prototype = { /** * @param {!WebInspector.ProfileType} profileType */ _addProfileType: function(profileType) { this._profileTypes.push(profileType); }, /** * @return {!Array.<!WebInspector.ProfileType>} */ profileTypes: function() { return this._profileTypes; } } WebInspector.ProfileTypeRegistry.instance = new WebInspector.ProfileTypeRegistry(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {string} id
* @param {string} name
* @suppressGlobalPropertiesCheck
*/
WebInspector.ProfileType = function(id, name)
{
WebInspector.Object.call(this);
this._id = id;
this._name = name;
/** @type {!Array.<!WebInspector.ProfileHeader>} */
this._profiles = [];
/** @type {?WebInspector.ProfileHeader} */
this._profileBeingRecorded = null;
this._nextProfileUid = 1;
if (!window.opener)
window.addEventListener("unload", this._clearTempStorage.bind(this), false);
}
/**
* @enum {string}
*/
WebInspector.ProfileType.Events = {
AddProfileHeader: "add-profile-header",
ProfileComplete: "profile-complete",
RemoveProfileHeader: "remove-profile-header",
ViewUpdated: "view-updated"
}
WebInspector.ProfileType.prototype = {
/**
* @return {number}
*/
nextProfileUid: function()
{
return this._nextProfileUid;
},
/**
* @return {boolean}
*/
hasTemporaryView: function()
{
return false;
},
/**
* @return {?string}
*/
fileExtension: function()
{
return null;
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [];
},
get buttonTooltip()
{
return "";
},
get id()
{
return this._id;
},
get treeItemTitle()
{
return this._name;
},
get name()
{
return this._name;
},
/**
* @return {boolean}
*/
buttonClicked: function()
{
return false;
},
get description()
{
return "";
},
/**
* @return {boolean}
*/
isInstantProfile: function()
{
return false;
},
/**
* @return {boolean}
*/
isEnabled: function()
{
return true;
},
/**
* @return {!Array.<!WebInspector.ProfileHeader>}
*/
getProfiles: function()
{
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {boolean}
* @this {WebInspector.ProfileType}
*/
function isFinished(profile)
{
return this._profileBeingRecorded !== profile;
}
return this._profiles.filter(isFinished.bind(this));
},
/**
* @return {?Element}
*/
decorationElement: function()
{
return null;
},
/**
* @param {number} uid
* @return {?WebInspector.ProfileHeader}
*/
getProfile: function(uid)
{
for (var i = 0; i < this._profiles.length; ++i) {
if (this._profiles[i].uid === uid)
return this._profiles[i];
}
return null;
},
/**
* @param {!File} file
*/
loadFromFile: function(file)
{
var name = file.name;
var fileExtension = this.fileExtension();
if (fileExtension && name.endsWith(fileExtension))
name = name.substr(0, name.length - fileExtension.length);
var profile = this.createProfileLoadedFromFile(name);
profile.setFromFile();
this.setProfileBeingRecorded(profile);
this.addProfile(profile);
profile.loadFromFile(file);
},
/**
* @param {string} title
* @return {!WebInspector.ProfileHeader}
*/
createProfileLoadedFromFile: function(title)
{
throw new Error("Needs implemented.");
},
/**
* @param {!WebInspector.ProfileHeader} profile
*/
addProfile: function(profile)
{
this._profiles.push(profile);
this.dispatchEventToListeners(WebInspector.ProfileType.Events.AddProfileHeader, profile);
},
/**
* @param {!WebInspector.ProfileHeader} profile
*/
removeProfile: function(profile)
{
var index = this._profiles.indexOf(profile);
if (index === -1)
return;
this._profiles.splice(index, 1);
this._disposeProfile(profile);
},
_clearTempStorage: function()
{
for (var i = 0; i < this._profiles.length; ++i)
this._profiles[i].removeTempFile();
},
/**
* @return {?WebInspector.ProfileHeader}
*/
profileBeingRecorded: function()
{
return this._profileBeingRecorded;
},
/**
* @param {?WebInspector.ProfileHeader} profile
*/
setProfileBeingRecorded: function(profile)
{
this._profileBeingRecorded = profile;
},
profileBeingRecordedRemoved: function()
{
},
_reset: function()
{
var profiles = this._profiles.slice(0);
for (var i = 0; i < profiles.length; ++i)
this._disposeProfile(profiles[i]);
this._profiles = [];
this._nextProfileUid = 1;
},
/**
* @param {!WebInspector.ProfileHeader} profile
*/
_disposeProfile: function(profile)
{
this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProfileHeader, profile);
profile.dispose();
if (this._profileBeingRecorded === profile) {
this.profileBeingRecordedRemoved();
this.setProfileBeingRecorded(null);
}
},
__proto__: WebInspector.Object.prototype
}
/**
* @interface
*/
WebInspector.ProfileType.DataDisplayDelegate = function()
{
}
WebInspector.ProfileType.DataDisplayDelegate.prototype = {
/**
* @param {?WebInspector.ProfileHeader} profile
* @return {?WebInspector.Widget}
*/
showProfile: function(profile) { },
/**
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
* @param {string} perspectiveName
*/
showObject: function(snapshotObjectId, perspectiveName) { }
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {?WebInspector.Target} target
* @param {!WebInspector.ProfileType} profileType
* @param {string} title
*/
WebInspector.ProfileHeader = function(target, profileType, title)
{
this._target = target;
this._profileType = profileType;
this.title = title;
this.uid = profileType._nextProfileUid++;
this._fromFile = false;
}
/**
* @constructor
* @param {?string} subtitle
* @param {boolean|undefined} wait
*/
WebInspector.ProfileHeader.StatusUpdate = function(subtitle, wait)
{
/** @type {?string} */
this.subtitle = subtitle;
/** @type {boolean|undefined} */
this.wait = wait;
}
WebInspector.ProfileHeader.Events = {
UpdateStatus: "UpdateStatus",
ProfileReceived: "ProfileReceived"
}
WebInspector.ProfileHeader.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @return {!WebInspector.ProfileType}
*/
profileType: function()
{
return this._profileType;
},
/**
* @param {?string} subtitle
* @param {boolean=} wait
*/
updateStatus: function(subtitle, wait)
{
this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.UpdateStatus, new WebInspector.ProfileHeader.StatusUpdate(subtitle, wait));
},
/**
* Must be implemented by subclasses.
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!WebInspector.ProfileSidebarTreeElement}
*/
createSidebarTreeElement: function(dataDisplayDelegate)
{
throw new Error("Needs implemented.");
},
/**
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!WebInspector.Widget}
*/
createView: function(dataDisplayDelegate)
{
throw new Error("Not implemented.");
},
removeTempFile: function()
{
if (this._tempFile)
this._tempFile.remove();
},
dispose: function()
{
},
/**
* @return {boolean}
*/
canSaveToFile: function()
{
return false;
},
saveToFile: function()
{
throw new Error("Needs implemented");
},
/**
* @param {!File} file
*/
loadFromFile: function(file)
{
throw new Error("Needs implemented");
},
/**
* @return {boolean}
*/
fromFile: function()
{
return this._fromFile;
},
setFromFile: function()
{
this._fromFile = true;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.ProfileType.DataDisplayDelegate}
* @extends {WebInspector.PanelWithSidebar}
*/
WebInspector.ProfilesPanel = function()
{
WebInspector.PanelWithSidebar.call(this, "profiles");
this.registerRequiredCSS("ui/panelEnablerView.css");
this.registerRequiredCSS("profiler/heapProfiler.css");
this.registerRequiredCSS("profiler/profilesPanel.css");
this.registerRequiredCSS("components/objectValue.css");
var mainContainer = new WebInspector.VBox();
this.splitWidget().setMainWidget(mainContainer);
this.profilesItemTreeElement = new WebInspector.ProfilesSidebarTreeElement(this);
this._sidebarTree = new TreeOutline();
this._sidebarTree.element.classList.add("sidebar-tree");
this.panelSidebarElement().appendChild(this._sidebarTree.element);
this.setDefaultFocusedElement(this._sidebarTree.element);
this._sidebarTree.appendChild(this.profilesItemTreeElement);
this.profileViews = createElement("div");
this.profileViews.id = "profile-views";
this.profileViews.classList.add("vbox");
mainContainer.element.appendChild(this.profileViews);
this._toolbarElement = createElementWithClass("div", "profiles-toolbar");
mainContainer.element.insertBefore(this._toolbarElement, mainContainer.element.firstChild);
this.panelSidebarElement().classList.add("profiles-sidebar-tree-box");
var toolbarContainerLeft = createElementWithClass("div", "profiles-toolbar");
this.panelSidebarElement().insertBefore(toolbarContainerLeft, this.panelSidebarElement().firstChild);
var toolbar = new WebInspector.Toolbar("", toolbarContainerLeft);
this._toggleRecordAction = WebInspector.actionRegistry.action("profiler.toggle-recording");
toolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleRecordAction));
this.clearResultsButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear all profiles"), "clear-toolbar-item");
this.clearResultsButton.addEventListener("click", this._reset, this);
toolbar.appendToolbarItem(this.clearResultsButton);
this._profileTypeToolbar = new WebInspector.Toolbar("", this._toolbarElement);
this._profileViewToolbar = new WebInspector.Toolbar("", this._toolbarElement);
this._profileGroups = {};
this._launcherView = new WebInspector.MultiProfileLauncherView(this);
this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, this._onProfileTypeSelected, this);
this._profileToView = [];
this._typeIdToSidebarSection = {};
var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
for (var i = 0; i < types.length; i++)
this._registerProfileType(types[i]);
this._launcherView.restoreSelectedProfileType();
this.profilesItemTreeElement.select();
this._showLauncherView();
this._createFileSelectorElement();
this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
this.contentElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
}
WebInspector.ProfilesPanel.prototype = {
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
var handled = false;
if (event.keyIdentifier === "Down" && !event.altKey)
handled = this._sidebarTree.selectNext();
else if (event.keyIdentifier === "Up" && !event.altKey)
handled = this._sidebarTree.selectPrevious();
if (handled)
event.consume(true);
},
/**
* @override
* @return {?WebInspector.SearchableView}
*/
searchableView: function()
{
return this.visibleView && this.visibleView.searchableView ? this.visibleView.searchableView() : null;
},
_createFileSelectorElement: function()
{
if (this._fileSelectorElement)
this.element.removeChild(this._fileSelectorElement);
this._fileSelectorElement = WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));
this.element.appendChild(this._fileSelectorElement);
},
_findProfileTypeByExtension: function(fileName)
{
var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
for (var i = 0; i < types.length; i++) {
var type = types[i];
var extension = type.fileExtension();
if (!extension)
continue;
if (fileName.endsWith(type.fileExtension()))
return type;
}
return null;
},
/**
* @param {!File} file
*/
_loadFromFile: function(file)
{
this._createFileSelectorElement();
var profileType = this._findProfileTypeByExtension(file.name);
if (!profileType) {
var extensions = [];
var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
for (var i = 0; i < types.length; i++) {
var extension = types[i].fileExtension();
if (!extension || extensions.indexOf(extension) !== -1)
continue;
extensions.push(extension);
}
WebInspector.console.error(WebInspector.UIString("Can't load file. Only files with extensions '%s' can be loaded.", extensions.join("', '")));
return;
}
if (!!profileType.profileBeingRecorded()) {
WebInspector.console.error(WebInspector.UIString("Can't load profile while another profile is recording."));
return;
}
profileType.loadFromFile(file);
},
/**
* @return {boolean}
*/
toggleRecord: function()
{
if (!this._toggleRecordAction.enabled())
return true;
var type = this._selectedProfileType;
var isProfiling = type.buttonClicked();
this._updateToggleRecordAction(isProfiling);
if (isProfiling) {
this._launcherView.profileStarted();
if (type.hasTemporaryView())
this.showProfile(type.profileBeingRecorded());
} else {
this._launcherView.profileFinished();
}
return true;
},
_onSuspendStateChanged: function()
{
this._updateToggleRecordAction(this._toggleRecordAction.toggled());
},
/**
* @param {boolean} toggled
*/
_updateToggleRecordAction: function(toggled)
{
var enable = toggled || !WebInspector.targetManager.allTargetsSuspended();
this._toggleRecordAction.setEnabled(enable);
this._toggleRecordAction.setToggled(toggled);
if (enable)
this._toggleRecordAction.setTitle(this._selectedProfileType ? this._selectedProfileType.buttonTooltip : "");
else
this._toggleRecordAction.setTitle(WebInspector.anotherProfilerActiveLabel());
if (this._selectedProfileType)
this._launcherView.updateProfileType(this._selectedProfileType, enable);
},
_profileBeingRecordedRemoved: function()
{
this._updateToggleRecordAction(false);
this._launcherView.profileFinished();
},
/**
* @param {!WebInspector.Event} event
*/
_onProfileTypeSelected: function(event)
{
this._selectedProfileType = /** @type {!WebInspector.ProfileType} */ (event.data);
this._updateProfileTypeSpecificUI();
},
_updateProfileTypeSpecificUI: function()
{
this._updateToggleRecordAction(this._toggleRecordAction.toggled());
this._profileTypeToolbar.removeToolbarItems();
var toolbarItems = this._selectedProfileType.toolbarItems();
for (var i = 0; i < toolbarItems.length; ++i)
this._profileTypeToolbar.appendToolbarItem(toolbarItems[i]);
},
_reset: function()
{
WebInspector.Panel.prototype.reset.call(this);
var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
for (var i = 0; i < types.length; i++)
types[i]._reset();
delete this.visibleView;
this._profileGroups = {};
this._updateToggleRecordAction(false);
this._launcherView.profileFinished();
this._sidebarTree.element.classList.remove("some-expandable");
this._launcherView.detach();
this.profileViews.removeChildren();
this._profileViewToolbar.removeToolbarItems();
this.removeAllListeners();
this._profileViewToolbar.element.classList.remove("hidden");
this.clearResultsButton.element.classList.remove("hidden");
this.profilesItemTreeElement.select();
this._showLauncherView();
},
_showLauncherView: function()
{
this.closeVisibleView();
this._profileViewToolbar.removeToolbarItems();
this._launcherView.show(this.profileViews);
this.visibleView = this._launcherView;
},
/**
* @param {!WebInspector.ProfileType} profileType
*/
_registerProfileType: function(profileType)
{
this._launcherView.addProfileType(profileType);
var profileTypeSection = new WebInspector.ProfileTypeSidebarSection(this, profileType);
this._typeIdToSidebarSection[profileType.id] = profileTypeSection;
this._sidebarTree.appendChild(profileTypeSection);
profileTypeSection.childrenListElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ProfilesPanel}
*/
function onAddProfileHeader(event)
{
this._addProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.data));
}
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ProfilesPanel}
*/
function onRemoveProfileHeader(event)
{
this._removeProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.data));
}
/**
* @param {!WebInspector.Event} event
* @this {WebInspector.ProfilesPanel}
*/
function profileComplete(event)
{
this.showProfile(/** @type {!WebInspector.ProfileHeader} */ (event.data));
}
profileType.addEventListener(WebInspector.ProfileType.Events.ViewUpdated, this._updateProfileTypeSpecificUI, this);
profileType.addEventListener(WebInspector.ProfileType.Events.AddProfileHeader, onAddProfileHeader, this);
profileType.addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, onRemoveProfileHeader, this);
profileType.addEventListener(WebInspector.ProfileType.Events.ProfileComplete, profileComplete, this);
var profiles = profileType.getProfiles();
for (var i = 0; i < profiles.length; i++)
this._addProfileHeader(profiles[i]);
},
/**
* @param {!Event} event
*/
_handleContextMenuEvent: function(event)
{
var element = event.srcElement;
while (element && !element.treeElement && element !== this.element)
element = element.parentElement;
if (!element)
return;
if (element.treeElement && element.treeElement.handleContextMenuEvent) {
element.treeElement.handleContextMenuEvent(event, this);
return;
}
var contextMenu = new WebInspector.ContextMenu(event);
if (this.visibleView instanceof WebInspector.HeapSnapshotView) {
this.visibleView.populateContextMenu(contextMenu, event);
}
if (element !== this.element || event.srcElement === this.panelSidebarElement()) {
contextMenu.appendItem(WebInspector.UIString("Load\u2026"), this._fileSelectorElement.click.bind(this._fileSelectorElement));
}
contextMenu.show();
},
showLoadFromFileDialog: function()
{
this._fileSelectorElement.click();
},
/**
* @param {!WebInspector.ProfileHeader} profile
*/
_addProfileHeader: function(profile)
{
var profileType = profile.profileType();
var typeId = profileType.id;
this._typeIdToSidebarSection[typeId].addProfileHeader(profile);
if (!this.visibleView || this.visibleView === this._launcherView)
this.showProfile(profile);
},
/**
* @param {!WebInspector.ProfileHeader} profile
*/
_removeProfileHeader: function(profile)
{
if (profile.profileType()._profileBeingRecorded === profile)
this._profileBeingRecordedRemoved();
var i = this._indexOfViewForProfile(profile);
if (i !== -1)
this._profileToView.splice(i, 1);
var profileType = profile.profileType();
var typeId = profileType.id;
var sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);
// No other item will be selected if there aren't any other profiles, so
// make sure that view gets cleared when the last profile is removed.
if (sectionIsEmpty) {
this.profilesItemTreeElement.select();
this._showLauncherView();
}
},
/**
* @override
* @param {?WebInspector.ProfileHeader} profile
* @return {?WebInspector.Widget}
*/
showProfile: function(profile)
{
if (!profile || (profile.profileType().profileBeingRecorded() === profile) && !profile.profileType().hasTemporaryView())
return null;
var view = this._viewForProfile(profile);
if (view === this.visibleView)
return view;
this.closeVisibleView();
view.show(this.profileViews);
view.focus();
this.visibleView = view;
var profileTypeSection = this._typeIdToSidebarSection[profile.profileType().id];
var sidebarElement = profileTypeSection.sidebarElementForProfile(profile);
sidebarElement.revealAndSelect();
this._profileViewToolbar.removeToolbarItems();
var toolbarItems = view.toolbarItems();
for (var i = 0; i < toolbarItems.length; ++i)
this._profileViewToolbar.appendToolbarItem(toolbarItems[i]);
return view;
},
/**
* @override
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
* @param {string} perspectiveName
*/
showObject: function(snapshotObjectId, perspectiveName)
{
var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
for (var i = 0; i < heapProfiles.length; i++) {
var profile = heapProfiles[i];
// FIXME: allow to choose snapshot if there are several options.
if (profile.maxJSObjectId >= snapshotObjectId) {
this.showProfile(profile);
var view = this._viewForProfile(profile);
view.selectLiveObject(perspectiveName, snapshotObjectId);
break;
}
}
},
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {!WebInspector.Widget}
*/
_viewForProfile: function(profile)
{
var index = this._indexOfViewForProfile(profile);
if (index !== -1)
return this._profileToView[index].view;
var view = profile.createView(this);
view.element.classList.add("profile-view");
this._profileToView.push({ profile: profile, view: view});
return view;
},
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {number}
*/
_indexOfViewForProfile: function(profile)
{
for (var i = 0; i < this._profileToView.length; i++) {
if (this._profileToView[i].profile === profile)
return i;
}
return -1;
},
closeVisibleView: function()
{
if (this.visibleView)
this.visibleView.detach();
delete this.visibleView;
},
/**
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
if (!(target instanceof WebInspector.RemoteObject))
return;
if (WebInspector.inspectorView.currentPanel() !== this)
return;
var object = /** @type {!WebInspector.RemoteObject} */ (target);
var objectId = object.objectId;
if (!objectId)
return;
var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
if (!heapProfiles.length)
return;
/**
* @this {WebInspector.ProfilesPanel}
*/
function revealInView(viewName)
{
object.target().heapProfilerAgent().getHeapObjectId(objectId, didReceiveHeapObjectId.bind(this, viewName));
}
/**
* @this {WebInspector.ProfilesPanel}
*/
function didReceiveHeapObjectId(viewName, error, result)
{
if (WebInspector.inspectorView.currentPanel() !== this)
return;
if (!error)
this.showObject(result, viewName);
}
contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Summary ^view"), revealInView.bind(this, "Summary"));
},
wasShown: function()
{
WebInspector.context.setFlavor(WebInspector.ProfilesPanel, this);
},
willHide: function()
{
WebInspector.context.setFlavor(WebInspector.ProfilesPanel, null);
},
__proto__: WebInspector.PanelWithSidebar.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarSectionTreeElement}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!WebInspector.ProfileType} profileType
*/
WebInspector.ProfileTypeSidebarSection = function(dataDisplayDelegate, profileType)
{
WebInspector.SidebarSectionTreeElement.call(this, profileType.treeItemTitle);
this._dataDisplayDelegate = dataDisplayDelegate;
this._profileTreeElements = [];
this._profileGroups = {};
this.hidden = true;
}
/**
* @constructor
*/
WebInspector.ProfileTypeSidebarSection.ProfileGroup = function()
{
this.profileSidebarTreeElements = [];
this.sidebarTreeElement = null;
}
WebInspector.ProfileTypeSidebarSection.prototype = {
/**
* @param {!WebInspector.ProfileHeader} profile
*/
addProfileHeader: function(profile)
{
this.hidden = false;
var profileType = profile.profileType();
var sidebarParent = this;
var profileTreeElement = profile.createSidebarTreeElement(this._dataDisplayDelegate);
this._profileTreeElements.push(profileTreeElement);
if (!profile.fromFile() && profileType.profileBeingRecorded() !== profile) {
var profileTitle = profile.title;
var group = this._profileGroups[profileTitle];
if (!group) {
group = new WebInspector.ProfileTypeSidebarSection.ProfileGroup();
this._profileGroups[profileTitle] = group;
}
group.profileSidebarTreeElements.push(profileTreeElement);
var groupSize = group.profileSidebarTreeElements.length;
if (groupSize === 2) {
// Make a group TreeElement now that there are 2 profiles.
group.sidebarTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(this._dataDisplayDelegate, profile.title);
var firstProfileTreeElement = group.profileSidebarTreeElements[0];
// Insert at the same index for the first profile of the group.
var index = this.children().indexOf(firstProfileTreeElement);
this.insertChild(group.sidebarTreeElement, index);
// Move the first profile to the group.
var selected = firstProfileTreeElement.selected;
this.removeChild(firstProfileTreeElement);
group.sidebarTreeElement.appendChild(firstProfileTreeElement);
if (selected)
firstProfileTreeElement.revealAndSelect();
firstProfileTreeElement.small = true;
firstProfileTreeElement.mainTitle = WebInspector.UIString("Run %d", 1);
this.treeOutline.element.classList.add("some-expandable");
}
if (groupSize >= 2) {
sidebarParent = group.sidebarTreeElement;
profileTreeElement.small = true;
profileTreeElement.mainTitle = WebInspector.UIString("Run %d", groupSize);
}
}
sidebarParent.appendChild(profileTreeElement);
},
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {boolean}
*/
removeProfileHeader: function(profile)
{
var index = this._sidebarElementIndex(profile);
if (index === -1)
return false;
var profileTreeElement = this._profileTreeElements[index];
this._profileTreeElements.splice(index, 1);
var sidebarParent = this;
var group = this._profileGroups[profile.title];
if (group) {
var groupElements = group.profileSidebarTreeElements;
groupElements.splice(groupElements.indexOf(profileTreeElement), 1);
if (groupElements.length === 1) {
// Move the last profile out of its group and remove the group.
var pos = sidebarParent.children().indexOf(group.sidebarTreeElement);
group.sidebarTreeElement.removeChild(groupElements[0]);
this.insertChild(groupElements[0], pos);
groupElements[0].small = false;
groupElements[0].mainTitle = group.sidebarTreeElement.title;
this.removeChild(group.sidebarTreeElement);
}
if (groupElements.length !== 0)
sidebarParent = group.sidebarTreeElement;
}
sidebarParent.removeChild(profileTreeElement);
profileTreeElement.dispose();
if (this.childCount())
return false;
this.hidden = true;
return true;
},
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {?WebInspector.ProfileSidebarTreeElement}
*/
sidebarElementForProfile: function(profile)
{
var index = this._sidebarElementIndex(profile);
return index === -1 ? null : this._profileTreeElements[index];
},
/**
* @param {!WebInspector.ProfileHeader} profile
* @return {number}
*/
_sidebarElementIndex: function(profile)
{
var elements = this._profileTreeElements;
for (var i = 0; i < elements.length; i++) {
if (elements[i].profile === profile)
return i;
}
return -1;
},
__proto__: WebInspector.SidebarSectionTreeElement.prototype
}
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.ProfilesPanel.ContextMenuProvider = function()
{
}
WebInspector.ProfilesPanel.ContextMenuProvider.prototype = {
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
WebInspector.ProfilesPanel._instance().appendApplicableItems(event, contextMenu, target);
}
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!WebInspector.ProfileHeader} profile
* @param {string} className
*/
WebInspector.ProfileSidebarTreeElement = function(dataDisplayDelegate, profile, className)
{
this._dataDisplayDelegate = dataDisplayDelegate;
this.profile = profile;
WebInspector.SidebarTreeElement.call(this, className, profile.title);
this.refreshTitles();
profile.addEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
if (profile.canSaveToFile())
this._createSaveLink();
else
profile.addEventListener(WebInspector.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
}
WebInspector.ProfileSidebarTreeElement.prototype = {
_createSaveLink: function()
{
this._saveLinkElement = this.titleContainer.createChild("span", "save-link");
this._saveLinkElement.textContent = WebInspector.UIString("Save");
this._saveLinkElement.addEventListener("click", this._saveProfile.bind(this), false);
},
_onProfileReceived: function(event)
{
this._createSaveLink();
},
/**
* @param {!WebInspector.Event} event
*/
_updateStatus: function(event)
{
var statusUpdate = event.data;
if (statusUpdate.subtitle !== null)
this.subtitle = statusUpdate.subtitle;
if (typeof statusUpdate.wait === "boolean")
this.wait = statusUpdate.wait;
this.refreshTitles();
},
dispose: function()
{
this.profile.removeEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
this.profile.removeEventListener(WebInspector.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
},
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._dataDisplayDelegate.showProfile(this.profile);
return true;
},
/**
* @override
* @return {boolean}
*/
ondelete: function()
{
this.profile.profileType().removeProfile(this.profile);
return true;
},
/**
* @param {!Event} event
* @param {!WebInspector.ProfilesPanel} panel
*/
handleContextMenuEvent: function(event, panel)
{
var profile = this.profile;
var contextMenu = new WebInspector.ContextMenu(event);
// FIXME: use context menu provider
contextMenu.appendItem(WebInspector.UIString("Load\u2026"), panel._fileSelectorElement.click.bind(panel._fileSelectorElement));
if (profile.canSaveToFile())
contextMenu.appendItem(WebInspector.UIString("Save\u2026"), profile.saveToFile.bind(profile));
contextMenu.appendItem(WebInspector.UIString("Delete"), this.ondelete.bind(this));
contextMenu.show();
},
_saveProfile: function(event)
{
this.profile.saveToFile();
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {string} title
* @param {string=} subtitle
*/
WebInspector.ProfileGroupSidebarTreeElement = function(dataDisplayDelegate, title, subtitle)
{
WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item", title, subtitle, true);
this._dataDisplayDelegate = dataDisplayDelegate;
}
WebInspector.ProfileGroupSidebarTreeElement.prototype = {
/**
* @override
* @return {boolean}
*/
onselect: function()
{
var hasChildren = this.childCount() > 0;
if (hasChildren)
this._dataDisplayDelegate.showProfile(this.lastChild().profile);
return hasChildren;
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {!WebInspector.ProfilesPanel} panel
*/
WebInspector.ProfilesSidebarTreeElement = function(panel)
{
this._panel = panel;
this.small = false;
WebInspector.SidebarTreeElement.call(this, "profile-launcher-view-tree-item", WebInspector.UIString("Profiles"));
}
WebInspector.ProfilesSidebarTreeElement.prototype = {
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._panel._showLauncherView();
return true;
},
get selectable()
{
return true;
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
WebInspector.ProfilesPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.ProfilesPanel._instance());
}
/**
* @return {!WebInspector.ProfilesPanel}
*/
WebInspector.ProfilesPanel._instance = function()
{
if (!WebInspector.ProfilesPanel._instanceObject)
WebInspector.ProfilesPanel._instanceObject = new WebInspector.ProfilesPanel();
return WebInspector.ProfilesPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.ProfilesPanelFactory = function()
{
}
WebInspector.ProfilesPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.ProfilesPanel._instance();
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.ProfilesPanel.RecordActionDelegate = function()
{
}
WebInspector.ProfilesPanel.RecordActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var panel = WebInspector.context.flavor(WebInspector.ProfilesPanel);
console.assert(panel && panel instanceof WebInspector.ProfilesPanel);
panel.toggleRecord();
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TargetManager.Observer}
* @param {!Element} selectElement
* @param {!Element} elementToHide
*/
WebInspector.TargetsComboBoxController = function(selectElement, elementToHide)
{
elementToHide.classList.add("hidden");
selectElement.addEventListener("change", this._onComboBoxSelectionChange.bind(this), false);
this._selectElement = selectElement;
this._elementToHide = elementToHide;
/** @type {!Map.<!WebInspector.Target, !Element>} */
this._targetToOption = new Map();
WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChangedExternally, this);
WebInspector.targetManager.observeTargets(this);
}
WebInspector.TargetsComboBoxController.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (!target.hasJSContext())
return;
var option = this._selectElement.createChild("option");
option.text = target.name();
option.__target = target;
this._targetToOption.set(target, option);
if (WebInspector.context.flavor(WebInspector.Target) === target)
this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
this._updateVisibility();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (!target.hasJSContext())
return;
var option = this._targetToOption.remove(target);
this._selectElement.removeChild(option);
this._updateVisibility();
},
_onComboBoxSelectionChange: function()
{
var selectedOption = this._selectElement[this._selectElement.selectedIndex];
if (!selectedOption)
return;
WebInspector.context.setFlavor(WebInspector.Target, selectedOption.__target);
},
_updateVisibility: function()
{
var hidden = this._selectElement.childElementCount === 1;
this._elementToHide.classList.toggle("hidden", hidden);
},
/**
* @param {!WebInspector.Event} event
*/
_targetChangedExternally: function(event)
{
var target = /** @type {?WebInspector.Target} */ (event.data);
if (target) {
var option = /** @type {!Element} */ (this._targetToOption.get(target));
this._select(option);
}
},
/**
* @param {!Element} option
*/
_select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ApplicationCacheItemsView.js | 2.68% | (3 / 112) | 0% | (0 / 40) | 0% | (0 / 16) | 2.75% | (3 / 109) | |
| CookieItemsView.js | 2.9% | (2 / 69) | 0% | (0 / 20) | 0% | (0 / 14) | 2.9% | (2 / 69) | |
| DOMStorageItemsView.js | 0.87% | (1 / 115) | 0% | (0 / 52) | 0% | (0 / 16) | 0.87% | (1 / 115) | |
| DOMStorageModel.js | 1.11% | (1 / 90) | 0% | (0 / 12) | 0% | (0 / 26) | 1.11% | (1 / 90) | |
| DatabaseModel.js | 5.08% | (3 / 59) | 0% | (0 / 14) | 0% | (0 / 19) | 5.08% | (3 / 59) | |
| DatabaseQueryView.js | 4.82% | (4 / 83) | 0% | (0 / 26) | 0% | (0 / 16) | 4.88% | (4 / 82) | |
| DatabaseTableView.js | 1.61% | (1 / 62) | 0% | (0 / 12) | 0% | (0 / 9) | 1.61% | (1 / 62) | |
| IndexedDBModel.js | 2.27% | (4 / 176) | 0% | (0 / 47) | 0% | (0 / 34) | 2.27% | (4 / 176) | |
| IndexedDBViews.js | 1.85% | (3 / 162) | 0% | (0 / 30) | 0% | (0 / 24) | 1.85% | (3 / 162) | |
| ResourcesPanel.js | 0.8% | (7 / 876) | 0% | (0 / 286) | 0% | (0 / 182) | 0.8% | (7 / 876) | |
| ServiceWorkerCacheViews.js | 1.47% | (1 / 68) | 0% | (0 / 9) | 0% | (0 / 12) | 1.47% | (1 / 68) | |
| ServiceWorkersView.js | 0.34% | (1 / 293) | 0% | (0 / 107) | 0% | (0 / 30) | 0.34% | (1 / 292) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | 2 1 1 | /*
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.ApplicationCacheItemsView = function(model, frameId)
{
WebInspector.VBox.call(this);
this._model = model;
this.element.classList.add("storage-view", "table");
this._deleteButton = new WebInspector.ToolbarButton(WebInspector.UIString("Delete"), "delete-toolbar-item");
this._deleteButton.setVisible(false);
this._deleteButton.addEventListener("click", this._deleteButtonClicked, this);
this._connectivityIcon = createElement("label", "dt-icon-label");
this._connectivityIcon.style.margin = "0 2px 0 5px";
this._statusIcon = createElement("label", "dt-icon-label");
this._statusIcon.style.margin = "0 2px 0 5px";
this._frameId = frameId;
this._emptyWidget = new WebInspector.EmptyWidget(WebInspector.UIString("No Application Cache information available."));
this._emptyWidget.show(this.element);
this._markDirty();
var status = this._model.frameManifestStatus(frameId);
this.updateStatus(status);
this.updateNetworkState(this._model.onLine);
// FIXME: Status bar items don't work well enough yet, so they are being hidden.
// http://webkit.org/b/41637 Web Inspector: Give Semantics to "Refresh" and "Delete" Buttons in ApplicationCache DataGrid
this._deleteButton.element.style.display = "none";
}
WebInspector.ApplicationCacheItemsView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [
this._deleteButton,
new WebInspector.ToolbarItem(this._connectivityIcon),
new WebInspector.ToolbarSeparator(),
new WebInspector.ToolbarItem(this._statusIcon)
];
},
wasShown: function()
{
this._maybeUpdate();
},
willHide: function()
{
this._deleteButton.setVisible(false);
},
_maybeUpdate: function()
{
if (!this.isShowing() || !this._viewDirty)
return;
this._update();
this._viewDirty = false;
},
_markDirty: function()
{
this._viewDirty = true;
},
/**
* @param {number} status
*/
updateStatus: function(status)
{
var oldStatus = this._status;
this._status = status;
var statusInformation = {};
// We should never have UNCACHED status, since we remove frames with UNCACHED application cache status from the tree.
statusInformation[applicationCache.UNCACHED] = { type: "red-ball", text: "UNCACHED" };
statusInformation[applicationCache.IDLE] = { type: "green-ball", text: "IDLE" };
statusInformation[applicationCache.CHECKING] = { type: "orange-ball", text: "CHECKING" };
statusInformation[applicationCache.DOWNLOADING] = { type: "orange-ball", text: "DOWNLOADING" };
statusInformation[applicationCache.UPDATEREADY] = { type: "green-ball", text: "UPDATEREADY" };
statusInformation[applicationCache.OBSOLETE] = { type: "red-ball", text: "OBSOLETE" };
var info = statusInformation[status] || statusInformation[applicationCache.UNCACHED];
this._statusIcon.type = info.type;
this._statusIcon.textContent = info.text;
if (this.isShowing() && this._status === applicationCache.IDLE && (oldStatus === applicationCache.UPDATEREADY || !this._resources))
this._markDirty();
this._maybeUpdate();
},
/**
* @param {boolean} isNowOnline
*/
updateNetworkState: function(isNowOnline)
{
if (isNowOnline) {
this._connectivityIcon.type = "green-ball";
this._connectivityIcon.textContent = WebInspector.UIString("Online");
} else {
this._connectivityIcon.type = "red-ball";
this._connectivityIcon.textContent = WebInspector.UIString("Offline");
}
},
_update: function()
{
this._model.requestApplicationCache(this._frameId, this._updateCallback.bind(this));
},
/**
* @param {?ApplicationCacheAgent.ApplicationCache} applicationCache
*/
_updateCallback: function(applicationCache)
{
if (!applicationCache || !applicationCache.manifestURL) {
delete this._manifest;
delete this._creationTime;
delete this._updateTime;
delete this._size;
delete this._resources;
this._emptyWidget.show(this.element);
this._deleteButton.setVisible(false);
if (this._dataGrid)
this._dataGrid.element.classList.add("hidden");
return;
}
// FIXME: are these variables needed anywhere else?
this._manifest = applicationCache.manifestURL;
this._creationTime = applicationCache.creationTime;
this._updateTime = applicationCache.updateTime;
this._size = applicationCache.size;
this._resources = applicationCache.resources;
if (!this._dataGrid)
this._createDataGrid();
this._populateDataGrid();
this._dataGrid.autoSizeColumns(20, 80);
this._dataGrid.element.classList.remove("hidden");
this._emptyWidget.detach();
this._deleteButton.setVisible(true);
// FIXME: For Chrome, put creationTime and updateTime somewhere.
// NOTE: localizedString has not yet been added.
// WebInspector.UIString("(%s) Created: %s Updated: %s", this._size, this._creationTime, this._updateTime);
},
_createDataGrid: function()
{
var columns = [
{title: WebInspector.UIString("Resource"), sort: WebInspector.DataGrid.Order.Ascending, sortable: true},
{title: WebInspector.UIString("Type"), sortable: true},
{title: WebInspector.UIString("Size"), align: WebInspector.DataGrid.Align.Right, sortable: true}
];
this._dataGrid = new WebInspector.DataGrid(columns);
this._dataGrid.asWidget().show(this.element);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._populateDataGrid, this);
},
_populateDataGrid: function()
{
var selectedResource = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.resource : null;
var sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
function numberCompare(field, resource1, resource2)
{
return sortDirection * (resource1[field] - resource2[field]);
}
function localeCompare(field, resource1, resource2)
{
return sortDirection * (resource1[field] + "").localeCompare(resource2[field] + "");
}
var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier(), 10)) {
case 0: comparator = localeCompare.bind(null, "name"); break;
case 1: comparator = localeCompare.bind(null, "type"); break;
case 2: comparator = numberCompare.bind(null, "size"); break;
default: localeCompare.bind(null, "resource"); // FIXME: comparator = ?
}
this._resources.sort(comparator);
this._dataGrid.rootNode().removeChildren();
var nodeToSelect;
for (var i = 0; i < this._resources.length; ++i) {
var data = {};
var resource = this._resources[i];
data[0] = resource.url;
data[1] = resource.type;
data[2] = Number.bytesToString(resource.size);
var node = new WebInspector.DataGridNode(data);
node.resource = resource;
node.selectable = true;
this._dataGrid.rootNode().appendChild(node);
if (resource === selectedResource) {
nodeToSelect = node;
nodeToSelect.selected = true;
}
}
if (!nodeToSelect && this._dataGrid.rootNode().children.length)
this._dataGrid.rootNode().children[0].selected = true;
},
_deleteButtonClicked: function(event)
{
if (!this._dataGrid || !this._dataGrid.selectedNode)
return;
// FIXME: Delete Button semantics are not yet defined. (Delete a single, or all?)
this._deleteCallback(this._dataGrid.selectedNode);
},
_deleteCallback: function(node)
{
// FIXME: Should we delete a single (selected) resource or all resources?
// InspectorBackend.deleteCachedResource(...)
// this._update();
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | 2 1 | /*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
WebInspector.VBox.call(this);
this.element.classList.add("storage-view");
this._deleteButton = new WebInspector.ToolbarButton(WebInspector.UIString("Delete"), "delete-toolbar-item");
this._deleteButton.setVisible(false);
this._deleteButton.addEventListener("click", this._deleteButtonClicked, this);
this._clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear"), "clear-toolbar-item");
this._clearButton.setVisible(false);
this._clearButton.addEventListener("click", this._clearButtonClicked, this);
this._refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this._treeElement = treeElement;
this._cookieDomain = cookieDomain;
this._emptyWidget = new WebInspector.EmptyWidget(cookieDomain ? WebInspector.UIString("This site has no cookies.") : WebInspector.UIString("By default cookies are disabled for local files.\nYou could override this by starting the browser with --enable-file-cookies command line flag."));
this._emptyWidget.show(this.element);
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
}
WebInspector.CookieItemsView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._refreshButton, this._clearButton, this._deleteButton];
},
wasShown: function()
{
this._update();
},
willHide: function()
{
this._deleteButton.setVisible(false);
},
_update: function()
{
WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
},
/**
* @param {!Array.<!WebInspector.Cookie>} allCookies
*/
_updateWithCookies: function(allCookies)
{
this._cookies = this._filterCookiesForDomain(allCookies);
if (!this._cookies.length) {
// Nothing to show.
this._emptyWidget.show(this.element);
this._clearButton.setVisible(false);
this._deleteButton.setVisible(false);
if (this._cookiesTable)
this._cookiesTable.detach();
return;
}
if (!this._cookiesTable)
this._cookiesTable = new WebInspector.CookiesTable(false, this._update.bind(this), this._showDeleteButton.bind(this));
this._cookiesTable.setCookies(this._cookies);
this._emptyWidget.detach();
this._cookiesTable.show(this.element);
this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
Number.bytesToString(this._totalSize));
this._clearButton.setVisible(true);
this._deleteButton.setVisible(!!this._cookiesTable.selectedCookie());
},
/**
* @param {!Array.<!WebInspector.Cookie>} allCookies
*/
_filterCookiesForDomain: function(allCookies)
{
var cookies = [];
var resourceURLsForDocumentURL = [];
this._totalSize = 0;
/**
* @this {WebInspector.CookieItemsView}
*/
function populateResourcesForDocuments(resource)
{
var url = resource.documentURL.asParsedURL();
if (url && url.host == this._cookieDomain)
resourceURLsForDocumentURL.push(resource.url);
}
WebInspector.forAllResources(populateResourcesForDocuments.bind(this));
for (var i = 0; i < allCookies.length; ++i) {
var pushed = false;
var size = allCookies[i].size();
for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
var resourceURL = resourceURLsForDocumentURL[j];
if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
this._totalSize += size;
if (!pushed) {
pushed = true;
cookies.push(allCookies[i]);
}
}
}
}
return cookies;
},
clear: function()
{
this._cookiesTable.clear();
this._update();
},
_clearButtonClicked: function()
{
this.clear();
},
_showDeleteButton: function()
{
this._deleteButton.setVisible(true);
},
_deleteButtonClicked: function()
{
var selectedCookie = this._cookiesTable.selectedCookie();
if (selectedCookie) {
selectedCookie.remove();
this._update();
}
},
_refreshButtonClicked: function(event)
{
this._update();
},
_contextMenu: function(event)
{
if (!this._cookies.length) {
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this));
contextMenu.show();
}
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | 2 | /*
* Copyright (C) 2008 Nokia Inc. All rights reserved.
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DOMStorageItemsView = function(domStorage)
{
WebInspector.VBox.call(this);
this.domStorage = domStorage;
this.element.classList.add("storage-view", "table");
this.deleteButton = new WebInspector.ToolbarButton(WebInspector.UIString("Delete"), "delete-toolbar-item");
this.deleteButton.setVisible(false);
this.deleteButton.addEventListener("click", this._deleteButtonClicked, this);
this.refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this.refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this);
this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemRemoved, this._domStorageItemRemoved, this);
this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemAdded, this._domStorageItemAdded, this);
this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemUpdated, this._domStorageItemUpdated, this);
}
WebInspector.DOMStorageItemsView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this.refreshButton, this.deleteButton];
},
wasShown: function()
{
this._update();
},
willHide: function()
{
this.deleteButton.setVisible(false);
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageItemsCleared: function(event)
{
if (!this.isShowing() || !this._dataGrid)
return;
this._dataGrid.rootNode().removeChildren();
this._dataGrid.addCreationNode(false);
this.deleteButton.setVisible(false);
event.consume(true);
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageItemRemoved: function(event)
{
if (!this.isShowing() || !this._dataGrid)
return;
var storageData = event.data;
var rootNode = this._dataGrid.rootNode();
var children = rootNode.children;
event.consume(true);
for (var i = 0; i < children.length; ++i) {
var childNode = children[i];
if (childNode.data.key === storageData.key) {
rootNode.removeChild(childNode);
this.deleteButton.setVisible(children.length > 1);
return;
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageItemAdded: function(event)
{
if (!this.isShowing() || !this._dataGrid)
return;
var storageData = event.data;
var rootNode = this._dataGrid.rootNode();
var children = rootNode.children;
event.consume(true);
this.deleteButton.setVisible(true);
for (var i = 0; i < children.length; ++i)
if (children[i].data.key === storageData.key)
return;
var childNode = new WebInspector.DataGridNode({key: storageData.key, value: storageData.value}, false);
rootNode.insertChild(childNode, children.length - 1);
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageItemUpdated: function(event)
{
if (!this.isShowing() || !this._dataGrid)
return;
var storageData = event.data;
var rootNode = this._dataGrid.rootNode();
var children = rootNode.children;
event.consume(true);
var keyFound = false;
for (var i = 0; i < children.length; ++i) {
var childNode = children[i];
if (childNode.data.key === storageData.key) {
if (keyFound) {
rootNode.removeChild(childNode);
return;
}
keyFound = true;
if (childNode.data.value !== storageData.value) {
childNode.data.value = storageData.value;
childNode.refresh();
childNode.select();
childNode.reveal();
}
this.deleteButton.setVisible(true);
}
}
},
_update: function()
{
this.detachChildWidgets();
this.domStorage.getItems(this._showDOMStorageItems.bind(this));
},
_showDOMStorageItems: function(error, items)
{
if (error)
return;
this._dataGrid = this._dataGridForDOMStorageItems(items);
this._dataGrid.asWidget().show(this.element);
this.deleteButton.setVisible(this._dataGrid.rootNode().children.length > 1);
},
_dataGridForDOMStorageItems: function(items)
{
var columns = [
{id: "key", title: WebInspector.UIString("Key"), editable: true, weight: 50},
{id: "value", title: WebInspector.UIString("Value"), editable: true, weight: 50}
];
var nodes = [];
var keys = [];
var length = items.length;
for (var i = 0; i < items.length; i++) {
var key = items[i][0];
var value = items[i][1];
var node = new WebInspector.DataGridNode({key: key, value: value}, false);
node.selectable = true;
nodes.push(node);
keys.push(key);
}
var dataGrid = new WebInspector.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this));
dataGrid.setName("DOMStorageItemsView");
length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.rootNode().appendChild(nodes[i]);
dataGrid.addCreationNode(false);
if (length > 0)
nodes[0].selected = true;
return dataGrid;
},
_deleteButtonClicked: function(event)
{
if (!this._dataGrid || !this._dataGrid.selectedNode)
return;
this._deleteCallback(this._dataGrid.selectedNode);
},
_refreshButtonClicked: function(event)
{
this._update();
},
_editingCallback: function(editingNode, columnIdentifier, oldText, newText)
{
var domStorage = this.domStorage;
if ("key" === columnIdentifier) {
if (typeof oldText === "string")
domStorage.removeItem(oldText);
domStorage.setItem(newText, editingNode.data.value || '');
this._removeDupes(editingNode);
} else
domStorage.setItem(editingNode.data.key || '', newText);
},
/**
* @param {!WebInspector.DataGridNode} masterNode
*/
_removeDupes: function(masterNode)
{
var rootNode = this._dataGrid.rootNode();
var children = rootNode.children;
for (var i = children.length - 1; i >= 0; --i) {
var childNode = children[i];
if ((childNode.data.key === masterNode.data.key) && (masterNode !== childNode))
rootNode.removeChild(childNode);
}
},
_deleteCallback: function(node)
{
if (!node || node.isCreationNode)
return;
if (this.domStorage)
this.domStorage.removeItem(node.data.key);
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | 2 | /*
* Copyright (C) 2008 Nokia Inc. All rights reserved.
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.DOMStorageModel} model
* @param {string} securityOrigin
* @param {boolean} isLocalStorage
*/
WebInspector.DOMStorage = function(model, securityOrigin, isLocalStorage)
{
this._model = model;
this._securityOrigin = securityOrigin;
this._isLocalStorage = isLocalStorage;
}
/**
* @param {string} securityOrigin
* @param {boolean} isLocalStorage
* @return {!DOMStorageAgent.StorageId}
*/
WebInspector.DOMStorage.storageId = function(securityOrigin, isLocalStorage)
{
return { securityOrigin: securityOrigin, isLocalStorage: isLocalStorage };
}
WebInspector.DOMStorage.Events = {
DOMStorageItemsCleared: "DOMStorageItemsCleared",
DOMStorageItemRemoved: "DOMStorageItemRemoved",
DOMStorageItemAdded: "DOMStorageItemAdded",
DOMStorageItemUpdated: "DOMStorageItemUpdated"
}
WebInspector.DOMStorage.prototype = {
/** @return {!DOMStorageAgent.StorageId} */
get id()
{
return WebInspector.DOMStorage.storageId(this._securityOrigin, this._isLocalStorage);
},
/** @return {string} */
get securityOrigin()
{
return this._securityOrigin;
},
/** @return {boolean} */
get isLocalStorage()
{
return this._isLocalStorage;
},
/**
* @param {function(?Protocol.Error, !Array.<!DOMStorageAgent.Item>):void=} callback
*/
getItems: function(callback)
{
this._model._agent.getDOMStorageItems(this.id, callback);
},
/**
* @param {string} key
* @param {string} value
*/
setItem: function(key, value)
{
this._model._agent.setDOMStorageItem(this.id, key, value);
},
/**
* @param {string} key
*/
removeItem: function(key)
{
this._model._agent.removeDOMStorageItem(this.id, key);
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.DOMStorageModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.DOMStorageModel, target);
/** @type {!Object.<string, !WebInspector.DOMStorage>} */
this._storages = {};
this._agent = target.domstorageAgent();
}
WebInspector.DOMStorageModel.Events = {
DOMStorageAdded: "DOMStorageAdded",
DOMStorageRemoved: "DOMStorageRemoved"
}
WebInspector.DOMStorageModel.prototype = {
enable: function()
{
if (this._enabled)
return;
this.target().registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
this._agent.enable();
var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
this._enabled = true;
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginAdded: function(event)
{
this._addOrigin(/** @type {string} */ (event.data));
},
/**
* @param {string} securityOrigin
*/
_addOrigin: function(securityOrigin)
{
var localStorageKey = this._storageKey(securityOrigin, true);
console.assert(!this._storages[localStorageKey]);
var localStorage = new WebInspector.DOMStorage(this, securityOrigin, true);
this._storages[localStorageKey] = localStorage;
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, localStorage);
var sessionStorageKey = this._storageKey(securityOrigin, false);
console.assert(!this._storages[sessionStorageKey]);
var sessionStorage = new WebInspector.DOMStorage(this, securityOrigin, false);
this._storages[sessionStorageKey] = sessionStorage;
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, sessionStorage);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginRemoved: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
var localStorageKey = this._storageKey(securityOrigin, true);
var localStorage = this._storages[localStorageKey];
console.assert(localStorage);
delete this._storages[localStorageKey];
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, localStorage);
var sessionStorageKey = this._storageKey(securityOrigin, false);
var sessionStorage = this._storages[sessionStorageKey];
console.assert(sessionStorage);
delete this._storages[sessionStorageKey];
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, sessionStorage);
},
/**
* @param {string} securityOrigin
* @param {boolean} isLocalStorage
* @return {string}
*/
_storageKey: function(securityOrigin, isLocalStorage)
{
return JSON.stringify(WebInspector.DOMStorage.storageId(securityOrigin, isLocalStorage));
},
/**
* @param {!DOMStorageAgent.StorageId} storageId
*/
_domStorageItemsCleared: function(storageId)
{
var domStorage = this.storageForId(storageId);
if (!domStorage)
return;
var eventData = {};
domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemsCleared, eventData);
},
/**
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
*/
_domStorageItemRemoved: function(storageId, key)
{
var domStorage = this.storageForId(storageId);
if (!domStorage)
return;
var eventData = { key: key };
domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemRemoved, eventData);
},
/**
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
* @param {string} value
*/
_domStorageItemAdded: function(storageId, key, value)
{
var domStorage = this.storageForId(storageId);
if (!domStorage)
return;
var eventData = { key: key, value: value };
domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemAdded, eventData);
},
/**
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
* @param {string} oldValue
* @param {string} value
*/
_domStorageItemUpdated: function(storageId, key, oldValue, value)
{
var domStorage = this.storageForId(storageId);
if (!domStorage)
return;
var eventData = { key: key, oldValue: oldValue, value: value };
domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemUpdated, eventData);
},
/**
* @param {!DOMStorageAgent.StorageId} storageId
* @return {!WebInspector.DOMStorage}
*/
storageForId: function(storageId)
{
return this._storages[JSON.stringify(storageId)];
},
/**
* @return {!Array.<!WebInspector.DOMStorage>}
*/
storages: function()
{
var result = [];
for (var id in this._storages)
result.push(this._storages[id]);
return result;
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {DOMStorageAgent.Dispatcher}
* @param {!WebInspector.DOMStorageModel} model
*/
WebInspector.DOMStorageDispatcher = function(model)
{
this._model = model;
}
WebInspector.DOMStorageDispatcher.prototype = {
/**
* @override
* @param {!DOMStorageAgent.StorageId} storageId
*/
domStorageItemsCleared: function(storageId)
{
this._model._domStorageItemsCleared(storageId);
},
/**
* @override
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
*/
domStorageItemRemoved: function(storageId, key)
{
this._model._domStorageItemRemoved(storageId, key);
},
/**
* @override
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
* @param {string} value
*/
domStorageItemAdded: function(storageId, key, value)
{
this._model._domStorageItemAdded(storageId, key, value);
},
/**
* @override
* @param {!DOMStorageAgent.StorageId} storageId
* @param {string} key
* @param {string} oldValue
* @param {string} value
*/
domStorageItemUpdated: function(storageId, key, oldValue, value)
{
this._model._domStorageItemUpdated(storageId, key, oldValue, value);
},
}
WebInspector.DOMStorageModel._symbol = Symbol("DomStorage");
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.DOMStorageModel}
*/
WebInspector.DOMStorageModel.fromTarget = function(target)
{
if (!target[WebInspector.DOMStorageModel._symbol])
target[WebInspector.DOMStorageModel._symbol] = new WebInspector.DOMStorageModel(target);
return target[WebInspector.DOMStorageModel._symbol];
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | 2 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.DatabaseModel} model
* @param {string} id
* @param {string} domain
* @param {string} name
* @param {string} version
*/
WebInspector.Database = function(model, id, domain, name, version)
{
this._model = model;
this._id = id;
this._domain = domain;
this._name = name;
this._version = version;
}
WebInspector.Database.prototype = {
/** @return {string} */
get id()
{
return this._id;
},
/** @return {string} */
get name()
{
return this._name;
},
set name(x)
{
this._name = x;
},
/** @return {string} */
get version()
{
return this._version;
},
set version(x)
{
this._version = x;
},
/** @return {string} */
get domain()
{
return this._domain;
},
set domain(x)
{
this._domain = x;
},
/**
* @param {function(!Array.<string>)} callback
*/
getTableNames: function(callback)
{
function sortingCallback(error, names)
{
if (!error)
callback(names.sort());
}
this._model._agent.getDatabaseTableNames(this._id, sortingCallback);
},
/**
* @param {string} query
* @param {function(!Array.<string>=, !Array.<*>=)} onSuccess
* @param {function(string)} onError
*/
executeSql: function(query, onSuccess, onError)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<string>=} columnNames
* @param {!Array.<*>=} values
* @param {!DatabaseAgent.Error=} errorObj
*/
function callback(error, columnNames, values, errorObj)
{
if (error) {
onError(error);
return;
}
if (errorObj) {
var message;
if (errorObj.message)
message = errorObj.message;
else if (errorObj.code == 2)
message = WebInspector.UIString("Database no longer has expected version.");
else
message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
onError(message);
return;
}
onSuccess(columnNames, values);
}
this._model._agent.executeSQL(this._id, query, callback);
}
}
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.DatabaseModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.DatabaseModel, target);
this._databases = [];
this._agent = target.databaseAgent();
}
WebInspector.DatabaseModel.Events = {
DatabaseAdded: "DatabaseAdded"
}
WebInspector.DatabaseModel.prototype = {
enable: function()
{
if (this._enabled)
return;
this.target().registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
this._agent.enable();
this._enabled = true;
},
/**
* @return {!Array.<!WebInspector.Database>}
*/
databases: function()
{
var result = [];
for (var database of this._databases)
result.push(database);
return result;
},
/**
* @param {!WebInspector.Database} database
*/
_addDatabase: function(database)
{
this._databases.push(database);
this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {DatabaseAgent.Dispatcher}
* @param {!WebInspector.DatabaseModel} model
*/
WebInspector.DatabaseDispatcher = function(model)
{
this._model = model;
}
WebInspector.DatabaseDispatcher.prototype = {
/**
* @override
* @param {!DatabaseAgent.Database} payload
*/
addDatabase: function(payload)
{
this._model._addDatabase(new WebInspector.Database(
this._model,
payload.id,
payload.domain,
payload.name,
payload.version));
}
}
WebInspector.DatabaseModel._symbol = Symbol("DatabaseModel");
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.DatabaseModel}
*/
WebInspector.DatabaseModel.fromTarget = function(target)
{
if (!target[WebInspector.DatabaseModel._symbol])
target[WebInspector.DatabaseModel._symbol] = new WebInspector.DatabaseModel(target);
return target[WebInspector.DatabaseModel._symbol];
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | 2 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DatabaseQueryView = function(database)
{
WebInspector.VBox.call(this);
this.database = database;
this.element.classList.add("storage-view", "query", "monospace");
this.element.addEventListener("selectstart", this._selectStart.bind(this), false);
this._promptElement = createElement("div");
this._promptElement.className = "database-query-prompt";
this._promptElement.appendChild(createElement("br"));
this._promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.element.appendChild(this._promptElement);
this._prompt = new WebInspector.TextPromptWithHistory(this.completions.bind(this), " ");
this._proxyElement = this._prompt.attach(this._promptElement);
this.element.addEventListener("click", this._messagesClicked.bind(this), true);
}
WebInspector.DatabaseQueryView.Events = {
SchemaUpdated: "SchemaUpdated"
}
WebInspector.DatabaseQueryView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [];
},
_messagesClicked: function()
{
if (!this._prompt.isCaretInsidePrompt() && this.element.isComponentSelectionCollapsed())
this._prompt.moveCaretToEndOfPrompt();
},
/**
* @param {!Element} proxyElement
* @param {string} text
* @param {number} cursorOffset
* @param {!Range} wordRange
* @param {boolean} force
* @param {function(!Array.<string>, number=)} completionsReadyCallback
*/
completions: function(proxyElement, text, cursorOffset, wordRange, force, completionsReadyCallback)
{
var prefix = wordRange.toString().toLowerCase();
if (!prefix)
return;
var results = [];
function accumulateMatches(textArray)
{
for (var i = 0; i < textArray.length; ++i) {
var text = textArray[i].toLowerCase();
if (text.length < prefix.length)
continue;
if (!text.startsWith(prefix))
continue;
results.push(textArray[i]);
}
}
function tableNamesCallback(tableNames)
{
accumulateMatches(tableNames.map(function(name) { return name + " "; }));
accumulateMatches(["SELECT ", "FROM ", "WHERE ", "LIMIT ", "DELETE FROM ", "CREATE ", "DROP ", "TABLE ", "INDEX ", "UPDATE ", "INSERT INTO ", "VALUES ("]);
completionsReadyCallback(results);
}
this.database.getTableNames(tableNamesCallback);
},
_selectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);
this._prompt.clearAutoComplete();
/**
* @this {WebInspector.DatabaseQueryView}
*/
function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this._prompt.isCaretInsidePrompt() && this.element.isComponentSelectionCollapsed())
this._prompt.moveCaretToEndOfPrompt();
this._prompt.autoCompleteSoon();
}
this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},
_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}
},
_enterKeyPressed: function(event)
{
event.consume(true);
this._prompt.clearAutoComplete(true);
var query = this._prompt.text();
if (!query.length)
return;
this._prompt.pushHistoryItem(query);
this._prompt.setText("");
this.database.executeSql(query, this._queryFinished.bind(this, query), this._queryError.bind(this, query));
},
_queryFinished: function(query, columnNames, values)
{
var dataGrid = WebInspector.SortableDataGrid.create(columnNames, values);
var trimmedQuery = query.trim();
if (dataGrid) {
dataGrid.renderInline();
this._appendViewQueryResult(trimmedQuery, dataGrid.asWidget());
dataGrid.autoSizeColumns(5);
}
if (trimmedQuery.match(/^create /i) || trimmedQuery.match(/^drop table /i))
this.dispatchEventToListeners(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this.database);
},
_queryError: function(query, errorMessage)
{
this._appendErrorQueryResult(query, errorMessage);
},
/**
* @param {string} query
* @param {!WebInspector.Widget} view
*/
_appendViewQueryResult: function(query, view)
{
var resultElement = this._appendQueryResult(query);
view.show(resultElement);
this._promptElement.scrollIntoView(false);
},
/**
* @param {string} query
* @param {string} errorText
*/
_appendErrorQueryResult: function(query, errorText)
{
var resultElement = this._appendQueryResult(query);
resultElement.classList.add("error");
resultElement.textContent = errorText;
this._promptElement.scrollIntoView(false);
},
_appendQueryResult: function(query)
{
var element = createElement("div");
element.className = "database-user-query";
this.element.insertBefore(element, this._proxyElement);
var commandTextElement = createElement("span");
commandTextElement.className = "database-query-text";
commandTextElement.textContent = query;
element.appendChild(commandTextElement);
var resultElement = createElement("div");
resultElement.className = "database-query-result";
element.appendChild(resultElement);
return resultElement;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.DatabaseTableView = function(database, tableName)
{
WebInspector.VBox.call(this);
this.database = database;
this.tableName = tableName;
this.element.classList.add("storage-view", "table");
this._visibleColumnsSetting = WebInspector.settings.createSetting("databaseTableViewVisibleColumns", {});
this.refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this.refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this._visibleColumnsInput = new WebInspector.ToolbarInput(WebInspector.UIString("Visible columns"), 1);
this._visibleColumnsInput.addEventListener(WebInspector.ToolbarInput.Event.TextChanged, this._onVisibleColumnsChanged, this);
}
WebInspector.DatabaseTableView.prototype = {
wasShown: function()
{
this.update();
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this.refreshButton, this._visibleColumnsInput];
},
/**
* @param {string} tableName
* @return {string}
*/
_escapeTableName: function(tableName)
{
return tableName.replace(/\"/g, "\"\"");
},
update: function()
{
this.database.executeSql("SELECT rowid, * FROM \"" + this._escapeTableName(this.tableName) + "\"", this._queryFinished.bind(this), this._queryError.bind(this));
},
_queryFinished: function(columnNames, values)
{
this.detachChildWidgets();
this.element.removeChildren();
this._dataGrid = WebInspector.SortableDataGrid.create(columnNames, values);
this._visibleColumnsInput.setVisible(!!this._dataGrid);
if (!this._dataGrid) {
this._emptyWidget = new WebInspector.EmptyWidget(WebInspector.UIString("The “%s”\ntable is empty.", this.tableName));
this._emptyWidget.show(this.element);
return;
}
this._dataGrid.asWidget().show(this.element);
this._dataGrid.autoSizeColumns(5);
this._columnsMap = new Map();
for (var i = 1; i < columnNames.length; ++i)
this._columnsMap.set(columnNames[i], String(i));
this._lastVisibleColumns = "";
var visibleColumnsText = this._visibleColumnsSetting.get()[this.tableName] || "";
this._visibleColumnsInput.setValue(visibleColumnsText);
this._onVisibleColumnsChanged();
},
_onVisibleColumnsChanged: function()
{
if (!this._dataGrid)
return;
var text = this._visibleColumnsInput.value();
var parts = text.split(/[\s,]+/);
var matches = new Set();
var columnsVisibility = {};
columnsVisibility["0"] = true;
for (var i = 0; i < parts.length; ++i) {
var part = parts[i];
if (this._columnsMap.has(part)) {
matches.add(part);
columnsVisibility[this._columnsMap.get(part)] = true;
}
}
var newVisibleColumns = matches.valuesArray().sort().join(", ");
if (newVisibleColumns.length === 0) {
for (var v of this._columnsMap.values())
columnsVisibility[v] = true;
}
if (newVisibleColumns === this._lastVisibleColumns)
return;
var visibleColumnsRegistry = this._visibleColumnsSetting.get();
visibleColumnsRegistry[this.tableName] = text;
this._visibleColumnsSetting.set(visibleColumnsRegistry);
this._dataGrid.setColumnsVisiblity(columnsVisibility);
this._lastVisibleColumns = newVisibleColumns;
},
_queryError: function(error)
{
this.detachChildWidgets();
this.element.removeChildren();
var errorMsgElement = createElement("div");
errorMsgElement.className = "storage-table-error";
errorMsgElement.textContent = WebInspector.UIString("An error occurred trying to\nread the “%s” table.", this.tableName);
this.element.appendChild(errorMsgElement);
},
_refreshButtonClicked: function(event)
{
this.update();
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | 2 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
*/
WebInspector.IndexedDBModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.IndexedDBModel, target);
this._agent = target.indexedDBAgent();
/** @type {!Map.<!WebInspector.IndexedDBModel.DatabaseId, !WebInspector.IndexedDBModel.Database>} */
this._databases = new Map();
/** @type {!Object.<string, !Array.<string>>} */
this._databaseNamesBySecurityOrigin = {};
}
WebInspector.IndexedDBModel.KeyTypes = {
NumberType: "number",
StringType: "string",
DateType: "date",
ArrayType: "array"
};
WebInspector.IndexedDBModel.KeyPathTypes = {
NullType: "null",
StringType: "string",
ArrayType: "array"
};
/**
* @param {*} idbKey
* @return {?Object}
*/
WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
{
if (typeof(idbKey) === "undefined" || idbKey === null)
return null;
var key = {};
switch (typeof(idbKey)) {
case "number":
key.number = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
break;
case "string":
key.string = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
break;
case "object":
if (idbKey instanceof Date) {
key.date = idbKey.getTime();
key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
} else if (Array.isArray(idbKey)) {
key.array = [];
for (var i = 0; i < idbKey.length; ++i)
key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
}
break;
default:
return null;
}
return key;
}
/**
* @param {?IDBKeyRange=} idbKeyRange
* @return {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}}
*/
WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
{
if (typeof idbKeyRange === "undefined" || idbKeyRange === null)
return null;
var keyRange = {};
keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
keyRange.lowerOpen = idbKeyRange.lowerOpen;
keyRange.upperOpen = idbKeyRange.upperOpen;
return keyRange;
}
/**
* @param {!IndexedDBAgent.KeyPath} keyPath
* @return {?string|!Array.<string>|undefined}
*/
WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
{
var idbKeyPath;
switch (keyPath.type) {
case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
idbKeyPath = null;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
idbKeyPath = keyPath.string;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
idbKeyPath = keyPath.array;
break;
}
return idbKeyPath;
}
/**
* @param {?string|!Array.<string>|undefined} idbKeyPath
* @return {?string}
*/
WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
{
if (typeof idbKeyPath === "string")
return "\"" + idbKeyPath + "\"";
if (idbKeyPath instanceof Array)
return "[\"" + idbKeyPath.join("\", \"") + "\"]";
return null;
}
WebInspector.IndexedDBModel.EventTypes = {
DatabaseAdded: "DatabaseAdded",
DatabaseRemoved: "DatabaseRemoved",
DatabaseLoaded: "DatabaseLoaded"
}
WebInspector.IndexedDBModel.prototype = {
enable: function()
{
if (this._enabled)
return;
this._agent.enable();
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
this._enabled = true;
},
refreshDatabaseNames: function()
{
for (var securityOrigin in this._databaseNamesBySecurityOrigin)
this._loadDatabaseNames(securityOrigin);
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
*/
refreshDatabase: function(databaseId)
{
this._loadDatabase(databaseId);
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} objectStoreName
* @param {function()} callback
*/
clearObjectStore: function(databaseId, objectStoreName, callback)
{
this._agent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName, callback);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginAdded: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
this._addOrigin(securityOrigin);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginRemoved: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
this._removeOrigin(securityOrigin);
},
/**
* @param {string} securityOrigin
*/
_addOrigin: function(securityOrigin)
{
console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]);
this._databaseNamesBySecurityOrigin[securityOrigin] = [];
this._loadDatabaseNames(securityOrigin);
},
/**
* @param {string} securityOrigin
*/
_removeOrigin: function(securityOrigin)
{
console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]);
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
delete this._databaseNamesBySecurityOrigin[securityOrigin];
},
/**
* @param {string} securityOrigin
* @param {!Array.<string>} databaseNames
*/
_updateOriginDatabaseNames: function(securityOrigin, databaseNames)
{
var newDatabaseNames = databaseNames.keySet();
var oldDatabaseNames = this._databaseNamesBySecurityOrigin[securityOrigin].keySet();
this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;
for (var databaseName in oldDatabaseNames) {
if (!newDatabaseNames[databaseName])
this._databaseRemoved(securityOrigin, databaseName);
}
for (var databaseName in newDatabaseNames) {
if (!oldDatabaseNames[databaseName])
this._databaseAdded(securityOrigin, databaseName);
}
},
/**
* @return {!Array.<!WebInspector.IndexedDBModel.DatabaseId>}
*/
databases: function()
{
var result = [];
for (var securityOrigin in this._databaseNamesBySecurityOrigin) {
var databaseNames = this._databaseNamesBySecurityOrigin[securityOrigin];
for (var i = 0; i < databaseNames.length; ++i) {
result.push(new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseNames[i]));
}
}
return result;
},
/**
* @param {string} securityOrigin
* @param {string} databaseName
*/
_databaseAdded: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
},
/**
* @param {string} securityOrigin
* @param {string} databaseName
*/
_databaseRemoved: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
},
/**
* @param {string} securityOrigin
*/
_loadDatabaseNames: function(securityOrigin)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<string>} databaseNames
* @this {WebInspector.IndexedDBModel}
*/
function callback(error, databaseNames)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
if (!this._databaseNamesBySecurityOrigin[securityOrigin])
return;
this._updateOriginDatabaseNames(securityOrigin, databaseNames);
}
this._agent.requestDatabaseNames(securityOrigin, callback.bind(this));
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
*/
_loadDatabase: function(databaseId)
{
/**
* @param {?Protocol.Error} error
* @param {!IndexedDBAgent.DatabaseWithObjectStores} databaseWithObjectStores
* @this {WebInspector.IndexedDBModel}
*/
function callback(error, databaseWithObjectStores)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
return;
var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version);
this._databases.set(databaseId, databaseModel);
for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
var objectStore = databaseWithObjectStores.objectStores[i];
var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
for (var j = 0; j < objectStore.indexes.length; ++j) {
var index = objectStore.indexes[j];
var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
objectStoreModel.indexes[indexModel.name] = indexModel;
}
databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
}
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
}
this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} objectStoreName
* @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
*/
loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} objectStoreName
* @param {string} indexName
* @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
*/
loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} databaseName
* @param {string} objectStoreName
* @param {string} indexName
* @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
*/
_requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!IndexedDBAgent.DataEntry>} dataEntries
* @param {boolean} hasMore
* @this {WebInspector.IndexedDBModel}
*/
function innerCallback(error, dataEntries, hasMore)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
return;
var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
var key = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].key));
var primaryKey = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].primaryKey));
var value = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].value));
entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
}
callback(entries, hasMore);
}
var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
this._agent.requestData(databaseId.securityOrigin, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @param {!WebInspector.RemoteObject} key
* @param {!WebInspector.RemoteObject} primaryKey
* @param {!WebInspector.RemoteObject} value
*/
WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
{
this.key = key;
this.primaryKey = primaryKey;
this.value = value;
}
/**
* @constructor
* @param {string} securityOrigin
* @param {string} name
*/
WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
{
this.securityOrigin = securityOrigin;
this.name = name;
}
WebInspector.IndexedDBModel.DatabaseId.prototype = {
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @return {boolean}
*/
equals: function(databaseId)
{
return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
},
}
/**
* @constructor
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {number} version
*/
WebInspector.IndexedDBModel.Database = function(databaseId, version)
{
this.databaseId = databaseId;
this.version = version;
this.objectStores = {};
}
/**
* @constructor
* @param {string} name
* @param {*} keyPath
* @param {boolean} autoIncrement
*/
WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
{
this.name = name;
this.keyPath = keyPath;
this.autoIncrement = autoIncrement;
this.indexes = {};
}
WebInspector.IndexedDBModel.ObjectStore.prototype = {
/**
* @type {string}
*/
get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}
/**
* @constructor
* @param {string} name
* @param {*} keyPath
* @param {boolean} unique
* @param {boolean} multiEntry
*/
WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
{
this.name = name;
this.keyPath = keyPath;
this.unique = unique;
this.multiEntry = multiEntry;
}
WebInspector.IndexedDBModel.Index.prototype = {
/**
* @type {string}
*/
get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.IndexedDBModel}
*/
WebInspector.IndexedDBModel.fromTarget = function(target)
{
var model = /** @type {?WebInspector.IndexedDBModel} */ (target.model(WebInspector.IndexedDBModel));
if (!model)
model = new WebInspector.IndexedDBModel(target);
return model;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.IndexedDBModel.Database} database
*/
WebInspector.IDBDatabaseView = function(database)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("resources/indexedDBViews.css");
this.element.classList.add("indexed-db-database-view");
this.element.classList.add("storage-view");
this._headersTreeOutline = new TreeOutline();
this._headersTreeOutline.element.classList.add("outline-disclosure");
this.element.appendChild(this._headersTreeOutline.element);
this._headersTreeOutline.expandTreeElementsWhenArrowing = true;
this._securityOriginTreeElement = new TreeElement();
this._securityOriginTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._securityOriginTreeElement);
this._nameTreeElement = new TreeElement();
this._nameTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._nameTreeElement);
this._versionTreeElement = new TreeElement();
this._versionTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._versionTreeElement);
this.update(database);
}
WebInspector.IDBDatabaseView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [];
},
/**
* @param {string} name
* @param {string} value
*/
_formatHeader: function(name, value)
{
var fragment = createDocumentFragment();
fragment.createChild("div", "attribute-name").textContent = name + ":";
fragment.createChild("div", "attribute-value source-code").textContent = value;
return fragment;
},
_refreshDatabase: function()
{
this._securityOriginTreeElement.title = this._formatHeader(WebInspector.UIString("Security origin"), this._database.databaseId.securityOrigin);
this._nameTreeElement.title = this._formatHeader(WebInspector.UIString("Name"), this._database.databaseId.name);
this._versionTreeElement.title = this._formatHeader(WebInspector.UIString("Version"), this._database.version);
},
/**
* @param {!WebInspector.IndexedDBModel.Database} database
*/
update: function(database)
{
this._database = database;
this._refreshDatabase();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
* @param {?WebInspector.IndexedDBModel.Index} index
*/
WebInspector.IDBDataView = function(model, databaseId, objectStore, index)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("resources/indexedDBViews.css");
this._model = model;
this._databaseId = databaseId;
this._isIndex = !!index;
this.element.classList.add("indexed-db-data-view");
this._createEditorToolbar();
this._refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this._clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear object store"), "clear-toolbar-item");
this._clearButton.addEventListener("click", this._clearButtonClicked, this);
this._pageSize = 50;
this._skipCount = 0;
this.update(objectStore, index);
this._entries = [];
}
WebInspector.IDBDataView.prototype = {
/**
* @return {!WebInspector.DataGrid}
*/
_createDataGrid: function()
{
var keyPath = this._isIndex ? this._index.keyPath : this._objectStore.keyPath;
var columns = [];
columns.push({id: "number", title: WebInspector.UIString("#"), width: "50px"});
columns.push({id: "key", titleDOMFragment: this._keyColumnHeaderFragment(WebInspector.UIString("Key"), keyPath)});
if (this._isIndex)
columns.push({id: "primaryKey", titleDOMFragment: this._keyColumnHeaderFragment(WebInspector.UIString("Primary key"), this._objectStore.keyPath)});
columns.push({id: "value", title: WebInspector.UIString("Value")});
var dataGrid = new WebInspector.DataGrid(columns);
return dataGrid;
},
/**
* @param {string} prefix
* @param {*} keyPath
* @return {!DocumentFragment}
*/
_keyColumnHeaderFragment: function(prefix, keyPath)
{
var keyColumnHeaderFragment = createDocumentFragment();
keyColumnHeaderFragment.createTextChild(prefix);
if (keyPath === null)
return keyColumnHeaderFragment;
keyColumnHeaderFragment.createTextChild(" (" + WebInspector.UIString("Key path: "));
if (Array.isArray(keyPath)) {
keyColumnHeaderFragment.createTextChild("[");
for (var i = 0; i < keyPath.length; ++i) {
if (i != 0)
keyColumnHeaderFragment.createTextChild(", ");
keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));
}
keyColumnHeaderFragment.createTextChild("]");
} else {
var keyPathString = /** @type {string} */ (keyPath);
keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPathString));
}
keyColumnHeaderFragment.createTextChild(")");
return keyColumnHeaderFragment;
},
/**
* @param {string} keyPathString
* @return {!DocumentFragment}
*/
_keyPathStringFragment: function(keyPathString)
{
var keyPathStringFragment = createDocumentFragment();
keyPathStringFragment.createTextChild("\"");
var keyPathSpan = keyPathStringFragment.createChild("span", "source-code indexed-db-key-path");
keyPathSpan.textContent = keyPathString;
keyPathStringFragment.createTextChild("\"");
return keyPathStringFragment;
},
_createEditorToolbar: function()
{
var editorToolbar = new WebInspector.Toolbar("data-view-toolbar", this.element);
this._pageBackButton = new WebInspector.ToolbarButton(WebInspector.UIString("Show previous page"), "play-backwards-toolbar-item");
this._pageBackButton.addEventListener("click", this._pageBackButtonClicked, this);
editorToolbar.appendToolbarItem(this._pageBackButton);
this._pageForwardButton = new WebInspector.ToolbarButton(WebInspector.UIString("Show next page"), "play-toolbar-item");
this._pageForwardButton.setEnabled(false);
this._pageForwardButton.addEventListener("click", this._pageForwardButtonClicked, this);
editorToolbar.appendToolbarItem(this._pageForwardButton);
this._keyInputElement = editorToolbar.element.createChild("input", "key-input");
this._keyInputElement.placeholder = WebInspector.UIString("Start from key");
this._keyInputElement.addEventListener("paste", this._keyInputChanged.bind(this), false);
this._keyInputElement.addEventListener("cut", this._keyInputChanged.bind(this), false);
this._keyInputElement.addEventListener("keypress", this._keyInputChanged.bind(this), false);
this._keyInputElement.addEventListener("keydown", this._keyInputChanged.bind(this), false);
},
_pageBackButtonClicked: function()
{
this._skipCount = Math.max(0, this._skipCount - this._pageSize);
this._updateData(false);
},
_pageForwardButtonClicked: function()
{
this._skipCount = this._skipCount + this._pageSize;
this._updateData(false);
},
_keyInputChanged: function()
{
window.setTimeout(this._updateData.bind(this, false), 0);
},
/**
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
* @param {?WebInspector.IndexedDBModel.Index} index
*/
update: function(objectStore, index)
{
this._objectStore = objectStore;
this._index = index;
if (this._dataGrid)
this._dataGrid.asWidget().detach();
this._dataGrid = this._createDataGrid();
this._dataGrid.asWidget().show(this.element);
this._skipCount = 0;
this._updateData(true);
},
/**
* @param {string} keyString
*/
_parseKey: function(keyString)
{
var result;
try {
result = JSON.parse(keyString);
} catch (e) {
result = keyString;
}
return result;
},
/**
* @param {boolean} force
*/
_updateData: function(force)
{
var key = this._parseKey(this._keyInputElement.value);
var pageSize = this._pageSize;
var skipCount = this._skipCount;
this._refreshButton.setEnabled(false);
this._clearButton.setEnabled(!this._isIndex);
if (!force && this._lastKey === key && this._lastPageSize === pageSize && this._lastSkipCount === skipCount)
return;
if (this._lastKey !== key || this._lastPageSize !== pageSize) {
skipCount = 0;
this._skipCount = 0;
}
this._lastKey = key;
this._lastPageSize = pageSize;
this._lastSkipCount = skipCount;
/**
* @param {!Array.<!WebInspector.IndexedDBModel.Entry>} entries
* @param {boolean} hasMore
* @this {WebInspector.IDBDataView}
*/
function callback(entries, hasMore)
{
this._refreshButton.setEnabled(true);
this.clear();
this._entries = entries;
for (var i = 0; i < entries.length; ++i) {
var data = {};
data["number"] = i + skipCount;
data["key"] = entries[i].key;
data["primaryKey"] = entries[i].primaryKey;
data["value"] = entries[i].value;
var node = new WebInspector.IDBDataGridNode(data);
this._dataGrid.rootNode().appendChild(node);
}
this._pageBackButton.setEnabled(!!skipCount);
this._pageForwardButton.setEnabled(hasMore);
}
var idbKeyRange = key ? window.IDBKeyRange.lowerBound(key) : null;
if (this._isIndex)
this._model.loadIndexData(this._databaseId, this._objectStore.name, this._index.name, idbKeyRange, skipCount, pageSize, callback.bind(this));
else
this._model.loadObjectStoreData(this._databaseId, this._objectStore.name, idbKeyRange, skipCount, pageSize, callback.bind(this));
},
_refreshButtonClicked: function(event)
{
this._updateData(true);
},
_clearButtonClicked: function(event)
{
/**
* @this {WebInspector.IDBDataView}
*/
function cleared() {
this._clearButton.setEnabled(true);
this._updateData(true);
}
this._clearButton.setEnabled(false);
this._model.clearObjectStore(this._databaseId, this._objectStore.name, cleared.bind(this));
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._refreshButton, this._clearButton];
},
clear: function()
{
this._dataGrid.rootNode().removeChildren();
this._entries = [];
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.DataGridNode}
* @param {!Object.<string, *>} data
*/
WebInspector.IDBDataGridNode = function(data)
{
WebInspector.DataGridNode.call(this, data, false);
this.selectable = false;
}
WebInspector.IDBDataGridNode.prototype = {
/**
* @override
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
var value = this.data[columnIdentifier];
switch (columnIdentifier) {
case "value":
case "key":
case "primaryKey":
cell.removeChildren();
var objectElement = WebInspector.ObjectPropertiesSection.defaultObjectPresentation(value, true);
cell.appendChild(objectElement);
break;
default:
}
return cell;
},
__proto__: WebInspector.DataGridNode.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.PanelWithSidebar}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.ResourcesPanel = function()
{
WebInspector.PanelWithSidebar.call(this, "resources");
this.registerRequiredCSS("resources/resourcesPanel.css");
this._resourcesLastSelectedItemSetting = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
this._sidebarTree = new TreeOutline();
this._sidebarTree.element.classList.add("filter-all", "children", "small", "outline-disclosure");
this.panelSidebarElement().appendChild(this._sidebarTree.element);
this.setDefaultFocusedElement(this._sidebarTree.element);
this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
this._sidebarTree.appendChild(this.resourcesListTreeElement);
this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]);
this._sidebarTree.appendChild(this.databasesListTreeElement);
this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this);
this._sidebarTree.appendChild(this.indexedDBListTreeElement);
this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]);
this._sidebarTree.appendChild(this.localStorageListTreeElement);
this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]);
this._sidebarTree.appendChild(this.sessionStorageListTreeElement);
this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]);
this._sidebarTree.appendChild(this.cookieListTreeElement);
this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]);
this._sidebarTree.appendChild(this.applicationCacheListTreeElement);
this.cacheStorageListTreeElement = new WebInspector.ServiceWorkerCacheTreeElement(this);
this._sidebarTree.appendChild(this.cacheStorageListTreeElement);
var mainContainer = new WebInspector.VBox();
this.storageViews = mainContainer.element.createChild("div", "vbox flex-auto");
this._storageViewToolbar = new WebInspector.Toolbar("resources-toolbar", mainContainer.element);
this.splitWidget().setMainWidget(mainContainer);
/** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
this._databaseTableViews = new Map();
/** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */
this._databaseQueryViews = new Map();
/** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */
this._databaseTreeElements = new Map();
/** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */
this._domStorageViews = new Map();
/** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */
this._domStorageTreeElements = new Map();
/** @type {!Object.<string, !WebInspector.CookieItemsView>} */
this._cookieViews = {};
/** @type {!Object.<string, boolean>} */
this._domains = {};
this.panelSidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
this.panelSidebarElement().addEventListener("mouseleave", this._onmouseleave.bind(this), false);
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ResourcesPanel.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (this._target)
return;
this._target = target;
if (target.serviceWorkerManager) {
this.serviceWorkersTreeElement = new WebInspector.ServiceWorkersTreeElement(this);
this._sidebarTree.appendChild(this.serviceWorkersTreeElement);
}
this._databaseModel = WebInspector.DatabaseModel.fromTarget(target);
this._domStorageModel = WebInspector.DOMStorageModel.fromTarget(target);
if (target.resourceTreeModel.cachedResourcesLoaded())
this._initialize();
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._initialize, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
this._databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (target !== this._target)
return;
delete this._target;
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._initialize, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
this._databaseModel.removeEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
this._resetWithFrames();
},
_initialize: function()
{
this._databaseModel.enable();
this._domStorageModel.enable();
var indexedDBModel = WebInspector.IndexedDBModel.fromTarget(this._target);
if (indexedDBModel)
indexedDBModel.enable();
var cacheStorageModel = WebInspector.ServiceWorkerCacheModel.fromTarget(this._target);
if (cacheStorageModel)
cacheStorageModel.enable();
if (this._target.isPage())
this._populateResourceTree();
this._populateDOMStorageTree();
this._populateApplicationCacheTree();
this.indexedDBListTreeElement._initialize();
this.cacheStorageListTreeElement._initialize();
this._initDefaultSelection();
this._initialized = true;
},
_loadEventFired: function()
{
this._initDefaultSelection();
},
_initDefaultSelection: function()
{
if (!this._initialized)
return;
var itemURL = this._resourcesLastSelectedItemSetting.get();
if (itemURL) {
var rootElement = this._sidebarTree.rootElement();
for (var treeElement = rootElement.firstChild(); treeElement; treeElement = treeElement.traverseNextTreeElement(false, rootElement, true)) {
if (treeElement.itemURL === itemURL) {
treeElement.revealAndSelect(true);
return;
}
}
}
var mainResource = this._target.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded
? this._target.resourceTreeModel.resourceForURL(this._target.resourceTreeModel.inspectedPageURL())
: null;
if (mainResource)
this.showResource(mainResource);
},
_resetWithFrames: function()
{
this.resourcesListTreeElement.removeChildren();
this._treeElementForFrameId = {};
this._reset();
},
_reset: function()
{
this._domains = {};
var queryViews = this._databaseQueryViews.valuesArray();
for (var i = 0; i < queryViews.length; ++i)
queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
this._databaseTableViews.clear();
this._databaseQueryViews.clear();
this._databaseTreeElements.clear();
this._domStorageViews.clear();
this._domStorageTreeElements.clear();
this._cookieViews = {};
this.databasesListTreeElement.removeChildren();
this.localStorageListTreeElement.removeChildren();
this.sessionStorageListTreeElement.removeChildren();
this.cookieListTreeElement.removeChildren();
this.cacheStorageListTreeElement.removeChildren();
if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView))
this.visibleView.detach();
this._storageViewToolbar.removeToolbarItems();
if (this._sidebarTree.selectedTreeElement)
this._sidebarTree.selectedTreeElement.deselect();
},
_populateResourceTree: function()
{
this._treeElementForFrameId = {};
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
/**
* @param {!WebInspector.ResourceTreeFrame} frame
* @this {WebInspector.ResourcesPanel}
*/
function populateFrame(frame)
{
this._frameAdded({data:frame});
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);
var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._resourceAdded({data:resources[i]});
}
populateFrame.call(this, this._target.resourceTreeModel.mainFrame);
},
_frameAdded: function(event)
{
var frame = event.data;
var parentFrame = frame.parentFrame;
var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement;
if (!parentTreeElement) {
console.warn("No frame to route " + frame.url + " to.");
return;
}
var frameTreeElement = new WebInspector.FrameTreeElement(this, frame);
this._treeElementForFrameId[frame.id] = frameTreeElement;
parentTreeElement.appendChild(frameTreeElement);
},
_frameDetached: function(event)
{
var frame = event.data;
var frameTreeElement = this._treeElementForFrameId[frame.id];
if (!frameTreeElement)
return;
delete this._treeElementForFrameId[frame.id];
if (frameTreeElement.parent)
frameTreeElement.parent.removeChild(frameTreeElement);
},
_resourceAdded: function(event)
{
var resource = event.data;
var frameId = resource.frameId;
if (resource.statusCode >= 301 && resource.statusCode <= 303)
return;
var frameTreeElement = this._treeElementForFrameId[frameId];
if (!frameTreeElement) {
// This is a frame's main resource, it will be retained
// and re-added by the resource manager;
return;
}
frameTreeElement.appendResource(resource);
},
_frameNavigated: function(event)
{
var frame = event.data;
if (!frame.parentFrame)
this._reset();
var frameId = frame.id;
var frameTreeElement = this._treeElementForFrameId[frameId];
if (frameTreeElement)
frameTreeElement.frameNavigated(frame);
var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId];
if (applicationCacheFrameTreeElement)
applicationCacheFrameTreeElement.frameNavigated(frame);
},
/**
* @param {!WebInspector.Event} event
*/
_databaseAdded: function(event)
{
var database = /** @type {!WebInspector.Database} */ (event.data);
this._addDatabase(database);
},
/**
* @param {!WebInspector.Database} database
*/
_addDatabase: function(database)
{
var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
this._databaseTreeElements.set(database, databaseTreeElement);
this.databasesListTreeElement.appendChild(databaseTreeElement);
},
addDocumentURL: function(url)
{
var parsedURL = url.asParsedURL();
if (!parsedURL)
return;
var domain = parsedURL.host;
if (!this._domains[domain]) {
this._domains[domain] = true;
var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
}
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageAdded: function(event)
{
var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
this._addDOMStorage(domStorage);
},
/**
* @param {!WebInspector.DOMStorage} domStorage
*/
_addDOMStorage: function(domStorage)
{
console.assert(!this._domStorageTreeElements.get(domStorage));
var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
this._domStorageTreeElements.set(domStorage, domStorageTreeElement);
if (domStorage.isLocalStorage)
this.localStorageListTreeElement.appendChild(domStorageTreeElement);
else
this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
},
/**
* @param {!WebInspector.Event} event
*/
_domStorageRemoved: function(event)
{
var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
this._removeDOMStorage(domStorage);
},
/**
* @param {!WebInspector.DOMStorage} domStorage
*/
_removeDOMStorage: function(domStorage)
{
var treeElement = this._domStorageTreeElements.get(domStorage);
if (!treeElement)
return;
var wasSelected = treeElement.selected;
var parentListTreeElement = treeElement.parent;
parentListTreeElement.removeChild(treeElement);
if (wasSelected)
parentListTreeElement.select();
this._domStorageTreeElements.remove(domStorage);
this._domStorageViews.remove(domStorage);
},
/**
* @param {!WebInspector.Database} database
*/
selectDatabase: function(database)
{
if (database) {
this._showDatabase(database);
this._databaseTreeElements.get(database).select();
}
},
/**
* @param {!WebInspector.DOMStorage} domStorage
*/
selectDOMStorage: function(domStorage)
{
if (domStorage) {
this._showDOMStorage(domStorage);
this._domStorageTreeElements.get(domStorage).select();
}
},
/**
* @param {!WebInspector.Resource} resource
* @param {number=} line
* @param {number=} column
* @return {boolean}
*/
showResource: function(resource, line, column)
{
var resourceTreeElement = this._findTreeElementForResource(resource);
if (resourceTreeElement)
resourceTreeElement.revealAndSelect(true);
if (typeof line === "number") {
var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource);
if (resourceSourceFrame)
resourceSourceFrame.revealPosition(line, column, true);
}
return true;
},
_showResourceView: function(resource)
{
var view = this._resourceViewForResource(resource);
if (!view) {
this.visibleView.detach();
return;
}
this._innerShowView(view);
},
/**
* @param {!WebInspector.Resource} resource
* @return {?WebInspector.Widget}
*/
_resourceViewForResource: function(resource)
{
if (resource.hasTextContent()) {
var treeElement = this._findTreeElementForResource(resource);
if (!treeElement)
return null;
return treeElement.sourceView();
}
switch (resource.resourceType()) {
case WebInspector.resourceTypes.Image:
return new WebInspector.ImageView(resource.mimeType, resource);
case WebInspector.resourceTypes.Font:
return new WebInspector.FontView(resource.mimeType, resource);
default:
return new WebInspector.EmptyWidget(resource.url);
}
},
/**
* @param {!WebInspector.Resource} resource
* @return {?WebInspector.ResourceSourceFrame}
*/
_resourceSourceFrameViewForResource: function(resource)
{
var resourceView = this._resourceViewForResource(resource);
if (resourceView && resourceView instanceof WebInspector.ResourceSourceFrame)
return /** @type {!WebInspector.ResourceSourceFrame} */ (resourceView);
return null;
},
/**
* @param {!WebInspector.Database} database
* @param {string=} tableName
*/
_showDatabase: function(database, tableName)
{
if (!database)
return;
var view;
if (tableName) {
var tableViews = this._databaseTableViews.get(database);
if (!tableViews) {
tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({});
this._databaseTableViews.set(database, tableViews);
}
view = tableViews[tableName];
if (!view) {
view = new WebInspector.DatabaseTableView(database, tableName);
tableViews[tableName] = view;
}
} else {
view = this._databaseQueryViews.get(database);
if (!view) {
view = new WebInspector.DatabaseQueryView(database);
this._databaseQueryViews.set(database, view);
view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
}
}
this._innerShowView(view);
},
/**
* @param {!WebInspector.Widget} view
*/
showIndexedDB: function(view)
{
this._innerShowView(view);
},
/**
* @param {!WebInspector.Widget} view
*/
showServiceWorkerCache: function(view)
{
this._innerShowView(view);
},
/**
* @param {!WebInspector.Widget} view
*/
showServiceWorkersView: function(view)
{
this._innerShowView(view);
},
/**
* @param {!WebInspector.DOMStorage} domStorage
*/
_showDOMStorage: function(domStorage)
{
if (!domStorage)
return;
var view;
view = this._domStorageViews.get(domStorage);
if (!view) {
view = new WebInspector.DOMStorageItemsView(domStorage);
this._domStorageViews.set(domStorage, view);
}
this._innerShowView(view);
},
/**
* @param {!WebInspector.CookieTreeElement} treeElement
* @param {string} cookieDomain
*/
showCookies: function(treeElement, cookieDomain)
{
var view = this._cookieViews[cookieDomain];
if (!view) {
view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
this._cookieViews[cookieDomain] = view;
}
this._innerShowView(view);
},
/**
* @param {string} cookieDomain
*/
clearCookies: function(cookieDomain)
{
this._cookieViews[cookieDomain].clear();
},
showApplicationCache: function(frameId)
{
if (!this._applicationCacheViews[frameId])
this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
this._innerShowView(this._applicationCacheViews[frameId]);
},
/**
* @param {!WebInspector.Widget} view
*/
showFileSystem: function(view)
{
this._innerShowView(view);
},
showCategoryView: function(categoryName)
{
if (!this._categoryView)
this._categoryView = new WebInspector.StorageCategoryView();
this._categoryView.setText(categoryName);
this._innerShowView(this._categoryView);
},
_innerShowView: function(view)
{
if (this.visibleView === view)
return;
if (this.visibleView)
this.visibleView.detach();
view.show(this.storageViews);
this.visibleView = view;
this._storageViewToolbar.removeToolbarItems();
var toolbarItems = view.toolbarItems ? view.toolbarItems() : null;
for (var i = 0; toolbarItems && i < toolbarItems.length; ++i)
this._storageViewToolbar.appendToolbarItem(toolbarItems[i]);
},
closeVisibleView: function()
{
if (!this.visibleView)
return;
this.visibleView.detach();
delete this.visibleView;
},
_updateDatabaseTables: function(event)
{
var database = event.data;
if (!database)
return;
var databasesTreeElement = this._databaseTreeElements.get(database);
if (!databasesTreeElement)
return;
databasesTreeElement.invalidateChildren();
var tableViews = this._databaseTableViews.get(database);
if (!tableViews)
return;
var tableNamesHash = {};
var self = this;
function tableNamesCallback(tableNames)
{
var tableNamesLength = tableNames.length;
for (var i = 0; i < tableNamesLength; ++i)
tableNamesHash[tableNames[i]] = true;
for (var tableName in tableViews) {
if (!(tableName in tableNamesHash)) {
if (self.visibleView === tableViews[tableName])
self.closeVisibleView();
delete tableViews[tableName];
}
}
}
database.getTableNames(tableNamesCallback);
},
_populateDOMStorageTree: function()
{
this._domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
this._domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
this._domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
},
_populateApplicationCacheTree: function()
{
this._applicationCacheModel = new WebInspector.ApplicationCacheModel(this._target);
this._applicationCacheViews = {};
this._applicationCacheFrameElements = {};
this._applicationCacheManifestElements = {};
this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this);
this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
},
_applicationCacheFrameManifestAdded: function(event)
{
var frameId = event.data;
var manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
if (!manifestTreeElement) {
manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL);
this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
}
var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL);
manifestTreeElement.appendChild(frameTreeElement);
manifestTreeElement.expand();
this._applicationCacheFrameElements[frameId] = frameTreeElement;
},
_applicationCacheFrameManifestRemoved: function(event)
{
var frameId = event.data;
var frameTreeElement = this._applicationCacheFrameElements[frameId];
if (!frameTreeElement)
return;
var manifestURL = frameTreeElement.manifestURL;
delete this._applicationCacheFrameElements[frameId];
delete this._applicationCacheViews[frameId];
frameTreeElement.parent.removeChild(frameTreeElement);
var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
if (manifestTreeElement.childCount())
return;
delete this._applicationCacheManifestElements[manifestURL];
manifestTreeElement.parent.removeChild(manifestTreeElement);
},
_applicationCacheFrameManifestStatusChanged: function(event)
{
var frameId = event.data;
var status = this._applicationCacheModel.frameManifestStatus(frameId);
if (this._applicationCacheViews[frameId])
this._applicationCacheViews[frameId].updateStatus(status);
},
_applicationCacheNetworkStateChanged: function(event)
{
var isNowOnline = event.data;
for (var manifestURL in this._applicationCacheViews)
this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
},
_findTreeElementForResource: function(resource)
{
return resource[WebInspector.FrameResourceTreeElement._symbol];
},
showView: function(view)
{
if (view)
this.showResource(view.resource);
},
_onmousemove: function(event)
{
var nodeUnderMouse = event.target;
if (!nodeUnderMouse)
return;
var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
if (!listNode)
return;
var element = listNode.treeElement;
if (this._previousHoveredElement === element)
return;
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
if (element instanceof WebInspector.FrameTreeElement) {
this._previousHoveredElement = element;
element.hovered = true;
}
},
_onmouseleave: function(event)
{
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
},
__proto__: WebInspector.PanelWithSidebar.prototype
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.ResourcesPanel.ResourceRevealer = function()
{
}
WebInspector.ResourcesPanel.ResourceRevealer.prototype = {
/**
* @override
* @param {!Object} resource
* @param {number=} lineNumber
* @return {!Promise}
*/
reveal: function(resource, lineNumber)
{
if (!(resource instanceof WebInspector.Resource))
return Promise.reject(new Error("Internal error: not a resource"));
var panel = WebInspector.ResourcesPanel._instance();
WebInspector.inspectorView.setCurrentPanel(panel);
panel.showResource(resource, lineNumber);
return Promise.resolve();
}
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {string} title
* @param {?Array.<string>=} iconClasses
* @param {boolean=} expandable
* @param {boolean=} noIcon
*/
WebInspector.BaseStorageTreeElement = function(storagePanel, title, iconClasses, expandable, noIcon)
{
TreeElement.call(this, "", expandable);
this._storagePanel = storagePanel;
this._titleText = title;
this._iconClasses = iconClasses;
this._noIcon = noIcon;
}
WebInspector.BaseStorageTreeElement.prototype = {
onattach: function()
{
this.listItemElement.removeChildren();
if (this._iconClasses) {
for (var i = 0; i < this._iconClasses.length; ++i)
this.listItemElement.classList.add(this._iconClasses[i]);
}
this.listItemElement.createChild("div", "selection fill");
if (!this._noIcon)
this.imageElement = this.listItemElement.createChild("img", "icon");
this.titleElement = this.listItemElement.createChild("div", "base-storage-tree-element-title");
this._titleTextNode = this.titleElement.createTextChild("");
this._updateTitle();
this._updateSubtitle();
},
get displayName()
{
return this._displayName;
},
_updateDisplayName: function()
{
this._displayName = this._titleText || "";
if (this._subtitleText)
this._displayName += " (" + this._subtitleText + ")";
},
_updateTitle: function()
{
this._updateDisplayName();
if (!this.titleElement)
return;
this._titleTextNode.textContent = this._titleText || "";
},
_updateSubtitle: function()
{
this._updateDisplayName();
if (!this.titleElement)
return;
if (this._subtitleText) {
if (!this._subtitleElement)
this._subtitleElement = this.titleElement.createChild("span", "base-storage-tree-element-subtitle");
this._subtitleElement.textContent = "(" + this._subtitleText + ")";
} else if (this._subtitleElement) {
this._subtitleElement.remove();
delete this._subtitleElement;
}
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
if (!selectedByUser)
return false;
var itemURL = this.itemURL;
if (itemURL)
this._storagePanel._resourcesLastSelectedItemSetting.set(itemURL);
return false;
},
get titleText()
{
return this._titleText;
},
set titleText(titleText)
{
this._titleText = titleText;
this._updateTitle();
},
get subtitleText()
{
return this._subtitleText;
},
set subtitleText(subtitleText)
{
this._subtitleText = subtitleText;
this._updateSubtitle();
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {string} categoryName
* @param {string} settingsKey
* @param {?Array.<string>=} iconClasses
* @param {boolean=} noIcon
*/
WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, categoryName, iconClasses, false, noIcon);
this._expandedSetting = WebInspector.settings.createSetting("resources" + settingsKey + "Expanded", settingsKey === "Frames");
this._categoryName = categoryName;
}
WebInspector.StorageCategoryTreeElement.prototype = {
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._storagePanel._target;
},
get itemURL()
{
return "category://" + this._categoryName;
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel.showCategoryView(this._categoryName);
return false;
},
/**
* @override
*/
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
if (this._expandedSetting.get())
this.expand();
},
/**
* @override
*/
onexpand: function()
{
this._expandedSetting.set(true);
},
/**
* @override
*/
oncollapse: function()
{
this._expandedSetting.set(false);
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.ResourceTreeFrame} frame
*/
WebInspector.FrameTreeElement = function(storagePanel, frame)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, "", ["frame-storage-tree-item"]);
this._frame = frame;
this.frameNavigated(frame);
}
WebInspector.FrameTreeElement.prototype = {
frameNavigated: function(frame)
{
this.removeChildren();
this._frameId = frame.id;
this.titleText = frame.name;
this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
this._categoryElements = {};
this._treeElementForResource = {};
this._storagePanel.addDocumentURL(frame.url);
},
get itemURL()
{
return "frame://" + encodeURI(this.displayName);
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel.showCategoryView(this.displayName);
this.listItemElement.classList.remove("hovered");
WebInspector.DOMModel.hideDOMNodeHighlight();
return false;
},
set hovered(hovered)
{
if (hovered) {
this.listItemElement.classList.add("hovered");
var domModel = WebInspector.DOMModel.fromTarget(this._frame.target());
if (domModel)
domModel.highlightFrame(this._frameId);
} else {
this.listItemElement.classList.remove("hovered");
WebInspector.DOMModel.hideDOMNodeHighlight();
}
},
/**
* @param {!WebInspector.Resource} resource
*/
appendResource: function(resource)
{
if (resource.isHidden())
return;
var resourceType = resource.resourceType();
var categoryName = resourceType.name();
var categoryElement = resourceType === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName];
if (!categoryElement) {
categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.resourceType().category().title, categoryName, null, true);
this._categoryElements[resourceType.name()] = categoryElement;
this._insertInPresentationOrder(this, categoryElement);
}
var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
this._insertInPresentationOrder(categoryElement, resourceTreeElement);
this._treeElementForResource[resource.url] = resourceTreeElement;
},
/**
* @param {string} url
* @return {?WebInspector.Resource}
*/
resourceByURL: function(url)
{
var treeElement = this._treeElementForResource[url];
return treeElement ? treeElement._resource : null;
},
appendChild: function(treeElement)
{
this._insertInPresentationOrder(this, treeElement);
},
_insertInPresentationOrder: function(parentTreeElement, childTreeElement)
{
// Insert in the alphabetical order, first frames, then resources. Document resource goes last.
function typeWeight(treeElement)
{
if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
return 2;
if (treeElement instanceof WebInspector.FrameTreeElement)
return 1;
return 3;
}
function compare(treeElement1, treeElement2)
{
var typeWeight1 = typeWeight(treeElement1);
var typeWeight2 = typeWeight(treeElement2);
var result;
if (typeWeight1 > typeWeight2)
result = 1;
else if (typeWeight1 < typeWeight2)
result = -1;
else {
var title1 = treeElement1.displayName || treeElement1.titleText;
var title2 = treeElement2.displayName || treeElement2.titleText;
result = title1.localeCompare(title2);
}
return result;
}
var childCount = parentTreeElement.childCount();
var i;
for (i = 0; i < childCount; ++i) {
if (compare(childTreeElement, parentTreeElement.childAt(i)) < 0)
break;
}
parentTreeElement.insertChild(childTreeElement, i);
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.Resource} resource
*/
WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.resourceType().name()]);
/** @type {!WebInspector.Resource} */
this._resource = resource;
this.tooltip = resource.url;
this._resource[WebInspector.FrameResourceTreeElement._symbol] = this;
}
WebInspector.FrameResourceTreeElement._symbol = Symbol("treeElement");
WebInspector.FrameResourceTreeElement.prototype = {
get itemURL()
{
return this._resource.url;
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel._showResourceView(this._resource);
return false;
},
/**
* @override
* @return {boolean}
*/
ondblclick: function(event)
{
InspectorFrontendHost.openInNewTab(this._resource.url);
return false;
},
/**
* @override
*/
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
if (this._resource.resourceType() === WebInspector.resourceTypes.Image) {
var iconElement = createElementWithClass("div", "icon");
var previewImage = iconElement.createChild("img", "image-resource-icon-preview");
this._resource.populateImageSource(previewImage);
this.listItemElement.replaceChild(iconElement, this.imageElement);
}
this._statusElement = createElementWithClass("div", "status");
this.listItemElement.insertBefore(this._statusElement, this.titleElement);
this.listItemElement.draggable = true;
this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_ondragstart: function(event)
{
event.dataTransfer.setData("text/plain", this._resource.content || "");
event.dataTransfer.effectAllowed = "copy";
return true;
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(this._resource);
contextMenu.show();
},
/**
* @return {!WebInspector.ResourceSourceFrame}
*/
sourceView: function()
{
if (!this._sourceView) {
var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource);
sourceFrame.setHighlighterType(this._resource.canonicalMimeType());
this._sourceView = sourceFrame;
}
return this._sourceView;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.Database} database
*/
WebInspector.DatabaseTreeElement = function(storagePanel, database)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, database.name, ["database-storage-tree-item"], true);
this._database = database;
}
WebInspector.DatabaseTreeElement.prototype = {
get itemURL()
{
return "database://" + encodeURI(this._database.name);
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel._showDatabase(this._database);
return false;
},
/**
* @override
*/
onexpand: function()
{
this._updateChildren();
},
_updateChildren: function()
{
this.removeChildren();
/**
* @param {!Array.<string>} tableNames
* @this {WebInspector.DatabaseTreeElement}
*/
function tableNamesCallback(tableNames)
{
var tableNamesLength = tableNames.length;
for (var i = 0; i < tableNamesLength; ++i)
this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
}
this._database.getTableNames(tableNamesCallback.bind(this));
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
*/
WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, tableName, ["database-table-storage-tree-item"]);
this._database = database;
this._tableName = tableName;
}
WebInspector.DatabaseTableTreeElement.prototype = {
get itemURL()
{
return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel._showDatabase(this._database, this._tableName);
return false;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.StorageCategoryTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
*/
WebInspector.ServiceWorkerCacheTreeElement = function(storagePanel)
{
WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("Cache Storage"), "CacheStorage", ["service-worker-cache-storage-tree-item"]);
}
WebInspector.ServiceWorkerCacheTreeElement.prototype = {
_initialize: function()
{
/** @type {!Array.<!WebInspector.SWCacheTreeElement>} */
this._swCacheTreeElements = [];
var target = this._storagePanel._target;
if (target) {
var model = WebInspector.ServiceWorkerCacheModel.fromTarget(target);
var caches = model.caches();
for (var cache of caches)
this._addCache(model, cache);
}
WebInspector.targetManager.addModelListener(WebInspector.ServiceWorkerCacheModel, WebInspector.ServiceWorkerCacheModel.EventTypes.CacheAdded, this._cacheAdded, this);
WebInspector.targetManager.addModelListener(WebInspector.ServiceWorkerCacheModel, WebInspector.ServiceWorkerCacheModel.EventTypes.CacheRemoved, this._cacheRemoved, this);
},
onattach: function()
{
WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Refresh Caches"), this._refreshCaches.bind(this));
contextMenu.show();
},
_refreshCaches: function()
{
var target = this._storagePanel._target;
if (target) {
var model = WebInspector.ServiceWorkerCacheModel.fromTarget(target);
model.refreshCacheNames();
}
},
/**
* @param {!WebInspector.Event} event
*/
_cacheAdded: function(event)
{
var cache = /** @type {!WebInspector.ServiceWorkerCacheModel.Cache} */ (event.data);
var model = /** @type {!WebInspector.ServiceWorkerCacheModel} */ (event.target);
this._addCache(model, cache);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel} model
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
_addCache: function(model, cache)
{
var swCacheTreeElement = new WebInspector.SWCacheTreeElement(this._storagePanel, model, cache);
this._swCacheTreeElements.push(swCacheTreeElement);
this.appendChild(swCacheTreeElement);
},
/**
* @param {!WebInspector.Event} event
*/
_cacheRemoved: function(event)
{
var cache = /** @type {!WebInspector.ServiceWorkerCacheModel.Cache} */ (event.data);
var model = /** @type {!WebInspector.ServiceWorkerCacheModel} */ (event.target);
var swCacheTreeElement = this._cacheTreeElement(model, cache);
if (!swCacheTreeElement)
return;
swCacheTreeElement.clear();
this.removeChild(swCacheTreeElement);
this._swCacheTreeElements.remove(swCacheTreeElement);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel} model
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @return {?WebInspector.SWCacheTreeElement}
*/
_cacheTreeElement: function(model, cache)
{
var index = -1;
for (var i = 0; i < this._swCacheTreeElements.length; ++i) {
if (this._swCacheTreeElements[i]._cache.equals(cache) && this._swCacheTreeElements[i]._model === model) {
index = i;
break;
}
}
if (index !== -1)
return this._swCacheTreeElements[i];
return null;
},
__proto__: WebInspector.StorageCategoryTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.ServiceWorkerCacheModel} model
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
WebInspector.SWCacheTreeElement = function(storagePanel, model, cache)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, cache.cacheName + " - " + cache.securityOrigin, ["service-worker-cache-tree-item"]);
this._model = model;
this._cache = cache;
}
WebInspector.SWCacheTreeElement.prototype = {
get itemURL()
{
// I don't think this will work at all.
return "cache://" + this._cache.cacheId;
},
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Delete"), this._clearCache.bind(this));
contextMenu.show();
},
_clearCache: function()
{
this._model.deleteCache(this._cache);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
update: function(cache)
{
this._cache = cache;
if (this._view)
this._view.update(cache);
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
if (!this._view)
this._view = new WebInspector.ServiceWorkerCacheView(this._model, this._cache);
this._storagePanel.showServiceWorkerCache(this._view);
return false;
},
clear: function()
{
if (this._view)
this._view.clear();
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.StorageCategoryTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
*/
WebInspector.ServiceWorkersTreeElement = function(storagePanel)
{
WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("Service Workers"), "Service Workers", ["service-workers-tree-item"]);
}
WebInspector.ServiceWorkersTreeElement.prototype = {
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.StorageCategoryTreeElement.prototype.onselect.call(this, selectedByUser);
if (!this._view)
this._view = new WebInspector.ServiceWorkersView();
this._storagePanel.showServiceWorkersView(this._view);
return false;
},
__proto__: WebInspector.StorageCategoryTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.StorageCategoryTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
*/
WebInspector.IndexedDBTreeElement = function(storagePanel)
{
WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]);
}
WebInspector.IndexedDBTreeElement.prototype = {
_initialize: function()
{
WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this);
/** @type {!Array.<!WebInspector.IDBDatabaseTreeElement>} */
this._idbDatabaseTreeElements = [];
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i) {
var indexedDBModel = WebInspector.IndexedDBModel.fromTarget(targets[i]);
var databases = indexedDBModel.databases();
for (var j = 0; j < databases.length; ++j)
this._addIndexedDB(indexedDBModel, databases[j]);
}
},
onattach: function()
{
WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this));
contextMenu.show();
},
refreshIndexedDB: function()
{
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i)
WebInspector.IndexedDBModel.fromTarget(targets[i]).refreshDatabaseNames();
},
/**
* @param {!WebInspector.Event} event
*/
_indexedDBAdded: function(event)
{
var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
this._addIndexedDB(model, databaseId);
},
/**
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
*/
_addIndexedDB: function(model, databaseId)
{
var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, model, databaseId);
this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
this.appendChild(idbDatabaseTreeElement);
model.refreshDatabase(databaseId);
},
/**
* @param {!WebInspector.Event} event
*/
_indexedDBRemoved: function(event)
{
var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId)
if (!idbDatabaseTreeElement)
return;
idbDatabaseTreeElement.clear();
this.removeChild(idbDatabaseTreeElement);
this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
},
/**
* @param {!WebInspector.Event} event
*/
_indexedDBLoaded: function(event)
{
var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data);
var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId);
if (!idbDatabaseTreeElement)
return;
idbDatabaseTreeElement.update(database);
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {!WebInspector.IndexedDBModel} model
* @return {?WebInspector.IDBDatabaseTreeElement}
*/
_idbDatabaseTreeElement: function(model, databaseId)
{
var index = -1;
for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) && this._idbDatabaseTreeElements[i]._model === model) {
index = i;
break;
}
}
if (index !== -1)
return this._idbDatabaseTreeElements[i];
return null;
},
__proto__: WebInspector.StorageCategoryTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
*/
WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]);
this._model = model;
this._databaseId = databaseId;
this._idbObjectStoreTreeElements = {};
}
WebInspector.IDBDatabaseTreeElement.prototype = {
get itemURL()
{
return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name;
},
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this));
contextMenu.show();
},
_refreshIndexedDB: function()
{
this._model.refreshDatabaseNames();
},
/**
* @param {!WebInspector.IndexedDBModel.Database} database
*/
update: function(database)
{
this._database = database;
var objectStoreNames = {};
for (var objectStoreName in this._database.objectStores) {
var objectStore = this._database.objectStores[objectStoreName];
objectStoreNames[objectStore.name] = true;
if (!this._idbObjectStoreTreeElements[objectStore.name]) {
var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
this.appendChild(idbObjectStoreTreeElement);
}
this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);
}
for (var objectStoreName in this._idbObjectStoreTreeElements) {
if (!objectStoreNames[objectStoreName])
this._objectStoreRemoved(objectStoreName);
}
if (this._view)
this._view.update(database);
this._updateTooltip();
},
_updateTooltip: function()
{
this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version;
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
if (!this._view)
this._view = new WebInspector.IDBDatabaseView(this._database);
this._storagePanel.showIndexedDB(this._view);
return false;
},
/**
* @param {string} objectStoreName
*/
_objectStoreRemoved: function(objectStoreName)
{
var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
objectStoreTreeElement.clear();
this.removeChild(objectStoreTreeElement);
delete this._idbObjectStoreTreeElements[objectStoreName];
},
clear: function()
{
for (var objectStoreName in this._idbObjectStoreTreeElements)
this._objectStoreRemoved(objectStoreName);
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
*/
WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, objectStore.name, ["indexed-db-object-store-storage-tree-item"]);
this._model = model;
this._databaseId = databaseId;
this._idbIndexTreeElements = {};
}
WebInspector.IDBObjectStoreTreeElement.prototype = {
get itemURL()
{
return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name;
},
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this));
contextMenu.show();
},
_clearObjectStore: function()
{
/**
* @this {WebInspector.IDBObjectStoreTreeElement}
*/
function callback() {
this.update(this._objectStore);
}
this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this));
},
/**
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
*/
update: function(objectStore)
{
this._objectStore = objectStore;
var indexNames = {};
for (var indexName in this._objectStore.indexes) {
var index = this._objectStore.indexes[indexName];
indexNames[index.name] = true;
if (!this._idbIndexTreeElements[index.name]) {
var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index);
this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
this.appendChild(idbIndexTreeElement);
}
this._idbIndexTreeElements[index.name].update(index);
}
for (var indexName in this._idbIndexTreeElements) {
if (!indexNames[indexName])
this._indexRemoved(indexName);
}
for (var indexName in this._idbIndexTreeElements) {
if (!indexNames[indexName]) {
this.removeChild(this._idbIndexTreeElements[indexName]);
delete this._idbIndexTreeElements[indexName];
}
}
if (this.childCount())
this.expand();
if (this._view)
this._view.update(this._objectStore);
this._updateTooltip();
},
_updateTooltip: function()
{
var keyPathString = this._objectStore.keyPathString;
var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : "";
if (this._objectStore.autoIncrement)
tooltipString += "\n" + WebInspector.UIString("autoIncrement");
this.tooltip = tooltipString;
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
if (!this._view)
this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null);
this._storagePanel.showIndexedDB(this._view);
return false;
},
/**
* @param {string} indexName
*/
_indexRemoved: function(indexName)
{
var indexTreeElement = this._idbIndexTreeElements[indexName];
indexTreeElement.clear();
this.removeChild(indexTreeElement);
delete this._idbIndexTreeElements[indexName];
},
clear: function()
{
for (var indexName in this._idbIndexTreeElements)
this._indexRemoved(indexName);
if (this._view)
this._view.clear();
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
* @param {!WebInspector.IndexedDBModel.Index} index
*/
WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, index.name, ["indexed-db-index-storage-tree-item"]);
this._model = model;
this._databaseId = databaseId;
this._objectStore = objectStore;
this._index = index;
}
WebInspector.IDBIndexTreeElement.prototype = {
get itemURL()
{
return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name;
},
/**
* @param {!WebInspector.IndexedDBModel.Index} index
*/
update: function(index)
{
this._index = index;
if (this._view)
this._view.update(this._index);
this._updateTooltip();
},
_updateTooltip: function()
{
var tooltipLines = [];
var keyPathString = this._index.keyPathString;
tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString);
if (this._index.unique)
tooltipLines.push(WebInspector.UIString("unique"));
if (this._index.multiEntry)
tooltipLines.push(WebInspector.UIString("multiEntry"));
this.tooltip = tooltipLines.join("\n");
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
if (!this._view)
this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
this._storagePanel.showIndexedDB(this._view);
return false;
},
clear: function()
{
if (this._view)
this._view.clear();
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
*/
WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]);
this._domStorage = domStorage;
}
WebInspector.DOMStorageTreeElement.prototype = {
get itemURL()
{
return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel._showDOMStorage(this._domStorage);
return false;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
*/
WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]);
this._cookieDomain = cookieDomain;
}
WebInspector.CookieTreeElement.prototype = {
get itemURL()
{
return "cookies://" + this._cookieDomain;
},
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},
/**
* @param {!Event} event
*/
_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this));
contextMenu.show();
},
/**
* @param {string} domain
*/
_clearCookies: function(domain)
{
this._storagePanel.clearCookies(this._cookieDomain);
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel.showCookies(this, this._cookieDomain);
return false;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
*/
WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL)
{
var title = new WebInspector.ParsedURL(manifestURL).displayName;
WebInspector.BaseStorageTreeElement.call(this, storagePanel, title, ["application-cache-storage-tree-item"]);
this.tooltip = manifestURL;
this._manifestURL = manifestURL;
}
WebInspector.ApplicationCacheManifestTreeElement.prototype = {
get itemURL()
{
return "appcache://" + this._manifestURL;
},
get manifestURL()
{
return this._manifestURL;
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel.showCategoryView(this._manifestURL);
return false;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
* @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!PageAgent.FrameId} frameId
* @param {string} manifestURL
*/
WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, "", ["frame-storage-tree-item"]);
this._frameId = frameId;
this._manifestURL = manifestURL;
this._refreshTitles();
}
WebInspector.ApplicationCacheFrameTreeElement.prototype = {
get itemURL()
{
return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName);
},
get frameId()
{
return this._frameId;
},
get manifestURL()
{
return this._manifestURL;
},
_refreshTitles: function()
{
var frame = this._storagePanel._target.resourceTreeModel.frameForId(this._frameId);
if (!frame) {
this.subtitleText = WebInspector.UIString("new frame");
return;
}
this.titleText = frame.name;
this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
},
frameNavigated: function()
{
this._refreshTitles();
},
/**
* @override
* @return {boolean}
*/
onselect: function(selectedByUser)
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
this._storagePanel.showApplicationCache(this._frameId);
return false;
},
__proto__: WebInspector.BaseStorageTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.StorageCategoryView = function()
{
WebInspector.VBox.call(this);
this.element.classList.add("storage-view");
this._emptyWidget = new WebInspector.EmptyWidget("");
this._emptyWidget.show(this.element);
}
WebInspector.StorageCategoryView.prototype = {
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [];
},
setText: function(text)
{
this._emptyWidget.text = text;
},
__proto__: WebInspector.VBox.prototype
}
WebInspector.ResourcesPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.ResourcesPanel._instance());
}
/**
* @return {!WebInspector.ResourcesPanel}
*/
WebInspector.ResourcesPanel._instance = function()
{
if (!WebInspector.ResourcesPanel._instanceObject)
WebInspector.ResourcesPanel._instanceObject = new WebInspector.ResourcesPanel();
return WebInspector.ResourcesPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.ResourcesPanelFactory = function()
{
}
WebInspector.ResourcesPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.ResourcesPanel._instance();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerCacheModel} model
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
WebInspector.ServiceWorkerCacheView = function(model, cache)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("resources/serviceWorkerCacheViews.css");
this._model = model;
this.element.classList.add("service-worker-cache-data-view");
this.element.classList.add("storage-view");
this._createEditorToolbar();
this._refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this._pageSize = 50;
this._skipCount = 0;
this.update(cache);
this._entries = [];
}
WebInspector.ServiceWorkerCacheView.prototype = {
/**
* @return {!WebInspector.DataGrid}
*/
_createDataGrid: function()
{
var columns = [];
columns.push({id: "number", title: WebInspector.UIString("#"), width: "50px"});
columns.push({id: "request", title: WebInspector.UIString("Request")});
columns.push({id: "response", title: WebInspector.UIString("Response")});
var dataGrid = new WebInspector.DataGrid(columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true));
return dataGrid;
},
_createEditorToolbar: function()
{
var editorToolbar = new WebInspector.Toolbar("data-view-toolbar", this.element);
this._pageBackButton = new WebInspector.ToolbarButton(WebInspector.UIString("Show previous page"), "play-backwards-toolbar-item");
this._pageBackButton.addEventListener("click", this._pageBackButtonClicked, this);
editorToolbar.appendToolbarItem(this._pageBackButton);
this._pageForwardButton = new WebInspector.ToolbarButton(WebInspector.UIString("Show next page"), "play-toolbar-item");
this._pageForwardButton.setEnabled(false);
this._pageForwardButton.addEventListener("click", this._pageForwardButtonClicked, this);
editorToolbar.appendToolbarItem(this._pageForwardButton);
},
_pageBackButtonClicked: function()
{
this._skipCount = Math.max(0, this._skipCount - this._pageSize);
this._updateData(false);
},
_pageForwardButtonClicked: function()
{
this._skipCount = this._skipCount + this._pageSize;
this._updateData(false);
},
/**
* @param {!WebInspector.DataGridNode} node
*/
_deleteButtonClicked: function(node)
{
this._model.deleteCacheEntry(this._cache, node.data["request"], node.remove.bind(node));
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
update: function(cache)
{
this._cache = cache;
if (this._dataGrid)
this._dataGrid.asWidget().detach();
this._dataGrid = this._createDataGrid();
this._dataGrid.asWidget().show(this.element);
this._skipCount = 0;
this._updateData(true);
},
/**
* @param {number} skipCount
* @param {!Array.<!WebInspector.ServiceWorkerCacheModel.Entry>} entries
* @param {boolean} hasMore
* @this {WebInspector.ServiceWorkerCacheView}
*/
_updateDataCallback(skipCount, entries, hasMore)
{
this._refreshButton.setEnabled(true);
this.clear();
this._entries = entries;
for (var i = 0; i < entries.length; ++i) {
var data = {};
data["number"] = i + skipCount;
data["request"] = entries[i].request;
data["response"] = entries[i].response;
var node = new WebInspector.DataGridNode(data);
node.selectable = true;
this._dataGrid.rootNode().appendChild(node);
}
this._pageBackButton.setEnabled(!!skipCount);
this._pageForwardButton.setEnabled(hasMore);
},
/**
* @param {boolean} force
*/
_updateData: function(force)
{
var pageSize = this._pageSize;
var skipCount = this._skipCount;
this._refreshButton.setEnabled(false);
if (!force && this._lastPageSize === pageSize && this._lastSkipCount === skipCount)
return;
if (this._lastPageSize !== pageSize) {
skipCount = 0;
this._skipCount = 0;
}
this._lastPageSize = pageSize;
this._lastSkipCount = skipCount;
this._model.loadCacheData(this._cache, skipCount, pageSize, this._updateDataCallback.bind(this, skipCount));
},
_refreshButtonClicked: function(event)
{
this._updateData(true);
},
/**
* @return {!Array.<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._refreshButton];
},
clear: function()
{
this._dataGrid.rootNode().removeChildren();
this._entries = [];
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.ServiceWorkersView = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("resources/serviceWorkersView.css");
this.contentElement.classList.add("service-workers-view");
/** @type {boolean} */
this._showAll = false;
/** @type {!Set.<string>} */
this._securityOriginHosts = new Set();
/** @type {!Map.<string, !WebInspector.ServiceWorkerOriginWidget>} */
this._originHostToOriginWidgetMap = new Map();
/** @type {!Map.<string, !WebInspector.ServiceWorkerOriginWidget>} */
this._registrationIdToOriginWidgetMap = new Map();
this._toolbar = new WebInspector.Toolbar("", this.contentElement);
this._root = this.contentElement.createChild("div");
this._root.classList.add("service-workers-root");
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ServiceWorkersView.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (this._target)
return;
this._target = target;
this._manager = this._target.serviceWorkerManager;
var forceUpdate = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Update on reload"), WebInspector.UIString("Update Service Worker on page reload"), this._manager.forceUpdateOnReloadSetting());
this._toolbar.appendToolbarItem(forceUpdate);
this._showAllCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Show all"), WebInspector.UIString("Show all Service Workers"));
this._showAllCheckbox.inputElement.addEventListener("change", this._onShowAllCheckboxChanged.bind(this), false);
this._toolbar.appendToolbarItem(this._showAllCheckbox);
for (var registration of this._manager.registrations().values())
this._updateRegistration(registration);
this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationUpdated, this);
this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationDeleted, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
var securityOrigins = this._target.resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (target !== this._target)
return;
delete this._target;
},
/**
* @param {!Event} event
*/
_onShowAllCheckboxChanged: function(event)
{
this._showAll = this._showAllCheckbox.checked();
if (this._showAll) {
for (var originWidget of this._originHostToOriginWidgetMap.values()) {
if (!originWidget.parentWidget())
originWidget.show(this._root);
}
} else {
for (var originWidget of this._originHostToOriginWidgetMap.values()) {
if (originWidget.parentWidget() && !this._securityOriginHosts.has(originWidget._originHost))
originWidget.detach();
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_registrationUpdated: function(event)
{
var registration = /** @type {!WebInspector.ServiceWorkerRegistration} */ (event.data);
this._updateRegistration(registration);
},
/**
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
_updateRegistration: function(registration)
{
var parsedURL = registration.scopeURL.asParsedURL();
if (!parsedURL)
return;
var originHost = parsedURL.host;
var originWidget = this._originHostToOriginWidgetMap.get(originHost);
if (!originWidget) {
originWidget = new WebInspector.ServiceWorkerOriginWidget(this._manager, originHost);
if (this._securityOriginHosts.has(originHost) || this._showAll)
originWidget.show(this._root);
this._originHostToOriginWidgetMap.set(originHost, originWidget);
}
this._registrationIdToOriginWidgetMap.set(registration.id, originWidget);
originWidget._updateRegistration(registration);
},
/**
* @param {!WebInspector.Event} event
*/
_registrationDeleted: function(event)
{
var registration = /** @type {!WebInspector.ServiceWorkerRegistration} */ (event.data);
var registrationId = registration.id;
var originWidget = this._registrationIdToOriginWidgetMap.get(registrationId);
if (!originWidget)
return;
this._registrationIdToOriginWidgetMap.delete(registrationId);
originWidget._deleteRegistration(registrationId);
if (originWidget._hasRegistration())
return;
if (originWidget.parentWidget())
originWidget.detach();
this._originHostToOriginWidgetMap.delete(originWidget._originHost);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginAdded: function(event)
{
this._addOrigin(/** @type {string} */ (event.data));
},
/**
* @param {string} securityOrigin
*/
_addOrigin: function(securityOrigin)
{
var parsedURL = securityOrigin.asParsedURL();
if (!parsedURL)
return;
var originHost = parsedURL.host;
if (this._securityOriginHosts.has(originHost))
return;
this._securityOriginHosts.add(originHost);
var originWidget = this._originHostToOriginWidgetMap.get(originHost);
if (!originWidget)
return;
originWidget.show(this._root);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginRemoved: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
var parsedURL = securityOrigin.asParsedURL();
if (!parsedURL)
return;
var originHost = parsedURL.host;
if (!this._securityOriginHosts.has(originHost))
return;
this._securityOriginHosts.delete(originHost);
if (this._showAll)
return;
var originWidget = this._originHostToOriginWidgetMap.get(originHost);
if (!originWidget)
return;
originWidget.detach();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {string} originHost
*/
WebInspector.ServiceWorkerOriginWidget = function(manager, originHost)
{
WebInspector.VBox.call(this);
this._manager = manager;
/** @type {!Map.<string, !WebInspector.SWRegistrationWidget>} */
this._registrationWidgets = new Map();
this._originHost = originHost;
this.element.classList.add("service-workers-origin");
this._titleElement = this.element.createChild("span", "service-workers-origin-title");
}
WebInspector.ServiceWorkerOriginWidget.prototype = {
/**
* @return {boolean}
*/
_hasRegistration: function()
{
return this._registrationWidgets.size != 0;
},
/**
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
_updateRegistration: function(registration)
{
this._titleElement.setTextAndTitle(WebInspector.UIString(registration.isDeleted ? "%s%s - deleted" : "%s%s", this._originHost, registration.scopeURL.asParsedURL().path));
var registrationWidget = this._registrationWidgets.get(registration.id);
if (registrationWidget) {
registrationWidget._updateRegistration(registration);
return;
}
registrationWidget = new WebInspector.SWRegistrationWidget(this._manager, this, registration);
this._registrationWidgets.set(registration.id, registrationWidget);
registrationWidget.show(this.element);
},
/**
* @param {string} registrationId
*/
_deleteRegistration: function(registrationId)
{
var registrationWidget = this._registrationWidgets.get(registrationId);
if (!registrationWidget)
return;
this._registrationWidgets.delete(registrationId);
registrationWidget.detach();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {!WebInspector.ServiceWorkerOriginWidget} originWidget
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
WebInspector.SWRegistrationWidget = function(manager, originWidget, registration)
{
WebInspector.VBox.call(this);
this._manager = manager;
this._originWidget = originWidget;
this._registration = registration;
this.element.classList.add("service-workers-registration");
var toolbar = new WebInspector.Toolbar("", this.element);
this._updateButton = new WebInspector.ToolbarButton(WebInspector.UIString("Update"), "refresh-toolbar-item", WebInspector.UIString("Update"));
this._updateButton.addEventListener("click", this._updateButtonClicked.bind(this));
toolbar.appendToolbarItem(this._updateButton);
toolbar.appendSeparator();
this._pushButton = new WebInspector.ToolbarButton(WebInspector.UIString("Emulate push event"), "notification-toolbar-item", WebInspector.UIString("Push"));
this._pushButton.addEventListener("click", this._pushButtonClicked.bind(this));
toolbar.appendToolbarItem(this._pushButton);
toolbar.appendSpacer();
this._deleteButton = new WebInspector.ToolbarButton(WebInspector.UIString("Delete"), "garbage-collect-toolbar-item", WebInspector.UIString("Delete"));
this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this));
toolbar.appendToolbarItem(this._deleteButton);
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
var modes = WebInspector.ServiceWorkerVersion.Modes;
this._tabbedPane.appendTab(modes.Installing, WebInspector.UIString("Installing"), new WebInspector.VBox());
this._tabbedPane.appendTab(modes.Waiting, WebInspector.UIString("Waiting"), new WebInspector.VBox());
this._tabbedPane.appendTab(modes.Active, WebInspector.UIString("Active"), new WebInspector.VBox());
this._tabbedPane.appendTab(modes.Redundant, WebInspector.UIString("Redundant"), new WebInspector.VBox());
this._tabbedPane.show(this.element);
/** @type {!Map<string, !WebInspector.SWVersionWidget>} */
this._versionWidgets = new Map();
this._updateRegistration(registration);
}
WebInspector.SWRegistrationWidget.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_tabSelected: function(event)
{
if (event.data["isUserGesture"])
this._lastManuallySelectedTab = event.data["tabId"];
},
/**
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
_updateRegistration: function(registration)
{
this._registration = registration;
this._updateButton.setEnabled(!registration.isDeleted);
this._deleteButton.setEnabled(!registration.isDeleted);
/** @type {!Map<string, !WebInspector.SWVersionWidget>} */
var versionWidgets = new Map();
// Remove all the redundant workers that are older than the
// active version.
var versions = registration.versions.valuesArray();
var activeVersion = versions.find(version => version.mode() === WebInspector.ServiceWorkerVersion.Modes.Active);
if (activeVersion) {
versions = versions.filter(version => {
if (version.mode() == WebInspector.ServiceWorkerVersion.Modes.Redundant)
return version.scriptLastModified > activeVersion.scriptLastModified;
return true;
});
}
var firstMode;
var modesWithVersions = new Set();
for (var version of versions) {
if (version.isStoppedAndRedundant() && !version.errorMessages.length)
continue;
var mode = version.mode();
if (!firstMode)
firstMode = mode;
modesWithVersions.add(mode);
var view = this._tabbedPane.tabView(mode);
var versionWidget = this._versionWidgets.get(version.id);
if (versionWidget)
versionWidget._updateVersion(version);
else
versionWidget = new WebInspector.SWVersionWidget(this._manager, this._registration.scopeURL, version);
versionWidget.show(view.element, view.element.firstElementChild);
versionWidgets.set(version.id, versionWidget);
}
for (var id of this._versionWidgets.keys()) {
if (!versionWidgets.has(id))
this._versionWidgets.get(id).detach();
}
this._versionWidgets = versionWidgets;
for (var id of this._tabbedPane.tabIds())
this._tabbedPane.setTabEnabled(id, modesWithVersions.has(id));
this._pushButton.setEnabled(modesWithVersions.has(WebInspector.ServiceWorkerVersion.Modes.Active) && !this._registration.isDeleted);
if (modesWithVersions.has(this._lastManuallySelectedTab)) {
this._tabbedPane.selectTab(this._lastManuallySelectedTab);
return;
}
if (activeVersion) {
this._tabbedPane.selectTab(WebInspector.ServiceWorkerVersion.Modes.Active);
return;
}
if (firstMode)
this._tabbedPane.selectTab(firstMode);
},
/**
* @param {!WebInspector.Event} event
*/
_deleteButtonClicked: function(event)
{
this._manager.deleteRegistration(this._registration.id);
},
/**
* @param {!WebInspector.Event} event
*/
_updateButtonClicked: function(event)
{
this._manager.updateRegistration(this._registration.id);
},
/**
* @param {!WebInspector.Event} event
*/
_pushButtonClicked: function(event)
{
var data = "Test push message from DevTools."
this._manager.deliverPushMessage(this._registration.id, data);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {string} scopeURL
* @param {!WebInspector.ServiceWorkerVersion} version
*/
WebInspector.SWVersionWidget = function(manager, scopeURL, version)
{
WebInspector.VBox.call(this);
this._manager = manager;
this._scopeURL = scopeURL;
this._version = version;
this.element.classList.add("service-workers-version", "flex-none");
/**
* @type {!Object.<string, !WebInspector.TargetInfo>}
*/
this._clientInfoCache = {};
this._createElements();
this._updateVersion(version);
}
WebInspector.SWVersionWidget.prototype = {
_createElements: function()
{
var panel = createElementWithClass("div", "service-workers-versions-panel");
var leftPanel = panel.createChild("div", "service-workers-versions-panel-left");
var rightPanel = panel.createChild("div", "service-workers-versions-panel-right");
this._stateCell = this._addTableRow(leftPanel, WebInspector.UIString("State"));
this._workerCell = this._addTableRow(leftPanel, WebInspector.UIString("Worker"));
this._scriptCell = this._addTableRow(leftPanel, WebInspector.UIString("Script URL"));
this._updatedCell = this._addTableRow(leftPanel, WebInspector.UIString("Updated"));
this._updatedCell.classList.add("service-worker-script-response-time");
this._scriptLastModifiedCell = this._addTableRow(leftPanel, WebInspector.UIString("Last-Modified"));
this._scriptLastModifiedCell.classList.add("service-worker-script-last-modified");
rightPanel.createChild("div", "service-workers-versions-table-messages-title").createTextChild(WebInspector.UIString("Recent messages"));
this._messagesPanel = rightPanel.createChild("div", "service-workers-versions-table-messages-content");
this._clientsTitle = rightPanel.createChild("div", "service-workers-versions-table-clients-title");
this._clientsTitle.createTextChild(WebInspector.UIString("Controlled clients"));
this._clientsPanel = rightPanel.createChild("div", "service-workers-versions-table-clients-content");
this.element.appendChild(panel);
},
/**
* @param {!WebInspector.ServiceWorkerVersion} version
*/
_updateVersion: function(version)
{
this._stateCell.setTextAndTitle(version.status);
this._workerCell.removeChildren();
if (version.isRunning() || version.isStarting() || version.isStartable()) {
var runningStatusCell = this._workerCell.createChild("div", "service-workers-versions-table-worker-running-status-cell");
var runningStatusLeftCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-left-cell");
var runningStatusRightCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-right-cell");
if (version.isRunning() || version.isStarting()) {
var toolbar = new WebInspector.Toolbar("", runningStatusLeftCell);
var stopButton = new WebInspector.ToolbarButton(WebInspector.UIString("Stop"), "stop-toolbar-item");
stopButton.addEventListener("click", this._stopButtonClicked.bind(this, version.id));
toolbar.appendToolbarItem(stopButton);
} else if (version.isStartable()) {
var toolbar = new WebInspector.Toolbar("", runningStatusLeftCell);
var startButton = new WebInspector.ToolbarButton(WebInspector.UIString("Start"), "play-toolbar-item");
startButton.addEventListener("click", this._startButtonClicked.bind(this));
toolbar.appendToolbarItem(startButton);
}
runningStatusRightCell.setTextAndTitle(version.runningStatus);
if (version.isRunning() || version.isStarting()) {
var inspectButton = runningStatusRightCell.createChild("div", "service-workers-versions-table-running-status-inspect");
inspectButton.setTextAndTitle(WebInspector.UIString("inspect"));
inspectButton.addEventListener("click", this._inspectButtonClicked.bind(this, version.id), false);
}
} else {
this._workerCell.setTextAndTitle(version.runningStatus);
}
this._scriptCell.setTextAndTitle(version.scriptURL.asParsedURL().path);
this._updatedCell.setTextAndTitle(version.scriptResponseTime ? (new Date(version.scriptResponseTime * 1000)).toConsoleTime() : '');
this._scriptLastModifiedCell.setTextAndTitle(version.scriptLastModified ? (new Date(version.scriptLastModified * 1000)).toConsoleTime() : '');
this._messagesPanel.removeChildren();
if (version.scriptLastModified) {
var scriptLastModifiedLabel = this._messagesPanel.createChild("label", " service-workers-info service-worker-script-last-modified", "dt-icon-label");
scriptLastModifiedLabel.type = "info-icon";
scriptLastModifiedLabel.createTextChild(WebInspector.UIString("Last-Modified: %s", (new Date(version.scriptLastModified * 1000)).toConsoleTime()));
}
if (version.scriptResponseTime) {
var scriptResponseTimeDiv = this._messagesPanel.createChild("label", " service-workers-info service-worker-script-response-time", "dt-icon-label");
scriptResponseTimeDiv.type = "info-icon";
scriptResponseTimeDiv.createTextChild(WebInspector.UIString("Server response time: %s", (new Date(version.scriptResponseTime * 1000)).toConsoleTime()));
}
var errorMessages = version.errorMessages;
for (var index = 0; index < errorMessages.length; ++index) {
var errorDiv = this._messagesPanel.createChild("div", "service-workers-error");
errorDiv.createChild("label", "", "dt-icon-label").type = "error-icon";
errorDiv.createChild("div", "service-workers-error-message").createTextChild(errorMessages[index].errorMessage);
var script_path = errorMessages[index].sourceURL;
var script_url;
if (script_url = script_path.asParsedURL())
script_path = script_url.displayName;
if (script_path.length && errorMessages[index].lineNumber != -1)
script_path = String.sprintf("(%s:%d)", script_path, errorMessages[index].lineNumber);
errorDiv.createChild("div", "service-workers-error-line").createTextChild(script_path);
}
this._clientsTitle.classList.toggle("hidden", version.controlledClients.length == 0);
this._clientsPanel.removeChildren();
for (var i = 0; i < version.controlledClients.length; ++i) {
var client = version.controlledClients[i];
var clientLabelText = this._clientsPanel.createChild("div", "service-worker-client");
if (this._clientInfoCache[client]) {
this._updateClientInfo(clientLabelText, this._clientInfoCache[client]);
}
this._manager.getTargetInfo(client, this._onClientInfo.bind(this, clientLabelText));
}
},
/**
* @param {!Element} tableElement
* @param {string} title
* @return {!Element}
*/
_addTableRow: function(tableElement, title)
{
var rowElement = tableElement.createChild("div", "service-workers-versions-table-row");
rowElement.createChild("div", "service-workers-versions-table-row-title").setTextAndTitle(title);
return rowElement.createChild("div", "service-workers-versions-table-row-content");
},
/**
* @param {!Element} element
* @param {?WebInspector.TargetInfo} targetInfo
*/
_onClientInfo: function(element, targetInfo)
{
if (!targetInfo)
return;
this._clientInfoCache[targetInfo.id] = targetInfo;
this._updateClientInfo(element, targetInfo);
},
/**
* @param {!Element} element
* @param {!WebInspector.TargetInfo} targetInfo
*/
_updateClientInfo: function(element, targetInfo)
{
if (!(targetInfo.isWebContents() || targetInfo.isFrame())) {
element.createTextChild(WebInspector.UIString("Worker: %s", targetInfo.url));
return;
}
element.removeChildren();
element.createTextChild(WebInspector.UIString("Tab: %s", targetInfo.url));
var focusLabel = element.createChild("label", "service-worker-client-focus");
focusLabel.createTextChild("focus");
focusLabel.addEventListener("click", this._activateTarget.bind(this, targetInfo.id), true);
},
/**
* @param {string} targetId
*/
_activateTarget: function(targetId)
{
this._manager.activateTarget(targetId);
},
/**
* @param {!WebInspector.Event} event
*/
_startButtonClicked: function(event)
{
this._manager.startWorker(this._scopeURL);
},
/**
* @param {string} versionId
* @param {!WebInspector.Event} event
*/
_stopButtonClicked: function(versionId, event)
{
this._manager.stopWorker(versionId);
},
/**
* @param {string} versionId
* @param {!Event} event
*/
_inspectButtonClicked: function(versionId, event)
{
this._manager.inspectWorker(versionId);
},
__proto__: WebInspector.VBox.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ASTService.js | 7.14% | (1 / 14) | 0% | (0 / 2) | 0% | (0 / 4) | 7.69% | (1 / 13) | |
| ASTSourceMap.js | 1.82% | (1 / 55) | 0% | (0 / 22) | 0% | (0 / 17) | 1.85% | (1 / 54) | |
| SASSProcessor.js | 0.87% | (2 / 230) | 0% | (0 / 66) | 0% | (0 / 32) | 0.89% | (2 / 224) | |
| SASSSourceMapFactory.js | 4.55% | (2 / 44) | 0% | (0 / 31) | 0% | (0 / 4) | 4.55% | (2 / 44) | |
| SASSSupport.js | 2.85% | (11 / 386) | 0% | (0 / 176) | 0% | (0 / 46) | 2.86% | (11 / 385) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.ASTService = function() { this._cssParserService = new WebInspector.CSSParserService(); this._sassInitPromise = self.runtime.instancePromise(WebInspector.TokenizerFactory); this._terminated = false; } WebInspector.ASTService.prototype = { /** * @param {string} url * @param {string} text * @return {!Promise<!WebInspector.SASSSupport.AST>} */ parseCSS: function(url, text) { console.assert(!this._terminated, "Illegal call parseCSS on terminated ASTService."); return WebInspector.SASSSupport.parseCSS(this._cssParserService, url, text); }, /** * @param {string} url * @param {string} text * @return {!Promise<!WebInspector.SASSSupport.AST>} */ parseSCSS: function(url, text) { console.assert(!this._terminated, "Illegal call parseSCSS on terminated ASTService."); return this._sassInitPromise.then(tokenizer => WebInspector.SASSSupport.parseSCSS(tokenizer, url, text)); }, dispose: function() { if (this._terminated) return; this._terminated = true; this._cssParserService.dispose(); }, } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.SourceMap}
* @param {string} compiledURL
* @param {string} sourceMapURL
* @param {!Map<string, !WebInspector.SASSSupport.AST>} models
* @param {?function(!WebInspector.ASTSourceMap, !Array<!WebInspector.TextRange>, !Array<string>):!Promise<?WebInspector.SourceMap.EditResult>} editCallback
*/
WebInspector.ASTSourceMap = function(compiledURL, sourceMapURL, models, editCallback)
{
this._editCallback = editCallback;
this._compiledURL = compiledURL;
this._sourceMapURL = sourceMapURL;
/** @type {!Map<string, !WebInspector.SASSSupport.AST>} */
this._models = models;
/** @type {!Map<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} */
this._compiledToSource = new Map();
/** @type {!Multimap<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} */
this._sourceToCompiled = new Multimap();
}
WebInspector.ASTSourceMap.prototype = {
/**
* @override
* @return {string}
*/
compiledURL: function()
{
return this._compiledURL;
},
/**
* @override
* @return {string}
*/
url: function()
{
return this._sourceMapURL;
},
/**
* @override
* @return {!Array<string>}
*/
sourceURLs: function()
{
return this._models.keysArray().filter(url => url !== this._compiledURL);
},
/**
* @override
* @param {string} sourceURL
* @param {!WebInspector.ResourceType} contentType
* @return {!WebInspector.ContentProvider}
*/
sourceContentProvider: function(sourceURL, contentType)
{
var model = this.modelForURL(sourceURL);
var sourceContent = model ? model.document.text.value() : "";
return new WebInspector.StaticContentProvider(contentType, sourceContent);
},
/**
* @override
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {?WebInspector.SourceMapEntry}
*/
findEntry: function(lineNumber, columnNumber)
{
columnNumber = columnNumber || 0;
var compiledNode = this.compiledModel().findNodeForPosition(lineNumber, columnNumber);
if (!compiledNode)
return null;
var sourceNode = this.toSourceNode(compiledNode);
if (!sourceNode)
return null;
return new WebInspector.SourceMapEntry(lineNumber, columnNumber, sourceNode.document.url, sourceNode.range.startLine, sourceNode.range.startColumn);
},
/**
* @override
* @return {boolean}
*/
editable: function()
{
return !!this._editCallback;
},
/**
* @override
* @param {!Array<!WebInspector.TextRange>} ranges
* @param {!Array<string>} texts
* @return {!Promise<?WebInspector.SourceMap.EditResult>}
*/
editCompiled: function(ranges, texts)
{
return this._editCallback.call(null, this, ranges, texts);
},
/**
* @return {!WebInspector.SASSSupport.AST}
*/
compiledModel: function()
{
return /** @type {!WebInspector.SASSSupport.AST} */(this._models.get(this._compiledURL));
},
/**
* @return {!Map<string, !WebInspector.SASSSupport.AST>}
*/
sourceModels: function()
{
var sourceModels = /** @type {!Map<string, !WebInspector.SASSSupport.AST>} */(new Map(this._models));
sourceModels.delete(this._compiledURL);
return sourceModels;
},
/**
* @return {!Map<string, !WebInspector.SASSSupport.AST>}
*/
models: function()
{
return /** @type {!Map<string, !WebInspector.SASSSupport.AST>} */(new Map(this._models));
},
/**
* @param {string} url
* @return {?WebInspector.SASSSupport.AST}
*/
modelForURL: function(url)
{
return this._models.get(url) || null;
},
/**
* @param {!WebInspector.SASSSupport.TextNode} compiled
* @param {!WebInspector.SASSSupport.TextNode} source
*/
addMapping: function(compiled, source)
{
this._compiledToSource.set(compiled, source);
this._sourceToCompiled.set(source, compiled);
},
/**
* @param {!WebInspector.SASSSupport.TextNode} compiled
* @param {!WebInspector.SASSSupport.TextNode} source
*/
removeMapping: function(compiled, source)
{
this._compiledToSource.delete(compiled);
this._sourceToCompiled.remove(source, compiled);
},
/**
* @param {!WebInspector.SASSSupport.TextNode} compiled
* @return {?WebInspector.SASSSupport.TextNode}
*/
toSourceNode: function(compiled)
{
return this._compiledToSource.get(compiled) || null;
},
/**
* @param {!WebInspector.SASSSupport.TextNode} source
* @return {!Array<!WebInspector.SASSSupport.TextNode>}
*/
toCompiledNodes: function(source)
{
var compiledNodes = this._sourceToCompiled.get(source);
return compiledNodes ? compiledNodes.valuesArray() : [];
},
/**
* @param {!Array<!WebInspector.SASSSupport.AST>} updated
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>=} outNodeMapping
* @return {?WebInspector.ASTSourceMap}
*/
rebase: function(updated, outNodeMapping)
{
outNodeMapping = outNodeMapping || new Map();
outNodeMapping.clear();
var models = /** @type {!Map<string, !WebInspector.SASSSupport.AST>} */(new Map(this._models));
for (var newAST of updated) {
var oldAST = models.get(newAST.document.url);
if (!oldAST.match(newAST, outNodeMapping))
return null;
models.set(newAST.document.url, newAST);
}
var newMap = new WebInspector.ASTSourceMap(this._compiledURL, this._sourceMapURL, models, this._editCallback);
var compiledNodes = this._compiledToSource.keysArray();
for (var i = 0; i < compiledNodes.length; ++i) {
var compiledNode = compiledNodes[i];
var sourceNode = /** @type {!WebInspector.SASSSupport.TextNode} */(this._compiledToSource.get(compiledNode));
var mappedCompiledNode = /** @type {!WebInspector.SASSSupport.TextNode} */(outNodeMapping.get(compiledNode) || compiledNode);
var mappedSourceNode = /** @type {!WebInspector.SASSSupport.TextNode} */(outNodeMapping.get(sourceNode) || sourceNode);
newMap.addMapping(mappedCompiledNode, mappedSourceNode);
}
return newMap;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.ASTService} astService
* @param {!WebInspector.ASTSourceMap} map
* @param {!Array<!WebInspector.SASSProcessor.EditOperation>} editOperations
*/
WebInspector.SASSProcessor = function(astService, map, editOperations)
{
this._astService = astService;
this._map = map;
this._editOperations = editOperations;
}
WebInspector.SASSProcessor.prototype = {
/**
* @return {!Promise<?WebInspector.SourceMap.EditResult>}
*/
_mutate: function()
{
/** @type {!Set<!WebInspector.SASSSupport.Rule>} */
var changedCSSRules = new Set();
for (var editOperation of this._editOperations) {
var rules = editOperation.perform();
changedCSSRules.addAll(rules);
}
// Reparse new texts, make sure changes result in anticipated AST trees.
var promises = [];
for (var ast of this._map.models().values()) {
if (!ast.document.hasChanged())
continue;
var promise;
if (ast.document.url === this._map.compiledURL())
promise = this._astService.parseCSS(ast.document.url, ast.document.newText().value());
else
promise = this._astService.parseSCSS(ast.document.url, ast.document.newText().value());
promises.push(promise);
}
return Promise.all(promises)
.then(this._onFinished.bind(this, changedCSSRules));
},
/**
* @param {!Set<!WebInspector.SASSSupport.Rule>} changedCSSRules
* @param {!Array<!WebInspector.SASSSupport.AST>} changedModels
* @return {?WebInspector.SourceMap.EditResult}
*/
_onFinished: function(changedCSSRules, changedModels)
{
var nodeMapping = new Map();
var map = this._map.rebase(changedModels, nodeMapping);
if (!map)
return null;
var cssEdits = [];
for (var rule of changedCSSRules) {
var oldRange = rule.styleRange;
var newRule = nodeMapping.get(rule);
var newText = newRule.document.text.extract(newRule.styleRange);
cssEdits.push(new WebInspector.SourceEdit(newRule.document.url, oldRange, newText));
}
/** @type {!Map<string, string>} */
var newSASSSources = new Map();
for (var model of changedModels) {
if (model.document.url === map.compiledURL())
continue;
newSASSSources.set(model.document.url, model.document.text.value());
}
return new WebInspector.SourceMap.EditResult(map, cssEdits, newSASSSources);
}
}
/**
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.Property} cssProperty
* @return {?WebInspector.SASSSupport.Property}
*/
WebInspector.SASSProcessor._toSASSProperty = function(map, cssProperty)
{
var sassName = map.toSourceNode(cssProperty.name);
return sassName ? sassName.parent : null;
}
/**
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.Property} sassProperty
* @return {!Array<!WebInspector.SASSSupport.Property>}
*/
WebInspector.SASSProcessor._toCSSProperties = function(map, sassProperty)
{
return map.toCompiledNodes(sassProperty.name).map(name => name.parent);
}
/**
* @param {!WebInspector.ASTService} astService
* @param {!WebInspector.ASTSourceMap} map
* @param {!Array<!WebInspector.TextRange>} ranges
* @param {!Array<string>} newTexts
* @return {!Promise<?WebInspector.SourceMap.EditResult>}
*/
WebInspector.SASSProcessor.processCSSEdits = function(astService, map, ranges, newTexts)
{
console.assert(ranges.length === newTexts.length);
var cssURL = map.compiledURL();
var cssText = map.compiledModel().document.text;
for (var i = 0; i < ranges.length; ++i)
cssText = new WebInspector.Text(cssText.replaceRange(ranges[i], newTexts[i]));
return astService.parseCSS(cssURL, cssText.value())
.then(onCSSParsed);
/**
* @param {!WebInspector.SASSSupport.AST} newCSSAST
* @return {!Promise<?WebInspector.SourceMap.EditResult>}
*/
function onCSSParsed(newCSSAST)
{
if (newCSSAST.rules.length !== map.compiledModel().rules.length)
return Promise.resolve(/** @type {?WebInspector.SourceMap.EditResult} */(null));
//TODO(lushnikov): only diff changed styles.
var cssDiff = WebInspector.SASSSupport.diffModels(map.compiledModel(), newCSSAST);
var edits = WebInspector.SASSProcessor._editsFromCSSDiff(cssDiff, map);
// Determine AST trees which will change and clone them.
var changedURLs = new Set(edits.map(edit => edit.sassURL));
changedURLs.add(map.compiledURL());
var clonedModels = [];
for (var url of changedURLs)
clonedModels.push(map.modelForURL(url).clone());
// Rebase map and edits onto a cloned AST trees.
var nodeMapping = new Map();
var rebasedMap = /** @type {!WebInspector.ASTSourceMap} */(map.rebase(clonedModels, nodeMapping));
console.assert(rebasedMap);
var rebasedEdits = edits.map(edit => edit.rebase(rebasedMap, nodeMapping));
return new WebInspector.SASSProcessor(astService, rebasedMap, rebasedEdits)._mutate();
}
}
/**
* @param {!WebInspector.SASSSupport.ASTDiff} cssDiff
* @param {!WebInspector.ASTSourceMap} map
* @return {!Array<!WebInspector.SASSProcessor.EditOperation>}
*/
WebInspector.SASSProcessor._editsFromCSSDiff = function(cssDiff, map)
{
var T = WebInspector.SASSSupport.PropertyChangeType;
var operations = [];
for (var i = 0; i < cssDiff.changes.length; ++i) {
var change = cssDiff.changes[i];
var operation = null;
if (change.type === T.ValueChanged || change.type === T.NameChanged)
operation = WebInspector.SASSProcessor.SetTextOperation.fromCSSChange(change, map);
else if (change.type === T.PropertyToggled)
operation = WebInspector.SASSProcessor.TogglePropertyOperation.fromCSSChange(change, map);
else if (change.type === T.PropertyRemoved)
operation = WebInspector.SASSProcessor.RemovePropertyOperation.fromCSSChange(change, map);
else if (change.type === T.PropertyAdded)
operation = WebInspector.SASSProcessor.InsertPropertiesOperation.fromCSSChange(change, map);
if (!operation) {
WebInspector.console.error("Operation ignored: " + change.type);
continue;
}
var merged = false;
for (var j = 0; !merged && j < operations.length; ++j)
merged = operations[j].merge(operation);
if (!merged)
operations.push(operation);
}
return operations;
}
/**
* @constructor
* @param {!WebInspector.ASTSourceMap} map
* @param {string} sassURL
*/
WebInspector.SASSProcessor.EditOperation = function(map, sassURL)
{
this.map = map;
this.sassURL = sassURL;
}
WebInspector.SASSProcessor.EditOperation.prototype = {
/**
* @param {!WebInspector.SASSProcessor.EditOperation} other
* @return {boolean}
*/
merge: function(other)
{
return false;
},
/**
* @return {!Array<!WebInspector.SASSSupport.Rule>}
*/
perform: function()
{
return [];
},
/**
* @param {!WebInspector.ASTSourceMap} newMap
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>} nodeMapping
* @return {!WebInspector.SASSProcessor.EditOperation}
*/
rebase: function(newMap, nodeMapping)
{
return this;
},
}
/**
* @constructor
* @extends {WebInspector.SASSProcessor.EditOperation}
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.TextNode} sassNode
* @param {string} newText
*/
WebInspector.SASSProcessor.SetTextOperation = function(map, sassNode, newText)
{
WebInspector.SASSProcessor.EditOperation.call(this, map, sassNode.document.url);
this._sassNode = sassNode;
this._newText = newText;
}
/**
* @param {!WebInspector.SASSSupport.PropertyChange} change
* @param {!WebInspector.ASTSourceMap} map
* @return {?WebInspector.SASSProcessor.SetTextOperation}
*/
WebInspector.SASSProcessor.SetTextOperation.fromCSSChange = function(change, map)
{
var oldProperty = /** @type {!WebInspector.SASSSupport.Property} */(change.oldProperty());
var newProperty = /** @type {!WebInspector.SASSSupport.Property} */(change.newProperty());
console.assert(oldProperty && newProperty, "SetTextOperation must have both oldProperty and newProperty");
var newValue = null;
var sassNode = null;
if (change.type === WebInspector.SASSSupport.PropertyChangeType.NameChanged) {
newValue = newProperty.name.text;
sassNode = map.toSourceNode(oldProperty.name);
} else {
newValue = newProperty.value.text;
sassNode = map.toSourceNode(oldProperty.value);
}
if (!sassNode)
return null;
return new WebInspector.SASSProcessor.SetTextOperation(map, sassNode, newValue);
}
WebInspector.SASSProcessor.SetTextOperation.prototype = {
/**
* @override
* @param {!WebInspector.SASSProcessor.EditOperation} other
* @return {boolean}
*/
merge: function(other)
{
if (!(other instanceof WebInspector.SASSProcessor.SetTextOperation))
return false;
return this._sassNode === other._sassNode;
},
/**
* @override
* @return {!Array<!WebInspector.SASSSupport.Rule>}
*/
perform: function()
{
this._sassNode.setText(this._newText);
var nodes = this.map.toCompiledNodes(this._sassNode);
for (var node of nodes)
node.setText(this._newText);
var cssRules = nodes.map(textNode => textNode.parent.parent);
return cssRules;
},
/**
* @override
* @param {!WebInspector.ASTSourceMap} newMap
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>} nodeMapping
* @return {!WebInspector.SASSProcessor.SetTextOperation}
*/
rebase: function(newMap, nodeMapping)
{
var sassNode = /** @type {?WebInspector.SASSSupport.TextNode} */(nodeMapping.get(this._sassNode)) || this._sassNode;
return new WebInspector.SASSProcessor.SetTextOperation(newMap, sassNode, this._newText);
},
__proto__: WebInspector.SASSProcessor.EditOperation.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSProcessor.EditOperation}
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.Property} sassProperty
* @param {boolean} newDisabled
*/
WebInspector.SASSProcessor.TogglePropertyOperation = function(map, sassProperty, newDisabled)
{
WebInspector.SASSProcessor.EditOperation.call(this, map, sassProperty.document.url);
this._sassProperty = sassProperty;
this._newDisabled = newDisabled;
}
/**
* @param {!WebInspector.SASSSupport.PropertyChange} change
* @param {!WebInspector.ASTSourceMap} map
* @return {?WebInspector.SASSProcessor.TogglePropertyOperation}
*/
WebInspector.SASSProcessor.TogglePropertyOperation.fromCSSChange = function(change, map)
{
var oldCSSProperty = /** @type {!WebInspector.SASSSupport.Property} */(change.oldProperty());
console.assert(oldCSSProperty, "TogglePropertyOperation must have old CSS property");
var sassProperty = WebInspector.SASSProcessor._toSASSProperty(map, oldCSSProperty);
if (!sassProperty)
return null;
var newDisabled = change.newProperty().disabled;
return new WebInspector.SASSProcessor.TogglePropertyOperation(map, sassProperty, newDisabled);
}
WebInspector.SASSProcessor.TogglePropertyOperation.prototype = {
/**
* @override
* @param {!WebInspector.SASSProcessor.EditOperation} other
* @return {boolean}
*/
merge: function(other)
{
if (!(other instanceof WebInspector.SASSProcessor.TogglePropertyOperation))
return false;
return this._sassProperty === other._sassProperty;
},
/**
* @override
* @return {!Array<!WebInspector.SASSSupport.Rule>}
*/
perform: function()
{
this._sassProperty.setDisabled(this._newDisabled);
var cssProperties = WebInspector.SASSProcessor._toCSSProperties(this.map, this._sassProperty);
for (var property of cssProperties)
property.setDisabled(this._newDisabled);
var cssRules = cssProperties.map(property => property.parent);
return cssRules;
},
/**
* @override
* @param {!WebInspector.ASTSourceMap} newMap
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>} nodeMapping
* @return {!WebInspector.SASSProcessor.TogglePropertyOperation}
*/
rebase: function(newMap, nodeMapping)
{
var sassProperty = /** @type {?WebInspector.SASSSupport.Property} */(nodeMapping.get(this._sassProperty)) || this._sassProperty;
return new WebInspector.SASSProcessor.TogglePropertyOperation(newMap, sassProperty, this._newDisabled);
},
__proto__: WebInspector.SASSProcessor.EditOperation.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSProcessor.EditOperation}
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.Property} sassProperty
*/
WebInspector.SASSProcessor.RemovePropertyOperation = function(map, sassProperty)
{
WebInspector.SASSProcessor.EditOperation.call(this, map, sassProperty.document.url);
this._sassProperty = sassProperty;
}
/**
* @param {!WebInspector.SASSSupport.PropertyChange} change
* @param {!WebInspector.ASTSourceMap} map
* @return {?WebInspector.SASSProcessor.RemovePropertyOperation}
*/
WebInspector.SASSProcessor.RemovePropertyOperation.fromCSSChange = function(change, map)
{
var removedProperty = /** @type {!WebInspector.SASSSupport.Property} */(change.oldProperty());
console.assert(removedProperty, "RemovePropertyOperation must have removed CSS property");
var sassProperty = WebInspector.SASSProcessor._toSASSProperty(map, removedProperty);
if (!sassProperty)
return null;
return new WebInspector.SASSProcessor.RemovePropertyOperation(map, sassProperty);
}
WebInspector.SASSProcessor.RemovePropertyOperation.prototype = {
/**
* @override
* @param {!WebInspector.SASSProcessor.EditOperation} other
* @return {boolean}
*/
merge: function(other)
{
if (!(other instanceof WebInspector.SASSProcessor.RemovePropertyOperation))
return false;
return this._sassProperty === other._sassProperty;
},
/**
* @override
* @return {!Array<!WebInspector.SASSSupport.Rule>}
*/
perform: function()
{
var cssProperties = WebInspector.SASSProcessor._toCSSProperties(this.map, this._sassProperty);
var cssRules = cssProperties.map(property => property.parent);
this._sassProperty.remove();
for (var cssProperty of cssProperties) {
cssProperty.remove();
this.map.removeMapping(cssProperty.name, this._sassProperty.name);
this.map.removeMapping(cssProperty.value, this._sassProperty.value);
}
return cssRules;
},
/**
* @override
* @param {!WebInspector.ASTSourceMap} newMap
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>} nodeMapping
* @return {!WebInspector.SASSProcessor.RemovePropertyOperation}
*/
rebase: function(newMap, nodeMapping)
{
var sassProperty = /** @type {?WebInspector.SASSSupport.Property} */(nodeMapping.get(this._sassProperty)) || this._sassProperty;
return new WebInspector.SASSProcessor.RemovePropertyOperation(newMap, sassProperty);
},
__proto__: WebInspector.SASSProcessor.EditOperation.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSProcessor.EditOperation}
* @param {!WebInspector.ASTSourceMap} map
* @param {!WebInspector.SASSSupport.Property} sassAnchor
* @param {boolean} insertBefore
* @param {!Array<string>} propertyNames
* @param {!Array<string>} propertyValues
* @param {!Array<boolean>} disabledStates
*/
WebInspector.SASSProcessor.InsertPropertiesOperation = function(map, sassAnchor, insertBefore, propertyNames, propertyValues, disabledStates)
{
console.assert(propertyNames.length === propertyValues.length && propertyValues.length === disabledStates.length);
WebInspector.SASSProcessor.EditOperation.call(this, map, sassAnchor.document.url);
this._sassAnchor = sassAnchor;
this._insertBefore = insertBefore;
this._nameTexts = propertyNames;
this._valueTexts = propertyValues;
this._disabledStates = disabledStates;
}
/**
* @param {!WebInspector.SASSSupport.PropertyChange} change
* @param {!WebInspector.ASTSourceMap} map
* @return {?WebInspector.SASSProcessor.InsertPropertiesOperation}
*/
WebInspector.SASSProcessor.InsertPropertiesOperation.fromCSSChange = function(change, map)
{
var insertBefore = false;
var cssAnchor = null;
var sassAnchor = null;
if (change.oldPropertyIndex) {
cssAnchor = change.oldRule.properties[change.oldPropertyIndex - 1].name;
sassAnchor = map.toSourceNode(cssAnchor);
} else {
insertBefore = true;
cssAnchor = change.oldRule.properties[0].name;
sassAnchor = map.toSourceNode(cssAnchor);
}
if (!sassAnchor)
return null;
var insertedProperty = /** @type {!WebInspector.SASSSupport.Property} */(change.newProperty());
console.assert(insertedProperty, "InsertPropertiesOperation must have inserted CSS property");
var names = [insertedProperty.name.text];
var values = [insertedProperty.value.text];
var disabledStates = [insertedProperty.disabled];
return new WebInspector.SASSProcessor.InsertPropertiesOperation(map, sassAnchor.parent, insertBefore, names, values, disabledStates);
}
WebInspector.SASSProcessor.InsertPropertiesOperation.prototype = {
/**
* @override
* @param {!WebInspector.SASSProcessor.EditOperation} other
* @return {boolean}
*/
merge: function(other)
{
if (!(other instanceof WebInspector.SASSProcessor.InsertPropertiesOperation))
return false;
if (this._sassAnchor !== other._sassAnchor || this._insertBefore !== other._insertBefore)
return false;
var names = new Set(this._nameTexts);
for (var i = 0; i < other._nameTexts.length; ++i) {
var nameText = other._nameTexts[i];
if (names.has(nameText))
continue;
this._nameTexts.push(nameText);
this._valueTexts.push(other._valueTexts[i]);
this._disabledStates.push(other._disabledStates[i]);
}
return true;
},
/**
* @override
* @return {!Array<!WebInspector.SASSSupport.Rule>}
*/
perform: function()
{
var cssRules = [];
var sassRule = this._sassAnchor.parent;
var newSASSProperties = sassRule.insertProperties(this._nameTexts, this._valueTexts, this._disabledStates, this._sassAnchor, this._insertBefore);
var cssAnchors = WebInspector.SASSProcessor._toCSSProperties(this.map, this._sassAnchor);
for (var cssAnchor of cssAnchors) {
var cssRule = cssAnchor.parent;
cssRules.push(cssRule);
var newCSSProperties = cssRule.insertProperties(this._nameTexts, this._valueTexts, this._disabledStates, cssAnchor, this._insertBefore);
for (var i = 0; i < newCSSProperties.length; ++i) {
this.map.addMapping(newCSSProperties[i].name, newSASSProperties[i].name);
this.map.addMapping(newCSSProperties[i].value, newSASSProperties[i].value);
}
}
return cssRules;
},
/**
* @override
* @param {!WebInspector.ASTSourceMap} newMap
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>} nodeMapping
* @return {!WebInspector.SASSProcessor.InsertPropertiesOperation}
*/
rebase: function(newMap, nodeMapping)
{
var sassAnchor = /** @type {?WebInspector.SASSSupport.Property} */(nodeMapping.get(this._sassAnchor)) || this._sassAnchor;
return new WebInspector.SASSProcessor.InsertPropertiesOperation(newMap, sassAnchor, this._insertBefore, this._nameTexts, this._valueTexts, this._disabledStates);
},
__proto__: WebInspector.SASSProcessor.EditOperation.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.SourceMapFactory}
*/
WebInspector.SASSSourceMapFactory = function()
{
this._astService = new WebInspector.ASTService();
}
WebInspector.SASSSourceMapFactory.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
* @param {!WebInspector.SourceMap} sourceMap
* @return {!Promise<?WebInspector.SourceMap>}
*/
editableSourceMap: function(target, sourceMap)
{
var cssModel = WebInspector.CSSModel.fromTarget(target);
if (!cssModel)
return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null));
var headerIds = cssModel.styleSheetIdsForURL(sourceMap.compiledURL());
if (!headerIds || !headerIds.length)
return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null));
var header = cssModel.styleSheetHeaderForId(headerIds[0]);
/** @type {!Map<string, !WebInspector.SASSSupport.AST>} */
var models = new Map();
var promises = [];
for (let url of sourceMap.sourceURLs()) {
var contentProvider = sourceMap.sourceContentProvider(url, WebInspector.resourceTypes.SourceMapStyleSheet);
var sassPromise = contentProvider.requestContent()
.then(text => this._astService.parseSCSS(url, text || ""))
.then(ast => models.set(ast.document.url, ast));
promises.push(sassPromise);
}
var cssURL = sourceMap.compiledURL();
var cssPromise = header.requestContent()
.then(text => this._astService.parseCSS(cssURL, text || ""))
.then(ast => models.set(ast.document.url, ast));
promises.push(cssPromise);
return Promise.all(promises)
.then(this._onSourcesParsed.bind(this, sourceMap, models))
.catchException(/** @type {?WebInspector.SourceMap} */(null));
},
/**
* @param {!WebInspector.SourceMap} sourceMap
* @param {!Map<string, !WebInspector.SASSSupport.AST>} models
* @return {?WebInspector.SourceMap}
*/
_onSourcesParsed: function(sourceMap, models)
{
var editCallback = WebInspector.SASSProcessor.processCSSEdits.bind(WebInspector.SASSProcessor, this._astService);
var map = new WebInspector.ASTSourceMap(sourceMap.compiledURL(), sourceMap.url(), models, editCallback);
var valid = true;
map.compiledModel().visit(onNode);
return valid ? map : null;
/**
* @param {!WebInspector.SASSSupport.Node} cssNode
*/
function onNode(cssNode)
{
if (!(cssNode instanceof WebInspector.SASSSupport.TextNode))
return;
var entry = sourceMap.findEntry(cssNode.range.endLine, cssNode.range.endColumn);
if (!entry || !entry.sourceURL || typeof entry.sourceLineNumber === "undefined" || typeof entry.sourceColumnNumber === "undefined")
return;
var sassAST = models.get(entry.sourceURL);
if (!sassAST)
return;
var sassNode = sassAST.findNodeForPosition(entry.sourceLineNumber, entry.sourceColumnNumber);
if (!sassNode)
return;
if (cssNode.parent && (cssNode.parent instanceof WebInspector.SASSSupport.Property) && cssNode === cssNode.parent.name)
valid = valid && cssNode.text.trim() === sassNode.text.trim();
map.addMapping(cssNode, sassNode);
}
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | 2 1 1 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.SASSSupport = {}
/**
* @param {!WebInspector.CSSParserService} cssParserService
* @param {string} url
* @param {string} text
* @return {!Promise<!WebInspector.SASSSupport.AST>}
*/
WebInspector.SASSSupport.parseCSS = function(cssParserService, url, text)
{
return cssParserService.parseCSS(text)
.then(onParsed);
/**
* @param {!Array.<!WebInspector.CSSParser.Rule>} parsedCSS
* @return {!WebInspector.SASSSupport.AST}
*/
function onParsed(parsedCSS)
{
var document = new WebInspector.SASSSupport.ASTDocument(url, new WebInspector.Text(text));
var rules = [];
for (var i = 0; i < parsedCSS.length; ++i) {
var rule = parsedCSS[i];
if (!rule.properties)
continue;
var properties = [];
for (var j = 0; j < rule.properties.length; ++j) {
var cssProperty = rule.properties[j];
var name = new WebInspector.SASSSupport.TextNode(document, cssProperty.name, WebInspector.TextRange.fromObject(cssProperty.nameRange));
var value = new WebInspector.SASSSupport.TextNode(document, cssProperty.value, WebInspector.TextRange.fromObject(cssProperty.valueRange));
var property = new WebInspector.SASSSupport.Property(document, name, value, WebInspector.TextRange.fromObject(cssProperty.range), !!cssProperty.disabled);
properties.push(property);
}
rules.push(new WebInspector.SASSSupport.Rule(document, rule.selectorText, WebInspector.TextRange.fromObject(rule.styleRange), properties));
}
return new WebInspector.SASSSupport.AST(document, rules);
}
}
/**
* @param {!WebInspector.TokenizerFactory} tokenizerFactory
* @param {string} url
* @param {string} text
* @return {!WebInspector.SASSSupport.AST}
*/
WebInspector.SASSSupport.parseSCSS = function(tokenizerFactory, url, text)
{
var document = new WebInspector.SASSSupport.ASTDocument(url, new WebInspector.Text(text));
var result = WebInspector.SASSSupport._innerParseSCSS(document, tokenizerFactory);
var rules = [
new WebInspector.SASSSupport.Rule(document, "variables", WebInspector.TextRange.createFromLocation(0, 0), result.variables),
new WebInspector.SASSSupport.Rule(document, "properties", WebInspector.TextRange.createFromLocation(0, 0), result.properties),
new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.TextRange.createFromLocation(0, 0), result.mixins)
];
return new WebInspector.SASSSupport.AST(document, rules);
}
/** @enum {string} */
WebInspector.SASSSupport.SCSSParserStates = {
Initial: "Initial",
PropertyName: "PropertyName",
PropertyValue: "PropertyValue",
VariableName: "VariableName",
VariableValue: "VariableValue",
MixinName: "MixinName",
MixinValue: "MixinValue",
Media: "Media"
}
/**
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @param {!WebInspector.TokenizerFactory} tokenizerFactory
* @return {!{variables: !Array<!WebInspector.SASSSupport.Property>, properties: !Array<!WebInspector.SASSSupport.Property>, mixins: !Array<!WebInspector.SASSSupport.Property>}}
*/
WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
{
var properties = [];
var variables = [];
var mixins = [];
var States = WebInspector.SASSSupport.SCSSParserStates;
var state = States.Initial;
var propertyName, propertyValue;
var variableName, variableValue;
var mixinName, mixinValue;
var UndefTokenType = {};
var cursor = new WebInspector.TextCursor(document.text.lineEndings());
/**
* @param {string} tokenValue
* @param {?string} tokenTypes
* @param {number} startPosition
* @param {number} endPosition
*/
function processToken(tokenValue, tokenTypes, startPosition, endPosition)
{
cursor.advance(startPosition);
var startLine = cursor.lineNumber();
var startColumn = cursor.columnNumber();
cursor.advance(endPosition);
var endLine = cursor.lineNumber();
var endColumn = cursor.columnNumber();
var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType;
switch (state) {
case States.Initial:
if (tokenType["css-variable-2"]) {
variableName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.VariableName;
} else if (tokenType["css-property"] || tokenType["css-meta"]) {
propertyName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.PropertyName;
} else if (tokenType["css-def"] && tokenValue === "@include") {
mixinName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.MixinName;
} else if (tokenType["css-comment"]) {
// Support only a one-line comments.
if (startLine !== endLine || tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/")
break;
var uncommentedText = tokenValue.substring(2, tokenValue.length - 2);
var fakeRuleText = "a{" + uncommentedText + "}";
var fakeDocument = new WebInspector.SASSSupport.ASTDocument("", new WebInspector.Text(fakeRuleText));
var result = WebInspector.SASSSupport._innerParseSCSS(fakeDocument, tokenizerFactory);
if (result.properties.length === 1 && result.variables.length === 0 && result.mixins.length === 0) {
var disabledProperty = result.properties[0];
var nameRange = rebaseInsideOneLineComment(disabledProperty.name.range, startLine, startColumn);
var valueRange = rebaseInsideOneLineComment(disabledProperty.value.range, startLine, startColumn);
var name = new WebInspector.SASSSupport.TextNode(document, disabledProperty.name.text, nameRange);
var value = new WebInspector.SASSSupport.TextNode(document, disabledProperty.value.text, valueRange);
var range = new WebInspector.TextRange(startLine, startColumn, startLine, endColumn);
var property = new WebInspector.SASSSupport.Property(document, name, value, range, true);
properties.push(property);
}
} else if (tokenType["css-def"] && tokenValue === "@media") {
state = States.Media;
}
break;
case States.VariableName:
if (tokenValue === "}" && tokenType === UndefTokenType) {
state = States.Initial;
} else if (tokenValue === ")" && tokenType === UndefTokenType) {
state = States.Initial;
} else if (tokenValue === ":" && tokenType === UndefTokenType) {
state = States.VariableValue;
variableValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenType !== UndefTokenType) {
state = States.Initial;
}
break;
case States.VariableValue:
if (tokenValue === ";" && tokenType === UndefTokenType) {
variableValue.range.endLine = startLine;
variableValue.range.endColumn = startColumn;
var variable = new WebInspector.SASSSupport.Property(document, variableName, variableValue, variableName.range.clone(), false);
variable.range.endLine = startLine;
variable.range.endColumn = endColumn;
variables.push(variable);
state = States.Initial;
} else {
variableValue.text += tokenValue;
}
break;
case States.PropertyName:
if (tokenValue === "{" && tokenType === UndefTokenType) {
state = States.Initial;
} else if (tokenValue === ":" && tokenType === UndefTokenType) {
state = States.PropertyValue;
propertyName.range.endLine = startLine;
propertyName.range.endColumn = startColumn;
propertyValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenType["css-property"]) {
propertyName.text += tokenValue;
}
break;
case States.PropertyValue:
if (tokenValue === "{" && tokenType === UndefTokenType) {
state = States.Initial;
} else if ((tokenValue === "}" || tokenValue === ";") && tokenType === UndefTokenType) {
propertyValue.range.endLine = startLine;
propertyValue.range.endColumn = startColumn;
var property = new WebInspector.SASSSupport.Property(document, propertyName, propertyValue, propertyName.range.clone(), false);
property.range.endLine = startLine;
property.range.endColumn = endColumn;
properties.push(property);
state = States.Initial;
} else {
propertyValue.text += tokenValue;
}
break;
case States.MixinName:
if (tokenValue === "(" && tokenType === UndefTokenType) {
state = States.MixinValue;
mixinName.range.endLine = startLine;
mixinName.range.endColumn = startColumn;
mixinValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenValue === ";" && tokenType === UndefTokenType) {
state = States.Initial;
mixinValue = null;
} else {
mixinName.text += tokenValue;
}
break;
case States.MixinValue:
if (tokenValue === ")" && tokenType === UndefTokenType) {
mixinValue.range.endLine = startLine;
mixinValue.range.endColumn = startColumn;
var mixin = new WebInspector.SASSSupport.Property(document, mixinName, /** @type {!WebInspector.SASSSupport.TextNode} */(mixinValue), mixinName.range.clone(), false);
mixin.range.endLine = startLine;
mixin.range.endColumn = endColumn;
mixins.push(mixin);
state = States.Initial;
} else {
mixinValue.text += tokenValue;
}
break;
case States.Media:
if (tokenValue === "{" && tokenType === UndefTokenType)
state = States.Initial;
break;
default:
console.assert(false, "Unknown SASS parser state.");
}
}
var tokenizer = tokenizerFactory.createTokenizer("text/x-scss");
tokenizer(document.text.value(), processToken);
return {
variables: variables,
properties: properties,
mixins: mixins
};
/**
* @param {!WebInspector.TextRange} range
* @param {number} startLine
* @param {number} startColumn
* @return {!WebInspector.TextRange}
*/
function rebaseInsideOneLineComment(range, startLine, startColumn)
{
return new WebInspector.TextRange(range.startLine + startLine, range.startColumn + startColumn, range.endLine + startLine, range.endColumn + startColumn);
}
}
/**
* @constructor
* @param {string} url
* @param {!WebInspector.Text} text
*/
WebInspector.SASSSupport.ASTDocument = function(url, text)
{
this.url = url;
this.text = text;
this.edits = [];
}
WebInspector.SASSSupport.ASTDocument.prototype = {
/**
* @return {!WebInspector.SASSSupport.ASTDocument}
*/
clone: function()
{
return new WebInspector.SASSSupport.ASTDocument(this.url, this.text);
},
/**
* @return {boolean}
*/
hasChanged: function()
{
return !!this.edits.length;
},
/**
* @return {!WebInspector.Text}
*/
newText: function()
{
this.edits.stableSort(sequentialOrder);
var text = this.text;
for (var i = this.edits.length - 1; i >= 0; --i) {
var range = this.edits[i].oldRange;
var newText = this.edits[i].newText;
text = new WebInspector.Text(text.replaceRange(range, newText));
}
return text;
/**
* @param {!WebInspector.SourceEdit} edit1
* @param {!WebInspector.SourceEdit} edit2
* @return {number}
*/
function sequentialOrder(edit1, edit2)
{
var range1 = edit1.oldRange.collapseToStart();
var range2 = edit2.oldRange.collapseToStart();
if (range1.equal(range2))
return 0;
return range1.follows(range2) ? 1 : -1;
}
},
}
/**
* @constructor
* @param {!WebInspector.SASSSupport.ASTDocument} document
*/
WebInspector.SASSSupport.Node = function(document)
{
this.document = document;
}
/**
* @constructor
* @extends {WebInspector.SASSSupport.Node}
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @param {string} text
* @param {!WebInspector.TextRange} range
*/
WebInspector.SASSSupport.TextNode = function(document, text, range)
{
WebInspector.SASSSupport.Node.call(this, document);
this.text = text;
this.range = range;
}
WebInspector.SASSSupport.TextNode.prototype = {
/**
* @param {string} newText
*/
setText: function(newText)
{
if (this.text === newText)
return;
this.text = newText;
this.document.edits.push(new WebInspector.SourceEdit(this.document.url, this.range, newText));
},
/**
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @return {!WebInspector.SASSSupport.TextNode}
*/
clone: function(document)
{
return new WebInspector.SASSSupport.TextNode(document, this.text, this.range.clone());
},
/**
* @param {!WebInspector.SASSSupport.TextNode} other
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>=} outNodeMapping
* @return {boolean}
*/
match: function(other, outNodeMapping)
{
if (this.text.trim() !== other.text.trim())
return false;
if (outNodeMapping)
outNodeMapping.set(this, other);
return true;
},
__proto__: WebInspector.SASSSupport.Node.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSSupport.Node}
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @param {!WebInspector.SASSSupport.TextNode} name
* @param {!WebInspector.SASSSupport.TextNode} value
* @param {!WebInspector.TextRange} range
* @param {boolean} disabled
*/
WebInspector.SASSSupport.Property = function(document, name, value, range, disabled)
{
WebInspector.SASSSupport.Node.call(this, document);
this.name = name;
this.value = value;
this.range = range;
this.name.parent = this;
this.value.parent = this;
this.disabled = disabled;
}
WebInspector.SASSSupport.Property.prototype = {
/**
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @return {!WebInspector.SASSSupport.Property}
*/
clone: function(document)
{
return new WebInspector.SASSSupport.Property(document, this.name.clone(document), this.value.clone(document), this.range.clone(), this.disabled);
},
/**
* @param {function(!WebInspector.SASSSupport.Node)} callback
*/
visit: function(callback)
{
callback(this);
callback(this.name);
callback(this.value);
},
/**
* @param {!WebInspector.SASSSupport.Property} other
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>=} outNodeMapping
* @return {boolean}
*/
match: function(other, outNodeMapping)
{
if (this.disabled !== other.disabled)
return false;
if (outNodeMapping)
outNodeMapping.set(this, other);
return this.name.match(other.name, outNodeMapping) && this.value.match(other.value, outNodeMapping);
},
/**
* @param {boolean} disabled
*/
setDisabled: function(disabled)
{
if (this.disabled === disabled)
return;
this.disabled = disabled;
if (disabled) {
var oldRange1 = WebInspector.TextRange.createFromLocation(this.range.startLine, this.range.startColumn);
var edit1 = new WebInspector.SourceEdit(this.document.url, oldRange1, "/* ");
var oldRange2 = WebInspector.TextRange.createFromLocation(this.range.endLine, this.range.endColumn);
var edit2 = new WebInspector.SourceEdit(this.document.url, oldRange2, " */");
this.document.edits.push(edit1, edit2);
return;
}
var oldRange1 = new WebInspector.TextRange(this.range.startLine, this.range.startColumn, this.range.startLine, this.name.range.startColumn);
var edit1 = new WebInspector.SourceEdit(this.document.url, oldRange1, "");
var oldRange2 = new WebInspector.TextRange(this.range.endLine, this.range.endColumn - 2, this.range.endLine, this.range.endColumn);
var edit2 = new WebInspector.SourceEdit(this.document.url, oldRange2, "");
this.document.edits.push(edit1, edit2);
},
remove: function()
{
console.assert(this.parent);
var rule = this.parent;
var index = rule.properties.indexOf(this);
rule.properties.splice(index, 1);
this.parent = null;
var lineRange = new WebInspector.TextRange(this.range.startLine, 0, this.range.endLine + 1, 0);
var oldRange;
if (this.document.text.extract(lineRange).trim() === this.document.text.extract(this.range).trim())
oldRange = lineRange;
else
oldRange = this.range;
this.document.edits.push(new WebInspector.SourceEdit(this.document.url, oldRange, ""));
},
__proto__: WebInspector.SASSSupport.Node.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSSupport.Node}
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @param {string} selector
* @param {!WebInspector.TextRange} styleRange
* @param {!Array<!WebInspector.SASSSupport.Property>} properties
*/
WebInspector.SASSSupport.Rule = function(document, selector, styleRange, properties)
{
WebInspector.SASSSupport.Node.call(this, document);
this.selector = selector;
this.properties = properties;
this.styleRange = styleRange;
for (var i = 0; i < this.properties.length; ++i)
this.properties[i].parent = this;
this._hasTrailingSemicolon = !this.properties.length || this.document.text.extract(this.properties.peekLast().range).endsWith(";");
}
WebInspector.SASSSupport.Rule.prototype = {
/**
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @return {!WebInspector.SASSSupport.Rule}
*/
clone: function(document)
{
var properties = [];
for (var i = 0; i < this.properties.length; ++i)
properties.push(this.properties[i].clone(document));
return new WebInspector.SASSSupport.Rule(document, this.selector, this.styleRange.clone(), properties);
},
/**
* @param {function(!WebInspector.SASSSupport.Node)} callback
*/
visit: function(callback)
{
callback(this);
for (var i = 0; i < this.properties.length; ++i)
this.properties[i].visit(callback);
},
/**
* @param {!WebInspector.SASSSupport.Rule} other
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>=} outNodeMapping
* @return {boolean}
*/
match: function(other, outNodeMapping)
{
if (this.selector !== other.selector)
return false;
if (this.properties.length !== other.properties.length)
return false;
if (outNodeMapping)
outNodeMapping.set(this, other);
var result = true;
for (var i = 0; result && i < this.properties.length; ++i)
result = result && this.properties[i].match(other.properties[i], outNodeMapping);
return result;
},
_addTrailingSemicolon: function()
{
if (this._hasTrailingSemicolon || !this.properties)
return;
this._hasTrailingSemicolon = true;
this.document.edits.push(new WebInspector.SourceEdit(this.document.url, this.properties.peekLast().range.collapseToEnd(), ";"))
},
/**
* @param {!Array<string>} nameTexts
* @param {!Array<string>} valueTexts
* @param {!Array<boolean>} disabledStates
* @param {!WebInspector.SASSSupport.Property} anchorProperty
* @param {boolean} insertBefore
* @return {!Array<!WebInspector.SASSSupport.Property>}
*/
insertProperties: function(nameTexts, valueTexts, disabledStates, anchorProperty, insertBefore)
{
console.assert(this.properties.length, "Cannot insert in empty rule.");
console.assert(nameTexts.length === valueTexts.length && valueTexts.length === disabledStates.length, "Input array should be of the same size.");
this._addTrailingSemicolon();
var newProperties = [];
var index = this.properties.indexOf(anchorProperty);
for (var i = 0; i < nameTexts.length; ++i) {
var nameText = nameTexts[i];
var valueText = valueTexts[i];
var disabled = disabledStates[i];
this.document.edits.push(this._insertPropertyEdit(nameText, valueText, disabled, anchorProperty, insertBefore));
var name = new WebInspector.SASSSupport.TextNode(this.document, nameText, WebInspector.TextRange.createFromLocation(0, 0));
var value = new WebInspector.SASSSupport.TextNode(this.document, valueText, WebInspector.TextRange.createFromLocation(0, 0));
var newProperty = new WebInspector.SASSSupport.Property(this.document, name, value, WebInspector.TextRange.createFromLocation(0, 0), disabled);
this.properties.splice(insertBefore ? index + i : index + i + 1, 0, newProperty);
newProperty.parent = this;
newProperties.push(newProperty);
}
return newProperties;
},
/**
* @param {string} nameText
* @param {string} valueText
* @param {boolean} disabled
* @param {!WebInspector.SASSSupport.Property} anchorProperty
* @param {boolean} insertBefore
* @return {!WebInspector.SourceEdit}
*/
_insertPropertyEdit: function(nameText, valueText, disabled, anchorProperty, insertBefore)
{
var oldRange = insertBefore ? anchorProperty.range.collapseToStart() : anchorProperty.range.collapseToEnd();
var indent = this.document.text.extract(new WebInspector.TextRange(anchorProperty.range.startLine, 0, anchorProperty.range.startLine, anchorProperty.range.startColumn));
if (!/^\s+$/.test(indent)) indent = "";
var newText = "";
var leftComment = disabled ? "/* " : "";
var rightComment = disabled ? " */" : "";
if (insertBefore) {
newText = String.sprintf("%s%s: %s;%s\n%s", leftComment, nameText, valueText, rightComment, indent);
} else {
newText = String.sprintf("\n%s%s%s: %s;%s", indent, leftComment, nameText, valueText, rightComment);
}
return new WebInspector.SourceEdit(this.document.url, oldRange, newText);
},
__proto__: WebInspector.SASSSupport.Node.prototype
}
/**
* @constructor
* @extends {WebInspector.SASSSupport.Node}
* @param {!WebInspector.SASSSupport.ASTDocument} document
* @param {!Array<!WebInspector.SASSSupport.Rule>} rules
*/
WebInspector.SASSSupport.AST = function(document, rules)
{
WebInspector.SASSSupport.Node.call(this, document);
this.rules = rules;
for (var i = 0; i < rules.length; ++i)
rules[i].parent = this;
}
WebInspector.SASSSupport.AST.prototype = {
/**
* @return {!WebInspector.SASSSupport.AST}
*/
clone: function()
{
var document = this.document.clone();
var rules = [];
for (var i = 0; i < this.rules.length; ++i)
rules.push(this.rules[i].clone(document));
return new WebInspector.SASSSupport.AST(document, rules);
},
/**
* @param {!WebInspector.SASSSupport.AST} other
* @param {!Map<!WebInspector.SASSSupport.Node, !WebInspector.SASSSupport.Node>=} outNodeMapping
* @return {boolean}
*/
match: function(other, outNodeMapping)
{
if (other.document.url !== this.document.url)
return false;
if (other.rules.length !== this.rules.length)
return false;
if (outNodeMapping)
outNodeMapping.set(this, other);
var result = true;
for (var i = 0; result && i < this.rules.length; ++i)
result = result && this.rules[i].match(other.rules[i], outNodeMapping);
return result;
},
/**
* @param {function(!WebInspector.SASSSupport.Node)} callback
*/
visit: function(callback)
{
callback(this);
for (var i = 0; i < this.rules.length; ++i)
this.rules[i].visit(callback);
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.SASSSupport.TextNode}
*/
findNodeForPosition: function(lineNumber, columnNumber)
{
this._ensureNodePositionsIndex();
var index = this._sortedTextNodes.lowerBound({lineNumber: lineNumber, columnNumber: columnNumber}, nodeComparator);
var node = this._sortedTextNodes[index];
if (!node)
return null;
return node.range.containsLocation(lineNumber, columnNumber) ? node : null;
/**
* @param {!{lineNumber: number, columnNumber: number}} position
* @param {!WebInspector.SASSSupport.TextNode} textNode
* @return {number}
*/
function nodeComparator(position, textNode)
{
return textNode.range.compareToPosition(position.lineNumber, position.columnNumber);
}
},
_ensureNodePositionsIndex: function()
{
if (this._sortedTextNodes)
return;
this._sortedTextNodes = [];
this.visit(onNode.bind(this));
this._sortedTextNodes.sort(nodeComparator);
/**
* @param {!WebInspector.SASSSupport.Node} node
* @this {WebInspector.SASSSupport.AST}
*/
function onNode(node)
{
if (!(node instanceof WebInspector.SASSSupport.TextNode))
return;
this._sortedTextNodes.push(node);
}
/**
* @param {!WebInspector.SASSSupport.TextNode} text1
* @param {!WebInspector.SASSSupport.TextNode} text2
* @return {number}
*/
function nodeComparator(text1, text2)
{
return WebInspector.TextRange.comparator(text1.range, text2.range);
}
},
__proto__: WebInspector.SASSSupport.Node.prototype
}
/** @enum {string} */
WebInspector.SASSSupport.PropertyChangeType = {
PropertyAdded: "PropertyAdded",
PropertyRemoved: "PropertyRemoved",
PropertyToggled: "PropertyToggled",
ValueChanged: "ValueChanged",
NameChanged: "NameChanged"
}
/**
* @constructor
* @param {!WebInspector.SASSSupport.PropertyChangeType} type
* @param {!WebInspector.SASSSupport.Rule} oldRule
* @param {!WebInspector.SASSSupport.Rule} newRule
* @param {number} oldPropertyIndex
* @param {number} newPropertyIndex
*/
WebInspector.SASSSupport.PropertyChange = function(type, oldRule, newRule, oldPropertyIndex, newPropertyIndex)
{
this.type = type;
this.oldRule = oldRule;
this.newRule = newRule;
this.oldPropertyIndex = oldPropertyIndex;
this.newPropertyIndex = newPropertyIndex;
}
WebInspector.SASSSupport.PropertyChange.prototype = {
/**
* @return {?WebInspector.SASSSupport.Property}
*/
oldProperty: function()
{
return this.oldRule.properties[this.oldPropertyIndex] || null;
},
/**
* @return {?WebInspector.SASSSupport.Property}
*/
newProperty: function()
{
return this.newRule.properties[this.newPropertyIndex] || null;
}
}
/**
* @constructor
* @param {string} url
* @param {!WebInspector.SASSSupport.AST} oldAST
* @param {!WebInspector.SASSSupport.AST} newAST
* @param {!Map<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} mapping
* @param {!Array<!WebInspector.SASSSupport.PropertyChange>} changes
*/
WebInspector.SASSSupport.ASTDiff = function(url, oldAST, newAST, mapping, changes)
{
this.url = url;
this.mapping = mapping;
this.changes = changes;
this.oldAST = oldAST;
this.newAST = newAST;
}
/**
* @param {!WebInspector.SASSSupport.AST} oldAST
* @param {!WebInspector.SASSSupport.AST} newAST
* @return {!WebInspector.SASSSupport.ASTDiff}
*/
WebInspector.SASSSupport.diffModels = function(oldAST, newAST)
{
console.assert(oldAST.rules.length === newAST.rules.length, "Not implemented for rule diff.");
console.assert(oldAST.document.url === newAST.document.url, "Diff makes sense for models with the same url.");
var T = WebInspector.SASSSupport.PropertyChangeType;
var changes = [];
/** @type {!Map<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} */
var mapping = new Map();
for (var i = 0; i < oldAST.rules.length; ++i) {
var oldRule = oldAST.rules[i];
var newRule = newAST.rules[i];
computeRuleDiff(mapping, oldRule, newRule);
}
return new WebInspector.SASSSupport.ASTDiff(oldAST.document.url, oldAST, newAST, mapping, changes);
/**
* @param {!WebInspector.SASSSupport.PropertyChangeType} type
* @param {!WebInspector.SASSSupport.Rule} oldRule
* @param {!WebInspector.SASSSupport.Rule} newRule
* @param {number} oldPropertyIndex
* @param {number} newPropertyIndex
*/
function addChange(type, oldRule, newRule, oldPropertyIndex, newPropertyIndex)
{
changes.push(new WebInspector.SASSSupport.PropertyChange(type, oldRule, newRule, oldPropertyIndex, newPropertyIndex));
}
/**
* @param {!Map<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} mapping
* @param {!WebInspector.SASSSupport.Rule} oldRule
* @param {!WebInspector.SASSSupport.Rule} newRule
*/
function computeRuleDiff(mapping, oldRule, newRule)
{
var oldLines = [];
for (var i = 0; i < oldRule.properties.length; ++i)
oldLines.push(oldRule.properties[i].name.text.trim() + ":" + oldRule.properties[i].value.text.trim());
var newLines = [];
for (var i = 0; i < newRule.properties.length; ++i)
newLines.push(newRule.properties[i].name.text.trim() + ":" + newRule.properties[i].value.text.trim());
var diff = WebInspector.Diff.lineDiff(oldLines, newLines);
diff = WebInspector.Diff.convertToEditDiff(diff);
var p1 = 0, p2 = 0;
for (var i = 0; i < diff.length; ++i) {
var token = diff[i];
if (token[0] === WebInspector.Diff.Operation.Delete) {
for (var j = 0; j < token[1]; ++j)
addChange(T.PropertyRemoved, oldRule, newRule, p1++, p2);
} else if (token[0] === WebInspector.Diff.Operation.Insert) {
for (var j = 0; j < token[1]; ++j)
addChange(T.PropertyAdded, oldRule, newRule, p1, p2++);
} else {
for (var j = 0; j < token[1]; ++j)
computePropertyDiff(mapping, oldRule, newRule, p1++, p2++);
}
}
}
/**
* @param {!Map<!WebInspector.SASSSupport.TextNode, !WebInspector.SASSSupport.TextNode>} mapping
* @param {!WebInspector.SASSSupport.Rule} oldRule
* @param {!WebInspector.SASSSupport.Rule} newRule
* @param {number} oldPropertyIndex
* @param {number} newPropertyIndex
*/
function computePropertyDiff(mapping, oldRule, newRule, oldPropertyIndex, newPropertyIndex)
{
var oldProperty = oldRule.properties[oldPropertyIndex];
var newProperty = newRule.properties[newPropertyIndex];
mapping.set(oldProperty.name, newProperty.name);
mapping.set(oldProperty.value, newProperty.value);
if (oldProperty.name.text.trim() !== newProperty.name.text.trim())
addChange(T.NameChanged, oldRule, newRule, oldPropertyIndex, newPropertyIndex);
if (oldProperty.value.text.trim() !== newProperty.value.text.trim())
addChange(T.ValueChanged, oldRule, newRule, oldPropertyIndex, newPropertyIndex);
if (oldProperty.disabled !== newProperty.disabled)
addChange(T.PropertyToggled, oldRule, newRule, oldPropertyIndex, newPropertyIndex);
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ScreencastApp.js | 1.85% | (1 / 54) | 0% | (0 / 16) | 0% | (0 / 11) | 1.85% | (1 / 54) | |
| ScreencastView.js | 0.89% | (4 / 448) | 0% | (0 / 181) | 0% | (0 / 52) | 0.9% | (4 / 445) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.App}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.ScreencastApp = function()
{
this._enabledSetting = WebInspector.settings.createSetting("screencastEnabled", true);
this._toggleButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Toggle screencast"), "phone-toolbar-item");
this._toggleButton.setToggled(this._enabledSetting.get());
this._toggleButton.addEventListener("click", this._toggleButtonClicked, this);
WebInspector.targetManager.observeTargets(this);
};
WebInspector.ScreencastApp.prototype = {
/**
* @override
* @param {!Document} document
*/
presentUI: function(document)
{
var rootView = new WebInspector.RootView();
this._rootSplitWidget = new WebInspector.SplitWidget(false, true, "InspectorView.screencastSplitViewState", 300, 300);
this._rootSplitWidget.setVertical(true);
this._rootSplitWidget.setSecondIsSidebar(true);
this._rootSplitWidget.show(rootView.element);
this._rootSplitWidget.hideMain();
this._rootSplitWidget.setSidebarWidget(WebInspector.inspectorView);
WebInspector.inspectorView.showInitialPanel();
rootView.attachToDocument(document);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (this._target)
return;
this._target = target;
if (target.isPage()) {
this._screencastView = new WebInspector.ScreencastView(target);
this._rootSplitWidget.setMainWidget(this._screencastView);
this._screencastView.initialize();
} else {
this._toggleButton.setEnabled(false);
}
this._onScreencastEnabledChanged();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (this._target === target) {
delete this._target;
if (!this._screencastView)
return;
this._toggleButton.setEnabled(false);
this._screencastView.detach();
delete this._screencastView;
this._onScreencastEnabledChanged();
}
},
_toggleButtonClicked: function()
{
var enabled = !this._toggleButton.toggled();
this._enabledSetting.set(enabled);
this._onScreencastEnabledChanged();
},
_onScreencastEnabledChanged: function()
{
if (!this._rootSplitWidget)
return;
var enabled = this._enabledSetting.get() && this._screencastView;
this._toggleButton.setToggled(enabled);
if (enabled)
this._rootSplitWidget.showBoth();
else
this._rootSplitWidget.hideMain();
}
};
/** @type {!WebInspector.ScreencastApp} */
WebInspector.ScreencastApp._appInstance;
/**
* @return {!WebInspector.ScreencastApp}
*/
WebInspector.ScreencastApp._instance = function()
{
if (!WebInspector.ScreencastApp._appInstance)
WebInspector.ScreencastApp._appInstance = new WebInspector.ScreencastApp();
return WebInspector.ScreencastApp._appInstance;
};
/**
* @constructor
* @implements {WebInspector.ToolbarItem.Provider}
*/
WebInspector.ScreencastApp.ToolbarButtonProvider = function()
{
}
WebInspector.ScreencastApp.ToolbarButtonProvider.prototype = {
/**
* @override
* @return {?WebInspector.ToolbarItem}
*/
item: function()
{
return WebInspector.ScreencastApp._instance()._toggleButton;
}
}
/**
* @constructor
* @implements {WebInspector.AppProvider}
*/
WebInspector.ScreencastAppProvider = function()
{
};
WebInspector.ScreencastAppProvider.prototype = {
/**
* @override
* @return {!WebInspector.App}
*/
createApp: function()
{
return WebInspector.ScreencastApp._instance();
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | 2 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.DOMNodeHighlighter}
* @param {!WebInspector.Target} target
*/
WebInspector.ScreencastView = function(target)
{
WebInspector.VBox.call(this);
this._target = target;
this._domModel = WebInspector.DOMModel.fromTarget(target);
this.setMinimumSize(150, 150);
this.registerRequiredCSS("screencast/screencastView.css");
};
WebInspector.ScreencastView._bordersSize = 44;
WebInspector.ScreencastView._navBarHeight = 29;
WebInspector.ScreencastView._HttpRegex = /^http:\/\/(.+)/;
WebInspector.ScreencastView._SchemeRegex = /^(https?|about|chrome):/;
WebInspector.ScreencastView.prototype = {
initialize: function()
{
this.element.classList.add("screencast");
this._createNavigationBar();
this._viewportElement = this.element.createChild("div", "screencast-viewport hidden");
this._canvasContainerElement = this._viewportElement.createChild("div", "screencast-canvas-container");
this._glassPaneElement = this._canvasContainerElement.createChild("div", "screencast-glasspane fill hidden");
this._canvasElement = this._canvasContainerElement.createChild("canvas");
this._canvasElement.tabIndex = 1;
this._canvasElement.addEventListener("mousedown", this._handleMouseEvent.bind(this), false);
this._canvasElement.addEventListener("mouseup", this._handleMouseEvent.bind(this), false);
this._canvasElement.addEventListener("mousemove", this._handleMouseEvent.bind(this), false);
this._canvasElement.addEventListener("mousewheel", this._handleMouseEvent.bind(this), false);
this._canvasElement.addEventListener("click", this._handleMouseEvent.bind(this), false);
this._canvasElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
this._canvasElement.addEventListener("keydown", this._handleKeyEvent.bind(this), false);
this._canvasElement.addEventListener("keyup", this._handleKeyEvent.bind(this), false);
this._canvasElement.addEventListener("keypress", this._handleKeyEvent.bind(this), false);
this._canvasElement.addEventListener("blur", this._handleBlurEvent.bind(this), false);
this._titleElement = this._canvasContainerElement.createChild("div", "screencast-element-title monospace hidden");
this._tagNameElement = this._titleElement.createChild("span", "screencast-tag-name");
this._nodeIdElement = this._titleElement.createChild("span", "screencast-node-id");
this._classNameElement = this._titleElement.createChild("span", "screencast-class-name");
this._titleElement.createTextChild(" ");
this._nodeWidthElement = this._titleElement.createChild("span");
this._titleElement.createChild("span", "screencast-px").textContent = "px";
this._titleElement.createTextChild(" \u00D7 ");
this._nodeHeightElement = this._titleElement.createChild("span");
this._titleElement.createChild("span", "screencast-px").textContent = "px";
this._titleElement.style.top = "0";
this._titleElement.style.left = "0";
this._imageElement = new Image();
this._isCasting = false;
this._context = this._canvasElement.getContext("2d");
this._checkerboardPattern = this._createCheckerboardPattern(this._context);
this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl)] = this._focusNavigationBar.bind(this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, this._screencastFrame, this);
this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, this._screencastVisibilityChanged, this);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChange, this);
this._updateGlasspane();
},
wasShown: function()
{
this._startCasting();
},
willHide: function()
{
this._stopCasting();
},
_startCasting: function()
{
if (WebInspector.targetManager.allTargetsSuspended())
return;
if (this._isCasting)
return;
this._isCasting = true;
const maxImageDimension = 2048;
var dimensions = this._viewportDimensions();
if (dimensions.width < 0 || dimensions.height < 0) {
this._isCasting = false;
return;
}
dimensions.width *= window.devicePixelRatio;
dimensions.height *= window.devicePixelRatio;
this._target.pageAgent().startScreencast("jpeg", 80, Math.min(maxImageDimension, dimensions.width), Math.min(maxImageDimension, dimensions.height));
this._target.emulationAgent().setTouchEmulationEnabled(true);
this._domModel.setHighlighter(this);
},
_stopCasting: function()
{
if (!this._isCasting)
return;
this._isCasting = false;
this._target.pageAgent().stopScreencast();
this._target.emulationAgent().setTouchEmulationEnabled(false);
this._domModel.setHighlighter(null);
},
/**
* @param {!WebInspector.Event} event
*/
_screencastFrame: function(event)
{
var metadata = /** type {PageAgent.ScreencastFrameMetadata} */(event.data.metadata);
var base64Data = /** type {string} */(event.data.data);
this._imageElement.src = "data:image/jpg;base64," + base64Data;
this._pageScaleFactor = metadata.pageScaleFactor;
this._screenOffsetTop = metadata.offsetTop;
this._scrollOffsetX = metadata.scrollOffsetX;
this._scrollOffsetY = metadata.scrollOffsetY;
var deviceSizeRatio = metadata.deviceHeight / metadata.deviceWidth;
var dimensionsCSS = this._viewportDimensions();
this._imageZoom = Math.min(dimensionsCSS.width / this._imageElement.naturalWidth, dimensionsCSS.height / (this._imageElement.naturalWidth * deviceSizeRatio));
this._viewportElement.classList.remove("hidden");
var bordersSize = WebInspector.ScreencastView._bordersSize;
if (this._imageZoom < 1.01 / window.devicePixelRatio)
this._imageZoom = 1 / window.devicePixelRatio;
this._screenZoom = this._imageElement.naturalWidth * this._imageZoom / metadata.deviceWidth;
this._viewportElement.style.width = metadata.deviceWidth * this._screenZoom + bordersSize + "px";
this._viewportElement.style.height = metadata.deviceHeight * this._screenZoom + bordersSize + "px";
this.highlightDOMNode(this._highlightNode, this._highlightConfig);
},
_isGlassPaneActive: function()
{
return !this._glassPaneElement.classList.contains("hidden");
},
/**
* @param {!WebInspector.Event} event
*/
_screencastVisibilityChanged: function(event)
{
this._targetInactive = !event.data.visible;
this._updateGlasspane();
},
/**
* @param {!WebInspector.Event} event
*/
_onSuspendStateChange: function(event)
{
if (WebInspector.targetManager.allTargetsSuspended())
this._stopCasting();
else
this._startCasting();
this._updateGlasspane();
},
_updateGlasspane: function()
{
if (this._targetInactive) {
this._glassPaneElement.textContent = WebInspector.UIString("The tab is inactive");
this._glassPaneElement.classList.remove("hidden");
} else if (WebInspector.targetManager.allTargetsSuspended()) {
this._glassPaneElement.textContent = WebInspector.UIString("Profiling in progress");
this._glassPaneElement.classList.remove("hidden");
} else {
this._glassPaneElement.classList.add("hidden");
}
},
/**
* @param {!Event} event
*/
_handleMouseEvent: function(event)
{
if (this._isGlassPaneActive()) {
event.consume();
return;
}
if (!this._pageScaleFactor)
return;
if (!this._inspectModeConfig || event.type === "mousewheel") {
this._simulateTouchForMouseEvent(event);
event.preventDefault();
if (event.type === "mousedown")
this._canvasElement.focus();
return;
}
var position = this._convertIntoScreenSpace(event);
this._domModel.nodeForLocation(position.x / this._pageScaleFactor + this._scrollOffsetX, position.y / this._pageScaleFactor + this._scrollOffsetY, callback.bind(this));
/**
* @param {?WebInspector.DOMNode} node
* @this {WebInspector.ScreencastView}
*/
function callback(node)
{
if (!node)
return;
if (event.type === "mousemove") {
this.highlightDOMNode(node, this._inspectModeConfig);
this._domModel.nodeHighlightRequested(node.id);
} else if (event.type === "click") {
WebInspector.Revealer.reveal(node);
}
}
},
/**
* @param {!Event} event
*/
_handleKeyEvent: function(event)
{
if (this._isGlassPaneActive()) {
event.consume();
return;
}
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(/** @type {!KeyboardEvent} */ (event));
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event)) {
event.consume();
return;
}
var type;
switch (event.type) {
case "keydown": type = "keyDown"; break;
case "keyup": type = "keyUp"; break;
case "keypress": type = "char"; break;
default: return;
}
var text = event.type === "keypress" ? String.fromCharCode(event.charCode) : undefined;
this._target.inputAgent().invoke_dispatchKeyEvent({
type: type,
modifiers: this._modifiersForEvent(event),
timestamp: event.timeStamp / 1000,
text: text,
unmodifiedText: text ? text.toLowerCase() : undefined,
keyIdentifier: event.keyIdentifier,
code: event.code,
key: event.key,
windowsVirtualKeyCode: event.keyCode,
nativeVirtualKeyCode: event.keyCode,
autoRepeat: false,
isKeypad: false,
isSystemKey: false});
event.consume();
this._canvasElement.focus();
},
/**
* @param {!Event} event
*/
_handleContextMenuEvent: function(event)
{
event.consume(true);
},
/**
* @param {!Event} event
*/
_simulateTouchForMouseEvent: function(event)
{
const buttons = {0: "none", 1: "left", 2: "middle", 3: "right"};
const types = {"mousedown" : "mousePressed", "mouseup": "mouseReleased", "mousemove": "mouseMoved", "mousewheel": "mouseWheel"};
if (!(event.type in types) || !(event.which in buttons))
return;
if (event.type !== "mousewheel" && buttons[event.which] === "none")
return;
if (event.type === "mousedown" || typeof this._eventScreenOffsetTop === "undefined")
this._eventScreenOffsetTop = this._screenOffsetTop;
var modifiers = (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0);
var convertedPosition = this._zoomIntoScreenSpace(event);
convertedPosition.y = Math.round(convertedPosition.y - this._eventScreenOffsetTop);
var params = {type: types[event.type], x: convertedPosition.x, y: convertedPosition.y, modifiers: modifiers, timestamp: event.timeStamp / 1000, button: buttons[event.which], clickCount: 0};
if (event.type === "mousewheel") {
params.deltaX = event.wheelDeltaX / this._screenZoom;
params.deltaY = event.wheelDeltaY / this._screenZoom;
} else {
this._eventParams = params;
}
if (event.type === "mouseup")
delete this._eventScreenOffsetTop;
this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params);
},
/**
* @param {!Event} event
*/
_handleBlurEvent: function(event)
{
if (typeof this._eventScreenOffsetTop !== "undefined") {
var params = this._eventParams;
delete this._eventParams;
params.type = "mouseReleased";
this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params);
}
},
/**
* @param {!Event} event
* @return {!{x: number, y: number}}
*/
_zoomIntoScreenSpace: function(event)
{
var position = {};
position.x = Math.round(event.offsetX / this._screenZoom);
position.y = Math.round(event.offsetY / this._screenZoom);
return position;
},
/**
* @param {!Event} event
* @return {!{x: number, y: number}}
*/
_convertIntoScreenSpace: function(event)
{
var position = this._zoomIntoScreenSpace(event);
position.y = Math.round(position.y - this._screenOffsetTop);
return position;
},
/**
* @param {!Event} event
* @return {number}
*/
_modifiersForEvent: function(event)
{
var modifiers = 0;
if (event.altKey)
modifiers = 1;
if (event.ctrlKey)
modifiers += 2;
if (event.metaKey)
modifiers += 4;
if (event.shiftKey)
modifiers += 8;
return modifiers;
},
onResize: function()
{
if (this._deferredCasting) {
clearTimeout(this._deferredCasting);
delete this._deferredCasting;
}
this._stopCasting();
this._deferredCasting = setTimeout(this._startCasting.bind(this), 100);
},
/**
* @override
* @param {?WebInspector.DOMNode} node
* @param {?DOMAgent.HighlightConfig} config
* @param {!DOMAgent.BackendNodeId=} backendNodeId
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlightDOMNode: function(node, config, backendNodeId, objectId)
{
this._highlightNode = node;
this._highlightConfig = config;
if (!node) {
this._model = null;
this._config = null;
this._node = null;
this._titleElement.classList.add("hidden");
this._repaint();
return;
}
this._node = node;
node.boxModel(callback.bind(this));
/**
* @param {?DOMAgent.BoxModel} model
* @this {WebInspector.ScreencastView}
*/
function callback(model)
{
//fixme GS_MODIFY
if (!model ||Object.keys(model).length==0|| !this._pageScaleFactor) {
this._repaint();
return;
}
this._model = this._scaleModel(model);
this._config = config;
this._repaint();
}
},
/**
* @param {!DOMAgent.BoxModel} model
* @return {!DOMAgent.BoxModel}
*/
_scaleModel: function(model)
{
/**
* @param {!DOMAgent.Quad} quad
* @this {WebInspector.ScreencastView}
*/
function scaleQuad(quad)
{
for (var i = 0; i < quad.length; i += 2) {
quad[i] = quad[i] * this._screenZoom;
quad[i + 1] = (quad[i + 1] + this._screenOffsetTop) * this._screenZoom;
}
}
scaleQuad.call(this, model.content);
scaleQuad.call(this, model.padding);
scaleQuad.call(this, model.border);
scaleQuad.call(this, model.margin);
return model;
},
_repaint: function()
{
var model = this._model;
var config = this._config;
var canvasWidth = this._canvasElement.getBoundingClientRect().width;
var canvasHeight = this._canvasElement.getBoundingClientRect().height;
this._canvasElement.width = window.devicePixelRatio * canvasWidth;
this._canvasElement.height = window.devicePixelRatio * canvasHeight;
this._context.save();
this._context.scale(window.devicePixelRatio, window.devicePixelRatio);
// Paint top and bottom gutter.
this._context.save();
this._context.fillStyle = this._checkerboardPattern;
this._context.fillRect(0, 0, canvasWidth, this._screenOffsetTop * this._screenZoom);
this._context.fillRect(0, this._screenOffsetTop * this._screenZoom + this._imageElement.naturalHeight * this._imageZoom, canvasWidth, canvasHeight);
this._context.restore();
if (model && config) {
this._context.save();
const transparentColor = "rgba(0, 0, 0, 0)";
var quads = [];
if (model.content && config.contentColor !== transparentColor)
quads.push({quad: model.content, color: config.contentColor});
if (model.padding && config.paddingColor !== transparentColor)
quads.push({quad: model.padding, color: config.paddingColor});
if (model.border && config.borderColor !== transparentColor)
quads.push({quad: model.border, color: config.borderColor});
if (model.margin && config.marginColor !== transparentColor)
quads.push({quad: model.margin, color: config.marginColor});
for (var i = quads.length - 1; i > 0; --i)
this._drawOutlinedQuadWithClip(quads[i].quad, quads[i - 1].quad, quads[i].color);
if (quads.length > 0)
this._drawOutlinedQuad(quads[0].quad, quads[0].color);
this._context.restore();
this._drawElementTitle();
this._context.globalCompositeOperation = "destination-over";
}
this._context.drawImage(this._imageElement, 0, this._screenOffsetTop * this._screenZoom, this._imageElement.naturalWidth * this._imageZoom, this._imageElement.naturalHeight * this._imageZoom);
this._context.restore();
},
/**
* @param {!DOMAgent.RGBA} color
* @return {string}
*/
_cssColor: function(color)
{
if (!color)
return "transparent";
return WebInspector.Color.fromRGBA([color.r, color.g, color.b, color.a]).asString(WebInspector.Color.Format.RGBA) || "";
},
/**
* @param {!DOMAgent.Quad} quad
* @return {!CanvasRenderingContext2D}
*/
_quadToPath: function(quad)
{
this._context.beginPath();
this._context.moveTo(quad[0], quad[1]);
this._context.lineTo(quad[2], quad[3]);
this._context.lineTo(quad[4], quad[5]);
this._context.lineTo(quad[6], quad[7]);
this._context.closePath();
return this._context;
},
/**
* @param {!DOMAgent.Quad} quad
* @param {!DOMAgent.RGBA} fillColor
*/
_drawOutlinedQuad: function(quad, fillColor)
{
this._context.save();
this._context.lineWidth = 2;
this._quadToPath(quad).clip();
this._context.fillStyle = this._cssColor(fillColor);
this._context.fill();
this._context.restore();
},
/**
* @param {!DOMAgent.Quad} quad
* @param {!DOMAgent.Quad} clipQuad
* @param {!DOMAgent.RGBA} fillColor
*/
_drawOutlinedQuadWithClip: function (quad, clipQuad, fillColor)
{
this._context.fillStyle = this._cssColor(fillColor);
this._context.save();
this._context.lineWidth = 0;
this._quadToPath(quad).fill();
this._context.globalCompositeOperation = "destination-out";
this._context.fillStyle = "red";
this._quadToPath(clipQuad).fill();
this._context.restore();
},
_drawElementTitle: function()
{
if (!this._node)
return;
var canvasWidth = this._canvasElement.getBoundingClientRect().width;
var canvasHeight = this._canvasElement.getBoundingClientRect().height;
var lowerCaseName = this._node.localName() || this._node.nodeName().toLowerCase();
this._tagNameElement.textContent = lowerCaseName;
this._nodeIdElement.textContent = this._node.getAttribute("id") ? "#" + this._node.getAttribute("id") : "";
this._nodeIdElement.textContent = this._node.getAttribute("id") ? "#" + this._node.getAttribute("id") : "";
var className = this._node.getAttribute("class");
if (className && className.length > 50)
className = className.substring(0, 50) + "\u2026";
this._classNameElement.textContent = className || "";
this._nodeWidthElement.textContent = this._model.width;
this._nodeHeightElement.textContent = this._model.height;
this._titleElement.classList.remove("hidden");
var titleWidth = this._titleElement.offsetWidth + 6;
var titleHeight = this._titleElement.offsetHeight + 4;
var anchorTop = this._model.margin[1];
var anchorBottom = this._model.margin[7];
const arrowHeight = 7;
var renderArrowUp = false;
var renderArrowDown = false;
var boxX = Math.max(2, this._model.margin[0]);
if (boxX + titleWidth > canvasWidth)
boxX = canvasWidth - titleWidth - 2;
var boxY;
if (anchorTop > canvasHeight) {
boxY = canvasHeight - titleHeight - arrowHeight;
renderArrowDown = true;
} else if (anchorBottom < 0) {
boxY = arrowHeight;
renderArrowUp = true;
} else if (anchorBottom + titleHeight + arrowHeight < canvasHeight) {
boxY = anchorBottom + arrowHeight - 4;
renderArrowUp = true;
} else if (anchorTop - titleHeight - arrowHeight > 0) {
boxY = anchorTop - titleHeight - arrowHeight + 3;
renderArrowDown = true;
} else
boxY = arrowHeight;
this._context.save();
this._context.translate(0.5, 0.5);
this._context.beginPath();
this._context.moveTo(boxX, boxY);
if (renderArrowUp) {
this._context.lineTo(boxX + 2 * arrowHeight, boxY);
this._context.lineTo(boxX + 3 * arrowHeight, boxY - arrowHeight);
this._context.lineTo(boxX + 4 * arrowHeight, boxY);
}
this._context.lineTo(boxX + titleWidth, boxY);
this._context.lineTo(boxX + titleWidth, boxY + titleHeight);
if (renderArrowDown) {
this._context.lineTo(boxX + 4 * arrowHeight, boxY + titleHeight);
this._context.lineTo(boxX + 3 * arrowHeight, boxY + titleHeight + arrowHeight);
this._context.lineTo(boxX + 2 * arrowHeight, boxY + titleHeight);
}
this._context.lineTo(boxX, boxY + titleHeight);
this._context.closePath();
this._context.fillStyle = "rgb(255, 255, 194)";
this._context.fill();
this._context.strokeStyle = "rgb(128, 128, 128)";
this._context.stroke();
this._context.restore();
this._titleElement.style.top = (boxY + 3) + "px";
this._titleElement.style.left = (boxX + 3) + "px";
},
/**
* @return {!{width: number, height: number}}
*/
_viewportDimensions: function()
{
const gutterSize = 30;
const bordersSize = WebInspector.ScreencastView._bordersSize;
var width = this.element.offsetWidth - bordersSize - gutterSize;
var height = this.element.offsetHeight - bordersSize - gutterSize - WebInspector.ScreencastView._navBarHeight;
return { width: width, height: height };
},
/**
* @override
* @param {!DOMAgent.InspectMode} mode
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
setInspectMode: function(mode, config, callback)
{
this._inspectModeConfig = mode !== DOMAgent.InspectMode.None ? config : null;
if (callback)
callback(null);
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
highlightFrame: function(frameId)
{
},
/**
* @param {!CanvasRenderingContext2D} context
*/
_createCheckerboardPattern: function(context)
{
var pattern = /** @type {!HTMLCanvasElement} */(createElement("canvas"));
const size = 32;
pattern.width = size * 2;
pattern.height = size * 2;
var pctx = pattern.getContext("2d");
pctx.fillStyle = "rgb(195, 195, 195)";
pctx.fillRect(0, 0, size * 2, size * 2);
pctx.fillStyle = "rgb(225, 225, 225)";
pctx.fillRect(0, 0, size, size);
pctx.fillRect(size, size, size, size);
return context.createPattern(pattern, "repeat");
},
_createNavigationBar: function()
{
this._navigationBar = this.element.createChild("div", "toolbar-background screencast-navigation");
if (Runtime.queryParam("hideNavigation"))
this._navigationBar.classList.add("hidden");
this._navigationBack = this._navigationBar.createChild("button", "back");
this._navigationBack.disabled = true;
this._navigationBack.addEventListener("click", this._navigateToHistoryEntry.bind(this, -1), false);
this._navigationForward = this._navigationBar.createChild("button", "forward");
this._navigationForward.disabled = true;
this._navigationForward.addEventListener("click", this._navigateToHistoryEntry.bind(this, 1), false);
this._navigationReload = this._navigationBar.createChild("button", "reload");
this._navigationReload.addEventListener("click", this._navigateReload.bind(this), false);
this._navigationUrl = this._navigationBar.createChild("input");
this._navigationUrl.type = "text";
this._navigationUrl.addEventListener('keyup', this._navigationUrlKeyUp.bind(this), true);
this._navigationProgressBar = new WebInspector.ScreencastView.ProgressTracker(this._navigationBar.createChild("div", "progress"));
this._requestNavigationHistory();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged, this._requestNavigationHistory, this);
},
_navigateToHistoryEntry: function(offset)
{
var newIndex = this._historyIndex + offset;
if (newIndex < 0 || newIndex >= this._historyEntries.length)
return;
this._target.pageAgent().navigateToHistoryEntry(this._historyEntries[newIndex].id);
this._requestNavigationHistory();
},
_navigateReload: function()
{
this._target.resourceTreeModel.reloadPage();
},
_navigationUrlKeyUp: function(event)
{
if (event.keyIdentifier != 'Enter')
return;
var url = this._navigationUrl.value;
if (!url)
return;
if (!url.match(WebInspector.ScreencastView._SchemeRegex))
url = "http://" + url;
this._target.pageAgent().navigate(url);
this._canvasElement.focus();
},
_requestNavigationHistory: function()
{
this._target.pageAgent().getNavigationHistory(this._onNavigationHistory.bind(this));
},
_onNavigationHistory: function(error, currentIndex, entries)
{
//fixme GS_MODIFY
if (error||!entries)
return;
this._historyIndex = currentIndex;
this._historyEntries = entries;
this._navigationBack.disabled = currentIndex == 0;
this._navigationForward.disabled = currentIndex == (entries.length - 1);
var url = entries[currentIndex].url;
var match = url.match(WebInspector.ScreencastView._HttpRegex);
if (match)
url = match[1];
InspectorFrontendHost.inspectedURLChanged(url);
this._navigationUrl.value = url;
},
_focusNavigationBar: function()
{
this._navigationUrl.focus();
this._navigationUrl.select();
return true;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @param {!Element} element
* @constructor
*/
WebInspector.ScreencastView.ProgressTracker = function(element)
{
this._element = element;
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.Load, this._onLoad, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
}
WebInspector.ScreencastView.ProgressTracker.prototype = {
_onMainFrameNavigated: function()
{
this._requestIds = {};
this._startedRequests = 0;
this._finishedRequests = 0;
this._maxDisplayedProgress = 0;
this._updateProgress(0.1); // Display first 10% on navigation start.
},
_onLoad: function()
{
delete this._requestIds;
this._updateProgress(1); // Display 100% progress on load, hide it in 0.5s.
setTimeout(function() {
if (!this._navigationProgressVisible())
this._displayProgress(0);
}.bind(this), 500);
},
_navigationProgressVisible: function()
{
return !!this._requestIds;
},
_onRequestStarted: function(event)
{
if (!this._navigationProgressVisible())
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
// Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
if (request.type === WebInspector.resourceTypes.WebSocket)
return;
this._requestIds[request.requestId] = request;
++this._startedRequests;
},
_onRequestFinished: function(event)
{
if (!this._navigationProgressVisible())
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
if (!(request.requestId in this._requestIds))
return;
++this._finishedRequests;
setTimeout(function() {
this._updateProgress(this._finishedRequests / this._startedRequests * 0.9); // Finished requests drive the progress up to 90%.
}.bind(this), 500); // Delay to give the new requests time to start. This makes the progress smoother.
},
_updateProgress: function(progress)
{
if (!this._navigationProgressVisible())
return;
if (this._maxDisplayedProgress >= progress)
return;
this._maxDisplayedProgress = progress;
this._displayProgress(progress);
},
_displayProgress: function(progress)
{
this._element.style.width = (100 * progress) + "%";
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ApplicationCacheModel.js | 2.94% | (2 / 68) | 0% | (0 / 28) | 0% | (0 / 18) | 2.94% | (2 / 68) | |
| CPUProfileDataModel.js | 3.24% | (8 / 247) | 0% | (0 / 74) | 0% | (0 / 18) | 3.27% | (8 / 245) | |
| CPUProfilerModel.js | 6.9% | (2 / 29) | 0% | (0 / 6) | 0% | (0 / 10) | 6.9% | (2 / 29) | |
| CSSMatchedStyles.js | 2.54% | (5 / 197) | 0% | (0 / 117) | 0% | (0 / 22) | 2.56% | (5 / 195) | |
| CSSMedia.js | 1.28% | (1 / 78) | 0% | (0 / 41) | 0% | (0 / 22) | 1.28% | (1 / 78) | |
| CSSMetadata.js | 0.71% | (1 / 141) | 0% | (0 / 81) | 0% | (0 / 20) | 0.71% | (1 / 141) | |
| CSSModel.js | 6.48% | (25 / 386) | 0% | (0 / 186) | 0% | (0 / 83) | 6.49% | (25 / 385) | |
| CSSParser.js | 3.37% | (3 / 89) | 0% | (0 / 17) | 0% | (0 / 21) | 3.41% | (3 / 88) | |
| CSSProperty.js | 4.21% | (4 / 95) | 0% | (0 / 80) | 0% | (0 / 14) | 4.21% | (4 / 95) | |
| CSSRule.js | 1.01% | (1 / 99) | 0% | (0 / 42) | 0% | (0 / 26) | 1.02% | (1 / 98) | |
| CSSStyleDeclaration.js | 1.72% | (2 / 116) | 0% | (0 / 60) | 0% | (0 / 21) | 1.72% | (2 / 116) | |
| CSSStyleSheetHeader.js | 5.26% | (2 / 38) | 0% | (0 / 12) | 0% | (0 / 14) | 5.26% | (2 / 38) | |
| ConsoleModel.js | 2.37% | (4 / 169) | 0% | (0 / 120) | 0% | (0 / 39) | 2.37% | (4 / 169) | |
| ContentProviders.js | 13.04% | (3 / 23) | 0% | (0 / 4) | 0% | (0 / 7) | 13.64% | (3 / 22) | |
| CookieParser.js | 1.55% | (2 / 129) | 0% | (0 / 65) | 0% | (0 / 36) | 1.55% | (2 / 129) | |
| DOMModel.js | 4.63% | (31 / 670) | 0% | (0 / 322) | 0% | (0 / 187) | 4.63% | (31 / 670) | |
| DebuggerModel.js | 3.69% | (14 / 379) | 0% | (0 / 193) | 0% | (0 / 101) | 3.69% | (14 / 379) | |
| HAREntry.js | 2.08% | (2 / 96) | 0% | (0 / 69) | 0% | (0 / 24) | 2.08% | (2 / 96) | |
| HeapProfilerModel.js | 4.17% | (1 / 24) | 0% | (0 / 2) | 0% | (0 / 13) | 4.17% | (1 / 24) | |
| InspectorBackend.js | 6.43% | (16 / 249) | 0% | (0 / 114) | 0% | (0 / 54) | 6.48% | (16 / 247) | |
| InspectorBackendHostedMode.js | 4% | (3 / 75) | 0% | (0 / 40) | 0% | (0 / 4) | 4% | (3 / 75) | |
| NetworkLog.js | 1.92% | (1 / 52) | 0% | (0 / 12) | 0% | (0 / 12) | 1.92% | (1 / 52) | |
| NetworkManager.js | 1.31% | (4 / 306) | 0% | (0 / 133) | 0% | (0 / 54) | 1.31% | (4 / 306) | |
| NetworkRequest.js | 0.87% | (3 / 344) | 0% | (0 / 167) | 0% | (0 / 111) | 0.88% | (3 / 342) | |
| PaintProfiler.js | 6.45% | (2 / 31) | 0% | (0 / 10) | 0% | (0 / 10) | 6.67% | (2 / 30) | |
| RemoteObject.js | 8.05% | (38 / 472) | 0% | (0 / 250) | 0% | (0 / 129) | 8.09% | (38 / 470) | |
| Resource.js | 7.45% | (7 / 94) | 0% | (0 / 52) | 0% | (0 / 31) | 7.53% | (7 / 93) | |
| ResourceTreeModel.js | 1.11% | (3 / 271) | 0% | (0 / 122) | 0% | (0 / 72) | 1.11% | (3 / 271) | |
| RuntimeModel.js | 5.22% | (12 / 230) | 0% | (0 / 141) | 0% | (0 / 49) | 5.22% | (12 / 230) | |
| Script.js | 6.52% | (6 / 92) | 0% | (0 / 40) | 0% | (0 / 23) | 6.59% | (6 / 91) | |
| ServiceWorkerCacheModel.js | 5.94% | (6 / 101) | 0% | (0 / 22) | 0% | (0 / 27) | 5.94% | (6 / 101) | |
| ServiceWorkerManager.js | 0.88% | (2 / 227) | 0% | (0 / 62) | 0% | (0 / 70) | 0.88% | (2 / 227) | |
| SourceMap.js | 4.15% | (8 / 193) | 0% | (0 / 80) | 0% | (0 / 41) | 4.17% | (8 / 192) | |
| Target.js | 2.13% | (1 / 47) | 0% | (0 / 8) | 0% | (0 / 23) | 2.13% | (1 / 47) | |
| TargetManager.js | 0.72% | (1 / 139) | 0% | (0 / 57) | 0% | (0 / 25) | 0.72% | (1 / 139) | |
| TracingManager.js | 2.27% | (1 / 44) | 0% | (0 / 13) | 0% | (0 / 17) | 2.27% | (1 / 44) | |
| TracingModel.js | 0.93% | (3 / 321) | 0% | (0 / 148) | 0% | (0 / 67) | 0.93% | (3 / 321) | |
| WorkerManager.js | 1.61% | (1 / 62) | 0% | (0 / 16) | 0% | (0 / 18) | 1.61% | (1 / 62) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | 2 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
*/
WebInspector.ApplicationCacheModel = function(target)
{
WebInspector.SDKObject.call(this, target);
target.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
this._agent = target.applicationCacheAgent();
this._agent.enable();
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
this._statuses = {};
this._manifestURLsByFrame = {};
this._mainFrameNavigated();
this._onLine = true;
}
WebInspector.ApplicationCacheModel.EventTypes = {
FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
FrameManifestAdded: "FrameManifestAdded",
FrameManifestRemoved: "FrameManifestRemoved",
NetworkStateChanged: "NetworkStateChanged"
}
WebInspector.ApplicationCacheModel.prototype = {
_frameNavigated: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
if (frame.isMainFrame()) {
this._mainFrameNavigated();
return;
}
this._agent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
},
/**
* @param {!WebInspector.Event} event
*/
_frameDetached: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
this._frameManifestRemoved(frame.id);
},
_mainFrameNavigated: function()
{
this._agent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
},
/**
* @param {string} frameId
* @param {?Protocol.Error} error
* @param {string} manifestURL
*/
_manifestForFrameLoaded: function(frameId, error, manifestURL)
{
if (error) {
console.error(error);
return;
}
if (!manifestURL)
this._frameManifestRemoved(frameId);
},
/**
* @param {?Protocol.Error} error
* @param {!Array.<!ApplicationCacheAgent.FrameWithManifest>} framesWithManifests
*/
_framesWithManifestsLoaded: function(error, framesWithManifests)
{
if (error) {
console.error(error);
return;
}
for (var i = 0; i < framesWithManifests.length; ++i)
this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
},
/**
* @param {string} frameId
* @param {string} manifestURL
* @param {number} status
*/
_frameManifestUpdated: function(frameId, manifestURL, status)
{
if (status === applicationCache.UNCACHED) {
this._frameManifestRemoved(frameId);
return;
}
if (!manifestURL)
return;
if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
this._frameManifestRemoved(frameId);
var statusChanged = this._statuses[frameId] !== status;
this._statuses[frameId] = status;
if (!this._manifestURLsByFrame[frameId]) {
this._manifestURLsByFrame[frameId] = manifestURL;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
}
if (statusChanged)
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
},
/**
* @param {string} frameId
*/
_frameManifestRemoved: function(frameId)
{
if (!this._manifestURLsByFrame[frameId])
return;
delete this._manifestURLsByFrame[frameId];
delete this._statuses[frameId];
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
},
/**
* @param {string} frameId
* @return {string}
*/
frameManifestURL: function(frameId)
{
return this._manifestURLsByFrame[frameId] || "";
},
/**
* @param {string} frameId
* @return {number}
*/
frameManifestStatus: function(frameId)
{
return this._statuses[frameId] || applicationCache.UNCACHED;
},
/**
* @return {boolean}
*/
get onLine()
{
return this._onLine;
},
/**
* @param {string} frameId
* @param {string} manifestURL
* @param {number} status
*/
_statusUpdated: function(frameId, manifestURL, status)
{
this._frameManifestUpdated(frameId, manifestURL, status);
},
/**
* @param {string} frameId
* @param {function(?ApplicationCacheAgent.ApplicationCache)} callback
*/
requestApplicationCache: function(frameId, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!ApplicationCacheAgent.ApplicationCache} applicationCache
*/
function callbackWrapper(error, applicationCache)
{
if (error) {
console.error(error);
callback(null);
return;
}
callback(applicationCache);
}
this._agent.getApplicationCacheForFrame(frameId, callbackWrapper);
},
/**
* @param {boolean} isNowOnline
*/
_networkStateUpdated: function(isNowOnline)
{
this._onLine = isNowOnline;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @implements {ApplicationCacheAgent.Dispatcher}
*/
WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
{
this._applicationCacheModel = applicationCacheModel;
}
WebInspector.ApplicationCacheDispatcher.prototype = {
/**
* @override
* @param {string} frameId
* @param {string} manifestURL
* @param {number} status
*/
applicationCacheStatusUpdated: function(frameId, manifestURL, status)
{
this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
},
/**
* @override
* @param {boolean} isNowOnline
*/
networkStateUpdated: function(isNowOnline)
{
this._applicationCacheModel._networkStateUpdated(isNowOnline);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | 2 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!ProfilerAgent.CPUProfile} profile
*/
WebInspector.CPUProfileDataModel = function(profile)
{
this.profileHead = profile.head;
this.samples = profile.samples;
this.timestamps = profile.timestamps;
this.profileStartTime = profile.startTime * 1000;
this.profileEndTime = profile.endTime * 1000;
this._assignParentsInProfile();
if (this.samples) {
this._sortSamples();
this._normalizeTimestamps();
this._buildIdToNodeMap();
this._fixMissingSamples();
}
if (!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get())
this._filterNativeFrames();
this._assignDepthsInProfile();
this._calculateTimes(profile);
}
WebInspector.CPUProfileDataModel.prototype = {
/**
* @param {!ProfilerAgent.CPUProfile} profile
*/
_calculateTimes: function(profile)
{
function totalHitCount(node) {
var result = node.hitCount;
for (var i = 0; i < node.children.length; i++)
result += totalHitCount(node.children[i]);
return result;
}
profile.totalHitCount = totalHitCount(profile.head);
this.totalHitCount = profile.totalHitCount;
var duration = this.profileEndTime - this.profileStartTime;
var samplingInterval = duration / profile.totalHitCount;
this.samplingInterval = samplingInterval;
function calculateTimesForNode(node) {
node.selfTime = node.hitCount * samplingInterval;
var totalHitCount = node.hitCount;
for (var i = 0; i < node.children.length; i++)
totalHitCount += calculateTimesForNode(node.children[i]);
node.totalTime = totalHitCount * samplingInterval;
return totalHitCount;
}
calculateTimesForNode(profile.head);
},
_filterNativeFrames: function()
{
if (this.samples) {
for (var i = 0; i < this.samples.length; ++i) {
var node = this.nodeByIndex(i);
while (isNativeNode(node))
node = node.parent;
this.samples[i] = node.id;
}
}
processSubtree(this.profileHead);
/**
* @param {!ProfilerAgent.CPUProfileNode} node
* @return {boolean}
*/
function isNativeNode(node)
{
return !!node.url && node.url.startsWith("native ");
}
/**
* @param {!ProfilerAgent.CPUProfileNode} node
*/
function processSubtree(node)
{
var nativeChildren = [];
var children = node.children;
for (var i = 0, j = 0; i < children.length; ++i) {
var child = children[i];
if (isNativeNode(child)) {
nativeChildren.push(child);
} else {
children[j++] = child;
processSubtree(child);
}
}
children.length = j;
nativeChildren.forEach(mergeChildren.bind(null, node));
}
/**
* @param {!ProfilerAgent.CPUProfileNode} node
* @param {!ProfilerAgent.CPUProfileNode} nativeNode
*/
function mergeChildren(node, nativeNode)
{
node.hitCount += nativeNode.hitCount;
for (var i = 0; i < nativeNode.children.length; ++i) {
var child = nativeNode.children[i];
if (isNativeNode(child)) {
mergeChildren(node, child);
} else {
node.children.push(child);
child.parent = node;
processSubtree(child);
}
}
}
},
_assignParentsInProfile: function()
{
var head = this.profileHead;
head.parent = null;
var nodesToTraverse = [ head ];
while (nodesToTraverse.length) {
var parent = nodesToTraverse.pop();
var children = parent.children;
var length = children.length;
for (var i = 0; i < length; ++i) {
var child = children[i];
child.parent = parent;
if (child.children.length)
nodesToTraverse.push(child);
}
}
},
_assignDepthsInProfile: function()
{
var head = this.profileHead;
head.depth = -1;
this.maxDepth = 0;
var nodesToTraverse = [ head ];
while (nodesToTraverse.length) {
var parent = nodesToTraverse.pop();
var depth = parent.depth + 1;
if (depth > this.maxDepth)
this.maxDepth = depth;
var children = parent.children;
var length = children.length;
for (var i = 0; i < length; ++i) {
var child = children[i];
child.depth = depth;
if (child.children.length)
nodesToTraverse.push(child);
}
}
},
_sortSamples: function()
{
var timestamps = this.timestamps;
if (!timestamps)
return;
var samples = this.samples;
var indices = timestamps.map((x, index) => index);
indices.sort((a, b) => timestamps[a] - timestamps[b]);
for (var i = 0; i < timestamps.length; ++i) {
var index = indices[i];
if (index === i)
continue;
// Move items in a cycle.
var savedTimestamp = timestamps[i];
var savedSample = samples[i];
var currentIndex = i;
while (index !== i) {
samples[currentIndex] = samples[index];
timestamps[currentIndex] = timestamps[index];
currentIndex = index;
index = indices[index];
indices[currentIndex] = currentIndex;
}
samples[currentIndex] = savedSample;
timestamps[currentIndex] = savedTimestamp;
}
},
_normalizeTimestamps: function()
{
var timestamps = this.timestamps;
if (!timestamps) {
// Support loading old CPU profiles that are missing timestamps.
// Derive timestamps from profile start and stop times.
var profileStartTime = this.profileStartTime;
var interval = (this.profileEndTime - profileStartTime) / this.samples.length;
timestamps = new Float64Array(this.samples.length + 1);
for (var i = 0; i < timestamps.length; ++i)
timestamps[i] = profileStartTime + i * interval;
this.timestamps = timestamps;
return;
}
// Convert samples from usec to msec
for (var i = 0; i < timestamps.length; ++i)
timestamps[i] /= 1000;
var averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1);
// Add an extra timestamp used to calculate the last sample duration.
this.timestamps.push(timestamps.peekLast() + averageSample);
this.profileStartTime = timestamps[0];
this.profileEndTime = timestamps.peekLast();
},
_buildIdToNodeMap: function()
{
/** @type {!Object.<number, !ProfilerAgent.CPUProfileNode>} */
this._idToNode = {};
var idToNode = this._idToNode;
var stack = [this.profileHead];
while (stack.length) {
var node = stack.pop();
idToNode[node.id] = node;
for (var i = 0; i < node.children.length; i++)
stack.push(node.children[i]);
}
var topLevelNodes = this.profileHead.children;
for (var i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {
var node = topLevelNodes[i];
if (node.functionName === "(garbage collector)")
this.gcNode = node;
else if (node.functionName === "(program)")
this.programNode = node;
else if (node.functionName === "(idle)")
this.idleNode = node;
}
},
_fixMissingSamples: function()
{
// Sometimes sampler is not able to parse the JS stack and returns
// a (program) sample instead. The issue leads to call frames belong
// to the same function invocation being split apart.
// Here's a workaround for that. When there's a single (program) sample
// between two call stacks sharing the same bottom node, it is replaced
// with the preceeding sample.
var samples = this.samples;
var samplesCount = samples.length;
if (!this.programNode || samplesCount < 3)
return;
var idToNode = this._idToNode;
var programNodeId = this.programNode.id;
var gcNodeId = this.gcNode ? this.gcNode.id : -1;
var idleNodeId = this.idleNode ? this.idleNode.id : -1;
var prevNodeId = samples[0];
var nodeId = samples[1];
for (var sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {
var nextNodeId = samples[sampleIndex + 1];
if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId)
&& bottomNode(idToNode[prevNodeId]) === bottomNode(idToNode[nextNodeId])) {
samples[sampleIndex] = prevNodeId;
}
prevNodeId = nodeId;
nodeId = nextNodeId;
}
/**
* @param {!ProfilerAgent.CPUProfileNode} node
* @return {!ProfilerAgent.CPUProfileNode}
*/
function bottomNode(node)
{
while (node.parent.parent)
node = node.parent;
return node;
}
/**
* @param {number} nodeId
* @return {boolean}
*/
function isSystemNode(nodeId)
{
return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;
}
},
/**
* @param {function(number, !ProfilerAgent.CPUProfileNode, number)} openFrameCallback
* @param {function(number, !ProfilerAgent.CPUProfileNode, number, number, number)} closeFrameCallback
* @param {number=} startTime
* @param {number=} stopTime
*/
forEachFrame: function(openFrameCallback, closeFrameCallback, startTime, stopTime)
{
if (!this.profileHead)
return;
startTime = startTime || 0;
stopTime = stopTime || Infinity;
var samples = this.samples;
var timestamps = this.timestamps;
var idToNode = this._idToNode;
var gcNode = this.gcNode;
var samplesCount = samples.length;
var startIndex = timestamps.lowerBound(startTime);
var stackTop = 0;
var stackNodes = [];
var prevId = this.profileHead.id;
var sampleTime = timestamps[samplesCount];
var gcParentNode = null;
if (!this._stackStartTimes)
this._stackStartTimes = new Float64Array(this.maxDepth + 2);
var stackStartTimes = this._stackStartTimes;
if (!this._stackChildrenDuration)
this._stackChildrenDuration = new Float64Array(this.maxDepth + 2);
var stackChildrenDuration = this._stackChildrenDuration;
for (var sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {
sampleTime = timestamps[sampleIndex];
if (sampleTime >= stopTime)
break;
var id = samples[sampleIndex];
if (id === prevId)
continue;
var node = idToNode[id];
var prevNode = idToNode[prevId];
if (node === gcNode) {
// GC samples have no stack, so we just put GC node on top of the last recorded sample.
gcParentNode = prevNode;
openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);
stackStartTimes[++stackTop] = sampleTime;
stackChildrenDuration[stackTop] = 0;
prevId = id;
continue;
}
if (prevNode === gcNode) {
// end of GC frame
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
prevNode = gcParentNode;
prevId = prevNode.id;
gcParentNode = null;
}
while (node.depth > prevNode.depth) {
stackNodes.push(node);
node = node.parent;
}
// Go down to the LCA and close current intervals.
while (prevNode !== node) {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
if (node.depth === prevNode.depth) {
stackNodes.push(node);
node = node.parent;
}
prevNode = prevNode.parent;
}
// Go up the nodes stack and open new intervals.
while (stackNodes.length) {
node = stackNodes.pop();
openFrameCallback(node.depth, node, sampleTime);
stackStartTimes[++stackTop] = sampleTime;
stackChildrenDuration[stackTop] = 0;
}
prevId = id;
}
if (idToNode[prevId] === gcNode) {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
}
for (var node = idToNode[prevId]; node.parent; node = node.parent) {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
}
},
/**
* @param {number} index
* @return {!ProfilerAgent.CPUProfileNode}
*/
nodeByIndex: function(index)
{
return this._idToNode[this.samples[index]];
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | 2 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
* @implements {ProfilerAgent.Dispatcher}
*/
WebInspector.CPUProfilerModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.CPUProfilerModel, target);
this._isRecording = false;
target.registerProfilerDispatcher(this);
target.profilerAgent().enable();
this._configureCpuProfilerSamplingInterval();
WebInspector.moduleSetting("highResolutionCpuProfiling").addChangeListener(this._configureCpuProfilerSamplingInterval, this);
}
/** @enum {symbol} */
WebInspector.CPUProfilerModel.EventTypes = {
ConsoleProfileStarted: Symbol("ConsoleProfileStarted"),
ConsoleProfileFinished: Symbol("ConsoleProfileFinished")
};
/** @typedef {!{id: string, scriptLocation: !WebInspector.DebuggerModel.Location, title: (string|undefined), cpuProfile: (!ProfilerAgent.CPUProfile|undefined)}} */
WebInspector.CPUProfilerModel.EventData;
WebInspector.CPUProfilerModel.prototype = {
_configureCpuProfilerSamplingInterval: function()
{
var intervalUs = WebInspector.moduleSetting("highResolutionCpuProfiling").get() ? 100 : 1000;
this.target().profilerAgent().setSamplingInterval(intervalUs);
},
/**
* @override
* @param {string} id
* @param {!DebuggerAgent.Location} scriptLocation
* @param {string=} title
*/
consoleProfileStarted: function(id, scriptLocation, title)
{
this._dispatchProfileEvent(WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileStarted, id, scriptLocation, title);
},
/**
* @override
* @param {string} id
* @param {!DebuggerAgent.Location} scriptLocation
* @param {!ProfilerAgent.CPUProfile} cpuProfile
* @param {string=} title
*/
consoleProfileFinished: function(id, scriptLocation, cpuProfile, title)
{
this._dispatchProfileEvent(WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileFinished, id, scriptLocation, title, cpuProfile);
},
/**
* @param {symbol} eventName
* @param {string} id
* @param {!DebuggerAgent.Location} scriptLocation
* @param {string=} title
* @param {!ProfilerAgent.CPUProfile=} cpuProfile
*/
_dispatchProfileEvent: function(eventName, id, scriptLocation, title, cpuProfile)
{
// Make sure ProfilesPanel is initialized and CPUProfileType is created.
self.runtime.loadModulePromise("profiler").then(_ => {
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (WebInspector.DebuggerModel.fromTarget(this.target()));
var debuggerLocation = WebInspector.DebuggerModel.Location.fromPayload(debuggerModel, scriptLocation);
var globalId = this.target().id() + "." + id;
var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ ({id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title});
this.dispatchEventToListeners(eventName, data);
});
},
/**
* @return {boolean}
*/
isRecordingProfile: function()
{
return this._isRecording;
},
startRecording: function()
{
this._isRecording = true;
this.target().profilerAgent().start();
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesCPUProfileTaken);
},
/**
* @return {!Promise.<?ProfilerAgent.CPUProfile>}
*/
stopRecording: function()
{
/**
* @param {?Protocol.Error} error
* @param {?ProfilerAgent.CPUProfile} profile
* @return {?ProfilerAgent.CPUProfile}
*/
function extractProfile(error, profile)
{
return !error && profile ? profile : null;
}
this._isRecording = false;
return this.target().profilerAgent().stop(extractProfile);
},
dispose: function()
{
WebInspector.moduleSetting("highResolutionCpuProfiling").removeChangeListener(this._configureCpuProfilerSamplingInterval, this);
},
__proto__: WebInspector.SDKModel.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | 2 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {!WebInspector.DOMNode} node
* @param {?CSSAgent.CSSStyle} inlinePayload
* @param {?CSSAgent.CSSStyle} attributesPayload
* @param {!Array.<!CSSAgent.RuleMatch>} matchedPayload
* @param {!Array.<!CSSAgent.PseudoElementMatches>} pseudoPayload
* @param {!Array.<!CSSAgent.InheritedStyleEntry>} inheritedPayload
* @param {!Array.<!CSSAgent.CSSKeyframesRule>} animationsPayload
*/
WebInspector.CSSMatchedStyles = function(cssModel, node, inlinePayload, attributesPayload, matchedPayload, pseudoPayload, inheritedPayload, animationsPayload)
{
this._cssModel = cssModel;
this._node = node;
this._nodeStyles = [];
this._nodeForStyle = new Map();
this._inheritedStyles = new Set();
this._keyframes = [];
/** @type {!Map<!DOMAgent.NodeId, !Map<string, boolean>>} */
this._matchingSelectors = new Map();
/**
* @this {WebInspector.CSSMatchedStyles}
*/
function addAttributesStyle()
{
if (!attributesPayload)
return;
var style = new WebInspector.CSSStyleDeclaration(cssModel, null, attributesPayload, WebInspector.CSSStyleDeclaration.Type.Attributes);
this._nodeForStyle.set(style, this._node);
this._nodeStyles.push(style);
}
// Inline style has the greatest specificity.
if (inlinePayload && this._node.nodeType() === Node.ELEMENT_NODE) {
var style = new WebInspector.CSSStyleDeclaration(cssModel, null, inlinePayload, WebInspector.CSSStyleDeclaration.Type.Inline);
this._nodeForStyle.set(style, this._node);
this._nodeStyles.push(style);
}
// Add rules in reverse order to match the cascade order.
var addedAttributesStyle;
for (var i = matchedPayload.length - 1; i >= 0; --i) {
var rule = new WebInspector.CSSStyleRule(cssModel, matchedPayload[i].rule);
if ((rule.isInjected() || rule.isUserAgent()) && !addedAttributesStyle) {
// Show element's Style Attributes after all author rules.
addedAttributesStyle = true;
addAttributesStyle.call(this);
}
this._nodeForStyle.set(rule.style, this._node);
this._nodeStyles.push(rule.style);
addMatchingSelectors.call(this, this._node, rule, matchedPayload[i].matchingSelectors);
}
if (!addedAttributesStyle)
addAttributesStyle.call(this);
// Walk the node structure and identify styles with inherited properties.
var parentNode = this._node.parentNode;
for (var i = 0; parentNode && inheritedPayload && i < inheritedPayload.length; ++i) {
var entryPayload = inheritedPayload[i];
var inheritedInlineStyle = entryPayload.inlineStyle ? new WebInspector.CSSStyleDeclaration(cssModel, null, entryPayload.inlineStyle, WebInspector.CSSStyleDeclaration.Type.Inline) : null;
if (inheritedInlineStyle && this._containsInherited(inheritedInlineStyle)) {
this._nodeForStyle.set(inheritedInlineStyle, parentNode);
this._nodeStyles.push(inheritedInlineStyle);
this._inheritedStyles.add(inheritedInlineStyle);
}
var inheritedMatchedCSSRules = entryPayload.matchedCSSRules || [];
for (var j = inheritedMatchedCSSRules.length - 1; j >= 0; --j) {
var inheritedRule = new WebInspector.CSSStyleRule(cssModel, inheritedMatchedCSSRules[j].rule);
addMatchingSelectors.call(this, parentNode, inheritedRule, inheritedMatchedCSSRules[j].matchingSelectors);
if (!this._containsInherited(inheritedRule.style))
continue;
this._nodeForStyle.set(inheritedRule.style, parentNode);
this._nodeStyles.push(inheritedRule.style);
this._inheritedStyles.add(inheritedRule.style);
}
parentNode = parentNode.parentNode;
}
// Set up pseudo styles map.
this._pseudoStyles = new Map();
if (pseudoPayload) {
for (var i = 0; i < pseudoPayload.length; ++i) {
var entryPayload = pseudoPayload[i];
// PseudoElement nodes are not created unless "content" css property is set.
var pseudoElement = this._node.pseudoElements().get(entryPayload.pseudoType) || null;
var pseudoStyles = [];
var rules = entryPayload.matches || [];
for (var j = rules.length - 1; j >= 0; --j) {
var pseudoRule = new WebInspector.CSSStyleRule(cssModel, rules[j].rule);
pseudoStyles.push(pseudoRule.style);
this._nodeForStyle.set(pseudoRule.style, pseudoElement);
if (pseudoElement)
addMatchingSelectors.call(this, pseudoElement, pseudoRule, rules[j].matchingSelectors);
}
this._pseudoStyles.set(entryPayload.pseudoType, pseudoStyles);
}
}
if (animationsPayload)
this._keyframes = animationsPayload.map(rule => new WebInspector.CSSKeyframesRule(cssModel, rule));
this.resetActiveProperties();
/**
* @param {!WebInspector.DOMNode} node
* @param {!WebInspector.CSSStyleRule} rule
* @param {!Array<number>} matchingSelectorIndices
* @this {WebInspector.CSSMatchedStyles}
*/
function addMatchingSelectors(node, rule, matchingSelectorIndices)
{
for (var matchingSelectorIndex of matchingSelectorIndices) {
var selector = rule.selectors[matchingSelectorIndex];
this._setSelectorMatches(node, selector.text, true);
}
}
}
WebInspector.CSSMatchedStyles.prototype = {
/**
* @return {!WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @return {!WebInspector.CSSModel}
*/
cssModel: function()
{
return this._cssModel;
},
/**
* @param {!WebInspector.CSSStyleRule} rule
* @return {boolean}
*/
hasMatchingSelectors: function(rule)
{
var matchingSelectors = this.matchingSelectors(rule);
return matchingSelectors.length > 0 && this.mediaMatches(rule.style);
},
/**
* @param {!WebInspector.CSSStyleRule} rule
* @return {!Array<number>}
*/
matchingSelectors: function(rule)
{
var node = this.nodeForStyle(rule.style);
if (!node)
return [];
var map = this._matchingSelectors.get(node.id);
if (!map)
return [];
var result = [];
for (var i = 0; i < rule.selectors.length; ++i) {
if (map.get(rule.selectors[i].text))
result.push(i);
}
return result;
},
/**
* @param {!WebInspector.CSSStyleRule} rule
* @return {!Promise}
*/
recomputeMatchingSelectors: function(rule)
{
var node = this.nodeForStyle(rule.style);
if (!node)
return Promise.resolve();
var promises = [];
for (var selector of rule.selectors)
promises.push(querySelector.call(this, node, selector.text));
return Promise.all(promises);
/**
* @param {!WebInspector.DOMNode} node
* @param {string} selectorText
* @return {!Promise}
* @this {WebInspector.CSSMatchedStyles}
*/
function querySelector(node, selectorText)
{
var ownerDocument = node.ownerDocument || null;
// We assume that "matching" property does not ever change during the
// MatchedStyleResult's lifetime.
var map = this._matchingSelectors.get(node.id);
if ((map && map.has(selectorText)) || !ownerDocument)
return Promise.resolve();
var resolve;
var promise = new Promise(fulfill => resolve = fulfill);
this._node.domModel().querySelectorAll(ownerDocument.id, selectorText, onQueryComplete.bind(this, node, selectorText, resolve));
return promise;
}
/**
* @param {!WebInspector.DOMNode} node
* @param {string} selectorText
* @param {function()} callback
* @param {!Array.<!DOMAgent.NodeId>=} matchingNodeIds
* @this {WebInspector.CSSMatchedStyles}
*/
function onQueryComplete(node, selectorText, callback, matchingNodeIds)
{
if (matchingNodeIds)
this._setSelectorMatches(node, selectorText, matchingNodeIds.indexOf(node.id) !== -1);
callback();
}
},
/**
* @param {!WebInspector.CSSStyleRule} rule
* @param {!WebInspector.DOMNode} node
* @return {!Promise}
*/
addNewRule: function(rule, node)
{
this._nodeForStyle.set(rule.style, node);
return this.recomputeMatchingSelectors(rule);
},
/**
* @param {!WebInspector.DOMNode} node
* @param {string} selectorText
* @param {boolean} value
*/
_setSelectorMatches: function(node, selectorText, value)
{
var map = this._matchingSelectors.get(node.id);
if (!map) {
map = new Map();
this._matchingSelectors.set(node.id, map);
}
map.set(selectorText, value);
},
/**
* @param {!WebInspector.CSSStyleDeclaration} style
* @return {boolean}
*/
mediaMatches: function(style)
{
var media = style.parentRule ? style.parentRule.media : [];
for (var i = 0; media && i < media.length; ++i) {
if (!media[i].active())
return false;
}
return true;
},
/**
* @return {!Array<!WebInspector.CSSStyleDeclaration>}
*/
nodeStyles: function()
{
return this._nodeStyles;
},
/**
* @return {!Array.<!WebInspector.CSSKeyframesRule>}
*/
keyframes: function()
{
return this._keyframes;
},
/**
* @return {!Map.<!DOMAgent.PseudoType, !Array<!WebInspector.CSSStyleDeclaration>>}
*/
pseudoStyles: function()
{
return this._pseudoStyles;
},
/**
* @param {!WebInspector.CSSStyleDeclaration} style
* @return {boolean}
*/
_containsInherited: function(style)
{
var properties = style.allProperties;
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
// Does this style contain non-overridden inherited property?
if (property.activeInStyle() && WebInspector.CSSMetadata.isPropertyInherited(property.name))
return true;
}
return false;
},
/**
* @param {!WebInspector.CSSStyleDeclaration} style
* @return {?WebInspector.DOMNode}
*/
nodeForStyle: function(style)
{
return this._nodeForStyle.get(style) || null;
},
/**
* @param {!WebInspector.CSSStyleDeclaration} style
* @return {boolean}
*/
isInherited: function(style)
{
return this._inheritedStyles.has(style);
},
/**
* @param {!WebInspector.CSSProperty} property
* @return {?WebInspector.CSSMatchedStyles.PropertyState}
*/
propertyState: function(property)
{
if (this._propertiesState.size === 0) {
this._computeActiveProperties(this._nodeStyles, this._propertiesState);
for (var pseudoElementStyles of this._pseudoStyles.valuesArray())
this._computeActiveProperties(pseudoElementStyles, this._propertiesState);
}
return this._propertiesState.get(property) || null;
},
resetActiveProperties: function()
{
/** @type {!Map<!WebInspector.CSSProperty, !WebInspector.CSSMatchedStyles.PropertyState>} */
this._propertiesState = new Map();
},
/**
* @param {!Array<!WebInspector.CSSStyleDeclaration>} styles
* @param {!Map<!WebInspector.CSSProperty, !WebInspector.CSSMatchedStyles.PropertyState>} result
*/
_computeActiveProperties: function(styles, result)
{
/** @type {!Set.<string>} */
var foundImportantProperties = new Set();
/** @type {!Map.<string, !Map<string, !WebInspector.CSSProperty>>} */
var propertyToEffectiveRule = new Map();
/** @type {!Map.<string, !WebInspector.DOMNode>} */
var inheritedPropertyToNode = new Map();
/** @type {!Set<string>} */
var allUsedProperties = new Set();
for (var i = 0; i < styles.length; ++i) {
var style = styles[i];
var rule = style.parentRule;
// Compute cascade for CSSStyleRules only.
if (rule && !(rule instanceof WebInspector.CSSStyleRule))
continue;
if (rule && !this.hasMatchingSelectors(rule))
continue;
/** @type {!Map<string, !WebInspector.CSSProperty>} */
var styleActiveProperties = new Map();
var allProperties = style.allProperties;
for (var j = 0; j < allProperties.length; ++j) {
var property = allProperties[j];
// Do not pick non-inherited properties from inherited styles.
var inherited = this.isInherited(style);
if (inherited && !WebInspector.CSSMetadata.isPropertyInherited(property.name))
continue;
if (!property.activeInStyle()) {
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
continue;
}
var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name);
if (foundImportantProperties.has(canonicalName)) {
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
continue;
}
if (!property.important && allUsedProperties.has(canonicalName)) {
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
continue;
}
var isKnownProperty = propertyToEffectiveRule.has(canonicalName);
var inheritedFromNode = inherited ? this.nodeForStyle(style) : null;
if (!isKnownProperty && inheritedFromNode && !inheritedPropertyToNode.has(canonicalName))
inheritedPropertyToNode.set(canonicalName, inheritedFromNode);
if (property.important) {
if (inherited && isKnownProperty && inheritedFromNode !== inheritedPropertyToNode.get(canonicalName)) {
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
continue;
}
foundImportantProperties.add(canonicalName);
if (isKnownProperty) {
var overloaded = /** @type {!WebInspector.CSSProperty} */(propertyToEffectiveRule.get(canonicalName).get(canonicalName));
result.set(overloaded, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
propertyToEffectiveRule.get(canonicalName).delete(canonicalName);
}
}
styleActiveProperties.set(canonicalName, property);
allUsedProperties.add(canonicalName);
propertyToEffectiveRule.set(canonicalName, styleActiveProperties);
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Active);
}
// If every longhand of the shorthand is not active, then the shorthand is not active too.
for (var property of style.leadingProperties()) {
var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name);
if (!styleActiveProperties.has(canonicalName))
continue;
var longhands = style.longhandProperties(property.name);
if (!longhands.length)
continue;
var notUsed = true;
for (var longhand of longhands) {
var longhandCanonicalName = WebInspector.CSSMetadata.canonicalPropertyName(longhand.name);
notUsed = notUsed && !styleActiveProperties.has(longhandCanonicalName);
}
if (!notUsed)
continue;
styleActiveProperties.delete(canonicalName);
allUsedProperties.delete(canonicalName);
result.set(property, WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
}
}
}
}
/** @enum {string} */
WebInspector.CSSMatchedStyles.PropertyState = {
Active: "Active",
Overloaded: "Overloaded"
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!CSSAgent.MediaQuery} payload
*/
WebInspector.CSSMediaQuery = function(payload)
{
this._active = payload.active;
this._expressions = [];
for (var j = 0; j < payload.expressions.length; ++j)
this._expressions.push(WebInspector.CSSMediaQueryExpression.parsePayload(payload.expressions[j]));
}
/**
* @param {!CSSAgent.MediaQuery} payload
* @return {!WebInspector.CSSMediaQuery}
*/
WebInspector.CSSMediaQuery.parsePayload = function(payload)
{
return new WebInspector.CSSMediaQuery(payload);
}
WebInspector.CSSMediaQuery.prototype = {
/**
* @return {boolean}
*/
active: function()
{
return this._active;
},
/**
* @return {!Array.<!WebInspector.CSSMediaQueryExpression>}
*/
expressions: function()
{
return this._expressions;
}
}
/**
* @constructor
* @param {!CSSAgent.MediaQueryExpression} payload
*/
WebInspector.CSSMediaQueryExpression = function(payload)
{
this._value = payload.value;
this._unit = payload.unit;
this._feature = payload.feature;
this._valueRange = payload.valueRange ? WebInspector.TextRange.fromObject(payload.valueRange) : null;
this._computedLength = payload.computedLength || null;
}
/**
* @param {!CSSAgent.MediaQueryExpression} payload
* @return {!WebInspector.CSSMediaQueryExpression}
*/
WebInspector.CSSMediaQueryExpression.parsePayload = function(payload)
{
return new WebInspector.CSSMediaQueryExpression(payload);
}
WebInspector.CSSMediaQueryExpression.prototype = {
/**
* @return {number}
*/
value: function()
{
return this._value;
},
/**
* @return {string}
*/
unit: function()
{
return this._unit;
},
/**
* @return {string}
*/
feature: function()
{
return this._feature;
},
/**
* @return {?WebInspector.TextRange}
*/
valueRange: function()
{
return this._valueRange;
},
/**
* @return {?number}
*/
computedLength: function()
{
return this._computedLength;
}
}
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSMedia} payload
*/
WebInspector.CSSMedia = function(cssModel, payload)
{
this._cssModel = cssModel;
this._reinitialize(payload);
}
WebInspector.CSSMedia.Source = {
LINKED_SHEET: "linkedSheet",
INLINE_SHEET: "inlineSheet",
MEDIA_RULE: "mediaRule",
IMPORT_RULE: "importRule"
};
/**
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSMedia} payload
* @return {!WebInspector.CSSMedia}
*/
WebInspector.CSSMedia.parsePayload = function(cssModel, payload)
{
return new WebInspector.CSSMedia(cssModel, payload);
}
/**
* @param {!WebInspector.CSSModel} cssModel
* @param {!Array.<!CSSAgent.CSSMedia>} payload
* @return {!Array.<!WebInspector.CSSMedia>}
*/
WebInspector.CSSMedia.parseMediaArrayPayload = function(cssModel, payload)
{
var result = [];
for (var i = 0; i < payload.length; ++i)
result.push(WebInspector.CSSMedia.parsePayload(cssModel, payload[i]));
return result;
}
WebInspector.CSSMedia.prototype = {
/**
* @param {!CSSAgent.CSSMedia} payload
*/
_reinitialize: function(payload)
{
this.text = payload.text;
this.source = payload.source;
this.sourceURL = payload.sourceURL || "";
this.range = payload.range ? WebInspector.TextRange.fromObject(payload.range) : null;
this.parentStyleSheetId = payload.parentStyleSheetId;
this.mediaList = null;
if (payload.mediaList) {
this.mediaList = [];
for (var i = 0; i < payload.mediaList.length; ++i)
this.mediaList.push(WebInspector.CSSMediaQuery.parsePayload(payload.mediaList[i]));
}
},
/**
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.parentStyleSheetId !== edit.styleSheetId || !this.range)
return;
if (edit.oldRange.equal(this.range))
this._reinitialize(/** @type {!CSSAgent.CSSMedia} */(edit.payload));
else
this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
},
/**
* @param {!WebInspector.CSSMedia} other
* @return {boolean}
*/
equal: function(other)
{
if (!this.parentStyleSheetId || !this.range || !other.range)
return false;
return this.parentStyleSheetId === other.parentStyleSheetId && this.range.equal(other.range);
},
/**
* @return {boolean}
*/
active: function()
{
if (!this.mediaList)
return true;
for (var i = 0; i < this.mediaList.length; ++i) {
if (this.mediaList[i].active())
return true;
}
return false;
},
/**
* @return {number|undefined}
*/
lineNumberInSource: function()
{
if (!this.range)
return undefined;
var header = this.header();
if (!header)
return undefined;
return header.lineNumberInSource(this.range.startLine);
},
/**
* @return {number|undefined}
*/
columnNumberInSource: function()
{
if (!this.range)
return undefined;
var header = this.header();
if (!header)
return undefined;
return header.columnNumberInSource(this.range.startLine, this.range.startColumn);
},
/**
* @return {?WebInspector.CSSStyleSheetHeader}
*/
header: function()
{
return this.parentStyleSheetId ? this._cssModel.styleSheetHeaderForId(this.parentStyleSheetId) : null;
},
/**
* @return {?WebInspector.CSSLocation}
*/
rawLocation: function()
{
var header = this.header();
if (!header || this.lineNumberInSource() === undefined)
return null;
var lineNumber = Number(this.lineNumberInSource());
return new WebInspector.CSSLocation(header, lineNumber, this.columnNumberInSource());
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | 2 | /*
* Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
* Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!Array.<!{name: string, longhands: !Array.<string>}|string>} properties
*/
WebInspector.CSSMetadata = function(properties)
{
this._values = /** !Array.<string> */ ([]);
this._longhands = {};
this._shorthands = {};
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (typeof property === "string") {
this._values.push(property);
continue;
}
var propertyName = property.name;
if (!CSS.supports(propertyName, "initial"))
continue;
this._values.push(propertyName);
var longhands = properties[i].longhands;
if (longhands) {
this._longhands[propertyName] = longhands;
for (var j = 0; j < longhands.length; ++j) {
var longhandName = longhands[j];
var shorthands = this._shorthands[longhandName];
if (!shorthands) {
shorthands = [];
this._shorthands[longhandName] = shorthands;
}
shorthands.push(propertyName);
}
}
}
this._values.sort();
}
/**
* @type {!WebInspector.CSSMetadata}
*/
WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata([]);
/**
* @param {string} propertyName
* @return {boolean}
*/
WebInspector.CSSMetadata.isColorAwareProperty = function(propertyName)
{
return !!WebInspector.CSSMetadata._colorAwareProperties[propertyName.toLowerCase()];
}
/**
* @param {string} propertyName
* @return {boolean}
*/
WebInspector.CSSMetadata.isLengthProperty = function(propertyName)
{
if (propertyName === "line-height")
return false;
if (!WebInspector.CSSMetadata._distancePropertiesKeySet)
WebInspector.CSSMetadata._distancePropertiesKeySet = WebInspector.CSSMetadata._distanceProperties.keySet();
return WebInspector.CSSMetadata._distancePropertiesKeySet[propertyName] || propertyName.startsWith("margin") || propertyName.startsWith("padding") || propertyName.indexOf("width") !== -1 || propertyName.indexOf("height") !== -1;
}
/**
* @param {string} propertyName
* @return {boolean}
*/
WebInspector.CSSMetadata.isBezierAwareProperty = function(propertyName)
{
return !!WebInspector.CSSMetadata._bezierAwareProperties[propertyName.toLowerCase()];
}
// Originally taken from http://www.w3.org/TR/CSS21/propidx.html and augmented.
WebInspector.CSSMetadata.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
"empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
"line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "overflow-wrap", "pitch-range",
"pitch", "quotes", "resize", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
"text-align", "text-indent", "text-transform", "text-shadow", "-webkit-user-select", "visibility", "voice-family", "volume", "white-space", "widows",
"word-spacing", "word-wrap", "zoom"
].keySet();
// These non-standard Blink-specific properties augment the InheritedProperties.
WebInspector.CSSMetadata.NonStandardInheritedProperties = [
"-webkit-font-smoothing"
].keySet();
/**
* @param {string} name
* @return {string}
*/
WebInspector.CSSMetadata.canonicalPropertyName = function(name)
{
if (!name || name.length < 9 || name.charAt(0) !== "-")
return name.toLowerCase();
var match = name.match(/(?:-webkit-)(.+)/);
var propertiesSet = WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet();
var hasSupportedProperties = WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length > 0;
if (!match || (hasSupportedProperties && !propertiesSet.hasOwnProperty(match[1].toLowerCase())))
return name.toLowerCase();
return match[1].toLowerCase();
}
/**
* @param {string} propertyName
* @return {boolean}
*/
WebInspector.CSSMetadata.isCSSPropertyName = function(propertyName)
{
if (propertyName.startsWith("-moz-") || propertyName.startsWith("-o-") || propertyName.startsWith("-webkit-") || propertyName.startsWith("-ms-"))
return true;
var hasSupportedProperties = WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length > 0;
return !hasSupportedProperties || WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet().hasOwnProperty(propertyName);
}
/**
* @param {string} propertyName
* @return {boolean}
*/
WebInspector.CSSMetadata.isPropertyInherited = function(propertyName)
{
return !!(WebInspector.CSSMetadata.InheritedProperties[WebInspector.CSSMetadata.canonicalPropertyName(propertyName)]
|| WebInspector.CSSMetadata.NonStandardInheritedProperties[propertyName.toLowerCase()]);
}
WebInspector.CSSMetadata._distanceProperties = [
'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height', 'max-width', 'min-height',
'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing'
];
WebInspector.CSSMetadata._bezierAwareProperties = [
"animation", "animation-timing-function", "transition", "transition-timing-function", "-webkit-animation", "-webkit-animation-timing-function",
"-webkit-transition", "-webkit-transition-timing-function"
].keySet();
WebInspector.CSSMetadata._colorAwareProperties = [
"background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
"border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
"fill", "outline", "outline-color", "stroke", "text-shadow", "-webkit-box-shadow", "-webkit-column-rule-color",
"-webkit-text-decoration-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
].keySet();
WebInspector.CSSMetadata._propertyDataMap = {
"table-layout": { values: [
"auto", "fixed"
] },
"visibility": { values: [
"hidden", "visible", "collapse"
] },
"background-repeat": { values: [
"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
] },
"content": { values: [
"list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
] },
"list-style-image": { values: [
"none"
] },
"clear": { values: [
"none", "left", "right", "both"
] },
"overflow-x": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"stroke-linejoin": { values: [
"round", "miter", "bevel"
] },
"baseline-shift": { values: [
"baseline", "sub", "super"
] },
"border-bottom-width": { values: [
"medium", "thick", "thin"
] },
"margin-top-collapse": { values: [
"collapse", "separate", "discard"
] },
"max-height": { values: [
"none"
] },
"box-orient": { values: [
"horizontal", "vertical", "inline-axis", "block-axis"
], },
"font-stretch": { values: [
"normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
] },
"border-left-width": { values: [
"medium", "thick", "thin"
] },
"box-shadow": { values: [
"inset", "none"
] },
"writing-mode": { values: [
"horizontal-tb", "vertical-rl", "vertical-lr"
] },
"-webkit-writing-mode": { values: [
"lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr"
] },
"border-collapse": { values: [
"collapse", "separate"
] },
"page-break-inside": { values: [
"auto", "avoid"
] },
"border-top-width": { values: [
"medium", "thick", "thin"
] },
"outline-color": { values: [
"invert"
] },
"outline-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"cursor": { values: [
"none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
"alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
"nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
"nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
"-webkit-grabbing"
] },
"border-width": { values: [
"medium", "thick", "thin"
] },
"border-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"size": { values: [
"a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
] },
"background-size": { values: [
"contain", "cover"
] },
"direction": { values: [
"ltr", "rtl"
] },
"enable-background": { values: [
"accumulate", "new"
] },
"float": { values: [
"none", "left", "right"
] },
"overflow-y": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"margin-bottom-collapse": { values: [
"collapse", "separate", "discard"
] },
"box-reflect": { values: [
"left", "right", "above", "below"
] },
"overflow": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"text-rendering": { values: [
"auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
] },
"text-align": { values: [
"-webkit-auto", "start", "end", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
] },
"list-style-position": { values: [
"outside", "inside", "hanging"
] },
"margin-bottom": { values: [
"auto"
] },
"color-interpolation": { values: [
"linearrgb"
] },
"background-origin": { values: [
"border-box", "content-box", "padding-box"
] },
"word-wrap": { values: [
"normal", "break-word"
] },
"font-weight": { values: [
"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
] },
"margin-before-collapse": { values: [
"collapse", "separate", "discard"
] },
"text-transform": { values: [
"none", "capitalize", "uppercase", "lowercase"
] },
"border-right-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"border-left-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"-webkit-text-emphasis": { values: [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
] },
"font-style": { values: [
"italic", "oblique", "normal"
] },
"speak": { values: [
"none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
] },
"color-rendering": { values: [
"auto", "optimizeSpeed", "optimizeQuality"
] },
"list-style-type": { values: [
"none", "inline", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
"cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
"mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
"lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
"ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
"ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
"ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
"ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
"ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
"ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
"ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
"lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
"katakana-iroha"
] },
"text-combine-upright": { values: [
"none", "all"
] },
"-webkit-text-combine": { values: [
"none", "horizontal"
] },
"text-orientation": { values: [
"mixed", "upright", "sideways"
] },
"outline": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"font": { values: [
"caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
"-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
"100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
"large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
"fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
] },
"dominant-baseline": { values: [
"middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
"mathematical", "use-script", "no-change", "reset-size"
] },
"display": { values: [
"none", "inline", "block", "list-item", "run-in", "inline-block", "table", "inline-table",
"table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
"table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box",
"flex", "inline-flex", "grid", "inline-grid"
] },
"-webkit-text-emphasis-position": { values: [
"over", "under"
] },
"image-rendering": { values: [
"auto", "optimizeSpeed", "optimizeQuality", "pixelated"
] },
"alignment-baseline": { values: [
"baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
"ideographic", "alphabetic", "hanging", "mathematical"
] },
"outline-width": { values: [
"medium", "thick", "thin"
] },
"box-align": { values: [
"baseline", "center", "stretch", "start", "end"
] },
"border-right-width": { values: [
"medium", "thick", "thin"
] },
"border-top-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"line-height": { values: [
"normal"
] },
"text-overflow": { values: [
"clip", "ellipsis"
] },
"overflow-wrap": { values: [
"normal", "break-word"
] },
"box-direction": { values: [
"normal", "reverse"
] },
"margin-after-collapse": { values: [
"collapse", "separate", "discard"
] },
"page-break-before": { values: [
"left", "right", "auto", "always", "avoid"
] },
"border-image": { values: [
"repeat", "stretch"
] },
"text-decoration": { values: [
"blink", "line-through", "overline", "underline"
] },
"position": { values: [
"absolute", "fixed", "relative", "static"
] },
"font-family": { values: [
"serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
] },
"text-overflow-mode": { values: [
"clip", "ellipsis"
] },
"border-bottom-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"unicode-bidi": { values: [
"normal", "bidi-override", "embed", "isolate", "isolate-override", "plaintext"
] },
"clip-rule": { values: [
"nonzero", "evenodd"
] },
"margin-left": { values: [
"auto"
] },
"margin-top": { values: [
"auto"
] },
"zoom": { values: [
"normal", "document", "reset"
] },
"max-width": { values: [
"none"
] },
"caption-side": { values: [
"top", "bottom"
] },
"empty-cells": { values: [
"hide", "show"
] },
"pointer-events": { values: [
"none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke", "bounding-box"
] },
"letter-spacing": { values: [
"normal"
] },
"background-clip": { values: [
"border-box", "content-box", "padding-box"
] },
"-webkit-font-smoothing": { values: [
"none", "auto", "antialiased", "subpixel-antialiased"
] },
"border": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"font-size": { values: [
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
"larger"
] },
"font-variant": { values: [
"small-caps", "normal"
] },
"vertical-align": { values: [
"baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
] },
"white-space": { values: [
"normal", "nowrap", "pre", "pre-line", "pre-wrap"
] },
"box-lines": { values: [
"single", "multiple"
] },
"page-break-after": { values: [
"left", "right", "auto", "always", "avoid"
] },
"clip-path": { values: [
"none"
] },
"margin": { values: [
"auto"
] },
"margin-right": { values: [
"auto"
] },
"word-break": { values: [
"normal", "break-all", "break-word"
] },
"word-spacing": { values: [
"normal"
] },
"-webkit-text-emphasis-style": { values: [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
] },
"transform": { values: [
"scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY",
"translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
] },
"image-resolution": { values: [
"from-image", "snap"
] },
"box-sizing": { values: [
"content-box", "border-box"
] },
"clip": { values: [
"auto"
] },
"resize": { values: [
"none", "both", "horizontal", "vertical"
] },
"align-content": { values: [
"flex-start", "flex-end", "center", "space-between", "space-around", "stretch"
] },
"align-items": { values: [
"flex-start", "flex-end", "center", "baseline", "stretch"
] },
"align-self": { values: [
"auto", "flex-start", "flex-end", "center", "baseline", "stretch"
] },
"flex-direction": { values: [
"row", "row-reverse", "column", "column-reverse"
] },
"justify-content": { values: [
"flex-start", "flex-end", "center", "space-between", "space-around"
] },
"flex-wrap": { values: [
"nowrap", "wrap", "wrap-reverse"
] },
"perspective": { values: [
"none"
] },
"perspective-origin": { values: [
"left", "center", "right", "top", "bottom"
] },
"transform-origin": { values: [
"left", "center", "right", "top", "bottom"
] },
"transform-style": { values: [
"flat", "preserve-3d"
] },
"transition-timing-function": { values: [
"ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
] },
"animation-timing-function": { values: [
"ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
] },
"animation-direction": { values: [
"normal", "reverse", "alternate", "alternate-reverse"
] },
"animation-play-state": { values: [
"running", "paused"
] },
"animation-fill-mode": { values: [
"none", "forwards", "backwards", "both"
] },
"-webkit-backface-visibility": { values: [
"visible", "hidden"
] },
"-webkit-box-decoration-break": { values: [
"slice", "clone"
] },
"-webkit-column-break-after": { values: [
"auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
] },
"-webkit-column-break-before": { values: [
"auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
] },
"-webkit-column-break-inside": { values: [
"auto", "avoid", "avoid-page", "avoid-column"
] },
"-webkit-column-span": { values: [
"none", "all"
] },
"-webkit-column-count": { values: [
"auto"
] },
"-webkit-column-gap": { values: [
"normal"
] },
"-webkit-filter": { values: [
"url", "blur", "brightness", "contrast", "drop-shadow", "grayscale", "hue-rotate", "invert", "opacity", "saturate", "sepia"
] },
"-webkit-line-break": { values: [
"auto", "loose", "normal", "strict"
] },
"text-align-last": { values: [
"auto", "start", "end", "left", "right", "center", "justify"
] },
"-webkit-text-decoration-line": { values: [
"none", "underline", "overline", "line-through", "blink"
] },
"-webkit-text-decoration-style": { values: [
"solid", "double", "dotted", "dashed", "wavy"
] },
"-webkit-text-decoration-skip": { values: [
"none", "objects", "spaces", "ink", "edges", "box-decoration"
] },
"mix-blend-mode": { values: [
"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light",
"difference", "exclusion", "hue", "saturation", "color", "luminosity", "unset"
] },
"background-blend-mode": { values: [
"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light",
"difference", "exclusion", "hue", "saturation", "color", "luminosity", "unset"
] },
}
/**
* @param {string} propertyName
* @return {!WebInspector.CSSMetadata}
*/
WebInspector.CSSMetadata.keywordsForProperty = function(propertyName)
{
var acceptedKeywords = ["inherit", "initial"];
var descriptor = WebInspector.CSSMetadata.descriptor(propertyName);
if (descriptor && descriptor.values)
acceptedKeywords.push.apply(acceptedKeywords, descriptor.values);
if (WebInspector.CSSMetadata.isColorAwareProperty(propertyName)) {
acceptedKeywords.push("currentColor");
for (var color in WebInspector.Color.Nicknames)
acceptedKeywords.push(color);
}
return new WebInspector.CSSMetadata(acceptedKeywords);
}
/**
* @param {string} propertyName
* @return {?Object}
*/
WebInspector.CSSMetadata.descriptor = function(propertyName)
{
if (!propertyName)
return null;
var unprefixedName = propertyName.replace(/^-webkit-/, "");
propertyName = propertyName.toLowerCase();
var entry = WebInspector.CSSMetadata._propertyDataMap[propertyName];
if (!entry && unprefixedName !== propertyName)
entry = WebInspector.CSSMetadata._propertyDataMap[unprefixedName];
return entry || null;
}
WebInspector.CSSMetadata.initializeWithSupportedProperties = function(properties)
{
WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
}
/**
* @return {!Object.<string, boolean>}
*/
WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet = function()
{
if (!WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet)
WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet = WebInspector.CSSMetadata.cssPropertiesMetainfo.keySet();
return WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet;
}
// Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity
WebInspector.CSSMetadata.Weight = {
"align-content": 57,
"align-items": 129,
"align-self": 55,
"animation": 175,
"animation-delay": 114,
"animation-direction": 113,
"animation-duration": 137,
"animation-fill-mode": 132,
"animation-iteration-count": 124,
"animation-name": 139,
"animation-play-state": 104,
"animation-timing-function": 141,
"backface-visibility": 123,
"background": 260,
"background-attachment": 119,
"background-clip": 165,
"background-color": 259,
"background-image": 246,
"background-origin": 107,
"background-position": 237,
"background-position-x": 108,
"background-position-y": 93,
"background-repeat": 234,
"background-size": 203,
"border": 263,
"border-bottom": 233,
"border-bottom-color": 190,
"border-bottom-left-radius": 186,
"border-bottom-right-radius": 185,
"border-bottom-style": 150,
"border-bottom-width": 179,
"border-collapse": 209,
"border-color": 226,
"border-image": 89,
"border-image-outset": 50,
"border-image-repeat": 49,
"border-image-slice": 58,
"border-image-source": 32,
"border-image-width": 52,
"border-left": 221,
"border-left-color": 174,
"border-left-style": 142,
"border-left-width": 172,
"border-radius": 224,
"border-right": 223,
"border-right-color": 182,
"border-right-style": 130,
"border-right-width": 178,
"border-spacing": 198,
"border-style": 206,
"border-top": 231,
"border-top-color": 192,
"border-top-left-radius": 187,
"border-top-right-radius": 189,
"border-top-style": 152,
"border-top-width": 180,
"border-width": 214,
"bottom": 227,
"box-shadow": 213,
"box-sizing": 216,
"caption-side": 96,
"clear": 229,
"clip": 173,
"clip-rule": 5,
"color": 256,
"content": 219,
"counter-increment": 111,
"counter-reset": 110,
"cursor": 250,
"direction": 176,
"display": 262,
"empty-cells": 99,
"fill": 140,
"fill-opacity": 82,
"fill-rule": 22,
"filter": 160,
"flex": 133,
"flex-basis": 66,
"flex-direction": 85,
"flex-flow": 94,
"flex-grow": 112,
"flex-shrink": 61,
"flex-wrap": 68,
"float": 252,
"font": 211,
"font-family": 254,
"font-kerning": 18,
"font-size": 264,
"font-stretch": 77,
"font-style": 220,
"font-variant": 161,
"font-weight": 257,
"height": 266,
"image-rendering": 90,
"justify-content": 127,
"left": 248,
"letter-spacing": 188,
"line-height": 244,
"list-style": 215,
"list-style-image": 145,
"list-style-position": 149,
"list-style-type": 199,
"margin": 267,
"margin-bottom": 241,
"margin-left": 243,
"margin-right": 238,
"margin-top": 253,
"mask": 20,
"max-height": 205,
"max-width": 225,
"min-height": 217,
"min-width": 218,
"object-fit": 33,
"opacity": 251,
"order": 117,
"orphans": 146,
"outline": 222,
"outline-color": 153,
"outline-offset": 147,
"outline-style": 151,
"outline-width": 148,
"overflow": 255,
"overflow-wrap": 105,
"overflow-x": 184,
"overflow-y": 196,
"padding": 265,
"padding-bottom": 230,
"padding-left": 235,
"padding-right": 232,
"padding-top": 240,
"page": 8,
"page-break-after": 120,
"page-break-before": 69,
"page-break-inside": 121,
"perspective": 92,
"perspective-origin": 103,
"pointer-events": 183,
"position": 261,
"quotes": 158,
"resize": 168,
"right": 245,
"shape-rendering": 38,
"size": 64,
"speak": 118,
"src": 170,
"stop-color": 42,
"stop-opacity": 31,
"stroke": 98,
"stroke-dasharray": 36,
"stroke-dashoffset": 3,
"stroke-linecap": 30,
"stroke-linejoin": 21,
"stroke-miterlimit": 12,
"stroke-opacity": 34,
"stroke-width": 87,
"table-layout": 171,
"tab-size": 46,
"text-align": 260,
"text-anchor": 35,
"text-decoration": 247,
"text-indent": 207,
"text-overflow": 204,
"text-rendering": 155,
"text-shadow": 208,
"text-transform": 202,
"top": 258,
"touch-action": 80,
"transform": 181,
"transform-origin": 162,
"transform-style": 86,
"transition": 193,
"transition-delay": 134,
"transition-duration": 135,
"transition-property": 131,
"transition-timing-function": 122,
"unicode-bidi": 156,
"unicode-range": 136,
"vertical-align": 236,
"visibility": 242,
"-webkit-appearance": 191,
"-webkit-backface-visibility": 154,
"-webkit-background-clip": 164,
"-webkit-background-origin": 40,
"-webkit-background-size": 163,
"-webkit-border-end": 9,
"-webkit-border-horizontal-spacing": 81,
"-webkit-border-image": 75,
"-webkit-border-radius": 212,
"-webkit-border-start": 10,
"-webkit-border-start-color": 16,
"-webkit-border-start-width": 13,
"-webkit-border-vertical-spacing": 43,
"-webkit-box-align": 101,
"-webkit-box-direction": 51,
"-webkit-box-flex": 128,
"-webkit-box-lines": 2,
"-webkit-box-ordinal-group": 91,
"-webkit-box-orient": 144,
"-webkit-box-pack": 106,
"-webkit-box-reflect": 39,
"-webkit-box-shadow": 210,
"-webkit-column-break-inside": 60,
"-webkit-column-count": 84,
"-webkit-column-gap": 76,
"-webkit-column-rule": 25,
"-webkit-column-rule-color": 23,
"-webkit-columns": 44,
"-webkit-column-span": 29,
"-webkit-column-width": 47,
"-webkit-filter": 159,
"-webkit-font-feature-settings": 59,
"-webkit-font-smoothing": 177,
"-webkit-highlight": 1,
"-webkit-line-break": 45,
"-webkit-line-clamp": 126,
"-webkit-margin-after": 67,
"-webkit-margin-before": 70,
"-webkit-margin-collapse": 14,
"-webkit-margin-end": 65,
"-webkit-margin-start": 100,
"-webkit-margin-top-collapse": 78,
"-webkit-mask": 19,
"-webkit-mask-box-image": 72,
"-webkit-mask-image": 88,
"-webkit-mask-position": 54,
"-webkit-mask-repeat": 63,
"-webkit-mask-size": 79,
"-webkit-padding-after": 15,
"-webkit-padding-before": 28,
"-webkit-padding-end": 48,
"-webkit-padding-start": 73,
"-webkit-print-color-adjust": 83,
"-webkit-rtl-ordering": 7,
"-webkit-tap-highlight-color": 169,
"-webkit-text-emphasis-color": 11,
"-webkit-text-fill-color": 71,
"-webkit-text-security": 17,
"-webkit-text-stroke": 56,
"-webkit-text-stroke-color": 37,
"-webkit-text-stroke-width": 53,
"-webkit-user-drag": 95,
"-webkit-user-modify": 62,
"-webkit-user-select": 194,
"-webkit-writing-mode": 4,
"white-space": 228,
"widows": 115,
"width": 268,
"will-change": 74,
"word-break": 166,
"word-spacing": 157,
"word-wrap": 197,
"writing-mode": 41,
"z-index": 239,
"zoom": 200
};
WebInspector.CSSMetadata.prototype = {
/**
* @param {string} prefix
* @return {!Array.<string>}
*/
startsWith: function(prefix)
{
var firstIndex = this._firstIndexOfPrefix(prefix);
if (firstIndex === -1)
return [];
var results = [];
while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
results.push(this._values[firstIndex++]);
return results;
},
/**
* @param {!Array.<string>} properties
* @return {number}
*/
mostUsedOf: function(properties)
{
var maxWeight = 0;
var index = 0;
for (var i = 0; i < properties.length; i++) {
var weight = WebInspector.CSSMetadata.Weight[properties[i]];
if (!weight)
weight = WebInspector.CSSMetadata.Weight[WebInspector.CSSMetadata.canonicalPropertyName(properties[i])];
if (weight > maxWeight) {
maxWeight = weight;
index = i;
}
}
return index;
},
_firstIndexOfPrefix: function(prefix)
{
if (!this._values.length)
return -1;
if (!prefix)
return 0;
var maxIndex = this._values.length - 1;
var minIndex = 0;
var foundIndex;
do {
var middleIndex = (maxIndex + minIndex) >> 1;
if (this._values[middleIndex].startsWith(prefix)) {
foundIndex = middleIndex;
break;
}
if (this._values[middleIndex] < prefix)
minIndex = middleIndex + 1;
else
maxIndex = middleIndex - 1;
} while (minIndex <= maxIndex);
if (foundIndex === undefined)
return -1;
while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
foundIndex--;
return foundIndex;
},
/**
* @return {!Object.<string, boolean>}
*/
keySet: function()
{
if (!this._keySet)
this._keySet = this._values.keySet();
return this._keySet;
},
/**
* @param {string} str
* @param {string} prefix
* @return {string}
*/
next: function(str, prefix)
{
return this._closest(str, prefix, 1);
},
/**
* @param {string} str
* @param {string} prefix
* @return {string}
*/
previous: function(str, prefix)
{
return this._closest(str, prefix, -1);
},
/**
* @param {string} str
* @param {string} prefix
* @param {number} shift
* @return {string}
*/
_closest: function(str, prefix, shift)
{
if (!str)
return "";
var index = this._values.indexOf(str);
if (index === -1)
return "";
if (!prefix) {
index = (index + this._values.length + shift) % this._values.length;
return this._values[index];
}
var propertiesWithPrefix = this.startsWith(prefix);
var j = propertiesWithPrefix.indexOf(str);
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
},
/**
* @param {string} shorthand
* @return {?Array.<string>}
*/
longhands: function(shorthand)
{
return this._longhands[shorthand];
},
/**
* @param {string} longhand
* @return {?Array.<string>}
*/
shorthands: function(longhand)
{
return this._shorthands[longhand];
}
}
WebInspector.CSSMetadata.initializeWithSupportedProperties([]);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.CSSModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.CSSModel, target);
this._domModel = WebInspector.DOMModel.fromTarget(target);
this._agent = target.cssAgent();
this._styleLoader = new WebInspector.CSSModel.ComputedStyleLoader(this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
target.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
this._agent.enable().then(this._wasEnabled.bind(this));
/** @type {!Map.<string, !WebInspector.CSSStyleSheetHeader>} */
this._styleSheetIdToHeader = new Map();
/** @type {!Map.<string, !Object.<!PageAgent.FrameId, !Array.<!CSSAgent.StyleSheetId>>>} */
this._styleSheetIdsForURL = new Map();
/** @type {!Multimap<string, !CSSAgent.StyleSheetId>} */
this._sourceMapLoadingStyleSheetsIds = new Multimap();
/** @type {!Map<string, !WebInspector.SourceMap>} */
this._sourceMapByURL = new Map();
/** @type {!Multimap<string, !WebInspector.CSSStyleSheetHeader>} */
this._sourceMapURLToHeaders = new Multimap();
WebInspector.moduleSetting("cssSourceMapsEnabled").addChangeListener(this._toggleSourceMapSupport, this);
}
WebInspector.CSSModel.Events = {
LayoutEditorChange: "LayoutEditorChange",
MediaQueryResultChanged: "MediaQueryResultChanged",
ModelWasEnabled: "ModelWasEnabled",
PseudoStateForced: "PseudoStateForced",
StyleSheetAdded: "StyleSheetAdded",
StyleSheetChanged: "StyleSheetChanged",
StyleSheetRemoved: "StyleSheetRemoved",
SourceMapAttached: "SourceMapAttached",
SourceMapDetached: "SourceMapDetached",
SourceMapChanged: "SourceMapChanged"
}
WebInspector.CSSModel.MediaTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"];
WebInspector.CSSModel.PseudoStateMarker = "pseudo-state-marker";
/**
* @constructor
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.TextRange} oldRange
* @param {string} newText
* @param {?Object} payload
*/
WebInspector.CSSModel.Edit = function(styleSheetId, oldRange, newText, payload)
{
this.styleSheetId = styleSheetId;
this.oldRange = oldRange;
this.newRange = WebInspector.TextRange.fromEdit(oldRange, newText);
this.payload = payload;
}
WebInspector.CSSModel.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_toggleSourceMapSupport: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
var headers = this.styleSheetHeaders();
for (var header of headers) {
if (enabled)
this._attachSourceMap(header);
else
this._detachSourceMap(header);
}
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {?WebInspector.SourceMap}
*/
sourceMapForHeader: function(header)
{
return this._sourceMapByURL.get(header.sourceMapURL) || null;
},
_sourceMapLoadedForTest: function() { },
/**
* @param {!WebInspector.SourceMap} sourceMap
* @return {!Array<!WebInspector.CSSStyleSheetHeader>}
*/
headersForSourceMap: function(sourceMap)
{
return this._sourceMapURLToHeaders.get(sourceMap.url()).valuesArray();
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
_attachSourceMap: function(header)
{
var sourceMapURL = header.sourceMapURL;
if (!sourceMapURL || !WebInspector.moduleSetting("cssSourceMapsEnabled").get())
return;
if (this._sourceMapByURL.has(sourceMapURL)) {
attach.call(this, sourceMapURL, header);
return;
}
if (!this._sourceMapLoadingStyleSheetsIds.has(sourceMapURL)) {
WebInspector.TextSourceMap.load(sourceMapURL, header.sourceURL)
.then(onTextSourceMapLoaded.bind(this, sourceMapURL))
.then(onSourceMap.bind(this, sourceMapURL));
}
this._sourceMapLoadingStyleSheetsIds.set(sourceMapURL, header.id);
/**
* @param {string} sourceMapURL
* @param {?WebInspector.TextSourceMap} sourceMap
* @return {!Promise<?WebInspector.SourceMap>}
* @this {WebInspector.CSSModel}
*/
function onTextSourceMapLoaded(sourceMapURL, sourceMap)
{
if (!sourceMap)
return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null));
var factoryExtension = this._factoryForSourceMap(sourceMap);
if (!factoryExtension)
return Promise.resolve(/** @type {?WebInspector.SourceMap} */(sourceMap));
return factoryExtension.instancePromise()
.then(factory => factory.editableSourceMap(this.target(), sourceMap))
.then(map => map || sourceMap)
.catchException(/** @type {?WebInspector.SourceMap} */(null));
}
/**
* @param {string} sourceMapURL
* @param {?WebInspector.SourceMap} sourceMap
* @this {WebInspector.CSSModel}
*/
function onSourceMap(sourceMapURL, sourceMap)
{
this._sourceMapLoadedForTest();
var styleSheetIds = this._sourceMapLoadingStyleSheetsIds.get(sourceMapURL);
this._sourceMapLoadingStyleSheetsIds.removeAll(sourceMapURL);
if (!sourceMap)
return;
var headers = new Set();
for (var styleSheetId of styleSheetIds) {
var header = this.styleSheetHeaderForId(styleSheetId);
if (header)
headers.add(header);
}
if (!headers.size)
return;
if (sourceMap.editable())
WebInspector.console.log(WebInspector.UIString("LiveSASS started: %s", sourceMapURL));
this._sourceMapByURL.set(sourceMapURL, sourceMap);
for (var header of headers)
attach.call(this, sourceMapURL, header);
}
/**
* @param {string} sourceMapURL
* @param {!WebInspector.CSSStyleSheetHeader} header
* @this {WebInspector.CSSModel}
*/
function attach(sourceMapURL, header)
{
this._sourceMapURLToHeaders.set(sourceMapURL, header);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapAttached, header);
}
},
/**
* @param {!WebInspector.SourceMap} sourceMap
* @return {?Runtime.Extension}
*/
_factoryForSourceMap: function(sourceMap)
{
var sourceExtensions = new Set(sourceMap.sourceURLs().map(url => WebInspector.TextUtils.extension(url)));
for (var runtimeExtension of self.runtime.extensions(WebInspector.SourceMapFactory)) {
var supportedExtensions = new Set(runtimeExtension.descriptor()["extensions"]);
if (supportedExtensions.containsAll(sourceExtensions))
return runtimeExtension;
}
return null;
},
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
_detachSourceMap: function(header)
{
if (!header.sourceMapURL || !this._sourceMapURLToHeaders.hasValue(header.sourceMapURL, header))
return;
this._sourceMapURLToHeaders.remove(header.sourceMapURL, header);
if (!this._sourceMapURLToHeaders.has(header.sourceMapURL))
var sourceMap = this._sourceMapByURL.get(header.sourceMapURL);
if (sourceMap.editable())
WebInspector.console.log(WebInspector.UIString("LiveSASS stopped: %s", header.sourceMapURL));
this._sourceMapByURL.delete(header.sourceMapURL);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapDetached, header);
},
/**
* @return {!WebInspector.DOMModel}
*/
domModel: function()
{
return /** @type {!WebInspector.DOMModel} */(this._domModel);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.TextRange} range
* @param {string} text
* @param {boolean} majorChange
* @return {!Promise<boolean>}
*/
setStyleText: function(styleSheetId, range, text, majorChange)
{
var original = this._innerSetStyleTexts.bind(this, [styleSheetId], [range], [text], majorChange);
var header = this.styleSheetHeaderForId(styleSheetId);
if (!header)
return original();
var sourceMap = this.sourceMapForHeader(header);
if (!sourceMap)
return original();
var originalAndDetach = originalAndDetachIfSuccess.bind(this, header);
if (!sourceMap.editable())
return originalAndDetach();
return /** @type {!Promise<boolean>} */(sourceMap.editCompiled([range], [text])
.then(onEditingDone.bind(this))
.catch(onError.bind(this, header)));
/**
* @param {?WebInspector.SourceMap.EditResult} editResult
* @return {!Promise<boolean>}
* @this {WebInspector.CSSModel}
*/
function onEditingDone(editResult)
{
if (!editResult)
return originalAndDetach();
var edits = editResult.compiledEdits;
if (!edits.length)
return onCSSPatched.call(this, editResult, true);
edits.sort(WebInspector.SourceEdit.comparator);
edits = edits.reverse();
var styleSheetIds = [];
var ranges = [];
var texts = [];
for (var edit of edits) {
styleSheetIds.push(header.id);
ranges.push(edit.oldRange);
texts.push(edit.newText);
}
return this._innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange)
.then(onCSSPatched.bind(this, editResult));
}
/**
* @param {!WebInspector.SourceMap.EditResult} editResult
* @param {boolean} success
* @return {!Promise<boolean>}
* @this {WebInspector.CSSModel}
*/
function onCSSPatched(editResult, success)
{
if (!success)
return originalAndDetach();
this._sourceMapByURL.set(header.sourceMapURL, editResult.map);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapChanged, {
sourceMap: editResult.map,
newSources: editResult.newSources
});
return Promise.resolve(true);
}
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @param {*} error
* @return {!Promise<boolean>}
* @this {WebInspector.CSSModel}
*/
function onError(header, error)
{
WebInspector.console.error(WebInspector.UIString("LiveSASS failed: %s", sourceMap.compiledURL()));
console.error(error);
this._detachSourceMap(header);
return original();
}
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {!Promise<boolean>}
* @this {WebInspector.CSSModel}
*/
function originalAndDetachIfSuccess(header)
{
return this._innerSetStyleTexts([styleSheetId], [range], [text], majorChange)
.then(detachIfSuccess.bind(this));
/**
* @param {boolean} success
* @return {boolean}
* @this {WebInspector.CSSModel}
*/
function detachIfSuccess(success)
{
if (success)
this._detachSourceMap(header);
return success;
}
}
},
/**
* @param {!Array<!CSSAgent.StyleSheetId>} styleSheetIds
* @param {!Array<!WebInspector.TextRange>} ranges
* @param {!Array<string>} texts
* @param {boolean} majorChange
* @return {!Promise<boolean>}
*/
_innerSetStyleTexts: function(styleSheetIds, ranges, texts, majorChange)
{
/**
* @param {?Protocol.Error} error
* @param {?Array<!CSSAgent.CSSStyle>} stylePayloads
* @return {boolean}
* @this {WebInspector.CSSModel}
*/
function parsePayload(error, stylePayloads)
{
if (error || !stylePayloads || stylePayloads.length !== ranges.length)
return false;
if (majorChange)
this._domModel.markUndoableState();
for (var i = 0; i < ranges.length; ++i) {
var edit = new WebInspector.CSSModel.Edit(styleSheetIds[i], ranges[i], texts[i], stylePayloads[i]);
this._fireStyleSheetChanged(styleSheetIds[i], edit);
}
return true;
}
console.assert(styleSheetIds.length === ranges.length && ranges.length === texts.length, "Array lengths must be equal");
var edits = [];
for (var i = 0; i < styleSheetIds.length; ++i) {
edits.push({
styleSheetId: styleSheetIds[i],
range: ranges[i].serializeToObject(),
text: texts[i]
});
}
return this._agent.setStyleTexts(edits, parsePayload.bind(this))
.catchException(false);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.TextRange} range
* @param {string} text
* @return {!Promise<boolean>}
*/
setSelectorText: function(styleSheetId, range, text)
{
/**
* @param {?Protocol.Error} error
* @param {?CSSAgent.SelectorList} selectorPayload
* @return {boolean}
* @this {WebInspector.CSSModel}
*/
function callback(error, selectorPayload)
{
if (error || !selectorPayload)
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, range, text, selectorPayload);
this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return true;
}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);
return this._agent.setRuleSelector(styleSheetId, range, text, callback.bind(this))
.catchException(false);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.TextRange} range
* @param {string} text
* @return {!Promise<boolean>}
*/
setKeyframeKey: function(styleSheetId, range, text)
{
/**
* @param {?Protocol.Error} error
* @param {!CSSAgent.Value} payload
* @return {boolean}
* @this {WebInspector.CSSModel}
*/
function callback(error, payload)
{
if (error || !payload)
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, range, text, payload);
this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return true;
}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);
return this._agent.setKeyframeKey(styleSheetId, range, text, callback.bind(this))
.catchException(false);
},
/**
* @return {!Promise.<!Array.<!WebInspector.CSSMedia>>}
*/
mediaQueriesPromise: function()
{
/**
* @param {?Protocol.Error} error
* @param {?Array.<!CSSAgent.CSSMedia>} payload
* @return {!Array.<!WebInspector.CSSMedia>}
* @this {!WebInspector.CSSModel}
*/
function parsePayload(error, payload)
{
return !error && payload ? WebInspector.CSSMedia.parseMediaArrayPayload(this, payload) : [];
}
return this._agent.getMediaQueries(parsePayload.bind(this));
},
/**
* @return {boolean}
*/
isEnabled: function()
{
return this._isEnabled;
},
/**
* @param {?Protocol.Error} error
*/
_wasEnabled: function(error)
{
if (error) {
console.error("Failed to enabled CSS agent: " + error);
return;
}
this._isEnabled = true;
this.dispatchEventToListeners(WebInspector.CSSModel.Events.ModelWasEnabled);
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {!Promise.<?WebInspector.CSSMatchedStyles>}
*/
matchedStylesPromise: function(nodeId)
{
/**
* @param {?Protocol.Error} error
* @param {?CSSAgent.CSSStyle=} inlinePayload
* @param {?CSSAgent.CSSStyle=} attributesPayload
* @param {!Array.<!CSSAgent.RuleMatch>=} matchedPayload
* @param {!Array.<!CSSAgent.PseudoElementMatches>=} pseudoPayload
* @param {!Array.<!CSSAgent.InheritedStyleEntry>=} inheritedPayload
* @param {!Array.<!CSSAgent.CSSKeyframesRule>=} animationsPayload
* @return {?WebInspector.CSSMatchedStyles}
* @this {WebInspector.CSSModel}
*/
function callback(error, inlinePayload, attributesPayload, matchedPayload, pseudoPayload, inheritedPayload, animationsPayload)
{
if (error)
return null;
var node = this._domModel.nodeForId(nodeId);
if (!node)
return null;
return new WebInspector.CSSMatchedStyles(this, node, inlinePayload || null, attributesPayload || null, matchedPayload || [], pseudoPayload || [], inheritedPayload || [], animationsPayload || []);
}
return this._agent.getMatchedStylesForNode(nodeId, callback.bind(this));
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {!Promise.<?Map.<string, string>>}
*/
computedStylePromise: function(nodeId)
{
return this._styleLoader.computedStylePromise(nodeId);
},
/**
* @param {number} nodeId
* @return {!Promise<?Array<string>>}
*/
backgroundColorsPromise: function(nodeId)
{
/**
* @param {?string} error
* @param {!Array<string>=} backgroundColors
* @return {?Array<string>}
*/
function backgroundColorsCallback(error, backgroundColors) {
return !error && backgroundColors ? backgroundColors : null;
}
return this._agent.getBackgroundColors(nodeId, backgroundColorsCallback);
},
/**
* @param {number} nodeId
* @return {!Promise.<?Array.<!CSSAgent.PlatformFontUsage>>}
*/
platformFontsPromise: function(nodeId)
{
/**
* @param {?Protocol.Error} error
* @param {?Array.<!CSSAgent.PlatformFontUsage>} fonts
* @return {?Array.<!CSSAgent.PlatformFontUsage>}
*/
function platformFontsCallback(error, fonts)
{
return !error && fonts ? fonts : null;
}
return this._agent.getPlatformFontsForNode(nodeId, platformFontsCallback);
},
/**
* @return {!Array.<!WebInspector.CSSStyleSheetHeader>}
*/
allStyleSheets: function()
{
var values = this._styleSheetIdToHeader.valuesArray();
/**
* @param {!WebInspector.CSSStyleSheetHeader} a
* @param {!WebInspector.CSSStyleSheetHeader} b
* @return {number}
*/
function styleSheetComparator(a, b)
{
if (a.sourceURL < b.sourceURL)
return -1;
else if (a.sourceURL > b.sourceURL)
return 1;
return a.startLine - b.startLine || a.startColumn - b.startColumn;
}
values.sort(styleSheetComparator);
return values;
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {!Promise.<?WebInspector.CSSModel.InlineStyleResult>}
*/
inlineStylesPromise: function(nodeId)
{
/**
* @param {?Protocol.Error} error
* @param {?CSSAgent.CSSStyle=} inlinePayload
* @param {?CSSAgent.CSSStyle=} attributesStylePayload
* @return {?WebInspector.CSSModel.InlineStyleResult}
* @this {WebInspector.CSSModel}
*/
function callback(error, inlinePayload, attributesStylePayload)
{
if (error || !inlinePayload)
return null;
var inlineStyle = inlinePayload ? new WebInspector.CSSStyleDeclaration(this, null, inlinePayload, WebInspector.CSSStyleDeclaration.Type.Inline) : null;
var attributesStyle = attributesStylePayload ? new WebInspector.CSSStyleDeclaration(this, null, attributesStylePayload, WebInspector.CSSStyleDeclaration.Type.Attributes) : null;
return new WebInspector.CSSModel.InlineStyleResult(inlineStyle, attributesStyle);
}
return this._agent.getInlineStylesForNode(nodeId, callback.bind(this));
},
/**
* @param {!WebInspector.DOMNode} node
* @param {string} pseudoClass
* @param {boolean} enable
* @return {boolean}
*/
forcePseudoState: function(node, pseudoClass, enable)
{
var pseudoClasses = node.marker(WebInspector.CSSModel.PseudoStateMarker) || [];
if (enable) {
if (pseudoClasses.indexOf(pseudoClass) >= 0)
return false;
pseudoClasses.push(pseudoClass);
node.setMarker(WebInspector.CSSModel.PseudoStateMarker, pseudoClasses);
} else {
if (pseudoClasses.indexOf(pseudoClass) < 0)
return false;
pseudoClasses.remove(pseudoClass);
if (pseudoClasses.length)
node.setMarker(WebInspector.CSSModel.PseudoStateMarker, pseudoClasses);
else
node.setMarker(WebInspector.CSSModel.PseudoStateMarker, null);
}
this._agent.forcePseudoState(node.id, pseudoClasses);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.PseudoStateForced, { node: node, pseudoClass: pseudoClass, enable: enable });
return true;
},
/**
* @param {!WebInspector.DOMNode} node
* @return {?Array<string>} state
*/
pseudoState: function(node)
{
return node.marker(WebInspector.CSSModel.PseudoStateMarker) || [];
},
/**
* @param {!WebInspector.CSSMedia} media
* @param {string} newMediaText
* @param {function(?WebInspector.CSSMedia)} userCallback
*/
setMediaText: function(media, newMediaText, userCallback)
{
/**
* @param {?Protocol.Error} error
* @param {!CSSAgent.CSSMedia} mediaPayload
* @return {boolean}
* @this {WebInspector.CSSModel}
*/
function parsePayload(error, mediaPayload)
{
if (!mediaPayload)
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(media.parentStyleSheetId, media.range, newMediaText, mediaPayload);
this._fireStyleSheetChangedAndDetach(media.parentStyleSheetId, edit);
return true;
}
console.assert(!!media.parentStyleSheetId);
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);
this._agent.setMediaText(media.parentStyleSheetId, media.range, newMediaText, parsePayload.bind(this))
.catchException(null)
.then(userCallback);
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {string} ruleText
* @param {!WebInspector.TextRange} ruleLocation
* @return {!Promise<?WebInspector.CSSStyleRule>}
*/
addRule: function(styleSheetId, ruleText, ruleLocation)
{
return this._agent.addRule(styleSheetId, ruleText, ruleLocation, parsePayload.bind(this))
.catchException(/** @type {?WebInspector.CSSStyleRule} */(null))
/**
* @param {?Protocol.Error} error
* @param {?CSSAgent.CSSRule} rulePayload
* @return {?WebInspector.CSSStyleRule}
* @this {WebInspector.CSSModel}
*/
function parsePayload(error, rulePayload)
{
if (error || !rulePayload)
return null;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, ruleLocation, ruleText, rulePayload);
this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return new WebInspector.CSSStyleRule(this, rulePayload);
}
},
/**
* @param {!WebInspector.DOMNode} node
* @param {function(?WebInspector.CSSStyleSheetHeader)} userCallback
*/
requestViaInspectorStylesheet: function(node, userCallback)
{
var frameId = node.frameId() || this.target().resourceTreeModel.mainFrame.id;
var headers = this._styleSheetIdToHeader.valuesArray();
for (var i = 0; i < headers.length; ++i) {
var styleSheetHeader = headers[i];
if (styleSheetHeader.frameId === frameId && styleSheetHeader.isViaInspector()) {
userCallback(styleSheetHeader);
return;
}
}
/**
* @param {?Protocol.Error} error
* @param {?CSSAgent.StyleSheetId} styleSheetId
* @return {?WebInspector.CSSStyleSheetHeader}
* @this {WebInspector.CSSModel}
*/
function innerCallback(error, styleSheetId)
{
return !error && styleSheetId ? this._styleSheetIdToHeader.get(styleSheetId) || null : null;
}
this._agent.createStyleSheet(frameId, innerCallback.bind(this))
.catchException(null)
.then(userCallback)
},
mediaQueryResultChanged: function()
{
this.dispatchEventToListeners(WebInspector.CSSModel.Events.MediaQueryResultChanged);
},
/**
* @param {!CSSAgent.StyleSheetId} id
* @return {?WebInspector.CSSStyleSheetHeader}
*/
styleSheetHeaderForId: function(id)
{
return this._styleSheetIdToHeader.get(id) || null;
},
/**
* @return {!Array.<!WebInspector.CSSStyleSheetHeader>}
*/
styleSheetHeaders: function()
{
return this._styleSheetIdToHeader.valuesArray();
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.CSSModel.Edit=} edit
*/
_fireStyleSheetChanged: function(styleSheetId, edit)
{
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, edit: edit });
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {!WebInspector.CSSModel.Edit=} edit
*/
_fireStyleSheetChangedAndDetach: function(styleSheetId, edit)
{
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, edit: edit });
var header = this.styleSheetHeaderForId(styleSheetId);
if (header)
this._detachSourceMap(header);
},
/**
* @param {!CSSAgent.CSSStyleSheetHeader} header
*/
_styleSheetAdded: function(header)
{
console.assert(!this._styleSheetIdToHeader.get(header.styleSheetId));
var styleSheetHeader = new WebInspector.CSSStyleSheetHeader(this, header);
this._styleSheetIdToHeader.set(header.styleSheetId, styleSheetHeader);
var url = styleSheetHeader.resourceURL();
if (!this._styleSheetIdsForURL.get(url))
this._styleSheetIdsForURL.set(url, {});
var frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
var styleSheetIds = frameIdToStyleSheetIds[styleSheetHeader.frameId];
if (!styleSheetIds) {
styleSheetIds = [];
frameIdToStyleSheetIds[styleSheetHeader.frameId] = styleSheetIds;
}
styleSheetIds.push(styleSheetHeader.id);
this._attachSourceMap(styleSheetHeader);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetAdded, styleSheetHeader);
},
/**
* @param {!CSSAgent.StyleSheetId} id
*/
_styleSheetRemoved: function(id)
{
var header = this._styleSheetIdToHeader.get(id);
console.assert(header);
if (!header)
return;
this._styleSheetIdToHeader.remove(id);
var url = header.resourceURL();
var frameIdToStyleSheetIds = /** @type {!Object.<!PageAgent.FrameId, !Array.<!CSSAgent.StyleSheetId>>} */ (this._styleSheetIdsForURL.get(url));
console.assert(frameIdToStyleSheetIds, "No frameId to styleSheetId map is available for given style sheet URL.");
frameIdToStyleSheetIds[header.frameId].remove(id);
if (!frameIdToStyleSheetIds[header.frameId].length) {
delete frameIdToStyleSheetIds[header.frameId];
if (!Object.keys(frameIdToStyleSheetIds).length)
this._styleSheetIdsForURL.remove(url);
}
this._detachSourceMap(header);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved, header);
},
/**
* @param {string} url
* @return {!Array.<!CSSAgent.StyleSheetId>}
*/
styleSheetIdsForURL: function(url)
{
var frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
if (!frameIdToStyleSheetIds)
return [];
var result = [];
for (var frameId in frameIdToStyleSheetIds)
result = result.concat(frameIdToStyleSheetIds[frameId]);
return result;
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {string} newText
* @param {boolean} majorChange
* @return {!Promise.<?Protocol.Error>}
*/
setStyleSheetText: function(styleSheetId, newText, majorChange)
{
var header = /** @type {!WebInspector.CSSStyleSheetHeader} */(this._styleSheetIdToHeader.get(styleSheetId));
console.assert(header);
newText = WebInspector.CSSModel.trimSourceURL(newText);
if (header.hasSourceURL)
newText += "\n/*# sourceURL=" + header.sourceURL + " */";
return this._agent.setStyleSheetText(header.id, newText, callback.bind(this));
/**
* @param {?Protocol.Error} error
* @param {string=} sourceMapURL
* @return {?Protocol.Error}
* @this {WebInspector.CSSModel}
*/
function callback(error, sourceMapURL)
{
this._detachSourceMap(header);
header.setSourceMapURL(sourceMapURL);
this._attachSourceMap(header);
if (error)
return error;
if (majorChange)
this._domModel.markUndoableState();
this._fireStyleSheetChanged(styleSheetId);
return null;
}
},
/**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @return {!Promise<string>}
*/
getStyleSheetText: function(styleSheetId)
{
/**
* @param {?Protocol.Error} error
* @param {?string} text
* @return {string}
*/
function textCallback(error, text)
{
if (error || text === null) {
WebInspector.console.error("Failed to get text for stylesheet " + styleSheetId + ": " + error)
text = "";
// Fall through.
}
return WebInspector.CSSModel.trimSourceURL(text);
}
return this._agent.getStyleSheetText(styleSheetId, textCallback)
.catchException(/** @type {string} */(""));
},
_mainFrameNavigated: function()
{
this._resetStyleSheets();
},
_resetStyleSheets: function()
{
var headers = this._styleSheetIdToHeader.valuesArray();
this._styleSheetIdsForURL.clear();
this._styleSheetIdToHeader.clear();
for (var i = 0; i < headers.length; ++i) {
this._detachSourceMap(headers[i]);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved, headers[i]);
}
this._sourceMapByURL.clear();
this._sourceMapURLToHeaders.clear();
this._sourceMapLoadingStyleSheetsIds.clear();
},
/**
* @override
* @return {!Promise}
*/
suspendModel: function()
{
this._isEnabled = false;
return this._agent.disable().then(this._resetStyleSheets.bind(this));
},
/**
* @override
* @return {!Promise}
*/
resumeModel: function()
{
return this._agent.enable().then(this._wasEnabled.bind(this));
},
/**
* @param {!CSSAgent.StyleSheetId} id
* @param {!CSSAgent.SourceRange} range
*/
_layoutEditorChange: function(id, range)
{
this.dispatchEventToListeners(WebInspector.CSSModel.Events.LayoutEditorChange, {id: id, range: range});
},
/**
* @param {number} nodeId
* @param {string} name
* @param {string} value
*/
setEffectivePropertyValueForNode: function(nodeId, name, value)
{
this._agent.setEffectivePropertyValueForNode(nodeId, name, value);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @param {string} text
* @return {string}
*/
WebInspector.CSSModel.trimSourceURL = function(text)
{
var sourceURLIndex = text.lastIndexOf("/*# sourceURL=");
if (sourceURLIndex === -1) {
sourceURLIndex = text.lastIndexOf("/*@ sourceURL=");
if (sourceURLIndex === -1)
return text;
}
var sourceURLLineIndex = text.lastIndexOf("\n", sourceURLIndex);
if (sourceURLLineIndex === -1)
return text;
var sourceURLLine = text.substr(sourceURLLineIndex + 1).split("\n", 1)[0];
var sourceURLRegex = /[\040\t]*\/\*[#@] sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/;
if (sourceURLLine.search(sourceURLRegex) === -1)
return text;
return text.substr(0, sourceURLLineIndex) + text.substr(sourceURLLineIndex + sourceURLLine.length + 1);
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.CSSStyleSheetHeader} header
* @param {number} lineNumber
* @param {number=} columnNumber
*/
WebInspector.CSSLocation = function(header, lineNumber, columnNumber)
{
WebInspector.SDKObject.call(this, header.target());
this._header = header;
this.styleSheetId = header.id;
this.url = header.resourceURL();
this.lineNumber = lineNumber;
this.columnNumber = columnNumber || 0;
}
WebInspector.CSSLocation.prototype = {
/**
* @return {!WebInspector.CSSModel}
*/
cssModel: function()
{
return this._header.cssModel();
},
/**
* @return {!WebInspector.CSSStyleSheetHeader}
*/
header: function()
{
return this._header;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @implements {CSSAgent.Dispatcher}
* @param {!WebInspector.CSSModel} cssModel
*/
WebInspector.CSSDispatcher = function(cssModel)
{
this._cssModel = cssModel;
}
WebInspector.CSSDispatcher.prototype = {
/**
* @override
*/
mediaQueryResultChanged: function()
{
this._cssModel.mediaQueryResultChanged();
},
/**
* @override
* @param {!CSSAgent.StyleSheetId} styleSheetId
*/
styleSheetChanged: function(styleSheetId)
{
this._cssModel._fireStyleSheetChangedAndDetach(styleSheetId);
},
/**
* @override
* @param {!CSSAgent.CSSStyleSheetHeader} header
*/
styleSheetAdded: function(header)
{
this._cssModel._styleSheetAdded(header);
},
/**
* @override
* @param {!CSSAgent.StyleSheetId} id
*/
styleSheetRemoved: function(id)
{
this._cssModel._styleSheetRemoved(id);
},
/**
* @override
* @param {!CSSAgent.StyleSheetId} id
* @param {!CSSAgent.SourceRange} range
*/
layoutEditorChange: function(id, range)
{
this._cssModel._layoutEditorChange(id, range);
},
}
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
*/
WebInspector.CSSModel.ComputedStyleLoader = function(cssModel)
{
this._cssModel = cssModel;
/** @type {!Map<!DOMAgent.NodeId, !Promise<?Map<string, string>>>} */
this._nodeIdToPromise = new Map();
}
WebInspector.CSSModel.ComputedStyleLoader.prototype = {
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {!Promise<?Map<string, string>>}
*/
computedStylePromise: function(nodeId)
{
if (!this._nodeIdToPromise.has(nodeId))
this._nodeIdToPromise.set(nodeId, this._cssModel._agent.getComputedStyleForNode(nodeId, parsePayload).then(cleanUp.bind(this)));
return /** @type {!Promise.<?Map.<string, string>>} */(this._nodeIdToPromise.get(nodeId));
/**
* @param {?Protocol.Error} error
* @param {!Array.<!CSSAgent.CSSComputedStyleProperty>} computedPayload
* @return {?Map.<string, string>}
*/
function parsePayload(error, computedPayload)
{
if (error || !computedPayload || !computedPayload.length)
return null;
var result = new Map();
for (var property of computedPayload)
result.set(property.name, property.value);
return result;
}
/**
* @param {?Map.<string, string>} computedStyle
* @return {?Map.<string, string>}
* @this {WebInspector.CSSModel.ComputedStyleLoader}
*/
function cleanUp(computedStyle)
{
this._nodeIdToPromise.delete(nodeId);
return computedStyle;
}
}
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.CSSModel}
*/
WebInspector.CSSModel.fromTarget = function(target)
{
if (!target.isPage())
return null;
return /** @type {?WebInspector.CSSModel} */ (target.model(WebInspector.CSSModel));
}
/**
* @param {!WebInspector.DOMNode} node
* @return {!WebInspector.CSSModel}
*/
WebInspector.CSSModel.fromNode = function(node)
{
return /** @type {!WebInspector.CSSModel} */ (WebInspector.CSSModel.fromTarget(node.target()));
}
/**
* @constructor
* @param {?WebInspector.CSSStyleDeclaration} inlineStyle
* @param {?WebInspector.CSSStyleDeclaration} attributesStyle
*/
WebInspector.CSSModel.InlineStyleResult = function(inlineStyle, attributesStyle)
{
this.inlineStyle = inlineStyle;
this.attributesStyle = attributesStyle;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | 2 1 1 | /**
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.CSSParser = function()
{
this._worker = new WorkerRuntime.Worker("formatter_worker");
this._worker.onmessage = this._onRuleChunk.bind(this);
this._rules = [];
}
WebInspector.CSSParser.Events = {
RulesParsed: "RulesParsed"
}
WebInspector.CSSParser.prototype = {
/**
* @param {!WebInspector.CSSStyleSheetHeader} styleSheetHeader
* @param {function(!Array.<!WebInspector.CSSParser.Rule>)=} callback
*/
fetchAndParse: function(styleSheetHeader, callback)
{
this._lock();
this._finishedCallback = callback;
styleSheetHeader.requestContent().then(this._innerParse.bind(this));
},
/**
* @param {string} text
* @param {function(!Array.<!WebInspector.CSSParser.Rule>)=} callback
*/
parse: function(text, callback)
{
this._lock();
this._finishedCallback = callback;
this._innerParse(text);
},
/**
* @param {string} text
* @return {!Promise<!Array.<!WebInspector.CSSParser.Rule>>}
*/
parsePromise: function(text)
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function()} succ
* @param {function()} fail
* @this {WebInspector.CSSParser}
*/
function promiseConstructor(succ, fail)
{
this.parse(text, succ);
}
},
dispose: function()
{
if (this._worker) {
this._worker.terminate();
delete this._worker;
this._runFinishedCallback([]);
}
},
/**
* @return {!Array.<!WebInspector.CSSParser.Rule>}
*/
rules: function()
{
return this._rules;
},
_lock: function()
{
console.assert(!this._parsingStyleSheet, "Received request to parse stylesheet before previous was completed.");
this._parsingStyleSheet = true;
},
_unlock: function()
{
delete this._parsingStyleSheet;
},
/**
* @param {?string} text
*/
_innerParse: function(text)
{
this._rules = [];
this._worker.postMessage({ method: "parseCSS", params: { content: text } });
},
/**
* @param {!MessageEvent} event
*/
_onRuleChunk: function(event)
{
var data = /** @type {!WebInspector.CSSParser.DataChunk} */ (event.data);
var chunk = data.chunk;
for (var i = 0; i < chunk.length; ++i)
this._rules.push(chunk[i]);
if (data.isLastChunk)
this._onFinishedParsing();
this.dispatchEventToListeners(WebInspector.CSSParser.Events.RulesParsed);
},
_onFinishedParsing: function()
{
this._unlock();
this._runFinishedCallback(this._rules);
},
/**
* @param {!Array<!WebInspector.CSSRule>} rules
*/
_runFinishedCallback: function(rules)
{
var callback = this._finishedCallback;
delete this._finishedCallback;
if (callback)
callback.call(null, rules);
},
__proto__: WebInspector.Object.prototype,
}
/**
* @typedef {{isLastChunk: boolean, chunk: !Array.<!WebInspector.CSSParser.Rule>}}
*/
WebInspector.CSSParser.DataChunk;
/**
* @constructor
*/
WebInspector.CSSParser.StyleRule = function()
{
/** @type {string} */
this.selectorText;
/** @type {!WebInspector.CSSParser.Range} */
this.styleRange;
/** @type {number} */
this.lineNumber;
/** @type {number} */
this.columnNumber;
/** @type {!Array.<!WebInspector.CSSParser.Property>} */
this.properties;
}
/**
* @typedef {{atRule: string, lineNumber: number, columnNumber: number}}
*/
WebInspector.CSSParser.AtRule;
/**
* @typedef {(WebInspector.CSSParser.StyleRule|WebInspector.CSSParser.AtRule)}
*/
WebInspector.CSSParser.Rule;
/**
* @typedef {{startLine: number, startColumn: number, endLine: number, endColumn: number}}
*/
WebInspector.CSSParser.Range;
/**
* @constructor
*/
WebInspector.CSSParser.Property = function()
{
/** @type {string} */
this.name;
/** @type {!WebInspector.CSSParser.Range} */
this.nameRange;
/** @type {string} */
this.value;
/** @type {!WebInspector.CSSParser.Range} */
this.valueRange;
/** @type {!WebInspector.CSSParser.Range} */
this.range;
/** @type {(boolean|undefined)} */
this.disabled;
}
/**
* @constructor
*/
WebInspector.CSSParserService = function()
{
this._cssParser = null;
this._cssRequests = [];
this._terminated = false;
}
WebInspector.CSSParserService.prototype = {
/**
* @param {string} text
* @return {!Promise<!Array.<!WebInspector.CSSParser.Rule>>}
*/
parseCSS: function(text)
{
console.assert(!this._terminated, "Illegal call parseCSS on terminated CSSParserService.");
if (!this._cssParser)
this._cssParser = new WebInspector.CSSParser();
var request = new WebInspector.CSSParserService.ParseRequest(text);
this._cssRequests.push(request);
this._maybeParseCSS();
return request.parsedPromise;
},
_maybeParseCSS: function()
{
if (this._terminated || this._isParsingCSS || !this._cssRequests.length)
return;
this._isParsingCSS = true;
var request = this._cssRequests.shift();
this._cssParser.parsePromise(request.text)
.catchException(/** @type {!Array.<!WebInspector.CSSParser.Rule>} */([]))
.then(onCSSParsed.bind(this));
/**
* @param {!Array.<!WebInspector.CSSParser.Rule>} rules
* @this {WebInspector.CSSParserService}
*/
function onCSSParsed(rules)
{
request.parsedCallback.call(null, rules);
this._isParsingCSS = false;
this._maybeParseCSS();
}
},
dispose: function()
{
if (this._terminated)
return;
this._terminated = true;
if (this._cssParser)
this._cssParser.dispose();
for (var request of this._cssRequests)
request.parsedCallback.call(null, /** @type {!Array.<!WebInspector.CSSParser.Rule>} */([]));
this._cssRequests = [];
},
}
/**
* @constructor
* @param {string} text
*/
WebInspector.CSSParserService.ParseRequest = function(text)
{
this.text = text;
/** @type {function(!Array.<!WebInspector.CSSParser.Rule>)} */
this.parsedCallback;
this.parsedPromise = new Promise(fulfill => this.parsedCallback = fulfill);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | 2 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.CSSStyleDeclaration} ownerStyle
* @param {number} index
* @param {string} name
* @param {string} value
* @param {boolean} important
* @param {boolean} disabled
* @param {boolean} parsedOk
* @param {boolean} implicit
* @param {?string=} text
* @param {!CSSAgent.SourceRange=} range
*/
WebInspector.CSSProperty = function(ownerStyle, index, name, value, important, disabled, parsedOk, implicit, text, range)
{
this.ownerStyle = ownerStyle;
this.index = index;
this.name = name;
this.value = value;
this.important = important;
this.disabled = disabled;
this.parsedOk = parsedOk;
this.implicit = implicit; // A longhand, implicitly set by missing values of shorthand.
this.text = text;
this.range = range ? WebInspector.TextRange.fromObject(range) : null;
this._active = true;
}
/**
* @param {!WebInspector.CSSStyleDeclaration} ownerStyle
* @param {number} index
* @param {!CSSAgent.CSSProperty} payload
* @return {!WebInspector.CSSProperty}
*/
WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{
// The following default field values are used in the payload:
// important: false
// parsedOk: true
// implicit: false
// disabled: false
var result = new WebInspector.CSSProperty(
ownerStyle, index, payload.name, payload.value, payload.important || false, payload.disabled || false, ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text, payload.range);
return result;
}
WebInspector.CSSProperty.prototype = {
/**
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.ownerStyle.styleSheetId !== edit.styleSheetId)
return;
if (this.range)
this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
},
/**
* @param {boolean} active
*/
_setActive: function(active)
{
this._active = active;
},
get propertyText()
{
if (this.text !== undefined)
return this.text;
if (this.name === "")
return "";
return this.name + ": " + this.value + (this.important ? " !important" : "") + ";";
},
/**
* @return {boolean}
*/
activeInStyle: function()
{
return this._active;
},
/**
* @param {string} propertyText
* @param {boolean} majorChange
* @param {boolean} overwrite
* @return {!Promise.<boolean>}
*/
setText: function(propertyText, majorChange, overwrite)
{
if (!this.ownerStyle)
return Promise.reject(new Error("No ownerStyle for property"));
if (!this.ownerStyle.styleSheetId)
return Promise.reject(new Error("No owner style id"));
if (!this.range || !this.ownerStyle.range)
return Promise.reject(new Error("Style not editable"));
if (majorChange)
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);
if (overwrite && propertyText === this.propertyText) {
if (majorChange)
this.ownerStyle.cssModel().domModel().markUndoableState();
return Promise.resolve(true);
}
var range = this.range.relativeTo(this.ownerStyle.range.startLine, this.ownerStyle.range.startColumn);
var indentation = this.ownerStyle.cssText ? this._detectIndentation(this.ownerStyle.cssText) : WebInspector.moduleSetting("textEditorIndent").get();
var endIndentation = this.ownerStyle.cssText ? indentation.substring(0, this.ownerStyle.range.endColumn) : "";
var text = new WebInspector.Text(this.ownerStyle.cssText || "");
var newStyleText = text.replaceRange(range, String.sprintf(";%s;", propertyText));
return self.runtime.instancePromise(WebInspector.TokenizerFactory)
.then(this._formatStyle.bind(this, newStyleText, indentation, endIndentation))
.then(setStyleText.bind(this));
/**
* @param {string} styleText
* @this {WebInspector.CSSProperty}
* @return {!Promise.<boolean>}
*/
function setStyleText(styleText)
{
return this.ownerStyle.setText(styleText, majorChange);
}
},
/**
* @param {string} styleText
* @param {string} indentation
* @param {string} endIndentation
* @param {!WebInspector.TokenizerFactory} tokenizerFactory
* @return {string}
*/
_formatStyle: function(styleText, indentation, endIndentation, tokenizerFactory)
{
if (indentation)
indentation = "\n" + indentation;
var result = "";
var propertyText;
var insideProperty = false;
var tokenize = tokenizerFactory.createTokenizer("text/css");
tokenize("*{" + styleText + "}", processToken);
if (insideProperty)
result += propertyText;
result = result.substring(2, result.length - 1).trimRight();
return result + (indentation ? "\n" + endIndentation : "");
/**
* @param {string} token
* @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
*/
function processToken(token, tokenType, column, newColumn)
{
if (!insideProperty) {
var disabledProperty = tokenType && tokenType.includes("css-comment") && isDisabledProperty(token);
var isPropertyStart = tokenType && (tokenType.includes("css-string") || tokenType.includes("css-meta") || tokenType.includes("css-property") || tokenType.includes("css-variable-2"));
if (disabledProperty) {
result = result.trimRight() + indentation + token;
} else if (isPropertyStart) {
insideProperty = true;
propertyText = token;
} else if (token !== ";") {
result += token;
}
return;
}
if (token === "}" || token === ";") {
result = result.trimRight() + indentation + propertyText.trim() + ";";
insideProperty = false;
if (token === "}")
result += "}";
} else {
propertyText += token;
}
}
/**
* @param {string} text
* @return {boolean}
*/
function isDisabledProperty(text)
{
var colon = text.indexOf(":");
if (colon === -1)
return false;
var propertyName = text.substring(2, colon).trim();
return WebInspector.CSSMetadata.isCSSPropertyName(propertyName);
}
},
/**
* @param {string} text
* @return {string}
*/
_detectIndentation: function(text)
{
var lines = text.split("\n");
if (lines.length < 2)
return "";
return WebInspector.TextUtils.lineIndent(lines[1]);
},
/**
* @param {string} newValue
* @param {boolean} majorChange
* @param {boolean} overwrite
* @param {function(boolean)=} userCallback
*/
setValue: function(newValue, majorChange, overwrite, userCallback)
{
var text = this.name + ": " + newValue + (this.important ? " !important" : "") + ";";
this.setText(text, majorChange, overwrite).then(userCallback);
},
/**
* @param {boolean} disabled
* @return {!Promise.<boolean>}
*/
setDisabled: function(disabled)
{
if (!this.ownerStyle)
return Promise.resolve(false);
if (disabled === this.disabled)
return Promise.resolve(true);
var propertyText = this.text.trim();
var text = disabled ? "/* " + propertyText + " */" : this.text.substring(2, propertyText.length - 2).trim();
return this.setText(text, true, true);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!CSSAgent.Value} payload
*/
WebInspector.CSSValue = function(payload)
{
this.text = payload.text;
if (payload.range)
this.range = WebInspector.TextRange.fromObject(payload.range);
}
WebInspector.CSSValue.prototype = {
/**
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (!this.range)
return;
this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
}
}
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {{style: !CSSAgent.CSSStyle, styleSheetId: (string|undefined), origin: !CSSAgent.StyleSheetOrigin}} payload
*/
WebInspector.CSSRule = function(cssModel, payload)
{
this._cssModel = cssModel;
this.styleSheetId = payload.styleSheetId;
if (this.styleSheetId) {
var styleSheetHeader = cssModel.styleSheetHeaderForId(this.styleSheetId);
this.sourceURL = styleSheetHeader.sourceURL;
}
this.origin = payload.origin;
this.style = new WebInspector.CSSStyleDeclaration(this._cssModel, this, payload.style, WebInspector.CSSStyleDeclaration.Type.Regular);
}
WebInspector.CSSRule.prototype = {
/**
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.styleSheetId !== edit.styleSheetId)
return;
this.style.rebase(edit);
},
/**
* @return {string}
*/
resourceURL: function()
{
if (!this.styleSheetId)
return "";
var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
return styleSheetHeader.resourceURL();
},
/**
* @return {boolean}
*/
isUserAgent: function()
{
return this.origin === CSSAgent.StyleSheetOrigin.UserAgent;
},
/**
* @return {boolean}
*/
isInjected: function()
{
return this.origin === CSSAgent.StyleSheetOrigin.Injected;
},
/**
* @return {boolean}
*/
isViaInspector: function()
{
return this.origin === CSSAgent.StyleSheetOrigin.Inspector;
},
/**
* @return {boolean}
*/
isRegular: function()
{
return this.origin === CSSAgent.StyleSheetOrigin.Regular;
}
}
/**
* @constructor
* @extends {WebInspector.CSSRule}
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSRule} payload
*/
WebInspector.CSSStyleRule = function(cssModel, payload)
{
WebInspector.CSSRule.call(this, cssModel, payload);
this._reinitializeSelectors(payload.selectorList);
this.media = payload.media ? WebInspector.CSSMedia.parseMediaArrayPayload(cssModel, payload.media) : [];
}
/**
* @param {!WebInspector.CSSModel} cssModel
* @param {string} selectorText
* @return {!WebInspector.CSSStyleRule}
*/
WebInspector.CSSStyleRule.createDummyRule = function(cssModel, selectorText)
{
var dummyPayload = {
selectorList: {
selectors: [{ text: selectorText}],
},
style: {
styleSheetId: "0",
range: new WebInspector.TextRange(0, 0, 0, 0),
shorthandEntries: [],
cssProperties: []
}
};
return new WebInspector.CSSStyleRule(cssModel, /** @type {!CSSAgent.CSSRule} */(dummyPayload));
}
WebInspector.CSSStyleRule.prototype = {
/**
* @param {!CSSAgent.SelectorList} selectorList
*/
_reinitializeSelectors: function(selectorList)
{
/** @type {!Array.<!WebInspector.CSSValue>} */
this.selectors = [];
for (var i = 0; i < selectorList.selectors.length; ++i)
this.selectors.push(new WebInspector.CSSValue(selectorList.selectors[i]));
},
/**
* @param {string} newSelector
* @return {!Promise.<boolean>}
*/
setSelectorText: function(newSelector)
{
var styleSheetId = this.styleSheetId;
if (!styleSheetId)
throw "No rule stylesheet id";
var range = this.selectorRange();
if (!range)
throw "Rule selector is not editable";
return this._cssModel.setSelectorText(styleSheetId, range, newSelector);
},
/**
* @return {string}
*/
selectorText: function()
{
return this.selectors.select("text").join(", ");
},
/**
* @return {?WebInspector.TextRange}
*/
selectorRange: function()
{
var firstRange = this.selectors[0].range;
if (!firstRange)
return null;
var lastRange = this.selectors.peekLast().range;
return new WebInspector.TextRange(firstRange.startLine, firstRange.startColumn, lastRange.endLine, lastRange.endColumn);
},
/**
* @param {number} selectorIndex
* @return {number}
*/
lineNumberInSource: function(selectorIndex)
{
var selector = this.selectors[selectorIndex];
if (!selector || !selector.range || !this.styleSheetId)
return 0;
var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
return styleSheetHeader.lineNumberInSource(selector.range.startLine);
},
/**
* @param {number} selectorIndex
* @return {number|undefined}
*/
columnNumberInSource: function(selectorIndex)
{
var selector = this.selectors[selectorIndex];
if (!selector || !selector.range || !this.styleSheetId)
return undefined;
var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
console.assert(styleSheetHeader);
return styleSheetHeader.columnNumberInSource(selector.range.startLine, selector.range.startColumn);
},
/**
* @override
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.styleSheetId !== edit.styleSheetId)
return;
if (this.selectorRange().equal(edit.oldRange)) {
this._reinitializeSelectors(/** @type {!CSSAgent.SelectorList} */(edit.payload));
} else {
for (var i = 0; i < this.selectors.length; ++i)
this.selectors[i].rebase(edit);
}
for (var media of this.media)
media.rebase(edit);
WebInspector.CSSRule.prototype.rebase.call(this, edit);
},
__proto__: WebInspector.CSSRule.prototype
}
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSKeyframesRule} payload
*/
WebInspector.CSSKeyframesRule = function(cssModel, payload)
{
this._cssModel = cssModel;
this._animationName = new WebInspector.CSSValue(payload.animationName);
this._keyframes = payload.keyframes.map(keyframeRule => new WebInspector.CSSKeyframeRule(cssModel, keyframeRule));
}
WebInspector.CSSKeyframesRule.prototype = {
/**
* @return {!WebInspector.CSSValue}
*/
name: function()
{
return this._animationName;
},
/**
* @return {!Array.<!WebInspector.CSSKeyframeRule>}
*/
keyframes: function()
{
return this._keyframes;
}
}
/**
* @constructor
* @extends {WebInspector.CSSRule}
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSKeyframeRule} payload
*/
WebInspector.CSSKeyframeRule = function(cssModel, payload)
{
WebInspector.CSSRule.call(this, cssModel, payload);
this._reinitializeKey(payload.keyText);
}
WebInspector.CSSKeyframeRule.prototype = {
/**
* @return {!WebInspector.CSSValue}
*/
key: function()
{
return this._keyText;
},
/**
* @param {!CSSAgent.Value} payload
*/
_reinitializeKey: function(payload)
{
this._keyText = new WebInspector.CSSValue(payload);
},
/**
* @override
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.styleSheetId !== edit.styleSheetId || !this._keyText.range)
return;
if (edit.oldRange.equal(this._keyText.range))
this._reinitializeKey(/** @type {!CSSAgent.Value} */(edit.payload));
else
this._keyText.rebase(edit);
WebInspector.CSSRule.prototype.rebase.call(this, edit);
},
/**
* @param {string} newKeyText
* @return {!Promise.<boolean>}
*/
setKeyText: function(newKeyText)
{
var styleSheetId = this.styleSheetId;
if (!styleSheetId)
throw "No rule stylesheet id";
var range = this._keyText.range;
if (!range)
throw "Keyframe key is not editable";
return this._cssModel.setKeyframeKey(styleSheetId, range, newKeyText);
},
__proto__: WebInspector.CSSRule.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.CSSModel} cssModel
* @param {?WebInspector.CSSRule} parentRule
* @param {!CSSAgent.CSSStyle} payload
* @param {!WebInspector.CSSStyleDeclaration.Type} type
*/
WebInspector.CSSStyleDeclaration = function(cssModel, parentRule, payload, type)
{
this._cssModel = cssModel;
this.parentRule = parentRule;
this._reinitialize(payload);
this.type = type;
}
/** @enum {string} */
WebInspector.CSSStyleDeclaration.Type = {
Regular: "Regular",
Inline: "Inline",
Attributes: "Attributes"
}
WebInspector.CSSStyleDeclaration.prototype = {
/**
* @param {!WebInspector.CSSModel.Edit} edit
*/
rebase: function(edit)
{
if (this.styleSheetId !== edit.styleSheetId || !this.range)
return;
if (edit.oldRange.equal(this.range)) {
this._reinitialize(/** @type {!CSSAgent.CSSStyle} */(edit.payload));
} else {
this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
for (var i = 0; i < this._allProperties.length; ++i)
this._allProperties[i].rebase(edit);
}
},
/**
* @param {!CSSAgent.CSSStyle} payload
*/
_reinitialize: function(payload)
{
this.styleSheetId = payload.styleSheetId;
this.range = payload.range ? WebInspector.TextRange.fromObject(payload.range) : null;
var shorthandEntries = payload.shorthandEntries;
/** @type {!Map.<string, string>} */
this._shorthandValues = new Map();
/** @type {!Set.<string>} */
this._shorthandIsImportant = new Set();
for (var i = 0; i < shorthandEntries.length; ++i) {
this._shorthandValues.set(shorthandEntries[i].name, shorthandEntries[i].value);
if (shorthandEntries[i].important)
this._shorthandIsImportant.add(shorthandEntries[i].name);
}
this._allProperties = [];
for (var i = 0; i < payload.cssProperties.length; ++i) {
var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
this._allProperties.push(property);
}
this._generateSyntheticPropertiesIfNeeded();
this._computeInactiveProperties();
this._activePropertyMap = new Map();
for (var property of this._allProperties) {
if (!property.activeInStyle())
continue;
this._activePropertyMap.set(property.name, property);
}
this.cssText = payload.cssText;
this._leadingProperties = null;
},
_generateSyntheticPropertiesIfNeeded: function()
{
if (this.range)
return;
if (!this._shorthandValues.size)
return;
var propertiesSet = new Set();
for (var property of this._allProperties)
propertiesSet.add(property.name);
var generatedProperties = [];
// For style-based properties, generate shorthands with values when possible.
for (var property of this._allProperties) {
// For style-based properties, try generating shorthands.
var shorthands = WebInspector.CSSMetadata.cssPropertiesMetainfo.shorthands(property.name) || [];
for (var shorthand of shorthands) {
if (propertiesSet.has(shorthand))
continue; // There already is a shorthand this longhands falls under.
var shorthandValue = this._shorthandValues.get(shorthand);
if (!shorthandValue)
continue; // Never generate synthetic shorthands when no value is available.
// Generate synthetic shorthand we have a value for.
var shorthandImportance = !!this._shorthandIsImportant.has(shorthand);
var shorthandProperty = new WebInspector.CSSProperty(this, this.allProperties.length, shorthand, shorthandValue, shorthandImportance, false, true, false);
generatedProperties.push(shorthandProperty);
propertiesSet.add(shorthand);
}
}
this._allProperties = this._allProperties.concat(generatedProperties);
},
/**
* @return {!Array.<!WebInspector.CSSProperty>}
*/
_computeLeadingProperties: function()
{
/**
* @param {!WebInspector.CSSProperty} property
* @return {boolean}
*/
function propertyHasRange(property)
{
return !!property.range;
}
if (this.range)
return this._allProperties.filter(propertyHasRange);
var leadingProperties = [];
for (var property of this._allProperties) {
var shorthands = WebInspector.CSSMetadata.cssPropertiesMetainfo.shorthands(property.name) || [];
var belongToAnyShorthand = false;
for (var shorthand of shorthands) {
if (this._shorthandValues.get(shorthand)) {
belongToAnyShorthand = true;
break;
}
}
if (!belongToAnyShorthand)
leadingProperties.push(property);
}
return leadingProperties;
},
/**
* @return {!Array.<!WebInspector.CSSProperty>}
*/
leadingProperties: function()
{
if (!this._leadingProperties)
this._leadingProperties = this._computeLeadingProperties();
return this._leadingProperties;
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._cssModel.target();
},
/**
* @return {!WebInspector.CSSModel}
*/
cssModel: function()
{
return this._cssModel;
},
_computeInactiveProperties: function()
{
var activeProperties = {};
for (var i = 0; i < this._allProperties.length; ++i) {
var property = this._allProperties[i];
if (property.disabled || !property.parsedOk) {
property._setActive(false);
continue;
}
var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name);
var activeProperty = activeProperties[canonicalName];
if (!activeProperty) {
activeProperties[canonicalName] = property;
} else if (!activeProperty.important || property.important) {
activeProperty._setActive(false);
activeProperties[canonicalName] = property;
} else {
property._setActive(false);
}
}
},
get allProperties()
{
return this._allProperties;
},
/**
* @param {string} name
* @return {string}
*/
getPropertyValue: function(name)
{
var property = this._activePropertyMap.get(name);
return property ? property.value : "";
},
/**
* @param {string} name
* @return {boolean}
*/
isPropertyImplicit: function(name)
{
var property = this._activePropertyMap.get(name);
return property ? property.implicit : "";
},
/**
* @param {string} name
* @return {!Array.<!WebInspector.CSSProperty>}
*/
longhandProperties: function(name)
{
var longhands = WebInspector.CSSMetadata.cssPropertiesMetainfo.longhands(name);
var result = [];
for (var i = 0; longhands && i < longhands.length; ++i) {
var property = this._activePropertyMap.get(longhands[i]);
if (property)
result.push(property);
}
return result;
},
/**
* @param {number} index
* @return {?WebInspector.CSSProperty}
*/
propertyAt: function(index)
{
return (index < this.allProperties.length) ? this.allProperties[index] : null;
},
/**
* @return {number}
*/
pastLastSourcePropertyIndex: function()
{
for (var i = this.allProperties.length - 1; i >= 0; --i) {
if (this.allProperties[i].range)
return i + 1;
}
return 0;
},
/**
* @param {number} index
* @return {!WebInspector.TextRange}
*/
_insertionRange: function(index)
{
var property = this.propertyAt(index);
return property && property.range ? property.range.collapseToStart() : this.range.collapseToEnd();
},
/**
* @param {number=} index
* @return {!WebInspector.CSSProperty}
*/
newBlankProperty: function(index)
{
index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
var property = new WebInspector.CSSProperty(this, index, "", "", false, false, true, false, "", this._insertionRange(index));
return property;
},
/**
* @param {string} text
* @param {boolean} majorChange
* @return {!Promise.<boolean>}
*/
setText: function(text, majorChange)
{
return this._cssModel.setStyleText(this.styleSheetId, this.range, text, majorChange)
},
/**
* @param {number} index
* @param {string} name
* @param {string} value
* @param {function(boolean)=} userCallback
*/
insertPropertyAt: function(index, name, value, userCallback)
{
this.newBlankProperty(index).setText(name + ": " + value + ";", false, true)
.then(userCallback);
},
/**
* @param {string} name
* @param {string} value
* @param {function(boolean)=} userCallback
*/
appendProperty: function(name, value, userCallback)
{
this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 2 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.CSSModel} cssModel
* @param {!CSSAgent.CSSStyleSheetHeader} payload
*/
WebInspector.CSSStyleSheetHeader = function(cssModel, payload)
{
this._cssModel = cssModel;
this.id = payload.styleSheetId;
this.frameId = payload.frameId;
this.sourceURL = payload.sourceURL;
this.hasSourceURL = !!payload.hasSourceURL;
this.origin = payload.origin;
this.title = payload.title;
this.disabled = payload.disabled;
this.isInline = payload.isInline;
this.startLine = payload.startLine;
this.startColumn = payload.startColumn;
if (payload.ownerNode)
this.ownerNode = new WebInspector.DeferredDOMNode(cssModel.target(), payload.ownerNode);
this.setSourceMapURL(payload.sourceMapURL);
}
WebInspector.CSSStyleSheetHeader.prototype = {
/**
* @param {string=} sourceMapURL
*/
setSourceMapURL: function(sourceMapURL)
{
var completeSourceMapURL = this.sourceURL && sourceMapURL ? WebInspector.ParsedURL.completeURL(this.sourceURL, sourceMapURL) : null;
this.sourceMapURL = completeSourceMapURL;
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._cssModel.target();
},
/**
* @return {!WebInspector.CSSModel}
*/
cssModel: function()
{
return this._cssModel;
},
/**
* @return {string}
*/
resourceURL: function()
{
return this.isViaInspector() ? this._viaInspectorResourceURL() : this.sourceURL;
},
/**
* @return {string}
*/
_viaInspectorResourceURL: function()
{
var frame = this._cssModel.target().resourceTreeModel.frameForId(this.frameId);
console.assert(frame);
var parsedURL = new WebInspector.ParsedURL(frame.url);
var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
if (!fakeURL.endsWith("/"))
fakeURL += "/";
fakeURL += "inspector-stylesheet";
return fakeURL;
},
/**
* @param {number} lineNumberInStyleSheet
* @return {number}
*/
lineNumberInSource: function(lineNumberInStyleSheet)
{
return this.startLine + lineNumberInStyleSheet;
},
/**
* @param {number} lineNumberInStyleSheet
* @param {number} columnNumberInStyleSheet
* @return {number|undefined}
*/
columnNumberInSource: function(lineNumberInStyleSheet, columnNumberInStyleSheet)
{
return (lineNumberInStyleSheet ? 0 : this.startColumn) + columnNumberInStyleSheet;
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this.resourceURL();
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return WebInspector.resourceTypes.Stylesheet;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
return /** @type {!Promise<?string>} */(this._cssModel.getStyleSheetText(this.id));
},
/**
* @override
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
function performSearch(content)
{
callback(WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
}
// searchInContent should call back later.
this.requestContent().then(performSearch);
},
/**
* @return {boolean}
*/
isViaInspector: function()
{
return this.origin === "inspector";
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | 2 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.ConsoleModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.ConsoleModel, target);
/** @type {!Array.<!WebInspector.ConsoleMessage>} */
this._messages = [];
/** @type {!Map<number, !WebInspector.ConsoleMessage>} */
this._messageById = new Map();
this._warnings = 0;
this._errors = 0;
this._revokedErrors = 0;
this._consoleAgent = target.consoleAgent();
target.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
this._enableAgent();
}
WebInspector.ConsoleModel.Events = {
ConsoleCleared: "ConsoleCleared",
MessageAdded: "MessageAdded",
MessageUpdated: "MessageUpdated",
CommandEvaluated: "CommandEvaluated",
}
WebInspector.ConsoleModel.prototype = {
_enableAgent: function()
{
this._enablingConsole = true;
/**
* @this {WebInspector.ConsoleModel}
*/
function callback()
{
delete this._enablingConsole;
}
this._consoleAgent.enable(callback.bind(this));
},
/**
* @param {!WebInspector.ConsoleMessage} msg
*/
addMessage: function(msg)
{
if (this._isBlacklisted(msg))
return;
if (msg.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError && msg._relatedMessageId) {
var relatedMessage = this._messageById.get(msg._relatedMessageId);
if (!relatedMessage)
return;
this._errors--;
this._revokedErrors++;
relatedMessage.level = WebInspector.ConsoleMessage.MessageLevel.RevokedError;
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated, relatedMessage);
return;
}
this._messages.push(msg);
if (msg._messageId)
this._messageById.set(msg._messageId, msg);
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
},
/**
* @param {!WebInspector.ConsoleMessage} msg
*/
_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
this._warnings++;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
this._errors++;
break;
case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
this._revokedErrors++;
break;
}
},
/**
* @param {!WebInspector.ConsoleMessage} msg
* @return {boolean}
*/
_isBlacklisted: function(msg)
{
if (msg.source != WebInspector.ConsoleMessage.MessageSource.Network || msg.level != WebInspector.ConsoleMessage.MessageLevel.Error || !msg.url || !msg.url.startsWith("chrome-extension"))
return false;
// ignore Chromecast's cast_sender spam
if (msg.url.includes("://boadgeojelhgndaghljhdicfkmllpafd") || msg.url.includes("://dliochdbjfkdbacpmhlcpmleaejidimm") || msg.url.includes("://pkedcjkdefgpdelpbcmbmeomcjbeemfm") || msg.url.includes("://fjhoaacokmgbjemoflkofnenfaiekifl") || msg.url.includes("://ekpaaapppgpmolpcldedioblbkmijaca"))
return true;
return false;
},
/**
* @return {!Array.<!WebInspector.ConsoleMessage>}
*/
messages: function()
{
return this._messages;
},
requestClearMessages: function()
{
this._consoleAgent.clearMessages();
this._messagesCleared();
},
_messagesCleared: function()
{
this._messages = [];
this._messageById.clear();
this._errors = 0;
this._revokedErrors = 0;
this._warnings = 0;
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
},
/**
* @return {number}
*/
errors: function()
{
return this._errors;
},
/**
* @return {number}
*/
revokedErrors: function()
{
return this._revokedErrors;
},
/**
* @return {number}
*/
warnings: function()
{
return this._warnings;
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @param {!WebInspector.ExecutionContext} executionContext
* @param {string} text
* @param {boolean=} useCommandLineAPI
*/
WebInspector.ConsoleModel.evaluateCommandInConsole = function(executionContext, text, useCommandLineAPI)
{
var target = executionContext.target();
var commandMessage = new WebInspector.ConsoleMessage(target, WebInspector.ConsoleMessage.MessageSource.JS, null, text, WebInspector.ConsoleMessage.MessageType.Command);
commandMessage.setExecutionContextId(executionContext.id);
target.consoleModel.addMessage(commandMessage);
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean} wasThrown
* @param {?RuntimeAgent.RemoteObject=} valueResult
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
function printResult(result, wasThrown, valueResult, exceptionDetails)
{
if (!result)
return;
WebInspector.console.showPromise().then(reportUponEvaluation);
function reportUponEvaluation()
{
target.consoleModel.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, wasThrown: wasThrown, text: text, commandMessage: commandMessage, exceptionDetails: exceptionDetails});
}
}
if (/^\s*\{/.test(text) && /\}\s*$/.test(text))
text = '(' + text + ')';
executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, true, printResult);
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ConsoleEvaluated);
}
WebInspector.ConsoleModel.clearConsole = function()
{
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i)
targets[i].consoleModel.requestClearMessages();
}
/**
* @constructor
* @param {?WebInspector.Target} target
* @param {string} source
* @param {?string} level
* @param {string} messageText
* @param {string=} type
* @param {?string=} url
* @param {number=} line
* @param {number=} column
* @param {!NetworkAgent.RequestId=} requestId
* @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
* @param {!RuntimeAgent.StackTrace=} stackTrace
* @param {number=} timestamp
* @param {!RuntimeAgent.ExecutionContextId=} executionContextId
* @param {?string=} scriptId
* @param {number=} messageId
* @param {number=} relatedMessageId
*/
WebInspector.ConsoleMessage = function(target, source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, executionContextId, scriptId, messageId, relatedMessageId)
{
this._target = target;
this.source = source;
this.level = level;
this.messageText = messageText;
this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
/** @type {string|undefined} */
this.url = url || undefined;
/** @type {number} */
this.line = line || 0;
/** @type {number} */
this.column = column || 0;
this.parameters = parameters;
/** @type {!RuntimeAgent.StackTrace|undefined} */
this.stackTrace = stackTrace;
this.timestamp = timestamp || Date.now();
this.executionContextId = executionContextId || 0;
this.scriptId = scriptId || null;
this._messageId = messageId || 0;
this._relatedMessageId = relatedMessageId || 0;
this.request = requestId ? target.networkLog.requestForId(requestId) : null;
if (this.request) {
var initiator = this.request.initiator();
if (initiator) {
this.stackTrace = initiator.stack || undefined;
if (initiator.url) {
this.url = initiator.url;
this.line = initiator.lineNumber || 0;
}
}
}
}
WebInspector.ConsoleMessage.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @param {!WebInspector.ConsoleMessage} originatingMessage
*/
setOriginatingMessage: function(originatingMessage)
{
this._originatingConsoleMessage = originatingMessage;
this.executionContextId = originatingMessage.executionContextId;
},
/**
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
*/
setExecutionContextId: function(executionContextId)
{
this.executionContextId = executionContextId;
},
/**
* @return {?WebInspector.ConsoleMessage}
*/
originatingMessage: function()
{
return this._originatingConsoleMessage;
},
/**
* @return {boolean}
*/
isGroupMessage: function()
{
return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed ||
this.type === WebInspector.ConsoleMessage.MessageType.EndGroup;
},
/**
* @return {boolean}
*/
isGroupStartMessage: function()
{
return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed;
},
/**
* @return {boolean}
*/
isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},
/**
* @param {?WebInspector.ConsoleMessage} msg
* @return {boolean}
*/
isEqual: function(msg)
{
if (!msg)
return false;
if (this._messageId || msg._messageId)
return false;
if (this._relatedMessageId || msg._relatedMessageId)
return false;
if (!this._isEqualStackTraces(this.stackTrace, msg.stackTrace))
return false;
if (this.parameters) {
if (!msg.parameters || this.parameters.length !== msg.parameters.length)
return false;
for (var i = 0; i < msg.parameters.length; ++i) {
// Never treat objects as equal - their properties might change over time.
if (this.parameters[i].type !== msg.parameters[i].type || msg.parameters[i].type === "object" || this.parameters[i].value !== msg.parameters[i].value)
return false;
}
}
return (this.target() === msg.target())
&& (this.source === msg.source)
&& (this.type === msg.type)
&& (this.level === msg.level)
&& (this.line === msg.line)
&& (this.url === msg.url)
&& (this.messageText === msg.messageText)
&& (this.request === msg.request)
&& (this.executionContextId === msg.executionContextId)
&& (this.scriptId === msg.scriptId);
},
/**
* @param {!RuntimeAgent.StackTrace|undefined} stackTrace1
* @param {!RuntimeAgent.StackTrace|undefined} stackTrace2
* @return {boolean}
*/
_isEqualStackTraces: function(stackTrace1, stackTrace2)
{
if (!stackTrace1 !== !stackTrace2)
return false;
if (!stackTrace1)
return true;
var callFrames1 = stackTrace1.callFrames;
var callFrames2 = stackTrace2.callFrames;
if (callFrames1.length !== callFrames2.length)
return false;
for (var i = 0, n = callFrames1.length; i < n; ++i) {
if (callFrames1[i].url !== callFrames2[i].url ||
callFrames1[i].functionName !== callFrames2[i].functionName ||
callFrames1[i].lineNumber !== callFrames2[i].lineNumber ||
callFrames1[i].columnNumber !== callFrames2[i].columnNumber)
return false;
}
return this._isEqualStackTraces(stackTrace1.parent, stackTrace2.parent);
}
}
// Note: Keep these constants in sync with the ones in Console.h
/**
* @enum {string}
*/
WebInspector.ConsoleMessage.MessageSource = {
XML: "xml",
JS: "javascript",
Network: "network",
ConsoleAPI: "console-api",
Storage: "storage",
AppCache: "appcache",
Rendering: "rendering",
CSS: "css",
Security: "security",
Other: "other",
Deprecation: "deprecation"
}
/**
* @enum {string}
*/
WebInspector.ConsoleMessage.MessageType = {
Log: "log",
Dir: "dir",
DirXML: "dirxml",
Table: "table",
Trace: "trace",
Clear: "clear",
StartGroup: "startGroup",
StartGroupCollapsed: "startGroupCollapsed",
EndGroup: "endGroup",
Assert: "assert",
Result: "result",
Profile: "profile",
ProfileEnd: "profileEnd",
Command: "command"
}
/**
* @enum {string}
*/
WebInspector.ConsoleMessage.MessageLevel = {
Log: "log",
Info: "info",
Warning: "warning",
Error: "error",
Debug: "debug",
RevokedError: "revokedError"
};
/**
* @param {!WebInspector.ConsoleMessage} a
* @param {!WebInspector.ConsoleMessage} b
* @return {number}
*/
WebInspector.ConsoleMessage.timestampComparator = function (a, b)
{
return a.timestamp - b.timestamp;
}
/**
* @constructor
* @implements {ConsoleAgent.Dispatcher}
* @param {!WebInspector.ConsoleModel} console
*/
WebInspector.ConsoleDispatcher = function(console)
{
this._console = console;
}
WebInspector.ConsoleDispatcher.prototype = {
/**
* @override
* @param {!ConsoleAgent.ConsoleMessage} payload
*/
messageAdded: function(payload)
{
var consoleMessage = new WebInspector.ConsoleMessage(
this._console.target(),
payload.source,
payload.level,
payload.text,
payload.type,
payload.url,
payload.line,
payload.column,
payload.networkRequestId,
payload.parameters,
payload.stack,
payload.timestamp * 1000, // Convert to ms.
payload.executionContextId,
payload.scriptId,
payload.messageId,
payload.relatedMessageId);
this._console.addMessage(consoleMessage);
},
/**
* @override
* @param {number} count
*/
messageRepeatCountUpdated: function(count)
{
},
/**
* @override
*/
messagesCleared: function()
{
if (!WebInspector.moduleSetting("preserveConsoleLog").get())
this._console._messagesCleared();
}
}
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.MultitargetConsoleModel = function()
{
WebInspector.targetManager.observeTargets(this);
WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.MessageUpdated, this._consoleMessageUpdated, this);
WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
}
WebInspector.MultitargetConsoleModel.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
if (!this._mainTarget) {
this._mainTarget = target;
target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
}
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (this._mainTarget === target) {
delete this._mainTarget;
target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
}
},
/**
* @return {!Array.<!WebInspector.ConsoleMessage>}
*/
messages: function()
{
var targets = WebInspector.targetManager.targets();
var result = [];
for (var i = 0; i < targets.length; ++i)
result = result.concat(targets[i].consoleModel.messages());
return result;
},
_consoleCleared: function()
{
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
},
/**
* @param {!WebInspector.Event} event
*/
_consoleMessageAdded: function(event)
{
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, event.data);
},
/**
* @param {!WebInspector.Event} event
*/
_consoleMessageUpdated: function(event)
{
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated, event.data);
},
/**
* @param {!WebInspector.Event} event
*/
_commandEvaluated: function(event)
{
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, event.data);
},
__proto__: WebInspector.Object.prototype
}
/**
* @type {!WebInspector.MultitargetConsoleModel}
*/
WebInspector.multitargetConsoleModel;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 2 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {string} sourceURL
* @param {!WebInspector.ResourceType} contentType
*/
WebInspector.CompilerSourceMappingContentProvider = function(sourceURL, contentType)
{
this._sourceURL = sourceURL;
this._contentType = contentType;
}
WebInspector.CompilerSourceMappingContentProvider.prototype = {
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._sourceURL;
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._contentType;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
var callback;
var promise = new Promise(fulfill => callback = fulfill);
WebInspector.multitargetNetworkManager.loadResource(this._sourceURL, contentLoaded.bind(this));
return promise;
/**
* @param {number} statusCode
* @param {!Object.<string, string>} headers
* @param {string} content
* @this {WebInspector.CompilerSourceMappingContentProvider}
*/
function contentLoaded(statusCode, headers, content)
{
if (statusCode >= 400) {
console.error("Could not load content for " + this._sourceURL + " : " + "HTTP status code: " + statusCode);
callback(null);
return;
}
callback(content);
}
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
this.requestContent().then(contentLoaded);
/**
* @param {?string} content
*/
function contentLoaded(content)
{
if (typeof content !== "string") {
callback([]);
return;
}
callback(WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | 2 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Ideally, we would rely on platform support for parsing a cookie, since
// this would save us from any potential inconsistency. However, exposing
// platform cookie parsing logic would require quite a bit of additional
// plumbing, and at least some platforms lack support for parsing Cookie,
// which is in a format slightly different from Set-Cookie and is normally
// only required on the server side.
/**
* @constructor
* @param {!WebInspector.Target} target
*/
WebInspector.CookieParser = function(target)
{
this._target = target;
}
/**
* @constructor
* @param {string} key
* @param {string|undefined} value
* @param {number} position
*/
WebInspector.CookieParser.KeyValue = function(key, value, position)
{
this.key = key;
this.value = value;
this.position = position;
}
WebInspector.CookieParser.prototype = {
/**
* @return {!Array.<!WebInspector.Cookie>}
*/
cookies: function()
{
return this._cookies;
},
/**
* @param {string|undefined} cookieHeader
* @return {?Array.<!WebInspector.Cookie>}
*/
parseCookie: function(cookieHeader)
{
if (!this._initialize(cookieHeader))
return null;
for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (kv.key.charAt(0) === "$" && this._lastCookie)
this._lastCookie.addAttribute(kv.key.slice(1), kv.value);
else if (kv.key.toLowerCase() !== "$version" && typeof kv.value === "string")
this._addCookie(kv, WebInspector.Cookie.Type.Request);
this._advanceAndCheckCookieDelimiter();
}
this._flushCookie();
return this._cookies;
},
/**
* @param {string|undefined} setCookieHeader
* @return {?Array.<!WebInspector.Cookie>}
*/
parseSetCookie: function(setCookieHeader)
{
if (!this._initialize(setCookieHeader))
return null;
for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (this._lastCookie)
this._lastCookie.addAttribute(kv.key, kv.value);
else
this._addCookie(kv, WebInspector.Cookie.Type.Response);
if (this._advanceAndCheckCookieDelimiter())
this._flushCookie();
}
this._flushCookie();
return this._cookies;
},
/**
* @param {string|undefined} headerValue
* @return {boolean}
*/
_initialize: function(headerValue)
{
this._input = headerValue;
if (typeof headerValue !== "string")
return false;
this._cookies = [];
this._lastCookie = null;
this._originalInputLength = this._input.length;
return true;
},
_flushCookie: function()
{
if (this._lastCookie)
this._lastCookie.setSize(this._originalInputLength - this._input.length - this._lastCookiePosition);
this._lastCookie = null;
},
/**
* @return {?WebInspector.CookieParser.KeyValue}
*/
_extractKeyValue: function()
{
if (!this._input || !this._input.length)
return null;
// Note: RFCs offer an option for quoted values that may contain commas and semicolons.
// Many browsers/platforms do not support this, however (see http://webkit.org/b/16699
// and http://crbug.com/12361). The logic below matches latest versions of IE, Firefox,
// Chrome and Safari on some old platforms. The latest version of Safari supports quoted
// cookie values, though.
var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);
if (!keyValueMatch) {
console.log("Failed parsing cookie header before: " + this._input);
return null;
}
var result = new WebInspector.CookieParser.KeyValue(keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._originalInputLength - this._input.length);
this._input = this._input.slice(keyValueMatch[0].length);
return result;
},
/**
* @return {boolean}
*/
_advanceAndCheckCookieDelimiter: function()
{
var match = /^\s*[\n;]\s*/.exec(this._input);
if (!match)
return false;
this._input = this._input.slice(match[0].length);
return match[0].match("\n") !== null;
},
/**
* @param {!WebInspector.CookieParser.KeyValue} keyValue
* @param {!WebInspector.Cookie.Type} type
*/
_addCookie: function(keyValue, type)
{
if (this._lastCookie)
this._lastCookie.setSize(keyValue.position - this._lastCookiePosition);
// Mozilla bug 169091: Mozilla, IE and Chrome treat single token (w/o "=") as
// specifying a value for a cookie with empty name.
this._lastCookie = typeof keyValue.value === "string" ? new WebInspector.Cookie(this._target, keyValue.key, keyValue.value, type) :
new WebInspector.Cookie(this._target, "", keyValue.key, type);
this._lastCookiePosition = keyValue.position;
this._cookies.push(this._lastCookie);
}
};
/**
* @param {!WebInspector.Target} target
* @param {string|undefined} header
* @return {?Array.<!WebInspector.Cookie>}
*/
WebInspector.CookieParser.parseCookie = function(target, header)
{
return (new WebInspector.CookieParser(target)).parseCookie(header);
}
/**
* @param {!WebInspector.Target} target
* @param {string|undefined} header
* @return {?Array.<!WebInspector.Cookie>}
*/
WebInspector.CookieParser.parseSetCookie = function(target, header)
{
return (new WebInspector.CookieParser(target)).parseSetCookie(header);
}
/**
* @constructor
* @param {!WebInspector.Target} target
* @param {string} name
* @param {string} value
* @param {?WebInspector.Cookie.Type} type
*/
WebInspector.Cookie = function(target, name, value, type)
{
this._target = target;
this._name = name;
this._value = value;
this._type = type;
this._attributes = {};
}
WebInspector.Cookie.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {string}
*/
value: function()
{
return this._value;
},
/**
* @return {?WebInspector.Cookie.Type}
*/
type: function()
{
return this._type;
},
/**
* @return {boolean}
*/
httpOnly: function()
{
return "httponly" in this._attributes;
},
/**
* @return {boolean}
*/
secure: function()
{
return "secure" in this._attributes;
},
/**
* @return {string}
*/
sameSite: function ()
{
return this._attributes["samesite"];
},
/**
* @return {boolean}
*/
session: function()
{
// RFC 2965 suggests using Discard attribute to mark session cookies, but this does not seem to be widely used.
// Check for absence of explicitly max-age or expiry date instead.
return !("expires" in this._attributes || "max-age" in this._attributes);
},
/**
* @return {string}
*/
path: function()
{
return this._attributes["path"];
},
/**
* @return {string}
*/
port: function()
{
return this._attributes["port"];
},
/**
* @return {string}
*/
domain: function()
{
return this._attributes["domain"];
},
/**
* @return {string}
*/
expires: function()
{
return this._attributes["expires"];
},
/**
* @return {string}
*/
maxAge: function()
{
return this._attributes["max-age"];
},
/**
* @return {number}
*/
size: function()
{
return this._size;
},
/**
* @param {number} size
*/
setSize: function(size)
{
this._size = size;
},
/**
* @return {?Date}
*/
expiresDate: function(requestDate)
{
// RFC 6265 indicates that the max-age attribute takes precedence over the expires attribute
if (this.maxAge()) {
var targetDate = requestDate === null ? new Date() : requestDate;
return new Date(targetDate.getTime() + 1000 * this.maxAge());
}
if (this.expires())
return new Date(this.expires());
return null;
},
/**
* @return {!Object}
*/
attributes: function()
{
return this._attributes;
},
/**
* @param {string} key
* @param {string=} value
*/
addAttribute: function(key, value)
{
this._attributes[key.toLowerCase()] = value;
},
/**
* @param {function(?Protocol.Error)=} callback
*/
remove: function(callback)
{
this._target.networkAgent().deleteCookie(this.name(), (this.secure() ? "https://" : "http://") + this.domain() + this.path(), callback);
}
}
/**
* @enum {number}
*/
WebInspector.Cookie.Type = {
Request: 0,
Response: 1
};
WebInspector.Cookies = {}
/**
* @param {function(!Array.<!WebInspector.Cookie>)} callback
*/
WebInspector.Cookies.getCookiesAsync = function(callback)
{
var allCookies = [];
/**
* @param {!WebInspector.Target} target
* @param {?Protocol.Error} error
* @param {!Array.<!NetworkAgent.Cookie>} cookies
*/
function mycallback(target, error, cookies)
{
if (error) {
console.error(error);
return;
}
for (var i = 0; i < cookies.length; ++i)
allCookies.push(WebInspector.Cookies._parseProtocolCookie(target, cookies[i]));
}
var barrier = new CallbackBarrier();
for (var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.networkAgent().getCookies(barrier.createCallback(mycallback.bind(null, target)));
barrier.callWhenDone(callback.bind(null, allCookies));
}
/**
* @param {!WebInspector.Target} target
* @param {!NetworkAgent.Cookie} protocolCookie
* @return {!WebInspector.Cookie}
*/
WebInspector.Cookies._parseProtocolCookie = function(target, protocolCookie)
{
var cookie = new WebInspector.Cookie(target, protocolCookie.name, protocolCookie.value, null);
cookie.addAttribute("domain", protocolCookie["domain"]);
cookie.addAttribute("path", protocolCookie["path"]);
cookie.addAttribute("port", protocolCookie["port"]);
if (protocolCookie["expires"])
cookie.addAttribute("expires", protocolCookie["expires"]);
if (protocolCookie["httpOnly"])
cookie.addAttribute("httpOnly");
if (protocolCookie["secure"])
cookie.addAttribute("secure");
if (protocolCookie["sameSite"])
cookie.addAttribute("sameSite", protocolCookie["sameSite"]);
cookie.setSize(protocolCookie["size"]);
return cookie;
}
/**
* @param {!WebInspector.Cookie} cookie
* @param {string} resourceURL
* @return {boolean}
*/
WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
var url = resourceURL.asParsedURL();
if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain(), url.host))
return false;
return (url.path.startsWith(cookie.path())
&& (!cookie.port() || url.port == cookie.port())
&& (!cookie.secure() || url.scheme === "https"));
}
/**
* @param {string} cookieDomain
* @param {string} resourceDomain
* @return {boolean}
*/
WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
{
if (cookieDomain.charAt(0) !== '.')
return resourceDomain === cookieDomain;
return !!resourceDomain.match(new RegExp("^([^\\.]+\\.)*" + cookieDomain.substring(1).escapeForRegExp() + "$", "i"));
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2009, 2010 Google Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.DOMModel} domModel
* @param {?WebInspector.DOMDocument} doc
* @param {boolean} isInShadowTree
* @param {!DOMAgent.Node} payload
*/
WebInspector.DOMNode = function(domModel, doc, isInShadowTree, payload)
{
WebInspector.SDKObject.call(this, domModel.target());
this._domModel = domModel;
this._agent = domModel._agent;
this.ownerDocument = doc;
this._isInShadowTree = isInShadowTree;
this.id = payload.nodeId;
domModel._idToDOMNode[this.id] = this;
this._nodeType = payload.nodeType;
this._nodeName = payload.nodeName;
this._localName = payload.localName;
this._nodeValue = payload.nodeValue;
this._pseudoType = payload.pseudoType;
this._shadowRootType = payload.shadowRootType;
this._frameId = payload.frameId || null;
this._xmlVersion = payload.xmlVersion;
this._shadowRoots = [];
this._attributes = [];
this._attributesMap = {};
if (payload.attributes)
this._setAttributesPayload(payload.attributes);
/** @type {!Map<string, ?>} */
this._markers = new Map();
this._subtreeMarkerCount = 0;
this._childNodeCount = payload.childNodeCount || 0;
this._children = null;
this.nextSibling = null;
this.previousSibling = null;
this.firstChild = null;
this.lastChild = null;
this.parentNode = null;
if (payload.shadowRoots) {
for (var i = 0; i < payload.shadowRoots.length; ++i) {
var root = payload.shadowRoots[i];
var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, root);
this._shadowRoots.push(node);
node.parentNode = this;
}
}
if (payload.templateContent) {
this._templateContent = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, payload.templateContent);
this._templateContent.parentNode = this;
}
if (payload.importedDocument) {
this._importedDocument = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, payload.importedDocument);
this._importedDocument.parentNode = this;
}
if (payload.distributedNodes)
this._setDistributedNodePayloads(payload.distributedNodes);
if (payload.children)
this._setChildrenPayload(payload.children);
this._setPseudoElements(payload.pseudoElements);
if (payload.contentDocument) {
this._contentDocument = new WebInspector.DOMDocument(domModel, payload.contentDocument);
this._children = [this._contentDocument];
this._renumber();
}
if (this._nodeType === Node.ELEMENT_NODE) {
// HTML and BODY from internal iframes should not overwrite top-level ones.
if (this.ownerDocument && !this.ownerDocument.documentElement && this._nodeName === "HTML")
this.ownerDocument.documentElement = this;
if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === "BODY")
this.ownerDocument.body = this;
} else if (this._nodeType === Node.DOCUMENT_TYPE_NODE) {
this.publicId = payload.publicId;
this.systemId = payload.systemId;
this.internalSubset = payload.internalSubset;
} else if (this._nodeType === Node.ATTRIBUTE_NODE) {
this.name = payload.name;
this.value = payload.value;
}
}
/**
* @enum {string}
*/
WebInspector.DOMNode.PseudoElementNames = {
Before: "before",
After: "after"
}
/**
* @enum {string}
*/
WebInspector.DOMNode.ShadowRootTypes = {
UserAgent: "user-agent",
Open: "open",
Closed: "closed"
}
WebInspector.DOMNode.prototype = {
/**
* @return {!WebInspector.DOMModel}
*/
domModel: function()
{
return this._domModel;
},
/**
* @return {?Array.<!WebInspector.DOMNode>}
*/
children: function()
{
return this._children ? this._children.slice() : null;
},
/**
* @return {boolean}
*/
hasAttributes: function()
{
return this._attributes.length > 0;
},
/**
* @return {number}
*/
childNodeCount: function()
{
return this._childNodeCount;
},
/**
* @return {boolean}
*/
hasShadowRoots: function()
{
return !!this._shadowRoots.length;
},
/**
* @return {!Array.<!WebInspector.DOMNode>}
*/
shadowRoots: function()
{
return this._shadowRoots.slice();
},
/**
* @return {?WebInspector.DOMNode}
*/
templateContent: function()
{
return this._templateContent || null;
},
/**
* @return {?WebInspector.DOMNode}
*/
importedDocument: function()
{
return this._importedDocument || null;
},
/**
* @return {number}
*/
nodeType: function()
{
return this._nodeType;
},
/**
* @return {string}
*/
nodeName: function()
{
return this._nodeName;
},
/**
* @return {string|undefined}
*/
pseudoType: function()
{
return this._pseudoType;
},
/**
* @return {boolean}
*/
hasPseudoElements: function()
{
return this._pseudoElements.size > 0;
},
/**
* @return {!Map<string, !WebInspector.DOMNode>}
*/
pseudoElements: function()
{
return this._pseudoElements;
},
/**
* @return {?WebInspector.DOMNode}
*/
beforePseudoElement: function()
{
if (!this._pseudoElements)
return null;
return this._pseudoElements.get(WebInspector.DOMNode.PseudoElementNames.Before);
},
/**
* @return {?WebInspector.DOMNode}
*/
afterPseudoElement: function()
{
if (!this._pseudoElements)
return null;
return this._pseudoElements.get(WebInspector.DOMNode.PseudoElementNames.After);
},
/**
* @return {boolean}
*/
isInsertionPoint: function()
{
return !this.isXMLNode() && (this._nodeName === "SHADOW" || this._nodeName === "CONTENT");
},
/**
* @return {!Array.<!WebInspector.DOMNodeShortcut>}
*/
distributedNodes: function()
{
return this._distributedNodes || [];
},
/**
* @return {boolean}
*/
isInShadowTree: function()
{
return this._isInShadowTree;
},
/**
* @return {?WebInspector.DOMNode}
*/
ancestorShadowHost: function()
{
var ancestorShadowRoot = this.ancestorShadowRoot();
return ancestorShadowRoot ? ancestorShadowRoot.parentNode : null;
},
/**
* @return {?WebInspector.DOMNode}
*/
ancestorShadowRoot: function()
{
if (!this._isInShadowTree)
return null;
var current = this;
while (current && !current.isShadowRoot())
current = current.parentNode;
return current;
},
/**
* @return {?WebInspector.DOMNode}
*/
ancestorUserAgentShadowRoot: function()
{
var ancestorShadowRoot = this.ancestorShadowRoot();
if (!ancestorShadowRoot)
return null;
return ancestorShadowRoot.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? ancestorShadowRoot : null;
},
/**
* @return {boolean}
*/
isShadowRoot: function()
{
return !!this._shadowRootType;
},
/**
* @return {?string}
*/
shadowRootType: function()
{
return this._shadowRootType || null;
},
/**
* @return {string}
*/
nodeNameInCorrectCase: function()
{
var shadowRootType = this.shadowRootType();
if (shadowRootType)
return "#shadow-root (" + shadowRootType + ")";
return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase();
},
/**
* @param {string} name
* @param {function(?Protocol.Error, number)=} callback
*/
setNodeName: function(name, callback)
{
this._agent.setNodeName(this.id, name, this._domModel._markRevision(this, callback));
},
/**
* @return {string}
*/
localName: function()
{
return this._localName;
},
/**
* @return {string}
*/
nodeValue: function()
{
return this._nodeValue;
},
/**
* @param {string} value
* @param {function(?Protocol.Error)=} callback
*/
setNodeValue: function(value, callback)
{
this._agent.setNodeValue(this.id, value, this._domModel._markRevision(this, callback));
},
/**
* @param {string} name
* @return {string}
*/
getAttribute: function(name)
{
var attr = this._attributesMap[name];
return attr ? attr.value : undefined;
},
/**
* @param {string} name
* @param {string} text
* @param {function(?Protocol.Error)=} callback
*/
setAttribute: function(name, text, callback)
{
this._agent.setAttributesAsText(this.id, text, name, this._domModel._markRevision(this, callback));
},
/**
* @param {string} name
* @param {string} value
* @param {function(?Protocol.Error)=} callback
*/
setAttributeValue: function(name, value, callback)
{
this._agent.setAttributeValue(this.id, name, value, this._domModel._markRevision(this, callback));
},
/**
* @return {!Object}
*/
attributes: function()
{
return this._attributes;
},
/**
* @param {string} name
* @param {function(?Protocol.Error)=} callback
*/
removeAttribute: function(name, callback)
{
/**
* @param {?Protocol.Error} error
* @this {WebInspector.DOMNode}
*/
function mycallback(error)
{
if (!error) {
delete this._attributesMap[name];
for (var i = 0; i < this._attributes.length; ++i) {
if (this._attributes[i].name === name) {
this._attributes.splice(i, 1);
break;
}
}
}
this._domModel._markRevision(this, callback)(error);
}
this._agent.removeAttribute(this.id, name, mycallback.bind(this));
},
/**
* @param {function(?Array.<!WebInspector.DOMNode>)=} callback
*/
getChildNodes: function(callback)
{
if (this._children) {
if (callback)
callback(this.children());
return;
}
/**
* @this {WebInspector.DOMNode}
* @param {?Protocol.Error} error
*/
function mycallback(error)
{
if (callback)
callback(error ? null : this.children());
}
this._agent.requestChildNodes(this.id, undefined, mycallback.bind(this));
},
/**
* @param {number} depth
* @param {function(?Array.<!WebInspector.DOMNode>)=} callback
*/
getSubtree: function(depth, callback)
{
/**
* @this {WebInspector.DOMNode}
* @param {?Protocol.Error} error
*/
function mycallback(error)
{
if (callback)
callback(error ? null : this._children);
}
this._agent.requestChildNodes(this.id, depth, mycallback.bind(this));
},
/**
* @param {function(?Protocol.Error, string)=} callback
*/
getOuterHTML: function(callback)
{
this._agent.getOuterHTML(this.id, callback);
},
/**
* @param {string} html
* @param {function(?Protocol.Error)=} callback
*/
setOuterHTML: function(html, callback)
{
this._agent.setOuterHTML(this.id, html, this._domModel._markRevision(this, callback));
},
/**
* @param {function(?Protocol.Error, !DOMAgent.NodeId=)=} callback
*/
removeNode: function(callback)
{
this._agent.removeNode(this.id, this._domModel._markRevision(this, callback));
},
/**
* @param {function(?string)=} callback
*/
copyNode: function(callback)
{
function copy(error, text)
{
if (!error)
InspectorFrontendHost.copyText(text);
if (callback)
callback(error ? null : text);
}
this._agent.getOuterHTML(this.id, copy);
},
/**
* @return {string}
*/
path: function()
{
/**
* @param {?WebInspector.DOMNode} node
*/
function canPush(node)
{
return node && ("index" in node || (node.isShadowRoot() && node.parentNode)) && node._nodeName.length;
}
var path = [];
var node = this;
while (canPush(node)) {
var index = typeof node.index === "number" ? node.index : (node.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? "u" : "a");
path.push([index, node._nodeName]);
node = node.parentNode;
}
path.reverse();
return path.join(",");
},
/**
* @param {!WebInspector.DOMNode} node
* @return {boolean}
*/
isAncestor: function(node)
{
if (!node)
return false;
var currentNode = node.parentNode;
while (currentNode) {
if (this === currentNode)
return true;
currentNode = currentNode.parentNode;
}
return false;
},
/**
* @param {!WebInspector.DOMNode} descendant
* @return {boolean}
*/
isDescendant: function(descendant)
{
return descendant !== null && descendant.isAncestor(this);
},
/**
* @return {?PageAgent.FrameId}
*/
frameId: function()
{
var node = this;
while (!node._frameId && node.parentNode)
node = node.parentNode;
return node._frameId;
},
/**
* @param {!Array.<string>} attrs
* @return {boolean}
*/
_setAttributesPayload: function(attrs)
{
var attributesChanged = !this._attributes || attrs.length !== this._attributes.length * 2;
var oldAttributesMap = this._attributesMap || {};
this._attributes = [];
this._attributesMap = {};
for (var i = 0; i < attrs.length; i += 2) {
var name = attrs[i];
var value = attrs[i + 1];
this._addAttribute(name, value);
if (attributesChanged)
continue;
if (!oldAttributesMap[name] || oldAttributesMap[name].value !== value)
attributesChanged = true;
}
return attributesChanged;
},
/**
* @param {!WebInspector.DOMNode} prev
* @param {!DOMAgent.Node} payload
* @return {!WebInspector.DOMNode}
*/
_insertChild: function(prev, payload)
{
var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
this._children.splice(this._children.indexOf(prev) + 1, 0, node);
this._renumber();
return node;
},
/**
* @param {!WebInspector.DOMNode} node
*/
_removeChild: function(node)
{
if (node.pseudoType()) {
this._pseudoElements.delete(node.pseudoType());
} else {
var shadowRootIndex = this._shadowRoots.indexOf(node);
if (shadowRootIndex !== -1) {
this._shadowRoots.splice(shadowRootIndex, 1);
} else {
console.assert(this._children.indexOf(node) !== -1);
this._children.splice(this._children.indexOf(node), 1);
}
}
node.parentNode = null;
this._subtreeMarkerCount -= node._subtreeMarkerCount;
if (node._subtreeMarkerCount)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged, this);
this._renumber();
},
/**
* @param {!Array.<!DOMAgent.Node>} payloads
*/
_setChildrenPayload: function(payloads)
{
// We set children in the constructor.
if (this._contentDocument)
return;
this._children = [];
for (var i = 0; i < payloads.length; ++i) {
var payload = payloads[i];
var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
this._children.push(node);
}
this._renumber();
},
/**
* @param {!Array.<!DOMAgent.Node>|undefined} payloads
*/
_setPseudoElements: function(payloads)
{
this._pseudoElements = new Map();
if (!payloads)
return;
for (var i = 0; i < payloads.length; ++i) {
var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payloads[i]);
node.parentNode = this;
this._pseudoElements.set(node.pseudoType(), node);
}
},
/**
* @param {!Array.<!DOMAgent.BackendNode>} payloads
*/
_setDistributedNodePayloads: function(payloads)
{
this._distributedNodes = [];
for (var payload of payloads)
this._distributedNodes.push(new WebInspector.DOMNodeShortcut(this._domModel.target(), payload.backendNodeId, payload.nodeType, payload.nodeName));
},
_renumber: function()
{
this._childNodeCount = this._children.length;
if (this._childNodeCount == 0) {
this.firstChild = null;
this.lastChild = null;
return;
}
this.firstChild = this._children[0];
this.lastChild = this._children[this._childNodeCount - 1];
for (var i = 0; i < this._childNodeCount; ++i) {
var child = this._children[i];
child.index = i;
child.nextSibling = i + 1 < this._childNodeCount ? this._children[i + 1] : null;
child.previousSibling = i - 1 >= 0 ? this._children[i - 1] : null;
child.parentNode = this;
}
},
/**
* @param {string} name
* @param {string} value
*/
_addAttribute: function(name, value)
{
var attr = {
name: name,
value: value,
_node: this
};
this._attributesMap[name] = attr;
this._attributes.push(attr);
},
/**
* @param {string} name
* @param {string} value
*/
_setAttribute: function(name, value)
{
var attr = this._attributesMap[name];
if (attr)
attr.value = value;
else
this._addAttribute(name, value);
},
/**
* @param {string} name
*/
_removeAttribute: function(name)
{
var attr = this._attributesMap[name];
if (attr) {
this._attributes.remove(attr);
delete this._attributesMap[name];
}
},
/**
* @param {!WebInspector.DOMNode} targetNode
* @param {?WebInspector.DOMNode} anchorNode
* @param {function(?Protocol.Error, !DOMAgent.NodeId=)=} callback
*/
copyTo: function(targetNode, anchorNode, callback)
{
this._agent.copyTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, this._domModel._markRevision(this, callback));
},
/**
* @param {!WebInspector.DOMNode} targetNode
* @param {?WebInspector.DOMNode} anchorNode
* @param {function(?Protocol.Error, !DOMAgent.NodeId=)=} callback
*/
moveTo: function(targetNode, anchorNode, callback)
{
this._agent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, this._domModel._markRevision(this, callback));
},
/**
* @return {boolean}
*/
isXMLNode: function()
{
return !!this._xmlVersion;
},
/**
* @param {string} name
* @param {?*} value
*/
setMarker: function(name, value)
{
if (value === null) {
if (!this._markers.has(name))
return;
this._markers.delete(name);
for (var node = this; node; node = node.parentNode)
--node._subtreeMarkerCount;
for (var node = this; node; node = node.parentNode)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged, node);
return;
}
if (this.parentNode && !this._markers.has(name)) {
for (var node = this; node; node = node.parentNode)
++node._subtreeMarkerCount;
}
this._markers.set(name, value);
for (var node = this; node; node = node.parentNode)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged, node);
},
/**
* @param {string} name
* @return {?T}
* @template T
*/
marker: function(name)
{
return this._markers.get(name) || null;
},
/**
* @param {function(!WebInspector.DOMNode, string)} visitor
*/
traverseMarkers: function(visitor)
{
/**
* @param {!WebInspector.DOMNode} node
*/
function traverse(node)
{
if (!node._subtreeMarkerCount)
return;
for (var marker of node._markers.keys())
visitor(node, marker);
if (!node._children)
return;
for (var child of node._children)
traverse(child);
}
traverse(this);
},
/**
* @param {string} url
* @return {?string}
*/
resolveURL: function(url)
{
if (!url)
return url;
for (var frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
if (frameOwnerCandidate.baseURL)
return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
}
return null;
},
/**
* @param {string=} mode
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlight: function(mode, objectId)
{
this._domModel.highlightDOMNode(this.id, mode, undefined, objectId);
},
highlightForTwoSeconds: function()
{
this._domModel.highlightDOMNodeForTwoSeconds(this.id);
},
/**
* @param {string=} objectGroup
* @param {function(?WebInspector.RemoteObject)=} callback
*/
resolveToObject: function(objectGroup, callback)
{
this._agent.resolveNode(this.id, objectGroup, mycallback.bind(this));
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} object
* @this {WebInspector.DOMNode}
*/
function mycallback(error, object)
{
if (!callback)
return;
if (error || !object)
callback(null);
else
callback(this.target().runtimeModel.createRemoteObject(object));
}
},
/**
* @param {string=} objectGroup
* @return {!Promise<!WebInspector.RemoteObject>}
*/
resolveToObjectPromise: function(objectGroup)
{
return new Promise(resolveToObject.bind(this));
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
* @this {WebInspector.DOMNode}
*/
function resolveToObject(fulfill, reject)
{
this.resolveToObject(objectGroup, mycallback);
function mycallback(object)
{
if (object)
fulfill(object)
else
reject(null);
}
}
},
/**
* @param {function(?DOMAgent.BoxModel)} callback
*/
boxModel: function(callback)
{
this._agent.getBoxModel(this.id, this._domModel._wrapClientCallback(callback));
},
setAsInspectedNode: function()
{
var node = this;
while (true) {
var ancestor = node.ancestorUserAgentShadowRoot();
if (!ancestor)
break;
ancestor = node.ancestorShadowHost();
if (!ancestor)
break
// User agent shadow root, keep climbing up.
node = ancestor;
}
this._agent.setInspectedNode(node.id);
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @param {!WebInspector.Target} target
* @param {number} backendNodeId
* @constructor
*/
WebInspector.DeferredDOMNode = function(target, backendNodeId)
{
this._domModel = WebInspector.DOMModel.fromTarget(target);
this._backendNodeId = backendNodeId;
}
WebInspector.DeferredDOMNode.prototype = {
/**
* @param {function(?WebInspector.DOMNode)} callback
*/
resolve: function(callback)
{
if (!this._domModel) {
callback(null);
return;
}
this._domModel.pushNodesByBackendIdsToFrontend(new Set([this._backendNodeId]), onGotNode.bind(this));
/**
* @param {?Map<number, ?WebInspector.DOMNode>} nodeIds
* @this {WebInspector.DeferredDOMNode}
*/
function onGotNode(nodeIds)
{
callback(nodeIds && (nodeIds.get(this._backendNodeId) || null));
}
},
/**
* @return {!Promise.<!WebInspector.DOMNode>}
*/
resolvePromise: function()
{
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
* @this {WebInspector.DeferredDOMNode}
*/
function resolveNode(fulfill, reject)
{
/**
* @param {?WebInspector.DOMNode} node
*/
function mycallback(node)
{
fulfill(node)
}
this.resolve(mycallback);
}
return new Promise(resolveNode.bind(this));
},
/**
* @return {number}
*/
backendNodeId: function()
{
return this._backendNodeId;
},
highlight: function()
{
if (this._domModel)
this._domModel.highlightDOMNode(undefined, undefined, this._backendNodeId);
}
}
/**
* @constructor
* @param {!WebInspector.Target} target
* @param {number} backendNodeId
* @param {number} nodeType
* @param {string} nodeName
*/
WebInspector.DOMNodeShortcut = function(target, backendNodeId, nodeType, nodeName)
{
this.nodeType = nodeType;
this.nodeName = nodeName;
this.deferredNode = new WebInspector.DeferredDOMNode(target, backendNodeId);
}
/**
* @extends {WebInspector.DOMNode}
* @constructor
* @param {!WebInspector.DOMModel} domModel
* @param {!DOMAgent.Node} payload
*/
WebInspector.DOMDocument = function(domModel, payload)
{
WebInspector.DOMNode.call(this, domModel, this, false, payload);
this.documentURL = payload.documentURL || "";
this.baseURL = payload.baseURL || "";
this._listeners = {};
}
WebInspector.DOMDocument.prototype = {
__proto__: WebInspector.DOMNode.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.DOMModel = function(target) {
WebInspector.SDKModel.call(this, WebInspector.DOMModel, target);
this._agent = target.domAgent();
/** @type {!Object.<number, !WebInspector.DOMNode>} */
this._idToDOMNode = {};
/** @type {?WebInspector.DOMDocument} */
this._document = null;
/** @type {!Object.<number, boolean>} */
this._attributeLoadNodeIds = {};
target.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));
this._inspectModeEnabled = false;
this._defaultHighlighter = new WebInspector.DefaultDOMNodeHighlighter(this._agent);
this._highlighter = this._defaultHighlighter;
this._agent.enable();
}
WebInspector.DOMModel.Events = {
AttrModified: "AttrModified",
AttrRemoved: "AttrRemoved",
CharacterDataModified: "CharacterDataModified",
DOMMutated: "DOMMutated",
NodeInserted: "NodeInserted",
NodeInspected: "NodeInspected",
NodeHighlightedInOverlay: "NodeHighlightedInOverlay",
NodeRemoved: "NodeRemoved",
DocumentUpdated: "DocumentUpdated",
ChildNodeCountUpdated: "ChildNodeCountUpdated",
UndoRedoRequested: "UndoRedoRequested",
UndoRedoCompleted: "UndoRedoCompleted",
DistributedNodesChanged: "DistributedNodesChanged",
ModelSuspended: "ModelSuspended",
InspectModeWillBeToggled: "InspectModeWillBeToggled",
MarkersChanged: "MarkersChanged"
}
/**
* @param {!WebInspector.RemoteObject} object
*/
WebInspector.DOMModel.highlightObjectAsDOMNode = function(object)
{
var domModel = WebInspector.DOMModel.fromTarget(object.target());
if (domModel)
domModel.highlightDOMNode(undefined, undefined, undefined, object.objectId);
}
/**
* @return {!Array<!WebInspector.DOMModel>}
*/
WebInspector.DOMModel.instances = function()
{
var result = [];
for (var target of WebInspector.targetManager.targets()) {
var domModel = WebInspector.DOMModel.fromTarget(target);
if (domModel)
result.push(domModel);
}
return result;
}
WebInspector.DOMModel.hideDOMNodeHighlight = function()
{
for (var domModel of WebInspector.DOMModel.instances())
domModel.highlightDOMNode(-1);//fixme GS_MODIFY
}
WebInspector.DOMModel.cancelSearch = function()
{
for (var domModel of WebInspector.DOMModel.instances())
domModel._cancelSearch();
}
WebInspector.DOMModel.prototype = {
/**
* @param {!WebInspector.DOMNode} node
*/
_scheduleMutationEvent: function(node)
{
if (!this.hasEventListeners(WebInspector.DOMModel.Events.DOMMutated))
return;
this._lastMutationId = (this._lastMutationId || 0) + 1;
Promise.resolve().then(callObserve.bind(this, node, this._lastMutationId));
/**
* @this {WebInspector.DOMModel}
* @param {!WebInspector.DOMNode} node
* @param {number} mutationId
*/
function callObserve(node, mutationId)
{
if (!this.hasEventListeners(WebInspector.DOMModel.Events.DOMMutated) || this._lastMutationId !== mutationId)
return;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.DOMMutated, node);
}
},
/**
* @param {function(!WebInspector.DOMDocument)=} callback
*/
requestDocument: function(callback)
{
if (this._document) {
if (callback)
callback(this._document);
return;
}
if (this._pendingDocumentRequestCallbacks) {
this._pendingDocumentRequestCallbacks.push(callback);
return;
}
this._pendingDocumentRequestCallbacks = [callback];
/**
* @this {WebInspector.DOMModel}
* @param {?Protocol.Error} error
* @param {!DOMAgent.Node} root
*/
function onDocumentAvailable(error, root)
{
if (!error)
this._setDocument(root);
for (var i = 0; i < this._pendingDocumentRequestCallbacks.length; ++i) {
var callback = this._pendingDocumentRequestCallbacks[i];
if (callback)
callback(this._document);
}
delete this._pendingDocumentRequestCallbacks;
}
this._agent.getDocument(onDocumentAvailable.bind(this));
},
/**
* @return {?WebInspector.DOMDocument}
*/
existingDocument: function()
{
return this._document;
},
/**
* @param {!RuntimeAgent.RemoteObjectId} objectId
* @param {function(?WebInspector.DOMNode)=} callback
*/
pushNodeToFrontend: function(objectId, callback)
{
/**
* @param {?DOMAgent.NodeId} nodeId
* @this {!WebInspector.DOMModel}
*/
function mycallback(nodeId)
{
callback(nodeId ? this.nodeForId(nodeId) : null);
}
this._dispatchWhenDocumentAvailable(this._agent.requestNode.bind(this._agent, objectId), mycallback.bind(this));
},
/**
* @param {string} path
* @param {function(?number)=} callback
*/
pushNodeByPathToFrontend: function(path, callback)
{
this._dispatchWhenDocumentAvailable(this._agent.pushNodeByPathToFrontend.bind(this._agent, path), callback);
},
/**
* @param {!Set<number>} backendNodeIds
* @param {function(?Map<number, ?WebInspector.DOMNode>)} callback
*/
pushNodesByBackendIdsToFrontend: function(backendNodeIds, callback)
{
var backendNodeIdsArray = Array.from(backendNodeIds.values());
/**
* @param {?Array<!DOMAgent.NodeId>} nodeIds
* @this {!WebInspector.DOMModel}
*/
function mycallback(nodeIds)
{
if (!nodeIds) {
callback(null);
return;
}
/** @type {!Map<number, ?WebInspector.DOMNode>} */
var map = new Map();
for (var i = 0; i < nodeIds.length; ++i) {
if (nodeIds[i])
map.set(backendNodeIdsArray[i], this.nodeForId(nodeIds[i]));
}
callback(map);
}
this._dispatchWhenDocumentAvailable(this._agent.pushNodesByBackendIdsToFrontend.bind(this._agent, backendNodeIdsArray), mycallback.bind(this));
},
/**
* @param {function(!T)=} callback
* @return {function(?Protocol.Error, !T=)|undefined}
* @template T
*/
_wrapClientCallback: function(callback)
{
if (!callback)
return;
/**
* @param {?Protocol.Error} error
* @param {!T=} result
* @template T
*/
var wrapper = function(error, result)
{
// Caller is responsible for handling the actual error.
callback(error ? null : result);
};
return wrapper;
},
/**
* @param {function(function(?Protocol.Error, !T=)=)} func
* @param {function(!T)=} callback
* @template T
*/
_dispatchWhenDocumentAvailable: function(func, callback)
{
var callbackWrapper = this._wrapClientCallback(callback);
/**
* @this {WebInspector.DOMModel}
*/
function onDocumentAvailable()
{
if (this._document)
func(callbackWrapper);
else {
if (callbackWrapper)
callbackWrapper("No document");
}
}
this.requestDocument(onDocumentAvailable.bind(this));
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {string} name
* @param {string} value
*/
_attributeModified: function(nodeId, name, value)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;
node._setAttribute(name, value);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified, { node: node, name: name });
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {string} name
*/
_attributeRemoved: function(nodeId, name)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;
node._removeAttribute(name);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrRemoved, { node: node, name: name });
this._scheduleMutationEvent(node);
},
/**
* @param {!Array.<!DOMAgent.NodeId>} nodeIds
*/
_inlineStyleInvalidated: function(nodeIds)
{
for (var i = 0; i < nodeIds.length; ++i)
this._attributeLoadNodeIds[nodeIds[i]] = true;
if ("_loadNodeAttributesTimeout" in this)
return;
this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 20);
},
_loadNodeAttributes: function()
{
/**
* @this {WebInspector.DOMModel}
* @param {!DOMAgent.NodeId} nodeId
* @param {?Protocol.Error} error
* @param {!Array.<string>} attributes
*/
function callback(nodeId, error, attributes)
{
if (error) {
// We are calling _loadNodeAttributes asynchronously, it is ok if node is not found.
return;
}
var node = this._idToDOMNode[nodeId];
if (node) {
if (node._setAttributesPayload(attributes)) {
this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified, { node: node, name: "style" });
this._scheduleMutationEvent(node);
}
}
}
delete this._loadNodeAttributesTimeout;
for (var nodeId in this._attributeLoadNodeIds) {
var nodeIdAsNumber = parseInt(nodeId, 10);
this._agent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsNumber));
}
this._attributeLoadNodeIds = {};
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {string} newValue
*/
_characterDataModified: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._nodeValue = newValue;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.CharacterDataModified, node);
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @return {?WebInspector.DOMNode}
*/
nodeForId: function(nodeId)
{
return this._idToDOMNode[nodeId] || null;
},
_documentUpdated: function()
{
this._setDocument(null);
},
/**
* @param {?DOMAgent.Node} payload
*/
_setDocument: function(payload)
{
this._idToDOMNode = {};
if (payload && "nodeId" in payload)
this._document = new WebInspector.DOMDocument(this, payload);
else
this._document = null;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.DocumentUpdated, this._document);
},
/**
* @param {!DOMAgent.Node} payload
*/
_setDetachedRoot: function(payload)
{
if (payload.nodeName === "#document")
new WebInspector.DOMDocument(this, payload);
else
new WebInspector.DOMNode(this, null, false, payload);
},
/**
* @param {!DOMAgent.NodeId} parentId
* @param {!Array.<!DOMAgent.Node>} payloads
*/
_setChildNodes: function(parentId, payloads)
{
if (!parentId && payloads.length) {
this._setDetachedRoot(payloads[0]);
return;
}
var parent = this._idToDOMNode[parentId];
parent._setChildrenPayload(payloads);
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {number} newValue
*/
_childNodeCountUpdated: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._childNodeCount = newValue;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.ChildNodeCountUpdated, node);
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.NodeId} prevId
* @param {!DOMAgent.Node} payload
*/
_childNodeInserted: function(parentId, prevId, payload)
{
var parent = this._idToDOMNode[parentId];
var prev = this._idToDOMNode[prevId];
var node = parent._insertChild(prev, payload);
this._idToDOMNode[node.id] = node;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.NodeId} nodeId
*/
_childNodeRemoved: function(parentId, nodeId)
{
var parent = this._idToDOMNode[parentId];
var node = this._idToDOMNode[nodeId];
parent._removeChild(node);
this._unbind(node);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: node, parent: parent});
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} hostId
* @param {!DOMAgent.Node} root
*/
_shadowRootPushed: function(hostId, root)
{
var host = this._idToDOMNode[hostId];
if (!host)
return;
var node = new WebInspector.DOMNode(this, host.ownerDocument, true, root);
node.parentNode = host;
this._idToDOMNode[node.id] = node;
host._shadowRoots.unshift(node);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} hostId
* @param {!DOMAgent.NodeId} rootId
*/
_shadowRootPopped: function(hostId, rootId)
{
var host = this._idToDOMNode[hostId];
if (!host)
return;
var root = this._idToDOMNode[rootId];
if (!root)
return;
host._removeChild(root);
this._unbind(root);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: root, parent: host});
this._scheduleMutationEvent(root);
},
/**
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.Node} pseudoElement
*/
_pseudoElementAdded: function(parentId, pseudoElement)
{
var parent = this._idToDOMNode[parentId];
if (!parent)
return;
var node = new WebInspector.DOMNode(this, parent.ownerDocument, false, pseudoElement);
node.parentNode = parent;
this._idToDOMNode[node.id] = node;
console.assert(!parent._pseudoElements.get(node.pseudoType()));
parent._pseudoElements.set(node.pseudoType(), node);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
this._scheduleMutationEvent(node);
},
/**
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.NodeId} pseudoElementId
*/
_pseudoElementRemoved: function(parentId, pseudoElementId)
{
var parent = this._idToDOMNode[parentId];
if (!parent)
return;
var pseudoElement = this._idToDOMNode[pseudoElementId];
if (!pseudoElement)
return;
parent._removeChild(pseudoElement);
this._unbind(pseudoElement);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: pseudoElement, parent: parent});
this._scheduleMutationEvent(pseudoElement);
},
/**
* @param {!DOMAgent.NodeId} insertionPointId
* @param {!Array.<!DOMAgent.BackendNode>} distributedNodes
*/
_distributedNodesUpdated: function(insertionPointId, distributedNodes)
{
var insertionPoint = this._idToDOMNode[insertionPointId];
if (!insertionPoint)
return;
insertionPoint._setDistributedNodePayloads(distributedNodes);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.DistributedNodesChanged, insertionPoint);
this._scheduleMutationEvent(insertionPoint);
},
/**
* @param {!WebInspector.DOMNode} node
*/
_unbind: function(node)
{
delete this._idToDOMNode[node.id];
for (var i = 0; node._children && i < node._children.length; ++i)
this._unbind(node._children[i]);
for (var i = 0; i < node._shadowRoots.length; ++i)
this._unbind(node._shadowRoots[i]);
var pseudoElements = node.pseudoElements();
for (var value of pseudoElements.values())
this._unbind(value);
if (node._templateContent)
this._unbind(node._templateContent);
},
/**
* @param {!DOMAgent.BackendNodeId} backendNodeId
*/
_inspectNodeRequested: function(backendNodeId)
{
var deferredNode = new WebInspector.DeferredDOMNode(this.target(), backendNodeId);
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInspected, deferredNode);
},
/**
* @param {string} query
* @param {boolean} includeUserAgentShadowDOM
* @param {function(number)} searchCallback
*/
performSearch: function(query, includeUserAgentShadowDOM, searchCallback)
{
WebInspector.DOMModel.cancelSearch();
/**
* @param {?Protocol.Error} error
* @param {string} searchId
* @param {number} resultsCount
* @this {WebInspector.DOMModel}
*/
function callback(error, searchId, resultsCount)
{
this._searchId = searchId;
searchCallback(resultsCount);
}
this._agent.performSearch(query, includeUserAgentShadowDOM, callback.bind(this));
},
/**
* @param {string} query
* @param {boolean} includeUserAgentShadowDOM
* @return {!Promise.<number>}
*/
performSearchPromise: function(query, includeUserAgentShadowDOM)
{
return new Promise(performSearch.bind(this));
/**
* @param {function(number)} resolve
* @this {WebInspector.DOMModel}
*/
function performSearch(resolve)
{
this._agent.performSearch(query, includeUserAgentShadowDOM, callback.bind(this));
/**
* @param {?Protocol.Error} error
* @param {string} searchId
* @param {number} resultsCount
* @this {WebInspector.DOMModel}
*/
function callback(error, searchId, resultsCount)
{
if (!error)
this._searchId = searchId;
resolve(error ? 0 : resultsCount);
}
}
},
/**
* @param {number} index
* @param {?function(?WebInspector.DOMNode)} callback
*/
searchResult: function(index, callback)
{
if (this._searchId)
this._agent.getSearchResults(this._searchId, index, index + 1, searchResultsCallback.bind(this));
else
callback(null);
/**
* @param {?Protocol.Error} error
* @param {!Array.<number>} nodeIds
* @this {WebInspector.DOMModel}
*/
function searchResultsCallback(error, nodeIds)
{
if (error) {
console.error(error);
callback(null);
return;
}
if (nodeIds.length != 1)
return;
callback(this.nodeForId(nodeIds[0]));
}
},
_cancelSearch: function()
{
if (this._searchId) {
this._agent.discardSearchResults(this._searchId);
delete this._searchId;
}
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {string} selectors
* @param {function(?DOMAgent.NodeId)=} callback
*/
querySelector: function(nodeId, selectors, callback)
{
this._agent.querySelector(nodeId, selectors, this._wrapClientCallback(callback));
},
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {string} selectors
* @param {function(!Array.<!DOMAgent.NodeId>=)=} callback
*/
querySelectorAll: function(nodeId, selectors, callback)
{
this._agent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callback));
},
/**
* @param {!DOMAgent.NodeId=} nodeId
* @param {string=} mode
* @param {!DOMAgent.BackendNodeId=} backendNodeId
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlightDOMNode: function(nodeId, mode, backendNodeId, objectId)
{
this.highlightDOMNodeWithConfig(nodeId, { mode: mode }, backendNodeId, objectId);
},
/**
* @param {!DOMAgent.NodeId=} nodeId
* @param {!{mode: (string|undefined), showInfo: (boolean|undefined), selectors: (string|undefined)}=} config
* @param {!DOMAgent.BackendNodeId=} backendNodeId
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlightDOMNodeWithConfig: function(nodeId, config, backendNodeId, objectId)
{
config = config || { mode: "all", showInfo: undefined, selectors: undefined };
if (this._hideDOMNodeHighlightTimeout) {
clearTimeout(this._hideDOMNodeHighlightTimeout);
delete this._hideDOMNodeHighlightTimeout;
}
var highlightConfig = this._buildHighlightConfig(config.mode);
if (typeof config.showInfo !== "undefined")
highlightConfig.showInfo = config.showInfo;
if (typeof config.selectors !== "undefined")
highlightConfig.selectorList = config.selectors;
this._highlighter.highlightDOMNode(this.nodeForId(nodeId || 0), highlightConfig, backendNodeId, objectId);
},
/**
* @param {!DOMAgent.NodeId} nodeId
*/
highlightDOMNodeForTwoSeconds: function(nodeId)
{
this.highlightDOMNode(nodeId);
this._hideDOMNodeHighlightTimeout = setTimeout(WebInspector.DOMModel.hideDOMNodeHighlight.bind(WebInspector.DOMModel), 2000);
},
/**
* @param {!PageAgent.FrameId} frameId
*/
highlightFrame: function(frameId)
{
this._highlighter.highlightFrame(frameId);
},
/**
* @param {!DOMAgent.InspectMode} mode
* @param {function(?Protocol.Error)=} callback
*/
setInspectMode: function(mode, callback)
{
/**
* @this {WebInspector.DOMModel}
*/
function onDocumentAvailable()
{
this._inspectModeEnabled = mode !== DOMAgent.InspectMode.None;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeEnabled);
this._highlighter.setInspectMode(mode, this._buildHighlightConfig(), callback);
}
this.requestDocument(onDocumentAvailable.bind(this));
},
/**
* @return {boolean}
*/
inspectModeEnabled: function()
{
return this._inspectModeEnabled;
},
/**
* @param {string=} mode
* @return {!DOMAgent.HighlightConfig}
*/
_buildHighlightConfig: function(mode)
{
mode = mode || "all";
var showRulers = WebInspector.moduleSetting("showMetricsRulers").get();
var highlightConfig = { showInfo: mode === "all", showRulers: showRulers, showExtensionLines: showRulers };
if (mode === "all" || mode === "content")
highlightConfig.contentColor = WebInspector.Color.PageHighlight.Content.toProtocolRGBA();
if (mode === "all" || mode === "padding")
highlightConfig.paddingColor = WebInspector.Color.PageHighlight.Padding.toProtocolRGBA();
if (mode === "all" || mode === "border")
highlightConfig.borderColor = WebInspector.Color.PageHighlight.Border.toProtocolRGBA();
if (mode === "all" || mode === "margin")
highlightConfig.marginColor = WebInspector.Color.PageHighlight.Margin.toProtocolRGBA();
if (mode === "all") {
highlightConfig.eventTargetColor = WebInspector.Color.PageHighlight.EventTarget.toProtocolRGBA();
highlightConfig.shapeColor = WebInspector.Color.PageHighlight.Shape.toProtocolRGBA();
highlightConfig.shapeMarginColor = WebInspector.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
highlightConfig.displayAsMaterial = Runtime.experiments.isEnabled("inspectTooltip");
}
return highlightConfig;
},
/**
* @param {!WebInspector.DOMNode} node
* @param {function(?Protocol.Error, ...)=} callback
* @return {function(...)}
* @template T
*/
_markRevision: function(node, callback)
{
/**
* @param {?Protocol.Error} error
* @this {WebInspector.DOMModel}
*/
function wrapperFunction(error)
{
if (!error)
this.markUndoableState();
if (callback)
callback.apply(this, arguments);
}
return wrapperFunction.bind(this);
},
markUndoableState: function()
{
this._agent.markUndoableState();
},
/**
* @param {function(?Protocol.Error)=} callback
*/
undo: function(callback)
{
/**
* @param {?Protocol.Error} error
* @this {WebInspector.DOMModel}
*/
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);
callback(error);
}
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);
this._agent.undo(callback);
},
/**
* @param {function(?Protocol.Error)=} callback
*/
redo: function(callback)
{
/**
* @param {?Protocol.Error} error
* @this {WebInspector.DOMModel}
*/
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);
callback(error);
}
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);
this._agent.redo(callback);
},
/**
* @param {?WebInspector.DOMNodeHighlighter} highlighter
*/
setHighlighter: function(highlighter)
{
this._highlighter = highlighter || this._defaultHighlighter;
},
/**
* @param {number} x
* @param {number} y
* @param {function(?WebInspector.DOMNode)} callback
*/
nodeForLocation: function(x, y, callback)
{
this._agent.getNodeForLocation(x, y, mycallback.bind(this));
/**
* @param {?Protocol.Error} error
* @param {number} nodeId
* @this {WebInspector.DOMModel}
*/
function mycallback(error, nodeId)
{
if (error) {
callback(null);
return;
}
callback(this.nodeForId(nodeId));
}
},
/**
* @param {!WebInspector.RemoteObject} object
* @param {function(?WebInspector.DOMNode)} callback
*/
pushObjectAsNodeToFrontend: function(object, callback)
{
if (object.isNode())
this.pushNodeToFrontend(object.objectId, callback);
else
callback(null);
},
/**
* @override
* @return {!Promise}
*/
suspendModel: function()
{
return new Promise(promiseBody.bind(this));
/**
* @param {function()} fulfill
* @this {WebInspector.DOMModel}
*/
function promiseBody(fulfill)
{
this._agent.disable(callback.bind(this));
/**
* @this {WebInspector.DOMModel}
*/
function callback()
{
this._setDocument(null);
fulfill();
}
}
},
/**
* @override
* @return {!Promise}
*/
resumeModel: function()
{
return new Promise(promiseBody.bind(this));
/**
* @param {function()} fulfill
* @this {WebInspector.DOMModel}
*/
function promiseBody(fulfill)
{
this._agent.enable(fulfill);
}
},
/**
* @param {!DOMAgent.NodeId} nodeId
*/
nodeHighlightRequested: function(nodeId)
{
var node = this.nodeForId(nodeId);
if (!node)
return;
this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeHighlightedInOverlay, node);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {DOMAgent.Dispatcher}
* @param {!WebInspector.DOMModel} domModel
*/
WebInspector.DOMDispatcher = function(domModel)
{
this._domModel = domModel;
}
WebInspector.DOMDispatcher.prototype = {
/**
* @override
*/
documentUpdated: function()
{
this._domModel._documentUpdated();
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
*/
inspectNodeRequested: function(nodeId)
{
this._domModel._inspectNodeRequested(nodeId);
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
* @param {string} name
* @param {string} value
*/
attributeModified: function(nodeId, name, value)
{
this._domModel._attributeModified(nodeId, name, value);
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
* @param {string} name
*/
attributeRemoved: function(nodeId, name)
{
this._domModel._attributeRemoved(nodeId, name);
},
/**
* @override
* @param {!Array.<!DOMAgent.NodeId>} nodeIds
*/
inlineStyleInvalidated: function(nodeIds)
{
this._domModel._inlineStyleInvalidated(nodeIds);
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
* @param {string} characterData
*/
characterDataModified: function(nodeId, characterData)
{
this._domModel._characterDataModified(nodeId, characterData);
},
/**
* @override
* @param {!DOMAgent.NodeId} parentId
* @param {!Array.<!DOMAgent.Node>} payloads
*/
setChildNodes: function(parentId, payloads)
{
this._domModel._setChildNodes(parentId, payloads);
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
* @param {number} childNodeCount
*/
childNodeCountUpdated: function(nodeId, childNodeCount)
{
this._domModel._childNodeCountUpdated(nodeId, childNodeCount);
},
/**
* @override
* @param {!DOMAgent.NodeId} parentNodeId
* @param {!DOMAgent.NodeId} previousNodeId
* @param {!DOMAgent.Node} payload
*/
childNodeInserted: function(parentNodeId, previousNodeId, payload)
{
this._domModel._childNodeInserted(parentNodeId, previousNodeId, payload);
},
/**
* @override
* @param {!DOMAgent.NodeId} parentNodeId
* @param {!DOMAgent.NodeId} nodeId
*/
childNodeRemoved: function(parentNodeId, nodeId)
{
this._domModel._childNodeRemoved(parentNodeId, nodeId);
},
/**
* @override
* @param {!DOMAgent.NodeId} hostId
* @param {!DOMAgent.Node} root
*/
shadowRootPushed: function(hostId, root)
{
this._domModel._shadowRootPushed(hostId, root);
},
/**
* @override
* @param {!DOMAgent.NodeId} hostId
* @param {!DOMAgent.NodeId} rootId
*/
shadowRootPopped: function(hostId, rootId)
{
this._domModel._shadowRootPopped(hostId, rootId);
},
/**
* @override
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.Node} pseudoElement
*/
pseudoElementAdded: function(parentId, pseudoElement)
{
this._domModel._pseudoElementAdded(parentId, pseudoElement);
},
/**
* @override
* @param {!DOMAgent.NodeId} parentId
* @param {!DOMAgent.NodeId} pseudoElementId
*/
pseudoElementRemoved: function(parentId, pseudoElementId)
{
this._domModel._pseudoElementRemoved(parentId, pseudoElementId);
},
/**
* @override
* @param {!DOMAgent.NodeId} insertionPointId
* @param {!Array.<!DOMAgent.BackendNode>} distributedNodes
*/
distributedNodesUpdated: function(insertionPointId, distributedNodes)
{
this._domModel._distributedNodesUpdated(insertionPointId, distributedNodes);
},
/**
* @override
* @param {!DOMAgent.NodeId} nodeId
*/
nodeHighlightRequested: function(nodeId)
{
this._domModel.nodeHighlightRequested(nodeId);
}
}
/**
* @interface
*/
WebInspector.DOMNodeHighlighter = function() {
}
WebInspector.DOMNodeHighlighter.prototype = {
/**
* @param {?WebInspector.DOMNode} node
* @param {!DOMAgent.HighlightConfig} config
* @param {!DOMAgent.BackendNodeId=} backendNodeId
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlightDOMNode: function(node, config, backendNodeId, objectId) {},
/**
* @param {!DOMAgent.InspectMode} mode
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
setInspectMode: function(mode, config, callback) {},
/**
* @param {!PageAgent.FrameId} frameId
*/
highlightFrame: function(frameId) {}
}
/**
* @constructor
* @implements {WebInspector.DOMNodeHighlighter}
* @param {!Protocol.DOMAgent} agent
*/
WebInspector.DefaultDOMNodeHighlighter = function(agent)
{
this._agent = agent;
}
WebInspector.DefaultDOMNodeHighlighter.prototype = {
/**
* @override
* @param {?WebInspector.DOMNode} node
* @param {!DOMAgent.HighlightConfig} config
* @param {!DOMAgent.BackendNodeId=} backendNodeId
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
highlightDOMNode: function(node, config, backendNodeId, objectId)
{
if (objectId || node || backendNodeId)
this._agent.highlightNode(config, (objectId || backendNodeId) ? undefined : node.id, backendNodeId, objectId);
else
this._agent.hideHighlight();
},
/**
* @override
* @param {!DOMAgent.InspectMode} mode
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
setInspectMode: function(mode, config, callback)
{
this._agent.setInspectMode(mode, config, callback);
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
highlightFrame: function(frameId)
{
this._agent.highlightFrame(frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
}
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.DOMModel}
*/
WebInspector.DOMModel.fromTarget = function(target)
{
return /** @type {?WebInspector.DOMModel} */ (target.model(WebInspector.DOMModel));
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.DebuggerModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.DebuggerModel, target);
target.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));
this._agent = target.debuggerAgent();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.TargetDisposed, this._targetDisposed, this);
/** @type {?WebInspector.DebuggerPausedDetails} */
this._debuggerPausedDetails = null;
/** @type {!Object.<string, !WebInspector.Script>} */
this._scripts = {};
/** @type {!Map.<string, !Array.<!WebInspector.Script>>} */
this._scriptsBySourceURL = new Map();
/** @type {!WebInspector.Object} */
this._breakpointResolvedEventTarget = new WebInspector.Object();
this._isPausing = false;
WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this._pauseOnExceptionStateChanged, this);
WebInspector.moduleSetting("pauseOnCaughtException").addChangeListener(this._pauseOnExceptionStateChanged, this);
WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this.asyncStackTracesStateChanged, this);
this.enableDebugger();
}
/** @typedef {{location: ?WebInspector.DebuggerModel.Location, sourceURL: ?string, functionName: string, scopeChain: (Array.<!DebuggerAgent.Scope>|null)}} */
WebInspector.DebuggerModel.FunctionDetails;
/** @typedef {{location: ?WebInspector.DebuggerModel.Location, sourceURL: ?string, functionName: string, status: string}} */
WebInspector.DebuggerModel.GeneratorObjectDetails;
/**
* Keep these in sync with WebCore::V8Debugger
*
* @enum {string}
*/
WebInspector.DebuggerModel.PauseOnExceptionsState = {
DontPauseOnExceptions : "none",
PauseOnAllExceptions : "all",
PauseOnUncaughtExceptions: "uncaught"
};
/** @enum {string} */
WebInspector.DebuggerModel.Events = {
DebuggerWasEnabled: "DebuggerWasEnabled",
DebuggerWasDisabled: "DebuggerWasDisabled",
BeforeDebuggerPaused: "BeforeDebuggerPaused",
DebuggerPaused: "DebuggerPaused",
DebuggerResumed: "DebuggerResumed",
ParsedScriptSource: "ParsedScriptSource",
FailedToParseScriptSource: "FailedToParseScriptSource",
GlobalObjectCleared: "GlobalObjectCleared",
CallFrameSelected: "CallFrameSelected",
ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame"
}
/** @enum {string} */
WebInspector.DebuggerModel.BreakReason = {
DOM: "DOM",
EventListener: "EventListener",
XHR: "XHR",
Exception: "exception",
PromiseRejection: "promiseRejection",
Assert: "assert",
CSPViolation: "CSPViolation",
DebugCommand: "debugCommand",
Other: "other"
}
/**
* @param {number=} value
* @return {number}
*/
WebInspector.DebuggerModel.fromOneBased = function(value)
{
// FIXME(webkit:62725): console stack trace line/column numbers are one-based.
return value ? value - 1 : 0;
}
WebInspector.DebuggerModel.prototype = {
/**
* @return {boolean}
*/
debuggerEnabled: function()
{
return !!this._debuggerEnabled;
},
/**
* @param {function()=} callback
*/
enableDebugger: function(callback)
{
if (this._debuggerEnabled) {
if (callback)
callback();
return;
}
this._agent.enable(callback);
this._debuggerEnabled = true;
this._pauseOnExceptionStateChanged();
this.asyncStackTracesStateChanged();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasEnabled);
},
/**
* @param {function()=} callback
*/
disableDebugger: function(callback)
{
if (!this._debuggerEnabled) {
if (callback)
callback();
return;
}
this._agent.disable(callback);
this._debuggerEnabled = false;
this._isPausing = false;
this.asyncStackTracesStateChanged();
this.globalObjectCleared();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
},
/**
* @param {boolean} skip
*/
_skipAllPauses: function(skip)
{
if (this._skipAllPausesTimeout) {
clearTimeout(this._skipAllPausesTimeout);
delete this._skipAllPausesTimeout;
}
this._agent.setSkipAllPauses(skip);
},
/**
* @param {number} timeout
*/
skipAllPausesUntilReloadOrTimeout: function(timeout)
{
if (this._skipAllPausesTimeout)
clearTimeout(this._skipAllPausesTimeout);
this._agent.setSkipAllPauses(true);
// If reload happens before the timeout, the flag will be already unset and the timeout callback won't change anything.
this._skipAllPausesTimeout = setTimeout(this._skipAllPauses.bind(this, false), timeout);
},
_pauseOnExceptionStateChanged: function()
{
var state;
if (!WebInspector.moduleSetting("pauseOnExceptionEnabled").get()) {
state = WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions;
} else if (WebInspector.moduleSetting("pauseOnCaughtException").get()) {
state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions;
} else {
state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions;
}
this._agent.setPauseOnExceptions(state);
},
asyncStackTracesStateChanged: function()
{
const maxAsyncStackChainDepth = 4;
var enabled = WebInspector.moduleSetting("enableAsyncStackTraces").get() && this._debuggerEnabled;
this._agent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0);
},
stepInto: function()
{
this._agent.stepInto();
},
stepOver: function()
{
this._agent.stepOver();
},
stepOut: function()
{
this._agent.stepOut();
},
resume: function()
{
this._agent.resume();
this._isPausing = false;
},
pause: function()
{
this._isPausing = true;
this._skipAllPauses(false);
this._agent.pause();
},
/**
* @param {boolean} active
*/
setBreakpointsActive: function(active)
{
this._agent.setBreakpointsActive(active);
},
/**
* @param {string} url
* @param {number} lineNumber
* @param {number=} columnNumber
* @param {string=} condition
* @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.DebuggerModel.Location>)=} callback
*/
setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callback)
{
// Adjust column if needed.
var minColumnNumber = 0;
var scripts = this._scriptsBySourceURL.get(url) || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (lineNumber === script.lineOffset)
minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.columnOffset) : script.columnOffset;
}
columnNumber = Math.max(columnNumber, minColumnNumber);
var target = this.target();
/**
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!Array.<!DebuggerAgent.Location>} locations
* @this {WebInspector.DebuggerModel}
*/
function didSetBreakpoint(error, breakpointId, locations)
{
if (callback) {
var rawLocations = locations ? locations.map(WebInspector.DebuggerModel.Location.fromPayload.bind(WebInspector.DebuggerModel.Location, this)) : [];
callback(error ? null : breakpointId, rawLocations);
}
}
this._agent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, didSetBreakpoint.bind(this));
},
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {string} condition
* @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.DebuggerModel.Location>)=} callback
*/
setBreakpointBySourceId: function(rawLocation, condition, callback)
{
var target = this.target();
/**
* @this {WebInspector.DebuggerModel}
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!DebuggerAgent.Location} actualLocation
*/
function didSetBreakpoint(error, breakpointId, actualLocation)
{
if (callback) {
var location = WebInspector.DebuggerModel.Location.fromPayload(this, actualLocation);
callback(error ? null : breakpointId, [location]);
}
}
this._agent.setBreakpoint(rawLocation.payload(), condition, didSetBreakpoint.bind(this));
},
/**
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {function()=} callback
*/
removeBreakpoint: function(breakpointId, callback)
{
this._agent.removeBreakpoint(breakpointId, innerCallback);
/**
* @param {?Protocol.Error} error
*/
function innerCallback(error)
{
if (error)
console.error("Failed to remove breakpoint: " + error);
if (callback)
callback();
}
},
/**
* @param {string} objectId
* @param {function(?Array.<!DebuggerAgent.CollectionEntry>)} callback
*/
getCollectionEntries: function(objectId, callback)
{
this._agent.getCollectionEntries(objectId, innerCallback);
/**
* @param {?Protocol.Error} error
* @param {?Array.<!DebuggerAgent.CollectionEntry>} response
*/
function innerCallback(error, response)
{
if (error) {
console.error(error);
callback(null);
return;
}
callback(response);
}
},
/**
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!DebuggerAgent.Location} location
*/
_breakpointResolved: function(breakpointId, location)
{
this._breakpointResolvedEventTarget.dispatchEventToListeners(breakpointId, WebInspector.DebuggerModel.Location.fromPayload(this, location));
},
globalObjectCleared: function()
{
this._setDebuggerPausedDetails(null);
this._reset();
// TODO(dgozman): move clients to ExecutionContextDestroyed/ScriptCollected events.
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObjectCleared);
},
_reset: function()
{
this._scripts = {};
this._scriptsBySourceURL.clear();
},
/**
* @return {!Object.<string, !WebInspector.Script>}
*/
get scripts()
{
return this._scripts;
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @return {!WebInspector.Script}
*/
scriptForId: function(scriptId)
{
return this._scripts[scriptId] || null;
},
/**
* @return {!Array.<!WebInspector.Script>}
*/
scriptsForSourceURL: function(sourceURL)
{
if (!sourceURL)
return [];
return this._scriptsBySourceURL.get(sourceURL) || [];
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {string} newSource
* @param {function(?Protocol.Error, !DebuggerAgent.SetScriptSourceError=)} callback
*/
setScriptSource: function(scriptId, newSource, callback)
{
this._scripts[scriptId].editSource(newSource, this._didEditScriptSource.bind(this, scriptId, newSource, callback));
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {string} newSource
* @param {function(?Protocol.Error, !DebuggerAgent.SetScriptSourceError=)} callback
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.SetScriptSourceError=} errorData
* @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
* @param {boolean=} needsStepIn
*/
_didEditScriptSource: function(scriptId, newSource, callback, error, errorData, callFrames, asyncStackTrace, needsStepIn)
{
if (needsStepIn) {
this.stepInto();
this._pendingLiveEditCallback = callback.bind(this, error, errorData);
return;
}
if (!error && callFrames && callFrames.length)
this._pausedScript(callFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData, this._debuggerPausedDetails.breakpointIds, asyncStackTrace);
callback(error, errorData);
},
/**
* @return {?Array.<!WebInspector.DebuggerModel.CallFrame>}
*/
get callFrames()
{
return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFrames : null;
},
/**
* @return {?WebInspector.DebuggerPausedDetails}
*/
debuggerPausedDetails: function()
{
return this._debuggerPausedDetails;
},
/**
* @param {?WebInspector.DebuggerPausedDetails} debuggerPausedDetails
* @return {boolean}
*/
_setDebuggerPausedDetails: function(debuggerPausedDetails)
{
this._isPausing = false;
this._debuggerPausedDetails = debuggerPausedDetails;
if (this._debuggerPausedDetails) {
if (Runtime.experiments.isEnabled("emptySourceMapAutoStepping")) {
if (this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BeforeDebuggerPaused, this._debuggerPausedDetails)) {
return false;
}
}
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
}
if (debuggerPausedDetails)
this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
else
this.setSelectedCallFrame(null);
return true;
},
/**
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @param {string} reason
* @param {!Object|undefined} auxData
* @param {!Array.<string>} breakpointIds
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
*/
_pausedScript: function(callFrames, reason, auxData, breakpointIds, asyncStackTrace)
{
var pausedDetails = new WebInspector.DebuggerPausedDetails(this, callFrames, reason, auxData, breakpointIds, asyncStackTrace);
if (this._setDebuggerPausedDetails(pausedDetails)) {
if (this._pendingLiveEditCallback) {
var callback = this._pendingLiveEditCallback;
delete this._pendingLiveEditCallback;
callback();
}
} else {
this._agent.stepInto();
}
},
_resumedScript: function()
{
this._setDebuggerPausedDetails(null);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {string} sourceURL
* @param {number} startLine
* @param {number} startColumn
* @param {number} endLine
* @param {number} endColumn
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
* @param {string} hash
* @param {boolean} isContentScript
* @param {boolean} isInternalScript
* @param {boolean} isLiveEdit
* @param {string=} sourceMapURL
* @param {boolean=} hasSourceURL
* @param {boolean=} deprecatedCommentWasUsed
* @param {boolean=} hasSyntaxError
* @return {!WebInspector.Script}
*/
_parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, hasSyntaxError)
{
var script = new WebInspector.Script(this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL);
this._registerScript(script);
if (!hasSyntaxError)
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
else
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script);
if (deprecatedCommentWasUsed) {
var text = WebInspector.UIString("'//@ sourceURL' and '//@ sourceMappingURL' are deprecated, please use '//# sourceURL=' and '//# sourceMappingURL=' instead.");
var msg = new WebInspector.ConsoleMessage(this.target(), WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageLevel.Warning, text, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, scriptId);
var consoleModel = this.target().consoleModel;
if (consoleModel)
consoleModel.addMessage(msg);
}
return script;
},
/**
* @param {!WebInspector.Script} script
*/
_registerScript: function(script)
{
this._scripts[script.scriptId] = script;
if (script.isAnonymousScript())
return;
var scripts = this._scriptsBySourceURL.get(script.sourceURL);
if (!scripts) {
scripts = [];
this._scriptsBySourceURL.set(script.sourceURL, scripts);
}
scripts.push(script);
},
/**
* @param {!WebInspector.Script} script
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
createRawLocation: function(script, lineNumber, columnNumber)
{
if (script.sourceURL)
return this.createRawLocationByURL(script.sourceURL, lineNumber, columnNumber);
return new WebInspector.DebuggerModel.Location(this, script.scriptId, lineNumber, columnNumber);
},
/**
* @param {string} sourceURL
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
createRawLocationByURL: function(sourceURL, lineNumber, columnNumber)
{
var closestScript = null;
var scripts = this._scriptsBySourceURL.get(sourceURL) || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (!closestScript)
closestScript = script;
if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
continue;
if (script.endLine < lineNumber || (script.endLine === lineNumber && script.endColumn <= columnNumber))
continue;
closestScript = script;
break;
}
return closestScript ? new WebInspector.DebuggerModel.Location(this, closestScript.scriptId, lineNumber, columnNumber) : null;
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
createRawLocationByScriptId: function(scriptId, lineNumber, columnNumber)
{
var script = this.scriptForId(scriptId);
return script ? this.createRawLocation(script, lineNumber, columnNumber) : null;
},
/**
* @param {!RuntimeAgent.StackTrace} stackTrace
* @return {!Array<!WebInspector.DebuggerModel.Location>}
*/
createRawLocationsByStackTrace: function(stackTrace)
{
var frames = [];
while (stackTrace) {
for (var frame of stackTrace.callFrames)
frames.push(frame);
stackTrace = stackTrace.parent;
}
var rawLocations = [];
for (var frame of frames) {
var rawLocation = this.createRawLocationByScriptId(frame.scriptId, WebInspector.DebuggerModel.fromOneBased(frame.lineNumber), WebInspector.DebuggerModel.fromOneBased(frame.columnNumber));
if (rawLocation)
rawLocations.push(rawLocation);
}
return rawLocations;
},
/**
* @return {boolean}
*/
isPaused: function()
{
return !!this.debuggerPausedDetails();
},
/**
* @return {boolean}
*/
isPausing: function()
{
return this._isPausing;
},
/**
* @param {?WebInspector.DebuggerModel.CallFrame} callFrame
*/
setSelectedCallFrame: function(callFrame)
{
this._selectedCallFrame = callFrame;
if (!this._selectedCallFrame)
return;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFrameSelected, callFrame);
},
/**
* @return {?WebInspector.DebuggerModel.CallFrame}
*/
selectedCallFrame: function()
{
return this._selectedCallFrame;
},
/**
* @param {string} code
* @param {string} objectGroup
* @param {boolean} includeCommandLineAPI
* @param {boolean} doNotPauseOnExceptionsAndMuteConsole
* @param {boolean} returnByValue
* @param {boolean} generatePreview
* @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback
*/
evaluateOnSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{
/**
* @param {?RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.DebuggerModel}
*/
function didEvaluate(result, wasThrown, exceptionDetails)
{
if (!result)
callback(null, false);
else if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result, exceptionDetails);
else
callback(this.target().runtimeModel.createRemoteObject(result), !!wasThrown, undefined, exceptionDetails);
if (objectGroup === "console")
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);
}
this.selectedCallFrame().evaluate(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluate.bind(this));
},
/**
* @param {!WebInspector.RemoteObject} remoteObject
* @param {function(?WebInspector.DebuggerModel.FunctionDetails)} callback
*/
functionDetails: function(remoteObject, callback)
{
this._agent.getFunctionDetails(remoteObject.objectId, didGetDetails.bind(this));
/**
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.FunctionDetails} response
* @this {WebInspector.DebuggerModel}
*/
function didGetDetails(error, response)
{
if (error) {
callback(null);
return;
}
var location = response.location;
var script = this.scriptForId(location.scriptId);
var rawLocation = script ? this.createRawLocation(script, location.lineNumber, location.columnNumber || 0) : null;
var sourceURL = script ? script.contentURL() : null;
callback({location: rawLocation, sourceURL: sourceURL, functionName: response.functionName, scopeChain: response.scopeChain || null});
}
},
/**
* @param {number} scopeNumber
* @param {string} variableName
* @param {!RuntimeAgent.CallArgument} newValue
* @param {string} callFrameId
* @param {function(string=)=} callback
*/
setVariableValue: function(scopeNumber, variableName, newValue, callFrameId, callback)
{
this._agent.setVariableValue(scopeNumber, variableName, newValue, callFrameId, innerCallback);
/**
* @param {?Protocol.Error} error
*/
function innerCallback(error)
{
if (error) {
console.error(error);
if (callback)
callback(error);
return;
}
if (callback)
callback();
}
},
/**
* @param {!WebInspector.RemoteObject} remoteObject
* @param {function(?WebInspector.DebuggerModel.GeneratorObjectDetails)} callback
*/
generatorObjectDetails: function(remoteObject, callback)
{
this._agent.getGeneratorObjectDetails(remoteObject.objectId, didGetDetails.bind(this));
/**
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.GeneratorObjectDetails} response
* @this {WebInspector.DebuggerModel}
*/
function didGetDetails(error, response)
{
if (error) {
console.error(error);
callback(null);
return;
}
var location = response.location;
var script = location && this.scriptForId(location.scriptId);
var rawLocation = script ? this.createRawLocation(script, location.lineNumber, location.columnNumber || 0) : null;
var sourceURL = script ? script.contentURL() : null;
callback({location: rawLocation, sourceURL: sourceURL, functionName: response.functionName, status: response.status});
}
},
/**
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
addBreakpointListener: function(breakpointId, listener, thisObject)
{
this._breakpointResolvedEventTarget.addEventListener(breakpointId, listener, thisObject)
},
/**
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeBreakpointListener: function(breakpointId, listener, thisObject)
{
this._breakpointResolvedEventTarget.removeEventListener(breakpointId, listener, thisObject);
},
/**
* @param {!WebInspector.Event} event
*/
_targetDisposed: function(event)
{
var target = /** @type {!WebInspector.Target} */ (event.data);
if (target != this.target())
return;
WebInspector.moduleSetting("pauseOnExceptionEnabled").removeChangeListener(this._pauseOnExceptionStateChanged, this);
WebInspector.moduleSetting("pauseOnCaughtException").removeChangeListener(this._pauseOnExceptionStateChanged, this);
WebInspector.moduleSetting("enableAsyncStackTraces").removeChangeListener(this.asyncStackTracesStateChanged, this);
},
/**
* @override
* @return {!Promise}
*/
suspendModel: function()
{
return new Promise(promiseBody.bind(this));
/**
* @param {function()} fulfill
* @this {WebInspector.DebuggerModel}
*/
function promiseBody(fulfill)
{
this.disableDebugger(fulfill);
}
},
/**
* @override
* @return {!Promise}
*/
resumeModel: function()
{
return new Promise(promiseBody.bind(this));
/**
* @param {function()} fulfill
* @this {WebInspector.DebuggerModel}
*/
function promiseBody(fulfill)
{
this.enableDebugger(fulfill);
}
},
__proto__: WebInspector.SDKModel.prototype
}
WebInspector.DebuggerEventTypes = {
JavaScriptPause: 0,
JavaScriptBreakpoint: 1,
NativeBreakpoint: 2
};
/**
* @constructor
* @implements {DebuggerAgent.Dispatcher}
* @param {!WebInspector.DebuggerModel} debuggerModel
*/
WebInspector.DebuggerDispatcher = function(debuggerModel)
{
this._debuggerModel = debuggerModel;
}
WebInspector.DebuggerDispatcher.prototype = {
/**
* @override
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @param {string} reason
* @param {!Object=} auxData
* @param {!Array.<string>=} breakpointIds
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
*/
paused: function(callFrames, reason, auxData, breakpointIds, asyncStackTrace)
{
this._debuggerModel._pausedScript(callFrames, reason, auxData, breakpointIds || [], asyncStackTrace);
},
/**
* @override
*/
resumed: function()
{
this._debuggerModel._resumedScript();
},
/**
* @override
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {string} sourceURL
* @param {number} startLine
* @param {number} startColumn
* @param {number} endLine
* @param {number} endColumn
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
* @param {string} hash
* @param {boolean=} isContentScript
* @param {boolean=} isInternalScript
* @param {boolean=} isLiveEdit
* @param {string=} sourceMapURL
* @param {boolean=} hasSourceURL
* @param {boolean=} deprecatedCommentWasUsed
*/
scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed)
{
this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, !!isContentScript, !!isInternalScript, !!isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, false);
},
/**
* @override
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {string} sourceURL
* @param {number} startLine
* @param {number} startColumn
* @param {number} endLine
* @param {number} endColumn
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
* @param {string} hash
* @param {boolean=} isContentScript
* @param {boolean=} isInternalScript
* @param {string=} sourceMapURL
* @param {boolean=} hasSourceURL
* @param {boolean=} deprecatedCommentWasUsed
*/
scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed)
{
this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, !!isContentScript, !!isInternalScript, false, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, true);
},
/**
* @override
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!DebuggerAgent.Location} location
*/
breakpointResolved: function(breakpointId, location)
{
this._debuggerModel._breakpointResolved(breakpointId, location);
}
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {string} scriptId
* @param {number} lineNumber
* @param {number=} columnNumber
*/
WebInspector.DebuggerModel.Location = function(debuggerModel, scriptId, lineNumber, columnNumber)
{
WebInspector.SDKObject.call(this, debuggerModel.target());
this._debuggerModel = debuggerModel;
this.scriptId = scriptId;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber || 0;
}
/**
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!DebuggerAgent.Location} payload
* @return {!WebInspector.DebuggerModel.Location}
*/
WebInspector.DebuggerModel.Location.fromPayload = function(debuggerModel, payload)
{
return new WebInspector.DebuggerModel.Location(debuggerModel, payload.scriptId, payload.lineNumber, payload.columnNumber);
}
WebInspector.DebuggerModel.Location.prototype = {
/**
* @return {!DebuggerAgent.Location}
*/
payload: function()
{
return { scriptId: this.scriptId, lineNumber: this.lineNumber, columnNumber: this.columnNumber };
},
/**
* @return {!WebInspector.Script}
*/
script: function()
{
return this._debuggerModel.scriptForId(this.scriptId);
},
continueToLocation: function()
{
this._debuggerModel._agent.continueToLocation(this.payload());
},
/**
* @return {string}
*/
id: function()
{
return this.target().id() + ":" + this.scriptId + ":" + this.lineNumber + ":" + this.columnNumber;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Script} script
* @param {!DebuggerAgent.CallFrame} payload
*/
WebInspector.DebuggerModel.CallFrame = function(debuggerModel, script, payload)
{
var target = debuggerModel.target();
WebInspector.SDKObject.call(this, target);
this.debuggerModel = debuggerModel;
this._debuggerAgent = debuggerModel._agent;
this._script = script;
this._payload = payload;
this._location = WebInspector.DebuggerModel.Location.fromPayload(debuggerModel, payload.location);
this._scopeChain = [];
this._localScope = null;
for (var i = 0; i < payload.scopeChain.length; ++i) {
var scope = new WebInspector.DebuggerModel.Scope(this, i);
this._scopeChain.push(scope);
if (scope.type() === DebuggerAgent.ScopeType.Local)
this._localScope = scope;
}
if (payload.functionLocation)
this._functionLocation = WebInspector.DebuggerModel.Location.fromPayload(debuggerModel, payload.functionLocation);
}
/**
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @return {!Array.<!WebInspector.DebuggerModel.CallFrame>}
*/
WebInspector.DebuggerModel.CallFrame.fromPayloadArray = function(debuggerModel, callFrames)
{
var result = [];
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
var script = debuggerModel.scriptForId(callFrame.location.scriptId);
if (script)
result.push(new WebInspector.DebuggerModel.CallFrame(debuggerModel, script, callFrame));
}
return result;
}
WebInspector.DebuggerModel.CallFrame.prototype = {
/**
* @return {!WebInspector.Script}
*/
get script()
{
return this._script;
},
/**
* @return {string}
*/
get id()
{
return this._payload.callFrameId;
},
/**
* @return {!Array.<!WebInspector.DebuggerModel.Scope>}
*/
scopeChain: function()
{
return this._scopeChain;
},
/**
* @return {?WebInspector.DebuggerModel.Scope}
*/
localScope: function()
{
return this._localScope;
},
/**
* @return {?WebInspector.RemoteObject}
*/
thisObject: function()
{
return this._payload.this ? this.target().runtimeModel.createRemoteObject(this._payload.this) : null;
},
/**
* @return {?WebInspector.RemoteObject}
*/
returnValue: function()
{
return this._payload.returnValue ? this.target().runtimeModel.createRemoteObject(this._payload.returnValue) : null;
},
/**
* @return {string}
*/
get functionName()
{
return this._payload.functionName;
},
/**
* @return {!WebInspector.DebuggerModel.Location}
*/
location: function()
{
return this._location;
},
/**
* @return {?WebInspector.DebuggerModel.Location}
*/
functionLocation: function()
{
return this._functionLocation || null;
},
/**
* @param {string} code
* @param {string} objectGroup
* @param {boolean} includeCommandLineAPI
* @param {boolean} doNotPauseOnExceptionsAndMuteConsole
* @param {boolean} returnByValue
* @param {boolean} generatePreview
* @param {function(?RuntimeAgent.RemoteObject, boolean=, ?RuntimeAgent.ExceptionDetails=)} callback
*/
evaluate: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
function didEvaluateOnCallFrame(error, result, wasThrown, exceptionDetails)
{
if (error) {
console.error(error);
callback(null, false);
return;
}
callback(result, wasThrown, exceptionDetails);
}
this._debuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluateOnCallFrame);
},
/**
* @param {function(?Protocol.Error=)=} callback
*/
restart: function(callback)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
* @this {WebInspector.DebuggerModel.CallFrame}
*/
function protocolCallback(error, callFrames, asyncStackTrace)
{
if (!error)
this.debuggerModel.stepInto();
if (callback)
callback(error);
}
this._debuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback.bind(this));
},
/**
* @param {function(!Object)} callback
*/
variableNames: function(callback)
{
var result = { this: true };
function propertiesCollected(properties)
{
for (var i = 0; properties && i < properties.length; ++i)
result[properties[i].name] = true;
if (--pendingRequests == 0)
callback(result);
}
var scopeChain = this.scopeChain();
var pendingRequests = scopeChain.length;
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var object = scope.object();
object.getAllProperties(false, propertiesCollected);
}
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @param {number} ordinal
*/
WebInspector.DebuggerModel.Scope = function(callFrame, ordinal)
{
this._callFrame = callFrame;
this._payload = callFrame._payload.scopeChain[ordinal];
this._type = this._payload.type;
this._name = this._payload.name;
this._ordinal = ordinal;
this._startLocation = this._payload.startLocation ? WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.startLocation) : null;
this._endLocation = this._payload.endLocation ? WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.endLocation) : null;
}
WebInspector.DebuggerModel.Scope.prototype = {
/**
* @return {string}
*/
type: function()
{
return this._type;
},
/**
* @return {string|undefined}
*/
name: function()
{
return this._name;
},
/**
* @return {?WebInspector.DebuggerModel.Location}
*/
startLocation: function()
{
return this._startLocation;
},
/**
* @return {?WebInspector.DebuggerModel.Location}
*/
endLocation: function()
{
return this._endLocation;
},
/**
* @return {!WebInspector.RemoteObject}
*/
object: function()
{
if (this._object)
return this._object;
var runtimeModel = this._callFrame.target().runtimeModel;
var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && this._type !== DebuggerAgent.ScopeType.Global;
if (declarativeScope)
this._object = runtimeModel.createScopeRemoteObject(this._payload.object, new WebInspector.ScopeRef(this._ordinal, this._callFrame.id));
else
this._object = runtimeModel.createRemoteObject(this._payload.object);
return this._object;
},
/**
* @return {string}
*/
description: function()
{
var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && this._type !== DebuggerAgent.ScopeType.Global;
return declarativeScope ? "" : (this._payload.object.description || "");
}
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @param {string} reason
* @param {!Object|undefined} auxData
* @param {!Array.<string>} breakpointIds
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
*/
WebInspector.DebuggerPausedDetails = function(debuggerModel, callFrames, reason, auxData, breakpointIds, asyncStackTrace)
{
WebInspector.SDKObject.call(this, debuggerModel.target());
this.debuggerModel = debuggerModel;
this.callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(debuggerModel, callFrames);
this.reason = reason;
this.auxData = auxData;
this.breakpointIds = breakpointIds;
this.asyncStackTrace = asyncStackTrace;
}
WebInspector.DebuggerPausedDetails.prototype = {
/**
* @return {?WebInspector.RemoteObject}
*/
exception: function()
{
if (this.reason !== WebInspector.DebuggerModel.BreakReason.Exception && this.reason !== WebInspector.DebuggerModel.BreakReason.PromiseRejection)
return null;
return this.target().runtimeModel.createRemoteObject(/** @type {!RuntimeAgent.RemoteObject} */(this.auxData));
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @return {!Array<!WebInspector.DebuggerModel>}
*/
WebInspector.DebuggerModel.instances = function()
{
var result = [];
for (var target of WebInspector.targetManager.targets()) {
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel)
result.push(debuggerModel);
}
return result;
}
/**
* @param {?WebInspector.Target} target
* @return {?WebInspector.DebuggerModel}
*/
WebInspector.DebuggerModel.fromTarget = function(target)
{
if (!target || !target.hasJSContext())
return null;
return /** @type {?WebInspector.DebuggerModel} */ (target.model(WebInspector.DebuggerModel));
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | 2 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// See http://www.softwareishard.com/blog/har-12-spec/
// for HAR specification.
// FIXME: Some fields are not yet supported due to back-end limitations.
// See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
/**
* @constructor
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.HAREntry = function(request)
{
this._request = request;
}
WebInspector.HAREntry.prototype = {
/**
* @return {!Object}
*/
build: function()
{
var ipAddress = this._request.remoteAddress();
var portPositionInString = ipAddress.lastIndexOf(":");
if (portPositionInString !== -1)
ipAddress = ipAddress.substr(0, portPositionInString);
var entry = {
startedDateTime: WebInspector.HARLog.pseudoWallTime(this._request, this._request.startTime),
time: this._request.timing ? WebInspector.HAREntry._toMilliseconds(this._request.duration) : 0,
request: this._buildRequest(),
response: this._buildResponse(),
cache: { }, // Not supported yet.
timings: this._buildTimings(),
serverIPAddress: ipAddress
};
if (this._request.connectionId !== "0")
entry.connection = this._request.connectionId;
var page = this._request.target().networkLog.pageLoadForRequest(this._request);
if (page)
entry.pageref = "page_" + page.id;
return entry;
},
/**
* @return {!Object}
*/
_buildRequest: function()
{
var headersText = this._request.requestHeadersText();
var res = {
method: this._request.requestMethod,
url: this._buildRequestURL(this._request.url),
httpVersion: this._request.requestHttpVersion(),
headers: this._request.requestHeaders(),
queryString: this._buildParameters(this._request.queryParameters || []),
cookies: this._buildCookies(this._request.requestCookies || []),
headersSize: headersText ? headersText.length : -1,
bodySize: this.requestBodySize
};
if (this._request.requestFormData)
res.postData = this._buildPostData();
return res;
},
/**
* @return {!Object}
*/
_buildResponse: function()
{
var headersText = this._request.responseHeadersText;
return {
status: this._request.statusCode,
statusText: this._request.statusText,
httpVersion: this._request.responseHttpVersion(),
headers: this._request.responseHeaders,
cookies: this._buildCookies(this._request.responseCookies || []),
content: this._buildContent(),
redirectURL: this._request.responseHeaderValue("Location") || "",
headersSize: headersText ? headersText.length : -1,
bodySize: this.responseBodySize,
_transferSize: this._request.transferSize,
_error: this._request.localizedFailDescription
};
},
/**
* @return {!Object}
*/
_buildContent: function()
{
var content = {
size: this._request.resourceSize,
mimeType: this._request.mimeType || "x-unknown",
// text: this._request.content // TODO: pull out into a boolean flag, as content can be huge (and needs to be requested with an async call)
};
var compression = this.responseCompression;
if (typeof compression === "number")
content.compression = compression;
return content;
},
/**
* @return {!Object}
*/
_buildTimings: function()
{
// Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], receive_headers_end
// HAR 'blocked' time is time before first network activity.
var timing = this._request.timing;
if (!timing)
return {blocked: -1, dns: -1, connect: -1, send: 0, wait: 0, receive: 0, ssl: -1};
function firstNonNegative(values)
{
for (var i = 0; i < values.length; ++i) {
if (values[i] >= 0)
return values[i];
}
console.assert(false, "Incomplete request timing information.");
}
var blocked = firstNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart]);
var dns = -1;
if (timing.dnsStart >= 0)
dns = firstNonNegative([timing.connectStart, timing.sendStart]) - timing.dnsStart;
var connect = -1;
if (timing.connectStart >= 0)
connect = timing.sendStart - timing.connectStart;
var send = timing.sendEnd - timing.sendStart;
var wait = timing.receiveHeadersEnd - timing.sendEnd;
var receive = WebInspector.HAREntry._toMilliseconds(this._request.duration) - timing.receiveHeadersEnd;
var ssl = -1;
if (timing.sslStart >= 0 && timing.sslEnd >= 0)
ssl = timing.sslEnd - timing.sslStart;
return {blocked: blocked, dns: dns, connect: connect, send: send, wait: wait, receive: receive, ssl: ssl};
},
/**
* @return {!Object}
*/
_buildPostData: function()
{
var res = {
mimeType: this._request.requestContentType(),
text: this._request.requestFormData
};
if (this._request.formParameters)
res.params = this._buildParameters(this._request.formParameters);
return res;
},
/**
* @param {!Array.<!Object>} parameters
* @return {!Array.<!Object>}
*/
_buildParameters: function(parameters)
{
return parameters.slice();
},
/**
* @param {string} url
* @return {string}
*/
_buildRequestURL: function(url)
{
return url.split("#", 2)[0];
},
/**
* @param {!Array.<!WebInspector.Cookie>} cookies
* @return {!Array.<!Object>}
*/
_buildCookies: function(cookies)
{
return cookies.map(this._buildCookie.bind(this));
},
/**
* @param {!WebInspector.Cookie} cookie
* @return {!Object}
*/
_buildCookie: function(cookie)
{
var c = {
name: cookie.name(),
value: cookie.value(),
path: cookie.path(),
domain: cookie.domain(),
expires: cookie.expiresDate(WebInspector.HARLog.pseudoWallTime(this._request, this._request.startTime)),
httpOnly: cookie.httpOnly(),
secure: cookie.secure()
};
if (cookie.sameSite())
c.sameSite = cookie.sameSite();
return c;
},
/**
* @return {number}
*/
get requestBodySize()
{
return !this._request.requestFormData ? 0 : this._request.requestFormData.length;
},
/**
* @return {number}
*/
get responseBodySize()
{
if (this._request.cached() || this._request.statusCode === 304)
return 0;
if (!this._request.responseHeadersText)
return -1;
return this._request.transferSize - this._request.responseHeadersText.length;
},
/**
* @return {number|undefined}
*/
get responseCompression()
{
if (this._request.cached() || this._request.statusCode === 304 || this._request.statusCode === 206)
return;
if (!this._request.responseHeadersText)
return;
return this._request.resourceSize - this.responseBodySize;
}
}
/**
* @param {number} time
* @return {number}
*/
WebInspector.HAREntry._toMilliseconds = function(time)
{
return time === -1 ? -1 : time * 1000;
}
/**
* @constructor
* @param {!Array.<!WebInspector.NetworkRequest>} requests
*/
WebInspector.HARLog = function(requests)
{
this._requests = requests;
}
/**
* @param {!WebInspector.NetworkRequest} request
* @param {number} monotonicTime
* @return {!Date}
*/
WebInspector.HARLog.pseudoWallTime = function(request, monotonicTime)
{
return new Date(request.pseudoWallTime(monotonicTime) * 1000);
}
WebInspector.HARLog.prototype = {
/**
* @return {!Object}
*/
build: function()
{
return {
version: "1.2",
creator: this._creator(),
pages: this._buildPages(),
entries: this._requests.map(this._convertResource.bind(this))
}
},
_creator: function()
{
var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);
return {
name: "WebInspector",
version: webKitVersion ? webKitVersion[1] : "n/a"
};
},
/**
* @return {!Array.<!Object>}
*/
_buildPages: function()
{
var seenIdentifiers = {};
var pages = [];
for (var i = 0; i < this._requests.length; ++i) {
var request = this._requests[i];
var page = request.target().networkLog.pageLoadForRequest(request);
if (!page || seenIdentifiers[page.id])
continue;
seenIdentifiers[page.id] = true;
pages.push(this._convertPage(page, request));
}
return pages;
},
/**
* @param {!WebInspector.PageLoad} page
* @param {!WebInspector.NetworkRequest} request
* @return {!Object}
*/
_convertPage: function(page, request)
{
return {
startedDateTime: WebInspector.HARLog.pseudoWallTime(request, page.startTime),
id: "page_" + page.id,
title: page.url, // We don't have actual page title here. URL is probably better than nothing.
pageTimings: {
onContentLoad: this._pageEventTime(page, page.contentLoadTime),
onLoad: this._pageEventTime(page, page.loadTime)
}
}
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!Object}
*/
_convertResource: function(request)
{
return (new WebInspector.HAREntry(request)).build();
},
/**
* @param {!WebInspector.PageLoad} page
* @param {number} time
* @return {number}
*/
_pageEventTime: function(page, time)
{
var startTime = page.startTime;
if (time === -1 || startTime === -1)
return -1;
return WebInspector.HAREntry._toMilliseconds(time - startTime);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 2 | /**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.HeapProfilerModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.HeapProfilerModel, target);
target.registerHeapProfilerDispatcher(new WebInspector.HeapProfilerDispatcher(this));
this._enabled = false;
this._heapProfilerAgent = target.heapProfilerAgent();
}
WebInspector.HeapProfilerModel.Events = {
HeapStatsUpdate: "HeapStatsUpdate",
LastSeenObjectId: "LastSeenObjectId",
AddHeapSnapshotChunk: "AddHeapSnapshotChunk",
ReportHeapSnapshotProgress: "ReportHeapSnapshotProgress",
ResetProfiles: "ResetProfiles"
}
WebInspector.HeapProfilerModel.prototype = {
enable: function()
{
if (this._enabled)
return;
this._enabled = true;
this._heapProfilerAgent.enable();
},
/**
* @param {!Array.<number>} samples
*/
heapStatsUpdate: function(samples)
{
this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, samples);
},
/**
* @param {number} lastSeenObjectId
* @param {number} timestamp
*/
lastSeenObjectId: function(lastSeenObjectId, timestamp)
{
this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.LastSeenObjectId ,{lastSeenObjectId: lastSeenObjectId, timestamp: timestamp});
},
/**
* @param {string} chunk
*/
addHeapSnapshotChunk: function(chunk)
{
this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk, chunk);
},
/**
* @param {number} done
* @param {number} total
* @param {boolean=} finished
*/
reportHeapSnapshotProgress: function(done, total, finished)
{
this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress, {done: done, total: total, finished: finished});
},
resetProfiles: function()
{
this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.ResetProfiles);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {HeapProfilerAgent.Dispatcher}
*/
WebInspector.HeapProfilerDispatcher = function(model)
{
this._heapProfilerModel = model;
}
WebInspector.HeapProfilerDispatcher.prototype = {
/**
* @override
* @param {!Array.<number>} samples
*/
heapStatsUpdate: function(samples)
{
this._heapProfilerModel.heapStatsUpdate(samples);
},
/**
* @override
* @param {number} lastSeenObjectId
* @param {number} timestamp
*/
lastSeenObjectId: function(lastSeenObjectId, timestamp)
{
this._heapProfilerModel.lastSeenObjectId(lastSeenObjectId, timestamp);
},
/**
* @override
* @param {string} chunk
*/
addHeapSnapshotChunk: function(chunk)
{
this._heapProfilerModel.addHeapSnapshotChunk(chunk);
},
/**
* @override
* @param {number} done
* @param {number} total
* @param {boolean=} finished
*/
reportHeapSnapshotProgress: function(done, total, finished)
{
this._heapProfilerModel.reportHeapSnapshotProgress(done, total, finished);
},
/**
* @override
*/
resetProfiles: function()
{
this._heapProfilerModel.resetProfiles();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1 1 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ function InspectorBackendClass() { this._agentPrototypes = {}; this._dispatcherPrototypes = {}; this._initialized = false; this._initProtocolAgentsConstructor(); } InspectorBackendClass._DevToolsErrorCode = -32000; InspectorBackendClass.DevToolsStubErrorCode = -32015; /** * @param {string} error * @param {!Object} messageObject */ InspectorBackendClass.reportProtocolError = function(error, messageObject) { console.error(error + ": " + JSON.stringify(messageObject)); } InspectorBackendClass.prototype = { /** * @return {boolean} */ isInitialized: function() { return this._initialized; }, _initProtocolAgentsConstructor: function() { window.Protocol = {}; /** * @constructor * @param {!Object.<string, !Object>} agentsMap */ window.Protocol.Agents = function(agentsMap) { this._agentsMap = agentsMap; }; }, /** * @param {string} domain */ _addAgentGetterMethodToProtocolAgentsPrototype: function(domain) { var upperCaseLength = 0; while (upperCaseLength < domain.length && domain[upperCaseLength].toLowerCase() !== domain[upperCaseLength]) ++upperCaseLength; var methodName = domain.substr(0, upperCaseLength).toLowerCase() + domain.slice(upperCaseLength) + "Agent"; /** * @this {Protocol.Agents} */ function agentGetter() { return this._agentsMap[domain]; } window.Protocol.Agents.prototype[methodName] = agentGetter; /** * @this {Protocol.Agents} */ function registerDispatcher(dispatcher) { this.registerDispatcher(domain, dispatcher) } window.Protocol.Agents.prototype["register" + domain + "Dispatcher"] = registerDispatcher; }, /** * @param {string} domain * @return {!InspectorBackendClass.AgentPrototype} */ _agentPrototype: function(domain) { if (!this._agentPrototypes[domain]) { this._agentPrototypes[domain] = new InspectorBackendClass.AgentPrototype(domain); this._addAgentGetterMethodToProtocolAgentsPrototype(domain); } return this._agentPrototypes[domain]; }, /** * @param {string} domain * @return {!InspectorBackendClass.DispatcherPrototype} */ _dispatcherPrototype: function(domain) { if (!this._dispatcherPrototypes[domain]) this._dispatcherPrototypes[domain] = new InspectorBackendClass.DispatcherPrototype(); return this._dispatcherPrototypes[domain]; }, /** * @param {string} method * @param {!Array.<!Object>} signature * @param {!Array.<string>} replyArgs * @param {boolean} hasErrorData */ registerCommand: function(method, signature, replyArgs, hasErrorData) { var domainAndMethod = method.split("."); this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1], signature, replyArgs, hasErrorData); this._initialized = true; }, /** * @param {string} type * @param {!Object} values */ registerEnum: function(type, values) { var domainAndMethod = type.split("."); var agentName = domainAndMethod[0] + "Agent"; if (!window[agentName]) window[agentName] = {}; window[agentName][domainAndMethod[1]] = values; this._initialized = true; }, /** * @param {string} eventName * @param {!Object} params */ registerEvent: function(eventName, params) { var domain = eventName.split(".")[0]; this._dispatcherPrototype(domain).registerEvent(eventName, params); this._initialized = true; }, /** * @param {function(T)} clientCallback * @param {string} errorPrefix * @param {function(new:T,S)=} constructor * @param {T=} defaultValue * @return {function(?string, S)} * @template T,S */ wrapClientCallback: function(clientCallback, errorPrefix, constructor, defaultValue) { /** * @param {?string} error * @param {S} value * @template S */ function callbackWrapper(error, value) { if (error) { console.error(errorPrefix + error); clientCallback(defaultValue); return; } if (constructor) clientCallback(new constructor(value)); else clientCallback(value); } return callbackWrapper; } } /** * @constructor * @extends {WebInspector.Object} */ InspectorBackendClass.Connection = function() { this._lastMessageId = 1; this._pendingResponsesCount = 0; this._agents = {}; this._dispatchers = {}; this._callbacks = {}; this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispatcherPrototypes); this._isConnected = true; } InspectorBackendClass.Connection.Events = { Disconnected: "Disconnected", } InspectorBackendClass.Connection.prototype = { /** * @param {!Object.<string, !InspectorBackendClass.AgentPrototype>} agentPrototypes * @param {!Object.<string, !InspectorBackendClass.DispatcherPrototype>} dispatcherPrototypes */ _initialize: function(agentPrototypes, dispatcherPrototypes) { for (var domain in agentPrototypes) { this._agents[domain] = Object.create(agentPrototypes[domain]); this._agents[domain].setConnection(this); } for (var domain in dispatcherPrototypes) this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain]); }, /** * @return {number} */ nextMessageId: function() { return this._lastMessageId++; }, /** * @param {string} domain * @return {!InspectorBackendClass.AgentPrototype} */ agent: function(domain) { return this._agents[domain]; }, /** * @return {!Object.<string, !Object>} */ agentsMap: function() { return this._agents; }, /** * @param {string} domain * @param {string} method * @param {?Object} params * @param {?function(*)} callback */ _wrapCallbackAndSendMessageObject: function(domain, method, params, callback) { if (!this._isConnected && callback) { this._dispatchConnectionErrorResponse(domain, method, callback); return; } var messageObject = {}; var messageId = this.nextMessageId(); messageObject.id = messageId; messageObject.method = method; if (params) messageObject.params = params; var wrappedCallback = this._wrap(callback, domain, method); if (InspectorBackendClass.Options.dumpInspectorProtocolMessages) this._dumpProtocolMessage("frontend: " + JSON.stringify(messageObject)); this.sendMessage(messageObject); ++this._pendingResponsesCount; this._callbacks[messageId] = wrappedCallback; }, /** * @param {?function(*)} callback * @param {string} method * @param {string} domain * @return {function(*)} */ _wrap: function(callback, domain, method) { if (!callback) callback = function() {}; callback.methodName = method; callback.domain = domain; if (InspectorBackendClass.Options.dumpInspectorTimeStats) callback.sendRequestTime = Date.now(); return callback; }, /** * @param {!Object} messageObject */ sendMessage: function(messageObject) { throw "Not implemented"; }, /** * @param {!Object|string} message */ dispatch: function(message) { if (InspectorBackendClass.Options.dumpInspectorProtocolMessages) this._dumpProtocolMessage("backend: " + ((typeof message === "string") ? message : JSON.stringify(message))); var messageObject = /** @type {!Object} */ ((typeof message === "string") ? JSON.parse(message) : message); if ("id" in messageObject) { // just a response for some request var callback = this._callbacks[messageObject.id]; if (!callback) { InspectorBackendClass.reportProtocolError("Protocol Error: the message with wrong id", messageObject); return; } var processingStartTime; if (InspectorBackendClass.Options.dumpInspectorTimeStats) processingStartTime = Date.now(); this.agent(callback.domain).dispatchResponse(messageObject, callback.methodName, callback); --this._pendingResponsesCount; delete this._callbacks[messageObject.id]; if (InspectorBackendClass.Options.dumpInspectorTimeStats) console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime)); if (this._scripts && !this._pendingResponsesCount) this.runAfterPendingDispatches(); return; } else { var method = messageObject.method.split("."); var domainName = method[0]; if (!(domainName in this._dispatchers)) { InspectorBackendClass.reportProtocolError("Protocol Error: the message " + messageObject.method + " is for non-existing domain '" + domainName + "'", messageObject); return; } this._dispatchers[domainName].dispatch(method[1], messageObject); } }, /** * @param {string} domain * @param {!Object} dispatcher */ registerDispatcher: function(domain, dispatcher) { if (!this._dispatchers[domain]) return; this._dispatchers[domain].setDomainDispatcher(dispatcher); }, /** * @param {function()=} script */ runAfterPendingDispatches: function(script) { if (!this._scripts) this._scripts = []; if (script) this._scripts.push(script); // Execute all promises. setTimeout(function() { if (!this._pendingResponsesCount) this._executeAfterPendingDispatches(); else this.runAfterPendingDispatches(); }.bind(this), 0); }, _executeAfterPendingDispatches: function() { if (!this._pendingResponsesCount) { var scripts = this._scripts; this._scripts = []; for (var id = 0; id < scripts.length; ++id) scripts[id].call(this); } }, _dumpProtocolMessage: function(message) { console.log(message); }, /** * @protected * @param {string} reason */ connectionClosed: function(reason) { this._isConnected = false; this._runPendingCallbacks(); this.dispatchEventToListeners(InspectorBackendClass.Connection.Events.Disconnected, {reason: reason}); }, _runPendingCallbacks: function() { var keys = Object.keys(this._callbacks).map(function(num) { return parseInt(num, 10); }); for (var i = 0; i < keys.length; ++i) { var callback = this._callbacks[keys[i]]; this._dispatchConnectionErrorResponse(callback.domain, callback.methodName, callback); } this._callbacks = {}; }, /** * @param {string} domain * @param {string} methodName * @param {function(*)} callback */ _dispatchConnectionErrorResponse: function(domain, methodName, callback) { var error = { message: "Connection is closed, can't dispatch pending " + methodName, code: InspectorBackendClass._DevToolsErrorCode, data: null}; var messageObject = {error: error}; setTimeout(InspectorBackendClass.AgentPrototype.prototype.dispatchResponse.bind(this.agent(domain), messageObject, methodName, callback), 0); }, /** * @return {boolean} */ isClosed: function() { return !this._isConnected; }, /** * @param {!Array.<string>} domains */ suppressErrorsForDomains: function(domains) { domains.forEach(function(domain) { this._agents[domain].suppressErrorLogging(); }, this); }, __proto__: WebInspector.Object.prototype } /** * @constructor * @param {string} domain */ InspectorBackendClass.AgentPrototype = function(domain) { this._replyArgs = {}; this._hasErrorData = {}; this._domain = domain; this._suppressErrorLogging = false; } InspectorBackendClass.AgentPrototype.prototype = { /** * @param {!InspectorBackendClass.Connection} connection */ setConnection: function(connection) { this._connection = connection; }, /** * @param {string} methodName * @param {!Array.<!Object>} signature * @param {!Array.<string>} replyArgs * @param {boolean} hasErrorData */ registerCommand: function(methodName, signature, replyArgs, hasErrorData) { var domainAndMethod = this._domain + "." + methodName; /** * @param {...*} vararg * @this {InspectorBackendClass.AgentPrototype} * @return {!Promise.<*>} */ function sendMessagePromise(vararg) { var params = Array.prototype.slice.call(arguments); return InspectorBackendClass.AgentPrototype.prototype._sendMessageToBackendPromise.call(this, domainAndMethod, signature, params); } this[methodName] = sendMessagePromise; /** * @param {...*} vararg * @this {InspectorBackendClass.AgentPrototype} */ function invoke(vararg) { var params = [domainAndMethod].concat(Array.prototype.slice.call(arguments)); InspectorBackendClass.AgentPrototype.prototype._invoke.apply(this, params); } this["invoke_" + methodName] = invoke; this._replyArgs[domainAndMethod] = replyArgs; if (hasErrorData) this._hasErrorData[domainAndMethod] = true; }, /** * @param {string} method * @param {!Array.<!Object>} signature * @param {!Array.<*>} args * @param {boolean} allowExtraUndefinedArg * @param {function(string)} errorCallback * @return {?Object} */ _prepareParameters: function(method, signature, args, allowExtraUndefinedArg, errorCallback) { var params = {}; var hasParams = false; for (var i = 0; i < signature.length; ++i) { var param = signature[i]; var paramName = param["name"]; var typeName = param["type"]; var optionalFlag = param["optional"]; if (!args.length && !optionalFlag) { errorCallback("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'."); return null; } var value = args.shift(); if (optionalFlag && typeof value === "undefined") continue; if (typeof value !== typeName) { errorCallback("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'."); return null; } params[paramName] = value; hasParams = true; } if (args.length === 1 && (!allowExtraUndefinedArg || (typeof args[0] !== "undefined"))) { errorCallback("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'."); return null; } if (args.length > 1) { errorCallback("Protocol Error: Extra " + args.length + " arguments in a call to method '" + method + "'."); return null; } return hasParams ? params : null }, /** * @param {string} method * @param {!Array.<!Object>} signature * @param {!Array.<*>} args * @return {!Promise.<*>} */ _sendMessageToBackendPromise: function(method, signature, args) { var errorMessage; /** * @param {string} message */ function onError(message) { console.error(message); errorMessage = message; } var userCallback = (args.length && typeof args.peekLast() === "function") ? args.pop() : null; var params = this._prepareParameters(method, signature, args, !userCallback, onError); if (errorMessage) return Promise.reject(new Error(errorMessage)); else return new Promise(promiseAction.bind(this)); /** * @param {function(?)} resolve * @param {function(!Error)} reject * @this {InspectorBackendClass.AgentPrototype} */ function promiseAction(resolve, reject) { /** * @param {...*} vararg */ function callback(vararg) { var result = userCallback ? userCallback.apply(null, arguments) : undefined; resolve(result); } this._connection._wrapCallbackAndSendMessageObject(this._domain, method, params, callback); } }, /** * @param {string} method * @param {?Object} args * @param {?function(*)} callback */ _invoke: function(method, args, callback) { this._connection._wrapCallbackAndSendMessageObject(this._domain, method, args, callback); }, /** * @param {!Object} messageObject * @param {string} methodName * @param {function(*)|function(?Protocol.Error, ?Object)} callback */ dispatchResponse: function(messageObject, methodName, callback) { if (messageObject.error && messageObject.error.code !== InspectorBackendClass._DevToolsErrorCode && messageObject.error.code !== InspectorBackendClass.DevToolsStubErrorCode && !InspectorBackendClass.Options.suppressRequestErrors && !this._suppressErrorLogging) { var id = InspectorBackendClass.Options.dumpInspectorProtocolMessages ? " with id = " + messageObject.id : ""; console.error("Request " + methodName + id + " failed. " + JSON.stringify(messageObject.error)); } var argumentsArray = []; argumentsArray[0] = messageObject.error ? messageObject.error.message: null; if (this._hasErrorData[methodName]) argumentsArray[1] = messageObject.error ? messageObject.error.data : null; if (messageObject.result) { var paramNames = this._replyArgs[methodName] || []; for (var i = 0; i < paramNames.length; ++i) argumentsArray.push(messageObject.result[paramNames[i]]); } callback.apply(null, argumentsArray); }, suppressErrorLogging: function() { this._suppressErrorLogging = true; } } /** * @constructor */ InspectorBackendClass.DispatcherPrototype = function() { this._eventArgs = {}; this._dispatcher = null; } InspectorBackendClass.DispatcherPrototype.prototype = { /** * @param {string} eventName * @param {!Object} params */ registerEvent: function(eventName, params) { this._eventArgs[eventName] = params; }, /** * @param {!Object} dispatcher */ setDomainDispatcher: function(dispatcher) { this._dispatcher = dispatcher; }, /** * @param {string} functionName * @param {!Object} messageObject */ dispatch: function(functionName, messageObject) { if (!this._dispatcher) return; if (!(functionName in this._dispatcher)) { InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'", messageObject); return; } if (!this._eventArgs[messageObject.method]) { InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'", messageObject); return; } var params = []; if (messageObject.params) { var paramNames = this._eventArgs[messageObject.method]; for (var i = 0; i < paramNames.length; ++i) params.push(messageObject.params[paramNames[i]]); } var processingStartTime; if (InspectorBackendClass.Options.dumpInspectorTimeStats) processingStartTime = Date.now(); this._dispatcher[functionName].apply(this._dispatcher, params); if (InspectorBackendClass.Options.dumpInspectorTimeStats) console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime)); } } InspectorBackendClass.Options = { dumpInspectorTimeStats: false, dumpInspectorProtocolMessages: false, suppressRequestErrors: false } InspectorBackend = new InspectorBackendClass(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//This should be executed immediately after InspectorBackend and InspectorBackendCommands
WebInspector.InspectorBackendHostedMode = {};
/**
* @param {string} jsonUrl
*/
WebInspector.InspectorBackendHostedMode.loadFromJSONIfNeeded = function(jsonUrl)
{
if (InspectorBackend.isInitialized())
return;
var xhr = new XMLHttpRequest();
xhr.open("GET", jsonUrl, false);
xhr.send(null);
var schema = JSON.parse(xhr.responseText);
var code = WebInspector.InspectorBackendHostedMode.generateCommands(schema);
eval(code);
}
/**
* @param {*} schema
* @return {string}
*/
WebInspector.InspectorBackendHostedMode.generateCommands = function(schema)
{
var jsTypes = { integer: "number", array: "object" };
var rawTypes = {};
var result = [];
var domains = schema["domains"] || [];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
for (var j = 0; domain.types && j < domain.types.length; ++j) {
var type = domain.types[j];
rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
}
}
function toUpperCase(groupIndex, group0, group1)
{
return [group0, group1][groupIndex].toUpperCase();
}
function generateEnum(enumName, items)
{
var members = [];
for (var m = 0; m < items.length; ++m) {
var value = items[m];
var name = value.replace(/-(\w)/g, toUpperCase.bind(null, 1)).toTitleCase();
name = name.replace(/HTML|XML|WML|API/ig, toUpperCase.bind(null, 0));
members.push(name + ": \"" + value +"\"");
}
return "InspectorBackend.registerEnum(\"" + enumName + "\", {" + members.join(", ") + "});";
}
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
var types = domain["types"] || [];
for (var j = 0; j < types.length; ++j) {
var type = types[j];
if ((type["type"] === "string") && type["enum"])
result.push(generateEnum(domain.domain + "." + type.id, type["enum"]));
else if (type["type"] === "object") {
var properties = type["properties"] || [];
for (var k = 0; k < properties.length; ++k) {
var property = properties[k];
if ((property["type"] === "string") && property["enum"])
result.push(generateEnum(domain.domain + "." + type.id + property["name"].toTitleCase(), property["enum"]));
}
}
}
var commands = domain["commands"] || [];
for (var j = 0; j < commands.length; ++j) {
var command = commands[j];
var parameters = command["parameters"];
var paramsText = [];
for (var k = 0; parameters && k < parameters.length; ++k) {
var parameter = parameters[k];
var type;
if (parameter.type)
type = jsTypes[parameter.type] || parameter.type;
else {
var ref = parameter["$ref"];
if (ref.indexOf(".") !== -1)
type = rawTypes[ref];
else
type = rawTypes[domain.domain + "." + ref];
}
var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
paramsText.push(text);
}
var returnsText = [];
var returns = command["returns"] || [];
for (var k = 0; k < returns.length; ++k) {
var parameter = returns[k];
returnsText.push("\"" + parameter.name + "\"");
}
var hasErrorData = String(Boolean(command.error));
result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "], " + hasErrorData + ");");
}
for (var j = 0; domain.events && j < domain.events.length; ++j) {
var event = domain.events[j];
var paramsText = [];
for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
var parameter = event.parameters[k];
paramsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
}
}
return result.join("\n");
}
WebInspector.InspectorBackendHostedMode.loadFromJSONIfNeeded("../protocol.json");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
*/
WebInspector.NetworkLog = function(target)
{
WebInspector.SDKObject.call(this, target);
this._requests = [];
this._requestForId = {};
target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._onLoad, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
}
/**
* @param {string} url
* @return {?WebInspector.NetworkRequest}
*/
WebInspector.NetworkLog.requestForURL = function(url)
{
for (var target of WebInspector.targetManager.targets()) {
var result = target.networkLog.requestForURL(url);
if (result)
return result;
}
return null;
}
/**
* @return {!Array.<!WebInspector.NetworkRequest>}
*/
WebInspector.NetworkLog.requests = function()
{
var result = [];
for (var target of WebInspector.targetManager.targets()) {
result = result.concat(target.networkLog.requests());
}
return result;
}
WebInspector.NetworkLog.prototype = {
/**
* @return {!Array.<!WebInspector.NetworkRequest>}
*/
requests: function()
{
return this._requests;
},
/**
* @param {string} url
* @return {?WebInspector.NetworkRequest}
*/
requestForURL: function(url)
{
for (var i = 0; i < this._requests.length; ++i) {
if (this._requests[i].url === url)
return this._requests[i];
}
return null;
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!WebInspector.PageLoad}
*/
pageLoadForRequest: function(request)
{
return request.__page;
},
/**
* @param {!WebInspector.Event} event
*/
_onMainFrameNavigated: function(event)
{
var mainFrame = /** type {WebInspector.ResourceTreeFrame} */ event.data;
// Preserve requests from the new session.
this._currentPageLoad = null;
var oldRequests = this._requests.splice(0, this._requests.length);
this._requestForId = {};
for (var i = 0; i < oldRequests.length; ++i) {
var request = oldRequests[i];
if (request.loaderId === mainFrame.loaderId) {
if (!this._currentPageLoad)
this._currentPageLoad = new WebInspector.PageLoad(request);
this._requests.push(request);
this._requestForId[request.requestId] = request;
request.__page = this._currentPageLoad;
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestStarted: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._requests.push(request);
this._requestForId[request.requestId] = request;
request.__page = this._currentPageLoad;
},
/**
* @param {!WebInspector.Event} event
*/
_onDOMContentLoaded: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.contentLoadTime = event.data;
},
/**
* @param {!WebInspector.Event} event
*/
_onLoad: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.loadTime = event.data;
},
/**
* @param {!NetworkAgent.RequestId} requestId
* @return {?WebInspector.NetworkRequest}
*/
requestForId: function(requestId)
{
return this._requestForId[requestId];
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @param {!WebInspector.NetworkRequest} mainRequest
*/
WebInspector.PageLoad = function(mainRequest)
{
this.id = ++WebInspector.PageLoad._lastIdentifier;
this.url = mainRequest.url;
this.startTime = mainRequest.startTime;
}
WebInspector.PageLoad._lastIdentifier = 0;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | 2 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.NetworkManager = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.NetworkManager, target);
this._dispatcher = new WebInspector.NetworkDispatcher(this);
this._target = target;
this._networkAgent = target.networkAgent();
target.registerNetworkDispatcher(this._dispatcher);
if (WebInspector.moduleSetting("cacheDisabled").get())
this._networkAgent.setCacheDisabled(true);
if (WebInspector.moduleSetting("monitoringXHREnabled").get())
this._networkAgent.setMonitoringXHREnabled(true);
// Limit buffer when talking to a remote device.
if (Runtime.queryParam("remoteFrontend") || Runtime.queryParam("ws"))
this._networkAgent.enable(10000000, 5000000);
else
this._networkAgent.enable();
/** @type {!Map<!NetworkAgent.CertificateId, !Promise<!NetworkAgent.CertificateDetails>>} */
this._certificateDetailsCache = new Map();
WebInspector.moduleSetting("cacheDisabled").addChangeListener(this._cacheDisabledSettingChanged, this);
}
WebInspector.NetworkManager.EventTypes = {
RequestStarted: "RequestStarted",
RequestUpdated: "RequestUpdated",
RequestFinished: "RequestFinished",
RequestUpdateDropped: "RequestUpdateDropped",
ResponseReceived: "ResponseReceived"
}
WebInspector.NetworkManager._MIMETypes = {
"text/html": {"document": true},
"text/xml": {"document": true},
"text/plain": {"document": true},
"application/xhtml+xml": {"document": true},
"image/svg+xml": {"document": true},
"text/css": {"stylesheet": true},
"text/xsl": {"stylesheet": true},
"text/vtt": {"texttrack": true},
}
/** @typedef {{download: number, upload: number, latency: number, title: string}} */
WebInspector.NetworkManager.Conditions;
/** @type {!WebInspector.NetworkManager.Conditions} */
WebInspector.NetworkManager.NoThrottlingConditions = {title: WebInspector.UIString("No throttling"), download: -1, upload: -1, latency: 0};
/** @type {!WebInspector.NetworkManager.Conditions} */
WebInspector.NetworkManager.OfflineConditions = {title: WebInspector.UIString("Offline"), download: 0, upload: 0, latency: 0};
WebInspector.NetworkManager.prototype = {
/**
* @param {string} url
* @return {!WebInspector.NetworkRequest}
*/
inflightRequestForURL: function(url)
{
return this._dispatcher._inflightRequestsByURL[url];
},
/**
* @param {!WebInspector.Event} event
*/
_cacheDisabledSettingChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
this._networkAgent.setCacheDisabled(enabled);
},
dispose: function()
{
WebInspector.moduleSetting("cacheDisabled").removeChangeListener(this._cacheDisabledSettingChanged, this);
},
/**
* @param {!NetworkAgent.CertificateId} certificateId
* @return {!Promise<!NetworkAgent.CertificateDetails>}
*/
certificateDetailsPromise: function(certificateId)
{
var cachedPromise = this._certificateDetailsCache.get(certificateId);
if (cachedPromise)
return cachedPromise;
/**
* @this {WebInspector.NetworkManager}
* @param {function(?NetworkAgent.CertificateDetails)} resolve
* @param {function()} reject
*/
function executor(resolve, reject) {
/**
* @param {?Protocol.Error} error
* @param {?NetworkAgent.CertificateDetails} certificateDetails
*/
function innerCallback(error, certificateDetails)
{
if (error) {
console.error("Unable to get certificate details from the browser (for certificate ID ", certificateId, "): ", error);
reject();
} else {
resolve(certificateDetails);
}
}
this._networkAgent.getCertificateDetails(certificateId, innerCallback);
}
var promise = new Promise(executor.bind(this));
this._certificateDetailsCache.set(certificateId, promise);
return promise;
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {NetworkAgent.Dispatcher}
*/
WebInspector.NetworkDispatcher = function(manager)
{
this._manager = manager;
this._inflightRequestsById = {};
this._inflightRequestsByURL = {};
}
WebInspector.NetworkDispatcher.prototype = {
/**
* @param {!NetworkAgent.Headers} headersMap
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
_headersMapToHeadersArray: function(headersMap)
{
var result = [];
for (var name in headersMap) {
var values = headersMap[name].split("\n");
for (var i = 0; i < values.length; ++i)
result.push({name: name, value: values[i]});
}
return result;
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
* @param {!NetworkAgent.Request} request
*/
_updateNetworkRequestWithRequest: function(networkRequest, request)
{
networkRequest.requestMethod = request.method;
networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
networkRequest.requestFormData = request.postData;
networkRequest.setInitialPriority(request.initialPriority);
networkRequest.mixedContentType = request.mixedContentType || NetworkAgent.RequestMixedContentType.None;
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
* @param {!NetworkAgent.Response=} response
*/
_updateNetworkRequestWithResponse: function(networkRequest, response)
{
if (response.url && networkRequest.url !== response.url)
networkRequest.url = response.url;
networkRequest.mimeType = response.mimeType;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
if (response.encodedDataLength >= 0)
networkRequest.setTransferSize(response.encodedDataLength);
if (response.headersText)
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders) {
networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
networkRequest.setRequestHeadersText(response.requestHeadersText || "");
}
networkRequest.connectionReused = response.connectionReused;
networkRequest.connectionId = String(response.connectionId);
if (response.remoteIPAddress)
networkRequest.setRemoteAddress(response.remoteIPAddress, response.remotePort || -1);
if (response.fromServiceWorker)
networkRequest.fetchedViaServiceWorker = true;
if (response.fromDiskCache)
networkRequest.setFromDiskCache();
networkRequest.timing = response.timing;
networkRequest.protocol = response.protocol;
networkRequest.setSecurityState(response.securityState);
if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
var consoleModel = this._manager._target.consoleModel;
consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(), WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Log,
WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.resourceType().title(), networkRequest.mimeType, networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
0,
networkRequest.requestId));
}
if (response.securityDetails)
networkRequest.setSecurityDetails(response.securityDetails);
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
* @return {boolean}
*/
_mimeTypeIsConsistentWithType: function(networkRequest)
{
// If status is an error, content is likely to be of an inconsistent type,
// as it's going to be an error message. We do not want to emit a warning
// for this, though, as this will already be reported as resource loading failure.
// Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,
// it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.
// Don't check for mime-types in 304-resources.
if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
return true;
var resourceType = networkRequest.resourceType();
if (resourceType !== WebInspector.resourceTypes.Stylesheet &&
resourceType !== WebInspector.resourceTypes.Document &&
resourceType !== WebInspector.resourceTypes.TextTrack) {
return true;
}
if (!networkRequest.mimeType)
return true; // Might be not known for cached resources with null responses.
if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
return resourceType.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];
return false;
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
* @param {string} documentURL
* @param {!NetworkAgent.Request} request
* @param {!NetworkAgent.Timestamp} time
* @param {!NetworkAgent.Timestamp} wallTime
* @param {!NetworkAgent.Initiator} initiator
* @param {!NetworkAgent.Response=} redirectResponse
* @param {!PageAgent.ResourceType=} resourceType
*/
requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, wallTime, initiator, redirectResponse, resourceType)
{
var networkRequest = this._inflightRequestsById[requestId];
if (networkRequest) {
// FIXME: move this check to the backend.
if (!redirectResponse)
return;
this.responseReceived(requestId, frameId, loaderId, time, PageAgent.ResourceType.Other, redirectResponse);
networkRequest = this._appendRedirect(requestId, time, request.url);
} else
networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
networkRequest.hasNetworkData = true;
this._updateNetworkRequestWithRequest(networkRequest, request);
networkRequest.setIssueTime(time, wallTime);
networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
this._startNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
*/
requestServedFromCache: function(requestId)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.setFromMemoryCache();
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
* @param {!NetworkAgent.Timestamp} time
* @param {!PageAgent.ResourceType} resourceType
* @param {!NetworkAgent.Response} response
*/
responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) {
// We missed the requestWillBeSent.
var eventData = {};
eventData.url = response.url;
eventData.frameId = frameId;
eventData.loaderId = loaderId;
eventData.resourceType = resourceType;
eventData.mimeType = response.mimeType;
this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
return;
}
networkRequest.responseReceivedTime = time;
networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
this._updateNetworkRequestWithResponse(networkRequest, response);
this._updateNetworkRequest(networkRequest);
this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResponseReceived, networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {number} dataLength
* @param {number} encodedDataLength
*/
dataReceived: function(requestId, time, dataLength, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.resourceSize += dataLength;
if (encodedDataLength != -1)
networkRequest.increaseTransferSize(encodedDataLength);
networkRequest.endTime = time;
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} finishTime
* @param {number} encodedDataLength
*/
loadingFinished: function(requestId, finishTime, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {!PageAgent.ResourceType} resourceType
* @param {string} localizedDescription
* @param {boolean=} canceled
* @param {!NetworkAgent.BlockedReason=} blockedReason
*/
loadingFailed: function(requestId, time, resourceType, localizedDescription, canceled, blockedReason)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.failed = true;
networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
networkRequest.canceled = canceled;
if (blockedReason) {
networkRequest.setBlockedReason(blockedReason);
if (blockedReason === NetworkAgent.BlockedReason.Inspector) {
var consoleModel = this._manager._target.consoleModel;
consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(), WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Warning,
WebInspector.UIString("Request was blocked by DevTools: \"%s\".", networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
0,
networkRequest.requestId));
}
}
networkRequest.localizedFailDescription = localizedDescription;
this._finishNetworkRequest(networkRequest, time, -1);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {string} requestURL
*/
webSocketCreated: function(requestId, requestURL)
{
// FIXME: WebSocket MUST have initiator info.
var networkRequest = new WebInspector.NetworkRequest(this._manager._target, requestId, requestURL, "", "", "", null);
networkRequest.setResourceType(WebInspector.resourceTypes.WebSocket);
this._startNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {!NetworkAgent.Timestamp} wallTime
* @param {!NetworkAgent.WebSocketRequest} request
*/
webSocketWillSendHandshakeRequest: function(requestId, time, wallTime, request)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.requestMethod = "GET";
networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
networkRequest.setIssueTime(time, wallTime);
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {!NetworkAgent.WebSocketResponse} response
*/
webSocketHandshakeResponseReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders)
networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
if (response.requestHeadersText)
networkRequest.setRequestHeadersText(response.requestHeadersText);
networkRequest.responseReceivedTime = time;
networkRequest.protocol = "websocket";
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {!NetworkAgent.WebSocketFrame} response
*/
webSocketFrameReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrame(response, time);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {!NetworkAgent.WebSocketFrame} response
*/
webSocketFrameSent: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrame(response, time, true);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {string} errorMessage
*/
webSocketFrameError: function(requestId, time, errorMessage)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrameError(errorMessage, time);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
*/
webSocketClosed: function(requestId, time)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, time, -1);
},
/**
* @override
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {string} eventName
* @param {string} eventId
* @param {string} data
*/
eventSourceMessageReceived: function(requestId, time, eventName, eventId, data)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addEventSourceMessage(time, eventName, eventId, data);
},
/**
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
* @param {string} redirectURL
* @return {!WebInspector.NetworkRequest}
*/
_appendRedirect: function(requestId, time, redirectURL)
{
var originalNetworkRequest = this._inflightRequestsById[requestId];
var previousRedirects = originalNetworkRequest.redirects || [];
originalNetworkRequest.requestId = requestId + ":redirected." + previousRedirects.length;
delete originalNetworkRequest.redirects;
if (previousRedirects.length > 0)
originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
this._finishNetworkRequest(originalNetworkRequest, time, -1);
var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator());
newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
return newNetworkRequest;
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
*/
_startNetworkRequest: function(networkRequest)
{
this._inflightRequestsById[networkRequest.requestId] = networkRequest;
this._inflightRequestsByURL[networkRequest.url] = networkRequest;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
*/
_updateNetworkRequest: function(networkRequest)
{
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
},
/**
* @param {!WebInspector.NetworkRequest} networkRequest
* @param {!NetworkAgent.Timestamp} finishTime
* @param {number} encodedDataLength
*/
_finishNetworkRequest: function(networkRequest, finishTime, encodedDataLength)
{
networkRequest.endTime = finishTime;
networkRequest.finished = true;
if (encodedDataLength >= 0)
networkRequest.setTransferSize(encodedDataLength);
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
delete this._inflightRequestsById[networkRequest.requestId];
delete this._inflightRequestsByURL[networkRequest.url];
},
/**
* @param {string} eventType
* @param {!WebInspector.NetworkRequest} networkRequest
*/
_dispatchEventToListeners: function(eventType, networkRequest)
{
this._manager.dispatchEventToListeners(eventType, networkRequest);
},
/**
* @param {!NetworkAgent.RequestId} requestId
* @param {string} frameId
* @param {!NetworkAgent.LoaderId} loaderId
* @param {string} url
* @param {string} documentURL
* @param {?NetworkAgent.Initiator} initiator
*/
_createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
{
return new WebInspector.NetworkRequest(this._manager._target, requestId, url, documentURL, frameId, loaderId, initiator);
}
}
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.MultitargetNetworkManager = function()
{
WebInspector.Object.call(this);
WebInspector.targetManager.observeTargets(this);
/** @type {!Set<string>} */
this._blockedURLs = new Set();
this._blockedSetting = WebInspector.moduleSetting("blockedURLs");
this._blockedSetting.addChangeListener(this._updateBlockedURLs, this);
this._blockedSetting.set([]);
this._updateBlockedURLs();
this._userAgentOverride = "";
/** @type {!Set<!Protocol.NetworkAgent>} */
this._agentsCapableOfEmulation = new Set();
/** @type {!WebInspector.NetworkManager.Conditions} */
this._networkConditions = WebInspector.NetworkManager.NoThrottlingConditions;
}
WebInspector.MultitargetNetworkManager.Events = {
ConditionsChanged: "ConditionsChanged",
UserAgentChanged: "UserAgentChanged"
}
WebInspector.MultitargetNetworkManager.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var networkAgent = target.networkAgent();
if (this._extraHeaders)
networkAgent.setExtraHTTPHeaders(this._extraHeaders);
if (this._currentUserAgent())
networkAgent.setUserAgentOverride(this._currentUserAgent());
for (var url of this._blockedURLs)
networkAgent.addBlockedURL(url);
networkAgent.canEmulateNetworkConditions(callback.bind(this));
/**
* @this {WebInspector.MultitargetNetworkManager}
*/
function callback(error, canEmulate)
{
if (error || !canEmulate)
return;
this._agentsCapableOfEmulation.add(networkAgent);
if (this.isThrottling())
this._updateNetworkConditions(networkAgent);
}
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
this._agentsCapableOfEmulation.delete(target.networkAgent());
},
/**
* @return {boolean}
*/
isThrottling: function()
{
return this._networkConditions.download >= 0 || this._networkConditions.upload >= 0 || this._networkConditions.latency > 0;
},
/**
* @return {boolean}
*/
isOffline: function()
{
return !this._networkConditions.download && !this._networkConditions.upload;
},
/**
* @param {!WebInspector.NetworkManager.Conditions} conditions
*/
setNetworkConditions: function(conditions)
{
this._networkConditions = conditions;
for (var agent of this._agentsCapableOfEmulation)
this._updateNetworkConditions(agent);
this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged);
},
/**
* @return {!WebInspector.NetworkManager.Conditions}
*/
networkConditions: function()
{
return this._networkConditions;
},
/**
* @param {!Protocol.NetworkAgent} networkAgent
*/
_updateNetworkConditions: function(networkAgent)
{
var conditions = this._networkConditions;
if (!this.isThrottling()) {
networkAgent.emulateNetworkConditions(false, 0, 0, 0);
} else {
networkAgent.emulateNetworkConditions(this.isOffline(), conditions.latency, conditions.download < 0 ? 0 : conditions.download, conditions.upload < 0 ? 0 : conditions.upload);
}
},
/**
* @param {!NetworkAgent.Headers} headers
*/
setExtraHTTPHeaders: function(headers)
{
this._extraHeaders = headers;
for (var target of WebInspector.targetManager.targets())
target.networkAgent().setExtraHTTPHeaders(this._extraHeaders);
},
/**
* @return {string}
*/
_currentUserAgent: function()
{
return this._customUserAgent ? this._customUserAgent : this._userAgentOverride;
},
_updateUserAgentOverride: function()
{
var userAgent = this._currentUserAgent();
WebInspector.ResourceLoader.targetUserAgent = userAgent;
for (var target of WebInspector.targetManager.targets())
target.networkAgent().setUserAgentOverride(userAgent);
},
/**
* @param {string} userAgent
*/
setUserAgentOverride: function(userAgent)
{
if (this._userAgentOverride === userAgent)
return;
this._userAgentOverride = userAgent;
if (!this._customUserAgent)
this._updateUserAgentOverride();
this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.UserAgentChanged);
},
/**
* @return {string}
*/
userAgentOverride: function()
{
return this._userAgentOverride;
},
/**
* @param {string} userAgent
*/
setCustomUserAgentOverride: function(userAgent)
{
this._customUserAgent = userAgent;
this._updateUserAgentOverride();
},
_updateBlockedURLs: function()
{
var blocked = this._blockedSetting.get();
for (var url of blocked) {
if (!this._blockedURLs.has(url))
this._addBlockedURL(url);
}
for (var url of this._blockedURLs) {
if (blocked.indexOf(url) === -1)
this._removeBlockedURL(url);
}
},
/**
* @param {string} url
*/
_addBlockedURL: function(url)
{
this._blockedURLs.add(url);
for (var target of WebInspector.targetManager.targets())
target.networkAgent().addBlockedURL(url);
},
/**
* @param {string} url
*/
_removeBlockedURL: function(url)
{
this._blockedURLs.delete(url);
for (var target of WebInspector.targetManager.targets())
target.networkAgent().removeBlockedURL(url);
},
clearBrowserCache: function()
{
for (var target of WebInspector.targetManager.targets())
target.networkAgent().clearBrowserCache();
},
clearBrowserCookies: function()
{
for (var target of WebInspector.targetManager.targets())
target.networkAgent().clearBrowserCookies();
},
/**
* @param {!NetworkAgent.CertificateId} certificateId
*/
showCertificateViewer: function(certificateId)
{
var target = WebInspector.targetManager.mainTarget();
if (target)
target.networkAgent().showCertificateViewer(certificateId);
},
/**
* @param {string} url
* @param {function(number, !Object.<string, string>, string)} callback
*/
loadResource: function(url, callback)
{
var headers = {};
var currentUserAgent = this._currentUserAgent();
if (currentUserAgent)
headers["User-Agent"] = currentUserAgent;
if (WebInspector.moduleSetting("cacheDisabled").get())
headers["Cache-Control"] = "no-cache";
WebInspector.ResourceLoader.load(url, headers, callback);
},
__proto__: WebInspector.Object.prototype
}
/**
* @type {!WebInspector.MultitargetNetworkManager}
*/
WebInspector.multitargetNetworkManager;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @implements {WebInspector.ContentProvider}
* @param {!NetworkAgent.RequestId} requestId
* @param {!WebInspector.Target} target
* @param {string} url
* @param {string} documentURL
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
* @param {?NetworkAgent.Initiator} initiator
*/
WebInspector.NetworkRequest = function(target, requestId, url, documentURL, frameId, loaderId, initiator)
{
WebInspector.SDKObject.call(this, target);
this._requestId = requestId;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
/** @type {?NetworkAgent.Initiator} */
this._initiator = initiator;
this._issueTime = -1;
this._startTime = -1;
this._endTime = -1;
/** @type {!NetworkAgent.BlockedReason|undefined} */
this._blockedReason = undefined;
this.statusCode = 0;
this.statusText = "";
this.requestMethod = "";
this.requestTime = 0;
this.protocol = "";
/** @type {!NetworkAgent.RequestMixedContentType} */
this.mixedContentType = NetworkAgent.RequestMixedContentType.None;
/** @type {?NetworkAgent.ResourcePriority} */
this._initialPriority = null;
/** @type {!WebInspector.ResourceType} */
this._resourceType = WebInspector.resourceTypes.Other;
this._contentEncoded = false;
this._pendingContentCallbacks = [];
/** @type {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>} */
this._frames = [];
/** @type {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>} */
this._eventSourceMessages = [];
this._responseHeaderValues = {};
this._remoteAddress = "";
/** @type {!SecurityAgent.SecurityState} */
this._securityState = SecurityAgent.SecurityState.Unknown;
/** @type {?NetworkAgent.SecurityDetails} */
this._securityDetails = null;
/** @type {string} */
this.connectionId = "0";
}
WebInspector.NetworkRequest.Events = {
FinishedLoading: "FinishedLoading",
TimingChanged: "TimingChanged",
RemoteAddressChanged: "RemoteAddressChanged",
RequestHeadersChanged: "RequestHeadersChanged",
ResponseHeadersChanged: "ResponseHeadersChanged",
WebsocketFrameAdded: "WebsocketFrameAdded",
EventSourceMessageAdded: "EventSourceMessageAdded",
}
/** @enum {string} */
WebInspector.NetworkRequest.InitiatorType = {
Other: "other",
Parser: "parser",
Redirect: "redirect",
Script: "script"
}
/** @typedef {!{name: string, value: string}} */
WebInspector.NetworkRequest.NameValue;
/** @enum {string} */
WebInspector.NetworkRequest.WebSocketFrameType = {
Send: "send",
Receive: "receive",
Error: "error"
}
/** @typedef {!{type: WebInspector.NetworkRequest.WebSocketFrameType, time: number, text: string, opCode: number, mask: boolean}} */
WebInspector.NetworkRequest.WebSocketFrame;
/** @typedef {!{time: number, eventName: string, eventId: string, data: string}} */
WebInspector.NetworkRequest.EventSourceMessage;
WebInspector.NetworkRequest.prototype = {
/**
* @param {!WebInspector.NetworkRequest} other
* @return {number}
*/
indentityCompare: function(other)
{
if (this._requestId > other._requestId)
return 1;
if (this._requestId < other._requestId)
return -1;
return 0;
},
/**
* @return {!NetworkAgent.RequestId}
*/
get requestId()
{
return this._requestId;
},
set requestId(requestId)
{
this._requestId = requestId;
},
/**
* @return {string}
*/
get url()
{
return this._url;
},
set url(x)
{
if (this._url === x)
return;
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
delete this._queryString;
delete this._parsedQueryParameters;
delete this._name;
delete this._path;
},
/**
* @return {string}
*/
get documentURL()
{
return this._documentURL;
},
get parsedURL()
{
return this._parsedURL;
},
/**
* @return {!PageAgent.FrameId}
*/
get frameId()
{
return this._frameId;
},
/**
* @return {!NetworkAgent.LoaderId}
*/
get loaderId()
{
return this._loaderId;
},
/**
* @param {string} ip
* @param {number} port
*/
setRemoteAddress: function(ip, port)
{
this._remoteAddress = ip + ":" + port;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this);
},
/**
* @return {string}
*/
remoteAddress: function()
{
return this._remoteAddress;
},
/**
* @return {!SecurityAgent.SecurityState}
*/
securityState: function()
{
return this._securityState;
},
/**
* @param {!SecurityAgent.SecurityState} securityState
*/
setSecurityState: function(securityState)
{
this._securityState = securityState;
},
/**
* @return {?NetworkAgent.SecurityDetails}
*/
securityDetails: function()
{
return this._securityDetails;
},
/**
* @param {!NetworkAgent.SecurityDetails} securityDetails
*/
setSecurityDetails: function(securityDetails)
{
this._securityDetails = securityDetails;
},
/**
* @return {number}
*/
get startTime()
{
return this._startTime || -1;
},
/**
* @param {number} monotonicTime
* @param {number} wallTime
*/
setIssueTime: function(monotonicTime, wallTime)
{
this._issueTime = monotonicTime;
this._wallIssueTime = wallTime;
this._startTime = monotonicTime;
},
/**
* @return {number}
*/
issueTime: function()
{
return this._issueTime;
},
/**
* @param {number} monotonicTime
* @return {number}
*/
pseudoWallTime: function(monotonicTime)
{
return this._wallIssueTime ? this._wallIssueTime - this._issueTime + monotonicTime : monotonicTime;
},
/**
* @return {number}
*/
get responseReceivedTime()
{
return this._responseReceivedTime || -1;
},
set responseReceivedTime(x)
{
this._responseReceivedTime = x;
},
/**
* @return {number}
*/
get endTime()
{
return this._endTime || -1;
},
set endTime(x)
{
if (this.timing && this.timing.requestTime) {
// Check against accurate responseReceivedTime.
this._endTime = Math.max(x, this.responseReceivedTime);
} else {
// Prefer endTime since it might be from the network stack.
this._endTime = x;
if (this._responseReceivedTime > x)
this._responseReceivedTime = x;
}
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
},
/**
* @return {number}
*/
get duration()
{
if (this._endTime === -1 || this._startTime === -1)
return -1;
return this._endTime - this._startTime;
},
/**
* @return {number}
*/
get latency()
{
if (this._responseReceivedTime === -1 || this._startTime === -1)
return -1;
return this._responseReceivedTime - this._startTime;
},
/**
* @return {number}
*/
get resourceSize()
{
return this._resourceSize || 0;
},
set resourceSize(x)
{
this._resourceSize = x;
},
/**
* @return {number}
*/
get transferSize()
{
return this._transferSize || 0;
},
/**
* @param {number} x
*/
increaseTransferSize: function(x)
{
this._transferSize = (this._transferSize || 0) + x;
},
/**
* @param {number} x
*/
setTransferSize: function(x)
{
this._transferSize = x;
},
/**
* @return {boolean}
*/
get finished()
{
return this._finished;
},
set finished(x)
{
if (this._finished === x)
return;
this._finished = x;
if (x) {
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
}
},
/**
* @return {boolean}
*/
get failed()
{
return this._failed;
},
set failed(x)
{
this._failed = x;
},
/**
* @return {boolean}
*/
get canceled()
{
return this._canceled;
},
set canceled(x)
{
this._canceled = x;
},
/**
* @return {!NetworkAgent.BlockedReason|undefined}
*/
blockedReason: function()
{
return this._blockedReason;
},
/**
* @param {!NetworkAgent.BlockedReason} reason
*/
setBlockedReason: function(reason)
{
this._blockedReason = reason;
},
/**
* @return {boolean}
*/
wasBlocked: function()
{
return !!this._blockedReason;
},
/**
* @return {boolean}
*/
cached: function()
{
return (!!this._fromMemoryCache || !!this._fromDiskCache) && !this._transferSize;
},
setFromMemoryCache: function()
{
this._fromMemoryCache = true;
delete this._timing;
},
setFromDiskCache: function()
{
this._fromDiskCache = true;
},
/**
* @return {boolean}
*/
get fetchedViaServiceWorker()
{
return this._fetchedViaServiceWorker;
},
set fetchedViaServiceWorker(x)
{
this._fetchedViaServiceWorker = x;
},
/**
* @return {!NetworkAgent.ResourceTiming|undefined}
*/
get timing()
{
return this._timing;
},
set timing(x)
{
if (x && !this._fromMemoryCache) {
// Take startTime and responseReceivedTime from timing data for better accuracy.
// Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
this._startTime = x.requestTime;
this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;
this._timing = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
}
},
/**
* @return {string}
*/
get mimeType()
{
return this._mimeType;
},
set mimeType(x)
{
this._mimeType = x;
},
/**
* @return {string}
*/
get displayName()
{
return this._parsedURL.displayName;
},
/**
* @return {string}
*/
name: function()
{
if (this._name)
return this._name;
this._parseNameAndPathFromURL();
return this._name;
},
/**
* @return {string}
*/
path: function()
{
if (this._path)
return this._path;
this._parseNameAndPathFromURL();
return this._path;
},
_parseNameAndPathFromURL: function()
{
if (this._parsedURL.isDataURL()) {
this._name = this._parsedURL.dataURLDisplayName();
this._path = "";
} else if (this._parsedURL.isAboutBlank()) {
this._name = this._parsedURL.url;
this._path = "";
} else {
this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;
this._path = this._path.trimURL(this.target().resourceTreeModel.inspectedPageDomain());
if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams)
this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : "");
else if (this._parsedURL.folderPathComponents) {
this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/";
this._path = this._path.substring(0, this._path.lastIndexOf("/"));
} else {
this._name = this._parsedURL.host;
this._path = "";
}
}
},
/**
* @return {string}
*/
get folder()
{
var path = this._parsedURL.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1)
path = path.substring(0, indexOfQuery);
var lastSlashIndex = path.lastIndexOf("/");
return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";
},
/**
* @return {!WebInspector.ResourceType}
*/
resourceType: function()
{
return this._resourceType;
},
/**
* @param {!WebInspector.ResourceType} resourceType
*/
setResourceType: function(resourceType)
{
this._resourceType = resourceType;
},
/**
* @return {string}
*/
get domain()
{
return this._parsedURL.host;
},
/**
* @return {string}
*/
get scheme()
{
return this._parsedURL.scheme;
},
/**
* @return {?WebInspector.NetworkRequest}
*/
get redirectSource()
{
if (this.redirects && this.redirects.length > 0)
return this.redirects[this.redirects.length - 1];
return this._redirectSource;
},
set redirectSource(x)
{
this._redirectSource = x;
delete this._initiatorInfo;
},
/**
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
requestHeaders: function()
{
return this._requestHeaders || [];
},
/**
* @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers
*/
setRequestHeaders: function(headers)
{
this._requestHeaders = headers;
delete this._requestCookies;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},
/**
* @return {string|undefined}
*/
requestHeadersText: function()
{
return this._requestHeadersText;
},
/**
* @param {string} text
*/
setRequestHeadersText: function(text)
{
this._requestHeadersText = text;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},
/**
* @param {string} headerName
* @return {string|undefined}
*/
requestHeaderValue: function(headerName)
{
return this._headerValue(this.requestHeaders(), headerName);
},
/**
* @return {!Array.<!WebInspector.Cookie>}
*/
get requestCookies()
{
if (!this._requestCookies)
this._requestCookies = WebInspector.CookieParser.parseCookie(this.target(), this.requestHeaderValue("Cookie"));
return this._requestCookies;
},
/**
* @return {string|undefined}
*/
get requestFormData()
{
return this._requestFormData;
},
set requestFormData(x)
{
this._requestFormData = x;
delete this._parsedFormParameters;
},
/**
* @return {string}
*/
requestHttpVersion: function()
{
var headersText = this.requestHeadersText();
if (!headersText)
return this.requestHeaderValue("version") || this.requestHeaderValue(":version") || "unknown";
var firstLine = headersText.split(/\r\n/)[0];
var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
return match ? match[1] : "HTTP/0.9";
},
/**
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
get responseHeaders()
{
return this._responseHeaders || [];
},
set responseHeaders(x)
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
delete this._responseCookies;
this._responseHeaderValues = {};
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},
/**
* @return {string}
*/
get responseHeadersText()
{
return this._responseHeadersText;
},
set responseHeadersText(x)
{
this._responseHeadersText = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},
/**
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
get sortedResponseHeaders()
{
if (this._sortedResponseHeaders !== undefined)
return this._sortedResponseHeaders;
this._sortedResponseHeaders = this.responseHeaders.slice();
this._sortedResponseHeaders.sort(function(a, b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); });
return this._sortedResponseHeaders;
},
/**
* @param {string} headerName
* @return {string|undefined}
*/
responseHeaderValue: function(headerName)
{
var value = this._responseHeaderValues[headerName];
if (value === undefined) {
value = this._headerValue(this.responseHeaders, headerName);
this._responseHeaderValues[headerName] = (value !== undefined) ? value : null;
}
return (value !== null) ? value : undefined;
},
/**
* @return {!Array.<!WebInspector.Cookie>}
*/
get responseCookies()
{
if (!this._responseCookies)
this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.target(), this.responseHeaderValue("Set-Cookie"));
return this._responseCookies;
},
/**
* @return {?string}
*/
queryString: function()
{
if (this._queryString !== undefined)
return this._queryString;
var queryString = null;
var url = this.url;
var questionMarkPosition = url.indexOf("?");
if (questionMarkPosition !== -1) {
queryString = url.substring(questionMarkPosition + 1);
var hashSignPosition = queryString.indexOf("#");
if (hashSignPosition !== -1)
queryString = queryString.substring(0, hashSignPosition);
}
this._queryString = queryString;
return this._queryString;
},
/**
* @return {?Array.<!WebInspector.NetworkRequest.NameValue>}
*/
get queryParameters()
{
if (this._parsedQueryParameters)
return this._parsedQueryParameters;
var queryString = this.queryString();
if (!queryString)
return null;
this._parsedQueryParameters = this._parseParameters(queryString);
return this._parsedQueryParameters;
},
/**
* @return {?Array.<!WebInspector.NetworkRequest.NameValue>}
*/
get formParameters()
{
if (this._parsedFormParameters)
return this._parsedFormParameters;
if (!this.requestFormData)
return null;
var requestContentType = this.requestContentType();
if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return null;
this._parsedFormParameters = this._parseParameters(this.requestFormData);
return this._parsedFormParameters;
},
/**
* @return {string}
*/
responseHttpVersion: function()
{
var headersText = this._responseHeadersText;
if (!headersText)
return this.responseHeaderValue("version") || this.responseHeaderValue(":version") || "unknown";
var firstLine = headersText.split(/\r\n/)[0];
var match = firstLine.match(/^(HTTP\/\d+\.\d+)/);
return match ? match[1] : "HTTP/0.9";
},
/**
* @param {string} queryString
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
_parseParameters: function(queryString)
{
function parseNameValue(pair)
{
var position = pair.indexOf("=");
if (position === -1)
return {name: pair, value: ""};
else
return {name: pair.substring(0, position), value: pair.substring(position + 1)};
}
return queryString.split("&").map(parseNameValue);
},
/**
* @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers
* @param {string} headerName
* @return {string|undefined}
*/
_headerValue: function(headers, headerName)
{
headerName = headerName.toLowerCase();
var values = [];
for (var i = 0; i < headers.length; ++i) {
if (headers[i].name.toLowerCase() === headerName)
values.push(headers[i].value);
}
if (!values.length)
return undefined;
// Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed.
if (headerName === "set-cookie")
return values.join("\n");
return values.join(", ");
},
/**
* @return {?string|undefined}
*/
get content()
{
return this._content;
},
/**
* @return {?Protocol.Error|undefined}
*/
contentError: function()
{
return this._contentError;
},
/**
* @return {boolean}
*/
get contentEncoded()
{
return this._contentEncoded;
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._url;
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._resourceType;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
// We do not support content retrieval for WebSockets at the moment.
// Since WebSockets are potentially long-living, fail requests immediately
// to prevent caller blocking until resource is marked as finished.
if (this._resourceType === WebInspector.resourceTypes.WebSocket)
return Promise.resolve(/** @type {?string} */(null));
if (typeof this._content !== "undefined")
return Promise.resolve(/** @type {?string} */(this.content || null));
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this._pendingContentCallbacks.push(callback);
if (this.finished)
this._innerRequestContent();
return promise;
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},
/**
* @return {boolean}
*/
isHttpFamily: function()
{
return !!this.url.match(/^https?:/i);
},
/**
* @return {string|undefined}
*/
requestContentType: function()
{
return this.requestHeaderValue("Content-Type");
},
/**
* @return {boolean}
*/
hasErrorStatusCode: function()
{
return this.statusCode >= 400;
},
/**
* @param {!NetworkAgent.ResourcePriority} priority
*/
setInitialPriority: function(priority)
{
this._initialPriority = priority;
},
/**
* @return {?NetworkAgent.ResourcePriority}
*/
initialPriority: function()
{
return this._initialPriority;
},
/**
* @param {!Element} image
*/
populateImageSource: function(image)
{
WebInspector.Resource.populateImageSource(this._url, this._mimeType, this, image);
},
/**
* @return {?string}
*/
asDataURL: function()
{
var content = this._content;
var charset = null;
if (!this._contentEncoded) {
content = content.toBase64();
charset = "utf-8";
}
return WebInspector.Resource.contentAsDataURL(content, this.mimeType, true, charset);
},
_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;
/**
* @param {?Protocol.Error} error
* @param {string} content
* @param {boolean} contentEncoded
* @this {WebInspector.NetworkRequest}
*/
function onResourceContent(error, content, contentEncoded)
{
this._content = error ? null : content;
this._contentError = error;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
this.target().networkAgent().getResponseBody(this._requestId, onResourceContent.bind(this));
},
/**
* @return {?NetworkAgent.Initiator}
*/
initiator: function()
{
return this._initiator;
},
/**
* @return {!{type: !WebInspector.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number, scriptId: ?string}}
*/
initiatorInfo: function()
{
if (this._initiatorInfo)
return this._initiatorInfo;
var type = WebInspector.NetworkRequest.InitiatorType.Other;
var url = "";
var lineNumber = -Infinity;
var columnNumber = -Infinity;
var scriptId = null;
var initiator = this._initiator;
if (this.redirectSource) {
type = WebInspector.NetworkRequest.InitiatorType.Redirect;
url = this.redirectSource.url;
} else if (initiator) {
if (initiator.type === NetworkAgent.InitiatorType.Parser) {
type = WebInspector.NetworkRequest.InitiatorType.Parser;
url = initiator.url ? initiator.url : url;
lineNumber = initiator.lineNumber ? initiator.lineNumber : lineNumber;
} else if (initiator.type === NetworkAgent.InitiatorType.Script) {
for (var stack = initiator.stack; stack; stack = stack.parent) {
var topFrame = stack.callFrames.length ? stack.callFrames[0] : null;
if (!topFrame)
continue;
type = WebInspector.NetworkRequest.InitiatorType.Script;
url = topFrame.url || WebInspector.UIString("<anonymous>");
lineNumber = topFrame.lineNumber;
columnNumber = topFrame.columnNumber;
scriptId = topFrame.scriptId;
break;
}
}
}
this._initiatorInfo = {type: type, url: url, lineNumber: lineNumber, columnNumber: columnNumber, scriptId: scriptId};
return this._initiatorInfo;
},
/**
* @return {?WebInspector.NetworkRequest}
*/
initiatorRequest: function()
{
if (this._initiatorRequest === undefined)
this._initiatorRequest = this.target().networkLog.requestForURL(this.initiatorInfo().url);
return this._initiatorRequest;
},
/**
* @return {!Set<!WebInspector.NetworkRequest>}
*/
initiatorChain: function()
{
if (this._initiatorChain)
return this._initiatorChain;
this._initiatorChain = new Set();
var request = this;
while (request) {
this._initiatorChain.add(request);
request = request.initiatorRequest();
}
return this._initiatorChain;
},
/**
* @return {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>}
*/
frames: function()
{
return this._frames;
},
/**
* @param {string} errorMessage
* @param {number} time
*/
addFrameError: function(errorMessage, time)
{
this._addFrame({ type: WebInspector.NetworkRequest.WebSocketFrameType.Error, text: errorMessage, time: this.pseudoWallTime(time), opCode: -1, mask: false });
},
/**
* @param {!NetworkAgent.WebSocketFrame} response
* @param {number} time
* @param {boolean} sent
*/
addFrame: function(response, time, sent)
{
var type = sent ? WebInspector.NetworkRequest.WebSocketFrameType.Send : WebInspector.NetworkRequest.WebSocketFrameType.Receive;
this._addFrame({ type: type, text: response.payloadData, time: this.pseudoWallTime(time), opCode: response.opcode, mask: response.mask });
},
/**
* @param {!WebInspector.NetworkRequest.WebSocketFrame} frame
*/
_addFrame: function(frame)
{
this._frames.push(frame);
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.WebsocketFrameAdded, frame);
},
/**
* @return {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>}
*/
eventSourceMessages: function()
{
return this._eventSourceMessages;
},
/**
* @param {number} time
* @param {string} eventName
* @param {string} eventId
* @param {string} data
*/
addEventSourceMessage: function(time, eventName, eventId, data)
{
var message = {time: this.pseudoWallTime(time), eventName: eventName, eventId: eventId, data: data};
this._eventSourceMessages.push(message);
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.EventSourceMessageAdded, message);
},
replayXHR: function()
{
this.target().networkAgent().replayXHR(this.requestId);
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 2 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @typedef {!{x: number, y: number, picture: string}}
*/
WebInspector.PictureFragment;
/**
* @constructor
* @param {!WebInspector.Target} target
* @param {string} snapshotId
*/
WebInspector.PaintProfilerSnapshot = function(target, snapshotId)
{
this._target = target;
this._id = snapshotId;
}
/**
* @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.PictureFragment>} fragments
* @param {function(?WebInspector.PaintProfilerSnapshot)} callback
*/
WebInspector.PaintProfilerSnapshot.loadFromFragments = function(target, fragments, callback)
{
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.loadSnapshot(): ", WebInspector.PaintProfilerSnapshot.bind(null, target));
target.layerTreeAgent().loadSnapshot(fragments, wrappedCallback);
}
/**
* @param {!WebInspector.Target} target
* @param {string} encodedPicture
* @param {function(?WebInspector.PaintProfilerSnapshot)} callback
*/
WebInspector.PaintProfilerSnapshot.load = function(target, encodedPicture, callback)
{
var fragment = {
x: 0,
y: 0,
picture: encodedPicture
};
WebInspector.PaintProfilerSnapshot.loadFromFragments(target, [fragment], callback);
}
WebInspector.PaintProfilerSnapshot.prototype = {
dispose: function()
{
this._target.layerTreeAgent().releaseSnapshot(this._id);
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @param {?number} firstStep
* @param {?number} lastStep
* @param {?number} scale
* @param {function(string=)} callback
*/
requestImage: function(firstStep, lastStep, scale, callback)
{
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.replaySnapshot(): ");
this._target.layerTreeAgent().replaySnapshot(this._id, firstStep || undefined, lastStep || undefined, scale || 1.0, wrappedCallback);
},
/**
* @param {?DOMAgent.Rect} clipRect
* @param {function(!Array.<!LayerTreeAgent.PaintProfile>=)} callback
*/
profile: function(clipRect, callback)
{
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.profileSnapshot(): ");
this._target.layerTreeAgent().profileSnapshot(this._id, 5, 1, clipRect || undefined, wrappedCallback);
},
/**
* @param {function(!Array.<!WebInspector.PaintProfilerLogItem>=)} callback
*/
commandLog: function(callback)
{
/**
* @param {?string} error
* @param {!Array.<!WebInspector.RawPaintProfilerLogItem>} log
*/
function callbackWrapper(error, log)
{
if (error) {
console.error("LayerTreeAgent.snapshotCommandLog(): " + error);
callback();
return;
}
var logItems = log.map((entry, index) => new WebInspector.PaintProfilerLogItem(entry, index));
callback(logItems);
}
this._target.layerTreeAgent().snapshotCommandLog(this._id, callbackWrapper);
}
};
/**
* @typedef {!{method: string, params: ?Object<string, *>}}
*/
WebInspector.RawPaintProfilerLogItem;
/**
* @constructor
* @param {!WebInspector.RawPaintProfilerLogItem} rawEntry
* @param {number} commandIndex
*/
WebInspector.PaintProfilerLogItem = function(rawEntry, commandIndex)
{
this.method = rawEntry.method;
this.params = rawEntry.params;
this.commandIndex = commandIndex;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @typedef {{object: ?WebInspector.RemoteObject, wasThrown: (boolean|undefined)}}
*/
WebInspector.CallFunctionResult;
/**
* This may not be an interface due to "instanceof WebInspector.RemoteObject" checks in the code.
*
* @constructor
*/
WebInspector.RemoteObject = function() { }
WebInspector.RemoteObject.prototype = {
/**
* @return {?RuntimeAgent.CustomPreview}
*/
customPreview: function()
{
return null;
},
/** @return {string} */
get type()
{
throw "Not implemented";
},
/** @return {string|undefined} */
get subtype()
{
throw "Not implemented";
},
/** @return {string|undefined} */
get description()
{
throw "Not implemented";
},
/** @return {boolean} */
get hasChildren()
{
throw "Not implemented";
},
/**
* @return {number}
*/
arrayLength: function()
{
throw "Not implemented";
},
/**
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getOwnProperties: function(callback)
{
throw "Not implemented";
},
/**
* @return {!Promise<!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}>}
*/
getOwnPropertiesPromise: function()
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} success
* @this {WebInspector.RemoteObject}
*/
function promiseConstructor(success)
{
this.getOwnProperties(getOwnPropertiesCallback.bind(null, success));
}
/**
* @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} callback
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
*/
function getOwnPropertiesCallback(callback, properties, internalProperties)
{
callback({
properties: properties,
internalProperties: internalProperties
});
}
},
/**
* @param {boolean} accessorPropertiesOnly
* @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebInspector.RemoteObjectProperty>)} callback
*/
getAllProperties: function(accessorPropertiesOnly, callback)
{
throw "Not implemented";
},
/**
* @param {boolean} accessorPropertiesOnly
* @return {!Promise<!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}>}
*/
getAllPropertiesPromise: function(accessorPropertiesOnly)
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function(!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} success
* @this {WebInspector.RemoteObject}
*/
function promiseConstructor(success)
{
this.getAllProperties(accessorPropertiesOnly, getAllPropertiesCallback.bind(null, success));
}
/**
* @param {function(!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>})} callback
* @param {?Array<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array<!WebInspector.RemoteObjectProperty>} internalProperties
*/
function getAllPropertiesCallback(callback, properties, internalProperties)
{
callback({
properties: properties,
internalProperties: internalProperties
});
}
},
/**
* @return {!Promise<?Array<!WebInspector.EventListener>>}
*/
eventListeners: function()
{
throw "Not implemented";
},
/**
* @param {!RuntimeAgent.CallArgument} name
* @param {function(string=)} callback
*/
deleteProperty: function(name, callback)
{
throw "Not implemented";
},
/**
* @param {string|!RuntimeAgent.CallArgument} name
* @param {string} value
* @param {function(string=)} callback
*/
setPropertyValue: function(name, value, callback)
{
throw "Not implemented";
},
/**
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>=} args
* @param {function(?WebInspector.RemoteObject, boolean=)=} callback
*/
callFunction: function(functionDeclaration, args, callback)
{
throw "Not implemented";
},
/**
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>=} args
* @return {!Promise<!WebInspector.CallFunctionResult>}
*/
callFunctionPromise: function(functionDeclaration, args)
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function(!WebInspector.CallFunctionResult)} success
* @this {WebInspector.RemoteObject}
*/
function promiseConstructor(success)
{
this.callFunction(functionDeclaration, args, callFunctionCallback.bind(null, success));
}
/**
* @param {function(!WebInspector.CallFunctionResult)} callback
* @param {?WebInspector.RemoteObject} object
* @param {boolean=} wasThrown
*/
function callFunctionCallback(callback, object, wasThrown)
{
callback({
object: object,
wasThrown: wasThrown
});
}
},
/**
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>|undefined} args
* @param {function(*)} callback
*/
callFunctionJSON: function(functionDeclaration, args, callback)
{
throw "Not implemented";
},
/**
* @param {function(this:Object, ...):T} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>|undefined} args
* @return {!Promise<T>}
* @template T
*/
callFunctionJSONPromise: function(functionDeclaration, args)
{
return new Promise(promiseConstructor.bind(this));
/**
* @this {WebInspector.RemoteObject}
*/
function promiseConstructor(success)
{
this.callFunctionJSON(functionDeclaration, args, success);
}
},
/**
* @return {!WebInspector.Target}
*/
target: function()
{
throw new Error("Target-less object");
},
/**
* @return {?WebInspector.DebuggerModel}
*/
debuggerModel: function()
{
throw new Error("DebuggerModel-less object");
},
/**
* @return {boolean}
*/
isNode: function()
{
return false;
},
/**
* @param {function(?WebInspector.DebuggerModel.FunctionDetails)} callback
*/
functionDetails: function(callback)
{
callback(null);
},
/**
* @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>}
*/
functionDetailsPromise: function()
{
return new Promise(promiseConstructor.bind(this));
/**
* @param {function(?WebInspector.DebuggerModel.FunctionDetails)} success
* @this {WebInspector.RemoteObject}
*/
function promiseConstructor(success)
{
this.functionDetails(success);
}
},
/**
* @param {function(?WebInspector.DebuggerModel.GeneratorObjectDetails)} callback
*/
generatorObjectDetails: function(callback)
{
callback(null);
},
/**
* @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback
*/
collectionEntries: function(callback)
{
callback(null);
}
}
/**
* @param {*} value
* @return {!WebInspector.RemoteObject}
*/
WebInspector.RemoteObject.fromLocalObject = function(value)
{
return new WebInspector.LocalJSONObject(value);
}
/**
* @param {!WebInspector.RemoteObject} remoteObject
* @return {string}
*/
WebInspector.RemoteObject.type = function(remoteObject)
{
if (remoteObject === null)
return "null";
var type = typeof remoteObject;
if (type !== "object" && type !== "function")
return type;
return remoteObject.type;
}
/**
* @param {!WebInspector.RemoteObject|!RuntimeAgent.RemoteObject|!RuntimeAgent.ObjectPreview} object
* @return {number}
*/
WebInspector.RemoteObject.arrayLength = function(object)
{
if (object.subtype !== "array")
return 0;
var matches = object.description.match(/\[([0-9]+)\]/);
if (!matches)
return 0;
return parseInt(matches[1], 10);
}
/**
* @param {!RuntimeAgent.RemoteObject|!WebInspector.RemoteObject|number|string|boolean|undefined|null} object
* @return {!RuntimeAgent.CallArgument}
*/
WebInspector.RemoteObject.toCallArgument = function(object)
{
var type = typeof object;
var value = object;
var objectId = undefined;
var description = String(object);
if (type === "number" && value === 0 && 1 / value < 0)
description = "-0";
switch (type) {
case "number":
case "string":
case "boolean":
case "undefined":
break;
default:
if (object) {
type = object.type;
value = object.value;
objectId = object.objectId;
description = object.description;
}
break;
}
// Handle special numbers: NaN, Infinity, -Infinity, -0.
if (type === "number") {
switch (description) {
case "NaN":
case "Infinity":
case "-Infinity":
case "-0":
value = description;
break;
}
}
return {
value: value,
objectId: objectId,
type: /** @type {!RuntimeAgent.CallArgumentType.<string>} */ (type)
};
}
/**
* @constructor
* @extends {WebInspector.RemoteObject}
* @param {!WebInspector.Target} target
* @param {string|undefined} objectId
* @param {string} type
* @param {string|undefined} subtype
* @param {*} value
* @param {string=} description
* @param {!RuntimeAgent.ObjectPreview=} preview
* @param {!RuntimeAgent.CustomPreview=} customPreview
*/
WebInspector.RemoteObjectImpl = function(target, objectId, type, subtype, value, description, preview, customPreview)
{
WebInspector.RemoteObject.call(this);
this._target = target;
this._runtimeAgent = target.runtimeAgent();
this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
this._type = type;
this._subtype = subtype;
if (objectId) {
// handle
this._objectId = objectId;
this._description = description;
this._hasChildren = (type !== "symbol");
this._preview = preview;
} else {
// Primitive or null object.
this._description = description || (value + "");
this._hasChildren = false;
// Handle special numbers: NaN, Infinity, -Infinity, -0.
if (type === "number" && typeof value !== "number")
this.value = Number(value);
else
this.value = value;
}
this._customPreview = customPreview || null;
}
WebInspector.RemoteObjectImpl.prototype = {
/**
* @override
* @return {?RuntimeAgent.CustomPreview}
*/
customPreview: function()
{
return this._customPreview;
},
/** @return {!RuntimeAgent.RemoteObjectId} */
get objectId()
{
return this._objectId;
},
/**
* @override
* @return {string}
*/
get type()
{
return this._type;
},
/**
* @override
* @return {string|undefined}
*/
get subtype()
{
return this._subtype;
},
/**
* @override
* @return {string|undefined}
*/
get description()
{
return this._description;
},
/**
* @override
* @return {boolean}
*/
get hasChildren()
{
return this._hasChildren;
},
/**
* @return {!RuntimeAgent.ObjectPreview|undefined}
*/
get preview()
{
return this._preview;
},
/**
* @override
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getOwnProperties: function(callback)
{
this.doGetProperties(true, false, false, callback);
},
/**
* @override
* @param {boolean} accessorPropertiesOnly
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getAllProperties: function(accessorPropertiesOnly, callback)
{
this.doGetProperties(false, accessorPropertiesOnly, false, callback);
},
/**
* @override
* @return {!Promise<?Array<!WebInspector.EventListener>>}
*/
eventListeners: function()
{
return new Promise(eventListeners.bind(this));
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
* @this {WebInspector.RemoteObject}
*/
function eventListeners(fulfill, reject)
{
if (!this.target().isPage()) {
// TODO(kozyatinskiy): figure out how this should work for |window| when there is no DOMDebugger.
fulfill([]);
return;
}
if (!this._objectId) {
reject(null);
return;
}
/** @type {?WebInspector.RemoteObject} */
var removeFunction = null;
this.callFunctionPromise(nodeRemoveEventListener).then(storeRemoveFunction.bind(this));
/**
* @param {!WebInspector.CallFunctionResult} result
* @this {WebInspector.RemoteObject}
*/
function storeRemoveFunction(result)
{
if (!result.wasThrown && result.object)
removeFunction = result.object;
this.target().domdebuggerAgent().getEventListeners(this._objectId, mycallback.bind(this));
}
/**
* @this {!WebInspector.RemoteObject}
* @param {?Protocol.Error} error
* @param {!Array<!DOMDebuggerAgent.EventListener>} payloads
*/
function mycallback(error, payloads)
{
if (error) {
reject(null);
return;
}
fulfill(payloads.map(createEventListener.bind(this)));
}
/**
* @suppressReceiverCheck
* @this {Node}
* @return {function(this:Node, string, function(), boolean=, boolean=): undefined}
*/
function nodeRemoveEventListener()
{
return removeEventListenerWrapper.bind(this);
/**
* @param {string} type
* @param {function()} handler
* @param {boolean=} useCapture
* @param {boolean=} passive
* @this {Node}
*/
function removeEventListenerWrapper(type, handler, useCapture, passive)
{
// TODO(dtapuska): Remove this one closure compiler is updated
// to handle EventListenerOptions and passive event listeners
// has shipped. Don't JSDoc these otherwise it will fail.
// @return {boolean|undefined|{capture: (boolean|undefined), passive: boolean}}
function eventListenerOptions()
{
if (passive && useCapture)
return {"capture": useCapture, "passive": passive};
else if (passive)
return {"passive": passive};
else if (useCapture)
return {"capture": useCapture};
else
return {};
}
this.removeEventListener(type, handler, eventListenerOptions());
if (this["on" + type])
this["on" + type] = null;
}
}
/**
* @this {!WebInspector.RemoteObject}
* @param {!DOMDebuggerAgent.EventListener} payload
*/
function createEventListener(payload)
{
return new WebInspector.EventListener(this._target,
payload.type,
payload.useCapture,
payload.passive,
payload.handler ? this.target().runtimeModel.createRemoteObject(payload.handler) : null,
payload.originalHandler ? this.target().runtimeModel.createRemoteObject(payload.originalHandler) : null,
WebInspector.DebuggerModel.Location.fromPayload(this._debuggerModel, payload.location),
removeFunction);
}
}
},
/**
* @param {!Array.<string>} propertyPath
* @param {function(?WebInspector.RemoteObject, boolean=)} callback
*/
getProperty: function(propertyPath, callback)
{
/**
* @param {string} arrayStr
* @suppressReceiverCheck
* @this {Object}
*/
function remoteFunction(arrayStr)
{
var result = this;
var properties = JSON.parse(arrayStr);
for (var i = 0, n = properties.length; i < n; ++i)
result = result[properties[i]];
return result;
}
var args = [{ value: JSON.stringify(propertyPath) }];
this.callFunction(remoteFunction, args, callback);
},
/**
* @param {boolean} ownProperties
* @param {boolean} accessorPropertiesOnly
* @param {boolean} generatePreview
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
doGetProperties: function(ownProperties, accessorPropertiesOnly, generatePreview, callback)
{
if (!this._objectId) {
callback(null, null);
return;
}
/**
* @param {?Protocol.Error} error
* @param {!Array.<!RuntimeAgent.PropertyDescriptor>} properties
* @param {!Array.<!RuntimeAgent.InternalPropertyDescriptor>=} internalProperties
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.RemoteObjectImpl}
*/
function remoteObjectBinder(error, properties, internalProperties, exceptionDetails)
{
if (error) {
callback(null, null);
return;
}
if (exceptionDetails) {
var msg = new WebInspector.ConsoleMessage(this._target, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageLevel.Error, exceptionDetails.text);
this._target.consoleModel.addMessage(msg);
callback(null, null);
return;
}
var result = [];
for (var i = 0; properties && i < properties.length; ++i) {
var property = properties[i];
var propertyValue = property.value ? this._target.runtimeModel.createRemoteObject(property.value) : null;
var propertySymbol = property.symbol ? this._target.runtimeModel.createRemoteObject(property.symbol) : null;
var remoteProperty = new WebInspector.RemoteObjectProperty(property.name, propertyValue,
!!property.enumerable, !!property.writable, !!property.isOwn, !!property.wasThrown, propertySymbol);
if (typeof property.value === "undefined") {
if (property.get && property.get.type !== "undefined")
remoteProperty.getter = this._target.runtimeModel.createRemoteObject(property.get);
if (property.set && property.set.type !== "undefined")
remoteProperty.setter = this._target.runtimeModel.createRemoteObject(property.set);
}
result.push(remoteProperty);
}
var internalPropertiesResult = null;
if (internalProperties) {
internalPropertiesResult = [];
for (var i = 0; i < internalProperties.length; i++) {
var property = internalProperties[i];
if (!property.value)
continue;
var propertyValue = this._target.runtimeModel.createRemoteObject(property.value);
internalPropertiesResult.push(new WebInspector.RemoteObjectProperty(property.name, propertyValue, true, false));
}
}
callback(result, internalPropertiesResult);
}
this._runtimeAgent.getProperties(this._objectId, ownProperties, accessorPropertiesOnly, generatePreview, remoteObjectBinder.bind(this));
},
/**
* @override
* @param {string|!RuntimeAgent.CallArgument} name
* @param {string} value
* @param {function(string=)} callback
*/
setPropertyValue: function(name, value, callback)
{
if (!this._objectId) {
callback("Can't set a property of non-object.");
return;
}
this._runtimeAgent.invoke_evaluate({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @this {WebInspector.RemoteObject}
*/
function evaluatedCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || (result.type !== "string" ? result.description : /** @type {string} */(result.value)));
return;
}
if (typeof name === "string")
name = WebInspector.RemoteObject.toCallArgument(name);
this.doSetObjectPropertyValue(result, name, callback);
if (result.objectId)
this._runtimeAgent.releaseObject(result.objectId);
}
},
/**
* @param {!RuntimeAgent.RemoteObject} result
* @param {!RuntimeAgent.CallArgument} name
* @param {function(string=)} callback
*/
doSetObjectPropertyValue: function(result, name, callback)
{
// This assignment may be for a regular (data) property, and for an accessor property (with getter/setter).
// Note the sensitive matter about accessor property: the property may be physically defined in some proto object,
// but logically it is bound to the object in question. JavaScript passes this object to getters/setters, not the object
// where property was defined; so do we.
var setPropertyValueFunction = "function(a, b) { this[a] = b; }";
var argv = [name, WebInspector.RemoteObject.toCallArgument(result)];
this._runtimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, argv, true, undefined, undefined, undefined, propertySetCallback);
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
*/
function propertySetCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
callback();
}
},
/**
* @override
* @param {!RuntimeAgent.CallArgument} name
* @param {function(string=)} callback
*/
deleteProperty: function(name, callback)
{
if (!this._objectId) {
callback("Can't delete a property of non-object.");
return;
}
var deletePropertyFunction = "function(a) { delete this[a]; return !(a in this); }";
this._runtimeAgent.callFunctionOn(this._objectId, deletePropertyFunction, [name], true, undefined, undefined, undefined, deletePropertyCallback);
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
*/
function deletePropertyCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
if (!result.value)
callback("Failed to delete property.");
else
callback();
}
},
/**
* @override
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array.<!RuntimeAgent.CallArgument>=} args
* @param {function(?WebInspector.RemoteObject, boolean=)=} callback
*/
callFunction: function(functionDeclaration, args, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @this {WebInspector.RemoteObjectImpl}
*/
function mycallback(error, result, wasThrown)
{
if (!callback)
return;
if (error)
callback(null, false);
else
callback(this.target().runtimeModel.createRemoteObject(result), wasThrown);
}
this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, undefined, mycallback.bind(this));
},
/**
* @override
* @param {function(this:Object)} functionDeclaration
* @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args
* @param {function(*)} callback
*/
callFunctionJSON: function(functionDeclaration, args, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
*/
function mycallback(error, result, wasThrown)
{
callback((error || wasThrown) ? null : result.value);
}
this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, undefined, mycallback);
},
release: function()
{
if (!this._objectId)
return;
this._runtimeAgent.releaseObject(this._objectId);
},
/**
* @override
* @return {number}
*/
arrayLength: function()
{
return WebInspector.RemoteObject.arrayLength(this);
},
/**
* @override
* @return {!WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @override
* @return {?WebInspector.DebuggerModel}
*/
debuggerModel: function()
{
return this._debuggerModel;
},
/**
* @override
* @return {boolean}
*/
isNode: function()
{
return !!this._objectId && this.type === "object" && this.subtype === "node";
},
/**
* @override
* @param {function(?WebInspector.DebuggerModel.FunctionDetails)} callback
*/
functionDetails: function(callback)
{
this._debuggerModel.functionDetails(this, callback);
},
/**
* @override
* @param {function(?WebInspector.DebuggerModel.GeneratorObjectDetails)} callback
*/
generatorObjectDetails: function(callback)
{
this._debuggerModel.generatorObjectDetails(this, callback);
},
/**
* @override
* @param {function(?Array.<!DebuggerAgent.CollectionEntry>)} callback
*/
collectionEntries: function(callback)
{
if (!this._objectId) {
callback(null);
return;
}
this._debuggerModel.getCollectionEntries(this._objectId, callback);
},
__proto__: WebInspector.RemoteObject.prototype
};
/**
* @param {!WebInspector.RemoteObject} object
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
WebInspector.RemoteObject.loadFromObjectPerProto = function(object, callback)
{
// Combines 2 asynch calls. Doesn't rely on call-back orders (some calls may be loop-back).
var savedOwnProperties;
var savedAccessorProperties;
var savedInternalProperties;
var resultCounter = 2;
function processCallback()
{
if (--resultCounter)
return;
if (savedOwnProperties && savedAccessorProperties) {
var combinedList = savedAccessorProperties.slice(0);
for (var i = 0; i < savedOwnProperties.length; i++) {
var property = savedOwnProperties[i];
if (!property.isAccessorProperty())
combinedList.push(property);
}
return callback(combinedList, savedInternalProperties ? savedInternalProperties : null);
} else {
callback(null, null);
}
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
*/
function allAccessorPropertiesCallback(properties, internalProperties)
{
savedAccessorProperties = properties;
processCallback();
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
*/
function ownPropertiesCallback(properties, internalProperties)
{
savedOwnProperties = properties;
savedInternalProperties = internalProperties;
processCallback();
}
object.getAllProperties(true, allAccessorPropertiesCallback);
object.getOwnProperties(ownPropertiesCallback);
};
/**
* @constructor
* @extends {WebInspector.RemoteObjectImpl}
* @param {!WebInspector.Target} target
* @param {string|undefined} objectId
* @param {!WebInspector.ScopeRef} scopeRef
* @param {string} type
* @param {string|undefined} subtype
* @param {*} value
* @param {string=} description
* @param {!RuntimeAgent.ObjectPreview=} preview
*/
WebInspector.ScopeRemoteObject = function(target, objectId, scopeRef, type, subtype, value, description, preview)
{
WebInspector.RemoteObjectImpl.call(this, target, objectId, type, subtype, value, description, preview);
this._scopeRef = scopeRef;
this._savedScopeProperties = undefined;
};
WebInspector.ScopeRemoteObject.prototype = {
/**
* @override
* @param {boolean} ownProperties
* @param {boolean} accessorPropertiesOnly
* @param {boolean} generatePreview
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
doGetProperties: function(ownProperties, accessorPropertiesOnly, generatePreview, callback)
{
if (accessorPropertiesOnly) {
callback([], []);
return;
}
if (this._savedScopeProperties) {
// No need to reload scope variables, as the remote object never
// changes its properties. If variable is updated, the properties
// array is patched locally.
callback(this._savedScopeProperties.slice(), []);
return;
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
* @this {WebInspector.ScopeRemoteObject}
*/
function wrappedCallback(properties, internalProperties)
{
if (this._scopeRef && Array.isArray(properties)) {
this._savedScopeProperties = properties.slice();
if (!this._scopeRef.callFrameId) {
for (var property of this._savedScopeProperties)
property.writable = false;
}
}
callback(properties, internalProperties);
}
// Scope objects always fetch preview.
generatePreview = true;
WebInspector.RemoteObjectImpl.prototype.doGetProperties.call(this, ownProperties, accessorPropertiesOnly, generatePreview, wrappedCallback.bind(this));
},
/**
* @override
* @param {!RuntimeAgent.RemoteObject} result
* @param {!RuntimeAgent.CallArgument} argumentName
* @param {function(string=)} callback
*/
doSetObjectPropertyValue: function(result, argumentName, callback)
{
var name = /** @type {string} */ (argumentName.value);
this._debuggerModel.setVariableValue(this._scopeRef.number, name, WebInspector.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId, setVariableValueCallback.bind(this));
/**
* @param {string=} error
* @this {WebInspector.ScopeRemoteObject}
*/
function setVariableValueCallback(error)
{
if (error) {
callback(error);
return;
}
if (this._savedScopeProperties) {
for (var i = 0; i < this._savedScopeProperties.length; i++) {
if (this._savedScopeProperties[i].name === name)
this._savedScopeProperties[i].value = this._target.runtimeModel.createRemoteObject(result);
}
}
callback();
}
},
__proto__: WebInspector.RemoteObjectImpl.prototype
};
/**
* @constructor
* @param {number} number
* @param {string=} callFrameId
*/
WebInspector.ScopeRef = function(number, callFrameId)
{
this.number = number;
this.callFrameId = callFrameId;
}
/**
* @constructor
* @param {string} name
* @param {?WebInspector.RemoteObject} value
* @param {boolean=} enumerable
* @param {boolean=} writable
* @param {boolean=} isOwn
* @param {boolean=} wasThrown
* @param {boolean=} synthetic
* @param {?WebInspector.RemoteObject=} symbol
*/
WebInspector.RemoteObjectProperty = function(name, value, enumerable, writable, isOwn, wasThrown, symbol, synthetic)
{
this.name = name;
if (value !== null)
this.value = value;
this.enumerable = typeof enumerable !== "undefined" ? enumerable : true;
this.writable = typeof writable !== "undefined" ? writable : true;
this.isOwn = !!isOwn;
this.wasThrown = !!wasThrown;
if (symbol)
this.symbol = symbol;
this.synthetic = !!synthetic;
}
WebInspector.RemoteObjectProperty.prototype = {
/**
* @return {boolean}
*/
isAccessorProperty: function()
{
return !!(this.getter || this.setter);
}
};
// Below is a wrapper around a local object that implements the RemoteObject interface,
// which can be used by the UI code (primarily ObjectPropertiesSection).
// Note that only JSON-compliant objects are currently supported, as there's no provision
// for traversing prototypes, extracting class names via constructor, handling properties
// or functions.
/**
* @constructor
* @extends {WebInspector.RemoteObject}
* @param {*} value
*/
WebInspector.LocalJSONObject = function(value)
{
WebInspector.RemoteObject.call(this);
this._value = value;
}
WebInspector.LocalJSONObject.prototype = {
/**
* @override
* @return {string}
*/
get description()
{
if (this._cachedDescription)
return this._cachedDescription;
/**
* @param {!WebInspector.RemoteObjectProperty} property
* @return {string}
* @this {WebInspector.LocalJSONObject}
*/
function formatArrayItem(property)
{
return this._formatValue(property.value);
}
/**
* @param {!WebInspector.RemoteObjectProperty} property
* @return {string}
* @this {WebInspector.LocalJSONObject}
*/
function formatObjectItem(property)
{
var name = property.name;
if (/^\s|\s$|^$|\n/.test(name))
name = "\"" + name.replace(/\n/g, "\u21B5") + "\"";
return name + ": " + this._formatValue(property.value);
}
if (this.type === "object") {
switch (this.subtype) {
case "array":
this._cachedDescription = this._concatenate("[", "]", formatArrayItem.bind(this));
break;
case "date":
this._cachedDescription = "" + this._value;
break;
case "null":
this._cachedDescription = "null";
break;
default:
this._cachedDescription = this._concatenate("{", "}", formatObjectItem.bind(this));
}
} else {
this._cachedDescription = String(this._value);
}
return this._cachedDescription;
},
/**
* @param {?WebInspector.RemoteObject} value
* @return {string}
*/
_formatValue: function(value)
{
if (!value)
return "undefined";
var description = value.description || "";
if (value.type === "string")
return "\"" + description.replace(/\n/g, "\u21B5") + "\"";
return description;
},
/**
* @param {string} prefix
* @param {string} suffix
* @param {function(!WebInspector.RemoteObjectProperty)} formatProperty
* @return {string}
*/
_concatenate: function(prefix, suffix, formatProperty)
{
var previewChars = 100;
var buffer = prefix;
var children = this._children();
for (var i = 0; i < children.length; ++i) {
var itemDescription = formatProperty(children[i]);
if (buffer.length + itemDescription.length > previewChars) {
buffer += ",\u2026";
break;
}
if (i)
buffer += ", ";
buffer += itemDescription;
}
buffer += suffix;
return buffer;
},
/**
* @override
* @return {string}
*/
get type()
{
return typeof this._value;
},
/**
* @override
* @return {string|undefined}
*/
get subtype()
{
if (this._value === null)
return "null";
if (Array.isArray(this._value))
return "array";
if (this._value instanceof Date)
return "date";
return undefined;
},
/**
* @override
* @return {boolean}
*/
get hasChildren()
{
if ((typeof this._value !== "object") || (this._value === null))
return false;
return !!Object.keys(/** @type {!Object} */ (this._value)).length;
},
/**
* @override
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getOwnProperties: function(callback)
{
callback(this._children(), null);
},
/**
* @override
* @param {boolean} accessorPropertiesOnly
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getAllProperties: function(accessorPropertiesOnly, callback)
{
if (accessorPropertiesOnly)
callback([], null);
else
callback(this._children(), null);
},
/**
* @return {!Array.<!WebInspector.RemoteObjectProperty>}
*/
_children: function()
{
if (!this.hasChildren)
return [];
var value = /** @type {!Object} */ (this._value);
/**
* @param {string} propName
* @return {!WebInspector.RemoteObjectProperty}
*/
function buildProperty(propName)
{
var propValue = value[propName];
if (!(propValue instanceof WebInspector.RemoteObject))
propValue = WebInspector.RemoteObject.fromLocalObject(propValue);
return new WebInspector.RemoteObjectProperty(propName, propValue);
}
if (!this._cachedChildren)
this._cachedChildren = Object.keys(value).map(buildProperty);
return this._cachedChildren;
},
/**
* @return {boolean}
*/
isError: function()
{
return false;
},
/**
* @override
* @return {number}
*/
arrayLength: function()
{
return Array.isArray(this._value) ? this._value.length : 0;
},
/**
* @override
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array.<!RuntimeAgent.CallArgument>=} args
* @param {function(?WebInspector.RemoteObject, boolean=)=} callback
*/
callFunction: function(functionDeclaration, args, callback)
{
var target = /** @type {?Object} */ (this._value);
var rawArgs = args ? args.map(function(arg) { return arg.value; }) : [];
var result;
var wasThrown = false;
try {
result = functionDeclaration.apply(target, rawArgs);
} catch (e) {
wasThrown = true;
}
if (!callback)
return;
callback(WebInspector.RemoteObject.fromLocalObject(result), wasThrown);
},
/**
* @override
* @param {function(this:Object)} functionDeclaration
* @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args
* @param {function(*)} callback
*/
callFunctionJSON: function(functionDeclaration, args, callback)
{
var target = /** @type {?Object} */ (this._value);
var rawArgs = args ? args.map(function(arg) { return arg.value; }) : [];
var result;
try {
result = functionDeclaration.apply(target, rawArgs);
} catch (e) {
result = null;
}
callback(result);
},
__proto__: WebInspector.RemoteObject.prototype
}
/**
* @constructor
* @param {!WebInspector.RemoteObject} object
*/
WebInspector.RemoteArray = function(object)
{
this._object = object;
};
/**
* @param {?WebInspector.RemoteObject} object
* @return {!WebInspector.RemoteArray}
*/
WebInspector.RemoteArray.objectAsArray = function(object)
{
if (!object || object.type !== "object" || object.subtype !== "array")
throw new Error("Object is empty or not an array");
return new WebInspector.RemoteArray(object);
}
/**
* @param {!Array<!WebInspector.RemoteObject>} objects
* @return {!Promise<!WebInspector.RemoteArray>}
*/
WebInspector.RemoteArray.createFromRemoteObjects = function(objects)
{
if (!objects.length)
throw new Error("Input array is empty");
var objectArguments = [];
for (var i = 0; i < objects.length; ++i)
objectArguments.push(WebInspector.RemoteObject.toCallArgument(objects[i]))
return objects[0].callFunctionPromise(createArray, objectArguments).then(returnRemoteArray);
/**
* @return {!Array<*>}
*/
function createArray()
{
if (arguments.length > 1)
return new Array(arguments);
return [arguments[0]];
}
/**
* @param {!WebInspector.CallFunctionResult} result
* @return {!WebInspector.RemoteArray}
*/
function returnRemoteArray(result)
{
if (result.wasThrown || !result.object)
throw new Error("Call function throws exceptions or returns empty value");
return WebInspector.RemoteArray.objectAsArray(result.object);
}
}
WebInspector.RemoteArray.prototype = {
/**
* @param {number} index
* @return {!Promise<!WebInspector.RemoteObject>}
*/
at: function(index)
{
if (index < 0 || index > this._object.arrayLength())
throw new Error("Out of range");
return this._object.callFunctionPromise(at, [WebInspector.RemoteObject.toCallArgument(index)]).then(assertCallFunctionResult);
/**
* @suppressReceiverCheck
* @param {number} index
* @return {*}
* @this {!Object}
*/
function at(index)
{
return this[index];
}
/**
* @param {!WebInspector.CallFunctionResult} result
* @return {!WebInspector.RemoteObject}
*/
function assertCallFunctionResult(result)
{
if (result.wasThrown || !result.object)
throw new Error("Exception in callFunction or result value is empty");
return result.object;
}
},
/**
* @return {number}
*/
length: function()
{
return this._object.arrayLength();
},
/**
* @param {function(!WebInspector.RemoteObject):!Promise<T>} func
* @return {!Promise<!Array<T>>}
* @template T
*/
map: function(func)
{
var promises = [];
for (var i = 0; i < this.length(); ++i)
promises.push(this.at(i).then(func));
return Promise.all(promises);
},
/**
* @return {!WebInspector.RemoteObject}
*/
object: function()
{
return this._object;
}
}
/**
* @constructor
* @param {!WebInspector.RemoteObject} object
*/
WebInspector.RemoteFunction = function(object)
{
this._object = object;
}
/**
* @param {?WebInspector.RemoteObject} object
* @return {!WebInspector.RemoteFunction}
*/
WebInspector.RemoteFunction.objectAsFunction = function(object)
{
if (!object || object.type !== "function")
throw new Error("Object is empty or not a function");
return new WebInspector.RemoteFunction(object);
}
WebInspector.RemoteFunction.prototype = {
/**
* @return {!Promise<!WebInspector.RemoteObject>}
*/
targetFunction: function()
{
return this._object.getOwnPropertiesPromise().then(targetFunction.bind(this));
/**
* @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}} ownProperties
* @return {!WebInspector.RemoteObject}
* @this {WebInspector.RemoteFunction}
*/
function targetFunction(ownProperties)
{
if (!ownProperties.internalProperties)
return this._object;
var internalProperties = ownProperties.internalProperties;
for (var property of internalProperties) {
if (property.name === "[[TargetFunction]]")
return property.value;
}
return this._object;
}
},
/**
* @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>}
*/
targetFunctionDetails: function()
{
return this.targetFunction().then(functionDetails.bind(this));
/**
* @param {!WebInspector.RemoteObject} targetFunction
* @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>}
* @this {WebInspector.RemoteFunction}
*/
function functionDetails(targetFunction)
{
var boundReleaseFunctionDetails = releaseTargetFunction.bind(null, this._object !== targetFunction ? targetFunction : null);
return targetFunction.functionDetailsPromise().then(boundReleaseFunctionDetails);
}
/**
* @param {?WebInspector.RemoteObject} targetFunction
* @param {?WebInspector.DebuggerModel.FunctionDetails} functionDetails
* @return {?WebInspector.DebuggerModel.FunctionDetails}
*/
function releaseTargetFunction(targetFunction, functionDetails)
{
if (targetFunction)
targetFunction.release();
return functionDetails;
}
},
/**
* @return {!WebInspector.RemoteObject}
*/
object: function()
{
return this._object;
}
}
/**
* @constructor
* @extends {WebInspector.LocalJSONObject}
* @param {*} value
*/
WebInspector.MapEntryLocalJSONObject = function(value)
{
WebInspector.LocalJSONObject.call(this, value);
}
WebInspector.MapEntryLocalJSONObject.prototype = {
/**
* @override
* @return {string}
*/
get description()
{
if (!this._cachedDescription) {
var children = this._children();
this._cachedDescription = "{" + this._formatValue(children[0].value) + " => " + this._formatValue(children[1].value) + "}";
}
return this._cachedDescription;
},
__proto__: WebInspector.LocalJSONObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.Target} target
* @param {?WebInspector.NetworkRequest} request
* @param {string} url
* @param {string} documentURL
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
* @param {!WebInspector.ResourceType} type
* @param {string} mimeType
* @param {boolean=} isHidden
*/
WebInspector.Resource = function(target, request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
{
WebInspector.SDKObject.call(this, target);
this._request = request;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._type = type || WebInspector.resourceTypes.Other;
this._mimeType = mimeType;
this._isHidden = isHidden;
/** @type {?string} */ this._content;
/** @type {boolean} */ this._contentEncoded;
this._pendingContentCallbacks = [];
if (this._request && !this._request.finished)
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
}
/**
* @param {?string} content
* @param {string} mimeType
* @param {boolean} contentEncoded
* @param {?string=} charset
* @return {?string}
*/
WebInspector.Resource.contentAsDataURL = function(content, mimeType, contentEncoded, charset)
{
const maxDataUrlSize = 1024 * 1024;
if (content === null || content.length > maxDataUrlSize)
return null;
return "data:" + mimeType + (charset ? ";charset=" + charset : "") + (contentEncoded ? ";base64" : "") + "," + content;
}
/**
* @param {string} url
* @param {string} mimeType
* @param {!WebInspector.ContentProvider} contentProvider
* @param {!Element} image
*/
WebInspector.Resource.populateImageSource = function(url, mimeType, contentProvider, image)
{
/**
* @param {?string} content
*/
function onResourceContent(content)
{
var imageSrc = WebInspector.Resource.contentAsDataURL(content, mimeType, true);
if (imageSrc === null)
imageSrc = url;
image.src = imageSrc;
}
contentProvider.requestContent().then(onResourceContent);
}
WebInspector.Resource.prototype = {
/**
* @return {?WebInspector.NetworkRequest}
*/
get request()
{
return this._request;
},
/**
* @return {string}
*/
get url()
{
return this._url;
},
set url(x)
{
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
},
get parsedURL()
{
return this._parsedURL;
},
/**
* @return {string}
*/
get documentURL()
{
return this._documentURL;
},
/**
* @return {!PageAgent.FrameId}
*/
get frameId()
{
return this._frameId;
},
/**
* @return {!NetworkAgent.LoaderId}
*/
get loaderId()
{
return this._loaderId;
},
/**
* @return {string}
*/
get displayName()
{
return this._parsedURL.displayName;
},
/**
* @return {!WebInspector.ResourceType}
*/
resourceType: function()
{
return this._request ? this._request.resourceType() : this._type;
},
/**
* @return {string}
*/
get mimeType()
{
return this._request ? this._request.mimeType : this._mimeType;
},
/**
* @return {?string}
*/
get content()
{
return this._content;
},
/**
* @return {boolean}
*/
get contentEncoded()
{
return this._contentEncoded;
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._url;
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
if (this.resourceType() === WebInspector.resourceTypes.Document && this.mimeType.indexOf("javascript") !== -1)
return WebInspector.resourceTypes.Script;
return this.resourceType();
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
if (typeof this._content !== "undefined")
return Promise.resolve(this._content);
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this._pendingContentCallbacks.push(callback);
if (!this._request || this._request.finished)
this._innerRequestContent();
return promise;
},
/**
* @return {string}
*/
canonicalMimeType: function()
{
return this.contentType().canonicalMimeType() || this.mimeType;
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!DebuggerAgent.SearchMatch>} searchMatches
*/
function callbackWrapper(error, searchMatches)
{
callback(searchMatches || []);
}
if (this.frameId)
this.target().pageAgent().searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
else
callback([]);
},
/**
* @param {!Element} image
*/
populateImageSource: function(image)
{
WebInspector.Resource.populateImageSource(this._url, this._mimeType, this, image);
},
_requestFinished: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
},
_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;
/**
* @param {?Protocol.Error} error
* @param {?string} content
* @param {boolean} contentEncoded
* @this {WebInspector.Resource}
*/
function contentLoaded(error, content, contentEncoded)
{
if (error || content === null) {
replyWithContent.call(this, null, false);
return;
}
replyWithContent.call(this, content, contentEncoded);
}
/**
* @param {?string} content
* @param {boolean} contentEncoded
* @this {WebInspector.Resource}
*/
function replyWithContent(content, contentEncoded)
{
this._content = content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
/**
* @param {?Protocol.Error} error
* @param {string} content
* @param {boolean} contentEncoded
* @this {WebInspector.Resource}
*/
function resourceContentLoaded(error, content, contentEncoded)
{
contentLoaded.call(this, error, content, contentEncoded);
}
if (this.request) {
this.request.requestContent().then(requestContentLoaded.bind(this));
return;
}
/**
* @param {?string} content
* @this {WebInspector.Resource}
*/
function requestContentLoaded(content)
{
contentLoaded.call(this, null, content, this.request.contentEncoded);
}
this.target().pageAgent().getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
},
/**
* @return {boolean}
*/
isHidden: function()
{
return !!this._isHidden;
},
/**
* @return {boolean}
*/
hasTextContent: function()
{
if (this._type.isTextType())
return true;
if (this._type === WebInspector.resourceTypes.Other)
return !!this._content && !this._contentEncoded;
return false;
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 | 2 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.ResourceTreeModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.ResourceTreeModel, target);
target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
this._agent = target.pageAgent();
this._agent.enable();
this._fetchResourceTree();
target.registerPageDispatcher(new WebInspector.PageDispatcher(this));
this._securityOriginFrameCount = {};
this._inspectedPageURL = "";
this._pendingReloadOptions = null;
this._reloadSuspensionCount = 0;
}
WebInspector.ResourceTreeModel.EventTypes = {
FrameAdded: "FrameAdded",
FrameNavigated: "FrameNavigated",
FrameDetached: "FrameDetached",
FrameResized: "FrameResized",
FrameWillNavigate: "FrameWillNavigate",
MainFrameNavigated: "MainFrameNavigated",
ResourceAdded: "ResourceAdded",
WillLoadCachedResources: "WillLoadCachedResources",
CachedResourcesLoaded: "CachedResourcesLoaded",
DOMContentLoaded: "DOMContentLoaded",
Load: "Load",
PageReloadRequested: "PageReloadRequested",
WillReloadPage: "WillReloadPage",
InspectedURLChanged: "InspectedURLChanged",
SecurityOriginAdded: "SecurityOriginAdded",
SecurityOriginRemoved: "SecurityOriginRemoved",
ScreencastFrame: "ScreencastFrame",
ScreencastVisibilityChanged: "ScreencastVisibilityChanged",
ColorPicked: "ColorPicked"
}
/**
* @return {!Array.<!WebInspector.ResourceTreeFrame>}
*/
WebInspector.ResourceTreeModel.frames = function()
{
var result = [];
for (var target of WebInspector.targetManager.targets())
result = result.concat(Object.values(target.resourceTreeModel._frames));
return result;
}
/**
* @param {string} url
* @return {?WebInspector.Resource}
*/
WebInspector.ResourceTreeModel.resourceForURL = function(url)
{
for (var target of WebInspector.targetManager.targets()) {
var mainFrame = target.resourceTreeModel.mainFrame;
var result = mainFrame ? mainFrame.resourceForURL(url) : null;
if (result)
return result;
}
return null;
}
WebInspector.ResourceTreeModel.prototype = {
_fetchResourceTree: function()
{
/** @type {!Object.<string, !WebInspector.ResourceTreeFrame>} */
this._frames = {};
this._cachedResourcesProcessed = false;
this._agent.getResourceTree(this._processCachedResources.bind(this));
},
_processCachedResources: function(error, mainFramePayload)
{
if (error) {
this._cachedResourcesProcessed = true;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
return;
}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
this._inspectedPageURL = mainFramePayload.frame.url;
// Do not process SW resources.
if (this.target().isPage())
this._addFramesRecursively(null, mainFramePayload);
else
this._addSecurityOrigin(mainFramePayload.frame.securityOrigin);
this._dispatchInspectedURLChanged();
this._cachedResourcesProcessed = true;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
},
/**
* @return {string}
*/
inspectedPageURL: function()
{
return this._inspectedPageURL;
},
/**
* @return {string}
*/
inspectedPageDomain: function()
{
var parsedURL = this._inspectedPageURL ? this._inspectedPageURL.asParsedURL() : null;
return parsedURL ? parsedURL.host : "";
},
/**
* @return {boolean}
*/
cachedResourcesLoaded: function()
{
return this._cachedResourcesProcessed;
},
_dispatchInspectedURLChanged: function()
{
InspectorFrontendHost.inspectedURLChanged(this._inspectedPageURL);
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedPageURL);
},
/**
* @param {!WebInspector.ResourceTreeFrame} frame
* @param {boolean=} aboutToNavigate
*/
_addFrame: function(frame, aboutToNavigate)
{
this._frames[frame.id] = frame;
if (frame.isMainFrame())
this.mainFrame = frame;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
if (!aboutToNavigate)
this._addSecurityOrigin(frame.securityOrigin);
},
/**
* @param {string} securityOrigin
*/
_addSecurityOrigin: function(securityOrigin)
{
if (!this._securityOriginFrameCount[securityOrigin]) {
this._securityOriginFrameCount[securityOrigin] = 1;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, securityOrigin);
return;
}
this._securityOriginFrameCount[securityOrigin] += 1;
},
/**
* @param {string|undefined} securityOrigin
*/
_removeSecurityOrigin: function(securityOrigin)
{
if (typeof securityOrigin === "undefined")
return;
if (this._securityOriginFrameCount[securityOrigin] === 1) {
delete this._securityOriginFrameCount[securityOrigin];
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, securityOrigin);
return;
}
this._securityOriginFrameCount[securityOrigin] -= 1;
},
/**
* @return {!Array.<string>}
*/
securityOrigins: function()
{
return Object.keys(this._securityOriginFrameCount);
},
/**
* @param {!WebInspector.ResourceTreeFrame} mainFrame
*/
_handleMainFrameDetached: function(mainFrame)
{
/**
* @param {!WebInspector.ResourceTreeFrame} frame
* @this {WebInspector.ResourceTreeModel}
*/
function removeOriginForFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
removeOriginForFrame.call(this, frame.childFrames[i]);
if (!frame.isMainFrame())
this._removeSecurityOrigin(frame.securityOrigin);
}
removeOriginForFrame.call(this, mainFrame);
},
/**
* @param {!PageAgent.FrameId} frameId
* @param {?PageAgent.FrameId} parentFrameId
* @return {?WebInspector.ResourceTreeFrame}
*/
_frameAttached: function(frameId, parentFrameId)
{
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed && parentFrameId)
return null;
if (this._frames[frameId])
return null;
var parentFrame = parentFrameId ? this._frames[parentFrameId] : null;
var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, frameId);
if (frame.isMainFrame() && this.mainFrame) {
this._handleMainFrameDetached(this.mainFrame);
// Navigation to the new backend process.
this._frameDetached(this.mainFrame.id);
}
this._addFrame(frame, true);
return frame;
},
/**
* @param {!PageAgent.Frame} framePayload
*/
_frameNavigated: function(framePayload)
{
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed && framePayload.parentId)
return;
var frame = this._frames[framePayload.id];
if (!frame) {
// Simulate missed "frameAttached" for a main frame navigation to the new backend process.
console.assert(!framePayload.parentId, "Main frame shouldn't have parent frame id.");
frame = this._frameAttached(framePayload.id, framePayload.parentId || "");
console.assert(frame);
}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameWillNavigate, frame);
this._removeSecurityOrigin(frame.securityOrigin);
frame._navigate(framePayload);
var addedOrigin = frame.securityOrigin;
if (frame.isMainFrame())
this._inspectedPageURL = frame.url;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
if (frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
if (addedOrigin)
this._addSecurityOrigin(addedOrigin);
// Fill frame with retained resources (the ones loaded using new loader).
var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);
if (frame.isMainFrame())
this._dispatchInspectedURLChanged();
},
/**
* @param {!PageAgent.FrameId} frameId
*/
_frameDetached: function(frameId)
{
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed)
return;
var frame = this._frames[frameId];
if (!frame)
return;
this._removeSecurityOrigin(frame.securityOrigin);
if (frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);
else
frame._remove();
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestFinished: function(event)
{
if (!this._cachedResourcesProcessed)
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
if (request.failed || request.resourceType() === WebInspector.resourceTypes.XHR)
return;
var frame = this._frames[request.frameId];
if (frame)
frame._addRequest(request);
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestUpdateDropped: function(event)
{
if (!this._cachedResourcesProcessed)
return;
var frameId = event.data.frameId;
var frame = this._frames[frameId];
if (!frame)
return;
var url = event.data.url;
if (frame._resourcesMap[url])
return;
var resource = new WebInspector.Resource(this.target(), null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
frame.addResource(resource);
},
/**
* @param {!PageAgent.FrameId} frameId
* @return {!WebInspector.ResourceTreeFrame}
*/
frameForId: function(frameId)
{
return this._frames[frameId];
},
/**
* @param {function(!WebInspector.Resource)} callback
* @return {boolean}
*/
forAllResources: function(callback)
{
if (this.mainFrame)
return this.mainFrame._callForFrameResources(callback);
return false;
},
/**
* @return {!Array.<!WebInspector.ResourceTreeFrame>}
*/
frames: function()
{
return Object.values(this._frames);
},
/**
* @param {string} url
* @return {?WebInspector.Resource}
*/
resourceForURL: function(url)
{
// Workers call into this with no frames available.
return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
},
/**
* @param {?WebInspector.ResourceTreeFrame} parentFrame
* @param {!PageAgent.FrameResourceTree} frameTreePayload
*/
_addFramesRecursively: function(parentFrame, frameTreePayload)
{
var framePayload = frameTreePayload.frame;
var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload.id, framePayload);
this._addFrame(frame);
var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
if (frame.isMainFrame())
this._inspectedPageURL = frameResource.url;
frame.addResource(frameResource);
for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
for (var i = 0; i < frameTreePayload.resources.length; ++i) {
var subresource = frameTreePayload.resources[i];
var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
frame.addResource(resource);
}
},
/**
* @param {!PageAgent.Frame} frame
* @param {string} url
* @param {!WebInspector.ResourceType} type
* @param {string} mimeType
* @return {!WebInspector.Resource}
*/
_createResourceFromFramePayload: function(frame, url, type, mimeType)
{
return new WebInspector.Resource(this.target(), null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
},
suspendReload: function()
{
this._reloadSuspensionCount++;
},
resumeReload: function()
{
this._reloadSuspensionCount--;
console.assert(this._reloadSuspensionCount >= 0, "Unbalanced call to ResourceTreeModel.resumeReload()");
if (!this._reloadSuspensionCount && this._pendingReloadOptions)
this.reloadPage.apply(this, this._pendingReloadOptions);
},
/**
* @param {boolean=} bypassCache
* @param {string=} scriptToEvaluateOnLoad
*/
reloadPage: function(bypassCache, scriptToEvaluateOnLoad)
{
// Only dispatch PageReloadRequested upon first reload request to simplify client logic.
if (!this._pendingReloadOptions)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.PageReloadRequested);
if (this._reloadSuspensionCount) {
this._pendingReloadOptions = [bypassCache, scriptToEvaluateOnLoad];
return;
}
this._pendingReloadOptions = null;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage);
this._agent.reload(bypassCache, scriptToEvaluateOnLoad);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @param {!WebInspector.ResourceTreeModel} model
* @param {?WebInspector.ResourceTreeFrame} parentFrame
* @param {!PageAgent.FrameId} frameId
* @param {!PageAgent.Frame=} payload
*/
WebInspector.ResourceTreeFrame = function(model, parentFrame, frameId, payload)
{
this._model = model;
this._parentFrame = parentFrame;
this._id = frameId;
this._url = "";
if (payload) {
this._loaderId = payload.loaderId;
this._name = payload.name;
this._url = payload.url;
this._securityOrigin = payload.securityOrigin;
this._mimeType = payload.mimeType;
}
/**
* @type {!Array.<!WebInspector.ResourceTreeFrame>}
*/
this._childFrames = [];
/**
* @type {!Object.<string, !WebInspector.Resource>}
*/
this._resourcesMap = {};
if (this._parentFrame)
this._parentFrame._childFrames.push(this);
}
/**
* @param {!WebInspector.Script} script
* @return {?WebInspector.ResourceTreeFrame}
*/
WebInspector.ResourceTreeFrame.fromScript = function(script)
{
var executionContext = script.executionContext();
if (!executionContext || !executionContext.frameId)
return null;
return script.target().resourceTreeModel.frameForId(executionContext.frameId);
}
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
* @return {?WebInspector.ResourceTreeFrame}
*/
WebInspector.ResourceTreeFrame.fromStyleSheet = function(header)
{
return header.target().resourceTreeModel.frameForId(header.frameId);
}
/**
* @param {!WebInspector.Resource} resource
* @return {?WebInspector.ResourceTreeFrame}
*/
WebInspector.ResourceTreeFrame.fromResource = function(resource)
{
return resource.target().resourceTreeModel.frameForId(resource.frameId);
}
WebInspector.ResourceTreeFrame.prototype = {
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._model.target();
},
/**
* @return {string}
*/
get id()
{
return this._id;
},
/**
* @return {string}
*/
get name()
{
return this._name || "";
},
/**
* @return {string}
*/
get url()
{
return this._url;
},
/**
* @return {string}
*/
get securityOrigin()
{
return this._securityOrigin;
},
/**
* @return {string}
*/
get loaderId()
{
return this._loaderId;
},
/**
* @return {?WebInspector.ResourceTreeFrame}
*/
get parentFrame()
{
return this._parentFrame;
},
/**
* @return {!Array.<!WebInspector.ResourceTreeFrame>}
*/
get childFrames()
{
return this._childFrames;
},
/**
* @return {boolean}
*/
isMainFrame: function()
{
return !this._parentFrame;
},
/**
* @param {!PageAgent.Frame} framePayload
*/
_navigate: function(framePayload)
{
this._loaderId = framePayload.loaderId;
this._name = framePayload.name;
this._url = framePayload.url;
this._securityOrigin = framePayload.securityOrigin;
this._mimeType = framePayload.mimeType;
var mainResource = this._resourcesMap[this._url];
this._resourcesMap = {};
this._removeChildFrames();
if (mainResource && mainResource.loaderId === this._loaderId)
this.addResource(mainResource);
},
/**
* @return {!WebInspector.Resource}
*/
get mainResource()
{
return this._resourcesMap[this._url];
},
/**
* @param {!WebInspector.ResourceTreeFrame} frame
*/
_removeChildFrame: function(frame)
{
this._childFrames.remove(frame);
frame._remove();
},
_removeChildFrames: function()
{
var frames = this._childFrames;
this._childFrames = [];
for (var i = 0; i < frames.length; ++i)
frames[i]._remove();
},
_remove: function()
{
this._removeChildFrames();
delete this._model._frames[this.id];
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
},
/**
* @param {!WebInspector.Resource} resource
*/
addResource: function(resource)
{
if (this._resourcesMap[resource.url] === resource) {
// Already in the tree, we just got an extra update.
return;
}
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
},
/**
* @param {!WebInspector.NetworkRequest} request
* @return {!WebInspector.Resource}
*/
_addRequest: function(request)
{
var resource = this._resourcesMap[request.url];
if (resource && resource.request === request) {
// Already in the tree, we just got an extra update.
return resource;
}
resource = new WebInspector.Resource(this.target(), request, request.url, request.documentURL, request.frameId, request.loaderId, request.resourceType(), request.mimeType);
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
return resource;
},
/**
* @return {!Array.<!WebInspector.Resource>}
*/
resources: function()
{
var result = [];
for (var url in this._resourcesMap)
result.push(this._resourcesMap[url]);
return result;
},
/**
* @param {string} url
* @return {?WebInspector.Resource}
*/
resourceForURL: function(url)
{
var result;
function filter(resource)
{
if (resource.url === url) {
result = resource;
return true;
}
}
this._callForFrameResources(filter);
return result || null;
},
/**
* @param {function(!WebInspector.Resource)} callback
* @return {boolean}
*/
_callForFrameResources: function(callback)
{
for (var url in this._resourcesMap) {
if (callback(this._resourcesMap[url]))
return true;
}
for (var i = 0; i < this._childFrames.length; ++i) {
if (this._childFrames[i]._callForFrameResources(callback))
return true;
}
return false;
},
/**
* @return {string}
*/
displayName: function()
{
if (!this._parentFrame)
return WebInspector.UIString("top");
var subtitle = new WebInspector.ParsedURL(this._url).displayName;
if (subtitle) {
if (!this._name)
return subtitle;
return this._name + " (" + subtitle + ")";
}
return WebInspector.UIString("<iframe>");
}
}
/**
* @constructor
* @implements {PageAgent.Dispatcher}
*/
WebInspector.PageDispatcher = function(resourceTreeModel)
{
this._resourceTreeModel = resourceTreeModel;
}
WebInspector.PageDispatcher.prototype = {
/**
* @override
* @param {number} time
*/
domContentEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
},
/**
* @override
* @param {number} time
*/
loadEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.Load, time);
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
* @param {!PageAgent.FrameId} parentFrameId
*/
frameAttached: function(frameId, parentFrameId)
{
this._resourceTreeModel._frameAttached(frameId, parentFrameId);
},
/**
* @override
* @param {!PageAgent.Frame} frame
*/
frameNavigated: function(frame)
{
this._resourceTreeModel._frameNavigated(frame);
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
frameDetached: function(frameId)
{
this._resourceTreeModel._frameDetached(frameId);
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
frameStartedLoading: function(frameId)
{
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
frameStoppedLoading: function(frameId)
{
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
* @param {number} delay
*/
frameScheduledNavigation: function(frameId, delay)
{
},
/**
* @override
* @param {!PageAgent.FrameId} frameId
*/
frameClearedScheduledNavigation: function(frameId)
{
},
/**
* @override
*/
frameResized: function()
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameResized, null);
},
/**
* @override
* @param {string} message
* @param {string} dialogType
*/
javascriptDialogOpening: function(message, dialogType)
{
},
/**
* @override
* @param {boolean} result
*/
javascriptDialogClosed: function(result)
{
},
/**
* @override
* @param {string} data
* @param {!PageAgent.ScreencastFrameMetadata=} metadata
* @param {number=} sessionId
*/
screencastFrame: function(data, metadata, sessionId)
{
this._resourceTreeModel._agent.screencastFrameAck(sessionId);
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, { data: data, metadata: metadata });
},
/**
* @override
* @param {boolean} visible
*/
screencastVisibilityChanged: function(visible)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, { visible: visible });
},
/**
* @override
* @param {!DOMAgent.RGBA} color
*/
colorPicked: function(color)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ColorPicked, color);
},
/**
* @override
*/
interstitialShown: function()
{
// Frontend is not interested in interstitials.
},
/**
* @override
*/
interstitialHidden: function()
{
// Frontend is not interested in interstitials.
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | 2 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.RuntimeModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.RuntimeModel, target);
this._agent = target.runtimeAgent();
this.target().registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));
if (target.hasJSContext())
this._agent.enable();
/**
* @type {!Object.<number, !WebInspector.ExecutionContext>}
*/
this._executionContextById = {};
if (WebInspector.moduleSetting("customFormatters").get())
this._agent.setCustomObjectFormatterEnabled(true);
WebInspector.moduleSetting("customFormatters").addChangeListener(this._customFormattersStateChanged.bind(this));
}
WebInspector.RuntimeModel.Events = {
ExecutionContextCreated: "ExecutionContextCreated",
ExecutionContextDestroyed: "ExecutionContextDestroyed",
}
WebInspector.RuntimeModel._privateScript = "private script";
WebInspector.RuntimeModel.prototype = {
/**
* @return {!Array.<!WebInspector.ExecutionContext>}
*/
executionContexts: function()
{
return Object.values(this._executionContextById);
},
/**
* @param {!RuntimeAgent.ExecutionContextId} id
* @return {?WebInspector.ExecutionContext}
*/
executionContext: function(id)
{
return this._executionContextById[id] || null;
},
/**
* @param {!RuntimeAgent.ExecutionContextDescription} context
*/
_executionContextCreated: function(context)
{
// The private script context should be hidden behind an experiment.
if (context.name == WebInspector.RuntimeModel._privateScript && !context.origin && !Runtime.experiments.isEnabled("privateScriptInspection")) {
return;
}
var executionContext = new WebInspector.ExecutionContext(this.target(), context.id, context.name, context.origin, context.isDefault, context.frameId);
this._executionContextById[executionContext.id] = executionContext;
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextCreated, executionContext);
},
/**
* @param {number} executionContextId
*/
_executionContextDestroyed: function(executionContextId)
{
var executionContext = this._executionContextById[executionContextId];
if (!executionContext)
return;
delete this._executionContextById[executionContextId];
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, executionContext);
},
_executionContextsCleared: function()
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(this.target());
if (debuggerModel)
debuggerModel.globalObjectCleared();
var contexts = this.executionContexts();
this._executionContextById = {};
for (var i = 0; i < contexts.length; ++i)
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, contexts[i]);
},
/**
* @param {!RuntimeAgent.RemoteObject} payload
* @return {!WebInspector.RemoteObject}
*/
createRemoteObject: function(payload)
{
console.assert(typeof payload === "object", "Remote object payload should only be an object");
return new WebInspector.RemoteObjectImpl(this.target(), payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview, payload.customPreview);
},
/**
* @param {!RuntimeAgent.RemoteObject} payload
* @param {!WebInspector.ScopeRef} scopeRef
* @return {!WebInspector.RemoteObject}
*/
createScopeRemoteObject: function(payload, scopeRef)
{
return new WebInspector.ScopeRemoteObject(this.target(), payload.objectId, scopeRef, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
},
/**
* @param {number|string|boolean} value
* @return {!WebInspector.RemoteObject}
*/
createRemoteObjectFromPrimitiveValue: function(value)
{
return new WebInspector.RemoteObjectImpl(this.target(), undefined, typeof value, undefined, value);
},
/**
* @param {string} name
* @param {number|string|boolean} value
* @return {!WebInspector.RemoteObjectProperty}
*/
createRemotePropertyFromPrimitiveValue: function(name, value)
{
return new WebInspector.RemoteObjectProperty(name, this.createRemoteObjectFromPrimitiveValue(value));
},
/**
* @param {!WebInspector.Event} event
*/
_customFormattersStateChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
this._agent.setCustomObjectFormatterEnabled(enabled);
},
/**
* @param {string} expression
* @param {string} sourceURL
* @param {boolean} persistScript
* @param {number} executionContextId
* @param {function(!RuntimeAgent.ScriptId=, ?RuntimeAgent.ExceptionDetails=)=} callback
*/
compileScript: function(expression, sourceURL, persistScript, executionContextId, callback)
{
this._agent.compileScript(expression, sourceURL, persistScript, executionContextId, innerCallback);
/**
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.ScriptId=} scriptId
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
function innerCallback(error, scriptId, exceptionDetails)
{
if (error) {
console.error(error);
return;
}
if (callback)
callback(scriptId, exceptionDetails);
}
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {number} executionContextId
* @param {string=} objectGroup
* @param {boolean=} doNotPauseOnExceptionsAndMuteConsole
* @param {boolean=} includeCommandLineAPI
* @param {function(?RuntimeAgent.RemoteObject, ?RuntimeAgent.ExceptionDetails=)=} callback
*/
runScript: function(scriptId, executionContextId, objectGroup, doNotPauseOnExceptionsAndMuteConsole, includeCommandLineAPI, callback)
{
this._agent.runScript(scriptId, executionContextId, objectGroup, doNotPauseOnExceptionsAndMuteConsole, includeCommandLineAPI, innerCallback);
/**
* @param {?Protocol.Error} error
* @param {?RuntimeAgent.RemoteObject} result
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
function innerCallback(error, result, exceptionDetails)
{
if (error) {
console.error(error);
return;
}
if (callback)
callback(result, exceptionDetails);
}
},
/**
* @param {!RuntimeAgent.RemoteObject} payload
* @param {!Object=} hints
*/
_inspectRequested: function(payload, hints)
{
var object = this.createRemoteObject(payload);
if (object.isNode()) {
WebInspector.Revealer.revealPromise(object).then(object.release.bind(object));
return;
}
if (object.type === "function") {
WebInspector.RemoteFunction.objectAsFunction(object).targetFunctionDetails().then(didGetDetails);
return;
}
/**
* @param {?WebInspector.DebuggerModel.FunctionDetails} response
*/
function didGetDetails(response)
{
object.release();
if (!response || !response.location)
return;
WebInspector.Revealer.reveal(response.location);
}
if (hints.copyToClipboard)
InspectorFrontendHost.copyText(object.value);
object.release();
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @implements {RuntimeAgent.Dispatcher}
* @param {!WebInspector.RuntimeModel} runtimeModel
*/
WebInspector.RuntimeDispatcher = function(runtimeModel)
{
this._runtimeModel = runtimeModel;
}
WebInspector.RuntimeDispatcher.prototype = {
/**
* @override
* @param {!RuntimeAgent.ExecutionContextDescription} context
*/
executionContextCreated: function(context)
{
this._runtimeModel._executionContextCreated(context);
},
/**
* @override
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
*/
executionContextDestroyed: function(executionContextId)
{
this._runtimeModel._executionContextDestroyed(executionContextId);
},
/**
* @override
*/
executionContextsCleared: function()
{
this._runtimeModel._executionContextsCleared();
},
/**
* @override
* @param {!RuntimeAgent.RemoteObject} payload
* @param {!Object=} hints
*/
inspectRequested: function(payload, hints)
{
this._runtimeModel._inspectRequested(payload, hints);
}
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {number} id
* @param {string} name
* @param {string} origin
* @param {boolean} isDefault
* @param {string=} frameId
*/
WebInspector.ExecutionContext = function(target, id, name, origin, isDefault, frameId)
{
WebInspector.SDKObject.call(this, target);
this.id = id;
this.name = name;
this.origin = origin;
this.isDefault = isDefault;
this.runtimeModel = target.runtimeModel;
this.debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
this.frameId = frameId;
}
/**
* @param {!WebInspector.ExecutionContext} a
* @param {!WebInspector.ExecutionContext} b
* @return {number}
*/
WebInspector.ExecutionContext.comparator = function(a, b)
{
/**
* @param {!WebInspector.Target} target
* @return {number}
*/
function targetWeight(target)
{
if (target.isPage())
return 3;
if (target.isDedicatedWorker())
return 2;
return 1;
}
var weightDiff = targetWeight(a.target()) - targetWeight(b.target());
if (weightDiff)
return -weightDiff;
var frameIdDiff = String.hashCode(a.frameId) - String.hashCode(b.frameId);
if (frameIdDiff)
return frameIdDiff;
// Main world context should always go first.
if (a.isDefault)
return -1;
if (b.isDefault)
return +1;
return a.name.localeCompare(b.name);
}
WebInspector.ExecutionContext.prototype = {
/**
* @param {string} expression
* @param {string} objectGroup
* @param {boolean} includeCommandLineAPI
* @param {boolean} doNotPauseOnExceptionsAndMuteConsole
* @param {boolean} returnByValue
* @param {boolean} generatePreview
* @param {boolean} userGesture
* @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback
*/
evaluate: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, userGesture, callback)
{
// FIXME: It will be moved to separate ExecutionContext.
if (this.debuggerModel.selectedCallFrame()) {
this.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback);
return;
}
this._evaluateGlobal.apply(this, arguments);
},
/**
* @param {string} objectGroup
* @param {boolean} returnByValue
* @param {boolean} generatePreview
* @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback
*/
globalObject: function(objectGroup, returnByValue, generatePreview, callback)
{
this._evaluateGlobal("this", objectGroup, false, true, returnByValue, generatePreview, false, callback);
},
/**
* @param {string} expression
* @param {string} objectGroup
* @param {boolean} includeCommandLineAPI
* @param {boolean} doNotPauseOnExceptionsAndMuteConsole
* @param {boolean} returnByValue
* @param {boolean} generatePreview
* @param {boolean} userGesture
* @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback
*/
_evaluateGlobal: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, userGesture, callback)
{
if (!expression) {
// There is no expression, so the completion should happen against global properties.
expression = "this";
}
/**
* @this {WebInspector.ExecutionContext}
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
*/
function evalCallback(error, result, wasThrown, exceptionDetails)
{
if (error) {
console.error(error);
callback(null, false);
return;
}
if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result, exceptionDetails);
else
callback(this.runtimeModel.createRemoteObject(result), !!wasThrown, undefined, exceptionDetails);
}
this.target().runtimeAgent().evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this.id, returnByValue, generatePreview, userGesture, evalCallback.bind(this));
},
/**
* @param {string} expressionString
* @param {string} text
* @param {number} cursorOffset
* @param {string} prefix
* @param {boolean} force
* @param {function(!Array.<string>, number=)} completionsReadyCallback
*/
completionsForExpression: function(expressionString, text, cursorOffset, prefix, force, completionsReadyCallback)
{
var lastIndex = expressionString.length - 1;
var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");
if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);
if (expressionString && parseInt(expressionString, 10) == expressionString) {
// User is entering float value, do not suggest anything.
completionsReadyCallback([]);
return;
}
if (!prefix && !expressionString && !force) {
completionsReadyCallback([]);
return;
}
if (!expressionString && this.debuggerModel.selectedCallFrame())
this.debuggerModel.selectedCallFrame().variableNames(receivedPropertyNames.bind(this));
else
this.evaluate(expressionString, "completion", true, true, false, false, false, evaluated.bind(this));
/**
* @this {WebInspector.ExecutionContext}
*/
function evaluated(result, wasThrown)
{
if (!result || wasThrown) {
completionsReadyCallback([]);
return;
}
/**
* @param {string=} type
* @suppressReceiverCheck
* @this {WebInspector.ExecutionContext}
*/
function getCompletions(type)
{
var object;
if (type === "string")
object = new String("");
else if (type === "number")
object = new Number(0);
else if (type === "boolean")
object = new Boolean(false);
else
object = this;
var resultSet = {};
for (var o = object; o; o = o.__proto__) {
try {
if (type === "array" && o === object && ArrayBuffer.isView(o) && o.length > 9999)
continue;
var names = Object.getOwnPropertyNames(o);
var isArray = Array.isArray(o);
for (var i = 0; i < names.length; ++i) {
// Skip array elements indexes.
if (isArray && /^[0-9]/.test(names[i]))
continue;
resultSet[names[i]] = true;
}
} catch (e) {
}
}
return resultSet;
}
if (result.type === "object" || result.type === "function")
result.callFunctionJSON(getCompletions, [WebInspector.RemoteObject.toCallArgument(result.subtype)], receivedPropertyNames.bind(this));
else if (result.type === "string" || result.type === "number" || result.type === "boolean")
this.evaluate("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, false, false, receivedPropertyNamesFromEval.bind(this));
}
/**
* @param {?WebInspector.RemoteObject} notRelevant
* @param {boolean} wasThrown
* @param {?RuntimeAgent.RemoteObject=} result
* @this {WebInspector.ExecutionContext}
*/
function receivedPropertyNamesFromEval(notRelevant, wasThrown, result)
{
if (result && !wasThrown)
receivedPropertyNames.call(this, result.value);
else
completionsReadyCallback([]);
}
/**
* @this {WebInspector.ExecutionContext}
*/
function receivedPropertyNames(propertyNames)
{
this.target().runtimeAgent().releaseObjectGroup("completion");
if (!propertyNames) {
completionsReadyCallback([]);
return;
}
var includeCommandLineAPI = (!dotNotation && !bracketNotation);
if (includeCommandLineAPI) {
const commandLineAPI = ["dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear",
"getEventListeners", "debug", "undebug", "monitor", "unmonitor", "table", "$", "$$", "$x"];
for (var i = 0; i < commandLineAPI.length; ++i)
propertyNames[commandLineAPI[i]] = true;
}
this._reportCompletions(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, Object.keys(propertyNames));
}
},
/**
* @param {function(!Array.<string>, number=)} completionsReadyCallback
* @param {boolean} dotNotation
* @param {boolean} bracketNotation
* @param {string} expressionString
* @param {string} prefix
* @param {!Array.<string>} properties
*/
_reportCompletions: function(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, properties) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}
var results = [];
if (!expressionString) {
const keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in",
"instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with"];
properties = properties.concat(keywords);
}
properties.sort();
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
// Assume that all non-ASCII characters are letters and thus can be used as part of identifier.
if (dotNotation && !/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/.test(property))
continue;
if (bracketNotation) {
if (!/^[0-9]+$/.test(property))
property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
property += "]";
}
if (property.length < prefix.length)
continue;
if (prefix.length && !property.startsWith(prefix))
continue;
// Substitute actual newlines with newline characters. @see crbug.com/498421
results.push(property.split("\n").join("\\n"));
}
completionsReadyCallback(results);
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
* @param {string} type
* @param {boolean} useCapture
* @param {boolean} passive
* @param {?WebInspector.RemoteObject} handler
* @param {?WebInspector.RemoteObject} originalHandler
* @param {!WebInspector.DebuggerModel.Location} location
* @param {?WebInspector.RemoteObject} removeFunction
* @param {string=} listenerType
*/
WebInspector.EventListener = function(target, type, useCapture, passive, handler, originalHandler, location, removeFunction, listenerType)
{
WebInspector.SDKObject.call(this, target);
this._type = type;
this._useCapture = useCapture;
this._passive = passive;
this._handler = handler;
this._originalHandler = originalHandler || handler;
this._location = location;
var script = location.script();
this._sourceURL = script ? script.contentURL() : "";
this._removeFunction = removeFunction;
this._listenerType = listenerType || "normal";
}
WebInspector.EventListener.prototype = {
/**
* @return {string}
*/
type: function()
{
return this._type;
},
/**
* @return {boolean}
*/
useCapture: function()
{
return this._useCapture;
},
/**
* @return {boolean}
*/
passive: function()
{
return this._passive;
},
/**
* @return {?WebInspector.RemoteObject}
*/
handler: function()
{
return this._handler;
},
/**
* @return {!WebInspector.DebuggerModel.Location}
*/
location: function()
{
return this._location;
},
/**
* @return {string}
*/
sourceURL: function()
{
return this._sourceURL;
},
/**
* @return {?WebInspector.RemoteObject}
*/
originalHandler: function()
{
return this._originalHandler;
},
/**
* @return {?WebInspector.RemoteObject}
*/
removeFunction: function()
{
return this._removeFunction;
},
/**
* @return {!Promise<undefined>}
*/
remove: function()
{
if (!this._removeFunction)
return Promise.resolve();
return new Promise(promiseConstructor.bind(this));
/**
* @param {function()} success
* @this {WebInspector.EventListener}
*/
function promiseConstructor(success)
{
this._removeFunction.callFunction(callCustomRemove, [
WebInspector.RemoteObject.toCallArgument(this._removeFunction),
WebInspector.RemoteObject.toCallArgument(this._type),
WebInspector.RemoteObject.toCallArgument(this._originalHandler),
WebInspector.RemoteObject.toCallArgument(this._useCapture),
WebInspector.RemoteObject.toCallArgument(this._passive),
], success);
/**
* @param {function(string, function(), boolean, boolean)} func
* @param {string} type
* @param {function()} listener
* @param {boolean} useCapture
* @param {boolean} passive
*/
function callCustomRemove(func, type, listener, useCapture, passive)
{
func.call(null, type, listener, useCapture, passive);
}
}
},
/**
* @return {string}
*/
listenerType: function()
{
return this._listenerType;
},
/**
* @param {string} listenerType
*/
setListenerType: function(listenerType)
{
this._listenerType = listenerType;
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | 2 1 1 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {string} scriptId
* @param {string} sourceURL
* @param {number} startLine
* @param {number} startColumn
* @param {number} endLine
* @param {number} endColumn
* @param {!RuntimeAgent.ExecutionContextId} executionContextId
* @param {string} hash
* @param {boolean} isContentScript
* @param {boolean} isInternalScript
* @param {boolean} isLiveEdit
* @param {string=} sourceMapURL
* @param {boolean=} hasSourceURL
*/
WebInspector.Script = function(debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL)
{
WebInspector.SDKObject.call(this, debuggerModel.target());
this.debuggerModel = debuggerModel;
this.scriptId = scriptId;
this.sourceURL = sourceURL;
this.lineOffset = startLine;
this.columnOffset = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
this._executionContextId = executionContextId;
this.hash = hash;
this._isContentScript = isContentScript;
this._isInternalScript = isInternalScript;
this._isLiveEdit = isLiveEdit;
this.sourceMapURL = sourceMapURL;
this.hasSourceURL = hasSourceURL;
}
WebInspector.Script.Events = {
ScriptEdited: "ScriptEdited",
SourceMapURLAdded: "SourceMapURLAdded"
}
WebInspector.Script.sourceURLRegex = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
/**
* @param {string} source
* @return {string}
*/
WebInspector.Script._trimSourceURLComment = function(source)
{
var sourceURLIndex = source.lastIndexOf("//# sourceURL=");
if (sourceURLIndex === -1) {
sourceURLIndex = source.lastIndexOf("//@ sourceURL=");
if (sourceURLIndex === -1)
return source;
}
var sourceURLLineIndex = source.lastIndexOf("\n", sourceURLIndex);
if (sourceURLLineIndex === -1)
return source;
var sourceURLLine = source.substr(sourceURLLineIndex + 1).split("\n", 1)[0];
if (sourceURLLine.search(WebInspector.Script.sourceURLRegex) === -1)
return source;
return source.substr(0, sourceURLLineIndex) + source.substr(sourceURLLineIndex + sourceURLLine.length + 1);
}
WebInspector.Script.prototype = {
/**
* @return {boolean}
*/
isContentScript: function()
{
return this._isContentScript;
},
/**
* @return {boolean}
*/
isInternalScript: function()
{
return this._isInternalScript;
},
/**
* @return {?WebInspector.ExecutionContext}
*/
executionContext: function()
{
return this.target().runtimeModel.executionContext(this._executionContextId);
},
/**
* @return {boolean}
*/
isLiveEdit: function()
{
return this._isLiveEdit;
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this.sourceURL;
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return WebInspector.resourceTypes.Script;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
if (this._source)
return Promise.resolve(this._source);
if (!this.scriptId)
return Promise.resolve(/** @type {?string} */(""));
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this.target().debuggerAgent().getScriptSource(this.scriptId, didGetScriptSource.bind(this));
return promise;
/**
* @this {WebInspector.Script}
* @param {?Protocol.Error} error
* @param {string} source
*/
function didGetScriptSource(error, source)
{
this._source = WebInspector.Script._trimSourceURLComment(error ? "" : source);
callback(this._source);
}
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!DebuggerAgent.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!DebuggerAgent.SearchMatch>} searchMatches
*/
function innerCallback(error, searchMatches)
{
if (error) {
console.error(error);
callback([]);
return;
}
var result = [];
for (var i = 0; i < searchMatches.length; ++i) {
var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber, searchMatches[i].lineContent);
result.push(searchMatch);
}
callback(result || []);
}
if (this.scriptId) {
// Script failed to parse.
this.target().debuggerAgent().searchInContent(this.scriptId, query, caseSensitive, isRegex, innerCallback);
} else {
callback([]);
}
},
/**
* @param {string} source
* @return {string}
*/
_appendSourceURLCommentIfNeeded: function(source)
{
if (!this.hasSourceURL)
return source;
return source + "\n //# sourceURL=" + this.sourceURL;
},
/**
* @param {string} newSource
* @param {function(?Protocol.Error, !DebuggerAgent.SetScriptSourceError=, !Array.<!DebuggerAgent.CallFrame>=, !RuntimeAgent.StackTrace=, boolean=)} callback
*/
editSource: function(newSource, callback)
{
/**
* @this {WebInspector.Script}
* @param {?Protocol.Error} error
* @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
* @param {boolean=} stackChanged
* @param {!RuntimeAgent.StackTrace=} asyncStackTrace
* @param {!DebuggerAgent.SetScriptSourceError=} compileError
*/
function didEditScriptSource(error, callFrames, stackChanged, asyncStackTrace, compileError)
{
if (!error && !compileError)
this._source = newSource;
var needsStepIn = !!stackChanged;
callback(error, compileError, callFrames, asyncStackTrace, needsStepIn);
}
newSource = WebInspector.Script._trimSourceURLComment(newSource);
// We append correct sourceURL to script for consistency only. It's not actually needed for things to work correctly.
newSource = this._appendSourceURLCommentIfNeeded(newSource);
if (this.scriptId)
this.target().debuggerAgent().setScriptSource(this.scriptId, newSource, undefined, didEditScriptSource.bind(this));
else
callback("Script failed to parse");
},
/**
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {!WebInspector.DebuggerModel.Location}
*/
rawLocation: function(lineNumber, columnNumber)
{
return new WebInspector.DebuggerModel.Location(this.debuggerModel, this.scriptId, lineNumber, columnNumber || 0);
},
/**
* @return {boolean}
*/
isInlineScript: function()
{
var startsAtZero = !this.lineOffset && !this.columnOffset;
return !!this.sourceURL && !startsAtZero;
},
/**
* @param {string} sourceMapURL
*/
addSourceMapURL: function(sourceMapURL)
{
if (this.sourceMapURL)
return;
this.sourceMapURL = sourceMapURL;
this.dispatchEventToListeners(WebInspector.Script.Events.SourceMapURLAdded, this.sourceMapURL);
},
/**
* @return {boolean}
*/
isAnonymousScript: function()
{
return !this.sourceURL;
},
/**
* @return {boolean}
*/
isInlineScriptWithSourceURL: function()
{
return !!this.hasSourceURL && this.isInlineScript();
},
/**
* @param {!Array<!DebuggerAgent.ScriptPosition>} positions
* @return {!Promise<boolean>}
*/
setBlackboxedRanges: function(positions)
{
return new Promise(setBlackboxedRanges.bind(this));
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
* @this {WebInspector.Script}
*/
function setBlackboxedRanges(fulfill, reject)
{
this.target().debuggerAgent().setBlackboxedRanges(this.scriptId, positions, callback);
/**
* @param {?Protocol.Error} error
*/
function callback(error)
{
if (error)
console.error(error);
fulfill(!error);
}
}
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | 2 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Invariant: This model can only be constructed on a ServiceWorker target.
* @constructor
* @extends {WebInspector.SDKModel}
*/
WebInspector.ServiceWorkerCacheModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.ServiceWorkerCacheModel, target);
/** @type {!Map<string, !WebInspector.ServiceWorkerCacheModel.Cache>} */
this._caches = new Map();
this._agent = target.cacheStorageAgent();
/** @type {boolean} */
this._enabled = false;
}
WebInspector.ServiceWorkerCacheModel.EventTypes = {
CacheAdded: "CacheAdded",
CacheRemoved: "CacheRemoved"
}
WebInspector.ServiceWorkerCacheModel.prototype = {
enable: function()
{
if (this._enabled)
return;
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
this._enabled = true;
},
refreshCacheNames: function()
{
var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var securityOrigin of securityOrigins)
this._loadCacheNames(securityOrigin);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
deleteCache: function(cache)
{
/**
* @this {WebInspector.ServiceWorkerCacheModel}
*/
function callback(error)
{
if (error) {
console.error("ServiceWorkerCacheAgent error deleting cache ", cache.toString(), ": ", error);
return;
}
this._caches.delete(cache.cacheId);
this._cacheRemoved(cache);
}
this._agent.deleteCache(cache.cacheId, callback.bind(this));
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @param {string} request
* @param {function()} callback
*/
deleteCacheEntry: function(cache, request, callback)
{
/**
* @param {?Protocol.Error} error
*/
function myCallback(error)
{
if (error) {
WebInspector.console.error(WebInspector.UIString("ServiceWorkerCacheAgent error deleting cache entry %s in cache: %s", cache.toString(), error));
return;
}
callback();
}
this._agent.deleteEntry(cache.cacheId, request, myCallback);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.ServiceWorkerCacheModel.Entry>, boolean)} callback
*/
loadCacheData: function(cache, skipCount, pageSize, callback)
{
this._requestEntries(cache, skipCount, pageSize, callback);
},
/**
* @return {!Array.<!WebInspector.ServiceWorkerCacheModel.Cache>}
*/
caches: function()
{
var caches = new Array();
for (var cache of this._caches.values())
caches.push(cache);
return caches;
},
dispose: function()
{
for (var cache of this._caches.values())
this._cacheRemoved(cache);
this._caches.clear();
if (this._enabled) {
this.target().resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
this.target().resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
}
},
_addOrigin: function(securityOrigin)
{
this._loadCacheNames(securityOrigin);
},
/**
* @param {string} securityOrigin
*/
_removeOrigin: function(securityOrigin)
{
for (var opaqueId of this._caches.keys()) {
var cache = this._caches.get(opaqueId);
if (cache.securityOrigin == securityOrigin) {
this._caches.delete(opaqueId);
this._cacheRemoved(cache);
}
}
},
/**
* @param {string} securityOrigin
*/
_loadCacheNames: function(securityOrigin)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!WebInspector.ServiceWorkerCacheModel.Cache>} caches
* @this {WebInspector.ServiceWorkerCacheModel}
*/
function callback(error, caches)
{
if (error) {
console.error("ServiceWorkerCacheAgent error while loading caches: ", error);
return;
}
this._updateCacheNames(securityOrigin, caches);
}
this._agent.requestCacheNames(securityOrigin, callback.bind(this));
},
/**
* @param {string} securityOrigin
* @param {!Array} cachesJson
*/
_updateCacheNames: function(securityOrigin, cachesJson)
{
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @this {WebInspector.ServiceWorkerCacheModel}
*/
function deleteAndSaveOldCaches(cache)
{
if (cache.securityOrigin == securityOrigin && !updatingCachesIds.has(cache.cacheId)) {
oldCaches.set(cache.cacheId, cache);
this._caches.delete(cache.cacheId);
}
}
/** @type {!Set<string>} */
var updatingCachesIds = new Set();
/** @type {!Map<string, !WebInspector.ServiceWorkerCacheModel.Cache>} */
var newCaches = new Map();
/** @type {!Map<string, !WebInspector.ServiceWorkerCacheModel.Cache>} */
var oldCaches = new Map();
for (var cacheJson of cachesJson) {
var cache = new WebInspector.ServiceWorkerCacheModel.Cache(cacheJson.securityOrigin, cacheJson.cacheName, cacheJson.cacheId);
updatingCachesIds.add(cache.cacheId);
if (this._caches.has(cache.cacheId))
continue;
newCaches.set(cache.cacheId, cache);
this._caches.set(cache.cacheId, cache);
}
this._caches.forEach(deleteAndSaveOldCaches, this);
newCaches.forEach(this._cacheAdded, this);
oldCaches.forEach(this._cacheRemoved, this);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginAdded: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
this._addOrigin(securityOrigin);
},
/**
* @param {!WebInspector.Event} event
*/
_securityOriginRemoved: function(event)
{
var securityOrigin = /** @type {string} */ (event.data);
this._removeOrigin(securityOrigin);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
_cacheAdded: function(cache)
{
this.dispatchEventToListeners(WebInspector.ServiceWorkerCacheModel.EventTypes.CacheAdded, cache);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
*/
_cacheRemoved: function(cache)
{
this.dispatchEventToListeners(WebInspector.ServiceWorkerCacheModel.EventTypes.CacheRemoved, cache);
},
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.ServiceWorkerCacheModel.Entry>, boolean)} callback
*/
_requestEntries: function(cache, skipCount, pageSize, callback)
{
/**
* @param {?Protocol.Error} error
* @param {!Array.<!WebInspector.ServiceWorkerCacheModel.Entry>} dataEntries
* @param {boolean} hasMore
*/
function innerCallback(error, dataEntries, hasMore)
{
if (error) {
console.error("ServiceWorkerCacheAgent error while requesting entries: ", error);
return;
}
var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
entries.push(new WebInspector.ServiceWorkerCacheModel.Entry(dataEntries[i].request, dataEntries[i].response));
}
callback(entries, hasMore);
}
this._agent.requestEntries(cache.cacheId, skipCount, pageSize, innerCallback);
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @param {string} request
* @param {string} response
*/
WebInspector.ServiceWorkerCacheModel.Entry = function(request, response)
{
this.request = request;
this.response = response;
}
/**
* @constructor
* @param {string} securityOrigin
* @param {string} cacheName
* @param {string} cacheId
*/
WebInspector.ServiceWorkerCacheModel.Cache = function(securityOrigin, cacheName, cacheId)
{
this.securityOrigin = securityOrigin;
this.cacheName = cacheName;
this.cacheId = cacheId;
}
WebInspector.ServiceWorkerCacheModel.Cache.prototype = {
/**
* @param {!WebInspector.ServiceWorkerCacheModel.Cache} cache
* @return {boolean}
*/
equals: function(cache)
{
return this.cacheId == cache.cacheId;
},
/**
* @override
* @return {string}
*/
toString: function()
{
return this.securityOrigin + this.cacheName;
}
}
WebInspector.ServiceWorkerCacheModel._symbol = Symbol("CacheStorageModel");
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.ServiceWorkerCacheModel}
*/
WebInspector.ServiceWorkerCacheModel.fromTarget = function(target)
{
if (!target[WebInspector.ServiceWorkerCacheModel._symbol])
target[WebInspector.ServiceWorkerCacheModel._symbol] = new WebInspector.ServiceWorkerCacheModel(target);
return target[WebInspector.ServiceWorkerCacheModel._symbol];
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 | 2 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
*/
WebInspector.ServiceWorkerManager = function(target)
{
WebInspector.SDKObject.call(this, target);
target.registerServiceWorkerDispatcher(new WebInspector.ServiceWorkerDispatcher(this));
this._lastAnonymousTargetId = 0;
this._agent = target.serviceWorkerAgent();
/** @type {!Map.<string, !WebInspector.ServiceWorker>} */
this._workers = new Map();
/** @type {!Map.<string, !WebInspector.ServiceWorkerRegistration>} */
this._registrations = new Map();
this.enable();
this._forceUpdateSetting = WebInspector.settings.createSetting("serviceWorkerUpdateOnReload", false);
if (this._forceUpdateSetting.get())
this._forceUpdateSettingChanged();
this._forceUpdateSetting.addChangeListener(this._forceUpdateSettingChanged, this);
}
WebInspector.ServiceWorkerManager.Events = {
WorkersUpdated: "WorkersUpdated",
RegistrationUpdated: "RegistrationUpdated",
RegistrationDeleted: "RegistrationDeleted"
}
WebInspector.ServiceWorkerManager.prototype = {
enable: function()
{
if (this._enabled)
return;
this._enabled = true;
this._agent.enable();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNavigated, this);
},
disable: function()
{
if (!this._enabled)
return;
this._enabled = false;
for (var worker of this._workers.values())
worker._connection.close();
this._workers.clear();
this._registrations.clear();
this._agent.disable();
WebInspector.targetManager.removeEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNavigated, this);
},
/**
* @return {!Iterable.<!WebInspector.ServiceWorker>}
*/
workers: function()
{
return this._workers.values();
},
/**
* @return {boolean}
*/
hasWorkers: function()
{
return !!this._workers.size;
},
/**
* @return {!Map.<string, !WebInspector.ServiceWorkerRegistration>}
*/
registrations: function()
{
return this._registrations;
},
/**
* @param {string} versionId
* @return {?WebInspector.ServiceWorkerVersion}
*/
findVersion: function(versionId)
{
for (var registration of this.registrations().values()) {
var version = registration.versions.get(versionId);
if (version)
return version;
}
return null;
},
/**
* @param {string} registrationId
*/
deleteRegistration: function(registrationId)
{
var registration = this._registrations.get(registrationId);
if (!registration)
return;
if (registration._isRedundant()) {
this._registrations.delete(registrationId);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted, registration);
return;
}
registration._deleting = true;
for (var version of registration.versions.values())
this.stopWorker(version.id);
this._unregister(registration.scopeURL);
},
/**
* @param {string} registrationId
*/
updateRegistration: function(registrationId)
{
var registration = this._registrations.get(registrationId);
if (!registration)
return;
this._agent.updateRegistration(registration.scopeURL);
},
/**
* @param {string} registrationId
* @param {string} data
*/
deliverPushMessage: function(registrationId, data)
{
var registration = this._registrations.get(registrationId);
if (!registration)
return;
var origin = WebInspector.ParsedURL.splitURLIntoPathComponents(registration.scopeURL)[0];
this._agent.deliverPushMessage(origin, registrationId, data);
},
/**
* @param {!ServiceWorkerAgent.TargetID} targetId
*/
activateTarget: function(targetId)
{
this._agent.activateTarget(targetId);
},
/**
* @param {string} scope
*/
_unregister: function(scope)
{
this._agent.unregister(scope);
},
/**
* @param {string} scope
*/
startWorker: function(scope)
{
this._agent.startWorker(scope);
},
/**
* @param {string} versionId
*/
stopWorker: function(versionId)
{
this._agent.stopWorker(versionId);
},
/**
* @param {string} versionId
*/
inspectWorker: function(versionId)
{
this._agent.inspectWorker(versionId);
},
/**
* @param {!ServiceWorkerAgent.TargetID} targetId
* @param {function(?WebInspector.TargetInfo)=} callback
*/
getTargetInfo: function(targetId, callback)
{
/**
* @param {?Protocol.Error} error
* @param {?ServiceWorkerAgent.TargetInfo} targetInfo
*/
function innerCallback(error, targetInfo)
{
if (error) {
console.error(error);
callback(null);
return;
}
if (targetInfo)
callback(new WebInspector.TargetInfo(targetInfo));
else
callback(null)
}
this._agent.getTargetInfo(targetId, innerCallback);
},
/**
* @param {string} workerId
* @param {string} url
* @param {string} versionId
*/
_workerCreated: function(workerId, url, versionId)
{
new WebInspector.ServiceWorker(this, workerId, url, versionId);
},
/**
* @param {string} workerId
*/
_workerTerminated: function(workerId)
{
var worker = this._workers.get(workerId);
if (!worker)
return;
worker._closeConnection();
this._workers.delete(workerId);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.WorkersUpdated);
},
/**
* @param {string} workerId
* @param {string} message
*/
_dispatchMessage: function(workerId, message)
{
var worker = this._workers.get(workerId);
if (worker)
worker._connection.dispatch(message);
},
/**
* @param {!Array.<!ServiceWorkerAgent.ServiceWorkerRegistration>} registrations
*/
_workerRegistrationUpdated: function(registrations)
{
for (var payload of registrations) {
var registration = this._registrations.get(payload.registrationId);
if (!registration) {
registration = new WebInspector.ServiceWorkerRegistration(payload);
this._registrations.set(payload.registrationId, registration);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, registration);
continue;
}
registration._update(payload);
if (registration._shouldBeRemoved()) {
this._registrations.delete(registration.id);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted, registration);
} else {
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, registration);
}
}
},
/**
* @param {!Array.<!ServiceWorkerAgent.ServiceWorkerVersion>} versions
*/
_workerVersionUpdated: function(versions)
{
/** @type {!Set.<!WebInspector.ServiceWorkerRegistration>} */
var registrations = new Set();
for (var payload of versions) {
var registration = this._registrations.get(payload.registrationId);
if (!registration)
continue;
registration._updateVersion(payload);
registrations.add(registration);
}
for (var registration of registrations) {
if (registration._shouldBeRemoved()) {
this._registrations.delete(registration.id);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted, registration);
} else {
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, registration);
}
}
},
/**
* @param {!ServiceWorkerAgent.ServiceWorkerErrorMessage} payload
*/
_workerErrorReported: function(payload)
{
var registration = this._registrations.get(payload.registrationId);
if (!registration)
return;
registration._addError(payload);
this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated, registration);
},
/**
* @param {!WebInspector.Event} event
*/
_mainFrameNavigated: function(event)
{
// Attach to the new worker set.
},
/**
* @return {!WebInspector.Setting}
*/
forceUpdateOnReloadSetting: function()
{
return this._forceUpdateSetting;
},
_forceUpdateSettingChanged: function()
{
this._agent.setForceUpdateOnPageLoad(this._forceUpdateSetting.get());
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {string} workerId
* @param {string} url
* @param {string} versionId
*/
WebInspector.ServiceWorker = function(manager, workerId, url, versionId)
{
this._manager = manager;
this._agent = manager.target().serviceWorkerAgent();
this._workerId = workerId;
this._connection = new WebInspector.ServiceWorkerConnection(this._agent, workerId);
this._url = url;
this._versionId = versionId;
var parsedURL = url.asParsedURL();
this._name = parsedURL ? parsedURL.lastPathComponentWithFragment() : "#" + (++WebInspector.ServiceWorker._lastAnonymousTargetId);
this._scope = parsedURL.host + parsedURL.folderPathComponents;
this._manager._workers.set(workerId, this);
this._target = WebInspector.targetManager.createTarget(this._name, WebInspector.Target.Type.ServiceWorker, this._connection, manager.target());
this._manager.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.WorkersUpdated);
this._target.runtimeAgent().run();
}
WebInspector.ServiceWorker._lastAnonymousTargetId = 0;
WebInspector.ServiceWorker.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {string}
*/
url: function()
{
return this._url;
},
/**
* @return {string}
*/
versionId: function()
{
return this._versionId;
},
/**
* @return {string}
*/
scope: function()
{
return this._scope;
},
stop: function()
{
this._agent.stop(this._workerId);
},
_closeConnection: function()
{
this._connection._close();
delete this._connection;
}
}
/**
* @constructor
* @implements {ServiceWorkerAgent.Dispatcher}
* @param {!WebInspector.ServiceWorkerManager} manager
*/
WebInspector.ServiceWorkerDispatcher = function(manager)
{
this._manager = manager;
}
WebInspector.ServiceWorkerDispatcher.prototype = {
/**
* @override
* @param {string} workerId
* @param {string} url
* @param {string} versionId
*/
workerCreated: function(workerId, url, versionId)
{
this._manager._workerCreated(workerId, url, versionId);
},
/**
* @override
* @param {string} workerId
*/
workerTerminated: function(workerId)
{
this._manager._workerTerminated(workerId);
},
/**
* @override
* @param {string} workerId
* @param {string} message
*/
dispatchMessage: function(workerId, message)
{
this._manager._dispatchMessage(workerId, message);
},
/**
* @override
* @param {!Array.<!ServiceWorkerAgent.ServiceWorkerRegistration>} registrations
*/
workerRegistrationUpdated: function(registrations)
{
this._manager._workerRegistrationUpdated(registrations);
},
/**
* @override
* @param {!Array.<!ServiceWorkerAgent.ServiceWorkerVersion>} versions
*/
workerVersionUpdated: function(versions)
{
this._manager._workerVersionUpdated(versions);
},
/**
* @override
* @param {!ServiceWorkerAgent.ServiceWorkerErrorMessage} errorMessage
*/
workerErrorReported: function(errorMessage)
{
this._manager._workerErrorReported(errorMessage);
}
}
/**
* @constructor
* @extends {InspectorBackendClass.Connection}
* @param {!Protocol.ServiceWorkerAgent} agent
* @param {string} workerId
*/
WebInspector.ServiceWorkerConnection = function(agent, workerId)
{
InspectorBackendClass.Connection.call(this);
//FIXME: remove resourceTreeModel and others from worker targets
this.suppressErrorsForDomains(["Worker", "Page", "CSS", "DOM", "DOMStorage", "Database", "Network", "IndexedDB"]);
this._agent = agent;
this._workerId = workerId;
}
WebInspector.ServiceWorkerConnection.prototype = {
/**
* @override
* @param {!Object} messageObject
*/
sendMessage: function(messageObject)
{
this._agent.sendMessage(this._workerId, JSON.stringify(messageObject));
},
_close: function()
{
this.connectionClosed("worker_terminated");
},
__proto__: InspectorBackendClass.Connection.prototype
}
/**
* @constructor
* @param {!ServiceWorkerAgent.TargetInfo} payload
*/
WebInspector.TargetInfo = function(payload)
{
this.id = payload.id;
this.type = payload.type;
this.title = payload.title;
this.url = payload.url;
}
WebInspector.TargetInfo.prototype = {
/**
* @return {boolean}
*/
isWebContents: function()
{
return this.type == "web_contents";
},
/**
* @return {boolean}
*/
isFrame: function()
{
return this.type == "frame";
},
}
/**
* @constructor
* @param {!ServiceWorkerAgent.ServiceWorkerErrorMessage} payload
*/
WebInspector.ServiceWorkerErrorMessage = function(payload)
{
this.errorMessage = payload.errorMessage;
this.sourceURL = payload.sourceURL;
this.lineNumber = payload.lineNumber;
this.columnNumber = payload.columnNumber;
}
/**
* @constructor
* @param {!WebInspector.ServiceWorkerRegistration} registration
* @param {!ServiceWorkerAgent.ServiceWorkerVersion} payload
*/
WebInspector.ServiceWorkerVersion = function(registration, payload)
{
this.registration = registration;
this._update(payload);
/** @type {!Array<!WebInspector.ServiceWorkerErrorMessage>} */
this.errorMessages = [];
}
/**
* @enum {string}
*/
WebInspector.ServiceWorkerVersion.Modes = {
Installing: "installing",
Waiting: "waiting",
Active: "active",
Redundant: "redundant"
}
WebInspector.ServiceWorkerVersion.prototype = {
/**
* @param {!ServiceWorkerAgent.ServiceWorkerVersion} payload
*/
_update: function(payload)
{
this.id = payload.versionId;
this.scriptURL = payload.scriptURL;
this.runningStatus = payload.runningStatus;
this.status = payload.status;
this.scriptLastModified = payload.scriptLastModified;
this.scriptResponseTime = payload.scriptResponseTime;
this.controlledClients = []
for (var i = 0; i < payload.controlledClients.length; ++i) {
this.controlledClients.push(payload.controlledClients[i]);
}
},
/**
* @return {boolean}
*/
isStartable: function()
{
return !this.registration.isDeleted && this.isActivated() && this.isStopped();
},
/**
* @return {boolean}
*/
isStoppedAndRedundant: function()
{
return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped && this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
},
/**
* @return {boolean}
*/
isStopped: function()
{
return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped;
},
/**
* @return {boolean}
*/
isStarting: function()
{
return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Starting;
},
/**
* @return {boolean}
*/
isRunning: function()
{
return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Running;
},
/**
* @return {boolean}
*/
isStopping: function()
{
return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopping;
},
/**
* @return {boolean}
*/
isNew: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.New;
},
/**
* @return {boolean}
*/
isInstalling: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Installing;
},
/**
* @return {boolean}
*/
isInstalled: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Installed;
},
/**
* @return {boolean}
*/
isActivating: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Activating;
},
/**
* @return {boolean}
*/
isActivated: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Activated;
},
/**
* @return {boolean}
*/
isRedundant: function()
{
return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
},
/**
* @return {string}
*/
mode: function()
{
if (this.isNew() || this.isInstalling())
return WebInspector.ServiceWorkerVersion.Modes.Installing;
else if (this.isInstalled())
return WebInspector.ServiceWorkerVersion.Modes.Waiting;
else if (this.isActivating() || this.isActivated())
return WebInspector.ServiceWorkerVersion.Modes.Active;
return WebInspector.ServiceWorkerVersion.Modes.Redundant;
},
/**
* @param {!ServiceWorkerAgent.ServiceWorkerErrorMessage} payload
*/
_addError: function(payload)
{
this.errorMessages.push(new WebInspector.ServiceWorkerErrorMessage(payload));
}
}
/**
* @constructor
* @param {!ServiceWorkerAgent.ServiceWorkerRegistration} payload
*/
WebInspector.ServiceWorkerRegistration = function(payload)
{
this._update(payload);
/** @type {!Map.<string, !WebInspector.ServiceWorkerVersion>} */
this.versions = new Map();
this._deleting = false;
}
WebInspector.ServiceWorkerRegistration.prototype = {
/**
* @param {!ServiceWorkerAgent.ServiceWorkerRegistration} payload
*/
_update: function(payload)
{
this.id = payload.registrationId;
this.scopeURL = payload.scopeURL;
this.isDeleted = payload.isDeleted;
this.forceUpdateOnPageLoad = payload.forceUpdateOnPageLoad;
},
/**
* @param {!ServiceWorkerAgent.ServiceWorkerVersion} payload
* @return {!WebInspector.ServiceWorkerVersion}
*/
_updateVersion: function(payload)
{
var version = this.versions.get(payload.versionId);
if (!version) {
version = new WebInspector.ServiceWorkerVersion(this, payload);
this.versions.set(payload.versionId, version);
return version;
}
version._update(payload);
return version;
},
/**
* @param {!ServiceWorkerAgent.ServiceWorkerErrorMessage} payload
*/
_addError: function(payload)
{
var version = this.versions.get(payload.versionId);
if (version)
version._addError(payload);
},
/**
* @return {boolean}
*/
_isRedundant: function()
{
for (var version of this.versions.values()) {
if (!version.isStoppedAndRedundant())
return false;
}
return true;
},
/**
* @return {boolean}
*/
_hasErrorLog: function()
{
for (var version of this.versions.values()) {
if (version.errorMessages.length)
return true;
}
return false;
},
/**
* @return {boolean}
*/
_shouldBeRemoved: function()
{
return this._isRedundant() && (!this._hasErrorLog() || this._deleting);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | 1 2 2 2 1 1 1 1 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ function SourceMapV3() { /** @type {number} */ this.version; /** @type {string|undefined} */ this.file; /** @type {!Array.<string>} */ this.sources; /** @type {!Array.<!SourceMapV3.Section>|undefined} */ this.sections; /** @type {string} */ this.mappings; /** @type {string|undefined} */ this.sourceRoot; /** @type {!Array.<string>|undefined} */ this.names; } /** * @constructor */ SourceMapV3.Section = function() { /** @type {!SourceMapV3} */ this.map; /** @type {!SourceMapV3.Offset} */ this.offset; } /** * @constructor */ SourceMapV3.Offset = function() { /** @type {number} */ this.line; /** @type {number} */ this.column; } /** * @constructor * @param {number} lineNumber * @param {number} columnNumber * @param {string=} sourceURL * @param {number=} sourceLineNumber * @param {number=} sourceColumnNumber * @param {string=} name */ WebInspector.SourceMapEntry = function(lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber, name) { this.lineNumber = lineNumber; this.columnNumber = columnNumber; this.sourceURL = sourceURL; this.sourceLineNumber = sourceLineNumber; this.sourceColumnNumber = sourceColumnNumber; this.name = name; } /** * @interface */ WebInspector.SourceMap = function() { } WebInspector.SourceMap.prototype = { /** * @return {string} */ compiledURL: function() { }, /** * @return {string} */ url: function() { }, /** * @return {!Array<string>} */ sourceURLs: function() { }, /** * @param {string} sourceURL * @param {!WebInspector.ResourceType} contentType * @return {!WebInspector.ContentProvider} */ sourceContentProvider: function(sourceURL, contentType) { }, /** * @param {number} lineNumber in compiled resource * @param {number} columnNumber in compiled resource * @return {?WebInspector.SourceMapEntry} */ findEntry: function(lineNumber, columnNumber) { }, /** * @return {boolean} */ editable: function() { }, /** * @param {!Array<!WebInspector.TextRange>} ranges * @param {!Array<string>} texts * @return {!Promise<?WebInspector.SourceMap.EditResult>} */ editCompiled: function(ranges, texts) { }, } /** * @constructor * @param {!WebInspector.SourceMap} map * @param {!Array<!WebInspector.SourceEdit>} compiledEdits * @param {!Map<string, string>} newSources */ WebInspector.SourceMap.EditResult = function(map, compiledEdits, newSources) { this.map = map; this.compiledEdits = compiledEdits; this.newSources = newSources; } /** * @interface */ WebInspector.SourceMapFactory = function() { } WebInspector.SourceMapFactory.prototype = { /** * @param {!WebInspector.Target} target * @param {!WebInspector.SourceMap} sourceMap * @return {!Promise<?WebInspector.SourceMap>} */ editableSourceMap: function(target, sourceMap) { }, } /** * Implements Source Map V3 model. See https://github.com/google/closure-compiler/wiki/Source-Maps * for format description. * @constructor * @implements {WebInspector.SourceMap} * @param {string} compiledURL * @param {string} sourceMappingURL * @param {!SourceMapV3} payload */ WebInspector.TextSourceMap = function(compiledURL, sourceMappingURL, payload) { if (!WebInspector.TextSourceMap.prototype._base64Map) { const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; WebInspector.TextSourceMap.prototype._base64Map = {}; for (var i = 0; i < base64Digits.length; ++i) WebInspector.TextSourceMap.prototype._base64Map[base64Digits.charAt(i)] = i; } this._compiledURL = compiledURL; this._sourceMappingURL = sourceMappingURL; this._reverseMappingsBySourceURL = new Map(); this._mappings = []; this._sources = {}; this._sourceContentByURL = {}; this._parseMappingPayload(payload); } /** * @param {string} sourceMapURL * @param {string} compiledURL * @return {!Promise<?WebInspector.TextSourceMap>} * @this {WebInspector.TextSourceMap} */ WebInspector.TextSourceMap.load = function(sourceMapURL, compiledURL) { var callback; var promise = new Promise(fulfill => callback = fulfill); WebInspector.multitargetNetworkManager.loadResource(sourceMapURL, contentLoaded); return promise; /** * @param {number} statusCode * @param {!Object.<string, string>} headers * @param {string} content */ function contentLoaded(statusCode, headers, content) { if (!content || statusCode >= 400) { callback(null); return; } if (content.slice(0, 3) === ")]}") content = content.substring(content.indexOf('\n')); try { var payload = /** @type {!SourceMapV3} */ (JSON.parse(content)); var baseURL = sourceMapURL.startsWith("data:") ? compiledURL : sourceMapURL; callback(new WebInspector.TextSourceMap(compiledURL, baseURL, payload)); } catch(e) { console.error(e); WebInspector.console.error("Failed to parse SourceMap: " + sourceMapURL); callback(null); } } } WebInspector.TextSourceMap.prototype = { /** * @override * @return {string} */ compiledURL: function() { return this._compiledURL; }, /** * @override * @return {string} */ url: function() { return this._sourceMappingURL; }, /** * @override * @return {!Array.<string>} */ sourceURLs: function() { return Object.keys(this._sources); }, /** * @override * @param {string} sourceURL * @param {!WebInspector.ResourceType} contentType * @return {!WebInspector.ContentProvider} */ sourceContentProvider: function(sourceURL, contentType) { var sourceContent = this._sourceContentByURL[sourceURL]; if (sourceContent) return new WebInspector.StaticContentProvider(contentType, sourceContent); return new WebInspector.CompilerSourceMappingContentProvider(sourceURL, contentType); }, /** * @override * @return {boolean} */ editable: function() { return false; }, /** * @override * @param {!Array<!WebInspector.TextRange>} ranges * @param {!Array<string>} texts * @return {!Promise<?WebInspector.SourceMap.EditResult>} */ editCompiled: function(ranges, texts) { return Promise.resolve(/** @type {?WebInspector.SourceMap.EditResult} */(null)); }, /** * @param {!SourceMapV3} mappingPayload */ _parseMappingPayload: function(mappingPayload) { if (mappingPayload.sections) this._parseSections(mappingPayload.sections); else this._parseMap(mappingPayload, 0, 0); }, /** * @param {!Array.<!SourceMapV3.Section>} sections */ _parseSections: function(sections) { for (var i = 0; i < sections.length; ++i) { var section = sections[i]; this._parseMap(section.map, section.offset.line, section.offset.column); } }, /** * @override * @param {number} lineNumber in compiled resource * @param {number} columnNumber in compiled resource * @return {?WebInspector.SourceMapEntry} */ findEntry: function(lineNumber, columnNumber) { var first = 0; var count = this._mappings.length; while (count > 1) { var step = count >> 1; var middle = first + step; var mapping = this._mappings[middle]; if (lineNumber < mapping.lineNumber || (lineNumber === mapping.lineNumber && columnNumber < mapping.columnNumber)) count = step; else { first = middle; count -= step; } } var entry = this._mappings[first]; if (!first && entry && (lineNumber < entry.lineNumber || (lineNumber === entry.lineNumber && columnNumber < entry.columnNumber))) return null; return entry; }, /** * @param {string} sourceURL * @param {number} lineNumber * @return {?WebInspector.SourceMapEntry} */ firstSourceLineMapping: function(sourceURL, lineNumber) { var mappings = this._reversedMappings(sourceURL); var index = mappings.lowerBound(lineNumber, lineComparator); if (index >= mappings.length || mappings[index].sourceLineNumber !== lineNumber) return null; return mappings[index]; /** * @param {number} lineNumber * @param {!WebInspector.SourceMapEntry} mapping * @return {number} */ function lineComparator(lineNumber, mapping) { return lineNumber - mapping.sourceLineNumber; } }, /** * @return {!Array<!WebInspector.SourceMapEntry>} */ mappings: function() { return this._mappings; }, /** * @param {string} sourceURL * @return {!Array.<!WebInspector.SourceMapEntry>} */ _reversedMappings: function(sourceURL) { var mappings = this._reverseMappingsBySourceURL.get(sourceURL); if (!mappings) return []; if (!mappings._sorted) { mappings.sort(sourceMappingComparator); mappings._sorted = true; } return mappings; /** * @param {!WebInspector.SourceMapEntry} a * @param {!WebInspector.SourceMapEntry} b * @return {number} */ function sourceMappingComparator(a, b) { if (a.sourceLineNumber !== b.sourceLineNumber) return a.sourceLineNumber - b.sourceLineNumber; if (a.sourceColumnNumber !== b.sourceColumnNumber) return a.sourceColumnNumber - b.sourceColumnNumber; if (a.lineNumber !== b.lineNumber) return a.lineNumber - b.lineNumber; return a.columnNumber - b.columnNumber; } }, /** * @param {!SourceMapV3} map * @param {number} lineNumber * @param {number} columnNumber */ _parseMap: function(map, lineNumber, columnNumber) { var sourceIndex = 0; var sourceLineNumber = 0; var sourceColumnNumber = 0; var nameIndex = 0; var sources = []; var names = map.names || []; var sourceRoot = map.sourceRoot || ""; if (sourceRoot && !sourceRoot.endsWith("/")) sourceRoot += "/"; for (var i = 0; i < map.sources.length; ++i) { var href = sourceRoot + map.sources[i]; var url = WebInspector.ParsedURL.completeURL(this._sourceMappingURL, href) || href; var hasSource = map.sourcesContent && map.sourcesContent[i]; if (url === this._compiledURL && hasSource) url += WebInspector.UIString(" [sm]"); sources.push(url); this._sources[url] = true; if (hasSource) this._sourceContentByURL[url] = map.sourcesContent[i]; } var stringCharIterator = new WebInspector.TextSourceMap.StringCharIterator(map.mappings); var sourceURL = sources[sourceIndex]; while (true) { if (stringCharIterator.peek() === ",") stringCharIterator.next(); else { while (stringCharIterator.peek() === ";") { lineNumber += 1; columnNumber = 0; stringCharIterator.next(); } if (!stringCharIterator.hasNext()) break; } columnNumber += this._decodeVLQ(stringCharIterator); if (!stringCharIterator.hasNext() || this._isSeparator(stringCharIterator.peek())) { this._mappings.push(new WebInspector.SourceMapEntry(lineNumber, columnNumber)); continue; } var sourceIndexDelta = this._decodeVLQ(stringCharIterator); if (sourceIndexDelta) { sourceIndex += sourceIndexDelta; sourceURL = sources[sourceIndex]; } sourceLineNumber += this._decodeVLQ(stringCharIterator); sourceColumnNumber += this._decodeVLQ(stringCharIterator); if (!this._isSeparator(stringCharIterator.peek())) nameIndex += this._decodeVLQ(stringCharIterator); this._mappings.push(new WebInspector.SourceMapEntry(lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber, names[nameIndex])); } for (var i = 0; i < this._mappings.length; ++i) { var mapping = this._mappings[i]; var url = mapping.sourceURL; if (!url) continue; if (!this._reverseMappingsBySourceURL.has(url)) this._reverseMappingsBySourceURL.set(url, []); var reverseMappings = this._reverseMappingsBySourceURL.get(url); reverseMappings.push(mapping); } }, /** * @param {string} char * @return {boolean} */ _isSeparator: function(char) { return char === "," || char === ";"; }, /** * @param {!WebInspector.TextSourceMap.StringCharIterator} stringCharIterator * @return {number} */ _decodeVLQ: function(stringCharIterator) { // Read unsigned value. var result = 0; var shift = 0; do { var digit = this._base64Map[stringCharIterator.next()]; result += (digit & this._VLQ_BASE_MASK) << shift; shift += this._VLQ_BASE_SHIFT; } while (digit & this._VLQ_CONTINUATION_MASK); // Fix the sign. var negative = result & 1; result >>= 1; return negative ? -result : result; }, /** * @param {string} url * @param {!WebInspector.TextRange} textRange * @return {!WebInspector.TextRange} */ reverseMapTextRange: function(url, textRange) { /** * @param {!{lineNumber: number, columnNumber: number}} position * @param {!WebInspector.SourceMapEntry} mapping * @return {number} */ function comparator(position, mapping) { if (position.lineNumber !== mapping.sourceLineNumber) return position.lineNumber - mapping.sourceLineNumber; return position.columnNumber - mapping.sourceColumnNumber; } var mappings = this._reversedMappings(url); var startIndex = mappings.lowerBound({lineNumber: textRange.startLine, columnNumber: textRange.startColumn}, comparator); var endIndex = mappings.upperBound({lineNumber: textRange.endLine, columnNumber: textRange.endColumn}, comparator); var startMapping = mappings[startIndex]; var endMapping = mappings[endIndex]; return new WebInspector.TextRange(startMapping.lineNumber, startMapping.columnNumber, endMapping.lineNumber, endMapping.columnNumber); }, _VLQ_BASE_SHIFT: 5, _VLQ_BASE_MASK: (1 << 5) - 1, _VLQ_CONTINUATION_MASK: 1 << 5 } /** * @constructor * @param {string} string */ WebInspector.TextSourceMap.StringCharIterator = function(string) { this._string = string; this._position = 0; } WebInspector.TextSourceMap.StringCharIterator.prototype = { /** * @return {string} */ next: function() { return this._string.charAt(this._position++); }, /** * @return {string} */ peek: function() { return this._string.charAt(this._position); }, /** * @return {boolean} */ hasNext: function() { return this._position < this._string.length; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | 2 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {Protocol.Agents}
* @param {!WebInspector.TargetManager} targetManager
* @param {string} name
* @param {number} type
* @param {!InspectorBackendClass.Connection} connection
* @param {?WebInspector.Target} parentTarget
*/
WebInspector.Target = function(targetManager, name, type, connection, parentTarget)
{
Protocol.Agents.call(this, connection.agentsMap());
this._targetManager = targetManager;
this._name = name;
this._type = type;
this._connection = connection;
this._parentTarget = parentTarget;
connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, this._onDisconnect, this);
this._id = WebInspector.Target._nextId++;
/** @type {!Map.<!Function, !WebInspector.SDKModel>} */
this._modelByConstructor = new Map();
}
/**
* @enum {number}
*/
WebInspector.Target.Type = {
Page: 1,
DedicatedWorker: 2,
ServiceWorker: 4
}
WebInspector.Target._nextId = 1;
WebInspector.Target.prototype = {
/**
* @return {number}
*/
id: function()
{
return this._id;
},
/**
*
* @return {string}
*/
name: function()
{
return this._name;
},
/**
*
* @return {number}
*/
type: function()
{
return this._type;
},
/**
*
* @return {!WebInspector.TargetManager}
*/
targetManager: function()
{
return this._targetManager;
},
/**
* @param {string} label
* @return {string}
*/
decorateLabel: function(label)
{
return this.isWorker() ? "\u2699 " + label : label;
},
/**
* @override
* @param {string} domain
* @param {!Object} dispatcher
*/
registerDispatcher: function(domain, dispatcher)
{
this._connection.registerDispatcher(domain, dispatcher);
},
/**
* @return {boolean}
*/
isPage: function()
{
return this._type === WebInspector.Target.Type.Page;
},
/**
* @return {boolean}
*/
isWorker: function()
{
return this.isDedicatedWorker() || this.isServiceWorker();
},
/**
* @return {boolean}
*/
isDedicatedWorker: function()
{
return this._type === WebInspector.Target.Type.DedicatedWorker;
},
/**
* @return {boolean}
*/
isServiceWorker: function()
{
return this._type === WebInspector.Target.Type.ServiceWorker;
},
/**
* @return {boolean}
*/
hasJSContext: function()
{
return !this.isServiceWorker();
},
/**
* @return {?WebInspector.Target}
*/
parentTarget: function()
{
return this._parentTarget;
},
_onDisconnect: function()
{
this._targetManager.removeTarget(this);
this._dispose();
},
_dispose: function()
{
this._targetManager.dispatchEventToListeners(WebInspector.TargetManager.Events.TargetDisposed, this);
this.networkManager.dispose();
this.cpuProfilerModel.dispose();
WebInspector.ServiceWorkerCacheModel.fromTarget(this).dispose();
if (this.workerManager)
this.workerManager.dispose();
},
/**
* @return {boolean}
*/
isDetached: function()
{
return this._connection.isClosed();
},
/**
* @param {!Function} modelClass
* @return {?WebInspector.SDKModel}
*/
model: function(modelClass)
{
return this._modelByConstructor.get(modelClass) || null;
},
/**
* @return {!Array<!WebInspector.SDKModel>}
*/
models: function()
{
return this._modelByConstructor.valuesArray();
},
__proto__: Protocol.Agents.prototype
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.Target} target
*/
WebInspector.SDKObject = function(target)
{
WebInspector.Object.call(this);
this._target = target;
}
WebInspector.SDKObject.prototype = {
/**
* @return {!WebInspector.Target}
*/
target: function()
{
return this._target;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!Function} modelClass
* @param {!WebInspector.Target} target
*/
WebInspector.SDKModel = function(modelClass, target)
{
WebInspector.SDKObject.call(this, target);
target._modelByConstructor.set(modelClass, this);
}
WebInspector.SDKModel.prototype = {
/**
* @return {!Promise}
*/
suspendModel: function()
{
return Promise.resolve();
},
/**
* @return {!Promise}
*/
resumeModel: function()
{
return Promise.resolve();
},
__proto__: WebInspector.SDKObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | 2 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.TargetManager = function()
{
WebInspector.Object.call(this);
/** @type {!Array.<!WebInspector.Target>} */
this._targets = [];
/** @type {!Array.<!WebInspector.TargetManager.Observer>} */
this._observers = [];
this._observerTypeSymbol = Symbol("observerType");
/** @type {!Object.<string, !Array.<{modelClass: !Function, thisObject: (!Object|undefined), listener: function(!WebInspector.Event)}>>} */
this._modelListeners = {};
this._isSuspended = false;
}
WebInspector.TargetManager.Events = {
InspectedURLChanged: "InspectedURLChanged",
MainFrameNavigated: "MainFrameNavigated",
Load: "Load",
PageReloadRequested: "PageReloadRequested",
WillReloadPage: "WillReloadPage",
TargetDisposed: "TargetDisposed",
SuspendStateChanged: "SuspendStateChanged"
}
WebInspector.TargetManager.prototype = {
suspendAllTargets: function()
{
if (this._isSuspended)
return;
this._isSuspended = true;
this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);
for (var i = 0; i < this._targets.length; ++i) {
for (var model of this._targets[i].models())
model.suspendModel();
}
},
/**
* @return {!Promise}
*/
resumeAllTargets: function()
{
if (!this._isSuspended)
throw new Error("Not suspended");
this._isSuspended = false;
this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);
var promises = [];
for (var i = 0; i < this._targets.length; ++i) {
for (var model of this._targets[i].models())
promises.push(model.resumeModel());
}
return Promise.all(promises);
},
suspendAndResumeAllTargets: function()
{
this.suspendAllTargets();
this.resumeAllTargets();
},
/**
* @return {boolean}
*/
allTargetsSuspended: function()
{
return this._isSuspended;
},
/**
* @return {string}
*/
inspectedPageURL: function()
{
if (!this._targets.length)
return "";
return this._targets[0].resourceTreeModel.inspectedPageURL();
},
/**
* @return {string}
*/
inspectedPageDomain: function()
{
if (!this._targets.length)
return "";
return this._targets[0].resourceTreeModel.inspectedPageDomain();
},
/**
* @param {!WebInspector.Event} event
*/
_redispatchEvent: function(event)
{
this.dispatchEventToListeners(event.type, event.data);
},
/**
* @param {boolean=} bypassCache
* @param {string=} injectedScript
*/
reloadPage: function(bypassCache, injectedScript)
{
if (this._targets.length)
this._targets[0].resourceTreeModel.reloadPage(bypassCache, injectedScript);
},
/**
* @param {!Function} modelClass
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
addModelListener: function(modelClass, eventType, listener, thisObject)
{
for (var i = 0; i < this._targets.length; ++i) {
var model = this._targets[i].model(modelClass);
if (model)
model.addEventListener(eventType, listener, thisObject);
}
if (!this._modelListeners[eventType])
this._modelListeners[eventType] = [];
this._modelListeners[eventType].push({ modelClass: modelClass, thisObject: thisObject, listener: listener });
},
/**
* @param {!Function} modelClass
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
*/
removeModelListener: function(modelClass, eventType, listener, thisObject)
{
if (!this._modelListeners[eventType])
return;
for (var i = 0; i < this._targets.length; ++i) {
var model = this._targets[i].model(modelClass);
if (model)
model.removeEventListener(eventType, listener, thisObject);
}
var listeners = this._modelListeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
if (listeners[i].modelClass === modelClass && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i--, 1);
}
if (!listeners.length)
delete this._modelListeners[eventType];
},
/**
* @param {!WebInspector.TargetManager.Observer} targetObserver
* @param {number=} type
*/
observeTargets: function(targetObserver, type)
{
if (this._observerTypeSymbol in targetObserver)
throw new Error("Observer can only be registered once");
targetObserver[this._observerTypeSymbol] = type || 0x7fff;
this.targets(type).forEach(targetObserver.targetAdded.bind(targetObserver));
this._observers.push(targetObserver);
},
/**
* @param {!WebInspector.TargetManager.Observer} targetObserver
*/
unobserveTargets: function(targetObserver)
{
delete targetObserver[this._observerTypeSymbol];
this._observers.remove(targetObserver);
},
/**
* @param {string} name
* @param {number} type
* @param {!InspectorBackendClass.Connection} connection
* @param {?WebInspector.Target} parentTarget
* @return {!WebInspector.Target}
*/
createTarget: function(name, type, connection, parentTarget)
{
var target = new WebInspector.Target(this, name, type, connection, parentTarget);
/** @type {!WebInspector.ConsoleModel} */
target.consoleModel = new WebInspector.ConsoleModel(target);
/** @type {!WebInspector.NetworkManager} */
target.networkManager = new WebInspector.NetworkManager(target);
/** @type {!WebInspector.ResourceTreeModel} */
target.resourceTreeModel = new WebInspector.ResourceTreeModel(target);
/** @type {!WebInspector.NetworkLog} */
target.networkLog = new WebInspector.NetworkLog(target);
/** @type {!WebInspector.RuntimeModel} */
target.runtimeModel = new WebInspector.RuntimeModel(target);
if (target.hasJSContext())
new WebInspector.DebuggerModel(target);
if (target.type() === WebInspector.Target.Type.Page) {
new WebInspector.DOMModel(target);
new WebInspector.CSSModel(target);
}
/** @type {?WebInspector.WorkerManager} */
target.workerManager = !target.isDedicatedWorker() ? new WebInspector.WorkerManager(target) : null;
/** @type {!WebInspector.CPUProfilerModel} */
target.cpuProfilerModel = new WebInspector.CPUProfilerModel(target);
/** @type {!WebInspector.HeapProfilerModel} */
target.heapProfilerModel = new WebInspector.HeapProfilerModel(target);
target.tracingManager = new WebInspector.TracingManager(target);
if (target.isPage())
target.serviceWorkerManager = new WebInspector.ServiceWorkerManager(target);
this.addTarget(target);
return target;
},
/**
* @param {number} type
* @return {!Array<!WebInspector.TargetManager.Observer>}
*/
_observersByType: function(type)
{
var result = [];
for (var observer of this._observers) {
if (observer[this._observerTypeSymbol] & type)
result.push(observer);
}
return result;
},
/**
* @param {!WebInspector.Target} target
*/
addTarget: function(target)
{
this._targets.push(target);
if (this._targets.length === 1) {
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._redispatchEvent, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._redispatchEvent, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._redispatchEvent, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.PageReloadRequested, this._redispatchEvent, this);
target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._redispatchEvent, this);
}
var copy = this._observersByType(target.type());
for (var i = 0; i < copy.length; ++i)
copy[i].targetAdded(target);
for (var eventType in this._modelListeners) {
var listeners = this._modelListeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
var model = target.model(listeners[i].modelClass);
if (model)
model.addEventListener(eventType, listeners[i].listener, listeners[i].thisObject);
}
}
},
/**
* @param {!WebInspector.Target} target
*/
removeTarget: function(target)
{
this._targets.remove(target);
if (this._targets.length === 0) {
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._redispatchEvent, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._redispatchEvent, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._redispatchEvent, this);
target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._redispatchEvent, this);
}
var copy = this._observersByType(target.type());
for (var i = 0; i < copy.length; ++i)
copy[i].targetRemoved(target);
for (var eventType in this._modelListeners) {
var listeners = this._modelListeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
var model = target.model(listeners[i].modelClass);
if (model)
model.removeEventListener(eventType, listeners[i].listener, listeners[i].thisObject);
}
}
},
/**
* @param {number=} type
* @return {boolean}
*/
hasTargets: function(type)
{
return !!this.targets(type).length;
},
/**
* @param {number=} type
* @return {!Array.<!WebInspector.Target>}
*/
targets: function(type)
{
if (!type)
return this._targets.slice();
var result = [];
for (var target of this._targets) {
if (target.type() & type)
result.push(target);
}
return result;
},
/**
* @return {!Array.<!WebInspector.Target>}
*/
targetsWithJSContext: function()
{
var result = [];
for (var target of this._targets) {
if (target.hasJSContext())
result.push(target);
}
return result;
},
/**
*
* @param {number} id
* @return {?WebInspector.Target}
*/
targetById: function(id)
{
for (var i = 0; i < this._targets.length; ++i) {
if (this._targets[i].id() === id)
return this._targets[i];
}
return null;
},
/**
* @return {?WebInspector.Target}
*/
mainTarget: function()
{
return this._targets[0] || null;
},
__proto__: WebInspector.Object.prototype
}
/**
* @interface
*/
WebInspector.TargetManager.Observer = function()
{
}
WebInspector.TargetManager.Observer.prototype = {
/**
* @param {!WebInspector.Target} target
*/
targetAdded: function(target) { },
/**
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target) { },
}
/**
* @type {!WebInspector.TargetManager}
*/
WebInspector.targetManager = new WebInspector.TargetManager();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | 2 | /* * Copyright 2014 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /** * @interface */ WebInspector.TracingManagerClient = function() { } WebInspector.TracingManagerClient.prototype = { tracingStarted: function() { }, /** * @param {!Array.<!WebInspector.TracingManager.EventPayload>} events */ traceEventsCollected: function(events) { }, tracingComplete: function() { }, /** * @param {number} usage */ tracingBufferUsage: function(usage) { }, /** * @param {number} progress */ eventsRetrievalProgress: function(progress) { } } /** * @constructor * @param {!WebInspector.Target} target */ WebInspector.TracingManager = function(target) { this._target = target; target.registerTracingDispatcher(new WebInspector.TracingDispatcher(this)); /** @type {?WebInspector.TracingManagerClient} */ this._activeClient = null; this._eventBufferSize = 0; this._eventsRetrieved = 0; } /** @typedef {!{ cat: string, pid: number, tid: number, ts: number, ph: string, name: string, args: !Object, dur: number, id: string, bind_id: string, s: string }} */ WebInspector.TracingManager.EventPayload; WebInspector.TracingManager.TransferMode = { ReportEvents: "ReportEvents", ReturnAsStream: "ReturnAsStream" }; WebInspector.TracingManager.prototype = { /** * @return {?WebInspector.Target} */ target: function() { return this._target; }, /** * @param {number=} usage * @param {number=} eventCount * @param {number=} percentFull */ _bufferUsage: function(usage, eventCount, percentFull) { this._eventBufferSize = eventCount; this._activeClient.tracingBufferUsage(usage || percentFull || 0); }, /** * @param {!Array.<!WebInspector.TracingManager.EventPayload>} events */ _eventsCollected: function(events) { this._activeClient.traceEventsCollected(events); this._eventsRetrieved += events.length; if (!this._eventBufferSize) return; if (this._eventsRetrieved > this._eventBufferSize) this._eventsRetrieved = this._eventBufferSize; this._activeClient.eventsRetrievalProgress(this._eventsRetrieved / this._eventBufferSize); }, _tracingComplete: function() { this._eventBufferSize = 0; this._eventsRetrieved = 0; this._activeClient.tracingComplete(); this._activeClient = null; this._finishing = false; }, /** * @param {!WebInspector.TracingManagerClient} client * @param {string} categoryFilter * @param {string} options * @param {function(?string)=} callback */ start: function(client, categoryFilter, options, callback) { if (this._activeClient) throw new Error("Tracing is already started"); var bufferUsageReportingIntervalMs = 500; this._activeClient = client; this._target.tracingAgent().start(categoryFilter, options, bufferUsageReportingIntervalMs, WebInspector.TracingManager.TransferMode.ReportEvents, callback); this._activeClient.tracingStarted(); }, stop: function() { if (!this._activeClient) throw new Error("Tracing is not started"); if (this._finishing) throw new Error("Tracing is already being stopped"); this._finishing = true; this._target.tracingAgent().end(); } } /** * @constructor * @implements {TracingAgent.Dispatcher} * @param {!WebInspector.TracingManager} tracingManager */ WebInspector.TracingDispatcher = function(tracingManager) { this._tracingManager = tracingManager; } WebInspector.TracingDispatcher.prototype = { /** * @override * @param {number=} usage * @param {number=} eventCount * @param {number=} percentFull */ bufferUsage: function(usage, eventCount, percentFull) { this._tracingManager._bufferUsage(usage, eventCount, percentFull); }, /** * @override * @param {!Array.<!WebInspector.TracingManager.EventPayload>} data */ dataCollected: function(data) { this._tracingManager._eventsCollected(data); }, /** * @override */ tracingComplete: function() { this._tracingManager._tracingComplete(); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | 2 1 1 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @param {!WebInspector.BackingStorage} backingStorage
*/
WebInspector.TracingModel = function(backingStorage)
{
this._backingStorage = backingStorage;
// Avoid extra reset of the storage as it's expensive.
this._firstWritePending = true;
this.reset();
}
/**
* @enum {string}
*/
WebInspector.TracingModel.Phase = {
Begin: "B",
End: "E",
Complete: "X",
Instant: "I",
AsyncBegin: "S",
AsyncStepInto: "T",
AsyncStepPast: "p",
AsyncEnd: "F",
NestableAsyncBegin: "b",
NestableAsyncEnd: "e",
NestableAsyncInstant: "n",
FlowBegin: "s",
FlowStep: "t",
FlowEnd: "f",
Metadata: "M",
Counter: "C",
Sample: "P",
CreateObject: "N",
SnapshotObject: "O",
DeleteObject: "D"
};
WebInspector.TracingModel.MetadataEvent = {
ProcessSortIndex: "process_sort_index",
ProcessName: "process_name",
ThreadSortIndex: "thread_sort_index",
ThreadName: "thread_name"
}
WebInspector.TracingModel.TopLevelEventCategory = "toplevel";
WebInspector.TracingModel.DevToolsMetadataEventCategory = "disabled-by-default-devtools.timeline";
WebInspector.TracingModel.DevToolsTimelineEventCategory = "disabled-by-default-devtools.timeline";
WebInspector.TracingModel.FrameLifecycleEventCategory = "cc,devtools";
/**
* @param {string} phase
* @return {boolean}
*/
WebInspector.TracingModel.isNestableAsyncPhase = function(phase)
{
return phase === "b" || phase === "e" || phase === "n";
}
/**
* @param {string} phase
* @return {boolean}
*/
WebInspector.TracingModel.isAsyncBeginPhase = function(phase)
{
return phase === "S" || phase === "b";
}
/**
* @param {string} phase
* @return {boolean}
*/
WebInspector.TracingModel.isAsyncPhase = function(phase)
{
return WebInspector.TracingModel.isNestableAsyncPhase(phase) || phase === "S" || phase === "T" || phase === "F" || phase === "p";
}
/**
* @param {string} phase
* @return {boolean}
*/
WebInspector.TracingModel.isFlowPhase = function(phase)
{
return phase === "s" || phase === "t" || phase === "f";
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
WebInspector.TracingModel.isTopLevelEvent = function(event)
{
return event.hasCategory(WebInspector.TracingModel.TopLevelEventCategory) ||
event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory) && event.name === "Program"; // Older timelines may have this instead of toplevel.
}
/**
* @interface
*/
WebInspector.BackingStorage = function()
{
}
WebInspector.BackingStorage.prototype = {
/**
* @param {string} string
*/
appendString: function(string) { },
/**
* @param {string} string
* @return {function():!Promise.<?string>}
*/
appendAccessibleString: function(string) { },
finishWriting: function() { },
reset: function() { },
}
WebInspector.TracingModel.prototype = {
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
devToolsMetadataEvents: function()
{
return this._devToolsMetadataEvents;
},
/**
* @param {!Array.<!WebInspector.TracingManager.EventPayload>} events
*/
setEventsForTest: function(events)
{
this.reset();
this.addEvents(events);
this.tracingComplete();
},
/**
* @param {!Array.<!WebInspector.TracingManager.EventPayload>} events
*/
addEvents: function(events)
{
for (var i = 0; i < events.length; ++i)
this._addEvent(events[i]);
},
tracingComplete: function()
{
this._processPendingAsyncEvents();
this._backingStorage.appendString(this._firstWritePending ? "[]" : "]");
this._backingStorage.finishWriting();
this._firstWritePending = false;
for (var process of Object.values(this._processById)) {
for (var thread of Object.values(process._threads))
thread.tracingComplete();
}
},
reset: function()
{
/** @type {!Object.<(number|string), !WebInspector.TracingModel.Process>} */
this._processById = {};
this._processByName = new Map();
this._minimumRecordTime = 0;
this._maximumRecordTime = 0;
this._devToolsMetadataEvents = [];
if (!this._firstWritePending)
this._backingStorage.reset();
this._firstWritePending = true;
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._asyncEvents = [];
/** @type {!Map<string, !WebInspector.TracingModel.AsyncEvent>} */
this._openAsyncEvents = new Map();
/** @type {!Map<string, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
this._openNestableAsyncEvents = new Map();
/** @type {!Map<string, !Set<string>>} */
this._parsedCategories = new Map();
},
/**
* @param {!WebInspector.TracingManager.EventPayload} payload
*/
_addEvent: function(payload)
{
var process = this._processById[payload.pid];
if (!process) {
process = new WebInspector.TracingModel.Process(this, payload.pid);
this._processById[payload.pid] = process;
}
var eventsDelimiter = ",\n";
this._backingStorage.appendString(this._firstWritePending ? "[" : eventsDelimiter);
this._firstWritePending = false;
var stringPayload = JSON.stringify(payload);
var isAccessible = payload.ph === WebInspector.TracingModel.Phase.SnapshotObject;
var backingStorage = null;
var keepStringsLessThan = 10000;
if (isAccessible && stringPayload.length > keepStringsLessThan)
backingStorage = this._backingStorage.appendAccessibleString(stringPayload);
else
this._backingStorage.appendString(stringPayload);
var timestamp = payload.ts / 1000;
// We do allow records for unrelated threads to arrive out-of-order,
// so there's a chance we're getting records from the past.
if (timestamp && (!this._minimumRecordTime || timestamp < this._minimumRecordTime))
this._minimumRecordTime = timestamp;
var endTimeStamp = (payload.ts + (payload.dur || 0)) / 1000;
this._maximumRecordTime = Math.max(this._maximumRecordTime, endTimeStamp);
var event = process._addEvent(payload);
if (!event)
return;
// Build async event when we've got events from all threads & processes, so we can sort them and process in the
// chronological order. However, also add individual async events to the thread flow (above), so we can easily
// display them on the same chart as other events, should we choose so.
if (WebInspector.TracingModel.isAsyncPhase(payload.ph))
this._asyncEvents.push(event);
event._setBackingStorage(backingStorage);
if (event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory))
this._devToolsMetadataEvents.push(event);
if (payload.ph !== WebInspector.TracingModel.Phase.Metadata)
return;
switch (payload.name) {
case WebInspector.TracingModel.MetadataEvent.ProcessSortIndex:
process._setSortIndex(payload.args["sort_index"]);
break;
case WebInspector.TracingModel.MetadataEvent.ProcessName:
var processName = payload.args["name"];
process._setName(processName);
this._processByName.set(processName, process);
break;
case WebInspector.TracingModel.MetadataEvent.ThreadSortIndex:
process.threadById(payload.tid)._setSortIndex(payload.args["sort_index"]);
break;
case WebInspector.TracingModel.MetadataEvent.ThreadName:
process.threadById(payload.tid)._setName(payload.args["name"]);
break;
}
},
/**
* @return {number}
*/
minimumRecordTime: function()
{
return this._minimumRecordTime;
},
/**
* @return {number}
*/
maximumRecordTime: function()
{
return this._maximumRecordTime;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Process>}
*/
sortedProcesses: function()
{
return WebInspector.TracingModel.NamedObject._sort(Object.values(this._processById));
},
/**
* @param {string} name
* @return {?WebInspector.TracingModel.Process}
*/
processByName: function(name)
{
return this._processByName.get(name);
},
/**
* @param {string} processName
* @param {string} threadName
* @return {?WebInspector.TracingModel.Thread}
*/
threadByName: function(processName, threadName)
{
var process = this.processByName(processName);
return process && process.threadByName(threadName);
},
_processPendingAsyncEvents: function()
{
this._asyncEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
for (var i = 0; i < this._asyncEvents.length; ++i) {
var event = this._asyncEvents[i];
if (WebInspector.TracingModel.isNestableAsyncPhase(event.phase))
this._addNestableAsyncEvent(event);
else
this._addAsyncEvent(event);
}
this._asyncEvents = [];
this._closeOpenAsyncEvents();
},
_closeOpenAsyncEvents: function()
{
for (var event of this._openAsyncEvents.values()) {
event.setEndTime(this._maximumRecordTime);
// FIXME: remove this once we figure a better way to convert async console
// events to sync [waterfall] timeline records.
event.steps[0].setEndTime(this._maximumRecordTime);
}
this._openAsyncEvents.clear();
for (var eventStack of this._openNestableAsyncEvents.values()) {
while (eventStack.length)
eventStack.pop().setEndTime(this._maximumRecordTime);
}
this._openNestableAsyncEvents.clear();
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_addNestableAsyncEvent: function(event)
{
var phase = WebInspector.TracingModel.Phase;
var key = event.categoriesString + "." + event.id;
var openEventsStack = this._openNestableAsyncEvents.get(key);
switch (event.phase) {
case phase.NestableAsyncBegin:
if (!openEventsStack) {
openEventsStack = [];
this._openNestableAsyncEvents.set(key, openEventsStack);
}
var asyncEvent = new WebInspector.TracingModel.AsyncEvent(event);
openEventsStack.push(asyncEvent);
event.thread._addAsyncEvent(asyncEvent);
break;
case phase.NestableAsyncInstant:
if (openEventsStack && openEventsStack.length)
openEventsStack.peekLast()._addStep(event);
break;
case phase.NestableAsyncEnd:
if (!openEventsStack || !openEventsStack.length)
break;
var top = openEventsStack.pop();
if (top.name !== event.name) {
console.error("Begin/end event mismatch for nestable async event, " + top.name + " vs. " + event.name);
break;
}
top._addStep(event);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_addAsyncEvent: function(event)
{
var phase = WebInspector.TracingModel.Phase;
var key = event.categoriesString + "." + event.name + "." + event.id;
var asyncEvent = this._openAsyncEvents.get(key);
if (event.phase === phase.AsyncBegin) {
if (asyncEvent) {
console.error("Event " + event.name + " has already been started");
return;
}
asyncEvent = new WebInspector.TracingModel.AsyncEvent(event);
this._openAsyncEvents.set(key, asyncEvent);
event.thread._addAsyncEvent(asyncEvent);
return;
}
if (!asyncEvent) {
// Quietly ignore stray async events, we're probably too late for the start.
return;
}
if (event.phase === phase.AsyncEnd) {
asyncEvent._addStep(event);
this._openAsyncEvents.delete(key);
return;
}
if (event.phase === phase.AsyncStepInto || event.phase === phase.AsyncStepPast) {
var lastStep = asyncEvent.steps.peekLast();
if (lastStep.phase !== phase.AsyncBegin && lastStep.phase !== event.phase) {
console.assert(false, "Async event step phase mismatch: " + lastStep.phase + " at " + lastStep.startTime + " vs. " + event.phase + " at " + event.startTime);
return;
}
asyncEvent._addStep(event);
return;
}
console.assert(false, "Invalid async event phase");
},
/**
* @param {string} str
* @return {!Set<string>}
*/
_parsedCategoriesForString: function(str)
{
var parsedCategories = this._parsedCategories.get(str);
if (!parsedCategories) {
parsedCategories = new Set(str.split(","));
this._parsedCategories.set(str, parsedCategories);
}
return parsedCategories;
}
}
/**
* @constructor
* @param {string} categories
* @param {string} name
* @param {!WebInspector.TracingModel.Phase} phase
* @param {number} startTime
* @param {!WebInspector.TracingModel.Thread} thread
*/
WebInspector.TracingModel.Event = function(categories, name, phase, startTime, thread)
{
/** @type {string} */
this.categoriesString = categories;
/** @type {!Set<string>} */
this._parsedCategories = thread._model._parsedCategoriesForString(categories);
/** @type {string} */
this.name = name;
/** @type {!WebInspector.TracingModel.Phase} */
this.phase = phase;
/** @type {number} */
this.startTime = startTime;
/** @type {!WebInspector.TracingModel.Thread} */
this.thread = thread;
/** @type {!Object} */
this.args = {};
/** @type {?string} */
this.warning = null;
/** @type {?WebInspector.TracingModel.Event} */
this.initiator = null;
/** @type {?Array.<!RuntimeAgent.CallFrame>} */
this.stackTrace = null;
/** @type {?Element} */
this.previewElement = null;
/** @type {?string} */
this.url = null;
/** @type {number} */
this.backendNodeId = 0;
/** @type {number} */
this.selfTime = 0;
}
/**
* @param {!WebInspector.TracingManager.EventPayload} payload
* @param {!WebInspector.TracingModel.Thread} thread
* @return {!WebInspector.TracingModel.Event}
*/
WebInspector.TracingModel.Event.fromPayload = function(payload, thread)
{
var event = new WebInspector.TracingModel.Event(payload.cat, payload.name, /** @type {!WebInspector.TracingModel.Phase} */ (payload.ph), payload.ts / 1000, thread);
if (payload.args)
event.addArgs(payload.args);
else
console.error("Missing mandatory event argument 'args' at " + payload.ts / 1000);
if (typeof payload.dur === "number")
event.setEndTime((payload.ts + payload.dur) / 1000);
if (payload.id)
event.id = payload.id;
if (payload.bind_id)
event.bind_id = payload.bind_id;
return event;
}
WebInspector.TracingModel.Event.prototype = {
/**
* @param {string} categoryName
* @return {boolean}
*/
hasCategory: function(categoryName)
{
return this._parsedCategories.has(categoryName);
},
/**
* @param {number} endTime
*/
setEndTime: function(endTime)
{
if (endTime < this.startTime) {
console.assert(false, "Event out of order: " + this.name);
return;
}
this.endTime = endTime;
this.duration = endTime - this.startTime;
},
/**
* @param {!Object} args
*/
addArgs: function(args)
{
// Shallow copy args to avoid modifying original payload which may be saved to file.
for (var name in args) {
if (name in this.args)
console.error("Same argument name (" + name + ") is used for begin and end phases of " + this.name);
this.args[name] = args[name];
}
},
/**
* @param {!WebInspector.TracingModel.Event} endEvent
*/
_complete: function(endEvent)
{
if (endEvent.args)
this.addArgs(endEvent.args);
else
console.error("Missing mandatory event argument 'args' at " + endEvent.startTime);
this.setEndTime(endEvent.startTime);
},
/**
* @param {?function():!Promise.<?string>} backingStorage
*/
_setBackingStorage: function(backingStorage)
{
}
}
/**
* @param {!WebInspector.TracingModel.Event} a
* @param {!WebInspector.TracingModel.Event} b
* @return {number}
*/
WebInspector.TracingModel.Event.compareStartTime = function (a, b)
{
return a.startTime - b.startTime;
}
/**
* @param {!WebInspector.TracingModel.Event} a
* @param {!WebInspector.TracingModel.Event} b
* @return {number}
*/
WebInspector.TracingModel.Event.compareStartAndEndTime = function (a, b)
{
return a.startTime - b.startTime || (b.endTime != undefined && a.endTime !== undefined && b.endTime - a.endTime) || 0;
}
/**
* @param {!WebInspector.TracingModel.Event} a
* @param {!WebInspector.TracingModel.Event} b
* @return {number}
*/
WebInspector.TracingModel.Event.orderedCompareStartTime = function (a, b)
{
// Array.mergeOrdered coalesces objects if comparator returns 0.
// To change this behavior this comparator return -1 in the case events
// startTime's are equal, so both events got placed into the result array.
return a.startTime - b.startTime || a.ordinal - b.ordinal || -1;
}
/**
* @constructor
* @extends {WebInspector.TracingModel.Event}
* @param {string} category
* @param {string} name
* @param {number} startTime
* @param {!WebInspector.TracingModel.Thread} thread
*/
WebInspector.TracingModel.ObjectSnapshot = function(category, name, startTime, thread)
{
WebInspector.TracingModel.Event.call(this, category, name, WebInspector.TracingModel.Phase.SnapshotObject, startTime, thread);
}
/**
* @param {!WebInspector.TracingManager.EventPayload} payload
* @param {!WebInspector.TracingModel.Thread} thread
* @return {!WebInspector.TracingModel.ObjectSnapshot}
*/
WebInspector.TracingModel.ObjectSnapshot.fromPayload = function(payload, thread)
{
var snapshot = new WebInspector.TracingModel.ObjectSnapshot(payload.cat, payload.name, payload.ts / 1000, thread);
if (payload.id)
snapshot.id = payload.id;
if (!payload.args || !payload.args["snapshot"]) {
console.error("Missing mandatory 'snapshot' argument at " + payload.ts / 1000);
return snapshot;
}
if (payload.args)
snapshot.addArgs(payload.args);
return snapshot;
}
WebInspector.TracingModel.ObjectSnapshot.prototype = {
/**
* @param {function(?)} callback
*/
requestObject: function(callback)
{
var snapshot = this.args["snapshot"];
if (snapshot) {
callback(snapshot);
return;
}
this._backingStorage().then(onRead, callback.bind(null, null));
/**
* @param {?string} result
*/
function onRead(result)
{
if (!result) {
callback(null);
return;
}
try {
var payload = JSON.parse(result);
callback(payload["args"]["snapshot"]);
} catch (e) {
WebInspector.console.error("Malformed event data in backing storage");
callback(null);
}
}
},
/**
* @return {!Promise<?>}
*/
objectPromise: function()
{
if (!this._objectPromise)
this._objectPromise = new Promise(this.requestObject.bind(this));
return this._objectPromise;
},
/**
* @override
* @param {?function():!Promise.<?>} backingStorage
*/
_setBackingStorage: function(backingStorage)
{
if (!backingStorage)
return;
this._backingStorage = backingStorage;
this.args = {};
},
__proto__: WebInspector.TracingModel.Event.prototype
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} startEvent
* @extends {WebInspector.TracingModel.Event}
*/
WebInspector.TracingModel.AsyncEvent = function(startEvent)
{
WebInspector.TracingModel.Event.call(this, startEvent.categoriesString, startEvent.name, startEvent.phase, startEvent.startTime, startEvent.thread)
this.addArgs(startEvent.args);
this.steps = [startEvent];
}
WebInspector.TracingModel.AsyncEvent.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_addStep: function(event)
{
this.steps.push(event)
if (event.phase === WebInspector.TracingModel.Phase.AsyncEnd || event.phase === WebInspector.TracingModel.Phase.NestableAsyncEnd) {
this.setEndTime(event.startTime);
// FIXME: ideally, we shouldn't do this, but this makes the logic of converting
// async console events to sync ones much simpler.
this.steps[0].setEndTime(event.startTime);
}
},
__proto__: WebInspector.TracingModel.Event.prototype
}
/**
* @constructor
*/
WebInspector.TracingModel.NamedObject = function()
{
}
WebInspector.TracingModel.NamedObject.prototype =
{
/**
* @param {string} name
*/
_setName: function(name)
{
this._name = name;
},
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @param {number} sortIndex
*/
_setSortIndex: function(sortIndex)
{
this._sortIndex = sortIndex;
},
}
/**
* @param {!Array.<!WebInspector.TracingModel.NamedObject>} array
*/
WebInspector.TracingModel.NamedObject._sort = function(array)
{
/**
* @param {!WebInspector.TracingModel.NamedObject} a
* @param {!WebInspector.TracingModel.NamedObject} b
*/
function comparator(a, b)
{
return a._sortIndex !== b._sortIndex ? a._sortIndex - b._sortIndex : a.name().localeCompare(b.name());
}
return array.sort(comparator);
}
/**
* @constructor
* @extends {WebInspector.TracingModel.NamedObject}
* @param {!WebInspector.TracingModel} model
* @param {number} id
*/
WebInspector.TracingModel.Process = function(model, id)
{
WebInspector.TracingModel.NamedObject.call(this);
this._setName("Process " + id);
this._id = id;
/** @type {!Object.<number, !WebInspector.TracingModel.Thread>} */
this._threads = {};
this._threadByName = new Map();
this._model = model;
}
WebInspector.TracingModel.Process.prototype = {
/**
* @return {number}
*/
id: function()
{
return this._id;
},
/**
* @param {number} id
* @return {!WebInspector.TracingModel.Thread}
*/
threadById: function(id)
{
var thread = this._threads[id];
if (!thread) {
thread = new WebInspector.TracingModel.Thread(this, id);
this._threads[id] = thread;
}
return thread;
},
/**
* @param {string} name
* @return {?WebInspector.TracingModel.Thread}
*/
threadByName: function(name)
{
return this._threadByName.get(name) || null;
},
/**
* @param {string} name
* @param {!WebInspector.TracingModel.Thread} thread
*/
_setThreadByName: function(name, thread)
{
this._threadByName.set(name, thread);
},
/**
* @param {!WebInspector.TracingManager.EventPayload} payload
* @return {?WebInspector.TracingModel.Event} event
*/
_addEvent: function(payload)
{
return this.threadById(payload.tid)._addEvent(payload);
},
/**
* @return {!Array.<!WebInspector.TracingModel.Thread>}
*/
sortedThreads: function()
{
return WebInspector.TracingModel.NamedObject._sort(Object.values(this._threads));
},
__proto__: WebInspector.TracingModel.NamedObject.prototype
}
/**
* @constructor
* @extends {WebInspector.TracingModel.NamedObject}
* @param {!WebInspector.TracingModel.Process} process
* @param {number} id
*/
WebInspector.TracingModel.Thread = function(process, id)
{
WebInspector.TracingModel.NamedObject.call(this);
this._process = process;
this._setName("Thread " + id);
this._events = [];
this._asyncEvents = [];
this._id = id;
this._model = process._model;
}
WebInspector.TracingModel.Thread.prototype = {
tracingComplete: function()
{
this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartAndEndTime);
this._events.stableSort(WebInspector.TracingModel.Event.compareStartTime);
var phases = WebInspector.TracingModel.Phase;
var stack = [];
for (var i = 0; i < this._events.length; ++i) {
var e = this._events[i];
e.ordinal = i;
switch (e.phase) {
case phases.End:
this._events[i] = null; // Mark for removal.
// Quietly ignore unbalanced close events, they're legit (we could have missed start one).
if (!stack.length)
continue;
var top = stack.pop();
if (top.name !== e.name || top.categoriesString !== e.categoriesString)
console.error("B/E events mismatch at " + top.startTime + " (" + top.name + ") vs. " + e.startTime + " (" + e.name + ")");
else
top._complete(e);
break;
case phases.Begin:
stack.push(e);
break;
}
}
this._events.remove(null, false);
},
/**
* @param {!WebInspector.TracingManager.EventPayload} payload
* @return {?WebInspector.TracingModel.Event} event
*/
_addEvent: function(payload)
{
var event = payload.ph === WebInspector.TracingModel.Phase.SnapshotObject
? WebInspector.TracingModel.ObjectSnapshot.fromPayload(payload, this)
: WebInspector.TracingModel.Event.fromPayload(payload, this);
if (WebInspector.TracingModel.isTopLevelEvent(event)) {
// Discard nested "top-level" events.
if (this._lastTopLevelEvent && this._lastTopLevelEvent.endTime > event.startTime)
return null;
this._lastTopLevelEvent = event;
}
this._events.push(event);
return event;
},
/**
* @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent
*/
_addAsyncEvent: function(asyncEvent)
{
this._asyncEvents.push(asyncEvent);
},
/**
* @override
* @param {string} name
*/
_setName: function(name)
{
WebInspector.TracingModel.NamedObject.prototype._setName.call(this, name);
this._process._setThreadByName(name, this);
},
/**
* @return {number}
*/
id: function()
{
return this._id;
},
/**
* @return {!WebInspector.TracingModel.Process}
*/
process: function()
{
return this._process;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
events: function()
{
return this._events;
},
/**
* @return {!Array.<!WebInspector.TracingModel.AsyncEvent>}
*/
asyncEvents: function()
{
return this._asyncEvents;
},
__proto__: WebInspector.TracingModel.NamedObject.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SDKObject}
* @param {!WebInspector.Target} target
*/
WebInspector.WorkerManager = function(target)
{
WebInspector.SDKObject.call(this, target);
target.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));
this._lastAnonymousTargetId = 0;
/** @type {!Map.<string, !WebInspector.WorkerConnection>} */
this._connections = new Map();
/** @type {!Map.<string, !WebInspector.Target>} */
this._targetsByWorkerId = new Map();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
this._onSuspendStateChanged();
this.enable();
}
WebInspector.WorkerManager.prototype = {
enable: function()
{
if (this._enabled)
return;
this._enabled = true;
this.target().workerAgent().enable();
this.target().resourceTreeModel.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNavigated, this);
},
disable: function()
{
if (!this._enabled)
return;
this._enabled = false;
this._reset();
this.target().workerAgent().disable();
this.target().resourceTreeModel.removeEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._mainFrameNavigated, this);
},
dispose: function()
{
this._reset();
},
_reset: function()
{
for (var connection of this._connections.values())
connection._close();
this._connections.clear();
this._targetsByWorkerId.clear();
},
_onSuspendStateChanged: function()
{
var suspended = WebInspector.targetManager.allTargetsSuspended();
this.target().workerAgent().setWaitForDebuggerOnStart(!suspended);
},
/**
* @param {string} workerId
* @param {string} url
* @param {boolean} waitingForDebugger
*/
_workerCreated: function(workerId, url, waitingForDebugger)
{
var connection = new WebInspector.WorkerConnection(this, workerId);
this._connections.set(workerId, connection);
var parsedURL = url.asParsedURL();
var workerName = parsedURL ? parsedURL.lastPathComponentWithFragment() : "#" + (++this._lastAnonymousTargetId);
var target = WebInspector.targetManager.createTarget(workerName, WebInspector.Target.Type.DedicatedWorker, connection, this.target());
this._targetsByWorkerId.set(workerId, target);
// Only pause new worker if debugging SW - we are going through the
// pause on start checkbox.
var mainIsServiceWorker = WebInspector.targetManager.mainTarget().isServiceWorker();
if (mainIsServiceWorker && waitingForDebugger)
target.debuggerAgent().pause();
target.runtimeAgent().run();
},
/**
* @param {string} workerId
*/
_workerTerminated: function(workerId)
{
var connection = this._connections.get(workerId);
if (connection)
connection._close();
this._connections.delete(workerId);
this._targetsByWorkerId.delete(workerId);
},
/**
* @param {string} workerId
* @param {string} message
*/
_dispatchMessageFromWorker: function(workerId, message)
{
var connection = this._connections.get(workerId);
if (connection)
connection.dispatch(message);
},
/**
* @param {!WebInspector.Event} event
*/
_mainFrameNavigated: function(event)
{
this._reset();
},
/**
* @param {string} workerId
* @return {?WebInspector.Target}
*/
targetByWorkerId: function(workerId)
{
return this._targetsByWorkerId.get(workerId) || null;
},
__proto__: WebInspector.SDKObject.prototype
}
/**
* @constructor
* @implements {WorkerAgent.Dispatcher}
*/
WebInspector.WorkerDispatcher = function(workerManager)
{
this._workerManager = workerManager;
}
WebInspector.WorkerDispatcher.prototype = {
/**
* @override
* @param {string} workerId
* @param {string} url
* @param {boolean} waitingForDebugger
*/
workerCreated: function(workerId, url, waitingForDebugger)
{
this._workerManager._workerCreated(workerId, url, waitingForDebugger);
},
/**
* @override
* @param {string} workerId
*/
workerTerminated: function(workerId)
{
this._workerManager._workerTerminated(workerId);
},
/**
* @override
* @param {string} workerId
* @param {string} message
*/
dispatchMessageFromWorker: function(workerId, message)
{
this._workerManager._dispatchMessageFromWorker(workerId, message);
}
}
/**
* @constructor
* @extends {InspectorBackendClass.Connection}
* @param {!WebInspector.WorkerManager} workerManager
* @param {string} workerId
*/
WebInspector.WorkerConnection = function(workerManager, workerId)
{
InspectorBackendClass.Connection.call(this);
//FIXME: remove resourceTreeModel and others from worker targets
this.suppressErrorsForDomains(["Worker", "Page", "CSS", "DOM", "DOMStorage", "Database", "Network", "IndexedDB"]);
this._agent = workerManager.target().workerAgent();
this._workerId = workerId;
}
WebInspector.WorkerConnection.prototype = {
/**
* @override
* @param {!Object} messageObject
*/
sendMessage: function(messageObject)
{
this._agent.sendMessageToWorker(this._workerId, JSON.stringify(messageObject));
},
_close: function()
{
this.connectionClosed("worker_terminated");
},
__proto__: InspectorBackendClass.Connection.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| SecurityModel.js | 2.86% | (1 / 35) | 0% | (0 / 14) | 0% | (0 / 6) | 2.86% | (1 / 35) | |
| SecurityPanel.js | 2.53% | (9 / 356) | 0% | (0 / 121) | 0% | (0 / 55) | 2.53% | (9 / 356) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SDKModel}
* @param {!WebInspector.Target} target
*/
WebInspector.SecurityModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.SecurityModel, target);
this._dispatcher = new WebInspector.SecurityDispatcher(this);
this._securityAgent = target.securityAgent();
target.registerSecurityDispatcher(this._dispatcher);
this._securityAgent.enable();
}
WebInspector.SecurityModel.EventTypes = {
SecurityStateChanged: "SecurityStateChanged"
}
WebInspector.SecurityModel.prototype = {
__proto__: WebInspector.SDKModel.prototype
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.SecurityModel}
*/
WebInspector.SecurityModel.fromTarget = function(target)
{
var model = /** @type {?WebInspector.SecurityModel} */ (target.model(WebInspector.SecurityModel));
if (!model)
model = new WebInspector.SecurityModel(target);
return model;
}
/**
* @param {!SecurityAgent.SecurityState} a
* @param {!SecurityAgent.SecurityState} b
* @return {number}
*/
WebInspector.SecurityModel.SecurityStateComparator = function(a, b)
{
var securityStateMap;
if (WebInspector.SecurityModel._symbolicToNumericSecurityState) {
securityStateMap = WebInspector.SecurityModel._symbolicToNumericSecurityState;
} else {
securityStateMap = new Map();
var ordering = [
SecurityAgent.SecurityState.Info,
SecurityAgent.SecurityState.Insecure,
SecurityAgent.SecurityState.Neutral,
SecurityAgent.SecurityState.Warning,
SecurityAgent.SecurityState.Secure,
// Unknown is max so that failed/cancelled requests don't overwrite the origin security state for successful requests,
// and so that failed/cancelled requests appear at the bottom of the origins list.
SecurityAgent.SecurityState.Unknown
];
for (var i = 0; i < ordering.length; i++)
securityStateMap.set(ordering[i], i + 1);
WebInspector.SecurityModel._symbolicToNumericSecurityState = securityStateMap;
}
var aScore = securityStateMap.get(a) || 0;
var bScore = securityStateMap.get(b) || 0;
return aScore - bScore;
}
/**
* @constructor
* @param {!SecurityAgent.SecurityState} securityState
* @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
* @param {?SecurityAgent.MixedContentStatus} mixedContentStatus
* @param {boolean} schemeIsCryptographic
*/
WebInspector.PageSecurityState = function (securityState, explanations, mixedContentStatus, schemeIsCryptographic) {
this.securityState = securityState;
this.explanations = explanations;
this.mixedContentStatus = mixedContentStatus;
this.schemeIsCryptographic = schemeIsCryptographic;
}
/**
* @constructor
* @implements {SecurityAgent.Dispatcher}
*/
WebInspector.SecurityDispatcher = function(model)
{
this._model = model;
}
WebInspector.SecurityDispatcher.prototype = {
/**
* @override
* @param {!SecurityAgent.SecurityState} securityState
* @param {!Array<!SecurityAgent.SecurityStateExplanation>=} explanations
* @param {!SecurityAgent.MixedContentStatus=} mixedContentStatus
* @param {boolean=} schemeIsCryptographic
*/
securityStateChanged: function(securityState, explanations, mixedContentStatus, schemeIsCryptographic)
{
var pageSecurityState = new WebInspector.PageSecurityState(securityState, explanations || [], mixedContentStatus || null, schemeIsCryptographic || false);
this._model.dispatchEventToListeners(WebInspector.SecurityModel.EventTypes.SecurityStateChanged, pageSecurityState);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | 2 1 1 1 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.PanelWithSidebar}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.SecurityPanel = function()
{
WebInspector.PanelWithSidebar.call(this, "security");
this._mainView = new WebInspector.SecurityMainView(this);
this._sidebarMainViewElement = new WebInspector.SecurityPanelSidebarTreeElement(WebInspector.UIString("Overview"), this._setVisibleView.bind(this, this._mainView), "security-main-view-sidebar-tree-item", "lock-icon");
this._sidebarTree = new WebInspector.SecurityPanelSidebarTree(this._sidebarMainViewElement, this.showOrigin.bind(this));
this.panelSidebarElement().appendChild(this._sidebarTree.element);
this.setDefaultFocusedElement(this._sidebarTree.element);
/** @type {!Map<!NetworkAgent.LoaderId, !WebInspector.NetworkRequest>} */
this._lastResponseReceivedForLoaderId = new Map();
/** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPanel.OriginState>} */
this._origins = new Map();
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
/** @type {!Map<!WebInspector.NetworkLogView.MixedContentFilterValues, number>} */
this._filterRequestCounts = new Map();
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.ResponseReceived, this._onResponseReceived, this);
WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
WebInspector.targetManager.addModelListener(WebInspector.SecurityModel, WebInspector.SecurityModel.EventTypes.SecurityStateChanged, this._onSecurityStateChanged, this);
}
/** @typedef {string} */
WebInspector.SecurityPanel.Origin;
/**
* @typedef {Object}
* @property {!SecurityAgent.SecurityState} securityState - Current security state of the origin.
* @property {?NetworkAgent.SecurityDetails} securityDetails - Security details of the origin, if available.
* @property {?Promise<!NetworkAgent.CertificateDetails>} certificateDetailsPromise - Certificate details of the origin. Only available if securityDetails are available.
* @property {?WebInspector.SecurityOriginView} originView - Current SecurityOriginView corresponding to origin.
*/
WebInspector.SecurityPanel.OriginState;
WebInspector.SecurityPanel.prototype = {
/**
* @param {!SecurityAgent.SecurityState} securityState
*/
setRanInsecureContentStyle: function(securityState)
{
this._ranInsecureContentStyle = securityState;
},
/**
* @param {!SecurityAgent.SecurityState} securityState
*/
setDisplayedInsecureContentStyle: function(securityState)
{
this._displayedInsecureContentStyle = securityState;
},
/**
* @param {!SecurityAgent.SecurityState} newSecurityState
* @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
* @param {?SecurityAgent.MixedContentStatus} mixedContentStatus
* @param {boolean} schemeIsCryptographic
*/
_updateSecurityState: function(newSecurityState, explanations, mixedContentStatus, schemeIsCryptographic)
{
this._sidebarMainViewElement.setSecurityState(newSecurityState);
this._mainView.updateSecurityState(newSecurityState, explanations, mixedContentStatus, schemeIsCryptographic);
},
/**
* @param {!WebInspector.Event} event
*/
_onSecurityStateChanged: function(event)
{
var data = /** @type {!WebInspector.PageSecurityState} */ (event.data);
var securityState = /** @type {!SecurityAgent.SecurityState} */ (data.securityState);
var explanations = /** @type {!Array<!SecurityAgent.SecurityStateExplanation>} */ (data.explanations);
var mixedContentStatus = /** @type {?SecurityAgent.MixedContentStatus} */ (data.mixedContentStatus);
var schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptographic);
this._updateSecurityState(securityState, explanations, mixedContentStatus, schemeIsCryptographic);
},
selectAndSwitchToMainView: function()
{
// The sidebar element will trigger displaying the main view. Rather than making a redundant call to display the main view, we rely on this.
this._sidebarMainViewElement.select();
},
/**
* @param {!WebInspector.SecurityPanel.Origin} origin
*/
showOrigin: function(origin)
{
var originState = this._origins.get(origin);
if (!originState.originView)
originState.originView = new WebInspector.SecurityOriginView(this, origin, originState);
this._setVisibleView(originState.originView);
},
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (!this._visibleView)
this.selectAndSwitchToMainView();
},
/**
* @param {!WebInspector.VBox} view
*/
_setVisibleView: function(view)
{
if (this._visibleView === view)
return;
if (this._visibleView)
this._visibleView.detach();
this._visibleView = view;
if (view)
this.splitWidget().setMainWidget(view);
},
/**
* @param {!WebInspector.Event} event
*/
_onResponseReceived: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
if (request.resourceType() == WebInspector.resourceTypes.Document)
this._lastResponseReceivedForLoaderId.set(request.loaderId, request);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_processRequest: function(request)
{
var origin = WebInspector.ParsedURL.splitURLIntoPathComponents(request.url)[0];
if (!origin) {
// We don't handle resources like data: URIs. Most of them don't affect the lock icon.
return;
}
var securityState = /** @type {!SecurityAgent.SecurityState} */ (request.securityState());
if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Blockable && this._ranInsecureContentStyle)
securityState = this._ranInsecureContentStyle;
else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.OptionallyBlockable && this._displayedInsecureContentStyle)
securityState = this._displayedInsecureContentStyle;
if (this._origins.has(origin)) {
var originState = this._origins.get(origin);
var oldSecurityState = originState.securityState;
originState.securityState = this._securityStateMin(oldSecurityState, securityState);
if (oldSecurityState != originState.securityState) {
this._sidebarTree.updateOrigin(origin, securityState);
if (originState.originView)
originState.originView.setSecurityState(securityState);
}
} else {
// TODO(lgarron): Store a (deduplicated) list of different security details we have seen. https://crbug.com/503170
var originState = {};
originState.securityState = securityState;
var securityDetails = request.securityDetails();
if (securityDetails) {
originState.securityDetails = securityDetails;
originState.certificateDetailsPromise = request.target().networkManager.certificateDetailsPromise(securityDetails.certificateId);
}
this._origins.set(origin, originState);
this._sidebarTree.addOrigin(origin, securityState);
// Don't construct the origin view yet (let it happen lazily).
}
},
/**
* @param {!WebInspector.Event} event
*/
_onRequestFinished: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
this._updateFilterRequestCounts(request);
this._processRequest(request);
},
/**
* @param {!WebInspector.NetworkRequest} request
*/
_updateFilterRequestCounts: function(request)
{
if (request.mixedContentType === NetworkAgent.RequestMixedContentType.None)
return;
/** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */
var filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.All;
if (request.wasBlocked())
filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blocked;
else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Blockable)
filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden;
else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.OptionallyBlockable)
filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Displayed;
if (!this._filterRequestCounts.has(filterKey))
this._filterRequestCounts.set(filterKey, 1);
else
this._filterRequestCounts.set(filterKey, this._filterRequestCounts.get(filterKey) + 1);
this._mainView.refreshExplanations();
},
/**
* @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
* @return {number}
*/
filterRequestCount: function(filterKey)
{
return this._filterRequestCounts.get(filterKey) || 0;
},
/**
* @param {!SecurityAgent.SecurityState} stateA
* @param {!SecurityAgent.SecurityState} stateB
* @return {!SecurityAgent.SecurityState}
*/
_securityStateMin: function(stateA, stateB)
{
return WebInspector.SecurityModel.SecurityStateComparator(stateA, stateB) < 0 ? stateA : stateB;
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
WebInspector.SecurityModel.fromTarget(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
},
_clearOrigins: function()
{
this.selectAndSwitchToMainView();
this._sidebarTree.clearOrigins();
this._origins.clear();
this._lastResponseReceivedForLoaderId.clear();
this._filterRequestCounts.clear();
},
/**
* @param {!WebInspector.Event} event
*/
_onMainFrameNavigated: function(event) {
var frame = /** type {!PageAgent.Frame}*/ (event.data);
var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId);
this._clearOrigins();
var origin = WebInspector.ParsedURL.splitURLIntoPathComponents(request.url)[0];
this._sidebarTree.setMainOrigin(origin);
if (request)
this._processRequest(request);
},
__proto__: WebInspector.PanelWithSidebar.prototype
}
/**
* @return {!WebInspector.SecurityPanel}
*/
WebInspector.SecurityPanel._instance = function()
{
if (!WebInspector.SecurityPanel._instanceObject)
WebInspector.SecurityPanel._instanceObject = new WebInspector.SecurityPanel();
return WebInspector.SecurityPanel._instanceObject;
}
/**
* @param {string} text
* @param {!NetworkAgent.CertificateId} certificateId
* @return {!Element}
*/
WebInspector.SecurityPanel.createCertificateViewerButton = function(text, certificateId)
{
/**
* @param {!Event} e
*/
function showCertificateViewer(e)
{
e.consume();
WebInspector.multitargetNetworkManager.showCertificateViewer(/** @type {number} */ (certificateId));
}
return createTextButton(text, showCertificateViewer, "security-certificate-button");
}
/**
* @constructor
* @extends {TreeOutlineInShadow}
* @param {!WebInspector.SecurityPanelSidebarTreeElement} mainViewElement
* @param {function(!WebInspector.SecurityPanel.Origin)} showOriginInPanel
*/
WebInspector.SecurityPanelSidebarTree = function(mainViewElement, showOriginInPanel)
{
this._showOriginInPanel = showOriginInPanel;
this._mainOrigin = null;
TreeOutlineInShadow.call(this);
this.element.classList.add("sidebar-tree");
this.registerRequiredCSS("security/sidebar.css");
this.registerRequiredCSS("security/lockIcon.css");
this.appendChild(mainViewElement);
/** @type {!Map<!WebInspector.SecurityPanelSidebarTree.OriginGroupName, !WebInspector.SidebarSectionTreeElement>} */
this._originGroups = new Map();
for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) {
var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupName[key];
var originGroup = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString(originGroupName));
originGroup.listItemElement.classList.add("security-sidebar-origins");
this._originGroups.set(originGroupName, originGroup);
this.appendChild(originGroup);
}
this._clearOriginGroups();
// This message will be removed by clearOrigins() during the first new page load after the panel was opened.
var mainViewReloadMessage = new WebInspector.SidebarTreeElement("security-main-view-reload-message", WebInspector.UIString("Reload to view details"));
mainViewReloadMessage.selectable = false;
this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin).appendChild(mainViewReloadMessage);
/** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPanelSidebarTreeElement>} */
this._elementsByOrigin = new Map();
}
WebInspector.SecurityPanelSidebarTree.prototype = {
/**
* @param {!WebInspector.SecurityPanel.Origin} origin
* @param {!SecurityAgent.SecurityState} securityState
*/
addOrigin: function(origin, securityState)
{
var originElement = new WebInspector.SecurityPanelSidebarTreeElement(origin, this._showOriginInPanel.bind(this, origin), "security-sidebar-tree-item", "security-property");
originElement.listItemElement.title = origin;
this._elementsByOrigin.set(origin, originElement);
this.updateOrigin(origin, securityState);
},
/**
* @param {!WebInspector.SecurityPanel.Origin} origin
*/
setMainOrigin: function(origin)
{
this._mainOrigin = origin;
},
/**
* @param {!WebInspector.SecurityPanel.Origin} origin
* @param {!SecurityAgent.SecurityState} securityState
*/
updateOrigin: function(origin, securityState)
{
var originElement = /** @type {!WebInspector.SecurityPanelSidebarTreeElement} */ (this._elementsByOrigin.get(origin));
originElement.setSecurityState(securityState);
var newParent;
if (origin === this._mainOrigin) {
newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin);
} else {
switch (securityState) {
case SecurityAgent.SecurityState.Secure:
newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.Secure);
break;
case SecurityAgent.SecurityState.Unknown:
newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.Unknown);
break;
default:
newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.NonSecure);
break;
}
}
var oldParent = originElement.parent;
if (oldParent !== newParent) {
if (oldParent) {
oldParent.removeChild(originElement);
if (oldParent.childCount() === 0)
oldParent.hidden = true;
}
newParent.appendChild(originElement);
newParent.hidden = false;
}
},
_clearOriginGroups: function()
{
for (var originGroup of this._originGroups.values()) {
originGroup.removeChildren();
originGroup.hidden = true;
}
this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin).hidden = false;
},
clearOrigins: function()
{
this._clearOriginGroups();
this._elementsByOrigin.clear();
},
__proto__: TreeOutlineInShadow.prototype
}
/**
* A mapping from Javascript key IDs to names (sidebar section titles).
* Note: The names are used as keys into a map, so they must be distinct from each other.
* @enum {string}
*/
WebInspector.SecurityPanelSidebarTree.OriginGroupName = {
MainOrigin: "Main Origin",
NonSecure: "Non-Secure Origins",
Secure: "Secure Origins",
Unknown: "Unknown / Canceled"
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
* @param {string} text
* @param {function()} selectCallback
* @param {string} className
* @param {string} cssPrefix
*/
WebInspector.SecurityPanelSidebarTreeElement = function(text, selectCallback, className, cssPrefix)
{
this._selectCallback = selectCallback;
this._cssPrefix = cssPrefix;
WebInspector.SidebarTreeElement.call(this, className, text);
this.iconElement.classList.add(this._cssPrefix);
this.setSecurityState(SecurityAgent.SecurityState.Unknown);
}
WebInspector.SecurityPanelSidebarTreeElement.prototype = {
/**
* @param {!SecurityAgent.SecurityState} newSecurityState
*/
setSecurityState: function(newSecurityState)
{
if (this._securityState)
this.iconElement.classList.remove(this._cssPrefix + "-" + this._securityState)
this._securityState = newSecurityState;
this.iconElement.classList.add(this._cssPrefix + "-" + newSecurityState);
},
/**
* @return {!SecurityAgent.SecurityState}
*/
securityState: function()
{
return this._securityState;
},
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._selectCallback();
return true;
},
__proto__: WebInspector.SidebarTreeElement.prototype
}
/**
* @param {!WebInspector.SecurityPanelSidebarTreeElement} a
* @param {!WebInspector.SecurityPanelSidebarTreeElement} b
* @return {number}
*/
WebInspector.SecurityPanelSidebarTreeElement.SecurityStateComparator = function(a, b)
{
return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(), b.securityState());
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.SecurityPanelFactory = function()
{
}
WebInspector.SecurityPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.SecurityPanel._instance();
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.SecurityPanel} panel
*/
WebInspector.SecurityMainView = function(panel)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("security/mainView.css");
this.registerRequiredCSS("security/lockIcon.css");
this.setMinimumSize(200, 100);
this.contentElement.classList.add("security-main-view");
this._panel = panel;
this._summarySection = this.contentElement.createChild("div", "security-summary");
this._securityExplanations = this.contentElement.createChild("div", "security-explanation-list");
// Fill the security summary section.
this._summarySection.createChild("div", "security-summary-section-title").textContent = WebInspector.UIString("Security Overview");
var lockSpectrum = this._summarySection.createChild("div", "lock-spectrum");
lockSpectrum.createChild("div", "lock-icon lock-icon-secure").title = WebInspector.UIString("Secure");
lockSpectrum.createChild("div", "security-summary-lock-spacer");
lockSpectrum.createChild("div", "lock-icon lock-icon-neutral").title = WebInspector.UIString("Not Secure");
lockSpectrum.createChild("div", "security-summary-lock-spacer");
lockSpectrum.createChild("div", "lock-icon lock-icon-insecure").title = WebInspector.UIString("Insecure (Broken)");
this._summarySection.createChild("div", "triangle-pointer-container").createChild("div", "triangle-pointer-wrapper").createChild("div", "triangle-pointer");
this._summaryText = this._summarySection.createChild("div", "security-summary-text");
}
WebInspector.SecurityMainView.prototype = {
/**
* @param {!SecurityAgent.SecurityStateExplanation} explanation
* @return {!Element}
*/
_addExplanation: function(explanation)
{
var explanationSection = this._securityExplanations.createChild("div", "security-explanation");
explanationSection.classList.add("security-explanation-" + explanation.securityState);
explanationSection.createChild("div", "security-property").classList.add("security-property-" + explanation.securityState);
var text = explanationSection.createChild("div", "security-explanation-text");
text.createChild("div", "security-explanation-title").textContent = explanation.summary;
text.createChild("div").textContent = explanation.description;
if (explanation.certificateId) {
text.appendChild(WebInspector.SecurityPanel.createCertificateViewerButton(WebInspector.UIString("View certificate"), explanation.certificateId));
}
return text;
},
/**
* @param {!SecurityAgent.SecurityState} newSecurityState
* @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
* @param {?SecurityAgent.MixedContentStatus} mixedContentStatus
* @param {boolean} schemeIsCryptographic
*/
updateSecurityState: function(newSecurityState, explanations, mixedContentStatus, schemeIsCryptographic)
{
// Remove old state.
// It's safe to call this even when this._securityState is undefined.
this._summarySection.classList.remove("security-summary-" + this._securityState);
// Add new state.
this._securityState = newSecurityState;
this._summarySection.classList.add("security-summary-" + this._securityState);
var summaryExplanationStrings = {
"unknown": WebInspector.UIString("This security of this page is unknown."),
"insecure": WebInspector.UIString("This page is insecure (broken HTTPS)."),
"neutral": WebInspector.UIString("This page is not secure."),
"secure": WebInspector.UIString("This page is secure (valid HTTPS).")
}
this._summaryText.textContent = summaryExplanationStrings[this._securityState];
this._explanations = explanations,
this._mixedContentStatus = mixedContentStatus;
this._schemeIsCryptographic = schemeIsCryptographic;
this._panel.setRanInsecureContentStyle(mixedContentStatus.ranInsecureContentStyle);
this._panel.setDisplayedInsecureContentStyle(mixedContentStatus.displayedInsecureContentStyle);
this.refreshExplanations();
},
refreshExplanations: function ()
{
this._securityExplanations.removeChildren();
for (var explanation of this._explanations)
this._addExplanation(explanation);
this._addMixedContentExplanations();
},
_addMixedContentExplanations: function ()
{
if (!this._schemeIsCryptographic)
return;
if (this._mixedContentStatus && (this._mixedContentStatus.ranInsecureContent || this._mixedContentStatus.displayedInsecureContent)) {
if (this._mixedContentStatus.ranInsecureContent)
this._addMixedContentExplanation(this._mixedContentStatus.ranInsecureContentStyle, WebInspector.UIString("Active Mixed Content"), WebInspector.UIString("You have recently allowed insecure content (such as scripts or iframes) to run on this site."), WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden, showBlockOverriddenMixedContentInNetworkPanel);
if (this._mixedContentStatus.displayedInsecureContent)
this._addMixedContentExplanation(this._mixedContentStatus.displayedInsecureContentStyle, WebInspector.UIString("Mixed Content"), WebInspector.UIString("The site includes HTTP resources."), WebInspector.NetworkLogView.MixedContentFilterValues.Displayed, showDisplayedMixedContentInNetworkPanel);
}
if (this._mixedContentStatus && (!this._mixedContentStatus.displayedInsecureContent && !this._mixedContentStatus.ranInsecureContent)) {
this._addExplanation(/** @type {!SecurityAgent.SecurityStateExplanation} */ ({
"securityState": SecurityAgent.SecurityState.Secure,
"summary": WebInspector.UIString("Secure Resources"),
"description": WebInspector.UIString("All resources on this page are served securely.")
}));
}
if (this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedContentFilterValues.Blocked) > 0)
this._addMixedContentExplanation(SecurityAgent.SecurityState.Info, WebInspector.UIString("Blocked mixed content"), WebInspector.UIString("Your page requested insecure resources that were blocked."), WebInspector.NetworkLogView.MixedContentFilterValues.Blocked, showBlockedMixedContentInNetworkPanel);
/**
* @param {!Event} e
*/
function showDisplayedMixedContentInNetworkPanel(e)
{
e.consume();
WebInspector.NetworkPanel.revealAndFilter([
{
filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Displayed
}
]);
}
/**
* @param {!Event} e
*/
function showBlockOverriddenMixedContentInNetworkPanel(e)
{
e.consume();
WebInspector.NetworkPanel.revealAndFilter([
{
filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden
}
]);
}
/**
* @param {!Event} e
*/
function showBlockedMixedContentInNetworkPanel(e)
{
e.consume();
WebInspector.NetworkPanel.revealAndFilter([
{
filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Blocked
}
]);
}
},
/**
* @param {!SecurityAgent.SecurityState} securityState
* @param {string} summary
* @param {string} description
* @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
* @param {!Function} networkFilterFn
*/
_addMixedContentExplanation: function(securityState, summary, description, filterKey, networkFilterFn)
{
var mixedContentExplanation = /** @type {!SecurityAgent.SecurityStateExplanation} */ ({
"securityState": securityState,
"summary": summary,
"description": description
});
var filterRequestCount = this._panel.filterRequestCount(filterKey);
var requestsAnchor = this._addExplanation(mixedContentExplanation).createChild("div", "security-mixed-content link");
if (filterRequestCount > 0) {
requestsAnchor.textContent = WebInspector.UIString("View %d request%s in Network Panel", filterRequestCount, (filterRequestCount > 1 ? "s" : ""));
} else {
// Network instrumentation might not have been enabled for the page load, so the security panel does not necessarily know a count of individual mixed requests at this point. Point the user at the Network Panel which prompts them to refresh.
requestsAnchor.textContent = WebInspector.UIString("View requests in Network Panel");
}
requestsAnchor.href = "";
requestsAnchor.addEventListener("click", networkFilterFn);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.SecurityPanel} panel
* @param {!WebInspector.SecurityPanel.Origin} origin
* @param {!WebInspector.SecurityPanel.OriginState} originState
*/
WebInspector.SecurityOriginView = function(panel, origin, originState)
{
this._panel = panel;
WebInspector.VBox.call(this);
this.setMinimumSize(200, 100);
this.element.classList.add("security-origin-view");
this.registerRequiredCSS("security/originView.css");
this.registerRequiredCSS("security/lockIcon.css");
var titleSection = this.element.createChild("div", "origin-view-section title-section");
titleSection.createChild("div", "origin-view-title").textContent = WebInspector.UIString("Origin");
var originDisplay = titleSection.createChild("div", "origin-display");
this._originLockIcon = originDisplay.createChild("span", "security-property");
this._originLockIcon.classList.add("security-property-" + originState.securityState);
// TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589
originDisplay.createChild("span", "origin").textContent = origin;
var originNetworkLink = originDisplay.createChild("div", "link");
originNetworkLink.textContent = WebInspector.UIString("View requests in Network Panel");
function showOriginRequestsInNetworkPanel()
{
var parsedURL = new WebInspector.ParsedURL(origin);
WebInspector.NetworkPanel.revealAndFilter([
{
filterType: WebInspector.NetworkLogView.FilterType.Domain,
filterValue: parsedURL.host
},
{
filterType: WebInspector.NetworkLogView.FilterType.Scheme,
filterValue: parsedURL.scheme
}
]);
}
originNetworkLink.addEventListener("click", showOriginRequestsInNetworkPanel, false);
if (originState.securityDetails) {
var connectionSection = this.element.createChild("div", "origin-view-section");
connectionSection.createChild("div", "origin-view-section-title").textContent = WebInspector.UIString("Connection");
var table = new WebInspector.SecurityDetailsTable();
connectionSection.appendChild(table.element());
table.addRow("Protocol", originState.securityDetails.protocol);
table.addRow("Key Exchange", originState.securityDetails.keyExchange);
table.addRow("Cipher Suite", originState.securityDetails.cipher + (originState.securityDetails.mac ? " with " + originState.securityDetails.mac : ""));
// Create the certificate section outside the callback, so that it appears in the right place.
var certificateSection = this.element.createChild("div", "origin-view-section");
certificateSection.createChild("div", "origin-view-section-title").textContent = WebInspector.UIString("Certificate");
/**
* @this {WebInspector.SecurityOriginView}
* @param {?NetworkAgent.CertificateDetails} certificateDetails
*/
function displayCertificateDetails(certificateDetails)
{
var sanDiv = this._createSanDiv(certificateDetails.subject);
var validFromString = new Date(1000 * certificateDetails.validFrom).toUTCString();
var validUntilString = new Date(1000 * certificateDetails.validTo).toUTCString();
var table = new WebInspector.SecurityDetailsTable();
certificateSection.appendChild(table.element());
table.addRow(WebInspector.UIString("Subject"), certificateDetails.subject.name);
table.addRow(WebInspector.UIString("SAN"), sanDiv);
table.addRow(WebInspector.UIString("Valid From"), validFromString);
table.addRow(WebInspector.UIString("Valid Until"), validUntilString);
table.addRow(WebInspector.UIString("Issuer"), certificateDetails.issuer);
table.addRow(WebInspector.UIString("SCTs"), this.sctSummary(originState.securityDetails.certificateValidationDetails));
table.addRow("", WebInspector.SecurityPanel.createCertificateViewerButton(WebInspector.UIString("Open full certificate details"), originState.securityDetails.certificateId));
}
function displayCertificateDetailsUnavailable ()
{
certificateSection.createChild("div").textContent = WebInspector.UIString("Certificate details unavailable.");
}
originState.certificateDetailsPromise.then(displayCertificateDetails.bind(this), displayCertificateDetailsUnavailable);
var noteSection = this.element.createChild("div", "origin-view-section");
// TODO(lgarron): Fix the issue and then remove this section. See comment in SecurityPanel._processRequest().
noteSection.createChild("div").textContent = WebInspector.UIString("The security details above are from the first inspected response.");
} else if (originState.securityState !== SecurityAgent.SecurityState.Unknown) {
var notSecureSection = this.element.createChild("div", "origin-view-section");
notSecureSection.createChild("div", "origin-view-section-title").textContent = WebInspector.UIString("Not Secure");
notSecureSection.createChild("div").textContent = WebInspector.UIString("Your connection to this origin is not secure.");
} else {
var noInfoSection = this.element.createChild("div", "origin-view-section");
noInfoSection.createChild("div", "origin-view-section-title").textContent = WebInspector.UIString("No Security Information");
noInfoSection.createChild("div").textContent = WebInspector.UIString("No security details are available for this origin.");
}
}
WebInspector.SecurityOriginView.prototype = {
/**
* @param {!NetworkAgent.CertificateSubject} certificateSubject
* *return {!Element}
*/
_createSanDiv: function(certificateSubject)
{
var sanDiv = createElement("div");
var sanList = certificateSubject.sanDnsNames.concat(certificateSubject.sanIpAddresses);
if (sanList.length === 0) {
sanDiv.textContent = WebInspector.UIString("(N/A)");
sanDiv.classList.add("empty-san");
} else {
var truncatedNumToShow = 2;
var listIsTruncated = sanList.length > truncatedNumToShow;
for (var i = 0; i < sanList.length; i++) {
var span = sanDiv.createChild("span", "san-entry");
span.textContent = sanList[i];
if (listIsTruncated && i >= truncatedNumToShow)
span.classList.add("truncated-entry");
}
if (listIsTruncated) {
var truncatedSANToggle = sanDiv.createChild("div", "link");
truncatedSANToggle.href = "";
function toggleSANTruncation()
{
if (sanDiv.classList.contains("truncated-san")) {
sanDiv.classList.remove("truncated-san")
truncatedSANToggle.textContent = WebInspector.UIString("Show less");
} else {
sanDiv.classList.add("truncated-san");
truncatedSANToggle.textContent = WebInspector.UIString("Show more (%d total)", sanList.length);
}
}
truncatedSANToggle.addEventListener("click", toggleSANTruncation, false);
toggleSANTruncation();
}
}
return sanDiv;
},
/**
* @param {!SecurityAgent.SecurityState} newSecurityState
*/
setSecurityState: function(newSecurityState)
{
for (var className of Array.prototype.slice.call(this._originLockIcon.classList)) {
if (className.startsWith("security-property-"))
this._originLockIcon.classList.remove(className);
}
this._originLockIcon.classList.add("security-property-" + newSecurityState);
},
/**
* @constructor
* @param {?NetworkAgent.CertificateValidationDetails} details
* @return {string}
*/
sctSummary: function(details)
{
if (!details)
return WebInspector.UIString("N/A");
var sctTypeList = [];
if (details.numValidScts)
sctTypeList.push(WebInspector.UIString("%d valid SCT%s", details.numValidScts, (details.numValidScts > 1) ? "s" : ""));
if (details.numInvalidScts)
sctTypeList.push(WebInspector.UIString("%d invalid SCT%s", details.numInvalidScts, (details.numInvalidScts > 1) ? "s" : ""));
if (details.numUnknownScts)
sctTypeList.push(WebInspector.UIString("%d SCT%s from unknown logs", details.numUnknownScts, (details.numUnknownScts > 1) ? "s" : ""));
return sctTypeList.length ? sctTypeList.join(", ") : WebInspector.UIString("0 SCTs");
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
*/
WebInspector.SecurityDetailsTable = function()
{
this._element = createElement("table");
this._element.classList.add("details-table");
}
WebInspector.SecurityDetailsTable.prototype = {
/**
* @return: {!Element}
*/
element: function()
{
return this._element;
},
/**
* @param {string} key
* @param {string|!Node} value
*/
addRow: function(key, value)
{
var row = this._element.createChild("div", "details-table-row");
row.createChild("div").textContent = key;
var valueDiv = row.createChild("div");
if (typeof value === "string") {
valueDiv.textContent = value;
} else {
valueDiv.appendChild(value);
}
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| EditFileSystemView.js | 2.82% | (4 / 142) | 0% | (0 / 46) | 0% | (0 / 15) | 2.82% | (4 / 142) | |
| FrameworkBlackboxSettingsTab.js | 4.05% | (3 / 74) | 0% | (0 / 16) | 0% | (0 / 11) | 4.05% | (3 / 74) | |
| SettingsScreen.js | 3.54% | (9 / 254) | 0% | (0 / 64) | 0% | (0 / 37) | 3.56% | (9 / 253) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | 2 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ListWidget.Delegate}
* @param {string} fileSystemPath
*/
WebInspector.EditFileSystemView = function(fileSystemPath)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("settings/editFileSystemView.css");
this._fileSystemPath = fileSystemPath;
this._eventListeners = [
WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded, this._update, this),
WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved, this._update, this),
WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderAdded, this._update, this),
WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, this._update, this)
];
var mappingsHeader = this.contentElement.createChild("div", "file-system-header");
mappingsHeader.createChild("div", "file-system-header-text").textContent = WebInspector.UIString("Mappings");
mappingsHeader.appendChild(createTextButton(WebInspector.UIString("Add"), this._addMappingButtonClicked.bind(this), "add-button"));
this._mappingsList = new WebInspector.ListWidget(this);
this._mappingsList.element.classList.add("file-system-list");
this._mappingsList.registerRequiredCSS("settings/editFileSystemView.css");
var mappingsPlaceholder = createElementWithClass("div", "file-system-list-empty");
mappingsPlaceholder.textContent = WebInspector.UIString("No mappings");
this._mappingsList.setEmptyPlaceholder(mappingsPlaceholder);
this._mappingsList.show(this.contentElement);
var excludedFoldersHeader = this.contentElement.createChild("div", "file-system-header");
excludedFoldersHeader.createChild("div", "file-system-header-text").textContent = WebInspector.UIString("Excluded folders");
excludedFoldersHeader.appendChild(createTextButton(WebInspector.UIString("Add"), this._addExcludedFolderButtonClicked.bind(this), "add-button"));
this._excludedFoldersList = new WebInspector.ListWidget(this);
this._excludedFoldersList.element.classList.add("file-system-list");
this._excludedFoldersList.registerRequiredCSS("settings/editFileSystemView.css");
var excludedFoldersPlaceholder = createElementWithClass("div", "file-system-list-empty");
excludedFoldersPlaceholder.textContent = WebInspector.UIString("No excluded folders");
this._excludedFoldersList.setEmptyPlaceholder(excludedFoldersPlaceholder);
this._excludedFoldersList.show(this.contentElement);
this.contentElement.tabIndex = 0;
this._update();
}
WebInspector.EditFileSystemView.prototype = {
dispose: function()
{
WebInspector.EventTarget.removeEventListeners(this._eventListeners);
},
_update: function()
{
if (this._muteUpdate)
return;
this._mappingsList.clear();
this._mappings = [];
var mappings = WebInspector.fileSystemMapping.mappingEntries(this._fileSystemPath);
for (var entry of mappings) {
if (entry.configurable) {
this._mappingsList.appendItem(entry, true);
this._mappings.push(entry);
}
}
for (var entry of mappings) {
if (!entry.configurable) {
this._mappingsList.appendItem(entry, false);
this._mappings.push(entry);
}
}
this._excludedFoldersList.clear();
this._excludedFolders = [];
for (var folder of WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).excludedFolders().values()) {
this._excludedFolders.push(folder);
this._excludedFoldersList.appendItem(folder, true);
}
for (var folder of WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).nonConfigurableExcludedFolders().values()) {
this._excludedFolders.push(folder);
this._excludedFoldersList.appendItem(folder, false);
}
},
_addMappingButtonClicked: function()
{
var entry = new WebInspector.FileSystemMapping.Entry(this._fileSystemPath, "", "", true);
this._mappingsList.addNewItem(0, entry);
},
_addExcludedFolderButtonClicked: function()
{
this._excludedFoldersList.addNewItem(0, "");
},
/**
* @override
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable)
{
var element = createElementWithClass("div", "file-system-list-item");
if (!editable)
element.classList.add("locked");
if (item instanceof WebInspector.FileSystemMapping.Entry) {
var entry = /** @type {!WebInspector.FileSystemMapping.Entry} */ (item);
var urlPrefix = entry.configurable ? entry.urlPrefix : WebInspector.UIString("%s (via .devtools)", entry.urlPrefix);
var urlPrefixElement = element.createChild("div", "file-system-value");
urlPrefixElement.textContent = urlPrefix;
urlPrefixElement.title = urlPrefix;
element.createChild("div", "file-system-separator");
var pathPrefixElement = element.createChild("div", "file-system-value");
pathPrefixElement.textContent = entry.pathPrefix;
pathPrefixElement.title = entry.pathPrefix;
} else {
var pathPrefix = /** @type {string} */ (editable ? item : WebInspector.UIString("%s (via .devtools)", item));
var pathPrefixElement = element.createChild("div", "file-system-value");
pathPrefixElement.textContent = pathPrefix;
pathPrefixElement.title = pathPrefix;
}
element.createChild("div", "file-system-locked").title = WebInspector.UIString("From .devtools file");
return element;
},
/**
* @override
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index)
{
if (item instanceof WebInspector.FileSystemMapping.Entry) {
var entry = this._mappings[index];
WebInspector.fileSystemMapping.removeFileMapping(entry.fileSystemPath, entry.urlPrefix, entry.pathPrefix);
} else {
WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).removeExcludedFolder(this._excludedFolders[index]);
}
},
/**
* @override
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew)
{
this._muteUpdate = true;
if (item instanceof WebInspector.FileSystemMapping.Entry) {
var entry = /** @type {!WebInspector.FileSystemMapping.Entry} */ (item);
if (!isNew)
WebInspector.fileSystemMapping.removeFileMapping(this._fileSystemPath, entry.urlPrefix, entry.pathPrefix);
WebInspector.fileSystemMapping.addFileMapping(this._fileSystemPath, this._normalizePrefix(editor.control("urlPrefix").value), this._normalizePrefix(editor.control("pathPrefix").value));
} else {
if (!isNew)
WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).removeExcludedFolder(/** @type {string} */ (item));
WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).addExcludedFolder(this._normalizePrefix(editor.control("pathPrefix").value));
}
this._muteUpdate = false;
this._update();
},
/**
* @override
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item)
{
if (item instanceof WebInspector.FileSystemMapping.Entry) {
var entry = /** @type {!WebInspector.FileSystemMapping.Entry} */ (item);
var editor = this._createMappingEditor();
editor.control("urlPrefix").value = entry.urlPrefix;
editor.control("pathPrefix").value = entry.pathPrefix;
return editor;
} else {
var editor = this._createExcludedFolderEditor();
editor.control("pathPrefix").value = item;
return editor;
}
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createMappingEditor: function()
{
if (this._mappingEditor)
return this._mappingEditor;
var editor = new WebInspector.ListWidget.Editor();
this._mappingEditor = editor;
var content = editor.contentElement();
var titles = content.createChild("div", "file-system-edit-row");
titles.createChild("div", "file-system-value").textContent = WebInspector.UIString("URL prefix");
titles.createChild("div", "file-system-separator file-system-separator-invisible");
titles.createChild("div", "file-system-value").textContent = WebInspector.UIString("Folder path");
var fields = content.createChild("div", "file-system-edit-row");
fields.createChild("div", "file-system-value").appendChild(editor.createInput("urlPrefix", "text", "http://localhost:8000/url", urlPrefixValidator.bind(this)));
fields.createChild("div", "file-system-separator file-system-separator-invisible");
fields.createChild("div", "file-system-value").appendChild(editor.createInput("pathPrefix", "text", "/path/to/folder/", pathPrefixValidator.bind(this)));
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
* @this {WebInspector.EditFileSystemView}
*/
function urlPrefixValidator(item, index, input)
{
var prefix = this._normalizePrefix(input.value);
for (var i = 0; i < this._mappings.length; ++i) {
if (i !== index && this._mappings[i].configurable && this._mappings[i].urlPrefix === prefix)
return false;
}
return !!prefix;
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
* @this {WebInspector.EditFileSystemView}
*/
function pathPrefixValidator(item, index, input)
{
var prefix = this._normalizePrefix(input.value);
for (var i = 0; i < this._mappings.length; ++i) {
if (i !== index && this._mappings[i].configurable && this._mappings[i].pathPrefix === prefix)
return false;
}
return !!prefix;
}
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createExcludedFolderEditor: function()
{
if (this._excludedFolderEditor)
return this._excludedFolderEditor;
var editor = new WebInspector.ListWidget.Editor();
this._excludedFolderEditor = editor;
var content = editor.contentElement();
var titles = content.createChild("div", "file-system-edit-row");
titles.createChild("div", "file-system-value").textContent = WebInspector.UIString("Folder path");
var fields = content.createChild("div", "file-system-edit-row");
fields.createChild("div", "file-system-value").appendChild(editor.createInput("pathPrefix", "text", "/path/to/folder/", pathPrefixValidator.bind(this)));
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
* @this {WebInspector.EditFileSystemView}
*/
function pathPrefixValidator(item, index, input)
{
var prefix = this._normalizePrefix(input.value);
var configurableCount = WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).excludedFolders().size;
for (var i = 0; i < configurableCount; ++i) {
if (i !== index && this._excludedFolders[i] === prefix)
return false;
}
return !!prefix;
}
},
/**
* @param {string} prefix
* @return {string}
*/
_normalizePrefix: function(prefix)
{
if (!prefix)
return "";
return prefix + (prefix[prefix.length - 1] === "/" ? "" : "/");
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | 2 1 1 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ListWidget.Delegate}
*/
WebInspector.FrameworkBlackboxSettingsTab = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("settings/frameworkBlackboxSettingsTab.css");
this.contentElement.createChild("div", "header").textContent = WebInspector.UIString("Framework Blackbox Patterns");
this.contentElement.createChild("div", "blackbox-content-scripts").appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Blackbox content scripts"), WebInspector.moduleSetting("skipContentScripts"), true));
this._blackboxLabel = WebInspector.UIString("Blackbox");
this._disabledLabel = WebInspector.UIString("Disabled");
this._list = new WebInspector.ListWidget(this);
this._list.element.classList.add("blackbox-list");
this._list.registerRequiredCSS("settings/frameworkBlackboxSettingsTab.css");
var placeholder = createElementWithClass("div", "blackbox-list-empty");
placeholder.textContent = WebInspector.UIString("No blackboxed patterns");
this._list.setEmptyPlaceholder(placeholder);
this._list.show(this.contentElement);
this.contentElement.appendChild(createTextButton(WebInspector.UIString("Add pattern..."), this._addButtonClicked.bind(this), "add-button"));
this._setting = WebInspector.moduleSetting("skipStackFramesPattern");
this._setting.addChangeListener(this._settingUpdated, this);
this.contentElement.tabIndex = 0;
}
WebInspector.FrameworkBlackboxSettingsTab.prototype = {
wasShown: function()
{
WebInspector.SettingsTab.prototype.wasShown.call(this);
this._settingUpdated();
},
_settingUpdated: function()
{
this._list.clear();
var patterns = this._setting.getAsArray();
for (var i = 0; i < patterns.length; ++i)
this._list.appendItem(patterns[i], true);
},
_addButtonClicked: function()
{
this._list.addNewItem(this._setting.getAsArray().length, {pattern: "", disabled: false});
},
/**
* @override
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable)
{
var element = createElementWithClass("div", "blackbox-list-item");
var pattern = element.createChild("div", "blackbox-pattern");
pattern.textContent = item.pattern;
pattern.title = item.pattern;
element.createChild("div", "blackbox-separator");
element.createChild("div", "blackbox-behavior").textContent = item.disabled ? this._disabledLabel : this._blackboxLabel;
if (item.disabled)
element.classList.add("blackbox-disabled");
return element;
},
/**
* @override
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index)
{
var patterns = this._setting.getAsArray();
patterns.splice(index, 1);
this._setting.setAsArray(patterns);
},
/**
* @override
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew)
{
item.pattern = editor.control("pattern").value.trim();
item.disabled = editor.control("behavior").value === this._disabledLabel;
var list = this._setting.getAsArray();
if (isNew)
list.push(item);
this._setting.setAsArray(list);
},
/**
* @override
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item)
{
var editor = this._createEditor();
editor.control("pattern").value = item.pattern;
editor.control("behavior").value = item.disabled ? this._disabledLabel : this._blackboxLabel;
return editor;
},
/**
* @return {!WebInspector.ListWidget.Editor}
*/
_createEditor: function()
{
if (this._editor)
return this._editor;
var editor = new WebInspector.ListWidget.Editor();
this._editor = editor;
var content = editor.contentElement();
var titles = content.createChild("div", "blackbox-edit-row");
titles.createChild("div", "blackbox-pattern").textContent = WebInspector.UIString("Pattern");
titles.createChild("div", "blackbox-separator blackbox-separator-invisible");
titles.createChild("div", "blackbox-behavior").textContent = WebInspector.UIString("Behavior");
var fields = content.createChild("div", "blackbox-edit-row");
fields.createChild("div", "blackbox-pattern").appendChild(editor.createInput("pattern", "text", "/framework\\.js$", patternValidator.bind(this)));
fields.createChild("div", "blackbox-separator blackbox-separator-invisible");
fields.createChild("div", "blackbox-behavior").appendChild(editor.createSelect("behavior", [this._blackboxLabel, this._disabledLabel], behaviorValidator));
return editor;
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @this {WebInspector.FrameworkBlackboxSettingsTab}
* @return {boolean}
*/
function patternValidator(item, index, input)
{
var pattern = input.value.trim();
var patterns = this._setting.getAsArray();
for (var i = 0; i < patterns.length; ++i) {
if (i !== index && patterns[i].pattern === pattern)
return false;
}
var regex;
try {
regex = new RegExp(pattern);
} catch (e) {
}
return !!(pattern && regex);
}
/**
* @param {*} item
* @param {number} index
* @param {!HTMLInputElement|!HTMLSelectElement} input
* @return {boolean}
*/
function behaviorValidator(item, index, input)
{
return true;
}
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | 2 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.SettingsScreen = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("settings/settingsScreen.css");
this.contentElement.tabIndex = 0;
this.contentElement.classList.add("help-window-main");
this.contentElement.classList.add("vbox");
var settingsLabelElement = createElementWithClass("div", "help-window-label");
settingsLabelElement.createTextChild(WebInspector.UIString("Settings"));
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.insertBeforeTabStrip(settingsLabelElement);
this._tabbedPane.setShrinkableTabs(false);
this._tabbedPane.setVerticalTabLayout(true);
this._tabbedPane.appendTab("preferences", WebInspector.UIString("Preferences"), new WebInspector.GenericSettingsTab());
this._tabbedPane.appendTab("workspace", WebInspector.UIString("Workspace"), new WebInspector.WorkspaceSettingsTab());
this._tabbedPane.appendTab("blackbox", WebInspector.manageBlackboxingSettingsTabLabel(), new WebInspector.FrameworkBlackboxSettingsTab());
if (Runtime.experiments.supportEnabled())
this._tabbedPane.appendTab("experiments", WebInspector.UIString("Experiments"), new WebInspector.ExperimentsSettingsTab());
this._tabbedPaneController = new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "settings-view");
this._tabbedPane.appendTab("shortcuts", WebInspector.UIString("Shortcuts"), WebInspector.shortcutsScreen.createShortcutsTabView());
this.element.addEventListener("keydown", this._keyDown.bind(this), false);
this._developerModeCounter = 0;
this.setDefaultFocusedElement(this.contentElement);
}
WebInspector.SettingsScreen.prototype = {
/**
* @override
*/
wasShown: function()
{
this._tabbedPane.selectTab("preferences");
this._tabbedPane.show(this.contentElement);
WebInspector.VBox.prototype.wasShown.call(this);
},
/**
* @param {string} name
*/
selectTab: function(name)
{
this._tabbedPane.selectTab(name);
},
/**
* @param {!Event} event
*/
_keyDown: function(event)
{
var shiftKeyCode = 16;
if (event.keyCode === shiftKeyCode && ++this._developerModeCounter > 5)
this.contentElement.classList.add("settings-developer-mode");
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {string} name
* @param {string=} id
*/
WebInspector.SettingsTab = function(name, id)
{
WebInspector.VBox.call(this);
this.element.classList.add("settings-tab-container");
if (id)
this.element.id = id;
var header = this.element.createChild("header");
header.createChild("h3").createTextChild(name);
this.containerElement = this.element.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
}
WebInspector.SettingsTab.prototype = {
/**
* @param {string=} name
* @return {!Element}
*/
_appendSection: function(name)
{
var block = this.containerElement.createChild("div", "help-block");
if (name)
block.createChild("div", "help-section-title").textContent = name;
return block;
},
_createSelectSetting: function(name, options, setting)
{
var p = createElement("p");
p.createChild("label").textContent = name;
var select = p.createChild("select", "chrome-select");
var settingValue = setting.get();
for (var i = 0; i < options.length; ++i) {
var option = options[i];
select.add(new Option(option[0], option[1]));
if (settingValue === option[1])
select.selectedIndex = i;
}
function changeListener(e)
{
// Don't use e.target.value to avoid conversion of the value to string.
setting.set(options[select.selectedIndex][1]);
}
select.addEventListener("change", changeListener, false);
return p;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.SettingsTab}
*/
WebInspector.GenericSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Preferences"), "preferences-tab-content");
/** @const */
var explicitSectionOrder = ["", "Appearance", "Elements", "Sources", "Network", "Profiler", "Console", "Extensions"];
/** @type {!Map<string, !Element>} */
this._nameToSection = new Map();
/** @type {!Map<string, !Element>} */
this._nameToSettingElement = new Map();
for (var sectionName of explicitSectionOrder)
this._sectionElement(sectionName);
self.runtime.extensions("setting").forEach(this._addSetting.bind(this));
self.runtime.extensions(WebInspector.SettingUI).forEach(this._addSettingUI.bind(this));
this._appendSection().appendChild(createTextButton(WebInspector.UIString("Restore defaults and reload"), restoreAndReload));
function restoreAndReload()
{
WebInspector.settings.clearAll();
WebInspector.reload();
}
}
/**
* @param {!Runtime.Extension} extension
* @return {boolean}
*/
WebInspector.GenericSettingsTab.isSettingVisible = function(extension)
{
var descriptor = extension.descriptor();
if (!("title" in descriptor))
return false;
if (!("category" in descriptor))
return false;
return true;
}
WebInspector.GenericSettingsTab.prototype = {
/**
* @param {!Runtime.Extension} extension
*/
_addSetting: function(extension)
{
if (!WebInspector.GenericSettingsTab.isSettingVisible(extension))
return;
var descriptor = extension.descriptor();
var sectionName = descriptor["category"];
var settingName = descriptor["settingName"];
var setting = WebInspector.moduleSetting(settingName);
var uiTitle = WebInspector.UIString(extension.title(WebInspector.platform()));
var sectionElement = this._sectionElement(sectionName);
var settingControl;
switch (descriptor["settingType"]) {
case "boolean":
settingControl = WebInspector.SettingsUI.createSettingCheckbox(uiTitle, setting);
break;
case "enum":
var descriptorOptions = descriptor["options"];
var options = new Array(descriptorOptions.length);
for (var i = 0; i < options.length; ++i) {
// The "raw" flag indicates text is non-i18n-izable.
var optionName = descriptorOptions[i]["raw"] ? descriptorOptions[i]["text"] : WebInspector.UIString(descriptorOptions[i]["text"]);
options[i] = [optionName, descriptorOptions[i]["value"]];
}
settingControl = this._createSelectSetting(uiTitle, options, setting);
break;
default:
console.error("Invalid setting type: " + descriptor["settingType"]);
return;
}
this._nameToSettingElement.set(settingName, settingControl);
sectionElement.appendChild(/** @type {!Element} */ (settingControl));
},
/**
* @param {!Runtime.Extension} extension
*/
_addSettingUI: function(extension)
{
var descriptor = extension.descriptor();
var sectionName = descriptor["category"] || "";
extension.instancePromise().then(appendCustomSetting.bind(this));
/**
* @param {!Object} object
* @this {WebInspector.GenericSettingsTab}
*/
function appendCustomSetting(object)
{
var settingUI = /** @type {!WebInspector.SettingUI} */ (object);
var element = settingUI.settingElement();
if (element)
this._sectionElement(sectionName).appendChild(element);
}
},
/**
* @param {string} sectionName
* @return {!Element}
*/
_sectionElement: function(sectionName)
{
var sectionElement = this._nameToSection.get(sectionName);
if (!sectionElement) {
var uiSectionName = sectionName && WebInspector.UIString(sectionName);
sectionElement = this._appendSection(uiSectionName);
this._nameToSection.set(sectionName, sectionElement);
}
return sectionElement;
},
__proto__: WebInspector.SettingsTab.prototype
}
/**
* @constructor
* @extends {WebInspector.SettingsTab}
*/
WebInspector.WorkspaceSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Workspace"), "workspace-tab-content");
WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
var folderExcludePatternInput = this._createFolderExcludePatternInput();
folderExcludePatternInput.classList.add("folder-exclude-pattern");
this.containerElement.appendChild(folderExcludePatternInput);
this._fileSystemsListContainer = this.containerElement.createChild("div", "");
this.containerElement.appendChild(createTextButton(WebInspector.UIString("Add folder\u2026"), this._addFileSystemClicked.bind(this)));
/** @type {!Map<string, !Element>} */
this._elementByPath = new Map();
/** @type {!Map<string, !WebInspector.EditFileSystemView>} */
this._mappingViewByPath = new Map();
var fileSystemPaths = WebInspector.isolatedFileSystemManager.fileSystemPaths();
for (var i = 0; i < fileSystemPaths.length; ++i)
this._addItem(/** @type {!WebInspector.IsolatedFileSystem} */ (WebInspector.isolatedFileSystemManager.fileSystem(fileSystemPaths[i])));
}
WebInspector.WorkspaceSettingsTab.prototype = {
/**
* @return {!Element}
*/
_createFolderExcludePatternInput: function()
{
var p = createElement("p");
var labelElement = p.createChild("label");
labelElement.textContent = WebInspector.UIString("Folder exclude pattern");
var inputElement = p.createChild("input");
inputElement.type = "text";
inputElement.style.width = "270px";
var folderExcludeSetting = WebInspector.isolatedFileSystemManager.workspaceFolderExcludePatternSetting();
var setValue = WebInspector.bindInput(inputElement, folderExcludeSetting.set.bind(folderExcludeSetting), regexValidator, false);
folderExcludeSetting.addChangeListener(() => setValue.call(null, folderExcludeSetting.get()));
setValue(folderExcludeSetting.get());
return p;
/**
* @param {string} value
* @return {boolean}
*/
function regexValidator(value)
{
var regex;
try {
regex = new RegExp(value);
} catch (e) {
}
return !!regex;
}
},
/**
* @param {!WebInspector.IsolatedFileSystem} fileSystem
*/
_addItem: function(fileSystem)
{
var element = this._renderFileSystem(fileSystem);
this._elementByPath.set(fileSystem.path(), element);
this._fileSystemsListContainer.appendChild(element);
var mappingView = new WebInspector.EditFileSystemView(fileSystem.path());
this._mappingViewByPath.set(fileSystem.path(), mappingView);
mappingView.element.classList.add("file-system-mapping-view");
mappingView.show(element);
},
/**
* @param {!WebInspector.IsolatedFileSystem} fileSystem
* @return {!Element}
*/
_renderFileSystem: function(fileSystem)
{
var fileSystemPath = fileSystem.path();
var lastIndexOfSlash = fileSystemPath.lastIndexOf(WebInspector.isWin() ? "\\" : "/");
var folderName = fileSystemPath.substr(lastIndexOfSlash + 1);
var element = createElementWithClass("div", "file-system-container");
var header = element.createChild("div", "file-system-header");
header.createChild("div", "file-system-name").textContent = folderName;
var path = header.createChild("div", "file-system-path");
path.textContent = fileSystemPath;
path.title = fileSystemPath;
var toolbar = new WebInspector.Toolbar("");
var button = new WebInspector.ToolbarButton(WebInspector.UIString("Remove"), "delete-toolbar-item");
button.addEventListener("click", this._removeFileSystemClicked.bind(this, fileSystem));
toolbar.appendToolbarItem(button);
header.appendChild(toolbar.element);
return element;
},
/**
* @param {!WebInspector.IsolatedFileSystem} fileSystem
*/
_removeFileSystemClicked: function(fileSystem)
{
WebInspector.isolatedFileSystemManager.removeFileSystem(fileSystem);
},
_addFileSystemClicked: function()
{
WebInspector.isolatedFileSystemManager.addFileSystem();
},
_fileSystemAdded: function(event)
{
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
this._addItem(fileSystem);
},
_fileSystemRemoved: function(event)
{
var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
var mappingView = this._mappingViewByPath.get(fileSystem.path());
if (mappingView) {
mappingView.dispose();
this._mappingViewByPath.delete(fileSystem.path());
}
var element = this._elementByPath.get(fileSystem.path());
if (element) {
this._elementByPath.delete(fileSystem.path());
element.remove();
}
},
__proto__: WebInspector.SettingsTab.prototype
}
/**
* @constructor
* @extends {WebInspector.SettingsTab}
*/
WebInspector.ExperimentsSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Experiments"), "experiments-tab-content");
var experiments = Runtime.experiments.allConfigurableExperiments();
if (experiments.length) {
var experimentsSection = this._appendSection();
experimentsSection.appendChild(this._createExperimentsWarningSubsection());
for (var i = 0; i < experiments.length; ++i)
experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));
}
}
WebInspector.ExperimentsSettingsTab.prototype = {
/**
* @return {!Element} element
*/
_createExperimentsWarningSubsection: function()
{
var subsection = createElement("div");
var warning = subsection.createChild("span", "settings-experiments-warning-subsection-warning");
warning.textContent = WebInspector.UIString("WARNING:");
subsection.createTextChild(" ");
var message = subsection.createChild("span", "settings-experiments-warning-subsection-message");
message.textContent = WebInspector.UIString("These experiments could be dangerous and may require restart.");
return subsection;
},
_createExperimentCheckbox: function(experiment)
{
var label = createCheckboxLabel(WebInspector.UIString(experiment.title), experiment.isEnabled());
var input = label.checkboxElement;
input.name = experiment.name;
function listener()
{
experiment.setEnabled(input.checked);
}
input.addEventListener("click", listener, false);
var p = createElement("p");
p.className = experiment.hidden && !experiment.isEnabled() ? "settings-experiment-hidden" : "";
p.appendChild(label);
return p;
},
__proto__: WebInspector.SettingsTab.prototype
}
/**
* @constructor
*/
WebInspector.SettingsController = function()
{
/** @type {?WebInspector.SettingsScreen} */
this._settingsScreen;
}
WebInspector.SettingsController.prototype = {
/**
* @param {string=} name
*/
showSettingsScreen: function(name)
{
if (!this._settingsScreen)
this._settingsScreen = new WebInspector.SettingsScreen();
var dialog = new WebInspector.Dialog();
dialog.addCloseButton();
this._settingsScreen.show(dialog.element);
dialog.show();
if (name)
this._settingsScreen.selectTab(name);
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.SettingsController.ActionDelegate = function() { }
WebInspector.SettingsController.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
switch (actionId) {
case "settings.show":
WebInspector._settingsController.showSettingsScreen();
return true;
case "settings.help":
InspectorFrontendHost.openInNewTab("https://developers.google.com/web/tools/chrome-devtools/");
return true;
case "settings.shortcuts":
WebInspector._settingsController.showSettingsScreen("shortcuts");
return true;
}
return false;
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.SettingsController.Revealer = function() { }
WebInspector.SettingsController.Revealer.prototype = {
/**
* @override
* @param {!Object} object
* @param {number=} lineNumber
* @return {!Promise}
*/
reveal: function(object, lineNumber)
{
console.assert(object instanceof WebInspector.Setting);
var setting = /** @type {!WebInspector.Setting} */ (object);
var success = false;
self.runtime.extensions("setting").forEach(revealModuleSetting);
self.runtime.extensions(WebInspector.SettingUI).forEach(revealSettingUI);
self.runtime.extensions("settings-view").forEach(revealSettingsView);
return success ? Promise.resolve() : Promise.reject();
/**
* @param {!Runtime.Extension} extension
*/
function revealModuleSetting(extension)
{
if (!WebInspector.GenericSettingsTab.isSettingVisible(extension))
return;
if (extension.descriptor()["settingName"] === setting.name) {
WebInspector._settingsController.showSettingsScreen("preferences");
success = true;
}
}
/**
* @param {!Runtime.Extension} extension
*/
function revealSettingUI(extension)
{
var settings = extension.descriptor()["settings"];
if (settings && settings.indexOf(setting.name) !== -1) {
WebInspector._settingsController.showSettingsScreen("preferences");
success = true;
}
}
/**
* @param {!Runtime.Extension} extension
*/
function revealSettingsView(extension)
{
var settings = extension.descriptor()["settings"];
if (settings && settings.indexOf(setting.name) !== -1) {
WebInspector._settingsController.showSettingsScreen(extension.descriptor()["name"]);
success = true;
}
}
}
}
WebInspector._settingsController = new WebInspector.SettingsController();
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ScriptSnippetModel.js | 2.17% | (4 / 184) | 0% | (0 / 34) | 0% | (0 / 52) | 2.2% | (4 / 182) | |
| SnippetStorage.js | 1.69% | (1 / 59) | 0% | (0 / 10) | 0% | (0 / 18) | 1.69% | (1 / 59) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 | 2 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.ScriptSnippetModel = function(workspace)
{
this._workspace = workspace;
/** @type {!Object.<string, !WebInspector.UISourceCode>} */
this._uiSourceCodeForSnippetId = {};
/** @type {!Map.<!WebInspector.UISourceCode, string>} */
this._snippetIdForUISourceCode = new Map();
/** @type {!Map.<!WebInspector.Target, !WebInspector.SnippetScriptMapping>} */
this._mappingForTarget = new Map();
this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
this._project = new WebInspector.SnippetsProject(workspace, this);
this._loadSnippets();
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ScriptSnippetModel.snippetSourceURLPrefix = "snippets:///";
WebInspector.ScriptSnippetModel.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel)
this._mappingForTarget.set(target, new WebInspector.SnippetScriptMapping(debuggerModel, this));
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
if (WebInspector.DebuggerModel.fromTarget(target))
this._mappingForTarget.remove(target);
},
/**
* @param {!WebInspector.Target} target
* @return {!WebInspector.SnippetScriptMapping|undefined}
*/
snippetScriptMapping: function(target)
{
return this._mappingForTarget.get(target);
},
/**
* @return {!WebInspector.Project}
*/
project: function()
{
return this._project;
},
_loadSnippets: function()
{
var snippets = this._snippetStorage.snippets();
for (var i = 0; i < snippets.length; ++i)
this._addScriptSnippet(snippets[i]);
},
/**
* @param {string} content
* @return {!WebInspector.UISourceCode}
*/
createScriptSnippet: function(content)
{
var snippet = this._snippetStorage.createSnippet();
snippet.content = content;
return this._addScriptSnippet(snippet);
},
/**
* @param {!WebInspector.Snippet} snippet
* @return {!WebInspector.UISourceCode}
*/
_addScriptSnippet: function(snippet)
{
var uiSourceCode = this._project.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet));
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id);
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
return uiSourceCode;
},
/**
* @param {!WebInspector.Event} event
*/
_workingCopyChanged: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
this._scriptSnippetEdited(uiSourceCode);
},
/**
* @param {string} url
*/
deleteScriptSnippet: function(url)
{
var uiSourceCode = this._project.uiSourceCodeForURL(url);
if (!uiSourceCode)
return;
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
var snippet = this._snippetStorage.snippetForId(snippetId);
this._snippetStorage.deleteSnippet(snippet);
this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
delete this._uiSourceCodeForSnippetId[snippet.id];
this._snippetIdForUISourceCode.remove(uiSourceCode);
this._project.removeFile(snippet.name);
},
/**
* @param {string} name
* @param {string} newName
* @param {function(boolean, string=)} callback
*/
renameScriptSnippet: function(name, newName, callback)
{
newName = newName.trim();
if (!newName || newName.indexOf("/") !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
callback(false);
return;
}
var snippet = this._snippetStorage.snippetForName(name);
console.assert(snippet, "Snippet '" + name + "' was not found.");
var uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
console.assert(uiSourceCode, "No uiSourceCode was found for snippet '" + name + "'.");
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
snippet.name = newName;
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
callback(true, newName);
},
/**
* @param {string} name
* @param {string} newContent
*/
_setScriptSnippetContent: function(name, newContent)
{
var snippet = this._snippetStorage.snippetForName(name);
snippet.content = newContent;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_scriptSnippetEdited: function(uiSourceCode)
{
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
this._mappingForTarget.valuesArray().forEach(function(mapping) {mapping._restoreBreakpoints(uiSourceCode, breakpointLocations);});
},
/**
* @return {number}
*/
_nextEvaluationIndex: function()
{
var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
return evaluationIndex;
},
/**
* @param {!WebInspector.ExecutionContext} executionContext
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
evaluateScriptSnippet: function(executionContext, uiSourceCode)
{
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
var target = executionContext.target();
var runtimeModel = target.runtimeModel;
var evaluationIndex = this._nextEvaluationIndex();
var mapping = this._mappingForTarget.get(target);
mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
var evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
var expression = uiSourceCode.workingCopy();
WebInspector.console.show();
runtimeModel.compileScript(expression, "", true, executionContext.id, compileCallback.bind(this));
/**
* @param {!RuntimeAgent.ScriptId=} scriptId
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.ScriptSnippetModel}
*/
function compileCallback(scriptId, exceptionDetails)
{
var mapping = this._mappingForTarget.get(target);
if (mapping.evaluationIndex(uiSourceCode) !== evaluationIndex)
return;
if (!scriptId) {
this._printRunOrCompileScriptResultFailure(target, exceptionDetails, evaluationUrl);
return;
}
mapping._addScript(executionContext.debuggerModel.scriptForId(scriptId), uiSourceCode);
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
this._runScript(scriptId, executionContext, evaluationUrl);
}
},
/**
* @param {!RuntimeAgent.ScriptId} scriptId
* @param {!WebInspector.ExecutionContext} executionContext
* @param {?string=} sourceURL
*/
_runScript: function(scriptId, executionContext, sourceURL)
{
var target = executionContext.target();
target.runtimeModel.runScript(scriptId, executionContext.id, "console", false, true, runCallback.bind(this, target));
/**
* @param {!WebInspector.Target} target
* @param {?RuntimeAgent.RemoteObject} result
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.ScriptSnippetModel}
*/
function runCallback(target, result, exceptionDetails)
{
if (!exceptionDetails)
this._printRunScriptResult(target, result, sourceURL);
else
this._printRunOrCompileScriptResultFailure(target, exceptionDetails, sourceURL);
}
},
/**
* @param {!WebInspector.Target} target
* @param {?RuntimeAgent.RemoteObject} result
* @param {?string=} sourceURL
*/
_printRunScriptResult: function(target, result, sourceURL)
{
var consoleMessage = new WebInspector.ConsoleMessage(
target,
WebInspector.ConsoleMessage.MessageSource.JS,
WebInspector.ConsoleMessage.MessageLevel.Log,
"",
undefined,
sourceURL,
undefined,
undefined,
undefined,
[result],
undefined);
target.consoleModel.addMessage(consoleMessage);
},
/**
* @param {!WebInspector.Target} target
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @param {?string=} sourceURL
*/
_printRunOrCompileScriptResultFailure: function(target, exceptionDetails, sourceURL)
{
var consoleMessage = new WebInspector.ConsoleMessage(
target,
exceptionDetails.source,
WebInspector.ConsoleMessage.MessageLevel.Error,
exceptionDetails.text,
undefined,
sourceURL,
exceptionDetails.line,
exceptionDetails.column,
undefined,
undefined,
exceptionDetails.stack);
target.consoleModel.addMessage(consoleMessage);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
_removeBreakpoints: function(uiSourceCode)
{
var breakpointLocations = WebInspector.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
for (var i = 0; i < breakpointLocations.length; ++i)
breakpointLocations[i].breakpoint.remove();
return breakpointLocations;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
*/
_restoreBreakpoints: function(uiSourceCode, breakpointLocations)
{
for (var i = 0; i < breakpointLocations.length; ++i) {
var uiLocation = breakpointLocations[i].uiLocation;
var breakpoint = breakpointLocations[i].breakpoint;
WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_releaseSnippetScript: function(uiSourceCode)
{
this._mappingForTarget.valuesArray().forEach(function(mapping) {mapping._releaseSnippetScript(uiSourceCode);});
},
/**
* @param {string} sourceURL
* @return {?string}
*/
_snippetIdForSourceURL: function(sourceURL)
{
var snippetPrefix = WebInspector.ScriptSnippetModel.snippetSourceURLPrefix;
if (!sourceURL.startsWith(snippetPrefix))
return null;
var splitURL = sourceURL.substring(snippetPrefix.length).split("_");
var snippetId = splitURL[0];
return snippetId;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.DebuggerSourceMapping}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.ScriptSnippetModel} scriptSnippetModel
*/
WebInspector.SnippetScriptMapping = function(debuggerModel, scriptSnippetModel)
{
this._target = debuggerModel.target();
this._debuggerModel = debuggerModel;
this._scriptSnippetModel = scriptSnippetModel;
/** @type {!Object.<string, !WebInspector.UISourceCode>} */
this._uiSourceCodeForScriptId = {};
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Script>} */
this._scriptForUISourceCode = new Map();
/** @type {!Map.<!WebInspector.UISourceCode, number>} */
this._evaluationIndexForUISourceCode = new Map();
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
}
WebInspector.SnippetScriptMapping.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_releaseSnippetScript: function(uiSourceCode)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return;
delete this._uiSourceCodeForScriptId[script.scriptId];
this._scriptForUISourceCode.remove(uiSourceCode);
this._evaluationIndexForUISourceCode.remove(uiSourceCode);
},
/**
+* @param {number} evaluationIndex
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_setEvaluationIndex: function(evaluationIndex, uiSourceCode)
{
this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {number|undefined}
*/
evaluationIndex: function(uiSourceCode)
{
return this._evaluationIndexForUISourceCode.get(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
_evaluationSourceURL: function(uiSourceCode)
{
var evaluationSuffix = "_" + this._evaluationIndexForUISourceCode.get(uiSourceCode);
var snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
return WebInspector.ScriptSnippetModel.snippetSourceURLPrefix + snippetId + evaluationSuffix;
},
_reset: function()
{
this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode.clear();
this._evaluationIndexForUISourceCode.clear();
},
/**
* @override
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */(rawLocation);
var uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
if (!uiSourceCode)
return null;
return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return null;
return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
/**
* @param {!WebInspector.Script} script
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_addScript: function(script, uiSourceCode)
{
console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
WebInspector.debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, this);
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptForUISourceCode.set(uiSourceCode, script);
WebInspector.debuggerWorkspaceBinding.pushSourceMapping(script, this);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
*/
_restoreBreakpoints: function(uiSourceCode, breakpointLocations)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return;
var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (this._debuggerModel.createRawLocation(script, 0, 0));
var scriptUISourceCode = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation).uiSourceCode;
if (scriptUISourceCode)
this._scriptSnippetModel._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
}
}
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.Snippet} snippet
*/
WebInspector.SnippetContentProvider = function(snippet)
{
this._snippet = snippet;
}
WebInspector.SnippetContentProvider.prototype = {
/**
* @override
* @return {string}
*/
contentURL: function()
{
return "";
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return WebInspector.resourceTypes.Script;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
return Promise.resolve(/** @type {?string} */(this._snippet.content));
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
/**
* @this {WebInspector.SnippetContentProvider}
*/
function performSearch()
{
callback(WebInspector.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex));
}
// searchInContent should call back later.
window.setTimeout(performSearch.bind(this), 0);
}
}
/**
* @constructor
* @extends {WebInspector.ContentProviderBasedProject}
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.ScriptSnippetModel} model
*/
WebInspector.SnippetsProject = function(workspace, model)
{
WebInspector.ContentProviderBasedProject.call(this, workspace, "snippets:", WebInspector.projectTypes.Snippets, "");
this._model = model;
}
WebInspector.SnippetsProject.prototype = {
/**
* @param {string} name
* @param {!WebInspector.ContentProvider} contentProvider
* @return {!WebInspector.UISourceCode}
*/
addSnippet: function(name, contentProvider)
{
return this.addContentProvider(name, contentProvider);
},
/**
* @override
* @return {boolean}
*/
canSetFileContent: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} newContent
* @param {function(?string)} callback
*/
setFileContent: function(uiSourceCode, newContent, callback)
{
this._model._setScriptSnippetContent(uiSourceCode.url(), newContent);
callback("");
},
/**
* @override
* @return {boolean}
*/
canRename: function()
{
return true;
},
/**
* @override
* @param {string} url
* @param {string} newName
* @param {function(boolean, string=)} callback
*/
performRename: function(url, newName, callback)
{
this._model.renameScriptSnippet(url, newName, callback);
},
/**
* @override
* @param {string} url
* @param {?string} name
* @param {string} content
* @param {function(?WebInspector.UISourceCode)} callback
*/
createFile: function(url, name, content, callback)
{
callback(this._model.createScriptSnippet(content));
},
/**
* @override
* @param {string} url
*/
deleteFile: function(url)
{
this._model.deleteScriptSnippet(url);
},
__proto__: WebInspector.ContentProviderBasedProject.prototype
}
/**
* @type {!WebInspector.ScriptSnippetModel}
*/
WebInspector.scriptSnippetModel = new WebInspector.ScriptSnippetModel(WebInspector.workspace);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.SnippetStorage = function(settingPrefix, namePrefix)
{
this._snippets = {};
this._lastSnippetIdentifierSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets_lastIdentifier", 0);
this._snippetsSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets", []);
this._namePrefix = namePrefix;
this._loadSettings();
}
WebInspector.SnippetStorage.prototype = {
get namePrefix()
{
return this._namePrefix;
},
_saveSettings: function()
{
var savedSnippets = [];
for (var id in this._snippets)
savedSnippets.push(this._snippets[id].serializeToObject());
this._snippetsSetting.set(savedSnippets);
},
/**
* @return {!Array.<!WebInspector.Snippet>}
*/
snippets: function()
{
var result = [];
for (var id in this._snippets)
result.push(this._snippets[id]);
return result;
},
/**
* @param {string} id
* @return {!WebInspector.Snippet}
*/
snippetForId: function(id)
{
return this._snippets[id];
},
/**
* @param {string} name
* @return {?WebInspector.Snippet}
*/
snippetForName: function(name)
{
var snippets = Object.values(this._snippets);
for (var i = 0; i < snippets.length; ++i)
if (snippets[i].name === name)
return snippets[i];
return null;
},
_loadSettings: function()
{
var savedSnippets = this._snippetsSetting.get();
for (var i = 0; i < savedSnippets.length; ++i)
this._snippetAdded(WebInspector.Snippet.fromObject(this, savedSnippets[i]));
},
/**
* @param {!WebInspector.Snippet} snippet
*/
deleteSnippet: function(snippet)
{
delete this._snippets[snippet.id];
this._saveSettings();
},
/**
* @return {!WebInspector.Snippet}
*/
createSnippet: function()
{
var nextId = this._lastSnippetIdentifierSetting.get() + 1;
var snippetId = String(nextId);
this._lastSnippetIdentifierSetting.set(nextId);
var snippet = new WebInspector.Snippet(this, snippetId);
this._snippetAdded(snippet);
this._saveSettings();
return snippet;
},
/**
* @param {!WebInspector.Snippet} snippet
*/
_snippetAdded: function(snippet)
{
this._snippets[snippet.id] = snippet;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.SnippetStorage} storage
* @param {string} id
* @param {string=} name
* @param {string=} content
*/
WebInspector.Snippet = function(storage, id, name, content)
{
this._storage = storage;
this._id = id;
this._name = name || storage.namePrefix + id;
this._content = content || "";
}
/**
* @param {!WebInspector.SnippetStorage} storage
* @param {!Object} serializedSnippet
* @return {!WebInspector.Snippet}
*/
WebInspector.Snippet.fromObject = function(storage, serializedSnippet)
{
return new WebInspector.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
}
WebInspector.Snippet.prototype = {
/**
* @return {string}
*/
get id()
{
return this._id;
},
/**
* @return {string}
*/
get name()
{
return this._name;
},
set name(name)
{
if (this._name === name)
return;
this._name = name;
this._storage._saveSettings();
},
/**
* @return {string}
*/
get content()
{
return this._content;
},
set content(content)
{
if (this._content === content)
return;
this._content = content;
this._storage._saveSettings();
},
/**
* @return {!Object}
*/
serializeToObject: function()
{
var serializedSnippet = {};
serializedSnippet.id = this.id;
serializedSnippet.name = this.name;
serializedSnippet.content = this.content;
return serializedSnippet;
},
__proto__: WebInspector.Object.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CodeMirrorDictionary.js | 7.14% | (3 / 42) | 0% | (0 / 15) | 0% | (0 / 13) | 7.14% | (3 / 42) | |
| CodeMirrorTextEditor.js | 2.16% | (21 / 971) | 0% | (0 / 474) | 0% | (0 / 163) | 2.16% | (21 / 970) | |
| CodeMirrorUtils.js | 5.06% | (4 / 79) | 0% | (0 / 14) | 0% | (0 / 19) | 5.06% | (4 / 79) | |
| FontView.js | 1.56% | (1 / 64) | 0% | (0 / 18) | 0% | (0 / 8) | 1.56% | (1 / 64) | |
| ImageView.js | 4.76% | (2 / 42) | 0% | (0 / 18) | 0% | (0 / 10) | 4.76% | (2 / 42) | |
| ResourceSourceFrame.js | 14.29% | (1 / 7) | 100% | (0 / 0) | 0% | (0 / 3) | 14.29% | (1 / 7) | |
| SourceFrame.js | 0.43% | (1 / 233) | 0% | (0 / 106) | 0% | (0 / 65) | 0.43% | (1 / 231) | |
| TextEditorAutocompleteController.js | 2.04% | (3 / 147) | 0% | (0 / 86) | 0% | (0 / 28) | 2.05% | (3 / 146) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!CodeMirror} codeMirror
* @param {string=} additionalWordChars
*/
WebInspector.CodeMirrorDictionary = function(codeMirror, additionalWordChars)
{
this._codeMirror = codeMirror;
this._additionalWordChars = new Set(/** @type {!Iterable} */ (additionalWordChars));
this._dictionary = new WebInspector.TextDictionary();
this._addText(this._codeMirror.getValue());
this._changes = this._changes.bind(this);
this._beforeChange = this._beforeChange.bind(this);
this._codeMirror.on("beforeChange", this._beforeChange);
this._codeMirror.on("changes", this._changes);
}
WebInspector.CodeMirrorDictionary.prototype = {
/**
* @param {!CodeMirror} codeMirror
* @param {!CodeMirror.BeforeChangeObject} changeObject
*/
_beforeChange: function(codeMirror, changeObject)
{
this._updatedLines = this._updatedLines || {};
for (var i = changeObject.from.line; i <= changeObject.to.line; ++i)
this._updatedLines[i] = this._codeMirror.getLine(i);
},
/**
* @param {!CodeMirror} codeMirror
* @param {!Array.<!CodeMirror.ChangeObject>} changes
*/
_changes: function(codeMirror, changes)
{
if (!changes.length || !this._updatedLines)
return;
for (var lineNumber in this._updatedLines)
this._removeText(this._updatedLines[lineNumber]);
delete this._updatedLines;
var linesToUpdate = {};
for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
var changeObject = changes[changeIndex];
var editInfo = WebInspector.CodeMirrorUtils.changeObjectToEditOperation(changeObject);
for (var i = editInfo.newRange.startLine; i <= editInfo.newRange.endLine; ++i)
linesToUpdate[i] = this._codeMirror.getLine(i);
}
for (var lineNumber in linesToUpdate)
this._addText(linesToUpdate[lineNumber]);
},
/**
* @param {string} word
* @return {boolean}
*/
_validWord: function(word)
{
return !!word.length && (word[0] < '0' || word[0] > '9');
},
/**
* @param {string} text
*/
_addText: function(text)
{
WebInspector.TextUtils.textToWords(text, this.isWordChar.bind(this), addWord.bind(this));
/**
* @param {string} word
* @this {WebInspector.CodeMirrorDictionary}
*/
function addWord(word)
{
if (this._validWord(word))
this._dictionary.addWord(word);
}
},
/**
* @param {string} text
*/
_removeText: function(text)
{
WebInspector.TextUtils.textToWords(text, this.isWordChar.bind(this), removeWord.bind(this));
/**
* @param {string} word
* @this {WebInspector.CodeMirrorDictionary}
*/
function removeWord(word)
{
if (this._validWord(word))
this._dictionary.removeWord(word);
}
},
/**
* @param {string} char
* @return {boolean}
*/
isWordChar: function(char)
{
return WebInspector.TextUtils.isWordChar(char) || this._additionalWordChars.has(char);
},
/**
* @param {string} prefix
* @return {!Array.<string>}
*/
wordsWithPrefix: function(prefix)
{
return this._dictionary.wordsWithPrefix(prefix);
},
/**
* @param {string} word
* @return {boolean}
*/
hasWord: function(word)
{
return this._dictionary.hasWord(word);
},
/**
* @param {string} word
* @return {number}
*/
wordCount: function(word)
{
return this._dictionary.wordCount(word);
},
dispose: function()
{
this._codeMirror.off("beforeChange", this._beforeChange);
this._codeMirror.off("changes", this._changes);
this._dictionary.reset();
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {?string} url
* @param {!WebInspector.TextEditorDelegate} delegate
*/
WebInspector.CodeMirrorTextEditor = function(url, delegate)
{
WebInspector.VBox.call(this);
this._delegate = delegate;
this._url = url;
/** @type {!Map<string, !Set<number>>}} */
this._decoratedGutterLines = new Map();
this.registerRequiredCSS("cm/codemirror.css");
this.registerRequiredCSS("source_frame/cmdevtools.css");
WebInspector.CodeMirrorUtils.appendThemeStyle(this.element);
this._codeMirror = new window.CodeMirror(this.element, {
lineNumbers: true,
gutters: ["CodeMirror-linenumbers"],
matchBrackets: true,
smartIndent: false,
styleSelectedText: true,
electricChars: false,
styleActiveLine: true
});
this._codeMirrorElement = this.element.lastElementChild;
this._codeMirror._codeMirrorTextEditor = this;
CodeMirror.keyMap["devtools-common"] = {
"Left": "goCharLeft",
"Right": "goCharRight",
"Up": "goLineUp",
"Down": "goLineDown",
"End": "goLineEnd",
"Home": "goLineStartSmart",
"PageUp": "goPageUp",
"PageDown": "goPageDown",
"Delete": "delCharAfter",
"Backspace": "delCharBefore",
"Tab": "defaultTab",
"Shift-Tab": "indentLess",
"Enter": "smartNewlineAndIndent",
"Ctrl-Space": "autocomplete",
"Esc": "dismissMultipleSelections",
"Ctrl-M": "gotoMatchingBracket"
};
CodeMirror.keyMap["devtools-pc"] = {
"Ctrl-A": "selectAll",
"Ctrl-Z": "undoAndReveal",
"Shift-Ctrl-Z": "redoAndReveal",
"Ctrl-Y": "redo",
"Ctrl-Home": "goDocStart",
"Ctrl-Up": "goDocStart",
"Ctrl-End": "goDocEnd",
"Ctrl-Down": "goDocEnd",
"Ctrl-Left": "goGroupLeft",
"Ctrl-Right": "goGroupRight",
"Alt-Left": "moveCamelLeft",
"Alt-Right": "moveCamelRight",
"Shift-Alt-Left": "selectCamelLeft",
"Shift-Alt-Right": "selectCamelRight",
"Ctrl-Backspace": "delGroupBefore",
"Ctrl-Delete": "delGroupAfter",
"Ctrl-/": "toggleComment",
"Ctrl-D": "selectNextOccurrence",
"Ctrl-U": "undoLastSelection",
fallthrough: "devtools-common"
};
CodeMirror.keyMap["devtools-mac"] = {
"Cmd-A" : "selectAll",
"Cmd-Z" : "undoAndReveal",
"Shift-Cmd-Z": "redoAndReveal",
"Cmd-Up": "goDocStart",
"Cmd-Down": "goDocEnd",
"Alt-Left": "goGroupLeft",
"Alt-Right": "goGroupRight",
"Ctrl-Left": "moveCamelLeft",
"Ctrl-Right": "moveCamelRight",
"Shift-Ctrl-Left": "selectCamelLeft",
"Shift-Ctrl-Right": "selectCamelRight",
"Cmd-Left": "goLineStartSmart",
"Cmd-Right": "goLineEnd",
"Cmd-Backspace": "delLineLeft",
"Alt-Backspace": "delGroupBefore",
"Alt-Delete": "delGroupAfter",
"Cmd-/": "toggleComment",
"Cmd-D": "selectNextOccurrence",
"Cmd-U": "undoLastSelection",
fallthrough: "devtools-common"
};
WebInspector.moduleSetting("textEditorIndent").addChangeListener(this._onUpdateEditorIndentation, this);
WebInspector.moduleSetting("textEditorAutoDetectIndent").addChangeListener(this._onUpdateEditorIndentation, this);
this._onUpdateEditorIndentation();
WebInspector.moduleSetting("showWhitespacesInEditor").addChangeListener(this._updateCodeMirrorMode, this);
WebInspector.moduleSetting("textEditorBracketMatching").addChangeListener(this._enableBracketMatchingIfNeeded, this);
this._enableBracketMatchingIfNeeded();
this._codeMirror.setOption("keyMap", WebInspector.isMac() ? "devtools-mac" : "devtools-pc");
this._codeMirror.addKeyMap({
"'": "maybeAvoidSmartSingleQuotes",
"'\"'": "maybeAvoidSmartDoubleQuotes"
});
this._codeMirror.setOption("flattenSpans", false);
this._codeMirror.setOption("maxHighlightLength", WebInspector.CodeMirrorTextEditor.maxHighlightLength);
this._codeMirror.setOption("mode", null);
this._codeMirror.setOption("crudeMeasuringFrom", 1000);
this._shouldClearHistory = true;
this._lineSeparator = "\n";
this._autocompleteController = new WebInspector.TextEditorAutocompleteController(this, this._codeMirror);
this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this, this._codeMirror);
this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);
this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);
this._selectNextOccurrenceController = new WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController(this, this._codeMirror);
WebInspector.moduleSetting("textEditorAutocompletion").addChangeListener(this._enableAutocompletionIfNeeded, this);
this._enableAutocompletionIfNeeded();
this._codeMirror.on("changes", this._changes.bind(this));
this._codeMirror.on("gutterClick", this._gutterClick.bind(this));
this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this));
this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bind(this));
this._codeMirror.on("scroll", this._scroll.bind(this));
this._codeMirror.on("focus", this._focus.bind(this));
this._codeMirror.on("keyHandled", this._onKeyHandled.bind(this));
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);
/**
* @this {WebInspector.CodeMirrorTextEditor}
*/
function updateAnticipateJumpFlag(value)
{
this._isHandlingMouseDownEvent = value;
}
this.element.addEventListener("mousedown", updateAnticipateJumpFlag.bind(this, true), true);
this.element.addEventListener("mousedown", updateAnticipateJumpFlag.bind(this, false), false);
this.element.style.overflow = "hidden";
this._codeMirrorElement.classList.add("source-code");
this._codeMirrorElement.classList.add("fill");
this._elementToWidget = new Map();
this._nestedUpdatesCounter = 0;
this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), true);
this.element.addEventListener("keydown", this._handlePostKeyDown.bind(this), false);
this.element.tabIndex = 0;
this._setupWhitespaceHighlight();
}
WebInspector.CodeMirrorTextEditor.maxHighlightLength = 1000;
/**
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror)
{
codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();
}
CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocompleteCommand;
/**
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand = function(codeMirror)
{
codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.undoLastSelection();
}
CodeMirror.commands.undoLastSelection = WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand;
/**
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand = function(codeMirror)
{
codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.selectNextOccurrence();
}
CodeMirror.commands.selectNextOccurrence = WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand;
/**
* @param {boolean} shift
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand = function(shift, codeMirror)
{
codeMirror._codeMirrorTextEditor._doCamelCaseMovement(-1, shift);
}
CodeMirror.commands.moveCamelLeft = WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null, false);
CodeMirror.commands.selectCamelLeft = WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null, true);
/**
* @param {boolean} shift
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.moveCamelRightCommand = function(shift, codeMirror)
{
codeMirror._codeMirrorTextEditor._doCamelCaseMovement(1, shift);
}
CodeMirror.commands.moveCamelRight = WebInspector.CodeMirrorTextEditor.moveCamelRightCommand.bind(null, false);
CodeMirror.commands.selectCamelRight = WebInspector.CodeMirrorTextEditor.moveCamelRightCommand.bind(null, true);
/**
* @param {!CodeMirror} codeMirror
*/
CodeMirror.commands.smartNewlineAndIndent = function(codeMirror)
{
codeMirror.operation(innerSmartNewlineAndIndent.bind(null, codeMirror));
function innerSmartNewlineAndIndent(codeMirror)
{
var selections = codeMirror.listSelections();
var replacements = [];
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var cur = CodeMirror.cmpPos(selection.head, selection.anchor) < 0 ? selection.head : selection.anchor;
var line = codeMirror.getLine(cur.line);
var indent = WebInspector.TextUtils.lineIndent(line);
replacements.push("\n" + indent.substring(0, Math.min(cur.ch, indent.length)));
}
codeMirror.replaceSelections(replacements);
codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
}
}
/**
* @param {!CodeMirror} codeMirror
*/
CodeMirror.commands.gotoMatchingBracket = function(codeMirror)
{
var updatedSelections = [];
var selections = codeMirror.listSelections();
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var cursor = selection.head;
var matchingBracket = codeMirror.findMatchingBracket(cursor, false, { maxScanLines: 10000 });
var updatedHead = cursor;
if (matchingBracket && matchingBracket.match) {
var columnCorrection = CodeMirror.cmpPos(matchingBracket.from, cursor) === 0 ? 1 : 0;
updatedHead = new CodeMirror.Pos(matchingBracket.to.line, matchingBracket.to.ch + columnCorrection);
}
updatedSelections.push({
anchor: updatedHead,
head: updatedHead
});
}
codeMirror.setSelections(updatedSelections);
}
/**
* @param {!CodeMirror} codemirror
*/
CodeMirror.commands.undoAndReveal = function(codemirror)
{
var scrollInfo = codemirror.getScrollInfo();
codemirror.execCommand("undo");
var cursor = codemirror.getCursor("start");
codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();
}
/**
* @param {!CodeMirror} codemirror
*/
CodeMirror.commands.redoAndReveal = function(codemirror)
{
var scrollInfo = codemirror.getScrollInfo();
codemirror.execCommand("redo");
var cursor = codemirror.getCursor("start");
codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();
}
/**
* @return {!Object|undefined}
*/
CodeMirror.commands.dismissMultipleSelections = function(codemirror)
{
var selections = codemirror.listSelections();
var selection = selections[0];
if (selections.length === 1) {
if (codemirror._codeMirrorTextEditor._isSearchActive())
return CodeMirror.Pass;
if (WebInspector.CodeMirrorUtils.toRange(selection.anchor, selection.head).isEmpty())
return CodeMirror.Pass;
codemirror.setSelection(selection.anchor, selection.anchor, {scroll: false});
codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);
return;
}
codemirror.setSelection(selection.anchor, selection.head, {scroll: false});
codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);
}
/**
* @param {string} quoteCharacter
* @param {!CodeMirror} codeMirror
* @return {*}
*/
WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes = function(quoteCharacter, codeMirror)
{
var textEditor = codeMirror._codeMirrorTextEditor;
if (!WebInspector.moduleSetting("textEditorBracketMatching").get())
return CodeMirror.Pass;
var selections = textEditor.selections();
if (selections.length !== 1 || !selections[0].isEmpty())
return CodeMirror.Pass;
var selection = selections[0];
var token = textEditor.tokenAtTextPosition(selection.startLine, selection.startColumn);
if (!token || !token.type || token.type.indexOf("string") === -1)
return CodeMirror.Pass;
var line = textEditor.line(selection.startLine);
var tokenValue = line.substring(token.startColumn, token.endColumn);
if (tokenValue[0] === tokenValue[tokenValue.length - 1] && (tokenValue[0] === "'" || tokenValue[0] === "\""))
return CodeMirror.Pass;
codeMirror.replaceSelection(quoteCharacter);
}
CodeMirror.commands.maybeAvoidSmartSingleQuotes = WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes.bind(null, "'");
CodeMirror.commands.maybeAvoidSmartDoubleQuotes = WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes.bind(null, "\"");
WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000;
WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16;
WebInspector.CodeMirrorTextEditor.MaxEditableTextSize = 1024 * 1024 * 10;
WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing = 1000;
/**
* @param {!Array.<string>} lines
* @return {string}
*/
WebInspector.CodeMirrorTextEditor._guessIndentationLevel = function(lines)
{
var tabRegex = /^\t+/;
var tabLines = 0;
var indents = {};
for (var lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
var text = lines[lineNumber];
if (text.length === 0 || !WebInspector.TextUtils.isSpaceChar(text[0]))
continue;
if (tabRegex.test(text)) {
++tabLines;
continue;
}
var i = 0;
while (i < text.length && WebInspector.TextUtils.isSpaceChar(text[i]))
++i;
if (i % 2 !== 0)
continue;
indents[i] = 1 + (indents[i] || 0);
}
var linesCountPerIndentThreshold = 3 * lines.length / 100;
if (tabLines && tabLines > linesCountPerIndentThreshold)
return "\t";
var minimumIndent = Infinity;
for (var i in indents) {
if (indents[i] < linesCountPerIndentThreshold)
continue;
var indent = parseInt(i, 10);
if (minimumIndent > indent)
minimumIndent = indent;
}
if (minimumIndent === Infinity)
return WebInspector.moduleSetting("textEditorIndent").get();
return " ".repeat(minimumIndent);
}
WebInspector.CodeMirrorTextEditor.prototype = {
/**
* @param {string=} additionalWordChars
* @return {!WebInspector.CodeMirrorDictionary}
*/
createTextDictionary: function(additionalWordChars)
{
return new WebInspector.CodeMirrorDictionary(this._codeMirror, additionalWordChars);
},
_enableAutocompletionIfNeeded: function()
{
this._autocompleteController.setEnabled(WebInspector.moduleSetting("textEditorAutocompletion").get());
},
_onKeyHandled: function()
{
WebInspector.shortcutRegistry.dismissPendingShortcutAction();
},
_onAutoAppendedSpaces: function()
{
this._autoAppendedSpaces = this._autoAppendedSpaces || [];
for (var i = 0; i < this._autoAppendedSpaces.length; ++i) {
var position = this._autoAppendedSpaces[i].resolve();
if (!position)
continue;
var line = this.line(position.lineNumber);
if (line.length === position.columnNumber && WebInspector.TextUtils.lineIndent(line).length === line.length)
this._codeMirror.replaceRange("", new CodeMirror.Pos(position.lineNumber, 0), new CodeMirror.Pos(position.lineNumber, position.columnNumber));
}
this._autoAppendedSpaces = [];
var selections = this.selections();
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
this._autoAppendedSpaces.push(this.textEditorPositionHandle(selection.startLine, selection.startColumn));
}
},
/**
* @param {number} lineNumber
* @param {number} lineLength
* @param {number} charNumber
* @return {{lineNumber: number, columnNumber: number}}
*/
_normalizePositionForOverlappingColumn: function(lineNumber, lineLength, charNumber)
{
var linesCount = this._codeMirror.lineCount();
var columnNumber = charNumber;
if (charNumber < 0 && lineNumber > 0) {
--lineNumber;
columnNumber = this.line(lineNumber).length;
} else if (charNumber >= lineLength && lineNumber < linesCount - 1) {
++lineNumber;
columnNumber = 0;
} else {
columnNumber = Number.constrain(charNumber, 0, lineLength);
}
return {
lineNumber: lineNumber,
columnNumber: columnNumber
};
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @param {number} direction
* @return {{lineNumber: number, columnNumber: number}}
*/
_camelCaseMoveFromPosition: function(lineNumber, columnNumber, direction)
{
/**
* @param {number} charNumber
* @param {number} length
* @return {boolean}
*/
function valid(charNumber, length)
{
return charNumber >= 0 && charNumber < length;
}
/**
* @param {string} text
* @param {number} charNumber
* @return {boolean}
*/
function isWordStart(text, charNumber)
{
var position = charNumber;
var nextPosition = charNumber + 1;
return valid(position, text.length) && valid(nextPosition, text.length)
&& WebInspector.TextUtils.isWordChar(text[position]) && WebInspector.TextUtils.isWordChar(text[nextPosition])
&& WebInspector.TextUtils.isUpperCase(text[position]) && WebInspector.TextUtils.isLowerCase(text[nextPosition]);
}
/**
* @param {string} text
* @param {number} charNumber
* @return {boolean}
*/
function isWordEnd(text, charNumber)
{
var position = charNumber;
var prevPosition = charNumber - 1;
return valid(position, text.length) && valid(prevPosition, text.length)
&& WebInspector.TextUtils.isWordChar(text[position]) && WebInspector.TextUtils.isWordChar(text[prevPosition])
&& WebInspector.TextUtils.isUpperCase(text[position]) && WebInspector.TextUtils.isLowerCase(text[prevPosition]);
}
/**
* @param {number} lineNumber
* @param {number} lineLength
* @param {number} columnNumber
* @return {{lineNumber: number, columnNumber: number}}
*/
function constrainPosition(lineNumber, lineLength, columnNumber)
{
return {
lineNumber: lineNumber,
columnNumber: Number.constrain(columnNumber, 0, lineLength)
};
}
var text = this.line(lineNumber);
var length = text.length;
if ((columnNumber === length && direction === 1)
|| (columnNumber === 0 && direction === -1))
return this._normalizePositionForOverlappingColumn(lineNumber, length, columnNumber + direction);
var charNumber = direction === 1 ? columnNumber : columnNumber - 1;
// Move through initial spaces if any.
while (valid(charNumber, length) && WebInspector.TextUtils.isSpaceChar(text[charNumber]))
charNumber += direction;
if (!valid(charNumber, length))
return constrainPosition(lineNumber, length, charNumber);
if (WebInspector.TextUtils.isStopChar(text[charNumber])) {
while (valid(charNumber, length) && WebInspector.TextUtils.isStopChar(text[charNumber]))
charNumber += direction;
if (!valid(charNumber, length))
return constrainPosition(lineNumber, length, charNumber);
return {
lineNumber: lineNumber,
columnNumber: direction === -1 ? charNumber + 1 : charNumber
};
}
charNumber += direction;
while (valid(charNumber, length) && !isWordStart(text, charNumber) && !isWordEnd(text, charNumber) && WebInspector.TextUtils.isWordChar(text[charNumber]))
charNumber += direction;
if (!valid(charNumber, length))
return constrainPosition(lineNumber, length, charNumber);
if (isWordStart(text, charNumber) || isWordEnd(text, charNumber)) {
return {
lineNumber: lineNumber,
columnNumber: charNumber
};
}
return {
lineNumber: lineNumber,
columnNumber: direction === -1 ? charNumber + 1 : charNumber
};
},
/**
* @param {number} direction
* @param {boolean} shift
*/
_doCamelCaseMovement: function(direction, shift)
{
var selections = this.selections();
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var move = this._camelCaseMoveFromPosition(selection.endLine, selection.endColumn, direction);
selection.endLine = move.lineNumber;
selection.endColumn = move.columnNumber;
if (!shift)
selections[i] = selection.collapseToEnd();
}
this.setSelections(selections);
},
dispose: function()
{
WebInspector.moduleSetting("textEditorIndent").removeChangeListener(this._onUpdateEditorIndentation, this);
WebInspector.moduleSetting("textEditorAutoDetectIndent").removeChangeListener(this._onUpdateEditorIndentation, this);
WebInspector.moduleSetting("showWhitespacesInEditor").removeChangeListener(this._updateCodeMirrorMode, this);
WebInspector.moduleSetting("textEditorBracketMatching").removeChangeListener(this._enableBracketMatchingIfNeeded, this);
WebInspector.moduleSetting("textEditorAutocompletion").removeChangeListener(this._enableAutocompletionIfNeeded, this);
},
_enableBracketMatchingIfNeeded: function()
{
this._codeMirror.setOption("autoCloseBrackets", WebInspector.moduleSetting("textEditorBracketMatching").get() ? { explode: false } : false);
},
/**
* @override
*/
wasShown: function()
{
if (this._wasOnceShown)
return;
this._wasOnceShown = true;
this._codeMirror.refresh();
},
/**
* @override
*/
willHide: function()
{
delete this._editorSizeInSync;
},
_onUpdateEditorIndentation: function()
{
this._setEditorIndentation(WebInspector.CodeMirrorUtils.pullLines(this._codeMirror, WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing));
},
/**
* @param {!Array.<string>} lines
*/
_setEditorIndentation: function(lines)
{
var extraKeys = {};
var indent = WebInspector.moduleSetting("textEditorIndent").get();
if (WebInspector.moduleSetting("textEditorAutoDetectIndent").get())
indent = WebInspector.CodeMirrorTextEditor._guessIndentationLevel(lines);
if (indent === WebInspector.TextUtils.Indent.TabCharacter) {
this._codeMirror.setOption("indentWithTabs", true);
this._codeMirror.setOption("indentUnit", 4);
} else {
this._codeMirror.setOption("indentWithTabs", false);
this._codeMirror.setOption("indentUnit", indent.length);
extraKeys.Tab = function(codeMirror)
{
if (codeMirror.somethingSelected())
return CodeMirror.Pass;
var pos = codeMirror.getCursor("head");
codeMirror.replaceRange(indent.substring(pos.ch % indent.length), codeMirror.getCursor());
}
}
this._codeMirror.setOption("extraKeys", extraKeys);
this._indentationLevel = indent;
},
/**
* @return {string}
*/
indent: function()
{
return this._indentationLevel;
},
/**
* @return {boolean}
*/
_isSearchActive: function()
{
return !!this._tokenHighlighter.highlightedRegex();
},
/**
* @param {!RegExp} regex
* @param {?WebInspector.TextRange} range
*/
highlightSearchResults: function(regex, range)
{
/**
* @this {WebInspector.CodeMirrorTextEditor}
*/
function innerHighlightRegex()
{
if (range) {
this._revealLine(range.startLine);
if (range.endColumn > WebInspector.CodeMirrorTextEditor.maxHighlightLength)
this.setSelection(range);
else
this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine, range.startColumn));
}
this._tokenHighlighter.highlightSearchResults(regex, range);
}
if (!this._selectionBeforeSearch)
this._selectionBeforeSearch = this.selection();
this._codeMirror.operation(innerHighlightRegex.bind(this));
},
cancelSearchResultsHighlight: function()
{
this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
if (this._selectionBeforeSearch) {
this._reportJump(this._selectionBeforeSearch, this.selection());
delete this._selectionBeforeSearch;
}
},
undo: function()
{
this._codeMirror.undo();
},
redo: function()
{
this._codeMirror.redo();
},
_setupWhitespaceHighlight: function()
{
var doc = this.element.ownerDocument;
if (doc._codeMirrorWhitespaceStyleInjected || !WebInspector.moduleSetting("showWhitespacesInEditor").get())
return;
doc._codeMirrorWhitespaceStyleInjected = true;
const classBase = ".show-whitespaces .CodeMirror .cm-whitespace-";
const spaceChar = "·";
var spaceChars = "";
var rules = "";
for (var i = 1; i <= WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan; ++i) {
spaceChars += spaceChar;
var rule = classBase + i + "::before { content: '" + spaceChars + "';}\n";
rules += rule;
}
var style = doc.createElement("style");
style.textContent = rules;
doc.head.appendChild(style);
},
_handleKeyDown: function(e)
{
if (this._autocompleteController.keyDown(e))
e.consume(true);
},
_handlePostKeyDown: function(e)
{
if (e.defaultPrevented)
e.consume(true);
},
/**
* @param {!WebInspector.TextEditorAutocompleteDelegate} delegate
*/
setAutocompleteDelegate: function(delegate)
{
this._autocompleteController.setDelegate(delegate);
},
/**
* @param {number} lineNumber
* @param {number} column
* @return {?{x: number, y: number, height: number}}
*/
cursorPositionToCoordinates: function(lineNumber, column)
{
if (lineNumber >= this._codeMirror.lineCount() || lineNumber < 0 || column < 0 || column > this._codeMirror.getLine(lineNumber).length)
return null;
var metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, column));
return {
x: metrics.left,
y: metrics.top,
height: metrics.bottom - metrics.top
};
},
/**
* @param {number} x
* @param {number} y
* @return {?WebInspector.TextRange}
*/
coordinatesToCursorPosition: function(x, y)
{
var element = this.element.ownerDocument.elementFromPoint(x, y);
if (!element || !element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
return null;
var gutterBox = this._codeMirror.getGutterElement().boxInWindow();
if (x >= gutterBox.x && x <= gutterBox.x + gutterBox.width &&
y >= gutterBox.y && y <= gutterBox.y + gutterBox.height)
return null;
var coords = this._codeMirror.coordsChar({left: x, top: y});
return WebInspector.CodeMirrorUtils.toRange(coords, coords);
},
/**
* @param {number} lineNumber
* @param {number} column
* @return {?{startColumn: number, endColumn: number, type: string}}
*/
tokenAtTextPosition: function(lineNumber, column)
{
if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
return null;
var token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, (column || 0) + 1));
if (!token)
return null;
return {
startColumn: token.start,
endColumn: token.end,
type: token.type
};
},
/**
* @param {!WebInspector.TextRange} textRange
* @return {string}
*/
copyRange: function(textRange)
{
var pos = WebInspector.CodeMirrorUtils.toPos(textRange.normalize());
return this._codeMirror.getRange(pos.start, pos.end);
},
/**
* @return {boolean}
*/
isClean: function()
{
return this._codeMirror.isClean();
},
markClean: function()
{
this._codeMirror.markClean();
},
_hasLongLines: function()
{
function lineIterator(lineHandle)
{
if (lineHandle.text.length > WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold)
hasLongLines = true;
return hasLongLines;
}
var hasLongLines = false;
this._codeMirror.eachLine(lineIterator);
return hasLongLines;
},
/**
* @param {string} mimeType
* @return {string}
*/
_allWhitespaceOverlayMode: function(mimeType)
{
var modeName = CodeMirror.mimeModes[mimeType] ? (CodeMirror.mimeModes[mimeType].name || CodeMirror.mimeModes[mimeType]) : CodeMirror.mimeModes["text/plain"];
modeName += "+all-whitespaces";
if (CodeMirror.modes[modeName])
return modeName;
function modeConstructor(config, parserConfig)
{
function nextToken(stream)
{
if (stream.peek() === " ") {
var spaces = 0;
while (spaces < WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan && stream.peek() === " ") {
++spaces;
stream.next();
}
return "whitespace whitespace-" + spaces;
}
while (!stream.eol() && stream.peek() !== " ")
stream.next();
return null;
}
var whitespaceMode = {
token: nextToken
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false);
}
CodeMirror.defineMode(modeName, modeConstructor);
return modeName;
},
/**
* @param {string} mimeType
* @return {string}
*/
_trailingWhitespaceOverlayMode: function(mimeType)
{
var modeName = CodeMirror.mimeModes[mimeType] ? (CodeMirror.mimeModes[mimeType].name || CodeMirror.mimeModes[mimeType]) : CodeMirror.mimeModes["text/plain"];
modeName += "+trailing-whitespaces";
if (CodeMirror.modes[modeName])
return modeName;
function modeConstructor(config, parserConfig)
{
function nextToken(stream)
{
var pos = stream.pos;
if (stream.match(/^\s+$/, true))
return true ? "trailing-whitespace" : null;
do {
stream.next();
} while (!stream.eol() && stream.peek() !== " ");
return null;
}
var whitespaceMode = {
token: nextToken
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false);
}
CodeMirror.defineMode(modeName, modeConstructor);
return modeName;
},
_enableLongLinesMode: function()
{
this._codeMirror.setOption("styleSelectedText", false);
},
_disableLongLinesMode: function()
{
this._codeMirror.setOption("styleSelectedText", true);
},
_updateCodeMirrorMode: function()
{
this._setupWhitespaceHighlight();
var whitespaceMode = WebInspector.moduleSetting("showWhitespacesInEditor").get();
this.element.classList.toggle("show-whitespaces", whitespaceMode === "all");
var mimeType = this._mimeType;
if (whitespaceMode === "all")
mimeType = this._allWhitespaceOverlayMode(this._mimeType);
else if (whitespaceMode === "trailing")
mimeType = this._trailingWhitespaceOverlayMode(this._mimeType);
this._codeMirror.setOption("mode", mimeType);
WebInspector.CodeMirrorTextEditor._loadMimeTypeModes(this._mimeType, this._mimeTypeModesLoaded.bind(this));
},
_mimeTypeModesLoaded: function()
{
// Do not remove, this function is sniffed in tests.
this._updateCodeMirrorMode();
},
/**
* @param {string} mimeType
*/
setMimeType: function(mimeType)
{
this._mimeType = mimeType;
if (this._hasLongLines())
this._enableLongLinesMode();
else
this._disableLongLinesMode();
this._updateCodeMirrorMode();
},
/**
* @param {boolean} readOnly
*/
setReadOnly: function(readOnly)
{
this.element.classList.toggle("CodeMirror-readonly", readOnly);
this._codeMirror.setOption("readOnly", readOnly);
},
/**
* @return {boolean}
*/
readOnly: function()
{
return !!this._codeMirror.getOption("readOnly");
},
/**
* @param {!Object} highlightDescriptor
*/
removeHighlight: function(highlightDescriptor)
{
highlightDescriptor.clear();
},
/**
* @param {!WebInspector.TextRange} range
* @param {string} cssClass
* @return {!Object}
*/
highlightRange: function(range, cssClass)
{
cssClass = "CodeMirror-persist-highlight " + cssClass;
var pos = WebInspector.CodeMirrorUtils.toPos(range);
++pos.end.ch;
return this._codeMirror.markText(pos.start, pos.end, {
className: cssClass,
startStyle: cssClass + "-start",
endStyle: cssClass + "-end"
});
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this.element;
},
focus: function()
{
this._codeMirror.focus();
},
_handleElementFocus: function()
{
this._codeMirror.focus();
},
/**
* @param {function()} operation
*/
operation: function(operation)
{
this._codeMirror.operation(operation);
},
/**
* @param {number} lineNumber
*/
_revealLine: function(lineNumber)
{
this._innerRevealLine(lineNumber, this._codeMirror.getScrollInfo());
},
/**
* @param {number} lineNumber
* @param {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}} scrollInfo
*/
_innerRevealLine: function(lineNumber, scrollInfo)
{
var topLine = this._codeMirror.lineAtHeight(scrollInfo.top, "local");
var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
var linesPerScreen = bottomLine - topLine + 1;
if (lineNumber < topLine) {
var topLineToReveal = Math.max(lineNumber - (linesPerScreen / 2) + 1, 0) | 0;
this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal, 0));
} else if (lineNumber > bottomLine) {
var bottomLineToReveal = Math.min(lineNumber + (linesPerScreen / 2) - 1, this.linesCount - 1) | 0;
this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal, 0));
}
},
_gutterClick: function(instance, lineNumber, gutter, event)
{
this.dispatchEventToListeners(WebInspector.CodeMirrorTextEditor.Events.GutterClick, { lineNumber: lineNumber, event: event });
},
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
event.consume(true); //Consume event now to prevent document from handling the async menu
var target = event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt");
var promise;
if (target)
promise = this._delegate.populateLineGutterContextMenu(contextMenu, parseInt(target.textContent, 10) - 1);
else {
var textSelection = this.selection();
promise = this._delegate.populateTextAreaContextMenu(contextMenu, textSelection.startLine, textSelection.startColumn);
}
promise.then(showAsync.bind(this));
/**
* @this {WebInspector.CodeMirrorTextEditor}
*/
function showAsync()
{
contextMenu.appendApplicableItems(this);
contextMenu.show();
}
},
/**
* @param {number} lineNumber
* @param {boolean} disabled
* @param {boolean} conditional
*/
addBreakpoint: function(lineNumber, disabled, conditional)
{
if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
return;
var className = "cm-breakpoint" + (conditional ? " cm-breakpoint-conditional" : "") + (disabled ? " cm-breakpoint-disabled" : "");
this._codeMirror.addLineClass(lineNumber, "wrap", className);
},
/**
* @param {number} lineNumber
*/
removeBreakpoint: function(lineNumber)
{
if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
return;
var wrapClasses = this._codeMirror.getLineHandle(lineNumber).wrapClass;
if (!wrapClasses)
return;
var classes = wrapClasses.split(" ");
for (var i = 0; i < classes.length; ++i) {
if (classes[i].startsWith("cm-breakpoint"))
this._codeMirror.removeLineClass(lineNumber, "wrap", classes[i]);
}
},
/**
* @param {number} lineNumber
* @param {string} type
* @param {!Element} element
*/
setGutterDecoration: function(lineNumber, type, element)
{
var lines = this._decoratedGutterLines.get(type);
if (!lines) {
lines = new Set();
this._decoratedGutterLines.set(type, lines);
var gutters = this._codeMirror.getOption("gutters");
var gutterType = "CodeMirror-gutter-" + type;
if (gutters.indexOf(gutterType) === -1) {
gutters = gutters.concat([gutterType]);
this._codeMirror.setOption("gutters", gutters);
this._codeMirror.refresh();
}
}
lines.add(lineNumber);
this._codeMirror.setGutterMarker(lineNumber, "CodeMirror-gutter-" + type, element);
},
/**
* @param {string} type
*/
resetGutterDecorations: function(type)
{
this._decoratedGutterLines.delete(type);
var gutters = this._codeMirror.getOption("gutters").slice();
if (!gutters.remove("CodeMirror-gutter-" + type))
return;
this._codeMirror.setOption("gutters", gutters);
this._codeMirror.refresh();
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
*/
setExecutionLocation: function(lineNumber, columnNumber)
{
this.clearPositionHighlight();
this._executionLine = this._codeMirror.getLineHandle(lineNumber);
if (!this._executionLine)
return;
this._codeMirror.addLineClass(this._executionLine, "wrap", "cm-execution-line");
this._executionLineTailMarker = this._codeMirror.markText({ line: lineNumber, ch: columnNumber }, { line: lineNumber, ch: this._codeMirror.getLine(lineNumber).length }, { className: "cm-execution-line-tail" });
},
clearExecutionLine: function()
{
this.clearPositionHighlight();
if (this._executionLine)
this._codeMirror.removeLineClass(this._executionLine, "wrap", "cm-execution-line");
delete this._executionLine;
if (this._executionLineTailMarker)
this._executionLineTailMarker.clear();
delete this._executionLineTailMarker;
},
/**
* @param {number} lineNumber
* @param {string} className
* @param {boolean} toggled
*/
toggleLineClass: function(lineNumber, className, toggled)
{
if (this.hasLineClass(lineNumber, className) === toggled)
return;
var lineHandle = this._codeMirror.getLineHandle(lineNumber);
if (!lineHandle)
return;
if (toggled)
this._codeMirror.addLineClass(lineHandle, "wrap", className);
else
this._codeMirror.removeLineClass(lineHandle, "wrap", className);
},
/**
* @param {number} lineNumber
* @param {string} className
* @return {boolean}
*/
hasLineClass: function(lineNumber, className)
{
var lineInfo = this._codeMirror.lineInfo(lineNumber);
var wrapClass = lineInfo.wrapClass || "";
var classNames = wrapClass.split(" ");
return classNames.indexOf(className) !== -1;
},
/**
* @param {number} lineNumber
* @param {!Element} element
*/
addDecoration: function(lineNumber, element)
{
var widget = this._codeMirror.addLineWidget(lineNumber, element);
this._elementToWidget.set(element, widget);
},
/**
* @param {number} lineNumber
* @param {!Element} element
*/
removeDecoration: function(lineNumber, element)
{
var widget = this._elementToWidget.remove(element);
if (widget)
this._codeMirror.removeLineWidget(widget);
},
/**
* @param {number} lineNumber 0-based
* @param {number=} columnNumber
* @param {boolean=} shouldHighlight
*/
revealPosition: function(lineNumber, columnNumber, shouldHighlight)
{
lineNumber = Number.constrain(lineNumber, 0, this._codeMirror.lineCount() - 1);
if (typeof columnNumber !== "number")
columnNumber = 0;
columnNumber = Number.constrain(columnNumber, 0, this._codeMirror.getLine(lineNumber).length);
this.clearPositionHighlight();
this._highlightedLine = this._codeMirror.getLineHandle(lineNumber);
if (!this._highlightedLine)
return;
this._revealLine(lineNumber);
if (shouldHighlight) {
this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight");
this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
}
this.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, columnNumber));
},
clearPositionHighlight: function()
{
if (this._clearHighlightTimeout)
clearTimeout(this._clearHighlightTimeout);
delete this._clearHighlightTimeout;
if (this._highlightedLine)
this._codeMirror.removeLineClass(this._highlightedLine, null, "cm-highlight");
delete this._highlightedLine;
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [];
},
/**
* @param {number} width
* @param {number} height
*/
_updatePaddingBottom: function(width, height)
{
var scrollInfo = this._codeMirror.getScrollInfo();
var newPaddingBottom;
var linesElement = this._codeMirrorElement.querySelector(".CodeMirror-lines");
var lineCount = this._codeMirror.lineCount();
if (lineCount <= 1)
newPaddingBottom = 0;
else
newPaddingBottom = Math.max(scrollInfo.clientHeight - this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height, 0);
newPaddingBottom += "px";
linesElement.style.paddingBottom = newPaddingBottom;
this._codeMirror.setSize(width, height);
},
_resizeEditor: function()
{
var parentElement = this.element.parentElement;
if (!parentElement || !this.isShowing())
return;
var scrollLeft = this._codeMirror.doc.scrollLeft;
var scrollTop = this._codeMirror.doc.scrollTop;
var width = parentElement.offsetWidth;
var height = parentElement.offsetHeight - this.element.offsetTop;
this._codeMirror.setSize(width, height);
this._updatePaddingBottom(width, height);
this._codeMirror.scrollTo(scrollLeft, scrollTop);
},
/**
* @override
*/
onResize: function()
{
this._autocompleteController.finishAutocomplete();
this._resizeEditor();
this._editorSizeInSync = true;
if (this._selectionSetScheduled) {
delete this._selectionSetScheduled;
this.setSelection(this._lastSelection);
}
},
/**
* @param {!WebInspector.TextRange} range
* @param {string} text
* @return {!WebInspector.TextRange}
*/
editRange: function(range, text)
{
var pos = WebInspector.CodeMirrorUtils.toPos(range);
this._codeMirror.replaceRange(text, pos.start, pos.end);
var newRange = WebInspector.CodeMirrorUtils.toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
this._delegate.onTextChanged(range, newRange);
if (WebInspector.moduleSetting("textEditorAutoDetectIndent").get())
this._onUpdateEditorIndentation();
return newRange;
},
/**
* @param {number} lineNumber
* @param {number} column
* @param {function(string):boolean} isWordChar
* @return {!WebInspector.TextRange}
*/
wordRangeForCursorPosition: function(lineNumber, column, isWordChar)
{
var line = this.line(lineNumber);
var wordStart = column;
if (column !== 0 && isWordChar(line.charAt(column - 1))) {
wordStart = column - 1;
while (wordStart > 0 && isWordChar(line.charAt(wordStart - 1)))
--wordStart;
}
var wordEnd = column;
while (wordEnd < line.length && isWordChar(line.charAt(wordEnd)))
++wordEnd;
return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wordEnd);
},
/**
* @param {!CodeMirror} codeMirror
* @param {!Array.<!CodeMirror.ChangeObject>} changes
*/
_changes: function(codeMirror, changes)
{
if (!changes.length)
return;
// We do not show "scroll beyond end of file" span for one line documents, so we need to check if "document has one line" changed.
var hasOneLine = this._codeMirror.lineCount() === 1;
if (hasOneLine !== this._hasOneLine)
this._resizeEditor();
this._hasOneLine = hasOneLine;
var widgets = this._elementToWidget.valuesArray();
for (var i = 0; i < widgets.length; ++i)
this._codeMirror.removeLineWidget(widgets[i]);
this._elementToWidget.clear();
for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
var changeObject = changes[changeIndex];
var editInfo = WebInspector.CodeMirrorUtils.changeObjectToEditOperation(changeObject);
if (!this._muteTextChangedEvent)
this._delegate.onTextChanged(editInfo.oldRange, editInfo.newRange);
}
},
_cursorActivity: function()
{
var start = this._codeMirror.getCursor("anchor");
var end = this._codeMirror.getCursor("head");
this._delegate.selectionChanged(WebInspector.CodeMirrorUtils.toRange(start, end));
if (!this._isSearchActive())
this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
},
/**
* @param {!CodeMirror} codeMirror
* @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>}} selection
*/
_beforeSelectionChange: function(codeMirror, selection)
{
this._selectNextOccurrenceController.selectionWillChange();
if (!this._isHandlingMouseDownEvent)
return;
if (!selection.ranges.length)
return;
var primarySelection = selection.ranges[0];
this._reportJump(this.selection(), WebInspector.CodeMirrorUtils.toRange(primarySelection.anchor, primarySelection.head));
},
/**
* @param {?WebInspector.TextRange} from
* @param {?WebInspector.TextRange} to
*/
_reportJump: function(from, to)
{
if (from && to && from.equal(to))
return;
this._delegate.onJumpToPosition(from, to);
},
_scroll: function()
{
if (this._scrollTimer)
clearTimeout(this._scrollTimer);
var topmostLineNumber = this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local");
this._scrollTimer = setTimeout(this._delegate.scrollChanged.bind(this._delegate, topmostLineNumber), 100);
},
_focus: function()
{
this._delegate.editorFocused();
},
/**
* @param {number} lineNumber
*/
scrollToLine: function(lineNumber)
{
var pos = new CodeMirror.Pos(lineNumber, 0);
var coords = this._codeMirror.charCoords(pos, "local");
this._codeMirror.scrollTo(0, coords.top);
},
/**
* @return {number}
*/
firstVisibleLine: function()
{
return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local");
},
/**
* @return {number}
*/
lastVisibleLine: function()
{
var scrollInfo = this._codeMirror.getScrollInfo();
return this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
},
/**
* @return {!WebInspector.TextRange}
*/
selection: function()
{
var start = this._codeMirror.getCursor("anchor");
var end = this._codeMirror.getCursor("head");
return WebInspector.CodeMirrorUtils.toRange(start, end);
},
/**
* @return {!Array.<!WebInspector.TextRange>}
*/
selections: function()
{
var selectionList = this._codeMirror.listSelections();
var result = [];
for (var i = 0; i < selectionList.length; ++i) {
var selection = selectionList[i];
result.push(WebInspector.CodeMirrorUtils.toRange(selection.anchor, selection.head));
}
return result;
},
/**
* @return {?WebInspector.TextRange}
*/
lastSelection: function()
{
return this._lastSelection;
},
/**
* @param {!WebInspector.TextRange} textRange
*/
setSelection: function(textRange)
{
this._lastSelection = textRange;
if (!this._editorSizeInSync) {
this._selectionSetScheduled = true;
return;
}
var pos = WebInspector.CodeMirrorUtils.toPos(textRange);
this._codeMirror.setSelection(pos.start, pos.end);
},
/**
* @param {!Array.<!WebInspector.TextRange>} ranges
* @param {number=} primarySelectionIndex
*/
setSelections: function(ranges, primarySelectionIndex)
{
var selections = [];
for (var i = 0; i < ranges.length; ++i) {
var selection = WebInspector.CodeMirrorUtils.toPos(ranges[i]);
selections.push({
anchor: selection.start,
head: selection.end
});
}
primarySelectionIndex = primarySelectionIndex || 0;
this._codeMirror.setSelections(selections, primarySelectionIndex, { scroll: false });
},
/**
* @param {string} text
*/
_detectLineSeparator: function(text)
{
this._lineSeparator = text.indexOf("\r\n") >= 0 ? "\r\n" : "\n";
},
/**
* @param {string} text
*/
setText: function(text)
{
this._muteTextChangedEvent = true;
if (text.length > WebInspector.CodeMirrorTextEditor.MaxEditableTextSize) {
this._autocompleteController.setEnabled(false);
this.setReadOnly(true);
}
this._setEditorIndentation(text.split("\n").slice(0, WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing));
this._codeMirror.setValue(text);
if (this._shouldClearHistory) {
this._codeMirror.clearHistory();
this._shouldClearHistory = false;
}
this._detectLineSeparator(text);
delete this._muteTextChangedEvent;
},
/**
* @return {string}
*/
text: function()
{
return this._codeMirror.getValue().replace(/\n/g, this._lineSeparator);
},
/**
* @return {!WebInspector.TextRange}
*/
range: function()
{
var lineCount = this.linesCount;
var lastLine = this._codeMirror.getLine(lineCount - 1);
return WebInspector.CodeMirrorUtils.toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
},
/**
* @param {number} lineNumber
* @return {string}
*/
line: function(lineNumber)
{
return this._codeMirror.getLine(lineNumber);
},
/**
* @return {number}
*/
get linesCount()
{
return this._codeMirror.lineCount();
},
/**
* @param {number} line
* @param {string} name
* @param {?Object} value
*/
setAttribute: function(line, name, value)
{
if (line < 0 || line >= this._codeMirror.lineCount())
return;
var handle = this._codeMirror.getLineHandle(line);
if (handle.attributes === undefined) handle.attributes = {};
handle.attributes[name] = value;
},
/**
* @param {number} line
* @param {string} name
* @return {?Object} value
*/
getAttribute: function(line, name)
{
if (line < 0 || line >= this._codeMirror.lineCount())
return null;
var handle = this._codeMirror.getLineHandle(line);
return handle.attributes && handle.attributes[name] !== undefined ? handle.attributes[name] : null;
},
/**
* @param {number} line
* @param {string} name
*/
removeAttribute: function(line, name)
{
if (line < 0 || line >= this._codeMirror.lineCount())
return;
var handle = this._codeMirror.getLineHandle(line);
if (handle && handle.attributes)
delete handle.attributes[name];
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!WebInspector.TextEditorPositionHandle}
*/
textEditorPositionHandle: function(lineNumber, columnNumber)
{
return new WebInspector.CodeMirrorPositionHandle(this._codeMirror, new CodeMirror.Pos(lineNumber, columnNumber));
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.TextEditorPositionHandle}
* @param {!CodeMirror} codeMirror
* @param {!CodeMirror.Pos} pos
*/
WebInspector.CodeMirrorPositionHandle = function(codeMirror, pos)
{
this._codeMirror = codeMirror;
this._lineHandle = codeMirror.getLineHandle(pos.line);
this._columnNumber = pos.ch;
}
WebInspector.CodeMirrorPositionHandle.prototype = {
/**
* @override
* @return {?{lineNumber: number, columnNumber: number}}
*/
resolve: function()
{
var lineNumber = this._codeMirror.getLineNumber(this._lineHandle);
if (typeof lineNumber !== "number")
return null;
return {
lineNumber: lineNumber,
columnNumber: this._columnNumber
};
},
/**
* @override
* @param {!WebInspector.TextEditorPositionHandle} positionHandle
* @return {boolean}
*/
equal: function(positionHandle)
{
return positionHandle._lineHandle === this._lineHandle && positionHandle._columnNumber == this._columnNumber && positionHandle._codeMirror === this._codeMirror;
}
}
/**
* @constructor
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(textEditor, codeMirror)
{
this._textEditor = textEditor;
this._codeMirror = codeMirror;
}
WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
/**
* @param {!RegExp} regex
* @param {?WebInspector.TextRange} range
*/
highlightSearchResults: function(regex, range)
{
var oldRegex = this._highlightRegex;
this._highlightRegex = regex;
this._highlightRange = range;
if (this._searchResultMarker) {
this._searchResultMarker.clear();
delete this._searchResultMarker;
}
if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection");
var selectionStart = this._highlightRange ? new CodeMirror.Pos(this._highlightRange.startLine, this._highlightRange.startColumn) : null;
if (selectionStart)
this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection");
if (this._highlightRegex === oldRegex) {
// Do not re-add overlay mode if regex did not change for better performance.
if (this._highlightDescriptor)
this._highlightDescriptor.selectionStart = selectionStart;
} else {
this._removeHighlight();
this._setHighlighter(this._searchHighlighter.bind(this, this._highlightRegex), selectionStart);
}
if (this._highlightRange) {
var pos = WebInspector.CodeMirrorUtils.toPos(this._highlightRange);
this._searchResultMarker = this._codeMirror.markText(pos.start, pos.end, {className: "cm-column-with-selection"});
}
},
/**
* @return {!RegExp|undefined}
*/
highlightedRegex: function()
{
return this._highlightRegex;
},
highlightSelectedTokens: function()
{
delete this._highlightRegex;
delete this._highlightRange;
if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection");
this._removeHighlight();
var selectionStart = this._codeMirror.getCursor("start");
var selectionEnd = this._codeMirror.getCursor("end");
if (selectionStart.line !== selectionEnd.line)
return;
if (selectionStart.ch === selectionEnd.ch)
return;
var selections = this._codeMirror.getSelections();
if (selections.length > 1)
return;
var selectedText = selections[0];
if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch)) {
if (selectionStart)
this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection");
this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart);
}
},
/**
* @param {string} selectedText
* @param {number} lineNumber
* @param {number} startColumn
* @param {number} endColumn
*/
_isWord: function(selectedText, lineNumber, startColumn, endColumn)
{
var line = this._codeMirror.getLine(lineNumber);
var leftBound = startColumn === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(startColumn - 1));
var rightBound = endColumn === line.length || !WebInspector.TextUtils.isWordChar(line.charAt(endColumn));
return leftBound && rightBound && WebInspector.TextUtils.isWord(selectedText);
},
_removeHighlight: function()
{
if (this._highlightDescriptor) {
this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);
delete this._highlightDescriptor;
}
},
/**
* @param {!RegExp} regex
* @param {!CodeMirror.StringStream} stream
*/
_searchHighlighter: function(regex, stream)
{
if (stream.column() === 0)
delete this._searchMatchLength;
if (this._searchMatchLength) {
if (this._searchMatchLength > 2) {
for (var i = 0; i < this._searchMatchLength - 2; ++i)
stream.next();
this._searchMatchLength = 1;
return "search-highlight";
} else {
stream.next();
delete this._searchMatchLength;
return "search-highlight search-highlight-end";
}
}
var match = stream.match(regex, false);
if (match) {
stream.next();
var matchLength = match[0].length;
if (matchLength === 1)
return "search-highlight search-highlight-full";
this._searchMatchLength = matchLength;
return "search-highlight search-highlight-start";
}
while (!stream.match(regex, false) && stream.next()) {}
},
/**
* @param {string} token
* @param {!CodeMirror.Pos} selectionStart
* @param {!CodeMirror.StringStream} stream
*/
_tokenHighlighter: function(token, selectionStart, stream)
{
var tokenFirstChar = token.charAt(0);
if (stream.match(token) && (stream.eol() || !WebInspector.TextUtils.isWordChar(stream.peek())))
return stream.column() === selectionStart.ch ? "token-highlight column-with-selection" : "token-highlight";
var eatenChar;
do {
eatenChar = stream.next();
} while (eatenChar && (WebInspector.TextUtils.isWordChar(eatenChar) || stream.peek() !== tokenFirstChar));
},
/**
* @param {function(!CodeMirror.StringStream)} highlighter
* @param {?CodeMirror.Pos} selectionStart
*/
_setHighlighter: function(highlighter, selectionStart)
{
var overlayMode = {
token: highlighter
};
this._codeMirror.addOverlay(overlayMode);
this._highlightDescriptor = {
overlay: overlayMode,
selectionStart: selectionStart
};
}
}
/**
* @constructor
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.BlockIndentController = function(codeMirror)
{
codeMirror.addKeyMap(this);
}
WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = {
name: "blockIndentKeymap",
/**
* @return {*}
*/
Enter: function(codeMirror)
{
var selections = codeMirror.listSelections();
var replacements = [];
var allSelectionsAreCollapsedBlocks = false;
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var start = CodeMirror.cmpPos(selection.head, selection.anchor) < 0 ? selection.head : selection.anchor;
var line = codeMirror.getLine(start.line);
var indent = WebInspector.TextUtils.lineIndent(line);
var indentToInsert = "\n" + indent + codeMirror._codeMirrorTextEditor.indent();
var isCollapsedBlock = false;
if (selection.head.ch === 0)
return CodeMirror.Pass;
if (line.substr(selection.head.ch - 1, 2) === "{}") {
indentToInsert += "\n" + indent;
isCollapsedBlock = true;
} else if (line.substr(selection.head.ch - 1, 1) !== "{") {
return CodeMirror.Pass;
}
if (i > 0 && allSelectionsAreCollapsedBlocks !== isCollapsedBlock)
return CodeMirror.Pass;
replacements.push(indentToInsert);
allSelectionsAreCollapsedBlocks = isCollapsedBlock;
}
codeMirror.replaceSelections(replacements);
if (!allSelectionsAreCollapsedBlocks) {
codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
return;
}
selections = codeMirror.listSelections();
var updatedSelections = [];
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var line = codeMirror.getLine(selection.head.line - 1);
var position = new CodeMirror.Pos(selection.head.line - 1, line.length);
updatedSelections.push({
head: position,
anchor: position
});
}
codeMirror.setSelections(updatedSelections);
codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
},
/**
* @return {*}
*/
"'}'": function(codeMirror)
{
if (codeMirror.somethingSelected())
return CodeMirror.Pass;
var selections = codeMirror.listSelections();
var replacements = [];
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var line = codeMirror.getLine(selection.head.line);
if (line !== WebInspector.TextUtils.lineIndent(line))
return CodeMirror.Pass;
replacements.push("}");
}
codeMirror.replaceSelections(replacements);
selections = codeMirror.listSelections();
replacements = [];
var updatedSelections = [];
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var matchingBracket = codeMirror.findMatchingBracket(selection.head);
if (!matchingBracket || !matchingBracket.match)
return;
updatedSelections.push({
head: selection.head,
anchor: new CodeMirror.Pos(selection.head.line, 0)
});
var line = codeMirror.getLine(matchingBracket.to.line);
var indent = WebInspector.TextUtils.lineIndent(line);
replacements.push(indent + "}");
}
codeMirror.setSelections(updatedSelections);
codeMirror.replaceSelections(replacements);
}
}
/**
* @constructor
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror)
{
function moveLeft(shift, codeMirror)
{
codeMirror.setExtending(shift);
var cursor = codeMirror.getCursor("head");
codeMirror.execCommand("goGroupLeft");
var newCursor = codeMirror.getCursor("head");
if (newCursor.ch === 0 && newCursor.line !== 0) {
codeMirror.setExtending(false);
return;
}
var skippedText = codeMirror.getRange(newCursor, cursor, "#");
if (/^\s+$/.test(skippedText))
codeMirror.execCommand("goGroupLeft");
codeMirror.setExtending(false);
}
function moveRight(shift, codeMirror)
{
codeMirror.setExtending(shift);
var cursor = codeMirror.getCursor("head");
codeMirror.execCommand("goGroupRight");
var newCursor = codeMirror.getCursor("head");
if (newCursor.ch === 0 && newCursor.line !== 0) {
codeMirror.setExtending(false);
return;
}
var skippedText = codeMirror.getRange(cursor, newCursor, "#");
if (/^\s+$/.test(skippedText))
codeMirror.execCommand("goGroupRight");
codeMirror.setExtending(false);
}
var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl";
var leftKey = modifierKey + "-Left";
var rightKey = modifierKey + "-Right";
var keyMap = {};
keyMap[leftKey] = moveLeft.bind(null, false);
keyMap[rightKey] = moveRight.bind(null, false);
keyMap["Shift-" + leftKey] = moveLeft.bind(null, true);
keyMap["Shift-" + rightKey] = moveRight.bind(null, true);
codeMirror.addKeyMap(keyMap);
}
/**
* @constructor
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {!CodeMirror} codeMirror
*/
WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController = function(textEditor, codeMirror)
{
this._textEditor = textEditor;
this._codeMirror = codeMirror;
}
WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController.prototype = {
selectionWillChange: function()
{
if (!this._muteSelectionListener)
delete this._fullWordSelection;
},
/**
* @param {!Array.<!WebInspector.TextRange>} selections
* @param {!WebInspector.TextRange} range
* @return {boolean}
*/
_findRange: function(selections, range)
{
for (var i = 0; i < selections.length; ++i) {
if (range.equal(selections[i]))
return true;
}
return false;
},
undoLastSelection: function()
{
this._muteSelectionListener = true;
this._codeMirror.execCommand("undoSelection");
this._muteSelectionListener = false;
},
selectNextOccurrence: function()
{
var selections = this._textEditor.selections();
var anyEmptySelection = false;
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
anyEmptySelection = anyEmptySelection || selection.isEmpty();
if (selection.startLine !== selection.endLine)
return;
}
if (anyEmptySelection) {
this._expandSelectionsToWords(selections);
return;
}
var last = selections[selections.length - 1];
var next = last;
do {
next = this._findNextOccurrence(next, !!this._fullWordSelection);
} while (next && this._findRange(selections, next) && !next.equal(last));
if (!next)
return;
selections.push(next);
this._muteSelectionListener = true;
this._textEditor.setSelections(selections, selections.length - 1);
delete this._muteSelectionListener;
this._textEditor._revealLine(next.startLine);
},
/**
* @param {!Array.<!WebInspector.TextRange>} selections
*/
_expandSelectionsToWords: function(selections)
{
var newSelections = [];
for (var i = 0; i < selections.length; ++i) {
var selection = selections[i];
var startRangeWord = this._textEditor.wordRangeForCursorPosition(selection.startLine, selection.startColumn, WebInspector.TextUtils.isWordChar)
|| WebInspector.TextRange.createFromLocation(selection.startLine, selection.startColumn);
var endRangeWord = this._textEditor.wordRangeForCursorPosition(selection.endLine, selection.endColumn, WebInspector.TextUtils.isWordChar)
|| WebInspector.TextRange.createFromLocation(selection.endLine, selection.endColumn);
var newSelection = new WebInspector.TextRange(startRangeWord.startLine, startRangeWord.startColumn, endRangeWord.endLine, endRangeWord.endColumn);
newSelections.push(newSelection);
}
this._textEditor.setSelections(newSelections, newSelections.length - 1);
this._fullWordSelection = true;
},
/**
* @param {!WebInspector.TextRange} range
* @param {boolean} fullWord
* @return {?WebInspector.TextRange}
*/
_findNextOccurrence: function(range, fullWord)
{
range = range.normalize();
var matchedLineNumber;
var matchedColumnNumber;
var textToFind = this._textEditor.copyRange(range);
function findWordInLine(wordRegex, lineNumber, lineText, from, to)
{
if (typeof matchedLineNumber === "number")
return true;
wordRegex.lastIndex = from;
var result = wordRegex.exec(lineText);
if (!result || result.index + textToFind.length > to)
return false;
matchedLineNumber = lineNumber;
matchedColumnNumber = result.index;
return true;
}
var iteratedLineNumber;
function lineIterator(regex, lineHandle)
{
if (findWordInLine(regex, iteratedLineNumber++, lineHandle.text, 0, lineHandle.text.length))
return true;
}
var regexSource = textToFind.escapeForRegExp();
if (fullWord)
regexSource = "\\b" + regexSource + "\\b";
var wordRegex = new RegExp(regexSource, "g");
var currentLineText = this._codeMirror.getLine(range.startLine);
findWordInLine(wordRegex, range.startLine, currentLineText, range.endColumn, currentLineText.length);
iteratedLineNumber = range.startLine + 1;
this._codeMirror.eachLine(range.startLine + 1, this._codeMirror.lineCount(), lineIterator.bind(null, wordRegex));
iteratedLineNumber = 0;
this._codeMirror.eachLine(0, range.startLine, lineIterator.bind(null, wordRegex));
findWordInLine(wordRegex, range.startLine, currentLineText, 0, range.startColumn);
if (typeof matchedLineNumber !== "number")
return null;
return new WebInspector.TextRange(matchedLineNumber, matchedColumnNumber, matchedLineNumber, matchedColumnNumber + textToFind.length);
}
}
/**
* @param {string} modeName
* @param {string} tokenPrefix
*/
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(modeName, tokenPrefix)
{
var oldModeName = modeName + "-old";
if (CodeMirror.modes[oldModeName])
return;
CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]);
CodeMirror.defineMode(modeName, modeConstructor);
function modeConstructor(config, parserConfig)
{
var innerConfig = {};
for (var i in parserConfig)
innerConfig[i] = parserConfig[i];
innerConfig.name = oldModeName;
var codeMirrorMode = CodeMirror.getMode(config, innerConfig);
codeMirrorMode.name = modeName;
codeMirrorMode.token = tokenOverride.bind(null, codeMirrorMode.token);
return codeMirrorMode;
}
function tokenOverride(superToken, stream, state)
{
var token = superToken(stream, state);
return token ? tokenPrefix + token.split(/ +/).join(" " + tokenPrefix) : token;
}
}
/**
* @interface
*/
WebInspector.TextEditorPositionHandle = function() {}
WebInspector.TextEditorPositionHandle.prototype = {
/**
* @return {?{lineNumber: number, columnNumber: number}}
*/
resolve: function() { },
/**
* @param {!WebInspector.TextEditorPositionHandle} positionHandle
* @return {boolean}
*/
equal: function(positionHandle) { }
}
/**
* @interface
*/
WebInspector.TextEditorDelegate = function() {}
WebInspector.TextEditorDelegate.prototype = {
/**
* @param {!WebInspector.TextRange} oldRange
* @param {!WebInspector.TextRange} newRange
*/
onTextChanged: function(oldRange, newRange) { },
/**
* @param {!WebInspector.TextRange} textRange
*/
selectionChanged: function(textRange) { },
/**
* @param {number} lineNumber
*/
scrollChanged: function(lineNumber) { },
editorFocused: function() { },
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
* @return {!Promise}
*/
populateLineGutterContextMenu: function(contextMenu, lineNumber) { },
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber) { },
/**
* @param {?WebInspector.TextRange} from
* @param {?WebInspector.TextRange} to
*/
onJumpToPosition: function(from, to) { }
}
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("css", "css-");
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("javascript", "js-");
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("xml", "xml-");
/** @typedef {{lineNumber: number, event: !Event}} */
WebInspector.CodeMirrorTextEditor.GutterClickEventData;
/** @enum {string} */
WebInspector.CodeMirrorTextEditor.Events = {
GutterClick: "GutterClick"
}
/** @type {!Set<!Runtime.Extension>} */
WebInspector.CodeMirrorTextEditor._loadedMimeModeExtensions = new Set();
/**
* @param {string} mimeType
* @param {function()} callback
*/
WebInspector.CodeMirrorTextEditor._loadMimeTypeModes = function(mimeType, callback)
{
var installed = WebInspector.CodeMirrorTextEditor._loadedMimeModeExtensions;
var nameToExtension = new Map();
var extensions = self.runtime.extensions(WebInspector.CodeMirrorMimeMode);
for (var extension of extensions)
nameToExtension.set(extension.descriptor()["fileName"], extension);
var modesToLoad = new Set();
for (var extension of extensions) {
var descriptor = extension.descriptor();
if (installed.has(extension) || descriptor["mimeTypes"].indexOf(mimeType) === -1)
continue;
modesToLoad.add(extension);
var deps = descriptor["dependencies"] || [];
for (var i = 0; i < deps.length; ++i) {
var extension = nameToExtension.get(deps[i]);
if (extension && !installed.has(extension))
modesToLoad.add(extension);
}
}
var promises = [];
for (var extension of modesToLoad)
promises.push(extension.instancePromise().then(installMode.bind(null, extension)));
if (promises.length)
Promise.all(promises).then(callback);
/**
* @param {!Runtime.Extension} extension
* @param {!Object} instance
*/
function installMode(extension, instance)
{
if (installed.has(extension))
return;
var mode = /** @type {!WebInspector.CodeMirrorMimeMode} */ (instance);
mode.install(extension);
installed.add(extension);
}
}
/**
* @interface
*/
WebInspector.CodeMirrorMimeMode = function()
{
}
WebInspector.CodeMirrorMimeMode.prototype = {
/**
* @param {!Runtime.Extension} extension
*/
install: function(extension) { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | 2 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.InplaceEditor}
*/
WebInspector.CodeMirrorUtils = function()
{
WebInspector.InplaceEditor.call(this);
}
/**
* @param {!WebInspector.TextRange} range
* @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}}
*/
WebInspector.CodeMirrorUtils.toPos = function(range)
{
return {
start: new CodeMirror.Pos(range.startLine, range.startColumn),
end: new CodeMirror.Pos(range.endLine, range.endColumn)
};
}
/**
* @param {!CodeMirror.Pos} start
* @param {!CodeMirror.Pos} end
* @return {!WebInspector.TextRange}
*/
WebInspector.CodeMirrorUtils.toRange = function(start, end)
{
return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
}
/**
* @param {!CodeMirror.ChangeObject} changeObject
* @return {{oldRange: !WebInspector.TextRange, newRange: !WebInspector.TextRange}}
*/
WebInspector.CodeMirrorUtils.changeObjectToEditOperation = function(changeObject)
{
var oldRange = WebInspector.CodeMirrorUtils.toRange(changeObject.from, changeObject.to);
var newRange = oldRange.clone();
var linesAdded = changeObject.text.length;
if (linesAdded === 0) {
newRange.endLine = newRange.startLine;
newRange.endColumn = newRange.startColumn;
} else if (linesAdded === 1) {
newRange.endLine = newRange.startLine;
newRange.endColumn = newRange.startColumn + changeObject.text[0].length;
} else {
newRange.endLine = newRange.startLine + linesAdded - 1;
newRange.endColumn = changeObject.text[linesAdded - 1].length;
}
return {
oldRange: oldRange,
newRange: newRange
};
}
/**
* @param {!CodeMirror} codeMirror
* @param {number} linesCount
* @return {!Array.<string>}
*/
WebInspector.CodeMirrorUtils.pullLines = function(codeMirror, linesCount)
{
var lines = [];
codeMirror.eachLine(0, linesCount, onLineHandle);
return lines;
/**
* @param {!{text: string}} lineHandle
*/
function onLineHandle(lineHandle)
{
lines.push(lineHandle.text);
}
}
WebInspector.CodeMirrorUtils.prototype = {
/**
* @override
* @return {string}
*/
editorContent: function(editingContext) {
return editingContext.codeMirror.getValue();
},
/**
* @param {!Event} e
*/
_consumeCopy: function(e)
{
e.consume();
},
setUpEditor: function(editingContext)
{
var element = editingContext.element;
var config = editingContext.config;
editingContext.cssLoadView = new WebInspector.CodeMirrorCSSLoadView();
editingContext.cssLoadView.show(element);
WebInspector.setCurrentFocusElement(element);
element.addEventListener("copy", this._consumeCopy, false);
var codeMirror = new window.CodeMirror(element, {
mode: config.mode,
lineWrapping: config.lineWrapping,
smartIndent: config.smartIndent,
autofocus: true,
theme: config.theme,
value: config.initialValue
});
codeMirror.getWrapperElement().classList.add("source-code");
codeMirror.on("cursorActivity", function(cm) {
cm.display.cursorDiv.scrollIntoViewIfNeeded(false);
});
editingContext.codeMirror = codeMirror;
},
closeEditor: function(editingContext)
{
editingContext.element.removeEventListener("copy", this._consumeCopy, false);
editingContext.cssLoadView.detach();
},
cancelEditing: function(editingContext)
{
editingContext.codeMirror.setValue(editingContext.oldText);
},
augmentEditingHandle: function(editingContext, handle)
{
function setWidth(editingContext, width)
{
var padding = 30;
var codeMirror = editingContext.codeMirror;
codeMirror.getWrapperElement().style.width = (width - codeMirror.getWrapperElement().offsetLeft - padding) + "px";
codeMirror.refresh();
}
handle.codeMirror = editingContext.codeMirror;
handle.setWidth = setWidth.bind(null, editingContext);
},
__proto__: WebInspector.InplaceEditor.prototype
}
/**
* @constructor
* @implements {WebInspector.TokenizerFactory}
*/
WebInspector.CodeMirrorUtils.TokenizerFactory = function() { }
WebInspector.CodeMirrorUtils.TokenizerFactory.prototype = {
/**
* @override
* @param {string} mimeType
* @return {function(string, function(string, ?string, number, number))}
*/
createTokenizer: function(mimeType)
{
var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
var state = CodeMirror.startState(mode);
function tokenize(line, callback)
{
var stream = new CodeMirror.StringStream(line);
while (!stream.eol()) {
var style = mode.token(stream, state);
var value = stream.current();
callback(value, style, stream.start, stream.start + value.length);
stream.start = stream.pos;
}
}
return tokenize;
}
}
/**
* This bogus view is needed to load/unload CodeMirror-related CSS on demand.
*
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.CodeMirrorCSSLoadView = function()
{
WebInspector.VBox.call(this);
this.element.classList.add("hidden");
this.registerRequiredCSS("cm/codemirror.css");
this.registerRequiredCSS("source_frame/cmdevtools.css");
WebInspector.CodeMirrorUtils.appendThemeStyle(this.element);
}
WebInspector.CodeMirrorCSSLoadView.prototype = {
__proto__: WebInspector.VBox.prototype
}
/**
* @param {!Element} element
*/
WebInspector.CodeMirrorUtils.appendThemeStyle = function(element)
{
if (WebInspector.themeSupport.hasTheme())
return;
var backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor();
var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor();
var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : "";
var style = createElement("style");
if (foregroundColorRule || backgroundColorRule)
style.textContent = backgroundColorRule + foregroundColorRule;
element.appendChild(style);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBoxWithToolbarItems}
* @param {string} mimeType
* @param {!WebInspector.ContentProvider} contentProvider
*/
WebInspector.FontView = function(mimeType, contentProvider)
{
WebInspector.VBoxWithToolbarItems.call(this);
this.registerRequiredCSS("source_frame/fontView.css");
this.element.classList.add("font-view");
this._url = contentProvider.contentURL();
this._mimeType = mimeType;
this._contentProvider = contentProvider;
this._mimeTypeLabel = new WebInspector.ToolbarText(mimeType);
}
WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ];
WebInspector.FontView._fontId = 0;
WebInspector.FontView._measureFontSize = 50;
WebInspector.FontView.prototype = {
/**
* @override
* @return {!Array<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._mimeTypeLabel];
},
/**
* @param {string} uniqueFontName
* @param {?string} content
*/
_onFontContentLoaded: function(uniqueFontName, content)
{
var url = content ? WebInspector.Resource.contentAsDataURL(content, this._mimeType, true) : this._url;
this.fontStyleElement.textContent = String.sprintf("@font-face { font-family: \"%s\"; src: url(%s); }", uniqueFontName, url);
},
_createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;
var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId);
this.fontStyleElement = createElement("style");
this._contentProvider.requestContent().then(this._onFontContentLoaded.bind(this, uniqueFontName));
this.element.appendChild(this.fontStyleElement);
var fontPreview = createElement("div");
for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) {
if (i > 0)
fontPreview.createChild("br");
fontPreview.createTextChild(WebInspector.FontView._fontPreviewLines[i]);
}
this.fontPreviewElement = fontPreview.cloneNode(true);
this.fontPreviewElement.style.setProperty("font-family", uniqueFontName);
this.fontPreviewElement.style.setProperty("visibility", "hidden");
this._dummyElement = fontPreview;
this._dummyElement.style.visibility = "hidden";
this._dummyElement.style.zIndex = "-1";
this._dummyElement.style.display = "inline";
this._dummyElement.style.position = "absolute";
this._dummyElement.style.setProperty("font-family", uniqueFontName);
this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px");
this.element.appendChild(this.fontPreviewElement);
},
wasShown: function()
{
this._createContentIfNeeded();
this.updateFontPreviewSize();
},
onResize: function()
{
if (this._inResize)
return;
this._inResize = true;
try {
this.updateFontPreviewSize();
} finally {
delete this._inResize;
}
},
_measureElement: function()
{
this.element.appendChild(this._dummyElement);
var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight };
this.element.removeChild(this._dummyElement);
return result;
},
updateFontPreviewSize: function()
{
if (!this.fontPreviewElement || !this.isShowing())
return;
this.fontPreviewElement.style.removeProperty("visibility");
var dimension = this._measureElement();
const height = dimension.height;
const width = dimension.width;
// Subtract some padding. This should match the paddings in the CSS plus room for the scrollbar.
const containerWidth = this.element.offsetWidth - 50;
const containerHeight = this.element.offsetHeight - 30;
if (!height || !width || !containerWidth || !containerHeight) {
this.fontPreviewElement.style.removeProperty("font-size");
return;
}
var widthRatio = containerWidth / width;
var heightRatio = containerHeight / height;
var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;
this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
},
__proto__: WebInspector.VBoxWithToolbarItems.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 2 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @extends {WebInspector.VBoxWithToolbarItems}
* @constructor
* @param {string} mimeType
* @param {!WebInspector.ContentProvider} contentProvider
*/
WebInspector.ImageView = function(mimeType, contentProvider)
{
WebInspector.VBoxWithToolbarItems.call(this);
this.registerRequiredCSS("source_frame/imageView.css");
this.element.classList.add("image-view");
this._url = contentProvider.contentURL();
this._parsedURL = new WebInspector.ParsedURL(this._url);
this._mimeType = mimeType;
this._contentProvider = contentProvider;
this._sizeLabel = new WebInspector.ToolbarText();
this._dimensionsLabel = new WebInspector.ToolbarText();
this._mimeTypeLabel = new WebInspector.ToolbarText(mimeType);
}
WebInspector.ImageView.prototype = {
/**
* @override
* @return {!Array<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._sizeLabel, new WebInspector.ToolbarSeparator(), this._dimensionsLabel, new WebInspector.ToolbarSeparator(), this._mimeTypeLabel];
},
wasShown: function()
{
this._createContentIfNeeded();
},
_createContentIfNeeded: function()
{
if (this._container)
return;
this._container = this.element.createChild("div", "image");
var imagePreviewElement = this._container.createChild("img", "resource-image-view");
imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);
WebInspector.Resource.populateImageSource(this._url, this._mimeType, this._contentProvider, imagePreviewElement);
this._contentProvider.requestContent().then(onContentAvailable.bind(this));
/**
* @param {?string} content
* @this {WebInspector.ImageView}
*/
function onContentAvailable(content)
{
this._sizeLabel.setText(Number.bytesToString(this._base64ToSize(content)));
this._dimensionsLabel.setText(WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight));
}
this._imagePreviewElement = imagePreviewElement;
},
/**
* @param {?string} content
* @return {number}
*/
_base64ToSize: function(content)
{
if (!content || !content.length)
return 0;
var size = (content.length || 0) * 3 / 4;
if (content.length > 0 && content[content.length - 1] === "=")
size--;
if (content.length > 1 && content[content.length - 2] === "=")
size--;
return size;
},
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^image URL"), this._copyImageURL.bind(this));
if (this._imagePreviewElement.src)
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^image as Data URL"), this._copyImageAsDataURL.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^image in ^new ^tab"), this._openInNewTab.bind(this));
contextMenu.show();
},
_copyImageAsDataURL: function()
{
InspectorFrontendHost.copyText(this._imagePreviewElement.src);
},
_copyImageURL: function()
{
InspectorFrontendHost.copyText(this._url);
},
_openInNewTab: function()
{
InspectorFrontendHost.openInNewTab(this._url);
},
__proto__: WebInspector.VBoxWithToolbarItems.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) IBM Corp. 2009 All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @extends {WebInspector.SourceFrame}
* @constructor
* @param {!WebInspector.ContentProvider} resource
*/
WebInspector.ResourceSourceFrame = function(resource)
{
this._resource = resource;
WebInspector.SourceFrame.call(this, resource);
}
WebInspector.ResourceSourceFrame.prototype = {
get resource()
{
return this._resource;
},
/**
* @override
* @param {!WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
{
contextMenu.appendApplicableItems(this._resource);
return Promise.resolve();
},
__proto__: WebInspector.SourceFrame.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBoxWithToolbarItems}
* @implements {WebInspector.Searchable}
* @implements {WebInspector.Replaceable}
* @param {!WebInspector.ContentProvider} contentProvider
*/
WebInspector.SourceFrame = function(contentProvider)
{
WebInspector.VBoxWithToolbarItems.call(this);
this._url = contentProvider.contentURL();
this._contentProvider = contentProvider;
var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);
this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
this._currentSearchResultIndex = -1;
this._searchResults = [];
this._textEditor.setReadOnly(!this.canEditSource());
this._shortcuts = {};
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this._sourcePosition = new WebInspector.ToolbarText();
/**
* @type {?WebInspector.SearchableView}
*/
this._searchableView = null;
}
WebInspector.SourceFrame.Events = {
ScrollChanged: "ScrollChanged",
SelectionChanged: "SelectionChanged",
JumpHappened: "JumpHappened"
}
WebInspector.SourceFrame.prototype = {
/**
* @param {number} key
* @param {function():boolean} handler
*/
addShortcut: function(key, handler)
{
this._shortcuts[key] = handler;
},
wasShown: function()
{
this._ensureContentLoaded();
this._textEditor.show(this.element);
this._editorAttached = true;
this._wasShownOrLoaded();
},
/**
* @return {boolean}
*/
isEditorShowing: function()
{
return this.isShowing() && this._editorAttached;
},
willHide: function()
{
WebInspector.Widget.prototype.willHide.call(this);
this._clearPositionToReveal();
},
/**
* @override
* @return {!Array<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [this._sourcePosition];
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._textEditor.defaultFocusedElement();
},
get loaded()
{
return this._loaded;
},
get textEditor()
{
return this._textEditor;
},
_ensureContentLoaded: function()
{
if (!this._contentRequested) {
this._contentRequested = true;
this._contentProvider.requestContent().then(this.setContent.bind(this));
}
},
/**
* @param {number} line 0-based
* @param {number=} column
* @param {boolean=} shouldHighlight
*/
revealPosition: function(line, column, shouldHighlight)
{
this._clearLineToScrollTo();
this._clearSelectionToSet();
this._positionToReveal = { line: line, column: column, shouldHighlight: shouldHighlight };
this._innerRevealPositionIfNeeded();
},
_innerRevealPositionIfNeeded: function()
{
if (!this._positionToReveal)
return;
if (!this.loaded || !this.isEditorShowing())
return;
this._textEditor.revealPosition(this._positionToReveal.line, this._positionToReveal.column, this._positionToReveal.shouldHighlight);
delete this._positionToReveal;
},
_clearPositionToReveal: function()
{
this._textEditor.clearPositionHighlight();
delete this._positionToReveal;
},
/**
* @param {number} line
*/
scrollToLine: function(line)
{
this._clearPositionToReveal();
this._lineToScrollTo = line;
this._innerScrollToLineIfNeeded();
},
_innerScrollToLineIfNeeded: function()
{
if (typeof this._lineToScrollTo === "number") {
if (this.loaded && this.isEditorShowing()) {
this._textEditor.scrollToLine(this._lineToScrollTo);
delete this._lineToScrollTo;
}
}
},
_clearLineToScrollTo: function()
{
delete this._lineToScrollTo;
},
/**
* @return {!WebInspector.TextRange}
*/
selection: function()
{
return this.textEditor.selection();
},
/**
* @param {!WebInspector.TextRange} textRange
*/
setSelection: function(textRange)
{
this._selectionToSet = textRange;
this._innerSetSelectionIfNeeded();
},
_innerSetSelectionIfNeeded: function()
{
if (this._selectionToSet && this.loaded && this.isEditorShowing()) {
this._textEditor.setSelection(this._selectionToSet);
delete this._selectionToSet;
}
},
_clearSelectionToSet: function()
{
delete this._selectionToSet;
},
_wasShownOrLoaded: function()
{
this._innerRevealPositionIfNeeded();
this._innerSetSelectionIfNeeded();
this._innerScrollToLineIfNeeded();
},
/**
* @param {!WebInspector.TextRange} oldRange
* @param {!WebInspector.TextRange} newRange
*/
onTextChanged: function(oldRange, newRange)
{
if (this._searchConfig && this._searchableView)
this.performSearch(this._searchConfig, false, false);
},
/**
* @param {string} content
* @param {string} mimeType
* @return {string}
*/
_simplifyMimeType: function(content, mimeType)
{
if (!mimeType)
return "";
if (mimeType.indexOf("javascript") >= 0 ||
mimeType.indexOf("jscript") >= 0 ||
mimeType.indexOf("ecmascript") >= 0)
return "text/javascript";
// A hack around the fact that files with "php" extension might be either standalone or html embedded php scripts.
if (mimeType === "text/x-php" && content.match(/\<\?.*\?\>/g))
return "application/x-httpd-php";
return mimeType;
},
/**
* @param {string} highlighterType
*/
setHighlighterType: function(highlighterType)
{
this._highlighterType = highlighterType;
this._updateHighlighterType("");
},
/**
* @param {string} content
*/
_updateHighlighterType: function(content)
{
this._textEditor.setMimeType(this._simplifyMimeType(content, this._highlighterType));
},
/**
* @param {?string} content
*/
setContent: function(content)
{
if (!this._loaded) {
this._loaded = true;
this._textEditor.setText(content || "");
this._textEditor.markClean();
} else {
var firstLine = this._textEditor.firstVisibleLine();
var selection = this._textEditor.selection();
this._textEditor.setText(content || "");
this._textEditor.scrollToLine(firstLine);
this._textEditor.setSelection(selection);
}
this._updateHighlighterType(content || "");
this._wasShownOrLoaded();
if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
delete this._delayedFindSearchMatches;
}
this.onTextEditorContentLoaded();
},
onTextEditorContentLoaded: function() {},
/**
* @param {?WebInspector.SearchableView} view
*/
setSearchableView: function(view)
{
this._searchableView = view;
},
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean} jumpBackwards
*/
_doFindSearchMatches: function(searchConfig, shouldJump, jumpBackwards)
{
this._currentSearchResultIndex = -1;
this._searchResults = [];
var regex = searchConfig.toSearchRegex();
this._searchRegex = regex;
this._searchResults = this._collectRegexMatches(regex);
if (this._searchableView)
this._searchableView.updateSearchMatchesCount(this._searchResults.length);
if (!this._searchResults.length)
this._textEditor.cancelSearchResultsHighlight();
else if (shouldJump && jumpBackwards)
this.jumpToPreviousSearchResult();
else if (shouldJump)
this.jumpToNextSearchResult();
else
this._textEditor.highlightSearchResults(regex, null);
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
if (this._searchableView)
this._searchableView.updateSearchMatchesCount(0);
this._resetSearch();
this._searchConfig = searchConfig;
if (this.loaded)
this._doFindSearchMatches(searchConfig, shouldJump, !!jumpBackwards)
else
this._delayedFindSearchMatches = this._doFindSearchMatches.bind(this, searchConfig, shouldJump, !!jumpBackwards);
this._ensureContentLoaded();
},
_editorFocused: function()
{
this._resetCurrentSearchResultIndex();
},
_resetCurrentSearchResultIndex: function()
{
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = -1;
if (this._searchableView)
this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
this._textEditor.highlightSearchResults(this._searchRegex, null);
},
_resetSearch: function()
{
delete this._searchConfig;
delete this._delayedFindSearchMatches;
this._currentSearchResultIndex = -1;
this._searchResults = [];
delete this._searchRegex;
},
/**
* @override
*/
searchCanceled: function()
{
var range = this._currentSearchResultIndex !== -1 ? this._searchResults[this._currentSearchResultIndex] : null;
this._resetSearch();
if (!this.loaded)
return;
this._textEditor.cancelSearchResultsHighlight();
if (range)
this.setSelection(range);
},
/**
* @return {boolean}
*/
hasSearchResults: function()
{
return this._searchResults.length > 0;
},
jumpToFirstSearchResult: function()
{
this.jumpToSearchResult(0);
},
jumpToLastSearchResult: function()
{
this.jumpToSearchResult(this._searchResults.length - 1);
},
/**
* @return {number}
*/
_searchResultIndexForCurrentSelection: function()
{
return this._searchResults.lowerBound(this._textEditor.selection().collapseToEnd(), WebInspector.TextRange.comparator);
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
var currentIndex = this._searchResultIndexForCurrentSelection();
var nextIndex = this._currentSearchResultIndex === -1 ? currentIndex : currentIndex + 1;
this.jumpToSearchResult(nextIndex);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
var currentIndex = this._searchResultIndexForCurrentSelection();
this.jumpToSearchResult(currentIndex - 1);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function ()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return true;
},
get currentSearchResultIndex()
{
return this._currentSearchResultIndex;
},
jumpToSearchResult: function(index)
{
if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
if (this._searchableView)
this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
this._textEditor.highlightSearchResults(this._searchRegex, this._searchResults[this._currentSearchResultIndex]);
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceSelectionWith: function(searchConfig, replacement)
{
var range = this._searchResults[this._currentSearchResultIndex];
if (!range)
return;
this._textEditor.highlightSearchResults(this._searchRegex, null);
var oldText = this._textEditor.copyRange(range);
var regex = searchConfig.toSearchRegex();
var text;
if (regex.__fromRegExpQuery)
text = oldText.replace(regex, replacement);
else
text = oldText.replace(regex, function() { return replacement; });
var newRange = this._textEditor.editRange(range, text);
this._textEditor.setSelection(newRange.collapseToEnd());
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceAllWith: function(searchConfig, replacement)
{
this._resetCurrentSearchResultIndex();
var text = this._textEditor.text();
var range = this._textEditor.range();
var regex = searchConfig.toSearchRegex(true);
if (regex.__fromRegExpQuery)
text = text.replace(regex, replacement);
else
text = text.replace(regex, function() { return replacement; });
var ranges = this._collectRegexMatches(regex);
if (!ranges.length)
return;
// Calculate the position of the end of the last range to be edited.
var currentRangeIndex = ranges.lowerBound(this._textEditor.selection(), WebInspector.TextRange.comparator);
var lastRangeIndex = mod(currentRangeIndex - 1, ranges.length);
var lastRange = ranges[lastRangeIndex];
var replacementLineEndings = replacement.computeLineEndings();
var replacementLineCount = replacementLineEndings.length;
var lastLineNumber = lastRange.startLine + replacementLineEndings.length - 1;
var lastColumnNumber = lastRange.startColumn;
if (replacementLineEndings.length > 1)
lastColumnNumber = replacementLineEndings[replacementLineCount - 1] - replacementLineEndings[replacementLineCount - 2] - 1;
this._textEditor.editRange(range, text);
this._textEditor.revealPosition(lastLineNumber, lastColumnNumber);
this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(lastLineNumber, lastColumnNumber));
},
_collectRegexMatches: function(regexObject)
{
var ranges = [];
for (var i = 0; i < this._textEditor.linesCount; ++i) {
var line = this._textEditor.line(i);
var offset = 0;
do {
var match = regexObject.exec(line);
if (match) {
var matchEndIndex = match.index + Math.max(match[0].length, 1);
if (match[0].length)
ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + matchEndIndex));
offset += matchEndIndex;
line = line.substring(matchEndIndex);
}
} while (match && line);
}
return ranges;
},
/**
* @return {!Promise}
*/
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
return Promise.resolve();
},
/**
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
{
return Promise.resolve();
},
/**
* @param {?WebInspector.TextRange} from
* @param {?WebInspector.TextRange} to
*/
onJumpToPosition: function(from, to)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.JumpHappened, {
from: from,
to: to
});
},
/**
* @return {boolean}
*/
canEditSource: function()
{
return false;
},
/**
* @param {!WebInspector.TextRange} textRange
*/
selectionChanged: function(textRange)
{
this._updateSourcePosition();
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
WebInspector.notifications.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
},
_updateSourcePosition: function()
{
var selections = this._textEditor.selections();
if (!selections.length)
return;
if (selections.length > 1) {
this._sourcePosition.setText(WebInspector.UIString("%d selection regions", selections.length));
return;
}
var textRange = selections[0];
if (textRange.isEmpty()) {
this._sourcePosition.setText(WebInspector.UIString("Line %d, Column %d", textRange.endLine + 1, textRange.endColumn + 1));
return;
}
textRange = textRange.normalize();
var selectedText = this._textEditor.copyRange(textRange);
if (textRange.startLine === textRange.endLine)
this._sourcePosition.setText(WebInspector.UIString("%d characters selected", selectedText.length));
else
this._sourcePosition.setText(WebInspector.UIString("%d lines, %d characters selected", textRange.endLine - textRange.startLine + 1, selectedText.length));
},
/**
* @param {number} lineNumber
*/
scrollChanged: function(lineNumber)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
},
_handleKeyDown: function(e)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},
__proto__: WebInspector.VBoxWithToolbarItems.prototype
}
/**
* @implements {WebInspector.TextEditorDelegate}
* @constructor
*/
WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame)
{
this._sourceFrame = sourceFrame;
}
WebInspector.TextEditorDelegateForSourceFrame.prototype = {
/**
* @override
* @param {!WebInspector.TextRange} oldRange
* @param {!WebInspector.TextRange} newRange
*/
onTextChanged: function(oldRange, newRange)
{
this._sourceFrame.onTextChanged(oldRange, newRange);
},
/**
* @override
* @param {!WebInspector.TextRange} textRange
*/
selectionChanged: function(textRange)
{
this._sourceFrame.selectionChanged(textRange);
},
/**
* @override
* @param {number} lineNumber
*/
scrollChanged: function(lineNumber)
{
this._sourceFrame.scrollChanged(lineNumber);
},
/**
* @override
*/
editorFocused: function()
{
this._sourceFrame._editorFocused();
},
/**
* @override
* @param {!WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
* @return {!Promise}
*/
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
return this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
},
/**
* @override
* @param {!WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
{
return this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber);
},
/**
* @override
* @param {?WebInspector.TextRange} from
* @param {?WebInspector.TextRange} to
*/
onJumpToPosition: function(from, to)
{
this._sourceFrame.onJumpToPosition(from, to);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | 2 1 1 | // Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.SuggestBoxDelegate}
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {!CodeMirror} codeMirror
*/
WebInspector.TextEditorAutocompleteController = function(textEditor, codeMirror)
{
this._textEditor = textEditor;
this._codeMirror = codeMirror;
this._onScroll = this._onScroll.bind(this);
this._onCursorActivity = this._onCursorActivity.bind(this);
this._changes = this._changes.bind(this);
this._blur = this._blur.bind(this);
this._codeMirror.on("changes", this._changes);
this._enabled = true;
this._initialized = false;
}
WebInspector.TextEditorAutocompleteController.prototype = {
_initializeIfNeeded: function()
{
if (this._initialized)
return;
this._initialized = true;
this._codeMirror.on("scroll", this._onScroll);
this._codeMirror.on("cursorActivity", this._onCursorActivity);
this._codeMirror.on("blur", this._blur);
this._delegate.initialize(this._textEditor);
},
/**
* @param {!WebInspector.TextEditorAutocompleteDelegate} delegate
*/
setDelegate: function(delegate)
{
if (this._delegate)
this._delegate.dispose();
this._delegate = delegate;
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
if (enabled === this._enabled)
return;
this._enabled = enabled;
if (!this._delegate)
return;
if (!enabled)
this._delegate.dispose();
else
this._delegate.initialize();
},
/**
* @param {!CodeMirror} codeMirror
* @param {!Array.<!CodeMirror.ChangeObject>} changes
*/
_changes: function(codeMirror, changes)
{
if (!changes.length || !this._enabled || !this._delegate)
return;
var singleCharInput = false;
for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
var changeObject = changes[changeIndex];
singleCharInput = (changeObject.origin === "+input" && changeObject.text.length === 1 && changeObject.text[0].length === 1) ||
(this._suggestBox && changeObject.origin === "+delete" && changeObject.removed.length === 1 && changeObject.removed[0].length === 1);
}
if (singleCharInput)
setImmediate(this.autocomplete.bind(this));
},
_blur: function()
{
this.finishAutocomplete();
},
/**
* @param {!WebInspector.TextRange} mainSelection
* @return {boolean}
*/
_validateSelectionsContexts: function(mainSelection)
{
var selections = this._codeMirror.listSelections();
if (selections.length <= 1)
return true;
var mainSelectionContext = this._textEditor.copyRange(mainSelection);
for (var i = 0; i < selections.length; ++i) {
var wordRange = this._delegate.substituteRange(this._textEditor, selections[i].head.line, selections[i].head.ch);
if (!wordRange)
return false;
var context = this._textEditor.copyRange(wordRange);
if (context !== mainSelectionContext)
return false;
}
return true;
},
autocomplete: function()
{
if (!this._enabled || !this._delegate)
return;
this._initializeIfNeeded();
if (this._codeMirror.somethingSelected()) {
this.finishAutocomplete();
return;
}
var cursor = this._codeMirror.getCursor("head");
var substituteRange = this._delegate.substituteRange(this._textEditor, cursor.line, cursor.ch);
if (!substituteRange || !this._validateSelectionsContexts(substituteRange)) {
this.finishAutocomplete();
return;
}
var prefixRange = substituteRange.clone();
prefixRange.endColumn = cursor.ch;
var wordsWithPrefix = this._delegate.wordsWithPrefix(this._textEditor, prefixRange, substituteRange);
if (!wordsWithPrefix.length) {
this.finishAutocomplete();
return;
}
if (!this._suggestBox)
this._suggestBox = new WebInspector.SuggestBox(this, 6);
var oldPrefixRange = this._prefixRange;
this._prefixRange = prefixRange;
if (!oldPrefixRange || prefixRange.startLine !== oldPrefixRange.startLine || prefixRange.startColumn !== oldPrefixRange.startColumn)
this._updateAnchorBox();
this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix.map(item => ({title: item})), 0, true, this._textEditor.copyRange(prefixRange));
if (!this._suggestBox.visible())
this.finishAutocomplete();
this._onSuggestionsShownForTest(wordsWithPrefix);
},
/**
* @param {!Array.<string>} suggestions
*/
_onSuggestionsShownForTest: function(suggestions) { },
finishAutocomplete: function()
{
if (!this._suggestBox)
return;
this._suggestBox.hide();
this._suggestBox = null;
this._prefixRange = null;
this._anchorBox = null;
},
/**
* @param {!Event} e
* @return {boolean}
*/
keyDown: function(e)
{
if (!this._suggestBox)
return false;
if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
this.finishAutocomplete();
return true;
}
if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
this._suggestBox.acceptSuggestion();
this.finishAutocomplete();
return true;
}
return this._suggestBox.keyPressed(e);
},
/**
* @override
* @param {string} suggestion
* @param {boolean=} isIntermediateSuggestion
*/
applySuggestion: function(suggestion, isIntermediateSuggestion)
{
this._currentSuggestion = suggestion;
},
/**
* @override
*/
acceptSuggestion: function()
{
if (this._prefixRange.endColumn - this._prefixRange.startColumn === this._currentSuggestion.length)
return;
var selections = this._codeMirror.listSelections().slice();
var prefixLength = this._prefixRange.endColumn - this._prefixRange.startColumn;
for (var i = selections.length - 1; i >= 0; --i) {
var start = selections[i].head;
var end = new CodeMirror.Pos(start.line, start.ch - prefixLength);
this._codeMirror.replaceRange(this._currentSuggestion, start, end, "+autocomplete");
}
},
_onScroll: function()
{
if (!this._suggestBox)
return;
var cursor = this._codeMirror.getCursor();
var scrollInfo = this._codeMirror.getScrollInfo();
var topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, "local");
var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
if (cursor.line < topmostLineNumber || cursor.line > bottomLine)
this.finishAutocomplete();
else {
this._updateAnchorBox();
this._suggestBox.setPosition(this._anchorBox);
}
},
_onCursorActivity: function()
{
if (!this._suggestBox)
return;
var cursor = this._codeMirror.getCursor();
if (cursor.line !== this._prefixRange.startLine || cursor.ch > this._prefixRange.endColumn || cursor.ch <= this._prefixRange.startColumn)
this.finishAutocomplete();
},
_updateAnchorBox: function()
{
var line = this._prefixRange.startLine;
var column = this._prefixRange.startColumn;
var metrics = this._textEditor.cursorPositionToCoordinates(line, column);
this._anchorBox = metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
},
}
/**
* @interface
*/
WebInspector.TextEditorAutocompleteDelegate = function() {}
WebInspector.TextEditorAutocompleteDelegate.prototype = {
/**
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.TextRange}
*/
substituteRange: function(editor, lineNumber, columnNumber) {},
/**
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {!WebInspector.TextRange} prefixRange
* @param {!WebInspector.TextRange} substituteRange
* @return {!Array.<string>}
*/
wordsWithPrefix: function(editor, prefixRange, substituteRange) {},
/**
* @param {!WebInspector.CodeMirrorTextEditor} editor
*/
initialize: function(editor) {},
dispose: function() {}
}
/**
* @constructor
* @implements {WebInspector.TextEditorAutocompleteDelegate}
* @param {string=} additionalWordChars
*/
WebInspector.SimpleAutocompleteDelegate = function(additionalWordChars)
{
this._additionalWordChars = additionalWordChars;
}
WebInspector.SimpleAutocompleteDelegate.prototype = {
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
*/
initialize: function(editor)
{
if (this._dictionary)
this._dictionary.dispose();
this._dictionary = editor.createTextDictionary(this._additionalWordChars);
},
/**
* @override
*/
dispose: function()
{
if (this._dictionary) {
this._dictionary.dispose();
delete this._dictionary;
}
},
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.TextRange}
*/
substituteRange: function(editor, lineNumber, columnNumber)
{
return editor.wordRangeForCursorPosition(lineNumber, columnNumber, this._dictionary.isWordChar.bind(this._dictionary));
},
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {!WebInspector.TextRange} prefixRange
* @param {!WebInspector.TextRange} substituteRange
* @return {!Array.<string>}
*/
wordsWithPrefix: function(editor, prefixRange, substituteRange)
{
if (prefixRange.startColumn === prefixRange.endColumn)
return [];
var dictionary = this._dictionary;
var completions = dictionary.wordsWithPrefix(editor.copyRange(prefixRange));
var substituteWord = editor.copyRange(substituteRange);
if (dictionary.wordCount(substituteWord) === 1)
completions = completions.filter(excludeFilter.bind(null, substituteWord));
completions.sort(sortSuggestions);
return completions;
function sortSuggestions(a, b)
{
return dictionary.wordCount(b) - dictionary.wordCount(a) || a.length - b.length;
}
function excludeFilter(excludeWord, word)
{
return word !== excludeWord;
}
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AddSourceMapURLDialog.js | 7.41% | (2 / 27) | 0% | (0 / 2) | 0% | (0 / 5) | 7.41% | (2 / 27) | |
| AdvancedSearchView.js | 1.16% | (2 / 172) | 0% | (0 / 67) | 0% | (0 / 38) | 1.16% | (2 / 172) | |
| CSSSourceFrame.js | 1.39% | (1 / 72) | 0% | (0 / 36) | 0% | (0 / 10) | 1.39% | (1 / 72) | |
| CallStackSidebarPane.js | 0.45% | (1 / 224) | 0% | (0 / 109) | 0% | (0 / 25) | 0.45% | (1 / 224) | |
| EditingLocationHistoryManager.js | 3.39% | (2 / 59) | 0% | (0 / 26) | 0% | (0 / 16) | 3.39% | (2 / 59) | |
| EventListenerBreakpointsSidebarPane.js | 0.61% | (1 / 163) | 0% | (0 / 64) | 0% | (0 / 18) | 0.61% | (1 / 163) | |
| FileBasedSearchResultsPane.js | 1% | (1 / 100) | 0% | (0 / 14) | 0% | (0 / 14) | 1% | (1 / 100) | |
| FilePathScoreFunction.js | 1.3% | (1 / 77) | 0% | (0 / 64) | 0% | (0 / 7) | 1.3% | (1 / 77) | |
| FilteredUISourceCodeListDelegate.js | 1.27% | (1 / 79) | 0% | (0 / 38) | 0% | (0 / 14) | 1.27% | (1 / 79) | |
| InplaceFormatterEditorAction.js | 7.32% | (3 / 41) | 0% | (0 / 20) | 0% | (0 / 9) | 7.32% | (3 / 41) | |
| JavaScriptBreakpointsSidebarPane.js | 2.68% | (3 / 112) | 0% | (0 / 38) | 0% | (0 / 19) | 2.68% | (3 / 112) | |
| JavaScriptCompiler.js | 5.26% | (2 / 38) | 0% | (0 / 14) | 0% | (0 / 6) | 5.26% | (2 / 38) | |
| JavaScriptOutlineDialog.js | 2.86% | (1 / 35) | 0% | (0 / 14) | 0% | (0 / 9) | 2.86% | (1 / 35) | |
| JavaScriptSourceFrame.js | 1.76% | (10 / 568) | 0% | (0 / 326) | 0% | (0 / 66) | 1.76% | (10 / 567) | |
| NavigatorView.js | 2.36% | (14 / 592) | 0% | (0 / 244) | 0% | (0 / 117) | 2.36% | (14 / 592) | |
| ObjectEventListenersSidebarPane.js | 8.33% | (3 / 36) | 0% | (0 / 6) | 0% | (0 / 8) | 8.33% | (3 / 36) | |
| OpenResourceDialog.js | 3.85% | (1 / 26) | 0% | (0 / 4) | 0% | (0 / 9) | 3.85% | (1 / 26) | |
| RevisionHistoryView.js | 3.76% | (5 / 133) | 0% | (0 / 30) | 0% | (0 / 20) | 3.79% | (5 / 132) | |
| ScopeChainSidebarPane.js | 1.54% | (1 / 65) | 0% | (0 / 31) | 0% | (0 / 2) | 1.54% | (1 / 65) | |
| ScriptFormatter.js | 1.85% | (1 / 54) | 0% | (0 / 22) | 0% | (0 / 17) | 1.85% | (1 / 54) | |
| ScriptFormatterEditorAction.js | 2.42% | (4 / 165) | 0% | (0 / 54) | 0% | (0 / 25) | 2.44% | (4 / 164) | |
| SimpleHistoryManager.js | 1.85% | (1 / 54) | 0% | (0 / 24) | 0% | (0 / 13) | 1.85% | (1 / 54) | |
| SourceCodeDiff.js | 3.42% | (5 / 146) | 0% | (0 / 63) | 0% | (0 / 16) | 3.47% | (5 / 144) | |
| SourceMapNamesResolver.js | 4.79% | (9 / 188) | 0% | (0 / 62) | 0% | (0 / 42) | 4.84% | (9 / 186) | |
| SourcesNavigator.js | 2.33% | (2 / 86) | 0% | (0 / 24) | 0% | (0 / 22) | 2.35% | (2 / 85) | |
| SourcesPanel.js | 1.72% | (10 / 582) | 0% | (0 / 218) | 0% | (0 / 101) | 1.72% | (10 / 582) | |
| SourcesSearchScope.js | 6.61% | (8 / 121) | 0% | (0 / 49) | 0% | (0 / 17) | 6.61% | (8 / 121) | |
| SourcesView.js | 1.63% | (5 / 307) | 0% | (0 / 134) | 0% | (0 / 59) | 1.63% | (5 / 307) | |
| StyleSheetOutlineDialog.js | 4.17% | (1 / 24) | 0% | (0 / 8) | 0% | (0 / 8) | 4.17% | (1 / 24) | |
| TabbedEditorContainer.js | 0.75% | (2 / 265) | 0% | (0 / 93) | 0% | (0 / 57) | 0.75% | (2 / 265) | |
| ThreadsSidebarPane.js | 1.82% | (1 / 55) | 0% | (0 / 18) | 0% | (0 / 9) | 1.82% | (1 / 55) | |
| UIList.js | 1.54% | (1 / 65) | 0% | (0 / 20) | 0% | (0 / 21) | 1.54% | (1 / 65) | |
| UISourceCodeFrame.js | 0.79% | (2 / 252) | 0% | (0 / 77) | 0% | (0 / 47) | 0.8% | (2 / 250) | |
| WatchExpressionsSidebarPane.js | 1.14% | (2 / 176) | 0% | (0 / 64) | 0% | (0 / 31) | 1.14% | (2 / 176) | |
| WorkspaceMappingTip.js | 1.22% | (1 / 82) | 0% | (0 / 40) | 0% | (0 / 8) | 1.22% | (1 / 82) | |
| XHRBreakpointsSidebarPane.js | 4.63% | (5 / 108) | 0% | (0 / 34) | 0% | (0 / 19) | 4.63% | (5 / 108) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.HBox}
* @param {function(string)} callback
*/
WebInspector.AddSourceMapURLDialog = function(callback)
{
WebInspector.HBox.call(this, true);
this.registerRequiredCSS("sources/addSourceMapURLDialog.css");
this.contentElement.createChild("label").textContent = WebInspector.UIString("Source map URL: ");
this._input = this.contentElement.createChild("input");
this._input.setAttribute("type", "text");
this._input.addEventListener("keydown", this._onKeyDown.bind(this), false);
var addButton = this.contentElement.createChild("button");
addButton.textContent = WebInspector.UIString("Add");
addButton.addEventListener("click", this._apply.bind(this), false);
this.setDefaultFocusedElement(this._input);
this._callback = callback;
this.contentElement.tabIndex = 0;
}
/**
* @param {function(string)} callback
*/
WebInspector.AddSourceMapURLDialog.show = function(callback)
{
var dialog = new WebInspector.Dialog();
var addSourceMapURLDialog = new WebInspector.AddSourceMapURLDialog(done);
addSourceMapURLDialog.show(dialog.element);
dialog.setWrapsContent(true);
dialog.show();
/**
* @param {string} value
*/
function done(value)
{
dialog.detach();
callback(value);
}
}
WebInspector.AddSourceMapURLDialog.prototype = {
_apply: function()
{
this._callback(this._input.value);
},
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code) {
event.preventDefault();
this._apply();
}
},
__proto__: WebInspector.HBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.AdvancedSearchView = function()
{
WebInspector.VBox.call(this, true);
this.setMinimumSize(0, 40);
this.registerRequiredCSS("sources/sourcesSearch.css");
this._searchId = 0;
this.contentElement.classList.add("search-view");
this._searchPanelElement = this.contentElement.createChild("div", "search-drawer-header");
this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._searchResultsElement = this.contentElement.createChild("div");
this._searchResultsElement.className = "search-results";
this._search = WebInspector.HistoryInput.create();
this._searchPanelElement.appendChild(this._search);
this._search.placeholder = WebInspector.UIString("Enter query, use `file:` to filter by path");
this._search.setAttribute("type", "text");
this._search.classList.add("search-config-search");
this._search.setAttribute("results", "0");
this._search.setAttribute("size", 42);
this._ignoreCaseLabel = createCheckboxLabel(WebInspector.UIString("Ignore case"));
this._ignoreCaseLabel.classList.add("search-config-label");
this._searchPanelElement.appendChild(this._ignoreCaseLabel);
this._ignoreCaseCheckbox = this._ignoreCaseLabel.checkboxElement;
this._ignoreCaseCheckbox.classList.add("search-config-checkbox");
this._regexLabel = createCheckboxLabel(WebInspector.UIString("Regular expression"));
this._regexLabel.classList.add("search-config-label");
this._searchPanelElement.appendChild(this._regexLabel);
this._regexCheckbox = this._regexLabel.checkboxElement;
this._regexCheckbox.classList.add("search-config-checkbox");
this._searchToolbarElement = this.contentElement.createChild("div", "search-toolbar-summary");
this._searchMessageElement = this._searchToolbarElement.createChild("div", "search-message");
this._searchProgressPlaceholderElement = this._searchToolbarElement.createChild("div", "flex-centered");
this._searchResultsMessageElement = this._searchToolbarElement.createChild("div", "search-message");
this._advancedSearchConfig = WebInspector.settings.createLocalSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false).toPlainObject());
this._load();
/** @type {!WebInspector.SearchScope} */
this._searchScope = new WebInspector.SourcesSearchScope();
}
WebInspector.AdvancedSearchView.prototype = {
/**
* @return {!WebInspector.SearchConfig}
*/
_buildSearchConfig: function()
{
return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
},
/**
* @param {string} queryCandidate
*/
_toggle: function(queryCandidate)
{
if (queryCandidate)
this._search.value = queryCandidate;
this.focus();
this._startIndexing();
},
_onIndexingFinished: function()
{
var finished = !this._progressIndicator.isCanceled();
this._progressIndicator.done();
delete this._progressIndicator;
delete this._isIndexing;
this._indexingFinished(finished);
if (!finished)
delete this._pendingSearchConfig;
if (!this._pendingSearchConfig)
return;
var searchConfig = this._pendingSearchConfig;
delete this._pendingSearchConfig;
this._innerStartSearch(searchConfig);
},
_startIndexing: function()
{
this._isIndexing = true;
if (this._progressIndicator)
this._progressIndicator.done();
this._progressIndicator = new WebInspector.ProgressIndicator();
this._searchMessageElement.textContent = WebInspector.UIString("Indexing\u2026");
this._progressIndicator.show(this._searchProgressPlaceholderElement);
this._searchScope.performIndexing(new WebInspector.ProgressProxy(this._progressIndicator, this._onIndexingFinished.bind(this)));
},
/**
* @param {number} searchId
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
_onSearchResult: function(searchId, searchResult)
{
if (searchId !== this._searchId || !this._progressIndicator)
return;
if (this._progressIndicator && this._progressIndicator.isCanceled()) {
this._onIndexingFinished();
return;
}
this._addSearchResult(searchResult);
if (!searchResult.searchMatches.length)
return;
if (!this._searchResultsPane)
this._searchResultsPane = this._searchScope.createSearchResultsPane(this._searchConfig);
this._resetResults();
this._searchResultsElement.appendChild(this._searchResultsPane.element);
this._searchResultsPane.addSearchResult(searchResult);
},
/**
* @param {number} searchId
* @param {boolean} finished
*/
_onSearchFinished: function(searchId, finished)
{
if (searchId !== this._searchId || !this._progressIndicator)
return;
if (!this._searchResultsPane)
this._nothingFound();
this._searchFinished(finished);
delete this._searchConfig;
},
/**
* @param {!WebInspector.SearchConfig} searchConfig
*/
_startSearch: function(searchConfig)
{
this._resetSearch();
++this._searchId;
if (!this._isIndexing)
this._startIndexing();
this._pendingSearchConfig = searchConfig;
},
/**
* @param {!WebInspector.SearchConfig} searchConfig
*/
_innerStartSearch: function(searchConfig)
{
this._searchConfig = searchConfig;
if (this._progressIndicator)
this._progressIndicator.done();
this._progressIndicator = new WebInspector.ProgressIndicator();
this._searchStarted(this._progressIndicator);
this._searchScope.performSearch(searchConfig, this._progressIndicator, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
},
_resetSearch: function()
{
this._stopSearch();
if (this._searchResultsPane) {
this._resetResults();
delete this._searchResultsPane;
}
},
_stopSearch: function()
{
if (this._progressIndicator && !this._isIndexing)
this._progressIndicator.cancel();
if (this._searchScope)
this._searchScope.stopSearch();
delete this._searchConfig;
},
/**
* @param {!WebInspector.ProgressIndicator} progressIndicator
*/
_searchStarted: function(progressIndicator)
{
this._resetResults();
this._resetCounters();
this._searchMessageElement.textContent = WebInspector.UIString("Searching\u2026");
progressIndicator.show(this._searchProgressPlaceholderElement);
this._updateSearchResultsMessage();
if (!this._searchingView)
this._searchingView = new WebInspector.EmptyWidget(WebInspector.UIString("Searching\u2026"));
this._searchingView.show(this._searchResultsElement);
},
/**
* @param {boolean} finished
*/
_indexingFinished: function(finished)
{
this._searchMessageElement.textContent = finished ? "" : WebInspector.UIString("Indexing interrupted.");
},
_updateSearchResultsMessage: function()
{
if (this._searchMatchesCount && this._searchResultsCount)
this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
else
this._searchResultsMessageElement.textContent = "";
},
_resetResults: function()
{
if (this._searchingView)
this._searchingView.detach();
if (this._notFoundView)
this._notFoundView.detach();
this._searchResultsElement.removeChildren();
},
_resetCounters: function()
{
this._searchMatchesCount = 0;
this._searchResultsCount = 0;
this._nonEmptySearchResultsCount = 0;
},
_nothingFound: function()
{
this._resetResults();
if (!this._notFoundView)
this._notFoundView = new WebInspector.EmptyWidget(WebInspector.UIString("No matches found."));
this._notFoundView.show(this._searchResultsElement);
this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
},
/**
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
_addSearchResult: function(searchResult)
{
this._searchMatchesCount += searchResult.searchMatches.length;
this._searchResultsCount++;
if (searchResult.searchMatches.length)
this._nonEmptySearchResultsCount++;
this._updateSearchResultsMessage();
},
/**
* @param {boolean} finished
*/
_searchFinished: function(finished)
{
this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
},
focus: function()
{
WebInspector.setCurrentFocusElement(this._search);
this._search.select();
},
willHide: function()
{
this._stopSearch();
},
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
switch (event.keyCode) {
case WebInspector.KeyboardShortcut.Keys.Enter.code:
this._onAction();
break;
}
},
_save: function()
{
this._advancedSearchConfig.set(this._buildSearchConfig().toPlainObject());
},
_load: function()
{
var searchConfig = WebInspector.SearchConfig.fromPlainObject(this._advancedSearchConfig.get());
this._search.value = searchConfig.query();
this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase();
this._regexCheckbox.checked = searchConfig.isRegex();
},
_onAction: function()
{
var searchConfig = this._buildSearchConfig();
if (!searchConfig.query() || !searchConfig.query().length)
return;
this._save();
this._startSearch(searchConfig);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {!WebInspector.ProjectSearchConfig} searchConfig
*/
WebInspector.SearchResultsPane = function(searchConfig)
{
this._searchConfig = searchConfig;
this.element = createElement("div");
}
WebInspector.SearchResultsPane.prototype = {
/**
* @return {!WebInspector.ProjectSearchConfig}
*/
get searchConfig()
{
return this._searchConfig;
},
/**
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
addSearchResult: function(searchResult) { }
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.AdvancedSearchView.ActionDelegate = function()
{
}
WebInspector.AdvancedSearchView.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
this._showSearch();
return true;
},
/**
* @return {!Promise.<!WebInspector.AdvancedSearchView>}
*/
_showSearch: function()
{
/**
* @param {?WebInspector.Widget} view
* @return {!WebInspector.AdvancedSearchView}
*/
function updateSearchBox(view)
{
console.assert(view && view instanceof WebInspector.AdvancedSearchView);
var searchView = /** @type {!WebInspector.AdvancedSearchView} */(view);
if (searchView._search !== searchView.element.window().document.activeElement) {
WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());
searchView._toggle(queryCandidate);
searchView.focus();
}
return searchView;
}
var selection = WebInspector.inspectorView.element.getDeepSelection();
var queryCandidate = "";
if (selection.rangeCount)
queryCandidate = selection.toString().replace(/\r?\n.*/, "");
return WebInspector.inspectorView.showViewInDrawer("sources.search").then(updateSearchBox);
}
}
/**
* @constructor
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!Array.<!Object>} searchMatches
*/
WebInspector.FileBasedSearchResult = function(uiSourceCode, searchMatches) {
this.uiSourceCode = uiSourceCode;
this.searchMatches = searchMatches;
}
/**
* @interface
*/
WebInspector.SearchScope = function()
{
}
WebInspector.SearchScope.prototype = {
/**
* @param {!WebInspector.SearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!WebInspector.FileBasedSearchResult)} searchResultCallback
* @param {function(boolean)} searchFinishedCallback
*/
performSearch: function(searchConfig, progress, searchResultCallback, searchFinishedCallback) { },
/**
* @param {!WebInspector.Progress} progress
*/
performIndexing: function(progress) { },
stopSearch: function() { },
/**
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @return {!WebInspector.SearchResultsPane}
*/
createSearchResultsPane: function(searchConfig) { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.UISourceCodeFrame}
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
WebInspector.CSSSourceFrame = function(uiSourceCode)
{
WebInspector.UISourceCodeFrame.call(this, uiSourceCode);
this.textEditor.setAutocompleteDelegate(new WebInspector.CSSSourceFrame.AutocompleteDelegate());
this._registerShortcuts();
}
WebInspector.CSSSourceFrame.prototype = {
_registerShortcuts: function()
{
var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts;
for (var i = 0; i < shortcutKeys.IncreaseCSSUnitByOne.length; ++i)
this.addShortcut(shortcutKeys.IncreaseCSSUnitByOne[i].key, this._handleUnitModification.bind(this, 1));
for (var i = 0; i < shortcutKeys.DecreaseCSSUnitByOne.length; ++i)
this.addShortcut(shortcutKeys.DecreaseCSSUnitByOne[i].key, this._handleUnitModification.bind(this, -1));
for (var i = 0; i < shortcutKeys.IncreaseCSSUnitByTen.length; ++i)
this.addShortcut(shortcutKeys.IncreaseCSSUnitByTen[i].key, this._handleUnitModification.bind(this, 10));
for (var i = 0; i < shortcutKeys.DecreaseCSSUnitByTen.length; ++i)
this.addShortcut(shortcutKeys.DecreaseCSSUnitByTen[i].key, this._handleUnitModification.bind(this, -10));
},
/**
* @param {string} unit
* @param {number} change
* @return {?string}
*/
_modifyUnit: function(unit, change)
{
var unitValue = parseInt(unit, 10);
if (isNaN(unitValue))
return null;
var tail = unit.substring((unitValue).toString().length);
return String.sprintf("%d%s", unitValue + change, tail);
},
/**
* @param {number} change
* @return {boolean}
*/
_handleUnitModification: function(change)
{
var selection = this.textEditor.selection().normalize();
var token = this.textEditor.tokenAtTextPosition(selection.startLine, selection.startColumn);
if (!token) {
if (selection.startColumn > 0)
token = this.textEditor.tokenAtTextPosition(selection.startLine, selection.startColumn - 1);
if (!token)
return false;
}
if (token.type !== "css-number")
return false;
var cssUnitRange = new WebInspector.TextRange(selection.startLine, token.startColumn, selection.startLine, token.endColumn);
var cssUnitText = this.textEditor.copyRange(cssUnitRange);
var newUnitText = this._modifyUnit(cssUnitText, change);
if (!newUnitText)
return false;
this.textEditor.editRange(cssUnitRange, newUnitText);
selection.startColumn = token.startColumn;
selection.endColumn = selection.startColumn + newUnitText.length;
this.textEditor.setSelection(selection);
return true;
},
__proto__: WebInspector.UISourceCodeFrame.prototype
}
/**
* @constructor
* @implements {WebInspector.TextEditorAutocompleteDelegate}
*/
WebInspector.CSSSourceFrame.AutocompleteDelegate = function()
{
this._simpleDelegate = new WebInspector.SimpleAutocompleteDelegate(".-$");
}
WebInspector.CSSSourceFrame._backtrackDepth = 10;
WebInspector.CSSSourceFrame.AutocompleteDelegate.prototype = {
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
*/
initialize: function(editor)
{
this._simpleDelegate.initialize(editor);
},
/**
* @override
*/
dispose: function()
{
this._simpleDelegate.dispose();
},
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.TextRange}
*/
substituteRange: function(editor, lineNumber, columnNumber)
{
return this._simpleDelegate.substituteRange(editor, lineNumber, columnNumber);
},
/**
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?{startColumn: number, endColumn: number, type: string}}
*/
_backtrackPropertyToken: function(editor, lineNumber, columnNumber)
{
var tokenPosition = columnNumber;
var line = editor.line(lineNumber);
var seenColumn = false;
for (var i = 0; i < WebInspector.CSSSourceFrame._backtrackDepth && tokenPosition >= 0; ++i) {
var token = editor.tokenAtTextPosition(lineNumber, tokenPosition);
if (!token)
return null;
if (token.type === "css-property")
return seenColumn ? token : null;
if (token.type && !(token.type.indexOf("whitespace") !== -1 || token.type.startsWith("css-comment")))
return null;
if (!token.type && line.substring(token.startColumn, token.endColumn) === ":") {
if (!seenColumn)
seenColumn = true;
else
return null;
}
tokenPosition = token.startColumn - 1;
}
return null;
},
/**
* @override
* @param {!WebInspector.CodeMirrorTextEditor} editor
* @param {!WebInspector.TextRange} prefixRange
* @param {!WebInspector.TextRange} substituteRange
* @return {!Array.<string>}
*/
wordsWithPrefix: function(editor, prefixRange, substituteRange)
{
var prefix = editor.copyRange(prefixRange);
if (prefix.startsWith("$"))
return this._simpleDelegate.wordsWithPrefix(editor, prefixRange, substituteRange);
var propertyToken = this._backtrackPropertyToken(editor, prefixRange.startLine, prefixRange.startColumn - 1);
if (!propertyToken)
return this._simpleDelegate.wordsWithPrefix(editor, prefixRange, substituteRange);
var line = editor.line(prefixRange.startLine);
var tokenContent = line.substring(propertyToken.startColumn, propertyToken.endColumn);
var keywords = WebInspector.CSSMetadata.keywordsForProperty(tokenContent);
return keywords.startsWith(prefix);
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SidebarPane}
*/
WebInspector.CallStackSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
this.element.addEventListener("keydown", this._keyDown.bind(this), true);
this.element.tabIndex = 0;
this.callFrameList = new WebInspector.UIList();
this.callFrameList.show(this.element);
this._linkifier = new WebInspector.Linkifier();
WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this._asyncStackTracesStateChanged, this);
WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._blackboxingStateChanged, this);
/** @type {!Array<!WebInspector.CallStackSidebarPane.CallFrame>} */
this.callFrames = [];
this._locationPool = new WebInspector.LiveLocationPool();
}
/** @enum {string} */
WebInspector.CallStackSidebarPane.Events = {
CallFrameSelected: "CallFrameSelected",
}
WebInspector.CallStackSidebarPane.prototype = {
/**
* @param {?WebInspector.DebuggerPausedDetails} details
*/
update: function(details)
{
this.callFrameList.detach();
this.callFrameList.clear();
this._linkifier.reset();
this.element.removeChildren();
this._locationPool.disposeAll();
if (!details) {
var infoElement = this.element.createChild("div", "callstack-info");
infoElement.textContent = WebInspector.UIString("Not Paused");
return;
}
this.callFrameList.show(this.element);
this._debuggerModel = details.debuggerModel;
var asyncStackTrace = details.asyncStackTrace;
delete this._statusMessageElement;
delete this._hiddenCallFramesMessageElement;
this.callFrames = [];
this._hiddenCallFrames = 0;
this._appendSidebarCallFrames(this._callFramesFromDebugger(details.callFrames));
var topStackHidden = (this._hiddenCallFrames === this.callFrames.length);
while (asyncStackTrace) {
var title = WebInspector.asyncStackTraceLabel(asyncStackTrace.description);
var asyncCallFrame = new WebInspector.UIList.Item(title, "", true);
asyncCallFrame.setHoverable(false);
asyncCallFrame.element.addEventListener("contextmenu", this._asyncCallFrameContextMenu.bind(this, this.callFrames.length), true);
this._appendSidebarCallFrames(this._callFramesFromRuntime(asyncStackTrace.callFrames, asyncCallFrame), asyncCallFrame);
asyncStackTrace = asyncStackTrace.parent;
}
if (topStackHidden)
this._revealHiddenCallFrames();
if (this._hiddenCallFrames) {
var element = createElementWithClass("div", "hidden-callframes-message");
if (this._hiddenCallFrames === 1)
element.textContent = WebInspector.UIString("1 stack frame is hidden (black-boxed).");
else
element.textContent = WebInspector.UIString("%d stack frames are hidden (black-boxed).", this._hiddenCallFrames);
element.createTextChild(" ");
var showAllLink = element.createChild("span", "link");
showAllLink.textContent = WebInspector.UIString("Show");
showAllLink.addEventListener("click", this._revealHiddenCallFrames.bind(this), false);
this.element.insertBefore(element, this.element.firstChild);
this._hiddenCallFramesMessageElement = element;
}
},
/**
* @param {!Array.<!WebInspector.DebuggerModel.CallFrame>} callFrames
* @return {!Array<!WebInspector.CallStackSidebarPane.CallFrame>}
*/
_callFramesFromDebugger: function(callFrames)
{
var callFrameItems = [];
for (var i = 0, n = callFrames.length; i < n; ++i) {
var callFrame = callFrames[i];
var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, callFrame.location(), this._linkifier, callFrame, this._locationPool);
callFrameItem.element.addEventListener("click", this._callFrameSelected.bind(this, callFrameItem), false);
callFrameItems.push(callFrameItem);
}
return callFrameItems;
},
/**
* @param {!Array.<!RuntimeAgent.CallFrame>} callFrames
* @param {!WebInspector.UIList.Item} asyncCallFrameItem
* @return {!Array<!WebInspector.CallStackSidebarPane.CallFrame>}
*/
_callFramesFromRuntime: function(callFrames, asyncCallFrameItem)
{
var callFrameItems = [];
for (var i = 0, n = callFrames.length; i < n; ++i) {
var callFrame = callFrames[i];
// TODO(591496): conform location in debugger and runtime
var lineNumber = callFrame.lineNumber ? callFrame.lineNumber - 1 : 0;
var columnNumber = callFrame.columnNumber ? callFrame.columnNumber - 1 : 0;
var location = new WebInspector.DebuggerModel.Location(this._debuggerModel, callFrame.scriptId, lineNumber, columnNumber);
var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, location, this._linkifier, null, this._locationPool, asyncCallFrameItem);
callFrameItem.element.addEventListener("click", this._asyncCallFrameClicked.bind(this, callFrameItem), false);
callFrameItems.push(callFrameItem);
}
return callFrameItems;
},
/**
* @param {!Array.<!WebInspector.CallStackSidebarPane.CallFrame>} callFrames
* @param {!WebInspector.UIList.Item=} asyncCallFrameItem
*/
_appendSidebarCallFrames: function(callFrames, asyncCallFrameItem)
{
if (asyncCallFrameItem)
this.callFrameList.addItem(asyncCallFrameItem);
var allCallFramesHidden = true;
for (var i = 0, n = callFrames.length; i < n; ++i) {
var callFrameItem = callFrames[i];
callFrameItem.element.addEventListener("contextmenu", this._callFrameContextMenu.bind(this, callFrameItem), true);
this.callFrames.push(callFrameItem);
if (WebInspector.blackboxManager.isBlackboxedRawLocation(callFrameItem._location)) {
callFrameItem.setHidden(true);
callFrameItem.setDimmed(true);
++this._hiddenCallFrames;
} else {
this.callFrameList.addItem(callFrameItem);
allCallFramesHidden = false;
}
}
if (allCallFramesHidden && asyncCallFrameItem) {
asyncCallFrameItem.setHidden(true);
asyncCallFrameItem.element.remove();
}
},
_revealHiddenCallFrames: function()
{
if (!this._hiddenCallFrames)
return;
this._hiddenCallFrames = 0;
this.callFrameList.clear();
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
if (callFrame._asyncCallFrame) {
callFrame._asyncCallFrame.setHidden(false);
if (i && callFrame._asyncCallFrame !== this.callFrames[i - 1]._asyncCallFrame)
this.callFrameList.addItem(callFrame._asyncCallFrame);
}
callFrame.setHidden(false);
this.callFrameList.addItem(callFrame);
}
if (this._hiddenCallFramesMessageElement) {
this._hiddenCallFramesMessageElement.remove();
delete this._hiddenCallFramesMessageElement;
}
},
/**
* @param {!WebInspector.CallStackSidebarPane.CallFrame} callFrame
* @param {!Event} event
*/
_callFrameContextMenu: function(callFrame, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
var debuggerCallFrame = callFrame._debuggerCallFrame;
if (debuggerCallFrame)
contextMenu.appendItem(WebInspector.UIString.capitalize("Restart ^frame"), debuggerCallFrame.restart.bind(debuggerCallFrame));
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^stack ^trace"), this._copyStackTrace.bind(this));
var uiLocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrame._location);
this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode);
contextMenu.show();
},
/**
* @param {number} index
* @param {!Event} event
*/
_asyncCallFrameContextMenu: function(index, event)
{
for (; index < this.callFrames.length; ++index) {
var callFrame = this.callFrames[index];
if (!callFrame.isHidden()) {
this._callFrameContextMenu(callFrame, event);
break;
}
}
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
appendBlackboxURLContextMenuItems: function(contextMenu, uiSourceCode)
{
var canBlackbox = WebInspector.blackboxManager.canBlackboxUISourceCode(uiSourceCode);
var isBlackboxed = WebInspector.blackboxManager.isBlackboxedUISourceCode(uiSourceCode);
var isContentScript = uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts;
var manager = WebInspector.blackboxManager;
if (canBlackbox) {
if (isBlackboxed)
contextMenu.appendItem(WebInspector.UIString.capitalize("Stop ^blackboxing"), manager.unblackboxUISourceCode.bind(manager, uiSourceCode));
else
contextMenu.appendItem(WebInspector.UIString.capitalize("Blackbox ^script"), manager.blackboxUISourceCode.bind(manager, uiSourceCode));
}
if (isContentScript) {
if (isBlackboxed)
contextMenu.appendItem(WebInspector.UIString.capitalize("Stop blackboxing ^all ^content ^scripts"), manager.blackboxContentScripts.bind(manager));
else
contextMenu.appendItem(WebInspector.UIString.capitalize("Blackbox ^all ^content ^scripts"), manager.unblackboxContentScripts.bind(manager));
}
},
_blackboxingStateChanged: function()
{
if (!this._debuggerModel)
return;
var details = this._debuggerModel.debuggerPausedDetails();
if (!details)
return;
this.update(details);
var selectedCallFrame = this._debuggerModel.selectedCallFrame();
if (selectedCallFrame)
this.setSelectedCallFrame(selectedCallFrame);
},
_asyncStackTracesStateChanged: function()
{
var enabled = WebInspector.moduleSetting("enableAsyncStackTraces").get();
if (!enabled && this.callFrames)
this._removeAsyncCallFrames();
},
_removeAsyncCallFrames: function()
{
var shouldSelectTopFrame = false;
var lastSyncCallFrameIndex = -1;
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
if (callFrame._asyncCallFrame) {
if (callFrame.isSelected())
shouldSelectTopFrame = true;
callFrame._asyncCallFrame.element.remove();
callFrame.element.remove();
} else {
lastSyncCallFrameIndex = i;
}
}
this.callFrames.length = lastSyncCallFrameIndex + 1;
if (shouldSelectTopFrame)
this._selectNextVisibleCallFrame(0);
},
/**
* @param {!WebInspector.DebuggerModel.CallFrame} x
*/
setSelectedCallFrame: function(x)
{
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
callFrame.setSelected(callFrame._debuggerCallFrame === x);
if (callFrame.isSelected() && callFrame.isHidden())
this._revealHiddenCallFrames();
}
},
/**
* @return {boolean}
*/
_selectNextCallFrameOnStack: function()
{
var index = this._selectedCallFrameIndex();
if (index === -1)
return false;
return this._selectNextVisibleCallFrame(index + 1);
},
/**
* @return {boolean}
*/
_selectPreviousCallFrameOnStack: function()
{
var index = this._selectedCallFrameIndex();
if (index === -1)
return false;
return this._selectNextVisibleCallFrame(index - 1, true);
},
/**
* @param {number} index
* @param {boolean=} backward
* @return {boolean}
*/
_selectNextVisibleCallFrame: function(index, backward)
{
while (0 <= index && index < this.callFrames.length) {
var callFrame = this.callFrames[index];
if (!callFrame.isHidden() && !callFrame.isLabel() && !callFrame._asyncCallFrame) {
this._callFrameSelected(callFrame);
return true;
}
index += backward ? -1 : 1;
}
return false;
},
/**
* @return {number}
*/
_selectedCallFrameIndex: function()
{
if (!this._debuggerModel)
return -1;
var selectedCallFrame = this._debuggerModel.selectedCallFrame();
if (!selectedCallFrame)
return -1;
for (var i = 0; i < this.callFrames.length; ++i) {
if (this.callFrames[i]._debuggerCallFrame === selectedCallFrame)
return i;
}
return -1;
},
/**
* @param {!WebInspector.CallStackSidebarPane.CallFrame} callFrameItem
*/
_asyncCallFrameClicked: function(callFrameItem)
{
var uiLocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrameItem._location);
WebInspector.Revealer.reveal(uiLocation);
},
/**
* @param {!WebInspector.CallStackSidebarPane.CallFrame} callFrameItem
*/
_callFrameSelected: function(callFrameItem)
{
callFrameItem.element.scrollIntoViewIfNeeded();
var callFrame = callFrameItem._debuggerCallFrame;
if (callFrame)
this.dispatchEventToListeners(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, callFrame);
},
_copyStackTrace: function()
{
var text = "";
var lastCallFrame = null;
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
if (callFrame.isHidden())
continue;
if (lastCallFrame && callFrame._asyncCallFrame !== lastCallFrame._asyncCallFrame)
text += callFrame._asyncCallFrame.title() + "\n";
text += callFrame.title() + " (" + callFrame.subtitle() + ")\n";
lastCallFrame = callFrame;
}
InspectorFrontendHost.copyText(text);
},
/**
* @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(!Event=):boolean)} registerShortcutDelegate
*/
registerShortcuts: function(registerShortcutDelegate)
{
registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNextCallFrameOnStack.bind(this));
registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPreviousCallFrameOnStack.bind(this));
},
/**
* @param {!Element|string} status
*/
setStatus: function(status)
{
if (!this._statusMessageElement)
this._statusMessageElement = this.element.createChild("div", "callstack-info status");
if (typeof status === "string") {
this._statusMessageElement.textContent = status;
} else {
this._statusMessageElement.removeChildren();
this._statusMessageElement.appendChild(status);
}
},
_keyDown: function(event)
{
if (event.altKey || event.shiftKey || event.metaKey || event.ctrlKey)
return;
if (event.keyIdentifier === "Up" && this._selectPreviousCallFrameOnStack() || event.keyIdentifier === "Down" && this._selectNextCallFrameOnStack())
event.consume(true);
},
__proto__: WebInspector.SidebarPane.prototype
}
/**
* @constructor
* @extends {WebInspector.UIList.Item}
* @param {string} functionName
* @param {!WebInspector.DebuggerModel.Location} location
* @param {!WebInspector.Linkifier} linkifier
* @param {?WebInspector.DebuggerModel.CallFrame} debuggerCallFrame
* @param {!WebInspector.LiveLocationPool} locationPool
* @param {!WebInspector.UIList.Item=} asyncCallFrame
*/
WebInspector.CallStackSidebarPane.CallFrame = function(functionName, location, linkifier, debuggerCallFrame, locationPool, asyncCallFrame)
{
WebInspector.UIList.Item.call(this, WebInspector.beautifyFunctionName(functionName), "");
this._location = location;
this._debuggerCallFrame = debuggerCallFrame;
this._asyncCallFrame = asyncCallFrame;
if (asyncCallFrame) {
var locationElement = linkifier.linkifyRawLocation(location, location.script().sourceURL);
this.subtitleElement.appendChild(locationElement);
} else {
this._liveLocationPool = new WebInspector.LiveLocationPool();
WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, this._update.bind(this), locationPool);
}
}
WebInspector.CallStackSidebarPane.CallFrame.prototype = {
/**
* @param {!WebInspector.LiveLocation} liveLocation
*/
_update: function(liveLocation)
{
var uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
var text = uiLocation.linkText();
this.setSubtitle(text.trimMiddle(30));
this.subtitleElement.title = text;
},
__proto__: WebInspector.UIList.Item.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 2 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.SourcesView} sourcesView
* @param {function():?WebInspector.SourceFrame} currentSourceFrameCallback
*/
WebInspector.EditingLocationHistoryManager = function(sourcesView, currentSourceFrameCallback)
{
this._sourcesView = sourcesView;
this._historyManager = new WebInspector.SimpleHistoryManager(WebInspector.EditingLocationHistoryManager.HistoryDepth);
this._currentSourceFrameCallback = currentSourceFrameCallback;
}
WebInspector.EditingLocationHistoryManager.HistoryDepth = 20;
WebInspector.EditingLocationHistoryManager.prototype = {
/**
* @param {!WebInspector.UISourceCodeFrame} sourceFrame
*/
trackSourceFrameCursorJumps: function(sourceFrame)
{
sourceFrame.addEventListener(WebInspector.SourceFrame.Events.JumpHappened, this._onJumpHappened.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_onJumpHappened: function(event)
{
if (event.data.from)
this._updateActiveState(event.data.from);
if (event.data.to)
this._pushActiveState(event.data.to);
},
rollback: function()
{
this._historyManager.rollback();
},
rollover: function()
{
this._historyManager.rollover();
},
updateCurrentState: function()
{
var sourceFrame = this._currentSourceFrameCallback();
if (!sourceFrame)
return;
this._updateActiveState(sourceFrame.textEditor.selection());
},
pushNewState: function()
{
var sourceFrame = this._currentSourceFrameCallback();
if (!sourceFrame)
return;
this._pushActiveState(sourceFrame.textEditor.selection());
},
/**
* @param {!WebInspector.TextRange} selection
*/
_updateActiveState: function(selection)
{
var active = this._historyManager.active();
if (!active)
return;
var sourceFrame = this._currentSourceFrameCallback();
if (!sourceFrame)
return;
var entry = new WebInspector.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
active.merge(entry);
},
/**
* @param {!WebInspector.TextRange} selection
*/
_pushActiveState: function(selection)
{
var sourceFrame = this._currentSourceFrameCallback();
if (!sourceFrame)
return;
var entry = new WebInspector.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
this._historyManager.push(entry);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
removeHistoryForSourceCode: function(uiSourceCode)
{
function filterOut(entry)
{
return entry._projectId === uiSourceCode.project().id() && entry._url === uiSourceCode.url();
}
this._historyManager.filterOut(filterOut);
},
}
/**
* @constructor
* @implements {WebInspector.HistoryEntry}
* @param {!WebInspector.SourcesView} sourcesView
* @param {!WebInspector.EditingLocationHistoryManager} editingLocationManager
* @param {!WebInspector.SourceFrame} sourceFrame
* @param {!WebInspector.TextRange} selection
*/
WebInspector.EditingLocationHistoryEntry = function(sourcesView, editingLocationManager, sourceFrame, selection)
{
this._sourcesView = sourcesView;
this._editingLocationManager = editingLocationManager;
var uiSourceCode = sourceFrame.uiSourceCode();
this._projectId = uiSourceCode.project().id();
this._url = uiSourceCode.url();
var position = this._positionFromSelection(selection);
this._positionHandle = sourceFrame.textEditor.textEditorPositionHandle(position.lineNumber, position.columnNumber);
}
WebInspector.EditingLocationHistoryEntry.prototype = {
/**
* @param {!WebInspector.HistoryEntry} entry
*/
merge: function(entry)
{
if (this._projectId !== entry._projectId || this._url !== entry._url)
return;
this._positionHandle = entry._positionHandle;
},
/**
* @param {!WebInspector.TextRange} selection
* @return {!{lineNumber: number, columnNumber: number}}
*/
_positionFromSelection: function(selection)
{
return {
lineNumber: selection.endLine,
columnNumber: selection.endColumn
};
},
/**
* @override
* @return {boolean}
*/
valid: function()
{
var position = this._positionHandle.resolve();
var uiSourceCode = WebInspector.workspace.uiSourceCode(this._projectId, this._url);
return !!(position && uiSourceCode);
},
/**
* @override
*/
reveal: function()
{
var position = this._positionHandle.resolve();
var uiSourceCode = WebInspector.workspace.uiSourceCode(this._projectId, this._url);
if (!position || !uiSourceCode)
return;
this._editingLocationManager.updateCurrentState();
this._sourcesView.showSourceLocation(uiSourceCode, position.lineNumber, position.columnNumber);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.EventListenerBreakpointsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));
this.registerRequiredCSS("components/breakpointsList.css");
this._eventListenerBreakpointsSetting = WebInspector.settings.createLocalSetting("eventListenerBreakpoints", []);
this._categoriesTreeOutline = new TreeOutline();
this._categoriesTreeOutline.element.tabIndex = 0;
this._categoriesTreeOutline.element.classList.add("event-listener-breakpoints");
this.element.appendChild(this._categoriesTreeOutline.element);
this._categoryItems = [];
// FIXME: uncomment following once inspector stops being drop targer in major ports.
// Otherwise, inspector page reacts on drop event and tries to load the event data.
// this._createCategory(WebInspector.UIString("Drag"), ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]);
this._createCategory(WebInspector.UIString("Animation"), ["requestAnimationFrame", "cancelAnimationFrame", "animationFrameFired"], true);
this._createCategory(WebInspector.UIString("Clipboard"), ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
this._createCategory(WebInspector.UIString("Control"), ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
this._createCategory(WebInspector.UIString("Device"), ["deviceorientation", "devicemotion"]);
this._createCategory(WebInspector.UIString("DOM Mutation"), ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
this._createCategory(WebInspector.UIString("Drag / drop"), ["dragenter", "dragover", "dragleave", "drop"]);
this._createCategory(WebInspector.UIString("Keyboard"), ["keydown", "keyup", "keypress", "input"]);
this._createCategory(WebInspector.UIString("Load"), ["load", "beforeunload", "unload", "abort", "error", "hashchange", "popstate"]);
this._createCategory(WebInspector.UIString("Media"), ["play", "pause", "playing", "canplay", "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "ratechange", "durationchange", "volumechange", "loadstart", "progress", "suspend", "abort", "error", "emptied", "stalled", "loadedmetadata", "loadeddata", "waiting"], false, ["audio", "video"]);
this._createCategory(WebInspector.UIString("Mouse"), ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mouseenter", "mouseleave", "mousewheel", "wheel", "contextmenu"]);
this._createCategory(WebInspector.UIString("Parse"), ["setInnerHTML"], true);
this._createCategory(WebInspector.UIString("Pointer"), ["pointerover", "pointerout", "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "pointercancel", "gotpointercapture", "lostpointercapture"], true);
this._createCategory(WebInspector.UIString("Script"), ["scriptFirstStatement"], true);
this._createCategory(WebInspector.UIString("Timer"), ["setTimer", "clearTimer", "timerFired"], true);
this._createCategory(WebInspector.UIString("Touch"), ["touchstart", "touchmove", "touchend", "touchcancel"]);
this._createCategory(WebInspector.UIString("WebGL"), ["webglErrorFired", "webglWarningFired"], true);
this._createCategory(WebInspector.UIString("Window"), ["close"], true);
this._createCategory(WebInspector.UIString("XHR"), ["readystatechange", "load", "loadstart", "loadend", "abort", "error", "progress", "timeout"], false, ["XMLHttpRequest", "XMLHttpRequestUpload"]);
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.EventListenerBreakpointsSidebarPane.categoryListener = "listener:";
WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation = "instrumentation:";
WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny = "*";
/**
* @param {string} eventName
* @param {!Object=} auxData
* @return {string}
*/
WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(eventName, auxData)
{
if (!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI) {
WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI = {
"instrumentation:setTimer": WebInspector.UIString("Set Timer"),
"instrumentation:clearTimer": WebInspector.UIString("Clear Timer"),
"instrumentation:timerFired": WebInspector.UIString("Timer Fired"),
"instrumentation:scriptFirstStatement": WebInspector.UIString("Script First Statement"),
"instrumentation:requestAnimationFrame": WebInspector.UIString("Request Animation Frame"),
"instrumentation:cancelAnimationFrame": WebInspector.UIString("Cancel Animation Frame"),
"instrumentation:animationFrameFired": WebInspector.UIString("Animation Frame Fired"),
"instrumentation:webglErrorFired": WebInspector.UIString("WebGL Error Fired"),
"instrumentation:webglWarningFired": WebInspector.UIString("WebGL Warning Fired"),
"instrumentation:setInnerHTML": WebInspector.UIString("Set innerHTML"),
};
}
if (auxData) {
if (eventName === "instrumentation:webglErrorFired" && auxData["webglErrorName"]) {
var errorName = auxData["webglErrorName"];
// If there is a hex code of the error, display only this.
errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, "$1");
return WebInspector.UIString("WebGL Error Fired (%s)", errorName);
}
}
return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1);
}
WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._restoreBreakpoints(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target) { },
/**
* @param {string} name
* @param {!Array.<string>} eventNames
* @param {boolean=} isInstrumentationEvent
* @param {!Array.<string>=} targetNames
*/
_createCategory: function(name, eventNames, isInstrumentationEvent, targetNames)
{
var labelNode = createCheckboxLabel(name);
var categoryItem = {};
categoryItem.element = new TreeElement(labelNode);
this._categoriesTreeOutline.appendChild(categoryItem.element);
categoryItem.element.listItemElement.classList.add("event-category");
categoryItem.element.selectable = true;
categoryItem.checkbox = labelNode.checkboxElement;
categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true);
categoryItem.targetNames = this._stringArrayToLowerCase(targetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny]);
categoryItem.children = {};
var category = (isInstrumentationEvent ? WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation : WebInspector.EventListenerBreakpointsSidebarPane.categoryListener);
for (var i = 0; i < eventNames.length; ++i) {
var eventName = category + eventNames[i];
var breakpointItem = {};
var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
labelNode = createCheckboxLabel(title);
labelNode.classList.add("source-code");
breakpointItem.element = new TreeElement(labelNode);
categoryItem.element.appendChild(breakpointItem.element);
breakpointItem.element.listItemElement.createChild("div", "breakpoint-hit-marker");
breakpointItem.element.selectable = false;
breakpointItem.checkbox = labelNode.checkboxElement;
breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, eventName, categoryItem.targetNames), true);
breakpointItem.parent = categoryItem;
categoryItem.children[eventName] = breakpointItem;
}
this._categoryItems.push(categoryItem);
},
/**
* @param {!Array.<string>} array
* @return {!Array.<string>}
*/
_stringArrayToLowerCase: function(array)
{
return array.map(function(value) {
return value.toLowerCase();
});
},
_categoryCheckboxClicked: function(categoryItem)
{
var checked = categoryItem.checkbox.checked;
for (var eventName in categoryItem.children) {
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem.checkbox.checked === checked)
continue;
if (checked)
this._setBreakpoint(eventName, categoryItem.targetNames);
else
this._removeBreakpoint(eventName, categoryItem.targetNames);
}
this._saveBreakpoints();
},
/**
* @param {string} eventName
* @param {!Array.<string>} targetNames
* @param {!Event} event
*/
_breakpointCheckboxClicked: function(eventName, targetNames, event)
{
if (event.target.checked)
this._setBreakpoint(eventName, targetNames);
else
this._removeBreakpoint(eventName, targetNames);
this._saveBreakpoints();
},
/**
* @param {string} eventName
* @param {?Array.<string>=} eventTargetNames
* @param {!WebInspector.Target=} target
*/
_setBreakpoint: function(eventName, eventTargetNames, target)
{
eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];
for (var i = 0; i < eventTargetNames.length; ++i) {
var eventTargetName = eventTargetNames[i];
var breakpointItem = this._findBreakpointItem(eventName, eventTargetName);
if (!breakpointItem)
continue;
breakpointItem.checkbox.checked = true;
breakpointItem.parent.dirtyCheckbox = true;
this._updateBreakpointOnTarget(eventName, eventTargetName, true, target);
}
this._updateCategoryCheckboxes();
},
/**
* @param {string} eventName
* @param {?Array.<string>=} eventTargetNames
* @param {!WebInspector.Target=} target
*/
_removeBreakpoint: function(eventName, eventTargetNames, target)
{
eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];
for (var i = 0; i < eventTargetNames.length; ++i) {
var eventTargetName = eventTargetNames[i];
var breakpointItem = this._findBreakpointItem(eventName, eventTargetName);
if (!breakpointItem)
continue;
breakpointItem.checkbox.checked = false;
breakpointItem.parent.dirtyCheckbox = true;
this._updateBreakpointOnTarget(eventName, eventTargetName, false, target);
}
this._updateCategoryCheckboxes();
},
/**
* @param {string} eventName
* @param {string} eventTargetName
* @param {boolean} enable
* @param {!WebInspector.Target=} target
*/
_updateBreakpointOnTarget: function(eventName, eventTargetName, enable, target)
{
var targets = target ? [target] : WebInspector.targetManager.targets(WebInspector.Target.Type.Page);
for (var i = 0; i < targets.length; ++i) {
if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener)) {
var protocolEventName = eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener.length);
if (enable)
targets[i].domdebuggerAgent().setEventListenerBreakpoint(protocolEventName, eventTargetName);
else
targets[i].domdebuggerAgent().removeEventListenerBreakpoint(protocolEventName, eventTargetName);
} else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation)) {
var protocolEventName = eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation.length);
if (enable)
targets[i].domdebuggerAgent().setInstrumentationBreakpoint(protocolEventName);
else
targets[i].domdebuggerAgent().removeInstrumentationBreakpoint(protocolEventName);
}
}
},
_updateCategoryCheckboxes: function()
{
for (var i = 0; i < this._categoryItems.length; ++i) {
var categoryItem = this._categoryItems[i];
if (!categoryItem.dirtyCheckbox)
continue;
categoryItem.dirtyCheckbox = false;
var hasEnabled = false;
var hasDisabled = false;
for (var eventName in categoryItem.children) {
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem.checkbox.checked)
hasEnabled = true;
else
hasDisabled = true;
}
categoryItem.checkbox.checked = hasEnabled;
categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
}
},
/**
* @param {string} eventName
* @param {string=} targetName
* @return {?Object}
*/
_findBreakpointItem: function(eventName, targetName)
{
targetName = (targetName || WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny).toLowerCase();
for (var i = 0; i < this._categoryItems.length; ++i) {
var categoryItem = this._categoryItems[i];
if (categoryItem.targetNames.indexOf(targetName) === -1)
continue;
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem)
return breakpointItem;
}
return null;
},
/**
* @param {string} eventName
* @param {string=} targetName
*/
highlightBreakpoint: function(eventName, targetName)
{
var breakpointItem = this._findBreakpointItem(eventName, targetName);
if (!breakpointItem || !breakpointItem.checkbox.checked)
breakpointItem = this._findBreakpointItem(eventName, WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny);
if (!breakpointItem)
return;
this.expand();
breakpointItem.parent.element.expand();
breakpointItem.element.listItemElement.classList.add("breakpoint-hit");
this._highlightedElement = breakpointItem.element.listItemElement;
},
clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.classList.remove("breakpoint-hit");
delete this._highlightedElement;
}
},
_saveBreakpoints: function()
{
var breakpoints = [];
for (var i = 0; i < this._categoryItems.length; ++i) {
var categoryItem = this._categoryItems[i];
for (var eventName in categoryItem.children) {
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem.checkbox.checked)
breakpoints.push({ eventName: eventName, targetNames: categoryItem.targetNames });
}
}
this._eventListenerBreakpointsSetting.set(breakpoints);
},
/**
* @param {!WebInspector.Target} target
*/
_restoreBreakpoints: function(target)
{
var breakpoints = this._eventListenerBreakpointsSetting.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint && typeof breakpoint.eventName === "string")
this._setBreakpoint(breakpoint.eventName, breakpoint.targetNames, target);
}
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SearchResultsPane}
* @param {!WebInspector.ProjectSearchConfig} searchConfig
*/
WebInspector.FileBasedSearchResultsPane = function(searchConfig)
{
WebInspector.SearchResultsPane.call(this, searchConfig);
this._searchResults = [];
this.element.id = "search-results-pane-file-based";
this._treeOutline = new TreeOutline();
this._treeOutline.element.classList.add("search-results-outline-disclosure");
this.element.appendChild(this._treeOutline.element);
this._matchesExpandedCount = 0;
}
WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;
WebInspector.FileBasedSearchResultsPane.prototype = {
/**
* @override
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
addSearchResult: function(searchResult)
{
this._searchResults.push(searchResult);
var uiSourceCode = searchResult.uiSourceCode;
if (!uiSourceCode)
return;
this._addFileTreeElement(searchResult);
},
/**
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
_addFileTreeElement: function(searchResult)
{
var fileTreeElement = new WebInspector.FileBasedSearchResultsPane.FileTreeElement(this._searchConfig, searchResult);
this._treeOutline.appendChild(fileTreeElement);
// Expand until at least a certain number of matches is expanded.
if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
fileTreeElement.expand();
this._matchesExpandedCount += searchResult.searchMatches.length;
},
__proto__: WebInspector.SearchResultsPane.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.FileBasedSearchResult} searchResult
*/
WebInspector.FileBasedSearchResultsPane.FileTreeElement = function(searchConfig, searchResult)
{
TreeElement.call(this, "", true);
this._searchConfig = searchConfig;
this._searchResult = searchResult;
this.toggleOnClick = true;
this.selectable = false;
}
WebInspector.FileBasedSearchResultsPane.FileTreeElement.prototype = {
onexpand: function()
{
if (this._initialized)
return;
this._updateMatchesUI();
this._initialized = true;
},
_updateMatchesUI: function()
{
this.removeChildren();
var toIndex = Math.min(this._searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
if (toIndex < this._searchResult.searchMatches.length) {
this._appendSearchMatches(0, toIndex - 1);
this._appendShowMoreMatchesElement(toIndex - 1);
} else {
this._appendSearchMatches(0, toIndex);
}
},
onattach: function()
{
this._updateSearchMatches();
},
_updateSearchMatches: function()
{
this.listItemElement.classList.add("search-result");
var fileNameSpan = createElement("span");
fileNameSpan.className = "search-result-file-name";
fileNameSpan.textContent = this._searchResult.uiSourceCode.fullDisplayName();
this.listItemElement.appendChild(fileNameSpan);
var matchesCountSpan = createElement("span");
matchesCountSpan.className = "search-result-matches-count";
var searchMatchesCount = this._searchResult.searchMatches.length;
if (searchMatchesCount === 1)
matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
else
matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
this.listItemElement.appendChild(matchesCountSpan);
if (this.expanded)
this._updateMatchesUI();
},
/**
* @param {number} fromIndex
* @param {number} toIndex
*/
_appendSearchMatches: function(fromIndex, toIndex)
{
var searchResult = this._searchResult;
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;
var queries = this._searchConfig.queries();
var regexes = [];
for (var i = 0; i < queries.length; ++i)
regexes.push(createSearchRegex(queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex()));
for (var i = fromIndex; i < toIndex; ++i) {
var lineNumber = searchMatches[i].lineNumber;
var lineContent = searchMatches[i].lineContent;
var matchRanges = [];
for (var j = 0; j < regexes.length; ++j)
matchRanges = matchRanges.concat(this._regexMatchRanges(lineContent, regexes[j]));
var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);
var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
var lineNumberSpan = createElement("span");
lineNumberSpan.classList.add("search-match-line-number");
lineNumberSpan.textContent = numberString;
anchor.appendChild(lineNumberSpan);
var contentSpan = this._createContentSpan(lineContent, matchRanges);
anchor.appendChild(contentSpan);
var searchMatchElement = new TreeElement();
searchMatchElement.selectable = false;
this.appendChild(searchMatchElement);
searchMatchElement.listItemElement.className = "search-match source-code";
searchMatchElement.listItemElement.appendChild(anchor);
}
},
/**
* @param {number} startMatchIndex
*/
_appendShowMoreMatchesElement: function(startMatchIndex)
{
var matchesLeftCount = this._searchResult.searchMatches.length - startMatchIndex;
var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
this._showMoreMatchesTreeElement = new TreeElement(showMoreMatchesText);
this.appendChild(this._showMoreMatchesTreeElement);
this._showMoreMatchesTreeElement.listItemElement.classList.add("show-more-matches");
this._showMoreMatchesTreeElement.onselect = this._showMoreMatchesElementSelected.bind(this, startMatchIndex);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Element}
*/
_createAnchor: function(uiSourceCode, lineNumber, columnNumber)
{
return WebInspector.Linkifier.linkifyUsingRevealer(uiSourceCode.uiLocation(lineNumber, columnNumber), "");
},
/**
* @param {string} lineContent
* @param {!Array.<!WebInspector.SourceRange>} matchRanges
*/
_createContentSpan: function(lineContent, matchRanges)
{
var contentSpan = createElement("span");
contentSpan.className = "search-match-content";
contentSpan.textContent = lineContent;
WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
return contentSpan;
},
/**
* @param {string} lineContent
* @param {!RegExp} regex
* @return {!Array.<!WebInspector.SourceRange>}
*/
_regexMatchRanges: function(lineContent, regex)
{
regex.lastIndex = 0;
var match;
var matchRanges = [];
while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
return matchRanges;
},
/**
* @param {number} startMatchIndex
* @return {boolean}
*/
_showMoreMatchesElementSelected: function(startMatchIndex)
{
this.removeChild(this._showMoreMatchesTreeElement);
this._appendSearchMatches(startMatchIndex, this._searchResult.searchMatches.length);
return false;
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} query
*/
WebInspector.FilePathScoreFunction = function(query)
{
this._query = query;
this._queryUpperCase = query.toUpperCase();
this._score = null;
this._sequence = null;
this._dataUpperCase = "";
this._fileNameIndex = 0;
}
WebInspector.FilePathScoreFunction.prototype = {
/**
* @param {string} data
* @param {?Array<number>} matchIndexes
* @return {number}
*/
score: function(data, matchIndexes)
{
if (!data || !this._query)
return 0;
var n = this._query.length;
var m = data.length;
if (!this._score || this._score.length < n * m) {
this._score = new Int32Array(n * m * 2);
this._sequence = new Int32Array(n * m * 2);
}
var score = this._score;
var sequence = /** @type {!Int32Array} */ (this._sequence);
this._dataUpperCase = data.toUpperCase();
this._fileNameIndex = data.lastIndexOf("/");
for (var i = 0; i < n; ++i) {
for (var j = 0; j < m; ++j) {
var skipCharScore = j === 0 ? 0 : score[i * m + j - 1];
var prevCharScore = i === 0 || j === 0 ? 0 : score[(i - 1) * m + j - 1];
var consecutiveMatch = i === 0 || j === 0 ? 0 : sequence[(i - 1) * m + j - 1];
var pickCharScore = this._match(this._query, data, i, j, consecutiveMatch);
if (pickCharScore && prevCharScore + pickCharScore >= skipCharScore) {
sequence[i * m + j] = consecutiveMatch + 1;
score[i * m + j] = (prevCharScore + pickCharScore);
} else {
sequence[i * m + j] = 0;
score[i * m + j] = skipCharScore;
}
}
}
if (matchIndexes)
this._restoreMatchIndexes(sequence, n, m, matchIndexes);
return score[n * m - 1];
},
/**
* @param {string} data
* @param {number} j
* @return {boolean}
*/
_testWordStart: function(data, j)
{
var prevChar = data.charAt(j - 1);
return j === 0 || prevChar === "_" || prevChar === "-" || prevChar === "/" ||
(data[j - 1] !== this._dataUpperCase[j - 1] && data[j] === this._dataUpperCase[j]);
},
/**
* @param {!Int32Array} sequence
* @param {number} n
* @param {number} m
* @param {!Array<number>} out
*/
_restoreMatchIndexes: function(sequence, n, m, out)
{
var i = n - 1, j = m - 1;
while (i >= 0 && j >= 0) {
switch (sequence[i * m + j]) {
case 0:
--j;
break;
default:
out.push(j);
--i;
--j;
break;
}
}
out.reverse();
},
/**
* @param {string} query
* @param {string} data
* @param {number} i
* @param {number} j
* @return {number}
*/
_singleCharScore: function(query, data, i, j)
{
var isWordStart = this._testWordStart(data, j);
var isFileName = j > this._fileNameIndex;
var isPathTokenStart = j === 0 || data[j - 1] === "/";
var isCapsMatch = query[i] === data[j] && query[i] == this._queryUpperCase[i];
var score = 10;
if (isPathTokenStart)
score += 4;
if (isWordStart)
score += 2;
if (isCapsMatch)
score += 6;
if (isFileName)
score += 4;
// promote the case of making the whole match in the filename
if (j === this._fileNameIndex + 1 && i === 0)
score += 5;
if (isFileName && isWordStart)
score += 3;
return score;
},
/**
* @param {string} query
* @param {string} data
* @param {number} i
* @param {number} j
* @param {number} sequenceLength
* @return {number}
*/
_sequenceCharScore: function(query, data, i, j, sequenceLength)
{
var isFileName = j > this._fileNameIndex;
var isPathTokenStart = j === 0 || data[j - 1] === "/";
var score = 10;
if (isFileName)
score += 4;
if (isPathTokenStart)
score += 5;
score += sequenceLength * 4;
return score;
},
/**
* @param {string} query
* @param {string} data
* @param {number} i
* @param {number} j
* @param {number} consecutiveMatch
* @return {number}
*/
_match: function(query, data, i, j, consecutiveMatch)
{
if (this._queryUpperCase[i] !== this._dataUpperCase[j])
return 0;
if (!consecutiveMatch)
return this._singleCharScore(query, data, i, j);
else
return this._sequenceCharScore(query, data, i, j - consecutiveMatch, consecutiveMatch);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | 2 | /*
* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.FilteredListWidget.Delegate}
* @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
* @param {!Array<string>=} history
*/
WebInspector.FilteredUISourceCodeListDelegate = function(defaultScores, history)
{
WebInspector.FilteredListWidget.Delegate.call(this, history || []);
this._populate();
this._defaultScores = defaultScores;
this._scorer = new WebInspector.FilePathScoreFunction("");
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
}
WebInspector.FilteredUISourceCodeListDelegate.prototype = {
_projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
this._populate(project);
this.refresh();
},
/**
* @param {!WebInspector.Project=} skipProject
*/
_populate: function(skipProject)
{
/** @type {!Array.<!WebInspector.UISourceCode>} */
this._uiSourceCodes = [];
var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
for (var i = 0; i < projects.length; ++i) {
if (skipProject && projects[i] === skipProject)
continue;
this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
}
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
* @param {number=} columnNumber
*/
uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
// Overridden by subclasses
},
/**
* @param {!WebInspector.Project} project
* @return {boolean}
*/
filterProject: function(project)
{
return true;
// Overridden by subclasses
},
/**
* @override
* @return {number}
*/
itemCount: function()
{
return this._uiSourceCodes.length;
},
/**
* @override
* @param {number} itemIndex
* @return {string}
*/
itemKeyAt: function(itemIndex)
{
return this._uiSourceCodes[itemIndex].url();
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @return {number}
*/
itemScoreAt: function(itemIndex, query)
{
var uiSourceCode = this._uiSourceCodes[itemIndex];
var score = this._defaultScores ? (this._defaultScores.get(uiSourceCode) || 0) : 0;
if (!query || query.length < 2)
return score;
if (this._query !== query) {
this._query = query;
this._scorer = new WebInspector.FilePathScoreFunction(query);
}
var url = uiSourceCode.url();
return score + 10 * this._scorer.score(url, null);
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @param {!Element} titleElement
* @param {!Element} subtitleElement
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
query = this.rewriteQuery(query);
var uiSourceCode = this._uiSourceCodes[itemIndex];
var fullDisplayName = uiSourceCode.fullDisplayName();
var indexes = [];
var score = new WebInspector.FilePathScoreFunction(query).score(fullDisplayName, indexes);
var fileNameIndex = fullDisplayName.lastIndexOf("/");
titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || "");
this._renderSubtitleElement(subtitleElement, fullDisplayName);
subtitleElement.title = fullDisplayName;
var ranges = [];
for (var i = 0; i < indexes.length; ++i)
ranges.push({offset: indexes[i], length: 1});
if (indexes[0] > fileNameIndex) {
for (var i = 0; i < ranges.length; ++i)
ranges[i].offset -= fileNameIndex + 1;
WebInspector.highlightRangesWithStyleClass(titleElement, ranges, "highlight");
} else {
WebInspector.highlightRangesWithStyleClass(subtitleElement, ranges, "highlight");
}
},
/**
* @param {!Element} element
* @param {string} text
*/
_renderSubtitleElement: function(element, text)
{
element.removeChildren();
var splitPosition = text.lastIndexOf("/");
if (text.length > 55)
splitPosition = text.length - 55;
var first = element.createChild("div", "first-part");
first.textContent = text.substring(0, splitPosition);
var second = element.createChild("div", "second-part");
second.textContent = text.substring(splitPosition);
element.title = text;
},
/**
* @override
* @param {?number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
var parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
if (!parsedExpression)
return;
var lineNumber;
var columnNumber;
if (parsedExpression[2])
lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
if (parsedExpression[3])
columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
var uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
},
/**
* @override
* @param {string} query
* @return {string}
*/
rewriteQuery: function(query)
{
if (!query)
return query;
query = query.trim();
var lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : "";
return lineNumberMatch ? lineNumberMatch[1] : query;
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (!this.filterProject(uiSourceCode.project()))
return;
this._uiSourceCodes.push(uiSourceCode);
this.refresh();
},
dispose: function()
{
WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
},
__proto__: WebInspector.FilteredListWidget.Delegate.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 2 1 1 |
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.SourcesView.EditorAction}
*/
WebInspector.InplaceFormatterEditorAction = function()
{
}
WebInspector.InplaceFormatterEditorAction.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._updateButton(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_editorClosed: function(event)
{
var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
if (wasSelected)
this._updateButton(null);
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
*/
_updateButton: function(uiSourceCode)
{
this._button.element.classList.toggle("hidden", !this._isFormattable(uiSourceCode));
},
/**
* @override
* @param {!WebInspector.SourcesView} sourcesView
* @return {!WebInspector.ToolbarButton}
*/
button: function(sourcesView)
{
if (this._button)
return this._button;
this._sourcesView = sourcesView;
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
this._button = new WebInspector.ToolbarButton(WebInspector.UIString("Format"), "format-toolbar-item");
this._button.addEventListener("click", this._formatSourceInPlace, this);
this._updateButton(sourcesView.currentUISourceCode());
return this._button;
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
_isFormattable: function(uiSourceCode)
{
if (!uiSourceCode)
return false;
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
return true;
return uiSourceCode.contentType().isStyleSheet()
|| uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
},
_formatSourceInPlace: function()
{
var uiSourceCode = this._sourcesView.currentUISourceCode();
if (!this._isFormattable(uiSourceCode))
return;
if (uiSourceCode.isDirty())
contentLoaded.call(this, uiSourceCode.workingCopy());
else
uiSourceCode.requestContent().then(contentLoaded.bind(this));
/**
* @this {WebInspector.InplaceFormatterEditorAction}
* @param {?string} content
*/
function contentLoaded(content)
{
var highlighterType = WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode);
WebInspector.Formatter.format(uiSourceCode.contentType(), highlighterType, content || "", innerCallback.bind(this));
}
/**
* @this {WebInspector.InplaceFormatterEditorAction}
* @param {string} formattedContent
* @param {!WebInspector.FormatterSourceMapping} formatterMapping
*/
function innerCallback(formattedContent, formatterMapping)
{
if (uiSourceCode.workingCopy() === formattedContent)
return;
var sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
var start = [0, 0];
if (sourceFrame) {
var selection = sourceFrame.selection();
start = formatterMapping.originalToFormatted(selection.startLine, selection.startColumn);
}
uiSourceCode.setWorkingCopy(formattedContent);
this._sourcesView.showSourceLocation(uiSourceCode, start[0], start[1]);
}
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | 2 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {!WebInspector.BreakpointManager} breakpointManager
* @param {function(!WebInspector.UISourceCode, number=, number=, boolean=)} showSourceLineDelegate
*/
WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, showSourceLineDelegate)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
this.registerRequiredCSS("components/breakpointsList.css");
this._breakpointManager = breakpointManager;
this._showSourceLineDelegate = showSourceLineDelegate;
this.listElement = createElementWithClass("ol", "breakpoint-list");
this.emptyElement = this.element.createChild("div", "info");
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
this._items = new Map();
var breakpointLocations = this._breakpointManager.allBreakpointLocations();
for (var i = 0; i < breakpointLocations.length; ++i)
this._addBreakpoint(breakpointLocations[i].breakpoint, breakpointLocations[i].uiLocation);
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true);
}
WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
_emptyElementContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
this._appendBreakpointActiveItem(contextMenu);
contextMenu.show();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendBreakpointActiveItem: function(contextMenu)
{
var breakpointActive = this._breakpointManager.breakpointsActive();
var breakpointActiveTitle = breakpointActive ?
WebInspector.UIString.capitalize("Deactivate ^breakpoints") :
WebInspector.UIString.capitalize("Activate ^breakpoints");
contextMenu.appendItem(breakpointActiveTitle, this._breakpointManager.setBreakpointsActive.bind(this._breakpointManager, !breakpointActive));
},
/**
* @param {!WebInspector.Event} event
*/
_breakpointAdded: function(event)
{
this._breakpointRemoved(event);
var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation);
this._addBreakpoint(breakpoint, uiLocation);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!WebInspector.UILocation} uiLocation
*/
_addBreakpoint: function(breakpoint, uiLocation)
{
var element = createElementWithClass("li", "cursor-pointer");
element.addEventListener("contextmenu", this._breakpointContextMenu.bind(this, breakpoint), true);
element.addEventListener("click", this._breakpointClicked.bind(this, uiLocation), false);
var checkboxLabel = createCheckboxLabel(uiLocation.linkText(), breakpoint.enabled());
element.appendChild(checkboxLabel);
checkboxLabel.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpoint), false);
var snippetElement = element.createChild("div", "source-text monospace");
/**
* @param {?string} content
* @this {WebInspector.JavaScriptBreakpointsSidebarPane}
*/
function didRequestContent(content)
{
var lineNumber = uiLocation.lineNumber
var columnNumber = uiLocation.columnNumber;
var text = new WebInspector.Text(content || "");
if (lineNumber < text.lineCount()) {
var lineText = text.lineAt(lineNumber);
var maxSnippetLength = 200;
var snippetStartIndex = columnNumber > 100 ? columnNumber : 0;
snippetElement.textContent = lineText.substr(snippetStartIndex).trimEnd(maxSnippetLength);
}
this.didReceiveBreakpointLineForTest(uiLocation.uiSourceCode);
}
uiLocation.uiSourceCode.requestContent().then(didRequestContent.bind(this));
element._data = uiLocation;
var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0)
break;
currentElement = currentElement.nextSibling;
}
this._addListElement(element, currentElement);
var breakpointItem = { element: element, checkbox: checkboxLabel.checkboxElement };
this._items.set(breakpoint, breakpointItem);
this.expand();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
didReceiveBreakpointLineForTest: function(uiSourceCode)
{
},
/**
* @param {!WebInspector.Event} event
*/
_breakpointRemoved: function(event)
{
var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
var breakpointItem = this._items.get(breakpoint);
if (!breakpointItem)
return;
this._items.remove(breakpoint);
this._removeListElement(breakpointItem.element);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
*/
highlightBreakpoint: function(breakpoint)
{
var breakpointItem = this._items.get(breakpoint);
if (!breakpointItem)
return;
breakpointItem.element.classList.add("breakpoint-hit");
this._highlightedBreakpointItem = breakpointItem;
},
clearBreakpointHighlight: function()
{
if (this._highlightedBreakpointItem) {
this._highlightedBreakpointItem.element.classList.remove("breakpoint-hit");
delete this._highlightedBreakpointItem;
}
},
_breakpointClicked: function(uiLocation, event)
{
this._showSourceLineDelegate(uiLocation.uiSourceCode, uiLocation.lineNumber);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!Event} event
*/
_breakpointCheckboxClicked: function(breakpoint, event)
{
// Breakpoint element has it's own click handler.
event.consume();
breakpoint.setEnabled(event.target.checkboxElement.checked);
},
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {!Event} event
*/
_breakpointContextMenu: function(breakpoint, event)
{
var breakpoints = this._items.valuesArray();
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"), breakpoint.remove.bind(breakpoint));
if (breakpoints.length > 1) {
var removeAllTitle = WebInspector.UIString.capitalize("Remove ^all ^breakpoints");
contextMenu.appendItem(removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager));
}
contextMenu.appendSeparator();
this._appendBreakpointActiveItem(contextMenu);
function enabledBreakpointCount(breakpoints)
{
var count = 0;
for (var i = 0; i < breakpoints.length; ++i) {
if (breakpoints[i].checkbox.checked)
count++;
}
return count;
}
if (breakpoints.length > 1) {
var enableBreakpointCount = enabledBreakpointCount(breakpoints);
var enableTitle = WebInspector.UIString.capitalize("Enable ^all ^breakpoints");
var disableTitle = WebInspector.UIString.capitalize("Disable ^all ^breakpoints");
contextMenu.appendSeparator();
contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount != breakpoints.length));
contextMenu.appendItem(disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false), !(enableBreakpointCount > 1));
}
contextMenu.show();
},
_addListElement: function(element, beforeElement)
{
if (beforeElement)
this.listElement.insertBefore(element, beforeElement);
else {
if (!this.listElement.firstChild) {
this.element.removeChild(this.emptyElement);
this.element.appendChild(this.listElement);
}
this.listElement.appendChild(element);
}
},
_removeListElement: function(element)
{
this.listElement.removeChild(element);
if (!this.listElement.firstChild) {
this.element.removeChild(this.listElement);
this.element.appendChild(this.emptyElement);
}
},
_compare: function(x, y)
{
if (x !== y)
return x < y ? -1 : 1;
return 0;
},
_compareBreakpoints: function(b1, b2)
{
return this._compare(b1.uiSourceCode.url(), b2.uiSourceCode.url()) || this._compare(b1.lineNumber, b2.lineNumber);
},
reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.element.removeChild(this.listElement);
this.element.appendChild(this.emptyElement);
}
this._items.clear();
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.JavaScriptSourceFrame} sourceFrame
*/
WebInspector.JavaScriptCompiler = function(sourceFrame)
{
this._sourceFrame = sourceFrame;
this._compiling = false;
}
WebInspector.JavaScriptCompiler.CompileDelay = 1000;
WebInspector.JavaScriptCompiler.prototype = {
scheduleCompile: function()
{
if (this._compiling) {
this._recompileScheduled = true;
return;
}
if (this._timeout)
clearTimeout(this._timeout);
this._timeout = setTimeout(this._compile.bind(this), WebInspector.JavaScriptCompiler.CompileDelay);
},
/**
* @return {?WebInspector.Target}
*/
_findTarget: function()
{
var targets = WebInspector.targetManager.targets();
var sourceCode = this._sourceFrame.uiSourceCode();
for (var i = 0; i < targets.length; ++i) {
var scriptFile = WebInspector.debuggerWorkspaceBinding.scriptFile(sourceCode, targets[i]);
if (scriptFile)
return targets[i];
}
return WebInspector.targetManager.mainTarget();
},
_compile: function()
{
var target = this._findTarget();
if (!target)
return;
var runtimeModel = target.runtimeModel;
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!currentExecutionContext)
return;
this._compiling = true;
var code = this._sourceFrame.textEditor.text();
runtimeModel.compileScript(code, "", false, currentExecutionContext.id, compileCallback.bind(this, target));
/**
* @param {!WebInspector.Target} target
* @param {!RuntimeAgent.ScriptId=} scriptId
* @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.JavaScriptCompiler}
*/
function compileCallback(target, scriptId, exceptionDetails)
{
this._compiling = false;
if (this._recompileScheduled) {
delete this._recompileScheduled;
this.scheduleCompile();
return;
}
if (!exceptionDetails)
return;
this._sourceFrame.uiSourceCode().addLineMessage(WebInspector.UISourceCode.Message.Level.Error, exceptionDetails.text, exceptionDetails.line - 1, exceptionDetails.column + 1);
this._compilationFinishedForTest();
}
},
_compilationFinishedForTest: function() {}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 2 | /*
* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.FilteredListWidget.Delegate}
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback)
{
WebInspector.FilteredListWidget.Delegate.call(this, []);
this._functionItems = [];
this._selectItemCallback = selectItemCallback;
this._outlineWorker = new WorkerRuntime.Worker("formatter_worker");
this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
this._outlineWorker.postMessage({ method: "javaScriptOutline", params: { content: uiSourceCode.workingCopy() } });
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
WebInspector.JavaScriptOutlineDialog.show = function(uiSourceCode, selectItemCallback)
{
new WebInspector.FilteredListWidget(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback), false).showAsDialog();
}
WebInspector.JavaScriptOutlineDialog.prototype = {
/**
* @param {!MessageEvent} event
*/
_didBuildOutlineChunk: function(event)
{
var data = /** @type {!WebInspector.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
var chunk = data.chunk;
for (var i = 0; i < chunk.length; ++i)
this._functionItems.push(chunk[i]);
if (data.isLastChunk)
this.dispose();
this.refresh();
},
/**
* @override
* @return {number}
*/
itemCount: function()
{
return this._functionItems.length;
},
/**
* @override
* @param {number} itemIndex
* @return {string}
*/
itemKeyAt: function(itemIndex)
{
var item = this._functionItems[itemIndex];
return item.name + (item.arguments ? item.arguments : "");
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @return {number}
*/
itemScoreAt: function(itemIndex, query)
{
var item = this._functionItems[itemIndex];
return -item.line;
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @param {!Element} titleElement
* @param {!Element} subtitleElement
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
var item = this._functionItems[itemIndex];
titleElement.textContent = item.name + (item.arguments ? item.arguments : "");
this.highlightRanges(titleElement, query);
subtitleElement.textContent = ":" + (item.line + 1);
},
/**
* @override
* @param {?number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
if (itemIndex === null)
return;
var lineNumber = this._functionItems[itemIndex].line;
if (!isNaN(lineNumber) && lineNumber >= 0)
this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
},
dispose: function()
{
if (this._outlineWorker) {
this._outlineWorker.terminate();
delete this._outlineWorker;
}
},
__proto__: WebInspector.FilteredListWidget.Delegate.prototype
}
/**
* @typedef {{isLastChunk: boolean, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
*/
WebInspector.JavaScriptOutlineDialog.MessageEventData;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 | 2 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.UISourceCodeFrame}
* @param {!WebInspector.SourcesPanel} scriptsPanel
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
WebInspector.JavaScriptSourceFrame = function(scriptsPanel, uiSourceCode)
{
this._scriptsPanel = scriptsPanel;
this._breakpointManager = WebInspector.breakpointManager;
WebInspector.UISourceCodeFrame.call(this, uiSourceCode);
if (uiSourceCode.project().type() === WebInspector.projectTypes.Debugger)
this.element.classList.add("source-frame-debugger-script");
this._popoverHelper = new WebInspector.ObjectPopoverHelper(scriptsPanel.element,
this._getPopoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), this._onHidePopover.bind(this), true);
this._popoverHelper.setTimeout(250, 250);
this.textEditor.element.addEventListener("keydown", this._onKeyDown.bind(this), true);
this.textEditor.addEventListener(WebInspector.CodeMirrorTextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this);
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this);
this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this);
/** @type {!Map.<!WebInspector.Target, !WebInspector.ResourceScriptFile>}*/
this._scriptFileForTarget = new Map();
this._registerShortcuts();
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i) {
var scriptFile = WebInspector.debuggerWorkspaceBinding.scriptFile(uiSourceCode, targets[i]);
if (scriptFile)
this._updateScriptFile(targets[i]);
}
if (this._scriptFileForTarget.size || uiSourceCode.extension() === "js")
this._compiler = new WebInspector.JavaScriptCompiler(this);
WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._showBlackboxInfobarIfNeeded, this);
WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._showBlackboxInfobarIfNeeded, this);
this._showBlackboxInfobarIfNeeded();
/** @type {!Map.<number, !Element>} */
this._valueWidgets = new Map();
}
WebInspector.JavaScriptSourceFrame.prototype = {
/**
* @override
* @return {!Array<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
var result = WebInspector.UISourceCodeFrame.prototype.toolbarItems.call(this);
var originURL = WebInspector.CompilerScriptMapping.uiSourceCodeOrigin(this.uiSourceCode());
if (originURL) {
var parsedURL = originURL.asParsedURL();
if (parsedURL)
result.push(new WebInspector.ToolbarText(WebInspector.UIString("(source mapped from %s)", parsedURL.displayName)));
}
return result;
},
_updateInfobars: function()
{
this.attachInfobars([this._blackboxInfobar, this._divergedInfobar]);
},
_showDivergedInfobar: function()
{
if (!this.uiSourceCode().contentType().isScript())
return;
if (this._divergedInfobar)
this._divergedInfobar.dispose();
var infobar = new WebInspector.Infobar(WebInspector.Infobar.Type.Warning, WebInspector.UIString("Workspace mapping mismatch"));
this._divergedInfobar = infobar;
var fileURL = this.uiSourceCode().url();
infobar.createDetailsRowMessage(WebInspector.UIString("The content of this file on the file system:\u00a0")).appendChild(
WebInspector.linkifyURLAsNode(fileURL, fileURL, "source-frame-infobar-details-url", true));
var scriptURL = WebInspector.networkMapping.networkURL(this.uiSourceCode());
infobar.createDetailsRowMessage(WebInspector.UIString("does not match the loaded script:\u00a0")).appendChild(
WebInspector.linkifyURLAsNode(scriptURL, scriptURL, "source-frame-infobar-details-url", true));
infobar.createDetailsRowMessage();
infobar.createDetailsRowMessage(WebInspector.UIString("Possible solutions are:"));
if (WebInspector.moduleSetting("cacheDisabled").get())
infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Reload inspected page"));
else
infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Check \"Disable cache\" in settings and reload inspected page (recommended setup for authoring and debugging)"));
infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Check that your file and script are both loaded from the correct source and their contents match"));
this._updateInfobars();
},
_hideDivergedInfobar: function()
{
if (!this._divergedInfobar)
return;
this._divergedInfobar.dispose();
delete this._divergedInfobar;
},
_showBlackboxInfobarIfNeeded: function()
{
var uiSourceCode = this.uiSourceCode();
if (!uiSourceCode.contentType().hasScripts())
return;
var projectType = uiSourceCode.project().type();
if (projectType === WebInspector.projectTypes.Snippets)
return;
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
var url = projectType === WebInspector.projectTypes.Formatter ? uiSourceCode.url() : networkURL;
var isContentScript = projectType === WebInspector.projectTypes.ContentScripts;
if (!WebInspector.blackboxManager.isBlackboxedUISourceCode(uiSourceCode)) {
this._hideBlackboxInfobar();
return;
}
if (this._blackboxInfobar)
this._blackboxInfobar.dispose();
var infobar = new WebInspector.Infobar(WebInspector.Infobar.Type.Warning, WebInspector.UIString("This script is blackboxed in debugger"));
this._blackboxInfobar = infobar;
infobar.createDetailsRowMessage(WebInspector.UIString("Debugger will skip stepping through this script, and will not stop on exceptions"));
var scriptFile = this._scriptFileForTarget.size ? this._scriptFileForTarget.valuesArray()[0] : null;
if (scriptFile && scriptFile.hasSourceMapURL())
infobar.createDetailsRowMessage(WebInspector.UIString("Source map found, but ignored for blackboxed file."));
infobar.createDetailsRowMessage();
infobar.createDetailsRowMessage(WebInspector.UIString("Possible ways to cancel this behavior are:"));
infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Go to \"%s\" tab in settings", WebInspector.manageBlackboxingSettingsTabLabel()));
var unblackboxLink = infobar.createDetailsRowMessage(" - ").createChild("span", "link");
unblackboxLink.textContent = WebInspector.UIString("Unblackbox this script");
unblackboxLink.addEventListener("click", unblackbox, false);
function unblackbox()
{
WebInspector.blackboxManager.unblackboxUISourceCode(uiSourceCode);
if (projectType === WebInspector.projectTypes.ContentScripts)
WebInspector.blackboxManager.unblackboxContentScripts();
}
this._updateInfobars();
},
_hideBlackboxInfobar: function()
{
if (!this._blackboxInfobar)
return;
this._blackboxInfobar.dispose();
delete this._blackboxInfobar;
},
_registerShortcuts: function()
{
var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts;
for (var i = 0; i < shortcutKeys.EvaluateSelectionInConsole.length; ++i) {
var keyDescriptor = shortcutKeys.EvaluateSelectionInConsole[i];
this.addShortcut(keyDescriptor.key, this._evaluateSelectionInConsole.bind(this));
}
for (var i = 0; i < shortcutKeys.AddSelectionToWatch.length; ++i) {
var keyDescriptor = shortcutKeys.AddSelectionToWatch[i];
this.addShortcut(keyDescriptor.key, this._addCurrentSelectionToWatch.bind(this));
}
},
_addCurrentSelectionToWatch: function()
{
var textSelection = this.textEditor.selection();
if (textSelection && !textSelection.isEmpty())
this._innerAddToWatch(this.textEditor.copyRange(textSelection));
return true;
},
/**
* @param {string} expression
*/
_innerAddToWatch: function(expression)
{
this._scriptsPanel.addToWatch(expression);
},
/**
* @return {boolean}
*/
_evaluateSelectionInConsole: function()
{
var selection = this.textEditor.selection();
if (!selection || selection.isEmpty())
return true;
this._evaluateInConsole(this.textEditor.copyRange(selection));
return true;
},
/**
* @param {string} expression
*/
_evaluateInConsole: function(expression)
{
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (currentExecutionContext)
WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, expression);
},
/**
* @override
*/
wasShown: function()
{
WebInspector.UISourceCodeFrame.prototype.wasShown.call(this);
if (this._executionLocation && this.loaded) {
// We need CodeMirrorTextEditor to be initialized prior to this call. @see crbug.com/499889
setImmediate(this._generateValuesInSource.bind(this));
}
},
/**
* @override
*/
willHide: function()
{
WebInspector.UISourceCodeFrame.prototype.willHide.call(this);
this._popoverHelper.hidePopover();
},
onUISourceCodeContentChanged: function()
{
this._removeAllBreakpoints();
WebInspector.UISourceCodeFrame.prototype.onUISourceCodeContentChanged.call(this);
},
onTextChanged: function(oldRange, newRange)
{
this._scriptsPanel.updateLastModificationTime();
WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this, oldRange, newRange);
if (this._compiler)
this._compiler.scheduleCompile();
},
/**
* @override
* @return {!Promise}
*/
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
/**
* @this {WebInspector.JavaScriptSourceFrame}
*/
function populate(resolve, reject)
{
var uiLocation = new WebInspector.UILocation(this.uiSourceCode(), lineNumber, 0);
this._scriptsPanel.appendUILocationItems(contextMenu, uiLocation);
var breakpoint = this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(), lineNumber);
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
contextMenu.appendItem(WebInspector.UIString("Add breakpoint"), this._createNewBreakpoint.bind(this, lineNumber, 0, "", true));
contextMenu.appendItem(WebInspector.UIString("Add conditional breakpoint…"), this._editBreakpointCondition.bind(this, lineNumber));
contextMenu.appendItem(WebInspector.UIString("Never pause here"), this._createNewBreakpoint.bind(this, lineNumber, 0, "false", true));
} else {
// This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
contextMenu.appendItem(WebInspector.UIString("Remove breakpoint"), breakpoint.remove.bind(breakpoint));
contextMenu.appendItem(WebInspector.UIString("Edit breakpoint…"), this._editBreakpointCondition.bind(this, lineNumber, breakpoint));
if (breakpoint.enabled())
contextMenu.appendItem(WebInspector.UIString("Disable breakpoint"), breakpoint.setEnabled.bind(breakpoint, false));
else
contextMenu.appendItem(WebInspector.UIString("Enable breakpoint"), breakpoint.setEnabled.bind(breakpoint, true));
}
resolve();
}
return new Promise(populate.bind(this));
},
/**
* @override
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
{
var textSelection = this.textEditor.selection();
if (textSelection && !textSelection.isEmpty()) {
var selection = this.textEditor.copyRange(textSelection);
var addToWatchLabel = WebInspector.UIString.capitalize("Add to ^watch");
contextMenu.appendItem(addToWatchLabel, this._innerAddToWatch.bind(this, selection));
var evaluateLabel = WebInspector.UIString.capitalize("Evaluate in ^console");
contextMenu.appendItem(evaluateLabel, this._evaluateInConsole.bind(this, selection));
contextMenu.appendSeparator();
}
/**
* @param {!WebInspector.ResourceScriptFile} scriptFile
*/
function addSourceMapURL(scriptFile)
{
WebInspector.AddSourceMapURLDialog.show(addSourceMapURLDialogCallback.bind(null, scriptFile));
}
/**
* @param {!WebInspector.ResourceScriptFile} scriptFile
* @param {string} url
*/
function addSourceMapURLDialogCallback(scriptFile, url)
{
if (!url)
return;
scriptFile.addSourceMapURL(url);
}
/**
* @this {WebInspector.JavaScriptSourceFrame}
*/
function populateSourceMapMembers()
{
if (this.uiSourceCode().project().type() === WebInspector.projectTypes.Network && WebInspector.moduleSetting("jsSourceMapsEnabled").get() && !WebInspector.blackboxManager.isBlackboxedUISourceCode(this.uiSourceCode())) {
if (this._scriptFileForTarget.size) {
var scriptFile = this._scriptFileForTarget.valuesArray()[0];
var addSourceMapURLLabel = WebInspector.UIString.capitalize("Add ^source ^map\u2026");
contextMenu.appendItem(addSourceMapURLLabel, addSourceMapURL.bind(null, scriptFile));
contextMenu.appendSeparator();
}
}
}
return WebInspector.UISourceCodeFrame.prototype.populateTextAreaContextMenu.call(this, contextMenu, lineNumber, columnNumber).then(populateSourceMapMembers.bind(this));
},
_workingCopyChanged: function(event)
{
if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForTarget.size)
return;
if (this.uiSourceCode().isDirty())
this._muteBreakpointsWhileEditing();
else
this._restoreBreakpointsAfterEditing();
},
_workingCopyCommitted: function(event)
{
this._scriptsPanel.updateLastModificationTime();
if (this._supportsEnabledBreakpointsWhileEditing())
return;
if (!this._scriptFileForTarget.size)
this._restoreBreakpointsAfterEditing();
},
_didMergeToVM: function()
{
if (this._supportsEnabledBreakpointsWhileEditing())
return;
this._updateDivergedInfobar();
this._restoreBreakpointsIfConsistentScripts();
},
_didDivergeFromVM: function()
{
if (this._supportsEnabledBreakpointsWhileEditing())
return;
this._updateDivergedInfobar();
this._muteBreakpointsWhileEditing();
},
_muteBreakpointsWhileEditing: function()
{
if (this._muted)
return;
for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber) {
var breakpointDecoration = this._textEditor.getAttribute(lineNumber, "breakpoint");
if (!breakpointDecoration)
continue;
this._removeBreakpointDecoration(lineNumber);
this._addBreakpointDecoration(lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled, true);
}
this._muted = true;
},
_updateDivergedInfobar: function()
{
if (this.uiSourceCode().project().type() !== WebInspector.projectTypes.FileSystem) {
this._hideDivergedInfobar();
return;
}
var scriptFiles = this._scriptFileForTarget.valuesArray();
var hasDivergedScript = false;
for (var i = 0; i < scriptFiles.length; ++i)
hasDivergedScript = hasDivergedScript || scriptFiles[i].hasDivergedFromVM();
if (this._divergedInfobar) {
if (!hasDivergedScript)
this._hideDivergedInfobar();
} else {
if (hasDivergedScript && !this.uiSourceCode().isDirty())
this._showDivergedInfobar();
}
},
_supportsEnabledBreakpointsWhileEditing: function()
{
return this.uiSourceCode().project().type() === WebInspector.projectTypes.Snippets;
},
_restoreBreakpointsIfConsistentScripts: function()
{
var scriptFiles = this._scriptFileForTarget.valuesArray();
for (var i = 0; i < scriptFiles.length; ++i)
if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM())
return;
this._restoreBreakpointsAfterEditing();
},
_restoreBreakpointsAfterEditing: function()
{
delete this._muted;
var breakpoints = {};
// Save and remove muted breakpoint decorations.
for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber) {
var breakpointDecoration = this._textEditor.getAttribute(lineNumber, "breakpoint");
if (breakpointDecoration) {
breakpoints[lineNumber] = breakpointDecoration;
this._removeBreakpointDecoration(lineNumber);
}
}
// Remove all breakpoints.
this._removeAllBreakpoints();
// Restore all breakpoints from saved decorations.
for (var lineNumberString in breakpoints) {
var lineNumber = parseInt(lineNumberString, 10);
if (isNaN(lineNumber))
continue;
var breakpointDecoration = breakpoints[lineNumberString];
this._setBreakpoint(lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled);
}
},
_removeAllBreakpoints: function()
{
var breakpoints = this._breakpointManager.breakpointsForUISourceCode(this.uiSourceCode());
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();
},
/**
* @param {string} tokenType
* @return {boolean}
*/
_isIdentifier: function(tokenType)
{
return tokenType.startsWith("js-variable") || tokenType.startsWith("js-property") || tokenType == "js-def";
},
_getPopoverAnchor: function(element, event)
{
var target = WebInspector.context.flavor(WebInspector.Target);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel || !debuggerModel.isPaused())
return;
var textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y);
if (!textPosition)
return;
var mouseLine = textPosition.startLine;
var mouseColumn = textPosition.startColumn;
var textSelection = this.textEditor.selection().normalize();
if (textSelection && !textSelection.isEmpty()) {
if (textSelection.startLine !== textSelection.endLine || textSelection.startLine !== mouseLine || mouseColumn < textSelection.startColumn || mouseColumn > textSelection.endColumn)
return;
var leftCorner = this.textEditor.cursorPositionToCoordinates(textSelection.startLine, textSelection.startColumn);
var rightCorner = this.textEditor.cursorPositionToCoordinates(textSelection.endLine, textSelection.endColumn);
var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height);
anchorBox.highlight = {
lineNumber: textSelection.startLine,
startColumn: textSelection.startColumn,
endColumn: textSelection.endColumn - 1
};
anchorBox.forSelection = true;
return anchorBox;
}
var token = this.textEditor.tokenAtTextPosition(textPosition.startLine, textPosition.startColumn);
if (!token || !token.type)
return;
var lineNumber = textPosition.startLine;
var line = this.textEditor.line(lineNumber);
var tokenContent = line.substring(token.startColumn, token.endColumn);
var isIdentifier = this._isIdentifier(token.type);
if (!isIdentifier && (token.type !== "js-keyword" || tokenContent !== "this"))
return;
var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.startColumn);
var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.endColumn - 1);
var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height);
anchorBox.highlight = {
lineNumber: lineNumber,
startColumn: token.startColumn,
endColumn: token.endColumn - 1
};
return anchorBox;
},
_resolveObjectForPopover: function(anchorBox, showCallback, objectGroupName)
{
var target = WebInspector.context.flavor(WebInspector.Target);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel || !debuggerModel.isPaused()) {
this._popoverHelper.hidePopover();
return;
}
var lineNumber = anchorBox.highlight.lineNumber;
var startHighlight = anchorBox.highlight.startColumn;
var endHighlight = anchorBox.highlight.endColumn;
var line = this.textEditor.line(lineNumber);
if (!anchorBox.forSelection) {
while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') {
var token = this.textEditor.tokenAtTextPosition(lineNumber, startHighlight - 2);
if (!token || !token.type) {
this._popoverHelper.hidePopover();
return;
}
startHighlight = token.startColumn;
}
}
var evaluationText = line.substring(startHighlight, endHighlight + 1);
var selectedCallFrame = /** @type {!WebInspector.DebuggerModel.CallFrame}*/ (debuggerModel.selectedCallFrame());
WebInspector.SourceMapNamesResolver.resolveExpression(selectedCallFrame, evaluationText, this.uiSourceCode(), lineNumber, startHighlight, endHighlight).then(onResolve.bind(this));
/**
* @param {?string=} text
* @this {WebInspector.JavaScriptSourceFrame}
*/
function onResolve(text)
{
selectedCallFrame.evaluate(text || evaluationText, objectGroupName, false, true, false, false, showObjectPopover.bind(this));
}
/**
* @param {?RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
* @this {WebInspector.JavaScriptSourceFrame}
*/
function showObjectPopover(result, wasThrown)
{
var target = WebInspector.context.flavor(WebInspector.Target);
if (selectedCallFrame.target() != target || !debuggerModel.isPaused() || !result) {
this._popoverHelper.hidePopover();
return;
}
this._popoverAnchorBox = anchorBox;
showCallback(target.runtimeModel.createRemoteObject(result), wasThrown, this._popoverAnchorBox);
// Popover may have been removed by showCallback().
if (this._popoverAnchorBox) {
var highlightRange = new WebInspector.TextRange(lineNumber, startHighlight, lineNumber, endHighlight);
this._popoverAnchorBox._highlightDescriptor = this.textEditor.highlightRange(highlightRange, "source-frame-eval-expression");
}
}
},
_onHidePopover: function()
{
if (!this._popoverAnchorBox)
return;
if (this._popoverAnchorBox._highlightDescriptor)
this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescriptor);
delete this._popoverAnchorBox;
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @param {boolean} mutedWhileEditing
*/
_addBreakpointDecoration: function(lineNumber, columnNumber, condition, enabled, mutedWhileEditing)
{
var breakpoint = {
condition: condition,
enabled: enabled,
columnNumber: columnNumber
};
this.textEditor.setAttribute(lineNumber, "breakpoint", breakpoint);
var disabled = !enabled || mutedWhileEditing;
this.textEditor.addBreakpoint(lineNumber, disabled, !!condition);
},
_removeBreakpointDecoration: function(lineNumber)
{
this.textEditor.removeAttribute(lineNumber, "breakpoint");
this.textEditor.removeBreakpoint(lineNumber);
},
_onKeyDown: function(event)
{
if (event.keyIdentifier === "U+001B") { // Escape key
if (this._popoverHelper.isPopoverVisible()) {
this._popoverHelper.hidePopover();
event.consume();
}
}
},
/**
* @param {number} lineNumber
* @param {!WebInspector.BreakpointManager.Breakpoint=} breakpoint
*/
_editBreakpointCondition: function(lineNumber, breakpoint)
{
this._conditionElement = this._createConditionElement(lineNumber);
this.textEditor.addDecoration(lineNumber, this._conditionElement);
/**
* @this {WebInspector.JavaScriptSourceFrame}
*/
function finishEditing(committed, element, newText)
{
this.textEditor.removeDecoration(lineNumber, this._conditionElement);
delete this._conditionEditorElement;
delete this._conditionElement;
if (!committed)
return;
if (breakpoint)
breakpoint.setCondition(newText);
else
this._createNewBreakpoint(lineNumber, 0, newText, true);
}
var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
WebInspector.InplaceEditor.startEditing(this._conditionEditorElement, config);
this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : "";
this._conditionEditorElement.select();
},
_createConditionElement: function(lineNumber)
{
var conditionElement = createElementWithClass("div", "source-frame-breakpoint-condition");
var labelElement = conditionElement.createChild("label", "source-frame-breakpoint-message");
labelElement.htmlFor = "source-frame-breakpoint-condition";
labelElement.createTextChild(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber + 1));
var editorElement = conditionElement.createChild("input", "monospace");
editorElement.id = "source-frame-breakpoint-condition";
editorElement.type = "text";
this._conditionEditorElement = editorElement;
return conditionElement;
},
/**
* @param {!WebInspector.UILocation} uiLocation
*/
setExecutionLocation: function(uiLocation)
{
this._executionLocation = uiLocation;
if (!this.loaded)
return;
this.textEditor.setExecutionLocation(uiLocation.lineNumber, uiLocation.columnNumber);
if (this.isShowing()) {
// We need CodeMirrorTextEditor to be initialized prior to this call. @see crbug.com/506566
setImmediate(this._generateValuesInSource.bind(this));
}
},
_generateValuesInSource: function()
{
if (!WebInspector.moduleSetting("inlineVariableValues").get())
return;
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!executionContext)
return;
var callFrame = executionContext.debuggerModel.selectedCallFrame();
if (!callFrame)
return;
var localScope = callFrame.localScope();
var functionLocation = callFrame.functionLocation();
if (localScope && functionLocation)
WebInspector.SourceMapNamesResolver.resolveScopeInObject(localScope).getAllProperties(false, this._prepareScopeVariables.bind(this, callFrame));
if (this._clearValueWidgetsTimer) {
clearTimeout(this._clearValueWidgetsTimer);
delete this._clearValueWidgetsTimer;
}
},
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
*/
_prepareScopeVariables: function(callFrame, properties, internalProperties)
{
if (!properties || !properties.length || properties.length > 500) {
this._clearValueWidgets();
return;
}
var functionUILocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(/**@type {!WebInspector.DebuggerModel.Location} */ (callFrame.functionLocation()));
var executionUILocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrame.location());
if (functionUILocation.uiSourceCode !== this.uiSourceCode() || executionUILocation.uiSourceCode !== this.uiSourceCode()) {
this._clearValueWidgets();
return;
}
var fromLine = functionUILocation.lineNumber;
var fromColumn = functionUILocation.columnNumber;
var toLine = executionUILocation.lineNumber;
// Make sure we have a chance to update all existing widgets.
if (this._valueWidgets) {
for (var line of this._valueWidgets.keys())
toLine = Math.max(toLine, line + 1);
}
if (fromLine >= toLine || toLine - fromLine > 500 || fromLine < 0 || toLine >= this.textEditor.linesCount) {
this._clearValueWidgets();
return;
}
var valuesMap = new Map();
for (var property of properties)
valuesMap.set(property.name, property.value);
/** @type {!Map.<number, !Set<string>>} */
var namesPerLine = new Map();
var tokenizer = new WebInspector.CodeMirrorUtils.TokenizerFactory().createTokenizer("text/javascript");
tokenizer(this.textEditor.line(fromLine).substring(fromColumn), processToken.bind(this, fromLine));
for (var i = fromLine + 1; i < toLine; ++i)
tokenizer(this.textEditor.line(i), processToken.bind(this, i));
/**
* @param {number} lineNumber
* @param {string} tokenValue
* @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
* @this {WebInspector.JavaScriptSourceFrame}
*/
function processToken(lineNumber, tokenValue, tokenType, column, newColumn)
{
if (tokenType && this._isIdentifier(tokenType) && valuesMap.get(tokenValue)) {
var names = namesPerLine.get(lineNumber);
if (!names) {
names = new Set();
namesPerLine.set(lineNumber, names);
}
names.add(tokenValue);
}
}
this.textEditor.operation(this._renderDecorations.bind(this, valuesMap, namesPerLine, fromLine, toLine));
},
/**
* @param {!Map.<string,!WebInspector.RemoteObject>} valuesMap
* @param {!Map.<number, !Set<string>>} namesPerLine
* @param {number} fromLine
* @param {number} toLine
*/
_renderDecorations: function(valuesMap, namesPerLine, fromLine, toLine)
{
var formatter = new WebInspector.RemoteObjectPreviewFormatter();
for (var i = fromLine; i < toLine; ++i) {
var names = namesPerLine.get(i);
var oldWidget = this._valueWidgets.get(i);
if (!names) {
if (oldWidget) {
this._valueWidgets.delete(i);
this.textEditor.removeDecoration(i, oldWidget);
}
continue;
}
var widget = createElementWithClass("div", "text-editor-value-decoration");
var base = this.textEditor.cursorPositionToCoordinates(i, 0);
var offset = this.textEditor.cursorPositionToCoordinates(i, this.textEditor.line(i).length);
var codeMirrorLinesLeftPadding = 4;
var left = offset.x - base.x + codeMirrorLinesLeftPadding;
widget.style.left = left + "px";
widget.__nameToToken = new Map();
widget.__lineNumber = i;
var renderedNameCount = 0;
for (var name of names) {
if (renderedNameCount > 10)
break;
if (namesPerLine.get(i - 1) && namesPerLine.get(i - 1).has(name))
continue; // Only render name once in the given continuous block.
if (renderedNameCount)
widget.createTextChild(", ");
var nameValuePair = widget.createChild("span");
widget.__nameToToken.set(name, nameValuePair);
nameValuePair.createTextChild(name + " = ");
var value = valuesMap.get(name);
var propertyCount = value.preview ? value.preview.properties.length : 0;
var entryCount = value.preview && value.preview.entries ? value.preview.entries.length : 0;
if (value.preview && propertyCount + entryCount < 10)
formatter.appendObjectPreview(nameValuePair, value.preview);
else
nameValuePair.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(value, false));
++renderedNameCount;
}
var widgetChanged = true;
if (oldWidget) {
widgetChanged = false;
for (var name of widget.__nameToToken.keys()) {
var oldText = oldWidget.__nameToToken.get(name) ? oldWidget.__nameToToken.get(name).textContent : "";
var newText = widget.__nameToToken.get(name) ? widget.__nameToToken.get(name).textContent : "";
if (newText !== oldText) {
widgetChanged = true;
// value has changed, update it.
WebInspector.runCSSAnimationOnce(/** @type {!Element} */ (widget.__nameToToken.get(name)), "source-frame-value-update-highlight");
}
}
if (widgetChanged) {
this._valueWidgets.delete(i);
this.textEditor.removeDecoration(i, oldWidget);
}
}
if (widgetChanged) {
this._valueWidgets.set(i, widget);
this.textEditor.addDecoration(i, widget);
}
}
},
clearExecutionLine: function()
{
if (this.loaded && this._executionLocation)
this.textEditor.clearExecutionLine();
delete this._executionLocation;
this._clearValueWidgetsTimer = setTimeout(this._clearValueWidgets.bind(this), 1000);
},
_clearValueWidgets: function()
{
delete this._clearValueWidgetsTimer;
for (var line of this._valueWidgets.keys())
this.textEditor.removeDecoration(line, this._valueWidgets.get(line));
this._valueWidgets.clear();
},
/**
* @return {boolean}
*/
_shouldIgnoreExternalBreakpointEvents: function()
{
if (this._supportsEnabledBreakpointsWhileEditing())
return false;
if (this._muted)
return true;
var scriptFiles = this._scriptFileForTarget.valuesArray();
for (var i = 0; i < scriptFiles.length; ++i) {
if (scriptFiles[i].isDivergingFromVM() || scriptFiles[i].isMergingToVM())
return true;
}
return false;
},
_breakpointAdded: function(event)
{
var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation);
if (uiLocation.uiSourceCode !== this.uiSourceCode())
return;
if (this._shouldIgnoreExternalBreakpointEvents())
return;
var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
if (this.loaded)
this._addBreakpointDecoration(uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled(), false);
},
_breakpointRemoved: function(event)
{
var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation);
if (uiLocation.uiSourceCode !== this.uiSourceCode())
return;
if (this._shouldIgnoreExternalBreakpointEvents())
return;
var remainingBreakpoint = this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(), uiLocation.lineNumber);
if (!remainingBreakpoint && this.loaded)
this._removeBreakpointDecoration(uiLocation.lineNumber);
},
/**
* @param {!WebInspector.Event} event
*/
_onSourceMappingChanged: function(event)
{
var data = /** @type {{target: !WebInspector.Target}} */ (event.data);
this._updateScriptFile(data.target);
this._updateLinesWithoutMappingHighlight();
},
_updateLinesWithoutMappingHighlight: function()
{
var linesCount = this.textEditor.linesCount;
for (var i = 0; i < linesCount; ++i) {
var lineHasMapping = WebInspector.debuggerWorkspaceBinding.uiLineHasMapping(this.uiSourceCode(), i);
if (!lineHasMapping)
this._hasLineWithoutMapping = true;
if (this._hasLineWithoutMapping)
this.textEditor.toggleLineClass(i, "cm-line-without-source-mapping", !lineHasMapping);
}
},
/**
* @param {!WebInspector.Target} target
*/
_updateScriptFile: function(target)
{
var oldScriptFile = this._scriptFileForTarget.get(target);
var newScriptFile = WebInspector.debuggerWorkspaceBinding.scriptFile(this.uiSourceCode(), target);
this._scriptFileForTarget.remove(target);
if (oldScriptFile) {
oldScriptFile.removeEventListener(WebInspector.ResourceScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
oldScriptFile.removeEventListener(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
if (this._muted && !this.uiSourceCode().isDirty())
this._restoreBreakpointsIfConsistentScripts();
}
if (newScriptFile)
this._scriptFileForTarget.set(target, newScriptFile);
this._updateDivergedInfobar();
if (newScriptFile) {
newScriptFile.addEventListener(WebInspector.ResourceScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
newScriptFile.addEventListener(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
if (this.loaded)
newScriptFile.checkMapping();
if (newScriptFile.hasSourceMapURL()) {
var sourceMapInfobar = WebInspector.Infobar.create(WebInspector.Infobar.Type.Info, WebInspector.UIString("Source Map detected."), WebInspector.settings.createSetting("sourceMapInfobarDisabled", false));
if (sourceMapInfobar) {
sourceMapInfobar.createDetailsRowMessage(WebInspector.UIString("Associated files should be added to the file tree. You can debug these resolved source files as regular JavaScript files."));
sourceMapInfobar.createDetailsRowMessage(WebInspector.UIString("Associated files are available via file tree or %s.", WebInspector.shortcutRegistry.shortcutTitleForAction("sources.go-to-source")));
this.attachInfobars([sourceMapInfobar]);
}
}
}
},
/**
* @override
*/
onTextEditorContentLoaded: function()
{
WebInspector.UISourceCodeFrame.prototype.onTextEditorContentLoaded.call(this);
if (this._executionLocation)
this.setExecutionLocation(this._executionLocation);
var breakpointLocations = this._breakpointManager.breakpointLocationsForUISourceCode(this.uiSourceCode());
for (var i = 0; i < breakpointLocations.length; ++i)
this._breakpointAdded({data:breakpointLocations[i]});
var scriptFiles = this._scriptFileForTarget.valuesArray();
for (var i = 0; i < scriptFiles.length; ++i)
scriptFiles[i].checkMapping();
this._updateLinesWithoutMappingHighlight();
this._detectMinified();
},
_detectMinified: function()
{
if (this._prettyPrintInfobar)
return;
var minified = false;
for (var i = 0; i < 10 && i < this.textEditor.linesCount; ++i) {
var line = this.textEditor.line(i);
if (line.startsWith("//#")) // mind source map.
continue;
if (line.length > 500) {
minified = true;
break;
}
}
if (!minified)
return;
this._prettyPrintInfobar = WebInspector.Infobar.create(
WebInspector.Infobar.Type.Info,
WebInspector.UIString("Pretty-print this minified file?"),
WebInspector.settings.createSetting("prettyPrintInfobarDisabled", false));
if (!this._prettyPrintInfobar)
return;
this._prettyPrintInfobar.setCloseCallback(() => delete this._prettyPrintInfobar);
var toolbar = new WebInspector.Toolbar("");
var button = new WebInspector.ToolbarButton("", "format-toolbar-item")
toolbar.appendToolbarItem(button);
toolbar.element.style.display = "inline-block";
toolbar.element.style.verticalAlign = "middle";
toolbar.element.style.marginBottom = "3px";
toolbar.element.style.pointerEvents = "none";
var element = this._prettyPrintInfobar.createDetailsRowMessage();
element.appendChild(WebInspector.formatLocalized("You can click the %s button on the bottom status bar, and continue debugging with the new formatted source.", [toolbar.element]));
this.attachInfobars([this._prettyPrintInfobar]);
},
/**
* @param {!WebInspector.Event} event
*/
_handleGutterClick: function(event)
{
if (this._muted)
return;
var eventData = /** @type {!WebInspector.CodeMirrorTextEditor.GutterClickEventData} */ (event.data);
var lineNumber = eventData.lineNumber;
var eventObject = eventData.event;
if (eventObject.button != 0 || eventObject.altKey || eventObject.ctrlKey || eventObject.metaKey)
return;
this._toggleBreakpoint(lineNumber, eventObject.shiftKey);
eventObject.consume(true);
},
/**
* @param {number} lineNumber
* @param {boolean} onlyDisable
*/
_toggleBreakpoint: function(lineNumber, onlyDisable)
{
var breakpoint = this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(), lineNumber);
if (breakpoint) {
if (onlyDisable)
breakpoint.setEnabled(!breakpoint.enabled());
else
breakpoint.remove();
} else
this._createNewBreakpoint(lineNumber, 0, "", true);
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
*/
_createNewBreakpoint: function(lineNumber, columnNumber, condition, enabled)
{
this._setBreakpoint(lineNumber, columnNumber, condition, enabled);
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ScriptsBreakpointSet);
},
toggleBreakpointOnCurrentLine: function()
{
if (this._muted)
return;
var selection = this.textEditor.selection();
if (!selection)
return;
this._toggleBreakpoint(selection.startLine, false);
},
/**
* @param {number} lineNumber
* @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
*/
_setBreakpoint: function(lineNumber, columnNumber, condition, enabled)
{
this._breakpointManager.setBreakpoint(this.uiSourceCode(), lineNumber, columnNumber, condition, enabled);
},
dispose: function()
{
this._breakpointManager.removeEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
this._breakpointManager.removeEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this);
this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this);
WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListener(this._showBlackboxInfobarIfNeeded, this);
WebInspector.moduleSetting("skipContentScripts").removeChangeListener(this._showBlackboxInfobarIfNeeded, this);
WebInspector.UISourceCodeFrame.prototype.dispose.call(this);
},
__proto__: WebInspector.UISourceCodeFrame.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.NavigatorView = function()
{
WebInspector.VBox.call(this);
this._scriptsTree = new TreeOutlineInShadow();
this._scriptsTree.registerRequiredCSS("sources/navigatorView.css");
this._scriptsTree.setComparator(WebInspector.NavigatorView._treeElementsCompare);
this.element.appendChild(this._scriptsTree.element);
this.setDefaultFocusedElement(this._scriptsTree.element);
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.NavigatorUISourceCodeTreeNode>} */
this._uiSourceCodeNodes = new Map();
/** @type {!Map.<string, !WebInspector.NavigatorFolderTreeNode>} */
this._subfolderNodes = new Map();
this._rootNode = new WebInspector.NavigatorRootTreeNode(this);
this._rootNode.populate();
/** @type {!Map.<!WebInspector.ResourceTreeFrame, !WebInspector.NavigatorGroupTreeNode>} */
this._frameNodes = new Map();
this.element.addEventListener("contextmenu", this.handleContextMenu.bind(this), false);
this._navigatorGroupByFolderSetting = WebInspector.moduleSetting("navigatorGroupByFolder");
this._navigatorGroupByFolderSetting.addChangeListener(this._groupingChanged.bind(this));
this._initGrouping();
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
WebInspector.targetManager.observeTargets(this);
}
WebInspector.NavigatorView.Events = {
ItemSelected: "ItemSelected",
ItemRenamed: "ItemRenamed",
}
WebInspector.NavigatorView.Types = {
Category: "category",
Domain: "domain",
File: "file",
FileSystem: "fs",
FileSystemFolder: "fs-folder",
Frame: "frame",
NetworkFolder: "nw-folder",
Root: "root",
SourceMapFolder: "sm-folder",
Worker: "worker"
}
/**
* @param {!TreeElement} treeElement
*/
WebInspector.NavigatorView._treeElementOrder = function(treeElement)
{
if (treeElement._boostOrder)
return 0;
if (!WebInspector.NavigatorView._typeOrders) {
var weights = {};
var types = WebInspector.NavigatorView.Types;
weights[types.Root] = 1;
weights[types.Category] = 1;
weights[types.Domain] = 10;
weights[types.FileSystemFolder] = 1;
weights[types.NetworkFolder] = 1;
weights[types.SourceMapFolder] = 2;
weights[types.File] = 10;
weights[types.Frame] = 70;
weights[types.Worker] = 90;
weights[types.FileSystem] = 100;
WebInspector.NavigatorView._typeOrders = weights;
}
var order = WebInspector.NavigatorView._typeOrders[treeElement._nodeType];
if (treeElement._uiSourceCode) {
var contentType = treeElement._uiSourceCode.contentType();
if (contentType.isDocument())
order += 3;
else if (contentType.isScript())
order += 5;
else if (contentType.isStyleSheet())
order += 10;
else
order += 15;
}
return order;
}
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
WebInspector.NavigatorView.appendAddFolderItem = function(contextMenu)
{
function addFolder()
{
WebInspector.isolatedFileSystemManager.addFileSystem();
}
var addFolderLabel = WebInspector.UIString.capitalize("Add ^folder to ^workspace");
contextMenu.appendItem(addFolderLabel, addFolder);
}
WebInspector.NavigatorView.prototype = {
/**
* @param {!WebInspector.Workspace} workspace
*/
setWorkspace: function(workspace)
{
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
},
wasShown: function()
{
if (this._loaded)
return;
this._loaded = true;
this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
accept: function(uiSourceCode)
{
return !uiSourceCode.isFromServiceProject();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {?WebInspector.ResourceTreeFrame}
*/
_uiSourceCodeFrame: function(uiSourceCode)
{
var target = WebInspector.NetworkProject.targetForProject(uiSourceCode.project());
if (!target)
return null;
return WebInspector.NetworkProject.frameForProject(uiSourceCode.project()) || target.resourceTreeModel.mainFrame;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_addUISourceCode: function(uiSourceCode)
{
if (!this.accept(uiSourceCode))
return;
var isFromSourceMap = uiSourceCode.contentType().isFromSourceMap();
var path;
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
path = WebInspector.FileSystemWorkspaceBinding.relativePath(uiSourceCode).slice(0, -1);
else
path = WebInspector.ParsedURL.splitURLIntoPathComponents(uiSourceCode.url()).slice(1, -1);
var project = uiSourceCode.project();
var target = WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);
var frame = this._uiSourceCodeFrame(uiSourceCode);
var folderNode = this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap);
var uiSourceCodeNode = new WebInspector.NavigatorUISourceCodeTreeNode(this, uiSourceCode);
this._uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNode);
folderNode.appendChild(uiSourceCodeNode);
this.uiSourceCodeAdded(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
uiSourceCodeAdded: function(uiSourceCode)
{
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._addUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._removeUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var frame = WebInspector.NetworkProject.frameForProject(project);
if (frame)
this._discardFrame(frame);
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
this._removeUISourceCode(uiSourceCodes[i]);
},
/**
* @param {!WebInspector.Project} project
* @param {?WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} projectOrigin
* @param {string} path
* @return {string}
*/
_folderNodeId: function(project, target, frame, projectOrigin, path)
{
var targetId = target ? target.id() : "";
var projectId = project.type() === WebInspector.projectTypes.FileSystem ? project.id() : "";
var frameId = this._groupByFrame && frame ? frame.id : "";
return targetId + ":" + projectId + ":" + frameId + ":" + projectOrigin + ":" + path;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.Project} project
* @param {?WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} projectOrigin
* @param {!Array<string>} path
* @param {boolean} fromSourceMap
* @return {!WebInspector.NavigatorTreeNode}
*/
_folderNode: function(uiSourceCode, project, target, frame, projectOrigin, path, fromSourceMap)
{
if (project.type() === WebInspector.projectTypes.Snippets)
return this._rootNode;
if (target && !this._groupByFolder && !fromSourceMap)
return this._domainNode(uiSourceCode, project, target, frame, projectOrigin);
var folderPath = path.join("/");
var folderId = this._folderNodeId(project, target, frame, projectOrigin, folderPath);
var folderNode = this._subfolderNodes.get(folderId);
if (folderNode)
return folderNode;
if (!path.length) {
if (target)
return this._domainNode(uiSourceCode, project, target, frame, projectOrigin);
var fileSystemNode = this._rootNode.child(project.id());
if (!fileSystemNode) {
fileSystemNode = new WebInspector.NavigatorGroupTreeNode(this, project, project.id(), WebInspector.NavigatorView.Types.FileSystem, project.displayName());
this._rootNode.appendChild(fileSystemNode);
}
return fileSystemNode;
}
var parentNode = this._folderNode(uiSourceCode, project, target, frame, projectOrigin, path.slice(0, -1), fromSourceMap);
var type = fromSourceMap ? WebInspector.NavigatorView.Types.SourceMapFolder : WebInspector.NavigatorView.Types.NetworkFolder;
if (project.type() === WebInspector.projectTypes.FileSystem)
type = WebInspector.NavigatorView.Types.FileSystemFolder;
var name = path[path.length - 1];
folderNode = new WebInspector.NavigatorFolderTreeNode(this, project, folderId, type, folderPath, name);
this._subfolderNodes.set(folderId, folderNode);
parentNode.appendChild(folderNode);
return folderNode;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.Project} project
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @param {string} projectOrigin
* @return {!WebInspector.NavigatorTreeNode}
*/
_domainNode: function(uiSourceCode, project, target, frame, projectOrigin)
{
var frameNode = this._frameNode(project, target, frame);
if (!this._groupByDomain)
return frameNode;
var domainNode = frameNode.child(projectOrigin);
if (domainNode)
return domainNode;
domainNode = new WebInspector.NavigatorGroupTreeNode(this, project, projectOrigin, WebInspector.NavigatorView.Types.Domain, this._computeProjectDisplayName(target, projectOrigin));
if (frame && projectOrigin === WebInspector.ParsedURL.extractOrigin(frame.url))
domainNode.treeNode()._boostOrder = true;
frameNode.appendChild(domainNode);
return domainNode;
},
/**
* @param {!WebInspector.Project} project
* @param {!WebInspector.Target} target
* @param {?WebInspector.ResourceTreeFrame} frame
* @return {!WebInspector.NavigatorTreeNode}
*/
_frameNode: function(project, target, frame)
{
if (!this._groupByFrame || !frame)
return this._targetNode(project, target);
var frameNode = this._frameNodes.get(frame);
if (frameNode)
return frameNode;
frameNode = new WebInspector.NavigatorGroupTreeNode(this, project, target.id() + ":" + frame.id, WebInspector.NavigatorView.Types.Frame, frame.displayName());
frameNode.setHoverCallback(hoverCallback);
this._frameNodes.set(frame, frameNode);
this._frameNode(project, target, frame.parentFrame).appendChild(frameNode);
if (!frame.parentFrame)
frameNode.treeNode()._boostOrder = true;
/**
* @param {boolean} hovered
*/
function hoverCallback(hovered)
{
if (hovered) {
var domModel = WebInspector.DOMModel.fromTarget(target);
if (domModel)
domModel.highlightFrame(frame.id);
} else {
WebInspector.DOMModel.hideDOMNodeHighlight();
}
}
return frameNode;
},
/**
* @param {!WebInspector.Project} project
* @param {!WebInspector.Target} target
* @return {!WebInspector.NavigatorTreeNode}
*/
_targetNode: function(project, target)
{
if (target === WebInspector.targetManager.mainTarget())
return this._rootNode;
var targetNode = this._rootNode.child("target:" + target.id());
if (!targetNode) {
targetNode = new WebInspector.NavigatorGroupTreeNode(this, project, "target:" + target.id(), target.isWorker() ? WebInspector.NavigatorView.Types.Worker : WebInspector.NavigatorView.Types.NetworkFolder, target.name());
this._rootNode.appendChild(targetNode);
}
return targetNode;
},
/**
* @param {!WebInspector.Target} target
* @param {string} projectOrigin
* @return {string}
*/
_computeProjectDisplayName: function(target, projectOrigin)
{
for (var context of target.runtimeModel.executionContexts()) {
if (context.name && context.origin && projectOrigin.startsWith(context.origin))
return context.name;
}
if (!projectOrigin)
return WebInspector.UIString("(no domain)");
var parsedURL = new WebInspector.ParsedURL(projectOrigin);
var prettyURL = parsedURL.isValid ? parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") : "";
return (prettyURL || projectOrigin);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean=} select
*/
revealUISourceCode: function(uiSourceCode, select)
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
if (!node)
return;
if (this._scriptsTree.selectedTreeElement)
this._scriptsTree.selectedTreeElement.deselect();
this._lastSelectedUISourceCode = uiSourceCode;
node.reveal(select);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean} focusSource
*/
_sourceSelected: function(uiSourceCode, focusSource)
{
this._lastSelectedUISourceCode = uiSourceCode;
var data = { uiSourceCode: uiSourceCode, focusSource: focusSource};
this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemSelected, data);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
sourceDeleted: function(uiSourceCode)
{
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeUISourceCode: function(uiSourceCode)
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
if (!node)
return;
var project = uiSourceCode.project();
var target = WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);
var frame = this._uiSourceCodeFrame(uiSourceCode);
var parentNode = node.parent;
this._uiSourceCodeNodes.delete(uiSourceCode);
parentNode.removeChild(node);
node = parentNode;
while (node) {
parentNode = node.parent;
if (!parentNode || !node.isEmpty())
break;
if (!(node instanceof WebInspector.NavigatorGroupTreeNode || node instanceof WebInspector.NavigatorFolderTreeNode))
break;
var folderId = this._folderNodeId(project, target, frame, uiSourceCode.origin(), node._folderPath);
this._subfolderNodes.delete(folderId);
parentNode.removeChild(node);
node = parentNode;
}
},
reset: function()
{
var nodes = this._uiSourceCodeNodes.valuesArray();
for (var i = 0; i < nodes.length; ++i)
nodes[i].dispose();
this._scriptsTree.removeChildren();
this._uiSourceCodeNodes.clear();
this._subfolderNodes.clear();
this._frameNodes.clear();
this._rootNode.reset();
},
/**
* @param {!Event} event
*/
handleContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
WebInspector.NavigatorView.appendAddFolderItem(contextMenu);
contextMenu.show();
},
/**
* @param {!WebInspector.Project} project
* @param {string} path
*/
_handleContextMenuRefresh: function(project, path)
{
project.refresh(path);
},
/**
* @param {!WebInspector.Project} project
* @param {string} path
* @param {!WebInspector.UISourceCode=} uiSourceCode
*/
_handleContextMenuCreate: function(project, path, uiSourceCode)
{
this.create(project, path, uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_handleContextMenuRename: function(uiSourceCode)
{
this.rename(uiSourceCode, false);
},
/**
* @param {!WebInspector.Project} project
* @param {string} path
*/
_handleContextMenuExclude: function(project, path)
{
var shouldExclude = window.confirm(WebInspector.UIString("Are you sure you want to exclude this folder?"));
if (shouldExclude) {
WebInspector.startBatchUpdate();
project.excludeFolder(WebInspector.FileSystemWorkspaceBinding.completeURL(project, path));
WebInspector.endBatchUpdate();
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_handleContextMenuDelete: function(uiSourceCode)
{
var shouldDelete = window.confirm(WebInspector.UIString("Are you sure you want to delete this file?"));
if (shouldDelete)
uiSourceCode.project().deleteFile(uiSourceCode.url());
},
/**
* @param {!Event} event
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
handleFileContextMenu: function(event, uiSourceCode)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(uiSourceCode);
contextMenu.appendSeparator();
var project = uiSourceCode.project();
if (project.type() === WebInspector.projectTypes.FileSystem) {
var parentURL = uiSourceCode.parentURL();
contextMenu.appendItem(WebInspector.UIString.capitalize("Rename\u2026"), this._handleContextMenuRename.bind(this, uiSourceCode));
contextMenu.appendItem(WebInspector.UIString.capitalize("Make a ^copy\u2026"), this._handleContextMenuCreate.bind(this, project, parentURL, uiSourceCode));
contextMenu.appendItem(WebInspector.UIString.capitalize("Delete"), this._handleContextMenuDelete.bind(this, uiSourceCode));
contextMenu.appendSeparator();
}
contextMenu.show();
},
/**
* @param {!Event} event
* @param {!WebInspector.NavigatorFolderTreeNode} node
*/
handleFolderContextMenu: function(event, node)
{
var path = node._folderPath;
var project = node._project;
var contextMenu = new WebInspector.ContextMenu(event);
if (project && project.type() === WebInspector.projectTypes.FileSystem) {
contextMenu.appendItem(WebInspector.UIString.capitalize("Refresh"), this._handleContextMenuRefresh.bind(this, project, path));
if (node instanceof WebInspector.NavigatorFolderTreeNode) {
contextMenu.appendItem(WebInspector.UIString.capitalize("New ^file"), this._handleContextMenuCreate.bind(this, project, path));
contextMenu.appendItem(WebInspector.UIString.capitalize("Exclude ^folder"), this._handleContextMenuExclude.bind(this, project, path));
}
}
contextMenu.appendSeparator();
WebInspector.NavigatorView.appendAddFolderItem(contextMenu);
function removeFolder()
{
var shouldRemove = window.confirm(WebInspector.UIString("Are you sure you want to remove this folder?"));
if (shouldRemove)
project.remove();
}
if (project && project.type() === WebInspector.projectTypes.FileSystem) {
var removeFolderLabel = WebInspector.UIString.capitalize("Remove ^folder from ^workspace");
contextMenu.appendItem(removeFolderLabel, removeFolder);
}
contextMenu.show();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean} deleteIfCanceled
*/
rename: function(uiSourceCode, deleteIfCanceled)
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
console.assert(node);
node.rename(callback.bind(this));
/**
* @this {WebInspector.NavigatorView}
* @param {boolean} committed
*/
function callback(committed)
{
if (!committed) {
if (deleteIfCanceled)
uiSourceCode.remove();
return;
}
this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemRenamed, uiSourceCode);
this._sourceSelected(uiSourceCode, true);
}
},
/**
* @param {!WebInspector.Project} project
* @param {string} path
* @param {!WebInspector.UISourceCode=} uiSourceCodeToCopy
*/
create: function(project, path, uiSourceCodeToCopy)
{
var filePath;
var uiSourceCode;
/**
* @this {WebInspector.NavigatorView}
* @param {?string} content
*/
function contentLoaded(content)
{
createFile.call(this, content || "");
}
if (uiSourceCodeToCopy)
uiSourceCodeToCopy.requestContent().then(contentLoaded.bind(this));
else
createFile.call(this);
/**
* @this {WebInspector.NavigatorView}
* @param {string=} content
*/
function createFile(content)
{
project.createFile(path, null, content || "", fileCreated.bind(this));
}
/**
* @this {WebInspector.NavigatorView}
* @param {?WebInspector.UISourceCode} uiSourceCode
*/
function fileCreated(uiSourceCode)
{
if (!uiSourceCode)
return;
this._sourceSelected(uiSourceCode, false);
this.revealUISourceCode(uiSourceCode, true);
this.rename(uiSourceCode, true);
}
},
_groupingChanged: function()
{
this.reset();
this._initGrouping();
this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
},
_initGrouping: function()
{
this._groupByFrame = true;
this._groupByDomain = this._navigatorGroupByFolderSetting.get();
this._groupByFolder = this._groupByDomain;
},
_resetForTest: function()
{
this.reset();
this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_frameNavigated: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
var node = this._frameNodes.get(frame);
if (!node)
return;
node.treeNode().title = frame.displayName();
for (var child of frame.childFrames)
this._discardFrame(child);
},
/**
* @param {!WebInspector.Event} event
*/
_frameDetached: function(event)
{
var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
this._discardFrame(frame);
},
/**
* @param {!WebInspector.ResourceTreeFrame} frame
*/
_discardFrame: function(frame)
{
var node = this._frameNodes.get(frame);
if (!node)
return;
if (node.parent)
node.parent.removeChild(node);
this._frameNodes.delete(frame);
for (var child of frame.childFrames)
this._discardFrame(child);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var targetNode = this._rootNode.child("target:" + target.id());
if (targetNode)
this._rootNode.removeChild(targetNode);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @param {!TreeElement} treeElement1
* @param {!TreeElement} treeElement2
* @return {number}
*/
WebInspector.NavigatorView._treeElementsCompare = function compare(treeElement1, treeElement2)
{
var typeWeight1 = WebInspector.NavigatorView._treeElementOrder(treeElement1);
var typeWeight2 = WebInspector.NavigatorView._treeElementOrder(treeElement2);
var result;
if (typeWeight1 > typeWeight2)
return 1;
if (typeWeight1 < typeWeight2)
return -1;
var title1 = /** @type {string} */(treeElement1.title);
var title2 = /** @type {string} */(treeElement2.title);
return title1.compareTo(title2);
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.NavigatorView} navigatorView
* @param {string} type
* @param {string} title
* @param {function(boolean)=} hoverCallback
*/
WebInspector.NavigatorFolderTreeElement = function(navigatorView, type, title, hoverCallback)
{
TreeElement.call(this, "", true);
this.listItemElement.classList.add("navigator-" + type + "-tree-item", "navigator-folder-tree-item");
this._nodeType = type;
this.title = title;
this.tooltip = title;
this.createIcon();
this._navigatorView = navigatorView;
this._hoverCallback = hoverCallback;
}
WebInspector.NavigatorFolderTreeElement.prototype = {
onpopulate: function()
{
this._node.populate();
},
onattach: function()
{
this.collapse();
this._node.onattach();
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
this.listItemElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
this.listItemElement.addEventListener("mouseleave", this._mouseLeave.bind(this), false);
},
/**
* @param {!WebInspector.NavigatorTreeNode} node
*/
setNode: function(node)
{
this._node = node;
var paths = [];
while (node && !node.isRoot()) {
paths.push(node._title);
node = node.parent;
}
paths.reverse();
this.tooltip = paths.join("/");
},
/**
* @param {!Event} event
*/
_handleContextMenuEvent: function(event)
{
if (!this._node)
return;
this.select();
this._navigatorView.handleFolderContextMenu(event, this._node);
},
/**
* @param {!Event} event
*/
_mouseMove: function(event)
{
if (this._hovered || !this._hoverCallback)
return;
this._hovered = true;
this._hoverCallback(true);
},
/**
* @param {!Event} event
*/
_mouseLeave: function(event)
{
if (!this._hoverCallback)
return;
this._hovered = false;
this._hoverCallback(false);
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.NavigatorView} navigatorView
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {string} title
*/
WebInspector.NavigatorSourceTreeElement = function(navigatorView, uiSourceCode, title)
{
TreeElement.call(this, "", false);
this._nodeType = WebInspector.NavigatorView.Types.File;
this.title = title;
this.listItemElement.classList.add("navigator-" + uiSourceCode.contentType().name() + "-tree-item", "navigator-file-tree-item");
this.tooltip = uiSourceCode.url();
this.createIcon();
this._navigatorView = navigatorView;
this._uiSourceCode = uiSourceCode;
}
WebInspector.NavigatorSourceTreeElement.prototype = {
/**
* @return {!WebInspector.UISourceCode}
*/
get uiSourceCode()
{
return this._uiSourceCode;
},
onattach: function()
{
this.listItemElement.draggable = true;
this.listItemElement.addEventListener("click", this._onclick.bind(this), false);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
this.listItemElement.addEventListener("mousedown", this._onmousedown.bind(this), false);
this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
},
_onmousedown: function(event)
{
if (event.which === 1) // Warm-up data for drag'n'drop
this._uiSourceCode.requestContent().then(callback.bind(this));
/**
* @param {?string} content
* @this {WebInspector.NavigatorSourceTreeElement}
*/
function callback(content)
{
this._warmedUpContent = content;
}
},
_shouldRenameOnMouseDown: function()
{
if (!this._uiSourceCode.canRename())
return false;
var isSelected = this === this.treeOutline.selectedTreeElement;
var document = this.treeOutline.element.ownerDocument;
var isFocused = this.treeOutline.element.isSelfOrAncestor(document.activeElement);
return isSelected && isFocused && !WebInspector.isBeingEdited(this.treeOutline.element);
},
selectOnMouseDown: function(event)
{
if (event.which !== 1 || !this._shouldRenameOnMouseDown()) {
TreeElement.prototype.selectOnMouseDown.call(this, event);
return;
}
setTimeout(rename.bind(this), 300);
/**
* @this {WebInspector.NavigatorSourceTreeElement}
*/
function rename()
{
if (this._shouldRenameOnMouseDown())
this._navigatorView.rename(this.uiSourceCode, false);
}
},
_ondragstart: function(event)
{
event.dataTransfer.setData("text/plain", this._warmedUpContent);
event.dataTransfer.effectAllowed = "copy";
return true;
},
/**
* @override
* @return {boolean}
*/
onspace: function()
{
this._navigatorView._sourceSelected(this.uiSourceCode, true);
return true;
},
/**
* @param {!Event} event
*/
_onclick: function(event)
{
this._navigatorView._sourceSelected(this.uiSourceCode, false);
},
/**
* @override
* @return {boolean}
*/
ondblclick: function(event)
{
var middleClick = event.button === 1;
this._navigatorView._sourceSelected(this.uiSourceCode, !middleClick);
return false;
},
/**
* @override
* @return {boolean}
*/
onenter: function()
{
this._navigatorView._sourceSelected(this.uiSourceCode, true);
return true;
},
/**
* @override
* @return {boolean}
*/
ondelete: function()
{
this._navigatorView.sourceDeleted(this.uiSourceCode);
return true;
},
/**
* @param {!Event} event
*/
_handleContextMenuEvent: function(event)
{
this.select();
this._navigatorView.handleFileContextMenu(event, this._uiSourceCode);
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @param {string} id
* @param {string} type
*/
WebInspector.NavigatorTreeNode = function(id, type)
{
this.id = id;
this._type = type;
/** @type {!Map.<string, !WebInspector.NavigatorTreeNode>} */
this._children = new Map();
}
WebInspector.NavigatorTreeNode.prototype = {
/**
* @return {!TreeElement}
*/
treeNode: function() { throw "Not implemented"; },
dispose: function() { },
/**
* @return {boolean}
*/
isRoot: function()
{
return false;
},
/**
* @return {boolean}
*/
hasChildren: function()
{
return true;
},
onattach: function()
{
},
populate: function()
{
if (this.isPopulated())
return;
if (this.parent)
this.parent.populate();
this._populated = true;
this.wasPopulated();
},
wasPopulated: function()
{
var children = this.children();
for (var i = 0; i < children.length; ++i)
this.treeNode().appendChild(/** @type {!TreeElement} */ (children[i].treeNode()));
},
/**
* @param {!WebInspector.NavigatorTreeNode} node
*/
didAddChild: function(node)
{
if (this.isPopulated())
this.treeNode().appendChild(/** @type {!TreeElement} */ (node.treeNode()));
},
/**
* @param {!WebInspector.NavigatorTreeNode} node
*/
willRemoveChild: function(node)
{
if (this.isPopulated())
this.treeNode().removeChild(/** @type {!TreeElement} */ (node.treeNode()));
},
/**
* @return {boolean}
*/
isPopulated: function()
{
return this._populated;
},
/**
* @return {boolean}
*/
isEmpty: function()
{
return !this._children.size;
},
/**
* @return {!Array.<!WebInspector.NavigatorTreeNode>}
*/
children: function()
{
return this._children.valuesArray();
},
/**
* @param {string} id
* @return {?WebInspector.NavigatorTreeNode}
*/
child: function(id)
{
return this._children.get(id) || null;
},
/**
* @param {!WebInspector.NavigatorTreeNode} node
*/
appendChild: function(node)
{
this._children.set(node.id, node);
node.parent = this;
this.didAddChild(node);
},
/**
* @param {!WebInspector.NavigatorTreeNode} node
*/
removeChild: function(node)
{
this.willRemoveChild(node);
this._children.remove(node.id);
delete node.parent;
node.dispose();
},
reset: function()
{
this._children.clear();
}
}
/**
* @constructor
* @extends {WebInspector.NavigatorTreeNode}
* @param {!WebInspector.NavigatorView} navigatorView
*/
WebInspector.NavigatorRootTreeNode = function(navigatorView)
{
WebInspector.NavigatorTreeNode.call(this, "", WebInspector.NavigatorView.Types.Root);
this._navigatorView = navigatorView;
}
WebInspector.NavigatorRootTreeNode.prototype = {
/**
* @override
* @return {boolean}
*/
isRoot: function()
{
return true;
},
/**
* @override
* @return {!TreeElement}
*/
treeNode: function()
{
return this._navigatorView._scriptsTree.rootElement();
},
__proto__: WebInspector.NavigatorTreeNode.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorTreeNode}
* @param {!WebInspector.NavigatorView} navigatorView
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
WebInspector.NavigatorUISourceCodeTreeNode = function(navigatorView, uiSourceCode)
{
WebInspector.NavigatorTreeNode.call(this, uiSourceCode.project().id() + ":" + uiSourceCode.url(), WebInspector.NavigatorView.Types.File);
this._navigatorView = navigatorView;
this._uiSourceCode = uiSourceCode;
this._treeElement = null;
}
WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
/**
* @return {!WebInspector.UISourceCode}
*/
uiSourceCode: function()
{
return this._uiSourceCode;
},
/**
* @override
* @return {!TreeElement}
*/
treeNode: function()
{
if (this._treeElement)
return this._treeElement;
this._treeElement = new WebInspector.NavigatorSourceTreeElement(this._navigatorView, this._uiSourceCode, "");
this.updateTitle();
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._titleChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
return this._treeElement;
},
/**
* @param {boolean=} ignoreIsDirty
*/
updateTitle: function(ignoreIsDirty)
{
if (!this._treeElement)
return;
var titleText = this._uiSourceCode.displayName();
if (!ignoreIsDirty && (this._uiSourceCode.isDirty() || this._uiSourceCode.hasUnsavedCommittedChanges()))
titleText = "*" + titleText;
this._treeElement.title = titleText;
var tooltip = this._uiSourceCode.url();
if (this._uiSourceCode.contentType().isFromSourceMap())
tooltip = WebInspector.UIString("%s (from source map)", this._uiSourceCode.displayName());
this._treeElement.tooltip = tooltip;
},
/**
* @override
* @return {boolean}
*/
hasChildren: function()
{
return false;
},
dispose: function()
{
if (!this._treeElement)
return;
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._titleChanged, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
},
_titleChanged: function(event)
{
this.updateTitle();
},
_workingCopyChanged: function(event)
{
this.updateTitle();
},
_workingCopyCommitted: function(event)
{
this.updateTitle();
},
/**
* @param {boolean=} select
*/
reveal: function(select)
{
this.parent.populate();
this.parent.treeNode().expand();
this._treeElement.reveal();
if (select)
this._treeElement.select(true);
},
/**
* @param {function(boolean)=} callback
*/
rename: function(callback)
{
if (!this._treeElement)
return;
// Tree outline should be marked as edited as well as the tree element to prevent search from starting.
var treeOutlineElement = this._treeElement.treeOutline.element;
WebInspector.markBeingEdited(treeOutlineElement, true);
/**
* @param {!Element} element
* @param {string} newTitle
* @param {string} oldTitle
* @this {WebInspector.NavigatorUISourceCodeTreeNode}
*/
function commitHandler(element, newTitle, oldTitle)
{
if (newTitle !== oldTitle) {
this._treeElement.title = newTitle;
this._uiSourceCode.rename(newTitle, renameCallback.bind(this));
return;
}
afterEditing.call(this, true);
}
/**
* @param {boolean} success
* @this {WebInspector.NavigatorUISourceCodeTreeNode}
*/
function renameCallback(success)
{
if (!success) {
WebInspector.markBeingEdited(treeOutlineElement, false);
this.updateTitle();
this.rename(callback);
return;
}
afterEditing.call(this, true);
}
/**
* @param {boolean} committed
* @this {WebInspector.NavigatorUISourceCodeTreeNode}
*/
function afterEditing(committed)
{
WebInspector.markBeingEdited(treeOutlineElement, false);
this.updateTitle();
this._treeElement.treeOutline.focus();
if (callback)
callback(committed);
}
this.updateTitle(true);
this._treeElement.startEditingTitle(new WebInspector.InplaceEditor.Config(commitHandler.bind(this), afterEditing.bind(this, false)));
},
__proto__: WebInspector.NavigatorTreeNode.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorTreeNode}
* @param {!WebInspector.NavigatorView} navigatorView
* @param {?WebInspector.Project} project
* @param {string} id
* @param {string} type
* @param {string} folderPath
* @param {string} title
*/
WebInspector.NavigatorFolderTreeNode = function(navigatorView, project, id, type, folderPath, title)
{
WebInspector.NavigatorTreeNode.call(this, id, type);
this._navigatorView = navigatorView;
this._project = project;
this._folderPath = folderPath;
this._title = title;
}
WebInspector.NavigatorFolderTreeNode.prototype = {
/**
* @override
* @return {!TreeElement}
*/
treeNode: function()
{
if (this._treeElement)
return this._treeElement;
this._treeElement = this._createTreeElement(this._title, this);
return this._treeElement;
},
/**
* @return {!TreeElement}
*/
_createTreeElement: function(title, node)
{
if (this._project.type() !== WebInspector.projectTypes.FileSystem) {
try {
title = decodeURI(title);
} catch (e) {
}
}
var treeElement = new WebInspector.NavigatorFolderTreeElement(this._navigatorView, this._type, title);
treeElement.setNode(node);
return treeElement;
},
wasPopulated: function()
{
if (!this._treeElement || this._treeElement._node !== this)
return;
this._addChildrenRecursive();
},
_addChildrenRecursive: function()
{
var children = this.children();
for (var i = 0; i < children.length; ++i) {
var child = children[i];
this.didAddChild(child);
if (child instanceof WebInspector.NavigatorFolderTreeNode)
child._addChildrenRecursive();
}
},
_shouldMerge: function(node)
{
return this._type !== WebInspector.NavigatorView.Types.Domain && node instanceof WebInspector.NavigatorFolderTreeNode;
},
didAddChild: function(node)
{
function titleForNode(node)
{
return node._title;
}
if (!this._treeElement)
return;
var children = this.children();
if (children.length === 1 && this._shouldMerge(node)) {
node._isMerged = true;
this._treeElement.title = this._treeElement.title + "/" + node._title;
node._treeElement = this._treeElement;
this._treeElement.setNode(node);
return;
}
var oldNode;
if (children.length === 2)
oldNode = children[0] !== node ? children[0] : children[1];
if (oldNode && oldNode._isMerged) {
delete oldNode._isMerged;
var mergedToNodes = [];
mergedToNodes.push(this);
var treeNode = this;
while (treeNode._isMerged) {
treeNode = treeNode.parent;
mergedToNodes.push(treeNode);
}
mergedToNodes.reverse();
var titleText = mergedToNodes.map(titleForNode).join("/");
var nodes = [];
treeNode = oldNode;
do {
nodes.push(treeNode);
children = treeNode.children();
treeNode = children.length === 1 ? children[0] : null;
} while (treeNode && treeNode._isMerged);
if (!this.isPopulated()) {
this._treeElement.title = titleText;
this._treeElement.setNode(this);
for (var i = 0; i < nodes.length; ++i) {
delete nodes[i]._treeElement;
delete nodes[i]._isMerged;
}
return;
}
var oldTreeElement = this._treeElement;
var treeElement = this._createTreeElement(titleText, this);
for (var i = 0; i < mergedToNodes.length; ++i)
mergedToNodes[i]._treeElement = treeElement;
oldTreeElement.parent.appendChild(treeElement);
oldTreeElement.setNode(nodes[nodes.length - 1]);
oldTreeElement.title = nodes.map(titleForNode).join("/");
oldTreeElement.parent.removeChild(oldTreeElement);
this._treeElement.appendChild(oldTreeElement);
if (oldTreeElement.expanded)
treeElement.expand();
}
if (this.isPopulated())
this._treeElement.appendChild(node.treeNode());
},
/**
* @override
* @param {!WebInspector.NavigatorTreeNode} node
*/
willRemoveChild: function(node)
{
if (node._isMerged || !this.isPopulated())
return;
this._treeElement.removeChild(node._treeElement);
},
__proto__: WebInspector.NavigatorTreeNode.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorTreeNode}
* @param {!WebInspector.NavigatorView} navigatorView
* @param {!WebInspector.Project} project
* @param {string} id
* @param {string} type
* @param {string} title
*/
WebInspector.NavigatorGroupTreeNode = function(navigatorView, project, id, type, title)
{
WebInspector.NavigatorTreeNode.call(this, id, type);
this._project = project;
this._navigatorView = navigatorView;
this._title = title;
this.populate();
}
WebInspector.NavigatorGroupTreeNode.prototype = {
/**
* @param {function(boolean)} hoverCallback
*/
setHoverCallback: function(hoverCallback)
{
this._hoverCallback = hoverCallback;
},
/**
* @override
* @return {!TreeElement}
*/
treeNode: function()
{
if (this._treeElement)
return this._treeElement;
this._treeElement = new WebInspector.NavigatorFolderTreeElement(this._navigatorView, this._type, this._title, this._hoverCallback);
this._treeElement.setNode(this);
return this._treeElement;
},
__proto__: WebInspector.NavigatorTreeNode.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 2 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
*/
WebInspector.ObjectEventListenersSidebarPane = function()
{
WebInspector.SidebarPane.call(this, "Event Listeners");
this.element.classList.add("event-listeners-sidebar-pane");
this._refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
this._refreshButton.addEventListener("click", this._refreshClick.bind(this));
this._refreshButton.setEnabled(false);
this.toolbar().appendToolbarItem(this._refreshButton);
this._eventListenersView = new WebInspector.EventListenersView(this.element);
}
WebInspector.ObjectEventListenersSidebarPane._objectGroupName = "object-event-listeners-sidebar-pane";
WebInspector.ObjectEventListenersSidebarPane.prototype = {
update: function()
{
if (this._lastRequestedContext) {
this._lastRequestedContext.target().runtimeAgent().releaseObjectGroup(WebInspector.ObjectEventListenersSidebarPane._objectGroupName);
delete this._lastRequestedContext;
}
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!executionContext) {
this._eventListenersView.reset();
this._eventListenersView.addEmptyHolderIfNeeded();
return;
}
this._lastRequestedContext = executionContext;
Promise.all([this._windowObjectInContext(executionContext)]).then(this._eventListenersView.addObjects.bind(this._eventListenersView));
},
wasShown: function()
{
WebInspector.SidebarPane.prototype.wasShown.call(this);
WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.update, this);
this._refreshButton.setEnabled(true);
this.update();
},
willHide: function()
{
WebInspector.SidebarPane.prototype.willHide.call(this);
WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionContext, this.update, this);
this._refreshButton.setEnabled(false);
},
/**
* @param {!WebInspector.ExecutionContext} executionContext
* @return {!Promise<!WebInspector.RemoteObject>} object
*/
_windowObjectInContext: function(executionContext)
{
return new Promise(windowObjectInContext);
/**
* @param {function(?)} fulfill
* @param {function(*)} reject
*/
function windowObjectInContext(fulfill, reject)
{
executionContext.evaluate("self", WebInspector.ObjectEventListenersSidebarPane._objectGroupName, false, true, false, false, false, mycallback);
/**
* @param {?WebInspector.RemoteObject} object
*/
function mycallback(object)
{
if (object)
fulfill(object);
else
reject(null);
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_refreshClick: function(event)
{
event.consume();
this.update();
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 2 | /*
* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.FilteredUISourceCodeListDelegate}
* @param {!WebInspector.SourcesView} sourcesView
* @param {!Map.<!WebInspector.UISourceCode, number>} defaultScores
* @param {!Array<string>} history
*/
WebInspector.OpenResourceDialog = function(sourcesView, defaultScores, history)
{
WebInspector.FilteredUISourceCodeListDelegate.call(this, defaultScores, history);
this._sourcesView = sourcesView;
}
WebInspector.OpenResourceDialog.prototype = {
/**
* @override
* @param {?WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
* @param {number=} columnNumber
*/
uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
if (!uiSourceCode)
uiSourceCode = this._sourcesView.currentUISourceCode();
if (!uiSourceCode)
return;
this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
},
/**
* @override
* @param {string} query
* @return {boolean}
*/
shouldShowMatchingItems: function(query)
{
return !query.startsWith(":");
},
/**
* @override
* @param {!WebInspector.Project} project
* @return {boolean}
*/
filterProject: function(project)
{
return !WebInspector.Project.isServiceProject(project);
},
__proto__: WebInspector.FilteredUISourceCodeListDelegate.prototype
}
/**
* @param {!WebInspector.SourcesView} sourcesView
* @param {string} query
* @param {!Map.<!WebInspector.UISourceCode, number>} defaultScores
* @param {!Array<string>} history
*/
WebInspector.OpenResourceDialog.show = function(sourcesView, query, defaultScores, history)
{
var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.OpenResourceDialog(sourcesView, defaultScores, history), true);
filteredItemSelectionDialog.showAsDialog();
filteredItemSelectionDialog.setQuery(query);
}
/**
* @constructor
* @extends {WebInspector.FilteredUISourceCodeListDelegate}
* @param {!Array.<string>} types
* @param {function(?WebInspector.UISourceCode)} callback
*/
WebInspector.SelectUISourceCodeForProjectTypesDialog = function(types, callback)
{
this._types = types;
WebInspector.FilteredUISourceCodeListDelegate.call(this);
this._callback = callback;
}
WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = {
/**
* @override
* @param {?WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
* @param {number=} columnNumber
*/
uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
this._callback(uiSourceCode);
},
/**
* @override
* @param {!WebInspector.Project} project
* @return {boolean}
*/
filterProject: function(project)
{
return this._types.indexOf(project.type()) !== -1;
},
__proto__: WebInspector.FilteredUISourceCodeListDelegate.prototype
}
/**
* @param {string} name
* @param {!Array.<string>} types
* @param {function(?WebInspector.UISourceCode)} callback
*/
WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback)
{
var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback), true);
filteredItemSelectionDialog.showAsDialog();
filteredItemSelectionDialog.setQuery(name);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | 2 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.RevisionHistoryView = function()
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("sources/revisionHistory.css");
this.element.classList.add("revision-history-drawer");
this._uiSourceCodeItems = new Map();
this._treeOutline = new TreeOutline();
this._treeOutline.element.classList.add("outline-disclosure");
this.element.appendChild(this._treeOutline.element);
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @this {WebInspector.RevisionHistoryView}
*/
function populateRevisions(uiSourceCode)
{
if (uiSourceCode.history.length)
this._createUISourceCodeItem(uiSourceCode);
}
WebInspector.workspace.uiSourceCodes().forEach(populateRevisions.bind(this));
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, this._revisionAdded, this);
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
WebInspector.RevisionHistoryView.showHistory = function(uiSourceCode)
{
/**
* @param {?WebInspector.Widget} view
*/
function revealSource(view)
{
console.assert(view && view instanceof WebInspector.RevisionHistoryView);
var historyView = /** @type {!WebInspector.RevisionHistoryView} */(view);
historyView._revealUISourceCode(uiSourceCode);
}
WebInspector.inspectorView.showViewInDrawer("sources.history").then(revealSource);
}
WebInspector.RevisionHistoryView.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_createUISourceCodeItem: function(uiSourceCode)
{
var uiSourceCodeItem = new TreeElement(uiSourceCode.displayName(), true);
uiSourceCodeItem.selectable = false;
// Insert in sorted order
var rootElement = this._treeOutline.rootElement();
for (var i = 0; i < rootElement.childCount(); ++i) {
if (rootElement.childAt(i).title.localeCompare(uiSourceCode.displayName()) > 0) {
rootElement.insertChild(uiSourceCodeItem, i);
break;
}
}
if (i === rootElement.childCount())
rootElement.appendChild(uiSourceCodeItem);
this._uiSourceCodeItems.set(uiSourceCode, uiSourceCodeItem);
var revisionCount = uiSourceCode.history.length;
for (var i = revisionCount - 1; i >= 0; --i) {
var revision = uiSourceCode.history[i];
var historyItem = new WebInspector.RevisionHistoryTreeElement(revision, uiSourceCode.history[i - 1], i !== revisionCount - 1);
uiSourceCodeItem.appendChild(historyItem);
}
var linkItem = new TreeElement();
linkItem.selectable = false;
uiSourceCodeItem.appendChild(linkItem);
var revertToOriginal = linkItem.listItemElement.createChild("span", "revision-history-link revision-history-link-row");
revertToOriginal.textContent = WebInspector.UIString("apply original content");
revertToOriginal.addEventListener("click", this._revertToOriginal.bind(this, uiSourceCode));
var clearHistoryElement = uiSourceCodeItem.listItemElement.createChild("span", "revision-history-link");
clearHistoryElement.textContent = WebInspector.UIString("revert");
clearHistoryElement.addEventListener("click", this._clearHistory.bind(this, uiSourceCode));
return uiSourceCodeItem;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_revertToOriginal: function(uiSourceCode)
{
uiSourceCode.revertToOriginal();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_clearHistory: function(uiSourceCode)
{
uiSourceCode.revertAndClearHistory(this._removeUISourceCode.bind(this));
},
_revisionAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
var uiSourceCodeItem = this._uiSourceCodeItems.get(uiSourceCode);
if (!uiSourceCodeItem) {
uiSourceCodeItem = this._createUISourceCodeItem(uiSourceCode);
return;
}
var historyLength = uiSourceCode.history.length;
var historyItem = new WebInspector.RevisionHistoryTreeElement(uiSourceCode.history[historyLength - 1], uiSourceCode.history[historyLength - 2], false);
if (uiSourceCodeItem.firstChild())
uiSourceCodeItem.firstChild().allowRevert();
uiSourceCodeItem.insertChild(historyItem, 0);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_revealUISourceCode: function(uiSourceCode)
{
var uiSourceCodeItem = this._uiSourceCodeItems.get(uiSourceCode);
if (uiSourceCodeItem) {
uiSourceCodeItem.reveal();
uiSourceCodeItem.expand();
}
},
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._removeUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeUISourceCode: function(uiSourceCode)
{
var uiSourceCodeItem = this._uiSourceCodeItems.get(uiSourceCode);
if (!uiSourceCodeItem)
return;
this._treeOutline.removeChild(uiSourceCodeItem);
this._uiSourceCodeItems.remove(uiSourceCode);
},
_projectRemoved: function(event)
{
var project = event.data;
project.uiSourceCodes().forEach(this._removeUISourceCode.bind(this));
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.Revision} revision
* @param {!WebInspector.Revision} baseRevision
* @param {boolean} allowRevert
*/
WebInspector.RevisionHistoryTreeElement = function(revision, baseRevision, allowRevert)
{
TreeElement.call(this, revision.timestamp.toLocaleTimeString(), true);
this.selectable = false;
this._revision = revision;
this._baseRevision = baseRevision;
this._revertElement = createElement("span");
this._revertElement.className = "revision-history-link";
this._revertElement.textContent = WebInspector.UIString("apply revision content");
this._revertElement.addEventListener("click", event => {this._revision.revertToThis();}, false);
if (!allowRevert)
this._revertElement.classList.add("hidden");
}
WebInspector.RevisionHistoryTreeElement.prototype = {
onattach: function()
{
this.listItemElement.classList.add("revision-history-revision");
},
onpopulate: function()
{
this.listItemElement.appendChild(this._revertElement);
this.childrenListElement.classList.add("source-code");
Promise.all([
this._baseRevision ? this._baseRevision.requestContent() : this._revision.uiSourceCode.requestOriginalContent(),
this._revision.requestContent()
]).spread(diff.bind(this));
/**
* @param {?string} baseContent
* @param {?string} newContent
* @this {WebInspector.RevisionHistoryTreeElement}
*/
function diff(baseContent, newContent)
{
var baseLines = baseContent.split("\n");
var newLines = newContent.split("\n");
var opcodes = WebInspector.Diff.lineDiff(baseLines, newLines);
var lastWasSeparator = false;
var baseLineNumber = 0;
var newLineNumber = 0;
for (var idx = 0; idx < opcodes.length; idx++) {
var code = opcodes[idx][0];
var rowCount = opcodes[idx][1].length;
if (code === WebInspector.Diff.Operation.Equal) {
baseLineNumber += rowCount;
newLineNumber += rowCount;
if (!lastWasSeparator)
this._createLine(null, null, " \u2026", "separator");
lastWasSeparator = true;
} else if (code === WebInspector.Diff.Operation.Delete) {
lastWasSeparator = false;
for (var i = 0; i < rowCount; ++i)
this._createLine(baseLineNumber + i, null, baseLines[baseLineNumber + i], "removed");
baseLineNumber += rowCount;
} else if (code === WebInspector.Diff.Operation.Insert) {
lastWasSeparator = false;
for (var i = 0; i < rowCount; ++i)
this._createLine(null, newLineNumber + i, newLines[newLineNumber + i], "added");
newLineNumber += rowCount;
}
}
}
},
oncollapse: function()
{
this._revertElement.remove();
},
/**
* @param {?number} baseLineNumber
* @param {?number} newLineNumber
* @param {string} lineContent
* @param {string} changeType
*/
_createLine: function(baseLineNumber, newLineNumber, lineContent, changeType)
{
var child = new TreeElement();
child.selectable = false;
this.appendChild(child);
function appendLineNumber(lineNumber)
{
var numberString = lineNumber !== null ? numberToStringWithSpacesPadding(lineNumber + 1, 4) : spacesPadding(4);
var lineNumberSpan = createElement("span");
lineNumberSpan.classList.add("webkit-line-number");
lineNumberSpan.textContent = numberString;
child.listItemElement.appendChild(lineNumberSpan);
}
appendLineNumber(baseLineNumber);
appendLineNumber(newLineNumber);
var contentSpan = createElement("span");
contentSpan.textContent = lineContent;
child.listItemElement.appendChild(contentSpan);
child.listItemElement.classList.add("revision-history-line");
contentSpan.classList.add("revision-history-line-" + changeType);
},
allowRevert: function()
{
this._revertElement.classList.remove("hidden");
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SidebarPane}
*/
WebInspector.ScopeChainSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Scope"));
this._expandController = new WebInspector.ObjectPropertiesSectionExpandController();
}
WebInspector.ScopeChainSidebarPane._pathSymbol = Symbol("path");
WebInspector.ScopeChainSidebarPane.prototype = {
/**
* @param {?WebInspector.DebuggerModel.CallFrame} callFrame
*/
update: function(callFrame)
{
this.element.removeChildren();
if (!callFrame) {
var infoElement = createElement("div");
infoElement.className = "info";
infoElement.textContent = WebInspector.UIString("Not Paused");
this.element.appendChild(infoElement);
return;
}
var foundLocalScope = false;
var scopeChain = callFrame.scopeChain();
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
var emptyPlaceholder = null;
var extraProperties = [];
switch (scope.type()) {
case DebuggerAgent.ScopeType.Local:
foundLocalScope = true;
title = WebInspector.UIString("Local");
emptyPlaceholder = WebInspector.UIString("No Variables");
var thisObject = callFrame.thisObject();
if (thisObject)
extraProperties.push(new WebInspector.RemoteObjectProperty("this", thisObject));
if (i == 0) {
var details = callFrame.debuggerModel.debuggerPausedDetails();
var exception = details.exception();
if (exception)
extraProperties.push(new WebInspector.RemoteObjectProperty(WebInspector.UIString.capitalize("Exception"), exception, undefined, undefined, undefined, undefined, undefined, true));
var returnValue = callFrame.returnValue();
if (returnValue)
extraProperties.push(new WebInspector.RemoteObjectProperty(WebInspector.UIString.capitalize("Return ^value"), returnValue, undefined, undefined, undefined, undefined, undefined, true));
}
break;
case DebuggerAgent.ScopeType.Closure:
var scopeName = scope.name();
if (scopeName)
title = WebInspector.UIString("Closure (%s)", WebInspector.beautifyFunctionName(scopeName));
else
title = WebInspector.UIString("Closure");
emptyPlaceholder = WebInspector.UIString("No Variables");
break;
case DebuggerAgent.ScopeType.Catch:
title = WebInspector.UIString("Catch");
break;
case DebuggerAgent.ScopeType.Block:
title = WebInspector.UIString("Block");
break;
case DebuggerAgent.ScopeType.Script:
title = WebInspector.UIString("Script");
break;
case DebuggerAgent.ScopeType.With:
title = WebInspector.UIString("With Block");
break;
case DebuggerAgent.ScopeType.Global:
title = WebInspector.UIString("Global");
break;
}
var subtitle = scope.description();
if (!title || title === subtitle)
subtitle = undefined;
var titleElement = createElementWithClass("div", "scope-chain-sidebar-pane-section-header");
titleElement.createChild("div", "scope-chain-sidebar-pane-section-subtitle").textContent = subtitle;
titleElement.createChild("div", "scope-chain-sidebar-pane-section-title").textContent = title;
var section = new WebInspector.ObjectPropertiesSection(WebInspector.SourceMapNamesResolver.resolveScopeInObject(scope), titleElement, emptyPlaceholder, true, extraProperties);
this._expandController.watchSection(title + (subtitle ? ":" + subtitle : ""), section);
if (scope.type() === DebuggerAgent.ScopeType.Global)
section.objectTreeElement().collapse();
else if (!foundLocalScope || scope.type() === DebuggerAgent.ScopeType.Local)
section.objectTreeElement().expand();
section.element.classList.add("scope-chain-sidebar-pane-section");
this.element.appendChild(section.element);
}
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | 2 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.Formatter = function() { } /** * @param {!WebInspector.ResourceType} contentType * @param {string} mimeType * @param {string} content * @param {function(string, !WebInspector.FormatterSourceMapping)} callback */ WebInspector.Formatter.format = function(contentType, mimeType, content, callback) { if (contentType.isDocumentOrScriptOrStyleSheet()) new WebInspector.ScriptFormatter(mimeType, content, callback); else new WebInspector.IdentityFormatter(mimeType, content, callback); } /** * @param {!Array.<number>} lineEndings * @param {number} lineNumber * @param {number} columnNumber * @return {number} */ WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber) { var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0; return position + columnNumber; } /** * @param {!Array.<number>} lineEndings * @param {number} position * @return {!Array.<number>} */ WebInspector.Formatter.positionToLocation = function(lineEndings, position) { var lineNumber = lineEndings.upperBound(position - 1); if (!lineNumber) var columnNumber = position; else var columnNumber = position - lineEndings[lineNumber - 1] - 1; return [lineNumber, columnNumber]; } /** * @constructor * @implements {WebInspector.Formatter} * @param {string} mimeType * @param {string} content * @param {function(string, !WebInspector.FormatterSourceMapping)} callback */ WebInspector.ScriptFormatter = function(mimeType, content, callback) { content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''); this._callback = callback; this._originalContent = content; this._worker = new WorkerRuntime.Worker("formatter_worker"); this._worker.onmessage = this._didFormatContent.bind(this); var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.moduleSetting("textEditorIndent").get() }; this._worker.postMessage({ method: "format", params: parameters }); } WebInspector.ScriptFormatter.prototype = { /** * @param {!MessageEvent} event */ _didFormatContent: function(event) { this._worker.terminate(); var originalContent = this._originalContent; var formattedContent = event.data.content; var mapping = event.data["mapping"]; var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.computeLineEndings(), formattedContent.computeLineEndings(), mapping); this._callback(formattedContent, sourceMapping); } } /** * @constructor * @implements {WebInspector.Formatter} * @param {string} mimeType * @param {string} content * @param {function(string, !WebInspector.FormatterSourceMapping)} callback */ WebInspector.IdentityFormatter = function(mimeType, content, callback) { callback(content, new WebInspector.IdentityFormatterSourceMapping()); } /** * @typedef {{original: !Array.<number>, formatted: !Array.<number>}} */ WebInspector.FormatterMappingPayload; /** * @interface */ WebInspector.FormatterSourceMapping = function() { } WebInspector.FormatterSourceMapping.prototype = { /** * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ originalToFormatted: function(lineNumber, columnNumber) { }, /** * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ formattedToOriginal: function(lineNumber, columnNumber) { } } /** * @constructor * @implements {WebInspector.FormatterSourceMapping} */ WebInspector.IdentityFormatterSourceMapping = function() { } WebInspector.IdentityFormatterSourceMapping.prototype = { /** * @override * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ originalToFormatted: function(lineNumber, columnNumber) { return [lineNumber, columnNumber || 0]; }, /** * @override * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ formattedToOriginal: function(lineNumber, columnNumber) { return [lineNumber, columnNumber || 0]; } } /** * @constructor * @implements {WebInspector.FormatterSourceMapping} * @param {!Array.<number>} originalLineEndings * @param {!Array.<number>} formattedLineEndings * @param {!WebInspector.FormatterMappingPayload} mapping */ WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping) { this._originalLineEndings = originalLineEndings; this._formattedLineEndings = formattedLineEndings; this._mapping = mapping; } WebInspector.FormatterSourceMappingImpl.prototype = { /** * @override * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ originalToFormatted: function(lineNumber, columnNumber) { var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0); var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0); return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition); }, /** * @override * @param {number} lineNumber * @param {number=} columnNumber * @return {!Array.<number>} */ formattedToOriginal: function(lineNumber, columnNumber) { var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0); var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition); return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0); }, /** * @param {!Array.<number>} positions1 * @param {!Array.<number>} positions2 * @param {number} position * @return {number} */ _convertPosition: function(positions1, positions2, position) { var index = positions1.upperBound(position) - 1; var convertedPosition = positions2[index] + position - positions1[index]; if (index < positions2.length - 1 && convertedPosition > positions2[index + 1]) convertedPosition = positions2[index + 1]; return convertedPosition; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | 2 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.DebuggerSourceMapping}
* @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.ScriptFormatterEditorAction} editorAction
*/
WebInspector.FormatterScriptMapping = function(debuggerModel, editorAction)
{
this._debuggerModel = debuggerModel;
this._editorAction = editorAction;
}
WebInspector.FormatterScriptMapping.prototype = {
/**
* @override
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @return {?WebInspector.UILocation}
*/
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
var script = debuggerModelLocation.script();
var uiSourceCode = this._editorAction._uiSourceCodes.get(script);
if (!uiSourceCode)
return null;
var formatData = this._editorAction._formatData.get(uiSourceCode);
if (!formatData)
return null;
var mapping = formatData.mapping;
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
var formattedLocation = mapping.originalToFormatted(lineNumber, columnNumber);
return uiSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.DebuggerModel.Location}
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var formatData = this._editorAction._formatData.get(uiSourceCode);
if (!formatData)
return null;
var originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
for (var i = 0; i < formatData.scripts.length; ++i) {
if (formatData.scripts[i].debuggerModel === this._debuggerModel)
return this._debuggerModel.createRawLocation(formatData.scripts[i], originalLocation[0], originalLocation[1]);
}
return null;
},
/**
* @override
* @return {boolean}
*/
isIdentity: function()
{
return false;
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @return {boolean}
*/
uiLineHasMapping: function(uiSourceCode, lineNumber)
{
return true;
}
}
/**
* @constructor
* @param {string} projectId
* @param {string} path
* @param {!WebInspector.FormatterSourceMapping} mapping
* @param {!Array.<!WebInspector.Script>} scripts
*/
WebInspector.FormatterScriptMapping.FormatData = function(projectId, path, mapping, scripts)
{
this.projectId = projectId;
this.path = path;
this.mapping = mapping;
this.scripts = scripts;
}
/**
* @constructor
* @implements {WebInspector.SourcesView.EditorAction}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.ScriptFormatterEditorAction = function()
{
this._projectId = "formatter:";
this._project = new WebInspector.ContentProviderBasedProject(WebInspector.workspace, this._projectId, WebInspector.projectTypes.Formatter, "formatter");
/** @type {!Map.<!WebInspector.Script, !WebInspector.UISourceCode>} */
this._uiSourceCodes = new Map();
/** @type {!Map.<string, string>} */
this._formattedPaths = new Map();
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.FormatterScriptMapping.FormatData>} */
this._formatData = new Map();
/** @type {!Set.<string>} */
this._pathsToFormatOnLoad = new Set();
/** @type {!Map.<!WebInspector.Target, !WebInspector.FormatterScriptMapping>} */
this._scriptMappingByTarget = new Map();
this._workspace = WebInspector.workspace;
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ScriptFormatterEditorAction.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return;
this._scriptMappingByTarget.set(target, new WebInspector.FormatterScriptMapping(debuggerModel, this));
debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return;
this._scriptMappingByTarget.remove(target);
this._cleanForTarget(target);
debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
},
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._updateButton(uiSourceCode);
var path = uiSourceCode.project().id() + ":" + uiSourceCode.url();
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
if (this._isFormatableScript(uiSourceCode) && networkURL && this._pathsToFormatOnLoad.has(path) && !this._formattedPaths.get(path))
this._formatUISourceCodeScript(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_editorClosed: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
if (wasSelected)
this._updateButton(null);
this._discardFormattedUISourceCodeScript(uiSourceCode);
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
*/
_updateButton: function(uiSourceCode)
{
this._button.element.classList.toggle("hidden", !this._isFormatableScript(uiSourceCode));
},
/**
* @override
* @param {!WebInspector.SourcesView} sourcesView
* @return {!WebInspector.ToolbarButton}
*/
button: function(sourcesView)
{
if (this._button)
return this._button;
this._sourcesView = sourcesView;
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
this._button = new WebInspector.ToolbarButton(WebInspector.UIString("Pretty print"), "format-toolbar-item");
this._button.addEventListener("click", this._toggleFormatScriptSource, this);
this._updateButton(sourcesView.currentUISourceCode());
return this._button;
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
_isFormatableScript: function(uiSourceCode)
{
if (!uiSourceCode)
return false;
var supportedProjectTypes = [WebInspector.projectTypes.Network, WebInspector.projectTypes.Debugger, WebInspector.projectTypes.ContentScripts];
if (supportedProjectTypes.indexOf(uiSourceCode.project().type()) === -1)
return false;
return uiSourceCode.contentType().hasScripts();
},
_toggleFormatScriptSource: function()
{
var uiSourceCode = this._sourcesView.currentUISourceCode();
if (this._isFormatableScript(uiSourceCode))
this._formatUISourceCodeScript(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.UISourceCode} formattedUISourceCode
* @param {!WebInspector.FormatterSourceMapping} mapping
* @private
*/
_showIfNeeded: function(uiSourceCode, formattedUISourceCode, mapping)
{
if (uiSourceCode !== this._sourcesView.currentUISourceCode())
return;
var sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
var start = [0, 0];
if (sourceFrame) {
var selection = sourceFrame.selection();
start = mapping.originalToFormatted(selection.startLine, selection.startColumn);
}
this._sourcesView.showSourceLocation(formattedUISourceCode, start[0], start[1]);
this._updateButton(formattedUISourceCode);
},
/**
* @param {!WebInspector.UISourceCode} formattedUISourceCode
*/
_discardFormattedUISourceCodeScript: function(formattedUISourceCode)
{
var formatData = this._formatData.get(formattedUISourceCode);
if (!formatData)
return;
this._formatData.remove(formattedUISourceCode);
var path = formatData.projectId + ":" + formatData.path;
this._formattedPaths.remove(path);
this._pathsToFormatOnLoad.delete(path);
for (var i = 0; i < formatData.scripts.length; ++i) {
this._uiSourceCodes.remove(formatData.scripts[i]);
WebInspector.debuggerWorkspaceBinding.popSourceMapping(formatData.scripts[i]);
}
this._project.removeFile(formattedUISourceCode.url());
},
/**
* @param {!WebInspector.Target} target
*/
_cleanForTarget: function(target)
{
var uiSourceCodes = this._formatData.keysArray();
for (var i = 0; i < uiSourceCodes.length; ++i) {
WebInspector.debuggerWorkspaceBinding.setSourceMapping(target, uiSourceCodes[i], null);
var formatData = this._formatData.get(uiSourceCodes[i]);
var scripts = [];
for (var j = 0; j < formatData.scripts.length; ++j) {
if (formatData.scripts[j].target() === target)
this._uiSourceCodes.remove(formatData.scripts[j]);
else
scripts.push(formatData.scripts[j]);
}
if (scripts.length)
formatData.scripts = scripts;
else {
this._formattedPaths.remove(formatData.projectId + ":" + formatData.path);
this._formatData.remove(uiSourceCodes[i]);
this._project.removeFile(uiSourceCodes[i].url());
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerReset: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
this._cleanForTarget(debuggerModel.target());
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!Array.<!WebInspector.Script>}
*/
_scriptsForUISourceCode: function(uiSourceCode)
{
/**
* @param {!WebInspector.Script} script
* @return {boolean}
*/
function isInlineScript(script)
{
return script.isInlineScript() && !script.hasSourceURL;
}
if (uiSourceCode.contentType() === WebInspector.resourceTypes.Document) {
var scripts = [];
var debuggerModels = WebInspector.DebuggerModel.instances();
for (var i = 0; i < debuggerModels.length; ++i) {
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
scripts.pushAll(debuggerModels[i].scriptsForSourceURL(networkURL));
}
return scripts.filter(isInlineScript);
}
if (uiSourceCode.contentType().isScript()) {
var rawLocations = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0);
return rawLocations.map(function(rawLocation) { return rawLocation.script(); });
}
return [];
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_formatUISourceCodeScript: function(uiSourceCode)
{
var formattedPath = this._formattedPaths.get(uiSourceCode.project().id() + ":" + uiSourceCode.url());
if (formattedPath) {
var uiSourceCodePath = formattedPath;
var formattedUISourceCode = this._workspace.uiSourceCode(this._projectId, uiSourceCodePath);
var formatData = formattedUISourceCode ? this._formatData.get(formattedUISourceCode) : null;
if (formatData)
this._showIfNeeded(uiSourceCode, /** @type {!WebInspector.UISourceCode} */ (formattedUISourceCode), formatData.mapping);
return;
}
uiSourceCode.requestContent().then(contentLoaded.bind(this));
/**
* @this {WebInspector.ScriptFormatterEditorAction}
* @param {?string} content
*/
function contentLoaded(content)
{
var highlighterType = WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode);
WebInspector.Formatter.format(uiSourceCode.contentType(), highlighterType, content || "", innerCallback.bind(this));
}
/**
* @this {WebInspector.ScriptFormatterEditorAction}
* @param {string} formattedContent
* @param {!WebInspector.FormatterSourceMapping} formatterMapping
*/
function innerCallback(formattedContent, formatterMapping)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
var contentProvider = new WebInspector.StaticContentProvider(uiSourceCode.contentType(), formattedContent);
var formattedUISourceCode = this._project.addContentProvider(uiSourceCode.url() + ":formatted", contentProvider);
var formattedPath = formattedUISourceCode.url();
var formatData = new WebInspector.FormatterScriptMapping.FormatData(uiSourceCode.project().id(), uiSourceCode.url(), formatterMapping, scripts);
this._formatData.set(formattedUISourceCode, formatData);
var path = uiSourceCode.project().id() + ":" + uiSourceCode.url();
this._formattedPaths.set(path, formattedPath);
this._pathsToFormatOnLoad.add(path);
for (var i = 0; i < scripts.length; ++i) {
this._uiSourceCodes.set(scripts[i], formattedUISourceCode);
var scriptMapping = /** @type {!WebInspector.FormatterScriptMapping} */(this._scriptMappingByTarget.get(scripts[i].target()));
WebInspector.debuggerWorkspaceBinding.pushSourceMapping(scripts[i], scriptMapping);
}
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i) {
var scriptMapping = /** @type {!WebInspector.FormatterScriptMapping} */(this._scriptMappingByTarget.get(targets[i]));
WebInspector.debuggerWorkspaceBinding.setSourceMapping(targets[i], formattedUISourceCode, scriptMapping);
}
this._showIfNeeded(uiSourceCode, formattedUISourceCode, formatterMapping);
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 2 | /* * Copyright (C) 2014 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.HistoryEntry = function() { } WebInspector.HistoryEntry.prototype = { /** * @return {boolean} */ valid: function() { }, reveal: function() { } }; /** * @constructor * @param {number} historyDepth */ WebInspector.SimpleHistoryManager = function(historyDepth) { this._entries = []; this._activeEntryIndex = -1; this._coalescingReadonly = 0; this._historyDepth = historyDepth; } WebInspector.SimpleHistoryManager.prototype = { readOnlyLock: function() { ++this._coalescingReadonly; }, releaseReadOnlyLock: function() { --this._coalescingReadonly; }, /** * @return {boolean} */ readOnly: function() { return !!this._coalescingReadonly; }, /** * @param {function(!WebInspector.HistoryEntry):boolean} filterOutCallback */ filterOut: function(filterOutCallback) { if (this.readOnly()) return; var filteredEntries = []; var removedBeforeActiveEntry = 0; for (var i = 0; i < this._entries.length; ++i) { if (!filterOutCallback(this._entries[i])) { filteredEntries.push(this._entries[i]); } else if (i <= this._activeEntryIndex) ++removedBeforeActiveEntry; } this._entries = filteredEntries; this._activeEntryIndex = Math.max(0, this._activeEntryIndex - removedBeforeActiveEntry); }, /** * @return {boolean} */ empty: function() { return !this._entries.length; }, /** * @return {?WebInspector.HistoryEntry} */ active: function() { return this.empty() ? null : this._entries[this._activeEntryIndex]; }, /** * @param {!WebInspector.HistoryEntry} entry */ push: function(entry) { if (this.readOnly()) return; if (!this.empty()) this._entries.splice(this._activeEntryIndex + 1); this._entries.push(entry); if (this._entries.length > this._historyDepth) this._entries.shift(); this._activeEntryIndex = this._entries.length - 1; }, /** * @return {boolean} */ rollback: function() { if (this.empty()) return false; var revealIndex = this._activeEntryIndex - 1; while (revealIndex >= 0 && !this._entries[revealIndex].valid()) --revealIndex; if (revealIndex < 0) return false; this.readOnlyLock(); this._entries[revealIndex].reveal(); this.releaseReadOnlyLock(); this._activeEntryIndex = revealIndex; return true; }, /** * @return {boolean} */ rollover: function() { var revealIndex = this._activeEntryIndex + 1; while (revealIndex < this._entries.length && !this._entries[revealIndex].valid()) ++revealIndex; if (revealIndex >= this._entries.length) return false; this.readOnlyLock(); this._entries[revealIndex].reveal(); this.releaseReadOnlyLock(); this._activeEntryIndex = revealIndex; return true; }, }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | 2 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
*/
WebInspector.SourceCodeDiff = function(uiSourceCode, textEditor)
{
this._uiSourceCode = uiSourceCode;
this._textEditor = textEditor;
this._decorations = [];
this._textEditor.installGutter(WebInspector.SourceCodeDiff.DiffGutterType, true);
this._diffBaseline = this._uiSourceCode.requestOriginalContent();
/** @type {!Array<!WebInspector.TextEditorPositionHandle>}*/
this._animatedLines = [];
}
/** @type {number} */
WebInspector.SourceCodeDiff.UpdateTimeout = 200;
/** @type {string} */
WebInspector.SourceCodeDiff.DiffGutterType = "CodeMirror-gutter-diff";
WebInspector.SourceCodeDiff.prototype = {
updateDiffMarkersWhenPossible: function()
{
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
this._updateTimeout = setTimeout(this.updateDiffMarkersImmediately.bind(this), WebInspector.SourceCodeDiff.UpdateTimeout);
},
updateDiffMarkersImmediately: function()
{
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
this._updateTimeout = null;
this._diffBaseline.then(this._innerUpdate.bind(this));
},
/**
* @param {?string} oldContent
* @param {?string} newContent
*/
highlightModifiedLines: function(oldContent, newContent)
{
if (typeof oldContent !== "string" || typeof newContent !== "string")
return;
var diff = this._computeDiff(oldContent, newContent);
var changedLines = [];
for (var i = 0; i < diff.length; ++i) {
var diffEntry = diff[i];
if (diffEntry.type === WebInspector.SourceCodeDiff.GutterDecorationType.Delete)
continue;
for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber) {
var position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
if (position)
changedLines.push(position);
}
}
this._updateHighlightedLines(changedLines);
this._animationTimeout = setTimeout(this._updateHighlightedLines.bind(this, []), 400); // // Keep this timeout in sync with sourcesView.css.
},
/**
* @param {!Array<!WebInspector.TextEditorPositionHandle>} newLines
*/
_updateHighlightedLines: function(newLines)
{
if (this._animationTimeout)
clearTimeout(this._animationTimeout);
this._animationTimeout = null;
this._textEditor.operation(operation.bind(this));
/**
* @this {WebInspector.SourceCodeDiff}
*/
function operation()
{
toggleLines.call(this, false);
this._animatedLines = newLines;
toggleLines.call(this, true);
}
/**
* @param {boolean} value
* @this {WebInspector.SourceCodeDiff}
*/
function toggleLines(value)
{
for (var i = 0; i < this._animatedLines.length; ++i) {
var location = this._animatedLines[i].resolve();
if (location)
this._textEditor.toggleLineClass(location.lineNumber, "highlight-line-modification", value);
}
}
},
/**
* @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} removed
* @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} added
*/
_updateDecorations: function(removed, added)
{
this._textEditor.operation(operation);
function operation()
{
for (var decoration of removed)
decoration.remove();
for (var decoration of added)
decoration.install();
}
},
/**
* @param {string} baseline
* @param {string} current
* @return {!Array<!{type: !WebInspector.SourceCodeDiff.GutterDecorationType, from: number, to: number}>}
*/
_computeDiff: function(baseline, current)
{
var diff = WebInspector.Diff.lineDiff(baseline.split("\n"), current.split("\n"));
var result = [];
var hasAdded = false;
var hasRemoved = false;
var blockStartLineNumber = 0;
var currentLineNumber = 0;
var isInsideBlock = false;
for (var i = 0; i < diff.length; ++i) {
var token = diff[i];
if (token[0] === WebInspector.Diff.Operation.Equal) {
if (isInsideBlock)
flush();
currentLineNumber += token[1].length;
continue;
}
if (!isInsideBlock) {
isInsideBlock = true;
blockStartLineNumber = currentLineNumber;
}
if (token[0] === WebInspector.Diff.Operation.Delete) {
hasRemoved = true;
} else {
currentLineNumber += token[1].length;
hasAdded = true;
}
}
if (isInsideBlock)
flush();
if (result.length > 1 && result[0].from === 0 && result[1].from === 0) {
var merged = {
type: WebInspector.SourceCodeDiff.GutterDecorationType.Modify,
from: 0,
to: result[1].to
};
result.splice(0, 2, merged);
}
return result;
function flush()
{
var type = WebInspector.SourceCodeDiff.GutterDecorationType.Insert;
var from = blockStartLineNumber;
var to = currentLineNumber;
if (hasAdded && hasRemoved) {
type = WebInspector.SourceCodeDiff.GutterDecorationType.Modify;
} else if (!hasAdded && hasRemoved && from === 0 && to === 0) {
type = WebInspector.SourceCodeDiff.GutterDecorationType.Modify;
to = 1;
} else if (!hasAdded && hasRemoved) {
type = WebInspector.SourceCodeDiff.GutterDecorationType.Delete;
from -= 1;
}
result.push({
type: type,
from: from,
to: to
});
isInsideBlock = false;
hasAdded = false;
hasRemoved = false;
}
},
/**
* @param {?string} baseline
*/
_innerUpdate: function(baseline)
{
var current = this._uiSourceCode.workingCopy();
if (typeof current !== "string" || typeof baseline !== "string") {
this._updateDecorations(this._decorations, [] /* added */);
this._decorations = [];
return;
}
var diff = this._computeDiff(baseline, current);
/** @type {!Map<number, !WebInspector.SourceCodeDiff.GutterDecoration>} */
var oldDecorations = new Map();
for (var i = 0; i < this._decorations.length; ++i) {
var decoration = this._decorations[i];
var lineNumber = decoration.lineNumber();
if (lineNumber === -1)
continue;
oldDecorations.set(lineNumber, decoration);
}
/** @type {!Map<number, !{lineNumber: number, type: !WebInspector.SourceCodeDiff.GutterDecorationType}>} */
var newDecorations = new Map();
for (var i = 0; i < diff.length; ++i) {
var diffEntry = diff[i];
for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber)
newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry.type});
}
var decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type);
var addedDecorations = decorationDiff.added.map(entry => new WebInspector.SourceCodeDiff.GutterDecoration(this._textEditor, entry.lineNumber, entry.type));
this._decorations = decorationDiff.equal.concat(addedDecorations);
this._updateDecorations(decorationDiff.removed, addedDecorations);
},
}
/** @enum {string} */
WebInspector.SourceCodeDiff.GutterDecorationType = {
Insert: "Insert",
Delete: "Delete",
Modify: "Modify",
}
/**
* @constructor
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {number} lineNumber
* @param {!WebInspector.SourceCodeDiff.GutterDecorationType} type
*/
WebInspector.SourceCodeDiff.GutterDecoration = function(textEditor, lineNumber, type)
{
this._textEditor = textEditor;
this._position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
this._className = "";
if (type === WebInspector.SourceCodeDiff.GutterDecorationType.Insert)
this._className = "diff-entry-insert";
else if (type === WebInspector.SourceCodeDiff.GutterDecorationType.Delete)
this._className = "diff-entry-delete";
else if (type === WebInspector.SourceCodeDiff.GutterDecorationType.Modify)
this._className = "diff-entry-modify";
this.type = type;
}
WebInspector.SourceCodeDiff.GutterDecoration.prototype = {
/**
* @return {number}
*/
lineNumber: function()
{
var location = this._position.resolve();
if (!location)
return -1;
return location.lineNumber;
},
install: function()
{
var location = this._position.resolve();
if (!location)
return;
var element = createElementWithClass("div", "diff-marker");
element.textContent = "\u00A0";
this._textEditor.setGutterDecoration(location.lineNumber, WebInspector.SourceCodeDiff.DiffGutterType, element);
this._textEditor.toggleLineClass(location.lineNumber, this._className, true);
},
remove: function()
{
var location = this._position.resolve();
if (!location)
return;
this._textEditor.setGutterDecoration(location.lineNumber, WebInspector.SourceCodeDiff.DiffGutterType, null);
this._textEditor.toggleLineClass(location.lineNumber, this._className, false);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | 2 1 1 1 1 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.SourceMapNamesResolver = {};
WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache");
WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cachePromise");
/**
* @param {!WebInspector.DebuggerModel.Scope} scope
* @return {!Promise.<!Map<string, string>>}
*/
WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
{
var cachedMap = scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol];
if (cachedMap)
return Promise.resolve(cachedMap);
var cachedPromise = scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol];
if (cachedPromise)
return cachedPromise;
var startLocation = scope.startLocation();
var endLocation = scope.endLocation();
if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endLocation || !startLocation.script().sourceMapURL || (startLocation.script() !== endLocation.script()))
return Promise.resolve(new Map());
var script = startLocation.script();
var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);
if (!sourceMap)
return Promise.resolve(new Map());
var promise = script.requestContent().then(onContent);
scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol] = promise;
return promise;
/**
* @param {?string} content
* @return {!Promise<!Map<string, string>>}
*/
function onContent(content)
{
if (!content)
return Promise.resolve(new Map());
var startLocation = scope.startLocation();
var endLocation = scope.endLocation();
var textRange = new WebInspector.TextRange(startLocation.lineNumber, startLocation.columnNumber, endLocation.lineNumber, endLocation.columnNumber);
var text = new WebInspector.Text(content);
var scopeText = text.extract(textRange);
var scopeStart = text.toSourceRange(textRange).offset;
var prefix = "function fui";
return WebInspector.SourceMapNamesResolverWorker._instance().javaScriptIdentifiers(prefix + scopeText)
.then(onIdentifiers.bind(null, text, scopeStart, prefix));
}
/**
* @param {!WebInspector.Text} text
* @param {number} scopeStart
* @param {string} prefix
* @param {!Array<!{name: string, offset: number}>} identifiers
* @return {!Map<string, string>}
*/
function onIdentifiers(text, scopeStart, prefix, identifiers)
{
var namesMapping = new Map();
var lineEndings = text.lineEndings();
for (var i = 0; i < identifiers.length; ++i) {
var id = identifiers[i];
var start = scopeStart + id.offset - prefix.length;
var lineNumber = lineEndings.lowerBound(start);
var columnNumber = start - (lineNumber === 0 ? 0 : (lineEndings[lineNumber - 1] + 1));
var entry = sourceMap.findEntry(lineNumber, columnNumber);
if (entry)
namesMapping.set(id.name, entry.name);
}
scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = namesMapping;
delete scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol];
WebInspector.SourceMapNamesResolver._scopeResolvedForTest();
return namesMapping;
}
}
WebInspector.SourceMapNamesResolver._scopeResolvedForTest = function() { }
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @return {!Promise.<!Map<string, string>>}
*/
WebInspector.SourceMapNamesResolver._allVariablesInCallFrame = function(callFrame)
{
var cached = callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol];
if (cached)
return Promise.resolve(cached);
var promises = [];
var scopeChain = callFrame.scopeChain();
for (var i = 0; i < scopeChain.length; ++i)
promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeChain[i]));
return Promise.all(promises).then(mergeVariables);
/**
* @param {!Array<!Map<string, string>>} nameMappings
* @return {!Map<string, string>}
*/
function mergeVariables(nameMappings)
{
var reverseMapping = new Map();
for (var map of nameMappings) {
for (var compiledName of map.keys()) {
var originalName = map.get(compiledName);
if (!reverseMapping.has(originalName))
reverseMapping.set(originalName, compiledName);
}
}
callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = reverseMapping;
return reverseMapping;
}
}
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @param {string} originalText
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} startColumnNumber
* @param {number} endColumnNumber
* @return {!Promise<string>}
*/
WebInspector.SourceMapNamesResolver.resolveExpression = function(callFrame, originalText, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
{
if (!Runtime.experiments.isEnabled("resolveVariableNames") || !uiSourceCode.contentType().isFromSourceMap())
return Promise.resolve("");
return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName);
/**
* @param {!Map<string, string>} reverseMapping
* @return {!Promise<string>}
*/
function findCompiledName(reverseMapping)
{
if (reverseMapping.has(originalText))
return Promise.resolve(reverseMapping.get(originalText) || "");
return WebInspector.SourceMapNamesResolver._resolveExpression(callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
}
}
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} startColumnNumber
* @param {number} endColumnNumber
* @return {!Promise<string>}
*/
WebInspector.SourceMapNamesResolver._resolveExpression = function(callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
{
var target = callFrame.target();
var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocation(target, uiSourceCode, lineNumber, startColumnNumber);
if (!rawLocation)
return Promise.resolve("");
var script = rawLocation.script();
var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);
if (!sourceMap)
return Promise.resolve("");
return script.requestContent().then(onContent);
/**
* @param {?string} content
* @return {!Promise<string>}
*/
function onContent(content)
{
if (!content)
return Promise.resolve("");
var text = new WebInspector.Text(content);
var textRange = sourceMap.reverseMapTextRange(uiSourceCode.url(), new WebInspector.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber));
var originalText = text.extract(textRange);
if (!originalText)
return Promise.resolve("");
return WebInspector.SourceMapNamesResolverWorker._instance().evaluatableJavaScriptSubstring(originalText);
}
}
/**
* @param {!WebInspector.DebuggerModel.Scope} scope
* @return {!WebInspector.RemoteObject}
*/
WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope)
{
if (!Runtime.experiments.isEnabled("resolveVariableNames"))
return scope.object();
var startLocation = scope.startLocation();
var endLocation = scope.endLocation();
if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endLocation || !startLocation.script().sourceMapURL || startLocation.script() !== endLocation.script())
return scope.object();
return new WebInspector.SourceMapNamesResolver.RemoteObject(scope);
}
/**
* @constructor
* @extends {WebInspector.RemoteObject}
* @param {!WebInspector.DebuggerModel.Scope} scope
*/
WebInspector.SourceMapNamesResolver.RemoteObject = function(scope)
{
WebInspector.RemoteObject.call(this);
this._scope = scope;
this._object = scope.object();
};
WebInspector.SourceMapNamesResolver.RemoteObject.prototype = {
/**
* @override
* @return {?RuntimeAgent.CustomPreview}
*/
customPreview: function()
{
return this._object.customPreview();
},
/**
* @override
* @return {string}
*/
get type()
{
return this._object.type;
},
/**
* @override
* @return {string|undefined}
*/
get subtype()
{
return this._object.subtype;
},
/**
* @override
* @return {string|undefined}
*/
get description()
{
return this._object.description;
},
/**
* @override
* @return {boolean}
*/
get hasChildren()
{
return this._object.hasChildren;
},
/**
* @override
* @return {number}
*/
arrayLength: function()
{
return this._object.arrayLength();
},
/**
* @override
* @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getOwnProperties: function(callback)
{
this._object.getOwnProperties(callback);
},
/**
* @override
* @param {boolean} accessorPropertiesOnly
* @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebInspector.RemoteObjectProperty>)} callback
*/
getAllProperties: function(accessorPropertiesOnly, callback)
{
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
* @this {WebInspector.SourceMapNamesResolver.RemoteObject}
*/
function wrappedCallback(properties, internalProperties)
{
WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(resolveNames.bind(null, properties, internalProperties))
}
/**
* @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
* @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties
* @param {!Map<string, string>} namesMapping
*/
function resolveNames(properties, internalProperties, namesMapping)
{
var newProperties = [];
if (properties) {
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
var name = namesMapping.get(property.name) || properties[i].name;
newProperties.push(new WebInspector.RemoteObjectProperty(name, property.value, property.enumerable, property.writable, property.isOwn, property.wasThrown, property.symbol, property.synthetic));
}
}
callback(newProperties, internalProperties);
}
this._object.getAllProperties(accessorPropertiesOnly, wrappedCallback.bind(this));
},
/**
* @override
* @param {string|!RuntimeAgent.CallArgument} argumentName
* @param {string} value
* @param {function(string=)} callback
*/
setPropertyValue: function(argumentName, value, callback)
{
WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(resolveName.bind(this));
/**
* @param {!Map<string, string>} namesMapping
* @this {WebInspector.SourceMapNamesResolver.RemoteObject}
*/
function resolveName(namesMapping)
{
var name;
if (typeof argumentName === "string")
name = argumentName;
else
name = /** @type {string} */ (argumentName.value);
var actualName = name;
for (var compiledName of namesMapping.keys()) {
if (namesMapping.get(compiledName) === name) {
actualName = compiledName;
break;
}
}
this._object.setPropertyValue(actualName, value, callback);
}
},
/**
* @override
* @return {!Promise<?Array<!WebInspector.EventListener>>}
*/
eventListeners: function()
{
return this._object.eventListeners();
},
/**
* @override
* @param {!RuntimeAgent.CallArgument} name
* @param {function(string=)} callback
*/
deleteProperty: function(name, callback)
{
this._object.deleteProperty(name, callback);
},
/**
* @override
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>=} args
* @param {function(?WebInspector.RemoteObject, boolean=)=} callback
*/
callFunction: function(functionDeclaration, args, callback)
{
this._object.callFunction(functionDeclaration, args, callback);
},
/**
* @override
* @param {function(this:Object, ...)} functionDeclaration
* @param {!Array<!RuntimeAgent.CallArgument>|undefined} args
* @param {function(*)} callback
*/
callFunctionJSON: function(functionDeclaration, args, callback)
{
this._object.callFunctionJSON(functionDeclaration, args, callback);
},
/**
* @override
* @return {!WebInspector.Target}
*/
target: function()
{
return this._object.target();
},
/**
* @override
* @return {?WebInspector.DebuggerModel}
*/
debuggerModel: function()
{
return this._object.debuggerModel();
},
/**
* @override
* @return {boolean}
*/
isNode: function()
{
return this._object.isNode();
},
/**
* @override
* @param {function(?WebInspector.DebuggerModel.FunctionDetails)} callback
*/
functionDetails: function(callback)
{
this._object.functionDetails(callback);
},
/**
* @override
* @param {function(?WebInspector.DebuggerModel.GeneratorObjectDetails)} callback
*/
generatorObjectDetails: function(callback)
{
this._object.generatorObjectDetails(callback);
},
/**
* @override
* @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback
*/
collectionEntries: function(callback)
{
this._object.collectionEntries(callback);
},
__proto__: WebInspector.RemoteObject.prototype
}
/**
* @constructor
*/
WebInspector.SourceMapNamesResolverWorker = function()
{
this._worker = new WorkerRuntime.Worker("formatter_worker");
this._worker.onmessage = this._onMessage.bind(this);
this._methodNames = [];
this._contents = [];
this._callbacks = [];
}
WebInspector.SourceMapNamesResolverWorker.prototype = {
/**
* @param {string} text
* @return {!Promise<string>}
*/
evaluatableJavaScriptSubstring: function(text)
{
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this._methodNames.push("evaluatableJavaScriptSubstring");
this._contents.push(text);
this._callbacks.push(this._evaluatableJavaScriptSubstringCallback.bind(this, callback));
this._maybeRunTask();
return promise;
},
/**
* @param {function(string)} callback
* @param {!MessageEvent} event
*/
_evaluatableJavaScriptSubstringCallback: function(callback, event)
{
callback.call(null, /** @type {string} */(event.data));
},
/**
* @param {string} text
* @return {!Promise<!Array<!{name: string, offset: number}>>}
*/
javaScriptIdentifiers: function(text)
{
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this._methodNames.push("javaScriptIdentifiers");
this._contents.push(text);
this._callbacks.push(this._javaScriptIdentifiersCallback.bind(this, callback));
this._maybeRunTask();
return promise;
},
/**
* @param {function(!Array<!{name: string, offset: number}>)} callback
* @param {!MessageEvent} event
*/
_javaScriptIdentifiersCallback: function(callback, event)
{
callback.call(null, /** @type {!Array<!{name: string, offset: number}>} */(event.data));
},
/**
* @param {!MessageEvent} event
*/
_onMessage: function(event)
{
var callback = this._callbacks[0];
this._methodNames.shift();
this._contents.shift();
this._callbacks.shift();
callback.call(null, event);
this._runningTask = false;
this._maybeRunTask();
},
_maybeRunTask: function()
{
if (this._runningTask || !this._methodNames.length)
return;
this._runningTask = true;
var methodName = this._methodNames[0];
var content = this._contents[0];
this._worker.postMessage({ method: methodName, params: { content: content } });
}
}
/**
* @return {!WebInspector.SourceMapNamesResolverWorker}
*/
WebInspector.SourceMapNamesResolverWorker._instance = function()
{
if (!WebInspector.SourceMapNamesResolverWorker._instanceObject)
WebInspector.SourceMapNamesResolverWorker._instanceObject = new WebInspector.SourceMapNamesResolverWorker();
return WebInspector.SourceMapNamesResolverWorker._instanceObject;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | 2 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.SourcesNavigator = function(workspace)
{
WebInspector.Object.call(this);
this._workspace = workspace;
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.setShrinkableTabs(true);
this._tabbedPane.element.classList.add("navigator-tabbed-pane");
this._tabbedPaneController = new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "navigator-view", this._navigatorViewCreated.bind(this));
/** @type {!Map.<string, ?WebInspector.NavigatorView>} */
this._navigatorViews = new Map();
var toolbar = new WebInspector.Toolbar("");
var menuButton = new WebInspector.ToolbarMenuButton(this._populateMenu.bind(this), true);
menuButton.setTitle(WebInspector.UIString("More options"));
toolbar.appendToolbarItem(menuButton);
this._tabbedPane.appendAfterTabStrip(toolbar.element);
}
WebInspector.SourcesNavigator.Events = {
SourceSelected: "SourceSelected",
SourceRenamed: "SourceRenamed"
}
WebInspector.SourcesNavigator.prototype = {
/**
* @param {string} id
* @param {!WebInspector.Widget} view
*/
_navigatorViewCreated: function(id, view)
{
var navigatorView = /** @type {!WebInspector.NavigatorView} */ (view);
navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected, this._sourceSelected, this);
navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamed, this._sourceRenamed, this);
this._navigatorViews.set(id, navigatorView);
navigatorView.setWorkspace(this._workspace);
},
/**
* @return {!WebInspector.Widget}
*/
get view()
{
return this._tabbedPane;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
revealUISourceCode: function(uiSourceCode)
{
var ids = this._tabbedPaneController.viewIds();
var promises = [];
for (var i = 0; i < ids.length; ++i)
promises.push(this._tabbedPaneController.viewForId(ids[i]));
Promise.all(promises).then(filterNavigators.bind(this));
/**
* @param {!Array.<!Object>} objects
* @this {WebInspector.SourcesNavigator}
*/
function filterNavigators(objects)
{
for (var i = 0; i < objects.length; ++i) {
var navigatorView = /** @type {!WebInspector.NavigatorView} */ (objects[i]);
if (navigatorView.accept(uiSourceCode)) {
this._tabbedPane.selectTab(ids[i]);
navigatorView.revealUISourceCode(uiSourceCode, true);
}
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_sourceSelected: function(event)
{
this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceSelected, event.data);
},
/**
* @param {!WebInspector.Event} event
*/
_sourceRenamed: function(event)
{
this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceRenamed, event.data);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_populateMenu: function(contextMenu)
{
var groupByFolderSetting = WebInspector.moduleSetting("navigatorGroupByFolder");
contextMenu.appendItemsAtLocation("navigatorMenu");
contextMenu.appendSeparator();
contextMenu.appendCheckboxItem(WebInspector.UIString("Group by folder"), () => groupByFolderSetting.set(!groupByFolderSetting.get()), groupByFolderSetting.get());
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorView}
*/
WebInspector.SourcesNavigatorView = function()
{
WebInspector.NavigatorView.call(this);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
}
WebInspector.SourcesNavigatorView.prototype = {
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
accept: function(uiSourceCode)
{
if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
return false;
return uiSourceCode.project().type() !== WebInspector.projectTypes.ContentScripts && uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets;
},
/**
* @param {!WebInspector.Event} event
*/
_inspectedURLChanged: function(event)
{
var nodes = this._uiSourceCodeNodes.valuesArray();
for (var i = 0; i < nodes.length; ++i) {
var uiSourceCode = nodes[i].uiSourceCode();
var inspectedPageURL = WebInspector.targetManager.inspectedPageURL();
if (inspectedPageURL && WebInspector.networkMapping.networkURL(uiSourceCode) === inspectedPageURL)
this.revealUISourceCode(uiSourceCode, true);
}
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
uiSourceCodeAdded: function(uiSourceCode)
{
var inspectedPageURL = WebInspector.targetManager.inspectedPageURL();
if (inspectedPageURL && WebInspector.networkMapping.networkURL(uiSourceCode) === inspectedPageURL)
this.revealUISourceCode(uiSourceCode, true);
},
__proto__: WebInspector.NavigatorView.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorView}
*/
WebInspector.ContentScriptsNavigatorView = function()
{
WebInspector.NavigatorView.call(this);
}
WebInspector.ContentScriptsNavigatorView.prototype = {
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
accept: function(uiSourceCode)
{
if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
return false;
return uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts;
},
__proto__: WebInspector.NavigatorView.prototype
}
/**
* @constructor
* @extends {WebInspector.NavigatorView}
*/
WebInspector.SnippetsNavigatorView = function()
{
WebInspector.NavigatorView.call(this);
}
WebInspector.SnippetsNavigatorView.prototype = {
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
accept: function(uiSourceCode)
{
if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
return false;
return uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
},
/**
* @override
* @param {!Event} event
*/
handleContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
contextMenu.show();
},
/**
* @override
* @param {!Event} event
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
handleFileContextMenu: function(event, uiSourceCode)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Run"), this._handleEvaluateSnippet.bind(this, uiSourceCode));
contextMenu.appendItem(WebInspector.UIString("Rename"), this.rename.bind(this, uiSourceCode));
contextMenu.appendItem(WebInspector.UIString("Remove"), this._handleRemoveSnippet.bind(this, uiSourceCode));
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
contextMenu.show();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_handleEvaluateSnippet: function(uiSourceCode)
{
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets || !executionContext)
return;
WebInspector.scriptSnippetModel.evaluateScriptSnippet(executionContext, uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_handleRemoveSnippet: function(uiSourceCode)
{
if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
return;
uiSourceCode.remove();
},
_handleCreateSnippet: function()
{
this.create(WebInspector.scriptSnippetModel.project(), "");
},
/**
* @override
*/
sourceDeleted: function(uiSourceCode)
{
this._handleRemoveSnippet(uiSourceCode);
},
__proto__: WebInspector.NavigatorView.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 | 2 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Panel}
* @implements {WebInspector.ContextMenu.Provider}
* @param {!WebInspector.Workspace=} workspaceForTest
*/
WebInspector.SourcesPanel = function(workspaceForTest)
{
WebInspector.Panel.call(this, "sources");
this.registerRequiredCSS("sources/sourcesPanel.css");
new WebInspector.DropTarget(this.element, [WebInspector.DropTarget.Types.Files], WebInspector.UIString("Drop workspace folder here"), this._handleDrop.bind(this));
this._workspace = workspaceForTest || WebInspector.workspace;
this._networkMapping = WebInspector.networkMapping;
this._runSnippetAction = WebInspector.actionRegistry.action("debugger.run-snippet");
this._togglePauseAction = WebInspector.actionRegistry.action("debugger.toggle-pause");
this._stepOverAction = WebInspector.actionRegistry.action("debugger.step-over");
this._stepIntoAction = WebInspector.actionRegistry.action("debugger.step-into");
this._stepOutAction = WebInspector.actionRegistry.action("debugger.step-out");
this._toggleBreakpointsActiveAction = WebInspector.actionRegistry.action("debugger.toggle-breakpoints-active");
this._toggleBreakpointsActiveAction.setToggled(false);
this._toggleBreakpointsActiveAction.setTitle(WebInspector.UIString("Deactivate breakpoints"));
this._debugToolbar = this._createDebugToolbar();
this._debugToolbarDrawer = this._createDebugToolbarDrawer();
const initialDebugSidebarWidth = 225;
this._splitWidget = new WebInspector.SplitWidget(true, true, "sourcesPanelSplitViewState", initialDebugSidebarWidth);
this._splitWidget.enableShowModeSaving();
this._splitWidget.show(this.element);
// Create scripts navigator
const initialNavigatorWidth = 225;
this.editorView = new WebInspector.SplitWidget(true, false, "sourcesPanelNavigatorSplitViewState", initialNavigatorWidth);
this.editorView.enableShowModeSaving();
this.editorView.element.tabIndex = 0;
this._splitWidget.setMainWidget(this.editorView);
this._navigator = new WebInspector.SourcesNavigator(this._workspace);
this._navigator.view.setMinimumSize(100, 25);
this.editorView.setSidebarWidget(this._navigator.view);
this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected, this._sourceSelected, this);
this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceRenamed, this._sourceRenamed, this);
this._sourcesView = new WebInspector.SourcesView(this._workspace, this);
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
this._sourcesView.registerShortcuts(this.registerShortcuts.bind(this));
this.editorView.setMainWidget(this._sourcesView);
this.sidebarPanes = {};
this.sidebarPanes.threads = new WebInspector.ThreadsSidebarPane();
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this));
this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this.showUISourceCode.bind(this));
this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
this.sidebarPanes.objectEventListeners = new WebInspector.ObjectEventListenersSidebarPane();
this._lastSelectedTabSetting = WebInspector.settings.createLocalSetting("lastSelectedSourcesSidebarPaneTab", this.sidebarPanes.scopechain.title());
this._installDebuggerSidebarController();
WebInspector.moduleSetting("sidebarPosition").addChangeListener(this._updateSidebarPosition.bind(this));
this._updateSidebarPosition();
this._updateDebuggerButtons();
this._pauseOnExceptionEnabledChanged();
WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this._pauseOnExceptionEnabledChanged, this);
this._liveLocationPool = new WebInspector.LiveLocationPool();
this._setTarget(WebInspector.context.flavor(WebInspector.Target));
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._onCurrentTargetChanged, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
new WebInspector.WorkspaceMappingTip(this, this._workspace);
WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
WebInspector.DataSaverInfobar.maybeShowInPanel(this);
}
WebInspector.SourcesPanel._lastModificationTimeout = 200;
WebInspector.SourcesPanel.minToolbarWidth = 215;
WebInspector.SourcesPanel.prototype = {
/**
* @param {?WebInspector.Target} target
*/
_setTarget: function(target)
{
if (!target)
return;
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return;
if (debuggerModel.isPaused()) {
this._showDebuggerPausedDetails(/** @type {!WebInspector.DebuggerPausedDetails} */ (debuggerModel.debuggerPausedDetails()));
var callFrame = debuggerModel.selectedCallFrame();
if (callFrame)
this._selectCallFrame(callFrame);
} else {
this._paused = false;
this._clearInterface();
this._toggleDebuggerSidebarButton.disabled = false;
}
},
/**
* @param {!WebInspector.Event} event
*/
_onCurrentTargetChanged: function(event)
{
var target = /** @type {?WebInspector.Target} */ (event.data);
this._setTarget(target);
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._sourcesView.defaultFocusedElement();
},
/**
* @return {boolean}
*/
paused: function()
{
return this._paused;
},
wasShown: function()
{
WebInspector.context.setFlavor(WebInspector.SourcesPanel, this);
WebInspector.Panel.prototype.wasShown.call(this);
},
willHide: function()
{
WebInspector.Panel.prototype.willHide.call(this);
WebInspector.context.setFlavor(WebInspector.SourcesPanel, null);
},
onResize: function()
{
if (WebInspector.moduleSetting("sidebarPosition").get() === "auto")
this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this)); // Do not force layout.
},
/**
* @override
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._sourcesView.searchableView();
},
_consoleCommandEvaluatedInSelectedCallFrame: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
var target = debuggerModel.target();
if (WebInspector.context.flavor(WebInspector.Target) !== target)
return;
this.sidebarPanes.scopechain.update(debuggerModel.selectedCallFrame());
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerPaused: function(event)
{
var details = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data);
if (!this._paused)
WebInspector.inspectorView.setCurrentPanel(this);
if (WebInspector.context.flavor(WebInspector.Target) === details.target())
this._showDebuggerPausedDetails(details);
else if (!this._paused)
WebInspector.context.setFlavor(WebInspector.Target, details.target());
},
/**
* @param {!WebInspector.DebuggerPausedDetails} details
*/
_showDebuggerPausedDetails: function(details)
{
this._paused = true;
this._updateDebuggerButtons();
this.sidebarPanes.callstack.update(details);
/**
* @param {!Element} element
* @this {WebInspector.SourcesPanel}
*/
function didCreateBreakpointHitStatusMessage(element)
{
this.sidebarPanes.callstack.setStatus(element);
}
/**
* @param {!WebInspector.LiveLocation} liveLocation
* @this {WebInspector.SourcesPanel}
*/
function didGetUILocation(liveLocation)
{
var uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
var breakpoint = WebInspector.breakpointManager.findBreakpointOnLine(uiLocation.uiSourceCode, uiLocation.lineNumber);
if (!breakpoint)
return;
this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
}
if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details, didCreateBreakpointHitStatusMessage.bind(this));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
var eventName = details.auxData["eventName"];
var targetName = details.auxData["targetName"];
this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(eventName, targetName);
var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData);
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception) {
var description = details.auxData["description"] || "";
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", description.split("\n", 1)[0]));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.PromiseRejection) {
var description = details.auxData["description"] || "";
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on promise rejection: '%s'.", description.split("\n", 1)[0]));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert) {
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation) {
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
} else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand) {
this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function."));
} else {
if (details.callFrames.length)
WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(details.callFrames[0].location(), didGetUILocation.bind(this), this._liveLocationPool);
else
console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
}
this._splitWidget.showBoth(true);
this._toggleDebuggerSidebarButton.disabled = true;
window.focus();
InspectorFrontendHost.bringToFront();
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerResumed: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
var target = debuggerModel.target();
if (WebInspector.context.flavor(WebInspector.Target) !== target)
return;
this._paused = false;
this._clearInterface();
this._toggleDebuggerSidebarButton.disabled = false;
this._switchToPausedTargetTimeout = setTimeout(this._switchToPausedTarget.bind(this, debuggerModel), 500);
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerWasEnabled: function(event)
{
var target = /** @type {!WebInspector.Target} */ (event.target.target());
if (WebInspector.context.flavor(WebInspector.Target) !== target)
return;
this._updateDebuggerButtons();
},
/**
* @param {!WebInspector.Event} event
*/
_debuggerReset: function(event)
{
this._debuggerResumed(event);
},
/**
* @return {!WebInspector.Widget}
*/
get visibleView()
{
return this._sourcesView.visibleView();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber 0-based
* @param {number=} columnNumber
*/
showUISourceCode: function(uiSourceCode, lineNumber, columnNumber)
{
this._showEditor();
this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
},
_showEditor: function()
{
WebInspector.inspectorView.setCurrentPanel(this);
},
/**
* @param {!WebInspector.UILocation} uiLocation
*/
showUILocation: function(uiLocation)
{
this.showUISourceCode(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_revealInNavigator: function(uiSourceCode)
{
this._navigator.revealUISourceCode(uiSourceCode);
},
/**
* @param {boolean} ignoreExecutionLineEvents
*/
setIgnoreExecutionLineEvents: function(ignoreExecutionLineEvents)
{
this._ignoreExecutionLineEvents = ignoreExecutionLineEvents;
},
updateLastModificationTime: function()
{
this._lastModificationTime = window.performance.now();
},
/**
* @param {!WebInspector.LiveLocation} liveLocation
*/
_executionLineChanged: function(liveLocation)
{
var uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
this._sourcesView.clearCurrentExecutionLine();
this._sourcesView.setExecutionLocation(uiLocation);
if (window.performance.now() - this._lastModificationTime < WebInspector.SourcesPanel._lastModificationTimeout)
return;
this._sourcesView.showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, undefined, true);
},
_lastModificationTimeoutPassedForTest: function()
{
WebInspector.SourcesPanel._lastModificationTimeout = Number.MIN_VALUE;
},
_updateLastModificationTimeForTest: function()
{
WebInspector.SourcesPanel._lastModificationTimeout = Number.MAX_VALUE;
},
/**
* @param {!WebInspector.Event} event
*/
_callFrameSelected: function(event)
{
var callFrame = /** @type {?WebInspector.DebuggerModel.CallFrame} */ (event.data);
if (!callFrame || callFrame.target() !== WebInspector.context.flavor(WebInspector.Target))
return;
this._selectCallFrame(callFrame);
},
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
*/
_selectCallFrame: function(callFrame)
{
this.sidebarPanes.scopechain.update(callFrame);
this.sidebarPanes.watchExpressions.refreshExpressions();
this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame.location(), this._executionLineChanged.bind(this), this._liveLocationPool);
},
/**
* @param {!WebInspector.Event} event
*/
_sourceSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
this._sourcesView.showSourceLocation(uiSourceCode, undefined, undefined, !event.data.focusSource)
},
/**
* @param {!WebInspector.Event} event
*/
_sourceRenamed: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._sourcesView.sourceRenamed(uiSourceCode);
},
_pauseOnExceptionEnabledChanged: function()
{
var enabled = WebInspector.moduleSetting("pauseOnExceptionEnabled").get();
this._pauseOnExceptionButton.setToggled(enabled);
this._pauseOnExceptionButton.setTitle(WebInspector.UIString(enabled ? "Don't pause on exceptions" : "Pause on exceptions"));
this._debugToolbarDrawer.classList.toggle("expanded", enabled);
},
_updateDebuggerButtons: function()
{
var currentTarget = WebInspector.context.flavor(WebInspector.Target);
var currentDebuggerModel = WebInspector.DebuggerModel.fromTarget(currentTarget);
if (!currentDebuggerModel) {
this._togglePauseAction.setEnabled(false);
this._stepOverAction.setEnabled(false);
this._stepIntoAction.setEnabled(false);
this._stepOutAction.setEnabled(false);
} else if (this._paused) {
this._togglePauseAction.setTitle(WebInspector.UIString("Resume script execution"));
this._togglePauseAction.setToggled(true);
this._togglePauseAction.setEnabled(true);
this._stepOverAction.setEnabled(true);
this._stepIntoAction.setEnabled(true);
this._stepOutAction.setEnabled(true);
} else {
this._togglePauseAction.setTitle(WebInspector.UIString("Pause script execution"));
this._togglePauseAction.setToggled(false);
this._togglePauseAction.setEnabled(!currentDebuggerModel.isPausing());
this._stepOverAction.setEnabled(false);
this._stepIntoAction.setEnabled(false);
this._stepOutAction.setEnabled(false);
}
},
_clearInterface: function()
{
this.sidebarPanes.callstack.update(null);
this.sidebarPanes.scopechain.update(null);
this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
if (this.sidebarPanes.asyncOperationBreakpoints)
this.sidebarPanes.asyncOperationBreakpoints.clearBreakpointHighlight();
this._sourcesView.clearCurrentExecutionLine();
this._updateDebuggerButtons();
if (this._switchToPausedTargetTimeout)
clearTimeout(this._switchToPausedTargetTimeout);
this._liveLocationPool.disposeAll();
},
/**
* @param {!WebInspector.DebuggerModel} debuggerModel
*/
_switchToPausedTarget: function(debuggerModel)
{
delete this._switchToPausedTargetTimeout;
if (this._paused)
return;
var target = WebInspector.context.flavor(WebInspector.Target);
if (debuggerModel.isPaused())
return;
var debuggerModels = WebInspector.DebuggerModel.instances();
for (var i = 0; i < debuggerModels.length; ++i) {
if (debuggerModels[i].isPaused()) {
WebInspector.context.setFlavor(WebInspector.Target, debuggerModels[i].target());
break;
}
}
},
_togglePauseOnExceptions: function()
{
WebInspector.moduleSetting("pauseOnExceptionEnabled").set(!this._pauseOnExceptionButton.toggled());
},
/**
* @return {boolean}
*/
_runSnippet: function()
{
var uiSourceCode = this._sourcesView.currentUISourceCode();
if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
return false;
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!currentExecutionContext)
return false;
WebInspector.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode);
return true;
},
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._editorChanged(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
_editorClosed: function(event)
{
var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
if (wasSelected)
this._editorChanged(null);
},
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
*/
_editorChanged: function(uiSourceCode)
{
var isSnippet = uiSourceCode && uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
this._runSnippetButton.setVisible(isSnippet);
},
/**
* @return {boolean}
*/
_togglePause: function()
{
var target = WebInspector.context.flavor(WebInspector.Target);
if (!target)
return true;
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (!debuggerModel)
return true;
if (this._paused) {
this._paused = false;
debuggerModel.resume();
} else {
// Make sure pauses didn't stick skipped.
debuggerModel.pause();
}
this._clearInterface();
return true;
},
/**
* @return {?WebInspector.DebuggerModel}
*/
_prepareToResume: function()
{
if (!this._paused)
return null;
this._paused = false;
this._clearInterface();
var target = WebInspector.context.flavor(WebInspector.Target);
return target ? WebInspector.DebuggerModel.fromTarget(target) : null;
},
/**
* @return {boolean}
*/
_longResume: function()
{
var debuggerModel = this._prepareToResume();
if (!debuggerModel)
return true;
debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
debuggerModel.resume();
return true;
},
/**
* @return {boolean}
*/
_stepOver: function()
{
var debuggerModel = this._prepareToResume();
if (!debuggerModel)
return true;
debuggerModel.stepOver();
return true;
},
/**
* @return {boolean}
*/
_stepInto: function()
{
var debuggerModel = this._prepareToResume();
if (!debuggerModel)
return true;
debuggerModel.stepInto();
return true;
},
/**
* @return {boolean}
*/
_stepOut: function()
{
var debuggerModel = this._prepareToResume();
if (!debuggerModel)
return true;
debuggerModel.stepOut();
return true;
},
/**
* @param {!WebInspector.Event} event
*/
_callFrameSelectedInSidebar: function(event)
{
var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data);
callFrame.debuggerModel.setSelectedCallFrame(callFrame);
},
/**
* @param {!WebInspector.UILocation} uiLocation
*/
_continueToLocation: function(uiLocation)
{
var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!executionContext)
return;
// Always use 0 column.
var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocation(executionContext.target(), uiLocation.uiSourceCode, uiLocation.lineNumber, 0);
if (!rawLocation)
return;
if (!this._prepareToResume())
return;
rawLocation.continueToLocation();
},
_toggleBreakpointsActive: function()
{
WebInspector.breakpointManager.setBreakpointsActive(!WebInspector.breakpointManager.breakpointsActive());
},
_breakpointsActiveStateChanged: function(event)
{
var active = event.data;
this._toggleBreakpointsActiveAction.setToggled(!active);
this.sidebarPanes.jsBreakpoints.listElement.classList.toggle("breakpoints-list-deactivated", !active);
this._sourcesView.toggleBreakpointsActiveState(active);
if (active)
this._toggleBreakpointsActiveAction.setTitle(WebInspector.UIString("Deactivate breakpoints"));
else
this._toggleBreakpointsActiveAction.setTitle(WebInspector.UIString("Activate breakpoints"));
},
/**
* @return {!WebInspector.Toolbar}
*/
_createDebugToolbar: function()
{
var debugToolbar = new WebInspector.Toolbar("scripts-debug-toolbar");
this._runSnippetButton = WebInspector.Toolbar.createActionButton(this._runSnippetAction);
debugToolbar.appendToolbarItem(this._runSnippetButton);
this._runSnippetButton.setVisible(false);
var longResumeButton = new WebInspector.ToolbarButton(WebInspector.UIString("Resume with all pauses blocked for 500 ms"), "play-toolbar-item");
longResumeButton.addEventListener("click", this._longResume.bind(this), this);
debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._togglePauseAction, [longResumeButton], []));
debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepOverAction));
debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepIntoAction));
debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepOutAction));
debugToolbar.appendSeparator();
debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleBreakpointsActiveAction));
this._pauseOnExceptionButton = new WebInspector.ToolbarToggle("", "pause-on-exceptions-toolbar-item");
this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
debugToolbar.appendToolbarItem(this._pauseOnExceptionButton);
debugToolbar.appendSeparator();
debugToolbar.appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Async"), WebInspector.UIString("Capture async stack traces"), WebInspector.moduleSetting("enableAsyncStackTraces")));
return debugToolbar;
},
_createDebugToolbarDrawer: function()
{
var debugToolbarDrawer = createElementWithClass("div", "scripts-debug-toolbar-drawer");
var label = WebInspector.UIString("Pause On Caught Exceptions");
var setting = WebInspector.moduleSetting("pauseOnCaughtException");
debugToolbarDrawer.appendChild(WebInspector.SettingsUI.createSettingCheckbox(label, setting, true));
return debugToolbarDrawer;
},
addToWatch: function(expression)
{
this.sidebarPanes.watchExpressions.addExpression(expression);
},
_installDebuggerSidebarController: function()
{
this.editorView.displayShowHideSidebarButton("navigator");
this._toggleDebuggerSidebarButton = this._splitWidget.displayShowHideSidebarButton("debugger", "scripts-debugger-show-hide-button");
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_showLocalHistory: function(uiSourceCode)
{
WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
},
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
this._appendUISourceCodeItems(event, contextMenu, target);
this.appendUILocationItems(contextMenu, target);
this._appendRemoteObjectItems(contextMenu, target);
this._appendNetworkRequestItems(contextMenu, target);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
mapFileSystemToNetwork: function(uiSourceCode)
{
WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this));
/**
* @param {?WebInspector.UISourceCode} networkUISourceCode
* @this {WebInspector.SourcesPanel}
*/
function mapFileSystemToNetwork(networkUISourceCode)
{
if (!networkUISourceCode)
return;
this._networkMapping.addMapping(networkUISourceCode, uiSourceCode);
}
},
/**
* @param {!WebInspector.UISourceCode} networkUISourceCode
*/
mapNetworkToFileSystem: function(networkUISourceCode)
{
WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this));
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @this {WebInspector.SourcesPanel}
*/
function mapNetworkToFileSystem(uiSourceCode)
{
if (!uiSourceCode)
return;
this._networkMapping.addMapping(networkUISourceCode, uiSourceCode);
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeNetworkMapping: function(uiSourceCode)
{
this._networkMapping.removeMapping(uiSourceCode);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
{
WebInspector.NavigatorView.appendAddFolderItem(contextMenu);
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var hasMappings = !!this._networkMapping.networkURL(uiSourceCode);
if (!hasMappings)
contextMenu.appendItem(WebInspector.UIString.capitalize("Map to ^network ^resource\u2026"), this.mapFileSystemToNetwork.bind(this, uiSourceCode));
else
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^network ^mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
}
/**
* @param {!WebInspector.Project} project
*/
function filterProject(project)
{
return project.type() === WebInspector.projectTypes.FileSystem;
}
if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
if (!this._workspace.projects().filter(filterProject).length)
return;
var networkURL = this._networkMapping.networkURL(uiSourceCode);
if (this._networkMapping.uiSourceCodeForURLForAnyTarget(networkURL) === uiSourceCode)
contextMenu.appendItem(WebInspector.UIString.capitalize("Map to ^file ^system ^resource\u2026"), this.mapNetworkToFileSystem.bind(this, uiSourceCode));
}
},
/**
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
_appendUISourceCodeItems: function(event, contextMenu, target)
{
if (!(target instanceof WebInspector.UISourceCode))
return;
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target);
var projectType = uiSourceCode.project().type();
if (projectType !== WebInspector.projectTypes.Debugger && !event.target.isSelfOrDescendant(this._navigator.view.element)) {
contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in ^navigator"), this._handleContextMenuReveal.bind(this, uiSourceCode));
contextMenu.appendSeparator();
}
this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
if (projectType !== WebInspector.projectTypes.FileSystem)
contextMenu.appendItem(WebInspector.UIString.capitalize("Local ^modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} object
*/
appendUILocationItems: function(contextMenu, object)
{
if (!(object instanceof WebInspector.UILocation))
return;
var uiLocation = /** @type {!WebInspector.UILocation} */ (object);
var uiSourceCode = uiLocation.uiSourceCode;
var projectType = uiSourceCode.project().type();
var contentType = uiSourceCode.contentType();
if (contentType.hasScripts()) {
var target = WebInspector.context.flavor(WebInspector.Target);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
if (debuggerModel && debuggerModel.isPaused())
contextMenu.appendItem(WebInspector.UIString.capitalize("Continue to ^here"), this._continueToLocation.bind(this, uiLocation));
}
if (contentType.hasScripts() && projectType !== WebInspector.projectTypes.Snippets)
this.sidebarPanes.callstack.appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_handleContextMenuReveal: function(uiSourceCode)
{
this.editorView.showBoth();
this._revealInNavigator(uiSourceCode);
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
_appendRemoteObjectItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.RemoteObject))
return;
var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
contextMenu.appendItem(WebInspector.UIString.capitalize("Store as ^global ^variable"), this._saveToTempVariable.bind(this, remoteObject));
if (remoteObject.type === "function")
contextMenu.appendItem(WebInspector.UIString.capitalize("Show ^function ^definition"), this._showFunctionDefinition.bind(this, remoteObject));
if (remoteObject.subtype === "generator")
contextMenu.appendItem(WebInspector.UIString.capitalize("Show ^generator ^location"), this._showGeneratorLocation.bind(this, remoteObject));
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
_appendNetworkRequestItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.NetworkRequest))
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (target);
var uiSourceCode = this._networkMapping.uiSourceCodeForURLForAnyTarget(request.url);
if (!uiSourceCode)
return;
var openText = WebInspector.UIString.capitalize("Open in Sources ^panel");
contextMenu.appendItem(openText, this.showUILocation.bind(this, uiSourceCode.uiLocation(0, 0)));
},
/**
* @param {!WebInspector.RemoteObject} remoteObject
*/
_saveToTempVariable: function(remoteObject)
{
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (!currentExecutionContext)
return;
currentExecutionContext.globalObject("", false, false, didGetGlobalObject);
/**
* @param {?WebInspector.RemoteObject} global
* @param {boolean=} wasThrown
*/
function didGetGlobalObject(global, wasThrown)
{
/**
* @suppressReceiverCheck
* @this {Window}
*/
function remoteFunction(value)
{
var prefix = "temp";
var index = 1;
while ((prefix + index) in this)
++index;
var name = prefix + index;
this[name] = value;
return name;
}
if (wasThrown || !global)
failedToSave(global);
else
global.callFunction(remoteFunction, [WebInspector.RemoteObject.toCallArgument(remoteObject)], didSave.bind(null, global));
}
/**
* @param {!WebInspector.RemoteObject} global
* @param {?WebInspector.RemoteObject} result
* @param {boolean=} wasThrown
*/
function didSave(global, result, wasThrown)
{
global.release();
if (wasThrown || !result || result.type !== "string")
failedToSave(result);
else
WebInspector.ConsoleModel.evaluateCommandInConsole(/** @type {!WebInspector.ExecutionContext} */ (currentExecutionContext), result.value);
}
/**
* @param {?WebInspector.RemoteObject} result
*/
function failedToSave(result)
{
var message = WebInspector.UIString("Failed to save to temp variable.");
if (result) {
message += " " + result.description;
result.release();
}
WebInspector.console.error(message);
}
},
/**
* @param {!WebInspector.RemoteObject} remoteObject
*/
_showFunctionDefinition: function(remoteObject)
{
remoteObject.debuggerModel().functionDetails(remoteObject, this._didGetFunctionOrGeneratorObjectDetails.bind(this));
},
/**
* @param {!WebInspector.RemoteObject} remoteObject
*/
_showGeneratorLocation: function(remoteObject)
{
remoteObject.debuggerModel().generatorObjectDetails(remoteObject, this._didGetFunctionOrGeneratorObjectDetails.bind(this));
},
/**
* @param {?{location: ?WebInspector.DebuggerModel.Location}} response
*/
_didGetFunctionOrGeneratorObjectDetails: function(response)
{
if (!response || !response.location)
return;
var location = response.location;
if (!location)
return;
var uiLocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location);
if (uiLocation)
this.showUILocation(uiLocation);
},
showGoToSourceDialog: function()
{
this._sourcesView.showOpenResourceDialog();
},
_updateSidebarPosition: function()
{
var vertically;
var position = WebInspector.moduleSetting("sidebarPosition").get();
if (position === "right")
vertically = false;
else if (position === "bottom")
vertically = true;
else
vertically = WebInspector.inspectorView.element.offsetWidth < 680;
if (this.sidebarPaneView && vertically === !this._splitWidget.isVertical())
return;
if (this.sidebarPaneView && this.sidebarPaneView.shouldHideOnDetach())
return; // We can't reparent extension iframes.
if (this.sidebarPaneView)
this.sidebarPaneView.detach();
this._splitWidget.setVertical(!vertically);
this._splitWidget.element.classList.toggle("sources-split-view-vertical", vertically);
if (!vertically)
this._splitWidget.uninstallResizer(this._sourcesView.toolbarContainerElement());
else
this._splitWidget.installResizer(this._sourcesView.toolbarContainerElement());
// Create vertical box with stack.
var vbox = new WebInspector.VBox();
vbox.element.appendChild(this._debugToolbarDrawer);
vbox.setMinimumAndPreferredSizes(25, 25, WebInspector.SourcesPanel.minToolbarWidth, 100);
var sidebarPaneStack = new WebInspector.SidebarPaneStack();
sidebarPaneStack.element.classList.add("flex-auto");
sidebarPaneStack.show(vbox.element);
vbox.element.appendChild(this._debugToolbar.element);
if (!vertically) {
// Populate the only stack.
for (var pane in this.sidebarPanes)
sidebarPaneStack.addPane(this.sidebarPanes[pane]);
this._extensionSidebarPanesContainer = sidebarPaneStack;
this.sidebarPaneView = vbox;
this.sidebarPanes.scopechain.expand();
this.sidebarPanes.watchExpressions.expandIfNecessary();
} else {
var splitWidget = new WebInspector.SplitWidget(true, true, "sourcesPanelDebuggerSidebarSplitViewState", 0.5);
splitWidget.setMainWidget(vbox);
// Populate the left stack.
sidebarPaneStack.addPane(this.sidebarPanes.threads);
sidebarPaneStack.addPane(this.sidebarPanes.callstack);
sidebarPaneStack.addPane(this.sidebarPanes.jsBreakpoints);
sidebarPaneStack.addPane(this.sidebarPanes.domBreakpoints);
sidebarPaneStack.addPane(this.sidebarPanes.xhrBreakpoints);
sidebarPaneStack.addPane(this.sidebarPanes.eventListenerBreakpoints);
sidebarPaneStack.addPane(this.sidebarPanes.objectEventListeners);
var tabbedPane = new WebInspector.SidebarTabbedPane();
splitWidget.setSidebarWidget(tabbedPane);
tabbedPane.addPane(this.sidebarPanes.scopechain);
tabbedPane.addPane(this.sidebarPanes.watchExpressions);
if (this.sidebarPanes.serviceWorkers)
tabbedPane.addPane(this.sidebarPanes.serviceWorkers);
tabbedPane.selectTab(this._lastSelectedTabSetting.get());
tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._extensionSidebarPanesContainer = tabbedPane;
this.sidebarPaneView = splitWidget;
}
var extensionSidebarPanes = WebInspector.extensionServer.sidebarPanes();
for (var i = 0; i < extensionSidebarPanes.length; ++i)
this._addExtensionSidebarPane(extensionSidebarPanes[i]);
this._splitWidget.setSidebarWidget(this.sidebarPaneView);
this.sidebarPanes.threads.expand();
this.sidebarPanes.jsBreakpoints.expand();
this.sidebarPanes.callstack.expand();
},
/**
* @param {!WebInspector.Event} event
*/
_tabSelected: function(event)
{
this._lastSelectedTabSetting.set(event.data.tabId);
},
/**
* @param {!WebInspector.Event} event
*/
_extensionSidebarPaneAdded: function(event)
{
var pane = /** @type {!WebInspector.ExtensionSidebarPane} */ (event.data);
this._addExtensionSidebarPane(pane);
},
/**
* @param {!WebInspector.ExtensionSidebarPane} pane
*/
_addExtensionSidebarPane: function(pane)
{
if (pane.panelName() === this.name)
this._extensionSidebarPanesContainer.addPane(pane);
},
/**
* @return {!WebInspector.SourcesView}
*/
sourcesView: function()
{
return this._sourcesView;
},
/**
* @param {!DataTransfer} dataTransfer
*/
_handleDrop: function(dataTransfer)
{
var items = dataTransfer.items;
if (!items.length)
return;
var entry = items[0].webkitGetAsEntry();
if (!entry.isDirectory)
return;
InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);
},
__proto__: WebInspector.Panel.prototype
}
/**
* @constructor
* @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.SourcesPanel.ContextMenuProvider = function()
{
}
WebInspector.SourcesPanel.ContextMenuProvider.prototype = {
/**
* @override
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
WebInspector.SourcesPanel.instance().appendApplicableItems(event, contextMenu, target);
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.SourcesPanel.UILocationRevealer = function()
{
}
WebInspector.SourcesPanel.UILocationRevealer.prototype = {
/**
* @override
* @param {!Object} uiLocation
* @return {!Promise}
*/
reveal: function(uiLocation)
{
if (!(uiLocation instanceof WebInspector.UILocation))
return Promise.reject(new Error("Internal error: not a ui location"));
WebInspector.SourcesPanel.instance().showUILocation(uiLocation);
return Promise.resolve();
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.SourcesPanel.DebuggerLocationRevealer = function()
{
}
WebInspector.SourcesPanel.DebuggerLocationRevealer.prototype = {
/**
* @override
* @param {!Object} rawLocation
* @return {!Promise}
*/
reveal: function(rawLocation)
{
if (!(rawLocation instanceof WebInspector.DebuggerModel.Location))
return Promise.reject(new Error("Internal error: not a debugger location"));
WebInspector.SourcesPanel.instance().showUILocation(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation));
return Promise.resolve();
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.SourcesPanel.UISourceCodeRevealer = function()
{
}
WebInspector.SourcesPanel.UISourceCodeRevealer.prototype = {
/**
* @override
* @param {!Object} uiSourceCode
* @return {!Promise}
*/
reveal: function(uiSourceCode)
{
if (!(uiSourceCode instanceof WebInspector.UISourceCode))
return Promise.reject(new Error("Internal error: not a ui source code"));
WebInspector.SourcesPanel.instance().showUISourceCode(uiSourceCode);
return Promise.resolve();
}
}
/**
* @constructor
* @implements {WebInspector.Revealer}
*/
WebInspector.SourcesPanel.DebuggerPausedDetailsRevealer = function()
{
}
WebInspector.SourcesPanel.DebuggerPausedDetailsRevealer.prototype = {
/**
* @override
* @param {!Object} object
* @return {!Promise}
*/
reveal: function(object)
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());
return Promise.resolve();
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.SourcesPanel.RevealingActionDelegate = function() {}
WebInspector.SourcesPanel.RevealingActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var panel = WebInspector.SourcesPanel.instance();
if (panel !== WebInspector.inspectorView.setCurrentPanel(panel))
return false;
switch (actionId) {
case "debugger.toggle-pause":
panel._togglePause();
return true;
case "sources.go-to-source":
panel.showGoToSourceDialog();
return true;
}
return false;
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.SourcesPanel.DebuggingActionDelegate = function()
{
}
WebInspector.SourcesPanel.DebuggingActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var panel = WebInspector.SourcesPanel.instance();
switch (actionId) {
case "debugger.step-over":
panel._stepOver();
return true;
case "debugger.step-into":
panel._stepInto();
return true;
case "debugger.step-out":
panel._stepOut();
return true;
case "debugger.run-snippet":
panel._runSnippet();
return true;
case "debugger.toggle-breakpoints-active":
panel._toggleBreakpointsActive();
return true;
}
return false;
}
}
WebInspector.SourcesPanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());
}
/**
* @return {!WebInspector.SourcesPanel}
*/
WebInspector.SourcesPanel.instance = function()
{
if (!WebInspector.SourcesPanel._instanceObject)
WebInspector.SourcesPanel._instanceObject = new WebInspector.SourcesPanel();
return WebInspector.SourcesPanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.SourcesPanelFactory = function()
{
}
WebInspector.SourcesPanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.SourcesPanel.instance();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | 2 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.SearchScope}
*/
WebInspector.SourcesSearchScope = function()
{
// FIXME: Add title once it is used by search controller.
this._searchId = 0;
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode1
* @param {!WebInspector.UISourceCode} uiSourceCode2
* @return {number}
*/
WebInspector.SourcesSearchScope._filesComparator = function(uiSourceCode1, uiSourceCode2)
{
if (uiSourceCode1.isDirty() && !uiSourceCode2.isDirty())
return -1;
if (!uiSourceCode1.isDirty() && uiSourceCode2.isDirty())
return 1;
var networkURL1 = WebInspector.networkMapping.networkURL(uiSourceCode1);
var networkURL2 = WebInspector.networkMapping.networkURL(uiSourceCode2);
if (networkURL1 && !networkURL2)
return -1;
if (!networkURL1 && networkURL2)
return 1;
return String.naturalOrderComparator(uiSourceCode1.fullDisplayName(), uiSourceCode2.fullDisplayName());
}
WebInspector.SourcesSearchScope.prototype = {
/**
* @override
* @param {!WebInspector.Progress} progress
*/
performIndexing: function(progress)
{
this.stopSearch();
var projects = this._projects();
var compositeProgress = new WebInspector.CompositeProgress(progress);
for (var i = 0; i < projects.length; ++i) {
var project = projects[i];
var projectProgress = compositeProgress.createSubProgress(project.uiSourceCodes().length);
project.indexContent(projectProgress);
}
},
/**
* @return {!Array.<!WebInspector.Project>}
*/
_projects: function()
{
/**
* @param {!WebInspector.Project} project
* @return {boolean}
*/
function filterOutServiceProjects(project)
{
return project.type() !== WebInspector.projectTypes.Service;
}
/**
* @param {!WebInspector.Project} project
* @return {boolean}
*/
function filterOutContentScriptsIfNeeded(project)
{
return WebInspector.moduleSetting("searchInContentScripts").get() || project.type() !== WebInspector.projectTypes.ContentScripts;
}
return WebInspector.workspace.projects().filter(filterOutServiceProjects).filter(filterOutContentScriptsIfNeeded);
},
/**
* @override
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!WebInspector.FileBasedSearchResult)} searchResultCallback
* @param {function(boolean)} searchFinishedCallback
*/
performSearch: function(searchConfig, progress, searchResultCallback, searchFinishedCallback)
{
this.stopSearch();
this._searchResultCandidates = [];
this._searchResultCallback = searchResultCallback;
this._searchFinishedCallback = searchFinishedCallback;
this._searchConfig = searchConfig;
var projects = this._projects();
var barrier = new CallbackBarrier();
var compositeProgress = new WebInspector.CompositeProgress(progress);
var searchContentProgress = compositeProgress.createSubProgress();
var findMatchingFilesProgress = new WebInspector.CompositeProgress(compositeProgress.createSubProgress());
for (var i = 0; i < projects.length; ++i) {
var project = projects[i];
var weight = project.uiSourceCodes().length;
var findMatchingFilesInProjectProgress = findMatchingFilesProgress.createSubProgress(weight);
var barrierCallback = barrier.createCallback();
var filesMathingFileQuery = this._projectFilesMatchingFileQuery(project, searchConfig);
var callback = this._processMatchingFilesForProject.bind(this, this._searchId, project, filesMathingFileQuery, barrierCallback);
project.findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, findMatchingFilesInProjectProgress, callback);
}
barrier.callWhenDone(this._processMatchingFiles.bind(this, this._searchId, searchContentProgress, this._searchFinishedCallback.bind(this, true)));
},
/**
* @param {!WebInspector.Project} project
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {boolean=} dirtyOnly
* @return {!Array.<string>}
*/
_projectFilesMatchingFileQuery: function(project, searchConfig, dirtyOnly)
{
var result = [];
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i) {
var uiSourceCode = uiSourceCodes[i];
if (dirtyOnly && !uiSourceCode.isDirty())
continue;
if (this._searchConfig.filePathMatchesFileQuery(uiSourceCode.fullDisplayName()))
result.push(uiSourceCode.url());
}
result.sort(String.naturalOrderComparator);
return result;
},
/**
* @param {number} searchId
* @param {!WebInspector.Project} project
* @param {!Array.<string>} filesMathingFileQuery
* @param {function()} callback
* @param {!Array.<string>} files
*/
_processMatchingFilesForProject: function(searchId, project, filesMathingFileQuery, callback, files)
{
if (searchId !== this._searchId) {
this._searchFinishedCallback(false);
return;
}
files.sort(String.naturalOrderComparator);
files = files.intersectOrdered(filesMathingFileQuery, String.naturalOrderComparator);
var dirtyFiles = this._projectFilesMatchingFileQuery(project, this._searchConfig, true);
files = files.mergeOrdered(dirtyFiles, String.naturalOrderComparator);
var uiSourceCodes = [];
for (var i = 0; i < files.length; ++i) {
var uiSourceCode = project.uiSourceCodeForURL(files[i]);
if (uiSourceCode) {
var script = WebInspector.DefaultScriptMapping.scriptForUISourceCode(uiSourceCode);
if (script && (script.isInternalScript() || !script.isAnonymousScript()))
continue;
uiSourceCodes.push(uiSourceCode);
}
}
uiSourceCodes.sort(WebInspector.SourcesSearchScope._filesComparator);
this._searchResultCandidates = this._searchResultCandidates.mergeOrdered(uiSourceCodes, WebInspector.SourcesSearchScope._filesComparator);
callback();
},
/**
* @param {number} searchId
* @param {!WebInspector.Progress} progress
* @param {function()} callback
*/
_processMatchingFiles: function(searchId, progress, callback)
{
if (searchId !== this._searchId) {
this._searchFinishedCallback(false);
return;
}
var files = this._searchResultCandidates;
if (!files.length) {
progress.done();
callback();
return;
}
progress.setTotalWork(files.length);
var fileIndex = 0;
var maxFileContentRequests = 20;
var callbacksLeft = 0;
for (var i = 0; i < maxFileContentRequests && i < files.length; ++i)
scheduleSearchInNextFileOrFinish.call(this);
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @this {WebInspector.SourcesSearchScope}
*/
function searchInNextFile(uiSourceCode)
{
if (uiSourceCode.isDirty())
contentLoaded.call(this, uiSourceCode, uiSourceCode.workingCopy());
else
uiSourceCode.checkContentUpdated(true, contentUpdated.bind(this, uiSourceCode));
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @this {WebInspector.SourcesSearchScope}
*/
function contentUpdated(uiSourceCode)
{
uiSourceCode.requestContent().then(contentLoaded.bind(this, uiSourceCode));
}
/**
* @this {WebInspector.SourcesSearchScope}
*/
function scheduleSearchInNextFileOrFinish()
{
if (fileIndex >= files.length) {
if (!callbacksLeft) {
progress.done();
callback();
return;
}
return;
}
++callbacksLeft;
var uiSourceCode = files[fileIndex++];
setTimeout(searchInNextFile.bind(this, uiSourceCode), 0);
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?string} content
* @this {WebInspector.SourcesSearchScope}
*/
function contentLoaded(uiSourceCode, content)
{
/**
* @param {!WebInspector.ContentProvider.SearchMatch} a
* @param {!WebInspector.ContentProvider.SearchMatch} b
*/
function matchesComparator(a, b)
{
return a.lineNumber - b.lineNumber;
}
progress.worked(1);
var matches = [];
var queries = this._searchConfig.queries();
if (content !== null) {
for (var i = 0; i < queries.length; ++i) {
var nextMatches = WebInspector.ContentProvider.performSearchInContent(content, queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex());
matches = matches.mergeOrdered(nextMatches, matchesComparator);
}
}
if (matches) {
var searchResult = new WebInspector.FileBasedSearchResult(uiSourceCode, matches);
this._searchResultCallback(searchResult);
}
--callbacksLeft;
scheduleSearchInNextFileOrFinish.call(this);
}
},
/**
* @override
*/
stopSearch: function()
{
++this._searchId;
},
/**
* @override
* @param {!WebInspector.ProjectSearchConfig} searchConfig
* @return {!WebInspector.FileBasedSearchResultsPane}
*/
createSearchResultsPane: function(searchConfig)
{
return new WebInspector.FileBasedSearchResultsPane(searchConfig);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | 2 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.TabbedEditorContainerDelegate}
* @implements {WebInspector.Searchable}
* @implements {WebInspector.Replaceable}
* @extends {WebInspector.VBox}
* @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.SourcesPanel} sourcesPanel
* @suppressGlobalPropertiesCheck
*/
WebInspector.SourcesView = function(workspace, sourcesPanel)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("sources/sourcesView.css");
this.element.id = "sources-panel-sources-view";
this.setMinimumAndPreferredSizes(50, 52, 150, 100);
this._workspace = workspace;
this._sourcesPanel = sourcesPanel;
this._searchableView = new WebInspector.SearchableView(this, "sourcesViewSearchConfig");
this._searchableView.setMinimalSearchQuerySize(0);
this._searchableView.show(this.element);
/** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.VBoxWithToolbarItems>} */
this._sourceViewByUISourceCode = new Map();
var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIString("Hit Cmd+P to open a file") : WebInspector.UIString("Hit Ctrl+P to open a file");
this._editorContainer = new WebInspector.TabbedEditorContainer(this, WebInspector.settings.createLocalSetting("previouslyViewedFiles", []), tabbedEditorPlaceholderText);
this._editorContainer.show(this._searchableView.element);
this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
this._historyManager = new WebInspector.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));
this._toolbarContainerElement = this.element.createChild("div", "sources-toolbar");
this._toolbarEditorActions = new WebInspector.Toolbar("", this._toolbarContainerElement);
self.runtime.instancesPromise(WebInspector.SourcesView.EditorAction).then(appendButtonsForExtensions.bind(this));
/**
* @param {!Array.<!WebInspector.SourcesView.EditorAction>} actions
* @this {WebInspector.SourcesView}
*/
function appendButtonsForExtensions(actions)
{
for (var i = 0; i < actions.length; ++i)
this._toolbarEditorActions.appendToolbarItem(actions[i].button(this));
}
this._scriptViewToolbar = new WebInspector.Toolbar("", this._toolbarContainerElement);
WebInspector.startBatchUpdate();
this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
WebInspector.endBatchUpdate();
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
function handleBeforeUnload(event)
{
if (event.returnValue)
return;
var unsavedSourceCodes = WebInspector.workspace.unsavedSourceCodes();
if (!unsavedSourceCodes.length)
return;
event.returnValue = WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");
WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());
for (var i = 0; i < unsavedSourceCodes.length; ++i)
WebInspector.Revealer.reveal(unsavedSourceCodes[i]);
}
if (!window.opener)
window.addEventListener("beforeunload", handleBeforeUnload, true);
this._shortcuts = {};
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
}
WebInspector.SourcesView.Events = {
EditorClosed: "EditorClosed",
EditorSelected: "EditorSelected",
}
WebInspector.SourcesView.prototype = {
/**
* @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(!Event=):boolean)} registerShortcutDelegate
*/
registerShortcuts: function(registerShortcutDelegate)
{
/**
* @this {WebInspector.SourcesView}
* @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
* @param {function(!Event=):boolean} handler
*/
function registerShortcut(shortcuts, handler)
{
registerShortcutDelegate(shortcuts, handler);
this._registerShortcuts(shortcuts, handler);
}
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation, this._onJumpToPreviousLocation.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation, this._onJumpToNextLocation.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab, this._onCloseEditorTab.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, this._showGoToLineDialog.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, this._showOutlineDialog.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.Save, this._save.bind(this));
registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SaveAll, this._saveAll.bind(this));
},
/**
* @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
* @param {function(!Event=):boolean} handler
*/
_registerShortcuts: function(keys, handler)
{
for (var i = 0; i < keys.length; ++i)
this._shortcuts[keys[i].key] = handler;
},
_handleKeyDown: function(event)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
event.consume(true);
},
wasShown: function()
{
WebInspector.VBox.prototype.wasShown.call(this);
WebInspector.context.setFlavor(WebInspector.SourcesView, this);
},
willHide: function()
{
WebInspector.context.setFlavor(WebInspector.SourcesView, null);
WebInspector.VBox.prototype.willHide.call(this);
},
/**
* @return {!Element}
*/
toolbarContainerElement: function()
{
return this._toolbarContainerElement;
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._editorContainer.view.defaultFocusedElement();
},
/**
* @return {!WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
/**
* @return {!WebInspector.Widget}
*/
visibleView: function()
{
return this._editorContainer.visibleView;
},
/**
* @return {?WebInspector.UISourceCodeFrame}
*/
currentSourceFrame: function()
{
var view = this.visibleView();
if (!(view instanceof WebInspector.UISourceCodeFrame))
return null;
return /** @type {!WebInspector.UISourceCodeFrame} */ (view);
},
/**
* @return {?WebInspector.UISourceCode}
*/
currentUISourceCode: function()
{
return this._currentUISourceCode;
},
/**
* @param {!Event=} event
*/
_onCloseEditorTab: function(event)
{
var uiSourceCode = this.currentUISourceCode();
if (!uiSourceCode)
return false;
this._editorContainer.closeFile(uiSourceCode);
return true;
},
/**
* @param {!Event=} event
*/
_onJumpToPreviousLocation: function(event)
{
this._historyManager.rollback();
return true;
},
/**
* @param {!Event=} event
*/
_onJumpToNextLocation: function(event)
{
this._historyManager.rollover();
return true;
},
/**
* @param {!WebInspector.Event} event
*/
_uiSourceCodeAdded: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._addUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_addUISourceCode: function(uiSourceCode)
{
if (uiSourceCode.isFromServiceProject())
return;
this._editorContainer.addUISourceCode(uiSourceCode);
// Replace debugger script-based uiSourceCode with a network-based one.
var currentUISourceCode = this._currentUISourceCode;
if (!currentUISourceCode)
return;
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
var currentNetworkURL = WebInspector.networkMapping.networkURL(currentUISourceCode);
if (currentUISourceCode.isFromServiceProject() && currentUISourceCode !== uiSourceCode && currentNetworkURL === networkURL && networkURL) {
this._showFile(uiSourceCode);
this._editorContainer.removeUISourceCode(currentUISourceCode);
}
},
_uiSourceCodeRemoved: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._removeUISourceCodes([uiSourceCode]);
},
/**
* @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes
*/
_removeUISourceCodes: function(uiSourceCodes)
{
this._editorContainer.removeUISourceCodes(uiSourceCodes);
for (var i = 0; i < uiSourceCodes.length; ++i) {
this._removeSourceFrame(uiSourceCodes[i]);
this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
}
},
_projectRemoved: function(event)
{
var project = event.data;
var uiSourceCodes = project.uiSourceCodes();
this._removeUISourceCodes(uiSourceCodes);
},
_updateScriptViewToolbarItems: function()
{
this._scriptViewToolbar.removeToolbarItems();
var view = /** @type {?WebInspector.VBoxWithToolbarItems} */(this.visibleView());
if (view) {
for (var item of view.toolbarItems())
this._scriptViewToolbar.appendToolbarItem(item);
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber 0-based
* @param {number=} columnNumber
* @param {boolean=} omitFocus
* @param {boolean=} omitHighlight
*/
showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHighlight)
{
this._historyManager.updateCurrentState();
var sourceView = this._showFile(uiSourceCode);
if (typeof lineNumber === "number" && sourceView instanceof WebInspector.UISourceCodeFrame)
/** @type {!WebInspector.UISourceCodeFrame} */(sourceView).revealPosition(lineNumber, columnNumber, !omitHighlight);
this._historyManager.pushNewState();
if (!omitFocus)
sourceView.focus();
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!WebInspector.Widget}
*/
_showFile: function(uiSourceCode)
{
var sourceView = this._getOrCreateSourceView(uiSourceCode);
if (this._currentUISourceCode === uiSourceCode)
return sourceView;
var currentFrame = this.currentSourceFrame();
if (currentFrame)
currentFrame.setSearchableView(null);
this._currentUISourceCode = uiSourceCode;
this._editorContainer.showFile(uiSourceCode);
this._updateScriptViewToolbarItems();
currentFrame = this.currentSourceFrame();
if (currentFrame)
currentFrame.setSearchableView(this._searchableView);
return sourceView;
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!WebInspector.Widget}
*/
_createSourceView: function(uiSourceCode)
{
var sourceFrame;
var sourceView;
var contentType = uiSourceCode.contentType();
if (contentType.hasScripts())
sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode);
else if (contentType.isStyleSheet())
sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode);
else if (contentType === WebInspector.resourceTypes.Image)
sourceView = new WebInspector.ImageView(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode), uiSourceCode);
else if (contentType === WebInspector.resourceTypes.Font)
sourceView = new WebInspector.FontView(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode), uiSourceCode);
else
sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
if (sourceFrame) {
sourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode));
this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
}
this._sourceViewByUISourceCode.set(uiSourceCode, /** @type {!WebInspector.VBoxWithToolbarItems} */(sourceFrame || sourceView));
return /** @type {!WebInspector.Widget} */(sourceFrame || sourceView);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!WebInspector.Widget}
*/
_getOrCreateSourceView: function(uiSourceCode)
{
return this._sourceViewByUISourceCode.get(uiSourceCode) || this._createSourceView(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCodeFrame} sourceFrame
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {boolean}
*/
_sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode)
{
if (uiSourceCode.contentType().hasScripts())
return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;
if (uiSourceCode.contentType().isStyleSheet())
return sourceFrame instanceof WebInspector.CSSSourceFrame;
return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_recreateSourceFrameIfNeeded: function(uiSourceCode)
{
var oldSourceView = this._sourceViewByUISourceCode.get(uiSourceCode);
if (!oldSourceView || !(oldSourceView instanceof WebInspector.UISourceCodeFrame))
return;
var oldSourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */(oldSourceView);
if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
oldSourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode));
} else {
this._editorContainer.removeUISourceCode(uiSourceCode);
this._removeSourceFrame(uiSourceCode);
}
},
/**
* @override
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!WebInspector.Widget}
*/
viewForFile: function(uiSourceCode)
{
return this._getOrCreateSourceView(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeSourceFrame: function(uiSourceCode)
{
var sourceView = this._sourceViewByUISourceCode.get(uiSourceCode);
this._sourceViewByUISourceCode.remove(uiSourceCode);
if (sourceView && sourceView instanceof WebInspector.UISourceCodeFrame)
/** @type {!WebInspector.UISourceCodeFrame} */ (sourceView).dispose();
},
clearCurrentExecutionLine: function()
{
if (this._executionSourceFrame)
this._executionSourceFrame.clearExecutionLine();
delete this._executionSourceFrame;
},
/**
* @param {!WebInspector.UILocation} uiLocation
*/
setExecutionLocation: function(uiLocation)
{
var sourceView = this._getOrCreateSourceView(uiLocation.uiSourceCode);
if (sourceView instanceof WebInspector.UISourceCodeFrame) {
var sourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */(sourceView);
sourceFrame.setExecutionLocation(uiLocation);
this._executionSourceFrame = sourceFrame;
}
},
_editorClosed: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._historyManager.removeHistoryForSourceCode(uiSourceCode);
var wasSelected = false;
if (this._currentUISourceCode === uiSourceCode) {
delete this._currentUISourceCode;
wasSelected = true;
}
// SourcesNavigator does not need to update on EditorClosed.
this._updateScriptViewToolbarItems();
this._searchableView.resetSearch();
var data = {};
data.uiSourceCode = uiSourceCode;
data.wasSelected = wasSelected;
this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClosed, data);
},
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.currentFile);
var shouldUseHistoryManager = uiSourceCode !== this._currentUISourceCode && event.data.userGesture;
if (shouldUseHistoryManager)
this._historyManager.updateCurrentState();
var sourceView = this._showFile(uiSourceCode);
if (shouldUseHistoryManager)
this._historyManager.pushNewState();
this._searchableView.setReplaceable(sourceView instanceof WebInspector.UISourceCodeFrame && /** @type {!WebInspector.UISourceCodeFrame} */(sourceView).canEditSource());
this._searchableView.refreshSearch();
this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSelected, uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
sourceRenamed: function(uiSourceCode)
{
this._recreateSourceFrameIfNeeded(uiSourceCode);
},
/**
* @override
*/
searchCanceled: function()
{
if (this._searchView)
this._searchView.searchCanceled();
delete this._searchView;
delete this._searchConfig;
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var sourceFrame = this.currentSourceFrame();
if (!sourceFrame)
return;
this._searchView = sourceFrame;
this._searchConfig = searchConfig;
this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackwards);
},
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._searchView)
return;
if (this._searchView !== this.currentSourceFrame()) {
this.performSearch(this._searchConfig, true);
return;
}
this._searchView.jumpToNextSearchResult();
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._searchView)
return;
if (this._searchView !== this.currentSourceFrame()) {
this.performSearch(this._searchConfig, true);
if (this._searchView)
this._searchView.jumpToLastSearchResult();
return;
}
this._searchView.jumpToPreviousSearchResult();
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return true;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return true;
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceSelectionWith: function(searchConfig, replacement)
{
var sourceFrame = this.currentSourceFrame();
if (!sourceFrame) {
console.assert(sourceFrame);
return;
}
sourceFrame.replaceSelectionWith(searchConfig, replacement);
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceAllWith: function(searchConfig, replacement)
{
var sourceFrame = this.currentSourceFrame();
if (!sourceFrame) {
console.assert(sourceFrame);
return;
}
sourceFrame.replaceAllWith(searchConfig, replacement);
},
/**
* @param {!Event=} event
* @return {boolean}
*/
_showOutlineDialog: function(event)
{
var uiSourceCode = this._editorContainer.currentFile();
if (!uiSourceCode)
return false;
if (uiSourceCode.contentType().hasScripts()) {
WebInspector.JavaScriptOutlineDialog.show(uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
return true;
}
if (uiSourceCode.contentType().isStyleSheet()) {
WebInspector.StyleSheetOutlineDialog.show(uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
return true;
}
// We don't want default browser shortcut to be executed, so pretend to handle this event.
return true;
},
/**
* @param {string=} query
*/
showOpenResourceDialog: function(query)
{
var uiSourceCodes = this._editorContainer.historyUISourceCodes();
/** @type {!Map.<!WebInspector.UISourceCode, number>} */
var defaultScores = new Map();
for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i);
if (!this._openResourceDialogHistory)
this._openResourceDialogHistory = [];
WebInspector.OpenResourceDialog.show(this, query || "", defaultScores, this._openResourceDialogHistory);
},
/**
* @param {!Event=} event
* @return {boolean}
*/
_showGoToLineDialog: function(event)
{
if (this._currentUISourceCode)
this.showOpenResourceDialog(":");
return true;
},
/**
* @return {boolean}
*/
_save: function()
{
this._saveSourceFrame(this.currentSourceFrame());
return true;
},
/**
* @return {boolean}
*/
_saveAll: function()
{
var sourceFrames = this._editorContainer.fileViews();
sourceFrames.forEach(this._saveSourceFrame.bind(this));
return true;
},
/**
* @param {?WebInspector.Widget} sourceFrame
*/
_saveSourceFrame: function(sourceFrame)
{
if (!(sourceFrame instanceof WebInspector.UISourceCodeFrame))
return;
var uiSourceCodeFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (sourceFrame);
uiSourceCodeFrame.commitEditing();
},
/**
* @return {boolean}
*/
_toggleBreakpoint: function()
{
var sourceFrame = this.currentSourceFrame();
if (!sourceFrame)
return false;
if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
return true;
}
return false;
},
/**
* @param {boolean} active
*/
toggleBreakpointsActiveState: function(active)
{
this._editorContainer.view.element.classList.toggle("breakpoints-deactivated", !active);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @interface
*/
WebInspector.SourcesView.EditorAction = function()
{
}
WebInspector.SourcesView.EditorAction.prototype = {
/**
* @param {!WebInspector.SourcesView} sourcesView
* @return {!WebInspector.ToolbarButton}
*/
button: function(sourcesView) { }
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.SourcesView.SwitchFileActionDelegate = function()
{
}
/**
* @param {!WebInspector.UISourceCode} currentUISourceCode
* @return {?WebInspector.UISourceCode}
*/
WebInspector.SourcesView.SwitchFileActionDelegate._nextFile = function(currentUISourceCode)
{
/**
* @param {string} name
* @return {string}
*/
function fileNamePrefix(name)
{
var lastDotIndex = name.lastIndexOf(".");
var namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : name.length);
return namePrefix.toLowerCase();
}
var uiSourceCodes = currentUISourceCode.project().uiSourceCodes();
var candidates = [];
var url = currentUISourceCode.parentURL();
var name = currentUISourceCode.name();
var namePrefix = fileNamePrefix(name);
for (var i = 0; i < uiSourceCodes.length; ++i) {
var uiSourceCode = uiSourceCodes[i];
if (url !== uiSourceCode.parentURL())
continue;
if (fileNamePrefix(uiSourceCode.name()) === namePrefix)
candidates.push(uiSourceCode.name());
}
candidates.sort(String.naturalOrderComparator);
var index = mod(candidates.indexOf(name) + 1, candidates.length);
var fullURL = (url ? url + "/" : "") + candidates[index];
var nextUISourceCode = currentUISourceCode.project().uiSourceCodeForURL(fullURL);
return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null;
}
WebInspector.SourcesView.SwitchFileActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView);
var currentUISourceCode = sourcesView.currentUISourceCode();
if (!currentUISourceCode)
return false;
var nextUISourceCode = WebInspector.SourcesView.SwitchFileActionDelegate._nextFile(currentUISourceCode);
if (!nextUISourceCode)
return false;
sourcesView.showSourceLocation(nextUISourceCode);
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.FilteredListWidget.Delegate}
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
WebInspector.StyleSheetOutlineDialog = function(uiSourceCode, selectItemCallback)
{
WebInspector.FilteredListWidget.Delegate.call(this, []);
this._selectItemCallback = selectItemCallback;
this._cssParser = new WebInspector.CSSParser();
this._cssParser.addEventListener(WebInspector.CSSParser.Events.RulesParsed, this.refresh.bind(this));
this._cssParser.parse(uiSourceCode.workingCopy());
}
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
WebInspector.StyleSheetOutlineDialog.show = function(uiSourceCode, selectItemCallback)
{
WebInspector.StyleSheetOutlineDialog._instanceForTests = new WebInspector.StyleSheetOutlineDialog(uiSourceCode, selectItemCallback);
new WebInspector.FilteredListWidget(WebInspector.StyleSheetOutlineDialog._instanceForTests, false).showAsDialog();
}
WebInspector.StyleSheetOutlineDialog.prototype = {
/**
* @override
* @return {number}
*/
itemCount: function()
{
return this._cssParser.rules().length;
},
/**
* @override
* @param {number} itemIndex
* @return {string}
*/
itemKeyAt: function(itemIndex)
{
var rule = this._cssParser.rules()[itemIndex];
return rule.selectorText || rule.atRule;
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @return {number}
*/
itemScoreAt: function(itemIndex, query)
{
var rule = this._cssParser.rules()[itemIndex];
return -rule.lineNumber;
},
/**
* @override
* @param {number} itemIndex
* @param {string} query
* @param {!Element} titleElement
* @param {!Element} subtitleElement
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
var rule = this._cssParser.rules()[itemIndex];
titleElement.textContent = rule.selectorText || rule.atRule;
this.highlightRanges(titleElement, query);
subtitleElement.textContent = ":" + (rule.lineNumber + 1);
},
/**
* @override
* @param {number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
var rule = this._cssParser.rules()[itemIndex];
var lineNumber = rule.lineNumber;
if (!isNaN(lineNumber) && lineNumber >= 0)
this._selectItemCallback(lineNumber, rule.columnNumber);
},
dispose: function()
{
this._cssParser.dispose();
},
__proto__: WebInspector.FilteredListWidget.Delegate.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | 2 1 | /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.TabbedEditorContainerDelegate = function() { } WebInspector.TabbedEditorContainerDelegate.prototype = { /** * @param {!WebInspector.UISourceCode} uiSourceCode * @return {!WebInspector.Widget} */ viewForFile: function(uiSourceCode) { }, } /** * @constructor * @extends {WebInspector.Object} * @param {!WebInspector.TabbedEditorContainerDelegate} delegate * @param {!WebInspector.Setting} setting * @param {string} placeholderText */ WebInspector.TabbedEditorContainer = function(delegate, setting, placeholderText) { WebInspector.Object.call(this); this._delegate = delegate; this._tabbedPane = new WebInspector.TabbedPane(); this._tabbedPane.setPlaceholderText(placeholderText); this._tabbedPane.setTabDelegate(new WebInspector.EditorContainerTabDelegate(this)); this._tabbedPane.setCloseableTabs(true); this._tabbedPane.setAllowTabReorder(true, true); this._tabbedPane.insertBeforeTabStrip(createElementWithClass("div", "sources-editor-tabstrip-left")); this._tabbedPane.appendAfterTabStrip(createElementWithClass("div", "sources-editor-tabstrip-right")); this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this); this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this); this._tabIds = new Map(); this._files = {}; this._previouslyViewedFilesSetting = setting; this._history = WebInspector.TabbedEditorContainer.History.fromObject(this._previouslyViewedFilesSetting.get()); } WebInspector.TabbedEditorContainer.Events = { EditorSelected: "EditorSelected", EditorClosed: "EditorClosed" } WebInspector.TabbedEditorContainer._tabId = 0; WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount = 30; WebInspector.TabbedEditorContainer.prototype = { /** * @return {!WebInspector.Widget} */ get view() { return this._tabbedPane; }, /** * @type {!WebInspector.Widget} */ get visibleView() { return this._tabbedPane.visibleView; }, /** * @return {!Array.<!WebInspector.Widget>} */ fileViews: function() { return /** @type {!Array.<!WebInspector.Widget>} */ (this._tabbedPane.tabViews()); }, /** * @param {!Element} parentElement */ show: function(parentElement) { this._tabbedPane.show(parentElement); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ showFile: function(uiSourceCode) { this._innerShowFile(uiSourceCode, true); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ closeFile: function(uiSourceCode) { var tabId = this._tabIds.get(uiSourceCode); if (!tabId) return; this._closeTabs([tabId]); }, /** * @return {!Array.<!WebInspector.UISourceCode>} */ historyUISourceCodes: function() { // FIXME: there should be a way to fetch UISourceCode for its uri. var uriToUISourceCode = {}; for (var id in this._files) { var uiSourceCode = this._files[id]; uriToUISourceCode[uiSourceCode.url()] = uiSourceCode; } var result = []; var uris = this._history._urls(); for (var i = 0; i < uris.length; ++i) { var uiSourceCode = uriToUISourceCode[uris[i]]; if (uiSourceCode) result.push(uiSourceCode); } return result; }, _addViewListeners: function() { if (!this._currentView) return; this._currentView.addEventListener(WebInspector.SourceFrame.Events.ScrollChanged, this._scrollChanged, this); this._currentView.addEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this); }, _removeViewListeners: function() { if (!this._currentView) return; this._currentView.removeEventListener(WebInspector.SourceFrame.Events.ScrollChanged, this._scrollChanged, this); this._currentView.removeEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this); }, /** * @param {!WebInspector.Event} event */ _scrollChanged: function(event) { var lineNumber = /** @type {number} */ (event.data); this._history.updateScrollLineNumber(this._currentFile.url(), lineNumber); this._history.save(this._previouslyViewedFilesSetting); }, /** * @param {!WebInspector.Event} event */ _selectionChanged: function(event) { var range = /** @type {!WebInspector.TextRange} */ (event.data); this._history.updateSelectionRange(this._currentFile.url(), range); this._history.save(this._previouslyViewedFilesSetting); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {boolean=} userGesture */ _innerShowFile: function(uiSourceCode, userGesture) { if (this._currentFile === uiSourceCode) return; this._removeViewListeners(); this._currentFile = uiSourceCode; var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, userGesture); this._tabbedPane.selectTab(tabId, userGesture); if (userGesture) this._editorSelectedByUserAction(); this._currentView = this.visibleView; this._addViewListeners(); var eventData = { currentFile: this._currentFile, userGesture: userGesture }; this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorSelected, eventData); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @return {string} */ _titleForFile: function(uiSourceCode) { var maxDisplayNameLength = 30; var title = uiSourceCode.displayName(true).trimMiddle(maxDisplayNameLength); if (uiSourceCode.isDirty() || uiSourceCode.hasUnsavedCommittedChanges()) title += "*"; return title; }, /** * @param {string} id * @param {string} nextTabId */ _maybeCloseTab: function(id, nextTabId) { var uiSourceCode = this._files[id]; var shouldPrompt = uiSourceCode.isDirty() && uiSourceCode.project().canSetFileContent(); // FIXME: this should be replaced with common Save/Discard/Cancel dialog. if (!shouldPrompt || confirm(WebInspector.UIString("Are you sure you want to close unsaved file: %s?", uiSourceCode.name()))) { uiSourceCode.resetWorkingCopy(); if (nextTabId) this._tabbedPane.selectTab(nextTabId, true); this._tabbedPane.closeTab(id, true); return true; } return false; }, /** * @param {!Array.<string>} ids */ _closeTabs: function(ids) { var dirtyTabs = []; var cleanTabs = []; for (var i = 0; i < ids.length; ++i) { var id = ids[i]; var uiSourceCode = this._files[id]; if (uiSourceCode.isDirty()) dirtyTabs.push(id); else cleanTabs.push(id); } if (dirtyTabs.length) this._tabbedPane.selectTab(dirtyTabs[0], true); this._tabbedPane.closeTabs(cleanTabs, true); for (var i = 0; i < dirtyTabs.length; ++i) { var nextTabId = i + 1 < dirtyTabs.length ? dirtyTabs[i + 1] : null; if (!this._maybeCloseTab(dirtyTabs[i], nextTabId)) break; } }, /** * @param {string} tabId * @param {!WebInspector.ContextMenu} contextMenu */ _onContextMenu: function(tabId, contextMenu) { var uiSourceCode = this._files[tabId]; if (uiSourceCode) contextMenu.appendApplicableItems(uiSourceCode); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ addUISourceCode: function(uiSourceCode) { var uri = uiSourceCode.url(); var index = this._history.index(uri); if (index === -1) return; if (!this._tabIds.has(uiSourceCode)) this._appendFileTab(uiSourceCode, false); // Select tab if this file was the last to be shown. if (!index) { this._innerShowFile(uiSourceCode, false); return; } if (!this._currentFile) return; var currentProjectType = this._currentFile.project().type(); var addedProjectType = uiSourceCode.project().type(); var snippetsProjectType = WebInspector.projectTypes.Snippets; if (this._history.index(this._currentFile.url()) && currentProjectType === snippetsProjectType && addedProjectType !== snippetsProjectType) this._innerShowFile(uiSourceCode, false); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ removeUISourceCode: function(uiSourceCode) { this.removeUISourceCodes([uiSourceCode]); }, /** * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes */ removeUISourceCodes: function(uiSourceCodes) { var tabIds = []; for (var i = 0; i < uiSourceCodes.length; ++i) { var uiSourceCode = uiSourceCodes[i]; var tabId = this._tabIds.get(uiSourceCode); if (tabId) tabIds.push(tabId); } this._tabbedPane.closeTabs(tabIds); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _editorClosedByUserAction: function(uiSourceCode) { this._history.remove(uiSourceCode.url()); this._updateHistory(); }, _editorSelectedByUserAction: function() { this._updateHistory(); }, _updateHistory: function() { var tabIds = this._tabbedPane.lastOpenedTabIds(WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount); /** * @param {string} tabId * @this {WebInspector.TabbedEditorContainer} */ function tabIdToURI(tabId) { return this._files[tabId].url(); } this._history.update(tabIds.map(tabIdToURI.bind(this))); this._history.save(this._previouslyViewedFilesSetting); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @return {string} */ _tooltipForFile: function(uiSourceCode) { return uiSourceCode.url(); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {boolean=} userGesture * @return {string} */ _appendFileTab: function(uiSourceCode, userGesture) { var view = this._delegate.viewForFile(uiSourceCode); var sourceFrame = view instanceof WebInspector.SourceFrame ? /** @type {!WebInspector.SourceFrame} */ (view) : null; var title = this._titleForFile(uiSourceCode); var tooltip = this._tooltipForFile(uiSourceCode); var tabId = this._generateTabId(); this._tabIds.set(uiSourceCode, tabId); this._files[tabId] = uiSourceCode; var savedSelectionRange = this._history.selectionRange(uiSourceCode.url()); if (sourceFrame && savedSelectionRange) sourceFrame.setSelection(savedSelectionRange); var savedScrollLineNumber = this._history.scrollLineNumber(uiSourceCode.url()); if (sourceFrame && savedScrollLineNumber) sourceFrame.scrollToLine(savedScrollLineNumber); this._tabbedPane.appendTab(tabId, title, view, tooltip, userGesture); this._updateFileTitle(uiSourceCode); this._addUISourceCodeListeners(uiSourceCode); return tabId; }, /** * @param {!WebInspector.Event} event */ _tabClosed: function(event) { var tabId = /** @type {string} */ (event.data.tabId); var userGesture = /** @type {boolean} */ (event.data.isUserGesture); var uiSourceCode = this._files[tabId]; if (this._currentFile === uiSourceCode) { this._removeViewListeners(); delete this._currentView; delete this._currentFile; } this._tabIds.remove(uiSourceCode); delete this._files[tabId]; this._removeUISourceCodeListeners(uiSourceCode); this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorClosed, uiSourceCode); if (userGesture) this._editorClosedByUserAction(uiSourceCode); }, /** * @param {!WebInspector.Event} event */ _tabSelected: function(event) { var tabId = /** @type {string} */ (event.data.tabId); var userGesture = /** @type {boolean} */ (event.data.isUserGesture); var uiSourceCode = this._files[tabId]; this._innerShowFile(uiSourceCode, userGesture); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _addUISourceCodeListeners: function(uiSourceCode) { uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this); uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this); uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _removeUISourceCodeListeners: function(uiSourceCode) { uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this); uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this); uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _updateFileTitle: function(uiSourceCode) { var tabId = this._tabIds.get(uiSourceCode); if (tabId) { var title = this._titleForFile(uiSourceCode); this._tabbedPane.changeTabTitle(tabId, title); if (uiSourceCode.hasUnsavedCommittedChanges()) this._tabbedPane.setTabIcon(tabId, "warning-icon", WebInspector.UIString("Changes to this file were not saved to file system.")); else this._tabbedPane.setTabIcon(tabId, ""); } }, _uiSourceCodeTitleChanged: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target); this._updateFileTitle(uiSourceCode); this._updateHistory(); }, _uiSourceCodeWorkingCopyChanged: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target); this._updateFileTitle(uiSourceCode); }, _uiSourceCodeWorkingCopyCommitted: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target); this._updateFileTitle(uiSourceCode); }, /** * @return {string} */ _generateTabId: function() { return "tab_" + (WebInspector.TabbedEditorContainer._tabId++); }, /** * @return {!WebInspector.UISourceCode} uiSourceCode */ currentFile: function() { return this._currentFile; }, __proto__: WebInspector.Object.prototype } /** * @constructor * @param {string} url * @param {!WebInspector.TextRange=} selectionRange * @param {number=} scrollLineNumber */ WebInspector.TabbedEditorContainer.HistoryItem = function(url, selectionRange, scrollLineNumber) { /** @const */ this.url = url; /** @const */ this._isSerializable = url.length < WebInspector.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit; this.selectionRange = selectionRange; this.scrollLineNumber = scrollLineNumber; } WebInspector.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit = 4096; /** * @param {!Object} serializedHistoryItem * @return {!WebInspector.TabbedEditorContainer.HistoryItem} */ WebInspector.TabbedEditorContainer.HistoryItem.fromObject = function (serializedHistoryItem) { var selectionRange = serializedHistoryItem.selectionRange ? WebInspector.TextRange.fromObject(serializedHistoryItem.selectionRange) : undefined; return new WebInspector.TabbedEditorContainer.HistoryItem(serializedHistoryItem.url, selectionRange, serializedHistoryItem.scrollLineNumber); } WebInspector.TabbedEditorContainer.HistoryItem.prototype = { /** * @return {?Object} */ serializeToObject: function() { if (!this._isSerializable) return null; var serializedHistoryItem = {}; serializedHistoryItem.url = this.url; serializedHistoryItem.selectionRange = this.selectionRange; serializedHistoryItem.scrollLineNumber = this.scrollLineNumber; return serializedHistoryItem; } } /** * @constructor * @param {!Array.<!WebInspector.TabbedEditorContainer.HistoryItem>} items */ WebInspector.TabbedEditorContainer.History = function(items) { this._items = items; this._rebuildItemIndex(); } /** * @param {!Array.<!Object>} serializedHistory * @return {!WebInspector.TabbedEditorContainer.History} */ WebInspector.TabbedEditorContainer.History.fromObject = function(serializedHistory) { var items = []; for (var i = 0; i < serializedHistory.length; ++i) items.push(WebInspector.TabbedEditorContainer.HistoryItem.fromObject(serializedHistory[i])); return new WebInspector.TabbedEditorContainer.History(items); } WebInspector.TabbedEditorContainer.History.prototype = { /** * @param {string} url * @return {number} */ index: function(url) { return this._itemsIndex.has(url) ? /** @type {number} */(this._itemsIndex.get(url)) : -1; }, _rebuildItemIndex: function() { /** @type {!Map<string, number>} */ this._itemsIndex = new Map(); for (var i = 0; i < this._items.length; ++i) { console.assert(!this._itemsIndex.has(this._items[i].url)); this._itemsIndex.set(this._items[i].url, i); } }, /** * @param {string} url * @return {!WebInspector.TextRange|undefined} */ selectionRange: function(url) { var index = this.index(url); return index !== -1 ? this._items[index].selectionRange : undefined; }, /** * @param {string} url * @param {!WebInspector.TextRange=} selectionRange */ updateSelectionRange: function(url, selectionRange) { if (!selectionRange) return; var index = this.index(url); if (index === -1) return; this._items[index].selectionRange = selectionRange; }, /** * @param {string} url * @return {number|undefined} */ scrollLineNumber: function(url) { var index = this.index(url); return index !== -1 ? this._items[index].scrollLineNumber : undefined; }, /** * @param {string} url * @param {number} scrollLineNumber */ updateScrollLineNumber: function(url, scrollLineNumber) { var index = this.index(url); if (index === -1) return; this._items[index].scrollLineNumber = scrollLineNumber; }, /** * @param {!Array.<string>} urls */ update: function(urls) { for (var i = urls.length - 1; i >= 0; --i) { var index = this.index(urls[i]); var item; if (index !== -1) { item = this._items[index]; this._items.splice(index, 1); } else item = new WebInspector.TabbedEditorContainer.HistoryItem(urls[i]); this._items.unshift(item); this._rebuildItemIndex(); } }, /** * @param {string} url */ remove: function(url) { var index = this.index(url); if (index !== -1) { this._items.splice(index, 1); this._rebuildItemIndex(); } }, /** * @param {!WebInspector.Setting} setting */ save: function(setting) { setting.set(this._serializeToObject()); }, /** * @return {!Array.<!Object>} */ _serializeToObject: function() { var serializedHistory = []; for (var i = 0; i < this._items.length; ++i) { var serializedItem = this._items[i].serializeToObject(); if (serializedItem) serializedHistory.push(serializedItem); if (serializedHistory.length === WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount) break; } return serializedHistory; }, /** * @return {!Array.<string>} */ _urls: function() { var result = []; for (var i = 0; i < this._items.length; ++i) result.push(this._items[i].url); return result; } } /** * @constructor * @implements {WebInspector.TabbedPaneTabDelegate} * @param {!WebInspector.TabbedEditorContainer} editorContainer */ WebInspector.EditorContainerTabDelegate = function(editorContainer) { this._editorContainer = editorContainer; } WebInspector.EditorContainerTabDelegate.prototype = { /** * @override * @param {!WebInspector.TabbedPane} tabbedPane * @param {!Array.<string>} ids */ closeTabs: function(tabbedPane, ids) { this._editorContainer._closeTabs(ids); }, /** * @override * @param {string} tabId * @param {!WebInspector.ContextMenu} contextMenu */ onContextMenu: function(tabId, contextMenu) { this._editorContainer._onContextMenu(tabId, contextMenu); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.SidebarPane}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.ThreadsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Threads"));
this.setVisible(false);
/** @type {!Map.<!WebInspector.DebuggerModel, !WebInspector.UIList.Item>} */
this._debuggerModelToListItems = new Map();
/** @type {!Map.<!WebInspector.UIList.Item, !WebInspector.Target>} */
this._listItemsToTargets = new Map();
/** @type {?WebInspector.UIList.Item} */
this._selectedListItem = null;
this.threadList = new WebInspector.UIList();
this.threadList.show(this.element);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._onDebuggerStateChanged, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._onDebuggerStateChanged, this);
WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this);
WebInspector.targetManager.observeTargets(this);
}
WebInspector.ThreadsSidebarPane.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target)
if (!debuggerModel) {
this._updateVisibility();
return;
}
var listItem = new WebInspector.UIList.Item(target.name(), "");
listItem.element.addEventListener("click", this._onListItemClick.bind(this, listItem), false);
var currentTarget = WebInspector.context.flavor(WebInspector.Target);
if (currentTarget === target)
this._selectListItem(listItem);
this._debuggerModelToListItems.set(debuggerModel, listItem);
this._listItemsToTargets.set(listItem, target);
this.threadList.addItem(listItem);
this._updateDebuggerState(debuggerModel);
this._updateVisibility();
},
_updateVisibility: function()
{
this._wasVisibleAtLeastOnce = this._wasVisibleAtLeastOnce || this._debuggerModelToListItems.size > 1;
this.setVisible(this._wasVisibleAtLeastOnce);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(target)
if (!debuggerModel)
return;
var listItem = this._debuggerModelToListItems.remove(debuggerModel);
if (listItem) {
this._listItemsToTargets.remove(listItem);
this.threadList.removeItem(listItem);
}
this._updateVisibility();
},
/**
* @param {!WebInspector.Event} event
*/
_targetChanged: function(event)
{
var newTarget = /** @type {!WebInspector.Target} */(event.data);
var debuggerModel = WebInspector.DebuggerModel.fromTarget(newTarget)
if (!debuggerModel)
return;
var listItem = /** @type {!WebInspector.UIList.Item} */ (this._debuggerModelToListItems.get(debuggerModel));
this._selectListItem(listItem);
},
/**
* @param {!WebInspector.Event} event
*/
_onDebuggerStateChanged: function(event)
{
var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
this._updateDebuggerState(debuggerModel);
},
/**
* @param {!WebInspector.DebuggerModel} debuggerModel
*/
_updateDebuggerState: function(debuggerModel)
{
var listItem = this._debuggerModelToListItems.get(debuggerModel);
listItem.setSubtitle(WebInspector.UIString(debuggerModel.isPaused() ? "paused" : ""));
},
/**
* @param {!WebInspector.UIList.Item} listItem
*/
_selectListItem: function(listItem)
{
if (listItem === this._selectedListItem)
return;
if (this._selectedListItem)
this._selectedListItem.setSelected(false);
this._selectedListItem = listItem;
listItem.setSelected(true);
},
/**
* @param {!WebInspector.UIList.Item} listItem
*/
_onListItemClick: function(listItem)
{
WebInspector.context.setFlavor(WebInspector.Target, this._listItemsToTargets.get(listItem));
listItem.element.scrollIntoViewIfNeeded();
},
__proto__: WebInspector.SidebarPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.UIList = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("sources/uiList.css");
/** @type {!Array.<!WebInspector.UIList.Item>} */
this._items = [];
}
WebInspector.UIList._Key = Symbol("ownerList");
WebInspector.UIList.prototype = {
/**
* @param {!WebInspector.UIList.Item} item
* @param {?WebInspector.UIList.Item=} beforeItem
*/
addItem: function(item, beforeItem)
{
item[WebInspector.UIList._Key] = this;
var beforeElement = beforeItem ? beforeItem.element : null;
this.contentElement.insertBefore(item.element, beforeElement);
var index = beforeItem ? this._items.indexOf(beforeItem) : this._items.length;
console.assert(index >= 0, "Anchor item not found in UIList");
this._items.splice(index, 0, item);
},
/**
* @param {!WebInspector.UIList.Item} item
*/
removeItem: function(item)
{
var index = this._items.indexOf(item);
console.assert(index >= 0);
this._items.splice(index, 1);
item.element.remove();
},
clear: function()
{
this.contentElement.removeChildren();
this._items = [];
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {string} title
* @param {string} subtitle
* @param {boolean=} isLabel
*/
WebInspector.UIList.Item = function(title, subtitle, isLabel)
{
this.element = createElementWithClass("div", "list-item");
if (isLabel)
this.element.classList.add("label");
this.subtitleElement = this.element.createChild("div", "subtitle");
this.titleElement = this.element.createChild("div", "title");
this._hidden = false;
this._isLabel = !!isLabel;
this.setTitle(title);
this.setSubtitle(subtitle);
this.setSelected(false);
}
WebInspector.UIList.Item.prototype = {
/**
* @return {?WebInspector.UIList.Item}
*/
nextSibling: function()
{
var list = this[WebInspector.UIList._Key];
var index = list._items.indexOf(this);
console.assert(index >= 0);
return list._items[index + 1] || null;
},
/**
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @param {string} x
*/
setTitle: function(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},
/**
* @return {string}
*/
subtitle: function()
{
return this._subtitle;
},
/**
* @param {string} x
*/
setSubtitle: function(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},
/**
* @return {boolean}
*/
isSelected: function()
{
return this._selected;
},
/**
* @param {boolean} x
*/
setSelected: function(x)
{
if (x)
this.select();
else
this.deselect();
},
select: function()
{
if (this._selected)
return;
this._selected = true;
this.element.classList.add("selected");
},
deselect: function()
{
if (!this._selected)
return;
this._selected = false;
this.element.classList.remove("selected");
},
toggleSelected: function()
{
this.setSelected(!this.isSelected());
},
/**
* @return {boolean}
*/
isHidden: function()
{
return this._hidden;
},
/**
* @param {boolean} x
*/
setHidden: function(x)
{
if (this._hidden === x)
return;
this._hidden = x;
this.element.classList.toggle("hidden", x);
},
/**
* @return {boolean}
*/
isLabel: function()
{
return this._isLabel;
},
/**
* @param {boolean} x
*/
setDimmed: function(x)
{
this.element.classList.toggle("dimmed", x);
},
discard: function()
{
},
/**
* @param {boolean} hoverable
*/
setHoverable: function(hoverable)
{
this.element.classList.toggle("ignore-hover", !hoverable);
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | 2 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SourceFrame}
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
WebInspector.UISourceCodeFrame = function(uiSourceCode)
{
this._uiSourceCode = uiSourceCode;
WebInspector.SourceFrame.call(this, this._uiSourceCode);
this.textEditor.setAutocompleteDelegate(new WebInspector.SimpleAutocompleteDelegate());
this._rowMessageBuckets = {};
/** @type {!Set<string>} */
this._typeDecorationsPending = new Set();
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.MessageAdded, this._onMessageAdded, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.MessageRemoved, this._onMessageRemoved, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDecorationAdded, this._onLineDecorationAdded, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDecorationRemoved, this._onLineDecorationRemoved, this);
this._updateStyle();
this._errorPopoverHelper = new WebInspector.PopoverHelper(this.element, this._getErrorAnchor.bind(this), this._showErrorPopover.bind(this));
this._errorPopoverHelper.setTimeout(100, 100);
}
WebInspector.UISourceCodeFrame.prototype = {
/**
* @return {!WebInspector.UISourceCode}
*/
uiSourceCode: function()
{
return this._uiSourceCode;
},
wasShown: function()
{
WebInspector.SourceFrame.prototype.wasShown.call(this);
this._boundWindowFocused = this._windowFocused.bind(this);
this.element.ownerDocument.defaultView.addEventListener("focus", this._boundWindowFocused, false);
this._checkContentUpdated();
// We need CodeMirrorTextEditor to be initialized prior to this call as it calls |cursorPositionToCoordinates| internally. @see crbug.com/506566
setImmediate(this._updateBucketDecorations.bind(this));
},
willHide: function()
{
WebInspector.SourceFrame.prototype.willHide.call(this);
this.element.ownerDocument.defaultView.removeEventListener("focus", this._boundWindowFocused, false);
delete this._boundWindowFocused;
this._uiSourceCode.removeWorkingCopyGetter();
},
/**
* @override
* @return {boolean}
*/
canEditSource: function()
{
var projectType = this._uiSourceCode.project().type();
if (projectType === WebInspector.projectTypes.Service || projectType === WebInspector.projectTypes.Debugger || projectType === WebInspector.projectTypes.Formatter)
return false;
if (projectType === WebInspector.projectTypes.Network && this._uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
return false;
return true;
},
_windowFocused: function(event)
{
this._checkContentUpdated();
},
_checkContentUpdated: function()
{
if (!this.loaded || !this.isShowing())
return;
this._uiSourceCode.checkContentUpdated(true);
},
commitEditing: function()
{
if (!this._uiSourceCode.isDirty())
return;
this._muteSourceCodeEvents = true;
this._uiSourceCode.commitWorkingCopy();
delete this._muteSourceCodeEvents;
},
/**
* @override
*/
onTextEditorContentLoaded: function()
{
WebInspector.SourceFrame.prototype.onTextEditorContentLoaded.call(this);
for (var message of this._uiSourceCode.messages())
this._addMessageToSource(message);
this._decorateAllTypes();
},
/**
* @override
* @param {!WebInspector.TextRange} oldRange
* @param {!WebInspector.TextRange} newRange
*/
onTextChanged: function(oldRange, newRange)
{
WebInspector.SourceFrame.prototype.onTextChanged.call(this, oldRange, newRange);
this._clearMessages();
if (this._isSettingContent)
return;
this._muteSourceCodeEvents = true;
if (this._textEditor.isClean())
this._uiSourceCode.resetWorkingCopy();
else
this._uiSourceCode.setWorkingCopyGetter(this._textEditor.text.bind(this._textEditor));
delete this._muteSourceCodeEvents;
},
/**
* @param {!WebInspector.Event} event
*/
_onWorkingCopyChanged: function(event)
{
if (this._muteSourceCodeEvents)
return;
this._innerSetContent(this._uiSourceCode.workingCopy());
this.onUISourceCodeContentChanged();
},
/**
* @param {!WebInspector.Event} event
*/
_onWorkingCopyCommitted: function(event)
{
if (!this._muteSourceCodeEvents) {
this._innerSetContent(this._uiSourceCode.workingCopy());
this.onUISourceCodeContentChanged();
}
this._textEditor.markClean();
this._updateStyle();
},
_updateStyle: function()
{
this.element.classList.toggle("source-frame-unsaved-committed-changes", this._uiSourceCode.hasUnsavedCommittedChanges());
},
onUISourceCodeContentChanged: function()
{
},
/**
* @param {string} content
*/
_innerSetContent: function(content)
{
this._isSettingContent = true;
this.setContent(content);
delete this._isSettingContent;
},
/**
* @override
* @return {!Promise}
*/
populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
{
/**
* @this {WebInspector.UISourceCodeFrame}
*/
function appendItems()
{
contextMenu.appendApplicableItems(this._uiSourceCode);
contextMenu.appendApplicableItems(new WebInspector.UILocation(this._uiSourceCode, lineNumber, columnNumber));
contextMenu.appendSeparator();
}
return WebInspector.SourceFrame.prototype.populateTextAreaContextMenu.call(this, contextMenu, lineNumber, columnNumber)
.then(appendItems.bind(this));
},
/**
* @param {!Array.<!WebInspector.Infobar|undefined>} infobars
*/
attachInfobars: function(infobars)
{
for (var i = infobars.length - 1; i >= 0; --i) {
var infobar = infobars[i];
if (!infobar)
continue;
this.element.insertBefore(infobar.element, this.element.children[0]);
infobar.setParentView(this);
}
this.doResize();
},
dispose: function()
{
this._textEditor.dispose();
this.detach();
},
/**
* @param {!WebInspector.Event} event
*/
_onMessageAdded: function(event)
{
if (!this.loaded)
return;
var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.data);
this._addMessageToSource(message);
},
/**
* @param {!WebInspector.UISourceCode.Message} message
*/
_addMessageToSource: function(message)
{
var lineNumber = message.lineNumber();
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;
if (!this._rowMessageBuckets[lineNumber])
this._rowMessageBuckets[lineNumber] = new WebInspector.UISourceCodeFrame.RowMessageBucket(this, this._textEditor, lineNumber);
var messageBucket = this._rowMessageBuckets[lineNumber];
messageBucket.addMessage(message);
},
/**
* @param {!WebInspector.Event} event
*/
_onMessageRemoved: function(event)
{
if (!this.loaded)
return;
var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.data);
this._removeMessageFromSource(message);
},
/**
* @param {!WebInspector.UISourceCode.Message} message
*/
_removeMessageFromSource: function(message)
{
var lineNumber = message.lineNumber();
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;
var messageBucket = this._rowMessageBuckets[lineNumber];
if (!messageBucket)
return;
messageBucket.removeMessage(message);
if (!messageBucket.uniqueMessagesCount()) {
messageBucket.detachFromEditor();
delete this._rowMessageBuckets[lineNumber];
}
},
_clearMessages: function()
{
for (var line in this._rowMessageBuckets) {
var bubble = this._rowMessageBuckets[line];
bubble.detachFromEditor();
}
this._rowMessageBuckets = {};
this._errorPopoverHelper.hidePopover();
this._uiSourceCode.removeAllMessages();
},
/**
* @param {!Element} target
* @param {!Event} event
* @return {(!Element|undefined)}
*/
_getErrorAnchor: function(target, event)
{
var element = target.enclosingNodeOrSelfWithClass("text-editor-line-decoration-icon")
|| target.enclosingNodeOrSelfWithClass("text-editor-line-decoration-wave");
if (!element)
return;
this._errorWavePopoverAnchor = new AnchorBox(event.clientX, event.clientY, 1, 1);
return element;
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showErrorPopover: function(anchor, popover)
{
var messageBucket = anchor.enclosingNodeOrSelfWithClass("text-editor-line-decoration")._messageBucket;
var messagesOutline = messageBucket.messagesDescription();
var popoverAnchor = anchor.enclosingNodeOrSelfWithClass("text-editor-line-decoration-icon") ? anchor : this._errorWavePopoverAnchor;
popover.showForAnchor(messagesOutline, popoverAnchor);
},
_updateBucketDecorations: function()
{
for (var line in this._rowMessageBuckets) {
var bucket = this._rowMessageBuckets[line];
bucket._updateDecoration();
}
},
/**
* @param {!WebInspector.Event} event
*/
_onLineDecorationAdded: function(event)
{
var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event.data);
this._decorateTypeThrottled(marker.type());
},
/**
* @param {!WebInspector.Event} event
*/
_onLineDecorationRemoved: function(event)
{
var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event.data);
this._decorateTypeThrottled(marker.type());
},
/**
* @param {string} type
*/
_decorateTypeThrottled: function(type)
{
if (this._typeDecorationsPending.has(type))
return;
this._typeDecorationsPending.add(type);
self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator).find(extension => extension.descriptor()["decoratorType"] === type).instancePromise().then(decorator => {
this._typeDecorationsPending.delete(type);
decorator.decorate(this.uiSourceCode(), this._textEditor);
});
},
_decorateAllTypes: function()
{
var extensions = self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator);
extensions.forEach(extension => this._decorateTypeThrottled(extension.descriptor()["decoratorType"]));
},
__proto__: WebInspector.SourceFrame.prototype
}
WebInspector.UISourceCodeFrame._iconClassPerLevel = {};
WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Message.Level.Error] = "error-icon";
WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Message.Level.Warning] = "warning-icon";
WebInspector.UISourceCodeFrame._lineClassPerLevel = {};
WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Message.Level.Error] = "text-editor-line-with-error";
WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Message.Level.Warning] = "text-editor-line-with-warning";
/**
* @interface
*/
WebInspector.UISourceCodeFrame.LineDecorator = function() { }
WebInspector.UISourceCodeFrame.LineDecorator.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
*/
decorate: function(uiSourceCode, textEditor) { }
}
/**
* @constructor
* @param {!WebInspector.UISourceCode.Message} message
*/
WebInspector.UISourceCodeFrame.RowMessage = function(message)
{
this._message = message;
this._repeatCount = 1;
this.element = createElementWithClass("div", "text-editor-row-message");
this._icon = this.element.createChild("label", "", "dt-icon-label");
this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[message.level()];
this._repeatCountElement = this.element.createChild("span", "bubble-repeat-count hidden error");
var linesContainer = this.element.createChild("div", "text-editor-row-message-lines");
var lines = this._message.text().split("\n");
for (var i = 0; i < lines.length; ++i) {
var messageLine = linesContainer.createChild("div");
messageLine.textContent = lines[i];
}
}
WebInspector.UISourceCodeFrame.RowMessage.prototype = {
/**
* @return {!WebInspector.UISourceCode.Message}
*/
message: function()
{
return this._message;
},
/**
* @return {number}
*/
repeatCount: function()
{
return this._repeatCount;
},
setRepeatCount: function(repeatCount)
{
if (this._repeatCount === repeatCount)
return;
this._repeatCount = repeatCount;
this._updateMessageRepeatCount();
},
_updateMessageRepeatCount: function()
{
this._repeatCountElement.textContent = this._repeatCount;
var showRepeatCount = this._repeatCount > 1;
this._repeatCountElement.classList.toggle("hidden", !showRepeatCount);
this._icon.classList.toggle("hidden", showRepeatCount);
}
}
/**
* @constructor
* @param {!WebInspector.UISourceCodeFrame} sourceFrame
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {number} lineNumber
*/
WebInspector.UISourceCodeFrame.RowMessageBucket = function(sourceFrame, textEditor, lineNumber)
{
this._sourceFrame = sourceFrame;
this._textEditor = textEditor;
this._lineHandle = textEditor.textEditorPositionHandle(lineNumber, 0);
this._decoration = createElementWithClass("div", "text-editor-line-decoration");
this._decoration._messageBucket = this;
this._wave = this._decoration.createChild("div", "text-editor-line-decoration-wave");
this._icon = this._wave.createChild("label", "text-editor-line-decoration-icon", "dt-icon-label");
this._textEditor.addDecoration(lineNumber, this._decoration);
this._messagesDescriptionElement = createElementWithClass("div", "text-editor-messages-description-container");
/** @type {!Array.<!WebInspector.UISourceCodeFrame.RowMessage>} */
this._messages = [];
this._level = null;
}
WebInspector.UISourceCodeFrame.RowMessageBucket.prototype = {
/**
* @param {number} lineNumber
* @param {number} columnNumber
*/
_updateWavePosition: function(lineNumber, columnNumber)
{
lineNumber = Math.min(lineNumber, this._textEditor.linesCount - 1);
var lineText = this._textEditor.line(lineNumber);
columnNumber = Math.min(columnNumber, lineText.length);
var lineIndent = WebInspector.TextUtils.lineIndent(lineText).length;
var base = this._textEditor.cursorPositionToCoordinates(lineNumber, 0);
var start = this._textEditor.cursorPositionToCoordinates(lineNumber, Math.max(columnNumber - 1, lineIndent));
var end = this._textEditor.cursorPositionToCoordinates(lineNumber, lineText.length);
/** @const */
var codeMirrorLinesLeftPadding = 4;
this._wave.style.left = (start.x - base.x + codeMirrorLinesLeftPadding) + "px";
this._wave.style.width = (end.x - start.x) + "px";
},
/**
* @return {!Element}
*/
messagesDescription: function()
{
this._messagesDescriptionElement.removeChildren();
for (var i = 0; i < this._messages.length; ++i) {
this._messagesDescriptionElement.appendChild(this._messages[i].element);
}
return this._messagesDescriptionElement;
},
detachFromEditor: function()
{
var position = this._lineHandle.resolve();
if (!position)
return;
var lineNumber = position.lineNumber;
if (this._level)
this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level], false);
this._textEditor.removeDecoration(lineNumber, this._decoration);
},
/**
* @return {number}
*/
uniqueMessagesCount: function()
{
return this._messages.length;
},
/**
* @param {!WebInspector.UISourceCode.Message} message
*/
addMessage: function(message)
{
for (var i = 0; i < this._messages.length; ++i) {
var rowMessage = this._messages[i];
if (rowMessage.message().isEqual(message)) {
rowMessage.setRepeatCount(rowMessage.repeatCount() + 1);
return;
}
}
var rowMessage = new WebInspector.UISourceCodeFrame.RowMessage(message);
this._messages.push(rowMessage);
this._updateDecoration();
},
/**
* @param {!WebInspector.UISourceCode.Message} message
*/
removeMessage: function(message)
{
for (var i = 0; i < this._messages.length; ++i) {
var rowMessage = this._messages[i];
if (!rowMessage.message().isEqual(message))
continue;
rowMessage.setRepeatCount(rowMessage.repeatCount() - 1);
if (!rowMessage.repeatCount())
this._messages.splice(i, 1);
this._updateDecoration();
return;
}
},
_updateDecoration: function()
{
if (!this._sourceFrame.isEditorShowing())
return;
if (!this._messages.length)
return;
var position = this._lineHandle.resolve();
if (!position)
return;
var lineNumber = position.lineNumber;
var columnNumber = Number.MAX_VALUE;
var maxMessage = null;
for (var i = 0; i < this._messages.length; ++i) {
var message = this._messages[i].message();
columnNumber = Math.min(columnNumber, message.columnNumber());
if (!maxMessage || WebInspector.UISourceCode.Message.messageLevelComparator(maxMessage, message) < 0)
maxMessage = message;
}
this._updateWavePosition(lineNumber, columnNumber);
if (this._level) {
this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level], false);
this._icon.type = "";
}
this._level = maxMessage.level();
if (!this._level)
return;
this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level], true);
this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[this._level];
}
}
WebInspector.UISourceCode.Message._messageLevelPriority = {
"Warning": 3,
"Error": 4
};
/**
* @param {!WebInspector.UISourceCode.Message} a
* @param {!WebInspector.UISourceCode.Message} b
* @return {number}
*/
WebInspector.UISourceCode.Message.messageLevelComparator = function(a, b)
{
return WebInspector.UISourceCode.Message._messageLevelPriority[a.level()] - WebInspector.UISourceCode.Message._messageLevelPriority[b.level()];
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | 2 1 | /*
* Copyright (C) IBM Corp. 2009 All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of IBM Corp. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.SidebarPane}
*/
WebInspector.WatchExpressionsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch"));
this.registerRequiredCSS("components/objectValue.css");
this._requiresUpdate = true;
/** @type {!Array.<!WebInspector.WatchExpression>} */
this._watchExpressions = [];
this._watchExpressionsSetting = WebInspector.settings.createLocalSetting("watchExpressions", []);
var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add expression"), "add-toolbar-item");
addButton.addEventListener("click", this._addButtonClicked.bind(this));
this.toolbar().appendToolbarItem(addButton);
var refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item");
refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this));
this.toolbar().appendToolbarItem(refreshButton);
this._bodyElement = this.element.createChild("div", "vbox watch-expressions");
this._bodyElement.addEventListener("contextmenu", this._contextMenu.bind(this), false);
this._expandController = new WebInspector.ObjectPropertiesSectionExpandController();
WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.refreshExpressions, this);
}
WebInspector.WatchExpressionsSidebarPane.prototype = {
wasShown: function()
{
this._refreshExpressionsIfNeeded();
},
refreshExpressions: function()
{
this._requiresUpdate = true;
this._refreshExpressionsIfNeeded();
},
/**
* @param {string} expressionString
*/
addExpression: function(expressionString)
{
this.expand();
if (this._requiresUpdate) {
this._rebuildWatchExpressions();
delete this._requiresUpdate;
}
this._createWatchExpression(expressionString);
this._saveExpressions();
},
expandIfNecessary: function()
{
if (this._watchExpressionsSetting.get().length)
this.expand();
},
_saveExpressions: function()
{
var toSave = [];
for (var i = 0; i < this._watchExpressions.length; i++)
if (this._watchExpressions[i].expression())
toSave.push(this._watchExpressions[i].expression());
this._watchExpressionsSetting.set(toSave);
},
_refreshExpressionsIfNeeded: function()
{
if (this._requiresUpdate && this.isShowing()) {
this._rebuildWatchExpressions();
delete this._requiresUpdate;
} else
this._requiresUpdate = true;
},
/**
* @param {!WebInspector.Event=} event
*/
_addButtonClicked: function(event)
{
if (event)
event.consume(true);
this.expand();
this._createWatchExpression(null).startEditing();
},
/**
* @param {!WebInspector.Event} event
*/
_refreshButtonClicked: function(event)
{
event.consume();
this.refreshExpressions();
},
_rebuildWatchExpressions: function()
{
this._bodyElement.removeChildren();
this._watchExpressions = [];
this._emptyElement = this._bodyElement.createChild("div", "info");
this._emptyElement.textContent = WebInspector.UIString("No Watch Expressions");
var watchExpressionStrings = this._watchExpressionsSetting.get();
for (var i = 0; i < watchExpressionStrings.length; ++i) {
var expression = watchExpressionStrings[i];
if (!expression)
continue;
this._createWatchExpression(expression);
}
},
/**
* @param {?string} expression
* @return {!WebInspector.WatchExpression}
*/
_createWatchExpression: function(expression)
{
this._emptyElement.classList.add("hidden");
var watchExpression = new WebInspector.WatchExpression(expression, this._expandController);
watchExpression.addEventListener(WebInspector.WatchExpression.Events.ExpressionUpdated, this._watchExpressionUpdated.bind(this));
this._bodyElement.appendChild(watchExpression.element());
this._watchExpressions.push(watchExpression);
return watchExpression;
},
/**
* @param {!WebInspector.Event} event
*/
_watchExpressionUpdated: function(event)
{
var watchExpression = /** @type {!WebInspector.WatchExpression} */ (event.target);
if (!watchExpression.expression()) {
this._watchExpressions.remove(watchExpression);
this._bodyElement.removeChild(watchExpression.element());
this._emptyElement.classList.toggle("hidden", !!this._watchExpressions.length);
}
this._saveExpressions();
},
/**
* @param {!Event} event
*/
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
this._populateContextMenu(contextMenu, event);
contextMenu.show();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Event} event
*/
_populateContextMenu: function(contextMenu, event)
{
var isEditing = false;
for (var watchExpression of this._watchExpressions)
isEditing |= watchExpression.isEditing();
if (!isEditing)
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^watch ^expression"), this._addButtonClicked.bind(this));
if (this._watchExpressions.length > 1)
contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^all ^watch ^expressions"), this._deleteAllButtonClicked.bind(this));
for (var watchExpression of this._watchExpressions)
if (watchExpression.element().containsEventPoint(event))
watchExpression._populateContextMenu(contextMenu, event);
},
_deleteAllButtonClicked: function()
{
this._watchExpressions = [];
this._saveExpressions();
this._rebuildWatchExpressions();
},
__proto__: WebInspector.SidebarPane.prototype
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {?string} expression
* @param {!WebInspector.ObjectPropertiesSectionExpandController} expandController
*/
WebInspector.WatchExpression = function(expression, expandController)
{
this._expression = expression;
this._expandController = expandController;
this._element = createElementWithClass("div", "watch-expression monospace");
this._editing = false;
this._createWatchExpression(null, false);
this.update();
}
WebInspector.WatchExpression._watchObjectGroupId = "watch-group";
WebInspector.WatchExpression.Events = {
ExpressionUpdated: "ExpressionUpdated"
}
WebInspector.WatchExpression.prototype = {
/**
* @return {!Element}
*/
element: function()
{
return this._element;
},
/**
* @return {?string}
*/
expression: function()
{
return this._expression;
},
update: function()
{
var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
if (currentExecutionContext && this._expression)
currentExecutionContext.evaluate(this._expression, WebInspector.WatchExpression._watchObjectGroupId, false, true, false, false, false, this._createWatchExpression.bind(this));
},
startEditing: function()
{
this._editing = true;
this._element.removeChild(this._objectPresentationElement);
var newDiv = this._element.createChild("div");
newDiv.textContent = this._nameElement.textContent;
this._textPrompt = new WebInspector.ObjectPropertyPrompt();
this._textPrompt.renderAsBlock();
var proxyElement = this._textPrompt.attachAndStartEditing(newDiv, this._finishEditing.bind(this));
proxyElement.classList.add("watch-expression-text-prompt-proxy");
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
this._element.getComponentSelection().setBaseAndExtent(newDiv, 0, newDiv, 1);
},
/**
* @return {boolean}
*/
isEditing: function()
{
return !!this._editing;
},
/**
* @param {!Event} event
* @param {boolean=} canceled
*/
_finishEditing: function(event, canceled)
{
if (event)
event.consume(true);
this._editing = false;
this._textPrompt.detach();
var newExpression = canceled ? this._expression : this._textPrompt.text();
delete this._textPrompt;
this._element.removeChildren();
this._element.appendChild(this._objectPresentationElement);
this._updateExpression(newExpression);
},
/**
* @param {!Event} event
*/
_dblClickOnWatchExpression: function(event)
{
event.consume();
if (!this.isEditing())
this.startEditing();
},
/**
* @param {?string} newExpression
*/
_updateExpression: function(newExpression)
{
if (this._expression)
this._expandController.stopWatchSectionsWithId(this._expression);
this._expression = newExpression;
this.update();
this.dispatchEventToListeners(WebInspector.WatchExpression.Events.ExpressionUpdated);
},
/**
* @param {!Event} event
*/
_deleteWatchExpression: function(event)
{
event.consume(true);
this._updateExpression(null);
},
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean} wasThrown
*/
_createWatchExpression: function(result, wasThrown)
{
this._result = result;
var headerElement= createElementWithClass("div", "watch-expression-header");
var deleteButton = headerElement.createChild("button", "watch-expression-delete-button");
deleteButton.title = WebInspector.UIString("Delete watch expression");
deleteButton.addEventListener("click", this._deleteWatchExpression.bind(this), false);
var titleElement = headerElement.createChild("div", "watch-expression-title");
this._nameElement = WebInspector.ObjectPropertiesSection.createNameElement(this._expression);
if (wasThrown || !result) {
this._valueElement = createElementWithClass("span", "error-message value");
titleElement.classList.add("dimmed");
this._valueElement.textContent = WebInspector.UIString("<not available>");
} else {
this._valueElement = WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(result, wasThrown, titleElement);
}
var separatorElement = createElementWithClass("span", "watch-expressions-separator");
separatorElement.textContent = ": ";
titleElement.appendChildren(this._nameElement, separatorElement, this._valueElement);
this._element.removeChildren();
this._objectPropertiesSection = null;
if (!wasThrown && result && result.hasChildren && !result.customPreview()) {
headerElement.classList.add("watch-expression-object-header");
this._objectPropertiesSection = new WebInspector.ObjectPropertiesSection(result, headerElement);
this._objectPresentationElement = this._objectPropertiesSection.element;
this._expandController.watchSection(/** @type {string} */ (this._expression), this._objectPropertiesSection);
var objectTreeElement = this._objectPropertiesSection.objectTreeElement();
objectTreeElement.toggleOnClick = false;
objectTreeElement.listItemElement.addEventListener("click", this._onSectionClick.bind(this), false);
objectTreeElement.listItemElement.addEventListener("dblclick", this._dblClickOnWatchExpression.bind(this));
} else {
this._objectPresentationElement = headerElement;
this._objectPresentationElement.addEventListener("dblclick", this._dblClickOnWatchExpression.bind(this));
}
this._element.appendChild(this._objectPresentationElement);
},
/**
* @param {!Event} event
*/
_onSectionClick: function(event)
{
event.consume(true);
if (event.detail == 1) {
this._preventClickTimeout = setTimeout(handleClick.bind(this), 333);
} else {
clearTimeout(this._preventClickTimeout);
delete this._preventClickTimeout;
}
/**
* @this {WebInspector.WatchExpression}
*/
function handleClick()
{
if (!this._objectPropertiesSection)
return;
var objectTreeElement = this._objectPropertiesSection.objectTreeElement();
if (objectTreeElement.expanded)
objectTreeElement.collapse();
else
objectTreeElement.expand();
}
},
/**
* @param {!Event} event
*/
_promptKeyDown: function(event)
{
if (isEnterKey(event) || isEscKey(event))
this._finishEditing(event, isEscKey(event));
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Event} event
*/
_populateContextMenu: function(contextMenu, event)
{
if (!this.isEditing())
contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^watch ^expression"), this._updateExpression.bind(this, null));
if (!this.isEditing() && this._result && (this._result.type === "number" || this._result.type === "string"))
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^value"), this._copyValueButtonClicked.bind(this));
if (this._valueElement.containsEventPoint(event))
contextMenu.appendApplicableItems(this._result);
},
_copyValueButtonClicked: function()
{
InspectorFrontendHost.copyText(this._valueElement.textContent);
},
__proto__: WebInspector.Object.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | 2 |
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.SourcesPanel} sourcesPanel
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.WorkspaceMappingTip = function(sourcesPanel, workspace)
{
this._sourcesPanel = sourcesPanel;
this._workspace = workspace;
this._sourcesView = this._sourcesPanel.sourcesView();
this._workspaceInfobarDisabledSetting = WebInspector.settings.createSetting("workspaceInfobarDisabled", false);
this._workspaceMappingInfobarDisabledSetting = WebInspector.settings.createSetting("workspaceMappingInfobarDisabled", false);
if (this._workspaceInfobarDisabledSetting.get() && this._workspaceMappingInfobarDisabledSetting.get())
return;
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
}
WebInspector.WorkspaceMappingTip._infobarSymbol = Symbol("infobar");
WebInspector.WorkspaceMappingTip.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (this._editorSelectedTimer)
clearTimeout(this._editorSelectedTimer);
this._editorSelectedTimer = setTimeout(this._updateSuggestedMappingInfobar.bind(this, uiSourceCode), 3000);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_updateSuggestedMappingInfobar: function(uiSourceCode)
{
var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode);
if (!uiSourceCodeFrame.isShowing())
return;
if (uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol])
return;
// First try mapping filesystem -> network.
if (!this._workspaceMappingInfobarDisabledSetting.get() && uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
var hasMappings = !!networkURL;
if (hasMappings)
return;
var networkProjects = this._workspace.projectsForType(WebInspector.projectTypes.Network);
networkProjects = networkProjects.concat(this._workspace.projectsForType(WebInspector.projectTypes.ContentScripts));
for (var i = 0; i < networkProjects.length; ++i) {
var name = uiSourceCode.name();
var networkUiSourceCodes = networkProjects[i].uiSourceCodes();
for (var j = 0; j < networkUiSourceCodes.length; ++j) {
if (networkUiSourceCodes[j].name() === name && this._isLocalHost(networkUiSourceCodes[j].url())) {
this._showMappingInfobar(uiSourceCode, false);
return;
}
}
}
}
// Then map network -> filesystem.
if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
// Suggest for localhost only.
if (!this._isLocalHost(uiSourceCode.url()))
return;
var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
if (WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(networkURL) !== uiSourceCode)
return;
var filesystemProjects = this._workspace.projectsForType(WebInspector.projectTypes.FileSystem);
for (var i = 0; i < filesystemProjects.length; ++i) {
var name = uiSourceCode.name();
var fsUiSourceCodes = filesystemProjects[i].uiSourceCodes();
for (var j = 0; j < fsUiSourceCodes.length; ++j) {
if (fsUiSourceCodes[j].name() === name) {
this._showMappingInfobar(uiSourceCode, true);
return;
}
}
}
this._showWorkspaceInfobar(uiSourceCode);
}
},
/**
* @param {string} url
* @return {boolean}
*/
_isLocalHost: function(url)
{
var parsedURL = url.asParsedURL();
return !!parsedURL && parsedURL.host === "localhost";
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_showWorkspaceInfobar: function(uiSourceCode)
{
var infobar = WebInspector.Infobar.create(WebInspector.Infobar.Type.Info, WebInspector.UIString("Serving from the file system? Add your files into the workspace."), this._workspaceInfobarDisabledSetting);
if (!infobar)
return;
infobar.createDetailsRowMessage(WebInspector.UIString("If you add files into your DevTools workspace, your changes will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("To add a folder into the workspace, drag and drop it into the Sources panel."));
this._appendInfobar(uiSourceCode, infobar);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean} isNetwork
*/
_showMappingInfobar: function(uiSourceCode, isNetwork)
{
var title;
if (isNetwork)
title = WebInspector.UIString("Map network resource '%s' to workspace?", uiSourceCode.url());
else
title = WebInspector.UIString("Map workspace resource '%s' to network?", uiSourceCode.url());
var infobar = WebInspector.Infobar.create(WebInspector.Infobar.Type.Info, title, this._workspaceMappingInfobarDisabledSetting);
if (!infobar)
return;
infobar.createDetailsRowMessage(WebInspector.UIString("You can map files in your workspace to the ones loaded over the network. As a result, changes made in DevTools will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("Use context menu to establish the mapping at any time."));
var anchor = createElementWithClass("a", "link");
anchor.textContent = WebInspector.UIString("Establish the mapping now...");
anchor.addEventListener("click", this._establishTheMapping.bind(this, uiSourceCode), false);
infobar.createDetailsRowMessage("").appendChild(anchor);
this._appendInfobar(uiSourceCode, infobar);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?Event} event
*/
_establishTheMapping: function(uiSourceCode, event)
{
event.consume(true);
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
this._sourcesPanel.mapFileSystemToNetwork(uiSourceCode);
else
this._sourcesPanel.mapNetworkToFileSystem(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.Infobar} infobar
*/
_appendInfobar: function(uiSourceCode, infobar)
{
var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode);
var rowElement = infobar.createDetailsRowMessage(WebInspector.UIString("For more information on workspaces, refer to the "));
rowElement.appendChild(WebInspector.linkifyDocumentationURLAsNode("../setup/setup-workflow", WebInspector.UIString("workspaces documentation")));
rowElement.createTextChild(".");
uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol] = infobar;
uiSourceCodeFrame.attachInfobars([infobar]);
WebInspector.runCSSAnimationOnce(infobar.element, "source-frame-infobar-animation");
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | 2 1 1 1 1 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.BreakpointsSidebarPaneBase}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.XHRBreakpointsSidebarPane = function()
{
WebInspector.BreakpointsSidebarPaneBase.call(this, WebInspector.UIString("XHR Breakpoints"));
this._xhrBreakpointsSetting = WebInspector.settings.createLocalSetting("xhrBreakpoints", []);
/** @type {!Map.<string, !Element>} */
this._breakpointElements = new Map();
var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add breakpoint"), "add-toolbar-item");
addButton.addEventListener("click", this._addButtonClicked.bind(this));
this.toolbar().appendToolbarItem(addButton);
this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true);
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.XHRBreakpointsSidebarPane.prototype = {
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._restoreBreakpoints(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target) { },
_emptyElementContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint"), this._addButtonClicked.bind(this));
contextMenu.show();
},
_addButtonClicked: function(event)
{
if (event)
event.consume();
this.expand();
var inputElementContainer = createElementWithClass("p", "breakpoint-condition");
inputElementContainer.textContent = WebInspector.UIString("Break when URL contains:");
var inputElement = inputElementContainer.createChild("span", "editing");
inputElement.id = "breakpoint-condition-input";
this.addListElement(inputElementContainer, /** @type {?Element} */ (this.listElement.firstChild));
/**
* @param {boolean} accept
* @param {!Element} e
* @param {string} text
* @this {WebInspector.XHRBreakpointsSidebarPane}
*/
function finishEditing(accept, e, text)
{
this.removeListElement(inputElementContainer);
if (accept) {
this._setBreakpoint(text, true);
this._saveBreakpoints();
}
}
var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
WebInspector.InplaceEditor.startEditing(inputElement, config);
},
/**
* @param {string} url
* @param {boolean} enabled
* @param {!WebInspector.Target=} target
*/
_setBreakpoint: function(url, enabled, target)
{
if (enabled)
this._updateBreakpointOnTarget(url, true, target);
if (this._breakpointElements.has(url))
return;
var element = createElement("li");
element._url = url;
element.addEventListener("contextmenu", this._contextMenu.bind(this, url), true);
var title = url ? WebInspector.UIString("URL contains \"%s\"", url) : WebInspector.UIString("Any XHR");
var label = createCheckboxLabel(title, enabled);
element.appendChild(label);
label.checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, url), false);
element._checkboxElement = label.checkboxElement;
label.textElement.classList.add("cursor-auto");
label.textElement.addEventListener("dblclick", this._labelClicked.bind(this, url), false);
var currentElement = /** @type {?Element} */ (this.listElement.firstChild);
while (currentElement) {
if (currentElement._url && currentElement._url < element._url)
break;
currentElement = /** @type {?Element} */ (currentElement.nextSibling);
}
this.addListElement(element, currentElement);
this._breakpointElements.set(url, element);
},
/**
* @param {string} url
* @param {!WebInspector.Target=} target
*/
_removeBreakpoint: function(url, target)
{
var element = this._breakpointElements.get(url);
if (!element)
return;
this.removeListElement(element);
this._breakpointElements.delete(url);
if (element._checkboxElement.checked)
this._updateBreakpointOnTarget(url, false, target);
},
/**
* @param {string} url
* @param {boolean} enable
* @param {!WebInspector.Target=} target
*/
_updateBreakpointOnTarget: function(url, enable, target)
{
var targets = target ? [target] : WebInspector.targetManager.targets(WebInspector.Target.Type.Page);
for (var i = 0; i < targets.length; ++i) {
if (enable)
targets[i].domdebuggerAgent().setXHRBreakpoint(url);
else
targets[i].domdebuggerAgent().removeXHRBreakpoint(url);
}
},
_contextMenu: function(url, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
/**
* @this {WebInspector.XHRBreakpointsSidebarPane}
*/
function removeBreakpoint()
{
this._removeBreakpoint(url);
this._saveBreakpoints();
}
/**
* @this {WebInspector.XHRBreakpointsSidebarPane}
*/
function removeAllBreakpoints()
{
for (var url of this._breakpointElements.keys())
this._removeBreakpoint(url);
this._saveBreakpoints();
}
var removeAllTitle = WebInspector.UIString.capitalize("Remove ^all ^breakpoints");
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint"), this._addButtonClicked.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"), removeBreakpoint.bind(this));
contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this));
contextMenu.show();
},
_checkboxClicked: function(url, event)
{
this._updateBreakpointOnTarget(url, event.target.checked);
this._saveBreakpoints();
},
_labelClicked: function(url)
{
var element = this._breakpointElements.get(url) || null;
var inputElement = createElementWithClass("span", "breakpoint-condition editing");
inputElement.textContent = url;
this.listElement.insertBefore(inputElement, element);
element.classList.add("hidden");
/**
* @param {boolean} accept
* @param {!Element} e
* @param {string} text
* @this {WebInspector.XHRBreakpointsSidebarPane}
*/
function finishEditing(accept, e, text)
{
this.removeListElement(inputElement);
if (accept) {
this._removeBreakpoint(url);
this._setBreakpoint(text, element._checkboxElement.checked);
this._saveBreakpoints();
} else
element.classList.remove("hidden");
}
WebInspector.InplaceEditor.startEditing(inputElement, new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false)));
},
highlightBreakpoint: function(url)
{
var element = this._breakpointElements.get(url);
if (!element)
return;
this.expand();
element.classList.add("breakpoint-hit");
this._highlightedElement = element;
},
clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.classList.remove("breakpoint-hit");
delete this._highlightedElement;
}
},
_saveBreakpoints: function()
{
var breakpoints = [];
for (var url of this._breakpointElements.keys())
breakpoints.push({ url: url, enabled: this._breakpointElements.get(url)._checkboxElement.checked });
this._xhrBreakpointsSetting.set(breakpoints);
},
/**
* @param {!WebInspector.Target} target
*/
_restoreBreakpoints: function(target)
{
var breakpoints = this._xhrBreakpointsSetting.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint && typeof breakpoint.url === "string")
this._setBreakpoint(breakpoint.url, breakpoint.enabled, target);
}
},
__proto__: WebInspector.BreakpointsSidebarPaneBase.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| TempStorageSharedWorker.js | 26.79% | (15 / 56) | 0% | (0 / 14) | 0% | (0 / 12) | 26.79% | (15 / 56) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var ports = [];
var isTempStorageCleared = false;
/**
* @type {string}
*/
var tempStorageError;
/**
* @param {!MessageEvent} event
*/
self.onconnect = function(event)
{
var newPort = /** @type {!MessagePort} */ (event.ports[0]);
if (isTempStorageCleared) {
notifyTempStorageCleared(newPort);
return;
}
newPort.onmessage = handleMessage;
newPort.onerror = handleError;
ports.push(newPort);
if (ports.length === 1)
clearTempStorage();
}
function clearTempStorage()
{
function didFail(e)
{
tempStorageError = "Failed to clear temp storage: " + e.message + " " + e.name;
console.error(tempStorageError);
didClearTempStorage();
}
/**
* @param {!FileSystem} fs
*/
function didGetFS(fs)
{
fs.root.createReader().readEntries(didReadEntries, didFail);
}
/**
* @param {!Array.<!Entry>} entries
*/
function didReadEntries(entries)
{
var remainingEntries = entries.length;
if (!remainingEntries) {
didClearTempStorage();
return;
}
function didDeleteEntry()
{
if (!--remainingEntries)
didClearTempStorage();
}
function failedToDeleteEntry(e)
{
tempStorageError = "Failed to delete entry: " + e.message + " " + e.name;
console.error(tempStorageError);
didDeleteEntry();
}
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (entry.isFile)
entry.remove(didDeleteEntry, failedToDeleteEntry);
else
entry.removeRecursively(didDeleteEntry, failedToDeleteEntry);
}
}
self.webkitRequestFileSystem(self.TEMPORARY, 10, didGetFS, didFail);
}
function didClearTempStorage()
{
isTempStorageCleared = true;
for (var i = 0; i < ports.length; i++)
notifyTempStorageCleared(ports[i]);
ports = null;
}
/**
* @param {!MessagePort} port
*/
function notifyTempStorageCleared(port)
{
port.postMessage({
type: "tempStorageCleared",
error: tempStorageError
});
}
function handleMessage(event)
{
if (event.data.type === "disconnect")
removePort(event.target);
}
function handleError(event)
{
console.error("Error: " + event.data);
removePort(event.target);
}
function removePort(port)
{
if (!ports)
return;
var index = ports.indexOf(port);
ports.splice(index, 1);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CountersGraph.js | 0.82% | (2 / 244) | 0% | (0 / 68) | 0% | (0 / 51) | 0.82% | (2 / 244) | |
| LayerDetailsView.js | 1.45% | (1 / 69) | 0% | (0 / 24) | 0% | (0 / 12) | 1.45% | (1 / 69) | |
| LayerTreeModel.js | 2.27% | (7 / 309) | 0% | (0 / 124) | 0% | (0 / 123) | 2.27% | (7 / 308) | |
| LayerTreeOutline.js | 1.85% | (2 / 108) | 0% | (0 / 72) | 0% | (0 / 15) | 1.85% | (2 / 108) | |
| LayerViewHost.js | 1.47% | (1 / 68) | 0% | (0 / 41) | 0% | (0 / 26) | 1.47% | (1 / 68) | |
| Layers3DView.js | 1.71% | (8 / 467) | 0% | (0 / 132) | 0% | (0 / 67) | 1.71% | (8 / 467) | |
| MemoryCountersGraph.js | 3.7% | (1 / 27) | 0% | (0 / 8) | 0% | (0 / 2) | 3.7% | (1 / 27) | |
| PaintProfilerView.js | 0.78% | (2 / 255) | 0% | (0 / 69) | 0% | (0 / 30) | 0.78% | (2 / 255) | |
| TimelineController.js | 3.06% | (3 / 98) | 0% | (0 / 50) | 0% | (0 / 21) | 3.13% | (3 / 96) | |
| TimelineEventOverview.js | 3.61% | (15 / 416) | 0% | (0 / 101) | 0% | (0 / 40) | 3.61% | (15 / 416) | |
| TimelineFlameChart.js | 0.88% | (5 / 566) | 0% | (0 / 236) | 0% | (0 / 91) | 0.89% | (5 / 562) | |
| TimelineFrameModel.js | 4.15% | (11 / 265) | 0% | (0 / 171) | 0% | (0 / 48) | 4.15% | (11 / 265) | |
| TimelineIRModel.js | 2.7% | (3 / 111) | 0% | (0 / 59) | 0% | (0 / 10) | 2.7% | (3 / 111) | |
| TimelineJSProfile.js | 6.05% | (13 / 215) | 0% | (0 / 91) | 0% | (0 / 29) | 6.07% | (13 / 214) | |
| TimelineLayersView.js | 7.27% | (4 / 55) | 0% | (0 / 12) | 0% | (0 / 9) | 7.27% | (4 / 55) | |
| TimelineLoader.js | 1.08% | (1 / 93) | 0% | (0 / 36) | 0% | (0 / 19) | 1.08% | (1 / 93) | |
| TimelineModel.js | 0.83% | (6 / 724) | 0% | (0 / 435) | 0% | (0 / 93) | 0.84% | (6 / 718) | |
| TimelinePaintProfilerView.js | 4.04% | (4 / 99) | 0% | (0 / 28) | 0% | (0 / 14) | 4.04% | (4 / 99) | |
| TimelinePanel.js | 1.69% | (14 / 829) | 0% | (0 / 281) | 0% | (0 / 171) | 1.7% | (14 / 825) | |
| TimelineProfileTree.js | 3.8% | (7 / 184) | 0% | (0 / 93) | 0% | (0 / 20) | 3.83% | (7 / 183) | |
| TimelineTreeView.js | 1.73% | (6 / 346) | 0% | (0 / 139) | 0% | (0 / 57) | 1.75% | (6 / 342) | |
| TimelineUIUtils.js | 1.96% | (20 / 1023) | 0% | (0 / 590) | 0% | (0 / 100) | 1.96% | (20 / 1023) | |
| TransformController.js | 0.85% | (1 / 118) | 0% | (0 / 22) | 0% | (0 / 28) | 0.85% | (1 / 118) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 | 2 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TimelineModeView}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} model
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
*/
WebInspector.CountersGraph = function(delegate, model, filters)
{
WebInspector.VBox.call(this);
this.element.id = "memory-graphs-container";
this._delegate = delegate;
this._model = model;
this._filters = filters;
this._calculator = new WebInspector.CounterGraphCalculator(this._model);
// Create selectors
this._infoWidget = new WebInspector.HBox();
this._infoWidget.element.classList.add("memory-counter-selector-swatches", "timeline-toolbar-resizer");
this._infoWidget.show(this.element);
this._graphsContainer = new WebInspector.VBox();
this._graphsContainer.show(this.element);
var canvasWidget = new WebInspector.VBoxWithResizeCallback(this._resize.bind(this));
canvasWidget.show(this._graphsContainer.element);
this._createCurrentValuesBar();
this._canvasContainer = canvasWidget.element;
this._canvasContainer.id = "memory-graphs-canvas-container";
this._canvas = this._canvasContainer.createChild("canvas");
this._canvas.id = "memory-counters-graph";
this._canvasContainer.addEventListener("mouseover", this._onMouseMove.bind(this), true);
this._canvasContainer.addEventListener("mousemove", this._onMouseMove.bind(this), true);
this._canvasContainer.addEventListener("mouseleave", this._onMouseLeave.bind(this), true);
this._canvasContainer.addEventListener("click", this._onClick.bind(this), true);
// We create extra timeline grid here to reuse its event dividers.
this._timelineGrid = new WebInspector.TimelineGrid();
this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
this._counters = [];
this._counterUI = [];
}
WebInspector.CountersGraph.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._model.target();
},
_createCurrentValuesBar: function()
{
this._currentValuesBar = this._graphsContainer.element.createChild("div");
this._currentValuesBar.id = "counter-values-bar";
},
/**
* @param {string} uiName
* @param {string} uiValueTemplate
* @param {string} color
* @param {function(number):string=} formatter
* @return {!WebInspector.CountersGraph.Counter}
*/
createCounter: function(uiName, uiValueTemplate, color, formatter)
{
var counter = new WebInspector.CountersGraph.Counter();
this._counters.push(counter);
this._counterUI.push(new WebInspector.CountersGraph.CounterUI(this, uiName, uiValueTemplate, color, counter, formatter));
return counter;
},
/**
* @override
* @return {!WebInspector.Widget}
*/
view: function()
{
return this;
},
/**
* @override
*/
dispose: function()
{
},
/**
* @override
*/
reset: function()
{
for (var i = 0; i < this._counters.length; ++i) {
this._counters[i].reset();
this._counterUI[i].reset();
}
this.refresh();
},
/**
* @override
* @return {?Element}
*/
resizerElement: function()
{
return this._infoWidget.element;
},
_resize: function()
{
var parentElement = this._canvas.parentElement;
this._canvas.width = parentElement.clientWidth * window.devicePixelRatio;
this._canvas.height = parentElement.clientHeight * window.devicePixelRatio;
var timelinePaddingLeft = 15;
this._calculator.setDisplayWindow(this._canvas.width, timelinePaddingLeft);
this.refresh();
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
*/
setWindowTimes: function(startTime, endTime)
{
this._calculator.setWindow(startTime, endTime);
this.scheduleRefresh();
},
scheduleRefresh: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this.refresh);
},
draw: function()
{
for (var i = 0; i < this._counters.length; ++i) {
this._counters[i]._calculateVisibleIndexes(this._calculator);
this._counters[i]._calculateXValues(this._canvas.width);
}
this._clear();
for (var i = 0; i < this._counterUI.length; i++)
this._counterUI[i]._drawGraph(this._canvas);
},
/**
* @param {!Event} event
*/
_onClick: function(event)
{
var x = event.x - this._canvasContainer.totalOffsetLeft();
var minDistance = Infinity;
var bestTime;
for (var i = 0; i < this._counterUI.length; ++i) {
var counterUI = this._counterUI[i];
if (!counterUI.counter.times.length)
continue;
var index = counterUI._recordIndexAt(x);
var distance = Math.abs(x * window.devicePixelRatio - counterUI.counter.x[index]);
if (distance < minDistance) {
minDistance = distance;
bestTime = counterUI.counter.times[index];
}
}
if (bestTime !== undefined)
this._revealRecordAt(bestTime);
},
/**
* @param {number} time
*/
_revealRecordAt: function(time)
{
var recordToReveal;
/**
* @param {!WebInspector.TimelineModel.Record} record
* @return {boolean}
* @this {WebInspector.CountersGraph}
*/
function findRecordToReveal(record)
{
if (!WebInspector.TimelineModel.isVisible(this._filters, record.traceEvent()))
return false;
if (record.startTime() <= time && time <= record.endTime()) {
recordToReveal = record;
return true;
}
// If there is no record containing the time than use the latest one before that time.
if (!recordToReveal || record.endTime() < time && recordToReveal.endTime() < record.endTime())
recordToReveal = record;
return false;
}
this._model.forAllRecords(null, findRecordToReveal.bind(this));
this._delegate.select(recordToReveal ? WebInspector.TimelineSelection.fromTraceEvent(recordToReveal.traceEvent()) : null);
},
/**
* @param {!Event} event
*/
_onMouseLeave: function(event)
{
delete this._markerXPosition;
this._clearCurrentValueAndMarker();
},
_clearCurrentValueAndMarker: function()
{
for (var i = 0; i < this._counterUI.length; i++)
this._counterUI[i]._clearCurrentValueAndMarker();
},
/**
* @param {!Event} event
*/
_onMouseMove: function(event)
{
var x = event.x - this._canvasContainer.totalOffsetLeft();
this._markerXPosition = x;
this._refreshCurrentValues();
},
_refreshCurrentValues: function()
{
if (this._markerXPosition === undefined)
return;
for (var i = 0; i < this._counterUI.length; ++i)
this._counterUI[i].updateCurrentValue(this._markerXPosition);
},
refresh: function()
{
this._timelineGrid.updateDividers(this._calculator);
this.draw();
this._refreshCurrentValues();
},
/**
* @override
*/
refreshRecords: function() { },
_clear: function()
{
var ctx = this._canvas.getContext("2d");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
},
/**
* @override
* @param {?WebInspector.TimelineModel.Record} record
* @param {string=} regex
* @param {boolean=} selectRecord
*/
highlightSearchResult: function(record, regex, selectRecord)
{
},
/**
* @override
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event)
{
},
/**
* @override
* @param {?WebInspector.TimelineSelection} selection
*/
setSelection: function(selection)
{
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
*/
WebInspector.CountersGraph.Counter = function()
{
this.times = [];
this.values = [];
}
WebInspector.CountersGraph.Counter.prototype = {
/**
* @param {number} time
* @param {number} value
*/
appendSample: function(time, value)
{
if (this.values.length && this.values.peekLast() === value)
return;
this.times.push(time);
this.values.push(value);
},
reset: function()
{
this.times = [];
this.values = [];
},
/**
* @param {number} value
*/
setLimit: function(value)
{
this._limitValue = value;
},
/**
* @return {!{min: number, max: number}}
*/
_calculateBounds: function()
{
var maxValue;
var minValue;
for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
var value = this.values[i];
if (minValue === undefined || value < minValue)
minValue = value;
if (maxValue === undefined || value > maxValue)
maxValue = value;
}
minValue = minValue || 0;
maxValue = maxValue || 1;
if (this._limitValue) {
if (maxValue > this._limitValue * 0.5)
maxValue = Math.max(maxValue, this._limitValue);
minValue = Math.min(minValue, this._limitValue);
}
return { min: minValue, max: maxValue };
},
/**
* @param {!WebInspector.CounterGraphCalculator} calculator
*/
_calculateVisibleIndexes: function(calculator)
{
var start = calculator.minimumBoundary();
var end = calculator.maximumBoundary();
// Maximum index of element whose time <= start.
this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, this.times.length - 1);
// Minimum index of element whose time >= end.
this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, this.times.length - 1);
// Current window bounds.
this._minTime = start;
this._maxTime = end;
},
/**
* @param {number} width
*/
_calculateXValues: function(width)
{
if (!this.values.length)
return;
var xFactor = width / (this._maxTime - this._minTime);
this.x = new Array(this.values.length);
for (var i = this._minimumIndex + 1; i <= this._maximumIndex; i++)
this.x[i] = xFactor * (this.times[i] - this._minTime);
}
}
/**
* @constructor
* @param {!WebInspector.CountersGraph} memoryCountersPane
* @param {string} title
* @param {string} currentValueLabel
* @param {string} graphColor
* @param {!WebInspector.CountersGraph.Counter} counter
* @param {(function(number): string)|undefined} formatter
*/
WebInspector.CountersGraph.CounterUI = function(memoryCountersPane, title, currentValueLabel, graphColor, counter, formatter)
{
this._memoryCountersPane = memoryCountersPane;
this.counter = counter;
this._formatter = formatter || Number.withThousandsSeparator;
var container = memoryCountersPane._infoWidget.element.createChild("div", "memory-counter-selector-info");
this._setting = WebInspector.settings.createSetting("timelineCountersGraph-" + title, true);
this._filter = new WebInspector.ToolbarCheckbox(title, title, this._setting);
var color = WebInspector.Color.parse(graphColor).setAlpha(0.5).asString(WebInspector.Color.Format.RGBA);
if (color) {
this._filter.element.backgroundColor = color;
this._filter.element.borderColor = "transparent";
}
this._filter.inputElement.addEventListener("click", this._toggleCounterGraph.bind(this));
container.appendChild(this._filter.element);
this._range = this._filter.element.createChild("span", "range");
this._value = memoryCountersPane._currentValuesBar.createChild("span", "memory-counter-value");
this._value.style.color = graphColor;
this.graphColor = graphColor;
this.limitColor = WebInspector.Color.parse(graphColor).setAlpha(0.3).asString(WebInspector.Color.Format.RGBA);
this.graphYValues = [];
this._verticalPadding = 10;
this._currentValueLabel = currentValueLabel;
this._marker = memoryCountersPane._canvasContainer.createChild("div", "memory-counter-marker");
this._marker.style.backgroundColor = graphColor;
this._clearCurrentValueAndMarker();
}
WebInspector.CountersGraph.CounterUI.prototype = {
reset: function()
{
this._range.textContent = "";
},
/**
* @param {number} minValue
* @param {number} maxValue
*/
setRange: function(minValue, maxValue)
{
var min = this._formatter(minValue);
var max = this._formatter(maxValue);
this._range.textContent = WebInspector.UIString("[%s\u2009\u2013\u2009%s]", min, max);
},
/**
* @param {!WebInspector.Event} event
*/
_toggleCounterGraph: function(event)
{
this._value.classList.toggle("hidden", !this._filter.checked());
this._memoryCountersPane.refresh();
},
/**
* @param {number} x
* @return {number}
*/
_recordIndexAt: function(x)
{
return this.counter.x.upperBound(x * window.devicePixelRatio, null, this.counter._minimumIndex + 1, this.counter._maximumIndex + 1) - 1;
},
/**
* @param {number} x
*/
updateCurrentValue: function(x)
{
if (!this.visible() || !this.counter.values.length || !this.counter.x)
return;
var index = this._recordIndexAt(x);
var value = Number.withThousandsSeparator(this.counter.values[index]);
this._value.textContent = WebInspector.UIString(this._currentValueLabel, value);
var y = this.graphYValues[index] / window.devicePixelRatio;
this._marker.style.left = x + "px";
this._marker.style.top = y + "px";
this._marker.classList.remove("hidden");
},
_clearCurrentValueAndMarker: function()
{
this._value.textContent = "";
this._marker.classList.add("hidden");
},
/**
* @param {!HTMLCanvasElement} canvas
*/
_drawGraph: function(canvas)
{
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height - 2 * this._verticalPadding;
if (height <= 0) {
this.graphYValues = [];
return;
}
var originY = this._verticalPadding;
var counter = this.counter;
var values = counter.values;
if (!values.length)
return;
var bounds = counter._calculateBounds();
var minValue = bounds.min;
var maxValue = bounds.max;
this.setRange(minValue, maxValue);
if (!this.visible())
return;
var yValues = this.graphYValues;
var maxYRange = maxValue - minValue;
var yFactor = maxYRange ? height / (maxYRange) : 1;
ctx.save();
ctx.lineWidth = window.devicePixelRatio;
if (ctx.lineWidth % 2)
ctx.translate(0.5, 0.5);
ctx.beginPath();
var value = values[counter._minimumIndex];
var currentY = Math.round(originY + height - (value - minValue) * yFactor);
ctx.moveTo(0, currentY);
for (var i = counter._minimumIndex; i <= counter._maximumIndex; i++) {
var x = Math.round(counter.x[i]);
ctx.lineTo(x, currentY);
var currentValue = values[i];
if (typeof currentValue !== "undefined")
value = currentValue;
currentY = Math.round(originY + height - (value - minValue) * yFactor);
ctx.lineTo(x, currentY);
yValues[i] = currentY;
}
yValues.length = i;
ctx.lineTo(width, currentY);
ctx.strokeStyle = this.graphColor;
ctx.stroke();
if (counter._limitValue) {
var limitLineY = Math.round(originY + height - (counter._limitValue - minValue) * yFactor);
ctx.moveTo(0, limitLineY);
ctx.lineTo(width, limitLineY);
ctx.strokeStyle = this.limitColor;
ctx.stroke();
}
ctx.closePath();
ctx.restore();
},
/**
* @return {boolean}
*/
visible: function()
{
return this._filter.checked();
}
}
/**
* @constructor
* @param {!WebInspector.TimelineModel} model
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.CounterGraphCalculator = function(model)
{
this._model = model;
}
WebInspector.CounterGraphCalculator._minWidth = 5;
WebInspector.CounterGraphCalculator.prototype = {
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return this._paddingLeft;
},
/**
* @override
* @param {number} time
* @return {number}
*/
computePosition: function(time)
{
return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this._paddingLeft;
},
setWindow: function(minimumBoundary, maximumBoundary)
{
this._minimumBoundary = minimumBoundary;
this._maximumBoundary = maximumBoundary;
},
/**
* @param {number} clientWidth
* @param {number=} paddingLeft
*/
setDisplayWindow: function(clientWidth, paddingLeft)
{
this._paddingLeft = paddingLeft || 0;
this._workingArea = clientWidth - WebInspector.CounterGraphCalculator._minWidth - this._paddingLeft;
},
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.preciseMillisToString(value - this.zeroTime(), precision);
},
/**
* @override
* @return {number}
*/
maximumBoundary: function()
{
return this._maximumBoundary;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
zeroTime: function()
{
return this._model.minimumRecordTime();
},
/**
* @override
* @return {number}
*/
boundarySpan: function()
{
return this._maximumBoundary - this._minimumBoundary;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.LayerViewHost} layerViewHost
* @extends {WebInspector.Widget}
* @implements {WebInspector.LayerView}
*/
WebInspector.LayerDetailsView = function(layerViewHost)
{
WebInspector.Widget.call(this);
this.element.classList.add("layer-details-view");
this._layerViewHost = layerViewHost;
this._layerViewHost.registerView(this);
this._emptyWidget = new WebInspector.EmptyWidget(WebInspector.UIString("Select a layer to see its details"));
this._buildContent();
}
/**
* @enum {string}
*/
WebInspector.LayerDetailsView.Events = {
PaintProfilerRequested: "PaintProfilerRequested"
}
/**
* @type {!Object.<string, string>}
*/
WebInspector.LayerDetailsView.CompositingReasonDetail = {
"transform3D": WebInspector.UIString("Composition due to association with an element with a CSS 3D transform."),
"video": WebInspector.UIString("Composition due to association with a <video> element."),
"canvas": WebInspector.UIString("Composition due to the element being a <canvas> element."),
"plugin": WebInspector.UIString("Composition due to association with a plugin."),
"iFrame": WebInspector.UIString("Composition due to association with an <iframe> element."),
"backfaceVisibilityHidden": WebInspector.UIString("Composition due to association with an element with a \"backface-visibility: hidden\" style."),
"animation": WebInspector.UIString("Composition due to association with an animated element."),
"filters": WebInspector.UIString("Composition due to association with an element with CSS filters applied."),
"positionFixed": WebInspector.UIString("Composition due to association with an element with a \"position: fixed\" style."),
// FIXME: Can we remove this entry now that position: sticky has been removed?
"positionSticky": WebInspector.UIString("Composition due to association with an element with a \"position: sticky\" style."),
"overflowScrollingTouch": WebInspector.UIString("Composition due to association with an element with a \"overflow-scrolling: touch\" style."),
"blending": WebInspector.UIString("Composition due to association with an element that has blend mode other than \"normal\"."),
"assumedOverlap": WebInspector.UIString("Composition due to association with an element that may overlap other composited elements."),
"overlap": WebInspector.UIString("Composition due to association with an element overlapping other composited elements."),
"negativeZIndexChildren": WebInspector.UIString("Composition due to association with an element with descendants that have a negative z-index."),
"transformWithCompositedDescendants": WebInspector.UIString("Composition due to association with an element with composited descendants."),
"opacityWithCompositedDescendants": WebInspector.UIString("Composition due to association with an element with opacity applied and composited descendants."),
"maskWithCompositedDescendants": WebInspector.UIString("Composition due to association with a masked element and composited descendants."),
"reflectionWithCompositedDescendants": WebInspector.UIString("Composition due to association with an element with a reflection and composited descendants."),
"filterWithCompositedDescendants": WebInspector.UIString("Composition due to association with an element with CSS filters applied and composited descendants."),
"blendingWithCompositedDescendants": WebInspector.UIString("Composition due to association with an element with CSS blending applied and composited descendants."),
"clipsCompositingDescendants": WebInspector.UIString("Composition due to association with an element clipping compositing descendants."),
"perspective": WebInspector.UIString("Composition due to association with an element with perspective applied."),
"preserve3D": WebInspector.UIString("Composition due to association with an element with a \"transform-style: preserve-3d\" style."),
"root": WebInspector.UIString("Root layer."),
"layerForClip": WebInspector.UIString("Layer for clip."),
"layerForScrollbar": WebInspector.UIString("Layer for scrollbar."),
"layerForScrollingContainer": WebInspector.UIString("Layer for scrolling container."),
"layerForForeground": WebInspector.UIString("Layer for foreground."),
"layerForBackground": WebInspector.UIString("Layer for background."),
"layerForMask": WebInspector.UIString("Layer for mask."),
"layerForVideoOverlay": WebInspector.UIString("Layer for video overlay."),
};
WebInspector.LayerDetailsView.prototype = {
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
hoverObject: function(selection) { },
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
selectObject: function(selection)
{
this._selection = selection;
if (this.isShowing())
this.update();
},
/**
* @param {?WebInspector.LayerTreeBase} layerTree
* @override
*/
setLayerTree: function(layerTree) { },
wasShown: function()
{
WebInspector.Widget.prototype.wasShown.call(this);
this.update();
},
/**
* @param {number} index
* @param {!Event} event
*/
_onScrollRectClicked: function(index, event)
{
if (event.which !== 1)
return;
this._layerViewHost.selectObject(new WebInspector.LayerView.ScrollRectSelection(this._selection.layer(), index));
},
_onPaintProfilerButtonClicked: function()
{
var traceEvent = this._selection.type() === WebInspector.LayerView.Selection.Type.Tile ? /** @type {!WebInspector.LayerView.TileSelection} */ (this._selection).traceEvent() : null;
this.dispatchEventToListeners(WebInspector.LayerDetailsView.Events.PaintProfilerRequested, traceEvent);
},
/**
* @param {!LayerTreeAgent.ScrollRect} scrollRect
* @param {number} index
*/
_createScrollRectElement: function(scrollRect, index)
{
if (index)
this._scrollRectsCell.createTextChild(", ");
var element = this._scrollRectsCell.createChild("span", "scroll-rect");
if (this._selection.scrollRectIndex === index)
element.classList.add("active");
element.textContent = WebInspector.LayerTreeModel.ScrollRectType[scrollRect.type].description + " (" + scrollRect.rect.x + ", " + scrollRect.rect.y +
", " + scrollRect.rect.width + ", " + scrollRect.rect.height + ")";
element.addEventListener("click", this._onScrollRectClicked.bind(this, index), false);
},
update: function()
{
var layer = this._selection && this._selection.layer();
if (!layer) {
this._tableElement.remove();
this._paintProfilerButton.remove();
this._emptyWidget.show(this.element);
return;
}
this._emptyWidget.detach();
this.element.appendChild(this._tableElement);
this.element.appendChild(this._paintProfilerButton);
this._sizeCell.textContent = WebInspector.UIString("%d × %d (at %d,%d)", layer.width(), layer.height(), layer.offsetX(), layer.offsetY());
this._paintCountCell.parentElement.classList.toggle("hidden", !layer.paintCount());
this._paintCountCell.textContent = layer.paintCount();
this._memoryEstimateCell.textContent = Number.bytesToString(layer.gpuMemoryUsage());
layer.requestCompositingReasons(this._updateCompositingReasons.bind(this));
this._scrollRectsCell.removeChildren();
layer.scrollRects().forEach(this._createScrollRectElement.bind(this));
var traceEvent = this._selection.type() === WebInspector.LayerView.Selection.Type.Tile ? /** @type {!WebInspector.LayerView.TileSelection} */ (this._selection).traceEvent() : null;
this._paintProfilerButton.classList.toggle("hidden", !traceEvent);
},
_buildContent: function()
{
this._tableElement = this.element.createChild("table");
this._tbodyElement = this._tableElement.createChild("tbody");
this._sizeCell = this._createRow(WebInspector.UIString("Size"));
this._compositingReasonsCell = this._createRow(WebInspector.UIString("Compositing Reasons"));
this._memoryEstimateCell = this._createRow(WebInspector.UIString("Memory estimate"));
this._paintCountCell = this._createRow(WebInspector.UIString("Paint count"));
this._scrollRectsCell = this._createRow(WebInspector.UIString("Slow scroll regions"));
this._paintProfilerButton = this.element.createChild("a", "hidden link");
this._paintProfilerButton.textContent = WebInspector.UIString("Paint Profiler");
this._paintProfilerButton.addEventListener("click", this._onPaintProfilerButtonClicked.bind(this));
},
/**
* @param {string} title
*/
_createRow: function(title)
{
var tr = this._tbodyElement.createChild("tr");
var titleCell = tr.createChild("td");
titleCell.textContent = title;
return tr.createChild("td");
},
/**
* @param {!Array.<string>} compositingReasons
*/
_updateCompositingReasons: function(compositingReasons)
{
if (!compositingReasons || !compositingReasons.length) {
this._compositingReasonsCell.textContent = "n/a";
return;
}
this._compositingReasonsCell.removeChildren();
var list = this._compositingReasonsCell.createChild("ul");
for (var i = 0; i < compositingReasons.length; ++i) {
var text = WebInspector.LayerDetailsView.CompositingReasonDetail[compositingReasons[i]] || compositingReasons[i];
// If the text is more than one word but does not terminate with period, add the period.
if (/\s.*[^.]$/.test(text))
text += ".";
list.createChild("li").textContent = text;
}
},
__proto__: WebInspector.Widget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @typedef {!{
bounds: {height: number, width: number},
children: Array.<!WebInspector.TracingLayerPayload>,
layer_id: number,
position: Array.<number>,
scroll_offset: Array.<number>,
layer_quad: Array.<number>,
draws_content: number,
gpu_memory_usage: number,
transform: Array.<number>,
owner_node: number,
compositing_reasons: Array.<string>
}}
*/
WebInspector.TracingLayerPayload;
/** @typedef {!{
id: string,
layer_id: number,
gpu_memory_usage: number,
content_rect: !Array.<number>
}}
*/
WebInspector.TracingLayerTile;
/**
* @constructor
* @extends {WebInspector.SDKModel}
*/
WebInspector.LayerTreeModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.LayerTreeModel, target);
target.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
/** @type {?WebInspector.LayerTreeBase} */
this._layerTree = null;
}
WebInspector.LayerTreeModel.Events = {
LayerTreeChanged: "LayerTreeChanged",
LayerPainted: "LayerPainted",
}
WebInspector.LayerTreeModel.ScrollRectType = {
NonFastScrollable: {name: "NonFastScrollable", description: "Non fast scrollable"},
TouchEventHandler: {name: "TouchEventHandler", description: "Touch event handler"},
WheelEventHandler: {name: "WheelEventHandler", description: "Wheel event handler"},
RepaintsOnScroll: {name: "RepaintsOnScroll", description: "Repaints on scroll"}
}
WebInspector.LayerTreeModel.prototype = {
disable: function()
{
if (!this._enabled)
return;
this._enabled = false;
this._layerTree = null;
this.target().layerTreeAgent().disable();
},
enable: function()
{
if (this._enabled)
return;
this._enabled = true;
this._forceEnable();
},
_forceEnable: function()
{
this._layerTree = new WebInspector.AgentLayerTree(this.target());
this._lastPaintRectByLayerId = {};
this.target().layerTreeAgent().enable();
},
/**
* @param {!WebInspector.LayerTreeBase} layerTree
*/
setLayerTree: function(layerTree)
{
this.disable();
this._layerTree = layerTree;
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
},
/**
* @return {?WebInspector.LayerTreeBase}
*/
layerTree: function()
{
return this._layerTree;
},
/**
* @param {?Array.<!LayerTreeAgent.Layer>} layers
*/
_layerTreeChanged: function(layers)
{
if (!this._enabled)
return;
var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
layerTree.setLayers(layers, onLayersSet.bind(this));
/**
* @this {WebInspector.LayerTreeModel}
*/
function onLayersSet()
{
for (var layerId in this._lastPaintRectByLayerId) {
var lastPaintRect = this._lastPaintRectByLayerId[layerId];
var layer = layerTree.layerById(layerId);
if (layer)
layer._lastPaintRect = lastPaintRect;
}
this._lastPaintRectByLayerId = {};
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
}
},
/**
* @param {!LayerTreeAgent.LayerId} layerId
* @param {!DOMAgent.Rect} clipRect
*/
_layerPainted: function(layerId, clipRect)
{
if (!this._enabled)
return;
var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
var layer = layerTree.layerById(layerId);
if (!layer) {
this._lastPaintRectByLayerId[layerId] = clipRect;
return;
}
layer._didPaint(clipRect);
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted, layer);
},
_onMainFrameNavigated: function()
{
if (this._enabled)
this._forceEnable();
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @param {?WebInspector.Target} target
*/
WebInspector.LayerTreeBase = function(target)
{
this._target = target;
this._domModel = target ? WebInspector.DOMModel.fromTarget(target) : null;
this._layersById = {};
/** @type Map<number, ?WebInspector.DOMNode> */
this._backendNodeIdToNode = new Map();
this._reset();
}
WebInspector.LayerTreeBase.prototype = {
_reset: function()
{
this._root = null;
this._contentRoot = null;
},
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @return {?WebInspector.Layer}
*/
root: function()
{
return this._root;
},
/**
* @return {?WebInspector.Layer}
*/
contentRoot: function()
{
return this._contentRoot;
},
/**
* @param {function(!WebInspector.Layer)} callback
* @param {?WebInspector.Layer=} root
* @return {boolean}
*/
forEachLayer: function(callback, root)
{
if (!root) {
root = this.root();
if (!root)
return false;
}
return callback(root) || root.children().some(this.forEachLayer.bind(this, callback));
},
/**
* @param {string} id
* @return {?WebInspector.Layer}
*/
layerById: function(id)
{
return this._layersById[id] || null;
},
/**
* @param {!Set<number>} requestedNodeIds
* @param {function()} callback
*/
_resolveBackendNodeIds: function(requestedNodeIds, callback)
{
if (!requestedNodeIds.size || !this._domModel) {
callback();
return;
}
if (this._domModel)
this._domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds, populateBackendNodeMap.bind(this));
/**
* @this {WebInspector.LayerTreeBase}
* @param {?Map<number, ?WebInspector.DOMNode>} nodesMap
*/
function populateBackendNodeMap(nodesMap)
{
if (nodesMap) {
for (var nodeId of nodesMap.keysArray())
this._backendNodeIdToNode.set(nodeId, nodesMap.get(nodeId) || null);
}
callback();
}
},
/**
* @param {!Object} viewportSize
*/
setViewportSize: function(viewportSize)
{
this._viewportSize = viewportSize;
},
/**
* @return {!Object | undefined}
*/
viewportSize: function()
{
return this._viewportSize;
},
/**
* @param {number} id
* @return {?WebInspector.DOMNode}
*/
_nodeForId: function(id)
{
return this._domModel ? this._domModel.nodeForId(id) : null;
}
}
/**
* @constructor
* @extends {WebInspector.LayerTreeBase}
* @param {?WebInspector.Target} target
*/
WebInspector.TracingLayerTree = function(target)
{
WebInspector.LayerTreeBase.call(this, target);
/** @type {!Map.<string, !WebInspector.TracingLayerTile>} */
this._tileById = new Map();
}
WebInspector.TracingLayerTree.prototype = {
/**
* @param {!WebInspector.TracingLayerPayload} root
* @param {function()} callback
*/
setLayers: function(root, callback)
{
var idsToResolve = new Set();
this._extractNodeIdsToResolve(idsToResolve, {}, root);
this._resolveBackendNodeIds(idsToResolve, onBackendNodeIdsResolved.bind(this));
/**
* @this {WebInspector.TracingLayerTree}
*/
function onBackendNodeIdsResolved()
{
var oldLayersById = this._layersById;
this._layersById = {};
this._contentRoot = null;
this._root = this._innerSetLayers(oldLayersById, root);
callback();
}
},
/**
* @param {!Array.<!WebInspector.TracingLayerTile>} tiles
*/
setTiles: function(tiles)
{
this._tileById = new Map();
for (var tile of tiles)
this._tileById.set(tile.id, tile);
},
/**
* @param {string} id
* @return {?WebInspector.TracingLayerTile}
*/
tileById: function(id)
{
return this._tileById.get(id) || null;
},
/**
* @param {!Object.<(string|number), !WebInspector.Layer>} oldLayersById
* @param {!WebInspector.TracingLayerPayload} payload
* @return {!WebInspector.TracingLayer}
*/
_innerSetLayers: function(oldLayersById, payload)
{
var layer = /** @type {?WebInspector.TracingLayer} */ (oldLayersById[payload.layer_id]);
if (layer)
layer._reset(payload);
else
layer = new WebInspector.TracingLayer(payload);
this._layersById[payload.layer_id] = layer;
if (payload.owner_node)
layer._setNode(this._backendNodeIdToNode.get(payload.owner_node) || null);
if (!this._contentRoot && layer.drawsContent())
this._contentRoot = layer;
for (var i = 0; payload.children && i < payload.children.length; ++i)
layer.addChild(this._innerSetLayers(oldLayersById, payload.children[i]));
return layer;
},
/**
* @param {!Set<number>} nodeIdsToResolve
* @param {!Object} seenNodeIds
* @param {!WebInspector.TracingLayerPayload} payload
*/
_extractNodeIdsToResolve: function(nodeIdsToResolve, seenNodeIds, payload)
{
var backendNodeId = payload.owner_node;
if (backendNodeId && !this._backendNodeIdToNode.has(backendNodeId))
nodeIdsToResolve.add(backendNodeId);
for (var i = 0; payload.children && i < payload.children.length; ++i)
this._extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload.children[i]);
},
__proto__: WebInspector.LayerTreeBase.prototype
}
/**
* @constructor
* @param {?WebInspector.Target} target
* @extends {WebInspector.LayerTreeBase}
*/
WebInspector.AgentLayerTree = function(target)
{
WebInspector.LayerTreeBase.call(this, target);
}
WebInspector.AgentLayerTree.prototype = {
/**
* @param {?Array.<!LayerTreeAgent.Layer>} payload
* @param {function()} callback
*/
setLayers: function(payload, callback)
{
if (!payload) {
onBackendNodeIdsResolved.call(this);
return;
}
var idsToResolve = new Set();
for (var i = 0; i < payload.length; ++i) {
var backendNodeId = payload[i].backendNodeId;
if (!backendNodeId || this._backendNodeIdToNode.has(backendNodeId))
continue;
idsToResolve.add(backendNodeId);
}
this._resolveBackendNodeIds(idsToResolve, onBackendNodeIdsResolved.bind(this));
/**
* @this {WebInspector.AgentLayerTree}
*/
function onBackendNodeIdsResolved()
{
this._innerSetLayers(payload);
callback();
}
},
/**
* @param {?Array.<!LayerTreeAgent.Layer>} layers
*/
_innerSetLayers: function(layers)
{
this._reset();
// Payload will be null when not in the composited mode.
if (!layers)
return;
var oldLayersById = this._layersById;
this._layersById = {};
for (var i = 0; i < layers.length; ++i) {
var layerId = layers[i].layerId;
var layer = oldLayersById[layerId];
if (layer)
layer._reset(layers[i]);
else
layer = new WebInspector.AgentLayer(this._target, layers[i]);
this._layersById[layerId] = layer;
var backendNodeId = layers[i].backendNodeId;
if (backendNodeId)
layer._setNode(this._backendNodeIdToNode.get(backendNodeId));
if (!this._contentRoot && layer.drawsContent())
this._contentRoot = layer;
var parentId = layer.parentId();
if (parentId) {
var parent = this._layersById[parentId];
if (!parent)
console.assert(parent, "missing parent " + parentId + " for layer " + layerId);
parent.addChild(layer);
} else {
if (this._root)
console.assert(false, "Multiple root layers");
this._root = layer;
}
}
if (this._root)
this._root._calculateQuad(new WebKitCSSMatrix());
},
__proto__: WebInspector.LayerTreeBase.prototype
}
/**
* @interface
*/
WebInspector.Layer = function()
{
}
WebInspector.Layer.prototype = {
/**
* @return {string}
*/
id: function() { },
/**
* @return {?string}
*/
parentId: function() { },
/**
* @return {?WebInspector.Layer}
*/
parent: function() { },
/**
* @return {boolean}
*/
isRoot: function() { },
/**
* @return {!Array.<!WebInspector.Layer>}
*/
children: function() { },
/**
* @param {!WebInspector.Layer} child
*/
addChild: function(child) { },
/**
* @return {?WebInspector.DOMNode}
*/
node: function() { },
/**
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function() { },
/**
* @return {number}
*/
offsetX: function() { },
/**
* @return {number}
*/
offsetY: function() { },
/**
* @return {number}
*/
width: function() { },
/**
* @return {number}
*/
height: function() { },
/**
* @return {?Array.<number>}
*/
transform: function() { },
/**
* @return {!Array.<number>}
*/
quad: function() { },
/**
* @return {!Array.<number>}
*/
anchorPoint: function() { },
/**
* @return {boolean}
*/
invisible: function() { },
/**
* @return {number}
*/
paintCount: function() { },
/**
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function() { },
/**
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function() { },
/**
* @return {number}
*/
gpuMemoryUsage: function() { },
/**
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback) { },
/**
* @return {boolean}
*/
drawsContent: function() { }
}
/**
* @constructor
* @implements {WebInspector.Layer}
* @param {?WebInspector.Target} target
* @param {!LayerTreeAgent.Layer} layerPayload
*/
WebInspector.AgentLayer = function(target, layerPayload)
{
this._target = target;
this._reset(layerPayload);
}
WebInspector.AgentLayer.prototype = {
/**
* @override
* @return {string}
*/
id: function()
{
return this._layerPayload.layerId;
},
/**
* @override
* @return {?string}
*/
parentId: function()
{
return this._layerPayload.parentLayerId;
},
/**
* @override
* @return {?WebInspector.Layer}
*/
parent: function()
{
return this._parent;
},
/**
* @override
* @return {boolean}
*/
isRoot: function()
{
return !this.parentId();
},
/**
* @override
* @return {!Array.<!WebInspector.Layer>}
*/
children: function()
{
return this._children;
},
/**
* @override
* @param {!WebInspector.Layer} child
*/
addChild: function(child)
{
if (child._parent)
console.assert(false, "Child already has a parent");
this._children.push(child);
child._parent = this;
},
/**
* @param {?WebInspector.DOMNode} node
*/
_setNode: function(node)
{
this._node = node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function()
{
for (var layer = this; layer; layer = layer._parent) {
if (layer._node)
return layer._node;
}
return null;
},
/**
* @override
* @return {number}
*/
offsetX: function()
{
return this._layerPayload.offsetX;
},
/**
* @override
* @return {number}
*/
offsetY: function()
{
return this._layerPayload.offsetY;
},
/**
* @override
* @return {number}
*/
width: function()
{
return this._layerPayload.width;
},
/**
* @override
* @return {number}
*/
height: function()
{
return this._layerPayload.height;
},
/**
* @override
* @return {?Array.<number>}
*/
transform: function()
{
return this._layerPayload.transform;
},
/**
* @override
* @return {!Array.<number>}
*/
quad: function()
{
return this._quad;
},
/**
* @override
* @return {!Array.<number>}
*/
anchorPoint: function()
{
return [
this._layerPayload.anchorX || 0,
this._layerPayload.anchorY || 0,
this._layerPayload.anchorZ || 0,
];
},
/**
* @override
* @return {boolean}
*/
invisible: function()
{
return this._layerPayload.invisible;
},
/**
* @override
* @return {number}
*/
paintCount: function()
{
return this._paintCount || this._layerPayload.paintCount;
},
/**
* @override
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function()
{
return this._lastPaintRect;
},
/**
* @override
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function()
{
return this._scrollRects;
},
/**
* @override
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback)
{
if (!this._target) {
callback([]);
return;
}
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.reasonsForCompositingLayer(): ", undefined, []);
this._target.layerTreeAgent().compositingReasons(this.id(), wrappedCallback);
},
/**
* @override
* @return {boolean}
*/
drawsContent: function()
{
return this._layerPayload.drawsContent;
},
/**
* @override
* @return {number}
*/
gpuMemoryUsage: function()
{
/**
* @const
*/
var bytesPerPixel = 4;
return this.drawsContent() ? this.width() * this.height() * bytesPerPixel : 0;
},
/**
* @param {function(!WebInspector.PaintProfilerSnapshot=)} callback
*/
requestSnapshot: function(callback)
{
if (!this._target) {
callback();
return;
}
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.makeSnapshot(): ", WebInspector.PaintProfilerSnapshot.bind(null, this._target));
this._target.layerTreeAgent().makeSnapshot(this.id(), wrappedCallback);
},
/**
* @param {!DOMAgent.Rect} rect
*/
_didPaint: function(rect)
{
this._lastPaintRect = rect;
this._paintCount = this.paintCount() + 1;
this._image = null;
},
/**
* @param {!LayerTreeAgent.Layer} layerPayload
*/
_reset: function(layerPayload)
{
/** @type {?WebInspector.DOMNode} */
this._node = null;
this._children = [];
this._parent = null;
this._paintCount = 0;
this._layerPayload = layerPayload;
this._image = null;
this._scrollRects = this._layerPayload.scrollRects || [];
},
/**
* @param {!Array.<number>} a
* @return {!CSSMatrix}
*/
_matrixFromArray: function(a)
{
function toFixed9(x) { return x.toFixed(9); }
return new WebKitCSSMatrix("matrix3d(" + a.map(toFixed9).join(",") + ")");
},
/**
* @param {!CSSMatrix} parentTransform
* @return {!CSSMatrix}
*/
_calculateTransformToViewport: function(parentTransform)
{
var offsetMatrix = new WebKitCSSMatrix().translate(this._layerPayload.offsetX, this._layerPayload.offsetY);
var matrix = offsetMatrix;
if (this._layerPayload.transform) {
var transformMatrix = this._matrixFromArray(this._layerPayload.transform);
var anchorVector = new WebInspector.Geometry.Vector(this._layerPayload.width * this.anchorPoint()[0], this._layerPayload.height * this.anchorPoint()[1], this.anchorPoint()[2]);
var anchorPoint = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
var anchorMatrix = new WebKitCSSMatrix().translate(-anchorPoint.x, -anchorPoint.y, -anchorPoint.z);
matrix = anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
}
matrix = parentTransform.multiply(matrix);
return matrix;
},
/**
* @param {number} width
* @param {number} height
* @return {!Array.<number>}
*/
_createVertexArrayForRect: function(width, height)
{
return [0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0];
},
/**
* @param {!CSSMatrix} parentTransform
*/
_calculateQuad: function(parentTransform)
{
var matrix = this._calculateTransformToViewport(parentTransform);
this._quad = [];
var vertices = this._createVertexArrayForRect(this._layerPayload.width, this._layerPayload.height);
for (var i = 0; i < 4; ++i) {
var point = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
this._quad.push(point.x, point.y);
}
function calculateQuadForLayer(layer)
{
layer._calculateQuad(matrix);
}
this._children.forEach(calculateQuadForLayer);
}
}
/**
* @constructor
* @param {!WebInspector.TracingLayerPayload} payload
* @implements {WebInspector.Layer}
*/
WebInspector.TracingLayer = function(payload)
{
this._reset(payload);
}
WebInspector.TracingLayer.prototype = {
/**
* @param {!WebInspector.TracingLayerPayload} payload
*/
_reset: function(payload)
{
/** @type {?WebInspector.DOMNode} */
this._node = null;
this._layerId = String(payload.layer_id);
this._offsetX = payload.position[0];
this._offsetY = payload.position[1];
this._width = payload.bounds.width;
this._height = payload.bounds.height;
this._children = [];
this._parentLayerId = null;
this._parent = null;
this._quad = payload.layer_quad || [];
this._createScrollRects(payload);
this._compositingReasons = payload.compositing_reasons || [];
this._drawsContent = !!payload.draws_content;
this._gpuMemoryUsage = payload.gpu_memory_usage;
},
/**
* @override
* @return {string}
*/
id: function()
{
return this._layerId;
},
/**
* @override
* @return {?string}
*/
parentId: function()
{
return this._parentLayerId;
},
/**
* @override
* @return {?WebInspector.Layer}
*/
parent: function()
{
return this._parent;
},
/**
* @override
* @return {boolean}
*/
isRoot: function()
{
return !this.parentId();
},
/**
* @override
* @return {!Array.<!WebInspector.Layer>}
*/
children: function()
{
return this._children;
},
/**
* @override
* @param {!WebInspector.Layer} child
*/
addChild: function(child)
{
if (child._parent)
console.assert(false, "Child already has a parent");
this._children.push(child);
child._parent = this;
child._parentLayerId = this._layerId;
},
/**
* @param {?WebInspector.DOMNode} node
*/
_setNode: function(node)
{
this._node = node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function()
{
for (var layer = this; layer; layer = layer._parent) {
if (layer._node)
return layer._node;
}
return null;
},
/**
* @override
* @return {number}
*/
offsetX: function()
{
return this._offsetX;
},
/**
* @override
* @return {number}
*/
offsetY: function()
{
return this._offsetY;
},
/**
* @override
* @return {number}
*/
width: function()
{
return this._width;
},
/**
* @override
* @return {number}
*/
height: function()
{
return this._height;
},
/**
* @override
* @return {?Array.<number>}
*/
transform: function()
{
return null;
},
/**
* @override
* @return {!Array.<number>}
*/
quad: function()
{
return this._quad;
},
/**
* @override
* @return {!Array.<number>}
*/
anchorPoint: function()
{
return [0.5, 0.5, 0];
},
/**
* @override
* @return {boolean}
*/
invisible: function()
{
return false;
},
/**
* @override
* @return {number}
*/
paintCount: function()
{
return 0;
},
/**
* @override
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function()
{
return null;
},
/**
* @override
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function()
{
return this._scrollRects;
},
/**
* @override
* @return {number}
*/
gpuMemoryUsage: function()
{
return this._gpuMemoryUsage;
},
/**
* @param {!Array.<number>} params
* @param {string} type
* @return {!Object}
*/
_scrollRectsFromParams: function(params, type)
{
return {rect: {x: params[0], y: params[1], width: params[2], height: params[3]}, type: type};
},
/**
* @param {!WebInspector.TracingLayerPayload} payload
*/
_createScrollRects: function(payload)
{
this._scrollRects = [];
if (payload.non_fast_scrollable_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region, WebInspector.LayerTreeModel.ScrollRectType.NonFastScrollable.name));
if (payload.touch_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.TouchEventHandler.name));
if (payload.wheel_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.WheelEventHandler.name));
if (payload.scroll_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.RepaintsOnScroll.name));
},
/**
* @override
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback)
{
callback(this._compositingReasons);
},
/**
* @override
* @return {boolean}
*/
drawsContent: function()
{
return this._drawsContent;
}
}
/**
* @constructor
* @param {?WebInspector.Target} target
*/
WebInspector.DeferredLayerTree = function(target)
{
this._target = target;
}
WebInspector.DeferredLayerTree.prototype = {
/**
* @param {function(!WebInspector.LayerTreeBase)} callback
*/
resolve: function(callback) { },
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
}
};
/**
* @constructor
* @implements {LayerTreeAgent.Dispatcher}
* @param {!WebInspector.LayerTreeModel} layerTreeModel
*/
WebInspector.LayerTreeDispatcher = function(layerTreeModel)
{
this._layerTreeModel = layerTreeModel;
}
WebInspector.LayerTreeDispatcher.prototype = {
/**
* @override
* @param {!Array.<!LayerTreeAgent.Layer>=} layers
*/
layerTreeDidChange: function(layers)
{
this._layerTreeModel._layerTreeChanged(layers || null);
},
/**
* @override
* @param {!LayerTreeAgent.LayerId} layerId
* @param {!DOMAgent.Rect} clipRect
*/
layerPainted: function(layerId, clipRect)
{
this._layerTreeModel._layerPainted(layerId, clipRect);
}
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.LayerTreeModel}
*/
WebInspector.LayerTreeModel.fromTarget = function(target)
{
if (!target.isPage())
return null;
var model = /** @type {?WebInspector.LayerTreeModel} */ (target.model(WebInspector.LayerTreeModel));
if (!model)
model = new WebInspector.LayerTreeModel(target);
return model;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | 2 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.LayerViewHost} layerViewHost
* @extends {WebInspector.Object}
* @implements {WebInspector.LayerView}
*/
WebInspector.LayerTreeOutline = function(layerViewHost)
{
WebInspector.Object.call(this);
this._layerViewHost = layerViewHost;
this._layerViewHost.registerView(this);
this._treeOutline = new TreeOutlineInShadow();
this._treeOutline.element.classList.add("layer-tree");
this._treeOutline.element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
this._treeOutline.element.addEventListener("mouseout", this._onMouseMove.bind(this), false);
this._treeOutline.element.addEventListener("contextmenu", this._onContextMenu.bind(this), true);
this._lastHoveredNode = null;
this.element = this._treeOutline.element;
this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
}
WebInspector.LayerTreeOutline.prototype = {
focus: function()
{
this._treeOutline.focus();
},
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
selectObject: function(selection)
{
this.hoverObject(null);
var layer = selection && selection.layer();
var node = layer && layer[WebInspector.LayerTreeElement._symbol];
if (node)
node.revealAndSelect(true);
else if (this._treeOutline.selectedTreeElement)
this._treeOutline.selectedTreeElement.deselect();
},
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
hoverObject: function(selection)
{
var layer = selection && selection.layer();
var node = layer && layer[WebInspector.LayerTreeElement._symbol];
if (node === this._lastHoveredNode)
return;
if (this._lastHoveredNode)
this._lastHoveredNode.setHovered(false);
if (node)
node.setHovered(true);
this._lastHoveredNode = node;
},
/**
* @param {?WebInspector.LayerTreeBase} layerTree
* @override
*/
setLayerTree: function(layerTree)
{
this._layerTree = layerTree;
this._update();
},
_update: function()
{
var showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
var seenLayers = new Map();
var root = null;
if (this._layerTree) {
if (!showInternalLayers)
root = this._layerTree.contentRoot();
if (!root)
root = this._layerTree.root();
}
/**
* @param {!WebInspector.Layer} layer
* @this {WebInspector.LayerTreeOutline}
*/
function updateLayer(layer)
{
if (!layer.drawsContent() && !showInternalLayers)
return;
if (seenLayers.get(layer))
console.assert(false, "Duplicate layer: " + layer.id());
seenLayers.set(layer, true);
var node = layer[WebInspector.LayerTreeElement._symbol];
var parentLayer = layer.parent();
// Skip till nearest visible ancestor.
while (parentLayer && parentLayer !== root && !parentLayer.drawsContent() && !showInternalLayers)
parentLayer = parentLayer.parent();
var parent = layer === root ? this._treeOutline.rootElement() : parentLayer[WebInspector.LayerTreeElement._symbol];
if (!parent) {
console.assert(false, "Parent is not in the tree");
return;
}
if (!node) {
node = new WebInspector.LayerTreeElement(this, layer);
parent.appendChild(node);
// Expand all new non-content layers to expose content layers better.
if (!layer.drawsContent())
node.expand();
} else {
if (node.parent !== parent) {
var oldSelection = this._treeOutline.selectedTreeElement;
if (node.parent)
node.parent.removeChild(node);
parent.appendChild(node);
if (oldSelection !== this._treeOutline.selectedTreeElement)
oldSelection.select();
}
node._update();
}
}
if (root)
this._layerTree.forEachLayer(updateLayer.bind(this), root);
// Cleanup layers that don't exist anymore from tree.
var rootElement = this._treeOutline.rootElement();
for (var node = rootElement.firstChild(); node && !node.root;) {
if (seenLayers.get(node._layer)) {
node = node.traverseNextTreeElement(false);
} else {
var nextNode = node.nextSibling || node.parent;
node.parent.removeChild(node);
if (node === this._lastHoveredNode)
this._lastHoveredNode = null;
node = nextNode;
}
}
if (!this._treeOutline.selectedTreeElement) {
var elementToSelect = this._layerTree.contentRoot() || this._layerTree.root();
if (elementToSelect)
elementToSelect[WebInspector.LayerTreeElement._symbol].revealAndSelect(true);
}
},
/**
* @param {!Event} event
*/
_onMouseMove: function(event)
{
var node = this._treeOutline.treeElementFromEvent(event);
if (node === this._lastHoveredNode)
return;
this._layerViewHost.hoverObject(this._selectionForNode(node));
},
/**
* @param {!WebInspector.LayerTreeElement} node
*/
_selectedNodeChanged: function(node)
{
this._layerViewHost.selectObject(this._selectionForNode(node));
},
/**
* @param {!Event} event
*/
_onContextMenu: function(event)
{
var selection = this._selectionForNode(this._treeOutline.treeElementFromEvent(event));
var contextMenu = new WebInspector.ContextMenu(event);
this._layerViewHost.showContextMenu(contextMenu, selection);
},
/**
* @param {?TreeElement} node
* @return {?WebInspector.LayerView.Selection}
*/
_selectionForNode: function(node)
{
return node && node._layer ? new WebInspector.LayerView.LayerSelection(node._layer) : null;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {!WebInspector.LayerTreeOutline} tree
* @param {!WebInspector.Layer} layer
* @extends {TreeElement}
*/
WebInspector.LayerTreeElement = function(tree, layer)
{
TreeElement.call(this);
this._treeOutline = tree;
this._layer = layer;
this._layer[WebInspector.LayerTreeElement._symbol] = this;
this._update();
}
WebInspector.LayerTreeElement._symbol = Symbol("layer");
WebInspector.LayerTreeElement.prototype = {
_update: function()
{
var node = this._layer.nodeForSelfOrAncestor();
var title = createDocumentFragment();
title.createTextChild(node ? WebInspector.DOMPresentationUtils.simpleSelector(node) : "#" + this._layer.id());
var details = title.createChild("span", "dimmed");
details.textContent = WebInspector.UIString(" (%d × %d)", this._layer.width(), this._layer.height());
this.title = title;
},
/**
* @override
* @return {boolean}
*/
onselect: function()
{
this._treeOutline._selectedNodeChanged(this);
return false;
},
/**
* @param {boolean} hovered
*/
setHovered: function(hovered)
{
this.listItemElement.classList.toggle("hovered", hovered);
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | 2 | /* * Copyright 2015 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /** * @interface */ WebInspector.LayerView = function() { } WebInspector.LayerView.prototype = { /** * @param {?WebInspector.LayerView.Selection} selection */ hoverObject: function(selection) { }, /** * @param {?WebInspector.LayerView.Selection} selection */ selectObject: function(selection) { }, /** * @param {?WebInspector.LayerTreeBase} layerTree */ setLayerTree: function(layerTree) { } } /** * @constructor * @param {!WebInspector.LayerView.Selection.Type} type * @param {!WebInspector.Layer} layer */ WebInspector.LayerView.Selection = function(type, layer) { this._type = type; this._layer = layer; } /** * @enum {string} */ WebInspector.LayerView.Selection.Type = { Layer: "Layer", ScrollRect: "ScrollRect", Tile: "Tile", } /** * @param {?WebInspector.LayerView.Selection} a * @param {?WebInspector.LayerView.Selection} b * @return {boolean} */ WebInspector.LayerView.Selection.isEqual = function(a, b) { return a && b ? a._isEqual(b) : a === b; } WebInspector.LayerView.Selection.prototype = { /** * @return {!WebInspector.LayerView.Selection.Type} */ type: function() { return this._type; }, /** * @return {!WebInspector.Layer} */ layer: function() { return this._layer; }, /** * @param {!WebInspector.LayerView.Selection} other * @return {boolean} */ _isEqual: function(other) { return false; } } /** * @constructor * @extends {WebInspector.LayerView.Selection} * @param {!WebInspector.Layer} layer */ WebInspector.LayerView.LayerSelection = function(layer) { console.assert(layer, "LayerSelection with empty layer"); WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.Layer, layer); } WebInspector.LayerView.LayerSelection.prototype = { /** * @override * @param {!WebInspector.LayerView.Selection} other * @return {boolean} */ _isEqual: function(other) { return other._type === WebInspector.LayerView.Selection.Type.Layer && other.layer().id() === this.layer().id(); }, __proto__: WebInspector.LayerView.Selection.prototype } /** * @constructor * @extends {WebInspector.LayerView.Selection} * @param {!WebInspector.Layer} layer * @param {number} scrollRectIndex */ WebInspector.LayerView.ScrollRectSelection = function(layer, scrollRectIndex) { WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.ScrollRect, layer); this.scrollRectIndex = scrollRectIndex; } WebInspector.LayerView.ScrollRectSelection.prototype = { /** * @override * @param {!WebInspector.LayerView.Selection} other * @return {boolean} */ _isEqual: function(other) { return other._type === WebInspector.LayerView.Selection.Type.ScrollRect && this.layer().id() === other.layer().id() && this.scrollRectIndex === other.scrollRectIndex; }, __proto__: WebInspector.LayerView.Selection.prototype } /** * @constructor * @extends {WebInspector.LayerView.Selection} * @param {!WebInspector.Layer} layer * @param {!WebInspector.TracingModel.Event} traceEvent */ WebInspector.LayerView.TileSelection = function(layer, traceEvent) { WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.Tile, layer); this._traceEvent = traceEvent; } WebInspector.LayerView.TileSelection.prototype = { /** * @override * @param {!WebInspector.LayerView.Selection} other * @return {boolean} */ _isEqual: function(other) { return other._type === WebInspector.LayerView.Selection.Type.Tile && this.layer().id() === other.layer().id() && this.traceEvent === other.traceEvent; }, /** * @return {!WebInspector.TracingModel.Event} */ traceEvent: function() { return this._traceEvent; }, __proto__: WebInspector.LayerView.Selection.prototype } /** * @constructor */ WebInspector.LayerViewHost = function() { /** @type {!Array.<!WebInspector.LayerView>} */ this._views = []; this._selectedObject = null; this._hoveredObject = null; this._showInternalLayersSetting = WebInspector.settings.createSetting("layersShowInternalLayers", false); } WebInspector.LayerViewHost.prototype = { /** * @param {!WebInspector.LayerView} layerView */ registerView: function(layerView) { this._views.push(layerView); }, /** * @param {?WebInspector.LayerTreeBase} layerTree */ setLayerTree: function(layerTree) { this._target = layerTree.target(); var selectedLayer = this._selectedObject && this._selectedObject.layer(); if (selectedLayer && (!layerTree || !layerTree.layerById(selectedLayer.id()))) this.selectObject(null); var hoveredLayer = this._hoveredObject && this._hoveredObject.layer(); if (hoveredLayer && (!layerTree || !layerTree.layerById(hoveredLayer.id()))) this.hoverObject(null); for (var view of this._views) view.setLayerTree(layerTree); }, /** * @param {?WebInspector.LayerView.Selection} selection */ hoverObject: function(selection) { if (WebInspector.LayerView.Selection.isEqual(this._hoveredObject, selection)) return; this._hoveredObject = selection; var layer = selection && selection.layer(); this._toggleNodeHighlight(layer ? layer.nodeForSelfOrAncestor() : null); for (var view of this._views) view.hoverObject(selection); }, /** * @param {?WebInspector.LayerView.Selection} selection */ selectObject: function(selection) { if (WebInspector.LayerView.Selection.isEqual(this._selectedObject, selection)) return; this._selectedObject = selection; for (var view of this._views) view.selectObject(selection); }, /** * @return {?WebInspector.LayerView.Selection} */ selection: function() { return this._selectedObject; }, /** * @param {!WebInspector.ContextMenu} contextMenu * @param {?WebInspector.LayerView.Selection} selection */ showContextMenu: function(contextMenu, selection) { contextMenu.appendCheckboxItem(WebInspector.UIString("Show internal layers"), this._toggleShowInternalLayers.bind(this), this._showInternalLayersSetting.get()); var node = selection && selection.layer() && selection.layer().nodeForSelfOrAncestor(); if (node) contextMenu.appendApplicableItems(node); contextMenu.show(); }, /** * @return {!WebInspector.Setting} */ showInternalLayersSetting: function() { return this._showInternalLayersSetting; }, _toggleShowInternalLayers: function() { this._showInternalLayersSetting.set(!this._showInternalLayersSetting.get()); }, /** * @param {?WebInspector.DOMNode} node */ _toggleNodeHighlight: function(node) { if (node) { node.highlightForTwoSeconds(); return; } WebInspector.DOMModel.hideDOMNodeHighlight(); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | 2 1 1 1 1 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.LayerViewHost} layerViewHost
* @implements {WebInspector.LayerView}
*/
WebInspector.Layers3DView = function(layerViewHost)
{
WebInspector.VBox.call(this);
this.element.classList.add("layers-3d-view");
this._failBanner = new WebInspector.VBox();
this._failBanner.element.classList.add("banner");
this._failBanner.element.createTextChild(WebInspector.UIString("Layer information is not yet available."));
this._layerViewHost = layerViewHost;
this._layerViewHost.registerView(this);
this._transformController = new WebInspector.TransformController(this.element);
this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged, this._update, this);
this._initToolbar();
this._canvasElement = this.element.createChild("canvas");
this._canvasElement.tabIndex = 0;
this._canvasElement.addEventListener("dblclick", this._onDoubleClick.bind(this), false);
this._canvasElement.addEventListener("mousedown", this._onMouseDown.bind(this), false);
this._canvasElement.addEventListener("mouseup", this._onMouseUp.bind(this), false);
this._canvasElement.addEventListener("mouseleave", this._onMouseMove.bind(this), false);
this._canvasElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
this._canvasElement.addEventListener("contextmenu", this._onContextMenu.bind(this), false);
this._lastSelection = {};
this._layerTree = null;
this._textureManager = new WebInspector.LayerTextureManager();
this._textureManager.addEventListener(WebInspector.LayerTextureManager.Events.TextureUpdated, this._update, this);
/** @type Array.<!WebGLTexture|undefined> */
this._chromeTextures = [];
this._rects = [];
this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
}
/** @typedef {{borderColor: !Array.<number>, borderWidth: number}} */
WebInspector.Layers3DView.LayerStyle;
/** @typedef {{layerId: string, rect: !Array.<number>, snapshot: !WebInspector.PaintProfilerSnapshot, traceEvent: !WebInspector.TracingModel.Event}} */
WebInspector.Layers3DView.PaintTile;
/**
* @enum {string}
*/
WebInspector.Layers3DView.OutlineType = {
Hovered: "hovered",
Selected: "selected"
}
/**
* @enum {string}
*/
WebInspector.Layers3DView.Events = {
LayerSnapshotRequested: "LayerSnapshotRequested",
PaintProfilerRequested: "PaintProfilerRequested",
}
/**
* @enum {number}
*/
WebInspector.Layers3DView.ChromeTexture = {
Left: 0,
Middle: 1,
Right: 2
}
/**
* @enum {string}
*/
WebInspector.Layers3DView.ScrollRectTitles = {
RepaintsOnScroll: WebInspector.UIString("repaints on scroll"),
TouchEventHandler: WebInspector.UIString("touch event listener"),
WheelEventHandler: WebInspector.UIString("mousewheel event listener")
}
WebInspector.Layers3DView.FragmentShader = "" +
"precision mediump float;\n" +
"varying vec4 vColor;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D uSampler;\n" +
"void main(void)\n" +
"{\n" +
" gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n" +
"}";
WebInspector.Layers3DView.VertexShader = "" +
"attribute vec3 aVertexPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"attribute vec4 aVertexColor;\n" +
"uniform mat4 uPMatrix;\n" +
"varying vec2 vTextureCoord;\n" +
"varying vec4 vColor;\n" +
"void main(void)\n" +
"{\n" +
"gl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\n" +
"vColor = aVertexColor;\n" +
"vTextureCoord = aTextureCoord;\n" +
"}";
WebInspector.Layers3DView.HoveredBorderColor = [0, 0, 255, 1];
WebInspector.Layers3DView.SelectedBorderColor = [0, 255, 0, 1];
WebInspector.Layers3DView.BorderColor = [0, 0, 0, 1];
WebInspector.Layers3DView.ViewportBorderColor = [160, 160, 160, 1];
WebInspector.Layers3DView.ScrollRectBackgroundColor = [178, 100, 100, 0.6];
WebInspector.Layers3DView.HoveredImageMaskColor = [200, 200, 255, 1];
WebInspector.Layers3DView.BorderWidth = 1;
WebInspector.Layers3DView.SelectedBorderWidth = 2;
WebInspector.Layers3DView.ViewportBorderWidth = 3;
WebInspector.Layers3DView.LayerSpacing = 20;
WebInspector.Layers3DView.ScrollRectSpacing = 4;
WebInspector.Layers3DView.prototype = {
/**
* @param {?WebInspector.LayerTreeBase} layerTree
* @override
*/
setLayerTree: function(layerTree)
{
this._layerTree = layerTree;
this._textureManager.reset();
this._update();
},
/**
* @param {?Array.<!WebInspector.Layers3DView.PaintTile>} tiles
*/
setTiles: function(tiles)
{
this._textureManager.setTiles(tiles);
},
/**
* @param {!WebInspector.Layer} layer
* @param {string=} imageURL
*/
showImageForLayer: function(layer, imageURL)
{
if (imageURL)
this._textureManager.createTexture(onTextureCreated.bind(this), imageURL);
else
onTextureCreated.call(this, null);
/**
* @this {WebInspector.Layers3DView}
* @param {?WebGLTexture} texture
*/
function onTextureCreated(texture)
{
this._layerTexture = texture ? {layerId: layer.id(), texture: texture} : null;
this._update();
}
},
onResize: function()
{
this._resizeCanvas();
this._update();
},
wasShown: function()
{
if (!this._needsUpdate)
return;
this._resizeCanvas();
this._update();
},
/**
* @param {!WebInspector.Layers3DView.OutlineType} type
* @param {?WebInspector.LayerView.Selection} selection
*/
_setOutline: function(type, selection)
{
this._lastSelection[type] = selection;
this._update();
},
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
hoverObject: function(selection)
{
this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, selection);
},
/**
* @param {?WebInspector.LayerView.Selection} selection
* @override
*/
selectObject: function(selection)
{
this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, selection);
},
/**
* @param {!Element} canvas
* @return {?WebGLRenderingContext}
*/
_initGL: function(canvas)
{
var gl = canvas.getContext("webgl");
if (!gl)
return null;
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.enable(gl.DEPTH_TEST);
return gl;
},
/**
* @param {!Object} type
* @param {string} script
*/
_createShader: function(type, script)
{
var shader = this._gl.createShader(type);
this._gl.shaderSource(shader, script);
this._gl.compileShader(shader);
this._gl.attachShader(this._shaderProgram, shader);
},
_initShaders: function()
{
this._shaderProgram = this._gl.createProgram();
this._createShader(this._gl.FRAGMENT_SHADER, WebInspector.Layers3DView.FragmentShader);
this._createShader(this._gl.VERTEX_SHADER, WebInspector.Layers3DView.VertexShader);
this._gl.linkProgram(this._shaderProgram);
this._gl.useProgram(this._shaderProgram);
this._shaderProgram.vertexPositionAttribute = this._gl.getAttribLocation(this._shaderProgram, "aVertexPosition");
this._gl.enableVertexAttribArray(this._shaderProgram.vertexPositionAttribute);
this._shaderProgram.vertexColorAttribute = this._gl.getAttribLocation(this._shaderProgram, "aVertexColor");
this._gl.enableVertexAttribArray(this._shaderProgram.vertexColorAttribute);
this._shaderProgram.textureCoordAttribute = this._gl.getAttribLocation(this._shaderProgram, "aTextureCoord");
this._gl.enableVertexAttribArray(this._shaderProgram.textureCoordAttribute);
this._shaderProgram.pMatrixUniform = this._gl.getUniformLocation(this._shaderProgram, "uPMatrix");
this._shaderProgram.samplerUniform = this._gl.getUniformLocation(this._shaderProgram, "uSampler");
},
_resizeCanvas: function()
{
this._canvasElement.width = this._canvasElement.offsetWidth * window.devicePixelRatio;
this._canvasElement.height = this._canvasElement.offsetHeight * window.devicePixelRatio;
},
_updateTransformAndConstraints: function()
{
var paddingFraction = 0.1;
var viewport = this._layerTree.viewportSize();
var root = this._layerTree.root();
var baseWidth = viewport ? viewport.width : this._dimensionsForAutoscale.width;
var baseHeight = viewport ? viewport.height : this._dimensionsForAutoscale.height;
var canvasWidth = this._canvasElement.width;
var canvasHeight = this._canvasElement.height;
var paddingX = canvasWidth * paddingFraction;
var paddingY = canvasHeight * paddingFraction;
var scaleX = (canvasWidth - 2 * paddingX) / baseWidth;
var scaleY = (canvasHeight - 2 * paddingY) / baseHeight;
var viewScale = Math.min(scaleX, scaleY);
var minScaleConstraint = Math.min(baseWidth / this._dimensionsForAutoscale.width, baseHeight / this._dimensionsForAutoscale.width) / 2;
this._transformController.setScaleConstraints(minScaleConstraint, 10 / viewScale); // 1/viewScale is 1:1 in terms of pixels, so allow zooming to 10x of native size
var scale = this._transformController.scale();
var rotateX = this._transformController.rotateX();
var rotateY = this._transformController.rotateY();
this._scale = scale * viewScale;
var scaleAndRotationMatrix = new WebKitCSSMatrix().scale(scale, scale, scale).translate(canvasWidth / 2, canvasHeight / 2, 0)
.rotate(rotateX, rotateY, 0).scale(viewScale, viewScale, viewScale).translate(-baseWidth / 2, -baseHeight / 2, 0);
var bounds;
for (var i = 0; i < this._rects.length; ++i)
bounds = WebInspector.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix, this._rects[i].vertices, bounds);
this._transformController.clampOffsets((paddingX - bounds.maxX) / window.devicePixelRatio, (canvasWidth - paddingX - bounds.minX) / window.devicePixelRatio,
(paddingY - bounds.maxY) / window.devicePixelRatio, (canvasHeight - paddingY - bounds.minY) / window.devicePixelRatio);
var offsetX = this._transformController.offsetX() * window.devicePixelRatio;
var offsetY = this._transformController.offsetY() * window.devicePixelRatio;
// Multiply to translation matrix on the right rather than translate (which would implicitly multiply on the left).
this._projectionMatrix = new WebKitCSSMatrix().translate(offsetX, offsetY, 0).multiply(scaleAndRotationMatrix);
var glProjectionMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0)
.scale(2 / this._canvasElement.width, 2 / this._canvasElement.height, 1 / 1000000).multiply(this._projectionMatrix);
this._gl.uniformMatrix4fv(this._shaderProgram.pMatrixUniform, false, this._arrayFromMatrix(glProjectionMatrix));
},
/**
* @param {!CSSMatrix} m
* @return {!Float32Array}
*/
_arrayFromMatrix: function(m)
{
return new Float32Array([m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44]);
},
_initWhiteTexture: function()
{
this._whiteTexture = this._gl.createTexture();
this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
var whitePixel = new Uint8Array([255, 255, 255, 255]);
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, 1, 1, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, whitePixel);
},
_initChromeTextures: function()
{
/**
* @this {WebInspector.Layers3DView}
* @param {!WebInspector.Layers3DView.ChromeTexture} index
* @param {?WebGLTexture} value
*/
function saveChromeTexture(index, value)
{
this._chromeTextures[index] = value || undefined;
}
this._textureManager.createTexture(saveChromeTexture.bind(this, WebInspector.Layers3DView.ChromeTexture.Left), "Images/chromeLeft.png");
this._textureManager.createTexture(saveChromeTexture.bind(this, WebInspector.Layers3DView.ChromeTexture.Middle), "Images/chromeMiddle.png");
this._textureManager.createTexture(saveChromeTexture.bind(this, WebInspector.Layers3DView.ChromeTexture.Right), "Images/chromeRight.png");
},
/**
* @return {?WebGLRenderingContext}
*/
_initGLIfNecessary: function()
{
if (this._gl)
return this._gl;
this._gl = this._initGL(this._canvasElement);
if (!this._gl)
return null;
this._initShaders();
this._initWhiteTexture();
this._initChromeTextures();
this._textureManager.setContext(this._gl);
return this._gl;
},
_calculateDepthsAndVisibility: function()
{
this._depthByLayerId = {};
var depth = 0;
var showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
var root = showInternalLayers ? this._layerTree.root() : (this._layerTree.contentRoot() || this._layerTree.root());
var queue = [root];
this._depthByLayerId[root.id()] = 0;
this._visibleLayers = {};
while (queue.length > 0) {
var layer = queue.shift();
this._visibleLayers[layer.id()] = showInternalLayers || layer.drawsContent();
var children = layer.children();
for (var i = 0; i < children.length; ++i) {
this._depthByLayerId[children[i].id()] = ++depth;
queue.push(children[i]);
}
}
this._maxDepth = depth;
},
/**
* @param {!WebInspector.Layer} layer
* @return {number}
*/
_depthForLayer: function(layer)
{
return this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing;
},
/**
* @param {!WebInspector.Layer} layer
* @param {number} index
* @return {number}
*/
_calculateScrollRectDepth: function(layer, index)
{
return this._depthForLayer(layer) + index * WebInspector.Layers3DView.ScrollRectSpacing + 1;
},
/**
* @param {!WebInspector.Layer} layer
*/
_updateDimensionsForAutoscale: function(layer)
{
// We don't want to be precise, but rather pick something least affected by
// animationtransforms, so that we don't change scale too often. So let's
// disregard transforms, scrolling and relative layer positioning and choose
// the largest dimensions of all layers.
this._dimensionsForAutoscale.width = Math.max(layer.width(), this._dimensionsForAutoscale.width);
this._dimensionsForAutoscale.height = Math.max(layer.height(), this._dimensionsForAutoscale.height);
},
/**
* @param {!WebInspector.Layer} layer
*/
_calculateLayerRect: function(layer)
{
if (!this._visibleLayers[layer.id()])
return;
var selection = new WebInspector.LayerView.LayerSelection(layer);
var rect = new WebInspector.Layers3DView.Rectangle(selection);
rect.setVertices(layer.quad(), this._depthForLayer(layer));
this._appendRect(rect);
this._updateDimensionsForAutoscale(layer);
},
/**
* @param {!WebInspector.Layers3DView.Rectangle} rect
*/
_appendRect: function(rect)
{
var selection = rect.relatedObject;
var isSelected = WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Selected], selection);
var isHovered = WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Hovered], selection);
if (isSelected) {
rect.borderColor = WebInspector.Layers3DView.SelectedBorderColor;
} else if (isHovered) {
rect.borderColor = WebInspector.Layers3DView.HoveredBorderColor;
var fillColor = rect.fillColor || [255, 255, 255, 1];
var maskColor = WebInspector.Layers3DView.HoveredImageMaskColor;
rect.fillColor = [fillColor[0] * maskColor[0] / 255, fillColor[1] * maskColor[1] / 255, fillColor[2] * maskColor[2] / 255, fillColor[3] * maskColor[3]];
} else {
rect.borderColor = WebInspector.Layers3DView.BorderColor;
}
rect.lineWidth = isSelected ? WebInspector.Layers3DView.SelectedBorderWidth : WebInspector.Layers3DView.BorderWidth;
this._rects.push(rect);
},
/**
* @param {!WebInspector.Layer} layer
*/
_calculateLayerScrollRects: function(layer)
{
var scrollRects = layer.scrollRects();
for (var i = 0; i < scrollRects.length; ++i) {
var selection = new WebInspector.LayerView.ScrollRectSelection(layer, i);
var rect = new WebInspector.Layers3DView.Rectangle(selection);
rect.calculateVerticesFromRect(layer, scrollRects[i].rect, this._calculateScrollRectDepth(layer, i));
rect.fillColor = WebInspector.Layers3DView.ScrollRectBackgroundColor;
this._appendRect(rect);
}
},
/**
* @param {!WebInspector.Layer} layer
*/
_calculateLayerImageRect: function(layer)
{
var layerTexture = this._layerTexture;
if (layer.id() !== layerTexture.layerId)
return;
var selection = new WebInspector.LayerView.LayerSelection(layer);
var rect = new WebInspector.Layers3DView.Rectangle(selection);
rect.setVertices(layer.quad(), this._depthForLayer(layer));
rect.texture = layerTexture.texture;
this._appendRect(rect);
},
/**
* @param {!WebInspector.Layer} layer
*/
_calculateLayerTileRects: function(layer)
{
var tiles = this._textureManager.tilesForLayer(layer.id());
for (var i = 0; i < tiles.length; ++i) {
var tile = tiles[i];
if (!tile.texture)
continue;
var selection = new WebInspector.LayerView.TileSelection(layer, tile.traceEvent);
var rect = new WebInspector.Layers3DView.Rectangle(selection);
rect.calculateVerticesFromRect(layer, {x: tile.rect[0], y: tile.rect[1], width: tile.rect[2], height: tile.rect[3]}, this._depthForLayer(layer) + 1);
rect.texture = tile.texture;
this._appendRect(rect);
}
},
_calculateRects: function()
{
this._rects = [];
this._dimensionsForAutoscale = { width: 0, height: 0 };
this._layerTree.forEachLayer(this._calculateLayerRect.bind(this));
if (this._showSlowScrollRectsSetting.get())
this._layerTree.forEachLayer(this._calculateLayerScrollRects.bind(this));
if (this._showPaintsSetting.get()) {
if (this._layerTexture)
this._layerTree.forEachLayer(this._calculateLayerImageRect.bind(this));
else
this._layerTree.forEachLayer(this._calculateLayerTileRects.bind(this));
}
},
/**
* @param {!Array.<number>} color
* @return {!Array.<number>}
*/
_makeColorsArray: function(color)
{
var colors = [];
var normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
for (var i = 0; i < 4; i++)
colors = colors.concat(normalizedColor);
return colors;
},
/**
* @param {!Object} attribute
* @param {!Array.<number>} array
* @param {number} length
*/
_setVertexAttribute: function(attribute, array, length)
{
var gl = this._gl;
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);
gl.vertexAttribPointer(attribute, length, gl.FLOAT, false, 0, 0);
},
/**
* @param {!Array.<number>} vertices
* @param {number} mode
* @param {!Array.<number>=} color
* @param {!Object=} texture
*/
_drawRectangle: function(vertices, mode, color, texture)
{
var gl = this._gl;
var white = [255, 255, 255, 1];
color = color || white;
this._setVertexAttribute(this._shaderProgram.vertexPositionAttribute, vertices, 3);
this._setVertexAttribute(this._shaderProgram.textureCoordAttribute, [0, 1, 1, 1, 1, 0, 0, 0], 2);
this._setVertexAttribute(this._shaderProgram.vertexColorAttribute, this._makeColorsArray(color), color.length);
if (texture) {
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(this._shaderProgram.samplerUniform, 0);
} else {
gl.bindTexture(gl.TEXTURE_2D, this._whiteTexture);
}
var numberOfVertices = vertices.length / 3;
gl.drawArrays(mode, 0, numberOfVertices);
},
/**
* @param {!Array.<number>} vertices
* @param {!WebGLTexture} texture
* @param {!Array.<number>=} color
*/
_drawTexture: function(vertices, texture, color)
{
this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, color, texture);
},
_drawViewportAndChrome: function()
{
var viewport = this._layerTree.viewportSize();
if (!viewport)
return;
var drawChrome = !WebInspector.moduleSetting("frameViewerHideChromeWindow").get() && this._chromeTextures.length >= 3 && this._chromeTextures.indexOf(undefined) < 0;
var z = (this._maxDepth + 1) * WebInspector.Layers3DView.LayerSpacing;
var borderWidth = Math.ceil(WebInspector.Layers3DView.ViewportBorderWidth * this._scale);
var vertices = [viewport.width, 0, z, viewport.width, viewport.height, z, 0, viewport.height, z, 0, 0, z];
this._gl.lineWidth(borderWidth);
this._drawRectangle(vertices, drawChrome ? this._gl.LINE_STRIP : this._gl.LINE_LOOP, WebInspector.Layers3DView.ViewportBorderColor);
if (!drawChrome)
return;
var borderAdjustment = WebInspector.Layers3DView.ViewportBorderWidth / 2;
var viewportWidth = this._layerTree.viewportSize().width + 2 * borderAdjustment;
var chromeHeight = this._chromeTextures[0].image.naturalHeight;
var middleFragmentWidth = viewportWidth - this._chromeTextures[0].image.naturalWidth - this._chromeTextures[2].image.naturalWidth;
var x = -borderAdjustment;
var y = -chromeHeight;
for (var i = 0; i < this._chromeTextures.length; ++i) {
var width = i === WebInspector.Layers3DView.ChromeTexture.Middle ? middleFragmentWidth : this._chromeTextures[i].image.naturalWidth;
if (width < 0 || x + width > viewportWidth)
break;
vertices = [x, y, z, x + width, y, z, x + width, y + chromeHeight, z, x, y + chromeHeight, z];
this._drawTexture(vertices, /** @type {!WebGLTexture} */ (this._chromeTextures[i]));
x += width;
}
},
/**
* @param {!WebInspector.Layers3DView.Rectangle} rect
*/
_drawViewRect: function(rect)
{
var vertices = rect.vertices;
if (rect.texture)
this._drawTexture(vertices, rect.texture, rect.fillColor || undefined);
else if (rect.fillColor)
this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, rect.fillColor);
this._gl.lineWidth(rect.lineWidth);
if (rect.borderColor)
this._drawRectangle(vertices, this._gl.LINE_LOOP, rect.borderColor);
},
_update: function()
{
if (!this.isShowing()) {
this._needsUpdate = true;
return;
}
if (!this._layerTree || !this._layerTree.root()) {
this._failBanner.show(this.element);
return;
}
var gl = this._initGLIfNecessary();
if (!gl) {
this._failBanner.element.removeChildren();
this._failBanner.element.appendChild(this._webglDisabledBanner());
this._failBanner.show(this.element);
return;
}
this._failBanner.detach();
this._gl.viewportWidth = this._canvasElement.width;
this._gl.viewportHeight = this._canvasElement.height;
this._calculateDepthsAndVisibility();
this._calculateRects();
this._updateTransformAndConstraints();
this._textureManager.setScale(Number.constrain(0.1, 1, this._scale));
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
this._rects.forEach(this._drawViewRect.bind(this));
this._drawViewportAndChrome();
},
/**
* @return {!Node}
*/
_webglDisabledBanner: function()
{
var fragment = this.element.ownerDocument.createDocumentFragment();
fragment.createChild("div").textContent = WebInspector.UIString("Can't display layers,");
fragment.createChild("div").textContent = WebInspector.UIString("WebGL support is disabled in your browser.");
fragment.appendChild(WebInspector.formatLocalized("Check %s for possible reasons.", [WebInspector.linkifyURLAsNode("about:gpu", undefined, undefined, true)]));
return fragment;
},
/**
* @param {!Event} event
* @return {?WebInspector.LayerView.Selection}
*/
_selectionFromEventPoint: function(event)
{
if (!this._layerTree)
return null;
var closestIntersectionPoint = Infinity;
var closestObject = null;
var projectionMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._projectionMatrix);
var x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
var y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;
/**
* @param {!WebInspector.Layers3DView.Rectangle} rect
*/
function checkIntersection(rect)
{
if (!rect.relatedObject)
return;
var t = rect.intersectWithLine(projectionMatrix, x0, y0);
if (t < closestIntersectionPoint) {
closestIntersectionPoint = t;
closestObject = rect.relatedObject;
}
}
this._rects.forEach(checkIntersection);
return closestObject;
},
/**
* @param {string} caption
* @param {string} name
* @param {boolean} value
* @param {!WebInspector.Toolbar} toolbar
* @return {!WebInspector.Setting}
*/
_createVisibilitySetting: function(caption, name, value, toolbar)
{
var checkbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString(caption));
toolbar.appendToolbarItem(checkbox);
var setting = WebInspector.settings.createSetting(name, value);
WebInspector.SettingsUI.bindCheckbox(checkbox.inputElement, setting);
setting.addChangeListener(this._update, this);
return setting;
},
_initToolbar: function()
{
this._panelToolbar = this._transformController.toolbar();
this.element.appendChild(this._panelToolbar.element);
this._showSlowScrollRectsSetting = this._createVisibilitySetting("Slow scroll rects", "frameViewerShowSlowScrollRects", true, this._panelToolbar);
this._showPaintsSetting = this._createVisibilitySetting("Paints", "frameViewerShowPaints", true, this._panelToolbar);
WebInspector.moduleSetting("frameViewerHideChromeWindow").addChangeListener(this._update, this);
},
/**
* @param {!Event} event
*/
_onContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Reset View"), this._transformController.resetAndNotify.bind(this._transformController), false);
var selection = this._selectionFromEventPoint(event);
if (selection && selection.type() === WebInspector.LayerView.Selection.Type.Tile)
contextMenu.appendItem(WebInspector.UIString("Show Paint Profiler"), this.dispatchEventToListeners.bind(this, WebInspector.Layers3DView.Events.PaintProfilerRequested, selection.traceEvent()), false);
this._layerViewHost.showContextMenu(contextMenu, selection);
},
/**
* @param {!Event} event
*/
_onMouseMove: function(event)
{
if (event.which)
return;
this._layerViewHost.hoverObject(this._selectionFromEventPoint(event));
},
/**
* @param {!Event} event
*/
_onMouseDown: function(event)
{
this._mouseDownX = event.clientX;
this._mouseDownY = event.clientY;
},
/**
* @param {!Event} event
*/
_onMouseUp: function(event)
{
const maxDistanceInPixels = 6;
if (this._mouseDownX && Math.abs(event.clientX - this._mouseDownX) < maxDistanceInPixels && Math.abs(event.clientY - this._mouseDownY) < maxDistanceInPixels)
this._layerViewHost.selectObject(this._selectionFromEventPoint(event));
delete this._mouseDownX;
delete this._mouseDownY;
},
/**
* @param {!Event} event
*/
_onDoubleClick: function(event)
{
var selection = this._selectionFromEventPoint(event);
if (selection) {
if (selection.type() == WebInspector.LayerView.Selection.Type.Tile)
this.dispatchEventToListeners(WebInspector.Layers3DView.Events.PaintProfilerRequested, selection.traceEvent());
else if (selection.layer())
this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSnapshotRequested, selection.layer());
}
event.stopPropagation();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.LayerTextureManager = function()
{
WebInspector.Object.call(this);
this.reset();
}
WebInspector.LayerTextureManager.Events = {
TextureUpdated: "TextureUpated"
}
WebInspector.LayerTextureManager.prototype = {
reset: function()
{
/** @type {!Object.<string, !Array.<!WebInspector.LayerTextureManager.Tile>>} */
this._tilesByLayerId = {};
this._scale = 0;
},
/**
* @param {!WebGLRenderingContext} glContext
*/
setContext: function(glContext)
{
this._gl = glContext;
if (this._scale)
this._updateTextures();
},
/**
* @param {?Array.<!WebInspector.Layers3DView.PaintTile>} paintTiles
*/
setTiles: function(paintTiles)
{
this._tilesByLayerId = {};
if (!paintTiles)
return;
for (var i = 0; i < paintTiles.length; ++i) {
var layerId = paintTiles[i].layerId;
var tilesForLayer = this._tilesByLayerId[layerId];
if (!tilesForLayer) {
tilesForLayer = [];
this._tilesByLayerId[layerId] = tilesForLayer;
}
var tile = new WebInspector.LayerTextureManager.Tile(paintTiles[i].snapshot, paintTiles[i].rect, paintTiles[i].traceEvent);
tilesForLayer.push(tile);
if (this._scale && this._gl)
this._updateTile(tile);
}
},
/**
* @param {number} scale
*/
setScale: function(scale)
{
if (this._scale && this._scale >= scale)
return;
this._scale = scale;
this._updateTextures();
},
/**
* @param {string} layerId
* @return {!Array.<!WebInspector.LayerTextureManager.Tile>}
*/
tilesForLayer: function(layerId)
{
return this._tilesByLayerId[layerId] || [];
},
_updateTextures: function()
{
if (!this._gl)
return;
if (!this._scale)
return;
for (var layerId in this._tilesByLayerId) {
for (var i = 0; i < this._tilesByLayerId[layerId].length; ++i) {
var tile = this._tilesByLayerId[layerId][i];
if (!tile.scale || tile.scale < this._scale)
this._updateTile(tile);
}
}
},
/**
* @param {!WebInspector.LayerTextureManager.Tile} tile
*/
_updateTile: function(tile)
{
console.assert(this._scale && this._gl);
tile.scale = this._scale;
tile.snapshot.requestImage(null, null, tile.scale, onGotImage.bind(this));
/**
* @this {WebInspector.LayerTextureManager}
* @param {string=} imageURL
*/
function onGotImage(imageURL)
{
if (imageURL)
this.createTexture(onTextureCreated.bind(this), imageURL);
}
/**
* @this {WebInspector.LayerTextureManager}
* @param {?WebGLTexture} texture
*/
function onTextureCreated(texture)
{
tile.texture = texture;
this.dispatchEventToListeners(WebInspector.LayerTextureManager.Events.TextureUpdated);
}
},
/**
* @param {function(?WebGLTexture)} textureCreatedCallback
* @param {string} imageURL
*/
createTexture: function(textureCreatedCallback, imageURL)
{
var image = new Image();
image.addEventListener("load", onImageLoaded.bind(this), false);
image.addEventListener("error", onImageError, false);
image.src = imageURL;
/**
* @this {WebInspector.LayerTextureManager}
*/
function onImageLoaded()
{
textureCreatedCallback(this._createTextureForImage(image));
}
function onImageError()
{
textureCreatedCallback(null);
}
},
/**
* @param {!Image} image
* @return {!WebGLTexture} texture
*/
_createTextureForImage: function(image)
{
var texture = this._gl.createTexture();
texture.image = image;
this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, true);
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture.image);
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
return texture;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {?WebInspector.LayerView.Selection} relatedObject
*/
WebInspector.Layers3DView.Rectangle = function(relatedObject)
{
this.relatedObject = relatedObject;
/** @type {number} */
this.lineWidth = 1;
/** @type {?Array.<number>} */
this.borderColor = null;
/** @type {?Array.<number>} */
this.fillColor = null;
/** @type {?WebGLTexture} */
this.texture = null;
}
WebInspector.Layers3DView.Rectangle.prototype = {
/**
* @param {!Array.<number>} quad
* @param {number} z
*/
setVertices: function(quad, z)
{
this.vertices = [quad[0], quad[1], z, quad[2], quad[3], z, quad[4], quad[5], z, quad[6], quad[7], z];
},
/**
* Finds coordinates of point on layer quad, having offsets (ratioX * width) and (ratioY * height)
* from the left corner of the initial layer rect, where width and heigth are layer bounds.
* @param {!Array.<number>} quad
* @param {number} ratioX
* @param {number} ratioY
* @return {!Array.<number>}
*/
_calculatePointOnQuad: function(quad, ratioX, ratioY)
{
var x0 = quad[0];
var y0 = quad[1];
var x1 = quad[2];
var y1 = quad[3];
var x2 = quad[4];
var y2 = quad[5];
var x3 = quad[6];
var y3 = quad[7];
// Point on the first quad side clockwise
var firstSidePointX = x0 + ratioX * (x1 - x0);
var firstSidePointY = y0 + ratioX * (y1 - y0);
// Point on the third quad side clockwise
var thirdSidePointX = x3 + ratioX * (x2 - x3);
var thirdSidePointY = y3 + ratioX * (y2 - y3);
var x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
var y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
return [x, y];
},
/**
* @param {!WebInspector.Layer} layer
* @param {!DOMAgent.Rect} rect
* @param {number} z
*/
calculateVerticesFromRect: function(layer, rect, z)
{
var quad = layer.quad();
var rx1 = rect.x / layer.width();
var rx2 = (rect.x + rect.width) / layer.width();
var ry1 = rect.y / layer.height();
var ry2 = (rect.y + rect.height) / layer.height();
var rectQuad = this._calculatePointOnQuad(quad, rx1, ry1).concat(this._calculatePointOnQuad(quad, rx2, ry1))
.concat(this._calculatePointOnQuad(quad, rx2, ry2)).concat(this._calculatePointOnQuad(quad, rx1, ry2));
this.setVertices(rectQuad, z);
},
/**
* Intersects quad with given transform matrix and line l(t) = (x0, y0, t)
* @param {!CSSMatrix} matrix
* @param {number} x0
* @param {number} y0
* @return {(number|undefined)}
*/
intersectWithLine: function(matrix, x0, y0)
{
var i;
// Vertices of the quad with transform matrix applied
var points = [];
for (i = 0; i < 4; ++i)
points[i] = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
// Calculating quad plane normal
var normal = WebInspector.Geometry.crossProduct(WebInspector.Geometry.subtract(points[1], points[0]), WebInspector.Geometry.subtract(points[2], points[1]));
// General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
var A = normal.x;
var B = normal.y;
var C = normal.z;
var D = -(A * points[0].x + B * points[0].y + C * points[0].z);
// Finding t from the equation
var t = -(D + A * x0 + B * y0) / C;
// Point of the intersection
var pt = new WebInspector.Geometry.Vector(x0, y0, t);
// Vectors from the intersection point to vertices of the quad
var tVects = points.map(WebInspector.Geometry.subtract.bind(null, pt));
// Intersection point lies inside of the polygon if scalar products of normal of the plane and
// cross products of successive tVects are all nonstrictly above or all nonstrictly below zero
for (i = 0; i < tVects.length; ++i) {
var product = WebInspector.Geometry.scalarProduct(normal, WebInspector.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
if (product < 0)
return undefined;
}
return t;
}
}
/**
* @constructor
* @param {!WebInspector.PaintProfilerSnapshot} snapshot
* @param {!Array.<number>} rect
* @param {!WebInspector.TracingModel.Event} traceEvent
*/
WebInspector.LayerTextureManager.Tile = function(snapshot, rect, traceEvent)
{
this.snapshot = snapshot;
this.rect = rect;
this.traceEvent = traceEvent;
this.scale = 0;
/** @type {?WebGLTexture} */
this.texture = null;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.CountersGraph}
* @implements {WebInspector.TimelineModeView}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} model
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
*/
WebInspector.MemoryCountersGraph = function(delegate, model, filters)
{
WebInspector.CountersGraph.call(this, delegate, model, filters);
this._countersByName = {};
this._countersByName["jsHeapSizeUsed"] = this.createCounter(WebInspector.UIString("JS Heap"), WebInspector.UIString("JS Heap: %s"), "hsl(220, 90%, 43%)", Number.bytesToString);
this._countersByName["documents"] = this.createCounter(WebInspector.UIString("Documents"), WebInspector.UIString("Documents: %s"), "hsl(0, 90%, 43%)");
this._countersByName["nodes"] = this.createCounter(WebInspector.UIString("Nodes"), WebInspector.UIString("Nodes: %s"), "hsl(120, 90%, 43%)");
this._countersByName["jsEventListeners"] = this.createCounter(WebInspector.UIString("Listeners"), WebInspector.UIString("Listeners: %s"), "hsl(38, 90%, 43%)");
this._gpuMemoryCounter = this.createCounter(WebInspector.UIString("GPU Memory"), WebInspector.UIString("GPU Memory [KB]: %s"), "hsl(300, 90%, 43%)", Number.bytesToString);
this._countersByName["gpuMemoryUsedKB"] = this._gpuMemoryCounter;
}
WebInspector.MemoryCountersGraph.prototype = {
/**
* @override
*/
refreshRecords: function()
{
this.reset();
var events = this._model.mainThreadEvents();
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (event.name !== WebInspector.TimelineModel.RecordType.UpdateCounters)
continue;
var counters = event.args.data;
if (!counters)
return;
for (var name in counters) {
var counter = this._countersByName[name];
if (counter)
counter.appendSample(event.startTime, counters[name]);
}
var gpuMemoryLimitCounterName = "gpuMemoryLimitKB";
if (gpuMemoryLimitCounterName in counters)
this._gpuMemoryCounter.setLimit(counters[gpuMemoryLimitCounterName]);
}
this.scheduleRefresh();
},
__proto__: WebInspector.CountersGraph.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | 2 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {function(string=)} showImageCallback
* @extends {WebInspector.HBox}
*/
WebInspector.PaintProfilerView = function(showImageCallback)
{
WebInspector.HBox.call(this);
this.element.classList.add("paint-profiler-overview", "hbox");
this._canvasContainer = this.element.createChild("div", "paint-profiler-canvas-container");
this._progressBanner = this.element.createChild("div", "banner hidden");
this._progressBanner.textContent = WebInspector.UIString("Profiling\u2026");
this._pieChart = new WebInspector.PieChart(55, this._formatPieChartTime.bind(this), true);
this._pieChart.element.classList.add("paint-profiler-pie-chart");
this.element.appendChild(this._pieChart.element);
this._showImageCallback = showImageCallback;
this._canvas = this._canvasContainer.createChild("canvas", "fill");
this._context = this._canvas.getContext("2d");
this._selectionWindow = new WebInspector.OverviewGrid.Window(this._canvasContainer);
this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
this._innerBarWidth = 4 * window.devicePixelRatio;
this._minBarHeight = window.devicePixelRatio;
this._barPaddingWidth = 2 * window.devicePixelRatio;
this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth;
this._reset();
}
WebInspector.PaintProfilerView.Events = {
WindowChanged: "WindowChanged"
};
WebInspector.PaintProfilerView.prototype = {
onResize: function()
{
this._update();
},
/**
* @param {?WebInspector.PaintProfilerSnapshot} snapshot
* @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
* @param {?DOMAgent.Rect} clipRect
*/
setSnapshotAndLog: function(snapshot, log, clipRect)
{
this._reset();
this._snapshot = snapshot;
this._log = log;
this._logCategories = this._log.map(WebInspector.PaintProfilerView._categoryForLogItem);
if (!this._snapshot) {
this._update();
this._pieChart.setTotal(0);
this._selectionWindow.setEnabled(false);
return;
}
this._selectionWindow.setEnabled(true);
this._progressBanner.classList.remove("hidden");
snapshot.requestImage(null, null, 1, this._showImageCallback);
snapshot.profile(clipRect, onProfileDone.bind(this));
/**
* @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles
* @this {WebInspector.PaintProfilerView}
*/
function onProfileDone(profiles)
{
this._progressBanner.classList.add("hidden");
this._profiles = profiles;
this._update();
this._updatePieChart();
}
},
_update: function()
{
this._canvas.width = this._canvasContainer.clientWidth * window.devicePixelRatio;
this._canvas.height = this._canvasContainer.clientHeight * window.devicePixelRatio;
this._samplesPerBar = 0;
if (!this._profiles || !this._profiles.length)
return;
var maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth) / this._outerBarWidth);
var sampleCount = this._log.length;
this._samplesPerBar = Math.ceil(sampleCount / maxBars);
var maxBarTime = 0;
var barTimes = [];
var barHeightByCategory = [];
var heightByCategory = {};
for (var i = 0, lastBarIndex = 0, lastBarTime = 0; i < sampleCount;) {
var categoryName = (this._logCategories[i] && this._logCategories[i].name) || "misc";
var sampleIndex = this._log[i].commandIndex;
for (var row = 0; row < this._profiles.length; row++) {
var sample = this._profiles[row][sampleIndex];
lastBarTime += sample;
heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
}
++i;
if (i - lastBarIndex == this._samplesPerBar || i == sampleCount) {
// Normalize by total number of samples accumulated.
var factor = this._profiles.length * (i - lastBarIndex);
lastBarTime /= factor;
for (categoryName in heightByCategory)
heightByCategory[categoryName] /= factor;
barTimes.push(lastBarTime);
barHeightByCategory.push(heightByCategory);
if (lastBarTime > maxBarTime)
maxBarTime = lastBarTime;
lastBarTime = 0;
heightByCategory = {};
lastBarIndex = i;
}
}
const paddingHeight = 4 * window.devicePixelRatio;
var scale = (this._canvas.height - paddingHeight - this._minBarHeight) / maxBarTime;
for (var i = 0; i < barTimes.length; ++i) {
for (var categoryName in barHeightByCategory[i])
barHeightByCategory[i][categoryName] *= (barTimes[i] * scale + this._minBarHeight) / barTimes[i];
this._renderBar(i, barHeightByCategory[i]);
}
},
/**
* @param {number} index
* @param {!Object.<string, number>} heightByCategory
*/
_renderBar: function(index, heightByCategory)
{
var categories = WebInspector.PaintProfilerView.categories();
var currentHeight = 0;
var x = this._barPaddingWidth + index * this._outerBarWidth;
for (var categoryName in categories) {
if (!heightByCategory[categoryName])
continue;
currentHeight += heightByCategory[categoryName];
var y = this._canvas.height - currentHeight;
this._context.fillStyle = categories[categoryName].color;
this._context.fillRect(x, y, this._innerBarWidth, heightByCategory[categoryName]);
}
},
_onWindowChanged: function()
{
this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.WindowChanged);
this._updatePieChart();
if (this._updateImageTimer)
return;
this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
},
_updatePieChart: function()
{
if (!this._profiles || !this._profiles.length)
return;
var window = this.windowBoundaries();
var totalTime = 0;
var timeByCategory = {};
for (var i = window.left; i < window.right; ++i) {
var logEntry = this._log[i];
var category = WebInspector.PaintProfilerView._categoryForLogItem(logEntry);
timeByCategory[category.color] = timeByCategory[category.color] || 0;
for (var j = 0; j < this._profiles.length; ++j) {
var time = this._profiles[j][logEntry.commandIndex];
totalTime += time;
timeByCategory[category.color] += time;
}
}
this._pieChart.setTotal(totalTime / this._profiles.length);
for (var color in timeByCategory)
this._pieChart.addSlice(timeByCategory[color] / this._profiles.length, color);
},
/**
* @param {number} value
* @return {string}
*/
_formatPieChartTime: function(value)
{
return Number.millisToString(value * 1000, true);
},
/**
* @return {{left: number, right: number}}
*/
windowBoundaries: function()
{
var screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
var screenRight = this._selectionWindow.windowRight * this._canvas.width;
var barLeft = Math.floor(screenLeft / this._outerBarWidth);
var barRight = Math.floor((screenRight + this._innerBarWidth - this._barPaddingWidth / 2) / this._outerBarWidth);
var stepLeft = Number.constrain(barLeft * this._samplesPerBar, 0, this._log.length - 1);
var stepRight = Number.constrain(barRight * this._samplesPerBar, 0, this._log.length);
return { left: stepLeft, right: stepRight };
},
_updateImage: function()
{
delete this._updateImageTimer;
if (!this._profiles || !this._profiles.length)
return;
var window = this.windowBoundaries();
this._snapshot.requestImage(this._log[window.left].commandIndex, this._log[window.right - 1].commandIndex, 1, this._showImageCallback);
},
_reset: function()
{
this._snapshot = null;
this._profiles = null;
this._selectionWindow.reset();
},
__proto__: WebInspector.HBox.prototype
};
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.PaintProfilerCommandLogView = function()
{
WebInspector.VBox.call(this);
this.setMinimumSize(100, 25);
this.element.classList.add("profiler-log-view");
this._treeOutline = new TreeOutlineInShadow();
this.element.appendChild(this._treeOutline.element);
this._reset();
}
WebInspector.PaintProfilerCommandLogView.prototype = {
/**
* @param {?WebInspector.Target} target
* @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
*/
setCommandLog: function(target, log)
{
this._target = target;
this._log = log;
this.updateWindow();
},
/**
* @param {!TreeOutline} treeOutline
* @param {!WebInspector.PaintProfilerLogItem} logItem
*/
_appendLogItem: function(treeOutline, logItem)
{
var treeElement = new WebInspector.LogTreeElement(this, logItem);
treeOutline.appendChild(treeElement);
},
/**
* @param {number=} stepLeft
* @param {number=} stepRight
*/
updateWindow: function(stepLeft, stepRight)
{
this._treeOutline.removeChildren();
if (!this._log.length)
return;
stepLeft = stepLeft || 0;
stepRight = stepRight || this._log.length;
for (var i = stepLeft; i < stepRight; ++i)
this._appendLogItem(this._treeOutline, this._log[i]);
},
_reset: function()
{
this._log = [];
},
__proto__: WebInspector.VBox.prototype
};
/**
* @constructor
* @param {!WebInspector.PaintProfilerCommandLogView} ownerView
* @param {!WebInspector.PaintProfilerLogItem} logItem
* @extends {TreeElement}
*/
WebInspector.LogTreeElement = function(ownerView, logItem)
{
TreeElement.call(this, "", !!logItem.params);
this._logItem = logItem;
this._ownerView = ownerView;
this._filled = false;
}
WebInspector.LogTreeElement.prototype = {
onattach: function()
{
this._update();
},
onpopulate: function()
{
for (var param in this._logItem.params)
WebInspector.LogPropertyTreeElement._appendLogPropertyItem(this, param, this._logItem.params[param]);
},
/**
* @param {*} param
* @param {string} name
* @return {string}
*/
_paramToString: function(param, name)
{
if (typeof param !== "object")
return typeof param === "string" && param.length > 100 ? name : JSON.stringify(param);
var str = "";
var keyCount = 0;
for (var key in param) {
if (++keyCount > 4 || typeof param[key] === "object" || (typeof param[key] === "string" && param[key].length > 100))
return name;
if (str)
str += ", ";
str += param[key];
}
return str;
},
/**
* @param {?Object<string, *>} params
* @return {string}
*/
_paramsToString: function(params)
{
var str = "";
for (var key in params) {
if (str)
str += ", ";
str += this._paramToString(params[key], key);
}
return str;
},
_update: function()
{
var title = createDocumentFragment();
title.createTextChild(this._logItem.method + "(" + this._paramsToString(this._logItem.params) + ")");
this.title = title;
},
__proto__: TreeElement.prototype
};
/**
* @constructor
* @param {!{name: string, value}} property
* @extends {TreeElement}
*/
WebInspector.LogPropertyTreeElement = function(property)
{
TreeElement.call(this);
this._property = property;
};
/**
* @param {!TreeElement} element
* @param {string} name
* @param {*} value
*/
WebInspector.LogPropertyTreeElement._appendLogPropertyItem = function(element, name, value)
{
var treeElement = new WebInspector.LogPropertyTreeElement({name: name, value: value});
element.appendChild(treeElement);
if (value && typeof value === "object") {
for (var property in value)
WebInspector.LogPropertyTreeElement._appendLogPropertyItem(treeElement, property, value[property]);
}
};
WebInspector.LogPropertyTreeElement.prototype = {
onattach: function()
{
var title = createDocumentFragment();
var nameElement = title.createChild("span", "name");
nameElement.textContent = this._property.name;
var separatorElement = title.createChild("span", "separator");
separatorElement.textContent = ": ";
if (this._property.value === null || typeof this._property.value !== "object") {
var valueElement = title.createChild("span", "value");
valueElement.textContent = JSON.stringify(this._property.value);
valueElement.classList.add("cm-js-" + (this._property.value === null ? "null" : typeof this._property.value));
}
this.title = title;
},
__proto__: TreeElement.prototype
}
/**
* @return {!Object.<string, !WebInspector.PaintProfilerCategory>}
*/
WebInspector.PaintProfilerView.categories = function()
{
if (WebInspector.PaintProfilerView._categories)
return WebInspector.PaintProfilerView._categories;
WebInspector.PaintProfilerView._categories = {
shapes: new WebInspector.PaintProfilerCategory("shapes", WebInspector.UIString("Shapes"), "rgb(255, 161, 129)"),
bitmap: new WebInspector.PaintProfilerCategory("bitmap", WebInspector.UIString("Bitmap"), "rgb(136, 196, 255)"),
text: new WebInspector.PaintProfilerCategory("text", WebInspector.UIString("Text"), "rgb(180, 255, 137)"),
misc: new WebInspector.PaintProfilerCategory("misc", WebInspector.UIString("Misc"), "rgb(206, 160, 255)")
};
return WebInspector.PaintProfilerView._categories;
};
/**
* @constructor
* @param {string} name
* @param {string} title
* @param {string} color
*/
WebInspector.PaintProfilerCategory = function(name, title, color)
{
this.name = name;
this.title = title;
this.color = color;
}
/**
* @return {!Object.<string, !WebInspector.PaintProfilerCategory>}
*/
WebInspector.PaintProfilerView._initLogItemCategories = function()
{
if (WebInspector.PaintProfilerView._logItemCategoriesMap)
return WebInspector.PaintProfilerView._logItemCategoriesMap;
var categories = WebInspector.PaintProfilerView.categories();
var logItemCategories = {};
logItemCategories["Clear"] = categories["misc"];
logItemCategories["DrawPaint"] = categories["misc"];
logItemCategories["DrawData"] = categories["misc"];
logItemCategories["SetMatrix"] = categories["misc"];
logItemCategories["PushCull"] = categories["misc"];
logItemCategories["PopCull"] = categories["misc"];
logItemCategories["Translate"] = categories["misc"];
logItemCategories["Scale"] = categories["misc"];
logItemCategories["Concat"] = categories["misc"];
logItemCategories["Restore"] = categories["misc"];
logItemCategories["SaveLayer"] = categories["misc"];
logItemCategories["Save"] = categories["misc"];
logItemCategories["BeginCommentGroup"] = categories["misc"];
logItemCategories["AddComment"] = categories["misc"];
logItemCategories["EndCommentGroup"] = categories["misc"];
logItemCategories["ClipRect"] = categories["misc"];
logItemCategories["ClipRRect"] = categories["misc"];
logItemCategories["ClipPath"] = categories["misc"];
logItemCategories["ClipRegion"] = categories["misc"];
logItemCategories["DrawPoints"] = categories["shapes"];
logItemCategories["DrawRect"] = categories["shapes"];
logItemCategories["DrawOval"] = categories["shapes"];
logItemCategories["DrawRRect"] = categories["shapes"];
logItemCategories["DrawPath"] = categories["shapes"];
logItemCategories["DrawVertices"] = categories["shapes"];
logItemCategories["DrawDRRect"] = categories["shapes"];
logItemCategories["DrawBitmap"] = categories["bitmap"];
logItemCategories["DrawBitmapRectToRect"] = categories["bitmap"];
logItemCategories["DrawBitmapMatrix"] = categories["bitmap"];
logItemCategories["DrawBitmapNine"] = categories["bitmap"];
logItemCategories["DrawSprite"] = categories["bitmap"];
logItemCategories["DrawPicture"] = categories["bitmap"];
logItemCategories["DrawText"] = categories["text"];
logItemCategories["DrawPosText"] = categories["text"];
logItemCategories["DrawPosTextH"] = categories["text"];
logItemCategories["DrawTextOnPath"] = categories["text"];
WebInspector.PaintProfilerView._logItemCategoriesMap = logItemCategories;
return logItemCategories;
}
/**
* @param {!Object} logItem
* @return {!WebInspector.PaintProfilerCategory}
*/
WebInspector.PaintProfilerView._categoryForLogItem = function(logItem)
{
var method = logItem.method.toTitleCase();
var logItemCategories = WebInspector.PaintProfilerView._initLogItemCategories();
var result = logItemCategories[method];
if (!result) {
result = WebInspector.PaintProfilerView.categories()["misc"];
logItemCategories[method] = result;
}
return result;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | 2 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.Target} target
* @param {!WebInspector.TimelineLifecycleDelegate} delegate
* @param {!WebInspector.TracingModel} tracingModel
* @implements {WebInspector.TargetManager.Observer}
* @implements {WebInspector.TracingManagerClient}
*/
WebInspector.TimelineController = function(target, delegate, tracingModel)
{
this._delegate = delegate;
this._target = target;
this._tracingModel = tracingModel;
this._targets = [];
this._allProfilesStoppedPromise = Promise.resolve();
this._targetsResumedPromise = Promise.resolve();
WebInspector.targetManager.observeTargets(this);
}
WebInspector.TimelineController.prototype = {
/**
* @param {boolean} captureCauses
* @param {boolean} enableJSSampling
* @param {boolean} captureMemory
* @param {boolean} capturePictures
* @param {boolean} captureFilmStrip
*/
startRecording: function(captureCauses, enableJSSampling, captureMemory, capturePictures, captureFilmStrip)
{
function disabledByDefault(category)
{
return "disabled-by-default-" + category;
}
var categoriesArray = [
"-*",
"devtools.timeline",
disabledByDefault("devtools.timeline"),
disabledByDefault("devtools.timeline.frame"),
WebInspector.TracingModel.TopLevelEventCategory,
WebInspector.TimelineModel.Category.Console,
WebInspector.TimelineModel.Category.UserTiming
];
categoriesArray.push(WebInspector.TimelineModel.Category.LatencyInfo)
if (Runtime.experiments.isEnabled("timelineFlowEvents")) {
categoriesArray.push(disabledByDefault("toplevel.flow"),
disabledByDefault("ipc.flow"));
}
if (Runtime.experiments.isEnabled("timelineTracingJSProfile") && enableJSSampling) {
categoriesArray.push(disabledByDefault("v8.cpu_profile"));
if (WebInspector.moduleSetting("highResolutionCpuProfiling").get())
categoriesArray.push(disabledByDefault("v8.cpu_profile.hires"));
}
if (captureCauses || enableJSSampling)
categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
if (captureCauses && Runtime.experiments.isEnabled("timelineInvalidationTracking"))
categoriesArray.push(disabledByDefault("devtools.timeline.invalidationTracking"));
if (capturePictures) {
categoriesArray.push(disabledByDefault("devtools.timeline.layers"),
disabledByDefault("devtools.timeline.picture"),
disabledByDefault("blink.graphics_context_annotations"));
}
if (captureFilmStrip)
categoriesArray.push(disabledByDefault("devtools.screenshot"));
var categories = categoriesArray.join(",");
this._startRecordingWithCategories(categories, enableJSSampling);
},
stopRecording: function()
{
this._allProfilesStoppedPromise = this._stopProfilingOnAllTargets();
this._target.tracingManager.stop();
this._targetsResumedPromise = WebInspector.targetManager.resumeAllTargets();
this._delegate.loadingStarted();
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._targets.push(target);
if (this._profiling)
this._startProfilingOnTarget(target);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
this._targets.remove(target, true);
// FIXME: We'd like to stop profiling on the target and retrieve a profile
// but it's too late. Backend connection is closed.
},
/**
* @param {!WebInspector.Target} target
* @return {!Promise}
*/
_startProfilingOnTarget: function(target)
{
return target.profilerAgent().start();
},
/**
* @return {!Promise}
*/
_startProfilingOnAllTargets: function()
{
var intervalUs = WebInspector.moduleSetting("highResolutionCpuProfiling").get() ? 100 : 1000;
this._target.profilerAgent().setSamplingInterval(intervalUs);
this._profiling = true;
return Promise.all(this._targets.map(this._startProfilingOnTarget));
},
/**
* @param {!WebInspector.Target} target
* @return {!Promise}
*/
_stopProfilingOnTarget: function(target)
{
return target.profilerAgent().stop(this._addCpuProfile.bind(this, target.id()));
},
/**
* @param {number} targetId
* @param {?Protocol.Error} error
* @param {?ProfilerAgent.CPUProfile} cpuProfile
*/
_addCpuProfile: function(targetId, error, cpuProfile)
{
if (!cpuProfile) {
WebInspector.console.warn(WebInspector.UIString("CPU profile for a target is not available. %s", error || ""));
return;
}
if (!this._cpuProfiles)
this._cpuProfiles = new Map();
this._cpuProfiles.set(targetId, cpuProfile);
},
/**
* @return {!Promise}
*/
_stopProfilingOnAllTargets: function()
{
var targets = this._profiling ? this._targets : [];
this._profiling = false;
return Promise.all(targets.map(this._stopProfilingOnTarget, this));
},
/**
* @param {string} categories
* @param {boolean=} enableJSSampling
* @param {function(?string)=} callback
*/
_startRecordingWithCategories: function(categories, enableJSSampling, callback)
{
WebInspector.targetManager.suspendAllTargets();
var profilingStartedPromise = enableJSSampling && !Runtime.experiments.isEnabled("timelineTracingJSProfile") ?
this._startProfilingOnAllTargets() : Promise.resolve();
var samplingFrequencyHz = WebInspector.moduleSetting("highResolutionCpuProfiling").get() ? 10000 : 1000;
var options = "sampling-frequency=" + samplingFrequencyHz;
var target = this._target;
var tracingManager = target.tracingManager;
target.resourceTreeModel.suspendReload();
profilingStartedPromise.then(tracingManager.start.bind(tracingManager, this, categories, options, onTraceStarted));
/**
* @param {?string} error
*/
function onTraceStarted(error)
{
target.resourceTreeModel.resumeReload();
if (callback)
callback(error);
}
},
/**
* @override
*/
tracingStarted: function()
{
this._tracingModel.reset();
this._delegate.recordingStarted();
},
/**
* @param {!Array.<!WebInspector.TracingManager.EventPayload>} events
* @override
*/
traceEventsCollected: function(events)
{
this._tracingModel.addEvents(events);
},
/**
* @override
*/
tracingComplete: function()
{
Promise.all([this._allProfilesStoppedPromise, this._targetsResumedPromise])
.then(this._didStopRecordingTraceEvents.bind(this));
},
_didStopRecordingTraceEvents: function()
{
this._injectCpuProfileEvents();
this._tracingModel.tracingComplete();
this._delegate.loadingComplete(true);
},
/**
* @param {number} pid
* @param {number} tid
* @param {?ProfilerAgent.CPUProfile} cpuProfile
*/
_injectCpuProfileEvent: function(pid, tid, cpuProfile)
{
if (!cpuProfile)
return;
var cpuProfileEvent = /** @type {!WebInspector.TracingManager.EventPayload} */ ({
cat: WebInspector.TracingModel.DevToolsMetadataEventCategory,
ph: WebInspector.TracingModel.Phase.Instant,
ts: this._tracingModel.maximumRecordTime() * 1000,
pid: pid,
tid: tid,
name: WebInspector.TimelineModel.RecordType.CpuProfile,
args: { data: { cpuProfile: cpuProfile } }
});
this._tracingModel.addEvents([cpuProfileEvent]);
},
_injectCpuProfileEvents: function()
{
if (!this._cpuProfiles)
return;
var metadataEventTypes = WebInspector.TimelineModel.DevToolsMetadataEvent;
var metadataEvents = this._tracingModel.devToolsMetadataEvents();
var mainMetaEvent = metadataEvents.filter(event => event.name === metadataEventTypes.TracingStartedInPage).peekLast();
if (!mainMetaEvent)
return;
var pid = mainMetaEvent.thread.process().id();
var mainCpuProfile = this._cpuProfiles.get(this._target.id());
this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile);
var workerMetaEvents = metadataEvents.filter(event => event.name === metadataEventTypes.TracingSessionIdForWorker);
for (var metaEvent of workerMetaEvents) {
var workerId = metaEvent.args["data"]["workerId"];
var workerTarget = this._target.workerManager ? this._target.workerManager.targetByWorkerId(workerId) : null;
if (!workerTarget)
continue;
var cpuProfile = this._cpuProfiles.get(workerTarget.id());
this._injectCpuProfileEvent(pid, metaEvent.args["data"]["workerThreadId"], cpuProfile);
}
this._cpuProfiles = null;
},
/**
* @param {number} usage
* @override
*/
tracingBufferUsage: function(usage)
{
this._delegate.recordingProgress(usage);
},
/**
* @param {number} progress
* @override
*/
eventsRetrievalProgress: function(progress)
{
this._delegate.loadingProgress(progress);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
* @param {string} id
* @param {?string} title
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineEventOverview = function(id, title, model)
{
WebInspector.TimelineOverviewBase.call(this);
this.element.id = "timeline-overview-" + id;
this.element.classList.add("overview-strip");
if (title)
this.element.createChild("div", "timeline-overview-strip-title").textContent = title;
this._model = model;
}
WebInspector.TimelineEventOverview.prototype = {
/**
* @param {number} begin
* @param {number} end
* @param {number} position
* @param {number} height
* @param {string} color
*/
_renderBar: function(begin, end, position, height, color)
{
var x = begin;
var width = end - begin;
this._context.fillStyle = color;
this._context.fillRect(x, position, width, height);
},
/**
* @override
* @param {number} windowLeft
* @param {number} windowRight
* @return {!{startTime: number, endTime: number}}
*/
windowTimes: function(windowLeft, windowRight)
{
var absoluteMin = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - absoluteMin;
return {
startTime: absoluteMin + timeSpan * windowLeft,
endTime: absoluteMin + timeSpan * windowRight
};
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
* @return {!{left: number, right: number}}
*/
windowBoundaries: function(startTime, endTime)
{
var absoluteMin = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - absoluteMin;
var haveRecords = absoluteMin > 0;
return {
left: haveRecords && startTime ? Math.min((startTime - absoluteMin) / timeSpan, 1) : 0,
right: haveRecords && endTime < Infinity ? (endTime - absoluteMin) / timeSpan : 1
};
},
__proto__: WebInspector.TimelineOverviewBase.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineEventOverview.Input = function(model)
{
WebInspector.TimelineEventOverview.call(this, "input", null, model);
}
WebInspector.TimelineEventOverview.Input.prototype = {
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var events = this._model.mainThreadEvents();
var height = this._canvas.height;
var descriptors = WebInspector.TimelineUIUtils.eventDispatchDesciptors();
/** @type {!Map.<string,!WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor>} */
var descriptorsByType = new Map();
var maxPriority = -1;
for (var descriptor of descriptors) {
for (var type of descriptor.eventTypes)
descriptorsByType.set(type, descriptor);
maxPriority = Math.max(maxPriority, descriptor.priority);
}
var /** @const */ minWidth = 2 * window.devicePixelRatio;
var timeOffset = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - timeOffset;
var canvasWidth = this._canvas.width;
var scale = canvasWidth / timeSpan;
for (var priority = 0; priority <= maxPriority; ++priority) {
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (event.name !== WebInspector.TimelineModel.RecordType.EventDispatch)
continue;
var descriptor = descriptorsByType.get(event.args["data"]["type"]);
if (!descriptor || descriptor.priority !== priority)
continue;
var start = Number.constrain(Math.floor((event.startTime - timeOffset) * scale), 0, canvasWidth);
var end = Number.constrain(Math.ceil((event.endTime - timeOffset) * scale), 0, canvasWidth);
var width = Math.max(end - start, minWidth);
this._renderBar(start, start + width, 0, height, descriptor.color);
}
}
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineEventOverview.Network = function(model)
{
WebInspector.TimelineEventOverview.call(this, "network", WebInspector.UIString("NET"), model);
}
WebInspector.TimelineEventOverview.Network.prototype = {
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var height = this._canvas.height;
var numBands = categoryBand(WebInspector.TimelineUIUtils.NetworkCategory.Other) + 1;
var bandHeight = Math.floor(height / numBands);
var devicePixelRatio = window.devicePixelRatio;
var timeOffset = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - timeOffset;
var canvasWidth = this._canvas.width;
var scale = canvasWidth / timeSpan;
var ctx = this._context;
var requests = this._model.networkRequests();
/** @type {!Map<string,!{waiting:!Path2D,transfer:!Path2D}>} */
var paths = new Map();
requests.forEach(drawRequest);
for (var path of paths) {
ctx.fillStyle = path[0];
ctx.globalAlpha = 0.3;
ctx.fill(path[1]["waiting"]);
ctx.globalAlpha = 1;
ctx.fill(path[1]["transfer"]);
}
/**
* @param {!WebInspector.TimelineUIUtils.NetworkCategory} category
* @return {number}
*/
function categoryBand(category)
{
var categories = WebInspector.TimelineUIUtils.NetworkCategory;
switch (category) {
case categories.HTML: return 0;
case categories.Script: return 1;
case categories.Style: return 2;
case categories.Media: return 3;
default: return 4;
}
}
/**
* @param {!WebInspector.TimelineModel.NetworkRequest} request
*/
function drawRequest(request)
{
var tickWidth = 2 * devicePixelRatio;
var category = WebInspector.TimelineUIUtils.networkRequestCategory(request);
var style = WebInspector.TimelineUIUtils.networkCategoryColor(category);
var band = categoryBand(category);
var y = band * bandHeight;
var path = paths.get(style);
if (!path) {
path = { waiting: new Path2D(), transfer: new Path2D() };
paths.set(style, path);
}
var s = Math.max(Math.floor((request.startTime - timeOffset) * scale), 0);
var e = Math.min(Math.ceil((request.endTime - timeOffset) * scale), canvasWidth);
path["waiting"].rect(s, y, e - s, bandHeight - 1);
path["transfer"].rect(e - tickWidth / 2, y, tickWidth, bandHeight - 1);
if (!request.responseTime)
return;
var r = Math.ceil((request.responseTime - timeOffset) * scale);
path["transfer"].rect(r - tickWidth / 2, y, tickWidth, bandHeight - 1);
}
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineEventOverview.CPUActivity = function(model)
{
WebInspector.TimelineEventOverview.call(this, "cpu-activity", WebInspector.UIString("CPU"), model);
this._backgroundCanvas = this.element.createChild("canvas", "fill background");
}
WebInspector.TimelineEventOverview.CPUActivity.prototype = {
/**
* @override
*/
resetCanvas: function()
{
WebInspector.TimelineEventOverview.prototype.resetCanvas.call(this);
this._backgroundCanvas.width = this.element.clientWidth * window.devicePixelRatio;
this._backgroundCanvas.height = this.element.clientHeight * window.devicePixelRatio;
},
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var /** @const */ quantSizePx = 4 * window.devicePixelRatio;
var width = this._canvas.width;
var height = this._canvas.height;
var baseLine = height;
var timeOffset = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - timeOffset;
var scale = width / timeSpan;
var quantTime = quantSizePx / scale;
var categories = WebInspector.TimelineUIUtils.categories();
var categoryOrder = ["idle", "loading", "painting", "rendering", "scripting", "other"];
var otherIndex = categoryOrder.indexOf("other");
var idleIndex = 0;
console.assert(idleIndex === categoryOrder.indexOf("idle"));
for (var i = idleIndex + 1; i < categoryOrder.length; ++i)
categories[categoryOrder[i]]._overviewIndex = i;
var backgroundContext = this._backgroundCanvas.getContext("2d");
for (var thread of this._model.virtualThreads())
drawThreadEvents(backgroundContext, thread.events);
applyPattern(backgroundContext);
drawThreadEvents(this._context, this._model.mainThreadEvents());
/**
* @param {!CanvasRenderingContext2D} ctx
* @param {!Array<!WebInspector.TracingModel.Event>} events
*/
function drawThreadEvents(ctx, events)
{
var quantizer = new WebInspector.Quantizer(timeOffset, quantTime, drawSample);
var x = 0;
var categoryIndexStack = [];
var paths = [];
var lastY = [];
for (var i = 0; i < categoryOrder.length; ++i) {
paths[i] = new Path2D();
paths[i].moveTo(0, height);
lastY[i] = height;
}
/**
* @param {!Array<number>} counters
*/
function drawSample(counters)
{
var y = baseLine;
for (var i = idleIndex + 1; i < categoryOrder.length; ++i) {
var h = (counters[i] || 0) / quantTime * height;
y -= h;
paths[i].bezierCurveTo(x, lastY[i], x, y, x + quantSizePx / 2, y);
lastY[i] = y;
}
x += quantSizePx;
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEventStart(e)
{
var index = categoryIndexStack.length ? categoryIndexStack.peekLast() : idleIndex;
quantizer.appendInterval(e.startTime, index);
categoryIndexStack.push(WebInspector.TimelineUIUtils.eventStyle(e).category._overviewIndex || otherIndex);
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEventEnd(e)
{
quantizer.appendInterval(e.endTime, categoryIndexStack.pop());
}
WebInspector.TimelineModel.forEachEvent(events, onEventStart, onEventEnd);
quantizer.appendInterval(timeOffset + timeSpan + quantTime, idleIndex); // Kick drawing the last bucket.
for (var i = categoryOrder.length - 1; i > 0; --i) {
paths[i].lineTo(width, height);
ctx.fillStyle = categories[categoryOrder[i]].color;
ctx.fill(paths[i]);
}
}
/**
* @param {!CanvasRenderingContext2D} ctx
*/
function applyPattern(ctx)
{
var step = 4 * window.devicePixelRatio;
ctx.save();
ctx.lineWidth = step / Math.sqrt(8);
for (var x = 0.5; x < width + height; x += step) {
ctx.moveTo(x, 0);
ctx.lineTo(x - height, height);
}
ctx.globalCompositeOperation = "destination-out";
ctx.stroke();
ctx.restore();
}
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineFrameModelBase} frameModel
*/
WebInspector.TimelineEventOverview.Responsiveness = function(model, frameModel)
{
WebInspector.TimelineEventOverview.call(this, "responsiveness", null, model)
this._frameModel = frameModel;
}
WebInspector.TimelineEventOverview.Responsiveness.prototype = {
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var height = this._canvas.height;
var timeOffset = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - timeOffset;
var scale = this._canvas.width / timeSpan;
var frames = this._frameModel.frames();
var ctx = this._context;
var fillPath = new Path2D();
var markersPath = new Path2D();
for (var i = 0; i < frames.length; ++i) {
var frame = frames[i];
if (!frame.hasWarnings())
continue;
paintWarningDecoration(frame.startTime, frame.duration);
}
var events = this._model.mainThreadEvents();
for (var i = 0; i < events.length; ++i) {
if (!events[i].warning)
continue;
paintWarningDecoration(events[i].startTime, events[i].duration);
}
ctx.fillStyle = "hsl(0, 80%, 90%)";
ctx.strokeStyle = "red";
ctx.lineWidth = 2 * window.devicePixelRatio;
ctx.fill(fillPath);
ctx.stroke(markersPath);
/**
* @param {number} time
* @param {number} duration
*/
function paintWarningDecoration(time, duration)
{
var x = Math.round(scale * (time - timeOffset));
var w = Math.round(scale * duration);
fillPath.rect(x, 0, w, height);
markersPath.moveTo(x + w, 0);
markersPath.lineTo(x + w, height);
}
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TracingModel} tracingModel
*/
WebInspector.TimelineFilmStripOverview = function(model, tracingModel)
{
WebInspector.TimelineEventOverview.call(this, "filmstrip", null, model);
this._tracingModel = tracingModel;
this.reset();
}
WebInspector.TimelineFilmStripOverview.Padding = 2;
WebInspector.TimelineFilmStripOverview.prototype = {
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
if (!this._filmStripModel)
return;
var frames = this._filmStripModel.frames();
if (!frames.length)
return;
var drawGeneration = Symbol("drawGeneration");
this._drawGeneration = drawGeneration;
this._imageByFrame(frames[0]).then(image => {
if (this._drawGeneration !== drawGeneration)
return;
if (!image.naturalWidth || !image.naturalHeight)
return;
var imageHeight = this._canvas.height - 2 * WebInspector.TimelineFilmStripOverview.Padding;
var imageWidth = Math.ceil(imageHeight * image.naturalWidth / image.naturalHeight);
var popoverScale = Math.min(200 / image.naturalWidth, 1);
this._emptyImage = new Image(image.naturalWidth * popoverScale, image.naturalHeight * popoverScale);
this._drawFrames(imageWidth, imageHeight);
});
},
/**
* @param {!WebInspector.FilmStripModel.Frame} frame
* @return {!Promise<!HTMLImageElement>}
*/
_imageByFrame: function(frame)
{
var imagePromise = this._frameToImagePromise.get(frame);
if (!imagePromise) {
imagePromise = frame.imageDataPromise().then(createImage);
this._frameToImagePromise.set(frame, imagePromise);
}
return imagePromise;
/**
* @param {?string} data
* @return {!Promise<!HTMLImageElement>}
*/
function createImage(data)
{
var image = /** @type {!HTMLImageElement} */ (createElement("img"));
if (data)
image.src = "data:image/jpg;base64," + data;
return image.completePromise();
}
},
/**
* @param {number} imageWidth
* @param {number} imageHeight
*/
_drawFrames: function(imageWidth, imageHeight)
{
if (!this._filmStripModel || !imageWidth)
return;
if (!this._filmStripModel.frames().length)
return;
var padding = WebInspector.TimelineFilmStripOverview.Padding;
var width = this._canvas.width;
var zeroTime = this._tracingModel.minimumRecordTime();
var spanTime = this._tracingModel.maximumRecordTime() - zeroTime;
var scale = spanTime / width;
var context = this._canvas.getContext("2d");
var drawGeneration = this._drawGeneration;
context.beginPath();
for (var x = padding; x < width; x += imageWidth + 2 * padding) {
var time = zeroTime + (x + imageWidth / 2) * scale;
var frame = this._filmStripModel.frameByTimestamp(time);
if (!frame)
continue;
context.rect(x - 0.5, 0.5, imageWidth + 1, imageHeight + 1);
this._imageByFrame(frame).then(drawFrameImage.bind(this, x));
}
context.strokeStyle = "#ddd";
context.stroke();
/**
* @param {number} x
* @param {!HTMLImageElement} image
* @this {WebInspector.TimelineFilmStripOverview}
*/
function drawFrameImage(x, image)
{
// Ignore draws deferred from a previous update call.
if (this._drawGeneration !== drawGeneration)
return;
context.drawImage(image, x, 1, imageWidth, imageHeight);
}
},
/**
* @override
* @param {number} x
* @return {!Promise<?Element>}
*/
popoverElementPromise: function(x)
{
if (!this._filmStripModel || !this._filmStripModel.frames().length)
return Promise.resolve(/** @type {?Element} */ (null));
var time = this._calculator.positionToTime(x);
var frame = this._filmStripModel.frameByTimestamp(time);
if (frame === this._lastFrame)
return Promise.resolve(this._lastElement);
var imagePromise = frame ? this._imageByFrame(frame) : Promise.resolve(this._emptyImage);
return imagePromise.then(createFrameElement.bind(this));
/**
* @this {WebInspector.TimelineFilmStripOverview}
* @param {!HTMLImageElement} image
* @return {?Element}
*/
function createFrameElement(image)
{
var element = createElementWithClass("div", "frame");
element.createChild("div", "thumbnail").appendChild(image);
WebInspector.appendStyle(element, "timeline/timelinePanel.css");
this._lastFrame = frame;
this._lastElement = element;
return element;
}
},
/**
* @override
*/
reset: function()
{
this._lastFrame = undefined;
this._lastElement = null;
this._filmStripModel = new WebInspector.FilmStripModel(this._tracingModel);
/** @type {!Map<!WebInspector.FilmStripModel.Frame,!Promise<!HTMLImageElement>>} */
this._frameToImagePromise = new Map();
this._imageWidth = 0;
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineFrameModelBase} frameModel
*/
WebInspector.TimelineEventOverview.Frames = function(model, frameModel)
{
WebInspector.TimelineEventOverview.call(this, "framerate", WebInspector.UIString("FPS"), model);
this._frameModel = frameModel;
}
WebInspector.TimelineEventOverview.Frames.prototype = {
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var height = this._canvas.height;
var /** @const */ padding = 1 * window.devicePixelRatio;
var /** @const */ baseFrameDurationMs = 1e3 / 60;
var visualHeight = height - 2 * padding;
var timeOffset = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - timeOffset;
var scale = this._canvas.width / timeSpan;
var frames = this._frameModel.frames();
var baseY = height - padding;
var ctx = this._context;
var bottomY = baseY + 10 * window.devicePixelRatio;
var y = bottomY;
if (!frames.length)
return;
var lineWidth = window.devicePixelRatio;
var offset = lineWidth & 1 ? 0.5 : 0;
var tickDepth = 1.5 * window.devicePixelRatio;
ctx.beginPath();
ctx.moveTo(0, y);
for (var i = 0; i < frames.length; ++i) {
var frame = frames[i];
var x = Math.round((frame.startTime - timeOffset) * scale) + offset;
ctx.lineTo(x, y);
ctx.lineTo(x, y + tickDepth);
y = frame.idle ? bottomY : Math.round(baseY - visualHeight * Math.min(baseFrameDurationMs / frame.duration, 1)) - offset;
ctx.lineTo(x, y + tickDepth);
ctx.lineTo(x, y);
}
if (frames.length) {
var lastFrame = frames.peekLast();
var x = Math.round((lastFrame.startTime + lastFrame.duration - timeOffset) * scale) + offset;
ctx.lineTo(x, y);
}
ctx.lineTo(x, bottomY);
ctx.fillStyle = "hsl(110, 50%, 88%)";
ctx.strokeStyle = "hsl(110, 50%, 60%)";
ctx.lineWidth = lineWidth;
ctx.fill();
ctx.stroke();
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineEventOverview}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineEventOverview.Memory = function(model)
{
WebInspector.TimelineEventOverview.call(this, "memory", WebInspector.UIString("HEAP"), model);
this._heapSizeLabel = this.element.createChild("div", "memory-graph-label");
}
WebInspector.TimelineEventOverview.Memory.prototype = {
resetHeapSizeLabels: function()
{
this._heapSizeLabel.textContent = "";
},
/**
* @override
*/
update: function()
{
WebInspector.TimelineEventOverview.prototype.update.call(this);
var ratio = window.devicePixelRatio;
var events = this._model.mainThreadEvents();
if (!events.length) {
this.resetHeapSizeLabels();
return;
}
var lowerOffset = 3 * ratio;
var maxUsedHeapSize = 0;
var minUsedHeapSize = 100000000000;
var minTime = this._model.minimumRecordTime();
var maxTime = this._model.maximumRecordTime();
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
function isUpdateCountersEvent(event)
{
return event.name === WebInspector.TimelineModel.RecordType.UpdateCounters;
}
events = events.filter(isUpdateCountersEvent);
/**
* @param {!WebInspector.TracingModel.Event} event
*/
function calculateMinMaxSizes(event)
{
var counters = event.args.data;
if (!counters || !counters.jsHeapSizeUsed)
return;
maxUsedHeapSize = Math.max(maxUsedHeapSize, counters.jsHeapSizeUsed);
minUsedHeapSize = Math.min(minUsedHeapSize, counters.jsHeapSizeUsed);
}
events.forEach(calculateMinMaxSizes);
minUsedHeapSize = Math.min(minUsedHeapSize, maxUsedHeapSize);
var lineWidth = 1;
var width = this._canvas.width;
var height = this._canvas.height - lowerOffset;
var xFactor = width / (maxTime - minTime);
var yFactor = (height - lineWidth) / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
var histogram = new Array(width);
/**
* @param {!WebInspector.TracingModel.Event} event
*/
function buildHistogram(event)
{
var counters = event.args.data;
if (!counters || !counters.jsHeapSizeUsed)
return;
var x = Math.round((event.startTime - minTime) * xFactor);
var y = Math.round((counters.jsHeapSizeUsed - minUsedHeapSize) * yFactor);
histogram[x] = Math.max(histogram[x] || 0, y);
}
events.forEach(buildHistogram);
var ctx = this._context;
var heightBeyondView = height + lowerOffset + lineWidth;
ctx.translate(0.5, 0.5);
ctx.beginPath();
ctx.moveTo(-lineWidth, heightBeyondView);
var y = 0;
var isFirstPoint = true;
var lastX = 0;
for (var x = 0; x < histogram.length; x++) {
if (typeof histogram[x] === "undefined")
continue;
if (isFirstPoint) {
isFirstPoint = false;
y = histogram[x];
ctx.lineTo(-lineWidth, height - y);
}
var nextY = histogram[x];
if (Math.abs(nextY - y) > 2 && Math.abs(x - lastX) > 1)
ctx.lineTo(x, height - y);
y = nextY;
ctx.lineTo(x, height - y);
lastX = x;
}
ctx.lineTo(width + lineWidth, height - y);
ctx.lineTo(width + lineWidth, heightBeyondView);
ctx.closePath();
ctx.fillStyle = "hsla(220, 90%, 70%, 0.2)";
ctx.fill();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = "hsl(220, 90%, 70%)";
ctx.stroke();
this._heapSizeLabel.textContent = WebInspector.UIString("%s \u2013 %s", Number.bytesToString(minUsedHeapSize), Number.bytesToString(maxUsedHeapSize));
},
__proto__: WebInspector.TimelineEventOverview.prototype
}
/**
* @constructor
* @param {number} startTime
* @param {number} quantDuration
* @param {function(!Array<number>)} callback
*/
WebInspector.Quantizer = function(startTime, quantDuration, callback)
{
this._lastTime = startTime;
this._quantDuration = quantDuration;
this._callback = callback;
this._counters = [];
this._remainder = quantDuration;
}
WebInspector.Quantizer.prototype = {
/**
* @param {number} time
* @param {number} group
*/
appendInterval: function(time, group)
{
var interval = time - this._lastTime;
if (interval <= this._remainder) {
this._counters[group] = (this._counters[group] || 0) + interval;
this._remainder -= interval;
this._lastTime = time;
return;
}
this._counters[group] = (this._counters[group] || 0) + this._remainder;
this._callback(this._counters);
interval -= this._remainder;
while (interval >= this._quantDuration) {
var counters = [];
counters[group] = this._quantDuration;
this._callback(counters);
interval -= this._quantDuration;
}
this._counters = [];
this._counters[group] = interval;
this._lastTime = time;
this._remainder = this._quantDuration - interval;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 | 2 1 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.FlameChartDataProvider}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineFlameChartDataProviderBase = function(model)
{
WebInspector.FlameChartDataProvider.call(this);
this.reset();
this._model = model;
/** @type {?WebInspector.FlameChart.TimelineData} */
this._timelineData;
this._font = "11px " + WebInspector.fontFamily();
this._filters = [];
if (!Runtime.experiments.isEnabled("timelineShowAllEvents")) {
this._filters.push(WebInspector.TimelineUIUtils.visibleEventsFilter());
this._filters.push(new WebInspector.ExcludeTopLevelFilter());
}
}
WebInspector.TimelineFlameChartDataProviderBase.prototype = {
/**
* @override
* @return {number}
*/
barHeight: function()
{
return 17;
},
/**
* @override
* @return {number}
*/
textBaseline: function()
{
return 5;
},
/**
* @override
* @return {number}
*/
textPadding: function()
{
return 4;
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
entryFont: function(entryIndex)
{
return this._font;
},
/**
* @override
* @param {number} entryIndex
* @return {?string}
*/
entryTitle: function(entryIndex)
{
return null;
},
reset: function()
{
this._timelineData = null;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
totalTime: function()
{
return this._timeSpan;
},
/**
* @override
* @return {number}
*/
maxStackDepth: function()
{
return this._currentLevel;
},
/**
* @override
* @param {number} entryIndex
* @return {?Array.<!{title: string, value: (string|!Element)}>}
*/
prepareHighlightedEntryInfo: function(entryIndex)
{
return null;
},
/**
* @override
* @param {number} entryIndex
* @return {boolean}
*/
canJumpToEntry: function(entryIndex)
{
return false;
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
entryColor: function(entryIndex)
{
return "red";
},
/**
* @override
* @param {number} index
* @return {boolean}
*/
forceDecoration: function(index)
{
return false;
},
/**
* @override
* @param {number} entryIndex
* @param {!CanvasRenderingContext2D} context
* @param {?string} text
* @param {number} barX
* @param {number} barY
* @param {number} barWidth
* @param {number} barHeight
* @param {number} unclippedBarX
* @param {number} timeToPixels
* @return {boolean}
*/
decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixels)
{
return false;
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
* @return {?Array.<number>}
*/
dividerOffsets: function(startTime, endTime)
{
return null;
},
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return 0;
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
textColor: function(entryIndex)
{
return "#333";
},
/**
* @override
* @param {number} entryIndex
* @return {?{startTime: number, endTime: number}}
*/
highlightTimeRange: function(entryIndex)
{
var startTime = this._timelineData.entryStartTimes[entryIndex];
return {
startTime: startTime,
endTime: startTime + this._timelineData.entryTotalTimes[entryIndex]
};
},
/**
* @param {number} entryIndex
* @return {?WebInspector.TimelineSelection}
*/
createSelection: function(entryIndex)
{
return null;
},
/**
* @override
* @return {!WebInspector.FlameChart.TimelineData}
*/
timelineData: function()
{
throw new Error("Not implemented");
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
_isVisible: function(event)
{
return this._filters.every(function (filter) { return filter.accept(event); });
}
}
/**
* @enum {symbol}
*/
WebInspector.TimelineFlameChartEntryType = {
Frame: Symbol("Frame"),
Event: Symbol("Event"),
InteractionRecord: Symbol("InteractionRecord"),
};
/**
* @constructor
* @extends {WebInspector.TimelineFlameChartDataProviderBase}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineFrameModelBase} frameModel
* @param {!WebInspector.TimelineIRModel} irModel
*/
WebInspector.TimelineFlameChartDataProvider = function(model, frameModel, irModel)
{
WebInspector.TimelineFlameChartDataProviderBase.call(this, model);
this._frameModel = frameModel;
this._irModel = irModel;
this._consoleColorGenerator = new WebInspector.FlameChart.ColorGenerator(
{ min: 30, max: 55 },
{ min: 70, max: 100, count: 6 },
50, 0.7);
this._headerLevel1 = {
padding: 4,
height: 17,
collapsible: true,
color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground),
font: this._font,
backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background),
nestingLevel: 0
};
this._headerLevel2 = {
padding: 2,
height: 17,
collapsible: false,
font: this._font,
color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground),
backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background),
nestingLevel: 1,
shareHeaderLine: true
};
this._interactionsHeaderLevel1 = {
padding: 4,
height: 17,
collapsible: Runtime.experiments.isEnabled("timelineLatencyInfo"),
color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground),
font: this._font,
backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background),
nestingLevel: 0,
useFirstLineForOverview: true,
shareHeaderLine: true
};
this._interactionsHeaderLevel2 = {
padding: 4,
height: 17,
collapsible: true,
color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground),
font: this._font,
backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background),
nestingLevel: 1
};
}
WebInspector.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs = 0.001;
WebInspector.TimelineFlameChartDataProvider.prototype = {
/**
* @override
* @param {number} entryIndex
* @return {?string}
*/
entryTitle: function(entryIndex)
{
var entryType = this._entryType(entryIndex);
if (entryType === WebInspector.TimelineFlameChartEntryType.Event) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]);
if (event.phase === WebInspector.TracingModel.Phase.AsyncStepInto || event.phase === WebInspector.TracingModel.Phase.AsyncStepPast)
return event.name + ":" + event.args["step"];
if (event._blackboxRoot)
return WebInspector.UIString("Blackboxed");
var name = WebInspector.TimelineUIUtils.eventStyle(event).title;
// TODO(yurys): support event dividers
var detailsText = WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent(event, this._model.target());
if (event.name === WebInspector.TimelineModel.RecordType.JSFrame && detailsText)
return detailsText;
return detailsText ? WebInspector.UIString("%s (%s)", name, detailsText) : name;
}
var title = this._entryIndexToTitle[entryIndex];
if (!title) {
title = WebInspector.UIString("Unexpected entryIndex %d", entryIndex);
console.error(title);
}
return title;
},
/**
* @override
* @param {number} index
* @return {string}
*/
textColor: function(index)
{
var event = this._entryData[index];
if (event && event._blackboxRoot)
return "#888";
else
return WebInspector.TimelineFlameChartDataProviderBase.prototype.textColor.call(this, index);
},
/**
* @override
*/
reset: function()
{
WebInspector.TimelineFlameChartDataProviderBase.prototype.reset.call(this);
/** @type {!Array<!WebInspector.TracingModel.Event|!WebInspector.TimelineFrame|!WebInspector.TimelineIRModel.Phases>} */
this._entryData = [];
/** @type {!Array<!WebInspector.TimelineFlameChartEntryType>} */
this._entryTypeByLevel = [];
/** @type {!Array<string>} */
this._entryIndexToTitle = [];
/** @type {!Array.<!WebInspector.TimelineFlameChartMarker>} */
this._markers = [];
this._asyncColorByCategory = {};
},
/**
* @override
* @return {!WebInspector.FlameChart.TimelineData}
*/
timelineData: function()
{
if (this._timelineData)
return this._timelineData;
this._timelineData = new WebInspector.FlameChart.TimelineData([], [], [], []);
this._flowEventIndexById = {};
this._minimumBoundary = this._model.minimumRecordTime();
this._timeSpan = this._model.isEmpty() ? 1000 : this._model.maximumRecordTime() - this._minimumBoundary;
this._currentLevel = 0;
this._appendFrameBars(this._frameModel.frames());
this._appendHeader(WebInspector.UIString("Interactions"), this._interactionsHeaderLevel1);
this._appendInteractionRecords();
if (Runtime.experiments.isEnabled("timelineLatencyInfo")) {
var asyncEventGroups = WebInspector.TimelineUIUtils.asyncEventGroups();
var inputLatencies = this._model.mainThreadAsyncEvents().get(asyncEventGroups.input);
if (inputLatencies && inputLatencies.length)
this._appendAsyncEventsGroup(asyncEventGroups.input.title, inputLatencies, this._interactionsHeaderLevel2);
var animations = this._model.mainThreadAsyncEvents().get(asyncEventGroups.animation);
if (animations && animations.length)
this._appendAsyncEventsGroup(asyncEventGroups.animation.title, animations, this._interactionsHeaderLevel2);
}
var threads = this._model.virtualThreads();
this._appendThreadTimelineData(WebInspector.UIString("Main"), this._model.mainThreadEvents(), this._model.mainThreadAsyncEvents(), true);
var compositorThreads = threads.filter(thread => thread.name.startsWith("CompositorTileWorker"));
var otherThreads = threads.filter(thread => !thread.name.startsWith("CompositorTileWorker"));
if (compositorThreads.length) {
this._appendHeader(WebInspector.UIString("Raster"), this._headerLevel1);
for (var i = 0; i < compositorThreads.length; ++i)
this._appendSyncEvents(compositorThreads[i].events, WebInspector.UIString("Rasterizer Thread %d", i), this._headerLevel2);
}
this._appendGPUEvents();
otherThreads.forEach(thread => this._appendThreadTimelineData(thread.name, thread.events, thread.asyncEventsByGroup));
/**
* @param {!WebInspector.TimelineFlameChartMarker} a
* @param {!WebInspector.TimelineFlameChartMarker} b
*/
function compareStartTime(a, b)
{
return a.startTime() - b.startTime();
}
this._markers.sort(compareStartTime);
this._timelineData.markers = this._markers;
this._flowEventIndexById = {};
return this._timelineData;
},
/**
* @param {string} threadTitle
* @param {!Array<!WebInspector.TracingModel.Event>} syncEvents
* @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} asyncEvents
* @param {boolean=} forceExpanded
*/
_appendThreadTimelineData: function(threadTitle, syncEvents, asyncEvents, forceExpanded)
{
this._appendAsyncEvents(asyncEvents);
this._appendSyncEvents(syncEvents, threadTitle, this._headerLevel1, forceExpanded);
},
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @param {string} title
* @param {!WebInspector.FlameChart.GroupStyle} style
* @param {boolean=} forceExpanded
*/
_appendSyncEvents: function(events, title, style, forceExpanded)
{
var openEvents = [];
var flowEventsEnabled = Runtime.experiments.isEnabled("timelineFlowEvents");
var blackboxingEnabled = Runtime.experiments.isEnabled("blackboxJSFramesOnTimeline");
var maxStackDepth = 0;
for (var i = 0; i < events.length; ++i) {
var e = events[i];
if (WebInspector.TimelineUIUtils.isMarkerEvent(e))
this._markers.push(new WebInspector.TimelineFlameChartMarker(e.startTime, e.startTime - this._model.minimumRecordTime(), WebInspector.TimelineUIUtils.markerStyleForEvent(e)));
if (!WebInspector.TracingModel.isFlowPhase(e.phase)) {
if (!e.endTime && e.phase !== WebInspector.TracingModel.Phase.Instant)
continue;
if (WebInspector.TracingModel.isAsyncPhase(e.phase))
continue;
if (!this._isVisible(e))
continue;
}
while (openEvents.length && openEvents.peekLast().endTime <= e.startTime)
openEvents.pop();
e._blackboxRoot = false;
if (blackboxingEnabled && this._isBlackboxedEvent(e)) {
var parent = openEvents.peekLast();
if (parent && parent._blackboxRoot)
continue;
e._blackboxRoot = true;
}
if (title) {
this._appendHeader(title, style, forceExpanded);
title = "";
}
var level = this._currentLevel + openEvents.length;
this._appendEvent(e, level);
if (flowEventsEnabled)
this._appendFlowEvent(e, level);
maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1);
if (e.endTime)
openEvents.push(e);
}
this._entryTypeByLevel.length = this._currentLevel + maxStackDepth;
this._entryTypeByLevel.fill(WebInspector.TimelineFlameChartEntryType.Event, this._currentLevel);
this._currentLevel += maxStackDepth;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
_isBlackboxedEvent: function(event)
{
if (event.name !== WebInspector.TimelineModel.RecordType.JSFrame)
return false;
var url = event.args["data"]["url"];
return url && this._isBlackboxedURL(url);
},
/**
* @param {string} url
* @return {boolean}
*/
_isBlackboxedURL: function(url)
{
return WebInspector.blackboxManager.isBlackboxedURL(url);
},
/**
* @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} asyncEvents
*/
_appendAsyncEvents: function(asyncEvents)
{
var groups = WebInspector.TimelineUIUtils.asyncEventGroups();
var groupArray = Object.values(groups);
groupArray.remove(groups.animation);
groupArray.remove(groups.input);
for (var groupIndex = 0; groupIndex < groupArray.length; ++groupIndex) {
var group = groupArray[groupIndex];
var events = asyncEvents.get(group);
if (events)
this._appendAsyncEventsGroup(group.title, events, this._headerLevel1);
}
},
/**
* @param {string} header
* @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events
* @param {!WebInspector.FlameChart.GroupStyle} style
*/
_appendAsyncEventsGroup: function(header, events, style)
{
var lastUsedTimeByLevel = [];
var groupHeaderAppended = false;
for (var i = 0; i < events.length; ++i) {
var asyncEvent = events[i];
if (!this._isVisible(asyncEvent))
continue;
if (!groupHeaderAppended) {
this._appendHeader(header, style);
groupHeaderAppended = true;
}
var startTime = asyncEvent.startTime;
var level;
for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[level] > startTime; ++level) {}
this._appendAsyncEvent(asyncEvent, this._currentLevel + level);
lastUsedTimeByLevel[level] = asyncEvent.endTime;
}
this._entryTypeByLevel.length = this._currentLevel + lastUsedTimeByLevel.length;
this._entryTypeByLevel.fill(WebInspector.TimelineFlameChartEntryType.Event, this._currentLevel);
this._currentLevel += lastUsedTimeByLevel.length;
},
_appendGPUEvents: function()
{
if (this._appendSyncEvents(this._model.gpuEvents(), WebInspector.UIString("GPU"), this._headerLevel1, false))
++this._currentLevel;
},
_appendInteractionRecords: function()
{
this._irModel.interactionRecords().forEach(this._appendSegment, this);
this._entryTypeByLevel[this._currentLevel++] = WebInspector.TimelineFlameChartEntryType.InteractionRecord;
},
/**
* @param {!Array.<!WebInspector.TimelineFrame>} frames
*/
_appendFrameBars: function(frames)
{
var style = WebInspector.TimelineUIUtils.markerStyleForFrame();
this._entryTypeByLevel[this._currentLevel] = WebInspector.TimelineFlameChartEntryType.Frame;
for (var i = 0; i < frames.length; ++i) {
this._markers.push(new WebInspector.TimelineFlameChartMarker(frames[i].startTime, frames[i].startTime - this._model.minimumRecordTime(), style));
this._appendFrame(frames[i]);
}
++this._currentLevel;
},
/**
* @param {number} entryIndex
* @return {!WebInspector.TimelineFlameChartEntryType}
*/
_entryType: function(entryIndex)
{
return this._entryTypeByLevel[this._timelineData.entryLevels[entryIndex]];
},
/**
* @override
* @param {number} entryIndex
* @return {?Array.<!{title: string, value: (string|!Element)}>}
*/
prepareHighlightedEntryInfo: function(entryIndex)
{
var time;
var title;
var warning;
var type = this._entryType(entryIndex);
if (type === WebInspector.TimelineFlameChartEntryType.Event) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]);
var totalTime = event.duration;
var selfTime = event.selfTime;
var /** @const */ eps = 1e-6;
time = typeof totalTime === "number" && Math.abs(totalTime - selfTime) > eps && selfTime > eps ?
WebInspector.UIString("%s (self %s)", Number.millisToString(totalTime, true), Number.millisToString(selfTime, true)) :
Number.millisToString(totalTime, true);
title = this.entryTitle(entryIndex);
warning = WebInspector.TimelineUIUtils.eventWarning(event);
} else if (type === WebInspector.TimelineFlameChartEntryType.Frame) {
var frame = /** @type {!WebInspector.TimelineFrame} */ (this._entryData[entryIndex]);
time = WebInspector.UIString("%s ~ %.0f\u2009fps", Number.preciseMillisToString(frame.duration, 1), (1000 / frame.duration));
title = frame.idle ? WebInspector.UIString("Idle Frame") : WebInspector.UIString("Frame");
if (frame.hasWarnings()) {
warning = createElement("span");
warning.textContent = WebInspector.UIString("Long frame");
}
} else {
return null;
}
var value = createElement("div");
var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css");
var contents = root.createChild("div", "timeline-flamechart-popover");
contents.createChild("span", "timeline-info-time").textContent = time;
contents.createChild("span", "timeline-info-title").textContent = title;
if (warning) {
warning.classList.add("timeline-info-warning");
contents.appendChild(warning);
}
return [{ title: "", value: value }];
},
/**
* @override
* @param {number} entryIndex
* @return {string}
*/
entryColor: function(entryIndex)
{
var type = this._entryType(entryIndex);
if (type === WebInspector.TimelineFlameChartEntryType.Event) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]);
if (!WebInspector.TracingModel.isAsyncPhase(event.phase))
return WebInspector.TimelineUIUtils.eventColor(event);
if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
return this._consoleColorGenerator.colorForID(event.name);
var category = WebInspector.TimelineUIUtils.eventStyle(event).category;
var color = this._asyncColorByCategory[category.name];
if (color)
return color;
var parsedColor = WebInspector.Color.parse(category.color);
color = parsedColor.setAlpha(0.7).asString(WebInspector.Color.Format.RGBA) || "";
this._asyncColorByCategory[category.name] = color;
return color;
}
if (type === WebInspector.TimelineFlameChartEntryType.Frame)
return "white";
if (type === WebInspector.TimelineFlameChartEntryType.InteractionRecord)
return "transparent";
return "";
},
/**
* @override
* @param {number} entryIndex
* @param {!CanvasRenderingContext2D} context
* @param {?string} text
* @param {number} barX
* @param {number} barY
* @param {number} barWidth
* @param {number} barHeight
* @return {boolean}
*/
decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight)
{
var data = this._entryData[entryIndex];
var type = this._entryType(entryIndex);
if (type === WebInspector.TimelineFlameChartEntryType.Frame) {
var /** @const */ vPadding = 1;
var /** @const */ hPadding = 1;
var frame = /** {!WebInspector.TimelineFrame} */ (data);
barX += hPadding;
barWidth -= 2 * hPadding;
barY += vPadding;
barHeight -= 2 * vPadding + 1;
context.fillStyle = frame.idle ? "white" : (frame.hasWarnings() ? "#fad1d1" : "#d7f0d1");
context.fillRect(barX, barY, barWidth, barHeight);
var frameDurationText = Number.preciseMillisToString(frame.duration, 1);
var textWidth = context.measureText(frameDurationText).width;
if (barWidth >= textWidth) {
context.fillStyle = this.textColor(entryIndex);
context.fillText(frameDurationText, barX + (barWidth - textWidth) / 2, barY + barHeight - 3);
}
return true;
}
if (type === WebInspector.TimelineFlameChartEntryType.InteractionRecord) {
var color = WebInspector.TimelineUIUtils.interactionPhaseColor(/** @type {!WebInspector.TimelineIRModel.Phases} */ (this._entryData[entryIndex]));
context.fillStyle = color;
context.fillRect(barX, barY, barWidth - 1, 2);
context.fillRect(barX, barY - 3, 2, 3);
context.fillRect(barX + barWidth - 3, barY - 3, 2, 3);
return false;
}
if (type === WebInspector.TimelineFlameChartEntryType.Event) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]);
if (event && event.warning)
paintWarningDecoration(barX, barWidth - 1.5);
}
/**
* @param {number} x
* @param {number} width
*/
function paintWarningDecoration(x, width)
{
var /** @const */ triangleSize = 8;
context.save();
context.beginPath();
context.rect(x, barY, width, barHeight);
context.clip();
context.beginPath();
context.fillStyle = "red";
context.moveTo(x + width - triangleSize, barY);
context.lineTo(x + width, barY);
context.lineTo(x + width, barY + triangleSize);
context.fill();
context.restore();
}
return false;
},
/**
* @override
* @param {number} entryIndex
* @return {boolean}
*/
forceDecoration: function(entryIndex)
{
var type = this._entryType(entryIndex);
return type === WebInspector.TimelineFlameChartEntryType.Frame ||
type === WebInspector.TimelineFlameChartEntryType.Event && !!/** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]).warning;
},
/**
* @param {string} title
* @param {!WebInspector.FlameChart.GroupStyle} style
* @param {boolean=} expanded
*/
_appendHeader: function(title, style, expanded)
{
this._timelineData.groups.push({startLevel: this._currentLevel, name: title, expanded: expanded, style: style});
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} level
*/
_appendEvent: function(event, level)
{
var index = this._entryData.length;
this._entryData.push(event);
this._timelineData.entryLevels[index] = level;
this._timelineData.entryTotalTimes[index] = event.duration || WebInspector.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs;
this._timelineData.entryStartTimes[index] = event.startTime;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} level
*/
_appendFlowEvent: function(event, level)
{
var timelineData = this._timelineData;
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {number}
*/
function pushStartFlow(event)
{
var flowIndex = timelineData.flowStartTimes.length;
timelineData.flowStartTimes.push(event.startTime);
timelineData.flowStartLevels.push(level);
return flowIndex;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} flowIndex
*/
function pushEndFlow(event, flowIndex)
{
timelineData.flowEndTimes[flowIndex] = event.startTime;
timelineData.flowEndLevels[flowIndex] = level;
}
switch(event.phase) {
case WebInspector.TracingModel.Phase.FlowBegin:
this._flowEventIndexById[event.id] = pushStartFlow(event);
break;
case WebInspector.TracingModel.Phase.FlowStep:
pushEndFlow(event, this._flowEventIndexById[event.id]);
this._flowEventIndexById[event.id] = pushStartFlow(event);
break;
case WebInspector.TracingModel.Phase.FlowEnd:
pushEndFlow(event, this._flowEventIndexById[event.id]);
delete this._flowEventIndexById[event.id];
break;
}
},
/**
* @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent
* @param {number} level
*/
_appendAsyncEvent: function(asyncEvent, level)
{
if (WebInspector.TracingModel.isNestableAsyncPhase(asyncEvent.phase)) {
// FIXME: also add steps once we support event nesting in the FlameChart.
this._appendEvent(asyncEvent, level);
return;
}
var steps = asyncEvent.steps;
// If we have past steps, put the end event for each range rather than start one.
var eventOffset = steps.length > 1 && steps[1].phase === WebInspector.TracingModel.Phase.AsyncStepPast ? 1 : 0;
for (var i = 0; i < steps.length - 1; ++i) {
var index = this._entryData.length;
this._entryData.push(steps[i + eventOffset]);
var startTime = steps[i].startTime;
this._timelineData.entryLevels[index] = level;
this._timelineData.entryTotalTimes[index] = steps[i + 1].startTime - startTime;
this._timelineData.entryStartTimes[index] = startTime;
}
},
/**
* @param {!WebInspector.TimelineFrame} frame
*/
_appendFrame: function(frame)
{
var index = this._entryData.length;
this._entryData.push(frame);
this._entryIndexToTitle[index] = Number.millisToString(frame.duration, true);
this._timelineData.entryLevels[index] = this._currentLevel;
this._timelineData.entryTotalTimes[index] = frame.duration;
this._timelineData.entryStartTimes[index] = frame.startTime;
},
/**
* @param {!WebInspector.Segment} segment
*/
_appendSegment: function(segment)
{
var index = this._entryData.length;
this._entryData.push(/** @type {!WebInspector.TimelineIRModel.Phases} */(segment.data));
this._entryIndexToTitle[index] = /** @type {string} */ (segment.data);
this._timelineData.entryLevels[index] = this._currentLevel;
this._timelineData.entryTotalTimes[index] = segment.end - segment.begin;
this._timelineData.entryStartTimes[index] = segment.begin;
},
/**
* @override
* @param {number} entryIndex
* @return {?WebInspector.TimelineSelection}
*/
createSelection: function(entryIndex)
{
var type = this._entryType(entryIndex);
var timelineSelection = null;
if (type === WebInspector.TimelineFlameChartEntryType.Event)
timelineSelection = WebInspector.TimelineSelection.fromTraceEvent(/** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]))
else if (type === WebInspector.TimelineFlameChartEntryType.Frame)
timelineSelection = WebInspector.TimelineSelection.fromFrame(/** @type {!WebInspector.TimelineFrame} */ (this._entryData[entryIndex]));
if (timelineSelection)
this._lastSelection = new WebInspector.TimelineFlameChartView.Selection(timelineSelection, entryIndex);
return timelineSelection;
},
/**
* @param {?WebInspector.TimelineSelection} selection
* @return {number}
*/
entryIndexForSelection: function(selection)
{
if (!selection || selection.type() === WebInspector.TimelineSelection.Type.Range)
return -1;
if (this._lastSelection && this._lastSelection.timelineSelection.object() === selection.object())
return this._lastSelection.entryIndex;
var index = this._entryData.indexOf(/** @type {!WebInspector.TracingModel.Event|!WebInspector.TimelineFrame|!WebInspector.TimelineIRModel.Phases} */(selection.object()));
if (index !== -1)
this._lastSelection = new WebInspector.TimelineFlameChartView.Selection(selection, index);
return index;
},
__proto__: WebInspector.TimelineFlameChartDataProviderBase.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineFlameChartDataProviderBase}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineFlameChartNetworkDataProvider = function(model)
{
WebInspector.TimelineFlameChartDataProviderBase.call(this, model);
var loadingCategory = WebInspector.TimelineUIUtils.categories()["loading"];
this._waitingColor = loadingCategory.childColor;
this._processingColor = loadingCategory.color;
}
WebInspector.TimelineFlameChartNetworkDataProvider.prototype = {
/**
* @override
* @return {!WebInspector.FlameChart.TimelineData}
*/
timelineData: function()
{
if (this._timelineData)
return this._timelineData;
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
this._requests = [];
this._timelineData = new WebInspector.FlameChart.TimelineData([], [], [], []);
this._appendTimelineData(this._model.mainThreadEvents());
return this._timelineData;
},
/**
* @override
*/
reset: function()
{
WebInspector.TimelineFlameChartDataProviderBase.prototype.reset.call(this);
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
this._requests = [];
},
/**
* @param {number} startTime
* @param {number} endTime
*/
setWindowTimes: function(startTime, endTime)
{
this._startTime = startTime;
this._endTime = endTime;
this._updateTimelineData();
},
/**
* @override
* @param {number} index
* @return {?WebInspector.TimelineSelection}
*/
createSelection: function(index)
{
if (index === -1)
return null;
var request = this._requests[index];
this._lastSelection = new WebInspector.TimelineFlameChartView.Selection(WebInspector.TimelineSelection.fromNetworkRequest(request), index);
return this._lastSelection.timelineSelection;
},
/**
* @param {?WebInspector.TimelineSelection} selection
* @return {number}
*/
entryIndexForSelection: function(selection)
{
if (!selection)
return -1;
if (this._lastSelection && this._lastSelection.timelineSelection.object() === selection.object())
return this._lastSelection.entryIndex;
if (selection.type() !== WebInspector.TimelineSelection.Type.NetworkRequest)
return -1;
var request = /** @type{!WebInspector.TimelineModel.NetworkRequest} */ (selection.object());
var index = this._requests.indexOf(request);
if (index !== -1)
this._lastSelection = new WebInspector.TimelineFlameChartView.Selection(WebInspector.TimelineSelection.fromNetworkRequest(request), index);
return index;
},
/**
* @override
* @param {number} index
* @return {string}
*/
entryColor: function(index)
{
var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._requests[index]);
var category = WebInspector.TimelineUIUtils.networkRequestCategory(request);
return WebInspector.TimelineUIUtils.networkCategoryColor(category);
},
/**
* @override
* @param {number} index
* @return {?string}
*/
entryTitle: function(index)
{
var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._requests[index]);
return request.url || null;
},
/**
* @override
* @param {number} index
* @param {!CanvasRenderingContext2D} context
* @param {?string} text
* @param {number} barX
* @param {number} barY
* @param {number} barWidth
* @param {number} barHeight
* @param {number} unclippedBarX
* @param {number} timeToPixels
* @return {boolean}
*/
decorateEntry: function(index, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixels)
{
var minTransferWidthPx = 2;
var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._requests[index]);
var startTime = request.startTime;
var endTime = request.endTime;
var lastX = unclippedBarX;
context.fillStyle = "hsla(0, 0%, 100%, 0.6)";
for (var i = 0; i < request.children.length; ++i) {
var event = request.children[i];
var t0 = event.startTime;
var t1 = event.endTime || event.startTime;
var x0 = Math.floor(unclippedBarX + (t0 - startTime) * timeToPixels - 1);
var x1 = Math.floor(unclippedBarX + (t1 - startTime) * timeToPixels + 1);
if (x0 > lastX)
context.fillRect(lastX, barY, x0 - lastX, barHeight);
lastX = x1;
}
var endX = unclippedBarX + (endTime - startTime) * timeToPixels;
if (endX > lastX)
context.fillRect(lastX, barY, Math.min(endX - lastX, 1e5), barHeight);
if (typeof request.priority === "string") {
var color = this._colorForPriority(request.priority);
if (color) {
context.fillStyle = "hsl(0, 0%, 100%)";
context.fillRect(barX, barY, 4, 4);
context.fillStyle = color;
context.fillRect(barX, barY, 3, 3);
}
}
return false;
},
/**
* @override
* @param {number} index
* @return {boolean}
*/
forceDecoration: function(index)
{
return true;
},
/**
* @override
* @param {number} index
* @return {?Array<!{title: string, value: (string|!Element)}>}
*/
prepareHighlightedEntryInfo: function(index)
{
var /** @const */ maxURLChars = 80;
var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._requests[index]);
if (!request.url)
return null;
var value = createElement("div");
var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css");
var contents = root.createChild("div", "timeline-flamechart-popover");
var duration = request.endTime - request.startTime;
if (request.startTime && isFinite(duration))
contents.createChild("span", "timeline-info-network-time").textContent = Number.millisToString(duration);
if (typeof request.priority === "string") {
var div = contents.createChild("span");
div.textContent = WebInspector.uiLabelForPriority(/** @type {!NetworkAgent.ResourcePriority} */ (request.priority));
div.style.color = this._colorForPriority(request.priority) || "black";
}
contents.createChild("span").textContent = request.url.trimMiddle(maxURLChars);
return [{ title: "", value: value }];
},
/**
* @param {string} priority
* @return {?string}
*/
_colorForPriority: function(priority)
{
switch (/** @type {!NetworkAgent.ResourcePriority} */ (priority)) {
case NetworkAgent.ResourcePriority.VeryLow: return "#080";
case NetworkAgent.ResourcePriority.Low: return "#6c0";
case NetworkAgent.ResourcePriority.Medium: return "#fa0";
case NetworkAgent.ResourcePriority.High: return "#f60";
case NetworkAgent.ResourcePriority.VeryHigh: return "#f00";
}
return null;
},
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} events
*/
_appendTimelineData: function(events)
{
this._minimumBoundary = this._model.minimumRecordTime();
this._maximumBoundary = this._model.maximumRecordTime();
this._timeSpan = this._model.isEmpty() ? 1000 : this._maximumBoundary - this._minimumBoundary;
this._model.networkRequests().forEach(this._appendEntry.bind(this));
this._updateTimelineData();
},
_updateTimelineData: function()
{
if (!this._timelineData)
return;
var index = -1;
var lastTime = Infinity;
for (var i = 0; i < this._requests.length; ++i) {
var r = this._requests[i];
var visible = r.startTime < this._endTime && r.endTime > this._startTime;
if (!visible) {
this._timelineData.entryLevels[i] = -1;
continue;
}
if (lastTime > r.startTime)
++index;
lastTime = r.endTime;
this._timelineData.entryLevels[i] = index;
}
++index;
for (var i = 0; i < this._requests.length; ++i) {
if (this._timelineData.entryLevels[i] === -1)
this._timelineData.entryLevels[i] = index;
}
this._timelineData = new WebInspector.FlameChart.TimelineData(
this._timelineData.entryLevels,
this._timelineData.entryTotalTimes,
this._timelineData.entryStartTimes,
null);
this._currentLevel = index;
},
/**
* @param {!WebInspector.TimelineModel.NetworkRequest} request
*/
_appendEntry: function(request)
{
this._requests.push(request);
this._timelineData.entryStartTimes.push(request.startTime);
this._timelineData.entryTotalTimes.push(request.endTime - request.startTime);
this._timelineData.entryLevels.push(this._requests.length - 1);
},
__proto__: WebInspector.TimelineFlameChartDataProviderBase.prototype
}
/**
* @constructor
* @implements {WebInspector.FlameChartMarker}
* @param {number} startTime
* @param {number} startOffset
* @param {!WebInspector.TimelineMarkerStyle} style
*/
WebInspector.TimelineFlameChartMarker = function(startTime, startOffset, style)
{
this._startTime = startTime;
this._startOffset = startOffset;
this._style = style;
}
WebInspector.TimelineFlameChartMarker.prototype = {
/**
* @override
* @return {number}
*/
startTime: function()
{
return this._startTime;
},
/**
* @override
* @return {string}
*/
color: function()
{
return this._style.color;
},
/**
* @override
* @return {string}
*/
title: function()
{
var startTime = Number.millisToString(this._startOffset);
return WebInspector.UIString("%s at %s", this._style.title, startTime);
},
/**
* @override
* @param {!CanvasRenderingContext2D} context
* @param {number} x
* @param {number} height
* @param {number} pixelsPerMillisecond
*/
draw: function(context, x, height, pixelsPerMillisecond)
{
var lowPriorityVisibilityThresholdInPixelsPerMs = 4;
if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs)
return;
context.save();
if (!this._style.lowPriority) {
context.strokeStyle = this._style.color;
context.lineWidth = 2;
context.beginPath();
context.moveTo(x, 0);
context.lineTo(x, height);
context.stroke();
}
if (this._style.tall) {
context.strokeStyle = this._style.color;
context.lineWidth = this._style.lineWidth;
context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5);
context.beginPath();
context.moveTo(x, height);
context.setLineDash(this._style.dashStyle);
context.lineTo(x, context.canvas.height);
context.stroke();
}
context.restore();
}
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TimelineModeView}
* @implements {WebInspector.FlameChartDelegate}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} timelineModel
* @param {!WebInspector.TimelineFrameModelBase} frameModel
* @param {!WebInspector.TimelineIRModel} irModel
*/
WebInspector.TimelineFlameChartView = function(delegate, timelineModel, frameModel, irModel)
{
WebInspector.VBox.call(this);
this.element.classList.add("timeline-flamechart");
this._delegate = delegate;
this._model = timelineModel;
this._splitWidget = new WebInspector.SplitWidget(false, false, "timelineFlamechartMainView", 150);
this._dataProvider = new WebInspector.TimelineFlameChartDataProvider(this._model, frameModel, irModel);
var mainViewGroupExpansionSetting = WebInspector.settings.createSetting("timelineFlamechartMainViewGroupExpansion", {});
this._mainView = new WebInspector.FlameChart(this._dataProvider, this, mainViewGroupExpansionSetting);
this._networkDataProvider = new WebInspector.TimelineFlameChartNetworkDataProvider(this._model);
this._networkView = new WebInspector.FlameChart(this._networkDataProvider, this);
if (Runtime.experiments.isEnabled("networkRequestsOnTimeline")) {
this._splitWidget.setMainWidget(this._mainView);
this._splitWidget.setSidebarWidget(this._networkView);
this._splitWidget.show(this.element);
} else {
this._mainView.show(this.element);
}
this._onMainEntrySelected = this._onEntrySelected.bind(this, this._dataProvider);
this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider);
this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
this._networkView.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
WebInspector.blackboxManager.addChangeListener(this.refreshRecords, this);
}
WebInspector.TimelineFlameChartView.prototype = {
/**
* @override
*/
dispose: function()
{
this._mainView.removeEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
this._networkView.removeEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
WebInspector.blackboxManager.removeChangeListener(this.refreshRecords, this);
},
/**
* @override
* @return {?Element}
*/
resizerElement: function()
{
return null;
},
/**
* @override
* @param {number} windowStartTime
* @param {number} windowEndTime
*/
requestWindowTimes: function(windowStartTime, windowEndTime)
{
this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
*/
updateRangeSelection: function(startTime, endTime)
{
this._delegate.select(WebInspector.TimelineSelection.fromRange(startTime, endTime));
},
/**
* @override
*/
endRangeSelection: function()
{
if (Runtime.experiments.isEnabled("multipleTimelineViews"))
this._delegate.select(null);
},
/**
* @override
*/
refreshRecords: function()
{
this._dataProvider.reset();
this._mainView.scheduleUpdate();
this._networkDataProvider.reset();
this._networkView.scheduleUpdate();
},
/**
* @override
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event)
{
var entryIndex = event ? this._dataProvider.entryIndexForSelection(WebInspector.TimelineSelection.fromTraceEvent(event)) : -1;
if (entryIndex >= 0)
this._mainView.highlightEntry(entryIndex);
else
this._mainView.hideHighlight();
},
/**
* @override
*/
wasShown: function()
{
this._mainView.scheduleUpdate();
this._networkView.scheduleUpdate();
},
/**
* @override
* @return {!WebInspector.Widget}
*/
view: function()
{
return this;
},
/**
* @override
*/
reset: function()
{
this._dataProvider.reset();
this._mainView.reset();
this._mainView.setWindowTimes(0, Infinity);
this._networkDataProvider.reset();
this._networkView.reset();
this._networkView.setWindowTimes(0, Infinity);
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
*/
setWindowTimes: function(startTime, endTime)
{
this._mainView.setWindowTimes(startTime, endTime);
this._networkView.setWindowTimes(startTime, endTime);
this._networkDataProvider.setWindowTimes(startTime, endTime);
},
/**
* @override
* @param {?WebInspector.TimelineModel.Record} record
* @param {string=} regex
* @param {boolean=} selectRecord
*/
highlightSearchResult: function(record, regex, selectRecord)
{
if (!record) {
this._delegate.select(null);
return;
}
var traceEvent = record.traceEvent();
var entryIndex = this._dataProvider._entryData.indexOf(traceEvent);
var timelineSelection = this._dataProvider.createSelection(entryIndex);
if (timelineSelection)
this._delegate.select(timelineSelection);
},
/**
* @override
* @param {?WebInspector.TimelineSelection} selection
*/
setSelection: function(selection)
{
var index = this._dataProvider.entryIndexForSelection(selection);
this._mainView.setSelectedEntry(index);
index = this._networkDataProvider.entryIndexForSelection(selection);
this._networkView.setSelectedEntry(index);
},
/**
* @param {!WebInspector.FlameChartDataProvider} dataProvider
* @param {!WebInspector.Event} event
*/
_onEntrySelected: function(dataProvider, event)
{
var entryIndex = /** @type{number} */ (event.data);
this._delegate.select(dataProvider.createSelection(entryIndex));
},
/**
* @param {boolean} enable
* @param {boolean=} animate
*/
enableNetworkPane: function(enable, animate)
{
if (enable)
this._splitWidget.showBoth(animate);
else
this._splitWidget.hideSidebar(animate);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {!WebInspector.TimelineSelection} selection
* @param {number} entryIndex
*/
WebInspector.TimelineFlameChartView.Selection = function(selection, entryIndex)
{
this.timelineSelection = selection;
this.entryIndex = entryIndex;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | 2 1 1 1 1 1 1 1 1 1 1 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.TimelineFrameModelBase = function() { this.reset(); } WebInspector.TimelineFrameModelBase.prototype = { /** * @return {!Array.<!WebInspector.TimelineFrame>} */ frames: function() { return this._frames; }, /** * @param {number} startTime * @param {number} endTime * @return {!Array.<!WebInspector.TimelineFrame>} */ filteredFrames: function(startTime, endTime) { /** * @param {number} value * @param {!WebInspector.TimelineFrame} object * @return {number} */ function compareStartTime(value, object) { return value - object.startTime; } /** * @param {number} value * @param {!WebInspector.TimelineFrame} object * @return {number} */ function compareEndTime(value, object) { return value - object.endTime; } var frames = this._frames; var firstFrame = frames.lowerBound(startTime, compareEndTime); var lastFrame = frames.lowerBound(endTime, compareStartTime); return frames.slice(firstFrame, lastFrame); }, /** * @param {!WebInspector.TracingModel.Event} rasterTask * @return {boolean} */ hasRasterTile: function(rasterTask) { var data = rasterTask.args["tileData"]; if (!data) return false; var frameId = data["sourceFrameNumber"]; var frame = frameId && this._frameById[frameId]; if (!frame || !frame.layerTree) return false; return true; }, /** * @param {!WebInspector.TracingModel.Event} rasterTask * @param {function(?DOMAgent.Rect, ?WebInspector.PaintProfilerSnapshot)} callback */ requestRasterTile: function(rasterTask, callback) { var target = this._target; if (!target) { callback(null, null); return; } var data = rasterTask.args["tileData"]; var frameId = data["sourceFrameNumber"]; var frame = frameId && this._frameById[frameId]; if (!frame || !frame.layerTree) { callback(null, null); return; } var tileId = data["tileId"] && data["tileId"]["id_ref"]; /** @type {!Array.<!WebInspector.PictureFragment>}> */ var fragments = []; /** @type {?WebInspector.TracingLayerTile} */ var tile = null; var x0 = Infinity; var y0 = Infinity; frame.layerTree.resolve(layerTreeResolved); /** * @param {!WebInspector.LayerTreeBase} layerTree */ function layerTreeResolved(layerTree) { tile = tileId && (/** @type {!WebInspector.TracingLayerTree} */ (layerTree)).tileById("cc::Tile/" + tileId); if (!tile) { console.error("Tile " + tileId + " missing in frame " + frameId); callback(null, null); return; } var fetchPictureFragmentsBarrier = new CallbackBarrier(); for (var paint of frame.paints) { if (tile.layer_id === paint.layerId()) paint.loadPicture(fetchPictureFragmentsBarrier.createCallback(pictureLoaded)); } fetchPictureFragmentsBarrier.callWhenDone(allPicturesLoaded); } /** * @param {number} a1 * @param {number} a2 * @param {number} b1 * @param {number} b2 * @return {boolean} */ function segmentsOverlap(a1, a2, b1, b2) { console.assert(a1 <= a2 && b1 <= b2, "segments should be specified as ordered pairs"); return a2 > b1 && a1 < b2; } /** * @param {!Array.<number>} a * @param {!Array.<number>} b * @return {boolean} */ function rectsOverlap(a, b) { return segmentsOverlap(a[0], a[0] + a[2], b[0], b[0] + b[2]) && segmentsOverlap(a[1], a[1] + a[3], b[1], b[1] + b[3]); } /** * @param {?Array.<number>} rect * @param {?string} picture */ function pictureLoaded(rect, picture) { if (!rect || !picture) return; if (!rectsOverlap(rect, tile.content_rect)) return; var x = rect[0]; var y = rect[1]; x0 = Math.min(x0, x); y0 = Math.min(y0, y); fragments.push({x: x, y: y, picture: picture}); } function allPicturesLoaded() { if (!fragments.length) { callback(null, null); return; } var rectArray = tile.content_rect; // Rect is in layer content coordinates, make it relative to picture by offsetting to the top left corner. var rect = {x: rectArray[0] - x0, y: rectArray[1] - y0, width: rectArray[2], height: rectArray[3]}; WebInspector.PaintProfilerSnapshot.loadFromFragments(target, fragments, callback.bind(null, rect)); } }, reset: function() { this._minimumRecordTime = Infinity; this._frames = []; this._frameById = {}; this._lastFrame = null; this._lastLayerTree = null; this._mainFrameCommitted = false; this._mainFrameRequested = false; this._framePendingCommit = null; this._lastBeginFrame = null; this._lastNeedsBeginFrame = null; this._framePendingActivation = null; this._lastTaskBeginTime = null; }, /** * @param {number} startTime */ handleBeginFrame: function(startTime) { if (!this._lastFrame) this._startFrame(startTime); this._lastBeginFrame = startTime; }, /** * @param {number} startTime */ handleDrawFrame: function(startTime) { if (!this._lastFrame) { this._startFrame(startTime); return; } // - if it wasn't drawn, it didn't happen! // - only show frames that either did not wait for the main thread frame or had one committed. if (this._mainFrameCommitted || !this._mainFrameRequested) { if (this._lastNeedsBeginFrame) { var idleTimeEnd = this._framePendingActivation ? this._framePendingActivation.triggerTime : (this._lastBeginFrame || this._lastNeedsBeginFrame); if (idleTimeEnd > this._lastFrame.startTime) { this._lastFrame.idle = true; this._startFrame(idleTimeEnd); if (this._framePendingActivation) this._commitPendingFrame(); this._lastBeginFrame = null; } this._lastNeedsBeginFrame = null; } this._startFrame(startTime); } this._mainFrameCommitted = false; }, handleActivateLayerTree: function() { if (!this._lastFrame) return; if (this._framePendingActivation && !this._lastNeedsBeginFrame) this._commitPendingFrame(); }, handleRequestMainThreadFrame: function() { if (!this._lastFrame) return; this._mainFrameRequested = true; }, handleCompositeLayers: function() { if (!this._framePendingCommit) return; this._framePendingActivation = this._framePendingCommit; this._framePendingCommit = null; this._mainFrameRequested = false; this._mainFrameCommitted = true; }, /** * @param {!WebInspector.DeferredLayerTree} layerTree */ handleLayerTreeSnapshot: function(layerTree) { this._lastLayerTree = layerTree; }, /** * @param {number} startTime * @param {boolean} needsBeginFrame */ handleNeedFrameChanged: function(startTime, needsBeginFrame) { if (needsBeginFrame) this._lastNeedsBeginFrame = startTime; }, /** * @param {number} startTime */ _startFrame: function(startTime) { if (this._lastFrame) this._flushFrame(this._lastFrame, startTime); this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this._minimumRecordTime); }, /** * @param {!WebInspector.TimelineFrame} frame * @param {number} endTime */ _flushFrame: function(frame, endTime) { frame._setLayerTree(this._lastLayerTree); frame._setEndTime(endTime); if (this._frames.length && (frame.startTime !== this._frames.peekLast().endTime || frame.startTime > frame.endTime)) console.assert(false, `Inconsistent frame time for frame ${this._frames.length} (${frame.startTime} - ${frame.endTime})`); this._frames.push(frame); if (typeof frame._mainFrameId === "number") this._frameById[frame._mainFrameId] = frame; }, _commitPendingFrame: function() { this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCategory); this._lastFrame.paints = this._framePendingActivation.paints; this._lastFrame._mainFrameId = this._framePendingActivation.mainFrameId; this._framePendingActivation = null; }, /** * @param {!Array.<string>} types * @param {!WebInspector.TimelineModel.Record} record * @return {?WebInspector.TimelineModel.Record} record */ _findRecordRecursively: function(types, record) { if (types.indexOf(record.type()) >= 0) return record; if (!record.children()) return null; for (var i = 0; i < record.children().length; ++i) { var result = this._findRecordRecursively(types, record.children()[i]); if (result) return result; } return null; } } /** * @constructor * @extends {WebInspector.TimelineFrameModelBase} */ WebInspector.TracingTimelineFrameModel = function() { WebInspector.TimelineFrameModelBase.call(this); } WebInspector.TracingTimelineFrameModel._mainFrameMarkers = [ WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation, WebInspector.TimelineModel.RecordType.InvalidateLayout, WebInspector.TimelineModel.RecordType.BeginMainThreadFrame, WebInspector.TimelineModel.RecordType.ScrollLayer ]; WebInspector.TracingTimelineFrameModel.prototype = { reset: function() { WebInspector.TimelineFrameModelBase.prototype.reset.call(this); this._target = null; this._sessionId = null; this._currentTaskTimeByCategory = {}; }, /** * @param {?WebInspector.Target} target * @param {!Array.<!WebInspector.TracingModel.Event>} events * @param {string} sessionId */ addTraceEvents: function(target, events, sessionId) { this._target = target; this._sessionId = sessionId; if (!events.length) return; if (events[0].startTime < this._minimumRecordTime) this._minimumRecordTime = events[0].startTime; for (var i = 0; i < events.length; ++i) this._addTraceEvent(events[i]); }, /** * @param {!WebInspector.TracingModel.Event} event */ _addTraceEvent: function(event) { var eventNames = WebInspector.TimelineModel.RecordType; if (event.name === eventNames.SetLayerTreeId) { var sessionId = event.args["sessionId"] || event.args["data"]["sessionId"]; if (this._sessionId === sessionId) this._layerTreeId = event.args["layerTreeId"] || event.args["data"]["layerTreeId"]; } else if (event.name === eventNames.TracingStartedInPage) { this._mainThread = event.thread; } else if (event.phase === WebInspector.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0) === this._layerTreeId) { var snapshot = /** @type {!WebInspector.TracingModel.ObjectSnapshot} */ (event); this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(snapshot, this._target)); } else { this._processCompositorEvents(event); if (event.thread === this._mainThread) this._addMainThreadTraceEvent(event); else if (this._lastFrame && event.selfTime && !WebInspector.TracingModel.isTopLevelEvent(event)) this._lastFrame._addTimeForCategory(WebInspector.TimelineUIUtils.eventStyle(event).category.name, event.selfTime); } }, /** * @param {!WebInspector.TracingModel.Event} event */ _processCompositorEvents: function(event) { var eventNames = WebInspector.TimelineModel.RecordType; if (event.args["layerTreeId"] !== this._layerTreeId) return; var timestamp = event.startTime; if (event.name === eventNames.BeginFrame) this.handleBeginFrame(timestamp); else if (event.name === eventNames.DrawFrame) this.handleDrawFrame(timestamp); else if (event.name === eventNames.ActivateLayerTree) this.handleActivateLayerTree(); else if (event.name === eventNames.RequestMainThreadFrame) this.handleRequestMainThreadFrame(); else if (event.name === eventNames.NeedsBeginFrameChanged) this.handleNeedFrameChanged(timestamp, event.args["data"] && event.args["data"]["needsBeginFrame"]); }, /** * @param {!WebInspector.TracingModel.Event} event */ _addMainThreadTraceEvent: function(event) { var eventNames = WebInspector.TimelineModel.RecordType; var timestamp = event.startTime; var selfTime = event.selfTime || 0; if (WebInspector.TracingModel.isTopLevelEvent(event)) { this._currentTaskTimeByCategory = {}; this._lastTaskBeginTime = event.startTime; } if (!this._framePendingCommit && WebInspector.TracingTimelineFrameModel._mainFrameMarkers.indexOf(event.name) >= 0) this._framePendingCommit = new WebInspector.PendingFrame(this._lastTaskBeginTime || event.startTime, this._currentTaskTimeByCategory); if (!this._framePendingCommit) { this._addTimeForCategory(this._currentTaskTimeByCategory, event); return; } this._addTimeForCategory(this._framePendingCommit.timeByCategory, event); if (event.name === eventNames.BeginMainThreadFrame && event.args["data"] && event.args["data"]["frameId"]) this._framePendingCommit.mainFrameId = event.args["data"]["frameId"]; if (event.name === eventNames.Paint && event.args["data"]["layerId"] && event.picture && this._target) this._framePendingCommit.paints.push(new WebInspector.LayerPaintEvent(event, this._target)); if (event.name === eventNames.CompositeLayers && event.args["layerTreeId"] === this._layerTreeId) this.handleCompositeLayers(); }, /** * @param {!Object.<string, number>} timeByCategory * @param {!WebInspector.TracingModel.Event} event */ _addTimeForCategory: function(timeByCategory, event) { if (!event.selfTime) return; var categoryName = WebInspector.TimelineUIUtils.eventStyle(event).category.name; timeByCategory[categoryName] = (timeByCategory[categoryName] || 0) + event.selfTime; }, __proto__: WebInspector.TimelineFrameModelBase.prototype } /** * @constructor * @extends {WebInspector.DeferredLayerTree} * @param {!WebInspector.TracingModel.ObjectSnapshot} snapshot * @param {?WebInspector.Target} target */ WebInspector.DeferredTracingLayerTree = function(snapshot, target) { WebInspector.DeferredLayerTree.call(this, target); this._snapshot = snapshot; } WebInspector.DeferredTracingLayerTree.prototype = { /** * @override * @param {function(!WebInspector.LayerTreeBase)} callback */ resolve: function(callback) { this._snapshot.requestObject(onGotObject.bind(this)); /** * @this {WebInspector.DeferredTracingLayerTree} * @param {?Object} result */ function onGotObject(result) { if (!result) return; var viewport = result["device_viewport_size"]; var tiles = result["active_tiles"]; var rootLayer = result["active_tree"]["root_layer"]; var layerTree = new WebInspector.TracingLayerTree(this._target); layerTree.setViewportSize(viewport); layerTree.setTiles(tiles); layerTree.setLayers(rootLayer, callback.bind(null, layerTree)); } }, __proto__: WebInspector.DeferredLayerTree.prototype }; /** * @constructor * @param {number} startTime * @param {number} startTimeOffset */ WebInspector.TimelineFrame = function(startTime, startTimeOffset) { this.startTime = startTime; this.startTimeOffset = startTimeOffset; this.endTime = this.startTime; this.duration = 0; this.timeByCategory = {}; this.cpuTime = 0; this.idle = false; /** @type {?WebInspector.DeferredLayerTree} */ this.layerTree = null; /** @type {!Array.<!WebInspector.LayerPaintEvent>} */ this.paints = []; /** @type {number|undefined} */ this._mainFrameId = undefined; } WebInspector.TimelineFrame.prototype = { /** * @return {boolean} */ hasWarnings: function() { var /** @const */ longFrameDurationThresholdMs = 22; return !this.idle && this.duration > longFrameDurationThresholdMs; }, /** * @param {number} endTime */ _setEndTime: function(endTime) { this.endTime = endTime; this.duration = this.endTime - this.startTime; }, /** * @param {?WebInspector.DeferredLayerTree} layerTree */ _setLayerTree: function(layerTree) { this.layerTree = layerTree; }, /** * @param {!Object} timeByCategory */ _addTimeForCategories: function(timeByCategory) { for (var category in timeByCategory) this._addTimeForCategory(category, timeByCategory[category]); }, /** * @param {string} category * @param {number} time */ _addTimeForCategory: function(category, time) { this.timeByCategory[category] = (this.timeByCategory[category] || 0) + time; this.cpuTime += time; }, } /** * @constructor * @param {!WebInspector.TracingModel.Event} event * @param {?WebInspector.Target} target */ WebInspector.LayerPaintEvent = function(event, target) { this._event = event; this._target = target; } WebInspector.LayerPaintEvent.prototype = { /** * @return {string} */ layerId: function() { return this._event.args["data"]["layerId"]; }, /** * @return {!WebInspector.TracingModel.Event} */ event: function() { return this._event; }, /** * @param {function(?Array.<number>, ?string)} callback */ loadPicture: function(callback) { this._event.picture.requestObject(onGotObject); /** * @param {?Object} result */ function onGotObject(result) { if (!result || !result["skp64"]) { callback(null, null); return; } var rect = result["params"] && result["params"]["layer_rect"]; callback(rect, result["skp64"]); } }, /** * @param {function(?Array.<number>, ?WebInspector.PaintProfilerSnapshot)} callback */ loadSnapshot: function(callback) { this.loadPicture(onGotPicture.bind(this)); /** * @param {?Array.<number>} rect * @param {?string} picture * @this {WebInspector.LayerPaintEvent} */ function onGotPicture(rect, picture) { if (!rect || !picture || !this._target) { callback(null, null); return; } WebInspector.PaintProfilerSnapshot.load(this._target, picture, callback.bind(null, rect)); } } }; /** * @constructor * @param {number} triggerTime * @param {!Object.<string, number>} timeByCategory */ WebInspector.PendingFrame = function(triggerTime, timeByCategory) { /** @type {!Object.<string, number>} */ this.timeByCategory = timeByCategory; /** @type {!Array.<!WebInspector.LayerPaintEvent>} */ this.paints = []; /** @type {number|undefined} */ this.mainFrameId = undefined; this.triggerTime = triggerTime; } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | 2 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.TimelineIRModel = function() { this.reset(); } /** * @enum {string} */ WebInspector.TimelineIRModel.Phases = { Idle: "Idle", Response: "Response", Scroll: "Scroll", Fling: "Fling", Drag: "Drag", Animation: "Animation" }; /** * @enum {string} */ WebInspector.TimelineIRModel.InputEvents = { Char: "Char", Click: "GestureClick", ContextMenu: "ContextMenu", FlingCancel: "GestureFlingCancel", FlingStart: "GestureFlingStart", ImplSideFling: WebInspector.TimelineModel.RecordType.ImplSideFling, KeyDown: "KeyDown", KeyDownRow: "RawKeyDown", KeyUp: "KeyUp", LatencyScrollUpdate: "ScrollUpdate", MouseDown: "MouseDown", MouseMove: "MouseMove", MouseUp: "MouseUp", MouseWheel: "MouseWheel", PinchBegin: "GesturePinchBegin", PinchEnd: "GesturePinchEnd", PinchUpdate: "GesturePinchUpdate", ScrollBegin: "GestureScrollBegin", ScrollEnd: "GestureScrollEnd", ScrollUpdate: "GestureScrollUpdate", ScrollUpdateRenderer: "ScrollUpdate", ShowPress: "GestureShowPress", Tap: "GestureTap", TapCancel: "GestureTapCancel", TapDown: "GestureTapDown", TouchCancel: "TouchCancel", TouchEnd: "TouchEnd", TouchMove: "TouchMove", TouchStart: "TouchStart" }; WebInspector.TimelineIRModel._mergeThresholdsMs = { animation: 1, mouse: 40, }; WebInspector.TimelineIRModel.prototype = { /** * @param {!WebInspector.TimelineModel} timelineModel */ populate: function(timelineModel) { var eventTypes = WebInspector.TimelineIRModel.InputEvents; var phases = WebInspector.TimelineIRModel.Phases; this.reset(); var groups = WebInspector.TimelineUIUtils.asyncEventGroups(); var asyncEventsByGroup = timelineModel.mainThreadAsyncEvents(); var inputLatencies = asyncEventsByGroup.get(groups.input); if (!inputLatencies) return; this._processInputLatencies(inputLatencies); var animations = asyncEventsByGroup.get(groups.animation); if (animations) this._processAnimations(animations); var range = new WebInspector.SegmentedRange(); range.appendRange(this._drags); // Drags take lower precedence than animation, as we can't detect them reliably. range.appendRange(this._cssAnimations); range.appendRange(this._scrolls); range.appendRange(this._responses); this._segments = range.segments(); }, /** * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events */ _processInputLatencies: function(events) { var eventTypes = WebInspector.TimelineIRModel.InputEvents; var phases = WebInspector.TimelineIRModel.Phases; var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; var flingStart; var touchStart; var firstTouchMove; var mouseWheel; var mouseDown; var mouseMove; for (var i = 0; i < events.length; ++i) { var event = events[i]; if (i > 0 && events[i].startTime < events[i - 1].startTime) console.assert(false, "Unordered input events"); var type = this._inputEventType(event.name); switch (type) { case eventTypes.ScrollUpdate: touchStart = null; // Since we're scrolling now, disregard other touch gestures. this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); break; case eventTypes.FlingStart: if (flingStart) { WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s", flingStart.startTime, event.startTime)); break; } flingStart = event; break; case eventTypes.FlingCancel: // FIXME: also process renderer fling events. if (!flingStart) break; this._scrolls.append(new WebInspector.Segment(flingStart.startTime, event.endTime, phases.Fling)); flingStart = null; break; case eventTypes.ImplSideFling: this._scrolls.append(this._segmentForEvent(event, phases.Fling)); break; case eventTypes.ShowPress: case eventTypes.Tap: case eventTypes.KeyDown: case eventTypes.KeyDownRow: case eventTypes.KeyUp: case eventTypes.Char: case eventTypes.Click: case eventTypes.ContextMenu: this._responses.append(this._segmentForEvent(event, phases.Response)); break; case eventTypes.TouchStart: // We do not produce any response segment for TouchStart -- there's either going to be one upon // TouchMove for drag, or one for GestureTap. if (touchStart) { WebInspector.console.error(WebInspector.UIString("Two touches at the same time? %s vs %s", touchStart.startTime, event.startTime)); break; } touchStart = event; firstTouchMove = null; break; case eventTypes.TouchCancel: touchStart = null; break; case eventTypes.TouchMove: if (firstTouchMove) { this._drags.append(this._segmentForEvent(event, phases.Drag)); } else if (touchStart) { firstTouchMove = event; this._responses.append(new WebInspector.Segment(touchStart.startTime, event.endTime, phases.Response)); } break; case eventTypes.TouchEnd: touchStart = null; break; case eventTypes.MouseDown: mouseDown = event; mouseMove = null; break; case eventTypes.MouseMove: if (mouseDown && !mouseMove && mouseDown.startTime + thresholdsMs.mouse > event.startTime) { this._responses.append(this._segmentForEvent(mouseDown, phases.Response)); this._responses.append(this._segmentForEvent(event, phases.Response)); } else if (mouseDown) { this._drags.append(this._segmentForEvent(event, phases.Drag)); } mouseMove = event; break; case eventTypes.MouseUp: this._responses.append(this._segmentForEvent(event, phases.Response)); mouseDown = null; break; case eventTypes.MouseWheel: // Do not consider first MouseWheel as trace viewer's implementation does -- in case of MouseWheel it's not really special. if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event)) this._scrolls.append(new WebInspector.Segment(mouseWheel.endTime, event.startTime, phases.Scroll)); this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); mouseWheel = event; break; } } /** * @param {number} threshold * @param {!WebInspector.TracingModel.AsyncEvent} first * @param {!WebInspector.TracingModel.AsyncEvent} second * @return {boolean} */ function canMerge(threshold, first, second) { return first.endTime < second.startTime && second.startTime < first.endTime + threshold; } }, /** * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events */ _processAnimations: function(events) { for (var i = 0; i < events.length; ++i) this._cssAnimations.append(this._segmentForEvent(events[i], WebInspector.TimelineIRModel.Phases.Animation)); }, /** * @param {!WebInspector.TracingModel.AsyncEvent} event * @param {!WebInspector.TimelineIRModel.Phases} phase * @return {!WebInspector.Segment} */ _segmentForEvent: function(event, phase) { return new WebInspector.Segment(event.startTime, event.endTime, phase); }, /** * @return {!Array<!WebInspector.Segment>} */ interactionRecords: function() { return this._segments; }, reset: function() { var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; this._segments = []; this._drags = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.mouse)); this._cssAnimations = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.animation)); this._responses = new WebInspector.SegmentedRange(merge.bind(null, 0)); this._scrolls = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.animation)); /** * @param {number} threshold * @param {!WebInspector.Segment} first * @param {!WebInspector.Segment} second */ function merge(threshold, first, second) { return first.end + threshold >= second.begin && first.data === second.data ? first : null; } }, /** * @param {string} eventName * @return {?WebInspector.TimelineIRModel.InputEvents} */ _inputEventType: function(eventName) { var prefix = "InputLatency::"; if (!eventName.startsWith(prefix)) { if (eventName === WebInspector.TimelineIRModel.InputEvents.ImplSideFling) return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName); console.error("Unrecognized input latency event: " + eventName); return null; } return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName.substr(prefix.length)); } }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | 2 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.TimelineJSProfileProcessor = { };
/**
* @param {!WebInspector.CPUProfileDataModel} jsProfileModel
* @param {!WebInspector.TracingModel.Thread} thread
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(jsProfileModel, thread)
{
var idleNode = jsProfileModel.idleNode;
var programNode = jsProfileModel.programNode;
var gcNode = jsProfileModel.gcNode;
var samples = jsProfileModel.samples;
var timestamps = jsProfileModel.timestamps;
var jsEvents = [];
/** @type {!Map<!Object, !Array<!RuntimeAgent.CallFrame>>} */
var nodeToStackMap = new Map();
nodeToStackMap.set(programNode, []);
for (var i = 0; i < samples.length; ++i) {
var node = jsProfileModel.nodeByIndex(i);
if (node === gcNode || node === idleNode)
continue;
var callFrames = nodeToStackMap.get(node);
if (!callFrames) {
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (new Array(node.depth + 1));
nodeToStackMap.set(node, callFrames);
for (var j = 0; node.parent; node = node.parent)
callFrames[j++] = /** @type {!RuntimeAgent.CallFrame} */ (node);
}
var jsSampleEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,
WebInspector.TimelineModel.RecordType.JSSample,
WebInspector.TracingModel.Phase.Instant, timestamps[i], thread);
jsSampleEvent.args["data"] = { stackTrace: callFrames };
jsEvents.push(jsSampleEvent);
}
return jsEvents;
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents = function(events)
{
/**
* @param {!RuntimeAgent.CallFrame} frame1
* @param {!RuntimeAgent.CallFrame} frame2
* @return {boolean}
*/
function equalFrames(frame1, frame2)
{
return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName;
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @return {number}
*/
function eventEndTime(e)
{
return e.endTime || e.startTime;
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @return {boolean}
*/
function isJSInvocationEvent(e)
{
switch (e.name) {
case WebInspector.TimelineModel.RecordType.FunctionCall:
case WebInspector.TimelineModel.RecordType.EvaluateScript:
return true;
}
return false;
}
var jsFrameEvents = [];
var jsFramesStack = [];
var lockedJsStackDepth = [];
var ordinal = 0;
var filterNativeFunctions = !WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onStartEvent(e)
{
e.ordinal = ++ordinal;
extractStackTrace(e);
// For the duration of the event we cannot go beyond the stack associated with it.
lockedJsStackDepth.push(jsFramesStack.length);
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @param {?WebInspector.TracingModel.Event} parent
*/
function onInstantEvent(e, parent)
{
e.ordinal = ++ordinal;
if (parent && isJSInvocationEvent(parent))
extractStackTrace(e);
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEndEvent(e)
{
truncateJSStack(lockedJsStackDepth.pop(), e.endTime);
}
/**
* @param {number} depth
* @param {number} time
*/
function truncateJSStack(depth, time)
{
if (lockedJsStackDepth.length) {
var lockedDepth = lockedJsStackDepth.peekLast();
if (depth < lockedDepth) {
console.error("Child stack is shallower (" + depth + ") than the parent stack (" + lockedDepth + ") at " + time);
depth = lockedDepth;
}
}
if (jsFramesStack.length < depth) {
console.error("Trying to truncate higher than the current stack size at " + time);
depth = jsFramesStack.length;
}
for (var k = 0; k < jsFramesStack.length; ++k)
jsFramesStack[k].setEndTime(time);
jsFramesStack.length = depth;
}
/**
* @param {!Array<!RuntimeAgent.CallFrame>} stack
*/
function filterStackFrames(stack)
{
for (var i = 0, j = 0; i < stack.length; ++i) {
var url = stack[i].url;
if (url && url.startsWith("native "))
continue;
stack[j++] = stack[i];
}
stack.length = j;
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function extractStackTrace(e)
{
var recordTypes = WebInspector.TimelineModel.RecordType;
var callFrames;
if (e.name === recordTypes.JSSample) {
var eventData = e.args["data"] || e.args["beginData"];
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (eventData && eventData["stackTrace"]);
} else {
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (jsFramesStack.map(frameEvent => frameEvent.args["data"]).reverse());
}
if (filterNativeFunctions)
filterStackFrames(callFrames);
var endTime = eventEndTime(e);
var numFrames = callFrames.length;
var minFrames = Math.min(numFrames, jsFramesStack.length);
var i;
for (i = lockedJsStackDepth.peekLast() || 0; i < minFrames; ++i) {
var newFrame = callFrames[numFrames - 1 - i];
var oldFrame = jsFramesStack[i].args["data"];
if (!equalFrames(newFrame, oldFrame))
break;
jsFramesStack[i].setEndTime(Math.max(jsFramesStack[i].endTime, endTime));
}
truncateJSStack(i, e.startTime);
for (; i < numFrames; ++i) {
var frame = callFrames[numFrames - 1 - i];
var jsFrameEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory, recordTypes.JSFrame,
WebInspector.TracingModel.Phase.Complete, e.startTime, e.thread);
jsFrameEvent.ordinal = e.ordinal;
jsFrameEvent.addArgs({ data: frame });
jsFrameEvent.setEndTime(endTime);
jsFramesStack.push(jsFrameEvent);
jsFrameEvents.push(jsFrameEvent);
}
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {?WebInspector.TracingModel.Event}
*/
function findFirstTopLevelEvent(events)
{
for (var i = 0; i < events.length; ++i) {
if (WebInspector.TracingModel.isTopLevelEvent(events[i]))
return events[i];
}
return null;
}
var firstTopLevelEvent = findFirstTopLevelEvent(events);
if (firstTopLevelEvent)
WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent, firstTopLevelEvent.startTime);
return jsFrameEvents;
}
/**
* @constructor
*/
WebInspector.TimelineJSProfileProcessor.CodeMap = function()
{
/** @type {!Map<string, !WebInspector.TimelineJSProfileProcessor.CodeMap.Bank>} */
this._banks = new Map();
}
/**
* @constructor
* @param {number} address
* @param {number} size
* @param {!RuntimeAgent.CallFrame} callFrame
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.Entry = function(address, size, callFrame)
{
this.address = address;
this.size = size;
this.callFrame = callFrame;
}
/**
* @param {number} address
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} entry
* @return {number}
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.comparator = function(address, entry)
{
return address - entry.address;
}
WebInspector.TimelineJSProfileProcessor.CodeMap.prototype = {
/**
* @param {string} addressHex
* @param {number} size
* @param {!RuntimeAgent.CallFrame} callFrame
*/
addEntry: function(addressHex, size, callFrame)
{
var entry = new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry(this._getAddress(addressHex), size, callFrame);
this._addEntry(addressHex, entry);
},
/**
* @param {string} oldAddressHex
* @param {string} newAddressHex
* @param {number} size
*/
moveEntry: function(oldAddressHex, newAddressHex, size)
{
var entry = this._getBank(oldAddressHex).removeEntry(this._getAddress(oldAddressHex));
if (!entry) {
console.error("Entry at address " + oldAddressHex + " not found");
return;
}
entry.address = this._getAddress(newAddressHex);
entry.size = size;
this._addEntry(newAddressHex, entry);
},
/**
* @param {string} addressHex
* @return {?RuntimeAgent.CallFrame}
*/
lookupEntry: function(addressHex)
{
return this._getBank(addressHex).lookupEntry(this._getAddress(addressHex));
},
/**
* @param {string} addressHex
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} entry
*/
_addEntry: function(addressHex, entry)
{
// FIXME: deal with entries that span across [multiple] banks.
this._getBank(addressHex).addEntry(entry);
},
/**
* @param {string} addressHex
* @return {!WebInspector.TimelineJSProfileProcessor.CodeMap.Bank}
*/
_getBank: function(addressHex)
{
addressHex = addressHex.slice(2); // cut 0x prefix.
// 13 hex digits == 52 bits, double mantissa fits 53 bits.
var /** @const */ bankSizeHexDigits = 13;
var /** @const */ maxHexDigits = 16;
var bankName = addressHex.slice(-maxHexDigits, -bankSizeHexDigits);
var bank = this._banks.get(bankName);
if (!bank) {
bank = new WebInspector.TimelineJSProfileProcessor.CodeMap.Bank();
this._banks.set(bankName, bank);
}
return bank;
},
/**
* @param {string} addressHex
* @return {number}
*/
_getAddress: function(addressHex)
{
// 13 hex digits == 52 bits, double mantissa fits 53 bits.
var /** @const */ bankSizeHexDigits = 13;
addressHex = addressHex.slice(2); // cut 0x prefix.
return parseInt(addressHex.slice(-bankSizeHexDigits), 16);
}
}
/**
* @constructor
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.Bank = function()
{
/** @type {!Array<!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry>} */
this._entries = [];
}
WebInspector.TimelineJSProfileProcessor.CodeMap.Bank.prototype = {
/**
* @param {number} address
* @return {?WebInspector.TimelineJSProfileProcessor.CodeMap.Entry}
*/
removeEntry: function(address)
{
var index = this._entries.lowerBound(address, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
var entry = this._entries[index];
if (!entry || entry.address !== address)
return null;
this._entries.splice(index, 1);
return entry;
},
/**
* @param {number} address
* @return {?RuntimeAgent.CallFrame}
*/
lookupEntry: function(address)
{
var index = this._entries.upperBound(address, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator) - 1;
var entry = this._entries[index];
return entry && address < entry.address + entry.size ? entry.callFrame : null;
},
/**
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} newEntry
*/
addEntry: function(newEntry)
{
var endAddress = newEntry.address + newEntry.size;
var lastIndex = this._entries.lowerBound(endAddress, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
var index;
for (index = lastIndex - 1; index >= 0; --index) {
var entry = this._entries[index];
var entryEndAddress = entry.address + entry.size;
if (entryEndAddress <= newEntry.address)
break;
}
++index;
this._entries.splice(index, lastIndex - index, newEntry);
}
}
/**
* @param {string} name
* @param {number} scriptId
* @return {!RuntimeAgent.CallFrame}
*/
WebInspector.TimelineJSProfileProcessor._buildCallFrame = function(name, scriptId)
{
/**
* @param {string} functionName
* @param {string=} url
* @param {string=} scriptId
* @param {number=} line
* @param {number=} column
* @param {boolean=} isNative
* @return {!RuntimeAgent.CallFrame}
*/
function createFrame(functionName, url, scriptId, line, column, isNative)
{
return /** @type {!RuntimeAgent.CallFrame} */ ({
"functionName": functionName,
"url": url || "",
"scriptId": scriptId || "0",
"lineNumber": line || 0,
"columnNumber": column || 0,
"isNative": isNative || false
});
}
// Code states:
// (empty) -> compiled
// ~ -> optimizable
// * -> optimized
var rePrefix = /^(\w*:)?[*~]?(.*)$/m;
var tokens = rePrefix.exec(name);
var prefix = tokens[1];
var body = tokens[2];
var rawName;
var rawUrl;
if (prefix === "Script:") {
rawName = "";
rawUrl = body;
} else {
var spacePos = body.lastIndexOf(" ");
rawName = spacePos !== -1 ? body.substr(0, spacePos) : body;
rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : "";
}
var nativeSuffix = " native";
var isNative = rawName.endsWith(nativeSuffix);
var functionName = isNative ? rawName.slice(0, -nativeSuffix.length) : rawName;
var urlData = WebInspector.ParsedURL.splitLineAndColumn(rawUrl);
var url = urlData.url || "";
var line = urlData.lineNumber || 0;
var column = urlData.columnNumber || 0;
return createFrame(functionName, url, String(scriptId), line, column, isNative);
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events)
{
var missingAddesses = new Set();
/**
* @param {string} address
* @return {?RuntimeAgent.CallFrame}
*/
function convertRawFrame(address)
{
var entry = codeMap.lookupEntry(address);
if (entry)
return entry.isNative ? null : entry;
if (!missingAddesses.has(address)) {
missingAddesses.add(address);
console.error("Address " + address + " has missing code entry");
}
return null;
}
var recordTypes = WebInspector.TimelineModel.RecordType;
var samples = [];
var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap();
for (var i = 0; i < events.length; ++i) {
var e = events[i];
var data = e.args["data"];
switch (e.name) {
case recordTypes.JitCodeAdded:
var frame = WebInspector.TimelineJSProfileProcessor._buildCallFrame(data["name"], data["script_id"]);
codeMap.addEntry(data["code_start"], data["code_len"], frame);
break;
case recordTypes.JitCodeMoved:
codeMap.moveEntry(data["code_start"], data["new_code_start"], data["code_len"]);
break;
case recordTypes.V8Sample:
var rawStack = data["stack"];
// Sometimes backend fails to collect a stack and returns an empty stack.
// Skip these bogus samples.
if (data["vm_state"] === "js" && !rawStack.length)
break;
var stack = rawStack.map(convertRawFrame);
stack.remove(null);
var sampleEvent = new WebInspector.TracingModel.Event(
WebInspector.TracingModel.DevToolsTimelineEventCategory,
WebInspector.TimelineModel.RecordType.JSSample,
WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread);
sampleEvent.ordinal = e.ordinal;
sampleEvent.args = {"data": {"stackTrace": stack }};
samples.push(sampleEvent);
break;
}
}
return samples;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 2 1 1 1 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.SplitWidget}
* @param {!WebInspector.TimelineModel} model
* @param {function(!WebInspector.TracingModel.Event)} showEventDetailsCallback
*/
WebInspector.TimelineLayersView = function(model, showEventDetailsCallback)
{
WebInspector.SplitWidget.call(this, true, false, "timelineLayersView");
this._model = model;
this._showEventDetailsCallback = showEventDetailsCallback;
this.element.classList.add("timeline-layers-view");
this._rightSplitWidget = new WebInspector.SplitWidget(true, true, "timelineLayersViewDetails");
this._rightSplitWidget.element.classList.add("timeline-layers-view-properties");
this.setMainWidget(this._rightSplitWidget);
this._paintTiles = [];
var vbox = new WebInspector.VBox();
this.setSidebarWidget(vbox);
this._layerViewHost = new WebInspector.LayerViewHost();
var layerTreeOutline = new WebInspector.LayerTreeOutline(this._layerViewHost);
vbox.element.appendChild(layerTreeOutline.element);
this._layers3DView = new WebInspector.Layers3DView(this._layerViewHost);
this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.PaintProfilerRequested, this._jumpToPaintEvent, this);
this._rightSplitWidget.setMainWidget(this._layers3DView);
var layerDetailsView = new WebInspector.LayerDetailsView(this._layerViewHost);
this._rightSplitWidget.setSidebarWidget(layerDetailsView);
layerDetailsView.addEventListener(WebInspector.LayerDetailsView.Events.PaintProfilerRequested, this._jumpToPaintEvent, this);
}
WebInspector.TimelineLayersView.prototype = {
/**
* @param {!WebInspector.DeferredLayerTree} deferredLayerTree
* @param {?Array.<!WebInspector.LayerPaintEvent>} paints
*/
showLayerTree: function(deferredLayerTree, paints)
{
this._disposeTiles();
this._deferredLayerTree = deferredLayerTree;
this._paints = paints;
if (this.isShowing())
this._update();
else
this._updateWhenVisible = true;
},
wasShown: function()
{
if (this._updateWhenVisible) {
this._updateWhenVisible = false;
this._update();
}
},
/**
* @param {!WebInspector.Event} event
*/
_jumpToPaintEvent: function(event)
{
var traceEvent = /** @type {!WebInspector.TracingModel.Event} */ (event.data);
this._showEventDetailsCallback(traceEvent);
},
_update: function()
{
var layerTree;
this._target = this._deferredLayerTree.target();
var originalTiles = this._paintTiles;
var tilesReadyBarrier = new CallbackBarrier();
this._deferredLayerTree.resolve(tilesReadyBarrier.createCallback(onLayersReady));
for (var i = 0; this._paints && i < this._paints.length; ++i)
this._paints[i].loadSnapshot(tilesReadyBarrier.createCallback(onSnapshotLoaded.bind(this, this._paints[i])));
tilesReadyBarrier.callWhenDone(onLayersAndTilesReady.bind(this));
/**
* @param {!WebInspector.LayerTreeBase} resolvedLayerTree
*/
function onLayersReady(resolvedLayerTree)
{
layerTree = resolvedLayerTree;
}
/**
* @param {!WebInspector.LayerPaintEvent} paintEvent
* @param {?Array.<number>} rect
* @param {?WebInspector.PaintProfilerSnapshot} snapshot
* @this {WebInspector.TimelineLayersView}
*/
function onSnapshotLoaded(paintEvent, rect, snapshot)
{
if (!rect || !snapshot)
return;
// We're too late and there's a new generation of tiles being loaded.
if (originalTiles !== this._paintTiles) {
snapshot.dispose();
return;
}
this._paintTiles.push({layerId: paintEvent.layerId(), rect: rect, snapshot: snapshot, traceEvent: paintEvent.event()});
}
/**
* @this {WebInspector.TimelineLayersView}
*/
function onLayersAndTilesReady()
{
this._layerViewHost.setLayerTree(layerTree);
this._layers3DView.setTiles(this._paintTiles);
}
},
_disposeTiles: function()
{
for (var i = 0; i < this._paintTiles.length; ++i)
this._paintTiles[i].snapshot.dispose();
this._paintTiles = [];
},
__proto__: WebInspector.SplitWidget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | 2 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.OutputStream}
* @implements {WebInspector.OutputStreamDelegate}
* @param {!WebInspector.TracingModel} model
* @param {!WebInspector.TimelineLifecycleDelegate} delegate
*/
WebInspector.TimelineLoader = function(model, delegate)
{
this._model = model;
this._delegate = delegate;
/** @type {?function()} */
this._canceledCallback = null;
this._state = WebInspector.TimelineLoader.State.Initial;
this._buffer = "";
this._firstChunk = true;
this._loadedBytes = 0;
/** @type {number} */
this._totalSize;
this._jsonTokenizer = new WebInspector.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this), true);
}
/**
* @param {!WebInspector.TracingModel} model
* @param {!File} file
* @param {!WebInspector.TimelineLifecycleDelegate} delegate
* @return {!WebInspector.TimelineLoader}
*/
WebInspector.TimelineLoader.loadFromFile = function(model, file, delegate)
{
var loader = new WebInspector.TimelineLoader(model, delegate);
var fileReader = WebInspector.TimelineLoader._createFileReader(file, loader);
loader._canceledCallback = fileReader.cancel.bind(fileReader);
loader._totalSize = file.size;
fileReader.start(loader);
return loader;
}
/**
* @param {!WebInspector.TracingModel} model
* @param {string} url
* @param {!WebInspector.TimelineLifecycleDelegate} delegate
* @return {!WebInspector.TimelineLoader}
*/
WebInspector.TimelineLoader.loadFromURL = function(model, url, delegate)
{
var stream = new WebInspector.TimelineLoader(model, delegate);
WebInspector.ResourceLoader.loadAsStream(url, null, stream);
return stream;
}
WebInspector.TimelineLoader.TransferChunkLengthBytes = 5000000;
/**
* @param {!File} file
* @param {!WebInspector.OutputStreamDelegate} delegate
* @return {!WebInspector.ChunkedReader}
*/
WebInspector.TimelineLoader._createFileReader = function(file, delegate)
{
return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineLoader.TransferChunkLengthBytes, delegate);
}
WebInspector.TimelineLoader.State = {
Initial: "Initial",
LookingForEvents: "LookingForEvents",
ReadingEvents: "ReadingEvents"
}
WebInspector.TimelineLoader.prototype = {
cancel: function()
{
this._model.reset();
this._delegate.loadingComplete(false);
this._delegate = null;
if (this._canceledCallback)
this._canceledCallback();
},
/**
* @override
* @param {string} chunk
*/
write: function(chunk)
{
if (!this._delegate)
return;
this._loadedBytes += chunk.length;
if (!this._firstChunk)
this._delegate.loadingProgress(this._totalSize ? this._loadedBytes / this._totalSize : undefined);
if (this._state === WebInspector.TimelineLoader.State.Initial) {
if (chunk[0] === "{")
this._state = WebInspector.TimelineLoader.State.LookingForEvents;
else if (chunk[0] === "[")
this._state = WebInspector.TimelineLoader.State.ReadingEvents;
else {
this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: Unknown JSON format"));
return;
}
}
if (this._state === WebInspector.TimelineLoader.State.LookingForEvents) {
var objectName = "\"traceEvents\":";
var startPos = this._buffer.length - objectName.length;
this._buffer += chunk;
var pos = this._buffer.indexOf(objectName, startPos);
if (pos === -1)
return;
chunk = this._buffer.slice(pos + objectName.length)
this._state = WebInspector.TimelineLoader.State.ReadingEvents;
}
this._jsonTokenizer.write(chunk);
},
/**
* @param {string} data
*/
_writeBalancedJSON: function(data)
{
var json = data + "]";
if (this._firstChunk) {
this._delegate.loadingStarted();
} else {
var commaIndex = json.indexOf(",");
if (commaIndex !== -1)
json = json.slice(commaIndex + 1);
json = "[" + json;
}
var items;
try {
items = /** @type {!Array.<!WebInspector.TracingManager.EventPayload>} */ (JSON.parse(json));
} catch (e) {
this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s", e.toString()));
return;
}
if (this._firstChunk) {
this._firstChunk = false;
this._model.reset();
if (this._looksLikeAppVersion(items[0])) {
this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy Timeline format is not supported."));
return;
}
}
try {
this._model.addEvents(items);
} catch(e) {
this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s", e.toString()));
return;
}
},
/**
* @param {string=} message
*/
_reportErrorAndCancelLoading: function(message)
{
if (message)
WebInspector.console.error(message);
this.cancel();
},
/**
* @param {*} item
* @return {boolean}
*/
_looksLikeAppVersion: function(item)
{
return typeof item === "string" && item.indexOf("Chrome") !== -1;
},
/**
* @override
*/
close: function()
{
this._model.tracingComplete();
if (this._delegate)
this._delegate.loadingComplete(true);
},
/**
* @override
*/
onTransferStarted: function() {},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader) {},
/**
* @override
*/
onTransferFinished: function() {},
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
* @param {!Event} event
*/
onError: function(reader, event)
{
switch (event.target.error.code) {
case FileError.NOT_FOUND_ERR:
this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" not found.", reader.fileName()));
break;
case FileError.NOT_READABLE_ERR:
this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" is not readable", reader.fileName()));
break;
case FileError.ABORT_ERR:
break;
default:
this._reportErrorAndCancelLoading(WebInspector.UIString("An error occurred while reading the file \"%s\"", reader.fileName()));
}
}
}
/**
* @constructor
* @implements {WebInspector.OutputStreamDelegate}
*/
WebInspector.TracingTimelineSaver = function()
{
}
WebInspector.TracingTimelineSaver.prototype = {
/**
* @override
*/
onTransferStarted: function() { },
/**
* @override
*/
onTransferFinished: function() { },
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader) { },
/**
* @override
* @param {!WebInspector.ChunkedReader} reader
* @param {!Event} event
*/
onError: function(reader, event)
{
var error = event.target.error;
WebInspector.console.error(WebInspector.UIString("Failed to save timeline: %s (%s, %s)", error.message, error.name, error.code));
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 | 2 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.TimelineModel.Filter} eventFilter
*/
WebInspector.TimelineModel = function(eventFilter)
{
this._eventFilter = eventFilter;
this.reset();
}
/**
* @enum {string}
*/
WebInspector.TimelineModel.RecordType = {
Task: "Task",
Program: "Program",
EventDispatch: "EventDispatch",
GPUTask: "GPUTask",
Animation: "Animation",
RequestMainThreadFrame: "RequestMainThreadFrame",
BeginFrame: "BeginFrame",
NeedsBeginFrameChanged: "NeedsBeginFrameChanged",
BeginMainThreadFrame: "BeginMainThreadFrame",
ActivateLayerTree: "ActivateLayerTree",
DrawFrame: "DrawFrame",
HitTest: "HitTest",
ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
RecalculateStyles: "RecalculateStyles", // For backwards compatibility only, now replaced by UpdateLayoutTree.
UpdateLayoutTree: "UpdateLayoutTree",
InvalidateLayout: "InvalidateLayout",
Layout: "Layout",
UpdateLayer: "UpdateLayer",
UpdateLayerTree: "UpdateLayerTree",
PaintSetup: "PaintSetup",
Paint: "Paint",
PaintImage: "PaintImage",
Rasterize: "Rasterize",
RasterTask: "RasterTask",
ScrollLayer: "ScrollLayer",
CompositeLayers: "CompositeLayers",
ScheduleStyleInvalidationTracking: "ScheduleStyleInvalidationTracking",
StyleRecalcInvalidationTracking: "StyleRecalcInvalidationTracking",
StyleInvalidatorInvalidationTracking: "StyleInvalidatorInvalidationTracking",
LayoutInvalidationTracking: "LayoutInvalidationTracking",
LayerInvalidationTracking: "LayerInvalidationTracking",
PaintInvalidationTracking: "PaintInvalidationTracking",
ScrollInvalidationTracking: "ScrollInvalidationTracking",
ParseHTML: "ParseHTML",
ParseAuthorStyleSheet: "ParseAuthorStyleSheet",
TimerInstall: "TimerInstall",
TimerRemove: "TimerRemove",
TimerFire: "TimerFire",
XHRReadyStateChange: "XHRReadyStateChange",
XHRLoad: "XHRLoad",
CompileScript: "v8.compile",
EvaluateScript: "EvaluateScript",
CommitLoad: "CommitLoad",
MarkLoad: "MarkLoad",
MarkDOMContent: "MarkDOMContent",
MarkFirstPaint: "MarkFirstPaint",
TimeStamp: "TimeStamp",
ConsoleTime: "ConsoleTime",
UserTiming: "UserTiming",
ResourceSendRequest: "ResourceSendRequest",
ResourceReceiveResponse: "ResourceReceiveResponse",
ResourceReceivedData: "ResourceReceivedData",
ResourceFinish: "ResourceFinish",
FunctionCall: "FunctionCall",
GCEvent: "GCEvent", // For backwards compatibility only, now replaced by MinorGC/MajorGC.
MajorGC: "MajorGC",
MinorGC: "MinorGC",
JSFrame: "JSFrame",
JSSample: "JSSample",
// V8Sample events are coming from tracing and contain raw stacks with function addresses.
// After being processed with help of JitCodeAdded and JitCodeMoved events they
// get translated into function infos and stored as stacks in JSSample events.
V8Sample: "V8Sample",
JitCodeAdded: "JitCodeAdded",
JitCodeMoved: "JitCodeMoved",
ParseScriptOnBackground: "v8.parseOnBackground",
UpdateCounters: "UpdateCounters",
RequestAnimationFrame: "RequestAnimationFrame",
CancelAnimationFrame: "CancelAnimationFrame",
FireAnimationFrame: "FireAnimationFrame",
RequestIdleCallback: "RequestIdleCallback",
CancelIdleCallback: "CancelIdleCallback",
FireIdleCallback: "FireIdleCallback",
WebSocketCreate : "WebSocketCreate",
WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
WebSocketDestroy : "WebSocketDestroy",
EmbedderCallback : "EmbedderCallback",
SetLayerTreeId: "SetLayerTreeId",
TracingStartedInPage: "TracingStartedInPage",
TracingSessionIdForWorker: "TracingSessionIdForWorker",
DecodeImage: "Decode Image",
ResizeImage: "Resize Image",
DrawLazyPixelRef: "Draw LazyPixelRef",
DecodeLazyPixelRef: "Decode LazyPixelRef",
LazyPixelRef: "LazyPixelRef",
LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl",
PictureSnapshot: "cc::Picture",
DisplayItemListSnapshot: "cc::DisplayItemList",
LatencyInfo: "LatencyInfo",
LatencyInfoFlow: "LatencyInfo.Flow",
InputLatencyMouseMove: "InputLatency::MouseMove",
InputLatencyMouseWheel: "InputLatency::MouseWheel",
ImplSideFling: "InputHandlerProxy::HandleGestureFling::started",
GCIdleLazySweep: "ThreadState::performIdleLazySweep",
GCCompleteSweep: "ThreadState::completeSweep",
GCCollectGarbage: "Heap::collectGarbage",
// CpuProfile is a virtual event created on frontend to support
// serialization of CPU Profiles within tracing timeline data.
CpuProfile: "CpuProfile"
}
WebInspector.TimelineModel.Category = {
Console: "blink.console",
UserTiming: "blink.user_timing",
LatencyInfo: "latencyInfo"
};
/**
* @enum {string}
*/
WebInspector.TimelineModel.WarningType = {
ForcedStyle: "ForcedStyle",
ForcedLayout: "ForcedLayout",
IdleDeadlineExceeded: "IdleDeadlineExceeded",
V8Deopt: "V8Deopt"
}
WebInspector.TimelineModel.MainThreadName = "main";
WebInspector.TimelineModel.WorkerThreadName = "DedicatedWorker Thread";
WebInspector.TimelineModel.RendererMainThreadName = "CrRendererMain";
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} events
* @param {function(!WebInspector.TracingModel.Event)} onStartEvent
* @param {function(!WebInspector.TracingModel.Event)} onEndEvent
* @param {function(!WebInspector.TracingModel.Event,?WebInspector.TracingModel.Event)|undefined=} onInstantEvent
* @param {number=} startTime
* @param {number=} endTime
*/
WebInspector.TimelineModel.forEachEvent = function(events, onStartEvent, onEndEvent, onInstantEvent, startTime, endTime)
{
startTime = startTime || 0;
endTime = endTime || Infinity;
var stack = [];
for (var i = 0; i < events.length; ++i) {
var e = events[i];
if ((e.endTime || e.startTime) < startTime)
continue;
if (e.startTime >= endTime)
break;
if (WebInspector.TracingModel.isAsyncPhase(e.phase) || WebInspector.TracingModel.isFlowPhase(e.phase))
continue;
while (stack.length && stack.peekLast().endTime <= e.startTime)
onEndEvent(stack.pop());
if (e.duration) {
onStartEvent(e);
stack.push(e);
} else {
onInstantEvent && onInstantEvent(e, stack.peekLast() || null);
}
}
while (stack.length)
onEndEvent(stack.pop());
}
/**
* @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray
* @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector.TimelineModel.Record,number)} preOrderCallback
* @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)=} postOrderCallback
* @return {boolean}
*/
WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallback, postOrderCallback)
{
/**
* @param {!Array.<!WebInspector.TimelineModel.Record>} records
* @param {number} depth
* @return {boolean}
*/
function processRecords(records, depth)
{
for (var i = 0; i < records.length; ++i) {
var record = records[i];
if (preOrderCallback && preOrderCallback(record, depth))
return true;
if (processRecords(record.children(), depth + 1))
return true;
if (postOrderCallback && postOrderCallback(record, depth))
return true;
}
return false;
}
return processRecords(recordsArray, 0);
}
WebInspector.TimelineModel.DevToolsMetadataEvent = {
TracingStartedInBrowser: "TracingStartedInBrowser",
TracingStartedInPage: "TracingStartedInPage",
TracingSessionIdForWorker: "TracingSessionIdForWorker",
};
/**
* @constructor
* @param {string} name
*/
WebInspector.TimelineModel.VirtualThread = function(name)
{
this.name = name;
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this.events = [];
/** @type {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
this.asyncEventsByGroup = new Map();
}
WebInspector.TimelineModel.VirtualThread.prototype = {
/**
* @return {boolean}
*/
isWorker: function()
{
return this.name === WebInspector.TimelineModel.WorkerThreadName;
}
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} traceEvent
*/
WebInspector.TimelineModel.Record = function(traceEvent)
{
this._event = traceEvent;
this._children = [];
}
/**
* @param {!WebInspector.TimelineModel.Record} a
* @param {!WebInspector.TimelineModel.Record} b
* @return {number}
*/
WebInspector.TimelineModel.Record._compareStartTime = function(a, b)
{
// Never return 0 as otherwise equal records would be merged.
return a.startTime() <= b.startTime() ? -1 : 1;
}
WebInspector.TimelineModel.Record.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
var threadName = this._event.thread.name();
//FIXME: correctly specify target
return threadName === WebInspector.TimelineModel.RendererMainThreadName ? WebInspector.targetManager.targets()[0] || null : null;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
children: function()
{
return this._children;
},
/**
* @return {number}
*/
startTime: function()
{
return this._event.startTime;
},
/**
* @return {number}
*/
endTime: function()
{
return this._event.endTime || this._event.startTime;
},
/**
* @return {string}
*/
thread: function()
{
if (this._event.thread.name() === WebInspector.TimelineModel.RendererMainThreadName)
return WebInspector.TimelineModel.MainThreadName;
return this._event.thread.name();
},
/**
* @return {!WebInspector.TimelineModel.RecordType}
*/
type: function()
{
return WebInspector.TimelineModel._eventType(this._event);
},
/**
* @param {string} key
* @return {?Object}
*/
getUserObject: function(key)
{
if (key === "TimelineUIUtils::preview-element")
return this._event.previewElement;
throw new Error("Unexpected key: " + key);
},
/**
* @param {string} key
* @param {?Object|undefined} value
*/
setUserObject: function(key, value)
{
if (key !== "TimelineUIUtils::preview-element")
throw new Error("Unexpected key: " + key);
this._event.previewElement = /** @type {?Element} */ (value);
},
/**
* @return {!WebInspector.TracingModel.Event}
*/
traceEvent: function()
{
return this._event;
},
/**
* @param {!WebInspector.TimelineModel.Record} child
*/
_addChild: function(child)
{
this._children.push(child);
child.parent = this;
}
}
/** @typedef {!{page: !Array<!WebInspector.TracingModel.Event>, workers: !Array<!WebInspector.TracingModel.Event>}} */
WebInspector.TimelineModel.MetadataEvents;
/**
* @return {!WebInspector.TimelineModel.RecordType}
*/
WebInspector.TimelineModel._eventType = function(event)
{
if (event.hasCategory(WebInspector.TimelineModel.Category.Console))
return WebInspector.TimelineModel.RecordType.ConsoleTime;
if (event.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
return WebInspector.TimelineModel.RecordType.UserTiming;
if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo))
return WebInspector.TimelineModel.RecordType.LatencyInfo;
return /** @type !WebInspector.TimelineModel.RecordType */ (event.name);
}
WebInspector.TimelineModel.prototype = {
/**
* @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector.TimelineModel.Record,number)} preOrderCallback
* @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)=} postOrderCallback
*/
forAllRecords: function(preOrderCallback, postOrderCallback)
{
WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback, postOrderCallback);
},
/**
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)} callback
*/
forAllFilteredRecords: function(filters, callback)
{
/**
* @param {!WebInspector.TimelineModel.Record} record
* @param {number} depth
* @this {WebInspector.TimelineModel}
* @return {boolean}
*/
function processRecord(record, depth)
{
var visible = WebInspector.TimelineModel.isVisible(filters, record.traceEvent());
if (visible && callback(record, depth))
return true;
for (var i = 0; i < record.children().length; ++i) {
if (processRecord.call(this, record.children()[i], visible ? depth + 1 : depth))
return true;
}
return false;
}
for (var i = 0; i < this._records.length; ++i)
processRecord.call(this, this._records[i], 0);
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
records: function()
{
return this._records;
},
/**
* @return {?string}
*/
sessionId: function()
{
return this._sessionId;
},
/**
* @return {?WebInspector.Target}
*/
target: function()
{
// FIXME: Consider returning null for loaded traces.
return WebInspector.targetManager.targets()[0];
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @param {boolean=} produceTraceStartedInPage
*/
setEvents: function(tracingModel, produceTraceStartedInPage)
{
this.reset();
this._resetProcessingState();
this._minimumRecordTime = tracingModel.minimumRecordTime();
this._maximumRecordTime = tracingModel.maximumRecordTime();
var metadataEvents = this._processMetadataEvents(tracingModel, !!produceTraceStartedInPage);
var startTime = 0;
for (var i = 0, length = metadataEvents.page.length; i < length; i++) {
var metaEvent = metadataEvents.page[i];
var process = metaEvent.thread.process();
var endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity;
this._currentPage = metaEvent.args["data"] && metaEvent.args["data"]["page"];
for (var thread of process.sortedThreads()) {
if (thread.name() === WebInspector.TimelineModel.WorkerThreadName && !metadataEvents.workers.some(function(e) { return e.args["data"]["workerThreadId"] === thread.id(); }))
continue;
this._processThreadEvents(startTime, endTime, metaEvent.thread, thread);
}
startTime = endTime;
}
this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
this._cpuProfiles = null;
this._processBrowserEvents(tracingModel);
this._buildTimelineRecords();
this._buildGPUEvents(tracingModel);
this._insertFirstPaintEvent();
this._resetProcessingState();
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @param {boolean} produceTraceStartedInPage
* @return {!WebInspector.TimelineModel.MetadataEvents}
*/
_processMetadataEvents: function(tracingModel, produceTraceStartedInPage)
{
var metadataEvents = tracingModel.devToolsMetadataEvents();
var pageDevToolsMetadataEvents = [];
var workersDevToolsMetadataEvents = [];
for (var event of metadataEvents) {
if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage) {
pageDevToolsMetadataEvents.push(event);
} else if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker) {
workersDevToolsMetadataEvents.push(event);
} else if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) {
console.assert(!this._mainFrameNodeId, "Multiple sessions in trace");
this._mainFrameNodeId = event.args["frameTreeNodeId"];
}
}
if (!pageDevToolsMetadataEvents.length) {
// The trace is probably coming not from DevTools. Make a mock Metadata event.
var pageMetaEvent = produceTraceStartedInPage ? this._makeMockPageMetadataEvent(tracingModel) : null;
if (!pageMetaEvent) {
console.error(WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage + " event not found.");
return {page: [], workers: []};
}
pageDevToolsMetadataEvents.push(pageMetaEvent);
}
var sessionId = pageDevToolsMetadataEvents[0].args["sessionId"] || pageDevToolsMetadataEvents[0].args["data"]["sessionId"];
this._sessionId = sessionId;
var mismatchingIds = new Set();
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
function checkSessionId(event)
{
var args = event.args;
// FIXME: put sessionId into args["data"] for TracingStartedInPage event.
if (args["data"])
args = args["data"];
var id = args["sessionId"];
if (id === sessionId)
return true;
mismatchingIds.add(id);
return false;
}
var result = {
page: pageDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime),
workers: workersDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime)
};
if (mismatchingIds.size)
WebInspector.console.error("Timeline recording was started in more than one page simultaneously. Session id mismatch: " + this._sessionId + " and " + mismatchingIds.valuesArray() + ".");
return result;
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @return {?WebInspector.TracingModel.Event}
*/
_makeMockPageMetadataEvent: function(tracingModel)
{
var rendererMainThreadName = WebInspector.TimelineModel.RendererMainThreadName;
// FIXME: pick up the first renderer process for now.
var process = Object.values(tracingModel.sortedProcesses()).filter(function(p) { return p.threadByName(rendererMainThreadName); })[0];
var thread = process && process.threadByName(rendererMainThreadName);
if (!thread)
return null;
var pageMetaEvent = new WebInspector.TracingModel.Event(
WebInspector.TracingModel.DevToolsMetadataEventCategory,
WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage,
WebInspector.TracingModel.Phase.Metadata,
tracingModel.minimumRecordTime(), thread);
pageMetaEvent.addArgs({"data": {"sessionId": "mockSessionId"}});
return pageMetaEvent;
},
_insertFirstPaintEvent: function()
{
if (!this._firstCompositeLayers)
return;
// First Paint is actually a DrawFrame that happened after first CompositeLayers following last CommitLoadEvent.
var recordTypes = WebInspector.TimelineModel.RecordType;
var i = this._inspectedTargetEvents.lowerBound(this._firstCompositeLayers, WebInspector.TracingModel.Event.compareStartTime);
for (; i < this._inspectedTargetEvents.length && this._inspectedTargetEvents[i].name !== recordTypes.DrawFrame; ++i) { }
if (i >= this._inspectedTargetEvents.length)
return;
var drawFrameEvent = this._inspectedTargetEvents[i];
var firstPaintEvent = new WebInspector.TracingModel.Event(drawFrameEvent.categoriesString, recordTypes.MarkFirstPaint, WebInspector.TracingModel.Phase.Instant, drawFrameEvent.startTime, drawFrameEvent.thread);
this._mainThreadEvents.splice(this._mainThreadEvents.lowerBound(firstPaintEvent, WebInspector.TracingModel.Event.compareStartTime), 0, firstPaintEvent);
var firstPaintRecord = new WebInspector.TimelineModel.Record(firstPaintEvent);
this._eventDividerRecords.splice(this._eventDividerRecords.lowerBound(firstPaintRecord, WebInspector.TimelineModel.Record._compareStartTime), 0, firstPaintRecord);
},
/**
* @param {!WebInspector.TracingModel} tracingModel
*/
_processBrowserEvents: function(tracingModel)
{
var browserMain = tracingModel.threadByName("Browser", "CrBrowserMain");
if (!browserMain)
return;
// Disregard regular events, we don't need them yet, but still process to get proper metadata.
browserMain.events().forEach(this._processBrowserEvent, this);
/** @type {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
var asyncEventsByGroup = new Map();
this._processAsyncEvents(asyncEventsByGroup, browserMain.asyncEvents());
this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup, asyncEventsByGroup);
},
_buildTimelineRecords: function()
{
var topLevelRecords = this._buildTimelineRecordsForThread(this.mainThreadEvents());
for (var i = 0; i < topLevelRecords.length; i++) {
var record = topLevelRecords[i];
if (WebInspector.TracingModel.isTopLevelEvent(record.traceEvent()))
this._mainThreadTasks.push(record);
}
/**
* @param {!WebInspector.TimelineModel.VirtualThread} virtualThread
* @this {!WebInspector.TimelineModel}
*/
function processVirtualThreadEvents(virtualThread)
{
var threadRecords = this._buildTimelineRecordsForThread(virtualThread.events);
topLevelRecords = topLevelRecords.mergeOrdered(threadRecords, WebInspector.TimelineModel.Record._compareStartTime);
}
this.virtualThreads().forEach(processVirtualThreadEvents.bind(this));
this._records = topLevelRecords;
},
/**
* @param {!WebInspector.TracingModel} tracingModel
*/
_buildGPUEvents: function(tracingModel)
{
var thread = tracingModel.threadByName("GPU Process", "CrGpuMain");
if (!thread)
return;
var gpuEventName = WebInspector.TimelineModel.RecordType.GPUTask;
this._gpuEvents = thread.events().filter(event => event.name === gpuEventName);
},
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} threadEvents
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
_buildTimelineRecordsForThread: function(threadEvents)
{
var recordStack = [];
var topLevelRecords = [];
for (var i = 0, size = threadEvents.length; i < size; ++i) {
var event = threadEvents[i];
for (var top = recordStack.peekLast(); top && top._event.endTime <= event.startTime; top = recordStack.peekLast())
recordStack.pop();
if (event.phase === WebInspector.TracingModel.Phase.AsyncEnd || event.phase === WebInspector.TracingModel.Phase.NestableAsyncEnd)
continue;
var parentRecord = recordStack.peekLast();
// Maintain the back-end logic of old timeline, skip console.time() / console.timeEnd() that are not properly nested.
if (WebInspector.TracingModel.isAsyncBeginPhase(event.phase) && parentRecord && event.endTime > parentRecord._event.endTime)
continue;
var record = new WebInspector.TimelineModel.Record(event);
if (WebInspector.TimelineUIUtils.isMarkerEvent(event))
this._eventDividerRecords.push(record);
if (!this._eventFilter.accept(event) && !WebInspector.TracingModel.isTopLevelEvent(event))
continue;
if (parentRecord)
parentRecord._addChild(record);
else
topLevelRecords.push(record);
if (event.endTime)
recordStack.push(record);
}
return topLevelRecords;
},
_resetProcessingState: function()
{
this._asyncEventTracker = new WebInspector.TimelineAsyncEventTracker();
this._invalidationTracker = new WebInspector.InvalidationTracker();
this._layoutInvalidate = {};
this._lastScheduleStyleRecalculation = {};
this._paintImageEventByPixelRefId = {};
this._lastPaintForLayer = {};
this._lastRecalculateStylesEvent = null;
this._currentScriptEvent = null;
this._eventStack = [];
this._hadCommitLoad = false;
this._firstCompositeLayers = null;
/** @type {!Set<string>} */
this._knownInputEvents = new Set();
this._currentPage = null;
},
/**
* @param {number} startTime
* @param {number} endTime
* @param {!WebInspector.TracingModel.Thread} mainThread
* @param {!WebInspector.TracingModel.Thread} thread
*/
_processThreadEvents: function(startTime, endTime, mainThread, thread)
{
var events = thread.events();
var asyncEvents = thread.asyncEvents();
var jsSamples;
if (Runtime.experiments.isEnabled("timelineTracingJSProfile")) {
jsSamples = WebInspector.TimelineJSProfileProcessor.processRawV8Samples(events);
} else {
var cpuProfileEvent = events.peekLast();
if (cpuProfileEvent && cpuProfileEvent.name === WebInspector.TimelineModel.RecordType.CpuProfile) {
var cpuProfile = cpuProfileEvent.args["data"]["cpuProfile"];
if (cpuProfile) {
var jsProfileModel = new WebInspector.CPUProfileDataModel(cpuProfile);
this._lineLevelCPUProfile.appendCPUProfile(jsProfileModel);
jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(jsProfileModel, thread);
}
}
}
if (jsSamples && jsSamples.length)
events = events.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
if (jsSamples || events.some(function(e) { return e.name === WebInspector.TimelineModel.RecordType.JSSample; })) {
var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);
if (jsFrameEvents && jsFrameEvents.length)
events = jsFrameEvents.mergeOrdered(events, WebInspector.TracingModel.Event.orderedCompareStartTime);
}
var threadEvents;
var threadAsyncEventsByGroup;
if (thread === mainThread) {
threadEvents = this._mainThreadEvents;
threadAsyncEventsByGroup = this._mainThreadAsyncEventsByGroup;
} else {
var virtualThread = new WebInspector.TimelineModel.VirtualThread(thread.name());
this._virtualThreads.push(virtualThread);
threadEvents = virtualThread.events;
threadAsyncEventsByGroup = virtualThread.asyncEventsByGroup;
}
this._eventStack = [];
var i = events.lowerBound(startTime, function (time, event) { return time - event.startTime });
var length = events.length;
for (; i < length; i++) {
var event = events[i];
if (endTime && event.startTime >= endTime)
break;
if (!this._processEvent(event))
continue;
threadEvents.push(event);
this._inspectedTargetEvents.push(event);
}
this._processAsyncEvents(threadAsyncEventsByGroup, asyncEvents, startTime, endTime);
// Pretend the compositor's async events are on the main thread.
if (thread.name() === "Compositor") {
this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup, threadAsyncEventsByGroup);
threadAsyncEventsByGroup.clear();
}
},
/**
* @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} asyncEventsByGroup
* @param {!Array<!WebInspector.TracingModel.AsyncEvent>} asyncEvents
* @param {number=} startTime
* @param {number=} endTime
*/
_processAsyncEvents: function(asyncEventsByGroup, asyncEvents, startTime, endTime)
{
var i = startTime ? asyncEvents.lowerBound(startTime, function (time, asyncEvent) { return time - asyncEvent.startTime }) : 0;
for (; i < asyncEvents.length; ++i) {
var asyncEvent = asyncEvents[i];
if (endTime && asyncEvent.startTime >= endTime)
break;
var asyncGroup = this._processAsyncEvent(asyncEvent);
if (!asyncGroup)
continue;
var groupAsyncEvents = asyncEventsByGroup.get(asyncGroup);
if (!groupAsyncEvents) {
groupAsyncEvents = [];
asyncEventsByGroup.set(asyncGroup, groupAsyncEvents);
}
groupAsyncEvents.push(asyncEvent);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
_processEvent: function(event)
{
var eventStack = this._eventStack;
while (eventStack.length && eventStack.peekLast().endTime <= event.startTime)
eventStack.pop();
var recordTypes = WebInspector.TimelineModel.RecordType;
if (this._currentScriptEvent && event.startTime > this._currentScriptEvent.endTime)
this._currentScriptEvent = null;
var eventData = event.args["data"] || event.args["beginData"] || {};
if (eventData && eventData["stackTrace"])
event.stackTrace = eventData["stackTrace"];
if (eventStack.length && eventStack.peekLast().name === recordTypes.EventDispatch)
eventStack.peekLast().hasChildren = true;
this._asyncEventTracker.processEvent(event);
if (event.initiator && event.initiator.url)
event.url = event.initiator.url;
switch (event.name) {
case recordTypes.ResourceSendRequest:
case recordTypes.WebSocketCreate:
event.url = event.args["data"]["url"];
break;
case recordTypes.ScheduleStyleRecalculation:
this._lastScheduleStyleRecalculation[event.args["data"]["frame"]] = event;
break;
case recordTypes.UpdateLayoutTree:
case recordTypes.RecalculateStyles:
this._invalidationTracker.didRecalcStyle(event);
if (event.args["beginData"])
event.initiator = this._lastScheduleStyleRecalculation[event.args["beginData"]["frame"]];
this._lastRecalculateStylesEvent = event;
if (this._currentScriptEvent)
event.warning = WebInspector.TimelineModel.WarningType.ForcedStyle;
break;
case recordTypes.ScheduleStyleInvalidationTracking:
case recordTypes.StyleRecalcInvalidationTracking:
case recordTypes.StyleInvalidatorInvalidationTracking:
case recordTypes.LayoutInvalidationTracking:
case recordTypes.LayerInvalidationTracking:
case recordTypes.PaintInvalidationTracking:
case recordTypes.ScrollInvalidationTracking:
this._invalidationTracker.addInvalidation(new WebInspector.InvalidationTrackingEvent(event));
break;
case recordTypes.InvalidateLayout:
// Consider style recalculation as a reason for layout invalidation,
// but only if we had no earlier layout invalidation records.
var layoutInitator = event;
var frameId = event.args["data"]["frame"];
if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesEvent && this._lastRecalculateStylesEvent.endTime > event.startTime)
layoutInitator = this._lastRecalculateStylesEvent.initiator;
this._layoutInvalidate[frameId] = layoutInitator;
break;
case recordTypes.Layout:
this._invalidationTracker.didLayout(event);
var frameId = event.args["beginData"]["frame"];
event.initiator = this._layoutInvalidate[frameId];
// In case we have no closing Layout event, endData is not available.
if (event.args["endData"]) {
event.backendNodeId = event.args["endData"]["rootNode"];
event.highlightQuad = event.args["endData"]["root"];
}
this._layoutInvalidate[frameId] = null;
if (this._currentScriptEvent)
event.warning = WebInspector.TimelineModel.WarningType.ForcedLayout;
break;
case recordTypes.EvaluateScript:
case recordTypes.FunctionCall:
if (!this._currentScriptEvent)
this._currentScriptEvent = event;
break;
case recordTypes.SetLayerTreeId:
this._inspectedTargetLayerTreeId = event.args["layerTreeId"] || event.args["data"]["layerTreeId"];
break;
case recordTypes.Paint:
this._invalidationTracker.didPaint(event);
event.highlightQuad = event.args["data"]["clip"];
event.backendNodeId = event.args["data"]["nodeId"];
// Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
if (!event.args["data"]["layerId"])
break;
var layerId = event.args["data"]["layerId"];
this._lastPaintForLayer[layerId] = event;
break;
case recordTypes.DisplayItemListSnapshot:
case recordTypes.PictureSnapshot:
var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== this._inspectedTargetLayerTreeId)
break;
var paintEvent = this._lastPaintForLayer[layerUpdateEvent.args["layerId"]];
if (paintEvent)
paintEvent.picture = event;
break;
case recordTypes.ScrollLayer:
event.backendNodeId = event.args["data"]["nodeId"];
break;
case recordTypes.PaintImage:
event.backendNodeId = event.args["data"]["nodeId"];
event.url = event.args["data"]["url"];
break;
case recordTypes.DecodeImage:
case recordTypes.ResizeImage:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent) {
var decodeLazyPixelRefEvent = this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
paintImageEvent = decodeLazyPixelRefEvent && this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];
}
if (!paintImageEvent)
break;
event.backendNodeId = paintImageEvent.backendNodeId;
event.url = paintImageEvent.url;
break;
case recordTypes.DrawLazyPixelRef:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent)
break;
this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]] = paintImageEvent;
event.backendNodeId = paintImageEvent.backendNodeId;
event.url = paintImageEvent.url;
break;
case recordTypes.MarkDOMContent:
case recordTypes.MarkLoad:
var page = eventData["page"];
if (page && page !== this._currentPage)
return false;
break;
case recordTypes.CommitLoad:
var page = eventData["page"];
if (page && page !== this._currentPage)
return false;
if (!eventData["isMainFrame"])
break;
this._hadCommitLoad = true;
this._firstCompositeLayers = null;
break;
case recordTypes.CompositeLayers:
if (!this._firstCompositeLayers && this._hadCommitLoad)
this._firstCompositeLayers = event;
break;
case recordTypes.FireIdleCallback:
if (event.duration > eventData["allottedMilliseconds"]) {
event.warning = WebInspector.TimelineModel.WarningType.IdleDeadlineExceeded;
}
break;
}
if (WebInspector.TracingModel.isAsyncPhase(event.phase))
return true;
var duration = event.duration;
if (!duration)
return true;
if (eventStack.length) {
var parent = eventStack.peekLast();
parent.selfTime -= duration;
if (parent.selfTime < 0) {
var epsilon = 1e-3;
if (parent.selfTime < -epsilon)
console.error("Children are longer than parent at " + event.startTime + " (" + (event.startTime - this.minimumRecordTime()).toFixed(3) + ") by " + parent.selfTime.toFixed(3));
parent.selfTime = 0;
}
}
event.selfTime = duration;
eventStack.push(event);
return true;
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_processBrowserEvent: function(event)
{
if (event.name !== WebInspector.TimelineModel.RecordType.LatencyInfoFlow)
return;
var frameId = event.args["frameTreeNodeId"];
if (typeof frameId === "number" && frameId === this._mainFrameNodeId)
this._knownInputEvents.add(event.bind_id);
},
/**
* @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent
* @return {?WebInspector.AsyncEventGroup}
*/
_processAsyncEvent: function(asyncEvent)
{
var groups = WebInspector.TimelineUIUtils.asyncEventGroups();
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.Console))
return groups.console;
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
return groups.userTiming;
if (asyncEvent.name === WebInspector.TimelineModel.RecordType.Animation)
return groups.animation;
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo) || asyncEvent.name === WebInspector.TimelineModel.RecordType.ImplSideFling) {
var lastStep = asyncEvent.steps.peekLast();
// FIXME: fix event termination on the back-end instead.
if (lastStep.phase !== WebInspector.TracingModel.Phase.AsyncEnd)
return null;
var data = lastStep.args["data"];
asyncEvent.causedFrame = !!(data && data["INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT"]);
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) {
if (!this._knownInputEvents.has(lastStep.id))
return null;
if (asyncEvent.name === WebInspector.TimelineModel.RecordType.InputLatencyMouseMove && !asyncEvent.causedFrame)
return null;
}
return groups.input;
}
return null;
},
/**
* @param {string} name
* @return {?WebInspector.TracingModel.Event}
*/
_findAncestorEvent: function(name)
{
for (var i = this._eventStack.length - 1; i >= 0; --i) {
var event = this._eventStack[i];
if (event.name === name)
return event;
}
return null;
},
/**
* @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} target
* @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} source
*/
_mergeAsyncEvents: function(target, source)
{
for (var group of source.keys()) {
var events = target.get(group) || [];
events = events.mergeOrdered(source.get(group) || [], WebInspector.TracingModel.Event.compareStartAndEndTime);
target.set(group, events);
}
},
reset: function()
{
this._lineLevelCPUProfile = new WebInspector.TimelineModel.LineLevelProfile();
this._virtualThreads = [];
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._mainThreadEvents = [];
/** @type {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
this._mainThreadAsyncEventsByGroup = new Map();
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._inspectedTargetEvents = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._records = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._mainThreadTasks = [];
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._gpuEvents = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._eventDividerRecords = [];
/** @type {?string} */
this._sessionId = null;
/** @type {?number} */
this._mainFrameNodeId = null;
this._minimumRecordTime = 0;
this._maximumRecordTime = 0;
},
/**
* @return {!WebInspector.TimelineModel.LineLevelProfile}
*/
lineLevelCPUProfile: function()
{
return this._lineLevelCPUProfile;
},
/**
* @return {number}
*/
minimumRecordTime: function()
{
return this._minimumRecordTime;
},
/**
* @return {number}
*/
maximumRecordTime: function()
{
return this._maximumRecordTime;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
inspectedTargetEvents: function()
{
return this._inspectedTargetEvents;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
mainThreadEvents: function()
{
return this._mainThreadEvents;
},
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} events
*/
_setMainThreadEvents: function(events)
{
this._mainThreadEvents = events;
},
/**
* @return {!Map<!WebInspector.AsyncEventGroup, !Array.<!WebInspector.TracingModel.AsyncEvent>>}
*/
mainThreadAsyncEvents: function()
{
return this._mainThreadAsyncEventsByGroup;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.VirtualThread>}
*/
virtualThreads: function()
{
return this._virtualThreads;
},
/**
* @return {boolean}
*/
isEmpty: function()
{
return this.minimumRecordTime() === 0 && this.maximumRecordTime() === 0;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
mainThreadTasks: function()
{
return this._mainThreadTasks;
},
/**
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
gpuEvents: function()
{
return this._gpuEvents;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
eventDividerRecords: function()
{
return this._eventDividerRecords;
},
/**
* @return {!Array<!WebInspector.TimelineModel.NetworkRequest>}
*/
networkRequests: function()
{
/** @type {!Map<string,!WebInspector.TimelineModel.NetworkRequest>} */
var requests = new Map();
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
var requestsList = [];
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
var zeroStartRequestsList = [];
var types = WebInspector.TimelineModel.RecordType;
var resourceTypes = new Set([
types.ResourceSendRequest,
types.ResourceReceiveResponse,
types.ResourceReceivedData,
types.ResourceFinish
]);
var events = this.mainThreadEvents();
for (var i = 0; i < events.length; ++i) {
var e = events[i];
if (!resourceTypes.has(e.name))
continue;
var id = e.args["data"]["requestId"];
var request = requests.get(id);
if (request) {
request.addEvent(e);
} else {
request = new WebInspector.TimelineModel.NetworkRequest(e);
requests.set(id, request);
if (request.startTime)
requestsList.push(request);
else
zeroStartRequestsList.push(request);
}
}
return zeroStartRequestsList.concat(requestsList);
},
}
/**
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
WebInspector.TimelineModel.isVisible = function(filters, event)
{
for (var i = 0; i < filters.length; ++i) {
if (!filters[i].accept(event))
return false;
}
return true;
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} event
*/
WebInspector.TimelineModel.NetworkRequest = function(event)
{
this.startTime = event.name === WebInspector.TimelineModel.RecordType.ResourceSendRequest ? event.startTime : 0;
this.endTime = Infinity;
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this.children = [];
this.addEvent(event);
}
WebInspector.TimelineModel.NetworkRequest.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
*/
addEvent: function(event)
{
this.children.push(event);
var recordType = WebInspector.TimelineModel.RecordType;
this.startTime = Math.min(this.startTime, event.startTime);
var eventData = event.args["data"];
if (eventData["mimeType"])
this.mimeType = eventData["mimeType"];
if ("priority" in eventData)
this.priority = eventData["priority"];
if (event.name === recordType.ResourceFinish)
this.endTime = event.startTime;
if (!this.responseTime && (event.name === recordType.ResourceReceiveResponse || event.name === recordType.ResourceReceivedData))
this.responseTime = event.startTime;
if (!this.url)
this.url = eventData["url"];
if (!this.requestMethod)
this.requestMethod = eventData["requestMethod"];
}
}
/**
* @constructor
*/
WebInspector.TimelineModel.Filter = function()
{
}
WebInspector.TimelineModel.Filter.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return true;
}
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
* @param {!Array.<string>} visibleTypes
*/
WebInspector.TimelineVisibleEventsFilter = function(visibleTypes)
{
WebInspector.TimelineModel.Filter.call(this);
this._visibleTypes = new Set(visibleTypes);
}
WebInspector.TimelineVisibleEventsFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return this._visibleTypes.has(WebInspector.TimelineModel._eventType(event));
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
* @param {!Array<string>} excludeNames
*/
WebInspector.ExclusiveNameFilter = function(excludeNames)
{
WebInspector.TimelineModel.Filter.call(this);
this._excludeNames = new Set(excludeNames);
}
WebInspector.ExclusiveNameFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !this._excludeNames.has(event.name);
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.ExcludeTopLevelFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
}
WebInspector.ExcludeTopLevelFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !WebInspector.TracingModel.isTopLevelEvent(event);
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} event
*/
WebInspector.InvalidationTrackingEvent = function(event)
{
/** @type {string} */
this.type = event.name;
/** @type {number} */
this.startTime = event.startTime;
/** @type {!WebInspector.TracingModel.Event} */
this._tracingEvent = event;
var eventData = event.args["data"];
/** @type {number} */
this.frame = eventData["frame"];
/** @type {?number} */
this.nodeId = eventData["nodeId"];
/** @type {?string} */
this.nodeName = eventData["nodeName"];
/** @type {?number} */
this.paintId = eventData["paintId"];
/** @type {?number} */
this.invalidationSet = eventData["invalidationSet"];
/** @type {?string} */
this.invalidatedSelectorId = eventData["invalidatedSelectorId"];
/** @type {?string} */
this.changedId = eventData["changedId"];
/** @type {?string} */
this.changedClass = eventData["changedClass"];
/** @type {?string} */
this.changedAttribute = eventData["changedAttribute"];
/** @type {?string} */
this.changedPseudo = eventData["changedPseudo"];
/** @type {?string} */
this.selectorPart = eventData["selectorPart"];
/** @type {?string} */
this.extraData = eventData["extraData"];
/** @type {?Array.<!Object.<string, number>>} */
this.invalidationList = eventData["invalidationList"];
/** @type {!WebInspector.InvalidationCause} */
this.cause = {reason: eventData["reason"], stackTrace: eventData["stackTrace"]};
// FIXME: Move this to TimelineUIUtils.js.
if (!this.cause.reason && this.cause.stackTrace && this.type === WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking)
this.cause.reason = "Layout forced";
}
/** @typedef {{reason: string, stackTrace: ?Array.<!RuntimeAgent.CallFrame>}} */
WebInspector.InvalidationCause;
/**
* @constructor
*/
WebInspector.InvalidationTracker = function()
{
this._initializePerFrameState();
}
WebInspector.InvalidationTracker.prototype = {
/**
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
addInvalidation: function(invalidation)
{
this._startNewFrameIfNeeded();
if (!invalidation.nodeId && !invalidation.paintId) {
console.error("Invalidation lacks node information.");
console.error(invalidation);
return;
}
// PaintInvalidationTracking events provide a paintId and a nodeId which
// we can use to update the paintId for all other invalidation tracking
// events.
var recordTypes = WebInspector.TimelineModel.RecordType;
if (invalidation.type === recordTypes.PaintInvalidationTracking && invalidation.nodeId) {
var invalidations = this._invalidationsByNodeId[invalidation.nodeId] || [];
for (var i = 0; i < invalidations.length; ++i)
invalidations[i].paintId = invalidation.paintId;
// PaintInvalidationTracking is only used for updating paintIds.
return;
}
// Suppress StyleInvalidator StyleRecalcInvalidationTracking invalidations because they
// will be handled by StyleInvalidatorInvalidationTracking.
// FIXME: Investigate if we can remove StyleInvalidator invalidations entirely.
if (invalidation.type === recordTypes.StyleRecalcInvalidationTracking && invalidation.cause.reason === "StyleInvalidator")
return;
// Style invalidation events can occur before and during recalc style. didRecalcStyle
// handles style invalidations that occur before the recalc style event but we need to
// handle style recalc invalidations during recalc style here.
var styleRecalcInvalidation = (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking
|| invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking
|| invalidation.type === recordTypes.StyleRecalcInvalidationTracking);
if (styleRecalcInvalidation) {
var duringRecalcStyle = invalidation.startTime && this._lastRecalcStyle
&& invalidation.startTime >= this._lastRecalcStyle.startTime
&& invalidation.startTime <= this._lastRecalcStyle.endTime;
if (duringRecalcStyle)
this._associateWithLastRecalcStyleEvent(invalidation);
}
// Record the invalidation so later events can look it up.
if (this._invalidations[invalidation.type])
this._invalidations[invalidation.type].push(invalidation);
else
this._invalidations[invalidation.type] = [ invalidation ];
if (invalidation.nodeId) {
if (this._invalidationsByNodeId[invalidation.nodeId])
this._invalidationsByNodeId[invalidation.nodeId].push(invalidation);
else
this._invalidationsByNodeId[invalidation.nodeId] = [ invalidation ];
}
},
/**
* @param {!WebInspector.TracingModel.Event} recalcStyleEvent
*/
didRecalcStyle: function(recalcStyleEvent)
{
this._lastRecalcStyle = recalcStyleEvent;
var types = [WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,
WebInspector.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,
WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking];
for (var invalidation of this._invalidationsOfTypes(types))
this._associateWithLastRecalcStyleEvent(invalidation);
},
/**
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
_associateWithLastRecalcStyleEvent: function(invalidation)
{
if (invalidation.linkedRecalcStyleEvent)
return;
var recordTypes = WebInspector.TimelineModel.RecordType;
var recalcStyleFrameId = this._lastRecalcStyle.args["beginData"]["frame"];
if (invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking) {
// Instead of calling _addInvalidationToEvent directly, we create synthetic
// StyleRecalcInvalidationTracking events which will be added in _addInvalidationToEvent.
this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
} else if (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking) {
// ScheduleStyleInvalidationTracking events are only used for adding information to
// StyleInvalidatorInvalidationTracking events. See: _addSyntheticStyleRecalcInvalidations.
} else {
this._addInvalidationToEvent(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
}
invalidation.linkedRecalcStyleEvent = true;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} frameId
* @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
*/
_addSyntheticStyleRecalcInvalidations: function(event, frameId, styleInvalidatorInvalidation)
{
if (!styleInvalidatorInvalidation.invalidationList) {
this._addSyntheticStyleRecalcInvalidation(styleInvalidatorInvalidation._tracingEvent, styleInvalidatorInvalidation);
return;
}
if (!styleInvalidatorInvalidation.nodeId) {
console.error("Invalidation lacks node information.");
console.error(invalidation);
return;
}
for (var i = 0; i < styleInvalidatorInvalidation.invalidationList.length; i++) {
var setId = styleInvalidatorInvalidation.invalidationList[i]["id"];
var lastScheduleStyleRecalculation;
var nodeInvalidations = this._invalidationsByNodeId[styleInvalidatorInvalidation.nodeId] || [];
for (var j = 0; j < nodeInvalidations.length; j++) {
var invalidation = nodeInvalidations[j];
if (invalidation.frame !== frameId || invalidation.invalidationSet !== setId || invalidation.type !== WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking)
continue;
lastScheduleStyleRecalculation = invalidation;
}
if (!lastScheduleStyleRecalculation) {
console.error("Failed to lookup the event that scheduled a style invalidator invalidation.");
continue;
}
this._addSyntheticStyleRecalcInvalidation(lastScheduleStyleRecalculation._tracingEvent, styleInvalidatorInvalidation);
}
},
/**
* @param {!WebInspector.TracingModel.Event} baseEvent
* @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
*/
_addSyntheticStyleRecalcInvalidation: function(baseEvent, styleInvalidatorInvalidation)
{
var invalidation = new WebInspector.InvalidationTrackingEvent(baseEvent);
invalidation.type = WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking;
invalidation.synthetic = true;
if (styleInvalidatorInvalidation.cause.reason)
invalidation.cause.reason = styleInvalidatorInvalidation.cause.reason;
if (styleInvalidatorInvalidation.selectorPart)
invalidation.selectorPart = styleInvalidatorInvalidation.selectorPart;
this.addInvalidation(invalidation);
if (!invalidation.linkedRecalcStyleEvent)
this._associateWithLastRecalcStyleEvent(invalidation);
},
/**
* @param {!WebInspector.TracingModel.Event} layoutEvent
*/
didLayout: function(layoutEvent)
{
var layoutFrameId = layoutEvent.args["beginData"]["frame"];
for (var invalidation of this._invalidationsOfTypes([WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking])) {
if (invalidation.linkedLayoutEvent)
continue;
this._addInvalidationToEvent(layoutEvent, layoutFrameId, invalidation);
invalidation.linkedLayoutEvent = true;
}
},
/**
* @param {!WebInspector.TracingModel.Event} paintEvent
*/
didPaint: function(paintEvent)
{
this._didPaint = true;
// If a paint doesn't have a corresponding graphics layer id, it paints
// into its parent so add an effectivePaintId to these events.
var layerId = paintEvent.args["data"]["layerId"];
if (layerId)
this._lastPaintWithLayer = paintEvent;
if (!this._lastPaintWithLayer) {
console.error("Failed to find a paint container for a paint event.");
return;
}
var effectivePaintId = this._lastPaintWithLayer.args["data"]["nodeId"];
var paintFrameId = paintEvent.args["data"]["frame"];
var types = [WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking,
WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking,
WebInspector.TimelineModel.RecordType.PaintInvalidationTracking,
WebInspector.TimelineModel.RecordType.ScrollInvalidationTracking];
for (var invalidation of this._invalidationsOfTypes(types)) {
if (invalidation.paintId === effectivePaintId)
this._addInvalidationToEvent(paintEvent, paintFrameId, invalidation);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} eventFrameId
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
_addInvalidationToEvent: function(event, eventFrameId, invalidation)
{
if (eventFrameId !== invalidation.frame)
return;
if (!event.invalidationTrackingEvents)
event.invalidationTrackingEvents = [ invalidation ];
else
event.invalidationTrackingEvents.push(invalidation);
},
/**
* @param {!Array.<string>=} types
* @return {!Iterator.<!WebInspector.InvalidationTrackingEvent>}
*/
_invalidationsOfTypes: function(types)
{
var invalidations = this._invalidations;
if (!types)
types = Object.keys(invalidations);
function* generator()
{
for (var i = 0; i < types.length; ++i) {
var invalidationList = invalidations[types[i]] || [];
for (var j = 0; j < invalidationList.length; ++j)
yield invalidationList[j];
}
}
return generator();
},
_startNewFrameIfNeeded: function()
{
if (!this._didPaint)
return;
this._initializePerFrameState();
},
_initializePerFrameState: function()
{
/** @type {!Object.<string, !Array.<!WebInspector.InvalidationTrackingEvent>>} */
this._invalidations = {};
/** @type {!Object.<number, !Array.<!WebInspector.InvalidationTrackingEvent>>} */
this._invalidationsByNodeId = {};
this._lastRecalcStyle = undefined;
this._lastPaintWithLayer = undefined;
this._didPaint = false;
}
}
/**
* @constructor
*/
WebInspector.TimelineAsyncEventTracker = function()
{
WebInspector.TimelineAsyncEventTracker._initialize();
/** @type {!Map<!WebInspector.TimelineModel.RecordType, !Map<string, !WebInspector.TracingModel.Event>>} */
this._initiatorByType = new Map();
for (var initiator of WebInspector.TimelineAsyncEventTracker._asyncEvents.keys())
this._initiatorByType.set(initiator, new Map());
}
WebInspector.TimelineAsyncEventTracker._initialize = function()
{
if (WebInspector.TimelineAsyncEventTracker._asyncEvents)
return;
var events = new Map();
var type = WebInspector.TimelineModel.RecordType;
events.set(type.TimerInstall, {causes: [type.TimerFire], joinBy: "timerId"});
events.set(type.ResourceSendRequest, {causes: [type.ResourceReceiveResponse, type.ResourceReceivedData, type.ResourceFinish], joinBy: "requestId"});
events.set(type.RequestAnimationFrame, {causes: [type.FireAnimationFrame], joinBy: "id"});
events.set(type.RequestIdleCallback, {causes: [type.FireIdleCallback], joinBy: "id"});
events.set(type.WebSocketCreate, {causes: [type.WebSocketSendHandshakeRequest, type.WebSocketReceiveHandshakeResponse, type.WebSocketDestroy], joinBy: "identifier"});
WebInspector.TimelineAsyncEventTracker._asyncEvents = events;
/** @type {!Map<!WebInspector.TimelineModel.RecordType, !WebInspector.TimelineModel.RecordType>} */
WebInspector.TimelineAsyncEventTracker._typeToInitiator = new Map();
for (var entry of events) {
var types = entry[1].causes;
for (type of types)
WebInspector.TimelineAsyncEventTracker._typeToInitiator.set(type, entry[0]);
}
}
WebInspector.TimelineAsyncEventTracker.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
*/
processEvent: function(event)
{
var initiatorType = WebInspector.TimelineAsyncEventTracker._typeToInitiator.get(/** @type {!WebInspector.TimelineModel.RecordType} */ (event.name));
var isInitiator = !initiatorType;
if (!initiatorType)
initiatorType = /** @type {!WebInspector.TimelineModel.RecordType} */ (event.name);
var initiatorInfo = WebInspector.TimelineAsyncEventTracker._asyncEvents.get(initiatorType);
if (!initiatorInfo)
return;
var id = event.args["data"][initiatorInfo.joinBy];
if (!id)
return;
/** @type {!Map<string, !WebInspector.TracingModel.Event>|undefined} */
var initiatorMap = this._initiatorByType.get(initiatorType);
if (isInitiator)
initiatorMap.set(id, event);
else
event.initiator = initiatorMap.get(id) || null;
}
}
/**
* @constructor
*/
WebInspector.TimelineModel.LineLevelProfile = function()
{
/** @type {!Map<string, !Map<number, number>>} */
this._files = new Map();
}
WebInspector.TimelineModel.LineLevelProfile.prototype = {
/**
* @param {!WebInspector.CPUProfileDataModel} profile
*/
appendCPUProfile: function(profile)
{
var nodesToGo = [profile.profileHead];
var sampleDuration = (profile.profileEndTime - profile.profileStartTime) / profile.totalHitCount;
while (nodesToGo.length) {
var nodes = nodesToGo.pop().children;
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
nodesToGo.push(node);
if (!node.url || !node.positionTicks)
continue;
var fileInfo = this._files.get(node.url);
if (!fileInfo) {
fileInfo = new Map();
this._files.set(node.url, fileInfo);
}
for (var j = 0; j < node.positionTicks.length; ++j) {
var lineInfo = node.positionTicks[j];
var line = lineInfo.line;
var time = lineInfo.ticks * sampleDuration;
fileInfo.set(line, (fileInfo.get(line) || 0) + time);
}
}
}
},
/**
* @return {!Map<string, !Map<number, number>>}
*/
files: function()
{
return this._files;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | 2 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.TracingTimelineFrameModel} frameModel
* @extends {WebInspector.SplitWidget}
*/
WebInspector.TimelinePaintProfilerView = function(frameModel)
{
WebInspector.SplitWidget.call(this, false, false);
this.element.classList.add("timeline-paint-profiler-view");
this.setSidebarSize(60);
this.setResizable(false);
this._frameModel = frameModel;
this._logAndImageSplitWidget = new WebInspector.SplitWidget(true, false);
this._logAndImageSplitWidget.element.classList.add("timeline-paint-profiler-log-split");
this.setMainWidget(this._logAndImageSplitWidget);
this._imageView = new WebInspector.TimelinePaintImageView();
this._logAndImageSplitWidget.setMainWidget(this._imageView);
this._paintProfilerView = new WebInspector.PaintProfilerView(this._imageView.showImage.bind(this._imageView));
this._paintProfilerView.addEventListener(WebInspector.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this);
this.setSidebarWidget(this._paintProfilerView);
this._logTreeView = new WebInspector.PaintProfilerCommandLogView();
this._logAndImageSplitWidget.setSidebarWidget(this._logTreeView);
}
WebInspector.TimelinePaintProfilerView.prototype = {
wasShown: function()
{
if (this._updateWhenVisible) {
this._updateWhenVisible = false;
this._update();
}
},
/**
* @param {!WebInspector.Target} target
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
setEvent: function(target, event)
{
this._disposeSnapshot();
this._target = target;
this._event = event;
if (this.isShowing())
this._update();
else
this._updateWhenVisible = true;
if (this._event.name === WebInspector.TimelineModel.RecordType.Paint)
return !!event.picture;
if (this._event.name === WebInspector.TimelineModel.RecordType.RasterTask)
return this._frameModel.hasRasterTile(this._event);
return false;
},
_update: function()
{
this._logTreeView.setCommandLog(null, []);
this._paintProfilerView.setSnapshotAndLog(null, [], null);
if (this._event.name === WebInspector.TimelineModel.RecordType.Paint)
this._event.picture.requestObject(onDataAvailable.bind(this));
else if (this._event.name === WebInspector.TimelineModel.RecordType.RasterTask)
this._frameModel.requestRasterTile(this._event, onSnapshotLoaded.bind(this))
else
console.assert(false, "Unexpected event type: " + this._event.name);
/**
* @param {!Object} data
* @this WebInspector.TimelinePaintProfilerView
*/
function onDataAvailable(data)
{
if (data)
WebInspector.PaintProfilerSnapshot.load(this._target, data["skp64"], onSnapshotLoaded.bind(this, null));
}
/**
* @param {?DOMAgent.Rect} tileRect
* @param {?WebInspector.PaintProfilerSnapshot} snapshot
* @this WebInspector.TimelinePaintProfilerView
*/
function onSnapshotLoaded(tileRect, snapshot)
{
this._disposeSnapshot();
this._lastLoadedSnapshot = snapshot;
this._imageView.setMask(tileRect);
if (!snapshot) {
this._imageView.showImage();
return;
}
snapshot.commandLog(onCommandLogDone.bind(this, snapshot, tileRect));
}
/**
* @param {!WebInspector.PaintProfilerSnapshot} snapshot
* @param {?DOMAgent.Rect} clipRect
* @param {!Array.<!WebInspector.PaintProfilerLogItem>=} log
* @this {WebInspector.TimelinePaintProfilerView}
*/
function onCommandLogDone(snapshot, clipRect, log)
{
this._logTreeView.setCommandLog(snapshot.target(), log || []);
this._paintProfilerView.setSnapshotAndLog(snapshot, log || [], clipRect);
}
},
_disposeSnapshot: function()
{
if (!this._lastLoadedSnapshot)
return;
this._lastLoadedSnapshot.dispose();
this._lastLoadedSnapshot = null;
},
_onWindowChanged: function()
{
var window = this._paintProfilerView.windowBoundaries();
this._logTreeView.updateWindow(window.left, window.right);
},
__proto__: WebInspector.SplitWidget.prototype
};
/**
* @constructor
* @extends {WebInspector.Widget}
*/
WebInspector.TimelinePaintImageView = function()
{
WebInspector.Widget.call(this);
this.element.classList.add("fill", "paint-profiler-image-view");
this._imageContainer = this.element.createChild("div", "paint-profiler-image-container");
this._imageElement = this._imageContainer.createChild("img");
this._maskElement = this._imageContainer.createChild("div");
this._imageElement.addEventListener("load", this._updateImagePosition.bind(this), false);
this._transformController = new WebInspector.TransformController(this.element, true);
this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged, this._updateImagePosition, this);
}
WebInspector.TimelinePaintImageView.prototype = {
onResize: function()
{
if (this._imageElement.src)
this._updateImagePosition();
},
_updateImagePosition: function()
{
var width = this._imageElement.naturalWidth;
var height = this._imageElement.naturalHeight;
var clientWidth = this.element.clientWidth;
var clientHeight = this.element.clientHeight;
var paddingFraction = 0.1;
var paddingX = clientWidth * paddingFraction;
var paddingY = clientHeight * paddingFraction;
var scaleX = (clientWidth - paddingX) / width;
var scaleY = (clientHeight - paddingY) / height;
var scale = Math.min(scaleX, scaleY);
if (this._maskRectangle) {
var style = this._maskElement.style;
style.width = width + "px";
style.height = height + "px";
style.borderLeftWidth = this._maskRectangle.x + "px";
style.borderTopWidth = this._maskRectangle.y + "px";
style.borderRightWidth = (width - this._maskRectangle.x - this._maskRectangle.width) + "px";
style.borderBottomWidth = (height - this._maskRectangle.y - this._maskRectangle.height) + "px";
}
this._transformController.setScaleConstraints(0.5, 10 / scale);
var matrix = new WebKitCSSMatrix()
.scale(this._transformController.scale(), this._transformController.scale())
.translate(clientWidth / 2, clientHeight / 2)
.scale(scale, scale)
.translate(-width / 2, -height / 2);
var bounds = WebInspector.Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]);
this._transformController.clampOffsets(paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX,
paddingY - bounds.maxY, clientHeight - paddingY - bounds.minY);
matrix = new WebKitCSSMatrix().translate(this._transformController.offsetX(), this._transformController.offsetY()).multiply(matrix);
this._imageContainer.style.webkitTransform = matrix.toString();
},
/**
* @param {string=} imageURL
*/
showImage: function(imageURL)
{
this._imageContainer.classList.toggle("hidden", !imageURL);
if (imageURL)
this._imageElement.src = imageURL;
},
/**
* @param {?DOMAgent.Rect} maskRectangle
*/
setMask: function(maskRectangle)
{
this._maskRectangle = maskRectangle;
this._maskElement.classList.toggle("hidden", !maskRectangle);
},
__proto__: WebInspector.Widget.prototype
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2012 Intel Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Panel}
* @implements {WebInspector.TimelineLifecycleDelegate}
* @implements {WebInspector.TimelineModeViewDelegate}
* @implements {WebInspector.Searchable}
*/
WebInspector.TimelinePanel = function()
{
WebInspector.Panel.call(this, "timeline");
this.registerRequiredCSS("timeline/timelinePanel.css");
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);
this._dropTarget = new WebInspector.DropTarget(this.element, [WebInspector.DropTarget.Types.Files, WebInspector.DropTarget.Types.URIList], WebInspector.UIString("Drop timeline file or URL here"), this._handleDrop.bind(this));
this._state = WebInspector.TimelinePanel.State.Idle;
this._detailsLinkifier = new WebInspector.Linkifier();
this._windowStartTime = 0;
this._windowEndTime = Infinity;
this._millisecondsToRecordAfterLoadEvent = 3000;
this._toggleRecordAction = WebInspector.actionRegistry.action("timeline.toggle-recording");
// Create models.
this._tracingModelBackingStorage = new WebInspector.TempFileBackingStorage("tracing");
this._tracingModel = new WebInspector.TracingModel(this._tracingModelBackingStorage);
this._model = new WebInspector.TimelineModel(WebInspector.TimelineUIUtils.visibleEventsFilter());
this._frameModel = new WebInspector.TracingTimelineFrameModel();
this._irModel = new WebInspector.TimelineIRModel();
if (Runtime.experiments.isEnabled("cpuThrottling"))
this._cpuThrottlingManager = new WebInspector.CPUThrottlingManager();
/** @type {!Array.<!WebInspector.TimelineModeView>} */
this._currentViews = [];
this._viewModeSetting = WebInspector.settings.createSetting("timelineViewMode", WebInspector.TimelinePanel.ViewMode.FlameChart);
this._captureNetworkSetting = WebInspector.settings.createSetting("timelineCaptureNetwork", false);
this._captureJSProfileSetting = WebInspector.settings.createSetting("timelineEnableJSSampling", true);
this._captureMemorySetting = WebInspector.settings.createSetting("timelineCaptureMemory", false);
this._captureLayersAndPicturesSetting = WebInspector.settings.createSetting("timelineCaptureLayersAndPictures", false);
this._captureFilmStripSetting = WebInspector.settings.createSetting("timelineCaptureFilmStrip", false);
this._panelToolbar = new WebInspector.Toolbar("", this.element);
this._createToolbarItems();
var timelinePane = new WebInspector.VBox();
timelinePane.show(this.element);
var topPaneElement = timelinePane.element.createChild("div", "hbox");
topPaneElement.id = "timeline-overview-panel";
// Create top overview component.
this._overviewPane = new WebInspector.TimelineOverviewPane("timeline");
this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
this._overviewPane.show(topPaneElement);
this._statusPaneContainer = timelinePane.element.createChild("div", "status-pane-container fill");
this._createFileSelector();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.PageReloadRequested, this._pageReloadRequested, this);
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.Load, this._loadEventFired, this);
// Create top level properties splitter.
this._detailsSplitWidget = new WebInspector.SplitWidget(false, true, "timelinePanelDetailsSplitViewState");
this._detailsSplitWidget.element.classList.add("timeline-details-split");
this._detailsView = new WebInspector.TimelineDetailsView(this._model, this);
this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
this._detailsSplitWidget.setSidebarWidget(this._detailsView);
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.setMinimumSize(0, 100);
this._searchableView.element.classList.add("searchable-view");
this._detailsSplitWidget.setMainWidget(this._searchableView);
this._stackView = new WebInspector.StackView(false);
this._stackView.element.classList.add("timeline-view-stack");
if (Runtime.experiments.isEnabled("multipleTimelineViews")) {
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.appendTab(WebInspector.TimelinePanel.ViewMode.FlameChart, WebInspector.UIString("Flame Chart"), new WebInspector.VBox());
this._tabbedPane.appendTab(WebInspector.TimelinePanel.ViewMode.CallTree, WebInspector.UIString("Call Tree"), new WebInspector.VBox());
this._tabbedPane.appendTab(WebInspector.TimelinePanel.ViewMode.BottomUp, WebInspector.UIString("Bottom-Up"), new WebInspector.VBox());
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._onMainViewChanged.bind(this));
this._tabbedPane.show(this._searchableView.element);
} else {
this._stackView.show(this._searchableView.element);
this._onModeChanged();
}
this._detailsSplitWidget.show(timelinePane.element);
this._detailsSplitWidget.hideSidebar();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
this._showRecordingHelpMessage();
this._locationPool = new WebInspector.LiveLocationPool();
}
/**
* @enum {string}
*/
WebInspector.TimelinePanel.Perspectives = {
Load: "Load",
Responsiveness: "Responsiveness",
Custom: "Custom"
}
/**
* @enum {string}
*/
WebInspector.TimelinePanel.ViewMode = {
FlameChart: "FlameChart",
CallTree: "CallTree",
BottomUp: "BottomUp",
}
/**
* @enum {string}
*/
WebInspector.TimelinePanel.DetailsTab = {
Details: "Details",
Events: "Events",
CallTree: "CallTree",
BottomUp: "BottomUp",
PaintProfiler: "PaintProfiler",
LayerViewer: "LayerViewer"
}
/**
* @enum {symbol}
*/
WebInspector.TimelinePanel.State = {
Idle: Symbol("Idle"),
StartPending: Symbol("StartPending"),
Recording: Symbol("Recording"),
StopPending: Symbol("StopPending"),
Loading: Symbol("Loading")
}
// Define row and header height, should be in sync with styles for timeline graphs.
WebInspector.TimelinePanel.rowHeight = 18;
WebInspector.TimelinePanel.headerHeight = 20;
WebInspector.TimelinePanel.prototype = {
/**
* @override
* @return {?WebInspector.SearchableView}
*/
searchableView: function()
{
return this._searchableView;
},
wasShown: function()
{
WebInspector.context.setFlavor(WebInspector.TimelinePanel, this);
},
willHide: function()
{
WebInspector.context.setFlavor(WebInspector.TimelinePanel, null);
},
/**
* @return {number}
*/
windowStartTime: function()
{
if (this._windowStartTime)
return this._windowStartTime;
return this._model.minimumRecordTime();
},
/**
* @return {number}
*/
windowEndTime: function()
{
if (this._windowEndTime < Infinity)
return this._windowEndTime;
return this._model.maximumRecordTime() || Infinity;
},
/**
* @param {!WebInspector.Event} event
*/
_onWindowChanged: function(event)
{
this._windowStartTime = event.data.startTime;
this._windowEndTime = event.data.endTime;
for (var i = 0; i < this._currentViews.length; ++i)
this._currentViews[i].setWindowTimes(this._windowStartTime, this._windowEndTime);
if (!this._selection || this._selection.type() === WebInspector.TimelineSelection.Type.Range)
this.select(null);
},
_onMainViewChanged: function()
{
this._viewModeSetting.set(this._tabbedPane.selectedTabId);
this._onModeChanged();
},
/**
* @param {!WebInspector.Event} event
*/
_onOverviewSelectionChanged: function(event)
{
var selection = /** @type {!WebInspector.TimelineSelection} */ (event.data);
this.select(selection);
},
/**
* @override
* @param {number} windowStartTime
* @param {number} windowEndTime
*/
requestWindowTimes: function(windowStartTime, windowEndTime)
{
this._overviewPane.requestWindowTimes(windowStartTime, windowEndTime);
},
/**
* @return {!WebInspector.Widget}
*/
_layersView: function()
{
if (this._lazyLayersView)
return this._lazyLayersView;
this._lazyLayersView = new WebInspector.TimelineLayersView(this._model, showPaintEventDetails.bind(this));
return this._lazyLayersView;
/**
* @param {!WebInspector.TracingModel.Event} event
* @this {WebInspector.TimelinePanel}
*/
function showPaintEventDetails(event)
{
this._showEventInPaintProfiler(event, true);
this._detailsView.selectTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler, true);
}
},
_paintProfilerView: function()
{
if (this._lazyPaintProfilerView)
return this._lazyPaintProfilerView;
this._lazyPaintProfilerView = new WebInspector.TimelinePaintProfilerView(this._frameModel);
return this._lazyPaintProfilerView;
},
/**
* @param {!WebInspector.TimelineModeView} modeView
*/
_addModeView: function(modeView)
{
modeView.setWindowTimes(this.windowStartTime(), this.windowEndTime());
modeView.refreshRecords();
var splitWidget = this._stackView.appendView(modeView.view(), "timelinePanelTimelineStackSplitViewState", undefined, 112);
var resizer = modeView.resizerElement();
if (splitWidget && resizer) {
splitWidget.hideDefaultResizer();
splitWidget.installResizer(resizer);
}
this._currentViews.push(modeView);
},
_removeAllModeViews: function()
{
this._currentViews.forEach(view => view.dispose());
this._currentViews = [];
this._stackView.detachChildWidgets();
},
/**
* @param {!WebInspector.TimelinePanel.State} state
*/
_setState: function(state)
{
this._state = state;
this._updateTimelineControls();
},
/**
* @param {string} name
* @param {!WebInspector.Setting} setting
* @param {string} tooltip
* @return {!WebInspector.ToolbarItem}
*/
_createSettingCheckbox: function(name, setting, tooltip)
{
if (!this._recordingOptionUIControls)
this._recordingOptionUIControls = [];
var checkboxItem = new WebInspector.ToolbarCheckbox(name, tooltip, setting);
this._recordingOptionUIControls.push(checkboxItem);
return checkboxItem;
},
_createToolbarItems: function()
{
this._panelToolbar.removeToolbarItems();
var perspectiveSetting = WebInspector.settings.createSetting("timelinePerspective", WebInspector.TimelinePanel.Perspectives.Load);
if (Runtime.experiments.isEnabled("timelineRecordingPerspectives")) {
/**
* @this {!WebInspector.TimelinePanel}
*/
function onPerspectiveChanged()
{
perspectiveSetting.set(perspectiveCombobox.selectElement().value);
this._createToolbarItems();
}
/**
* @param {string} id
* @param {string} title
*/
function addPerspectiveOption(id, title)
{
var option = perspectiveCombobox.createOption(title, "", id);
perspectiveCombobox.addOption(option);
if (id === perspectiveSetting.get())
perspectiveCombobox.select(option);
}
var perspectiveCombobox = new WebInspector.ToolbarComboBox(onPerspectiveChanged.bind(this));
addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Load, WebInspector.UIString("Page Load"));
addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Responsiveness, WebInspector.UIString("Responsiveness"));
addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Custom, WebInspector.UIString("Custom"));
this._panelToolbar.appendToolbarItem(perspectiveCombobox);
switch (perspectiveSetting.get()) {
case WebInspector.TimelinePanel.Perspectives.Load:
this._captureNetworkSetting.set(true);
this._captureJSProfileSetting.set(true);
this._captureMemorySetting.set(false);
this._captureLayersAndPicturesSetting.set(false);
this._captureFilmStripSetting.set(true);
break;
case WebInspector.TimelinePanel.Perspectives.Responsiveness:
this._captureNetworkSetting.set(true);
this._captureJSProfileSetting.set(true);
this._captureMemorySetting.set(false);
this._captureLayersAndPicturesSetting.set(false);
this._captureFilmStripSetting.set(false);
break;
}
}
if (Runtime.experiments.isEnabled("timelineRecordingPerspectives") && perspectiveSetting.get() === WebInspector.TimelinePanel.Perspectives.Load) {
this._reloadButton = new WebInspector.ToolbarButton(WebInspector.UIString("Record & Reload"), "refresh-toolbar-item");
this._reloadButton.addEventListener("click", () => WebInspector.targetManager.reloadPage());
this._panelToolbar.appendToolbarItem(this._reloadButton);
} else {
this._panelToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleRecordAction));
}
this._updateTimelineControls();
var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear recording"), "clear-toolbar-item");
clearButton.addEventListener("click", this._clear, this);
this._panelToolbar.appendToolbarItem(clearButton);
this._panelToolbar.appendSeparator();
this._panelToolbar.appendText(WebInspector.UIString("Capture:"));
this._captureNetworkSetting.addChangeListener(this._onNetworkChanged, this);
if (!Runtime.experiments.isEnabled("timelineRecordingPerspectives") || perspectiveSetting.get() === WebInspector.TimelinePanel.Perspectives.Custom) {
if (Runtime.experiments.isEnabled("networkRequestsOnTimeline")) {
this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Network"),
this._captureNetworkSetting,
WebInspector.UIString("Capture network requests information")));
}
this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("JS Profile"),
this._captureJSProfileSetting,
WebInspector.UIString("Capture JavaScript stacks with sampling profiler. (Has performance overhead)")));
this._captureMemorySetting.addChangeListener(this._onModeChanged, this);
this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Memory"),
this._captureMemorySetting,
WebInspector.UIString("Capture memory information on every timeline event.")));
this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Paint"),
this._captureLayersAndPicturesSetting,
WebInspector.UIString("Capture graphics layer positions and painted pictures. (Has performance overhead)")));
}
this._captureFilmStripSetting.addChangeListener(this._onModeChanged, this);
this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Screenshots"),
this._captureFilmStripSetting,
WebInspector.UIString("Capture screenshots while recording. (Has performance overhead)")));
this._panelToolbar.appendSeparator();
var garbageCollectButton = new WebInspector.ToolbarButton(WebInspector.UIString("Collect garbage"), "garbage-collect-toolbar-item");
garbageCollectButton.addEventListener("click", this._garbageCollectButtonClicked, this);
this._panelToolbar.appendToolbarItem(garbageCollectButton);
if (Runtime.experiments.isEnabled("cpuThrottling")) {
this._panelToolbar.appendSeparator();
this._cpuThrottlingCombobox = new WebInspector.ToolbarComboBox(this._onCPUThrottlingChanged.bind(this));
/**
* @param {string} name
* @param {number} value
* @this {WebInspector.TimelinePanel}
*/
function addGroupingOption(name, value)
{
var option = this._cpuThrottlingCombobox.createOption(name, "", String(value));
this._cpuThrottlingCombobox.addOption(option);
if (value === this._cpuThrottlingManager.rate())
this._cpuThrottlingCombobox.select(option);
}
addGroupingOption.call(this, WebInspector.UIString("No CPU throttling"), 1);
for (var rate of [1.2, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 30, 50])
addGroupingOption.call(this, WebInspector.UIString("%fx slowdown", rate), rate);
this._panelToolbar.appendToolbarItem(this._cpuThrottlingCombobox);
}
},
_prepareToLoadTimeline: function()
{
console.assert(this._state === WebInspector.TimelinePanel.State.Idle);
this._setState(WebInspector.TimelinePanel.State.Loading);
},
_createFileSelector: function()
{
if (this._fileSelectorElement)
this._fileSelectorElement.remove();
this._fileSelectorElement = WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));
this.element.appendChild(this._fileSelectorElement);
},
/**
* @param {!Event} event
*/
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
var disabled = this._state !== WebInspector.TimelinePanel.State.Idle;
contextMenu.appendItem(WebInspector.UIString.capitalize("Save Timeline ^data\u2026"), this._saveToFile.bind(this), disabled);
contextMenu.appendItem(WebInspector.UIString.capitalize("Load Timeline ^data\u2026"), this._selectFileToLoad.bind(this), disabled);
contextMenu.show();
},
/**
* @return {boolean}
*/
_saveToFile: function()
{
if (this._state !== WebInspector.TimelinePanel.State.Idle)
return true;
var now = new Date();
var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json";
var stream = new WebInspector.FileOutputStream();
/**
* @param {boolean} accepted
* @this {WebInspector.TimelinePanel}
*/
function callback(accepted)
{
if (!accepted)
return;
var saver = new WebInspector.TracingTimelineSaver();
this._tracingModelBackingStorage.writeToStream(stream, saver);
}
stream.open(fileName, callback.bind(this));
return true;
},
/**
* @return {boolean}
*/
_selectFileToLoad: function()
{
this._fileSelectorElement.click();
return true;
},
/**
* @param {!File} file
*/
_loadFromFile: function(file)
{
if (this._state !== WebInspector.TimelinePanel.State.Idle)
return;
this._prepareToLoadTimeline();
this._loader = WebInspector.TimelineLoader.loadFromFile(this._tracingModel, file, this);
this._createFileSelector();
},
/**
* @param {string} url
*/
_loadFromURL: function(url)
{
if (this._state !== WebInspector.TimelinePanel.State.Idle)
return;
this._prepareToLoadTimeline();
this._loader = WebInspector.TimelineLoader.loadFromURL(this._tracingModel, url, this);
},
_refreshViews: function()
{
for (var i = 0; i < this._currentViews.length; ++i) {
var view = this._currentViews[i];
view.refreshRecords();
}
this._updateSelectionDetails();
},
_onModeChanged: function()
{
// Set up overview controls.
this._overviewControls = [];
this._overviewControls.push(new WebInspector.TimelineEventOverview.Responsiveness(this._model, this._frameModel));
if (Runtime.experiments.isEnabled("inputEventsOnTimelineOverview"))
this._overviewControls.push(new WebInspector.TimelineEventOverview.Input(this._model));
this._overviewControls.push(new WebInspector.TimelineEventOverview.Frames(this._model, this._frameModel));
this._overviewControls.push(new WebInspector.TimelineEventOverview.CPUActivity(this._model));
this._overviewControls.push(new WebInspector.TimelineEventOverview.Network(this._model));
if (this._captureFilmStripSetting.get())
this._overviewControls.push(new WebInspector.TimelineFilmStripOverview(this._model, this._tracingModel));
if (this._captureMemorySetting.get())
this._overviewControls.push(new WebInspector.TimelineEventOverview.Memory(this._model));
this._overviewPane.setOverviewControls(this._overviewControls);
// Set up the main view.
this._removeAllModeViews();
var viewMode = WebInspector.TimelinePanel.ViewMode.FlameChart;
this._flameChart = null;
if (Runtime.experiments.isEnabled("multipleTimelineViews")) {
viewMode = this._tabbedPane.selectedTabId;
this._stackView.detach();
this._stackView.show(this._tabbedPane.visibleView.element);
}
if (viewMode === WebInspector.TimelinePanel.ViewMode.FlameChart) {
this._flameChart = new WebInspector.TimelineFlameChartView(this, this._model, this._frameModel, this._irModel);
this._flameChart.enableNetworkPane(this._captureNetworkSetting.get());
this._addModeView(this._flameChart);
} else if (viewMode === WebInspector.TimelinePanel.ViewMode.CallTree || viewMode === WebInspector.TimelinePanel.ViewMode.BottomUp) {
var innerView = viewMode === WebInspector.TimelinePanel.ViewMode.BottomUp ? new WebInspector.BottomUpTimelineTreeView(this._model) : new WebInspector.CallTreeTimelineTreeView(this._model);
var treeView = new WebInspector.TimelineTreeModeView(this, innerView);
this._addModeView(treeView);
}
if (this._captureMemorySetting.get() && viewMode !== WebInspector.TimelinePanel.ViewMode.CallTree && viewMode !== WebInspector.TimelinePanel.ViewMode.BottomUp)
this._addModeView(new WebInspector.MemoryCountersGraph(this, this._model, [WebInspector.TimelineUIUtils.visibleEventsFilter()]));
this.doResize();
this.select(null);
},
_onNetworkChanged: function()
{
if (this._flameChart)
this._flameChart.enableNetworkPane(this._captureNetworkSetting.get(), true);
},
_onCPUThrottlingChanged: function()
{
if (!this._cpuThrottlingManager)
return;
var value = Number.parseFloat(this._cpuThrottlingCombobox.selectedOption().value);
this._cpuThrottlingManager.setRate(value);
},
/**
* @param {boolean} enabled
*/
_setUIControlsEnabled: function(enabled)
{
/**
* @param {!WebInspector.ToolbarButton} toolbarButton
*/
function handler(toolbarButton)
{
toolbarButton.setEnabled(enabled);
}
this._recordingOptionUIControls.forEach(handler);
},
/**
* @param {boolean} userInitiated
*/
_startRecording: function(userInitiated)
{
console.assert(!this._statusPane, "Status pane is already opened.");
var mainTarget = WebInspector.targetManager.mainTarget();
if (!mainTarget)
return;
this._setState(WebInspector.TimelinePanel.State.StartPending);
this._showRecordingStarted();
this._autoRecordGeneration = userInitiated ? null : Symbol("Generation");
this._controller = new WebInspector.TimelineController(mainTarget, this, this._tracingModel);
this._controller.startRecording(true, this._captureJSProfileSetting.get(), this._captureMemorySetting.get(), this._captureLayersAndPicturesSetting.get(), this._captureFilmStripSetting && this._captureFilmStripSetting.get());
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].timelineStarted();
if (userInitiated)
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.TimelineStarted);
this._setUIControlsEnabled(false);
this._hideRecordingHelpMessage();
},
_stopRecording: function()
{
if (this._statusPane) {
this._statusPane.finish();
this._statusPane.updateStatus(WebInspector.UIString("Stopping timeline\u2026"));
this._statusPane.updateProgressBar(WebInspector.UIString("Received"), 0);
}
this._setState(WebInspector.TimelinePanel.State.StopPending);
this._autoRecordGeneration = null;
this._controller.stopRecording();
this._controller = null;
this._setUIControlsEnabled(true);
},
_onSuspendStateChanged: function()
{
this._updateTimelineControls();
},
_updateTimelineControls: function()
{
var state = WebInspector.TimelinePanel.State;
var title =
this._state === state.Idle ? WebInspector.UIString("Record") :
this._state === state.Recording ? WebInspector.UIString("Stop") : "";
this._toggleRecordAction.setTitle(title);
this._toggleRecordAction.setToggled(this._state === state.Recording);
this._toggleRecordAction.setEnabled(this._state === state.Recording || this._state === state.Idle);
this._panelToolbar.setEnabled(this._state !== state.Loading);
this._dropTarget.setEnabled(this._state === state.Idle);
},
_toggleRecording: function()
{
if (this._state === WebInspector.TimelinePanel.State.Idle)
this._startRecording(true);
else if (this._state === WebInspector.TimelinePanel.State.Recording)
this._stopRecording();
},
_garbageCollectButtonClicked: function()
{
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i)
targets[i].heapProfilerAgent().collectGarbage();
},
_clear: function()
{
this._tracingModel.reset();
this._model.reset();
this._resetLineLevelCPUProfile();
this._showRecordingHelpMessage();
this.requestWindowTimes(0, Infinity);
delete this._selection;
this._frameModel.reset();
this._overviewPane.reset();
for (var i = 0; i < this._currentViews.length; ++i)
this._currentViews[i].reset();
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].reset();
this.select(null);
delete this._filmStripModel;
this._detailsSplitWidget.hideSidebar();
},
/**
* @override
*/
recordingStarted: function()
{
this._clear();
this._setState(WebInspector.TimelinePanel.State.Recording);
this._showRecordingStarted();
this._statusPane.updateStatus(WebInspector.UIString("Recording\u2026"));
this._statusPane.updateProgressBar(WebInspector.UIString("Buffer usage"), 0)
this._statusPane.startTimer();
this._hideRecordingHelpMessage();
},
/**
* @override
* @param {number} usage
*/
recordingProgress: function(usage)
{
this._statusPane.updateProgressBar(WebInspector.UIString("Buffer usage"), usage * 100);
},
_showRecordingHelpMessage: function()
{
/**
* @param {string} tagName
* @param {string} contents
* @return {!Element}
*/
function encloseWithTag(tagName, contents)
{
var e = createElement(tagName);
e.textContent = contents;
return e;
}
var recordNode = encloseWithTag("b", WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.toggle-recording")[0].name);
var reloadNode = encloseWithTag("b", WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name);
var navigateNode = encloseWithTag("b", WebInspector.UIString("WASD"));
var hintText = createElementWithClass("div");
hintText.appendChild(WebInspector.formatLocalized("To capture a new timeline, click the record toolbar button or hit %s.", [recordNode]));
hintText.createChild("br");
hintText.appendChild(WebInspector.formatLocalized("To evaluate page load performance, hit %s to record the reload.", [reloadNode]));
hintText.createChild("p");
hintText.appendChild(WebInspector.formatLocalized("After recording, select an area of interest in the overview by dragging.", []));
hintText.createChild("br");
hintText.appendChild(WebInspector.formatLocalized("Then, zoom and pan the timeline with the mousewheel and %s keys.", [navigateNode]));
this._hideRecordingHelpMessage();
this._helpMessageElement = this._searchableView.element.createChild("div", "banner timeline-status-pane");
this._helpMessageElement.appendChild(hintText);
},
_hideRecordingHelpMessage: function()
{
if (this._helpMessageElement)
this._helpMessageElement.remove();
delete this._helpMessageElement;
},
/**
* @override
*/
loadingStarted: function()
{
this._hideRecordingHelpMessage();
if (this._statusPane)
this._statusPane.hide();
this._statusPane = new WebInspector.TimelinePanel.StatusPane(false, this._cancelLoading.bind(this));
this._statusPane.showPane(this._statusPaneContainer);
this._statusPane.updateStatus(WebInspector.UIString("Loading timeline\u2026"));
// FIXME: make loading from backend cancelable as well.
if (!this._loader)
this._statusPane.finish();
this.loadingProgress(0);
},
/**
* @override
* @param {number=} progress
*/
loadingProgress: function(progress)
{
if (typeof progress === "number")
this._statusPane.updateProgressBar(WebInspector.UIString("Received"), progress * 100);
},
/**
* @override
* @param {boolean} success
*/
loadingComplete: function(success)
{
var loadedFromFile = !!this._loader;
delete this._loader;
this._setState(WebInspector.TimelinePanel.State.Idle);
if (!success) {
this._statusPane.hide();
delete this._statusPane;
this._clear();
return;
}
if (this._statusPane)
this._statusPane.updateStatus(WebInspector.UIString("Processing timeline\u2026"));
this._model.setEvents(this._tracingModel, loadedFromFile);
this._frameModel.reset();
this._frameModel.addTraceEvents(this._model.target(), this._model.inspectedTargetEvents(), this._model.sessionId() || "");
this._irModel.populate(this._model);
this._setLineLevelCPUProfile(this._model.lineLevelCPUProfile());
if (this._statusPane)
this._statusPane.hide();
delete this._statusPane;
this._overviewPane.reset();
this._overviewPane.setBounds(this._model.minimumRecordTime(), this._model.maximumRecordTime());
this._setAutoWindowTimes();
this._refreshViews();
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].timelineStopped();
this._setMarkers();
this._overviewPane.scheduleUpdate();
this._updateSearchHighlight(false, true);
this._detailsSplitWidget.showBoth();
},
_showRecordingStarted: function()
{
if (this._statusPane)
return;
this._statusPane = new WebInspector.TimelinePanel.StatusPane(true, this._stopRecording.bind(this));
this._statusPane.showPane(this._statusPaneContainer);
this._statusPane.updateStatus(WebInspector.UIString("Initializing recording\u2026"));
},
_cancelLoading: function()
{
if (this._loader)
this._loader.cancel();
},
_setMarkers: function()
{
var markers = new Map();
var recordTypes = WebInspector.TimelineModel.RecordType;
var zeroTime = this._model.minimumRecordTime();
for (var record of this._model.eventDividerRecords()) {
if (record.type() === recordTypes.TimeStamp || record.type() === recordTypes.ConsoleTime)
continue;
markers.set(record.startTime(), WebInspector.TimelineUIUtils.createDividerForRecord(record, zeroTime, 0));
}
this._overviewPane.setMarkers(markers);
},
/**
* @param {!WebInspector.Event} event
*/
_pageReloadRequested: function(event)
{
if (this._state !== WebInspector.TimelinePanel.State.Idle || !this.isShowing())
return;
this._startRecording(false);
},
/**
* @param {!WebInspector.Event} event
*/
_loadEventFired: function(event)
{
if (this._state !== WebInspector.TimelinePanel.State.Recording || !this._autoRecordGeneration)
return;
setTimeout(stopRecordingOnReload.bind(this, this._autoRecordGeneration), this._millisecondsToRecordAfterLoadEvent);
/**
* @this {WebInspector.TimelinePanel}
* @param {!Object} recordGeneration
*/
function stopRecordingOnReload(recordGeneration)
{
// Check if we're still in the same recording session.
if (this._state !== WebInspector.TimelinePanel.State.Recording || this._autoRecordGeneration !== recordGeneration)
return;
this._stopRecording();
}
},
// WebInspector.Searchable implementation
/**
* @override
*/
jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : -1;
this._jumpToSearchResult(index + 1);
},
/**
* @override
*/
jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : 0;
this._jumpToSearchResult(index - 1);
},
/**
* @override
* @return {boolean}
*/
supportsCaseSensitiveSearch: function()
{
return false;
},
/**
* @override
* @return {boolean}
*/
supportsRegexSearch: function()
{
return false;
},
/**
* @param {number} index
*/
_jumpToSearchResult: function(index)
{
this._selectSearchResult((index + this._searchResults.length) % this._searchResults.length);
this._currentViews[0].highlightSearchResult(this._selectedSearchResult, this._searchRegex, true);
},
/**
* @param {number} index
*/
_selectSearchResult: function(index)
{
this._selectedSearchResult = this._searchResults[index];
this._searchableView.updateCurrentMatchIndex(index);
},
_clearHighlight: function()
{
this._currentViews[0].highlightSearchResult(null);
},
/**
* @param {boolean} revealRecord
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
_updateSearchHighlight: function(revealRecord, shouldJump, jumpBackwards)
{
if (!this._searchRegex) {
this._clearHighlight();
return;
}
if (!this._searchResults)
this._updateSearchResults(shouldJump, jumpBackwards);
this._currentViews[0].highlightSearchResult(this._selectedSearchResult, this._searchRegex, revealRecord);
},
/**
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
_updateSearchResults: function(shouldJump, jumpBackwards)
{
var searchRegExp = this._searchRegex;
if (!searchRegExp)
return;
var matches = [];
/**
* @param {!WebInspector.TimelineModel.Record} record
* @this {WebInspector.TimelinePanel}
*/
function processRecord(record)
{
if (record.endTime() < this._windowStartTime ||
record.startTime() > this._windowEndTime)
return;
if (WebInspector.TimelineUIUtils.testContentMatching(record.traceEvent(), searchRegExp))
matches.push(record);
}
this._model.forAllFilteredRecords([WebInspector.TimelineUIUtils.visibleEventsFilter()], processRecord.bind(this));
var matchesCount = matches.length;
if (matchesCount) {
this._searchResults = matches;
this._searchableView.updateSearchMatchesCount(matchesCount);
var selectedIndex = matches.indexOf(this._selectedSearchResult);
if (shouldJump && selectedIndex === -1)
selectedIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
this._selectSearchResult(selectedIndex);
} else {
this._searchableView.updateSearchMatchesCount(0);
delete this._selectedSearchResult;
}
},
/**
* @override
*/
searchCanceled: function()
{
this._clearHighlight();
delete this._searchResults;
delete this._selectedSearchResult;
delete this._searchRegex;
},
/**
* @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
var query = searchConfig.query;
this._searchRegex = createPlainTextSearchRegex(query, "i");
delete this._searchResults;
this._updateSearchHighlight(true, shouldJump, jumpBackwards);
},
_updateSelectionDetails: function()
{
switch (this._selection.type()) {
case WebInspector.TimelineSelection.Type.TraceEvent:
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._selection.object());
WebInspector.TimelineUIUtils.buildTraceEventDetails(event, this._model, this._detailsLinkifier, true, this._appendDetailsTabsForTraceEventAndShowDetails.bind(this, event));
break;
case WebInspector.TimelineSelection.Type.Frame:
var frame = /** @type {!WebInspector.TimelineFrame} */ (this._selection.object());
if (!this._filmStripModel)
this._filmStripModel = new WebInspector.FilmStripModel(this._tracingModel);
var screenshotTime = frame.idle ? frame.startTime : frame.endTime; // For idle frames, look at the state at the beginning of the frame.
var filmStripFrame = this._filmStripModel && this._filmStripModel.frameByTimestamp(screenshotTime);
if (filmStripFrame && filmStripFrame.timestamp - frame.endTime > 10)
filmStripFrame = null;
this.showInDetails(WebInspector.TimelineUIUtils.generateDetailsContentForFrame(this._frameModel, frame, filmStripFrame));
if (frame.layerTree) {
var layersView = this._layersView();
layersView.showLayerTree(frame.layerTree, frame.paints);
if (!this._detailsView.hasTab(WebInspector.TimelinePanel.DetailsTab.LayerViewer))
this._detailsView.appendTab(WebInspector.TimelinePanel.DetailsTab.LayerViewer, WebInspector.UIString("Layers"), layersView);
}
break;
case WebInspector.TimelineSelection.Type.NetworkRequest:
var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._selection.object());
WebInspector.TimelineUIUtils.buildNetworkRequestDetails(request, this._model, this._detailsLinkifier)
.then(this.showInDetails.bind(this));
break;
case WebInspector.TimelineSelection.Type.Range:
this._updateSelectedRangeStats(this._selection._startTime, this._selection._endTime);
break;
}
this._detailsView.updateContents(this._selection);
},
/**
* @param {!WebInspector.TimelineSelection} selection
* @return {?WebInspector.TimelineFrame}
*/
_frameForSelection: function(selection)
{
switch (selection.type()) {
case WebInspector.TimelineSelection.Type.Frame:
return /** @type {!WebInspector.TimelineFrame} */ (selection.object());
case WebInspector.TimelineSelection.Type.Range:
return null;
case WebInspector.TimelineSelection.Type.TraceEvent:
return this._frameModel.filteredFrames(selection._endTime, selection._endTime)[0];
default:
console.assert(false, "Should never be reached");
return null;
}
},
/**
* @param {number} offset
*/
_jumpToFrame: function(offset)
{
var currentFrame = this._frameForSelection(this._selection);
if (!currentFrame)
return;
var frames = this._frameModel.frames();
var index = frames.indexOf(currentFrame);
console.assert(index >= 0, "Can't find current frame in the frame list");
index = Number.constrain(index + offset, 0, frames.length - 1);
var frame = frames[index];
this._revealTimeRange(frame.startTime, frame.endTime);
this.select(WebInspector.TimelineSelection.fromFrame(frame));
return true;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {!Node} content
*/
_appendDetailsTabsForTraceEventAndShowDetails: function(event, content)
{
this.showInDetails(content);
if (event.name === WebInspector.TimelineModel.RecordType.Paint || event.name === WebInspector.TimelineModel.RecordType.RasterTask)
this._showEventInPaintProfiler(event);
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {boolean=} isCloseable
*/
_showEventInPaintProfiler: function(event, isCloseable)
{
var target = this._model.target();
if (!target)
return;
var paintProfilerView = this._paintProfilerView();
var hasProfileData = paintProfilerView.setEvent(target, event);
if (!hasProfileData)
return;
if (!this._detailsView.hasTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler))
this._detailsView.appendTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler, WebInspector.UIString("Paint Profiler"), paintProfilerView, undefined, undefined, isCloseable);
},
/**
* @param {number} startTime
* @param {number} endTime
*/
_updateSelectedRangeStats: function(startTime, endTime)
{
this.showInDetails(WebInspector.TimelineUIUtils.buildRangeStats(this._model, startTime, endTime));
},
/**
* @override
* @param {?WebInspector.TimelineSelection} selection
* @param {!WebInspector.TimelinePanel.DetailsTab=} preferredTab
*/
select: function(selection, preferredTab)
{
if (!selection)
selection = WebInspector.TimelineSelection.fromRange(this._windowStartTime, this._windowEndTime);
this._selection = selection;
this._detailsLinkifier.reset();
if (preferredTab)
this._detailsView.setPreferredTab(preferredTab);
for (var view of this._currentViews)
view.setSelection(selection);
this._updateSelectionDetails();
},
/**
* @override
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event)
{
for (var view of this._currentViews)
view.highlightEvent(event);
},
/**
* @param {number} startTime
* @param {number} endTime
*/
_revealTimeRange: function(startTime, endTime)
{
var timeShift = 0;
if (this._windowEndTime < endTime)
timeShift = endTime - this._windowEndTime;
else if (this._windowStartTime > startTime)
timeShift = startTime - this._windowStartTime;
if (timeShift)
this.requestWindowTimes(this._windowStartTime + timeShift, this._windowEndTime + timeShift);
},
/**
* @override
* @param {!Node} node
*/
showInDetails: function(node)
{
this._detailsView.setContent(node);
},
/**
* @param {!DataTransfer} dataTransfer
*/
_handleDrop: function(dataTransfer)
{
var items = dataTransfer.items;
if (!items.length)
return;
var item = items[0];
if (item.kind === "string") {
var url = dataTransfer.getData("text/uri-list");
if (new WebInspector.ParsedURL(url).isValid)
this._loadFromURL(url);
} else if (item.kind === "file") {
var entry = items[0].webkitGetAsEntry();
if (!entry.isFile)
return;
entry.file(this._loadFromFile.bind(this));
}
},
_setAutoWindowTimes: function()
{
var tasks = this._model.mainThreadTasks();
if (!tasks.length) {
this.requestWindowTimes(this._tracingModel.minimumRecordTime(), this._tracingModel.maximumRecordTime());
return;
}
/**
* @param {number} startIndex
* @param {number} stopIndex
* @return {number}
*/
function findLowUtilizationRegion(startIndex, stopIndex)
{
var /** @const */ threshold = 0.1;
var cutIndex = startIndex;
var cutTime = (tasks[cutIndex].startTime() + tasks[cutIndex].endTime()) / 2;
var usedTime = 0;
var step = Math.sign(stopIndex - startIndex);
for (var i = startIndex; i !== stopIndex; i += step) {
var task = tasks[i];
var taskTime = (task.startTime() + task.endTime()) / 2;
var interval = Math.abs(cutTime - taskTime);
if (usedTime < threshold * interval) {
cutIndex = i;
cutTime = taskTime;
usedTime = 0;
}
usedTime += task.endTime() - task.startTime();
}
return cutIndex;
}
var rightIndex = findLowUtilizationRegion(tasks.length - 1, 0);
var leftIndex = findLowUtilizationRegion(0, rightIndex);
var leftTime = tasks[leftIndex].startTime();
var rightTime = tasks[rightIndex].endTime();
var span = rightTime - leftTime;
var totalSpan = this._tracingModel.maximumRecordTime() - this._tracingModel.minimumRecordTime();
if (span < totalSpan * 0.1) {
leftTime = this._tracingModel.minimumRecordTime();
rightTime = this._tracingModel.maximumRecordTime();
} else {
leftTime = Math.max(leftTime - 0.05 * span, this._tracingModel.minimumRecordTime());
rightTime = Math.min(rightTime + 0.05 * span, this._tracingModel.maximumRecordTime());
}
this.requestWindowTimes(leftTime, rightTime);
},
/**
* @param {!WebInspector.TimelineModel.LineLevelProfile} profile
*/
_setLineLevelCPUProfile: function(profile)
{
var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targetManager.mainTarget());
if (!debuggerModel)
return;
for (var fileInfo of profile.files()) {
var url = /** @type {string} */ (fileInfo[0]);
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
for (var lineInfo of fileInfo[1]) {
var line = lineInfo[0] - 1;
var time = lineInfo[1];
var rawLocation = debuggerModel.createRawLocationByURL(url, line, 0);
if (rawLocation)
new WebInspector.TimelineUIUtils.LineLevelProfilePresentation(rawLocation, time, this._locationPool);
else if (uiSourceCode)
uiSourceCode.addLineDecoration(line, WebInspector.TimelineUIUtils.PerformanceLineDecorator.type, time);
}
}
},
_resetLineLevelCPUProfile: function()
{
this._locationPool.disposeAll();
WebInspector.workspace.uiSourceCodes().forEach(uiSourceCode => uiSourceCode.removeAllLineDecorations(WebInspector.TimelineUIUtils.PerformanceLineDecorator.type));
},
__proto__: WebInspector.Panel.prototype
}
/**
* @interface
*/
WebInspector.TimelineLifecycleDelegate = function()
{
}
WebInspector.TimelineLifecycleDelegate.prototype = {
recordingStarted: function() {},
/**
* @param {number} usage
*/
recordingProgress: function(usage) {},
loadingStarted: function() {},
/**
* @param {number=} progress
*/
loadingProgress: function(progress) {},
/**
* @param {boolean} success
*/
loadingComplete: function(success) {},
};
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TimelineModeView}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineTreeView} innerTreeView
*/
WebInspector.TimelineTreeModeView = function(delegate, innerTreeView)
{
WebInspector.VBox.call(this);
this._treeView = innerTreeView;
this._treeView.show(this.element);
}
WebInspector.TimelineTreeModeView.prototype = {
/**
* @override
*/
dispose: function()
{
},
/**
* @override
* @return {?Element}
*/
resizerElement: function()
{
return null;
},
/**
* @override
*/
highlightSearchResult: function()
{
},
/**
* @override
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event)
{
},
/**
* @override
*/
refreshRecords: function()
{
},
/**
* @override
*/
reset: function()
{
},
/**
* @override
*/
setSelection: function()
{
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
*/
setWindowTimes: function(startTime, endTime)
{
this._treeView.setRange(startTime, endTime);
},
/**
* @override
* @return {!WebInspector.Widget}
*/
view: function()
{
return this;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.TabbedPane}
* @param {!WebInspector.TimelineModel} timelineModel
* @param {!WebInspector.TimelineModeViewDelegate} delegate
*/
WebInspector.TimelineDetailsView = function(timelineModel, delegate)
{
WebInspector.TabbedPane.call(this);
this.element.classList.add("timeline-details");
var tabIds = WebInspector.TimelinePanel.DetailsTab;
this._defaultDetailsWidget = new WebInspector.VBox();
this._defaultDetailsWidget.element.classList.add("timeline-details-view");
this._defaultDetailsContentElement = this._defaultDetailsWidget.element.createChild("div", "timeline-details-view-body vbox");
this.appendTab(tabIds.Details, WebInspector.UIString("Summary"), this._defaultDetailsWidget);
this.setPreferredTab(tabIds.Details);
/** @type Map<string, WebInspector.TimelineTreeView> */
this._rangeDetailViews = new Map();
if (!Runtime.experiments.isEnabled("multipleTimelineViews")) {
var bottomUpView = new WebInspector.BottomUpTimelineTreeView(timelineModel);
this.appendTab(tabIds.BottomUp, WebInspector.UIString("Bottom-Up"), bottomUpView);
this._rangeDetailViews.set(tabIds.BottomUp, bottomUpView);
var callTreeView = new WebInspector.CallTreeTimelineTreeView(timelineModel);
this.appendTab(tabIds.CallTree, WebInspector.UIString("Call Tree"), callTreeView);
this._rangeDetailViews.set(tabIds.CallTree, callTreeView);
var eventsView = new WebInspector.EventsTimelineTreeView(timelineModel, delegate);
this.appendTab(tabIds.Events, WebInspector.UIString("Event Log"), eventsView);
this._rangeDetailViews.set(tabIds.Events, eventsView);
}
this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
}
WebInspector.TimelineDetailsView.prototype = {
/**
* @param {!Node} node
*/
setContent: function(node)
{
var allTabs = this.otherTabs(WebInspector.TimelinePanel.DetailsTab.Details);
for (var i = 0; i < allTabs.length; ++i) {
if (!this._rangeDetailViews.has(allTabs[i]))
this.closeTab(allTabs[i]);
}
this._defaultDetailsContentElement.removeChildren();
this._defaultDetailsContentElement.appendChild(node);
},
/**
* @param {!WebInspector.TimelineSelection} selection
*/
updateContents: function(selection)
{
this._selection = selection;
var view = this.selectedTabId ? this._rangeDetailViews.get(this.selectedTabId) : null;
if (view)
view.updateContents(selection);
},
/**
* @override
* @param {string} id
* @param {string} tabTitle
* @param {!WebInspector.Widget} view
* @param {string=} tabTooltip
* @param {boolean=} userGesture
* @param {boolean=} isCloseable
*/
appendTab: function(id, tabTitle, view, tabTooltip, userGesture, isCloseable)
{
WebInspector.TabbedPane.prototype.appendTab.call(this, id, tabTitle, view, tabTooltip, userGesture, isCloseable);
if (this._preferredTabId !== this.selectedTabId)
this.selectTab(id);
},
/**
* @param {string} tabId
*/
setPreferredTab: function(tabId)
{
this._preferredTabId = tabId;
},
/**
* @param {!WebInspector.Event} event
*/
_tabSelected: function(event)
{
if (!event.data.isUserGesture)
return;
this.setPreferredTab(event.data.tabId);
this.updateContents(this._selection);
},
__proto__: WebInspector.TabbedPane.prototype
}
/**
* @constructor
* @param {!WebInspector.TimelineSelection.Type} type
* @param {number} startTime
* @param {number} endTime
* @param {!Object=} object
*/
WebInspector.TimelineSelection = function(type, startTime, endTime, object)
{
this._type = type;
this._startTime = startTime;
this._endTime = endTime;
this._object = object || null;
}
/**
* @enum {string}
*/
WebInspector.TimelineSelection.Type = {
Frame: "Frame",
NetworkRequest: "NetworkRequest",
TraceEvent: "TraceEvent",
Range: "Range"
};
/**
* @param {!WebInspector.TimelineFrame} frame
* @return {!WebInspector.TimelineSelection}
*/
WebInspector.TimelineSelection.fromFrame = function(frame)
{
return new WebInspector.TimelineSelection(
WebInspector.TimelineSelection.Type.Frame,
frame.startTime, frame.endTime,
frame);
}
/**
* @param {!WebInspector.TimelineModel.NetworkRequest} request
* @return {!WebInspector.TimelineSelection}
*/
WebInspector.TimelineSelection.fromNetworkRequest = function(request)
{
return new WebInspector.TimelineSelection(
WebInspector.TimelineSelection.Type.NetworkRequest,
request.startTime, request.endTime || request.startTime,
request);
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {!WebInspector.TimelineSelection}
*/
WebInspector.TimelineSelection.fromTraceEvent = function(event)
{
return new WebInspector.TimelineSelection(
WebInspector.TimelineSelection.Type.TraceEvent,
event.startTime, event.endTime || (event.startTime + 1),
event);
}
/**
* @param {number} startTime
* @param {number} endTime
* @return {!WebInspector.TimelineSelection}
*/
WebInspector.TimelineSelection.fromRange = function(startTime, endTime)
{
return new WebInspector.TimelineSelection(
WebInspector.TimelineSelection.Type.Range,
startTime, endTime);
}
WebInspector.TimelineSelection.prototype = {
/**
* @return {!WebInspector.TimelineSelection.Type}
*/
type: function()
{
return this._type;
},
/**
* @return {?Object}
*/
object: function()
{
return this._object;
},
/**
* @return {number}
*/
startTime: function()
{
return this._startTime;
},
/**
* @return {number}
*/
endTime: function()
{
return this._endTime;
}
};
/**
* @interface
* @extends {WebInspector.EventTarget}
*/
WebInspector.TimelineModeView = function()
{
}
WebInspector.TimelineModeView.prototype = {
/**
* @return {!WebInspector.Widget}
*/
view: function() {},
dispose: function() {},
/**
* @return {?Element}
*/
resizerElement: function() {},
reset: function() {},
refreshRecords: function() {},
/**
* @param {?WebInspector.TimelineModel.Record} record
* @param {string=} regex
* @param {boolean=} selectRecord
*/
highlightSearchResult: function(record, regex, selectRecord) {},
/**
* @param {number} startTime
* @param {number} endTime
*/
setWindowTimes: function(startTime, endTime) {},
/**
* @param {?WebInspector.TimelineSelection} selection
*/
setSelection: function(selection) {},
/**
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event) { }
}
/**
* @interface
*/
WebInspector.TimelineModeViewDelegate = function() {}
WebInspector.TimelineModeViewDelegate.prototype = {
/**
* @param {number} startTime
* @param {number} endTime
*/
requestWindowTimes: function(startTime, endTime) {},
/**
* @param {?WebInspector.TimelineSelection} selection
* @param {!WebInspector.TimelinePanel.DetailsTab=} preferredTab
*/
select: function(selection, preferredTab) {},
/**
* @param {!Node} node
*/
showInDetails: function(node) {},
/**
* @param {?WebInspector.TracingModel.Event} event
*/
highlightEvent: function(event) {}
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.TimelineCategoryFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
}
WebInspector.TimelineCategoryFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !WebInspector.TimelineUIUtils.eventStyle(event).category.hidden;
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.TimelineIsLongFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
this._minimumRecordDuration = 0;
}
WebInspector.TimelineIsLongFilter.prototype = {
/**
* @param {number} value
*/
setMinimumRecordDuration: function(value)
{
this._minimumRecordDuration = value;
},
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
var duration = event.endTime ? event.endTime - event.startTime : 0;
return duration >= this._minimumRecordDuration;
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.TimelineTextFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
}
WebInspector.TimelineTextFilter.prototype = {
/**
* @param {?RegExp} regExp
*/
_setRegExp: function(regExp)
{
this._regExp = regExp;
},
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !this._regExp || WebInspector.TimelineUIUtils.testContentMatching(event, this._regExp);
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.TimelineStaticFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
}
WebInspector.TimelineStaticFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
switch (event.name) {
case WebInspector.TimelineModel.RecordType.EventDispatch:
return event.hasChildren;
case WebInspector.TimelineModel.RecordType.JSFrame:
return false;
default:
return true;
}
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {boolean} showTimer
* @param {function()} stopCallback
*/
WebInspector.TimelinePanel.StatusPane = function(showTimer, stopCallback)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("timeline/timelineStatusDialog.css");
this.contentElement.classList.add("timeline-status-dialog");
var statusLine = this.contentElement.createChild("div", "status-dialog-line status");
statusLine.createChild("div", "label").textContent = WebInspector.UIString("Status");
this._status = statusLine.createChild("div", "content");
if (showTimer) {
var timeLine = this.contentElement.createChild("div", "status-dialog-line time");
timeLine.createChild("div", "label").textContent = WebInspector.UIString("Time");
this._time = timeLine.createChild("div", "content");
}
var progressLine = this.contentElement.createChild("div", "status-dialog-line progress");
this._progressLabel = progressLine.createChild("div", "label");
this._progressBar = progressLine.createChild("div", "indicator-container").createChild("div", "indicator");
this._stopButton = createTextButton(WebInspector.UIString("Stop"), stopCallback);
this.contentElement.createChild("div", "stop-button").appendChild(this._stopButton);
}
WebInspector.TimelinePanel.StatusPane.prototype = {
finish: function()
{
this._stopTimer();
this._stopButton.disabled = true;
},
hide: function()
{
this.element.parentNode.classList.remove("tinted");
this.element.remove();
},
/**
* @param {!Element} parent
*/
showPane: function(parent)
{
this.show(parent);
parent.classList.add("tinted");
},
/**
* @param {string} text
*/
updateStatus: function(text)
{
this._status.textContent = text;
},
/**
* @param {string} activity
* @param {number} percent
*/
updateProgressBar: function(activity, percent)
{
this._progressLabel.textContent = activity;
this._progressBar.style.width = percent.toFixed(1) + "%";
this._updateTimer();
},
startTimer: function()
{
this._startTime = Date.now();
this._timeUpdateTimer = setInterval(this._updateTimer.bind(this, false), 1000);
this._updateTimer();
},
_stopTimer: function()
{
if (!this._timeUpdateTimer)
return;
clearInterval(this._timeUpdateTimer);
this._updateTimer(true);
delete this._timeUpdateTimer;
},
/**
* @param {boolean=} precise
*/
_updateTimer: function(precise)
{
if (!this._timeUpdateTimer)
return;
var elapsed = (Date.now() - this._startTime) / 1000;
this._time.textContent = WebInspector.UIString("%s\u2009sec", elapsed.toFixed(precise ? 1 : 0));
},
__proto__: WebInspector.VBox.prototype
}
WebInspector.TimelinePanel.show = function()
{
WebInspector.inspectorView.setCurrentPanel(WebInspector.TimelinePanel.instance());
}
/**
* @return {!WebInspector.TimelinePanel}
*/
WebInspector.TimelinePanel.instance = function()
{
if (!WebInspector.TimelinePanel._instanceObject)
WebInspector.TimelinePanel._instanceObject = new WebInspector.TimelinePanel();
return WebInspector.TimelinePanel._instanceObject;
}
/**
* @constructor
* @implements {WebInspector.PanelFactory}
*/
WebInspector.TimelinePanelFactory = function()
{
}
WebInspector.TimelinePanelFactory.prototype = {
/**
* @override
* @return {!WebInspector.Panel}
*/
createPanel: function()
{
return WebInspector.TimelinePanel.instance();
}
}
/**
* @constructor
* @implements {WebInspector.QueryParamHandler}
*/
WebInspector.LoadTimelineHandler = function()
{
}
WebInspector.LoadTimelineHandler.prototype = {
/**
* @override
* @param {string} value
*/
handleQueryParam: function(value)
{
WebInspector.TimelinePanel.show();
WebInspector.TimelinePanel.instance()._loadFromURL(value);
}
}
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.TimelinePanel.ActionDelegate = function()
{
}
WebInspector.TimelinePanel.ActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
var panel = WebInspector.context.flavor(WebInspector.TimelinePanel);
console.assert(panel && panel instanceof WebInspector.TimelinePanel);
switch (actionId) {
case "timeline.toggle-recording":
panel._toggleRecording();
return true;
case "timeline.save-to-file":
panel._saveToFile();
return true;
case "timeline.load-from-file":
panel._selectFileToLoad();
return true;
case "timeline.jump-to-previous-frame":
panel._jumpToFrame(-1);
return true;
case "timeline.jump-to-next-frame":
panel._jumpToFrame(1);
return true;
}
return false;
}
}
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.TimelineFilters = function()
{
WebInspector.Object.call(this);
this._categoryFilter = new WebInspector.TimelineCategoryFilter();
this._durationFilter = new WebInspector.TimelineIsLongFilter();
this._textFilter = new WebInspector.TimelineTextFilter();
this._filters = [this._categoryFilter, this._durationFilter, this._textFilter];
this._createFilterBar();
}
WebInspector.TimelineFilters.Events = {
FilterChanged: Symbol("FilterChanged")
};
WebInspector.TimelineFilters._durationFilterPresetsMs = [0, 1, 15];
WebInspector.TimelineFilters.prototype = {
/**
* @return {!Array<!WebInspector.TimelineModel.Filter>}
*/
filters: function()
{
return this._filters;
},
/**
* @return {?RegExp}
*/
searchRegExp: function()
{
return this._textFilter._regExp;
},
/**
* @return {!WebInspector.ToolbarItem}
*/
filterButton: function()
{
return this._filterBar.filterButton();
},
/**
* @return {!WebInspector.Widget}
*/
filtersWidget: function()
{
return this._filterBar;
},
_createFilterBar: function()
{
this._filterBar = new WebInspector.FilterBar("timelinePanel");
this._textFilterUI = new WebInspector.TextFilterUI();
this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, textFilterChanged, this);
this._filterBar.addFilter(this._textFilterUI);
var durationOptions = [];
for (var durationMs of WebInspector.TimelineFilters._durationFilterPresetsMs) {
var durationOption = {};
if (!durationMs) {
durationOption.label = WebInspector.UIString("All");
durationOption.title = WebInspector.UIString("Show all records");
} else {
durationOption.label = WebInspector.UIString("\u2265 %dms", durationMs);
durationOption.title = WebInspector.UIString("Hide records shorter than %dms", durationMs);
}
durationOption.value = durationMs;
durationOptions.push(durationOption);
}
var durationFilterUI = new WebInspector.ComboBoxFilterUI(durationOptions);
durationFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, durationFilterChanged, this);
this._filterBar.addFilter(durationFilterUI);
var categoryFiltersUI = {};
var categories = WebInspector.TimelineUIUtils.categories();
for (var categoryName in categories) {
var category = categories[categoryName];
if (!category.visible)
continue;
var filter = new WebInspector.CheckboxFilterUI(category.name, category.title);
filter.setColor(category.color, "rgba(0, 0, 0, 0.2)");
categoryFiltersUI[category.name] = filter;
filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged, categoriesFilterChanged.bind(this, categoryName));
this._filterBar.addFilter(filter);
}
return this._filterBar;
/**
* @this {WebInspector.TimelineFilters}
*/
function textFilterChanged()
{
var searchQuery = this._textFilterUI.value();
this._textFilter._setRegExp(searchQuery ? createPlainTextSearchRegex(searchQuery, "i") : null);
this._notifyFiltersChanged();
}
/**
* @this {WebInspector.TimelineFilters}
*/
function durationFilterChanged()
{
var duration = durationFilterUI.value();
var minimumRecordDuration = parseInt(duration, 10);
this._durationFilter.setMinimumRecordDuration(minimumRecordDuration);
this._notifyFiltersChanged();
}
/**
* @param {string} name
* @this {WebInspector.TimelineFilters}
*/
function categoriesFilterChanged(name)
{
var categories = WebInspector.TimelineUIUtils.categories();
categories[name].hidden = !categoryFiltersUI[name].checked();
this._notifyFiltersChanged();
}
},
_notifyFiltersChanged: function()
{
this.dispatchEventToListeners(WebInspector.TimelineFilters.Events.FilterChanged);
},
__proto__: WebInspector.Object.prototype
};
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.CPUThrottlingManager = function()
{
this._targets = [];
this._throttlingRate = 1.; // No throttling
WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
}
WebInspector.CPUThrottlingManager.prototype = {
/**
* @param {number} value
*/
setRate: function(value)
{
this._throttlingRate = value;
this._targets.forEach(target => target.emulationAgent().setCPUThrottlingRate(value));
},
/**
* @return {number}
*/
rate: function()
{
return this._throttlingRate;
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetAdded: function(target)
{
this._targets.push(target);
target.emulationAgent().setCPUThrottlingRate(this._throttlingRate);
},
/**
* @override
* @param {!WebInspector.Target} target
*/
targetRemoved: function(target)
{
this._targets.remove(target, true);
},
__proto__: WebInspector.Object.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | 2 1 1 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.TimelineProfileTree = { };
/**
* @constructor
*/
WebInspector.TimelineProfileTree.Node = function()
{
/** @type {number} */
this.totalTime;
/** @type {number} */
this.selfTime;
/** @type {string} */
this.id;
/** @type {!WebInspector.TracingModel.Event} */
this.event;
/** @type {?Map<string|symbol,!WebInspector.TimelineProfileTree.Node>} */
this.children;
/** @type {?WebInspector.TimelineProfileTree.Node} */
this.parent;
this._isGroupNode = false;
}
WebInspector.TimelineProfileTree.Node.prototype = {
/**
* @return {boolean}
*/
isGroupNode: function()
{
return this._isGroupNode;
}
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {number} startTime
* @param {number} endTime
* @param {function(!WebInspector.TracingModel.Event):(string|symbol)=} eventIdCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startTime, endTime, eventIdCallback)
{
// Temporarily deposit a big enough value that exceeds the max recording time.
var /** @const */ initialTime = 1e7;
var root = new WebInspector.TimelineProfileTree.Node();
root.totalTime = initialTime;
root.selfTime = initialTime;
root.children = /** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */ (new Map());
var parent = root;
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onStartEvent(e)
{
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime) : 0;
var id = eventIdCallback ? eventIdCallback(e) : Symbol("uniqueEventId");
if (!parent.children)
parent.children = /** @type {!Map<string,!WebInspector.TimelineProfileTree.Node>} */ (new Map());
var node = parent.children.get(id);
if (node) {
node.selfTime += time;
node.totalTime += time;
} else {
node = new WebInspector.TimelineProfileTree.Node();
node.totalTime = time;
node.selfTime = time;
node.parent = parent;
node.id = id;
node.event = e;
parent.children.set(id, node);
}
parent.selfTime -= time;
if (parent.selfTime < 0) {
console.log("Error: Negative self of " + parent.selfTime, e);
parent.selfTime = 0;
}
if (e.endTime)
parent = node;
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEndEvent(e)
{
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
parent = parent.parent;
}
var instantEventCallback = eventIdCallback ? undefined : onStartEvent; // Ignore instant events when aggregating.
WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, instantEventCallback, startTime, endTime);
root.totalTime -= root.selfTime;
root.selfTime = 0;
return root;
}
/**
* @param {!WebInspector.TimelineProfileTree.Node} topDownTree
* @param {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node=} groupingCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
WebInspector.TimelineProfileTree.buildBottomUp = function(topDownTree, groupingCallback)
{
var buRoot = new WebInspector.TimelineProfileTree.Node();
buRoot.selfTime = 0;
buRoot.totalTime = 0;
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
buRoot.children = new Map();
var nodesOnStack = /** @type {!Set<string>} */ (new Set());
if (topDownTree.children)
topDownTree.children.forEach(processNode);
buRoot.totalTime = topDownTree.totalTime;
/**
* @param {!WebInspector.TimelineProfileTree.Node} tdNode
*/
function processNode(tdNode)
{
var buParent = groupingCallback && groupingCallback(tdNode) || buRoot;
if (buParent !== buRoot) {
buRoot.children.set(buParent.id, buParent);
buParent.parent = buRoot;
}
appendNode(tdNode, buParent);
var hadNode = nodesOnStack.has(tdNode.id);
if (!hadNode)
nodesOnStack.add(tdNode.id);
if (tdNode.children)
tdNode.children.forEach(processNode);
if (!hadNode)
nodesOnStack.delete(tdNode.id);
}
/**
* @param {!WebInspector.TimelineProfileTree.Node} tdNode
* @param {!WebInspector.TimelineProfileTree.Node} buParent
*/
function appendNode(tdNode, buParent)
{
var selfTime = tdNode.selfTime;
var totalTime = tdNode.totalTime;
buParent.selfTime += selfTime;
buParent.totalTime += selfTime;
while (tdNode.parent) {
if (!buParent.children)
buParent.children = /** @type {!Map<string,!WebInspector.TimelineProfileTree.Node>} */ (new Map());
var id = tdNode.id;
var buNode = buParent.children.get(id);
if (!buNode) {
buNode = new WebInspector.TimelineProfileTree.Node();
buNode.selfTime = selfTime;
buNode.totalTime = totalTime;
buNode.event = tdNode.event;
buNode.id = id;
buNode.parent = buParent;
buParent.children.set(id, buNode);
} else {
buNode.selfTime += selfTime;
if (!nodesOnStack.has(id))
buNode.totalTime += totalTime;
}
tdNode = tdNode.parent;
buParent = buNode;
}
}
// Purge zero self time nodes.
var rootChildren = buRoot.children;
for (var item of rootChildren.entries()) {
if (item[1].selfTime === 0)
rootChildren.delete(/** @type {string} */(item[0]));
}
return buRoot;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {?string}
*/
WebInspector.TimelineProfileTree.eventURL = function(event)
{
var data = event.args["data"] || event.args["beginData"];
if (data && data["url"])
return data["url"];
var frame = WebInspector.TimelineProfileTree.eventStackFrame(event);
while (frame) {
var url = frame["url"];
if (url)
return url;
frame = frame.parent;
}
return null;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {?Object}
*/
WebInspector.TimelineProfileTree.eventStackFrame = function(event)
{
if (event.name == WebInspector.TimelineModel.RecordType.JSFrame)
return event.args["data"];
var topFrame = event.stackTrace && event.stackTrace[0];
if (topFrame)
return topFrame;
var initiator = event.initiator;
return initiator && initiator.stackTrace && initiator.stackTrace[0] || null;
}
/**
* @constructor
* @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
*/
WebInspector.TimelineAggregator = function(categoryMapper)
{
this._categoryMapper = categoryMapper;
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
this._groupNodes = new Map();
}
/**
* @enum {string}
*/
WebInspector.TimelineAggregator.GroupBy = {
None: "None",
Category: "Category",
Domain: "Domain",
Subdomain: "Subdomain",
URL: "URL"
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {string}
*/
WebInspector.TimelineAggregator.eventId = function(event)
{
if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
var data = event.args["data"];
return "f:" + data["functionName"] + "@" + (data["scriptId"] || data["url"] || "");
}
return event.name + ":@" + WebInspector.TimelineProfileTree.eventURL(event);
}
WebInspector.TimelineAggregator._extensionInternalPrefix = "extensions::";
WebInspector.TimelineAggregator._groupNodeFlag = Symbol("groupNode");
/**
* @param {string} url
* @return {boolean}
*/
WebInspector.TimelineAggregator.isExtensionInternalURL = function(url)
{
return url.startsWith(WebInspector.TimelineAggregator._extensionInternalPrefix);
}
WebInspector.TimelineAggregator.prototype = {
/**
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node}
*/
groupFunction: function(groupBy)
{
var idMapper = this._nodeToGroupIdFunction(groupBy);
return idMapper && this._nodeToGroupNode.bind(this, idMapper);
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} root
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {!WebInspector.TimelineProfileTree.Node}
*/
performGrouping: function(root, groupBy)
{
var nodeMapper = this.groupFunction(groupBy);
if (!nodeMapper)
return root;
for (var node of root.children.values()) {
var groupNode = nodeMapper(node);
groupNode.parent = root;
groupNode.selfTime += node.selfTime;
groupNode.totalTime += node.totalTime;
groupNode.children.set(node.id, node);
node.parent = root;
}
root.children = this._groupNodes;
return root;
},
/**
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {?function(!WebInspector.TimelineProfileTree.Node):string}
*/
_nodeToGroupIdFunction: function(groupBy)
{
/**
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {string}
*/
function groupByURL(node)
{
return WebInspector.TimelineProfileTree.eventURL(node.event) || "";
}
/**
* @param {boolean} groupSubdomains
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {string}
*/
function groupByDomain(groupSubdomains, node)
{
var url = WebInspector.TimelineProfileTree.eventURL(node.event) || "";
if (WebInspector.TimelineAggregator.isExtensionInternalURL(url))
return WebInspector.TimelineAggregator._extensionInternalPrefix;
var parsedURL = url.asParsedURL();
if (!parsedURL)
return "";
if (parsedURL.scheme === "chrome-extension")
return parsedURL.scheme + "://" + parsedURL.host;
if (!groupSubdomains)
return parsedURL.host;
if (/^[.0-9]+$/.test(parsedURL.host))
return parsedURL.host;
var domainMatch = /([^.]*\.)?[^.]*$/.exec(parsedURL.host);
return domainMatch && domainMatch[0] || "";
}
switch (groupBy) {
case WebInspector.TimelineAggregator.GroupBy.None: return null;
case WebInspector.TimelineAggregator.GroupBy.Category: return node => node.event ? this._categoryMapper(node.event) : "";
case WebInspector.TimelineAggregator.GroupBy.Subdomain: return groupByDomain.bind(null, false);
case WebInspector.TimelineAggregator.GroupBy.Domain: return groupByDomain.bind(null, true);
case WebInspector.TimelineAggregator.GroupBy.URL: return groupByURL;
default: return null;
}
},
/**
* @param {string} id
* @param {!WebInspector.TracingModel.Event} event
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildGroupNode: function(id, event)
{
var groupNode = new WebInspector.TimelineProfileTree.Node();
groupNode.id = id;
groupNode.selfTime = 0;
groupNode.totalTime = 0;
groupNode.children = new Map();
groupNode.event = event;
groupNode._isGroupNode = true;
this._groupNodes.set(id, groupNode);
return groupNode;
},
/**
* @param {function(!WebInspector.TimelineProfileTree.Node):string} nodeToGroupId
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_nodeToGroupNode: function(nodeToGroupId, node)
{
var id = nodeToGroupId(node);
return this._groupNodes.get(id) || this._buildGroupNode(id, node.event);
},
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | 2 1 1 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineTreeView = function(model)
{
WebInspector.VBox.call(this);
this.element.classList.add("timeline-tree-view");
this._model = model;
this._linkifier = new WebInspector.Linkifier();
this._filters = [];
if (!Runtime.experiments.isEnabled("timelineShowAllEvents")) {
this._filters.push(WebInspector.TimelineUIUtils.visibleEventsFilter());
this._filters.push(new WebInspector.ExcludeTopLevelFilter());
}
var columns = [];
this._populateColumns(columns);
var mainView = new WebInspector.VBox();
this._populateToolbar(mainView.element);
this._dataGrid = new WebInspector.SortableDataGrid(columns);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortingChanged, this);
this._dataGrid.element.addEventListener("mousemove", this._onMouseMove.bind(this), true)
this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
this._dataGrid.asWidget().show(mainView.element);
this._splitWidget = new WebInspector.SplitWidget(true, true, "timelineTreeViewDetailsSplitWidget");
this._splitWidget.show(this.element);
this._splitWidget.setMainWidget(mainView);
this._detailsView = new WebInspector.VBox();
this._detailsView.element.classList.add("timeline-details-view", "timeline-details-view-body");
this._splitWidget.setSidebarWidget(this._detailsView);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._updateDetailsForSelection, this);
/** @type {?WebInspector.TimelineProfileTree.Node|undefined} */
this._lastSelectedNode;
}
WebInspector.TimelineTreeView.prototype = {
/**
* @param {!WebInspector.TimelineSelection} selection
*/
updateContents: function(selection)
{
this.setRange(selection.startTime(), selection.endTime());
},
/**
* @param {number} startTime
* @param {number} endTime
*/
setRange: function(startTime, endTime)
{
this._startTime = startTime;
this._endTime = endTime;
this._refreshTree();
},
/**
* @return {boolean}
*/
_exposePercentages: function()
{
return false;
},
/**
* @param {!Element} parent
*/
_populateToolbar: function(parent) { },
/**
* @param {?WebInspector.TimelineProfileTree.Node} node
*/
_onHover: function(node) { },
/**
* @param {!RuntimeAgent.CallFrame} frame
* @return {!Element}
*/
linkifyLocation: function(frame)
{
return this._linkifier.linkifyConsoleCallFrame(this._model.target(), frame);
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} treeNode
* @param {boolean} suppressSelectedEvent
*/
selectProfileNode: function(treeNode, suppressSelectedEvent)
{
var pathToRoot = [];
for (var node = treeNode; node; node = node.parent)
pathToRoot.push(node);
for (var i = pathToRoot.length - 1; i > 0; --i) {
var gridNode = this._dataGridNodeForTreeNode(pathToRoot[i]);
if (gridNode && gridNode.dataGrid)
gridNode.expand();
}
var gridNode = this._dataGridNodeForTreeNode(treeNode);
if (gridNode.dataGrid) {
gridNode.reveal();
gridNode.select(suppressSelectedEvent);
}
},
_refreshTree: function()
{
this._linkifier.reset();
this._dataGrid.rootNode().removeChildren();
var tree = this._buildTree();
if (!tree.children)
return;
var maxSelfTime = 0;
var maxTotalTime = 0;
for (var child of tree.children.values()) {
maxSelfTime = Math.max(maxSelfTime, child.selfTime);
maxTotalTime = Math.max(maxTotalTime, child.totalTime);
}
for (var child of tree.children.values()) {
// Exclude the idle time off the total calculation.
var gridNode = new WebInspector.TimelineTreeView.TreeGridNode(child, tree.totalTime, maxSelfTime, maxTotalTime, this);
this._dataGrid.insertChild(gridNode);
}
this._sortingChanged();
this._updateDetailsForSelection();
},
/**
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildTree: function()
{
throw new Error("Not Implemented");
},
/**
* @param {function(!WebInspector.TracingModel.Event):(string|symbol)=} eventIdCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildTopDownTree: function(eventIdCallback)
{
return WebInspector.TimelineProfileTree.buildTopDown(this._model.mainThreadEvents(), this._filters, this._startTime, this._endTime, eventIdCallback)
},
/**
* @param {!Array<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
_populateColumns: function(columns)
{
columns.push({id: "self", title: WebInspector.UIString("Self Time"), width: "110px", fixedWidth: true, sortable: true});
columns.push({id: "total", title: WebInspector.UIString("Total Time"), width: "110px", fixedWidth: true, sortable: true});
columns.push({id: "activity", title: WebInspector.UIString("Activity"), disclosure: true, sortable: true});
},
_sortingChanged: function()
{
var columnIdentifier = this._dataGrid.sortColumnIdentifier();
if (!columnIdentifier)
return;
var sortFunction;
switch (columnIdentifier) {
case "startTime":
sortFunction = compareStartTime;
break;
case "self":
sortFunction = compareNumericField.bind(null, "selfTime");
break;
case "total":
sortFunction = compareNumericField.bind(null, "totalTime");
break;
case "activity":
sortFunction = compareName;
break;
default:
console.assert(false, "Unknown sort field: " + columnIdentifier);
return;
}
this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());
/**
* @param {string} field
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
function compareNumericField(field, a, b)
{
var nodeA = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (a);
var nodeB = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (b);
return nodeA._profileNode[field] - nodeB._profileNode[field];
}
/**
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
function compareStartTime(a, b)
{
var nodeA = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (a);
var nodeB = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (b);
return nodeA._profileNode.event.startTime - nodeB._profileNode.event.startTime;
}
/**
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
function compareName(a, b)
{
var nodeA = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (a);
var nodeB = /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (b);
var nameA = WebInspector.TimelineTreeView.eventNameForSorting(nodeA._profileNode.event);
var nameB = WebInspector.TimelineTreeView.eventNameForSorting(nodeB._profileNode.event);
return nameA.localeCompare(nameB);
}
},
_updateDetailsForSelection: function()
{
var selectedNode = this._dataGrid.selectedNode ? /** @type {!WebInspector.TimelineTreeView.TreeGridNode} */ (this._dataGrid.selectedNode)._profileNode : null;
if (selectedNode === this._lastSelectedNode)
return;
this._lastSelectedNode = selectedNode;
this._detailsView.detachChildWidgets();
this._detailsView.element.removeChildren();
if (!selectedNode || !this._showDetailsForNode(selectedNode)) {
var banner = this._detailsView.element.createChild("div", "banner");
banner.createTextChild(WebInspector.UIString("Select item for details."));
}
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {boolean}
*/
_showDetailsForNode: function(node)
{
return false;
},
/**
* @param {!Event} event
*/
_onMouseMove: function(event)
{
var gridNode = event.target && (event.target instanceof Node)
? /** @type {?WebInspector.TimelineTreeView.TreeGridNode} */ (this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target)))
: null;
var profileNode = gridNode && gridNode._profileNode;
if (profileNode === this._lastHoveredProfileNode)
return;
this._lastHoveredProfileNode = profileNode;
this._onHover(profileNode);
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} treeNode
* @return {?WebInspector.TimelineTreeView.GridNode}
*/
_dataGridNodeForTreeNode: function(treeNode)
{
return treeNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol] || null;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {string}
*/
WebInspector.TimelineTreeView.eventNameForSorting = function(event)
{
if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
var data = event.args["data"];
return data["functionName"] + "@" + (data["scriptId"] || data["url"] || "");
}
return event.name + ":@" + WebInspector.TimelineProfileTree.eventURL(event);
}
/**
* @constructor
* @extends {WebInspector.SortableDataGridNode}
* @param {!WebInspector.TimelineProfileTree.Node} profileNode
* @param {number} grandTotalTime
* @param {number} maxSelfTime
* @param {number} maxTotalTime
* @param {!WebInspector.TimelineTreeView} treeView
*/
WebInspector.TimelineTreeView.GridNode = function(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView)
{
this._populated = false;
this._profileNode = profileNode;
this._treeView = treeView;
this._grandTotalTime = grandTotalTime;
this._maxSelfTime = maxSelfTime;
this._maxTotalTime = maxTotalTime;
WebInspector.SortableDataGridNode.call(this, null, false);
}
WebInspector.TimelineTreeView.GridNode.prototype = {
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
if (columnIdentifier === "activity")
return this._createNameCell(columnIdentifier);
return this._createValueCell(columnIdentifier) || WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
},
/**
* @param {string} columnIdentifier
* @return {!Element}
*/
_createNameCell: function(columnIdentifier)
{
var cell = this.createTD(columnIdentifier);
var container = cell.createChild("div", "name-container");
var icon = container.createChild("div", "activity-icon");
var name = container.createChild("div", "activity-name");
var event = this._profileNode.event;
if (this._profileNode.isGroupNode()) {
var treeView = /** @type {!WebInspector.AggregatedTimelineTreeView} */ (this._treeView);
var info = treeView._displayInfoForGroupNode(this._profileNode);
name.textContent = info.name;
icon.style.backgroundColor = info.color;
} else if (event) {
var data = event.args["data"];
var deoptReason = data && data["deoptReason"];
if (deoptReason && deoptReason !== "no reason")
container.createChild("div", "activity-warning").title = WebInspector.UIString("Not optimized: %s", deoptReason);
name.textContent = event.name === WebInspector.TimelineModel.RecordType.JSFrame
? WebInspector.beautifyFunctionName(event.args["data"]["functionName"])
: WebInspector.TimelineUIUtils.eventTitle(event);
var frame = WebInspector.TimelineProfileTree.eventStackFrame(event);
if (frame && frame["url"]) {
var callFrame = /** @type {!RuntimeAgent.CallFrame} */ (frame);
container.createChild("div", "activity-link").appendChild(this._treeView.linkifyLocation(callFrame));
}
icon.style.backgroundColor = WebInspector.TimelineUIUtils.eventColor(event);
}
return cell;
},
/**
* @param {string} columnIdentifier
* @return {?Element}
*/
_createValueCell: function(columnIdentifier)
{
if (columnIdentifier !== "self" && columnIdentifier !== "total" && columnIdentifier !== "startTime")
return null;
var showPercents = false;
var value;
var maxTime;
switch (columnIdentifier) {
case "startTime":
value = this._profileNode.event.startTime - this._treeView._model.minimumRecordTime();
break;
case "self":
value = this._profileNode.selfTime;
maxTime = this._maxSelfTime;
showPercents = true;
break;
case "total":
value = this._profileNode.totalTime;
maxTime = this._maxTotalTime;
showPercents = true;
break;
default:
return null;
}
var cell = this.createTD(columnIdentifier);
cell.className = "numeric-column";
var textDiv = cell.createChild("div");
textDiv.createChild("span").textContent = WebInspector.UIString("%.1f\u2009ms", value);
if (showPercents && this._treeView._exposePercentages())
textDiv.createChild("span", "percent-column").textContent = WebInspector.UIString("%.1f\u2009%%", value / this._grandTotalTime * 100);
if (maxTime) {
textDiv.classList.add("background-percent-bar");
cell.createChild("div", "background-bar-container").createChild("div", "background-bar").style.width = (value * 100 / maxTime).toFixed(1) + "%";
}
return cell;
},
__proto__: WebInspector.SortableDataGridNode.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineTreeView.GridNode}
* @param {!WebInspector.TimelineProfileTree.Node} profileNode
* @param {number} grandTotalTime
* @param {number} maxSelfTime
* @param {number} maxTotalTime
* @param {!WebInspector.TimelineTreeView} treeView
*/
WebInspector.TimelineTreeView.TreeGridNode = function(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView)
{
WebInspector.TimelineTreeView.GridNode.call(this, profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView);
this.hasChildren = this._profileNode.children ? this._profileNode.children.size > 0 : false;
profileNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol] = this;
}
WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol = Symbol("treeGridNode");
WebInspector.TimelineTreeView.TreeGridNode.prototype = {
/**
* @override
*/
populate: function()
{
if (this._populated)
return;
this._populated = true;
if (!this._profileNode.children)
return;
for (var node of this._profileNode.children.values()) {
var gridNode = new WebInspector.TimelineTreeView.TreeGridNode(node, this._grandTotalTime, this._maxSelfTime, this._maxTotalTime, this._treeView);
this.insertChildOrdered(gridNode);
}
},
__proto__: WebInspector.TimelineTreeView.GridNode.prototype
};
/**
* @constructor
* @extends {WebInspector.TimelineTreeView}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.AggregatedTimelineTreeView = function(model)
{
this._groupBySetting = WebInspector.settings.createSetting("timelineTreeGroupBy", WebInspector.TimelineAggregator.GroupBy.Category);
WebInspector.TimelineTreeView.call(this, model);
var nonessentialEvents = [
WebInspector.TimelineModel.RecordType.EventDispatch,
WebInspector.TimelineModel.RecordType.FunctionCall,
WebInspector.TimelineModel.RecordType.TimerFire
];
this._filters.push(new WebInspector.ExclusiveNameFilter(nonessentialEvents));
this._stackView = new WebInspector.TimelineStackView(this);
this._stackView.addEventListener(WebInspector.TimelineStackView.Events.SelectionChanged, this._onStackViewSelectionChanged, this);
}
WebInspector.AggregatedTimelineTreeView.prototype = {
/**
* @override
* @param {!WebInspector.TimelineSelection} selection
*/
updateContents: function(selection)
{
this._updateExtensionResolver();
WebInspector.TimelineTreeView.prototype.updateContents.call(this, selection);
var rootNode = this._dataGrid.rootNode();
if (rootNode.children.length)
rootNode.children[0].revealAndSelect();
},
_updateExtensionResolver: function()
{
this._executionContextNamesByOrigin = new Map();
for (var target of WebInspector.targetManager.targets()) {
for (var context of target.runtimeModel.executionContexts())
this._executionContextNamesByOrigin.set(context.origin, context.name);
}
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {!{name: string, color: string}}
*/
_displayInfoForGroupNode: function(node)
{
var categories = WebInspector.TimelineUIUtils.categories();
switch (this._groupBySetting.get()) {
case WebInspector.TimelineAggregator.GroupBy.Category:
var category = categories[node.id] || categories["other"];
return {name: category.title, color: category.color};
case WebInspector.TimelineAggregator.GroupBy.Domain:
case WebInspector.TimelineAggregator.GroupBy.Subdomain:
var name = node.id;
if (WebInspector.TimelineAggregator.isExtensionInternalURL(name))
name = WebInspector.UIString("[Chrome extensions overhead]");
else if (name.startsWith("chrome-extension"))
name = this._executionContextNamesByOrigin.get(name) || name;
return {
name: name || WebInspector.UIString("unattributed"),
color: node.id ? WebInspector.TimelineUIUtils.eventColor(node.event) : categories["other"].color
}
case WebInspector.TimelineAggregator.GroupBy.URL:
break;
default:
console.assert(false, "Unexpected aggregation type");
}
return {
name: node.id || WebInspector.UIString("unattributed"),
color: node.id ? WebInspector.TimelineUIUtils.eventColor(node.event) : categories["other"].color
}
},
/**
* @override
* @param {!Element} parent
*/
_populateToolbar: function(parent)
{
var panelToolbar = new WebInspector.Toolbar("", parent);
this._groupByCombobox = new WebInspector.ToolbarComboBox(this._onGroupByChanged.bind(this));
/**
* @param {string} name
* @param {string} id
* @this {WebInspector.TimelineTreeView}
*/
function addGroupingOption(name, id)
{
var option = this._groupByCombobox.createOption(name, "", id);
this._groupByCombobox.addOption(option);
if (id === this._groupBySetting.get())
this._groupByCombobox.select(option);
}
addGroupingOption.call(this, WebInspector.UIString("No Grouping"), WebInspector.TimelineAggregator.GroupBy.None);
addGroupingOption.call(this, WebInspector.UIString("Group by Category"), WebInspector.TimelineAggregator.GroupBy.Category);
addGroupingOption.call(this, WebInspector.UIString("Group by Domain"), WebInspector.TimelineAggregator.GroupBy.Domain);
addGroupingOption.call(this, WebInspector.UIString("Group by Subdomain"), WebInspector.TimelineAggregator.GroupBy.Subdomain);
addGroupingOption.call(this, WebInspector.UIString("Group by URL"), WebInspector.TimelineAggregator.GroupBy.URL);
panelToolbar.appendToolbarItem(this._groupByCombobox);
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} treeNode
* @return {!Array<!WebInspector.TimelineProfileTree.Node>}
*/
_buildHeaviestStack: function(treeNode)
{
console.assert(!!treeNode.parent, "Attempt to build stack for tree root");
var result = [];
// Do not add root to the stack, as it's the tree itself.
for (var node = treeNode; node && node.parent; node = node.parent)
result.push(node);
result = result.reverse();
for (node = treeNode; node && node.children && node.children.size;) {
var children = Array.from(node.children.values());
node = children.reduce((a, b) => a.totalTime > b.totalTime ? a : b);
result.push(node);
}
return result;
},
/**
* @override
* @return {boolean}
*/
_exposePercentages: function()
{
return true;
},
_onGroupByChanged: function()
{
this._groupBySetting.set(this._groupByCombobox.selectedOption().value);
this._refreshTree();
},
_onStackViewSelectionChanged: function()
{
var treeNode = this._stackView.selectedTreeNode();
if (treeNode)
this.selectProfileNode(treeNode, true);
},
/**
* @override
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {boolean}
*/
_showDetailsForNode: function(node)
{
var stack = this._buildHeaviestStack(node);
this._stackView.setStack(stack, node);
this._stackView.show(this._detailsView.element);
return true;
},
__proto__: WebInspector.TimelineTreeView.prototype,
};
/**
* @constructor
* @extends {WebInspector.AggregatedTimelineTreeView}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.CallTreeTimelineTreeView = function(model)
{
WebInspector.AggregatedTimelineTreeView.call(this, model);
this._dataGrid.markColumnAsSortedBy("total", WebInspector.DataGrid.Order.Descending);
}
WebInspector.CallTreeTimelineTreeView.prototype = {
/**
* @override
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildTree: function()
{
var topDown = this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);
var aggregator = new WebInspector.TimelineAggregator(event => WebInspector.TimelineUIUtils.eventStyle(event).category.name);
return aggregator.performGrouping(topDown, this._groupBySetting.get());
},
__proto__: WebInspector.AggregatedTimelineTreeView.prototype,
};
/**
* @constructor
* @extends {WebInspector.AggregatedTimelineTreeView}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.BottomUpTimelineTreeView = function(model)
{
WebInspector.AggregatedTimelineTreeView.call(this, model);
this._dataGrid.markColumnAsSortedBy("self", WebInspector.DataGrid.Order.Descending);
}
WebInspector.BottomUpTimelineTreeView.prototype = {
/**
* @override
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildTree: function()
{
var topDown = this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);
var aggregator = new WebInspector.TimelineAggregator(event => WebInspector.TimelineUIUtils.eventStyle(event).category.name);
return WebInspector.TimelineProfileTree.buildBottomUp(topDown, aggregator.groupFunction(this._groupBySetting.get()));
},
__proto__: WebInspector.AggregatedTimelineTreeView.prototype
};
/**
* @constructor
* @extends {WebInspector.TimelineTreeView}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineModeViewDelegate} delegate
*/
WebInspector.EventsTimelineTreeView = function(model, delegate)
{
this._filtersControl = new WebInspector.TimelineFilters();
this._filtersControl.addEventListener(WebInspector.TimelineFilters.Events.FilterChanged, this._onFilterChanged, this);
WebInspector.TimelineTreeView.call(this, model);
this._delegate = delegate;
this._filters.push.apply(this._filters, this._filtersControl.filters());
this._dataGrid.markColumnAsSortedBy("startTime", WebInspector.DataGrid.Order.Ascending);
}
WebInspector.EventsTimelineTreeView.prototype = {
/**
* @override
* @param {!WebInspector.TimelineSelection} selection
*/
updateContents: function(selection)
{
WebInspector.TimelineTreeView.prototype.updateContents.call(this, selection);
if (selection.type() === WebInspector.TimelineSelection.Type.TraceEvent) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (selection.object());
this._selectEvent(event, true);
}
},
/**
* @override
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildTree: function()
{
this._currentTree = this._buildTopDownTree();
return this._currentTree;
},
_onFilterChanged: function()
{
var selectedEvent = this._lastSelectedNode && this._lastSelectedNode.event;
this._refreshTree();
if (selectedEvent)
this._selectEvent(selectedEvent, false);
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {?WebInspector.TimelineProfileTree.Node}
*/
_findNodeWithEvent: function(event)
{
var iterators = [this._currentTree.children.values()];
while (iterators.length) {
var iterator = iterators.peekLast().next();
if (iterator.done) {
iterators.pop();
continue;
}
var child = /** @type {!WebInspector.TimelineProfileTree.Node} */ (iterator.value);
if (child.event === event)
return child;
if (child.children)
iterators.push(child.children.values());
}
return null;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {boolean=} expand
*/
_selectEvent: function(event, expand)
{
var node = this._findNodeWithEvent(event);
if (!node)
return;
this.selectProfileNode(node, false);
if (expand)
this._dataGridNodeForTreeNode(node).expand();
},
/**
* @override
* @param {!Array<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
_populateColumns: function(columns)
{
columns.push({id: "startTime", title: WebInspector.UIString("Start Time"), width: "110px", fixedWidth: true, sortable: true});
WebInspector.TimelineTreeView.prototype._populateColumns.call(this, columns);
},
/**
* @override
* @param {!Element} parent
*/
_populateToolbar: function(parent)
{
var filtersWidget = this._filtersControl.filtersWidget();
filtersWidget.forceShowFilterBar();
filtersWidget.show(parent);
},
/**
* @override
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {boolean}
*/
_showDetailsForNode: function(node)
{
var traceEvent = node.event;
if (!traceEvent)
return false;
WebInspector.TimelineUIUtils.buildTraceEventDetails(traceEvent, this._model, this._linkifier, false, showDetails.bind(this));
return true;
/**
* @param {!DocumentFragment} fragment
* @this {WebInspector.EventsTimelineTreeView}
*/
function showDetails(fragment)
{
this._detailsView.element.appendChild(fragment);
}
},
/**
* @override
* @param {?WebInspector.TimelineProfileTree.Node} node
*/
_onHover: function(node)
{
this._delegate.highlightEvent(node && node.event);
},
__proto__: WebInspector.TimelineTreeView.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.TimelineStackView = function(treeView)
{
WebInspector.VBox.call(this);
var header = this.element.createChild("div", "timeline-stack-view-header");
header.textContent = WebInspector.UIString("Heaviest stack");
this._treeView = treeView;
var columns = [
{id: "total", title: WebInspector.UIString("Total Time"), fixedWidth: true, width: "110px"},
{id: "activity", title: WebInspector.UIString("Activity")}
];
this._dataGrid = new WebInspector.ViewportDataGrid(columns);
this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._onSelectionChanged, this);
this._dataGrid.asWidget().show(this.element);
}
/**
* @enum {symbol}
*/
WebInspector.TimelineStackView.Events = {
SelectionChanged: Symbol("SelectionChanged")
}
WebInspector.TimelineStackView.prototype = {
/**
* @param {!Array<!WebInspector.TimelineProfileTree.Node>} stack
* @param {!WebInspector.TimelineProfileTree.Node} selectedNode
*/
setStack: function(stack, selectedNode)
{
var rootNode = this._dataGrid.rootNode();
rootNode.removeChildren();
var nodeToReveal = null;
var totalTime = Math.max.apply(Math, stack.map(node => node.totalTime));
for (var node of stack) {
var gridNode = new WebInspector.TimelineTreeView.GridNode(node, totalTime, totalTime, totalTime, this._treeView);
rootNode.appendChild(gridNode);
if (node === selectedNode)
nodeToReveal = gridNode;
}
nodeToReveal.revealAndSelect();
},
/**
* @return {?WebInspector.TimelineProfileTree.Node}
*/
selectedTreeNode: function()
{
var selectedNode = this._dataGrid.selectedNode;
return selectedNode && /** @type {!WebInspector.TimelineTreeView.GridNode} */ (selectedNode)._profileNode;
},
_onSelectionChanged: function()
{
this.dispatchEventToListeners(WebInspector.TimelineStackView.Events.SelectionChanged);
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * Copyright (C) 2012 Intel Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.TimelineUIUtils = function() { } /** * @constructor * @param {string} title * @param {!WebInspector.TimelineCategory} category * @param {boolean=} hidden */ WebInspector.TimelineRecordStyle = function(title, category, hidden) { this.title = title; this.category = category; this.hidden = !!hidden; } /** * @return {!Object.<string, !WebInspector.TimelineRecordStyle>} */ WebInspector.TimelineUIUtils._initEventStyles = function() { if (WebInspector.TimelineUIUtils._eventStylesMap) return WebInspector.TimelineUIUtils._eventStylesMap; var recordTypes = WebInspector.TimelineModel.RecordType; var categories = WebInspector.TimelineUIUtils.categories(); var eventStyles = {}; eventStyles[recordTypes.Task] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Task"), categories["other"]); eventStyles[recordTypes.Program] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Other"), categories["other"]); eventStyles[recordTypes.Animation] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation"), categories["rendering"]); eventStyles[recordTypes.EventDispatch] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Event"), categories["scripting"]); eventStyles[recordTypes.RequestMainThreadFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Main Thread Frame"), categories["rendering"], true); eventStyles[recordTypes.BeginFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start"), categories["rendering"], true); eventStyles[recordTypes.BeginMainThreadFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start (main thread)"), categories["rendering"], true); eventStyles[recordTypes.DrawFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Draw Frame"), categories["rendering"], true); eventStyles[recordTypes.HitTest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Hit Test"), categories["rendering"]); eventStyles[recordTypes.ScheduleStyleRecalculation] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Schedule Style Recalculation"), categories["rendering"], true); eventStyles[recordTypes.RecalculateStyles] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"), categories["rendering"]); eventStyles[recordTypes.UpdateLayoutTree] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"), categories["rendering"]); eventStyles[recordTypes.InvalidateLayout] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Invalidate Layout"), categories["rendering"], true); eventStyles[recordTypes.Layout] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Layout"), categories["rendering"]); eventStyles[recordTypes.PaintSetup] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Setup"), categories["painting"]); eventStyles[recordTypes.PaintImage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Image"), categories["painting"], true); eventStyles[recordTypes.UpdateLayer] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer"), categories["painting"], true); eventStyles[recordTypes.UpdateLayerTree] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer Tree"), categories["rendering"]); eventStyles[recordTypes.Paint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"), categories["painting"]); eventStyles[recordTypes.RasterTask] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Rasterize Paint"), categories["painting"]); eventStyles[recordTypes.ScrollLayer] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Scroll"), categories["rendering"]); eventStyles[recordTypes.CompositeLayers] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Composite Layers"), categories["painting"]); eventStyles[recordTypes.ParseHTML] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse HTML"), categories["loading"]); eventStyles[recordTypes.ParseAuthorStyleSheet] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Stylesheet"), categories["loading"]); eventStyles[recordTypes.TimerInstall] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Install Timer"), categories["scripting"]); eventStyles[recordTypes.TimerRemove] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Remove Timer"), categories["scripting"]); eventStyles[recordTypes.TimerFire] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timer Fired"), categories["scripting"]); eventStyles[recordTypes.XHRReadyStateChange] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Ready State Change"), categories["scripting"]); eventStyles[recordTypes.XHRLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Load"), categories["scripting"]); eventStyles[recordTypes.CompileScript] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Compile Script"), categories["scripting"]); eventStyles[recordTypes.EvaluateScript] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Evaluate Script"), categories["scripting"]); eventStyles[recordTypes.ParseScriptOnBackground] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Script"), categories["scripting"]); eventStyles[recordTypes.MarkLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Load event"), categories["scripting"], true); eventStyles[recordTypes.MarkDOMContent] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOMContentLoaded event"), categories["scripting"], true); eventStyles[recordTypes.MarkFirstPaint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"), categories["painting"], true); eventStyles[recordTypes.TimeStamp] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timestamp"), categories["scripting"]); eventStyles[recordTypes.ConsoleTime] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Console Time"), categories["scripting"]); eventStyles[recordTypes.UserTiming] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("User Timing"), categories["scripting"]); eventStyles[recordTypes.ResourceSendRequest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send Request"), categories["loading"]); eventStyles[recordTypes.ResourceReceiveResponse] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Response"), categories["loading"]); eventStyles[recordTypes.ResourceFinish] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Finish Loading"), categories["loading"]); eventStyles[recordTypes.ResourceReceivedData] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Data"), categories["loading"]); eventStyles[recordTypes.FunctionCall] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Function Call"), categories["scripting"]); eventStyles[recordTypes.GCEvent] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("GC Event"), categories["scripting"]); eventStyles[recordTypes.MajorGC] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Major GC"), categories["scripting"]); eventStyles[recordTypes.MinorGC] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Minor GC"), categories["scripting"]); eventStyles[recordTypes.JSFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("JS Frame"), categories["scripting"]); eventStyles[recordTypes.RequestAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Animation Frame"), categories["scripting"]); eventStyles[recordTypes.CancelAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Animation Frame"), categories["scripting"]); eventStyles[recordTypes.FireAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation Frame Fired"), categories["scripting"]); eventStyles[recordTypes.RequestIdleCallback] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Idle Callback"), categories["scripting"]); eventStyles[recordTypes.CancelIdleCallback] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Idle Callback"), categories["scripting"]); eventStyles[recordTypes.FireIdleCallback] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Fire Idle Callback"), categories["scripting"]); eventStyles[recordTypes.WebSocketCreate] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Create WebSocket"), categories["scripting"]); eventStyles[recordTypes.WebSocketSendHandshakeRequest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send WebSocket Handshake"), categories["scripting"]); eventStyles[recordTypes.WebSocketReceiveHandshakeResponse] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive WebSocket Handshake"), categories["scripting"]); eventStyles[recordTypes.WebSocketDestroy] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Destroy WebSocket"), categories["scripting"]); eventStyles[recordTypes.EmbedderCallback] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Embedder Callback"), categories["scripting"]); eventStyles[recordTypes.DecodeImage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Decode"), categories["painting"]); eventStyles[recordTypes.ResizeImage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Resize"), categories["painting"]); eventStyles[recordTypes.GPUTask] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("GPU"), categories["gpu"]); eventStyles[recordTypes.LatencyInfo] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Input Latency"), categories["scripting"]); eventStyles[recordTypes.GCIdleLazySweep] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"), categories["scripting"]); eventStyles[recordTypes.GCCompleteSweep] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"), categories["scripting"]); eventStyles[recordTypes.GCCollectGarbage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"), categories["scripting"]); WebInspector.TimelineUIUtils._eventStylesMap = eventStyles; return eventStyles; } /** * @param {!WebInspector.TracingModel.Event} traceEvent * @param {!RegExp} regExp * @return {boolean} */ WebInspector.TimelineUIUtils.testContentMatching = function(traceEvent, regExp) { var title = WebInspector.TimelineUIUtils.eventStyle(traceEvent).title; var tokens = [title]; if (traceEvent.url) tokens.push(traceEvent.url); for (var argName in traceEvent.args) { var argValue = traceEvent.args[argName]; for (var key in argValue) tokens.push(argValue[key]); } return regExp.test(tokens.join("|")); } /** * @param {!WebInspector.TimelineModel.Record} record * @return {!WebInspector.TimelineCategory} */ WebInspector.TimelineUIUtils.categoryForRecord = function(record) { return WebInspector.TimelineUIUtils.eventStyle(record.traceEvent()).category; } /** * @param {!WebInspector.TracingModel.Event} event * @return {!{title: string, category: !WebInspector.TimelineCategory}} */ WebInspector.TimelineUIUtils.eventStyle = function(event) { var eventStyles = WebInspector.TimelineUIUtils._initEventStyles(); if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return { title: event.name, category: WebInspector.TimelineUIUtils.categories()["scripting"] }; if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) { /** @const */ var prefix = "InputLatency::"; var name = event.name.startsWith(prefix) ? event.name.substr(prefix.length) : event.name; return { title: name, category: WebInspector.TimelineUIUtils.categories()["scripting"] }; } var result = eventStyles[event.name]; if (!result) { result = new WebInspector.TimelineRecordStyle(event.name, WebInspector.TimelineUIUtils.categories()["other"], true); eventStyles[event.name] = result; } return result; } /** * @param {!WebInspector.TracingModel.Event} event * @return {string} */ WebInspector.TimelineUIUtils.eventColor = function(event) { if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) { var frame = event.args["data"]; if (WebInspector.TimelineUIUtils.isUserFrame(frame)) return WebInspector.TimelineUIUtils.colorForURL(frame.url); } return WebInspector.TimelineUIUtils.eventStyle(event).category.color; } /** * @param {!WebInspector.TracingModel.Event} event * @return {string} */ WebInspector.TimelineUIUtils.eventTitle = function(event) { var title = WebInspector.TimelineUIUtils.eventStyle(event).title; if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) return title; if (event.name === WebInspector.TimelineModel.RecordType.TimeStamp) return WebInspector.UIString("%s: %s", title, event.args["data"]["message"]); if (event.name === WebInspector.TimelineModel.RecordType.Animation && event.args["data"] && event.args["data"]["name"]) return WebInspector.UIString("%s: %s", title, event.args["data"]["name"]); return title; } /** * !Map<!WebInspector.TimelineIRModel.Phases, !{color: string, label: string}> */ WebInspector.TimelineUIUtils._interactionPhaseStyles = function() { var map = WebInspector.TimelineUIUtils._interactionPhaseStylesMap; if (!map) { map = new Map([ [WebInspector.TimelineIRModel.Phases.Idle, {color: "white", label: "Idle"}], [WebInspector.TimelineIRModel.Phases.Response, {color: "hsl(43, 83%, 64%)", label: WebInspector.UIString("Response")}], [WebInspector.TimelineIRModel.Phases.Scroll, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Scroll")}], [WebInspector.TimelineIRModel.Phases.Fling, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Fling")}], [WebInspector.TimelineIRModel.Phases.Drag, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Drag")}], [WebInspector.TimelineIRModel.Phases.Animation, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Animation")}] ]); WebInspector.TimelineUIUtils._interactionPhaseStylesMap = map; } return map; } /** * @param {!WebInspector.TimelineIRModel.Phases} phase * @return {string} */ WebInspector.TimelineUIUtils.interactionPhaseColor = function(phase) { return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).color; } /** * @param {!WebInspector.TimelineIRModel.Phases} phase * @return {string} */ WebInspector.TimelineUIUtils.interactionPhaseLabel = function(phase) { return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).label; } /** * @param {!WebInspector.TracingModel.Event} event * @return {boolean} */ WebInspector.TimelineUIUtils.isMarkerEvent = function(event) { var recordTypes = WebInspector.TimelineModel.RecordType; switch (event.name) { case recordTypes.TimeStamp: case recordTypes.MarkFirstPaint: return true; case recordTypes.MarkDOMContent: case recordTypes.MarkLoad: return event.args["data"]["isMainFrame"]; default: return false; } } /** * @param {!RuntimeAgent.CallFrame} frame * @return {boolean} */ WebInspector.TimelineUIUtils.isUserFrame = function(frame) { return frame.scriptId !== "0" && !frame.url.startsWith("native "); } /** * @param {!WebInspector.TracingModel.Event} event * @return {?RuntimeAgent.CallFrame} */ WebInspector.TimelineUIUtils.topStackFrame = function(event) { var stackTrace = event.stackTrace || event.initiator && event.initiator.stackTrace; return stackTrace && stackTrace.length ? stackTrace[0] : null; } /** * @enum {symbol} */ WebInspector.TimelineUIUtils.NetworkCategory = { HTML: Symbol("HTML"), Script: Symbol("Script"), Style: Symbol("Style"), Media: Symbol("Media"), Other: Symbol("Other") } /** * @param {!WebInspector.TimelineModel.NetworkRequest} request * @return {!WebInspector.TimelineUIUtils.NetworkCategory} */ WebInspector.TimelineUIUtils.networkRequestCategory = function(request) { var categories = WebInspector.TimelineUIUtils.NetworkCategory; switch (request.mimeType) { case "text/html": return categories.HTML; case "application/javascript": case "application/x-javascript": case "text/javascript": return categories.Script; case "text/css": return categories.Style; case "audio/ogg": case "image/gif": case "image/jpeg": case "image/png": case "image/svg+xml": case "image/webp": case "image/x-icon": case "font/opentype": case "font/woff2": case "application/font-woff": return categories.Media; default: return categories.Other; } } /** * @param {!WebInspector.TimelineUIUtils.NetworkCategory} category * @return {string} */ WebInspector.TimelineUIUtils.networkCategoryColor = function(category) { var categories = WebInspector.TimelineUIUtils.NetworkCategory; switch (category) { case categories.HTML: return "hsl(214, 67%, 66%)"; case categories.Script: return "hsl(43, 83%, 64%)"; case categories.Style: return "hsl(256, 67%, 70%)"; case categories.Media: return "hsl(109, 33%, 55%)"; default: return "hsl(0, 0%, 70%)"; } } /** * @param {!WebInspector.TracingModel.Event} event * @param {?WebInspector.Target} target * @return {?string} */ WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent = function(event, target) { var recordType = WebInspector.TimelineModel.RecordType; var detailsText; var eventData = event.args["data"]; switch (event.name) { case recordType.GCEvent: case recordType.MajorGC: case recordType.MinorGC: var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"]; detailsText = WebInspector.UIString("%s collected", Number.bytesToString(delta)); break; case recordType.FunctionCall: // Omit internally generated script names. if (eventData && eventData["scriptName"]) detailsText = linkifyLocationAsText(eventData["scriptId"], eventData["scriptLine"], 0); break; case recordType.JSFrame: detailsText = WebInspector.beautifyFunctionName(eventData["functionName"]); break; case recordType.EventDispatch: detailsText = eventData ? eventData["type"] : null; break; case recordType.Paint: var width = WebInspector.TimelineUIUtils.quadWidth(eventData.clip); var height = WebInspector.TimelineUIUtils.quadHeight(eventData.clip); if (width && height) detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height); break; case recordType.ParseHTML: var endLine = event.args["endData"] && event.args["endData"]["endLine"]; var url = WebInspector.displayNameForURL(event.args["beginData"]["url"]); detailsText = WebInspector.UIString("%s [%s\u2026%s]", url, event.args["beginData"]["startLine"] + 1, endLine >= 0 ? endLine + 1 : ""); break; case recordType.CompileScript: case recordType.EvaluateScript: var url = eventData["url"]; if (url) detailsText = WebInspector.displayNameForURL(url) + ":" + eventData["lineNumber"]; break; case recordType.ParseScriptOnBackground: case recordType.XHRReadyStateChange: case recordType.XHRLoad: var url = eventData["url"]; if (url) detailsText = WebInspector.displayNameForURL(url); break; case recordType.WebSocketCreate: case recordType.WebSocketSendHandshakeRequest: case recordType.WebSocketReceiveHandshakeResponse: case recordType.WebSocketDestroy: case recordType.ResourceSendRequest: case recordType.ResourceReceivedData: case recordType.ResourceReceiveResponse: case recordType.ResourceFinish: case recordType.PaintImage: case recordType.DecodeImage: case recordType.ResizeImage: case recordType.DecodeLazyPixelRef: if (event.url) detailsText = WebInspector.displayNameForURL(event.url); break; case recordType.EmbedderCallback: detailsText = eventData["callbackName"]; break; case recordType.Animation: detailsText = eventData && eventData["name"]; break; case recordType.GCIdleLazySweep: detailsText = WebInspector.UIString("idle sweep"); break; case recordType.GCCompleteSweep: detailsText = WebInspector.UIString("complete sweep"); break; case recordType.GCCollectGarbage: detailsText = WebInspector.UIString("collect"); break; default: if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) detailsText = null; else detailsText = linkifyTopCallFrameAsText(); break; } return detailsText; /** * @param {string} scriptId * @param {number} lineNumber * @param {number=} columnNumber * @return {?string} */ function linkifyLocationAsText(scriptId, lineNumber, columnNumber) { // FIXME(62725): stack trace line/column numbers are one-based. var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); var rawLocation = target && !target.isDetached() && scriptId && debuggerModel ? debuggerModel.createRawLocationByScriptId(scriptId, lineNumber - 1, (columnNumber || 1) - 1) : null; if (!rawLocation) return null; var uiLocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation); return uiLocation.linkText(); } /** * @return {?string} */ function linkifyTopCallFrameAsText() { var frame = WebInspector.TimelineUIUtils.topStackFrame(event); var text = frame ? linkifyLocationAsText(frame.scriptId, frame.lineNumber, frame.columnNumber) : null; if (frame && !text) { text = frame.url; if (typeof frame.lineNumber === "number") text += ":" + (frame.lineNumber + 1); } return text; } } /** * @param {!WebInspector.TracingModel.Event} event * @param {?WebInspector.Target} target * @param {!WebInspector.Linkifier} linkifier * @return {?Node} */ WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, target, linkifier) { var recordType = WebInspector.TimelineModel.RecordType; var details; var detailsText; var eventData = event.args["data"]; switch (event.name) { case recordType.GCEvent: case recordType.MajorGC: case recordType.MinorGC: case recordType.EventDispatch: case recordType.Paint: case recordType.Animation: case recordType.EmbedderCallback: case recordType.ParseHTML: case recordType.WebSocketCreate: case recordType.WebSocketSendHandshakeRequest: case recordType.WebSocketReceiveHandshakeResponse: case recordType.WebSocketDestroy: case recordType.GCIdleLazySweep: case recordType.GCCompleteSweep: case recordType.GCCollectGarbage: detailsText = WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent(event, target); break; case recordType.PaintImage: case recordType.DecodeImage: case recordType.ResizeImage: case recordType.DecodeLazyPixelRef: case recordType.XHRReadyStateChange: case recordType.XHRLoad: case recordType.ResourceSendRequest: case recordType.ResourceReceivedData: case recordType.ResourceReceiveResponse: case recordType.ResourceFinish: if (event.url) details = WebInspector.linkifyResourceAsNode(event.url); break; case recordType.FunctionCall: details = linkifyLocation(eventData["scriptId"], eventData["scriptName"], eventData["scriptLine"], 0); break; case recordType.JSFrame: details = createElement("span"); details.createTextChild(WebInspector.beautifyFunctionName(eventData["functionName"])); var location = linkifyLocation(eventData["scriptId"], eventData["url"], eventData["lineNumber"], eventData["columnNumber"]); if (location) { details.createTextChild(" @ "); details.appendChild(location); } break; case recordType.CompileScript: case recordType.EvaluateScript: var url = eventData["url"]; if (url) details = linkifyLocation("", url, eventData["lineNumber"], 0); break; case recordType.ParseScriptOnBackground: var url = eventData["url"]; if (url) details = linkifyLocation("", url, 0, 0); break; default: if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) detailsText = null; else details = linkifyTopCallFrame(); break; } if (!details && detailsText) details = createTextNode(detailsText); return details; /** * @param {string} scriptId * @param {string} url * @param {number} lineNumber * @param {number=} columnNumber */ function linkifyLocation(scriptId, url, lineNumber, columnNumber) { if (!url) return null; // FIXME(62725): stack trace line/column numbers are one-based. if (columnNumber) --columnNumber; return linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber - 1, columnNumber, "timeline-details"); } /** * @return {?Element} */ function linkifyTopCallFrame() { var frame = WebInspector.TimelineUIUtils.topStackFrame(event); return frame ? linkifier.linkifyConsoleCallFrame(target, frame, "timeline-details") : null; } } /** * @param {!WebInspector.TracingModel.Event} event * @param {!WebInspector.TimelineModel} model * @param {!WebInspector.Linkifier} linkifier * @param {boolean} detailed * @param {function(!DocumentFragment)} callback */ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, linkifier, detailed, callback) { var target = model.target(); if (!target) { callbackWrapper(); return; } var relatedNodes = null; var barrier = new CallbackBarrier(); if (!event.previewElement) { if (event.url) WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, event.url, false, barrier.createCallback(saveImage)); else if (event.picture) WebInspector.TimelineUIUtils.buildPicturePreviewContent(event, target, barrier.createCallback(saveImage)); } var nodeIdsToResolve = new Set(); if (event.backendNodeId) nodeIdsToResolve.add(event.backendNodeId); if (event.invalidationTrackingEvents) WebInspector.TimelineUIUtils._collectInvalidationNodeIds(nodeIdsToResolve, event.invalidationTrackingEvents); if (nodeIdsToResolve.size) { var domModel = WebInspector.DOMModel.fromTarget(target); if (domModel) domModel.pushNodesByBackendIdsToFrontend(nodeIdsToResolve, barrier.createCallback(setRelatedNodeMap)); } barrier.callWhenDone(callbackWrapper); /** * @param {!Element=} element */ function saveImage(element) { event.previewElement = element || null; } /** * @param {?Map<number, ?WebInspector.DOMNode>} nodeMap */ function setRelatedNodeMap(nodeMap) { relatedNodes = nodeMap; } function callbackWrapper() { callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously(event, model, linkifier, detailed, relatedNodes)); } } /** * @param {!WebInspector.TracingModel.Event} event * @param {!WebInspector.TimelineModel} model * @param {!WebInspector.Linkifier} linkifier * @param {boolean} detailed * @param {?Map<number, ?WebInspector.DOMNode>} relatedNodesMap * @return {!DocumentFragment} */ WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(event, model, linkifier, detailed, relatedNodesMap) { var stats = {}; var recordTypes = WebInspector.TimelineModel.RecordType; // This message may vary per event.name; var relatedNodeLabel; var contentHelper = new WebInspector.TimelineDetailsContentHelper(model.target(), linkifier); contentHelper.addSection(WebInspector.TimelineUIUtils.eventTitle(event), WebInspector.TimelineUIUtils.eventStyle(event).category); var eventData = event.args["data"]; var initiator = event.initiator; if (event.warning) contentHelper.appendWarningRow(event); if (event.name === recordTypes.JSFrame) { var deoptReason = eventData["deoptReason"]; if (deoptReason && deoptReason != "no reason") contentHelper.appendWarningRow(event, WebInspector.TimelineModel.WarningType.V8Deopt); } if (detailed) { contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.millisToString(event.selfTime, true)); contentHelper.appendTextRow(WebInspector.UIString("Total Time"), Number.millisToString(event.duration || 0, true)); } switch (event.name) { case recordTypes.GCEvent: case recordTypes.MajorGC: case recordTypes.MinorGC: var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"]; contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(delta)); break; case recordTypes.JSFrame: var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.target(), linkifier); if (detailsNode) contentHelper.appendElementRow(WebInspector.UIString("Function"), detailsNode); break; case recordTypes.TimerFire: case recordTypes.TimerInstall: case recordTypes.TimerRemove: contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData["timerId"]); if (event.name === recordTypes.TimerInstall) { contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.millisToString(eventData["timeout"])); contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !eventData["singleShot"]); } break; case recordTypes.FireAnimationFrame: contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventData["id"]); break; case recordTypes.FunctionCall: if (typeof eventData["functionName"] === "string") contentHelper.appendTextRow(WebInspector.UIString("Function"), WebInspector.beautifyFunctionName(eventData["functionName"])); if (eventData["scriptName"]) contentHelper.appendLocationRow(WebInspector.UIString("Location"), eventData["scriptName"], eventData["scriptLine"]); break; case recordTypes.ResourceSendRequest: case recordTypes.ResourceReceiveResponse: case recordTypes.ResourceReceivedData: case recordTypes.ResourceFinish: var url = (event.name === recordTypes.ResourceSendRequest) ? eventData["url"] : initiator && initiator.args["data"]["url"]; if (url) contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(url)); if (eventData["requestMethod"]) contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]); if (typeof eventData["statusCode"] === "number") contentHelper.appendTextRow(WebInspector.UIString("Status Code"), eventData["statusCode"]); if (eventData["mimeType"]) contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), eventData["mimeType"]); if ("priority" in eventData) { var priority = WebInspector.uiLabelForPriority(eventData["priority"]); contentHelper.appendTextRow(WebInspector.UIString("Priority"), priority); } if (eventData["encodedDataLength"]) contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"])); break; case recordTypes.CompileScript: case recordTypes.EvaluateScript: var url = eventData["url"]; if (url) contentHelper.appendLocationRow(WebInspector.UIString("Script"), url, eventData["lineNumber"], eventData["columnNumber"]); break; case recordTypes.Paint: var clip = eventData["clip"]; contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1])); var clipWidth = WebInspector.TimelineUIUtils.quadWidth(clip); var clipHeight = WebInspector.TimelineUIUtils.quadHeight(clip); contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight)); // Fall-through intended. case recordTypes.PaintSetup: case recordTypes.Rasterize: case recordTypes.ScrollLayer: relatedNodeLabel = WebInspector.UIString("Layer Root"); break; case recordTypes.PaintImage: case recordTypes.DecodeLazyPixelRef: case recordTypes.DecodeImage: case recordTypes.ResizeImage: case recordTypes.DrawLazyPixelRef: relatedNodeLabel = WebInspector.UIString("Owner Element"); if (event.url) contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(event.url)); break; case recordTypes.ParseAuthorStyleSheet: var url = eventData["styleSheetUrl"]; if (url) contentHelper.appendElementRow(WebInspector.UIString("Stylesheet URL"), WebInspector.linkifyResourceAsNode(url)); break; case recordTypes.UpdateLayoutTree: // We don't want to see default details. case recordTypes.RecalculateStyles: contentHelper.appendTextRow(WebInspector.UIString("Elements Affected"), event.args["elementCount"]); break; case recordTypes.Layout: var beginData = event.args["beginData"]; contentHelper.appendTextRow(WebInspector.UIString("Nodes That Need Layout"), beginData["dirtyObjects"]); relatedNodeLabel = WebInspector.UIString("Layout root"); break; case recordTypes.ConsoleTime: contentHelper.appendTextRow(WebInspector.UIString("Message"), event.name); break; case recordTypes.WebSocketCreate: case recordTypes.WebSocketSendHandshakeRequest: case recordTypes.WebSocketReceiveHandshakeResponse: case recordTypes.WebSocketDestroy: var initiatorData = initiator ? initiator.args["data"] : eventData; if (typeof initiatorData["webSocketURL"] !== "undefined") contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorData["webSocketURL"]); if (typeof initiatorData["webSocketProtocol"] !== "undefined") contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), initiatorData["webSocketProtocol"]); if (typeof eventData["message"] !== "undefined") contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]); break; case recordTypes.EmbedderCallback: contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]); break; case recordTypes.Animation: if (event.phase === WebInspector.TracingModel.Phase.NestableAsyncInstant) contentHelper.appendTextRow(WebInspector.UIString("State"), eventData["state"]); break; case recordTypes.ParseHTML: var beginData = event.args["beginData"]; var url = beginData["url"]; var startLine = beginData["startLine"] + 1; var endLine = event.args["endData"] ? event.args["endData"]["endLine"] + 1 : 0; if (url) contentHelper.appendLocationRange(WebInspector.UIString("Range"), url, startLine, endLine); break; case recordTypes.FireIdleCallback: contentHelper.appendTextRow(WebInspector.UIString("Allotted Time"), Number.millisToString(eventData["allottedMilliseconds"])); contentHelper.appendTextRow(WebInspector.UIString("Invoked by Timeout"), eventData["timedOut"]); // Fall-through intended. case recordTypes.RequestIdleCallback: case recordTypes.CancelIdleCallback: contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventData["id"]); break; case recordTypes.EventDispatch: contentHelper.appendTextRow(WebInspector.UIString("Type"), eventData["type"]); break; default: var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.target(), linkifier); if (detailsNode) contentHelper.appendElementRow(WebInspector.UIString("Details"), detailsNode); break; } var relatedNode = relatedNodesMap && relatedNodesMap.get(event.backendNodeId); if (relatedNode) contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString("Related Node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(relatedNode)); if (event.previewElement) { contentHelper.addSection(WebInspector.UIString("Preview")); contentHelper.appendElementRow("", event.previewElement); } if (event.stackTrace || (event.initiator && event.initiator.stackTrace) || event.invalidationTrackingEvents) WebInspector.TimelineUIUtils._generateCauses(event, model.target(), relatedNodesMap, contentHelper); var showPieChart = detailed && WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(stats, model, event); if (showPieChart) { contentHelper.addSection(WebInspector.UIString("Aggregated Time")); var pieChart = WebInspector.TimelineUIUtils.generatePieChart(stats, WebInspector.TimelineUIUtils.eventStyle(event).category, event.selfTime); contentHelper.appendElementRow("", pieChart); } return contentHelper.fragment; } WebInspector.TimelineUIUtils._aggregatedStatsKey = Symbol("aggregatedStats"); /** * @param {!WebInspector.TimelineModel} model * @param {number} startTime * @param {number} endTime * @return {!DocumentFragment} */ WebInspector.TimelineUIUtils.buildRangeStats = function(model, startTime, endTime) { var aggregatedStats = {}; /** * @param {number} value * @param {!WebInspector.TimelineModel.Record} task * @return {number} */ function compareEndTime(value, task) { return value < task.endTime() ? -1 : 1; } var mainThreadTasks = model.mainThreadTasks(); var taskIndex = mainThreadTasks.lowerBound(startTime, compareEndTime); for (; taskIndex < mainThreadTasks.length; ++taskIndex) { var task = mainThreadTasks[taskIndex]; if (task.startTime() > endTime) break; if (task.startTime() > startTime && task.endTime() < endTime) { // cache stats for top-level entries that fit the range entirely. var taskStats = task[WebInspector.TimelineUIUtils._aggregatedStatsKey]; if (!taskStats) { taskStats = {}; WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task, startTime, endTime, taskStats); task[WebInspector.TimelineUIUtils._aggregatedStatsKey] = taskStats; } for (var key in taskStats) aggregatedStats[key] = (aggregatedStats[key] || 0) + taskStats[key]; continue; } WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task, startTime, endTime, aggregatedStats); } var aggregatedTotal = 0; for (var categoryName in aggregatedStats) aggregatedTotal += aggregatedStats[categoryName]; aggregatedStats["idle"] = Math.max(0, endTime - startTime - aggregatedTotal); var startOffset = startTime - model.minimumRecordTime(); var endOffset = endTime - model.minimumRecordTime(); var contentHelper = new WebInspector.TimelineDetailsContentHelper(null, null); contentHelper.addSection(WebInspector.UIString("Range: %s \u2013 %s", Number.millisToString(startOffset), Number.millisToString(endOffset))); var pieChart = WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats); contentHelper.appendElementRow("", pieChart); return contentHelper.fragment; } /** * @param {!WebInspector.TimelineModel.Record} record * @param {number} startTime * @param {number} endTime * @param {!Object} aggregatedStats */ WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord = function(record, startTime, endTime, aggregatedStats) { var records = []; if (!record.endTime() || record.endTime() < startTime || record.startTime() > endTime) return; var childrenTime = 0; var children = record.children() || []; for (var i = 0; i < children.length; ++i) { var child = children[i]; if (!child.endTime() || child.endTime() < startTime || child.startTime() > endTime) continue; childrenTime += Math.min(endTime, child.endTime()) - Math.max(startTime, child.startTime()); WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(child, startTime, endTime, aggregatedStats); } var categoryName = WebInspector.TimelineUIUtils.categoryForRecord(record).name; var ownTime = Math.min(endTime, record.endTime()) - Math.max(startTime, record.startTime()) - childrenTime; aggregatedStats[categoryName] = (aggregatedStats[categoryName] || 0) + ownTime; } /** * @param {!WebInspector.TimelineModel.NetworkRequest} request * @return {!Array<!{title: string, value: (string|!Element)}>} */ WebInspector.TimelineUIUtils.buildNetworkRequestInfo = function(request) { var duration = request.endTime - (request.startTime || -Infinity); var items = []; if (request.url) items.push({ title: WebInspector.UIString("URL"), value: WebInspector.linkifyURLAsNode(request.url) }); if (isFinite(duration)) items.push({ title: WebInspector.UIString("Duration"), value: Number.millisToString(duration, true) }); if (request.requestMethod) items.push({ title: WebInspector.UIString("Request Method"), value: request.requestMethod }); if (typeof request.priority === "string") { var priority = WebInspector.uiLabelForPriority(/** @type {!NetworkAgent.ResourcePriority} */ (request.priority)); items.push({ title: WebInspector.UIString("Priority"), value: priority }); } if (request.mimeType) items.push({ title: WebInspector.UIString("Mime Type"), value: request.mimeType }); return items; } /** * @param {!WebInspector.TimelineModel.NetworkRequest} request * @param {!WebInspector.TimelineModel} model * @param {!WebInspector.Linkifier} linkifier * @return {!Promise<!DocumentFragment>} */ WebInspector.TimelineUIUtils.buildNetworkRequestDetails = function(request, model, linkifier) { var target = model.target(); var contentHelper = new WebInspector.TimelineDetailsContentHelper(target, linkifier); var info = WebInspector.TimelineUIUtils.buildNetworkRequestInfo(request); for (var item of info) { if (typeof item.value === "string") contentHelper.appendTextRow(item.title, item.value); else contentHelper.appendElementRow(item.title, item.value); } /** * @param {function(?Element)} fulfill */ function action(fulfill) { WebInspector.DOMPresentationUtils.buildImagePreviewContents(/** @type {!WebInspector.Target} */(target), request.url, false, saveImage); /** * @param {!Element=} element */ function saveImage(element) { request.previewElement = element || null; fulfill(request.previewElement); } } var previewPromise; if (request.previewElement) previewPromise = Promise.resolve(request.previewElement); else previewPromise = request.url && target ? new Promise(action) : Promise.resolve(null); /** * @param {?Element} element * @return {!DocumentFragment} */ function appendPreview(element) { if (element) contentHelper.appendElementRow(WebInspector.UIString("Preview"), request.previewElement); return contentHelper.fragment; } return previewPromise.then(appendPreview); } /** * @param {!Array<!RuntimeAgent.CallFrame>} callFrames * @return {!RuntimeAgent.StackTrace} */ WebInspector.TimelineUIUtils._stackTraceFromCallFrames = function(callFrames) { return /** @type {!RuntimeAgent.StackTrace} */ ({ callFrames: callFrames }); } /** * @param {!WebInspector.TracingModel.Event} event * @param {?WebInspector.Target} target * @param {?Map<number, ?WebInspector.DOMNode>} relatedNodesMap * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper */ WebInspector.TimelineUIUtils._generateCauses = function(event, target, relatedNodesMap, contentHelper) { var recordTypes = WebInspector.TimelineModel.RecordType; var callSiteStackLabel; var stackLabel; var initiator = event.initiator; switch (event.name) { case recordTypes.TimerFire: callSiteStackLabel = WebInspector.UIString("Timer Installed"); break; case recordTypes.FireAnimationFrame: callSiteStackLabel = WebInspector.UIString("Animation Frame Requested"); break; case recordTypes.FireIdleCallback: callSiteStackLabel = WebInspector.UIString("Idle Callback Requested"); break; case recordTypes.UpdateLayoutTree: case recordTypes.RecalculateStyles: stackLabel = WebInspector.UIString("Recalculation Forced"); break; case recordTypes.Layout: callSiteStackLabel = WebInspector.UIString("First Layout Invalidation"); stackLabel = WebInspector.UIString("Layout Forced"); break; } // Direct cause. if (event.stackTrace && event.stackTrace.length) { contentHelper.addSection(WebInspector.UIString("Call Stacks")); contentHelper.appendStackTrace(stackLabel || WebInspector.UIString("Stack Trace"), WebInspector.TimelineUIUtils._stackTraceFromCallFrames(event.stackTrace)); } // Indirect causes. if (event.invalidationTrackingEvents && target) { // Full invalidation tracking (experimental). contentHelper.addSection(WebInspector.UIString("Invalidations")); WebInspector.TimelineUIUtils._generateInvalidations(event, target, relatedNodesMap, contentHelper); } else if (initiator && initiator.stackTrace) { // Partial invalidation tracking. contentHelper.appendStackTrace(callSiteStackLabel || WebInspector.UIString("First Invalidated"), WebInspector.TimelineUIUtils._stackTraceFromCallFrames(initiator.stackTrace)); } } /** * @param {!WebInspector.TracingModel.Event} event * @param {!WebInspector.Target} target * @param {?Map<number, ?WebInspector.DOMNode>} relatedNodesMap * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper */ WebInspector.TimelineUIUtils._generateInvalidations = function(event, target, relatedNodesMap, contentHelper) { if (!event.invalidationTrackingEvents) return; var invalidations = {}; event.invalidationTrackingEvents.forEach(function(invalidation) { if (!invalidations[invalidation.type]) invalidations[invalidation.type] = [invalidation]; else invalidations[invalidation.type].push(invalidation); }); Object.keys(invalidations).forEach(function(type) { WebInspector.TimelineUIUtils._generateInvalidationsForType( type, target, invalidations[type], relatedNodesMap, contentHelper); }); } /** * @param {string} type * @param {!WebInspector.Target} target * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations * @param {?Map<number, ?WebInspector.DOMNode>} relatedNodesMap * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper */ WebInspector.TimelineUIUtils._generateInvalidationsForType = function(type, target, invalidations, relatedNodesMap, contentHelper) { var title; switch (type) { case WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking: title = WebInspector.UIString("Style Invalidations"); break; case WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking: title = WebInspector.UIString("Layout Invalidations"); break; default: title = WebInspector.UIString("Other Invalidations"); break; } var invalidationsTreeOutline = new TreeOutlineInShadow(); invalidationsTreeOutline.registerRequiredCSS("timeline/invalidationsTree.css"); invalidationsTreeOutline.element.classList.add("invalidations-tree"); var invalidationGroups = groupInvalidationsByCause(invalidations); invalidationGroups.forEach(function(group) { var groupElement = new WebInspector.TimelineUIUtils.InvalidationsGroupElement(target, relatedNodesMap, contentHelper, group); invalidationsTreeOutline.appendChild(groupElement); }); contentHelper.appendElementRow(title, invalidationsTreeOutline.element, false, true); /** * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations */ function groupInvalidationsByCause(invalidations) { var causeToInvalidationMap = {}; for (var index = 0; index < invalidations.length; index++) { var invalidation = invalidations[index]; var causeKey = ""; if (invalidation.cause.reason) causeKey += invalidation.cause.reason + "."; if (invalidation.cause.stackTrace) { invalidation.cause.stackTrace.forEach(function(stackFrame) { causeKey += stackFrame["functionName"] + "."; causeKey += stackFrame["scriptId"] + "."; causeKey += stackFrame["url"] + "."; causeKey += stackFrame["lineNumber"] + "."; causeKey += stackFrame["columnNumber"] + "."; }); } if (causeToInvalidationMap[causeKey]) causeToInvalidationMap[causeKey].push(invalidation); else causeToInvalidationMap[causeKey] = [ invalidation ]; } return Object.values(causeToInvalidationMap); } } /** * @param {!Set<number>} nodeIds * @param {!WebInspector.InvalidationTrackingEvent} invalidations */ WebInspector.TimelineUIUtils._collectInvalidationNodeIds = function(nodeIds, invalidations) { for (var i = 0; i < invalidations.length; ++i) { if (invalidations[i].nodeId) nodeIds.add(invalidations[i].nodeId); } } /** * @constructor * @param {!WebInspector.Target} target * @param {?Map<number, ?WebInspector.DOMNode>} relatedNodesMap * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations * @extends {TreeElement} */ WebInspector.TimelineUIUtils.InvalidationsGroupElement = function(target, relatedNodesMap, contentHelper, invalidations) { TreeElement.call(this, "", true); this.listItemElement.classList.add("header"); this.selectable = false; this.toggleOnClick = true; this._relatedNodesMap = relatedNodesMap; this._contentHelper = contentHelper; this._invalidations = invalidations; this.title = this._createTitle(target); } WebInspector.TimelineUIUtils.InvalidationsGroupElement.prototype = { /** * @param {!WebInspector.Target} target * @return {!Element} */ _createTitle: function(target) { var first = this._invalidations[0]; var reason = first.cause.reason; var topFrame = first.cause.stackTrace && first.cause.stackTrace[0]; var title = createElement("span"); if (reason) title.createTextChild(WebInspector.UIString("%s for ", reason)); else title.createTextChild(WebInspector.UIString("Unknown cause for ")); this._appendTruncatedNodeList(title, this._invalidations); if (topFrame && this._contentHelper.linkifier()) { title.createTextChild(WebInspector.UIString(". ")); var stack = title.createChild("span", "monospace"); stack.createChild("span").textContent = WebInspector.beautifyFunctionName(topFrame.functionName); stack.createChild("span").textContent = " @ "; stack.createChild("span").appendChild(this._contentHelper.linkifier().linkifyConsoleCallFrame(target, topFrame)); } return title; }, /** * @override */ onpopulate: function() { var content = createElementWithClass("div", "content"); var first = this._invalidations[0]; if (first.cause.stackTrace) { var stack = content.createChild("div"); stack.createTextChild(WebInspector.UIString("Stack trace:")); this._contentHelper.createChildStackTraceElement(stack, WebInspector.TimelineUIUtils._stackTraceFromCallFrames(first.cause.stackTrace)); } content.createTextChild(this._invalidations.length > 1 ? WebInspector.UIString("Nodes:") : WebInspector.UIString("Node:")); var nodeList = content.createChild("div", "node-list"); var firstNode = true; for (var i = 0; i < this._invalidations.length; i++) { var invalidation = this._invalidations[i]; var invalidationNode = this._createInvalidationNode(invalidation, true); if (invalidationNode) { if (!firstNode) nodeList.createTextChild(WebInspector.UIString(", ")); firstNode = false; nodeList.appendChild(invalidationNode); var extraData = invalidation.extraData ? ", " + invalidation.extraData : ""; if (invalidation.changedId) nodeList.createTextChild(WebInspector.UIString("(changed id to \"%s\"%s)", invalidation.changedId, extraData)); else if (invalidation.changedClass) nodeList.createTextChild(WebInspector.UIString("(changed class to \"%s\"%s)", invalidation.changedClass, extraData)); else if (invalidation.changedAttribute) nodeList.createTextChild(WebInspector.UIString("(changed attribute to \"%s\"%s)", invalidation.changedAttribute, extraData)); else if (invalidation.changedPseudo) nodeList.createTextChild(WebInspector.UIString("(changed pesudo to \"%s\"%s)", invalidation.changedPseudo, extraData)); else if (invalidation.selectorPart) nodeList.createTextChild(WebInspector.UIString("(changed \"%s\"%s)", invalidation.selectorPart, extraData)); } } var contentTreeElement = new TreeElement(content, false); contentTreeElement.selectable = false; this.appendChild(contentTreeElement); }, /** * @param {!Element} parentElement * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations */ _appendTruncatedNodeList: function(parentElement, invalidations) { var invalidationNodes = []; var invalidationNodeIdMap = {}; for (var i = 0; i < invalidations.length; i++) { var invalidation = invalidations[i]; var invalidationNode = this._createInvalidationNode(invalidation, false); invalidationNode.addEventListener("click", consumeEvent, false); if (invalidationNode && !invalidationNodeIdMap[invalidation.nodeId]) { invalidationNodes.push(invalidationNode); invalidationNodeIdMap[invalidation.nodeId] = true; } } if (invalidationNodes.length === 1) { parentElement.appendChild(invalidationNodes[0]); } else if (invalidationNodes.length === 2) { parentElement.appendChild(invalidationNodes[0]); parentElement.createTextChild(WebInspector.UIString(" and ")); parentElement.appendChild(invalidationNodes[1]); } else if (invalidationNodes.length >= 3) { parentElement.appendChild(invalidationNodes[0]); parentElement.createTextChild(WebInspector.UIString(", ")); parentElement.appendChild(invalidationNodes[1]); parentElement.createTextChild(WebInspector.UIString(", and %s others", invalidationNodes.length - 2)); } }, /** * @param {!WebInspector.InvalidationTrackingEvent} invalidation * @param {boolean} showUnknownNodes */ _createInvalidationNode: function(invalidation, showUnknownNodes) { var node = (invalidation.nodeId && this._relatedNodesMap) ? this._relatedNodesMap.get(invalidation.nodeId) : null; if (node) return WebInspector.DOMPresentationUtils.linkifyNodeReference(node); if (invalidation.nodeName) { var nodeSpan = createElement("span"); nodeSpan.textContent = WebInspector.UIString("[ %s ]", invalidation.nodeName); return nodeSpan; } if (showUnknownNodes) { var nodeSpan = createElement("span"); return nodeSpan.createTextChild(WebInspector.UIString("[ unknown node ]")); } }, __proto__: TreeElement.prototype } /** * @param {!Object} total * @param {!WebInspector.TimelineModel} model * @param {!WebInspector.TracingModel.Event} event * @return {boolean} */ WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent = function(total, model, event) { var events = model.inspectedTargetEvents(); /** * @param {number} startTime * @param {!WebInspector.TracingModel.Event} e * @return {number} */ function eventComparator(startTime, e) { return startTime - e.startTime; } var index = events.binaryIndexOf(event.startTime, eventComparator); // Not a main thread event? if (index < 0) return false; var hasChildren = false; var endTime = event.endTime; if (endTime) { for (var i = index; i < events.length; i++) { var nextEvent = events[i]; if (nextEvent.startTime >= endTime) break; if (!nextEvent.selfTime) continue; if (nextEvent.thread !== event.thread) continue; if (i > index) hasChildren = true; var categoryName = WebInspector.TimelineUIUtils.eventStyle(nextEvent).category.name; total[categoryName] = (total[categoryName] || 0) + nextEvent.selfTime; } } if (WebInspector.TracingModel.isAsyncPhase(event.phase)) { if (event.endTime) { var aggregatedTotal = 0; for (var categoryName in total) aggregatedTotal += total[categoryName]; total["idle"] = Math.max(0, event.endTime - event.startTime - aggregatedTotal); } return false; } return hasChildren; } /** * @param {!WebInspector.TracingModel.Event} event * @param {!WebInspector.Target} target * @param {function(!Element=)} callback */ WebInspector.TimelineUIUtils.buildPicturePreviewContent = function(event, target, callback) { new WebInspector.LayerPaintEvent(event, target).loadSnapshot(onSnapshotLoaded); /** * @param {?Array.<number>} rect * @param {?WebInspector.PaintProfilerSnapshot} snapshot */ function onSnapshotLoaded(rect, snapshot) { if (!snapshot) { callback(); return; } snapshot.requestImage(null, null, 1, onGotImage); snapshot.dispose(); } /** * @param {string=} imageURL */ function onGotImage(imageURL) { if (!imageURL) { callback(); return; } var container = createElement("div"); container.classList.add("image-preview-container", "vbox", "link"); var img = container.createChild("img"); img.src = imageURL; var paintProfilerButton = container.createChild("a"); paintProfilerButton.textContent = WebInspector.UIString("Paint Profiler"); container.addEventListener("click", showPaintProfiler, false); callback(container); } function showPaintProfiler() { WebInspector.TimelinePanel.instance().select(WebInspector.TimelineSelection.fromTraceEvent(event), WebInspector.TimelinePanel.DetailsTab.PaintProfiler); } } /** * @param {!WebInspector.TimelineModel.RecordType} recordType * @param {?string} title * @param {number} position * @return {!Element} */ WebInspector.TimelineUIUtils.createEventDivider = function(recordType, title, position) { var eventDivider = createElement("div"); eventDivider.className = "resources-event-divider"; var recordTypes = WebInspector.TimelineModel.RecordType; if (recordType === recordTypes.MarkDOMContent) eventDivider.className += " resources-blue-divider"; else if (recordType === recordTypes.MarkLoad) eventDivider.className += " resources-red-divider"; else if (recordType === recordTypes.MarkFirstPaint) eventDivider.className += " resources-green-divider"; else if (recordType === recordTypes.TimeStamp || recordType === recordTypes.ConsoleTime || recordType === recordTypes.UserTiming) eventDivider.className += " resources-orange-divider"; else if (recordType === recordTypes.BeginFrame) eventDivider.className += " timeline-frame-divider"; if (title) eventDivider.title = title; eventDivider.style.left = position + "px"; return eventDivider; } /** * @param {!WebInspector.TimelineModel.Record} record * @param {number} zeroTime * @param {number} position * @return {!Element} */ WebInspector.TimelineUIUtils.createDividerForRecord = function(record, zeroTime, position) { var startTime = Number.millisToString(record.startTime() - zeroTime); var title = WebInspector.UIString("%s at %s", WebInspector.TimelineUIUtils.eventTitle(record.traceEvent()), startTime); return WebInspector.TimelineUIUtils.createEventDivider(record.type(), title, position); } /** * @return {!Array.<string>} */ WebInspector.TimelineUIUtils._visibleTypes = function() { var eventStyles = WebInspector.TimelineUIUtils._initEventStyles(); var result = []; for (var name in eventStyles) { if (!eventStyles[name].hidden) result.push(name); } return result; } /** * @return {!WebInspector.TimelineModel.Filter} */ WebInspector.TimelineUIUtils.visibleEventsFilter = function() { return new WebInspector.TimelineVisibleEventsFilter(WebInspector.TimelineUIUtils._visibleTypes()); } /** * @return {!Object.<string, !WebInspector.TimelineCategory>} */ WebInspector.TimelineUIUtils.categories = function() { if (WebInspector.TimelineUIUtils._categories) return WebInspector.TimelineUIUtils._categories; WebInspector.TimelineUIUtils._categories = { loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), true, "hsl(214, 67%, 74%)", "hsl(214, 67%, 66%)"), scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), true, "hsl(43, 83%, 72%)", "hsl(43, 83%, 64%) "), rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), true, "hsl(256, 67%, 76%)", "hsl(256, 67%, 70%)"), painting: new WebInspector.TimelineCategory("painting", WebInspector.UIString("Painting"), true, "hsl(109, 33%, 64%)", "hsl(109, 33%, 55%)"), gpu: new WebInspector.TimelineCategory("gpu", WebInspector.UIString("GPU"), false, "hsl(109, 33%, 64%)", "hsl(109, 33%, 55%)"), other: new WebInspector.TimelineCategory("other", WebInspector.UIString("Other"), false, "hsl(0, 0%, 87%)", "hsl(0, 0%, 79%)"), idle: new WebInspector.TimelineCategory("idle", WebInspector.UIString("Idle"), false, "hsl(0, 100%, 100%)", "hsl(0, 100%, 100%)") }; return WebInspector.TimelineUIUtils._categories; }; /** * @constructor * @param {string} title */ WebInspector.AsyncEventGroup = function(title) { this.title = title; } /** * @return {!Object<string, !WebInspector.AsyncEventGroup>} */ WebInspector.TimelineUIUtils.asyncEventGroups = function() { if (WebInspector.TimelineUIUtils._asyncEventGroups) return WebInspector.TimelineUIUtils._asyncEventGroups; WebInspector.TimelineUIUtils._asyncEventGroups = { animation: new WebInspector.AsyncEventGroup(WebInspector.UIString("Animation")), console: new WebInspector.AsyncEventGroup(WebInspector.UIString("Console")), userTiming: new WebInspector.AsyncEventGroup(WebInspector.UIString("User Timing")), input: new WebInspector.AsyncEventGroup(WebInspector.UIString("Input Events")) }; return WebInspector.TimelineUIUtils._asyncEventGroups; } /** * @param {!Object} aggregatedStats * @param {!WebInspector.TimelineCategory=} selfCategory * @param {number=} selfTime * @return {!Element} */ WebInspector.TimelineUIUtils.generatePieChart = function(aggregatedStats, selfCategory, selfTime) { var total = 0; for (var categoryName in aggregatedStats) total += aggregatedStats[categoryName]; var element = createElementWithClass("div", "timeline-details-view-pie-chart-wrapper hbox"); var pieChart = new WebInspector.PieChart(100); pieChart.element.classList.add("timeline-details-view-pie-chart"); pieChart.setTotal(total); var pieChartContainer = element.createChild("div", "vbox"); pieChartContainer.appendChild(pieChart.element); pieChartContainer.createChild("div", "timeline-details-view-pie-chart-total").textContent = WebInspector.UIString("Total: %s", Number.millisToString(total, true)); var footerElement = element.createChild("div", "timeline-aggregated-info-legend"); /** * @param {string} name * @param {string} title * @param {number} value * @param {string} color */ function appendLegendRow(name, title, value, color) { if (!value) return; pieChart.addSlice(value, color); var rowElement = footerElement.createChild("div"); rowElement.createChild("span", "timeline-aggregated-legend-value").textContent = Number.preciseMillisToString(value, 1); rowElement.createChild("span", "timeline-aggregated-legend-swatch").style.backgroundColor = color; rowElement.createChild("span", "timeline-aggregated-legend-title").textContent = title; } // In case of self time, first add self, then children of the same category. if (selfCategory) { if (selfTime) appendLegendRow(selfCategory.name, WebInspector.UIString("%s (self)", selfCategory.title), selfTime, selfCategory.color); // Children of the same category. var categoryTime = aggregatedStats[selfCategory.name]; var value = categoryTime - selfTime; if (value > 0) appendLegendRow(selfCategory.name, WebInspector.UIString("%s (children)", selfCategory.title), value, selfCategory.childColor); } // Add other categories. for (var categoryName in WebInspector.TimelineUIUtils.categories()) { var category = WebInspector.TimelineUIUtils.categories()[categoryName]; if (category === selfCategory) continue; appendLegendRow(category.name, category.title, aggregatedStats[category.name], category.childColor); } return element; } /** * @param {!WebInspector.TimelineFrameModelBase} frameModel * @param {!WebInspector.TimelineFrame} frame * @param {?WebInspector.FilmStripModel.Frame} filmStripFrame * @return {!Element} */ WebInspector.TimelineUIUtils.generateDetailsContentForFrame = function(frameModel, frame, filmStripFrame) { var pieChart = WebInspector.TimelineUIUtils.generatePieChart(frame.timeByCategory); var contentHelper = new WebInspector.TimelineDetailsContentHelper(null, null); contentHelper.addSection(WebInspector.UIString("Frame")); var duration = WebInspector.TimelineUIUtils.frameDuration(frame); contentHelper.appendElementRow(WebInspector.UIString("Duration"), duration, frame.hasWarnings()); if (filmStripFrame) { var filmStripPreview = createElementWithClass("img", "timeline-filmstrip-preview"); filmStripFrame.imageDataPromise().then(onGotImageData.bind(null, filmStripPreview)); contentHelper.appendElementRow("", filmStripPreview); filmStripPreview.addEventListener("click", frameClicked.bind(null, filmStripFrame), false); } var durationInMillis = frame.endTime - frame.startTime; contentHelper.appendTextRow(WebInspector.UIString("FPS"), Math.floor(1000 / durationInMillis)); contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.millisToString(frame.cpuTime, true)); if (Runtime.experiments.isEnabled("layersPanel") && frame.layerTree) { contentHelper.appendElementRow(WebInspector.UIString("Layer tree"), WebInspector.Linkifier.linkifyUsingRevealer(frame.layerTree, WebInspector.UIString("show"))); } /** * @param {!Element} image * @param {?string} data */ function onGotImageData(image, data) { if (data) image.src = "data:image/jpg;base64," + data; } /** * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame */ function frameClicked(filmStripFrame) { new WebInspector.FilmStripView.Dialog(filmStripFrame, 0); } return contentHelper.fragment; } /** * @param {!WebInspector.TimelineFrame} frame * @return {!Element} */ WebInspector.TimelineUIUtils.frameDuration = function(frame) { var durationText = WebInspector.UIString("%s (at %s)", Number.millisToString(frame.endTime - frame.startTime, true), Number.millisToString(frame.startTimeOffset, true)); var element = createElement("span"); element.createTextChild(durationText); if (!frame.hasWarnings()) return element; element.createTextChild(WebInspector.UIString(". Long frame times are an indication of ")); element.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/web/fundamentals/performance/rendering/", WebInspector.UIString("jank"), undefined, true)); element.createTextChild("."); return element; } /** * @param {!CanvasRenderingContext2D} context * @param {number} width * @param {number} height * @param {string} color0 * @param {string} color1 * @param {string} color2 * @return {!CanvasGradient} */ WebInspector.TimelineUIUtils.createFillStyle = function(context, width, height, color0, color1, color2) { var gradient = context.createLinearGradient(0, 0, width, height); gradient.addColorStop(0, color0); gradient.addColorStop(0.25, color1); gradient.addColorStop(0.75, color1); gradient.addColorStop(1, color2); return gradient; } /** * @param {!Array.<number>} quad * @return {number} */ WebInspector.TimelineUIUtils.quadWidth = function(quad) { return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1] - quad[3], 2))); } /** * @param {!Array.<number>} quad * @return {number} */ WebInspector.TimelineUIUtils.quadHeight = function(quad) { return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1] - quad[7], 2))); } /** * @constructor * @param {number} priority * @param {string} color * @param {!Array.<string>} eventTypes */ WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor = function(priority, color, eventTypes) { this.priority = priority; this.color = color; this.eventTypes = eventTypes; } /** * @return {!Array.<!WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor>} */ WebInspector.TimelineUIUtils.eventDispatchDesciptors = function() { if (WebInspector.TimelineUIUtils._eventDispatchDesciptors) return WebInspector.TimelineUIUtils._eventDispatchDesciptors; var lightOrange = "hsl(40,100%,80%)"; var orange = "hsl(40,100%,50%)"; var green = "hsl(90,100%,40%)"; var purple = "hsl(256,100%,75%)"; WebInspector.TimelineUIUtils._eventDispatchDesciptors = [ new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1, lightOrange, ["mousemove", "mouseenter", "mouseleave", "mouseout", "mouseover"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1, lightOrange, ["pointerover", "pointerout", "pointerenter", "pointerleave", "pointermove"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(2, green, ["wheel"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3, orange, ["click", "mousedown", "mouseup"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3, orange, ["touchstart", "touchend", "touchmove", "touchcancel"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3, orange, ["pointerdown", "pointerup", "pointercancel", "gotpointercapture", "lostpointercapture"]), new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3, purple, ["keydown", "keyup", "keypress"]) ]; return WebInspector.TimelineUIUtils._eventDispatchDesciptors; } /** * @constructor * @extends {WebInspector.Object} * @param {string} name * @param {string} title * @param {boolean} visible * @param {string} childColor * @param {string} color */ WebInspector.TimelineCategory = function(name, title, visible, childColor, color) { this.name = name; this.title = title; this.visible = visible; this.childColor = childColor; this.color = color; this.hidden = false; } WebInspector.TimelineCategory.Events = { VisibilityChanged: "VisibilityChanged" }; WebInspector.TimelineCategory.prototype = { /** * @return {boolean} */ get hidden() { return this._hidden; }, set hidden(hidden) { this._hidden = hidden; this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged, this); }, __proto__: WebInspector.Object.prototype } /** * @typedef {!{ * title: string, * color: string, * lineWidth: number, * dashStyle: !Array.<number>, * tall: boolean, * lowPriority: boolean * }} */ WebInspector.TimelineMarkerStyle; /** * @param {!WebInspector.TracingModel.Event} event * @return {!WebInspector.TimelineMarkerStyle} */ WebInspector.TimelineUIUtils.markerStyleForEvent = function(event) { var red = "rgb(255, 0, 0)"; var blue = "rgb(0, 0, 255)"; var orange = "rgb(255, 178, 23)"; var green = "rgb(0, 130, 0)"; var tallMarkerDashStyle = [10, 5]; var title = WebInspector.TimelineUIUtils.eventTitle(event) if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) { return { title: title, dashStyle: tallMarkerDashStyle, lineWidth: 0.5, color: orange, tall: false, lowPriority: false, }; } var recordTypes = WebInspector.TimelineModel.RecordType; var tall = false; var color = green; switch (event.name) { case recordTypes.MarkDOMContent: color = blue; tall = true; break; case recordTypes.MarkLoad: color = red; tall = true; break; case recordTypes.MarkFirstPaint: color = green; tall = true; break; case recordTypes.TimeStamp: color = orange; break; } return { title: title, dashStyle: tallMarkerDashStyle, lineWidth: 0.5, color: color, tall: tall, lowPriority: false, }; } /** * @return {!WebInspector.TimelineMarkerStyle} */ WebInspector.TimelineUIUtils.markerStyleForFrame = function() { return { title: WebInspector.UIString("Frame"), color: "rgba(100, 100, 100, 0.4)", lineWidth: 3, dashStyle: [3], tall: true, lowPriority: true }; } /** * @param {string} url * @return {string} */ WebInspector.TimelineUIUtils.colorForURL = function(url) { if (!WebInspector.TimelineUIUtils.colorForURL._colorGenerator) { WebInspector.TimelineUIUtils.colorForURL._colorGenerator = new WebInspector.FlameChart.ColorGenerator( { min: 30, max: 330 }, { min: 50, max: 80, count: 3 }, 85); } return WebInspector.TimelineUIUtils.colorForURL._colorGenerator.colorForID(url); } /** * @constructor * @param {string} title */ WebInspector.TimelinePopupContentHelper = function(title) { this._contentTable = createElement("table"); var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title"); titleCell.colSpan = 2; var titleRow = createElement("tr"); titleRow.appendChild(titleCell); this._contentTable.appendChild(titleRow); } WebInspector.TimelinePopupContentHelper.prototype = { /** * @return {!Element} */ contentTable: function() { return this._contentTable; }, /** * @param {string|number} content * @param {string=} styleName */ _createCell: function(content, styleName) { var text = createElement("label"); text.createTextChild(String(content)); var cell = createElement("td"); cell.className = "timeline-details"; if (styleName) cell.className += " " + styleName; cell.textContent = content; return cell; }, /** * @param {string} title * @param {string|number} content */ appendTextRow: function(title, content) { var row = createElement("tr"); row.appendChild(this._createCell(title, "timeline-details-row-title")); row.appendChild(this._createCell(content, "timeline-details-row-data")); this._contentTable.appendChild(row); }, /** * @param {string} title * @param {!Node|string} content */ appendElementRow: function(title, content) { var row = createElement("tr"); var titleCell = this._createCell(title, "timeline-details-row-title"); row.appendChild(titleCell); var cell = createElement("td"); cell.className = "details"; if (content instanceof Node) cell.appendChild(content); else cell.createTextChild(content || ""); row.appendChild(cell); this._contentTable.appendChild(row); } } /** * @constructor * @param {?WebInspector.Target} target * @param {?WebInspector.Linkifier} linkifier */ WebInspector.TimelineDetailsContentHelper = function(target, linkifier) { this.fragment = createDocumentFragment(); this._linkifier = linkifier; this._target = target; this.element = createElementWithClass("div", "timeline-details-view-block"); this._tableElement = this.element.createChild("div", "vbox timeline-details-chip-body"); this.fragment.appendChild(this.element); } WebInspector.TimelineDetailsContentHelper.prototype = { /** * @param {string} title * @param {!WebInspector.TimelineCategory=} category */ addSection: function(title, category) { if (!this._tableElement.hasChildNodes()) { this.element.removeChildren(); } else { this.element = createElementWithClass("div", "timeline-details-view-block"); this.fragment.appendChild(this.element); } if (title) { var titleElement = this.element.createChild("div", "timeline-details-chip-title"); if (category) titleElement.createChild("div").style.backgroundColor = category.color; titleElement.createTextChild(title); } this._tableElement = this.element.createChild("div", "vbox timeline-details-chip-body"); this.fragment.appendChild(this.element); }, /** * @return {?WebInspector.Linkifier} */ linkifier: function() { return this._linkifier; }, /** * @param {string} title * @param {string|number|boolean} value */ appendTextRow: function(title, value) { var rowElement = this._tableElement.createChild("div", "timeline-details-view-row"); rowElement.createChild("div", "timeline-details-view-row-title").textContent = title; rowElement.createChild("div", "timeline-details-view-row-value").textContent = value; }, /** * @param {string} title * @param {!Node|string} content * @param {boolean=} isWarning * @param {boolean=} isStacked */ appendElementRow: function(title, content, isWarning, isStacked) { var rowElement = this._tableElement.createChild("div", "timeline-details-view-row"); if (isWarning) rowElement.classList.add("timeline-details-warning"); if (isStacked) rowElement.classList.add("timeline-details-stack-values"); var titleElement = rowElement.createChild("div", "timeline-details-view-row-title"); titleElement.textContent = title; var valueElement = rowElement.createChild("div", "timeline-details-view-row-value"); if (content instanceof Node) valueElement.appendChild(content); else valueElement.createTextChild(content || ""); }, /** * @param {string} title * @param {string} url * @param {number} startLine * @param {number=} startColumn */ appendLocationRow: function(title, url, startLine, startColumn) { if (!this._linkifier || !this._target) return; if (startColumn) --startColumn; this.appendElementRow(title, this._linkifier.linkifyScriptLocation(this._target, null, url, startLine - 1, startColumn)); }, /** * @param {string} title * @param {string} url * @param {number} startLine * @param {number=} endLine */ appendLocationRange: function(title, url, startLine, endLine) { if (!this._linkifier || !this._target) return; var locationContent = createElement("span"); locationContent.appendChild(this._linkifier.linkifyScriptLocation(this._target, null, url, startLine - 1)); locationContent.createTextChild(String.sprintf(" [%s\u2026%s]", startLine, endLine || "")); this.appendElementRow(title, locationContent); }, /** * @param {string} title * @param {!RuntimeAgent.StackTrace} stackTrace */ appendStackTrace: function(title, stackTrace) { if (!this._linkifier || !this._target) return; var rowElement = this._tableElement.createChild("div", "timeline-details-view-row"); rowElement.createChild("div", "timeline-details-view-row-title").textContent = title; this.createChildStackTraceElement(rowElement, stackTrace); }, /** * @param {!Element} parentElement * @param {!RuntimeAgent.StackTrace} stackTrace */ createChildStackTraceElement: function(parentElement, stackTrace) { if (!this._linkifier || !this._target) return; parentElement.classList.add("timeline-details-stack-values"); var stackTraceElement = parentElement.createChild("div", "timeline-details-view-row-value timeline-details-view-row-stack-trace"); var callFrameElem = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(this._target, this._linkifier, stackTrace); stackTraceElement.appendChild(callFrameElem); }, /** * @param {!WebInspector.TracingModel.Event} event * @param {string=} warningType */ appendWarningRow: function(event, warningType) { var warning = WebInspector.TimelineUIUtils.eventWarning(event, warningType); if (warning) this.appendElementRow(WebInspector.UIString("Warning"), warning, true); } } /** * @param {!WebInspector.TracingModel.Event} event * @param {string=} warningType * @return {?Element} */ WebInspector.TimelineUIUtils.eventWarning = function(event, warningType) { var warning = warningType || event.warning; if (!warning) return null; var warnings = WebInspector.TimelineModel.WarningType; var span = createElement("span"); var eventData = event.args["data"]; switch (warning) { case warnings.ForcedStyle: case warnings.ForcedLayout: span.appendChild(WebInspector.linkifyDocumentationURLAsNode("../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts", WebInspector.UIString("Forced reflow"))); span.createTextChild(WebInspector.UIString(" is a likely performance bottleneck.")); break; case warnings.IdleDeadlineExceeded: span.textContent = WebInspector.UIString("Idle callback execution extended beyond deadline by " + Number.millisToString(event.duration - eventData["allottedMilliseconds"], true)); break; case warnings.V8Deopt: span.appendChild(WebInspector.linkifyURLAsNode("https://github.com/GoogleChrome/devtools-docs/issues/53", WebInspector.UIString("Not optimized"), undefined, true)); span.createTextChild(WebInspector.UIString(": %s", eventData["deoptReason"])); break; default: console.assert(false, "Unhandled TimelineModel.WarningType"); } return span; } /** * @constructor * @param {!WebInspector.DebuggerModel.Location} rawLocation * @param {number} time * @param {!WebInspector.LiveLocationPool} locationPool */ WebInspector.TimelineUIUtils.LineLevelProfilePresentation = function(rawLocation, time, locationPool) { this._time = time; WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this.updateLocation.bind(this), locationPool); } WebInspector.TimelineUIUtils.LineLevelProfilePresentation.prototype = { /** * @param {!WebInspector.LiveLocation} liveLocation */ updateLocation: function(liveLocation) { if (this._uiLocation) this._uiLocation.uiSourceCode.removeLineDecoration(this._uiLocation.lineNumber, WebInspector.TimelineUIUtils.PerformanceLineDecorator.type); this._uiLocation = liveLocation.uiLocation(); if (this._uiLocation) this._uiLocation.uiSourceCode.addLineDecoration(this._uiLocation.lineNumber, WebInspector.TimelineUIUtils.PerformanceLineDecorator.type, this._time); } } /** * @constructor * @implements {WebInspector.UISourceCodeFrame.LineDecorator} */ WebInspector.TimelineUIUtils.PerformanceLineDecorator = function() { } WebInspector.TimelineUIUtils.PerformanceLineDecorator.type = "performance"; WebInspector.TimelineUIUtils.PerformanceLineDecorator.prototype = { /** * @override * @param {!WebInspector.UISourceCode} uiSourceCode * @param {!WebInspector.CodeMirrorTextEditor} textEditor */ decorate: function(uiSourceCode, textEditor) { var type = WebInspector.TimelineUIUtils.PerformanceLineDecorator.type; var decorations = uiSourceCode.lineDecorations(type); textEditor.resetGutterDecorations(type); if (!decorations) return; for (var decoration of decorations.values()) { var time = /** @type {number} */ (decoration.data()); var text = WebInspector.UIString("%.1f\xa0ms", time); var intensity = Number.constrain(Math.log10(1 + 2 * time) / 5, 0.02, 1); var element = createElementWithClass("div", "text-editor-line-marker-performance"); element.textContent = text; element.style.backgroundColor = `hsla(44, 100%, 50%, ${intensity.toFixed(3)})`; textEditor.setGutterDecoration(decoration.line(), decoration.type(), element); } } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | 2 | /*
* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Element} element
* @param {boolean=} disableRotate
*/
WebInspector.TransformController = function(element, disableRotate)
{
this._shortcuts = {};
this.element = element;
if (this.element.tabIndex < 0)
this.element.tabIndex = 0;
this._registerShortcuts();
WebInspector.installDragHandle(element, this._onDragStart.bind(this), this._onDrag.bind(this), this._onDragEnd.bind(this), "move", null);
element.addEventListener("keydown", this._onKeyDown.bind(this), false);
element.addEventListener("keyup", this._onKeyUp.bind(this), false);
element.addEventListener("mousewheel", this._onMouseWheel.bind(this), false);
this._minScale = 0;
this._maxScale = Infinity;
this._controlPanelToolbar = new WebInspector.Toolbar("transform-control-panel");
/** @type {!Object<string, !WebInspector.ToolbarToggle>} */
this._modeButtons = {};
if (!disableRotate) {
var panModeButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Pan mode (X)"), "pan-toolbar-item");
panModeButton.addEventListener("click", this._setMode.bind(this, WebInspector.TransformController.Modes.Pan));
this._modeButtons[WebInspector.TransformController.Modes.Pan] = panModeButton;
this._controlPanelToolbar.appendToolbarItem(panModeButton);
var rotateModeButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Rotate mode (V)"), "rotate-toolbar-item");
rotateModeButton.addEventListener("click", this._setMode.bind(this, WebInspector.TransformController.Modes.Rotate));
this._modeButtons[WebInspector.TransformController.Modes.Rotate] = rotateModeButton;
this._controlPanelToolbar.appendToolbarItem(rotateModeButton);
}
this._setMode(WebInspector.TransformController.Modes.Pan);
var resetButton = new WebInspector.ToolbarButton(WebInspector.UIString("Reset transform (0)"), "center-toolbar-item");
resetButton.addEventListener("click", this.resetAndNotify.bind(this, undefined));
this._controlPanelToolbar.appendToolbarItem(resetButton);
this._reset();
}
/**
* @enum {string}
*/
WebInspector.TransformController.Events = {
TransformChanged: "TransformChanged"
}
/**
* @enum {string}
*/
WebInspector.TransformController.Modes = {
Pan: "Pan",
Rotate: "Rotate",
}
WebInspector.TransformController.prototype = {
/**
* @return {!WebInspector.Toolbar}
*/
toolbar: function()
{
return this._controlPanelToolbar;
},
_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Shift.code) {
this._toggleMode();
return;
}
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers(event);
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event))
event.consume();
},
_onKeyUp: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Shift.code)
this._toggleMode();
},
_addShortcuts: function(keys, handler)
{
for (var i = 0; i < keys.length; ++i)
this._shortcuts[keys[i].key] = handler;
},
_registerShortcuts: function()
{
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView, this.resetAndNotify.bind(this));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanMode, this._setMode.bind(this, WebInspector.TransformController.Modes.Pan));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateMode, this._setMode.bind(this, WebInspector.TransformController.Modes.Rotate));
var zoomFactor = 1.1;
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, this._onKeyboardZoom.bind(this, zoomFactor));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, this._onKeyboardZoom.bind(this, 1 / zoomFactor));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Up, this._onKeyboardPanOrRotate.bind(this, 0, -1));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Down, this._onKeyboardPanOrRotate.bind(this, 0, 1));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Left, this._onKeyboardPanOrRotate.bind(this, -1, 0));
this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Right, this._onKeyboardPanOrRotate.bind(this, 1, 0));
},
_postChangeEvent: function()
{
this.dispatchEventToListeners(WebInspector.TransformController.Events.TransformChanged);
},
_reset: function()
{
this._scale = 1;
this._offsetX = 0;
this._offsetY = 0;
this._rotateX = 0;
this._rotateY = 0;
},
_toggleMode: function()
{
this._setMode(this._mode === WebInspector.TransformController.Modes.Pan ? WebInspector.TransformController.Modes.Rotate : WebInspector.TransformController.Modes.Pan);
},
/**
* @param {!WebInspector.TransformController.Modes} mode
*/
_setMode: function(mode)
{
if (this._mode === mode)
return;
this._mode = mode;
this._updateModeButtons();
this.element.focus();
},
_updateModeButtons: function()
{
for (var mode in this._modeButtons)
this._modeButtons[mode].setToggled(mode === this._mode);
},
/**
* @param {!Event=} event
*/
resetAndNotify: function(event)
{
this._reset();
this._postChangeEvent();
if (event)
event.preventDefault();
this.element.focus();
},
/**
* @param {number} minScale
* @param {number} maxScale
*/
setScaleConstraints: function(minScale, maxScale)
{
this._minScale = minScale;
this._maxScale = maxScale;
this._scale = Number.constrain(this._scale, minScale, maxScale);
},
/**
* @param {number} minX
* @param {number} maxX
* @param {number} minY
* @param {number} maxY
*/
clampOffsets: function(minX, maxX, minY, maxY)
{
this._offsetX = Number.constrain(this._offsetX, minX, maxX);
this._offsetY = Number.constrain(this._offsetY, minY, maxY);
},
/**
* @return {number}
*/
scale: function()
{
return this._scale;
},
/**
* @return {number}
*/
offsetX: function()
{
return this._offsetX;
},
/**
* @return {number}
*/
offsetY: function()
{
return this._offsetY;
},
/**
* @return {number}
*/
rotateX: function()
{
return this._rotateX;
},
/**
* @return {number}
*/
rotateY: function()
{
return this._rotateY;
},
/**
* @param {number} scaleFactor
* @param {number} x
* @param {number} y
*/
_onScale: function(scaleFactor, x, y)
{
scaleFactor = Number.constrain(this._scale * scaleFactor, this._minScale, this._maxScale) / this._scale;
this._scale *= scaleFactor;
this._offsetX -= (x - this._offsetX) * (scaleFactor - 1);
this._offsetY -= (y - this._offsetY) * (scaleFactor - 1);
this._postChangeEvent();
},
/**
* @param {number} offsetX
* @param {number} offsetY
*/
_onPan: function(offsetX, offsetY)
{
this._offsetX += offsetX;
this._offsetY += offsetY;
this._postChangeEvent();
},
/**
* @param {number} rotateX
* @param {number} rotateY
*/
_onRotate: function(rotateX, rotateY)
{
this._rotateX = rotateX;
this._rotateY = rotateY;
this._postChangeEvent();
},
/**
* @param {number} zoomFactor
*/
_onKeyboardZoom: function(zoomFactor)
{
this._onScale(zoomFactor, this.element.clientWidth / 2, this.element.clientHeight / 2);
},
/**
* @param {number} xMultiplier
* @param {number} yMultiplier
*/
_onKeyboardPanOrRotate: function(xMultiplier, yMultiplier)
{
var panStepInPixels = 6;
var rotateStepInDegrees = 5;
if (this._mode === WebInspector.TransformController.Modes.Rotate) {
// Sic! _onRotate treats X and Y as "rotate around X" and "rotate around Y", so swap X/Y multiplers.
this._onRotate(this._rotateX + yMultiplier * rotateStepInDegrees, this._rotateY + xMultiplier * rotateStepInDegrees);
} else {
this._onPan(xMultiplier * panStepInPixels, yMultiplier * panStepInPixels);
}
},
/**
* @param {!Event} event
*/
_onMouseWheel: function(event)
{
/** @const */
var zoomFactor = 1.1;
/** @const */
var mouseWheelZoomSpeed = 1 / 120;
var scaleFactor = Math.pow(zoomFactor, event.wheelDeltaY * mouseWheelZoomSpeed);
this._onScale(scaleFactor, event.clientX - this.element.totalOffsetLeft(), event.clientY - this.element.totalOffsetTop());
},
/**
* @param {!Event} event
*/
_onDrag: function(event)
{
if (this._mode === WebInspector.TransformController.Modes.Rotate) {
this._onRotate(this._oldRotateX + (this._originY - event.clientY) / this.element.clientHeight * 180, this._oldRotateY - (this._originX - event.clientX) / this.element.clientWidth * 180);
} else {
this._onPan(event.clientX - this._originX, event.clientY - this._originY);
this._originX = event.clientX;
this._originY = event.clientY;
}
},
/**
* @param {!MouseEvent} event
*/
_onDragStart: function(event)
{
this.element.focus();
this._originX = event.clientX;
this._originY = event.clientY;
this._oldRotateX = this._rotateX;
this._oldRotateY = this._rotateY;
return true;
},
_onDragEnd: function()
{
delete this._originX;
delete this._originY;
delete this._oldRotateX;
delete this._oldRotateY;
},
__proto__: WebInspector.Object.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| LayerTreeModel.js | 2.19% | (7 / 320) | 0% | (0 / 130) | 0% | (0 / 124) | 2.19% | (7 / 319) | |
| TimelineFrameModel.js | 4.18% | (11 / 263) | 0% | (0 / 171) | 0% | (0 / 46) | 4.18% | (11 / 263) | |
| TimelineIRModel.js | 2.4% | (3 / 125) | 0% | (0 / 63) | 0% | (0 / 13) | 2.4% | (3 / 125) | |
| TimelineJSProfile.js | 5.96% | (13 / 218) | 0% | (0 / 93) | 0% | (0 / 29) | 5.99% | (13 / 217) | |
| TimelineModel.js | 0.84% | (6 / 711) | 0% | (0 / 436) | 0% | (0 / 90) | 0.85% | (6 / 705) | |
| TimelineProfileTree.js | 3.8% | (7 / 184) | 0% | (0 / 93) | 0% | (0 / 20) | 3.83% | (7 / 183) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @typedef {!{
bounds: {height: number, width: number},
children: Array.<!WebInspector.TracingLayerPayload>,
layer_id: number,
position: Array.<number>,
scroll_offset: Array.<number>,
layer_quad: Array.<number>,
draws_content: number,
gpu_memory_usage: number,
transform: Array.<number>,
owner_node: number,
compositing_reasons: Array.<string>
}}
*/
WebInspector.TracingLayerPayload;
/** @typedef {!{
id: string,
layer_id: number,
gpu_memory_usage: number,
content_rect: !Array.<number>
}}
*/
WebInspector.TracingLayerTile;
/**
* @constructor
* @extends {WebInspector.SDKModel}
*/
WebInspector.LayerTreeModel = function(target)
{
WebInspector.SDKModel.call(this, WebInspector.LayerTreeModel, target);
target.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
/** @type {?WebInspector.LayerTreeBase} */
this._layerTree = null;
}
WebInspector.LayerTreeModel.Events = {
LayerTreeChanged: "LayerTreeChanged",
LayerPainted: "LayerPainted",
}
WebInspector.LayerTreeModel.ScrollRectType = {
NonFastScrollable: {name: "NonFastScrollable", description: "Non fast scrollable"},
TouchEventHandler: {name: "TouchEventHandler", description: "Touch event handler"},
WheelEventHandler: {name: "WheelEventHandler", description: "Wheel event handler"},
RepaintsOnScroll: {name: "RepaintsOnScroll", description: "Repaints on scroll"}
}
WebInspector.LayerTreeModel.prototype = {
disable: function()
{
if (!this._enabled)
return;
this._enabled = false;
this._layerTree = null;
this.target().layerTreeAgent().disable();
},
enable: function()
{
if (this._enabled)
return;
this._enabled = true;
this._forceEnable();
},
_forceEnable: function()
{
this._layerTree = new WebInspector.AgentLayerTree(this.target());
this._lastPaintRectByLayerId = {};
this.target().layerTreeAgent().enable();
},
/**
* @param {!WebInspector.LayerTreeBase} layerTree
*/
setLayerTree: function(layerTree)
{
this.disable();
this._layerTree = layerTree;
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
},
/**
* @return {?WebInspector.LayerTreeBase}
*/
layerTree: function()
{
return this._layerTree;
},
/**
* @param {?Array.<!LayerTreeAgent.Layer>} layers
*/
_layerTreeChanged: function(layers)
{
if (!this._enabled)
return;
var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
layerTree.setLayers(layers, onLayersSet.bind(this));
/**
* @this {WebInspector.LayerTreeModel}
*/
function onLayersSet()
{
for (var layerId in this._lastPaintRectByLayerId) {
var lastPaintRect = this._lastPaintRectByLayerId[layerId];
var layer = layerTree.layerById(layerId);
if (layer)
layer._lastPaintRect = lastPaintRect;
}
this._lastPaintRectByLayerId = {};
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
}
},
/**
* @param {!LayerTreeAgent.LayerId} layerId
* @param {!DOMAgent.Rect} clipRect
*/
_layerPainted: function(layerId, clipRect)
{
if (!this._enabled)
return;
var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
var layer = layerTree.layerById(layerId);
if (!layer) {
this._lastPaintRectByLayerId[layerId] = clipRect;
return;
}
layer._didPaint(clipRect);
this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted, layer);
},
_onMainFrameNavigated: function()
{
if (this._enabled)
this._forceEnable();
},
__proto__: WebInspector.SDKModel.prototype
}
/**
* @constructor
* @param {?WebInspector.Target} target
*/
WebInspector.LayerTreeBase = function(target)
{
this._target = target;
this._domModel = target ? WebInspector.DOMModel.fromTarget(target) : null;
this._layersById = {};
/** @type Map<number, ?WebInspector.DOMNode> */
this._backendNodeIdToNode = new Map();
this._reset();
}
WebInspector.LayerTreeBase.prototype = {
_reset: function()
{
this._root = null;
this._contentRoot = null;
this._layers = null;
},
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
},
/**
* @return {?WebInspector.Layer}
*/
root: function()
{
return this._root;
},
/**
* @return {?WebInspector.Layer}
*/
contentRoot: function()
{
return this._contentRoot;
},
/**
* @return {!Array.<!WebInspector.Layer>}
*/
layers: function()
{
return this._layers;
},
/**
* @param {function(!WebInspector.Layer)} callback
* @param {?WebInspector.Layer=} root
* @return {boolean}
*/
forEachLayer: function(callback, root)
{
if (!root) {
root = this.root();
if (!root)
return false;
}
return callback(root) || root.children().some(this.forEachLayer.bind(this, callback));
},
/**
* @param {string} id
* @return {?WebInspector.Layer}
*/
layerById: function(id)
{
return this._layersById[id] || null;
},
/**
* @param {!Set<number>} requestedNodeIds
* @param {function()} callback
*/
_resolveBackendNodeIds: function(requestedNodeIds, callback)
{
if (!requestedNodeIds.size || !this._domModel) {
callback();
return;
}
if (this._domModel)
this._domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds, populateBackendNodeMap.bind(this));
/**
* @this {WebInspector.LayerTreeBase}
* @param {?Map<number, ?WebInspector.DOMNode>} nodesMap
*/
function populateBackendNodeMap(nodesMap)
{
if (nodesMap) {
for (var nodeId of nodesMap.keysArray())
this._backendNodeIdToNode.set(nodeId, nodesMap.get(nodeId) || null);
}
callback();
}
},
/**
* @param {!Object} viewportSize
*/
setViewportSize: function(viewportSize)
{
this._viewportSize = viewportSize;
},
/**
* @return {!Object | undefined}
*/
viewportSize: function()
{
return this._viewportSize;
},
/**
* @param {number} id
* @return {?WebInspector.DOMNode}
*/
_nodeForId: function(id)
{
return this._domModel ? this._domModel.nodeForId(id) : null;
}
}
/**
* @constructor
* @extends {WebInspector.LayerTreeBase}
* @param {?WebInspector.Target} target
*/
WebInspector.TracingLayerTree = function(target)
{
WebInspector.LayerTreeBase.call(this, target);
/** @type {!Map.<string, !WebInspector.TracingLayerTile>} */
this._tileById = new Map();
}
WebInspector.TracingLayerTree.prototype = {
/**
* @param {!WebInspector.TracingLayerPayload} root
* @param {?Array.<!WebInspector.TracingLayerPayload>} layers
* @param {function()} callback
*/
setLayers: function(root, layers, callback)
{
var idsToResolve = new Set();
if (root) {
// This is a legacy code path for compatibility, as cc is removing
// layer tree hierarchy, this code will eventually be removed.
this._extractNodeIdsToResolve(idsToResolve, {}, root);
} else {
for (var i = 0; i < layers.length; ++i)
this._extractNodeIdsToResolve(idsToResolve, {}, layers[i]);
}
this._resolveBackendNodeIds(idsToResolve, onBackendNodeIdsResolved.bind(this));
/**
* @this {WebInspector.TracingLayerTree}
*/
function onBackendNodeIdsResolved()
{
var oldLayersById = this._layersById;
this._layersById = {};
this._contentRoot = null;
if (root) {
this._root = this._innerSetLayers(oldLayersById, root);
} else {
this._layers = layers.map(this._innerSetLayers.bind(this, oldLayersById));
this._root = this._contentRoot;
for (var i = 0; i < this._layers.length; ++i) {
if (this._layers[i].id() !== this._contentRoot.id()) {
this._contentRoot.addChild(this._layers[i]);
}
}
}
callback();
}
},
/**
* @param {!Array.<!WebInspector.TracingLayerTile>} tiles
*/
setTiles: function(tiles)
{
this._tileById = new Map();
for (var tile of tiles)
this._tileById.set(tile.id, tile);
},
/**
* @param {string} id
* @return {?WebInspector.TracingLayerTile}
*/
tileById: function(id)
{
return this._tileById.get(id) || null;
},
/**
* @param {!Object.<(string|number), !WebInspector.Layer>} oldLayersById
* @param {!WebInspector.TracingLayerPayload} payload
* @return {!WebInspector.TracingLayer}
*/
_innerSetLayers: function(oldLayersById, payload)
{
var layer = /** @type {?WebInspector.TracingLayer} */ (oldLayersById[payload.layer_id]);
if (layer)
layer._reset(payload);
else
layer = new WebInspector.TracingLayer(payload);
this._layersById[payload.layer_id] = layer;
if (payload.owner_node)
layer._setNode(this._backendNodeIdToNode.get(payload.owner_node) || null);
if (!this._contentRoot && layer.drawsContent())
this._contentRoot = layer;
for (var i = 0; payload.children && i < payload.children.length; ++i)
layer.addChild(this._innerSetLayers(oldLayersById, payload.children[i]));
return layer;
},
/**
* @param {!Set<number>} nodeIdsToResolve
* @param {!Object} seenNodeIds
* @param {!WebInspector.TracingLayerPayload} payload
*/
_extractNodeIdsToResolve: function(nodeIdsToResolve, seenNodeIds, payload)
{
var backendNodeId = payload.owner_node;
if (backendNodeId && !this._backendNodeIdToNode.has(backendNodeId))
nodeIdsToResolve.add(backendNodeId);
for (var i = 0; payload.children && i < payload.children.length; ++i)
this._extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload.children[i]);
},
__proto__: WebInspector.LayerTreeBase.prototype
}
/**
* @constructor
* @param {?WebInspector.Target} target
* @extends {WebInspector.LayerTreeBase}
*/
WebInspector.AgentLayerTree = function(target)
{
WebInspector.LayerTreeBase.call(this, target);
}
WebInspector.AgentLayerTree.prototype = {
/**
* @param {?Array.<!LayerTreeAgent.Layer>} payload
* @param {function()} callback
*/
setLayers: function(payload, callback)
{
if (!payload) {
onBackendNodeIdsResolved.call(this);
return;
}
var idsToResolve = new Set();
for (var i = 0; i < payload.length; ++i) {
var backendNodeId = payload[i].backendNodeId;
if (!backendNodeId || this._backendNodeIdToNode.has(backendNodeId))
continue;
idsToResolve.add(backendNodeId);
}
this._resolveBackendNodeIds(idsToResolve, onBackendNodeIdsResolved.bind(this));
/**
* @this {WebInspector.AgentLayerTree}
*/
function onBackendNodeIdsResolved()
{
this._innerSetLayers(payload);
callback();
}
},
/**
* @param {?Array.<!LayerTreeAgent.Layer>} layers
*/
_innerSetLayers: function(layers)
{
this._reset();
// Payload will be null when not in the composited mode.
if (!layers)
return;
var oldLayersById = this._layersById;
this._layersById = {};
for (var i = 0; i < layers.length; ++i) {
var layerId = layers[i].layerId;
var layer = oldLayersById[layerId];
if (layer)
layer._reset(layers[i]);
else
layer = new WebInspector.AgentLayer(this._target, layers[i]);
this._layersById[layerId] = layer;
var backendNodeId = layers[i].backendNodeId;
if (backendNodeId)
layer._setNode(this._backendNodeIdToNode.get(backendNodeId));
if (!this._contentRoot && layer.drawsContent())
this._contentRoot = layer;
var parentId = layer.parentId();
if (parentId) {
var parent = this._layersById[parentId];
if (!parent)
console.assert(parent, "missing parent " + parentId + " for layer " + layerId);
parent.addChild(layer);
} else {
if (this._root)
console.assert(false, "Multiple root layers");
this._root = layer;
}
}
if (this._root)
this._root._calculateQuad(new WebKitCSSMatrix());
},
__proto__: WebInspector.LayerTreeBase.prototype
}
/**
* @interface
*/
WebInspector.Layer = function()
{
}
WebInspector.Layer.prototype = {
/**
* @return {string}
*/
id: function() { },
/**
* @return {?string}
*/
parentId: function() { },
/**
* @return {?WebInspector.Layer}
*/
parent: function() { },
/**
* @return {boolean}
*/
isRoot: function() { },
/**
* @return {!Array.<!WebInspector.Layer>}
*/
children: function() { },
/**
* @param {!WebInspector.Layer} child
*/
addChild: function(child) { },
/**
* @return {?WebInspector.DOMNode}
*/
node: function() { },
/**
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function() { },
/**
* @return {number}
*/
offsetX: function() { },
/**
* @return {number}
*/
offsetY: function() { },
/**
* @return {number}
*/
width: function() { },
/**
* @return {number}
*/
height: function() { },
/**
* @return {?Array.<number>}
*/
transform: function() { },
/**
* @return {!Array.<number>}
*/
quad: function() { },
/**
* @return {!Array.<number>}
*/
anchorPoint: function() { },
/**
* @return {boolean}
*/
invisible: function() { },
/**
* @return {number}
*/
paintCount: function() { },
/**
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function() { },
/**
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function() { },
/**
* @return {number}
*/
gpuMemoryUsage: function() { },
/**
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback) { },
/**
* @return {boolean}
*/
drawsContent: function() { }
}
/**
* @constructor
* @implements {WebInspector.Layer}
* @param {?WebInspector.Target} target
* @param {!LayerTreeAgent.Layer} layerPayload
*/
WebInspector.AgentLayer = function(target, layerPayload)
{
this._target = target;
this._reset(layerPayload);
}
WebInspector.AgentLayer.prototype = {
/**
* @override
* @return {string}
*/
id: function()
{
return this._layerPayload.layerId;
},
/**
* @override
* @return {?string}
*/
parentId: function()
{
return this._layerPayload.parentLayerId;
},
/**
* @override
* @return {?WebInspector.Layer}
*/
parent: function()
{
return this._parent;
},
/**
* @override
* @return {boolean}
*/
isRoot: function()
{
return !this.parentId();
},
/**
* @override
* @return {!Array.<!WebInspector.Layer>}
*/
children: function()
{
return this._children;
},
/**
* @override
* @param {!WebInspector.Layer} child
*/
addChild: function(child)
{
if (child._parent)
console.assert(false, "Child already has a parent");
this._children.push(child);
child._parent = this;
},
/**
* @param {?WebInspector.DOMNode} node
*/
_setNode: function(node)
{
this._node = node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function()
{
for (var layer = this; layer; layer = layer._parent) {
if (layer._node)
return layer._node;
}
return null;
},
/**
* @override
* @return {number}
*/
offsetX: function()
{
return this._layerPayload.offsetX;
},
/**
* @override
* @return {number}
*/
offsetY: function()
{
return this._layerPayload.offsetY;
},
/**
* @override
* @return {number}
*/
width: function()
{
return this._layerPayload.width;
},
/**
* @override
* @return {number}
*/
height: function()
{
return this._layerPayload.height;
},
/**
* @override
* @return {?Array.<number>}
*/
transform: function()
{
return this._layerPayload.transform;
},
/**
* @override
* @return {!Array.<number>}
*/
quad: function()
{
return this._quad;
},
/**
* @override
* @return {!Array.<number>}
*/
anchorPoint: function()
{
return [
this._layerPayload.anchorX || 0,
this._layerPayload.anchorY || 0,
this._layerPayload.anchorZ || 0,
];
},
/**
* @override
* @return {boolean}
*/
invisible: function()
{
return this._layerPayload.invisible;
},
/**
* @override
* @return {number}
*/
paintCount: function()
{
return this._paintCount || this._layerPayload.paintCount;
},
/**
* @override
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function()
{
return this._lastPaintRect;
},
/**
* @override
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function()
{
return this._scrollRects;
},
/**
* @override
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback)
{
if (!this._target) {
callback([]);
return;
}
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.reasonsForCompositingLayer(): ", undefined, []);
this._target.layerTreeAgent().compositingReasons(this.id(), wrappedCallback);
},
/**
* @override
* @return {boolean}
*/
drawsContent: function()
{
return this._layerPayload.drawsContent;
},
/**
* @override
* @return {number}
*/
gpuMemoryUsage: function()
{
/**
* @const
*/
var bytesPerPixel = 4;
return this.drawsContent() ? this.width() * this.height() * bytesPerPixel : 0;
},
/**
* @param {function(!WebInspector.PaintProfilerSnapshot=)} callback
*/
requestSnapshot: function(callback)
{
if (!this._target) {
callback();
return;
}
var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.makeSnapshot(): ", WebInspector.PaintProfilerSnapshot.bind(null, this._target));
this._target.layerTreeAgent().makeSnapshot(this.id(), wrappedCallback);
},
/**
* @param {!DOMAgent.Rect} rect
*/
_didPaint: function(rect)
{
this._lastPaintRect = rect;
this._paintCount = this.paintCount() + 1;
this._image = null;
},
/**
* @param {!LayerTreeAgent.Layer} layerPayload
*/
_reset: function(layerPayload)
{
/** @type {?WebInspector.DOMNode} */
this._node = null;
this._children = [];
this._parent = null;
this._paintCount = 0;
this._layerPayload = layerPayload;
this._image = null;
this._scrollRects = this._layerPayload.scrollRects || [];
},
/**
* @param {!Array.<number>} a
* @return {!CSSMatrix}
*/
_matrixFromArray: function(a)
{
function toFixed9(x) { return x.toFixed(9); }
return new WebKitCSSMatrix("matrix3d(" + a.map(toFixed9).join(",") + ")");
},
/**
* @param {!CSSMatrix} parentTransform
* @return {!CSSMatrix}
*/
_calculateTransformToViewport: function(parentTransform)
{
var offsetMatrix = new WebKitCSSMatrix().translate(this._layerPayload.offsetX, this._layerPayload.offsetY);
var matrix = offsetMatrix;
if (this._layerPayload.transform) {
var transformMatrix = this._matrixFromArray(this._layerPayload.transform);
var anchorVector = new WebInspector.Geometry.Vector(this._layerPayload.width * this.anchorPoint()[0], this._layerPayload.height * this.anchorPoint()[1], this.anchorPoint()[2]);
var anchorPoint = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
var anchorMatrix = new WebKitCSSMatrix().translate(-anchorPoint.x, -anchorPoint.y, -anchorPoint.z);
matrix = anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
}
matrix = parentTransform.multiply(matrix);
return matrix;
},
/**
* @param {number} width
* @param {number} height
* @return {!Array.<number>}
*/
_createVertexArrayForRect: function(width, height)
{
return [0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0];
},
/**
* @param {!CSSMatrix} parentTransform
*/
_calculateQuad: function(parentTransform)
{
var matrix = this._calculateTransformToViewport(parentTransform);
this._quad = [];
var vertices = this._createVertexArrayForRect(this._layerPayload.width, this._layerPayload.height);
for (var i = 0; i < 4; ++i) {
var point = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
this._quad.push(point.x, point.y);
}
function calculateQuadForLayer(layer)
{
layer._calculateQuad(matrix);
}
this._children.forEach(calculateQuadForLayer);
}
}
/**
* @constructor
* @param {!WebInspector.TracingLayerPayload} payload
* @implements {WebInspector.Layer}
*/
WebInspector.TracingLayer = function(payload)
{
this._reset(payload);
}
WebInspector.TracingLayer.prototype = {
/**
* @param {!WebInspector.TracingLayerPayload} payload
*/
_reset: function(payload)
{
/** @type {?WebInspector.DOMNode} */
this._node = null;
this._layerId = String(payload.layer_id);
this._offsetX = payload.position[0];
this._offsetY = payload.position[1];
this._width = payload.bounds.width;
this._height = payload.bounds.height;
this._children = [];
this._parentLayerId = null;
this._parent = null;
this._quad = payload.layer_quad || [];
this._createScrollRects(payload);
this._compositingReasons = payload.compositing_reasons || [];
this._drawsContent = !!payload.draws_content;
this._gpuMemoryUsage = payload.gpu_memory_usage;
},
/**
* @override
* @return {string}
*/
id: function()
{
return this._layerId;
},
/**
* @override
* @return {?string}
*/
parentId: function()
{
return this._parentLayerId;
},
/**
* @override
* @return {?WebInspector.Layer}
*/
parent: function()
{
return this._parent;
},
/**
* @override
* @return {boolean}
*/
isRoot: function()
{
return !this.parentId();
},
/**
* @override
* @return {!Array.<!WebInspector.Layer>}
*/
children: function()
{
return this._children;
},
/**
* @override
* @param {!WebInspector.Layer} child
*/
addChild: function(child)
{
if (child._parent)
console.assert(false, "Child already has a parent");
this._children.push(child);
child._parent = this;
child._parentLayerId = this._layerId;
},
/**
* @param {?WebInspector.DOMNode} node
*/
_setNode: function(node)
{
this._node = node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
node: function()
{
return this._node;
},
/**
* @override
* @return {?WebInspector.DOMNode}
*/
nodeForSelfOrAncestor: function()
{
for (var layer = this; layer; layer = layer._parent) {
if (layer._node)
return layer._node;
}
return null;
},
/**
* @override
* @return {number}
*/
offsetX: function()
{
return this._offsetX;
},
/**
* @override
* @return {number}
*/
offsetY: function()
{
return this._offsetY;
},
/**
* @override
* @return {number}
*/
width: function()
{
return this._width;
},
/**
* @override
* @return {number}
*/
height: function()
{
return this._height;
},
/**
* @override
* @return {?Array.<number>}
*/
transform: function()
{
return null;
},
/**
* @override
* @return {!Array.<number>}
*/
quad: function()
{
return this._quad;
},
/**
* @override
* @return {!Array.<number>}
*/
anchorPoint: function()
{
return [0.5, 0.5, 0];
},
/**
* @override
* @return {boolean}
*/
invisible: function()
{
return false;
},
/**
* @override
* @return {number}
*/
paintCount: function()
{
return 0;
},
/**
* @override
* @return {?DOMAgent.Rect}
*/
lastPaintRect: function()
{
return null;
},
/**
* @override
* @return {!Array.<!LayerTreeAgent.ScrollRect>}
*/
scrollRects: function()
{
return this._scrollRects;
},
/**
* @override
* @return {number}
*/
gpuMemoryUsage: function()
{
return this._gpuMemoryUsage;
},
/**
* @param {!Array.<number>} params
* @param {string} type
* @return {!Object}
*/
_scrollRectsFromParams: function(params, type)
{
return {rect: {x: params[0], y: params[1], width: params[2], height: params[3]}, type: type};
},
/**
* @param {!WebInspector.TracingLayerPayload} payload
*/
_createScrollRects: function(payload)
{
this._scrollRects = [];
if (payload.non_fast_scrollable_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region, WebInspector.LayerTreeModel.ScrollRectType.NonFastScrollable.name));
if (payload.touch_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.TouchEventHandler.name));
if (payload.wheel_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.WheelEventHandler.name));
if (payload.scroll_event_handler_region)
this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.RepaintsOnScroll.name));
},
/**
* @override
* @param {function(!Array.<string>)} callback
*/
requestCompositingReasons: function(callback)
{
callback(this._compositingReasons);
},
/**
* @override
* @return {boolean}
*/
drawsContent: function()
{
return this._drawsContent;
}
}
/**
* @constructor
* @param {?WebInspector.Target} target
*/
WebInspector.DeferredLayerTree = function(target)
{
this._target = target;
}
WebInspector.DeferredLayerTree.prototype = {
/**
* @param {function(!WebInspector.LayerTreeBase)} callback
*/
resolve: function(callback) { },
/**
* @return {?WebInspector.Target}
*/
target: function()
{
return this._target;
}
};
/**
* @constructor
* @implements {LayerTreeAgent.Dispatcher}
* @param {!WebInspector.LayerTreeModel} layerTreeModel
*/
WebInspector.LayerTreeDispatcher = function(layerTreeModel)
{
this._layerTreeModel = layerTreeModel;
}
WebInspector.LayerTreeDispatcher.prototype = {
/**
* @override
* @param {!Array.<!LayerTreeAgent.Layer>=} layers
*/
layerTreeDidChange: function(layers)
{
this._layerTreeModel._layerTreeChanged(layers || null);
},
/**
* @override
* @param {!LayerTreeAgent.LayerId} layerId
* @param {!DOMAgent.Rect} clipRect
*/
layerPainted: function(layerId, clipRect)
{
this._layerTreeModel._layerPainted(layerId, clipRect);
}
}
/**
* @param {!WebInspector.Target} target
* @return {?WebInspector.LayerTreeModel}
*/
WebInspector.LayerTreeModel.fromTarget = function(target)
{
if (!target.isPage())
return null;
var model = /** @type {?WebInspector.LayerTreeModel} */ (target.model(WebInspector.LayerTreeModel));
if (!model)
model = new WebInspector.LayerTreeModel(target);
return model;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | 2 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
*/
WebInspector.TimelineFrameModel = function(categoryMapper)
{
this._categoryMapper = categoryMapper;
this.reset();
}
WebInspector.TimelineFrameModel._mainFrameMarkers = [
WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation,
WebInspector.TimelineModel.RecordType.InvalidateLayout,
WebInspector.TimelineModel.RecordType.BeginMainThreadFrame,
WebInspector.TimelineModel.RecordType.ScrollLayer
];
WebInspector.TimelineFrameModel.prototype = {
/**
* @return {!Array.<!WebInspector.TimelineFrame>}
*/
frames: function()
{
return this._frames;
},
/**
* @param {number} startTime
* @param {number} endTime
* @return {!Array.<!WebInspector.TimelineFrame>}
*/
filteredFrames: function(startTime, endTime)
{
/**
* @param {number} value
* @param {!WebInspector.TimelineFrame} object
* @return {number}
*/
function compareStartTime(value, object)
{
return value - object.startTime;
}
/**
* @param {number} value
* @param {!WebInspector.TimelineFrame} object
* @return {number}
*/
function compareEndTime(value, object)
{
return value - object.endTime;
}
var frames = this._frames;
var firstFrame = frames.lowerBound(startTime, compareEndTime);
var lastFrame = frames.lowerBound(endTime, compareStartTime);
return frames.slice(firstFrame, lastFrame);
},
/**
* @param {!WebInspector.TracingModel.Event} rasterTask
* @return {boolean}
*/
hasRasterTile: function(rasterTask)
{
var data = rasterTask.args["tileData"];
if (!data)
return false;
var frameId = data["sourceFrameNumber"];
var frame = frameId && this._frameById[frameId];
if (!frame || !frame.layerTree)
return false;
return true;
},
/**
* @param {!WebInspector.TracingModel.Event} rasterTask
* @param {function(?DOMAgent.Rect, ?WebInspector.PaintProfilerSnapshot)} callback
*/
requestRasterTile: function(rasterTask, callback)
{
var target = this._target;
if (!target) {
callback(null, null);
return;
}
var data = rasterTask.args["tileData"];
var frameId = data["sourceFrameNumber"];
var frame = frameId && this._frameById[frameId];
if (!frame || !frame.layerTree) {
callback(null, null);
return;
}
var tileId = data["tileId"] && data["tileId"]["id_ref"];
/** @type {!Array.<!WebInspector.PictureFragment>}> */
var fragments = [];
/** @type {?WebInspector.TracingLayerTile} */
var tile = null;
var x0 = Infinity;
var y0 = Infinity;
frame.layerTree.resolve(layerTreeResolved);
/**
* @param {!WebInspector.LayerTreeBase} layerTree
*/
function layerTreeResolved(layerTree)
{
tile = tileId && (/** @type {!WebInspector.TracingLayerTree} */ (layerTree)).tileById("cc::Tile/" + tileId);
if (!tile) {
console.error("Tile " + tileId + " missing in frame " + frameId);
callback(null, null);
return;
}
var fetchPictureFragmentsBarrier = new CallbackBarrier();
for (var paint of frame.paints) {
if (tile.layer_id === paint.layerId())
paint.loadPicture(fetchPictureFragmentsBarrier.createCallback(pictureLoaded));
}
fetchPictureFragmentsBarrier.callWhenDone(allPicturesLoaded);
}
/**
* @param {number} a1
* @param {number} a2
* @param {number} b1
* @param {number} b2
* @return {boolean}
*/
function segmentsOverlap(a1, a2, b1, b2)
{
console.assert(a1 <= a2 && b1 <= b2, "segments should be specified as ordered pairs");
return a2 > b1 && a1 < b2;
}
/**
* @param {!Array.<number>} a
* @param {!Array.<number>} b
* @return {boolean}
*/
function rectsOverlap(a, b)
{
return segmentsOverlap(a[0], a[0] + a[2], b[0], b[0] + b[2]) && segmentsOverlap(a[1], a[1] + a[3], b[1], b[1] + b[3]);
}
/**
* @param {?Array.<number>} rect
* @param {?string} picture
*/
function pictureLoaded(rect, picture)
{
if (!rect || !picture)
return;
if (!rectsOverlap(rect, tile.content_rect))
return;
var x = rect[0];
var y = rect[1];
x0 = Math.min(x0, x);
y0 = Math.min(y0, y);
fragments.push({x: x, y: y, picture: picture});
}
function allPicturesLoaded()
{
if (!fragments.length) {
callback(null, null);
return;
}
var rectArray = tile.content_rect;
// Rect is in layer content coordinates, make it relative to picture by offsetting to the top left corner.
var rect = {x: rectArray[0] - x0, y: rectArray[1] - y0, width: rectArray[2], height: rectArray[3]};
WebInspector.PaintProfilerSnapshot.loadFromFragments(target, fragments, callback.bind(null, rect));
}
},
reset: function()
{
this._minimumRecordTime = Infinity;
this._frames = [];
this._frameById = {};
this._lastFrame = null;
this._lastLayerTree = null;
this._mainFrameCommitted = false;
this._mainFrameRequested = false;
this._framePendingCommit = null;
this._lastBeginFrame = null;
this._lastNeedsBeginFrame = null;
this._framePendingActivation = null;
this._lastTaskBeginTime = null;
this._target = null;
this._sessionId = null;
this._currentTaskTimeByCategory = {};
},
/**
* @param {number} startTime
*/
handleBeginFrame: function(startTime)
{
if (!this._lastFrame)
this._startFrame(startTime);
this._lastBeginFrame = startTime;
},
/**
* @param {number} startTime
*/
handleDrawFrame: function(startTime)
{
if (!this._lastFrame) {
this._startFrame(startTime);
return;
}
// - if it wasn't drawn, it didn't happen!
// - only show frames that either did not wait for the main thread frame or had one committed.
if (this._mainFrameCommitted || !this._mainFrameRequested) {
if (this._lastNeedsBeginFrame) {
var idleTimeEnd = this._framePendingActivation ? this._framePendingActivation.triggerTime : (this._lastBeginFrame || this._lastNeedsBeginFrame);
if (idleTimeEnd > this._lastFrame.startTime) {
this._lastFrame.idle = true;
this._startFrame(idleTimeEnd);
if (this._framePendingActivation)
this._commitPendingFrame();
this._lastBeginFrame = null;
}
this._lastNeedsBeginFrame = null;
}
this._startFrame(startTime);
}
this._mainFrameCommitted = false;
},
handleActivateLayerTree: function()
{
if (!this._lastFrame)
return;
if (this._framePendingActivation && !this._lastNeedsBeginFrame)
this._commitPendingFrame();
},
handleRequestMainThreadFrame: function()
{
if (!this._lastFrame)
return;
this._mainFrameRequested = true;
},
handleCompositeLayers: function()
{
if (!this._framePendingCommit)
return;
this._framePendingActivation = this._framePendingCommit;
this._framePendingCommit = null;
this._mainFrameRequested = false;
this._mainFrameCommitted = true;
},
/**
* @param {!WebInspector.DeferredLayerTree} layerTree
*/
handleLayerTreeSnapshot: function(layerTree)
{
this._lastLayerTree = layerTree;
},
/**
* @param {number} startTime
* @param {boolean} needsBeginFrame
*/
handleNeedFrameChanged: function(startTime, needsBeginFrame)
{
if (needsBeginFrame)
this._lastNeedsBeginFrame = startTime;
},
/**
* @param {number} startTime
*/
_startFrame: function(startTime)
{
if (this._lastFrame)
this._flushFrame(this._lastFrame, startTime);
this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this._minimumRecordTime);
},
/**
* @param {!WebInspector.TimelineFrame} frame
* @param {number} endTime
*/
_flushFrame: function(frame, endTime)
{
frame._setLayerTree(this._lastLayerTree);
frame._setEndTime(endTime);
if (this._frames.length && (frame.startTime !== this._frames.peekLast().endTime || frame.startTime > frame.endTime))
console.assert(false, `Inconsistent frame time for frame ${this._frames.length} (${frame.startTime} - ${frame.endTime})`);
this._frames.push(frame);
if (typeof frame._mainFrameId === "number")
this._frameById[frame._mainFrameId] = frame;
},
_commitPendingFrame: function()
{
this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCategory);
this._lastFrame.paints = this._framePendingActivation.paints;
this._lastFrame._mainFrameId = this._framePendingActivation.mainFrameId;
this._framePendingActivation = null;
},
/**
* @param {!Array.<string>} types
* @param {!WebInspector.TimelineModel.Record} record
* @return {?WebInspector.TimelineModel.Record} record
*/
_findRecordRecursively: function(types, record)
{
if (types.indexOf(record.type()) >= 0)
return record;
if (!record.children())
return null;
for (var i = 0; i < record.children().length; ++i) {
var result = this._findRecordRecursively(types, record.children()[i]);
if (result)
return result;
}
return null;
},
/**
* @param {?WebInspector.Target} target
* @param {!Array.<!WebInspector.TracingModel.Event>} events
* @param {string} sessionId
*/
addTraceEvents: function(target, events, sessionId)
{
this._target = target;
this._sessionId = sessionId;
if (!events.length)
return;
if (events[0].startTime < this._minimumRecordTime)
this._minimumRecordTime = events[0].startTime;
for (var i = 0; i < events.length; ++i)
this._addTraceEvent(events[i]);
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_addTraceEvent: function(event)
{
var eventNames = WebInspector.TimelineModel.RecordType;
if (event.name === eventNames.SetLayerTreeId) {
var sessionId = event.args["sessionId"] || event.args["data"]["sessionId"];
if (this._sessionId === sessionId)
this._layerTreeId = event.args["layerTreeId"] || event.args["data"]["layerTreeId"];
} else if (event.name === eventNames.TracingStartedInPage) {
this._mainThread = event.thread;
} else if (event.phase === WebInspector.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0) === this._layerTreeId) {
var snapshot = /** @type {!WebInspector.TracingModel.ObjectSnapshot} */ (event);
this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(snapshot, this._target));
} else {
this._processCompositorEvents(event);
if (event.thread === this._mainThread)
this._addMainThreadTraceEvent(event);
else if (this._lastFrame && event.selfTime && !WebInspector.TracingModel.isTopLevelEvent(event))
this._lastFrame._addTimeForCategory(this._categoryMapper(event), event.selfTime);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_processCompositorEvents: function(event)
{
var eventNames = WebInspector.TimelineModel.RecordType;
if (event.args["layerTreeId"] !== this._layerTreeId)
return;
var timestamp = event.startTime;
if (event.name === eventNames.BeginFrame)
this.handleBeginFrame(timestamp);
else if (event.name === eventNames.DrawFrame)
this.handleDrawFrame(timestamp);
else if (event.name === eventNames.ActivateLayerTree)
this.handleActivateLayerTree();
else if (event.name === eventNames.RequestMainThreadFrame)
this.handleRequestMainThreadFrame();
else if (event.name === eventNames.NeedsBeginFrameChanged)
this.handleNeedFrameChanged(timestamp, event.args["data"] && event.args["data"]["needsBeginFrame"]);
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_addMainThreadTraceEvent: function(event)
{
var eventNames = WebInspector.TimelineModel.RecordType;
var timestamp = event.startTime;
var selfTime = event.selfTime || 0;
if (WebInspector.TracingModel.isTopLevelEvent(event)) {
this._currentTaskTimeByCategory = {};
this._lastTaskBeginTime = event.startTime;
}
if (!this._framePendingCommit && WebInspector.TimelineFrameModel._mainFrameMarkers.indexOf(event.name) >= 0)
this._framePendingCommit = new WebInspector.PendingFrame(this._lastTaskBeginTime || event.startTime, this._currentTaskTimeByCategory);
if (!this._framePendingCommit) {
this._addTimeForCategory(this._currentTaskTimeByCategory, event);
return;
}
this._addTimeForCategory(this._framePendingCommit.timeByCategory, event);
if (event.name === eventNames.BeginMainThreadFrame && event.args["data"] && event.args["data"]["frameId"])
this._framePendingCommit.mainFrameId = event.args["data"]["frameId"];
if (event.name === eventNames.Paint && event.args["data"]["layerId"] && event.picture && this._target)
this._framePendingCommit.paints.push(new WebInspector.LayerPaintEvent(event, this._target));
if (event.name === eventNames.CompositeLayers && event.args["layerTreeId"] === this._layerTreeId)
this.handleCompositeLayers();
},
/**
* @param {!Object.<string, number>} timeByCategory
* @param {!WebInspector.TracingModel.Event} event
*/
_addTimeForCategory: function(timeByCategory, event)
{
if (!event.selfTime)
return;
var categoryName = this._categoryMapper(event);
timeByCategory[categoryName] = (timeByCategory[categoryName] || 0) + event.selfTime;
},
}
/**
* @constructor
* @extends {WebInspector.DeferredLayerTree}
* @param {!WebInspector.TracingModel.ObjectSnapshot} snapshot
* @param {?WebInspector.Target} target
*/
WebInspector.DeferredTracingLayerTree = function(snapshot, target)
{
WebInspector.DeferredLayerTree.call(this, target);
this._snapshot = snapshot;
}
WebInspector.DeferredTracingLayerTree.prototype = {
/**
* @override
* @param {function(!WebInspector.LayerTreeBase)} callback
*/
resolve: function(callback)
{
this._snapshot.requestObject(onGotObject.bind(this));
/**
* @this {WebInspector.DeferredTracingLayerTree}
* @param {?Object} result
*/
function onGotObject(result)
{
if (!result)
return;
var viewport = result["device_viewport_size"];
var tiles = result["active_tiles"];
var rootLayer = result["active_tree"]["root_layer"];
var layers = result["active_tree"]["layers"];
var layerTree = new WebInspector.TracingLayerTree(this._target);
layerTree.setViewportSize(viewport);
layerTree.setTiles(tiles);
layerTree.setLayers(rootLayer, layers, callback.bind(null, layerTree));
}
},
__proto__: WebInspector.DeferredLayerTree.prototype
};
/**
* @constructor
* @param {number} startTime
* @param {number} startTimeOffset
*/
WebInspector.TimelineFrame = function(startTime, startTimeOffset)
{
this.startTime = startTime;
this.startTimeOffset = startTimeOffset;
this.endTime = this.startTime;
this.duration = 0;
this.timeByCategory = {};
this.cpuTime = 0;
this.idle = false;
/** @type {?WebInspector.DeferredLayerTree} */
this.layerTree = null;
/** @type {!Array.<!WebInspector.LayerPaintEvent>} */
this.paints = [];
/** @type {number|undefined} */
this._mainFrameId = undefined;
}
WebInspector.TimelineFrame.prototype = {
/**
* @return {boolean}
*/
hasWarnings: function()
{
var /** @const */ longFrameDurationThresholdMs = 22;
return !this.idle && this.duration > longFrameDurationThresholdMs;
},
/**
* @param {number} endTime
*/
_setEndTime: function(endTime)
{
this.endTime = endTime;
this.duration = this.endTime - this.startTime;
},
/**
* @param {?WebInspector.DeferredLayerTree} layerTree
*/
_setLayerTree: function(layerTree)
{
this.layerTree = layerTree;
},
/**
* @param {!Object} timeByCategory
*/
_addTimeForCategories: function(timeByCategory)
{
for (var category in timeByCategory)
this._addTimeForCategory(category, timeByCategory[category]);
},
/**
* @param {string} category
* @param {number} time
*/
_addTimeForCategory: function(category, time)
{
this.timeByCategory[category] = (this.timeByCategory[category] || 0) + time;
this.cpuTime += time;
},
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} event
* @param {?WebInspector.Target} target
*/
WebInspector.LayerPaintEvent = function(event, target)
{
this._event = event;
this._target = target;
}
WebInspector.LayerPaintEvent.prototype = {
/**
* @return {string}
*/
layerId: function()
{
return this._event.args["data"]["layerId"];
},
/**
* @return {!WebInspector.TracingModel.Event}
*/
event: function()
{
return this._event;
},
/**
* @param {function(?Array.<number>, ?string)} callback
*/
loadPicture: function(callback)
{
this._event.picture.requestObject(onGotObject);
/**
* @param {?Object} result
*/
function onGotObject(result)
{
if (!result || !result["skp64"]) {
callback(null, null);
return;
}
var rect = result["params"] && result["params"]["layer_rect"];
callback(rect, result["skp64"]);
}
},
/**
* @param {function(?Array.<number>, ?WebInspector.PaintProfilerSnapshot)} callback
*/
loadSnapshot: function(callback)
{
this.loadPicture(onGotPicture.bind(this));
/**
* @param {?Array.<number>} rect
* @param {?string} picture
* @this {WebInspector.LayerPaintEvent}
*/
function onGotPicture(rect, picture)
{
if (!rect || !picture || !this._target) {
callback(null, null);
return;
}
WebInspector.PaintProfilerSnapshot.load(this._target, picture, callback.bind(null, rect));
}
}
};
/**
* @constructor
* @param {number} triggerTime
* @param {!Object.<string, number>} timeByCategory
*/
WebInspector.PendingFrame = function(triggerTime, timeByCategory)
{
/** @type {!Object.<string, number>} */
this.timeByCategory = timeByCategory;
/** @type {!Array.<!WebInspector.LayerPaintEvent>} */
this.paints = [];
/** @type {number|undefined} */
this.mainFrameId = undefined;
this.triggerTime = triggerTime;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | 2 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.TimelineIRModel = function() { this.reset(); } /** * @enum {string} */ WebInspector.TimelineIRModel.Phases = { Idle: "Idle", Response: "Response", Scroll: "Scroll", Fling: "Fling", Drag: "Drag", Animation: "Animation", Uncategorized: "Uncategorized" }; /** * @enum {string} */ WebInspector.TimelineIRModel.InputEvents = { Char: "Char", Click: "GestureClick", ContextMenu: "ContextMenu", FlingCancel: "GestureFlingCancel", FlingStart: "GestureFlingStart", ImplSideFling: WebInspector.TimelineModel.RecordType.ImplSideFling, KeyDown: "KeyDown", KeyDownRaw: "RawKeyDown", KeyUp: "KeyUp", LatencyScrollUpdate: "ScrollUpdate", MouseDown: "MouseDown", MouseMove: "MouseMove", MouseUp: "MouseUp", MouseWheel: "MouseWheel", PinchBegin: "GesturePinchBegin", PinchEnd: "GesturePinchEnd", PinchUpdate: "GesturePinchUpdate", ScrollBegin: "GestureScrollBegin", ScrollEnd: "GestureScrollEnd", ScrollUpdate: "GestureScrollUpdate", ScrollUpdateRenderer: "ScrollUpdate", ShowPress: "GestureShowPress", Tap: "GestureTap", TapCancel: "GestureTapCancel", TapDown: "GestureTapDown", TouchCancel: "TouchCancel", TouchEnd: "TouchEnd", TouchMove: "TouchMove", TouchStart: "TouchStart" }; WebInspector.TimelineIRModel._mergeThresholdsMs = { animation: 1, mouse: 40, }; WebInspector.TimelineIRModel._eventIRPhase = Symbol("eventIRPhase"); /** * @param {!WebInspector.TracingModel.Event} event * @return {!WebInspector.TimelineIRModel.Phases} */ WebInspector.TimelineIRModel.phaseForEvent = function(event) { return event[WebInspector.TimelineIRModel._eventIRPhase]; } WebInspector.TimelineIRModel.prototype = { /** * @param {?Array<!WebInspector.TracingModel.AsyncEvent>} inputLatencies * @param {?Array<!WebInspector.TracingModel.AsyncEvent>} animations */ populate: function(inputLatencies, animations) { var eventTypes = WebInspector.TimelineIRModel.InputEvents; var phases = WebInspector.TimelineIRModel.Phases; this.reset(); if (!inputLatencies) return; this._processInputLatencies(inputLatencies); if (animations) this._processAnimations(animations); var range = new WebInspector.SegmentedRange(); range.appendRange(this._drags); // Drags take lower precedence than animation, as we can't detect them reliably. range.appendRange(this._cssAnimations); range.appendRange(this._scrolls); range.appendRange(this._responses); this._segments = range.segments(); }, /** * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events */ _processInputLatencies: function(events) { var eventTypes = WebInspector.TimelineIRModel.InputEvents; var phases = WebInspector.TimelineIRModel.Phases; var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; var scrollStart; var flingStart; var touchStart; var firstTouchMove; var mouseWheel; var mouseDown; var mouseMove; for (var i = 0; i < events.length; ++i) { var event = events[i]; if (i > 0 && events[i].startTime < events[i - 1].startTime) console.assert(false, "Unordered input events"); var type = this._inputEventType(event.name); switch (type) { case eventTypes.ScrollBegin: this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); scrollStart = event; break; case eventTypes.ScrollEnd: if (scrollStart) this._scrolls.append(this._segmentForEventRange(scrollStart, event, phases.Scroll)); else this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); scrollStart = null; break; case eventTypes.ScrollUpdate: touchStart = null; // Since we're scrolling now, disregard other touch gestures. this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); break; case eventTypes.FlingStart: if (flingStart) { WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s", flingStart.startTime, event.startTime)); break; } flingStart = event; break; case eventTypes.FlingCancel: // FIXME: also process renderer fling events. if (!flingStart) break; this._scrolls.append(this._segmentForEventRange(flingStart, event, phases.Fling)); flingStart = null; break; case eventTypes.ImplSideFling: this._scrolls.append(this._segmentForEvent(event, phases.Fling)); break; case eventTypes.ShowPress: case eventTypes.Tap: case eventTypes.KeyDown: case eventTypes.KeyDownRaw: case eventTypes.KeyUp: case eventTypes.Char: case eventTypes.Click: case eventTypes.ContextMenu: this._responses.append(this._segmentForEvent(event, phases.Response)); break; case eventTypes.TouchStart: // We do not produce any response segment for TouchStart -- there's either going to be one upon // TouchMove for drag, or one for GestureTap. if (touchStart) { WebInspector.console.error(WebInspector.UIString("Two touches at the same time? %s vs %s", touchStart.startTime, event.startTime)); break; } touchStart = event; event.steps[0][WebInspector.TimelineIRModel._eventIRPhase] = phases.Response; firstTouchMove = null; break; case eventTypes.TouchCancel: touchStart = null; break; case eventTypes.TouchMove: if (firstTouchMove) { this._drags.append(this._segmentForEvent(event, phases.Drag)); } else if (touchStart) { firstTouchMove = event; this._responses.append(this._segmentForEventRange(touchStart, event, phases.Response)); } break; case eventTypes.TouchEnd: touchStart = null; break; case eventTypes.MouseDown: mouseDown = event; mouseMove = null; break; case eventTypes.MouseMove: if (mouseDown && !mouseMove && mouseDown.startTime + thresholdsMs.mouse > event.startTime) { this._responses.append(this._segmentForEvent(mouseDown, phases.Response)); this._responses.append(this._segmentForEvent(event, phases.Response)); } else if (mouseDown) { this._drags.append(this._segmentForEvent(event, phases.Drag)); } mouseMove = event; break; case eventTypes.MouseUp: this._responses.append(this._segmentForEvent(event, phases.Response)); mouseDown = null; break; case eventTypes.MouseWheel: // Do not consider first MouseWheel as trace viewer's implementation does -- in case of MouseWheel it's not really special. if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event)) this._scrolls.append(this._segmentForEventRange(mouseWheel, event, phases.Scroll)); else this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); mouseWheel = event; break; } } /** * @param {number} threshold * @param {!WebInspector.TracingModel.AsyncEvent} first * @param {!WebInspector.TracingModel.AsyncEvent} second * @return {boolean} */ function canMerge(threshold, first, second) { return first.endTime < second.startTime && second.startTime < first.endTime + threshold; } }, /** * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events */ _processAnimations: function(events) { for (var i = 0; i < events.length; ++i) this._cssAnimations.append(this._segmentForEvent(events[i], WebInspector.TimelineIRModel.Phases.Animation)); }, /** * @param {!WebInspector.TracingModel.AsyncEvent} event * @param {!WebInspector.TimelineIRModel.Phases} phase * @return {!WebInspector.Segment} */ _segmentForEvent: function(event, phase) { this._setPhaseForEvent(event, phase); return new WebInspector.Segment(event.startTime, event.endTime, phase); }, /** * @param {!WebInspector.TracingModel.AsyncEvent} startEvent * @param {!WebInspector.TracingModel.AsyncEvent} endEvent * @param {!WebInspector.TimelineIRModel.Phases} phase * @return {!WebInspector.Segment} */ _segmentForEventRange: function(startEvent, endEvent, phase) { this._setPhaseForEvent(startEvent, phase); this._setPhaseForEvent(endEvent, phase); return new WebInspector.Segment(startEvent.startTime, endEvent.endTime, phase); }, /** * @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent * @param {!WebInspector.TimelineIRModel.Phases} phase */ _setPhaseForEvent: function(asyncEvent, phase) { asyncEvent.steps[0][WebInspector.TimelineIRModel._eventIRPhase] = phase; }, /** * @return {!Array<!WebInspector.Segment>} */ interactionRecords: function() { return this._segments; }, reset: function() { var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; this._segments = []; this._drags = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.mouse)); this._cssAnimations = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.animation)); this._responses = new WebInspector.SegmentedRange(merge.bind(null, 0)); this._scrolls = new WebInspector.SegmentedRange(merge.bind(null, thresholdsMs.animation)); /** * @param {number} threshold * @param {!WebInspector.Segment} first * @param {!WebInspector.Segment} second */ function merge(threshold, first, second) { return first.end + threshold >= second.begin && first.data === second.data ? first : null; } }, /** * @param {string} eventName * @return {?WebInspector.TimelineIRModel.InputEvents} */ _inputEventType: function(eventName) { var prefix = "InputLatency::"; if (!eventName.startsWith(prefix)) { if (eventName === WebInspector.TimelineIRModel.InputEvents.ImplSideFling) return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName); console.error("Unrecognized input latency event: " + eventName); return null; } return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName.substr(prefix.length)); } }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | 2 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.TimelineJSProfileProcessor = { };
/**
* @param {!WebInspector.CPUProfileDataModel} jsProfileModel
* @param {!WebInspector.TracingModel.Thread} thread
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(jsProfileModel, thread)
{
var idleNode = jsProfileModel.idleNode;
var programNode = jsProfileModel.programNode;
var gcNode = jsProfileModel.gcNode;
var samples = jsProfileModel.samples;
var timestamps = jsProfileModel.timestamps;
var jsEvents = [];
/** @type {!Map<!Object, !Array<!RuntimeAgent.CallFrame>>} */
var nodeToStackMap = new Map();
nodeToStackMap.set(programNode, []);
for (var i = 0; i < samples.length; ++i) {
var node = jsProfileModel.nodeByIndex(i);
if (!node) {
console.error(`Node with unknown id ${samples[i]} at index ${i}`);
continue;
}
if (node === gcNode || node === idleNode)
continue;
var callFrames = nodeToStackMap.get(node);
if (!callFrames) {
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (new Array(node.depth + 1));
nodeToStackMap.set(node, callFrames);
for (var j = 0; node.parent; node = node.parent)
callFrames[j++] = /** @type {!RuntimeAgent.CallFrame} */ (node);
}
var jsSampleEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,
WebInspector.TimelineModel.RecordType.JSSample,
WebInspector.TracingModel.Phase.Instant, timestamps[i], thread);
jsSampleEvent.args["data"] = { stackTrace: callFrames };
jsEvents.push(jsSampleEvent);
}
return jsEvents;
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents = function(events)
{
/**
* @param {!RuntimeAgent.CallFrame} frame1
* @param {!RuntimeAgent.CallFrame} frame2
* @return {boolean}
*/
function equalFrames(frame1, frame2)
{
return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName;
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @return {number}
*/
function eventEndTime(e)
{
return e.endTime || e.startTime;
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @return {boolean}
*/
function isJSInvocationEvent(e)
{
switch (e.name) {
case WebInspector.TimelineModel.RecordType.FunctionCall:
case WebInspector.TimelineModel.RecordType.EvaluateScript:
return true;
}
return false;
}
var jsFrameEvents = [];
var jsFramesStack = [];
var lockedJsStackDepth = [];
var ordinal = 0;
var filterNativeFunctions = !WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onStartEvent(e)
{
e.ordinal = ++ordinal;
extractStackTrace(e);
// For the duration of the event we cannot go beyond the stack associated with it.
lockedJsStackDepth.push(jsFramesStack.length);
}
/**
* @param {!WebInspector.TracingModel.Event} e
* @param {?WebInspector.TracingModel.Event} parent
*/
function onInstantEvent(e, parent)
{
e.ordinal = ++ordinal;
if (parent && isJSInvocationEvent(parent))
extractStackTrace(e);
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEndEvent(e)
{
truncateJSStack(lockedJsStackDepth.pop(), e.endTime);
}
/**
* @param {number} depth
* @param {number} time
*/
function truncateJSStack(depth, time)
{
if (lockedJsStackDepth.length) {
var lockedDepth = lockedJsStackDepth.peekLast();
if (depth < lockedDepth) {
console.error("Child stack is shallower (" + depth + ") than the parent stack (" + lockedDepth + ") at " + time);
depth = lockedDepth;
}
}
if (jsFramesStack.length < depth) {
console.error("Trying to truncate higher than the current stack size at " + time);
depth = jsFramesStack.length;
}
for (var k = 0; k < jsFramesStack.length; ++k)
jsFramesStack[k].setEndTime(time);
jsFramesStack.length = depth;
}
/**
* @param {!Array<!RuntimeAgent.CallFrame>} stack
*/
function filterStackFrames(stack)
{
for (var i = 0, j = 0; i < stack.length; ++i) {
var url = stack[i].url;
if (url && url.startsWith("native "))
continue;
stack[j++] = stack[i];
}
stack.length = j;
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function extractStackTrace(e)
{
var recordTypes = WebInspector.TimelineModel.RecordType;
var callFrames;
if (e.name === recordTypes.JSSample) {
var eventData = e.args["data"] || e.args["beginData"];
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (eventData && eventData["stackTrace"]);
} else {
callFrames = /** @type {!Array<!RuntimeAgent.CallFrame>} */ (jsFramesStack.map(frameEvent => frameEvent.args["data"]).reverse());
}
if (filterNativeFunctions)
filterStackFrames(callFrames);
var endTime = eventEndTime(e);
var numFrames = callFrames.length;
var minFrames = Math.min(numFrames, jsFramesStack.length);
var i;
for (i = lockedJsStackDepth.peekLast() || 0; i < minFrames; ++i) {
var newFrame = callFrames[numFrames - 1 - i];
var oldFrame = jsFramesStack[i].args["data"];
if (!equalFrames(newFrame, oldFrame))
break;
jsFramesStack[i].setEndTime(Math.max(jsFramesStack[i].endTime, endTime));
}
truncateJSStack(i, e.startTime);
for (; i < numFrames; ++i) {
var frame = callFrames[numFrames - 1 - i];
var jsFrameEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory, recordTypes.JSFrame,
WebInspector.TracingModel.Phase.Complete, e.startTime, e.thread);
jsFrameEvent.ordinal = e.ordinal;
jsFrameEvent.addArgs({ data: frame });
jsFrameEvent.setEndTime(endTime);
jsFramesStack.push(jsFrameEvent);
jsFrameEvents.push(jsFrameEvent);
}
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {?WebInspector.TracingModel.Event}
*/
function findFirstTopLevelEvent(events)
{
for (var i = 0; i < events.length; ++i) {
if (WebInspector.TracingModel.isTopLevelEvent(events[i]))
return events[i];
}
return null;
}
var firstTopLevelEvent = findFirstTopLevelEvent(events);
if (firstTopLevelEvent)
WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent, firstTopLevelEvent.startTime);
return jsFrameEvents;
}
/**
* @constructor
*/
WebInspector.TimelineJSProfileProcessor.CodeMap = function()
{
/** @type {!Map<string, !WebInspector.TimelineJSProfileProcessor.CodeMap.Bank>} */
this._banks = new Map();
}
/**
* @constructor
* @param {number} address
* @param {number} size
* @param {!RuntimeAgent.CallFrame} callFrame
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.Entry = function(address, size, callFrame)
{
this.address = address;
this.size = size;
this.callFrame = callFrame;
}
/**
* @param {number} address
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} entry
* @return {number}
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.comparator = function(address, entry)
{
return address - entry.address;
}
WebInspector.TimelineJSProfileProcessor.CodeMap.prototype = {
/**
* @param {string} addressHex
* @param {number} size
* @param {!RuntimeAgent.CallFrame} callFrame
*/
addEntry: function(addressHex, size, callFrame)
{
var entry = new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry(this._getAddress(addressHex), size, callFrame);
this._addEntry(addressHex, entry);
},
/**
* @param {string} oldAddressHex
* @param {string} newAddressHex
* @param {number} size
*/
moveEntry: function(oldAddressHex, newAddressHex, size)
{
var entry = this._getBank(oldAddressHex).removeEntry(this._getAddress(oldAddressHex));
if (!entry) {
console.error("Entry at address " + oldAddressHex + " not found");
return;
}
entry.address = this._getAddress(newAddressHex);
entry.size = size;
this._addEntry(newAddressHex, entry);
},
/**
* @param {string} addressHex
* @return {?RuntimeAgent.CallFrame}
*/
lookupEntry: function(addressHex)
{
return this._getBank(addressHex).lookupEntry(this._getAddress(addressHex));
},
/**
* @param {string} addressHex
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} entry
*/
_addEntry: function(addressHex, entry)
{
// FIXME: deal with entries that span across [multiple] banks.
this._getBank(addressHex).addEntry(entry);
},
/**
* @param {string} addressHex
* @return {!WebInspector.TimelineJSProfileProcessor.CodeMap.Bank}
*/
_getBank: function(addressHex)
{
addressHex = addressHex.slice(2); // cut 0x prefix.
// 13 hex digits == 52 bits, double mantissa fits 53 bits.
var /** @const */ bankSizeHexDigits = 13;
var /** @const */ maxHexDigits = 16;
var bankName = addressHex.slice(-maxHexDigits, -bankSizeHexDigits);
var bank = this._banks.get(bankName);
if (!bank) {
bank = new WebInspector.TimelineJSProfileProcessor.CodeMap.Bank();
this._banks.set(bankName, bank);
}
return bank;
},
/**
* @param {string} addressHex
* @return {number}
*/
_getAddress: function(addressHex)
{
// 13 hex digits == 52 bits, double mantissa fits 53 bits.
var /** @const */ bankSizeHexDigits = 13;
addressHex = addressHex.slice(2); // cut 0x prefix.
return parseInt(addressHex.slice(-bankSizeHexDigits), 16);
}
}
/**
* @constructor
*/
WebInspector.TimelineJSProfileProcessor.CodeMap.Bank = function()
{
/** @type {!Array<!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry>} */
this._entries = [];
}
WebInspector.TimelineJSProfileProcessor.CodeMap.Bank.prototype = {
/**
* @param {number} address
* @return {?WebInspector.TimelineJSProfileProcessor.CodeMap.Entry}
*/
removeEntry: function(address)
{
var index = this._entries.lowerBound(address, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
var entry = this._entries[index];
if (!entry || entry.address !== address)
return null;
this._entries.splice(index, 1);
return entry;
},
/**
* @param {number} address
* @return {?RuntimeAgent.CallFrame}
*/
lookupEntry: function(address)
{
var index = this._entries.upperBound(address, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator) - 1;
var entry = this._entries[index];
return entry && address < entry.address + entry.size ? entry.callFrame : null;
},
/**
* @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} newEntry
*/
addEntry: function(newEntry)
{
var endAddress = newEntry.address + newEntry.size;
var lastIndex = this._entries.lowerBound(endAddress, WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
var index;
for (index = lastIndex - 1; index >= 0; --index) {
var entry = this._entries[index];
var entryEndAddress = entry.address + entry.size;
if (entryEndAddress <= newEntry.address)
break;
}
++index;
this._entries.splice(index, lastIndex - index, newEntry);
}
}
/**
* @param {string} name
* @param {number} scriptId
* @return {!RuntimeAgent.CallFrame}
*/
WebInspector.TimelineJSProfileProcessor._buildCallFrame = function(name, scriptId)
{
/**
* @param {string} functionName
* @param {string=} url
* @param {string=} scriptId
* @param {number=} line
* @param {number=} column
* @param {boolean=} isNative
* @return {!RuntimeAgent.CallFrame}
*/
function createFrame(functionName, url, scriptId, line, column, isNative)
{
return /** @type {!RuntimeAgent.CallFrame} */ ({
"functionName": functionName,
"url": url || "",
"scriptId": scriptId || "0",
"lineNumber": line || 0,
"columnNumber": column || 0,
"isNative": isNative || false
});
}
// Code states:
// (empty) -> compiled
// ~ -> optimizable
// * -> optimized
var rePrefix = /^(\w*:)?[*~]?(.*)$/m;
var tokens = rePrefix.exec(name);
var prefix = tokens[1];
var body = tokens[2];
var rawName;
var rawUrl;
if (prefix === "Script:") {
rawName = "";
rawUrl = body;
} else {
var spacePos = body.lastIndexOf(" ");
rawName = spacePos !== -1 ? body.substr(0, spacePos) : body;
rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : "";
}
var nativeSuffix = " native";
var isNative = rawName.endsWith(nativeSuffix);
var functionName = isNative ? rawName.slice(0, -nativeSuffix.length) : rawName;
var urlData = WebInspector.ParsedURL.splitLineAndColumn(rawUrl);
var url = urlData.url || "";
var line = urlData.lineNumber || 0;
var column = urlData.columnNumber || 0;
return createFrame(functionName, url, String(scriptId), line, column, isNative);
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events)
{
var missingAddesses = new Set();
/**
* @param {string} address
* @return {?RuntimeAgent.CallFrame}
*/
function convertRawFrame(address)
{
var entry = codeMap.lookupEntry(address);
if (entry)
return entry.isNative ? null : entry;
if (!missingAddesses.has(address)) {
missingAddesses.add(address);
console.error("Address " + address + " has missing code entry");
}
return null;
}
var recordTypes = WebInspector.TimelineModel.RecordType;
var samples = [];
var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap();
for (var i = 0; i < events.length; ++i) {
var e = events[i];
var data = e.args["data"];
switch (e.name) {
case recordTypes.JitCodeAdded:
var frame = WebInspector.TimelineJSProfileProcessor._buildCallFrame(data["name"], data["script_id"]);
codeMap.addEntry(data["code_start"], data["code_len"], frame);
break;
case recordTypes.JitCodeMoved:
codeMap.moveEntry(data["code_start"], data["new_code_start"], data["code_len"]);
break;
case recordTypes.V8Sample:
var rawStack = data["stack"];
// Sometimes backend fails to collect a stack and returns an empty stack.
// Skip these bogus samples.
if (data["vm_state"] === "js" && !rawStack.length)
break;
var stack = rawStack.map(convertRawFrame);
stack.remove(null);
var sampleEvent = new WebInspector.TracingModel.Event(
WebInspector.TracingModel.DevToolsTimelineEventCategory,
WebInspector.TimelineModel.RecordType.JSSample,
WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread);
sampleEvent.ordinal = e.ordinal;
sampleEvent.args = {"data": {"stackTrace": stack }};
samples.push(sampleEvent);
break;
}
}
return samples;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | 2 1 1 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.TimelineModel.Filter} eventFilter
*/
WebInspector.TimelineModel = function(eventFilter)
{
this._eventFilter = eventFilter;
this.reset();
}
/**
* @enum {string}
*/
WebInspector.TimelineModel.RecordType = {
Task: "Task",
Program: "Program",
EventDispatch: "EventDispatch",
GPUTask: "GPUTask",
Animation: "Animation",
RequestMainThreadFrame: "RequestMainThreadFrame",
BeginFrame: "BeginFrame",
NeedsBeginFrameChanged: "NeedsBeginFrameChanged",
BeginMainThreadFrame: "BeginMainThreadFrame",
ActivateLayerTree: "ActivateLayerTree",
DrawFrame: "DrawFrame",
HitTest: "HitTest",
ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
RecalculateStyles: "RecalculateStyles", // For backwards compatibility only, now replaced by UpdateLayoutTree.
UpdateLayoutTree: "UpdateLayoutTree",
InvalidateLayout: "InvalidateLayout",
Layout: "Layout",
UpdateLayer: "UpdateLayer",
UpdateLayerTree: "UpdateLayerTree",
PaintSetup: "PaintSetup",
Paint: "Paint",
PaintImage: "PaintImage",
Rasterize: "Rasterize",
RasterTask: "RasterTask",
ScrollLayer: "ScrollLayer",
CompositeLayers: "CompositeLayers",
ScheduleStyleInvalidationTracking: "ScheduleStyleInvalidationTracking",
StyleRecalcInvalidationTracking: "StyleRecalcInvalidationTracking",
StyleInvalidatorInvalidationTracking: "StyleInvalidatorInvalidationTracking",
LayoutInvalidationTracking: "LayoutInvalidationTracking",
LayerInvalidationTracking: "LayerInvalidationTracking",
PaintInvalidationTracking: "PaintInvalidationTracking",
ScrollInvalidationTracking: "ScrollInvalidationTracking",
ParseHTML: "ParseHTML",
ParseAuthorStyleSheet: "ParseAuthorStyleSheet",
TimerInstall: "TimerInstall",
TimerRemove: "TimerRemove",
TimerFire: "TimerFire",
XHRReadyStateChange: "XHRReadyStateChange",
XHRLoad: "XHRLoad",
CompileScript: "v8.compile",
EvaluateScript: "EvaluateScript",
CommitLoad: "CommitLoad",
MarkLoad: "MarkLoad",
MarkDOMContent: "MarkDOMContent",
MarkFirstPaint: "MarkFirstPaint",
TimeStamp: "TimeStamp",
ConsoleTime: "ConsoleTime",
UserTiming: "UserTiming",
ResourceSendRequest: "ResourceSendRequest",
ResourceReceiveResponse: "ResourceReceiveResponse",
ResourceReceivedData: "ResourceReceivedData",
ResourceFinish: "ResourceFinish",
FunctionCall: "FunctionCall",
GCEvent: "GCEvent", // For backwards compatibility only, now replaced by MinorGC/MajorGC.
MajorGC: "MajorGC",
MinorGC: "MinorGC",
JSFrame: "JSFrame",
JSSample: "JSSample",
// V8Sample events are coming from tracing and contain raw stacks with function addresses.
// After being processed with help of JitCodeAdded and JitCodeMoved events they
// get translated into function infos and stored as stacks in JSSample events.
V8Sample: "V8Sample",
JitCodeAdded: "JitCodeAdded",
JitCodeMoved: "JitCodeMoved",
ParseScriptOnBackground: "v8.parseOnBackground",
UpdateCounters: "UpdateCounters",
RequestAnimationFrame: "RequestAnimationFrame",
CancelAnimationFrame: "CancelAnimationFrame",
FireAnimationFrame: "FireAnimationFrame",
RequestIdleCallback: "RequestIdleCallback",
CancelIdleCallback: "CancelIdleCallback",
FireIdleCallback: "FireIdleCallback",
WebSocketCreate : "WebSocketCreate",
WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
WebSocketDestroy : "WebSocketDestroy",
EmbedderCallback : "EmbedderCallback",
SetLayerTreeId: "SetLayerTreeId",
TracingStartedInPage: "TracingStartedInPage",
TracingSessionIdForWorker: "TracingSessionIdForWorker",
DecodeImage: "Decode Image",
ResizeImage: "Resize Image",
DrawLazyPixelRef: "Draw LazyPixelRef",
DecodeLazyPixelRef: "Decode LazyPixelRef",
LazyPixelRef: "LazyPixelRef",
LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl",
PictureSnapshot: "cc::Picture",
DisplayItemListSnapshot: "cc::DisplayItemList",
LatencyInfo: "LatencyInfo",
LatencyInfoFlow: "LatencyInfo.Flow",
InputLatencyMouseMove: "InputLatency::MouseMove",
InputLatencyMouseWheel: "InputLatency::MouseWheel",
ImplSideFling: "InputHandlerProxy::HandleGestureFling::started",
GCIdleLazySweep: "ThreadState::performIdleLazySweep",
GCCompleteSweep: "ThreadState::completeSweep",
GCCollectGarbage: "BlinkGCMarking",
// CpuProfile is a virtual event created on frontend to support
// serialization of CPU Profiles within tracing timeline data.
CpuProfile: "CpuProfile"
}
WebInspector.TimelineModel.Category = {
Console: "blink.console",
UserTiming: "blink.user_timing",
LatencyInfo: "latencyInfo"
};
/**
* @enum {string}
*/
WebInspector.TimelineModel.WarningType = {
ForcedStyle: "ForcedStyle",
ForcedLayout: "ForcedLayout",
IdleDeadlineExceeded: "IdleDeadlineExceeded",
V8Deopt: "V8Deopt"
}
WebInspector.TimelineModel.MainThreadName = "main";
WebInspector.TimelineModel.WorkerThreadName = "DedicatedWorker Thread";
WebInspector.TimelineModel.RendererMainThreadName = "CrRendererMain";
/**
* @enum {symbol}
*/
WebInspector.TimelineModel.AsyncEventGroup = {
animation: Symbol("animation"),
console: Symbol("console"),
userTiming: Symbol("userTiming"),
input: Symbol("input")
};
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} events
* @param {function(!WebInspector.TracingModel.Event)} onStartEvent
* @param {function(!WebInspector.TracingModel.Event)} onEndEvent
* @param {function(!WebInspector.TracingModel.Event,?WebInspector.TracingModel.Event)|undefined=} onInstantEvent
* @param {number=} startTime
* @param {number=} endTime
*/
WebInspector.TimelineModel.forEachEvent = function(events, onStartEvent, onEndEvent, onInstantEvent, startTime, endTime)
{
startTime = startTime || 0;
endTime = endTime || Infinity;
var stack = [];
for (var i = 0; i < events.length; ++i) {
var e = events[i];
if ((e.endTime || e.startTime) < startTime)
continue;
if (e.startTime >= endTime)
break;
if (WebInspector.TracingModel.isAsyncPhase(e.phase) || WebInspector.TracingModel.isFlowPhase(e.phase))
continue;
while (stack.length && stack.peekLast().endTime <= e.startTime)
onEndEvent(stack.pop());
if (e.duration) {
onStartEvent(e);
stack.push(e);
} else {
onInstantEvent && onInstantEvent(e, stack.peekLast() || null);
}
}
while (stack.length)
onEndEvent(stack.pop());
}
WebInspector.TimelineModel.DevToolsMetadataEvent = {
TracingStartedInBrowser: "TracingStartedInBrowser",
TracingStartedInPage: "TracingStartedInPage",
TracingSessionIdForWorker: "TracingSessionIdForWorker",
};
/**
* @constructor
* @param {string} name
*/
WebInspector.TimelineModel.VirtualThread = function(name)
{
this.name = name;
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this.events = [];
/** @type {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
this.asyncEventsByGroup = new Map();
}
WebInspector.TimelineModel.VirtualThread.prototype = {
/**
* @return {boolean}
*/
isWorker: function()
{
return this.name === WebInspector.TimelineModel.WorkerThreadName;
}
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} traceEvent
*/
WebInspector.TimelineModel.Record = function(traceEvent)
{
this._event = traceEvent;
this._children = [];
}
/**
* @param {!WebInspector.TimelineModel.Record} a
* @param {!WebInspector.TimelineModel.Record} b
* @return {number}
*/
WebInspector.TimelineModel.Record._compareStartTime = function(a, b)
{
// Never return 0 as otherwise equal records would be merged.
return a.startTime() <= b.startTime() ? -1 : 1;
}
WebInspector.TimelineModel.Record.prototype = {
/**
* @return {?WebInspector.Target}
*/
target: function()
{
var threadName = this._event.thread.name();
// FIXME: correctly specify target
return threadName === WebInspector.TimelineModel.RendererMainThreadName ? WebInspector.targetManager.targets()[0] || null : null;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
children: function()
{
return this._children;
},
/**
* @return {number}
*/
startTime: function()
{
return this._event.startTime;
},
/**
* @return {number}
*/
endTime: function()
{
return this._event.endTime || this._event.startTime;
},
/**
* @return {string}
*/
thread: function()
{
if (this._event.thread.name() === WebInspector.TimelineModel.RendererMainThreadName)
return WebInspector.TimelineModel.MainThreadName;
return this._event.thread.name();
},
/**
* @return {!WebInspector.TimelineModel.RecordType}
*/
type: function()
{
return WebInspector.TimelineModel._eventType(this._event);
},
/**
* @param {string} key
* @return {?Object}
*/
getUserObject: function(key)
{
if (key === "TimelineUIUtils::preview-element")
return this._event.previewElement;
throw new Error("Unexpected key: " + key);
},
/**
* @param {string} key
* @param {?Object|undefined} value
*/
setUserObject: function(key, value)
{
if (key !== "TimelineUIUtils::preview-element")
throw new Error("Unexpected key: " + key);
this._event.previewElement = /** @type {?Element} */ (value);
},
/**
* @return {!WebInspector.TracingModel.Event}
*/
traceEvent: function()
{
return this._event;
},
/**
* @param {!WebInspector.TimelineModel.Record} child
*/
_addChild: function(child)
{
this._children.push(child);
child.parent = this;
}
}
/** @typedef {!{page: !Array<!WebInspector.TracingModel.Event>, workers: !Array<!WebInspector.TracingModel.Event>}} */
WebInspector.TimelineModel.MetadataEvents;
/**
* @return {!WebInspector.TimelineModel.RecordType}
*/
WebInspector.TimelineModel._eventType = function(event)
{
if (event.hasCategory(WebInspector.TimelineModel.Category.Console))
return WebInspector.TimelineModel.RecordType.ConsoleTime;
if (event.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
return WebInspector.TimelineModel.RecordType.UserTiming;
if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo))
return WebInspector.TimelineModel.RecordType.LatencyInfo;
return /** @type !WebInspector.TimelineModel.RecordType */ (event.name);
}
WebInspector.TimelineModel.prototype = {
/**
* @deprecated Test use only!
* @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector.TimelineModel.Record,number)} preOrderCallback
* @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)=} postOrderCallback
* @return {boolean}
*/
forAllRecords: function(preOrderCallback, postOrderCallback)
{
/**
* @param {!Array.<!WebInspector.TimelineModel.Record>} records
* @param {number} depth
* @return {boolean}
*/
function processRecords(records, depth)
{
for (var i = 0; i < records.length; ++i) {
var record = records[i];
if (preOrderCallback && preOrderCallback(record, depth))
return true;
if (processRecords(record.children(), depth + 1))
return true;
if (postOrderCallback && postOrderCallback(record, depth))
return true;
}
return false;
}
return processRecords(this._records, 0);
},
/**
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)} callback
*/
forAllFilteredRecords: function(filters, callback)
{
/**
* @param {!WebInspector.TimelineModel.Record} record
* @param {number} depth
* @this {WebInspector.TimelineModel}
* @return {boolean}
*/
function processRecord(record, depth)
{
var visible = WebInspector.TimelineModel.isVisible(filters, record.traceEvent());
if (visible && callback(record, depth))
return true;
for (var i = 0; i < record.children().length; ++i) {
if (processRecord.call(this, record.children()[i], visible ? depth + 1 : depth))
return true;
}
return false;
}
for (var i = 0; i < this._records.length; ++i)
processRecord.call(this, this._records[i], 0);
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
records: function()
{
return this._records;
},
/**
* @return {!Array<!WebInspector.CPUProfileDataModel>}
*/
cpuProfiles: function()
{
return this._cpuProfiles;
},
/**
* @return {?string}
*/
sessionId: function()
{
return this._sessionId;
},
/**
* @return {?WebInspector.Target}
*/
target: function()
{
// FIXME: Consider returning null for loaded traces.
return WebInspector.targetManager.targets()[0];
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @param {boolean=} produceTraceStartedInPage
*/
setEvents: function(tracingModel, produceTraceStartedInPage)
{
this.reset();
this._resetProcessingState();
this._minimumRecordTime = tracingModel.minimumRecordTime();
this._maximumRecordTime = tracingModel.maximumRecordTime();
var metadataEvents = this._processMetadataEvents(tracingModel, !!produceTraceStartedInPage);
var startTime = 0;
for (var i = 0, length = metadataEvents.page.length; i < length; i++) {
var metaEvent = metadataEvents.page[i];
var process = metaEvent.thread.process();
var endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity;
this._currentPage = metaEvent.args["data"] && metaEvent.args["data"]["page"];
for (var thread of process.sortedThreads()) {
if (thread.name() === WebInspector.TimelineModel.WorkerThreadName && !metadataEvents.workers.some(function(e) { return e.args["data"]["workerThreadId"] === thread.id(); }))
continue;
this._processThreadEvents(startTime, endTime, metaEvent.thread, thread);
}
startTime = endTime;
}
this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
this._processBrowserEvents(tracingModel);
this._buildTimelineRecords();
this._buildGPUEvents(tracingModel);
this._insertFirstPaintEvent();
this._resetProcessingState();
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @param {boolean} produceTraceStartedInPage
* @return {!WebInspector.TimelineModel.MetadataEvents}
*/
_processMetadataEvents: function(tracingModel, produceTraceStartedInPage)
{
var metadataEvents = tracingModel.devToolsMetadataEvents();
var pageDevToolsMetadataEvents = [];
var workersDevToolsMetadataEvents = [];
for (var event of metadataEvents) {
if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage) {
pageDevToolsMetadataEvents.push(event);
} else if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker) {
workersDevToolsMetadataEvents.push(event);
} else if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) {
console.assert(!this._mainFrameNodeId, "Multiple sessions in trace");
this._mainFrameNodeId = event.args["frameTreeNodeId"];
}
}
if (!pageDevToolsMetadataEvents.length) {
// The trace is probably coming not from DevTools. Make a mock Metadata event.
var pageMetaEvent = produceTraceStartedInPage ? this._makeMockPageMetadataEvent(tracingModel) : null;
if (!pageMetaEvent) {
console.error(WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage + " event not found.");
return {page: [], workers: []};
}
pageDevToolsMetadataEvents.push(pageMetaEvent);
}
var sessionId = pageDevToolsMetadataEvents[0].args["sessionId"] || pageDevToolsMetadataEvents[0].args["data"]["sessionId"];
this._sessionId = sessionId;
var mismatchingIds = new Set();
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
function checkSessionId(event)
{
var args = event.args;
// FIXME: put sessionId into args["data"] for TracingStartedInPage event.
if (args["data"])
args = args["data"];
var id = args["sessionId"];
if (id === sessionId)
return true;
mismatchingIds.add(id);
return false;
}
var result = {
page: pageDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime),
workers: workersDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime)
};
if (mismatchingIds.size)
WebInspector.console.error("Timeline recording was started in more than one page simultaneously. Session id mismatch: " + this._sessionId + " and " + mismatchingIds.valuesArray() + ".");
return result;
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @return {?WebInspector.TracingModel.Event}
*/
_makeMockPageMetadataEvent: function(tracingModel)
{
var rendererMainThreadName = WebInspector.TimelineModel.RendererMainThreadName;
// FIXME: pick up the first renderer process for now.
var process = Object.values(tracingModel.sortedProcesses()).filter(function(p) { return p.threadByName(rendererMainThreadName); })[0];
var thread = process && process.threadByName(rendererMainThreadName);
if (!thread)
return null;
var pageMetaEvent = new WebInspector.TracingModel.Event(
WebInspector.TracingModel.DevToolsMetadataEventCategory,
WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage,
WebInspector.TracingModel.Phase.Metadata,
tracingModel.minimumRecordTime(), thread);
pageMetaEvent.addArgs({"data": {"sessionId": "mockSessionId"}});
return pageMetaEvent;
},
_insertFirstPaintEvent: function()
{
if (!this._firstCompositeLayers)
return;
// First Paint is actually a DrawFrame that happened after first CompositeLayers following last CommitLoadEvent.
var recordTypes = WebInspector.TimelineModel.RecordType;
var i = this._inspectedTargetEvents.lowerBound(this._firstCompositeLayers, WebInspector.TracingModel.Event.compareStartTime);
for (; i < this._inspectedTargetEvents.length && this._inspectedTargetEvents[i].name !== recordTypes.DrawFrame; ++i) { }
if (i >= this._inspectedTargetEvents.length)
return;
var drawFrameEvent = this._inspectedTargetEvents[i];
var firstPaintEvent = new WebInspector.TracingModel.Event(drawFrameEvent.categoriesString, recordTypes.MarkFirstPaint, WebInspector.TracingModel.Phase.Instant, drawFrameEvent.startTime, drawFrameEvent.thread);
this._mainThreadEvents.splice(this._mainThreadEvents.lowerBound(firstPaintEvent, WebInspector.TracingModel.Event.compareStartTime), 0, firstPaintEvent);
var firstPaintRecord = new WebInspector.TimelineModel.Record(firstPaintEvent);
this._eventDividerRecords.splice(this._eventDividerRecords.lowerBound(firstPaintRecord, WebInspector.TimelineModel.Record._compareStartTime), 0, firstPaintRecord);
},
/**
* @param {!WebInspector.TracingModel} tracingModel
*/
_processBrowserEvents: function(tracingModel)
{
var browserMain = tracingModel.threadByName("Browser", "CrBrowserMain");
if (!browserMain)
return;
// Disregard regular events, we don't need them yet, but still process to get proper metadata.
browserMain.events().forEach(this._processBrowserEvent, this);
/** @type {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
var asyncEventsByGroup = new Map();
this._processAsyncEvents(asyncEventsByGroup, browserMain.asyncEvents());
this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup, asyncEventsByGroup);
},
_buildTimelineRecords: function()
{
var topLevelRecords = this._buildTimelineRecordsForThread(this.mainThreadEvents());
for (var i = 0; i < topLevelRecords.length; i++) {
var record = topLevelRecords[i];
if (WebInspector.TracingModel.isTopLevelEvent(record.traceEvent()))
this._mainThreadTasks.push(record);
}
/**
* @param {!WebInspector.TimelineModel.VirtualThread} virtualThread
* @this {!WebInspector.TimelineModel}
*/
function processVirtualThreadEvents(virtualThread)
{
var threadRecords = this._buildTimelineRecordsForThread(virtualThread.events);
topLevelRecords = topLevelRecords.mergeOrdered(threadRecords, WebInspector.TimelineModel.Record._compareStartTime);
}
this.virtualThreads().forEach(processVirtualThreadEvents.bind(this));
this._records = topLevelRecords;
},
/**
* @param {!WebInspector.TracingModel} tracingModel
*/
_buildGPUEvents: function(tracingModel)
{
var thread = tracingModel.threadByName("GPU Process", "CrGpuMain");
if (!thread)
return;
var gpuEventName = WebInspector.TimelineModel.RecordType.GPUTask;
this._gpuEvents = thread.events().filter(event => event.name === gpuEventName);
},
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} threadEvents
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
_buildTimelineRecordsForThread: function(threadEvents)
{
var recordStack = [];
var topLevelRecords = [];
for (var i = 0, size = threadEvents.length; i < size; ++i) {
var event = threadEvents[i];
for (var top = recordStack.peekLast(); top && top._event.endTime <= event.startTime; top = recordStack.peekLast())
recordStack.pop();
if (event.phase === WebInspector.TracingModel.Phase.AsyncEnd || event.phase === WebInspector.TracingModel.Phase.NestableAsyncEnd)
continue;
var parentRecord = recordStack.peekLast();
// Maintain the back-end logic of old timeline, skip console.time() / console.timeEnd() that are not properly nested.
if (WebInspector.TracingModel.isAsyncBeginPhase(event.phase) && parentRecord && event.endTime > parentRecord._event.endTime)
continue;
var record = new WebInspector.TimelineModel.Record(event);
if (WebInspector.TimelineModel.isMarkerEvent(event))
this._eventDividerRecords.push(record);
if (!this._eventFilter.accept(event) && !WebInspector.TracingModel.isTopLevelEvent(event))
continue;
if (parentRecord)
parentRecord._addChild(record);
else
topLevelRecords.push(record);
if (event.endTime)
recordStack.push(record);
}
return topLevelRecords;
},
_resetProcessingState: function()
{
this._asyncEventTracker = new WebInspector.TimelineAsyncEventTracker();
this._invalidationTracker = new WebInspector.InvalidationTracker();
this._layoutInvalidate = {};
this._lastScheduleStyleRecalculation = {};
this._paintImageEventByPixelRefId = {};
this._lastPaintForLayer = {};
this._lastRecalculateStylesEvent = null;
this._currentScriptEvent = null;
this._eventStack = [];
this._hadCommitLoad = false;
this._firstCompositeLayers = null;
/** @type {!Set<string>} */
this._knownInputEvents = new Set();
this._currentPage = null;
},
/**
* @param {number} startTime
* @param {number} endTime
* @param {!WebInspector.TracingModel.Thread} mainThread
* @param {!WebInspector.TracingModel.Thread} thread
*/
_processThreadEvents: function(startTime, endTime, mainThread, thread)
{
var events = thread.events();
var asyncEvents = thread.asyncEvents();
var jsSamples;
if (Runtime.experiments.isEnabled("timelineTracingJSProfile")) {
jsSamples = WebInspector.TimelineJSProfileProcessor.processRawV8Samples(events);
} else {
var cpuProfileEvent = events.peekLast();
if (cpuProfileEvent && cpuProfileEvent.name === WebInspector.TimelineModel.RecordType.CpuProfile) {
var cpuProfile = cpuProfileEvent.args["data"]["cpuProfile"];
if (cpuProfile) {
var jsProfileModel = new WebInspector.CPUProfileDataModel(cpuProfile);
this._cpuProfiles.push(jsProfileModel);
jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(jsProfileModel, thread);
}
}
}
if (jsSamples && jsSamples.length)
events = events.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
if (jsSamples || events.some(function(e) { return e.name === WebInspector.TimelineModel.RecordType.JSSample; })) {
var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);
if (jsFrameEvents && jsFrameEvents.length)
events = jsFrameEvents.mergeOrdered(events, WebInspector.TracingModel.Event.orderedCompareStartTime);
}
var threadEvents;
var threadAsyncEventsByGroup;
if (thread === mainThread) {
threadEvents = this._mainThreadEvents;
threadAsyncEventsByGroup = this._mainThreadAsyncEventsByGroup;
} else {
var virtualThread = new WebInspector.TimelineModel.VirtualThread(thread.name());
this._virtualThreads.push(virtualThread);
threadEvents = virtualThread.events;
threadAsyncEventsByGroup = virtualThread.asyncEventsByGroup;
}
this._eventStack = [];
var i = events.lowerBound(startTime, function(time, event) { return time - event.startTime });
var length = events.length;
for (; i < length; i++) {
var event = events[i];
if (endTime && event.startTime >= endTime)
break;
if (!this._processEvent(event))
continue;
threadEvents.push(event);
this._inspectedTargetEvents.push(event);
}
this._processAsyncEvents(threadAsyncEventsByGroup, asyncEvents, startTime, endTime);
// Pretend the compositor's async events are on the main thread.
if (thread.name() === "Compositor") {
this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup, threadAsyncEventsByGroup);
threadAsyncEventsByGroup.clear();
}
},
/**
* @param {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} asyncEventsByGroup
* @param {!Array<!WebInspector.TracingModel.AsyncEvent>} asyncEvents
* @param {number=} startTime
* @param {number=} endTime
*/
_processAsyncEvents: function(asyncEventsByGroup, asyncEvents, startTime, endTime)
{
var i = startTime ? asyncEvents.lowerBound(startTime, function(time, asyncEvent) { return time - asyncEvent.startTime }) : 0;
for (; i < asyncEvents.length; ++i) {
var asyncEvent = asyncEvents[i];
if (endTime && asyncEvent.startTime >= endTime)
break;
var asyncGroup = this._processAsyncEvent(asyncEvent);
if (!asyncGroup)
continue;
var groupAsyncEvents = asyncEventsByGroup.get(asyncGroup);
if (!groupAsyncEvents) {
groupAsyncEvents = [];
asyncEventsByGroup.set(asyncGroup, groupAsyncEvents);
}
groupAsyncEvents.push(asyncEvent);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
_processEvent: function(event)
{
var eventStack = this._eventStack;
while (eventStack.length && eventStack.peekLast().endTime <= event.startTime)
eventStack.pop();
var recordTypes = WebInspector.TimelineModel.RecordType;
if (this._currentScriptEvent && event.startTime > this._currentScriptEvent.endTime)
this._currentScriptEvent = null;
var eventData = event.args["data"] || event.args["beginData"] || {};
if (eventData && eventData["stackTrace"])
event.stackTrace = eventData["stackTrace"];
if (eventStack.length && eventStack.peekLast().name === recordTypes.EventDispatch)
eventStack.peekLast().hasChildren = true;
this._asyncEventTracker.processEvent(event);
if (event.initiator && event.initiator.url)
event.url = event.initiator.url;
switch (event.name) {
case recordTypes.ResourceSendRequest:
case recordTypes.WebSocketCreate:
event.url = event.args["data"]["url"];
event.initiator = eventStack.peekLast() || null;
break;
case recordTypes.ScheduleStyleRecalculation:
this._lastScheduleStyleRecalculation[event.args["data"]["frame"]] = event;
break;
case recordTypes.UpdateLayoutTree:
case recordTypes.RecalculateStyles:
this._invalidationTracker.didRecalcStyle(event);
if (event.args["beginData"])
event.initiator = this._lastScheduleStyleRecalculation[event.args["beginData"]["frame"]];
this._lastRecalculateStylesEvent = event;
if (this._currentScriptEvent)
event.warning = WebInspector.TimelineModel.WarningType.ForcedStyle;
break;
case recordTypes.ScheduleStyleInvalidationTracking:
case recordTypes.StyleRecalcInvalidationTracking:
case recordTypes.StyleInvalidatorInvalidationTracking:
case recordTypes.LayoutInvalidationTracking:
case recordTypes.LayerInvalidationTracking:
case recordTypes.PaintInvalidationTracking:
case recordTypes.ScrollInvalidationTracking:
this._invalidationTracker.addInvalidation(new WebInspector.InvalidationTrackingEvent(event));
break;
case recordTypes.InvalidateLayout:
// Consider style recalculation as a reason for layout invalidation,
// but only if we had no earlier layout invalidation records.
var layoutInitator = event;
var frameId = event.args["data"]["frame"];
if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesEvent && this._lastRecalculateStylesEvent.endTime > event.startTime)
layoutInitator = this._lastRecalculateStylesEvent.initiator;
this._layoutInvalidate[frameId] = layoutInitator;
break;
case recordTypes.Layout:
this._invalidationTracker.didLayout(event);
var frameId = event.args["beginData"]["frame"];
event.initiator = this._layoutInvalidate[frameId];
// In case we have no closing Layout event, endData is not available.
if (event.args["endData"]) {
event.backendNodeId = event.args["endData"]["rootNode"];
event.highlightQuad = event.args["endData"]["root"];
}
this._layoutInvalidate[frameId] = null;
if (this._currentScriptEvent)
event.warning = WebInspector.TimelineModel.WarningType.ForcedLayout;
break;
case recordTypes.EvaluateScript:
case recordTypes.FunctionCall:
if (!this._currentScriptEvent)
this._currentScriptEvent = event;
break;
case recordTypes.SetLayerTreeId:
this._inspectedTargetLayerTreeId = event.args["layerTreeId"] || event.args["data"]["layerTreeId"];
break;
case recordTypes.Paint:
this._invalidationTracker.didPaint(event);
event.highlightQuad = event.args["data"]["clip"];
event.backendNodeId = event.args["data"]["nodeId"];
// Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
if (!event.args["data"]["layerId"])
break;
var layerId = event.args["data"]["layerId"];
this._lastPaintForLayer[layerId] = event;
break;
case recordTypes.DisplayItemListSnapshot:
case recordTypes.PictureSnapshot:
var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== this._inspectedTargetLayerTreeId)
break;
var paintEvent = this._lastPaintForLayer[layerUpdateEvent.args["layerId"]];
if (paintEvent)
paintEvent.picture = event;
break;
case recordTypes.ScrollLayer:
event.backendNodeId = event.args["data"]["nodeId"];
break;
case recordTypes.PaintImage:
event.backendNodeId = event.args["data"]["nodeId"];
event.url = event.args["data"]["url"];
break;
case recordTypes.DecodeImage:
case recordTypes.ResizeImage:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent) {
var decodeLazyPixelRefEvent = this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
paintImageEvent = decodeLazyPixelRefEvent && this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];
}
if (!paintImageEvent)
break;
event.backendNodeId = paintImageEvent.backendNodeId;
event.url = paintImageEvent.url;
break;
case recordTypes.DrawLazyPixelRef:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent)
break;
this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]] = paintImageEvent;
event.backendNodeId = paintImageEvent.backendNodeId;
event.url = paintImageEvent.url;
break;
case recordTypes.MarkDOMContent:
case recordTypes.MarkLoad:
var page = eventData["page"];
if (page && page !== this._currentPage)
return false;
break;
case recordTypes.CommitLoad:
var page = eventData["page"];
if (page && page !== this._currentPage)
return false;
if (!eventData["isMainFrame"])
break;
this._hadCommitLoad = true;
this._firstCompositeLayers = null;
break;
case recordTypes.CompositeLayers:
if (!this._firstCompositeLayers && this._hadCommitLoad)
this._firstCompositeLayers = event;
break;
case recordTypes.FireIdleCallback:
if (event.duration > eventData["allottedMilliseconds"]) {
event.warning = WebInspector.TimelineModel.WarningType.IdleDeadlineExceeded;
}
break;
}
if (WebInspector.TracingModel.isAsyncPhase(event.phase))
return true;
var duration = event.duration;
if (!duration)
return true;
if (eventStack.length) {
var parent = eventStack.peekLast();
parent.selfTime -= duration;
if (parent.selfTime < 0) {
var epsilon = 1e-3;
if (parent.selfTime < -epsilon)
console.error("Children are longer than parent at " + event.startTime + " (" + (event.startTime - this.minimumRecordTime()).toFixed(3) + ") by " + parent.selfTime.toFixed(3));
parent.selfTime = 0;
}
}
event.selfTime = duration;
eventStack.push(event);
return true;
},
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_processBrowserEvent: function(event)
{
if (event.name !== WebInspector.TimelineModel.RecordType.LatencyInfoFlow)
return;
var frameId = event.args["frameTreeNodeId"];
if (typeof frameId === "number" && frameId === this._mainFrameNodeId)
this._knownInputEvents.add(event.bind_id);
},
/**
* @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent
* @return {?WebInspector.TimelineModel.AsyncEventGroup}
*/
_processAsyncEvent: function(asyncEvent)
{
var groups = WebInspector.TimelineModel.AsyncEventGroup;
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.Console))
return groups.console;
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
return groups.userTiming;
if (asyncEvent.name === WebInspector.TimelineModel.RecordType.Animation)
return groups.animation;
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo) || asyncEvent.name === WebInspector.TimelineModel.RecordType.ImplSideFling) {
var lastStep = asyncEvent.steps.peekLast();
// FIXME: fix event termination on the back-end instead.
if (lastStep.phase !== WebInspector.TracingModel.Phase.AsyncEnd)
return null;
var data = lastStep.args["data"];
asyncEvent.causedFrame = !!(data && data["INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT"]);
if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) {
if (!this._knownInputEvents.has(lastStep.id))
return null;
if (asyncEvent.name === WebInspector.TimelineModel.RecordType.InputLatencyMouseMove && !asyncEvent.causedFrame)
return null;
var rendererMain = data["INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT"];
if (rendererMain) {
var time = rendererMain["time"] / 1000;
asyncEvent.steps[0].timeWaitingForMainThread = time - asyncEvent.steps[0].startTime;
}
}
return groups.input;
}
return null;
},
/**
* @param {string} name
* @return {?WebInspector.TracingModel.Event}
*/
_findAncestorEvent: function(name)
{
for (var i = this._eventStack.length - 1; i >= 0; --i) {
var event = this._eventStack[i];
if (event.name === name)
return event;
}
return null;
},
/**
* @param {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} target
* @param {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} source
*/
_mergeAsyncEvents: function(target, source)
{
for (var group of source.keys()) {
var events = target.get(group) || [];
events = events.mergeOrdered(source.get(group) || [], WebInspector.TracingModel.Event.compareStartAndEndTime);
target.set(group, events);
}
},
reset: function()
{
this._virtualThreads = [];
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._mainThreadEvents = [];
/** @type {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} */
this._mainThreadAsyncEventsByGroup = new Map();
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._inspectedTargetEvents = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._records = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._mainThreadTasks = [];
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this._gpuEvents = [];
/** @type {!Array<!WebInspector.TimelineModel.Record>} */
this._eventDividerRecords = [];
/** @type {?string} */
this._sessionId = null;
/** @type {?number} */
this._mainFrameNodeId = null;
/** @type {!Array<!WebInspector.CPUProfileDataModel>} */
this._cpuProfiles = [];
this._minimumRecordTime = 0;
this._maximumRecordTime = 0;
},
/**
* @return {number}
*/
minimumRecordTime: function()
{
return this._minimumRecordTime;
},
/**
* @return {number}
*/
maximumRecordTime: function()
{
return this._maximumRecordTime;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
inspectedTargetEvents: function()
{
return this._inspectedTargetEvents;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
mainThreadEvents: function()
{
return this._mainThreadEvents;
},
/**
* @param {!Array.<!WebInspector.TracingModel.Event>} events
*/
_setMainThreadEvents: function(events)
{
this._mainThreadEvents = events;
},
/**
* @return {!Map<!WebInspector.TimelineModel.AsyncEventGroup, !Array.<!WebInspector.TracingModel.AsyncEvent>>}
*/
mainThreadAsyncEvents: function()
{
return this._mainThreadAsyncEventsByGroup;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.VirtualThread>}
*/
virtualThreads: function()
{
return this._virtualThreads;
},
/**
* @return {boolean}
*/
isEmpty: function()
{
return this.minimumRecordTime() === 0 && this.maximumRecordTime() === 0;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
mainThreadTasks: function()
{
return this._mainThreadTasks;
},
/**
* @return {!Array<!WebInspector.TracingModel.Event>}
*/
gpuEvents: function()
{
return this._gpuEvents;
},
/**
* @return {!Array.<!WebInspector.TimelineModel.Record>}
*/
eventDividerRecords: function()
{
return this._eventDividerRecords;
},
/**
* @return {!Array<!WebInspector.TimelineModel.NetworkRequest>}
*/
networkRequests: function()
{
/** @type {!Map<string,!WebInspector.TimelineModel.NetworkRequest>} */
var requests = new Map();
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
var requestsList = [];
/** @type {!Array<!WebInspector.TimelineModel.NetworkRequest>} */
var zeroStartRequestsList = [];
var types = WebInspector.TimelineModel.RecordType;
var resourceTypes = new Set([
types.ResourceSendRequest,
types.ResourceReceiveResponse,
types.ResourceReceivedData,
types.ResourceFinish
]);
var events = this.mainThreadEvents();
for (var i = 0; i < events.length; ++i) {
var e = events[i];
if (!resourceTypes.has(e.name))
continue;
var id = e.args["data"]["requestId"];
var request = requests.get(id);
if (request) {
request.addEvent(e);
} else {
request = new WebInspector.TimelineModel.NetworkRequest(e);
requests.set(id, request);
if (request.startTime)
requestsList.push(request);
else
zeroStartRequestsList.push(request);
}
}
return zeroStartRequestsList.concat(requestsList);
},
}
/**
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
WebInspector.TimelineModel.isVisible = function(filters, event)
{
for (var i = 0; i < filters.length; ++i) {
if (!filters[i].accept(event))
return false;
}
return true;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
WebInspector.TimelineModel.isMarkerEvent = function(event)
{
var recordTypes = WebInspector.TimelineModel.RecordType;
switch (event.name) {
case recordTypes.TimeStamp:
case recordTypes.MarkFirstPaint:
return true;
case recordTypes.MarkDOMContent:
case recordTypes.MarkLoad:
return event.args["data"]["isMainFrame"];
default:
return false;
}
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} event
*/
WebInspector.TimelineModel.NetworkRequest = function(event)
{
this.startTime = event.name === WebInspector.TimelineModel.RecordType.ResourceSendRequest ? event.startTime : 0;
this.endTime = Infinity;
/** @type {!Array<!WebInspector.TracingModel.Event>} */
this.children = [];
this.addEvent(event);
}
WebInspector.TimelineModel.NetworkRequest.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
*/
addEvent: function(event)
{
this.children.push(event);
var recordType = WebInspector.TimelineModel.RecordType;
this.startTime = Math.min(this.startTime, event.startTime);
var eventData = event.args["data"];
if (eventData["mimeType"])
this.mimeType = eventData["mimeType"];
if ("priority" in eventData)
this.priority = eventData["priority"];
if (event.name === recordType.ResourceFinish)
this.endTime = event.startTime;
if (!this.responseTime && (event.name === recordType.ResourceReceiveResponse || event.name === recordType.ResourceReceivedData))
this.responseTime = event.startTime;
if (!this.url)
this.url = eventData["url"];
if (!this.requestMethod)
this.requestMethod = eventData["requestMethod"];
}
}
/**
* @constructor
*/
WebInspector.TimelineModel.Filter = function()
{
}
WebInspector.TimelineModel.Filter.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return true;
}
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
* @param {!Array.<string>} visibleTypes
*/
WebInspector.TimelineVisibleEventsFilter = function(visibleTypes)
{
WebInspector.TimelineModel.Filter.call(this);
this._visibleTypes = new Set(visibleTypes);
}
WebInspector.TimelineVisibleEventsFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return this._visibleTypes.has(WebInspector.TimelineModel._eventType(event));
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
* @param {!Array<string>} excludeNames
*/
WebInspector.ExclusiveNameFilter = function(excludeNames)
{
WebInspector.TimelineModel.Filter.call(this);
this._excludeNames = new Set(excludeNames);
}
WebInspector.ExclusiveNameFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !this._excludeNames.has(event.name);
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @extends {WebInspector.TimelineModel.Filter}
*/
WebInspector.ExcludeTopLevelFilter = function()
{
WebInspector.TimelineModel.Filter.call(this);
}
WebInspector.ExcludeTopLevelFilter.prototype = {
/**
* @override
* @param {!WebInspector.TracingModel.Event} event
* @return {boolean}
*/
accept: function(event)
{
return !WebInspector.TracingModel.isTopLevelEvent(event);
},
__proto__: WebInspector.TimelineModel.Filter.prototype
}
/**
* @constructor
* @param {!WebInspector.TracingModel.Event} event
*/
WebInspector.InvalidationTrackingEvent = function(event)
{
/** @type {string} */
this.type = event.name;
/** @type {number} */
this.startTime = event.startTime;
/** @type {!WebInspector.TracingModel.Event} */
this._tracingEvent = event;
var eventData = event.args["data"];
/** @type {number} */
this.frame = eventData["frame"];
/** @type {?number} */
this.nodeId = eventData["nodeId"];
/** @type {?string} */
this.nodeName = eventData["nodeName"];
/** @type {?number} */
this.paintId = eventData["paintId"];
/** @type {?number} */
this.invalidationSet = eventData["invalidationSet"];
/** @type {?string} */
this.invalidatedSelectorId = eventData["invalidatedSelectorId"];
/** @type {?string} */
this.changedId = eventData["changedId"];
/** @type {?string} */
this.changedClass = eventData["changedClass"];
/** @type {?string} */
this.changedAttribute = eventData["changedAttribute"];
/** @type {?string} */
this.changedPseudo = eventData["changedPseudo"];
/** @type {?string} */
this.selectorPart = eventData["selectorPart"];
/** @type {?string} */
this.extraData = eventData["extraData"];
/** @type {?Array.<!Object.<string, number>>} */
this.invalidationList = eventData["invalidationList"];
/** @type {!WebInspector.InvalidationCause} */
this.cause = {reason: eventData["reason"], stackTrace: eventData["stackTrace"]};
// FIXME: Move this to TimelineUIUtils.js.
if (!this.cause.reason && this.cause.stackTrace && this.type === WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking)
this.cause.reason = "Layout forced";
}
/** @typedef {{reason: string, stackTrace: ?Array.<!RuntimeAgent.CallFrame>}} */
WebInspector.InvalidationCause;
/**
* @constructor
*/
WebInspector.InvalidationTracker = function()
{
this._initializePerFrameState();
}
WebInspector.InvalidationTracker.prototype = {
/**
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
addInvalidation: function(invalidation)
{
this._startNewFrameIfNeeded();
if (!invalidation.nodeId && !invalidation.paintId) {
console.error("Invalidation lacks node information.");
console.error(invalidation);
return;
}
// PaintInvalidationTracking events provide a paintId and a nodeId which
// we can use to update the paintId for all other invalidation tracking
// events.
var recordTypes = WebInspector.TimelineModel.RecordType;
if (invalidation.type === recordTypes.PaintInvalidationTracking && invalidation.nodeId) {
var invalidations = this._invalidationsByNodeId[invalidation.nodeId] || [];
for (var i = 0; i < invalidations.length; ++i)
invalidations[i].paintId = invalidation.paintId;
// PaintInvalidationTracking is only used for updating paintIds.
return;
}
// Suppress StyleInvalidator StyleRecalcInvalidationTracking invalidations because they
// will be handled by StyleInvalidatorInvalidationTracking.
// FIXME: Investigate if we can remove StyleInvalidator invalidations entirely.
if (invalidation.type === recordTypes.StyleRecalcInvalidationTracking && invalidation.cause.reason === "StyleInvalidator")
return;
// Style invalidation events can occur before and during recalc style. didRecalcStyle
// handles style invalidations that occur before the recalc style event but we need to
// handle style recalc invalidations during recalc style here.
var styleRecalcInvalidation = (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking
|| invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking
|| invalidation.type === recordTypes.StyleRecalcInvalidationTracking);
if (styleRecalcInvalidation) {
var duringRecalcStyle = invalidation.startTime && this._lastRecalcStyle
&& invalidation.startTime >= this._lastRecalcStyle.startTime
&& invalidation.startTime <= this._lastRecalcStyle.endTime;
if (duringRecalcStyle)
this._associateWithLastRecalcStyleEvent(invalidation);
}
// Record the invalidation so later events can look it up.
if (this._invalidations[invalidation.type])
this._invalidations[invalidation.type].push(invalidation);
else
this._invalidations[invalidation.type] = [ invalidation ];
if (invalidation.nodeId) {
if (this._invalidationsByNodeId[invalidation.nodeId])
this._invalidationsByNodeId[invalidation.nodeId].push(invalidation);
else
this._invalidationsByNodeId[invalidation.nodeId] = [ invalidation ];
}
},
/**
* @param {!WebInspector.TracingModel.Event} recalcStyleEvent
*/
didRecalcStyle: function(recalcStyleEvent)
{
this._lastRecalcStyle = recalcStyleEvent;
var types = [WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,
WebInspector.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,
WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking];
for (var invalidation of this._invalidationsOfTypes(types))
this._associateWithLastRecalcStyleEvent(invalidation);
},
/**
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
_associateWithLastRecalcStyleEvent: function(invalidation)
{
if (invalidation.linkedRecalcStyleEvent)
return;
var recordTypes = WebInspector.TimelineModel.RecordType;
var recalcStyleFrameId = this._lastRecalcStyle.args["beginData"]["frame"];
if (invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking) {
// Instead of calling _addInvalidationToEvent directly, we create synthetic
// StyleRecalcInvalidationTracking events which will be added in _addInvalidationToEvent.
this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
} else if (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking) {
// ScheduleStyleInvalidationTracking events are only used for adding information to
// StyleInvalidatorInvalidationTracking events. See: _addSyntheticStyleRecalcInvalidations.
} else {
this._addInvalidationToEvent(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
}
invalidation.linkedRecalcStyleEvent = true;
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} frameId
* @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
*/
_addSyntheticStyleRecalcInvalidations: function(event, frameId, styleInvalidatorInvalidation)
{
if (!styleInvalidatorInvalidation.invalidationList) {
this._addSyntheticStyleRecalcInvalidation(styleInvalidatorInvalidation._tracingEvent, styleInvalidatorInvalidation);
return;
}
if (!styleInvalidatorInvalidation.nodeId) {
console.error("Invalidation lacks node information.");
console.error(invalidation);
return;
}
for (var i = 0; i < styleInvalidatorInvalidation.invalidationList.length; i++) {
var setId = styleInvalidatorInvalidation.invalidationList[i]["id"];
var lastScheduleStyleRecalculation;
var nodeInvalidations = this._invalidationsByNodeId[styleInvalidatorInvalidation.nodeId] || [];
for (var j = 0; j < nodeInvalidations.length; j++) {
var invalidation = nodeInvalidations[j];
if (invalidation.frame !== frameId || invalidation.invalidationSet !== setId || invalidation.type !== WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking)
continue;
lastScheduleStyleRecalculation = invalidation;
}
if (!lastScheduleStyleRecalculation) {
console.error("Failed to lookup the event that scheduled a style invalidator invalidation.");
continue;
}
this._addSyntheticStyleRecalcInvalidation(lastScheduleStyleRecalculation._tracingEvent, styleInvalidatorInvalidation);
}
},
/**
* @param {!WebInspector.TracingModel.Event} baseEvent
* @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
*/
_addSyntheticStyleRecalcInvalidation: function(baseEvent, styleInvalidatorInvalidation)
{
var invalidation = new WebInspector.InvalidationTrackingEvent(baseEvent);
invalidation.type = WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking;
invalidation.synthetic = true;
if (styleInvalidatorInvalidation.cause.reason)
invalidation.cause.reason = styleInvalidatorInvalidation.cause.reason;
if (styleInvalidatorInvalidation.selectorPart)
invalidation.selectorPart = styleInvalidatorInvalidation.selectorPart;
this.addInvalidation(invalidation);
if (!invalidation.linkedRecalcStyleEvent)
this._associateWithLastRecalcStyleEvent(invalidation);
},
/**
* @param {!WebInspector.TracingModel.Event} layoutEvent
*/
didLayout: function(layoutEvent)
{
var layoutFrameId = layoutEvent.args["beginData"]["frame"];
for (var invalidation of this._invalidationsOfTypes([WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking])) {
if (invalidation.linkedLayoutEvent)
continue;
this._addInvalidationToEvent(layoutEvent, layoutFrameId, invalidation);
invalidation.linkedLayoutEvent = true;
}
},
/**
* @param {!WebInspector.TracingModel.Event} paintEvent
*/
didPaint: function(paintEvent)
{
this._didPaint = true;
// If a paint doesn't have a corresponding graphics layer id, it paints
// into its parent so add an effectivePaintId to these events.
var layerId = paintEvent.args["data"]["layerId"];
if (layerId)
this._lastPaintWithLayer = paintEvent;
if (!this._lastPaintWithLayer) {
console.error("Failed to find a paint container for a paint event.");
return;
}
var effectivePaintId = this._lastPaintWithLayer.args["data"]["nodeId"];
var paintFrameId = paintEvent.args["data"]["frame"];
var types = [WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking,
WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking,
WebInspector.TimelineModel.RecordType.PaintInvalidationTracking,
WebInspector.TimelineModel.RecordType.ScrollInvalidationTracking];
for (var invalidation of this._invalidationsOfTypes(types)) {
if (invalidation.paintId === effectivePaintId)
this._addInvalidationToEvent(paintEvent, paintFrameId, invalidation);
}
},
/**
* @param {!WebInspector.TracingModel.Event} event
* @param {number} eventFrameId
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
_addInvalidationToEvent: function(event, eventFrameId, invalidation)
{
if (eventFrameId !== invalidation.frame)
return;
if (!event.invalidationTrackingEvents)
event.invalidationTrackingEvents = [ invalidation ];
else
event.invalidationTrackingEvents.push(invalidation);
},
/**
* @param {!Array.<string>=} types
* @return {!Iterator.<!WebInspector.InvalidationTrackingEvent>}
*/
_invalidationsOfTypes: function(types)
{
var invalidations = this._invalidations;
if (!types)
types = Object.keys(invalidations);
function* generator()
{
for (var i = 0; i < types.length; ++i) {
var invalidationList = invalidations[types[i]] || [];
for (var j = 0; j < invalidationList.length; ++j)
yield invalidationList[j];
}
}
return generator();
},
_startNewFrameIfNeeded: function()
{
if (!this._didPaint)
return;
this._initializePerFrameState();
},
_initializePerFrameState: function()
{
/** @type {!Object.<string, !Array.<!WebInspector.InvalidationTrackingEvent>>} */
this._invalidations = {};
/** @type {!Object.<number, !Array.<!WebInspector.InvalidationTrackingEvent>>} */
this._invalidationsByNodeId = {};
this._lastRecalcStyle = undefined;
this._lastPaintWithLayer = undefined;
this._didPaint = false;
}
}
/**
* @constructor
*/
WebInspector.TimelineAsyncEventTracker = function()
{
WebInspector.TimelineAsyncEventTracker._initialize();
/** @type {!Map<!WebInspector.TimelineModel.RecordType, !Map<string, !WebInspector.TracingModel.Event>>} */
this._initiatorByType = new Map();
for (var initiator of WebInspector.TimelineAsyncEventTracker._asyncEvents.keys())
this._initiatorByType.set(initiator, new Map());
}
WebInspector.TimelineAsyncEventTracker._initialize = function()
{
if (WebInspector.TimelineAsyncEventTracker._asyncEvents)
return;
var events = new Map();
var type = WebInspector.TimelineModel.RecordType;
events.set(type.TimerInstall, {causes: [type.TimerFire], joinBy: "timerId"});
events.set(type.ResourceSendRequest, {causes: [type.ResourceReceiveResponse, type.ResourceReceivedData, type.ResourceFinish], joinBy: "requestId"});
events.set(type.RequestAnimationFrame, {causes: [type.FireAnimationFrame], joinBy: "id"});
events.set(type.RequestIdleCallback, {causes: [type.FireIdleCallback], joinBy: "id"});
events.set(type.WebSocketCreate, {causes: [type.WebSocketSendHandshakeRequest, type.WebSocketReceiveHandshakeResponse, type.WebSocketDestroy], joinBy: "identifier"});
WebInspector.TimelineAsyncEventTracker._asyncEvents = events;
/** @type {!Map<!WebInspector.TimelineModel.RecordType, !WebInspector.TimelineModel.RecordType>} */
WebInspector.TimelineAsyncEventTracker._typeToInitiator = new Map();
for (var entry of events) {
var types = entry[1].causes;
for (type of types)
WebInspector.TimelineAsyncEventTracker._typeToInitiator.set(type, entry[0]);
}
}
WebInspector.TimelineAsyncEventTracker.prototype = {
/**
* @param {!WebInspector.TracingModel.Event} event
*/
processEvent: function(event)
{
var initiatorType = WebInspector.TimelineAsyncEventTracker._typeToInitiator.get(/** @type {!WebInspector.TimelineModel.RecordType} */ (event.name));
var isInitiator = !initiatorType;
if (!initiatorType)
initiatorType = /** @type {!WebInspector.TimelineModel.RecordType} */ (event.name);
var initiatorInfo = WebInspector.TimelineAsyncEventTracker._asyncEvents.get(initiatorType);
if (!initiatorInfo)
return;
var id = event.args["data"][initiatorInfo.joinBy];
if (!id)
return;
/** @type {!Map<string, !WebInspector.TracingModel.Event>|undefined} */
var initiatorMap = this._initiatorByType.get(initiatorType);
if (isInitiator)
initiatorMap.set(id, event);
else
event.initiator = initiatorMap.get(id) || null;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | 2 1 1 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
WebInspector.TimelineProfileTree = { };
/**
* @constructor
*/
WebInspector.TimelineProfileTree.Node = function()
{
/** @type {number} */
this.totalTime;
/** @type {number} */
this.selfTime;
/** @type {string} */
this.id;
/** @type {!WebInspector.TracingModel.Event} */
this.event;
/** @type {?Map<string|symbol,!WebInspector.TimelineProfileTree.Node>} */
this.children;
/** @type {?WebInspector.TimelineProfileTree.Node} */
this.parent;
this._isGroupNode = false;
}
WebInspector.TimelineProfileTree.Node.prototype = {
/**
* @return {boolean}
*/
isGroupNode: function()
{
return this._isGroupNode;
}
}
/**
* @param {!Array<!WebInspector.TracingModel.Event>} events
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {number} startTime
* @param {number} endTime
* @param {function(!WebInspector.TracingModel.Event):(string|symbol)=} eventIdCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startTime, endTime, eventIdCallback)
{
// Temporarily deposit a big enough value that exceeds the max recording time.
var /** @const */ initialTime = 1e7;
var root = new WebInspector.TimelineProfileTree.Node();
root.totalTime = initialTime;
root.selfTime = initialTime;
root.children = /** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */ (new Map());
var parent = root;
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onStartEvent(e)
{
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime) : 0;
var id = eventIdCallback ? eventIdCallback(e) : Symbol("uniqueEventId");
if (!parent.children)
parent.children = /** @type {!Map<string,!WebInspector.TimelineProfileTree.Node>} */ (new Map());
var node = parent.children.get(id);
if (node) {
node.selfTime += time;
node.totalTime += time;
} else {
node = new WebInspector.TimelineProfileTree.Node();
node.totalTime = time;
node.selfTime = time;
node.parent = parent;
node.id = id;
node.event = e;
parent.children.set(id, node);
}
parent.selfTime -= time;
if (parent.selfTime < 0) {
console.log("Error: Negative self of " + parent.selfTime, e);
parent.selfTime = 0;
}
if (e.endTime)
parent = node;
}
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onEndEvent(e)
{
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
parent = parent.parent;
}
var instantEventCallback = eventIdCallback ? undefined : onStartEvent; // Ignore instant events when aggregating.
WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, instantEventCallback, startTime, endTime);
root.totalTime -= root.selfTime;
root.selfTime = 0;
return root;
}
/**
* @param {!WebInspector.TimelineProfileTree.Node} topDownTree
* @param {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node=} groupingCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
WebInspector.TimelineProfileTree.buildBottomUp = function(topDownTree, groupingCallback)
{
var buRoot = new WebInspector.TimelineProfileTree.Node();
buRoot.selfTime = 0;
buRoot.totalTime = 0;
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
buRoot.children = new Map();
var nodesOnStack = /** @type {!Set<string>} */ (new Set());
if (topDownTree.children)
topDownTree.children.forEach(processNode);
buRoot.totalTime = topDownTree.totalTime;
/**
* @param {!WebInspector.TimelineProfileTree.Node} tdNode
*/
function processNode(tdNode)
{
var buParent = groupingCallback && groupingCallback(tdNode) || buRoot;
if (buParent !== buRoot) {
buRoot.children.set(buParent.id, buParent);
buParent.parent = buRoot;
}
appendNode(tdNode, buParent);
var hadNode = nodesOnStack.has(tdNode.id);
if (!hadNode)
nodesOnStack.add(tdNode.id);
if (tdNode.children)
tdNode.children.forEach(processNode);
if (!hadNode)
nodesOnStack.delete(tdNode.id);
}
/**
* @param {!WebInspector.TimelineProfileTree.Node} tdNode
* @param {!WebInspector.TimelineProfileTree.Node} buParent
*/
function appendNode(tdNode, buParent)
{
var selfTime = tdNode.selfTime;
var totalTime = tdNode.totalTime;
buParent.selfTime += selfTime;
buParent.totalTime += selfTime;
while (tdNode.parent) {
if (!buParent.children)
buParent.children = /** @type {!Map<string,!WebInspector.TimelineProfileTree.Node>} */ (new Map());
var id = tdNode.id;
var buNode = buParent.children.get(id);
if (!buNode) {
buNode = new WebInspector.TimelineProfileTree.Node();
buNode.selfTime = selfTime;
buNode.totalTime = totalTime;
buNode.event = tdNode.event;
buNode.id = id;
buNode.parent = buParent;
buParent.children.set(id, buNode);
} else {
buNode.selfTime += selfTime;
if (!nodesOnStack.has(id))
buNode.totalTime += totalTime;
}
tdNode = tdNode.parent;
buParent = buNode;
}
}
// Purge zero self time nodes.
var rootChildren = buRoot.children;
for (var item of rootChildren.entries()) {
if (item[1].selfTime === 0)
rootChildren.delete(/** @type {string} */(item[0]));
}
return buRoot;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {?string}
*/
WebInspector.TimelineProfileTree.eventURL = function(event)
{
var data = event.args["data"] || event.args["beginData"];
if (data && data["url"])
return data["url"];
var frame = WebInspector.TimelineProfileTree.eventStackFrame(event);
while (frame) {
var url = frame["url"];
if (url)
return url;
frame = frame.parent;
}
return null;
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {?Object}
*/
WebInspector.TimelineProfileTree.eventStackFrame = function(event)
{
if (event.name === WebInspector.TimelineModel.RecordType.JSFrame)
return event.args["data"];
var topFrame = event.stackTrace && event.stackTrace[0];
if (topFrame)
return topFrame;
var initiator = event.initiator;
return initiator && initiator.stackTrace && initiator.stackTrace[0] || null;
}
/**
* @constructor
* @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
*/
WebInspector.TimelineAggregator = function(categoryMapper)
{
this._categoryMapper = categoryMapper;
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
this._groupNodes = new Map();
}
/**
* @enum {string}
*/
WebInspector.TimelineAggregator.GroupBy = {
None: "None",
Category: "Category",
Domain: "Domain",
Subdomain: "Subdomain",
URL: "URL"
}
/**
* @param {!WebInspector.TracingModel.Event} event
* @return {string}
*/
WebInspector.TimelineAggregator.eventId = function(event)
{
if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
var data = event.args["data"];
return "f:" + data["functionName"] + "@" + (data["scriptId"] || data["url"] || "");
}
return event.name + ":@" + WebInspector.TimelineProfileTree.eventURL(event);
}
WebInspector.TimelineAggregator._extensionInternalPrefix = "extensions::";
WebInspector.TimelineAggregator._groupNodeFlag = Symbol("groupNode");
/**
* @param {string} url
* @return {boolean}
*/
WebInspector.TimelineAggregator.isExtensionInternalURL = function(url)
{
return url.startsWith(WebInspector.TimelineAggregator._extensionInternalPrefix);
}
WebInspector.TimelineAggregator.prototype = {
/**
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node}
*/
groupFunction: function(groupBy)
{
var idMapper = this._nodeToGroupIdFunction(groupBy);
return idMapper && this._nodeToGroupNode.bind(this, idMapper);
},
/**
* @param {!WebInspector.TimelineProfileTree.Node} root
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {!WebInspector.TimelineProfileTree.Node}
*/
performGrouping: function(root, groupBy)
{
var nodeMapper = this.groupFunction(groupBy);
if (!nodeMapper)
return root;
for (var node of root.children.values()) {
var groupNode = nodeMapper(node);
groupNode.parent = root;
groupNode.selfTime += node.selfTime;
groupNode.totalTime += node.totalTime;
groupNode.children.set(node.id, node);
node.parent = root;
}
root.children = this._groupNodes;
return root;
},
/**
* @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {?function(!WebInspector.TimelineProfileTree.Node):string}
*/
_nodeToGroupIdFunction: function(groupBy)
{
/**
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {string}
*/
function groupByURL(node)
{
return WebInspector.TimelineProfileTree.eventURL(node.event) || "";
}
/**
* @param {boolean} groupSubdomains
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {string}
*/
function groupByDomain(groupSubdomains, node)
{
var url = WebInspector.TimelineProfileTree.eventURL(node.event) || "";
if (WebInspector.TimelineAggregator.isExtensionInternalURL(url))
return WebInspector.TimelineAggregator._extensionInternalPrefix;
var parsedURL = url.asParsedURL();
if (!parsedURL)
return "";
if (parsedURL.scheme === "chrome-extension")
return parsedURL.scheme + "://" + parsedURL.host;
if (!groupSubdomains)
return parsedURL.host;
if (/^[.0-9]+$/.test(parsedURL.host))
return parsedURL.host;
var domainMatch = /([^.]*\.)?[^.]*$/.exec(parsedURL.host);
return domainMatch && domainMatch[0] || "";
}
switch (groupBy) {
case WebInspector.TimelineAggregator.GroupBy.None: return null;
case WebInspector.TimelineAggregator.GroupBy.Category: return node => node.event ? this._categoryMapper(node.event) : "";
case WebInspector.TimelineAggregator.GroupBy.Subdomain: return groupByDomain.bind(null, false);
case WebInspector.TimelineAggregator.GroupBy.Domain: return groupByDomain.bind(null, true);
case WebInspector.TimelineAggregator.GroupBy.URL: return groupByURL;
default: return null;
}
},
/**
* @param {string} id
* @param {!WebInspector.TracingModel.Event} event
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_buildGroupNode: function(id, event)
{
var groupNode = new WebInspector.TimelineProfileTree.Node();
groupNode.id = id;
groupNode.selfTime = 0;
groupNode.totalTime = 0;
groupNode.children = new Map();
groupNode.event = event;
groupNode._isGroupNode = true;
this._groupNodes.set(id, groupNode);
return groupNode;
},
/**
* @param {function(!WebInspector.TimelineProfileTree.Node):string} nodeToGroupId
* @param {!WebInspector.TimelineProfileTree.Node} node
* @return {!WebInspector.TimelineProfileTree.Node}
*/
_nodeToGroupNode: function(nodeToGroupId, node)
{
var id = nodeToGroupId(node);
return this._groupNodes.get(id) || this._buildGroupNode(id, node.event);
},
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Toolbox.js | 42.86% | (3 / 7) | 0% | (0 / 2) | 50% | (1 / 2) | 42.86% | (3 / 7) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 2 1 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function()
{
/**
* @suppressGlobalPropertiesCheck
*/
function toolboxLoaded()
{
if (!window.opener)
return;
var app = window.opener.WebInspector["AdvancedApp"]["_instance"]();
app["toolboxLoaded"](document);
}
runOnWindowLoad(toolboxLoaded);
})();
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ActionRegistry.js | 5.71% | (4 / 70) | 0% | (0 / 26) | 0% | (0 / 26) | 5.71% | (4 / 70) | |
| ColorSwatch.js | 2% | (1 / 50) | 0% | (0 / 27) | 0% | (0 / 11) | 2% | (1 / 50) | |
| Context.js | 2.78% | (1 / 36) | 0% | (0 / 18) | 0% | (0 / 9) | 2.78% | (1 / 36) | |
| ContextMenu.js | 3.77% | (6 / 159) | 0% | (0 / 52) | 0% | (0 / 38) | 3.77% | (6 / 159) | |
| DOMSyntaxHighlighter.js | 8.82% | (3 / 34) | 0% | (0 / 12) | 0% | (0 / 5) | 8.82% | (3 / 34) | |
| Dialog.js | 1.18% | (1 / 85) | 0% | (0 / 20) | 0% | (0 / 19) | 1.18% | (1 / 85) | |
| Drawer.js | 2.27% | (1 / 44) | 0% | (0 / 14) | 0% | (0 / 11) | 2.27% | (1 / 44) | |
| DropDownMenu.js | 5.88% | (1 / 17) | 0% | (0 / 2) | 0% | (0 / 6) | 5.88% | (1 / 17) | |
| DropTarget.js | 2.78% | (1 / 36) | 0% | (0 / 14) | 0% | (0 / 8) | 2.78% | (1 / 36) | |
| EmptyWidget.js | 9.09% | (1 / 11) | 0% | (0 / 2) | 0% | (0 / 3) | 9.09% | (1 / 11) | |
| FilterBar.js | 0.41% | (1 / 243) | 0% | (0 / 85) | 0% | (0 / 63) | 0.41% | (1 / 242) | |
| ForwardedInputEventHandler.js | 7.14% | (1 / 14) | 0% | (0 / 2) | 0% | (0 / 2) | 7.14% | (1 / 14) | |
| HistoryInput.js | 3.45% | (1 / 29) | 0% | (0 / 14) | 0% | (0 / 6) | 3.45% | (1 / 29) | |
| Infobar.js | 2.17% | (1 / 46) | 0% | (0 / 14) | 0% | (0 / 10) | 2.17% | (1 / 46) | |
| InplaceEditor.js | 8.94% | (11 / 123) | 0% | (0 / 80) | 0% | (0 / 26) | 8.94% | (11 / 123) | |
| InspectorView.js | 2.7% | (6 / 222) | 0% | (0 / 101) | 0% | (0 / 42) | 2.7% | (6 / 222) | |
| KeyboardShortcut.js | 2.53% | (2 / 79) | 0% | (0 / 71) | 0% | (0 / 18) | 2.53% | (2 / 79) | |
| ListWidget.js | 2.22% | (4 / 180) | 0% | (0 / 55) | 0% | (0 / 30) | 2.22% | (4 / 180) | |
| Panel.js | 3.77% | (2 / 53) | 0% | (0 / 8) | 0% | (0 / 24) | 3.77% | (2 / 53) | |
| Popover.js | 1.12% | (2 / 178) | 0% | (0 / 104) | 0% | (0 / 26) | 1.12% | (2 / 178) | |
| ProgressIndicator.js | 3.85% | (1 / 26) | 0% | (0 / 6) | 0% | (0 / 9) | 3.85% | (1 / 26) | |
| ResizerWidget.js | 1.61% | (1 / 62) | 0% | (0 / 18) | 0% | (0 / 22) | 1.61% | (1 / 62) | |
| RootView.js | 5.56% | (1 / 18) | 0% | (0 / 2) | 0% | (0 / 3) | 5.56% | (1 / 18) | |
| SearchableView.js | 0.37% | (1 / 269) | 0% | (0 / 108) | 0% | (0 / 54) | 0.37% | (1 / 269) | |
| Section.js | 1.67% | (1 / 60) | 0% | (0 / 18) | 0% | (0 / 13) | 1.67% | (1 / 60) | |
| SettingsUI.js | 10.53% | (4 / 38) | 0% | (0 / 8) | 0% | (0 / 9) | 10.53% | (4 / 38) | |
| ShortcutRegistry.js | 7.5% | (6 / 80) | 0% | (0 / 42) | 0% | (0 / 17) | 7.5% | (6 / 80) | |
| SidebarPane.js | 1.32% | (1 / 76) | 0% | (0 / 28) | 0% | (0 / 18) | 1.32% | (1 / 76) | |
| SidebarTreeElement.js | 1.85% | (1 / 54) | 0% | (0 / 20) | 0% | (0 / 16) | 1.85% | (1 / 54) | |
| SoftContextMenu.js | 0.5% | (1 / 202) | 0% | (0 / 122) | 0% | (0 / 22) | 0.5% | (1 / 199) | |
| SplitWidget.js | 1.06% | (4 / 377) | 0% | (0 / 222) | 0% | (0 / 58) | 1.06% | (4 / 377) | |
| StackView.js | 5.88% | (1 / 17) | 0% | (0 / 2) | 0% | (0 / 3) | 5.88% | (1 / 17) | |
| SuggestBox.js | 1.05% | (2 / 191) | 0% | (0 / 74) | 0% | (0 / 38) | 1.05% | (2 / 191) | |
| TabbedPane.js | 1.43% | (8 / 560) | 0% | (0 / 262) | 0% | (0 / 114) | 1.44% | (8 / 554) | |
| TextPrompt.js | 0.47% | (2 / 422) | 0% | (0 / 247) | 0% | (0 / 56) | 0.48% | (2 / 420) | |
| ThrottledWidget.js | 11.11% | (2 / 18) | 0% | (0 / 6) | 0% | (0 / 5) | 11.11% | (2 / 18) | |
| Toolbar.js | 3.82% | (13 / 340) | 0% | (0 / 119) | 0% | (0 / 83) | 3.82% | (13 / 340) | |
| Tooltip.js | 1.06% | (1 / 94) | 0% | (0 / 46) | 0% | (0 / 10) | 1.06% | (1 / 94) | |
| UIUtils.js | 2.5% | (21 / 841) | 0% | (0 / 427) | 0% | (0 / 109) | 2.5% | (21 / 840) | |
| ViewportControl.js | 0.7% | (2 / 284) | 0% | (0 / 148) | 0% | (0 / 42) | 0.7% | (2 / 284) | |
| Widget.js | 1.2% | (3 / 249) | 0% | (0 / 127) | 0% | (0 / 61) | 1.2% | (3 / 249) | |
| ZoomManager.js | 7.14% | (1 / 14) | 0% | (0 / 2) | 0% | (0 / 5) | 7.14% | (1 / 14) | |
| treeoutline.js | 1.27% | (6 / 472) | 0% | (0 / 378) | 0% | (0 / 84) | 1.27% | (6 / 472) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | 2 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.ActionRegistry = function() { /** @type {!Map.<string, !WebInspector.Action>} */ this._actionsById = new Map(); this._registerActions(); } WebInspector.ActionRegistry.prototype = { _registerActions: function() { self.runtime.extensions(WebInspector.ActionDelegate).forEach(registerExtension, this); /** * @param {!Runtime.Extension} extension * @this {WebInspector.ActionRegistry} */ function registerExtension(extension) { var actionId = extension.descriptor()["actionId"]; console.assert(actionId); console.assert(!this._actionsById.get(actionId)); this._actionsById.set(actionId, new WebInspector.Action(extension)); } }, /** * @return {!Array.<!WebInspector.Action>} */ availableActions: function() { return this.applicableActions(this._actionsById.keysArray(), WebInspector.context); }, /** * @param {!Array.<string>} actionIds * @param {!WebInspector.Context} context * @return {!Array.<!WebInspector.Action>} */ applicableActions: function(actionIds, context) { var extensions = []; actionIds.forEach(function(actionId) { var action = this._actionsById.get(actionId); if (action) extensions.push(action._extension); }, this); return context.applicableExtensions(extensions).valuesArray().map(extensionToAction.bind(this)); /** * @param {!Runtime.Extension} extension * @return {!WebInspector.Action} * @this {WebInspector.ActionRegistry} */ function extensionToAction(extension) { return this.action(extension.descriptor()["actionId"]); } }, /** * @param {string} actionId * @return {!WebInspector.Action} */ action: function(actionId) { var action = this._actionsById.get(actionId); console.assert(action, "No action found for actionId '" + actionId + "'"); return /** @type {!WebInspector.Action} */ (action); } } /** * @constructor * @extends {WebInspector.Object} * @param {!Runtime.Extension} extension */ WebInspector.Action = function(extension) { WebInspector.Object.call(this); this._extension = extension; this._enabled = true; this._toggled = false; this._title = this._extension.descriptor()["title"] || ""; this._statesCount = this._extension.descriptor()["states"] || 2; if (this._statesCount == 2) this._state = WebInspector.Action._ToggleState.Off; else this._state = "0"; } WebInspector.Action._ToggleState = { On: "on", Off: "off" } WebInspector.Action.Events = { Enabled: "Enabled", StateChanged: "StateChanged", TitleChanged: "TitleChanged", } WebInspector.Action.prototype = { /** * @return {number} */ statesCount: function() { return this._statesCount; }, /** * @return {string} */ id: function() { return this._extension.descriptor()["actionId"]; }, /** * @return {!Promise.<boolean>} */ execute: function() { return this._extension.instancePromise().then(handleAction.bind(this)); /** * @param {!Object} actionDelegate * @return {boolean} * @this {WebInspector.Action} */ function handleAction(actionDelegate) { var actionId = this._extension.descriptor()["actionId"]; var delegate = /** @type {!WebInspector.ActionDelegate} */(actionDelegate); return delegate.handleAction(WebInspector.context, actionId); } }, /** * @return {string} */ icon: function() { return this._extension.descriptor()["iconClass"] || ""; }, /** * @param {boolean} enabled */ setEnabled: function(enabled) { if (this._enabled === enabled) return; this._enabled = enabled; this.dispatchEventToListeners(WebInspector.Action.Events.Enabled, enabled); }, /** * @return {boolean} */ enabled: function() { return this._enabled; }, /** * @param {string} title */ setTitle: function(title) { if (this._title === title) return; this._title = title; this.dispatchEventToListeners(WebInspector.Action.Events.TitleChanged, this._title); }, /** * @return {string} */ category: function() { return this._extension.descriptor()["category"] || ""; }, /** * @return {string} */ tags: function() { return this._extension.descriptor()["tags"] || ""; }, /** * @return {string} */ title: function() { return this._title; }, /** * @return {string} */ state: function() { return this._state; }, /** * @param {string} newState */ setState: function(newState) { if (this._state === newState) return; var oldState = this._state; this._state = newState; this.dispatchEventToListeners(WebInspector.Action.Events.StateChanged, {oldState: oldState, newState: newState}) }, /** * @return {boolean} */ toggled: function() { if (this._statesCount !== 2) throw("Only used toggled when there are 2 states, otherwise, use state"); return this.state() === WebInspector.Action._ToggleState.On; }, /** * @param {boolean} toggled */ setToggled: function(toggled) { if (this._statesCount !== 2) throw("Only used toggled when there are 2 states, otherwise, use state"); this.setState(toggled ? WebInspector.Action._ToggleState.On : WebInspector.Action._ToggleState.Off); }, __proto__: WebInspector.Object.prototype } /** * @interface */ WebInspector.ActionDelegate = function() { } WebInspector.ActionDelegate.prototype = { /** * @param {!WebInspector.Context} context * @param {string} actionId * @return {boolean} */ handleAction: function(context, actionId) {} } /** @type {!WebInspector.ActionRegistry} */ WebInspector.actionRegistry; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {HTMLSpanElement}
*/
WebInspector.ColorSwatch = function()
{
}
/**
* @return {!WebInspector.ColorSwatch}
*/
WebInspector.ColorSwatch.create = function()
{
if (!WebInspector.ColorSwatch._constructor)
WebInspector.ColorSwatch._constructor = registerCustomElement("span", "color-swatch", WebInspector.ColorSwatch.prototype);
return /** @type {!WebInspector.ColorSwatch} */(new WebInspector.ColorSwatch._constructor());
}
WebInspector.ColorSwatch.prototype = {
/**
* @return {!WebInspector.Color} color
*/
color: function()
{
return this._color;
},
/**
* @param {string} colorText
*/
setColorText: function(colorText)
{
this._color = WebInspector.Color.parse(colorText);
console.assert(this._color, "Color text could not be parsed.");
this._format = this._color.format();
this._colorValueElement.textContent = this._color.asString(this._format);
this._swatchInner.style.backgroundColor = colorText;
},
/**
* @return {!WebInspector.Color.Format}
*/
format: function()
{
return this._format;
},
/**
* @param {!WebInspector.Color.Format} format
*/
setFormat: function(format)
{
this._format = format;
this._colorValueElement.textContent = this._color.asString(this._format);
},
toggleNextFormat: function()
{
do {
this._format = WebInspector.ColorSwatch._nextColorFormat(this._color, this._format);
var currentValue = this._color.asString(this._format);
} while (currentValue === this._colorValueElement.textContent);
this._colorValueElement.textContent = currentValue;
},
/**
* @return {!Element}
*/
iconElement: function()
{
return this._iconElement;
},
createdCallback: function()
{
var root = WebInspector.createShadowRootWithCoreStyles(this, "ui/colorSwatch.css");
this._iconElement = root.createChild("span", "color-swatch");
this._iconElement.title = WebInspector.UIString("Shift-click to change color format");
this._swatchInner = this._iconElement.createChild("span", "color-swatch-inner");
this._swatchInner.addEventListener("dblclick", consumeEvent, false);
this._swatchInner.addEventListener("mousedown", consumeEvent, false);
this._swatchInner.addEventListener("click", this._handleClick.bind(this), true);
root.createChild("content");
this._colorValueElement = this.createChild("span");
this.setColorText("white");
},
/**
* @param {!Event} event
*/
_handleClick: function(event)
{
if (!event.shiftKey)
return;
event.target.parentNode.parentNode.host.toggleNextFormat();
event.consume(true);
},
__proto__: HTMLSpanElement.prototype
}
/**
* @param {!WebInspector.Color} color
* @param {string} curFormat
*/
WebInspector.ColorSwatch._nextColorFormat = function(color, curFormat)
{
// The format loop is as follows:
// * original
// * rgb(a)
// * hsl(a)
// * nickname (if the color has a nickname)
// * if the color is simple:
// - shorthex (if has short hex)
// - hex
var cf = WebInspector.Color.Format;
switch (curFormat) {
case cf.Original:
return !color.hasAlpha() ? cf.RGB : cf.RGBA;
case cf.RGB:
case cf.RGBA:
return !color.hasAlpha() ? cf.HSL : cf.HSLA;
case cf.HSL:
case cf.HSLA:
if (color.nickname())
return cf.Nickname;
if (!color.hasAlpha())
return color.canBeShortHex() ? cf.ShortHEX : cf.HEX;
else
return cf.Original;
case cf.ShortHEX:
return cf.HEX;
case cf.HEX:
return cf.Original;
case cf.Nickname:
if (!color.hasAlpha())
return color.canBeShortHex() ? cf.ShortHEX : cf.HEX;
else
return cf.Original;
default:
return cf.RGBA;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.Context = function() { this._flavors = new Map(); this._eventDispatchers = new Map(); } /** * @enum {string} */ WebInspector.Context.Events = { FlavorChanged: "FlavorChanged" } WebInspector.Context.prototype = { /** * @param {function(new:T, ...)} flavorType * @param {?T} flavorValue * @template T */ setFlavor: function(flavorType, flavorValue) { var value = this._flavors.get(flavorType) || null; if (value === flavorValue) return; if (flavorValue) this._flavors.set(flavorType, flavorValue); else this._flavors.remove(flavorType); this._dispatchFlavorChange(flavorType, flavorValue); }, /** * @param {function(new:T, ...)} flavorType * @param {?T} flavorValue * @template T */ _dispatchFlavorChange: function(flavorType, flavorValue) { var dispatcher = this._eventDispatchers.get(flavorType); if (!dispatcher) return; dispatcher.dispatchEventToListeners(WebInspector.Context.Events.FlavorChanged, flavorValue); }, /** * @param {function(new:Object, ...)} flavorType * @param {function(!WebInspector.Event)} listener * @param {!Object=} thisObject */ addFlavorChangeListener: function(flavorType, listener, thisObject) { var dispatcher = this._eventDispatchers.get(flavorType); if (!dispatcher) { dispatcher = new WebInspector.Object(); this._eventDispatchers.set(flavorType, dispatcher); } dispatcher.addEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject); }, /** * @param {function(new:Object, ...)} flavorType * @param {function(!WebInspector.Event)} listener * @param {!Object=} thisObject */ removeFlavorChangeListener: function(flavorType, listener, thisObject) { var dispatcher = this._eventDispatchers.get(flavorType); if (!dispatcher) return; dispatcher.removeEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject); if (!dispatcher.hasEventListeners(WebInspector.Context.Events.FlavorChanged)) this._eventDispatchers.remove(flavorType); }, /** * @param {function(new:T, ...)} flavorType * @return {?T} * @template T */ flavor: function(flavorType) { return this._flavors.get(flavorType) || null; }, /** * @return {!Set.<function(new:Object, ...)>} */ flavors: function() { return new Set(this._flavors.keys()); }, /** * @param {!Array.<!Runtime.Extension>} extensions * @return {!Set.<!Runtime.Extension>} */ applicableExtensions: function(extensions) { var targetExtensionSet = new Set(); var availableFlavors = this.flavors(); extensions.forEach(function(extension) { if (self.runtime.isExtensionApplicableToContextTypes(extension, availableFlavors)) targetExtensionSet.add(extension); }); return targetExtensionSet; } } WebInspector.context = new WebInspector.Context(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | 2 1 1 1 1 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.ContextMenu} topLevelMenu
* @param {string} type
* @param {string=} label
* @param {boolean=} disabled
* @param {boolean=} checked
*/
WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
{
this._type = type;
this._label = label;
this._disabled = disabled;
this._checked = checked;
this._contextMenu = topLevelMenu;
if (type === "item" || type === "checkbox")
this._id = topLevelMenu._nextId();
}
WebInspector.ContextMenuItem.prototype = {
/**
* @return {number}
*/
id: function()
{
return this._id;
},
/**
* @return {string}
*/
type: function()
{
return this._type;
},
/**
* @return {boolean}
*/
isEnabled: function()
{
return !this._disabled;
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._disabled = !enabled;
},
/**
* @return {!InspectorFrontendHostAPI.ContextMenuDescriptor}
*/
_buildDescriptor: function()
{
switch (this._type) {
case "item":
var result = { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
if (this._customElement)
result.element = this._customElement;
if (this._shortcut)
result.shortcut = this._shortcut;
return result;
case "separator":
return { type: "separator" };
case "checkbox":
return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
}
throw new Error("Invalid item type:" + this._type);
},
/**
* @param {string} shortcut
*/
setShortcut: function(shortcut)
{
this._shortcut = shortcut;
}
}
/**
* @constructor
* @extends {WebInspector.ContextMenuItem}
* @param {!WebInspector.ContextMenu} topLevelMenu
* @param {string=} label
* @param {boolean=} disabled
*/
WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
{
WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);
/** @type {!Array.<!WebInspector.ContextMenuItem>} */
this._items = [];
}
WebInspector.ContextSubMenuItem.prototype = {
/**
* @param {string} label
* @param {function(?)} handler
* @param {boolean=} disabled
* @return {!WebInspector.ContextMenuItem}
*/
appendItem: function(label, handler, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},
/**
* @param {!Element} element
* @return {!WebInspector.ContextMenuItem}
*/
appendCustomItem: function(element)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", "<custom>");
item._customElement = element;
this._pushItem(item);
return item;
},
/**
* @param {string} actionId
* @param {string=} label
* @return {!WebInspector.ContextMenuItem}
*/
appendAction: function(actionId, label)
{
var action = WebInspector.actionRegistry.action(actionId);
if (!label)
label = action.title();
var result = this.appendItem(label, action.execute.bind(action));
var shortcut = WebInspector.shortcutRegistry.shortcutTitleForAction(actionId);
if (shortcut)
result.setShortcut(shortcut);
return result;
},
/**
* @param {string} label
* @param {boolean=} disabled
* @return {!WebInspector.ContextSubMenuItem}
*/
appendSubMenuItem: function(label, disabled)
{
var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
this._pushItem(item);
return item;
},
/**
* @param {string} label
* @param {function()} handler
* @param {boolean=} checked
* @param {boolean=} disabled
* @return {!WebInspector.ContextMenuItem}
*/
appendCheckboxItem: function(label, handler, checked, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},
appendSeparator: function()
{
if (this._items.length)
this._pendingSeparator = true;
},
/**
* @param {!WebInspector.ContextMenuItem} item
*/
_pushItem: function(item)
{
if (this._pendingSeparator) {
this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
delete this._pendingSeparator;
}
this._items.push(item);
},
/**
* @return {boolean}
*/
isEmpty: function()
{
return !this._items.length;
},
/**
* @override
* @return {!InspectorFrontendHostAPI.ContextMenuDescriptor}
*/
_buildDescriptor: function()
{
var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
for (var i = 0; i < this._items.length; ++i)
result.subItems.push(this._items[i]._buildDescriptor());
return result;
},
/**
* @param {string} location
*/
appendItemsAtLocation: function(location)
{
/**
* @param {!WebInspector.ContextSubMenuItem} menu
* @param {!Runtime.Extension} extension
*/
function appendExtension(menu, extension)
{
var subMenuId = extension.descriptor()["subMenuId"];
if (subMenuId) {
var subMenuItem = menu.appendSubMenuItem(extension.title(WebInspector.platform()));
subMenuItem.appendItemsAtLocation(subMenuId);
} else {
menu.appendAction(extension.descriptor()["actionId"]);
}
}
// Hard-coded named groups for elements to maintain generic order.
var groupWeights = ["new", "open", "clipboard", "navigate", "footer"];
/** @type {!Map.<string, !Array.<!Runtime.Extension>>} */
var groups = new Map();
var extensions = self.runtime.extensions("context-menu-item");
for (var extension of extensions) {
var itemLocation = extension.descriptor()["location"] || "";
if (!itemLocation.startsWith(location + "/"))
continue;
var itemGroup = itemLocation.substr(location.length + 1);
if (!itemGroup || itemGroup.includes("/"))
continue;
var group = groups.get(itemGroup);
if (!group) {
group = [];
groups.set(itemGroup, group);
if (groupWeights.indexOf(itemGroup) === -1)
groupWeights.splice(4, 0, itemGroup);
}
group.push(extension);
}
for (var groupName of groupWeights) {
var group = groups.get(groupName);
if (!group)
continue;
group.forEach(appendExtension.bind(null, this));
this.appendSeparator();
}
},
__proto__: WebInspector.ContextMenuItem.prototype
}
/**
* @constructor
* @extends {WebInspector.ContextSubMenuItem}
* @param {!Event} event
* @param {boolean=} useSoftMenu
* @param {number=} x
* @param {number=} y
*/
WebInspector.ContextMenu = function(event, useSoftMenu, x, y)
{
WebInspector.ContextSubMenuItem.call(this, this, "");
/** @type {!Array.<!Promise.<!Array.<!WebInspector.ContextMenu.Provider>>>} */
this._pendingPromises = [];
/** @type {!Array<!Object>} */
this._pendingTargets = [];
this._event = event;
this._useSoftMenu = !!useSoftMenu;
this._x = x === undefined ? event.x : x;
this._y = y === undefined ? event.y : y;
this._handlers = {};
this._id = 0;
}
WebInspector.ContextMenu.initialize = function()
{
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetUseSoftMenu, setUseSoftMenu);
/**
* @param {!WebInspector.Event} event
*/
function setUseSoftMenu(event)
{
WebInspector.ContextMenu._useSoftMenu = /** @type {boolean} */ (event.data);
}
}
/**
* @param {!Document} doc
*/
WebInspector.ContextMenu.installHandler = function(doc)
{
doc.body.addEventListener("contextmenu", handler, false);
/**
* @param {!Event} event
*/
function handler(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(/** @type {!Object} */ (event.deepElementFromPoint()));
contextMenu.show();
}
}
WebInspector.ContextMenu.prototype = {
/**
* @return {number}
*/
_nextId: function()
{
return this._id++;
},
show: function()
{
Promise.all(this._pendingPromises).then(populateAndShow.bind(this));
WebInspector.ContextMenu._pendingMenu = this;
/**
* @param {!Array.<!Array.<!WebInspector.ContextMenu.Provider>>} appendCallResults
* @this {WebInspector.ContextMenu}
*/
function populateAndShow(appendCallResults)
{
if (WebInspector.ContextMenu._pendingMenu !== this)
return;
delete WebInspector.ContextMenu._pendingMenu;
for (var i = 0; i < appendCallResults.length; ++i) {
var providers = appendCallResults[i];
var target = this._pendingTargets[i];
for (var j = 0; j < providers.length; ++j) {
var provider = /** @type {!WebInspector.ContextMenu.Provider} */ (providers[j]);
this.appendSeparator();
provider.appendApplicableItems(this._event, this, target);
this.appendSeparator();
}
}
this._pendingPromises = [];
this._pendingTargets = [];
this._innerShow();
}
this._event.consume(true);
},
discard: function()
{
if (this._softMenu)
this._softMenu.discard();
},
_innerShow: function()
{
var menuObject = this._buildDescriptors();
WebInspector._contextMenu = this;
if (this._useSoftMenu || WebInspector.ContextMenu._useSoftMenu || InspectorFrontendHost.isHostedMode()) {
this._softMenu = new WebInspector.SoftContextMenu(menuObject, this._itemSelected.bind(this));
this._softMenu.show(this._event.target.ownerDocument, this._x, this._y);
} else {
InspectorFrontendHost.showContextMenuAtPoint(this._x, this._y, menuObject, this._event.target.ownerDocument);
/**
* @this {WebInspector.ContextMenu}
*/
function listenToEvents()
{
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this);
}
// showContextMenuAtPoint call above synchronously issues a clear event for previous context menu (if any),
// so we skip it before subscribing to the clear event.
setImmediate(listenToEvents.bind(this));
}
},
/**
* @param {number} id
* @param {function(?)} handler
*/
_setHandler: function(id, handler)
{
if (handler)
this._handlers[id] = handler;
},
/**
* @return {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>}
*/
_buildDescriptors: function()
{
var result = [];
for (var i = 0; i < this._items.length; ++i)
result.push(this._items[i]._buildDescriptor());
return result;
},
/**
* @param {!WebInspector.Event} event
*/
_onItemSelected: function(event)
{
this._itemSelected(/** @type {string} */ (event.data));
},
/**
* @param {string} id
*/
_itemSelected: function(id)
{
if (this._handlers[id])
this._handlers[id].call(this);
this._menuCleared();
},
_menuCleared: function()
{
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this);
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this);
},
/**
* @param {!Object} target
*/
appendApplicableItems: function(target)
{
this._pendingPromises.push(self.runtime.instancesPromise(WebInspector.ContextMenu.Provider, target));
this._pendingTargets.push(target);
},
__proto__: WebInspector.ContextSubMenuItem.prototype
}
/**
* @interface
*/
WebInspector.ContextMenu.Provider = function() {
}
WebInspector.ContextMenu.Provider.prototype = {
/**
* @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target) { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 2 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} mimeType
* @param {boolean} stripExtraWhitespace
*/
WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
{
this._mimeType = mimeType;
this._stripExtraWhitespace = stripExtraWhitespace;
}
WebInspector.DOMSyntaxHighlighter.prototype = {
/**
* @param {string} content
* @param {string} className
* @return {!Element}
*/
createSpan: function(content, className)
{
var span = createElement("span");
span.className = "cm-" + className;
if (this._stripExtraWhitespace && className !== "whitespace")
content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, "");
span.createTextChild(content);
return span;
},
/**
* @param {!Element} node
* @return {!Promise.<undefined>}
*/
syntaxHighlightNode: function(node)
{
var lines = node.textContent.split("\n");
var plainTextStart;
var line;
return self.runtime.instancePromise(WebInspector.TokenizerFactory).then(processTokens.bind(this));
/**
* @param {!WebInspector.TokenizerFactory} tokenizerFactory
* @this {WebInspector.DOMSyntaxHighlighter}
*/
function processTokens(tokenizerFactory)
{
node.removeChildren();
var tokenize = tokenizerFactory.createTokenizer(this._mimeType);
for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
line = lines[i];
plainTextStart = 0;
tokenize(line, processToken.bind(this));
if (plainTextStart < line.length) {
var plainText = line.substring(plainTextStart, line.length);
node.createTextChild(plainText);
}
if (i < lines.length - 1)
node.createTextChild("\n");
}
}
/**
* @param {string} token
* @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
* @this {WebInspector.DOMSyntaxHighlighter}
*/
function processToken(token, tokenType, column, newColumn)
{
if (!tokenType)
return;
if (column > plainTextStart) {
var plainText = line.substring(plainTextStart, column);
node.createTextChild(plainText);
}
node.appendChild(this.createSpan(token, tokenType));
plainTextStart = newColumn;
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Widget}
*/
WebInspector.Dialog = function()
{
WebInspector.Widget.call(this, true);
this.markAsRoot();
this.registerRequiredCSS("ui/dialog.css");
this.contentElement.createChild("content");
this.contentElement.tabIndex = 0;
this.contentElement.addEventListener("focus", this._onFocus.bind(this), false);
this.contentElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._wrapsContent = false;
this._dimmed = false;
/** @type {!Map<!HTMLElement, number>} */
this._tabIndexMap = new Map();
}
/**
* TODO(dgozman): remove this method (it's only used for shortcuts handling).
* @return {boolean}
*/
WebInspector.Dialog.hasInstance = function()
{
return !!WebInspector.Dialog._instance;
}
WebInspector.Dialog.prototype = {
/**
* @override
*/
show: function()
{
if (WebInspector.Dialog._instance)
WebInspector.Dialog._instance.detach();
WebInspector.Dialog._instance = this;
var document = /** @type {!Document} */ (WebInspector.Dialog._modalHostView.element.ownerDocument);
this._disableTabIndexOnElements(document);
this._glassPane = new WebInspector.GlassPane(document, this._dimmed);
this._glassPane.element.addEventListener("click", this._onGlassPaneClick.bind(this), false);
WebInspector.GlassPane.DefaultFocusedViewStack.push(this);
WebInspector.Widget.prototype.show.call(this, this._glassPane.element);
this._position();
this.focus();
},
/**
* @override
*/
detach: function()
{
WebInspector.Widget.prototype.detach.call(this);
WebInspector.GlassPane.DefaultFocusedViewStack.pop();
this._glassPane.dispose();
delete this._glassPane;
this._restoreTabIndexOnElements();
delete WebInspector.Dialog._instance;
},
addCloseButton: function()
{
var closeButton = this.contentElement.createChild("div", "dialog-close-button", "dt-close-button");
closeButton.gray = true;
closeButton.addEventListener("click", this.detach.bind(this, false), false);
},
/**
* @param {!Size} size
*/
setMaxSize: function(size)
{
this._maxSize = size;
},
/**
* @param {boolean} wraps
*/
setWrapsContent: function(wraps)
{
this.element.classList.toggle("wraps-content", wraps);
this._wrapsContent = wraps;
},
/**
* @param {boolean} dimmed
*/
setDimmed: function(dimmed)
{
this._dimmed = dimmed;
},
contentResized: function()
{
if (this._wrapsContent)
this._position();
},
/**
* @param {!Document} document
*/
_disableTabIndexOnElements: function(document)
{
this._tabIndexMap.clear();
for (var node = document; node; node = node.traverseNextNode(document)) {
if (node instanceof HTMLElement) {
var element = /** @type {!HTMLElement} */ (node);
var tabIndex = element.tabIndex;
if (tabIndex >= 0) {
this._tabIndexMap.set(element, tabIndex);
element.tabIndex = -1;
}
}
}
},
_restoreTabIndexOnElements: function()
{
for (var element of this._tabIndexMap.keys())
element.tabIndex = /** @type {number} */(this._tabIndexMap.get(element));
this._tabIndexMap.clear();
},
/**
* @param {!Event} event
*/
_onFocus: function(event)
{
this.focus();
},
/**
* @param {!Event} event
*/
_onGlassPaneClick: function(event)
{
if (!this.element.isSelfOrAncestor(/** @type {?Node} */ (event.target)))
this.detach();
},
_position: function()
{
var container = WebInspector.Dialog._modalHostView.element;
var width = container.offsetWidth - 10;
var height = container.offsetHeight- 10;
if (this._wrapsContent) {
width = Math.min(width, this.contentElement.offsetWidth);
height = Math.min(height, this.contentElement.offsetHeight);
}
if (this._maxSize) {
width = Math.min(width, this._maxSize.width);
height = Math.min(height, this._maxSize.height);
}
var positionX = (container.offsetWidth - width) / 2;
positionX = Number.constrain(positionX, 0, container.offsetWidth - width);
var positionY = (container.offsetHeight - height) / 2;
positionY = Number.constrain(positionY, 0, container.offsetHeight - height);
this.element.style.width = width + "px";
this.element.style.height = height + "px";
this.element.positionAt(positionX, positionY, container);
},
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
event.consume(true);
this.detach();
}
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
var children = this.children();
if (children.length)
return children[0].defaultFocusedElement();
return this.element;
},
__proto__: WebInspector.Widget.prototype
};
/** @type {?WebInspector.Widget} */
WebInspector.Dialog._modalHostView = null;
/**
* @param {!WebInspector.Widget} view
*/
WebInspector.Dialog.setModalHostView = function(view)
{
WebInspector.Dialog._modalHostView = view;
};
/**
* FIXME: make utility method in Dialog, so clients use it instead of this getter.
* Method should be like Dialog.showModalElement(position params, reposition callback).
* @return {?WebInspector.Widget}
*/
WebInspector.Dialog.modalHostView = function()
{
return WebInspector.Dialog._modalHostView;
};
WebInspector.Dialog.modalHostRepositioned = function()
{
if (WebInspector.Dialog._instance)
WebInspector.Dialog._instance._position();
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.SplitWidget} splitWidget
*/
WebInspector.Drawer = function(splitWidget)
{
WebInspector.VBox.call(this);
this.element.id = "drawer-contents";
this._splitWidget = splitWidget;
splitWidget.hideDefaultResizer();
splitWidget.setSidebarWidget(this);
this.setMinimumSize(0, 27);
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.element.id = "drawer-tabbed-pane";
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
var toolbar = new WebInspector.Toolbar("drawer-close-toolbar");
var closeButton = new WebInspector.ToolbarButton(WebInspector.UIString("Close drawer"), "delete-toolbar-item");
closeButton.addEventListener("click", this.closeDrawer.bind(this));
toolbar.appendToolbarItem(closeButton);
this._tabbedPane.appendAfterTabStrip(toolbar.element);
this._extensibleTabbedPaneController = new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "drawer-view");
this._extensibleTabbedPaneController.enableMoreTabsButton();
splitWidget.installResizer(this._tabbedPane.headerElement());
this._lastSelectedViewSetting = WebInspector.settings.createSetting("WebInspector.Drawer.lastSelectedView", "console");
this._tabbedPane.show(this.element);
}
WebInspector.Drawer.prototype = {
/**
* @param {string} id
* @param {boolean=} immediate
* @return {!Promise.<?WebInspector.Widget>}
*/
showView: function(id, immediate)
{
this._innerShow(immediate);
WebInspector.userMetrics.drawerShown(id);
return this._extensibleTabbedPaneController.showTab(id);
},
showDrawer: function()
{
this._innerShow();
},
wasShown: function()
{
var id = this._lastSelectedViewSetting.get();
if (!this._firstTabSelected && this._tabbedPane.hasTab(id))
this.showView(id);
},
willHide: function()
{
},
/**
* @param {boolean=} immediate
*/
_innerShow: function(immediate)
{
if (this.isShowing())
return;
this._splitWidget.showBoth(!immediate);
if (this._visibleView())
this._visibleView().focus();
},
closeDrawer: function()
{
if (!this.isShowing())
return;
WebInspector.restoreFocusFromElement(this.element);
this._splitWidget.hideSidebar(true);
},
/**
* @return {?WebInspector.Widget} view
*/
_visibleView: function()
{
return this._tabbedPane.visibleView;
},
/**
* @param {!WebInspector.Event} event
*/
_tabSelected: function(event)
{
this._firstTabSelected = true;
var tabId = this._tabbedPane.selectedTabId;
if (tabId && event.data["isUserGesture"])
this._lastSelectedViewSetting.set(tabId);
},
/**
* @return {?string}
*/
selectedViewId: function()
{
return this._tabbedPane.selectedTabId;
},
initialPanelShown: function()
{
this._initialPanelWasShown = true;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Element} element
*/
WebInspector.DropDownMenu = function(element)
{
/** @type {!Array.<!WebInspector.DropDownMenu.Item>} */
this._items = [];
element.addEventListener("mousedown", this._onMouseDown.bind(this));
}
/** @typedef {{id: string, title: string}} */
WebInspector.DropDownMenu.Item;
/** @enum {string} */
WebInspector.DropDownMenu.Events = {
ItemSelected: "ItemSelected"
}
WebInspector.DropDownMenu.prototype = {
/**
* @param {!Event} event
*/
_onMouseDown: function(event)
{
if (event.which !== 1)
return;
var menu = new WebInspector.ContextMenu(event);
for (var item of this._items)
menu.appendCheckboxItem(item.title, this._itemHandler.bind(this, item.id), item.id === this._selectedItemId);
menu.show();
},
/**
* @param {string} id
*/
_itemHandler: function(id)
{
this.dispatchEventToListeners(WebInspector.DropDownMenu.Events.ItemSelected, id);
},
/**
* @param {string} id
* @param {string} title
*/
addItem: function(id, title)
{
this._items.push({id: id, title: title});
},
/**
* @param {string} id
*/
selectItem: function(id)
{
this._selectedItemId = id;
},
clear: function()
{
this._items = [];
delete this._selectedItemId;
},
__proto__: WebInspector.Object.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!Element} element
* @param {!Array.<string>} transferTypes
* @param {string} messageText
* @param {function(!DataTransfer)} handleDrop
*/
WebInspector.DropTarget = function(element, transferTypes, messageText, handleDrop)
{
element.addEventListener("dragenter", this._onDragEnter.bind(this), true);
element.addEventListener("dragover", this._onDragOver.bind(this), true);
this._element = element;
this._transferTypes = transferTypes;
this._messageText = messageText;
this._handleDrop = handleDrop;
this._enabled = true;
}
WebInspector.DropTarget.Types = {
Files: "Files",
URIList: "text/uri-list"
}
WebInspector.DropTarget.prototype = {
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._enabled = enabled;
},
/**
* @param {!Event} event
*/
_onDragEnter: function(event)
{
if (this._enabled && this._hasMatchingType(event))
event.consume(true);
},
/**
* @param {!Event} event
* @return {boolean}
*/
_hasMatchingType: function(event)
{
for (var type of this._transferTypes) {
if (event.dataTransfer.types.indexOf(type) !== -1)
return true;
}
return false;
},
/**
* @param {!Event} event
*/
_onDragOver: function(event)
{
if (!this._enabled || !this._hasMatchingType(event))
return;
event.dataTransfer.dropEffect = "copy";
event.consume(true);
if (this._dragMaskElement)
return;
this._dragMaskElement = this._element.createChild("div", "");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(this._dragMaskElement, "ui/dropTarget.css");
shadowRoot.createChild("div", "drop-target-message").textContent = this._messageText;
this._dragMaskElement.addEventListener("drop", this._onDrop.bind(this), true);
this._dragMaskElement.addEventListener("dragleave", this._onDragLeave.bind(this), true);
},
/**
* @param {!Event} event
*/
_onDrop: function(event)
{
event.consume(true);
this._removeMask();
if (this._enabled)
this._handleDrop(event.dataTransfer);
},
/**
* @param {!Event} event
*/
_onDragLeave: function(event)
{
event.consume(true);
this._removeMask();
},
_removeMask: function()
{
this._dragMaskElement.remove();
delete this._dragMaskElement;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.EmptyWidget = function(text)
{
WebInspector.VBox.call(this);
this.registerRequiredCSS("ui/emptyWidget.css");
this.element.classList.add("empty-view");
this.textElement = this.element.createChild("span");
this._text = text;
}
WebInspector.EmptyWidget.prototype = {
wasShown: function()
{
this.textElement.textContent = this._text;
},
set text(text)
{
this._text = text;
if (this.isShowing())
this.textElement.textContent = this._text;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.HBox}
* @param {string} name
* @param {boolean=} visibleByDefault
*/
WebInspector.FilterBar = function(name, visibleByDefault)
{
WebInspector.HBox.call(this);
this.registerRequiredCSS("ui/filter.css");
this._filtersShown = false;
this._enabled = true;
this.element.classList.add("filter-bar");
this._filterButton = new WebInspector.ToolbarButton(WebInspector.UIString("Filter"), "filter-toolbar-item");
this._filterButton.addEventListener("click", this._handleFilterButtonClick, this);
this._filters = [];
this._stateSetting = WebInspector.settings.createSetting("filterBar-" + name + "-toggled", !!visibleByDefault);
this._setState(this._stateSetting.get());
}
WebInspector.FilterBar.FilterBarState = {
Inactive : "inactive",
Active : "active",
Shown : "on"
};
WebInspector.FilterBar.Events = {
Toggled: "Toggled"
};
WebInspector.FilterBar.prototype = {
/**
* @return {!WebInspector.ToolbarButton}
*/
filterButton: function()
{
return this._filterButton;
},
/**
* @param {!WebInspector.FilterUI} filter
*/
addFilter: function(filter)
{
this._filters.push(filter);
this.element.appendChild(filter.element());
filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
this._updateFilterButton();
},
setEnabled: function(enabled)
{
this._enabled = enabled;
this._filterButton.setEnabled(enabled);
this._updateFilterBar();
},
forceShowFilterBar: function()
{
this._alwaysShowFilters = true;
this._updateFilterBar();
},
/**
* @override
*/
wasShown: function()
{
this._updateFilterBar();
},
/**
* @param {!WebInspector.Event} event
*/
_filterChanged: function(event)
{
this._updateFilterButton();
},
/**
* @return {string}
*/
_filterBarState: function()
{
if (this._filtersShown)
return WebInspector.FilterBar.FilterBarState.Shown;
var isActive = false;
for (var i = 0; i < this._filters.length; ++i) {
if (this._filters[i].isActive())
return WebInspector.FilterBar.FilterBarState.Active;
}
return WebInspector.FilterBar.FilterBarState.Inactive;
},
_updateFilterBar: function()
{
var visible = this._alwaysShowFilters || (this._filtersShown && this._enabled);
this.element.classList.toggle("hidden", !visible);
if (visible) {
for (var i = 0; i < this._filters.length; ++i) {
if (this._filters[i] instanceof WebInspector.TextFilterUI) {
var textFilterUI = /** @type {!WebInspector.TextFilterUI} */ (this._filters[i]);
textFilterUI.focus();
}
}
}
this.invalidateSize();
},
_updateFilterButton: function()
{
this._filterButton.setState(this._filterBarState());
},
/**
* @param {!WebInspector.Event} event
*/
_handleFilterButtonClick: function(event)
{
this._setState(!this._filtersShown);
},
/**
* @param {boolean} filtersShown
*/
_setState: function(filtersShown)
{
if (this._filtersShown === filtersShown)
return;
this._filtersShown = filtersShown;
if (this._stateSetting)
this._stateSetting.set(filtersShown);
this._updateFilterButton();
this._updateFilterBar();
this.dispatchEventToListeners(WebInspector.FilterBar.Events.Toggled);
},
clear: function()
{
this.element.removeChildren();
this._filters = [];
this._updateFilterButton();
},
__proto__: WebInspector.HBox.prototype
}
/**
* @interface
* @extends {WebInspector.EventTarget}
*/
WebInspector.FilterUI = function()
{
}
WebInspector.FilterUI.Events = {
FilterChanged: "FilterChanged"
}
WebInspector.FilterUI.prototype = {
/**
* @return {boolean}
*/
isActive: function() { },
/**
* @return {!Element}
*/
element: function() { }
}
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.FilterUI}
* @implements {WebInspector.SuggestBoxDelegate}
* @param {boolean=} supportRegex
*/
WebInspector.TextFilterUI = function(supportRegex)
{
this._supportRegex = !!supportRegex;
this._regex = null;
this._filterElement = createElement("div");
this._filterElement.className = "filter-text-filter";
this._filterInputElement = /** @type {!HTMLInputElement} */ (this._filterElement.createChild("input", "filter-input-field"));
this._filterInputElement.placeholder = WebInspector.UIString("Filter");
this._filterInputElement.id = "filter-input-field";
this._filterInputElement.addEventListener("mousedown", this._onFilterFieldManualFocus.bind(this), false); // when the search field is manually selected
this._filterInputElement.addEventListener("input", this._onInput.bind(this), false);
this._filterInputElement.addEventListener("change", this._onChange.bind(this), false);
this._filterInputElement.addEventListener("keydown", this._onInputKeyDown.bind(this), true);
this._filterInputElement.addEventListener("blur", this._onBlur.bind(this), true);
/** @type {?WebInspector.TextFilterUI.SuggestionBuilder} */
this._suggestionBuilder = null;
this._suggestBox = new WebInspector.SuggestBox(this);
if (this._supportRegex) {
this._filterElement.classList.add("supports-regex");
var label = createCheckboxLabel(WebInspector.UIString("Regex"));
this._regexCheckBox = label.checkboxElement;
this._regexCheckBox.id = "text-filter-regex";
this._regexCheckBox.addEventListener("change", this._onInput.bind(this), false);
this._filterElement.appendChild(label);
this._regexLabel = this._filterElement.textElement;
}
}
WebInspector.TextFilterUI.prototype = {
/**
* @override
* @return {boolean}
*/
isActive: function()
{
return !!this._filterInputElement.value;
},
/**
* @override
* @return {!Element}
*/
element: function()
{
return this._filterElement;
},
/**
* @return {boolean}
*/
isRegexChecked: function()
{
return this._supportRegex ? this._regexCheckBox.checked : false;
},
/**
* @return {string}
*/
value: function()
{
return this._filterInputElement.value;
},
/**
* @param {string} value
*/
setValue: function(value)
{
this._filterInputElement.value = value;
this._valueChanged(false);
},
/**
* @return {?RegExp}
*/
regex: function()
{
return this._regex;
},
/**
* @param {!Event} event
*/
_onFilterFieldManualFocus: function(event)
{
WebInspector.setCurrentFocusElement(/** @type {?Node} */ (event.target));
},
/**
* @param {!Event} event
*/
_onBlur: function(event)
{
this._cancelSuggestion();
},
_cancelSuggestion: function()
{
if (this._suggestionBuilder && this._suggestBox.visible) {
this._suggestionBuilder.unapplySuggestion(this._filterInputElement);
this._suggestBox.hide();
}
},
_onInput: function()
{
this._valueChanged(true);
},
_onChange: function()
{
this._valueChanged(false);
},
focus: function()
{
this._filterInputElement.focus();
},
/**
* @param {?WebInspector.TextFilterUI.SuggestionBuilder} suggestionBuilder
*/
setSuggestionBuilder: function(suggestionBuilder)
{
this._cancelSuggestion();
this._suggestionBuilder = suggestionBuilder;
},
_updateSuggestions: function()
{
if (!this._suggestionBuilder)
return;
if (this.isRegexChecked()) {
if (this._suggestBox.visible())
this._suggestBox.hide();
return;
}
var suggestions = this._suggestionBuilder.buildSuggestions(this._filterInputElement);
if (suggestions && suggestions.length) {
if (this._suppressSuggestion)
delete this._suppressSuggestion;
else
this._suggestionBuilder.applySuggestion(this._filterInputElement, suggestions[0], true);
var anchorBox = this._filterInputElement.boxInWindow().relativeTo(new AnchorBox(-3, 0));
this._suggestBox.updateSuggestions(anchorBox, suggestions.map(item => ({title: item})), 0, true, "");
} else {
this._suggestBox.hide();
}
},
/**
* @param {boolean} showSuggestions
*/
_valueChanged: function(showSuggestions)
{
if (showSuggestions)
this._updateSuggestions();
else
this._suggestBox.hide();
var filterQuery = this.value();
this._regex = null;
this._filterInputElement.classList.remove("filter-text-invalid");
if (filterQuery) {
if (this.isRegexChecked()) {
try {
this._regex = new RegExp(filterQuery, "i");
} catch (e) {
this._filterInputElement.classList.add("filter-text-invalid");
}
} else {
this._regex = createPlainTextSearchRegex(filterQuery, "i");
}
}
this._dispatchFilterChanged();
},
_dispatchFilterChanged: function()
{
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
/**
* @param {!Event} event
* @return {boolean}
*/
_onInputKeyDown: function(event)
{
var handled = false;
if (event.keyIdentifier === "U+0008") { // Backspace
this._suppressSuggestion = true;
} else if (this._suggestBox.visible()) {
if (event.keyIdentifier === "U+001B") { // Esc
this._cancelSuggestion();
handled = true;
} else if (event.keyIdentifier === "U+0009") { // Tab
this._suggestBox.acceptSuggestion();
this._valueChanged(true);
handled = true;
} else {
handled = this._suggestBox.keyPressed(/** @type {!KeyboardEvent} */ (event));
}
}
if (handled)
event.consume(true);
return handled;
},
/**
* @override
* @param {string} suggestion
* @param {boolean=} isIntermediateSuggestion
*/
applySuggestion: function(suggestion, isIntermediateSuggestion)
{
if (!this._suggestionBuilder)
return;
this._suggestionBuilder.applySuggestion(this._filterInputElement, suggestion, !!isIntermediateSuggestion);
if (isIntermediateSuggestion)
this._dispatchFilterChanged();
},
/** @override */
acceptSuggestion: function()
{
this._filterInputElement.scrollLeft = this._filterInputElement.scrollWidth;
this._valueChanged(true);
},
__proto__: WebInspector.Object.prototype
}
/**
* @interface
*/
WebInspector.TextFilterUI.SuggestionBuilder = function()
{
}
WebInspector.TextFilterUI.SuggestionBuilder.prototype = {
/**
* @param {!HTMLInputElement} input
* @return {?Array.<string>}
*/
buildSuggestions: function(input) { },
/**
* @param {!HTMLInputElement} input
* @param {string} suggestion
* @param {boolean} isIntermediate
*/
applySuggestion: function(input, suggestion, isIntermediate) { },
/**
* @param {!HTMLInputElement} input
*/
unapplySuggestion: function(input) { }
}
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.FilterUI}
* @param {!Array.<!WebInspector.NamedBitSetFilterUI.Item>} items
* @param {!WebInspector.Setting=} setting
*/
WebInspector.NamedBitSetFilterUI = function(items, setting)
{
this._filtersElement = createElementWithClass("div", "filter-bitset-filter");
this._filtersElement.title = WebInspector.UIString("%sClick to select multiple types", WebInspector.KeyboardShortcut.shortcutToString("", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta));
this._allowedTypes = {};
this._typeFilterElements = {};
this._addBit(WebInspector.NamedBitSetFilterUI.ALL_TYPES, WebInspector.UIString("All"));
this._filtersElement.createChild("div", "filter-bitset-filter-divider");
for (var i = 0; i < items.length; ++i)
this._addBit(items[i].name, items[i].label, items[i].title);
if (setting) {
this._setting = setting;
setting.addChangeListener(this._settingChanged.bind(this));
this._settingChanged();
} else {
this._toggleTypeFilter(WebInspector.NamedBitSetFilterUI.ALL_TYPES, false);
}
}
/** @typedef {{name: string, label: string, title: (string|undefined)}} */
WebInspector.NamedBitSetFilterUI.Item;
WebInspector.NamedBitSetFilterUI.ALL_TYPES = "all";
WebInspector.NamedBitSetFilterUI.prototype = {
/**
* @override
* @return {boolean}
*/
isActive: function()
{
return !this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES];
},
/**
* @override
* @return {!Element}
*/
element: function()
{
return this._filtersElement;
},
/**
* @param {string} typeName
* @return {boolean}
*/
accept: function(typeName)
{
return !!this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES] || !!this._allowedTypes[typeName];
},
_settingChanged: function()
{
var allowedTypes = this._setting.get();
this._allowedTypes = {};
for (var typeName in this._typeFilterElements) {
if (allowedTypes[typeName])
this._allowedTypes[typeName] = true;
}
this._update();
},
_update: function()
{
if ((Object.keys(this._allowedTypes).length === 0) || this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES]) {
this._allowedTypes = {};
this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES] = true;
}
for (var typeName in this._typeFilterElements)
this._typeFilterElements[typeName].classList.toggle("selected", this._allowedTypes[typeName]);
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
/**
* @param {string} name
* @param {string} label
* @param {string=} title
*/
_addBit: function(name, label, title)
{
var typeFilterElement = this._filtersElement.createChild("li", name);
typeFilterElement.typeName = name;
typeFilterElement.createTextChild(label);
if (title)
typeFilterElement.title = title;
typeFilterElement.addEventListener("click", this._onTypeFilterClicked.bind(this), false);
this._typeFilterElements[name] = typeFilterElement;
},
/**
* @param {!Event} e
*/
_onTypeFilterClicked: function(e)
{
var toggle;
if (WebInspector.isMac())
toggle = e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey;
else
toggle = e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey;
this._toggleTypeFilter(e.target.typeName, toggle);
},
/**
* @param {string} typeName
* @param {boolean} allowMultiSelect
*/
_toggleTypeFilter: function(typeName, allowMultiSelect)
{
if (allowMultiSelect && typeName !== WebInspector.NamedBitSetFilterUI.ALL_TYPES)
this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES] = false;
else
this._allowedTypes = {};
this._allowedTypes[typeName] = !this._allowedTypes[typeName];
if (this._setting)
this._setting.set(this._allowedTypes);
else
this._update();
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.FilterUI}
* @extends {WebInspector.Object}
* @param {!Array.<!{value: *, label: string, title: string}>} options
*/
WebInspector.ComboBoxFilterUI = function(options)
{
this._filterElement = createElement("div");
this._filterElement.className = "filter-combobox-filter";
this._options = options;
this._filterComboBox = new WebInspector.ToolbarComboBox(this._filterChanged.bind(this));
for (var i = 0; i < options.length; ++i) {
var filterOption = options[i];
var option = createElement("option");
option.text = filterOption.label;
option.title = filterOption.title;
this._filterComboBox.addOption(option);
this._filterComboBox.element.title = this._filterComboBox.selectedOption().title;
}
this._filterElement.appendChild(this._filterComboBox.element);
}
WebInspector.ComboBoxFilterUI.prototype = {
/**
* @override
* @return {boolean}
*/
isActive: function()
{
return this._filterComboBox.selectedIndex() !== 0;
},
/**
* @override
* @return {!Element}
*/
element: function()
{
return this._filterElement;
},
/**
* @return {*}
*/
value: function()
{
var option = this._options[this._filterComboBox.selectedIndex()];
return option.value;
},
/**
* @param {number} index
*/
setSelectedIndex: function(index)
{
this._filterComboBox.setSelectedIndex(index);
},
/**
* @return {number}
*/
selectedIndex: function(index)
{
return this._filterComboBox.selectedIndex();
},
/**
* @param {!Event} event
*/
_filterChanged: function(event)
{
var option = this._options[this._filterComboBox.selectedIndex()];
this._filterComboBox.element.title = option.title;
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @implements {WebInspector.FilterUI}
* @extends {WebInspector.Object}
* @param {string} className
* @param {string} title
* @param {boolean=} activeWhenChecked
* @param {!WebInspector.Setting=} setting
*/
WebInspector.CheckboxFilterUI = function(className, title, activeWhenChecked, setting)
{
this._filterElement = createElementWithClass("div", "filter-checkbox-filter");
this._activeWhenChecked = !!activeWhenChecked;
this._label = createCheckboxLabel(title);
this._filterElement.appendChild(this._label);
this._checkboxElement = this._label.checkboxElement;
if (setting)
WebInspector.SettingsUI.bindCheckbox(this._checkboxElement, setting);
else
this._checkboxElement.checked = true;
this._checkboxElement.addEventListener("change", this._fireUpdated.bind(this), false);
}
WebInspector.CheckboxFilterUI.prototype = {
/**
* @override
* @return {boolean}
*/
isActive: function()
{
return this._activeWhenChecked === this._checkboxElement.checked;
},
/**
* @return {boolean}
*/
checked: function()
{
return this._checkboxElement.checked;
},
/**
* @override
* @return {!Element}
*/
element: function()
{
return this._filterElement;
},
/**
* @return {!Element}
*/
labelElement: function()
{
return this._label;
},
_fireUpdated: function()
{
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
/**
* @param {string} backgroundColor
* @param {string} borderColor
*/
setColor: function(backgroundColor, borderColor)
{
this._label.backgroundColor = backgroundColor;
this._label.borderColor = borderColor;
},
__proto__: WebInspector.Object.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.ForwardedInputEventHandler = function() { InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.KeyEventUnhandled, this._onKeyEventUnhandled, this); } WebInspector.ForwardedInputEventHandler.prototype = { /** * @param {!WebInspector.Event} event */ _onKeyEventUnhandled: function(event) { var data = event.data; var type = /** @type {string} */ (data.type); var keyIdentifier = /** @type {string} */ (data.keyIdentifier); var keyCode = /** @type {number} */ (data.keyCode); var modifiers =/** @type {number} */ (data.modifiers); if (type !== "keydown") return; WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut, WebInspector.ShortcutRegistry.ForwardedShortcut.instance); WebInspector.shortcutRegistry.handleKey(WebInspector.KeyboardShortcut.makeKey(keyCode, modifiers), keyIdentifier); WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut, null); } } /** @type {!WebInspector.ForwardedInputEventHandler} */ WebInspector.forwardedEventHandler = new WebInspector.ForwardedInputEventHandler(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {HTMLInputElement}
*/
WebInspector.HistoryInput = function()
{
}
/**
* @return {!WebInspector.HistoryInput}
*/
WebInspector.HistoryInput.create = function()
{
if (!WebInspector.HistoryInput._constructor)
WebInspector.HistoryInput._constructor = registerCustomElement("input", "history-input", WebInspector.HistoryInput.prototype);
return /** @type {!WebInspector.HistoryInput} */(new WebInspector.HistoryInput._constructor());
}
WebInspector.HistoryInput.prototype = {
createdCallback: function()
{
this._history = [""];
this._historyPosition = 0;
this.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.addEventListener("input", this._onInput.bind(this), false);
},
/**
* @param {!Event} event
*/
_onInput: function(event)
{
if (this._history.length === this._historyPosition + 1)
this._history[this._history.length - 1] = this.value;
},
/**
* @param {!Event} event
*/
_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Up.code) {
this._historyPosition = Math.max(this._historyPosition - 1, 0);
this.value = this._history[this._historyPosition];
this.dispatchEvent(createEvent("input", true, true));
event.consume(true);
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Down.code) {
this._historyPosition = Math.min(this._historyPosition + 1, this._history.length - 1);
this.value = this._history[this._historyPosition];
this.dispatchEvent(createEvent("input", true, true));
event.consume(true);
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code) {
this._saveToHistory();
}
},
_saveToHistory: function()
{
if (this._history.length > 1 && this._history[this._history.length - 2] === this.value)
return;
this._history[this._history.length - 1] = this.value;
this._historyPosition = this._history.length - 1;
this._history.push("");
},
__proto__: HTMLInputElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 2 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.Infobar.Type} type
* @param {string} text
* @param {!WebInspector.Setting=} disableSetting
*/
WebInspector.Infobar = function(type, text, disableSetting)
{
this.element = createElementWithClass("div", "flex-none");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/infobar.css");
this._contentElement = this._shadowRoot.createChild("div", "infobar infobar-" + type);
this._mainRow = this._contentElement.createChild("div", "infobar-main-row");
this._mainRow.createChild("div", type + "-icon icon");
this._mainRowText = this._mainRow.createChild("div", "infobar-main-title");
this._mainRowText.textContent = text;
this._detailsRows = this._contentElement.createChild("div", "infobar-details-rows hidden");
this._toggleElement = this._mainRow.createChild("div", "infobar-toggle hidden");
this._toggleElement.addEventListener("click", this._onToggleDetails.bind(this), false);
this._toggleElement.textContent = WebInspector.UIString("more");
/** @type {?WebInspector.Setting} */
this._disableSetting = disableSetting || null;
if (disableSetting) {
var disableButton = this._mainRow.createChild("div", "infobar-toggle");
disableButton.textContent = WebInspector.UIString("never show");
disableButton.addEventListener("click", this._onDisable.bind(this), false);
}
this._closeButton = this._contentElement.createChild("div", "close-button", "dt-close-button");
this._closeButton.addEventListener("click", this.dispose.bind(this), false);
/** @type {?function()} */
this._closeCallback = null;
}
/**
* @param {!WebInspector.Infobar.Type} type
* @param {string} text
* @param {!WebInspector.Setting=} disableSetting
* @return {?WebInspector.Infobar}
*/
WebInspector.Infobar.create = function(type, text, disableSetting)
{
if (disableSetting && disableSetting.get())
return null;
return new WebInspector.Infobar(type, text, disableSetting);
}
/** @enum {string} */
WebInspector.Infobar.Type = {
Warning: "warning",
Info: "info"
}
WebInspector.Infobar.prototype = {
dispose: function()
{
this.element.remove();
this._onResize();
if (this._closeCallback)
this._closeCallback.call(null);
},
/**
* @param {string} text
*/
setText: function(text)
{
this._mainRowText.textContent = text;
this._onResize();
},
/**
* @param {?function()} callback
*/
setCloseCallback: function(callback)
{
this._closeCallback = callback;
},
/**
* @param {!WebInspector.Widget} parentView
*/
setParentView: function(parentView)
{
this._parentView = parentView;
},
_onResize: function()
{
if (this._parentView)
this._parentView.doResize();
},
_onDisable: function()
{
this._disableSetting.set(true);
this.dispose();
},
_onToggleDetails: function()
{
this._detailsRows.classList.remove("hidden");
this._toggleElement.remove();
this._onResize();
},
/**
* @param {string=} message
* @return {!Element}
*/
createDetailsRowMessage: function(message)
{
this._toggleElement.classList.remove("hidden");
var infobarDetailsRow = this._detailsRows.createChild("div", "infobar-details-row");
var detailsRowMessage = infobarDetailsRow.createChild("span", "infobar-row-message");
detailsRowMessage.textContent = message || "";
return detailsRowMessage;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | 2 1 1 1 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.InplaceEditor = function() { } /** * @typedef {{cancel: function(), commit: function(), setWidth: function(number)}} */ WebInspector.InplaceEditor.Controller; /** * @param {!Element} element * @param {!WebInspector.InplaceEditor.Config=} config * @return {?WebInspector.InplaceEditor.Controller} */ WebInspector.InplaceEditor.startEditing = function(element, config) { if (!WebInspector.InplaceEditor._defaultInstance) WebInspector.InplaceEditor._defaultInstance = new WebInspector.InplaceEditor(); return WebInspector.InplaceEditor._defaultInstance.startEditing(element, config); } /** * @param {!Element} element * @param {!WebInspector.InplaceEditor.Config=} config * @return {!Promise.<!WebInspector.InplaceEditor.Controller>} */ WebInspector.InplaceEditor.startMultilineEditing = function(element, config) { return self.runtime.instancePromise(WebInspector.InplaceEditor).then(startEditing); /** * @param {!Object} inplaceEditor * @return {!WebInspector.InplaceEditor.Controller|!Promise.<!WebInspector.InplaceEditor.Controller>} */ function startEditing(inplaceEditor) { var controller = /** @type {!WebInspector.InplaceEditor} */ (inplaceEditor).startEditing(element, config); if (!controller) return Promise.reject(new Error("Editing is already in progress")); return controller; } } WebInspector.InplaceEditor.prototype = { /** * @return {string} */ editorContent: function(editingContext) { var element = editingContext.element; if (element.tagName === "INPUT" && element.type === "text") return element.value; return element.textContent; }, setUpEditor: function(editingContext) { var element = editingContext.element; element.classList.add("editing"); var oldTabIndex = element.getAttribute("tabIndex"); if (typeof oldTabIndex !== "number" || oldTabIndex < 0) element.tabIndex = 0; WebInspector.setCurrentFocusElement(element); editingContext.oldTabIndex = oldTabIndex; }, closeEditor: function(editingContext) { var element = editingContext.element; element.classList.remove("editing"); if (typeof editingContext.oldTabIndex !== "number") element.removeAttribute("tabIndex"); else element.tabIndex = editingContext.oldTabIndex; element.scrollTop = 0; element.scrollLeft = 0; }, cancelEditing: function(editingContext) { var element = editingContext.element; if (element.tagName === "INPUT" && element.type === "text") element.value = editingContext.oldText; else element.textContent = editingContext.oldText; }, augmentEditingHandle: function(editingContext, handle) { }, /** * @param {!Element} element * @param {!WebInspector.InplaceEditor.Config=} config * @return {?WebInspector.InplaceEditor.Controller} */ startEditing: function(element, config) { if (!WebInspector.markBeingEdited(element, true)) return null; config = config || new WebInspector.InplaceEditor.Config(function() {}, function() {}); var editingContext = { element: element, config: config }; var committedCallback = config.commitHandler; var cancelledCallback = config.cancelHandler; var pasteCallback = config.pasteHandler; var context = config.context; var isMultiline = config.multiline || false; var moveDirection = ""; var self = this; /** * @param {!Event} e */ function consumeCopy(e) { e.consume(); } this.setUpEditor(editingContext); editingContext.oldText = isMultiline ? config.initialValue : this.editorContent(editingContext); /** * @param {!Event=} e */ function blurEventListener(e) { if (config.blurHandler && !config.blurHandler(element, e)) return; if (!isMultiline || !e || !e.relatedTarget || !e.relatedTarget.isSelfOrDescendant(element)) editingCommitted.call(element); } function cleanUpAfterEditing() { WebInspector.markBeingEdited(element, false); element.removeEventListener("blur", blurEventListener, isMultiline); element.removeEventListener("keydown", keyDownEventListener, true); if (pasteCallback) element.removeEventListener("paste", pasteEventListener, true); WebInspector.restoreFocusFromElement(element); self.closeEditor(editingContext); } /** @this {Element} */ function editingCancelled() { self.cancelEditing(editingContext); cleanUpAfterEditing(); cancelledCallback(this, context); } /** @this {Element} */ function editingCommitted() { cleanUpAfterEditing(); committedCallback(this, self.editorContent(editingContext), editingContext.oldText, context, moveDirection); } /** * @param {!Event} event * @return {string} */ function defaultFinishHandler(event) { var isMetaOrCtrl = WebInspector.isMac() ? event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey : event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey; if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !isMultiline || isMetaOrCtrl)) return "commit"; else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") return "cancel"; else if (!isMultiline && event.keyIdentifier === "U+0009") // Tab key return "move-" + (event.shiftKey ? "backward" : "forward"); return ""; } function handleEditingResult(result, event) { if (result === "commit") { editingCommitted.call(element); event.consume(true); } else if (result === "cancel") { editingCancelled.call(element); event.consume(true); } else if (result && result.startsWith("move-")) { moveDirection = result.substring(5); if (event.keyIdentifier !== "U+0009") blurEventListener(); } } /** * @param {!Event} event */ function pasteEventListener(event) { var result = pasteCallback(event); handleEditingResult(result, event); } /** * @param {!Event} event */ function keyDownEventListener(event) { var result = defaultFinishHandler(event); if (!result && config.postKeydownFinishHandler) result = config.postKeydownFinishHandler(event); handleEditingResult(result, event); } element.addEventListener("blur", blurEventListener, isMultiline); element.addEventListener("keydown", keyDownEventListener, true); if (pasteCallback) element.addEventListener("paste", pasteEventListener, true); var handle = { cancel: editingCancelled.bind(element), commit: editingCommitted.bind(element), setWidth: function() {} }; this.augmentEditingHandle(editingContext, handle); return handle; } } /** * @constructor * @param {function(!Element,string,string,T,string)} commitHandler * @param {function(!Element,T)} cancelHandler * @param {T=} context * @param {function(!Element,!Event):boolean=} blurHandler * @template T */ WebInspector.InplaceEditor.Config = function(commitHandler, cancelHandler, context, blurHandler) { this.commitHandler = commitHandler; this.cancelHandler = cancelHandler; this.context = context; this.blurHandler = blurHandler; /** * @type {function(!Event):string|undefined} */ this.pasteHandler; /** * @type {boolean|undefined} */ this.multiline; /** * @type {function(!Event):string|undefined} */ this.postKeydownFinishHandler; } WebInspector.InplaceEditor.Config.prototype = { setPasteHandler: function(pasteHandler) { this.pasteHandler = pasteHandler; }, /** * @param {string} initialValue * @param {!Object} mode * @param {string} theme * @param {boolean=} lineWrapping * @param {boolean=} smartIndent */ setMultilineOptions: function(initialValue, mode, theme, lineWrapping, smartIndent) { this.multiline = true; this.initialValue = initialValue; this.mode = mode; this.theme = theme; this.lineWrapping = lineWrapping; this.smartIndent = smartIndent; }, /** * @param {function(!Event):string} postKeydownFinishHandler */ setPostKeydownFinishHandler: function(postKeydownFinishHandler) { this.postKeydownFinishHandler = postKeydownFinishHandler; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | 2 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.InspectorView = function()
{
WebInspector.VBox.call(this);
WebInspector.Dialog.setModalHostView(this);
WebInspector.GlassPane.DefaultFocusedViewStack.push(this);
this.setMinimumSize(240, 72);
// DevTools sidebar is a vertical split of panels tabbed pane and a drawer.
this._drawerSplitWidget = new WebInspector.SplitWidget(false, true, "Inspector.drawerSplitViewState", 200, 200);
this._drawerSplitWidget.hideSidebar();
this._drawerSplitWidget.enableShowModeSaving();
this._drawerSplitWidget.show(this.element);
this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.registerRequiredCSS("ui/inspectorViewTabbedPane.css");
this._tabbedPane.element.classList.add("inspector-view-tabbed-pane");
this._tabbedPane.setTabSlider(true);
this._tabbedPane.setAllowTabReorder(true, false);
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabOrderChanged, this._persistPanelOrder, this);
this._tabOrderSetting = WebInspector.settings.createSetting("InspectorView.panelOrder", {});
this._drawerSplitWidget.setMainWidget(this._tabbedPane);
this._drawer = new WebInspector.Drawer(this._drawerSplitWidget);
this._panels = {};
// Used by tests.
WebInspector["panels"] = this._panels;
this._history = [];
this._historyIterator = -1;
this._keyDownBound = this._keyDown.bind(this);
this._keyPressBound = this._keyPress.bind(this);
/** @type {!Object.<string, !WebInspector.PanelDescriptor>} */
this._panelDescriptors = {};
/** @type {!Object.<string, !Promise.<!WebInspector.Panel> >} */
this._panelPromises = {};
// Windows and Mac have two different definitions of '[' and ']', so accept both of each.
this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet();
this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
this._lastActivePanelSetting = WebInspector.settings.createSetting("lastActivePanel", "elements");
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ShowPanel, showPanel.bind(this));
this._loadPanelDesciptors();
/**
* @this {WebInspector.InspectorView}
* @param {!WebInspector.Event} event
*/
function showPanel(event)
{
var panelName = /** @type {string} */ (event.data);
this.showPanel(panelName);
}
};
WebInspector.InspectorView.prototype = {
wasShown: function()
{
this.element.ownerDocument.addEventListener("keydown", this._keyDownBound, false);
this.element.ownerDocument.addEventListener("keypress", this._keyPressBound, false);
},
willHide: function()
{
this.element.ownerDocument.removeEventListener("keydown", this._keyDownBound, false);
this.element.ownerDocument.removeEventListener("keypress", this._keyPressBound, false);
},
_loadPanelDesciptors: function()
{
/**
* @param {!Runtime.Extension} extension
* @this {!WebInspector.InspectorView}
*/
function processPanelExtensions(extension)
{
var descriptor = new WebInspector.RuntimeExtensionPanelDescriptor(extension);
var weight = this._tabOrderSetting.get()[descriptor.name()];
if (weight === undefined)
weight = extension.descriptor()["order"];
if (weight === undefined)
weight = 10000;
panelWeights.set(descriptor, weight);
}
/**
* @param {!WebInspector.PanelDescriptor} left
* @param {!WebInspector.PanelDescriptor} right
*/
function orderComparator(left, right)
{
return panelWeights.get(left) > panelWeights.get(right);
}
WebInspector.startBatchUpdate();
/** @type {!Map<!WebInspector.PanelDescriptor, number>} */
var panelWeights = new Map();
self.runtime.extensions(WebInspector.PanelFactory).forEach(processPanelExtensions.bind(this));
var sortedPanels = panelWeights.keysArray().sort(orderComparator);
for (var panelDescriptor of sortedPanels)
this._innerAddPanel(panelDescriptor);
WebInspector.endBatchUpdate();
},
createToolbars: function()
{
this._leftToolbar = new WebInspector.ExtensibleToolbar("main-toolbar-left");
this._leftToolbar.element.classList.add("inspector-view-toolbar", "inspector-view-toolbar-left");
this._tabbedPane.insertBeforeTabStrip(this._leftToolbar.element);
var rightToolbarContainer = createElementWithClass("div", "hbox flex-none flex-centered");
this._tabbedPane.appendAfterTabStrip(rightToolbarContainer);
this._rightToolbar = new WebInspector.ExtensibleToolbar("main-toolbar-right");
this._rightToolbar.element.classList.add("inspector-view-toolbar", "flex-none");
rightToolbarContainer.appendChild(this._rightToolbar.element);
},
/**
* @param {!WebInspector.PanelDescriptor} panelDescriptor
* @param {number=} index
*/
_innerAddPanel: function(panelDescriptor, index)
{
var panelName = panelDescriptor.name();
this._panelDescriptors[panelName] = panelDescriptor;
this._tabbedPane.appendTab(panelName, panelDescriptor.title(), new WebInspector.Widget(), undefined, undefined, undefined, index);
if (this._lastActivePanelSetting.get() === panelName)
this._tabbedPane.selectTab(panelName);
},
/**
* @param {!WebInspector.PanelDescriptor} panelDescriptor
*/
addPanel: function(panelDescriptor)
{
var weight = this._tabOrderSetting.get()[panelDescriptor.name()];
// Keep in sync with _persistPanelOrder().
if (weight)
weight = Math.max(0, Math.round(weight / 10) - 1);
this._innerAddPanel(panelDescriptor, weight);
},
/**
* @param {string} panelName
* @return {boolean}
*/
hasPanel: function(panelName)
{
return !!this._panelDescriptors[panelName];
},
/**
* @param {string} panelName
* @return {!Promise.<!WebInspector.Panel>}
*/
panel: function(panelName)
{
var panelDescriptor = this._panelDescriptors[panelName];
if (!panelDescriptor)
return Promise.reject(new Error("Can't load panel without the descriptor: " + panelName));
var promise = this._panelPromises[panelName];
if (promise)
return promise;
promise = panelDescriptor.panel();
this._panelPromises[panelName] = promise;
promise.then(cachePanel.bind(this));
/**
* @param {!WebInspector.Panel} panel
* @return {!WebInspector.Panel}
* @this {WebInspector.InspectorView}
*/
function cachePanel(panel)
{
delete this._panelPromises[panelName];
this._panels[panelName] = panel;
return panel;
}
return promise;
},
/**
* @param {boolean} allTargetsSuspended
*/
onSuspendStateChanged: function(allTargetsSuspended)
{
this._currentPanelLocked = allTargetsSuspended;
this._tabbedPane.setCurrentTabLocked(this._currentPanelLocked);
if (this._leftToolbar)
this._leftToolbar.setEnabled(!this._currentPanelLocked);
if (this._rightToolbar)
this._rightToolbar.setEnabled(!this._currentPanelLocked);
},
/**
* The returned Promise is resolved with null if another showPanel()
* gets called while this.panel(panelName) Promise is in flight.
*
* @param {string} panelName
* @return {!Promise.<?WebInspector.Panel>}
*/
showPanel: function(panelName)
{
if (this._currentPanelLocked) {
if (this._currentPanel !== this._panels[panelName])
return Promise.reject(new Error("Current panel locked"));
return Promise.resolve(this._currentPanel);
}
this._panelForShowPromise = this.panel(panelName);
return this._panelForShowPromise.then(setCurrentPanelIfNecessary.bind(this, this._panelForShowPromise));
/**
* @param {!Promise.<!WebInspector.Panel>} panelPromise
* @param {!WebInspector.Panel} panel
* @return {?WebInspector.Panel}
* @this {WebInspector.InspectorView}
*/
function setCurrentPanelIfNecessary(panelPromise, panel)
{
if (this._panelForShowPromise !== panelPromise)
return null;
this.setCurrentPanel(panel);
return panel;
}
},
/**
* @param {string} panelName
* @param {string} iconType
* @param {string=} iconTooltip
*/
setPanelIcon: function(panelName, iconType, iconTooltip)
{
this._tabbedPane.setTabIcon(panelName, iconType, iconTooltip);
},
/**
* @return {!WebInspector.Panel}
*/
currentPanel: function()
{
return this._currentPanel;
},
showInitialPanel: function()
{
if (InspectorFrontendHost.isUnderTest())
return;
this._showInitialPanel();
},
_showInitialPanel: function()
{
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._tabSelected();
this._drawer.initialPanelShown();
},
/**
* @param {string} panelName
*/
showInitialPanelForTest: function(panelName)
{
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this.setCurrentPanel(this._panels[panelName]);
this._drawer.initialPanelShown();
},
_tabSelected: function()
{
var panelName = this._tabbedPane.selectedTabId;
if (!panelName)
return;
this.showPanel(panelName);
},
/**
* @param {!WebInspector.Panel} panel
* @param {boolean=} suppressBringToFront
* @return {!WebInspector.Panel}
*/
setCurrentPanel: function(panel, suppressBringToFront)
{
delete this._panelForShowPromise;
if (this._currentPanelLocked)
return this._currentPanel;
if (!suppressBringToFront)
InspectorFrontendHost.bringToFront();
if (this._currentPanel === panel)
return panel;
this._currentPanel = panel;
if (!this._panels[panel.name])
this._panels[panel.name] = panel;
this._tabbedPane.changeTabView(panel.name, panel);
this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._tabbedPane.selectTab(panel.name);
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._lastActivePanelSetting.set(panel.name);
this._pushToHistory(panel.name);
WebInspector.userMetrics.panelShown(panel.name);
panel.focus();
return panel;
},
showDrawer: function()
{
this._drawer.showDrawer();
},
/**
* @return {boolean}
*/
drawerVisible: function()
{
return this._drawer.isShowing();
},
/**
* @param {string} id
* @param {boolean=} immediate
* @return {!Promise.<?WebInspector.Widget>}
*/
showViewInDrawer: function(id, immediate)
{
return this._drawer.showView(id, immediate);
},
/**
* @return {?string}
*/
selectedViewInDrawer: function()
{
return this._drawer.selectedViewId();
},
closeDrawer: function()
{
this._drawer.closeDrawer();
},
/**
* @param {boolean} minimized
*/
setDrawerMinimized: function(minimized)
{
this._drawerSplitWidget.setSidebarMinimized(minimized);
this._drawerSplitWidget.setResizable(!minimized);
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._currentPanel ? this._currentPanel.defaultFocusedElement() : null;
},
_keyPress: function(event)
{
// BUG 104250: Windows 7 posts a WM_CHAR message upon the Ctrl+']' keypress.
// Any charCode < 32 is not going to be a valid keypress.
if (event.charCode < 32 && WebInspector.isWin())
return;
clearTimeout(this._keyDownTimer);
delete this._keyDownTimer;
},
_keyDown: function(event)
{
if (!WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event))
return;
var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
// Ctrl/Cmd + 1-9 should show corresponding panel.
var panelShortcutEnabled = WebInspector.moduleSetting("shortcutPanelSwitch").get();
if (panelShortcutEnabled && !event.shiftKey && !event.altKey) {
var panelIndex = -1;
if (event.keyCode > 0x30 && event.keyCode < 0x3A)
panelIndex = event.keyCode - 0x31;
else if (event.keyCode > 0x60 && event.keyCode < 0x6A && keyboardEvent.location === KeyboardEvent.DOM_KEY_LOCATION_NUMPAD)
panelIndex = event.keyCode - 0x61;
if (panelIndex !== -1) {
var panelName = this._tabbedPane.allTabs()[panelIndex];
if (panelName) {
if (!WebInspector.Dialog.hasInstance() && !this._currentPanelLocked)
this.showPanel(panelName);
event.consume(true);
}
return;
}
}
// BUG85312: On French AZERTY keyboards, AltGr-]/[ combinations (synonymous to Ctrl-Alt-]/[ on Windows) are used to enter ]/[,
// so for a ]/[-related keydown we delay the panel switch using a timer, to see if there is a keypress event following this one.
// If there is, we cancel the timer and do not consider this a panel switch.
if (!WebInspector.isWin() || (!this._openBracketIdentifiers[event.keyIdentifier] && !this._closeBracketIdentifiers[event.keyIdentifier])) {
this._keyDownInternal(event);
return;
}
this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0);
},
_keyDownInternal: function(event)
{
if (this._currentPanelLocked)
return;
var direction = 0;
if (this._openBracketIdentifiers[event.keyIdentifier])
direction = -1;
if (this._closeBracketIdentifiers[event.keyIdentifier])
direction = 1;
if (!direction)
return;
if (!event.shiftKey && !event.altKey) {
if (!WebInspector.Dialog.hasInstance())
this._changePanelInDirection(direction);
event.consume(true);
return;
}
if (event.altKey && this._moveInHistory(direction))
event.consume(true);
},
/**
* @param {number} direction
*/
_changePanelInDirection: function(direction)
{
var panelOrder = this._tabbedPane.allTabs();
var index = panelOrder.indexOf(this.currentPanel().name);
index = (index + panelOrder.length + direction) % panelOrder.length;
this.showPanel(panelOrder[index]);
},
/**
* @param {number} move
*/
_moveInHistory: function(move)
{
var newIndex = this._historyIterator + move;
if (newIndex >= this._history.length || newIndex < 0)
return false;
this._inHistory = true;
this._historyIterator = newIndex;
if (!WebInspector.Dialog.hasInstance())
this.setCurrentPanel(this._panels[this._history[this._historyIterator]]);
delete this._inHistory;
return true;
},
_pushToHistory: function(panelName)
{
if (this._inHistory)
return;
this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
if (!this._history.length || this._history[this._history.length - 1] !== panelName)
this._history.push(panelName);
this._historyIterator = this._history.length - 1;
},
onResize: function()
{
WebInspector.Dialog.modalHostRepositioned();
},
/**
* @return {!Element}
*/
topResizerElement: function()
{
return this._tabbedPane.headerElement();
},
toolbarItemResized: function()
{
this._tabbedPane.headerResized();
},
/**
* @param {!WebInspector.Event} event
*/
_persistPanelOrder: function(event)
{
var tabs = /** @type {!Array.<!WebInspector.TabbedPaneTab>} */(event.data);
var tabOrders = this._tabOrderSetting.get();
for (var i = 0; i < tabs.length; i++)
tabOrders[tabs[i].id] = (i + 1)* 10;
this._tabOrderSetting.set(tabOrders);
},
__proto__: WebInspector.VBox.prototype
};
/**
* @type {!WebInspector.InspectorView}
*/
WebInspector.inspectorView;
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
*/
WebInspector.InspectorView.DrawerToggleActionDelegate = function()
{
}
WebInspector.InspectorView.DrawerToggleActionDelegate.prototype = {
/**
* @override
* @param {!WebInspector.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction: function(context, actionId)
{
if (WebInspector.inspectorView.drawerVisible())
WebInspector.inspectorView.closeDrawer();
else
WebInspector.inspectorView.showDrawer();
return true;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | 2 1 | /*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
*/
WebInspector.KeyboardShortcut = function()
{
}
/**
* Constants for encoding modifier key set as a bit mask.
* @see #_makeKeyFromCodeAndModifiers
*/
WebInspector.KeyboardShortcut.Modifiers = {
None: 0, // Constant for empty modifiers set.
Shift: 1,
Ctrl: 2,
Alt: 4,
Meta: 8, // Command key on Mac, Win key on other platforms.
get CtrlOrMeta()
{
// "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
return WebInspector.isMac() ? this.Meta : this.Ctrl;
},
get ShiftOrOption()
{
// Option on Mac, Shift on other platforms
return WebInspector.isMac() ? this.Alt : this.Shift;
}
};
/** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */
WebInspector.KeyboardShortcut.Key;
/** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */
WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
Tab: { code: 9, name: { mac: "\u21e5", other: "Tab" } },
Enter: { code: 13, name: { mac: "\u21a9", other: "Enter" } },
Shift: { code: 16, name: { mac: "\u21e7", other: "Shift" } },
Ctrl: { code: 17, name: "Ctrl" },
Esc: { code: 27, name: "Esc" },
Space: { code: 32, name: "Space" },
PageUp: { code: 33, name: { mac: "\u21de", other: "PageUp" } }, // also NUM_NORTH_EAST
PageDown: { code: 34, name: { mac: "\u21df", other: "PageDown" } }, // also NUM_SOUTH_EAST
End: { code: 35, name: { mac: "\u2197", other: "End" } }, // also NUM_SOUTH_WEST
Home: { code: 36, name: { mac: "\u2196", other: "Home" } }, // also NUM_NORTH_WEST
Left: { code: 37, name: "\u2190" }, // also NUM_WEST
Up: { code: 38, name: "\u2191" }, // also NUM_NORTH
Right: { code: 39, name: "\u2192" }, // also NUM_EAST
Down: { code: 40, name: "\u2193" }, // also NUM_SOUTH
Delete: { code: 46, name: "Del" },
Zero: { code: 48, name: "0" },
H: { code: 72, name: "H" },
Meta: { code: 91, name: "Meta" },
F1: { code: 112, name: "F1" },
F2: { code: 113, name: "F2" },
F3: { code: 114, name: "F3" },
F4: { code: 115, name: "F4" },
F5: { code: 116, name: "F5" },
F6: { code: 117, name: "F6" },
F7: { code: 118, name: "F7" },
F8: { code: 119, name: "F8" },
F9: { code: 120, name: "F9" },
F10: { code: 121, name: "F10" },
F11: { code: 122, name: "F11" },
F12: { code: 123, name: "F12" },
Semicolon: { code: 186, name: ";" },
NumpadPlus: { code: 107, name: "Numpad +" },
NumpadMinus: { code: 109, name: "Numpad -" },
Numpad0: { code: 96, name: "Numpad 0" },
Plus: { code: 187, name: "+" },
Comma: { code: 188, name: "," },
Minus: { code: 189, name: "-" },
Period: { code: 190, name: "." },
Slash: { code: 191, name: "/" },
QuestionMark: { code: 191, name: "?" },
Apostrophe: { code: 192, name: "`" },
Tilde: { code: 192, name: "Tilde" },
LeftSquareBracket: { code: 219, name: "[" },
RightSquareBracket: { code: 221, name: "]" },
Backslash: { code: 220, name: "\\" },
SingleQuote: { code: 222, name: "\'" },
get CtrlOrMeta()
{
// "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
return WebInspector.isMac() ? this.Meta : this.Ctrl;
},
};
WebInspector.KeyboardShortcut.KeyBindings = {};
(function() {
for (var key in WebInspector.KeyboardShortcut.Keys) {
var descriptor = WebInspector.KeyboardShortcut.Keys[key];
if (typeof descriptor === "object" && descriptor["code"]) {
var name = typeof descriptor["name"] === "string" ? descriptor["name"] : key;
WebInspector.KeyboardShortcut.KeyBindings[name] = descriptor;
}
}
})();
/**
* Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
* It is useful for matching pressed keys.
*
* @param {number|string} keyCode The code of the key, or a character "a-z" which is converted to a keyCode value.
* @param {number=} modifiers Optional list of modifiers passed as additional parameters.
* @return {number}
*/
WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
{
if (typeof keyCode === "string")
keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0);
modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
}
/**
* @param {?KeyboardEvent} keyboardEvent
* @return {number}
*/
WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
{
var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
if (keyboardEvent.shiftKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
if (keyboardEvent.ctrlKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
if (keyboardEvent.altKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
if (keyboardEvent.metaKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
// Use either a real or a synthetic keyCode (for events originating from extensions).
var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"];
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
}
/**
* @param {?KeyboardEvent} keyboardEvent
* @return {number}
*/
WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers = function(keyboardEvent)
{
var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"];
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, WebInspector.KeyboardShortcut.Modifiers.None);
}
/**
* @param {(?KeyboardEvent|?MouseEvent)} event
* @return {boolean}
*/
WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
{
return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
}
/**
* @param {!Event} event
* @return {boolean}
*/
WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
{
return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
}
/** @typedef {!{key: number, name: string}} */
WebInspector.KeyboardShortcut.Descriptor;
/**
* @param {string|!WebInspector.KeyboardShortcut.Key} key
* @param {number=} modifiers
* @return {!WebInspector.KeyboardShortcut.Descriptor}
*/
WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
{
return {
key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
};
}
/**
* @param {string} shortcut
* @return {?WebInspector.KeyboardShortcut.Descriptor}
*/
WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut = function(shortcut)
{
var parts = shortcut.split(/\+(?!$)/);
var modifiers = 0;
var keyString;
for (var i = 0; i < parts.length; ++i) {
if (typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]] !== "undefined") {
modifiers |= WebInspector.KeyboardShortcut.Modifiers[parts[i]];
continue;
}
console.assert(i === parts.length - 1, "Only one key other than modifier is allowed in shortcut <" + shortcut + ">");
keyString = parts[i];
break;
}
console.assert(keyString, "Modifiers-only shortcuts are not allowed (encountered <" + shortcut + ">)");
if (!keyString)
return null;
var key = WebInspector.KeyboardShortcut.Keys[keyString] || WebInspector.KeyboardShortcut.KeyBindings[keyString];
if (key && key.shiftKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
return WebInspector.KeyboardShortcut.makeDescriptor(key ? key : keyString, modifiers);
}
/**
* @param {string|!WebInspector.KeyboardShortcut.Key} key
* @param {number=} modifiers
* @return {string}
*/
WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
{
return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
}
/**
* @param {string|!WebInspector.KeyboardShortcut.Key} key
* @return {string}
*/
WebInspector.KeyboardShortcut._keyName = function(key)
{
if (typeof key === "string")
return key.toUpperCase();
if (typeof key.name === "string")
return key.name;
return key.name[WebInspector.platform()] || key.name.other || '';
}
/**
* @param {number} keyCode
* @param {?number} modifiers
* @return {number}
*/
WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
{
return (keyCode & 255) | (modifiers << 8);
};
/**
* @param {number} key
* @return {!{keyCode: number, modifiers: number}}
*/
WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey = function(key)
{
return { keyCode: key & 255, modifiers: key >> 8 };
}
/**
* @param {number|undefined} modifiers
* @return {string}
*/
WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
{
var isMac = WebInspector.isMac();
var m = WebInspector.KeyboardShortcut.Modifiers;
var modifierNames = new Map([
[m.Ctrl, isMac ? "Ctrl\u2004" : "Ctrl\u200A+\u200A"],
[m.Alt, isMac ? "opt\u2004" : "Alt\u200A+\u200A"],
[m.Shift, isMac ? "\u21e7\u2004" : "Shift\u200A+\u200A"],
[m.Meta, isMac ? "\u2318\u2004" : "Win\u200A+\u200A"]
]);
return [m.Meta, m.Ctrl, m.Alt, m.Shift].map(mapModifiers).join("");
/**
* @param {number} m
* @return {string}
*/
function mapModifiers(m)
{
return modifiers & m ? /** @type {string} */ (modifierNames.get(m)) : "";
}
};
WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | 2 1 1 1 | // Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.ListWidget.Delegate} delegate
*/
WebInspector.ListWidget = function(delegate)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("ui/listWidget.css");
this._delegate = delegate;
this._list = this.contentElement.createChild("div", "list");
/** @type {?WebInspector.ListWidget.Editor} */
this._editor = null;
/** @type {*|null} */
this._editItem = null;
/** @type {?Element} */
this._editElement = null;
/** @type {?Element} */
this._emptyPlaceholder = null;
this.clear();
}
/**
* @interface
*/
WebInspector.ListWidget.Delegate = function()
{
}
WebInspector.ListWidget.Delegate.prototype = {
/**
* @param {*} item
* @param {boolean} editable
* @return {!Element}
*/
renderItem: function(item, editable) { },
/**
* @param {*} item
* @param {number} index
*/
removeItemRequested: function(item, index) { },
/**
* @param {*} item
* @return {!WebInspector.ListWidget.Editor}
*/
beginEdit: function(item) { },
/**
* @param {*} item
* @param {!WebInspector.ListWidget.Editor} editor
* @param {boolean} isNew
*/
commitEdit: function(item, editor, isNew) { }
}
WebInspector.ListWidget.prototype = {
clear: function()
{
this._items = [];
this._editable = [];
this._elements = [];
this._lastSeparator = false;
this._list.removeChildren();
this._updatePlaceholder();
this._stopEditing();
},
/**
* @param {*} item
* @param {boolean} editable
*/
appendItem: function(item, editable)
{
if (this._lastSeparator && this._items.length)
this._list.appendChild(createElementWithClass("div", "list-separator"));
this._lastSeparator = false;
this._items.push(item);
this._editable.push(editable);
var element = this._list.createChild("div", "list-item");
element.appendChild(this._delegate.renderItem(item, editable));
if (editable) {
element.classList.add("editable");
element.appendChild(this._createControls(item, element));
}
this._elements.push(element);
this._updatePlaceholder();
},
appendSeparator: function()
{
this._lastSeparator = true;
},
/**
* @param {number} index
*/
removeItem: function(index)
{
if (this._editItem === this._items[index])
this._stopEditing();
var element = this._elements[index];
var previous = element.previousElementSibling;
var previousIsSeparator = previous && previous.classList.contains("list-separator");
var next = element.nextElementSibling;
var nextIsSeparator = next && next.classList.contains("list-separator");
if (previousIsSeparator && (nextIsSeparator || !next))
previous.remove();
if (nextIsSeparator && !previous)
next.remove();
element.remove();
this._elements.splice(index, 1);
this._items.splice(index, 1);
this._editable.splice(index, 1);
this._updatePlaceholder();
},
/**
* @param {number} index
* @param {*} item
*/
addNewItem: function(index, item)
{
this._startEditing(item, null, this._elements[index] || null);
},
/**
* @param {?Element} element
*/
setEmptyPlaceholder: function(element)
{
this._emptyPlaceholder = element;
this._updatePlaceholder();
},
/**
* @param {*} item
* @param {!Element} element
* @return {!Element}
*/
_createControls: function(item, element)
{
var controls = createElementWithClass("div", "controls-container fill");
var gradient = controls.createChild("div", "controls-gradient");
var buttons = controls.createChild("div", "controls-buttons");
var editButton = buttons.createChild("div", "edit-button");
editButton.title = WebInspector.UIString("Edit");
editButton.addEventListener("click", onEditClicked.bind(this), false);
var removeButton = buttons.createChild("div", "remove-button");
removeButton.title = WebInspector.UIString("Remove");
removeButton.addEventListener("click", onRemoveClicked.bind(this), false);
return controls;
/**
* @param {!Event} event
* @this {WebInspector.ListWidget}
*/
function onEditClicked(event)
{
event.consume();
var index = this._elements.indexOf(element);
var insertionPoint = this._elements[index + 1] || null;
this._startEditing(item, element, insertionPoint);
}
/**
* @param {!Event} event
* @this {WebInspector.ListWidget}
*/
function onRemoveClicked(event)
{
event.consume();
var index = this._elements.indexOf(element);
this._delegate.removeItemRequested(this._items[index], index);
}
},
wasShown: function()
{
WebInspector.VBox.prototype.wasShown.call(this);
this._stopEditing();
},
_updatePlaceholder: function()
{
if (!this._emptyPlaceholder)
return;
if (!this._elements.length && !this._editor)
this._list.appendChild(this._emptyPlaceholder);
else
this._emptyPlaceholder.remove();
},
/**
* @param {*} item
* @param {?Element} element
* @param {?Element} insertionPoint
*/
_startEditing: function(item, element, insertionPoint)
{
if (element && this._editElement === element)
return;
this._stopEditing();
this._list.classList.add("list-editing");
this._editItem = item;
this._editElement = element;
if (element)
element.classList.add("hidden");
var index = element ? this._elements.indexOf(element) : -1;
this._editor = this._delegate.beginEdit(item);
this._updatePlaceholder();
this._list.insertBefore(this._editor.element, insertionPoint);
this._editor.beginEdit(item, index, element ? WebInspector.UIString("Save") : WebInspector.UIString("Add"), this._commitEditing.bind(this), this._stopEditing.bind(this));
},
_commitEditing: function()
{
var editItem = this._editItem;
var isNew = !this._editElement;
var editor = /** @type {!WebInspector.ListWidget.Editor} */ (this._editor);
this._stopEditing();
this._delegate.commitEdit(editItem, editor, isNew);
},
_stopEditing: function()
{
this._list.classList.remove("list-editing");
if (this._editElement)
this._editElement.classList.remove("hidden");
if (this._editor && this._editor.element.parentElement)
this._editor.element.remove();
this._editor = null;
this._editItem = null;
this._editElement = null;
this._updatePlaceholder();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
*/
WebInspector.ListWidget.Editor = function()
{
this.element = createElementWithClass("div", "editor-container");
this.element.addEventListener("keydown", onKeyDown.bind(null, isEscKey, this._cancelClicked.bind(this)), false);
this.element.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, this._commitClicked.bind(this)), false);
this._contentElement = this.element.createChild("div", "editor-content");
var buttonsRow = this.element.createChild("div", "editor-buttons");
this._commitButton = createTextButton("", this._commitClicked.bind(this));
buttonsRow.appendChild(this._commitButton);
this._cancelButton = createTextButton(WebInspector.UIString("Cancel"), this._cancelClicked.bind(this));
this._cancelButton.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, this._cancelClicked.bind(this)), false);
buttonsRow.appendChild(this._cancelButton);
/**
* @param {function(!Event):boolean} predicate
* @param {function()} callback
* @param {!Event} event
*/
function onKeyDown(predicate, callback, event)
{
if (predicate(event)) {
event.consume(true);
callback();
}
}
/** @type {!Array<!HTMLInputElement|!HTMLSelectElement>} */
this._controls = [];
/** @type {!Map<string, !HTMLInputElement|!HTMLSelectElement>} */
this._controlByName = new Map();
/** @type {!Array<function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boolean>} */
this._validators = [];
/** @type {?function()} */
this._commit = null;
/** @type {?function()} */
this._cancel = null;
/** @type {*|null} */
this._item = null;
/** @type {number} */
this._index = -1;
}
WebInspector.ListWidget.Editor.prototype = {
/**
* @return {!Element}
*/
contentElement: function()
{
return this._contentElement;
},
/**
* @param {string} name
* @param {string} type
* @param {string} title
* @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boolean} validator
* @return {!HTMLInputElement}
*/
createInput: function(name, type, title, validator)
{
var input = /** @type {!HTMLInputElement} */ (createElement("input"));
input.type = type;
input.placeholder = title;
input.addEventListener("input", this._validateControls.bind(this, false), false);
input.addEventListener("blur", this._validateControls.bind(this, false), false);
this._controlByName.set(name, input);
this._controls.push(input);
this._validators.push(validator);
return input;
},
/**
* @param {string} name
* @param {!Array<string>} options
* @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boolean} validator
* @return {!HTMLSelectElement}
*/
createSelect: function(name, options, validator)
{
var select = /** @type {!HTMLSelectElement} */ (createElementWithClass("select", "chrome-select"));
for (var index = 0; index < options.length; ++index) {
var option = select.createChild("option");
option.value = options[index];
option.textContent = options[index];
}
select.addEventListener("input", this._validateControls.bind(this, false), false);
select.addEventListener("blur", this._validateControls.bind(this, false), false);
this._controlByName.set(name, select);
this._controls.push(select);
this._validators.push(validator);
return select;
},
/**
* @param {string} name
* @return {!HTMLInputElement|!HTMLSelectElement}
*/
control: function(name)
{
return /** @type {!HTMLInputElement|!HTMLSelectElement} */ (this._controlByName.get(name));
},
/**
* @param {boolean} forceValid
*/
_validateControls: function(forceValid)
{
var allValid = true;
for (var index = 0; index < this._controls.length; ++index) {
var input = this._controls[index];
var valid = this._validators[index].call(null, this._item, this._index, input);
input.classList.toggle("error-input", !valid && !forceValid);
allValid &= valid;
}
this._commitButton.disabled = !allValid;
},
/**
* @param {*} item
* @param {number} index
* @param {string} commitButtonTitle
* @param {function()} commit
* @param {function()} cancel
*/
beginEdit: function(item, index, commitButtonTitle, commit, cancel)
{
this._commit = commit;
this._cancel = cancel;
this._item = item;
this._index = index;
this._commitButton.textContent = commitButtonTitle;
this.element.scrollIntoViewIfNeeded(false);
if (this._controls.length)
this._controls[0].focus();
this._validateControls(true);
},
_commitClicked: function()
{
if (this._commitButton.disabled)
return;
var commit = this._commit;
this._commit = null;
this._cancel = null;
this._item = null;
this._index = -1;
commit();
},
_cancelClicked: function()
{
var cancel = this._cancel;
this._commit = null;
this._cancel = null;
this._item = null;
this._index = -1;
cancel();
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | 2 1 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @extends {WebInspector.VBox}
* @constructor
*/
WebInspector.Panel = function(name)
{
WebInspector.VBox.call(this);
this.element.classList.add("panel");
this.element.classList.add(name);
this._panelName = name;
this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
}
// Should by in sync with style declarations.
WebInspector.Panel.counterRightMargin = 25;
WebInspector.Panel.prototype = {
get name()
{
return this._panelName;
},
reset: function()
{
},
/**
* @return {?WebInspector.SearchableView}
*/
searchableView: function()
{
return null;
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [];
},
/**
* @param {!KeyboardEvent} event
*/
handleShortcut: function(event)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event))
event.handled = true;
},
/**
* @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
* @param {function(!Event=):boolean} handler
*/
registerShortcuts: function(keys, handler)
{
for (var i = 0; i < keys.length; ++i)
this._shortcuts[keys[i].key] = handler;
},
/**
* @param {!WebInspector.Infobar} infobar
*/
showInfobar: function(infobar)
{
infobar.setCloseCallback(this._onInfobarClosed.bind(this, infobar));
if (this.element.firstChild)
this.element.insertBefore(infobar.element, this.element.firstChild);
else
this.element.appendChild(infobar.element);
infobar.setParentView(this);
this.doResize();
},
/**
* @param {!WebInspector.Infobar} infobar
*/
_onInfobarClosed: function(infobar)
{
infobar.element.remove();
this.doResize();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @extends {WebInspector.Panel}
* @param {string} name
* @param {number=} defaultWidth
* @constructor
*/
WebInspector.PanelWithSidebar = function(name, defaultWidth)
{
WebInspector.Panel.call(this, name);
this._panelSplitWidget = new WebInspector.SplitWidget(true, false, this._panelName + "PanelSplitViewState", defaultWidth || 200);
this._panelSplitWidget.show(this.element);
this._mainWidget = new WebInspector.VBox();
this._panelSplitWidget.setMainWidget(this._mainWidget);
this._sidebarWidget = new WebInspector.VBox();
this._sidebarWidget.setMinimumSize(100, 25);
this._panelSplitWidget.setSidebarWidget(this._sidebarWidget);
this._sidebarWidget.element.classList.add("sidebar");
}
WebInspector.PanelWithSidebar.prototype = {
/**
* @return {!Element}
*/
panelSidebarElement: function()
{
return this._sidebarWidget.element;
},
/**
* @return {!Element}
*/
mainElement: function()
{
return this._mainWidget.element;
},
/**
* @return {!WebInspector.SplitWidget}
*/
splitWidget: function()
{
return this._panelSplitWidget;
},
__proto__: WebInspector.Panel.prototype
}
/**
* @interface
*/
WebInspector.PanelDescriptor = function()
{
}
WebInspector.PanelDescriptor.prototype = {
/**
* @return {string}
*/
name: function() {},
/**
* @return {string}
*/
title: function() {},
/**
* @return {!Promise.<!WebInspector.Panel>}
*/
panel: function() {}
}
/**
* @interface
*/
WebInspector.PanelFactory = function()
{
}
WebInspector.PanelFactory.prototype = {
/**
* @return {!WebInspector.Panel}
*/
createPanel: function() { }
}
/**
* @constructor
* @param {!Runtime.Extension} extension
* @implements {WebInspector.PanelDescriptor}
*/
WebInspector.RuntimeExtensionPanelDescriptor = function(extension)
{
this._name = extension.descriptor()["name"];
this._title = WebInspector.UIString(extension.descriptor()["title"]);
this._extension = extension;
}
WebInspector.RuntimeExtensionPanelDescriptor.prototype = {
/**
* @override
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @override
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @override
* @return {!Promise.<!WebInspector.Panel>}
*/
panel: function()
{
return this._extension.instancePromise().then(createPanel);
/**
* @param {!Object} panelFactory
* @return {!WebInspector.Panel}
*/
function createPanel(panelFactory)
{
return /** @type {!WebInspector.PanelFactory} */ (panelFactory).createPanel();
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | 2 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {!WebInspector.PopoverHelper=} popoverHelper
*/
WebInspector.Popover = function(popoverHelper)
{
WebInspector.Widget.call(this);
this.markAsRoot();
this.element.className = WebInspector.Popover._classNamePrefix; // Override
this._containerElement = createElementWithClass("div", "fill popover-container");
this._popupArrowElement = this.element.createChild("div", "arrow");
this._contentDiv = this.element.createChild("div", "content");
this._popoverHelper = popoverHelper;
this._hideBound = this.hide.bind(this);
}
WebInspector.Popover._classNamePrefix = "popover";
WebInspector.Popover.prototype = {
/**
* @param {!Element} element
* @param {!Element|!AnchorBox} anchor
* @param {?number=} preferredWidth
* @param {?number=} preferredHeight
* @param {?WebInspector.Popover.Orientation=} arrowDirection
*/
showForAnchor: function(element, anchor, preferredWidth, preferredHeight, arrowDirection)
{
this._innerShow(null, element, anchor, preferredWidth, preferredHeight, arrowDirection);
},
/**
* @param {!WebInspector.Widget} view
* @param {!Element|!AnchorBox} anchor
* @param {?number=} preferredWidth
* @param {?number=} preferredHeight
*/
showView: function(view, anchor, preferredWidth, preferredHeight)
{
this._innerShow(view, view.element, anchor, preferredWidth, preferredHeight);
},
/**
* @param {?WebInspector.Widget} view
* @param {!Element} contentElement
* @param {!Element|!AnchorBox} anchor
* @param {?number=} preferredWidth
* @param {?number=} preferredHeight
* @param {?WebInspector.Popover.Orientation=} arrowDirection
*/
_innerShow: function(view, contentElement, anchor, preferredWidth, preferredHeight, arrowDirection)
{
if (this._disposed)
return;
this._contentElement = contentElement;
// This should not happen, but we hide previous popup to be on the safe side.
if (WebInspector.Popover._popover)
WebInspector.Popover._popover.hide();
WebInspector.Popover._popover = this;
var document = anchor instanceof Element ? anchor.ownerDocument : contentElement.ownerDocument;
var window = document.defaultView;
// Temporarily attach in order to measure preferred dimensions.
var preferredSize = view ? view.measurePreferredSize() : WebInspector.measurePreferredSize(this._contentElement);
this._preferredWidth = preferredWidth || preferredSize.width;
this._preferredHeight = preferredHeight || preferredSize.height;
window.addEventListener("resize", this._hideBound, false);
document.body.appendChild(this._containerElement);
WebInspector.Widget.prototype.show.call(this, this._containerElement);
if (view)
view.show(this._contentDiv);
else
this._contentDiv.appendChild(this._contentElement);
this.positionElement(anchor, this._preferredWidth, this._preferredHeight, arrowDirection);
if (this._popoverHelper) {
this._contentDiv.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
this.element.addEventListener("mouseout", this._popoverHelper._popoverMouseOut.bind(this._popoverHelper), true);
}
},
hide: function()
{
this._containerElement.ownerDocument.defaultView.removeEventListener("resize", this._hideBound, false);
this.detach();
this._containerElement.remove();
delete WebInspector.Popover._popover;
},
get disposed()
{
return this._disposed;
},
dispose: function()
{
if (this.isShowing())
this.hide();
this._disposed = true;
},
/**
* @param {boolean} canShrink
*/
setCanShrink: function(canShrink)
{
this._hasFixedHeight = !canShrink;
this._contentDiv.classList.toggle("fixed-height", this._hasFixedHeight);
},
/**
* @param {boolean} noMargins
*/
setNoMargins: function(noMargins)
{
this._hasNoMargins = noMargins;
this._contentDiv.classList.toggle("no-margin", this._hasNoMargins);
},
/**
* @param {!Element|!AnchorBox} anchorElement
* @param {number=} preferredWidth
* @param {number=} preferredHeight
* @param {?WebInspector.Popover.Orientation=} arrowDirection
*/
positionElement: function(anchorElement, preferredWidth, preferredHeight, arrowDirection)
{
const borderWidth = this._hasNoMargins ? 0 : 8;
const scrollerWidth = this._hasFixedHeight ? 0 : 14;
const arrowHeight = this._hasNoMargins ? 8 : 15;
const arrowOffset = 10;
const borderRadius = 4;
const arrowRadius = 6;
preferredWidth = preferredWidth || this._preferredWidth;
preferredHeight = preferredHeight || this._preferredHeight;
// Skinny tooltips are not pretty, their arrow location is not nice.
preferredWidth = Math.max(preferredWidth, 50);
// Position relative to main DevTools element.
const container = WebInspector.Dialog.modalHostView().element;
const totalWidth = container.offsetWidth;
const totalHeight = container.offsetHeight;
var anchorBox = anchorElement instanceof AnchorBox ? anchorElement : anchorElement.boxInWindow(window);
anchorBox = anchorBox.relativeToElement(container);
var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
var verticalAlignment;
var roomAbove = anchorBox.y;
var roomBelow = totalHeight - anchorBox.y - anchorBox.height;
this._popupArrowElement.hidden = false;
if ((roomAbove > roomBelow) || (arrowDirection === WebInspector.Popover.Orientation.Bottom)) {
// Positioning above the anchor.
if ((anchorBox.y > newElementPosition.height + arrowHeight + borderRadius) || (arrowDirection === WebInspector.Popover.Orientation.Bottom))
newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
else {
this._popupArrowElement.hidden = true;
newElementPosition.y = borderRadius;
newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = borderRadius;
newElementPosition.height = preferredHeight;
}
}
verticalAlignment = WebInspector.Popover.Orientation.Bottom;
} else {
// Positioning below the anchor.
newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
if ((newElementPosition.y + newElementPosition.height + borderRadius >= totalHeight) && (arrowDirection !== WebInspector.Popover.Orientation.Top)) {
this._popupArrowElement.hidden = true;
newElementPosition.height = totalHeight - borderRadius - newElementPosition.y;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = totalHeight - preferredHeight - borderRadius;
newElementPosition.height = preferredHeight;
}
}
// Align arrow.
verticalAlignment = WebInspector.Popover.Orientation.Top;
}
var horizontalAlignment;
this._popupArrowElement.removeAttribute("style");
if (anchorBox.x + newElementPosition.width < totalWidth) {
newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
horizontalAlignment = "left";
this._popupArrowElement.style.left = arrowOffset + "px";
} else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
newElementPosition.x = totalWidth - newElementPosition.width - borderRadius - 2 * borderWidth;
horizontalAlignment = "right";
// Position arrow accurately.
var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
arrowRightPosition += anchorBox.width / 2;
arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
this._popupArrowElement.style.right = arrowRightPosition + "px";
} else {
newElementPosition.x = borderRadius;
newElementPosition.width = totalWidth - borderRadius * 2;
newElementPosition.height += scrollerWidth;
horizontalAlignment = "left";
if (verticalAlignment === WebInspector.Popover.Orientation.Bottom)
newElementPosition.y -= scrollerWidth;
// Position arrow accurately.
this._popupArrowElement.style.left = Math.max(0, anchorBox.x - newElementPosition.x - borderRadius - arrowRadius + anchorBox.width / 2) + "px";
}
this.element.className = WebInspector.Popover._classNamePrefix + " " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
this.element.positionAt(newElementPosition.x, newElementPosition.y - borderWidth, container);
this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
},
__proto__: WebInspector.Widget.prototype
}
/**
* @constructor
* @param {!Element} panelElement
* @param {function(!Element, !Event):(!Element|!AnchorBox|undefined)} getAnchor
* @param {function(!Element, !WebInspector.Popover):undefined} showPopover
* @param {function()=} onHide
* @param {boolean=} disableOnClick
*/
WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
{
this._getAnchor = getAnchor;
this._showPopover = showPopover;
this._onHide = onHide;
this._disableOnClick = !!disableOnClick;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false);
this.setTimeout(1000, 500);
}
WebInspector.PopoverHelper.prototype = {
/**
* @param {number} timeout
* @param {number=} hideTimeout
*/
setTimeout: function(timeout, hideTimeout)
{
this._timeout = timeout;
if (typeof hideTimeout === "number")
this._hideTimeout = hideTimeout;
else
this._hideTimeout = timeout / 2;
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_eventInHoverElement: function(event)
{
if (!this._hoverElement)
return false;
var box = this._hoverElement instanceof AnchorBox ? this._hoverElement : this._hoverElement.boxInWindow();
return (box.x <= event.clientX && event.clientX <= box.x + box.width &&
box.y <= event.clientY && event.clientY <= box.y + box.height);
},
_mouseDown: function(event)
{
if (this._disableOnClick || !this._eventInHoverElement(event))
this.hidePopover();
else {
this._killHidePopoverTimer();
this._handleMouseAction(event, true);
}
},
_mouseMove: function(event)
{
// Pretend that nothing has happened.
if (this._eventInHoverElement(event))
return;
this._startHidePopoverTimer();
this._handleMouseAction(event, false);
},
_popoverMouseOut: function(event)
{
if (!this.isPopoverVisible())
return;
if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this._popover._contentDiv))
this._startHidePopoverTimer();
},
_mouseOut: function(event)
{
if (!this.isPopoverVisible())
return;
if (!this._eventInHoverElement(event))
this._startHidePopoverTimer();
},
_startHidePopoverTimer: function()
{
// User has 500ms (this._hideTimeout) to reach the popup.
if (!this._popover || this._hidePopoverTimer)
return;
/**
* @this {WebInspector.PopoverHelper}
*/
function doHide()
{
this._hidePopover();
delete this._hidePopoverTimer;
}
this._hidePopoverTimer = setTimeout(doHide.bind(this), this._hideTimeout);
},
_handleMouseAction: function(event, isMouseDown)
{
this._resetHoverTimer();
if (event.which && this._disableOnClick)
return;
this._hoverElement = this._getAnchor(event.target, event);
if (!this._hoverElement)
return;
const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},
_resetHoverTimer: function()
{
if (this._hoverTimer) {
clearTimeout(this._hoverTimer);
delete this._hoverTimer;
}
},
/**
* @return {boolean}
*/
isPopoverVisible: function()
{
return !!this._popover;
},
hidePopover: function()
{
this._resetHoverTimer();
this._hidePopover();
},
_hidePopover: function()
{
if (!this._popover)
return;
if (this._onHide)
this._onHide();
this._popover.dispose();
delete this._popover;
this._hoverElement = null;
},
_mouseHover: function(element)
{
delete this._hoverTimer;
this._hoverElement = element;
this._hidePopover();
this._popover = new WebInspector.Popover(this);
this._showPopover(element, this._popover);
},
_killHidePopoverTimer: function()
{
if (this._hidePopoverTimer) {
clearTimeout(this._hidePopoverTimer);
delete this._hidePopoverTimer;
// We know that we reached the popup, but we might have moved over other elements.
// Discard pending command.
this._resetHoverTimer();
}
}
}
/** @enum {string} */
WebInspector.Popover.Orientation = {
Top: "top",
Bottom: "bottom"
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @implements {WebInspector.Progress}
*/
WebInspector.ProgressIndicator = function()
{
this.element = createElementWithClass("div", "progress-indicator");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/progressIndicator.css");
this._contentElement = this._shadowRoot.createChild("div", "progress-indicator-shadow-container");
this._labelElement = this._contentElement.createChild("div", "title");
this._progressElement = this._contentElement.createChild("progress");
this._progressElement.value = 0;
this._stopButton = this._contentElement.createChild("button", "progress-indicator-shadow-stop-button");
this._stopButton.addEventListener("click", this.cancel.bind(this));
this._isCanceled = false;
this._worked = 0;
}
WebInspector.ProgressIndicator.prototype = {
/**
* @param {!Element} parent
*/
show: function(parent)
{
parent.appendChild(this.element);
},
/**
* @override
*/
done: function()
{
if (this._isDone)
return;
this._isDone = true;
this.element.remove();
},
cancel: function()
{
this._isCanceled = true;
},
/**
* @override
* @return {boolean}
*/
isCanceled: function()
{
return this._isCanceled;
},
/**
* @override
* @param {string} title
*/
setTitle: function(title)
{
this._labelElement.textContent = title;
},
/**
* @override
* @param {number} totalWork
*/
setTotalWork: function(totalWork)
{
this._progressElement.max = totalWork;
},
/**
* @override
* @param {number} worked
* @param {string=} title
*/
setWorked: function(worked, title)
{
this._worked = worked;
this._progressElement.value = worked;
if (title)
this.setTitle(title);
},
/**
* @override
* @param {number=} worked
*/
worked: function(worked)
{
this.setWorked(this._worked + (worked || 1));
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.ResizerWidget = function()
{
WebInspector.Object.call(this);
this._isEnabled = true;
this._elements = [];
this._installDragOnMouseDownBound = this._installDragOnMouseDown.bind(this);
this._cursor = "nwse-resize";
};
WebInspector.ResizerWidget.Events = {
ResizeStart: "ResizeStart",
ResizeUpdate: "ResizeUpdate",
ResizeEnd: "ResizeEnd"
};
WebInspector.ResizerWidget.prototype = {
/**
* @return {boolean}
*/
isEnabled: function()
{
return this._isEnabled;
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._isEnabled = enabled;
this.updateElementCursors();
},
/**
* @return {!Array.<!Element>}
*/
elements: function()
{
return this._elements.slice();
},
/**
* @param {!Element} element
*/
addElement: function(element)
{
if (this._elements.indexOf(element) !== -1)
return;
this._elements.push(element);
element.addEventListener("mousedown", this._installDragOnMouseDownBound, false);
this._updateElementCursor(element);
},
/**
* @param {!Element} element
*/
removeElement: function(element)
{
if (this._elements.indexOf(element) === -1)
return;
this._elements.remove(element);
element.removeEventListener("mousedown", this._installDragOnMouseDownBound, false);
element.style.removeProperty("cursor");
},
updateElementCursors: function()
{
this._elements.forEach(this._updateElementCursor.bind(this));
},
/**
* @param {!Element} element
*/
_updateElementCursor: function(element)
{
if (this._isEnabled)
element.style.setProperty("cursor", this.cursor());
else
element.style.removeProperty("cursor");
},
/**
* @return {string}
*/
cursor: function()
{
return this._cursor;
},
/**
* @param {string} cursor
*/
setCursor: function(cursor)
{
this._cursor = cursor;
this.updateElementCursors();
},
/**
* @param {!Event} event
*/
_installDragOnMouseDown: function(event)
{
// Only handle drags of the nodes specified.
if (this._elements.indexOf(event.target) === -1)
return false;
WebInspector.elementDragStart(/** @type {!Element} */(event.target), this._dragStart.bind(this), this._drag.bind(this), this._dragEnd.bind(this), this.cursor(), event);
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_dragStart: function(event)
{
if (!this._isEnabled)
return false;
this._startX = event.pageX;
this._startY = event.pageY;
this.sendDragStart(this._startX, this._startY);
return true;
},
/**
* @param {number} x
* @param {number} y
*/
sendDragStart: function(x, y)
{
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeStart, { startX: x, currentX: x, startY: y, currentY: y });
},
/**
* @param {!MouseEvent} event
* @return {boolean}
*/
_drag: function(event)
{
if (!this._isEnabled) {
this._dragEnd(event);
return true; // Cancel drag.
}
this.sendDragMove(this._startX, event.pageX, this._startY, event.pageY, event.shiftKey);
event.preventDefault();
return false; // Continue drag.
},
/**
* @param {number} startX
* @param {number} currentX
* @param {number} startY
* @param {number} currentY
* @param {boolean} shiftKey
*/
sendDragMove: function(startX, currentX, startY, currentY, shiftKey)
{
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate, { startX: startX, currentX: currentX, startY: startY, currentY: currentY, shiftKey: shiftKey });
},
/**
* @param {!MouseEvent} event
*/
_dragEnd: function(event)
{
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeEnd);
delete this._startX;
delete this._startY;
},
__proto__: WebInspector.Object.prototype
};
/**
* @constructor
* @extends {WebInspector.ResizerWidget}
*/
WebInspector.SimpleResizerWidget = function()
{
WebInspector.ResizerWidget.call(this);
this._isVertical = true;
};
WebInspector.SimpleResizerWidget.prototype = {
/**
* @return {boolean}
*/
isVertical: function()
{
return this._isVertical;
},
/**
* Vertical widget resizes height (along y-axis).
* @param {boolean} vertical
*/
setVertical: function(vertical)
{
this._isVertical = vertical;
this.updateElementCursors();
},
/**
* @override
* @return {string}
*/
cursor: function()
{
return this._isVertical ? "ns-resize" : "ew-resize";
},
/**
* @override
* @param {number} x
* @param {number} y
*/
sendDragStart: function(x, y)
{
var position = this._isVertical ? y : x;
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeStart, { startPosition: position, currentPosition: position });
},
/**
* @override
* @param {number} startX
* @param {number} currentX
* @param {number} startY
* @param {number} currentY
* @param {boolean} shiftKey
*/
sendDragMove: function(startX, currentX, startY, currentY, shiftKey)
{
if (this._isVertical)
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate, { startPosition: startY, currentPosition: currentY, shiftKey: shiftKey });
else
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate, { startPosition: startX, currentPosition: currentX, shiftKey: shiftKey });
},
__proto__: WebInspector.ResizerWidget.prototype
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.RootView = function()
{
WebInspector.VBox.call(this);
this.markAsRoot();
this.element.classList.add("root-view");
this.element.setAttribute("spellcheck", false);
}
WebInspector.RootView.prototype = {
/**
* @param {!Document} document
*/
attachToDocument: function(document)
{
document.defaultView.addEventListener("resize", this.doResize.bind(this), false);
this._window = document.defaultView;
this.doResize();
this.show(document.body);
},
doResize: function()
{
if (this._window) {
var size = this.constraints().minimum;
var zoom = WebInspector.zoomManager.zoomFactor();
var right = Math.min(0, this._window.innerWidth - size.width / zoom);
this.element.style.marginRight = right + "px";
var bottom = Math.min(0, this._window.innerHeight - size.height / zoom);
this.element.style.marginBottom = bottom + "px";
}
WebInspector.VBox.prototype.doResize.call(this);
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | 2 | /*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
* Copyright (C) 2009 Joseph Pecoraro
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.Searchable} searchable
* @param {string=} settingName
*/
WebInspector.SearchableView = function(searchable, settingName)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("ui/searchableView.css");
this.element[WebInspector.SearchableView._symbol] = this;
this._searchProvider = searchable;
this._setting = settingName ? WebInspector.settings.createSetting(settingName, {}) : null;
this.contentElement.createChild("content");
this._footerElementContainer = this.contentElement.createChild("div", "search-bar hidden");
this._footerElementContainer.style.order = 100;
var toolbar = new WebInspector.Toolbar("search-toolbar", this._footerElementContainer);
if (this._searchProvider.supportsCaseSensitiveSearch()) {
this._caseSensitiveButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Case sensitive"), "");
this._caseSensitiveButton.setText("Aa");
this._caseSensitiveButton.addEventListener("click", this._toggleCaseSensitiveSearch, this);
toolbar.appendToolbarItem(this._caseSensitiveButton);
}
if (this._searchProvider.supportsRegexSearch()) {
this._regexButton = new WebInspector.ToolbarToggle(WebInspector.UIString("Regex"), "");
this._regexButton.setText(".*");
this._regexButton.addEventListener("click", this._toggleRegexSearch, this);
toolbar.appendToolbarItem(this._regexButton);
}
this._footerElement = this._footerElementContainer.createChild("table", "toolbar-search");
this._footerElement.cellSpacing = 0;
this._firstRowElement = this._footerElement.createChild("tr");
this._secondRowElement = this._footerElement.createChild("tr", "hidden");
// Column 1
var searchControlElementColumn = this._firstRowElement.createChild("td");
this._searchControlElement = searchControlElementColumn.createChild("span", "toolbar-search-control");
this._searchInputElement = WebInspector.HistoryInput.create();
this._searchInputElement.classList.add("search-replace");
this._searchControlElement.appendChild(this._searchInputElement);
this._searchInputElement.id = "search-input-field";
this._searchInputElement.placeholder = WebInspector.UIString("Find");
this._matchesElement = this._searchControlElement.createChild("label", "search-results-matches");
this._matchesElement.setAttribute("for", "search-input-field");
this._searchNavigationElement = this._searchControlElement.createChild("div", "toolbar-search-navigation-controls");
this._searchNavigationPrevElement = this._searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-prev");
this._searchNavigationPrevElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);
this._searchNavigationPrevElement.title = WebInspector.UIString("Search Previous");
this._searchNavigationNextElement = this._searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-next");
this._searchNavigationNextElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);
this._searchNavigationNextElement.title = WebInspector.UIString("Search Next");
this._searchInputElement.addEventListener("mousedown", this._onSearchFieldManualFocus.bind(this), false); // when the search field is manually selected
this._searchInputElement.addEventListener("keydown", this._onSearchKeyDown.bind(this), true);
this._searchInputElement.addEventListener("input", this._onInput.bind(this), false);
this._replaceInputElement = this._secondRowElement.createChild("td").createChild("input", "search-replace toolbar-replace-control");
this._replaceInputElement.addEventListener("keydown", this._onReplaceKeyDown.bind(this), true);
this._replaceInputElement.placeholder = WebInspector.UIString("Replace");
// Column 2
this._findButtonElement = this._firstRowElement.createChild("td").createChild("button", "search-action-button hidden");
this._findButtonElement.textContent = WebInspector.UIString("Find");
this._findButtonElement.tabIndex = -1;
this._findButtonElement.addEventListener("click", this._onFindClick.bind(this), false);
this._replaceButtonElement = this._secondRowElement.createChild("td").createChild("button", "search-action-button");
this._replaceButtonElement.textContent = WebInspector.UIString("Replace");
this._replaceButtonElement.disabled = true;
this._replaceButtonElement.tabIndex = -1;
this._replaceButtonElement.addEventListener("click", this._replace.bind(this), false);
// Column 3
this._prevButtonElement = this._firstRowElement.createChild("td").createChild("button", "search-action-button hidden");
this._prevButtonElement.textContent = WebInspector.UIString("Previous");
this._prevButtonElement.tabIndex = -1;
this._prevButtonElement.addEventListener("click", this._onPreviousClick.bind(this), false);
this._replaceAllButtonElement = this._secondRowElement.createChild("td").createChild("button", "search-action-button");
this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace All");
this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bind(this), false);
// Column 4
this._replaceElement = this._firstRowElement.createChild("td").createChild("span");
this._replaceLabelElement = createCheckboxLabel(WebInspector.UIString("Replace"));
this._replaceCheckboxElement = this._replaceLabelElement.checkboxElement;
this._uniqueId = ++WebInspector.SearchableView._lastUniqueId;
var replaceCheckboxId = "search-replace-trigger" + this._uniqueId;
this._replaceCheckboxElement.id = replaceCheckboxId;
this._replaceCheckboxElement.addEventListener("change", this._updateSecondRowVisibility.bind(this), false);
this._replaceElement.appendChild(this._replaceLabelElement);
// Column 5
var cancelButtonElement = this._firstRowElement.createChild("td").createChild("button", "search-action-button");
cancelButtonElement.textContent = WebInspector.UIString("Cancel");
cancelButtonElement.tabIndex = -1;
cancelButtonElement.addEventListener("click", this.closeSearch.bind(this), false);
this._minimalSearchQuerySize = 3;
this._loadSetting();
}
WebInspector.SearchableView._lastUniqueId = 0;
WebInspector.SearchableView._symbol = Symbol("searchableView");
/**
* @param {?Element} element
* @return {?WebInspector.SearchableView}
*/
WebInspector.SearchableView.fromElement = function(element)
{
var view = null;
while (element && !view) {
view = element[WebInspector.SearchableView._symbol];
element = element.parentElementOrShadowHost();
}
return view;
}
WebInspector.SearchableView.prototype = {
_toggleCaseSensitiveSearch: function()
{
this._caseSensitiveButton.setToggled(!this._caseSensitiveButton.toggled());
this._saveSetting();
this._performSearch(false, true);
},
_toggleRegexSearch: function()
{
this._regexButton.setToggled(!this._regexButton.toggled());
this._saveSetting();
this._performSearch(false, true);
},
_saveSetting: function()
{
if (!this._setting)
return;
var settingValue = this._setting.get() || {};
settingValue.caseSensitive = this._caseSensitiveButton.toggled();
settingValue.isRegex = this._regexButton.toggled();
this._setting.set(settingValue);
},
_loadSetting: function()
{
var settingValue = this._setting ? (this._setting.get() || {}) : {};
if (this._searchProvider.supportsCaseSensitiveSearch())
this._caseSensitiveButton.setToggled(!!settingValue.caseSensitive);
if (this._searchProvider.supportsRegexSearch())
this._regexButton.setToggled(!!settingValue.isRegex);
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
var children = this.children();
for (var i = 0; i < children.length; ++i) {
var element = children[i].defaultFocusedElement();
if (element)
return element;
}
return WebInspector.Widget.prototype.defaultFocusedElement.call(this);
},
/**
* @param {number} minimalSearchQuerySize
*/
setMinimalSearchQuerySize: function(minimalSearchQuerySize)
{
this._minimalSearchQuerySize = minimalSearchQuerySize;
},
/**
* @param {string} placeholder
*/
setPlaceholder: function(placeholder)
{
this._searchInputElement.placeholder = placeholder;
},
/**
* @param {boolean} replaceable
*/
setReplaceable: function(replaceable)
{
this._replaceable = replaceable;
},
/**
* @param {number} matches
*/
updateSearchMatchesCount: function(matches)
{
this._searchProvider.currentSearchMatches = matches;
this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentQuery ? matches : 0, -1);
},
/**
* @param {number} currentMatchIndex
*/
updateCurrentMatchIndex: function(currentMatchIndex)
{
this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentSearchMatches, currentMatchIndex);
},
/**
* @return {boolean}
*/
isSearchVisible: function()
{
return this._searchIsVisible;
},
closeSearch: function()
{
this.cancelSearch();
if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().isDescendant(this._footerElementContainer))
this.focus();
},
_toggleSearchBar: function(toggled)
{
this._footerElementContainer.classList.toggle("hidden", !toggled);
this.doResize();
},
cancelSearch: function()
{
if (!this._searchIsVisible)
return;
this.resetSearch();
delete this._searchIsVisible;
this._toggleSearchBar(false);
},
resetSearch: function()
{
this._clearSearch();
this._updateReplaceVisibility();
this._matchesElement.textContent = "";
},
refreshSearch: function()
{
if (!this._searchIsVisible)
return;
this.resetSearch();
this._performSearch(false, false);
},
/**
* @return {boolean}
*/
handleFindNextShortcut: function()
{
if (!this._searchIsVisible)
return false;
this._searchProvider.jumpToNextSearchResult();
return true;
},
/**
* @return {boolean}
*/
handleFindPreviousShortcut: function()
{
if (!this._searchIsVisible)
return false;
this._searchProvider.jumpToPreviousSearchResult();
return true;
},
/**
* @return {boolean}
*/
handleFindShortcut: function()
{
this.showSearchField();
return true;
},
/**
* @return {boolean}
*/
handleCancelSearchShortcut: function()
{
if (!this._searchIsVisible)
return false;
this.closeSearch();
return true;
},
/**
* @param {boolean} enabled
*/
_updateSearchNavigationButtonState: function(enabled)
{
this._replaceButtonElement.disabled = !enabled;
if (enabled) {
this._searchNavigationPrevElement.classList.add("enabled");
this._searchNavigationNextElement.classList.add("enabled");
} else {
this._searchNavigationPrevElement.classList.remove("enabled");
this._searchNavigationNextElement.classList.remove("enabled");
}
},
/**
* @param {number} matches
* @param {number} currentMatchIndex
*/
_updateSearchMatchesCountAndCurrentMatchIndex: function(matches, currentMatchIndex)
{
if (!this._currentQuery)
this._matchesElement.textContent = "";
else if (matches === 0 || currentMatchIndex >= 0)
this._matchesElement.textContent = WebInspector.UIString("%d of %d", currentMatchIndex + 1, matches);
else if (matches === 1)
this._matchesElement.textContent = WebInspector.UIString("1 match");
else
this._matchesElement.textContent = WebInspector.UIString("%d matches", matches);
this._updateSearchNavigationButtonState(matches > 0);
},
showSearchField: function()
{
if (this._searchIsVisible)
this.cancelSearch();
var queryCandidate;
if (WebInspector.currentFocusElement() !== this._searchInputElement) {
var selection = this._searchInputElement.getComponentSelection();
if (selection.rangeCount)
queryCandidate = selection.toString().replace(/\r?\n.*/, "");
}
this._toggleSearchBar(true);
this._updateReplaceVisibility();
if (queryCandidate)
this._searchInputElement.value = queryCandidate;
this._performSearch(false, false);
this._searchInputElement.focus();
this._searchInputElement.select();
this._searchIsVisible = true;
},
_updateReplaceVisibility: function()
{
this._replaceElement.classList.toggle("hidden", !this._replaceable);
if (!this._replaceable) {
this._replaceCheckboxElement.checked = false;
this._updateSecondRowVisibility();
}
},
/**
* @param {!Event} event
*/
_onSearchFieldManualFocus: function(event)
{
WebInspector.setCurrentFocusElement(/** @type {?Node} */ (event.target));
},
/**
* @param {!Event} event
*/
_onSearchKeyDown: function(event)
{
if (!isEnterKey(event))
return;
if (!this._currentQuery)
this._performSearch(true, true, event.shiftKey);
else
this._jumpToNextSearchResult(event.shiftKey);
},
/**
* @param {!Event} event
*/
_onReplaceKeyDown: function(event)
{
if (isEnterKey(event))
this._replace();
},
/**
* @param {boolean=} isBackwardSearch
*/
_jumpToNextSearchResult: function(isBackwardSearch)
{
if (!this._currentQuery || !this._searchNavigationPrevElement.classList.contains("enabled"))
return;
if (isBackwardSearch)
this._searchProvider.jumpToPreviousSearchResult();
else
this._searchProvider.jumpToNextSearchResult();
},
_onNextButtonSearch: function(event)
{
if (!this._searchNavigationNextElement.classList.contains("enabled"))
return;
this._jumpToNextSearchResult();
this._searchInputElement.focus();
},
_onPrevButtonSearch: function(event)
{
if (!this._searchNavigationPrevElement.classList.contains("enabled"))
return;
this._jumpToNextSearchResult(true);
this._searchInputElement.focus();
},
_onFindClick: function(event)
{
if (!this._currentQuery)
this._performSearch(true, true);
else
this._jumpToNextSearchResult();
this._searchInputElement.focus();
},
_onPreviousClick: function(event)
{
if (!this._currentQuery)
this._performSearch(true, true, true);
else
this._jumpToNextSearchResult(true);
this._searchInputElement.focus();
},
_clearSearch: function()
{
delete this._currentQuery;
if (!!this._searchProvider.currentQuery) {
delete this._searchProvider.currentQuery;
this._searchProvider.searchCanceled();
}
this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1);
},
/**
* @param {boolean} forceSearch
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
_performSearch: function(forceSearch, shouldJump, jumpBackwards)
{
var query = this._searchInputElement.value;
if (!query || (!forceSearch && query.length < this._minimalSearchQuerySize && !this._currentQuery)) {
this._clearSearch();
return;
}
this._currentQuery = query;
this._searchProvider.currentQuery = query;
var searchConfig = this._currentSearchConfig();
this._searchProvider.performSearch(searchConfig, shouldJump, jumpBackwards);
},
/**
* @return {!WebInspector.SearchableView.SearchConfig}
*/
_currentSearchConfig: function()
{
var query = this._searchInputElement.value;
var caseSensitive = this._caseSensitiveButton ? this._caseSensitiveButton.toggled() : false;
var isRegex = this._regexButton ? this._regexButton.toggled() : false;
return new WebInspector.SearchableView.SearchConfig(query, caseSensitive, isRegex);
},
_updateSecondRowVisibility: function()
{
var secondRowVisible = this._replaceCheckboxElement.checked;
this._footerElementContainer.classList.toggle("replaceable", secondRowVisible);
this._footerElement.classList.toggle("toolbar-search-replace", secondRowVisible);
this._secondRowElement.classList.toggle("hidden", !secondRowVisible);
this._prevButtonElement.classList.toggle("hidden", !secondRowVisible);
this._findButtonElement.classList.toggle("hidden", !secondRowVisible);
this._replaceCheckboxElement.tabIndex = secondRowVisible ? -1 : 0;
if (secondRowVisible)
this._replaceInputElement.focus();
else
this._searchInputElement.focus();
this.doResize();
},
_replace: function()
{
var searchConfig = this._currentSearchConfig();
/** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceSelectionWith(searchConfig, this._replaceInputElement.value);
delete this._currentQuery;
this._performSearch(true, true);
},
_replaceAll: function()
{
var searchConfig = this._currentSearchConfig();
/** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceAllWith(searchConfig, this._replaceInputElement.value);
},
/**
* @param {!Event} event
*/
_onInput: function(event)
{
if (this._valueChangedTimeoutId)
clearTimeout(this._valueChangedTimeoutId);
var timeout = this._searchInputElement.value.length < 3 ? 200 : 0;
this._valueChangedTimeoutId = setTimeout(this._onValueChanged.bind(this), timeout);
},
_onValueChanged: function()
{
delete this._valueChangedTimeoutId;
this._performSearch(false, true);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @interface
*/
WebInspector.Searchable = function()
{
}
WebInspector.Searchable.prototype = {
searchCanceled: function() { },
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean=} jumpBackwards
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards) { },
jumpToNextSearchResult: function() { },
jumpToPreviousSearchResult: function() { },
/**
* @return {boolean}
*/
supportsCaseSensitiveSearch: function() { },
/**
* @return {boolean}
*/
supportsRegexSearch: function() { }
}
/**
* @interface
*/
WebInspector.Replaceable = function()
{
}
WebInspector.Replaceable.prototype = {
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceSelectionWith: function(searchConfig, replacement) { },
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {string} replacement
*/
replaceAllWith: function(searchConfig, replacement) { }
}
/**
* @constructor
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
*/
WebInspector.SearchableView.SearchConfig = function(query, caseSensitive, isRegex)
{
this.query = query;
this.caseSensitive = caseSensitive;
this.isRegex = isRegex;
}
WebInspector.SearchableView.SearchConfig.prototype = {
/**
* @param {boolean=} global
* @return {!RegExp}
*/
toSearchRegex: function(global)
{
var modifiers = this.caseSensitive ? "" : "i";
if (global)
modifiers += "g";
var query = this.isRegex ? "/" + this.query + "/" : this.query;
var regex;
// First try creating regex if user knows the / / hint.
try {
if (/^\/.+\/$/.test(query)) {
regex = new RegExp(query.substring(1, query.length - 1), modifiers);
regex.__fromRegExpQuery = true;
}
} catch (e) {
// Silent catch.
}
// Otherwise just do a plain text search.
if (!regex)
regex = createPlainTextSearchRegex(query, modifiers);
return regex;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | 2 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string|!Node} title
* @param {string=} subtitle
*/
WebInspector.Section = function(title, subtitle)
{
this.element = createElementWithClass("div", "section");
this.element._section = this;
this.registerRequiredCSS("ui/section.css");
this.headerElement = createElementWithClass("div", "header monospace");
this.titleElement = createElementWithClass("div", "title");
this.subtitleElement = createElementWithClass("div", "subtitle");
this.headerElement.appendChild(this.subtitleElement);
this.headerElement.appendChild(this.titleElement);
this.headerElement.addEventListener("click", this.handleClick.bind(this), false);
this.element.appendChild(this.headerElement);
this.title = title;
if (subtitle) {
this._subtitle = subtitle;
this.subtitleElement.textContent = subtitle;
}
this._expanded = false;
}
WebInspector.Section.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
if (x instanceof Node) {
this.titleElement.removeChildren();
this.titleElement.appendChild(x);
} else
this.titleElement.textContent = x;
},
get subtitle()
{
return this._subtitle;
},
get expanded()
{
return this._expanded;
},
repopulate: function()
{
this._populated = false;
if (this._expanded) {
this.onpopulate();
this._populated = true;
}
},
/**
* @protected
*/
onpopulate: function()
{
// Overridden by subclasses.
},
expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.classList.add("expanded");
if (!this._populated) {
this.onpopulate();
this._populated = true;
}
},
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.classList.remove("expanded");
},
/**
* @param {string} cssFile
*/
registerRequiredCSS: function(cssFile)
{
WebInspector.appendStyle(this.element, cssFile);
},
/**
* @param {!Event} event
* @protected
*/
handleClick: function(event)
{
if (this._doNotExpandOnTitleClick)
return;
if (this._expanded)
this.collapse();
else
this.expand();
event.consume();
},
doNotExpandOnTitleClick: function()
{
this._doNotExpandOnTitleClick = true;
}
}
/**
* @constructor
* @extends {WebInspector.Section}
* @param {string|!Node} title
* @param {string=} subtitle
*/
WebInspector.PropertiesSection = function(title, subtitle)
{
WebInspector.Section.call(this, title, subtitle);
this.registerRequiredCSS("ui/propertiesSection.css");
this.propertiesTreeOutline = new TreeOutline(true);
this.propertiesElement = this.propertiesTreeOutline.element;
this.propertiesElement.classList.add("properties", "properties-tree", "monospace");
this.propertiesTreeOutline.setFocusable(false);
this.propertiesTreeOutline.section = this;
this.element.appendChild(this.propertiesElement);
}
WebInspector.PropertiesSection.prototype = {
__proto__: WebInspector.Section.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 2 1 1 1 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.SettingsUI = {}
/**
* @param {string} name
* @param {!WebInspector.Setting} setting
* @param {boolean=} omitParagraphElement
* @param {string=} tooltip
* @return {!Element}
*/
WebInspector.SettingsUI.createSettingCheckbox = function(name, setting, omitParagraphElement, tooltip)
{
var label = createCheckboxLabel(name);
if (tooltip)
label.title = tooltip;
var input = label.checkboxElement;
input.name = name;
WebInspector.SettingsUI.bindCheckbox(input, setting);
if (omitParagraphElement)
return label;
var p = createElement("p");
p.appendChild(label);
return p;
}
/**
* @param {!Element} input
* @param {!WebInspector.Setting} setting
*/
WebInspector.SettingsUI.bindCheckbox = function(input, setting)
{
function settingChanged()
{
if (input.checked !== setting.get())
input.checked = setting.get();
}
setting.addChangeListener(settingChanged);
settingChanged();
function inputChanged()
{
if (setting.get() !== input.checked)
setting.set(input.checked);
}
input.addEventListener("change", inputChanged, false);
}
/**
* @param {string} name
* @param {!Element} element
* @return {!Element}
*/
WebInspector.SettingsUI.createCustomSetting = function(name, element)
{
var p = createElement("p");
var fieldsetElement = p.createChild("fieldset");
fieldsetElement.createChild("label").textContent = name;
fieldsetElement.appendChild(element);
return p;
}
/**
* @param {!WebInspector.Setting} setting
* @return {!Element}
*/
WebInspector.SettingsUI.createSettingFieldset = function(setting)
{
var fieldset = createElement("fieldset");
fieldset.disabled = !setting.get();
setting.addChangeListener(settingChanged);
return fieldset;
function settingChanged()
{
fieldset.disabled = !setting.get();
}
}
/**
* @interface
*/
WebInspector.SettingUI = function()
{
}
WebInspector.SettingUI.prototype = {
/**
* @return {?Element}
*/
settingElement: function() { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | 2 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.ActionRegistry} actionRegistry
* @param {!Document} document
*/
WebInspector.ShortcutRegistry = function(actionRegistry, document)
{
this._actionRegistry = actionRegistry;
/** @type {!Multimap.<string, string>} */
this._defaultKeyToActions = new Multimap();
/** @type {!Multimap.<string, !WebInspector.KeyboardShortcut.Descriptor>} */
this._defaultActionToShortcut = new Multimap();
this._registerBindings(document);
}
WebInspector.ShortcutRegistry.prototype = {
/**
* @param {number} key
* @return {!Array.<!WebInspector.Action>}
*/
_applicableActions: function(key)
{
return this._actionRegistry.applicableActions(this._defaultActionsForKey(key).valuesArray(), WebInspector.context);
},
/**
* @param {number} key
* @return {!Set.<string>}
*/
_defaultActionsForKey: function(key)
{
return this._defaultKeyToActions.get(String(key));
},
/**
* @param {string} actionId
* @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
*/
shortcutDescriptorsForAction: function(actionId)
{
return this._defaultActionToShortcut.get(actionId).valuesArray();
},
/**
* @param {!Array.<string>} actionIds
* @return {!Array.<number>}
*/
keysForActions: function(actionIds)
{
var result = [];
for (var i = 0; i < actionIds.length; ++i) {
var descriptors = this.shortcutDescriptorsForAction(actionIds[i]);
for (var j = 0; j < descriptors.length; ++j)
result.push(descriptors[j].key);
}
return result;
},
/**
* @param {string} actionId
* @return {string|undefined}
*/
shortcutTitleForAction: function(actionId)
{
var descriptors = this.shortcutDescriptorsForAction(actionId);
if (descriptors.length)
return descriptors[0].name;
},
/**
* @param {!KeyboardEvent} event
*/
handleShortcut: function(event)
{
this.handleKey(WebInspector.KeyboardShortcut.makeKeyFromEvent(event), event.keyIdentifier, event);
},
/**
* @param {number} key
* @param {string} keyIdentifier
* @param {!KeyboardEvent=} event
*/
handleKey: function(key, keyIdentifier, event)
{
var keyModifiers = key >> 8;
var actions = this._applicableActions(key);
if (!actions.length)
return;
if (WebInspector.GlassPane.DefaultFocusedViewStack.length > 1) {
if (event && !isPossiblyInputKey())
event.consume(true);
return;
}
if (!isPossiblyInputKey()) {
if (event)
event.consume(true);
processNextAction.call(this, false);
} else {
this._pendingActionTimer = setTimeout(processNextAction.bind(this, false), 0);
}
/**
* @param {boolean} handled
* @this {WebInspector.ShortcutRegistry}
*/
function processNextAction(handled)
{
delete this._pendingActionTimer;
var action = actions.shift();
if (!action || handled)
return;
action.execute().then(processNextAction.bind(this));
}
/**
* @return {boolean}
*/
function isPossiblyInputKey()
{
if (!event || !WebInspector.isEditing() || /^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier))
return false;
if (!keyModifiers)
return true;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;
if ((keyModifiers & (modifiers.Ctrl | modifiers.Alt)) === (modifiers.Ctrl | modifiers.Alt))
return WebInspector.isWin();
return !hasModifier(modifiers.Ctrl) && !hasModifier(modifiers.Alt) && !hasModifier(modifiers.Meta);
}
/**
* @param {number} mod
* @return {boolean}
*/
function hasModifier(mod)
{
return !!(keyModifiers & mod);
}
},
/**
* @param {string} actionId
* @param {string} shortcut
*/
registerShortcut: function(actionId, shortcut)
{
var descriptor = WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut(shortcut);
if (!descriptor)
return;
this._defaultActionToShortcut.set(actionId, descriptor);
this._defaultKeyToActions.set(String(descriptor.key), actionId);
},
dismissPendingShortcutAction: function()
{
if (this._pendingActionTimer) {
clearTimeout(this._pendingActionTimer);
delete this._pendingActionTimer;
}
},
/**
* @param {!Document} document
*/
_registerBindings: function(document)
{
document.addEventListener("input", this.dismissPendingShortcutAction.bind(this), true);
var extensions = self.runtime.extensions(WebInspector.ActionDelegate);
extensions.forEach(registerExtension, this);
/**
* @param {!Runtime.Extension} extension
* @this {WebInspector.ShortcutRegistry}
*/
function registerExtension(extension)
{
var descriptor = extension.descriptor();
var bindings = descriptor["bindings"];
for (var i = 0; bindings && i < bindings.length; ++i) {
if (!platformMatches(bindings[i].platform))
continue;
var shortcuts = bindings[i]["shortcut"].split(/\s+/);
shortcuts.forEach(this.registerShortcut.bind(this, descriptor["actionId"]));
}
}
/**
* @param {string=} platformsString
* @return {boolean}
*/
function platformMatches(platformsString)
{
if (!platformsString)
return true;
var platforms = platformsString.split(",");
var isMatch = false;
var currentPlatform = WebInspector.platform();
for (var i = 0; !isMatch && i < platforms.length; ++i)
isMatch = platforms[i] === currentPlatform;
return isMatch;
}
}
}
/**
* @constructor
*/
WebInspector.ShortcutRegistry.ForwardedShortcut = function()
{
}
WebInspector.ShortcutRegistry.ForwardedShortcut.instance = new WebInspector.ShortcutRegistry.ForwardedShortcut();
/** @type {!WebInspector.ShortcutRegistry} */
WebInspector.shortcutRegistry;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | 2 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {string} title
*/
WebInspector.SidebarPane = function(title)
{
WebInspector.Widget.call(this);
this.setMinimumSize(25, 0);
this.element.className = "sidebar-pane"; // Override
this._title = title;
this._expandCallback = null;
this._paneVisible = true;
}
WebInspector.SidebarPane.prototype = {
/**
* @return {!WebInspector.Toolbar}
*/
toolbar: function()
{
if (!this._toolbar) {
this._toolbar = new WebInspector.Toolbar("");
this._toolbar.element.addEventListener("click", consumeEvent);
this.element.insertBefore(this._toolbar.element, this.element.firstChild);
}
return this._toolbar;
},
/**
* @return {string}
*/
title: function()
{
return this._title;
},
expand: function()
{
this.onContentReady();
},
onContentReady: function()
{
if (this._expandCallback)
this._expandCallback();
else
this._expandPending = true;
},
/**
* @param {function(boolean)} setVisibleCallback
* @param {function()} expandCallback
*/
_attached: function(setVisibleCallback, expandCallback)
{
this._setVisibleCallback = setVisibleCallback;
this._setVisibleCallback(this._paneVisible);
this._expandCallback = expandCallback;
if (this._expandPending) {
delete this._expandPending;
this._expandCallback();
}
},
/**
* @param {boolean} visible
*/
setVisible: function(visible)
{
this._paneVisible = visible;
if (this._setVisibleCallback)
this._setVisibleCallback(visible)
},
__proto__: WebInspector.Widget.prototype
}
/**
* @constructor
* @param {!Element} container
* @param {!WebInspector.SidebarPane} pane
*/
WebInspector.SidebarPaneTitle = function(container, pane)
{
this._pane = pane;
this.element = container.createChild("div", "sidebar-pane-title");
this.element.textContent = pane.title();
this.element.tabIndex = 0;
this.element.addEventListener("click", this._toggleExpanded.bind(this), false);
this.element.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);
}
WebInspector.SidebarPaneTitle.prototype = {
_expand: function()
{
this.element.classList.add("expanded");
this._pane.show(this.element.parentElement, /** @type {?Element} */ (this.element.nextSibling));
},
_collapse: function()
{
this.element.classList.remove("expanded");
if (this._pane.element.parentNode == this.element.parentNode)
this._pane.detach();
},
_toggleExpanded: function()
{
if (this.element.classList.contains("expanded"))
this._collapse();
else
this._pane.expand();
},
/**
* @param {!Event} event
*/
_onTitleKeyDown: function(event)
{
if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
this._toggleExpanded();
}
}
/**
* @constructor
* @extends {WebInspector.Widget}
*/
WebInspector.SidebarPaneStack = function()
{
WebInspector.Widget.call(this);
this.setMinimumSize(25, 0);
this.element.className = "sidebar-pane-stack"; // Override
/** @type {!Map.<!WebInspector.SidebarPane, !WebInspector.SidebarPaneTitle>} */
this._titleByPane = new Map();
}
WebInspector.SidebarPaneStack.prototype = {
/**
* @param {!WebInspector.SidebarPane} pane
*/
addPane: function(pane)
{
var paneTitle = new WebInspector.SidebarPaneTitle(this.element, pane);
this._titleByPane.set(pane, paneTitle);
if (pane._toolbar)
paneTitle.element.appendChild(pane._toolbar.element);
pane._attached(this._setPaneVisible.bind(this, pane), paneTitle._expand.bind(paneTitle));
},
/**
* @param {!WebInspector.SidebarPane} pane
* @param {boolean} visible
*/
_setPaneVisible: function(pane, visible)
{
var title = this._titleByPane.get(pane);
if (!title)
return;
title.element.classList.toggle("hidden", !visible);
pane.element.classList.toggle("sidebar-pane-hidden", !visible);
},
__proto__: WebInspector.Widget.prototype
}
/**
* @constructor
* @extends {WebInspector.TabbedPane}
*/
WebInspector.SidebarTabbedPane = function()
{
WebInspector.TabbedPane.call(this);
this.element.classList.add("sidebar-tabbed-pane");
}
WebInspector.SidebarTabbedPane.prototype = {
/**
* @param {!WebInspector.SidebarPane} pane
*/
addPane: function(pane)
{
var title = pane.title();
this.appendTab(title, title, pane);
if (pane._toolbar)
pane.element.insertBefore(pane._toolbar.element, pane.element.firstChild);
pane._attached(this._setPaneVisible.bind(this, pane), this.selectTab.bind(this, title));
},
/**
* @param {!WebInspector.SidebarPane} pane
* @param {boolean} visible
*/
_setPaneVisible: function(pane, visible)
{
var title = pane._title;
if (visible) {
if (!this.hasTab(title))
this.appendTab(title, title, pane);
} else {
if (this.hasTab(title))
this.closeTab(title);
}
},
__proto__: WebInspector.TabbedPane.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | 2 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {TreeElement}
* @param {string} title
*/
WebInspector.SidebarSectionTreeElement = function(title)
{
TreeElement.call(this, title.escapeHTML(), true);
this.expand();
}
WebInspector.SidebarSectionTreeElement.prototype = {
selectable: false,
collapse: function()
{
// Should not collapse as it is not selectable.
},
get smallChildren()
{
return this._smallChildren;
},
set smallChildren(x)
{
if (this._smallChildren === x)
return;
this._smallChildren = x;
this._childrenListNode.classList.toggle("small", this._smallChildren);
},
onattach: function()
{
this.listItemElement.classList.add("sidebar-tree-section");
},
__proto__: TreeElement.prototype
}
/**
* @constructor
* @extends {TreeElement}
* @param {string} className
* @param {string} title
* @param {string=} subtitle
* @param {boolean=} expandable
*/
WebInspector.SidebarTreeElement = function(className, title, subtitle, expandable)
{
TreeElement.call(this, "", expandable);
if (expandable)
this.disclosureButton = createElementWithClass("button", "disclosure-button");
this.iconElement = createElementWithClass("div", "icon");
this.statusElement = createElementWithClass("div", "status");
this._titlesElement = createElementWithClass("div", "titles");
this.titleContainer = this._titlesElement.createChild("span", "title-container");
this.titleElement = this.titleContainer.createChild("span", "title");
this.subtitleElement = this._titlesElement.createChild("span", "subtitle");
this.className = className;
this.mainTitle = title;
this.subtitle = subtitle;
}
WebInspector.SidebarTreeElement.prototype = {
get small()
{
return this._small;
},
set small(x)
{
this._small = x;
if (this.listItemElement)
this.listItemElement.classList.toggle("small", this._small);
},
get mainTitle()
{
return this._mainTitle;
},
set mainTitle(x)
{
this._mainTitle = x;
this.refreshTitles();
},
get subtitle()
{
return this._subtitle;
},
set subtitle(x)
{
this._subtitle = x;
this.refreshTitles();
},
set wait(x)
{
this.listItemElement.classList.toggle("wait", x);
},
refreshTitles: function()
{
var mainTitle = this.mainTitle;
if (this.titleElement.textContent !== mainTitle)
this.titleElement.textContent = mainTitle;
var subtitle = this.subtitle;
if (subtitle) {
if (this.subtitleElement.textContent !== subtitle)
this.subtitleElement.textContent = subtitle;
this._titlesElement.classList.remove("no-subtitle");
} else {
this.subtitleElement.textContent = "";
this._titlesElement.classList.add("no-subtitle");
}
},
/**
* @override
* @return {boolean}
*/
isEventWithinDisclosureTriangle: function(event)
{
return event.target === this.disclosureButton;
},
onattach: function()
{
this.listItemElement.classList.add("sidebar-tree-item");
if (this.className)
this.listItemElement.classList.add(this.className);
if (this.small)
this.listItemElement.classList.add("small");
if (this.isExpandable() && this.disclosureButton)
this.listItemElement.appendChild(this.disclosureButton);
this.listItemElement.appendChildren(this.iconElement, this.statusElement, this._titlesElement);
},
__proto__: TreeElement.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | 2 | /*
* Copyright (C) 2011 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
* @param {function(string)} itemSelectedCallback
* @param {!WebInspector.SoftContextMenu=} parentMenu
*/
WebInspector.SoftContextMenu = function(items, itemSelectedCallback, parentMenu)
{
this._items = items;
this._itemSelectedCallback = itemSelectedCallback;
this._parentMenu = parentMenu;
}
WebInspector.SoftContextMenu.prototype = {
/**
* @param {!Document} document
* @param {number} x
* @param {number} y
*/
show: function(document, x, y)
{
if (!this._items.length)
return;
this._document = document;
this._x = x;
this._y = y;
this._time = new Date().getTime();
// Create context menu.
this.element = createElementWithClass("div", "soft-context-menu");
var root = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/softContextMenu.css");
this._contextMenuElement = root.createChild("div");
this.element.style.top = y + "px";
var subMenuOverlap = 3;
this.element.style.left = (this._parentMenu ? x - subMenuOverlap : x) + "px";
this._contextMenuElement.tabIndex = 0;
this._contextMenuElement.addEventListener("mouseup", consumeEvent, false);
this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);
for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
// Install glass pane capturing events.
if (!this._parentMenu) {
this._glassPaneElement = createElementWithClass("div", "soft-context-menu-glass-pane fill");
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
this._glassPaneElement.appendChild(this.element);
document.body.appendChild(this._glassPaneElement);
this._discardMenuOnResizeListener = this._discardMenu.bind(this, true);
document.defaultView.addEventListener("resize", this._discardMenuOnResizeListener, false);
} else {
this._parentMenu._parentGlassPaneElement().appendChild(this.element);
}
// Re-position menu in case it does not fit.
if (document.body.offsetWidth < this.element.offsetLeft + this.element.offsetWidth) {
this.element.style.left = Math.max(WebInspector.Dialog.modalHostView().element.totalOffsetLeft(), this._parentMenu
? this._parentMenu.element.offsetLeft - this.element.offsetWidth + subMenuOverlap
: document.body.offsetWidth - this.element.offsetWidth) + "px";
}
// Move submenus upwards if it does not fit.
if (this._parentMenu && document.body.offsetHeight < this.element.offsetTop + this.element.offsetHeight) {
y = Math.max(WebInspector.Dialog.modalHostView().element.totalOffsetTop(), document.body.offsetHeight - this.element.offsetHeight);
this.element.style.top = y + "px";
}
var maxHeight = WebInspector.Dialog.modalHostView().element.offsetHeight;
maxHeight -= y - WebInspector.Dialog.modalHostView().element.totalOffsetTop();
this.element.style.maxHeight = maxHeight + "px";
this._focus();
},
discard: function()
{
this._discardMenu(true);
},
_parentGlassPaneElement: function()
{
if (this._glassPaneElement)
return this._glassPaneElement;
if (this._parentMenu)
return this._parentMenu._parentGlassPaneElement();
return null;
},
_createMenuItem: function(item)
{
if (item.type === "separator")
return this._createSeparator();
if (item.type === "subMenu")
return this._createSubMenu(item);
var menuItemElement = createElementWithClass("div", "soft-context-menu-item");
var checkMarkElement = menuItemElement.createChild("div", "checkmark");
if (!item.checked)
checkMarkElement.style.opacity = "0";
if (item.element) {
var wrapper = menuItemElement.createChild("div", "soft-context-menu-custom-item");
wrapper.appendChild(item.element);
menuItemElement._isCustom = true;
return menuItemElement;
}
if (!item.enabled)
menuItemElement.classList.add("soft-context-menu-disabled");
menuItemElement.createTextChild(item.label);
menuItemElement.createChild("span", "soft-context-menu-shortcut").textContent = item.shortcut;
menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
// Manually manage hover highlight since :hover does not work in case of click-and-hold menu invocation.
menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseleave", this._menuItemMouseLeave.bind(this), false);
menuItemElement._actionId = item.id;
return menuItemElement;
},
_createSubMenu: function(item)
{
var menuItemElement = createElementWithClass("div", "soft-context-menu-item");
menuItemElement._subItems = item.subItems;
// Occupy the same space on the left in all items.
var checkMarkElement = menuItemElement.createChild("span", "soft-context-menu-item-checkmark checkmark");
checkMarkElement.textContent = "\u2713 "; // Checkmark Unicode symbol
checkMarkElement.style.opacity = "0";
menuItemElement.createTextChild(item.label);
var subMenuArrowElement = menuItemElement.createChild("span", "soft-context-menu-item-submenu-arrow");
subMenuArrowElement.textContent = "\u25B6"; // BLACK RIGHT-POINTING TRIANGLE
menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
// Manually manage hover highlight since :hover does not work in case of click-and-hold menu invocation.
menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseleave", this._menuItemMouseLeave.bind(this), false);
return menuItemElement;
},
_createSeparator: function()
{
var separatorElement = createElementWithClass("div", "soft-context-menu-separator");
separatorElement._isSeparator = true;
separatorElement.createChild("div", "separator-line");
return separatorElement;
},
_menuItemMouseDown: function(event)
{
// Do not let separator's mouse down hit menu's handler - we need to receive mouse up!
event.consume(true);
},
_menuItemMouseUp: function(event)
{
this._triggerAction(event.target, event);
event.consume();
},
_focus: function()
{
this._contextMenuElement.focus();
},
_triggerAction: function(menuItemElement, event)
{
if (!menuItemElement._subItems) {
this._discardMenu(true, event);
if (typeof menuItemElement._actionId !== "undefined") {
this._itemSelectedCallback(menuItemElement._actionId);
delete menuItemElement._actionId;
}
return;
}
this._showSubMenu(menuItemElement);
event.consume();
},
_showSubMenu: function(menuItemElement)
{
if (menuItemElement._subMenuTimer) {
clearTimeout(menuItemElement._subMenuTimer);
delete menuItemElement._subMenuTimer;
}
if (this._subMenu)
return;
this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this._itemSelectedCallback, this);
var topPadding = 4;
this._subMenu.show(this._document, menuItemElement.totalOffsetLeft() + menuItemElement.offsetWidth, menuItemElement.totalOffsetTop() - 1 - topPadding);
},
_hideSubMenu: function()
{
if (!this._subMenu)
return;
this._subMenu._discardSubMenus();
this._focus();
},
_menuItemMouseOver: function(event)
{
this._highlightMenuItem(event.target, true);
},
_menuItemMouseLeave: function(event)
{
if (!this._subMenu || !event.relatedTarget) {
this._highlightMenuItem(null, true);
return;
}
var relatedTarget = event.relatedTarget;
if (relatedTarget.classList.contains("soft-context-menu-glass-pane"))
this._highlightMenuItem(null, true);
},
/**
* @param {?Element} menuItemElement
* @param {boolean} scheduleSubMenu
*/
_highlightMenuItem: function(menuItemElement, scheduleSubMenu)
{
if (this._highlightedMenuItemElement === menuItemElement)
return;
this._hideSubMenu();
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.classList.remove("soft-context-menu-item-mouse-over");
if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
delete this._highlightedMenuItemElement._subMenuTimer;
}
}
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.classList.add("soft-context-menu-item-mouse-over");
this._contextMenuElement.focus();
if (scheduleSubMenu && this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer)
this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement), 150);
}
},
_highlightPrevious: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement, false);
},
_highlightNext: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement, false);
},
_menuKeyDown: function(event)
{
switch (event.keyIdentifier) {
case "Up":
this._highlightPrevious(); break;
case "Down":
this._highlightNext(); break;
case "Left":
if (this._parentMenu) {
this._highlightMenuItem(null, false);
this._parentMenu._hideSubMenu();
}
break;
case "Right":
if (!this._highlightedMenuItemElement)
break;
if (this._highlightedMenuItemElement._subItems) {
this._showSubMenu(this._highlightedMenuItemElement);
this._subMenu._focus();
this._subMenu._highlightNext();
}
break;
case "U+001B": // Escape
this._discardMenu(false, event); break;
case "Enter":
if (!isEnterKey(event))
break;
// Fall through
case "U+0020": // Space
if (this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement, event);
if (this._highlightedMenuItemElement._subItems) {
this._subMenu._focus();
this._subMenu._highlightNext();
}
break;
}
event.consume(true);
},
_glassPaneMouseUp: function(event)
{
// Return if this is simple 'click', since dispatched on glass pane, can't use 'click' event.
if (new Date().getTime() - this._time < 300)
return;
if (event.target === this.element)
return;
this._discardMenu(true, event);
event.consume();
},
/**
* @param {boolean} closeParentMenus
* @param {!Event=} event
*/
_discardMenu: function(closeParentMenus, event)
{
if (this._subMenu && !closeParentMenus)
return;
if (this._glassPaneElement) {
var glassPane = this._glassPaneElement;
delete this._glassPaneElement;
// This can re-enter discardMenu due to blur.
this._document.body.removeChild(glassPane);
if (this._parentMenu) {
delete this._parentMenu._subMenu;
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
else
this._parentMenu._focus();
}
if (event)
event.consume(true);
} else if (this._parentMenu && this._contextMenuElement.parentElementOrShadowHost()) {
this._discardSubMenus();
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
else
this._parentMenu._focus();
if (event)
event.consume(true);
}
if (this._discardMenuOnResizeListener) {
this._document.defaultView.removeEventListener("resize", this._discardMenuOnResizeListener, false);
delete this._discardMenuOnResizeListener;
}
},
_discardSubMenus: function()
{
if (this._subMenu)
this._subMenu._discardSubMenus();
this.element.remove();
if (this._parentMenu)
delete this._parentMenu._subMenu;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | 2 1 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {boolean} isVertical
* @param {boolean} secondIsSidebar
* @param {string=} settingName
* @param {number=} defaultSidebarWidth
* @param {number=} defaultSidebarHeight
* @param {boolean=} constraintsInDip
*/
WebInspector.SplitWidget = function(isVertical, secondIsSidebar, settingName, defaultSidebarWidth, defaultSidebarHeight, constraintsInDip)
{
WebInspector.Widget.call(this, true);
this.element.classList.add("split-widget");
this.registerRequiredCSS("ui/splitWidget.css");
this.contentElement.classList.add("shadow-split-widget");
this._mainElement = this.contentElement.createChild("div", "shadow-split-widget-contents shadow-split-widget-main vbox");
this._mainElement.createChild("content").select = ".insertion-point-main";
this._sidebarElement = this.contentElement.createChild("div", "shadow-split-widget-contents shadow-split-widget-sidebar vbox");
this._sidebarElement.createChild("content").select = ".insertion-point-sidebar";
this._resizerElement = this.contentElement.createChild("div", "shadow-split-widget-resizer");
this._resizerWidget = new WebInspector.SimpleResizerWidget();
this._resizerWidget.setEnabled(true);
this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate, this);
this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
this._defaultSidebarWidth = defaultSidebarWidth || 200;
this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWidth;
this._constraintsInDip = !!constraintsInDip;
this._setting = settingName ? WebInspector.settings.createSetting(settingName, {}) : null;
this.setSecondIsSidebar(secondIsSidebar);
this._innerSetVertical(isVertical);
this._showMode = WebInspector.SplitWidget.ShowMode.Both;
// Should be called after isVertical has the right value.
this.installResizer(this._resizerElement);
}
/** @typedef {{showMode: string, size: number}} */
WebInspector.SplitWidget.SettingForOrientation;
WebInspector.SplitWidget.ShowMode = {
Both: "Both",
OnlyMain: "OnlyMain",
OnlySidebar: "OnlySidebar"
}
WebInspector.SplitWidget.Events = {
SidebarSizeChanged: "SidebarSizeChanged",
ShowModeChanged: "ShowModeChanged"
}
WebInspector.SplitWidget.MinPadding = 20;
WebInspector.SplitWidget.prototype = {
/**
* @return {boolean}
*/
isVertical: function()
{
return this._isVertical;
},
/**
* @param {boolean} isVertical
*/
setVertical: function(isVertical)
{
if (this._isVertical === isVertical)
return;
this._innerSetVertical(isVertical);
if (this.isShowing())
this._updateLayout();
},
/**
* @param {boolean} isVertical
*/
_innerSetVertical: function(isVertical)
{
this.contentElement.classList.toggle("vbox", !isVertical);
this.contentElement.classList.toggle("hbox", isVertical);
this._isVertical = isVertical;
delete this._resizerElementSize;
this._sidebarSizeDIP = -1;
this._restoreSidebarSizeFromSettings();
if (this._shouldSaveShowMode)
this._restoreAndApplyShowModeFromSettings();
this._updateShowHideSidebarButton();
// FIXME: reverse SplitWidget.isVertical meaning.
this._resizerWidget.setVertical(!isVertical);
this.invalidateConstraints();
},
/**
* @param {boolean=} animate
*/
_updateLayout: function(animate)
{
delete this._totalSizeCSS; // Lazy update.
delete this._totalSizeOtherDimensionCSS;
// Remove properties that might affect total size calculation.
this._mainElement.style.removeProperty("width");
this._mainElement.style.removeProperty("height");
this._sidebarElement.style.removeProperty("width");
this._sidebarElement.style.removeProperty("height");
this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(), !!animate);
},
/**
* @param {!WebInspector.Widget} widget
*/
setMainWidget: function(widget)
{
if (this._mainWidget === widget)
return;
if (this._mainWidget)
this._mainWidget.detach();
this._mainWidget = widget;
if (widget) {
widget.element.classList.add("insertion-point-main");
widget.element.classList.remove("insertion-point-sidebar");
if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain || this._showMode === WebInspector.SplitWidget.ShowMode.Both)
widget.show(this.element);
}
},
/**
* @param {!WebInspector.Widget} widget
*/
setSidebarWidget: function(widget)
{
if (this._sidebarWidget === widget)
return;
if (this._sidebarWidget)
this._sidebarWidget.detach();
this._sidebarWidget = widget;
if (widget) {
widget.element.classList.add("insertion-point-sidebar");
widget.element.classList.remove("insertion-point-main");
if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar || this._showMode === WebInspector.SplitWidget.ShowMode.Both)
widget.show(this.element);
}
},
/**
* @return {?WebInspector.Widget}
*/
mainWidget: function()
{
return this._mainWidget;
},
/**
* @return {?WebInspector.Widget}
*/
sidebarWidget: function()
{
return this._sidebarWidget;
},
/**
* @override
* @param {!WebInspector.Widget} widget
*/
childWasDetached: function(widget)
{
if (this._detaching)
return;
if (this._mainWidget === widget)
delete this._mainWidget;
if (this._sidebarWidget === widget)
delete this._sidebarWidget;
},
/**
* @return {boolean}
*/
isSidebarSecond: function()
{
return this._secondIsSidebar;
},
enableShowModeSaving: function()
{
this._shouldSaveShowMode = true;
this._restoreAndApplyShowModeFromSettings();
},
/**
* @return {string}
*/
showMode: function()
{
return this._showMode;
},
/**
* @param {boolean} secondIsSidebar
*/
setSecondIsSidebar: function(secondIsSidebar)
{
this.contentElement.classList.toggle("shadow-split-widget-first-is-sidebar", !secondIsSidebar);
this._secondIsSidebar = secondIsSidebar;
},
/**
* @return {?string}
*/
sidebarSide: function()
{
if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
return null;
return this._isVertical ?
(this._secondIsSidebar ? "right" : "left") :
(this._secondIsSidebar ? "bottom" : "top");
},
/**
* @return {!Element}
*/
resizerElement: function()
{
return this._resizerElement;
},
/**
* @param {boolean=} animate
*/
hideMain: function(animate)
{
this._showOnly(this._sidebarWidget, this._mainWidget, this._sidebarElement, this._mainElement, animate);
this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlySidebar);
},
/**
* @param {boolean=} animate
*/
hideSidebar: function(animate)
{
this._showOnly(this._mainWidget, this._sidebarWidget, this._mainElement, this._sidebarElement, animate);
this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlyMain);
},
/**
* @param {boolean} minimized
*/
setSidebarMinimized: function(minimized)
{
this._sidebarMinimized = minimized;
this.invalidateConstraints();
},
/**
* @param {!WebInspector.Widget} sideToShow
* @param {!WebInspector.Widget} sideToHide
* @param {!Element} shadowToShow
* @param {!Element} shadowToHide
* @param {boolean=} animate
*/
_showOnly: function(sideToShow, sideToHide, shadowToShow, shadowToHide, animate)
{
this._cancelAnimation();
/**
* @this {WebInspector.SplitWidget}
*/
function callback()
{
if (sideToShow) {
// Make sure main is first in the children list.
if (sideToShow === this._mainWidget)
this._mainWidget.show(this.element, this._sidebarWidget ? this._sidebarWidget.element : null);
else
this._sidebarWidget.show(this.element);
}
if (sideToHide) {
this._detaching = true;
sideToHide.detach();
delete this._detaching;
}
this._resizerElement.classList.add("hidden");
shadowToShow.classList.remove("hidden");
shadowToShow.classList.add("maximized");
shadowToHide.classList.add("hidden");
shadowToHide.classList.remove("maximized");
this._removeAllLayoutProperties();
this.doResize();
}
if (animate)
this._animate(true, callback.bind(this));
else
callback.call(this);
this._sidebarSizeDIP = -1;
this.setResizable(false);
},
_removeAllLayoutProperties: function()
{
this._sidebarElement.style.removeProperty("flexBasis");
this._mainElement.style.removeProperty("width");
this._mainElement.style.removeProperty("height");
this._sidebarElement.style.removeProperty("width");
this._sidebarElement.style.removeProperty("height");
this._resizerElement.style.removeProperty("left");
this._resizerElement.style.removeProperty("right");
this._resizerElement.style.removeProperty("top");
this._resizerElement.style.removeProperty("bottom");
this._resizerElement.style.removeProperty("margin-left");
this._resizerElement.style.removeProperty("margin-right");
this._resizerElement.style.removeProperty("margin-top");
this._resizerElement.style.removeProperty("margin-bottom");
},
/**
* @param {boolean=} animate
*/
showBoth: function(animate)
{
if (this._showMode === WebInspector.SplitWidget.ShowMode.Both)
animate = false;
this._cancelAnimation();
this._mainElement.classList.remove("maximized", "hidden");
this._sidebarElement.classList.remove("maximized", "hidden");
this._resizerElement.classList.remove("hidden");
this.setResizable(true);
// Make sure main is the first in the children list.
if (this._sidebarWidget)
this._sidebarWidget.show(this.element);
if (this._mainWidget)
this._mainWidget.show(this.element, this._sidebarWidget ? this._sidebarWidget.element : null);
// Order widgets in DOM properly.
this.setSecondIsSidebar(this._secondIsSidebar);
this._sidebarSizeDIP = -1;
this._updateShowMode(WebInspector.SplitWidget.ShowMode.Both);
this._updateLayout(animate);
},
/**
* @param {boolean} resizable
*/
setResizable: function(resizable)
{
this._resizerWidget.setEnabled(resizable);
},
/**
* @return {boolean}
*/
isResizable: function()
{
return this._resizerWidget.isEnabled();
},
/**
* @param {number} size
*/
setSidebarSize: function(size)
{
var sizeDIP = WebInspector.zoomManager.cssToDIP(size);
this._savedSidebarSizeDIP = sizeDIP;
this._saveSetting();
this._innerSetSidebarSizeDIP(sizeDIP, false, true);
},
/**
* @return {number}
*/
sidebarSize: function()
{
var sizeDIP = Math.max(0, this._sidebarSizeDIP);
return WebInspector.zoomManager.dipToCSS(sizeDIP);
},
/**
* Returns total size in DIP.
* @return {number}
*/
_totalSizeDIP: function()
{
if (!this._totalSizeCSS) {
this._totalSizeCSS = this._isVertical ? this.contentElement.offsetWidth : this.contentElement.offsetHeight;
this._totalSizeOtherDimensionCSS = this._isVertical ? this.contentElement.offsetHeight : this.contentElement.offsetWidth;
}
return WebInspector.zoomManager.cssToDIP(this._totalSizeCSS);
},
/**
* @param {string} showMode
*/
_updateShowMode: function(showMode)
{
this._showMode = showMode;
this._saveShowModeToSettings();
this._updateShowHideSidebarButton();
this.dispatchEventToListeners(WebInspector.SplitWidget.Events.ShowModeChanged, showMode);
this.invalidateConstraints();
},
/**
* @param {number} sizeDIP
* @param {boolean} animate
* @param {boolean=} userAction
*/
_innerSetSidebarSizeDIP: function(sizeDIP, animate, userAction)
{
if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both || !this.isShowing())
return;
sizeDIP = this._applyConstraints(sizeDIP, userAction);
if (this._sidebarSizeDIP === sizeDIP)
return;
if (!this._resizerElementSize)
this._resizerElementSize = this._isVertical ? this._resizerElement.offsetWidth : this._resizerElement.offsetHeight;
// Invalidate layout below.
this._removeAllLayoutProperties();
// this._totalSizeDIP is available below since we successfully applied constraints.
var sidebarSizeValue = WebInspector.zoomManager.dipToCSS(sizeDIP) + "px";
var mainSizeValue = (this._totalSizeCSS - WebInspector.zoomManager.dipToCSS(sizeDIP)) + "px";
this._sidebarElement.style.flexBasis = sidebarSizeValue;
// Make both sides relayout boundaries.
if (this._isVertical) {
this._sidebarElement.style.width = sidebarSizeValue;
this._mainElement.style.width = mainSizeValue;
this._sidebarElement.style.height = this._totalSizeOtherDimensionCSS + "px";
this._mainElement.style.height = this._totalSizeOtherDimensionCSS + "px";
} else {
this._sidebarElement.style.height = sidebarSizeValue;
this._mainElement.style.height = mainSizeValue;
this._sidebarElement.style.width = this._totalSizeOtherDimensionCSS + "px";
this._mainElement.style.width = this._totalSizeOtherDimensionCSS + "px";
}
// Position resizer.
if (this._isVertical) {
if (this._secondIsSidebar) {
this._resizerElement.style.right = sidebarSizeValue;
this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + "px";
} else {
this._resizerElement.style.left = sidebarSizeValue;
this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + "px";
}
} else {
if (this._secondIsSidebar) {
this._resizerElement.style.bottom = sidebarSizeValue;
this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + "px";
} else {
this._resizerElement.style.top = sidebarSizeValue;
this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + "px";
}
}
this._sidebarSizeDIP = sizeDIP;
// Force layout.
if (animate) {
this._animate(false);
} else {
// No need to recalculate this._sidebarSizeDIP and this._totalSizeDIP again.
this.doResize();
this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSizeChanged, this.sidebarSize());
}
},
/**
* @param {boolean} reverse
* @param {function()=} callback
*/
_animate: function(reverse, callback)
{
var animationTime = 50;
this._animationCallback = callback;
var animatedMarginPropertyName;
if (this._isVertical)
animatedMarginPropertyName = this._secondIsSidebar ? "margin-right" : "margin-left";
else
animatedMarginPropertyName = this._secondIsSidebar ? "margin-bottom" : "margin-top";
var marginFrom = reverse ? "0" : "-" + WebInspector.zoomManager.dipToCSS(this._sidebarSizeDIP) + "px";
var marginTo = reverse ? "-" + WebInspector.zoomManager.dipToCSS(this._sidebarSizeDIP) + "px" : "0";
// This order of things is important.
// 1. Resize main element early and force layout.
this.contentElement.style.setProperty(animatedMarginPropertyName, marginFrom);
if (!reverse) {
suppressUnused(this._mainElement.offsetWidth);
suppressUnused(this._sidebarElement.offsetWidth);
}
// 2. Issue onresize to the sidebar element, its size won't change.
if (!reverse)
this._sidebarWidget.doResize();
// 3. Configure and run animation
this.contentElement.style.setProperty("transition", animatedMarginPropertyName + " " + animationTime + "ms linear");
var boundAnimationFrame;
var startTime;
/**
* @this {WebInspector.SplitWidget}
*/
function animationFrame()
{
delete this._animationFrameHandle;
if (!startTime) {
// Kick animation on first frame.
this.contentElement.style.setProperty(animatedMarginPropertyName, marginTo);
startTime = window.performance.now();
} else if (window.performance.now() < startTime + animationTime) {
// Process regular animation frame.
if (this._mainWidget)
this._mainWidget.doResize();
} else {
// Complete animation.
this._cancelAnimation();
if (this._mainWidget)
this._mainWidget.doResize();
this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSizeChanged, this.sidebarSize());
return;
}
this._animationFrameHandle = this.contentElement.window().requestAnimationFrame(boundAnimationFrame);
}
boundAnimationFrame = animationFrame.bind(this);
this._animationFrameHandle = this.contentElement.window().requestAnimationFrame(boundAnimationFrame);
},
_cancelAnimation: function()
{
this.contentElement.style.removeProperty("margin-top");
this.contentElement.style.removeProperty("margin-right");
this.contentElement.style.removeProperty("margin-bottom");
this.contentElement.style.removeProperty("margin-left");
this.contentElement.style.removeProperty("transition");
if (this._animationFrameHandle) {
this.contentElement.window().cancelAnimationFrame(this._animationFrameHandle);
delete this._animationFrameHandle;
}
if (this._animationCallback) {
this._animationCallback();
delete this._animationCallback;
}
},
/**
* @param {number} sidebarSize
* @param {boolean=} userAction
* @return {number}
*/
_applyConstraints: function(sidebarSize, userAction)
{
var totalSize = this._totalSizeDIP();
var zoomFactor = this._constraintsInDip ? 1 : WebInspector.zoomManager.zoomFactor();
var constraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
var minSidebarSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
if (!minSidebarSize)
minSidebarSize = WebInspector.SplitWidget.MinPadding;
minSidebarSize *= zoomFactor;
if (this._sidebarMinimized)
sidebarSize = minSidebarSize;
var preferredSidebarSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
if (!preferredSidebarSize)
preferredSidebarSize = WebInspector.SplitWidget.MinPadding;
preferredSidebarSize *= zoomFactor;
// Allow sidebar to be less than preferred by explicit user action.
if (sidebarSize < preferredSidebarSize)
preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
preferredSidebarSize += zoomFactor; // 1 css pixel for splitter border.
constraints = this._mainWidget ? this._mainWidget.constraints() : new Constraints();
var minMainSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
if (!minMainSize)
minMainSize = WebInspector.SplitWidget.MinPadding;
minMainSize *= zoomFactor;
var preferredMainSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
if (!preferredMainSize)
preferredMainSize = WebInspector.SplitWidget.MinPadding;
preferredMainSize *= zoomFactor;
var savedMainSize = this.isVertical() ? this._savedVerticalMainSize : this._savedHorizontalMainSize;
if (typeof savedMainSize !== "undefined")
preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoomFactor);
if (userAction)
preferredMainSize = minMainSize;
// Enough space for preferred.
var totalPreferred = preferredMainSize + preferredSidebarSize;
if (totalPreferred <= totalSize)
return Number.constrain(sidebarSize, preferredSidebarSize, totalSize - preferredMainSize);
// Enough space for minimum.
if (minMainSize + minSidebarSize <= totalSize) {
var delta = totalPreferred - totalSize;
var sidebarDelta = delta * preferredSidebarSize / totalPreferred;
sidebarSize = preferredSidebarSize - sidebarDelta;
return Number.constrain(sidebarSize, minSidebarSize, totalSize - minMainSize);
}
// Not enough space even for minimum sizes.
return Math.max(0, totalSize - minMainSize);
},
wasShown: function()
{
this._forceUpdateLayout();
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
},
willHide: function()
{
WebInspector.zoomManager.removeEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
},
onResize: function()
{
this._updateLayout();
},
onLayout: function()
{
this._updateLayout();
},
/**
* @override
* @return {!Constraints}
*/
calculateConstraints: function()
{
if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain)
return this._mainWidget ? this._mainWidget.constraints() : new Constraints();
if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar)
return this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
var mainConstraints = this._mainWidget ? this._mainWidget.constraints() : new Constraints();
var sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
var min = WebInspector.SplitWidget.MinPadding;
if (this._isVertical) {
mainConstraints = mainConstraints.widthToMax(min).addWidth(1); // 1 for splitter
sidebarConstraints = sidebarConstraints.widthToMax(min);
return mainConstraints.addWidth(sidebarConstraints).heightToMax(sidebarConstraints);
} else {
mainConstraints = mainConstraints.heightToMax(min).addHeight(1); // 1 for splitter
sidebarConstraints = sidebarConstraints.heightToMax(min);
return mainConstraints.widthToMax(sidebarConstraints).addHeight(sidebarConstraints);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onResizeStart: function(event)
{
this._resizeStartSizeDIP = this._sidebarSizeDIP;
},
/**
* @param {!WebInspector.Event} event
*/
_onResizeUpdate: function(event)
{
var offset = event.data.currentPosition - event.data.startPosition;
var offsetDIP = WebInspector.zoomManager.cssToDIP(offset);
var newSizeDIP = this._secondIsSidebar ? this._resizeStartSizeDIP - offsetDIP : this._resizeStartSizeDIP + offsetDIP;
var constrainedSizeDIP = this._applyConstraints(newSizeDIP, true);
this._savedSidebarSizeDIP = constrainedSizeDIP;
this._saveSetting();
this._innerSetSidebarSizeDIP(constrainedSizeDIP, false, true);
if (this.isVertical())
this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSizeDIP;
else
this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebarSizeDIP;
},
/**
* @param {!WebInspector.Event} event
*/
_onResizeEnd: function(event)
{
delete this._resizeStartSizeDIP;
},
hideDefaultResizer: function()
{
this.uninstallResizer(this._resizerElement);
},
/**
* @param {!Element} resizerElement
*/
installResizer: function(resizerElement)
{
this._resizerWidget.addElement(resizerElement);
},
/**
* @param {!Element} resizerElement
*/
uninstallResizer: function(resizerElement)
{
this._resizerWidget.removeElement(resizerElement);
},
/**
* @return {boolean}
*/
hasCustomResizer: function()
{
var elements = this._resizerWidget.elements();
return elements.length > 1 || (elements.length == 1 && elements[0] !== this._resizerElement);
},
/**
* @param {!Element} resizer
* @param {boolean} on
*/
toggleResizer: function(resizer, on)
{
if (on)
this.installResizer(resizer);
else
this.uninstallResizer(resizer);
},
/**
* @return {?WebInspector.SplitWidget.SettingForOrientation}
*/
_settingForOrientation: function()
{
var state = this._setting ? this._setting.get() : {};
return this._isVertical ? state.vertical : state.horizontal;
},
/**
* @return {number}
*/
_preferredSidebarSizeDIP: function()
{
var size = this._savedSidebarSizeDIP;
if (!size) {
size = this._isVertical ? this._defaultSidebarWidth : this._defaultSidebarHeight;
// If we have default value in percents, calculate it on first use.
if (0 < size && size < 1)
size *= this._totalSizeDIP();
}
return size;
},
_restoreSidebarSizeFromSettings: function()
{
var settingForOrientation = this._settingForOrientation();
this._savedSidebarSizeDIP = settingForOrientation ? settingForOrientation.size : 0;
},
_restoreAndApplyShowModeFromSettings: function()
{
var orientationState = this._settingForOrientation();
this._savedShowMode = orientationState && orientationState.showMode ? orientationState.showMode : this._showMode;
this._showMode = this._savedShowMode;
switch (this._savedShowMode) {
case WebInspector.SplitWidget.ShowMode.Both:
this.showBoth();
break;
case WebInspector.SplitWidget.ShowMode.OnlyMain:
this.hideSidebar();
break;
case WebInspector.SplitWidget.ShowMode.OnlySidebar:
this.hideMain();
break;
}
},
_saveShowModeToSettings: function()
{
this._savedShowMode = this._showMode;
this._saveSetting();
},
_saveSetting: function()
{
if (!this._setting)
return;
var state = this._setting.get();
var orientationState = (this._isVertical ? state.vertical : state.horizontal) || {};
orientationState.size = this._savedSidebarSizeDIP;
if (this._shouldSaveShowMode)
orientationState.showMode = this._savedShowMode;
if (this._isVertical)
state.vertical = orientationState;
else
state.horizontal = orientationState;
this._setting.set(state);
},
_forceUpdateLayout: function()
{
// Force layout even if sidebar size does not change.
this._sidebarSizeDIP = -1;
this._updateLayout();
},
/**
* @param {!WebInspector.Event} event
*/
_onZoomChanged: function(event)
{
this._forceUpdateLayout();
},
/**
* @param {string} title
* @param {string=} className
* @return {!Element}
*/
displayShowHideSidebarButton: function(title, className)
{
console.assert(this.isVertical(), "Buttons for split widget with horizontal split are not supported yet.");
this._showHideSidebarButtonTitle = WebInspector.UIString(title);
this._showHideSidebarButton = this._mainElement.createChild("button", "sidebar-show-hide-button " + (className || ""));
this._showHideSidebarButton.addEventListener("click", buttonClicked.bind(this), false);
this._updateShowHideSidebarButton();
/**
* @param {!Event} event
* @this {WebInspector.SplitWidget}
*/
function buttonClicked(event)
{
if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
this.showBoth(true);
else
this.hideSidebar(true);
}
return this._showHideSidebarButton;
},
_updateShowHideSidebarButton: function()
{
if (!this._showHideSidebarButton)
return;
var sidebarHidden = this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain;
this._showHideSidebarButton.classList.toggle("toggled-show", sidebarHidden);
this._showHideSidebarButton.classList.toggle("toggled-hide", !sidebarHidden);
this._showHideSidebarButton.classList.toggle("top-sidebar-show-hide-button", !this.isVertical() && !this.isSidebarSecond());
this._showHideSidebarButton.classList.toggle("right-sidebar-show-hide-button", this.isVertical() && this.isSidebarSecond());
this._showHideSidebarButton.classList.toggle("bottom-sidebar-show-hide-button", !this.isVertical() && this.isSidebarSecond());
this._showHideSidebarButton.classList.toggle("left-sidebar-show-hide-button", this.isVertical() && !this.isSidebarSecond());
this._showHideSidebarButton.title = sidebarHidden ? WebInspector.UIString("Show %s", this._showHideSidebarButtonTitle) : WebInspector.UIString("Hide %s", this._showHideSidebarButtonTitle);
},
__proto__: WebInspector.Widget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 2 | /*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {boolean} isVertical
*/
WebInspector.StackView = function(isVertical)
{
WebInspector.VBox.call(this);
this._isVertical = isVertical;
this._currentSplitWidget = null;
}
WebInspector.StackView.prototype = {
/**
* @param {!WebInspector.Widget} view
* @param {string=} sidebarSizeSettingName
* @param {number=} defaultSidebarWidth
* @param {number=} defaultSidebarHeight
* @return {?WebInspector.SplitWidget}
*/
appendView: function(view, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight)
{
var splitWidget = new WebInspector.SplitWidget(this._isVertical, true, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight);
splitWidget.setMainWidget(view);
splitWidget.hideSidebar();
if (!this._currentSplitWidget) {
splitWidget.show(this.element);
} else {
this._currentSplitWidget.setSidebarWidget(splitWidget);
this._currentSplitWidget.showBoth();
}
var lastSplitWidget = this._currentSplitWidget;
this._currentSplitWidget = splitWidget;
return lastSplitWidget;
},
detachChildWidgets: function()
{
WebInspector.Widget.prototype.detachChildWidgets.call(this);
this._currentSplitWidget = null;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | 2 1 | /* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.SuggestBoxDelegate = function() { } WebInspector.SuggestBoxDelegate.prototype = { /** * @param {string} suggestion * @param {boolean=} isIntermediateSuggestion */ applySuggestion: function(suggestion, isIntermediateSuggestion) { }, /** * acceptSuggestion will be always called after call to applySuggestion with isIntermediateSuggestion being equal to false. */ acceptSuggestion: function() { }, } /** * @constructor * @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate * @param {number=} maxItemsHeight */ WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight) { this._suggestBoxDelegate = suggestBoxDelegate; this._length = 0; this._selectedIndex = -1; this._selectedElement = null; this._maxItemsHeight = maxItemsHeight; this._maybeHideBound = this._maybeHide.bind(this); this._container = createElementWithClass("div", "suggest-box-container"); this._element = this._container.createChild("div", "suggest-box"); this._element.addEventListener("mousedown", this._onBoxMouseDown.bind(this), true); this._detailsPopup = this._container.createChild("div", "suggest-box details-popup monospace"); this._detailsPopup.classList.add("hidden"); this._asyncDetailsCallback = null; /** @type {!Map<number, !Promise<{detail: string, description: string}>>} */ this._asyncDetailsPromises = new Map(); } /** * @typedef Array.<{title: string, className: (string|undefined)}> */ WebInspector.SuggestBox.Suggestions; WebInspector.SuggestBox.prototype = { /** * @return {boolean} */ visible: function() { return !!this._container.parentElement; }, /** * @param {!AnchorBox} anchorBox */ setPosition: function(anchorBox) { this._updateBoxPosition(anchorBox); }, /** * @param {!AnchorBox} anchorBox */ _updateBoxPosition: function(anchorBox) { console.assert(this._overlay); if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox)) return; this._lastAnchorBox = anchorBox; // Position relative to main DevTools element. var container = WebInspector.Dialog.modalHostView().element; anchorBox = anchorBox.relativeToElement(container); var totalHeight = container.offsetHeight; var aboveHeight = anchorBox.y; var underHeight = totalHeight - anchorBox.y - anchorBox.height; this._overlay.setLeftOffset(anchorBox.x); var under = underHeight >= aboveHeight; if (under) this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true); else this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false); /** const */ var rowHeight = 17; /** const */ var spacer = 6; var maxHeight = this._maxItemsHeight ? this._maxItemsHeight * rowHeight : Math.max(underHeight, aboveHeight) - spacer; this._element.style.maxHeight = maxHeight + "px"; }, /** * @param {!Event} event */ _onBoxMouseDown: function(event) { if (this._hideTimeoutId) { window.clearTimeout(this._hideTimeoutId); delete this._hideTimeoutId; } event.preventDefault(); }, _maybeHide: function() { if (!this._hideTimeoutId) this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0); }, /** * // FIXME: make SuggestBox work for multiple documents. * @suppressGlobalPropertiesCheck */ _show: function() { if (this.visible()) return; this._bodyElement = document.body; this._bodyElement.addEventListener("mousedown", this._maybeHideBound, true); this._overlay = new WebInspector.SuggestBox.Overlay(); this._overlay.setContentElement(this._container); }, hide: function() { if (!this.visible()) return; this._bodyElement.removeEventListener("mousedown", this._maybeHideBound, true); delete this._bodyElement; this._container.remove(); this._overlay.dispose(); delete this._overlay; delete this._selectedElement; this._selectedIndex = -1; delete this._lastAnchorBox; }, removeFromElement: function() { this.hide(); }, /** * @param {boolean=} isIntermediateSuggestion */ _applySuggestion: function(isIntermediateSuggestion) { if (!this.visible() || !this._selectedElement) return false; var suggestion = this._selectedElement.__fullValue; if (!suggestion) return false; this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion); return true; }, /** * @return {boolean} */ acceptSuggestion: function() { var result = this._applySuggestion(); this.hide(); if (!result) return false; this._suggestBoxDelegate.acceptSuggestion(); return true; }, /** * @param {number} shift * @param {boolean=} isCircular * @return {boolean} is changed */ _selectClosest: function(shift, isCircular) { if (!this._length) return false; if (this._selectedIndex === -1 && shift < 0) shift += 1; var index = this._selectedIndex + shift; if (isCircular) index = (this._length + index) % this._length; else index = Number.constrain(index, 0, this._length - 1); this._selectItem(index, true); this._applySuggestion(true); return true; }, /** * @param {!Event} event */ _onItemMouseDown: function(event) { this._selectedElement = event.currentTarget; this.acceptSuggestion(); event.consume(true); }, /** * @param {string} prefix * @param {string} text * @param {string|undefined} className * @param {number} index */ _createItemElement: function(prefix, text, className, index) { var element = createElementWithClass("div", "suggest-box-content-item source-code " + (className || "")); element.tabIndex = -1; if (prefix && prefix.length && !text.indexOf(prefix)) { element.createChild("span", "prefix").textContent = prefix; element.createChild("span", "suffix").textContent = text.substring(prefix.length).trimEnd(50); } else { element.createChild("span", "suffix").textContent = text.trimEnd(50); } element.__fullValue = text; element.createChild("span", "spacer"); element.addEventListener("mousedown", this._onItemMouseDown.bind(this), false); return element; }, /** * @param {!WebInspector.SuggestBox.Suggestions} items * @param {string} userEnteredText * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails */ _updateItems: function(items, userEnteredText, asyncDetails) { this._length = items.length; this._asyncDetailsPromises.clear(); this._asyncDetailsCallback = asyncDetails; this._element.removeChildren(); delete this._selectedElement; for (var i = 0; i < items.length; ++i) { var item = items[i]; var currentItemElement = this._createItemElement(userEnteredText, item.title, item.className, i); this._element.appendChild(currentItemElement); } }, /** * @param {number} index * @return {!Promise<?{detail: string, description: string}>} */ _asyncDetails: function(index) { if (!this._asyncDetailsCallback) return Promise.resolve(/** @type {?{description: string, detail: string}} */(null)); if (!this._asyncDetailsPromises.has(index)) this._asyncDetailsPromises.set(index, this._asyncDetailsCallback(index)); return /** @type {!Promise<?{detail: string, description: string}>} */(this._asyncDetailsPromises.get(index)); }, /** * @param {?{detail: string, description: string}} details */ _showDetailsPopup: function(details) { this._detailsPopup.removeChildren(); if (!details) return; this._detailsPopup.createChild("section", "detail").createTextChild(details.detail); this._detailsPopup.createChild("section", "description").createTextChild(details.description); this._detailsPopup.classList.remove("hidden"); }, /** * @param {number} index * @param {boolean} scrollIntoView */ _selectItem: function(index, scrollIntoView) { if (this._selectedElement) this._selectedElement.classList.remove("selected"); this._selectedIndex = index; if (index < 0) return; this._selectedElement = this._element.children[index]; this._selectedElement.classList.add("selected"); this._detailsPopup.classList.add("hidden"); var elem = this._selectedElement; this._asyncDetails(index).then(showDetails.bind(this), function(){}); if (scrollIntoView) this._selectedElement.scrollIntoViewIfNeeded(false); /** * @param {?{detail: string, description: string}} details * @this {WebInspector.SuggestBox} */ function showDetails(details) { if (elem === this._selectedElement) this._showDetailsPopup(details); } }, /** * @param {!WebInspector.SuggestBox.Suggestions} completions * @param {boolean} canShowForSingleItem * @param {string} userEnteredText */ _canShowBox: function(completions, canShowForSingleItem, userEnteredText) { if (!completions || !completions.length) return false; if (completions.length > 1) return true; // Do not show a single suggestion if it is the same as user-entered prefix, even if allowed to show single-item suggest boxes. return canShowForSingleItem && completions[0].title !== userEnteredText; }, _ensureRowCountPerViewport: function() { if (this._rowCountPerViewport) return; if (!this._element.firstChild) return; this._rowCountPerViewport = Math.floor(this._element.offsetHeight / this._element.firstChild.offsetHeight); }, /** * @param {!AnchorBox} anchorBox * @param {!WebInspector.SuggestBox.Suggestions} completions * @param {number} selectedIndex * @param {boolean} canShowForSingleItem * @param {string} userEnteredText * @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails */ updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText, asyncDetails) { if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) { this._updateItems(completions, userEnteredText, asyncDetails); this._show(); this._updateBoxPosition(anchorBox); this._selectItem(selectedIndex, selectedIndex > 0); delete this._rowCountPerViewport; } else this.hide(); }, /** * @param {!KeyboardEvent} event * @return {boolean} */ keyPressed: function(event) { switch (event.keyIdentifier) { case "Up": return this.upKeyPressed(); case "Down": return this.downKeyPressed(); case "PageUp": return this.pageUpKeyPressed(); case "PageDown": return this.pageDownKeyPressed(); case "Enter": return this.enterKeyPressed(); } return false; }, /** * @return {boolean} */ upKeyPressed: function() { return this._selectClosest(-1, true); }, /** * @return {boolean} */ downKeyPressed: function() { return this._selectClosest(1, true); }, /** * @return {boolean} */ pageUpKeyPressed: function() { this._ensureRowCountPerViewport(); return this._selectClosest(-this._rowCountPerViewport, false); }, /** * @return {boolean} */ pageDownKeyPressed: function() { this._ensureRowCountPerViewport(); return this._selectClosest(this._rowCountPerViewport, false); }, /** * @return {boolean} */ enterKeyPressed: function() { var hasSelectedItem = !!this._selectedElement; this.acceptSuggestion(); // Report the event as non-handled if there is no selected item, // to commit the input or handle it otherwise. return hasSelectedItem; } } /** * @constructor * // FIXME: make SuggestBox work for multiple documents. * @suppressGlobalPropertiesCheck */ WebInspector.SuggestBox.Overlay = function() { this.element = createElementWithClass("div", "suggest-box-overlay"); var root = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/suggestBox.css"); this._leftSpacerElement = root.createChild("div", "suggest-box-left-spacer"); this._horizontalElement = root.createChild("div", "suggest-box-horizontal"); this._topSpacerElement = this._horizontalElement.createChild("div", "suggest-box-top-spacer"); this._bottomSpacerElement = this._horizontalElement.createChild("div", "suggest-box-bottom-spacer"); this._resize(); document.body.appendChild(this.element); } WebInspector.SuggestBox.Overlay.prototype = { /** * @param {number} offset */ setLeftOffset: function(offset) { this._leftSpacerElement.style.flexBasis = offset + "px"; }, /** * @param {number} offset * @param {boolean} isTopOffset */ setVerticalOffset: function(offset, isTopOffset) { this.element.classList.toggle("under-anchor", isTopOffset); if (isTopOffset) { this._bottomSpacerElement.style.flexBasis = "auto"; this._topSpacerElement.style.flexBasis = offset + "px"; } else { this._bottomSpacerElement.style.flexBasis = offset + "px"; this._topSpacerElement.style.flexBasis = "auto"; } }, /** * @param {!Element} element */ setContentElement: function(element) { this._horizontalElement.insertBefore(element, this._bottomSpacerElement); }, _resize: function() { var container = WebInspector.Dialog.modalHostView().element; var containerBox = container.boxInWindow(container.ownerDocument.defaultView); this.element.style.left = containerBox.x + "px"; this.element.style.top = containerBox.y + "px"; this.element.style.height = containerBox.height + "px"; this.element.style.width = containerBox.width + "px"; }, dispose: function() { this.element.remove(); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 | 2 1 1 1 1 1 1 1 | /*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @extends {WebInspector.VBox}
* @constructor
*/
WebInspector.TabbedPane = function()
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("ui/tabbedPane.css");
this.element.classList.add("tabbed-pane");
this.contentElement.classList.add("tabbed-pane-shadow");
this.contentElement.tabIndex = -1;
this._headerElement = this.contentElement.createChild("div", "tabbed-pane-header");
this._headerElement.createChild("content").select = ".tabbed-pane-header-before";
this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
this._tabSlider = createElementWithClass("div", "tabbed-pane-tab-slider");
this._headerElement.createChild("content").select = ".tabbed-pane-header-after";
this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
this._contentElement = this.contentElement.createChild("div", "tabbed-pane-content");
this._contentElement.createChild("content");
/** @type {!Array.<!WebInspector.TabbedPaneTab>} */
this._tabs = [];
/** @type {!Array.<!WebInspector.TabbedPaneTab>} */
this._tabsHistory = [];
/** @type {!Object.<string, !WebInspector.TabbedPaneTab>} */
this._tabsById = {};
this._currentTabLocked = false;
this._dropDownButton = this._createDropDownButton();
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
}
WebInspector.TabbedPane.EventTypes = {
TabSelected: "TabSelected",
TabClosed: "TabClosed",
TabOrderChanged: "TabOrderChanged"
}
WebInspector.TabbedPane.prototype = {
/**
* @param {boolean} locked
*/
setCurrentTabLocked: function(locked)
{
this._currentTabLocked = locked;
this._headerElement.classList.toggle("locked", this._currentTabLocked);
},
/**
* @return {?WebInspector.Widget}
*/
get visibleView()
{
return this._currentTab ? this._currentTab.view : null;
},
/**
* @return {!Array.<string>}
*/
tabIds: function()
{
return this._tabs.map(tab => tab._id);
},
/**
* @return {!Array.<!WebInspector.Widget>}
*/
tabViews: function()
{
return this._tabs.map(tab => tab.view);
},
/**
* @param {string} tabId
* @return {?WebInspector.Widget}
*/
tabView: function(tabId)
{
return this._tabsById[tabId] ? this._tabsById[tabId].view : null;
},
/**
* @return {?string}
*/
get selectedTabId()
{
return this._currentTab ? this._currentTab.id : null;
},
/**
* @param {boolean} shrinkableTabs
*/
setShrinkableTabs: function(shrinkableTabs)
{
this._shrinkableTabs = shrinkableTabs;
},
/**
* @param {boolean} verticalTabLayout
*/
setVerticalTabLayout: function(verticalTabLayout)
{
this._verticalTabLayout = verticalTabLayout;
this.contentElement.classList.add("vertical-tab-layout");
this.invalidateConstraints();
},
/**
* @param {boolean} closeableTabs
*/
setCloseableTabs: function(closeableTabs)
{
this._closeableTabs = closeableTabs;
},
/**
* @override
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this.visibleView ? this.visibleView.defaultFocusedElement() : this.contentElement;
},
focus: function()
{
if (this.visibleView)
this.visibleView.focus();
else
this.contentElement.focus();
},
/**
* @return {!Element}
*/
headerElement: function()
{
return this._headerElement;
},
/**
* @param {string} id
* @return {boolean}
*/
isTabCloseable: function(id)
{
var tab = this._tabsById[id];
return tab ? tab.isCloseable() : false;
},
/**
* @param {!WebInspector.TabbedPaneTabDelegate} delegate
*/
setTabDelegate: function(delegate)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
tabs[i].setDelegate(delegate);
this._delegate = delegate;
},
/**
* @param {string} id
* @param {string} tabTitle
* @param {!WebInspector.Widget} view
* @param {string=} tabTooltip
* @param {boolean=} userGesture
* @param {boolean=} isCloseable
* @param {number=} index
*/
appendTab: function(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index)
{
isCloseable = typeof isCloseable === "boolean" ? isCloseable : this._closeableTabs;
var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, isCloseable, view, tabTooltip);
tab.setDelegate(this._delegate);
this._tabsById[id] = tab;
if (index !== undefined)
this._tabs.splice(index, 0, tab);
else
this._tabs.push(tab);
this._tabsHistory.push(tab);
if (this._tabsHistory[0] === tab && this.isShowing())
this.selectTab(tab.id, userGesture);
this._updateTabElements();
},
/**
* @param {string} id
* @param {boolean=} userGesture
*/
closeTab: function(id, userGesture)
{
this.closeTabs([id], userGesture);
},
/**
* @param {!Array.<string>} ids
* @param {boolean=} userGesture
*/
closeTabs: function(ids, userGesture)
{
var focused = this.hasFocus();
for (var i = 0; i < ids.length; ++i)
this._innerCloseTab(ids[i], userGesture);
this._updateTabElements();
if (this._tabsHistory.length)
this.selectTab(this._tabsHistory[0].id, false);
if (focused)
this.focus();
},
/**
* @param {string} id
* @param {boolean=} userGesture
*/
_innerCloseTab: function(id, userGesture)
{
if (!this._tabsById[id])
return;
if (userGesture && !this._tabsById[id]._closeable)
return;
if (this._currentTab && this._currentTab.id === id)
this._hideCurrentTab();
var tab = this._tabsById[id];
delete this._tabsById[id];
this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabs.splice(this._tabs.indexOf(tab), 1);
if (tab._shown)
this._hideTabElement(tab);
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
return true;
},
/**
* @param {string} tabId
* @return {boolean}
*/
hasTab: function(tabId)
{
return !!this._tabsById[tabId];
},
/**
* @return {!Array.<string>}
*/
allTabs: function()
{
return this._tabs.map(function (tab) { return tab.id; });
},
/**
* @param {string} id
* @return {!Array.<string>}
*/
otherTabs: function(id)
{
var result = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i].id !== id)
result.push(this._tabs[i].id);
}
return result;
},
/**
* @param {string} id
* @return {!Array.<string>}
*/
_tabsToTheRight: function(id)
{
var index = -1;
for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i].id === id) {
index = i;
break;
}
}
if (index === -1)
return [];
return this._tabs.slice(index + 1).map(function (tab) { return tab.id; });
},
/**
* @param {string} id
* @param {boolean=} userGesture
* @return {boolean}
*/
selectTab: function(id, userGesture)
{
if (this._currentTabLocked)
return false;
var focused = this.hasFocus();
var tab = this._tabsById[id];
if (!tab)
return false;
if (this._currentTab && this._currentTab.id === id)
return true;
this._hideCurrentTab();
this._showTab(tab);
this._currentTab = tab;
this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabsHistory.splice(0, 0, tab);
this._updateTabElements();
if (focused)
this.focus();
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
return true;
},
/**
* @param {number} tabsCount
* @return {!Array.<string>}
*/
lastOpenedTabIds: function(tabsCount)
{
function tabToTabId(tab) {
return tab.id;
}
return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
},
/**
* @param {string} id
* @param {string} iconType
* @param {string=} iconTooltip
*/
setTabIcon: function(id, iconType, iconTooltip)
{
var tab = this._tabsById[id];
if (tab._setIconType(iconType, iconTooltip))
this._updateTabElements();
},
/**
* @param {string} id
* @param {boolean} enabled
*/
setTabEnabled: function(id, enabled)
{
var tab = this._tabsById[id];
tab.tabElement.classList.toggle("disabled", !enabled);
},
/**
* @param {string} id
* @param {string} className
* @param {boolean=} force
*/
toggleTabClass: function(id, className, force)
{
var tab = this._tabsById[id];
if (tab._toggleClass(className, force))
this._updateTabElements();
},
/**
* @param {!WebInspector.Event} event
*/
_zoomChanged: function(event)
{
for (var i = 0; i < this._tabs.length; ++i)
delete this._tabs[i]._measuredWidth;
if (this.isShowing())
this._updateTabElements();
},
/**
* @param {string} id
* @param {string} tabTitle
*/
changeTabTitle: function(id, tabTitle)
{
var tab = this._tabsById[id];
if (tab.title === tabTitle)
return;
tab.title = tabTitle;
this._updateTabElements();
},
/**
* @param {string} id
* @param {!WebInspector.Widget} view
*/
changeTabView: function(id, view)
{
var tab = this._tabsById[id];
if (this._currentTab && this._currentTab.id === tab.id) {
if (tab.view !== view)
this._hideTab(tab);
tab.view = view;
this._showTab(tab);
} else
tab.view = view;
},
onResize: function()
{
this._updateTabElements();
},
headerResized: function()
{
this._updateTabElements();
},
wasShown: function()
{
var effectiveTab = this._currentTab || this._tabsHistory[0];
if (effectiveTab)
this.selectTab(effectiveTab.id);
},
/**
* @param {boolean} enable
*/
setTabSlider: function(enable)
{
this._sliderEnabled = enable;
this._tabSlider.classList.toggle("enabled", enable);
},
/**
* @override
* @return {!Constraints}
*/
calculateConstraints: function()
{
var constraints = WebInspector.VBox.prototype.calculateConstraints.call(this);
var minContentConstraints = new Constraints(new Size(0, 0), new Size(50, 50));
constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints);
if (this._verticalTabLayout)
constraints = constraints.addWidth(new Constraints(new Size(120, 0)));
else
constraints = constraints.addHeight(new Constraints(new Size(0, 30)));
return constraints;
},
_updateTabElements: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
},
/**
* @param {string} text
*/
setPlaceholderText: function(text)
{
this._noTabsMessage = text;
},
_innerUpdateTabElements: function()
{
if (!this.isShowing())
return;
if (!this._tabs.length) {
this._contentElement.classList.add("has-no-tabs");
if (this._noTabsMessage && !this._noTabsMessageElement) {
this._noTabsMessageElement = this._contentElement.createChild("div", "tabbed-pane-placeholder fill");
this._noTabsMessageElement.textContent = this._noTabsMessage;
}
} else {
this._contentElement.classList.remove("has-no-tabs");
if (this._noTabsMessageElement) {
this._noTabsMessageElement.remove();
delete this._noTabsMessageElement;
}
}
this._measureDropDownButton();
this._updateWidths();
this._updateTabsDropDown();
this._updateTabSlider();
},
/**
* @param {number} index
* @param {!WebInspector.TabbedPaneTab} tab
*/
_showTabElement: function(index, tab)
{
if (index >= this._tabsElement.children.length)
this._tabsElement.appendChild(tab.tabElement);
else
this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
tab._shown = true;
},
/**
* @param {!WebInspector.TabbedPaneTab} tab
*/
_hideTabElement: function(tab)
{
this._tabsElement.removeChild(tab.tabElement);
tab._shown = false;
},
_createDropDownButton: function()
{
var dropDownContainer = createElementWithClass("div", "tabbed-pane-header-tabs-drop-down-container");
dropDownContainer.createChild("div", "glyph");
this._dropDownMenu = new WebInspector.DropDownMenu(dropDownContainer);
this._dropDownMenu.addEventListener(WebInspector.DropDownMenu.Events.ItemSelected, this._dropDownMenuItemSelected, this);
return dropDownContainer;
},
/**
* @param {!WebInspector.Event} event
*/
_dropDownMenuItemSelected: function(event)
{
var tabId = /** @type {string} */ (event.data);
this._lastSelectedOverflowTab = this._tabsById[tabId];
this.selectTab(tabId, true);
},
_totalWidth: function()
{
return this._headerContentsElement.getBoundingClientRect().width;
},
/**
* @return {number}
*/
_numberOfTabsShown: function()
{
var numTabsShown = 0;
for (var tab of this._tabs) {
if (tab._shown)
numTabsShown++;
}
return numTabsShown;
},
disableOverflowMenu: function()
{
this._overflowDisabled = true;
},
_updateTabsDropDown: function()
{
var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth || 0);
if (this._lastSelectedOverflowTab && this._numberOfTabsShown() !== tabsToShowIndexes.length) {
delete this._lastSelectedOverflowTab;
this._updateTabsDropDown();
return;
}
for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
this._hideTabElement(this._tabs[i]);
}
for (var i = 0; i < tabsToShowIndexes.length; ++i) {
var tab = this._tabs[tabsToShowIndexes[i]];
if (!tab._shown)
this._showTabElement(i, tab);
}
if (!this._overflowDisabled)
this._populateDropDownFromIndex();
},
_populateDropDownFromIndex: function()
{
if (this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);
this._dropDownMenu.clear();
var tabsToShow = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (!this._tabs[i]._shown)
tabsToShow.push(this._tabs[i]);
}
var selectedId = null;
for (var i = 0; i < tabsToShow.length; ++i) {
var tab = tabsToShow[i];
this._dropDownMenu.addItem(tab.id, tab.title);
if (this._tabsHistory[0] === tab)
selectedId = tab.id;
}
if (tabsToShow.length) {
this._headerContentsElement.appendChild(this._dropDownButton);
this._dropDownMenu.selectItem(selectedId);
}
},
_measureDropDownButton: function()
{
if (this._overflowDisabled || this._measuredDropDownButtonWidth)
return;
this._dropDownButton.classList.add("measuring");
this._headerContentsElement.appendChild(this._dropDownButton);
this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
this._headerContentsElement.removeChild(this._dropDownButton);
this._dropDownButton.classList.remove("measuring");
},
_updateWidths: function()
{
var measuredWidths = this._measureWidths();
var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;
var i = 0;
for (var tab of this._tabs)
tab.setWidth(this._verticalTabLayout ? -1 : Math.min(maxWidth, measuredWidths[i++]));
},
_measureWidths: function()
{
// Add all elements to measure into this._tabsElement
this._tabsElement.style.setProperty("width", "2000px");
var measuringTabElements = [];
for (var tab of this._tabs) {
if (typeof tab._measuredWidth === "number")
continue;
var measuringTabElement = tab._createTabElement(true);
measuringTabElement.__tab = tab;
measuringTabElements.push(measuringTabElement);
this._tabsElement.appendChild(measuringTabElement);
}
// Perform measurement
for (var i = 0; i < measuringTabElements.length; ++i) {
var width = measuringTabElements[i].getBoundingClientRect().width;
measuringTabElements[i].__tab._measuredWidth = Math.ceil(width);
}
// Nuke elements from the UI
for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].remove();
// Combine the results.
var measuredWidths = [];
for (var tab of this._tabs)
measuredWidths.push(tab._measuredWidth);
this._tabsElement.style.removeProperty("width");
return measuredWidths;
},
/**
* @param {!Array.<number>} measuredWidths
* @param {number} totalWidth
*/
_calculateMaxWidth: function(measuredWidths, totalWidth)
{
if (!measuredWidths.length)
return 0;
measuredWidths.sort(function(x, y) { return x - y; });
var totalMeasuredWidth = 0;
for (var i = 0; i < measuredWidths.length; ++i)
totalMeasuredWidth += measuredWidths[i];
if (totalWidth >= totalMeasuredWidth)
return measuredWidths[measuredWidths.length - 1];
var totalExtraWidth = 0;
for (var i = measuredWidths.length - 1; i > 0; --i) {
var extraWidth = measuredWidths[i] - measuredWidths[i - 1];
totalExtraWidth += (measuredWidths.length - i) * extraWidth;
if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i);
}
return totalWidth / measuredWidths.length;
},
/**
* @param {!Array.<!WebInspector.TabbedPaneTab>} tabsOrdered
* @param {!Array.<!WebInspector.TabbedPaneTab>} tabsHistory
* @param {number} totalWidth
* @param {number} measuredDropDownButtonWidth
* @return {!Array.<number>}
*/
_tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth)
{
var tabsToShowIndexes = [];
var totalTabsWidth = 0;
var tabCount = tabsOrdered.length;
var tabsToLookAt = tabsOrdered.slice(0);
if (this._currentTab !== undefined)
tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._currentTab), 1)[0]);
if (this._lastSelectedOverflowTab !== undefined)
tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._lastSelectedOverflowTab), 1)[0]);
for (var i = 0; i < tabCount; ++i) {
var tab = this._automaticReorder ? tabsHistory[i] : tabsToLookAt[i];
totalTabsWidth += tab.width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabCount - 1)
minimalRequiredWidth += measuredDropDownButtonWidth;
if (!this._verticalTabLayout && minimalRequiredWidth > totalWidth)
break;
tabsToShowIndexes.push(tabsOrdered.indexOf(tab));
}
tabsToShowIndexes.sort(function(x, y) { return x - y; });
return tabsToShowIndexes;
},
_hideCurrentTab: function()
{
if (!this._currentTab)
return;
this._hideTab(this._currentTab);
delete this._currentTab;
},
/**
* @param {!WebInspector.TabbedPaneTab} tab
*/
_showTab: function(tab)
{
tab.tabElement.classList.add("selected");
tab.view.show(this.element);
this._updateTabSlider();
},
_updateTabSlider: function()
{
if (!this._currentTab || !this._sliderEnabled)
return;
var left = 0;
for (var i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i] && this._tabs[i]._shown; i++)
left += this._tabs[i]._measuredWidth;
var sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth;
var scaleFactor = window.devicePixelRatio >= 1.5 ? " scaleY(0.75)" : "";
this._tabSlider.style.transform = "translateX(" + left + "px)" + scaleFactor;
this._tabSlider.style.width = sliderWidth + "px";
if (this._tabSlider.parentElement !== this._headerContentsElement)
this._headerContentsElement.appendChild(this._tabSlider);
},
/**
* @param {!WebInspector.TabbedPaneTab} tab
*/
_hideTab: function(tab)
{
tab.tabElement.classList.remove("selected");
tab.view.detach();
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [ this._contentElement ];
},
/**
* @param {!WebInspector.TabbedPaneTab} tab
* @param {number} index
*/
_insertBefore: function(tab, index)
{
this._tabsElement.insertBefore(tab._tabElement || null, this._tabsElement.childNodes[index]);
var oldIndex = this._tabs.indexOf(tab);
this._tabs.splice(oldIndex, 1);
if (oldIndex < index)
--index;
this._tabs.splice(index, 0, tab);
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabOrderChanged, this._tabs);
},
/**
* @param {!Element} element
*/
insertBeforeTabStrip: function(element)
{
element.classList.add("tabbed-pane-header-before");
this.element.appendChild(element);
},
/**
* @param {!Element} element
*/
appendAfterTabStrip: function(element)
{
element.classList.add("tabbed-pane-header-after");
this.element.appendChild(element);
},
renderWithNoHeaderBackground: function()
{
this._headerElement.classList.add("tabbed-pane-no-header-background");
},
/**
* @param {boolean} allow
* @param {boolean=} automatic
*/
setAllowTabReorder: function(allow, automatic)
{
this._allowTabReorder = allow;
this._automaticReorder = automatic;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {!WebInspector.TabbedPane} tabbedPane
* @param {string} id
* @param {string} title
* @param {boolean} closeable
* @param {!WebInspector.Widget} view
* @param {string=} tooltip
*/
WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
{
this._closeable = closeable;
this._tabbedPane = tabbedPane;
this._id = id;
this._title = title;
this._tooltip = tooltip;
this._view = view;
this._shown = false;
/** @type {number} */ this._measuredWidth;
/** @type {!Element|undefined} */ this._tabElement;
}
WebInspector.TabbedPaneTab.prototype = {
/**
* @return {string}
*/
get id()
{
return this._id;
},
/**
* @return {string}
*/
get title()
{
return this._title;
},
set title(title)
{
if (title === this._title)
return;
this._title = title;
if (this._titleElement)
this._titleElement.textContent = title;
delete this._measuredWidth;
},
/**
* @return {boolean}
*/
isCloseable: function()
{
return this._closeable;
},
/**
* @param {string} iconType
* @param {string=} iconTooltip
* @return {boolean}
*/
_setIconType: function(iconType, iconTooltip)
{
if (iconType === this._iconType && iconTooltip === this._iconTooltip)
return false;
this._iconType = iconType;
this._iconTooltip = iconTooltip;
if (this._tabElement)
this._createIconElement(this._tabElement, this._titleElement);
delete this._measuredWidth;
return true;
},
/**
* @param {string} className
* @param {boolean=} force
* @return {boolean}
*/
_toggleClass: function(className, force)
{
var element = this.tabElement;
var hasClass = element.classList.contains(className);
if (hasClass === force)
return false;
element.classList.toggle(className, force);
delete this._measuredWidth;
return true;
},
/**
* @return {!WebInspector.Widget}
*/
get view()
{
return this._view;
},
set view(view)
{
this._view = view;
},
/**
* @return {string|undefined}
*/
get tooltip()
{
return this._tooltip;
},
set tooltip(tooltip)
{
this._tooltip = tooltip;
if (this._titleElement)
this._titleElement.title = tooltip || "";
},
/**
* @return {!Element}
*/
get tabElement()
{
if (!this._tabElement)
this._tabElement = this._createTabElement(false);
return this._tabElement;
},
/**
* @return {number}
*/
width: function()
{
return this._width;
},
/**
* @param {number} width
*/
setWidth: function(width)
{
this.tabElement.style.width = width === -1 ? "" : (width + "px");
this._width = width;
},
/**
* @param {!WebInspector.TabbedPaneTabDelegate} delegate
*/
setDelegate: function(delegate)
{
this._delegate = delegate;
},
/**
* @param {!Element} tabElement
* @param {!Element} titleElement
*/
_createIconElement: function(tabElement, titleElement)
{
if (tabElement.__iconElement)
tabElement.__iconElement.remove();
if (!this._iconType)
return;
var iconElement = createElementWithClass("label", "tabbed-pane-header-tab-icon", "dt-icon-label");
iconElement.type = this._iconType;
if (this._iconTooltip)
iconElement.title = this._iconTooltip;
tabElement.insertBefore(iconElement, titleElement);
tabElement.__iconElement = iconElement;
},
/**
* @param {boolean} measuring
* @return {!Element}
*/
_createTabElement: function(measuring)
{
var tabElement = createElementWithClass("div", "tabbed-pane-header-tab");
tabElement.id = "tab-" + this._id;
tabElement.tabIndex = -1;
tabElement.selectTabForTest = this._tabbedPane.selectTab.bind(this._tabbedPane, this.id, true);
var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title");
titleElement.textContent = this.title;
titleElement.title = this.tooltip || "";
this._createIconElement(tabElement, titleElement);
if (!measuring)
this._titleElement = titleElement;
if (this._closeable)
tabElement.createChild("div", "tabbed-pane-close-button", "dt-close-button").gray = true;
if (measuring) {
tabElement.classList.add("measuring");
} else {
tabElement.addEventListener("click", this._tabClicked.bind(this), false);
tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false);
tabElement.addEventListener("mouseup", this._tabMouseUp.bind(this), false);
tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false);
if (this._tabbedPane._allowTabReorder)
WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "-webkit-grabbing", "pointer", 200);
}
return tabElement;
},
/**
* @param {!Event} event
*/
_tabClicked: function(event)
{
var middleButton = event.button === 1;
var shouldClose = this._closeable && (middleButton || event.target.classList.contains("tabbed-pane-close-button"));
if (!shouldClose) {
this._tabbedPane.focus();
return;
}
this._closeTabs([this.id]);
event.consume(true);
},
/**
* @param {!Event} event
*/
_tabMouseDown: function(event)
{
if (event.target.classList.contains("tabbed-pane-close-button") || event.button === 1)
return;
this._tabbedPane.selectTab(this.id, true);
},
/**
* @param {!Event} event
*/
_tabMouseUp: function(event)
{
// This is needed to prevent middle-click pasting on linux when tabs are clicked.
if (event.button === 1)
event.consume(true);
},
/**
* @param {!Array.<string>} ids
*/
_closeTabs: function(ids)
{
if (this._delegate) {
this._delegate.closeTabs(this._tabbedPane, ids);
return;
}
this._tabbedPane.closeTabs(ids, true);
},
_tabContextMenu: function(event)
{
/**
* @this {WebInspector.TabbedPaneTab}
*/
function close()
{
this._closeTabs([this.id]);
}
/**
* @this {WebInspector.TabbedPaneTab}
*/
function closeOthers()
{
this._closeTabs(this._tabbedPane.otherTabs(this.id));
}
/**
* @this {WebInspector.TabbedPaneTab}
*/
function closeAll()
{
this._closeTabs(this._tabbedPane.allTabs());
}
/**
* @this {WebInspector.TabbedPaneTab}
*/
function closeToTheRight()
{
this._closeTabs(this._tabbedPane._tabsToTheRight(this.id));
}
var contextMenu = new WebInspector.ContextMenu(event);
if (this._closeable) {
contextMenu.appendItem(WebInspector.UIString.capitalize("Close"), close.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^others"), closeOthers.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^tabs to the ^right"), closeToTheRight.bind(this));
contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^all"), closeAll.bind(this));
}
if (this._delegate)
this._delegate.onContextMenu(this.id, contextMenu);
contextMenu.show();
},
/**
* @param {!Event} event
* @return {boolean}
*/
_startTabDragging: function(event)
{
if (event.target.classList.contains("tabbed-pane-close-button"))
return false;
this._dragStartX = event.pageX;
this._tabElement.classList.add("dragging");
this._tabbedPane._tabSlider.remove();
return true;
},
/**
* @param {!Event} event
*/
_tabDragging: function(event)
{
var tabElements = this._tabbedPane._tabsElement.childNodes;
for (var i = 0; i < tabElements.length; ++i) {
var tabElement = tabElements[i];
if (tabElement === this._tabElement)
continue;
var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
if (!intersects)
continue;
if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
break;
if (event.pageX - this._dragStartX > 0) {
tabElement = tabElement.nextSibling;
++i;
}
var oldOffsetLeft = this._tabElement.offsetLeft;
this._tabbedPane._insertBefore(this, i);
this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
break;
}
if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px");
},
/**
* @param {!Event} event
*/
_endTabDragging: function(event)
{
this._tabElement.classList.remove("dragging");
this._tabElement.style.removeProperty("left");
delete this._dragStartX;
this._tabbedPane._updateTabSlider();
}
}
/**
* @interface
*/
WebInspector.TabbedPaneTabDelegate = function()
{
}
WebInspector.TabbedPaneTabDelegate.prototype = {
/**
* @param {!WebInspector.TabbedPane} tabbedPane
* @param {!Array.<string>} ids
*/
closeTabs: function(tabbedPane, ids) { },
/**
* @param {string} tabId
* @param {!WebInspector.ContextMenu} contextMenu
*/
onContextMenu: function(tabId, contextMenu) { }
}
/**
* @constructor
* @param {!WebInspector.TabbedPane} tabbedPane
* @param {string} extensionPoint
* @param {function(string, !WebInspector.Widget)=} viewCallback
*/
WebInspector.ExtensibleTabbedPaneController = function(tabbedPane, extensionPoint, viewCallback)
{
this._tabbedPane = tabbedPane;
this._extensionPoint = extensionPoint;
this._viewCallback = viewCallback;
/** @type {!Object.<string, !Promise.<?WebInspector.Widget>>} */
this._promiseForId = {};
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
/** @type {!Map.<string, !WebInspector.Widget>} */
this._views = new Map();
this._closeableTabSetting = WebInspector.settings.createSetting(extensionPoint + "-closeableTabs", {});
this._initialize();
}
WebInspector.ExtensibleTabbedPaneController.prototype = {
_initialize: function()
{
/** @type {!Map.<string, !Runtime.Extension>} */
this._extensions = new Map();
var extensions = self.runtime.extensions(this._extensionPoint);
for (var i = 0; i < extensions.length; ++i) {
var id = extensions[i].descriptor()["name"];
this._extensions.set(id, extensions[i]);
if (this._isPermanentTab(id))
this._appendTab(extensions[i]);
}
for (var i = 0; i < extensions.length; i++) {
var id = extensions[i].descriptor()["name"];
if (this._isCloseableTab(id) && this._closeableTabSetting.get()[id])
this._appendTab(extensions[i]);
}
},
/**
* @param {string} id
* @return {boolean}
*/
_isPermanentTab: function(id)
{
return this._extensions.get(id).descriptor()["persistence"] === "permanent" || !this._extensions.get(id).descriptor()["persistence"];
},
/**
* @param {string} id
* @return {boolean}
*/
_isCloseableTab: function(id)
{
return this._extensions.get(id).descriptor()["persistence"] === "closeable";
},
enableMoreTabsButton: function()
{
var toolbar = new WebInspector.Toolbar("drawer-toolbar");
toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(this._appendTabsToMenu.bind(this)));
this._tabbedPane.insertBeforeTabStrip(toolbar.element);
this._tabbedPane.disableOverflowMenu();
},
/**
* @param {!WebInspector.ContextMenu} contextMenu
*/
_appendTabsToMenu: function(contextMenu)
{
for (var id of this._extensions.keysArray().filter(this._isPermanentTab.bind(this))) {
var title = WebInspector.UIString(this._extensions.get(id).title(WebInspector.platform()));
contextMenu.appendItem(title, this.showTab.bind(this, id));
}
for (var id of this._extensions.keysArray().filter(this._isCloseableTab.bind(this))) {
var title = WebInspector.UIString(this._extensions.get(id).title(WebInspector.platform()));
contextMenu.appendItem(title, this.showTab.bind(this, id));
}
},
/**
* @param {!Runtime.Extension} extension
*/
_appendTab: function(extension)
{
var descriptor = extension.descriptor();
var id = descriptor["name"];
var title = WebInspector.UIString(extension.title(WebInspector.platform()));
var closeable = descriptor["persistence"] === "closeable" || descriptor["persistence"] === "temporary";
this._tabbedPane.appendTab(id, title, this._views.get(id) || new WebInspector.Widget(), undefined, false, closeable);
},
/**
* @param {string} id
* @return {!Promise.<?WebInspector.Widget>}
*/
showTab: function(id)
{
/**
* @param {?WebInspector.Widget} view
* @return {?WebInspector.Widget} view
* @this {WebInspector.ExtensibleTabbedPaneController}
*/
function viewLoaded(view)
{
if (this._pendingView === id)
this._tabbedPane.selectTab(id);
delete this._pendingView;
return view;
}
console.assert(this._extensions.get(id));
if (!this._tabbedPane.hasTab(id))
this._appendTab(/** @type {!Runtime.Extension} */(this._extensions.get(id)));
this._tabbedPane.selectTab(id);
var descriptor = this._extensions.get(id).descriptor();
if (descriptor["persistence"] === "closeable") {
var tabs = this._closeableTabSetting.get();
if (!tabs[id]) {
tabs[id] = true;
this._closeableTabSetting.set(tabs);
}
}
this._pendingView = id;
return this.viewForId(id).then(viewLoaded.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_tabSelected: function(event)
{
var tabId = /** @type {string} */ (event.data.tabId);
this.viewForId(tabId);
},
/**
* @param {!WebInspector.Event} event
*/
_tabClosed: function(event)
{
var tabs = this._closeableTabSetting.get();
if (tabs[event.data.tabId]) {
delete tabs[event.data.tabId];
this._closeableTabSetting.set(tabs);
}
},
/**
* @return {!Array.<string>}
*/
viewIds: function()
{
return this._extensions.keysArray();
},
/**
* @param {string} id
* @return {!Promise.<?WebInspector.Widget>}
*/
viewForId: function(id)
{
if (this._views.has(id))
return Promise.resolve(/** @type {?WebInspector.Widget} */ (this._views.get(id)));
if (!this._extensions.has(id))
return Promise.resolve(/** @type {?WebInspector.Widget} */ (null));
if (this._promiseForId[id])
return this._promiseForId[id];
var promise = this._extensions.get(id).instancePromise();
this._promiseForId[id] = /** @type {!Promise.<?WebInspector.Widget>} */ (promise);
return promise.then(cacheView.bind(this));
/**
* @param {!Object} object
* @this {WebInspector.ExtensibleTabbedPaneController}
*/
function cacheView(object)
{
var view = /** @type {!WebInspector.Widget} */ (object);
delete this._promiseForId[id];
this._views.set(id, view);
if (this._viewCallback && view)
this._viewCallback(id, view);
var shouldFocus = this._tabbedPane.visibleView.element.isSelfOrAncestor(WebInspector.currentFocusElement());
this._tabbedPane.changeTabView(id, view);
if (shouldFocus)
view.focus();
return view;
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 | 2 1 | /*
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.SuggestBoxDelegate}
* @param {function(!Element, string, number, !Range, boolean, function(!Array.<string>, number=))} completions
* @param {string=} stopCharacters
*/
WebInspector.TextPrompt = function(completions, stopCharacters)
{
/**
* @type {!Element|undefined}
*/
this._proxyElement;
this._proxyElementDisplay = "inline-block";
this._loadCompletions = completions;
this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>.";
this._autocompletionTimeout = WebInspector.TextPrompt.DefaultAutocompletionTimeout;
}
WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250;
WebInspector.TextPrompt.Events = {
ItemApplied: "text-prompt-item-applied",
ItemAccepted: "text-prompt-item-accepted"
};
WebInspector.TextPrompt.prototype = {
/**
* @param {number} timeout
*/
setAutocompletionTimeout: function(timeout)
{
this._autocompletionTimeout = timeout;
},
/**
* @param {boolean} suggestBoxEnabled
*/
setSuggestBoxEnabled: function(suggestBoxEnabled)
{
this._suggestBoxEnabled = suggestBoxEnabled;
},
renderAsBlock: function()
{
this._proxyElementDisplay = "block";
},
/**
* Clients should never attach any event listeners to the |element|. Instead,
* they should use the result of this method to attach listeners for bubbling events.
*
* @param {!Element} element
* @return {!Element}
*/
attach: function(element)
{
return this._attachInternal(element);
},
/**
* Clients should never attach any event listeners to the |element|. Instead,
* they should use the result of this method to attach listeners for bubbling events
* or the |blurListener| parameter to register a "blur" event listener on the |element|
* (since the "blur" event does not bubble.)
*
* @param {!Element} element
* @param {function(!Event)} blurListener
* @return {!Element}
*/
attachAndStartEditing: function(element, blurListener)
{
var proxyElement = this._attachInternal(element);
this._startEditing(blurListener);
return proxyElement;
},
/**
* @param {!Element} element
* @return {!Element}
*/
_attachInternal: function(element)
{
if (this._proxyElement)
throw "Cannot attach an attached TextPrompt";
this._element = element;
this._boundOnKeyDown = this.onKeyDown.bind(this);
this._boundOnInput = this.onInput.bind(this);
this._boundOnMouseWheel = this.onMouseWheel.bind(this);
this._boundSelectStart = this._selectStart.bind(this);
this._boundRemoveSuggestionAids = this._removeSuggestionAids.bind(this);
this._proxyElement = element.ownerDocument.createElement("span");
var shadowRoot = WebInspector.createShadowRootWithCoreStyles(this._proxyElement, "ui/textPrompt.css");
this._contentElement = shadowRoot.createChild("div");
this._contentElement.createChild("content");
this._proxyElement.style.display = this._proxyElementDisplay;
element.parentElement.insertBefore(this._proxyElement, element);
this._proxyElement.appendChild(element);
this._element.classList.add("text-prompt");
this._element.addEventListener("keydown", this._boundOnKeyDown, false);
this._element.addEventListener("input", this._boundOnInput, false);
this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.addEventListener("selectstart", this._boundSelectStart, false);
this._element.addEventListener("blur", this._boundRemoveSuggestionAids, false);
this._element.ownerDocument.defaultView.addEventListener("resize", this._boundRemoveSuggestionAids, false);
if (this._suggestBoxEnabled)
this._suggestBox = new WebInspector.SuggestBox(this);
return this._proxyElement;
},
detach: function()
{
this._removeFromElement();
this._proxyElement.parentElement.insertBefore(this._element, this._proxyElement);
this._proxyElement.remove();
delete this._proxyElement;
this._element.classList.remove("text-prompt");
WebInspector.restoreFocusFromElement(this._element);
},
/**
* @return {string}
*/
text: function()
{
return this._element.textContent;
},
/**
* @return {string}
*/
userEnteredText: function()
{
var text = this.text();
if (this.autoCompleteElement) {
var addition = this.autoCompleteElement.textContent;
text = text.substring(0, text.length - addition.length);
}
return text;
},
/**
* @param {string} x
*/
setText: function(x)
{
this._removeSuggestionAids();
if (!x) {
// Append a break element instead of setting textContent to make sure the selection is inside the prompt.
this._element.removeChildren();
this._element.createChild("br");
} else {
this._element.textContent = x;
}
this.moveCaretToEndOfPrompt();
this._element.scrollIntoView();
},
_removeFromElement: function()
{
this.clearAutoComplete(true);
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("input", this._boundOnInput, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
this._element.removeEventListener("blur", this._boundRemoveSuggestionAids, false);
this._element.ownerDocument.defaultView.removeEventListener("resize", this._boundRemoveSuggestionAids, false);
if (this._isEditing)
this._stopEditing();
if (this._suggestBox)
this._suggestBox.removeFromElement();
},
/**
* @param {function(!Event)=} blurListener
*/
_startEditing: function(blurListener)
{
this._isEditing = true;
this._contentElement.classList.add("text-prompt-editing");
if (blurListener) {
this._blurListener = blurListener;
this._element.addEventListener("blur", this._blurListener, false);
}
this._oldTabIndex = this._element.tabIndex;
if (this._element.tabIndex < 0)
this._element.tabIndex = 0;
WebInspector.setCurrentFocusElement(this._element);
if (!this.text())
this._updateAutoComplete();
},
_stopEditing: function()
{
this._element.tabIndex = this._oldTabIndex;
if (this._blurListener)
this._element.removeEventListener("blur", this._blurListener, false);
this._contentElement.classList.remove("text-prompt-editing");
delete this._isEditing;
},
_removeSuggestionAids: function()
{
this.clearAutoComplete();
this.hideSuggestBox();
},
_selectStart: function()
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);
this._removeSuggestionAids();
/**
* @this {WebInspector.TextPrompt}
*/
function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.isCaretInsidePrompt() && this._element.isComponentSelectionCollapsed()) {
this.moveCaretToEndOfPrompt();
this.autoCompleteSoon();
}
}
this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},
/**
* @param {boolean=} force
*/
_updateAutoComplete: function(force)
{
this.clearAutoComplete();
this.autoCompleteSoon(force);
},
/**
* @param {!Event} event
*/
onMouseWheel: function(event)
{
// Subclasses can implement.
},
/**
* @param {!Event} event
*/
onKeyDown: function(event)
{
if (isEnterKey(event))
return;
var handled = false;
delete this._needUpdateAutocomplete;
switch (event.keyIdentifier) {
case "U+0009": // Tab
handled = this.tabKeyPressed(event);
break;
case "Left":
case "Home":
this._removeSuggestionAids();
break;
case "Right":
case "End":
if (this.isCaretAtEndOfPrompt())
handled = this.acceptAutoComplete();
else
this._removeSuggestionAids();
break;
case "U+001B": // Esc
if (this.isSuggestBoxVisible()) {
this._removeSuggestionAids();
handled = true;
}
break;
case "U+0020": // Space
if (event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
this._updateAutoComplete(true);
handled = true;
}
break;
case "Alt":
case "Meta":
case "Shift":
case "Control":
break;
}
if (!handled && this.isSuggestBoxVisible())
handled = this._suggestBox.keyPressed(event);
if (!handled)
this._needUpdateAutocomplete = true;
if (handled)
event.consume(true);
},
/**
* @param {!Event} event
*/
onInput: function(event)
{
if (this._needUpdateAutocomplete)
this._updateAutoComplete();
},
/**
* @return {boolean}
*/
acceptAutoComplete: function()
{
var result = false;
if (this.isSuggestBoxVisible())
result = this._suggestBox.acceptSuggestion();
if (!result)
result = this._acceptSuggestionInternal();
return result;
},
/**
* @param {boolean=} includeTimeout
*/
clearAutoComplete: function(includeTimeout)
{
if (includeTimeout && this._completeTimeout) {
clearTimeout(this._completeTimeout);
delete this._completeTimeout;
}
delete this._waitingForCompletions;
if (!this.autoCompleteElement)
return;
this.autoCompleteElement.remove();
delete this.autoCompleteElement;
delete this._userEnteredRange;
delete this._userEnteredText;
},
/**
* @param {boolean=} force
*/
autoCompleteSoon: function(force)
{
var immediately = this.isSuggestBoxVisible() || force;
if (!this._completeTimeout)
this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout);
},
/**
* @param {boolean=} force
* @param {boolean=} reverse
*/
complete: function(force, reverse)
{
this.clearAutoComplete(true);
var selection = this._element.getComponentSelection();
if (!selection.rangeCount)
return;
var selectionRange = selection.getRangeAt(0);
var shouldExit;
if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
shouldExit = true;
else if (!selection.isCollapsed)
shouldExit = true;
else if (!force) {
// BUG72018: Do not show suggest box if caret is followed by a non-stop character.
var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
if (wordSuffixRange.toString().length)
shouldExit = true;
}
if (shouldExit) {
this.hideSuggestBox();
return;
}
var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
this._waitingForCompletions = true;
this._loadCompletions(/** @type {!Element} */ (this._proxyElement), this.text(), selectionRange.startOffset, wordPrefixRange, force || false, this._completionsReady.bind(this, selection, wordPrefixRange, !!reverse, !!force));
},
disableDefaultSuggestionForEmptyInput: function()
{
this._disableDefaultSuggestionForEmptyInput = true;
},
/**
* @param {!Selection} selection
* @param {!Range} textRange
*/
_boxForAnchorAtStart: function(selection, textRange)
{
var rangeCopy = selection.getRangeAt(0).cloneRange();
var anchorElement = createElement("span");
anchorElement.textContent = "\u200B";
textRange.insertNode(anchorElement);
var box = anchorElement.boxInWindow(window);
anchorElement.remove();
selection.removeAllRanges();
selection.addRange(rangeCopy);
return box;
},
/**
* @param {!Array.<string>} completions
* @param {number} wordPrefixLength
*/
_buildCommonPrefix: function(completions, wordPrefixLength)
{
var commonPrefix = completions[0];
for (var i = 0; i < completions.length; ++i) {
var completion = completions[i];
var lastIndex = Math.min(commonPrefix.length, completion.length);
for (var j = wordPrefixLength; j < lastIndex; ++j) {
if (commonPrefix[j] !== completion[j]) {
commonPrefix = commonPrefix.substr(0, j);
break;
}
}
}
return commonPrefix;
},
/**
* @return {?Range}
* @suppressGlobalPropertiesCheck
*/
_createRange: function()
{
return document.createRange();
},
/**
* @param {string} prefix
* @return {!WebInspector.SuggestBox.Suggestions}
*/
additionalCompletions: function(prefix)
{
return [];
},
/**
* @param {!Selection} selection
* @param {!Range} originalWordPrefixRange
* @param {boolean} reverse
* @param {boolean} force
* @param {!Array.<string>} completions
* @param {number=} selectedIndex
*/
_completionsReady: function(selection, originalWordPrefixRange, reverse, force, completions, selectedIndex)
{
var prefix = originalWordPrefixRange.toString();
// Filter out dupes.
var store = new Set();
completions = completions.filter(item => !store.has(item) && !!store.add(item));
var annotatedCompletions = completions.map(item => ({title: item}));
if (prefix || force) {
if (prefix)
annotatedCompletions = annotatedCompletions.concat(this.additionalCompletions(prefix));
else
annotatedCompletions = this.additionalCompletions(prefix).concat(annotatedCompletions);
}
if (!this._waitingForCompletions || !annotatedCompletions.length) {
this.hideSuggestBox();
return;
}
delete this._waitingForCompletions;
var selectionRange = selection.getRangeAt(0);
var fullWordRange = this._createRange();
fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
if (prefix + selectionRange.toString() !== fullWordRange.toString())
return;
selectedIndex = (this._disableDefaultSuggestionForEmptyInput && !this.text()) ? -1 : (selectedIndex || 0);
this._userEnteredRange = fullWordRange;
this._userEnteredText = fullWordRange.toString();
if (this._suggestBox)
this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), annotatedCompletions, selectedIndex, !this.isCaretAtEndOfPrompt(), this._userEnteredText);
if (selectedIndex === -1)
return;
var wordPrefixLength = originalWordPrefixRange.toString().length;
this._commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
if (this.isCaretAtEndOfPrompt()) {
var completionText = annotatedCompletions[selectedIndex].title;
var prefixText = this._userEnteredRange.toString();
var suffixText = completionText.substring(wordPrefixLength);
this._userEnteredRange.deleteContents();
this._element.normalize();
var finalSelectionRange = this._createRange();
var prefixTextNode = createTextNode(prefixText);
fullWordRange.insertNode(prefixTextNode);
this.autoCompleteElement = createElementWithClass("span", "auto-complete-text");
this.autoCompleteElement.textContent = suffixText;
prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);
finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied);
}
},
_completeCommonPrefix: function()
{
if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText))
return;
if (!this.isSuggestBoxVisible()) {
this.acceptAutoComplete();
return;
}
this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
this._acceptSuggestionInternal(true);
},
/**
* @override
* @param {string} completionText
* @param {boolean=} isIntermediateSuggestion
*/
applySuggestion: function(completionText, isIntermediateSuggestion)
{
this._applySuggestion(completionText, isIntermediateSuggestion);
},
/**
* @param {string} completionText
* @param {boolean=} isIntermediateSuggestion
*/
_applySuggestion: function(completionText, isIntermediateSuggestion)
{
var wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;
this._userEnteredRange.deleteContents();
this._element.normalize();
var finalSelectionRange = this._createRange();
var completionTextNode = createTextNode(completionText);
this._userEnteredRange.insertNode(completionTextNode);
if (this.autoCompleteElement) {
this.autoCompleteElement.remove();
delete this.autoCompleteElement;
}
if (isIntermediateSuggestion)
finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
else
finalSelectionRange.setStart(completionTextNode, completionText.length);
finalSelectionRange.setEnd(completionTextNode, completionText.length);
var selection = this._element.getComponentSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (isIntermediateSuggestion)
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
},
/**
* @override
*/
acceptSuggestion: function()
{
this._acceptSuggestionInternal();
},
/**
* @param {boolean=} prefixAccepted
* @return {boolean}
*/
_acceptSuggestionInternal: function(prefixAccepted)
{
if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
return false;
var text = this.autoCompleteElement.textContent;
var textNode = createTextNode(text);
this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
delete this.autoCompleteElement;
var finalSelectionRange = this._createRange();
finalSelectionRange.setStart(textNode, text.length);
finalSelectionRange.setEnd(textNode, text.length);
var selection = this._element.getComponentSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (!prefixAccepted) {
this.hideSuggestBox();
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
} else
this.autoCompleteSoon(true);
return true;
},
hideSuggestBox: function()
{
if (this.isSuggestBoxVisible())
this._suggestBox.hide();
},
/**
* @return {boolean}
*/
isSuggestBoxVisible: function()
{
return this._suggestBox && this._suggestBox.visible();
},
/**
* @return {boolean}
*/
isCaretInsidePrompt: function()
{
return this._element.isInsertionCaretInside();
},
/**
* @return {boolean}
*/
isCaretAtEndOfPrompt: function()
{
var selection = this._element.getComponentSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;
var selectionRange = selection.getRangeAt(0);
var node = selectionRange.startContainer;
if (!node.isSelfOrDescendant(this._element))
return false;
if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
return false;
var foundNextText = false;
while (node) {
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
return false;
foundNextText = true;
}
node = node.traverseNextNode(this._element);
}
return true;
},
/**
* @return {boolean}
*/
isCaretOnFirstLine: function()
{
var selection = this._element.getComponentSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;
if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
}
return true;
},
/**
* @return {boolean}
*/
isCaretOnLastLine: function()
{
var selection = this._element.getComponentSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;
if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
}
return true;
},
moveCaretToEndOfPrompt: function()
{
var selection = this._element.getComponentSelection();
var selectionRange = this._createRange();
var container = this._element;
while (container.childNodes.length)
container = container.lastChild;
var offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : 0;
selectionRange.setStart(container, offset);
selectionRange.setEnd(container, offset);
selection.removeAllRanges();
selection.addRange(selectionRange);
},
/**
* @param {!Event} event
* @return {boolean}
*/
tabKeyPressed: function(event)
{
this.acceptAutoComplete();
// Consume the key.
return true;
},
/**
* @return {?Element}
*/
proxyElementForTests: function()
{
return this._proxyElement || null;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.TextPrompt}
* @param {function(!Element, string, number, !Range, boolean, function(!Array.<string>, number=))} completions
* @param {string=} stopCharacters
*/
WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
{
WebInspector.TextPrompt.call(this, completions, stopCharacters);
/**
* @type {!Array.<string>}
*/
this._data = [];
/**
* 1-based entry in the history stack.
* @type {number}
*/
this._historyOffset = 1;
this._addCompletionsFromHistory = true;
}
WebInspector.TextPromptWithHistory.prototype = {
/**
* @return {!Array.<string>}
*/
historyData: function()
{
// FIXME: do we need to copy this?
return this._data;
},
/**
* @override
* @param {string} prefix
* @return {!WebInspector.SuggestBox.Suggestions}
*/
additionalCompletions: function(prefix)
{
if (!this._addCompletionsFromHistory || !this.isCaretAtEndOfPrompt())
return [];
var result = [];
var text = this.text();
var set = new Set();
for (var i = this._data.length - 1; i >= 0 && result.length < 50; --i) {
var item = this._data[i];
if (!item.startsWith(text))
continue;
if (set.has(item))
continue;
set.add(item);
result.push({title: item.substring(text.length - prefix.length), className: "additional"});
}
return result;
},
/**
* @param {!Array.<string>} data
*/
setHistoryData: function(data)
{
this._data = [].concat(data);
this._historyOffset = 1;
},
/**
* @param {boolean} value
*/
setAddCompletionsFromHistory: function(value)
{
this._addCompletionsFromHistory = value;
},
/**
* Pushes a committed text into the history.
* @param {string} text
*/
pushHistoryItem: function(text)
{
if (this._uncommittedIsTop) {
this._data.pop();
delete this._uncommittedIsTop;
}
this._historyOffset = 1;
if (text === this._currentHistoryItem())
return;
this._data.push(text);
},
/**
* Pushes the current (uncommitted) text into the history.
*/
_pushCurrentText: function()
{
if (this._uncommittedIsTop)
this._data.pop(); // Throw away obsolete uncommitted text.
this._uncommittedIsTop = true;
this.clearAutoComplete(true);
this._data.push(this.text());
},
/**
* @return {string|undefined}
*/
_previous: function()
{
if (this._historyOffset > this._data.length)
return undefined;
if (this._historyOffset === 1)
this._pushCurrentText();
++this._historyOffset;
return this._currentHistoryItem();
},
/**
* @return {string|undefined}
*/
_next: function()
{
if (this._historyOffset === 1)
return undefined;
--this._historyOffset;
return this._currentHistoryItem();
},
/**
* @return {string|undefined}
*/
_currentHistoryItem: function()
{
return this._data[this._data.length - this._historyOffset];
},
/**
* @override
*/
onKeyDown: function(event)
{
var newText;
var isPrevious;
switch (event.keyIdentifier) {
case "Up":
if (!this.isCaretOnFirstLine() || this.isSuggestBoxVisible())
break;
newText = this._previous();
isPrevious = true;
break;
case "Down":
if (!this.isCaretOnLastLine() || this.isSuggestBoxVisible())
break;
newText = this._next();
break;
case "U+0050": // Ctrl+P = Previous
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
newText = this._previous();
isPrevious = true;
}
break;
case "U+004E": // Ctrl+N = Next
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
newText = this._next();
break;
}
if (newText !== undefined) {
event.consume(true);
this.setText(newText);
if (isPrevious) {
var firstNewlineIndex = this.text().indexOf("\n");
if (firstNewlineIndex === -1)
this.moveCaretToEndOfPrompt();
else {
var selection = this._element.getComponentSelection();
var selectionRange = this._createRange();
selectionRange.setStart(this._element.firstChild, firstNewlineIndex);
selectionRange.setEnd(this._element.firstChild, firstNewlineIndex);
selection.removeAllRanges();
selection.addRange(selectionRange);
}
}
return;
}
WebInspector.TextPrompt.prototype.onKeyDown.apply(this, arguments);
},
__proto__: WebInspector.TextPrompt.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {boolean=} isWebComponent
*/
WebInspector.ThrottledWidget = function(isWebComponent)
{
WebInspector.Widget.call(this, isWebComponent);
this._updateThrottler = new WebInspector.Throttler(100);
this._updateWhenVisible = false;
}
WebInspector.ThrottledWidget.prototype = {
/**
* @protected
* @return {!Promise.<?>}
*/
doUpdate: function()
{
return Promise.resolve();
},
update: function()
{
this._updateWhenVisible = !this.isShowing();
if (this._updateWhenVisible)
return;
this._updateThrottler.schedule(innerUpdate.bind(this));
/**
* @this {WebInspector.ThrottledWidget}
* @return {!Promise.<?>}
*/
function innerUpdate()
{
if (this.isShowing()) {
return this.doUpdate();
} else {
this._updateWhenVisible = true;
return Promise.resolve();
}
}
},
/**
* @override
*/
wasShown: function()
{
WebInspector.Widget.prototype.wasShown.call(this);
if (this._updateWhenVisible)
this.update();
},
__proto__: WebInspector.Widget.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | 2 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} className
* @param {!Element=} parentElement
*/
WebInspector.Toolbar = function(className, parentElement)
{
/** @type {!Array.<!WebInspector.ToolbarItem>} */
this._items = [];
this._reverse = false;
this.element = parentElement ? parentElement.createChild("div") : createElement("div");
this.element.className = className;
this.element.classList.add("toolbar");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/toolbar.css");
this._contentElement = this._shadowRoot.createChild("div", "toolbar-shadow");
this._insertionPoint = this._contentElement.createChild("content");
}
WebInspector.Toolbar.prototype = {
/**
* @param {boolean=} reverse
*/
makeWrappable: function(reverse)
{
this._contentElement.classList.add("wrappable");
this._reverse = !!reverse;
if (reverse)
this._contentElement.classList.add("wrappable-reverse");
},
makeVertical: function()
{
this._contentElement.classList.add("vertical");
},
makeBlueOnHover: function()
{
this._contentElement.classList.add("toolbar-blue-on-hover");
},
makeToggledGray: function()
{
this._contentElement.classList.add("toolbar-toggled-gray");
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
for (var item of this._items)
item.setEnabled(enabled);
},
/**
* @param {!WebInspector.ToolbarItem} item
*/
appendToolbarItem: function(item)
{
this._items.push(item);
item._toolbar = this;
if (this._reverse)
this._contentElement.insertBefore(item.element, this._insertionPoint.nextSibling);
else
this._contentElement.insertBefore(item.element, this._insertionPoint);
this._hideSeparatorDupes();
},
appendSeparator: function()
{
this.appendToolbarItem(new WebInspector.ToolbarSeparator());
},
appendSpacer: function()
{
this.appendToolbarItem(new WebInspector.ToolbarSeparator(true));
},
/**
* @param {string} text
*/
appendText: function(text)
{
this.appendToolbarItem(new WebInspector.ToolbarText(text));
},
removeToolbarItems: function()
{
for (var item of this._items)
delete item._toolbar;
this._items = [];
this._contentElement.removeChildren();
this._insertionPoint = this._contentElement.createChild("content");
},
/**
* @param {string} color
*/
setColor: function(color)
{
var style = createElement("style");
style.textContent = ".toolbar-glyph { background-color: " + color + " !important }";
this._shadowRoot.appendChild(style);
},
/**
* @param {string} color
*/
setToggledColor: function(color)
{
var style = createElement("style");
style.textContent = ".toolbar-button.toolbar-state-on .toolbar-glyph { background-color: " + color + " !important }";
this._shadowRoot.appendChild(style);
},
_hideSeparatorDupes: function()
{
if (!this._items.length)
return;
// Don't hide first and last separators if they were added explicitly.
var previousIsSeparator = false;
var lastSeparator;
var nonSeparatorVisible = false;
for (var i = 0; i < this._items.length; ++i) {
if (this._items[i] instanceof WebInspector.ToolbarSeparator) {
this._items[i].setVisible(!previousIsSeparator);
previousIsSeparator = true;
lastSeparator = this._items[i];
continue;
}
if (this._items[i].visible()) {
previousIsSeparator = false;
lastSeparator = null;
nonSeparatorVisible = true;
}
}
if (lastSeparator && lastSeparator !== this._items.peekLast())
lastSeparator.setVisible(false);
this.element.classList.toggle("hidden", !!lastSeparator && lastSeparator.visible() && !nonSeparatorVisible);
}
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Element} element
*/
WebInspector.ToolbarItem = function(element)
{
this.element = element;
this.element.classList.add("toolbar-item");
this._visible = true;
this._enabled = true;
this.element.addEventListener("mouseenter", this._mouseEnter.bind(this), false);
this.element.addEventListener("mouseleave", this._mouseLeave.bind(this), false);
}
WebInspector.ToolbarItem.prototype = {
/**
* @param {string} title
*/
setTitle: function(title)
{
if (this._title === title)
return;
this._title = title;
WebInspector.Tooltip.install(this.element, title);
},
_mouseEnter: function()
{
this.element.classList.add("hover");
},
_mouseLeave: function()
{
this.element.classList.remove("hover");
},
/**
* @param {boolean} value
*/
setEnabled: function(value)
{
if (this._enabled === value)
return;
this._enabled = value;
this._applyEnabledState();
},
_applyEnabledState: function()
{
this.element.disabled = !this._enabled;
},
/**
* @return {boolean} x
*/
visible: function()
{
return this._visible;
},
/**
* @param {boolean} x
*/
setVisible: function(x)
{
if (this._visible === x)
return;
this.element.classList.toggle("hidden", !x);
this._visible = x;
if (this._toolbar && !(this instanceof WebInspector.ToolbarSeparator))
this._toolbar._hideSeparatorDupes();
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {string=} text
*/
WebInspector.ToolbarText = function(text)
{
WebInspector.ToolbarItem.call(this, createElementWithClass("div", "toolbar-text"));
this.element.classList.add("toolbar-text");
this.setText(text || "");
}
WebInspector.ToolbarText.prototype = {
/**
* @param {string} text
*/
setText: function(text)
{
this.element.textContent = text;
},
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {string} title
* @param {string=} glyph
* @param {string=} text
*/
WebInspector.ToolbarButton = function(title, glyph, text)
{
WebInspector.ToolbarItem.call(this, createElementWithClass("button", "toolbar-button"));
this.element.addEventListener("click", this._clicked.bind(this), false);
this.element.addEventListener("mousedown", this._mouseDown.bind(this), false);
this.element.addEventListener("mouseup", this._mouseUp.bind(this), false);
this._glyphElement = this.element.createChild("div", "toolbar-glyph hidden");
this._textElement = this.element.createChild("div", "toolbar-text hidden");
this.setTitle(title);
if (glyph)
this.setGlyph(glyph);
this.setText(text || "");
this._state = "";
this._title = "";
}
WebInspector.ToolbarButton.prototype = {
/**
* @param {string} text
*/
setText: function(text)
{
if (this._text === text)
return;
this._textElement.textContent = text;
this._textElement.classList.toggle("hidden", !text);
this._text = text;
},
/**
* @param {string} glyph
*/
setGlyph: function(glyph)
{
if (this._glyph === glyph)
return;
if (this._glyph)
this._glyphElement.classList.remove(this._glyph);
if (glyph)
this._glyphElement.classList.add(glyph);
this._glyphElement.classList.toggle("hidden", !glyph);
this.element.classList.toggle("toolbar-has-glyph", !!glyph);
this._glyph = glyph;
},
/**
* @param {string} iconURL
*/
setBackgroundImage: function(iconURL)
{
this.element.style.backgroundImage = "url(" + iconURL + ")";
},
/**
* @return {string}
*/
state: function()
{
return this._state;
},
/**
* @param {string} state
*/
setState: function(state)
{
if (this._state === state)
return;
this.element.classList.remove("toolbar-state-" + this._state);
this.element.classList.add("toolbar-state-" + state);
this._state = state;
},
/**
* @param {number=} width
*/
turnIntoSelect: function(width)
{
this.element.classList.add("toolbar-has-dropdown");
this.element.createChild("div", "toolbar-dropdown-arrow");
if (width)
this.element.style.width = width + "px";
},
/**
* @param {!Event} event
*/
_clicked: function(event)
{
var defaultPrevented = this.dispatchEventToListeners("click", event);
event.consume(defaultPrevented);
},
/**
* @param {!Event} event
*/
_mouseDown: function(event)
{
this.dispatchEventToListeners("mousedown", event);
},
/**
* @param {!Event} event
*/
_mouseUp: function(event)
{
this.dispatchEventToListeners("mouseup", event);
},
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {string=} placeholder
* @param {number=} growFactor
*/
WebInspector.ToolbarInput = function(placeholder, growFactor)
{
WebInspector.ToolbarItem.call(this, createElementWithClass("input", "toolbar-item"));
this.element.addEventListener("input", this._onChangeCallback.bind(this), false);
if (growFactor)
this.element.style.flexGrow = growFactor;
if (placeholder)
this.element.setAttribute("placeholder", placeholder);
this._value = "";
}
WebInspector.ToolbarInput.Event = {
TextChanged: "TextChanged"
};
WebInspector.ToolbarInput.prototype = {
/**
* @param {string} value
*/
setValue: function(value)
{
this._value = value;
this.element.value = value;
},
/**
* @return {string}
*/
value: function()
{
return this.element.value;
},
_onChangeCallback: function()
{
this.dispatchEventToListeners(WebInspector.ToolbarInput.Event.TextChanged, this.element.value);
},
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarButton}
* @param {string} title
* @param {string=} glyph
* @param {string=} text
*/
WebInspector.ToolbarToggle = function(title, glyph, text)
{
WebInspector.ToolbarButton.call(this, title, glyph, text);
this._toggled = false;
this.setState("off");
}
WebInspector.ToolbarToggle.prototype = {
/**
* @return {boolean}
*/
toggled: function()
{
return this._toggled;
},
/**
* @param {boolean} toggled
*/
setToggled: function(toggled)
{
if (this._toggled === toggled)
return;
this._toggled = toggled;
this.setState(toggled ? "on" : "off");
},
__proto__: WebInspector.ToolbarButton.prototype
}
/**
* @param {!WebInspector.Action} action
* @param {!Array<!WebInspector.ToolbarButton>=} toggledOptions
* @param {!Array<!WebInspector.ToolbarButton>=} untoggledOptions
* @return {!WebInspector.ToolbarItem}
*/
WebInspector.Toolbar.createActionButton = function(action, toggledOptions, untoggledOptions)
{
var button = new WebInspector.ToolbarButton(action.title(), action.icon());
button.addEventListener("click", action.execute, action);
action.addEventListener(WebInspector.Action.Events.Enabled, enabledChanged);
action.addEventListener(WebInspector.Action.Events.StateChanged, stateChanged);
action.addEventListener(WebInspector.Action.Events.TitleChanged, titleChanged);
/** @type {?WebInspector.LongClickController} */
var longClickController = null;
/** @type {?Array<!WebInspector.ToolbarButton>} */
var longClickButtons = null;
/** @type {?Element} */
var longClickGlyph = null;
titleChanged();
stateChanged();
return button;
function titleChanged()
{
WebInspector.Tooltip.install(button.element, action.title(), action.id());
}
/**
* @param {!WebInspector.Event} event
*/
function enabledChanged(event)
{
button.setEnabled(/** @type {boolean} */ (event.data));
}
function stateChanged()
{
button.setState(action.state());
updateOptions();
}
function updateOptions()
{
if (action.statesCount() !== 2)
return;
var buttons = action.toggled() ? (toggledOptions || null) : (untoggledOptions || null);
if (buttons && buttons.length) {
if (!longClickController) {
longClickController = new WebInspector.LongClickController(button.element, showOptions);
longClickGlyph = button.element.createChild("div", "long-click-glyph toolbar-button-theme");
longClickButtons = buttons;
}
} else {
if (longClickController) {
longClickController.dispose();
longClickController = null;
longClickGlyph.remove();
longClickGlyph = null;
longClickButtons = null;
}
}
}
function showOptions()
{
var buttons = longClickButtons.slice();
var mainButtonClone = new WebInspector.ToolbarButton(action.title(), action.icon());
mainButtonClone.addEventListener("click", clicked);
/**
* @param {!WebInspector.Event} event
*/
function clicked(event)
{
button._clicked(/** @type {!Event} */ (event.data));
}
mainButtonClone.setState(action.state());
buttons.push(mainButtonClone);
var document = button.element.ownerDocument;
document.documentElement.addEventListener("mouseup", mouseUp, false);
var optionsGlassPane = new WebInspector.GlassPane(document);
var optionsBar = new WebInspector.Toolbar("fill", optionsGlassPane.element);
optionsBar._contentElement.classList.add("floating");
const buttonHeight = 26;
var hostButtonPosition = button.element.totalOffset();
var topNotBottom = hostButtonPosition.top + buttonHeight * buttons.length < document.documentElement.offsetHeight;
if (topNotBottom)
buttons = buttons.reverse();
optionsBar.element.style.height = (buttonHeight * buttons.length) + "px";
if (topNotBottom)
optionsBar.element.style.top = (hostButtonPosition.top + 1) + "px";
else
optionsBar.element.style.top = (hostButtonPosition.top - (buttonHeight * (buttons.length - 1))) + "px";
optionsBar.element.style.left = (hostButtonPosition.left + 1) + "px";
for (var i = 0; i < buttons.length; ++i) {
buttons[i].element.addEventListener("mousemove", mouseOver, false);
buttons[i].element.addEventListener("mouseout", mouseOut, false);
optionsBar.appendToolbarItem(buttons[i]);
}
var hostButtonIndex = topNotBottom ? 0 : buttons.length - 1;
buttons[hostButtonIndex].element.classList.add("emulate-active");
function mouseOver(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("toolbar-item");
buttonElement.classList.add("emulate-active");
}
function mouseOut(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("toolbar-item");
buttonElement.classList.remove("emulate-active");
}
function mouseUp(e)
{
if (e.which !== 1)
return;
optionsGlassPane.dispose();
document.documentElement.removeEventListener("mouseup", mouseUp, false);
for (var i = 0; i < buttons.length; ++i) {
if (buttons[i].element.classList.contains("emulate-active")) {
buttons[i].element.classList.remove("emulate-active");
buttons[i]._clicked(e);
break;
}
}
}
}
}
/**
* @constructor
* @extends {WebInspector.ToolbarButton}
* @param {function(!WebInspector.ContextMenu)} contextMenuHandler
* @param {boolean=} useSoftMenu
*/
WebInspector.ToolbarMenuButton = function(contextMenuHandler, useSoftMenu)
{
WebInspector.ToolbarButton.call(this, "", "menu-toolbar-item");
this._contextMenuHandler = contextMenuHandler;
this._useSoftMenu = !!useSoftMenu;
}
WebInspector.ToolbarMenuButton.prototype = {
/**
* @override
* @param {!Event} event
*/
_mouseDown: function(event)
{
if (event.buttons !== 1) {
WebInspector.ToolbarButton.prototype._mouseDown.call(this, event);
return;
}
if (!this._triggerTimeout)
this._triggerTimeout = setTimeout(this._trigger.bind(this, event), 200);
},
/**
* @param {!Event} event
*/
_trigger: function(event)
{
delete this._triggerTimeout;
var contextMenu = new WebInspector.ContextMenu(event,
this._useSoftMenu,
this.element.totalOffsetLeft(),
this.element.totalOffsetTop() + this.element.offsetHeight);
this._contextMenuHandler(contextMenu);
contextMenu.show();
},
/**
* @override
* @param {!Event} event
*/
_clicked: function(event)
{
if (!this._triggerTimeout)
return;
clearTimeout(this._triggerTimeout);
this._trigger(event);
},
__proto__: WebInspector.ToolbarButton.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarToggle}
* @param {!WebInspector.Setting} setting
* @param {string} glyph
* @param {string} title
* @param {string=} toggledTitle
*/
WebInspector.ToolbarSettingToggle = function(setting, glyph, title, toggledTitle)
{
WebInspector.ToolbarToggle.call(this, title, glyph);
this._defaultTitle = title;
this._toggledTitle = toggledTitle || title;
this._setting = setting;
this._settingChanged();
this._setting.addChangeListener(this._settingChanged, this);
}
WebInspector.ToolbarSettingToggle.prototype = {
_settingChanged: function()
{
var toggled = this._setting.get();
this.setToggled(toggled);
this.setTitle(toggled ? this._toggledTitle : this._defaultTitle);
},
/**
* @override
* @param {!Event} event
*/
_clicked: function(event)
{
this._setting.set(!this.toggled());
WebInspector.ToolbarToggle.prototype._clicked.call(this, event);
},
__proto__: WebInspector.ToolbarToggle.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {boolean=} spacer
*/
WebInspector.ToolbarSeparator = function(spacer)
{
WebInspector.ToolbarItem.call(this, createElementWithClass("div", spacer ? "toolbar-spacer" : "toolbar-divider"));
}
WebInspector.ToolbarSeparator.prototype = {
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @interface
*/
WebInspector.ToolbarItem.Provider = function()
{
}
WebInspector.ToolbarItem.Provider.prototype = {
/**
* @return {?WebInspector.ToolbarItem}
*/
item: function() {}
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {?function(!Event)} changeHandler
* @param {string=} className
*/
WebInspector.ToolbarComboBox = function(changeHandler, className)
{
WebInspector.ToolbarItem.call(this, createElementWithClass("span", "toolbar-select-container"));
this._selectElement = this.element.createChild("select", "toolbar-item");
this.element.createChild("div", "toolbar-dropdown-arrow");
if (changeHandler)
this._selectElement.addEventListener("change", changeHandler, false);
if (className)
this._selectElement.classList.add(className);
}
WebInspector.ToolbarComboBox.prototype = {
/**
* @return {!HTMLSelectElement}
*/
selectElement: function()
{
return /** @type {!HTMLSelectElement} */ (this._selectElement);
},
/**
* @return {number}
*/
size: function()
{
return this._selectElement.childElementCount;
},
/**
* @return {!Array.<!Element>}
*/
options: function()
{
return Array.prototype.slice.call(this._selectElement.children, 0);
},
/**
* @param {!Element} option
*/
addOption: function(option)
{
this._selectElement.appendChild(option);
},
/**
* @param {string} label
* @param {string=} title
* @param {string=} value
* @return {!Element}
*/
createOption: function(label, title, value)
{
var option = this._selectElement.createChild("option");
option.text = label;
if (title)
option.title = title;
if (typeof value !== "undefined")
option.value = value;
return option;
},
/**
* @override
*/
_applyEnabledState: function()
{
this._selectElement.disabled = !this._enabled;
},
/**
* @param {!Element} option
*/
removeOption: function(option)
{
this._selectElement.removeChild(option);
},
removeOptions: function()
{
this._selectElement.removeChildren();
},
/**
* @return {?Element}
*/
selectedOption: function()
{
if (this._selectElement.selectedIndex >= 0)
return this._selectElement[this._selectElement.selectedIndex];
return null;
},
/**
* @param {!Element} option
*/
select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
},
/**
* @param {number} index
*/
setSelectedIndex: function(index)
{
this._selectElement.selectedIndex = index;
},
/**
* @return {number}
*/
selectedIndex: function()
{
return this._selectElement.selectedIndex;
},
/**
* @param {number} width
*/
setMaxWidth: function(width)
{
this._selectElement.style.maxWidth = width + "px";
},
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
* @param {string} text
* @param {string=} title
* @param {!WebInspector.Setting=} setting
*/
WebInspector.ToolbarCheckbox = function(text, title, setting)
{
WebInspector.ToolbarItem.call(this, createCheckboxLabel(text));
this.element.classList.add("checkbox");
this.inputElement = this.element.checkboxElement;
if (title)
this.element.title = title;
if (setting)
WebInspector.SettingsUI.bindCheckbox(this.inputElement, setting);
}
WebInspector.ToolbarCheckbox.prototype = {
/**
* @return {boolean}
*/
checked: function()
{
return this.inputElement.checked;
},
__proto__: WebInspector.ToolbarItem.prototype
}
/**
* @constructor
* @extends {WebInspector.Toolbar}
* @param {string} location
* @param {!Element=} parentElement
*/
WebInspector.ExtensibleToolbar = function(location, parentElement)
{
WebInspector.Toolbar.call(this, "", parentElement);
this._loadItems(location);
}
WebInspector.ExtensibleToolbar.prototype = {
/**
* @param {string} location
*/
_loadItems: function(location)
{
var extensions = self.runtime.extensions(WebInspector.ToolbarItem.Provider);
var promises = [];
for (var i = 0; i < extensions.length; ++i) {
if (extensions[i].descriptor()["location"] === location)
promises.push(resolveItem(extensions[i]));
}
this._promise = Promise.all(promises).then(appendItemsInOrder.bind(this));
/**
* @param {!Runtime.Extension} extension
* @return {!Promise.<?WebInspector.ToolbarItem>}
*/
function resolveItem(extension)
{
var descriptor = extension.descriptor();
if (descriptor["separator"])
return Promise.resolve(/** @type {?WebInspector.ToolbarItem} */(new WebInspector.ToolbarSeparator()));
if (descriptor["actionId"])
return Promise.resolve(/** @type {?WebInspector.ToolbarItem} */(WebInspector.Toolbar.createActionButton(WebInspector.actionRegistry.action(descriptor["actionId"]))));
return extension.instancePromise().then(fetchItemFromProvider);
/**
* @param {!Object} provider
*/
function fetchItemFromProvider(provider)
{
return /** @type {!WebInspector.ToolbarItem.Provider} */ (provider).item();
}
}
/**
* @param {!Array.<?WebInspector.ToolbarItem>} items
* @this {WebInspector.ExtensibleToolbar}
*/
function appendItemsInOrder(items)
{
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item)
this.appendToolbarItem(item);
}
}
},
/**
* @return {!Promise}
*/
onLoad: function()
{
return this._promise;
},
__proto__: WebInspector.Toolbar.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 2 | // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!Document} doc
*/
WebInspector.Tooltip = function(doc)
{
this.element = doc.body.createChild("div");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/tooltip.css");
this._tooltipElement = this._shadowRoot.createChild("div", "tooltip");
doc.addEventListener("mousemove", this._mouseMove.bind(this), true);
doc.addEventListener("mousedown", this._hide.bind(this, true), true);
doc.addEventListener("mouseleave", this._hide.bind(this, false), true);
doc.addEventListener("keydown", this._hide.bind(this, true), true);
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._reset, this);
doc.defaultView.addEventListener("resize", this._reset.bind(this), false);
}
WebInspector.Tooltip.Timing = {
// Max time between tooltips showing that no opening delay is required.
"InstantThreshold": 300,
// Wait time before opening a tooltip.
"OpeningDelay": 600
}
WebInspector.Tooltip.prototype = {
/**
* @param {!Event} event
*/
_mouseMove: function(event)
{
var path = event.path;
if (!path || event.buttons !== 0)
return;
if (this._anchorElement && path.indexOf(this._anchorElement) === -1)
this._hide(false);
for (var element of path) {
if (element === this._anchorElement) {
return;
} else if (element[WebInspector.Tooltip._symbol]) {
this._show(element, event);
return;
}
}
},
/**
* @param {!Element} anchorElement
* @param {!Event} event
*/
_show: function(anchorElement, event)
{
var tooltip = anchorElement[WebInspector.Tooltip._symbol];
this._anchorElement = anchorElement;
this._tooltipElement.removeChildren();
// Check if native tooltips should be used.
for (var element of WebInspector.Tooltip._nativeOverrideContainer) {
if (this._anchorElement.isSelfOrDescendant(element)) {
Object.defineProperty(this._anchorElement, "title", WebInspector.Tooltip._nativeTitle);
this._anchorElement.title = tooltip.content;
return;
}
}
if (typeof tooltip.content === "string")
this._tooltipElement.setTextContentTruncatedIfNeeded(tooltip.content);
else
this._tooltipElement.appendChild(tooltip.content);
if (tooltip.actionId) {
var shortcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction(tooltip.actionId);
for (var shortcut of shortcuts) {
var shortcutElement = this._tooltipElement.createChild("div", "tooltip-shortcut");
shortcutElement.textContent = shortcut.name;
}
}
this._tooltipElement.classList.add("shown");
// Reposition to ensure text doesn't overflow unnecessarily.
this._tooltipElement.positionAt(0, 0);
// Show tooltip instantly if a tooltip was shown recently.
var now = Date.now();
var instant = (this._tooltipLastClosed && now - this._tooltipLastClosed < WebInspector.Tooltip.Timing.InstantThreshold);
this._tooltipElement.classList.toggle("instant", instant);
this._tooltipLastOpened = instant ? now : now + WebInspector.Tooltip.Timing.OpeningDelay;
// Get container element.
var container = WebInspector.Dialog.modalHostView().element;
if (!anchorElement.isDescendant(container))
container = this.element.parentElement;
// Posititon tooltip based on the anchor element.
var containerOffset = container.offsetRelativeToWindow(this.element.window());
var containerOffsetWidth = container.offsetWidth;
var containerOffsetHeight = container.offsetHeight;
var anchorBox = this._anchorElement.boxInWindow(this.element.window());
const anchorOffset = 2;
const pageMargin = 2;
var cursorOffset = 10;
this._tooltipElement.style.maxWidth = (containerOffsetWidth - pageMargin * 2) + "px";
this._tooltipElement.style.maxHeight = "";
var tooltipWidth = this._tooltipElement.offsetWidth;
var tooltipHeight = this._tooltipElement.offsetHeight;
var anchorTooltipAtElement = this._anchorElement.nodeName === "BUTTON" || this._anchorElement.nodeName === "LABEL";
var tooltipX = anchorTooltipAtElement ? anchorBox.x : event.x + cursorOffset;
tooltipX = Number.constrain(tooltipX,
containerOffset.x + pageMargin,
containerOffset.x + containerOffsetWidth - tooltipWidth - pageMargin);
var tooltipY;
if (!anchorTooltipAtElement) {
tooltipY = event.y + cursorOffset + tooltipHeight < containerOffset.y + containerOffsetHeight ? event.y + cursorOffset : event.y - tooltipHeight;
} else {
var onBottom = anchorBox.y + anchorOffset + anchorBox.height + tooltipHeight < containerOffset.y + containerOffsetHeight;
tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset;
}
this._tooltipElement.positionAt(tooltipX, tooltipY);
},
/**
* @param {boolean} removeInstant
*/
_hide: function(removeInstant)
{
delete this._anchorElement;
this._tooltipElement.classList.remove("shown");
if (Date.now() > this._tooltipLastOpened)
this._tooltipLastClosed = Date.now();
if (removeInstant)
delete this._tooltipLastClosed;
},
_reset: function()
{
this._hide(true);
this._tooltipElement.positionAt(0, 0);
this._tooltipElement.style.maxWidth = "0";
this._tooltipElement.style.maxHeight = "0";
}
}
WebInspector.Tooltip._symbol = Symbol("Tooltip");
/**
* @param {!Document} doc
*/
WebInspector.Tooltip.installHandler = function(doc)
{
new WebInspector.Tooltip(doc);
}
/**
* @param {!Element} element
* @param {!Element|string} tooltipContent
* @param {string=} actionId
* @param {!Object=} options
*/
WebInspector.Tooltip.install = function(element, tooltipContent, actionId, options)
{
if (typeof tooltipContent === "string" && tooltipContent === "") {
delete element[WebInspector.Tooltip._symbol];
return;
}
element[WebInspector.Tooltip._symbol] = { content: tooltipContent, actionId: actionId, options: options || {} };
}
/**
* @param {!Element} element
*/
WebInspector.Tooltip.addNativeOverrideContainer = function(element)
{
WebInspector.Tooltip._nativeOverrideContainer.push(element);
}
/** @type {!Array.<!Element>} */
WebInspector.Tooltip._nativeOverrideContainer = [];
WebInspector.Tooltip._nativeTitle = /** @type {!ObjectPropertyDescriptor} */(Object.getOwnPropertyDescriptor(HTMLElement.prototype, "title"));
Object.defineProperty(HTMLElement.prototype, "title", {
/**
* @return {!Element|string}
* @this {!Element}
*/
get: function()
{
var tooltip = this[WebInspector.Tooltip._symbol];
return tooltip ? tooltip.content : "";
},
/**
* @param {!Element|string} x
* @this {!Element}
*/
set: function(x)
{
WebInspector.Tooltip.install(this, x);
}
});
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.highlightedSearchResultClassName = "highlighted-search-result";
/**
* @param {!Element} element
* @param {?function(!MouseEvent): boolean} elementDragStart
* @param {function(!MouseEvent)} elementDrag
* @param {?function(!MouseEvent)} elementDragEnd
* @param {string} cursor
* @param {?string=} hoverCursor
* @param {number=} startDelay
*/
WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor, hoverCursor, startDelay)
{
/**
* @param {!Event} event
*/
function onMouseDown(event)
{
var dragStart = WebInspector.elementDragStart.bind(WebInspector, element, elementDragStart, elementDrag, elementDragEnd, cursor, event);
if (!startDelay)
dragStart();
startTimer = setTimeout(dragStart, startDelay || 0);
}
function onMouseUp()
{
if (startTimer)
clearInterval(startTimer);
startTimer = null;
}
var startTimer;
element.addEventListener("mousedown", onMouseDown, false);
if (startDelay)
element.addEventListener("mouseup", onMouseUp, false);
if (hoverCursor !== null)
element.style.cursor = hoverCursor || cursor;
}
/**
* @param {!Element} targetElement
* @param {?function(!MouseEvent):boolean} elementDragStart
* @param {function(!MouseEvent)} elementDrag
* @param {?function(!MouseEvent)} elementDragEnd
* @param {string} cursor
* @param {!Event} event
*/
WebInspector.elementDragStart = function(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event)
{
// Only drag upon left button. Right will likely cause a context menu. So will ctrl-click on mac.
if (event.button || (WebInspector.isMac() && event.ctrlKey))
return;
if (WebInspector._elementDraggingEventListener)
return;
if (elementDragStart && !elementDragStart(/** @type {!MouseEvent} */ (event)))
return;
if (WebInspector._elementDraggingGlassPane) {
WebInspector._elementDraggingGlassPane.dispose();
delete WebInspector._elementDraggingGlassPane;
}
var targetDocument = event.target.ownerDocument;
WebInspector._elementDraggingEventListener = elementDrag;
WebInspector._elementEndDraggingEventListener = elementDragEnd;
WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument;
WebInspector._dragEventsTargetDocument = targetDocument;
WebInspector._dragEventsTargetDocumentTop = targetDocument.defaultView.top.document;
targetDocument.addEventListener("mousemove", WebInspector._elementDragMove, true);
targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true);
targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
if (targetDocument !== WebInspector._dragEventsTargetDocumentTop)
WebInspector._dragEventsTargetDocumentTop.addEventListener("mouseup", WebInspector._elementDragEnd, true);
if (typeof cursor === "string") {
WebInspector._restoreCursorAfterDrag = restoreCursor.bind(null, targetElement.style.cursor);
targetElement.style.cursor = cursor;
targetDocument.body.style.cursor = cursor;
}
function restoreCursor(oldCursor)
{
targetDocument.body.style.removeProperty("cursor");
targetElement.style.cursor = oldCursor;
WebInspector._restoreCursorAfterDrag = null;
}
event.preventDefault();
}
WebInspector._mouseOutWhileDragging = function()
{
var document = WebInspector._mouseOutWhileDraggingTargetDocument;
WebInspector._unregisterMouseOutWhileDragging();
WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane(document);
}
WebInspector._unregisterMouseOutWhileDragging = function()
{
if (!WebInspector._mouseOutWhileDraggingTargetDocument)
return;
WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
delete WebInspector._mouseOutWhileDraggingTargetDocument;
}
WebInspector._unregisterDragEvents = function()
{
if (!WebInspector._dragEventsTargetDocument)
return;
WebInspector._dragEventsTargetDocument.removeEventListener("mousemove", WebInspector._elementDragMove, true);
WebInspector._dragEventsTargetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
if (WebInspector._dragEventsTargetDocument !== WebInspector._dragEventsTargetDocumentTop)
WebInspector._dragEventsTargetDocumentTop.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
delete WebInspector._dragEventsTargetDocument;
delete WebInspector._dragEventsTargetDocumentTop;
}
/**
* @param {!Event} event
*/
WebInspector._elementDragMove = function(event)
{
if (event.buttons !== 1) {
WebInspector._elementDragEnd(event);
return;
}
if (WebInspector._elementDraggingEventListener(/** @type {!MouseEvent} */ (event)))
WebInspector._cancelDragEvents(event);
}
/**
* @param {!Event} event
*/
WebInspector._cancelDragEvents = function(event)
{
WebInspector._unregisterDragEvents();
WebInspector._unregisterMouseOutWhileDragging();
if (WebInspector._restoreCursorAfterDrag)
WebInspector._restoreCursorAfterDrag();
if (WebInspector._elementDraggingGlassPane)
WebInspector._elementDraggingGlassPane.dispose();
delete WebInspector._elementDraggingGlassPane;
delete WebInspector._elementDraggingEventListener;
delete WebInspector._elementEndDraggingEventListener;
}
/**
* @param {!Event} event
*/
WebInspector._elementDragEnd = function(event)
{
var elementDragEnd = WebInspector._elementEndDraggingEventListener;
WebInspector._cancelDragEvents(/** @type {!MouseEvent} */ (event));
event.preventDefault();
if (elementDragEnd)
elementDragEnd(/** @type {!MouseEvent} */ (event));
}
/**
* @constructor
* @param {!Document} document
* @param {boolean=} dimmed
*/
WebInspector.GlassPane = function(document, dimmed)
{
this.element = createElement("div");
var background = dimmed ? "rgba(255, 255, 255, 0.5)" : "transparent";
this._zIndex = WebInspector._glassPane ? WebInspector._glassPane._zIndex + 1000 : 3000; // Deliberately starts with 3000 to hide other z-indexed elements below.
this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:" + background + ";z-index:" + this._zIndex + ";overflow:hidden;";
document.body.appendChild(this.element);
WebInspector._glassPane = this;
}
WebInspector.GlassPane.prototype = {
dispose: function()
{
delete WebInspector._glassPane;
if (WebInspector.GlassPane.DefaultFocusedViewStack.length)
WebInspector.GlassPane.DefaultFocusedViewStack.peekLast().focus();
this.element.remove();
}
}
/** @type {!WebInspector.GlassPane|undefined} */
WebInspector._glassPane;
/**
* @type {!Array.<!WebInspector.Widget|!WebInspector.Dialog>}
*/
WebInspector.GlassPane.DefaultFocusedViewStack = [];
/**
* @param {?Node=} node
* @return {boolean}
*/
WebInspector.isBeingEdited = function(node)
{
if (!node || node.nodeType !== Node.ELEMENT_NODE)
return false;
var element = /** {!Element} */ (node);
if (element.classList.contains("text-prompt") || element.nodeName === "INPUT" || element.nodeName === "TEXTAREA")
return true;
if (!WebInspector.__editingCount)
return false;
while (element) {
if (element.__editing)
return true;
element = element.parentElementOrShadowHost();
}
return false;
}
/**
* @return {boolean}
*/
WebInspector.isEditing = function()
{
if (WebInspector.__editingCount)
return true;
var element = WebInspector.currentFocusElement();
if (!element)
return false;
return element.classList.contains("text-prompt") || element.nodeName === "INPUT" || element.nodeName === "TEXTAREA";
}
/**
* @param {!Element} element
* @param {boolean} value
* @return {boolean}
*/
WebInspector.markBeingEdited = function(element, value)
{
if (value) {
if (element.__editing)
return false;
element.classList.add("being-edited");
element.__editing = true;
WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
} else {
if (!element.__editing)
return false;
element.classList.remove("being-edited");
delete element.__editing;
--WebInspector.__editingCount;
}
return true;
}
WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;
WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";
/**
* @param {!Event} event
* @return {?string}
*/
WebInspector._valueModificationDirection = function(event)
{
var direction = null;
if (event.type === "mousewheel") {
if (event.wheelDeltaY > 0)
direction = "Up";
else if (event.wheelDeltaY < 0)
direction = "Down";
} else {
if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
direction = "Up";
else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
direction = "Down";
}
return direction;
}
/**
* @param {string} hexString
* @param {!Event} event
*/
WebInspector._modifiedHexValue = function(hexString, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return hexString;
var number = parseInt(hexString, 16);
if (isNaN(number) || !isFinite(number))
return hexString;
var maxValue = Math.pow(16, hexString.length) - 1;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var delta;
if (arrowKeyOrMouseWheelEvent)
delta = (direction === "Up") ? 1 : -1;
else
delta = (event.keyIdentifier === "PageUp") ? 16 : -16;
if (event.shiftKey)
delta *= 16;
var result = number + delta;
if (result < 0)
result = 0; // Color hex values are never negative, so clamp to 0.
else if (result > maxValue)
return hexString;
// Ensure the result length is the same as the original hex value.
var resultString = result.toString(16).toUpperCase();
for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
resultString = "0" + resultString;
return resultString;
}
/**
* @param {number} number
* @param {!Event} event
*/
WebInspector._modifiedFloatNumber = function(number, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return number;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
// Jump by 10 when shift is down or jump by 0.1 when Alt/Option is down.
// Also jump by 10 for page up and down, or by 100 if shift is held with a page key.
var changeAmount = 1;
if (event.shiftKey && !arrowKeyOrMouseWheelEvent)
changeAmount = 100;
else if (event.shiftKey || !arrowKeyOrMouseWheelEvent)
changeAmount = 10;
else if (event.altKey)
changeAmount = 0.1;
if (direction === "Down")
changeAmount *= -1;
// Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
// Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
var result = Number((number + changeAmount).toFixed(6));
if (!String(result).match(WebInspector.CSSNumberRegex))
return null;
return result;
}
/**
* @param {string} wordString
* @param {!Event} event
* @param {function(string, number, string):string=} customNumberHandler
* @return {?string}
*/
WebInspector.createReplacementString = function(wordString, event, customNumberHandler)
{
var replacementString;
var prefix, suffix, number;
var matches;
matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedHexValue(matches[2], event);
replacementString = customNumberHandler ? customNumberHandler(prefix, number, suffix) : prefix + number + suffix;
} else {
matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);
// Need to check for null explicitly.
if (number === null)
return null;
replacementString = customNumberHandler ? customNumberHandler(prefix, number, suffix) : prefix + number + suffix;
}
}
return replacementString || null;
}
/**
* @param {!Event} event
* @param {!Element} element
* @param {function(string,string)=} finishHandler
* @param {function(string)=} suggestionHandler
* @param {function(string, number, string):string=} customNumberHandler
* @return {boolean}
*/
WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler)
{
/**
* @return {?Range}
* @suppressGlobalPropertiesCheck
*/
function createRange()
{
return document.createRange();
}
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
return false;
var selection = element.getComponentSelection();
if (!selection.rangeCount)
return false;
var selectionRange = selection.getRangeAt(0);
if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
return false;
var originalValue = element.textContent;
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
var wordString = wordRange.toString();
if (suggestionHandler && suggestionHandler(wordString))
return false;
var replacementString = WebInspector.createReplacementString(wordString, event, customNumberHandler);
if (replacementString) {
var replacementTextNode = createTextNode(replacementString);
wordRange.deleteContents();
wordRange.insertNode(replacementTextNode);
var finalSelectionRange = createRange();
finalSelectionRange.setStart(replacementTextNode, 0);
finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
event.handled = true;
event.preventDefault();
if (finishHandler)
finishHandler(originalValue, replacementString);
return true;
}
return false;
}
/**
* @param {number} ms
* @param {number=} precision
* @return {string}
*/
Number.preciseMillisToString = function(ms, precision)
{
precision = precision || 0;
var format = "%." + precision + "f\u2009ms";
return WebInspector.UIString(format, ms);
}
/** @type {!WebInspector.UIStringFormat} */
WebInspector._subMillisFormat = new WebInspector.UIStringFormat("%.2f\u2009ms");
/** @type {!WebInspector.UIStringFormat} */
WebInspector._millisFormat = new WebInspector.UIStringFormat("%.0f\u2009ms");
/** @type {!WebInspector.UIStringFormat} */
WebInspector._secondsFormat = new WebInspector.UIStringFormat("%.2f\u2009s");
/** @type {!WebInspector.UIStringFormat} */
WebInspector._minutesFormat = new WebInspector.UIStringFormat("%.1f\u2009min");
/** @type {!WebInspector.UIStringFormat} */
WebInspector._hoursFormat = new WebInspector.UIStringFormat("%.1f\u2009hrs");
/** @type {!WebInspector.UIStringFormat} */
WebInspector._daysFormat = new WebInspector.UIStringFormat("%.1f\u2009days");
/**
* @param {number} ms
* @param {boolean=} higherResolution
* @return {string}
*/
Number.millisToString = function(ms, higherResolution)
{
if (!isFinite(ms))
return "-";
if (ms === 0)
return "0";
if (higherResolution && ms < 1000)
return WebInspector._subMillisFormat.format(ms);
else if (ms < 1000)
return WebInspector._millisFormat.format(ms);
var seconds = ms / 1000;
if (seconds < 60)
return WebInspector._secondsFormat.format(seconds);
var minutes = seconds / 60;
if (minutes < 60)
return WebInspector._minutesFormat.format(minutes);
var hours = minutes / 60;
if (hours < 24)
return WebInspector._hoursFormat.format(hours);
var days = hours / 24;
return WebInspector._daysFormat.format(days);
}
/**
* @param {number} seconds
* @param {boolean=} higherResolution
* @return {string}
*/
Number.secondsToString = function(seconds, higherResolution)
{
if (!isFinite(seconds))
return "-";
return Number.millisToString(seconds * 1000, higherResolution);
}
/**
* @param {number} bytes
* @return {string}
*/
Number.bytesToString = function(bytes)
{
if (bytes < 1024)
return WebInspector.UIString("%.0f\u2009B", bytes);
var kilobytes = bytes / 1024;
if (kilobytes < 100)
return WebInspector.UIString("%.1f\u2009KB", kilobytes);
if (kilobytes < 1024)
return WebInspector.UIString("%.0f\u2009KB", kilobytes);
var megabytes = kilobytes / 1024;
if (megabytes < 100)
return WebInspector.UIString("%.1f\u2009MB", megabytes);
else
return WebInspector.UIString("%.0f\u2009MB", megabytes);
}
/**
* @param {number} num
* @return {string}
*/
Number.withThousandsSeparator = function(num)
{
var str = num + "";
var re = /(\d+)(\d{3})/;
while (str.match(re))
str = str.replace(re, "$1\u2009$2"); // \u2009 is a thin space.
return str;
}
/**
* @param {string} format
* @param {?ArrayLike} substitutions
* @return {!Element}
*/
WebInspector.formatLocalized = function(format, substitutions)
{
var formatters = {
s: substitution => substitution
};
/**
* @param {!Element} a
* @param {string|!Element} b
* @return {!Element}
*/
function append(a, b)
{
a.appendChild(typeof b === "string" ? createTextNode(b) : b);
return a;
}
return String.format(WebInspector.UIString(format), substitutions, formatters, createElement("span"), append).formattedResult;
}
/**
* @return {string}
*/
WebInspector.openLinkExternallyLabel = function()
{
return WebInspector.UIString.capitalize("Open ^link in ^new ^tab");
}
/**
* @return {string}
*/
WebInspector.copyLinkAddressLabel = function()
{
return WebInspector.UIString.capitalize("Copy ^link ^address");
}
/**
* @return {string}
*/
WebInspector.anotherProfilerActiveLabel = function()
{
return WebInspector.UIString("Another profiler is already active");
}
/**
* @param {string|undefined} description
* @return {string}
*/
WebInspector.asyncStackTraceLabel = function(description)
{
if (description)
return description + " " + WebInspector.UIString("(async)");
return WebInspector.UIString("Async Call");
}
/**
* @return {string}
*/
WebInspector.manageBlackboxingSettingsTabLabel = function()
{
return WebInspector.UIString("Blackboxing");
}
/**
* @param {!Element} element
*/
WebInspector.installComponentRootStyles = function(element)
{
WebInspector.appendStyle(element, "ui/inspectorCommon.css");
WebInspector.themeSupport.injectHighlightStyleSheets(element);
element.classList.add("platform-" + WebInspector.platform());
}
/**
* @param {!Element} element
* @param {string=} cssFile
* @return {!DocumentFragment}
*/
WebInspector.createShadowRootWithCoreStyles = function(element, cssFile)
{
var shadowRoot = element.createShadowRoot();
WebInspector.appendStyle(shadowRoot, "ui/inspectorCommon.css");
WebInspector.themeSupport.injectHighlightStyleSheets(shadowRoot);
if (cssFile)
WebInspector.appendStyle(shadowRoot, cssFile);
shadowRoot.addEventListener("focus", WebInspector._focusChanged.bind(WebInspector), true);
return shadowRoot;
}
/**
* @param {!Document} document
* @param {!Event} event
*/
WebInspector._windowFocused = function(document, event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.classList.remove("inactive");
}
/**
* @param {!Document} document
* @param {!Event} event
*/
WebInspector._windowBlurred = function(document, event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.classList.add("inactive");
}
/**
* @return {!Element}
*/
WebInspector.previousFocusElement = function()
{
return WebInspector._previousFocusElement;
}
/**
* @return {!Element}
*/
WebInspector.currentFocusElement = function()
{
return WebInspector._currentFocusElement;
}
/**
* @param {!Event} event
*/
WebInspector._focusChanged = function(event)
{
var node = event.deepActiveElement();
WebInspector.setCurrentFocusElement(node);
}
/**
* @param {!Document} document
* @param {!Event} event
*/
WebInspector._documentBlurred = function(document, event)
{
// We want to know when currentFocusElement loses focus to nowhere.
// This is the case when event.relatedTarget is null (no element is being focused)
// and document.activeElement is reset to default (this is not a window blur).
if (!event.relatedTarget && document.activeElement === document.body)
WebInspector.setCurrentFocusElement(null);
}
WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet();
WebInspector._isTextEditingElement = function(element)
{
if (element instanceof HTMLInputElement)
return element.type in WebInspector._textInputTypes;
if (element instanceof HTMLTextAreaElement)
return true;
return false;
}
/**
* @param {?Node} x
*/
WebInspector.setCurrentFocusElement = function(x)
{
if (WebInspector._glassPane && x && !WebInspector._glassPane.element.isAncestor(x))
return;
if (WebInspector._currentFocusElement !== x)
WebInspector._previousFocusElement = WebInspector._currentFocusElement;
WebInspector._currentFocusElement = x;
if (x) {
x.focus();
// Make a caret selection inside the new element if there isn't a range selection and there isn't already a caret selection inside.
// This is needed (at least) to remove caret from console when focus is moved to some element in the panel.
// The code below should not be applied to text fields and text areas, hence _isTextEditingElement check.
var selection = x.getComponentSelection();
if (!WebInspector._isTextEditingElement(x) && selection.isCollapsed && !x.isInsertionCaretInside()) {
var selectionRange = x.ownerDocument.createRange();
selectionRange.setStart(x, 0);
selectionRange.setEnd(x, 0);
selection.removeAllRanges();
selection.addRange(selectionRange);
}
} else if (WebInspector._previousFocusElement)
WebInspector._previousFocusElement.blur();
}
WebInspector.restoreFocusFromElement = function(element)
{
if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
}
/**
* @param {!Element} element
* @param {number} offset
* @param {number} length
* @param {!Array.<!Object>=} domChanges
* @return {?Element}
*/
WebInspector.highlightSearchResult = function(element, offset, length, domChanges)
{
var result = WebInspector.highlightSearchResults(element, [new WebInspector.SourceRange(offset, length)], domChanges);
return result.length ? result[0] : null;
}
/**
* @param {!Element} element
* @param {!Array.<!WebInspector.SourceRange>} resultRanges
* @param {!Array.<!Object>=} changes
* @return {!Array.<!Element>}
*/
WebInspector.highlightSearchResults = function(element, resultRanges, changes)
{
return WebInspector.highlightRangesWithStyleClass(element, resultRanges, WebInspector.highlightedSearchResultClassName, changes);
}
/**
* @param {!Element} element
* @param {string} className
*/
WebInspector.runCSSAnimationOnce = function(element, className)
{
function animationEndCallback()
{
element.classList.remove(className);
element.removeEventListener("webkitAnimationEnd", animationEndCallback, false);
}
if (element.classList.contains(className))
element.classList.remove(className);
element.addEventListener("webkitAnimationEnd", animationEndCallback, false);
element.classList.add(className);
}
/**
* @param {!Element} element
* @param {!Array.<!WebInspector.SourceRange>} resultRanges
* @param {string} styleClass
* @param {!Array.<!Object>=} changes
* @return {!Array.<!Element>}
*/
WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
changes = changes || [];
var highlightNodes = [];
var textNodes = element.childTextNodes();
var lineText = textNodes.map(function (node) { return node.textContent; }).join("");
var ownerDocument = element.ownerDocument;
if (textNodes.length === 0)
return highlightNodes;
var nodeRanges = [];
var rangeEndOffset = 0;
for (var i = 0; i < textNodes.length; ++i) {
var range = {};
range.offset = rangeEndOffset;
range.length = textNodes[i].textContent.length;
rangeEndOffset = range.offset + range.length;
nodeRanges.push(range);
}
var startIndex = 0;
for (var i = 0; i < resultRanges.length; ++i) {
var startOffset = resultRanges[i].offset;
var endOffset = startOffset + resultRanges[i].length;
while (startIndex < textNodes.length && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
startIndex++;
var endIndex = startIndex;
while (endIndex < textNodes.length && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
endIndex++;
if (endIndex === textNodes.length)
break;
var highlightNode = ownerDocument.createElement("span");
highlightNode.className = styleClass;
highlightNode.textContent = lineText.substring(startOffset, endOffset);
var lastTextNode = textNodes[endIndex];
var lastText = lastTextNode.textContent;
lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });
if (startIndex === endIndex) {
lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
highlightNodes.push(highlightNode);
var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
} else {
var firstTextNode = textNodes[startIndex];
var firstText = firstTextNode.textContent;
var anchorElement = firstTextNode.nextSibling;
firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
highlightNodes.push(highlightNode);
firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });
for (var j = startIndex + 1; j < endIndex; j++) {
var textNode = textNodes[j];
var text = textNode.textContent;
textNode.textContent = "";
changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
}
}
startIndex = endIndex;
nodeRanges[startIndex].offset = endOffset;
nodeRanges[startIndex].length = lastTextNode.textContent.length;
}
return highlightNodes;
}
WebInspector.applyDomChanges = function(domChanges)
{
for (var i = 0, size = domChanges.length; i < size; ++i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}
}
WebInspector.revertDomChanges = function(domChanges)
{
for (var i = domChanges.length - 1; i >= 0; --i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
entry.node.remove();
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
}
/**
* @param {!Element} element
* @param {?Element=} containerElement
* @return {!Size}
*/
WebInspector.measurePreferredSize = function(element, containerElement)
{
containerElement = containerElement || element.ownerDocument.body;
containerElement.appendChild(element);
element.positionAt(0, 0);
var result = new Size(element.offsetWidth, element.offsetHeight);
element.positionAt(undefined, undefined);
element.remove();
return result;
}
/**
* @constructor
* @param {boolean} autoInvoke
*/
WebInspector.InvokeOnceHandlers = function(autoInvoke)
{
this._handlers = null;
this._autoInvoke = autoInvoke;
}
WebInspector.InvokeOnceHandlers.prototype = {
/**
* @param {!Object} object
* @param {function()} method
*/
add: function(object, method)
{
if (!this._handlers) {
this._handlers = new Map();
if (this._autoInvoke)
this.scheduleInvoke();
}
var methods = this._handlers.get(object);
if (!methods) {
methods = new Set();
this._handlers.set(object, methods);
}
methods.add(method);
},
/**
* @suppressGlobalPropertiesCheck
*/
scheduleInvoke: function()
{
if (this._handlers)
requestAnimationFrame(this._invoke.bind(this));
},
_invoke: function()
{
var handlers = this._handlers;
this._handlers = null;
var keys = handlers.keysArray();
for (var i = 0; i < keys.length; ++i) {
var object = keys[i];
var methods = handlers.get(object).valuesArray();
for (var j = 0; j < methods.length; ++j)
methods[j].call(object);
}
}
}
WebInspector._coalescingLevel = 0;
WebInspector._postUpdateHandlers = null;
WebInspector.startBatchUpdate = function()
{
if (!WebInspector._coalescingLevel++)
WebInspector._postUpdateHandlers = new WebInspector.InvokeOnceHandlers(false);
}
WebInspector.endBatchUpdate = function()
{
if (--WebInspector._coalescingLevel)
return;
WebInspector._postUpdateHandlers.scheduleInvoke();
WebInspector._postUpdateHandlers = null;
}
/**
* @param {!Object} object
* @param {function()} method
*/
WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
{
if (!WebInspector._postUpdateHandlers)
WebInspector._postUpdateHandlers = new WebInspector.InvokeOnceHandlers(true);
WebInspector._postUpdateHandlers.add(object, method);
}
/**
* @param {!Window} window
* @param {!Function} func
* @param {!Array.<{from:number, to:number}>} params
* @param {number} frames
* @param {function()=} animationComplete
* @return {function()}
*/
WebInspector.animateFunction = function(window, func, params, frames, animationComplete)
{
var values = new Array(params.length);
var deltas = new Array(params.length);
for (var i = 0; i < params.length; ++i) {
values[i] = params[i].from;
deltas[i] = (params[i].to - params[i].from) / frames;
}
var raf = window.requestAnimationFrame(animationStep);
var framesLeft = frames;
function animationStep()
{
if (--framesLeft < 0) {
if (animationComplete)
animationComplete();
return;
}
for (var i = 0; i < params.length; ++i) {
if (params[i].to > params[i].from)
values[i] = Number.constrain(values[i] + deltas[i], params[i].from, params[i].to);
else
values[i] = Number.constrain(values[i] + deltas[i], params[i].to, params[i].from);
}
func.apply(null, values);
raf = window.requestAnimationFrame(animationStep);
}
function cancelAnimation()
{
window.cancelAnimationFrame(raf);
}
return cancelAnimation;
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Element} element
* @param {function(!Event)} callback
*/
WebInspector.LongClickController = function(element, callback)
{
this._element = element;
this._callback = callback;
this._enable();
}
WebInspector.LongClickController.prototype = {
reset: function()
{
if (this._longClickInterval) {
clearInterval(this._longClickInterval);
delete this._longClickInterval;
}
},
_enable: function()
{
if (this._longClickData)
return;
var boundMouseDown = mouseDown.bind(this);
var boundMouseUp = mouseUp.bind(this);
var boundReset = this.reset.bind(this);
this._element.addEventListener("mousedown", boundMouseDown, false);
this._element.addEventListener("mouseout", boundReset, false);
this._element.addEventListener("mouseup", boundMouseUp, false);
this._element.addEventListener("click", boundReset, true);
this._longClickData = { mouseUp: boundMouseUp, mouseDown: boundMouseDown, reset: boundReset };
/**
* @param {!Event} e
* @this {WebInspector.LongClickController}
*/
function mouseDown(e)
{
if (e.which !== 1)
return;
var callback = this._callback;
this._longClickInterval = setTimeout(callback.bind(null, e), 200);
}
/**
* @param {!Event} e
* @this {WebInspector.LongClickController}
*/
function mouseUp(e)
{
if (e.which !== 1)
return;
this.reset();
}
},
dispose: function()
{
if (!this._longClickData)
return;
this._element.removeEventListener("mousedown", this._longClickData.mouseDown, false);
this._element.removeEventListener("mouseout", this._longClickData.reset, false);
this._element.removeEventListener("mouseup", this._longClickData.mouseUp, false);
this._element.addEventListener("click", this._longClickData.reset, true);
delete this._longClickData;
},
__proto__: WebInspector.Object.prototype
}
/**
* @param {!Document} document
* @param {!WebInspector.Setting} themeSetting
*/
WebInspector.initializeUIUtils = function(document, themeSetting)
{
document.defaultView.addEventListener("focus", WebInspector._windowFocused.bind(WebInspector, document), false);
document.defaultView.addEventListener("blur", WebInspector._windowBlurred.bind(WebInspector, document), false);
document.addEventListener("focus", WebInspector._focusChanged.bind(WebInspector), true);
document.addEventListener("blur", WebInspector._documentBlurred.bind(WebInspector, document), true);
if (!WebInspector.themeSupport)
WebInspector.themeSupport = new WebInspector.ThemeSupport(themeSetting);
WebInspector.themeSupport.applyTheme(document);
var body = /** @type {!Element} */ (document.body);
WebInspector.appendStyle(body, "ui/inspectorStyle.css");
WebInspector.appendStyle(body, "ui/popover.css");
WebInspector.appendStyle(body, "ui/sidebarPane.css");
}
/**
* @param {string} name
* @return {string}
*/
WebInspector.beautifyFunctionName = function(name)
{
return name || WebInspector.UIString("(anonymous function)");
}
/**
* @param {string} localName
* @param {string} typeExtension
* @param {!Object} prototype
* @return {function()}
* @suppressGlobalPropertiesCheck
* @template T
*/
function registerCustomElement(localName, typeExtension, prototype)
{
return document.registerElement(typeExtension, {
prototype: Object.create(prototype),
extends: localName
});
}
/**
* @param {string} text
* @param {function(!Event)=} clickHandler
* @param {string=} className
* @param {string=} title
* @return {!Element}
*/
function createTextButton(text, clickHandler, className, title)
{
var element = createElementWithClass("button", className || "", "text-button");
element.textContent = text;
if (clickHandler)
element.addEventListener("click", clickHandler, false);
if (title)
element.title = title;
return element;
}
/**
* @param {string} name
* @param {string} title
* @param {boolean=} checked
* @return {!Element}
*/
function createRadioLabel(name, title, checked)
{
var element = createElement("label", "dt-radio");
element.radioElement.name = name;
element.radioElement.checked = !!checked;
element.createTextChild(title);
return element;
}
/**
* @param {string=} title
* @param {boolean=} checked
* @return {!Element}
*/
function createCheckboxLabel(title, checked)
{
var element = createElement("label", "dt-checkbox");
element.checkboxElement.checked = !!checked;
if (title !== undefined) {
element.textElement = element.createChild("div", "dt-checkbox-text");
element.textElement.textContent = title;
}
return element;
}
/**
* @param {!Node} node
* @param {string} cssFile
* @suppressGlobalPropertiesCheck
*/
WebInspector.appendStyle = function(node, cssFile)
{
var content = Runtime.cachedResources[cssFile] || "";
if (!content)
console.error(cssFile + " not preloaded. Check module.json");
var styleElement = createElement("style");
styleElement.type = "text/css";
styleElement.textContent = content;
node.appendChild(styleElement);
var themeStyleSheet = WebInspector.themeSupport.themeStyleSheet(cssFile, content);
if (themeStyleSheet) {
styleElement = createElement("style");
styleElement.type = "text/css";
styleElement.textContent = themeStyleSheet + "\n" + Runtime.resolveSourceURL(cssFile + ".theme");
node.appendChild(styleElement);
}
}
;(function() {
registerCustomElement("button", "text-button", {
/**
* @this {Element}
*/
createdCallback: function()
{
this.type = "button";
var root = WebInspector.createShadowRootWithCoreStyles(this, "ui/textButton.css");
root.createChild("content");
},
__proto__: HTMLButtonElement.prototype
});
registerCustomElement("label", "dt-radio", {
/**
* @this {Element}
*/
createdCallback: function()
{
this.radioElement = this.createChild("input", "dt-radio-button");
this.radioElement.type = "radio";
var root = WebInspector.createShadowRootWithCoreStyles(this, "ui/radioButton.css");
root.createChild("content").select = ".dt-radio-button";
root.createChild("content");
this.addEventListener("click", radioClickHandler, false);
},
__proto__: HTMLLabelElement.prototype
});
/**
* @param {!Event} event
* @suppressReceiverCheck
* @this {Element}
*/
function radioClickHandler(event)
{
if (this.radioElement.checked || this.radioElement.disabled)
return;
this.radioElement.checked = true;
this.radioElement.dispatchEvent(new Event("change"));
}
registerCustomElement("label", "dt-checkbox", {
/**
* @this {Element}
*/
createdCallback: function()
{
this._root = WebInspector.createShadowRootWithCoreStyles(this, "ui/checkboxTextLabel.css");
var checkboxElement = createElementWithClass("input", "dt-checkbox-button");
checkboxElement.type = "checkbox";
this._root.appendChild(checkboxElement);
this.checkboxElement = checkboxElement;
this.addEventListener("click", toggleCheckbox.bind(this));
/**
* @param {!Event} event
* @this {Node}
*/
function toggleCheckbox(event)
{
if (event.target !== checkboxElement && event.target !== this) {
event.consume();
checkboxElement.click();
}
}
this._root.createChild("content");
},
/**
* @param {string} color
* @this {Element}
*/
set backgroundColor(color)
{
this.checkboxElement.classList.add("dt-checkbox-themed");
this.checkboxElement.style.backgroundColor = color;
},
/**
* @param {string} color
* @this {Element}
*/
set checkColor(color)
{
this.checkboxElement.classList.add("dt-checkbox-themed");
var stylesheet = createElement("style");
stylesheet.textContent = "input.dt-checkbox-themed:checked:after { background-color: " + color + "}";
this._root.appendChild(stylesheet);
},
/**
* @param {string} color
* @this {Element}
*/
set borderColor(color)
{
this.checkboxElement.classList.add("dt-checkbox-themed");
this.checkboxElement.style.borderColor = color;
},
__proto__: HTMLLabelElement.prototype
});
registerCustomElement("label", "dt-icon-label", {
/**
* @this {Element}
*/
createdCallback: function()
{
var root = WebInspector.createShadowRootWithCoreStyles(this, "ui/smallIcon.css");
this._iconElement = root.createChild("div");
root.createChild("content");
},
/**
* @param {string} type
* @this {Element}
*/
set type(type)
{
this._iconElement.className = type;
},
__proto__: HTMLLabelElement.prototype
});
registerCustomElement("div", "dt-close-button", {
/**
* @this {Element}
*/
createdCallback: function()
{
var root = WebInspector.createShadowRootWithCoreStyles(this, "ui/closeButton.css");
this._buttonElement = root.createChild("div", "close-button");
},
/**
* @param {boolean} gray
* @this {Element}
*/
set gray(gray)
{
this._buttonElement.className = gray ? "close-button-gray" : "close-button";
},
__proto__: HTMLDivElement.prototype
});
})();
/**
* @param {!Element} input
* @param {function(string)} apply
* @param {function(string):boolean} validate
* @param {boolean} numeric
* @return {function(string)}
*/
WebInspector.bindInput = function(input, apply, validate, numeric)
{
input.addEventListener("change", onChange, false);
input.addEventListener("input", onInput, false);
input.addEventListener("keydown", onKeyDown, false);
input.addEventListener("focus", input.select.bind(input), false);
function onInput()
{
input.classList.toggle("error-input", !validate(input.value));
}
function onChange()
{
var valid = validate(input.value);
input.classList.toggle("error-input", !valid);
if (valid)
apply(input.value);
}
/**
* @param {!Event} event
*/
function onKeyDown(event)
{
if (isEnterKey(event)) {
if (validate(input.value))
apply(input.value);
return;
}
if (!numeric)
return;
var increment = event.keyIdentifier === "Up" ? 1 : event.keyIdentifier === "Down" ? -1 : 0;
if (!increment)
return;
if (event.shiftKey)
increment *= 10;
var value = input.value;
if (!validate(value) || !value)
return;
value = (value ? Number(value) : 0) + increment;
var stringValue = value ? String(value) : "";
if (!validate(stringValue) || !value)
return;
input.value = stringValue;
apply(input.value);
event.preventDefault();
}
/**
* @param {string} value
*/
function setValue(value)
{
if (value === input.value)
return;
var valid = validate(value);
input.classList.toggle("error-input", !valid);
input.value = value;
input.setSelectionRange(value.length, value.length);
}
return setValue;
}
/**
* @constructor
*/
WebInspector.StringFormatter = function()
{
this._processors = [];
this._regexes = [];
}
WebInspector.StringFormatter.prototype = {
/**
* @param {!RegExp} regex
* @param {function(string):!Node} handler
*/
addProcessor: function(regex, handler)
{
this._regexes.push(regex);
this._processors.push(handler);
},
/**
* @param {string} text
* @return {!Node}
*/
formatText: function(text)
{
return this._runProcessor(0, text);
},
/**
* @param {number} processorIndex
* @param {string} text
* @return {!Node}
*/
_runProcessor: function(processorIndex, text)
{
if (processorIndex >= this._processors.length)
return createTextNode(text);
var container = createDocumentFragment();
var regex = this._regexes[processorIndex];
var processor = this._processors[processorIndex];
// Due to the nature of regex, |items| array has matched elements on its even indexes.
var items = text.replace(regex, "\0$1\0").split("\0");
for (var i = 0; i < items.length; ++i) {
var processedNode = i % 2 ? processor(items[i]) : this._runProcessor(processorIndex + 1, items[i]);
container.appendChild(processedNode);
}
return container;
}
}
/**
* @constructor
* @param {!WebInspector.Setting} setting
*/
WebInspector.ThemeSupport = function(setting)
{
this._themeName = setting.get() || "default";
this._themableProperties = new Set([
"color", "box-shadow", "text-shadow", "outline-color",
"background-image", "background-color",
"border-left-color", "border-right-color", "border-top-color", "border-bottom-color",
"-webkit-border-image"]);
/** @type {!Map<string, string>} */
this._cachedThemePatches = new Map();
this._setting = setting;
}
/**
* @enum {number}
*/
WebInspector.ThemeSupport.ColorUsage = {
Unknown: 0,
Foreground: 1 << 0,
Background: 1 << 1,
Selection: 1 << 2,
};
WebInspector.ThemeSupport.prototype = {
/**
* @return {boolean}
*/
hasTheme: function()
{
return this._themeName !== "default";
},
/**
* @param {!Element} element
*/
injectHighlightStyleSheets: function(element)
{
this._injectingStyleSheet = true;
WebInspector.appendStyle(element, "ui/inspectorSyntaxHighlight.css");
if (this._themeName === "dark")
WebInspector.appendStyle(element, "ui/inspectorSyntaxHighlightDark.css");
this._injectingStyleSheet = false;
},
/**
* @param {!Document} document
*/
applyTheme: function(document)
{
if (!this.hasTheme())
return;
if (this._themeName === "dark")
document.body.classList.add("-theme-with-dark-background");
var styleSheets = document.styleSheets;
var result = [];
for (var i = 0; i < styleSheets.length; ++i)
result.push(this._patchForTheme(styleSheets[i].href, styleSheets[i]));
result.push("/*# sourceURL=inspector.css.theme */");
var styleElement = createElement("style");
styleElement.type = "text/css";
styleElement.textContent = result.join("\n");
document.head.appendChild(styleElement);
},
/**
* @param {string} id
* @param {string} text
* @return {string}
* @suppressGlobalPropertiesCheck
*/
themeStyleSheet: function(id, text)
{
if (!this.hasTheme() || this._injectingStyleSheet)
return "";
var patch = this._cachedThemePatches.get(id);
if (!patch) {
var styleElement = createElement("style");
styleElement.type = "text/css";
styleElement.textContent = text;
document.body.appendChild(styleElement);
patch = this._patchForTheme(id, styleElement.sheet);
document.body.removeChild(styleElement);
}
return patch;
},
/**
* @param {string} id
* @param {!StyleSheet} styleSheet
* @return {string}
*/
_patchForTheme: function(id, styleSheet)
{
var cached = this._cachedThemePatches.get(id);
if (cached)
return cached;
try {
var rules = styleSheet.cssRules;
var result = [];
for (var j = 0; j < rules.length; ++j) {
if (rules[j] instanceof CSSImportRule) {
result.push(this._patchForTheme(rules[j].styleSheet.href, rules[j].styleSheet));
continue;
}
var output = [];
var style = rules[j].style;
var selectorText = rules[j].selectorText;
for (var i = 0; style && i < style.length; ++i)
this._patchProperty(selectorText, style, style[i], output);
if (output.length)
result.push(rules[j].selectorText + "{" + output.join("") + "}");
}
var fullText = result.join("\n");
this._cachedThemePatches.set(id, fullText);
return fullText;
} catch(e) {
this._setting.set("default");
return "";
}
},
/**
* @param {string} selectorText
* @param {!CSSStyleDeclaration} style
* @param {string} name
* @param {!Array<string>} output
*
* Theming API is primarily targeted at making dark theme look good.
* - If rule has ".-theme-preserve" in selector, it won't be affected.
* - If rule has ".selection" or "selected" or "-theme-selection-color" in selector, its hue is rotated 180deg in dark themes.
* - One can create specializations for dark themes via body.-theme-with-dark-background selector in host context.
*/
_patchProperty: function(selectorText, style, name, output)
{
if (!this._themableProperties.has(name))
return;
var value = style.getPropertyValue(name);
if (!value || value === "none" || value === "inherit" || value === "initial" || value === "transparent")
return;
if (name === "background-image" && value.indexOf("gradient") === -1)
return;
var isSelection = selectorText.indexOf(".-theme-selection-color") !== -1;
if (selectorText.indexOf("-theme-") !== -1 && !isSelection)
return;
if (name === "-webkit-border-image") {
output.push("-webkit-filter: invert(100%)");
return;
}
isSelection = isSelection || selectorText.indexOf("selected") !== -1 || selectorText.indexOf(".selection") !== -1;
var colorUsage = WebInspector.ThemeSupport.ColorUsage.Unknown;
if (isSelection)
colorUsage |= WebInspector.ThemeSupport.ColorUsage.Selection;
if (name.indexOf("background") === 0 || name.indexOf("border") === 0)
colorUsage |= WebInspector.ThemeSupport.ColorUsage.Background;
if (name.indexOf("background") === -1)
colorUsage |= WebInspector.ThemeSupport.ColorUsage.Foreground;
var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;
output.push(name);
output.push(":");
var items = value.replace(colorRegex, "\0$1\0").split("\0");
for (var i = 0; i < items.length; ++i)
output.push(this.patchColor(items[i], colorUsage));
if (style.getPropertyPriority(name))
output.push(" !important");
output.push(";");
},
/**
* @param {string} text
* @param {!WebInspector.ThemeSupport.ColorUsage} colorUsage
* @return {string}
*/
patchColor: function(text, colorUsage)
{
var color = WebInspector.Color.parse(text);
if (!color)
return text;
var hsla = color.hsla();
this._patchHSLA(hsla, colorUsage);
var rgba = [];
WebInspector.Color.hsl2rgb(hsla, rgba);
var outColor = new WebInspector.Color(rgba, color.format());
var outText = outColor.asString(null);
if (!outText)
outText = outColor.asString(outColor.hasAlpha() ? WebInspector.Color.Format.RGBA : WebInspector.Color.Format.RGB);
return outText || text;
},
/**
* @param {!Array<number>} hsla
* @param {!WebInspector.ThemeSupport.ColorUsage} colorUsage
*/
_patchHSLA: function(hsla, colorUsage)
{
var hue = hsla[0];
var sat = hsla[1];
var lit = hsla[2];
var alpha = hsla[3]
switch (this._themeName) {
case "dark":
if (colorUsage & WebInspector.ThemeSupport.ColorUsage.Selection)
hue = (hue + 0.5) % 1;
var minCap = colorUsage & WebInspector.ThemeSupport.ColorUsage.Background ? 0.14 : 0;
var maxCap = colorUsage & WebInspector.ThemeSupport.ColorUsage.Foreground ? 0.9 : 1;
lit = 1 - lit;
if (lit < minCap * 2)
lit = minCap + lit / 2;
else if (lit > 2 * maxCap - 1)
lit = maxCap - 1 / 2 + lit / 2;
break;
}
hsla[0] = Number.constrain(hue, 0, 1);
hsla[1] = Number.constrain(sat, 0, 1);
hsla[2] = Number.constrain(lit, 0, 1);
hsla[3] = Number.constrain(alpha, 0, 1);
}
}
/**
* @param {?NetworkAgent.ResourcePriority} priority
* @return {string}
*/
WebInspector.uiLabelForPriority = function(priority)
{
var labelMap = WebInspector.uiLabelForPriority._priorityToUILabel;
if (!labelMap) {
labelMap = new Map([
[NetworkAgent.ResourcePriority.VeryLow, WebInspector.UIString("Lowest")],
[NetworkAgent.ResourcePriority.Low, WebInspector.UIString("Low")],
[NetworkAgent.ResourcePriority.Medium, WebInspector.UIString("Medium")],
[NetworkAgent.ResourcePriority.High, WebInspector.UIString("High")],
[NetworkAgent.ResourcePriority.VeryHigh, WebInspector.UIString("Highest")]
]);
WebInspector.uiLabelForPriority._priorityToUILabel = labelMap;
}
return labelMap.get(priority) || WebInspector.UIString("Unknown");
}
/** @type {!WebInspector.ThemeSupport} */
WebInspector.themeSupport;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | 2 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.ViewportControl.Provider} provider
*/
WebInspector.ViewportControl = function(provider)
{
this.element = createElement("div");
this.element.style.overflow = "auto";
this._topGapElement = this.element.createChild("div");
this._topGapElement.style.height = "0px";
this._topGapElement.style.color = "transparent";
this._contentElement = this.element.createChild("div");
this._bottomGapElement = this.element.createChild("div");
this._bottomGapElement.style.height = "0px";
this._bottomGapElement.style.color = "transparent";
// Text content needed for range intersection checks in _updateSelectionModel.
// Use Unicode ZERO WIDTH NO-BREAK SPACE, which avoids contributing any height to the element's layout overflow.
this._topGapElement.textContent = "\uFEFF";
this._bottomGapElement.textContent = "\uFEFF";
this._provider = provider;
this.element.addEventListener("scroll", this._onScroll.bind(this), false);
this.element.addEventListener("copy", this._onCopy.bind(this), false);
this.element.addEventListener("dragstart", this._onDragStart.bind(this), false);
this._firstVisibleIndex = 0;
this._lastVisibleIndex = -1;
this._renderedItems = [];
this._anchorSelection = null;
this._headSelection = null;
this._stickToBottom = false;
this._scrolledToBottom = true;
this._itemCount = 0;
}
/**
* @interface
*/
WebInspector.ViewportControl.Provider = function()
{
}
WebInspector.ViewportControl.Provider.prototype = {
/**
* @param {number} index
* @return {number}
*/
fastHeight: function(index) { return 0; },
/**
* @return {number}
*/
itemCount: function() { return 0; },
/**
* @return {number}
*/
minimumRowHeight: function() { return 0; },
/**
* @param {number} index
* @return {?WebInspector.ViewportElement}
*/
itemElement: function(index) { return null; }
}
/**
* @interface
*/
WebInspector.ViewportElement = function() { }
WebInspector.ViewportElement.prototype = {
willHide: function() { },
wasShown: function() { },
/**
* @return {!Element}
*/
element: function() { },
}
/**
* @constructor
* @implements {WebInspector.ViewportElement}
* @param {!Element} element
*/
WebInspector.StaticViewportElement = function(element)
{
this._element = element;
}
WebInspector.StaticViewportElement.prototype = {
/**
* @override
*/
willHide: function() { },
/**
* @override
*/
wasShown: function() { },
/**
* @override
* @return {!Element}
*/
element: function()
{
return this._element;
},
}
WebInspector.ViewportControl.prototype = {
/**
* @return {boolean}
*/
scrolledToBottom: function()
{
return this._scrolledToBottom;
},
/**
* @param {boolean} value
*/
setStickToBottom: function(value)
{
this._stickToBottom = value;
},
/**
* @param {!Event} event
*/
_onCopy: function(event)
{
var text = this._selectedText();
if (!text)
return;
event.preventDefault();
event.clipboardData.setData("text/plain", text);
},
/**
* @param {!Event} event
*/
_onDragStart: function(event)
{
var text = this._selectedText();
if (!text)
return false;
event.dataTransfer.clearData();
event.dataTransfer.setData("text/plain", text);
event.dataTransfer.effectAllowed = "copy";
return true;
},
/**
* @return {!Element}
*/
contentElement: function()
{
return this._contentElement;
},
invalidate: function()
{
delete this._cumulativeHeights;
delete this._cachedProviderElements;
this._itemCount = this._provider.itemCount();
this._innerRefresh(false);
},
/**
* @param {number} index
* @return {?WebInspector.ViewportElement}
*/
_providerElement: function(index)
{
if (!this._cachedProviderElements)
this._cachedProviderElements = new Array(this._itemCount);
var element = this._cachedProviderElements[index];
if (!element) {
element = this._provider.itemElement(index);
this._cachedProviderElements[index] = element;
}
return element;
},
_rebuildCumulativeHeightsIfNeeded: function()
{
if (this._cumulativeHeights)
return;
if (!this._itemCount)
return;
var firstVisibleIndex = this._firstVisibleIndex;
var lastVisibleIndex = this._lastVisibleIndex;
var height = 0;
this._cumulativeHeights = new Int32Array(this._itemCount);
for (var i = 0; i < this._itemCount; ++i) {
if (firstVisibleIndex <= i && i <= lastVisibleIndex)
height += this._renderedItems[i - firstVisibleIndex].element().offsetHeight;
else
height += this._provider.fastHeight(i);
this._cumulativeHeights[i] = height;
}
},
/**
* @param {number} index
* @return {number}
*/
_cachedItemHeight: function(index)
{
return index === 0 ? this._cumulativeHeights[0] : this._cumulativeHeights[index] - this._cumulativeHeights[index - 1];
},
/**
* @param {?Selection} selection
* @suppressGlobalPropertiesCheck
*/
_isSelectionBackwards: function(selection)
{
if (!selection || !selection.rangeCount)
return false;
var range = document.createRange();
range.setStart(selection.anchorNode, selection.anchorOffset);
range.setEnd(selection.focusNode, selection.focusOffset);
return range.collapsed;
},
/**
* @param {number} itemIndex
* @param {!Node} node
* @param {number} offset
* @return {!{item: number, node: !Node, offset: number}}
*/
_createSelectionModel: function(itemIndex, node, offset)
{
return {
item: itemIndex,
node: node,
offset: offset
};
},
/**
* @param {?Selection} selection
*/
_updateSelectionModel: function(selection)
{
if (!selection || !selection.rangeCount || selection.isCollapsed) {
this._headSelection = null;
this._anchorSelection = null;
return false;
}
var firstSelected = Number.MAX_VALUE;
var lastSelected = -1;
var range = selection.getRangeAt(0);
var hasVisibleSelection = false;
for (var i = 0; i < this._renderedItems.length; ++i) {
if (range.intersectsNode(this._renderedItems[i].element())) {
var index = i + this._firstVisibleIndex;
firstSelected = Math.min(firstSelected, index);
lastSelected = Math.max(lastSelected, index);
hasVisibleSelection = true;
}
}
if (hasVisibleSelection) {
firstSelected = this._createSelectionModel(firstSelected, /** @type {!Node} */(range.startContainer), range.startOffset);
lastSelected = this._createSelectionModel(lastSelected, /** @type {!Node} */(range.endContainer), range.endOffset);
}
var topOverlap = range.intersectsNode(this._topGapElement) && this._topGapElement._active;
var bottomOverlap = range.intersectsNode(this._bottomGapElement) && this._bottomGapElement._active;
if (!topOverlap && !bottomOverlap && !hasVisibleSelection) {
this._headSelection = null;
this._anchorSelection = null;
return false;
}
if (!this._anchorSelection || !this._headSelection) {
this._anchorSelection = this._createSelectionModel(0, this.element, 0);
this._headSelection = this._createSelectionModel(this._itemCount - 1, this.element, this.element.children.length);
this._selectionIsBackward = false;
}
var isBackward = this._isSelectionBackwards(selection);
var startSelection = this._selectionIsBackward ? this._headSelection : this._anchorSelection;
var endSelection = this._selectionIsBackward ? this._anchorSelection : this._headSelection;
if (topOverlap && bottomOverlap && hasVisibleSelection) {
firstSelected = firstSelected.item < startSelection.item ? firstSelected : startSelection;
lastSelected = lastSelected.item > endSelection.item ? lastSelected : endSelection;
} else if (!hasVisibleSelection) {
firstSelected = startSelection;
lastSelected = endSelection;
} else if (topOverlap)
firstSelected = isBackward ? this._headSelection : this._anchorSelection;
else if (bottomOverlap)
lastSelected = isBackward ? this._anchorSelection : this._headSelection;
if (isBackward) {
this._anchorSelection = lastSelected;
this._headSelection = firstSelected;
} else {
this._anchorSelection = firstSelected;
this._headSelection = lastSelected;
}
this._selectionIsBackward = isBackward;
return true;
},
/**
* @param {?Selection} selection
*/
_restoreSelection: function(selection)
{
var anchorElement = null;
var anchorOffset;
if (this._firstVisibleIndex <= this._anchorSelection.item && this._anchorSelection.item <= this._lastVisibleIndex) {
anchorElement = this._anchorSelection.node;
anchorOffset = this._anchorSelection.offset;
} else {
if (this._anchorSelection.item < this._firstVisibleIndex)
anchorElement = this._topGapElement;
else if (this._anchorSelection.item > this._lastVisibleIndex)
anchorElement = this._bottomGapElement;
anchorOffset = this._selectionIsBackward ? 1 : 0;
}
var headElement = null;
var headOffset;
if (this._firstVisibleIndex <= this._headSelection.item && this._headSelection.item <= this._lastVisibleIndex) {
headElement = this._headSelection.node;
headOffset = this._headSelection.offset;
} else {
if (this._headSelection.item < this._firstVisibleIndex)
headElement = this._topGapElement;
else if (this._headSelection.item > this._lastVisibleIndex)
headElement = this._bottomGapElement;
headOffset = this._selectionIsBackward ? 0 : 1;
}
selection.setBaseAndExtent(anchorElement, anchorOffset, headElement, headOffset);
},
refresh: function()
{
this._innerRefresh(false);
},
/**
* @param {boolean} isUserGesture
*/
_innerRefresh: function(isUserGesture)
{
if (!this._visibleHeight())
return; // Do nothing for invisible controls.
if (!this._itemCount) {
for (var i = 0; i < this._renderedItems.length; ++i)
this._renderedItems[i].willHide();
this._renderedItems = [];
this._contentElement.removeChildren();
this._topGapElement.style.height = "0px";
this._bottomGapElement.style.height = "0px";
this._firstVisibleIndex = -1;
this._lastVisibleIndex = -1;
return;
}
var selection = this.element.getComponentSelection();
var shouldRestoreSelection = this._updateSelectionModel(selection);
var visibleFrom = this.element.scrollTop;
var visibleHeight = this._visibleHeight();
this._scrolledToBottom = this.element.isScrolledToBottom();
var isInvalidating = !this._cumulativeHeights;
for (var i = 0; i < this._renderedItems.length; ++i) {
// Tolerate 1-pixel error due to double-to-integer rounding errors.
if (this._cumulativeHeights && Math.abs(this._cachedItemHeight(this._firstVisibleIndex + i) - this._renderedItems[i].element().offsetHeight) > 1)
delete this._cumulativeHeights;
}
this._rebuildCumulativeHeightsIfNeeded();
var oldFirstVisibleIndex = this._firstVisibleIndex;
var oldLastVisibleIndex = this._lastVisibleIndex;
var shouldStickToBottom = !isUserGesture && this._stickToBottom && this._scrolledToBottom;
if (shouldStickToBottom) {
this._lastVisibleIndex = this._itemCount - 1;
this._firstVisibleIndex = Math.max(this._itemCount - Math.ceil(visibleHeight / this._provider.minimumRowHeight()), 0);
} else {
this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0);
// Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(visibleHeight / this._provider.minimumRowHeight()) - 1;
this._lastVisibleIndex = Math.min(this._lastVisibleIndex, this._itemCount - 1);
}
var topGapHeight = this._cumulativeHeights[this._firstVisibleIndex - 1] || 0;
var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastVisibleIndex];
/**
* @this {WebInspector.ViewportControl}
*/
function prepare()
{
this._topGapElement.style.height = topGapHeight + "px";
this._bottomGapElement.style.height = bottomGapHeight + "px";
this._topGapElement._active = !!topGapHeight;
this._bottomGapElement._active = !!bottomGapHeight;
this._contentElement.style.setProperty("height", "10000000px");
}
if (isInvalidating)
this._fullViewportUpdate(prepare.bind(this));
else
this._partialViewportUpdate(oldFirstVisibleIndex, oldLastVisibleIndex, prepare.bind(this));
this._contentElement.style.removeProperty("height");
// Should be the last call in the method as it might force layout.
if (shouldRestoreSelection)
this._restoreSelection(selection);
if (shouldStickToBottom)
this.element.scrollTop = 10000000;
},
/**
* @param {function()} prepare
*/
_fullViewportUpdate: function(prepare)
{
for (var i = 0; i < this._renderedItems.length; ++i)
this._renderedItems[i].willHide();
prepare();
this._renderedItems = [];
this._contentElement.removeChildren();
for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i) {
var viewportElement = this._providerElement(i);
this._contentElement.appendChild(viewportElement.element());
this._renderedItems.push(viewportElement);
}
for (var i = 0; i < this._renderedItems.length; ++i)
this._renderedItems[i].wasShown();
},
/**
* @param {number} oldFirstVisibleIndex
* @param {number} oldLastVisibleIndex
* @param {function()} prepare
*/
_partialViewportUpdate: function(oldFirstVisibleIndex, oldLastVisibleIndex, prepare)
{
var willBeHidden = [];
for (var i = 0; i < this._renderedItems.length; ++i) {
var index = oldFirstVisibleIndex + i;
if (index < this._firstVisibleIndex || this._lastVisibleIndex < index)
willBeHidden.push(this._renderedItems[i]);
}
for (var i = 0; i < willBeHidden.length; ++i)
willBeHidden[i].willHide();
prepare();
for (var i = 0; i < willBeHidden.length; ++i)
willBeHidden[i].element().remove();
this._renderedItems = [];
var anchor = this._contentElement.firstChild;
var wasShown = [];
for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i) {
var viewportElement = this._providerElement(i);
var element = viewportElement.element();
if (element !== anchor) {
this._contentElement.insertBefore(element, anchor);
wasShown.push(viewportElement);
} else {
anchor = anchor.nextSibling;
}
this._renderedItems.push(viewportElement);
}
for (var i = 0; i < wasShown.length; ++i)
wasShown[i].wasShown();
},
/**
* @return {?string}
*/
_selectedText: function()
{
this._updateSelectionModel(this.element.getComponentSelection());
if (!this._headSelection || !this._anchorSelection)
return null;
var startSelection = null;
var endSelection = null;
if (this._selectionIsBackward) {
startSelection = this._headSelection;
endSelection = this._anchorSelection;
} else {
startSelection = this._anchorSelection;
endSelection = this._headSelection;
}
var textLines = [];
for (var i = startSelection.item; i <= endSelection.item; ++i)
textLines.push(this._providerElement(i).element().deepTextContent());
var endSelectionElement = this._providerElement(endSelection.item).element();
if (endSelection.node && endSelection.node.isSelfOrDescendant(endSelectionElement)) {
var itemTextOffset = this._textOffsetInNode(endSelectionElement, endSelection.node, endSelection.offset);
textLines[textLines.length - 1] = textLines.peekLast().substring(0, itemTextOffset);
}
var startSelectionElement = this._providerElement(startSelection.item).element();
if (startSelection.node && startSelection.node.isSelfOrDescendant(startSelectionElement)) {
var itemTextOffset = this._textOffsetInNode(startSelectionElement, startSelection.node, startSelection.offset);
textLines[0] = textLines[0].substring(itemTextOffset);
}
return textLines.join("\n");
},
/**
* @param {!Element} itemElement
* @param {!Node} container
* @param {number} offset
* @return {number}
*/
_textOffsetInNode: function(itemElement, container, offset)
{
var chars = 0;
var node = itemElement;
while ((node = node.traverseNextTextNode()) && node !== container)
chars += node.textContent.length;
return chars + offset;
},
/**
* @param {!Event} event
*/
_onScroll: function(event)
{
this._innerRefresh(event.isTrusted);
},
/**
* @return {number}
*/
firstVisibleIndex: function()
{
return this._firstVisibleIndex;
},
/**
* @return {number}
*/
lastVisibleIndex: function()
{
return this._lastVisibleIndex;
},
/**
* @return {?Element}
*/
renderedElementAt: function(index)
{
if (index < this._firstVisibleIndex)
return null;
if (index > this._lastVisibleIndex)
return null;
return this._renderedItems[index - this._firstVisibleIndex].element();
},
/**
* @param {number} index
* @param {boolean=} makeLast
*/
scrollItemIntoView: function(index, makeLast)
{
if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
return;
if (makeLast)
this.forceScrollItemToBeLast(index);
else if (index <= this._firstVisibleIndex)
this.forceScrollItemToBeFirst(index);
else if (index >= this._lastVisibleIndex)
this.forceScrollItemToBeLast(index);
},
/**
* @param {number} index
*/
forceScrollItemToBeFirst: function(index)
{
this._rebuildCumulativeHeightsIfNeeded();
this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
this._innerRefresh(false);
},
/**
* @param {number} index
*/
forceScrollItemToBeLast: function(index)
{
this._rebuildCumulativeHeightsIfNeeded();
this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight();
this._innerRefresh(false);
},
/**
* @return {number}
*/
_visibleHeight: function()
{
// Use offsetHeight instead of clientHeight to avoid being affected by horizontal scroll.
return this.element.offsetHeight;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | 2 1 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2011 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {boolean=} isWebComponent
*/
WebInspector.Widget = function(isWebComponent)
{
this.contentElement = createElementWithClass("div", "widget");
if (isWebComponent) {
this.element = createElementWithClass("div", "vbox flex-auto");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element);
this._shadowRoot.appendChild(this.contentElement);
} else {
this.element = this.contentElement;
}
this._isWebComponent = isWebComponent;
this.element.__widget = this;
this._visible = true;
this._isRoot = false;
this._isShowing = false;
this._children = [];
this._hideOnDetach = false;
this._notificationDepth = 0;
}
WebInspector.Widget.prototype = {
markAsRoot: function()
{
WebInspector.Widget.__assert(!this.element.parentElement, "Attempt to mark as root attached node");
this._isRoot = true;
},
/**
* @return {?WebInspector.Widget}
*/
parentWidget: function()
{
return this._parentWidget;
},
/**
* @return {!Array.<!WebInspector.Widget>}
*/
children: function()
{
return this._children;
},
/**
* @param {!WebInspector.Widget} widget
* @protected
*/
childWasDetached: function(widget)
{
},
/**
* @return {boolean}
*/
isShowing: function()
{
return this._isShowing;
},
/**
* @return {boolean}
*/
shouldHideOnDetach: function()
{
if (this._hideOnDetach)
return true;
for (var child of this._children) {
if (child.shouldHideOnDetach())
return true;
}
return false;
},
setHideOnDetach: function()
{
this._hideOnDetach = true;
},
/**
* @return {boolean}
*/
_inNotification: function()
{
return !!this._notificationDepth || (this._parentWidget && this._parentWidget._inNotification());
},
_parentIsShowing: function()
{
if (this._isRoot)
return true;
return this._parentWidget && this._parentWidget.isShowing();
},
/**
* @param {function(this:WebInspector.Widget)} method
*/
_callOnVisibleChildren: function(method)
{
var copy = this._children.slice();
for (var i = 0; i < copy.length; ++i) {
if (copy[i]._parentWidget === this && copy[i]._visible)
method.call(copy[i]);
}
},
_processWillShow: function()
{
this._callOnVisibleChildren(this._processWillShow);
this._isShowing = true;
},
_processWasShown: function()
{
if (this._inNotification())
return;
this.restoreScrollPositions();
this._notify(this.wasShown);
this._callOnVisibleChildren(this._processWasShown);
},
_processWillHide: function()
{
if (this._inNotification())
return;
this.storeScrollPositions();
this._callOnVisibleChildren(this._processWillHide);
this._notify(this.willHide);
this._isShowing = false;
},
_processWasHidden: function()
{
this._callOnVisibleChildren(this._processWasHidden);
},
_processOnResize: function()
{
if (this._inNotification())
return;
if (!this.isShowing())
return;
this._notify(this.onResize);
this._callOnVisibleChildren(this._processOnResize);
},
/**
* @param {function(this:WebInspector.Widget)} notification
*/
_notify: function(notification)
{
++this._notificationDepth;
try {
notification.call(this);
} finally {
--this._notificationDepth;
}
},
wasShown: function()
{
},
willHide: function()
{
},
onResize: function()
{
},
onLayout: function()
{
},
/**
* @param {?Element} parentElement
* @param {?Element=} insertBefore
*/
show: function(parentElement, insertBefore)
{
WebInspector.Widget.__assert(parentElement, "Attempt to attach widget with no parent element");
// Update widget hierarchy.
if (this.element.parentElement !== parentElement) {
if (this.element.parentElement)
this.detach();
var currentParent = parentElement;
while (currentParent && !currentParent.__widget)
currentParent = currentParent.parentElementOrShadowHost();
if (currentParent) {
this._parentWidget = currentParent.__widget;
this._parentWidget._children.push(this);
this._isRoot = false;
} else
WebInspector.Widget.__assert(this._isRoot, "Attempt to attach widget to orphan node");
} else if (this._visible) {
return;
}
this._visible = true;
if (this._parentIsShowing())
this._processWillShow();
this.element.classList.remove("hidden");
// Reparent
if (this.element.parentElement !== parentElement) {
WebInspector.Widget._incrementWidgetCounter(parentElement, this.element);
if (insertBefore)
WebInspector.Widget._originalInsertBefore.call(parentElement, this.element, insertBefore);
else
WebInspector.Widget._originalAppendChild.call(parentElement, this.element);
}
if (this._parentIsShowing())
this._processWasShown();
if (this._parentWidget && this._hasNonZeroConstraints())
this._parentWidget.invalidateConstraints();
else
this._processOnResize();
},
/**
* @param {boolean=} overrideHideOnDetach
*/
detach: function(overrideHideOnDetach)
{
var parentElement = this.element.parentElement;
if (!parentElement)
return;
if (this._parentIsShowing())
this._processWillHide();
if (!overrideHideOnDetach && this.shouldHideOnDetach()) {
this.element.classList.add("hidden");
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
if (this._parentWidget && this._hasNonZeroConstraints())
this._parentWidget.invalidateConstraints();
return;
}
// Force legal removal
WebInspector.Widget._decrementWidgetCounter(parentElement, this.element);
WebInspector.Widget._originalRemoveChild.call(parentElement, this.element);
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
// Update widget hierarchy.
if (this._parentWidget) {
var childIndex = this._parentWidget._children.indexOf(this);
WebInspector.Widget.__assert(childIndex >= 0, "Attempt to remove non-child widget");
this._parentWidget._children.splice(childIndex, 1);
this._parentWidget.childWasDetached(this);
var parent = this._parentWidget;
this._parentWidget = null;
if (this._hasNonZeroConstraints())
parent.invalidateConstraints();
} else
WebInspector.Widget.__assert(this._isRoot, "Removing non-root widget from DOM");
},
detachChildWidgets: function()
{
var children = this._children.slice();
for (var i = 0; i < children.length; ++i)
children[i].detach();
},
/**
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [this.element];
},
storeScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
container._scrollTop = container.scrollTop;
container._scrollLeft = container.scrollLeft;
}
},
restoreScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
if (container._scrollTop)
container.scrollTop = container._scrollTop;
if (container._scrollLeft)
container.scrollLeft = container._scrollLeft;
}
},
doResize: function()
{
if (!this.isShowing())
return;
// No matter what notification we are in, dispatching onResize is not needed.
if (!this._inNotification())
this._callOnVisibleChildren(this._processOnResize);
},
doLayout: function()
{
if (!this.isShowing())
return;
this._notify(this.onLayout);
this.doResize();
},
/**
* @param {string} cssFile
*/
registerRequiredCSS: function(cssFile)
{
WebInspector.appendStyle(this._isWebComponent ? this._shadowRoot : this.element, cssFile);
},
printWidgetHierarchy: function()
{
var lines = [];
this._collectWidgetHierarchy("", lines);
console.log(lines.join("\n"));
},
_collectWidgetHierarchy: function(prefix, lines)
{
lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : ""));
for (var i = 0; i < this._children.length; ++i)
this._children[i]._collectWidgetHierarchy(prefix + " ", lines);
if (this._children.length)
lines.push(prefix + "}");
},
/**
* @return {!Element}
*/
defaultFocusedElement: function()
{
return this._defaultFocusedElement || this.element;
},
/**
* @param {!Element} element
*/
setDefaultFocusedElement: function(element)
{
this._defaultFocusedElement = element;
},
focus: function()
{
var element = this.defaultFocusedElement();
if (!element || element.isAncestor(this.element.ownerDocument.activeElement))
return;
WebInspector.setCurrentFocusElement(element);
},
/**
* @return {boolean}
*/
hasFocus: function()
{
var activeElement = this.element.ownerDocument.activeElement;
return activeElement && activeElement.isSelfOrDescendant(this.element);
},
/**
* @return {!Size}
*/
measurePreferredSize: function()
{
var document = this.element.ownerDocument;
WebInspector.Widget._originalAppendChild.call(document.body, this.element);
this.element.positionAt(0, 0);
var result = new Size(this.element.offsetWidth, this.element.offsetHeight);
this.element.positionAt(undefined, undefined);
WebInspector.Widget._originalRemoveChild.call(document.body, this.element);
return result;
},
/**
* @return {!Constraints}
*/
calculateConstraints: function()
{
return new Constraints();
},
/**
* @return {!Constraints}
*/
constraints: function()
{
if (typeof this._constraints !== "undefined")
return this._constraints;
if (typeof this._cachedConstraints === "undefined")
this._cachedConstraints = this.calculateConstraints();
return this._cachedConstraints;
},
/**
* @param {number} width
* @param {number} height
* @param {number} preferredWidth
* @param {number} preferredHeight
*/
setMinimumAndPreferredSizes: function(width, height, preferredWidth, preferredHeight)
{
this._constraints = new Constraints(new Size(width, height), new Size(preferredWidth, preferredHeight));
this.invalidateConstraints();
},
/**
* @param {number} width
* @param {number} height
*/
setMinimumSize: function(width, height)
{
this._constraints = new Constraints(new Size(width, height));
this.invalidateConstraints();
},
/**
* @return {boolean}
*/
_hasNonZeroConstraints: function()
{
var constraints = this.constraints();
return !!(constraints.minimum.width || constraints.minimum.height || constraints.preferred.width || constraints.preferred.height);
},
invalidateConstraints: function()
{
var cached = this._cachedConstraints;
delete this._cachedConstraints;
var actual = this.constraints();
if (!actual.isEqual(cached) && this._parentWidget)
this._parentWidget.invalidateConstraints();
else
this.doLayout();
},
invalidateSize: function()
{
if (this._parentWidget)
this._parentWidget.doLayout();
},
__proto__: WebInspector.Object.prototype
}
WebInspector.Widget._originalAppendChild = Element.prototype.appendChild;
WebInspector.Widget._originalInsertBefore = Element.prototype.insertBefore;
WebInspector.Widget._originalRemoveChild = Element.prototype.removeChild;
WebInspector.Widget._originalRemoveChildren = Element.prototype.removeChildren;
WebInspector.Widget._incrementWidgetCounter = function(parentElement, childElement)
{
var count = (childElement.__widgetCounter || 0) + (childElement.__widget ? 1 : 0);
if (!count)
return;
while (parentElement) {
parentElement.__widgetCounter = (parentElement.__widgetCounter || 0) + count;
parentElement = parentElement.parentElementOrShadowHost();
}
}
WebInspector.Widget._decrementWidgetCounter = function(parentElement, childElement)
{
var count = (childElement.__widgetCounter || 0) + (childElement.__widget ? 1 : 0);
if (!count)
return;
while (parentElement) {
parentElement.__widgetCounter -= count;
parentElement = parentElement.parentElementOrShadowHost();
}
}
WebInspector.Widget.__assert = function(condition, message)
{
if (!condition) {
console.trace();
throw new Error(message);
}
}
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {boolean=} isWebComponent
*/
WebInspector.VBox = function(isWebComponent)
{
WebInspector.Widget.call(this, isWebComponent);
this.contentElement.classList.add("vbox");
};
WebInspector.VBox.prototype = {
/**
* @override
* @return {!Constraints}
*/
calculateConstraints: function()
{
var constraints = new Constraints();
/**
* @this {!WebInspector.Widget}
* @suppressReceiverCheck
*/
function updateForChild()
{
var child = this.constraints();
constraints = constraints.widthToMax(child);
constraints = constraints.addHeight(child);
}
this._callOnVisibleChildren(updateForChild);
return constraints;
},
__proto__: WebInspector.Widget.prototype
};
/**
* @constructor
* @extends {WebInspector.Widget}
* @param {boolean=} isWebComponent
*/
WebInspector.HBox = function(isWebComponent)
{
WebInspector.Widget.call(this, isWebComponent);
this.contentElement.classList.add("hbox");
};
WebInspector.HBox.prototype = {
/**
* @override
* @return {!Constraints}
*/
calculateConstraints: function()
{
var constraints = new Constraints();
/**
* @this {!WebInspector.Widget}
* @suppressReceiverCheck
*/
function updateForChild()
{
var child = this.constraints();
constraints = constraints.addWidth(child);
constraints = constraints.heightToMax(child);
}
this._callOnVisibleChildren(updateForChild);
return constraints;
},
__proto__: WebInspector.Widget.prototype
};
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {function()} resizeCallback
*/
WebInspector.VBoxWithResizeCallback = function(resizeCallback)
{
WebInspector.VBox.call(this);
this._resizeCallback = resizeCallback;
}
WebInspector.VBoxWithResizeCallback.prototype = {
onResize: function()
{
this._resizeCallback();
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.VBoxWithToolbarItems = function()
{
WebInspector.VBox.call(this);
}
WebInspector.VBoxWithToolbarItems.prototype = {
/**
* @return {!Array<!WebInspector.ToolbarItem>}
*/
toolbarItems: function()
{
return [];
},
__proto__: WebInspector.VBox.prototype
}
/**
* @override
* @param {?Node} child
* @return {?Node}
* @suppress {duplicate}
*/
Element.prototype.appendChild = function(child)
{
WebInspector.Widget.__assert(!child.__widget || child.parentElement === this, "Attempt to add widget via regular DOM operation.");
return WebInspector.Widget._originalAppendChild.call(this, child);
}
/**
* @override
* @param {?Node} child
* @param {?Node} anchor
* @return {!Node}
* @suppress {duplicate}
*/
Element.prototype.insertBefore = function(child, anchor)
{
WebInspector.Widget.__assert(!child.__widget || child.parentElement === this, "Attempt to add widget via regular DOM operation.");
return WebInspector.Widget._originalInsertBefore.call(this, child, anchor);
}
/**
* @override
* @param {?Node} child
* @return {!Node}
* @suppress {duplicate}
*/
Element.prototype.removeChild = function(child)
{
WebInspector.Widget.__assert(!child.__widgetCounter && !child.__widget, "Attempt to remove element containing widget via regular DOM operation");
return WebInspector.Widget._originalRemoveChild.call(this, child);
}
Element.prototype.removeChildren = function()
{
WebInspector.Widget.__assert(!this.__widgetCounter, "Attempt to remove element containing widget via regular DOM operation");
WebInspector.Widget._originalRemoveChildren.call(this);
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Window} window
* @param {!InspectorFrontendHostAPI} frontendHost
*/
WebInspector.ZoomManager = function(window, frontendHost)
{
this._frontendHost = frontendHost;
this._zoomFactor = this._frontendHost.zoomFactor();
window.addEventListener("resize", this._onWindowResize.bind(this), true);
};
WebInspector.ZoomManager.Events = {
ZoomChanged: "ZoomChanged"
};
WebInspector.ZoomManager.prototype = {
/**
* @return {number}
*/
zoomFactor: function()
{
return this._zoomFactor;
},
/**
* @param {number} value
* @return {number}
*/
cssToDIP: function(value)
{
return value * this._zoomFactor;
},
/**
* @param {number} valueDIP
* @return {number}
*/
dipToCSS: function(valueDIP)
{
return valueDIP / this._zoomFactor;
},
_onWindowResize: function()
{
var oldZoomFactor = this._zoomFactor;
this._zoomFactor = this._frontendHost.zoomFactor();
if (oldZoomFactor !== this._zoomFactor)
this.dispatchEventToListeners(WebInspector.ZoomManager.Events.ZoomChanged, {from: oldZoomFactor, to: this._zoomFactor});
},
__proto__: WebInspector.Object.prototype
};
/**
* @type {!WebInspector.ZoomManager}
*/
WebInspector.zoomManager;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 | 1 2 2 1 1 1 | /*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {boolean=} nonFocusable
*/
function TreeOutline(nonFocusable)
{
this._createRootElement();
this.selectedTreeElement = null;
this.expandTreeElementsWhenArrowing = false;
/** @type {?function(!TreeElement, !TreeElement):number} */
this._comparator = null;
this._contentElement = this._rootElement._childrenListNode;
this._contentElement.addEventListener("keydown", this._treeKeyDown.bind(this), true);
this.setFocusable(!nonFocusable);
this.element = this._contentElement;
}
TreeOutline.Events = {
ElementAttached: "ElementAttached",
ElementExpanded: "ElementExpanded",
ElementCollapsed: "ElementCollapsed",
ElementSelected: "ElementSelected"
}
TreeOutline.prototype = {
_createRootElement: function()
{
this._rootElement = new TreeElement();
this._rootElement.treeOutline = this;
this._rootElement.root = true;
this._rootElement.selectable = false;
this._rootElement.expanded = true;
this._rootElement._childrenListNode.classList.remove("children");
},
/**
* @return {!TreeElement}
*/
rootElement: function()
{
return this._rootElement;
},
/**
* @return {?TreeElement}
*/
firstChild: function()
{
return this._rootElement.firstChild();
},
/**
* @param {!TreeElement} child
*/
appendChild: function(child)
{
this._rootElement.appendChild(child);
},
/**
* @param {!TreeElement} child
* @param {number} index
*/
insertChild: function(child, index)
{
this._rootElement.insertChild(child, index);
},
/**
* @param {!TreeElement} child
*/
removeChild: function(child)
{
this._rootElement.removeChild(child);
},
removeChildren: function()
{
this._rootElement.removeChildren();
},
/**
* @param {number} x
* @param {number} y
* @return {?TreeElement}
*/
treeElementFromPoint: function(x, y)
{
var node = this._contentElement.ownerDocument.deepElementFromPoint(x, y);
if (!node)
return null;
var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
if (listNode)
return listNode.parentTreeElement || listNode.treeElement;
return null;
},
/**
* @param {?Event} event
* @return {?TreeElement}
*/
treeElementFromEvent: function(event)
{
return event ? this.treeElementFromPoint(event.pageX, event.pageY) : null;
},
/**
* @param {?function(!TreeElement, !TreeElement):number} comparator
*/
setComparator: function(comparator)
{
this._comparator = comparator;
},
/**
* @param {boolean} focusable
*/
setFocusable: function(focusable)
{
if (focusable)
this._contentElement.setAttribute("tabIndex", 0);
else
this._contentElement.removeAttribute("tabIndex");
},
focus: function()
{
this._contentElement.focus();
},
/**
* @param {!TreeElement} element
*/
_bindTreeElement: function(element)
{
if (element.treeOutline)
console.error("Binding element for the second time: " + new Error().stack);
element.treeOutline = this;
element.onbind();
},
/**
* @param {!TreeElement} element
*/
_unbindTreeElement: function(element)
{
if (!element.treeOutline)
console.error("Unbinding element that was not bound: " + new Error().stack);
element.deselect();
element.onunbind();
element.treeOutline = null;
},
/**
* @return {boolean}
*/
selectPrevious: function()
{
var nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
return true;
}
return false;
},
/**
* @return {boolean}
*/
selectNext: function()
{
var nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
return true;
}
return false;
},
/**
* @param {!Event} event
*/
_treeKeyDown: function(event)
{
if (event.target !== this._contentElement)
return;
if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
return;
var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Up" && !event.altKey) {
handled = this.selectPrevious();
} else if (event.keyIdentifier === "Down" && !event.altKey) {
handled = this.selectNext();
} else if (event.keyIdentifier === "Left") {
if (this.selectedTreeElement.expanded) {
if (event.altKey)
this.selectedTreeElement.collapseRecursively();
else
this.selectedTreeElement.collapse();
handled = true;
} else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
handled = true;
if (this.selectedTreeElement.parent.selectable) {
nextSelectedElement = this.selectedTreeElement.parent;
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.parent;
handled = nextSelectedElement ? true : false;
} else if (this.selectedTreeElement.parent)
this.selectedTreeElement.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedTreeElement.revealed()) {
this.selectedTreeElement.reveal();
handled = true;
} else if (this.selectedTreeElement._expandable) {
handled = true;
if (this.selectedTreeElement.expanded) {
nextSelectedElement = this.selectedTreeElement.firstChild();
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.nextSibling;
handled = nextSelectedElement ? true : false;
} else {
if (event.altKey)
this.selectedTreeElement.expandRecursively();
else
this.selectedTreeElement.expand();
}
}
} else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */)
handled = this.selectedTreeElement.ondelete();
else if (isEnterKey(event))
handled = this.selectedTreeElement.onenter();
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
handled = this.selectedTreeElement.onspace();
if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
}
if (handled)
event.consume(true);
},
/**
* @param {!TreeElement} treeElement
* @param {boolean} center
*/
_deferredScrollIntoView: function(treeElement, center)
{
if (!this._treeElementToScrollIntoView)
this.element.window().requestAnimationFrame(deferredScrollIntoView.bind(this));
this._treeElementToScrollIntoView = treeElement;
this._centerUponScrollIntoView = center;
/**
* @this {TreeOutline}
*/
function deferredScrollIntoView()
{
this._treeElementToScrollIntoView.listItemElement.scrollIntoViewIfNeeded(this._centerUponScrollIntoView);
delete this._treeElementToScrollIntoView;
delete this._centerUponScrollIntoView;
}
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {TreeOutline}
*/
function TreeOutlineInShadow()
{
TreeOutline.call(this);
var innerElement = this.element;
innerElement.classList.add("tree-outline");
// Redefine element to the external one.
this.element = createElement("div");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/treeoutline.css");
this._disclosureElement = this._shadowRoot.createChild("div", "tree-outline-disclosure");
this._disclosureElement.appendChild(innerElement);
this._renderSelection = true;
}
TreeOutlineInShadow.prototype = {
/**
* @param {string} cssFile
*/
registerRequiredCSS: function(cssFile)
{
WebInspector.appendStyle(this._shadowRoot, cssFile);
},
hideOverflow: function()
{
this._disclosureElement.classList.add("tree-outline-disclosure-hide-overflow");
},
__proto__: TreeOutline.prototype
}
/**
* @constructor
* @param {(string|!Node)=} title
* @param {boolean=} expandable
*/
function TreeElement(title, expandable)
{
/** @type {?TreeOutline} */
this.treeOutline = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this._listItemNode = createElement("li");
this._listItemNode.treeElement = this;
if (title)
this.title = title;
this._listItemNode.addEventListener("mousedown", this._handleMouseDown.bind(this), false);
this._listItemNode.addEventListener("selectstart", this._treeElementSelectStart.bind(this), false);
this._listItemNode.addEventListener("click", this._treeElementToggled.bind(this), false);
this._listItemNode.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);
this._childrenListNode = createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.classList.add("children");
this._hidden = false;
this._selectable = true;
this.expanded = false;
this.selected = false;
this.setExpandable(expandable || false);
this._collapsible = true;
}
/** @const */
TreeElement._ArrowToggleWidth = 10;
TreeElement.prototype = {
/**
* @param {?TreeElement} ancestor
* @return {boolean}
*/
hasAncestor: function(ancestor)
{
if (!ancestor)
return false;
var currentNode = this.parent;
while (currentNode) {
if (ancestor === currentNode)
return true;
currentNode = currentNode.parent;
}
return false;
},
/**
* @param {?TreeElement} ancestor
* @return {boolean}
*/
hasAncestorOrSelf: function(ancestor)
{
return this === ancestor || this.hasAncestor(ancestor);
},
/**
* @return {!Array.<!TreeElement>}
*/
children: function()
{
return this._children || [];
},
/**
* @return {number}
*/
childCount: function()
{
return this._children ? this._children.length : 0;
},
/**
* @return {?TreeElement}
*/
firstChild: function()
{
return this._children ? this._children[0] : null;
},
/**
* @return {?TreeElement}
*/
lastChild: function()
{
return this._children ? this._children[this._children.length - 1] : null;
},
/**
* @param {number} index
* @return {?TreeElement}
*/
childAt: function(index)
{
return this._children ? this._children[index] : null;
},
/**
* @param {!TreeElement} child
* @return {number}
*/
indexOfChild: function(child)
{
return this._children ? this._children.indexOf(child) : -1;
},
/**
* @param {!TreeElement} child
*/
appendChild: function(child)
{
if (!this._children)
this._children = [];
var insertionIndex;
if (this.treeOutline && this.treeOutline._comparator)
insertionIndex = this._children.lowerBound(child, this.treeOutline._comparator);
else
insertionIndex = this._children.length;
this.insertChild(child, insertionIndex);
},
/**
* @param {!TreeElement} child
* @param {number} index
*/
insertChild: function(child, index)
{
if (!this._children)
this._children = [];
if (!child)
throw("child can't be undefined or null");
console.assert(!child.parent, "Attempting to insert a child that is already in the tree, reparenting is not supported.");
var previousChild = (index > 0 ? this._children[index - 1] : null);
if (previousChild) {
previousChild.nextSibling = child;
child.previousSibling = previousChild;
} else {
child.previousSibling = null;
}
var nextChild = this._children[index];
if (nextChild) {
nextChild.previousSibling = child;
child.nextSibling = nextChild;
} else {
child.nextSibling = null;
}
this._children.splice(index, 0, child);
this.setExpandable(true);
child.parent = this;
if (this.treeOutline)
this.treeOutline._bindTreeElement(child);
for (var current = child.firstChild(); this.treeOutline && current; current = current.traverseNextTreeElement(false, child, true))
this.treeOutline._bindTreeElement(current);
child.onattach();
child._ensureSelection();
if (this.treeOutline)
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementAttached, child);
var nextSibling = child.nextSibling ? child.nextSibling._listItemNode : null;
this._childrenListNode.insertBefore(child._listItemNode, nextSibling);
this._childrenListNode.insertBefore(child._childrenListNode, nextSibling);
if (child.selected)
child.select();
if (child.expanded)
child.expand();
},
/**
* @param {number} childIndex
*/
removeChildAtIndex: function(childIndex)
{
if (childIndex < 0 || childIndex >= this._children.length)
throw("childIndex out of range");
var child = this._children[childIndex];
this._children.splice(childIndex, 1);
var parent = child.parent;
if (this.treeOutline && this.treeOutline.selectedTreeElement && this.treeOutline.selectedTreeElement.hasAncestorOrSelf(child)) {
if (child.nextSibling)
child.nextSibling.select(true);
else if (child.previousSibling)
child.previousSibling.select(true);
else if (parent)
parent.select(true);
}
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
child.parent = null;
if (this.treeOutline)
this.treeOutline._unbindTreeElement(child);
for (var current = child.firstChild(); this.treeOutline && current; current = current.traverseNextTreeElement(false, child, true))
this.treeOutline._unbindTreeElement(current);
child._detach();
},
/**
* @param {!TreeElement} child
*/
removeChild: function(child)
{
if (!child)
throw("child can't be undefined or null");
if (child.parent !== this)
return;
var childIndex = this._children.indexOf(child);
if (childIndex === -1)
throw("child not found in this node's children");
this.removeChildAtIndex(childIndex);
},
removeChildren: function()
{
if (!this.root && this.treeOutline && this.treeOutline.selectedTreeElement && this.treeOutline.selectedTreeElement.hasAncestorOrSelf(this))
this.select(true);
for (var i = 0; this._children && i < this._children.length; ++i) {
var child = this._children[i];
child.previousSibling = null
child.nextSibling = null;
child.parent = null;
if (this.treeOutline)
this.treeOutline._unbindTreeElement(child);
for (var current = child.firstChild(); this.treeOutline && current; current = current.traverseNextTreeElement(false, child, true))
this.treeOutline._unbindTreeElement(current);
child._detach();
}
this._children = [];
},
get selectable()
{
if (this._hidden)
return false;
return this._selectable;
},
set selectable(x)
{
this._selectable = x;
},
get listItemElement()
{
return this._listItemNode;
},
get childrenListElement()
{
return this._childrenListNode;
},
get title()
{
return this._title;
},
/**
* @param {string|!Node} x
*/
set title(x)
{
if (this._title === x)
return;
this._title = x;
if (typeof x === "string") {
this._titleElement = createElementWithClass("span", "tree-element-title");
this._titleElement.textContent = x;
this.tooltip = x;
} else {
this._titleElement = x;
this.tooltip = "";
}
this._listItemNode.removeChildren();
if (this._iconElement)
this._listItemNode.appendChild(this._iconElement);
this._listItemNode.appendChild(this._titleElement);
this._ensureSelection();
},
/**
* @param {!WebInspector.InplaceEditor.Config} editingConfig
*/
startEditingTitle: function(editingConfig)
{
WebInspector.InplaceEditor.startEditing(this._titleElement, editingConfig);
this.treeOutline._shadowRoot.getSelection().setBaseAndExtent(this._titleElement, 0, this._titleElement, 1);
},
createIcon()
{
if (!this._iconElement) {
this._iconElement = createElementWithClass("div", "icon");
this._listItemNode.insertBefore(this._iconElement, this._listItemNode.firstChild);
this._ensureSelection();
}
},
get tooltip()
{
return this._tooltip || "";
},
/**
* @param {string} x
*/
set tooltip(x)
{
if (this._tooltip === x)
return;
this._tooltip = x;
this._listItemNode.title = x;
},
/**
* @return {boolean}
*/
isExpandable: function()
{
return this._expandable;
},
/**
* @param {boolean} expandable
*/
setExpandable: function(expandable)
{
if (this._expandable === expandable)
return;
this._expandable = expandable;
this._listItemNode.classList.toggle("parent", expandable);
if (!expandable)
this.collapse();
},
/**
* @param {boolean} collapsible
*/
setCollapsible: function(collapsible)
{
if (this._collapsible === collapsible)
return;
this._collapsible = collapsible;
this._listItemNode.classList.toggle("always-parent", !collapsible);
if (!collapsible)
this.expand();
},
get hidden()
{
return this._hidden;
},
set hidden(x)
{
if (this._hidden === x)
return;
this._hidden = x;
this._listItemNode.classList.toggle("hidden", x);
this._childrenListNode.classList.toggle("hidden", x);
},
invalidateChildren: function()
{
if (this._children) {
this.removeChildren();
this._children = null;
}
},
_ensureSelection: function()
{
if (!this.treeOutline || !this.treeOutline._renderSelection)
return;
if (!this._selectionElement)
this._selectionElement = createElementWithClass("div", "selection fill");
this._listItemNode.insertBefore(this._selectionElement, this.listItemElement.firstChild);
},
/**
* @param {!Event} event
*/
_treeElementSelectStart: function(event)
{
event.currentTarget._selectionStarted = true;
},
/**
* @param {!Event} event
*/
_treeElementToggled: function(event)
{
var element = event.currentTarget;
if (element._selectionStarted) {
delete element._selectionStarted;
var selection = element.getComponentSelection();
if (selection && !selection.isCollapsed && element.isSelfOrAncestor(selection.anchorNode) && element.isSelfOrAncestor(selection.focusNode))
return;
}
if (element.treeElement !== this)
return;
var toggleOnClick = this.toggleOnClick && !this.selectable;
var isInTriangle = this.isEventWithinDisclosureTriangle(event);
if (!toggleOnClick && !isInTriangle)
return;
if (event.target && event.target.enclosingNodeOrSelfWithNodeName("a"))
return;
if (this.expanded) {
if (event.altKey)
this.collapseRecursively();
else
this.collapse();
} else {
if (event.altKey)
this.expandRecursively();
else
this.expand();
}
event.consume();
},
/**
* @param {!Event} event
*/
_handleMouseDown: function(event)
{
var element = event.currentTarget;
if (!element)
return;
delete element._selectionStarted;
if (!this.selectable)
return;
if (element.treeElement !== this)
return;
if (this.isEventWithinDisclosureTriangle(event))
return;
this.selectOnMouseDown(event);
},
/**
* @param {!Event} event
*/
_handleDoubleClick: function(event)
{
var element = event.currentTarget;
if (!element || element.treeElement !== this)
return;
var handled = this.ondblclick(event);
if (handled)
return;
if (this._expandable && !this.expanded)
this.expand();
},
_detach: function()
{
this._listItemNode.remove();
this._childrenListNode.remove();
},
collapse: function()
{
if (!this.expanded || !this._collapsible)
return;
this._listItemNode.classList.remove("expanded");
this._childrenListNode.classList.remove("expanded");
this.expanded = false;
this.oncollapse();
if (this.treeOutline)
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementCollapsed, this);
},
collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextTreeElement(false, this, true);
}
},
expand: function()
{
if (!this._expandable || (this.expanded && this._children))
return;
// Set this before onpopulate. Since onpopulate can add elements, this makes
// sure the expanded flag is true before calling those functions. This prevents the possibility
// of an infinite loop if onpopulate were to call expand.
this.expanded = true;
this._populateIfNeeded();
this._listItemNode.classList.add("expanded");
this._childrenListNode.classList.add("expanded");
if (this.treeOutline) {
this.onexpand();
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementExpanded, this);
}
},
/**
* @param {number=} maxDepth
*/
expandRecursively: function(maxDepth)
{
var item = this;
var info = {};
var depth = 0;
// The Inspector uses TreeOutlines to represents object properties, so recursive expansion
// in some case can be infinite, since JavaScript objects can hold circular references.
// So default to a recursion cap of 3 levels, since that gives fairly good results.
if (isNaN(maxDepth))
maxDepth = 3;
while (item) {
if (depth < maxDepth)
item.expand();
item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
depth += info.depthChange;
}
},
/**
* @param {boolean=} center
*/
reveal: function(center)
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}
this.treeOutline._deferredScrollIntoView(this, !!center);
},
/**
* @return {boolean}
*/
revealed: function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
return false;
currentAncestor = currentAncestor.parent;
}
return true;
},
selectOnMouseDown: function(event)
{
if (this.select(false, true))
event.consume(true);
},
/**
* @param {boolean=} omitFocus
* @param {boolean=} selectedByUser
* @return {boolean}
*/
select: function(omitFocus, selectedByUser)
{
if (!this.treeOutline || !this.selectable || this.selected)
return false;
if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.deselect();
this.treeOutline.selectedTreeElement = null;
if (this.treeOutline._rootElement === this)
return false;
this.selected = true;
if (!omitFocus)
this.treeOutline.focus();
// Focusing on another node may detach "this" from tree.
if (!this.treeOutline)
return false;
this.treeOutline.selectedTreeElement = this;
this._listItemNode.classList.add("selected");
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementSelected, this);
return this.onselect(selectedByUser);
},
/**
* @param {boolean=} omitFocus
*/
revealAndSelect: function(omitFocus)
{
this.reveal(true);
this.select(omitFocus);
},
/**
* @param {boolean=} supressOnDeselect
*/
deselect: function(supressOnDeselect)
{
if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
return;
this.selected = false;
this.treeOutline.selectedTreeElement = null;
this._listItemNode.classList.remove("selected");
},
_populateIfNeeded: function()
{
if (this.treeOutline && this._expandable && !this._children) {
this._children = [];
this.onpopulate();
}
},
onpopulate: function()
{
// Overridden by subclasses.
},
/**
* @return {boolean}
*/
onenter: function()
{
return false;
},
/**
* @return {boolean}
*/
ondelete: function()
{
return false;
},
/**
* @return {boolean}
*/
onspace: function()
{
return false;
},
onbind: function()
{
},
onunbind: function()
{
},
onattach: function()
{
},
onexpand: function()
{
},
oncollapse: function()
{
},
/**
* @param {!Event} e
* @return {boolean}
*/
ondblclick: function(e)
{
return false;
},
/**
* @param {boolean=} selectedByUser
* @return {boolean}
*/
onselect: function(selectedByUser)
{
return false;
},
/**
* @param {boolean} skipUnrevealed
* @param {?TreeElement=} stayWithin
* @param {boolean=} dontPopulate
* @param {!Object=} info
* @return {?TreeElement}
*/
traverseNextTreeElement: function(skipUnrevealed, stayWithin, dontPopulate, info)
{
if (!dontPopulate)
this._populateIfNeeded();
if (info)
info.depthChange = 0;
var element = skipUnrevealed ? (this.revealed() ? this.firstChild() : null) : this.firstChild();
if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
if (info)
info.depthChange = 1;
return element;
}
if (this === stayWithin)
return null;
element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
if (element)
return element;
element = this;
while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
element = element.parent;
}
if (!element || element.root)
return null;
return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
},
/**
* @param {boolean} skipUnrevealed
* @param {boolean=} dontPopulate
* @return {?TreeElement}
*/
traversePreviousTreeElement: function(skipUnrevealed, dontPopulate)
{
var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
if (!dontPopulate && element)
element._populateIfNeeded();
while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.lastChild() : null) : element.lastChild())) {
if (!dontPopulate)
element._populateIfNeeded();
element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.lastChild() : null) : element.lastChild());
}
if (element)
return element;
if (!this.parent || this.parent.root)
return null;
return this.parent;
},
/**
* @return {boolean}
*/
isEventWithinDisclosureTriangle: function(event)
{
// FIXME: We should not use getComputedStyle(). For that we need to get rid of using ::before for disclosure triangle. (http://webk.it/74446)
var paddingLeftValue = window.getComputedStyle(this._listItemNode).paddingLeft;
console.assert(paddingLeftValue.endsWith("px"));
var computedLeftPadding = parseFloat(paddingLeftValue);
var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
return event.pageX >= left && event.pageX <= left + TreeElement._ArrowToggleWidth && this._expandable;
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| CommandMenu.js | 5.1% | (5 / 98) | 0% | (0 / 30) | 0% | (0 / 28) | 5.1% | (5 / 98) | |
| DataGrid.js | 0.22% | (2 / 896) | 0% | (0 / 585) | 0% | (0 / 106) | 0.22% | (2 / 896) | |
| FilteredListWidget.js | 1.79% | (4 / 224) | 0% | (0 / 88) | 0% | (0 / 44) | 1.79% | (4 / 224) | |
| FlameChart.js | 1.12% | (11 / 982) | 0% | (0 / 397) | 0% | (0 / 121) | 1.12% | (11 / 980) | |
| OverviewGrid.js | 0.6% | (1 / 168) | 0% | (0 / 52) | 0% | (0 / 34) | 0.6% | (1 / 168) | |
| PieChart.js | 2.08% | (1 / 48) | 0% | (0 / 12) | 0% | (0 / 5) | 2.08% | (1 / 48) | |
| ShowMoreDataGridNode.js | 2.17% | (1 / 46) | 0% | (0 / 6) | 0% | (0 / 11) | 2.17% | (1 / 46) | |
| SortableDataGrid.js | 2.82% | (2 / 71) | 0% | (0 / 28) | 0% | (0 / 12) | 2.82% | (2 / 71) | |
| TimelineGrid.js | 0.71% | (1 / 141) | 0% | (0 / 23) | 0% | (0 / 25) | 0.71% | (1 / 141) | |
| TimelineOverviewPane.js | 2.76% | (5 / 181) | 0% | (0 / 36) | 0% | (0 / 61) | 2.78% | (5 / 180) | |
| ViewportDataGrid.js | 0.47% | (1 / 214) | 0% | (0 / 101) | 0% | (0 / 28) | 0.47% | (1 / 214) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | 2 1 1 1 1 | // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor */ WebInspector.CommandMenu = function() { this._commands = []; this._loadCommands(); } WebInspector.CommandMenu.prototype = { _loadCommands: function() { // Populate panels. var panelExtensions = self.runtime.extensions(WebInspector.PanelFactory); for (var extension of panelExtensions) this._commands.push(WebInspector.CommandMenu.createRevealPanelCommand(extension)); // Populate drawers. var drawerExtensions = self.runtime.extensions("drawer-view"); for (var extension of drawerExtensions) this._commands.push(WebInspector.CommandMenu.createRevealDrawerCommand(extension)); // Populate whitelisted settings. var settingExtensions = self.runtime.extensions("setting"); for (var extension of settingExtensions) { var options = extension.descriptor()["options"]; if (!options || !extension.descriptor()["category"]) continue; for (var pair of options) this._commands.push(WebInspector.CommandMenu.createSettingCommand(extension, pair["title"], pair["value"])); } }, /** * @return {!Array.<!WebInspector.CommandMenu.Command>} */ commands: function() { return this._commands; } } /** * @constructor * @extends {WebInspector.FilteredListWidget.Delegate} */ WebInspector.CommandMenuDelegate = function() { WebInspector.FilteredListWidget.Delegate.call(this, []); this._commands = []; this._appendAvailableCommands(); } WebInspector.CommandMenuDelegate.prototype = { _appendAvailableCommands: function() { var allCommands = WebInspector.commandMenu.commands(); // Populate whitelisted actions. var actions = WebInspector.actionRegistry.availableActions(); for (var action of actions) { if (action.category()) this._commands.push(WebInspector.CommandMenu.createActionCommand(action)); } for (var command of allCommands) { if (command.available()) this._commands.push(command); } this._commands = this._commands.sort(commandComparator); /** * @param {!WebInspector.CommandMenu.Command} left * @param {!WebInspector.CommandMenu.Command} right * @return {number} */ function commandComparator(left, right) { return left.title().compareTo(right.title()); } }, /** * @override * @return {number} */ itemCount: function() { return this._commands.length; }, /** * @override * @param {number} itemIndex * @return {string} */ itemKeyAt: function(itemIndex) { return this._commands[itemIndex].key(); }, /** * @override * @param {number} itemIndex * @param {string} query * @return {number} */ itemScoreAt: function(itemIndex, query) { var command = this._commands[itemIndex]; var opcodes = WebInspector.Diff.charDiff(query.toLowerCase(), command.title().toLowerCase()); var score = 0; // Score longer sequences higher. for (var i = 0; i < opcodes.length; ++i) { if (opcodes[i][0] === WebInspector.Diff.Operation.Equal) score += opcodes[i][1].length * opcodes[i][1].length; } // Score panel/drawer reveals above regular actions. if (command.title().startsWith("Panel")) score += 2; else if (command.title().startsWith("Drawer")) score += 1; return score; }, /** * @override * @param {number} itemIndex * @param {string} query * @param {!Element} titleElement * @param {!Element} subtitleElement */ renderItem: function(itemIndex, query, titleElement, subtitleElement) { var command = this._commands[itemIndex]; titleElement.textContent = command.title(); this.highlightRanges(titleElement, query); subtitleElement.textContent = command.shortcut(); }, /** * @override * @param {?number} itemIndex * @param {string} promptValue */ selectItem: function(itemIndex, promptValue) { this._commands[itemIndex].execute(); }, /** * @override * @return {boolean} */ caseSensitive: function() { return false; }, __proto__: WebInspector.FilteredListWidget.Delegate.prototype } /** * @constructor * @param {string} title * @param {string} key * @param {string} shortcut * @param {function()} executeHandler * @param {function()=} availableHandler */ WebInspector.CommandMenu.Command = function(title, key, shortcut, executeHandler, availableHandler) { this._title = title; this._key = title + "\0" + key; this._shortcut = shortcut; this._executeHandler = executeHandler; this._availableHandler = availableHandler; } WebInspector.CommandMenu.Command.prototype = { /** * @return {string} */ title: function() { return this._title; }, /** * @return {string} */ key: function() { return this._key; }, /** * @return {string} */ shortcut: function() { return this._shortcut; }, /** * @return {boolean} */ available: function() { return this._availableHandler ? this._availableHandler() : true; }, execute: function() { this._executeHandler(); } } /** * @param {string} category * @param {string} keys * @param {string} title * @param {string} shortcut * @param {function()} executeHandler * @param {function()=} availableHandler * @return {!WebInspector.CommandMenu.Command} */ WebInspector.CommandMenu.createCommand = function(category, keys, title, shortcut, executeHandler, availableHandler) { // Separate keys by null character, to prevent fuzzy matching from matching across them. var key = keys ? keys.split(",").join("\0") : ""; title = category ? WebInspector.UIString("%s: %s", category, title) : title; return new WebInspector.CommandMenu.Command(title, key, shortcut, executeHandler, availableHandler); } /** * @param {!Runtime.Extension} extension * @param {string} title * @param {V} value * @return {!WebInspector.CommandMenu.Command} * @template V */ WebInspector.CommandMenu.createSettingCommand = function(extension, title, value) { var category = extension.descriptor()["category"] || ""; var tags = extension.descriptor()["tags"] || ""; var setting = WebInspector.settings.moduleSetting(extension.descriptor()["settingName"]); return WebInspector.CommandMenu.createCommand(category, tags, title, "", setting.set.bind(setting, value), availableHandler); /** * @return {boolean} */ function availableHandler() { return setting.get() !== value; } } /** * @param {!WebInspector.Action} action * @return {!WebInspector.CommandMenu.Command} */ WebInspector.CommandMenu.createActionCommand = function(action) { var shortcut = WebInspector.shortcutRegistry.shortcutTitleForAction(action.id()) || ""; return WebInspector.CommandMenu.createCommand(action.category(), action.tags(), action.title(), shortcut, action.execute.bind(action)); } /** * @param {!Runtime.Extension} extension * @return {!WebInspector.CommandMenu.Command} */ WebInspector.CommandMenu.createRevealPanelCommand = function(extension) { var panelName = extension.descriptor()["name"]; var tags = extension.descriptor()["tags"] || ""; return WebInspector.CommandMenu.createCommand(WebInspector.UIString("Panel"), tags, WebInspector.UIString("Show %s", extension.title(WebInspector.platform())), "", executeHandler, availableHandler); /** * @return {boolean} */ function availableHandler() { return WebInspector.inspectorView.currentPanel().name !== panelName; } function executeHandler() { WebInspector.inspectorView.panel(panelName).then(WebInspector.inspectorView.setCurrentPanel.bind(WebInspector.inspectorView)); } } /** * @param {!Runtime.Extension} extension * @return {!WebInspector.CommandMenu.Command} */ WebInspector.CommandMenu.createRevealDrawerCommand = function(extension) { var drawerId = extension.descriptor()["name"]; var executeHandler = WebInspector.inspectorView.showViewInDrawer.bind(WebInspector.inspectorView, drawerId); var tags = extension.descriptor()["tags"] || ""; return WebInspector.CommandMenu.createCommand(WebInspector.UIString("Drawer"), tags, WebInspector.UIString("Show %s", extension.title(WebInspector.platform())), "", executeHandler); } /** @type {!WebInspector.CommandMenu} */ WebInspector.commandMenu = new WebInspector.CommandMenu(); /** * @constructor * @implements {WebInspector.ActionDelegate} */ WebInspector.CommandMenu.ShowActionDelegate = function() { } WebInspector.CommandMenu.ShowActionDelegate.prototype = { /** * @override * @param {!WebInspector.Context} context * @param {string} actionId * @return {boolean} */ handleAction: function(context, actionId) { new WebInspector.FilteredListWidget(new WebInspector.CommandMenuDelegate(), false).showAsDialog(); InspectorFrontendHost.bringToFront(); return true; } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 | 2 1 | /*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columnsArray
* @param {function(!WebInspector.DataGridNode, string, string, string)=} editCallback
* @param {function(!WebInspector.DataGridNode)=} deleteCallback
* @param {function()=} refreshCallback
* @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} contextMenuCallback
*/
WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback)
{
this.element = createElementWithClass("div", "data-grid");
WebInspector.appendStyle(this.element, "ui_lazy/dataGrid.css");
this.element.tabIndex = 0;
this.element.addEventListener("keydown", this._keyDown.bind(this), false);
var headerContainer = createElementWithClass("div", "header-container");
/** @type {!Element} */
this._headerTable = headerContainer.createChild("table", "header");
/** @type {!Object.<string, !Element>} */
this._headerTableHeaders = {};
/** @type {!Element} */
this._scrollContainer = createElementWithClass("div", "data-container");
/** @type {!Element} */
this._dataTable = this._scrollContainer.createChild("table", "data");
this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this));
this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true);
this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true);
// FIXME: Add a createCallback which is different from editCallback and has different
// behavior when creating a new node.
if (editCallback)
this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
/** @type {function(!WebInspector.DataGridNode, string, string, string)|undefined} */
this._editCallback = editCallback;
/** @type {function(!WebInspector.DataGridNode)|undefined} */
this._deleteCallback = deleteCallback;
/** @type {function()|undefined} */
this._refreshCallback = refreshCallback;
/** @type {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)|undefined} */
this._contextMenuCallback = contextMenuCallback;
this.element.appendChild(headerContainer);
this.element.appendChild(this._scrollContainer);
/** @type {!Element} */
this._headerRow = createElement("tr");
/** @type {!Element} */
this._headerTableColumnGroup = createElement("colgroup");
/** @type {!Element} */
this._dataTableColumnGroup = createElement("colgroup");
/** @type {!Element} */
this._topFillerRow = createElementWithClass("tr", "data-grid-filler-row revealed");
/** @type {!Element} */
this._bottomFillerRow = createElementWithClass("tr", "data-grid-filler-row revealed");
this.setVerticalPadding(0, 0);
/** @type {boolean} */
this._inline = false;
/** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */
this._columnsArray = columnsArray;
/** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */
this._visibleColumnsArray = columnsArray;
/** @type {!Object.<string, !WebInspector.DataGrid.ColumnDescriptor>} */
this._columns = {};
/** @type {?string} */
this._cellClass = null;
for (var i = 0; i < columnsArray.length; ++i) {
var column = columnsArray[i];
var columnIdentifier = column.identifier = column.id || String(i);
this._columns[columnIdentifier] = column;
if (column.disclosure)
this.disclosureColumnIdentifier = columnIdentifier;
var cell = createElement("th");
cell.className = columnIdentifier + "-column";
cell.columnIdentifier = String(columnIdentifier);
this._headerTableHeaders[columnIdentifier] = cell;
var div = createElement("div");
if (column.titleDOMFragment)
div.appendChild(column.titleDOMFragment);
else
div.textContent = column.title;
cell.appendChild(div);
if (column.sort) {
cell.classList.add(column.sort);
this._sortColumnCell = cell;
}
if (column.sortable) {
cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
cell.classList.add("sortable");
cell.createChild("div", "sort-order-icon-container").createChild("div", "sort-order-icon");
}
}
this._headerTable.appendChild(this._headerTableColumnGroup);
this.headerTableBody.appendChild(this._headerRow);
this._dataTable.appendChild(this._dataTableColumnGroup);
this.dataTableBody.appendChild(this._topFillerRow);
this.dataTableBody.appendChild(this._bottomFillerRow);
this._refreshHeader();
/** @type {boolean} */
this._editing = false;
/** @type {?WebInspector.DataGridNode} */
this.selectedNode = null;
/** @type {boolean} */
this.expandNodesWhenArrowing = false;
this.setRootNode(new WebInspector.DataGridNode());
/** @type {number} */
this.indentWidth = 15;
/** @type {!Array.<!Element|{__index: number, __position: number}>} */
this._resizers = [];
/** @type {boolean} */
this._columnWidthsInitialized = false;
/** @type {number} */
this._cornerWidth = WebInspector.DataGrid.CornerWidth;
/** @type {!WebInspector.DataGrid.ResizeMethod} */
this._resizeMethod = WebInspector.DataGrid.ResizeMethod.Nearest;
}
// Keep in sync with .data-grid col.corner style rule.
WebInspector.DataGrid.CornerWidth = 14;
/**
* @typedef {{
* id: string,
* title: string,
* sortable: boolean,
* sort: (?WebInspector.DataGrid.Order|undefined),
* align: (?WebInspector.DataGrid.Align|undefined),
* fixedWidth: (boolean|undefined),
* editable: (boolean|undefined),
* nonSelectable: (boolean|undefined),
* longText: (boolean|undefined),
* disclosure: (boolean|undefined),
* identifier: (string|undefined),
* weight: (number|undefined)
* }}
*/
WebInspector.DataGrid.ColumnDescriptor;
WebInspector.DataGrid.Events = {
SelectedNode: "SelectedNode",
DeselectedNode: "DeselectedNode",
SortingChanged: "SortingChanged",
ColumnsResized: "ColumnsResized"
}
/** @enum {string} */
WebInspector.DataGrid.Order = {
Ascending: "sort-ascending",
Descending: "sort-descending"
}
/** @enum {string} */
WebInspector.DataGrid.Align = {
Center: "center",
Right: "right"
}
WebInspector.DataGrid._preferredWidthSymbol = Symbol("preferredWidth");
WebInspector.DataGrid.prototype = {
/**
* @param {string} cellClass
*/
setCellClass: function(cellClass)
{
this._cellClass = cellClass;
},
_refreshHeader: function()
{
this._headerTableColumnGroup.removeChildren();
this._dataTableColumnGroup.removeChildren();
this._headerRow.removeChildren();
this._topFillerRow.removeChildren();
this._bottomFillerRow.removeChildren();
for (var i = 0; i < this._visibleColumnsArray.length; ++i) {
var column = this._visibleColumnsArray[i];
var columnIdentifier = column.identifier || String(i);
var headerColumn = this._headerTableColumnGroup.createChild("col");
var dataColumn = this._dataTableColumnGroup.createChild("col");
if (column.width) {
headerColumn.style.width = column.width;
dataColumn.style.width = column.width;
}
this._headerRow.appendChild(this._headerTableHeaders[columnIdentifier]);
this._topFillerRow.createChild("td", "top-filler-td");
this._bottomFillerRow.createChild("td", "bottom-filler-td").columnIdentifier_ = columnIdentifier;
}
this._headerRow.createChild("th", "corner");
this._topFillerRow.createChild("td", "corner").classList.add("top-filler-td");
this._bottomFillerRow.createChild("td", "corner").classList.add("bottom-filler-td");
this._headerTableColumnGroup.createChild("col", "corner");
this._dataTableColumnGroup.createChild("col", "corner");
},
/**
* @param {number} top
* @param {number} bottom
* @protected
*/
setVerticalPadding: function(top, bottom)
{
this._topFillerRow.style.height = top + "px";
if (top || bottom)
this._bottomFillerRow.style.height = bottom + "px";
else
this._bottomFillerRow.style.height = "auto";
},
/**
* @param {!WebInspector.DataGridNode} rootNode
* @protected
*/
setRootNode: function(rootNode)
{
if (this._rootNode) {
this._rootNode.removeChildren();
this._rootNode.dataGrid = null;
this._rootNode._isRoot = false;
}
/** @type {!WebInspector.DataGridNode} */
this._rootNode = rootNode;
rootNode._isRoot = true;
rootNode.hasChildren = false;
rootNode._expanded = true;
rootNode._revealed = true;
rootNode.selectable = false;
rootNode.dataGrid = this;
},
/**
* @return {!WebInspector.DataGridNode}
*/
rootNode: function()
{
return this._rootNode;
},
_ondblclick: function(event)
{
if (this._editing || this._editingNode)
return;
var columnIdentifier = this.columnIdentifierFromNode(event.target);
if (!columnIdentifier || !this._columns[columnIdentifier].editable)
return;
this._startEditing(event.target);
},
/**
* @param {!WebInspector.DataGridNode} node
* @param {number} cellIndex
*/
_startEditingColumnOfDataGridNode: function(node, cellIndex)
{
this._editing = true;
/** @type {?WebInspector.DataGridNode} */
this._editingNode = node;
this._editingNode.select();
var element = this._editingNode._element.children[cellIndex];
WebInspector.InplaceEditor.startEditing(element, this._startEditingConfig(element));
element.getComponentSelection().setBaseAndExtent(element, 0, element, 1);
},
_startEditing: function(target)
{
var element = target.enclosingNodeOrSelfWithNodeName("td");
if (!element)
return;
this._editingNode = this.dataGridNodeFromNode(target);
if (!this._editingNode) {
if (!this.creationNode)
return;
this._editingNode = this.creationNode;
}
// Force editing the 1st column when editing the creation node
if (this._editingNode.isCreationNode)
return this._startEditingColumnOfDataGridNode(this._editingNode, this._nextEditableColumn(-1));
this._editing = true;
WebInspector.InplaceEditor.startEditing(element, this._startEditingConfig(element));
element.getComponentSelection().setBaseAndExtent(element, 0, element, 1);
},
renderInline: function()
{
this.element.classList.add("inline");
this._cornerWidth = 0;
this._inline = true;
this.updateWidths();
},
_startEditingConfig: function(element)
{
return new WebInspector.InplaceEditor.Config(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
},
_editingCommitted: function(element, newText, oldText, context, moveDirection)
{
var columnIdentifier = this.columnIdentifierFromNode(element);
if (!columnIdentifier) {
this._editingCancelled(element);
return;
}
var column = this._columns[columnIdentifier];
var cellIndex = this._visibleColumnsArray.indexOf(column);
var textBeforeEditing = this._editingNode.data[columnIdentifier];
var currentEditingNode = this._editingNode;
/**
* @param {boolean} wasChange
* @this {WebInspector.DataGrid}
*/
function moveToNextIfNeeded(wasChange)
{
if (!moveDirection)
return;
if (moveDirection === "forward") {
var firstEditableColumn = this._nextEditableColumn(-1);
if (currentEditingNode.isCreationNode && cellIndex === firstEditableColumn && !wasChange)
return;
var nextEditableColumn = this._nextEditableColumn(cellIndex);
if (nextEditableColumn !== -1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, nextEditableColumn);
var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, firstEditableColumn);
if (currentEditingNode.isCreationNode && wasChange) {
this.addCreationNode(false);
return this._startEditingColumnOfDataGridNode(this.creationNode, firstEditableColumn);
}
return;
}
if (moveDirection === "backward") {
var prevEditableColumn = this._nextEditableColumn(cellIndex, true);
if (prevEditableColumn !== -1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, prevEditableColumn);
var lastEditableColumn = this._nextEditableColumn(this._visibleColumnsArray.length, true);
var nextDataGridNode = currentEditingNode.traversePreviousNode(true, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, lastEditableColumn);
return;
}
}
if (textBeforeEditing == newText) {
this._editingCancelled(element);
moveToNextIfNeeded.call(this, false);
return;
}
// Update the text in the datagrid that we typed
this._editingNode.data[columnIdentifier] = newText;
// Make the callback - expects an editing node (table row), the column number that is being edited,
// the text that used to be there, and the new text.
this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);
if (this._editingNode.isCreationNode)
this.addCreationNode(false);
this._editingCancelled(element);
moveToNextIfNeeded.call(this, true);
},
_editingCancelled: function(element)
{
this._editing = false;
this._editingNode = null;
},
/**
* @param {number} cellIndex
* @param {boolean=} moveBackward
* @return {number}
*/
_nextEditableColumn: function(cellIndex, moveBackward)
{
var increment = moveBackward ? -1 : 1;
var columns = this._visibleColumnsArray;
for (var i = cellIndex + increment; (i >= 0) && (i < columns.length); i += increment) {
if (columns[i].editable)
return i;
}
return -1;
},
/**
* @return {?string}
*/
sortColumnIdentifier: function()
{
if (!this._sortColumnCell)
return null;
return this._sortColumnCell.columnIdentifier;
},
/**
* @return {?string}
*/
sortOrder: function()
{
if (!this._sortColumnCell || this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Ascending))
return WebInspector.DataGrid.Order.Ascending;
if (this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Descending))
return WebInspector.DataGrid.Order.Descending;
return null;
},
/**
* @return {boolean}
*/
isSortOrderAscending: function()
{
return !this._sortColumnCell || this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Ascending);
},
get headerTableBody()
{
if ("_headerTableBody" in this)
return this._headerTableBody;
this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0];
if (!this._headerTableBody) {
this._headerTableBody = this.element.ownerDocument.createElement("tbody");
this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot);
}
return this._headerTableBody;
},
get dataTableBody()
{
if ("_dataTableBody" in this)
return this._dataTableBody;
this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0];
if (!this._dataTableBody) {
this._dataTableBody = this.element.ownerDocument.createElement("tbody");
this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot);
}
return this._dataTableBody;
},
/**
* @param {!Array.<number>} widths
* @param {number} minPercent
* @param {number=} maxPercent
* @return {!Array.<number>}
*/
_autoSizeWidths: function(widths, minPercent, maxPercent)
{
if (minPercent)
minPercent = Math.min(minPercent, Math.floor(100 / widths.length));
var totalWidth = 0;
for (var i = 0; i < widths.length; ++i)
totalWidth += widths[i];
var totalPercentWidth = 0;
for (var i = 0; i < widths.length; ++i) {
var width = Math.round(100 * widths[i] / totalWidth);
if (minPercent && width < minPercent)
width = minPercent;
else if (maxPercent && width > maxPercent)
width = maxPercent;
totalPercentWidth += width;
widths[i] = width;
}
var recoupPercent = totalPercentWidth - 100;
while (minPercent && recoupPercent > 0) {
for (var i = 0; i < widths.length; ++i) {
if (widths[i] > minPercent) {
--widths[i];
--recoupPercent;
if (!recoupPercent)
break;
}
}
}
while (maxPercent && recoupPercent < 0) {
for (var i = 0; i < widths.length; ++i) {
if (widths[i] < maxPercent) {
++widths[i];
++recoupPercent;
if (!recoupPercent)
break;
}
}
}
return widths;
},
/**
* @param {number} minPercent
* @param {number=} maxPercent
* @param {number=} maxDescentLevel
*/
autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
{
var widths = [];
for (var i = 0; i < this._columnsArray.length; ++i)
widths.push((this._columnsArray[i].title || "").length);
maxDescentLevel = maxDescentLevel || 0;
var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
for (var i = 0; i < children.length; ++i) {
var node = children[i];
for (var j = 0; j < this._columnsArray.length; ++j) {
var text = node.data[this._columnsArray[j].identifier] || "";
if (text.length > widths[j])
widths[j] = text.length;
}
}
widths = this._autoSizeWidths(widths, minPercent, maxPercent);
for (var i = 0; i < this._columnsArray.length; ++i)
this._columnsArray[i].weight = widths[i];
this._columnWidthsInitialized = false;
this.updateWidths();
},
_enumerateChildren: function(rootNode, result, maxLevel)
{
if (!rootNode._isRoot)
result.push(rootNode);
if (!maxLevel)
return;
for (var i = 0; i < rootNode.children.length; ++i)
this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
return result;
},
onResize: function()
{
this.updateWidths();
},
// Updates the widths of the table, including the positions of the column
// resizers.
//
// IMPORTANT: This function MUST be called once after the element of the
// DataGrid is attached to its parent element and every subsequent time the
// width of the parent element is changed in order to make it possible to
// resize the columns.
//
// If this function is not called after the DataGrid is attached to its
// parent element, then the DataGrid's columns will not be resizable.
updateWidths: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
// Use container size to avoid changes of table width caused by change of column widths.
var tableWidth = this.element.offsetWidth - this._cornerWidth;
var numColumns = headerTableColumns.length - 1; // Do not process corner column.
// Do not attempt to use offsetes if we're not attached to the document tree yet.
if (!this._columnWidthsInitialized && this.element.offsetWidth) {
// Give all the columns initial widths now so that during a resize,
// when the two columns that get resized get a percent value for
// their widths, all the other columns already have percent values
// for their widths.
for (var i = 0; i < numColumns; i++) {
var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
var column = this._visibleColumnsArray[i];
if (!column.weight)
column.weight = 100 * columnWidth / tableWidth;
}
this._columnWidthsInitialized = true;
}
this._applyColumnWeights();
},
/**
* @param {string} name
*/
setName: function(name)
{
this._columnWeightsSetting = WebInspector.settings.createSetting("dataGrid-" + name + "-columnWeights", {});
this._loadColumnWeights();
},
_loadColumnWeights: function()
{
if (!this._columnWeightsSetting)
return;
var weights = this._columnWeightsSetting.get();
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
var weight = weights[column.identifier];
if (weight)
column.weight = weight;
}
this._applyColumnWeights();
},
_saveColumnWeights: function()
{
if (!this._columnWeightsSetting)
return;
var weights = {};
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
weights[column.identifier] = column.weight;
}
this._columnWeightsSetting.set(weights);
},
wasShown: function()
{
this._loadColumnWeights();
},
willHide: function()
{
},
_applyColumnWeights: function()
{
var tableWidth = this.element.offsetWidth - this._cornerWidth;
if (tableWidth <= 0)
return;
var sumOfWeights = 0.0;
var fixedColumnWidths = [];
for (var i = 0; i < this._visibleColumnsArray.length; ++i) {
var column = this._visibleColumnsArray[i];
if (column.fixedWidth) {
var width = this._headerTableColumnGroup.children[i][WebInspector.DataGrid._preferredWidthSymbol] || this.headerTableBody.rows[0].cells[i].offsetWidth;
fixedColumnWidths[i] = width;
tableWidth -= width;
} else {
sumOfWeights += this._visibleColumnsArray[i].weight;
}
}
var sum = 0;
var lastOffset = 0;
for (var i = 0; i < this._visibleColumnsArray.length; ++i) {
var column = this._visibleColumnsArray[i];
var width;
if (column.fixedWidth) {
width = fixedColumnWidths[i];
} else {
sum += column.weight;
var offset = (sum * tableWidth / sumOfWeights) | 0;
width = offset - lastOffset;
lastOffset = offset;
}
this._setPreferredWidth(i, width);
}
this._positionResizers();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},
/**
* @param {!Object.<string, boolean>} columnsVisibility
*/
setColumnsVisiblity: function(columnsVisibility)
{
this._visibleColumnsArray = [];
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
if (columnsVisibility[column.identifier || String(i)])
this._visibleColumnsArray.push(column);
}
this._refreshHeader();
this._applyColumnWeights();
var nodes = this._enumerateChildren(this.rootNode(), [], -1);
for (var i = 0; i < nodes.length; ++i)
nodes[i].refresh();
},
get scrollContainer()
{
return this._scrollContainer;
},
_positionResizers: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length - 1; // Do not process corner column.
var left = [];
var resizers = this._resizers;
while (resizers.length > numColumns - 1)
resizers.pop().remove();
for (var i = 0; i < numColumns - 1; i++) {
// Get the width of the cell in the first (and only) row of the
// header table in order to determine the width of the column, since
// it is not possible to query a column for its width.
left[i] = (left[i-1] || 0) + this.headerTableBody.rows[0].cells[i].offsetWidth;
}
// Make n - 1 resizers for n columns.
for (var i = 0; i < numColumns - 1; i++) {
var resizer = resizers[i];
if (!resizer) {
// This is the first call to updateWidth, so the resizers need
// to be created.
resizer = createElement("div");
resizer.__index = i;
resizer.classList.add("data-grid-resizer");
// This resizer is associated with the column to its right.
WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
this.element.appendChild(resizer);
resizers.push(resizer);
}
if (resizer.__position !== left[i]) {
resizer.__position = left[i];
resizer.style.left = left[i] + "px";
}
}
},
addCreationNode: function(hasChildren)
{
if (this.creationNode)
this.creationNode.makeNormal();
var emptyData = {};
for (var column in this._columns)
emptyData[column] = null;
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.rootNode().appendChild(this.creationNode);
},
_keyDown: function(event)
{
if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
return;
var handled = false;
var nextSelectedNode;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedNode = this.selectedNode.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedNode.expanded) {
if (event.altKey)
this.selectedNode.collapseRecursively();
else
this.selectedNode.collapse();
handled = true;
} else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) {
handled = true;
if (this.selectedNode.parent.selectable) {
nextSelectedNode = this.selectedNode.parent;
handled = nextSelectedNode ? true : false;
} else if (this.selectedNode.parent)
this.selectedNode.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedNode.revealed) {
this.selectedNode.reveal();
handled = true;
} else if (this.selectedNode.hasChildren) {
handled = true;
if (this.selectedNode.expanded) {
nextSelectedNode = this.selectedNode.children[0];
handled = nextSelectedNode ? true : false;
} else {
if (event.altKey)
this.selectedNode.expandRecursively();
else
this.selectedNode.expand();
}
}
} else if (event.keyCode === 8 || event.keyCode === 46) {
if (this._deleteCallback) {
handled = true;
this._deleteCallback(this.selectedNode);
}
} else if (isEnterKey(event)) {
if (this._editCallback) {
handled = true;
this._startEditing(this.selectedNode._element.children[this._nextEditableColumn(-1)]);
}
}
if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}
if (handled)
event.consume(true);
},
/**
* @param {?WebInspector.DataGridNode} root
* @param {boolean} onlyAffectsSubtree
*/
updateSelectionBeforeRemoval: function(root, onlyAffectsSubtree)
{
var ancestor = this.selectedNode;
while (ancestor && ancestor !== root)
ancestor = ancestor.parent;
// Selection is not in the subtree being deleted.
if (!ancestor)
return;
var nextSelectedNode;
// Skip subtree being deleted when looking for the next selectable node.
for (ancestor = root; ancestor && !ancestor.nextSibling; ancestor = ancestor.parent) { }
if (ancestor)
nextSelectedNode = ancestor.nextSibling;
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);
if (!nextSelectedNode || nextSelectedNode.isCreationNode) {
nextSelectedNode = root.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
}
if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
} else {
this.selectedNode.deselect();
}
},
/**
* @param {!Node} target
* @return {?WebInspector.DataGridNode}
*/
dataGridNodeFromNode: function(target)
{
var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},
/**
* @param {!Node} target
* @return {?string}
*/
columnIdentifierFromNode: function(target)
{
var cellElement = target.enclosingNodeOrSelfWithNodeName("td");
return cellElement && cellElement.columnIdentifier_;
},
_clickInHeaderCell: function(event)
{
var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
if (!cell || (cell.columnIdentifier === undefined) || !cell.classList.contains("sortable"))
return;
var sortOrder = WebInspector.DataGrid.Order.Ascending;
if ((cell === this._sortColumnCell) && this.isSortOrderAscending())
sortOrder = WebInspector.DataGrid.Order.Descending;
if (this._sortColumnCell)
this._sortColumnCell.classList.remove(WebInspector.DataGrid.Order.Ascending, WebInspector.DataGrid.Order.Descending);
this._sortColumnCell = cell;
cell.classList.add(sortOrder);
this.dispatchEventToListeners(WebInspector.DataGrid.Events.SortingChanged);
},
/**
* @param {string} columnIdentifier
* @param {!WebInspector.DataGrid.Order} sortOrder
*/
markColumnAsSortedBy: function(columnIdentifier, sortOrder)
{
if (this._sortColumnCell)
this._sortColumnCell.classList.remove(WebInspector.DataGrid.Order.Ascending, WebInspector.DataGrid.Order.Descending);
this._sortColumnCell = this._headerTableHeaders[columnIdentifier];
this._sortColumnCell.classList.add(sortOrder);
},
/**
* @param {string} columnIdentifier
* @return {!Element}
*/
headerTableHeader: function(columnIdentifier)
{
return this._headerTableHeaders[columnIdentifier];
},
_mouseDownInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.selectable)
return;
if (gridNode.isEventWithinDisclosureTriangle(event))
return;
var columnIdentifier = this.columnIdentifierFromNode(event.target);
if (columnIdentifier && this._columns[columnIdentifier].nonSelectable)
return;
if (event.metaKey) {
if (gridNode.selected)
gridNode.deselect();
else
gridNode.select();
} else
gridNode.select();
},
_contextMenuInDataTable: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
var gridNode = this.dataGridNodeFromNode(event.target);
if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));
if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {
if (this._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^new"), this._startEditing.bind(this, event.target));
else {
var columnIdentifier = this.columnIdentifierFromNode(event.target);
if (columnIdentifier && this._columns[columnIdentifier].editable)
contextMenu.appendItem(WebInspector.UIString("Edit \"%s\"", this._columns[columnIdentifier].title), this._startEditing.bind(this, event.target));
}
}
if (this._deleteCallback && gridNode !== this.creationNode)
contextMenu.appendItem(WebInspector.UIString.capitalize("Delete"), this._deleteCallback.bind(this, gridNode));
if (this._contextMenuCallback)
this._contextMenuCallback(contextMenu, gridNode);
}
contextMenu.show();
},
_clickInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.hasChildren)
return;
if (!gridNode.isEventWithinDisclosureTriangle(event))
return;
if (gridNode.expanded) {
if (event.altKey)
gridNode.collapseRecursively();
else
gridNode.collapse();
} else {
if (event.altKey)
gridNode.expandRecursively();
else
gridNode.expand();
}
},
/**
* @param {!WebInspector.DataGrid.ResizeMethod} method
*/
setResizeMethod: function(method)
{
this._resizeMethod = method;
},
/**
* @return {boolean}
*/
_startResizerDragging: function(event)
{
this._currentResizer = event.target;
return true;
},
_resizerDragging: function(event)
{
var resizer = this._currentResizer;
if (!resizer)
return;
// Constrain the dragpoint to be within the containing div of the
// datagrid.
var dragPoint = event.clientX - this.element.totalOffsetLeft();
var firstRowCells = this.headerTableBody.rows[0].cells;
var leftEdgeOfPreviousColumn = 0;
// Constrain the dragpoint to be within the space made up by the
// column directly to the left and the column directly to the right.
var leftCellIndex = resizer.__index;
var rightCellIndex = leftCellIndex + 1;
for (var i = 0; i < leftCellIndex; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
// Differences for other resize methods
if (this._resizeMethod === WebInspector.DataGrid.ResizeMethod.Last) {
rightCellIndex = this._resizers.length;
} else if (this._resizeMethod === WebInspector.DataGrid.ResizeMethod.First) {
leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
leftCellIndex = 0;
}
var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;
// Give each column some padding so that they don't disappear.
var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;
if (leftMinimum > rightMaximum)
return;
dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
var position = (dragPoint - this.CenterResizerOverBorderAdjustment);
resizer.__position = position;
resizer.style.left = position + "px";
this._setPreferredWidth(leftCellIndex, dragPoint - leftEdgeOfPreviousColumn);
this._setPreferredWidth(rightCellIndex, rightEdgeOfNextColumn - dragPoint);
var leftColumn = this._visibleColumnsArray[leftCellIndex];
var rightColumn = this._visibleColumnsArray[rightCellIndex];
if (leftColumn.weight || rightColumn.weight) {
var sumOfWeights = leftColumn.weight + rightColumn.weight;
var delta = rightEdgeOfNextColumn - leftEdgeOfPreviousColumn;
leftColumn.weight = (dragPoint - leftEdgeOfPreviousColumn) * sumOfWeights / delta;
rightColumn.weight = (rightEdgeOfNextColumn - dragPoint) * sumOfWeights / delta;
}
this._positionResizers();
event.preventDefault();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},
/**
* @param {number} columnIndex
* @param {number} width
*/
_setPreferredWidth: function(columnIndex, width)
{
var pxWidth = width + "px";
this._headerTableColumnGroup.children[columnIndex][WebInspector.DataGrid._preferredWidthSymbol] = width;
this._headerTableColumnGroup.children[columnIndex].style.width = pxWidth;
this._dataTableColumnGroup.children[columnIndex].style.width = pxWidth;
},
/**
* @param {string} columnId
* @return {number}
*/
columnOffset: function(columnId)
{
if (!this.element.offsetWidth)
return 0;
for (var i = 1; i < this._visibleColumnsArray.length; ++i) {
if (columnId === this._visibleColumnsArray[i].identifier) {
if (this._resizers[i - 1])
return this._resizers[i - 1].__position;
}
}
return 0;
},
_endResizerDragging: function(event)
{
this._currentResizer = null;
this._saveColumnWeights();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},
/**
* @return {!WebInspector.DataGridWidget}
*/
asWidget: function()
{
if (!this._dataGridWidget)
this._dataGridWidget = new WebInspector.DataGridWidget(this);
return this._dataGridWidget;
},
ColumnResizePadding: 24,
CenterResizerOverBorderAdjustment: 3,
__proto__: WebInspector.Object.prototype
}
/** @enum {string} */
WebInspector.DataGrid.ResizeMethod = {
Nearest: "nearest",
First: "first",
Last: "last"
}
/**
* @constructor
* @extends {WebInspector.Object}
* @param {?Object.<string, *>=} data
* @param {boolean=} hasChildren
*/
WebInspector.DataGridNode = function(data, hasChildren)
{
/** @type {?Element} */
this._element = null;
/** @type {boolean} */
this._expanded = false;
/** @type {boolean} */
this._selected = false;
/** @type {number|undefined} */
this._depth;
/** @type {boolean|undefined} */
this._revealed;
/** @type {boolean} */
this._attached = false;
/** @type {?{parent: !WebInspector.DataGridNode, index: number}} */
this._savedPosition = null;
/** @type {boolean} */
this._shouldRefreshChildren = true;
/** @type {!Object.<string, *>} */
this._data = data || {};
/** @type {boolean} */
this.hasChildren = hasChildren || false;
/** @type {!Array.<!WebInspector.DataGridNode>} */
this.children = [];
/** @type {?WebInspector.DataGrid} */
this.dataGrid = null;
/** @type {?WebInspector.DataGridNode} */
this.parent = null;
/** @type {?WebInspector.DataGridNode} */
this.previousSibling = null;
/** @type {?WebInspector.DataGridNode} */
this.nextSibling = null;
/** @type {number} */
this.disclosureToggleWidth = 10;
}
WebInspector.DataGridNode.prototype = {
/** @type {boolean} */
selectable: true,
/** @type {boolean} */
_isRoot: false,
/**
* @return {!Element}
*/
element: function()
{
if (!this._element) {
this.createElement();
this.createCells();
}
return /** @type {!Element} */ (this._element);
},
/**
* @protected
*/
createElement: function()
{
this._element = createElement("tr");
this._element._dataGridNode = this;
if (this.hasChildren)
this._element.classList.add("parent");
if (this.expanded)
this._element.classList.add("expanded");
if (this.selected)
this._element.classList.add("selected");
if (this.revealed)
this._element.classList.add("revealed");
},
/**
* @protected
*/
createCells: function()
{
this._element.removeChildren();
var columnsArray = this.dataGrid._visibleColumnsArray;
for (var i = 0; i < columnsArray.length; ++i)
this._element.appendChild(this.createCell(columnsArray[i].identifier || String(i)));
this._element.appendChild(this._createTDWithClass("corner"));
},
get data()
{
return this._data;
},
set data(x)
{
this._data = x || {};
this.refresh();
},
get revealed()
{
if (this._revealed !== undefined)
return this._revealed;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded) {
this._revealed = false;
return false;
}
currentAncestor = currentAncestor.parent;
}
this._revealed = true;
return true;
},
set hasChildren(x)
{
if (this._hasChildren === x)
return;
this._hasChildren = x;
if (!this._element)
return;
this._element.classList.toggle("parent", this._hasChildren);
this._element.classList.toggle("expanded", this._hasChildren && this.expanded);
},
get hasChildren()
{
return this._hasChildren;
},
set revealed(x)
{
if (this._revealed === x)
return;
this._revealed = x;
if (this._element)
this._element.classList.toggle("revealed", this._revealed);
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = x && this.expanded;
},
/**
* @return {number}
*/
get depth()
{
if (this._depth !== undefined)
return this._depth;
if (this.parent && !this.parent._isRoot)
this._depth = this.parent.depth + 1;
else
this._depth = 0;
return this._depth;
},
get leftPadding()
{
return this.depth * this.dataGrid.indentWidth;
},
get shouldRefreshChildren()
{
return this._shouldRefreshChildren;
},
set shouldRefreshChildren(x)
{
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},
get selected()
{
return this._selected;
},
set selected(x)
{
if (x)
this.select();
else
this.deselect();
},
get expanded()
{
return this._expanded;
},
/**
* @param {boolean} x
*/
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
refresh: function()
{
if (!this.dataGrid)
this._element = null;
if (!this._element)
return;
this.createCells();
},
/**
* @param {string} className
* @return {!Element}
*/
_createTDWithClass: function(className)
{
var cell = createElementWithClass("td", className);
var cellClass = this.dataGrid._cellClass;
if (cellClass)
cell.classList.add(cellClass);
return cell;
},
/**
* @param {string} columnIdentifier
* @return {!Element}
*/
createTD: function(columnIdentifier)
{
var cell = this._createTDWithClass(columnIdentifier + "-column");
cell.columnIdentifier_ = columnIdentifier;
var alignment = this.dataGrid._columns[columnIdentifier].align;
if (alignment)
cell.classList.add(alignment);
if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.classList.add("disclosure");
if (this.leftPadding)
cell.style.setProperty("padding-left", this.leftPadding + "px");
}
return cell;
},
/**
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = this.createTD(columnIdentifier);
var data = this.data[columnIdentifier];
if (data instanceof Node) {
cell.appendChild(data);
} else {
cell.textContent = data;
if (this.dataGrid._columns[columnIdentifier].longText)
cell.title = data;
}
return cell;
},
/**
* @return {number}
*/
nodeSelfHeight: function()
{
return 16;
},
/**
* @param {!WebInspector.DataGridNode} child
*/
appendChild: function(child)
{
this.insertChild(child, this.children.length);
},
/**
* @param {!WebInspector.DataGridNode} child
* @param {number} index
*/
insertChild: function(child, index)
{
if (!child)
throw("insertChild: Node can't be undefined or null.");
if (child.parent === this) {
var currentIndex = this.children.indexOf(child);
if (currentIndex < 0)
console.assert(false, "Inconsistent DataGrid state");
if (currentIndex === index)
return;
if (currentIndex < index)
--index;
}
child.remove();
this.children.splice(index, 0, child);
this.hasChildren = true;
child.parent = this;
child.dataGrid = this.dataGrid;
child.recalculateSiblings(index);
child._depth = undefined;
child._revealed = undefined;
child._attached = false;
child._shouldRefreshChildren = true;
var current = child.children[0];
while (current) {
current.dataGrid = this.dataGrid;
current._depth = undefined;
current._revealed = undefined;
current._attached = false;
current._shouldRefreshChildren = true;
current = current.traverseNextNode(false, child, true);
}
if (this.expanded)
child._attach();
if (!this.revealed)
child.revealed = false;
},
remove: function()
{
if (this.parent)
this.parent.removeChild(this);
},
/**
* @param {!WebInspector.DataGridNode} child
*/
removeChild: function(child)
{
if (!child)
throw("removeChild: Node can't be undefined or null.");
if (child.parent !== this)
throw("removeChild: Node is not a child of this node.");
if (this.dataGrid)
this.dataGrid.updateSelectionBeforeRemoval(child, false);
child._detach();
this.children.remove(child, true);
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
if (this.children.length <= 0)
this.hasChildren = false;
},
removeChildren: function()
{
if (this.dataGrid)
this.dataGrid.updateSelectionBeforeRemoval(this, true);
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child._detach();
child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}
this.children = [];
this.hasChildren = false;
},
/**
* @param {number} myIndex
*/
recalculateSiblings: function(myIndex)
{
if (!this.parent)
return;
var previousChild = this.parent.children[myIndex - 1] || null;
if (previousChild)
previousChild.nextSibling = this;
this.previousSibling = previousChild;
var nextChild = this.parent.children[myIndex + 1] || null;
if (nextChild)
nextChild.previousSibling = this;
this.nextSibling = nextChild;
},
collapse: function()
{
if (this._isRoot)
return;
if (this._element)
this._element.classList.remove("expanded");
this._expanded = false;
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = false;
},
collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextNode(false, this, true);
}
},
populate: function() { },
expand: function()
{
if (!this.hasChildren || this.expanded)
return;
if (this._isRoot)
return;
if (this.revealed && !this._shouldRefreshChildren)
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = true;
if (this._shouldRefreshChildren) {
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();
this.populate();
if (this._attached) {
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
if (this.revealed)
child.revealed = true;
child._attach();
}
}
this._shouldRefreshChildren = false;
}
if (this._element)
this._element.classList.add("expanded");
this._expanded = true;
},
expandRecursively: function()
{
var item = this;
while (item) {
item.expand();
item = item.traverseNextNode(false, this);
}
},
reveal: function()
{
if (this._isRoot)
return;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}
this.element().scrollIntoViewIfNeeded(false);
},
/**
* @param {boolean=} supressSelectedEvent
*/
select: function(supressSelectedEvent)
{
if (!this.dataGrid || !this.selectable || this.selected)
return;
if (this.dataGrid.selectedNode)
this.dataGrid.selectedNode.deselect();
this._selected = true;
this.dataGrid.selectedNode = this;
if (this._element)
this._element.classList.add("selected");
if (!supressSelectedEvent)
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);
},
revealAndSelect: function()
{
if (this._isRoot)
return;
this.reveal();
this.select();
},
/**
* @param {boolean=} supressDeselectedEvent
*/
deselect: function(supressDeselectedEvent)
{
if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
return;
this._selected = false;
this.dataGrid.selectedNode = null;
if (this._element)
this._element.classList.remove("selected");
if (!supressDeselectedEvent)
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);
},
/**
* @param {boolean} skipHidden
* @param {?WebInspector.DataGridNode=} stayWithin
* @param {boolean=} dontPopulate
* @param {!Object=} info
* @return {?WebInspector.DataGridNode}
*/
traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.populate();
if (info)
info.depthChange = 0;
var node = (!skipHidden || this.revealed) ? this.children[0] : null;
if (node && (!skipHidden || this.expanded)) {
if (info)
info.depthChange = 1;
return node;
}
if (this === stayWithin)
return null;
node = (!skipHidden || this.revealed) ? this.nextSibling : null;
if (node)
return node;
node = this;
while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
node = node.parent;
}
if (!node)
return null;
return (!skipHidden || node.revealed) ? node.nextSibling : null;
},
/**
* @param {boolean} skipHidden
* @param {boolean=} dontPopulate
* @return {?WebInspector.DataGridNode}
*/
traversePreviousNode: function(skipHidden, dontPopulate)
{
var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
if (!dontPopulate && node && node.hasChildren)
node.populate();
while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
if (!dontPopulate && node.hasChildren)
node.populate();
node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
}
if (node)
return node;
if (!this.parent || this.parent._isRoot)
return null;
return this.parent;
},
/**
* @return {boolean}
*/
isEventWithinDisclosureTriangle: function(event)
{
if (!this.hasChildren)
return false;
var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell || !cell.classList.contains("disclosure"))
return false;
var left = cell.totalOffsetLeft() + this.leftPadding;
return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
},
_attach: function()
{
if (!this.dataGrid || this._attached)
return;
this._attached = true;
var previousNode = this.traversePreviousNode(true, true);
var previousElement = previousNode ? previousNode.element() : this.dataGrid._topFillerRow;
this.dataGrid.dataTableBody.insertBefore(this.element(), previousElement.nextSibling);
if (this.expanded)
for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();
},
_detach: function()
{
if (!this._attached)
return;
this._attached = false;
if (this._element)
this._element.remove();
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();
this.wasDetached();
},
wasDetached: function()
{
},
savePosition: function()
{
if (this._savedPosition)
return;
if (!this.parent)
throw("savePosition: Node must have a parent.");
this._savedPosition = {
parent: this.parent,
index: this.parent.children.indexOf(this)
};
},
restorePosition: function()
{
if (!this._savedPosition)
return;
if (this.parent !== this._savedPosition.parent)
this._savedPosition.parent.insertChild(this, this._savedPosition.index);
this._savedPosition = null;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @extends {WebInspector.DataGridNode}
*/
WebInspector.CreationDataGridNode = function(data, hasChildren)
{
WebInspector.DataGridNode.call(this, data, hasChildren);
/** @type {boolean} */
this.isCreationNode = true;
}
WebInspector.CreationDataGridNode.prototype = {
makeNormal: function()
{
this.isCreationNode = false;
},
__proto__: WebInspector.DataGridNode.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {!WebInspector.DataGrid} dataGrid
*/
WebInspector.DataGridWidget = function(dataGrid)
{
WebInspector.VBox.call(this);
this._dataGrid = dataGrid;
this.element.appendChild(dataGrid.element);
}
WebInspector.DataGridWidget.prototype = {
/**
* @override
*/
wasShown: function()
{
this._dataGrid.wasShown();
},
/**
* @override
*/
willHide: function()
{
this._dataGrid.willHide();
},
/**
* @override
*/
onResize: function()
{
this._dataGrid.onResize();
},
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
{
return [ this._dataGrid._scrollContainer ];
},
/**
* @override
*/
detachChildWidgets: function()
{
WebInspector.Widget.prototype.detachChildWidgets.call(this);
for (var dataGrid of this._dataGrids)
this.element.removeChild(dataGrid.element);
this._dataGrids = [];
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | 2 1 1 1 | /*
* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.ViewportControl.Provider}
* @param {!WebInspector.FilteredListWidget.Delegate} delegate
* @param {boolean} renderAsTwoRows
*/
WebInspector.FilteredListWidget = function(delegate, renderAsTwoRows)
{
WebInspector.VBox.call(this, true);
this._renderAsTwoRows = renderAsTwoRows;
this.contentElement.classList.add("filtered-list-widget");
this.contentElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.registerRequiredCSS("ui_lazy/filteredListWidget.css");
this._promptElement = this.contentElement.createChild("div", "monospace filtered-list-widget-input");
this._promptElement.setAttribute("spellcheck", "false");
this._promptElement.setAttribute("contenteditable", "plaintext-only");
this._prompt = new WebInspector.TextPrompt(this._autocomplete.bind(this));
this._prompt.renderAsBlock();
this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemAccepted, this._onAutocompleted, this);
var promptProxy = this._prompt.attach(this._promptElement);
promptProxy.addEventListener("input", this._onInput.bind(this), false);
promptProxy.classList.add("filtered-list-widget-prompt-element");
this._filteredItems = [];
this._viewportControl = new WebInspector.ViewportControl(this);
this._itemElementsContainer = this._viewportControl.element;
this._itemElementsContainer.classList.add("container");
this._itemElementsContainer.classList.add("monospace");
this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false);
this.contentElement.appendChild(this._itemElementsContainer);
this.setDefaultFocusedElement(this._promptElement);
this._delegate = delegate;
this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));
this._itemsLoaded();
this._updateShowMatchingItems();
this._viewportControl.refresh();
this._prompt.autoCompleteSoon(true);
}
/**
* @param {string} query
* @return {!RegExp}
*/
WebInspector.FilteredListWidget.filterRegex = function(query)
{
const toEscape = String.regexSpecialCharacters();
var regexString = "";
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (toEscape.indexOf(c) !== -1)
c = "\\" + c;
if (i)
regexString += "[^\\0" + c + "]*";
regexString += c;
}
return new RegExp(regexString, "i");
}
WebInspector.FilteredListWidget.prototype = {
showAsDialog: function()
{
this._dialog = new WebInspector.Dialog();
this._dialog.setMaxSize(new Size(504, 600));
this.show(this._dialog.element);
this._dialog.show();
},
/**
* @return {string}
*/
_value: function()
{
return this._prompt.userEnteredText().trim();
},
willHide: function()
{
this._delegate.dispose();
if (this._filterTimer)
clearTimeout(this._filterTimer);
},
/**
* @param {!Event} event
*/
_onEnter: function(event)
{
event.preventDefault();
if (!this._delegate.itemCount())
return;
var selectedIndex = this._shouldShowMatchingItems() && this._selectedIndexInFiltered < this._filteredItems.length ? this._filteredItems[this._selectedIndexInFiltered] : null;
this._delegate.selectItemWithQuery(selectedIndex, this._value());
if (this._dialog)
this._dialog.detach();
},
_itemsLoaded: function()
{
if (this._loadTimeout)
return;
this._loadTimeout = setTimeout(this._updateAfterItemsLoaded.bind(this), 0);
},
_updateAfterItemsLoaded: function()
{
delete this._loadTimeout;
this._filterItems();
},
/**
* @param {number} index
* @return {!Element}
*/
_createItemElement: function(index)
{
var itemElement = createElement("div");
itemElement.className = "filtered-list-widget-item " + (this._renderAsTwoRows ? "two-rows" : "one-row");
itemElement._titleElement = itemElement.createChild("div", "filtered-list-widget-title");
itemElement._subtitleElement = itemElement.createChild("div", "filtered-list-widget-subtitle");
itemElement._subtitleElement.textContent = "\u200B";
itemElement._index = index;
this._delegate.renderItem(index, this._value(), itemElement._titleElement, itemElement._subtitleElement);
return itemElement;
},
/**
* @param {string} query
*/
setQuery: function(query)
{
this._prompt.setText(query);
this._prompt.autoCompleteSoon(true);
this._scheduleFilter();
},
/**
* @param {!Element} proxyElement
* @param {string} query
* @param {number} cursorOffset
* @param {!Range} wordRange
* @param {boolean} force
* @param {function(!Array.<string>, number=)} completionsReadyCallback
*/
_autocomplete: function(proxyElement, query, cursorOffset, wordRange, force, completionsReadyCallback)
{
var completions = wordRange.startOffset === 0 ? [this._delegate.autocomplete(query)] : [];
completionsReadyCallback.call(null, completions);
this._autocompletedForTests();
},
_autocompletedForTests: function()
{
// Sniffed in tests.
},
_filterItems: function()
{
delete this._filterTimer;
if (this._scoringTimer) {
clearTimeout(this._scoringTimer);
delete this._scoringTimer;
}
var query = this._delegate.rewriteQuery(this._value());
this._query = query;
var filterRegex = query ? WebInspector.FilteredListWidget.filterRegex(query) : null;
var oldSelectedAbsoluteIndex = this._selectedIndexInFiltered ? this._filteredItems[this._selectedIndexInFiltered] : null;
var filteredItems = [];
this._selectedIndexInFiltered = 0;
var bestScores = [];
var bestItems = [];
var bestItemsToCollect = 100;
var minBestScore = 0;
var overflowItems = [];
scoreItems.call(this, 0);
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
function compareIntegers(a, b)
{
return b - a;
}
/**
* @param {number} fromIndex
* @this {WebInspector.FilteredListWidget}
*/
function scoreItems(fromIndex)
{
var maxWorkItems = 1000;
var workDone = 0;
for (var i = fromIndex; i < this._delegate.itemCount() && workDone < maxWorkItems; ++i) {
// Filter out non-matching items quickly.
if (filterRegex && !filterRegex.test(this._delegate.itemKeyAt(i)))
continue;
// Score item.
var score = this._delegate.itemScoreAt(i, query);
if (query)
workDone++;
// Find its index in the scores array (earlier elements have bigger scores).
if (score > minBestScore || bestScores.length < bestItemsToCollect) {
var index = bestScores.upperBound(score, compareIntegers);
bestScores.splice(index, 0, score);
bestItems.splice(index, 0, i);
if (bestScores.length > bestItemsToCollect) {
// Best list is too large -> drop last elements.
overflowItems.push(bestItems.peekLast());
bestScores.length = bestItemsToCollect;
bestItems.length = bestItemsToCollect;
}
minBestScore = bestScores.peekLast();
} else
filteredItems.push(i);
}
// Process everything in chunks.
if (i < this._delegate.itemCount()) {
this._scoringTimer = setTimeout(scoreItems.bind(this, i), 0);
return;
}
delete this._scoringTimer;
this._filteredItems = bestItems.concat(overflowItems).concat(filteredItems);
for (var i = 0; i < this._filteredItems.length; ++i) {
if (this._filteredItems[i] === oldSelectedAbsoluteIndex) {
this._selectedIndexInFiltered = i;
break;
}
}
this._viewportControl.invalidate();
if (!query)
this._selectedIndexInFiltered = 0;
this._updateSelection(this._selectedIndexInFiltered, false);
}
},
/**
* @return {boolean}
*/
_shouldShowMatchingItems: function()
{
return this._delegate.shouldShowMatchingItems(this._value());
},
_onAutocompleted: function()
{
this._prompt.autoCompleteSoon(true);
this._onInput();
},
_onInput: function()
{
this._updateShowMatchingItems();
this._scheduleFilter();
},
_updateShowMatchingItems: function()
{
var shouldShowMatchingItems = this._shouldShowMatchingItems();
this._itemElementsContainer.classList.toggle("hidden", !shouldShowMatchingItems);
},
/**
* @return {number}
*/
_rowsPerViewport: function()
{
return Math.floor(this._viewportControl.element.clientHeight / this._rowHeight);
},
_onKeyDown: function(event)
{
var newSelectedIndex = this._selectedIndexInFiltered;
switch (event.keyCode) {
case WebInspector.KeyboardShortcut.Keys.Down.code:
if (++newSelectedIndex >= this._filteredItems.length)
newSelectedIndex = 0;
this._updateSelection(newSelectedIndex, true);
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.Up.code:
if (--newSelectedIndex < 0)
newSelectedIndex = this._filteredItems.length - 1;
this._updateSelection(newSelectedIndex, false);
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.PageDown.code:
newSelectedIndex = Math.min(newSelectedIndex + this._rowsPerViewport(), this._filteredItems.length - 1);
this._updateSelection(newSelectedIndex, true);
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.PageUp.code:
newSelectedIndex = Math.max(newSelectedIndex - this._rowsPerViewport(), 0);
this._updateSelection(newSelectedIndex, false);
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.Enter.code:
this._onEnter(event);
break;
default:
}
},
_scheduleFilter: function()
{
if (this._filterTimer)
return;
this._filterTimer = setTimeout(this._filterItems.bind(this), 0);
},
/**
* @param {number} index
* @param {boolean} makeLast
*/
_updateSelection: function(index, makeLast)
{
if (!this._filteredItems.length)
return;
if (this._selectedElement)
this._selectedElement.classList.remove("selected");
this._viewportControl.scrollItemIntoView(index, makeLast);
this._selectedIndexInFiltered = index;
this._selectedElement = this._viewportControl.renderedElementAt(index);
if (this._selectedElement)
this._selectedElement.classList.add("selected");
},
_onClick: function(event)
{
var itemElement = event.target.enclosingNodeOrSelfWithClass("filtered-list-widget-item");
if (!itemElement)
return;
this._delegate.selectItemWithQuery(itemElement._index, this._value());
if (this._dialog)
this._dialog.detach();
},
/**
* @override
* @return {number}
*/
itemCount: function()
{
return this._filteredItems.length;
},
/**
* @override
* @param {number} index
* @return {number}
*/
fastHeight: function(index)
{
if (!this._rowHeight) {
var delegateIndex = this._filteredItems[index];
var element = this._createItemElement(delegateIndex);
this._rowHeight = WebInspector.measurePreferredSize(element, this._viewportControl.contentElement()).height;
}
return this._rowHeight;
},
/**
* @override
* @param {number} index
* @return {!WebInspector.ViewportElement}
*/
itemElement: function(index)
{
var delegateIndex = this._filteredItems[index];
var element = this._createItemElement(delegateIndex);
return new WebInspector.StaticViewportElement(element);
},
/**
* @override
* @return {number}
*/
minimumRowHeight: function()
{
return this.fastHeight(0);
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @param {!Array<string>} promptHistory
*/
WebInspector.FilteredListWidget.Delegate = function(promptHistory)
{
this._promptHistory = promptHistory;
}
WebInspector.FilteredListWidget.Delegate.prototype = {
/**
* @param {function():void} refreshCallback
*/
setRefreshCallback: function(refreshCallback)
{
this._refreshCallback = refreshCallback;
},
/**
* @param {string} query
* @return {boolean}
*/
shouldShowMatchingItems: function(query)
{
return true;
},
/**
* @return {number}
*/
itemCount: function()
{
return 0;
},
/**
* @param {number} itemIndex
* @return {string}
*/
itemKeyAt: function(itemIndex)
{
return "";
},
/**
* @param {number} itemIndex
* @param {string} query
* @return {number}
*/
itemScoreAt: function(itemIndex, query)
{
return 1;
},
/**
* @param {number} itemIndex
* @param {string} query
* @param {!Element} titleElement
* @param {!Element} subtitleElement
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
},
/**
* @param {!Element} element
* @param {string} query
* @return {boolean}
*/
highlightRanges: function(element, query)
{
if (!query)
return false;
/**
* @param {string} text
* @param {string} query
* @return {?Array.<!WebInspector.SourceRange>}
*/
function rangesForMatch(text, query)
{
var opcodes = WebInspector.Diff.charDiff(query, text);
var offset = 0;
var ranges = [];
for (var i = 0; i < opcodes.length; ++i) {
var opcode = opcodes[i];
if (opcode[0] === WebInspector.Diff.Operation.Equal)
ranges.push(new WebInspector.SourceRange(offset, opcode[1].length));
else if (opcode[0] !== WebInspector.Diff.Operation.Insert)
return null;
offset += opcode[1].length;
}
return ranges;
}
var text = element.textContent;
var ranges = rangesForMatch(text, query);
if (!ranges || !this.caseSensitive())
ranges = rangesForMatch(text.toUpperCase(), query.toUpperCase());
if (ranges) {
WebInspector.highlightRangesWithStyleClass(element, ranges, "highlight");
return true;
}
return false;
},
/**
* @return {boolean}
*/
caseSensitive: function()
{
return true;
},
/**
* @param {number} itemIndex
* @param {string} promptValue
*/
selectItemWithQuery: function(itemIndex, promptValue)
{
this._promptHistory.push(promptValue);
if (this._promptHistory.length > 100)
this._promptHistory.shift();
this.selectItem(itemIndex, promptValue);
},
/**
* @param {number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
},
refresh: function()
{
this._refreshCallback();
},
/**
* @param {string} query
* @return {string}
*/
rewriteQuery: function(query)
{
return query;
},
/**
* @param {string} query
* @return {string}
*/
autocomplete: function(query)
{
for (var i = this._promptHistory.length - 1; i >= 0; i--) {
if (this._promptHistory[i] !== query && this._promptHistory[i].startsWith(query))
return this._promptHistory[i];
}
return query;
},
dispose: function()
{
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 | 2 1 1 1 1 1 1 1 1 1 1 | /** * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.FlameChartDelegate = function() { } WebInspector.FlameChartDelegate.prototype = { /** * @param {number} startTime * @param {number} endTime */ requestWindowTimes: function(startTime, endTime) { }, /** * @param {number} startTime * @param {number} endTime */ updateRangeSelection: function(startTime, endTime) { }, endRangeSelection: function() { } } /** * @constructor * @extends {WebInspector.HBox} * @param {!WebInspector.FlameChartDataProvider} dataProvider * @param {!WebInspector.FlameChartDelegate} flameChartDelegate * @param {!WebInspector.Setting=} groupExpansionSetting */ WebInspector.FlameChart = function(dataProvider, flameChartDelegate, groupExpansionSetting) { WebInspector.HBox.call(this, true); this.registerRequiredCSS("ui_lazy/flameChart.css"); this.contentElement.classList.add("flame-chart-main-pane"); this._flameChartDelegate = flameChartDelegate; this._groupExpansionSetting = groupExpansionSetting; this._groupExpansionState = groupExpansionSetting && groupExpansionSetting.get() || {}; this._calculator = new WebInspector.FlameChart.Calculator(); this._canvas = this.contentElement.createChild("canvas"); this._canvas.tabIndex = 1; this.setDefaultFocusedElement(this._canvas); this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), false); this._canvas.addEventListener("mouseout", this._onMouseOut.bind(this), false); this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), false); this._canvas.addEventListener("click", this._onClick.bind(this), false); this._canvas.addEventListener("keydown", this._onKeyDown.bind(this), false); WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind(this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "-webkit-grabbing", null); WebInspector.installDragHandle(this._canvas, this._startRangeSelection.bind(this), this._rangeSelectionDragging.bind(this), this._endRangeSelection.bind(this), "text", null); this._vScrollElement = this.contentElement.createChild("div", "flame-chart-v-scroll"); this._vScrollContent = this._vScrollElement.createChild("div"); this._vScrollElement.addEventListener("scroll", this._onScroll.bind(this), false); this._scrollTop = 0; this._entryInfo = this.contentElement.createChild("div", "flame-chart-entry-info"); this._markerHighlighElement = this.contentElement.createChild("div", "flame-chart-marker-highlight-element"); this._highlightElement = this.contentElement.createChild("div", "flame-chart-highlight-element"); this._selectedElement = this.contentElement.createChild("div", "flame-chart-selected-element"); this._selectionOverlay = this.contentElement.createChild("div", "flame-chart-selection-overlay hidden"); this._selectedTimeSpanLabel = this._selectionOverlay.createChild("div", "time-span"); this._dataProvider = dataProvider; this._windowLeft = 0.0; this._windowRight = 1.0; this._timeWindowLeft = 0; this._timeWindowRight = Infinity; this._rangeSelectionStart = 0; this._rangeSelectionEnd = 0; this._barHeight = dataProvider.barHeight(); this._paddingLeft = this._dataProvider.paddingLeft(); var markerPadding = 2; this._markerRadius = this._barHeight / 2 - markerPadding; /** @const */ this._headerLeftPadding = 6; /** @const */ this._arrowSide = 8; /** @const */ this._expansionArrowX = this._headerLeftPadding + this._arrowSide / 2; /** @const */ this._headerLabelXPadding = 3; /** @const */ this._headerLabelYPadding = 2; this._highlightedMarkerIndex = -1; this._highlightedEntryIndex = -1; this._selectedEntryIndex = -1; this._rawTimelineDataLength = 0; /** @type {!Map<string,!Map<string,number>>} */ this._textWidth = new Map(); this._lastMouseOffsetX = 0; } WebInspector.FlameChart.DividersBarHeight = 18; WebInspector.FlameChart.MinimalTimeWindowMs = 0.01; /** * @interface */ WebInspector.FlameChartDataProvider = function() { } /** * @typedef {!{name: string, startLevel: number, expanded: (boolean|undefined), style: !WebInspector.FlameChart.GroupStyle}} */ WebInspector.FlameChart.Group; /** * @typedef {!{ * height: number, * padding: number, * collapsible: boolean, * font: string, * color: string, * backgroundColor: string, * nestingLevel: number, * shareHeaderLine: (boolean|undefined), * useFirstLineForOverview: (boolean|undefined) * }} */ WebInspector.FlameChart.GroupStyle; /** * @constructor * @param {!Array<number>|!Uint8Array} entryLevels * @param {!Array<number>|!Float32Array} entryTotalTimes * @param {!Array<number>|!Float64Array} entryStartTimes * @param {?Array<!WebInspector.FlameChart.Group>} groups */ WebInspector.FlameChart.TimelineData = function(entryLevels, entryTotalTimes, entryStartTimes, groups) { this.entryLevels = entryLevels; this.entryTotalTimes = entryTotalTimes; this.entryStartTimes = entryStartTimes; this.groups = groups; /** @type {!Array.<!WebInspector.FlameChartMarker>} */ this.markers = []; this.flowStartTimes = []; this.flowStartLevels = []; this.flowEndTimes = []; this.flowEndLevels = []; } WebInspector.FlameChartDataProvider.prototype = { /** * @return {number} */ barHeight: function() { }, /** * @param {number} startTime * @param {number} endTime * @return {?Array.<number>} */ dividerOffsets: function(startTime, endTime) { }, /** * @return {number} */ minimumBoundary: function() { }, /** * @return {number} */ totalTime: function() { }, /** * @return {number} */ maxStackDepth: function() { }, /** * @return {?WebInspector.FlameChart.TimelineData} */ timelineData: function() { }, /** * @param {number} entryIndex * @return {?Array.<!{title: string, value: (string|!Element)}>} */ prepareHighlightedEntryInfo: function(entryIndex) { }, /** * @param {number} entryIndex * @return {boolean} */ canJumpToEntry: function(entryIndex) { }, /** * @param {number} entryIndex * @return {?string} */ entryTitle: function(entryIndex) { }, /** * @param {number} entryIndex * @return {?string} */ entryFont: function(entryIndex) { }, /** * @param {number} entryIndex * @return {string} */ entryColor: function(entryIndex) { }, /** * @param {number} entryIndex * @param {!CanvasRenderingContext2D} context * @param {?string} text * @param {number} barX * @param {number} barY * @param {number} barWidth * @param {number} barHeight * @param {number} unclippedBarX * @param {number} timeToPixels * @return {boolean} */ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixels) { }, /** * @param {number} entryIndex * @return {boolean} */ forceDecoration: function(entryIndex) { }, /** * @param {number} entryIndex * @return {string} */ textColor: function(entryIndex) { }, /** * @return {number} */ textBaseline: function() { }, /** * @return {number} */ textPadding: function() { }, /** * @return {?{startTime: number, endTime: number}} */ highlightTimeRange: function(entryIndex) { }, /** * @return {number} */ paddingLeft: function() { }, } /** * @interface */ WebInspector.FlameChartMarker = function() { } WebInspector.FlameChartMarker.prototype = { /** * @return {number} */ startTime: function() { }, /** * @return {string} */ color: function() { }, /** * @return {string} */ title: function() { }, /** * @param {!CanvasRenderingContext2D} context * @param {number} x * @param {number} height * @param {number} pixelsPerMillisecond */ draw: function(context, x, height, pixelsPerMillisecond) { }, } WebInspector.FlameChart.Events = { EntrySelected: "EntrySelected" } /** * @constructor * @param {!{min: number, max: number}|number=} hueSpace * @param {!{min: number, max: number, count: (number|undefined)}|number=} satSpace * @param {!{min: number, max: number, count: (number|undefined)}|number=} lightnessSpace * @param {!{min: number, max: number, count: (number|undefined)}|number=} alphaSpace */ WebInspector.FlameChart.ColorGenerator = function(hueSpace, satSpace, lightnessSpace, alphaSpace) { this._hueSpace = hueSpace || { min: 0, max: 360 }; this._satSpace = satSpace || 67; this._lightnessSpace = lightnessSpace || 80; this._alphaSpace = alphaSpace || 1; /** @type {!Map<string, string>} */ this._colors = new Map(); } WebInspector.FlameChart.ColorGenerator.prototype = { /** * @param {string} id * @param {string} color */ setColorForID: function(id, color) { this._colors.set(id, color); }, /** * @param {string} id * @return {string} */ colorForID: function(id) { var color = this._colors.get(id); if (!color) { color = this._generateColorForID(id); this._colors.set(id, color); } return color; }, /** * @param {string} id * @return {string} */ _generateColorForID: function(id) { var hash = String.hashCode(id); var h = this._indexToValueInSpace(hash, this._hueSpace); var s = this._indexToValueInSpace(hash >> 8, this._satSpace); var l = this._indexToValueInSpace(hash >> 16, this._lightnessSpace); var a = this._indexToValueInSpace(hash >> 24, this._alphaSpace); return "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")"; }, /** * @param {number} index * @param {!{min: number, max: number, count: (number|undefined)}|number} space * @return {number} */ _indexToValueInSpace: function(index, space) { if (typeof space === "number") return space; var count = space.count || space.max - space.min; index %= count; return space.min + Math.floor(index / (count - 1) * (space.max - space.min)); } } /** * @constructor * @implements {WebInspector.TimelineGrid.Calculator} */ WebInspector.FlameChart.Calculator = function() { this._paddingLeft = 0; } WebInspector.FlameChart.Calculator.prototype = { /** * @override * @return {number} */ paddingLeft: function() { return this._paddingLeft; }, /** * @param {!WebInspector.FlameChart} mainPane */ _updateBoundaries: function(mainPane) { this._totalTime = mainPane._dataProvider.totalTime(); this._zeroTime = mainPane._dataProvider.minimumBoundary(); this._minimumBoundaries = this._zeroTime + mainPane._windowLeft * this._totalTime; this._maximumBoundaries = this._zeroTime + mainPane._windowRight * this._totalTime; this._paddingLeft = mainPane._paddingLeft; this._width = mainPane._canvas.width / window.devicePixelRatio - this._paddingLeft; this._timeToPixel = this._width / this.boundarySpan(); }, /** * @override * @param {number} time * @return {number} */ computePosition: function(time) { return Math.round((time - this._minimumBoundaries) * this._timeToPixel + this._paddingLeft); }, /** * @override * @param {number} value * @param {number=} precision * @return {string} */ formatTime: function(value, precision) { return Number.preciseMillisToString(value - this._zeroTime, precision); }, /** * @override * @return {number} */ maximumBoundary: function() { return this._maximumBoundaries; }, /** * @override * @return {number} */ minimumBoundary: function() { return this._minimumBoundaries; }, /** * @override * @return {number} */ zeroTime: function() { return this._zeroTime; }, /** * @override * @return {number} */ boundarySpan: function() { return this._maximumBoundaries - this._minimumBoundaries; } } WebInspector.FlameChart.prototype = { /** * @override */ willHide: function() { this.hideHighlight(); }, /** * @param {number} entryIndex */ highlightEntry: function(entryIndex) { if (this._highlightedEntryIndex === entryIndex) return; this._highlightedEntryIndex = entryIndex; this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex); }, hideHighlight: function() { this._entryInfo.removeChildren(); this._canvas.style.cursor = "default"; this._highlightedEntryIndex = -1; this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex); }, _resetCanvas: function() { var ratio = window.devicePixelRatio; this._canvas.width = this._offsetWidth * ratio; this._canvas.height = this._offsetHeight * ratio; this._canvas.style.width = this._offsetWidth + "px"; this._canvas.style.height = this._offsetHeight + "px"; }, /** * @return {?WebInspector.FlameChart.TimelineData} */ _timelineData: function() { var timelineData = this._dataProvider.timelineData(); if (timelineData !== this._rawTimelineData || timelineData.entryStartTimes.length !== this._rawTimelineDataLength) this._processTimelineData(timelineData); return this._rawTimelineData; }, _cancelAnimation: function() { if (this._cancelWindowTimesAnimation) { this._timeWindowLeft = this._pendingAnimationTimeLeft; this._timeWindowRight = this._pendingAnimationTimeRight; this._cancelWindowTimesAnimation(); delete this._cancelWindowTimesAnimation; } }, /** * @param {number} entryIndex */ _revealEntry: function(entryIndex) { var timelineData = this._timelineData(); if (!timelineData) return; // Think in terms of not where we are, but where we'll be after animation (if present) var timeLeft = this._cancelWindowTimesAnimation ? this._pendingAnimationTimeLeft : this._timeWindowLeft; var timeRight = this._cancelWindowTimesAnimation ? this._pendingAnimationTimeRight : this._timeWindowRight; var entryStartTime = timelineData.entryStartTimes[entryIndex]; var entryTotalTime = timelineData.entryTotalTimes[entryIndex]; var entryEndTime = entryStartTime + entryTotalTime; var minEntryTimeWindow = Math.min(entryTotalTime, timeRight - timeLeft); var y = this._levelToHeight(timelineData.entryLevels[entryIndex]); if (this._vScrollElement.scrollTop > y) this._vScrollElement.scrollTop = y; else if (this._vScrollElement.scrollTop < y - this._offsetHeight + this._barHeight) this._vScrollElement.scrollTop = y - this._offsetHeight + this._barHeight; if (timeLeft > entryEndTime) { var delta = timeLeft - entryEndTime + minEntryTimeWindow; this._flameChartDelegate.requestWindowTimes(timeLeft - delta, timeRight - delta); } else if (timeRight < entryStartTime) { var delta = entryStartTime - timeRight + minEntryTimeWindow; this._flameChartDelegate.requestWindowTimes(timeLeft + delta, timeRight + delta); } }, /** * @param {number} startTime * @param {number} endTime */ setWindowTimes: function(startTime, endTime) { if (this._muteAnimation || this._timeWindowLeft === 0 || this._timeWindowRight === Infinity || (startTime === 0 && endTime === Infinity) || (startTime === Infinity && endTime === Infinity)) { // Initial setup. this._timeWindowLeft = startTime; this._timeWindowRight = endTime; this.scheduleUpdate(); return; } this._cancelAnimation(); this._updateHighlight(); this._cancelWindowTimesAnimation = WebInspector.animateFunction(this.element.window(), this._animateWindowTimes.bind(this), [{from: this._timeWindowLeft, to: startTime}, {from: this._timeWindowRight, to: endTime}], 5, this._animationCompleted.bind(this)); this._pendingAnimationTimeLeft = startTime; this._pendingAnimationTimeRight = endTime; }, /** * @param {number} startTime * @param {number} endTime */ _animateWindowTimes: function(startTime, endTime) { this._timeWindowLeft = startTime; this._timeWindowRight = endTime; this._updateHighlight(); this.update(); }, _animationCompleted: function() { delete this._cancelWindowTimesAnimation; this._updateHighlight(); }, /** * @param {!MouseEvent} event */ _initMaxDragOffset: function(event) { this._maxDragOffsetSquared = 0; this._dragStartX = event.pageX; this._dragStartY = event.pageY; }, /** * @param {!MouseEvent} event */ _updateMaxDragOffset: function(event) { var dx = event.pageX - this._dragStartX; var dy = event.pageY - this._dragStartY; var dragOffsetSquared = dx * dx + dy * dy; this._maxDragOffsetSquared = Math.max(this._maxDragOffsetSquared, dragOffsetSquared); }, /** * @return {number} */ _maxDragOffset: function() { return Math.sqrt(this._maxDragOffsetSquared); }, /** * @param {!MouseEvent} event * @return {boolean} */ _startCanvasDragging: function(event) { if (event.shiftKey) return false; if (!this._timelineData() || this._timeWindowRight === Infinity) return false; this._isDragging = true; this._initMaxDragOffset(event); this._dragStartPointX = event.pageX; this._dragStartPointY = event.pageY; this._dragStartScrollTop = this._vScrollElement.scrollTop; this._dragStartWindowLeft = this._timeWindowLeft; this._dragStartWindowRight = this._timeWindowRight; this._canvas.style.cursor = ""; this.hideHighlight(); return true; }, /** * @param {!MouseEvent} event */ _canvasDragging: function(event) { var pixelShift = this._dragStartPointX - event.pageX; this._dragStartPointX = event.pageX; this._muteAnimation = true; this._handlePanGesture(pixelShift * this._pixelToTime); this._muteAnimation = false; var pixelScroll = this._dragStartPointY - event.pageY; this._vScrollElement.scrollTop = this._dragStartScrollTop + pixelScroll; this._updateMaxDragOffset(event); }, _endCanvasDragging: function() { this._isDragging = false; this._updateHighlight(); }, /** * @param {!MouseEvent} event * @return {boolean} */ _startRangeSelection: function(event) { if (!event.shiftKey) return false; this._isDragging = true; this._initMaxDragOffset(event); this._selectionOffsetShiftX = event.offsetX - event.pageX; this._selectionOffsetShiftY = event.offsetY - event.pageY; this._selectionStartX = event.offsetX; var style = this._selectionOverlay.style; style.left = this._selectionStartX + "px"; style.width = "1px"; this._selectedTimeSpanLabel.textContent = ""; this._selectionOverlay.classList.remove("hidden"); this.hideHighlight(); return true; }, _endRangeSelection: function() { this._isDragging = false; this._flameChartDelegate.endRangeSelection(); this._updateHighlight(); }, _hideRangeSelection: function() { this._selectionOverlay.classList.add("hidden"); }, /** * @param {!MouseEvent} event */ _rangeSelectionDragging: function(event) { this._updateMaxDragOffset(event); var x = Number.constrain(event.pageX + this._selectionOffsetShiftX, 0, this._offsetWidth); var start = this._cursorTime(this._selectionStartX); var end = this._cursorTime(x); this._rangeSelectionStart = Math.min(start, end); this._rangeSelectionEnd = Math.max(start, end); this._updateRangeSelectionOverlay(); this._flameChartDelegate.updateRangeSelection(this._rangeSelectionStart, this._rangeSelectionEnd); }, _updateRangeSelectionOverlay: function() { var /** @const */ margin = 100; var left = Number.constrain(this._timeToPosition(this._rangeSelectionStart), -margin, this._offsetWidth + margin); var right = Number.constrain(this._timeToPosition(this._rangeSelectionEnd), -margin, this._offsetWidth + margin); var style = this._selectionOverlay.style; style.left = left + "px"; style.width = (right - left) + "px"; var timeSpan = this._rangeSelectionEnd - this._rangeSelectionStart; this._selectedTimeSpanLabel.textContent = Number.preciseMillisToString(timeSpan, 2); }, /** * @param {!Event} event */ _onMouseMove: function(event) { this._lastMouseOffsetX = event.offsetX; this._lastMouseOffsetY = event.offsetY; if (!this._enabled()) return; if (this._isDragging) return; if (this._coordinatesToGroupIndex(event.offsetX, event.offsetY) >= 0) { this.hideHighlight(); this._canvas.style.cursor = "pointer"; return; } this._updateHighlight(); }, _updateHighlight: function() { var inDividersBar = this._lastMouseOffsetY < WebInspector.FlameChart.DividersBarHeight; this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPosition(this._lastMouseOffsetX) : -1; this._updateMarkerHighlight(); var entryIndex = this._coordinatesToEntryIndex(this._lastMouseOffsetX, this._lastMouseOffsetY); if (entryIndex === -1) { this.hideHighlight(); return; } this._updatePopover(entryIndex); this._canvas.style.cursor = this._dataProvider.canJumpToEntry(entryIndex) ? "pointer" : "default"; this.highlightEntry(entryIndex); }, _onMouseOut: function() { this._lastMouseOffsetX = -1; this._lastMouseOffsetY = -1; this.hideHighlight(); }, /** * @param {number} entryIndex */ _updatePopover: function(entryIndex) { if (entryIndex !== this._highlightedEntryIndex) { this._entryInfo.removeChildren(); var entryInfo = this._dataProvider.prepareHighlightedEntryInfo(entryIndex); if (entryInfo) this._entryInfo.appendChild(this._buildEntryInfo(entryInfo)); } var mouseX = this._lastMouseOffsetX; var mouseY = this._lastMouseOffsetY; var parentWidth = this._entryInfo.parentElement.clientWidth; var parentHeight = this._entryInfo.parentElement.clientHeight; var infoWidth = this._entryInfo.clientWidth; var infoHeight = this._entryInfo.clientHeight; var /** @const */ offsetX = 10; var /** @const */ offsetY = 6; var x; var y; for (var quadrant = 0; quadrant < 4; ++quadrant) { var dx = quadrant & 2 ? -offsetX - infoWidth : offsetX; var dy = quadrant & 1 ? -offsetY - infoHeight : offsetY; x = Number.constrain(mouseX + dx, 0, parentWidth - infoWidth); y = Number.constrain(mouseY + dy, 0, parentHeight - infoHeight); if (x >= mouseX || mouseX >= x + infoWidth || y >= mouseY || mouseY >= y + infoHeight) break; } this._entryInfo.style.left = x + "px"; this._entryInfo.style.top = y + "px"; }, _onClick: function(event) { this.focus(); // onClick comes after dragStart and dragEnd events. // So if there was drag (mouse move) in the middle of that events // we skip the click. Otherwise we jump to the sources. const clickThreshold = 5; if (this._maxDragOffset() > clickThreshold) return; var groupIndex = this._coordinatesToGroupIndex(event.offsetX, event.offsetY); if (groupIndex >= 0) { this._toggleGroupVisibility(groupIndex); return; } this._hideRangeSelection(); this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, this._highlightedEntryIndex); }, /** * @param {number} groupIndex */ _toggleGroupVisibility: function(groupIndex) { var groups = this._rawTimelineData.groups; var group = groups[groupIndex]; if (!group.style.collapsible) return; group.expanded = !group.expanded; this._groupExpansionState[group.name] = group.expanded; if (this._groupExpansionSetting) this._groupExpansionSetting.set(this._groupExpansionState); this._updateLevelPositions(); this._updateHighlight(); if (!group.expanded) { var timelineData = this._timelineData(); var level = timelineData.entryLevels[this._selectedEntryIndex]; if (this._selectedEntryIndex >= 0 && level >= group.startLevel && (groupIndex === groups.length || groups[groupIndex + 1].startLevel > level)) this._selectedEntryIndex = -1; } this._updateHeight(); this._resetCanvas(); this._draw(this._offsetWidth, this._offsetHeight); }, /** * @param {!Event} e */ _onMouseWheel: function(e) { if (!this._enabled()) return; // Pan vertically when shift down only. var panVertically = e.shiftKey && (e.wheelDeltaY || Math.abs(e.wheelDeltaX) === 120); var panHorizontally = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) && !e.shiftKey; if (panVertically) { this._vScrollElement.scrollTop -= (e.wheelDeltaY || e.wheelDeltaX) / 120 * this._offsetHeight / 8; } else if (panHorizontally) { var shift = -e.wheelDeltaX * this._pixelToTime; this._muteAnimation = true; this._handlePanGesture(shift); this._muteAnimation = false; } else { // Zoom. const mouseWheelZoomSpeed = 1 / 120; this._handleZoomGesture(Math.pow(1.2, -(e.wheelDeltaY || e.wheelDeltaX) * mouseWheelZoomSpeed) - 1); } // Block swipe gesture. e.consume(true); }, /** * @param {!Event} e */ _onKeyDown: function(e) { this._handleZoomPanKeys(e); this._handleSelectionNavigation(e); }, /** * @param {!Event} e */ _handleSelectionNavigation: function(e) { if (!WebInspector.KeyboardShortcut.hasNoModifiers(e)) return; if (this._selectedEntryIndex === -1) return; var timelineData = this._timelineData(); if (!timelineData) return; /** * @param {number} time * @param {number} entryIndex * @return {number} */ function timeComparator(time, entryIndex) { return time - timelineData.entryStartTimes[entryIndex]; } /** * @param {number} entry1 * @param {number} entry2 * @return {boolean} */ function entriesIntersect(entry1, entry2) { var start1 = timelineData.entryStartTimes[entry1]; var start2 = timelineData.entryStartTimes[entry2]; var end1 = start1 + timelineData.entryTotalTimes[entry1]; var end2 = start2 + timelineData.entryTotalTimes[entry2]; return start1 < end2 && start2 < end1; } var keys = WebInspector.KeyboardShortcut.Keys; if (e.keyCode === keys.Left.code || e.keyCode === keys.Right.code) { var level = timelineData.entryLevels[this._selectedEntryIndex]; var levelIndexes = this._timelineLevels[level]; var indexOnLevel = levelIndexes.lowerBound(this._selectedEntryIndex); indexOnLevel += e.keyCode === keys.Left.code ? -1 : 1; e.consume(true); if (indexOnLevel >= 0 && indexOnLevel < levelIndexes.length) this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, levelIndexes[indexOnLevel]); return; } if (e.keyCode === keys.Up.code || e.keyCode === keys.Down.code) { e.consume(true); var level = timelineData.entryLevels[this._selectedEntryIndex]; level += e.keyCode === keys.Up.code ? -1 : 1; if (level < 0 || level >= this._timelineLevels.length) return; var entryTime = timelineData.entryStartTimes[this._selectedEntryIndex] + timelineData.entryTotalTimes[this._selectedEntryIndex] / 2; var levelIndexes = this._timelineLevels[level]; var indexOnLevel = levelIndexes.upperBound(entryTime, timeComparator) - 1; if (!entriesIntersect(this._selectedEntryIndex, levelIndexes[indexOnLevel])) { ++indexOnLevel; if (indexOnLevel >= levelIndexes.length || !entriesIntersect(this._selectedEntryIndex, levelIndexes[indexOnLevel])) return; } this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, levelIndexes[indexOnLevel]); } }, /** * @param {!Event} e */ _handleZoomPanKeys: function(e) { if (!WebInspector.KeyboardShortcut.hasNoModifiers(e)) return; var zoomMultiplier = e.shiftKey ? 0.8 : 0.3; var panMultiplier = e.shiftKey ? 320 : 80; if (e.keyCode === "A".charCodeAt(0)) { this._handlePanGesture(-panMultiplier * this._pixelToTime); e.consume(true); } else if (e.keyCode === "D".charCodeAt(0)) { this._handlePanGesture(panMultiplier * this._pixelToTime); e.consume(true); } else if (e.keyCode === "W".charCodeAt(0)) { this._handleZoomGesture(-zoomMultiplier); e.consume(true); } else if (e.keyCode === "S".charCodeAt(0)) { this._handleZoomGesture(zoomMultiplier); e.consume(true); } }, /** * @param {number} zoom */ _handleZoomGesture: function(zoom) { this._cancelAnimation(); var bounds = this._windowForGesture(); var cursorTime = this._cursorTime(this._lastMouseOffsetX); bounds.left += (bounds.left - cursorTime) * zoom; bounds.right += (bounds.right - cursorTime) * zoom; this._requestWindowTimes(bounds); }, /** * @param {number} shift */ _handlePanGesture: function(shift) { this._cancelAnimation(); var bounds = this._windowForGesture(); shift = Number.constrain(shift, this._minimumBoundary - bounds.left, this._totalTime + this._minimumBoundary - bounds.right); bounds.left += shift; bounds.right += shift; this._requestWindowTimes(bounds); }, /** * @return {{left: number, right: number}} */ _windowForGesture: function() { var windowLeft = this._timeWindowLeft ? this._timeWindowLeft : this._dataProvider.minimumBoundary(); var windowRight = this._timeWindowRight !== Infinity ? this._timeWindowRight : this._dataProvider.minimumBoundary() + this._dataProvider.totalTime(); return {left: windowLeft, right: windowRight}; }, /** * @param {{left: number, right: number}} bounds */ _requestWindowTimes: function(bounds) { bounds.left = Number.constrain(bounds.left, this._minimumBoundary, this._totalTime + this._minimumBoundary); bounds.right = Number.constrain(bounds.right, this._minimumBoundary, this._totalTime + this._minimumBoundary); if (bounds.right - bounds.left < WebInspector.FlameChart.MinimalTimeWindowMs) return; this._flameChartDelegate.requestWindowTimes(bounds.left, bounds.right); }, /** * @param {number} x * @return {number} */ _cursorTime: function(x) { return (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTime + this._minimumBoundary; }, /** * @param {number} x * @param {number} y * @return {number} */ _coordinatesToEntryIndex: function(x, y) { if (x < 0 || y < 0) return -1; y += this._scrollTop; var timelineData = this._timelineData(); if (!timelineData) return -1; var cursorTime = this._cursorTime(x); var cursorLevel = this._visibleLevelOffsets.upperBound(y) - 1; if (cursorLevel < 0 || !this._visibleLevels[cursorLevel]) return -1; var offsetFromLevel = y - this._visibleLevelOffsets[cursorLevel]; if (offsetFromLevel > this._barHeight) return -1; var entryStartTimes = timelineData.entryStartTimes; var entryTotalTimes = timelineData.entryTotalTimes; var entryIndexes = this._timelineLevels[cursorLevel]; if (!entryIndexes || !entryIndexes.length) return -1; /** * @param {number} time * @param {number} entryIndex * @return {number} */ function comparator(time, entryIndex) { return time - entryStartTimes[entryIndex]; } var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparator) - 1, 0); /** * @this {WebInspector.FlameChart} * @param {number} entryIndex * @return {boolean} */ function checkEntryHit(entryIndex) { if (entryIndex === undefined) return false; var startTime = entryStartTimes[entryIndex]; var duration = entryTotalTimes[entryIndex]; if (isNaN(duration)) { var dx = (startTime - cursorTime) / this._pixelToTime; var dy = this._barHeight / 2 - offsetFromLevel; return dx * dx + dy * dy < this._markerRadius * this._markerRadius; } var endTime = startTime + duration; var barThreshold = 3 * this._pixelToTime; return startTime - barThreshold < cursorTime && cursorTime < endTime + barThreshold; } var entryIndex = entryIndexes[indexOnLevel]; if (checkEntryHit.call(this, entryIndex)) return entryIndex; entryIndex = entryIndexes[indexOnLevel + 1]; if (checkEntryHit.call(this, entryIndex)) return entryIndex; return -1; }, /** * @param {number} x * @param {number} y * @return {number} */ _coordinatesToGroupIndex: function(x, y) { if (x < 0 || y < 0) return -1; y += this._scrollTop; var groups = this._rawTimelineData.groups || []; var group = this._groupOffsets.upperBound(y) - 1; if (group < 0 || group >= groups.length || y - this._groupOffsets[group] >= groups[group].style.height) return -1; var context = this._canvas.getContext("2d"); context.save(); context.font = groups[group].style.font; var right = this._headerLeftPadding + this._labelWidthForGroup(context, groups[group]); context.restore(); if (x > right) return -1; return group; }, /** * @param {number} x * @return {number} */ _markerIndexAtPosition: function(x) { var markers = this._timelineData().markers; if (!markers) return -1; var accurracyOffsetPx = 1; var time = this._cursorTime(x); var leftTime = this._cursorTime(x - accurracyOffsetPx); var rightTime = this._cursorTime(x + accurracyOffsetPx); var left = this._markerIndexBeforeTime(leftTime); var markerIndex = -1; var distance = Infinity; for (var i = left; i < markers.length && markers[i].startTime() < rightTime; i++) { var nextDistance = Math.abs(markers[i].startTime() - time); if (nextDistance < distance) { markerIndex = i; distance = nextDistance; } } return markerIndex; }, /** * @param {number} time * @return {number} */ _markerIndexBeforeTime: function(time) { /** * @param {number} markerTimestamp * @param {!WebInspector.FlameChartMarker} marker * @return {number} */ function comparator(markerTimestamp, marker) { return markerTimestamp - marker.startTime(); } return this._timelineData().markers.lowerBound(time, comparator); }, /** * @param {number} height * @param {number} width */ _draw: function(width, height) { var timelineData = this._timelineData(); if (!timelineData) return; var context = this._canvas.getContext("2d"); context.save(); var ratio = window.devicePixelRatio; context.scale(ratio, ratio); context.translate(0, -this._scrollTop); context.font = "11px " + WebInspector.fontFamily(); var timeWindowRight = this._timeWindowRight; var timeWindowLeft = this._timeWindowLeft - this._paddingLeft / this._timeToPixel; var entryTotalTimes = timelineData.entryTotalTimes; var entryStartTimes = timelineData.entryStartTimes; var entryLevels = timelineData.entryLevels; var titleIndices = new Uint32Array(entryTotalTimes.length); var nextTitleIndex = 0; var markerIndices = new Uint32Array(entryTotalTimes.length); var nextMarkerIndex = 0; var textPadding = this._dataProvider.textPadding(); var minTextWidth = 2 * textPadding + this._measureWidth(context, "\u2026"); var unclippedWidth = width - (WebInspector.isMac() ? 0 : this._vScrollElement.offsetWidth); var barHeight = this._barHeight; var top = this._scrollTop; var minVisibleBarLevel = Math.max(this._visibleLevelOffsets.upperBound(top) - 1, 0); function comparator(time, entryIndex) { return time - entryStartTimes[entryIndex]; } var colorBuckets = {}; for (var level = minVisibleBarLevel; level < this._dataProvider.maxStackDepth(); ++level) { if (this._levelToHeight(level) > top + height) break; if (!this._visibleLevels[level]) continue; // Entries are ordered by start time within a level, so find the last visible entry. var levelIndexes = this._timelineLevels[level]; var rightIndexOnLevel = levelIndexes.lowerBound(timeWindowRight, comparator) - 1; var lastDrawOffset = Infinity; for (var entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) { var entryIndex = levelIndexes[entryIndexOnLevel]; var entryStartTime = entryStartTimes[entryIndex]; var entryOffsetRight = entryStartTime + (isNaN(entryTotalTimes[entryIndex]) ? 0 : entryTotalTimes[entryIndex]); if (entryOffsetRight <= timeWindowLeft) break; var barX = this._timeToPositionClipped(entryStartTime); // Check if the entry entirely fits into an already drawn pixel, we can just skip drawing it. if (barX >= lastDrawOffset) continue; lastDrawOffset = barX; var color = this._dataProvider.entryColor(entryIndex); var bucket = colorBuckets[color]; if (!bucket) { bucket = []; colorBuckets[color] = bucket; } bucket.push(entryIndex); } } var colors = Object.keys(colorBuckets); // We don't use for-in here because it couldn't be optimized. for (var c = 0; c < colors.length; ++c) { var color = colors[c]; context.fillStyle = color; context.strokeStyle = color; var indexes = colorBuckets[color]; // First fill the boxes. context.beginPath(); for (var i = 0; i < indexes.length; ++i) { var entryIndex = indexes[i]; var entryStartTime = entryStartTimes[entryIndex]; var barX = this._timeToPositionClipped(entryStartTime); var barRight = this._timeToPositionClipped(entryStartTime + entryTotalTimes[entryIndex]); var barWidth = Math.max(barRight - barX, 1); var barLevel = entryLevels[entryIndex]; var barY = this._levelToHeight(barLevel); if (isNaN(entryTotalTimes[entryIndex])) { context.moveTo(barX + this._markerRadius, barY + barHeight / 2); context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2); markerIndices[nextMarkerIndex++] = entryIndex; } else { context.rect(barX, barY, barWidth - 0.4, barHeight - 1); if (barWidth > minTextWidth || this._dataProvider.forceDecoration(entryIndex)) titleIndices[nextTitleIndex++] = entryIndex; } } context.fill(); } context.strokeStyle = "rgb(0, 0, 0)"; context.beginPath(); for (var m = 0; m < nextMarkerIndex; ++m) { var entryIndex = markerIndices[m]; var entryStartTime = entryStartTimes[entryIndex]; var barX = this._timeToPositionClipped(entryStartTime); var barLevel = entryLevels[entryIndex]; var barY = this._levelToHeight(barLevel); context.moveTo(barX + this._markerRadius, barY + barHeight / 2); context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2); } context.stroke(); context.textBaseline = "alphabetic"; var textBaseHeight = this._barHeight - this._dataProvider.textBaseline(); for (var i = 0; i < nextTitleIndex; ++i) { var entryIndex = titleIndices[i]; var entryStartTime = entryStartTimes[entryIndex]; var barX = this._timeToPositionClipped(entryStartTime); var barRight = Math.min(this._timeToPositionClipped(entryStartTime + entryTotalTimes[entryIndex]), unclippedWidth) + 1; var barWidth = barRight - barX; var barLevel = entryLevels[entryIndex]; var barY = this._levelToHeight(barLevel); var text = this._dataProvider.entryTitle(entryIndex); if (text && text.length) { context.font = this._dataProvider.entryFont(entryIndex); text = this._prepareText(context, text, barWidth - 2 * textPadding); } var unclippedBarX = this._timeToPosition(entryStartTime); if (this._dataProvider.decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, this._timeToPixel)) continue; if (!text || !text.length) continue; context.fillStyle = this._dataProvider.textColor(entryIndex); context.fillText(text, barX + textPadding, barY + textBaseHeight); } this._drawFlowEvents(context, width, height); context.restore(); var offsets = this._dataProvider.dividerOffsets(this._calculator.minimumBoundary(), this._calculator.maximumBoundary()); WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets); this._drawMarkers(); this._drawGroupHeaders(width, height); this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex); this._updateElementPosition(this._selectedElement, this._selectedEntryIndex); this._updateMarkerHighlight(); this._updateRangeSelectionOverlay(); }, /** * @param {number} width * @param {number} height */ _drawGroupHeaders: function(width, height) { var context = this._canvas.getContext("2d"); var top = this._scrollTop; var ratio = window.devicePixelRatio; var barHeight = this._barHeight; var textBaseHeight = barHeight - this._dataProvider.textBaseline(); var groups = this._rawTimelineData.groups || []; if (!groups.length) return; var groupOffsets = this._groupOffsets; var lastGroupOffset = Array.prototype.peekLast.call(groupOffsets); var colorUsage = WebInspector.ThemeSupport.ColorUsage; context.save(); context.scale(ratio, ratio); context.translate(0, -top); context.fillStyle = WebInspector.themeSupport.patchColor("#eee", colorUsage.Background); forEachGroup((offset, index, group) => { var paddingHeight = group.style.padding; if (paddingHeight < 5) return; context.fillRect(0, offset - paddingHeight + 2, width, paddingHeight - 4); }); if (groups.length && lastGroupOffset < top + height) context.fillRect(0, lastGroupOffset + 2, width, top + height - lastGroupOffset) context.strokeStyle = WebInspector.themeSupport.patchColor("#bbb", colorUsage.Background); context.beginPath(); forEachGroup((offset, index, group, isFirst) => { if (isFirst || group.style.padding < 4) return; hLine(offset - 2.5); }); hLine(lastGroupOffset + 0.5); context.stroke(); forEachGroup((offset, index, group) => { if (group.style.shareHeaderLine) return; if ((!group.style.collapsible || group.expanded)) { context.fillStyle = group.style.backgroundColor; context.fillRect(0, offset, width, group.style.height); return; } var nextGroup = index + 1; while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel) nextGroup++; var endLevel = nextGroup < groups.length ? groups[nextGroup].startLevel : this._dataProvider.maxStackDepth(); this._drawCollapsedOverviewForGroup(offset + 1, group.startLevel, endLevel); }); context.save(); forEachGroup((offset, index, group) => { context.font = group.style.font; if (group.style.collapsible && !group.expanded || group.style.shareHeaderLine) { var width = this._labelWidthForGroup(context, group); context.fillStyle = WebInspector.Color.parse(group.style.backgroundColor).setAlpha(0.7).asString(null); context.fillRect(this._headerLeftPadding - this._headerLabelXPadding, offset + this._headerLabelYPadding, width, barHeight - 2 * this._headerLabelYPadding); } context.fillStyle = group.style.color; context.fillText(group.name, Math.floor(this._expansionArrowX + this._arrowSide), offset + textBaseHeight); }); context.restore(); context.fillStyle = WebInspector.themeSupport.patchColor("#6e6e6e", colorUsage.Foreground); context.beginPath(); forEachGroup((offset, index, group) => { if (group.style.collapsible) drawExpansionArrow.call(this, this._expansionArrowX, offset + textBaseHeight - this._arrowSide / 2, !!group.expanded) }); context.fill(); context.strokeStyle = WebInspector.themeSupport.patchColor("#ddd", colorUsage.Background); context.beginPath(); context.stroke(); context.restore(); /** * @param {number} y */ function hLine(y) { context.moveTo(0, y); context.lineTo(width, y); } /** * @param {number} x * @param {number} y * @param {boolean} expanded * @this {WebInspector.FlameChart} */ function drawExpansionArrow(x, y, expanded) { var arrowHeight = this._arrowSide * Math.sqrt(3) / 2; var arrowCenterOffset = Math.round(arrowHeight / 2); context.save(); context.translate(x, y); context.rotate(expanded ? Math.PI / 2 : 0); context.moveTo(-arrowCenterOffset, -this._arrowSide / 2); context.lineTo(-arrowCenterOffset, this._arrowSide / 2); context.lineTo(arrowHeight - arrowCenterOffset, 0); context.restore(); } /** * @param {function(number, number, !WebInspector.FlameChart.Group, boolean)} callback */ function forEachGroup(callback) { /** @type !Array<{nestingLevel: number, visible: boolean}> */ var groupStack = [{nestingLevel: -1, visible: true}]; for (var i = 0; i < groups.length; ++i) { var groupTop = groupOffsets[i]; var group = groups[i]; if (groupTop - group.style.padding > top + height) break; var firstGroup = true; while (groupStack.peekLast().nestingLevel >= group.style.nestingLevel) { groupStack.pop(); firstGroup = false; } var parentGroupVisible = groupStack.peekLast().visible; var thisGroupVisible = parentGroupVisible && (!group.style.collapsible || group.expanded); groupStack.push({nestingLevel: group.style.nestingLevel, visible: thisGroupVisible}); if (!parentGroupVisible || groupTop + group.style.height < top) continue; callback(groupTop, i, group, firstGroup); } } }, /** * @param {!CanvasRenderingContext2D} context * @param {!WebInspector.FlameChart.Group} group * @return {number} */ _labelWidthForGroup: function(context, group) { return this._measureWidth(context, group.name) + 1.5 * this._arrowSide + 2 * this._headerLabelXPadding; }, /** * @param {number} y * @param {number} startLevel * @param {number} endLevel */ _drawCollapsedOverviewForGroup: function(y, startLevel, endLevel) { var range = new WebInspector.SegmentedRange(mergeCallback); var timeWindowRight = this._timeWindowRight; var timeWindowLeft = this._timeWindowLeft - this._paddingLeft / this._timeToPixel; var context = this._canvas.getContext("2d"); var barHeight = this._barHeight - 2; var entryStartTimes = this._rawTimelineData.entryStartTimes; var entryTotalTimes = this._rawTimelineData.entryTotalTimes; for (var level = startLevel; level < endLevel; ++level) { var levelIndexes = this._timelineLevels[level]; var rightIndexOnLevel = levelIndexes.lowerBound(timeWindowRight, (time, entryIndex) => time - entryStartTimes[entryIndex]) - 1; var lastDrawOffset = Infinity; for (var entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) { var entryIndex = levelIndexes[entryIndexOnLevel]; var entryStartTime = entryStartTimes[entryIndex]; var startPosition = this._timeToPositionClipped(entryStartTime); var entryEndTime = entryStartTime + entryTotalTimes[entryIndex]; if (isNaN(entryEndTime) || startPosition >= lastDrawOffset) continue; if (entryEndTime <= timeWindowLeft) break; lastDrawOffset = startPosition; var color = this._dataProvider.entryColor(entryIndex); range.append(new WebInspector.Segment(startPosition, this._timeToPositionClipped(entryEndTime), color)); } } var segments = range.segments().slice().sort((a, b) => a.data.localeCompare(b.data)); var lastColor; context.beginPath(); for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; if (lastColor !== segments[i].data) { context.fill(); context.beginPath(); lastColor = segments[i].data; context.fillStyle = lastColor; } context.rect(segment.begin, y, segment.end - segment.begin, barHeight); } context.fill(); /** * @param {!WebInspector.Segment} a * @param {!WebInspector.Segment} b * @return {?WebInspector.Segment} */ function mergeCallback(a, b) { return a.data === b.data && a.end + 0.4 > b.end ? a : null; } }, /** * @param {!CanvasRenderingContext2D} context * @param {number} height * @param {number} width */ _drawFlowEvents: function(context, width, height) { var timelineData = this._timelineData(); var timeWindowRight = this._timeWindowRight; var timeWindowLeft = this._timeWindowLeft; var flowStartTimes = timelineData.flowStartTimes; var flowEndTimes = timelineData.flowEndTimes; var flowStartLevels = timelineData.flowStartLevels; var flowEndLevels = timelineData.flowEndLevels; var flowCount = flowStartTimes.length; var endIndex = flowStartTimes.lowerBound(timeWindowRight); var color = []; var fadeColorsCount = 8; for (var i = 0; i <= fadeColorsCount; ++i) color[i] = "rgba(128, 0, 0, " + i / fadeColorsCount + ")"; var fadeColorsRange = color.length; var minimumFlowDistancePx = 15; var flowArcHeight = 4 * this._barHeight; var colorIndex = 0; context.lineWidth = 0.5; for (var i = 0; i < endIndex; ++i) { if (flowEndTimes[i] < timeWindowLeft) continue; var startX = this._timeToPosition(flowStartTimes[i]); var endX = this._timeToPosition(flowEndTimes[i]); if (endX - startX < minimumFlowDistancePx) continue; if (startX < -minimumFlowDistancePx && endX > width + minimumFlowDistancePx) continue; // Assign a trasparent color if the flow is small enough or if the previous color was a transparent color. if (endX - startX < minimumFlowDistancePx + fadeColorsRange || colorIndex !== color.length - 1) { colorIndex = Math.min(fadeColorsRange - 1, Math.floor(endX - startX - minimumFlowDistancePx)); context.strokeStyle = color[colorIndex]; } var startY = this._levelToHeight(flowStartLevels[i]) + this._barHeight; var endY = this._levelToHeight(flowEndLevels[i]); context.beginPath(); context.moveTo(startX, startY); var arcHeight = Math.max(Math.sqrt(Math.abs(startY - endY)), flowArcHeight) + 5; context.bezierCurveTo(startX, startY + arcHeight, endX, endY + arcHeight, endX, endY + this._barHeight); context.stroke(); } }, _drawMarkers: function() { var markers = this._timelineData().markers; var left = this._markerIndexBeforeTime(this._calculator.minimumBoundary()); var rightBoundary = this._calculator.maximumBoundary(); var context = this._canvas.getContext("2d"); context.save(); var ratio = window.devicePixelRatio; context.scale(ratio, ratio); var height = WebInspector.FlameChart.DividersBarHeight - 1; for (var i = left; i < markers.length; i++) { var timestamp = markers[i].startTime(); if (timestamp > rightBoundary) break; markers[i].draw(context, this._calculator.computePosition(timestamp), height, this._timeToPixel); } context.restore(); }, _updateMarkerHighlight: function() { var element = this._markerHighlighElement; if (element.parentElement) element.remove(); var markerIndex = this._highlightedMarkerIndex; if (markerIndex === -1) return; var marker = this._timelineData().markers[markerIndex]; var barX = this._timeToPositionClipped(marker.startTime()); element.title = marker.title(); var style = element.style; style.left = barX + "px"; style.backgroundColor = marker.color(); this.contentElement.appendChild(element); }, /** * @param {?WebInspector.FlameChart.TimelineData} timelineData */ _processTimelineData: function(timelineData) { if (!timelineData) { this._timelineLevels = null; this._visibleLevelOffsets = null; this._visibleLevels = null; this._groupOffsets = null; this._rawTimelineData = null; this._rawTimelineDataLength = 0; return; } this._rawTimelineData = timelineData; this._rawTimelineDataLength = timelineData.entryStartTimes.length; var entryCounters = new Uint32Array(this._dataProvider.maxStackDepth() + 1); for (var i = 0; i < timelineData.entryLevels.length; ++i) ++entryCounters[timelineData.entryLevels[i]]; var levelIndexes = new Array(entryCounters.length); for (var i = 0; i < levelIndexes.length; ++i) { levelIndexes[i] = new Uint32Array(entryCounters[i]); entryCounters[i] = 0; } for (var i = 0; i < timelineData.entryLevels.length; ++i) { var level = timelineData.entryLevels[i]; levelIndexes[level][entryCounters[level]++] = i; } this._timelineLevels = levelIndexes; var groups = this._rawTimelineData.groups || []; for (var i = 0; i < groups.length; ++i) { var expanded = this._groupExpansionState[groups[i].name]; if (expanded !== undefined) groups[i].expanded = expanded; } this._updateLevelPositions(); }, _updateLevelPositions: function() { var levelCount = this._dataProvider.maxStackDepth(); var groups = this._rawTimelineData.groups || []; this._visibleLevelOffsets = new Uint32Array(levelCount + 1); this._visibleLevels = new Uint8Array(levelCount); this._groupOffsets = new Uint32Array(groups.length + 1); var groupIndex = -1; var currentOffset = WebInspector.FlameChart.DividersBarHeight; var visible = true; /** @type !Array<{nestingLevel: number, visible: boolean}> */ var groupStack = [{nestingLevel: -1, visible: true}]; for (var level = 0; level < levelCount; ++level) { while (groupIndex < groups.length - 1 && level === groups[groupIndex + 1].startLevel) { ++groupIndex; var style = groups[groupIndex].style; var nextLevel = true; while (groupStack.peekLast().nestingLevel >= style.nestingLevel) { groupStack.pop(); nextLevel = false; } var thisGroupIsVisible = style.collapsible ? groups[groupIndex].expanded : true; var parentGroupIsVisible = groupStack.peekLast().visible; visible = thisGroupIsVisible && parentGroupIsVisible; groupStack.push({nestingLevel: style.nestingLevel, visible: visible}); if (parentGroupIsVisible) currentOffset += nextLevel ? 0 : style.padding; this._groupOffsets[groupIndex] = currentOffset; if (parentGroupIsVisible && !style.shareHeaderLine) currentOffset += style.height; } var thisLevelIsVisible = visible || groupIndex >= 0 && groups[groupIndex].style.useFirstLineForOverview && level === groups[groupIndex].startLevel; this._visibleLevels[level] = thisLevelIsVisible; this._visibleLevelOffsets[level] = currentOffset; if (thisLevelIsVisible) currentOffset += this._barHeight; } if (groupIndex >= 0) this._groupOffsets[groupIndex + 1] = currentOffset; this._visibleLevelOffsets[level] = currentOffset; }, /** * @param {number} entryIndex */ setSelectedEntry: function(entryIndex) { if (entryIndex === -1 && !this._isDragging) this._hideRangeSelection(); if (this._selectedEntryIndex === entryIndex) return; this._selectedEntryIndex = entryIndex; this._revealEntry(entryIndex); this._updateElementPosition(this._selectedElement, this._selectedEntryIndex); }, /** * @param {!Element} element * @param {number} entryIndex */ _updateElementPosition: function(element, entryIndex) { /** @const */ var elementMinWidth = 2; if (element.parentElement) element.remove(); if (entryIndex === -1) return; var timeRange = this._dataProvider.highlightTimeRange(entryIndex); if (!timeRange) return; var timelineData = this._timelineData(); var barX = this._timeToPositionClipped(timeRange.startTime); var barRight = this._timeToPositionClipped(timeRange.endTime); if (barRight === 0 || barX === this._canvas.width) return; var barWidth = barRight - barX; var barCenter = barX + barWidth / 2; barWidth = Math.max(barWidth, elementMinWidth); barX = barCenter - barWidth / 2; var barY = this._levelToHeight(timelineData.entryLevels[entryIndex]) - this._scrollTop; var style = element.style; style.left = barX + "px"; style.top = barY + "px"; style.width = barWidth + "px"; style.height = this._barHeight - 1 + "px"; this.contentElement.appendChild(element); }, /** * @param {number} time * @return {number} */ _timeToPositionClipped: function(time) { return Number.constrain(this._timeToPosition(time), 0, this._canvas.width); }, /** * @param {number} time * @return {number} */ _timeToPosition: function(time) { return Math.floor((time - this._minimumBoundary) * this._timeToPixel) - this._pixelWindowLeft + this._paddingLeft; }, /** * @param {number} level * @return {number} */ _levelToHeight: function(level) { return this._visibleLevelOffsets[level]; }, /** * @param {!Array<!{title: string, value: (string|!Element)}>} entryInfo * @return {!Element} */ _buildEntryInfo: function(entryInfo) { var infoTable = createElementWithClass("table", "info-table"); for (var entry of entryInfo) { var row = infoTable.createChild("tr"); row.createChild("td", "title").textContent = entry.title; if (typeof entry.value === "string") row.createChild("td").textContent = entry.value; else row.createChild("td").appendChild(entry.value); } return infoTable; }, /** * @param {!CanvasRenderingContext2D} context * @param {string} text * @param {number} maxWidth * @return {string} */ _prepareText: function(context, text, maxWidth) { var /** @const */ maxLength = 200; if (maxWidth <= 10) return ""; if (text.length > maxLength) text = text.trimMiddle(maxLength); var textWidth = this._measureWidth(context, text); if (textWidth <= maxWidth) return text; var l = 0; var r = text.length; var lv = 0; var rv = textWidth; while (l < r && lv !== rv && lv !== maxWidth) { var m = Math.ceil(l + (r - l) * (maxWidth - lv) / (rv - lv)); var mv = this._measureWidth(context, text.trimMiddle(m)); if (mv <= maxWidth) { l = m; lv = mv; } else { r = m - 1; rv = mv; } } text = text.trimMiddle(l); return text !== "\u2026" ? text : ""; }, /** * @param {!CanvasRenderingContext2D} context * @param {string} text * @return {number} */ _measureWidth: function(context, text) { var /** @const */ maxCacheableLength = 200; if (text.length > maxCacheableLength) return context.measureText(text).width; var font = context.font; var textWidths = this._textWidth.get(font); if (!textWidths) { textWidths = new Map(); this._textWidth.set(font, textWidths); } var width = textWidths.get(text); if (!width) { width = context.measureText(text).width; textWidths.set(text, width); } return width; }, _updateBoundaries: function() { this._totalTime = this._dataProvider.totalTime(); this._minimumBoundary = this._dataProvider.minimumBoundary(); var windowWidth = 1; if (this._timeWindowRight !== Infinity) { this._windowLeft = (this._timeWindowLeft - this._minimumBoundary) / this._totalTime; this._windowRight = (this._timeWindowRight - this._minimumBoundary) / this._totalTime; windowWidth = this._windowRight - this._windowLeft; } else if (this._timeWindowLeft === Infinity) { this._windowLeft = Infinity; this._windowRight = Infinity; } else { this._windowLeft = 0; this._windowRight = 1; } var totalPixels = Math.floor((this._offsetWidth - this._paddingLeft) / windowWidth); this._pixelWindowLeft = Math.floor(totalPixels * this._windowLeft); this._timeToPixel = totalPixels / this._totalTime; this._pixelToTime = this._totalTime / totalPixels; this._updateScrollBar(); }, _updateHeight: function() { this._totalHeight = this._levelToHeight(this._dataProvider.maxStackDepth()); this._vScrollContent.style.height = this._totalHeight + "px"; }, onResize: function() { this._updateScrollBar(); this._updateContentElementSize(); this.scheduleUpdate(); }, _updateScrollBar: function() { var showScroll = this._totalHeight > this._offsetHeight; if (this._vScrollElement.classList.contains("hidden") === showScroll) { this._vScrollElement.classList.toggle("hidden", !showScroll); this._updateContentElementSize(); } }, _updateContentElementSize: function() { this._offsetWidth = this.contentElement.offsetWidth; this._offsetHeight = this.contentElement.offsetHeight; }, _onScroll: function() { this._scrollTop = this._vScrollElement.scrollTop; this.scheduleUpdate(); }, scheduleUpdate: function() { if (this._updateTimerId || this._cancelWindowTimesAnimation) return; this._updateTimerId = this.element.window().requestAnimationFrame(this.update.bind(this)); }, update: function() { this._updateTimerId = 0; if (!this._timelineData()) return; this._resetCanvas(); this._updateHeight(); this._updateBoundaries(); this._calculator._updateBoundaries(this); this._draw(this._offsetWidth, this._offsetHeight); if (!this._isDragging) this._updateHighlight(); }, reset: function() { this._vScrollElement.scrollTop = 0; this._highlightedMarkerIndex = -1; this._highlightedEntryIndex = -1; this._selectedEntryIndex = -1; this._rangeSelectionStart = 0; this._rangeSelectionEnd = 0; /** @type {!Map<string,!Map<string,number>>} */ this._textWidth = new Map(); this.update(); }, _enabled: function() { return this._rawTimelineDataLength !== 0; }, __proto__: WebInspector.HBox.prototype } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} prefix
*/
WebInspector.OverviewGrid = function(prefix)
{
this.element = createElement("div");
this.element.id = prefix + "-overview-container";
this._grid = new WebInspector.TimelineGrid();
this._grid.element.id = prefix + "-overview-grid";
this._grid.setScrollTop(0);
this.element.appendChild(this._grid.element);
this._window = new WebInspector.OverviewGrid.Window(this.element, this._grid.dividersLabelBarElement);
this._window.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
}
WebInspector.OverviewGrid.prototype = {
/**
* @return {number}
*/
clientWidth: function()
{
return this.element.clientWidth;
},
/**
* @param {!WebInspector.TimelineGrid.Calculator} calculator
*/
updateDividers: function(calculator)
{
this._grid.updateDividers(calculator);
},
/**
* @param {!Array.<!Element>} dividers
*/
addEventDividers: function(dividers)
{
this._grid.addEventDividers(dividers);
},
removeEventDividers: function()
{
this._grid.removeEventDividers();
},
reset: function()
{
this._window.reset();
},
/**
* @return {number}
*/
windowLeft: function()
{
return this._window.windowLeft;
},
/**
* @return {number}
*/
windowRight: function()
{
return this._window.windowRight;
},
/**
* @param {number} left
* @param {number} right
*/
setWindow: function(left, right)
{
this._window._setWindow(left, right);
},
/**
* @param {string} eventType
* @param {function(!WebInspector.Event)} listener
* @param {!Object=} thisObject
* @return {!WebInspector.EventTarget.EventDescriptor}
*/
addEventListener: function(eventType, listener, thisObject)
{
return this._window.addEventListener(eventType, listener, thisObject);
},
/**
* @param {number} zoomFactor
* @param {number} referencePoint
*/
zoom: function(zoomFactor, referencePoint)
{
this._window._zoom(zoomFactor, referencePoint);
},
/**
* @param {boolean} enabled
*/
setResizeEnabled: function(enabled)
{
this._window.setEnabled(enabled);
},
_onWindowChanged: function()
{
this._grid.showCurtains(this.windowLeft(), this.windowRight());
}
}
WebInspector.OverviewGrid.MinSelectableSize = 14;
WebInspector.OverviewGrid.WindowScrollSpeedFactor = .3;
WebInspector.OverviewGrid.ResizerOffset = 3.5; // half pixel because offset values are not rounded but ceiled
/**
* @constructor
* @extends {WebInspector.Object}
* @param {!Element} parentElement
* @param {!Element=} dividersLabelBarElement
*/
WebInspector.OverviewGrid.Window = function(parentElement, dividersLabelBarElement)
{
this._parentElement = parentElement;
WebInspector.installDragHandle(this._parentElement, this._startWindowSelectorDragging.bind(this), this._windowSelectorDragging.bind(this), this._endWindowSelectorDragging.bind(this), "text", null);
if (dividersLabelBarElement)
WebInspector.installDragHandle(dividersLabelBarElement, this._startWindowDragging.bind(this), this._windowDragging.bind(this), null, "-webkit-grabbing", "-webkit-grab");
this.windowLeft = 0.0;
this.windowRight = 1.0;
this._parentElement.addEventListener("mousewheel", this._onMouseWheel.bind(this), true);
this._parentElement.addEventListener("dblclick", this._resizeWindowMaximum.bind(this), true);
WebInspector.appendStyle(this._parentElement, "ui_lazy/overviewGrid.css");
this._leftResizeElement = parentElement.createChild("div", "overview-grid-window-resizer");
this._leftResizeElement.style.left = 0;
WebInspector.installDragHandle(this._leftResizeElement, this._resizerElementStartDragging.bind(this), this._leftResizeElementDragging.bind(this), null, "ew-resize");
this._rightResizeElement = parentElement.createChild("div", "overview-grid-window-resizer");
this._rightResizeElement.style.right = 0;
WebInspector.installDragHandle(this._rightResizeElement, this._resizerElementStartDragging.bind(this), this._rightResizeElementDragging.bind(this), null, "ew-resize");
this.setEnabled(true);
}
WebInspector.OverviewGrid.Events = {
WindowChanged: "WindowChanged",
Click: "Click"
}
WebInspector.OverviewGrid.Window.prototype = {
reset: function()
{
this.windowLeft = 0.0;
this.windowRight = 1.0;
this._leftResizeElement.style.left = "0%";
this._rightResizeElement.style.left = "100%";
this.setEnabled(true);
},
/**
* @param {boolean} enabled
*/
setEnabled: function(enabled)
{
this._enabled = enabled;
},
/**
* @param {!Event} event
*/
_resizerElementStartDragging: function(event)
{
if (!this._enabled)
return false;
this._resizerParentOffsetLeft = event.pageX - event.offsetX - event.target.offsetLeft;
event.preventDefault();
return true;
},
/**
* @param {!Event} event
*/
_leftResizeElementDragging: function(event)
{
this._resizeWindowLeft(event.pageX - this._resizerParentOffsetLeft);
event.preventDefault();
},
/**
* @param {!Event} event
*/
_rightResizeElementDragging: function(event)
{
this._resizeWindowRight(event.pageX - this._resizerParentOffsetLeft);
event.preventDefault();
},
/**
* @param {!Event} event
* @return {boolean}
*/
_startWindowSelectorDragging: function(event)
{
if (!this._enabled)
return false;
this._offsetLeft = this._parentElement.totalOffsetLeft();
var position = event.x - this._offsetLeft;
this._overviewWindowSelector = new WebInspector.OverviewGrid.WindowSelector(this._parentElement, position);
return true;
},
/**
* @param {!Event} event
*/
_windowSelectorDragging: function(event)
{
this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft);
event.preventDefault();
},
/**
* @param {!Event} event
*/
_endWindowSelectorDragging: function(event)
{
var window = this._overviewWindowSelector._close(event.x - this._offsetLeft);
delete this._overviewWindowSelector;
var clickThreshold = 3;
if (window.end - window.start < clickThreshold) {
if (this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.Click, event))
return;
var middle = window.end;
window.start = Math.max(0, middle - WebInspector.OverviewGrid.MinSelectableSize / 2);
window.end = Math.min(this._parentElement.clientWidth, middle + WebInspector.OverviewGrid.MinSelectableSize / 2);
} else if (window.end - window.start < WebInspector.OverviewGrid.MinSelectableSize) {
if (this._parentElement.clientWidth - window.end > WebInspector.OverviewGrid.MinSelectableSize)
window.end = window.start + WebInspector.OverviewGrid.MinSelectableSize;
else
window.start = window.end - WebInspector.OverviewGrid.MinSelectableSize;
}
this._setWindowPosition(window.start, window.end);
},
/**
* @param {!Event} event
* @return {boolean}
*/
_startWindowDragging: function(event)
{
this._dragStartPoint = event.pageX;
this._dragStartLeft = this.windowLeft;
this._dragStartRight = this.windowRight;
return true;
},
/**
* @param {!Event} event
*/
_windowDragging: function(event)
{
event.preventDefault();
var delta = (event.pageX - this._dragStartPoint) / this._parentElement.clientWidth;
if (this._dragStartLeft + delta < 0)
delta = -this._dragStartLeft;
if (this._dragStartRight + delta > 1)
delta = 1 - this._dragStartRight;
this._setWindow(this._dragStartLeft + delta, this._dragStartRight + delta);
},
/**
* @param {number} start
*/
_resizeWindowLeft: function(start)
{
// Glue to edge.
if (start < 10)
start = 0;
else if (start > this._rightResizeElement.offsetLeft - 4)
start = this._rightResizeElement.offsetLeft - 4;
this._setWindowPosition(start, null);
},
/**
* @param {number} end
*/
_resizeWindowRight: function(end)
{
// Glue to edge.
if (end > this._parentElement.clientWidth - 10)
end = this._parentElement.clientWidth;
else if (end < this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.MinSelectableSize)
end = this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.MinSelectableSize;
this._setWindowPosition(null, end);
},
_resizeWindowMaximum: function()
{
this._setWindowPosition(0, this._parentElement.clientWidth);
},
/**
* @param {number} windowLeft
* @param {number} windowRight
*/
_setWindow: function(windowLeft, windowRight)
{
var left = windowLeft;
var right = windowRight;
var width = windowRight - windowLeft;
// We allow actual time window to be arbitrarily small but don't want the UI window to be too small.
var widthInPixels = width * this._parentElement.clientWidth;
var minWidthInPixels = WebInspector.OverviewGrid.MinSelectableSize / 2;
if (widthInPixels < minWidthInPixels) {
var factor = minWidthInPixels / widthInPixels;
left = ((windowRight + windowLeft) - width * factor) / 2;
right = ((windowRight + windowLeft) + width * factor) / 2;
}
this.windowLeft = windowLeft;
this._leftResizeElement.style.left = left * 100 + "%";
this.windowRight = windowRight;
this._rightResizeElement.style.left = right * 100 + "%";
this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged);
},
/**
* @param {?number} start
* @param {?number} end
*/
_setWindowPosition: function(start, end)
{
var clientWidth = this._parentElement.clientWidth;
var windowLeft = typeof start === "number" ? start / clientWidth : this.windowLeft;
var windowRight = typeof end === "number" ? end / clientWidth : this.windowRight;
this._setWindow(windowLeft, windowRight);
},
/**
* @param {!Event} event
*/
_onMouseWheel: function(event)
{
if (!this._enabled)
return;
if (typeof event.wheelDeltaY === "number" && event.wheelDeltaY) {
const zoomFactor = 1.1;
const mouseWheelZoomSpeed = 1 / 120;
var reference = event.offsetX / event.target.clientWidth;
this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference);
}
if (typeof event.wheelDeltaX === "number" && event.wheelDeltaX) {
var offset = Math.round(event.wheelDeltaX * WebInspector.OverviewGrid.WindowScrollSpeedFactor);
var windowLeft = this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.ResizerOffset;
var windowRight = this._rightResizeElement.offsetLeft + WebInspector.OverviewGrid.ResizerOffset;
if (windowLeft - offset < 0)
offset = windowLeft;
if (windowRight - offset > this._parentElement.clientWidth)
offset = windowRight - this._parentElement.clientWidth;
this._setWindowPosition(windowLeft - offset, windowRight - offset);
event.preventDefault();
}
},
/**
* @param {number} factor
* @param {number} reference
*/
_zoom: function(factor, reference)
{
var left = this.windowLeft;
var right = this.windowRight;
var windowSize = right - left;
var newWindowSize = factor * windowSize;
if (newWindowSize > 1) {
newWindowSize = 1;
factor = newWindowSize / windowSize;
}
left = reference + (left - reference) * factor;
left = Number.constrain(left, 0, 1 - newWindowSize);
right = reference + (right - reference) * factor;
right = Number.constrain(right, newWindowSize, 1);
this._setWindow(left, right);
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
*/
WebInspector.OverviewGrid.WindowSelector = function(parent, position)
{
this._startPosition = position;
this._width = parent.offsetWidth;
this._windowSelector = createElement("div");
this._windowSelector.className = "overview-grid-window-selector";
this._windowSelector.style.left = this._startPosition + "px";
this._windowSelector.style.right = this._width - this._startPosition + "px";
parent.appendChild(this._windowSelector);
}
WebInspector.OverviewGrid.WindowSelector.prototype = {
_close: function(position)
{
position = Math.max(0, Math.min(position, this._width));
this._windowSelector.remove();
return this._startPosition < position ? {start: this._startPosition, end: position} : {start: position, end: this._startPosition};
},
_updatePosition: function(position)
{
position = Math.max(0, Math.min(position, this._width));
if (position < this._startPosition) {
this._windowSelector.style.left = position + "px";
this._windowSelector.style.right = this._width - this._startPosition + "px";
} else {
this._windowSelector.style.left = this._startPosition + "px";
this._windowSelector.style.right = this._width - position + "px";
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 2 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {number} size
* @param {function(number):string=} formatter
* @param {boolean=} showTotal
*/
WebInspector.PieChart = function(size, formatter, showTotal)
{
this.element = createElement("div");
this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui_lazy/pieChart.css");
var root = this._shadowRoot.createChild("div", "root");
var svg = this._createSVGChild(root, "svg");
this._group = this._createSVGChild(svg, "g");
var background = this._createSVGChild(this._group, "circle");
background.setAttribute("r", 1.01);
background.setAttribute("fill", "hsl(0, 0%, 90%)");
this._foregroundElement = root.createChild("div", "pie-chart-foreground");
if (showTotal)
this._totalElement = this._foregroundElement.createChild("div", "pie-chart-total");
this._formatter = formatter;
this._slices = [];
this._lastAngle = -Math.PI/2;
this._setSize(size);
}
WebInspector.PieChart.prototype = {
/**
* @param {number} totalValue
*/
setTotal: function(totalValue)
{
for (var i = 0; i < this._slices.length; ++i)
this._slices[i].remove();
this._slices = [];
this._totalValue = totalValue;
var totalString;
if (totalValue)
totalString = this._formatter ? this._formatter(totalValue) : totalValue;
else
totalString = "";
if (this._totalElement)
this._totalElement.textContent = totalString;
},
/**
* @param {number} value
*/
_setSize: function(value)
{
this._group.setAttribute("transform", "scale(" + (value / 2) + ") translate(1, 1) scale(0.99, 0.99)");
var size = value + "px";
this.element.style.width = size;
this.element.style.height = size;
},
/**
* @param {number} value
* @param {string} color
*/
addSlice: function(value, color)
{
var sliceAngle = value / this._totalValue * 2 * Math.PI;
if (!isFinite(sliceAngle))
return;
sliceAngle = Math.min(sliceAngle, 2 * Math.PI * 0.9999);
var path = this._createSVGChild(this._group, "path");
var x1 = Math.cos(this._lastAngle);
var y1 = Math.sin(this._lastAngle);
this._lastAngle += sliceAngle;
var x2 = Math.cos(this._lastAngle);
var y2 = Math.sin(this._lastAngle);
var largeArc = sliceAngle > Math.PI ? 1 : 0;
path.setAttribute("d", "M0,0 L" + x1 + "," + y1 + " A1,1,0," + largeArc + ",1," + x2 + "," + y2 + " Z");
path.setAttribute("fill", color);
this._slices.push(path);
},
/**
* @param {!Element} parent
* @param {string} childType
* @return {!Element}
*/
_createSVGChild: function(parent, childType)
{
var child = parent.ownerDocument.createElementNS("http://www.w3.org/2000/svg", childType);
parent.appendChild(child);
return child;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 2 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.DataGridNode}
* @param {function(number, number)} callback
* @param {number} startPosition
* @param {number} endPosition
* @param {number} chunkSize
*/
WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize)
{
WebInspector.DataGridNode.call(this, {summaryRow:true}, false);
this._callback = callback;
this._startPosition = startPosition;
this._endPosition = endPosition;
this._chunkSize = chunkSize;
this.showNext = createElement("button");
this.showNext.setAttribute("type", "button");
this.showNext.addEventListener("click", this._showNextChunk.bind(this), false);
this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize);
this.showAll = createElement("button");
this.showAll.setAttribute("type", "button");
this.showAll.addEventListener("click", this._showAll.bind(this), false);
this.showLast = createElement("button");
this.showLast.setAttribute("type", "button");
this.showLast.addEventListener("click", this._showLastChunk.bind(this), false);
this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize);
this._updateLabels();
this.selectable = false;
}
WebInspector.ShowMoreDataGridNode.prototype = {
_showNextChunk: function()
{
this._callback(this._startPosition, this._startPosition + this._chunkSize);
},
_showAll: function()
{
this._callback(this._startPosition, this._endPosition);
},
_showLastChunk: function()
{
this._callback(this._endPosition - this._chunkSize, this._endPosition);
},
_updateLabels: function()
{
var totalSize = this._endPosition - this._startPosition;
if (totalSize > this._chunkSize) {
this.showNext.classList.remove("hidden");
this.showLast.classList.remove("hidden");
} else {
this.showNext.classList.add("hidden");
this.showLast.classList.add("hidden");
}
this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
},
/**
* @override
*/
createCells: function()
{
this._hasCells = false;
WebInspector.DataGridNode.prototype.createCells.call(this);
},
/**
* @override
* @param {string} columnIdentifier
* @return {!Element}
*/
createCell: function(columnIdentifier)
{
var cell = this.createTD(columnIdentifier);
if (!this._hasCells) {
this._hasCells = true;
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
cell.appendChild(this.showNext);
cell.appendChild(this.showAll);
cell.appendChild(this.showLast);
}
return cell;
},
/**
* @param {number} from
*/
setStartPosition: function(from)
{
this._startPosition = from;
this._updateLabels();
},
/**
* @param {number} to
*/
setEndPosition: function(to)
{
this._endPosition = to;
this._updateLabels();
},
/**
* @override
* @return {number}
*/
nodeSelfHeight: function()
{
return 32;
},
dispose: function()
{
},
__proto__: WebInspector.DataGridNode.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | 2 1 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.ViewportDataGrid}
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columnsArray
* @param {function(!WebInspector.DataGridNode, string, string, string)=} editCallback
* @param {function(!WebInspector.DataGridNode)=} deleteCallback
* @param {function()=} refreshCallback
* @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} contextMenuCallback
*/
WebInspector.SortableDataGrid = function(columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback)
{
WebInspector.ViewportDataGrid.call(this, columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback);
/** @type {!WebInspector.SortableDataGrid.NodeComparator} */
this._sortingFunction = WebInspector.SortableDataGrid.TrivialComparator;
this.setRootNode(new WebInspector.SortableDataGridNode());
}
/** @typedef {function(!WebInspector.DataGridNode, !WebInspector.DataGridNode):number} */
WebInspector.SortableDataGrid.NodeComparator;
/**
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
WebInspector.SortableDataGrid.TrivialComparator = function(a, b)
{
return 0;
}
/**
* @param {string} columnIdentifier
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
WebInspector.SortableDataGrid.NumericComparator = function(columnIdentifier, a, b)
{
var aValue = a.data[columnIdentifier];
var bValue = b.data[columnIdentifier];
var aNumber = Number(aValue instanceof Node ? aValue.textContent : aValue);
var bNumber = Number(bValue instanceof Node ? bValue.textContent : bValue);
return aNumber < bNumber ? -1 : (aNumber > bNumber ? 1 : 0);
}
/**
* @param {string} columnIdentifier
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
WebInspector.SortableDataGrid.StringComparator = function(columnIdentifier, a, b)
{
var aValue = a.data[columnIdentifier];
var bValue = b.data[columnIdentifier];
var aString = aValue instanceof Node ? aValue.textContent : String(aValue);
var bString = bValue instanceof Node ? bValue.textContent : String(bValue);
return aString < bString ? -1 : (aString > bString ? 1 : 0);
}
/**
* @param {!WebInspector.SortableDataGrid.NodeComparator} comparator
* @param {boolean} reverseMode
* @param {!WebInspector.DataGridNode} a
* @param {!WebInspector.DataGridNode} b
* @return {number}
*/
WebInspector.SortableDataGrid.Comparator = function(comparator, reverseMode, a, b)
{
return reverseMode ? comparator(b, a) : comparator(a, b);
}
/**
* @param {!Array.<string>} columnNames
* @param {!Array.<string>} values
* @return {?WebInspector.SortableDataGrid}
*/
WebInspector.SortableDataGrid.create = function(columnNames, values)
{
var numColumns = columnNames.length;
if (!numColumns)
return null;
var columns = [];
for (var i = 0; i < columnNames.length; ++i)
columns.push({ title: columnNames[i], width: columnNames[i].length, sortable: true });
var nodes = [];
for (var i = 0; i < values.length / numColumns; ++i) {
var data = {};
for (var j = 0; j < columnNames.length; ++j)
data[j] = values[numColumns * i + j];
var node = new WebInspector.SortableDataGridNode(data);
node.selectable = false;
nodes.push(node);
}
var dataGrid = new WebInspector.SortableDataGrid(columns);
var length = nodes.length;
var rootNode = dataGrid.rootNode();
for (var i = 0; i < length; ++i)
rootNode.appendChild(nodes[i]);
dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, sortDataGrid);
function sortDataGrid()
{
var nodes = dataGrid.rootNode().children;
var sortColumnIdentifier = dataGrid.sortColumnIdentifier();
if (!sortColumnIdentifier)
return;
var columnIsNumeric = true;
for (var i = 0; i < nodes.length; i++) {
var value = nodes[i].data[sortColumnIdentifier];
if (isNaN(value instanceof Node ? value.textContent : value)) {
columnIsNumeric = false;
break;
}
}
var comparator = columnIsNumeric ? WebInspector.SortableDataGrid.NumericComparator : WebInspector.SortableDataGrid.StringComparator;
dataGrid.sortNodes(comparator.bind(null, sortColumnIdentifier), !dataGrid.isSortOrderAscending());
}
return dataGrid;
}
WebInspector.SortableDataGrid.prototype = {
/**
* @param {!WebInspector.DataGridNode} node
*/
insertChild: function(node)
{
var root = /** @type {!WebInspector.SortableDataGridNode} */ (this.rootNode());
root.insertChildOrdered(node);
},
/**
* @param {!WebInspector.SortableDataGrid.NodeComparator} comparator
* @param {boolean} reverseMode
*/
sortNodes: function(comparator, reverseMode)
{
this._sortingFunction = WebInspector.SortableDataGrid.Comparator.bind(null, comparator, reverseMode);
this._rootNode._sortChildren(reverseMode);
this.scheduleUpdateStructure();
},
__proto__: WebInspector.ViewportDataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.ViewportDataGridNode}
* @param {?Object.<string, *>=} data
* @param {boolean=} hasChildren
*/
WebInspector.SortableDataGridNode = function(data, hasChildren)
{
WebInspector.ViewportDataGridNode.call(this, data, hasChildren);
}
WebInspector.SortableDataGridNode.prototype = {
/**
* @param {!WebInspector.DataGridNode} node
*/
insertChildOrdered: function(node)
{
this.insertChild(node, this.children.upperBound(node, this.dataGrid._sortingFunction));
},
_sortChildren: function()
{
this.children.sort(this.dataGrid._sortingFunction);
for (var i = 0; i < this.children.length; ++i)
this.children[i].recalculateSiblings(i);
for (var child of this.children)
child._sortChildren();
},
__proto__: WebInspector.ViewportDataGridNode.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | 2 | /*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
*/
WebInspector.TimelineGrid = function()
{
this.element = createElement("div");
WebInspector.appendStyle(this.element, "ui_lazy/timelineGrid.css");
this._dividersElement = this.element.createChild("div", "resources-dividers");
this._gridHeaderElement = createElement("div");
this._gridHeaderElement.classList.add("timeline-grid-header");
this._eventDividersElement = this._gridHeaderElement.createChild("div", "resources-event-dividers");
this._dividersLabelBarElement = this._gridHeaderElement.createChild("div", "resources-dividers-label-bar");
this.element.appendChild(this._gridHeaderElement);
this._leftCurtainElement = this.element.createChild("div", "timeline-curtain-left");
this._rightCurtainElement = this.element.createChild("div", "timeline-curtain-right");
}
/**
* @param {!WebInspector.TimelineGrid.Calculator} calculator
* @param {number=} freeZoneAtLeft
* @return {!{offsets: !Array.<number>, precision: number}}
*/
WebInspector.TimelineGrid.calculateDividerOffsets = function(calculator, freeZoneAtLeft)
{
/** @const */ var minGridSlicePx = 64; // minimal distance between grid lines.
var clientWidth = calculator.computePosition(calculator.maximumBoundary());
var dividersCount = clientWidth / minGridSlicePx;
var gridSliceTime = calculator.boundarySpan() / dividersCount;
var pixelsPerTime = clientWidth / calculator.boundarySpan();
// Align gridSliceTime to a nearest round value.
// We allow spans that fit into the formula: span = (1|2|5)x10^n,
// e.g.: ... .1 .2 .5 1 2 5 10 20 50 ...
// After a span has been chosen make grid lines at multiples of the span.
var logGridSliceTime = Math.ceil(Math.log(gridSliceTime) / Math.LN10);
gridSliceTime = Math.pow(10, logGridSliceTime);
if (gridSliceTime * pixelsPerTime >= 5 * minGridSlicePx)
gridSliceTime = gridSliceTime / 5;
if (gridSliceTime * pixelsPerTime >= 2 * minGridSlicePx)
gridSliceTime = gridSliceTime / 2;
var leftBoundaryTime = calculator.minimumBoundary() - calculator.paddingLeft() / pixelsPerTime;
var firstDividerTime = Math.ceil((leftBoundaryTime - calculator.zeroTime()) / gridSliceTime) * gridSliceTime + calculator.zeroTime();
var lastDividerTime = calculator.maximumBoundary();
// Add some extra space past the right boundary as the rightmost divider label text
// may be partially shown rather than just pop up when a new rightmost divider gets into the view.
lastDividerTime += minGridSlicePx / pixelsPerTime;
dividersCount = Math.ceil((lastDividerTime - firstDividerTime) / gridSliceTime);
if (!gridSliceTime)
dividersCount = 0;
var offsets = [];
for (var i = 0; i < dividersCount; ++i) {
var time = firstDividerTime + gridSliceTime * i;
if (calculator.computePosition(time) < freeZoneAtLeft)
continue;
offsets.push(time);
}
return {offsets: offsets, precision: Math.max(0, -Math.floor(Math.log(gridSliceTime * 1.01) / Math.LN10))};
}
/**
* @param {!Object} canvas
* @param {!WebInspector.TimelineGrid.Calculator} calculator
* @param {?Array.<number>=} dividerOffsets
*/
WebInspector.TimelineGrid.drawCanvasGrid = function(canvas, calculator, dividerOffsets)
{
var context = canvas.getContext("2d");
context.save();
var ratio = window.devicePixelRatio;
context.scale(ratio, ratio);
var printDeltas = !!dividerOffsets;
var width = canvas.width / window.devicePixelRatio;
var height = canvas.height / window.devicePixelRatio;
var precision = 0;
if (!dividerOffsets) {
var dividersData = WebInspector.TimelineGrid.calculateDividerOffsets(calculator);
dividerOffsets = dividersData.offsets;
precision = dividersData.precision;
}
context.fillStyle = "rgba(255, 255, 255, 0.5)";
context.fillRect(0, 0, width, 15);
context.fillStyle = "#333";
context.strokeStyle = "rgba(0, 0, 0, 0.1)";
context.textBaseline = "hanging";
context.font = (printDeltas ? "italic bold 11px " : " 11px ") + WebInspector.fontFamily();
context.lineWidth = 1;
context.translate(0.5, 0.5);
const minWidthForTitle = 60;
var lastPosition = 0;
var time = 0;
var lastTime = 0;
var paddingRight = 4;
var paddingTop = 3;
for (var i = 0; i < dividerOffsets.length; ++i) {
time = dividerOffsets[i];
var position = calculator.computePosition(time);
context.beginPath();
if (!printDeltas || i !== 0 && position - lastPosition > minWidthForTitle) {
var text = printDeltas ? calculator.formatTime(calculator.zeroTime() + time - lastTime) : calculator.formatTime(time, precision);
var textWidth = context.measureText(text).width;
var textPosition = printDeltas ? (position + lastPosition - textWidth) / 2 : position - textWidth - paddingRight;
context.fillText(text, textPosition, paddingTop);
}
context.moveTo(position, 0);
context.lineTo(position, height);
context.stroke();
lastTime = time;
lastPosition = position;
}
context.restore();
}
WebInspector.TimelineGrid.prototype = {
get dividersElement()
{
return this._dividersElement;
},
get dividersLabelBarElement()
{
return this._dividersLabelBarElement;
},
removeDividers: function()
{
this._dividersElement.removeChildren();
this._dividersLabelBarElement.removeChildren();
},
/**
* @param {!WebInspector.TimelineGrid.Calculator} calculator
* @param {number=} freeZoneAtLeft
* @return {boolean}
*/
updateDividers: function(calculator, freeZoneAtLeft)
{
var dividersData = WebInspector.TimelineGrid.calculateDividerOffsets(calculator, freeZoneAtLeft);
var dividerOffsets = dividersData.offsets;
var precision = dividersData.precision;
var dividersElementClientWidth = this._dividersElement.clientWidth;
// Reuse divider elements and labels.
var divider = /** @type {?Element} */ (this._dividersElement.firstChild);
var dividerLabelBar = /** @type {?Element} */ (this._dividersLabelBarElement.firstChild);
for (var i = 0; i < dividerOffsets.length; ++i) {
if (!divider) {
divider = createElement("div");
divider.className = "resources-divider";
this._dividersElement.appendChild(divider);
dividerLabelBar = createElement("div");
dividerLabelBar.className = "resources-divider";
var label = createElement("div");
label.className = "resources-divider-label";
dividerLabelBar._labelElement = label;
dividerLabelBar.appendChild(label);
this._dividersLabelBarElement.appendChild(dividerLabelBar);
}
var time = dividerOffsets[i];
var position = calculator.computePosition(time);
dividerLabelBar._labelElement.textContent = calculator.formatTime(time, precision);
var percentLeft = 100 * position / dividersElementClientWidth;
divider.style.left = percentLeft + "%";
dividerLabelBar.style.left = percentLeft + "%";
divider = /** @type {?Element} */ (divider.nextSibling);
dividerLabelBar = /** @type {?Element} */ (dividerLabelBar.nextSibling);
}
// Remove extras.
while (divider) {
var nextDivider = divider.nextSibling;
this._dividersElement.removeChild(divider);
divider = nextDivider;
}
while (dividerLabelBar) {
var nextDivider = dividerLabelBar.nextSibling;
this._dividersLabelBarElement.removeChild(dividerLabelBar);
dividerLabelBar = nextDivider;
}
return true;
},
/**
* @param {!Element} divider
*/
addEventDivider: function(divider)
{
this._eventDividersElement.appendChild(divider);
},
/**
* @param {!Array.<!Element>} dividers
*/
addEventDividers: function(dividers)
{
this._gridHeaderElement.removeChild(this._eventDividersElement);
for (var divider of dividers)
this._eventDividersElement.appendChild(divider);
this._gridHeaderElement.appendChild(this._eventDividersElement);
},
removeEventDividers: function()
{
this._eventDividersElement.removeChildren();
},
hideEventDividers: function()
{
this._eventDividersElement.classList.add("hidden");
},
showEventDividers: function()
{
this._eventDividersElement.classList.remove("hidden");
},
hideDividers: function()
{
this._dividersElement.classList.add("hidden");
},
showDividers: function()
{
this._dividersElement.classList.remove("hidden");
},
hideCurtains: function()
{
this._leftCurtainElement.classList.add("hidden");
this._rightCurtainElement.classList.add("hidden");
},
/**
* @param {number} left
* @param {number} right
*/
showCurtains: function(left, right)
{
this._leftCurtainElement.style.width = (100 * left).toFixed(2) + "%";
this._leftCurtainElement.classList.remove("hidden");
this._rightCurtainElement.style.width = (100 * (1 - right)).toFixed(2) + "%";
this._rightCurtainElement.classList.remove("hidden");
},
/**
* @param {number} scrollTop
*/
setScrollTop: function(scrollTop)
{
this._dividersLabelBarElement.style.top = scrollTop + "px";
this._eventDividersElement.style.top = scrollTop + "px";
this._leftCurtainElement.style.top = scrollTop + "px";
this._rightCurtainElement.style.top = scrollTop + "px";
}
}
/**
* @interface
*/
WebInspector.TimelineGrid.Calculator = function() { }
WebInspector.TimelineGrid.Calculator.prototype = {
/**
* @return {number}
*/
paddingLeft: function() { },
/**
* @param {number} time
* @return {number}
*/
computePosition: function(time) { },
/**
* @param {number} time
* @param {number=} precision
* @return {string}
*/
formatTime: function(time, precision) { },
/** @return {number} */
minimumBoundary: function() { },
/** @return {number} */
zeroTime: function() { },
/** @return {number} */
maximumBoundary: function() { },
/** @return {number} */
boundarySpan: function() { }
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 | 2 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.VBox}
* @param {string} prefix
*/
WebInspector.TimelineOverviewPane = function(prefix)
{
WebInspector.VBox.call(this);
this.element.id = prefix + "-overview-pane";
this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();
this._overviewGrid = new WebInspector.OverviewGrid(prefix);
this.element.appendChild(this._overviewGrid.element);
this._cursorArea = this._overviewGrid.element.createChild("div", "overview-grid-cursor-area");
this._cursorElement = this._overviewGrid.element.createChild("div", "overview-grid-cursor-position");
this._cursorArea.addEventListener("mousemove", this._onMouseMove.bind(this), true);
this._cursorArea.addEventListener("mouseleave", this._hideCursor.bind(this), true);
this._overviewGrid.setResizeEnabled(false);
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.Click, this._onClick, this);
this._overviewControls = [];
this._markers = new Map();
this._popoverHelper = new WebInspector.PopoverHelper(this._cursorArea, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), this._onHidePopover.bind(this));
this._popoverHelper.setTimeout(0);
this._updateThrottler = new WebInspector.Throttler(100);
this._cursorEnabled = false;
this._cursorPosition = 0;
this._lastWidth = 0;
}
WebInspector.TimelineOverviewPane.Events = {
WindowChanged: "WindowChanged"
};
WebInspector.TimelineOverviewPane.prototype = {
/**
* @param {!Element} element
* @param {!Event} event
* @return {!Element|!AnchorBox|undefined}
*/
_getPopoverAnchor: function(element, event)
{
return this._cursorArea;
},
/**
* @param {!Element} anchor
* @param {!WebInspector.Popover} popover
*/
_showPopover: function(anchor, popover)
{
this._buildPopoverContents().then(maybeShowPopover.bind(this));
/**
* @this {WebInspector.TimelineOverviewPane}
* @param {!DocumentFragment} fragment
*/
function maybeShowPopover(fragment)
{
if (!fragment.firstChild)
return;
var content = new WebInspector.TimelineOverviewPane.PopoverContents();
this._popoverContents = content.contentElement.createChild("div");
this._popoverContents.appendChild(fragment);
this._popover = popover;
popover.showView(content, this._cursorElement);
}
},
_onHidePopover: function()
{
this._popover = null;
this._popoverContents = null;
},
/**
* @param {!Event} event
*/
_onMouseMove: function(event)
{
if (!this._cursorEnabled)
return;
this._cursorPosition = event.offsetX + event.target.offsetLeft;
this._cursorElement.style.left = this._cursorPosition + "px";
this._cursorElement.style.visibility = "visible";
if (!this._popover)
return;
this._buildPopoverContents().then(updatePopover.bind(this));
this._popover.positionElement(this._cursorElement);
/**
* @param {!DocumentFragment} fragment
* @this {WebInspector.TimelineOverviewPane}
*/
function updatePopover(fragment)
{
if (!this._popoverContents)
return;
this._popoverContents.removeChildren();
this._popoverContents.appendChild(fragment);
}
},
/**
* @return {!Promise<!DocumentFragment>}
*/
_buildPopoverContents: function()
{
var document = this.element.ownerDocument;
var x = this._cursorPosition;
var promises = this._overviewControls.map(control => control.popoverElementPromise(x));
return Promise.all(promises).then(buildFragment);
/**
* @param {!Array<?Element>} elements
* @return {!DocumentFragment}
*/
function buildFragment(elements)
{
var fragment = document.createDocumentFragment();
elements.remove(null);
fragment.appendChildren.apply(fragment, elements);
return fragment;
}
},
_hideCursor: function()
{
this._cursorElement.style.visibility = "hidden";
},
/**
* @override
*/
wasShown: function()
{
this._update();
},
/**
* @override
*/
willHide: function()
{
this._popoverHelper.hidePopover();
},
/**
* @override
*/
onResize: function()
{
var width = this.element.offsetWidth;
if (width === this._lastWidth)
return;
this._lastWidth = width;
this.scheduleUpdate();
},
/**
* @param {!Array.<!WebInspector.TimelineOverview>} overviewControls
*/
setOverviewControls: function(overviewControls)
{
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].dispose();
for (var i = 0; i < overviewControls.length; ++i) {
overviewControls[i].setCalculator(this._overviewCalculator);
overviewControls[i].show(this._overviewGrid.element);
}
this._overviewControls = overviewControls;
this._update();
},
/**
* @param {number} minimumBoundary
* @param {number} maximumBoundary
*/
setBounds: function(minimumBoundary, maximumBoundary)
{
this._overviewCalculator.setBounds(minimumBoundary, maximumBoundary);
this._overviewGrid.setResizeEnabled(true);
this._cursorEnabled = true;
},
scheduleUpdate: function()
{
this._updateThrottler.schedule(process.bind(this));
/**
* @this {WebInspector.TimelineOverviewPane}
* @return {!Promise.<undefined>}
*/
function process()
{
this._update();
return Promise.resolve();
}
},
_update: function()
{
if (!this.isShowing())
return;
this._overviewCalculator.setDisplayWindow(this._overviewGrid.clientWidth());
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].update();
this._overviewGrid.updateDividers(this._overviewCalculator);
this._updateMarkers();
this._updateWindow();
},
/**
* @param {!Map<number, !Element>} markers
*/
setMarkers: function(markers)
{
this._markers = markers;
this._updateMarkers();
},
_updateMarkers: function()
{
var filteredMarkers = new Map();
for (var time of this._markers.keys()) {
var marker = this._markers.get(time);
var position = Math.round(this._overviewCalculator.computePosition(time));
// Limit the number of markers to one per pixel.
if (filteredMarkers.has(position))
continue;
filteredMarkers.set(position, marker);
marker.style.left = position + "px";
}
this._overviewGrid.removeEventDividers();
this._overviewGrid.addEventDividers(filteredMarkers.valuesArray());
},
reset: function()
{
this._windowStartTime = 0;
this._windowEndTime = Infinity;
this._overviewCalculator.reset();
this._overviewGrid.reset();
this._overviewGrid.setResizeEnabled(false);
this._overviewGrid.updateDividers(this._overviewCalculator);
this._cursorEnabled = false;
this._hideCursor();
this._markers = new Map();
for (var i = 0; i < this._overviewControls.length; ++i)
this._overviewControls[i].reset();
this._popoverHelper.hidePopover();
this._update();
},
/**
* @param {!WebInspector.Event} event
*/
_onClick: function(event)
{
var domEvent = /** @type {!Event} */ (event.data);
for (var overviewControl of this._overviewControls) {
if (overviewControl.onClick(domEvent)) {
event.preventDefault();
return;
}
}
},
/**
* @param {!WebInspector.Event} event
*/
_onWindowChanged: function(event)
{
if (this._muteOnWindowChanged)
return;
// Always use first control as a time converter.
if (!this._overviewControls.length)
return;
var windowTimes = this._overviewControls[0].windowTimes(this._overviewGrid.windowLeft(), this._overviewGrid.windowRight());
this._windowStartTime = windowTimes.startTime;
this._windowEndTime = windowTimes.endTime;
this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged, windowTimes);
},
/**
* @param {number} startTime
* @param {number} endTime
*/
requestWindowTimes: function(startTime, endTime)
{
if (startTime === this._windowStartTime && endTime === this._windowEndTime)
return;
this._windowStartTime = startTime;
this._windowEndTime = endTime;
this._updateWindow();
this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged, { startTime: startTime, endTime: endTime });
},
_updateWindow: function()
{
if (!this._overviewControls.length)
return;
var windowBoundaries = this._overviewControls[0].windowBoundaries(this._windowStartTime, this._windowEndTime);
this._muteOnWindowChanged = true;
this._overviewGrid.setWindow(windowBoundaries.left, windowBoundaries.right);
this._muteOnWindowChanged = false;
},
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.VBox}
*/
WebInspector.TimelineOverviewPane.PopoverContents = function()
{
WebInspector.VBox.call(this, true);
this.contentElement.classList.add("timeline-overview-popover");
}
WebInspector.TimelineOverviewPane.PopoverContents.prototype = {
__proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.TimelineOverviewCalculator = function()
{
this.reset();
}
WebInspector.TimelineOverviewCalculator.prototype = {
/**
* @override
* @return {number}
*/
paddingLeft: function()
{
return this._paddingLeft;
},
/**
* @override
* @param {number} time
* @return {number}
*/
computePosition: function(time)
{
return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this._paddingLeft;
},
/**
* @param {number} position
* @return {number}
*/
positionToTime: function(position)
{
return (position - this._paddingLeft) / this._workingArea * this.boundarySpan() + this._minimumBoundary;
},
/**
* @param {number} minimumBoundary
* @param {number} maximumBoundary
*/
setBounds: function(minimumBoundary, maximumBoundary)
{
this._minimumBoundary = minimumBoundary;
this._maximumBoundary = maximumBoundary;
},
/**
* @param {number} clientWidth
* @param {number=} paddingLeft
*/
setDisplayWindow: function(clientWidth, paddingLeft)
{
this._paddingLeft = paddingLeft || 0;
this._workingArea = clientWidth - this._paddingLeft;
},
reset: function()
{
this.setBounds(0, 1000);
},
/**
* @override
* @param {number} value
* @param {number=} precision
* @return {string}
*/
formatTime: function(value, precision)
{
return Number.preciseMillisToString(value - this.zeroTime(), precision);
},
/**
* @override
* @return {number}
*/
maximumBoundary: function()
{
return this._maximumBoundary;
},
/**
* @override
* @return {number}
*/
minimumBoundary: function()
{
return this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
zeroTime: function()
{
return this._minimumBoundary;
},
/**
* @override
* @return {number}
*/
boundarySpan: function()
{
return this._maximumBoundary - this._minimumBoundary;
}
}
/**
* @interface
*/
WebInspector.TimelineOverview = function()
{
}
WebInspector.TimelineOverview.prototype = {
/**
* @param {?Element} parentElement
* @param {!Element=} insertBefore
*/
show: function(parentElement, insertBefore) { },
update: function() { },
dispose: function() { },
reset: function() { },
/**
* @param {number} x
* @return {!Promise<?Element>}
*/
popoverElementPromise: function(x) { },
/**
* @param {!Event} event
* @return {boolean}
*/
onClick: function(event) { },
/**
* @param {number} windowLeft
* @param {number} windowRight
* @return {!{startTime: number, endTime: number}}
*/
windowTimes: function(windowLeft, windowRight) { },
/**
* @param {number} startTime
* @param {number} endTime
* @return {!{left: number, right: number}}
*/
windowBoundaries: function(startTime, endTime) { },
timelineStarted: function() { },
timelineStopped: function() { },
}
/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TimelineOverview}
*/
WebInspector.TimelineOverviewBase = function()
{
WebInspector.VBox.call(this);
/** @type {?WebInspector.TimelineOverviewCalculator} */
this._calculator = null;
this._canvas = this.element.createChild("canvas", "fill");
this._context = this._canvas.getContext("2d");
}
WebInspector.TimelineOverviewBase.prototype = {
/**
* @override
*/
update: function()
{
this.resetCanvas();
},
/**
* @override
*/
dispose: function()
{
this.detach();
},
/**
* @override
*/
reset: function()
{
},
/**
* @override
* @param {number} x
* @return {!Promise<?Element>}
*/
popoverElementPromise: function(x)
{
return Promise.resolve(/** @type {?Element} */ (null));
},
/**
* @override
*/
timelineStarted: function()
{
},
/**
* @override
*/
timelineStopped: function()
{
},
/**
* @param {!WebInspector.TimelineOverviewCalculator} calculator
*/
setCalculator: function(calculator)
{
this._calculator = calculator;
},
/**
* @override
* @param {!Event} event
* @return {boolean}
*/
onClick: function(event)
{
return false;
},
/**
* @override
* @param {number} windowLeft
* @param {number} windowRight
* @return {!{startTime: number, endTime: number}}
*/
windowTimes: function(windowLeft, windowRight)
{
var absoluteMin = this._calculator.minimumBoundary();
var timeSpan = this._calculator.maximumBoundary() - absoluteMin;
return {
startTime: absoluteMin + timeSpan * windowLeft,
endTime: absoluteMin + timeSpan * windowRight
};
},
/**
* @override
* @param {number} startTime
* @param {number} endTime
* @return {!{left: number, right: number}}
*/
windowBoundaries: function(startTime, endTime)
{
var absoluteMin = this._calculator.minimumBoundary();
var timeSpan = this._calculator.maximumBoundary() - absoluteMin;
var haveRecords = absoluteMin > 0;
return {
left: haveRecords && startTime ? Math.min((startTime - absoluteMin) / timeSpan, 1) : 0,
right: haveRecords && endTime < Infinity ? (endTime - absoluteMin) / timeSpan : 1
};
},
resetCanvas: function()
{
this._canvas.width = this.element.clientWidth * window.devicePixelRatio;
this._canvas.height = this.element.clientHeight * window.devicePixelRatio;
},
__proto__: WebInspector.VBox.prototype
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @extends {WebInspector.DataGrid}
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columnsArray
* @param {function(!WebInspector.DataGridNode, string, string, string)=} editCallback
* @param {function(!WebInspector.DataGridNode)=} deleteCallback
* @param {function()=} refreshCallback
* @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} contextMenuCallback
*/
WebInspector.ViewportDataGrid = function(columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback)
{
WebInspector.DataGrid.call(this, columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback);
this._scrollContainer.addEventListener("scroll", this._onScroll.bind(this), true);
this._scrollContainer.addEventListener("mousewheel", this._onWheel.bind(this), true);
/** @type {!Array.<!WebInspector.ViewportDataGridNode>} */
this._visibleNodes = [];
/** @type {?Array.<!WebInspector.ViewportDataGridNode>} */
this._flatNodes = null;
/** @type {boolean} */
this._inline = false;
// Wheel target shouldn't be removed from DOM to preserve native kinetic scrolling.
/** @type {?Node} */
this._wheelTarget = null;
// Element that was hidden earlier, but hasn't been removed yet.
/** @type {?Node} */
this._hiddenWheelTarget = null;
/** @type {boolean} */
this._stickToBottom = false;
/** @type {boolean} */
this._atBottom = true;
/** @type {number} */
this._lastScrollTop = 0;
this.setRootNode(new WebInspector.ViewportDataGridNode());
}
WebInspector.ViewportDataGrid.prototype = {
/**
* @override
*/
onResize: function()
{
if (this._stickToBottom && this._atBottom)
this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.clientHeight;
this.scheduleUpdate();
WebInspector.DataGrid.prototype.onResize.call(this);
},
/**
* @param {boolean} stick
*/
setStickToBottom: function(stick)
{
this._stickToBottom = stick;
},
/**
* @param {?Event} event
*/
_onWheel: function(event)
{
this._wheelTarget = event.target ? event.target.enclosingNodeOrSelfWithNodeName("tr") : null;
},
/**
* @param {?Event} event
*/
_onScroll: function(event)
{
this._atBottom = this._scrollContainer.isScrolledToBottom();
if (this._lastScrollTop !== this._scrollContainer.scrollTop)
this.scheduleUpdate();
},
/**
* @protected
*/
scheduleUpdateStructure: function()
{
this._flatNodes = null;
this.scheduleUpdate();
},
/**
* @protected
*/
scheduleUpdate: function()
{
if (this._updateAnimationFrameId)
return;
this._updateAnimationFrameId = this.element.window().requestAnimationFrame(this._update.bind(this));
},
updateInstantlyForTests: function()
{
if (!this._updateAnimationFrameId)
return;
this.element.window().cancelAnimationFrame(this._updateAnimationFrameId);
this._update();
},
/**
* @override
*/
renderInline: function()
{
this._inline = true;
WebInspector.DataGrid.prototype.renderInline.call(this);
this._update();
},
/**
* @return {!Array.<!WebInspector.ViewportDataGridNode>}
*/
_flatNodesList: function()
{
if (this._flatNodes)
return this._flatNodes;
var flatNodes = [];
var children = [this._rootNode.children];
var counters = [0];
var depth = 0;
while (depth >= 0) {
var node = children[depth][counters[depth]++];
if (!node) {
depth--;
continue;
}
flatNodes.push(node);
node.setDepth(depth);
if (node._expanded && node.children.length) {
depth++;
children[depth] = node.children;
counters[depth] = 0;
}
}
this._flatNodes = flatNodes;
return this._flatNodes;
},
/**
* @param {number} clientHeight
* @param {number} scrollTop
* @return {{topPadding: number, bottomPadding: number, contentHeight: number, visibleNodes: !Array.<!WebInspector.ViewportDataGridNode>, offset: number}}
*/
_calculateVisibleNodes: function(clientHeight, scrollTop)
{
var nodes = this._flatNodesList();
if (this._inline)
return {topPadding: 0, bottomPadding: 0, contentHeight: 0, visibleNodes: nodes, offset: 0};
var size = nodes.length;
var i = 0;
var y = 0;
for (; i < size && y + nodes[i].nodeSelfHeight() < scrollTop; ++i)
y += nodes[i].nodeSelfHeight();
var start = i;
var topPadding = y;
for (; i < size && y < scrollTop + clientHeight; ++i)
y += nodes[i].nodeSelfHeight();
var end = i;
var bottomPadding = 0;
for (; i < size; ++i)
bottomPadding += nodes[i].nodeSelfHeight();
return {topPadding: topPadding, bottomPadding: bottomPadding, contentHeight: y - topPadding, visibleNodes: nodes.slice(start, end), offset: start};
},
/**
* @return {number}
*/
_contentHeight: function()
{
var nodes = this._flatNodesList();
var result = 0;
for (var i = 0, size = nodes.length; i < size; ++i)
result += nodes[i].nodeSelfHeight();
return result;
},
_update: function()
{
delete this._updateAnimationFrameId;
var clientHeight = this._scrollContainer.clientHeight;
var scrollTop = this._scrollContainer.scrollTop;
var currentScrollTop = scrollTop;
var maxScrollTop = Math.max(0, this._contentHeight() - clientHeight);
if (this._stickToBottom && this._atBottom)
scrollTop = maxScrollTop;
scrollTop = Math.min(maxScrollTop, scrollTop);
this._atBottom = scrollTop === maxScrollTop;
var viewportState = this._calculateVisibleNodes(clientHeight, scrollTop);
var visibleNodes = viewportState.visibleNodes;
var visibleNodesSet = new Set(visibleNodes);
if (this._hiddenWheelTarget && this._hiddenWheelTarget !== this._wheelTarget) {
this._hiddenWheelTarget.remove();
this._hiddenWheelTarget = null;
}
for (var i = 0; i < this._visibleNodes.length; ++i) {
var oldNode = this._visibleNodes[i];
if (!visibleNodesSet.has(oldNode) && oldNode.attached()) {
var element = oldNode._element;
if (element === this._wheelTarget)
this._hiddenWheelTarget = oldNode.abandonElement();
else
element.remove();
oldNode.wasDetached();
}
}
var previousElement = this._topFillerRow;
if (previousElement.nextSibling === this._hiddenWheelTarget)
previousElement = this._hiddenWheelTarget;
var tBody = this.dataTableBody;
var offset = viewportState.offset;
for (var i = 0; i < visibleNodes.length; ++i) {
var node = visibleNodes[i];
var element = node.element();
node.willAttach();
element.classList.toggle("odd", (offset + i) % 2 === 0);
tBody.insertBefore(element, previousElement.nextSibling);
previousElement = element;
}
this.setVerticalPadding(viewportState.topPadding, viewportState.bottomPadding);
this._lastScrollTop = scrollTop;
if (scrollTop !== currentScrollTop)
this._scrollContainer.scrollTop = scrollTop;
var contentFits = viewportState.contentHeight <= clientHeight && viewportState.topPadding + viewportState.bottomPadding === 0;
if (contentFits !== this.element.classList.contains("data-grid-fits-viewport")) {
this.element.classList.toggle("data-grid-fits-viewport", contentFits);
this.updateWidths();
}
this._visibleNodes = visibleNodes;
},
/**
* @param {!WebInspector.ViewportDataGridNode} node
*/
_revealViewportNode: function(node)
{
var nodes = this._flatNodesList();
var index = nodes.indexOf(node);
if (index === -1)
return;
var fromY = 0;
for (var i = 0; i < index; ++i)
fromY += nodes[i].nodeSelfHeight();
var toY = fromY + node.nodeSelfHeight();
var scrollTop = this._scrollContainer.scrollTop;
if (scrollTop > fromY) {
scrollTop = fromY;
this._atBottom = false;
} else if (scrollTop + this._scrollContainer.offsetHeight < toY) {
scrollTop = toY - this._scrollContainer.offsetHeight;
}
this._scrollContainer.scrollTop = scrollTop;
},
__proto__: WebInspector.DataGrid.prototype
}
/**
* @constructor
* @extends {WebInspector.DataGridNode}
* @param {?Object.<string, *>=} data
* @param {boolean=} hasChildren
*/
WebInspector.ViewportDataGridNode = function(data, hasChildren)
{
WebInspector.DataGridNode.call(this, data, hasChildren);
/** @type {boolean} */
this._stale = false;
}
WebInspector.ViewportDataGridNode.prototype = {
/**
* @override
* @return {!Element}
*/
element: function()
{
if (!this._element) {
this.createElement();
this.createCells();
this._stale = false;
}
if (this._stale) {
this.createCells();
this._stale = false;
}
return /** @type {!Element} */ (this._element);
},
/**
* @param {number} depth
*/
setDepth: function(depth)
{
this._depth = depth;
},
/**
* @override
* @param {!WebInspector.DataGridNode} child
* @param {number} index
*/
insertChild: function(child, index)
{
if (child.parent === this) {
var currentIndex = this.children.indexOf(child);
if (currentIndex < 0)
console.assert(false, "Inconsistent DataGrid state");
if (currentIndex === index)
return;
if (currentIndex < index)
--index;
}
child.remove();
child.parent = this;
child.dataGrid = this.dataGrid;
if (!this.children.length)
this.hasChildren = true;
this.children.splice(index, 0, child);
child.recalculateSiblings(index);
if (this._expanded)
this.dataGrid.scheduleUpdateStructure();
},
/**
* @override
* @param {!WebInspector.DataGridNode} child
*/
removeChild: function(child)
{
if (this.dataGrid)
this.dataGrid.updateSelectionBeforeRemoval(child, false);
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
if (child.parent !== this)
throw("removeChild: Node is not a child of this node.");
child._unlink();
this.children.remove(child, true);
if (!this.children.length)
this.hasChildren = false;
if (this._expanded)
this.dataGrid.scheduleUpdateStructure();
},
/**
* @override
*/
removeChildren: function()
{
if (this.dataGrid)
this.dataGrid.updateSelectionBeforeRemoval(this, true);
for (var i = 0; i < this.children.length; ++i)
this.children[i]._unlink();
this.children = [];
if (this._expanded)
this.dataGrid.scheduleUpdateStructure();
},
_unlink: function()
{
if (this.attached()) {
this._element.remove();
this.wasDetached();
}
this.dataGrid = null;
this.parent = null;
this.nextSibling = null;
this.previousSibling = null;
},
/**
* @override
*/
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
if (this._element)
this._element.classList.remove("expanded");
this.dataGrid.scheduleUpdateStructure();
},
/**
* @override
*/
expand: function()
{
if (this._expanded)
return;
WebInspector.DataGridNode.prototype.expand.call(this);
this.dataGrid.scheduleUpdateStructure();
},
/**
* @protected
*/
willAttach: function() { },
/**
* @protected
* @return {boolean}
*/
attached: function()
{
return !!(this.dataGrid && this._element && this._element.parentElement);
},
/**
* @override
*/
refresh: function()
{
if (this.attached()) {
this._stale = true;
this.dataGrid.scheduleUpdate();
} else {
this._element = null;
}
},
/**
* @return {?Element}
*/
abandonElement: function()
{
var result = this._element;
if (result)
result.style.display = "none";
this._element = null;
return result;
},
reveal: function()
{
this.dataGrid._revealViewportNode(this);
},
__proto__: WebInspector.DataGridNode.prototype
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| FileManager.js | 3.23% | (1 / 31) | 0% | (0 / 4) | 0% | (0 / 9) | 3.23% | (1 / 31) | |
| FileSystemMapping.js | 0.76% | (1 / 132) | 0% | (0 / 53) | 0% | (0 / 21) | 0.76% | (1 / 132) | |
| IsolatedFileSystem.js | 15.35% | (31 / 202) | 0% | (0 / 56) | 0% | (0 / 54) | 15.42% | (31 / 201) | |
| IsolatedFileSystemManager.js | 2.54% | (3 / 118) | 0% | (0 / 28) | 0% | (0 / 25) | 2.56% | (3 / 117) | |
| SearchConfig.js | 1.39% | (1 / 72) | 0% | (0 / 30) | 0% | (0 / 13) | 1.39% | (1 / 72) | |
| UISourceCode.js | 2.49% | (7 / 281) | 0% | (0 / 114) | 0% | (0 / 87) | 2.52% | (7 / 278) | |
| Workspace.js | 3.26% | (3 / 92) | 0% | (0 / 21) | 0% | (0 / 54) | 3.26% | (3 / 92) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.FileManager = function()
{
this._savedURLsSetting = WebInspector.settings.createLocalSetting("savedURLs", {});
/** @type {!Object.<string, ?function(boolean)>} */
this._saveCallbacks = {};
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SavedURL, this._savedURL, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.CanceledSaveURL, this._canceledSaveURL, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.AppendedToURL, this._appendedToURL, this);
}
WebInspector.FileManager.EventTypes = {
SavedURL: "SavedURL",
AppendedToURL: "AppendedToURL"
}
WebInspector.FileManager.prototype = {
/**
* @param {string} url
* @param {string} content
* @param {boolean} forceSaveAs
* @param {function(boolean)=} callback
*/
save: function(url, content, forceSaveAs, callback)
{
// Remove this url from the saved URLs while it is being saved.
var savedURLs = this._savedURLsSetting.get();
delete savedURLs[url];
this._savedURLsSetting.set(savedURLs);
this._saveCallbacks[url] = callback || null;
InspectorFrontendHost.save(url, content, forceSaveAs);
},
/**
* @param {!WebInspector.Event} event
*/
_savedURL: function(event)
{
var url = /** @type {string} */ (event.data);
var savedURLs = this._savedURLsSetting.get();
savedURLs[url] = true;
this._savedURLsSetting.set(savedURLs);
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url);
this._invokeSaveCallback(url, true);
},
/**
* @param {string} url
* @param {boolean} accepted
*/
_invokeSaveCallback: function(url, accepted)
{
var callback = this._saveCallbacks[url];
delete this._saveCallbacks[url];
if (callback)
callback(accepted);
},
/**
* @param {!WebInspector.Event} event
*/
_canceledSaveURL: function(event)
{
var url = /** @type {string} */ (event.data);
this._invokeSaveCallback(url, false);
},
/**
* @param {string} url
* @return {boolean}
*/
isURLSaved: function(url)
{
var savedURLs = this._savedURLsSetting.get();
return savedURLs[url];
},
/**
* @param {string} url
* @param {string} content
*/
append: function(url, content)
{
InspectorFrontendHost.append(url, content);
},
/**
* @param {string} url
*/
close: function(url)
{
// Currently a no-op.
},
/**
* @param {!WebInspector.Event} event
*/
_appendedToURL: function(event)
{
var url = /** @type {string} */ (event.data);
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url);
},
__proto__: WebInspector.Object.prototype
}
/**
* @type {?WebInspector.FileManager}
*/
WebInspector.fileManager = null;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | 2 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.FileSystemMapping = function()
{
WebInspector.Object.call(this);
this._fileSystemMappingSetting = WebInspector.settings.createLocalSetting("fileSystemMapping", {});
/** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>} */
this._fileSystemMappings = {};
this._loadFromSettings();
}
WebInspector.FileSystemMapping.Events = {
FileMappingAdded: "FileMappingAdded",
FileMappingRemoved: "FileMappingRemoved"
}
WebInspector.FileSystemMapping.prototype = {
_loadFromSettings: function()
{
var savedMapping = this._fileSystemMappingSetting.get();
this._fileSystemMappings = {};
for (var fileSystemPath in savedMapping) {
var savedFileSystemMappings = savedMapping[fileSystemPath];
fileSystemPath = WebInspector.IsolatedFileSystemManager.normalizePath(fileSystemPath);
this._fileSystemMappings[fileSystemPath] = [];
var fileSystemMappings = this._fileSystemMappings[fileSystemPath];
for (var i = 0; i < savedFileSystemMappings.length; ++i) {
var savedEntry = savedFileSystemMappings[i];
var entry = new WebInspector.FileSystemMapping.Entry(fileSystemPath, savedEntry.urlPrefix, savedEntry.pathPrefix, true);
fileSystemMappings.push(entry);
}
}
this._rebuildIndexes();
},
_saveToSettings: function()
{
var setting = {};
for (var fileSystemPath in this._fileSystemMappings) {
setting[fileSystemPath] = [];
var entries = this._fileSystemMappings[fileSystemPath];
for (var entry of entries) {
if (entry.configurable)
setting[fileSystemPath].push(entry);
}
}
this._fileSystemMappingSetting.set(setting);
},
_rebuildIndexes: function()
{
// We are building an index here to search for the longest url prefix match faster.
this._mappingForURLPrefix = {};
this._urlPrefixes = [];
for (var fileSystemPath in this._fileSystemMappings) {
var fileSystemMapping = this._fileSystemMappings[fileSystemPath];
for (var i = 0; i < fileSystemMapping.length; ++i) {
var entry = fileSystemMapping[i];
// Resolve conflict in favor of configurable mapping.
if (this._mappingForURLPrefix[entry.urlPrefix] && !entry.configurable)
continue;
this._mappingForURLPrefix[entry.urlPrefix] = entry;
if (this._urlPrefixes.indexOf(entry.urlPrefix) === -1)
this._urlPrefixes.push(entry.urlPrefix);
}
}
this._urlPrefixes.sort();
},
/**
* @param {string} fileSystemPath
*/
addFileSystem: function(fileSystemPath)
{
if (this._fileSystemMappings[fileSystemPath])
return;
this._fileSystemMappings[fileSystemPath] = [];
this._saveToSettings();
},
/**
* @param {string} fileSystemPath
*/
removeFileSystem: function(fileSystemPath)
{
if (!this._fileSystemMappings[fileSystemPath])
return;
delete this._fileSystemMappings[fileSystemPath];
this._rebuildIndexes();
this._saveToSettings();
},
/**
* @param {string} fileSystemPath
* @param {string} urlPrefix
* @param {string} pathPrefix
*/
addFileMapping: function(fileSystemPath, urlPrefix, pathPrefix)
{
if (!urlPrefix.endsWith("/"))
urlPrefix += "/";
if (!pathPrefix.endsWith("/"))
pathPrefix += "/";
if (!pathPrefix.startsWith("/"))
pathPrefix = "/" + pathPrefix;
this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, true);
this._saveToSettings();
},
/**
* @param {string} fileSystemPath
* @param {string} urlPrefix
* @param {string} pathPrefix
*/
addNonConfigurableFileMapping: function(fileSystemPath, urlPrefix, pathPrefix)
{
this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, false);
},
/**
* @param {string} fileSystemPath
* @param {string} urlPrefix
* @param {string} pathPrefix
* @param {boolean} configurable
*/
_innerAddFileMapping: function(fileSystemPath, urlPrefix, pathPrefix, configurable)
{
var entry = new WebInspector.FileSystemMapping.Entry(fileSystemPath, urlPrefix, pathPrefix, configurable);
this._fileSystemMappings[fileSystemPath].push(entry);
this._rebuildIndexes();
this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingAdded, entry);
},
/**
* @param {string} fileSystemPath
* @param {string} urlPrefix
* @param {string} pathPrefix
*/
removeFileMapping: function(fileSystemPath, urlPrefix, pathPrefix)
{
var entry = this._configurableMappingEntryForPathPrefix(fileSystemPath, pathPrefix);
if (!entry)
return;
this._fileSystemMappings[fileSystemPath].remove(entry);
this._rebuildIndexes();
this._saveToSettings();
this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingRemoved, entry);
},
/**
* @param {string} url
* @return {?WebInspector.FileSystemMapping.Entry}
*/
_mappingEntryForURL: function(url)
{
for (var i = this._urlPrefixes.length - 1; i >= 0; --i) {
var urlPrefix = this._urlPrefixes[i];
if (url.startsWith(urlPrefix))
return this._mappingForURLPrefix[urlPrefix];
}
return null;
},
/**
* @param {string} fileSystemPath
* @param {string} filePath
* @return {?WebInspector.FileSystemMapping.Entry}
*/
_mappingEntryForPath: function(fileSystemPath, filePath)
{
var entries = this._fileSystemMappings[fileSystemPath];
if (!entries)
return null;
var entry = null;
for (var i = 0; i < entries.length; ++i) {
var pathPrefix = entries[i].pathPrefix;
if (entry && entry.configurable && !entries[i].configurable)
continue;
// We are looking for the longest pathPrefix match.
if (entry && entry.pathPrefix.length > pathPrefix.length)
continue;
if (filePath.startsWith(pathPrefix))
entry = entries[i];
}
return entry;
},
/**
* @param {string} fileSystemPath
* @param {string} pathPrefix
* @return {?WebInspector.FileSystemMapping.Entry}
*/
_configurableMappingEntryForPathPrefix: function(fileSystemPath, pathPrefix)
{
var entries = this._fileSystemMappings[fileSystemPath];
for (var i = 0; i < entries.length; ++i) {
if (entries[i].configurable && pathPrefix === entries[i].pathPrefix)
return entries[i];
}
return null;
},
/**
* @param {string} fileSystemPath
* @return {!Array.<!WebInspector.FileSystemMapping.Entry>}
*/
mappingEntries: function(fileSystemPath)
{
return this._fileSystemMappings[fileSystemPath].slice();
},
/**
* @param {string} url
* @return {boolean}
*/
hasMappingForNetworkURL: function(url)
{
return !!this._mappingEntryForURL(url);
},
/**
* @param {string} url
* @return {?{fileSystemPath: string, fileURL: string}}
*/
fileForURL: function(url)
{
var entry = this._mappingEntryForURL(url);
if (!entry)
return null;
var file = {};
file.fileSystemPath = entry.fileSystemPath;
file.fileURL = entry.fileSystemPath + entry.pathPrefix + url.substr(entry.urlPrefix.length);
return file;
},
/**
* @param {string} fileSystemPath
* @param {string} filePath
* @return {string}
*/
networkURLForFileSystemURL: function(fileSystemPath, filePath)
{
var relativePath = filePath.substring(fileSystemPath.length);
var entry = this._mappingEntryForPath(fileSystemPath, relativePath);
if (!entry)
return "";
return entry.urlPrefix + relativePath.substring(entry.pathPrefix.length);
},
/**
* @param {string} url
*/
removeMappingForURL: function(url)
{
var entry = this._mappingEntryForURL(url);
if (!entry || !entry.configurable)
return;
this._fileSystemMappings[entry.fileSystemPath].remove(entry);
this._saveToSettings();
},
/**
* @param {string} url
* @param {string} fileSystemPath
* @param {string} filePath
*/
addMappingForResource: function(url, fileSystemPath, filePath)
{
var commonPathSuffixLength = 0;
for (var i = 0; i < filePath.length; ++i) {
var filePathCharacter = filePath[filePath.length - 1 - i];
var urlCharacter = url[url.length - 1 - i];
if (filePathCharacter !== urlCharacter)
break;
if (filePathCharacter === "/")
commonPathSuffixLength = i;
}
var from = fileSystemPath.length;
var to = filePath.length - commonPathSuffixLength;
var pathPrefix = filePath.substring(from, to);
var urlPrefix = url.substr(0, url.length - commonPathSuffixLength);
if (to >= from)
this.addFileMapping(fileSystemPath, urlPrefix, pathPrefix);
else
this.addFileMapping(fileSystemPath, urlPrefix + pathPrefix, "/");
},
resetForTesting: function()
{
this._fileSystemMappings = {};
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {string} fileSystemPath
* @param {string} urlPrefix
* @param {string} pathPrefix
* @param {boolean} configurable
*/
WebInspector.FileSystemMapping.Entry = function(fileSystemPath, urlPrefix, pathPrefix, configurable)
{
this.fileSystemPath = fileSystemPath;
this.urlPrefix = urlPrefix;
this.pathPrefix = pathPrefix;
this.configurable = configurable;
}
/**
* @type {!WebInspector.FileSystemMapping}
*/
WebInspector.fileSystemMapping;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {!WebInspector.IsolatedFileSystemManager} manager
* @param {string} path
* @param {string} embedderPath
* @param {!DOMFileSystem} domFileSystem
*/
WebInspector.IsolatedFileSystem = function(manager, path, embedderPath, domFileSystem)
{
this._manager = manager;
this._path = path;
this._embedderPath = embedderPath;
this._domFileSystem = domFileSystem;
this._excludedFoldersSetting = WebInspector.settings.createLocalSetting("workspaceExcludedFolders", {});
/** @type {!Set<string>} */
this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] || []);
/** @type {!Set<string>} */
this._nonConfigurableExcludedFolders = new Set();
}
WebInspector.IsolatedFileSystem.ImageExtensions = new Set(["jpeg", "jpg", "svg", "gif", "webp", "png", "ico", "tiff", "tif", "bmp"]);
/**
* @constructor
* @param {!WebInspector.IsolatedFileSystemManager} manager
* @param {string} path
* @param {string} embedderPath
* @param {string} name
* @param {string} rootURL
* @return {!Promise<?WebInspector.IsolatedFileSystem>}
*/
WebInspector.IsolatedFileSystem.create = function(manager, path, embedderPath, name, rootURL)
{
return new Promise(promiseBody);
/**
* @param {function(?WebInspector.IsolatedFileSystem)} resolve
* @param {function(!Error)} reject
*/
function promiseBody(resolve, reject)
{
var domFileSystem = InspectorFrontendHost.isolatedFileSystem(name, rootURL);
if (!domFileSystem) {
resolve(null);
return;
}
var fileSystem = new WebInspector.IsolatedFileSystem(manager, path, embedderPath, domFileSystem);
fileSystem.requestFileContent(".devtools", onConfigAvailable);
/**
* @param {?string} projectText
*/
function onConfigAvailable(projectText)
{
if (projectText) {
try {
var projectObject = JSON.parse(projectText);
fileSystem._initializeProject(typeof projectObject === "object" ? /** @type {!Object} */ (projectObject) : null);
} catch (e) {
WebInspector.console.error("Invalid project file: " + projectText);
}
}
resolve(fileSystem);
}
}
}
/**
* @param {!FileError} error
* @return {string}
*/
WebInspector.IsolatedFileSystem.errorMessage = function(error)
{
return WebInspector.UIString("File system error: %s", error.message);
}
WebInspector.IsolatedFileSystem.prototype = {
/**
* @return {string}
*/
path: function()
{
return this._path;
},
/**
* @return {string}
*/
embedderPath: function()
{
return this._embedderPath;
},
/**
* @param {?Object} projectObject
*/
_initializeProject: function(projectObject)
{
this._projectObject = projectObject;
var projectExcludes = this.projectProperty("excludes");
if (Array.isArray(projectExcludes)) {
for (var folder of /** @type {!Array<*>} */ (projectExcludes)) {
if (typeof folder === "string")
this._nonConfigurableExcludedFolders.add(folder);
}
}
},
/**
* @param {string} key
* @return {*}
*/
projectProperty: function(key)
{
return this._projectObject ? this._projectObject[key] : null;
},
/**
* @param {string} path
* @param {function(string)} fileCallback
* @param {function()=} finishedCallback
*/
requestFilesRecursive: function(path, fileCallback, finishedCallback)
{
var pendingRequests = 1;
this._requestEntries(path, innerCallback.bind(this));
/**
* @param {!Array.<!FileEntry>} entries
* @this {WebInspector.IsolatedFileSystem}
*/
function innerCallback(entries)
{
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (!entry.isDirectory) {
if (this._isFileExcluded(entry.fullPath))
continue;
fileCallback(entry.fullPath.substr(1));
} else {
if (this._isFileExcluded(entry.fullPath + "/"))
continue;
++pendingRequests;
this._requestEntries(entry.fullPath, innerCallback.bind(this));
}
}
if (finishedCallback && (--pendingRequests === 0))
finishedCallback();
}
},
/**
* @param {string} path
* @param {?string} name
* @param {function(?string)} callback
*/
createFile: function(path, name, callback)
{
var newFileIndex = 1;
if (!name)
name = "NewFile";
var nameCandidate;
this._domFileSystem.root.getDirectory(path, null, dirEntryLoaded.bind(this), errorHandler.bind(this));
/**
* @param {!DirectoryEntry} dirEntry
* @this {WebInspector.IsolatedFileSystem}
*/
function dirEntryLoaded(dirEntry)
{
var nameCandidate = name;
if (newFileIndex > 1)
nameCandidate += newFileIndex;
++newFileIndex;
dirEntry.getFile(nameCandidate, { create: true, exclusive: true }, fileCreated, fileCreationError.bind(this));
function fileCreated(entry)
{
callback(entry.fullPath.substr(1));
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function fileCreationError(error)
{
if (error.code === FileError.INVALID_MODIFICATION_ERR) {
dirEntryLoaded.call(this, dirEntry);
return;
}
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when testing if file exists '" + (this._path + "/" + path + "/" + nameCandidate) + "'");
callback(null);
}
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
var filePath = this._path + "/" + path;
if (nameCandidate)
filePath += "/" + nameCandidate;
console.error(errorMessage + " when getting content for file '" + (filePath) + "'");
callback(null);
}
},
/**
* @param {string} path
*/
deleteFile: function(path)
{
this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), errorHandler.bind(this));
/**
* @param {!FileEntry} fileEntry
* @this {WebInspector.IsolatedFileSystem}
*/
function fileEntryLoaded(fileEntry)
{
fileEntry.remove(fileEntryRemoved, errorHandler.bind(this));
}
function fileEntryRemoved()
{
}
/**
* @param {!FileError} error
* @this {WebInspector.IsolatedFileSystem}
*/
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when deleting file '" + (this._path + "/" + path) + "'");
}
},
/**
* @param {string} path
* @param {function(?string)} callback
*/
requestFileContent: function(path, callback)
{
this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), errorHandler.bind(this));
/**
* @param {!FileEntry} entry
* @this {WebInspector.IsolatedFileSystem}
*/
function fileEntryLoaded(entry)
{
entry.file(fileLoaded, errorHandler.bind(this));
}
/**
* @param {!Blob} file
*/
function fileLoaded(file)
{
var reader = new FileReader();
reader.onloadend = readerLoadEnd;
if (WebInspector.IsolatedFileSystem.ImageExtensions.has(WebInspector.TextUtils.extension(path)))
reader.readAsDataURL(file);
else
reader.readAsText(file);
}
/**
* @this {!FileReader}
*/
function readerLoadEnd()
{
/** @type {?string} */
var string = null;
try {
string = /** @type {string} */ (this.result);
} catch (e) {
console.error("Can't read file: " + path + ": " + e);
}
callback(string);
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function errorHandler(error)
{
if (error.code === FileError.NOT_FOUND_ERR) {
callback(null);
return;
}
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when getting content for file '" + (this._path + "/" + path) + "'");
callback(null);
}
},
/**
* @param {string} path
* @param {string} content
* @param {function()} callback
*/
setFileContent: function(path, content, callback)
{
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.FileSavedInWorkspace);
this._domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded.bind(this), errorHandler.bind(this));
/**
* @param {!FileEntry} entry
* @this {WebInspector.IsolatedFileSystem}
*/
function fileEntryLoaded(entry)
{
entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this));
}
/**
* @param {!FileWriter} fileWriter
* @this {WebInspector.IsolatedFileSystem}
*/
function fileWriterCreated(fileWriter)
{
fileWriter.onerror = errorHandler.bind(this);
fileWriter.onwriteend = fileWritten;
var blob = new Blob([content], { type: "text/plain" });
fileWriter.write(blob);
function fileWritten()
{
fileWriter.onwriteend = callback;
fileWriter.truncate(blob.size);
}
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when setting content for file '" + (this._path + "/" + path) + "'");
callback();
}
},
/**
* @param {string} path
* @param {string} newName
* @param {function(boolean, string=)} callback
*/
renameFile: function(path, newName, callback)
{
newName = newName ? newName.trim() : newName;
if (!newName || newName.indexOf("/") !== -1) {
callback(false);
return;
}
var fileEntry;
var dirEntry;
this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), errorHandler.bind(this));
/**
* @param {!FileEntry} entry
* @this {WebInspector.IsolatedFileSystem}
*/
function fileEntryLoaded(entry)
{
if (entry.name === newName) {
callback(false);
return;
}
fileEntry = entry;
fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this));
}
/**
* @param {!Entry} entry
* @this {WebInspector.IsolatedFileSystem}
*/
function dirEntryLoaded(entry)
{
dirEntry = entry;
dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorHandler.bind(this));
}
/**
* @param {!FileEntry} entry
*/
function newFileEntryLoaded(entry)
{
callback(false);
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function newFileEntryLoadErrorHandler(error)
{
if (error.code !== FileError.NOT_FOUND_ERR) {
callback(false);
return;
}
fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(this));
}
/**
* @param {!FileEntry} entry
*/
function fileRenamed(entry)
{
callback(true, entry.name);
}
/**
* @this {WebInspector.IsolatedFileSystem}
*/
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when renaming file '" + (this._path + "/" + path) + "' to '" + newName + "'");
callback(false);
}
},
/**
* @param {!DirectoryEntry} dirEntry
* @param {function(!Array.<!FileEntry>)} callback
*/
_readDirectory: function(dirEntry, callback)
{
var dirReader = dirEntry.createReader();
var entries = [];
function innerCallback(results)
{
if (!results.length) {
callback(entries.sort());
} else {
entries = entries.concat(toArray(results));
dirReader.readEntries(innerCallback, errorHandler);
}
}
function toArray(list)
{
return Array.prototype.slice.call(list || [], 0);
}
dirReader.readEntries(innerCallback, errorHandler);
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when reading directory '" + dirEntry.fullPath + "'");
callback([]);
}
},
/**
* @param {string} path
* @param {function(!Array.<!FileEntry>)} callback
*/
_requestEntries: function(path, callback)
{
this._domFileSystem.root.getDirectory(path, null, innerCallback.bind(this), errorHandler);
/**
* @param {!DirectoryEntry} dirEntry
* @this {WebInspector.IsolatedFileSystem}
*/
function innerCallback(dirEntry)
{
this._readDirectory(dirEntry, callback);
}
function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when requesting entry '" + path + "'");
callback([]);
}
},
_saveExcludedFolders: function()
{
var settingValue = this._excludedFoldersSetting.get();
settingValue[this._path] = Array.from(this._excludedFolders.values());
this._excludedFoldersSetting.set(settingValue);
},
/**
* @param {string} path
*/
addExcludedFolder: function(path)
{
this._excludedFolders.add(path);
this._saveExcludedFolders();
this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderAdded, path);
},
/**
* @param {string} path
*/
removeExcludedFolder: function(path)
{
this._excludedFolders.delete(path);
this._saveExcludedFolders();
this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, path);
},
fileSystemRemoved: function()
{
var settingValue = this._excludedFoldersSetting.get();
delete settingValue[this._path];
this._excludedFoldersSetting.set(settingValue);
},
/**
* @param {string} folderPath
* @return {boolean}
*/
_isFileExcluded: function(folderPath)
{
if (this._nonConfigurableExcludedFolders.has(folderPath) || this._excludedFolders.has(folderPath))
return true;
var regex = this._manager.workspaceFolderExcludePatternSetting().asRegExp();
return !!(regex && regex.test(folderPath));
},
/**
* @return {!Set<string>}
*/
excludedFolders: function()
{
return this._excludedFolders;
},
/**
* @return {!Set<string>}
*/
nonConfigurableExcludedFolders: function()
{
return this._nonConfigurableExcludedFolders;
},
/**
* @param {string} query
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
searchInPath: function(query, progress, callback)
{
var requestId = this._manager.registerCallback(innerCallback);
InspectorFrontendHost.searchInPath(requestId, this._embedderPath, query);
/**
* @param {!Array.<string>} files
*/
function innerCallback(files)
{
files = files.map(embedderPath => WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath));
progress.worked(1);
callback(files);
}
},
/**
* @param {!WebInspector.Progress} progress
*/
indexContent: function(progress)
{
progress.setTotalWork(1);
var requestId = this._manager.registerProgress(progress);
InspectorFrontendHost.indexPath(requestId, this._embedderPath);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | 2 1 1 | /*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.IsolatedFileSystemManager = function()
{
/** @type {!Object.<string, !WebInspector.IsolatedFileSystem>} */
this._fileSystems = {};
/** @type {!Object.<number, function(!Array.<string>)>} */
this._callbacks = {};
/** @type {!Object.<number, !WebInspector.Progress>} */
this._progresses = {};
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemsLoaded, this._onFileSystemsLoaded, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemRemoved, this._onFileSystemRemoved, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemAdded, this._onFileSystemAdded, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemFilesChanged, this._onFileSystemFilesChanged, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this._onIndexingTotalWorkCalculated, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingWorked, this._onIndexingWorked, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingDone, this._onIndexingDone, this);
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SearchCompleted, this._onSearchCompleted, this);
this._initExcludePatterSetting();
}
/** @typedef {!{fileSystemName: string, rootURL: string, fileSystemPath: string}} */
WebInspector.IsolatedFileSystemManager.FileSystem;
WebInspector.IsolatedFileSystemManager.Events = {
FileSystemAdded: "FileSystemAdded",
FileSystemRemoved: "FileSystemRemoved",
FileSystemsLoaded: "FileSystemsLoaded",
FileSystemFilesChanged: "FileSystemFilesChanged",
ExcludedFolderAdded: "ExcludedFolderAdded",
ExcludedFolderRemoved: "ExcludedFolderRemoved"
}
WebInspector.IsolatedFileSystemManager._lastRequestId = 0;
/**
* @param {string} fileSystemPath
* @return {string}
*/
WebInspector.IsolatedFileSystemManager.normalizePath = function(fileSystemPath)
{
fileSystemPath = fileSystemPath.replace(/\\/g, "/");
if (!fileSystemPath.startsWith("file://")) {
if (fileSystemPath.startsWith("/"))
fileSystemPath = "file://" + fileSystemPath;
else
fileSystemPath = "file:///" + fileSystemPath;
}
return fileSystemPath;
}
WebInspector.IsolatedFileSystemManager.prototype = {
/**
* @param {function()} callback
*/
initialize: function(callback)
{
this._initializeCallback = callback;
InspectorFrontendHost.requestFileSystems();
},
addFileSystem: function()
{
InspectorFrontendHost.addFileSystem("");
},
/**
* @param {!WebInspector.IsolatedFileSystem} fileSystem
*/
removeFileSystem: function(fileSystem)
{
InspectorFrontendHost.removeFileSystem(fileSystem.embedderPath());
},
/**
* @param {!WebInspector.Event} event
*/
_onFileSystemsLoaded: function(event)
{
var fileSystems = /** @type {!Array.<!WebInspector.IsolatedFileSystemManager.FileSystem>} */ (event.data);
var promises = [];
for (var i = 0; i < fileSystems.length; ++i)
promises.push(this._innerAddFileSystem(fileSystems[i]));
Promise.all(promises).then(fireFileSystemsLoaded.bind(this));
/**
* @this {WebInspector.IsolatedFileSystemManager}
*/
function fireFileSystemsLoaded()
{
this._initializeCallback();
delete this._initializeCallback;
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemsLoaded);
}
},
/**
* @return {boolean}
*/
fileSystemsLoaded: function()
{
return !this._initializeCallback;
},
/**
* @param {!WebInspector.IsolatedFileSystemManager.FileSystem} fileSystem
* @return {!Promise}
*/
_innerAddFileSystem: function(fileSystem)
{
var embedderPath = fileSystem.fileSystemPath;
var fileSystemPath = WebInspector.IsolatedFileSystemManager.normalizePath(fileSystem.fileSystemPath);
var promise = WebInspector.IsolatedFileSystem.create(this, fileSystemPath, embedderPath, fileSystem.fileSystemName, fileSystem.rootURL);
return promise.then(storeFileSystem.bind(this));
/**
* @param {?WebInspector.IsolatedFileSystem} fileSystem
* @this {WebInspector.IsolatedFileSystemManager}
*/
function storeFileSystem(fileSystem)
{
if (!fileSystem)
return;
this._fileSystems[fileSystemPath] = fileSystem;
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, fileSystem);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onFileSystemAdded: function(event)
{
var errorMessage = /** @type {string} */ (event.data["errorMessage"]);
var fileSystem = /** @type {?WebInspector.IsolatedFileSystemManager.FileSystem} */ (event.data["fileSystem"]);
if (errorMessage)
WebInspector.console.error(errorMessage);
else if (fileSystem)
this._innerAddFileSystem(fileSystem);
},
/**
* @param {!WebInspector.Event} event
*/
_onFileSystemRemoved: function(event)
{
this._fileSystemRemoved(/** @type {string} */ (event.data));
},
/**
* @param {!WebInspector.Event} event
*/
_onFileSystemFilesChanged: function(event)
{
var embedderPaths = /** @type {!Array<string>} */ (event.data);
var paths = embedderPaths.map(embedderPath => WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath));
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemFilesChanged, paths);
},
/**
* @param {string} embedderPath
*/
_fileSystemRemoved: function(embedderPath)
{
var fileSystemPath = WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath);
var isolatedFileSystem = this._fileSystems[fileSystemPath];
delete this._fileSystems[fileSystemPath];
if (isolatedFileSystem) {
isolatedFileSystem.fileSystemRemoved();
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, isolatedFileSystem);
}
},
/**
* @return {!Array<string>}
*/
fileSystemPaths: function()
{
return Object.keys(this._fileSystems);
},
/**
* @param {string} fileSystemPath
* @return {?WebInspector.IsolatedFileSystem}
*/
fileSystem: function(fileSystemPath)
{
return this._fileSystems[fileSystemPath];
},
_initExcludePatterSetting: function()
{
var defaultCommonExcludedFolders = [
"/\\.devtools",
"/\\.git/",
"/\\.sass-cache/",
"/\\.hg/",
"/\\.idea/",
"/\\.svn/",
"/\\.cache/",
"/\\.project/"
];
var defaultWinExcludedFolders = [
"/Thumbs.db$",
"/ehthumbs.db$",
"/Desktop.ini$",
"/\\$RECYCLE.BIN/"
];
var defaultMacExcludedFolders = [
"/\\.DS_Store$",
"/\\.Trashes$",
"/\\.Spotlight-V100$",
"/\\.AppleDouble$",
"/\\.LSOverride$",
"/Icon$",
"/\\._.*$"
];
var defaultLinuxExcludedFolders = [
"/.*~$"
];
var defaultExcludedFolders = defaultCommonExcludedFolders;
if (WebInspector.isWin())
defaultExcludedFolders = defaultExcludedFolders.concat(defaultWinExcludedFolders);
else if (WebInspector.isMac())
defaultExcludedFolders = defaultExcludedFolders.concat(defaultMacExcludedFolders);
else
defaultExcludedFolders = defaultExcludedFolders.concat(defaultLinuxExcludedFolders);
var defaultExcludedFoldersPattern = defaultExcludedFolders.join("|");
this._workspaceFolderExcludePatternSetting = WebInspector.settings.createRegExpSetting("workspaceFolderExcludePattern", defaultExcludedFoldersPattern, WebInspector.isWin() ? "i" : "");
},
/**
* @return {!WebInspector.Setting}
*/
workspaceFolderExcludePatternSetting: function()
{
return this._workspaceFolderExcludePatternSetting;
},
/**
* @param {function(!Array.<string>)} callback
* @return {number}
*/
registerCallback: function(callback)
{
var requestId = ++WebInspector.IsolatedFileSystemManager._lastRequestId;
this._callbacks[requestId] = callback;
return requestId;
},
/**
* @param {!WebInspector.Progress} progress
* @return {number}
*/
registerProgress: function(progress)
{
var requestId = ++WebInspector.IsolatedFileSystemManager._lastRequestId;
this._progresses[requestId] = progress;
return requestId;
},
/**
* @param {!WebInspector.Event} event
*/
_onIndexingTotalWorkCalculated: function(event)
{
var requestId = /** @type {number} */ (event.data["requestId"]);
var totalWork = /** @type {number} */ (event.data["totalWork"]);
var progress = this._progresses[requestId];
if (!progress)
return;
progress.setTotalWork(totalWork);
},
/**
* @param {!WebInspector.Event} event
*/
_onIndexingWorked: function(event)
{
var requestId = /** @type {number} */ (event.data["requestId"]);
var worked = /** @type {number} */ (event.data["worked"]);
var progress = this._progresses[requestId];
if (!progress)
return;
progress.worked(worked);
if (progress.isCanceled()) {
InspectorFrontendHost.stopIndexing(requestId);
this._onIndexingDone(event);
}
},
/**
* @param {!WebInspector.Event} event
*/
_onIndexingDone: function(event)
{
var requestId = /** @type {number} */ (event.data["requestId"]);
var progress = this._progresses[requestId];
if (!progress)
return;
progress.done();
delete this._progresses[requestId];
},
/**
* @param {!WebInspector.Event} event
*/
_onSearchCompleted: function(event)
{
var requestId = /** @type {number} */ (event.data["requestId"]);
var files = /** @type {!Array.<string>} */ (event.data["files"]);
var callback = this._callbacks[requestId];
if (!callback)
return;
callback.call(null, files);
delete this._callbacks[requestId];
},
dispose: function()
{
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this._onIndexingTotalWorkCalculated, this);
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingWorked, this._onIndexingWorked, this);
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingDone, this._onIndexingDone, this);
InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.SearchCompleted, this._onSearchCompleted, this);
},
__proto__: WebInspector.Object.prototype
}
/**
* @type {!WebInspector.IsolatedFileSystemManager}
*/
WebInspector.isolatedFileSystemManager;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | 2 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {WebInspector.ProjectSearchConfig}
* @param {string} query
* @param {boolean} ignoreCase
* @param {boolean} isRegex
*/
WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
{
this._query = query;
this._ignoreCase = ignoreCase;
this._isRegex = isRegex;
this._parse();
}
/** @typedef {!{regex: !RegExp, isNegative: boolean}} */
WebInspector.SearchConfig.RegexQuery;
/**
* @param {{query: string, ignoreCase: boolean, isRegex: boolean}} object
* @return {!WebInspector.SearchConfig}
*/
WebInspector.SearchConfig.fromPlainObject = function(object)
{
return new WebInspector.SearchConfig(object.query, object.ignoreCase, object.isRegex);
}
WebInspector.SearchConfig.prototype = {
/**
* @override
* @return {string}
*/
query: function()
{
return this._query;
},
/**
* @override
* @return {boolean}
*/
ignoreCase: function()
{
return this._ignoreCase;
},
/**
* @override
* @return {boolean}
*/
isRegex: function()
{
return this._isRegex;
},
/**
* @return {{query: string, ignoreCase: boolean, isRegex: boolean}}
*/
toPlainObject: function()
{
return { query: this.query(), ignoreCase: this.ignoreCase(), isRegex: this.isRegex() };
},
_parse: function()
{
var filePattern = "-?f(ile)?:(([^\\\\ ]|\\\\.)+)"; // After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
var quotedPattern = "\"(([^\\\\\"]|\\\\.)+)\""; // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
// A word is a sequence of any symbols except space and backslash or any symbols escaped with a backslash, that does not start with file:.
var unquotedWordPattern = "(\\s*(?!-?f(ile)?:)[^\\\\ ]|\\\\.)+";
var unquotedPattern = unquotedWordPattern + "( +" + unquotedWordPattern + ")*"; // A word or several words separated by space(s).
var pattern = "(" + filePattern + ")|(" + quotedPattern + ")|(" + unquotedPattern + ")";
var regexp = new RegExp(pattern, "g");
var queryParts = this._query.match(regexp) || [];
/**
* @type {!Array.<!WebInspector.SearchConfig.QueryTerm>}
*/
this._fileQueries = [];
/**
* @type {!Array.<string>}
*/
this._queries = [];
for (var i = 0; i < queryParts.length; ++i) {
var queryPart = queryParts[i];
if (!queryPart)
continue;
var fileQuery = this._parseFileQuery(queryPart);
if (fileQuery) {
this._fileQueries.push(fileQuery);
/** @type {!Array.<!WebInspector.SearchConfig.RegexQuery>} */
this._fileRegexQueries = this._fileRegexQueries || [];
this._fileRegexQueries.push({ regex: new RegExp(fileQuery.text, this.ignoreCase ? "i" : ""), isNegative: fileQuery.isNegative });
continue;
}
if (this._isRegex) {
this._queries.push(queryPart);
continue;
}
if (queryPart.startsWith("\"")) {
if (!queryPart.endsWith("\""))
continue;
this._queries.push(this._parseQuotedQuery(queryPart));
continue;
}
this._queries.push(this._parseUnquotedQuery(queryPart));
}
},
/**
* @override
* @param {string} filePath
* @return {boolean}
*/
filePathMatchesFileQuery: function(filePath)
{
if (!this._fileRegexQueries)
return true;
for (var i = 0; i < this._fileRegexQueries.length; ++i) {
if (!!filePath.match(this._fileRegexQueries[i].regex) === this._fileRegexQueries[i].isNegative)
return false;
}
return true;
},
/**
* @override
* @return {!Array.<string>}
*/
queries: function()
{
return this._queries;
},
_parseUnquotedQuery: function(query)
{
return query.replace(/\\(.)/g, "$1");
},
_parseQuotedQuery: function(query)
{
return query.substring(1, query.length - 1).replace(/\\(.)/g, "$1");
},
/**
* @param {string} query
* @return {?WebInspector.SearchConfig.QueryTerm}
*/
_parseFileQuery: function(query)
{
var match = query.match(/^(-)?f(ile)?:/);
if (!match)
return null;
var isNegative = !!match[1];
query = query.substr(match[0].length);
var result = "";
for (var i = 0; i < query.length; ++i) {
var char = query[i];
if (char === "*") {
result += ".*";
} else if (char === "\\") {
++i;
var nextChar = query[i];
if (nextChar === " ")
result += " ";
} else {
if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1)
result += "\\";
result += query.charAt(i);
}
}
return new WebInspector.SearchConfig.QueryTerm(result, isNegative);
}
}
/**
* @constructor
* @param {string} text
* @param {boolean} isNegative
*/
WebInspector.SearchConfig.QueryTerm = function(text, isNegative)
{
this.text = text;
this.isNegative = isNegative;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 | 2 1 1 1 1 1 1 | /*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.Project} project
* @param {string} url
* @param {!WebInspector.ResourceType} contentType
*/
WebInspector.UISourceCode = function(project, url, contentType)
{
this._project = project;
this._url = url;
var pathComponents = WebInspector.ParsedURL.splitURLIntoPathComponents(url);
this._origin = pathComponents[0];
this._parentURL = pathComponents.slice(0, -1).join("/");
this._name = pathComponents[pathComponents.length - 1];
this._contentType = contentType;
/** @type {?function(?string)} */
this._requestContentCallback = null;
/** @type {?Promise<?string>} */
this._requestContentPromise = null;
/** @type {!Map<string, !Map<number, !WebInspector.UISourceCode.LineMarker>>} */
this._lineDecorations = new Map();
/** @type {!Array.<!WebInspector.Revision>} */
this.history = [];
this._hasUnsavedCommittedChanges = false;
/** @type {!Array<!WebInspector.UISourceCode.Message>} */
this._messages = [];
}
/**
* @enum {string}
*/
WebInspector.UISourceCode.Events = {
WorkingCopyChanged: "WorkingCopyChanged",
WorkingCopyCommitted: "WorkingCopyCommitted",
TitleChanged: "TitleChanged",
SourceMappingChanged: "SourceMappingChanged",
MessageAdded: "MessageAdded",
MessageRemoved: "MessageRemoved",
LineDecorationAdded: "LineDecorationAdded",
LineDecorationRemoved: "LineDecorationRemoved"
}
WebInspector.UISourceCode.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {string}
*/
url: function()
{
return this._url;
},
/**
* @return {string}
*/
parentURL: function()
{
return this._parentURL;
},
/**
* @return {string}
*/
origin: function()
{
return this._origin;
},
/**
* @return {string}
*/
fullDisplayName: function()
{
var parentPath = this._parentURL.replace(/^(?:https?|file)\:\/\//, "");
try {
parentPath = decodeURI(parentPath);
} catch (e) {
}
return parentPath + "/" + this.displayName(true);
},
/**
* @param {boolean=} skipTrim
* @return {string}
*/
displayName: function(skipTrim)
{
if (!this._name)
return WebInspector.UIString("(index)");
var name = this._name;
try {
name = decodeURI(name);
} catch (e) {
}
return skipTrim ? name : name.trimEnd(100);
},
/**
* @return {boolean}
*/
isFromServiceProject: function()
{
return WebInspector.Project.isServiceProject(this._project);
},
/**
* @return {boolean}
*/
canRename: function()
{
return this._project.canRename();
},
/**
* @param {string} newName
* @param {function(boolean)} callback
*/
rename: function(newName, callback)
{
this._project.rename(this, newName, innerCallback.bind(this));
/**
* @param {boolean} success
* @param {string=} newName
* @param {string=} newURL
* @param {!WebInspector.ResourceType=} newContentType
* @this {WebInspector.UISourceCode}
*/
function innerCallback(success, newName, newURL, newContentType)
{
if (success)
this._updateName(/** @type {string} */ (newName), /** @type {string} */ (newURL), /** @type {!WebInspector.ResourceType} */ (newContentType));
callback(success);
}
},
remove: function()
{
this._project.deleteFile(this.url());
},
/**
* @param {string} name
* @param {string} url
* @param {!WebInspector.ResourceType=} contentType
*/
_updateName: function(name, url, contentType)
{
var oldURД = this.url();
this._url = this._url.substring(0, this._url.length - this._name.length) + name;
this._name = name;
if (url)
this._url = url;
if (contentType)
this._contentType = contentType;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged, oldURД);
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this.url();
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._contentType;
},
/**
* @return {!WebInspector.Project}
*/
project: function()
{
return this._project;
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
if (this._content || this._contentLoaded)
return Promise.resolve(this._content);
var promise = this._requestContentPromise;
if (!promise) {
promise = new Promise(fulfill => this._requestContentCallback = fulfill);
this._requestContentPromise = promise;
this._project.requestFileContent(this, this._fireContentAvailable.bind(this));
}
return promise;
},
/**
* @param {function()} callback
*/
_pushCheckContentUpdatedCallback: function(callback)
{
if (!this._checkContentUpdatedCallbacks)
this._checkContentUpdatedCallbacks = [];
this._checkContentUpdatedCallbacks.push(callback);
},
_terminateContentCheck: function()
{
delete this._checkingContent;
if (this._checkContentUpdatedCallbacks) {
this._checkContentUpdatedCallbacks.forEach(function(callback) { callback(); });
delete this._checkContentUpdatedCallbacks;
}
},
/**
* @param {boolean=} forceLoad
* @param {function()=} callback
*/
checkContentUpdated: function(forceLoad, callback)
{
callback = callback || function() {};
forceLoad = forceLoad || this._forceLoadOnCheckContent;
if (!this.contentLoaded() && !forceLoad) {
callback();
return;
}
if (!this._project.canSetFileContent()) {
callback();
return;
}
this._pushCheckContentUpdatedCallback(callback);
if (this._checkingContent)
return;
this._checkingContent = true;
this._project.requestFileContent(this, contentLoaded.bind(this));
/**
* @param {?string} updatedContent
* @this {WebInspector.UISourceCode}
*/
function contentLoaded(updatedContent)
{
if (updatedContent === null) {
var workingCopy = this.workingCopy();
this._contentCommitted("", true, false);
this.setWorkingCopy(workingCopy);
this._terminateContentCheck();
return;
}
if (typeof this._lastAcceptedContent === "string" && this._lastAcceptedContent === updatedContent) {
this._terminateContentCheck();
return;
}
if (this._content === updatedContent) {
delete this._lastAcceptedContent;
this._terminateContentCheck();
return;
}
if (!this.isDirty() || this._workingCopy === updatedContent) {
this._contentCommitted(updatedContent, true, false);
this._terminateContentCheck();
return;
}
var shouldUpdate = window.confirm(WebInspector.UIString("This file was changed externally. Would you like to reload it?"));
if (shouldUpdate)
this._contentCommitted(updatedContent, true, false);
else
this._lastAcceptedContent = updatedContent;
this._terminateContentCheck();
}
},
forceLoadOnCheckContent: function()
{
this._forceLoadOnCheckContent = true;
},
/**
* @return {!Promise<?string>}
*/
requestOriginalContent: function()
{
var callback;
var promise = new Promise(fulfill => callback = fulfill);
this._project.requestFileContent(this, callback);
return promise;
},
/**
* @param {string} content
*/
_commitContent: function(content)
{
var wasPersisted = false;
if (this._project.canSetFileContent()) {
this._project.setFileContent(this, content, function() { });
wasPersisted = true;
} else if (this._project.workspace().hasResourceContentTrackingExtensions()) {
wasPersisted = true;
} else if (this._url && WebInspector.fileManager.isURLSaved(this._url)) {
WebInspector.fileManager.save(this._url, content, false, function() { });
WebInspector.fileManager.close(this._url);
wasPersisted = true;
}
this._contentCommitted(content, wasPersisted, true);
},
/**
* @param {string} content
* @param {boolean} wasPersisted
* @param {boolean} committedByUser
*/
_contentCommitted: function(content, wasPersisted, committedByUser)
{
delete this._lastAcceptedContent;
this._content = content;
this._contentLoaded = true;
var lastRevision = this.history.length ? this.history[this.history.length - 1] : null;
if (!lastRevision || lastRevision._content !== this._content) {
var revision = new WebInspector.Revision(this, this._content, new Date());
this.history.push(revision);
}
this._innerResetWorkingCopy();
this._hasUnsavedCommittedChanges = !wasPersisted;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCommitted);
this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyCommitted, { uiSourceCode: this, content: content });
if (committedByUser)
this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyCommittedByUser, { uiSourceCode: this, content: content });
},
saveAs: function()
{
WebInspector.fileManager.save(this._url, this.workingCopy(), true, callback.bind(this));
WebInspector.fileManager.close(this._url);
/**
* @param {boolean} accepted
* @this {WebInspector.UISourceCode}
*/
function callback(accepted)
{
if (accepted)
this._contentCommitted(this.workingCopy(), true, true);
}
},
/**
* @return {boolean}
*/
hasUnsavedCommittedChanges: function()
{
return this._hasUnsavedCommittedChanges;
},
/**
* @param {string} content
*/
addRevision: function(content)
{
this._commitContent(content);
},
/**
* @return {!Promise}
*/
revertToOriginal: function()
{
/**
* @this {WebInspector.UISourceCode}
* @param {?string} content
*/
function callback(content)
{
if (typeof content !== "string")
return;
this.addRevision(content);
}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);
return this.requestOriginalContent().then(callback.bind(this));
},
/**
* @param {function(!WebInspector.UISourceCode)} callback
*/
revertAndClearHistory: function(callback)
{
/**
* @this {WebInspector.UISourceCode}
* @param {?string} content
*/
function revert(content)
{
if (typeof content !== "string")
return;
this.addRevision(content);
this.history = [];
callback(this);
}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);
this.requestOriginalContent().then(revert.bind(this));
},
/**
* @return {string}
*/
workingCopy: function()
{
if (this._workingCopyGetter) {
this._workingCopy = this._workingCopyGetter();
delete this._workingCopyGetter;
}
if (this.isDirty())
return this._workingCopy;
return this._content;
},
resetWorkingCopy: function()
{
this._innerResetWorkingCopy();
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
},
_innerResetWorkingCopy: function()
{
delete this._workingCopy;
delete this._workingCopyGetter;
},
/**
* @param {string} newWorkingCopy
*/
setWorkingCopy: function(newWorkingCopy)
{
this._workingCopy = newWorkingCopy;
delete this._workingCopyGetter;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyChanged, { uiSourceCode: this });
},
setWorkingCopyGetter: function(workingCopyGetter)
{
this._workingCopyGetter = workingCopyGetter;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyChanged, { uiSourceCode: this });
},
removeWorkingCopyGetter: function()
{
if (!this._workingCopyGetter)
return;
this._workingCopy = this._workingCopyGetter();
delete this._workingCopyGetter;
},
commitWorkingCopy: function()
{
if (this.isDirty())
this._commitContent(this.workingCopy());
},
/**
* @return {boolean}
*/
isDirty: function()
{
return typeof this._workingCopy !== "undefined" || typeof this._workingCopyGetter !== "undefined";
},
/**
* @return {string}
*/
extension: function()
{
return WebInspector.TextUtils.extension(this._name);
},
/**
* @return {?string}
*/
content: function()
{
return this._content;
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
var content = this.content();
if (content) {
WebInspector.StaticContentProvider.searchInContent(content, query, caseSensitive, isRegex, callback);
return;
}
this._project.searchInFileContent(this, query, caseSensitive, isRegex, callback);
},
/**
* @param {?string} content
*/
_fireContentAvailable: function(content)
{
this._contentLoaded = true;
this._content = content;
var callback = this._requestContentCallback;
this._requestContentCallback = null;
this._requestContentPromise = null;
callback.call(null, content);
},
/**
* @return {boolean}
*/
contentLoaded: function()
{
return this._contentLoaded;
},
/**
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {!WebInspector.UILocation}
*/
uiLocation: function(lineNumber, columnNumber)
{
if (typeof columnNumber === "undefined")
columnNumber = 0;
return new WebInspector.UILocation(this, lineNumber, columnNumber);
},
/**
* @return {!Array<!WebInspector.UISourceCode.Message>}
*/
messages: function()
{
return this._messages.slice();
},
/**
* @param {!WebInspector.UISourceCode.Message.Level} level
* @param {string} text
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {!WebInspector.UISourceCode.Message} message
*/
addLineMessage: function(level, text, lineNumber, columnNumber)
{
return this.addMessage(level, text, new WebInspector.TextRange(lineNumber, columnNumber || 0, lineNumber, columnNumber || 0));
},
/**
* @param {!WebInspector.UISourceCode.Message.Level} level
* @param {string} text
* @param {!WebInspector.TextRange} range
* @return {!WebInspector.UISourceCode.Message} message
*/
addMessage: function(level, text, range)
{
var message = new WebInspector.UISourceCode.Message(this, level, text, range);
this._messages.push(message);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageAdded, message);
return message;
},
/**
* @param {!WebInspector.UISourceCode.Message} message
*/
removeMessage: function(message)
{
if (this._messages.remove(message))
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemoved, message);
},
removeAllMessages: function()
{
var messages = this._messages;
this._messages = [];
for (var message of messages)
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemoved, message);
},
/**
* @param {number} lineNumber
* @param {string} type
* @param {?} data
*/
addLineDecoration: function(lineNumber, type, data)
{
var markers = this._lineDecorations.get(type);
if (!markers) {
markers = new Map();
this._lineDecorations.set(type, markers);
}
var marker = new WebInspector.UISourceCode.LineMarker(lineNumber, type, data);
markers.set(lineNumber, marker);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationAdded, marker);
},
/**
* @param {number} lineNumber
* @param {string} type
*/
removeLineDecoration: function(lineNumber, type)
{
var markers = this._lineDecorations.get(type);
if (!markers)
return;
var marker = markers.get(lineNumber);
if (!marker)
return;
markers.delete(lineNumber);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationRemoved, marker);
if (!markers.size)
this._lineDecorations.delete(type);
},
/**
* @param {string} type
*/
removeAllLineDecorations: function(type)
{
var markers = this._lineDecorations.get(type);
if (!markers)
return;
this._lineDecorations.delete(type);
markers.forEach(marker => {
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationRemoved, marker);
});
},
/**
* @param {string} type
* @return {?Map<number, !WebInspector.UISourceCode.LineMarker>}
*/
lineDecorations: function(type)
{
return this._lineDecorations.get(type) || null;
},
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
*/
WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber)
{
this.uiSourceCode = uiSourceCode;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}
WebInspector.UILocation.prototype = {
/**
* @return {string}
*/
linkText: function()
{
var linkText = this.uiSourceCode.displayName();
if (typeof this.lineNumber === "number")
linkText += ":" + (this.lineNumber + 1);
return linkText;
},
/**
* @return {string}
*/
id: function()
{
return this.uiSourceCode.project().id() + ":" + this.uiSourceCode.url() + ":" + this.lineNumber + ":" + this.columnNumber;
},
/**
* @return {string}
*/
toUIString: function()
{
return this.uiSourceCode.url() + ":" + (this.lineNumber + 1);
}
}
/**
* @constructor
* @implements {WebInspector.ContentProvider}
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?string|undefined} content
* @param {!Date} timestamp
*/
WebInspector.Revision = function(uiSourceCode, content, timestamp)
{
this._uiSourceCode = uiSourceCode;
this._content = content;
this._timestamp = timestamp;
}
WebInspector.Revision.prototype = {
/**
* @return {!WebInspector.UISourceCode}
*/
get uiSourceCode()
{
return this._uiSourceCode;
},
/**
* @return {!Date}
*/
get timestamp()
{
return this._timestamp;
},
/**
* @return {?string}
*/
get content()
{
return this._content || null;
},
/**
* @return {!Promise}
*/
revertToThis: function()
{
/**
* @param {?string} content
* @this {WebInspector.Revision}
*/
function revert(content)
{
if (content && this._uiSourceCode._content !== content)
this._uiSourceCode.addRevision(content);
}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);
return this.requestContent().then(revert.bind(this));
},
/**
* @override
* @return {string}
*/
contentURL: function()
{
return this._uiSourceCode.url();
},
/**
* @override
* @return {!WebInspector.ResourceType}
*/
contentType: function()
{
return this._uiSourceCode.contentType();
},
/**
* @override
* @return {!Promise<?string>}
*/
requestContent: function()
{
return Promise.resolve(/** @type {?string} */(this._content || ""));
},
/**
* @override
* @param {string} query
* @param {boolean} caseSensitive
* @param {boolean} isRegex
* @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
*/
searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
}
}
/**
* @constructor
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.UISourceCode.Message.Level} level
* @param {string} text
* @param {!WebInspector.TextRange} range
*/
WebInspector.UISourceCode.Message = function(uiSourceCode, level, text, range)
{
this._uiSourceCode = uiSourceCode;
this._level = level;
this._text = text;
this._range = range;
}
/**
* @enum {string}
*/
WebInspector.UISourceCode.Message.Level = {
Error: "Error",
Warning: "Warning"
}
WebInspector.UISourceCode.Message.prototype = {
/**
* @return {!WebInspector.UISourceCode}
*/
uiSourceCode: function()
{
return this._uiSourceCode;
},
/**
* @return {!WebInspector.UISourceCode.Message.Level}
*/
level: function()
{
return this._level;
},
/**
* @return {string}
*/
text: function()
{
return this._text;
},
/**
* @return {!WebInspector.TextRange}
*/
range: function()
{
return this._range;
},
/**
* @return {number}
*/
lineNumber: function()
{
return this._range.startLine;
},
/**
* @return {(number|undefined)}
*/
columnNumber: function()
{
return this._range.startColumn;
},
/**
* @param {!WebInspector.UISourceCode.Message} another
* @return {boolean}
*/
isEqual: function(another)
{
return this._uiSourceCode === another._uiSourceCode && this.text() === another.text() && this.level() === another.level() && this.range().equal(another.range());
},
remove: function()
{
this._uiSourceCode.removeMessage(this);
}
}
/**
* @constructor
* @param {number} line
* @param {string} type
* @param {?} data
*/
WebInspector.UISourceCode.LineMarker = function(line, type, data)
{
this._line = line;
this._type = type;
this._data = data;
}
WebInspector.UISourceCode.LineMarker.prototype = {
/**
* @return {number}
*/
line: function()
{
return this._line;
},
/**
* @return {string}
*/
type: function()
{
return this._type;
},
/**
* @return {*}
*/
data: function()
{
return this._data;
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | 2 1 1 | /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @interface */ WebInspector.ProjectSearchConfig = function() {} WebInspector.ProjectSearchConfig.prototype = { /** * @return {string} */ query: function() { }, /** * @return {boolean} */ ignoreCase: function() { }, /** * @return {boolean} */ isRegex: function() { }, /** * @return {!Array.<string>} */ queries: function() { }, /** * @param {string} filePath * @return {boolean} */ filePathMatchesFileQuery: function(filePath) { } } /** * @interface */ WebInspector.Project = function() { } /** * @param {!WebInspector.Project} project * @return {boolean} */ WebInspector.Project.isServiceProject = function(project) { return project.type() === WebInspector.projectTypes.Debugger || project.type() === WebInspector.projectTypes.Formatter || project.type() === WebInspector.projectTypes.Service; } WebInspector.Project.prototype = { /** * @return {!WebInspector.Workspace} */ workspace: function() { }, /** * @return {string} */ id: function() { }, /** * @return {string} */ type: function() { }, /** * @return {string} */ displayName: function() { }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {function(?string)} callback */ requestFileContent: function(uiSourceCode, callback) { }, /** * @return {boolean} */ canSetFileContent: function() { }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newContent * @param {function(?string)} callback */ setFileContent: function(uiSourceCode, newContent, callback) { }, /** * @return {boolean} */ canRename: function() { }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback */ rename: function(uiSourceCode, newName, callback) { }, /** * @param {string} path * @param {function()=} callback */ refresh: function(path, callback) { }, /** * @param {string} path */ excludeFolder: function(path) { }, /** * @param {string} path * @param {?string} name * @param {string} content * @param {function(?WebInspector.UISourceCode)} callback */ createFile: function(path, name, content, callback) { }, /** * @param {string} path */ deleteFile: function(path) { }, remove: function() { }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback */ searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback) { }, /** * @param {!WebInspector.ProjectSearchConfig} searchConfig * @param {!Array.<string>} filesMathingFileQuery * @param {!WebInspector.Progress} progress * @param {function(!Array.<string>)} callback */ findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery, progress, callback) { }, /** * @param {!WebInspector.Progress} progress */ indexContent: function(progress) { }, /** * @param {string} url * @return {?WebInspector.UISourceCode} */ uiSourceCodeForURL: function(url) { }, /** * @return {!Array.<!WebInspector.UISourceCode>} */ uiSourceCodes: function() { } } /** * @enum {string} */ WebInspector.projectTypes = { Debugger: "debugger", Formatter: "formatter", Network: "network", Snippets: "snippets", FileSystem: "filesystem", ContentScripts: "contentscripts", Service: "service" } /** * @constructor * @param {!WebInspector.Workspace} workspace * @param {string} id * @param {!WebInspector.projectTypes} type * @param {string} displayName */ WebInspector.ProjectStore = function(workspace, id, type, displayName) { this._workspace = workspace; this._id = id; this._type = type; this._displayName = displayName; /** @type {!Map.<string, !{uiSourceCode: !WebInspector.UISourceCode, index: number}>} */ this._uiSourceCodesMap = new Map(); /** @type {!Array.<!WebInspector.UISourceCode>} */ this._uiSourceCodesList = []; this._project = /** @type {!WebInspector.Project} */(this); } WebInspector.ProjectStore.prototype = { /** * @return {string} */ id: function() { return this._id; }, /** * @return {string} */ type: function() { return this._type; }, /** * @return {string} */ displayName: function() { return this._displayName; }, /** * @return {!WebInspector.Workspace} */ workspace: function() { return this._workspace; }, /** * @param {string} url * @param {!WebInspector.ResourceType} contentType * @return {!WebInspector.UISourceCode} */ createUISourceCode: function(url, contentType) { return new WebInspector.UISourceCode(this._project, url, contentType); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {boolean=} replace * @return {boolean} */ addUISourceCode: function(uiSourceCode, replace) { var url = uiSourceCode.url(); if (this.uiSourceCodeForURL(url)) { if (replace) this.removeUISourceCode(url); else return false; } this._uiSourceCodesMap.set(url, {uiSourceCode: uiSourceCode, index: this._uiSourceCodesList.length}); this._uiSourceCodesList.push(uiSourceCode); this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeAdded, uiSourceCode); return true; }, /** * @param {string} url */ removeUISourceCode: function(url) { var uiSourceCode = this.uiSourceCodeForURL(url); if (!uiSourceCode) return; var entry = this._uiSourceCodesMap.get(url); var movedUISourceCode = this._uiSourceCodesList[this._uiSourceCodesList.length - 1]; this._uiSourceCodesList[entry.index] = movedUISourceCode; var movedEntry = this._uiSourceCodesMap.get(movedUISourceCode.url()); movedEntry.index = entry.index; this._uiSourceCodesList.splice(this._uiSourceCodesList.length - 1, 1); this._uiSourceCodesMap.delete(url); this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeRemoved, entry.uiSourceCode); }, removeProject: function() { this._workspace._removeProject(this._project); this._uiSourceCodesMap = new Map(); this._uiSourceCodesList = []; }, /** * @param {string} url * @return {?WebInspector.UISourceCode} */ uiSourceCodeForURL: function(url) { var entry = this._uiSourceCodesMap.get(url); return entry ? entry.uiSourceCode : null; }, /** * @return {!Array.<!WebInspector.UISourceCode>} */ uiSourceCodes: function() { return this._uiSourceCodesList; }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName */ renameUISourceCode: function(uiSourceCode, newName) { var oldPath = uiSourceCode.url(); var newPath = uiSourceCode.parentURL() ? uiSourceCode.parentURL() + "/" + newName : newName; var value = /** @type {!{uiSourceCode: !WebInspector.UISourceCode, index: number}} */ (this._uiSourceCodesMap.get(oldPath)); this._uiSourceCodesMap.set(newPath, value); this._uiSourceCodesMap.delete(oldPath); } } /** * @constructor * @extends {WebInspector.Object} */ WebInspector.Workspace = function() { /** @type {!Map<string, !WebInspector.Project>} */ this._projects = new Map(); this._hasResourceContentTrackingExtensions = false; } WebInspector.Workspace.Events = { UISourceCodeAdded: "UISourceCodeAdded", UISourceCodeRemoved: "UISourceCodeRemoved", WorkingCopyChanged: "WorkingCopyChanged", WorkingCopyCommitted: "WorkingCopyCommitted", WorkingCopyCommittedByUser: "WorkingCopyCommittedByUser", ProjectAdded: "ProjectAdded", ProjectRemoved: "ProjectRemoved" } WebInspector.Workspace.prototype = { /** * @return {!Array.<!WebInspector.UISourceCode>} */ unsavedSourceCodes: function() { /** * @param {!WebInspector.UISourceCode} sourceCode * @return {boolean} */ function filterUnsaved(sourceCode) { return sourceCode.isDirty(); } var unsavedSourceCodes = []; var projects = this.projectsForType(WebInspector.projectTypes.FileSystem); for (var i = 0; i < projects.length; ++i) unsavedSourceCodes = unsavedSourceCodes.concat(projects[i].uiSourceCodes().filter(filterUnsaved)); return unsavedSourceCodes; }, /** * @param {string} projectId * @param {string} url * @return {?WebInspector.UISourceCode} */ uiSourceCode: function(projectId, url) { var project = this._projects.get(projectId); return project ? project.uiSourceCodeForURL(url) : null; }, /** * @param {string} url * @return {?WebInspector.UISourceCode} */ uiSourceCodeForURL: function(url) { for (var project of this._projects.values()) { var uiSourceCode = project.uiSourceCodeForURL(url); if (uiSourceCode) return uiSourceCode; } return null; }, /** * @param {string} type * @return {!Array.<!WebInspector.UISourceCode>} */ uiSourceCodesForProjectType: function(type) { var result = []; for (var project of this._projects.values()) { if (project.type() === type) result = result.concat(project.uiSourceCodes()); } return result; }, /** * @param {!WebInspector.Project} project */ addProject: function(project) { this._projects.set(project.id(), project); this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectAdded, project); }, /** * @param {!WebInspector.Project} project */ _removeProject: function(project) { this._projects.delete(project.id()); this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved, project); }, /** * @param {string} projectId * @return {?WebInspector.Project} */ project: function(projectId) { return this._projects.get(projectId) || null; }, /** * @return {!Array.<!WebInspector.Project>} */ projects: function() { return Array.from(this._projects.values()); }, /** * @param {string} type * @return {!Array.<!WebInspector.Project>} */ projectsForType: function(type) { function filterByType(project) { return project.type() === type; } return this.projects().filter(filterByType); }, /** * @return {!Array.<!WebInspector.UISourceCode>} */ uiSourceCodes: function() { var result = []; for (var project of this._projects.values()) result = result.concat(project.uiSourceCodes()); return result; }, /** * @param {boolean} hasExtensions */ setHasResourceContentTrackingExtensions: function(hasExtensions) { this._hasResourceContentTrackingExtensions = hasExtensions; }, /** * @return {boolean} */ hasResourceContentTrackingExtensions: function() { return this._hasResourceContentTrackingExtensions; }, __proto__: WebInspector.Object.prototype } /** * @type {!WebInspector.Workspace} */ WebInspector.workspace; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| InspectorBackendCommands.js | 0.24% | (1 / 425) | 100% | (0 / 0) | 100% | (0 / 0) | 0.24% | (1 / 425) | |
| SupportedCSSProperties.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| accessibility_module.js | 1.62% | (7 / 431) | 0% | (0 / 154) | 0% | (0 / 52) | 6.14% | (7 / 114) | |
| animation_module.js | 1.37% | (12 / 873) | 0% | (0 / 274) | 0% | (0 / 176) | 3.56% | (12 / 337) | |
| audits_module.js | 3.14% | (37 / 1179) | 0% | (0 / 449) | 0% | (0 / 211) | 7.47% | (37 / 495) | |
| cm_modes_module.js | 7.14% | (1 / 14) | 100% | (0 / 0) | 0% | (0 / 2) | 33.33% | (1 / 3) | |
| components_lazy_module.js | 2.31% | (9 / 390) | 0% | (0 / 158) | 0% | (0 / 61) | 6.47% | (9 / 139) | |
| console_module.js | 1.97% | (25 / 1266) | 0% | (0 / 582) | 0% | (0 / 198) | 5.77% | (25 / 433) | |
| devices_module.js | 2.43% | (9 / 371) | 0% | (0 / 117) | 0% | (0 / 37) | 8.91% | (9 / 101) | |
| devtools.js | 6.93% | (14 / 202) | 0% | (0 / 49) | 0% | (0 / 110) | 6.97% | (14 / 201) | |
| devtools_extension_api.js | 14.85% | (53 / 357) | 0% | (0 / 110) | 1.08% | (1 / 93) | 14.89% | (53 / 356) | |
| diff_module.js | 1.43% | (8 / 558) | 0% | (0 / 533) | 0% | (0 / 46) | 40% | (6 / 15) | |
| es_tree_module.js | 18.64% | (388 / 2082) | 1.75% | (23 / 1312) | 13.82% | (30 / 217) | 46.71% | (78 / 167) | |
| formatter_worker.js | 2.69% | (132 / 4914) | 0% | (0 / 3172) | 0.16% | (1 / 637) | 10.62% | (120 / 1130) | |
| gonzales_module.js | 10.14% | (344 / 3393) | 0.58% | (11 / 1905) | 4.49% | (21 / 468) | 38.68% | (41 / 106) | |
| heap_snapshot_worker.js | 2.67% | (81 / 3037) | 0% | (0 / 1088) | 0.19% | (1 / 513) | 6.56% | (75 / 1143) | |
| inspector.js | 2.58% | (680 / 26337) | 0% | (0 / 11640) | 0.02% | (1 / 5344) | 6.17% | (673 / 10903) | |
| layers_module.js | 3.26% | (3 / 92) | 0% | (0 / 32) | 0% | (0 / 21) | 7.69% | (3 / 39) | |
| network_module.js | 1.13% | (37 / 3271) | 0% | (0 / 1255) | 0% | (0 / 480) | 3.57% | (37 / 1036) | |
| profiler_module.js | 1.85% | (69 / 3725) | 0% | (0 / 1156) | 0% | (0 / 813) | 4.68% | (69 / 1474) | |
| resources_module.js | 0.99% | (22 / 2232) | 0% | (0 / 662) | 0% | (0 / 413) | 2.74% | (22 / 802) | |
| sass_module.js | 2.21% | (14 / 634) | 0% | (0 / 222) | 0% | (0 / 102) | 5.71% | (14 / 245) | |
| screencast_module.js | 0.8% | (4 / 503) | 0% | (0 / 194) | 0% | (0 / 63) | 3.13% | (4 / 128) | |
| security_module.js | 2.27% | (9 / 397) | 0% | (0 / 137) | 0% | (0 / 61) | 6.52% | (9 / 138) | |
| settings_module.js | 2.96% | (14 / 473) | 0% | (0 / 126) | 0% | (0 / 63) | 10.45% | (14 / 134) | |
| snippets_module.js | 1.65% | (4 / 243) | 0% | (0 / 44) | 0% | (0 / 70) | 3.81% | (4 / 105) | |
| source_frame_module.js | 5.55% | (522 / 9413) | 0.04% | (3 / 6797) | 0.15% | (2 / 1345) | 25.61% | (505 / 1972) | |
| sources_module.js | 1.63% | (89 / 5461) | 0% | (0 / 2246) | 0% | (0 / 946) | 4.42% | (89 / 2014) | |
| temp_storage_shared_worker.js | 8.3% | (40 / 482) | 0% | (0 / 204) | 1.02% | (1 / 98) | 14.59% | (34 / 233) | |
| timeline_module.js | 1.72% | (114 / 6628) | 0% | (0 / 2858) | 0% | (0 / 1055) | 4.99% | (114 / 2284) | |
| toolbox.js | 5.32% | (76 / 1428) | 0% | (0 / 700) | 0.37% | (1 / 271) | 9.85% | (70 / 711) | |
| ui_lazy_module.js | 0.77% | (24 / 3097) | 0% | (0 / 1379) | 0% | (0 / 480) | 2.35% | (24 / 1021) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | 2 | // File is generated by src-52.0.2743.116-third_party-WebKit-Source/devtools/scripts/CodeGeneratorFrontend.py
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Inspector.
InspectorBackend.registerEvent("Inspector.detached", ["reason"]);
InspectorBackend.registerEvent("Inspector.targetCrashed", []);
InspectorBackend.registerCommand("Inspector.enable", [], [], false);
InspectorBackend.registerCommand("Inspector.disable", [], [], false);
// Memory.
InspectorBackend.registerEnum("Memory.PressureLevel", {Moderate: "moderate", Critical: "critical"});
InspectorBackend.registerCommand("Memory.getDOMCounters", [], ["documents", "nodes", "jsEventListeners"], false);
InspectorBackend.registerCommand("Memory.setPressureNotificationsSuppressed", [{"name": "suppressed", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Memory.simulatePressureNotification", [{"name": "level", "type": "string", "optional": false}], [], false);
// Page.
InspectorBackend.registerEnum("Page.ResourceType", {Document: "Document", Stylesheet: "Stylesheet", Image: "Image", Media: "Media", Font: "Font", Script: "Script", TextTrack: "TextTrack", XHR: "XHR", Fetch: "Fetch", EventSource: "EventSource", WebSocket: "WebSocket", Manifest: "Manifest", Other: "Other"});
InspectorBackend.registerEnum("Page.DialogType", {Alert: "alert", Confirm: "confirm", Prompt: "prompt", Beforeunload: "beforeunload"});
InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.frameAttached", ["frameId", "parentFrameId"]);
InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
InspectorBackend.registerEvent("Page.frameStartedLoading", ["frameId"]);
InspectorBackend.registerEvent("Page.frameStoppedLoading", ["frameId"]);
InspectorBackend.registerEvent("Page.frameScheduledNavigation", ["frameId", "delay"]);
InspectorBackend.registerEvent("Page.frameClearedScheduledNavigation", ["frameId"]);
InspectorBackend.registerEvent("Page.frameResized", []);
InspectorBackend.registerEvent("Page.javascriptDialogOpening", ["message", "type"]);
InspectorBackend.registerEvent("Page.javascriptDialogClosed", ["result"]);
InspectorBackend.registerEvent("Page.screencastFrame", ["data", "metadata", "sessionId"]);
InspectorBackend.registerEvent("Page.screencastVisibilityChanged", ["visible"]);
InspectorBackend.registerEvent("Page.colorPicked", ["color"]);
InspectorBackend.registerEvent("Page.interstitialShown", []);
InspectorBackend.registerEvent("Page.interstitialHidden", []);
InspectorBackend.registerCommand("Page.enable", [], [], false);
InspectorBackend.registerCommand("Page.disable", [], [], false);
InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"], false);
InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.setAutoAttachToCreatedPages", [{"name": "autoAttach", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], ["frameId"], false);
InspectorBackend.registerCommand("Page.getNavigationHistory", [], ["currentIndex", "entries"], false);
InspectorBackend.registerCommand("Page.navigateToHistoryEntry", [{"name": "entryId", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.getCookies", [], ["cookies"], false);
InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"], false);
InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"], false);
InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"], false);
InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "deviceScaleFactor", "type": "number", "optional": false}, {"name": "mobile", "type": "boolean", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}, {"name": "scale", "type": "number", "optional": true}, {"name": "offsetX", "type": "number", "optional": true}, {"name": "offsetY", "type": "number", "optional": true}, {"name": "screenWidth", "type": "number", "optional": true}, {"name": "screenHeight", "type": "number", "optional": true}, {"name": "positionX", "type": "number", "optional": true}, {"name": "positionY", "type": "number", "optional": true}, {"name": "screenOrientation", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.clearDeviceMetricsOverride", [], [], false);
InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], [], false);
InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], [], false);
InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "configuration", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.captureScreenshot", [], ["data"], false);
InspectorBackend.registerCommand("Page.startScreencast", [{"name": "format", "type": "string", "optional": true}, {"name": "quality", "type": "number", "optional": true}, {"name": "maxWidth", "type": "number", "optional": true}, {"name": "maxHeight", "type": "number", "optional": true}, {"name": "everyNthFrame", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.stopScreencast", [], [], false);
InspectorBackend.registerCommand("Page.screencastFrameAck", [{"name": "sessionId", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.handleJavaScriptDialog", [{"name": "accept", "type": "boolean", "optional": false}, {"name": "promptText", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.setColorPickerEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Page.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Page.getAppManifest", [], ["url", "errors", "data"], false);
InspectorBackend.registerCommand("Page.requestAppBanner", [], [], false);
InspectorBackend.registerCommand("Page.setBlockedEventsWarningThreshold", [{"name": "threshold", "type": "number", "optional": false}], [], false);
// Rendering.
InspectorBackend.registerCommand("Rendering.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Rendering.setShowDebugBorders", [{"name": "show", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Rendering.setShowFPSCounter", [{"name": "show", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Rendering.setShowScrollBottleneckRects", [{"name": "show", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Rendering.setShowViewportSizeOnResize", [{"name": "show", "type": "boolean", "optional": false}], [], false);
// Emulation.
InspectorBackend.registerEnum("Emulation.ScreenOrientationType", {PortraitPrimary: "portraitPrimary", PortraitSecondary: "portraitSecondary", LandscapePrimary: "landscapePrimary", LandscapeSecondary: "landscapeSecondary"});
InspectorBackend.registerCommand("Emulation.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "deviceScaleFactor", "type": "number", "optional": false}, {"name": "mobile", "type": "boolean", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}, {"name": "scale", "type": "number", "optional": true}, {"name": "offsetX", "type": "number", "optional": true}, {"name": "offsetY", "type": "number", "optional": true}, {"name": "screenWidth", "type": "number", "optional": true}, {"name": "screenHeight", "type": "number", "optional": true}, {"name": "positionX", "type": "number", "optional": true}, {"name": "positionY", "type": "number", "optional": true}, {"name": "screenOrientation", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("Emulation.clearDeviceMetricsOverride", [], [], false);
InspectorBackend.registerCommand("Emulation.resetPageScaleFactor", [], [], false);
InspectorBackend.registerCommand("Emulation.setPageScaleFactor", [{"name": "pageScaleFactor", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Emulation.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Emulation.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Emulation.clearGeolocationOverride", [], [], false);
InspectorBackend.registerCommand("Emulation.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "configuration", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Emulation.setEmulatedMedia", [{"name": "media", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Emulation.setCPUThrottlingRate", [{"name": "rate", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Emulation.canEmulate", [], ["result"], false);
// Runtime.
InspectorBackend.registerEnum("Runtime.RemoteObjectType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean", Symbol: "symbol"});
InspectorBackend.registerEnum("Runtime.RemoteObjectSubtype", {Array: "array", Null: "null", Node: "node", Regexp: "regexp", Date: "date", Map: "map", Set: "set", Iterator: "iterator", Generator: "generator", Error: "error"});
InspectorBackend.registerEnum("Runtime.ObjectPreviewType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean", Symbol: "symbol"});
InspectorBackend.registerEnum("Runtime.ObjectPreviewSubtype", {Array: "array", Null: "null", Node: "node", Regexp: "regexp", Date: "date", Map: "map", Set: "set", Iterator: "iterator", Generator: "generator", Error: "error"});
InspectorBackend.registerEnum("Runtime.PropertyPreviewType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean", Symbol: "symbol", Accessor: "accessor"});
InspectorBackend.registerEnum("Runtime.PropertyPreviewSubtype", {Array: "array", Null: "null", Node: "node", Regexp: "regexp", Date: "date", Map: "map", Set: "set", Iterator: "iterator", Generator: "generator", Error: "error"});
InspectorBackend.registerEnum("Runtime.CallArgumentType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean", Symbol: "symbol"});
InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]);
InspectorBackend.registerEvent("Runtime.executionContextDestroyed", ["executionContextId"]);
InspectorBackend.registerEvent("Runtime.executionContextsCleared", []);
InspectorBackend.registerEvent("Runtime.inspectRequested", ["object", "hints"]);
InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}, {"name": "userGesture", "type": "boolean", "optional": true}], ["result", "wasThrown", "exceptionDetails"], false);
InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}, {"name": "userGesture", "type": "boolean", "optional": true}], ["result", "wasThrown"], false);
InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}, {"name": "accessorPropertiesOnly", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "internalProperties", "exceptionDetails"], false);
InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Runtime.run", [], [], false);
InspectorBackend.registerCommand("Runtime.enable", [], [], false);
InspectorBackend.registerCommand("Runtime.disable", [], [], false);
InspectorBackend.registerCommand("Runtime.setCustomObjectFormatterEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Runtime.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}, {"name": "persistScript", "type": "boolean", "optional": false}, {"name": "executionContextId", "type": "number", "optional": false}], ["scriptId", "exceptionDetails"], false);
InspectorBackend.registerCommand("Runtime.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "executionContextId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}], ["result", "exceptionDetails"], false);
// Console.
InspectorBackend.registerEnum("Console.ConsoleMessageSource", {XML: "xml", Javascript: "javascript", Network: "network", ConsoleAPI: "console-api", Storage: "storage", Appcache: "appcache", Rendering: "rendering", Security: "security", Other: "other", Deprecation: "deprecation"});
InspectorBackend.registerEnum("Console.ConsoleMessageLevel", {Log: "log", Warning: "warning", Error: "error", Debug: "debug", Info: "info", RevokedError: "revokedError"});
InspectorBackend.registerEnum("Console.ConsoleMessageType", {Log: "log", Dir: "dir", DirXML: "dirxml", Table: "table", Trace: "trace", Clear: "clear", StartGroup: "startGroup", StartGroupCollapsed: "startGroupCollapsed", EndGroup: "endGroup", Assert: "assert", Profile: "profile", ProfileEnd: "profileEnd"});
InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count", "timestamp"]);
InspectorBackend.registerEvent("Console.messagesCleared", []);
InspectorBackend.registerCommand("Console.enable", [], [], false);
InspectorBackend.registerCommand("Console.disable", [], [], false);
InspectorBackend.registerCommand("Console.clearMessages", [], [], false);
// Security.
InspectorBackend.registerEnum("Security.SecurityState", {Unknown: "unknown", Neutral: "neutral", Insecure: "insecure", Warning: "warning", Secure: "secure", Info: "info"});
InspectorBackend.registerEvent("Security.securityStateChanged", ["securityState", "explanations", "mixedContentStatus", "schemeIsCryptographic"]);
InspectorBackend.registerCommand("Security.enable", [], [], false);
InspectorBackend.registerCommand("Security.disable", [], [], false);
// Network.
InspectorBackend.registerEnum("Network.ResourcePriority", {VeryLow: "VeryLow", Low: "Low", Medium: "Medium", High: "High", VeryHigh: "VeryHigh"});
InspectorBackend.registerEnum("Network.RequestMixedContentType", {Blockable: "blockable", OptionallyBlockable: "optionally-blockable", None: "none"});
InspectorBackend.registerEnum("Network.BlockedReason", {Csp: "csp", MixedContent: "mixed-content", Origin: "origin", Inspector: "inspector", Other: "other"});
InspectorBackend.registerEnum("Network.InitiatorType", {Parser: "parser", Script: "script", Other: "other"});
InspectorBackend.registerEnum("Network.CookieSameSite", {Strict: "Strict", Lax: "Lax"});
InspectorBackend.registerEvent("Network.resourceChangedPriority", ["requestId", "newPriority", "timestamp"]);
InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "wallTime", "initiator", "redirectResponse", "type"]);
InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp", "encodedDataLength"]);
InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "type", "errorText", "canceled", "blockedReason"]);
InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "wallTime", "request"]);
InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]);
InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.eventSourceMessageReceived", ["requestId", "timestamp", "eventName", "eventId", "data"]);
InspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true}, {"name": "maxResourceBufferSize", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Network.disable", [], [], false);
InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"], false);
InspectorBackend.registerCommand("Network.addBlockedURL", [{"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.removeBlockedURL", [{"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"], false);
InspectorBackend.registerCommand("Network.clearBrowserCache", [], [], false);
InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"], false);
InspectorBackend.registerCommand("Network.clearBrowserCookies", [], [], false);
InspectorBackend.registerCommand("Network.getCookies", [], ["cookies"], false);
InspectorBackend.registerCommand("Network.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.canEmulateNetworkConditions", [], ["result"], false);
InspectorBackend.registerCommand("Network.emulateNetworkConditions", [{"name": "offline", "type": "boolean", "optional": false}, {"name": "latency", "type": "number", "optional": false}, {"name": "downloadThroughput", "type": "number", "optional": false}, {"name": "uploadThroughput", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.setBypassServiceWorker", [{"name": "bypass", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.setDataSizeLimitsForTest", [{"name": "maxTotalSize", "type": "number", "optional": false}, {"name": "maxResourceSize", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Network.getCertificateDetails", [{"name": "certificateId", "type": "number", "optional": false}], ["result"], false);
InspectorBackend.registerCommand("Network.showCertificateViewer", [{"name": "certificateId", "type": "number", "optional": false}], [], false);
// Database.
InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
InspectorBackend.registerCommand("Database.enable", [], [], false);
InspectorBackend.registerCommand("Database.disable", [], [], false);
InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"], false);
InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"], false);
// IndexedDB.
InspectorBackend.registerEnum("IndexedDB.KeyType", {Number: "number", String: "string", Date: "date", Array: "array"});
InspectorBackend.registerEnum("IndexedDB.KeyPathType", {Null: "null", String: "string", Array: "array"});
InspectorBackend.registerCommand("IndexedDB.enable", [], [], false);
InspectorBackend.registerCommand("IndexedDB.disable", [], [], false);
InspectorBackend.registerCommand("IndexedDB.requestDatabaseNames", [{"name": "securityOrigin", "type": "string", "optional": false}], ["databaseNames"], false);
InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"], false);
InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"], false);
InspectorBackend.registerCommand("IndexedDB.clearObjectStore", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}], [], false);
// CacheStorage.
InspectorBackend.registerCommand("CacheStorage.requestCacheNames", [{"name": "securityOrigin", "type": "string", "optional": false}], ["caches"], false);
InspectorBackend.registerCommand("CacheStorage.requestEntries", [{"name": "cacheId", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}], ["cacheDataEntries", "hasMore"], false);
InspectorBackend.registerCommand("CacheStorage.deleteCache", [{"name": "cacheId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("CacheStorage.deleteEntry", [{"name": "cacheId", "type": "string", "optional": false}, {"name": "request", "type": "string", "optional": false}], [], false);
// DOMStorage.
InspectorBackend.registerEvent("DOMStorage.domStorageItemsCleared", ["storageId"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemRemoved", ["storageId", "key"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemAdded", ["storageId", "key", "newValue"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemUpdated", ["storageId", "key", "oldValue", "newValue"]);
InspectorBackend.registerCommand("DOMStorage.enable", [], [], false);
InspectorBackend.registerCommand("DOMStorage.disable", [], [], false);
InspectorBackend.registerCommand("DOMStorage.getDOMStorageItems", [{"name": "storageId", "type": "object", "optional": false}], ["entries"], false);
InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "object", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "object", "optional": false}, {"name": "key", "type": "string", "optional": false}], [], false);
// ApplicationCache.
InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"], false);
InspectorBackend.registerCommand("ApplicationCache.enable", [], [], false);
InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"], false);
InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"], false);
// DOM.
InspectorBackend.registerEnum("DOM.PseudoType", {FirstLine: "first-line", FirstLetter: "first-letter", Before: "before", After: "after", Backdrop: "backdrop", Selection: "selection", FirstLineInherited: "first-line-inherited", Scrollbar: "scrollbar", ScrollbarThumb: "scrollbar-thumb", ScrollbarButton: "scrollbar-button", ScrollbarTrack: "scrollbar-track", ScrollbarTrackPiece: "scrollbar-track-piece", ScrollbarCorner: "scrollbar-corner", Resizer: "resizer", InputListButton: "input-list-button"});
InspectorBackend.registerEnum("DOM.ShadowRootType", {UserAgent: "user-agent", Open: "open", Closed: "closed"});
InspectorBackend.registerEnum("DOM.InspectMode", {SearchForNode: "searchForNode", SearchForUAShadowDOM: "searchForUAShadowDOM", ShowLayoutEditor: "showLayoutEditor", None: "none"});
InspectorBackend.registerEvent("DOM.documentUpdated", []);
InspectorBackend.registerEvent("DOM.inspectNodeRequested", ["backendNodeId"]);
InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
InspectorBackend.registerEvent("DOM.pseudoElementAdded", ["parentId", "pseudoElement"]);
InspectorBackend.registerEvent("DOM.pseudoElementRemoved", ["parentId", "pseudoElementId"]);
InspectorBackend.registerEvent("DOM.distributedNodesUpdated", ["insertionPointId", "distributedNodes"]);
InspectorBackend.registerEvent("DOM.nodeHighlightRequested", ["nodeId"]);
InspectorBackend.registerCommand("DOM.enable", [], [], false);
InspectorBackend.registerCommand("DOM.disable", [], [], false);
InspectorBackend.registerCommand("DOM.getDocument", [], ["root"], false);
InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "depth", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"], false);
InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"], false);
InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}, {"name": "includeUserAgentShadowDOM", "type": "boolean", "optional": true}], ["searchId", "resultCount"], false);
InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"], false);
InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.setInspectMode", [{"name": "mode", "type": "string", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.highlightQuad", [{"name": "quad", "type": "object", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "highlightConfig", "type": "object", "optional": false}, {"name": "nodeId", "type": "number", "optional": true}, {"name": "backendNodeId", "type": "number", "optional": true}, {"name": "objectId", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.hideHighlight", [], [], false);
InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.pushNodesByBackendIdsToFrontend", [{"name": "backendNodeIds", "type": "object", "optional": false}], ["nodeIds"], false);
InspectorBackend.registerCommand("DOM.setInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"], false);
InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"], false);
InspectorBackend.registerCommand("DOM.copyTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.undo", [], [], false);
InspectorBackend.registerCommand("DOM.redo", [], [], false);
InspectorBackend.registerCommand("DOM.markUndoableState", [], [], false);
InspectorBackend.registerCommand("DOM.focus", [{"name": "nodeId", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.setFileInputFiles", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "files", "type": "object", "optional": false}], [], false);
InspectorBackend.registerCommand("DOM.getBoxModel", [{"name": "nodeId", "type": "number", "optional": false}], ["model"], false);
InspectorBackend.registerCommand("DOM.getNodeForLocation", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.getRelayoutBoundary", [{"name": "nodeId", "type": "number", "optional": false}], ["nodeId"], false);
InspectorBackend.registerCommand("DOM.getHighlightObjectForTest", [{"name": "nodeId", "type": "number", "optional": false}], ["highlight"], false);
// CSS.
InspectorBackend.registerEnum("CSS.StyleSheetOrigin", {Injected: "injected", UserAgent: "user-agent", Inspector: "inspector", Regular: "regular"});
InspectorBackend.registerEnum("CSS.CSSMediaSource", {MediaRule: "mediaRule", ImportRule: "importRule", LinkedSheet: "linkedSheet", InlineSheet: "inlineSheet"});
InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.styleSheetAdded", ["header"]);
InspectorBackend.registerEvent("CSS.styleSheetRemoved", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.layoutEditorChange", ["styleSheetId", "changeRange"]);
InspectorBackend.registerCommand("CSS.enable", [], [], false);
InspectorBackend.registerCommand("CSS.disable", [], [], false);
InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle", "matchedCSSRules", "pseudoElements", "inherited", "cssKeyframesRules"], false);
InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"], false);
InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"], false);
InspectorBackend.registerCommand("CSS.getPlatformFontsForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["fonts"], false);
InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"], false);
InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], ["sourceMapURL"], false);
InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "range", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["selectorList"], false);
InspectorBackend.registerCommand("CSS.setKeyframeKey", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "range", "type": "object", "optional": false}, {"name": "keyText", "type": "string", "optional": false}], ["keyText"], false);
InspectorBackend.registerCommand("CSS.setStyleTexts", [{"name": "edits", "type": "object", "optional": false}], ["styles"], false);
InspectorBackend.registerCommand("CSS.setMediaText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "range", "type": "object", "optional": false}, {"name": "text", "type": "string", "optional": false}], ["media"], false);
InspectorBackend.registerCommand("CSS.createStyleSheet", [{"name": "frameId", "type": "string", "optional": false}], ["styleSheetId"], false);
InspectorBackend.registerCommand("CSS.addRule", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "ruleText", "type": "string", "optional": false}, {"name": "location", "type": "object", "optional": false}], ["rule"], false);
InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], [], false);
InspectorBackend.registerCommand("CSS.getMediaQueries", [], ["medias"], false);
InspectorBackend.registerCommand("CSS.setEffectivePropertyValueForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "propertyName", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("CSS.getBackgroundColors", [{"name": "nodeId", "type": "number", "optional": false}], ["backgroundColors"], false);
// IO.
InspectorBackend.registerCommand("IO.read", [{"name": "handle", "type": "string", "optional": false}, {"name": "offset", "type": "number", "optional": true}, {"name": "size", "type": "number", "optional": true}], ["data", "eof"], false);
InspectorBackend.registerCommand("IO.close", [{"name": "handle", "type": "string", "optional": false}], [], false);
// Debugger.
InspectorBackend.registerEnum("Debugger.GeneratorObjectDetailsStatus", {Running: "running", Suspended: "suspended", Closed: "closed"});
InspectorBackend.registerEnum("Debugger.ScopeType", {Global: "global", Local: "local", With: "with", Closure: "closure", Catch: "catch", Block: "block", Script: "script"});
InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "executionContextId", "hash", "isContentScript", "isInternalScript", "isLiveEdit", "sourceMapURL", "hasSourceURL", "deprecatedCommentWasUsed"]);
InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "executionContextId", "hash", "isContentScript", "isInternalScript", "sourceMapURL", "hasSourceURL", "deprecatedCommentWasUsed"]);
InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data", "hitBreakpoints", "asyncStackTrace"]);
InspectorBackend.registerEvent("Debugger.resumed", []);
InspectorBackend.registerCommand("Debugger.enable", [], [], false);
InspectorBackend.registerCommand("Debugger.disable", [], [], false);
InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.setSkipAllPauses", [{"name": "skipped", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"], false);
InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"], false);
InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}, {"name": "interstatementLocation", "type": "boolean", "optional": true}], [], false);
InspectorBackend.registerCommand("Debugger.stepOver", [], [], false);
InspectorBackend.registerCommand("Debugger.stepInto", [], [], false);
InspectorBackend.registerCommand("Debugger.stepOut", [], [], false);
InspectorBackend.registerCommand("Debugger.pause", [], [], false);
InspectorBackend.registerCommand("Debugger.resume", [], [], false);
InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"], false);
InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"], false);
InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "stackChanged", "asyncStackTrace", "compileError"], false);
InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "asyncStackTrace"], false);
InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"], false);
InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"], false);
InspectorBackend.registerCommand("Debugger.getGeneratorObjectDetails", [{"name": "objectId", "type": "string", "optional": false}], ["details"], false);
InspectorBackend.registerCommand("Debugger.getCollectionEntries", [{"name": "objectId", "type": "string", "optional": false}], ["entries"], false);
InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown", "exceptionDetails"], false);
InspectorBackend.registerCommand("Debugger.setVariableValue", [{"name": "scopeNumber", "type": "number", "optional": false}, {"name": "variableName", "type": "string", "optional": false}, {"name": "newValue", "type": "object", "optional": false}, {"name": "callFrameId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.getBacktrace", [], ["callFrames", "asyncStackTrace"], false);
InspectorBackend.registerCommand("Debugger.setAsyncCallStackDepth", [{"name": "maxDepth", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.setBlackboxPatterns", [{"name": "patterns", "type": "object", "optional": false}], [], false);
InspectorBackend.registerCommand("Debugger.setBlackboxedRanges", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "positions", "type": "object", "optional": false}], [], false);
// DOMDebugger.
InspectorBackend.registerEnum("DOMDebugger.DOMBreakpointType", {SubtreeModified: "subtree-modified", AttributeModified: "attribute-modified", NodeRemoved: "node-removed"});
InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}, {"name": "targetName", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}, {"name": "targetName", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("DOMDebugger.getEventListeners", [{"name": "objectId", "type": "string", "optional": false}], ["listeners"], false);
// Profiler.
InspectorBackend.registerEvent("Profiler.consoleProfileStarted", ["id", "location", "title"]);
InspectorBackend.registerEvent("Profiler.consoleProfileFinished", ["id", "location", "profile", "title"]);
InspectorBackend.registerCommand("Profiler.enable", [], [], false);
InspectorBackend.registerCommand("Profiler.disable", [], [], false);
InspectorBackend.registerCommand("Profiler.setSamplingInterval", [{"name": "interval", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Profiler.start", [], [], false);
InspectorBackend.registerCommand("Profiler.stop", [], ["profile"], false);
// HeapProfiler.
InspectorBackend.registerEvent("HeapProfiler.addHeapSnapshotChunk", ["chunk"]);
InspectorBackend.registerEvent("HeapProfiler.resetProfiles", []);
InspectorBackend.registerEvent("HeapProfiler.reportHeapSnapshotProgress", ["done", "total", "finished"]);
InspectorBackend.registerEvent("HeapProfiler.lastSeenObjectId", ["lastSeenObjectId", "timestamp"]);
InspectorBackend.registerEvent("HeapProfiler.heapStatsUpdate", ["statsUpdate"]);
InspectorBackend.registerCommand("HeapProfiler.enable", [], [], false);
InspectorBackend.registerCommand("HeapProfiler.disable", [], [], false);
InspectorBackend.registerCommand("HeapProfiler.startTrackingHeapObjects", [{"name": "trackAllocations", "type": "boolean", "optional": true}], [], false);
InspectorBackend.registerCommand("HeapProfiler.stopTrackingHeapObjects", [{"name": "reportProgress", "type": "boolean", "optional": true}], [], false);
InspectorBackend.registerCommand("HeapProfiler.takeHeapSnapshot", [{"name": "reportProgress", "type": "boolean", "optional": true}], [], false);
InspectorBackend.registerCommand("HeapProfiler.collectGarbage", [], [], false);
InspectorBackend.registerCommand("HeapProfiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"], false);
InspectorBackend.registerCommand("HeapProfiler.addInspectedHeapObject", [{"name": "heapObjectId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("HeapProfiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"], false);
InspectorBackend.registerCommand("HeapProfiler.startSampling", [{"name": "samplingInterval", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("HeapProfiler.stopSampling", [], ["profile"], false);
// Worker.
InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "waitingForDebugger"]);
InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
InspectorBackend.registerCommand("Worker.enable", [], [], false);
InspectorBackend.registerCommand("Worker.disable", [], [], false);
InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "string", "optional": false}, {"name": "message", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("Worker.setWaitForDebuggerOnStart", [{"name": "value", "type": "boolean", "optional": false}], [], false);
// ServiceWorker.
InspectorBackend.registerEnum("ServiceWorker.ServiceWorkerVersionRunningStatus", {Stopped: "stopped", Starting: "starting", Running: "running", Stopping: "stopping"});
InspectorBackend.registerEnum("ServiceWorker.ServiceWorkerVersionStatus", {New: "new", Installing: "installing", Installed: "installed", Activating: "activating", Activated: "activated", Redundant: "redundant"});
InspectorBackend.registerEvent("ServiceWorker.workerCreated", ["workerId", "url", "versionId"]);
InspectorBackend.registerEvent("ServiceWorker.workerTerminated", ["workerId"]);
InspectorBackend.registerEvent("ServiceWorker.dispatchMessage", ["workerId", "message"]);
InspectorBackend.registerEvent("ServiceWorker.workerRegistrationUpdated", ["registrations"]);
InspectorBackend.registerEvent("ServiceWorker.workerVersionUpdated", ["versions"]);
InspectorBackend.registerEvent("ServiceWorker.workerErrorReported", ["errorMessage"]);
InspectorBackend.registerCommand("ServiceWorker.enable", [], [], false);
InspectorBackend.registerCommand("ServiceWorker.disable", [], [], false);
InspectorBackend.registerCommand("ServiceWorker.sendMessage", [{"name": "workerId", "type": "string", "optional": false}, {"name": "message", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.stop", [{"name": "workerId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.unregister", [{"name": "scopeURL", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.updateRegistration", [{"name": "scopeURL", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.startWorker", [{"name": "scopeURL", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.skipWaiting", [{"name": "scopeURL", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.stopWorker", [{"name": "versionId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.inspectWorker", [{"name": "versionId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.setForceUpdateOnPageLoad", [{"name": "forceUpdateOnPageLoad", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.deliverPushMessage", [{"name": "origin", "type": "string", "optional": false}, {"name": "registrationId", "type": "string", "optional": false}, {"name": "data", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("ServiceWorker.getTargetInfo", [{"name": "targetId", "type": "string", "optional": false}], ["targetInfo"], false);
InspectorBackend.registerCommand("ServiceWorker.activateTarget", [{"name": "targetId", "type": "string", "optional": false}], [], false);
// Input.
InspectorBackend.registerEnum("Input.TouchPointState", {TouchPressed: "touchPressed", TouchReleased: "touchReleased", TouchMoved: "touchMoved", TouchStationary: "touchStationary", TouchCancelled: "touchCancelled"});
InspectorBackend.registerEnum("Input.GestureSourceType", {Default: "default", Touch: "touch", Mouse: "mouse"});
InspectorBackend.registerCommand("Input.dispatchKeyEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}, {"name": "text", "type": "string", "optional": true}, {"name": "unmodifiedText", "type": "string", "optional": true}, {"name": "keyIdentifier", "type": "string", "optional": true}, {"name": "code", "type": "string", "optional": true}, {"name": "key", "type": "string", "optional": true}, {"name": "windowsVirtualKeyCode", "type": "number", "optional": true}, {"name": "nativeVirtualKeyCode", "type": "number", "optional": true}, {"name": "autoRepeat", "type": "boolean", "optional": true}, {"name": "isKeypad", "type": "boolean", "optional": true}, {"name": "isSystemKey", "type": "boolean", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.dispatchMouseEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}, {"name": "button", "type": "string", "optional": true}, {"name": "clickCount", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.dispatchTouchEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "touchPoints", "type": "object", "optional": false}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.emulateTouchFromMouseEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "timestamp", "type": "number", "optional": false}, {"name": "button", "type": "string", "optional": false}, {"name": "deltaX", "type": "number", "optional": true}, {"name": "deltaY", "type": "number", "optional": true}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "clickCount", "type": "number", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.synthesizePinchGesture", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "scaleFactor", "type": "number", "optional": false}, {"name": "relativeSpeed", "type": "number", "optional": true}, {"name": "gestureSourceType", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.synthesizeScrollGesture", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "xDistance", "type": "number", "optional": true}, {"name": "yDistance", "type": "number", "optional": true}, {"name": "xOverscroll", "type": "number", "optional": true}, {"name": "yOverscroll", "type": "number", "optional": true}, {"name": "preventFling", "type": "boolean", "optional": true}, {"name": "speed", "type": "number", "optional": true}, {"name": "gestureSourceType", "type": "string", "optional": true}, {"name": "repeatCount", "type": "number", "optional": true}, {"name": "repeatDelayMs", "type": "number", "optional": true}, {"name": "interactionMarkerName", "type": "string", "optional": true}], [], false);
InspectorBackend.registerCommand("Input.synthesizeTapGesture", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "duration", "type": "number", "optional": true}, {"name": "tapCount", "type": "number", "optional": true}, {"name": "gestureSourceType", "type": "string", "optional": true}], [], false);
// LayerTree.
InspectorBackend.registerEnum("LayerTree.ScrollRectType", {RepaintsOnScroll: "RepaintsOnScroll", TouchEventHandler: "TouchEventHandler", WheelEventHandler: "WheelEventHandler"});
InspectorBackend.registerEvent("LayerTree.layerTreeDidChange", ["layers"]);
InspectorBackend.registerEvent("LayerTree.layerPainted", ["layerId", "clip"]);
InspectorBackend.registerCommand("LayerTree.enable", [], [], false);
InspectorBackend.registerCommand("LayerTree.disable", [], [], false);
InspectorBackend.registerCommand("LayerTree.compositingReasons", [{"name": "layerId", "type": "string", "optional": false}], ["compositingReasons"], false);
InspectorBackend.registerCommand("LayerTree.makeSnapshot", [{"name": "layerId", "type": "string", "optional": false}], ["snapshotId"], false);
InspectorBackend.registerCommand("LayerTree.loadSnapshot", [{"name": "tiles", "type": "object", "optional": false}], ["snapshotId"], false);
InspectorBackend.registerCommand("LayerTree.releaseSnapshot", [{"name": "snapshotId", "type": "string", "optional": false}], [], false);
InspectorBackend.registerCommand("LayerTree.profileSnapshot", [{"name": "snapshotId", "type": "string", "optional": false}, {"name": "minRepeatCount", "type": "number", "optional": true}, {"name": "minDuration", "type": "number", "optional": true}, {"name": "clipRect", "type": "object", "optional": true}], ["timings"], false);
InspectorBackend.registerCommand("LayerTree.replaySnapshot", [{"name": "snapshotId", "type": "string", "optional": false}, {"name": "fromStep", "type": "number", "optional": true}, {"name": "toStep", "type": "number", "optional": true}, {"name": "scale", "type": "number", "optional": true}], ["dataURL"], false);
InspectorBackend.registerCommand("LayerTree.snapshotCommandLog", [{"name": "snapshotId", "type": "string", "optional": false}], ["commandLog"], false);
// DeviceOrientation.
InspectorBackend.registerCommand("DeviceOrientation.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("DeviceOrientation.clearDeviceOrientationOverride", [], [], false);
// Tracing.
InspectorBackend.registerEnum("Tracing.TraceConfigRecordMode", {RecordUntilFull: "recordUntilFull", RecordContinuously: "recordContinuously", RecordAsMuchAsPossible: "recordAsMuchAsPossible", EchoToConsole: "echoToConsole"});
InspectorBackend.registerEvent("Tracing.dataCollected", ["value"]);
InspectorBackend.registerEvent("Tracing.tracingComplete", ["stream"]);
InspectorBackend.registerEvent("Tracing.bufferUsage", ["percentFull", "eventCount", "value"]);
InspectorBackend.registerCommand("Tracing.start", [{"name": "categories", "type": "string", "optional": true}, {"name": "options", "type": "string", "optional": true}, {"name": "bufferUsageReportingInterval", "type": "number", "optional": true}, {"name": "transferMode", "type": "string", "optional": true}, {"name": "traceConfig", "type": "object", "optional": true}], [], false);
InspectorBackend.registerCommand("Tracing.end", [], [], false);
InspectorBackend.registerCommand("Tracing.getCategories", [], ["categories"], false);
InspectorBackend.registerCommand("Tracing.requestMemoryDump", [], ["dumpGuid", "success"], false);
InspectorBackend.registerCommand("Tracing.recordClockSyncMarker", [{"name": "syncId", "type": "string", "optional": false}], [], false);
// Animation.
InspectorBackend.registerEnum("Animation.AnimationType", {CSSTransition: "CSSTransition", CSSAnimation: "CSSAnimation", WebAnimation: "WebAnimation"});
InspectorBackend.registerEvent("Animation.animationCreated", ["id"]);
InspectorBackend.registerEvent("Animation.animationStarted", ["animation"]);
InspectorBackend.registerEvent("Animation.animationCanceled", ["id"]);
InspectorBackend.registerCommand("Animation.enable", [], [], false);
InspectorBackend.registerCommand("Animation.disable", [], [], false);
InspectorBackend.registerCommand("Animation.getPlaybackRate", [], ["playbackRate"], false);
InspectorBackend.registerCommand("Animation.setPlaybackRate", [{"name": "playbackRate", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Animation.getCurrentTime", [{"name": "id", "type": "string", "optional": false}], ["currentTime"], false);
InspectorBackend.registerCommand("Animation.setPaused", [{"name": "animations", "type": "object", "optional": false}, {"name": "paused", "type": "boolean", "optional": false}], [], false);
InspectorBackend.registerCommand("Animation.setTiming", [{"name": "animationId", "type": "string", "optional": false}, {"name": "duration", "type": "number", "optional": false}, {"name": "delay", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Animation.seekAnimations", [{"name": "animations", "type": "object", "optional": false}, {"name": "currentTime", "type": "number", "optional": false}], [], false);
InspectorBackend.registerCommand("Animation.releaseAnimations", [{"name": "animations", "type": "object", "optional": false}], [], false);
InspectorBackend.registerCommand("Animation.resolveAnimation", [{"name": "animationId", "type": "string", "optional": false}], ["remoteObject"], false);
// Accessibility.
InspectorBackend.registerEnum("Accessibility.AXValueType", {Boolean: "boolean", Tristate: "tristate", BooleanOrUndefined: "booleanOrUndefined", Idref: "idref", IdrefList: "idrefList", Integer: "integer", Node: "node", NodeList: "nodeList", Number: "number", String: "string", ComputedString: "computedString", Token: "token", TokenList: "tokenList", DomRelation: "domRelation", Role: "role", InternalRole: "internalRole", ValueUndefined: "valueUndefined"});
InspectorBackend.registerEnum("Accessibility.AXValueSourceType", {Attribute: "attribute", Implicit: "implicit", Style: "style", Contents: "contents", Placeholder: "placeholder", RelatedElement: "relatedElement"});
InspectorBackend.registerEnum("Accessibility.AXValueNativeSourceType", {Figcaption: "figcaption", Label: "label", Labelfor: "labelfor", Labelwrapped: "labelwrapped", Legend: "legend", Tablecaption: "tablecaption", Title: "title", Other: "other"});
InspectorBackend.registerEnum("Accessibility.AXGlobalStates", {Disabled: "disabled", Hidden: "hidden", HiddenRoot: "hiddenRoot", Invalid: "invalid"});
InspectorBackend.registerEnum("Accessibility.AXLiveRegionAttributes", {Live: "live", Atomic: "atomic", Relevant: "relevant", Busy: "busy", Root: "root"});
InspectorBackend.registerEnum("Accessibility.AXWidgetAttributes", {Autocomplete: "autocomplete", Haspopup: "haspopup", Level: "level", Multiselectable: "multiselectable", Orientation: "orientation", Multiline: "multiline", Readonly: "readonly", Required: "required", Valuemin: "valuemin", Valuemax: "valuemax", Valuetext: "valuetext"});
InspectorBackend.registerEnum("Accessibility.AXWidgetStates", {Checked: "checked", Expanded: "expanded", Pressed: "pressed", Selected: "selected"});
InspectorBackend.registerEnum("Accessibility.AXRelationshipAttributes", {Activedescendant: "activedescendant", Flowto: "flowto", Controls: "controls", Describedby: "describedby", Labelledby: "labelledby", Owns: "owns"});
InspectorBackend.registerCommand("Accessibility.getAXNode", [{"name": "nodeId", "type": "number", "optional": false}], ["accessibilityNode"], false);
// Storage.
InspectorBackend.registerEnum("Storage.StorageType", {Appcache: "appcache", Cookies: "cookies", File_systems: "file_systems", Indexeddb: "indexeddb", Local_storage: "local_storage", Shader_cache: "shader_cache", Websql: "websql", Webrtc_indetity: "webrtc_indetity", Service_workers: "service_workers", Cache_storage: "cache_storage", All: "all"});
InspectorBackend.registerCommand("Storage.clearDataForOrigin", [{"name": "origin", "type": "string", "optional": false}, {"name": "storageTypes", "type": "string", "optional": false}], [], false);
|
| 1 2 | 2 | WebInspector.CSSMetadata.initializeWithSupportedProperties([{"name": "color"}, {"name": "direction"}, {"name": "font-family"}, {"name": "font-kerning"}, {"name": "font-size"}, {"name": "font-size-adjust"}, {"name": "font-stretch"}, {"name": "font-style"}, {"name": "font-variant-ligatures"}, {"name": "font-variant-caps"}, {"name": "font-variant-numeric"}, {"name": "font-weight"}, {"name": "font-feature-settings"}, {"name": "-webkit-font-smoothing"}, {"name": "-webkit-locale"}, {"name": "text-orientation"}, {"name": "-webkit-text-orientation"}, {"name": "writing-mode"}, {"name": "-webkit-writing-mode"}, {"name": "text-rendering"}, {"name": "zoom"}, {"name": "align-content"}, {"name": "align-items"}, {"name": "alignment-baseline"}, {"name": "align-self"}, {"name": "animation-delay"}, {"name": "animation-direction"}, {"name": "animation-duration"}, {"name": "animation-fill-mode"}, {"name": "animation-iteration-count"}, {"name": "animation-name"}, {"name": "animation-play-state"}, {"name": "animation-timing-function"}, {"name": "backdrop-filter"}, {"name": "backface-visibility"}, {"name": "background-attachment"}, {"name": "background-blend-mode"}, {"name": "background-clip"}, {"name": "background-color"}, {"name": "background-image"}, {"name": "background-origin"}, {"name": "background-position-x"}, {"name": "background-position-y"}, {"name": "background-repeat-x"}, {"name": "background-repeat-y"}, {"name": "background-size"}, {"name": "baseline-shift"}, {"name": "border-bottom-color"}, {"name": "border-bottom-left-radius"}, {"name": "border-bottom-right-radius"}, {"name": "border-bottom-style"}, {"name": "border-bottom-width"}, {"name": "border-collapse"}, {"name": "border-image-outset"}, {"name": "border-image-repeat"}, {"name": "border-image-slice"}, {"name": "border-image-source"}, {"name": "border-image-width"}, {"name": "border-left-color"}, {"name": "border-left-style"}, {"name": "border-left-width"}, {"name": "border-right-color"}, {"name": "border-right-style"}, {"name": "border-right-width"}, {"name": "border-top-color"}, {"name": "border-top-left-radius"}, {"name": "border-top-right-radius"}, {"name": "border-top-style"}, {"name": "border-top-width"}, {"name": "bottom"}, {"name": "box-shadow"}, {"name": "box-sizing"}, {"name": "break-after"}, {"name": "break-before"}, {"name": "break-inside"}, {"name": "buffered-rendering"}, {"name": "caption-side"}, {"name": "clear"}, {"name": "clip"}, {"name": "clip-path"}, {"name": "clip-rule"}, {"name": "color-interpolation"}, {"name": "color-interpolation-filters"}, {"name": "color-rendering"}, {"name": "column-fill"}, {"name": "contain"}, {"name": "content"}, {"name": "counter-increment"}, {"name": "counter-reset"}, {"name": "cursor"}, {"name": "cx"}, {"name": "cy"}, {"name": "d"}, {"name": "display"}, {"name": "dominant-baseline"}, {"name": "empty-cells"}, {"name": "fill"}, {"name": "fill-opacity"}, {"name": "fill-rule"}, {"name": "filter"}, {"name": "flex-basis"}, {"name": "flex-direction"}, {"name": "flex-grow"}, {"name": "flex-shrink"}, {"name": "flex-wrap"}, {"name": "float"}, {"name": "flood-color"}, {"name": "flood-opacity"}, {"name": "grid-auto-columns"}, {"name": "grid-auto-flow"}, {"name": "grid-auto-rows"}, {"name": "grid-column-end"}, {"name": "grid-column-gap"}, {"name": "grid-column-start"}, {"name": "grid-row-end"}, {"name": "grid-row-gap"}, {"name": "grid-row-start"}, {"name": "grid-template-areas"}, {"name": "grid-template-columns"}, {"name": "grid-template-rows"}, {"name": "height"}, {"name": "hyphens"}, {"name": "image-rendering"}, {"name": "image-orientation"}, {"name": "isolation"}, {"name": "justify-content"}, {"name": "justify-items"}, {"name": "justify-self"}, {"name": "left"}, {"name": "letter-spacing"}, {"name": "lighting-color"}, {"name": "line-height"}, {"name": "list-style-image"}, {"name": "list-style-position"}, {"name": "list-style-type"}, {"name": "margin-bottom"}, {"name": "margin-left"}, {"name": "margin-right"}, {"name": "margin-top"}, {"name": "marker-end"}, {"name": "marker-mid"}, {"name": "marker-start"}, {"name": "mask"}, {"name": "mask-source-type"}, {"name": "mask-type"}, {"name": "max-height"}, {"name": "max-width"}, {"name": "min-height"}, {"name": "min-width"}, {"name": "mix-blend-mode"}, {"name": "motion-offset"}, {"name": "motion-path"}, {"name": "motion-rotation"}, {"name": "object-fit"}, {"name": "object-position"}, {"name": "opacity"}, {"name": "order"}, {"name": "orphans"}, {"name": "outline-color"}, {"name": "outline-offset"}, {"name": "outline-style"}, {"name": "outline-width"}, {"name": "overflow-wrap"}, {"name": "overflow-x"}, {"name": "overflow-y"}, {"name": "padding-bottom"}, {"name": "padding-left"}, {"name": "padding-right"}, {"name": "padding-top"}, {"name": "paint-order"}, {"name": "perspective"}, {"name": "perspective-origin"}, {"name": "pointer-events"}, {"name": "position"}, {"name": "quotes"}, {"name": "resize"}, {"name": "right"}, {"name": "r"}, {"name": "rx"}, {"name": "ry"}, {"name": "scroll-behavior"}, {"name": "scroll-snap-type"}, {"name": "scroll-snap-points-x"}, {"name": "scroll-snap-points-y"}, {"name": "scroll-snap-destination"}, {"name": "scroll-snap-coordinate"}, {"name": "shape-image-threshold"}, {"name": "shape-margin"}, {"name": "shape-outside"}, {"name": "shape-rendering"}, {"name": "size"}, {"name": "snap-height"}, {"name": "speak"}, {"name": "stop-color"}, {"name": "stop-opacity"}, {"name": "stroke"}, {"name": "stroke-dasharray"}, {"name": "stroke-dashoffset"}, {"name": "stroke-linecap"}, {"name": "stroke-linejoin"}, {"name": "stroke-miterlimit"}, {"name": "stroke-opacity"}, {"name": "stroke-width"}, {"name": "table-layout"}, {"name": "tab-size"}, {"name": "text-align"}, {"name": "text-align-last"}, {"name": "text-anchor"}, {"name": "text-combine-upright"}, {"longhands": ["text-decoration-line", "text-decoration-style", "text-decoration-color"], "name": "text-decoration"}, {"name": "text-decoration-color"}, {"name": "text-decoration-line"}, {"name": "text-decoration-style"}, {"name": "text-indent"}, {"name": "text-justify"}, {"name": "text-overflow"}, {"name": "text-shadow"}, {"name": "text-transform"}, {"name": "text-underline-position"}, {"name": "top"}, {"name": "touch-action"}, {"name": "transform"}, {"name": "transform-origin"}, {"name": "transform-style"}, {"name": "translate"}, {"name": "rotate"}, {"name": "scale"}, {"name": "transition-delay"}, {"name": "transition-duration"}, {"name": "transition-property"}, {"name": "transition-timing-function"}, {"name": "unicode-bidi"}, {"name": "vector-effect"}, {"name": "vertical-align"}, {"name": "visibility"}, {"name": "x"}, {"name": "y"}, {"name": "-webkit-appearance"}, {"name": "-webkit-app-region"}, {"name": "-webkit-background-clip"}, {"name": "-webkit-background-origin"}, {"name": "-webkit-border-horizontal-spacing"}, {"name": "-webkit-border-image"}, {"name": "-webkit-border-vertical-spacing"}, {"name": "-webkit-box-align"}, {"name": "-webkit-box-decoration-break"}, {"name": "-webkit-box-direction"}, {"name": "-webkit-box-flex"}, {"name": "-webkit-box-flex-group"}, {"name": "-webkit-box-lines"}, {"name": "-webkit-box-ordinal-group"}, {"name": "-webkit-box-orient"}, {"name": "-webkit-box-pack"}, {"name": "-webkit-box-reflect"}, {"name": "-webkit-clip-path"}, {"name": "column-count"}, {"name": "column-gap"}, {"name": "column-rule-color"}, {"name": "column-rule-style"}, {"name": "column-rule-width"}, {"name": "column-span"}, {"name": "column-width"}, {"name": "-webkit-filter"}, {"name": "-webkit-highlight"}, {"name": "-webkit-hyphenate-character"}, {"name": "-webkit-line-break"}, {"name": "-webkit-line-clamp"}, {"name": "-webkit-margin-after-collapse"}, {"name": "-webkit-margin-before-collapse"}, {"name": "-webkit-margin-bottom-collapse"}, {"name": "-webkit-margin-top-collapse"}, {"name": "-webkit-mask-box-image-outset"}, {"name": "-webkit-mask-box-image-repeat"}, {"name": "-webkit-mask-box-image-slice"}, {"name": "-webkit-mask-box-image-source"}, {"name": "-webkit-mask-box-image-width"}, {"name": "-webkit-mask-clip"}, {"name": "-webkit-mask-composite"}, {"name": "-webkit-mask-image"}, {"name": "-webkit-mask-origin"}, {"name": "-webkit-mask-position-x"}, {"name": "-webkit-mask-position-y"}, {"name": "-webkit-mask-repeat-x"}, {"name": "-webkit-mask-repeat-y"}, {"name": "-webkit-mask-size"}, {"name": "-webkit-perspective-origin-x"}, {"name": "-webkit-perspective-origin-y"}, {"name": "-webkit-print-color-adjust"}, {"name": "-webkit-rtl-ordering"}, {"name": "-webkit-ruby-position"}, {"name": "-webkit-tap-highlight-color"}, {"name": "-webkit-text-combine"}, {"name": "-webkit-text-emphasis-color"}, {"name": "-webkit-text-emphasis-position"}, {"name": "-webkit-text-emphasis-style"}, {"name": "-webkit-text-fill-color"}, {"name": "-webkit-text-security"}, {"name": "-webkit-text-stroke-color"}, {"name": "-webkit-text-stroke-width"}, {"name": "-webkit-transform-origin-x"}, {"name": "-webkit-transform-origin-y"}, {"name": "-webkit-transform-origin-z"}, {"name": "-webkit-user-drag"}, {"name": "-webkit-user-modify"}, {"name": "-webkit-user-select"}, {"name": "white-space"}, {"name": "widows"}, {"name": "width"}, {"name": "will-change"}, {"name": "word-break"}, {"name": "word-spacing"}, {"name": "word-wrap"}, {"name": "z-index"}, {"name": "-webkit-border-end-color"}, {"name": "-webkit-border-end-style"}, {"name": "-webkit-border-end-width"}, {"name": "-webkit-border-start-color"}, {"name": "-webkit-border-start-style"}, {"name": "-webkit-border-start-width"}, {"name": "-webkit-border-before-color"}, {"name": "-webkit-border-before-style"}, {"name": "-webkit-border-before-width"}, {"name": "-webkit-border-after-color"}, {"name": "-webkit-border-after-style"}, {"name": "-webkit-border-after-width"}, {"name": "-webkit-margin-end"}, {"name": "-webkit-margin-start"}, {"name": "-webkit-margin-before"}, {"name": "-webkit-margin-after"}, {"name": "-webkit-padding-end"}, {"name": "-webkit-padding-start"}, {"name": "-webkit-padding-before"}, {"name": "-webkit-padding-after"}, {"name": "-webkit-logical-width"}, {"name": "-webkit-logical-height"}, {"name": "-webkit-min-logical-width"}, {"name": "-webkit-min-logical-height"}, {"name": "-webkit-max-logical-width"}, {"name": "-webkit-max-logical-height"}, {"name": "all"}, {"name": "font-display"}, {"name": "max-zoom"}, {"name": "min-zoom"}, {"name": "orientation"}, {"name": "page"}, {"name": "src"}, {"name": "unicode-range"}, {"name": "user-zoom"}, {"name": "-webkit-font-size-delta"}, {"name": "-webkit-text-decorations-in-effect"}, {"longhands": ["animation-name", "animation-duration", "animation-timing-function", "animation-delay", "animation-iteration-count", "animation-direction", "animation-fill-mode", "animation-play-state"], "name": "animation"}, {"longhands": ["background-image", "background-position-x", "background-position-y", "background-size", "background-repeat-x", "background-repeat-y", "background-attachment", "background-origin", "background-clip", "background-color"], "name": "background"}, {"longhands": ["background-position-x", "background-position-y"], "name": "background-position"}, {"longhands": ["background-repeat-x", "background-repeat-y"], "name": "background-repeat"}, {"longhands": ["border-top-color", "border-top-style", "border-top-width", "border-right-color", "border-right-style", "border-right-width", "border-bottom-color", "border-bottom-style", "border-bottom-width", "border-left-color", "border-left-style", "border-left-width", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "name": "border"}, {"longhands": ["border-bottom-width", "border-bottom-style", "border-bottom-color"], "name": "border-bottom"}, {"longhands": ["border-top-color", "border-right-color", "border-bottom-color", "border-left-color"], "name": "border-color"}, {"longhands": ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "name": "border-image"}, {"longhands": ["border-left-width", "border-left-style", "border-left-color"], "name": "border-left"}, {"longhands": ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius"], "name": "border-radius"}, {"longhands": ["border-right-width", "border-right-style", "border-right-color"], "name": "border-right"}, {"longhands": ["-webkit-border-horizontal-spacing", "-webkit-border-vertical-spacing"], "name": "border-spacing"}, {"longhands": ["border-top-style", "border-right-style", "border-bottom-style", "border-left-style"], "name": "border-style"}, {"longhands": ["border-top-width", "border-top-style", "border-top-color"], "name": "border-top"}, {"longhands": ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"], "name": "border-width"}, {"longhands": ["flex-grow", "flex-shrink", "flex-basis"], "name": "flex"}, {"longhands": ["flex-direction", "flex-wrap"], "name": "flex-flow"}, {"longhands": ["font-style", "font-variant-ligatures", "font-variant-caps", "font-variant-numeric", "font-weight", "font-stretch", "font-size", "line-height", "font-family"], "name": "font"}, {"longhands": ["font-variant-ligatures", "font-variant-caps", "font-variant-numeric"], "name": "font-variant"}, {"longhands": ["grid-template-rows", "grid-template-columns", "grid-template-areas", "grid-auto-flow", "grid-auto-rows", "grid-auto-columns", "grid-column-gap", "grid-row-gap"], "name": "grid"}, {"longhands": ["grid-row-start", "grid-column-start", "grid-row-end", "grid-column-end"], "name": "grid-area"}, {"longhands": ["grid-column-start", "grid-column-end"], "name": "grid-column"}, {"longhands": ["grid-row-gap", "grid-column-gap"], "name": "grid-gap"}, {"longhands": ["grid-row-start", "grid-row-end"], "name": "grid-row"}, {"longhands": ["grid-template-rows", "grid-template-columns", "grid-template-areas"], "name": "grid-template"}, {"longhands": ["list-style-type", "list-style-position", "list-style-image"], "name": "list-style"}, {"longhands": ["margin-top", "margin-right", "margin-bottom", "margin-left"], "name": "margin"}, {"longhands": ["marker-start", "marker-mid", "marker-end"], "name": "marker"}, {"longhands": ["motion-path", "motion-offset", "motion-rotation"], "name": "motion"}, {"longhands": ["outline-color", "outline-style", "outline-width"], "name": "outline"}, {"longhands": ["overflow-x", "overflow-y"], "name": "overflow"}, {"longhands": ["padding-top", "padding-right", "padding-bottom", "padding-left"], "name": "padding"}, {"longhands": ["break-after"], "name": "page-break-after"}, {"longhands": ["break-before"], "name": "page-break-before"}, {"longhands": ["break-inside"], "name": "page-break-inside"}, {"longhands": ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"], "name": "transition"}, {"longhands": ["-webkit-border-after-width", "-webkit-border-after-style", "-webkit-border-after-color"], "name": "-webkit-border-after"}, {"longhands": ["-webkit-border-before-width", "-webkit-border-before-style", "-webkit-border-before-color"], "name": "-webkit-border-before"}, {"longhands": ["-webkit-border-end-width", "-webkit-border-end-style", "-webkit-border-end-color"], "name": "-webkit-border-end"}, {"longhands": ["-webkit-border-start-width", "-webkit-border-start-style", "-webkit-border-start-color"], "name": "-webkit-border-start"}, {"longhands": ["break-after"], "name": "-webkit-column-break-after"}, {"longhands": ["break-before"], "name": "-webkit-column-break-before"}, {"longhands": ["break-inside"], "name": "-webkit-column-break-inside"}, {"longhands": ["column-rule-width", "column-rule-style", "column-rule-color"], "name": "column-rule"}, {"longhands": ["column-width", "column-count"], "name": "columns"}, {"longhands": ["-webkit-margin-before-collapse", "-webkit-margin-after-collapse"], "name": "-webkit-margin-collapse"}, {"longhands": ["-webkit-mask-image", "-webkit-mask-position-x", "-webkit-mask-position-y", "-webkit-mask-size", "-webkit-mask-repeat-x", "-webkit-mask-repeat-y", "-webkit-mask-origin", "-webkit-mask-clip"], "name": "-webkit-mask"}, {"longhands": ["-webkit-mask-box-image-source", "-webkit-mask-box-image-slice", "-webkit-mask-box-image-width", "-webkit-mask-box-image-outset", "-webkit-mask-box-image-repeat"], "name": "-webkit-mask-box-image"}, {"longhands": ["-webkit-mask-position-x", "-webkit-mask-position-y"], "name": "-webkit-mask-position"}, {"longhands": ["-webkit-mask-repeat-x", "-webkit-mask-repeat-y"], "name": "-webkit-mask-repeat"}, {"longhands": ["-webkit-text-emphasis-style", "-webkit-text-emphasis-color"], "name": "-webkit-text-emphasis"}, {"longhands": ["-webkit-text-stroke-width", "-webkit-text-stroke-color"], "name": "-webkit-text-stroke"}]);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 2 1 1 1 1 1 1 | WebInspector.AccessibilityModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.AccessibilityModel,target);this._agent=target.accessibilityAgent();};WebInspector.AccessibilityModel.prototype={getAXNode:function(nodeId) {function parsePayload(error,value) {if(error) console.error("AccessibilityAgent.getAXNode(): "+error);return value||null;} return this._agent.getAXNode(nodeId,parsePayload);},__proto__:WebInspector.SDKModel.prototype} WebInspector.AccessibilityModel._symbol=Symbol("AccessibilityModel");WebInspector.AccessibilityModel.fromTarget=function(target) {if(!target[WebInspector.AccessibilityModel._symbol]) target[WebInspector.AccessibilityModel._symbol]=new WebInspector.AccessibilityModel(target);return target[WebInspector.AccessibilityModel._symbol];};WebInspector.AccessibilitySidebarView=function() {WebInspector.ThrottledWidget.call(this);this._computedTextSubPane=null;this._axNodeSubPane=null;this._node=null;this._sidebarPaneStack=null;WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode,this._pullNode,this);this._pullNode();} WebInspector.AccessibilitySidebarView.prototype={node:function() {return this._node;},doUpdate:function() {function accessibilityNodeCallback(accessibilityNode) {if(this._computedTextSubPane) this._computedTextSubPane.setAXNode(accessibilityNode);if(this._axNodeSubPane) this._axNodeSubPane.setAXNode(accessibilityNode);} var node=this.node();return WebInspector.AccessibilityModel.fromTarget(node.target()).getAXNode(node.id).then(accessibilityNodeCallback.bind(this))},wasShown:function() {WebInspector.ThrottledWidget.prototype.wasShown.call(this);if(!this._sidebarPaneStack){this._computedTextSubPane=new WebInspector.AXComputedTextSubPane();this._computedTextSubPane.setNode(this.node());this._computedTextSubPane.show(this.element);this._computedTextSubPane.expand();this._axNodeSubPane=new WebInspector.AXNodeSubPane();this._axNodeSubPane.setNode(this.node());this._axNodeSubPane.show(this.element);this._axNodeSubPane.expand();this._sidebarPaneStack=new WebInspector.SidebarPaneStack();this._sidebarPaneStack.element.classList.add("flex-auto");this._sidebarPaneStack.show(this.element);this._sidebarPaneStack.addPane(this._computedTextSubPane);this._sidebarPaneStack.addPane(this._axNodeSubPane);} WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.AttrModified,this._onAttrChange,this);WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.AttrRemoved,this._onAttrChange,this);WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.CharacterDataModified,this._onNodeChange,this);WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.ChildNodeCountUpdated,this._onNodeChange,this);},willHide:function() {WebInspector.targetManager.removeModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.AttrModified,this._onAttrChange,this);WebInspector.targetManager.removeModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.AttrRemoved,this._onAttrChange,this);WebInspector.targetManager.removeModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.CharacterDataModified,this._onNodeChange,this);WebInspector.targetManager.removeModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.ChildNodeCountUpdated,this._onNodeChange,this);},_pullNode:function() {this._node=WebInspector.context.flavor(WebInspector.DOMNode);if(this._computedTextSubPane) this._computedTextSubPane.setNode(this._node);if(this._axNodeSubPane) this._axNodeSubPane.setNode(this._node);this.update();},_onAttrChange:function(event) {if(!this.node()) return;var node=event.data.node;if(this.node()!==node) return;this.update();},_onNodeChange:function(event) {if(!this.node()) return;var node=event.data;if(this.node()!==node) return;this.update();},__proto__:WebInspector.ThrottledWidget.prototype};WebInspector.AccessibilitySubPane=function(name) {WebInspector.SidebarPane.call(this,name);this._axNode=null;this.registerRequiredCSS("accessibility/accessibilityNode.css");} WebInspector.AccessibilitySubPane.prototype={setAXNode:function(axNode) {},node:function() {return this._node;},setNode:function(node) {this._node=node;},createInfo:function(textContent,className) {var classNameOrDefault=className||"info";var info=this.element.createChild("div",classNameOrDefault);info.textContent=textContent;return info;},createTreeOutline:function() {var treeOutline=new TreeOutlineInShadow();treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css");treeOutline.registerRequiredCSS("components/objectValue.css");treeOutline.element.classList.add("hidden");this.element.appendChild(treeOutline.element);return treeOutline;},__proto__:WebInspector.SidebarPane.prototype} WebInspector.AXComputedTextSubPane=function() {WebInspector.AccessibilitySubPane.call(this,WebInspector.UIString("Computed Text"));this._computedTextElement=this.element.createChild("div","ax-computed-text hidden");this._noTextInfo=this.createInfo(WebInspector.UIString("Node has no text alternative."));this._treeOutline=this.createTreeOutline();};WebInspector.AXComputedTextSubPane.prototype={setAXNode:function(axNode) {if(this._axNode===axNode) return;this._axNode=axNode;var treeOutline=this._treeOutline;treeOutline.removeChildren();var target=this.node().target();if(!axNode||axNode.ignored){this._computedTextElement.classList.add("hidden");treeOutline.element.classList.add("hidden");this._noTextInfo.classList.remove("hidden");return;} this._computedTextElement.removeChildren();this._computedTextElement.classList.toggle("hidden",!axNode.name||!axNode.name.value);if(axNode.name&&axNode.name.value) this._computedTextElement.createChild("div").textContent=axNode.name.value;var foundProperty=false;function addProperty(property) {foundProperty=true;treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property,target));} if(axNode.value&&axNode.value.type===AccessibilityAgent.AXValueType.String) addProperty(({name:"value",value:axNode.value}));var propertiesArray=(axNode.properties);for(var property of propertiesArray){if(property.name==AccessibilityAgent.AXWidgetAttributes.Valuetext){addProperty(property);break;}} treeOutline.element.classList.toggle("hidden",!foundProperty) this._noTextInfo.classList.toggle("hidden",!treeOutline.element.classList.contains("hidden")||!this._computedTextElement.classList.contains("hidden"));},__proto__:WebInspector.AccessibilitySubPane.prototype};;WebInspector.AXNodeSubPane=function() {WebInspector.AccessibilitySubPane.call(this,WebInspector.UIString("Accessibility Node"));this._noNodeInfo=this.createInfo(WebInspector.UIString("No accessibility node"));this._ignoredInfo=this.createInfo(WebInspector.UIString("Accessibility node not exposed"),"ax-ignored-info hidden");this._treeOutline=this.createTreeOutline();this._ignoredReasonsTree=this.createTreeOutline();};WebInspector.AXNodeSubPane.prototype={setAXNode:function(axNode) {if(this._axNode===axNode) return;this._axNode=axNode;var treeOutline=this._treeOutline;treeOutline.removeChildren();var ignoredReasons=this._ignoredReasonsTree;ignoredReasons.removeChildren();var target=this.node().target();if(!axNode){treeOutline.element.classList.add("hidden");this._ignoredInfo.classList.add("hidden");ignoredReasons.element.classList.add("hidden");this._noNodeInfo.classList.remove("hidden");this.element.classList.add("ax-ignored-node-pane");return;}else if(axNode.ignored){this._noNodeInfo.classList.add("hidden");treeOutline.element.classList.add("hidden");this.element.classList.add("ax-ignored-node-pane");this._ignoredInfo.classList.remove("hidden");ignoredReasons.element.classList.remove("hidden");function addIgnoredReason(property) {ignoredReasons.appendChild(new WebInspector.AXNodeIgnoredReasonTreeElement(property,axNode,target));} var ignoredReasonsArray=(axNode.ignoredReasons);for(var reason of ignoredReasonsArray) addIgnoredReason(reason);if(!ignoredReasons.firstChild()) ignoredReasons.element.classList.add("hidden");return;} this.element.classList.remove("ax-ignored-node-pane");this._ignoredInfo.classList.add("hidden");ignoredReasons.element.classList.add("hidden");this._noNodeInfo.classList.add("hidden");treeOutline.element.classList.remove("hidden");function addProperty(property) {treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property,target));} for(var propertyName of["name","description","help","value"]){if(propertyName in axNode){var defaultProperty=({name:propertyName,value:axNode[propertyName]});addProperty(defaultProperty);}} var roleProperty=({name:"role",value:axNode.role});addProperty(roleProperty);var propertyMap={};var propertiesArray=(axNode.properties);for(var property of propertiesArray) propertyMap[property.name]=property;for(var propertySet of[AccessibilityAgent.AXWidgetAttributes,AccessibilityAgent.AXWidgetStates,AccessibilityAgent.AXGlobalStates,AccessibilityAgent.AXLiveRegionAttributes,AccessibilityAgent.AXRelationshipAttributes]){for(var propertyKey in propertySet){var property=propertySet[propertyKey];if(property in propertyMap) addProperty(propertyMap[property]);}}},__proto__:WebInspector.AccessibilitySubPane.prototype};WebInspector.AXNodePropertyTreeElement=function(target) {this._target=target;TreeElement.call(this,"");};WebInspector.AXNodePropertyTreeElement.createSimpleValueElement=function(type,value) {var valueElement;var AXValueType=AccessibilityAgent.AXValueType;if(!type||type===AXValueType.ValueUndefined||type===AXValueType.ComputedString) valueElement=createElement("span");else valueElement=createElementWithClass("span","monospace");var valueText;if(type===AXValueType.String||type===AXValueType.ComputedString||type===AXValueType.IdrefList||type===AXValueType.Idref){valueText=value.replace(/\n/g,"\u21B5");valueElement._originalTextContent=value;}else{valueText=String(value);} if(type&&type in WebInspector.AXNodePropertyTreeElement.TypeStyles) valueElement.classList.add(WebInspector.AXNodePropertyTreeElement.TypeStyles[type]);valueElement.setTextContentTruncatedIfNeeded(valueText||"");valueElement.title=String(value)||"";return valueElement;};WebInspector.AXNodePropertyTreeElement.createExclamationMark=function(tooltip) {var exclamationElement=createElement("label","dt-icon-label");exclamationElement.type="warning-icon";exclamationElement.title=tooltip;return exclamationElement;};WebInspector.AXNodePropertyTreeElement.TypeStyles={attribute:"ax-value-string",boolean:"object-value-boolean",booleanOrUndefined:"object-value-boolean",computedString:"ax-readable-string",idref:"ax-value-string",idrefList:"ax-value-string",integer:"object-value-number",internalRole:"ax-internal-role",number:"ax-value-number",role:"ax-role",string:"ax-value-string",tristate:"object-value-boolean",valueUndefined:"ax-value-undefined"};WebInspector.AXNodePropertyTreeElement.StringProperties=new Set([AccessibilityAgent.AXValueType.String,AccessibilityAgent.AXValueType.ComputedString,AccessibilityAgent.AXValueType.IdrefList,AccessibilityAgent.AXValueType.Idref]);WebInspector.AXNodePropertyTreeElement.prototype={appendNameElement:function(name) {var nameElement=createElement("span");var AXAttributes=WebInspector.AccessibilityStrings.AXAttributes;if(name in AXAttributes){nameElement.textContent=WebInspector.UIString(AXAttributes[name].name);nameElement.title=AXAttributes[name].description;nameElement.classList.add("ax-readable-name");}else{nameElement.textContent=name;nameElement.classList.add("ax-name");nameElement.classList.add("monospace");} this.listItemElement.appendChild(nameElement);},appendValueElement:function(value) {var AXValueType=AccessibilityAgent.AXValueType;if(value.type===AXValueType.Idref||value.type===AXValueType.Node||value.type===AXValueType.IdrefList||value.type===AXValueType.NodeList){this.appendRelatedNodeListValueElement(value);return;}else if(value.sources){var sources=value.sources;for(var i=0;i<sources.length;i++){var source=sources[i];var child=new WebInspector.AXValueSourceTreeElement(source,this._target);this.appendChild(child);} this.expand();} var isStringProperty=WebInspector.AXNodePropertyTreeElement.StringProperties.has(value.type);if(isStringProperty) this.listItemElement.createTextChild("\"");this.listItemElement.appendChild(WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(value.type,String(value.value)));if(isStringProperty) this.listItemElement.createTextChild("\"");},appendRelatedNode:function(relatedNode,index) {if(index>0) this.listItemElement.createTextChild(",\u00a0");var deferredNode=new WebInspector.DeferredDOMNode(this._target,relatedNode.backendNodeId);var linkedNode=new WebInspector.AXRelatedNodeElement({deferredNode:deferredNode},relatedNode);this.listItemElement.appendChild(linkedNode.render());},appendRelatedNodeListValueElement:function(value) {value.relatedNodes.forEach(this.appendRelatedNode,this);},__proto__:TreeElement.prototype};WebInspector.AXNodePropertyTreePropertyElement=function(property,target) {this._property=property;this.toggleOnClick=true;this.selectable=false;WebInspector.AXNodePropertyTreeElement.call(this,target);this.listItemElement.classList.add("property");} WebInspector.AXNodePropertyTreePropertyElement.prototype={onattach:function() {this._update();},_update:function() {this.listItemElement.removeChildren();this.appendNameElement(this._property.name);this.listItemElement.createChild("span","separator").textContent=":\u00A0";this.appendValueElement(this._property.value);},__proto__:WebInspector.AXNodePropertyTreeElement.prototype};WebInspector.AXValueSourceTreeElement=function(source,target) {this._source=source;WebInspector.AXNodePropertyTreeElement.call(this,target);this.selectable=false;} WebInspector.AXValueSourceTreeElement.prototype={onattach:function() {this._update();},appendRelatedNode:function(relatedNode,index) {var deferredNode=new WebInspector.DeferredDOMNode(this._target,relatedNode.backendNodeId);var nodeTreeElement=new WebInspector.AXRelatedNodeSourceTreeElement({deferredNode:deferredNode},relatedNode);this.appendChild(nodeTreeElement);},appendRelatedNodeWithIdref:function(relatedNode,index,idref) {var deferredNode=new WebInspector.DeferredDOMNode(this._target,relatedNode.backendNodeId);var nodeTreeElement=new WebInspector.AXRelatedNodeSourceTreeElement({deferredNode:deferredNode,idref:idref},relatedNode);this.appendChild(nodeTreeElement);},appendIDRefValueElement:function(value) {var relatedNodes=value.relatedNodes;var numNodes=relatedNodes.length;var valueElement;var idrefs=value.value.trim().split(/\s+/);if(idrefs.length===1){var idref=idrefs[0];var matchingNode=relatedNodes.find(node=>node.idref===idref);if(matchingNode){this.appendRelatedNodeWithIdref(matchingNode,0,idref);}else{this.listItemElement.appendChild(new WebInspector.AXRelatedNodeElement({idref:idref}).render());}}else{for(var i=0;i<idrefs.length;++i){var idref=idrefs[i];var matchingNode=relatedNodes.find(node=>node.idref===idref);if(matchingNode){this.appendRelatedNodeWithIdref(matchingNode,i,idref);}else{this.appendChild(new WebInspector.AXRelatedNodeSourceTreeElement({idref:idref}));}}}},appendRelatedNodeListValueElement:function(value) {var relatedNodes=value.relatedNodes;var numNodes=relatedNodes.length;if(value.type===AccessibilityAgent.AXValueType.IdrefList||value.type===AccessibilityAgent.AXValueType.Idref){this.appendIDRefValueElement(value);}else{WebInspector.AXNodePropertyTreeElement.prototype.appendRelatedNodeListValueElement.call(this,value);} if(numNodes<=3) this.expand();else this.collapse();},appendSourceNameElement:function(source) {var nameElement=createElement("span");var AXValueSourceType=AccessibilityAgent.AXValueSourceType;var type=source.type;var name;switch(type){case AXValueSourceType.Attribute:case AXValueSourceType.Placeholder:case AXValueSourceType.RelatedElement:if(source.nativeSource){var AXNativeSourceTypes=WebInspector.AccessibilityStrings.AXNativeSourceTypes;var nativeSource=source.nativeSource;nameElement.textContent=WebInspector.UIString(AXNativeSourceTypes[nativeSource].name);nameElement.title=WebInspector.UIString(AXNativeSourceTypes[nativeSource].description);nameElement.classList.add("ax-readable-name");break;} nameElement.textContent=source.attribute;nameElement.classList.add("ax-name");nameElement.classList.add("monospace");break;default:var AXSourceTypes=WebInspector.AccessibilityStrings.AXSourceTypes;if(type in AXSourceTypes){nameElement.textContent=WebInspector.UIString(AXSourceTypes[type].name);nameElement.title=WebInspector.UIString(AXSourceTypes[type].description);nameElement.classList.add("ax-readable-name");}else{console.warn(type,"not in AXSourceTypes");nameElement.textContent=WebInspector.UIString(type);}} this.listItemElement.appendChild(nameElement);},_update:function() {this.listItemElement.removeChildren();if(this._source.invalid){var exclamationMark=WebInspector.AXNodePropertyTreeElement.createExclamationMark(WebInspector.UIString("Invalid source."));this.listItemElement.appendChild(exclamationMark);this.listItemElement.classList.add("ax-value-source-invalid");}else if(this._source.superseded){this.listItemElement.classList.add("ax-value-source-unused");} this.appendSourceNameElement(this._source);this.listItemElement.createChild("span","separator").textContent=":\u00a0";if(this._source.attributeValue){this.appendValueElement(this._source.attributeValue);this.listItemElement.createTextChild("\u00a0");}else if(this._source.nativeSourceValue){this.appendValueElement(this._source.nativeSourceValue);this.listItemElement.createTextChild("\u00a0");} if(this._source.value){this.appendValueElement(this._source.value);if(this._source.superseded) this.listItemElement.classList.add("ax-value-source-superseded");}else{var valueElement=WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(AccessibilityAgent.AXValueType.ValueUndefined,WebInspector.UIString("Not specified"));this.listItemElement.appendChild(valueElement);this.listItemElement.classList.add("ax-value-source-unused");}},__proto__:WebInspector.AXNodePropertyTreeElement.prototype};WebInspector.AXRelatedNodeSourceTreeElement=function(node,value) {this._value=value;this._axRelatedNodeElement=new WebInspector.AXRelatedNodeElement(node,value);TreeElement.call(this,"");this.selectable=false;};WebInspector.AXRelatedNodeSourceTreeElement.prototype={onattach:function() {this.listItemElement.appendChild(this._axRelatedNodeElement.render());if(!this._value) return;this.listItemElement.createTextChild("\u00a0\"");if(this._value.text) this.listItemElement.appendChild(WebInspector.AXNodePropertyTreeElement.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString,this._value.text));this.listItemElement.createTextChild("\"");},__proto__:TreeElement.prototype};WebInspector.AXRelatedNodeElement=function(node,value) {this._deferredNode=node.deferredNode;this._idref=node.idref;this._value=value;};WebInspector.AXRelatedNodeElement.prototype={render:function() {var element=createElement("span");var valueElement;function onNodeResolved(node) {valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node,this._idref));} if(this._deferredNode){valueElement=createElement("span");element.appendChild(valueElement);this._deferredNode.resolve(onNodeResolved.bind(this));}else if(this._idref){element.classList.add("invalid");valueElement=WebInspector.AXNodePropertyTreeElement.createExclamationMark(WebInspector.UIString("No node with this ID."));valueElement.createTextChild(this._idref);element.appendChild(valueElement);} return element;}};WebInspector.AXNodeIgnoredReasonTreeElement=function(property,axNode,target) {this._property=property;this._axNode=axNode;WebInspector.AXNodePropertyTreeElement.call(this,target);this.toggleOnClick=true;this.selectable=false;} WebInspector.AXNodeIgnoredReasonTreeElement.prototype={onattach:function() {this.listItemElement.removeChildren();this._reasonElement=WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement(this._property.name,this._axNode);this.listItemElement.appendChild(this._reasonElement);var value=this._property.value;if(value.type===AccessibilityAgent.AXValueType.Idref) this.appendRelatedNodeListValueElement(value);},__proto__:WebInspector.AXNodePropertyTreeElement.prototype};WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement=function(reason,axNode) {var reasonElement=null;switch(reason){case"activeModalDialog":reasonElement=WebInspector.formatLocalized("Element is hidden by active modal dialog:\u00a0",[]);break;case"ancestorDisallowsChild":reasonElement=WebInspector.formatLocalized("Element is not permitted as child of ",[]);break;case"ancestorIsLeafNode":reasonElement=WebInspector.formatLocalized("Ancestor's children are all presentational:\u00a0",[]);break;case"ariaHidden":var ariaHiddenSpan=createElement("span","source-code").textContent="aria-hidden";reasonElement=WebInspector.formatLocalized("Element is %s.",[ariaHiddenSpan]);break;case"ariaHiddenRoot":var ariaHiddenSpan=createElement("span","source-code").textContent="aria-hidden";var trueSpan=createElement("span","source-code").textContent="true";reasonElement=WebInspector.formatLocalized("%s is %s on ancestor:\u00a0",[ariaHiddenSpan,trueSpan]);break;case"emptyAlt":reasonElement=WebInspector.formatLocalized("Element has empty alt text.",[]);break;case"emptyText":reasonElement=WebInspector.formatLocalized("No text content.",[]);break;case"inert":reasonElement=WebInspector.formatLocalized("Element is inert.",[]);break;case"inheritsPresentation":reasonElement=WebInspector.formatLocalized("Element inherits presentational role from\u00a0",[]);break;case"labelContainer":reasonElement=WebInspector.formatLocalized("Part of label element:\u00a0",[]);break;case"labelFor":reasonElement=WebInspector.formatLocalized("Label for\u00a0",[]);break;case"notRendered":reasonElement=WebInspector.formatLocalized("Element is not rendered.",[]);break;case"notVisible":reasonElement=WebInspector.formatLocalized("Element is not visible.",[]);break;case"presentationalRole":var rolePresentationSpan=createElement("span","source-code").textContent="role="+axNode.role.value;reasonElement=WebInspector.formatLocalized("Element has %s.",[rolePresentationSpan]);break;case"probablyPresentational":reasonElement=WebInspector.formatLocalized("Element is presentational.",[]);break;case"staticTextUsedAsNameFor":reasonElement=WebInspector.formatLocalized("Static text node is used as name for\u00a0",[]);break;case"uninteresting":reasonElement=WebInspector.formatLocalized("Element not interesting for accessibility.",[]);break;} if(reasonElement) reasonElement.classList.add("ax-reason");return reasonElement;};;WebInspector.AccessibilityStrings={};WebInspector.AccessibilityStrings.AXAttributes={"disabled":{name:"Disabled",description:"If true, this element currently cannot be interacted with.",group:"AXGlobalStates"},"invalid":{name:"Invalid user entry",description:"If true, this element's user-entered value does not conform to validation requirement.",group:"AXGlobalStates"},"live":{name:"Live region",description:"Whether and what priority of live updates may be expected for this element.",group:"AXLiveRegionAttributes"},"atomic":{name:"Atomic (live regions)",description:"If this element may receive live updates, whether the entire live region should be presented to the user on changes, or only changed nodes.",group:"AXLiveRegionAttributes"},"relevant":{name:"Relevant (live regions)",description:"If this element may receive live updates, what type of updates should trigger a notification.",group:"AXLiveRegionAttributes"},"busy":{name:"Busy (live regions)",description:"Whether this element or its subtree are currently being updated (and thus may be in an inconsistent state).",group:"AXLiveRegionAttributes"},"root":{name:"Live region root",description:"If this element may receive live updates, the root element of the containing live region.",group:"AXLiveRegionAttributes"},"autocomplete":{name:"Has autocomplete",description:"Whether and what type of autocomplete suggestions are currently provided by this element.",group:"AXWidgetAttributes"},"haspopup":{name:"Has popup",description:"Whether this element has caused some kind of pop-up (such as a menu) to appear.",group:"AXWidgetAttributes"},"level":{name:"Level",description:"The hierarchical level of this element.",group:"AXWidgetAttributes"},"multiselectable":{name:"Multi-selectable",description:"Whether a user may select more than one option from this widget.",group:"AXWidgetAttributes"},"orientation":{name:"Orientation",description:"Whether this linear element's orientation is horizontal or vertical.",group:"AXWidgetAttributes"},"multiline":{name:"Multi-line",description:"Whether this textbox may have more than one line.",group:"AXWidgetAttributes"},"readonly":{name:"Read-only",description:"If true, this element may be interacted with, but its value cannot be changed.",group:"AXWidgetAttributes"},"required":{name:"Required",description:"Whether this element is a required field in a form.",group:"AXWidgetAttributes"},"valuemin":{name:"Minimum value",description:"For a range widget, the minimum allowed value.",group:"AXWidgetAttributes"},"valuemax":{name:"Maximum value",description:"For a range widget, the maximum allowed value.",group:"AXWidgetAttributes"},"valuetext":{name:"Value description",description:"A human-readable version of the value of a range widget (where necessary).",group:"AXWidgetAttributes"},"checked":{name:"Checked",description:"Whether this checkbox, radio button or tree item is checked, unchecked, or mixed (e.g. has both checked and un-checked children).",group:"AXWidgetStates"},"expanded":{name:"Expanded",description:"Whether this element, or another grouping element it controls, is expanded.",group:"AXWidgetStates"},"pressed":{name:"Pressed",description:"Whether this toggle button is currently in a pressed state.",group:"AXWidgetStates"},"selected":{name:"Selected",description:"Whether the option represented by this element is currently selected.",group:"AXWidgetStates"},"activedescendant":{name:"Active descendant",description:"The descendant of this element which is active; i.e. the element to which focus should be delegated.",group:"AXRelationshipAttributes"},"flowto":{name:"Flows to",description:"Element to which the user may choose to navigate after this one, instead of the next element in the DOM order.",group:"AXRelationshipAttributes"},"controls":{name:"Controls",description:"Element or elements whose content or presence is/are controlled by this widget.",group:"AXRelationshipAttributes"},"describedby":{name:"Described by",description:"Element or elements which form the description of this element.",group:"AXRelationshipAttributes"},"labelledby":{name:"Labeled by",description:"Element or elements which may form the name of this element.",group:"AXRelationshipAttributes"},"owns":{name:"Owns",description:"Element or elements which should be considered descendants of this element, despite not being descendants in the DOM.",group:"AXRelationshipAttributes"},"name":{name:"Name",description:"The computed name of this element.",group:"Default"},"role":{name:"Role",description:"Indicates the purpose of this element, such as a user interface idiom for a widget, or structural role within a document.",group:"Default"},"value":{name:"Value",description:"The value of this element; this may be user-provided or developer-provided, depending on the element.",group:"Default"},"help":{name:"Help",description:"The computed help text for this element.",group:"Default"},"description":{name:"Description",description:"The accessible description for this element.",group:"Default"}};WebInspector.AccessibilityStrings.AXSourceTypes={"attribute":{name:"From attribute",description:"Value from attribute."},"implicit":{name:"Implicit",description:"Implicit value.",},"style":{name:"From style",description:"Value from style."},"contents":{name:"Contents",description:"Value from element contents."},"placeholder":{name:"From placeholder attribute",description:"Value from placeholder attribute."},"relatedElement":{name:"Related element",description:"Value from related element."}} WebInspector.AccessibilityStrings.AXNativeSourceTypes={"figcaption":{name:"From caption",description:"Value from figcaption element."},"label":{name:"From label",description:"Value from label element."},"labelfor":{name:"From label (for)",description:"Value from label element with for= attribute."},"labelwrapped":{name:"From label (wrapped)",description:"Value from label element wrapped."},"tablecaption":{name:"From caption",description:"Value from table caption."},"other":{name:"From native HTML",description:"Value from native HTML (unknown source)."},};Runtime.cachedResources["accessibility/accessibilityNode.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.ax-computed-text {\n padding: 3px 5px 0;\n background-image: url(Images/speech.png);\n background-repeat: no-repeat;\n background-position: 16px center;\n padding: 4px 4px 0 4px;\n padding-left: 36px;\n min-height: 18px;\n}\n\n.ax-computed-text div {\n display: inline-block;\n padding: 2px;\n width: 100%;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n width: 100%;\n}\n\ndiv.ax-text-alternatives {\n margin-bottom: 3px;\n border-bottom: 1px solid #BFBFBF;\n}\n\n.ax-name {\n color: rgb(153, 69, 0);\n flex-shrink: 0;\n}\n\n.ax-readable-name {\n flex-shrink: 0;\n padding-left: 2px;\n}\n\n.ax-readable-string {\n font-style: italic;\n}\n\nspan.ax-role {\n font-weight: bold;\n}\n\nspan.ax-internal-role {\n font-style: italic;\n}\n\n.ax-ignored-info {\n padding: 6px;\n}\n\n.ax-ignored-node-pane {\n background-color: hsl(0, 0%, 96%);\n}\n\n.tree-outline li {\n padding-left: 1px;\n align-items: baseline;\n}\n\n.tree-outline li.property {\n color: rgb(33, 33, 33);\n}\n\n.tree-outline li.invalid {\n position: relative;\n left: -2px;\n}\n\n.invalid {\n text-decoration: line-through;\n}\n\n.tree-outline label[is=dt-icon-label] {\n position: relative;\n left: -11px;\n}\n\nspan.ax-value-undefined {\n font-style: italic;\n}\n\n.ax-value-source-unused {\n opacity: 0.5;\n}\n\n.ax-value-source-superseded,\n.ax-value-source-invalid {\n text-decoration: line-through;\n}\n\n.tree-outline label[is=dt-icon-label] + .ax-name {\n margin-left: -11px;\n}\n\n.ax-value-string {\n color: rgb(26, 26, 166);\n}\n\n.sidebar-pane-stack .sidebar-pane {\n padding-left: 4px;\n}\n\n/*# sourceURL=accessibility/accessibilityNode.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | 2 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.AnimationModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.AnimationModel,target);this._agent=target.animationAgent();target.registerAnimationDispatcher(new WebInspector.AnimationDispatcher(this));this._animationsById=new Map();this._animationGroups=new Map();this._pendingAnimations=[];this._playbackRate=1;target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._reset,this);this._screenshotCapture=new WebInspector.AnimationModel.ScreenshotCapture(target,this);} WebInspector.AnimationModel.Events={AnimationGroupStarted:"AnimationGroupStarted",ModelReset:"ModelReset"} WebInspector.AnimationModel.prototype={_reset:function() {this._animationsById.clear();this._animationGroups.clear();this._pendingAnimations=[];this.dispatchEventToListeners(WebInspector.AnimationModel.Events.ModelReset);},animationCreated:function(id) {this._pendingAnimations.push(id);},_animationCanceled:function(id) {this._pendingAnimations.remove(id);this._flushPendingAnimationsIfNeeded();},animationStarted:function(payload) {var animation=WebInspector.AnimationModel.Animation.parsePayload(this.target(),payload);if(animation.type()==="WebAnimation"&&animation.source().keyframesRule().keyframes().length===0){this._pendingAnimations.remove(animation.id());}else{this._animationsById.set(animation.id(),animation);if(this._pendingAnimations.indexOf(animation.id())===-1) this._pendingAnimations.push(animation.id());} this._flushPendingAnimationsIfNeeded();},_flushPendingAnimationsIfNeeded:function() {for(var id of this._pendingAnimations){if(!this._animationsById.get(id)) return;} while(this._pendingAnimations.length) this._matchExistingGroups(this._createGroupFromPendingAnimations());},_matchExistingGroups:function(incomingGroup) {var matchedGroup=null;for(var group of this._animationGroups.values()){if(group._matches(incomingGroup)){matchedGroup=group;group._update(incomingGroup);break;}} if(!matchedGroup){this._animationGroups.set(incomingGroup.id(),incomingGroup);this._screenshotCapture.captureScreenshots(incomingGroup.finiteDuration(),incomingGroup._screenshots);} this.dispatchEventToListeners(WebInspector.AnimationModel.Events.AnimationGroupStarted,matchedGroup||incomingGroup);return!!matchedGroup;},_createGroupFromPendingAnimations:function() {console.assert(this._pendingAnimations.length);var groupedAnimations=[this._animationsById.get(this._pendingAnimations.shift())];var remainingAnimations=[];for(var id of this._pendingAnimations){var anim=this._animationsById.get(id);if(anim.startTime()===groupedAnimations[0].startTime()) groupedAnimations.push(anim);else remainingAnimations.push(id);} this._pendingAnimations=remainingAnimations;return new WebInspector.AnimationModel.AnimationGroup(this,groupedAnimations[0].id(),groupedAnimations);},playbackRatePromise:function() {function callback(error,playbackRate) {if(error) return 1;this._playbackRate=playbackRate;return playbackRate;} return this._agent.getPlaybackRate(callback.bind(this)).catchException(1);},setPlaybackRate:function(playbackRate) {this._playbackRate=playbackRate;this._agent.setPlaybackRate(playbackRate);},_releaseAnimations:function(animations) {this.target().animationAgent().releaseAnimations(animations);},suspendModel:function() {this._reset();return this._agent.disable();},resumeModel:function() {if(!this._enabled) return Promise.resolve();return this._agent.enable();},ensureEnabled:function() {if(this._enabled) return;this._agent.enable();this._enabled=true;},__proto__:WebInspector.SDKModel.prototype} WebInspector.AnimationModel._symbol=Symbol("AnimationModel");WebInspector.AnimationModel.fromTarget=function(target) {if(!target[WebInspector.AnimationModel._symbol]) target[WebInspector.AnimationModel._symbol]=new WebInspector.AnimationModel(target);return target[WebInspector.AnimationModel._symbol];} WebInspector.AnimationModel.Animation=function(target,payload) {WebInspector.SDKObject.call(this,target);this._payload=payload;this._source=new WebInspector.AnimationModel.AnimationEffect(this.target(),this._payload.source);} WebInspector.AnimationModel.Animation.parsePayload=function(target,payload) {return new WebInspector.AnimationModel.Animation(target,payload);} WebInspector.AnimationModel.Animation.Type={CSSTransition:"CSSTransition",CSSAnimation:"CSSAnimation",WebAnimation:"WebAnimation"} WebInspector.AnimationModel.Animation.prototype={payload:function() {return this._payload;},id:function() {return this._payload.id;},name:function() {return this._payload.name;},paused:function() {return this._payload.pausedState;},playState:function() {return this._playState||this._payload.playState;},setPlayState:function(playState) {this._playState=playState;},playbackRate:function() {return this._payload.playbackRate;},startTime:function() {return this._payload.startTime;},endTime:function() {if(!this.source().iterations) return Infinity;return this.startTime()+this.source().delay()+this.source().duration()*this.source().iterations()+this.source().endDelay();},_finiteDuration:function() {var iterations=Math.min(this.source().iterations(),3);return this.source().delay()+this.source().duration()*iterations;},currentTime:function() {return this._payload.currentTime;},source:function() {return this._source;},type:function() {return(this._payload.type);},overlaps:function(animation) {if(!this.source().iterations()||!animation.source().iterations()) return true;var firstAnimation=this.startTime()<animation.startTime()?this:animation;var secondAnimation=firstAnimation===this?animation:this;return firstAnimation.endTime()>=secondAnimation.startTime();},setTiming:function(duration,delay) {this._source.node().then(this._updateNodeStyle.bind(this,duration,delay));this._source._duration=duration;this._source._delay=delay;this.target().animationAgent().setTiming(this.id(),duration,delay);},_updateNodeStyle:function(duration,delay,node) {var animationPrefix;if(this.type()==WebInspector.AnimationModel.Animation.Type.CSSTransition) animationPrefix="transition-";else if(this.type()==WebInspector.AnimationModel.Animation.Type.CSSAnimation) animationPrefix="animation-";else return;var cssModel=WebInspector.CSSModel.fromTarget(node.target());if(!cssModel) return;cssModel.setEffectivePropertyValueForNode(node.id,animationPrefix+"duration",duration+"ms");cssModel.setEffectivePropertyValueForNode(node.id,animationPrefix+"delay",delay+"ms");},remoteObjectPromise:function() {function callback(error,payload) {return!error?this.target().runtimeModel.createRemoteObject(payload):null;} return this.target().animationAgent().resolveAnimation(this.id(),callback.bind(this));},_cssId:function() {return this._payload.cssId||"";},__proto__:WebInspector.SDKObject.prototype} WebInspector.AnimationModel.AnimationEffect=function(target,payload) {WebInspector.SDKObject.call(this,target);this._payload=payload;if(payload.keyframesRule) this._keyframesRule=new WebInspector.AnimationModel.KeyframesRule(target,payload.keyframesRule);this._delay=this._payload.delay;this._duration=this._payload.duration;} WebInspector.AnimationModel.AnimationEffect.prototype={delay:function() {return this._delay;},endDelay:function() {return this._payload.endDelay;},playbackRate:function() {return this._payload.playbackRate;},iterationStart:function() {return this._payload.iterationStart;},iterations:function() {if(!this.delay()&&!this.endDelay()&&!this.duration()) return 0;return this._payload.iterations||Infinity;},duration:function() {return this._duration;},direction:function() {return this._payload.direction;},fill:function() {return this._payload.fill;},node:function() {if(!this._deferredNode) this._deferredNode=new WebInspector.DeferredDOMNode(this.target(),this.backendNodeId());return this._deferredNode.resolvePromise();},deferredNode:function() {return new WebInspector.DeferredDOMNode(this.target(),this.backendNodeId());},backendNodeId:function() {return this._payload.backendNodeId;},keyframesRule:function() {return this._keyframesRule;},easing:function() {return this._payload.easing;},__proto__:WebInspector.SDKObject.prototype} WebInspector.AnimationModel.KeyframesRule=function(target,payload) {WebInspector.SDKObject.call(this,target);this._payload=payload;this._keyframes=this._payload.keyframes.map(function(keyframeStyle){return new WebInspector.AnimationModel.KeyframeStyle(target,keyframeStyle);});} WebInspector.AnimationModel.KeyframesRule.prototype={_setKeyframesPayload:function(payload) {this._keyframes=payload.map(function(keyframeStyle){return new WebInspector.AnimationModel.KeyframeStyle(this._target,keyframeStyle);});},name:function() {return this._payload.name;},keyframes:function() {return this._keyframes;},__proto__:WebInspector.SDKObject.prototype} WebInspector.AnimationModel.KeyframeStyle=function(target,payload) {WebInspector.SDKObject.call(this,target);this._payload=payload;this._offset=this._payload.offset;} WebInspector.AnimationModel.KeyframeStyle.prototype={offset:function() {return this._offset;},setOffset:function(offset) {this._offset=offset*100+"%";},offsetAsNumber:function() {return parseFloat(this._offset)/100;},easing:function() {return this._payload.easing;},__proto__:WebInspector.SDKObject.prototype} WebInspector.AnimationModel.AnimationGroup=function(model,id,animations) {WebInspector.SDKObject.call(this,model.target());this._model=model;this._id=id;this._animations=animations;this._paused=false;this._screenshots=[];this._screenshotImages=[];} WebInspector.AnimationModel.AnimationGroup.prototype={id:function() {return this._id;},animations:function() {return this._animations;},release:function() {this._model._animationGroups.remove(this.id());this._model._releaseAnimations(this._animationIds());},_animationIds:function() {function extractId(animation) {return animation.id();} return this._animations.map(extractId);},startTime:function() {return this._animations[0].startTime();},finiteDuration:function() {var maxDuration=0;for(var i=0;i<this._animations.length;++i) maxDuration=Math.max(maxDuration,this._animations[i]._finiteDuration());return maxDuration;},seekTo:function(currentTime) {this.target().animationAgent().seekAnimations(this._animationIds(),currentTime);},paused:function() {return this._paused;},togglePause:function(paused) {if(paused===this._paused) return;this._paused=paused;this.target().animationAgent().setPaused(this._animationIds(),paused);},currentTimePromise:function() {function callback(error,currentTime) {return!error?currentTime:0;} var longestAnim=null;for(var anim of this._animations){if(!longestAnim||anim.endTime()>longestAnim.endTime()) longestAnim=anim;} return this.target().animationAgent().getCurrentTime(longestAnim.id(),callback).catchException(0);},_matches:function(group) {function extractId(anim) {if(anim.type()===WebInspector.AnimationModel.Animation.Type.WebAnimation) return anim.type()+anim.id();else return anim._cssId();} if(this._animations.length!==group._animations.length) return false;var left=this._animations.map(extractId).sort();var right=group._animations.map(extractId).sort();for(var i=0;i<left.length;i++){if(left[i]!==right[i]) return false;} return true;},_update:function(group) {this._model._releaseAnimations(this._animationIds());this._animations=group._animations;},screenshots:function() {for(var i=0;i<this._screenshots.length;++i){var image=new Image();image.src="data:image/jpeg;base64,"+this._screenshots[i];this._screenshotImages.push(image);} this._screenshots=[];return this._screenshotImages;},__proto__:WebInspector.SDKObject.prototype} WebInspector.AnimationDispatcher=function(animationModel) {this._animationModel=animationModel;} WebInspector.AnimationDispatcher.prototype={animationCreated:function(id) {this._animationModel.animationCreated(id);},animationCanceled:function(id) {this._animationModel._animationCanceled(id);},animationStarted:function(payload) {this._animationModel.animationStarted(payload);}} WebInspector.AnimationModel.ScreenshotCapture=function(target,model) {this._target=target;this._requests=[];this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame,this._screencastFrame,this);this._model=model;this._model.addEventListener(WebInspector.AnimationModel.Events.ModelReset,this._stopScreencast,this);} WebInspector.AnimationModel.ScreenshotCapture.Request;WebInspector.AnimationModel.ScreenshotCapture.prototype={captureScreenshots:function(duration,screenshots) {var screencastDuration=Math.min(duration/this._model._playbackRate,3000);var endTime=screencastDuration+window.performance.now();this._requests.push({endTime:endTime,screenshots:screenshots});if(!this._endTime||endTime>this._endTime){clearTimeout(this._stopTimer);this._stopTimer=setTimeout(this._stopScreencast.bind(this),screencastDuration);this._endTime=endTime;} if(this._capturing) return;this._capturing=true;this._target.pageAgent().startScreencast("jpeg",80,undefined,300,2);},_screencastFrame:function(event) {function isAnimating(request) {return request.endTime>=now;} if(!this._capturing) return;var base64Data=(event.data["data"]);var now=window.performance.now();this._requests=this._requests.filter(isAnimating);for(var request of this._requests) request.screenshots.push(base64Data);},_stopScreencast:function() {if(!this._capturing) return;delete this._stopTimer;delete this._endTime;this._requests=[];this._capturing=false;this._target.pageAgent().stopScreencast();}};WebInspector.AnimationGroupPreviewUI=function(model) {this._model=model;this.element=createElementWithClass("div","animation-buffer-preview");this.element.createChild("div","animation-paused fill");this._removeButton=this.element.createChild("div","animation-remove-button");this._removeButton.textContent="\u2715";this._replayOverlayElement=this.element.createChild("div","animation-buffer-preview-animation");this._svg=this.element.createSVGChild("svg");this._svg.setAttribute("width","100%");this._svg.setAttribute("preserveAspectRatio","none");this._svg.setAttribute("height","100%");this._viewBoxHeight=32;this._svg.setAttribute("viewBox","0 0 100 "+this._viewBoxHeight);this._svg.setAttribute("shape-rendering","crispEdges");this._render();} WebInspector.AnimationGroupPreviewUI.prototype={_groupDuration:function() {var duration=0;for(var anim of this._model.animations()){var animDuration=anim.source().delay()+anim.source().duration();if(animDuration>duration) duration=animDuration;} return duration;},removeButton:function() {return this._removeButton;},replay:function() {this._replayOverlayElement.animate([{offset:0,width:"0%",opacity:1},{offset:0.9,width:"100%",opacity:1},{offset:1,width:"100%",opacity:0}],{duration:200,easing:"cubic-bezier(0, 0, 0.2, 1)"});},_render:function() {this._svg.removeChildren();var maxToShow=10;var numberOfAnimations=Math.min(this._model.animations().length,maxToShow);var timeToPixelRatio=100/Math.max(this._groupDuration(),750);for(var i=0;i<numberOfAnimations;i++){var effect=this._model.animations()[i].source();var line=this._svg.createSVGChild("line");line.setAttribute("x1",effect.delay()*timeToPixelRatio);line.setAttribute("x2",(effect.delay()+effect.duration())*timeToPixelRatio);var y=Math.floor(this._viewBoxHeight/Math.max(6,numberOfAnimations)*i+1);line.setAttribute("y1",y);line.setAttribute("y2",y);line.style.stroke=WebInspector.AnimationUI.Color(this._model.animations()[i]);}}};WebInspector.AnimationScreenshotPopover=function(images) {WebInspector.VBox.call(this,true);console.assert(images.length);this.registerRequiredCSS("animation/animationScreenshotPopover.css");this.contentElement.classList.add("animation-screenshot-popover");this._frames=images;for(var image of images){this.contentElement.appendChild(image);image.style.display="none";} this._currentFrame=0;this._frames[0].style.display="block";this._progressBar=this.contentElement.createChild("div","animation-progress");} WebInspector.AnimationScreenshotPopover.prototype={wasShown:function() {this._rafId=this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));},willHide:function() {this.contentElement.window().cancelAnimationFrame(this._rafId);delete this._endDelay;},_changeFrame:function() {this._rafId=this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));if(this._endDelay){this._endDelay--;return;} this._showFrame=!this._showFrame;if(!this._showFrame) return;var numFrames=this._frames.length;this._frames[this._currentFrame%numFrames].style.display="none";this._currentFrame++;this._frames[(this._currentFrame)%numFrames].style.display="block";if(this._currentFrame%numFrames===numFrames-1) this._endDelay=50;this._progressBar.style.width=(this._currentFrame%numFrames+1)/numFrames*100+"%";},__proto__:WebInspector.VBox.prototype};WebInspector.AnimationTimeline=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("animation/animationTimeline.css");this.element.classList.add("animations-timeline");this._grid=this.contentElement.createSVGChild("svg","animation-timeline-grid");this._playbackRate=1;this._allPaused=false;this._createHeader();this._animationsContainer=this.contentElement.createChild("div","animation-timeline-rows");var timelineHint=this.contentElement.createChild("div","animation-timeline-rows-hint");timelineHint.textContent=WebInspector.UIString("Select an effect above to inspect and modify.");this._defaultDuration=100;this._duration=this._defaultDuration;this._timelineControlsWidth=150;this._nodesMap=new Map();this._uiAnimations=[];this._groupBuffer=[];this._previewMap=new Map();this._symbol=Symbol("animationTimeline");this._animationsMap=new Map();WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.NodeRemoved,this._nodeRemoved,this);WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode,this._nodeChanged,this);} WebInspector.AnimationTimeline.GlobalPlaybackRates=[1,0.25,0.1];WebInspector.AnimationTimeline._ControlState={Play:"play-outline",Replay:"replay-outline",Pause:"pause-outline"} WebInspector.AnimationTimeline.prototype={wasShown:function() {for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)) this._addEventListeners(target);},willHide:function() {for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)) this._removeEventListeners(target);this._popoverHelper.hidePopover();},targetAdded:function(target) {if(this.isShowing()) this._addEventListeners(target);},targetRemoved:function(target) {this._removeEventListeners(target);},_addEventListeners:function(target) {var animationModel=WebInspector.AnimationModel.fromTarget(target);animationModel.ensureEnabled();animationModel.addEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted,this._animationGroupStarted,this);animationModel.addEventListener(WebInspector.AnimationModel.Events.ModelReset,this._reset,this);},_removeEventListeners:function(target) {var animationModel=WebInspector.AnimationModel.fromTarget(target);animationModel.removeEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted,this._animationGroupStarted,this);animationModel.removeEventListener(WebInspector.AnimationModel.Events.ModelReset,this._reset,this);},_nodeChanged:function() {for(var nodeUI of this._nodesMap.values()) nodeUI._nodeChanged();},_createScrubber:function(){this._timelineScrubber=createElementWithClass("div","animation-scrubber hidden");this._timelineScrubberLine=this._timelineScrubber.createChild("div","animation-scrubber-line");this._timelineScrubberLine.createChild("div","animation-scrubber-head");this._timelineScrubber.createChild("div","animation-time-overlay");return this._timelineScrubber;},_createHeader:function() {var toolbarContainer=this.contentElement.createChild("div","animation-timeline-toolbar-container");var topToolbar=new WebInspector.Toolbar("animation-timeline-toolbar",toolbarContainer);var clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear all"),"clear-toolbar-item");clearButton.addEventListener("click",this._reset.bind(this));topToolbar.appendToolbarItem(clearButton);topToolbar.appendSeparator();this._pauseButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Pause all"),"pause-toolbar-item");this._pauseButton.addEventListener("click",this._togglePauseAll.bind(this));topToolbar.appendToolbarItem(this._pauseButton);var playbackRateControl=toolbarContainer.createChild("div","animation-playback-rate-control");this._playbackRateButtons=[];for(var playbackRate of WebInspector.AnimationTimeline.GlobalPlaybackRates){var button=playbackRateControl.createChild("div","animation-playback-rate-button");button.textContent=playbackRate?WebInspector.UIString(playbackRate*100+"%"):WebInspector.UIString("Pause");button.playbackRate=playbackRate;button.addEventListener("click",this._setPlaybackRate.bind(this,playbackRate));button.title=WebInspector.UIString("Set speed to ")+button.textContent;this._playbackRateButtons.push(button);} this._updatePlaybackControls();this._previewContainer=this.contentElement.createChild("div","animation-timeline-buffer");this._popoverHelper=new WebInspector.PopoverHelper(this._previewContainer,this._getPopoverAnchor.bind(this),this._showPopover.bind(this),this._onHidePopover.bind(this),true);this._popoverHelper.setTimeout(0);var emptyBufferHint=this.contentElement.createChild("div","animation-timeline-buffer-hint");emptyBufferHint.textContent=WebInspector.UIString("Listening for animations...");var container=this.contentElement.createChild("div","animation-timeline-header");var controls=container.createChild("div","animation-controls");this._currentTime=controls.createChild("div","animation-timeline-current-time monospace");var toolbar=new WebInspector.Toolbar("animation-controls-toolbar",controls);this._controlButton=new WebInspector.ToolbarButton(WebInspector.UIString("Replay timeline"),"animation-control-toolbar-item");this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Replay);this._controlButton.addEventListener("click",this._controlButtonToggle.bind(this));toolbar.appendToolbarItem(this._controlButton);var gridHeader=container.createChild("div","animation-grid-header");WebInspector.installDragHandle(gridHeader,this._repositionScrubber.bind(this),this._scrubberDragMove.bind(this),this._scrubberDragEnd.bind(this),"text");container.appendChild(this._createScrubber());WebInspector.installDragHandle(this._timelineScrubberLine,this._scrubberDragStart.bind(this),this._scrubberDragMove.bind(this),this._scrubberDragEnd.bind(this),"col-resize");this._currentTime.textContent="";return container;},_getPopoverAnchor:function(element,event) {if(element.isDescendant(this._previewContainer)) return element;},_showPopover:function(anchor,popover) {var animGroup;for(var group of this._previewMap.keysArray()){if(this._previewMap.get(group).element===anchor.parentElement) animGroup=group;} console.assert(animGroup);var screenshots=animGroup.screenshots();if(!screenshots.length) return;var content=new WebInspector.AnimationScreenshotPopover(screenshots);popover.setNoMargins(true);popover.showView(content,anchor);},_onHidePopover:function() {},_togglePauseAll:function() {this._allPaused=!this._allPaused;this._pauseButton.setToggled(this._allPaused);this._setPlaybackRate(this._playbackRate);this._pauseButton.setTitle(this._allPaused?WebInspector.UIString("Resume all"):WebInspector.UIString("Pause all"));},_setPlaybackRate:function(playbackRate) {this._playbackRate=playbackRate;var target=WebInspector.targetManager.mainTarget();if(target) WebInspector.AnimationModel.fromTarget(target).setPlaybackRate(this._allPaused?0:this._playbackRate);WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.AnimationsPlaybackRateChanged);if(this._scrubberPlayer) this._scrubberPlayer.playbackRate=this._effectivePlaybackRate();this._updatePlaybackControls();},_updatePlaybackControls:function() {for(var button of this._playbackRateButtons){var selected=this._playbackRate===button.playbackRate;button.classList.toggle("selected",selected);}},_controlButtonToggle:function() {if(this._controlButton.state()===WebInspector.AnimationTimeline._ControlState.Play) this._togglePause(false);else if(this._controlButton.state()===WebInspector.AnimationTimeline._ControlState.Replay) this._replay();else this._togglePause(true);},_updateControlButton:function() {this._controlButton.setEnabled(!!this._selectedGroup);if(this._selectedGroup&&this._selectedGroup.paused()){this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Play);this._controlButton.setTitle(WebInspector.UIString("Play timeline"));}else if(!this._scrubberPlayer||this._scrubberPlayer.currentTime>=this.duration()){this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Replay);this._controlButton.setTitle(WebInspector.UIString("Replay timeline"));}else{this._controlButton.setState(WebInspector.AnimationTimeline._ControlState.Pause);this._controlButton.setTitle(WebInspector.UIString("Pause timeline"));}},_effectivePlaybackRate:function() {return(this._allPaused||(this._selectedGroup&&this._selectedGroup.paused()))?0:this._playbackRate;},_togglePause:function(pause) {this._selectedGroup.togglePause(pause);if(this._scrubberPlayer) this._scrubberPlayer.playbackRate=this._effectivePlaybackRate();this._previewMap.get(this._selectedGroup).element.classList.toggle("paused",pause);this._updateControlButton();},_replay:function() {if(!this._selectedGroup) return;this._selectedGroup.seekTo(0);this._animateTime(0);this._updateControlButton();},duration:function() {return this._duration;},setDuration:function(duration) {this._duration=duration;this.scheduleRedraw();},_clearTimeline:function() {this._uiAnimations=[];this._nodesMap.clear();this._animationsMap.clear();this._animationsContainer.removeChildren();this._duration=this._defaultDuration;this._timelineScrubber.classList.add("hidden");delete this._selectedGroup;if(this._scrubberPlayer) this._scrubberPlayer.cancel();delete this._scrubberPlayer;this._currentTime.textContent="";this._updateControlButton();},_reset:function() {this._clearTimeline();if(this._allPaused){this._playbackRate=1;this._togglePauseAll();}else{this._setPlaybackRate(1);} for(var group of this._groupBuffer) group.release();this._groupBuffer=[];this._previewMap.clear();this._previewContainer.removeChildren();this._popoverHelper.hidePopover();this._renderGrid();},_animationGroupStarted:function(event) {this._addAnimationGroup((event.data));},_addAnimationGroup:function(group) {function startTimeComparator(left,right) {return left.startTime()>right.startTime();} if(this._previewMap.get(group)){if(this._selectedGroup===group) this._syncScrubber();else this._previewMap.get(group).replay();return;} this._groupBuffer.sort(startTimeComparator);var groupsToDiscard=[];var bufferSize=this.width()/50;while(this._groupBuffer.length>bufferSize){var toDiscard=this._groupBuffer.splice(this._groupBuffer[0]===this._selectedGroup?1:0,1);groupsToDiscard.push(toDiscard[0]);} for(var g of groupsToDiscard){this._previewMap.get(g).element.remove();this._previewMap.delete(g);g.release();} var preview=new WebInspector.AnimationGroupPreviewUI(group);this._groupBuffer.push(group);this._previewMap.set(group,preview);this._previewContainer.appendChild(preview.element);preview.removeButton().addEventListener("click",this._removeAnimationGroup.bind(this,group));preview.element.addEventListener("click",this._selectAnimationGroup.bind(this,group));},_removeAnimationGroup:function(group,event) {this._groupBuffer.remove(group);this._previewMap.get(group).element.remove();this._previewMap.delete(group);group.release();event.consume(true);if(this._selectedGroup===group){this._clearTimeline();this._renderGrid();}},_selectAnimationGroup:function(group) {function applySelectionClass(ui,group) {ui.element.classList.toggle("selected",this._selectedGroup===group);} if(this._selectedGroup===group){this._togglePause(false);this._replay();return;} this._clearTimeline();this._selectedGroup=group;this._previewMap.forEach(applySelectionClass,this);this.setDuration(Math.max(500,group.finiteDuration()+100));for(var anim of group.animations()) this._addAnimation(anim);this.scheduleRedraw();this._timelineScrubber.classList.remove("hidden");this._togglePause(false);this._replay();},_addAnimation:function(animation) {function nodeResolved(node) {nodeUI.nodeResolved(node);uiAnimation.setNode(node);if(node) node[this._symbol]=nodeUI;} var nodeUI=this._nodesMap.get(animation.source().backendNodeId());if(!nodeUI){nodeUI=new WebInspector.AnimationTimeline.NodeUI(animation.source());this._animationsContainer.appendChild(nodeUI.element);this._nodesMap.set(animation.source().backendNodeId(),nodeUI);} var nodeRow=nodeUI.createNewRow();var uiAnimation=new WebInspector.AnimationUI(animation,this,nodeRow);animation.source().deferredNode().resolve(nodeResolved.bind(this));this._uiAnimations.push(uiAnimation);this._animationsMap.set(animation.id(),animation);},_nodeRemoved:function(event) {var node=event.data.node;if(node[this._symbol]) node[this._symbol].nodeRemoved();},_renderGrid:function() {var gridSize=250;this._grid.setAttribute("width",this.width()+10);this._grid.setAttribute("height",this._cachedTimelineHeight+30);this._grid.setAttribute("shape-rendering","crispEdges");this._grid.removeChildren();var lastDraw=undefined;for(var time=0;time<this.duration();time+=gridSize){var line=this._grid.createSVGChild("rect","animation-timeline-grid-line");line.setAttribute("x",time*this.pixelMsRatio()+10);line.setAttribute("y",23);line.setAttribute("height","100%");line.setAttribute("width",1);} for(var time=0;time<this.duration();time+=gridSize){var gridWidth=time*this.pixelMsRatio();if(lastDraw===undefined||gridWidth-lastDraw>50){lastDraw=gridWidth;var label=this._grid.createSVGChild("text","animation-timeline-grid-label");label.textContent=WebInspector.UIString(Number.millisToString(time));label.setAttribute("x",gridWidth+10);label.setAttribute("y",16);}}},scheduleRedraw:function() {this._renderQueue=[];for(var ui of this._uiAnimations) this._renderQueue.push(ui);if(this._redrawing) return;this._redrawing=true;this._renderGrid();this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));},_render:function(timestamp) {while(this._renderQueue.length&&(!timestamp||window.performance.now()-timestamp<50)) this._renderQueue.shift().redraw();if(this._renderQueue.length) this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));else delete this._redrawing;},onResize:function() {this._cachedTimelineWidth=Math.max(0,this._animationsContainer.offsetWidth-this._timelineControlsWidth)||0;this._cachedTimelineHeight=this._animationsContainer.offsetHeight;this.scheduleRedraw();if(this._scrubberPlayer) this._syncScrubber();delete this._gridOffsetLeft;},width:function() {return this._cachedTimelineWidth||0;},_resizeWindow:function(animation) {var resized=false;var duration=animation.source().duration()*Math.min(2,animation.source().iterations());var requiredDuration=animation.source().delay()+duration+animation.source().endDelay();if(requiredDuration>this._duration){resized=true;this._duration=requiredDuration+200;} return resized;},_syncScrubber:function() {if(!this._selectedGroup) return;this._selectedGroup.currentTimePromise().then(this._animateTime.bind(this)).then(this._updateControlButton.bind(this));},_animateTime:function(currentTime) {if(this._scrubberPlayer) this._scrubberPlayer.cancel();this._scrubberPlayer=this._timelineScrubber.animate([{transform:"translateX(0px)"},{transform:"translateX("+this.width()+"px)"}],{duration:this.duration(),fill:"forwards"});this._scrubberPlayer.playbackRate=this._effectivePlaybackRate();this._scrubberPlayer.onfinish=this._updateControlButton.bind(this);this._scrubberPlayer.currentTime=currentTime;this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));},pixelMsRatio:function() {return this.width()/this.duration()||0;},_updateScrubber:function(timestamp) {if(!this._scrubberPlayer) return;this._currentTime.textContent=WebInspector.UIString(Number.millisToString(this._scrubberPlayer.currentTime));if(this._scrubberPlayer.playState==="pending"||this._scrubberPlayer.playState==="running"){this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));}else if(this._scrubberPlayer.playState==="finished"){this._currentTime.textContent="";}},_repositionScrubber:function(event) {if(!this._selectedGroup) return false;if(!this._gridOffsetLeft) this._gridOffsetLeft=this._grid.totalOffsetLeft()+10;var seekTime=Math.max(0,event.x-this._gridOffsetLeft)/this.pixelMsRatio();this._selectedGroup.seekTo(seekTime);this._togglePause(true);this._animateTime(seekTime);this._originalScrubberTime=seekTime;this._originalMousePosition=event.x;return true;},_scrubberDragStart:function(event) {if(!this._scrubberPlayer||!this._selectedGroup) return false;this._originalScrubberTime=this._scrubberPlayer.currentTime;this._timelineScrubber.classList.remove("animation-timeline-end");this._scrubberPlayer.pause();this._originalMousePosition=event.x;this._togglePause(true);return true;},_scrubberDragMove:function(event) {var delta=event.x-this._originalMousePosition;var currentTime=Math.max(0,Math.min(this._originalScrubberTime+delta/this.pixelMsRatio(),this.duration()));this._scrubberPlayer.currentTime=currentTime;this._currentTime.textContent=WebInspector.UIString(Number.millisToString(Math.round(currentTime)));this._selectedGroup.seekTo(currentTime);},_scrubberDragEnd:function(event) {var currentTime=Math.max(0,this._scrubberPlayer.currentTime);this._scrubberPlayer.play();this._scrubberPlayer.currentTime=currentTime;this._currentTime.window().requestAnimationFrame(this._updateScrubber.bind(this));},__proto__:WebInspector.VBox.prototype} WebInspector.AnimationTimeline.NodeUI=function(animationEffect) {this.element=createElementWithClass("div","animation-node-row");this._description=this.element.createChild("div","animation-node-description");this._timelineElement=this.element.createChild("div","animation-node-timeline");} WebInspector.AnimationTimeline.NodeUI.prototype={nodeResolved:function(node) {if(!node){this._description.createTextChild(WebInspector.UIString("<node>"));return;} this._node=node;this._nodeChanged();this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));if(!node.ownerDocument) this.nodeRemoved();},createNewRow:function() {return this._timelineElement.createChild("div","animation-timeline-row");},nodeRemoved:function() {this.element.classList.add("animation-node-removed");this._node=null;},_nodeChanged:function() {this.element.classList.toggle("animation-node-selected",this._node&&this._node===WebInspector.context.flavor(WebInspector.DOMNode));}} WebInspector.AnimationTimeline.StepTimingFunction=function(steps,stepAtPosition) {this.steps=steps;this.stepAtPosition=stepAtPosition;} WebInspector.AnimationTimeline.StepTimingFunction.parse=function(text){var match=text.match(/^step-(start|middle|end)$/);if(match) return new WebInspector.AnimationTimeline.StepTimingFunction(1,match[1]);match=text.match(/^steps\((\d+), (start|middle|end)\)$/);if(match) return new WebInspector.AnimationTimeline.StepTimingFunction(parseInt(match[1],10),match[2]);return null;} WebInspector.AnimationTimeline.ButtonProvider=function() {this._button=new WebInspector.ToolbarButton(WebInspector.UIString("Animations"),"animation-toolbar-item");this._button.addEventListener("click",this._clicked,this);} WebInspector.AnimationTimeline.ButtonProvider.prototype={_clicked:function() {WebInspector.inspectorView.showViewInDrawer("animations");},item:function() {return this._button;}};WebInspector.AnimationUI=function(animation,timeline,parentElement){this._animation=animation;this._timeline=timeline;this._parentElement=parentElement;if(this._animation.source().keyframesRule()) this._keyframes=this._animation.source().keyframesRule().keyframes();this._nameElement=parentElement.createChild("div","animation-name");this._nameElement.textContent=this._animation.name();this._svg=parentElement.createSVGChild("svg","animation-ui");this._svg.setAttribute("height",WebInspector.AnimationUI.Options.AnimationSVGHeight);this._svg.style.marginLeft="-"+WebInspector.AnimationUI.Options.AnimationMargin+"px";this._svg.addEventListener("contextmenu",this._onContextMenu.bind(this));this._activeIntervalGroup=this._svg.createSVGChild("g");WebInspector.installDragHandle(this._activeIntervalGroup,this._mouseDown.bind(this,WebInspector.AnimationUI.MouseEvents.AnimationDrag,null),this._mouseMove.bind(this),this._mouseUp.bind(this),"-webkit-grabbing","-webkit-grab");this._cachedElements=[];this._movementInMs=0;this._color=WebInspector.AnimationUI.Color(this._animation);} WebInspector.AnimationUI.MouseEvents={AnimationDrag:"AnimationDrag",KeyframeMove:"KeyframeMove",StartEndpointMove:"StartEndpointMove",FinishEndpointMove:"FinishEndpointMove"} WebInspector.AnimationUI.prototype={animation:function() {return this._animation;},setNode:function(node) {this._node=node;},_createLine:function(parentElement,className) {var line=parentElement.createSVGChild("line",className);line.setAttribute("x1",WebInspector.AnimationUI.Options.AnimationMargin);line.setAttribute("y1",WebInspector.AnimationUI.Options.AnimationHeight);line.setAttribute("y2",WebInspector.AnimationUI.Options.AnimationHeight);line.style.stroke=this._color;return line;},_drawAnimationLine:function(iteration,parentElement) {var cache=this._cachedElements[iteration];if(!cache.animationLine) cache.animationLine=this._createLine(parentElement,"animation-line");cache.animationLine.setAttribute("x2",(this._duration()*this._timeline.pixelMsRatio()+WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2));},_drawDelayLine:function(parentElement) {if(!this._delayLine){this._delayLine=this._createLine(parentElement,"animation-delay-line");this._endDelayLine=this._createLine(parentElement,"animation-delay-line");} var fill=this._animation.source().fill();this._delayLine.classList.toggle("animation-fill",fill==="backwards"||fill==="both");var margin=WebInspector.AnimationUI.Options.AnimationMargin;this._delayLine.setAttribute("x1",margin);this._delayLine.setAttribute("x2",(this._delay()*this._timeline.pixelMsRatio()+margin).toFixed(2));var forwardsFill=fill==="forwards"||fill==="both";this._endDelayLine.classList.toggle("animation-fill",forwardsFill);var leftMargin=Math.min(this._timeline.width(),(this._delay()+this._duration()*this._animation.source().iterations())*this._timeline.pixelMsRatio());this._endDelayLine.style.transform="translateX("+leftMargin.toFixed(2)+"px)";this._endDelayLine.setAttribute("x1",margin);this._endDelayLine.setAttribute("x2",forwardsFill?(this._timeline.width()-leftMargin+margin).toFixed(2):(this._animation.source().endDelay()*this._timeline.pixelMsRatio()+margin).toFixed(2));},_drawPoint:function(iteration,parentElement,x,keyframeIndex,attachEvents) {if(this._cachedElements[iteration].keyframePoints[keyframeIndex]){this._cachedElements[iteration].keyframePoints[keyframeIndex].setAttribute("cx",x.toFixed(2));return;} var circle=parentElement.createSVGChild("circle",keyframeIndex<=0?"animation-endpoint":"animation-keyframe-point");circle.setAttribute("cx",x.toFixed(2));circle.setAttribute("cy",WebInspector.AnimationUI.Options.AnimationHeight);circle.style.stroke=this._color;circle.setAttribute("r",WebInspector.AnimationUI.Options.AnimationMargin/2);if(keyframeIndex<=0) circle.style.fill=this._color;this._cachedElements[iteration].keyframePoints[keyframeIndex]=circle;if(!attachEvents) return;var eventType;if(keyframeIndex===0) eventType=WebInspector.AnimationUI.MouseEvents.StartEndpointMove;else if(keyframeIndex===-1) eventType=WebInspector.AnimationUI.MouseEvents.FinishEndpointMove;else eventType=WebInspector.AnimationUI.MouseEvents.KeyframeMove;WebInspector.installDragHandle(circle,this._mouseDown.bind(this,eventType,keyframeIndex),this._mouseMove.bind(this),this._mouseUp.bind(this),"ew-resize");},_renderKeyframe:function(iteration,keyframeIndex,parentElement,leftDistance,width,easing) {function createStepLine(parentElement,x,strokeColor) {var line=parentElement.createSVGChild("line");line.setAttribute("x1",x);line.setAttribute("x2",x);line.setAttribute("y1",WebInspector.AnimationUI.Options.AnimationMargin);line.setAttribute("y2",WebInspector.AnimationUI.Options.AnimationHeight);line.style.stroke=strokeColor;} var bezier=WebInspector.Geometry.CubicBezier.parse(easing);var cache=this._cachedElements[iteration].keyframeRender;if(!cache[keyframeIndex]) cache[keyframeIndex]=bezier?parentElement.createSVGChild("path","animation-keyframe"):parentElement.createSVGChild("g","animation-keyframe-step");var group=cache[keyframeIndex];group.style.transform="translateX("+leftDistance.toFixed(2)+"px)";if(easing==="linear"){group.style.fill=this._color;var height=WebInspector.BezierUI.Height;group.setAttribute("d",["M",0,height,"L",0,5,"L",width.toFixed(2),5,"L",width.toFixed(2),height,"Z"].join(" "));}else if(bezier){group.style.fill=this._color;WebInspector.BezierUI.drawVelocityChart(bezier,group,width);}else{var stepFunction=WebInspector.AnimationTimeline.StepTimingFunction.parse(easing);group.removeChildren();var offsetMap={"start":0,"middle":0.5,"end":1};var offsetWeight=offsetMap[stepFunction.stepAtPosition];for(var i=0;i<stepFunction.steps;i++) createStepLine(group,(i+offsetWeight)*width/stepFunction.steps,this._color);}},redraw:function() {var durationWithDelay=this._delay()+this._duration()*this._animation.source().iterations()+this._animation.source().endDelay();var maxWidth=this._timeline.width()-WebInspector.AnimationUI.Options.AnimationMargin;this._svg.setAttribute("width",(maxWidth+2*WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2));this._activeIntervalGroup.style.transform="translateX("+(this._delay()*this._timeline.pixelMsRatio()).toFixed(2)+"px)";this._nameElement.style.transform="translateX("+(this._delay()*this._timeline.pixelMsRatio()+WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2)+"px)";this._nameElement.style.width=(this._duration()*this._timeline.pixelMsRatio()).toFixed(2)+"px";this._drawDelayLine(this._svg);if(this._animation.type()==="CSSTransition"){this._renderTransition();return;} this._renderIteration(this._activeIntervalGroup,0);if(!this._tailGroup) this._tailGroup=this._activeIntervalGroup.createSVGChild("g","animation-tail-iterations");var iterationWidth=this._duration()*this._timeline.pixelMsRatio();for(var iteration=1;iteration<this._animation.source().iterations()&&iterationWidth*(iteration-1)<this._timeline.width();iteration++) this._renderIteration(this._tailGroup,iteration);while(iteration<this._cachedElements.length) this._cachedElements.pop().group.remove();},_renderTransition:function() {if(!this._cachedElements[0]) this._cachedElements[0]={animationLine:null,keyframePoints:{},keyframeRender:{},group:null};this._drawAnimationLine(0,this._activeIntervalGroup);this._renderKeyframe(0,0,this._activeIntervalGroup,WebInspector.AnimationUI.Options.AnimationMargin,this._duration()*this._timeline.pixelMsRatio(),this._animation.source().easing());this._drawPoint(0,this._activeIntervalGroup,WebInspector.AnimationUI.Options.AnimationMargin,0,true);this._drawPoint(0,this._activeIntervalGroup,this._duration()*this._timeline.pixelMsRatio()+WebInspector.AnimationUI.Options.AnimationMargin,-1,true);},_renderIteration:function(parentElement,iteration) {if(!this._cachedElements[iteration]) this._cachedElements[iteration]={animationLine:null,keyframePoints:{},keyframeRender:{},group:parentElement.createSVGChild("g")};var group=this._cachedElements[iteration].group;group.style.transform="translateX("+(iteration*this._duration()*this._timeline.pixelMsRatio()).toFixed(2)+"px)";this._drawAnimationLine(iteration,group);console.assert(this._keyframes.length>1);for(var i=0;i<this._keyframes.length-1;i++){var leftDistance=this._offset(i)*this._duration()*this._timeline.pixelMsRatio()+WebInspector.AnimationUI.Options.AnimationMargin;var width=this._duration()*(this._offset(i+1)-this._offset(i))*this._timeline.pixelMsRatio();this._renderKeyframe(iteration,i,group,leftDistance,width,this._keyframes[i].easing());if(i||(!i&&iteration===0)) this._drawPoint(iteration,group,leftDistance,i,iteration===0);} this._drawPoint(iteration,group,this._duration()*this._timeline.pixelMsRatio()+WebInspector.AnimationUI.Options.AnimationMargin,-1,iteration===0);},_delay:function() {var delay=this._animation.source().delay();if(this._mouseEventType===WebInspector.AnimationUI.MouseEvents.AnimationDrag||this._mouseEventType===WebInspector.AnimationUI.MouseEvents.StartEndpointMove) delay+=this._movementInMs;return Math.max(0,delay);},_duration:function() {var duration=this._animation.source().duration();if(this._mouseEventType===WebInspector.AnimationUI.MouseEvents.FinishEndpointMove) duration+=this._movementInMs;else if(this._mouseEventType===WebInspector.AnimationUI.MouseEvents.StartEndpointMove) duration-=Math.max(this._movementInMs,-this._animation.source().delay());return Math.max(0,duration);},_offset:function(i) {var offset=this._keyframes[i].offsetAsNumber();if(this._mouseEventType===WebInspector.AnimationUI.MouseEvents.KeyframeMove&&i===this._keyframeMoved){console.assert(i>0&&i<this._keyframes.length-1,"First and last keyframe cannot be moved");offset+=this._movementInMs/this._animation.source().duration();offset=Math.max(offset,this._keyframes[i-1].offsetAsNumber());offset=Math.min(offset,this._keyframes[i+1].offsetAsNumber());} return offset;},_mouseDown:function(mouseEventType,keyframeIndex,event) {if(event.buttons==2) return false;if(this._svg.enclosingNodeOrSelfWithClass("animation-node-removed")) return false;this._mouseEventType=mouseEventType;this._keyframeMoved=keyframeIndex;this._downMouseX=event.clientX;event.consume(true);if(this._node) WebInspector.Revealer.reveal(this._node);return true;},_mouseMove:function(event) {this._movementInMs=(event.clientX-this._downMouseX)/this._timeline.pixelMsRatio();if(this._delay()+this._duration()>this._timeline.duration()*0.8) this._timeline.setDuration(this._timeline.duration()*1.2);this.redraw();},_mouseUp:function(event) {this._movementInMs=(event.clientX-this._downMouseX)/this._timeline.pixelMsRatio();if(this._mouseEventType===WebInspector.AnimationUI.MouseEvents.KeyframeMove) this._keyframes[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));else this._animation.setTiming(this._duration(),this._delay());this._movementInMs=0;this.redraw();delete this._mouseEventType;delete this._downMouseX;delete this._keyframeMoved;},_onContextMenu:function(event) {function showContextMenu(remoteObject) {if(!remoteObject) return;var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems(remoteObject);contextMenu.show();} this._animation.remoteObjectPromise().then(showContextMenu);event.consume(true);}} WebInspector.AnimationUI.Options={AnimationHeight:26,AnimationSVGHeight:50,AnimationMargin:7,EndpointsClickRegionSize:10,GridCanvasHeight:40} WebInspector.AnimationUI.Colors={"Purple":WebInspector.Color.parse("#9C27B0"),"Light Blue":WebInspector.Color.parse("#03A9F4"),"Deep Orange":WebInspector.Color.parse("#FF5722"),"Blue":WebInspector.Color.parse("#5677FC"),"Lime":WebInspector.Color.parse("#CDDC39"),"Blue Grey":WebInspector.Color.parse("#607D8B"),"Pink":WebInspector.Color.parse("#E91E63"),"Green":WebInspector.Color.parse("#0F9D58"),"Brown":WebInspector.Color.parse("#795548"),"Cyan":WebInspector.Color.parse("#00BCD4")} WebInspector.AnimationUI.Color=function(animation) {var names=Object.keys(WebInspector.AnimationUI.Colors);var color=WebInspector.AnimationUI.Colors[names[String.hashCode(animation.name()||animation.id())%names.length]];return color.asString(WebInspector.Color.Format.RGB);};Runtime.cachedResources["animation/animationScreenshotPopover.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\nimg {\n max-height: 300px;\n border-radius: 2px;\n}\n\n.animation-progress {\n position: absolute;\n height: 2px;\n bottom: 0;\n left: 0;\n background: hsl(217, 89%, 61%);\n}\n\n/*# sourceURL=animation/animationScreenshotPopover.css */";Runtime.cachedResources["animation/animationTimeline.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow: hidden;\n}\n\n.animation-node-row {\n width: 100%;\n display: flex;\n border-bottom: 1px dashed hsla(0,0%,94%,1);\n}\n\n.animation-node-description {\n width: 150px;\n padding-left: 8px;\n overflow: hidden;\n position: relative;\n transform-style: preserve-3d;\n border-bottom: 1px solid hsl(0, 0%, 90%);\n margin-bottom: -1px;\n background-color: hsl(0, 0%, 98%);\n display: flex;\n align-items: center;\n flex: 0 0 150px;\n}\n\n.animation-node-description > * {\n flex: 0 0 auto;\n}\n\n.animation-timeline-row {\n height: 32px;\n position: relative;\n}\n\npath.animation-keyframe {\n fill-opacity: 0.2;\n}\n\nsvg.animation-ui g:first-child:hover path.animation-keyframe {\n fill-opacity: 0.4;\n}\n\n.animation-node-selected path.animation-keyframe {\n fill-opacity: 0.4;\n}\n\nline.animation-line {\n stroke-width: 2px;\n stroke-linecap: round;\n fill: none;\n}\n\nline.animation-delay-line {\n stroke-width: 2px;\n stroke-dasharray: 6, 4;\n}\n\nline.animation-delay-line.animation-fill {\n stroke-dasharray: none;\n}\n\ncircle.animation-endpoint, circle.animation-keyframe-point {\n stroke-width: 2px;\n transition: transform 100ms cubic-bezier(0, 0, 0.2, 1);\n transform: scale(1);\n transform-origin: 50% 50%;\n}\n\n.animation-ui circle.animation-endpoint:hover, .animation-ui circle.animation-keyframe-point:hover {\n transform: scale(1.2);\n}\n\ncircle.animation-endpoint:active, circle.animation-keyframe-point:active {\n transform: scale(1);\n}\n\ncircle.animation-keyframe-point {\n fill: white;\n}\n\n.animation-name {\n position: absolute;\n top: 8px;\n color: #333;\n text-align: center;\n margin-left: -8px;\n white-space: nowrap;\n}\n\n.animation-timeline-toolbar-container {\n display: flex;\n border-bottom: 1px solid #ccc;\n flex: 0 0;\n}\n\n.animation-timeline-toolbar {\n display: inline-block;\n}\n\n.animation-timeline-header {\n height: 28px;\n border-bottom: 1px solid #ccc;\n flex-shrink: 0;\n display: flex;\n}\n\n.animation-timeline-header:after {\n content: \"\";\n height: calc(100% - 48px - 28px);\n position: absolute;\n width: 150px;\n left: 0;\n margin-top: 28px;\n background-color: hsl(0, 0%, 98%);\n z-index: 0;\n border-right: 1px solid hsl(0, 0%, 90%);\n}\n\n.animation-controls {\n flex: 0 0 150px;\n position: relative;\n display: flex;\n justify-content: flex-end;\n padding-right: 8px;\n}\n\n.animation-timeline-current-time {flex: 0 0 auto;line-height: 28px;margin-right: 5px;}\n.animation-grid-header {\n flex: 1 0 auto;\n z-index: 1;\n cursor: text;\n}\n\n.animation-timeline-buffer, .animation-timeline-buffer-hint {\n height: 48px;\n flex: 0 0 auto;\n border-bottom: 1px solid #ccc;\n display: flex;\n padding: 0 2px;\n}\n\n.animation-timeline-buffer:empty, .animation-timeline-buffer-hint {\n display: none;\n}\n\n.animation-timeline-buffer:empty ~ .animation-timeline-buffer-hint {\n align-items: center;\n justify-content: center;\n font-size: 14px;\n z-index: 101;\n display: flex;\n}\n\n.animation-time-overlay {\n background-color: black;\n opacity: 0.05;\n position: absolute;\n height: 100%;\n width: 100%;\n z-index: -1;\n}\n\n.animation-timeline-end > .animation-time-overlay {\n visibility: hidden;\n}\n\n.animation-scrubber {\n opacity: 1;\n position: absolute;\n left: 150px;\n height: calc(100% - 103px);\n width: calc(100% - 150px);\n top: 103px;\n border-left: 1px solid hsla(4,90%,58%,1);\n z-index: 1;\n}\n\n.animation-scrubber-line {\n width: 11px;\n background: linear-gradient(to right, transparent 5px, hsla(4,90%,58%,1) 5px, hsla(4,90%,58%,1) 6px, transparent 6px);\n position: absolute;\n top: -28px;\n height: 28px;\n left: -6px;\n padding: 0 5px;\n z-index: 2;\n}\n\n.animation-scrubber-head {\n width: 7px;\n height: 7px;\n transform: rotate(45deg);\n background: red;\n position: absolute;\n left: 2px;\n top: 1px;\n}\n\nsvg.animation-timeline-grid {\n position: absolute;\n left: 140px;\n top: 76px;\n z-index: 0;\n}\n\nrect.animation-timeline-grid-line {\n fill: hsla(0,0%,93%,1);\n}\n\n.animation-timeline-row > svg.animation-ui {\n position: absolute;\n}\n\n.animation-node-timeline {\n flex-grow: 1;\n}\n\n.animation-node-description > div {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n max-height: 100%;\n}\n\n.animation-node-removed {\n -webkit-filter: saturate(0);\n cursor: not-allowed;\n}\n\nsvg.animation-ui g:first-child {\n opacity: 1;\n}\n\n.animation-tail-iterations {\n opacity: 0.5;\n}\n\n.animation-keyframe-step line {\n stroke-width: 2;\n stroke-opacity: 0.3;\n}\n\ntext.animation-timeline-grid-label {\n font-size: 10px;\n fill: #5a5a5a;\n text-anchor: middle;\n}\n\n.animation-timeline-rows, .animation-timeline-rows-hint {\n flex-grow: 1;\n overflow-y: auto;\n z-index: 1;\n overflow-x: hidden;\n}\n\n.animation-timeline-rows-hint {\n display: none;\n}\n\n.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty {\n flex-grow: 0;\n}\n\n.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty ~ .animation-timeline-rows-hint {\n font-size: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 150px;\n padding: 10px;\n}\n\n.toolbar.animation-controls-toolbar {\n flex: 0 0 auto;\n}\n\n.animation-node-row.animation-node-selected {\n background-color: hsla(216, 71%, 53%, 0.08);\n}\n\n.animation-node-selected > .animation-node-description {\n background-color: #EFF4FD;\n}\n\n.animation-timeline-empty-message {\n padding-left: 230px;\n padding-right: 30px;\n text-align: center;\n position: absolute;\n font-size: 20px;\n line-height: 32px;\n align-items: center; justify-content: center;\n width: 100%;\n height: calc(100% - 44px);\n display: flex;\n}\n\n.animation-buffer-preview {\n height: 40px;\n margin: 4px 2px;\n background-color: #F3F3F3;\n border-radius: 2px;\n flex: 1 1;\n padding: 4px;\n max-width: 100px;\n animation: newGroupAnim 200ms;\n position: relative;\n}\n\n.animation-buffer-preview-animation {\n width: 100%;\n height: 100%;\n border-radius: 2px 0 0 2px;\n position: absolute;\n top: 0;\n left: 0;\n background: hsla(219, 100%, 66%, 0.27);\n opacity: 0;\n border-right: 1px solid #A7A7A7;\n cursor: pointer;\n}\n\n.animation-buffer-preview:not(.selected):hover {\n background-color: hsla(217,90%,92%,1);\n}\n\n.animation-buffer-preview.selected {\n background-color: hsl(217, 89%, 61%);\n}\n\n.animation-paused {\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: hsla(0,0%,70%,0.5);\n display: none;\n}\n\n.animation-paused:before, .animation-paused:after {\n content: \"\";\n background: hsl(0, 100%, 100%);\n width: 7px;\n height: 20px;\n border-radius: 2px;\n margin: 2px;\n border: 1px solid #ccc;\n}\n\n.animation-buffer-preview.paused .animation-paused {\n display: flex;\n}\n\n.animation-buffer-preview.selected > svg > line {\n stroke: white !important;\n}\n\n.animation-buffer-preview > svg > line {\n stroke-width: 1px;\n}\n\n@keyframes newGroupAnim {\n from {\n -webkit-clip-path: polygon(0% 0%, 0% 100%, 0% 100%, 0% 0%);\n }\n to {\n -webkit-clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%);\n }\n}\n\n.animation-playback-rate-control {\n margin: 4px 0 4px 2px;\n display: flex;\n width: 120px;\n}\n\n.animation-playback-rate-button:first-child {\n border-radius: 4px 0 0 4px;\n}\n\n.animation-playback-rate-button:last-child {\n border-radius: 0 4px 4px 0;\n}\n\n.animation-playback-rate-button {\n border: 1px solid #ccc;\n display: inline-block;\n margin-right: -1px;\n padding: 1px 4px;\n background: white;\n flex: 1 0 auto;\n text-align: center;\n cursor: pointer;\n}\n\n.animation-playback-rate-button:not(.selected):hover {\n background: hsl(211, 100%, 95%);\n}\n\n.animation-playback-rate-button.selected {\n color: hsl(0, 100%, 100%);\n background-color: hsl(217, 89%, 61%);\n border-color: hsl(217, 89%, 61%);\n z-index: 1;\n}\n\n.animation-playback-rate-button.selected:first-child {\n color: hsl(217, 89%, 61%);\n background-color: hsl(217, 89%, 100%);\n}\n\n.animation-remove-button {\n position: absolute;\n top: -3px;\n right: -3px;\n background: #7B7B7B;\n border-radius: 12px;\n height: 16px;\n width: 16px;\n align-items: center;\n font-size: 10px;\n justify-content: center;\n box-shadow: 0 1px 4px 0 rgb(185, 185, 185);\n z-index: 100;\n display: none;\n cursor: pointer;\n font-weight: 700;\n color: white;\n}\n\n.animation-remove-button:hover {\n background: #585858;\n}\n\n.animation-buffer-preview:hover .animation-remove-button {\n display: flex;\n}\n\n/*# sourceURL=animation/animationTimeline.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.AuditsPanel=function() {WebInspector.PanelWithSidebar.call(this,"audits");this.registerRequiredCSS("ui/panelEnablerView.css");this.registerRequiredCSS("audits/auditsPanel.css");var sidebarTree=new TreeOutline();sidebarTree.element.classList.add("sidebar-tree");this.panelSidebarElement().appendChild(sidebarTree.element);this.setDefaultFocusedElement(sidebarTree.element);this.auditsTreeElement=new WebInspector.SidebarSectionTreeElement("");sidebarTree.appendChild(this.auditsTreeElement);this.auditsTreeElement.listItemElement.classList.add("hidden");this.auditsItemTreeElement=new WebInspector.AuditsSidebarTreeElement(this);this.auditsTreeElement.appendChild(this.auditsItemTreeElement);this.auditResultsTreeElement=new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RESULTS"));sidebarTree.appendChild(this.auditResultsTreeElement);this.auditResultsTreeElement.expand();this._constructCategories();this._auditController=new WebInspector.AuditController(this);this._launcherView=new WebInspector.AuditLauncherView(this._auditController);for(var id in this.categoriesById) this._launcherView.addCategory(this.categoriesById[id]);var extensionCategories=WebInspector.extensionServer.auditCategories();for(var i=0;i<extensionCategories.length;++i){var category=extensionCategories[i];this.addCategory(new WebInspector.AuditExtensionCategory(category.extensionOrigin,category.id,category.displayName,category.ruleCount));} WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.AuditCategoryAdded,this._extensionAuditCategoryAdded,this);} WebInspector.AuditsPanel.prototype={get categoriesById() {return this._auditCategoriesById;},addCategory:function(category) {this.categoriesById[category.id]=category;this._launcherView.addCategory(category);},getCategory:function(id) {return this.categoriesById[id];},_constructCategories:function() {this._auditCategoriesById={};for(var categoryCtorID in WebInspector.AuditCategories){var auditCategory=new WebInspector.AuditCategories[categoryCtorID]();auditCategory._id=categoryCtorID;this.categoriesById[categoryCtorID]=auditCategory;}},auditFinishedCallback:function(mainResourceURL,results) {var ordinal=1;for(var child of this.auditResultsTreeElement.children()){if(child.mainResourceURL===mainResourceURL) ordinal++;} var resultTreeElement=new WebInspector.AuditResultSidebarTreeElement(this,results,mainResourceURL,ordinal);this.auditResultsTreeElement.appendChild(resultTreeElement);resultTreeElement.revealAndSelect();},showResults:function(categoryResults) {if(!categoryResults._resultView) categoryResults._resultView=new WebInspector.AuditResultView(categoryResults);this.visibleView=categoryResults._resultView;},showLauncherView:function() {this.visibleView=this._launcherView;},get visibleView() {return this._visibleView;},set visibleView(x) {if(this._visibleView===x) return;if(this._visibleView) this._visibleView.detach();this._visibleView=x;if(x) this.splitWidget().setMainWidget(x);},wasShown:function() {WebInspector.Panel.prototype.wasShown.call(this);if(!this._visibleView) this.auditsItemTreeElement.select();},clearResults:function() {this.auditsItemTreeElement.revealAndSelect();this.auditResultsTreeElement.removeChildren();},_extensionAuditCategoryAdded:function(event) {var category=(event.data);this.addCategory(new WebInspector.AuditExtensionCategory(category.extensionOrigin,category.id,category.displayName,category.ruleCount));},__proto__:WebInspector.PanelWithSidebar.prototype} WebInspector.AuditCategoryImpl=function(displayName) {this._displayName=displayName;this._rules=[];} WebInspector.AuditCategoryImpl.prototype={get id() {return this._id;},get displayName() {return this._displayName;},addRule:function(rule,severity) {rule.severity=severity;this._rules.push(rule);},run:function(target,requests,ruleResultCallback,progress) {this._ensureInitialized();var remainingRulesCount=this._rules.length;progress.setTotalWork(remainingRulesCount);function callbackWrapper(result) {ruleResultCallback(result);progress.worked();if(!--remainingRulesCount) progress.done();} for(var i=0;i<this._rules.length;++i){if(!progress.isCanceled()) this._rules[i].run(target,requests,callbackWrapper,progress);else callbackWrapper(null);}},_ensureInitialized:function() {if(!this._initialized){if("initialize"in this) this.initialize();this._initialized=true;}}} WebInspector.AuditRule=function(id,displayName) {this._id=id;this._displayName=displayName;} WebInspector.AuditRule.Severity={Info:"info",Warning:"warning",Severe:"severe"} WebInspector.AuditRule.SeverityOrder={"info":3,"warning":2,"severe":1} WebInspector.AuditRule.prototype={get id() {return this._id;},get displayName() {return this._displayName;},set severity(severity) {this._severity=severity;},run:function(target,requests,callback,progress) {if(progress.isCanceled()) return;var result=new WebInspector.AuditRuleResult(this.displayName);result.severity=this._severity;this.doRun(target,requests,result,callback,progress);},doRun:function(target,requests,result,callback,progress) {throw new Error("doRun() not implemented");}} WebInspector.AuditCategoryResult=function(category) {this.title=category.displayName;this.ruleResults=[];} WebInspector.AuditCategoryResult.prototype={addRuleResult:function(ruleResult) {this.ruleResults.push(ruleResult);}} WebInspector.AuditRuleResult=function(value,expanded,className) {this.value=value;this.className=className;this.expanded=expanded;this.violationCount=0;this._formatters={r:WebInspector.AuditRuleResult.linkifyDisplayName};var standardFormatters=Object.keys(String.standardFormatters);for(var i=0;i<standardFormatters.length;++i) this._formatters[standardFormatters[i]]=String.standardFormatters[standardFormatters[i]];} WebInspector.AuditRuleResult.linkifyDisplayName=function(url) {return WebInspector.linkifyURLAsNode(url,WebInspector.displayNameForURL(url));} WebInspector.AuditRuleResult.resourceDomain=function(domain) {return domain||WebInspector.UIString("[empty domain]");} WebInspector.AuditRuleResult.prototype={addChild:function(value,expanded,className) {if(!this.children) this.children=[];var entry=new WebInspector.AuditRuleResult(value,expanded,className);this.children.push(entry);return entry;},addURL:function(url) {this.addChild(WebInspector.AuditRuleResult.linkifyDisplayName(url));},addURLs:function(urls) {for(var i=0;i<urls.length;++i) this.addURL(urls[i]);},addSnippet:function(snippet) {this.addChild(snippet,false,"source-code");},addFormatted:function(format,vararg) {var substitutions=Array.prototype.slice.call(arguments,1);var fragment=createDocumentFragment();function append(a,b) {if(!(b instanceof Node)) b=createTextNode(b);a.appendChild(b);return a;} var formattedResult=String.format(format,substitutions,this._formatters,fragment,append).formattedResult;if(formattedResult instanceof Node) formattedResult.normalize();return this.addChild(formattedResult);}} WebInspector.AuditsSidebarTreeElement=function(panel) {this._panel=panel;this.small=false;WebInspector.SidebarTreeElement.call(this,"audits-sidebar-tree-item",WebInspector.UIString("Audits"));} WebInspector.AuditsSidebarTreeElement.prototype={onattach:function() {WebInspector.SidebarTreeElement.prototype.onattach.call(this);},onselect:function() {this._panel.showLauncherView();return true;},get selectable() {return true;},refresh:function() {this.refreshTitles();},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.AuditResultSidebarTreeElement=function(panel,results,mainResourceURL,ordinal) {this._panel=panel;this.results=results;this.mainResourceURL=mainResourceURL;WebInspector.SidebarTreeElement.call(this,"audit-result-sidebar-tree-item",String.sprintf("%s (%d)",mainResourceURL,ordinal));} WebInspector.AuditResultSidebarTreeElement.prototype={onselect:function() {this._panel.showResults(this.results);return true;},get selectable() {return true;},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.AuditsPanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.AuditsPanel.instance());} WebInspector.AuditsPanel.instance=function() {if(!WebInspector.AuditsPanel._instanceObject) WebInspector.AuditsPanel._instanceObject=new WebInspector.AuditsPanel();return WebInspector.AuditsPanel._instanceObject;} WebInspector.AuditsPanelFactory=function() {} WebInspector.AuditsPanelFactory.prototype={createPanel:function() {return WebInspector.AuditsPanel.instance();}} WebInspector.AuditRules={};WebInspector.AuditCategories={};;WebInspector.AuditCategory=function() {} WebInspector.AuditCategory.prototype={get id() {},get displayName() {},run:function(target,requests,ruleResultCallback,progress) {}};WebInspector.AuditCategories.PagePerformance=function(){WebInspector.AuditCategoryImpl.call(this,WebInspector.AuditCategories.PagePerformance.AuditCategoryName);} WebInspector.AuditCategories.PagePerformance.AuditCategoryName=WebInspector.UIString("Web Page Performance");WebInspector.AuditCategories.PagePerformance.prototype={initialize:function() {this.addRule(new WebInspector.AuditRules.UnusedCssRule(),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CssInHeadRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.StylesScriptsOrderRule(),WebInspector.AuditRule.Severity.Severe);},__proto__:WebInspector.AuditCategoryImpl.prototype} WebInspector.AuditCategories.NetworkUtilization=function(){WebInspector.AuditCategoryImpl.call(this,WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);} WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName=WebInspector.UIString("Network Utilization");WebInspector.AuditCategories.NetworkUtilization.prototype={initialize:function() {this.addRule(new WebInspector.AuditRules.GzipRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.ImageDimensionsRule(),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CookieSizeRule(400),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.StaticCookielessRule(5),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CombineJsResourcesRule(2),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.CombineCssResourcesRule(2),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.MinimizeDnsLookupsRule(4),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.ParallelizeDownloadRule(4,10,0.5),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.BrowserCacheControlRule(),WebInspector.AuditRule.Severity.Severe);},__proto__:WebInspector.AuditCategoryImpl.prototype};WebInspector.AuditController=function(auditsPanel) {this._auditsPanel=auditsPanel;WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.Load,this._didMainResourceLoad,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._didLoadResource,this);} WebInspector.AuditController.prototype={_executeAudit:function(target,categories,resultCallback) {this._progress.setTitle(WebInspector.UIString("Running audit"));function ruleResultReadyCallback(categoryResult,ruleResult) {if(ruleResult&&ruleResult.children) categoryResult.addRuleResult(ruleResult);} var results=[];var mainResourceURL=target.resourceTreeModel.inspectedPageURL();var categoriesDone=0;function categoryDoneCallback() {if(++categoriesDone!==categories.length) return;resultCallback(mainResourceURL,results);} var requests=target.networkLog.requests().slice();var compositeProgress=new WebInspector.CompositeProgress(this._progress);var subprogresses=[];for(var i=0;i<categories.length;++i) subprogresses.push(new WebInspector.ProgressProxy(compositeProgress.createSubProgress(),categoryDoneCallback));for(var i=0;i<categories.length;++i){if(this._progress.isCanceled()){subprogresses[i].done();continue;} var category=categories[i];var result=new WebInspector.AuditCategoryResult(category);results.push(result);category.run(target,requests,ruleResultReadyCallback.bind(null,result),subprogresses[i]);}},_auditFinishedCallback:function(mainResourceURL,results) {if(!this._progress.isCanceled()) this._auditsPanel.auditFinishedCallback(mainResourceURL,results);this._progress.done();},initiateAudit:function(categoryIds,progress,runImmediately,startedCallback) {var target=WebInspector.targetManager.mainTarget();if(!categoryIds||!categoryIds.length||!target) return;this._progress=progress;var categories=[];for(var i=0;i<categoryIds.length;++i) categories.push(this._auditsPanel.categoriesById[categoryIds[i]]);if(runImmediately) this._startAuditWhenResourcesReady(target,categories,startedCallback);else this._reloadResources(this._startAuditWhenResourcesReady.bind(this,target,categories,startedCallback));WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.AuditsStarted);},_startAuditWhenResourcesReady:function(target,categories,startedCallback) {if(this._progress.isCanceled()){this._progress.done();return;} startedCallback();this._executeAudit(target,categories,this._auditFinishedCallback.bind(this));},_reloadResources:function(callback) {this._pageReloadCallback=callback;WebInspector.targetManager.reloadPage();},_didLoadResource:function() {if(this._pageReloadCallback&&this._progress&&this._progress.isCanceled()) this._pageReloadCallback();},_didMainResourceLoad:function() {if(this._pageReloadCallback){var callback=this._pageReloadCallback;delete this._pageReloadCallback;callback();}},clearResults:function() {this._auditsPanel.clearResults();}};WebInspector.AuditFormatters=function() {} WebInspector.AuditFormatters.Registry={text:function(text) {return createTextNode(text);},snippet:function(snippetText) {var div=createElement("div");div.textContent=snippetText;div.className="source-code";return div;},concat:function() {var parent=createElement("span");for(var arg=0;arg<arguments.length;++arg) parent.appendChild(WebInspector.auditFormatters.apply(arguments[arg]));return parent;},url:function(url,displayText) {return WebInspector.linkifyURLAsNode(url,displayText,undefined,true);},resourceLink:function(url,line) {return WebInspector.linkifyResourceAsNode(url,line,undefined,"resource-url webkit-html-resource-link");}};WebInspector.AuditFormatters.prototype={apply:function(value) {var formatter;var type=typeof value;var args;switch(type){case"string":case"boolean":case"number":formatter=WebInspector.AuditFormatters.Registry.text;args=[value.toString()];break;case"object":if(value instanceof Node) return value;if(Array.isArray(value)){formatter=WebInspector.AuditFormatters.Registry.concat;args=value;}else if(value.type&&value.arguments){formatter=WebInspector.AuditFormatters.Registry[value.type];args=value.arguments;}} if(!formatter) throw"Invalid value or formatter: "+type+JSON.stringify(value);return formatter.apply(null,args);},partiallyApply:function(formatters,thisArgument,value) {if(Array.isArray(value)) return value.map(this.partiallyApply.bind(this,formatters,thisArgument));if(typeof value==="object"&&typeof formatters[value.type]==="function"&&value.arguments) return formatters[value.type].apply(thisArgument,value.arguments);return value;}} WebInspector.auditFormatters=new WebInspector.AuditFormatters();;WebInspector.AuditLauncherView=function(auditController) {WebInspector.VBox.call(this);this.setMinimumSize(100,25);this._auditController=auditController;this._categoryIdPrefix="audit-category-item-";this._auditRunning=false;this.element.classList.add("audit-launcher-view");this.element.classList.add("panel-enabler-view");this._contentElement=createElement("div");this._contentElement.className="audit-launcher-view-content";this.element.appendChild(this._contentElement);this._boundCategoryClickListener=this._categoryClicked.bind(this);this._resetResourceCount();this._sortedCategories=[];this._headerElement=createElement("h1");this._headerElement.className="no-audits";this._headerElement.textContent=WebInspector.UIString("No audits to run");this._contentElement.appendChild(this._headerElement);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestStarted,this._onRequestStarted,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);var defaultSelectedAuditCategory={};defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey]=true;this._selectedCategoriesSetting=WebInspector.settings.createSetting("selectedAuditCategories",defaultSelectedAuditCategory);} WebInspector.AuditLauncherView.AllCategoriesKey="__AllCategories";WebInspector.AuditLauncherView.prototype={_resetResourceCount:function() {this._loadedResources=0;this._totalResources=0;},_onRequestStarted:function(event) {var request=(event.data);if(request.resourceType()===WebInspector.resourceTypes.WebSocket) return;++this._totalResources;this._updateResourceProgress();},_onRequestFinished:function(event) {var request=(event.data);if(request.resourceType()===WebInspector.resourceTypes.WebSocket) return;++this._loadedResources;this._updateResourceProgress();},addCategory:function(category) {if(!this._sortedCategories.length) this._createLauncherUI();var selectedCategories=this._selectedCategoriesSetting.get();var categoryElement=this._createCategoryElement(category.displayName,category.id);category._checkboxElement=categoryElement.checkboxElement;if(this._selectAllCheckboxElement.checked||selectedCategories[category.displayName]){category._checkboxElement.checked=true;++this._currentCategoriesCount;} function compareCategories(a,b) {var aTitle=a.displayName||"";var bTitle=b.displayName||"";return aTitle.localeCompare(bTitle);} var insertBefore=this._sortedCategories.lowerBound(category,compareCategories);this._categoriesElement.insertBefore(categoryElement,this._categoriesElement.children[insertBefore]);this._sortedCategories.splice(insertBefore,0,category);this._selectedCategoriesUpdated();},_startAudit:function() {this._auditRunning=true;this._updateButton();this._toggleUIComponents(this._auditRunning);var catIds=[];for(var category=0;category<this._sortedCategories.length;++category){if(this._sortedCategories[category]._checkboxElement.checked) catIds.push(this._sortedCategories[category].id);} this._resetResourceCount();this._progressIndicator=new WebInspector.ProgressIndicator();this._buttonContainerElement.appendChild(this._progressIndicator.element);this._displayResourceLoadingProgress=true;function onAuditStarted() {this._displayResourceLoadingProgress=false;} this._auditController.initiateAudit(catIds,new WebInspector.ProgressProxy(this._progressIndicator,this._auditsDone.bind(this)),this._auditPresentStateElement.checked,onAuditStarted.bind(this));},_auditsDone:function() {this._displayResourceLoadingProgress=false;delete this._progressIndicator;this._launchButton.disabled=false;this._auditRunning=false;this._updateButton();this._toggleUIComponents(this._auditRunning);},_toggleUIComponents:function(disable) {this._selectAllCheckboxElement.disabled=disable;for(var child=this._categoriesElement.firstChild;child;child=child.nextSibling) child.checkboxElement.disabled=disable;this._auditPresentStateElement.disabled=disable;this._auditReloadedStateElement.disabled=disable;},_launchButtonClicked:function(event) {if(this._auditRunning){this._launchButton.disabled=true;this._progressIndicator.cancel();return;} this._startAudit();},_clearButtonClicked:function() {this._auditController.clearResults();},_selectAllClicked:function(checkCategories,userGesture) {var childNodes=this._categoriesElement.childNodes;for(var i=0,length=childNodes.length;i<length;++i) childNodes[i].checkboxElement.checked=checkCategories;this._currentCategoriesCount=checkCategories?this._sortedCategories.length:0;this._selectedCategoriesUpdated(userGesture);},_categoryClicked:function(event) {this._currentCategoriesCount+=event.target.checked?1:-1;this._selectAllCheckboxElement.checked=this._currentCategoriesCount===this._sortedCategories.length;this._selectedCategoriesUpdated(true);},_createCategoryElement:function(title,id) {var labelElement=createCheckboxLabel(title);if(id){labelElement.id=this._categoryIdPrefix+id;labelElement.checkboxElement.addEventListener("click",this._boundCategoryClickListener,false);} labelElement.__displayName=title;return labelElement;},_createLauncherUI:function() {this._headerElement=createElement("h1");this._headerElement.textContent=WebInspector.UIString("Select audits to run");this._contentElement.removeChildren();this._contentElement.appendChild(this._headerElement);function handleSelectAllClick(event) {this._selectAllClicked(event.target.checked,true);} var categoryElement=this._createCategoryElement(WebInspector.UIString("Select All"),"");categoryElement.id="audit-launcher-selectall";this._selectAllCheckboxElement=categoryElement.checkboxElement;this._selectAllCheckboxElement.checked=this._selectedCategoriesSetting.get()[WebInspector.AuditLauncherView.AllCategoriesKey];this._selectAllCheckboxElement.addEventListener("click",handleSelectAllClick.bind(this),false);this._contentElement.appendChild(categoryElement);this._categoriesElement=this._contentElement.createChild("fieldset","audit-categories-container");this._currentCategoriesCount=0;this._contentElement.createChild("div","flexible-space");this._buttonContainerElement=this._contentElement.createChild("div","button-container");var radio=createRadioLabel("audit-mode",WebInspector.UIString("Audit Present State"),true);this._buttonContainerElement.appendChild(radio);this._auditPresentStateElement=radio.radioElement;radio=createRadioLabel("audit-mode",WebInspector.UIString("Reload Page and Audit on Load"));this._buttonContainerElement.appendChild(radio);this._auditReloadedStateElement=radio.radioElement;this._launchButton=createTextButton(WebInspector.UIString("Run"),this._launchButtonClicked.bind(this));this._buttonContainerElement.appendChild(this._launchButton);this._clearButton=createTextButton(WebInspector.UIString("Clear"),this._clearButtonClicked.bind(this));this._buttonContainerElement.appendChild(this._clearButton);this._selectAllClicked(this._selectAllCheckboxElement.checked);},_updateResourceProgress:function() {if(this._displayResourceLoadingProgress) this._progressIndicator.setTitle(WebInspector.UIString("Loading (%d of %d)",this._loadedResources,this._totalResources));},_selectedCategoriesUpdated:function(userGesture) {var selectedCategories=userGesture?{}:this._selectedCategoriesSetting.get();var childNodes=this._categoriesElement.childNodes;for(var i=0,length=childNodes.length;i<length;++i) selectedCategories[childNodes[i].__displayName]=childNodes[i].checkboxElement.checked;selectedCategories[WebInspector.AuditLauncherView.AllCategoriesKey]=this._selectAllCheckboxElement.checked;this._selectedCategoriesSetting.set(selectedCategories);this._updateButton();},_updateButton:function() {this._launchButton.textContent=this._auditRunning?WebInspector.UIString("Stop"):WebInspector.UIString("Run");this._launchButton.disabled=!this._currentCategoriesCount;},__proto__:WebInspector.VBox.prototype};WebInspector.AuditResultView=function(categoryResults) {WebInspector.SidebarPaneStack.call(this);this.setMinimumSize(100,25);this.element.classList.add("audit-result-view");function categorySorter(a,b){return(a.title||"").localeCompare(b.title||"");} categoryResults.sort(categorySorter);for(var i=0;i<categoryResults.length;++i) this.addPane(new WebInspector.AuditCategoryResultPane(categoryResults[i]));} WebInspector.AuditResultView.prototype={__proto__:WebInspector.SidebarPaneStack.prototype} WebInspector.AuditCategoryResultPane=function(categoryResult) {WebInspector.SidebarPane.call(this,categoryResult.title);this._treeOutline=new TreeOutlineInShadow();this._treeOutline.registerRequiredCSS("audits/auditResultTree.css");this._treeOutline.element.classList.add("audit-result-tree");this.element.appendChild(this._treeOutline.element);this._treeOutline.expandTreeElementsWhenArrowing=true;function ruleSorter(a,b) {var result=WebInspector.AuditRule.SeverityOrder[a.severity||0]-WebInspector.AuditRule.SeverityOrder[b.severity||0];if(!result) result=(a.value||"").localeCompare(b.value||"");return result;} categoryResult.ruleResults.sort(ruleSorter);for(var i=0;i<categoryResult.ruleResults.length;++i){var ruleResult=categoryResult.ruleResults[i];var treeElement=this._appendResult(this._treeOutline.rootElement(),ruleResult,ruleResult.severity);treeElement.listItemElement.classList.add("audit-result");} this.expand();} WebInspector.AuditCategoryResultPane.prototype={_appendResult:function(parentTreeNode,result,severity) {var title="";if(typeof result.value==="string"){title=result.value;if(result.violationCount) title=String.sprintf("%s (%d)",title,result.violationCount);} var titleFragment=createDocumentFragment();if(severity){var severityElement=createElement("div");severityElement.classList.add("severity",severity);titleFragment.appendChild(severityElement);} titleFragment.createTextChild(title);var treeElement=new TreeElement(titleFragment,!!result.children);treeElement.selectable=false;parentTreeNode.appendChild(treeElement);if(result.className) treeElement.listItemElement.classList.add(result.className);if(typeof result.value!=="string") treeElement.listItemElement.appendChild(WebInspector.auditFormatters.apply(result.value));if(result.children){for(var i=0;i<result.children.length;++i) this._appendResult(treeElement,result.children[i]);} if(result.expanded){treeElement.listItemElement.classList.remove("parent");treeElement.listItemElement.classList.add("parent-expanded");treeElement.expand();} return treeElement;},__proto__:WebInspector.SidebarPane.prototype};WebInspector.AuditRules.IPAddressRegexp=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;WebInspector.AuditRules.CacheableResponseCodes={200:true,203:true,206:true,300:true,301:true,410:true,304:true} WebInspector.AuditRules.getDomainToResourcesMap=function(requests,types,needFullResources) {var domainToResourcesMap={};for(var i=0,size=requests.length;i<size;++i){var request=requests[i];if(types&&types.indexOf(request.resourceType())===-1) continue;var parsedURL=request.url.asParsedURL();if(!parsedURL) continue;var domain=parsedURL.host;var domainResources=domainToResourcesMap[domain];if(domainResources===undefined){domainResources=[];domainToResourcesMap[domain]=domainResources;} domainResources.push(needFullResources?request:request.url);} return domainToResourcesMap;} WebInspector.AuditRules.GzipRule=function() {WebInspector.AuditRule.call(this,"network-gzip",WebInspector.UIString("Enable gzip compression"));} WebInspector.AuditRules.GzipRule.prototype={doRun:function(target,requests,result,callback,progress) {var totalSavings=0;var compressedSize=0;var candidateSize=0;var summary=result.addChild("",true);for(var i=0,length=requests.length;i<length;++i){var request=requests[i];if(request.cached()||request.statusCode===304) continue;if(this._shouldCompress(request)){var size=request.resourceSize;candidateSize+=size;if(this._isCompressed(request)){compressedSize+=size;continue;} var savings=2*size/3;totalSavings+=savings;summary.addFormatted("%r could save ~%s",request.url,Number.bytesToString(savings));result.violationCount++;}} if(!totalSavings){callback(null);return;} summary.value=WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):",Number.bytesToString(totalSavings));callback(result);},_isCompressed:function(request) {var encodingHeader=request.responseHeaderValue("Content-Encoding");if(!encodingHeader) return false;return/\b(?:gzip|deflate)\b/.test(encodingHeader);},_shouldCompress:function(request) {return request.resourceType().isTextType()&&request.parsedURL.host&&request.resourceSize!==undefined&&request.resourceSize>150;},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CombineExternalResourcesRule=function(id,name,type,resourceTypeName,allowedPerDomain) {WebInspector.AuditRule.call(this,id,name);this._type=type;this._resourceTypeName=resourceTypeName;this._allowedPerDomain=allowedPerDomain;} WebInspector.AuditRules.CombineExternalResourcesRule.prototype={doRun:function(target,requests,result,callback,progress) {var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,[this._type],false);var penalizedResourceCount=0;var summary=result.addChild("",true);for(var domain in domainToResourcesMap){var domainResources=domainToResourcesMap[domain];var extraResourceCount=domainResources.length-this._allowedPerDomain;if(extraResourceCount<=0) continue;penalizedResourceCount+=extraResourceCount-1;summary.addChild(WebInspector.UIString("%d %s resources served from %s.",domainResources.length,this._resourceTypeName,WebInspector.AuditRuleResult.resourceDomain(domain)));result.violationCount+=domainResources.length;} if(!penalizedResourceCount){callback(null);return;} summary.value=WebInspector.UIString("There are multiple resources served from same domain. Consider combining them into as few files as possible.");callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CombineJsResourcesRule=function(allowedPerDomain){WebInspector.AuditRules.CombineExternalResourcesRule.call(this,"page-externaljs",WebInspector.UIString("Combine external JavaScript"),WebInspector.resourceTypes.Script,"JavaScript",allowedPerDomain);} WebInspector.AuditRules.CombineJsResourcesRule.prototype={__proto__:WebInspector.AuditRules.CombineExternalResourcesRule.prototype} WebInspector.AuditRules.CombineCssResourcesRule=function(allowedPerDomain){WebInspector.AuditRules.CombineExternalResourcesRule.call(this,"page-externalcss",WebInspector.UIString("Combine external CSS"),WebInspector.resourceTypes.Stylesheet,"CSS",allowedPerDomain);} WebInspector.AuditRules.CombineCssResourcesRule.prototype={__proto__:WebInspector.AuditRules.CombineExternalResourcesRule.prototype} WebInspector.AuditRules.MinimizeDnsLookupsRule=function(hostCountThreshold){WebInspector.AuditRule.call(this,"network-minimizelookups",WebInspector.UIString("Minimize DNS lookups"));this._hostCountThreshold=hostCountThreshold;} WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype={doRun:function(target,requests,result,callback,progress) {var summary=result.addChild("");var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,null,false);for(var domain in domainToResourcesMap){if(domainToResourcesMap[domain].length>1) continue;var parsedURL=domain.asParsedURL();if(!parsedURL) continue;if(!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp)) continue;summary.addSnippet(domain);result.violationCount++;} if(!summary.children||summary.children.length<=this._hostCountThreshold){callback(null);return;} summary.value=WebInspector.UIString("The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.");callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.ParallelizeDownloadRule=function(optimalHostnameCount,minRequestThreshold,minBalanceThreshold) {WebInspector.AuditRule.call(this,"network-parallelizehosts",WebInspector.UIString("Parallelize downloads across hostnames"));this._optimalHostnameCount=optimalHostnameCount;this._minRequestThreshold=minRequestThreshold;this._minBalanceThreshold=minBalanceThreshold;} WebInspector.AuditRules.ParallelizeDownloadRule.prototype={doRun:function(target,requests,result,callback,progress) {function hostSorter(a,b) {var aCount=domainToResourcesMap[a].length;var bCount=domainToResourcesMap[b].length;return(aCount<bCount)?1:(aCount===bCount)?0:-1;} var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,[WebInspector.resourceTypes.Stylesheet,WebInspector.resourceTypes.Image],true);var hosts=[];for(var url in domainToResourcesMap) hosts.push(url);if(!hosts.length){callback(null);return;} hosts.sort(hostSorter);var optimalHostnameCount=this._optimalHostnameCount;if(hosts.length>optimalHostnameCount) hosts.splice(optimalHostnameCount);var busiestHostResourceCount=domainToResourcesMap[hosts[0]].length;var requestCountAboveThreshold=busiestHostResourceCount-this._minRequestThreshold;if(requestCountAboveThreshold<=0){callback(null);return;} var avgResourcesPerHost=0;for(var i=0,size=hosts.length;i<size;++i) avgResourcesPerHost+=domainToResourcesMap[hosts[i]].length;avgResourcesPerHost/=optimalHostnameCount;avgResourcesPerHost=Math.max(avgResourcesPerHost,1);var pctAboveAvg=(requestCountAboveThreshold/avgResourcesPerHost)-1.0;var minBalanceThreshold=this._minBalanceThreshold;if(pctAboveAvg<minBalanceThreshold){callback(null);return;} var requestsOnBusiestHost=domainToResourcesMap[hosts[0]];var entry=result.addChild(WebInspector.UIString("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.",busiestHostResourceCount,hosts[0]),true);for(var i=0;i<requestsOnBusiestHost.length;++i) entry.addURL(requestsOnBusiestHost[i].url);result.violationCount=requestsOnBusiestHost.length;callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.UnusedCssRule=function() {WebInspector.AuditRule.call(this,"page-unusedcss",WebInspector.UIString("Remove unused CSS rules"));} WebInspector.AuditRules.UnusedCssRule.prototype={doRun:function(target,requests,result,callback,progress) {var domModel=WebInspector.DOMModel.fromTarget(target);var cssModel=WebInspector.CSSModel.fromTarget(target);if(!domModel||!cssModel){callback(null);return;} function evalCallback(styleSheets){if(!styleSheets.length) return callback(null);var selectors=[];var testedSelectors={};for(var i=0;i<styleSheets.length;++i){var styleSheet=styleSheets[i];for(var curRule=0;curRule<styleSheet.rules.length;++curRule){var selectorText=styleSheet.rules[curRule].selectorText;if(testedSelectors[selectorText]) continue;selectors.push(selectorText);testedSelectors[selectorText]=1;}} var foundSelectors={};function selectorsCallback(styleSheets) {if(progress.isCanceled()){callback(null);return;} var inlineBlockOrdinal=0;var totalStylesheetSize=0;var totalUnusedStylesheetSize=0;var summary;for(var i=0;i<styleSheets.length;++i){var styleSheet=styleSheets[i];var unusedRules=[];for(var curRule=0;curRule<styleSheet.rules.length;++curRule){var rule=styleSheet.rules[curRule];if(!testedSelectors[rule.selectorText]||foundSelectors[rule.selectorText]) continue;unusedRules.push(rule.selectorText);} totalStylesheetSize+=styleSheet.rules.length;totalUnusedStylesheetSize+=unusedRules.length;if(!unusedRules.length) continue;var resource=WebInspector.resourceForURL(styleSheet.sourceURL);var isInlineBlock=resource&&resource.request&&resource.request.resourceType()===WebInspector.resourceTypes.Document;var url=!isInlineBlock?WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL):WebInspector.UIString("Inline block #%d",++inlineBlockOrdinal);var pctUnused=Math.round(100*unusedRules.length/styleSheet.rules.length);if(!summary) summary=result.addChild("",true);var entry=summary.addFormatted("%s: %d% is not used by the current page.",url,pctUnused);for(var j=0;j<unusedRules.length;++j) entry.addSnippet(unusedRules[j]);result.violationCount+=unusedRules.length;} if(!totalUnusedStylesheetSize) return callback(null);var totalUnusedPercent=Math.round(100*totalUnusedStylesheetSize/totalStylesheetSize);summary.value=WebInspector.UIString("%s rules (%d%) of CSS not used by the current page.",totalUnusedStylesheetSize,totalUnusedPercent);callback(result);} function queryCallback(boundSelectorsCallback,selector,nodeId) {if(nodeId) foundSelectors[selector]=true;if(boundSelectorsCallback) boundSelectorsCallback();} function documentLoaded(selectors,document){var pseudoSelectorRegexp=/::?(?:[\w-]+)(?:\(.*?\))?/g;if(!selectors.length){selectorsCallback([]);return;} for(var i=0;i<selectors.length;++i){if(progress.isCanceled()){callback(null);return;} var effectiveSelector=selectors[i].replace(pseudoSelectorRegexp,"");domModel.querySelector(document.id,effectiveSelector,queryCallback.bind(null,i===selectors.length-1?selectorsCallback.bind(null,styleSheets):null,selectors[i]));}} domModel.requestDocument(documentLoaded.bind(null,selectors));} var styleSheetInfos=cssModel.allStyleSheets();if(!styleSheetInfos||!styleSheetInfos.length){evalCallback([]);return;} var styleSheetProcessor=new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos,progress,evalCallback);styleSheetProcessor.run();},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.ParsedStyleSheet;WebInspector.AuditRules.StyleSheetProcessor=function(styleSheetHeaders,progress,styleSheetsParsedCallback) {this._styleSheetHeaders=styleSheetHeaders;this._progress=progress;this._styleSheets=[];this._styleSheetsParsedCallback=styleSheetsParsedCallback;} WebInspector.AuditRules.StyleSheetProcessor.prototype={run:function() {this._parser=new WebInspector.CSSParser();this._processNextStyleSheet();},_terminateWorker:function() {if(this._parser){this._parser.dispose();delete this._parser;}},_finish:function() {this._terminateWorker();this._styleSheetsParsedCallback(this._styleSheets);},_processNextStyleSheet:function() {if(!this._styleSheetHeaders.length){this._finish();return;} this._currentStyleSheetHeader=this._styleSheetHeaders.shift();this._parser.fetchAndParse(this._currentStyleSheetHeader,this._onStyleSheetParsed.bind(this));},_onStyleSheetParsed:function(rules) {if(this._progress.isCanceled()){this._finish();return;} var styleRules=[];for(var i=0;i<rules.length;++i){var rule=rules[i];if(rule.selectorText) styleRules.push(rule);} this._styleSheets.push({sourceURL:this._currentStyleSheetHeader.sourceURL,rules:styleRules});this._processNextStyleSheet();},} WebInspector.AuditRules.CacheControlRule=function(id,name) {WebInspector.AuditRule.call(this,id,name);} WebInspector.AuditRules.CacheControlRule.MillisPerMonth=1000*60*60*24*30;WebInspector.AuditRules.CacheControlRule.prototype={doRun:function(target,requests,result,callback,progress) {var cacheableAndNonCacheableResources=this._cacheableAndNonCacheableResources(requests);if(cacheableAndNonCacheableResources[0].length) this.runChecks(cacheableAndNonCacheableResources[0],result);this.handleNonCacheableResources(cacheableAndNonCacheableResources[1],result);callback(result);},handleNonCacheableResources:function(requests,result) {},_cacheableAndNonCacheableResources:function(requests) {var processedResources=[[],[]];for(var i=0;i<requests.length;++i){var request=requests[i];if(!this.isCacheableResource(request)) continue;if(this._isExplicitlyNonCacheable(request)) processedResources[1].push(request);else processedResources[0].push(request);} return processedResources;},execCheck:function(messageText,requestCheckFunction,requests,result) {var requestCount=requests.length;var urls=[];for(var i=0;i<requestCount;++i){if(requestCheckFunction.call(this,requests[i])) urls.push(requests[i].url);} if(urls.length){var entry=result.addChild(messageText,true);entry.addURLs(urls);result.violationCount+=urls.length;}},freshnessLifetimeGreaterThan:function(request,timeMs) {var dateHeader=this.responseHeader(request,"Date");if(!dateHeader) return false;var dateHeaderMs=Date.parse(dateHeader);if(isNaN(dateHeaderMs)) return false;var freshnessLifetimeMs;var maxAgeMatch=this.responseHeaderMatch(request,"Cache-Control","max-age=(\\d+)");if(maxAgeMatch) freshnessLifetimeMs=(maxAgeMatch[1])?1000*maxAgeMatch[1]:0;else{var expiresHeader=this.responseHeader(request,"Expires");if(expiresHeader){var expDate=Date.parse(expiresHeader);if(!isNaN(expDate)) freshnessLifetimeMs=expDate-dateHeaderMs;}} return(isNaN(freshnessLifetimeMs))?false:freshnessLifetimeMs>timeMs;},responseHeader:function(request,header) {return request.responseHeaderValue(header);},hasResponseHeader:function(request,header) {return request.responseHeaderValue(header)!==undefined;},isCompressible:function(request) {return request.resourceType().isTextType();},isPubliclyCacheable:function(request) {if(this._isExplicitlyNonCacheable(request)) return false;if(this.responseHeaderMatch(request,"Cache-Control","public")) return true;return request.url.indexOf("?")===-1&&!this.responseHeaderMatch(request,"Cache-Control","private");},responseHeaderMatch:function(request,header,regexp) {return request.responseHeaderValue(header)?request.responseHeaderValue(header).match(new RegExp(regexp,"im")):null;},hasExplicitExpiration:function(request) {return this.hasResponseHeader(request,"Date")&&(this.hasResponseHeader(request,"Expires")||!!this.responseHeaderMatch(request,"Cache-Control","max-age"));},_isExplicitlyNonCacheable:function(request) {var hasExplicitExp=this.hasExplicitExpiration(request);return!!this.responseHeaderMatch(request,"Cache-Control","(no-cache|no-store)")||!!this.responseHeaderMatch(request,"Pragma","no-cache")||(hasExplicitExp&&!this.freshnessLifetimeGreaterThan(request,0))||(!hasExplicitExp&&!!request.url&&request.url.indexOf("?")>=0)||(!hasExplicitExp&&!this.isCacheableResource(request));},isCacheableResource:function(request) {return request.statusCode!==undefined&&WebInspector.AuditRules.CacheableResponseCodes[request.statusCode];},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.BrowserCacheControlRule=function() {WebInspector.AuditRules.CacheControlRule.call(this,"http-browsercache",WebInspector.UIString("Leverage browser caching"));} WebInspector.AuditRules.BrowserCacheControlRule.prototype={handleNonCacheableResources:function(requests,result) {if(requests.length){var entry=result.addChild(WebInspector.UIString("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:"),true);result.violationCount+=requests.length;for(var i=0;i<requests.length;++i) entry.addURL(requests[i].url);}},runChecks:function(requests,result,callback) {this.execCheck(WebInspector.UIString("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:"),this._missingExpirationCheck,requests,result);this.execCheck(WebInspector.UIString("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:"),this._varyCheck,requests,result);this.execCheck(WebInspector.UIString("The following cacheable resources have a short freshness lifetime:"),this._oneMonthExpirationCheck,requests,result);this.execCheck(WebInspector.UIString("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:"),this._oneYearExpirationCheck,requests,result);},_missingExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.hasExplicitExpiration(request);},_varyCheck:function(request) {var varyHeader=this.responseHeader(request,"Vary");if(varyHeader){varyHeader=varyHeader.replace(/User-Agent/gi,"");varyHeader=varyHeader.replace(/Accept-Encoding/gi,"");varyHeader=varyHeader.replace(/[, ]*/g,"");} return varyHeader&&varyHeader.length&&this.isCacheableResource(request)&&this.freshnessLifetimeGreaterThan(request,0);},_oneMonthExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.freshnessLifetimeGreaterThan(request,WebInspector.AuditRules.CacheControlRule.MillisPerMonth)&&this.freshnessLifetimeGreaterThan(request,0);},_oneYearExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.freshnessLifetimeGreaterThan(request,11*WebInspector.AuditRules.CacheControlRule.MillisPerMonth)&&this.freshnessLifetimeGreaterThan(request,WebInspector.AuditRules.CacheControlRule.MillisPerMonth);},__proto__:WebInspector.AuditRules.CacheControlRule.prototype} WebInspector.AuditRules.ImageDimensionsRule=function() {WebInspector.AuditRule.call(this,"page-imagedims",WebInspector.UIString("Specify image dimensions"));} WebInspector.AuditRules.ImageDimensionsRule.prototype={doRun:function(target,requests,result,callback,progress) {var domModel=WebInspector.DOMModel.fromTarget(target);var cssModel=WebInspector.CSSModel.fromTarget(target);if(!domModel||!cssModel){callback(null);return;} var urlToNoDimensionCount={};function doneCallback() {for(var url in urlToNoDimensionCount){var entry=entry||result.addChild(WebInspector.UIString("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:"),true);var format="%r";if(urlToNoDimensionCount[url]>1) format+=" (%d uses)";entry.addFormatted(format,url,urlToNoDimensionCount[url]);result.violationCount++;} callback(entry?result:null);} function imageStylesReady(imageId,styles) {if(progress.isCanceled()){callback(null);return;} const node=domModel.nodeForId(imageId);var src=node.getAttribute("src");if(!src.asParsedURL()){for(var frameOwnerCandidate=node;frameOwnerCandidate;frameOwnerCandidate=frameOwnerCandidate.parentNode){if(frameOwnerCandidate.baseURL){var completeSrc=WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL,src);break;}}} if(completeSrc) src=completeSrc;if(styles.computedStyle.get("position")==="absolute") return;var widthFound=false;var heightFound=false;for(var i=0;!(widthFound&&heightFound)&&i<styles.nodeStyles.length;++i){var style=styles.nodeStyles[i];if(style.getPropertyValue("width")!=="") widthFound=true;if(style.getPropertyValue("height")!=="") heightFound=true;} if(!widthFound||!heightFound){if(src in urlToNoDimensionCount) ++urlToNoDimensionCount[src];else urlToNoDimensionCount[src]=1;}} function getStyles(nodeIds) {if(progress.isCanceled()){callback(null);return;} var targetResult={};function matchedCallback(matchedStyleResult) {if(!matchedStyleResult) return;targetResult.nodeStyles=matchedStyleResult.nodeStyles();} function computedCallback(computedStyle) {targetResult.computedStyle=computedStyle;} if(!nodeIds||!nodeIds.length) doneCallback();var nodePromises=[];for(var i=0;nodeIds&&i<nodeIds.length;++i){var stylePromises=[cssModel.matchedStylesPromise(nodeIds[i]).then(matchedCallback),cssModel.computedStylePromise(nodeIds[i]).then(computedCallback)];var nodePromise=Promise.all(stylePromises).then(imageStylesReady.bind(null,nodeIds[i],targetResult));nodePromises.push(nodePromise);} Promise.all(nodePromises).catchException(null).then(doneCallback);} function onDocumentAvailable(root) {if(progress.isCanceled()){callback(null);return;} domModel.querySelectorAll(root.id,"img[src]",getStyles);} if(progress.isCanceled()){callback(null);return;} domModel.requestDocument(onDocumentAvailable);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CssInHeadRule=function() {WebInspector.AuditRule.call(this,"page-cssinhead",WebInspector.UIString("Put CSS in the document head"));} WebInspector.AuditRules.CssInHeadRule.prototype={doRun:function(target,requests,result,callback,progress) {var domModel=WebInspector.DOMModel.fromTarget(target);if(!domModel){callback(null);return;} function evalCallback(evalResult) {if(progress.isCanceled()){callback(null);return;} if(!evalResult) return callback(null);var summary=result.addChild("");for(var url in evalResult){var urlViolations=evalResult[url];if(urlViolations[0]){result.addFormatted("%s style block(s) in the %r body should be moved to the document head.",urlViolations[0],url);result.violationCount+=urlViolations[0];} for(var i=0;i<urlViolations[1].length;++i) result.addFormatted("Link node %r should be moved to the document head in %r",urlViolations[1][i],url);result.violationCount+=urlViolations[1].length;} summary.value=WebInspector.UIString("CSS in the document body adversely impacts rendering performance.");callback(result);} function externalStylesheetsReceived(root,inlineStyleNodeIds,nodeIds) {if(progress.isCanceled()){callback(null);return;} if(!nodeIds) return;var externalStylesheetNodeIds=nodeIds;var result=null;if(inlineStyleNodeIds.length||externalStylesheetNodeIds.length){var urlToViolationsArray={};var externalStylesheetHrefs=[];for(var j=0;j<externalStylesheetNodeIds.length;++j){var linkNode=domModel.nodeForId(externalStylesheetNodeIds[j]);var completeHref=WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL,linkNode.getAttribute("href"));externalStylesheetHrefs.push(completeHref||"<empty>");} urlToViolationsArray[root.documentURL]=[inlineStyleNodeIds.length,externalStylesheetHrefs];result=urlToViolationsArray;} evalCallback(result);} function inlineStylesReceived(root,nodeIds) {if(progress.isCanceled()){callback(null);return;} if(!nodeIds) return;domModel.querySelectorAll(root.id,"body link[rel~='stylesheet'][href]",externalStylesheetsReceived.bind(null,root,nodeIds));} function onDocumentAvailable(root) {if(progress.isCanceled()){callback(null);return;} domModel.querySelectorAll(root.id,"body style",inlineStylesReceived.bind(null,root));} domModel.requestDocument(onDocumentAvailable);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.StylesScriptsOrderRule=function() {WebInspector.AuditRule.call(this,"page-stylescriptorder",WebInspector.UIString("Optimize the order of styles and scripts"));} WebInspector.AuditRules.StylesScriptsOrderRule.prototype={doRun:function(target,requests,result,callback,progress) {var domModel=WebInspector.DOMModel.fromTarget(target);if(!domModel){callback(null);return;} function evalCallback(resultValue) {if(progress.isCanceled()){callback(null);return;} if(!resultValue) return callback(null);var lateCssUrls=resultValue[0];var cssBeforeInlineCount=resultValue[1];if(lateCssUrls.length){var entry=result.addChild(WebInspector.UIString("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript."),true);entry.addURLs(lateCssUrls);result.violationCount+=lateCssUrls.length;} if(cssBeforeInlineCount){result.addChild(WebInspector.UIString(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.",cssBeforeInlineCount,cssBeforeInlineCount>1?"s were":" was"));result.violationCount+=cssBeforeInlineCount;} callback(result);} function cssBeforeInlineReceived(lateStyleIds,nodeIds) {if(progress.isCanceled()){callback(null);return;} if(!nodeIds) return;var cssBeforeInlineCount=nodeIds.length;var result=null;if(lateStyleIds.length||cssBeforeInlineCount){var lateStyleUrls=[];for(var i=0;i<lateStyleIds.length;++i){var lateStyleNode=domModel.nodeForId(lateStyleIds[i]);var completeHref=WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL,lateStyleNode.getAttribute("href"));lateStyleUrls.push(completeHref||"<empty>");} result=[lateStyleUrls,cssBeforeInlineCount];} evalCallback(result);} function lateStylesReceived(root,nodeIds) {if(progress.isCanceled()){callback(null);return;} if(!nodeIds) return;domModel.querySelectorAll(root.id,"head link[rel~='stylesheet'][href] ~ script:not([src])",cssBeforeInlineReceived.bind(null,nodeIds));} function onDocumentAvailable(root) {if(progress.isCanceled()){callback(null);return;} domModel.querySelectorAll(root.id,"head script[src] ~ link[rel~='stylesheet'][href]",lateStylesReceived.bind(null,root));} domModel.requestDocument(onDocumentAvailable);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CSSRuleBase=function(id,name) {WebInspector.AuditRule.call(this,id,name);} WebInspector.AuditRules.CSSRuleBase.prototype={doRun:function(target,requests,result,callback,progress) {var cssModel=WebInspector.CSSModel.fromTarget(target);if(!cssModel){callback(null);return;} var headers=cssModel.allStyleSheets();if(!headers.length){callback(null);return;} var activeHeaders=[];for(var i=0;i<headers.length;++i){if(!headers[i].disabled) activeHeaders.push(headers[i]);} var styleSheetProcessor=new WebInspector.AuditRules.StyleSheetProcessor(activeHeaders,progress,this._styleSheetsLoaded.bind(this,result,callback,progress));styleSheetProcessor.run();},_styleSheetsLoaded:function(result,callback,progress,styleSheets) {for(var i=0;i<styleSheets.length;++i) this._visitStyleSheet(styleSheets[i],result);callback(result);},_visitStyleSheet:function(styleSheet,result) {this.visitStyleSheet(styleSheet,result);for(var i=0;i<styleSheet.rules.length;++i) this._visitRule(styleSheet,styleSheet.rules[i],result);this.didVisitStyleSheet(styleSheet,result);},_visitRule:function(styleSheet,rule,result) {this.visitRule(styleSheet,rule,result);var allProperties=rule.properties;for(var i=0;i<allProperties.length;++i) this.visitProperty(styleSheet,rule,allProperties[i],result);this.didVisitRule(styleSheet,rule,result);},visitStyleSheet:function(styleSheet,result) {},didVisitStyleSheet:function(styleSheet,result) {},visitRule:function(styleSheet,rule,result) {},didVisitRule:function(styleSheet,rule,result) {},visitProperty:function(styleSheet,rule,property,result) {},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CookieRuleBase=function(id,name) {WebInspector.AuditRule.call(this,id,name);} WebInspector.AuditRules.CookieRuleBase.prototype={doRun:function(target,requests,result,callback,progress) {var self=this;function resultCallback(receivedCookies) {if(progress.isCanceled()){callback(result);return;} self.processCookies(receivedCookies,requests,result);callback(result);} WebInspector.Cookies.getCookiesAsync(resultCallback);},mapResourceCookies:function(requestsByDomain,allCookies,callback) {for(var i=0;i<allCookies.length;++i){for(var requestDomain in requestsByDomain){if(WebInspector.Cookies.cookieDomainMatchesResourceDomain(allCookies[i].domain(),requestDomain)) this._callbackForResourceCookiePairs(requestsByDomain[requestDomain],allCookies[i],callback);}}},_callbackForResourceCookiePairs:function(requests,cookie,callback) {if(!requests) return;for(var i=0;i<requests.length;++i){if(WebInspector.Cookies.cookieMatchesResourceURL(cookie,requests[i].url)) callback(requests[i],cookie);}},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CookieSizeRule=function(avgBytesThreshold) {WebInspector.AuditRules.CookieRuleBase.call(this,"http-cookiesize",WebInspector.UIString("Minimize cookie size"));this._avgBytesThreshold=avgBytesThreshold;this._maxBytesThreshold=1000;} WebInspector.AuditRules.CookieSizeRule.prototype={_average:function(cookieArray) {var total=0;for(var i=0;i<cookieArray.length;++i) total+=cookieArray[i].size();return cookieArray.length?Math.round(total/cookieArray.length):0;},_max:function(cookieArray) {var result=0;for(var i=0;i<cookieArray.length;++i) result=Math.max(cookieArray[i].size(),result);return result;},processCookies:function(allCookies,requests,result) {function maxSizeSorter(a,b) {return b.maxCookieSize-a.maxCookieSize;} function avgSizeSorter(a,b) {return b.avgCookieSize-a.avgCookieSize;} var cookiesPerResourceDomain={};function collectorCallback(request,cookie) {var cookies=cookiesPerResourceDomain[request.parsedURL.host];if(!cookies){cookies=[];cookiesPerResourceDomain[request.parsedURL.host]=cookies;} cookies.push(cookie);} if(!allCookies.length) return;var sortedCookieSizes=[];var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,null,true);this.mapResourceCookies(domainToResourcesMap,allCookies,collectorCallback);for(var requestDomain in cookiesPerResourceDomain){var cookies=cookiesPerResourceDomain[requestDomain];sortedCookieSizes.push({domain:requestDomain,avgCookieSize:this._average(cookies),maxCookieSize:this._max(cookies)});} var avgAllCookiesSize=this._average(allCookies);var hugeCookieDomains=[];sortedCookieSizes.sort(maxSizeSorter);for(var i=0,len=sortedCookieSizes.length;i<len;++i){var maxCookieSize=sortedCookieSizes[i].maxCookieSize;if(maxCookieSize>this._maxBytesThreshold) hugeCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(sortedCookieSizes[i].domain)+": "+Number.bytesToString(maxCookieSize));} var bigAvgCookieDomains=[];sortedCookieSizes.sort(avgSizeSorter);for(var i=0,len=sortedCookieSizes.length;i<len;++i){var domain=sortedCookieSizes[i].domain;var avgCookieSize=sortedCookieSizes[i].avgCookieSize;if(avgCookieSize>this._avgBytesThreshold&&avgCookieSize<this._maxBytesThreshold) bigAvgCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(domain)+": "+Number.bytesToString(avgCookieSize));} result.addChild(WebInspector.UIString("The average cookie size for all requests on this page is %s",Number.bytesToString(avgAllCookiesSize)));if(hugeCookieDomains.length){var entry=result.addChild(WebInspector.UIString("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet."),true);entry.addURLs(hugeCookieDomains);result.violationCount+=hugeCookieDomains.length;} if(bigAvgCookieDomains.length){var entry=result.addChild(WebInspector.UIString("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.",this._avgBytesThreshold),true);entry.addURLs(bigAvgCookieDomains);result.violationCount+=bigAvgCookieDomains.length;}},__proto__:WebInspector.AuditRules.CookieRuleBase.prototype} WebInspector.AuditRules.StaticCookielessRule=function(minResources) {WebInspector.AuditRules.CookieRuleBase.call(this,"http-staticcookieless",WebInspector.UIString("Serve static content from a cookieless domain"));this._minResources=minResources;} WebInspector.AuditRules.StaticCookielessRule.prototype={processCookies:function(allCookies,requests,result) {var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,[WebInspector.resourceTypes.Stylesheet,WebInspector.resourceTypes.Image],true);var totalStaticResources=0;for(var domain in domainToResourcesMap) totalStaticResources+=domainToResourcesMap[domain].length;if(totalStaticResources<this._minResources) return;var matchingResourceData={};this.mapResourceCookies(domainToResourcesMap,allCookies,this._collectorCallback.bind(this,matchingResourceData));var badUrls=[];var cookieBytes=0;for(var url in matchingResourceData){badUrls.push(url);cookieBytes+=matchingResourceData[url];} if(badUrls.length<this._minResources) return;var entry=result.addChild(WebInspector.UIString("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:",Number.bytesToString(cookieBytes)),true);entry.addURLs(badUrls);result.violationCount=badUrls.length;},_collectorCallback:function(matchingResourceData,request,cookie) {matchingResourceData[request.url]=(matchingResourceData[request.url]||0)+cookie.size();},__proto__:WebInspector.AuditRules.CookieRuleBase.prototype};WebInspector.AuditExtensionCategory=function(extensionOrigin,id,displayName,ruleCount) {this._extensionOrigin=extensionOrigin;this._id=id;this._displayName=displayName;this._ruleCount=ruleCount;} WebInspector.AuditExtensionCategory.prototype={get id() {return this._id;},get displayName() {return this._displayName;},run:function(target,requests,ruleResultCallback,progress) {var results=new WebInspector.AuditExtensionCategoryResults(this,target,ruleResultCallback,progress);WebInspector.extensionServer.startAuditRun(this.id,results);}} WebInspector.AuditExtensionCategoryResults=function(category,target,ruleResultCallback,progress) {this._target=target;this._category=category;this._ruleResultCallback=ruleResultCallback;this._progress=progress;this._progress.setTotalWork(1);this._expectedResults=category._ruleCount;this._actualResults=0;this._id=category.id+"-"+ ++WebInspector.AuditExtensionCategoryResults._lastId;} WebInspector.AuditExtensionCategoryResults.prototype={id:function() {return this._id;},done:function() {WebInspector.extensionServer.stopAuditRun(this);this._progress.done();},addResult:function(displayName,description,severity,details) {var result=new WebInspector.AuditRuleResult(displayName);if(description) result.addChild(description);result.severity=severity;if(details) this._addNode(result,details);this._addResult(result);},_addNode:function(parent,node) {var contents=WebInspector.auditFormatters.partiallyApply(WebInspector.AuditExtensionFormatters,this,node.contents);var addedNode=parent.addChild(contents,node.expanded);if(node.children){for(var i=0;i<node.children.length;++i) this._addNode(addedNode,node.children[i]);}},_addResult:function(result) {this._ruleResultCallback(result);++this._actualResults;if(typeof this._expectedResults==="number"){this._progress.setWorked(this._actualResults/this._expectedResults);if(this._actualResults===this._expectedResults) this.done();}},updateProgress:function(progress) {this._progress.setWorked(progress);},evaluate:function(expression,evaluateOptions,callback) {function onEvaluate(error,result,wasThrown) {if(wasThrown) return;var object=this._target.runtimeModel.createRemoteObject(result);callback(object);} var evaluateCallback=(onEvaluate.bind(this));WebInspector.extensionServer.evaluate(expression,false,false,evaluateOptions,this._category._extensionOrigin,evaluateCallback);}} WebInspector.AuditExtensionFormatters={object:function(expression,title,evaluateOptions) {var parentElement=createElement("div");function onEvaluate(remoteObject) {var section=new WebInspector.ObjectPropertiesSection(remoteObject,title);section.expand();section.editable=false;parentElement.appendChild(section.element);} this.evaluate(expression,evaluateOptions,onEvaluate);return parentElement;},node:function(expression,evaluateOptions) {var parentElement=createElement("div");this.evaluate(expression,evaluateOptions,onEvaluate);function onEvaluate(remoteObject) {WebInspector.Renderer.renderPromise(remoteObject).then(appendRenderer).then(remoteObject.release.bind(remoteObject));function appendRenderer(element) {parentElement.appendChild(element);}} return parentElement;}} WebInspector.AuditExtensionCategoryResults._lastId=0;;Runtime.cachedResources["audits/auditsPanel.css"]="/*\n * Copyright (C) 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.audits-sidebar-tree-item .icon {\n content: url(Images/resourcesTimeGraphIcon.png);\n}\n\n.audit-result-sidebar-tree-item .icon {\n content: url(Images/resourceDocumentIcon.png);\n}\n\n.audit-launcher-view .audit-launcher-view-content {\n padding: 0 0 0 16px;\n white-space: nowrap;\n display: -webkit-flex;\n text-align: left;\n -webkit-flex-direction: column;\n flex: auto;\n}\n\n.audit-launcher-view h1 {\n padding-top: 15px;\n -webkit-flex: none;\n}\n\n.audit-launcher-view h1.no-audits {\n text-align: center;\n font-style: italic;\n position: relative;\n left: -8px;\n}\n\n.audit-launcher-view div.button-container {\n width: 100%;\n padding: 16px 0;\n -webkit-flex: none;\n}\n\n.audit-launcher-view div.button-container > button {\n -webkit-align-self: flex-start;\n margin-right: 10px;\n margin-bottom: 5px;\n margin-top: 5px;\n}\n\n.audit-launcher-view fieldset.audit-categories-container {\n position: relative;\n top: 11px;\n left: 0;\n width: 100%;\n overflow-y: auto;\n border: 0 none;\n -webkit-flex: none;\n}\n\n.audit-launcher-view button {\n margin: 0 5px 0 0;\n}\n\n.panel-enabler-view.audit-launcher-view label {\n padding: 0 0 5px 0;\n margin: 0;\n display: flex;\n flex-shrink: 0;\n}\n\n.panel-enabler-view.audit-launcher-view label.disabled {\n color: rgb(130, 130, 130);\n}\n\n.audit-launcher-view input[type=\"checkbox\"] {\n margin-left: 0;\n height: 14px;\n width: 14px;\n}\n\n.audit-result-view {\n overflow: auto;\n display: block;\n flex: auto;\n}\n\n.audit-result-tree {\n margin: 0 0 3px;\n}\n\n.audit-launcher-view .progress-indicator {\n display: inline-block;\n}\n\n.resource-url {\n float: right;\n text-align: right;\n max-width: 100%;\n margin-left: 4px;\n}\n\n/*# sourceURL=audits/auditsPanel.css */";Runtime.cachedResources["audits/auditResultTree.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.severity {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n display: inline-block;\n width: 10px;\n height: 10px;\n position: relative;\n top: 1px;\n margin-right: 4px;\n}\n\nli {\n -webkit-user-select: text;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.severity {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.severity.severe {\n background-position: -224px -96px;\n}\n\n.severity.warning {\n background-position: -246px -96px;\n}\n\n.severity.info {\n background-position: -235px -96px;\n}\n.audit-result {\n font-weight: bold;\n}\n\n/*# sourceURL=audits/auditResultTree.css */"; |
| 1 2 3 4 5 | 2 | WebInspector.DefaultCodeMirrorMimeMode=function() {} WebInspector.DefaultCodeMirrorMimeMode.prototype={install:function(extension) {var modeFileName=extension.descriptor()["fileName"];var modeContent=extension.module().resource(modeFileName);self.eval(modeContent+"\n//# sourceURL="+modeFileName);}};Runtime.cachedResources["cm_modes/clike.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.defineMode(\"clike\", function(config, parserConfig) {\n var indentUnit = config.indentUnit,\n statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,\n dontAlignCalls = parserConfig.dontAlignCalls,\n keywords = parserConfig.keywords || {},\n builtin = parserConfig.builtin || {},\n blockKeywords = parserConfig.blockKeywords || {},\n atoms = parserConfig.atoms || {},\n hooks = parserConfig.hooks || {},\n multiLineStrings = parserConfig.multiLineStrings;\n var isOperatorChar = /[+\\-*&%=<>!?|\\/]/;\n\n var curPunc;\n\n function tokenBase(stream, state) {\n var ch = stream.next();\n if (hooks[ch]) {\n var result = hooks[ch](stream, state);\n if (result !== false) return result;\n }\n if (ch == '\"' || ch == \"'\") {\n state.tokenize = tokenString(ch);\n return state.tokenize(stream, state);\n }\n if (/[\\[\\]{}\\(\\),;\\:\\.]/.test(ch)) {\n curPunc = ch;\n return null;\n }\n if (/\\d/.test(ch)) {\n stream.eatWhile(/[\\w\\.]/);\n return \"number\";\n }\n if (ch == \"/\") {\n if (stream.eat(\"*\")) {\n state.tokenize = tokenComment;\n return tokenComment(stream, state);\n }\n if (stream.eat(\"/\")) {\n stream.skipToEnd();\n return \"comment\";\n }\n }\n if (isOperatorChar.test(ch)) {\n stream.eatWhile(isOperatorChar);\n return \"operator\";\n }\n stream.eatWhile(/[\\w\\$_]/);\n var cur = stream.current();\n if (keywords.propertyIsEnumerable(cur)) {\n if (blockKeywords.propertyIsEnumerable(cur)) curPunc = \"newstatement\";\n return \"keyword\";\n }\n if (builtin.propertyIsEnumerable(cur)) {\n if (blockKeywords.propertyIsEnumerable(cur)) curPunc = \"newstatement\";\n return \"builtin\";\n }\n if (atoms.propertyIsEnumerable(cur)) return \"atom\";\n return \"variable\";\n }\n\n function tokenString(quote) {\n return function(stream, state) {\n var escaped = false, next, end = false;\n while ((next = stream.next()) != null) {\n if (next == quote && !escaped) {end = true; break;}\n escaped = !escaped && next == \"\\\\\";\n }\n if (end || !(escaped || multiLineStrings))\n state.tokenize = null;\n return \"string\";\n };\n }\n\n function tokenComment(stream, state) {\n var maybeEnd = false, ch;\n while (ch = stream.next()) {\n if (ch == \"/\" && maybeEnd) {\n state.tokenize = null;\n break;\n }\n maybeEnd = (ch == \"*\");\n }\n return \"comment\";\n }\n\n function Context(indented, column, type, align, prev) {\n this.indented = indented;\n this.column = column;\n this.type = type;\n this.align = align;\n this.prev = prev;\n }\n function pushContext(state, col, type) {\n var indent = state.indented;\n if (state.context && state.context.type == \"statement\")\n indent = state.context.indented;\n return state.context = new Context(indent, col, type, null, state.context);\n }\n function popContext(state) {\n var t = state.context.type;\n if (t == \")\" || t == \"]\" || t == \"}\")\n state.indented = state.context.indented;\n return state.context = state.context.prev;\n }\n\n // Interface\n\n return {\n startState: function(basecolumn) {\n return {\n tokenize: null,\n context: new Context((basecolumn || 0) - indentUnit, 0, \"top\", false),\n indented: 0,\n startOfLine: true\n };\n },\n\n token: function(stream, state) {\n var ctx = state.context;\n if (stream.sol()) {\n if (ctx.align == null) ctx.align = false;\n state.indented = stream.indentation();\n state.startOfLine = true;\n }\n if (stream.eatSpace()) return null;\n curPunc = null;\n var style = (state.tokenize || tokenBase)(stream, state);\n if (style == \"comment\" || style == \"meta\") return style;\n if (ctx.align == null) ctx.align = true;\n\n if ((curPunc == \";\" || curPunc == \":\" || curPunc == \",\") && ctx.type == \"statement\") popContext(state);\n else if (curPunc == \"{\") pushContext(state, stream.column(), \"}\");\n else if (curPunc == \"[\") pushContext(state, stream.column(), \"]\");\n else if (curPunc == \"(\") pushContext(state, stream.column(), \")\");\n else if (curPunc == \"}\") {\n while (ctx.type == \"statement\") ctx = popContext(state);\n if (ctx.type == \"}\") ctx = popContext(state);\n while (ctx.type == \"statement\") ctx = popContext(state);\n }\n else if (curPunc == ctx.type) popContext(state);\n else if (((ctx.type == \"}\" || ctx.type == \"top\") && curPunc != ';') || (ctx.type == \"statement\" && curPunc == \"newstatement\"))\n pushContext(state, stream.column(), \"statement\");\n state.startOfLine = false;\n return style;\n },\n\n indent: function(state, textAfter) {\n if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;\n var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);\n if (ctx.type == \"statement\" && firstChar == \"}\") ctx = ctx.prev;\n var closing = firstChar == ctx.type;\n if (ctx.type == \"statement\") return ctx.indented + (firstChar == \"{\" ? 0 : statementIndentUnit);\n else if (ctx.align && (!dontAlignCalls || ctx.type != \")\")) return ctx.column + (closing ? 0 : 1);\n else if (ctx.type == \")\" && !closing) return ctx.indented + statementIndentUnit;\n else return ctx.indented + (closing ? 0 : indentUnit);\n },\n\n electricChars: \"{}\",\n blockCommentStart: \"/*\",\n blockCommentEnd: \"*/\",\n lineComment: \"//\",\n fold: \"brace\"\n };\n});\n\n function words(str) {\n var obj = {}, words = str.split(\" \");\n for (var i = 0; i < words.length; ++i) obj[words[i]] = true;\n return obj;\n }\n var cKeywords = \"auto if break int case long char register continue return default short do sizeof \" +\n \"double static else struct entry switch extern typedef float union for unsigned \" +\n \"goto while enum void const signed volatile\";\n\n function cppHook(stream, state) {\n if (!state.startOfLine) return false;\n for (;;) {\n if (stream.skipTo(\"\\\\\")) {\n stream.next();\n if (stream.eol()) {\n state.tokenize = cppHook;\n break;\n }\n } else {\n stream.skipToEnd();\n state.tokenize = null;\n break;\n }\n }\n return \"meta\";\n }\n\n function cpp11StringHook(stream, state) {\n stream.backUp(1);\n // Raw strings.\n if (stream.match(/(R|u8R|uR|UR|LR)/)) {\n var match = stream.match(/\"([^\\s\\\\()]{0,16})\\(/);\n if (!match) {\n return false;\n }\n state.cpp11RawStringDelim = match[1];\n state.tokenize = tokenRawString;\n return tokenRawString(stream, state);\n }\n // Unicode strings/chars.\n if (stream.match(/(u8|u|U|L)/)) {\n if (stream.match(/[\"']/, /* eat */ false)) {\n return \"string\";\n }\n return false;\n }\n // Ignore this hook.\n stream.next();\n return false;\n }\n\n // C#-style strings where \"\" escapes a quote.\n function tokenAtString(stream, state) {\n var next;\n while ((next = stream.next()) != null) {\n if (next == '\"' && !stream.eat('\"')) {\n state.tokenize = null;\n break;\n }\n }\n return \"string\";\n }\n\n // C++11 raw string literal is <prefix>\"<delim>( anything )<delim>\", where\n // <delim> can be a string up to 16 characters long.\n function tokenRawString(stream, state) {\n // Escape characters that have special regex meanings.\n var delim = state.cpp11RawStringDelim.replace(/[^\\w\\s]/g, '\\\\$&');\n var match = stream.match(new RegExp(\".*?\\\\)\" + delim + '\"'));\n if (match)\n state.tokenize = null;\n else\n stream.skipToEnd();\n return \"string\";\n }\n\n function def(mimes, mode) {\n if (typeof mimes == \"string\") mimes = [mimes];\n var words = [];\n function add(obj) {\n if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))\n words.push(prop);\n }\n add(mode.keywords);\n add(mode.builtin);\n add(mode.atoms);\n if (words.length) {\n mode.helperType = mimes[0];\n CodeMirror.registerHelper(\"hintWords\", mimes[0], words);\n }\n\n for (var i = 0; i < mimes.length; ++i)\n CodeMirror.defineMIME(mimes[i], mode);\n }\n\n def([\"text/x-csrc\", \"text/x-c\", \"text/x-chdr\"], {\n name: \"clike\",\n keywords: words(cKeywords),\n blockKeywords: words(\"case do else for if switch while struct\"),\n atoms: words(\"null\"),\n hooks: {\"#\": cppHook},\n modeProps: {fold: [\"brace\", \"include\"]}\n });\n\n def([\"text/x-c++src\", \"text/x-c++hdr\"], {\n name: \"clike\",\n keywords: words(cKeywords + \" asm dynamic_cast namespace reinterpret_cast try bool explicit new \" +\n \"static_cast typeid catch operator template typename class friend private \" +\n \"this using const_cast inline public throw virtual delete mutable protected \" +\n \"wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final \" +\n \"static_assert override\"),\n blockKeywords: words(\"catch class do else finally for if struct switch try while\"),\n atoms: words(\"true false null\"),\n hooks: {\n \"#\": cppHook,\n \"u\": cpp11StringHook,\n \"U\": cpp11StringHook,\n \"L\": cpp11StringHook,\n \"R\": cpp11StringHook\n },\n modeProps: {fold: [\"brace\", \"include\"]}\n });\n def(\"text/x-java\", {\n name: \"clike\",\n keywords: words(\"abstract assert boolean break byte case catch char class const continue default \" +\n \"do double else enum extends final finally float for goto if implements import \" +\n \"instanceof int interface long native new package private protected public \" +\n \"return short static strictfp super switch synchronized this throw throws transient \" +\n \"try void volatile while\"),\n blockKeywords: words(\"catch class do else finally for if switch try while\"),\n atoms: words(\"true false null\"),\n hooks: {\n \"@\": function(stream) {\n stream.eatWhile(/[\\w\\$_]/);\n return \"meta\";\n }\n },\n modeProps: {fold: [\"brace\", \"import\"]}\n });\n def(\"text/x-csharp\", {\n name: \"clike\",\n keywords: words(\"abstract as base break case catch checked class const continue\" +\n \" default delegate do else enum event explicit extern finally fixed for\" +\n \" foreach goto if implicit in interface internal is lock namespace new\" +\n \" operator out override params private protected public readonly ref return sealed\" +\n \" sizeof stackalloc static struct switch this throw try typeof unchecked\" +\n \" unsafe using virtual void volatile while add alias ascending descending dynamic from get\" +\n \" global group into join let orderby partial remove select set value var yield\"),\n blockKeywords: words(\"catch class do else finally for foreach if struct switch try while\"),\n builtin: words(\"Boolean Byte Char DateTime DateTimeOffset Decimal Double\" +\n \" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32\" +\n \" UInt64 bool byte char decimal double short int long object\" +\n \" sbyte float string ushort uint ulong\"),\n atoms: words(\"true false null\"),\n hooks: {\n \"@\": function(stream, state) {\n if (stream.eat('\"')) {\n state.tokenize = tokenAtString;\n return tokenAtString(stream, state);\n }\n stream.eatWhile(/[\\w\\$_]/);\n return \"meta\";\n }\n }\n });\n def(\"text/x-scala\", {\n name: \"clike\",\n keywords: words(\n\n /* scala */\n \"abstract case catch class def do else extends false final finally for forSome if \" +\n \"implicit import lazy match new null object override package private protected return \" +\n \"sealed super this throw trait try trye type val var while with yield _ : = => <- <: \" +\n \"<% >: # @ \" +\n\n /* package scala */\n \"assert assume require print println printf readLine readBoolean readByte readShort \" +\n \"readChar readInt readLong readFloat readDouble \" +\n\n \"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either \" +\n \"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable \" +\n \"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering \" +\n \"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder \" +\n \"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: \" +\n\n /* package java.lang */\n \"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable \" +\n \"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process \" +\n \"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String \" +\n \"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void\"\n\n\n ),\n blockKeywords: words(\"catch class do else finally for forSome if match switch try while\"),\n atoms: words(\"true false null\"),\n hooks: {\n \"@\": function(stream) {\n stream.eatWhile(/[\\w\\$_]/);\n return \"meta\";\n }\n }\n });\n def([\"x-shader/x-vertex\", \"x-shader/x-fragment\"], {\n name: \"clike\",\n keywords: words(\"float int bool void \" +\n \"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 \" +\n \"mat2 mat3 mat4 \" +\n \"sampler1D sampler2D sampler3D samplerCube \" +\n \"sampler1DShadow sampler2DShadow\" +\n \"const attribute uniform varying \" +\n \"break continue discard return \" +\n \"for while do if else struct \" +\n \"in out inout\"),\n blockKeywords: words(\"for while do if else struct\"),\n builtin: words(\"radians degrees sin cos tan asin acos atan \" +\n \"pow exp log exp2 sqrt inversesqrt \" +\n \"abs sign floor ceil fract mod min max clamp mix step smootstep \" +\n \"length distance dot cross normalize ftransform faceforward \" +\n \"reflect refract matrixCompMult \" +\n \"lessThan lessThanEqual greaterThan greaterThanEqual \" +\n \"equal notEqual any all not \" +\n \"texture1D texture1DProj texture1DLod texture1DProjLod \" +\n \"texture2D texture2DProj texture2DLod texture2DProjLod \" +\n \"texture3D texture3DProj texture3DLod texture3DProjLod \" +\n \"textureCube textureCubeLod \" +\n \"shadow1D shadow2D shadow1DProj shadow2DProj \" +\n \"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod \" +\n \"dFdx dFdy fwidth \" +\n \"noise1 noise2 noise3 noise4\"),\n atoms: words(\"true false \" +\n \"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex \" +\n \"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 \" +\n \"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 \" +\n \"gl_FogCoord \" +\n \"gl_Position gl_PointSize gl_ClipVertex \" +\n \"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor \" +\n \"gl_TexCoord gl_FogFragCoord \" +\n \"gl_FragCoord gl_FrontFacing \" +\n \"gl_FragColor gl_FragData gl_FragDepth \" +\n \"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix \" +\n \"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse \" +\n \"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse \" +\n \"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose \" +\n \"gl_ProjectionMatrixInverseTranspose \" +\n \"gl_ModelViewProjectionMatrixInverseTranspose \" +\n \"gl_TextureMatrixInverseTranspose \" +\n \"gl_NormalScale gl_DepthRange gl_ClipPlane \" +\n \"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel \" +\n \"gl_FrontLightModelProduct gl_BackLightModelProduct \" +\n \"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ \" +\n \"gl_FogParameters \" +\n \"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords \" +\n \"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats \" +\n \"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits \" +\n \"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits \" +\n \"gl_MaxDrawBuffers\"),\n hooks: {\"#\": cppHook},\n modeProps: {fold: [\"brace\", \"include\"]}\n });\n\n});\n\n/*# sourceURL=cm_modes/clike.js */";Runtime.cachedResources["cm_modes/coffeescript.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n/**\n * Link to the project's GitHub page:\n * https://github.com/pickhardt/coffeescript-codemirror-mode\n */\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.defineMode(\"coffeescript\", function(conf) {\n var ERRORCLASS = \"error\";\n\n function wordRegexp(words) {\n return new RegExp(\"^((\" + words.join(\")|(\") + \"))\\\\b\");\n }\n\n var operators = /^(?:->|=>|\\+[+=]?|-[\\-=]?|\\*[\\*=]?|\\/[\\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\\|=?|\\^=?|\\~|!|\\?)/;\n var delimiters = /^(?:[()\\[\\]{},:`=;]|\\.\\.?\\.?)/;\n var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;\n var properties = /^(@|this\\.)[_A-Za-z$][_A-Za-z$0-9]*/;\n\n var wordOperators = wordRegexp([\"and\", \"or\", \"not\",\n \"is\", \"isnt\", \"in\",\n \"instanceof\", \"typeof\"]);\n var indentKeywords = [\"for\", \"while\", \"loop\", \"if\", \"unless\", \"else\",\n \"switch\", \"try\", \"catch\", \"finally\", \"class\"];\n var commonKeywords = [\"break\", \"by\", \"continue\", \"debugger\", \"delete\",\n \"do\", \"in\", \"of\", \"new\", \"return\", \"then\",\n \"this\", \"throw\", \"when\", \"until\"];\n\n var keywords = wordRegexp(indentKeywords.concat(commonKeywords));\n\n indentKeywords = wordRegexp(indentKeywords);\n\n\n var stringPrefixes = /^('{3}|\\\"{3}|['\\\"])/;\n var regexPrefixes = /^(\\/{3}|\\/)/;\n var commonConstants = [\"Infinity\", \"NaN\", \"undefined\", \"null\", \"true\", \"false\", \"on\", \"off\", \"yes\", \"no\"];\n var constants = wordRegexp(commonConstants);\n\n // Tokenizers\n function tokenBase(stream, state) {\n // Handle scope changes\n if (stream.sol()) {\n if (state.scope.align === null) state.scope.align = false;\n var scopeOffset = state.scope.offset;\n if (stream.eatSpace()) {\n var lineOffset = stream.indentation();\n if (lineOffset > scopeOffset && state.scope.type == \"coffee\") {\n return \"indent\";\n } else if (lineOffset < scopeOffset) {\n return \"dedent\";\n }\n return null;\n } else {\n if (scopeOffset > 0) {\n dedent(stream, state);\n }\n }\n }\n if (stream.eatSpace()) {\n return null;\n }\n\n var ch = stream.peek();\n\n // Handle docco title comment (single line)\n if (stream.match(\"####\")) {\n stream.skipToEnd();\n return \"comment\";\n }\n\n // Handle multi line comments\n if (stream.match(\"###\")) {\n state.tokenize = longComment;\n return state.tokenize(stream, state);\n }\n\n // Single line comment\n if (ch === \"#\") {\n stream.skipToEnd();\n return \"comment\";\n }\n\n // Handle number literals\n if (stream.match(/^-?[0-9\\.]/, false)) {\n var floatLiteral = false;\n // Floats\n if (stream.match(/^-?\\d*\\.\\d+(e[\\+\\-]?\\d+)?/i)) {\n floatLiteral = true;\n }\n if (stream.match(/^-?\\d+\\.\\d*/)) {\n floatLiteral = true;\n }\n if (stream.match(/^-?\\.\\d+/)) {\n floatLiteral = true;\n }\n\n if (floatLiteral) {\n // prevent from getting extra . on 1..\n if (stream.peek() == \".\"){\n stream.backUp(1);\n }\n return \"number\";\n }\n // Integers\n var intLiteral = false;\n // Hex\n if (stream.match(/^-?0x[0-9a-f]+/i)) {\n intLiteral = true;\n }\n // Decimal\n if (stream.match(/^-?[1-9]\\d*(e[\\+\\-]?\\d+)?/)) {\n intLiteral = true;\n }\n // Zero by itself with no other piece of number.\n if (stream.match(/^-?0(?![\\dx])/i)) {\n intLiteral = true;\n }\n if (intLiteral) {\n return \"number\";\n }\n }\n\n // Handle strings\n if (stream.match(stringPrefixes)) {\n state.tokenize = tokenFactory(stream.current(), false, \"string\");\n return state.tokenize(stream, state);\n }\n // Handle regex literals\n if (stream.match(regexPrefixes)) {\n if (stream.current() != \"/\" || stream.match(/^.*\\//, false)) { // prevent highlight of division\n state.tokenize = tokenFactory(stream.current(), true, \"string-2\");\n return state.tokenize(stream, state);\n } else {\n stream.backUp(1);\n }\n }\n\n // Handle operators and delimiters\n if (stream.match(operators) || stream.match(wordOperators)) {\n return \"operator\";\n }\n if (stream.match(delimiters)) {\n return \"punctuation\";\n }\n\n if (stream.match(constants)) {\n return \"atom\";\n }\n\n if (stream.match(keywords)) {\n return \"keyword\";\n }\n\n if (stream.match(identifiers)) {\n return \"variable\";\n }\n\n if (stream.match(properties)) {\n return \"property\";\n }\n\n // Handle non-detected items\n stream.next();\n return ERRORCLASS;\n }\n\n function tokenFactory(delimiter, singleline, outclass) {\n return function(stream, state) {\n while (!stream.eol()) {\n stream.eatWhile(/[^'\"\\/\\\\]/);\n if (stream.eat(\"\\\\\")) {\n stream.next();\n if (singleline && stream.eol()) {\n return outclass;\n }\n } else if (stream.match(delimiter)) {\n state.tokenize = tokenBase;\n return outclass;\n } else {\n stream.eat(/['\"\\/]/);\n }\n }\n if (singleline) {\n if (conf.mode.singleLineStringErrors) {\n outclass = ERRORCLASS;\n } else {\n state.tokenize = tokenBase;\n }\n }\n return outclass;\n };\n }\n\n function longComment(stream, state) {\n while (!stream.eol()) {\n stream.eatWhile(/[^#]/);\n if (stream.match(\"###\")) {\n state.tokenize = tokenBase;\n break;\n }\n stream.eatWhile(\"#\");\n }\n return \"comment\";\n }\n\n function indent(stream, state, type) {\n type = type || \"coffee\";\n var offset = 0, align = false, alignOffset = null;\n for (var scope = state.scope; scope; scope = scope.prev) {\n if (scope.type === \"coffee\") {\n offset = scope.offset + conf.indentUnit;\n break;\n }\n }\n if (type !== \"coffee\") {\n align = null;\n alignOffset = stream.column() + stream.current().length;\n } else if (state.scope.align) {\n state.scope.align = false;\n }\n state.scope = {\n offset: offset,\n type: type,\n prev: state.scope,\n align: align,\n alignOffset: alignOffset\n };\n }\n\n function dedent(stream, state) {\n if (!state.scope.prev) return;\n if (state.scope.type === \"coffee\") {\n var _indent = stream.indentation();\n var matched = false;\n for (var scope = state.scope; scope; scope = scope.prev) {\n if (_indent === scope.offset) {\n matched = true;\n break;\n }\n }\n if (!matched) {\n return true;\n }\n while (state.scope.prev && state.scope.offset !== _indent) {\n state.scope = state.scope.prev;\n }\n return false;\n } else {\n state.scope = state.scope.prev;\n return false;\n }\n }\n\n function tokenLexer(stream, state) {\n var style = state.tokenize(stream, state);\n var current = stream.current();\n\n // Handle \".\" connected identifiers\n if (current === \".\") {\n style = state.tokenize(stream, state);\n current = stream.current();\n if (/^\\.[\\w$]+$/.test(current)) {\n return \"variable\";\n } else {\n return ERRORCLASS;\n }\n }\n\n // Handle scope changes.\n if (current === \"return\") {\n state.dedent += 1;\n }\n if (((current === \"->\" || current === \"=>\") &&\n !state.lambda &&\n !stream.peek())\n || style === \"indent\") {\n indent(stream, state);\n }\n var delimiter_index = \"[({\".indexOf(current);\n if (delimiter_index !== -1) {\n indent(stream, state, \"])}\".slice(delimiter_index, delimiter_index+1));\n }\n if (indentKeywords.exec(current)){\n indent(stream, state);\n }\n if (current == \"then\"){\n dedent(stream, state);\n }\n\n\n if (style === \"dedent\") {\n if (dedent(stream, state)) {\n return ERRORCLASS;\n }\n }\n delimiter_index = \"])}\".indexOf(current);\n if (delimiter_index !== -1) {\n while (state.scope.type == \"coffee\" && state.scope.prev)\n state.scope = state.scope.prev;\n if (state.scope.type == current)\n state.scope = state.scope.prev;\n }\n if (state.dedent > 0 && stream.eol() && state.scope.type == \"coffee\") {\n if (state.scope.prev) state.scope = state.scope.prev;\n state.dedent -= 1;\n }\n\n return style;\n }\n\n var external = {\n startState: function(basecolumn) {\n return {\n tokenize: tokenBase,\n scope: {offset:basecolumn || 0, type:\"coffee\", prev: null, align: false},\n lastToken: null,\n lambda: false,\n dedent: 0\n };\n },\n\n token: function(stream, state) {\n var fillAlign = state.scope.align === null && state.scope;\n if (fillAlign && stream.sol()) fillAlign.align = false;\n\n var style = tokenLexer(stream, state);\n if (fillAlign && style && style != \"comment\") fillAlign.align = true;\n\n state.lastToken = {style:style, content: stream.current()};\n\n if (stream.eol() && stream.lambda) {\n state.lambda = false;\n }\n\n return style;\n },\n\n indent: function(state, text) {\n if (state.tokenize != tokenBase) return 0;\n var scope = state.scope;\n var closer = text && \"])}\".indexOf(text.charAt(0)) > -1;\n if (closer) while (scope.type == \"coffee\" && scope.prev) scope = scope.prev;\n var closes = closer && scope.type === text.charAt(0);\n if (scope.align)\n return scope.alignOffset - (closes ? 1 : 0);\n else\n return (closes ? scope.prev : scope).offset;\n },\n\n lineComment: \"#\",\n fold: \"indent\"\n };\n return external;\n});\n\nCodeMirror.defineMIME(\"text/x-coffeescript\", \"coffeescript\");\n\n});\n\n/*# sourceURL=cm_modes/coffeescript.js */";Runtime.cachedResources["cm_modes/php.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"), require(\"../htmlmixed/htmlmixed\"), require(\"../clike/clike\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\", \"../htmlmixed/htmlmixed\", \"../clike/clike\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n function keywords(str) {\n var obj = {}, words = str.split(\" \");\n for (var i = 0; i < words.length; ++i) obj[words[i]] = true;\n return obj;\n }\n function heredoc(delim) {\n return function(stream, state) {\n if (stream.match(delim)) state.tokenize = null;\n else stream.skipToEnd();\n return \"string\";\n };\n }\n\n // Helper for stringWithEscapes\n function matchSequence(list) {\n if (list.length == 0) return stringWithEscapes;\n return function (stream, state) {\n var patterns = list[0];\n for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {\n state.tokenize = matchSequence(list.slice(1));\n return patterns[i][1];\n }\n state.tokenize = stringWithEscapes;\n return \"string\";\n };\n }\n function stringWithEscapes(stream, state) {\n var escaped = false, next, end = false;\n\n if (stream.current() == '\"') return \"string\";\n\n // \"Complex\" syntax\n if (stream.match(\"${\", false) || stream.match(\"{$\", false)) {\n state.tokenize = null;\n return \"string\";\n }\n\n // Simple syntax\n if (stream.match(/\\$[a-zA-Z_][a-zA-Z0-9_]*/)) {\n // After the variable name there may appear array or object operator.\n if (stream.match(\"[\", false)) {\n // Match array operator\n state.tokenize = matchSequence([\n [[\"[\", null]],\n [[/\\d[\\w\\.]*/, \"number\"],\n [/\\$[a-zA-Z_][a-zA-Z0-9_]*/, \"variable-2\"],\n [/[\\w\\$]+/, \"variable\"]],\n [[\"]\", null]]\n ]);\n }\n if (stream.match(/\\-\\>\\w/, false)) {\n // Match object operator\n state.tokenize = matchSequence([\n [[\"->\", null]],\n [[/[\\w]+/, \"variable\"]]\n ]);\n }\n return \"variable-2\";\n }\n\n // Normal string\n while (\n !stream.eol() &&\n (!stream.match(\"{$\", false)) &&\n (!stream.match(/(\\$[a-zA-Z_][a-zA-Z0-9_]*|\\$\\{)/, false) || escaped)\n ) {\n next = stream.next();\n if (!escaped && next == '\"') { end = true; break; }\n escaped = !escaped && next == \"\\\\\";\n }\n if (end) {\n state.tokenize = null;\n state.phpEncapsStack.pop();\n }\n return \"string\";\n }\n\n var phpKeywords = \"abstract and array as break case catch class clone const continue declare default \" +\n \"do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final \" +\n \"for foreach function global goto if implements interface instanceof namespace \" +\n \"new or private protected public static switch throw trait try use var while xor \" +\n \"die echo empty exit eval include include_once isset list require require_once return \" +\n \"print unset __halt_compiler self static parent yield insteadof finally\";\n var phpAtoms = \"true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__\";\n var phpBuiltin = \"func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once\";\n CodeMirror.registerHelper(\"hintWords\", \"php\", [phpKeywords, phpAtoms, phpBuiltin].join(\" \").split(\" \"));\n CodeMirror.registerHelper(\"wordChars\", \"php\", /[\\\\w$]/);\n\n var phpConfig = {\n name: \"clike\",\n helperType: \"php\",\n keywords: keywords(phpKeywords),\n blockKeywords: keywords(\"catch do else elseif for foreach if switch try while finally\"),\n atoms: keywords(phpAtoms),\n builtin: keywords(phpBuiltin),\n multiLineStrings: true,\n hooks: {\n \"$\": function(stream) {\n stream.eatWhile(/[\\w\\$_]/);\n return \"variable-2\";\n },\n \"<\": function(stream, state) {\n if (stream.match(/<</)) {\n stream.eatWhile(/[\\w\\.]/);\n state.tokenize = heredoc(stream.current().slice(3));\n return state.tokenize(stream, state);\n }\n return false;\n },\n \"#\": function(stream) {\n while (!stream.eol() && !stream.match(\"?>\", false)) stream.next();\n return \"comment\";\n },\n \"/\": function(stream) {\n if (stream.eat(\"/\")) {\n while (!stream.eol() && !stream.match(\"?>\", false)) stream.next();\n return \"comment\";\n }\n return false;\n },\n '\"': function(stream, state) {\n if (!state.phpEncapsStack)\n state.phpEncapsStack = [];\n state.phpEncapsStack.push(0);\n state.tokenize = stringWithEscapes;\n return state.tokenize(stream, state);\n },\n \"{\": function(_stream, state) {\n if (state.phpEncapsStack && state.phpEncapsStack.length > 0)\n state.phpEncapsStack[state.phpEncapsStack.length - 1]++;\n return false;\n },\n \"}\": function(_stream, state) {\n if (state.phpEncapsStack && state.phpEncapsStack.length > 0)\n if (--state.phpEncapsStack[state.phpEncapsStack.length - 1] == 0)\n state.tokenize = stringWithEscapes;\n return false;\n }\n }\n };\n\n CodeMirror.defineMode(\"php\", function(config, parserConfig) {\n var htmlMode = CodeMirror.getMode(config, \"text/html\");\n var phpMode = CodeMirror.getMode(config, phpConfig);\n\n function dispatch(stream, state) {\n var isPHP = state.curMode == phpMode;\n if (stream.sol() && state.pending && state.pending != '\"' && state.pending != \"'\") state.pending = null;\n if (!isPHP) {\n if (stream.match(/^<\\?\\w*/)) {\n state.curMode = phpMode;\n state.curState = state.php;\n return \"meta\";\n }\n if (state.pending == '\"' || state.pending == \"'\") {\n while (!stream.eol() && stream.next() != state.pending) {}\n var style = \"string\";\n } else if (state.pending && stream.pos < state.pending.end) {\n stream.pos = state.pending.end;\n var style = state.pending.style;\n } else {\n var style = htmlMode.token(stream, state.curState);\n }\n if (state.pending) state.pending = null;\n var cur = stream.current(), openPHP = cur.search(/<\\?/), m;\n if (openPHP != -1) {\n if (style == \"string\" && (m = cur.match(/[\\'\\\"]$/)) && !/\\?>/.test(cur)) state.pending = m[0];\n else state.pending = {end: stream.pos, style: style};\n stream.backUp(cur.length - openPHP);\n }\n return style;\n } else if (isPHP && state.php.tokenize == null && stream.match(\"?>\")) {\n state.curMode = htmlMode;\n state.curState = state.html;\n return \"meta\";\n } else {\n return phpMode.token(stream, state.curState);\n }\n }\n\n return {\n startState: function() {\n var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);\n return {html: html,\n php: php,\n curMode: parserConfig.startOpen ? phpMode : htmlMode,\n curState: parserConfig.startOpen ? php : html,\n pending: null};\n },\n\n copyState: function(state) {\n var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),\n php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;\n if (state.curMode == htmlMode) cur = htmlNew;\n else cur = phpNew;\n return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,\n pending: state.pending};\n },\n\n token: dispatch,\n\n indent: function(state, textAfter) {\n if ((state.curMode != phpMode && /^\\s*<\\//.test(textAfter)) ||\n (state.curMode == phpMode && /^\\?>/.test(textAfter)))\n return htmlMode.indent(state.html, textAfter);\n return state.curMode.indent(state.curState, textAfter);\n },\n\n blockCommentStart: \"/*\",\n blockCommentEnd: \"*/\",\n lineComment: \"//\",\n\n innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }\n };\n }, \"htmlmixed\", \"clike\");\n\n CodeMirror.defineMIME(\"application/x-httpd-php\", \"php\");\n CodeMirror.defineMIME(\"application/x-httpd-php-open\", {name: \"php\", startOpen: true});\n CodeMirror.defineMIME(\"text/x-php\", phpConfig);\n});\n\n/*# sourceURL=cm_modes/php.js */";Runtime.cachedResources["cm_modes/python.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n function wordRegexp(words) {\n return new RegExp(\"^((\" + words.join(\")|(\") + \"))\\\\b\");\n }\n\n var wordOperators = wordRegexp([\"and\", \"or\", \"not\", \"is\", \"in\"]);\n var commonKeywords = [\"as\", \"assert\", \"break\", \"class\", \"continue\",\n \"def\", \"del\", \"elif\", \"else\", \"except\", \"finally\",\n \"for\", \"from\", \"global\", \"if\", \"import\",\n \"lambda\", \"pass\", \"raise\", \"return\",\n \"try\", \"while\", \"with\", \"yield\"];\n var commonBuiltins = [\"abs\", \"all\", \"any\", \"bin\", \"bool\", \"bytearray\", \"callable\", \"chr\",\n \"classmethod\", \"compile\", \"complex\", \"delattr\", \"dict\", \"dir\", \"divmod\",\n \"enumerate\", \"eval\", \"filter\", \"float\", \"format\", \"frozenset\",\n \"getattr\", \"globals\", \"hasattr\", \"hash\", \"help\", \"hex\", \"id\",\n \"input\", \"int\", \"isinstance\", \"issubclass\", \"iter\", \"len\",\n \"list\", \"locals\", \"map\", \"max\", \"memoryview\", \"min\", \"next\",\n \"object\", \"oct\", \"open\", \"ord\", \"pow\", \"property\", \"range\",\n \"repr\", \"reversed\", \"round\", \"set\", \"setattr\", \"slice\",\n \"sorted\", \"staticmethod\", \"str\", \"sum\", \"super\", \"tuple\",\n \"type\", \"vars\", \"zip\", \"__import__\", \"NotImplemented\",\n \"Ellipsis\", \"__debug__\"];\n var py2 = {builtins: [\"apply\", \"basestring\", \"buffer\", \"cmp\", \"coerce\", \"execfile\",\n \"file\", \"intern\", \"long\", \"raw_input\", \"reduce\", \"reload\",\n \"unichr\", \"unicode\", \"xrange\", \"False\", \"True\", \"None\"],\n keywords: [\"exec\", \"print\"]};\n var py3 = {builtins: [\"ascii\", \"bytes\", \"exec\", \"print\"],\n keywords: [\"nonlocal\", \"False\", \"True\", \"None\"]};\n\n CodeMirror.registerHelper(\"hintWords\", \"python\", commonKeywords.concat(commonBuiltins));\n\n function top(state) {\n return state.scopes[state.scopes.length - 1];\n }\n\n CodeMirror.defineMode(\"python\", function(conf, parserConf) {\n var ERRORCLASS = \"error\";\n\n var singleOperators = parserConf.singleOperators || new RegExp(\"^[\\\\+\\\\-\\\\*/%&|\\\\^~<>!]\");\n var singleDelimiters = parserConf.singleDelimiters || new RegExp(\"^[\\\\(\\\\)\\\\[\\\\]\\\\{\\\\}@,:`=;\\\\.]\");\n var doubleOperators = parserConf.doubleOperators || new RegExp(\"^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\\\*\\\\*))\");\n var doubleDelimiters = parserConf.doubleDelimiters || new RegExp(\"^((\\\\+=)|(\\\\-=)|(\\\\*=)|(%=)|(/=)|(&=)|(\\\\|=)|(\\\\^=))\");\n var tripleDelimiters = parserConf.tripleDelimiters || new RegExp(\"^((//=)|(>>=)|(<<=)|(\\\\*\\\\*=))\");\n var identifiers = parserConf.identifiers|| new RegExp(\"^[_A-Za-z][_A-Za-z0-9]*\");\n var hangingIndent = parserConf.hangingIndent || conf.indentUnit;\n\n var myKeywords = commonKeywords, myBuiltins = commonBuiltins;\n if(parserConf.extra_keywords != undefined){\n myKeywords = myKeywords.concat(parserConf.extra_keywords);\n }\n if(parserConf.extra_builtins != undefined){\n myBuiltins = myBuiltins.concat(parserConf.extra_builtins);\n }\n if (parserConf.version && parseInt(parserConf.version, 10) == 3) {\n myKeywords = myKeywords.concat(py3.keywords);\n myBuiltins = myBuiltins.concat(py3.builtins);\n var stringPrefixes = new RegExp(\"^(([rb]|(br))?('{3}|\\\"{3}|['\\\"]))\", \"i\");\n } else {\n myKeywords = myKeywords.concat(py2.keywords);\n myBuiltins = myBuiltins.concat(py2.builtins);\n var stringPrefixes = new RegExp(\"^(([rub]|(ur)|(br))?('{3}|\\\"{3}|['\\\"]))\", \"i\");\n }\n var keywords = wordRegexp(myKeywords);\n var builtins = wordRegexp(myBuiltins);\n\n // tokenizers\n function tokenBase(stream, state) {\n // Handle scope changes\n if (stream.sol() && top(state).type == \"py\") {\n var scopeOffset = top(state).offset;\n if (stream.eatSpace()) {\n var lineOffset = stream.indentation();\n if (lineOffset > scopeOffset)\n pushScope(stream, state, \"py\");\n else if (lineOffset < scopeOffset && dedent(stream, state))\n state.errorToken = true;\n return null;\n } else {\n var style = tokenBaseInner(stream, state);\n if (scopeOffset > 0 && dedent(stream, state))\n style += \" \" + ERRORCLASS;\n return style;\n }\n }\n return tokenBaseInner(stream, state);\n }\n\n function tokenBaseInner(stream, state) {\n if (stream.eatSpace()) return null;\n\n var ch = stream.peek();\n\n // Handle Comments\n if (ch == \"#\") {\n stream.skipToEnd();\n return \"comment\";\n }\n\n // Handle Number Literals\n if (stream.match(/^[0-9\\.]/, false)) {\n var floatLiteral = false;\n // Floats\n if (stream.match(/^\\d*\\.\\d+(e[\\+\\-]?\\d+)?/i)) { floatLiteral = true; }\n if (stream.match(/^\\d+\\.\\d*/)) { floatLiteral = true; }\n if (stream.match(/^\\.\\d+/)) { floatLiteral = true; }\n if (floatLiteral) {\n // Float literals may be \"imaginary\"\n stream.eat(/J/i);\n return \"number\";\n }\n // Integers\n var intLiteral = false;\n // Hex\n if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;\n // Binary\n if (stream.match(/^0b[01]+/i)) intLiteral = true;\n // Octal\n if (stream.match(/^0o[0-7]+/i)) intLiteral = true;\n // Decimal\n if (stream.match(/^[1-9]\\d*(e[\\+\\-]?\\d+)?/)) {\n // Decimal literals may be \"imaginary\"\n stream.eat(/J/i);\n // TODO - Can you have imaginary longs?\n intLiteral = true;\n }\n // Zero by itself with no other piece of number.\n if (stream.match(/^0(?![\\dx])/i)) intLiteral = true;\n if (intLiteral) {\n // Integer literals may be \"long\"\n stream.eat(/L/i);\n return \"number\";\n }\n }\n\n // Handle Strings\n if (stream.match(stringPrefixes)) {\n state.tokenize = tokenStringFactory(stream.current());\n return state.tokenize(stream, state);\n }\n\n // Handle operators and Delimiters\n if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))\n return null;\n\n if (stream.match(doubleOperators)\n || stream.match(singleOperators)\n || stream.match(wordOperators))\n return \"operator\";\n\n if (stream.match(singleDelimiters))\n return null;\n\n if (stream.match(keywords))\n return \"keyword\";\n\n if (stream.match(builtins))\n return \"builtin\";\n\n if (stream.match(/^(self|cls)\\b/))\n return \"variable-2\";\n\n if (stream.match(identifiers)) {\n if (state.lastToken == \"def\" || state.lastToken == \"class\")\n return \"def\";\n return \"variable\";\n }\n\n // Handle non-detected items\n stream.next();\n return ERRORCLASS;\n }\n\n function tokenStringFactory(delimiter) {\n while (\"rub\".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)\n delimiter = delimiter.substr(1);\n\n var singleline = delimiter.length == 1;\n var OUTCLASS = \"string\";\n\n function tokenString(stream, state) {\n while (!stream.eol()) {\n stream.eatWhile(/[^'\"\\\\]/);\n if (stream.eat(\"\\\\\")) {\n stream.next();\n if (singleline && stream.eol())\n return OUTCLASS;\n } else if (stream.match(delimiter)) {\n state.tokenize = tokenBase;\n return OUTCLASS;\n } else {\n stream.eat(/['\"]/);\n }\n }\n if (singleline) {\n if (parserConf.singleLineStringErrors)\n return ERRORCLASS;\n else\n state.tokenize = tokenBase;\n }\n return OUTCLASS;\n }\n tokenString.isString = true;\n return tokenString;\n }\n\n function pushScope(stream, state, type) {\n var offset = 0, align = null;\n if (type == \"py\") {\n while (top(state).type != \"py\")\n state.scopes.pop();\n }\n offset = top(state).offset + (type == \"py\" ? conf.indentUnit : hangingIndent);\n if (type != \"py\" && !stream.match(/^(\\s|#.*)*$/, false))\n align = stream.column() + 1;\n state.scopes.push({offset: offset, type: type, align: align});\n }\n\n function dedent(stream, state) {\n var indented = stream.indentation();\n while (top(state).offset > indented) {\n if (top(state).type != \"py\") return true;\n state.scopes.pop();\n }\n return top(state).offset != indented;\n }\n\n function tokenLexer(stream, state) {\n var style = state.tokenize(stream, state);\n var current = stream.current();\n\n // Handle '.' connected identifiers\n if (current == \".\") {\n style = stream.match(identifiers, false) ? null : ERRORCLASS;\n if (style == null && state.lastStyle == \"meta\") {\n // Apply 'meta' style to '.' connected identifiers when\n // appropriate.\n style = \"meta\";\n }\n return style;\n }\n\n // Handle decorators\n if (current == \"@\")\n return stream.match(identifiers, false) ? \"meta\" : ERRORCLASS;\n\n if ((style == \"variable\" || style == \"builtin\")\n && state.lastStyle == \"meta\")\n style = \"meta\";\n\n // Handle scope changes.\n if (current == \"pass\" || current == \"return\")\n state.dedent += 1;\n\n if (current == \"lambda\") state.lambda = true;\n if (current == \":\" && !state.lambda && top(state).type == \"py\")\n pushScope(stream, state, \"py\");\n\n var delimiter_index = current.length == 1 ? \"[({\".indexOf(current) : -1;\n if (delimiter_index != -1)\n pushScope(stream, state, \"])}\".slice(delimiter_index, delimiter_index+1));\n\n delimiter_index = \"])}\".indexOf(current);\n if (delimiter_index != -1) {\n if (top(state).type == current) state.scopes.pop();\n else return ERRORCLASS;\n }\n if (state.dedent > 0 && stream.eol() && top(state).type == \"py\") {\n if (state.scopes.length > 1) state.scopes.pop();\n state.dedent -= 1;\n }\n\n return style;\n }\n\n var external = {\n startState: function(basecolumn) {\n return {\n tokenize: tokenBase,\n scopes: [{offset: basecolumn || 0, type: \"py\", align: null}],\n lastStyle: null,\n lastToken: null,\n lambda: false,\n dedent: 0\n };\n },\n\n token: function(stream, state) {\n var addErr = state.errorToken;\n if (addErr) state.errorToken = false;\n var style = tokenLexer(stream, state);\n\n state.lastStyle = style;\n\n var current = stream.current();\n if (current && style)\n state.lastToken = current;\n\n if (stream.eol() && state.lambda)\n state.lambda = false;\n return addErr ? style + \" \" + ERRORCLASS : style;\n },\n\n indent: function(state, textAfter) {\n if (state.tokenize != tokenBase)\n return state.tokenize.isString ? CodeMirror.Pass : 0;\n\n var scope = top(state);\n var closing = textAfter && textAfter.charAt(0) == scope.type;\n if (scope.align != null)\n return scope.align - (closing ? 1 : 0);\n else if (closing && state.scopes.length > 1)\n return state.scopes[state.scopes.length - 2].offset;\n else\n return scope.offset;\n },\n\n lineComment: \"#\",\n fold: \"indent\"\n };\n return external;\n });\n\n CodeMirror.defineMIME(\"text/x-python\", \"python\");\n\n var words = function(str) { return str.split(\" \"); };\n\n CodeMirror.defineMIME(\"text/x-cython\", {\n name: \"python\",\n extra_keywords: words(\"by cdef cimport cpdef ctypedef enum except\"+\n \"extern gil include nogil property public\"+\n \"readonly struct union DEF IF ELIF ELSE\")\n });\n\n});\n\n/*# sourceURL=cm_modes/python.js */";Runtime.cachedResources["cm_modes/shell.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.defineMode('shell', function() {\n\n var words = {};\n function define(style, string) {\n var split = string.split(' ');\n for(var i = 0; i < split.length; i++) {\n words[split[i]] = style;\n }\n };\n\n // Atoms\n define('atom', 'true false');\n\n // Keywords\n define('keyword', 'if then do else elif while until for in esac fi fin ' +\n 'fil done exit set unset export function');\n\n // Commands\n define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +\n 'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +\n 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +\n 'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +\n 'touch vi vim wall wc wget who write yes zsh');\n\n function tokenBase(stream, state) {\n if (stream.eatSpace()) return null;\n\n var sol = stream.sol();\n var ch = stream.next();\n\n if (ch === '\\\\') {\n stream.next();\n return null;\n }\n if (ch === '\\'' || ch === '\"' || ch === '`') {\n state.tokens.unshift(tokenString(ch));\n return tokenize(stream, state);\n }\n if (ch === '#') {\n if (sol && stream.eat('!')) {\n stream.skipToEnd();\n return 'meta'; // 'comment'?\n }\n stream.skipToEnd();\n return 'comment';\n }\n if (ch === '$') {\n state.tokens.unshift(tokenDollar);\n return tokenize(stream, state);\n }\n if (ch === '+' || ch === '=') {\n return 'operator';\n }\n if (ch === '-') {\n stream.eat('-');\n stream.eatWhile(/\\w/);\n return 'attribute';\n }\n if (/\\d/.test(ch)) {\n stream.eatWhile(/\\d/);\n if(stream.eol() || !/\\w/.test(stream.peek())) {\n return 'number';\n }\n }\n stream.eatWhile(/[\\w-]/);\n var cur = stream.current();\n if (stream.peek() === '=' && /\\w+/.test(cur)) return 'def';\n return words.hasOwnProperty(cur) ? words[cur] : null;\n }\n\n function tokenString(quote) {\n return function(stream, state) {\n var next, end = false, escaped = false;\n while ((next = stream.next()) != null) {\n if (next === quote && !escaped) {\n end = true;\n break;\n }\n if (next === '$' && !escaped && quote !== '\\'') {\n escaped = true;\n stream.backUp(1);\n state.tokens.unshift(tokenDollar);\n break;\n }\n escaped = !escaped && next === '\\\\';\n }\n if (end || !escaped) {\n state.tokens.shift();\n }\n return (quote === '`' || quote === ')' ? 'quote' : 'string');\n };\n };\n\n var tokenDollar = function(stream, state) {\n if (state.tokens.length > 1) stream.eat('$');\n var ch = stream.next(), hungry = /\\w/;\n if (ch === '{') hungry = /[^}]/;\n if (ch === '(') {\n state.tokens[0] = tokenString(')');\n return tokenize(stream, state);\n }\n if (!/\\d/.test(ch)) {\n stream.eatWhile(hungry);\n stream.eat('}');\n }\n state.tokens.shift();\n return 'def';\n };\n\n function tokenize(stream, state) {\n return (state.tokens[0] || tokenBase) (stream, state);\n };\n\n return {\n startState: function() {return {tokens:[]};},\n token: function(stream, state) {\n return tokenize(stream, state);\n }\n };\n});\n\nCodeMirror.defineMIME('text/x-sh', 'shell');\n\n});\n\n/*# sourceURL=cm_modes/shell.js */";Runtime.cachedResources["cm_modes/livescript.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n/**\n * Link to the project's GitHub page:\n * https://github.com/duralog/CodeMirror\n */\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineMode('livescript', function(){\n var tokenBase = function(stream, state) {\n var next_rule = state.next || \"start\";\n if (next_rule) {\n state.next = state.next;\n var nr = Rules[next_rule];\n if (nr.splice) {\n for (var i$ = 0; i$ < nr.length; ++i$) {\n var r = nr[i$];\n if (r.regex && stream.match(r.regex)) {\n state.next = r.next || state.next;\n return r.token;\n }\n }\n stream.next();\n return 'error';\n }\n if (stream.match(r = Rules[next_rule])) {\n if (r.regex && stream.match(r.regex)) {\n state.next = r.next;\n return r.token;\n } else {\n stream.next();\n return 'error';\n }\n }\n }\n stream.next();\n return 'error';\n };\n var external = {\n startState: function(){\n return {\n next: 'start',\n lastToken: null\n };\n },\n token: function(stream, state){\n while (stream.pos == stream.start)\n var style = tokenBase(stream, state);\n state.lastToken = {\n style: style,\n indent: stream.indentation(),\n content: stream.current()\n };\n return style.replace(/\\./g, ' ');\n },\n indent: function(state){\n var indentation = state.lastToken.indent;\n if (state.lastToken.content.match(indenter)) {\n indentation += 2;\n }\n return indentation;\n }\n };\n return external;\n });\n\n var identifier = '(?![\\\\d\\\\s])[$\\\\w\\\\xAA-\\\\uFFDC](?:(?!\\\\s)[$\\\\w\\\\xAA-\\\\uFFDC]|-[A-Za-z])*';\n var indenter = RegExp('(?:[({[=:]|[-~]>|\\\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\\\s*all)?|const|var|let|new|catch(?:\\\\s*' + identifier + ')?))\\\\s*$');\n var keywordend = '(?![$\\\\w]|-[A-Za-z]|\\\\s*:(?![:=]))';\n var stringfill = {\n token: 'string',\n regex: '.+'\n };\n var Rules = {\n start: [\n {\n token: 'comment.doc',\n regex: '/\\\\*',\n next: 'comment'\n }, {\n token: 'comment',\n regex: '#.*'\n }, {\n token: 'keyword',\n regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend\n }, {\n token: 'constant.language',\n regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend\n }, {\n token: 'invalid.illegal',\n regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend\n }, {\n token: 'language.support.class',\n regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend\n }, {\n token: 'language.support.function',\n regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend\n }, {\n token: 'variable.language',\n regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend\n }, {\n token: 'identifier',\n regex: identifier + '\\\\s*:(?![:=])'\n }, {\n token: 'variable',\n regex: identifier\n }, {\n token: 'keyword.operator',\n regex: '(?:\\\\.{3}|\\\\s+\\\\?)'\n }, {\n token: 'keyword.variable',\n regex: '(?:@+|::|\\\\.\\\\.)',\n next: 'key'\n }, {\n token: 'keyword.operator',\n regex: '\\\\.\\\\s*',\n next: 'key'\n }, {\n token: 'string',\n regex: '\\\\\\\\\\\\S[^\\\\s,;)}\\\\]]*'\n }, {\n token: 'string.doc',\n regex: '\\'\\'\\'',\n next: 'qdoc'\n }, {\n token: 'string.doc',\n regex: '\"\"\"',\n next: 'qqdoc'\n }, {\n token: 'string',\n regex: '\\'',\n next: 'qstring'\n }, {\n token: 'string',\n regex: '\"',\n next: 'qqstring'\n }, {\n token: 'string',\n regex: '`',\n next: 'js'\n }, {\n token: 'string',\n regex: '<\\\\[',\n next: 'words'\n }, {\n token: 'string.regex',\n regex: '//',\n next: 'heregex'\n }, {\n token: 'string.regex',\n regex: '\\\\/(?:[^[\\\\/\\\\n\\\\\\\\]*(?:(?:\\\\\\\\.|\\\\[[^\\\\]\\\\n\\\\\\\\]*(?:\\\\\\\\.[^\\\\]\\\\n\\\\\\\\]*)*\\\\])[^[\\\\/\\\\n\\\\\\\\]*)*)\\\\/[gimy$]{0,4}',\n next: 'key'\n }, {\n token: 'constant.numeric',\n regex: '(?:0x[\\\\da-fA-F][\\\\da-fA-F_]*|(?:[2-9]|[12]\\\\d|3[0-6])r[\\\\da-zA-Z][\\\\da-zA-Z_]*|(?:\\\\d[\\\\d_]*(?:\\\\.\\\\d[\\\\d_]*)?|\\\\.\\\\d[\\\\d_]*)(?:e[+-]?\\\\d[\\\\d_]*)?[\\\\w$]*)'\n }, {\n token: 'lparen',\n regex: '[({[]'\n }, {\n token: 'rparen',\n regex: '[)}\\\\]]',\n next: 'key'\n }, {\n token: 'keyword.operator',\n regex: '\\\\S+'\n }, {\n token: 'text',\n regex: '\\\\s+'\n }\n ],\n heregex: [\n {\n token: 'string.regex',\n regex: '.*?//[gimy$?]{0,4}',\n next: 'start'\n }, {\n token: 'string.regex',\n regex: '\\\\s*#{'\n }, {\n token: 'comment.regex',\n regex: '\\\\s+(?:#.*)?'\n }, {\n token: 'string.regex',\n regex: '\\\\S+'\n }\n ],\n key: [\n {\n token: 'keyword.operator',\n regex: '[.?@!]+'\n }, {\n token: 'identifier',\n regex: identifier,\n next: 'start'\n }, {\n token: 'text',\n regex: '',\n next: 'start'\n }\n ],\n comment: [\n {\n token: 'comment.doc',\n regex: '.*?\\\\*/',\n next: 'start'\n }, {\n token: 'comment.doc',\n regex: '.+'\n }\n ],\n qdoc: [\n {\n token: 'string',\n regex: \".*?'''\",\n next: 'key'\n }, stringfill\n ],\n qqdoc: [\n {\n token: 'string',\n regex: '.*?\"\"\"',\n next: 'key'\n }, stringfill\n ],\n qstring: [\n {\n token: 'string',\n regex: '[^\\\\\\\\\\']*(?:\\\\\\\\.[^\\\\\\\\\\']*)*\\'',\n next: 'key'\n }, stringfill\n ],\n qqstring: [\n {\n token: 'string',\n regex: '[^\\\\\\\\\"]*(?:\\\\\\\\.[^\\\\\\\\\"]*)*\"',\n next: 'key'\n }, stringfill\n ],\n js: [\n {\n token: 'string',\n regex: '[^\\\\\\\\`]*(?:\\\\\\\\.[^\\\\\\\\`]*)*`',\n next: 'key'\n }, stringfill\n ],\n words: [\n {\n token: 'string',\n regex: '.*?\\\\]>',\n next: 'key'\n }, stringfill\n ]\n };\n for (var idx in Rules) {\n var r = Rules[idx];\n if (r.splice) {\n for (var i = 0, len = r.length; i < len; ++i) {\n var rr = r[i];\n if (typeof rr.regex === 'string') {\n Rules[idx][i].regex = new RegExp('^' + rr.regex);\n }\n }\n } else if (typeof rr.regex === 'string') {\n Rules[idx].regex = new RegExp('^' + r.regex);\n }\n }\n\n CodeMirror.defineMIME('text/x-livescript', 'livescript');\n\n});\n\n/*# sourceURL=cm_modes/livescript.js */";Runtime.cachedResources["cm_modes/clojure.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n/**\n * Author: Hans Engel\n * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)\n */\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.defineMode(\"clojure\", function (options) {\n var BUILTIN = \"builtin\", COMMENT = \"comment\", STRING = \"string\", CHARACTER = \"string-2\",\n ATOM = \"atom\", NUMBER = \"number\", BRACKET = \"bracket\", KEYWORD = \"keyword\", VAR = \"variable\";\n var INDENT_WORD_SKIP = options.indentUnit || 2;\n var NORMAL_INDENT_UNIT = options.indentUnit || 2;\n\n function makeKeywords(str) {\n var obj = {}, words = str.split(\" \");\n for (var i = 0; i < words.length; ++i) obj[words[i]] = true;\n return obj;\n }\n\n var atoms = makeKeywords(\"true false nil\");\n\n var keywords = makeKeywords(\n \"defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle\");\n\n var builtins = makeKeywords(\n \"* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> ->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? declare default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int rand-nth range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap *default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! set-agent-send-off-executor! some-> some->>\");\n\n var indentKeys = makeKeywords(\n // Built-ins\n \"ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch \" +\n\n // Binding forms\n \"let letfn binding loop for doseq dotimes when-let if-let \" +\n\n // Data structures\n \"defstruct struct-map assoc \" +\n\n // clojure.test\n \"testing deftest \" +\n\n // contrib\n \"handler-case handle dotrace deftrace\");\n\n var tests = {\n digit: /\\d/,\n digit_or_colon: /[\\d:]/,\n hex: /[0-9a-f]/i,\n sign: /[+-]/,\n exponent: /e/i,\n keyword_char: /[^\\s\\(\\[\\;\\)\\]]/,\n symbol: /[\\w*+!\\-\\._?:<>\\/\\xa1-\\uffff]/\n };\n\n function stateStack(indent, type, prev) { // represents a state stack object\n this.indent = indent;\n this.type = type;\n this.prev = prev;\n }\n\n function pushStack(state, indent, type) {\n state.indentStack = new stateStack(indent, type, state.indentStack);\n }\n\n function popStack(state) {\n state.indentStack = state.indentStack.prev;\n }\n\n function isNumber(ch, stream){\n // hex\n if ( ch === '0' && stream.eat(/x/i) ) {\n stream.eatWhile(tests.hex);\n return true;\n }\n\n // leading sign\n if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {\n stream.eat(tests.sign);\n ch = stream.next();\n }\n\n if ( tests.digit.test(ch) ) {\n stream.eat(ch);\n stream.eatWhile(tests.digit);\n\n if ( '.' == stream.peek() ) {\n stream.eat('.');\n stream.eatWhile(tests.digit);\n }\n\n if ( stream.eat(tests.exponent) ) {\n stream.eat(tests.sign);\n stream.eatWhile(tests.digit);\n }\n\n return true;\n }\n\n return false;\n }\n\n // Eat character that starts after backslash \\\n function eatCharacter(stream) {\n var first = stream.next();\n // Read special literals: backspace, newline, space, return.\n // Just read all lowercase letters.\n if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {\n return;\n }\n // Read unicode character: \\u1000 \\uA0a1\n if (first === \"u\") {\n stream.match(/[0-9a-z]{4}/i, true);\n }\n }\n\n return {\n startState: function () {\n return {\n indentStack: null,\n indentation: 0,\n mode: false\n };\n },\n\n token: function (stream, state) {\n if (state.indentStack == null && stream.sol()) {\n // update indentation, but only if indentStack is empty\n state.indentation = stream.indentation();\n }\n\n // skip spaces\n if (stream.eatSpace()) {\n return null;\n }\n var returnType = null;\n\n switch(state.mode){\n case \"string\": // multi-line string parsing mode\n var next, escaped = false;\n while ((next = stream.next()) != null) {\n if (next == \"\\\"\" && !escaped) {\n\n state.mode = false;\n break;\n }\n escaped = !escaped && next == \"\\\\\";\n }\n returnType = STRING; // continue on in string mode\n break;\n default: // default parsing mode\n var ch = stream.next();\n\n if (ch == \"\\\"\") {\n state.mode = \"string\";\n returnType = STRING;\n } else if (ch == \"\\\\\") {\n eatCharacter(stream);\n returnType = CHARACTER;\n } else if (ch == \"'\" && !( tests.digit_or_colon.test(stream.peek()) )) {\n returnType = ATOM;\n } else if (ch == \";\") { // comment\n stream.skipToEnd(); // rest of the line is a comment\n returnType = COMMENT;\n } else if (isNumber(ch,stream)){\n returnType = NUMBER;\n } else if (ch == \"(\" || ch == \"[\" || ch == \"{\" ) {\n var keyWord = '', indentTemp = stream.column(), letter;\n /**\n Either\n (indent-word ..\n (non-indent-word ..\n (;something else, bracket, etc.\n */\n\n if (ch == \"(\") while ((letter = stream.eat(tests.keyword_char)) != null) {\n keyWord += letter;\n }\n\n if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||\n /^(?:def|with)/.test(keyWord))) { // indent-word\n pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);\n } else { // non-indent word\n // we continue eating the spaces\n stream.eatSpace();\n if (stream.eol() || stream.peek() == \";\") {\n // nothing significant after\n // we restart indentation the user defined spaces after\n pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);\n } else {\n pushStack(state, indentTemp + stream.current().length, ch); // else we match\n }\n }\n stream.backUp(stream.current().length - 1); // undo all the eating\n\n returnType = BRACKET;\n } else if (ch == \")\" || ch == \"]\" || ch == \"}\") {\n returnType = BRACKET;\n if (state.indentStack != null && state.indentStack.type == (ch == \")\" ? \"(\" : (ch == \"]\" ? \"[\" :\"{\"))) {\n popStack(state);\n }\n } else if ( ch == \":\" ) {\n stream.eatWhile(tests.symbol);\n return ATOM;\n } else {\n stream.eatWhile(tests.symbol);\n\n if (keywords && keywords.propertyIsEnumerable(stream.current())) {\n returnType = KEYWORD;\n } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {\n returnType = BUILTIN;\n } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {\n returnType = ATOM;\n } else {\n returnType = VAR;\n }\n }\n }\n\n return returnType;\n },\n\n indent: function (state) {\n if (state.indentStack == null) return state.indentation;\n return state.indentStack.indent;\n },\n\n closeBrackets: {pairs: \"()[]{}\\\"\\\"\"},\n lineComment: \";;\"\n };\n});\n\nCodeMirror.defineMIME(\"text/x-clojure\", \"clojure\");\n\n});\n\n/*# sourceURL=cm_modes/clojure.js */";Runtime.cachedResources["cm_modes/stylus.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineMode(\"stylus\", function(config) {\n var indentUnit = config.indentUnit,\n tagKeywords = keySet(tagKeywords_),\n tagVariablesRegexp = /^(a|b|i|s|col|em)$/i,\n propertyKeywords = keySet(propertyKeywords_),\n nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_),\n valueKeywords = keySet(valueKeywords_),\n colorKeywords = keySet(colorKeywords_),\n documentTypes = keySet(documentTypes_),\n documentTypesRegexp = wordRegexp(documentTypes_),\n mediaFeatures = keySet(mediaFeatures_),\n mediaTypes = keySet(mediaTypes_),\n fontProperties = keySet(fontProperties_),\n operatorsRegexp = /^\\s*([.]{2,3}|&&|\\|\\||\\*\\*|[?!=:]?=|[-+*\\/%<>]=?|\\?:|\\~)/,\n wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_),\n blockKeywords = keySet(blockKeywords_),\n vendorPrefixesRegexp = new RegExp(/^\\-(moz|ms|o|webkit)-/i),\n commonAtoms = keySet(commonAtoms_),\n firstWordMatch = \"\",\n states = {},\n ch,\n style,\n type,\n override;\n\n /**\n * Tokenizers\n */\n function tokenBase(stream, state) {\n firstWordMatch = stream.string.match(/(^[\\w-]+\\s*=\\s*$)|(^\\s*[\\w-]+\\s*=\\s*[\\w-])|(^\\s*(\\.|#|@|\\$|\\&|\\[|\\d|\\+|::?|\\{|\\>|~|\\/)?\\s*[\\w-]*([a-z0-9-]|\\*|\\/\\*)(\\(|,)?)/);\n state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(/^\\s*/, \"\") : \"\";\n state.context.line.indent = stream.indentation();\n ch = stream.peek();\n\n // Line comment\n if (stream.match(\"//\")) {\n stream.skipToEnd();\n return [\"comment\", \"comment\"];\n }\n // Block comment\n if (stream.match(\"/*\")) {\n state.tokenize = tokenCComment;\n return tokenCComment(stream, state);\n }\n // String\n if (ch == \"\\\"\" || ch == \"'\") {\n stream.next();\n state.tokenize = tokenString(ch);\n return state.tokenize(stream, state);\n }\n // Def\n if (ch == \"@\") {\n stream.next();\n stream.eatWhile(/[\\w\\\\-]/);\n return [\"def\", stream.current()];\n }\n // ID selector or Hex color\n if (ch == \"#\") {\n stream.next();\n // Hex color\n if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) {\n return [\"atom\", \"atom\"];\n }\n // ID selector\n if (stream.match(/^[a-z][\\w-]*/i)) {\n return [\"builtin\", \"hash\"];\n }\n }\n // Vendor prefixes\n if (stream.match(vendorPrefixesRegexp)) {\n return [\"meta\", \"vendor-prefixes\"];\n }\n // Numbers\n if (stream.match(/^-?[0-9]?\\.?[0-9]/)) {\n stream.eatWhile(/[a-z%]/i);\n return [\"number\", \"unit\"];\n }\n // !important|optional\n if (ch == \"!\") {\n stream.next();\n return [stream.match(/^(important|optional)/i) ? \"keyword\": \"operator\", \"important\"];\n }\n // Class\n if (ch == \".\" && stream.match(/^\\.[a-z][\\w-]*/i)) {\n return [\"qualifier\", \"qualifier\"];\n }\n // url url-prefix domain regexp\n if (stream.match(documentTypesRegexp)) {\n if (stream.peek() == \"(\") state.tokenize = tokenParenthesized;\n return [\"property\", \"word\"];\n }\n // Mixins / Functions\n if (stream.match(/^[a-z][\\w-]*\\(/i)) {\n stream.backUp(1);\n return [\"keyword\", \"mixin\"];\n }\n // Block mixins\n if (stream.match(/^(\\+|-)[a-z][\\w-]*\\(/i)) {\n stream.backUp(1);\n return [\"keyword\", \"block-mixin\"];\n }\n // Parent Reference BEM naming\n if (stream.string.match(/^\\s*&/) && stream.match(/^[-_]+[a-z][\\w-]*/)) {\n return [\"qualifier\", \"qualifier\"];\n }\n // / Root Reference & Parent Reference\n if (stream.match(/^(\\/|&)(-|_|:|\\.|#|[a-z])/)) {\n stream.backUp(1);\n return [\"variable-3\", \"reference\"];\n }\n if (stream.match(/^&{1}\\s*$/)) {\n return [\"variable-3\", \"reference\"];\n }\n // Word operator\n if (stream.match(wordOperatorKeywordsRegexp)) {\n return [\"operator\", \"operator\"];\n }\n // Word\n if (stream.match(/^\\$?[-_]*[a-z0-9]+[\\w-]*/i)) {\n // Variable\n if (stream.match(/^(\\.|\\[)[\\w-\\'\\\"\\]]+/i, false)) {\n if (!wordIsTag(stream.current())) {\n stream.match(/\\./);\n return [\"variable-2\", \"variable-name\"];\n }\n }\n return [\"variable-2\", \"word\"];\n }\n // Operators\n if (stream.match(operatorsRegexp)) {\n return [\"operator\", stream.current()];\n }\n // Delimiters\n if (/[:;,{}\\[\\]\\(\\)]/.test(ch)) {\n stream.next();\n return [null, ch];\n }\n // Non-detected items\n stream.next();\n return [null, null];\n }\n\n /**\n * Token comment\n */\n function tokenCComment(stream, state) {\n var maybeEnd = false, ch;\n while ((ch = stream.next()) != null) {\n if (maybeEnd && ch == \"/\") {\n state.tokenize = null;\n break;\n }\n maybeEnd = (ch == \"*\");\n }\n return [\"comment\", \"comment\"];\n }\n\n /**\n * Token string\n */\n function tokenString(quote) {\n return function(stream, state) {\n var escaped = false, ch;\n while ((ch = stream.next()) != null) {\n if (ch == quote && !escaped) {\n if (quote == \")\") stream.backUp(1);\n break;\n }\n escaped = !escaped && ch == \"\\\\\";\n }\n if (ch == quote || !escaped && quote != \")\") state.tokenize = null;\n return [\"string\", \"string\"];\n };\n }\n\n /**\n * Token parenthesized\n */\n function tokenParenthesized(stream, state) {\n stream.next(); // Must be \"(\"\n if (!stream.match(/\\s*[\\\"\\')]/, false))\n state.tokenize = tokenString(\")\");\n else\n state.tokenize = null;\n return [null, \"(\"];\n }\n\n /**\n * Context management\n */\n function Context(type, indent, prev, line) {\n this.type = type;\n this.indent = indent;\n this.prev = prev;\n this.line = line || {firstWord: \"\", indent: 0};\n }\n\n function pushContext(state, stream, type, indent) {\n indent = indent >= 0 ? indent : indentUnit;\n state.context = new Context(type, stream.indentation() + indent, state.context);\n return type;\n }\n\n function popContext(state, currentIndent) {\n var contextIndent = state.context.indent - indentUnit;\n currentIndent = currentIndent || false;\n state.context = state.context.prev;\n if (currentIndent) state.context.indent = contextIndent;\n return state.context.type;\n }\n\n function pass(type, stream, state) {\n return states[state.context.type](type, stream, state);\n }\n\n function popAndPass(type, stream, state, n) {\n for (var i = n || 1; i > 0; i--)\n state.context = state.context.prev;\n return pass(type, stream, state);\n }\n\n\n /**\n * Parser\n */\n function wordIsTag(word) {\n return word.toLowerCase() in tagKeywords;\n }\n\n function wordIsProperty(word) {\n word = word.toLowerCase();\n return word in propertyKeywords || word in fontProperties;\n }\n\n function wordIsBlock(word) {\n return word.toLowerCase() in blockKeywords;\n }\n\n function wordIsVendorPrefix(word) {\n return word.toLowerCase().match(vendorPrefixesRegexp);\n }\n\n function wordAsValue(word) {\n var wordLC = word.toLowerCase();\n var override = \"variable-2\";\n if (wordIsTag(word)) override = \"tag\";\n else if (wordIsBlock(word)) override = \"block-keyword\";\n else if (wordIsProperty(word)) override = \"property\";\n else if (wordLC in valueKeywords || wordLC in commonAtoms) override = \"atom\";\n else if (wordLC == \"return\" || wordLC in colorKeywords) override = \"keyword\";\n\n // Font family\n else if (word.match(/^[A-Z]/)) override = \"string\";\n return override;\n }\n\n function typeIsBlock(type, stream) {\n return ((endOfLine(stream) && (type == \"{\" || type == \"]\" || type == \"hash\" || type == \"qualifier\")) || type == \"block-mixin\");\n }\n\n function typeIsInterpolation(type, stream) {\n return type == \"{\" && stream.match(/^\\s*\\$?[\\w-]+/i, false);\n }\n\n function typeIsPseudo(type, stream) {\n return type == \":\" && stream.match(/^[a-z-]+/, false);\n }\n\n function startOfLine(stream) {\n return stream.sol() || stream.string.match(new RegExp(\"^\\\\s*\" + escapeRegExp(stream.current())));\n }\n\n function endOfLine(stream) {\n return stream.eol() || stream.match(/^\\s*$/, false);\n }\n\n function firstWordOfLine(line) {\n var re = /^\\s*[-_]*[a-z0-9]+[\\w-]*/i;\n var result = typeof line == \"string\" ? line.match(re) : line.string.match(re);\n return result ? result[0].replace(/^\\s*/, \"\") : \"\";\n }\n\n\n /**\n * Block\n */\n states.block = function(type, stream, state) {\n if ((type == \"comment\" && startOfLine(stream)) ||\n (type == \",\" && endOfLine(stream)) ||\n type == \"mixin\") {\n return pushContext(state, stream, \"block\", 0);\n }\n if (typeIsInterpolation(type, stream)) {\n return pushContext(state, stream, \"interpolation\");\n }\n if (endOfLine(stream) && type == \"]\") {\n if (!/^\\s*(\\.|#|:|\\[|\\*|&)/.test(stream.string) && !wordIsTag(firstWordOfLine(stream))) {\n return pushContext(state, stream, \"block\", 0);\n }\n }\n if (typeIsBlock(type, stream, state)) {\n return pushContext(state, stream, \"block\");\n }\n if (type == \"}\" && endOfLine(stream)) {\n return pushContext(state, stream, \"block\", 0);\n }\n if (type == \"variable-name\") {\n if (stream.string.match(/^\\s?\\$[\\w-\\.\\[\\]\\'\\\"]+$/) || wordIsBlock(firstWordOfLine(stream))) {\n return pushContext(state, stream, \"variableName\");\n }\n else {\n return pushContext(state, stream, \"variableName\", 0);\n }\n }\n if (type == \"=\") {\n if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) {\n return pushContext(state, stream, \"block\", 0);\n }\n return pushContext(state, stream, \"block\");\n }\n if (type == \"*\") {\n if (endOfLine(stream) || stream.match(/\\s*(,|\\.|#|\\[|:|{)/,false)) {\n override = \"tag\";\n return pushContext(state, stream, \"block\");\n }\n }\n if (typeIsPseudo(type, stream)) {\n return pushContext(state, stream, \"pseudo\");\n }\n if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {\n return pushContext(state, stream, endOfLine(stream) ? \"block\" : \"atBlock\");\n }\n if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {\n return pushContext(state, stream, \"keyframes\");\n }\n if (/@extends?/.test(type)) {\n return pushContext(state, stream, \"extend\", 0);\n }\n if (type && type.charAt(0) == \"@\") {\n\n // Property Lookup\n if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1))) {\n override = \"variable-2\";\n return \"block\";\n }\n if (/(@import|@require|@charset)/.test(type)) {\n return pushContext(state, stream, \"block\", 0);\n }\n return pushContext(state, stream, \"block\");\n }\n if (type == \"reference\" && endOfLine(stream)) {\n return pushContext(state, stream, \"block\");\n }\n if (type == \"(\") {\n return pushContext(state, stream, \"parens\");\n }\n\n if (type == \"vendor-prefixes\") {\n return pushContext(state, stream, \"vendorPrefixes\");\n }\n if (type == \"word\") {\n var word = stream.current();\n override = wordAsValue(word);\n\n if (override == \"property\") {\n if (startOfLine(stream)) {\n return pushContext(state, stream, \"block\", 0);\n } else {\n override = \"atom\";\n return \"block\";\n }\n }\n\n if (override == \"tag\") {\n\n // tag is a css value\n if (/embed|menu|pre|progress|sub|table/.test(word)) {\n if (wordIsProperty(firstWordOfLine(stream))) {\n override = \"atom\";\n return \"block\";\n }\n }\n\n // tag is an attribute\n if (stream.string.match(new RegExp(\"\\\\[\\\\s*\" + word + \"|\" + word +\"\\\\s*\\\\]\"))) {\n override = \"atom\";\n return \"block\";\n }\n\n // tag is a variable\n if (tagVariablesRegexp.test(word)) {\n if ((startOfLine(stream) && stream.string.match(/=/)) ||\n (!startOfLine(stream) &&\n !stream.string.match(/^(\\s*\\.|#|\\&|\\[|\\/|>|\\*)/) &&\n !wordIsTag(firstWordOfLine(stream)))) {\n override = \"variable-2\";\n if (wordIsBlock(firstWordOfLine(stream))) return \"block\";\n return pushContext(state, stream, \"block\", 0);\n }\n }\n\n if (endOfLine(stream)) return pushContext(state, stream, \"block\");\n }\n if (override == \"block-keyword\") {\n override = \"keyword\";\n\n // Postfix conditionals\n if (stream.current(/(if|unless)/) && !startOfLine(stream)) {\n return \"block\";\n }\n return pushContext(state, stream, \"block\");\n }\n if (word == \"return\") return pushContext(state, stream, \"block\", 0);\n\n // Placeholder selector\n if (override == \"variable-2\" && stream.string.match(/^\\s?\\$[\\w-\\.\\[\\]\\'\\\"]+$/)) {\n return pushContext(state, stream, \"block\");\n }\n }\n return state.context.type;\n };\n\n\n /**\n * Parens\n */\n states.parens = function(type, stream, state) {\n if (type == \"(\") return pushContext(state, stream, \"parens\");\n if (type == \")\") {\n if (state.context.prev.type == \"parens\") {\n return popContext(state);\n }\n if ((stream.string.match(/^[a-z][\\w-]*\\(/i) && endOfLine(stream)) ||\n wordIsBlock(firstWordOfLine(stream)) ||\n /(\\.|#|:|\\[|\\*|&|>|~|\\+|\\/)/.test(firstWordOfLine(stream)) ||\n (!stream.string.match(/^-?[a-z][\\w-\\.\\[\\]\\'\\\"]*\\s*=/) &&\n wordIsTag(firstWordOfLine(stream)))) {\n return pushContext(state, stream, \"block\");\n }\n if (stream.string.match(/^[\\$-]?[a-z][\\w-\\.\\[\\]\\'\\\"]*\\s*=/) ||\n stream.string.match(/^\\s*(\\(|\\)|[0-9])/) ||\n stream.string.match(/^\\s+[a-z][\\w-]*\\(/i) ||\n stream.string.match(/^\\s+[\\$-]?[a-z]/i)) {\n return pushContext(state, stream, \"block\", 0);\n }\n if (endOfLine(stream)) return pushContext(state, stream, \"block\");\n else return pushContext(state, stream, \"block\", 0);\n }\n if (type && type.charAt(0) == \"@\" && wordIsProperty(stream.current().slice(1))) {\n override = \"variable-2\";\n }\n if (type == \"word\") {\n var word = stream.current();\n override = wordAsValue(word);\n if (override == \"tag\" && tagVariablesRegexp.test(word)) {\n override = \"variable-2\";\n }\n if (override == \"property\" || word == \"to\") override = \"atom\";\n }\n if (type == \"variable-name\") {\n return pushContext(state, stream, \"variableName\");\n }\n if (typeIsPseudo(type, stream)) {\n return pushContext(state, stream, \"pseudo\");\n }\n return state.context.type;\n };\n\n\n /**\n * Vendor prefixes\n */\n states.vendorPrefixes = function(type, stream, state) {\n if (type == \"word\") {\n override = \"property\";\n return pushContext(state, stream, \"block\", 0);\n }\n return popContext(state);\n };\n\n\n /**\n * Pseudo\n */\n states.pseudo = function(type, stream, state) {\n if (!wordIsProperty(firstWordOfLine(stream.string))) {\n stream.match(/^[a-z-]+/);\n override = \"variable-3\";\n if (endOfLine(stream)) return pushContext(state, stream, \"block\");\n return popContext(state);\n }\n return popAndPass(type, stream, state);\n };\n\n\n /**\n * atBlock\n */\n states.atBlock = function(type, stream, state) {\n if (type == \"(\") return pushContext(state, stream, \"atBlock_parens\");\n if (typeIsBlock(type, stream, state)) {\n return pushContext(state, stream, \"block\");\n }\n if (typeIsInterpolation(type, stream)) {\n return pushContext(state, stream, \"interpolation\");\n }\n if (type == \"word\") {\n var word = stream.current().toLowerCase();\n if (/^(only|not|and|or)$/.test(word))\n override = \"keyword\";\n else if (documentTypes.hasOwnProperty(word))\n override = \"tag\";\n else if (mediaTypes.hasOwnProperty(word))\n override = \"attribute\";\n else if (mediaFeatures.hasOwnProperty(word))\n override = \"property\";\n else if (nonStandardPropertyKeywords.hasOwnProperty(word))\n override = \"string-2\";\n else override = wordAsValue(stream.current());\n if (override == \"tag\" && endOfLine(stream)) {\n return pushContext(state, stream, \"block\");\n }\n }\n if (type == \"operator\" && /^(not|and|or)$/.test(stream.current())) {\n override = \"keyword\";\n }\n return state.context.type;\n };\n\n states.atBlock_parens = function(type, stream, state) {\n if (type == \"{\" || type == \"}\") return state.context.type;\n if (type == \")\") {\n if (endOfLine(stream)) return pushContext(state, stream, \"block\");\n else return pushContext(state, stream, \"atBlock\");\n }\n if (type == \"word\") {\n var word = stream.current().toLowerCase();\n override = wordAsValue(word);\n if (/^(max|min)/.test(word)) override = \"property\";\n if (override == \"tag\") {\n tagVariablesRegexp.test(word) ? override = \"variable-2\" : override = \"atom\";\n }\n return state.context.type;\n }\n return states.atBlock(type, stream, state);\n };\n\n\n /**\n * Keyframes\n */\n states.keyframes = function(type, stream, state) {\n if (stream.indentation() == \"0\" && ((type == \"}\" && startOfLine(stream)) || type == \"]\" || type == \"hash\"\n || type == \"qualifier\" || wordIsTag(stream.current()))) {\n return popAndPass(type, stream, state);\n }\n if (type == \"{\") return pushContext(state, stream, \"keyframes\");\n if (type == \"}\") {\n if (startOfLine(stream)) return popContext(state, true);\n else return pushContext(state, stream, \"keyframes\");\n }\n if (type == \"unit\" && /^[0-9]+\\%$/.test(stream.current())) {\n return pushContext(state, stream, \"keyframes\");\n }\n if (type == \"word\") {\n override = wordAsValue(stream.current());\n if (override == \"block-keyword\") {\n override = \"keyword\";\n return pushContext(state, stream, \"keyframes\");\n }\n }\n if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {\n return pushContext(state, stream, endOfLine(stream) ? \"block\" : \"atBlock\");\n }\n if (type == \"mixin\") {\n return pushContext(state, stream, \"block\", 0);\n }\n return state.context.type;\n };\n\n\n /**\n * Interpolation\n */\n states.interpolation = function(type, stream, state) {\n if (type == \"{\") popContext(state) && pushContext(state, stream, \"block\");\n if (type == \"}\") {\n if (stream.string.match(/^\\s*(\\.|#|:|\\[|\\*|&|>|~|\\+|\\/)/i) ||\n (stream.string.match(/^\\s*[a-z]/i) && wordIsTag(firstWordOfLine(stream)))) {\n return pushContext(state, stream, \"block\");\n }\n if (!stream.string.match(/^(\\{|\\s*\\&)/) ||\n stream.match(/\\s*[\\w-]/,false)) {\n return pushContext(state, stream, \"block\", 0);\n }\n return pushContext(state, stream, \"block\");\n }\n if (type == \"variable-name\") {\n return pushContext(state, stream, \"variableName\", 0);\n }\n if (type == \"word\") {\n override = wordAsValue(stream.current());\n if (override == \"tag\") override = \"atom\";\n }\n return state.context.type;\n };\n\n\n /**\n * Extend/s\n */\n states.extend = function(type, stream, state) {\n if (type == \"[\" || type == \"=\") return \"extend\";\n if (type == \"]\") return popContext(state);\n if (type == \"word\") {\n override = wordAsValue(stream.current());\n return \"extend\";\n }\n return popContext(state);\n };\n\n\n /**\n * Variable name\n */\n states.variableName = function(type, stream, state) {\n if (type == \"string\" || type == \"[\" || type == \"]\" || stream.current().match(/^(\\.|\\$)/)) {\n if (stream.current().match(/^\\.[\\w-]+/i)) override = \"variable-2\";\n return \"variableName\";\n }\n return popAndPass(type, stream, state);\n };\n\n\n return {\n startState: function(base) {\n return {\n tokenize: null,\n state: \"block\",\n context: new Context(\"block\", base || 0, null)\n };\n },\n token: function(stream, state) {\n if (!state.tokenize && stream.eatSpace()) return null;\n style = (state.tokenize || tokenBase)(stream, state);\n if (style && typeof style == \"object\") {\n type = style[1];\n style = style[0];\n }\n override = style;\n state.state = states[state.state](type, stream, state);\n return override;\n },\n indent: function(state, textAfter, line) {\n\n var cx = state.context,\n ch = textAfter && textAfter.charAt(0),\n indent = cx.indent,\n lineFirstWord = firstWordOfLine(textAfter),\n lineIndent = line.length - line.replace(/^\\s*/, \"\").length,\n prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : \"\",\n prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent;\n\n if (cx.prev &&\n (ch == \"}\" && (cx.type == \"block\" || cx.type == \"atBlock\" || cx.type == \"keyframes\") ||\n ch == \")\" && (cx.type == \"parens\" || cx.type == \"atBlock_parens\") ||\n ch == \"{\" && (cx.type == \"at\"))) {\n indent = cx.indent - indentUnit;\n cx = cx.prev;\n } else if (!(/(\\})/.test(ch))) {\n if (/@|\\$|\\d/.test(ch) ||\n /^\\{/.test(textAfter) ||\n/^\\s*\\/(\\/|\\*)/.test(textAfter) ||\n /^\\s*\\/\\*/.test(prevLineFirstWord) ||\n /^\\s*[\\w-\\.\\[\\]\\'\\\"]+\\s*(\\?|:|\\+)?=/i.test(textAfter) ||\n/^(\\+|-)?[a-z][\\w-]*\\(/i.test(textAfter) ||\n/^return/.test(textAfter) ||\n wordIsBlock(lineFirstWord)) {\n indent = lineIndent;\n } else if (/(\\.|#|:|\\[|\\*|&|>|~|\\+|\\/)/.test(ch) || wordIsTag(lineFirstWord)) {\n if (/\\,\\s*$/.test(prevLineFirstWord)) {\n indent = prevLineIndent;\n } else if (/^\\s+/.test(line) && (/(\\.|#|:|\\[|\\*|&|>|~|\\+|\\/)/.test(prevLineFirstWord) || wordIsTag(prevLineFirstWord))) {\n indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;\n } else {\n indent = lineIndent;\n }\n } else if (!/,\\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) || wordIsProperty(lineFirstWord))) {\n if (wordIsBlock(prevLineFirstWord)) {\n indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;\n } else if (/^\\{/.test(prevLineFirstWord)) {\n indent = lineIndent <= prevLineIndent ? lineIndent : prevLineIndent + indentUnit;\n } else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(prevLineFirstWord)) {\n indent = lineIndent >= prevLineIndent ? prevLineIndent : lineIndent;\n } else if (/^(\\.|#|:|\\[|\\*|&|@|\\+|\\-|>|~|\\/)/.test(prevLineFirstWord) ||\n /=\\s*$/.test(prevLineFirstWord) ||\n wordIsTag(prevLineFirstWord) ||\n /^\\$[\\w-\\.\\[\\]\\'\\\"]/.test(prevLineFirstWord)) {\n indent = prevLineIndent + indentUnit;\n } else {\n indent = lineIndent;\n }\n }\n }\n return indent;\n },\n electricChars: \"}\",\n lineComment: \"//\",\n fold: \"indent\"\n };\n });\n\n // developer.mozilla.org/en-US/docs/Web/HTML/Element\n var tagKeywords_ = [\"a\",\"abbr\",\"address\",\"area\",\"article\",\"aside\",\"audio\", \"b\", \"base\",\"bdi\", \"bdo\",\"bgsound\",\"blockquote\",\"body\",\"br\",\"button\",\"canvas\",\"caption\",\"cite\", \"code\",\"col\",\"colgroup\",\"data\",\"datalist\",\"dd\",\"del\",\"details\",\"dfn\",\"div\", \"dl\",\"dt\",\"em\",\"embed\",\"fieldset\",\"figcaption\",\"figure\",\"footer\",\"form\",\"h1\", \"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"head\",\"header\",\"hgroup\",\"hr\",\"html\",\"i\",\"iframe\", \"img\",\"input\",\"ins\",\"kbd\",\"keygen\",\"label\",\"legend\",\"li\",\"link\",\"main\",\"map\", \"mark\",\"marquee\",\"menu\",\"menuitem\",\"meta\",\"meter\",\"nav\",\"nobr\",\"noframes\", \"noscript\",\"object\",\"ol\",\"optgroup\",\"option\",\"output\",\"p\",\"param\",\"pre\", \"progress\",\"q\",\"rp\",\"rt\",\"ruby\",\"s\",\"samp\",\"script\",\"section\",\"select\", \"small\",\"source\",\"span\",\"strong\",\"style\",\"sub\",\"summary\",\"sup\",\"table\",\"tbody\",\"td\",\"textarea\",\"tfoot\",\"th\",\"thead\",\"time\",\"tr\",\"track\", \"u\",\"ul\",\"var\",\"video\"];\n\n // github.com/codemirror/CodeMirror/blob/master/mode/css/css.js\n var documentTypes_ = [\"domain\", \"regexp\", \"url\", \"url-prefix\"];\n var mediaTypes_ = [\"all\",\"aural\",\"braille\",\"handheld\",\"print\",\"projection\",\"screen\",\"tty\",\"tv\",\"embossed\"];\n var mediaFeatures_ = [\"width\",\"min-width\",\"max-width\",\"height\",\"min-height\",\"max-height\",\"device-width\",\"min-device-width\",\"max-device-width\",\"device-height\",\"min-device-height\",\"max-device-height\",\"aspect-ratio\",\"min-aspect-ratio\",\"max-aspect-ratio\",\"device-aspect-ratio\",\"min-device-aspect-ratio\",\"max-device-aspect-ratio\",\"color\",\"min-color\",\"max-color\",\"color-index\",\"min-color-index\",\"max-color-index\",\"monochrome\",\"min-monochrome\",\"max-monochrome\",\"resolution\",\"min-resolution\",\"max-resolution\",\"scan\",\"grid\"];\n var propertyKeywords_ = [\"align-content\",\"align-items\",\"align-self\",\"alignment-adjust\",\"alignment-baseline\",\"anchor-point\",\"animation\",\"animation-delay\",\"animation-direction\",\"animation-duration\",\"animation-fill-mode\",\"animation-iteration-count\",\"animation-name\",\"animation-play-state\",\"animation-timing-function\",\"appearance\",\"azimuth\",\"backface-visibility\",\"background\",\"background-attachment\",\"background-clip\",\"background-color\",\"background-image\",\"background-origin\",\"background-position\",\"background-repeat\",\"background-size\",\"baseline-shift\",\"binding\",\"bleed\",\"bookmark-label\",\"bookmark-level\",\"bookmark-state\",\"bookmark-target\",\"border\",\"border-bottom\",\"border-bottom-color\",\"border-bottom-left-radius\",\"border-bottom-right-radius\",\"border-bottom-style\",\"border-bottom-width\",\"border-collapse\",\"border-color\",\"border-image\",\"border-image-outset\",\"border-image-repeat\",\"border-image-slice\",\"border-image-source\",\"border-image-width\",\"border-left\",\"border-left-color\",\"border-left-style\",\"border-left-width\",\"border-radius\",\"border-right\",\"border-right-color\",\"border-right-style\",\"border-right-width\",\"border-spacing\",\"border-style\",\"border-top\",\"border-top-color\",\"border-top-left-radius\",\"border-top-right-radius\",\"border-top-style\",\"border-top-width\",\"border-width\",\"bottom\",\"box-decoration-break\",\"box-shadow\",\"box-sizing\",\"break-after\",\"break-before\",\"break-inside\",\"caption-side\",\"clear\",\"clip\",\"color\",\"color-profile\",\"column-count\",\"column-fill\",\"column-gap\",\"column-rule\",\"column-rule-color\",\"column-rule-style\",\"column-rule-width\",\"column-span\",\"column-width\",\"columns\",\"content\",\"counter-increment\",\"counter-reset\",\"crop\",\"cue\",\"cue-after\",\"cue-before\",\"cursor\",\"direction\",\"display\",\"dominant-baseline\",\"drop-initial-after-adjust\",\"drop-initial-after-align\",\"drop-initial-before-adjust\",\"drop-initial-before-align\",\"drop-initial-size\",\"drop-initial-value\",\"elevation\",\"empty-cells\",\"fit\",\"fit-position\",\"flex\",\"flex-basis\",\"flex-direction\",\"flex-flow\",\"flex-grow\",\"flex-shrink\",\"flex-wrap\",\"float\",\"float-offset\",\"flow-from\",\"flow-into\",\"font\",\"font-feature-settings\",\"font-family\",\"font-kerning\",\"font-language-override\",\"font-size\",\"font-size-adjust\",\"font-stretch\",\"font-style\",\"font-synthesis\",\"font-variant\",\"font-variant-alternates\",\"font-variant-caps\",\"font-variant-east-asian\",\"font-variant-ligatures\",\"font-variant-numeric\",\"font-variant-position\",\"font-weight\",\"grid\",\"grid-area\",\"grid-auto-columns\",\"grid-auto-flow\",\"grid-auto-position\",\"grid-auto-rows\",\"grid-column\",\"grid-column-end\",\"grid-column-start\",\"grid-row\",\"grid-row-end\",\"grid-row-start\",\"grid-template\",\"grid-template-areas\",\"grid-template-columns\",\"grid-template-rows\",\"hanging-punctuation\",\"height\",\"hyphens\",\"icon\",\"image-orientation\",\"image-rendering\",\"image-resolution\",\"inline-box-align\",\"justify-content\",\"left\",\"letter-spacing\",\"line-break\",\"line-height\",\"line-stacking\",\"line-stacking-ruby\",\"line-stacking-shift\",\"line-stacking-strategy\",\"list-style\",\"list-style-image\",\"list-style-position\",\"list-style-type\",\"margin\",\"margin-bottom\",\"margin-left\",\"margin-right\",\"margin-top\",\"marker-offset\",\"marks\",\"marquee-direction\",\"marquee-loop\",\"marquee-play-count\",\"marquee-speed\",\"marquee-style\",\"max-height\",\"max-width\",\"min-height\",\"min-width\",\"move-to\",\"nav-down\",\"nav-index\",\"nav-left\",\"nav-right\",\"nav-up\",\"object-fit\",\"object-position\",\"opacity\",\"order\",\"orphans\",\"outline\",\"outline-color\",\"outline-offset\",\"outline-style\",\"outline-width\",\"overflow\",\"overflow-style\",\"overflow-wrap\",\"overflow-x\",\"overflow-y\",\"padding\",\"padding-bottom\",\"padding-left\",\"padding-right\",\"padding-top\",\"page\",\"page-break-after\",\"page-break-before\",\"page-break-inside\",\"page-policy\",\"pause\",\"pause-after\",\"pause-before\",\"perspective\",\"perspective-origin\",\"pitch\",\"pitch-range\",\"play-during\",\"position\",\"presentation-level\",\"punctuation-trim\",\"quotes\",\"region-break-after\",\"region-break-before\",\"region-break-inside\",\"region-fragment\",\"rendering-intent\",\"resize\",\"rest\",\"rest-after\",\"rest-before\",\"richness\",\"right\",\"rotation\",\"rotation-point\",\"ruby-align\",\"ruby-overhang\",\"ruby-position\",\"ruby-span\",\"shape-image-threshold\",\"shape-inside\",\"shape-margin\",\"shape-outside\",\"size\",\"speak\",\"speak-as\",\"speak-header\",\"speak-numeral\",\"speak-punctuation\",\"speech-rate\",\"stress\",\"string-set\",\"tab-size\",\"table-layout\",\"target\",\"target-name\",\"target-new\",\"target-position\",\"text-align\",\"text-align-last\",\"text-decoration\",\"text-decoration-color\",\"text-decoration-line\",\"text-decoration-skip\",\"text-decoration-style\",\"text-emphasis\",\"text-emphasis-color\",\"text-emphasis-position\",\"text-emphasis-style\",\"text-height\",\"text-indent\",\"text-justify\",\"text-outline\",\"text-overflow\",\"text-shadow\",\"text-size-adjust\",\"text-space-collapse\",\"text-transform\",\"text-underline-position\",\"text-wrap\",\"top\",\"transform\",\"transform-origin\",\"transform-style\",\"transition\",\"transition-delay\",\"transition-duration\",\"transition-property\",\"transition-timing-function\",\"unicode-bidi\",\"vertical-align\",\"visibility\",\"voice-balance\",\"voice-duration\",\"voice-family\",\"voice-pitch\",\"voice-range\",\"voice-rate\",\"voice-stress\",\"voice-volume\",\"volume\",\"white-space\",\"widows\",\"width\",\"word-break\",\"word-spacing\",\"word-wrap\",\"z-index\",\"clip-path\",\"clip-rule\",\"mask\",\"enable-background\",\"filter\",\"flood-color\",\"flood-opacity\",\"lighting-color\",\"stop-color\",\"stop-opacity\",\"pointer-events\",\"color-interpolation\",\"color-interpolation-filters\",\"color-rendering\",\"fill\",\"fill-opacity\",\"fill-rule\",\"image-rendering\",\"marker\",\"marker-end\",\"marker-mid\",\"marker-start\",\"shape-rendering\",\"stroke\",\"stroke-dasharray\",\"stroke-dashoffset\",\"stroke-linecap\",\"stroke-linejoin\",\"stroke-miterlimit\",\"stroke-opacity\",\"stroke-width\",\"text-rendering\",\"baseline-shift\",\"dominant-baseline\",\"glyph-orientation-horizontal\",\"glyph-orientation-vertical\",\"text-anchor\",\"writing-mode\",\"font-smoothing\",\"osx-font-smoothing\"];\n var nonStandardPropertyKeywords_ = [\"scrollbar-arrow-color\",\"scrollbar-base-color\",\"scrollbar-dark-shadow-color\",\"scrollbar-face-color\",\"scrollbar-highlight-color\",\"scrollbar-shadow-color\",\"scrollbar-3d-light-color\",\"scrollbar-track-color\",\"shape-inside\",\"searchfield-cancel-button\",\"searchfield-decoration\",\"searchfield-results-button\",\"searchfield-results-decoration\",\"zoom\"];\n var fontProperties_ = [\"font-family\",\"src\",\"unicode-range\",\"font-variant\",\"font-feature-settings\",\"font-stretch\",\"font-weight\",\"font-style\"];\n var colorKeywords_ = [\"aliceblue\",\"antiquewhite\",\"aqua\",\"aquamarine\",\"azure\",\"beige\",\"bisque\",\"black\",\"blanchedalmond\",\"blue\",\"blueviolet\",\"brown\",\"burlywood\",\"cadetblue\",\"chartreuse\",\"chocolate\",\"coral\",\"cornflowerblue\",\"cornsilk\",\"crimson\",\"cyan\",\"darkblue\",\"darkcyan\",\"darkgoldenrod\",\"darkgray\",\"darkgreen\",\"darkkhaki\",\"darkmagenta\",\"darkolivegreen\",\"darkorange\",\"darkorchid\",\"darkred\",\"darksalmon\",\"darkseagreen\",\"darkslateblue\",\"darkslategray\",\"darkturquoise\",\"darkviolet\",\"deeppink\",\"deepskyblue\",\"dimgray\",\"dodgerblue\",\"firebrick\",\"floralwhite\",\"forestgreen\",\"fuchsia\",\"gainsboro\",\"ghostwhite\",\"gold\",\"goldenrod\",\"gray\",\"grey\",\"green\",\"greenyellow\",\"honeydew\",\"hotpink\",\"indianred\",\"indigo\",\"ivory\",\"khaki\",\"lavender\",\"lavenderblush\",\"lawngreen\",\"lemonchiffon\",\"lightblue\",\"lightcoral\",\"lightcyan\",\"lightgoldenrodyellow\",\"lightgray\",\"lightgreen\",\"lightpink\",\"lightsalmon\",\"lightseagreen\",\"lightskyblue\",\"lightslategray\",\"lightsteelblue\",\"lightyellow\",\"lime\",\"limegreen\",\"linen\",\"magenta\",\"maroon\",\"mediumaquamarine\",\"mediumblue\",\"mediumorchid\",\"mediumpurple\",\"mediumseagreen\",\"mediumslateblue\",\"mediumspringgreen\",\"mediumturquoise\",\"mediumvioletred\",\"midnightblue\",\"mintcream\",\"mistyrose\",\"moccasin\",\"navajowhite\",\"navy\",\"oldlace\",\"olive\",\"olivedrab\",\"orange\",\"orangered\",\"orchid\",\"palegoldenrod\",\"palegreen\",\"paleturquoise\",\"palevioletred\",\"papayawhip\",\"peachpuff\",\"peru\",\"pink\",\"plum\",\"powderblue\",\"purple\",\"rebeccapurple\",\"red\",\"rosybrown\",\"royalblue\",\"saddlebrown\",\"salmon\",\"sandybrown\",\"seagreen\",\"seashell\",\"sienna\",\"silver\",\"skyblue\",\"slateblue\",\"slategray\",\"snow\",\"springgreen\",\"steelblue\",\"tan\",\"teal\",\"thistle\",\"tomato\",\"turquoise\",\"violet\",\"wheat\",\"white\",\"whitesmoke\",\"yellow\",\"yellowgreen\"];\n var valueKeywords_ = [\"above\",\"absolute\",\"activeborder\",\"additive\",\"activecaption\",\"afar\",\"after-white-space\",\"ahead\",\"alias\",\"all\",\"all-scroll\",\"alphabetic\",\"alternate\",\"always\",\"amharic\",\"amharic-abegede\",\"antialiased\",\"appworkspace\",\"arabic-indic\",\"armenian\",\"asterisks\",\"attr\",\"auto\",\"avoid\",\"avoid-column\",\"avoid-page\",\"avoid-region\",\"background\",\"backwards\",\"baseline\",\"below\",\"bidi-override\",\"binary\",\"bengali\",\"blink\",\"block\",\"block-axis\",\"bold\",\"bolder\",\"border\",\"border-box\",\"both\",\"bottom\",\"break\",\"break-all\",\"break-word\",\"bullets\",\"button\",\"button-bevel\",\"buttonface\",\"buttonhighlight\",\"buttonshadow\",\"buttontext\",\"calc\",\"cambodian\",\"capitalize\",\"caps-lock-indicator\",\"caption\",\"captiontext\",\"caret\",\"cell\",\"center\",\"checkbox\",\"circle\",\"cjk-decimal\",\"cjk-earthly-branch\",\"cjk-heavenly-stem\",\"cjk-ideographic\",\"clear\",\"clip\",\"close-quote\",\"col-resize\",\"collapse\",\"column\",\"compact\",\"condensed\",\"contain\",\"content\",\"content-box\",\"context-menu\",\"continuous\",\"copy\",\"counter\",\"counters\",\"cover\",\"crop\",\"cross\",\"crosshair\",\"currentcolor\",\"cursive\",\"cyclic\",\"dashed\",\"decimal\",\"decimal-leading-zero\",\"default\",\"default-button\",\"destination-atop\",\"destination-in\",\"destination-out\",\"destination-over\",\"devanagari\",\"disc\",\"discard\",\"disclosure-closed\",\"disclosure-open\",\"document\",\"dot-dash\",\"dot-dot-dash\",\"dotted\",\"double\",\"down\",\"e-resize\",\"ease\",\"ease-in\",\"ease-in-out\",\"ease-out\",\"element\",\"ellipse\",\"ellipsis\",\"embed\",\"end\",\"ethiopic\",\"ethiopic-abegede\",\"ethiopic-abegede-am-et\",\"ethiopic-abegede-gez\",\"ethiopic-abegede-ti-er\",\"ethiopic-abegede-ti-et\",\"ethiopic-halehame-aa-er\",\"ethiopic-halehame-aa-et\",\"ethiopic-halehame-am-et\",\"ethiopic-halehame-gez\",\"ethiopic-halehame-om-et\",\"ethiopic-halehame-sid-et\",\"ethiopic-halehame-so-et\",\"ethiopic-halehame-ti-er\",\"ethiopic-halehame-ti-et\",\"ethiopic-halehame-tig\",\"ethiopic-numeric\",\"ew-resize\",\"expanded\",\"extends\",\"extra-condensed\",\"extra-expanded\",\"fantasy\",\"fast\",\"fill\",\"fixed\",\"flat\",\"flex\",\"footnotes\",\"forwards\",\"from\",\"geometricPrecision\",\"georgian\",\"graytext\",\"groove\",\"gujarati\",\"gurmukhi\",\"hand\",\"hangul\",\"hangul-consonant\",\"hebrew\",\"help\",\"hidden\",\"hide\",\"higher\",\"highlight\",\"highlighttext\",\"hiragana\",\"hiragana-iroha\",\"horizontal\",\"hsl\",\"hsla\",\"icon\",\"ignore\",\"inactiveborder\",\"inactivecaption\",\"inactivecaptiontext\",\"infinite\",\"infobackground\",\"infotext\",\"inherit\",\"initial\",\"inline\",\"inline-axis\",\"inline-block\",\"inline-flex\",\"inline-table\",\"inset\",\"inside\",\"intrinsic\",\"invert\",\"italic\",\"japanese-formal\",\"japanese-informal\",\"justify\",\"kannada\",\"katakana\",\"katakana-iroha\",\"keep-all\",\"khmer\",\"korean-hangul-formal\",\"korean-hanja-formal\",\"korean-hanja-informal\",\"landscape\",\"lao\",\"large\",\"larger\",\"left\",\"level\",\"lighter\",\"line-through\",\"linear\",\"linear-gradient\",\"lines\",\"list-item\",\"listbox\",\"listitem\",\"local\",\"logical\",\"loud\",\"lower\",\"lower-alpha\",\"lower-armenian\",\"lower-greek\",\"lower-hexadecimal\",\"lower-latin\",\"lower-norwegian\",\"lower-roman\",\"lowercase\",\"ltr\",\"malayalam\",\"match\",\"matrix\",\"matrix3d\",\"media-controls-background\",\"media-current-time-display\",\"media-fullscreen-button\",\"media-mute-button\",\"media-play-button\",\"media-return-to-realtime-button\",\"media-rewind-button\",\"media-seek-back-button\",\"media-seek-forward-button\",\"media-slider\",\"media-sliderthumb\",\"media-time-remaining-display\",\"media-volume-slider\",\"media-volume-slider-container\",\"media-volume-sliderthumb\",\"medium\",\"menu\",\"menulist\",\"menulist-button\",\"menulist-text\",\"menulist-textfield\",\"menutext\",\"message-box\",\"middle\",\"min-intrinsic\",\"mix\",\"mongolian\",\"monospace\",\"move\",\"multiple\",\"myanmar\",\"n-resize\",\"narrower\",\"ne-resize\",\"nesw-resize\",\"no-close-quote\",\"no-drop\",\"no-open-quote\",\"no-repeat\",\"none\",\"normal\",\"not-allowed\",\"nowrap\",\"ns-resize\",\"numbers\",\"numeric\",\"nw-resize\",\"nwse-resize\",\"oblique\",\"octal\",\"open-quote\",\"optimizeLegibility\",\"optimizeSpeed\",\"oriya\",\"oromo\",\"outset\",\"outside\",\"outside-shape\",\"overlay\",\"overline\",\"padding\",\"padding-box\",\"painted\",\"page\",\"paused\",\"persian\",\"perspective\",\"plus-darker\",\"plus-lighter\",\"pointer\",\"polygon\",\"portrait\",\"pre\",\"pre-line\",\"pre-wrap\",\"preserve-3d\",\"progress\",\"push-button\",\"radial-gradient\",\"radio\",\"read-only\",\"read-write\",\"read-write-plaintext-only\",\"rectangle\",\"region\",\"relative\",\"repeat\",\"repeating-linear-gradient\",\"repeating-radial-gradient\",\"repeat-x\",\"repeat-y\",\"reset\",\"reverse\",\"rgb\",\"rgba\",\"ridge\",\"right\",\"rotate\",\"rotate3d\",\"rotateX\",\"rotateY\",\"rotateZ\",\"round\",\"row-resize\",\"rtl\",\"run-in\",\"running\",\"s-resize\",\"sans-serif\",\"scale\",\"scale3d\",\"scaleX\",\"scaleY\",\"scaleZ\",\"scroll\",\"scrollbar\",\"se-resize\",\"searchfield\",\"searchfield-cancel-button\",\"searchfield-decoration\",\"searchfield-results-button\",\"searchfield-results-decoration\",\"semi-condensed\",\"semi-expanded\",\"separate\",\"serif\",\"show\",\"sidama\",\"simp-chinese-formal\",\"simp-chinese-informal\",\"single\",\"skew\",\"skewX\",\"skewY\",\"skip-white-space\",\"slide\",\"slider-horizontal\",\"slider-vertical\",\"sliderthumb-horizontal\",\"sliderthumb-vertical\",\"slow\",\"small\",\"small-caps\",\"small-caption\",\"smaller\",\"solid\",\"somali\",\"source-atop\",\"source-in\",\"source-out\",\"source-over\",\"space\",\"spell-out\",\"square\",\"square-button\",\"start\",\"static\",\"status-bar\",\"stretch\",\"stroke\",\"sub\",\"subpixel-antialiased\",\"super\",\"sw-resize\",\"symbolic\",\"symbols\",\"table\",\"table-caption\",\"table-cell\",\"table-column\",\"table-column-group\",\"table-footer-group\",\"table-header-group\",\"table-row\",\"table-row-group\",\"tamil\",\"telugu\",\"text\",\"text-bottom\",\"text-top\",\"textarea\",\"textfield\",\"thai\",\"thick\",\"thin\",\"threeddarkshadow\",\"threedface\",\"threedhighlight\",\"threedlightshadow\",\"threedshadow\",\"tibetan\",\"tigre\",\"tigrinya-er\",\"tigrinya-er-abegede\",\"tigrinya-et\",\"tigrinya-et-abegede\",\"to\",\"top\",\"trad-chinese-formal\",\"trad-chinese-informal\",\"translate\",\"translate3d\",\"translateX\",\"translateY\",\"translateZ\",\"transparent\",\"ultra-condensed\",\"ultra-expanded\",\"underline\",\"up\",\"upper-alpha\",\"upper-armenian\",\"upper-greek\",\"upper-hexadecimal\",\"upper-latin\",\"upper-norwegian\",\"upper-roman\",\"uppercase\",\"urdu\",\"url\",\"var\",\"vertical\",\"vertical-text\",\"visible\",\"visibleFill\",\"visiblePainted\",\"visibleStroke\",\"visual\",\"w-resize\",\"wait\",\"wave\",\"wider\",\"window\",\"windowframe\",\"windowtext\",\"words\",\"x-large\",\"x-small\",\"xor\",\"xx-large\",\"xx-small\",\"bicubic\",\"optimizespeed\",\"grayscale\",\"row\",\"row-reverse\",\"wrap\",\"wrap-reverse\",\"column-reverse\",\"flex-start\",\"flex-end\",\"space-between\",\"space-around\"];\n\n var wordOperatorKeywords_ = [\"in\",\"and\",\"or\",\"not\",\"is not\",\"is a\",\"is\",\"isnt\",\"defined\",\"if unless\"],\n blockKeywords_ = [\"for\",\"if\",\"else\",\"unless\", \"from\", \"to\"],\n commonAtoms_ = [\"null\",\"true\",\"false\",\"href\",\"title\",\"type\",\"not-allowed\",\"readonly\",\"disabled\"],\n commonDef_ = [\"@font-face\", \"@keyframes\", \"@media\", \"@viewport\", \"@page\", \"@host\", \"@supports\", \"@block\", \"@css\"];\n\n var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_,\n propertyKeywords_,nonStandardPropertyKeywords_,\n colorKeywords_,valueKeywords_,fontProperties_,\n wordOperatorKeywords_,blockKeywords_,\n commonAtoms_,commonDef_);\n\n function wordRegexp(words) {\n words = words.sort(function(a,b){return b > a;});\n return new RegExp(\"^((\" + words.join(\")|(\") + \"))\\\\b\");\n }\n\n function keySet(array) {\n var keys = {};\n for (var i = 0; i < array.length; ++i) keys[array[i]] = true;\n return keys;\n }\n\n function escapeRegExp(text) {\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n }\n\n CodeMirror.registerHelper(\"hintWords\", \"stylus\", hintWords);\n CodeMirror.defineMIME(\"text/x-styl\", \"stylus\");\n});\n\n/*# sourceURL=cm_modes/stylus.js */";Runtime.cachedResources["cm_modes/jsx.js"]="// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"), require(\"../xml/xml\"), require(\"../javascript/javascript\"))\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\", \"../xml/xml\", \"../javascript/javascript\"], mod)\n else // Plain browser env\n mod(CodeMirror)\n})(function(CodeMirror) {\n \"use strict\"\n\n function copyContext(context) {\n return {state: CodeMirror.copyState(context.mode, context.state),\n mode: context.mode,\n depth: context.depth,\n prev: context.prev && copyContext(context.prev)}\n }\n\n CodeMirror.defineMode(\"jsx\", function(config) {\n var xmlMode = CodeMirror.getMode(config, \"xml\")\n var jsMode = CodeMirror.getMode(config, \"javascript\")\n\n return {\n startState: function() {\n return {context: {state: CodeMirror.startState(jsMode), mode: jsMode}}\n },\n\n copyState: function(state) {\n return {context: copyContext(state.context)}\n },\n\n token: function(stream, state) {\n var cx = state.context\n if (cx.mode == xmlMode) {\n if (stream.peek() == \"{\") {\n xmlMode.skipAttribute(cx.state)\n state.context = {state: CodeMirror.startState(jsMode, xmlMode.indent(cx.state, \"\")),\n mode: jsMode,\n depth: 1,\n prev: state.context}\n return jsMode.token(stream, state.context.state)\n } else { // FIXME skip attribute\n var style = xmlMode.token(stream, cx.state), cur, brace\n if (/\\btag\\b/.test(style) && !cx.state.context && /^\\/?>$/.test(stream.current()))\n state.context = state.context.prev\n else if (!style && (brace = (cur = stream.current()).indexOf(\"{\")) > -1)\n stream.backUp(cur.length - brace)\n return style\n }\n } else { // jsMode\n if (stream.peek() == \"<\" && jsMode.expressionAllowed(stream, cx.state)) {\n jsMode.skipExpression(cx.state)\n state.context = {state: CodeMirror.startState(xmlMode, jsMode.indent(cx.state, \"\")),\n mode: xmlMode,\n prev: state.context}\n return xmlMode.token(stream, state.context.state)\n } else {\n var style = jsMode.token(stream, cx.state)\n if (!style && cx.depth != null) {\n var cur = stream.current()\n if (cur == \"{\") {\n cx.depth++\n } else if (cur == \"}\") {\n if (--cx.depth == 0) state.context = state.context.prev\n }\n }\n return style\n }\n }\n },\n\n indent: function(state, textAfter, fullLine) {\n return state.context.mode.indent(state.context.state, textAfter, fullLine)\n },\n\n innerMode: function(state) {\n return state.context[state.context.length - 1]\n }\n }\n }, \"xml\", \"javascript\")\n\n CodeMirror.defineMIME(\"text/jsx\", \"jsx\")\n})\n\n/*# sourceURL=cm_modes/jsx.js */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 2 1 1 1 1 1 1 1 1 | WebInspector.CookiesTable=function(expandable,refreshCallback,selectedCallback) {WebInspector.VBox.call(this);var readOnly=expandable;this._refreshCallback=refreshCallback;var columns=[{id:"name",title:WebInspector.UIString("Name"),sortable:true,disclosure:expandable,sort:WebInspector.DataGrid.Order.Ascending,longText:true,weight:24},{id:"value",title:WebInspector.UIString("Value"),sortable:true,longText:true,weight:34},{id:"domain",title:WebInspector.UIString("Domain"),sortable:true,weight:7},{id:"path",title:WebInspector.UIString("Path"),sortable:true,weight:7},{id:"expires",title:WebInspector.UIString("Expires / Max-Age"),sortable:true,weight:7},{id:"size",title:WebInspector.UIString("Size"),sortable:true,align:WebInspector.DataGrid.Align.Right,weight:7},{id:"httpOnly",title:WebInspector.UIString("HTTP"),sortable:true,align:WebInspector.DataGrid.Align.Center,weight:7},{id:"secure",title:WebInspector.UIString("Secure"),sortable:true,align:WebInspector.DataGrid.Align.Center,weight:7},{id:"sameSite",title:WebInspector.UIString("SameSite"),sortable:true,align:WebInspector.DataGrid.Align.Center,weight:7}];if(readOnly) this._dataGrid=new WebInspector.DataGrid(columns);else this._dataGrid=new WebInspector.DataGrid(columns,undefined,this._onDeleteCookie.bind(this),refreshCallback,this._onContextMenu.bind(this));this._dataGrid.setName("cookiesTable");this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._rebuildTable,this);if(selectedCallback) this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,selectedCallback,this);this._nextSelectedCookie=(null);this._dataGrid.asWidget().show(this.element);this._data=[];} WebInspector.CookiesTable.prototype={_clearAndRefresh:function(domain) {this.clear(domain);this._refresh();},_onContextMenu:function(contextMenu,node) {if(node===this._dataGrid.creationNode) return;var cookie=node.cookie;var domain=cookie.domain();if(domain) contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all from \"%s\"",domain),this._clearAndRefresh.bind(this,domain));contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all"),this._clearAndRefresh.bind(this,null));},setCookies:function(cookies) {this.setCookieFolders([{cookies:cookies}]);},setCookieFolders:function(cookieFolders) {this._data=cookieFolders;this._rebuildTable();},selectedCookie:function() {var node=this._dataGrid.selectedNode;return node?node.cookie:null;},clear:function(domain) {for(var i=0,length=this._data.length;i<length;++i){var cookies=this._data[i].cookies;for(var j=0,cookieCount=cookies.length;j<cookieCount;++j){if(!domain||cookies[j].domain()===domain) cookies[j].remove();}}},_rebuildTable:function() {var selectedCookie=this._nextSelectedCookie||this.selectedCookie();this._nextSelectedCookie=null;this._dataGrid.rootNode().removeChildren();for(var i=0;i<this._data.length;++i){var item=this._data[i];if(item.folderName){var groupData={name:item.folderName,value:"",domain:"",path:"",expires:"",size:this._totalSize(item.cookies),httpOnly:"",secure:"",sameSite:""};var groupNode=new WebInspector.DataGridNode(groupData);groupNode.selectable=true;this._dataGrid.rootNode().appendChild(groupNode);groupNode.element().classList.add("row-group");this._populateNode(groupNode,item.cookies,selectedCookie);groupNode.expand();}else this._populateNode(this._dataGrid.rootNode(),item.cookies,selectedCookie);}},_populateNode:function(parentNode,cookies,selectedCookie) {parentNode.removeChildren();if(!cookies) return;this._sortCookies(cookies);for(var i=0;i<cookies.length;++i){var cookie=cookies[i];var cookieNode=this._createGridNode(cookie);parentNode.appendChild(cookieNode);if(selectedCookie&&selectedCookie.name()===cookie.name()&&selectedCookie.domain()===cookie.domain()&&selectedCookie.path()===cookie.path()) cookieNode.select();}},_totalSize:function(cookies) {var totalSize=0;for(var i=0;cookies&&i<cookies.length;++i) totalSize+=cookies[i].size();return totalSize;},_sortCookies:function(cookies) {var sortDirection=this._dataGrid.isSortOrderAscending()?1:-1;function compareTo(getter,cookie1,cookie2) {return sortDirection*(getter.apply(cookie1)+"").compareTo(getter.apply(cookie2)+"");} function numberCompare(getter,cookie1,cookie2) {return sortDirection*(getter.apply(cookie1)-getter.apply(cookie2));} function expiresCompare(cookie1,cookie2) {if(cookie1.session()!==cookie2.session()) return sortDirection*(cookie1.session()?1:-1);if(cookie1.session()) return 0;if(cookie1.maxAge()&&cookie2.maxAge()) return sortDirection*(cookie1.maxAge()-cookie2.maxAge());if(cookie1.expires()&&cookie2.expires()) return sortDirection*(cookie1.expires()-cookie2.expires());return sortDirection*(cookie1.expires()?1:-1);} var comparator;switch(this._dataGrid.sortColumnIdentifier()){case"name":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.name);break;case"value":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.value);break;case"domain":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.domain);break;case"path":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.path);break;case"expires":comparator=expiresCompare;break;case"size":comparator=numberCompare.bind(null,WebInspector.Cookie.prototype.size);break;case"httpOnly":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.httpOnly);break;case"secure":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.secure);break;case"sameSite":comparator=compareTo.bind(null,WebInspector.Cookie.prototype.sameSite);break;default:compareTo.bind(null,WebInspector.Cookie.prototype.name);} cookies.sort(comparator);},_createGridNode:function(cookie) {var data={};data.name=cookie.name();data.value=cookie.value();if(cookie.type()===WebInspector.Cookie.Type.Request){data.domain=WebInspector.UIString("N/A");data.path=WebInspector.UIString("N/A");data.expires=WebInspector.UIString("N/A");}else{data.domain=cookie.domain()||"";data.path=cookie.path()||"";if(cookie.maxAge()) data.expires=Number.secondsToString(parseInt(cookie.maxAge(),10));else if(cookie.expires()) data.expires=new Date(cookie.expires()).toISOString();else data.expires=WebInspector.UIString("Session");} data.size=cookie.size();const checkmark="\u2713";data.httpOnly=(cookie.httpOnly()?checkmark:"");data.secure=(cookie.secure()?checkmark:"");data.sameSite=cookie.sameSite()||"";var node=new WebInspector.DataGridNode(data);node.cookie=cookie;node.selectable=true;return node;},_onDeleteCookie:function(node) {var cookie=node.cookie;var neighbour=node.traverseNextNode()||node.traversePreviousNode();if(neighbour) this._nextSelectedCookie=neighbour.cookie;cookie.remove();this._refresh();},_refresh:function() {if(this._refreshCallback) this._refreshCallback();},__proto__:WebInspector.VBox.prototype};WebInspector.FilmStripModel=function(tracingModel,zeroTime) {this._tracingModel=tracingModel;this._zeroTime=zeroTime||tracingModel.minimumRecordTime();this._frames=[];var browserProcess=tracingModel.processByName("Browser");if(!browserProcess) return;var mainThread=browserProcess.threadByName("CrBrowserMain");if(!mainThread) return;var events=mainThread.events();for(var i=0;i<events.length;++i){var event=events[i];if(event.startTime<this._zeroTime) continue;if(!event.hasCategory(WebInspector.FilmStripModel._category)) continue;if(event.name===WebInspector.FilmStripModel.TraceEvents.CaptureFrame){var data=event.args["data"];if(data) this._frames.push(WebInspector.FilmStripModel.Frame._fromEvent(this,event,this._frames.length));}else if(event.name===WebInspector.FilmStripModel.TraceEvents.Screenshot){this._frames.push(WebInspector.FilmStripModel.Frame._fromSnapshot(this,(event),this._frames.length));}}} WebInspector.FilmStripModel._category="disabled-by-default-devtools.screenshot";WebInspector.FilmStripModel.TraceEvents={CaptureFrame:"CaptureFrame",Screenshot:"Screenshot"} WebInspector.FilmStripModel.prototype={frames:function() {return this._frames;},zeroTime:function() {return this._zeroTime;},frameByTimestamp:function(timestamp) {var index=this._frames.upperBound(timestamp,(timestamp,frame)=>timestamp-frame.timestamp)-1;return index>=0?this._frames[index]:null;}} WebInspector.FilmStripModel.Frame=function(model,timestamp,index) {this._model=model;this.timestamp=timestamp;this.index=index;this._imageData=null;this._snapshot=null;} WebInspector.FilmStripModel.Frame._fromEvent=function(model,event,index) {var frame=new WebInspector.FilmStripModel.Frame(model,event.startTime,index);frame._imageData=event.args["data"];return frame;} WebInspector.FilmStripModel.Frame._fromSnapshot=function(model,snapshot,index) {var frame=new WebInspector.FilmStripModel.Frame(model,snapshot.startTime,index);frame._snapshot=snapshot;return frame;} WebInspector.FilmStripModel.Frame.prototype={model:function() {return this._model;},imageDataPromise:function() {if(this._imageData||!this._snapshot) return Promise.resolve(this._imageData);return(this._snapshot.objectPromise());}};WebInspector.FilmStripView=function() {WebInspector.HBox.call(this,true);this.registerRequiredCSS("components_lazy/filmStripView.css");this.contentElement.classList.add("film-strip-view");this._statusLabel=this.contentElement.createChild("div","label");this.reset();this.setMode(WebInspector.FilmStripView.Modes.TimeBased);} WebInspector.FilmStripView.Events={FrameSelected:"FrameSelected",FrameEnter:"FrameEnter",FrameExit:"FrameExit",} WebInspector.FilmStripView.Modes={TimeBased:"TimeBased",FrameBased:"FrameBased"} WebInspector.FilmStripView.prototype={setMode:function(mode) {this._mode=mode;this.contentElement.classList.toggle("time-based",mode===WebInspector.FilmStripView.Modes.TimeBased);this.update();},setModel:function(filmStripModel,zeroTime,spanTime) {this._model=filmStripModel;this._zeroTime=zeroTime;this._spanTime=spanTime;var frames=filmStripModel.frames();if(!frames.length){this.reset();return;} this.update();},createFrameElement:function(frame) {var time=frame.timestamp;var element=createElementWithClass("div","frame");element.title=WebInspector.UIString("Doubleclick to zoom image. Click to view preceding requests.");element.createChild("div","time").textContent=Number.millisToString(time-this._zeroTime);var imageElement=element.createChild("div","thumbnail").createChild("img");element.addEventListener("mousedown",this._onMouseEvent.bind(this,WebInspector.FilmStripView.Events.FrameSelected,time),false);element.addEventListener("mouseenter",this._onMouseEvent.bind(this,WebInspector.FilmStripView.Events.FrameEnter,time),false);element.addEventListener("mouseout",this._onMouseEvent.bind(this,WebInspector.FilmStripView.Events.FrameExit,time),false);element.addEventListener("dblclick",this._onDoubleClick.bind(this,frame),false);return frame.imageDataPromise().then(WebInspector.FilmStripView._setImageData.bind(null,imageElement)).then(returnElement);function returnElement() {return element;}},frameByTime:function(time) {function comparator(time,frame) {return time-frame.timestamp;} var frames=this._model.frames();var index=Math.max(frames.upperBound(time,comparator)-1,0);return frames[index];},update:function() {if(!this._model) return;var frames=this._model.frames();if(!frames.length) return;if(this._mode===WebInspector.FilmStripView.Modes.FrameBased){Promise.all(frames.map(this.createFrameElement.bind(this))).then(appendElements.bind(this));return;} var width=this.contentElement.clientWidth;var scale=this._spanTime/width;this.createFrameElement(frames[0]).then(continueWhenFrameImageLoaded.bind(this));function continueWhenFrameImageLoaded(element0) {var frameWidth=Math.ceil(WebInspector.measurePreferredSize(element0,this.contentElement).width);if(!frameWidth) return;var promises=[];for(var pos=frameWidth;pos<width;pos+=frameWidth){var time=pos*scale+this._zeroTime;promises.push(this.createFrameElement(this.frameByTime(time)).then(fixWidth));} Promise.all(promises).then(appendElements.bind(this));function fixWidth(element) {element.style.width=frameWidth+"px";return element;}} function appendElements(elements) {this.contentElement.removeChildren();for(var i=0;i<elements.length;++i) this.contentElement.appendChild(elements[i]);}},onResize:function() {if(this._mode===WebInspector.FilmStripView.Modes.FrameBased) return;this.update();},_onMouseEvent:function(eventName,timestamp) {this.dispatchEventToListeners(eventName,timestamp);},_onDoubleClick:function(filmStripFrame) {new WebInspector.FilmStripView.Dialog(filmStripFrame,this._zeroTime);},reset:function() {this._zeroTime=0;this.contentElement.removeChildren();this.contentElement.appendChild(this._statusLabel);},setStatusText:function(text) {this._statusLabel.textContent=text;},__proto__:WebInspector.HBox.prototype} WebInspector.FilmStripView._setImageData=function(imageElement,data) {if(data) imageElement.src="data:image/jpg;base64,"+data;} WebInspector.FilmStripView.Dialog=function(filmStripFrame,zeroTime) {WebInspector.VBox.call(this,true);this.registerRequiredCSS("components_lazy/filmStripDialog.css");this.contentElement.classList.add("filmstrip-dialog");this.contentElement.tabIndex=0;this._frames=filmStripFrame.model().frames();this._index=filmStripFrame.index;this._zeroTime=zeroTime||filmStripFrame.model().zeroTime();this._imageElement=this.contentElement.createChild("img");var footerElement=this.contentElement.createChild("div","filmstrip-dialog-footer");footerElement.createChild("div","flex-auto");var prevButton=createTextButton("\u25C0",this._onPrevFrame.bind(this),undefined,WebInspector.UIString("Previous frame"));footerElement.appendChild(prevButton);this._timeLabel=footerElement.createChild("div","filmstrip-dialog-label");var nextButton=createTextButton("\u25B6",this._onNextFrame.bind(this),undefined,WebInspector.UIString("Next frame"));footerElement.appendChild(nextButton);footerElement.createChild("div","flex-auto");this.contentElement.addEventListener("keydown",this._keyDown.bind(this),false);this.setDefaultFocusedElement(this.contentElement);this._render();} WebInspector.FilmStripView.Dialog.prototype={_resize:function() {if(!this._dialog){this._dialog=new WebInspector.Dialog();this.show(this._dialog.element);this._dialog.setWrapsContent(true);this._dialog.show();} this._dialog.contentResized();},_keyDown:function(event) {switch(event.keyIdentifier){case"Left":if(WebInspector.isMac()&&event.metaKey) this._onFirstFrame();else this._onPrevFrame();break;case"Right":if(WebInspector.isMac()&&event.metaKey) this._onLastFrame();else this._onNextFrame();break;case"Home":this._onFirstFrame();break;case"End":this._onLastFrame();break;}},_onPrevFrame:function() {if(this._index>0) --this._index;this._render();},_onNextFrame:function() {if(this._index<this._frames.length-1) ++this._index;this._render();},_onFirstFrame:function() {this._index=0;this._render();},_onLastFrame:function() {this._index=this._frames.length-1;this._render();},_render:function() {var frame=this._frames[this._index];this._timeLabel.textContent=Number.millisToString(frame.timestamp-this._zeroTime);return frame.imageDataPromise().then(WebInspector.FilmStripView._setImageData.bind(null,this._imageElement)).then(this._resize.bind(this));},__proto__:WebInspector.VBox.prototype};WebInspector.LineLevelProfile=function() {this._locationPool=new WebInspector.LiveLocationPool();this.reset();} WebInspector.LineLevelProfile.instance=function() {if(!WebInspector.LineLevelProfile._instance) WebInspector.LineLevelProfile._instance=new WebInspector.LineLevelProfile();return WebInspector.LineLevelProfile._instance;} WebInspector.LineLevelProfile.prototype={appendCPUProfile:function(profile) {var nodesToGo=[profile.profileHead];var sampleDuration=(profile.profileEndTime-profile.profileStartTime)/profile.totalHitCount;while(nodesToGo.length){var nodes=nodesToGo.pop().children;for(var i=0;i<nodes.length;++i){var node=nodes[i];nodesToGo.push(node);if(!node.url||!node.positionTicks) continue;var fileInfo=this._files.get(node.url);if(!fileInfo){fileInfo=new Map();this._files.set(node.url,fileInfo);} for(var j=0;j<node.positionTicks.length;++j){var lineInfo=node.positionTicks[j];var line=lineInfo.line;var time=lineInfo.ticks*sampleDuration;fileInfo.set(line,(fileInfo.get(line)||0)+time);}}} this._scheduleUpdate();},reset:function() {this._files=new Map();this._scheduleUpdate();},_scheduleUpdate:function() {if(this._updateTimer) return;this._updateTimer=setTimeout(()=>{this._updateTimer=null;this._doUpdate();},0);},_doUpdate:function() {this._locationPool.disposeAll();WebInspector.workspace.uiSourceCodes().forEach(uiSourceCode=>uiSourceCode.removeAllLineDecorations(WebInspector.LineLevelProfile.LineDecorator.type));var debuggerModel=WebInspector.DebuggerModel.fromTarget(WebInspector.targetManager.mainTarget());if(!debuggerModel) return;for(var fileInfo of this._files){var url=(fileInfo[0]);var uiSourceCode=WebInspector.workspace.uiSourceCodeForURL(url);for(var lineInfo of fileInfo[1]){var line=lineInfo[0]-1;var time=lineInfo[1];var rawLocation=debuggerModel.createRawLocationByURL(url,line,0);if(rawLocation) new WebInspector.LineLevelProfile.Presentation(rawLocation,time,this._locationPool);else if(uiSourceCode) uiSourceCode.addLineDecoration(line,WebInspector.LineLevelProfile.LineDecorator.type,time);}}}} WebInspector.LineLevelProfile.Presentation=function(rawLocation,time,locationPool) {this._time=time;WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation,this.updateLocation.bind(this),locationPool);} WebInspector.LineLevelProfile.Presentation.prototype={updateLocation:function(liveLocation) {if(this._uiLocation) this._uiLocation.uiSourceCode.removeLineDecoration(this._uiLocation.lineNumber,WebInspector.LineLevelProfile.LineDecorator.type);this._uiLocation=liveLocation.uiLocation();if(this._uiLocation) this._uiLocation.uiSourceCode.addLineDecoration(this._uiLocation.lineNumber,WebInspector.LineLevelProfile.LineDecorator.type,this._time);}} WebInspector.LineLevelProfile.LineDecorator=function() {} WebInspector.LineLevelProfile.LineDecorator.type="performance";WebInspector.LineLevelProfile.LineDecorator.prototype={decorate:function(uiSourceCode,textEditor) {var gutterType="CodeMirror-gutter-performance";var decorations=uiSourceCode.lineDecorations(WebInspector.LineLevelProfile.LineDecorator.type);textEditor.uninstallGutter(gutterType);if(!decorations) return;textEditor.installGutter(gutterType,false);for(var decoration of decorations.values()){var time=(decoration.data());var text=WebInspector.UIString("%.1f\xa0ms",time);var intensity=Number.constrain(Math.log10(1+2*time)/5,0.02,1);var element=createElementWithClass("div","text-editor-line-marker-performance");element.textContent=text;element.style.backgroundColor=`hsla(44,100%,50%,${intensity.toFixed(3)})`;textEditor.setGutterDecoration(decoration.line(),gutterType,element);}}};Runtime.cachedResources["components_lazy/filmStripDialog.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n flex: none !important;\n}\n\n.filmstrip-dialog {\n margin: 12px;\n}\n\n.filmstrip-dialog > img {\n border: 1px solid #ddd;\n max-height: 80vh;\n max-width: 80vw;\n}\n\n.filmstrip-dialog-footer {\n display: flex;\n align-items: center;\n margin-top: 10px;\n}\n\n.filmstrip-dialog-label {\n margin: 8px 8px;\n}\n\n/*# sourceURL=components_lazy/filmStripDialog.css */";Runtime.cachedResources["components_lazy/filmStripView.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.film-strip-view {\n overflow-x: auto;\n overflow-y: hidden;\n align-content: flex-start;\n min-height: 81px;\n}\n\n.film-strip-view.time-based .frame .time {\n display: none;\n}\n\n.film-strip-view .label {\n margin: auto;\n font-size: 18px;\n color: #999;\n}\n\n.film-strip-view .frame {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 4px;\n flex: none;\n cursor: pointer;\n}\n\n.film-strip-view .frame-limit-reached {\n font-size: 24px;\n color: #888;\n justify-content: center;\n display: inline-flex;\n flex-direction: column;\n flex: none;\n}\n\n.film-strip-view .frame .thumbnail {\n min-width: 24px;\n display: flex;\n flex-direction: row;\n align-items: center;\n pointer-events: none;\n margin: 4px 0 2px;\n border: 2px solid transparent;\n}\n\n.film-strip-view .frame:hover .thumbnail {\n border-color: #FBCA46;\n}\n\n.film-strip-view .frame .thumbnail img {\n height: auto;\n width: auto;\n max-width: 80px;\n max-height: 50px;\n pointer-events: none;\n box-shadow: 0 0 3px #bbb;\n flex: 0 0 auto;\n}\n\n.film-strip-view .frame:hover .thumbnail img {\n box-shadow: none;\n}\n\n.film-strip-view .frame .time {\n font-size: 10px;\n margin-top: 2px;\n}\n\n/*# sourceURL=components_lazy/filmStripView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.ConsoleContextSelector=function(selectElement) {this._selectElement=selectElement;this._optionByExecutionContext=new Map();WebInspector.targetManager.observeTargets(this);WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextCreated,this._onExecutionContextCreated,this);WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextChanged,this._onExecutionContextChanged,this);WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextDestroyed,this._onExecutionContextDestroyed,this);this._selectElement.addEventListener("change",this._executionContextChanged.bind(this),false);WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext,this._executionContextChangedExternally,this);} WebInspector.ConsoleContextSelector.prototype={_titleFor:function(executionContext) {var result;if(executionContext.isDefault){if(executionContext.frameId){var frame=executionContext.target().resourceTreeModel.frameForId(executionContext.frameId);result=frame?frame.displayName():executionContext.label();}else{result=executionContext.target().decorateLabel(executionContext.label());}}else{result="\u00a0\u00a0\u00a0\u00a0"+(executionContext.label()||executionContext.origin);} var maxLength=50;return result.trimMiddle(maxLength);},_executionContextCreated:function(executionContext) {if(executionContext.target().isServiceWorker()) return;var newOption=createElement("option");newOption.__executionContext=executionContext;newOption.text=this._titleFor(executionContext);this._optionByExecutionContext.set(executionContext,newOption);var options=this._selectElement.options;var contexts=Array.prototype.map.call(options,mapping);var index=contexts.lowerBound(executionContext,WebInspector.ExecutionContext.comparator) this._selectElement.insertBefore(newOption,options[index]);if(executionContext===WebInspector.context.flavor(WebInspector.ExecutionContext)) this._select(newOption);function mapping(option) {return option.__executionContext;}},_onExecutionContextCreated:function(event) {var executionContext=(event.data);this._executionContextCreated(executionContext);},_onExecutionContextChanged:function(event) {var executionContext=(event.data);var option=this._optionByExecutionContext.get(executionContext);if(option) option.text=this._titleFor(executionContext);},_executionContextDestroyed:function(executionContext) {var option=this._optionByExecutionContext.remove(executionContext);option.remove();},_onExecutionContextDestroyed:function(event) {var executionContext=(event.data);this._executionContextDestroyed(executionContext);},_executionContextChangedExternally:function(event) {var executionContext=(event.data);if(!executionContext) return;var options=this._selectElement.options;for(var i=0;i<options.length;++i){if(options[i].__executionContext===executionContext) this._select(options[i]);}},_executionContextChanged:function() {var option=this._selectedOption();var newContext=option?option.__executionContext:null;WebInspector.context.setFlavor(WebInspector.ExecutionContext,newContext);},targetAdded:function(target) {target.runtimeModel.executionContexts().forEach(this._executionContextCreated,this);},targetRemoved:function(target) {var executionContexts=this._optionByExecutionContext.keysArray();for(var i=0;i<executionContexts.length;++i){if(executionContexts[i].target()===target) this._executionContextDestroyed(executionContexts[i]);}},_select:function(option) {this._selectElement.selectedIndex=Array.prototype.indexOf.call((this._selectElement),option);},_selectedOption:function() {if(this._selectElement.selectedIndex>=0) return this._selectElement[this._selectElement.selectedIndex];return null;}};WebInspector.ConsoleViewMessage=function(consoleMessage,linkifier,nestingLevel) {this._message=consoleMessage;this._linkifier=linkifier;this._repeatCount=1;this._closeGroupDecorationCount=0;this._nestingLevel=nestingLevel;this._dataGrids=[];this._customFormatters={"array":this._formatParameterAsArray,"error":this._formatParameterAsError,"function":this._formatParameterAsFunction,"generator":this._formatParameterAsObject,"iterator":this._formatParameterAsObject,"map":this._formatParameterAsObject,"node":this._formatParameterAsNode,"object":this._formatParameterAsObject,"proxy":this._formatParameterAsObject,"set":this._formatParameterAsObject,"string":this._formatParameterAsString};this._previewFormatter=new WebInspector.RemoteObjectPreviewFormatter();this._searchRegex=null;} WebInspector.ConsoleViewMessage.prototype={_target:function() {return this.consoleMessage().target();},element:function() {return this.toMessageElement();},wasShown:function() {for(var i=0;this._dataGrids&&i<this._dataGrids.length;++i) this._dataGrids[i].updateWidths();this._isVisible=true;},onResize:function() {if(!this._isVisible) return;for(var i=0;this._dataGrids&&i<this._dataGrids.length;++i) this._dataGrids[i].onResize();},willHide:function() {this._isVisible=false;this._cachedHeight=this.contentElement().offsetHeight;},fastHeight:function() {if(this._cachedHeight) return this._cachedHeight;const defaultConsoleRowHeight=18;if(this._message.type===WebInspector.ConsoleMessage.MessageType.Table){var table=this._message.parameters[0];if(table&&table.preview) return defaultConsoleRowHeight*table.preview.properties.length;} return defaultConsoleRowHeight;},consoleMessage:function() {return this._message;},_formatMessage:function() {this._formattedMessage=createElement("span");WebInspector.appendStyle(this._formattedMessage,"components/objectValue.css");this._formattedMessage.className="console-message-text source-code";function linkifyRequest(title) {return WebInspector.Linkifier.linkifyUsingRevealer((this.request),title,this.request.url);} var consoleMessage=this._message;if(!this._messageElement){if(consoleMessage.source===WebInspector.ConsoleMessage.MessageSource.ConsoleAPI){switch(consoleMessage.type){case WebInspector.ConsoleMessage.MessageType.Trace:this._messageElement=this._format(consoleMessage.parameters||["console.trace()"]);break;case WebInspector.ConsoleMessage.MessageType.Clear:this._messageElement=createTextNode(WebInspector.UIString("Console was cleared"));this._formattedMessage.classList.add("console-info");break;case WebInspector.ConsoleMessage.MessageType.Assert:var args=[WebInspector.UIString("Assertion failed:")];if(consoleMessage.parameters) args=args.concat(consoleMessage.parameters);this._messageElement=this._format(args);break;case WebInspector.ConsoleMessage.MessageType.Dir:var obj=consoleMessage.parameters?consoleMessage.parameters[0]:undefined;var args=["%O",obj];this._messageElement=this._format(args);break;case WebInspector.ConsoleMessage.MessageType.Profile:case WebInspector.ConsoleMessage.MessageType.ProfileEnd:this._messageElement=this._format([consoleMessage.messageText]);break;default:if(consoleMessage.parameters&&consoleMessage.parameters.length===1&&consoleMessage.parameters[0].type==="string") this._messageElement=this._tryFormatAsError((consoleMessage.parameters[0].value));var args=consoleMessage.parameters||[consoleMessage.messageText];this._messageElement=this._messageElement||this._format(args);}}else if(consoleMessage.source===WebInspector.ConsoleMessage.MessageSource.Network){if(consoleMessage.request){this._messageElement=createElement("span");if(consoleMessage.level===WebInspector.ConsoleMessage.MessageLevel.Error||consoleMessage.level===WebInspector.ConsoleMessage.MessageLevel.RevokedError){this._messageElement.createTextChildren(consoleMessage.request.requestMethod," ");this._messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(consoleMessage.request,consoleMessage.request.url,consoleMessage.request.url));if(consoleMessage.request.failed) this._messageElement.createTextChildren(" ",consoleMessage.request.localizedFailDescription);else this._messageElement.createTextChildren(" ",String(consoleMessage.request.statusCode)," (",consoleMessage.request.statusText,")");}else{var fragment=WebInspector.linkifyStringAsFragmentWithCustomLinkifier(consoleMessage.messageText,linkifyRequest.bind(consoleMessage));this._messageElement.appendChild(fragment);}}else{var url=consoleMessage.url;if(url){var isExternal=!WebInspector.resourceForURL(url)&&!WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);this._anchorElement=WebInspector.linkifyURLAsNode(url,url,"console-message-url",isExternal);} this._messageElement=this._format([consoleMessage.messageText]);}}else{var args=consoleMessage.parameters||[consoleMessage.messageText];this._messageElement=this._format(args);}} if(consoleMessage.source!==WebInspector.ConsoleMessage.MessageSource.Network||consoleMessage.request){if(consoleMessage.scriptId){this._anchorElement=this._linkifyScriptId(consoleMessage.scriptId,consoleMessage.url||"",consoleMessage.line,consoleMessage.column);}else{if(consoleMessage.stackTrace&&consoleMessage.stackTrace.callFrames.length) this._anchorElement=this._linkifyStackTraceTopFrame(consoleMessage.stackTrace);else if(consoleMessage.url&&consoleMessage.url!=="undefined") this._anchorElement=this._linkifyLocation(consoleMessage.url,consoleMessage.line,consoleMessage.column);}} this._formattedMessage.appendChild(this._messageElement);if(this._anchorElement){this._anchorElement.appendChild(createTextNode(" "));this._formattedMessage.insertBefore(this._anchorElement,this._formattedMessage.firstChild);} var dumpStackTrace=!!consoleMessage.stackTrace&&(consoleMessage.source===WebInspector.ConsoleMessage.MessageSource.Network||consoleMessage.level===WebInspector.ConsoleMessage.MessageLevel.Error||consoleMessage.level===WebInspector.ConsoleMessage.MessageLevel.RevokedError||consoleMessage.type===WebInspector.ConsoleMessage.MessageType.Trace);if(dumpStackTrace){var treeOutline=new TreeOutline();treeOutline.element.classList.add("outline-disclosure","outline-disclosure-no-padding");var content=this._formattedMessage;var root=new TreeElement(content);root.toggleOnClick=true;root.selectable=false;content.treeElementForTest=root;treeOutline.appendChild(root);if(consoleMessage.type===WebInspector.ConsoleMessage.MessageType.Trace) root.expand();this._populateStackTraceTreeElement(root);this._formattedMessage=treeOutline.element;}},formattedMessage:function() {if(!this._formattedMessage) this._formatMessage();return this._formattedMessage;},_linkifyLocation:function(url,lineNumber,columnNumber) {var target=this._target();if(!target) return null;lineNumber=lineNumber?lineNumber-1:0;columnNumber=columnNumber?columnNumber-1:0;return this._linkifier.linkifyScriptLocation(target,null,url,lineNumber,columnNumber,"console-message-url");},_linkifyStackTraceTopFrame:function(stackTrace) {var target=this._target();if(!target) return null;return this._linkifier.linkifyStackTraceTopFrame(target,stackTrace,"console-message-url");},_linkifyScriptId:function(scriptId,url,lineNumber,columnNumber) {var target=this._target();if(!target) return null;lineNumber=lineNumber?lineNumber-1:0;columnNumber=columnNumber?columnNumber-1:0;return this._linkifier.linkifyScriptLocation(target,scriptId,url,lineNumber,columnNumber,"console-message-url");},_format:function(parameters) {var formattedResult=createElement("span");if(!parameters.length) return formattedResult;var target=this._target();for(var i=0;i<parameters.length;++i){if(parameters[i]instanceof WebInspector.RemoteObject) continue;if(!target){parameters[i]=WebInspector.RemoteObject.fromLocalObject(parameters[i]);continue;} if(typeof parameters[i]==="object") parameters[i]=target.runtimeModel.createRemoteObject(parameters[i]);else parameters[i]=target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameters[i]);} var shouldFormatMessage=WebInspector.RemoteObject.type(parameters[0])==="string"&&(this._message.type!==WebInspector.ConsoleMessage.MessageType.Result||this._message.level===WebInspector.ConsoleMessage.MessageLevel.Error||this._message.level===WebInspector.ConsoleMessage.MessageLevel.RevokedError);if(shouldFormatMessage){var result=this._formatWithSubstitutionString(parameters[0].description,parameters.slice(1),formattedResult);parameters=result.unusedSubstitutions;if(parameters.length) formattedResult.createTextChild(" ");} if(this._message.type===WebInspector.ConsoleMessage.MessageType.Table){formattedResult.appendChild(this._formatParameterAsTable(parameters));return formattedResult;} for(var i=0;i<parameters.length;++i){if(shouldFormatMessage&¶meters[i].type==="string") formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description));else formattedResult.appendChild(this._formatParameter(parameters[i],false,true));if(i<parameters.length-1) formattedResult.createTextChild(" ");} return formattedResult;},_formatParameter:function(output,forceObjectFormat,includePreview) {if(output.customPreview()){return(new WebInspector.CustomPreviewComponent(output)).element;} var type=forceObjectFormat?"object":(output.subtype||output.type);var formatter=this._customFormatters[type]||this._formatParameterAsValue;var span=createElement("span");span.className="object-value-"+type+" source-code";formatter.call(this,output,span,includePreview);return span;},_formatParameterAsValue:function(obj,elem) {elem.createTextChild(obj.description||"");if(obj.objectId) elem.addEventListener("contextmenu",this._contextMenuEventFired.bind(this,obj),false);},_formatParameterAsObject:function(obj,elem,includePreview) {this._formatParameterAsArrayOrObject(obj,elem,includePreview);},_formatParameterAsArrayOrObject:function(obj,elem,includePreview) {var titleElement=createElement("span");if(includePreview&&obj.preview){titleElement.classList.add("console-object-preview");this._previewFormatter.appendObjectPreview(titleElement,obj.preview);}else{if(obj.type==="function"){WebInspector.ObjectPropertiesSection.formatObjectAsFunction(obj,titleElement,false);titleElement.classList.add("object-value-function");}else{titleElement.createTextChild(obj.description||"");}} var note=titleElement.createChild("span","object-state-note");note.classList.add("info-note");note.title=WebInspector.UIString("Object value at left was snapshotted when logged, value below was evaluated just now.");var section=new WebInspector.ObjectPropertiesSection(obj,titleElement);section.enableContextMenu();elem.appendChild(section.element);section.element.classList.add("console-view-object-properties-section");},_formatParameterAsFunction:function(func,element,includePreview) {WebInspector.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));function formatTargetFunction(targetFunction) {var functionElement=createElement("span") WebInspector.ObjectPropertiesSection.formatObjectAsFunction(targetFunction,functionElement,true,includePreview);element.appendChild(functionElement);if(targetFunction!==func){var note=element.createChild("span","object-info-state-note");note.title=WebInspector.UIString("Function was resolved from bound function.");} element.addEventListener("contextmenu",this._contextMenuEventFired.bind(this,targetFunction),false);}},_contextMenuEventFired:function(obj,event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems(obj);contextMenu.show();},_renderPropertyPreviewOrAccessor:function(object,propertyPath) {var property=propertyPath.peekLast();if(property.type==="accessor") return this._formatAsAccessorProperty(object,propertyPath.map(property=>property.name),false);return this._previewFormatter.renderPropertyPreview(property.type,(property.subtype),property.value);},_formatParameterAsNode:function(object,elem) {WebInspector.Renderer.renderPromise(object).then(appendRenderer.bind(this),failedToRender.bind(this));function appendRenderer(rendererElement) {elem.appendChild(rendererElement);this._formattedParameterAsNodeForTest();} function failedToRender() {this._formatParameterAsObject(object,elem,false);}},_formattedParameterAsNodeForTest:function() {},useArrayPreviewInFormatter:function(array) {return this._message.type!==WebInspector.ConsoleMessage.MessageType.DirXML;},_formatParameterAsArray:function(array,elem) {var maxFlatArrayLength=100;if(this.useArrayPreviewInFormatter(array)||array.arrayLength()>maxFlatArrayLength) this._formatParameterAsArrayOrObject(array,elem,this.useArrayPreviewInFormatter(array)||array.arrayLength()<=maxFlatArrayLength);else array.getAllProperties(false,this._printArray.bind(this,array,elem));},_formatParameterAsTable:function(parameters) {var element=createElementWithClass("div","console-message-formatted-table");var table=parameters[0];if(!table||!table.preview) return element;var columnNames=[];var preview=table.preview;var rows=[];for(var i=0;i<preview.properties.length;++i){var rowProperty=preview.properties[i];var rowPreview=rowProperty.valuePreview;if(!rowPreview) continue;var rowValue={};const maxColumnsToRender=20;for(var j=0;j<rowPreview.properties.length;++j){var cellProperty=rowPreview.properties[j];var columnRendered=columnNames.indexOf(cellProperty.name)!=-1;if(!columnRendered){if(columnNames.length===maxColumnsToRender) continue;columnRendered=true;columnNames.push(cellProperty.name);} if(columnRendered){var cellElement=this._renderPropertyPreviewOrAccessor(table,[rowProperty,cellProperty]);cellElement.classList.add("console-message-nowrap-below");rowValue[cellProperty.name]=cellElement;}} rows.push([rowProperty.name,rowValue]);} var flatValues=[];for(var i=0;i<rows.length;++i){var rowName=rows[i][0];var rowValue=rows[i][1];flatValues.push(rowName);for(var j=0;j<columnNames.length;++j) flatValues.push(rowValue[columnNames[j]]);} var dataGridContainer=element.createChild("span");element.appendChild(this._formatParameter(table,true,false));if(!flatValues.length) return element;columnNames.unshift(WebInspector.UIString("(index)"));var dataGrid=WebInspector.SortableDataGrid.create(columnNames,flatValues);dataGrid.renderInline();dataGridContainer.appendChild(dataGrid.element);this._dataGrids.push(dataGrid);return element;},_formatParameterAsString:function(output,elem) {var span=createElement("span");span.className="object-value-string source-code";span.appendChild(WebInspector.linkifyStringAsFragment(output.description||""));elem.classList.remove("object-value-string");elem.createTextChild("\"");elem.appendChild(span);elem.createTextChild("\"");},_formatParameterAsError:function(output,elem) {var span=elem.createChild("span","object-value-error source-code");var text=output.description||"";var lines=text.split("\n",2);span.appendChild(WebInspector.linkifyStringAsFragment(lines[0]));if(lines.length>1){var detailedLink=elem.createChild("a");detailedLink.textContent="(\u2026)";function showDetailed(event) {span.removeChildren();detailedLink.remove();span.appendChild(WebInspector.linkifyStringAsFragment(text));event.consume(true);} detailedLink._showDetailedForTest=showDetailed.bind(null,new MouseEvent("click"));detailedLink.addEventListener("click",showDetailed,false);}},_printArray:function(array,elem,properties) {if(!properties){this._formatParameterAsObject(array,elem,false);return;} var elements={};for(var i=0;i<properties.length;++i){var property=properties[i];var name=property.name;if(isNaN(name)) continue;if(property.getter) elements[name]=this._formatAsAccessorProperty(array,[name],true);else if(property.value) elements[name]=this._formatAsArrayEntry(property.value);} elem.createTextChild("[");var lastNonEmptyIndex=-1;function appendUndefined(elem,index) {if(index-lastNonEmptyIndex<=1) return;var span=elem.createChild("span","object-value-undefined");span.textContent=WebInspector.UIString("undefined × %d",index-lastNonEmptyIndex-1);} var length=array.arrayLength();for(var i=0;i<length;++i){var element=elements[i];if(!element) continue;if(i-lastNonEmptyIndex>1){appendUndefined(elem,i);elem.createTextChild(", ");} elem.appendChild(element);lastNonEmptyIndex=i;if(i<length-1) elem.createTextChild(", ");} appendUndefined(elem,length);elem.createTextChild("]");elem.addEventListener("contextmenu",this._contextMenuEventFired.bind(this,array),false);},_formatAsArrayEntry:function(output) {return this._formatParameter(output,output.subtype==="array",false);},_formatAsAccessorProperty:function(object,propertyPath,isArrayEntry) {var rootElement=WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(object,propertyPath,onInvokeGetterClick.bind(this));function onInvokeGetterClick(result,wasThrown) {if(!result) return;rootElement.removeChildren();if(wasThrown){var element=rootElement.createChild("span","error-message");element.textContent=WebInspector.UIString("<exception>");element.title=(result.description);}else if(isArrayEntry){rootElement.appendChild(this._formatAsArrayEntry(result));}else{const maxLength=100;var type=result.type;var subtype=result.subtype;var description="";if(type!=="function"&&result.description){if(type==="string"||subtype==="regexp") description=result.description.trimMiddle(maxLength);else description=result.description.trimEnd(maxLength);} rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type,subtype,description));}} return rootElement;},_formatWithSubstitutionString:function(format,parameters,formattedResult) {var formatters={};function parameterFormatter(force,obj) {return this._formatParameter(obj,force,false);} function stringFormatter(obj) {return obj.description;} function floatFormatter(obj) {if(typeof obj.value!=="number") return"NaN";return obj.value;} function integerFormatter(obj) {if(typeof obj.value!=="number") return"NaN";return Math.floor(obj.value);} function bypassFormatter(obj) {return(obj instanceof Node)?obj:"";} var currentStyle=null;function styleFormatter(obj) {currentStyle={};var buffer=createElement("span");buffer.setAttribute("style",obj.description);for(var i=0;i<buffer.style.length;i++){var property=buffer.style[i];var value=buffer.style.getPropertyValue(property);if(!value.startsWith("url(")&&isWhitelistedProperty(property)) currentStyle[property]=buffer.style[property];}} function isWhitelistedProperty(property) {var prefixes=["background","border","color","font","line","margin","padding","text","-webkit-background","-webkit-border","-webkit-font","-webkit-margin","-webkit-padding","-webkit-text"];for(var i=0;i<prefixes.length;i++){if(property.startsWith(prefixes[i])) return true;} return false;} formatters.o=parameterFormatter.bind(this,false);formatters.s=stringFormatter;formatters.f=floatFormatter;formatters.i=integerFormatter;formatters.d=integerFormatter;formatters.c=styleFormatter;formatters.O=parameterFormatter.bind(this,true);formatters._=bypassFormatter;function append(a,b) {if(b instanceof Node) a.appendChild(b);else if(typeof b!=="undefined"){var toAppend=WebInspector.linkifyStringAsFragment(String(b));if(currentStyle){var wrapper=createElement("span");wrapper.appendChild(toAppend);applyCurrentStyle(wrapper);for(var i=0;i<wrapper.children.length;++i) applyCurrentStyle(wrapper.children[i]);toAppend=wrapper;} a.appendChild(toAppend);} return a;} function applyCurrentStyle(element) {for(var key in currentStyle) element.style[key]=currentStyle[key];} return String.format(format,parameters,formatters,formattedResult,append);},matchesFilterRegex:function(regexObject) {regexObject.lastIndex=0;var text=this.searchableElement().deepTextContent();if(this._anchorElement) text+=" "+this._anchorElement.textContent;return regexObject.test(text);},updateTimestamp:function(show) {if(!this._formattedMessage) return;if(show&&!this.timestampElement){this.timestampElement=createElementWithClass("span","console-timestamp");this.timestampElement.textContent=(new Date(this._message.timestamp)).toConsoleTime()+" ";var afterRepeatCountChild=this._repeatCountElement&&this._repeatCountElement.nextSibling;this._formattedMessage.insertBefore(this.timestampElement,this._formattedMessage.firstChild);return;} if(!show&&this.timestampElement){this.timestampElement.remove();delete this.timestampElement;}},nestingLevel:function() {return this._nestingLevel;},resetCloseGroupDecorationCount:function() {if(!this._closeGroupDecorationCount) return;this._closeGroupDecorationCount=0;this._updateCloseGroupDecorations();},incrementCloseGroupDecorationCount:function() {++this._closeGroupDecorationCount;this._updateCloseGroupDecorations();},_updateCloseGroupDecorations:function() {if(!this._nestingLevelMarkers) return;for(var i=0,n=this._nestingLevelMarkers.length;i<n;++i){var marker=this._nestingLevelMarkers[i];marker.classList.toggle("group-closed",n-i<=this._closeGroupDecorationCount);}},contentElement:function() {if(this._element) return this._element;var element=createElementWithClass("div","console-message");this._element=element;if(this._message.type===WebInspector.ConsoleMessage.MessageType.StartGroup||this._message.type===WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) element.classList.add("console-group-title");element.appendChild(this.formattedMessage());if(this._repeatCount>1) this._showRepeatCountElement();this.updateTimestamp(WebInspector.moduleSetting("consoleTimestampsEnabled").get());return this._element;},toMessageElement:function() {if(this._wrapperElement) return this._wrapperElement;this._wrapperElement=createElement("div");this.updateMessageElement();return this._wrapperElement;},updateMessageElement:function() {if(!this._wrapperElement) return;this._wrapperElement.className="console-message-wrapper";this._wrapperElement.removeChildren();this._nestingLevelMarkers=[];for(var i=0;i<this._nestingLevel;++i) this._nestingLevelMarkers.push(this._wrapperElement.createChild("div","nesting-level-marker"));this._updateCloseGroupDecorations();this._wrapperElement.message=this;switch(this._message.level){case WebInspector.ConsoleMessage.MessageLevel.Log:this._wrapperElement.classList.add("console-log-level");break;case WebInspector.ConsoleMessage.MessageLevel.Debug:this._wrapperElement.classList.add("console-debug-level");break;case WebInspector.ConsoleMessage.MessageLevel.Warning:this._wrapperElement.classList.add("console-warning-level");break;case WebInspector.ConsoleMessage.MessageLevel.Error:this._wrapperElement.classList.add("console-error-level");break;case WebInspector.ConsoleMessage.MessageLevel.RevokedError:this._wrapperElement.classList.add("console-revokedError-level");break;case WebInspector.ConsoleMessage.MessageLevel.Info:this._wrapperElement.classList.add("console-info-level");break;} this._wrapperElement.appendChild(this.contentElement());},_populateStackTraceTreeElement:function(parentTreeElement) {var target=this._target();if(!target) return;var content=WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(target,this._linkifier,this._message.stackTrace);var treeElement=new TreeElement(content);treeElement.selectable=false;parentTreeElement.appendChild(treeElement);},resetIncrementRepeatCount:function() {this._repeatCount=1;if(!this._repeatCountElement) return;this._repeatCountElement.remove();delete this._repeatCountElement;},incrementRepeatCount:function() {this._repeatCount++;this._showRepeatCountElement();},_showRepeatCountElement:function() {if(!this._element) return;if(!this._repeatCountElement){this._repeatCountElement=createElement("span");this._repeatCountElement.className="bubble-repeat-count";this._element.insertBefore(this._repeatCountElement,this._element.firstChild);this._element.classList.add("repeated-message");} this._repeatCountElement.textContent=this._repeatCount;},toString:function() {var sourceString;switch(this._message.source){case WebInspector.ConsoleMessage.MessageSource.XML:sourceString="XML";break;case WebInspector.ConsoleMessage.MessageSource.JS:sourceString="JavaScript";break;case WebInspector.ConsoleMessage.MessageSource.Network:sourceString="Network";break;case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:sourceString="ConsoleAPI";break;case WebInspector.ConsoleMessage.MessageSource.Storage:sourceString="Storage";break;case WebInspector.ConsoleMessage.MessageSource.AppCache:sourceString="AppCache";break;case WebInspector.ConsoleMessage.MessageSource.Rendering:sourceString="Rendering";break;case WebInspector.ConsoleMessage.MessageSource.CSS:sourceString="CSS";break;case WebInspector.ConsoleMessage.MessageSource.Security:sourceString="Security";break;case WebInspector.ConsoleMessage.MessageSource.Other:sourceString="Other";break;} var typeString;switch(this._message.type){case WebInspector.ConsoleMessage.MessageType.Log:typeString="Log";break;case WebInspector.ConsoleMessage.MessageType.Dir:typeString="Dir";break;case WebInspector.ConsoleMessage.MessageType.DirXML:typeString="Dir XML";break;case WebInspector.ConsoleMessage.MessageType.Trace:typeString="Trace";break;case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:case WebInspector.ConsoleMessage.MessageType.StartGroup:typeString="Start Group";break;case WebInspector.ConsoleMessage.MessageType.EndGroup:typeString="End Group";break;case WebInspector.ConsoleMessage.MessageType.Assert:typeString="Assert";break;case WebInspector.ConsoleMessage.MessageType.Result:typeString="Result";break;case WebInspector.ConsoleMessage.MessageType.Profile:case WebInspector.ConsoleMessage.MessageType.ProfileEnd:typeString="Profiling";break;} var levelString;switch(this._message.level){case WebInspector.ConsoleMessage.MessageLevel.Log:levelString="Log";break;case WebInspector.ConsoleMessage.MessageLevel.Warning:levelString="Warning";break;case WebInspector.ConsoleMessage.MessageLevel.Debug:levelString="Debug";break;case WebInspector.ConsoleMessage.MessageLevel.Error:levelString="Error";break;case WebInspector.ConsoleMessage.MessageLevel.RevokedError:levelString="RevokedError";break;case WebInspector.ConsoleMessage.MessageLevel.Info:levelString="Info";break;} return sourceString+" "+typeString+" "+levelString+": "+this.formattedMessage().textContent+"\n"+this._message.url+" line "+this._message.line;},get text() {return this._message.messageText;},setSearchRegex:function(regex) {if(this._searchHiglightNodeChanges&&this._searchHiglightNodeChanges.length) WebInspector.revertDomChanges(this._searchHiglightNodeChanges);this._searchRegex=regex;this._searchHighlightNodes=[];this._searchHiglightNodeChanges=[];if(!this._searchRegex) return;var text=this.searchableElement().deepTextContent();var match;this._searchRegex.lastIndex=0;var sourceRanges=[];while((match=this._searchRegex.exec(text))&&match[0]) sourceRanges.push(new WebInspector.SourceRange(match.index,match[0].length));if(sourceRanges.length&&this.searchableElement()) this._searchHighlightNodes=WebInspector.highlightSearchResults(this.searchableElement(),sourceRanges,this._searchHiglightNodeChanges);},searchRegex:function() {return this._searchRegex;},searchCount:function() {return this._searchHighlightNodes.length;},searchHighlightNode:function(index) {return this._searchHighlightNodes[index];},searchableElement:function() {this.formattedMessage();return this._messageElement;},_tryFormatAsError:function(string) {function startsWith(prefix) {return string.startsWith(prefix);} var errorPrefixes=["EvalError","ReferenceError","SyntaxError","TypeError","RangeError","Error","URIError"];var target=this._target();if(!target||!errorPrefixes.some(startsWith)) return null;var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel) return null;var lines=string.split("\n");var links=[];var position=0;for(var i=0;i<lines.length;++i){position+=i>0?lines[i-1].length+1:0;var isCallFrameLine=/^\s*at\s/.test(lines[i]);if(!isCallFrameLine&&links.length) return null;if(!isCallFrameLine) continue;var openBracketIndex=-1;var closeBracketIndex=-1;var match=/\([^\)\(]+\)/.exec(lines[i]);if(match){openBracketIndex=match.index;closeBracketIndex=match.index+match[0].length-1;} var hasOpenBracket=openBracketIndex!==-1;var left=hasOpenBracket?openBracketIndex+1:lines[i].indexOf("at")+3;var right=hasOpenBracket?closeBracketIndex:lines[i].length;var linkCandidate=lines[i].substring(left,right);var splitResult=WebInspector.ParsedURL.splitLineAndColumn(linkCandidate);if(!splitResult) return null;var parsed=splitResult.url.asParsedURL();var url;if(parsed) url=parsed.url;else if(debuggerModel.scriptsForSourceURL(splitResult.url).length) url=splitResult.url;else if(splitResult.url==="<anonymous>") continue;else return null;links.push({url:url,positionLeft:position+left,positionRight:position+right,lineNumber:splitResult.lineNumber,columnNumber:splitResult.columnNumber});} if(!links.length) return null;var formattedResult=createElement("span");var start=0;for(var i=0;i<links.length;++i){formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start,links[i].positionLeft)));formattedResult.appendChild(this._linkifier.linkifyScriptLocation(target,null,links[i].url,links[i].lineNumber,links[i].columnNumber));start=links[i].positionRight;} if(start!=string.length) formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));return formattedResult;}} WebInspector.ConsoleGroupViewMessage=function(consoleMessage,linkifier,nestingLevel) {console.assert(consoleMessage.isGroupStartMessage());WebInspector.ConsoleViewMessage.call(this,consoleMessage,linkifier,nestingLevel);this.setCollapsed(consoleMessage.type===WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed);} WebInspector.ConsoleGroupViewMessage.prototype={setCollapsed:function(collapsed) {this._collapsed=collapsed;if(this._wrapperElement) this._wrapperElement.classList.toggle("collapsed",this._collapsed);},collapsed:function() {return this._collapsed;},toMessageElement:function() {if(!this._wrapperElement){WebInspector.ConsoleViewMessage.prototype.toMessageElement.call(this);this._wrapperElement.classList.toggle("collapsed",this._collapsed);} return this._wrapperElement;},__proto__:WebInspector.ConsoleViewMessage.prototype};WebInspector.ConsoleView=function() {WebInspector.VBox.call(this);this.setMinimumSize(0,35);this.registerRequiredCSS("console/consoleView.css");this._searchableView=new WebInspector.SearchableView(this);this._searchableView.setPlaceholder(WebInspector.UIString("Find string in logs"));this._searchableView.setMinimalSearchQuerySize(0);this._searchableView.show(this.element);this._contentsElement=this._searchableView.element;this._contentsElement.classList.add("console-view");this._visibleViewMessages=[];this._urlToMessageCount={};this._hiddenByFilterCount=0;this._regexMatchRanges=[];this._executionContextComboBox=new WebInspector.ToolbarComboBox(null,"console-context");this._executionContextComboBox.setMaxWidth(200);this._executionContextModel=new WebInspector.ConsoleContextSelector(this._executionContextComboBox.selectElement());this._filter=new WebInspector.ConsoleViewFilter(this);this._filter.addEventListener(WebInspector.ConsoleViewFilter.Events.FilterChanged,this._updateMessageList.bind(this));this._filterBar=new WebInspector.FilterBar("consoleView");this._preserveLogCheckbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Preserve log"),WebInspector.UIString("Do not clear log on page reload / navigation"),WebInspector.moduleSetting("preserveConsoleLog"));this._progressToolbarItem=new WebInspector.ToolbarItem(createElement("div"));var toolbar=new WebInspector.Toolbar("",this._contentsElement);toolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton((WebInspector.actionRegistry.action("console.clear"))));toolbar.appendToolbarItem(this._filterBar.filterButton());toolbar.appendToolbarItem(this._executionContextComboBox);toolbar.appendToolbarItem(this._preserveLogCheckbox);toolbar.appendToolbarItem(this._progressToolbarItem);this._filterBar.show(this._contentsElement);this._filter.addFilters(this._filterBar);this._viewport=new WebInspector.ViewportControl(this);this._viewport.setStickToBottom(true);this._viewport.contentElement().classList.add("console-group","console-group-messages");this._contentsElement.appendChild(this._viewport.element);this._messagesElement=this._viewport.element;this._messagesElement.id="console-messages";this._messagesElement.classList.add("monospace");this._messagesElement.addEventListener("click",this._messagesClicked.bind(this),true);this._viewportThrottler=new WebInspector.Throttler(50);this._filterStatusMessageElement=createElementWithClass("div","console-message");this._messagesElement.insertBefore(this._filterStatusMessageElement,this._messagesElement.firstChild);this._filterStatusTextElement=this._filterStatusMessageElement.createChild("span","console-info");this._filterStatusMessageElement.createTextChild(" ");var resetFiltersLink=this._filterStatusMessageElement.createChild("span","console-info link");resetFiltersLink.textContent=WebInspector.UIString("Show all messages.");resetFiltersLink.addEventListener("click",this._filter.reset.bind(this._filter),true);this._topGroup=WebInspector.ConsoleGroup.createTopGroup();this._currentGroup=this._topGroup;this._promptElement=this._messagesElement.createChild("div","source-code");this._promptElement.id="console-prompt";this._promptElement.spellcheck=false;this._searchableView.setDefaultFocusedElement(this._promptElement);var selectAllFixer=this._messagesElement.createChild("div","console-view-fix-select-all");selectAllFixer.textContent=".";this._showAllMessagesCheckbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Show all messages"));this._showAllMessagesCheckbox.inputElement.checked=true;this._showAllMessagesCheckbox.inputElement.addEventListener("change",this._updateMessageList.bind(this),false);this._showAllMessagesCheckbox.element.classList.add("hidden");toolbar.appendToolbarItem(this._showAllMessagesCheckbox);this._registerShortcuts();this._messagesElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),false);WebInspector.moduleSetting("monitoringXHREnabled").addChangeListener(this._monitoringXHREnabledSettingChanged,this);this._linkifier=new WebInspector.Linkifier();this._consoleMessages=[];this._viewMessageSymbol=Symbol("viewMessage");this._prompt=new WebInspector.TextPromptWithHistory(WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);this._prompt.setSuggestBoxEnabled(true);this._prompt.setAutocompletionTimeout(0);this._prompt.renderAsBlock();var proxyElement=this._prompt.attach(this._promptElement);proxyElement.addEventListener("keydown",this._promptKeyDown.bind(this),false);this._consoleHistorySetting=WebInspector.settings.createLocalSetting("consoleHistory",[]);var historyData=this._consoleHistorySetting.get();this._prompt.setHistoryData(historyData);this._consoleHistoryAutocompleteSetting=WebInspector.moduleSetting("consoleHistoryAutocomplete");this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHistoryAutocompleteChanged,this);this._consoleHistoryAutocompleteChanged();this._updateFilterStatus();WebInspector.moduleSetting("consoleTimestampsEnabled").addChangeListener(this._consoleTimestampsSettingChanged,this);this._registerWithMessageSink();WebInspector.targetManager.observeTargets(this);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._onMainFrameNavigated,this);this._initConsoleMessages();WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext,this._executionContextChanged,this);} WebInspector.ConsoleView.persistedHistorySize=300;WebInspector.ConsoleView.prototype={searchableView:function() {return this._searchableView;},_clearHistory:function() {this._consoleHistorySetting.set([]);this._prompt.setHistoryData([]);},_consoleHistoryAutocompleteChanged:function() {this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSetting.get());},_onMainFrameNavigated:function(event) {var frame=(event.data);WebInspector.console.log(WebInspector.UIString("Navigated to %s",frame.url));},_initConsoleMessages:function() {var mainTarget=WebInspector.targetManager.mainTarget();if(!mainTarget||!mainTarget.resourceTreeModel.cachedResourcesLoaded()){WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded,this._onResourceTreeModelLoaded,this);return;} this._fetchMultitargetMessages();},_onResourceTreeModelLoaded:function(event) {var resourceTreeModel=event.target;if(resourceTreeModel.target()!==WebInspector.targetManager.mainTarget()) return;WebInspector.targetManager.removeModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded,this._onResourceTreeModelLoaded,this);this._fetchMultitargetMessages();},_fetchMultitargetMessages:function() {WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared,this._consoleCleared,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded,this._onConsoleMessageAdded,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageUpdated,this._onConsoleMessageUpdated,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.CommandEvaluated,this._commandEvaluated,this);WebInspector.multitargetConsoleModel.messages().forEach(this._addConsoleMessage,this);},itemCount:function() {return this._visibleViewMessages.length;},itemElement:function(index) {return this._visibleViewMessages[index];},fastHeight:function(index) {return this._visibleViewMessages[index].fastHeight();},minimumRowHeight:function() {return 16;},targetAdded:function(target) {this._viewport.invalidate();if(WebInspector.targetManager.targets().length>1&&WebInspector.targetManager.mainTarget().isPage()) this._showAllMessagesCheckbox.element.classList.toggle("hidden",false);},targetRemoved:function(target) {},_registerWithMessageSink:function() {WebInspector.console.messages().forEach(this._addSinkMessage,this);WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded,messageAdded,this);function messageAdded(event) {this._addSinkMessage((event.data));}},_addSinkMessage:function(message) {var level=WebInspector.ConsoleMessage.MessageLevel.Debug;switch(message.level){case WebInspector.Console.MessageLevel.Error:level=WebInspector.ConsoleMessage.MessageLevel.Error;break;case WebInspector.Console.MessageLevel.Warning:level=WebInspector.ConsoleMessage.MessageLevel.Warning;break;} var consoleMessage=new WebInspector.ConsoleMessage(null,WebInspector.ConsoleMessage.MessageSource.Other,level,message.text,undefined,undefined,undefined,undefined,undefined,undefined,undefined,message.timestamp);this._addConsoleMessage(consoleMessage);},_consoleTimestampsSettingChanged:function(event) {var enabled=(event.data);this._updateMessageList();this._consoleMessages.forEach(function(viewMessage){viewMessage.updateTimestamp(enabled);});},defaultFocusedElement:function() {return this._promptElement;},_executionContextChanged:function() {this._prompt.clearAutoComplete(true);if(!this._showAllMessagesCheckbox.checked()) this._updateMessageList();},willHide:function() {this._hidePromptSuggestBox();},wasShown:function() {this._viewport.refresh();if(!this._prompt.isCaretInsidePrompt()) this._prompt.moveCaretToEndOfPrompt();},focus:function() {if(this._promptElement===WebInspector.currentFocusElement()) return;this._prompt.moveCaretToEndOfPrompt();WebInspector.setCurrentFocusElement(this._promptElement);},restoreScrollPositions:function() {if(this._viewport.scrolledToBottom()) this._immediatelyScrollToBottom();else WebInspector.Widget.prototype.restoreScrollPositions.call(this);},onResize:function() {this._scheduleViewportRefresh();this._hidePromptSuggestBox();if(this._viewport.scrolledToBottom()) this._immediatelyScrollToBottom();for(var i=0;i<this._visibleViewMessages.length;++i) this._visibleViewMessages[i].onResize();},_hidePromptSuggestBox:function() {this._prompt.hideSuggestBox();this._prompt.clearAutoComplete(true);},_scheduleViewportRefresh:function() {function invalidateViewport() {if(this._needsFullUpdate){this._updateMessageList();delete this._needsFullUpdate;}else{this._viewport.invalidate();} return Promise.resolve();} this._viewportThrottler.schedule(invalidateViewport.bind(this));},_immediatelyScrollToBottom:function() {this._promptElement.scrollIntoView(true);},_updateFilterStatus:function() {this._filterStatusTextElement.textContent=WebInspector.UIString(this._hiddenByFilterCount===1?"%d message is hidden by filters.":"%d messages are hidden by filters.",this._hiddenByFilterCount);this._filterStatusMessageElement.style.display=this._hiddenByFilterCount?"":"none";},_onConsoleMessageAdded:function(event) {var message=(event.data);this._addConsoleMessage(message);},_addConsoleMessage:function(message) {function compareTimestamps(viewMessage1,viewMessage2) {return WebInspector.ConsoleMessage.timestampComparator(viewMessage1.consoleMessage(),viewMessage2.consoleMessage());} if(message.type===WebInspector.ConsoleMessage.MessageType.Command||message.type===WebInspector.ConsoleMessage.MessageType.Result) message.timestamp=this._consoleMessages.length?this._consoleMessages.peekLast().consoleMessage().timestamp:0;var viewMessage=this._createViewMessage(message);message[this._viewMessageSymbol]=viewMessage;var insertAt=this._consoleMessages.upperBound(viewMessage,compareTimestamps) var insertedInMiddle=insertAt<this._consoleMessages.length;this._consoleMessages.splice(insertAt,0,viewMessage);if(this._urlToMessageCount[message.url]) ++this._urlToMessageCount[message.url];else this._urlToMessageCount[message.url]=1;if(!insertedInMiddle){this._appendMessageToEnd(viewMessage);this._updateFilterStatus();this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);}else{this._needsFullUpdate=true;} this._scheduleViewportRefresh();this._consoleMessageAddedForTest(viewMessage);},_onConsoleMessageUpdated:function(event) {var message=(event.data);var viewMessage=message[this._viewMessageSymbol];if(viewMessage){viewMessage.updateMessageElement();this._updateMessageList();}},_consoleMessageAddedForTest:function(viewMessage){},_appendMessageToEnd:function(viewMessage) {if(!this._filter.shouldBeVisible(viewMessage)){this._hiddenByFilterCount++;return;} if(this._tryToCollapseMessages(viewMessage,this._visibleViewMessages.peekLast())) return;var lastMessage=this._visibleViewMessages.peekLast();if(viewMessage.consoleMessage().type===WebInspector.ConsoleMessage.MessageType.EndGroup){if(lastMessage&&!this._currentGroup.messagesHidden()) lastMessage.incrementCloseGroupDecorationCount();this._currentGroup=this._currentGroup.parentGroup();return;} if(!this._currentGroup.messagesHidden()){var originatingMessage=viewMessage.consoleMessage().originatingMessage();if(lastMessage&&originatingMessage&&lastMessage.consoleMessage()===originatingMessage) lastMessage.toMessageElement().classList.add("console-adjacent-user-command-result");this._visibleViewMessages.push(viewMessage);this._searchMessage(this._visibleViewMessages.length-1);} if(viewMessage.consoleMessage().isGroupStartMessage()) this._currentGroup=new WebInspector.ConsoleGroup(this._currentGroup,viewMessage);this._messageAppendedForTests();},_messageAppendedForTests:function() {},_createViewMessage:function(message) {var nestingLevel=this._currentGroup.nestingLevel();switch(message.type){case WebInspector.ConsoleMessage.MessageType.Command:return new WebInspector.ConsoleCommand(message,this._linkifier,nestingLevel);case WebInspector.ConsoleMessage.MessageType.Result:return new WebInspector.ConsoleCommandResult(message,this._linkifier,nestingLevel);case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:case WebInspector.ConsoleMessage.MessageType.StartGroup:return new WebInspector.ConsoleGroupViewMessage(message,this._linkifier,nestingLevel);default:return new WebInspector.ConsoleViewMessage(message,this._linkifier,nestingLevel);}},_consoleCleared:function() {this._currentMatchRangeIndex=-1;this._consoleMessages=[];this._updateMessageList();this._hidePromptSuggestBox();this._linkifier.reset();},_handleContextMenuEvent:function(event) {if(event.target.enclosingNodeOrSelfWithNodeName("a")) return;var contextMenu=new WebInspector.ContextMenu(event);if(event.target.isSelfOrDescendant(this._promptElement)){contextMenu.show() return;} function monitoringXHRItemAction() {WebInspector.moduleSetting("monitoringXHREnabled").set(!WebInspector.moduleSetting("monitoringXHREnabled").get());} contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"),monitoringXHRItemAction,WebInspector.moduleSetting("monitoringXHREnabled").get());var sourceElement=event.target.enclosingNodeOrSelfWithClass("console-message-wrapper");var consoleMessage=sourceElement?sourceElement.message.consoleMessage():null;var filterSubMenu=contextMenu.appendSubMenuItem(WebInspector.UIString("Filter"));if(consoleMessage&&consoleMessage.url){var menuTitle=WebInspector.UIString.capitalize("Hide ^messages from %s",new WebInspector.ParsedURL(consoleMessage.url).displayName);filterSubMenu.appendItem(menuTitle,this._filter.addMessageURLFilter.bind(this._filter,consoleMessage.url));} filterSubMenu.appendSeparator();var unhideAll=filterSubMenu.appendItem(WebInspector.UIString.capitalize("Unhide ^all"),this._filter.removeMessageURLFilter.bind(this._filter));filterSubMenu.appendSeparator();var hasFilters=false;for(var url in this._filter.messageURLFilters){filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)",new WebInspector.ParsedURL(url).displayName,this._urlToMessageCount[url]),this._filter.removeMessageURLFilter.bind(this._filter,url),true);hasFilters=true;} filterSubMenu.setEnabled(hasFilters||(consoleMessage&&consoleMessage.url));unhideAll.setEnabled(hasFilters);contextMenu.appendSeparator();contextMenu.appendAction("console.clear");contextMenu.appendAction("console.clear.history");contextMenu.appendItem(WebInspector.UIString("Save as..."),this._saveConsole.bind(this));var request=consoleMessage?consoleMessage.request:null;if(request&&request.resourceType()===WebInspector.resourceTypes.XHR){contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("Replay XHR"),request.replayXHR.bind(request));} contextMenu.show();},_saveConsole:function() {var filename=String.sprintf("%s-%d.log",WebInspector.targetManager.inspectedPageDomain(),Date.now());var stream=new WebInspector.FileOutputStream();var progressIndicator=new WebInspector.ProgressIndicator();progressIndicator.setTitle(WebInspector.UIString("Writing file…"));progressIndicator.setTotalWork(this.itemCount());var chunkSize=350;var messageIndex=0;stream.open(filename,openCallback.bind(this));function openCallback(accepted) {if(!accepted) return;this._progressToolbarItem.element.appendChild(progressIndicator.element);writeNextChunk.call(this,stream);} function writeNextChunk(stream,error) {if(messageIndex>=this.itemCount()||error){stream.close();progressIndicator.done();return;} var lines=[];for(var i=0;i<chunkSize&&i+messageIndex<this.itemCount();++i){var message=this.itemElement(messageIndex+i);lines.push(message.searchableElement().deepTextContent());} messageIndex+=i;stream.write(lines.join("\n")+"\n",writeNextChunk.bind(this));progressIndicator.setWorked(messageIndex);}},_tryToCollapseMessages:function(lastMessage,viewMessage) {if(!WebInspector.moduleSetting("consoleTimestampsEnabled").get()&&viewMessage&&!lastMessage.consoleMessage().isGroupMessage()&&lastMessage.consoleMessage().isEqual(viewMessage.consoleMessage())){viewMessage.incrementRepeatCount();return true;} return false;},_updateMessageList:function() {this._topGroup=WebInspector.ConsoleGroup.createTopGroup();this._currentGroup=this._topGroup;this._regexMatchRanges=[];this._hiddenByFilterCount=0;for(var i=0;i<this._visibleViewMessages.length;++i){this._visibleViewMessages[i].resetCloseGroupDecorationCount();this._visibleViewMessages[i].resetIncrementRepeatCount();} this._visibleViewMessages=[];for(var i=0;i<this._consoleMessages.length;++i) this._appendMessageToEnd(this._consoleMessages[i]);this._updateFilterStatus();this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);this._viewport.invalidate();},_monitoringXHREnabledSettingChanged:function(event) {var enabled=(event.data);WebInspector.targetManager.targets().forEach(function(target){target.networkAgent().setMonitoringXHREnabled(enabled);});},_messagesClicked:function(event) {var targetElement=event.deepElementFromPoint();if(!this._prompt.isCaretInsidePrompt()&&(!targetElement||targetElement.isComponentSelectionCollapsed())) this._prompt.moveCaretToEndOfPrompt();var groupMessage=event.target.enclosingNodeOrSelfWithClass("console-group-title");if(!groupMessage) return;var consoleGroupViewMessage=groupMessage.parentElement.message;consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed());this._updateMessageList();},_registerShortcuts:function() {this._shortcuts={};var shortcut=WebInspector.KeyboardShortcut;var section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));var shortcutL=shortcut.makeDescriptor("l",WebInspector.KeyboardShortcut.Modifiers.Ctrl);var keys=[shortcutL];if(WebInspector.isMac()){var shortcutK=shortcut.makeDescriptor("k",WebInspector.KeyboardShortcut.Modifiers.Meta);keys.unshift(shortcutK);} section.addAlternateKeys(keys,WebInspector.UIString("Clear console"));section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab),WebInspector.UIString("Autocomplete common prefix"));section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right),WebInspector.UIString("Accept suggestion"));var shortcutU=shortcut.makeDescriptor("u",WebInspector.KeyboardShortcut.Modifiers.Ctrl);this._shortcuts[shortcutU.key]=this._clearPromptBackwards.bind(this);section.addAlternateKeys([shortcutU],WebInspector.UIString("Clear console prompt"));keys=[shortcut.makeDescriptor(shortcut.Keys.Down),shortcut.makeDescriptor(shortcut.Keys.Up)];section.addRelatedKeys(keys,WebInspector.UIString("Next/previous line"));if(WebInspector.isMac()){keys=[shortcut.makeDescriptor("N",shortcut.Modifiers.Alt),shortcut.makeDescriptor("P",shortcut.Modifiers.Alt)];section.addRelatedKeys(keys,WebInspector.UIString("Next/previous command"));} section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter),WebInspector.UIString("Execute command"));},_clearPromptBackwards:function() {this._prompt.setText("");},_promptKeyDown:function(event) {if(isEnterKey(event)){this._enterKeyPressed(event);return;} var shortcut=WebInspector.KeyboardShortcut.makeKeyFromEvent(event);var handler=this._shortcuts[shortcut];if(handler){handler();event.preventDefault();}},_enterKeyPressed:function(event) {if(event.altKey||event.ctrlKey||event.shiftKey) return;event.consume(true);this._prompt.clearAutoComplete(true);var str=this._prompt.text();if(!str.length) return;this._appendCommand(str,true);},_printResult:function(result,wasThrown,originatingConsoleMessage,exceptionDetails) {if(!result) return;var level=wasThrown?WebInspector.ConsoleMessage.MessageLevel.Error:WebInspector.ConsoleMessage.MessageLevel.Log;var message;if(!wasThrown) message=new WebInspector.ConsoleMessage(result.target(),WebInspector.ConsoleMessage.MessageSource.JS,level,"",WebInspector.ConsoleMessage.MessageType.Result,undefined,undefined,undefined,undefined,[result]);else message=new WebInspector.ConsoleMessage(result.target(),WebInspector.ConsoleMessage.MessageSource.JS,level,exceptionDetails.text,WebInspector.ConsoleMessage.MessageType.Result,exceptionDetails.url,exceptionDetails.line,exceptionDetails.column,undefined,[WebInspector.UIString("Uncaught"),result],exceptionDetails.stack,undefined,undefined,exceptionDetails.scriptId);message.setOriginatingMessage(originatingConsoleMessage);result.target().consoleModel.addMessage(message);},_appendCommand:function(text,useCommandLineAPI) {this._prompt.setText("");var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(currentExecutionContext){WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext,text,useCommandLineAPI);if(WebInspector.inspectorView.currentPanel()&&WebInspector.inspectorView.currentPanel().name==="console") WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.CommandEvaluatedInConsolePanel);}},_commandEvaluated:function(event) {var data=(event.data);this._prompt.pushHistoryItem(data.text);this._consoleHistorySetting.set(this._prompt.historyData().slice(-WebInspector.ConsoleView.persistedHistorySize));this._printResult(data.result,data.wasThrown,data.commandMessage,data.exceptionDetails);},elementsToRestoreScrollPositionsFor:function() {return[this._messagesElement];},searchCanceled:function() {this._cleanupAfterSearch();for(var i=0;i<this._visibleViewMessages.length;++i){var message=this._visibleViewMessages[i];message.setSearchRegex(null);} this._currentMatchRangeIndex=-1;this._regexMatchRanges=[];delete this._searchRegex;this._viewport.refresh();},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this.searchCanceled();this._searchableView.updateSearchMatchesCount(0);this._searchRegex=searchConfig.toSearchRegex(true);this._regexMatchRanges=[];this._currentMatchRangeIndex=-1;if(shouldJump) this._searchShouldJumpBackwards=!!jumpBackwards;this._searchProgressIndicator=new WebInspector.ProgressIndicator();this._searchProgressIndicator.setTitle(WebInspector.UIString("Searching…"));this._searchProgressIndicator.setTotalWork(this._visibleViewMessages.length);this._progressToolbarItem.element.appendChild(this._searchProgressIndicator.element);this._innerSearch(0);},_cleanupAfterSearch:function() {delete this._searchShouldJumpBackwards;if(this._innerSearchTimeoutId){clearTimeout(this._innerSearchTimeoutId);delete this._innerSearchTimeoutId;} if(this._searchProgressIndicator){this._searchProgressIndicator.done();delete this._searchProgressIndicator;}},_searchFinishedForTests:function() {},_innerSearch:function(index) {delete this._innerSearchTimeoutId;if(this._searchProgressIndicator.isCanceled()){this._cleanupAfterSearch();return;} var startTime=Date.now();for(;index<this._visibleViewMessages.length&&Date.now()-startTime<100;++index) this._searchMessage(index);this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);if(typeof this._searchShouldJumpBackwards!=="undefined"&&this._regexMatchRanges.length){this._jumpToMatch(this._searchShouldJumpBackwards?-1:0);delete this._searchShouldJumpBackwards;} if(index===this._visibleViewMessages.length){this._cleanupAfterSearch();setTimeout(this._searchFinishedForTests.bind(this),0);return;} this._innerSearchTimeoutId=setTimeout(this._innerSearch.bind(this,index),100);this._searchProgressIndicator.setWorked(index);},_searchMessage:function(index) {var message=this._visibleViewMessages[index];message.setSearchRegex(this._searchRegex);for(var i=0;i<message.searchCount();++i){this._regexMatchRanges.push({messageIndex:index,matchIndex:i});}},jumpToNextSearchResult:function() {this._jumpToMatch(this._currentMatchRangeIndex+1);},jumpToPreviousSearchResult:function() {this._jumpToMatch(this._currentMatchRangeIndex-1);},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return true;},_jumpToMatch:function(index) {if(!this._regexMatchRanges.length) return;var matchRange;if(this._currentMatchRangeIndex>=0){matchRange=this._regexMatchRanges[this._currentMatchRangeIndex];var message=this._visibleViewMessages[matchRange.messageIndex];message.searchHighlightNode(matchRange.matchIndex).classList.remove(WebInspector.highlightedCurrentSearchResultClassName);} index=mod(index,this._regexMatchRanges.length);this._currentMatchRangeIndex=index;this._searchableView.updateCurrentMatchIndex(index);matchRange=this._regexMatchRanges[index];var message=this._visibleViewMessages[matchRange.messageIndex];var highlightNode=message.searchHighlightNode(matchRange.matchIndex);highlightNode.classList.add(WebInspector.highlightedCurrentSearchResultClassName);this._viewport.scrollItemIntoView(matchRange.messageIndex);highlightNode.scrollIntoViewIfNeeded();},__proto__:WebInspector.VBox.prototype} WebInspector.ConsoleViewFilter=function(view) {this._messageURLFiltersSetting=WebInspector.settings.createSetting("messageURLFilters",{});this._messageLevelFiltersSetting=WebInspector.settings.createSetting("messageLevelFilters",{});this._view=view;this._messageURLFilters=this._messageURLFiltersSetting.get();this._filterChanged=this.dispatchEventToListeners.bind(this,WebInspector.ConsoleViewFilter.Events.FilterChanged);};WebInspector.ConsoleViewFilter.Events={FilterChanged:"FilterChanged"};WebInspector.ConsoleViewFilter.prototype={addFilters:function(filterBar) {this._textFilterUI=new WebInspector.TextFilterUI(true);this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._textFilterChanged,this);filterBar.addFilter(this._textFilterUI);this._hideNetworkMessagesCheckbox=new WebInspector.CheckboxFilterUI("hide-network-messages",WebInspector.UIString("Hide network messages"),true,WebInspector.moduleSetting("hideNetworkMessages"));this._hideNetworkMessagesCheckbox.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged.bind(this),this);filterBar.addFilter(this._hideNetworkMessagesCheckbox);var levels=[{name:WebInspector.ConsoleMessage.MessageLevel.Error,label:WebInspector.UIString("Errors")},{name:WebInspector.ConsoleMessage.MessageLevel.Warning,label:WebInspector.UIString("Warnings")},{name:WebInspector.ConsoleMessage.MessageLevel.Info,label:WebInspector.UIString("Info")},{name:WebInspector.ConsoleMessage.MessageLevel.Log,label:WebInspector.UIString("Logs")},{name:WebInspector.ConsoleMessage.MessageLevel.Debug,label:WebInspector.UIString("Debug")},{name:WebInspector.ConsoleMessage.MessageLevel.RevokedError,label:WebInspector.UIString("Handled")}];this._levelFilterUI=new WebInspector.NamedBitSetFilterUI(levels,this._messageLevelFiltersSetting);this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged,this);filterBar.addFilter(this._levelFilterUI);},_textFilterChanged:function(event) {this._filterRegex=this._textFilterUI.regex();this._filterChanged();},addMessageURLFilter:function(url) {this._messageURLFilters[url]=true;this._messageURLFiltersSetting.set(this._messageURLFilters);this._filterChanged();},removeMessageURLFilter:function(url) {if(!url) this._messageURLFilters={};else delete this._messageURLFilters[url];this._messageURLFiltersSetting.set(this._messageURLFilters);this._filterChanged();},get messageURLFilters() {return this._messageURLFilters;},shouldBeVisible:function(viewMessage) {var message=viewMessage.consoleMessage();var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!message.target()) return true;if(!this._view._showAllMessagesCheckbox.checked()&&executionContext){if(message.target()!==executionContext.target()) return false;if(message.executionContextId&&message.executionContextId!==executionContext.id){return false;}} if(WebInspector.moduleSetting("hideNetworkMessages").get()&&viewMessage.consoleMessage().source===WebInspector.ConsoleMessage.MessageSource.Network) return false;if(viewMessage.consoleMessage().isGroupMessage()) return true;if(message.type===WebInspector.ConsoleMessage.MessageType.Result||message.type===WebInspector.ConsoleMessage.MessageType.Command) return true;if(message.url&&this._messageURLFilters[message.url]) return false;if(message.level&&!this._levelFilterUI.accept(message.level)) return false;if(this._filterRegex){this._filterRegex.lastIndex=0;if(!viewMessage.matchesFilterRegex(this._filterRegex)) return false;} return true;},reset:function() {this._messageURLFilters={};this._messageURLFiltersSetting.set(this._messageURLFilters);this._messageLevelFiltersSetting.set({});this._view._showAllMessagesCheckbox.inputElement.checked=true;WebInspector.moduleSetting("hideNetworkMessages").set(false);this._textFilterUI.setValue("");this._filterChanged();},__proto__:WebInspector.Object.prototype};WebInspector.ConsoleCommand=function(message,linkifier,nestingLevel) {WebInspector.ConsoleViewMessage.call(this,message,linkifier,nestingLevel);} WebInspector.ConsoleCommand.prototype={searchableElement:function() {return this.contentElement();},contentElement:function() {if(!this._element){this._element=createElementWithClass("div","console-user-command");this._element.message=this;this._formattedCommand=createElementWithClass("span","console-message-text source-code");this._formattedCommand.textContent=this.text.replaceControlCharacters();this._element.appendChild(this._formattedCommand);var javascriptSyntaxHighlighter=new WebInspector.DOMSyntaxHighlighter("text/javascript",true);javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this))} return this._element;},_updateSearch:function() {this.setSearchRegex(this.searchRegex());},__proto__:WebInspector.ConsoleViewMessage.prototype} WebInspector.ConsoleCommandResult=function(message,linkifier,nestingLevel) {WebInspector.ConsoleViewMessage.call(this,message,linkifier,nestingLevel);} WebInspector.ConsoleCommandResult.prototype={useArrayPreviewInFormatter:function(array) {return false;},contentElement:function() {var element=WebInspector.ConsoleViewMessage.prototype.contentElement.call(this);element.classList.add("console-user-command-result");this.updateTimestamp(false);return element;},__proto__:WebInspector.ConsoleViewMessage.prototype} WebInspector.ConsoleGroup=function(parentGroup,groupMessage) {this._parentGroup=parentGroup;this._nestingLevel=parentGroup?parentGroup.nestingLevel()+1:0;this._messagesHidden=groupMessage&&groupMessage.collapsed()||this._parentGroup&&this._parentGroup.messagesHidden();} WebInspector.ConsoleGroup.createTopGroup=function() {return new WebInspector.ConsoleGroup(null,null);} WebInspector.ConsoleGroup.prototype={messagesHidden:function() {return this._messagesHidden;},nestingLevel:function() {return this._nestingLevel;},parentGroup:function() {return this._parentGroup||this;},} WebInspector.ConsoleView.instance=function() {if(!WebInspector.ConsoleView._instance) WebInspector.ConsoleView._instance=new WebInspector.ConsoleView();return WebInspector.ConsoleView._instance;} WebInspector.ConsoleView.ActionDelegate=function() {} WebInspector.ConsoleView.ActionDelegate.prototype={handleAction:function(context,actionId) {switch(actionId){case"console.show":WebInspector.console.show();return true;case"console.clear":WebInspector.ConsoleModel.clearConsole();return true;case"console.clear.history":WebInspector.ConsoleView.instance()._clearHistory();return true;} return false;}} WebInspector.ConsoleView.RegexMatchRange;;WebInspector.ConsolePanel=function() {WebInspector.Panel.call(this,"console");this._view=WebInspector.ConsoleView.instance();} WebInspector.ConsolePanel.prototype={defaultFocusedElement:function() {return this._view.defaultFocusedElement();},focus:function() {this._view.focus();},wasShown:function() {WebInspector.Panel.prototype.wasShown.call(this);var wrapper=WebInspector.ConsolePanel.WrapperView._instance;if(wrapper&&wrapper.isShowing()) WebInspector.inspectorView.setDrawerMinimized(true);this._view.show(this.element);},willHide:function() {WebInspector.Panel.prototype.willHide.call(this);if(WebInspector.ConsolePanel.WrapperView._instance) WebInspector.ConsolePanel.WrapperView._instance._showViewInWrapper();WebInspector.inspectorView.setDrawerMinimized(false);},searchableView:function() {return WebInspector.ConsoleView.instance().searchableView();},__proto__:WebInspector.Panel.prototype} WebInspector.ConsolePanel.WrapperView=function() {WebInspector.VBox.call(this);this.element.classList.add("console-view-wrapper");WebInspector.ConsolePanel.WrapperView._instance=this;this._view=WebInspector.ConsoleView.instance();} WebInspector.ConsolePanel.WrapperView.prototype={wasShown:function() {if(!WebInspector.inspectorView.currentPanel()||WebInspector.inspectorView.currentPanel().name!=="console") this._showViewInWrapper();else WebInspector.inspectorView.setDrawerMinimized(true);},willHide:function() {WebInspector.inspectorView.setDrawerMinimized(false);},defaultFocusedElement:function() {return this._view.defaultFocusedElement();},focus:function() {this._view.focus();},_showViewInWrapper:function() {this._view.show(this.element);},__proto__:WebInspector.VBox.prototype} WebInspector.ConsolePanel.ConsoleRevealer=function() {} WebInspector.ConsolePanel.ConsoleRevealer.prototype={reveal:function(object) {var consoleView=WebInspector.ConsoleView.instance();if(consoleView.isShowing()){consoleView.focus();return Promise.resolve();} WebInspector.inspectorView.showViewInDrawer("console");return Promise.resolve();}} WebInspector.ConsolePanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.ConsolePanel._instance());} WebInspector.ConsolePanel._instance=function() {if(!WebInspector.ConsolePanel._instanceObject) WebInspector.ConsolePanel._instanceObject=new WebInspector.ConsolePanel();return WebInspector.ConsolePanel._instanceObject;} WebInspector.ConsolePanelFactory=function() {} WebInspector.ConsolePanelFactory.prototype={createPanel:function() {return WebInspector.ConsolePanel._instance();}};Runtime.cachedResources["console/consoleView.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.console-view {\n background-color: white;\n overflow: hidden;\n}\n\n.console-view > .toolbar {\n border-bottom: 1px solid #dadada;\n}\n\n.console-view-wrapper {\n background-color: #eee;\n}\n\n.console-view-fix-select-all {\n height: 0;\n overflow: hidden;\n}\n\n#console-messages {\n flex: 1 1;\n padding: 2px 0;\n overflow-y: auto;\n word-wrap: break-word;\n -webkit-user-select: text;\n transform: translateZ(0);\n}\n\n#console-prompt {\n clear: right;\n position: relative;\n padding: 3px 22px 1px 0;\n margin-left: 24px;\n min-height: 18px; /* Sync with ConsoleViewMessage.js */\n white-space: pre-wrap;\n -webkit-user-modify: read-write-plaintext-only;\n}\n\n#console-prompt::before {\n background-position: -192px -96px;\n}\n\n.console-log-level .console-user-command-result::before {\n background-position: -202px -96px;\n}\n\n.console-message,\n.console-user-command {\n clear: right;\n position: relative;\n padding: 3px 22px 1px 0;\n margin-left: 24px;\n min-height: 18px; /* Sync with ConsoleViewMessage.js */\n flex: auto;\n display: flex;\n}\n\n.console-message > * {\n flex: auto;\n}\n\n.console-adjacent-user-command-result + .console-user-command-result.console-log-level::before {\n background-image: none;\n}\n\n.console-timestamp {\n color: gray;\n -webkit-user-select: none;\n}\n\n.console-message::before,\n.console-user-command::before,\n#console-prompt::before,\n.console-group-title::before {\n position: absolute;\n display: block;\n content: \"\";\n left: -17px;\n top: 9px;\n width: 10px;\n height: 10px;\n margin-top: -4px;\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.console-message::before,\n.console-user-command::before,\n#console-prompt::before,\n.console-group-title::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.console-message > .outline-disclosure li.parent::before {\n top: 0;\n}\n\n.bubble-repeat-count {\n display: inline-block;\n height: 14px;\n background-color: rgb(128, 151, 189);\n vertical-align: middle;\n white-space: nowrap;\n padding: 1px 4px;\n text-align: left;\n font-size: 11px;\n line-height: normal;\n font-weight: bold;\n text-shadow: none;\n color: white;\n margin-top: -1px;\n border-radius: 7px;\n flex: none;\n}\n\n.console-message .bubble-repeat-count {\n margin-right: 4px;\n margin-left: -18px;\n}\n\n.console-error-level .repeated-message::before,\n.console-revokedError-level .repeated-message::before,\n.console-warning-level .repeated-message::before,\n.console-debug-level .repeated-message::before,\n.console-info-level .repeated-message::before {\n visibility: hidden;\n}\n\n.repeated-message .outline-disclosure,\n.repeated-message > .console-message-text {\n flex: 1;\n}\n\n.console-warning-level .repeated-message,\n.console-error-level .repeated-message,\n.console-revokedError-level .repeated-message,\n.console-log-level .repeated-message,\n.console-debug-level .repeated-message,\n.console-info-level .repeated-message {\n display: flex;\n}\n\n.console-info {\n color: rgb(128, 128, 128);\n font-style: italic;\n}\n\n.console-group .console-group > .console-group-messages {\n margin-left: 16px;\n}\n\n.console-group-title {\n font-weight: bold;\n}\n\n.console-group-title::before {\n -webkit-user-select: none;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n float: left;\n width: 8px;\n content: \"a\";\n color: transparent;\n text-shadow: none;\n margin-left: 3px;\n margin-top: -7px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.console-group-title::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.console-group .console-group-title::before {\n -webkit-mask-position: -20px -96px;\n background-color: rgb(110, 110, 110);\n}\n\n.console-message-wrapper.collapsed .console-group-title::before {\n -webkit-mask-position: -4px -96px;\n}\n\n.console-group {\n position: relative;\n}\n\n.console-message-wrapper {\n display: flex;\n border-bottom: 1px solid rgb(240, 240, 240);\n}\n\n.console-message-wrapper.console-adjacent-user-command-result {\n border-bottom: none;\n}\n\n.console-message-wrapper.console-error-level {\n border-top: 1px solid hsl(0, 100%, 92%);\n border-bottom: 1px solid hsl(0, 100%, 92%);\n margin-top: -1px;\n}\n\n.console-message-wrapper.console-warning-level {\n border-top: 1px solid hsl(50, 100%, 88%);\n border-bottom: 1px solid hsl(50, 100%, 88%);\n margin-top: -1px;\n}\n\n.console-message-wrapper .nesting-level-marker {\n width: 14px;\n flex: 0 0 auto;\n border-right: 1px solid #a5a5a5;\n position: relative;\n margin-bottom: -1px;\n}\n\n.console-message-wrapper:last-child .nesting-level-marker::before,\n.console-message-wrapper .nesting-level-marker.group-closed::before {\n content: \"\";\n}\n\n.console-message-wrapper .nesting-level-marker::before {\n border-bottom: 1px solid #a5a5a5;\n position: absolute;\n top: 0;\n left: 0;\n margin-left: 100%;\n width: 3px;\n height: 100%;\n box-sizing: border-box;\n}\n\n.console-error-level {\n background-color: hsl(0, 100%, 97%);\n}\n\n.-theme-with-dark-background .console-error-level {\n background-color: hsl(0, 100%, 8%);\n}\n\n.console-warning-level {\n background-color: hsl(50, 100%, 95%);\n}\n\n.-theme-with-dark-background .console-warning-level {\n background-color: hsl(50, 100%, 10%);\n}\n\n.console-warning-level .console-message-text {\n color: hsl(39, 100%, 18%);\n}\n\n.console-error-level .console-message-text,\n.console-error-level .console-view-object-properties-section {\n color: red !important;\n}\n\n.-theme-with-dark-background .console-error-level .console-message-text,\n.-theme-with-dark-background .console-error-level .console-view-object-properties-section {\n color: hsl(0, 100%, 75%) !important;\n}\n\n.console-debug-level .console-message-text {\n color: blue;\n}\n\n.-theme-with-dark-background .console-debug-level .console-message-text {\n color: hsl(220, 100%, 65%) !important;\n}\n\n.console-message.console-warning-level {\n background-color: rgb(255, 250, 224);\n}\n\n.console-error-level .console-message::before,\n.console-revokedError-level .console-message::before,\n.console-warning-level .console-message::before,\n.console-debug-level .console-message::before,\n.console-info-level .console-message::before {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n width: 10px;\n height: 10px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.console-error-level .console-message::before,\n.console-revokedError-level .console-message::before,\n.console-warning-level .console-message::before,\n.console-debug-level .console-message::before,\n.console-info-level .console-message::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.console-warning-level .console-message::before {\n background-position: -202px -107px;\n}\n\n.console-error-level .console-message::before {\n background-position: -213px -96px;\n}\n\n.console-revokedError-level .console-message::before {\n background-position: -245px -107px;\n}\n\n.console-info-level .console-message::before {\n background-position: -213px -107px;\n}\n\n.console-user-command .console-message {\n margin-left: -24px;\n padding-right: 0;\n border-bottom: none;\n}\n\n.console-user-command::before {\n background-position: -192px -107px;\n}\n\n#console-messages .link {\n text-decoration: underline;\n}\n\n#console-messages .link,\n#console-messages a {\n color: rgb(33%, 33%, 33%);\n cursor: pointer;\n}\n\n#console-messages .link:hover,\n#console-messages a:hover {\n color: rgb(15%, 15%, 15%);\n}\n\n.console-group-messages .section {\n margin: 0 0 0 12px !important;\n}\n\n.console-group-messages .section > .header {\n padding: 0 8px 0 0;\n background-image: none;\n border: none;\n min-height: 0;\n}\n\n.console-group-messages .section > .header::before {\n margin-left: -12px;\n}\n\n.console-group-messages .section > .header .title {\n color: #222;\n font-weight: normal;\n line-height: 13px;\n}\n\n.console-group-messages .section .properties li .info {\n padding-top: 0;\n padding-bottom: 0;\n color: rgb(60%, 60%, 60%);\n}\n\n.console-object-preview {\n font-style: italic;\n white-space: normal;\n word-wrap: break-word;\n}\n\n.console-object-preview .name {\n /* Follows .section .properties .name, .event-properties .name */\n color: rgb(136, 19, 145);\n flex-shrink: 0;\n}\n\n.console-message-text .object-value-string {\n white-space: pre-wrap;\n}\n\n.console-message-formatted-table {\n clear: both;\n}\n\n.console-message-url {\n float: right;\n text-align: right;\n max-width: 100%;\n margin-left: 4px;\n}\n\n.console-message-nowrap-below,\n.console-message-nowrap-below div,\n.console-message-nowrap-below span {\n white-space: nowrap !important;\n}\n\n.object-state-note {\n display: inline-block;\n width: 11px;\n height: 11px;\n color: white;\n text-align: center;\n border-radius: 3px;\n line-height: 13px;\n margin: 0 6px;\n font-size: 9px;\n}\n\n.-theme-with-dark-background .object-state-note {\n background-color: hsl(230, 100%, 80%);\n}\n\n.info-note {\n background-color: rgb(179, 203, 247);\n}\n\n.info-note::before {\n content: \"i\";\n}\n\n.console-view-object-properties-section:not(.expanded) .info-note {\n display: none;\n}\n\n/*# sourceURL=console/consoleView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 2 1 1 1 1 1 1 1 1 | WebInspector.DevicesView=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("devices/devicesView.css");this.contentElement.classList.add("devices-view");var hbox=this.contentElement.createChild("div","hbox devices-container");var sidebar=hbox.createChild("div","devices-sidebar");sidebar.createChild("div","devices-view-title").createTextChild(WebInspector.UIString("Devices"));this._sidebarList=sidebar.createChild("div","devices-sidebar-list");this._discoveryView=new WebInspector.DevicesView.DiscoveryView();this._sidebarListSpacer=this._sidebarList.createChild("div","devices-sidebar-spacer");this._discoveryListItem=this._sidebarList.createChild("div","devices-sidebar-item");this._discoveryListItem.textContent=WebInspector.UIString("Settings");this._discoveryListItem.addEventListener("click",this._selectSidebarListItem.bind(this,this._discoveryListItem,this._discoveryView));this._viewById=new Map();this._devices=[];this._listItemById=new Map();this._viewContainer=hbox.createChild("div","flex-auto vbox");var discoveryFooter=this.contentElement.createChild("div","devices-footer");this._deviceCountSpan=discoveryFooter.createChild("span");discoveryFooter.createChild("span").textContent=WebInspector.UIString(" Read ");discoveryFooter.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/chrome-developer-tools/docs/remote-debugging",WebInspector.UIString("remote debugging documentation"),undefined,true));discoveryFooter.createChild("span").textContent=WebInspector.UIString(" for more information.");this._updateFooter();this._selectSidebarListItem(this._discoveryListItem,this._discoveryView);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesUpdated,this._devicesUpdated,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged,this._devicesDiscoveryConfigChanged,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged,this._devicesPortForwardingStatusChanged,this);this.contentElement.tabIndex=0;this.setDefaultFocusedElement(this.contentElement);} WebInspector.DevicesView.prototype={_selectSidebarListItem:function(listItem,view) {if(this._selectedListItem===listItem) return;if(this._selectedListItem){this._selectedListItem.classList.remove("selected");this._visibleView.detach();} this._visibleView=view;this._selectedListItem=listItem;this._visibleView.show(this._viewContainer);this._selectedListItem.classList.add("selected");},_devicesUpdated:function(event) {this._devices=(event.data).slice().filter(d=>d.adbSerial.toUpperCase()!=="WEBRTC");for(var device of this._devices){if(!device.adbConnected) device.adbModel=WebInspector.UIString("Unknown");} var ids=new Set();for(var device of this._devices) ids.add(device.id);var selectedRemoved=false;for(var deviceId of this._viewById.keys()){if(!ids.has(deviceId)){var listItem=(this._listItemById.get(deviceId));this._listItemById.remove(deviceId);this._viewById.remove(deviceId);listItem.remove();if(listItem===this._selectedListItem) selectedRemoved=true;}} for(var device of this._devices){var view=this._viewById.get(device.id);var listItem=this._listItemById.get(device.id);if(!view){view=new WebInspector.DevicesView.DeviceView();this._viewById.set(device.id,view);listItem=this._createSidebarListItem(view);this._listItemById.set(device.id,listItem);this._sidebarList.insertBefore(listItem,this._sidebarListSpacer);} listItem._title.textContent=device.adbModel;listItem._status.textContent=device.adbConnected?WebInspector.UIString("Connected"):WebInspector.UIString("Pending Authorization");listItem.classList.toggle("device-connected",device.adbConnected);view.update(device);} if(selectedRemoved) this._selectSidebarListItem(this._discoveryListItem,this._discoveryView);this._updateFooter();},_createSidebarListItem:function(view) {var listItem=createElementWithClass("div","devices-sidebar-item");listItem.addEventListener("click",this._selectSidebarListItem.bind(this,listItem,view));listItem._title=listItem.createChild("div","devices-sidebar-item-title");listItem._status=listItem.createChild("div","devices-sidebar-item-status");return listItem;},_devicesDiscoveryConfigChanged:function(event) {var discoverUsbDevices=(event.data["discoverUsbDevices"]);var portForwardingEnabled=(event.data["portForwardingEnabled"]);var portForwardingConfig=(event.data["portForwardingConfig"]);this._discoveryView.discoveryConfigChanged(discoverUsbDevices,portForwardingEnabled,portForwardingConfig);},_devicesPortForwardingStatusChanged:function(event) {var status=(event.data);for(var deviceId in status){var view=this._viewById.get(deviceId);if(view) view.portForwardingStatusChanged(status[deviceId]);} for(var deviceId of this._viewById.keys()){var view=this._viewById.get(deviceId);if(view&&!(deviceId in status)) view.portForwardingStatusChanged({ports:{},browserId:""});}},_updateFooter:function() {this._deviceCountSpan.textContent=!this._devices.length?WebInspector.UIString("No devices detected."):this._devices.length===1?WebInspector.UIString("1 device detected."):WebInspector.UIString("%d devices detected.",this._devices.length);},wasShown:function() {WebInspector.PanelWithSidebar.prototype.wasShown.call(this);InspectorFrontendHost.setDevicesUpdatesEnabled(true);},willHide:function() {WebInspector.PanelWithSidebar.prototype.wasShown.call(this);InspectorFrontendHost.setDevicesUpdatesEnabled(false);},__proto__:WebInspector.VBox.prototype} WebInspector.DevicesView._instance=function() {if(!WebInspector.DevicesView._instanceObject) WebInspector.DevicesView._instanceObject=new WebInspector.DevicesView();return WebInspector.DevicesView._instanceObject;} WebInspector.DevicesView.DiscoveryView=function() {WebInspector.VBox.call(this);this.setMinimumSize(100,100);this.element.classList.add("discovery-view");this.contentElement.createChild("div","hbox device-text-row").createChild("div","view-title").textContent=WebInspector.UIString("Settings");var discoverUsbDevicesCheckbox=createCheckboxLabel(WebInspector.UIString("Discover USB devices"));discoverUsbDevicesCheckbox.classList.add("usb-checkbox");this.element.appendChild(discoverUsbDevicesCheckbox);this._discoverUsbDevicesCheckbox=discoverUsbDevicesCheckbox.checkboxElement;this._discoverUsbDevicesCheckbox.addEventListener("click",this._updateDiscoveryConfig.bind(this),false);var help=this.element.createChild("div","discovery-help");help.createChild("span").textContent=WebInspector.UIString("Need help? Read Chrome ");help.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/chrome-developer-tools/docs/remote-debugging",WebInspector.UIString("remote debugging documentation."),undefined,true));var portForwardingHeader=this.element.createChild("div","port-forwarding-header");var portForwardingEnabledCheckbox=createCheckboxLabel(WebInspector.UIString("Port forwarding"));portForwardingEnabledCheckbox.classList.add("port-forwarding-checkbox");portForwardingHeader.appendChild(portForwardingEnabledCheckbox);this._portForwardingEnabledCheckbox=portForwardingEnabledCheckbox.checkboxElement;this._portForwardingEnabledCheckbox.addEventListener("click",this._updateDiscoveryConfig.bind(this),false);var portForwardingFooter=this.element.createChild("div","port-forwarding-footer");portForwardingFooter.createChild("span").textContent=WebInspector.UIString("Define the listening port on your device that maps to a port accessible from your development machine. ");portForwardingFooter.appendChild(WebInspector.linkifyURLAsNode("https://developer.chrome.com/devtools/docs/remote-debugging#port-forwarding",WebInspector.UIString("Learn more"),undefined,true));this._list=new WebInspector.ListWidget(this);this._list.registerRequiredCSS("devices/devicesView.css");this._list.element.classList.add("port-forwarding-list");var placeholder=createElementWithClass("div","port-forwarding-list-empty");placeholder.textContent=WebInspector.UIString("No rules");this._list.setEmptyPlaceholder(placeholder);this._list.show(this.element);this.element.appendChild(createTextButton(WebInspector.UIString("Add rule"),this._addRuleButtonClicked.bind(this),"add-rule-button"));this._portForwardingConfig=[];} WebInspector.DevicesView.DiscoveryView.prototype={_addRuleButtonClicked:function() {this._list.addNewItem(this._portForwardingConfig.length,{port:"",address:""});},discoveryConfigChanged:function(discoverUsbDevices,portForwardingEnabled,portForwardingConfig) {this._discoverUsbDevicesCheckbox.checked=discoverUsbDevices;this._portForwardingEnabledCheckbox.checked=portForwardingEnabled;this._portForwardingConfig=[];this._list.clear();for(var key of Object.keys(portForwardingConfig)){var rule=({port:key,address:portForwardingConfig[key]});this._portForwardingConfig.push(rule);this._list.appendItem(rule,true);}},renderItem:function(item,editable) {var rule=(item);var element=createElementWithClass("div","port-forwarding-list-item");var port=element.createChild("div","port-forwarding-value port-forwarding-port");port.createChild("span","port-localhost").textContent=WebInspector.UIString("localhost:");port.createTextChild(rule.port);element.createChild("div","port-forwarding-separator");element.createChild("div","port-forwarding-value").textContent=rule.address;return element;},removeItemRequested:function(item,index) {this._portForwardingConfig.splice(index,1);this._list.removeItem(index);this._updateDiscoveryConfig();},commitEdit:function(item,editor,isNew) {var rule=(item);rule.port=editor.control("port").value.trim();rule.address=editor.control("address").value.trim();if(isNew) this._portForwardingConfig.push(rule);this._updateDiscoveryConfig();},beginEdit:function(item) {var rule=(item);var editor=this._createEditor();editor.control("port").value=rule.port;editor.control("address").value=rule.address;return editor;},_createEditor:function() {if(this._editor) return this._editor;var editor=new WebInspector.ListWidget.Editor();this._editor=editor;var content=editor.contentElement();var fields=content.createChild("div","port-forwarding-edit-row");fields.createChild("div","port-forwarding-value port-forwarding-port").appendChild(editor.createInput("port","text","Device port (3333)",portValidator.bind(this)));fields.createChild("div","port-forwarding-separator port-forwarding-separator-invisible");fields.createChild("div","port-forwarding-value").appendChild(editor.createInput("address","text","Local address (dev.example.corp:3333)",addressValidator));return editor;function portValidator(item,index,input) {var value=input.value.trim();var match=value.match(/^(\d+)$/);if(!match) return false;var port=parseInt(match[1],10);if(port<1024||port>65535) return false;for(var i=0;i<this._portForwardingConfig.length;++i){if(i!==index&&this._portForwardingConfig[i].port===value) return false;} return true;} function addressValidator(item,index,input) {var match=input.value.trim().match(/^([a-zA-Z0-9\.\-_]+):(\d+)$/);if(!match) return false;var port=parseInt(match[2],10);return port<=65535;}},_updateDiscoveryConfig:function() {var configMap=({});for(var rule of this._portForwardingConfig) configMap[rule.port]=rule.address;InspectorFrontendHost.setDevicesDiscoveryConfig(this._discoverUsbDevicesCheckbox.checked,this._portForwardingEnabledCheckbox.checked,configMap);},__proto__:WebInspector.VBox.prototype} WebInspector.DevicesView.DeviceView=function() {WebInspector.VBox.call(this);this.setMinimumSize(100,100);this.contentElement.classList.add("device-view");var topRow=this.contentElement.createChild("div","hbox device-text-row");this._deviceTitle=topRow.createChild("div","view-title");this._deviceSerial=topRow.createChild("div","device-serial");this._portStatus=this.contentElement.createChild("div","device-port-status hidden");this._deviceOffline=this.contentElement.createChild("div");this._deviceOffline.textContent=WebInspector.UIString("Pending authentication: please accept debugging session on the device.");this._noBrowsers=this.contentElement.createChild("div");this._noBrowsers.textContent=WebInspector.UIString("No browsers detected.");this._browsers=this.contentElement.createChild("div","device-browser-list vbox");this._browserById=new Map();this._device=null;} WebInspector.DevicesView.BrowserSection;WebInspector.DevicesView.PageSection;WebInspector.DevicesView.DeviceView.prototype={update:function(device) {if(!this._device||this._device.adbModel!==device.adbModel) this._deviceTitle.textContent=device.adbModel;if(!this._device||this._device.adbSerial!==device.adbSerial) this._deviceSerial.textContent="#"+device.adbSerial;this._deviceOffline.classList.toggle("hidden",device.adbConnected);this._noBrowsers.classList.toggle("hidden",!device.adbConnected||!!device.browsers.length);this._browsers.classList.toggle("hidden",!device.adbConnected||!device.browsers.length);var browserIds=new Set();for(var browser of device.browsers) browserIds.add(browser.id);for(var browserId of this._browserById.keys()){if(!browserIds.has(browserId)){this._browserById.get(browserId).element.remove();this._browserById.remove(browserId);}} for(var browser of device.browsers){var section=this._browserById.get(browser.id);if(!section){section=this._createBrowserSection();this._browserById.set(browser.id,section);this._browsers.appendChild(section.element);} this._updateBrowserSection(section,browser);} this._device=device;},_createBrowserSection:function() {var element=createElementWithClass("div","vbox flex-none");var topRow=element.createChild("div","");var title=topRow.createChild("div","device-browser-title");var newTabRow=element.createChild("div","device-browser-new-tab");newTabRow.createChild("div","").textContent=WebInspector.UIString("New tab:");var newTabInput=newTabRow.createChild("input","");newTabInput.type="text";newTabInput.placeholder=WebInspector.UIString("Enter URL");newTabInput.addEventListener("keydown",newTabKeyDown,false);var newTabButton=createTextButton(WebInspector.UIString("Open"),openNewTab);newTabRow.appendChild(newTabButton);var pages=element.createChild("div","device-page-list vbox");var viewMore=element.createChild("div","device-view-more");viewMore.addEventListener("click",viewMoreClick,false);updateViewMoreTitle();var section={browser:null,element:element,title:title,pages:pages,viewMore:viewMore,newTab:newTabRow,pageSections:new Map()};return section;function viewMoreClick() {pages.classList.toggle("device-view-more-toggled");updateViewMoreTitle();} function updateViewMoreTitle() {viewMore.textContent=pages.classList.contains("device-view-more-toggled")?WebInspector.UIString("View less tabs\u2026"):WebInspector.UIString("View more tabs\u2026");} function newTabKeyDown(event) {if(event.keyIdentifier==="Enter"){event.consume(true);openNewTab();}} function openNewTab() {if(section.browser){InspectorFrontendHost.openRemotePage(section.browser.id,newTabInput.value.trim()||"about:blank");newTabInput.value="";}}},_updateBrowserSection:function(section,browser) {if(!section.browser||section.browser.adbBrowserName!==browser.adbBrowserName||section.browser.adbBrowserVersion!==browser.adbBrowserVersion){if(browser.adbBrowserVersion) section.title.textContent=String.sprintf("%s (%s)",browser.adbBrowserName,browser.adbBrowserVersion);else section.title.textContent=browser.adbBrowserName;} var pageIds=new Set();for(var page of browser.pages) pageIds.add(page.id);for(var pageId of section.pageSections.keys()){if(!pageIds.has(pageId)){section.pageSections.get(pageId).element.remove();section.pageSections.remove(pageId);}} for(var index=0;index<browser.pages.length;++index){var page=browser.pages[index];var pageSection=section.pageSections.get(page.id);if(!pageSection){pageSection=this._createPageSection();section.pageSections.set(page.id,pageSection);section.pages.appendChild(pageSection.element);} this._updatePageSection(pageSection,page);if(!index&§ion.pages.firstChild!==pageSection.element) section.pages.insertBefore(pageSection.element,section.pages.firstChild);} var kViewMoreCount=3;for(var index=0,element=section.pages.firstChild;element;element=element.nextSibling,++index) element.classList.toggle("device-view-more-page",index>=kViewMoreCount);section.viewMore.classList.toggle("device-needs-view-more",browser.pages.length>kViewMoreCount);section.newTab.classList.toggle("hidden",!browser.adbBrowserChromeVersion);section.browser=browser;},_createPageSection:function() {var element=createElementWithClass("div","vbox");var titleRow=element.createChild("div","device-page-title-row");var title=titleRow.createChild("div","device-page-title");var inspect=createTextButton(WebInspector.UIString("Inspect"),doAction.bind(null,"inspect"),"device-inspect-button");titleRow.appendChild(inspect);var toolbar=new WebInspector.Toolbar("");toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(appendActions));titleRow.appendChild(toolbar.element);var url=element.createChild("div","device-page-url");var section={page:null,element:element,title:title,url:url,inspect:inspect};return section;function appendActions(contextMenu) {contextMenu.appendItem(WebInspector.UIString("Reload"),doAction.bind(null,"reload"));contextMenu.appendItem(WebInspector.UIString("Focus"),doAction.bind(null,"activate"));contextMenu.appendItem(WebInspector.UIString("Close"),doAction.bind(null,"close"));} function doAction(action) {if(section.page) InspectorFrontendHost.performActionOnRemotePage(section.page.id,action);}},_updatePageSection:function(section,page) {if(!section.page||section.page.name!==page.name){section.title.textContent=page.name;section.title.title=page.name;} if(!section.page||section.page.url!==page.url){section.url.textContent="";section.url.appendChild(WebInspector.linkifyURLAsNode(page.url,undefined,undefined,true));} section.inspect.disabled=page.adbAttachedForeign;section.page=page;},portForwardingStatusChanged:function(status) {var json=JSON.stringify(status);if(json===this._cachedPortStatus) return;this._cachedPortStatus=json;this._portStatus.removeChildren();this._portStatus.createChild("div","device-port-status-text").textContent=WebInspector.UIString("Port Forwarding:");var connected=[];var transient=[];var error=[];var empty=true;for(var port in status.ports){if(!status.ports.hasOwnProperty(port)) continue;empty=false;var portStatus=status.ports[port];var portNumber=createElementWithClass("div","device-view-port-number monospace");portNumber.textContent=":"+port;if(portStatus>=0) this._portStatus.appendChild(portNumber);else this._portStatus.insertBefore(portNumber,this._portStatus.firstChild);var portIcon=createElementWithClass("div","device-view-port-icon");if(portStatus>=0){connected.push(port);}else if(portStatus===-1||portStatus===-2){portIcon.classList.add("device-view-port-icon-transient");transient.push(port);}else if(portStatus<0){portIcon.classList.add("device-view-port-icon-error");error.push(port);} this._portStatus.insertBefore(portIcon,portNumber);} var title=[];if(connected.length) title.push(WebInspector.UIString("Connected: %s",connected.join(", ")));if(transient.length) title.push(WebInspector.UIString("Transient: %s",transient.join(", ")));if(error.length) title.push(WebInspector.UIString("Error: %s",error.join(", ")));this._portStatus.title=title.join("; ");this._portStatus.classList.toggle("hidden",empty);},__proto__:WebInspector.VBox.prototype};WebInspector.DevicesDialog=function() {} WebInspector.DevicesDialog.ActionDelegate=function() {this._view=null;} WebInspector.DevicesDialog.ActionDelegate.prototype={handleAction:function(context,actionId) {if(actionId==="devices.dialog.show"){if(!this._view) this._view=new WebInspector.DevicesView();var dialog=new WebInspector.Dialog();dialog.addCloseButton();this._view.show(dialog.element);dialog.setMaxSize(new Size(700,500));dialog.show();return true;} return false;}};Runtime.cachedResources["devices/devicesView.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.devices-view {\n padding-top: 15px;\n}\n\n.devices-container {\n overflow: hidden;\n flex: auto;\n}\n\n.devices-sidebar {\n flex: 0 0 150px;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n}\n\n.devices-sidebar-list {\n flex: none;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n}\n\n.devices-sidebar-item {\n color: #222 !important;\n padding: 6px 6px 6px 16px;\n flex: auto;\n display: flex;\n flex-direction: column;\n justify-content: center;\n font-size: 14px;\n}\n\n.devices-sidebar-item.selected {\n border-left: 6px solid #666 !important;\n padding-left: 10px;\n}\n\n.devices-sidebar-item-status {\n font-size: 11px;\n}\n\n.devices-sidebar-item-status:before {\n content: \"\\25cf\";\n font-size: 16px;\n color: red;\n position: relative;\n top: 1px;\n margin-right: 2px;\n}\n\n.devices-sidebar-item.device-connected .devices-sidebar-item-status:before {\n color: green;\n}\n\n.devices-sidebar-spacer {\n flex: none;\n}\n\n.devices-view-title {\n font-size: 16px;\n margin: 0 0 15px 15px;\n padding-top: 1px;\n}\n\n.view-title {\n font-size: 16px;\n flex: none;\n}\n\n.devices-footer {\n border-top: 1px solid #cdcdcd;\n background-color: #f3f3f3;\n flex: none;\n padding: 3px 10px;\n}\n\n.devices-footer > span {\n white-space: pre;\n}\n\n.usb-checkbox {\n padding-bottom: 8px;\n margin-top: 20px;\n}\n\n.port-forwarding-header {\n display: flex;\n align-items: center;\n flex-direction: row;\n margin-top: 5px;\n}\n\n.add-rule-button {\n margin: 10px 25px;\n align-self: flex-start;\n}\n\n.discovery-help {\n margin: 5px 0 25px 25px;\n}\n\n.discovery-help > span {\n white-space: pre;\n}\n\n.port-forwarding-list {\n margin: 10px 0 0 25px;\n max-width: 500px;\n flex: 0 1 auto;\n}\n\n.port-forwarding-list-empty {\n flex: auto;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.port-forwarding-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n flex: auto 1 1;\n}\n\n.port-forwarding-value {\n white-space: nowrap;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n color: #222;\n flex: 3 1 0;\n overflow: hidden;\n}\n\n.port-forwarding-value.port-forwarding-port {\n flex: 1 1 0;\n}\n\n.port-localhost {\n color: #aaa;\n}\n\n.port-forwarding-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.port-forwarding-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.port-forwarding-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n align-items: center;\n}\n\n.port-forwarding-edit-row input {\n width: 100%;\n text-align: inherit;\n}\n\n.port-forwarding-footer {\n overflow: hidden;\n margin: 15px 0 0 25px;\n max-width: 500px;\n}\n\n.port-forwarding-footer > * {\n white-space: pre-wrap;\n}\n\n.device-view {\n overflow: auto;\n -webkit-user-select: text;\n flex: auto;\n}\n\n.device-text-row {\n align-items: baseline;\n margin-right: 25px;\n}\n\n.device-serial {\n color: #777;\n margin-left: 5px;\n flex: none;\n}\n\n.device-browser-list {\n flex: auto;\n overflow: auto;\n padding-right: 10px;\n margin-top: 20px;\n}\n\n.device-browser-list > div {\n margin-bottom: 15px;\n}\n\n.device-browser-title {\n font-size: 16px;\n}\n\n.device-browser-new-tab {\n display: flex;\n flex-direction: row;\n align-items: center;\n margin: 10px 0 0 10px;\n}\n\n.device-browser-new-tab > div {\n font-size: 13px;\n}\n\n.device-browser-new-tab > input {\n margin: 0 10px;\n}\n\n.device-page-list {\n margin: 10px 0 0 10px;\n overflow-x: auto;\n align-items: stretch;\n flex: none;\n}\n\n.device-page-list > div {\n flex: none;\n padding: 5px 0;\n}\n\n.device-page-list:not(.device-view-more-toggled) > div.device-view-more-page {\n display: none;\n}\n\n.device-page-title-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.device-page-title {\n font-size: 15px;\n flex: auto;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.device-page-title-row .toolbar {\n margin-left: 3px;\n padding: 0;\n border-radius: 3px;\n}\n\n.device-page-title-row .toolbar:hover {\n background-color: hsl(0, 0%, 90%);\n}\n\n.device-page-url {\n margin: 3px 0;\n}\n\n.device-page-url a {\n color: #777;\n word-break: break-all;\n}\n\n.device-view-more {\n cursor: pointer;\n text-decoration: underline;\n color: rgb(17, 85, 204);\n margin: 5px 0 0 10px;\n display: none;\n}\n\n.device-view-more.device-needs-view-more {\n display: block;\n}\n\n.device-port-status {\n overflow: hidden;\n flex: none;\n display: flex;\n align-items: baseline;\n margin: 10px 0 0 10px;\n}\n\n.device-port-status-text {\n margin-right: 10px;\n}\n\n.device-view-port-icon {\n background-color: green;\n border: 0 solid transparent;\n border-radius: 6px;\n height: 12px;\n width: 12px;\n position: relative;\n top: 2px;\n flex: none;\n}\n\n.device-view-port-number {\n margin: 0 10px 0 2px;\n flex: none;\n}\n\n.device-view-port-icon.device-view-port-icon-error {\n background-color: red;\n}\n\n.device-view-port-icon.device-view-port-icon-transient {\n transform: scale(1.2);\n background-color: orange;\n}\n\n/*# sourceURL=devices/devicesView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. (function(window) { // DevToolsAPI ---------------------------------------------------------------- /** * @constructor */ function DevToolsAPIImpl() { /** * @type {number} */ this._lastCallId = 0; /** * @type {!Object.<number, function(?Object)>} */ this._callbacks = {}; } DevToolsAPIImpl.prototype = { /** * @param {number} id * @param {?Object} arg */ embedderMessageAck: function(id, arg) { var callback = this._callbacks[id]; delete this._callbacks[id]; if (callback) callback(arg); }, /** * @param {string} method * @param {!Array.<*>} args * @param {?function(?Object)} callback */ sendMessageToEmbedder: function(method, args, callback) { var callId = ++this._lastCallId; if (callback) this._callbacks[callId] = callback; var message = { "id": callId, "method": method }; if (args.length) message.params = args; DevToolsHost.sendMessageToEmbedder(JSON.stringify(message)); }, /** * @param {string} method * @param {!Array.<*>} args */ _dispatchOnInspectorFrontendAPI: function(method, args) { var api = window["InspectorFrontendAPI"]; api[method].apply(api, args); }, // API methods below this line -------------------------------------------- /** * @param {!Array.<!ExtensionDescriptor>} extensions */ addExtensions: function(extensions) { // Support for legacy front-ends (<M41). if (window["WebInspector"].addExtensions) window["WebInspector"].addExtensions(extensions); else this._dispatchOnInspectorFrontendAPI("addExtensions", [extensions]); }, /** * @param {string} url */ appendedToURL: function(url) { this._dispatchOnInspectorFrontendAPI("appendedToURL", [url]); }, /** * @param {string} url */ canceledSaveURL: function(url) { this._dispatchOnInspectorFrontendAPI("canceledSaveURL", [url]); }, contextMenuCleared: function() { this._dispatchOnInspectorFrontendAPI("contextMenuCleared", []); }, /** * @param {string} id */ contextMenuItemSelected: function(id) { this._dispatchOnInspectorFrontendAPI("contextMenuItemSelected", [id]); }, /** * @param {number} count */ deviceCountUpdated: function(count) { this._dispatchOnInspectorFrontendAPI("deviceCountUpdated", [count]); }, /** * @param {boolean} discoverUsbDevices * @param {boolean} portForwardingEnabled * @param {!Adb.PortForwardingConfig} portForwardingConfig */ devicesDiscoveryConfigChanged: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig) { this._dispatchOnInspectorFrontendAPI("devicesDiscoveryConfigChanged", [discoverUsbDevices, portForwardingEnabled, portForwardingConfig]); }, /** * @param {!Adb.PortForwardingStatus} status */ devicesPortForwardingStatusChanged: function(status) { this._dispatchOnInspectorFrontendAPI("devicesPortForwardingStatusChanged", [status]); }, /** * @param {!Array.<!Adb.Device>} devices */ devicesUpdated: function(devices) { this._dispatchOnInspectorFrontendAPI("devicesUpdated", [devices]); }, /** * @param {string} message */ dispatchMessage: function(message) { this._dispatchOnInspectorFrontendAPI("dispatchMessage", [message]); }, /** * @param {string} messageChunk * @param {number} messageSize */ dispatchMessageChunk: function(messageChunk, messageSize) { this._dispatchOnInspectorFrontendAPI("dispatchMessageChunk", [messageChunk, messageSize]); }, enterInspectElementMode: function() { this._dispatchOnInspectorFrontendAPI("enterInspectElementMode", []); }, /** * @param {number} callId * @param {string} script */ evaluateForTestInFrontend: function(callId, script) { this._dispatchOnInspectorFrontendAPI("evaluateForTestInFrontend", [callId, script]); }, /** * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems */ fileSystemsLoaded: function(fileSystems) { this._dispatchOnInspectorFrontendAPI("fileSystemsLoaded", [fileSystems]); }, /** * @param {string} fileSystemPath */ fileSystemRemoved: function(fileSystemPath) { this._dispatchOnInspectorFrontendAPI("fileSystemRemoved", [fileSystemPath]); }, /** * @param {!{fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem */ fileSystemAdded: function(fileSystem) { this._dispatchOnInspectorFrontendAPI("fileSystemAdded", ["", fileSystem]); }, fileSystemFilesChanged: function(path) { this._dispatchOnInspectorFrontendAPI("fileSystemFilesChanged", [path]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {number} totalWork */ indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork) { this._dispatchOnInspectorFrontendAPI("indexingTotalWorkCalculated", [requestId, fileSystemPath, totalWork]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {number} worked */ indexingWorked: function(requestId, fileSystemPath, worked) { this._dispatchOnInspectorFrontendAPI("indexingWorked", [requestId, fileSystemPath, worked]); }, /** * @param {number} requestId * @param {string} fileSystemPath */ indexingDone: function(requestId, fileSystemPath) { this._dispatchOnInspectorFrontendAPI("indexingDone", [requestId, fileSystemPath]); }, /** * @param {{type: string, keyIdentifier: string, keyCode: number, modifiers: number}} event */ keyEventUnhandled: function(event) { this._dispatchOnInspectorFrontendAPI("keyEventUnhandled", [event]); }, /** * @param {boolean} hard */ reloadInspectedPage: function(hard) { this._dispatchOnInspectorFrontendAPI("reloadInspectedPage", [hard]); }, /** * @param {string} url * @param {number} lineNumber * @param {number} columnNumber */ revealSourceLine: function(url, lineNumber, columnNumber) { this._dispatchOnInspectorFrontendAPI("revealSourceLine", [url, lineNumber, columnNumber]); }, /** * @param {string} url */ savedURL: function(url) { this._dispatchOnInspectorFrontendAPI("savedURL", [url]); }, /** * @param {number} requestId * @param {string} fileSystemPath * @param {!Array.<string>} files */ searchCompleted: function(requestId, fileSystemPath, files) { this._dispatchOnInspectorFrontendAPI("searchCompleted", [requestId, fileSystemPath, files]); }, /** * @param {string} tabId */ setInspectedTabId: function(tabId) { // Support for legacy front-ends (<M41). if (window["WebInspector"].setInspectedTabId) window["WebInspector"].setInspectedTabId(tabId); else this._dispatchOnInspectorFrontendAPI("setInspectedTabId", [tabId]); }, /** * @param {boolean} useSoftMenu */ setUseSoftMenu: function(useSoftMenu) { this._dispatchOnInspectorFrontendAPI("setUseSoftMenu", [useSoftMenu]); }, /** * @param {string} panelName */ showPanel: function(panelName) { this._dispatchOnInspectorFrontendAPI("showPanel", [panelName]); }, /** * @param {number} id * @param {string} chunk * @param {boolean} encoded */ streamWrite: function(id, chunk, encoded) { this._dispatchOnInspectorFrontendAPI("streamWrite", [id, encoded ? this._decodeBase64(chunk) : chunk]); }, /** * @param {string} chunk * @return {string} */ _decodeBase64: function(chunk) { var request = new XMLHttpRequest(); request.open("GET", "data:text/plain;base64," + chunk, false); request.send(null); if (request.status === 200) { return request.responseText; } else { console.error("Error while decoding chunk in streamWrite"); return ""; } } } var DevToolsAPI = new DevToolsAPIImpl(); window.DevToolsAPI = DevToolsAPI; // InspectorFrontendHostImpl -------------------------------------------------- /** * @constructor * @implements {InspectorFrontendHostAPI} */ function InspectorFrontendHostImpl() { } InspectorFrontendHostImpl.prototype = { /** * @override * @return {string} */ getSelectionBackgroundColor: function() { return DevToolsHost.getSelectionBackgroundColor(); }, /** * @override * @return {string} */ getSelectionForegroundColor: function() { return DevToolsHost.getSelectionForegroundColor(); }, /** * @override * @return {string} */ platform: function() { return DevToolsHost.platform(); }, /** * @override */ loadCompleted: function() { DevToolsAPI.sendMessageToEmbedder("loadCompleted", [], null); }, /** * @override */ bringToFront: function() { DevToolsAPI.sendMessageToEmbedder("bringToFront", [], null); }, /** * @override */ closeWindow: function() { DevToolsAPI.sendMessageToEmbedder("closeWindow", [], null); }, /** * @override * @param {boolean} isDocked * @param {function()} callback */ setIsDocked: function(isDocked, callback) { DevToolsAPI.sendMessageToEmbedder("setIsDocked", [isDocked], callback); }, /** * Requests inspected page to be placed atop of the inspector frontend with specified bounds. * @override * @param {{x: number, y: number, width: number, height: number}} bounds */ setInspectedPageBounds: function(bounds) { DevToolsAPI.sendMessageToEmbedder("setInspectedPageBounds", [bounds], null); }, /** * @override */ inspectElementCompleted: function() { DevToolsAPI.sendMessageToEmbedder("inspectElementCompleted", [], null); }, /** * @override * @param {string} url * @param {string} headers * @param {number} streamId * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback */ loadNetworkResource: function(url, headers, streamId, callback) { DevToolsAPI.sendMessageToEmbedder("loadNetworkResource", [url, headers, streamId], /** @type {function(?Object)} */ (callback)); }, /** * @override * @param {function(!Object<string, string>)} callback */ getPreferences: function(callback) { DevToolsAPI.sendMessageToEmbedder("getPreferences", [], /** @type {function(?Object)} */ (callback)); }, /** * @override * @param {string} name * @param {string} value */ setPreference: function(name, value) { DevToolsAPI.sendMessageToEmbedder("setPreference", [name, value], null); }, /** * @override * @param {string} name */ removePreference: function(name) { DevToolsAPI.sendMessageToEmbedder("removePreference", [name], null); }, /** * @override */ clearPreferences: function() { DevToolsAPI.sendMessageToEmbedder("clearPreferences", [], null); }, /** * @override * @param {string} origin * @param {string} script */ setInjectedScriptForOrigin: function(origin, script) { DevToolsHost.setInjectedScriptForOrigin(origin, script); }, /** * @override * @param {string} url */ inspectedURLChanged: function(url) { DevToolsAPI.sendMessageToEmbedder("inspectedURLChanged", [url], null); }, /** * @override * @param {string} text */ copyText: function(text) { DevToolsHost.copyText(text); }, /** * @override * @param {string} url */ openInNewTab: function(url) { DevToolsAPI.sendMessageToEmbedder("openInNewTab", [url], null); }, /** * @override * @param {string} url * @param {string} content * @param {boolean} forceSaveAs */ save: function(url, content, forceSaveAs) { DevToolsAPI.sendMessageToEmbedder("save", [url, content, forceSaveAs], null); }, /** * @override * @param {string} url * @param {string} content */ append: function(url, content) { DevToolsAPI.sendMessageToEmbedder("append", [url, content], null); }, /** * @override * @param {string} message */ sendMessageToBackend: function(message) { DevToolsAPI.sendMessageToEmbedder("dispatchProtocolMessage", [message], null); }, /** * @override * @param {string} actionName * @param {number} actionCode * @param {number} bucketSize */ recordEnumeratedHistogram: function(actionName, actionCode, bucketSize) { // Support for M49 frontend. if (actionName === "DevTools.DrawerShown") return; DevToolsAPI.sendMessageToEmbedder("recordEnumeratedHistogram", [actionName, actionCode, bucketSize], null); }, /** * @override */ requestFileSystems: function() { DevToolsAPI.sendMessageToEmbedder("requestFileSystems", [], null); }, /** * @override * @param {string=} fileSystemPath */ addFileSystem: function(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("addFileSystem", [fileSystemPath || ""], null); }, /** * @override * @param {string} fileSystemPath */ removeFileSystem: function(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("removeFileSystem", [fileSystemPath], null); }, /** * @override * @param {string} fileSystemId * @param {string} registeredName * @return {?DOMFileSystem} */ isolatedFileSystem: function(fileSystemId, registeredName) { return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName); }, /** * @override * @param {!FileSystem} fileSystem */ upgradeDraggedFileSystemPermissions: function(fileSystem) { DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem); }, /** * @override * @param {number} requestId * @param {string} fileSystemPath */ indexPath: function(requestId, fileSystemPath) { DevToolsAPI.sendMessageToEmbedder("indexPath", [requestId, fileSystemPath], null); }, /** * @override * @param {number} requestId */ stopIndexing: function(requestId) { DevToolsAPI.sendMessageToEmbedder("stopIndexing", [requestId], null); }, /** * @override * @param {number} requestId * @param {string} fileSystemPath * @param {string} query */ searchInPath: function(requestId, fileSystemPath, query) { DevToolsAPI.sendMessageToEmbedder("searchInPath", [requestId, fileSystemPath, query], null); }, /** * @override * @return {number} */ zoomFactor: function() { return DevToolsHost.zoomFactor(); }, /** * @override */ zoomIn: function() { DevToolsAPI.sendMessageToEmbedder("zoomIn", [], null); }, /** * @override */ zoomOut: function() { DevToolsAPI.sendMessageToEmbedder("zoomOut", [], null); }, /** * @override */ resetZoom: function() { DevToolsAPI.sendMessageToEmbedder("resetZoom", [], null); }, /** * @override * @param {string} shortcuts */ setWhitelistedShortcuts: function(shortcuts) { DevToolsAPI.sendMessageToEmbedder("setWhitelistedShortcuts", [shortcuts], null); }, /** * @override * @return {boolean} */ isUnderTest: function() { return DevToolsHost.isUnderTest(); }, /** * @override */ readyForTest: function() { DevToolsAPI.sendMessageToEmbedder("readyForTest", [], null); }, /** * @override * @param {boolean} discoverUsbDevices * @param {boolean} portForwardingEnabled * @param {!Adb.PortForwardingConfig} portForwardingConfig */ setDevicesDiscoveryConfig: function(discoverUsbDevices, portForwardingEnabled, portForwardingConfig) { DevToolsAPI.sendMessageToEmbedder("setDevicesDiscoveryConfig", [discoverUsbDevices, portForwardingEnabled, JSON.stringify(portForwardingConfig)], null); }, /** * @override * @param {boolean} enabled */ setDevicesUpdatesEnabled: function(enabled) { DevToolsAPI.sendMessageToEmbedder("setDevicesUpdatesEnabled", [enabled], null); }, /** * @override * @param {string} pageId * @param {string} action */ performActionOnRemotePage: function(pageId, action) { DevToolsAPI.sendMessageToEmbedder("performActionOnRemotePage", [pageId, action], null); }, /** * @override * @param {string} browserId * @param {string} url */ openRemotePage: function(browserId, url) { DevToolsAPI.sendMessageToEmbedder("openRemotePage", [browserId, url], null); }, /** * @override * @param {number} x * @param {number} y * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items * @param {!Document} document */ showContextMenuAtPoint: function(x, y, items, document) { DevToolsHost.showContextMenuAtPoint(x, y, items, document); }, /** * @override * @return {boolean} */ isHostedMode: function() { return DevToolsHost.isHostedMode(); }, // Backward-compatible methods below this line -------------------------------------------- /** * Support for legacy front-ends (<M50). * @param {string} message */ sendFrontendAPINotification: function(message) { }, /** * Support for legacy front-ends (<M41). * @return {string} */ port: function() { return "unknown"; }, /** * Support for legacy front-ends (<M38). * @param {number} zoomFactor */ setZoomFactor: function(zoomFactor) { }, /** * Support for legacy front-ends (<M34). */ sendMessageToEmbedder: function() { }, /** * Support for legacy front-ends (<M34). * @param {string} dockSide */ requestSetDockSide: function(dockSide) { DevToolsAPI.sendMessageToEmbedder("setIsDocked", [dockSide !== "undocked"], null); }, /** * Support for legacy front-ends (<M34). * @return {boolean} */ supportsFileSystems: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canInspectWorkers: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canSaveAs: function() { return true; }, /** * Support for legacy front-ends (<M28). * @return {boolean} */ canSave: function() { return true; }, /** * Support for legacy front-ends (<M28). */ loaded: function() { }, /** * Support for legacy front-ends (<M28). * @return {string} */ hiddenPanels: function() { return ""; }, /** * Support for legacy front-ends (<M28). * @return {string} */ localizedStringsURL: function() { return ""; }, /** * Support for legacy front-ends (<M28). * @param {string} url */ close: function(url) { }, /** * Support for legacy front-ends (<M44). * @param {number} actionCode */ recordActionTaken: function(actionCode) { this.recordEnumeratedHistogram("DevTools.ActionTaken", actionCode, 100); }, /** * Support for legacy front-ends (<M44). * @param {number} panelCode */ recordPanelShown: function(panelCode) { this.recordEnumeratedHistogram("DevTools.PanelShown", panelCode, 20); } } window.InspectorFrontendHost = new InspectorFrontendHostImpl(); // DevToolsApp --------------------------------------------------------------- function installObjectObserve() { var properties = [ "advancedSearchConfig", "auditsPanelSplitViewState", "auditsSidebarWidth", "blockedURLs", "breakpoints", "cacheDisabled", "colorFormat", "consoleHistory", "consoleTimestampsEnabled", "cpuProfilerView", "cssSourceMapsEnabled", "currentDockState", "customColorPalette", "customDevicePresets", "customEmulatedDeviceList", "customFormatters", "customUserAgent", "databaseTableViewVisibleColumns", "dataGrid-cookiesTable", "dataGrid-DOMStorageItemsView", "debuggerSidebarHidden", "disableDataSaverInfobar", "disablePausedStateOverlay", "domBreakpoints", "domWordWrap", "elementsPanelSplitViewState", "elementsSidebarWidth", "emulation.deviceHeight", "emulation.deviceModeValue", "emulation.deviceOrientationOverride", "emulation.deviceScale", "emulation.deviceScaleFactor", "emulation.deviceUA", "emulation.deviceWidth", "emulation.geolocationOverride", "emulation.showDeviceMode", "emulation.showRulers", "enableAsyncStackTraces", "eventListenerBreakpoints", "fileMappingEntries", "fileSystemMapping", "FileSystemViewSidebarWidth", "fileSystemViewSplitViewState", "filterBar-consoleView", "filterBar-networkPanel", "filterBar-promisePane", "filterBar-timelinePanel", "frameViewerHideChromeWindow", "heapSnapshotRetainersViewSize", "heapSnapshotSplitViewState", "hideCollectedPromises", "hideNetworkMessages", "highlightNodeOnHoverInOverlay", "highResolutionCpuProfiling", "inlineVariableValues", "Inspector.drawerSplitView", "Inspector.drawerSplitViewState", "InspectorView.panelOrder", "InspectorView.screencastSplitView", "InspectorView.screencastSplitViewState", "InspectorView.splitView", "InspectorView.splitViewState", "javaScriptDisabled", "jsSourceMapsEnabled", "lastActivePanel", "lastDockState", "lastSelectedSourcesSidebarPaneTab", "lastSnippetEvaluationIndex", "layerDetailsSplitView", "layerDetailsSplitViewState", "layersPanelSplitViewState", "layersShowInternalLayers", "layersSidebarWidth", "messageLevelFilters", "messageURLFilters", "monitoringXHREnabled", "navigatorGroupByFolder", "navigatorHidden", "networkColorCodeResourceTypes", "networkConditions", "networkConditionsCustomProfiles", "networkHideDataURL", "networkLogColumnsVisibility", "networkLogLargeRows", "networkLogShowOverview", "networkPanelSplitViewState", "networkRecordFilmStripSetting", "networkResourceTypeFilters", "networkShowPrimaryLoadWaterfall", "networkSidebarWidth", "openLinkHandler", "pauseOnCaughtException", "pauseOnExceptionEnabled", "preserveConsoleLog", "prettyPrintInfobarDisabled", "previouslyViewedFiles", "profilesPanelSplitViewState", "profilesSidebarWidth", "promiseStatusFilters", "recordAllocationStacks", "requestHeaderFilterSetting", "request-info-formData-category-expanded", "request-info-general-category-expanded", "request-info-queryString-category-expanded", "request-info-requestHeaders-category-expanded", "request-info-requestPayload-category-expanded", "request-info-responseHeaders-category-expanded", "resources", "resourcesLastSelectedItem", "resourcesPanelSplitViewState", "resourcesSidebarWidth", "resourceViewTab", "savedURLs", "screencastEnabled", "scriptsPanelNavigatorSidebarWidth", "searchInContentScripts", "selectedAuditCategories", "selectedColorPalette", "selectedProfileType", "shortcutPanelSwitch", "showAdvancedHeapSnapshotProperties", "showEventListenersForAncestors", "showFrameowkrListeners", "showHeaSnapshotObjectsHiddenProperties", "showInheritedComputedStyleProperties", "showMediaQueryInspector", "showNativeFunctionsInJSProfile", "showUAShadowDOM", "showWhitespacesInEditor", "sidebarPosition", "skipContentScripts", "skipStackFramesPattern", "sourceMapInfobarDisabled", "sourcesPanelDebuggerSidebarSplitViewState", "sourcesPanelNavigatorSplitViewState", "sourcesPanelSplitSidebarRatio", "sourcesPanelSplitViewState", "sourcesSidebarWidth", "standardEmulatedDeviceList", "StylesPaneSplitRatio", "stylesPaneSplitViewState", "textEditorAutocompletion", "textEditorAutoDetectIndent", "textEditorBracketMatching", "textEditorIndent", "timelineCaptureFilmStrip", "timelineCaptureLayersAndPictures", "timelineCaptureMemory", "timelineCaptureNetwork", "timeline-details", "timelineEnableJSSampling", "timelineOverviewMode", "timelinePanelDetailsSplitViewState", "timelinePanelRecorsSplitViewState", "timelinePanelTimelineStackSplitViewState", "timelinePerspective", "timeline-split", "timelineTreeGroupBy", "timeline-view", "timelineViewMode", "uiTheme", "watchExpressions", "WebInspector.Drawer.lastSelectedView", "WebInspector.Drawer.showOnLoad", "workspaceExcludedFolders", "workspaceFolderExcludePattern", "workspaceInfobarDisabled", "workspaceMappingInfobarDisabled", "xhrBreakpoints"]; /** * @this {!{_storage: Object, _name: string}} */ function settingRemove() { this._storage[this._name] = undefined; } function objectObserve(object, observer) { if (window["WebInspector"]) { var settingPrototype = window["WebInspector"]["Setting"]["prototype"]; if (typeof settingPrototype["remove"] === "function") settingPrototype["remove"] = settingRemove; } var changedProperties = new Set(); var scheduled = false; function scheduleObserver() { if (!scheduled) { scheduled = true; setImmediate(callObserver); } } function callObserver() { scheduled = false; var changes = []; changedProperties.forEach(function(name) { changes.push({name: name}); }); changedProperties.clear(); observer.call(null, changes); } var storage = new Map(); function defineProperty(property) { if (property in object) { storage.set(property, object[property]); delete object[property]; } Object.defineProperty(object, property, { get: function() { return storage.get(property); }, set: function(value) { storage.set(property, value); changedProperties.add(property); scheduleObserver(); } }); } for (var i = 0; i < properties.length; ++i) defineProperty(properties[i]); } window.Object.observe = objectObserve; } /** * @suppressGlobalPropertiesCheck */ function sanitizeRemoteFrontendUrl() { var remoteBaseRegexp = /^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/; var remoteFrontendUrlRegexp = /^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_rev\/@?[0-9a-zA-Z]+\/(devtools|inspector)\.html$/; var queryParams = location.search; if (!queryParams) return; var params = queryParams.substring(1).split("&"); for (var i = 0; i < params.length; ++i) { var pair = params[i].split("="); var name = pair.shift(); var value = pair.join("="); if (name === "remoteFrontendUrl" && !remoteFrontendUrlRegexp.test(value)) location.search = ""; if (name === "remoteBase" && !remoteBaseRegexp.test(value)) location.search = ""; } } /** * @suppressGlobalPropertiesCheck */ function installBackwardsCompatibility() { sanitizeRemoteFrontendUrl(); if (window.location.search.indexOf("remoteFrontend") === -1) return; // Support for legacy (<M50) frontends. installObjectObserve(); /** * @this {CSSStyleDeclaration} */ function getValue(property) { // Note that |property| comes from another context, so we can't use === here. if (property == "padding-left") { return { /** * @suppressReceiverCheck * @this {Object} */ getFloatValue: function() { return this.__paddingLeft; }, __paddingLeft: parseFloat(this.paddingLeft) }; } throw new Error("getPropertyCSSValue is undefined"); } // Support for legacy (<M41) frontends. Remove in M45. window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue; function CSSPrimitiveValue() { } CSSPrimitiveValue.CSS_PX = 5; window.CSSPrimitiveValue = CSSPrimitiveValue; // Support for legacy (<M44) frontends. Remove in M48. var styleElement = window.document.createElement("style"); styleElement.type = "text/css"; styleElement.textContent = "html /deep/ * { min-width: 0; min-height: 0; }"; // Support for quirky border-image behavior (<M51), see: // https://bugs.chromium.org/p/chromium/issues/detail?id=559258 styleElement.textContent += "\nhtml /deep/ .cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }"; styleElement.textContent += "\nhtml /deep/ .cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }"; window.document.head.appendChild(styleElement); // Support for legacy (<M49) frontends. Remove in M52. Event.prototype.deepPath = undefined; } function windowLoaded() { window.removeEventListener("DOMContentLoaded", windowLoaded, false); installBackwardsCompatibility(); } sanitizeRemoteFrontendUrl(); if (window.document.head && (window.document.readyState === "complete" || window.document.readyState === "interactive")) installBackwardsCompatibility(); else window.addEventListener("DOMContentLoaded", windowLoaded, false); })(window); if (!DOMTokenList.prototype.__originalDOMTokenListToggle) { DOMTokenList.prototype.__originalDOMTokenListToggle = DOMTokenList.prototype.toggle; DOMTokenList.prototype.toggle = function(token, force) { if (arguments.length === 1) force = !this.contains(token); return this.__originalDOMTokenListToggle(token, !!force); } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 | (function() {
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function defineCommonExtensionSymbols(apiPrivate)
{
if (!apiPrivate.audits)
apiPrivate.audits = {};
apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
};
if (!apiPrivate.panels)
apiPrivate.panels = {};
apiPrivate.panels.SearchAction = {
CancelSearch: "cancelSearch",
PerformSearch: "performSearch",
NextSearchResult: "nextSearchResult",
PreviousSearchResult: "previousSearchResult"
};
apiPrivate.Events = {
AuditStarted: "audit-started-",
ButtonClicked: "button-clicked-",
PanelObjectSelected: "panel-objectSelected-",
NetworkRequestFinished: "network-request-finished",
OpenResource: "open-resource",
PanelSearch: "panel-search-",
ResourceAdded: "resource-added",
ResourceContentCommitted: "resource-content-committed",
ViewShown: "view-shown-",
ViewHidden: "view-hidden-"
};
apiPrivate.Commands = {
AddAuditCategory: "addAuditCategory",
AddAuditResult: "addAuditResult",
AddRequestHeaders: "addRequestHeaders",
ApplyStyleSheet: "applyStyleSheet",
CreatePanel: "createPanel",
CreateSidebarPane: "createSidebarPane",
CreateToolbarButton: "createToolbarButton",
EvaluateOnInspectedPage: "evaluateOnInspectedPage",
ForwardKeyboardEvent: "_forwardKeyboardEvent",
GetHAR: "getHAR",
GetPageResources: "getPageResources",
GetRequestContent: "getRequestContent",
GetResourceContent: "getResourceContent",
InspectedURLChanged: "inspectedURLChanged",
OpenResource: "openResource",
Reload: "Reload",
Subscribe: "subscribe",
SetOpenResourceHandler: "setOpenResourceHandler",
SetResourceContent: "setResourceContent",
SetSidebarContent: "setSidebarContent",
SetSidebarPage: "setSidebarPage",
ShowPanel: "showPanel",
StopAuditCategoryRun: "stopAuditCategoryRun",
Unsubscribe: "unsubscribe",
UpdateAuditProgress: "updateAuditProgress",
UpdateButton: "updateButton"
};
}
/**
* @param {number} injectedScriptId
* @return {!Object}
* @suppressGlobalPropertiesCheck
*/
function injectedExtensionAPI(injectedScriptId)
{
var apiPrivate = {};
defineCommonExtensionSymbols(apiPrivate);
var commands = apiPrivate.Commands;
var events = apiPrivate.Events;
var userAction = false;
// Here and below, all constructors are private to API implementation.
// For a public type Foo, if internal fields are present, these are on
// a private FooImpl type, an instance of FooImpl is used in a closure
// by Foo consutrctor to re-bind publicly exported members to an instance
// of Foo.
/**
* @constructor
*/
function EventSinkImpl(type, customDispatch)
{
this._type = type;
this._listeners = [];
this._customDispatch = customDispatch;
}
EventSinkImpl.prototype = {
addListener: function(callback)
{
if (typeof callback !== "function")
throw "addListener: callback is not a function";
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
this._listeners.push(callback);
extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
},
removeListener: function(callback)
{
var listeners = this._listeners;
for (var i = 0; i < listeners.length; ++i) {
if (listeners[i] === callback) {
listeners.splice(i, 1);
break;
}
}
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type });
},
/**
* @param {...} vararg
*/
_fire: function(vararg)
{
var listeners = this._listeners.slice();
for (var i = 0; i < listeners.length; ++i)
listeners[i].apply(null, arguments);
},
_dispatch: function(request)
{
if (this._customDispatch)
this._customDispatch.call(this, request);
else
this._fire.apply(this, request.arguments);
}
}
/**
* @constructor
*/
function InspectorExtensionAPI()
{
this.audits = new Audits();
this.inspectedWindow = new InspectedWindow();
this.panels = new Panels();
this.network = new Network();
defineDeprecatedProperty(this, "webInspector", "resources", "network");
}
/**
* @constructor
*/
function Network()
{
/**
* @this {EventSinkImpl}
*/
function dispatchRequestEvent(message)
{
var request = message.arguments[1];
request.__proto__ = new Request(message.arguments[0]);
this._fire(request);
}
this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
this.onNavigated = new EventSink(events.InspectedURLChanged);
}
Network.prototype = {
getHAR: function(callback)
{
function callbackWrapper(result)
{
var entries = (result && result.entries) || [];
for (var i = 0; i < entries.length; ++i) {
entries[i].__proto__ = new Request(entries[i]._requestId);
delete entries[i]._requestId;
}
callback(result);
}
extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
},
addRequestHeaders: function(headers)
{
extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
}
}
/**
* @constructor
*/
function RequestImpl(id)
{
this._id = id;
}
RequestImpl.prototype = {
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper);
}
}
/**
* @constructor
*/
function Panels()
{
var panels = {
elements: new ElementsPanel(),
sources: new SourcesPanel(),
};
function panelGetter(name)
{
return panels[name];
}
for (var panel in panels)
this.__defineGetter__(panel, panelGetter.bind(null, panel));
this.applyStyleSheet = function(styleSheet) { extensionServer.sendRequest({ command: commands.ApplyStyleSheet, styleSheet: styleSheet }); };
}
Panels.prototype = {
create: function(title, icon, page, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
var request = {
command: commands.CreatePanel,
id: id,
title: title,
icon: icon,
page: page
};
extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
},
setOpenResourceHandler: function(callback)
{
var hadHandler = extensionServer.hasHandler(events.OpenResource);
function callbackWrapper(message)
{
// Allow the panel to show itself when handling the event.
userAction = true;
try {
callback.call(null, new Resource(message.resource), message.lineNumber);
} finally {
userAction = false;
}
}
if (!callback)
extensionServer.unregisterHandler(events.OpenResource);
else
extensionServer.registerHandler(events.OpenResource, callbackWrapper);
// Only send command if we either removed an existing handler or added handler and had none before.
if (hadHandler === !callback)
extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
},
openResource: function(url, lineNumber, callback)
{
extensionServer.sendRequest({ command: commands.OpenResource, "url": url, "lineNumber": lineNumber }, callback);
},
get SearchAction()
{
return apiPrivate.panels.SearchAction;
}
}
/**
* @constructor
*/
function ExtensionViewImpl(id)
{
this._id = id;
/**
* @this {EventSinkImpl}
*/
function dispatchShowEvent(message)
{
var frameIndex = message.arguments[0];
if (typeof frameIndex === "number")
this._fire(window.parent.frames[frameIndex]);
else
this._fire();
}
if (id) {
this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
this.onHidden = new EventSink(events.ViewHidden + id);
}
}
/**
* @constructor
* @extends {ExtensionViewImpl}
* @param {string} hostPanelName
*/
function PanelWithSidebarImpl(hostPanelName)
{
ExtensionViewImpl.call(this, null);
this._hostPanelName = hostPanelName;
this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPanelName);
}
PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateSidebarPane,
panel: this._hostPanelName,
id: id,
title: title
};
function callbackWrapper()
{
callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
},
__proto__: ExtensionViewImpl.prototype
}
function declareInterfaceClass(implConstructor)
{
return function()
{
var impl = { __proto__: implConstructor.prototype };
implConstructor.apply(impl, arguments);
populateInterfaceClass(this, impl);
};
}
function defineDeprecatedProperty(object, className, oldName, newName)
{
var warningGiven = false;
function getter()
{
if (!warningGiven) {
console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
warningGiven = true;
}
return object[newName];
}
object.__defineGetter__(oldName, getter);
}
function defineDeprecatedMethod(object, className, oldName)
{
var warningGiven = false;
function noop()
{
if (warningGiven)
return;
console.warn(className + "." + oldName + " is deprecated, please don't use it. It is a no-op.");
warningGiven = true;
}
object[oldName] = noop;
}
function extractCallbackArgument(args)
{
var lastArgument = args[args.length - 1];
return typeof lastArgument === "function" ? lastArgument : undefined;
}
var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
var AuditResult = declareInterfaceClass(AuditResultImpl);
var Button = declareInterfaceClass(ButtonImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Request = declareInterfaceClass(RequestImpl);
var Resource = declareInterfaceClass(ResourceImpl);
/**
* @constructor
* @extends {PanelWithSidebar}
*/
function ElementsPanel()
{
PanelWithSidebar.call(this, "elements");
}
ElementsPanel.prototype = {
__proto__: PanelWithSidebar.prototype
}
/**
* @constructor
* @extends {PanelWithSidebar}
*/
function SourcesPanel()
{
PanelWithSidebar.call(this, "sources");
}
SourcesPanel.prototype = {
__proto__: PanelWithSidebar.prototype
}
/**
* @constructor
* @extends {ExtensionViewImpl}
*/
function ExtensionPanelImpl(id)
{
ExtensionViewImpl.call(this, id);
this.onSearch = new EventSink(events.PanelSearch + id);
}
ExtensionPanelImpl.prototype = {
/**
* @return {!Object}
*/
createStatusBarButton: function(iconPath, tooltipText, disabled)
{
var id = "button-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateToolbarButton,
panel: this._id,
id: id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
return new Button(id);
},
show: function()
{
if (!userAction)
return;
var request = {
command: commands.ShowPanel,
id: this._id
};
extensionServer.sendRequest(request);
},
__proto__: ExtensionViewImpl.prototype
}
/**
* @constructor
* @extends {ExtensionViewImpl}
*/
function ExtensionSidebarPaneImpl(id)
{
ExtensionViewImpl.call(this, id);
defineDeprecatedMethod(this, "ExtensionSidebarPane", "setHeight");
}
ExtensionSidebarPaneImpl.prototype = {
setExpression: function(expression, rootTitle, evaluateOptions)
{
var request = {
command: commands.SetSidebarContent,
id: this._id,
expression: expression,
rootTitle: rootTitle,
evaluateOnPage: true,
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
extensionServer.sendRequest(request, extractCallbackArgument(arguments));
},
setObject: function(jsonObject, rootTitle, callback)
{
extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
},
setPage: function(page)
{
extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
},
__proto__: ExtensionViewImpl.prototype
}
/**
* @constructor
*/
function ButtonImpl(id)
{
this._id = id;
this.onClicked = new EventSink(events.ButtonClicked + id);
}
ButtonImpl.prototype = {
update: function(iconPath, tooltipText, disabled)
{
var request = {
command: commands.UpdateButton,
id: this._id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
}
};
/**
* @constructor
*/
function Audits()
{
}
Audits.prototype = {
/**
* @return {!AuditCategory}
*/
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
if (typeof resultCount !== "undefined")
console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}
/**
* @constructor
*/
function AuditCategoryImpl(id)
{
/**
* @this {EventSinkImpl}
*/
function dispatchAuditEvent(request)
{
var auditResult = new AuditResult(request.arguments[0]);
try {
this._fire(auditResult);
} catch (e) {
console.error("Uncaught exception in extension audit event handler: " + e);
auditResult.done();
}
}
this._id = id;
this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent);
}
/**
* @constructor
*/
function AuditResultImpl(id)
{
this._id = id;
this.createURL = this._nodeFactory.bind(this, "url");
this.createSnippet = this._nodeFactory.bind(this, "snippet");
this.createText = this._nodeFactory.bind(this, "text");
this.createObject = this._nodeFactory.bind(this, "object");
this.createNode = this._nodeFactory.bind(this, "node");
}
AuditResultImpl.prototype = {
addResult: function(displayName, description, severity, details)
{
// shorthand for specifying details directly in addResult().
if (details && !(details instanceof AuditResultNode))
details = new AuditResultNode(Array.isArray(details) ? details : [details]);
var request = {
command: commands.AddAuditResult,
resultId: this._id,
displayName: displayName,
description: description,
severity: severity,
details: details
};
extensionServer.sendRequest(request);
},
/**
* @return {!Object}
*/
createResult: function()
{
return new AuditResultNode(Array.prototype.slice.call(arguments));
},
updateProgress: function(worked, totalWork)
{
extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
},
done: function()
{
extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
},
/**
* @type {!Object.<string, string>}
*/
get Severity()
{
return apiPrivate.audits.Severity;
},
/**
* @return {!{type: string, arguments: !Array.<string|number>}}
*/
createResourceLink: function(url, lineNumber)
{
return {
type: "resourceLink",
arguments: [url, lineNumber && lineNumber - 1]
};
},
/**
* @return {!{type: string, arguments: !Array.<string|number>}}
*/
_nodeFactory: function(type)
{
return {
type: type,
arguments: Array.prototype.slice.call(arguments, 1)
};
}
}
/**
* @constructor
*/
function AuditResultNode(contents)
{
this.contents = contents;
this.children = [];
this.expanded = false;
}
AuditResultNode.prototype = {
/**
* @return {!Object}
*/
addChild: function()
{
var node = new AuditResultNode(Array.prototype.slice.call(arguments));
this.children.push(node);
return node;
}
};
/**
* @constructor
*/
function InspectedWindow()
{
/**
* @this {EventSinkImpl}
*/
function dispatchResourceEvent(message)
{
this._fire(new Resource(message.arguments[0]));
}
/**
* @this {EventSinkImpl}
*/
function dispatchResourceContentEvent(message)
{
this._fire(new Resource(message.arguments[0]), message.arguments[1]);
}
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
}
InspectedWindow.prototype = {
reload: function(optionsOrUserAgent)
{
var options = null;
if (typeof optionsOrUserAgent === "object") {
options = optionsOrUserAgent;
} else if (typeof optionsOrUserAgent === "string") {
options = { userAgent: optionsOrUserAgent };
console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
"Use inspectedWindow.reload({ userAgent: value}) instead.");
}
extensionServer.sendRequest({ command: commands.Reload, options: options });
},
/**
* @return {?Object}
*/
eval: function(expression, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
function callbackWrapper(result)
{
if (result.isError || result.isException)
callback(undefined, result);
else
callback(result.value);
}
var request = {
command: commands.EvaluateOnInspectedPage,
expression: expression
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
extensionServer.sendRequest(request, callback && callbackWrapper);
return null;
},
getResources: function(callback)
{
function wrapResource(resourceData)
{
return new Resource(resourceData);
}
function callbackWrapper(resources)
{
callback(resources.map(wrapResource));
}
extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
}
}
/**
* @constructor
*/
function ResourceImpl(resourceData)
{
this._url = resourceData.url;
this._type = resourceData.type;
}
ResourceImpl.prototype = {
get url()
{
return this._url;
},
get type()
{
return this._type;
},
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
},
setContent: function(content, commit, callback)
{
extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
}
}
var keyboardEventRequestQueue = [];
var forwardTimer = null;
function forwardKeyboardEvent(event)
{
const Esc = "U+001B";
// We only care about global hotkeys, not about random text
if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.keyIdentifier) && event.keyIdentifier !== Esc)
return;
var requestPayload = {
eventType: event.type,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
metaKey: event.metaKey,
keyIdentifier: event.keyIdentifier,
location: event.location,
keyCode: event.keyCode
};
keyboardEventRequestQueue.push(requestPayload);
if (!forwardTimer)
forwardTimer = setTimeout(forwardEventQueue, 0);
}
function forwardEventQueue()
{
forwardTimer = null;
var request = {
command: commands.ForwardKeyboardEvent,
entries: keyboardEventRequestQueue
};
extensionServer.sendRequest(request);
keyboardEventRequestQueue = [];
}
document.addEventListener("keydown", forwardKeyboardEvent, false);
document.addEventListener("keypress", forwardKeyboardEvent, false);
/**
* @constructor
*/
function ExtensionServerClient()
{
this._callbacks = {};
this._handlers = {};
this._lastRequestId = 0;
this._lastObjectId = 0;
this.registerHandler("callback", this._onCallback.bind(this));
var channel = new MessageChannel();
this._port = channel.port1;
this._port.addEventListener("message", this._onMessage.bind(this), false);
this._port.start();
window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
}
ExtensionServerClient.prototype = {
/**
* @param {!Object} message
* @param {function()=} callback
*/
sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
this._port.postMessage(message);
},
/**
* @return {boolean}
*/
hasHandler: function(command)
{
return !!this._handlers[command];
},
registerHandler: function(command, handler)
{
this._handlers[command] = handler;
},
unregisterHandler: function(command)
{
delete this._handlers[command];
},
/**
* @return {string}
*/
nextObjectId: function()
{
return injectedScriptId.toString() + "_" + ++this._lastObjectId;
},
_registerCallback: function(callback)
{
var id = ++this._lastRequestId;
this._callbacks[id] = callback;
return id;
},
_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
callback(request.result);
}
},
_onMessage: function(event)
{
var request = event.data;
var handler = this._handlers[request.command];
if (handler)
handler.call(this, request);
}
}
function populateInterfaceClass(interfaze, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
continue;
var descriptor = null;
// Traverse prototype chain until we find the owner.
for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
descriptor = Object.getOwnPropertyDescriptor(owner, member);
if (!descriptor)
continue;
if (typeof descriptor.value === "function")
interfaze[member] = descriptor.value.bind(implementation);
else if (typeof descriptor.get === "function")
interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
else
Object.defineProperty(interfaze, member, descriptor);
}
}
// extensionServer is a closure variable defined by the glue below -- make sure we fail if it's not there.
if (!extensionServer)
extensionServer = new ExtensionServerClient();
return new InspectorExtensionAPI();
}
/**
* @suppress {checkVars, checkTypes}
*/
function platformExtensionAPI(coreAPI)
{
function getTabId()
{
return tabId;
}
var chrome = window.chrome || {};
// Override chrome.devtools as a workaround for a error-throwing getter being exposed
// in extension pages loaded into a non-extension process (only happens for remote client
// extensions)
var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
if (!devtools_descriptor || devtools_descriptor.get)
Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });
// Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
chrome.devtools.inspectedWindow = {};
chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
chrome.devtools.network = coreAPI.network;
chrome.devtools.panels = coreAPI.panels;
// default to expose experimental APIs for now.
if (extensionInfo.exposeExperimentalAPIs !== false) {
chrome.experimental = chrome.experimental || {};
chrome.experimental.devtools = chrome.experimental.devtools || {};
var properties = Object.getOwnPropertyNames(coreAPI);
for (var i = 0; i < properties.length; ++i) {
var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
}
chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
}
if (extensionInfo.exposeWebInspectorNamespace)
window.webInspector = coreAPI;
}
/**
* @param {!ExtensionDescriptor} extensionInfo
* @param {string} inspectedTabId
* @return {string}
*/
function buildPlatformExtensionAPI(extensionInfo, inspectedTabId)
{
return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
"var tabId = " + inspectedTabId + ";" +
platformExtensionAPI.toString();
}
/**
* @param {!ExtensionDescriptor} extensionInfo
* @param {string} inspectedTabId
* @return {string}
*/
function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId)
{
return "(function(injectedScriptId){ " +
"var extensionServer;" +
defineCommonExtensionSymbols.toString() + ";" +
injectedExtensionAPI.toString() + ";" +
buildPlatformExtensionAPI(extensionInfo, inspectedTabId) + ";" +
"platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
"return {};" +
"})";
}
var tabId;
var extensionInfo = {};
var extensionServer;
platformExtensionAPI(injectedExtensionAPI("remote-" + window.parent.frames.length));
})();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 2 1 1 1 1 1 | WebInspector.Diff={charDiff:function(text1,text2)
{var differ=new diff_match_patch();return differ.diff_main(text1,text2);},lineDiff:function(lines1,lines2)
{var lineToChar=new Map();var charCode=33;var text1=encode(lines1);var text2=encode(lines2);return WebInspector.Diff.charDiff(text1,text2);function encode(lines)
{var text="";for(var i=0;i<lines.length;++i){var line=lines[i];var character=lineToChar.get(line);if(!character){character=String.fromCharCode(charCode++);lineToChar.set(line,character);}
text+=character;}
return text;}},convertToEditDiff:function(diff)
{var normalized=[];var added=0;var removed=0;for(var i=0;i<diff.length;++i){var token=diff[i];if(token[0]===WebInspector.Diff.Operation.Equal){flush();normalized.push([WebInspector.Diff.Operation.Equal,token[1].length]);}else if(token[0]===WebInspector.Diff.Operation.Delete){removed+=token[1].length;}else{added+=token[1].length;}}
flush();return normalized;function flush()
{if(added&&removed){var min=Math.min(added,removed);normalized.push([WebInspector.Diff.Operation.Edit,min]);added-=min;removed-=min;}
if(added||removed){var balance=added-removed;var type=balance<0?WebInspector.Diff.Operation.Delete:WebInspector.Diff.Operation.Insert;normalized.push([type,Math.abs(balance)]);added=0;removed=0;}}}}
WebInspector.Diff.Operation={Equal:0,Insert:1,Delete:-1,Edit:2};(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,d):this.diff_bisect_(a,b,d)};diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case-1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case-1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&").replace(d,"<").replace(e,">").replace(f,"¶<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case-1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case-1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case-1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case"+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case"-":case"=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=c.length+d.length;a.length2+=c.length+d.length}};diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case-1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case-1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | 92 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 14 14 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 148 148 74 2 2 2 | (function(f){Eif(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){Iif(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var pp=_state.Parser.prototype;pp.checkPropClash=function(prop,propHash){if(this.options.ecmaVersion>=6&&(prop.computed||prop.method||prop.shorthand))return;var key=prop.key;var name=undefined;switch(key.type){case"Identifier":name=key.name;break;case"Literal":name=String(key.value);break;default:return;}
var kind=prop.kind;if(this.options.ecmaVersion>=6){if(name==="__proto__"&&kind==="init"){if(propHash.proto)this.raise(key.start,"Redefinition of __proto__ property");propHash.proto=true;}
return;}
name="$"+name;var other=propHash[name];if(other){var isGetSet=kind!=="init";if((this.strict||isGetSet)&&other[kind]||!(isGetSet^other.init))this.raise(key.start,"Redefinition of property");}else{other=propHash[name]={init:false,get:false,set:false};}
other[kind]=true;};pp.parseExpression=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeAssign(noIn,refShorthandDefaultPos);if(this.type===_tokentype.types.comma){var node=this.startNodeAt(startPos,startLoc);node.expressions=[expr];while(this.eat(_tokentype.types.comma))node.expressions.push(this.parseMaybeAssign(noIn,refShorthandDefaultPos));return this.finishNode(node,"SequenceExpression");}
return expr;};pp.parseMaybeAssign=function(noIn,refShorthandDefaultPos,afterLeftParse){if(this.type==_tokentype.types._yield&&this.inGenerator)return this.parseYield();var failOnShorthandAssign=undefined;if(!refShorthandDefaultPos){refShorthandDefaultPos={start:0};failOnShorthandAssign=true;}else{failOnShorthandAssign=false;}
var startPos=this.start,startLoc=this.startLoc;if(this.type==_tokentype.types.parenL||this.type==_tokentype.types.name)this.potentialArrowAt=this.start;var left=this.parseMaybeConditional(noIn,refShorthandDefaultPos);if(afterLeftParse)left=afterLeftParse.call(this,left,startPos,startLoc);if(this.type.isAssign){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.left=this.type===_tokentype.types.eq?this.toAssignable(left):left;refShorthandDefaultPos.start=0;this.checkLVal(left);this.next();node.right=this.parseMaybeAssign(noIn);return this.finishNode(node,"AssignmentExpression");}else if(failOnShorthandAssign&&refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start);}
return left;};pp.parseMaybeConditional=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprOps(noIn,refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;if(this.eat(_tokentype.types.question)){var node=this.startNodeAt(startPos,startLoc);node.test=expr;node.consequent=this.parseMaybeAssign();this.expect(_tokentype.types.colon);node.alternate=this.parseMaybeAssign(noIn);return this.finishNode(node,"ConditionalExpression");}
return expr;};pp.parseExprOps=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeUnary(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseExprOp(expr,startPos,startLoc,-1,noIn);};pp.parseExprOp=function(left,leftStartPos,leftStartLoc,minPrec,noIn){var prec=this.type.binop;if(prec!=null&&(!noIn||this.type!==_tokentype.types._in)){if(prec>minPrec){var node=this.startNodeAt(leftStartPos,leftStartLoc);node.left=left;node.operator=this.value;var op=this.type;this.next();var startPos=this.start,startLoc=this.startLoc;node.right=this.parseExprOp(this.parseMaybeUnary(),startPos,startLoc,prec,noIn);this.finishNode(node,op===_tokentype.types.logicalOR||op===_tokentype.types.logicalAND?"LogicalExpression":"BinaryExpression");return this.parseExprOp(node,leftStartPos,leftStartLoc,minPrec,noIn);}}
return left;};pp.parseMaybeUnary=function(refShorthandDefaultPos){if(this.type.prefix){var node=this.startNode(),update=this.type===_tokentype.types.incDec;node.operator=this.value;node.prefix=true;this.next();node.argument=this.parseMaybeUnary();if(refShorthandDefaultPos&&refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(update)this.checkLVal(node.argument);else if(this.strict&&node.operator==="delete"&&node.argument.type==="Identifier")this.raise(node.start,"Deleting local variable in strict mode");return this.finishNode(node,update?"UpdateExpression":"UnaryExpression");}
var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprSubscripts(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;while(this.type.postfix&&!this.canInsertSemicolon()){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.prefix=false;node.argument=expr;this.checkLVal(expr);this.next();expr=this.finishNode(node,"UpdateExpression");}
return expr;};pp.parseExprSubscripts=function(refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprAtom(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseSubscripts(expr,startPos,startLoc);};pp.parseSubscripts=function(base,startPos,startLoc,noCalls){for(;;){if(this.eat(_tokentype.types.dot)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseIdent(true);node.computed=false;base=this.finishNode(node,"MemberExpression");}else if(this.eat(_tokentype.types.bracketL)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseExpression();node.computed=true;this.expect(_tokentype.types.bracketR);base=this.finishNode(node,"MemberExpression");}else if(!noCalls&&this.eat(_tokentype.types.parenL)){var node=this.startNodeAt(startPos,startLoc);node.callee=base;node.arguments=this.parseExprList(_tokentype.types.parenR,false);base=this.finishNode(node,"CallExpression");}else if(this.type===_tokentype.types.backQuote){var node=this.startNodeAt(startPos,startLoc);node.tag=base;node.quasi=this.parseTemplate();base=this.finishNode(node,"TaggedTemplateExpression");}else{return base;}}};pp.parseExprAtom=function(refShorthandDefaultPos){var node=undefined,canBeArrow=this.potentialArrowAt==this.start;switch(this.type){case _tokentype.types._super:if(!this.inFunction)this.raise(this.start,"'super' outside of function or class");case _tokentype.types._this:var type=this.type===_tokentype.types._this?"ThisExpression":"Super";node=this.startNode();this.next();return this.finishNode(node,type);case _tokentype.types._yield:if(this.inGenerator)this.unexpected();case _tokentype.types.name:var startPos=this.start,startLoc=this.startLoc;var id=this.parseIdent(this.type!==_tokentype.types.name);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(_tokentype.types.arrow))return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id]);return id;case _tokentype.types.regexp:var value=this.value;node=this.parseLiteral(value.value);node.regex={pattern:value.pattern,flags:value.flags};return node;case _tokentype.types.num:case _tokentype.types.string:return this.parseLiteral(this.value);case _tokentype.types._null:case _tokentype.types._true:case _tokentype.types._false:node=this.startNode();node.value=this.type===_tokentype.types._null?null:this.type===_tokentype.types._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case _tokentype.types.parenL:return this.parseParenAndDistinguishExpression(canBeArrow);case _tokentype.types.bracketL:node=this.startNode();this.next();if(this.options.ecmaVersion>=7&&this.type===_tokentype.types._for){return this.parseComprehension(node,false);}
node.elements=this.parseExprList(_tokentype.types.bracketR,true,true,refShorthandDefaultPos);return this.finishNode(node,"ArrayExpression");case _tokentype.types.braceL:return this.parseObj(false,refShorthandDefaultPos);case _tokentype.types._function:node=this.startNode();this.next();return this.parseFunction(node,false);case _tokentype.types._class:return this.parseClass(this.startNode(),false);case _tokentype.types._new:return this.parseNew();case _tokentype.types.backQuote:return this.parseTemplate();default:this.unexpected();}};pp.parseLiteral=function(value){var node=this.startNode();node.value=value;node.raw=this.input.slice(this.start,this.end);this.next();return this.finishNode(node,"Literal");};pp.parseParenExpression=function(){this.expect(_tokentype.types.parenL);var val=this.parseExpression();this.expect(_tokentype.types.parenR);return val;};pp.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val=undefined;if(this.options.ecmaVersion>=6){this.next();if(this.options.ecmaVersion>=7&&this.type===_tokentype.types._for){return this.parseComprehension(this.startNodeAt(startPos,startLoc),true);}
var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true;var refShorthandDefaultPos={start:0},spreadStart=undefined,innerParenStart=undefined;while(this.type!==_tokentype.types.parenR){first?first=false:this.expect(_tokentype.types.comma);if(this.type===_tokentype.types.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRest()));break;}else{if(this.type===_tokentype.types.parenL&&!innerParenStart){innerParenStart=this.start;}
exprList.push(this.parseMaybeAssign(false,refShorthandDefaultPos,this.parseParenItem));}}
var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(_tokentype.types.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(_tokentype.types.arrow)){if(innerParenStart)this.unexpected(innerParenStart);return this.parseParenArrowList(startPos,startLoc,exprList);}
if(!exprList.length)this.unexpected(this.lastTokStart);if(spreadStart)this.unexpected(spreadStart);if(refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc);}else{val=exprList[0];}}else{val=this.parseParenExpression();}
if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression");}else{return val;}};pp.parseParenItem=function(item){return item;};pp.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList);};var empty=[];pp.parseNew=function(){var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(_tokentype.types.dot)){node.meta=meta;node.property=this.parseIdent(true);if(node.property.name!=="target")this.raise(node.property.start,"The only valid meta property for new is new.target");if(!this.inFunction)this.raise(node.start,"new.target can only be used in functions");return this.finishNode(node,"MetaProperty");}
var startPos=this.start,startLoc=this.startLoc;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(this.eat(_tokentype.types.parenL))node.arguments=this.parseExprList(_tokentype.types.parenR,false);else node.arguments=empty;return this.finishNode(node,"NewExpression");};pp.parseTemplateElement=function(){var elem=this.startNode();elem.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,'\n'),cooked:this.value};this.next();elem.tail=this.type===_tokentype.types.backQuote;return this.finishNode(elem,"TemplateElement");};pp.parseTemplate=function(){var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement();node.quasis=[curElt];while(!curElt.tail){this.expect(_tokentype.types.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(_tokentype.types.braceR);node.quasis.push(curElt=this.parseTemplateElement());}
this.next();return this.finishNode(node,"TemplateLiteral");};pp.parseObj=function(isPattern,refShorthandDefaultPos){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var prop=this.startNode(),isGenerator=undefined,startPos=undefined,startLoc=undefined;if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refShorthandDefaultPos){startPos=this.start;startLoc=this.startLoc;}
if(!isPattern)isGenerator=this.eat(_tokentype.types.star);}
this.parsePropertyName(prop);this.parsePropertyValue(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos);this.checkPropClash(prop,propHash);node.properties.push(this.finishNode(prop,"Property"));}
return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression");};pp.parsePropertyValue=function(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos){if(this.eat(_tokentype.types.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refShorthandDefaultPos);prop.kind="init";}else if(this.options.ecmaVersion>=6&&this.type===_tokentype.types.parenL){if(isPattern)this.unexpected();prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator);}else if(this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!=_tokentype.types.comma&&this.type!=_tokentype.types.braceR)){if(isGenerator||isPattern)this.unexpected();prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false);var paramCount=prop.kind==="get"?0:1;if(prop.value.params.length!==paramCount){var start=prop.value.start;if(prop.kind==="get")this.raise(start,"getter should have no params");else this.raise(start,"setter should have exactly one param");}}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){prop.kind="init";if(isPattern){if(this.keywords.test(prop.key.name)||(this.strict?this.reservedWordsStrictBind:this.reservedWords).test(prop.key.name))this.raise(prop.key.start,"Binding "+prop.key.name);prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key);}else if(this.type===_tokentype.types.eq&&refShorthandDefaultPos){if(!refShorthandDefaultPos.start)refShorthandDefaultPos.start=this.start;prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key);}else{prop.value=prop.key;}
prop.shorthand=true;}else this.unexpected();};pp.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(_tokentype.types.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(_tokentype.types.bracketR);return prop.key;}else{prop.computed=false;}}
return prop.key=this.type===_tokentype.types.num||this.type===_tokentype.types.string?this.parseExprAtom():this.parseIdent(true);};pp.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=false;node.expression=false;}};pp.parseMethod=function(isGenerator){var node=this.startNode();this.initFunction(node);this.expect(_tokentype.types.parenL);node.params=this.parseBindingList(_tokentype.types.parenR,false,false);if(this.options.ecmaVersion>=6)node.generator=isGenerator;this.parseFunctionBody(node,false);return this.finishNode(node,"FunctionExpression");};pp.parseArrowExpression=function(node,params){this.initFunction(node);node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true);return this.finishNode(node,"ArrowFunctionExpression");};pp.parseFunctionBody=function(node,isArrowFunction){var isExpression=isArrowFunction&&this.type!==_tokentype.types.braceL;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true;}else{var oldInFunc=this.inFunction,oldInGen=this.inGenerator,oldLabels=this.labels;this.inFunction=true;this.inGenerator=node.generator;this.labels=[];node.body=this.parseBlock(true);node.expression=false;this.inFunction=oldInFunc;this.inGenerator=oldInGen;this.labels=oldLabels;}
if(this.strict||!isExpression&&node.body.body.length&&this.isUseStrict(node.body.body[0])){var oldStrict=this.strict;this.strict=true;if(node.id)this.checkLVal(node.id,true);this.checkParams(node);this.strict=oldStrict;}else if(isArrowFunction){this.checkParams(node);}};pp.checkParams=function(node){var nameHash={};for(var i=0;i<node.params.length;i++){this.checkLVal(node.params[i],true,nameHash);}};pp.parseExprList=function(close,allowTrailingComma,allowEmpty,refShorthandDefaultPos){var elts=[],first=true;while(!this.eat(close)){if(!first){this.expect(_tokentype.types.comma);if(allowTrailingComma&&this.afterTrailingComma(close))break;}else first=false;var elt=undefined;if(allowEmpty&&this.type===_tokentype.types.comma)elt=null;else if(this.type===_tokentype.types.ellipsis)elt=this.parseSpread(refShorthandDefaultPos);else elt=this.parseMaybeAssign(false,refShorthandDefaultPos);elts.push(elt);}
return elts;};pp.parseIdent=function(liberal){var node=this.startNode();if(liberal&&this.options.allowReserved=="never")liberal=false;if(this.type===_tokentype.types.name){if(!liberal&&(this.strict?this.reservedWordsStrict:this.reservedWords).test(this.value)&&(this.options.ecmaVersion>=6||this.input.slice(this.start,this.end).indexOf("\\")==-1))this.raise(this.start,"The keyword '"+this.value+"' is reserved");node.name=this.value;}else if(liberal&&this.type.keyword){node.name=this.type.keyword;}else{this.unexpected();}
this.next();return this.finishNode(node,"Identifier");};pp.parseYield=function(){var node=this.startNode();this.next();if(this.type==_tokentype.types.semi||this.canInsertSemicolon()||this.type!=_tokentype.types.star&&!this.type.startsExpr){node.delegate=false;node.argument=null;}else{node.delegate=this.eat(_tokentype.types.star);node.argument=this.parseMaybeAssign();}
return this.finishNode(node,"YieldExpression");};pp.parseComprehension=function(node,isGenerator){node.blocks=[];while(this.type===_tokentype.types._for){var block=this.startNode();this.next();this.expect(_tokentype.types.parenL);block.left=this.parseBindingAtom();this.checkLVal(block.left,true);this.expectContextual("of");block.right=this.parseExpression();this.expect(_tokentype.types.parenR);node.blocks.push(this.finishNode(block,"ComprehensionBlock"));}
node.filter=this.eat(_tokentype.types._if)?this.parseParenExpression():null;node.body=this.parseExpression();this.expect(isGenerator?_tokentype.types.parenR:_tokentype.types.bracketR);node.generator=isGenerator;return this.finishNode(node,"ComprehensionExpression");};},{"./state":10,"./tokentype":14}],2:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isIdentifierStart=isIdentifierStart;exports.isIdentifierChar=isIdentifierChar;var reservedWords={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"};exports.reservedWords=reservedWords;var ecma5AndLessKeywords="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";var keywords={5:ecma5AndLessKeywords,6:ecma5AndLessKeywords+" let const class extends export import yield super"};exports.keywords=keywords;var nonASCIIidentifierStartChars="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";var nonASCIIidentifierChars="·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";var nonASCIIidentifierStart=new RegExp("["+nonASCIIidentifierStartChars+"]");var nonASCIIidentifier=new RegExp("["+nonASCIIidentifierStartChars+nonASCIIidentifierChars+"]");nonASCIIidentifierStartChars=nonASCIIidentifierChars=null;var astralIdentifierStartCodes=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,99,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,98,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,955,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,38,17,2,24,133,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,32,4,287,47,21,1,2,0,185,46,82,47,21,0,60,42,502,63,32,0,449,56,1288,920,104,110,2962,1070,13266,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,16481,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,1340,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,16355,541];var astralIdentifierCodes=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,16,9,83,11,168,11,6,9,8,2,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,316,19,13,9,214,6,3,8,112,16,16,9,82,12,9,9,535,9,20855,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,4305,6,792618,239];function isInAstralSet(code,set){var pos=0x10000;for(var i=0;i<set.length;i+=2){pos+=set[i];if(pos>code)return false;pos+=set[i+1];if(pos>=code)return true;}}
function isIdentifierStart(code,astral){if(code<65)return code===36;if(code<91)return true;if(code<97)return code===95;if(code<123)return true;if(code<=0xffff)return code>=0xaa&&nonASCIIidentifierStart.test(String.fromCharCode(code));if(astral===false)return false;return isInAstralSet(code,astralIdentifierStartCodes);}
function isIdentifierChar(code,astral){if(code<48)return code===36;if(code<58)return true;if(code<65)return false;if(code<91)return true;if(code<97)return code===95;if(code<123)return true;if(code<=0xffff)return code>=0xaa&&nonASCIIidentifier.test(String.fromCharCode(code));if(astral===false)return false;return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes);}},{}],3:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.parse=parse;exports.parseExpressionAt=parseExpressionAt;exports.tokenizer=tokenizer;var _state=_dereq_("./state");_dereq_("./parseutil");_dereq_("./statement");_dereq_("./lval");_dereq_("./expression");_dereq_("./location");exports.Parser=_state.Parser;exports.plugins=_state.plugins;var _options=_dereq_("./options");exports.defaultOptions=_options.defaultOptions;var _locutil=_dereq_("./locutil");exports.Position=_locutil.Position;exports.SourceLocation=_locutil.SourceLocation;exports.getLineInfo=_locutil.getLineInfo;var _node=_dereq_("./node");exports.Node=_node.Node;var _tokentype=_dereq_("./tokentype");exports.TokenType=_tokentype.TokenType;exports.tokTypes=_tokentype.types;var _tokencontext=_dereq_("./tokencontext");exports.TokContext=_tokencontext.TokContext;exports.tokContexts=_tokencontext.types;var _identifier=_dereq_("./identifier");exports.isIdentifierChar=_identifier.isIdentifierChar;exports.isIdentifierStart=_identifier.isIdentifierStart;var _tokenize=_dereq_("./tokenize");exports.Token=_tokenize.Token;var _whitespace=_dereq_("./whitespace");exports.isNewLine=_whitespace.isNewLine;exports.lineBreak=_whitespace.lineBreak;exports.lineBreakG=_whitespace.lineBreakG;var version="2.4.1";exports.version=version;function parse(input,options){return new _state.Parser(options,input).parse();}
function parseExpressionAt(input,pos,options){var p=new _state.Parser(options,input,pos);p.nextToken();return p.parseExpression();}
function tokenizer(input,options){return new _state.Parser(options,input);}},{"./expression":1,"./identifier":2,"./location":4,"./locutil":5,"./lval":6,"./node":7,"./options":8,"./parseutil":9,"./state":10,"./statement":11,"./tokencontext":12,"./tokenize":13,"./tokentype":14,"./whitespace":16}],4:[function(_dereq_,module,exports){"use strict";var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var pp=_state.Parser.prototype;pp.raise=function(pos,message){var loc=_locutil.getLineInfo(this.input,pos);message+=" ("+loc.line+":"+loc.column+")";var err=new SyntaxError(message);err.pos=pos;err.loc=loc;err.raisedAt=this.pos;throw err;};pp.curPosition=function(){if(this.options.locations){return new _locutil.Position(this.curLine,this.pos-this.lineStart);}};},{"./locutil":5,"./state":10}],5:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.getLineInfo=getLineInfo;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _whitespace=_dereq_("./whitespace");var Position=(function(){function Position(line,col){_classCallCheck(this,Position);this.line=line;this.column=col;}
Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n);};return Position;})();exports.Position=Position;var SourceLocation=function SourceLocation(p,start,end){_classCallCheck(this,SourceLocation);this.start=start;this.end=end;if(p.sourceFile!==null)this.source=p.sourceFile;};exports.SourceLocation=SourceLocation;function getLineInfo(input,offset){for(var line=1,cur=0;;){_whitespace.lineBreakG.lastIndex=cur;var match=_whitespace.lineBreakG.exec(input);if(match&&match.index<offset){++line;cur=match.index+match[0].length;}else{return new Position(line,offset-cur);}}}},{"./whitespace":16}],6:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _util=_dereq_("./util");var pp=_state.Parser.prototype;pp.toAssignable=function(node,isBinding){if(this.options.ecmaVersion>=6&&node){switch(node.type){case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":break;case"ObjectExpression":node.type="ObjectPattern";for(var i=0;i<node.properties.length;i++){var prop=node.properties[i];if(prop.kind!=="init")this.raise(prop.key.start,"Object pattern can't contain getter or setter");this.toAssignable(prop.value,isBinding);}
break;case"ArrayExpression":node.type="ArrayPattern";this.toAssignableList(node.elements,isBinding);break;case"AssignmentExpression":if(node.operator==="="){node.type="AssignmentPattern";delete node.operator;}else{this.raise(node.left.end,"Only '=' operator can be used for specifying default value.");}
break;case"ParenthesizedExpression":node.expression=this.toAssignable(node.expression,isBinding);break;case"MemberExpression":if(!isBinding)break;default:this.raise(node.start,"Assigning to rvalue");}}
return node;};pp.toAssignableList=function(exprList,isBinding){var end=exprList.length;if(end){var last=exprList[end-1];if(last&&last.type=="RestElement"){--end;}else if(last&&last.type=="SpreadElement"){last.type="RestElement";var arg=last.argument;this.toAssignable(arg,isBinding);if(arg.type!=="Identifier"&&arg.type!=="MemberExpression"&&arg.type!=="ArrayPattern")this.unexpected(arg.start);--end;}
if(isBinding&&last.type==="RestElement"&&last.argument.type!=="Identifier")this.unexpected(last.argument.start);}
for(var i=0;i<end;i++){var elt=exprList[i];if(elt)this.toAssignable(elt,isBinding);}
return exprList;};pp.parseSpread=function(refShorthandDefaultPos){var node=this.startNode();this.next();node.argument=this.parseMaybeAssign(refShorthandDefaultPos);return this.finishNode(node,"SpreadElement");};pp.parseRest=function(allowNonIdent){var node=this.startNode();this.next();if(allowNonIdent)node.argument=this.type===_tokentype.types.name?this.parseIdent():this.unexpected();else node.argument=this.type===_tokentype.types.name||this.type===_tokentype.types.bracketL?this.parseBindingAtom():this.unexpected();return this.finishNode(node,"RestElement");};pp.parseBindingAtom=function(){if(this.options.ecmaVersion<6)return this.parseIdent();switch(this.type){case _tokentype.types.name:return this.parseIdent();case _tokentype.types.bracketL:var node=this.startNode();this.next();node.elements=this.parseBindingList(_tokentype.types.bracketR,true,true);return this.finishNode(node,"ArrayPattern");case _tokentype.types.braceL:return this.parseObj(true);default:this.unexpected();}};pp.parseBindingList=function(close,allowEmpty,allowTrailingComma,allowNonIdent){var elts=[],first=true;while(!this.eat(close)){if(first)first=false;else this.expect(_tokentype.types.comma);if(allowEmpty&&this.type===_tokentype.types.comma){elts.push(null);}else if(allowTrailingComma&&this.afterTrailingComma(close)){break;}else if(this.type===_tokentype.types.ellipsis){var rest=this.parseRest(allowNonIdent);this.parseBindingListItem(rest);elts.push(rest);this.expect(close);break;}else{var elem=this.parseMaybeDefault(this.start,this.startLoc);this.parseBindingListItem(elem);elts.push(elem);}}
return elts;};pp.parseBindingListItem=function(param){return param;};pp.parseMaybeDefault=function(startPos,startLoc,left){left=left||this.parseBindingAtom();if(this.options.ecmaVersion<6||!this.eat(_tokentype.types.eq))return left;var node=this.startNodeAt(startPos,startLoc);node.left=left;node.right=this.parseMaybeAssign();return this.finishNode(node,"AssignmentPattern");};pp.checkLVal=function(expr,isBinding,checkClashes){switch(expr.type){case"Identifier":if(this.strict&&this.reservedWordsStrictBind.test(expr.name))this.raise(expr.start,(isBinding?"Binding ":"Assigning to ")+expr.name+" in strict mode");if(checkClashes){if(_util.has(checkClashes,expr.name))this.raise(expr.start,"Argument name clash");checkClashes[expr.name]=true;}
break;case"MemberExpression":if(isBinding)this.raise(expr.start,(isBinding?"Binding":"Assigning to")+" member expression");break;case"ObjectPattern":for(var i=0;i<expr.properties.length;i++){this.checkLVal(expr.properties[i].value,isBinding,checkClashes);}break;case"ArrayPattern":for(var i=0;i<expr.elements.length;i++){var elem=expr.elements[i];if(elem)this.checkLVal(elem,isBinding,checkClashes);}
break;case"AssignmentPattern":this.checkLVal(expr.left,isBinding,checkClashes);break;case"RestElement":this.checkLVal(expr.argument,isBinding,checkClashes);break;case"ParenthesizedExpression":this.checkLVal(expr.expression,isBinding,checkClashes);break;default:this.raise(expr.start,(isBinding?"Binding":"Assigning to")+" rvalue");}};},{"./state":10,"./tokentype":14,"./util":15}],7:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var Node=function Node(parser,pos,loc){_classCallCheck(this,Node);this.type="";this.start=pos;this.end=0;if(parser.options.locations)this.loc=new _locutil.SourceLocation(parser,loc);if(parser.options.directSourceFile)this.sourceFile=parser.options.directSourceFile;if(parser.options.ranges)this.range=[pos,0];};exports.Node=Node;var pp=_state.Parser.prototype;pp.startNode=function(){return new Node(this,this.start,this.startLoc);};pp.startNodeAt=function(pos,loc){return new Node(this,pos,loc);};function finishNodeAt(node,type,pos,loc){node.type=type;node.end=pos;if(this.options.locations)node.loc.end=loc;if(this.options.ranges)node.range[1]=pos;return node;}
pp.finishNode=function(node,type){return finishNodeAt.call(this,node,type,this.lastTokEnd,this.lastTokEndLoc);};pp.finishNodeAt=function(node,type,pos,loc){return finishNodeAt.call(this,node,type,pos,loc);};},{"./locutil":5,"./state":10}],8:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.getOptions=getOptions;var _util=_dereq_("./util");var _locutil=_dereq_("./locutil");var defaultOptions={ecmaVersion:5,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:false,allowImportExportEverywhere:false,allowHashBang:false,locations:false,onToken:null,onComment:null,ranges:false,program:null,sourceFile:null,directSourceFile:null,preserveParens:false,plugins:{}};exports.defaultOptions=defaultOptions;function getOptions(opts){var options={};for(var opt in defaultOptions){options[opt]=opts&&_util.has(opts,opt)?opts[opt]:defaultOptions[opt];}if(options.allowReserved==null)options.allowReserved=options.ecmaVersion>=5;if(_util.isArray(options.onToken)){(function(){var tokens=options.onToken;options.onToken=function(token){return tokens.push(token);};})();}
if(_util.isArray(options.onComment))options.onComment=pushComment(options,options.onComment);return options;}
function pushComment(options,array){return function(block,text,start,end,startLoc,endLoc){var comment={type:block?'Block':'Line',value:text,start:start,end:end};if(options.locations)comment.loc=new _locutil.SourceLocation(this,startLoc,endLoc);if(options.ranges)comment.range=[start,end];array.push(comment);};}},{"./locutil":5,"./util":15}],9:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _whitespace=_dereq_("./whitespace");var pp=_state.Parser.prototype;pp.isUseStrict=function(stmt){return this.options.ecmaVersion>=5&&stmt.type==="ExpressionStatement"&&stmt.expression.type==="Literal"&&stmt.expression.raw.slice(1,-1)==="use strict";};pp.eat=function(type){if(this.type===type){this.next();return true;}else{return false;}};pp.isContextual=function(name){return this.type===_tokentype.types.name&&this.value===name;};pp.eatContextual=function(name){return this.value===name&&this.eat(_tokentype.types.name);};pp.expectContextual=function(name){if(!this.eatContextual(name))this.unexpected();};pp.canInsertSemicolon=function(){return this.type===_tokentype.types.eof||this.type===_tokentype.types.braceR||_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start));};pp.insertSemicolon=function(){if(this.canInsertSemicolon()){if(this.options.onInsertedSemicolon)this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc);return true;}};pp.semicolon=function(){if(!this.eat(_tokentype.types.semi)&&!this.insertSemicolon())this.unexpected();};pp.afterTrailingComma=function(tokType){if(this.type==tokType){if(this.options.onTrailingComma)this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc);this.next();return true;}};pp.expect=function(type){this.eat(type)||this.unexpected();};pp.unexpected=function(pos){this.raise(pos!=null?pos:this.start,"Unexpected token");};},{"./state":10,"./tokentype":14,"./whitespace":16}],10:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _identifier=_dereq_("./identifier");var _tokentype=_dereq_("./tokentype");var _whitespace=_dereq_("./whitespace");var _options=_dereq_("./options");var plugins={};exports.plugins=plugins;function keywordRegexp(words){return new RegExp("^("+words.replace(/ /g,"|")+")$");}
var Parser=(function(){function Parser(options,input,startPos){_classCallCheck(this,Parser);this.options=_options.getOptions(options);this.sourceFile=this.options.sourceFile;this.keywords=keywordRegexp(_identifier.keywords[this.options.ecmaVersion>=6?6:5]);var reserved=this.options.allowReserved?"":_identifier.reservedWords[this.options.ecmaVersion]+(options.sourceType=="module"?" await":"");this.reservedWords=keywordRegexp(reserved);var reservedStrict=(reserved?reserved+" ":"")+_identifier.reservedWords.strict;this.reservedWordsStrict=keywordRegexp(reservedStrict);this.reservedWordsStrictBind=keywordRegexp(reservedStrict+" "+_identifier.reservedWords.strictBind);this.input=String(input);this.containsEsc=false;this.loadPlugins(this.options.plugins);if(startPos){this.pos=startPos;this.lineStart=Math.max(0,this.input.lastIndexOf("\n",startPos));this.curLine=this.input.slice(0,this.lineStart).split(_whitespace.lineBreak).length;}else{this.pos=this.lineStart=0;this.curLine=1;}
this.type=_tokentype.types.eof;this.value=null;this.start=this.end=this.pos;this.startLoc=this.endLoc=this.curPosition();this.lastTokEndLoc=this.lastTokStartLoc=null;this.lastTokStart=this.lastTokEnd=this.pos;this.context=this.initialContext();this.exprAllowed=true;this.strict=this.inModule=this.options.sourceType==="module";this.potentialArrowAt=-1;this.inFunction=this.inGenerator=false;this.labels=[];if(this.pos===0&&this.options.allowHashBang&&this.input.slice(0,2)==='#!')this.skipLineComment(2);}
Parser.prototype.isKeyword=function isKeyword(word){return this.keywords.test(word);};Parser.prototype.isReservedWord=function isReservedWord(word){return this.reservedWords.test(word);};Parser.prototype.extend=function extend(name,f){this[name]=f(this[name]);};Parser.prototype.loadPlugins=function loadPlugins(pluginConfigs){for(var _name in pluginConfigs){var plugin=plugins[_name];if(!plugin)throw new Error("Plugin '"+_name+"' not found");plugin(this,pluginConfigs[_name]);}};Parser.prototype.parse=function parse(){var node=this.options.program||this.startNode();this.nextToken();return this.parseTopLevel(node);};return Parser;})();exports.Parser=Parser;},{"./identifier":2,"./options":8,"./tokentype":14,"./whitespace":16}],11:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _whitespace=_dereq_("./whitespace");var pp=_state.Parser.prototype;pp.parseTopLevel=function(node){var first=true;if(!node.body)node.body=[];while(this.type!==_tokentype.types.eof){var stmt=this.parseStatement(true,true);node.body.push(stmt);if(first){if(this.isUseStrict(stmt))this.setStrict(true);first=false;}}
this.next();if(this.options.ecmaVersion>=6){node.sourceType=this.options.sourceType;}
return this.finishNode(node,"Program");};var loopLabel={kind:"loop"},switchLabel={kind:"switch"};pp.parseStatement=function(declaration,topLevel){var starttype=this.type,node=this.startNode();switch(starttype){case _tokentype.types._break:case _tokentype.types._continue:return this.parseBreakContinueStatement(node,starttype.keyword);case _tokentype.types._debugger:return this.parseDebuggerStatement(node);case _tokentype.types._do:return this.parseDoStatement(node);case _tokentype.types._for:return this.parseForStatement(node);case _tokentype.types._function:if(!declaration&&this.options.ecmaVersion>=6)this.unexpected();return this.parseFunctionStatement(node);case _tokentype.types._class:if(!declaration)this.unexpected();return this.parseClass(node,true);case _tokentype.types._if:return this.parseIfStatement(node);case _tokentype.types._return:return this.parseReturnStatement(node);case _tokentype.types._switch:return this.parseSwitchStatement(node);case _tokentype.types._throw:return this.parseThrowStatement(node);case _tokentype.types._try:return this.parseTryStatement(node);case _tokentype.types._let:case _tokentype.types._const:if(!declaration)this.unexpected();case _tokentype.types._var:return this.parseVarStatement(node,starttype);case _tokentype.types._while:return this.parseWhileStatement(node);case _tokentype.types._with:return this.parseWithStatement(node);case _tokentype.types.braceL:return this.parseBlock();case _tokentype.types.semi:return this.parseEmptyStatement(node);case _tokentype.types._export:case _tokentype.types._import:if(!this.options.allowImportExportEverywhere){if(!topLevel)this.raise(this.start,"'import' and 'export' may only appear at the top level");if(!this.inModule)this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'");}
return starttype===_tokentype.types._import?this.parseImport(node):this.parseExport(node);default:var maybeName=this.value,expr=this.parseExpression();if(starttype===_tokentype.types.name&&expr.type==="Identifier"&&this.eat(_tokentype.types.colon))return this.parseLabeledStatement(node,maybeName,expr);else return this.parseExpressionStatement(node,expr);}};pp.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword=="break";this.next();if(this.eat(_tokentype.types.semi)||this.insertSemicolon())node.label=null;else if(this.type!==_tokentype.types.name)this.unexpected();else{node.label=this.parseIdent();this.semicolon();}
for(var i=0;i<this.labels.length;++i){var lab=this.labels[i];if(node.label==null||lab.name===node.label.name){if(lab.kind!=null&&(isBreak||lab.kind==="loop"))break;if(node.label&&isBreak)break;}}
if(i===this.labels.length)this.raise(node.start,"Unsyntactic "+keyword);return this.finishNode(node,isBreak?"BreakStatement":"ContinueStatement");};pp.parseDebuggerStatement=function(node){this.next();this.semicolon();return this.finishNode(node,"DebuggerStatement");};pp.parseDoStatement=function(node){this.next();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();this.expect(_tokentype.types._while);node.test=this.parseParenExpression();if(this.options.ecmaVersion>=6)this.eat(_tokentype.types.semi);else this.semicolon();return this.finishNode(node,"DoWhileStatement");};pp.parseForStatement=function(node){this.next();this.labels.push(loopLabel);this.expect(_tokentype.types.parenL);if(this.type===_tokentype.types.semi)return this.parseFor(node,null);if(this.type===_tokentype.types._var||this.type===_tokentype.types._let||this.type===_tokentype.types._const){var _init=this.startNode(),varKind=this.type;this.next();this.parseVar(_init,true,varKind);this.finishNode(_init,"VariableDeclaration");if((this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&_init.declarations.length===1&&!(varKind!==_tokentype.types._var&&_init.declarations[0].init))return this.parseForIn(node,_init);return this.parseFor(node,_init);}
var refShorthandDefaultPos={start:0};var init=this.parseExpression(true,refShorthandDefaultPos);if(this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of")){this.toAssignable(init);this.checkLVal(init);return this.parseForIn(node,init);}else if(refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start);}
return this.parseFor(node,init);};pp.parseFunctionStatement=function(node){this.next();return this.parseFunction(node,true);};pp.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement(false);node.alternate=this.eat(_tokentype.types._else)?this.parseStatement(false):null;return this.finishNode(node,"IfStatement");};pp.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction)this.raise(this.start,"'return' outside of function");this.next();if(this.eat(_tokentype.types.semi)||this.insertSemicolon())node.argument=null;else{node.argument=this.parseExpression();this.semicolon();}
return this.finishNode(node,"ReturnStatement");};pp.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(_tokentype.types.braceL);this.labels.push(switchLabel);for(var cur,sawDefault=false;this.type!=_tokentype.types.braceR;){if(this.type===_tokentype.types._case||this.type===_tokentype.types._default){var isCase=this.type===_tokentype.types._case;if(cur)this.finishNode(cur,"SwitchCase");node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression();}else{if(sawDefault)this.raise(this.lastTokStart,"Multiple default clauses");sawDefault=true;cur.test=null;}
this.expect(_tokentype.types.colon);}else{if(!cur)this.unexpected();cur.consequent.push(this.parseStatement(true));}}
if(cur)this.finishNode(cur,"SwitchCase");this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement");};pp.parseThrowStatement=function(node){this.next();if(_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))this.raise(this.lastTokEnd,"Illegal newline after throw");node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement");};var empty=[];pp.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===_tokentype.types._catch){var clause=this.startNode();this.next();this.expect(_tokentype.types.parenL);clause.param=this.parseBindingAtom();this.checkLVal(clause.param,true);this.expect(_tokentype.types.parenR);clause.body=this.parseBlock();node.handler=this.finishNode(clause,"CatchClause");}
node.finalizer=this.eat(_tokentype.types._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer)this.raise(node.start,"Missing catch or finally clause");return this.finishNode(node,"TryStatement");};pp.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration");};pp.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"WhileStatement");};pp.parseWithStatement=function(node){if(this.strict)this.raise(this.start,"'with' in strict mode");this.next();node.object=this.parseParenExpression();node.body=this.parseStatement(false);return this.finishNode(node,"WithStatement");};pp.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement");};pp.parseLabeledStatement=function(node,maybeName,expr){for(var i=0;i<this.labels.length;++i){if(this.labels[i].name===maybeName)this.raise(expr.start,"Label '"+maybeName+"' is already declared");}var kind=this.type.isLoop?"loop":this.type===_tokentype.types._switch?"switch":null;for(var i=this.labels.length-1;i>=0;i--){var label=this.labels[i];if(label.statementStart==node.start){label.statementStart=this.start;label.kind=kind;}else break;}
this.labels.push({name:maybeName,kind:kind,statementStart:this.start});node.body=this.parseStatement(true);this.labels.pop();node.label=expr;return this.finishNode(node,"LabeledStatement");};pp.parseExpressionStatement=function(node,expr){node.expression=expr;this.semicolon();return this.finishNode(node,"ExpressionStatement");};pp.parseBlock=function(allowStrict){var node=this.startNode(),first=true,oldStrict=undefined;node.body=[];this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){var stmt=this.parseStatement(true);node.body.push(stmt);if(first&&allowStrict&&this.isUseStrict(stmt)){oldStrict=this.strict;this.setStrict(this.strict=true);}
first=false;}
if(oldStrict===false)this.setStrict(false);return this.finishNode(node,"BlockStatement");};pp.parseFor=function(node,init){node.init=init;this.expect(_tokentype.types.semi);node.test=this.type===_tokentype.types.semi?null:this.parseExpression();this.expect(_tokentype.types.semi);node.update=this.type===_tokentype.types.parenR?null:this.parseExpression();this.expect(_tokentype.types.parenR);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"ForStatement");};pp.parseForIn=function(node,init){var type=this.type===_tokentype.types._in?"ForInStatement":"ForOfStatement";this.next();node.left=init;node.right=this.parseExpression();this.expect(_tokentype.types.parenR);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,type);};pp.parseVar=function(node,isFor,kind){node.declarations=[];node.kind=kind.keyword;for(;;){var decl=this.startNode();this.parseVarId(decl);if(this.eat(_tokentype.types.eq)){decl.init=this.parseMaybeAssign(isFor);}else if(kind===_tokentype.types._const&&!(this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))){this.unexpected();}else if(decl.id.type!="Identifier"&&!(isFor&&(this.type===_tokentype.types._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value");}else{decl.init=null;}
node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(_tokentype.types.comma))break;}
return node;};pp.parseVarId=function(decl){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,true);};pp.parseFunction=function(node,isStatement,allowExpressionBody){this.initFunction(node);if(this.options.ecmaVersion>=6)node.generator=this.eat(_tokentype.types.star);if(isStatement||this.type===_tokentype.types.name)node.id=this.parseIdent();this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,isStatement?"FunctionDeclaration":"FunctionExpression");};pp.parseFunctionParams=function(node){this.expect(_tokentype.types.parenL);node.params=this.parseBindingList(_tokentype.types.parenR,false,false,true);};pp.parseClass=function(node,isStatement){this.next();this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(this.eat(_tokentype.types.semi))continue;var method=this.startNode();var isGenerator=this.eat(_tokentype.types.star);var isMaybeStatic=this.type===_tokentype.types.name&&this.value==="static";this.parsePropertyName(method);method["static"]=isMaybeStatic&&this.type!==_tokentype.types.parenL;if(method["static"]){if(isGenerator)this.unexpected();isGenerator=this.eat(_tokentype.types.star);this.parsePropertyName(method);}
method.kind="method";var isGetSet=false;if(!method.computed){var key=method.key;if(!isGenerator&&key.type==="Identifier"&&this.type!==_tokentype.types.parenL&&(key.name==="get"||key.name==="set")){isGetSet=true;method.kind=key.name;key=this.parsePropertyName(method);}
if(!method["static"]&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(hadConstructor)this.raise(key.start,"Duplicate constructor in the same class");if(isGetSet)this.raise(key.start,"Constructor can't have get/set modifier");if(isGenerator)this.raise(key.start,"Constructor can't be a generator");method.kind="constructor";hadConstructor=true;}}
this.parseClassMethod(classBody,method,isGenerator);if(isGetSet){var paramCount=method.kind==="get"?0:1;if(method.value.params.length!==paramCount){var start=method.value.start;if(method.kind==="get")this.raise(start,"getter should have no params");else this.raise(start,"setter should have exactly one param");}}}
node.body=this.finishNode(classBody,"ClassBody");return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression");};pp.parseClassMethod=function(classBody,method,isGenerator){method.value=this.parseMethod(isGenerator);classBody.body.push(this.finishNode(method,"MethodDefinition"));};pp.parseClassId=function(node,isStatement){node.id=this.type===_tokentype.types.name?this.parseIdent():isStatement?this.unexpected():null;};pp.parseClassSuper=function(node){node.superClass=this.eat(_tokentype.types._extends)?this.parseExprSubscripts():null;};pp.parseExport=function(node){this.next();if(this.eat(_tokentype.types.star)){this.expectContextual("from");node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();this.semicolon();return this.finishNode(node,"ExportAllDeclaration");}
if(this.eat(_tokentype.types._default)){var expr=this.parseMaybeAssign();var needsSemi=true;if(expr.type=="FunctionExpression"||expr.type=="ClassExpression"){needsSemi=false;if(expr.id){expr.type=expr.type=="FunctionExpression"?"FunctionDeclaration":"ClassDeclaration";}}
node.declaration=expr;if(needsSemi)this.semicolon();return this.finishNode(node,"ExportDefaultDeclaration");}
if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(true);node.specifiers=[];node.source=null;}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers();if(this.eatContextual("from")){node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();}else{for(var i=0;i<node.specifiers.length;i++){if(this.keywords.test(node.specifiers[i].local.name)||this.reservedWords.test(node.specifiers[i].local.name)){this.unexpected(node.specifiers[i].local.start);}}
node.source=null;}
this.semicolon();}
return this.finishNode(node,"ExportNamedDeclaration");};pp.shouldParseExportStatement=function(){return this.type.keyword;};pp.parseExportSpecifiers=function(){var nodes=[],first=true;this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var node=this.startNode();node.local=this.parseIdent(this.type===_tokentype.types._default);node.exported=this.eatContextual("as")?this.parseIdent(true):node.local;nodes.push(this.finishNode(node,"ExportSpecifier"));}
return nodes;};pp.parseImport=function(node){this.next();if(this.type===_tokentype.types.string){node.specifiers=empty;node.source=this.parseExprAtom();}else{node.specifiers=this.parseImportSpecifiers();this.expectContextual("from");node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();}
this.semicolon();return this.finishNode(node,"ImportDeclaration");};pp.parseImportSpecifiers=function(){var nodes=[],first=true;if(this.type===_tokentype.types.name){var node=this.startNode();node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportDefaultSpecifier"));if(!this.eat(_tokentype.types.comma))return nodes;}
if(this.type===_tokentype.types.star){var node=this.startNode();this.next();this.expectContextual("as");node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportNamespaceSpecifier"));return nodes;}
this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var node=this.startNode();node.imported=this.parseIdent(true);node.local=this.eatContextual("as")?this.parseIdent():node.imported;this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportSpecifier"));}
return nodes;};},{"./state":10,"./tokentype":14,"./whitespace":16}],12:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){Iif(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _state=_dereq_("./state");var _tokentype=_dereq_("./tokentype");var _whitespace=_dereq_("./whitespace");var TokContext=function TokContext(token,isExpr,preserveSpace,override){_classCallCheck(this,TokContext);this.token=token;this.isExpr=!!isExpr;this.preserveSpace=!!preserveSpace;this.override=override;};exports.TokContext=TokContext;var types={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",true),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.readTmplToken();}),f_expr:new TokContext("function",true)};exports.types=types;var pp=_state.Parser.prototype;pp.initialContext=function(){return[types.b_stat];};pp.braceIsBlock=function(prevType){if(prevType===_tokentype.types.colon){var _parent=this.curContext();if(_parent===types.b_stat||_parent===types.b_expr)return!_parent.isExpr;}
if(prevType===_tokentype.types._return)return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start));if(prevType===_tokentype.types._else||prevType===_tokentype.types.semi||prevType===_tokentype.types.eof||prevType===_tokentype.types.parenR)return true;if(prevType==_tokentype.types.braceL)return this.curContext()===types.b_stat;return!this.exprAllowed;};pp.updateContext=function(prevType){var update=undefined,type=this.type;if(type.keyword&&prevType==_tokentype.types.dot)this.exprAllowed=false;else if(update=type.updateContext)update.call(this,prevType);else this.exprAllowed=type.beforeExpr;};_tokentype.types.parenR.updateContext=_tokentype.types.braceR.updateContext=function(){if(this.context.length==1){this.exprAllowed=true;return;}
var out=this.context.pop();if(out===types.b_stat&&this.curContext()===types.f_expr){this.context.pop();this.exprAllowed=false;}else if(out===types.b_tmpl){this.exprAllowed=true;}else{this.exprAllowed=!out.isExpr;}};_tokentype.types.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types.b_stat:types.b_expr);this.exprAllowed=true;};_tokentype.types.dollarBraceL.updateContext=function(){this.context.push(types.b_tmpl);this.exprAllowed=true;};_tokentype.types.parenL.updateContext=function(prevType){var statementParens=prevType===_tokentype.types._if||prevType===_tokentype.types._for||prevType===_tokentype.types._with||prevType===_tokentype.types._while;this.context.push(statementParens?types.p_stat:types.p_expr);this.exprAllowed=true;};_tokentype.types.incDec.updateContext=function(){};_tokentype.types._function.updateContext=function(){if(this.curContext()!==types.b_stat)this.context.push(types.f_expr);this.exprAllowed=false;};_tokentype.types.backQuote.updateContext=function(){if(this.curContext()===types.q_tmpl)this.context.pop();else this.context.push(types.q_tmpl);this.exprAllowed=false;};},{"./state":10,"./tokentype":14,"./whitespace":16}],13:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _identifier=_dereq_("./identifier");var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var _whitespace=_dereq_("./whitespace");var Token=function Token(p){_classCallCheck(this,Token);this.type=p.type;this.value=p.value;this.start=p.start;this.end=p.end;if(p.options.locations)this.loc=new _locutil.SourceLocation(p,p.startLoc,p.endLoc);if(p.options.ranges)this.range=[p.start,p.end];};exports.Token=Token;var pp=_state.Parser.prototype;var isRhino=typeof Packages=="object"&&Object.prototype.toString.call(Packages)=="[object JavaPackage]";pp.next=function(){if(this.options.onToken)this.options.onToken(new Token(this));this.lastTokEnd=this.end;this.lastTokStart=this.start;this.lastTokEndLoc=this.endLoc;this.lastTokStartLoc=this.startLoc;this.nextToken();};pp.getToken=function(){this.next();return new Token(this);};Eif(typeof Symbol!=="undefined")pp[Symbol.iterator]=function(){var self=this;return{next:function next(){var token=self.getToken();return{done:token.type===_tokentype.types.eof,value:token};}};};pp.setStrict=function(strict){this.strict=strict;if(this.type!==_tokentype.types.num&&this.type!==_tokentype.types.string)return;this.pos=this.start;if(this.options.locations){while(this.pos<this.lineStart){this.lineStart=this.input.lastIndexOf("\n",this.lineStart-2)+1;--this.curLine;}}
this.nextToken();};pp.curContext=function(){return this.context[this.context.length-1];};pp.nextToken=function(){var curContext=this.curContext();if(!curContext||!curContext.preserveSpace)this.skipSpace();this.start=this.pos;if(this.options.locations)this.startLoc=this.curPosition();if(this.pos>=this.input.length)return this.finishToken(_tokentype.types.eof);if(curContext.override)return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());};pp.readToken=function(code){if(_identifier.isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92)return this.readWord();return this.getTokenFromCode(code);};pp.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=0xd7ff||code>=0xe000)return code;var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-0x35fdc00;};pp.skipBlockComment=function(){var startLoc=this.options.onComment&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1)this.raise(this.pos-2,"Unterminated comment");this.pos=end+2;if(this.options.locations){_whitespace.lineBreakG.lastIndex=start;var match=undefined;while((match=_whitespace.lineBreakG.exec(this.input))&&match.index<this.pos){++this.curLine;this.lineStart=match.index+match[0].length;}}
if(this.options.onComment)this.options.onComment(true,this.input.slice(start+2,end),start,this.pos,startLoc,this.curPosition());};pp.skipLineComment=function(startSkip){var start=this.pos;var startLoc=this.options.onComment&&this.curPosition();var ch=this.input.charCodeAt(this.pos+=startSkip);while(this.pos<this.input.length&&ch!==10&&ch!==13&&ch!==8232&&ch!==8233){++this.pos;ch=this.input.charCodeAt(this.pos);}
if(this.options.onComment)this.options.onComment(false,this.input.slice(start+startSkip,this.pos),start,this.pos,startLoc,this.curPosition());};pp.skipSpace=function(){loop:while(this.pos<this.input.length){var ch=this.input.charCodeAt(this.pos);switch(ch){case 32:case 160:++this.pos;break;case 13:if(this.input.charCodeAt(this.pos+1)===10){++this.pos;}
case 10:case 8232:case 8233:++this.pos;if(this.options.locations){++this.curLine;this.lineStart=this.pos;}
break;case 47:switch(this.input.charCodeAt(this.pos+1)){case 42:this.skipBlockComment();break;case 47:this.skipLineComment(2);break;default:break loop;}
break;default:if(ch>8&&ch<14||ch>=5760&&_whitespace.nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos;}else{break loop;}}}};pp.finishToken=function(type,val){this.end=this.pos;if(this.options.locations)this.endLoc=this.curPosition();var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType);};pp.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57)return this.readNumber(true);var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(_tokentype.types.ellipsis);}else{++this.pos;return this.finishToken(_tokentype.types.dot);}};pp.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp();}
if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.slash,1);};pp.readToken_mult_modulo=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(code===42?_tokentype.types.star:_tokentype.types.modulo,1);};pp.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code)return this.finishOp(code===124?_tokentype.types.logicalOR:_tokentype.types.logicalAND,2);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(code===124?_tokentype.types.bitwiseOR:_tokentype.types.bitwiseAND,1);};pp.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.bitwiseXOR,1);};pp.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next==45&&this.input.charCodeAt(this.pos+2)==62&&_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.pos))){this.skipLineComment(3);this.skipSpace();return this.nextToken();}
return this.finishOp(_tokentype.types.incDec,2);}
if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.plusMin,1);};pp.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61)return this.finishOp(_tokentype.types.assign,size+1);return this.finishOp(_tokentype.types.bitShift,size);}
if(next==33&&code==60&&this.input.charCodeAt(this.pos+2)==45&&this.input.charCodeAt(this.pos+3)==45){if(this.inModule)this.unexpected();this.skipLineComment(4);this.skipSpace();return this.nextToken();}
if(next===61)size=this.input.charCodeAt(this.pos+2)===61?3:2;return this.finishOp(_tokentype.types.relational,size);};pp.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.equality,this.input.charCodeAt(this.pos+2)===61?3:2);if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(_tokentype.types.arrow);}
return this.finishOp(code===61?_tokentype.types.eq:_tokentype.types.prefix,1);};pp.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(_tokentype.types.parenL);case 41:++this.pos;return this.finishToken(_tokentype.types.parenR);case 59:++this.pos;return this.finishToken(_tokentype.types.semi);case 44:++this.pos;return this.finishToken(_tokentype.types.comma);case 91:++this.pos;return this.finishToken(_tokentype.types.bracketL);case 93:++this.pos;return this.finishToken(_tokentype.types.bracketR);case 123:++this.pos;return this.finishToken(_tokentype.types.braceL);case 125:++this.pos;return this.finishToken(_tokentype.types.braceR);case 58:++this.pos;return this.finishToken(_tokentype.types.colon);case 63:++this.pos;return this.finishToken(_tokentype.types.question);case 96:if(this.options.ecmaVersion<6)break;++this.pos;return this.finishToken(_tokentype.types.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(next===111||next===79)return this.readRadixNumber(8);if(next===98||next===66)return this.readRadixNumber(2);}
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(_tokentype.types.prefix,1);}
this.raise(this.pos,"Unexpected character '"+codePointToString(code)+"'");};pp.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str);};function tryCreateRegexp(src,flags,throwErrorAt,parser){try{return new RegExp(src,flags);}catch(e){if(throwErrorAt!==undefined){if(e instanceof SyntaxError)parser.raise(throwErrorAt,"Error parsing regular expression: "+e.message);throw e;}}}
var regexpUnicodeSupport=!!tryCreateRegexp("","u");pp.readRegexp=function(){var _this=this;var escaped=undefined,inClass=undefined,start=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(start,"Unterminated regular expression");var ch=this.input.charAt(this.pos);if(_whitespace.lineBreak.test(ch))this.raise(start,"Unterminated regular expression");if(!escaped){if(ch==="[")inClass=true;else if(ch==="]"&&inClass)inClass=false;else if(ch==="/"&&!inClass)break;escaped=ch==="\\";}else escaped=false;++this.pos;}
var content=this.input.slice(start,this.pos);++this.pos;var mods=this.readWord1();var tmp=content;if(mods){var validFlags=/^[gmsiy]*$/;if(this.options.ecmaVersion>=6)validFlags=/^[gmsiyu]*$/;if(!validFlags.test(mods))this.raise(start,"Invalid regular expression flag");if(mods.indexOf('u')>=0&&!regexpUnicodeSupport){tmp=tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(_match,code,offset){code=Number("0x"+code);if(code>0x10FFFF)_this.raise(start+offset+3,"Code point out of bounds");return"x";});tmp=tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x");}}
var value=null;if(!isRhino){tryCreateRegexp(tmp,undefined,start,this);value=tryCreateRegexp(content,mods);}
return this.finishToken(_tokentype.types.regexp,{pattern:content,flags:mods,value:value});};pp.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i<e;++i){var code=this.input.charCodeAt(this.pos),val=undefined;if(code>=97)val=code-97+10;else if(code>=65)val=code-65+10;else if(code>=48&&code<=57)val=code-48;else val=Infinity;if(val>=radix)break;++this.pos;total=total*radix+val;}
if(this.pos===start||len!=null&&this.pos-start!==len)return null;return total;};pp.readRadixNumber=function(radix){this.pos+=2;var val=this.readInt(radix);if(val==null)this.raise(this.start+2,"Expected number in radix "+radix);if(_identifier.isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");return this.finishToken(_tokentype.types.num,val);};pp.readNumber=function(startsWithDot){var start=this.pos,isFloat=false,octal=this.input.charCodeAt(this.pos)===48;if(!startsWithDot&&this.readInt(10)===null)this.raise(start,"Invalid number");var next=this.input.charCodeAt(this.pos);if(next===46){++this.pos;this.readInt(10);isFloat=true;next=this.input.charCodeAt(this.pos);}
if(next===69||next===101){next=this.input.charCodeAt(++this.pos);if(next===43||next===45)++this.pos;if(this.readInt(10)===null)this.raise(start,"Invalid number");isFloat=true;}
if(_identifier.isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");var str=this.input.slice(start,this.pos),val=undefined;if(isFloat)val=parseFloat(str);else if(!octal||str.length===1)val=parseInt(str,10);else if(/[89]/.test(str)||this.strict)this.raise(start,"Invalid number");else val=parseInt(str,8);return this.finishToken(_tokentype.types.num,val);};pp.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code=undefined;if(ch===123){if(this.options.ecmaVersion<6)this.unexpected();var codePos=++this.pos;code=this.readHexChar(this.input.indexOf('}',this.pos)-this.pos);++this.pos;if(code>0x10FFFF)this.raise(codePos,"Code point out of bounds");}else{code=this.readHexChar(4);}
return code;};function codePointToString(code){if(code<=0xFFFF)return String.fromCharCode(code);code-=0x10000;return String.fromCharCode((code>>10)+0xD800,(code&1023)+0xDC00);}
pp.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated string constant");var ch=this.input.charCodeAt(this.pos);if(ch===quote)break;if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(false);chunkStart=this.pos;}else{if(_whitespace.isNewLine(ch))this.raise(this.start,"Unterminated string constant");++this.pos;}}
out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(_tokentype.types.string,out);};pp.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated template");var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&this.type===_tokentype.types.template){if(ch===36){this.pos+=2;return this.finishToken(_tokentype.types.dollarBraceL);}else{++this.pos;return this.finishToken(_tokentype.types.backQuote);}}
out+=this.input.slice(chunkStart,this.pos);return this.finishToken(_tokentype.types.template,out);}
if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(true);chunkStart=this.pos;}else if(_whitespace.isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;switch(ch){case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:out+="\n";break;default:out+=String.fromCharCode(ch);break;}
if(this.options.locations){++this.curLine;this.lineStart=this.pos;}
chunkStart=this.pos;}else{++this.pos;}}};pp.readEscapedChar=function(inTemplate){var ch=this.input.charCodeAt(++this.pos);++this.pos;switch(ch){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return codePointToString(this.readCodePoint());case 116:return"\t";case 98:return"\b";case 118:return"\u000b";case 102:return"\f";case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:if(this.options.locations){this.lineStart=this.pos;++this.curLine;}
return"";default:if(ch>=48&&ch<=55){var octalStr=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0];var octal=parseInt(octalStr,8);if(octal>255){octalStr=octalStr.slice(0,-1);octal=parseInt(octalStr,8);}
if(octal>0&&(this.strict||inTemplate)){this.raise(this.pos-2,"Octal literal in strict mode");}
this.pos+=octalStr.length-1;return String.fromCharCode(octal);}
return String.fromCharCode(ch);}};pp.readHexChar=function(len){var codePos=this.pos;var n=this.readInt(16,len);if(n===null)this.raise(codePos,"Bad character escape sequence");return n;};pp.readWord1=function(){this.containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos<this.input.length){var ch=this.fullCharCodeAtPos();if(_identifier.isIdentifierChar(ch,astral)){this.pos+=ch<=0xffff?1:2;}else if(ch===92){this.containsEsc=true;word+=this.input.slice(chunkStart,this.pos);var escStart=this.pos;if(this.input.charCodeAt(++this.pos)!=117)
this.raise(this.pos,"Expecting Unicode escape sequence \\uXXXX");++this.pos;var esc=this.readCodePoint();if(!(first?_identifier.isIdentifierStart:_identifier.isIdentifierChar)(esc,astral))this.raise(escStart,"Invalid Unicode escape");word+=codePointToString(esc);chunkStart=this.pos;}else{break;}
first=false;}
return word+this.input.slice(chunkStart,this.pos);};pp.readWord=function(){var word=this.readWord1();var type=_tokentype.types.name;if((this.options.ecmaVersion>=6||!this.containsEsc)&&this.keywords.test(word))type=_tokentype.keywords[word];return this.finishToken(type,word);};},{"./identifier":2,"./locutil":5,"./state":10,"./tokentype":14,"./whitespace":16}],14:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){Iif(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var TokenType=function TokenType(label){var conf=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];_classCallCheck(this,TokenType);this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null;};exports.TokenType=TokenType;function binop(name,prec){return new TokenType(name,{beforeExpr:true,binop:prec});}
var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("prefix",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=",6),relational:binop("</>",7),bitShift:binop("<</>>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10)};exports.types=types;var keywords={};exports.keywords=keywords;function kw(name){var options=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];options.keyword=name;keywords[name]=types["_"+name]=new TokenType(name,options);}
kw("break");kw("case",beforeExpr);kw("catch");kw("continue");kw("debugger");kw("default",beforeExpr);kw("do",{isLoop:true,beforeExpr:true});kw("else",beforeExpr);kw("finally");kw("for",{isLoop:true});kw("function",startsExpr);kw("if");kw("return",beforeExpr);kw("switch");kw("throw",beforeExpr);kw("try");kw("var");kw("let");kw("const");kw("while",{isLoop:true});kw("with");kw("new",{beforeExpr:true,startsExpr:true});kw("this",startsExpr);kw("super",startsExpr);kw("class");kw("extends",beforeExpr);kw("export");kw("import");kw("yield",{beforeExpr:true,startsExpr:true});kw("null",startsExpr);kw("true",startsExpr);kw("false",startsExpr);kw("in",{beforeExpr:true,binop:7});kw("instanceof",{beforeExpr:true,binop:7});kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true});kw("void",{beforeExpr:true,prefix:true,startsExpr:true});kw("delete",{beforeExpr:true,prefix:true,startsExpr:true});},{}],15:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isArray=isArray;exports.has=has;function isArray(obj){return Object.prototype.toString.call(obj)==="[object Array]";}
function has(obj,propName){return Object.prototype.hasOwnProperty.call(obj,propName);}},{}],16:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isNewLine=isNewLine;var lineBreak=/\r\n?|\n|\u2028|\u2029/;exports.lineBreak=lineBreak;var lineBreakG=new RegExp(lineBreak.source,"g");exports.lineBreakG=lineBreakG;function isNewLine(code){return code===10||code===13||code===0x2028||code==0x2029;}
var nonASCIIwhitespace=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;exports.nonASCIIwhitespace=nonASCIIwhitespace;},{}]},{},[3])(3)});;WebInspector.AcornTokenizer=function(content)
{this._content=content;this._comments=[];this._tokenizer=acorn.tokenizer(this._content,{ecmaVersion:6,onComment:this._comments});this._lineEndings=this._content.computeLineEndings();this._lineNumber=0;this._tokenLineStart=0;this._tokenLineEnd=0;this._nextTokenInternal();}
WebInspector.AcornTokenizer.punctuator=function(token,values)
{return token.type!==acorn.tokTypes.num&&token.type!==acorn.tokTypes.regexp&&token.type!==acorn.tokTypes.string&&token.type!==acorn.tokTypes.name&&!token.type.keyword&&(!values||(token.type.label.length===1&&values.indexOf(token.type.label)!==-1));}
WebInspector.AcornTokenizer.keyword=function(token,keyword)
{return!!token.type.keyword&&token.type!==acorn.tokTypes._true&&token.type!==acorn.tokTypes._false&&(!keyword||token.type.keyword===keyword);}
WebInspector.AcornTokenizer.identifier=function(token,identifier)
{return token.type===acorn.tokTypes.name&&(!identifier||token.value===identifier);}
WebInspector.AcornTokenizer.lineComment=function(token)
{return token.type==="Line";}
WebInspector.AcornTokenizer.blockComment=function(token)
{return token.type==="Block";}
WebInspector.AcornTokenizer.prototype={_nextTokenInternal:function()
{if(this._comments.length)
return this._comments.shift();var token=this._bufferedToken;this._bufferedToken=this._tokenizer.getToken();return token;},_rollLineNumberToPosition:function(position)
{while(this._lineNumber+1<this._lineEndings.length&&position>this._lineEndings[this._lineNumber])
++this._lineNumber;return this._lineNumber;},nextToken:function()
{var token=this._nextTokenInternal();if(token.type===acorn.tokTypes.eof)
return null;this._tokenLineStart=this._rollLineNumberToPosition(token.start);this._tokenLineEnd=this._rollLineNumberToPosition(token.end);this._tokenColumnStart=this._tokenLineStart>0?token.start-this._lineEndings[this._tokenLineStart-1]-1:token.start;return token;},peekToken:function()
{if(this._comments.length)
return this._comments[0];return this._bufferedToken.type!==acorn.tokTypes.eof?this._bufferedToken:null;},tokenLineStart:function()
{return this._tokenLineStart;},tokenLineEnd:function()
{return this._tokenLineEnd;},tokenColumnStart:function()
{return this._tokenColumnStart;}};WebInspector.ESTreeWalker=function(beforeVisit,afterVisit)
{this._beforeVisit=beforeVisit;this._afterVisit=afterVisit||new Function();this._walkNulls=false;}
WebInspector.ESTreeWalker.SkipSubtree={};WebInspector.ESTreeWalker.prototype={setWalkNulls:function(value)
{this._walkNulls=value;},walk:function(ast)
{this._innerWalk(ast,null);},_innerWalk:function(node,parent)
{if(!node&&parent&&this._walkNulls){node=({type:"Literal",raw:"null",value:null});}
if(!node)
return;node.parent=parent;if(this._beforeVisit.call(null,node)===WebInspector.ESTreeWalker.SkipSubtree){this._afterVisit.call(null,node);return;}
var walkOrder=WebInspector.ESTreeWalker._walkOrder[node.type];if(!walkOrder){console.error("Walk order not defined for "+node.type);return;}
if(node.type==="TemplateLiteral"){var templateLiteral=(node);var expressionsLength=templateLiteral.expressions.length;for(var i=0;i<expressionsLength;++i){this._innerWalk(templateLiteral.quasis[i],templateLiteral);this._innerWalk(templateLiteral.expressions[i],templateLiteral);}
this._innerWalk(templateLiteral.quasis[expressionsLength],templateLiteral);}else{for(var i=0;i<walkOrder.length;++i){var entity=node[walkOrder[i]];if(Array.isArray(entity))
this._walkArray(entity,node);else
this._innerWalk(entity,node);}}
this._afterVisit.call(null,node);},_walkArray:function(nodeArray,parentNode)
{for(var i=0;i<nodeArray.length;++i)
this._innerWalk(nodeArray[i],parentNode);},}
WebInspector.ESTreeWalker._walkOrder={"ArrayExpression":["elements"],"ArrowFunctionExpression":["params","body"],"AssignmentExpression":["left","right"],"BinaryExpression":["left","right"],"BlockStatement":["body"],"BreakStatement":["label"],"CallExpression":["callee","arguments"],"CatchClause":["param","body"],"ClassBody":["body"],"ClassDeclaration":["id","superClass","body"],"ConditionalExpression":["test","consequent","alternate"],"ContinueStatement":["label"],"DebuggerStatement":[],"DoWhileStatement":["body","test"],"EmptyStatement":[],"ExpressionStatement":["expression"],"ForInStatement":["left","right","body"],"ForOfStatement":["left","right","body"],"ForStatement":["init","test","update","body"],"FunctionDeclaration":["id","params","body"],"FunctionExpression":["id","params","body"],"Identifier":[],"IfStatement":["test","consequent","alternate"],"LabeledStatement":["label","body"],"Literal":[],"LogicalExpression":["left","right"],"MemberExpression":["object","property"],"MethodDefinition":["key","value"],"NewExpression":["callee","arguments"],"ObjectExpression":["properties"],"Program":["body"],"Property":["key","value"],"ReturnStatement":["argument"],"SequenceExpression":["expressions"],"Super":[],"SwitchCase":["test","consequent"],"SwitchStatement":["discriminant","cases"],"TaggedTemplateExpression":["tag","quasi"],"TemplateElement":[],"TemplateLiteral":["quasis","expressions"],"ThisExpression":[],"ThrowStatement":["argument"],"TryStatement":["block","handler","finalizer"],"UnaryExpression":["argument"],"UpdateExpression":["argument"],"VariableDeclaration":["declarations"],"VariableDeclarator":["id","init"],"WhileStatement":["test","body"],"WithStatement":["object","body"],"YieldExpression":["argument"]};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var allDescriptors=[{"remote":true,"name":"gonzales","skip_compilation":["gonzales-scss.js"],"dependencies":["formatter_worker"],"extensions":[{"className":"WebInspector.SCSSParser","mimeType":"text/x-scss","type":"@WebInspector.FormatterWorkerContentParser"}],"scripts":[]},{"skip_compilation":["../acorn/acorn.js","../cm/headlesscodemirror.js","../cm/css.js","../cm/xml.js"],"name":"formatter_worker","scripts":[]}];var applicationDescriptor;var _loadedScripts={};for(var k of[]){};function loadResourcePromise(url)
{return new Promise(load);function load(fulfill,reject)
{var xhr=new XMLHttpRequest();xhr.open("GET",url,true);xhr.onreadystatechange=onreadystatechange;function onreadystatechange(e)
{if(xhr.readyState!==4)
return;if([0,200,304].indexOf(xhr.status)===-1)
reject(new Error("While loading from url "+url+" server responded with a status of "+xhr.status));else
fulfill(e.target.response);}
xhr.send(null);}}
function normalizePath(path)
{if(path.indexOf("..")===-1&&path.indexOf(".")===-1)
return path;var normalizedSegments=[];var segments=path.split("/");for(var i=0;i<segments.length;i++){var segment=segments[i];if(segment===".")
continue;else if(segment==="..")
normalizedSegments.pop();else if(segment)
normalizedSegments.push(segment);}
var normalizedPath=normalizedSegments.join("/");if(normalizedPath[normalizedPath.length-1]==="/")
return normalizedPath;if(path[0]==="/"&&normalizedPath)
normalizedPath="/"+normalizedPath;if((path[path.length-1]==="/")||(segments[segments.length-1]===".")||(segments[segments.length-1]===".."))
normalizedPath=normalizedPath+"/";return normalizedPath;}
function loadScriptsPromise(scriptNames,base)
{var promises=[];var urls=[];var sources=new Array(scriptNames.length);var scriptToEval=0;for(var i=0;i<scriptNames.length;++i){var scriptName=scriptNames[i];var sourceURL=(base||self._importScriptPathPrefix)+scriptName;var schemaIndex=sourceURL.indexOf("://")+3;var pathIndex=sourceURL.indexOf("/",schemaIndex);if(pathIndex===-1)
pathIndex=sourceURL.length;sourceURL=sourceURL.substring(0,pathIndex)+normalizePath(sourceURL.substring(pathIndex));if(_loadedScripts[sourceURL])
continue;urls.push(sourceURL);promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null,i),scriptSourceLoaded.bind(null,i,undefined)));}
return Promise.all(promises).then(undefined);function scriptSourceLoaded(scriptNumber,scriptSource)
{sources[scriptNumber]=scriptSource||"";while(typeof sources[scriptToEval]!=="undefined"){evaluateScript(urls[scriptToEval],sources[scriptToEval]);++scriptToEval;}}
function evaluateScript(sourceURL,scriptSource)
{_loadedScripts[sourceURL]=true;if(!scriptSource){console.error("Empty response arrived for script '"+sourceURL+"'");return;}
self.eval(scriptSource+"\n//# sourceURL="+sourceURL);}}
(function(){var baseUrl=self.location?self.location.origin+self.location.pathname:"";self._importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf("/")+1);})();function Runtime(descriptors)
{this._modules=[];this._modulesMap={};this._extensions=[];this._cachedTypeClasses={};this._descriptorsMap={};for(var i=0;i<descriptors.length;++i)
this._registerModule(descriptors[i]);}
Runtime._queryParamsObject={__proto__:null};Runtime.cachedResources={__proto__:null};Runtime.isReleaseMode=function()
{return!!allDescriptors.length;}
Runtime.startApplication=function(appName)
{console.timeStamp("Runtime.startApplication");var allDescriptorsByName={};for(var i=0;Runtime.isReleaseMode()&&i<allDescriptors.length;++i){var d=allDescriptors[i];allDescriptorsByName[d["name"]]=d;}
var applicationPromise;if(applicationDescriptor)
applicationPromise=Promise.resolve(applicationDescriptor);else
applicationPromise=loadResourcePromise(appName+".json").then(JSON.parse.bind(JSON));return applicationPromise.then(parseModuleDescriptors);function parseModuleDescriptors(appDescriptor)
{var configuration=appDescriptor.modules;var moduleJSONPromises=[];var coreModuleNames=[];for(var i=0;i<configuration.length;++i){var descriptor=configuration[i];var name=descriptor["name"];var moduleJSON=allDescriptorsByName[name];if(moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));else
moduleJSONPromises.push(loadResourcePromise(name+"/module.json").then(JSON.parse.bind(JSON)));if(descriptor["type"]==="autostart")
coreModuleNames.push(name);}
return Promise.all(moduleJSONPromises).then(instantiateRuntime);function instantiateRuntime(moduleDescriptors)
{for(var i=0;!Runtime.isReleaseMode()&&i<moduleDescriptors.length;++i){moduleDescriptors[i]["name"]=configuration[i]["name"];moduleDescriptors[i]["condition"]=configuration[i]["condition"];}
self.runtime=new Runtime(moduleDescriptors);if(coreModuleNames)
return(self.runtime._loadAutoStartModules(coreModuleNames));return Promise.resolve();}}}
Runtime.startWorker=function(appName)
{return Runtime.startApplication(appName).then(sendWorkerReady);function sendWorkerReady()
{self.postMessage("workerReady");}}
Runtime._sharedWorkerNewPortCallback=null;Runtime._sharedWorkerConnectedPorts=[];Runtime.startSharedWorker=function(appName)
{var startPromise=Runtime.startApplication(appName);self.onconnect=function(event)
{var newPort=(event.ports[0]);startPromise.then(sendWorkerReadyAndContinue);function sendWorkerReadyAndContinue()
{newPort.postMessage("workerReady");if(Runtime._sharedWorkerNewPortCallback)
Runtime._sharedWorkerNewPortCallback.call(null,newPort);else
Runtime._sharedWorkerConnectedPorts.push(newPort);}}}
Runtime.setSharedWorkerNewPortCallback=function(callback)
{Runtime._sharedWorkerNewPortCallback=callback;while(Runtime._sharedWorkerConnectedPorts.length){var port=Runtime._sharedWorkerConnectedPorts.shift();callback.call(null,port);}}
Runtime.queryParam=function(name)
{return Runtime._queryParamsObject[name]||null;}
Runtime.constructQueryParams=function(banned)
{var params=[];for(var key in Runtime._queryParamsObject){if(!key||banned.indexOf(key)!==-1)
continue;params.push(key+"="+Runtime._queryParamsObject[key]);}
return params.length?"?"+params.join("&"):"";}
Runtime._experimentsSetting=function()
{try{return(JSON.parse(self.localStorage&&self.localStorage["experiments"]?self.localStorage["experiments"]:"{}"));}catch(e){console.error("Failed to parse localStorage['experiments']");return{};}}
Runtime._some=function(promises)
{var all=[];var wasRejected=[];for(var i=0;i<promises.length;++i){var handlerFunction=(handler.bind(promises[i],i));all.push(promises[i].catch(handlerFunction));}
return Promise.all(all).then(filterOutFailuresResults);function filterOutFailuresResults(results)
{var filtered=[];for(var i=0;i<results.length;++i){if(!wasRejected[i])
filtered.push(results[i]);}
return filtered;}
function handler(index,e)
{wasRejected[index]=true;console.error(e.stack);}}
Runtime._console=console;Runtime._originalAssert=console.assert;Runtime._assert=function(value,message)
{if(value)
return;Runtime._originalAssert.call(Runtime._console,value,message+" "+new Error().stack);}
Runtime.prototype={useTestBase:function()
{Runtime._remoteBase="http://localhost:8000/inspector-sources/";},_registerModule:function(descriptor)
{var module=new Runtime.Module(this,descriptor);this._modules.push(module);this._modulesMap[descriptor["name"]]=module;},loadModulePromise:function(moduleName)
{return this._modulesMap[moduleName]._loadPromise();},_loadAutoStartModules:function(moduleNames)
{var promises=[];for(var i=0;i<moduleNames.length;++i){if(Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded=true;else
promises.push(this.loadModulePromise(moduleNames[i]));}
return Promise.all(promises);},_checkExtensionApplicability:function(extension,predicate)
{if(!predicate)
return false;var contextTypes=(extension.descriptor().contextTypes);if(!contextTypes)
return true;for(var i=0;i<contextTypes.length;++i){var contextType=this._resolve(contextTypes[i]);var isMatching=!!contextType&&predicate(contextType);if(isMatching)
return true;}
return false;},isExtensionApplicableToContext:function(extension,context)
{if(!context)
return true;return this._checkExtensionApplicability(extension,isInstanceOf);function isInstanceOf(targetType)
{return context instanceof targetType;}},isExtensionApplicableToContextTypes:function(extension,currentContextTypes)
{if(!extension.descriptor().contextTypes)
return true;return this._checkExtensionApplicability(extension,currentContextTypes?isContextTypeKnown:null);function isContextTypeKnown(targetType)
{return currentContextTypes.has(targetType);}},extensions:function(type,context)
{return this._extensions.filter(filter).sort(orderComparator);function filter(extension)
{if(extension._type!==type&&extension._typeClass()!==type)
return false;if(!extension.enabled())
return false;return!context||extension.isApplicable(context);}
function orderComparator(extension1,extension2)
{var order1=extension1.descriptor()["order"]||0;var order2=extension2.descriptor()["order"]||0;return order1-order2;}},extension:function(type,context)
{return this.extensions(type,context)[0]||null;},instancesPromise:function(type,context)
{var extensions=this.extensions(type,context);var promises=[];for(var i=0;i<extensions.length;++i)
promises.push(extensions[i].instancePromise());return Runtime._some(promises);},instancePromise:function(type,context)
{var extension=this.extension(type,context);if(!extension)
return Promise.reject(new Error("No such extension: "+type+" in given context."));return extension.instancePromise();},_resolve:function(typeName)
{if(!this._cachedTypeClasses[typeName]){var path=typeName.split(".");var object=self;for(var i=0;object&&(i<path.length);++i)
object=object[path[i]];if(object)
this._cachedTypeClasses[typeName]=(object);}
return this._cachedTypeClasses[typeName]||null;}}
Runtime.ModuleDescriptor=function()
{this.name;this.extensions;this.dependencies;this.scripts;this.remote;}
Runtime.ExtensionDescriptor=function()
{this.type;this.className;this.contextTypes;}
Runtime.Module=function(manager,descriptor)
{this._manager=manager;this._descriptor=descriptor;this._name=descriptor.name;this._instanceMap={};var extensions=(descriptor.extensions);for(var i=0;extensions&&i<extensions.length;++i)
this._manager._extensions.push(new Runtime.Extension(this,extensions[i]));this._loaded=false;}
Runtime.Module.prototype={name:function()
{return this._name;},enabled:function()
{return Runtime._isDescriptorEnabled(this._descriptor);},resource:function(name)
{var fullName=this._name+"/"+name;var content=Runtime.cachedResources[fullName];if(!content)
throw new Error(fullName+" not preloaded. Check module.json");return content;},_loadPromise:function()
{if(this._loaded)
return Promise.resolve();if(!this.enabled())
return Promise.reject(new Error("Module "+this._name+" is not enabled"));if(this._pendingLoadPromise)
return this._pendingLoadPromise;var dependencies=this._descriptor.dependencies;var dependencyPromises=[];for(var i=0;dependencies&&i<dependencies.length;++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());this._pendingLoadPromise=Promise.all(dependencyPromises).then(this._loadResources.bind(this)).then(this._loadScripts.bind(this)).then(markAsLoaded.bind(this));return this._pendingLoadPromise;function markAsLoaded()
{delete this._pendingLoadPromise;this._loaded=true;}},_loadResources:function()
{var resources=this._descriptor["resources"];if(!resources)
return Promise.resolve();var promises=[];for(var i=0;i<resources.length;++i){var url=this._modularizeURL(resources[i]);promises.push(loadResourcePromise(url).then(cacheResource.bind(this,url),cacheResource.bind(this,url,undefined)));}
return Promise.all(promises).then(undefined);function cacheResource(path,content)
{if(!content){console.error("Failed to load resource: "+path);return;}
Runtime.cachedResources[path]=content+Runtime.resolveSourceURL(path);}},_loadScripts:function()
{if(!this._descriptor.scripts)
return Promise.resolve();if(Runtime.isReleaseMode())
return loadScriptsPromise([this._name+"_module.js"],this._remoteBase());return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL,this));},_modularizeURL:function(resourceName)
{return normalizePath(this._name+"/"+resourceName);},_remoteBase:function()
{return this._descriptor.remote&&Runtime._remoteBase||undefined;},substituteURL:function(value)
{var base=this._remoteBase()||"";return value.replace(/@url\(([^\)]*?)\)/g,convertURL.bind(this));function convertURL(match,url)
{return base+this._modularizeURL(url);}},_instance:function(className,extension)
{if(className in this._instanceMap)
return this._instanceMap[className];var constructorFunction=self.eval(className);if(!(constructorFunction instanceof Function)){this._instanceMap[className]=null;return null;}
var instance=new constructorFunction(extension);this._instanceMap[className]=instance;return instance;}}
Runtime._isDescriptorEnabled=function(descriptor)
{var activatorExperiment=descriptor["experiment"];if(activatorExperiment&&activatorExperiment.startsWith("!")&&Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;if(activatorExperiment&&!activatorExperiment.startsWith("!")&&!Runtime.experiments.isEnabled(activatorExperiment))
return false;var condition=descriptor["condition"];if(condition&&!condition.startsWith("!")&&!Runtime.queryParam(condition))
return false;if(condition&&condition.startsWith("!")&&Runtime.queryParam(condition.substring(1)))
return false;return true;}
Runtime.Extension=function(module,descriptor)
{this._module=module;this._descriptor=descriptor;this._type=descriptor.type;this._hasTypeClass=this._type.charAt(0)==="@";this._className=descriptor.className||null;}
Runtime.Extension.prototype={descriptor:function()
{return this._descriptor;},module:function()
{return this._module;},enabled:function()
{return this._module.enabled()&&Runtime._isDescriptorEnabled(this.descriptor());},_typeClass:function()
{if(!this._hasTypeClass)
return null;return this._module._manager._resolve(this._type.substring(1));},isApplicable:function(context)
{return this._module._manager.isExtensionApplicableToContext(this,context);},instancePromise:function()
{if(!this._className)
return Promise.reject(new Error("No class name in extension"));var className=this._className;if(this._instance)
return Promise.resolve(this._instance);return this._module._loadPromise().then(constructInstance.bind(this));function constructInstance()
{var result=this._module._instance(className,this);if(!result)
return Promise.reject("Could not instantiate: "+className);return result;}},title:function(platform)
{return this._descriptor["title-"+platform]||this._descriptor["title"];}}
Runtime.ExperimentsSupport=function()
{this._supportEnabled=Runtime.queryParam("experiments")!==null;this._experiments=[];this._experimentNames={};this._enabledTransiently={};}
Runtime.ExperimentsSupport.prototype={allConfigurableExperiments:function()
{var result=[];for(var i=0;i<this._experiments.length;i++){var experiment=this._experiments[i];if(!this._enabledTransiently[experiment.name])
result.push(experiment);}
return result;},supportEnabled:function()
{return this._supportEnabled;},_setExperimentsSetting:function(value)
{if(!self.localStorage)
return;self.localStorage["experiments"]=JSON.stringify(value);},register:function(experimentName,experimentTitle,hidden)
{Runtime._assert(!this._experimentNames[experimentName],"Duplicate registration of experiment "+experimentName);this._experimentNames[experimentName]=true;this._experiments.push(new Runtime.Experiment(this,experimentName,experimentTitle,!!hidden));},isEnabled:function(experimentName)
{this._checkExperiment(experimentName);if(this._enabledTransiently[experimentName])
return true;if(!this.supportEnabled())
return false;return!!Runtime._experimentsSetting()[experimentName];},setEnabled:function(experimentName,enabled)
{this._checkExperiment(experimentName);var experimentsSetting=Runtime._experimentsSetting();experimentsSetting[experimentName]=enabled;this._setExperimentsSetting(experimentsSetting);},setDefaultExperiments:function(experimentNames)
{for(var i=0;i<experimentNames.length;++i){this._checkExperiment(experimentNames[i]);this._enabledTransiently[experimentNames[i]]=true;}},enableForTest:function(experimentName)
{this._checkExperiment(experimentName);this._enabledTransiently[experimentName]=true;},clearForTest:function()
{this._experiments=[];this._experimentNames={};this._enabledTransiently={};},cleanUpStaleExperiments:function()
{var experimentsSetting=Runtime._experimentsSetting();var cleanedUpExperimentSetting={};for(var i=0;i<this._experiments.length;++i){var experimentName=this._experiments[i].name;if(experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName]=true;}
this._setExperimentsSetting(cleanedUpExperimentSetting);},_checkExperiment:function(experimentName)
{Runtime._assert(this._experimentNames[experimentName],"Unknown experiment "+experimentName);}}
Runtime.Experiment=function(experiments,name,title,hidden)
{this.name=name;this.title=title;this.hidden=hidden;this._experiments=experiments;}
Runtime.Experiment.prototype={isEnabled:function()
{return this._experiments.isEnabled(this.name);},setEnabled:function(enabled)
{this._experiments.setEnabled(this.name,enabled);}}
{(function parseQueryParameters()
{var queryParams=location.search;if(!queryParams)
return;var params=queryParams.substring(1).split("&");for(var i=0;i<params.length;++i){var pair=params[i].split("=");var name=pair.shift();Runtime._queryParamsObject[name]=pair.join("=");}})();}
Runtime.experiments=new Runtime.ExperimentsSupport();Runtime._remoteBase=Runtime.queryParam("remoteBase");{(function validateRemoteBase()
{var remoteBaseRegexp=/^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/;if(Runtime._remoteBase&&!remoteBaseRegexp.test(Runtime._remoteBase))
Runtime._remoteBase=null;})();}
Runtime.resolveSourceURL=function(path)
{var sourceURL=self.location.href;if(self.location.search)
sourceURL=sourceURL.replace(self.location.search,"");sourceURL=sourceURL.substring(0,sourceURL.lastIndexOf("/")+1)+path;return"\n/*# sourceURL="+sourceURL+" */";}
var runtime;console=console;console.__originalAssert=console.assert;console.assert=function(value,message)
{if(value)
return;console.__originalAssert(value,message);}
var ArrayLike;Object.isEmpty=function(obj)
{for(var i in obj)
return false;return true;}
Object.values=function(obj)
{var result=Object.keys(obj);var length=result.length;for(var i=0;i<length;++i)
result[i]=obj[result[i]];return result;}
function mod(m,n)
{return((m%n)+n)%n;}
String.prototype.findAll=function(string)
{var matches=[];var i=this.indexOf(string);while(i!==-1){matches.push(i);i=this.indexOf(string,i+string.length);}
return matches;}
String.prototype.replaceControlCharacters=function()
{return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g,"�");}
String.prototype.isWhitespace=function()
{return/^\s*$/.test(this);}
String.prototype.computeLineEndings=function()
{var endings=this.findAll("\n");endings.push(this.length);return endings;}
String.prototype.escapeCharacters=function(chars)
{var foundChar=false;for(var i=0;i<chars.length;++i){if(this.indexOf(chars.charAt(i))!==-1){foundChar=true;break;}}
if(!foundChar)
return String(this);var result="";for(var i=0;i<this.length;++i){if(chars.indexOf(this.charAt(i))!==-1)
result+="\\";result+=this.charAt(i);}
return result;}
String.regexSpecialCharacters=function()
{return"^[]{}()\\.^$*+?|-,";}
String.prototype.escapeForRegExp=function()
{return this.escapeCharacters(String.regexSpecialCharacters());}
String.prototype.escapeHTML=function()
{return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");}
String.prototype.unescapeHTML=function()
{return this.replace(/</g,"<").replace(/>/g,">").replace(/:/g,":").replace(/"/g,"\"").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");}
String.prototype.collapseWhitespace=function()
{return this.replace(/[\s\xA0]+/g," ");}
String.prototype.trimMiddle=function(maxLength)
{if(this.length<=maxLength)
return String(this);var leftHalf=maxLength>>1;var rightHalf=maxLength-leftHalf-1;return this.substr(0,leftHalf)+"\u2026"+this.substr(this.length-rightHalf,rightHalf);}
String.prototype.trimEnd=function(maxLength)
{if(this.length<=maxLength)
return String(this);return this.substr(0,maxLength-1)+"\u2026";}
String.prototype.trimURL=function(baseURLDomain)
{var result=this.replace(/^(https|http|file):\/\//i,"");if(baseURLDomain){if(result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
result=result.substr(baseURLDomain.length);}
return result;}
String.prototype.toTitleCase=function()
{return this.substring(0,1).toUpperCase()+this.substring(1);}
String.prototype.compareTo=function(other)
{if(this>other)
return 1;if(this<other)
return-1;return 0;}
String.prototype.removeURLFragment=function()
{var fragmentIndex=this.indexOf("#");if(fragmentIndex==-1)
fragmentIndex=this.length;return this.substring(0,fragmentIndex);}
String.hashCode=function(string)
{if(!string)
return 0;var p=((1<<30)*4-5);var z=0x5033d967;var z2=0x59d2f15d;var s=0;var zi=1;for(var i=0;i<string.length;i++){var xi=string.charCodeAt(i)*z2;s=(s+zi*xi)%p;zi=(zi*z)%p;}
s=(s+zi*(p-1))%p;return Math.abs(s|0);}
String.isDigitAt=function(string,index)
{var c=string.charCodeAt(index);return(48<=c&&c<=57);}
String.prototype.toBase64=function()
{function encodeBits(b)
{return b<26?b+65:b<52?b+71:b<62?b-4:b===62?43:b===63?47:65;}
var encoder=new TextEncoder();var data=encoder.encode(this.toString());var n=data.length;var encoded="";if(n===0)
return encoded;var shift;var v=0;for(var i=0;i<n;i++){shift=i%3;v|=data[i]<<(16>>>shift&24);if(shift===2){encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),encodeBits(v&63));v=0;}}
if(shift===0)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),61,61);else if(shift===1)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),61);return encoded;}
String.naturalOrderComparator=function(a,b)
{var chunk=/^\d+|^\D+/;var chunka,chunkb,anum,bnum;while(1){if(a){if(!b)
return 1;}else{if(b)
return-1;else
return 0;}
chunka=a.match(chunk)[0];chunkb=b.match(chunk)[0];anum=!isNaN(chunka);bnum=!isNaN(chunkb);if(anum&&!bnum)
return-1;if(bnum&&!anum)
return 1;if(anum&&bnum){var diff=chunka-chunkb;if(diff)
return diff;if(chunka.length!==chunkb.length){if(!+chunka&&!+chunkb)
return chunka.length-chunkb.length;else
return chunkb.length-chunka.length;}}else if(chunka!==chunkb)
return(chunka<chunkb)?-1:1;a=a.substring(chunka.length);b=b.substring(chunkb.length);}}
String.caseInsensetiveComparator=function(a,b)
{a=a.toUpperCase();b=b.toUpperCase();if(a===b)
return 0;return a>b?1:-1;}
Number.constrain=function(num,min,max)
{if(num<min)
num=min;else if(num>max)
num=max;return num;}
Number.gcd=function(a,b)
{if(b===0)
return a;else
return Number.gcd(b,a%b);}
Number.toFixedIfFloating=function(value)
{if(!value||isNaN(value))
return value;var number=Number(value);return number%1?number.toFixed(3):String(number);}
Date.prototype.toISO8601Compact=function()
{function leadZero(x)
{return(x>9?"":"0")+x;}
return this.getFullYear()+
leadZero(this.getMonth()+1)+
leadZero(this.getDate())+"T"+
leadZero(this.getHours())+
leadZero(this.getMinutes())+
leadZero(this.getSeconds());}
Date.prototype.toConsoleTime=function()
{function leadZero2(x)
{return(x>9?"":"0")+x;}
function leadZero3(x)
{return"0".repeat(3-x.toString().length)+x;}
return this.getFullYear()+"-"+
leadZero2(this.getMonth()+1)+"-"+
leadZero2(this.getDate())+" "+
leadZero2(this.getHours())+":"+
leadZero2(this.getMinutes())+":"+
leadZero2(this.getSeconds())+"."+
leadZero3(this.getMilliseconds());}
Object.defineProperty(Array.prototype,"remove",{value:function(value,firstOnly)
{var index=this.indexOf(value);if(index===-1)
return false;if(firstOnly){this.splice(index,1);return true;}
for(var i=index+1,n=this.length;i<n;++i){if(this[i]!==value)
this[index++]=this[i];}
this.length=index;return true;}});Object.defineProperty(Array.prototype,"keySet",{value:function()
{var keys={};for(var i=0;i<this.length;++i)
keys[this[i]]=true;return keys;}});Object.defineProperty(Array.prototype,"pushAll",{value:function(array)
{Array.prototype.push.apply(this,array);}});Object.defineProperty(Array.prototype,"rotate",{value:function(index)
{var result=[];for(var i=index;i<index+this.length;++i)
result.push(this[i%this.length]);return result;}});Object.defineProperty(Array.prototype,"sortNumbers",{value:function()
{function numericComparator(a,b)
{return a-b;}
this.sort(numericComparator);}});Object.defineProperty(Uint32Array.prototype,"sort",{value:Array.prototype.sort});(function(){var partition={value:function(comparator,left,right,pivotIndex)
{function swap(array,i1,i2)
{var temp=array[i1];array[i1]=array[i2];array[i2]=temp;}
var pivotValue=this[pivotIndex];swap(this,right,pivotIndex);var storeIndex=left;for(var i=left;i<right;++i){if(comparator(this[i],pivotValue)<0){swap(this,storeIndex,i);++storeIndex;}}
swap(this,right,storeIndex);return storeIndex;}};Object.defineProperty(Array.prototype,"partition",partition);Object.defineProperty(Uint32Array.prototype,"partition",partition);var sortRange={value:function(comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight)
{function quickSortRange(array,comparator,left,right,sortWindowLeft,sortWindowRight)
{if(right<=left)
return;var pivotIndex=Math.floor(Math.random()*(right-left))+left;var pivotNewIndex=array.partition(comparator,left,right,pivotIndex);if(sortWindowLeft<pivotNewIndex)
quickSortRange(array,comparator,left,pivotNewIndex-1,sortWindowLeft,sortWindowRight);if(pivotNewIndex<sortWindowRight)
quickSortRange(array,comparator,pivotNewIndex+1,right,sortWindowLeft,sortWindowRight);}
if(leftBound===0&&rightBound===(this.length-1)&&sortWindowLeft===0&&sortWindowRight>=rightBound)
this.sort(comparator);else
quickSortRange(this,comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight);return this;}}
Object.defineProperty(Array.prototype,"sortRange",sortRange);Object.defineProperty(Uint32Array.prototype,"sortRange",sortRange);})();Object.defineProperty(Array.prototype,"stableSort",{value:function(comparator)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var indices=new Array(this.length);for(var i=0;i<this.length;++i)
indices[i]=i;var self=this;function indexComparator(a,b)
{var result=comparator(self[a],self[b]);return result?result:a-b;}
indices.sort(indexComparator);for(var i=0;i<this.length;++i){if(indices[i]<0||i===indices[i])
continue;var cyclical=i;var saved=this[i];while(true){var next=indices[cyclical];indices[cyclical]=-1;if(next===i){this[cyclical]=saved;break;}else{this[cyclical]=this[next];cyclical=next;}}}
return this;}});Object.defineProperty(Array.prototype,"qselect",{value:function(k,comparator)
{if(k<0||k>=this.length)
return;if(!comparator)
comparator=function(a,b){return a-b;}
var low=0;var high=this.length-1;for(;;){var pivotPosition=this.partition(comparator,low,high,Math.floor((high+low)/2));if(pivotPosition===k)
return this[k];else if(pivotPosition>k)
high=pivotPosition-1;else
low=pivotPosition+1;}}});Object.defineProperty(Array.prototype,"lowerBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Array.prototype,"upperBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>=0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Uint32Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Uint32Array.prototype,"upperBound",{value:Array.prototype.upperBound});Object.defineProperty(Float64Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Array.prototype,"binaryIndexOf",{value:function(value,comparator)
{var index=this.lowerBound(value,comparator);return index<this.length&&comparator(value,this[index])===0?index:-1;}});Object.defineProperty(Array.prototype,"select",{value:function(field)
{var result=new Array(this.length);for(var i=0;i<this.length;++i)
result[i]=this[i][field];return result;}});Object.defineProperty(Array.prototype,"peekLast",{value:function()
{return this[this.length-1];}});(function(){function mergeOrIntersect(array1,array2,comparator,mergeNotIntersect)
{var result=[];var i=0;var j=0;while(i<array1.length&&j<array2.length){var compareValue=comparator(array1[i],array2[j]);if(mergeNotIntersect||!compareValue)
result.push(compareValue<=0?array1[i]:array2[j]);if(compareValue<=0)
i++;if(compareValue>=0)
j++;}
if(mergeNotIntersect){while(i<array1.length)
result.push(array1[i++]);while(j<array2.length)
result.push(array2[j++]);}
return result;}
Object.defineProperty(Array.prototype,"intersectOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,false);}});Object.defineProperty(Array.prototype,"mergeOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,true);}});})();String.sprintf=function(format,var_arg)
{return String.vsprintf(format,Array.prototype.slice.call(arguments,1));}
String.tokenizeFormatString=function(format,formatters)
{var tokens=[];var substitutionIndex=0;function addStringToken(str)
{if(tokens.length&&tokens[tokens.length-1].type==="string")
tokens[tokens.length-1].value+=str;else
tokens.push({type:"string",value:str});}
function addSpecifierToken(specifier,precision,substitutionIndex)
{tokens.push({type:"specifier",specifier:specifier,precision:precision,substitutionIndex:substitutionIndex});}
var index=0;for(var precentIndex=format.indexOf("%",index);precentIndex!==-1;precentIndex=format.indexOf("%",index)){if(format.length===index)
break;addStringToken(format.substring(index,precentIndex));index=precentIndex+1;if(format[index]==="%"){addStringToken("%");++index;continue;}
if(String.isDigitAt(format,index)){var number=parseInt(format.substring(index),10);while(String.isDigitAt(format,index))
++index;if(number>0&&format[index]==="$"){substitutionIndex=(number-1);++index;}}
var precision=-1;if(format[index]==="."){++index;precision=parseInt(format.substring(index),10);if(isNaN(precision))
precision=0;while(String.isDigitAt(format,index))
++index;}
if(!(format[index]in formatters)){addStringToken(format.substring(precentIndex,index+1));++index;continue;}
addSpecifierToken(format[index],precision,substitutionIndex);++substitutionIndex;++index;}
addStringToken(format.substring(index));return tokens;}
String.standardFormatters={d:function(substitution)
{return!isNaN(substitution)?substitution:0;},f:function(substitution,token)
{if(substitution&&token.precision>-1)
substitution=substitution.toFixed(token.precision);return!isNaN(substitution)?substitution:(token.precision>-1?Number(0).toFixed(token.precision):0);},s:function(substitution)
{return substitution;}}
String.vsprintf=function(format,substitutions)
{return String.format(format,substitutions,String.standardFormatters,"",function(a,b){return a+b;}).formattedResult;}
String.format=function(format,substitutions,formatters,initialValue,append,tokenizedFormat)
{if(!format||!substitutions||!substitutions.length)
return{formattedResult:append(initialValue,format),unusedSubstitutions:substitutions};function prettyFunctionName()
{return"String.format(\""+format+"\", \""+Array.prototype.join.call(substitutions,"\", \"")+"\")";}
function warn(msg)
{console.warn(prettyFunctionName()+": "+msg);}
function error(msg)
{console.error(prettyFunctionName()+": "+msg);}
var result=initialValue;var tokens=tokenizedFormat||String.tokenizeFormatString(format,formatters);var usedSubstitutionIndexes={};for(var i=0;i<tokens.length;++i){var token=tokens[i];if(token.type==="string"){result=append(result,token.value);continue;}
if(token.type!=="specifier"){error("Unknown token type \""+token.type+"\" found.");continue;}
if(token.substitutionIndex>=substitutions.length){error("not enough substitution arguments. Had "+substitutions.length+" but needed "+(token.substitutionIndex+1)+", so substitution was skipped.");result=append(result,"%"+(token.precision>-1?token.precision:"")+token.specifier);continue;}
usedSubstitutionIndexes[token.substitutionIndex]=true;if(!(token.specifier in formatters)){warn("unsupported format character \u201C"+token.specifier+"\u201D. Treating as a string.");result=append(result,substitutions[token.substitutionIndex]);continue;}
result=append(result,formatters[token.specifier](substitutions[token.substitutionIndex],token));}
var unusedSubstitutions=[];for(var i=0;i<substitutions.length;++i){if(i in usedSubstitutionIndexes)
continue;unusedSubstitutions.push(substitutions[i]);}
return{formattedResult:result,unusedSubstitutions:unusedSubstitutions};}
function createSearchRegex(query,caseSensitive,isRegex)
{var regexFlags=caseSensitive?"g":"gi";var regexObject;if(isRegex){try{regexObject=new RegExp(query,regexFlags);}catch(e){}}
if(!regexObject)
regexObject=createPlainTextSearchRegex(query,regexFlags);return regexObject;}
function createPlainTextSearchRegex(query,flags)
{var regexSpecialCharacters=String.regexSpecialCharacters();var regex="";for(var i=0;i<query.length;++i){var c=query.charAt(i);if(regexSpecialCharacters.indexOf(c)!=-1)
regex+="\\";regex+=c;}
return new RegExp(regex,flags||"");}
function countRegexMatches(regex,content)
{var text=content;var result=0;var match;while(text&&(match=regex.exec(text))){if(match[0].length>0)
++result;text=text.substring(match.index+1);}
return result;}
function spacesPadding(spacesCount)
{return"\u00a0".repeat(spacesCount);}
function numberToStringWithSpacesPadding(value,symbolsCount)
{var numberString=value.toString();var paddingLength=Math.max(0,symbolsCount-numberString.length);return spacesPadding(paddingLength)+numberString;}
Set.prototype.valuesArray=function()
{return Array.from(this.values());}
Set.prototype.addAll=function(iterable)
{for(var e of iterable)
this.add(e);}
Set.prototype.containsAll=function(iterable)
{for(var e of iterable){if(!this.has(e))
return false;}
return true;}
Map.prototype.remove=function(key)
{var value=this.get(key);this.delete(key);return value;}
Map.prototype.valuesArray=function()
{return Array.from(this.values());}
Map.prototype.keysArray=function()
{return Array.from(this.keys());}
Map.prototype.inverse=function()
{var result=new Multimap();for(var key of this.keys()){var value=this.get(key);result.set(value,key);}
return result;}
var Multimap=function()
{this._map=new Map();}
Multimap.prototype={set:function(key,value)
{var set=this._map.get(key);if(!set){set=new Set();this._map.set(key,set);}
set.add(value);},get:function(key)
{var result=this._map.get(key);if(!result)
result=new Set();return result;},has:function(key)
{return this._map.has(key);},hasValue:function(key,value)
{var set=this._map.get(key);if(!set)
return false;return set.has(value);},get size()
{return this._map.size;},remove:function(key,value)
{var values=this.get(key);values.delete(value);if(!values.size)
this._map.delete(key);},removeAll:function(key)
{this._map.delete(key);},keysArray:function()
{return this._map.keysArray();},valuesArray:function()
{var result=[];var keys=this.keysArray();for(var i=0;i<keys.length;++i)
result.pushAll(this.get(keys[i]).valuesArray());return result;},clear:function()
{this._map.clear();}}
function loadXHR(url)
{return new Promise(load);function load(successCallback,failureCallback)
{function onReadyStateChanged()
{if(xhr.readyState!==XMLHttpRequest.DONE)
return;if(xhr.status!==200){xhr.onreadystatechange=null;failureCallback(new Error(xhr.status));return;}
xhr.onreadystatechange=null;successCallback(xhr.responseText);}
var xhr=new XMLHttpRequest();xhr.withCredentials=false;xhr.open("GET",url,true);xhr.onreadystatechange=onReadyStateChanged;xhr.send(null);}}
function CallbackBarrier()
{this._pendingIncomingCallbacksCount=0;}
CallbackBarrier.prototype={createCallback:function(userCallback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");++this._pendingIncomingCallbacksCount;return this._incomingCallback.bind(this,userCallback);},callWhenDone:function(callback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.callWhenDone() is called multiple times");this._outgoingCallback=callback;if(!this._pendingIncomingCallbacksCount)
this._outgoingCallback();},donePromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callWhenDone(success);}},_incomingCallback:function(userCallback)
{console.assert(this._pendingIncomingCallbacksCount>0);if(userCallback){var args=Array.prototype.slice.call(arguments,1);userCallback.apply(null,args);}
if(!--this._pendingIncomingCallbacksCount&&this._outgoingCallback)
this._outgoingCallback();}}
function suppressUnused(value)
{}
self.setImmediate=function(callback)
{Promise.resolve().then(callback);return 0;}
Promise.prototype.spread=function(callback)
{return this.then(spreadPromise);function spreadPromise(arg)
{return callback.apply(null,arg);}}
Promise.prototype.catchException=function(defaultValue){return this.catch(function(error){console.error(error);return defaultValue;});}
Map.prototype.diff=function(other,isEqual)
{var leftKeys=this.keysArray();var rightKeys=other.keysArray();leftKeys.sort((a,b)=>a-b);rightKeys.sort((a,b)=>a-b);var removed=[];var added=[];var equal=[];var leftIndex=0;var rightIndex=0;while(leftIndex<leftKeys.length&&rightIndex<rightKeys.length){var leftKey=leftKeys[leftIndex];var rightKey=rightKeys[rightIndex];if(leftKey===rightKey&&isEqual(this.get(leftKey),other.get(rightKey))){equal.push(this.get(leftKey));++leftIndex;++rightIndex;continue;}
if(leftKey<=rightKey){removed.push(this.get(leftKey));++leftIndex;continue;}
added.push(other.get(rightKey));++rightIndex;}
while(leftIndex<leftKeys.length){var leftKey=leftKeys[leftIndex++];removed.push(this.get(leftKey));}
while(rightIndex<rightKeys.length){var rightKey=rightKeys[rightIndex++];added.push(other.get(rightKey));}
return{added:added,removed:removed,equal:equal}};(function(window){window.CodeMirror={};(function(){"use strict";function splitLines(string){return string.split(/\r?\n|\r/);};function StringStream(string){this.pos=this.start=0;this.string=string;this.lineStart=0;}
StringStream.prototype={eol:function(){return this.pos>=this.string.length;},sol:function(){return this.pos==0;},peek:function(){return this.string.charAt(this.pos)||null;},next:function(){if(this.pos<this.string.length)
return this.string.charAt(this.pos++);},eat:function(match){var ch=this.string.charAt(this.pos);if(typeof match=="string")var ok=ch==match;else var ok=ch&&(match.test?match.test(ch):match(ch));if(ok){++this.pos;return ch;}},eatWhile:function(match){var start=this.pos;while(this.eat(match)){}
return this.pos>start;},eatSpace:function(){var start=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>start;},skipToEnd:function(){this.pos=this.string.length;},skipTo:function(ch){var found=this.string.indexOf(ch,this.pos);if(found>-1){this.pos=found;return true;}},backUp:function(n){this.pos-=n;},column:function(){return this.start-this.lineStart;},indentation:function(){return 0;},match:function(pattern,consume,caseInsensitive){if(typeof pattern=="string"){var cased=function(str){return caseInsensitive?str.toLowerCase():str;};var substr=this.string.substr(this.pos,pattern.length);if(cased(substr)==cased(pattern)){if(consume!==false)this.pos+=pattern.length;return true;}}else{var match=this.string.slice(this.pos).match(pattern);if(match&&match.index>0)return null;if(match&&consume!==false)this.pos+=match[0].length;return match;}},current:function(){return this.string.slice(this.start,this.pos);},hideFirstChars:function(n,inner){this.lineStart+=n;try{return inner();}
finally{this.lineStart-=n;}}};CodeMirror.StringStream=StringStream;CodeMirror.startState=function(mode,a1,a2){return mode.startState?mode.startState(a1,a2):true;};var modes=CodeMirror.modes={},mimeModes=CodeMirror.mimeModes={};CodeMirror.defineMode=function(name,mode){if(arguments.length>2)
mode.dependencies=Array.prototype.slice.call(arguments,2);modes[name]=mode;};CodeMirror.defineMIME=function(mime,spec){mimeModes[mime]=spec;};CodeMirror.resolveMode=function(spec){if(typeof spec=="string"&&mimeModes.hasOwnProperty(spec)){spec=mimeModes[spec];}else if(spec&&typeof spec.name=="string"&&mimeModes.hasOwnProperty(spec.name)){spec=mimeModes[spec.name];}
if(typeof spec=="string")return{name:spec};else return spec||{name:"null"};};CodeMirror.getMode=function(options,spec){spec=CodeMirror.resolveMode(spec);var mfactory=modes[spec.name];if(!mfactory)throw new Error("Unknown mode: "+spec);return mfactory(options,spec);};CodeMirror.registerHelper=CodeMirror.registerGlobalHelper=Math.min;CodeMirror.defineMode("null",function(){return{token:function(stream){stream.skipToEnd();}};});CodeMirror.defineMIME("text/plain","null");CodeMirror.runMode=function(string,modespec,callback,options){var mode=CodeMirror.getMode({indentUnit:2},modespec);if(callback.nodeType==1){var tabSize=(options&&options.tabSize)||4;var node=callback,col=0;node.innerHTML="";callback=function(text,style){if(text=="\n"){node.appendChild(document.createElement("br"));col=0;return;}
var content="";for(var pos=0;;){var idx=text.indexOf("\t",pos);if(idx==-1){content+=text.slice(pos);col+=text.length-pos;break;}else{col+=idx-pos;content+=text.slice(pos,idx);var size=tabSize-col%tabSize;col+=size;for(var i=0;i<size;++i)content+=" ";pos=idx+1;}}
if(style){var sp=node.appendChild(document.createElement("span"));sp.className="cm-"+style.replace(/ +/g," cm-");sp.appendChild(document.createTextNode(content));}else{node.appendChild(document.createTextNode(content));}};}
var lines=splitLines(string),state=(options&&options.state)||CodeMirror.startState(mode);for(var i=0,e=lines.length;i<e;++i){if(i)callback("\n");var stream=new CodeMirror.StringStream(lines[i]);if(!stream.string&&mode.blankLine)mode.blankLine(state);while(!stream.eol()){var style=mode.token(stream,state);callback(stream.current(),style,i,stream.start,state);stream.start=stream.pos;}}};})();}(this));(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineMode("css",function(config,parserConfig){var inline=parserConfig.inline
if(!parserConfig.propertyKeywords)parserConfig=CodeMirror.resolveMode("text/css");var indentUnit=config.indentUnit,tokenHooks=parserConfig.tokenHooks,documentTypes=parserConfig.documentTypes||{},mediaTypes=parserConfig.mediaTypes||{},mediaFeatures=parserConfig.mediaFeatures||{},mediaValueKeywords=parserConfig.mediaValueKeywords||{},propertyKeywords=parserConfig.propertyKeywords||{},nonStandardPropertyKeywords=parserConfig.nonStandardPropertyKeywords||{},fontProperties=parserConfig.fontProperties||{},counterDescriptors=parserConfig.counterDescriptors||{},colorKeywords=parserConfig.colorKeywords||{},valueKeywords=parserConfig.valueKeywords||{},allowNested=parserConfig.allowNested,supportsAtComponent=parserConfig.supportsAtComponent===true;var type,override;function ret(style,tp){type=tp;return style;}
function tokenBase(stream,state){var ch=stream.next();if(tokenHooks[ch]){var result=tokenHooks[ch](stream,state);if(result!==false)return result;}
if(ch=="@"){stream.eatWhile(/[\w\\\-]/);return ret("def",stream.current());}else if(ch=="="||(ch=="~"||ch=="|")&&stream.eat("=")){return ret(null,"compare");}else if(ch=="\""||ch=="'"){state.tokenize=tokenString(ch);return state.tokenize(stream,state);}else if(ch=="#"){stream.eatWhile(/[\w\\\-]/);return ret("atom","hash");}else if(ch=="!"){stream.match(/^\s*\w*/);return ret("keyword","important");}else if(/\d/.test(ch)||ch=="."&&stream.eat(/\d/)){stream.eatWhile(/[\w.%]/);return ret("number","unit");}else if(ch==="-"){if(/[\d.]/.test(stream.peek())){stream.eatWhile(/[\w.%]/);return ret("number","unit");}else if(stream.match(/^-[\w\\\-]+/)){stream.eatWhile(/[\w\\\-]/);if(stream.match(/^\s*:/,false))
return ret("variable-2","variable-definition");return ret("variable-2","variable");}else if(stream.match(/^\w+-/)){return ret("meta","meta");}}else if(/[,+>*\/]/.test(ch)){return ret(null,"select-op");}else if(ch=="."&&stream.match(/^-?[_a-z][_a-z0-9-]*/i)){return ret("qualifier","qualifier");}else if(/[:;{}\[\]\(\)]/.test(ch)){return ret(null,ch);}else if((ch=="u"&&stream.match(/rl(-prefix)?\(/))||(ch=="d"&&stream.match("omain("))||(ch=="r"&&stream.match("egexp("))){stream.backUp(1);state.tokenize=tokenParenthesized;return ret("property","word");}else if(/[\w\\\-]/.test(ch)){stream.eatWhile(/[\w\\\-]/);return ret("property","word");}else{return ret(null,null);}}
function tokenString(quote){return function(stream,state){var escaped=false,ch;while((ch=stream.next())!=null){if(ch==quote&&!escaped){if(quote==")")stream.backUp(1);break;}
escaped=!escaped&&ch=="\\";}
if(ch==quote||!escaped&"e!=")")state.tokenize=null;return ret("string","string");};}
function tokenParenthesized(stream,state){stream.next();if(!stream.match(/\s*[\"\')]/,false))
state.tokenize=tokenString(")");else
state.tokenize=null;return ret(null,"(");}
function Context(type,indent,prev){this.type=type;this.indent=indent;this.prev=prev;}
function pushContext(state,stream,type,indent){state.context=new Context(type,stream.indentation()+(indent===false?0:indentUnit),state.context);return type;}
function popContext(state){if(state.context.prev)
state.context=state.context.prev;return state.context.type;}
function pass(type,stream,state){return states[state.context.type](type,stream,state);}
function popAndPass(type,stream,state,n){for(var i=n||1;i>0;i--)
state.context=state.context.prev;return pass(type,stream,state);}
function wordAsValue(stream){var word=stream.current().toLowerCase();if(valueKeywords.hasOwnProperty(word))
override="atom";else if(colorKeywords.hasOwnProperty(word))
override="keyword";else
override="variable";}
var states={};states.top=function(type,stream,state){if(type=="{"){return pushContext(state,stream,"block");}else if(type=="}"&&state.context.prev){return popContext(state);}else if(supportsAtComponent&&/@component/.test(type)){return pushContext(state,stream,"atComponentBlock");}else if(/^@(-moz-)?document$/.test(type)){return pushContext(state,stream,"documentTypes");}else if(/^@(media|supports|(-moz-)?document|import)$/.test(type)){return pushContext(state,stream,"atBlock");}else if(/^@(font-face|counter-style)/.test(type)){state.stateArg=type;return"restricted_atBlock_before";}else if(/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)){return"keyframes";}else if(type&&type.charAt(0)=="@"){return pushContext(state,stream,"at");}else if(type=="hash"){override="builtin";}else if(type=="word"){override="tag";}else if(type=="variable-definition"){return"maybeprop";}else if(type=="interpolation"){return pushContext(state,stream,"interpolation");}else if(type==":"){return"pseudo";}else if(allowNested&&type=="("){return pushContext(state,stream,"parens");}
return state.context.type;};states.block=function(type,stream,state){if(type=="word"){var word=stream.current().toLowerCase();if(propertyKeywords.hasOwnProperty(word)){override="property";return"maybeprop";}else if(nonStandardPropertyKeywords.hasOwnProperty(word)){override="string-2";return"maybeprop";}else if(allowNested){override=stream.match(/^\s*:(?:\s|$)/,false)?"property":"tag";return"block";}else{override+=" error";return"maybeprop";}}else if(type=="meta"){return"block";}else if(!allowNested&&(type=="hash"||type=="qualifier")){override="error";return"block";}else{return states.top(type,stream,state);}};states.maybeprop=function(type,stream,state){if(type==":")return pushContext(state,stream,"prop");return pass(type,stream,state);};states.prop=function(type,stream,state){if(type==";")return popContext(state);if(type=="{"&&allowNested)return pushContext(state,stream,"propBlock");if(type=="}"||type=="{")return popAndPass(type,stream,state);if(type=="(")return pushContext(state,stream,"parens");if(type=="hash"&&!/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())){override+=" error";}else if(type=="word"){wordAsValue(stream);}else if(type=="interpolation"){return pushContext(state,stream,"interpolation");}
return"prop";};states.propBlock=function(type,_stream,state){if(type=="}")return popContext(state);if(type=="word"){override="property";return"maybeprop";}
return state.context.type;};states.parens=function(type,stream,state){if(type=="{"||type=="}")return popAndPass(type,stream,state);if(type==")")return popContext(state);if(type=="(")return pushContext(state,stream,"parens");if(type=="interpolation")return pushContext(state,stream,"interpolation");if(type=="word")wordAsValue(stream);return"parens";};states.pseudo=function(type,stream,state){if(type=="word"){override="variable-3";return state.context.type;}
return pass(type,stream,state);};states.documentTypes=function(type,stream,state){if(type=="word"&&documentTypes.hasOwnProperty(stream.current())){override="tag";return state.context.type;}else{return states.atBlock(type,stream,state);}};states.atBlock=function(type,stream,state){if(type=="(")return pushContext(state,stream,"atBlock_parens");if(type=="}"||type==";")return popAndPass(type,stream,state);if(type=="{")return popContext(state)&&pushContext(state,stream,allowNested?"block":"top");if(type=="interpolation")return pushContext(state,stream,"interpolation");if(type=="word"){var word=stream.current().toLowerCase();if(word=="only"||word=="not"||word=="and"||word=="or")
override="keyword";else if(mediaTypes.hasOwnProperty(word))
override="attribute";else if(mediaFeatures.hasOwnProperty(word))
override="property";else if(mediaValueKeywords.hasOwnProperty(word))
override="keyword";else if(propertyKeywords.hasOwnProperty(word))
override="property";else if(nonStandardPropertyKeywords.hasOwnProperty(word))
override="string-2";else if(valueKeywords.hasOwnProperty(word))
override="atom";else if(colorKeywords.hasOwnProperty(word))
override="keyword";else
override="error";}
return state.context.type;};states.atComponentBlock=function(type,stream,state){if(type=="}")
return popAndPass(type,stream,state);if(type=="{")
return popContext(state)&&pushContext(state,stream,allowNested?"block":"top",false);if(type=="word")
override="error";return state.context.type;};states.atBlock_parens=function(type,stream,state){if(type==")")return popContext(state);if(type=="{"||type=="}")return popAndPass(type,stream,state,2);return states.atBlock(type,stream,state);};states.restricted_atBlock_before=function(type,stream,state){if(type=="{")
return pushContext(state,stream,"restricted_atBlock");if(type=="word"&&state.stateArg=="@counter-style"){override="variable";return"restricted_atBlock_before";}
return pass(type,stream,state);};states.restricted_atBlock=function(type,stream,state){if(type=="}"){state.stateArg=null;return popContext(state);}
if(type=="word"){if((state.stateArg=="@font-face"&&!fontProperties.hasOwnProperty(stream.current().toLowerCase()))||(state.stateArg=="@counter-style"&&!counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override="error";else
override="property";return"maybeprop";}
return"restricted_atBlock";};states.keyframes=function(type,stream,state){if(type=="word"){override="variable";return"keyframes";}
if(type=="{")return pushContext(state,stream,"top");return pass(type,stream,state);};states.at=function(type,stream,state){if(type==";")return popContext(state);if(type=="{"||type=="}")return popAndPass(type,stream,state);if(type=="word")override="tag";else if(type=="hash")override="builtin";return"at";};states.interpolation=function(type,stream,state){if(type=="}")return popContext(state);if(type=="{"||type==";")return popAndPass(type,stream,state);if(type=="word")override="variable";else if(type!="variable"&&type!="("&&type!=")")override="error";return"interpolation";};return{startState:function(base){return{tokenize:null,state:inline?"block":"top",stateArg:null,context:new Context(inline?"block":"top",base||0,null)};},token:function(stream,state){if(!state.tokenize&&stream.eatSpace())return null;var style=(state.tokenize||tokenBase)(stream,state);if(style&&typeof style=="object"){type=style[1];style=style[0];}
override=style;state.state=states[state.state](type,stream,state);return override;},indent:function(state,textAfter){var cx=state.context,ch=textAfter&&textAfter.charAt(0);var indent=cx.indent;if(cx.type=="prop"&&(ch=="}"||ch==")"))cx=cx.prev;if(cx.prev){if(ch=="}"&&(cx.type=="block"||cx.type=="top"||cx.type=="interpolation"||cx.type=="restricted_atBlock")){cx=cx.prev;indent=cx.indent;}else if(ch==")"&&(cx.type=="parens"||cx.type=="atBlock_parens")||ch=="{"&&(cx.type=="at"||cx.type=="atBlock")){indent=Math.max(0,cx.indent-indentUnit);cx=cx.prev;}}
return indent;},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",fold:"brace"};});function keySet(array){var keys={};for(var i=0;i<array.length;++i){keys[array[i]]=true;}
return keys;}
var documentTypes_=["domain","regexp","url","url-prefix"],documentTypes=keySet(documentTypes_);var mediaTypes_=["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"],mediaTypes=keySet(mediaTypes_);var mediaFeatures_=["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","orientation","device-pixel-ratio","min-device-pixel-ratio","max-device-pixel-ratio","pointer","any-pointer","hover","any-hover"],mediaFeatures=keySet(mediaFeatures_);var mediaValueKeywords_=["landscape","portrait","none","coarse","fine","on-demand","hover","interlace","progressive"],mediaValueKeywords=keySet(mediaValueKeywords_);var propertyKeywords_=["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode"],propertyKeywords=keySet(propertyKeywords_);var nonStandardPropertyKeywords_=["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"],nonStandardPropertyKeywords=keySet(nonStandardPropertyKeywords_);var fontProperties_=["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"],fontProperties=keySet(fontProperties_);var counterDescriptors_=["additive-symbols","fallback","negative","pad","prefix","range","speak-as","suffix","symbols","system"],counterDescriptors=keySet(counterDescriptors_);var colorKeywords_=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],colorKeywords=keySet(colorKeywords_);var valueKeywords_=["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","color","color-burn","color-dodge","column","column-reverse","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","darken","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","difference","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","exclusion","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hard-light","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","hue","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","lighten","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","luminosity","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","multiply","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","saturation","scale","scale3d","scaleX","scaleY","scaleZ","screen","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","soft-light","solid","somali","source-atop","source-in","source-out","source-over","space","space-around","space-between","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"],valueKeywords=keySet(valueKeywords_);var allWords=documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_).concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);CodeMirror.registerHelper("hintWords","css",allWords);function tokenCComment(stream,state){var maybeEnd=false,ch;while((ch=stream.next())!=null){if(maybeEnd&&ch=="/"){state.tokenize=null;break;}
maybeEnd=(ch=="*");}
return["comment","comment"];}
CodeMirror.defineMIME("text/css",{documentTypes:documentTypes,mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,fontProperties:fontProperties,counterDescriptors:counterDescriptors,colorKeywords:colorKeywords,valueKeywords:valueKeywords,tokenHooks:{"/":function(stream,state){if(!stream.eat("*"))return false;state.tokenize=tokenCComment;return tokenCComment(stream,state);}},name:"css"});CodeMirror.defineMIME("text/x-scss",{mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,fontProperties:fontProperties,allowNested:true,tokenHooks:{"/":function(stream,state){if(stream.eat("/")){stream.skipToEnd();return["comment","comment"];}else if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}else{return["operator","operator"];}},":":function(stream){if(stream.match(/\s*\{/))
return[null,"{"];return false;},"$":function(stream){stream.match(/^[\w-]+/);if(stream.match(/^\s*:/,false))
return["variable-2","variable-definition"];return["variable-2","variable"];},"#":function(stream){if(!stream.eat("{"))return false;return[null,"interpolation"];}},name:"css",helperType:"scss"});CodeMirror.defineMIME("text/x-less",{mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,fontProperties:fontProperties,allowNested:true,tokenHooks:{"/":function(stream,state){if(stream.eat("/")){stream.skipToEnd();return["comment","comment"];}else if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}else{return["operator","operator"];}},"@":function(stream){if(stream.eat("{"))return[null,"interpolation"];if(stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/,false))return false;stream.eatWhile(/[\w\\\-]/);if(stream.match(/^\s*:/,false))
return["variable-2","variable-definition"];return["variable-2","variable"];},"&":function(){return["atom","atom"];}},name:"css",helperType:"less"});CodeMirror.defineMIME("text/x-gss",{documentTypes:documentTypes,mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,fontProperties:fontProperties,counterDescriptors:counterDescriptors,colorKeywords:colorKeywords,valueKeywords:valueKeywords,supportsAtComponent:true,tokenHooks:{"/":function(stream,state){if(!stream.eat("*"))return false;state.tokenize=tokenCComment;return tokenCComment(stream,state);}},name:"css",helperType:"gss"});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";var htmlConfig={autoSelfClosers:{'area':true,'base':true,'br':true,'col':true,'command':true,'embed':true,'frame':true,'hr':true,'img':true,'input':true,'keygen':true,'link':true,'meta':true,'param':true,'source':true,'track':true,'wbr':true,'menuitem':true},implicitlyClosed:{'dd':true,'li':true,'optgroup':true,'option':true,'p':true,'rp':true,'rt':true,'tbody':true,'td':true,'tfoot':true,'th':true,'tr':true},contextGrabbers:{'dd':{'dd':true,'dt':true},'dt':{'dd':true,'dt':true},'li':{'li':true},'option':{'option':true,'optgroup':true},'optgroup':{'optgroup':true},'p':{'address':true,'article':true,'aside':true,'blockquote':true,'dir':true,'div':true,'dl':true,'fieldset':true,'footer':true,'form':true,'h1':true,'h2':true,'h3':true,'h4':true,'h5':true,'h6':true,'header':true,'hgroup':true,'hr':true,'menu':true,'nav':true,'ol':true,'p':true,'pre':true,'section':true,'table':true,'ul':true},'rp':{'rp':true,'rt':true},'rt':{'rp':true,'rt':true},'tbody':{'tbody':true,'tfoot':true},'td':{'td':true,'th':true},'tfoot':{'tbody':true},'th':{'td':true,'th':true},'thead':{'tbody':true,'tfoot':true},'tr':{'tr':true}},doNotIndent:{"pre":true},allowUnquoted:true,allowMissing:true,caseFold:true}
var xmlConfig={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:false,allowMissing:false,caseFold:false}
CodeMirror.defineMode("xml",function(editorConf,config_){var indentUnit=editorConf.indentUnit
var config={}
var defaults=config_.htmlMode?htmlConfig:xmlConfig
for(var prop in defaults)config[prop]=defaults[prop]
for(var prop in config_)config[prop]=config_[prop]
var type,setStyle;function inText(stream,state){function chain(parser){state.tokenize=parser;return parser(stream,state);}
var ch=stream.next();if(ch=="<"){if(stream.eat("!")){if(stream.eat("[")){if(stream.match("CDATA["))return chain(inBlock("atom","]]>"));else return null;}else if(stream.match("--")){return chain(inBlock("comment","-->"));}else if(stream.match("DOCTYPE",true,true)){stream.eatWhile(/[\w\._\-]/);return chain(doctype(1));}else{return null;}}else if(stream.eat("?")){stream.eatWhile(/[\w\._\-]/);state.tokenize=inBlock("meta","?>");return"meta";}else{type=stream.eat("/")?"closeTag":"openTag";state.tokenize=inTag;return"tag bracket";}}else if(ch=="&"){var ok;if(stream.eat("#")){if(stream.eat("x")){ok=stream.eatWhile(/[a-fA-F\d]/)&&stream.eat(";");}else{ok=stream.eatWhile(/[\d]/)&&stream.eat(";");}}else{ok=stream.eatWhile(/[\w\.\-:]/)&&stream.eat(";");}
return ok?"atom":"error";}else{stream.eatWhile(/[^&<]/);return null;}}
inText.isInText=true;function inTag(stream,state){var ch=stream.next();if(ch==">"||(ch=="/"&&stream.eat(">"))){state.tokenize=inText;type=ch==">"?"endTag":"selfcloseTag";return"tag bracket";}else if(ch=="="){type="equals";return null;}else if(ch=="<"){state.tokenize=inText;state.state=baseState;state.tagName=state.tagStart=null;var next=state.tokenize(stream,state);return next?next+" tag error":"tag error";}else if(/[\'\"]/.test(ch)){state.tokenize=inAttribute(ch);state.stringStartCol=stream.column();return state.tokenize(stream,state);}else{stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);return"word";}}
function inAttribute(quote){var closure=function(stream,state){while(!stream.eol()){if(stream.next()==quote){state.tokenize=inTag;break;}}
return"string";};closure.isInAttribute=true;return closure;}
function inBlock(style,terminator){return function(stream,state){while(!stream.eol()){if(stream.match(terminator)){state.tokenize=inText;break;}
stream.next();}
return style;};}
function doctype(depth){return function(stream,state){var ch;while((ch=stream.next())!=null){if(ch=="<"){state.tokenize=doctype(depth+1);return state.tokenize(stream,state);}else if(ch==">"){if(depth==1){state.tokenize=inText;break;}else{state.tokenize=doctype(depth-1);return state.tokenize(stream,state);}}}
return"meta";};}
function Context(state,tagName,startOfLine){this.prev=state.context;this.tagName=tagName;this.indent=state.indented;this.startOfLine=startOfLine;if(config.doNotIndent.hasOwnProperty(tagName)||(state.context&&state.context.noIndent))
this.noIndent=true;}
function popContext(state){if(state.context)state.context=state.context.prev;}
function maybePopContext(state,nextTagName){var parentTagName;while(true){if(!state.context){return;}
parentTagName=state.context.tagName;if(!config.contextGrabbers.hasOwnProperty(parentTagName)||!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)){return;}
popContext(state);}}
function baseState(type,stream,state){if(type=="openTag"){state.tagStart=stream.column();return tagNameState;}else if(type=="closeTag"){return closeTagNameState;}else{return baseState;}}
function tagNameState(type,stream,state){if(type=="word"){state.tagName=stream.current();setStyle="tag";return attrState;}else{setStyle="error";return tagNameState;}}
function closeTagNameState(type,stream,state){if(type=="word"){var tagName=stream.current();if(state.context&&state.context.tagName!=tagName&&config.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);if((state.context&&state.context.tagName==tagName)||config.matchClosing===false){setStyle="tag";return closeState;}else{setStyle="tag error";return closeStateErr;}}else{setStyle="error";return closeStateErr;}}
function closeState(type,_stream,state){if(type!="endTag"){setStyle="error";return closeState;}
popContext(state);return baseState;}
function closeStateErr(type,stream,state){setStyle="error";return closeState(type,stream,state);}
function attrState(type,_stream,state){if(type=="word"){setStyle="attribute";return attrEqState;}else if(type=="endTag"||type=="selfcloseTag"){var tagName=state.tagName,tagStart=state.tagStart;state.tagName=state.tagStart=null;if(type=="selfcloseTag"||config.autoSelfClosers.hasOwnProperty(tagName)){maybePopContext(state,tagName);}else{maybePopContext(state,tagName);state.context=new Context(state,tagName,tagStart==state.indented);}
return baseState;}
setStyle="error";return attrState;}
function attrEqState(type,stream,state){if(type=="equals")return attrValueState;if(!config.allowMissing)setStyle="error";return attrState(type,stream,state);}
function attrValueState(type,stream,state){if(type=="string")return attrContinuedState;if(type=="word"&&config.allowUnquoted){setStyle="string";return attrState;}
setStyle="error";return attrState(type,stream,state);}
function attrContinuedState(type,stream,state){if(type=="string")return attrContinuedState;return attrState(type,stream,state);}
return{startState:function(baseIndent){var state={tokenize:inText,state:baseState,indented:baseIndent||0,tagName:null,tagStart:null,context:null}
if(baseIndent!=null)state.baseIndent=baseIndent
return state},token:function(stream,state){if(!state.tagName&&stream.sol())
state.indented=stream.indentation();if(stream.eatSpace())return null;type=null;var style=state.tokenize(stream,state);if((style||type)&&style!="comment"){setStyle=null;state.state=state.state(type||style,stream,state);if(setStyle)
style=setStyle=="error"?style+" error":setStyle;}
return style;},indent:function(state,textAfter,fullLine){var context=state.context;if(state.tokenize.isInAttribute){if(state.tagStart==state.indented)
return state.stringStartCol+1;else
return state.indented+indentUnit;}
if(context&&context.noIndent)return CodeMirror.Pass;if(state.tokenize!=inTag&&state.tokenize!=inText)
return fullLine?fullLine.match(/^(\s*)/)[0].length:0;if(state.tagName){if(config.multilineTagIndentPastTag!==false)
return state.tagStart+state.tagName.length+2;else
return state.tagStart+indentUnit*(config.multilineTagIndentFactor||1);}
if(config.alignCDATA&&/<!\[CDATA\[/.test(textAfter))return 0;var tagAfter=textAfter&&/^<(\/)?([\w_:\.-]*)/.exec(textAfter);if(tagAfter&&tagAfter[1]){while(context){if(context.tagName==tagAfter[2]){context=context.prev;break;}else if(config.implicitlyClosed.hasOwnProperty(context.tagName)){context=context.prev;}else{break;}}}else if(tagAfter){while(context){var grabbers=config.contextGrabbers[context.tagName];if(grabbers&&grabbers.hasOwnProperty(tagAfter[2]))
context=context.prev;else
break;}}
while(context&&context.prev&&!context.startOfLine)
context=context.prev;if(context)return context.indent+indentUnit;else return state.baseIndent||0;},electricInput:/<\/[\s\w:]+>$/,blockCommentStart:"<!--",blockCommentEnd:"-->",configuration:config.htmlMode?"html":"xml",helperType:config.htmlMode?"html":"xml",skipAttribute:function(state){if(state.state==attrValueState)
state.state=attrState}};});CodeMirror.defineMIME("text/xml","xml");CodeMirror.defineMIME("application/xml","xml");if(!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:true});});;self.WebInspector={};WebInspector.Text=function(value)
{this._value=value;}
WebInspector.Text.prototype={lineEndings:function()
{if(!this._lineEndings)
this._lineEndings=this._value.computeLineEndings();return this._lineEndings;},value:function()
{return this._value;},lineCount:function()
{var lineEndings=this.lineEndings();return lineEndings.length;},offsetFromPosition:function(lineNumber,columNumber)
{return(lineNumber?this.lineEndings()[lineNumber-1]+1:0)+columNumber;},lineAt:function(lineNumber)
{var lineEndings=this.lineEndings();var lineStart=lineNumber>0?lineEndings[lineNumber-1]+1:0;var lineEnd=lineEndings[lineNumber];var lineContent=this._value.substring(lineStart,lineEnd);if(lineContent.length>0&&lineContent.charAt(lineContent.length-1)==="\r")
lineContent=lineContent.substring(0,lineContent.length-1);return lineContent;},toSourceRange:function(range)
{var start=this.offsetFromPosition(range.startLine,range.startColumn);var end=this.offsetFromPosition(range.endLine,range.endColumn);return new WebInspector.SourceRange(start,end-start);},toTextRange:function(sourceRange)
{var cursor=new WebInspector.TextCursor(this.lineEndings());var result=WebInspector.TextRange.createFromLocation(0,0);cursor.resetTo(sourceRange.offset);result.startLine=cursor.lineNumber();result.startColumn=cursor.columnNumber();cursor.advance(sourceRange.offset+sourceRange.length);result.endLine=cursor.lineNumber();result.endColumn=cursor.columnNumber();return result;},replaceRange:function(range,replacement)
{var sourceRange=this.toSourceRange(range);return this._value.substring(0,sourceRange.offset)+replacement+this._value.substring(sourceRange.offset+sourceRange.length);},extract:function(range)
{var sourceRange=this.toSourceRange(range);return this._value.substr(sourceRange.offset,sourceRange.length);}}
WebInspector.TextCursor=function(lineEndings)
{this._lineEndings=lineEndings;this._offset=0;this._lineNumber=0;this._columnNumber=0;}
WebInspector.TextCursor.prototype={advance:function(offset)
{this._offset=offset;while(this._lineNumber<this._lineEndings.length&&this._lineEndings[this._lineNumber]<this._offset)
++this._lineNumber;this._columnNumber=this._lineNumber?this._offset-this._lineEndings[this._lineNumber-1]-1:this._offset;},offset:function()
{return this._offset;},resetTo:function(offset)
{this._offset=offset;this._lineNumber=this._lineEndings.lowerBound(offset);this._columnNumber=this._lineNumber?this._offset-this._lineEndings[this._lineNumber-1]-1:this._offset;},lineNumber:function()
{return this._lineNumber;},columnNumber:function()
{return this._columnNumber;}};WebInspector.TextRange=function(startLine,startColumn,endLine,endColumn)
{this.startLine=startLine;this.startColumn=startColumn;this.endLine=endLine;this.endColumn=endColumn;}
WebInspector.TextRange.createFromLocation=function(line,column)
{return new WebInspector.TextRange(line,column,line,column);}
WebInspector.TextRange.fromObject=function(serializedTextRange)
{return new WebInspector.TextRange(serializedTextRange.startLine,serializedTextRange.startColumn,serializedTextRange.endLine,serializedTextRange.endColumn);}
WebInspector.TextRange.comparator=function(range1,range2)
{return range1.compareTo(range2);}
WebInspector.TextRange.prototype={isEmpty:function()
{return this.startLine===this.endLine&&this.startColumn===this.endColumn;},immediatelyPrecedes:function(range)
{if(!range)
return false;return this.endLine===range.startLine&&this.endColumn===range.startColumn;},immediatelyFollows:function(range)
{if(!range)
return false;return range.immediatelyPrecedes(this);},follows:function(range)
{return(range.endLine===this.startLine&&range.endColumn<=this.startColumn)||range.endLine<this.startLine;},get linesCount()
{return this.endLine-this.startLine;},collapseToEnd:function()
{return new WebInspector.TextRange(this.endLine,this.endColumn,this.endLine,this.endColumn);},collapseToStart:function()
{return new WebInspector.TextRange(this.startLine,this.startColumn,this.startLine,this.startColumn);},normalize:function()
{if(this.startLine>this.endLine||(this.startLine===this.endLine&&this.startColumn>this.endColumn))
return new WebInspector.TextRange(this.endLine,this.endColumn,this.startLine,this.startColumn);else
return this.clone();},clone:function()
{return new WebInspector.TextRange(this.startLine,this.startColumn,this.endLine,this.endColumn);},serializeToObject:function()
{var serializedTextRange={};serializedTextRange.startLine=this.startLine;serializedTextRange.startColumn=this.startColumn;serializedTextRange.endLine=this.endLine;serializedTextRange.endColumn=this.endColumn;return serializedTextRange;},compareTo:function(other)
{if(this.startLine>other.startLine)
return 1;if(this.startLine<other.startLine)
return-1;if(this.startColumn>other.startColumn)
return 1;if(this.startColumn<other.startColumn)
return-1;return 0;},compareToPosition:function(lineNumber,columnNumber)
{if(lineNumber<this.startLine||(lineNumber===this.startLine&&columnNumber<this.startColumn))
return-1;if(lineNumber>this.endLine||(lineNumber===this.endLine&&columnNumber>this.endColumn))
return 1;return 0;},equal:function(other)
{return this.startLine===other.startLine&&this.endLine===other.endLine&&this.startColumn===other.startColumn&&this.endColumn===other.endColumn;},relativeTo:function(line,column)
{var relative=this.clone();if(this.startLine==line)
relative.startColumn-=column;if(this.endLine==line)
relative.endColumn-=column;relative.startLine-=line;relative.endLine-=line;return relative;},rebaseAfterTextEdit:function(originalRange,editedRange)
{console.assert(originalRange.startLine===editedRange.startLine);console.assert(originalRange.startColumn===editedRange.startColumn);var rebase=this.clone();if(!this.follows(originalRange))
return rebase;var lineDelta=editedRange.endLine-originalRange.endLine;var columnDelta=editedRange.endColumn-originalRange.endColumn;rebase.startLine+=lineDelta;rebase.endLine+=lineDelta;if(rebase.startLine===editedRange.endLine)
rebase.startColumn+=columnDelta;if(rebase.endLine===editedRange.endLine)
rebase.endColumn+=columnDelta;return rebase;},toString:function()
{return JSON.stringify(this);},containsLocation:function(lineNumber,columnNumber)
{if(this.startLine===this.endLine)
return this.startLine===lineNumber&&this.startColumn<=columnNumber&&columnNumber<=this.endColumn;if(this.startLine===lineNumber)
return this.startColumn<=columnNumber;if(this.endLine===lineNumber)
return columnNumber<=this.endColumn;return this.startLine<lineNumber&&lineNumber<this.endLine;}}
WebInspector.TextRange.fromEdit=function(oldRange,newText)
{var endLine=oldRange.startLine;var endColumn=oldRange.startColumn+newText.length;var lineEndings=newText.computeLineEndings();if(lineEndings.length>1){endLine=oldRange.startLine+lineEndings.length-1;var len=lineEndings.length;endColumn=lineEndings[len-1]-lineEndings[len-2]-1;}
return new WebInspector.TextRange(oldRange.startLine,oldRange.startColumn,endLine,endColumn);}
WebInspector.SourceRange=function(offset,length)
{this.offset=offset;this.length=length;}
WebInspector.SourceEdit=function(sourceURL,oldRange,newText)
{this.sourceURL=sourceURL;this.oldRange=oldRange;this.newText=newText;}
WebInspector.SourceEdit.prototype={newRange:function()
{return WebInspector.TextRange.fromEdit(this.oldRange,this.newText);},}
WebInspector.SourceEdit.comparator=function(edit1,edit2)
{return WebInspector.TextRange.comparator(edit1.oldRange,edit2.oldRange);};WebInspector.ESTreeWalker=function(beforeVisit,afterVisit)
{this._beforeVisit=beforeVisit;this._afterVisit=afterVisit||new Function();this._walkNulls=false;}
WebInspector.ESTreeWalker.SkipSubtree={};WebInspector.ESTreeWalker.prototype={setWalkNulls:function(value)
{this._walkNulls=value;},walk:function(ast)
{this._innerWalk(ast,null);},_innerWalk:function(node,parent)
{if(!node&&parent&&this._walkNulls){node=({type:"Literal",raw:"null",value:null});}
if(!node)
return;node.parent=parent;if(this._beforeVisit.call(null,node)===WebInspector.ESTreeWalker.SkipSubtree){this._afterVisit.call(null,node);return;}
var walkOrder=WebInspector.ESTreeWalker._walkOrder[node.type];if(!walkOrder){console.error("Walk order not defined for "+node.type);return;}
if(node.type==="TemplateLiteral"){var templateLiteral=(node);var expressionsLength=templateLiteral.expressions.length;for(var i=0;i<expressionsLength;++i){this._innerWalk(templateLiteral.quasis[i],templateLiteral);this._innerWalk(templateLiteral.expressions[i],templateLiteral);}
this._innerWalk(templateLiteral.quasis[expressionsLength],templateLiteral);}else{for(var i=0;i<walkOrder.length;++i){var entity=node[walkOrder[i]];if(Array.isArray(entity))
this._walkArray(entity,node);else
this._innerWalk(entity,node);}}
this._afterVisit.call(null,node);},_walkArray:function(nodeArray,parentNode)
{for(var i=0;i<nodeArray.length;++i)
this._innerWalk(nodeArray[i],parentNode);},}
WebInspector.ESTreeWalker._walkOrder={"ArrayExpression":["elements"],"ArrowFunctionExpression":["params","body"],"AssignmentExpression":["left","right"],"BinaryExpression":["left","right"],"BlockStatement":["body"],"BreakStatement":["label"],"CallExpression":["callee","arguments"],"CatchClause":["param","body"],"ClassBody":["body"],"ClassDeclaration":["id","superClass","body"],"ConditionalExpression":["test","consequent","alternate"],"ContinueStatement":["label"],"DebuggerStatement":[],"DoWhileStatement":["body","test"],"EmptyStatement":[],"ExpressionStatement":["expression"],"ForInStatement":["left","right","body"],"ForOfStatement":["left","right","body"],"ForStatement":["init","test","update","body"],"FunctionDeclaration":["id","params","body"],"FunctionExpression":["id","params","body"],"Identifier":[],"IfStatement":["test","consequent","alternate"],"LabeledStatement":["label","body"],"Literal":[],"LogicalExpression":["left","right"],"MemberExpression":["object","property"],"MethodDefinition":["key","value"],"NewExpression":["callee","arguments"],"ObjectExpression":["properties"],"Program":["body"],"Property":["key","value"],"ReturnStatement":["argument"],"SequenceExpression":["expressions"],"Super":[],"SwitchCase":["test","consequent"],"SwitchStatement":["discriminant","cases"],"TaggedTemplateExpression":["tag","quasi"],"TemplateElement":[],"TemplateLiteral":["quasis","expressions"],"ThisExpression":[],"ThrowStatement":["argument"],"TryStatement":["block","handler","finalizer"],"UnaryExpression":["argument"],"UpdateExpression":["argument"],"VariableDeclaration":["declarations"],"VariableDeclarator":["id","init"],"WhileStatement":["test","body"],"WithStatement":["object","body"],"YieldExpression":["argument"]};WebInspector.createTokenizer=function(mimeType)
{var mode=CodeMirror.getMode({indentUnit:2},mimeType);var state=CodeMirror.startState(mode);function tokenize(line,callback)
{var stream=new CodeMirror.StringStream(line);while(!stream.eol()){var style=mode.token(stream,state);var value=stream.current();if(callback(value,style,stream.start,stream.start+value.length)===WebInspector.AbortTokenization)
return;stream.start=stream.pos;}}
return tokenize;}
WebInspector.AbortTokenization={};self.onmessage=function(event){var method=(event.data.method);var params=(event.data.params);if(!method)
return;switch(method){case"format":WebInspector.format(params.mimeType,params.content,params.indentString);break;case"parseCSS":WebInspector.parseCSS(params.content);break;case"parseSCSS":WebInspector.FormatterWorkerContentParser.parse(params.content,"text/x-scss");break;case"javaScriptOutline":WebInspector.javaScriptOutline(params.content);break;case"javaScriptIdentifiers":WebInspector.javaScriptIdentifiers(params.content);break;case"evaluatableJavaScriptSubstring":WebInspector.evaluatableJavaScriptSubstring(params.content);break;case"relaxedJSONParser":WebInspector.relaxedJSONParser(params.content);break;default:console.error("Unsupport method name: "+method);}};WebInspector.relaxedJSONParser=function(content)
{postMessage(WebInspector.RelaxedJSONParser.parse(content));}
WebInspector.evaluatableJavaScriptSubstring=function(content)
{var tokenizer=acorn.tokenizer(content,{ecmaVersion:6});var result="";try{var token=tokenizer.getToken();while(token.type!==acorn.tokTypes.eof&&WebInspector.AcornTokenizer.punctuator(token))
token=tokenizer.getToken();var startIndex=token.start;var endIndex=token.end;var openBracketsCounter=0;while(token.type!==acorn.tokTypes.eof){var isIdentifier=WebInspector.AcornTokenizer.identifier(token);var isThis=WebInspector.AcornTokenizer.keyword(token,"this");var isString=token.type===acorn.tokTypes.string;if(!isThis&&!isIdentifier&&!isString)
break;endIndex=token.end;token=tokenizer.getToken();while(WebInspector.AcornTokenizer.punctuator(token,".[]")){if(WebInspector.AcornTokenizer.punctuator(token,"["))
openBracketsCounter++;if(WebInspector.AcornTokenizer.punctuator(token,"]")){endIndex=openBracketsCounter>0?token.end:endIndex;openBracketsCounter--;}
token=tokenizer.getToken();}}
result=content.substring(startIndex,endIndex);}catch(e){console.error(e);}
postMessage(result);}
WebInspector.javaScriptIdentifiers=function(content)
{var root=acorn.parse(content,{ranges:false,ecmaVersion:6});var identifiers=[];var walker=new WebInspector.ESTreeWalker(beforeVisit);function isFunction(node)
{return node.type==="FunctionDeclaration"||node.type==="FunctionExpression"||node.type==="ArrowFunctionExpression";}
function beforeVisit(node)
{if(isFunction(node)){if(node.id)
identifiers.push(node.id);return WebInspector.ESTreeWalker.SkipSubtree;}
if(node.type!=="Identifier")
return;if(node.parent&&node.parent.type==="MemberExpression"&&node.parent.property===node&&!node.parent.computed)
return;identifiers.push(node);}
if(!root||root.type!=="Program"||root.body.length!==1||!isFunction(root.body[0])){postMessage([]);return;}
var functionNode=root.body[0];for(var param of functionNode.params)
walker.walk(param);walker.walk(functionNode.body);var reduced=identifiers.map(id=>({name:id.name,offset:id.start}));postMessage(reduced);}
WebInspector.format=function(mimeType,text,indentString)
{indentString=indentString||" ";var result={};var builder=new WebInspector.FormattedContentBuilder(indentString);var lineEndings=text.computeLineEndings();try{switch(mimeType){case"text/html":var formatter=new WebInspector.HTMLFormatter(builder);formatter.format(text,lineEndings);break;case"text/css":var formatter=new WebInspector.CSSFormatter(builder);formatter.format(text,lineEndings,0,text.length);break;case"text/javascript":var formatter=new WebInspector.JavaScriptFormatter(builder);formatter.format(text,lineEndings,0,text.length);break;default:var formatter=new WebInspector.IdentityFormatter(builder);formatter.format(text,lineEndings,0,text.length);}
result.mapping=builder.mapping();result.content=builder.content();}catch(e){console.error(e);result.mapping={original:[0],formatted:[0]};result.content=text;}
postMessage(result);}
WebInspector.FormatterWorkerContentParser=function(){}
WebInspector.FormatterWorkerContentParser.prototype={parse:function(content){}}
WebInspector.FormatterWorkerContentParser.parse=function(content,mimeType)
{var extension=self.runtime.extensions(WebInspector.FormatterWorkerContentParser).find(findExtension);console.assert(extension);extension.instancePromise().then(instance=>instance.parse(content)).catchException(null).then(postMessage);function findExtension(extension)
{return extension.descriptor()["mimeType"]===mimeType;}};(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var pp=_state.Parser.prototype;pp.checkPropClash=function(prop,propHash){if(this.options.ecmaVersion>=6&&(prop.computed||prop.method||prop.shorthand))return;var key=prop.key;var name=undefined;switch(key.type){case"Identifier":name=key.name;break;case"Literal":name=String(key.value);break;default:return;}
var kind=prop.kind;if(this.options.ecmaVersion>=6){if(name==="__proto__"&&kind==="init"){if(propHash.proto)this.raise(key.start,"Redefinition of __proto__ property");propHash.proto=true;}
return;}
name="$"+name;var other=propHash[name];if(other){var isGetSet=kind!=="init";if((this.strict||isGetSet)&&other[kind]||!(isGetSet^other.init))this.raise(key.start,"Redefinition of property");}else{other=propHash[name]={init:false,get:false,set:false};}
other[kind]=true;};pp.parseExpression=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeAssign(noIn,refShorthandDefaultPos);if(this.type===_tokentype.types.comma){var node=this.startNodeAt(startPos,startLoc);node.expressions=[expr];while(this.eat(_tokentype.types.comma))node.expressions.push(this.parseMaybeAssign(noIn,refShorthandDefaultPos));return this.finishNode(node,"SequenceExpression");}
return expr;};pp.parseMaybeAssign=function(noIn,refShorthandDefaultPos,afterLeftParse){if(this.type==_tokentype.types._yield&&this.inGenerator)return this.parseYield();var failOnShorthandAssign=undefined;if(!refShorthandDefaultPos){refShorthandDefaultPos={start:0};failOnShorthandAssign=true;}else{failOnShorthandAssign=false;}
var startPos=this.start,startLoc=this.startLoc;if(this.type==_tokentype.types.parenL||this.type==_tokentype.types.name)this.potentialArrowAt=this.start;var left=this.parseMaybeConditional(noIn,refShorthandDefaultPos);if(afterLeftParse)left=afterLeftParse.call(this,left,startPos,startLoc);if(this.type.isAssign){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.left=this.type===_tokentype.types.eq?this.toAssignable(left):left;refShorthandDefaultPos.start=0;this.checkLVal(left);this.next();node.right=this.parseMaybeAssign(noIn);return this.finishNode(node,"AssignmentExpression");}else if(failOnShorthandAssign&&refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start);}
return left;};pp.parseMaybeConditional=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprOps(noIn,refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;if(this.eat(_tokentype.types.question)){var node=this.startNodeAt(startPos,startLoc);node.test=expr;node.consequent=this.parseMaybeAssign();this.expect(_tokentype.types.colon);node.alternate=this.parseMaybeAssign(noIn);return this.finishNode(node,"ConditionalExpression");}
return expr;};pp.parseExprOps=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeUnary(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseExprOp(expr,startPos,startLoc,-1,noIn);};pp.parseExprOp=function(left,leftStartPos,leftStartLoc,minPrec,noIn){var prec=this.type.binop;if(prec!=null&&(!noIn||this.type!==_tokentype.types._in)){if(prec>minPrec){var node=this.startNodeAt(leftStartPos,leftStartLoc);node.left=left;node.operator=this.value;var op=this.type;this.next();var startPos=this.start,startLoc=this.startLoc;node.right=this.parseExprOp(this.parseMaybeUnary(),startPos,startLoc,prec,noIn);this.finishNode(node,op===_tokentype.types.logicalOR||op===_tokentype.types.logicalAND?"LogicalExpression":"BinaryExpression");return this.parseExprOp(node,leftStartPos,leftStartLoc,minPrec,noIn);}}
return left;};pp.parseMaybeUnary=function(refShorthandDefaultPos){if(this.type.prefix){var node=this.startNode(),update=this.type===_tokentype.types.incDec;node.operator=this.value;node.prefix=true;this.next();node.argument=this.parseMaybeUnary();if(refShorthandDefaultPos&&refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(update)this.checkLVal(node.argument);else if(this.strict&&node.operator==="delete"&&node.argument.type==="Identifier")this.raise(node.start,"Deleting local variable in strict mode");return this.finishNode(node,update?"UpdateExpression":"UnaryExpression");}
var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprSubscripts(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;while(this.type.postfix&&!this.canInsertSemicolon()){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.prefix=false;node.argument=expr;this.checkLVal(expr);this.next();expr=this.finishNode(node,"UpdateExpression");}
return expr;};pp.parseExprSubscripts=function(refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprAtom(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseSubscripts(expr,startPos,startLoc);};pp.parseSubscripts=function(base,startPos,startLoc,noCalls){for(;;){if(this.eat(_tokentype.types.dot)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseIdent(true);node.computed=false;base=this.finishNode(node,"MemberExpression");}else if(this.eat(_tokentype.types.bracketL)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseExpression();node.computed=true;this.expect(_tokentype.types.bracketR);base=this.finishNode(node,"MemberExpression");}else if(!noCalls&&this.eat(_tokentype.types.parenL)){var node=this.startNodeAt(startPos,startLoc);node.callee=base;node.arguments=this.parseExprList(_tokentype.types.parenR,false);base=this.finishNode(node,"CallExpression");}else if(this.type===_tokentype.types.backQuote){var node=this.startNodeAt(startPos,startLoc);node.tag=base;node.quasi=this.parseTemplate();base=this.finishNode(node,"TaggedTemplateExpression");}else{return base;}}};pp.parseExprAtom=function(refShorthandDefaultPos){var node=undefined,canBeArrow=this.potentialArrowAt==this.start;switch(this.type){case _tokentype.types._super:if(!this.inFunction)this.raise(this.start,"'super' outside of function or class");case _tokentype.types._this:var type=this.type===_tokentype.types._this?"ThisExpression":"Super";node=this.startNode();this.next();return this.finishNode(node,type);case _tokentype.types._yield:if(this.inGenerator)this.unexpected();case _tokentype.types.name:var startPos=this.start,startLoc=this.startLoc;var id=this.parseIdent(this.type!==_tokentype.types.name);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(_tokentype.types.arrow))return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id]);return id;case _tokentype.types.regexp:var value=this.value;node=this.parseLiteral(value.value);node.regex={pattern:value.pattern,flags:value.flags};return node;case _tokentype.types.num:case _tokentype.types.string:return this.parseLiteral(this.value);case _tokentype.types._null:case _tokentype.types._true:case _tokentype.types._false:node=this.startNode();node.value=this.type===_tokentype.types._null?null:this.type===_tokentype.types._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case _tokentype.types.parenL:return this.parseParenAndDistinguishExpression(canBeArrow);case _tokentype.types.bracketL:node=this.startNode();this.next();if(this.options.ecmaVersion>=7&&this.type===_tokentype.types._for){return this.parseComprehension(node,false);}
node.elements=this.parseExprList(_tokentype.types.bracketR,true,true,refShorthandDefaultPos);return this.finishNode(node,"ArrayExpression");case _tokentype.types.braceL:return this.parseObj(false,refShorthandDefaultPos);case _tokentype.types._function:node=this.startNode();this.next();return this.parseFunction(node,false);case _tokentype.types._class:return this.parseClass(this.startNode(),false);case _tokentype.types._new:return this.parseNew();case _tokentype.types.backQuote:return this.parseTemplate();default:this.unexpected();}};pp.parseLiteral=function(value){var node=this.startNode();node.value=value;node.raw=this.input.slice(this.start,this.end);this.next();return this.finishNode(node,"Literal");};pp.parseParenExpression=function(){this.expect(_tokentype.types.parenL);var val=this.parseExpression();this.expect(_tokentype.types.parenR);return val;};pp.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val=undefined;if(this.options.ecmaVersion>=6){this.next();if(this.options.ecmaVersion>=7&&this.type===_tokentype.types._for){return this.parseComprehension(this.startNodeAt(startPos,startLoc),true);}
var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true;var refShorthandDefaultPos={start:0},spreadStart=undefined,innerParenStart=undefined;while(this.type!==_tokentype.types.parenR){first?first=false:this.expect(_tokentype.types.comma);if(this.type===_tokentype.types.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRest()));break;}else{if(this.type===_tokentype.types.parenL&&!innerParenStart){innerParenStart=this.start;}
exprList.push(this.parseMaybeAssign(false,refShorthandDefaultPos,this.parseParenItem));}}
var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(_tokentype.types.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(_tokentype.types.arrow)){if(innerParenStart)this.unexpected(innerParenStart);return this.parseParenArrowList(startPos,startLoc,exprList);}
if(!exprList.length)this.unexpected(this.lastTokStart);if(spreadStart)this.unexpected(spreadStart);if(refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc);}else{val=exprList[0];}}else{val=this.parseParenExpression();}
if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression");}else{return val;}};pp.parseParenItem=function(item){return item;};pp.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList);};var empty=[];pp.parseNew=function(){var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(_tokentype.types.dot)){node.meta=meta;node.property=this.parseIdent(true);if(node.property.name!=="target")this.raise(node.property.start,"The only valid meta property for new is new.target");if(!this.inFunction)this.raise(node.start,"new.target can only be used in functions");return this.finishNode(node,"MetaProperty");}
var startPos=this.start,startLoc=this.startLoc;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(this.eat(_tokentype.types.parenL))node.arguments=this.parseExprList(_tokentype.types.parenR,false);else node.arguments=empty;return this.finishNode(node,"NewExpression");};pp.parseTemplateElement=function(){var elem=this.startNode();elem.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,'\n'),cooked:this.value};this.next();elem.tail=this.type===_tokentype.types.backQuote;return this.finishNode(elem,"TemplateElement");};pp.parseTemplate=function(){var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement();node.quasis=[curElt];while(!curElt.tail){this.expect(_tokentype.types.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(_tokentype.types.braceR);node.quasis.push(curElt=this.parseTemplateElement());}
this.next();return this.finishNode(node,"TemplateLiteral");};pp.parseObj=function(isPattern,refShorthandDefaultPos){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var prop=this.startNode(),isGenerator=undefined,startPos=undefined,startLoc=undefined;if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refShorthandDefaultPos){startPos=this.start;startLoc=this.startLoc;}
if(!isPattern)isGenerator=this.eat(_tokentype.types.star);}
this.parsePropertyName(prop);this.parsePropertyValue(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos);this.checkPropClash(prop,propHash);node.properties.push(this.finishNode(prop,"Property"));}
return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression");};pp.parsePropertyValue=function(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos){if(this.eat(_tokentype.types.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refShorthandDefaultPos);prop.kind="init";}else if(this.options.ecmaVersion>=6&&this.type===_tokentype.types.parenL){if(isPattern)this.unexpected();prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator);}else if(this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!=_tokentype.types.comma&&this.type!=_tokentype.types.braceR)){if(isGenerator||isPattern)this.unexpected();prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false);var paramCount=prop.kind==="get"?0:1;if(prop.value.params.length!==paramCount){var start=prop.value.start;if(prop.kind==="get")this.raise(start,"getter should have no params");else this.raise(start,"setter should have exactly one param");}}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){prop.kind="init";if(isPattern){if(this.keywords.test(prop.key.name)||(this.strict?this.reservedWordsStrictBind:this.reservedWords).test(prop.key.name))this.raise(prop.key.start,"Binding "+prop.key.name);prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key);}else if(this.type===_tokentype.types.eq&&refShorthandDefaultPos){if(!refShorthandDefaultPos.start)refShorthandDefaultPos.start=this.start;prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key);}else{prop.value=prop.key;}
prop.shorthand=true;}else this.unexpected();};pp.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(_tokentype.types.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(_tokentype.types.bracketR);return prop.key;}else{prop.computed=false;}}
return prop.key=this.type===_tokentype.types.num||this.type===_tokentype.types.string?this.parseExprAtom():this.parseIdent(true);};pp.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=false;node.expression=false;}};pp.parseMethod=function(isGenerator){var node=this.startNode();this.initFunction(node);this.expect(_tokentype.types.parenL);node.params=this.parseBindingList(_tokentype.types.parenR,false,false);if(this.options.ecmaVersion>=6)node.generator=isGenerator;this.parseFunctionBody(node,false);return this.finishNode(node,"FunctionExpression");};pp.parseArrowExpression=function(node,params){this.initFunction(node);node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true);return this.finishNode(node,"ArrowFunctionExpression");};pp.parseFunctionBody=function(node,isArrowFunction){var isExpression=isArrowFunction&&this.type!==_tokentype.types.braceL;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true;}else{var oldInFunc=this.inFunction,oldInGen=this.inGenerator,oldLabels=this.labels;this.inFunction=true;this.inGenerator=node.generator;this.labels=[];node.body=this.parseBlock(true);node.expression=false;this.inFunction=oldInFunc;this.inGenerator=oldInGen;this.labels=oldLabels;}
if(this.strict||!isExpression&&node.body.body.length&&this.isUseStrict(node.body.body[0])){var oldStrict=this.strict;this.strict=true;if(node.id)this.checkLVal(node.id,true);this.checkParams(node);this.strict=oldStrict;}else if(isArrowFunction){this.checkParams(node);}};pp.checkParams=function(node){var nameHash={};for(var i=0;i<node.params.length;i++){this.checkLVal(node.params[i],true,nameHash);}};pp.parseExprList=function(close,allowTrailingComma,allowEmpty,refShorthandDefaultPos){var elts=[],first=true;while(!this.eat(close)){if(!first){this.expect(_tokentype.types.comma);if(allowTrailingComma&&this.afterTrailingComma(close))break;}else first=false;var elt=undefined;if(allowEmpty&&this.type===_tokentype.types.comma)elt=null;else if(this.type===_tokentype.types.ellipsis)elt=this.parseSpread(refShorthandDefaultPos);else elt=this.parseMaybeAssign(false,refShorthandDefaultPos);elts.push(elt);}
return elts;};pp.parseIdent=function(liberal){var node=this.startNode();if(liberal&&this.options.allowReserved=="never")liberal=false;if(this.type===_tokentype.types.name){if(!liberal&&(this.strict?this.reservedWordsStrict:this.reservedWords).test(this.value)&&(this.options.ecmaVersion>=6||this.input.slice(this.start,this.end).indexOf("\\")==-1))this.raise(this.start,"The keyword '"+this.value+"' is reserved");node.name=this.value;}else if(liberal&&this.type.keyword){node.name=this.type.keyword;}else{this.unexpected();}
this.next();return this.finishNode(node,"Identifier");};pp.parseYield=function(){var node=this.startNode();this.next();if(this.type==_tokentype.types.semi||this.canInsertSemicolon()||this.type!=_tokentype.types.star&&!this.type.startsExpr){node.delegate=false;node.argument=null;}else{node.delegate=this.eat(_tokentype.types.star);node.argument=this.parseMaybeAssign();}
return this.finishNode(node,"YieldExpression");};pp.parseComprehension=function(node,isGenerator){node.blocks=[];while(this.type===_tokentype.types._for){var block=this.startNode();this.next();this.expect(_tokentype.types.parenL);block.left=this.parseBindingAtom();this.checkLVal(block.left,true);this.expectContextual("of");block.right=this.parseExpression();this.expect(_tokentype.types.parenR);node.blocks.push(this.finishNode(block,"ComprehensionBlock"));}
node.filter=this.eat(_tokentype.types._if)?this.parseParenExpression():null;node.body=this.parseExpression();this.expect(isGenerator?_tokentype.types.parenR:_tokentype.types.bracketR);node.generator=isGenerator;return this.finishNode(node,"ComprehensionExpression");};},{"./state":10,"./tokentype":14}],2:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isIdentifierStart=isIdentifierStart;exports.isIdentifierChar=isIdentifierChar;var reservedWords={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"};exports.reservedWords=reservedWords;var ecma5AndLessKeywords="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";var keywords={5:ecma5AndLessKeywords,6:ecma5AndLessKeywords+" let const class extends export import yield super"};exports.keywords=keywords;var nonASCIIidentifierStartChars="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";var nonASCIIidentifierChars="·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";var nonASCIIidentifierStart=new RegExp("["+nonASCIIidentifierStartChars+"]");var nonASCIIidentifier=new RegExp("["+nonASCIIidentifierStartChars+nonASCIIidentifierChars+"]");nonASCIIidentifierStartChars=nonASCIIidentifierChars=null;var astralIdentifierStartCodes=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,99,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,98,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,955,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,38,17,2,24,133,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,32,4,287,47,21,1,2,0,185,46,82,47,21,0,60,42,502,63,32,0,449,56,1288,920,104,110,2962,1070,13266,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,16481,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,1340,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,16355,541];var astralIdentifierCodes=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,16,9,83,11,168,11,6,9,8,2,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,316,19,13,9,214,6,3,8,112,16,16,9,82,12,9,9,535,9,20855,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,4305,6,792618,239];function isInAstralSet(code,set){var pos=0x10000;for(var i=0;i<set.length;i+=2){pos+=set[i];if(pos>code)return false;pos+=set[i+1];if(pos>=code)return true;}}
function isIdentifierStart(code,astral){if(code<65)return code===36;if(code<91)return true;if(code<97)return code===95;if(code<123)return true;if(code<=0xffff)return code>=0xaa&&nonASCIIidentifierStart.test(String.fromCharCode(code));if(astral===false)return false;return isInAstralSet(code,astralIdentifierStartCodes);}
function isIdentifierChar(code,astral){if(code<48)return code===36;if(code<58)return true;if(code<65)return false;if(code<91)return true;if(code<97)return code===95;if(code<123)return true;if(code<=0xffff)return code>=0xaa&&nonASCIIidentifier.test(String.fromCharCode(code));if(astral===false)return false;return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes);}},{}],3:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.parse=parse;exports.parseExpressionAt=parseExpressionAt;exports.tokenizer=tokenizer;var _state=_dereq_("./state");_dereq_("./parseutil");_dereq_("./statement");_dereq_("./lval");_dereq_("./expression");_dereq_("./location");exports.Parser=_state.Parser;exports.plugins=_state.plugins;var _options=_dereq_("./options");exports.defaultOptions=_options.defaultOptions;var _locutil=_dereq_("./locutil");exports.Position=_locutil.Position;exports.SourceLocation=_locutil.SourceLocation;exports.getLineInfo=_locutil.getLineInfo;var _node=_dereq_("./node");exports.Node=_node.Node;var _tokentype=_dereq_("./tokentype");exports.TokenType=_tokentype.TokenType;exports.tokTypes=_tokentype.types;var _tokencontext=_dereq_("./tokencontext");exports.TokContext=_tokencontext.TokContext;exports.tokContexts=_tokencontext.types;var _identifier=_dereq_("./identifier");exports.isIdentifierChar=_identifier.isIdentifierChar;exports.isIdentifierStart=_identifier.isIdentifierStart;var _tokenize=_dereq_("./tokenize");exports.Token=_tokenize.Token;var _whitespace=_dereq_("./whitespace");exports.isNewLine=_whitespace.isNewLine;exports.lineBreak=_whitespace.lineBreak;exports.lineBreakG=_whitespace.lineBreakG;var version="2.4.1";exports.version=version;function parse(input,options){return new _state.Parser(options,input).parse();}
function parseExpressionAt(input,pos,options){var p=new _state.Parser(options,input,pos);p.nextToken();return p.parseExpression();}
function tokenizer(input,options){return new _state.Parser(options,input);}},{"./expression":1,"./identifier":2,"./location":4,"./locutil":5,"./lval":6,"./node":7,"./options":8,"./parseutil":9,"./state":10,"./statement":11,"./tokencontext":12,"./tokenize":13,"./tokentype":14,"./whitespace":16}],4:[function(_dereq_,module,exports){"use strict";var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var pp=_state.Parser.prototype;pp.raise=function(pos,message){var loc=_locutil.getLineInfo(this.input,pos);message+=" ("+loc.line+":"+loc.column+")";var err=new SyntaxError(message);err.pos=pos;err.loc=loc;err.raisedAt=this.pos;throw err;};pp.curPosition=function(){if(this.options.locations){return new _locutil.Position(this.curLine,this.pos-this.lineStart);}};},{"./locutil":5,"./state":10}],5:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.getLineInfo=getLineInfo;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _whitespace=_dereq_("./whitespace");var Position=(function(){function Position(line,col){_classCallCheck(this,Position);this.line=line;this.column=col;}
Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n);};return Position;})();exports.Position=Position;var SourceLocation=function SourceLocation(p,start,end){_classCallCheck(this,SourceLocation);this.start=start;this.end=end;if(p.sourceFile!==null)this.source=p.sourceFile;};exports.SourceLocation=SourceLocation;function getLineInfo(input,offset){for(var line=1,cur=0;;){_whitespace.lineBreakG.lastIndex=cur;var match=_whitespace.lineBreakG.exec(input);if(match&&match.index<offset){++line;cur=match.index+match[0].length;}else{return new Position(line,offset-cur);}}}},{"./whitespace":16}],6:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _util=_dereq_("./util");var pp=_state.Parser.prototype;pp.toAssignable=function(node,isBinding){if(this.options.ecmaVersion>=6&&node){switch(node.type){case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":break;case"ObjectExpression":node.type="ObjectPattern";for(var i=0;i<node.properties.length;i++){var prop=node.properties[i];if(prop.kind!=="init")this.raise(prop.key.start,"Object pattern can't contain getter or setter");this.toAssignable(prop.value,isBinding);}
break;case"ArrayExpression":node.type="ArrayPattern";this.toAssignableList(node.elements,isBinding);break;case"AssignmentExpression":if(node.operator==="="){node.type="AssignmentPattern";delete node.operator;}else{this.raise(node.left.end,"Only '=' operator can be used for specifying default value.");}
break;case"ParenthesizedExpression":node.expression=this.toAssignable(node.expression,isBinding);break;case"MemberExpression":if(!isBinding)break;default:this.raise(node.start,"Assigning to rvalue");}}
return node;};pp.toAssignableList=function(exprList,isBinding){var end=exprList.length;if(end){var last=exprList[end-1];if(last&&last.type=="RestElement"){--end;}else if(last&&last.type=="SpreadElement"){last.type="RestElement";var arg=last.argument;this.toAssignable(arg,isBinding);if(arg.type!=="Identifier"&&arg.type!=="MemberExpression"&&arg.type!=="ArrayPattern")this.unexpected(arg.start);--end;}
if(isBinding&&last.type==="RestElement"&&last.argument.type!=="Identifier")this.unexpected(last.argument.start);}
for(var i=0;i<end;i++){var elt=exprList[i];if(elt)this.toAssignable(elt,isBinding);}
return exprList;};pp.parseSpread=function(refShorthandDefaultPos){var node=this.startNode();this.next();node.argument=this.parseMaybeAssign(refShorthandDefaultPos);return this.finishNode(node,"SpreadElement");};pp.parseRest=function(allowNonIdent){var node=this.startNode();this.next();if(allowNonIdent)node.argument=this.type===_tokentype.types.name?this.parseIdent():this.unexpected();else node.argument=this.type===_tokentype.types.name||this.type===_tokentype.types.bracketL?this.parseBindingAtom():this.unexpected();return this.finishNode(node,"RestElement");};pp.parseBindingAtom=function(){if(this.options.ecmaVersion<6)return this.parseIdent();switch(this.type){case _tokentype.types.name:return this.parseIdent();case _tokentype.types.bracketL:var node=this.startNode();this.next();node.elements=this.parseBindingList(_tokentype.types.bracketR,true,true);return this.finishNode(node,"ArrayPattern");case _tokentype.types.braceL:return this.parseObj(true);default:this.unexpected();}};pp.parseBindingList=function(close,allowEmpty,allowTrailingComma,allowNonIdent){var elts=[],first=true;while(!this.eat(close)){if(first)first=false;else this.expect(_tokentype.types.comma);if(allowEmpty&&this.type===_tokentype.types.comma){elts.push(null);}else if(allowTrailingComma&&this.afterTrailingComma(close)){break;}else if(this.type===_tokentype.types.ellipsis){var rest=this.parseRest(allowNonIdent);this.parseBindingListItem(rest);elts.push(rest);this.expect(close);break;}else{var elem=this.parseMaybeDefault(this.start,this.startLoc);this.parseBindingListItem(elem);elts.push(elem);}}
return elts;};pp.parseBindingListItem=function(param){return param;};pp.parseMaybeDefault=function(startPos,startLoc,left){left=left||this.parseBindingAtom();if(this.options.ecmaVersion<6||!this.eat(_tokentype.types.eq))return left;var node=this.startNodeAt(startPos,startLoc);node.left=left;node.right=this.parseMaybeAssign();return this.finishNode(node,"AssignmentPattern");};pp.checkLVal=function(expr,isBinding,checkClashes){switch(expr.type){case"Identifier":if(this.strict&&this.reservedWordsStrictBind.test(expr.name))this.raise(expr.start,(isBinding?"Binding ":"Assigning to ")+expr.name+" in strict mode");if(checkClashes){if(_util.has(checkClashes,expr.name))this.raise(expr.start,"Argument name clash");checkClashes[expr.name]=true;}
break;case"MemberExpression":if(isBinding)this.raise(expr.start,(isBinding?"Binding":"Assigning to")+" member expression");break;case"ObjectPattern":for(var i=0;i<expr.properties.length;i++){this.checkLVal(expr.properties[i].value,isBinding,checkClashes);}break;case"ArrayPattern":for(var i=0;i<expr.elements.length;i++){var elem=expr.elements[i];if(elem)this.checkLVal(elem,isBinding,checkClashes);}
break;case"AssignmentPattern":this.checkLVal(expr.left,isBinding,checkClashes);break;case"RestElement":this.checkLVal(expr.argument,isBinding,checkClashes);break;case"ParenthesizedExpression":this.checkLVal(expr.expression,isBinding,checkClashes);break;default:this.raise(expr.start,(isBinding?"Binding":"Assigning to")+" rvalue");}};},{"./state":10,"./tokentype":14,"./util":15}],7:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var Node=function Node(parser,pos,loc){_classCallCheck(this,Node);this.type="";this.start=pos;this.end=0;if(parser.options.locations)this.loc=new _locutil.SourceLocation(parser,loc);if(parser.options.directSourceFile)this.sourceFile=parser.options.directSourceFile;if(parser.options.ranges)this.range=[pos,0];};exports.Node=Node;var pp=_state.Parser.prototype;pp.startNode=function(){return new Node(this,this.start,this.startLoc);};pp.startNodeAt=function(pos,loc){return new Node(this,pos,loc);};function finishNodeAt(node,type,pos,loc){node.type=type;node.end=pos;if(this.options.locations)node.loc.end=loc;if(this.options.ranges)node.range[1]=pos;return node;}
pp.finishNode=function(node,type){return finishNodeAt.call(this,node,type,this.lastTokEnd,this.lastTokEndLoc);};pp.finishNodeAt=function(node,type,pos,loc){return finishNodeAt.call(this,node,type,pos,loc);};},{"./locutil":5,"./state":10}],8:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.getOptions=getOptions;var _util=_dereq_("./util");var _locutil=_dereq_("./locutil");var defaultOptions={ecmaVersion:5,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:false,allowImportExportEverywhere:false,allowHashBang:false,locations:false,onToken:null,onComment:null,ranges:false,program:null,sourceFile:null,directSourceFile:null,preserveParens:false,plugins:{}};exports.defaultOptions=defaultOptions;function getOptions(opts){var options={};for(var opt in defaultOptions){options[opt]=opts&&_util.has(opts,opt)?opts[opt]:defaultOptions[opt];}if(options.allowReserved==null)options.allowReserved=options.ecmaVersion>=5;if(_util.isArray(options.onToken)){(function(){var tokens=options.onToken;options.onToken=function(token){return tokens.push(token);};})();}
if(_util.isArray(options.onComment))options.onComment=pushComment(options,options.onComment);return options;}
function pushComment(options,array){return function(block,text,start,end,startLoc,endLoc){var comment={type:block?'Block':'Line',value:text,start:start,end:end};if(options.locations)comment.loc=new _locutil.SourceLocation(this,startLoc,endLoc);if(options.ranges)comment.range=[start,end];array.push(comment);};}},{"./locutil":5,"./util":15}],9:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _whitespace=_dereq_("./whitespace");var pp=_state.Parser.prototype;pp.isUseStrict=function(stmt){return this.options.ecmaVersion>=5&&stmt.type==="ExpressionStatement"&&stmt.expression.type==="Literal"&&stmt.expression.raw.slice(1,-1)==="use strict";};pp.eat=function(type){if(this.type===type){this.next();return true;}else{return false;}};pp.isContextual=function(name){return this.type===_tokentype.types.name&&this.value===name;};pp.eatContextual=function(name){return this.value===name&&this.eat(_tokentype.types.name);};pp.expectContextual=function(name){if(!this.eatContextual(name))this.unexpected();};pp.canInsertSemicolon=function(){return this.type===_tokentype.types.eof||this.type===_tokentype.types.braceR||_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start));};pp.insertSemicolon=function(){if(this.canInsertSemicolon()){if(this.options.onInsertedSemicolon)this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc);return true;}};pp.semicolon=function(){if(!this.eat(_tokentype.types.semi)&&!this.insertSemicolon())this.unexpected();};pp.afterTrailingComma=function(tokType){if(this.type==tokType){if(this.options.onTrailingComma)this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc);this.next();return true;}};pp.expect=function(type){this.eat(type)||this.unexpected();};pp.unexpected=function(pos){this.raise(pos!=null?pos:this.start,"Unexpected token");};},{"./state":10,"./tokentype":14,"./whitespace":16}],10:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _identifier=_dereq_("./identifier");var _tokentype=_dereq_("./tokentype");var _whitespace=_dereq_("./whitespace");var _options=_dereq_("./options");var plugins={};exports.plugins=plugins;function keywordRegexp(words){return new RegExp("^("+words.replace(/ /g,"|")+")$");}
var Parser=(function(){function Parser(options,input,startPos){_classCallCheck(this,Parser);this.options=_options.getOptions(options);this.sourceFile=this.options.sourceFile;this.keywords=keywordRegexp(_identifier.keywords[this.options.ecmaVersion>=6?6:5]);var reserved=this.options.allowReserved?"":_identifier.reservedWords[this.options.ecmaVersion]+(options.sourceType=="module"?" await":"");this.reservedWords=keywordRegexp(reserved);var reservedStrict=(reserved?reserved+" ":"")+_identifier.reservedWords.strict;this.reservedWordsStrict=keywordRegexp(reservedStrict);this.reservedWordsStrictBind=keywordRegexp(reservedStrict+" "+_identifier.reservedWords.strictBind);this.input=String(input);this.containsEsc=false;this.loadPlugins(this.options.plugins);if(startPos){this.pos=startPos;this.lineStart=Math.max(0,this.input.lastIndexOf("\n",startPos));this.curLine=this.input.slice(0,this.lineStart).split(_whitespace.lineBreak).length;}else{this.pos=this.lineStart=0;this.curLine=1;}
this.type=_tokentype.types.eof;this.value=null;this.start=this.end=this.pos;this.startLoc=this.endLoc=this.curPosition();this.lastTokEndLoc=this.lastTokStartLoc=null;this.lastTokStart=this.lastTokEnd=this.pos;this.context=this.initialContext();this.exprAllowed=true;this.strict=this.inModule=this.options.sourceType==="module";this.potentialArrowAt=-1;this.inFunction=this.inGenerator=false;this.labels=[];if(this.pos===0&&this.options.allowHashBang&&this.input.slice(0,2)==='#!')this.skipLineComment(2);}
Parser.prototype.isKeyword=function isKeyword(word){return this.keywords.test(word);};Parser.prototype.isReservedWord=function isReservedWord(word){return this.reservedWords.test(word);};Parser.prototype.extend=function extend(name,f){this[name]=f(this[name]);};Parser.prototype.loadPlugins=function loadPlugins(pluginConfigs){for(var _name in pluginConfigs){var plugin=plugins[_name];if(!plugin)throw new Error("Plugin '"+_name+"' not found");plugin(this,pluginConfigs[_name]);}};Parser.prototype.parse=function parse(){var node=this.options.program||this.startNode();this.nextToken();return this.parseTopLevel(node);};return Parser;})();exports.Parser=Parser;},{"./identifier":2,"./options":8,"./tokentype":14,"./whitespace":16}],11:[function(_dereq_,module,exports){"use strict";var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _whitespace=_dereq_("./whitespace");var pp=_state.Parser.prototype;pp.parseTopLevel=function(node){var first=true;if(!node.body)node.body=[];while(this.type!==_tokentype.types.eof){var stmt=this.parseStatement(true,true);node.body.push(stmt);if(first){if(this.isUseStrict(stmt))this.setStrict(true);first=false;}}
this.next();if(this.options.ecmaVersion>=6){node.sourceType=this.options.sourceType;}
return this.finishNode(node,"Program");};var loopLabel={kind:"loop"},switchLabel={kind:"switch"};pp.parseStatement=function(declaration,topLevel){var starttype=this.type,node=this.startNode();switch(starttype){case _tokentype.types._break:case _tokentype.types._continue:return this.parseBreakContinueStatement(node,starttype.keyword);case _tokentype.types._debugger:return this.parseDebuggerStatement(node);case _tokentype.types._do:return this.parseDoStatement(node);case _tokentype.types._for:return this.parseForStatement(node);case _tokentype.types._function:if(!declaration&&this.options.ecmaVersion>=6)this.unexpected();return this.parseFunctionStatement(node);case _tokentype.types._class:if(!declaration)this.unexpected();return this.parseClass(node,true);case _tokentype.types._if:return this.parseIfStatement(node);case _tokentype.types._return:return this.parseReturnStatement(node);case _tokentype.types._switch:return this.parseSwitchStatement(node);case _tokentype.types._throw:return this.parseThrowStatement(node);case _tokentype.types._try:return this.parseTryStatement(node);case _tokentype.types._let:case _tokentype.types._const:if(!declaration)this.unexpected();case _tokentype.types._var:return this.parseVarStatement(node,starttype);case _tokentype.types._while:return this.parseWhileStatement(node);case _tokentype.types._with:return this.parseWithStatement(node);case _tokentype.types.braceL:return this.parseBlock();case _tokentype.types.semi:return this.parseEmptyStatement(node);case _tokentype.types._export:case _tokentype.types._import:if(!this.options.allowImportExportEverywhere){if(!topLevel)this.raise(this.start,"'import' and 'export' may only appear at the top level");if(!this.inModule)this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'");}
return starttype===_tokentype.types._import?this.parseImport(node):this.parseExport(node);default:var maybeName=this.value,expr=this.parseExpression();if(starttype===_tokentype.types.name&&expr.type==="Identifier"&&this.eat(_tokentype.types.colon))return this.parseLabeledStatement(node,maybeName,expr);else return this.parseExpressionStatement(node,expr);}};pp.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword=="break";this.next();if(this.eat(_tokentype.types.semi)||this.insertSemicolon())node.label=null;else if(this.type!==_tokentype.types.name)this.unexpected();else{node.label=this.parseIdent();this.semicolon();}
for(var i=0;i<this.labels.length;++i){var lab=this.labels[i];if(node.label==null||lab.name===node.label.name){if(lab.kind!=null&&(isBreak||lab.kind==="loop"))break;if(node.label&&isBreak)break;}}
if(i===this.labels.length)this.raise(node.start,"Unsyntactic "+keyword);return this.finishNode(node,isBreak?"BreakStatement":"ContinueStatement");};pp.parseDebuggerStatement=function(node){this.next();this.semicolon();return this.finishNode(node,"DebuggerStatement");};pp.parseDoStatement=function(node){this.next();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();this.expect(_tokentype.types._while);node.test=this.parseParenExpression();if(this.options.ecmaVersion>=6)this.eat(_tokentype.types.semi);else this.semicolon();return this.finishNode(node,"DoWhileStatement");};pp.parseForStatement=function(node){this.next();this.labels.push(loopLabel);this.expect(_tokentype.types.parenL);if(this.type===_tokentype.types.semi)return this.parseFor(node,null);if(this.type===_tokentype.types._var||this.type===_tokentype.types._let||this.type===_tokentype.types._const){var _init=this.startNode(),varKind=this.type;this.next();this.parseVar(_init,true,varKind);this.finishNode(_init,"VariableDeclaration");if((this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&_init.declarations.length===1&&!(varKind!==_tokentype.types._var&&_init.declarations[0].init))return this.parseForIn(node,_init);return this.parseFor(node,_init);}
var refShorthandDefaultPos={start:0};var init=this.parseExpression(true,refShorthandDefaultPos);if(this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of")){this.toAssignable(init);this.checkLVal(init);return this.parseForIn(node,init);}else if(refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start);}
return this.parseFor(node,init);};pp.parseFunctionStatement=function(node){this.next();return this.parseFunction(node,true);};pp.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement(false);node.alternate=this.eat(_tokentype.types._else)?this.parseStatement(false):null;return this.finishNode(node,"IfStatement");};pp.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction)this.raise(this.start,"'return' outside of function");this.next();if(this.eat(_tokentype.types.semi)||this.insertSemicolon())node.argument=null;else{node.argument=this.parseExpression();this.semicolon();}
return this.finishNode(node,"ReturnStatement");};pp.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(_tokentype.types.braceL);this.labels.push(switchLabel);for(var cur,sawDefault=false;this.type!=_tokentype.types.braceR;){if(this.type===_tokentype.types._case||this.type===_tokentype.types._default){var isCase=this.type===_tokentype.types._case;if(cur)this.finishNode(cur,"SwitchCase");node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression();}else{if(sawDefault)this.raise(this.lastTokStart,"Multiple default clauses");sawDefault=true;cur.test=null;}
this.expect(_tokentype.types.colon);}else{if(!cur)this.unexpected();cur.consequent.push(this.parseStatement(true));}}
if(cur)this.finishNode(cur,"SwitchCase");this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement");};pp.parseThrowStatement=function(node){this.next();if(_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))this.raise(this.lastTokEnd,"Illegal newline after throw");node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement");};var empty=[];pp.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===_tokentype.types._catch){var clause=this.startNode();this.next();this.expect(_tokentype.types.parenL);clause.param=this.parseBindingAtom();this.checkLVal(clause.param,true);this.expect(_tokentype.types.parenR);clause.body=this.parseBlock();node.handler=this.finishNode(clause,"CatchClause");}
node.finalizer=this.eat(_tokentype.types._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer)this.raise(node.start,"Missing catch or finally clause");return this.finishNode(node,"TryStatement");};pp.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration");};pp.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"WhileStatement");};pp.parseWithStatement=function(node){if(this.strict)this.raise(this.start,"'with' in strict mode");this.next();node.object=this.parseParenExpression();node.body=this.parseStatement(false);return this.finishNode(node,"WithStatement");};pp.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement");};pp.parseLabeledStatement=function(node,maybeName,expr){for(var i=0;i<this.labels.length;++i){if(this.labels[i].name===maybeName)this.raise(expr.start,"Label '"+maybeName+"' is already declared");}var kind=this.type.isLoop?"loop":this.type===_tokentype.types._switch?"switch":null;for(var i=this.labels.length-1;i>=0;i--){var label=this.labels[i];if(label.statementStart==node.start){label.statementStart=this.start;label.kind=kind;}else break;}
this.labels.push({name:maybeName,kind:kind,statementStart:this.start});node.body=this.parseStatement(true);this.labels.pop();node.label=expr;return this.finishNode(node,"LabeledStatement");};pp.parseExpressionStatement=function(node,expr){node.expression=expr;this.semicolon();return this.finishNode(node,"ExpressionStatement");};pp.parseBlock=function(allowStrict){var node=this.startNode(),first=true,oldStrict=undefined;node.body=[];this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){var stmt=this.parseStatement(true);node.body.push(stmt);if(first&&allowStrict&&this.isUseStrict(stmt)){oldStrict=this.strict;this.setStrict(this.strict=true);}
first=false;}
if(oldStrict===false)this.setStrict(false);return this.finishNode(node,"BlockStatement");};pp.parseFor=function(node,init){node.init=init;this.expect(_tokentype.types.semi);node.test=this.type===_tokentype.types.semi?null:this.parseExpression();this.expect(_tokentype.types.semi);node.update=this.type===_tokentype.types.parenR?null:this.parseExpression();this.expect(_tokentype.types.parenR);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"ForStatement");};pp.parseForIn=function(node,init){var type=this.type===_tokentype.types._in?"ForInStatement":"ForOfStatement";this.next();node.left=init;node.right=this.parseExpression();this.expect(_tokentype.types.parenR);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,type);};pp.parseVar=function(node,isFor,kind){node.declarations=[];node.kind=kind.keyword;for(;;){var decl=this.startNode();this.parseVarId(decl);if(this.eat(_tokentype.types.eq)){decl.init=this.parseMaybeAssign(isFor);}else if(kind===_tokentype.types._const&&!(this.type===_tokentype.types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))){this.unexpected();}else if(decl.id.type!="Identifier"&&!(isFor&&(this.type===_tokentype.types._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value");}else{decl.init=null;}
node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(_tokentype.types.comma))break;}
return node;};pp.parseVarId=function(decl){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,true);};pp.parseFunction=function(node,isStatement,allowExpressionBody){this.initFunction(node);if(this.options.ecmaVersion>=6)node.generator=this.eat(_tokentype.types.star);if(isStatement||this.type===_tokentype.types.name)node.id=this.parseIdent();this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,isStatement?"FunctionDeclaration":"FunctionExpression");};pp.parseFunctionParams=function(node){this.expect(_tokentype.types.parenL);node.params=this.parseBindingList(_tokentype.types.parenR,false,false,true);};pp.parseClass=function(node,isStatement){this.next();this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(this.eat(_tokentype.types.semi))continue;var method=this.startNode();var isGenerator=this.eat(_tokentype.types.star);var isMaybeStatic=this.type===_tokentype.types.name&&this.value==="static";this.parsePropertyName(method);method["static"]=isMaybeStatic&&this.type!==_tokentype.types.parenL;if(method["static"]){if(isGenerator)this.unexpected();isGenerator=this.eat(_tokentype.types.star);this.parsePropertyName(method);}
method.kind="method";var isGetSet=false;if(!method.computed){var key=method.key;if(!isGenerator&&key.type==="Identifier"&&this.type!==_tokentype.types.parenL&&(key.name==="get"||key.name==="set")){isGetSet=true;method.kind=key.name;key=this.parsePropertyName(method);}
if(!method["static"]&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(hadConstructor)this.raise(key.start,"Duplicate constructor in the same class");if(isGetSet)this.raise(key.start,"Constructor can't have get/set modifier");if(isGenerator)this.raise(key.start,"Constructor can't be a generator");method.kind="constructor";hadConstructor=true;}}
this.parseClassMethod(classBody,method,isGenerator);if(isGetSet){var paramCount=method.kind==="get"?0:1;if(method.value.params.length!==paramCount){var start=method.value.start;if(method.kind==="get")this.raise(start,"getter should have no params");else this.raise(start,"setter should have exactly one param");}}}
node.body=this.finishNode(classBody,"ClassBody");return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression");};pp.parseClassMethod=function(classBody,method,isGenerator){method.value=this.parseMethod(isGenerator);classBody.body.push(this.finishNode(method,"MethodDefinition"));};pp.parseClassId=function(node,isStatement){node.id=this.type===_tokentype.types.name?this.parseIdent():isStatement?this.unexpected():null;};pp.parseClassSuper=function(node){node.superClass=this.eat(_tokentype.types._extends)?this.parseExprSubscripts():null;};pp.parseExport=function(node){this.next();if(this.eat(_tokentype.types.star)){this.expectContextual("from");node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();this.semicolon();return this.finishNode(node,"ExportAllDeclaration");}
if(this.eat(_tokentype.types._default)){var expr=this.parseMaybeAssign();var needsSemi=true;if(expr.type=="FunctionExpression"||expr.type=="ClassExpression"){needsSemi=false;if(expr.id){expr.type=expr.type=="FunctionExpression"?"FunctionDeclaration":"ClassDeclaration";}}
node.declaration=expr;if(needsSemi)this.semicolon();return this.finishNode(node,"ExportDefaultDeclaration");}
if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(true);node.specifiers=[];node.source=null;}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers();if(this.eatContextual("from")){node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();}else{for(var i=0;i<node.specifiers.length;i++){if(this.keywords.test(node.specifiers[i].local.name)||this.reservedWords.test(node.specifiers[i].local.name)){this.unexpected(node.specifiers[i].local.start);}}
node.source=null;}
this.semicolon();}
return this.finishNode(node,"ExportNamedDeclaration");};pp.shouldParseExportStatement=function(){return this.type.keyword;};pp.parseExportSpecifiers=function(){var nodes=[],first=true;this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var node=this.startNode();node.local=this.parseIdent(this.type===_tokentype.types._default);node.exported=this.eatContextual("as")?this.parseIdent(true):node.local;nodes.push(this.finishNode(node,"ExportSpecifier"));}
return nodes;};pp.parseImport=function(node){this.next();if(this.type===_tokentype.types.string){node.specifiers=empty;node.source=this.parseExprAtom();}else{node.specifiers=this.parseImportSpecifiers();this.expectContextual("from");node.source=this.type===_tokentype.types.string?this.parseExprAtom():this.unexpected();}
this.semicolon();return this.finishNode(node,"ImportDeclaration");};pp.parseImportSpecifiers=function(){var nodes=[],first=true;if(this.type===_tokentype.types.name){var node=this.startNode();node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportDefaultSpecifier"));if(!this.eat(_tokentype.types.comma))return nodes;}
if(this.type===_tokentype.types.star){var node=this.startNode();this.next();this.expectContextual("as");node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportNamespaceSpecifier"));return nodes;}
this.expect(_tokentype.types.braceL);while(!this.eat(_tokentype.types.braceR)){if(!first){this.expect(_tokentype.types.comma);if(this.afterTrailingComma(_tokentype.types.braceR))break;}else first=false;var node=this.startNode();node.imported=this.parseIdent(true);node.local=this.eatContextual("as")?this.parseIdent():node.imported;this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportSpecifier"));}
return nodes;};},{"./state":10,"./tokentype":14,"./whitespace":16}],12:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _state=_dereq_("./state");var _tokentype=_dereq_("./tokentype");var _whitespace=_dereq_("./whitespace");var TokContext=function TokContext(token,isExpr,preserveSpace,override){_classCallCheck(this,TokContext);this.token=token;this.isExpr=!!isExpr;this.preserveSpace=!!preserveSpace;this.override=override;};exports.TokContext=TokContext;var types={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",true),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.readTmplToken();}),f_expr:new TokContext("function",true)};exports.types=types;var pp=_state.Parser.prototype;pp.initialContext=function(){return[types.b_stat];};pp.braceIsBlock=function(prevType){if(prevType===_tokentype.types.colon){var _parent=this.curContext();if(_parent===types.b_stat||_parent===types.b_expr)return!_parent.isExpr;}
if(prevType===_tokentype.types._return)return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.start));if(prevType===_tokentype.types._else||prevType===_tokentype.types.semi||prevType===_tokentype.types.eof||prevType===_tokentype.types.parenR)return true;if(prevType==_tokentype.types.braceL)return this.curContext()===types.b_stat;return!this.exprAllowed;};pp.updateContext=function(prevType){var update=undefined,type=this.type;if(type.keyword&&prevType==_tokentype.types.dot)this.exprAllowed=false;else if(update=type.updateContext)update.call(this,prevType);else this.exprAllowed=type.beforeExpr;};_tokentype.types.parenR.updateContext=_tokentype.types.braceR.updateContext=function(){if(this.context.length==1){this.exprAllowed=true;return;}
var out=this.context.pop();if(out===types.b_stat&&this.curContext()===types.f_expr){this.context.pop();this.exprAllowed=false;}else if(out===types.b_tmpl){this.exprAllowed=true;}else{this.exprAllowed=!out.isExpr;}};_tokentype.types.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types.b_stat:types.b_expr);this.exprAllowed=true;};_tokentype.types.dollarBraceL.updateContext=function(){this.context.push(types.b_tmpl);this.exprAllowed=true;};_tokentype.types.parenL.updateContext=function(prevType){var statementParens=prevType===_tokentype.types._if||prevType===_tokentype.types._for||prevType===_tokentype.types._with||prevType===_tokentype.types._while;this.context.push(statementParens?types.p_stat:types.p_expr);this.exprAllowed=true;};_tokentype.types.incDec.updateContext=function(){};_tokentype.types._function.updateContext=function(){if(this.curContext()!==types.b_stat)this.context.push(types.f_expr);this.exprAllowed=false;};_tokentype.types.backQuote.updateContext=function(){if(this.curContext()===types.q_tmpl)this.context.pop();else this.context.push(types.q_tmpl);this.exprAllowed=false;};},{"./state":10,"./tokentype":14,"./whitespace":16}],13:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var _identifier=_dereq_("./identifier");var _tokentype=_dereq_("./tokentype");var _state=_dereq_("./state");var _locutil=_dereq_("./locutil");var _whitespace=_dereq_("./whitespace");var Token=function Token(p){_classCallCheck(this,Token);this.type=p.type;this.value=p.value;this.start=p.start;this.end=p.end;if(p.options.locations)this.loc=new _locutil.SourceLocation(p,p.startLoc,p.endLoc);if(p.options.ranges)this.range=[p.start,p.end];};exports.Token=Token;var pp=_state.Parser.prototype;var isRhino=typeof Packages=="object"&&Object.prototype.toString.call(Packages)=="[object JavaPackage]";pp.next=function(){if(this.options.onToken)this.options.onToken(new Token(this));this.lastTokEnd=this.end;this.lastTokStart=this.start;this.lastTokEndLoc=this.endLoc;this.lastTokStartLoc=this.startLoc;this.nextToken();};pp.getToken=function(){this.next();return new Token(this);};if(typeof Symbol!=="undefined")pp[Symbol.iterator]=function(){var self=this;return{next:function next(){var token=self.getToken();return{done:token.type===_tokentype.types.eof,value:token};}};};pp.setStrict=function(strict){this.strict=strict;if(this.type!==_tokentype.types.num&&this.type!==_tokentype.types.string)return;this.pos=this.start;if(this.options.locations){while(this.pos<this.lineStart){this.lineStart=this.input.lastIndexOf("\n",this.lineStart-2)+1;--this.curLine;}}
this.nextToken();};pp.curContext=function(){return this.context[this.context.length-1];};pp.nextToken=function(){var curContext=this.curContext();if(!curContext||!curContext.preserveSpace)this.skipSpace();this.start=this.pos;if(this.options.locations)this.startLoc=this.curPosition();if(this.pos>=this.input.length)return this.finishToken(_tokentype.types.eof);if(curContext.override)return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());};pp.readToken=function(code){if(_identifier.isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92)return this.readWord();return this.getTokenFromCode(code);};pp.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=0xd7ff||code>=0xe000)return code;var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-0x35fdc00;};pp.skipBlockComment=function(){var startLoc=this.options.onComment&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1)this.raise(this.pos-2,"Unterminated comment");this.pos=end+2;if(this.options.locations){_whitespace.lineBreakG.lastIndex=start;var match=undefined;while((match=_whitespace.lineBreakG.exec(this.input))&&match.index<this.pos){++this.curLine;this.lineStart=match.index+match[0].length;}}
if(this.options.onComment)this.options.onComment(true,this.input.slice(start+2,end),start,this.pos,startLoc,this.curPosition());};pp.skipLineComment=function(startSkip){var start=this.pos;var startLoc=this.options.onComment&&this.curPosition();var ch=this.input.charCodeAt(this.pos+=startSkip);while(this.pos<this.input.length&&ch!==10&&ch!==13&&ch!==8232&&ch!==8233){++this.pos;ch=this.input.charCodeAt(this.pos);}
if(this.options.onComment)this.options.onComment(false,this.input.slice(start+startSkip,this.pos),start,this.pos,startLoc,this.curPosition());};pp.skipSpace=function(){loop:while(this.pos<this.input.length){var ch=this.input.charCodeAt(this.pos);switch(ch){case 32:case 160:++this.pos;break;case 13:if(this.input.charCodeAt(this.pos+1)===10){++this.pos;}
case 10:case 8232:case 8233:++this.pos;if(this.options.locations){++this.curLine;this.lineStart=this.pos;}
break;case 47:switch(this.input.charCodeAt(this.pos+1)){case 42:this.skipBlockComment();break;case 47:this.skipLineComment(2);break;default:break loop;}
break;default:if(ch>8&&ch<14||ch>=5760&&_whitespace.nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos;}else{break loop;}}}};pp.finishToken=function(type,val){this.end=this.pos;if(this.options.locations)this.endLoc=this.curPosition();var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType);};pp.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57)return this.readNumber(true);var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(_tokentype.types.ellipsis);}else{++this.pos;return this.finishToken(_tokentype.types.dot);}};pp.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp();}
if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.slash,1);};pp.readToken_mult_modulo=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(code===42?_tokentype.types.star:_tokentype.types.modulo,1);};pp.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code)return this.finishOp(code===124?_tokentype.types.logicalOR:_tokentype.types.logicalAND,2);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(code===124?_tokentype.types.bitwiseOR:_tokentype.types.bitwiseAND,1);};pp.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.bitwiseXOR,1);};pp.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next==45&&this.input.charCodeAt(this.pos+2)==62&&_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd,this.pos))){this.skipLineComment(3);this.skipSpace();return this.nextToken();}
return this.finishOp(_tokentype.types.incDec,2);}
if(next===61)return this.finishOp(_tokentype.types.assign,2);return this.finishOp(_tokentype.types.plusMin,1);};pp.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61)return this.finishOp(_tokentype.types.assign,size+1);return this.finishOp(_tokentype.types.bitShift,size);}
if(next==33&&code==60&&this.input.charCodeAt(this.pos+2)==45&&this.input.charCodeAt(this.pos+3)==45){if(this.inModule)this.unexpected();this.skipLineComment(4);this.skipSpace();return this.nextToken();}
if(next===61)size=this.input.charCodeAt(this.pos+2)===61?3:2;return this.finishOp(_tokentype.types.relational,size);};pp.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(_tokentype.types.equality,this.input.charCodeAt(this.pos+2)===61?3:2);if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(_tokentype.types.arrow);}
return this.finishOp(code===61?_tokentype.types.eq:_tokentype.types.prefix,1);};pp.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(_tokentype.types.parenL);case 41:++this.pos;return this.finishToken(_tokentype.types.parenR);case 59:++this.pos;return this.finishToken(_tokentype.types.semi);case 44:++this.pos;return this.finishToken(_tokentype.types.comma);case 91:++this.pos;return this.finishToken(_tokentype.types.bracketL);case 93:++this.pos;return this.finishToken(_tokentype.types.bracketR);case 123:++this.pos;return this.finishToken(_tokentype.types.braceL);case 125:++this.pos;return this.finishToken(_tokentype.types.braceR);case 58:++this.pos;return this.finishToken(_tokentype.types.colon);case 63:++this.pos;return this.finishToken(_tokentype.types.question);case 96:if(this.options.ecmaVersion<6)break;++this.pos;return this.finishToken(_tokentype.types.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(next===111||next===79)return this.readRadixNumber(8);if(next===98||next===66)return this.readRadixNumber(2);}
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(_tokentype.types.prefix,1);}
this.raise(this.pos,"Unexpected character '"+codePointToString(code)+"'");};pp.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str);};function tryCreateRegexp(src,flags,throwErrorAt,parser){try{return new RegExp(src,flags);}catch(e){if(throwErrorAt!==undefined){if(e instanceof SyntaxError)parser.raise(throwErrorAt,"Error parsing regular expression: "+e.message);throw e;}}}
var regexpUnicodeSupport=!!tryCreateRegexp("","u");pp.readRegexp=function(){var _this=this;var escaped=undefined,inClass=undefined,start=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(start,"Unterminated regular expression");var ch=this.input.charAt(this.pos);if(_whitespace.lineBreak.test(ch))this.raise(start,"Unterminated regular expression");if(!escaped){if(ch==="[")inClass=true;else if(ch==="]"&&inClass)inClass=false;else if(ch==="/"&&!inClass)break;escaped=ch==="\\";}else escaped=false;++this.pos;}
var content=this.input.slice(start,this.pos);++this.pos;var mods=this.readWord1();var tmp=content;if(mods){var validFlags=/^[gmsiy]*$/;if(this.options.ecmaVersion>=6)validFlags=/^[gmsiyu]*$/;if(!validFlags.test(mods))this.raise(start,"Invalid regular expression flag");if(mods.indexOf('u')>=0&&!regexpUnicodeSupport){tmp=tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(_match,code,offset){code=Number("0x"+code);if(code>0x10FFFF)_this.raise(start+offset+3,"Code point out of bounds");return"x";});tmp=tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x");}}
var value=null;if(!isRhino){tryCreateRegexp(tmp,undefined,start,this);value=tryCreateRegexp(content,mods);}
return this.finishToken(_tokentype.types.regexp,{pattern:content,flags:mods,value:value});};pp.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i<e;++i){var code=this.input.charCodeAt(this.pos),val=undefined;if(code>=97)val=code-97+10;else if(code>=65)val=code-65+10;else if(code>=48&&code<=57)val=code-48;else val=Infinity;if(val>=radix)break;++this.pos;total=total*radix+val;}
if(this.pos===start||len!=null&&this.pos-start!==len)return null;return total;};pp.readRadixNumber=function(radix){this.pos+=2;var val=this.readInt(radix);if(val==null)this.raise(this.start+2,"Expected number in radix "+radix);if(_identifier.isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");return this.finishToken(_tokentype.types.num,val);};pp.readNumber=function(startsWithDot){var start=this.pos,isFloat=false,octal=this.input.charCodeAt(this.pos)===48;if(!startsWithDot&&this.readInt(10)===null)this.raise(start,"Invalid number");var next=this.input.charCodeAt(this.pos);if(next===46){++this.pos;this.readInt(10);isFloat=true;next=this.input.charCodeAt(this.pos);}
if(next===69||next===101){next=this.input.charCodeAt(++this.pos);if(next===43||next===45)++this.pos;if(this.readInt(10)===null)this.raise(start,"Invalid number");isFloat=true;}
if(_identifier.isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");var str=this.input.slice(start,this.pos),val=undefined;if(isFloat)val=parseFloat(str);else if(!octal||str.length===1)val=parseInt(str,10);else if(/[89]/.test(str)||this.strict)this.raise(start,"Invalid number");else val=parseInt(str,8);return this.finishToken(_tokentype.types.num,val);};pp.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code=undefined;if(ch===123){if(this.options.ecmaVersion<6)this.unexpected();var codePos=++this.pos;code=this.readHexChar(this.input.indexOf('}',this.pos)-this.pos);++this.pos;if(code>0x10FFFF)this.raise(codePos,"Code point out of bounds");}else{code=this.readHexChar(4);}
return code;};function codePointToString(code){if(code<=0xFFFF)return String.fromCharCode(code);code-=0x10000;return String.fromCharCode((code>>10)+0xD800,(code&1023)+0xDC00);}
pp.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated string constant");var ch=this.input.charCodeAt(this.pos);if(ch===quote)break;if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(false);chunkStart=this.pos;}else{if(_whitespace.isNewLine(ch))this.raise(this.start,"Unterminated string constant");++this.pos;}}
out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(_tokentype.types.string,out);};pp.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated template");var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&this.type===_tokentype.types.template){if(ch===36){this.pos+=2;return this.finishToken(_tokentype.types.dollarBraceL);}else{++this.pos;return this.finishToken(_tokentype.types.backQuote);}}
out+=this.input.slice(chunkStart,this.pos);return this.finishToken(_tokentype.types.template,out);}
if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(true);chunkStart=this.pos;}else if(_whitespace.isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;switch(ch){case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:out+="\n";break;default:out+=String.fromCharCode(ch);break;}
if(this.options.locations){++this.curLine;this.lineStart=this.pos;}
chunkStart=this.pos;}else{++this.pos;}}};pp.readEscapedChar=function(inTemplate){var ch=this.input.charCodeAt(++this.pos);++this.pos;switch(ch){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return codePointToString(this.readCodePoint());case 116:return"\t";case 98:return"\b";case 118:return"\u000b";case 102:return"\f";case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:if(this.options.locations){this.lineStart=this.pos;++this.curLine;}
return"";default:if(ch>=48&&ch<=55){var octalStr=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0];var octal=parseInt(octalStr,8);if(octal>255){octalStr=octalStr.slice(0,-1);octal=parseInt(octalStr,8);}
if(octal>0&&(this.strict||inTemplate)){this.raise(this.pos-2,"Octal literal in strict mode");}
this.pos+=octalStr.length-1;return String.fromCharCode(octal);}
return String.fromCharCode(ch);}};pp.readHexChar=function(len){var codePos=this.pos;var n=this.readInt(16,len);if(n===null)this.raise(codePos,"Bad character escape sequence");return n;};pp.readWord1=function(){this.containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos<this.input.length){var ch=this.fullCharCodeAtPos();if(_identifier.isIdentifierChar(ch,astral)){this.pos+=ch<=0xffff?1:2;}else if(ch===92){this.containsEsc=true;word+=this.input.slice(chunkStart,this.pos);var escStart=this.pos;if(this.input.charCodeAt(++this.pos)!=117)
this.raise(this.pos,"Expecting Unicode escape sequence \\uXXXX");++this.pos;var esc=this.readCodePoint();if(!(first?_identifier.isIdentifierStart:_identifier.isIdentifierChar)(esc,astral))this.raise(escStart,"Invalid Unicode escape");word+=codePointToString(esc);chunkStart=this.pos;}else{break;}
first=false;}
return word+this.input.slice(chunkStart,this.pos);};pp.readWord=function(){var word=this.readWord1();var type=_tokentype.types.name;if((this.options.ecmaVersion>=6||!this.containsEsc)&&this.keywords.test(word))type=_tokentype.keywords[word];return this.finishToken(type,word);};},{"./identifier":2,"./locutil":5,"./state":10,"./tokentype":14,"./whitespace":16}],14:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
var TokenType=function TokenType(label){var conf=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];_classCallCheck(this,TokenType);this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null;};exports.TokenType=TokenType;function binop(name,prec){return new TokenType(name,{beforeExpr:true,binop:prec});}
var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("prefix",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=",6),relational:binop("</>",7),bitShift:binop("<</>>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10)};exports.types=types;var keywords={};exports.keywords=keywords;function kw(name){var options=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];options.keyword=name;keywords[name]=types["_"+name]=new TokenType(name,options);}
kw("break");kw("case",beforeExpr);kw("catch");kw("continue");kw("debugger");kw("default",beforeExpr);kw("do",{isLoop:true,beforeExpr:true});kw("else",beforeExpr);kw("finally");kw("for",{isLoop:true});kw("function",startsExpr);kw("if");kw("return",beforeExpr);kw("switch");kw("throw",beforeExpr);kw("try");kw("var");kw("let");kw("const");kw("while",{isLoop:true});kw("with");kw("new",{beforeExpr:true,startsExpr:true});kw("this",startsExpr);kw("super",startsExpr);kw("class");kw("extends",beforeExpr);kw("export");kw("import");kw("yield",{beforeExpr:true,startsExpr:true});kw("null",startsExpr);kw("true",startsExpr);kw("false",startsExpr);kw("in",{beforeExpr:true,binop:7});kw("instanceof",{beforeExpr:true,binop:7});kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true});kw("void",{beforeExpr:true,prefix:true,startsExpr:true});kw("delete",{beforeExpr:true,prefix:true,startsExpr:true});},{}],15:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isArray=isArray;exports.has=has;function isArray(obj){return Object.prototype.toString.call(obj)==="[object Array]";}
function has(obj,propName){return Object.prototype.hasOwnProperty.call(obj,propName);}},{}],16:[function(_dereq_,module,exports){"use strict";exports.__esModule=true;exports.isNewLine=isNewLine;var lineBreak=/\r\n?|\n|\u2028|\u2029/;exports.lineBreak=lineBreak;var lineBreakG=new RegExp(lineBreak.source,"g");exports.lineBreakG=lineBreakG;function isNewLine(code){return code===10||code===13||code===0x2028||code==0x2029;}
var nonASCIIwhitespace=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;exports.nonASCIIwhitespace=nonASCIIwhitespace;},{}]},{},[3])(3)});;WebInspector.CSSFormatter=function(builder)
{this._builder=builder;}
WebInspector.CSSFormatter.prototype={format:function(text,lineEndings,fromOffset,toOffset)
{this._lineEndings=lineEndings;this._fromOffset=fromOffset;this._toOffset=toOffset;this._lastLine=-1;this._state={};var tokenize=WebInspector.createTokenizer("text/css");var oldEnforce=this._builder.setEnforceSpaceBetweenWords(false);tokenize(text.substring(this._fromOffset,this._toOffset),this._tokenCallback.bind(this));this._builder.setEnforceSpaceBetweenWords(oldEnforce);},_tokenCallback:function(token,type,startPosition)
{startPosition+=this._fromOffset;var startLine=this._lineEndings.lowerBound(startPosition);if(startLine!==this._lastLine)
this._state.eatWhitespace=true;if(/^property/.test(type)&&!this._state.inPropertyValue)
this._state.seenProperty=true;this._lastLine=startLine;var isWhitespace=/^\s+$/.test(token);if(isWhitespace){if(!this._state.eatWhitespace)
this._builder.addSoftSpace();return;}
this._state.eatWhitespace=false;if(token==="\n")
return;if(token!=="}"){if(this._state.afterClosingBrace)
this._builder.addNewLine(true);this._state.afterClosingBrace=false;}
if(token==="}"){if(this._state.inPropertyValue)
this._builder.addNewLine();this._builder.decreaseNestingLevel();this._state.afterClosingBrace=true;this._state.inPropertyValue=false;}else if(token===":"&&!this._state.inPropertyValue&&this._state.seenProperty){this._builder.addToken(token,startPosition);this._builder.addSoftSpace();this._state.eatWhitespace=true;this._state.inPropertyValue=true;this._state.seenProperty=false;return;}else if(token==="{"){this._builder.addSoftSpace();this._builder.addToken(token,startPosition);this._builder.addNewLine();this._builder.increaseNestingLevel();return;}
this._builder.addToken(token,startPosition);if(type==="comment"&&!this._state.inPropertyValue&&!this._state.seenProperty)
this._builder.addNewLine();if(token===";"&&this._state.inPropertyValue){this._state.inPropertyValue=false;this._builder.addNewLine();}else if(token==="}"){this._builder.addNewLine();}}};WebInspector.AcornTokenizer=function(content)
{this._content=content;this._comments=[];this._tokenizer=acorn.tokenizer(this._content,{ecmaVersion:6,onComment:this._comments});this._lineEndings=this._content.computeLineEndings();this._lineNumber=0;this._tokenLineStart=0;this._tokenLineEnd=0;this._nextTokenInternal();}
WebInspector.AcornTokenizer.punctuator=function(token,values)
{return token.type!==acorn.tokTypes.num&&token.type!==acorn.tokTypes.regexp&&token.type!==acorn.tokTypes.string&&token.type!==acorn.tokTypes.name&&!token.type.keyword&&(!values||(token.type.label.length===1&&values.indexOf(token.type.label)!==-1));}
WebInspector.AcornTokenizer.keyword=function(token,keyword)
{return!!token.type.keyword&&token.type!==acorn.tokTypes._true&&token.type!==acorn.tokTypes._false&&(!keyword||token.type.keyword===keyword);}
WebInspector.AcornTokenizer.identifier=function(token,identifier)
{return token.type===acorn.tokTypes.name&&(!identifier||token.value===identifier);}
WebInspector.AcornTokenizer.lineComment=function(token)
{return token.type==="Line";}
WebInspector.AcornTokenizer.blockComment=function(token)
{return token.type==="Block";}
WebInspector.AcornTokenizer.prototype={_nextTokenInternal:function()
{if(this._comments.length)
return this._comments.shift();var token=this._bufferedToken;this._bufferedToken=this._tokenizer.getToken();return token;},_rollLineNumberToPosition:function(position)
{while(this._lineNumber+1<this._lineEndings.length&&position>this._lineEndings[this._lineNumber])
++this._lineNumber;return this._lineNumber;},nextToken:function()
{var token=this._nextTokenInternal();if(token.type===acorn.tokTypes.eof)
return null;this._tokenLineStart=this._rollLineNumberToPosition(token.start);this._tokenLineEnd=this._rollLineNumberToPosition(token.end);this._tokenColumnStart=this._tokenLineStart>0?token.start-this._lineEndings[this._tokenLineStart-1]-1:token.start;return token;},peekToken:function()
{if(this._comments.length)
return this._comments[0];return this._bufferedToken.type!==acorn.tokTypes.eof?this._bufferedToken:null;},tokenLineStart:function()
{return this._tokenLineStart;},tokenLineEnd:function()
{return this._tokenLineEnd;},tokenColumnStart:function()
{return this._tokenColumnStart;}};WebInspector.JavaScriptFormatter=function(builder)
{this._builder=builder;}
WebInspector.JavaScriptFormatter.prototype={format:function(text,lineEndings,fromOffset,toOffset)
{this._fromOffset=fromOffset;this._toOffset=toOffset;this._content=text.substring(this._fromOffset,this._toOffset);this._tokenizer=new WebInspector.AcornTokenizer(this._content);var ast=acorn.parse(this._content,{ranges:false,ecmaVersion:6});var walker=new WebInspector.ESTreeWalker(this._beforeVisit.bind(this),this._afterVisit.bind(this));walker.walk(ast);},_push:function(token,format)
{for(var i=0;i<format.length;++i){if(format[i]==="s")
this._builder.addSoftSpace();else if(format[i]==="S")
this._builder.addHardSpace();else if(format[i]==="n")
this._builder.addNewLine();else if(format[i]===">")
this._builder.increaseNestingLevel();else if(format[i]==="<")
this._builder.decreaseNestingLevel();else if(format[i]==="t")
this._builder.addToken(this._content.substring(token.start,token.end),this._fromOffset+token.start);}},_beforeVisit:function(node)
{if(!node.parent)
return;while(this._tokenizer.peekToken()&&this._tokenizer.peekToken().start<node.start){var token=(this._tokenizer.nextToken());var format=this._formatToken(node.parent,token);this._push(token,format);}},_afterVisit:function(node)
{while(this._tokenizer.peekToken()&&this._tokenizer.peekToken().start<node.end){var token=(this._tokenizer.nextToken());var format=this._formatToken(node,token);this._push(token,format);}
this._push(null,this._finishNode(node));},_inForLoopHeader:function(node)
{var parent=node.parent;if(!parent)
return false;if(parent.type==="ForStatement")
return node===parent.init||node===parent.test||node===parent.update;if(parent.type==="ForInStatement"||parent.type==="ForOfStatement")
return node===parent.left||parent.right;return false;},_formatToken:function(node,token)
{var AT=WebInspector.AcornTokenizer;if(AT.lineComment(token))
return"tn";if(AT.blockComment(token))
return"tn";if(node.type==="ContinueStatement"||node.type==="BreakStatement"){return node.label&&AT.keyword(token)?"ts":"t";}else if(node.type==="Identifier"){return"t";}else if(node.type==="ReturnStatement"){if(AT.punctuator(token,";"))
return"t";return node.argument?"ts":"t";}else if(node.type==="Property"){if(AT.punctuator(token,":"))
return"ts";return"t";}else if(node.type==="ArrayExpression"){if(AT.punctuator(token,","))
return"ts";return"t";}else if(node.type==="LabeledStatement"){if(AT.punctuator(token,":"))
return"ts";}else if(node.type==="LogicalExpression"||node.type==="AssignmentExpression"||node.type==="BinaryExpression"){if(AT.punctuator(token)&&!AT.punctuator(token,"()"))
return"sts";}else if(node.type==="ConditionalExpression"){if(AT.punctuator(token,"?:"))
return"sts";}else if(node.type==="VariableDeclarator"){if(AT.punctuator(token,"="))
return"sts";}else if(node.type==="FunctionDeclaration"){if(AT.punctuator(token,",)"))
return"ts";}else if(node.type==="FunctionExpression"){if(AT.punctuator(token,",)"))
return"ts";if(AT.keyword(token,"function"))
return node.id?"ts":"t";}else if(node.type==="WithStatement"){if(AT.punctuator(token,")"))
return node.body&&node.body.type==="BlockStatement"?"ts":"tn>";}else if(node.type==="SwitchStatement"){if(AT.punctuator(token,"{"))
return"tn>";if(AT.punctuator(token,"}"))
return"n<tn";if(AT.punctuator(token,")"))
return"ts";}else if(node.type==="SwitchCase"){if(AT.keyword(token,"case"))
return"n<ts";if(AT.keyword(token,"default"))
return"n<t";if(AT.punctuator(token,":"))
return"tn>";}else if(node.type==="VariableDeclaration"){if(AT.punctuator(token,",")){var allVariablesInitialized=true;var declarations=(node.declarations);for(var i=0;i<declarations.length;++i)
allVariablesInitialized=allVariablesInitialized&&!!declarations[i].init;return!this._inForLoopHeader(node)&&allVariablesInitialized?"nSSts":"ts";}}else if(node.type==="BlockStatement"){if(AT.punctuator(token,"{"))
return node.body.length?"tn>":"t";if(AT.punctuator(token,"}"))
return node.body.length?"n<t":"t";}else if(node.type==="CatchClause"){if(AT.punctuator(token,")"))
return"ts";}else if(node.type==="ObjectExpression"){if(!node.properties.length)
return"t";if(AT.punctuator(token,"{"))
return"tn>";if(AT.punctuator(token,"}"))
return"n<t";if(AT.punctuator(token,","))
return"tn";}else if(node.type==="IfStatement"){if(AT.punctuator(token,")"))
return node.consequent&&node.consequent.type==="BlockStatement"?"ts":"tn>";if(AT.keyword(token,"else")){var preFormat=node.consequent&&node.consequent.type==="BlockStatement"?"st":"n<t";var postFormat="n>";if(node.alternate&&(node.alternate.type==="BlockStatement"||node.alternate.type==="IfStatement"))
postFormat="s";return preFormat+postFormat;}}else if(node.type==="CallExpression"){if(AT.punctuator(token,","))
return"ts";}else if(node.type==="SequenceExpression"&&AT.punctuator(token,",")){return node.parent&&node.parent.type==="SwitchCase"?"ts":"tn";}else if(node.type==="ForStatement"||node.type==="ForOfStatement"||node.type==="ForInStatement"){if(AT.punctuator(token,";"))
return"ts";if(AT.keyword(token,"in")||AT.identifier(token,"of"))
return"sts";if(AT.punctuator(token,")"))
return node.body&&node.body.type==="BlockStatement"?"ts":"tn>";}else if(node.type==="WhileStatement"){if(AT.punctuator(token,")"))
return node.body&&node.body.type==="BlockStatement"?"ts":"tn>";}else if(node.type==="DoWhileStatement"){var blockBody=node.body&&node.body.type==="BlockStatement";if(AT.keyword(token,"do"))
return blockBody?"ts":"tn>";if(AT.keyword(token,"while"))
return blockBody?"sts":"n<ts";}else if(node.type==="ClassBody"){if(AT.punctuator(token,"{"))
return"stn>";if(AT.punctuator(token,"}"))
return"<ntn";return"t";}else if(node.type==="YieldExpression"){return"t";}else if(node.type==="Super"){return"t";}
return AT.keyword(token)&&!AT.keyword(token,"this")?"ts":"t";},_finishNode:function(node)
{if(node.type==="WithStatement"){if(node.body&&node.body.type!=="BlockStatement")
return"n<";}else if(node.type==="VariableDeclaration"){if(!this._inForLoopHeader(node))
return"n";}else if(node.type==="ForStatement"||node.type==="ForOfStatement"||node.type==="ForInStatement"){if(node.body&&node.body.type!=="BlockStatement")
return"n<";}else if(node.type==="BlockStatement"){if(node.parent&&node.parent.type==="IfStatement"&&node.parent.alternate&&node.parent.consequent===node)
return"";if(node.parent&&node.parent.type==="FunctionExpression"&&node.parent.parent&&node.parent.parent.type==="Property")
return"";if(node.parent&&node.parent.type==="FunctionExpression"&&node.parent.parent&&node.parent.parent.type==="CallExpression")
return"";if(node.parent&&node.parent.type==="DoWhileStatement")
return"";if(node.parent&&node.parent.type==="TryStatement"&&node.parent.block==node)
return"s";if(node.parent&&node.parent.type==="CatchClause"&&node.parent.parent.finalizer)
return"s";return"n";}else if(node.type==="WhileStatement"){if(node.body&&node.body.type!=="BlockStatement")
return"n<";}else if(node.type==="IfStatement"){if(node.alternate){if(node.alternate.type!=="BlockStatement"&&node.alternate.type!=="IfStatement")
return"<";}else if(node.consequent){if(node.consequent.type!=="BlockStatement")
return"<";}}else if(node.type==="BreakStatement"||node.type==="ThrowStatement"||node.type==="ReturnStatement"||node.type==="ExpressionStatement"){return"n";}
return"";}};WebInspector.FormattedContentBuilder=function(indentString)
{this._lastOriginalPosition=0;this._formattedContent=[];this._formattedContentLength=0;this._lastFormattedPosition=0;this._mapping={original:[0],formatted:[0]};this._nestingLevel=0;this._indentString=indentString;this._cachedIndents=new Map();this._newLines=0;this._softSpace=false;this._hardSpaces=0;this._enforceSpaceBetweenWords=true;}
WebInspector.FormattedContentBuilder.prototype={setEnforceSpaceBetweenWords:function(value)
{var oldValue=this._enforceSpaceBetweenWords;this._enforceSpaceBetweenWords=value;return oldValue;},addToken:function(token,offset)
{var last=this._formattedContent.peekLast();if(this._enforceSpaceBetweenWords&&last&&/\w/.test(last[last.length-1])&&/\w/.test(token))
this.addSoftSpace();this._appendFormatting();this._addMappingIfNeeded(offset);this._addText(token);},addSoftSpace:function()
{if(!this._hardSpaces)
this._softSpace=true;},addHardSpace:function()
{this._softSpace=false;++this._hardSpaces;},addNewLine:function(noSquash)
{if(!this._formattedContentLength)
return;if(noSquash)
++this._newLines;else
this._newLines=this._newLines||1;},increaseNestingLevel:function()
{this._nestingLevel+=1;},decreaseNestingLevel:function()
{if(this._nestingLevel>0)
this._nestingLevel-=1;},_appendFormatting:function()
{if(this._newLines){for(var i=0;i<this._newLines;++i)
this._addText("\n");this._addText(this._indent());}else if(this._softSpace){this._addText(" ");}
if(this._hardSpaces){for(var i=0;i<this._hardSpaces;++i)
this._addText(" ");}
this._newLines=0;this._softSpace=false;this._hardSpaces=0;},content:function()
{return this._formattedContent.join("")+(this._newLines?"\n":"");},mapping:function()
{return this._mapping;},_indent:function()
{var cachedValue=this._cachedIndents.get(this._nestingLevel)
if(cachedValue)
return cachedValue;var fullIndent="";for(var i=0;i<this._nestingLevel;++i)
fullIndent+=this._indentString;if(this._nestingLevel<=20)
this._cachedIndents.set(this._nestingLevel,fullIndent);return fullIndent;},_addText:function(text)
{this._formattedContent.push(text);this._formattedContentLength+=text.length;},_addMappingIfNeeded:function(originalPosition)
{if(originalPosition-this._lastOriginalPosition===this._formattedContentLength-this._lastFormattedPosition)
return;this._mapping.original.push(originalPosition);this._lastOriginalPosition=originalPosition;this._mapping.formatted.push(this._formattedContentLength);this._lastFormattedPosition=this._formattedContentLength;}};WebInspector.CSSParserStates={Initial:"Initial",Selector:"Selector",Style:"Style",PropertyName:"PropertyName",PropertyValue:"PropertyValue",AtRule:"AtRule"};WebInspector.parseCSS=function(text)
{WebInspector._innerParseCSS(text,postMessage);}
WebInspector._innerParseCSS=function(text,chunkCallback)
{var chunkSize=100000;var lines=text.split("\n");var rules=[];var processedChunkCharacters=0;var state=WebInspector.CSSParserStates.Initial;var rule;var property;var UndefTokenType={};var disabledRules=[];function disabledRulesCallback(chunk)
{disabledRules=disabledRules.concat(chunk.chunk);}
function processToken(tokenValue,tokenTypes,column,newColumn)
{var tokenType=tokenTypes?tokenTypes.split(" ").keySet():UndefTokenType;switch(state){case WebInspector.CSSParserStates.Initial:if(tokenType["qualifier"]||tokenType["builtin"]||tokenType["tag"]){rule={selectorText:tokenValue,lineNumber:lineNumber,columnNumber:column,properties:[],};state=WebInspector.CSSParserStates.Selector;}else if(tokenType["def"]){rule={atRule:tokenValue,lineNumber:lineNumber,columnNumber:column,};state=WebInspector.CSSParserStates.AtRule;}
break;case WebInspector.CSSParserStates.Selector:if(tokenValue==="{"&&tokenType===UndefTokenType){rule.selectorText=rule.selectorText.trim();rule.styleRange=createRange(lineNumber,newColumn);state=WebInspector.CSSParserStates.Style;}else{rule.selectorText+=tokenValue;}
break;case WebInspector.CSSParserStates.AtRule:if((tokenValue===";"||tokenValue==="{")&&tokenType===UndefTokenType){rule.atRule=rule.atRule.trim();rules.push(rule);state=WebInspector.CSSParserStates.Initial;}else{rule.atRule+=tokenValue;}
break;case WebInspector.CSSParserStates.Style:if(tokenType["meta"]||tokenType["property"]){property={name:tokenValue,value:"",range:createRange(lineNumber,column),nameRange:createRange(lineNumber,column)};state=WebInspector.CSSParserStates.PropertyName;}else if(tokenValue==="}"&&tokenType===UndefTokenType){rule.styleRange.endLine=lineNumber;rule.styleRange.endColumn=column;rules.push(rule);state=WebInspector.CSSParserStates.Initial;}else if(tokenType["comment"]){if(tokenValue.substring(0,2)!=="/*"||tokenValue.substring(tokenValue.length-2)!=="*/")
break;var uncommentedText=tokenValue.substring(2,tokenValue.length-2);var fakeRule="a{\n"+uncommentedText+"}";disabledRules=[];WebInspector._innerParseCSS(fakeRule,disabledRulesCallback);if(disabledRules.length===1&&disabledRules[0].properties.length===1){var disabledProperty=disabledRules[0].properties[0];disabledProperty.disabled=true;disabledProperty.range=createRange(lineNumber,column);disabledProperty.range.endColumn=newColumn;var lineOffset=lineNumber-1;var columnOffset=column+2;disabledProperty.nameRange.startLine+=lineOffset;disabledProperty.nameRange.startColumn+=columnOffset;disabledProperty.nameRange.endLine+=lineOffset;disabledProperty.nameRange.endColumn+=columnOffset;disabledProperty.valueRange.startLine+=lineOffset;disabledProperty.valueRange.startColumn+=columnOffset;disabledProperty.valueRange.endLine+=lineOffset;disabledProperty.valueRange.endColumn+=columnOffset;rule.properties.push(disabledProperty);}}
break;case WebInspector.CSSParserStates.PropertyName:if(tokenValue===":"&&tokenType===UndefTokenType){property.name=property.name;property.nameRange.endLine=lineNumber;property.nameRange.endColumn=column;property.valueRange=createRange(lineNumber,newColumn);state=WebInspector.CSSParserStates.PropertyValue;}else if(tokenType["property"]){property.name+=tokenValue;}
break;case WebInspector.CSSParserStates.PropertyValue:if((tokenValue===";"||tokenValue==="}")&&tokenType===UndefTokenType){property.value=property.value;property.valueRange.endLine=lineNumber;property.valueRange.endColumn=column;property.range.endLine=lineNumber;property.range.endColumn=tokenValue===";"?newColumn:column;rule.properties.push(property);if(tokenValue==="}"){rule.styleRange.endLine=lineNumber;rule.styleRange.endColumn=column;rules.push(rule);state=WebInspector.CSSParserStates.Initial;}else{state=WebInspector.CSSParserStates.Style;}}else if(!tokenType["comment"]){property.value+=tokenValue;}
break;default:console.assert(false,"Unknown CSS parser state.");}
processedChunkCharacters+=newColumn-column;if(processedChunkCharacters>chunkSize){chunkCallback({chunk:rules,isLastChunk:false});rules=[];processedChunkCharacters=0;}}
var tokenizer=WebInspector.createTokenizer("text/css");var lineNumber;for(lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber];tokenizer(line,processToken);processToken("\n",null,line.length,line.length+1);}
chunkCallback({chunk:rules,isLastChunk:true});function createRange(lineNumber,columnNumber)
{return{startLine:lineNumber,startColumn:columnNumber,endLine:lineNumber,endColumn:columnNumber};}};WebInspector.HTMLFormatter=function(builder)
{this._builder=builder;this._jsFormatter=new WebInspector.JavaScriptFormatter(builder);this._cssFormatter=new WebInspector.CSSFormatter(builder);}
WebInspector.HTMLFormatter.SupportedJavaScriptMimeTypes=new Set(["text/javascript","text/ecmascript","application/javascript","application/ecmascript"]);WebInspector.HTMLFormatter.prototype={format:function(text,lineEndings)
{this._text=text;this._lineEndings=lineEndings;this._model=new WebInspector.HTMLModel(text);this._walk(this._model.document());},_formatTokensTill:function(element,offset)
{while(this._model.peekToken()&&this._model.peekToken().startOffset<offset){var token=this._model.nextToken();this._formatToken(element,token);}},_walk:function(element)
{if(element.parent)
this._formatTokensTill(element.parent,element.openTag.startOffset);this._beforeOpenTag(element);this._formatTokensTill(element,element.openTag.endOffset);this._afterOpenTag(element);for(var i=0;i<element.children.length;++i)
this._walk(element.children[i]);this._formatTokensTill(element,element.closeTag.startOffset);this._beforeCloseTag(element);this._formatTokensTill(element,element.closeTag.endOffset);this._afterCloseTag(element);},_beforeOpenTag:function(element)
{if(!element.children.length||element===this._model.document())
return;this._builder.addNewLine();},_afterOpenTag:function(element)
{if(!element.children.length||element===this._model.document())
return;this._builder.increaseNestingLevel();this._builder.addNewLine();},_beforeCloseTag:function(element)
{if(!element.children.length||element===this._model.document())
return;this._builder.decreaseNestingLevel();this._builder.addNewLine();},_afterCloseTag:function(element)
{this._builder.addNewLine();},_formatToken:function(element,token)
{if(token.value.isWhitespace())
return;if(token.type.has("comment")||token.type.has("meta")){this._builder.addNewLine();this._builder.addToken(token.value.trim(),token.startOffset);this._builder.addNewLine();return;}
var isBodyToken=element.openTag.endOffset<=token.startOffset&&token.startOffset<element.closeTag.startOffset;if(isBodyToken&&element.name==="style"){this._builder.addNewLine();this._builder.increaseNestingLevel();this._cssFormatter.format(this._text,this._lineEndings,token.startOffset,token.endOffset);this._builder.decreaseNestingLevel();return;}
if(isBodyToken&&element.name==="script"){this._builder.addNewLine();this._builder.increaseNestingLevel();var mimeType=element.openTag.attributes.has("type")?element.openTag.attributes.get("type").toLowerCase():null;if(!mimeType||WebInspector.HTMLFormatter.SupportedJavaScriptMimeTypes.has(mimeType)){this._jsFormatter.format(this._text,this._lineEndings,token.startOffset,token.endOffset);}else{this._builder.addToken(token.value,token.startOffset);this._builder.addNewLine();}
this._builder.decreaseNestingLevel();return;}
if(!isBodyToken&&token.type.has("attribute"))
this._builder.addSoftSpace();this._builder.addToken(token.value,token.startOffset);}}
WebInspector.HTMLModel=function(text)
{this._state=WebInspector.HTMLModel.ParseState.Initial;this._document=new WebInspector.HTMLModel.Element("document");this._document.openTag=new WebInspector.HTMLModel.Tag("document",0,0,new Map(),true,false);this._document.closeTag=new WebInspector.HTMLModel.Tag("document",text.length,text.length,new Map(),false,false);this._stack=[this._document];this._tokens=[];this._tokenIndex=0;this._build(text);}
WebInspector.HTMLModel.SelfClosingTags=new Set(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]);WebInspector.HTMLModel.AutoClosingTags={"head":new Set(["body"]),"li":new Set(["li"]),"dt":new Set(["dt","dd"]),"dd":new Set(["dt","dd"]),"p":new Set(["address","article","aside","blockquote","div","dl","fieldset","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","nav","ol","p","pre","section","table","ul"]),"rb":new Set(["rb","rt","rtc","rp"]),"rt":new Set(["rb","rt","rtc","rp"]),"rtc":new Set(["rb","rtc","rp"]),"rp":new Set(["rb","rt","rtc","rp"]),"optgroup":new Set(["optgroup"]),"option":new Set(["option","optgroup"]),"colgroup":new Set(["colgroup"]),"thead":new Set(["tbody","tfoot"]),"tbody":new Set(["tbody","tfoot"]),"tfoot":new Set(["tbody"]),"tr":new Set(["tr"]),"td":new Set(["td","th"]),"th":new Set(["td","th"]),};WebInspector.HTMLModel.ParseState={Initial:"Initial",Tag:"Tag",AttributeName:"AttributeName",AttributeValue:"AttributeValue"}
WebInspector.HTMLModel.prototype={_build:function(text)
{var tokenizer=WebInspector.createTokenizer("text/html");var lastOffset=0;var lowerCaseText=text.toLowerCase();while(true){tokenizer(text.substring(lastOffset),processToken.bind(this,lastOffset));if(lastOffset>=text.length)
break;var element=this._stack.peekLast();lastOffset=lowerCaseText.indexOf("</"+element.name,lastOffset);if(lastOffset===-1)
lastOffset=text.length;var tokenStart=element.openTag.endOffset;var tokenEnd=lastOffset;var tokenValue=text.substring(tokenStart,tokenEnd);this._tokens.push(new WebInspector.HTMLModel.Token(tokenValue,new Set(),tokenStart,tokenEnd));}
while(this._stack.length>1){var element=this._stack.peekLast();this._popElement(new WebInspector.HTMLModel.Tag(element.name,text.length,text.length,new Map(),false,false));}
function processToken(baseOffset,tokenValue,type,tokenStart,tokenEnd)
{tokenStart+=baseOffset;tokenEnd+=baseOffset;lastOffset=tokenEnd;var tokenType=type?new Set(type.split(" ")):new Set();var token=new WebInspector.HTMLModel.Token(tokenValue,tokenType,tokenStart,tokenEnd);this._tokens.push(token);this._updateDOM(token);var element=this._stack.peekLast();if(element&&(element.name==="script"||element.name==="style")&&element.openTag.endOffset===lastOffset)
return WebInspector.AbortTokenization;}},_updateDOM:function(token)
{var S=WebInspector.HTMLModel.ParseState;var value=token.value;var type=token.type;switch(this._state){case S.Initial:if(type.has("bracket")&&(value==="<"||value==="</")){this._onStartTag(token);this._state=S.Tag;}
return;case S.Tag:if(type.has("tag")&&!type.has("bracket")){this._tagName=value.trim().toLowerCase();}else if(type.has("attribute")){this._attributeName=value.trim().toLowerCase();this._attributes.set(this._attributeName,"");this._state=S.AttributeName;}else if(type.has("bracket")&&(value===">"||value==="/>")){this._onEndTag(token);this._state=S.Initial;}
return;case S.AttributeName:if(!type.size&&value==="="){this._state=S.AttributeValue;}else if(type.has("bracket")&&(value===">"||value==="/>")){this._onEndTag(token);this._state=S.Initial;}
return;case S.AttributeValue:if(type.has("string")){this._attributes.set(this._attributeName,value);this._state=S.Tag;}else if(type.has("bracket")&&(value===">"||value==="/>")){this._onEndTag(token);this._state=S.Initial;}
return;}},_onStartTag:function(token)
{this._tagName="";this._tagStartOffset=token.startOffset;this._tagEndOffset=null;this._attributes=new Map();this._attributeName="";this._isOpenTag=token.value==="<";},_onEndTag:function(token)
{this._tagEndOffset=token.endOffset;var selfClosingTag=token.value==="/>"||WebInspector.HTMLModel.SelfClosingTags.has(this._tagName);var tag=new WebInspector.HTMLModel.Tag(this._tagName,this._tagStartOffset,this._tagEndOffset,this._attributes,this._isOpenTag,selfClosingTag);this._onTagComplete(tag);},_onTagComplete:function(tag)
{if(tag.isOpenTag){var topElement=this._stack.peekLast();if(topElement!==this._document&&topElement.openTag.selfClosingTag)
this._popElement(autocloseTag(topElement,topElement.openTag.endOffset));else if((topElement.name in WebInspector.HTMLModel.AutoClosingTags)&&WebInspector.HTMLModel.AutoClosingTags[topElement.name].has(tag.name))
this._popElement(autocloseTag(topElement,tag.startOffset));this._pushElement(tag);return;}
while(this._stack.length>1&&this._stack.peekLast().name!==tag.name)
this._popElement(autocloseTag(this._stack.peekLast(),tag.startOffset));if(this._stack.length===1)
return;this._popElement(tag);function autocloseTag(element,offset)
{return new WebInspector.HTMLModel.Tag(element.name,offset,offset,new Map(),false,false);}},_popElement:function(closeTag)
{var element=this._stack.pop();element.closeTag=closeTag;},_pushElement:function(openTag)
{var topElement=this._stack.peekLast();var newElement=new WebInspector.HTMLModel.Element(openTag.name);newElement.parent=topElement;topElement.children.push(newElement);newElement.openTag=openTag;this._stack.push(newElement);},peekToken:function()
{return this._tokenIndex<this._tokens.length?this._tokens[this._tokenIndex]:null;},nextToken:function()
{return this._tokens[this._tokenIndex++];},document:function()
{return this._document;}}
WebInspector.HTMLModel.Token=function(value,type,startOffset,endOffset)
{this.value=value;this.type=type;this.startOffset=startOffset;this.endOffset=endOffset;}
WebInspector.HTMLModel.Tag=function(name,startOffset,endOffset,attributes,isOpenTag,selfClosingTag)
{this.name=name;this.startOffset=startOffset;this.endOffset=endOffset;this.attributes=attributes;this.isOpenTag=isOpenTag;this.selfClosingTag=selfClosingTag;}
WebInspector.HTMLModel.Element=function(name)
{this.name=name;this.children=[];this.parent=null;this.openTag=null;this.closeTag=null;};WebInspector.IdentityFormatter=function(builder)
{this._builder=builder;}
WebInspector.IdentityFormatter.prototype={format:function(text,lineEndings,fromOffset,toOffset)
{var content=text.substring(fromOffset,toOffset);this._builder.addToken(content,fromOffset);}};WebInspector.javaScriptOutline=function(content)
{var chunkSize=100000;var outlineChunk=[];var previousIdentifier=null;var previousToken=null;var processedChunkCharacters=0;var addedFunction=false;var isReadingArguments=false;var argumentsText="";var currentFunction=null;var tokenizer=new WebInspector.AcornTokenizer(content);var AT=WebInspector.AcornTokenizer;while(tokenizer.peekToken()){var token=(tokenizer.nextToken());if(AT.lineComment(token)||AT.blockComment(token))
continue;var tokenValue=content.substring(token.start,token.end);if(AT.identifier(token)&&previousToken&&(AT.identifier(previousToken,"get")||AT.identifier(previousToken,"set"))){currentFunction={line:tokenizer.tokenLineStart(),column:tokenizer.tokenColumnStart(),name:previousToken.value+" "+tokenValue};addedFunction=true;previousIdentifier=null;}else if(AT.identifier(token)){previousIdentifier=tokenValue;if(tokenValue&&previousToken&&AT.keyword(previousToken,"function")){currentFunction={line:tokenizer.tokenLineStart(),column:tokenizer.tokenColumnStart(),name:tokenValue};addedFunction=true;previousIdentifier=null;}}else if(AT.keyword(token,"function")&&previousIdentifier&&previousToken&&AT.punctuator(previousToken,":=")){currentFunction={line:tokenizer.tokenLineStart(),column:tokenizer.tokenColumnStart(),name:previousIdentifier};addedFunction=true;previousIdentifier=null;}else if(AT.punctuator(token,".")&&previousToken&&AT.identifier(previousToken))
previousIdentifier+=".";else if(AT.punctuator(token,"(")&&addedFunction)
isReadingArguments=true;if(isReadingArguments&&tokenValue)
argumentsText+=tokenValue;if(AT.punctuator(token,")")&&isReadingArguments){addedFunction=false;isReadingArguments=false;currentFunction.arguments=argumentsText.replace(/,[\r\n\s]*/g,", ").replace(/([^,])[\r\n\s]+/g,"$1");argumentsText="";outlineChunk.push(currentFunction);}
previousToken=token;processedChunkCharacters+=token.end-token.start;if(processedChunkCharacters>=chunkSize){postMessage({chunk:outlineChunk,isLastChunk:false});outlineChunk=[];processedChunkCharacters=0;}}
postMessage({chunk:outlineChunk,isLastChunk:true});};WebInspector.RelaxedJSONParser={};WebInspector.RelaxedJSONParser.States={ExpectKey:"ExpectKey",ExpectValue:"ExpectValue"};WebInspector.RelaxedJSONParser.Keywords={"NaN":NaN,"true":true,"false":false,"Infinity":Infinity,"undefined":undefined,"null":null};WebInspector.RelaxedJSONParser.parse=function(content)
{var Keywords=WebInspector.RelaxedJSONParser.Keywords;var States=WebInspector.RelaxedJSONParser.States;content="("+content+")";try{var root=acorn.parse(content,{});}catch(e){return null;}
var walker=new WebInspector.ESTreeWalker(beforeVisit,afterVisit);var rootTip=[];var stack=[];var stackData=({key:0,tip:rootTip,state:States.ExpectValue,parentIsArray:true});walker.setWalkNulls(true);var hasExpression=false;walker.walk(root);if(hasExpression)
return null;return rootTip.length?rootTip[0]:null;function pushStack(newStack)
{stack.push(stackData);stackData=newStack;}
function popStack()
{stackData=stack.pop();}
function applyValue(value)
{stackData.tip[stackData.key]=value;if(stackData.parentIsArray)
stackData.key++;else
stackData.state=null;}
function beforeVisit(node)
{switch(node.type){case"ObjectExpression":var newTip={};applyValue(newTip);pushStack(({key:null,tip:newTip,state:null,parentIsArray:false}));break;case"ArrayExpression":var newTip=[];applyValue(newTip);pushStack(({key:0,tip:newTip,state:States.ExpectValue,parentIsArray:true}));break;case"Property":stackData.state=States.ExpectKey;break;case"Literal":if(stackData.state===States.ExpectKey){stackData.key=node.value;stackData.state=States.ExpectValue;}else if(stackData.state===States.ExpectValue){applyValue(extractValue(node));return WebInspector.ESTreeWalker.SkipSubtree;}
break;case"Identifier":if(stackData.state===States.ExpectKey){stackData.key=(node.name);stackData.state=States.ExpectValue;}else if(stackData.state===States.ExpectValue){applyValue(extractValue(node));return WebInspector.ESTreeWalker.SkipSubtree;}
break;case"UnaryExpression":if(stackData.state===States.ExpectValue){applyValue(extractValue(node));return WebInspector.ESTreeWalker.SkipSubtree;}
break;case"Program":case"ExpressionStatement":break;default:if(stackData.state===States.ExpectValue)
applyValue(extractValue(node));return WebInspector.ESTreeWalker.SkipSubtree;}}
function afterVisit(node)
{if(node.type==="ObjectExpression"||node.type==="ArrayExpression")
popStack();}
function extractValue(node)
{var isNegative=false;var originalNode=node;var value;if(node.type==="UnaryExpression"&&(node.operator==="-"||node.operator==="+")){if(node.operator==="-")
isNegative=true;node=(node.argument);}
if(node.type==="Literal"){value=node.value;}else if(node.type==="Identifier"&&Keywords.hasOwnProperty(node.name)){value=Keywords[node.name];}else{hasExpression=true;return content.substring(originalNode.start,originalNode.end);}
if(isNegative){if(typeof value!=="number"){hasExpression=true;return content.substring(originalNode.start,originalNode.end);}
value=-(value);}
return value;}}
WebInspector.RelaxedJSONParser.Context;;applicationDescriptor={"has_html":false,"modules":[{"type":"remote","name":"gonzales"},{"type":"autostart","name":"formatter_worker"}]};if(!self.Runtime)
self.importScripts('Runtime.js');Runtime.startWorker("formatter_worker");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 2 2 28 24 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 1 2 2 2 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 2 1 | (function webpackUniversalModuleDefinition(root,factory){Eif(typeof exports==='object'&&typeof module==='object')
module.exports=factory();else if(typeof define==='function'&&define.amd)
define([],factory);else if(typeof exports==='object')
exports["gonzales"]=factory();else
root["gonzales"]=factory();})(this,function(){return(function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])
return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.loaded=true;return module.exports;}
__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0);})
([function(module,exports,__webpack_require__){'use strict';var Node=__webpack_require__(1);var parse=__webpack_require__(7);module.exports={createNode:function(options){return new Node(options);},parse:parse};},function(module,exports,__webpack_require__){'use strict';var _createClass=(function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;Iif('value'in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){Eif(protoProps)defineProperties(Constructor.prototype,protoProps);Iif(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError('Cannot call a class as a function');}}
var Node=(function(){function Node(options){_classCallCheck(this,Node);this.type=options.type;this.content=options.content;this.syntax=options.syntax;if(options.start)this.start=options.start;if(options.end)this.end=options.end;}
Node.prototype.contains=function contains(type){return this.content.some(function(node){return node.type===type;});};Node.prototype.eachFor=function eachFor(type,callback){if(!Array.isArray(this.content))return;if(typeof type!=='string'){callback=type;type=null;}
var l=this.content.length;var breakLoop;for(var i=l;i--;){if(breakLoop===null)break;if(!type||this.content[i]&&this.content[i].type===type)breakLoop=callback(this.content[i],i,this);}
if(breakLoop===null)return null;};Node.prototype.first=function first(type){if(!Array.isArray(this.content))return null;if(!type)return this.content[0];var i=0;var l=this.content.length;for(;i<l;i++){if(this.content[i].type===type)return this.content[i];}
return null;};Node.prototype.forEach=function forEach(type,callback){if(!Array.isArray(this.content))return;if(typeof type!=='string'){callback=type;type=null;}
var i=0;var l=this.content.length;var breakLoop;for(;i<l;i++){if(breakLoop===null)break;if(!type||this.content[i]&&this.content[i].type===type)breakLoop=callback(this.content[i],i,this);}
if(breakLoop===null)return null;};Node.prototype.get=function get(index){if(!Array.isArray(this.content))return null;var node=this.content[index];return node?node:null;};Node.prototype.insert=function insert(index,node){if(!Array.isArray(this.content))return;this.content.splice(index,0,node);};Node.prototype.is=function is(type){return this.type===type;};Node.prototype.last=function last(type){if(!Array.isArray(this.content))return null;var i=this.content.length-1;if(!type)return this.content[i];for(;;i--){if(this.content[i].type===type)return this.content[i];}
return null;};Node.prototype.removeChild=function removeChild(index){if(!Array.isArray(this.content))return;var removedChild=this.content.splice(index,1);return removedChild;};Node.prototype.toJson=function toJson(){return JSON.stringify(this,false,2);};Node.prototype.toString=function toString(){var stringify=undefined;try{stringify=__webpack_require__(2)("./"+this.syntax+'/stringify');}catch(e){var message='Syntax "'+this.syntax+'" is not supported yet, sorry';return console.error(message);}
return stringify(this);};Node.prototype.traverse=function traverse(callback,index){var level=arguments.length<=2||arguments[2]===undefined?0:arguments[2];var parent=arguments.length<=3||arguments[3]===undefined?null:arguments[3];var breakLoop;var x;level++;callback(this,index,parent,level);if(!Array.isArray(this.content))return;for(var i=0,l=this.content.length;i<l;i++){breakLoop=this.content[i].traverse(callback,i,level,this);if(breakLoop===null)break;if(x=this.content.length-l){l+=x;i+=x;}}
if(breakLoop===null)return null;};Node.prototype.traverseByType=function traverseByType(type,callback){this.traverse(function(node){if(node.type===type)callback.apply(node,arguments);});};Node.prototype.traverseByTypes=function traverseByTypes(types,callback){this.traverse(function(node){if(types.indexOf(node.type)!==-1)callback.apply(node,arguments);});};_createClass(Node,[{key:'length',get:function(){if(!Array.isArray(this.content))return 0;return this.content.length;}}]);return Node;})();module.exports=Node;},function(module,exports,__webpack_require__){var map={"./css/stringify":3,"./less/stringify":4,"./sass/stringify":5,"./scss/stringify":6};function webpackContext(req){return __webpack_require__(webpackContextResolve(req));};function webpackContextResolve(req){return map[req]||(function(){throw new Error("Cannot find module '"+req+"'.")}());};webpackContext.keys=function webpackContextKeys(){return Object.keys(map);};webpackContext.resolve=webpackContextResolve;module.exports=webpackContext;webpackContext.id=2;},function(module,exports){'use strict';module.exports=function stringify(tree){if(!tree)throw new Error('We need tree to translate');function _t(tree){var type=tree.type;if(_unique[type])return _unique[type](tree);if(typeof tree.content==='string')return tree.content;if(Array.isArray(tree.content))return _composite(tree.content);return'';}
function _composite(t,i){if(!t)return'';var s='';i=i||0;for(;i<t.length;i++)s+=_t(t[i]);return s;}
var _unique={'arguments':function(t){return'('+_composite(t.content)+')';},'atkeyword':function(t){return'@'+_composite(t.content);},'attributeSelector':function(t){return'['+_composite(t.content)+']';},'block':function(t){return'{'+_composite(t.content)+'}';},'brackets':function(t){return'['+_composite(t.content)+']';},'class':function(t){return'.'+_composite(t.content);},'color':function(t){return'#'+t.content;},'expression':function(t){return'expression('+t.content+')';},'id':function(t){return'#'+_composite(t.content);},'multilineComment':function(t){return'/*'+t.content+'*/';},'nthSelector':function(t){return':'+_t(t.content[0])+'('+_composite(t.content.slice(1))+')';},'parentheses':function(t){return'('+_composite(t.content)+')';},'percentage':function(t){return _composite(t.content)+'%';},'pseudoClass':function(t){return':'+_composite(t.content);},'pseudoElement':function(t){return'::'+_composite(t.content);},'uri':function(t){return'url('+_composite(t.content)+')';}};return _t(tree);};},function(module,exports){'use strict';module.exports=function stringify(tree){if(!tree)throw new Error('We need tree to translate');function _t(tree){var type=tree.type;if(_unique[type])return _unique[type](tree);if(typeof tree.content==='string')return tree.content;if(Array.isArray(tree.content))return _composite(tree.content);return'';}
function _composite(t,i){if(!t)return'';var s='';i=i||0;for(;i<t.length;i++)s+=_t(t[i]);return s;}
var _unique={'arguments':function(t){return'('+_composite(t.content)+')';},'atkeyword':function(t){return'@'+_composite(t.content);},'attributeSelector':function(t){return'['+_composite(t.content)+']';},'block':function(t){return'{'+_composite(t.content)+'}';},'brackets':function(t){return'['+_composite(t.content)+']';},'class':function(t){return'.'+_composite(t.content);},'color':function(t){return'#'+t.content;},'escapedString':function(t){return'~'+t.content;},'expression':function(t){return'expression('+t.content+')';},'id':function(t){return'#'+_composite(t.content);},'interpolatedVariable':function(t){return'@{'+_composite(t.content)+'}';},'multilineComment':function(t){return'/*'+t.content+'*/';},'nthSelector':function(t){return':'+_t(t.content[0])+'('+_composite(t.content.slice(1))+')';},'parentheses':function(t){return'('+_composite(t.content)+')';},'percentage':function(t){return _composite(t.content)+'%';},'pseudoClass':function(t){return':'+_composite(t.content);},'pseudoElement':function(t){return'::'+_composite(t.content);},'singlelineComment':function(t){return'/'+'/'+t.content;},'uri':function(t){return'url('+_composite(t.content)+')';},'variable':function(t){return'@'+_composite(t.content);},'variablesList':function(t){return _composite(t.content)+'...';}};return _t(tree);};},function(module,exports){'use strict';module.exports=function stringify(tree){if(!tree)throw new Error('We need tree to translate');function _t(tree){var type=tree.type;if(_unique[type])return _unique[type](tree);if(typeof tree.content==='string')return tree.content;if(Array.isArray(tree.content))return _composite(tree.content);return'';}
function _composite(t,i){if(!t)return'';var s='';i=i||0;for(;i<t.length;i++)s+=_t(t[i]);return s;}
var _unique={'arguments':function(t){return'('+_composite(t.content)+')';},'atkeyword':function(t){return'@'+_composite(t.content);},'attributeSelector':function(t){return'['+_composite(t.content)+']';},'block':function(t){return _composite(t.content);},'brackets':function(t){return'['+_composite(t.content)+']';},'class':function(t){return'.'+_composite(t.content);},'color':function(t){return'#'+t.content;},'expression':function(t){return'expression('+t.content+')';},'id':function(t){return'#'+_composite(t.content);},'interpolation':function(t){return'#{'+_composite(t.content)+'}';},'multilineComment':function(t){return'/*'+t.content;},'nthSelector':function(t){return':'+_t(t.content[0])+'('+_composite(t.content.slice(1))+')';},'parentheses':function(t){return'('+_composite(t.content)+')';},'percentage':function(t){return _composite(t.content)+'%';},'placeholder':function(t){return'%'+_composite(t.content);},'pseudoClass':function(t){return':'+_composite(t.content);},'pseudoElement':function(t){return'::'+_composite(t.content);},'singlelineComment':function(t){return'/'+'/'+t.content;},'uri':function(t){return'url('+_composite(t.content)+')';},'variable':function(t){return'$'+_composite(t.content);},'variablesList':function(t){return _composite(t.content)+'...';}};return _t(tree);};},function(module,exports){'use strict';module.exports=function stringify(tree){if(!tree)throw new Error('We need tree to translate');function _t(tree){var type=tree.type;if(_unique[type])return _unique[type](tree);if(typeof tree.content==='string')return tree.content;if(Array.isArray(tree.content))return _composite(tree.content);return'';}
function _composite(t,i){if(!t)return'';var s='';i=i||0;for(;i<t.length;i++)s+=_t(t[i]);return s;}
var _unique={'arguments':function(t){return'('+_composite(t.content)+')';},'atkeyword':function(t){return'@'+_composite(t.content);},'attributeSelector':function(t){return'['+_composite(t.content)+']';},'block':function(t){return'{'+_composite(t.content)+'}';},'brackets':function(t){return'['+_composite(t.content)+']';},'class':function(t){return'.'+_composite(t.content);},'color':function(t){return'#'+t.content;},'expression':function(t){return'expression('+t.content+')';},'id':function(t){return'#'+_composite(t.content);},'interpolation':function(t){return'#{'+_composite(t.content)+'}';},'multilineComment':function(t){return'/*'+t.content+'*/';},'nthSelector':function(t){return':'+_t(t.content[0])+'('+_composite(t.content.slice(1))+')';},'parentheses':function(t){return'('+_composite(t.content)+')';},'percentage':function(t){return _composite(t.content)+'%';},'placeholder':function(t){return'%'+_composite(t.content);},'pseudoClass':function(t){return':'+_composite(t.content);},'pseudoElement':function(t){return'::'+_composite(t.content);},'singlelineComment':function(t){return'/'+'/'+t.content;},'uri':function(t){return'url('+_composite(t.content)+')';},'variable':function(t){return'$'+_composite(t.content);},'variablesList':function(t){return _composite(t.content)+'...';}};return _t(tree);};},function(module,exports,__webpack_require__){'use strict';var ParsingError=__webpack_require__(8);var syntaxes=__webpack_require__(10);var isInteger=Number.isInteger||function(value){return typeof value==='number'&&Math.floor(value)===value;};function parser(css,options){if(typeof css!=='string')throw new Error('Please, pass a string to parse');else if(!css)return __webpack_require__(16)();var syntax=options&&options.syntax||'css';var context=options&&options.context||'stylesheet';var tabSize=options&&options.tabSize;if(!isInteger(tabSize)||tabSize<1)tabSize=1;var syntaxParser=undefined;if(syntaxes[syntax]){syntaxParser=syntaxes[syntax];}else{syntaxParser=syntaxes;}
if(!syntaxParser){var message='Syntax "'+syntax+'" is not supported yet, sorry';return console.error(message);}
var getTokens=syntaxParser.tokenizer;var mark=syntaxParser.mark;var parse=syntaxParser.parse;var tokens=getTokens(css,tabSize);mark(tokens);var ast;try{ast=parse(tokens,context);}catch(e){if(!e.syntax)throw e;throw new ParsingError(e,css);}
return ast;}
module.exports=parser;},function(module,exports,__webpack_require__){'use strict';var parserPackage=__webpack_require__(9);function ParsingError(e,css){this.line=e.line;this.syntax=e.syntax;this.css_=css;}
ParsingError.prototype=Object.defineProperties({customMessage_:'',line:null,name:'Parsing error',syntax:null,version:parserPackage.version,toString:function(){return[this.name+': '+this.message,'',this.context,'','Syntax: '+this.syntax,'Gonzales PE version: '+this.version].join('\n');}},{context:{get:function(){var LINES_AROUND=2;var result=[];var currentLineNumber=this.line;var start=currentLineNumber-1-LINES_AROUND;var end=currentLineNumber+LINES_AROUND;var lines=this.css_.split(/\r\n|\r|\n/);for(var i=start;i<end;i++){var line=lines[i];if(!line)continue;var ln=i+1;var mark=ln===currentLineNumber?'*':' ';result.push(ln+mark+'| '+line);}
return result.join('\n');},configurable:true,enumerable:true},message:{get:function(){if(this.customMessage_){return this.customMessage_;}else{var message='Please check validity of the block';if(typeof this.line==='number')message+=' starting from line #'+this.line;return message;}},set:function(message){this.customMessage_=message;},configurable:true,enumerable:true}});module.exports=ParsingError;},function(module,exports){module.exports={"name":"gonzales-pe","description":"Gonzales Preprocessor Edition (fast CSS parser)","version":"3.3.1","homepage":"http://github.com/tonyganch/gonzales-pe","bugs":"http://github.com/tonyganch/gonzales-pe/issues","license":"MIT","author":{"name":"Tony Ganch","email":"tonyganch+github@gmail.com","url":"http://tonyganch.com"},"main":"./lib/gonzales","repository":{"type":"git","url":"http://github.com/tonyganch/gonzales-pe.git"},"scripts":{"autofix-tests":"bash ./scripts/build.sh && bash ./scripts/autofix-tests.sh","build":"bash ./scripts/build.sh","init":"bash ./scripts/init.sh","log":"bash ./scripts/log.sh","prepublish":"bash ./scripts/prepublish.sh","postpublish":"bash ./scripts/postpublish.sh","test":"bash ./scripts/build.sh && bash ./scripts/test.sh","watch":"bash ./scripts/watch.sh"},"bin":{"gonzales":"./bin/gonzales.js"},"dependencies":{"minimist":"1.1.x"},"devDependencies":{"babel-loader":"^5.3.2","coffee-script":"~1.7.1","jscs":"2.1.0","jshint":"2.8.0","json-loader":"^0.5.3","mocha":"2.2.x","webpack":"^1.12.2"},"engines":{"node":">=0.6.0"}};},function(module,exports,__webpack_require__){'use strict';exports.__esModule=true;exports['default']={mark:__webpack_require__(11),parse:__webpack_require__(13),stringify:__webpack_require__(6),tokenizer:__webpack_require__(15)};module.exports=exports['default'];},function(module,exports,__webpack_require__){'use strict';var TokenType=__webpack_require__(12);module.exports=(function(){function markSC(tokens){var tokensLength=tokens.length;var ws=-1;var sc=-1;var t=undefined;for(var i=0;i<tokensLength;i++){t=tokens[i];switch(t.type){case TokenType.Space:case TokenType.Tab:case TokenType.Newline:t.ws=true;t.sc=true;if(ws===-1)ws=i;if(sc===-1)sc=i;break;case TokenType.CommentML:case TokenType.CommentSL:if(ws!==-1){tokens[ws].ws_last=i-1;ws=-1;}
t.sc=true;break;default:if(ws!==-1){tokens[ws].ws_last=i-1;ws=-1;}
if(sc!==-1){tokens[sc].sc_last=i-1;sc=-1;}}}
if(ws!==-1)tokens[ws].ws_last=i-1;if(sc!==-1)tokens[sc].sc_last=i-1;}
function markBrackets(tokens){var tokensLength=tokens.length;var ps=[];var sbs=[];var cbs=[];var t=undefined;for(var i=0;i<tokensLength;i++){t=tokens[i];switch(t.type){case TokenType.LeftParenthesis:ps.push(i);break;case TokenType.RightParenthesis:if(ps.length){t.left=ps.pop();tokens[t.left].right=i;}
break;case TokenType.LeftSquareBracket:sbs.push(i);break;case TokenType.RightSquareBracket:if(sbs.length){t.left=sbs.pop();tokens[t.left].right=i;}
break;case TokenType.LeftCurlyBracket:cbs.push(i);break;case TokenType.RightCurlyBracket:if(cbs.length){t.left=cbs.pop();tokens[t.left].right=i;}
break;}}}
return function(tokens){markBrackets(tokens);markSC(tokens);};})();},function(module,exports){'use strict';module.exports={StringSQ:'StringSQ',StringDQ:'StringDQ',CommentML:'CommentML',CommentSL:'CommentSL',Newline:'Newline',Space:'Space',Tab:'Tab',ExclamationMark:'ExclamationMark',QuotationMark:'QuotationMark',NumberSign:'NumberSign',DollarSign:'DollarSign',PercentSign:'PercentSign',Ampersand:'Ampersand',Apostrophe:'Apostrophe',LeftParenthesis:'LeftParenthesis',RightParenthesis:'RightParenthesis',Asterisk:'Asterisk',PlusSign:'PlusSign',Comma:'Comma',HyphenMinus:'HyphenMinus',FullStop:'FullStop',Solidus:'Solidus',Colon:'Colon',Semicolon:'Semicolon',LessThanSign:'LessThanSign',EqualsSign:'EqualsSign',EqualitySign:'EqualitySign',InequalitySign:'InequalitySign',GreaterThanSign:'GreaterThanSign',QuestionMark:'QuestionMark',CommercialAt:'CommercialAt',LeftSquareBracket:'LeftSquareBracket',ReverseSolidus:'ReverseSolidus',RightSquareBracket:'RightSquareBracket',CircumflexAccent:'CircumflexAccent',LowLine:'LowLine',LeftCurlyBracket:'LeftCurlyBracket',VerticalLine:'VerticalLine',RightCurlyBracket:'RightCurlyBracket',Tilde:'Tilde',Identifier:'Identifier',DecimalNumber:'DecimalNumber'};},function(module,exports,__webpack_require__){'use strict';var Node=__webpack_require__(1);var NodeType=__webpack_require__(14);var TokenType=__webpack_require__(12);var tokens=undefined;var tokensLength=undefined;var pos=undefined;var contexts={'arguments':function(){return checkArguments(pos)&&getArguments();},'atkeyword':function(){return checkAtkeyword(pos)&&getAtkeyword();},'atrule':function(){return checkAtrule(pos)&&getAtrule();},'block':function(){return checkBlock(pos)&&getBlock();},'brackets':function(){return checkBrackets(pos)&&getBrackets();},'class':function(){return checkClass(pos)&&getClass();},'combinator':function(){return checkCombinator(pos)&&getCombinator();},'commentML':function(){return checkCommentML(pos)&&getCommentML();},'commentSL':function(){return checkCommentSL(pos)&&getCommentSL();},'condition':function(){return checkCondition(pos)&&getCondition();},'conditionalStatement':function(){return checkConditionalStatement(pos)&&getConditionalStatement();},'declaration':function(){return checkDeclaration(pos)&&getDeclaration();},'declDelim':function(){return checkDeclDelim(pos)&&getDeclDelim();},'default':function(){return checkDefault(pos)&&getDefault();},'delim':function(){return checkDelim(pos)&&getDelim();},'dimension':function(){return checkDimension(pos)&&getDimension();},'expression':function(){return checkExpression(pos)&&getExpression();},'extend':function(){return checkExtend(pos)&&getExtend();},'function':function(){return checkFunction(pos)&&getFunction();},'global':function(){return checkGlobal(pos)&&getGlobal();},'ident':function(){return checkIdent(pos)&&getIdent();},'important':function(){return checkImportant(pos)&&getImportant();},'include':function(){return checkInclude(pos)&&getInclude();},'interpolation':function(){return checkInterpolation(pos)&&getInterpolation();},'loop':function(){return checkLoop(pos)&&getLoop();},'mixin':function(){return checkMixin(pos)&&getMixin();},'namespace':function(){return checkNamespace(pos)&&getNamespace();},'number':function(){return checkNumber(pos)&&getNumber();},'operator':function(){return checkOperator(pos)&&getOperator();},'optional':function(){return checkOptional(pos)&&getOptional();},'parentheses':function(){return checkParentheses(pos)&&getParentheses();},'parentselector':function(){return checkParentSelector(pos)&&getParentSelector();},'percentage':function(){return checkPercentage(pos)&&getPercentage();},'placeholder':function(){return checkPlaceholder(pos)&&getPlaceholder();},'progid':function(){return checkProgid(pos)&&getProgid();},'property':function(){return checkProperty(pos)&&getProperty();},'propertyDelim':function(){return checkPropertyDelim(pos)&&getPropertyDelim();},'pseudoc':function(){return checkPseudoc(pos)&&getPseudoc();},'pseudoe':function(){return checkPseudoe(pos)&&getPseudoe();},'ruleset':function(){return checkRuleset(pos)&&getRuleset();},'s':function(){return checkS(pos)&&getS();},'selector':function(){return checkSelector(pos)&&getSelector();},'shash':function(){return checkShash(pos)&&getShash();},'string':function(){return checkString(pos)&&getString();},'stylesheet':function(){return checkStylesheet(pos)&&getStylesheet();},'unary':function(){return checkUnary(pos)&&getUnary();},'uri':function(){return checkUri(pos)&&getUri();},'value':function(){return checkValue(pos)&&getValue();},'variable':function(){return checkVariable(pos)&&getVariable();},'variableslist':function(){return checkVariablesList(pos)&&getVariablesList();},'vhash':function(){return checkVhash(pos)&&getVhash();}};function throwError(i){var ln=i?tokens[i].ln:tokens[pos].ln;throw{line:ln,syntax:'scss'};}function checkExcluding(exclude,i){var start=i;while(i<tokensLength){if(exclude[tokens[i++].type])break;}return i-start-2;}function joinValues(start,finish){var s='';for(var i=start;i<finish+1;i++){s+=tokens[i].value;}return s;}function joinValues2(start,num){if(start+num-1>=tokensLength)return;var s='';for(var i=0;i<num;i++){s+=tokens[start+i].value;}return s;}function getLastPosition(content,line,column,colOffset){return typeof content==='string'?getLastPositionForString(content,line,column,colOffset):getLastPositionForArray(content,line,column,colOffset);}function getLastPositionForString(content,line,column,colOffset){var position=[];if(!content){position=[line,column];if(colOffset)position[1]+=colOffset-1;return position;}var lastLinebreak=content.lastIndexOf('\n');var endsWithLinebreak=lastLinebreak===content.length-1;var splitContent=content.split('\n');var linebreaksCount=splitContent.length-1;var prevLinebreak=linebreaksCount===0||linebreaksCount===1?-1:content.length-splitContent[linebreaksCount-1].length-2;var offset=endsWithLinebreak?linebreaksCount-1:linebreaksCount;position[0]=line+offset;if(endsWithLinebreak){offset=prevLinebreak!==-1?content.length-prevLinebreak:content.length-1;}else{offset=linebreaksCount!==0?content.length-lastLinebreak-column-1:content.length-1;}position[1]=column+offset;if(!colOffset)return position;if(endsWithLinebreak){position[0]++;position[1]=colOffset;}else{position[1]+=colOffset;}return position;}function getLastPositionForArray(content,line,column,colOffset){var position;if(content.length===0){position=[line,column];}else{var c=content[content.length-1];if(c.hasOwnProperty('end')){position=[c.end.line,c.end.column];}else{position=getLastPosition(c.content,line,column);}}if(!colOffset)return position;if(tokens[pos-1].type!=='Newline'){position[1]+=colOffset;}else{position[0]++;position[1]=1;}return position;}function newNode(type,content,line,column,end){if(!end)end=getLastPosition(content,line,column);return new Node({type:type,content:content,start:{line:line,column:column},end:{line:end[0],column:end[1]},syntax:'scss'});}function checkAny(i){return checkBrackets(i)||checkParentheses(i)||checkString(i)||checkVariablesList(i)||checkVariable(i)||checkPlaceholder(i)||checkPercentage(i)||checkDimension(i)||checkNumber(i)||checkUri(i)||checkExpression(i)||checkFunction(i)||checkInterpolation(i)||checkIdent(i)||checkClass(i)||checkUnary(i);}function getAny(){if(checkBrackets(pos))return getBrackets();else if(checkParentheses(pos))return getParentheses();else if(checkString(pos))return getString();else if(checkVariablesList(pos))return getVariablesList();else if(checkVariable(pos))return getVariable();else if(checkPlaceholder(pos))return getPlaceholder();else if(checkPercentage(pos))return getPercentage();else if(checkDimension(pos))return getDimension();else if(checkNumber(pos))return getNumber();else if(checkUri(pos))return getUri();else if(checkExpression(pos))return getExpression();else if(checkFunction(pos))return getFunction();else if(checkInterpolation(pos))return getInterpolation();else if(checkIdent(pos))return getIdent();else if(checkClass(pos))return getClass();else if(checkUnary(pos))return getUnary();}function checkArguments(i){var start=i;var l=undefined;if(i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;i++;while(i<tokens[start].right){if(l=checkArgument(i))i+=l;else return 0;}return tokens[start].right-start+1;}function checkArgument(i){return checkBrackets(i)||checkParentheses(i)||checkDeclaration(i)||checkFunction(i)||checkVariablesList(i)||checkVariable(i)||checkSC(i)||checkDelim(i)||checkDeclDelim(i)||checkString(i)||checkPercentage(i)||checkDimension(i)||checkNumber(i)||checkUri(i)||checkInterpolation(i)||checkIdent(i)||checkVhash(i)||checkOperator(i)||checkUnary(i);}function getArgument(){if(checkBrackets(pos))return getBrackets();else if(checkParentheses(pos))return getParentheses();else if(checkDeclaration(pos))return getDeclaration();else if(checkFunction(pos))return getFunction();else if(checkVariablesList(pos))return getVariablesList();else if(checkVariable(pos))return getVariable();else if(checkSC(pos))return getSC();else if(checkDelim(pos))return getDelim();else if(checkDeclDelim(pos))return getDeclDelim();else if(checkString(pos))return getString();else if(checkPercentage(pos))return getPercentage();else if(checkDimension(pos))return getDimension();else if(checkNumber(pos))return getNumber();else if(checkUri(pos))return getUri();else if(checkInterpolation(pos))return getInterpolation();else if(checkIdent(pos))return getIdent();else if(checkVhash(pos))return getVhash();else if(checkOperator(pos))return getOperator();else if(checkUnary(pos))return getUnary();}function checkAtkeyword(i){var l;if(i>=tokensLength||tokens[i++].type!==TokenType.CommercialAt)return 0;return(l=checkIdentOrInterpolation(i))?l+1:0;}function getAtkeyword(){var startPos=pos;var x=undefined;pos++;x=getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.AtkeywordType,x,token.ln,token.col);}function checkAtrule(i){var l;if(i>=tokensLength)return 0;if(tokens[i].atrule_l!==undefined)return tokens[i].atrule_l;if(l=checkKeyframesRule(i))tokens[i].atrule_type=4;else if(l=checkAtruler(i))tokens[i].atrule_type=1;else if(l=checkAtruleb(i))tokens[i].atrule_type=2;else if(l=checkAtrules(i))tokens[i].atrule_type=3;else return 0;tokens[i].atrule_l=l;return l;}function getAtrule(){switch(tokens[pos].atrule_type){case 1:return getAtruler();case 2:return getAtruleb();case 3:return getAtrules();case 4:return getKeyframesRule();}}function checkAtruleb(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(l=checkTsets(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getAtruleb(){var startPos=pos;var x=undefined;x=[getAtkeyword()].concat(getTsets()).concat([getBlock()]);var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);}function checkAtruler(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(l=checkTsets(i))i+=l;if(i<tokensLength&&tokens[i].type===TokenType.LeftCurlyBracket)i++;else return 0;if(l=checkAtrulers(i))i+=l;if(i<tokensLength&&tokens[i].type===TokenType.RightCurlyBracket)i++;else return 0;return i-start;}function getAtruler(){var startPos=pos;var x=undefined;x=[getAtkeyword()].concat(getTsets());x.push(getAtrulers());var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);}function checkAtrulers(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;while(l=checkRuleset(i)||checkAtrule(i)||checkSC(i)){i+=l;}if(i<tokensLength)tokens[i].atrulers_end=1;return i-start;}function getAtrulers(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;x=getSC();while(!tokens[pos].atrulers_end){if(checkSC(pos))x=x.concat(getSC());else if(checkAtrule(pos))x.push(getAtrule());else if(checkRuleset(pos))x.push(getRuleset());}x=x.concat(getSC());var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.BlockType,x,token.ln,token.col,end);}function checkAtrules(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(l=checkTsets(i))i+=l;return i-start;}function getAtrules(){var startPos=pos;var x=undefined;x=[getAtkeyword()].concat(getTsets());var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);}function checkBlock(i){return i<tokensLength&&tokens[i].type===TokenType.LeftCurlyBracket?tokens[i].right-i+1:0;}function getBlock(){var startPos=pos;var end=tokens[pos].right;var x=[];var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;while(pos<end){if(checkBlockdecl(pos))x=x.concat(getBlockdecl());else throwError();}var end_=getLastPosition(x,line,column,1);pos=end+1;return newNode(NodeType.BlockType,x,token.ln,token.col,end_);}function checkBlockdecl(i){var l;if(i>=tokensLength)return 0;if(l=checkBlockdecl1(i))tokens[i].bd_type=1;else if(l=checkBlockdecl2(i))tokens[i].bd_type=2;else if(l=checkBlockdecl3(i))tokens[i].bd_type=3;else if(l=checkBlockdecl4(i))tokens[i].bd_type=4;else return 0;return l;}function getBlockdecl(){switch(tokens[pos].bd_type){case 1:return getBlockdecl1();case 2:return getBlockdecl2();case 3:return getBlockdecl3();case 4:return getBlockdecl4();}}function checkBlockdecl1(i){var start=i;var l=undefined;if(l=checkSC(i))i+=l;if(l=checkConditionalStatement(i))tokens[i].bd_kind=1;else if(l=checkInclude(i))tokens[i].bd_kind=2;else if(l=checkExtend(i))tokens[i].bd_kind=4;else if(l=checkLoop(i))tokens[i].bd_kind=3;else if(l=checkAtrule(i))tokens[i].bd_kind=6;else if(l=checkRuleset(i))tokens[i].bd_kind=7;else if(l=checkDeclaration(i))tokens[i].bd_kind=5;else return 0;i+=l;if(i<tokensLength&&(l=checkDeclDelim(i)))i+=l;else return 0;if(l=checkSC(i))i+=l;return i-start;}function getBlockdecl1(){var sc=getSC();var x=undefined;switch(tokens[pos].bd_kind){case 1:x=getConditionalStatement();break;case 2:x=getInclude();break;case 3:x=getLoop();break;case 4:x=getExtend();break;case 5:x=getDeclaration();break;case 6:x=getAtrule();break;case 7:x=getRuleset();break;}return sc.concat([x]).concat([getDeclDelim()]).concat(getSC());}function checkBlockdecl2(i){var start=i;var l=undefined;if(l=checkSC(i))i+=l;if(l=checkConditionalStatement(i))tokens[i].bd_kind=1;else if(l=checkInclude(i))tokens[i].bd_kind=2;else if(l=checkExtend(i))tokens[i].bd_kind=4;else if(l=checkMixin(i))tokens[i].bd_kind=8;else if(l=checkLoop(i))tokens[i].bd_kind=3;else if(l=checkAtrule(i))tokens[i].bd_kind=6;else if(l=checkRuleset(i))tokens[i].bd_kind=7;else if(l=checkDeclaration(i))tokens[i].bd_kind=5;else return 0;i+=l;if(l=checkSC(i))i+=l;return i-start;}function getBlockdecl2(){var sc=getSC();var x=undefined;switch(tokens[pos].bd_kind){case 1:x=getConditionalStatement();break;case 2:x=getInclude();break;case 3:x=getLoop();break;case 4:x=getExtend();break;case 5:x=getDeclaration();break;case 6:x=getAtrule();break;case 7:x=getRuleset();break;case 8:x=getMixin();break;}return sc.concat([x]).concat(getSC());}function checkBlockdecl3(i){var start=i;var l=undefined;if(l=checkSC(i))i+=l;if(l=checkDeclDelim(i))i+=l;else return 0;if(l=checkSC(i))i+=l;return i-start;}function getBlockdecl3(){return getSC().concat([getDeclDelim()]).concat(getSC());}function checkBlockdecl4(i){return checkSC(i);}function getBlockdecl4(){return getSC();}function checkBrackets(i){if(i>=tokensLength||tokens[i].type!==TokenType.LeftSquareBracket)return 0;return tokens[i].right-i+1;}function getBrackets(){var startPos=pos;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;var tsets=getTsets();var end=getLastPosition(tsets,line,column,1);pos++;return newNode(NodeType.BracketsType,tsets,token.ln,token.col,end);}function checkClass(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(tokens[i].class_l)return tokens[i].class_l;if(tokens[i++].type!==TokenType.FullStop)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getClass(){var startPos=pos;var x=[];pos++;x=x.concat(getIdentOrInterpolation());var token=tokens[startPos];return newNode(NodeType.ClassType,x,token.ln,token.col);}function checkCombinator(i){if(i>=tokensLength)return 0;var l=undefined;if(l=checkCombinator1(i))tokens[i].combinatorType=1;else if(l=checkCombinator2(i))tokens[i].combinatorType=2;else if(l=checkCombinator3(i))tokens[i].combinatorType=3;return l;}function getCombinator(){var type=tokens[pos].combinatorType;if(type===1)return getCombinator1();if(type===2)return getCombinator2();if(type===3)return getCombinator3();}function checkCombinator1(i){if(tokens[i].type===TokenType.VerticalLine&&tokens[i+1].type===TokenType.VerticalLine)return 2;else return 0;}function getCombinator1(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='||';pos+=2;return newNode(type,content,line,column);}function checkCombinator2(i){var type=tokens[i].type;if(type===TokenType.PlusSign||type===TokenType.GreaterThanSign||type===TokenType.Tilde)return 1;else return 0;}function getCombinator2(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=tokens[pos++].value;return newNode(type,content,line,column);}function checkCombinator3(i){var start=i;if(tokens[i].type===TokenType.Solidus)i++;else return 0;var l=undefined;if(l=checkIdent(i))i+=l;else return 0;if(tokens[i].type===TokenType.Solidus)i++;else return 0;return i-start;}function getCombinator3(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var ident=getIdent();pos++;var content='/'+ident.content+'/';return newNode(type,content,line,column);}function checkCommentML(i){return i<tokensLength&&tokens[i].type===TokenType.CommentML?1:0;}function getCommentML(){var startPos=pos;var s=tokens[pos].value.substring(2);var l=s.length;var token=tokens[startPos];var line=token.ln;var column=token.col;if(s.charAt(l-2)==='*'&&s.charAt(l-1)==='/')s=s.substring(0,l-2);var end=getLastPosition(s,line,column,2);if(end[0]===line)end[1]+=2;pos++;return newNode(NodeType.CommentMLType,s,token.ln,token.col,end);}function checkCommentSL(i){return i<tokensLength&&tokens[i].type===TokenType.CommentSL?1:0;}function getCommentSL(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;x=tokens[pos++].value.substring(2);var end=getLastPosition(x,line,column+2);return newNode(NodeType.CommentSLType,x,token.ln,token.col,end);}function checkCondition(i){var start=i;var l=undefined;var _i=undefined;var s=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(['if','else'].indexOf(tokens[start+1].value)<0)return 0;while(i<tokensLength){if(l=checkBlock(i))break;s=checkSC(i);_i=i+s;if(l=_checkCondition(_i))i+=l+s;else break;}return i-start;}function _checkCondition(i){return checkVariable(i)||checkNumber(i)||checkInterpolation(i)||checkIdent(i)||checkOperator(i)||checkCombinator(i)||checkString(i);}function getCondition(){var startPos=pos;var x=[];var s;var _pos;x.push(getAtkeyword());while(pos<tokensLength){if(checkBlock(pos))break;s=checkSC(pos);_pos=pos+s;if(!_checkCondition(_pos))break;if(s)x=x.concat(getSC());x.push(_getCondition());}var token=tokens[startPos];return newNode(NodeType.ConditionType,x,token.ln,token.col);}function _getCondition(){if(checkVariable(pos))return getVariable();if(checkNumber(pos))return getNumber();if(checkInterpolation(pos))return getInterpolation();if(checkIdent(pos))return getIdent();if(checkOperator(pos))return getOperator();if(checkCombinator(pos))return getCombinator();if(checkString(pos))return getString();}function checkConditionalStatement(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkCondition(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getConditionalStatement(){var startPos=pos;var x=[];x.push(getCondition());x=x.concat(getSC());x.push(getBlock());var token=tokens[startPos];return newNode(NodeType.ConditionalStatementType,x,token.ln,token.col);}function checkDeclaration(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkProperty(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkPropertyDelim(i))i++;else return 0;if(l=checkSC(i))i+=l;if(l=checkValue(i))i+=l;else return 0;return i-start;}function getDeclaration(){var startPos=pos;var x=[];x.push(getProperty());x=x.concat(getSC());x.push(getPropertyDelim());x=x.concat(getSC());x.push(getValue());var token=tokens[startPos];return newNode(NodeType.DeclarationType,x,token.ln,token.col);}function checkDeclDelim(i){return i<tokensLength&&tokens[i].type===TokenType.Semicolon?1:0;}function getDeclDelim(){var startPos=pos++;var token=tokens[startPos];return newNode(NodeType.DeclDelimType,';',token.ln,token.col);}function checkDefault(i){var start=i;var l=undefined;if(i>=tokensLength||tokens[i++].type!==TokenType.ExclamationMark)return 0;if(l=checkSC(i))i+=l;if(tokens[i].value==='default'){tokens[start].defaultEnd=i;return i-start+1;}else{return 0;}}function getDefault(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.defaultEnd);pos=token.defaultEnd+1;return newNode(NodeType.DefaultType,content,line,column);}function checkDelim(i){return i<tokensLength&&tokens[i].type===TokenType.Comma?1:0;}function getDelim(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.DelimType,',',token.ln,token.col);}function checkDimension(i){var ln=checkNumber(i);var li=undefined;if(i>=tokensLength||!ln||i+ln>=tokensLength)return 0;return(li=checkNmName2(i+ln))?ln+li:0;}function getDimension(){var startPos=pos;var x=[getNumber()];var token=tokens[pos];var ident=newNode(NodeType.IdentType,getNmName2(),token.ln,token.col);x.push(ident);token=tokens[startPos];return newNode(NodeType.DimensionType,x,token.ln,token.col);}function checkExpression(i){var start=i;if(i>=tokensLength||tokens[i++].value!=='expression'||i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;return tokens[i].right-start+1;}function getExpression(){var startPos=pos;var e;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;e=joinValues(pos+1,tokens[pos].right-1);var end=getLastPosition(e,line,column,1);if(end[0]===line)end[1]+=11;pos=tokens[pos].right+1;return newNode(NodeType.ExpressionType,e,token.ln,token.col,end);}function checkExtend(i){var l=0;if(l=checkExtend1(i))tokens[i].extend_child=1;else if(l=checkExtend2(i))tokens[i].extend_child=2;return l;}function getExtend(){var type=tokens[pos].extend_child;if(type===1)return getExtend1();else if(type===2)return getExtend2();}function checkExtend1(i){var start=i;var l;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='extend')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkSelectorsGroup(i))i+=l;else return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkOptional(i))i+=l;else return 0;return i-start;}function getExtend1(){var startPos=pos;var x=[].concat([getAtkeyword()],getSC(),getSelectorsGroup(),getSC(),[getOptional()]);var token=tokens[startPos];return newNode(NodeType.ExtendType,x,token.ln,token.col);}function checkExtend2(i){var start=i;var l;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='extend')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkSelectorsGroup(i))i+=l;else return 0;return i-start;}function getExtend2(){var startPos=pos;var x=[].concat([getAtkeyword()],getSC(),getSelectorsGroup());var token=tokens[startPos];return newNode(NodeType.ExtendType,x,token.ln,token.col);}function checkFunction(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i<tokensLength&&tokens[i].type===TokenType.LeftParenthesis?tokens[i].right-start+1:0;}function getFunction(){var startPos=pos;var x=getIdentOrInterpolation();var body=undefined;body=getArguments();x.push(body);var token=tokens[startPos];return newNode(NodeType.FunctionType,x,token.ln,token.col);}function getArguments(){var startPos=pos;var x=[];var body=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;while(pos<tokensLength&&tokens[pos].type!==TokenType.RightParenthesis){if(checkDeclaration(pos))x.push(getDeclaration());else if(checkArgument(pos)){body=getArgument();if(typeof body.content==='string')x.push(body);else x=x.concat(body);}else if(checkClass(pos))x.push(getClass());else throwError();}var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.ArgumentsType,x,token.ln,token.col,end);}function checkIdent(i){var start=i;var interpolations=[];var wasIdent=undefined;var wasInt=false;var l=undefined;if(i>=tokensLength)return 0;if(tokens[i].type===TokenType.LowLine)return checkIdentLowLine(i);if(tokens[i].type===TokenType.HyphenMinus&&tokens[i+1].type===TokenType.DecimalNumber)return 0;if(l=_checkIdent(i))i+=l;else return 0;wasIdent=tokens[i-1].type===TokenType.Identifier;while(i<tokensLength){l=_checkIdent(i);if(!l)break;wasIdent=true;i+=l;}if(!wasIdent&&!wasInt&&tokens[start].type!==TokenType.Asterisk)return 0;tokens[start].ident_last=i-1;if(interpolations.length)tokens[start].interpolations=interpolations;return i-start;}function _checkIdent(i){if(tokens[i].type===TokenType.HyphenMinus||tokens[i].type===TokenType.Identifier||tokens[i].type===TokenType.DollarSign||tokens[i].type===TokenType.LowLine||tokens[i].type===TokenType.DecimalNumber||tokens[i].type===TokenType.Asterisk)return 1;return 0;}function checkIdentLowLine(i){var start=i;if(i++>=tokensLength)return 0;for(;i<tokensLength;i++){if(tokens[i].type!==TokenType.HyphenMinus&&tokens[i].type!==TokenType.DecimalNumber&&tokens[i].type!==TokenType.LowLine&&tokens[i].type!==TokenType.Identifier)break;}
tokens[start].ident_last=i-1;return i-start;}function getIdent(){var startPos=pos;var x=joinValues(pos,tokens[pos].ident_last);pos=tokens[pos].ident_last+1;var token=tokens[startPos];return newNode(NodeType.IdentType,x,token.ln,token.col);}function checkIdentOrInterpolation(i){var start=i;var l=undefined;while(i<tokensLength){if(l=checkInterpolation(i)||checkIdent(i))i+=l;else break;}return i-start;}function getIdentOrInterpolation(){var x=[];while(pos<tokensLength){if(checkInterpolation(pos))x.push(getInterpolation());else if(checkIdent(pos))x.push(getIdent());else break;}return x;}function checkImportant(i){var start=i;var l=undefined;if(i>=tokensLength||tokens[i++].type!==TokenType.ExclamationMark)return 0;if(l=checkSC(i))i+=l;if(tokens[i].value==='important'){tokens[start].importantEnd=i;return i-start+1;}else{return 0;}}function getImportant(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.importantEnd);pos=token.importantEnd+1;return newNode(NodeType.ImportantType,content,line,column);}function checkInclude(i){var l;if(i>=tokensLength)return 0;if(l=checkInclude1(i))tokens[i].include_type=1;else if(l=checkInclude2(i))tokens[i].include_type=2;else if(l=checkInclude3(i))tokens[i].include_type=3;else if(l=checkInclude4(i))tokens[i].include_type=4;else if(l=checkInclude5(i))tokens[i].include_type=5;return l;}function checkGlobal(i){var start=i;var l=undefined;if(i>=tokensLength||tokens[i++].type!==TokenType.ExclamationMark)return 0;if(l=checkSC(i))i+=l;if(tokens[i].value==='global'){tokens[start].globalEnd=i;return i-start+1;}else{return 0;}}function getGlobal(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.globalEnd);pos=token.globalEnd+1;return newNode(NodeType.GlobalType,content,line,column);}function getInclude(){switch(tokens[pos].include_type){case 1:return getInclude1();case 2:return getInclude2();case 3:return getInclude3();case 4:return getInclude4();case 5:return getInclude5();}}function checkInclude1(i){var start=i;var l=undefined;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='include')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkArguments(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkKeyframesBlocks(i))i+=l;else return 0;return i-start;}function getInclude1(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments(),getSC(),getKeyframesBlocks());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);}function checkInclude2(i){var start=i;var l=undefined;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='include')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkArguments(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getInclude2(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments(),getSC(),getBlock());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);}function checkInclude3(i){var start=i;var l=undefined;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='include')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkArguments(i))i+=l;else return 0;return i-start;}function getInclude3(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);}function checkInclude4(i){var start=i;var l=undefined;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='include')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getInclude4(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getBlock());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);}function checkInclude5(i){var start=i;var l=undefined;if(l=checkAtkeyword(i))i+=l;else return 0;if(tokens[start+1].value!=='include')return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getInclude5(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);}function checkInterpolation(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(tokens[i].type!==TokenType.NumberSign||!tokens[i+1]||tokens[i+1].type!==TokenType.LeftCurlyBracket)return 0;i+=2;while(tokens[i].type!==TokenType.RightCurlyBracket){if(l=checkArgument(i))i+=l;else return 0;}return tokens[i].type===TokenType.RightCurlyBracket?i-start+1:0;}function getInterpolation(){var startPos=pos;var x=[];var token=tokens[startPos];var line=token.ln;var column=token.col;pos+=2;while(pos<tokensLength&&tokens[pos].type!==TokenType.RightCurlyBracket){var body=getArgument();if(typeof body.content==='string')x.push(body);else x=x.concat(body);}var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.InterpolationType,x,token.ln,token.col,end);}function checkKeyframesBlock(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkKeyframesSelector(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getKeyframesBlock(){var type=NodeType.RulesetType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[].concat([getKeyframesSelector()],getSC(),[getBlock()]);return newNode(type,content,line,column);}function checkKeyframesBlocks(i){var start=i;var l=undefined;if(i<tokensLength&&tokens[i].type===TokenType.LeftCurlyBracket)i++;else return 0;if(l=checkSC(i))i+=l;if(l=checkKeyframesBlock(i))i+=l;else return 0;while(tokens[i].type!==TokenType.RightCurlyBracket){if(l=checkSC(i))i+=l;else if(l=checkKeyframesBlock(i))i+=l;else break;}if(i<tokensLength&&tokens[i].type===TokenType.RightCurlyBracket)i++;else return 0;return i-start;}function getKeyframesBlocks(){var type=NodeType.BlockType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];var keyframesBlocksEnd=token.right;pos++;while(pos<keyframesBlocksEnd){if(checkSC(pos))content=content.concat(getSC());else if(checkKeyframesBlock(pos))content.push(getKeyframesBlock());}var end=getLastPosition(content,line,column,1);pos++;return newNode(type,content,line,column,end);}function checkKeyframesRule(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;var atruleName=joinValues2(i-l,l);if(atruleName.indexOf('keyframes')===-1)return 0;if(l=checkSC(i))i+=l;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkKeyframesBlocks(i))i+=l;else return 0;return i-start;}function getKeyframesRule(){var type=NodeType.AtruleType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[].concat([getAtkeyword()],getSC(),getIdentOrInterpolation(),getSC(),[getKeyframesBlocks()]);return newNode(type,content,line,column);}function checkKeyframesSelector(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkIdent(i)){var selector=joinValues2(i,l);if(selector!=='from'&&selector!=='to')return 0;i+=l;tokens[start].keyframesSelectorType=1;}else if(l=checkPercentage(i)){i+=l;tokens[start].keyframesSelectorType=2;}else if(l=checkInterpolation(i)){i+=l;tokens[start].keyframesSelectorType=3;}else{return 0;}return i-start;}function getKeyframesSelector(){var keyframesSelectorType=NodeType.KeyframesSelectorType;var selectorType=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(token.keyframesSelectorType===1){content.push(getIdent());}else if(token.keyframesSelectorType===2){content.push(getPercentage());}else{content.push(getInterpolation());}var keyframesSelector=newNode(keyframesSelectorType,content,line,column);return newNode(selectorType,[keyframesSelector],line,column);}function checkLoop(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkAtkeyword(i))i+=l;else return 0;if(['for','each','while'].indexOf(tokens[start+1].value)<0)return 0;while(i<tokensLength){if(l=checkBlock(i)){i+=l;break;}else if(l=checkVariable(i)||checkNumber(i)||checkInterpolation(i)||checkIdent(i)||checkSC(i)||checkOperator(i)||checkCombinator(i)||checkString(i))i+=l;else return 0;}return i-start;}function getLoop(){var startPos=pos;var x=[];x.push(getAtkeyword());while(pos<tokensLength){if(checkBlock(pos)){x.push(getBlock());break;}else if(checkVariable(pos))x.push(getVariable());else if(checkNumber(pos))x.push(getNumber());else if(checkInterpolation(pos))x.push(getInterpolation());else if(checkIdent(pos))x.push(getIdent());else if(checkOperator(pos))x.push(getOperator());else if(checkCombinator(pos))x.push(getCombinator());else if(checkSC(pos))x=x.concat(getSC());else if(checkString(pos))x.push(getString());}var token=tokens[startPos];return newNode(NodeType.LoopType,x,token.ln,token.col);}function checkMixin(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if((l=checkAtkeyword(i))&&tokens[i+1].value==='mixin')i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkArguments(i))i+=l;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getMixin(){var startPos=pos;var x=[getAtkeyword()];x=x.concat(getSC());if(checkIdentOrInterpolation(pos))x=x.concat(getIdentOrInterpolation());x=x.concat(getSC());if(checkArguments(pos))x.push(getArguments());x=x.concat(getSC());if(checkBlock(pos))x.push(getBlock());var token=tokens[startPos];return newNode(NodeType.MixinType,x,token.ln,token.col);}function checkNamespace(i){return i<tokensLength&&tokens[i].type===TokenType.VerticalLine?1:0;}function getNamespace(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.NamespaceType,'|',token.ln,token.col);}function checkNmName2(i){if(tokens[i].type===TokenType.Identifier)return 1;else if(tokens[i].type!==TokenType.DecimalNumber)return 0;i++;return i<tokensLength&&tokens[i].type===TokenType.Identifier?2:1;}function getNmName2(){var s=tokens[pos].value;if(tokens[pos++].type===TokenType.DecimalNumber&&pos<tokensLength&&tokens[pos].type===TokenType.Identifier)s+=tokens[pos++].value;return s;}function checkNumber(i){if(i>=tokensLength)return 0;if(tokens[i].number_l)return tokens[i].number_l;if(i<tokensLength&&tokens[i].type===TokenType.DecimalNumber&&(!tokens[i+1]||tokens[i+1]&&tokens[i+1].type!==TokenType.FullStop))return tokens[i].number_l=1,tokens[i].number_l;if(i<tokensLength&&tokens[i].type===TokenType.DecimalNumber&&tokens[i+1]&&tokens[i+1].type===TokenType.FullStop&&(!tokens[i+2]||tokens[i+2].type!==TokenType.DecimalNumber))return tokens[i].number_l=2,tokens[i].number_l;if(i<tokensLength&&tokens[i].type===TokenType.FullStop&&tokens[i+1].type===TokenType.DecimalNumber)return tokens[i].number_l=2,tokens[i].number_l;if(i<tokensLength&&tokens[i].type===TokenType.DecimalNumber&&tokens[i+1]&&tokens[i+1].type===TokenType.FullStop&&tokens[i+2]&&tokens[i+2].type===TokenType.DecimalNumber)return tokens[i].number_l=3,tokens[i].number_l;return 0;}function getNumber(){var s='';var startPos=pos;var l=tokens[pos].number_l;for(var j=0;j<l;j++){s+=tokens[pos+j].value;}pos+=l;var token=tokens[startPos];return newNode(NodeType.NumberType,s,token.ln,token.col);}function checkOperator(i){if(i>=tokensLength)return 0;switch(tokens[i].type){case TokenType.Solidus:case TokenType.PercentSign:case TokenType.Comma:case TokenType.Colon:case TokenType.EqualsSign:case TokenType.EqualitySign:case TokenType.InequalitySign:case TokenType.LessThanSign:case TokenType.GreaterThanSign:case TokenType.Asterisk:return 1;}return 0;}function getOperator(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.OperatorType,x,token.ln,token.col);}function checkOptional(i){var start=i;var l=undefined;if(i>=tokensLength||tokens[i++].type!==TokenType.ExclamationMark)return 0;if(l=checkSC(i))i+=l;if(tokens[i].value==='optional'){tokens[start].optionalEnd=i;return i-start+1;}else{return 0;}}function getOptional(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.optionalEnd);pos=token.optionalEnd+1;return newNode(NodeType.OptionalType,content,line,column);}function checkParentheses(i){if(i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;return tokens[i].right-i+1;}function getParentheses(){var type=NodeType.ParenthesesType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var tsets=getTsets();var end=getLastPosition(tsets,line,column,1);pos++;return newNode(type,tsets,line,column,end);}function checkParentSelector(i){return i<tokensLength&&tokens[i].type===TokenType.Ampersand?1:0;}function getParentSelector(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.ParentSelectorType,'&',token.ln,token.col);}function checkParentSelectorExtension(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;while(i<tokensLength){if(l=checkNumber(i)||checkIdentOrInterpolation(i))i+=l;else break;}return i-start;}function getParentSelectorExtension(){var type=NodeType.ParentSelectorExtensionType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];while(pos<tokensLength){if(checkNumber(pos))content.push(getNumber());else if(checkIdentOrInterpolation(pos))content=content.concat(getIdentOrInterpolation());else break;}return newNode(type,content,line,column);}function checkParentSelectorWithExtension(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkParentSelector(i))i+=l;else return 0;if(l=checkParentSelectorExtension(i))i+=l;return i-start;}function getParentSelectorWithExtension(){var content=[getParentSelector()];if(checkParentSelectorExtension(pos))content.push(getParentSelectorExtension());return content;}function checkPercentage(i){var x;if(i>=tokensLength)return 0;x=checkNumber(i);if(!x||i+x>=tokensLength)return 0;return tokens[i+x].type===TokenType.PercentSign?x+1:0;}function getPercentage(){var startPos=pos;var x=[getNumber()];var token=tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.PercentageType,x,token.ln,token.col,end);}function checkPlaceholder(i){var l;if(i>=tokensLength)return 0;if(tokens[i].placeholder_l)return tokens[i].placeholder_l;if(tokens[i].type===TokenType.PercentSign&&(l=checkIdentOrInterpolation(i+1))){tokens[i].placeholder_l=l+1;return l+1;}else return 0;}function getPlaceholder(){var startPos=pos;pos++;var x=getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.PlaceholderType,x,token.ln,token.col);}function checkProgid(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(joinValues2(i,6)==='progid:DXImageTransform.Microsoft.')i+=6;else return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(tokens[i].type===TokenType.LeftParenthesis){tokens[start].progid_end=tokens[i].right;i=tokens[i].right+1;}else return 0;return i-start;}function getProgid(){var startPos=pos;var progid_end=tokens[pos].progid_end;var x=joinValues(pos,progid_end);pos=progid_end+1;var token=tokens[startPos];return newNode(NodeType.ProgidType,x,token.ln,token.col);}function checkProperty(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkVariable(i)||checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getProperty(){var startPos=pos;var x=[];if(checkVariable(pos)){x.push(getVariable());}else{x=x.concat(getIdentOrInterpolation());}var token=tokens[startPos];return newNode(NodeType.PropertyType,x,token.ln,token.col);}function checkPropertyDelim(i){return i<tokensLength&&tokens[i].type===TokenType.Colon?1:0;}function getPropertyDelim(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.PropertyDelimType,':',token.ln,token.col);}function checkPseudo(i){return checkPseudoe(i)||checkPseudoc(i);}function getPseudo(){if(checkPseudoe(pos))return getPseudoe();if(checkPseudoc(pos))return getPseudoc();}function checkPseudoe(i){var l;if(i>=tokensLength||tokens[i++].type!==TokenType.Colon||i>=tokensLength||tokens[i++].type!==TokenType.Colon)return 0;return(l=checkIdentOrInterpolation(i))?l+2:0;}function getPseudoe(){var startPos=pos;pos+=2;var x=getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.PseudoeType,x,token.ln,token.col);}function checkPseudoc(i){var l;if(i>=tokensLength||tokens[i].type!==TokenType.Colon)return 0;if(l=checkPseudoClass3(i))tokens[i].pseudoClassType=3;else if(l=checkPseudoClass4(i))tokens[i].pseudoClassType=4;else if(l=checkPseudoClass5(i))tokens[i].pseudoClassType=5;else if(l=checkPseudoClass1(i))tokens[i].pseudoClassType=1;else if(l=checkPseudoClass2(i))tokens[i].pseudoClassType=2;else if(l=checkPseudoClass6(i))tokens[i].pseudoClassType=6;else return 0;return l;}function getPseudoc(){var childType=tokens[pos].pseudoClassType;if(childType===1)return getPseudoClass1();if(childType===2)return getPseudoClass2();if(childType===3)return getPseudoClass3();if(childType===4)return getPseudoClass4();if(childType===5)return getPseudoClass5();if(childType===6)return getPseudoClass6();}function checkPseudoClass1(i){var start=i;i++;if(i>=tokensLength)return 0;var l=undefined;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;var right=tokens[i].right;i++;if(l=checkSelectorsGroup(i))i+=l;else return 0;if(i!==right)return 0;return right-start+1;}function getPseudoClass1(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];pos++;content=content.concat(getIdentOrInterpolation());{var _type=NodeType.ArgumentsType;var _token=tokens[pos];var _line=_token.ln;var _column=_token.col;pos++;var selectors=getSelectorsGroup();var end=getLastPosition(selectors,_line,_column,1);var args=newNode(_type,selectors,_line,_column,end);content.push(args);pos++;}return newNode(type,content,line,column);}function checkPseudoClass2(i){var start=i;var l=0;i++;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;var right=tokens[i].right;i++;if(l=checkSC(i))i+=l;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(i!==right)return 0;return i-start+1;}function getPseudoClass2(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];pos++;content=content.concat(getIdentOrInterpolation());var l=tokens[pos].ln;var c=tokens[pos].col;var value=[];pos++;value=value.concat(getSC()).concat(getIdentOrInterpolation()).concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args);pos++;return newNode(type,content,line,column);}function checkPseudoClass3(i){var start=i;var l=0;i++;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;var right=tokens[i].right;i++;if(l=checkSC(i))i+=l;if(l=checkUnary(i))i+=l;if(i>=tokensLength)return 0;if(tokens[i].type===TokenType.DecimalNumber)i++;if(i>=tokensLength)return 0;if(tokens[i].value==='n')i++;else return 0;if(l=checkSC(i))i+=l;if(i>=tokensLength)return 0;if(tokens[i].value==='+'||tokens[i].value==='-')i++;else return 0;if(l=checkSC(i))i+=l;if(tokens[i].type===TokenType.DecimalNumber)i++;else return 0;if(l=checkSC(i))i+=l;if(i!==right)return 0;return i-start+1;}function getPseudoClass3(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[];pos++;if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());{var _l=tokens[pos].ln;var _c=tokens[pos].col;var _content=tokens[pos].value;var ident=newNode(NodeType.IdentType,_content,_l,_c);value.push(ident);pos++;}value=value.concat(getSC());if(checkUnary(pos))value.push(getUnary());value=value.concat(getSC());if(checkNumber(pos))value.push(getNumber());value=value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args);pos++;return newNode(type,content,line,column);}function checkPseudoClass4(i){var start=i;var l=0;i++;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(i>=tokensLength)return 0;if(tokens[i].type!==TokenType.LeftParenthesis)return 0;var right=tokens[i].right;i++;if(l=checkSC(i))i+=l;if(l=checkUnary(i))i+=l;if(tokens[i].type===TokenType.DecimalNumber)i++;if(tokens[i].value==='n')i++;else return 0;if(l=checkSC(i))i+=l;if(i!==right)return 0;return i-start+1;}function getPseudoClass4(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[];pos++;value=value.concat(getSC());if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());if(checkIdent(pos))value.push(getIdent());value=value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args);pos++;return newNode(type,content,line,column);}function checkPseudoClass5(i){var start=i;var l=0;i++;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;if(i>=tokensLength)return 0;if(tokens[i].type!==TokenType.LeftParenthesis)return 0;var right=tokens[i].right;i++;if(l=checkSC(i))i+=l;if(l=checkUnary(i))i+=l;if(tokens[i].type===TokenType.DecimalNumber)i++;else return 0;if(l=checkSC(i))i+=l;if(i!==right)return 0;return i-start+1;}function getPseudoClass5(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[];pos++;if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());value=value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args);pos++;return newNode(type,content,line,column);}function checkPseudoClass6(i){var start=i;var l=0;i++;if(i>=tokensLength)return 0;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getPseudoClass6(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var content=getIdentOrInterpolation();return newNode(type,content,line,column);}function checkRuleset(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkSelectorsGroup(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkBlock(i))i+=l;else return 0;return i-start;}function getRuleset(){var type=NodeType.RulesetType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];content=content.concat(getSelectorsGroup());content=content.concat(getSC());content.push(getBlock());return newNode(type,content,line,column);}function checkS(i){return i<tokensLength&&tokens[i].ws?tokens[i].ws_last-i+1:0;}function getS(){var startPos=pos;var x=joinValues(pos,tokens[pos].ws_last);pos=tokens[pos].ws_last+1;var token=tokens[startPos];return newNode(NodeType.SType,x,token.ln,token.col);}function checkSC(i){if(i>=tokensLength)return 0;var l=undefined;var lsc=0;while(i<tokensLength){if(!(l=checkS(i))&&!(l=checkCommentML(i))&&!(l=checkCommentSL(i)))break;i+=l;lsc+=l;}return lsc||0;}function getSC(){var sc=[];if(pos>=tokensLength)return sc;while(pos<tokensLength){if(checkS(pos))sc.push(getS());else if(checkCommentML(pos))sc.push(getCommentML());else if(checkCommentSL(pos))sc.push(getCommentSL());else break;}return sc;}function checkShash(i){var l;if(i>=tokensLength||tokens[i].type!==TokenType.NumberSign)return 0;return(l=checkIdentOrInterpolation(i+1))?l+1:0;}function getShash(){var startPos=pos;var token=tokens[startPos];pos++;var x=getIdentOrInterpolation();return newNode(NodeType.ShashType,x,token.ln,token.col);}function checkString(i){return i<tokensLength&&(tokens[i].type===TokenType.StringSQ||tokens[i].type===TokenType.StringDQ)?1:0;}function getString(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.StringType,x,token.ln,token.col);}function checkStylesheet(i){var start=i;var l=undefined;while(i<tokensLength){if(l=checkSC(i)||checkDeclaration(i)||checkDeclDelim(i)||checkInclude(i)||checkExtend(i)||checkMixin(i)||checkLoop(i)||checkConditionalStatement(i)||checkAtrule(i)||checkRuleset(i))i+=l;else throwError(i);}return i-start;}function getStylesheet(){var startPos=pos;var x=[];while(pos<tokensLength){if(checkSC(pos))x=x.concat(getSC());else if(checkRuleset(pos))x.push(getRuleset());else if(checkInclude(pos))x.push(getInclude());else if(checkExtend(pos))x.push(getExtend());else if(checkMixin(pos))x.push(getMixin());else if(checkLoop(pos))x.push(getLoop());else if(checkConditionalStatement(pos))x.push(getConditionalStatement());else if(checkAtrule(pos))x.push(getAtrule());else if(checkDeclaration(pos))x.push(getDeclaration());else if(checkDeclDelim(pos))x.push(getDeclDelim());else throwError();}var token=tokens[startPos];return newNode(NodeType.StylesheetType,x,token.ln,token.col);}function checkTset(i){return checkVhash(i)||checkOperator(i)||checkAny(i)||checkSC(i)||checkInterpolation(i);}function getTset(){if(checkVhash(pos))return getVhash();else if(checkOperator(pos))return getOperator();else if(checkAny(pos))return getAny();else if(checkSC(pos))return getSC();else if(checkInterpolation(pos))return getInterpolation();}function checkTsets(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;while(l=checkTset(i)){i+=l;}return i-start;}function getTsets(){var x=[];var t=undefined;while(t=getTset()){if(typeof t.content==='string')x.push(t);else x=x.concat(t);}return x;}function checkUnary(i){return i<tokensLength&&(tokens[i].type===TokenType.HyphenMinus||tokens[i].type===TokenType.PlusSign)?1:0;}function getUnary(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.OperatorType,x,token.ln,token.col);}function checkUri(i){var start=i;if(i>=tokensLength||tokens[i++].value!=='url'||i>=tokensLength||tokens[i].type!==TokenType.LeftParenthesis)return 0;return tokens[i].right-start+1;}function getUri(){var startPos=pos;var uriExcluding={};var uri=undefined;var token=undefined;var l=undefined;var raw=undefined;pos+=2;uriExcluding[TokenType.Space]=1;uriExcluding[TokenType.Tab]=1;uriExcluding[TokenType.Newline]=1;uriExcluding[TokenType.LeftParenthesis]=1;uriExcluding[TokenType.RightParenthesis]=1;if(checkUriContent(pos)){uri=[].concat(getSC()).concat(getUriContent()).concat(getSC());}else{uri=[].concat(getSC());l=checkExcluding(uriExcluding,pos);token=tokens[pos];raw=newNode(NodeType.RawType,joinValues(pos,pos+l),token.ln,token.col);uri.push(raw);pos+=l+1;uri=uri.concat(getSC());}token=tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition(uri,line,column,1);pos++;return newNode(NodeType.UriType,uri,token.ln,token.col,end);}function checkUriContent(i){return checkUri1(i)||checkFunction(i);}function getUriContent(){if(checkUri1(pos))return getString();else if(checkFunction(pos))return getFunction();}function checkUri1(i){var start=i;var l=undefined;if(i>=tokensLength)return 0;if(l=checkSC(i))i+=l;if(tokens[i].type!==TokenType.StringDQ&&tokens[i].type!==TokenType.StringSQ)return 0;i++;if(l=checkSC(i))i+=l;return i-start;}function checkValue(i){var start=i;var l=undefined;var s=undefined;var _i=undefined;while(i<tokensLength){if(checkDeclDelim(i))break;s=checkSC(i);_i=i+s;if(l=_checkValue(_i))i+=l+s;if(!l||checkBlock(i-l))break;}return i-start;}function _checkValue(i){return checkInterpolation(i)||checkVariable(i)||checkVhash(i)||checkBlock(i)||checkAtkeyword(i)||checkOperator(i)||checkImportant(i)||checkGlobal(i)||checkDefault(i)||checkProgid(i)||checkAny(i);}function getValue(){var startPos=pos;var x=[];var _pos=undefined;var s=undefined;while(pos<tokensLength){s=checkSC(pos);_pos=pos+s;if(checkDeclDelim(_pos))break;if(!_checkValue(_pos))break;if(s)x=x.concat(getSC());x.push(_getValue());if(checkBlock(_pos))break;}var token=tokens[startPos];return newNode(NodeType.ValueType,x,token.ln,token.col);}function _getValue(){if(checkInterpolation(pos))return getInterpolation();else if(checkVariable(pos))return getVariable();else if(checkVhash(pos))return getVhash();else if(checkBlock(pos))return getBlock();else if(checkAtkeyword(pos))return getAtkeyword();else if(checkOperator(pos))return getOperator();else if(checkImportant(pos))return getImportant();else if(checkGlobal(pos))return getGlobal();else if(checkDefault(pos))return getDefault();else if(checkProgid(pos))return getProgid();else if(checkAny(pos))return getAny();}function checkVariable(i){var l;if(i>=tokensLength||tokens[i].type!==TokenType.DollarSign)return 0;return(l=checkIdent(i+1))?l+1:0;}function getVariable(){var startPos=pos;var x=[];pos++;x.push(getIdent());var token=tokens[startPos];return newNode(NodeType.VariableType,x,token.ln,token.col);}function checkVariablesList(i){var d=0;var l=undefined;if(i>=tokensLength)return 0;if(l=checkVariable(i))i+=l;else return 0;while(i<tokensLength&&tokens[i].type===TokenType.FullStop){d++;i++;}return d===3?l+d:0;}function getVariablesList(){var startPos=pos;var x=getVariable();var token=tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition([x],line,column,3);pos+=3;return newNode(NodeType.VariablesListType,[x],token.ln,token.col,end);}function checkVhash(i){var l;if(i>=tokensLength||tokens[i].type!==TokenType.NumberSign)return 0;return(l=checkNmName2(i+1))?l+1:0;}function getVhash(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;x=getNmName2();var end=getLastPosition(x,line,column+1);return newNode(NodeType.VhashType,x,token.ln,token.col,end);}module.exports=function(_tokens,context){tokens=_tokens;tokensLength=tokens.length;pos=0;return contexts[context]();};function checkSelectorsGroup(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkSelector(i))i+=l;else return 0;while(i<tokensLength){var sb=checkSC(i);var c=checkDelim(i+sb);if(!c)break;var sa=checkSC(i+sb+c);if(l=checkSelector(i+sb+c+sa))i+=sb+c+sa+l;else break;}tokens[start].selectorsGroupEnd=i;return i-start;}function getSelectorsGroup(){var selectorsGroup=[];var selectorsGroupEnd=tokens[pos].selectorsGroupEnd;selectorsGroup.push(getSelector());while(pos<selectorsGroupEnd){selectorsGroup=selectorsGroup.concat(getSC());selectorsGroup.push(getDelim());selectorsGroup=selectorsGroup.concat(getSC());selectorsGroup.push(getSelector());}return selectorsGroup;}function checkSelector(i){var l;if(l=checkSelector1(i))tokens[i].selectorType=1;else if(l=checkSelector2(i))tokens[i].selectorType=2;return l;}function getSelector(){var selectorType=tokens[pos].selectorType;if(selectorType===1)return getSelector1();else return getSelector2();}function checkSelector1(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkCompoundSelector(i))i+=l;else return 0;while(i<tokensLength){var s=checkSC(i);var c=checkCombinator(i+s);if(!s&&!c)break;if(c){i+=s+c;s=checkSC(i);}if(l=checkCompoundSelector(i+s))i+=s+l;else break;}tokens[start].selectorEnd=i;return i-start;}function getSelector1(){var type=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var selectorEnd=token.selectorEnd;var content=getCompoundSelector();while(pos<selectorEnd){if(checkSC(pos))content=content.concat(getSC());else if(checkCombinator(pos))content.push(getCombinator());else if(checkCompoundSelector(pos))content=content.concat(getCompoundSelector());}return newNode(type,content,line,column);}function checkSelector2(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkCombinator(i))i+=l;else return 0;while(i<tokensLength){var sb=checkSC(i);if(l=checkCompoundSelector(i+sb))i+=sb+l;else break;var sa=checkSC(i);var c=checkCombinator(i+sa);if(!sa&&!c)break;if(c){i+=sa+c;}}tokens[start].selectorEnd=i;return i-start;}function getSelector2(){var type=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var selectorEnd=token.selectorEnd;var content=[getCombinator()];while(pos<selectorEnd){if(checkSC(pos))content=content.concat(getSC());else if(checkCombinator(pos))content.push(getCombinator());else if(checkCompoundSelector(pos))content=content.concat(getCompoundSelector());}return newNode(type,content,line,column);}function checkCompoundSelector(i){var l=undefined;if(l=checkCompoundSelector1(i)){tokens[i].compoundSelectorType=1;}else if(l=checkCompoundSelector2(i)){tokens[i].compoundSelectorType=2;}return l;}function getCompoundSelector(){var type=tokens[pos].compoundSelectorType;if(type===1)return getCompoundSelector1();if(type===2)return getCompoundSelector2();}function checkCompoundSelector1(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkTypeSelector(i)||checkPlaceholder(i)||checkParentSelectorWithExtension(i))i+=l;else return 0;while(i<tokensLength){var _l2=checkShash(i)||checkClass(i)||checkAttributeSelector(i)||checkPseudo(i)||checkPlaceholder(i);if(_l2)i+=_l2;else break;}tokens[start].compoundSelectorEnd=i;return i-start;}function getCompoundSelector1(){var sequence=[];var compoundSelectorEnd=tokens[pos].compoundSelectorEnd;if(checkTypeSelector(pos))sequence.push(getTypeSelector());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());else if(checkParentSelectorWithExtension(pos))sequence=sequence.concat(getParentSelectorWithExtension());while(pos<compoundSelectorEnd){if(checkShash(pos))sequence.push(getShash());else if(checkClass(pos))sequence.push(getClass());else if(checkAttributeSelector(pos))sequence.push(getAttributeSelector());else if(checkPseudo(pos))sequence.push(getPseudo());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());}return sequence;}function checkCompoundSelector2(i){if(i>=tokensLength)return 0;var start=i;while(i<tokensLength){var l=checkShash(i)||checkClass(i)||checkAttributeSelector(i)||checkPseudo(i)||checkPlaceholder(i);if(l)i+=l;else break;}tokens[start].compoundSelectorEnd=i;return i-start;}function getCompoundSelector2(){var sequence=[];var compoundSelectorEnd=tokens[pos].compoundSelectorEnd;while(pos<compoundSelectorEnd){if(checkShash(pos))sequence.push(getShash());else if(checkClass(pos))sequence.push(getClass());else if(checkAttributeSelector(pos))sequence.push(getAttributeSelector());else if(checkPseudo(pos))sequence.push(getPseudo());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());}return sequence;}function checkTypeSelector(i){if(i>=tokensLength)return 0;var start=i;var l=undefined;if(l=checkNamePrefix(i))i+=l;if(tokens[i].type===TokenType.Asterisk)i++;else if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getTypeSelector(){var type=NodeType.TypeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkNamePrefix(pos))content.push(getNamePrefix());if(checkIdentOrInterpolation(pos))content=content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeSelector(i){var l=undefined;if(l=checkAttributeSelector1(i))tokens[i].attributeSelectorType=1;else if(l=checkAttributeSelector2(i))tokens[i].attributeSelectorType=2;return l;}function getAttributeSelector(){var type=tokens[pos].attributeSelectorType;if(type===1)return getAttributeSelector1();else return getAttributeSelector2();}function checkAttributeSelector1(i){var start=i;if(tokens[i].type===TokenType.LeftSquareBracket)i++;else return 0;var l=undefined;if(l=checkSC(i))i+=l;if(l=checkAttributeName(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkAttributeMatch(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkAttributeValue(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(l=checkAttributeFlags(i)){i+=l;if(l=checkSC(i))i+=l;}if(tokens[i].type===TokenType.RightSquareBracket)i++;else return 0;return i-start;}function getAttributeSelector1(){var type=NodeType.AttributeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];pos++;content=content.concat(getSC());content.push(getAttributeName());content=content.concat(getSC());content.push(getAttributeMatch());content=content.concat(getSC());content.push(getAttributeValue());content=content.concat(getSC());if(checkAttributeFlags(pos)){content.push(getAttributeFlags());content=content.concat(getSC());}
pos++;var end=getLastPosition(content,line,column,1);return newNode(type,content,line,column,end);}function checkAttributeSelector2(i){var start=i;if(tokens[i].type===TokenType.LeftSquareBracket)i++;else return 0;var l=undefined;if(l=checkSC(i))i+=l;if(l=checkAttributeName(i))i+=l;else return 0;if(l=checkSC(i))i+=l;if(tokens[i].type===TokenType.RightSquareBracket)i++;else return 0;return i-start;}function getAttributeSelector2(){var type=NodeType.AttributeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];pos++;content=content.concat(getSC());content.push(getAttributeName());content=content.concat(getSC());pos++;var end=getLastPosition(content,line,column,1);return newNode(type,content,line,column,end);}function checkAttributeName(i){var start=i;var l=undefined;if(l=checkNamePrefix(i))i+=l;if(l=checkIdentOrInterpolation(i))i+=l;else return 0;return i-start;}function getAttributeName(){var type=NodeType.AttributeNameType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkNamePrefix(pos))content.push(getNamePrefix());content=content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeMatch(i){var l=undefined;if(l=checkAttributeMatch1(i))tokens[i].attributeMatchType=1;else if(l=checkAttributeMatch2(i))tokens[i].attributeMatchType=2;return l;}function getAttributeMatch(){var type=tokens[pos].attributeMatchType;if(type===1)return getAttributeMatch1();else return getAttributeMatch2();}function checkAttributeMatch1(i){var start=i;var type=tokens[i].type;if(type===TokenType.Tilde||type===TokenType.VerticalLine||type===TokenType.CircumflexAccent||type===TokenType.DollarSign||type===TokenType.Asterisk)i++;else return 0;if(tokens[i].type===TokenType.EqualsSign)i++;else return 0;return i-start;}function getAttributeMatch1(){var type=NodeType.AttributeMatchType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=tokens[pos].value+tokens[pos+1].value;pos+=2;return newNode(type,content,line,column);}function checkAttributeMatch2(i){if(tokens[i].type===TokenType.EqualsSign)return 1;else return 0;}function getAttributeMatch2(){var type=NodeType.AttributeMatchType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='=';pos++;return newNode(type,content,line,column);}function checkAttributeValue(i){return checkString(i)||checkIdentOrInterpolation(i);}function getAttributeValue(){var type=NodeType.AttributeValueType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkString(pos))content.push(getString());else content=content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeFlags(i){return checkIdentOrInterpolation(i);}function getAttributeFlags(){var type=NodeType.AttributeFlagsType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=getIdentOrInterpolation();return newNode(type,content,line,column);}function checkNamePrefix(i){if(i>=tokensLength)return 0;var l=undefined;if(l=checkNamePrefix1(i))tokens[i].namePrefixType=1;else if(l=checkNamePrefix2(i))tokens[i].namePrefixType=2;return l;}function getNamePrefix(){var type=tokens[pos].namePrefixType;if(type===1)return getNamePrefix1();else return getNamePrefix2();}function checkNamePrefix1(i){var start=i;var l=undefined;if(l=checkNamespacePrefix(i))i+=l;else return 0;if(l=checkCommentML(i))i+=l;if(l=checkNamespaceSeparator(i))i+=l;else return 0;return i-start;}function getNamePrefix1(){var type=NodeType.NamePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];content.push(getNamespacePrefix());if(checkCommentML(pos))content.push(getCommentML());content.push(getNamespaceSeparator());return newNode(type,content,line,column);}function checkNamePrefix2(i){return checkNamespaceSeparator(i);}function getNamePrefix2(){var type=NodeType.NamePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[getNamespaceSeparator()];return newNode(type,content,line,column);}function checkNamespacePrefix(i){if(i>=tokensLength)return 0;var l=undefined;if(tokens[i].type===TokenType.Asterisk)return 1;else if(l=checkIdentOrInterpolation(i))return l;else return 0;}function getNamespacePrefix(){var type=NodeType.NamespacePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkIdentOrInterpolation(pos))content=content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkNamespaceSeparator(i){if(i>=tokensLength)return 0;if(tokens[i].type===TokenType.VerticalLine)return 1;else return 0;}function getNamespaceSeparator(){var type=NodeType.NamespaceSeparatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='|';pos++;return newNode(type,content,line,column);}},function(module,exports){'use strict';module.exports={ArgumentsType:'arguments',AtkeywordType:'atkeyword',AtruleType:'atrule',AttributeSelectorType:'attributeSelector',AttributeNameType:'attributeName',AttributeFlagsType:'attributeFlags',AttributeMatchType:'attributeMatch',AttributeValueType:'attributeValue',BlockType:'block',BracketsType:'brackets',ClassType:'class',CombinatorType:'combinator',CommentMLType:'multilineComment',CommentSLType:'singlelineComment',ConditionType:'condition',ConditionalStatementType:'conditionalStatement',DeclarationType:'declaration',DeclDelimType:'declarationDelimiter',DefaultType:'default',DelimType:'delimiter',DimensionType:'dimension',EscapedStringType:'escapedString',ExtendType:'extend',ExpressionType:'expression',FunctionType:'function',GlobalType:'global',IdentType:'ident',ImportantType:'important',IncludeType:'include',InterpolationType:'interpolation',InterpolatedVariableType:'interpolatedVariable',KeyframesSelectorType:'keyframesSelector',LoopType:'loop',MixinType:'mixin',NamePrefixType:'namePrefix',NamespacePrefixType:'namespacePrefix',NamespaceSeparatorType:'namespaceSeparator',NumberType:'number',OperatorType:'operator',OptionalType:'optional',ParenthesesType:'parentheses',ParentSelectorType:'parentSelector',ParentSelectorExtensionType:'parentSelectorExtension',PercentageType:'percentage',PlaceholderType:'placeholder',ProgidType:'progid',PropertyType:'property',PropertyDelimType:'propertyDelimiter',PseudocType:'pseudoClass',PseudoeType:'pseudoElement',RawType:'raw',RulesetType:'ruleset',SType:'space',SelectorType:'selector',ShashType:'id',StringType:'string',StylesheetType:'stylesheet',TypeSelectorType:'typeSelector',UriType:'uri',ValueType:'value',VariableType:'variable',VariablesListType:'variablesList',VhashType:'color'};},function(module,exports,__webpack_require__){'use strict';module.exports=function(css,tabSize){var TokenType=__webpack_require__(12);var tokens=[];var urlMode=false;var blockMode=0;var c=undefined;var cn=undefined;var pos=0;var tn=0;var ln=1;var col=1;var Punctuation={' ':TokenType.Space,'\n':TokenType.Newline,'\r':TokenType.Newline,'\t':TokenType.Tab,'!':TokenType.ExclamationMark,'"':TokenType.QuotationMark,'#':TokenType.NumberSign,'$':TokenType.DollarSign,'%':TokenType.PercentSign,'&':TokenType.Ampersand,'\'':TokenType.Apostrophe,'(':TokenType.LeftParenthesis,')':TokenType.RightParenthesis,'*':TokenType.Asterisk,'+':TokenType.PlusSign,',':TokenType.Comma,'-':TokenType.HyphenMinus,'.':TokenType.FullStop,'/':TokenType.Solidus,':':TokenType.Colon,';':TokenType.Semicolon,'<':TokenType.LessThanSign,'=':TokenType.EqualsSign,'==':TokenType.EqualitySign,'!=':TokenType.InequalitySign,'>':TokenType.GreaterThanSign,'?':TokenType.QuestionMark,'@':TokenType.CommercialAt,'[':TokenType.LeftSquareBracket,']':TokenType.RightSquareBracket,'^':TokenType.CircumflexAccent,'_':TokenType.LowLine,'{':TokenType.LeftCurlyBracket,'|':TokenType.VerticalLine,'}':TokenType.RightCurlyBracket,'~':TokenType.Tilde};function pushToken(type,value,column){tokens.push({tn:tn++,ln:ln,col:column,type:type,value:value});}
function isDecimalDigit(c){return'0123456789'.indexOf(c)>=0;}
function parseSpaces(css){var start=pos;for(;pos<css.length;pos++){if(css.charAt(pos)!==' ')break;}
pushToken(TokenType.Space,css.substring(start,pos--),col);col+=pos-start;}
function parseString(css,q){var start=pos;for(pos++;pos<css.length;pos++){if(css.charAt(pos)==='\\')pos++;else if(css.charAt(pos)===q)break;}
var type=q==='"'?TokenType.StringDQ:TokenType.StringSQ;pushToken(type,css.substring(start,pos+1),col);col+=pos-start;}
function parseDecimalNumber(css){var start=pos;for(;pos<css.length;pos++){if(!isDecimalDigit(css.charAt(pos)))break;}
pushToken(TokenType.DecimalNumber,css.substring(start,pos--),col);col+=pos-start;}
function parseIdentifier(css){var start=pos;while(css.charAt(pos)==='/')pos++;for(;pos<css.length;pos++){if(css.charAt(pos)==='\\')pos++;else if(css.charAt(pos)in Punctuation)break;}
var ident=css.substring(start,pos--);if(!urlMode&&ident==='url'&&css.charAt(pos+1)==='('){urlMode=true;}
pushToken(TokenType.Identifier,ident,col);col+=pos-start;}
function parseEquality(){pushToken(TokenType.EqualitySign,'==',col);pos++;col++;}
function parseInequality(){pushToken(TokenType.InequalitySign,'!=',col);pos++;col++;}
function parseMLComment(css){var start=pos;for(pos+=2;pos<css.length;pos++){if(css.charAt(pos)==='*'&&css.charAt(pos+1)==='/'){pos++;break;}}
var comment=css.substring(start,pos+1);pushToken(TokenType.CommentML,comment,col);var newlines=comment.split('\n');if(newlines.length>1){ln+=newlines.length-1;col=newlines[newlines.length-1].length;}else{col+=pos-start;}}
function parseSLComment(css){var start=pos;for(pos+=2;pos<css.length;pos++){if(css.charAt(pos)==='\n'||css.charAt(pos)==='\r'){break;}}
pushToken(TokenType.CommentSL,css.substring(start,pos--),col);col+=pos-start;}
function getTokens(css){for(pos=0;pos<css.length;col++,pos++){c=css.charAt(pos);cn=css.charAt(pos+1);if(c==='/'&&cn==='*'){parseMLComment(css);}
else if(!urlMode&&c==='/'&&cn==='/'){parseSLComment(css);}
else if(c==='"'||c==="'"){parseString(css,c);}
else if(c===' '){parseSpaces(css);}
else if(c==='='&&cn==='='){parseEquality(css);}
else if(c==='!'&&cn==='='){parseInequality(css);}
else if(c in Punctuation){if(c==='\r'&&cn==='\n'||c==='\n'){if(c==='\r'){pushToken(TokenType.Newline,'\r\n',col);pos++;}else if(c==='\n'){pushToken(Punctuation[c],c,col);}
ln++;col=0;}else if(c!=='\r'&&c!=='\n'){pushToken(Punctuation[c],c,col);}
if(c===')')urlMode=false;if(c==='{')blockMode++;if(c==='}')blockMode--;else if(c==='\t'&&tabSize>1)col+=tabSize-1;}
else if(isDecimalDigit(c)){parseDecimalNumber(css);}
else{parseIdentifier(css);}}
return tokens;}
return getTokens(css);};},function(module,exports,__webpack_require__){'use strict';var Node=__webpack_require__(1);var NodeTypes=__webpack_require__(14);module.exports=function(){return new Node({type:NodeTypes.StylesheetType,content:[],start:[0,0],end:[0,0]});};}])});;;WebInspector.SCSSParser=function()
{}
WebInspector.SCSSParser.prototype={parse:function(content)
{var ast=null;try{ast=gonzales.parse(content,{syntax:"scss"});}catch(e){return[];}
var rootBlock={properties:[],node:ast};var blocks=[rootBlock];ast.selectors=[];WebInspector.SCSSParser.extractNodes(ast,blocks,rootBlock);var rules=[];for(var block of blocks)
this._handleBlock(block,rules);return rules;},_handleBlock:function(block,output)
{var selectors=block.node.selectors.map(WebInspector.SCSSParser.rangeFromNode);var properties=[];var styleRange=WebInspector.SCSSParser.rangeFromNode(block.node);styleRange.startColumn+=1;styleRange.endColumn-=1;for(var node of block.properties){if(node.type==="declaration")
this._handleDeclaration(node,properties);else if(node.type==="include")
this._handleInclude(node,properties);else if(node.type==="multilineComment"&&node.start.line===node.end.line)
this._handleComment(node,properties);}
if(!selectors.length&&!properties.length)
return;var rule=new WebInspector.SCSSParser.Rule(selectors,properties,styleRange);output.push(rule);},_handleDeclaration:function(node,output)
{var propertyNode=node.content.find(node=>node.type==="property");var valueNode=node.content.find(node=>node.type==="value");if(!propertyNode||!valueNode)
return;var nameRange=WebInspector.SCSSParser.rangeFromNode(propertyNode);var valueRange=WebInspector.SCSSParser.rangeFromNode(valueNode);var range=(node.declarationRange);var property=new WebInspector.SCSSParser.Property(range,nameRange,valueRange,false);output.push(property);},_handleInclude:function(node,output)
{var mixinName=node.content.find(node=>node.type==="ident");if(!mixinName)
return;var nameRange=WebInspector.SCSSParser.rangeFromNode(mixinName);var mixinArguments=node.content.find(node=>node.type==="arguments");if(!mixinArguments)
return;var parameters=mixinArguments.content.filter(node=>node.type!=="delimiter"&&node.type!=="space");for(var parameter of parameters){var range=WebInspector.SCSSParser.rangeFromNode(node);var valueRange=WebInspector.SCSSParser.rangeFromNode(parameter);var property=new WebInspector.SCSSParser.Property(range,nameRange,valueRange,false);output.push(property);}},_handleComment:function(node,output)
{if(node.start.line!==node.end.line)
return;var innerText=(node.content);var innerResult=this.parse(innerText);if(innerResult.length!==1||innerResult[0].properties.length!==1)
return;var property=innerResult[0].properties[0];var disabledProperty=property.rebaseInsideOneLineComment(node);output.push(disabledProperty);},}
WebInspector.SCSSParser.rangeFromNode=function(node)
{return new WebInspector.TextRange(node.start.line-1,node.start.column-1,node.end.line-1,node.end.column);}
WebInspector.SCSSParser.Property=function(range,nameRange,valueRange,disabled)
{this.range=range;this.name=nameRange;this.value=valueRange;this.disabled=disabled;}
WebInspector.SCSSParser.Property.prototype={rebaseInsideOneLineComment:function(commentNode)
{var lineOffset=commentNode.start.line-1;var columnOffset=commentNode.start.column-1+2;var range=WebInspector.SCSSParser.rangeFromNode(commentNode);var name=rebaseRange(this.name,lineOffset,columnOffset);var value=rebaseRange(this.value,lineOffset,columnOffset);return new WebInspector.SCSSParser.Property(range,name,value,true);function rebaseRange(range,lineOffset,columnOffset)
{return new WebInspector.TextRange(range.startLine+lineOffset,range.startColumn+columnOffset,range.endLine+lineOffset,range.endColumn+columnOffset);}}}
WebInspector.SCSSParser.Rule=function(selectors,properties,styleRange)
{this.selectors=selectors;this.properties=properties;this.styleRange=styleRange;}
WebInspector.SCSSParser.extractNodes=function(node,blocks,lastBlock)
{if(!Array.isArray(node.content))
return;if(node.type==="block"){lastBlock={node:node,properties:[]};blocks.push(lastBlock);}
var lastDeclaration=null;var selectors=[];for(var i=0;i<node.content.length;++i){var child=node.content[i];if(child.type==="declarationDelimiter"&&lastDeclaration){lastDeclaration.declarationRange.endLine=child.end.line-1;lastDeclaration.declarationRange.endColumn=child.end.column;lastDeclaration=null;}else if(child.type==="selector"){selectors.push(child);}else if(child.type==="block"){child.selectors=selectors;selectors=[];}
if(child.type==="include"||child.type==="declaration"||child.type==="multilineComment")
lastBlock.properties.push(child);if(child.type==="declaration"){lastDeclaration=child;lastDeclaration.declarationRange=WebInspector.TextRange.createFromLocation(child.start.line-1,child.start.column-1);}
WebInspector.SCSSParser.extractNodes(child,blocks,lastBlock);}
if(lastDeclaration){lastDeclaration.declarationRange.endLine=node.end.line-1;lastDeclaration.declarationRange.endColumn=node.end.column-1;}};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var allDescriptors=[{"name":"heap_snapshot_worker","scripts":[]}];var applicationDescriptor;var _loadedScripts={};for(var k of[]){};function loadResourcePromise(url)
{return new Promise(load);function load(fulfill,reject)
{var xhr=new XMLHttpRequest();xhr.open("GET",url,true);xhr.onreadystatechange=onreadystatechange;function onreadystatechange(e)
{if(xhr.readyState!==4)
return;if([0,200,304].indexOf(xhr.status)===-1)
reject(new Error("While loading from url "+url+" server responded with a status of "+xhr.status));else
fulfill(e.target.response);}
xhr.send(null);}}
function normalizePath(path)
{if(path.indexOf("..")===-1&&path.indexOf(".")===-1)
return path;var normalizedSegments=[];var segments=path.split("/");for(var i=0;i<segments.length;i++){var segment=segments[i];if(segment===".")
continue;else if(segment==="..")
normalizedSegments.pop();else if(segment)
normalizedSegments.push(segment);}
var normalizedPath=normalizedSegments.join("/");if(normalizedPath[normalizedPath.length-1]==="/")
return normalizedPath;if(path[0]==="/"&&normalizedPath)
normalizedPath="/"+normalizedPath;if((path[path.length-1]==="/")||(segments[segments.length-1]===".")||(segments[segments.length-1]===".."))
normalizedPath=normalizedPath+"/";return normalizedPath;}
function loadScriptsPromise(scriptNames,base)
{var promises=[];var urls=[];var sources=new Array(scriptNames.length);var scriptToEval=0;for(var i=0;i<scriptNames.length;++i){var scriptName=scriptNames[i];var sourceURL=(base||self._importScriptPathPrefix)+scriptName;var schemaIndex=sourceURL.indexOf("://")+3;var pathIndex=sourceURL.indexOf("/",schemaIndex);if(pathIndex===-1)
pathIndex=sourceURL.length;sourceURL=sourceURL.substring(0,pathIndex)+normalizePath(sourceURL.substring(pathIndex));if(_loadedScripts[sourceURL])
continue;urls.push(sourceURL);promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null,i),scriptSourceLoaded.bind(null,i,undefined)));}
return Promise.all(promises).then(undefined);function scriptSourceLoaded(scriptNumber,scriptSource)
{sources[scriptNumber]=scriptSource||"";while(typeof sources[scriptToEval]!=="undefined"){evaluateScript(urls[scriptToEval],sources[scriptToEval]);++scriptToEval;}}
function evaluateScript(sourceURL,scriptSource)
{_loadedScripts[sourceURL]=true;if(!scriptSource){console.error("Empty response arrived for script '"+sourceURL+"'");return;}
self.eval(scriptSource+"\n//# sourceURL="+sourceURL);}}
(function(){var baseUrl=self.location?self.location.origin+self.location.pathname:"";self._importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf("/")+1);})();function Runtime(descriptors)
{this._modules=[];this._modulesMap={};this._extensions=[];this._cachedTypeClasses={};this._descriptorsMap={};for(var i=0;i<descriptors.length;++i)
this._registerModule(descriptors[i]);}
Runtime._queryParamsObject={__proto__:null};Runtime.cachedResources={__proto__:null};Runtime.isReleaseMode=function()
{return!!allDescriptors.length;}
Runtime.startApplication=function(appName)
{console.timeStamp("Runtime.startApplication");var allDescriptorsByName={};for(var i=0;Runtime.isReleaseMode()&&i<allDescriptors.length;++i){var d=allDescriptors[i];allDescriptorsByName[d["name"]]=d;}
var applicationPromise;if(applicationDescriptor)
applicationPromise=Promise.resolve(applicationDescriptor);else
applicationPromise=loadResourcePromise(appName+".json").then(JSON.parse.bind(JSON));return applicationPromise.then(parseModuleDescriptors);function parseModuleDescriptors(appDescriptor)
{var configuration=appDescriptor.modules;var moduleJSONPromises=[];var coreModuleNames=[];for(var i=0;i<configuration.length;++i){var descriptor=configuration[i];var name=descriptor["name"];var moduleJSON=allDescriptorsByName[name];if(moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));else
moduleJSONPromises.push(loadResourcePromise(name+"/module.json").then(JSON.parse.bind(JSON)));if(descriptor["type"]==="autostart")
coreModuleNames.push(name);}
return Promise.all(moduleJSONPromises).then(instantiateRuntime);function instantiateRuntime(moduleDescriptors)
{for(var i=0;!Runtime.isReleaseMode()&&i<moduleDescriptors.length;++i){moduleDescriptors[i]["name"]=configuration[i]["name"];moduleDescriptors[i]["condition"]=configuration[i]["condition"];}
self.runtime=new Runtime(moduleDescriptors);if(coreModuleNames)
return(self.runtime._loadAutoStartModules(coreModuleNames));return Promise.resolve();}}}
Runtime.startWorker=function(appName)
{return Runtime.startApplication(appName).then(sendWorkerReady);function sendWorkerReady()
{self.postMessage("workerReady");}}
Runtime._sharedWorkerNewPortCallback=null;Runtime._sharedWorkerConnectedPorts=[];Runtime.startSharedWorker=function(appName)
{var startPromise=Runtime.startApplication(appName);self.onconnect=function(event)
{var newPort=(event.ports[0]);startPromise.then(sendWorkerReadyAndContinue);function sendWorkerReadyAndContinue()
{newPort.postMessage("workerReady");if(Runtime._sharedWorkerNewPortCallback)
Runtime._sharedWorkerNewPortCallback.call(null,newPort);else
Runtime._sharedWorkerConnectedPorts.push(newPort);}}}
Runtime.setSharedWorkerNewPortCallback=function(callback)
{Runtime._sharedWorkerNewPortCallback=callback;while(Runtime._sharedWorkerConnectedPorts.length){var port=Runtime._sharedWorkerConnectedPorts.shift();callback.call(null,port);}}
Runtime.queryParam=function(name)
{return Runtime._queryParamsObject[name]||null;}
Runtime.constructQueryParams=function(banned)
{var params=[];for(var key in Runtime._queryParamsObject){if(!key||banned.indexOf(key)!==-1)
continue;params.push(key+"="+Runtime._queryParamsObject[key]);}
return params.length?"?"+params.join("&"):"";}
Runtime._experimentsSetting=function()
{try{return(JSON.parse(self.localStorage&&self.localStorage["experiments"]?self.localStorage["experiments"]:"{}"));}catch(e){console.error("Failed to parse localStorage['experiments']");return{};}}
Runtime._some=function(promises)
{var all=[];var wasRejected=[];for(var i=0;i<promises.length;++i){var handlerFunction=(handler.bind(promises[i],i));all.push(promises[i].catch(handlerFunction));}
return Promise.all(all).then(filterOutFailuresResults);function filterOutFailuresResults(results)
{var filtered=[];for(var i=0;i<results.length;++i){if(!wasRejected[i])
filtered.push(results[i]);}
return filtered;}
function handler(index,e)
{wasRejected[index]=true;console.error(e.stack);}}
Runtime._console=console;Runtime._originalAssert=console.assert;Runtime._assert=function(value,message)
{if(value)
return;Runtime._originalAssert.call(Runtime._console,value,message+" "+new Error().stack);}
Runtime.prototype={useTestBase:function()
{Runtime._remoteBase="http://localhost:8000/inspector-sources/";},_registerModule:function(descriptor)
{var module=new Runtime.Module(this,descriptor);this._modules.push(module);this._modulesMap[descriptor["name"]]=module;},loadModulePromise:function(moduleName)
{return this._modulesMap[moduleName]._loadPromise();},_loadAutoStartModules:function(moduleNames)
{var promises=[];for(var i=0;i<moduleNames.length;++i){if(Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded=true;else
promises.push(this.loadModulePromise(moduleNames[i]));}
return Promise.all(promises);},_checkExtensionApplicability:function(extension,predicate)
{if(!predicate)
return false;var contextTypes=(extension.descriptor().contextTypes);if(!contextTypes)
return true;for(var i=0;i<contextTypes.length;++i){var contextType=this._resolve(contextTypes[i]);var isMatching=!!contextType&&predicate(contextType);if(isMatching)
return true;}
return false;},isExtensionApplicableToContext:function(extension,context)
{if(!context)
return true;return this._checkExtensionApplicability(extension,isInstanceOf);function isInstanceOf(targetType)
{return context instanceof targetType;}},isExtensionApplicableToContextTypes:function(extension,currentContextTypes)
{if(!extension.descriptor().contextTypes)
return true;return this._checkExtensionApplicability(extension,currentContextTypes?isContextTypeKnown:null);function isContextTypeKnown(targetType)
{return currentContextTypes.has(targetType);}},extensions:function(type,context)
{return this._extensions.filter(filter).sort(orderComparator);function filter(extension)
{if(extension._type!==type&&extension._typeClass()!==type)
return false;if(!extension.enabled())
return false;return!context||extension.isApplicable(context);}
function orderComparator(extension1,extension2)
{var order1=extension1.descriptor()["order"]||0;var order2=extension2.descriptor()["order"]||0;return order1-order2;}},extension:function(type,context)
{return this.extensions(type,context)[0]||null;},instancesPromise:function(type,context)
{var extensions=this.extensions(type,context);var promises=[];for(var i=0;i<extensions.length;++i)
promises.push(extensions[i].instancePromise());return Runtime._some(promises);},instancePromise:function(type,context)
{var extension=this.extension(type,context);if(!extension)
return Promise.reject(new Error("No such extension: "+type+" in given context."));return extension.instancePromise();},_resolve:function(typeName)
{if(!this._cachedTypeClasses[typeName]){var path=typeName.split(".");var object=self;for(var i=0;object&&(i<path.length);++i)
object=object[path[i]];if(object)
this._cachedTypeClasses[typeName]=(object);}
return this._cachedTypeClasses[typeName]||null;}}
Runtime.ModuleDescriptor=function()
{this.name;this.extensions;this.dependencies;this.scripts;this.remote;}
Runtime.ExtensionDescriptor=function()
{this.type;this.className;this.contextTypes;}
Runtime.Module=function(manager,descriptor)
{this._manager=manager;this._descriptor=descriptor;this._name=descriptor.name;this._instanceMap={};var extensions=(descriptor.extensions);for(var i=0;extensions&&i<extensions.length;++i)
this._manager._extensions.push(new Runtime.Extension(this,extensions[i]));this._loaded=false;}
Runtime.Module.prototype={name:function()
{return this._name;},enabled:function()
{return Runtime._isDescriptorEnabled(this._descriptor);},resource:function(name)
{var fullName=this._name+"/"+name;var content=Runtime.cachedResources[fullName];if(!content)
throw new Error(fullName+" not preloaded. Check module.json");return content;},_loadPromise:function()
{if(this._loaded)
return Promise.resolve();if(!this.enabled())
return Promise.reject(new Error("Module "+this._name+" is not enabled"));if(this._pendingLoadPromise)
return this._pendingLoadPromise;var dependencies=this._descriptor.dependencies;var dependencyPromises=[];for(var i=0;dependencies&&i<dependencies.length;++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());this._pendingLoadPromise=Promise.all(dependencyPromises).then(this._loadResources.bind(this)).then(this._loadScripts.bind(this)).then(markAsLoaded.bind(this));return this._pendingLoadPromise;function markAsLoaded()
{delete this._pendingLoadPromise;this._loaded=true;}},_loadResources:function()
{var resources=this._descriptor["resources"];if(!resources)
return Promise.resolve();var promises=[];for(var i=0;i<resources.length;++i){var url=this._modularizeURL(resources[i]);promises.push(loadResourcePromise(url).then(cacheResource.bind(this,url),cacheResource.bind(this,url,undefined)));}
return Promise.all(promises).then(undefined);function cacheResource(path,content)
{if(!content){console.error("Failed to load resource: "+path);return;}
Runtime.cachedResources[path]=content+Runtime.resolveSourceURL(path);}},_loadScripts:function()
{if(!this._descriptor.scripts)
return Promise.resolve();if(Runtime.isReleaseMode())
return loadScriptsPromise([this._name+"_module.js"],this._remoteBase());return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL,this));},_modularizeURL:function(resourceName)
{return normalizePath(this._name+"/"+resourceName);},_remoteBase:function()
{return this._descriptor.remote&&Runtime._remoteBase||undefined;},substituteURL:function(value)
{var base=this._remoteBase()||"";return value.replace(/@url\(([^\)]*?)\)/g,convertURL.bind(this));function convertURL(match,url)
{return base+this._modularizeURL(url);}},_instance:function(className,extension)
{if(className in this._instanceMap)
return this._instanceMap[className];var constructorFunction=self.eval(className);if(!(constructorFunction instanceof Function)){this._instanceMap[className]=null;return null;}
var instance=new constructorFunction(extension);this._instanceMap[className]=instance;return instance;}}
Runtime._isDescriptorEnabled=function(descriptor)
{var activatorExperiment=descriptor["experiment"];if(activatorExperiment&&activatorExperiment.startsWith("!")&&Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;if(activatorExperiment&&!activatorExperiment.startsWith("!")&&!Runtime.experiments.isEnabled(activatorExperiment))
return false;var condition=descriptor["condition"];if(condition&&!condition.startsWith("!")&&!Runtime.queryParam(condition))
return false;if(condition&&condition.startsWith("!")&&Runtime.queryParam(condition.substring(1)))
return false;return true;}
Runtime.Extension=function(module,descriptor)
{this._module=module;this._descriptor=descriptor;this._type=descriptor.type;this._hasTypeClass=this._type.charAt(0)==="@";this._className=descriptor.className||null;}
Runtime.Extension.prototype={descriptor:function()
{return this._descriptor;},module:function()
{return this._module;},enabled:function()
{return this._module.enabled()&&Runtime._isDescriptorEnabled(this.descriptor());},_typeClass:function()
{if(!this._hasTypeClass)
return null;return this._module._manager._resolve(this._type.substring(1));},isApplicable:function(context)
{return this._module._manager.isExtensionApplicableToContext(this,context);},instancePromise:function()
{if(!this._className)
return Promise.reject(new Error("No class name in extension"));var className=this._className;if(this._instance)
return Promise.resolve(this._instance);return this._module._loadPromise().then(constructInstance.bind(this));function constructInstance()
{var result=this._module._instance(className,this);if(!result)
return Promise.reject("Could not instantiate: "+className);return result;}},title:function(platform)
{return this._descriptor["title-"+platform]||this._descriptor["title"];}}
Runtime.ExperimentsSupport=function()
{this._supportEnabled=Runtime.queryParam("experiments")!==null;this._experiments=[];this._experimentNames={};this._enabledTransiently={};}
Runtime.ExperimentsSupport.prototype={allConfigurableExperiments:function()
{var result=[];for(var i=0;i<this._experiments.length;i++){var experiment=this._experiments[i];if(!this._enabledTransiently[experiment.name])
result.push(experiment);}
return result;},supportEnabled:function()
{return this._supportEnabled;},_setExperimentsSetting:function(value)
{if(!self.localStorage)
return;self.localStorage["experiments"]=JSON.stringify(value);},register:function(experimentName,experimentTitle,hidden)
{Runtime._assert(!this._experimentNames[experimentName],"Duplicate registration of experiment "+experimentName);this._experimentNames[experimentName]=true;this._experiments.push(new Runtime.Experiment(this,experimentName,experimentTitle,!!hidden));},isEnabled:function(experimentName)
{this._checkExperiment(experimentName);if(this._enabledTransiently[experimentName])
return true;if(!this.supportEnabled())
return false;return!!Runtime._experimentsSetting()[experimentName];},setEnabled:function(experimentName,enabled)
{this._checkExperiment(experimentName);var experimentsSetting=Runtime._experimentsSetting();experimentsSetting[experimentName]=enabled;this._setExperimentsSetting(experimentsSetting);},setDefaultExperiments:function(experimentNames)
{for(var i=0;i<experimentNames.length;++i){this._checkExperiment(experimentNames[i]);this._enabledTransiently[experimentNames[i]]=true;}},enableForTest:function(experimentName)
{this._checkExperiment(experimentName);this._enabledTransiently[experimentName]=true;},clearForTest:function()
{this._experiments=[];this._experimentNames={};this._enabledTransiently={};},cleanUpStaleExperiments:function()
{var experimentsSetting=Runtime._experimentsSetting();var cleanedUpExperimentSetting={};for(var i=0;i<this._experiments.length;++i){var experimentName=this._experiments[i].name;if(experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName]=true;}
this._setExperimentsSetting(cleanedUpExperimentSetting);},_checkExperiment:function(experimentName)
{Runtime._assert(this._experimentNames[experimentName],"Unknown experiment "+experimentName);}}
Runtime.Experiment=function(experiments,name,title,hidden)
{this.name=name;this.title=title;this.hidden=hidden;this._experiments=experiments;}
Runtime.Experiment.prototype={isEnabled:function()
{return this._experiments.isEnabled(this.name);},setEnabled:function(enabled)
{this._experiments.setEnabled(this.name,enabled);}}
{(function parseQueryParameters()
{var queryParams=location.search;if(!queryParams)
return;var params=queryParams.substring(1).split("&");for(var i=0;i<params.length;++i){var pair=params[i].split("=");var name=pair.shift();Runtime._queryParamsObject[name]=pair.join("=");}})();}
Runtime.experiments=new Runtime.ExperimentsSupport();Runtime._remoteBase=Runtime.queryParam("remoteBase");{(function validateRemoteBase()
{var remoteBaseRegexp=/^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/;if(Runtime._remoteBase&&!remoteBaseRegexp.test(Runtime._remoteBase))
Runtime._remoteBase=null;})();}
Runtime.resolveSourceURL=function(path)
{var sourceURL=self.location.href;if(self.location.search)
sourceURL=sourceURL.replace(self.location.search,"");sourceURL=sourceURL.substring(0,sourceURL.lastIndexOf("/")+1)+path;return"\n/*# sourceURL="+sourceURL+" */";}
var runtime;console=console;console.__originalAssert=console.assert;console.assert=function(value,message)
{if(value)
return;console.__originalAssert(value,message);}
var ArrayLike;Object.isEmpty=function(obj)
{for(var i in obj)
return false;return true;}
Object.values=function(obj)
{var result=Object.keys(obj);var length=result.length;for(var i=0;i<length;++i)
result[i]=obj[result[i]];return result;}
function mod(m,n)
{return((m%n)+n)%n;}
String.prototype.findAll=function(string)
{var matches=[];var i=this.indexOf(string);while(i!==-1){matches.push(i);i=this.indexOf(string,i+string.length);}
return matches;}
String.prototype.replaceControlCharacters=function()
{return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g,"�");}
String.prototype.isWhitespace=function()
{return/^\s*$/.test(this);}
String.prototype.computeLineEndings=function()
{var endings=this.findAll("\n");endings.push(this.length);return endings;}
String.prototype.escapeCharacters=function(chars)
{var foundChar=false;for(var i=0;i<chars.length;++i){if(this.indexOf(chars.charAt(i))!==-1){foundChar=true;break;}}
if(!foundChar)
return String(this);var result="";for(var i=0;i<this.length;++i){if(chars.indexOf(this.charAt(i))!==-1)
result+="\\";result+=this.charAt(i);}
return result;}
String.regexSpecialCharacters=function()
{return"^[]{}()\\.^$*+?|-,";}
String.prototype.escapeForRegExp=function()
{return this.escapeCharacters(String.regexSpecialCharacters());}
String.prototype.escapeHTML=function()
{return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");}
String.prototype.unescapeHTML=function()
{return this.replace(/</g,"<").replace(/>/g,">").replace(/:/g,":").replace(/"/g,"\"").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");}
String.prototype.collapseWhitespace=function()
{return this.replace(/[\s\xA0]+/g," ");}
String.prototype.trimMiddle=function(maxLength)
{if(this.length<=maxLength)
return String(this);var leftHalf=maxLength>>1;var rightHalf=maxLength-leftHalf-1;return this.substr(0,leftHalf)+"\u2026"+this.substr(this.length-rightHalf,rightHalf);}
String.prototype.trimEnd=function(maxLength)
{if(this.length<=maxLength)
return String(this);return this.substr(0,maxLength-1)+"\u2026";}
String.prototype.trimURL=function(baseURLDomain)
{var result=this.replace(/^(https|http|file):\/\//i,"");if(baseURLDomain){if(result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
result=result.substr(baseURLDomain.length);}
return result;}
String.prototype.toTitleCase=function()
{return this.substring(0,1).toUpperCase()+this.substring(1);}
String.prototype.compareTo=function(other)
{if(this>other)
return 1;if(this<other)
return-1;return 0;}
String.prototype.removeURLFragment=function()
{var fragmentIndex=this.indexOf("#");if(fragmentIndex==-1)
fragmentIndex=this.length;return this.substring(0,fragmentIndex);}
String.hashCode=function(string)
{if(!string)
return 0;var p=((1<<30)*4-5);var z=0x5033d967;var z2=0x59d2f15d;var s=0;var zi=1;for(var i=0;i<string.length;i++){var xi=string.charCodeAt(i)*z2;s=(s+zi*xi)%p;zi=(zi*z)%p;}
s=(s+zi*(p-1))%p;return Math.abs(s|0);}
String.isDigitAt=function(string,index)
{var c=string.charCodeAt(index);return(48<=c&&c<=57);}
String.prototype.toBase64=function()
{function encodeBits(b)
{return b<26?b+65:b<52?b+71:b<62?b-4:b===62?43:b===63?47:65;}
var encoder=new TextEncoder();var data=encoder.encode(this.toString());var n=data.length;var encoded="";if(n===0)
return encoded;var shift;var v=0;for(var i=0;i<n;i++){shift=i%3;v|=data[i]<<(16>>>shift&24);if(shift===2){encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),encodeBits(v&63));v=0;}}
if(shift===0)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),61,61);else if(shift===1)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),61);return encoded;}
String.naturalOrderComparator=function(a,b)
{var chunk=/^\d+|^\D+/;var chunka,chunkb,anum,bnum;while(1){if(a){if(!b)
return 1;}else{if(b)
return-1;else
return 0;}
chunka=a.match(chunk)[0];chunkb=b.match(chunk)[0];anum=!isNaN(chunka);bnum=!isNaN(chunkb);if(anum&&!bnum)
return-1;if(bnum&&!anum)
return 1;if(anum&&bnum){var diff=chunka-chunkb;if(diff)
return diff;if(chunka.length!==chunkb.length){if(!+chunka&&!+chunkb)
return chunka.length-chunkb.length;else
return chunkb.length-chunka.length;}}else if(chunka!==chunkb)
return(chunka<chunkb)?-1:1;a=a.substring(chunka.length);b=b.substring(chunkb.length);}}
String.caseInsensetiveComparator=function(a,b)
{a=a.toUpperCase();b=b.toUpperCase();if(a===b)
return 0;return a>b?1:-1;}
Number.constrain=function(num,min,max)
{if(num<min)
num=min;else if(num>max)
num=max;return num;}
Number.gcd=function(a,b)
{if(b===0)
return a;else
return Number.gcd(b,a%b);}
Number.toFixedIfFloating=function(value)
{if(!value||isNaN(value))
return value;var number=Number(value);return number%1?number.toFixed(3):String(number);}
Date.prototype.toISO8601Compact=function()
{function leadZero(x)
{return(x>9?"":"0")+x;}
return this.getFullYear()+
leadZero(this.getMonth()+1)+
leadZero(this.getDate())+"T"+
leadZero(this.getHours())+
leadZero(this.getMinutes())+
leadZero(this.getSeconds());}
Date.prototype.toConsoleTime=function()
{function leadZero2(x)
{return(x>9?"":"0")+x;}
function leadZero3(x)
{return"0".repeat(3-x.toString().length)+x;}
return this.getFullYear()+"-"+
leadZero2(this.getMonth()+1)+"-"+
leadZero2(this.getDate())+" "+
leadZero2(this.getHours())+":"+
leadZero2(this.getMinutes())+":"+
leadZero2(this.getSeconds())+"."+
leadZero3(this.getMilliseconds());}
Object.defineProperty(Array.prototype,"remove",{value:function(value,firstOnly)
{var index=this.indexOf(value);if(index===-1)
return false;if(firstOnly){this.splice(index,1);return true;}
for(var i=index+1,n=this.length;i<n;++i){if(this[i]!==value)
this[index++]=this[i];}
this.length=index;return true;}});Object.defineProperty(Array.prototype,"keySet",{value:function()
{var keys={};for(var i=0;i<this.length;++i)
keys[this[i]]=true;return keys;}});Object.defineProperty(Array.prototype,"pushAll",{value:function(array)
{Array.prototype.push.apply(this,array);}});Object.defineProperty(Array.prototype,"rotate",{value:function(index)
{var result=[];for(var i=index;i<index+this.length;++i)
result.push(this[i%this.length]);return result;}});Object.defineProperty(Array.prototype,"sortNumbers",{value:function()
{function numericComparator(a,b)
{return a-b;}
this.sort(numericComparator);}});Object.defineProperty(Uint32Array.prototype,"sort",{value:Array.prototype.sort});(function(){var partition={value:function(comparator,left,right,pivotIndex)
{function swap(array,i1,i2)
{var temp=array[i1];array[i1]=array[i2];array[i2]=temp;}
var pivotValue=this[pivotIndex];swap(this,right,pivotIndex);var storeIndex=left;for(var i=left;i<right;++i){if(comparator(this[i],pivotValue)<0){swap(this,storeIndex,i);++storeIndex;}}
swap(this,right,storeIndex);return storeIndex;}};Object.defineProperty(Array.prototype,"partition",partition);Object.defineProperty(Uint32Array.prototype,"partition",partition);var sortRange={value:function(comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight)
{function quickSortRange(array,comparator,left,right,sortWindowLeft,sortWindowRight)
{if(right<=left)
return;var pivotIndex=Math.floor(Math.random()*(right-left))+left;var pivotNewIndex=array.partition(comparator,left,right,pivotIndex);if(sortWindowLeft<pivotNewIndex)
quickSortRange(array,comparator,left,pivotNewIndex-1,sortWindowLeft,sortWindowRight);if(pivotNewIndex<sortWindowRight)
quickSortRange(array,comparator,pivotNewIndex+1,right,sortWindowLeft,sortWindowRight);}
if(leftBound===0&&rightBound===(this.length-1)&&sortWindowLeft===0&&sortWindowRight>=rightBound)
this.sort(comparator);else
quickSortRange(this,comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight);return this;}}
Object.defineProperty(Array.prototype,"sortRange",sortRange);Object.defineProperty(Uint32Array.prototype,"sortRange",sortRange);})();Object.defineProperty(Array.prototype,"stableSort",{value:function(comparator)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var indices=new Array(this.length);for(var i=0;i<this.length;++i)
indices[i]=i;var self=this;function indexComparator(a,b)
{var result=comparator(self[a],self[b]);return result?result:a-b;}
indices.sort(indexComparator);for(var i=0;i<this.length;++i){if(indices[i]<0||i===indices[i])
continue;var cyclical=i;var saved=this[i];while(true){var next=indices[cyclical];indices[cyclical]=-1;if(next===i){this[cyclical]=saved;break;}else{this[cyclical]=this[next];cyclical=next;}}}
return this;}});Object.defineProperty(Array.prototype,"qselect",{value:function(k,comparator)
{if(k<0||k>=this.length)
return;if(!comparator)
comparator=function(a,b){return a-b;}
var low=0;var high=this.length-1;for(;;){var pivotPosition=this.partition(comparator,low,high,Math.floor((high+low)/2));if(pivotPosition===k)
return this[k];else if(pivotPosition>k)
high=pivotPosition-1;else
low=pivotPosition+1;}}});Object.defineProperty(Array.prototype,"lowerBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Array.prototype,"upperBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>=0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Uint32Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Uint32Array.prototype,"upperBound",{value:Array.prototype.upperBound});Object.defineProperty(Float64Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Array.prototype,"binaryIndexOf",{value:function(value,comparator)
{var index=this.lowerBound(value,comparator);return index<this.length&&comparator(value,this[index])===0?index:-1;}});Object.defineProperty(Array.prototype,"select",{value:function(field)
{var result=new Array(this.length);for(var i=0;i<this.length;++i)
result[i]=this[i][field];return result;}});Object.defineProperty(Array.prototype,"peekLast",{value:function()
{return this[this.length-1];}});(function(){function mergeOrIntersect(array1,array2,comparator,mergeNotIntersect)
{var result=[];var i=0;var j=0;while(i<array1.length&&j<array2.length){var compareValue=comparator(array1[i],array2[j]);if(mergeNotIntersect||!compareValue)
result.push(compareValue<=0?array1[i]:array2[j]);if(compareValue<=0)
i++;if(compareValue>=0)
j++;}
if(mergeNotIntersect){while(i<array1.length)
result.push(array1[i++]);while(j<array2.length)
result.push(array2[j++]);}
return result;}
Object.defineProperty(Array.prototype,"intersectOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,false);}});Object.defineProperty(Array.prototype,"mergeOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,true);}});})();String.sprintf=function(format,var_arg)
{return String.vsprintf(format,Array.prototype.slice.call(arguments,1));}
String.tokenizeFormatString=function(format,formatters)
{var tokens=[];var substitutionIndex=0;function addStringToken(str)
{if(tokens.length&&tokens[tokens.length-1].type==="string")
tokens[tokens.length-1].value+=str;else
tokens.push({type:"string",value:str});}
function addSpecifierToken(specifier,precision,substitutionIndex)
{tokens.push({type:"specifier",specifier:specifier,precision:precision,substitutionIndex:substitutionIndex});}
var index=0;for(var precentIndex=format.indexOf("%",index);precentIndex!==-1;precentIndex=format.indexOf("%",index)){if(format.length===index)
break;addStringToken(format.substring(index,precentIndex));index=precentIndex+1;if(format[index]==="%"){addStringToken("%");++index;continue;}
if(String.isDigitAt(format,index)){var number=parseInt(format.substring(index),10);while(String.isDigitAt(format,index))
++index;if(number>0&&format[index]==="$"){substitutionIndex=(number-1);++index;}}
var precision=-1;if(format[index]==="."){++index;precision=parseInt(format.substring(index),10);if(isNaN(precision))
precision=0;while(String.isDigitAt(format,index))
++index;}
if(!(format[index]in formatters)){addStringToken(format.substring(precentIndex,index+1));++index;continue;}
addSpecifierToken(format[index],precision,substitutionIndex);++substitutionIndex;++index;}
addStringToken(format.substring(index));return tokens;}
String.standardFormatters={d:function(substitution)
{return!isNaN(substitution)?substitution:0;},f:function(substitution,token)
{if(substitution&&token.precision>-1)
substitution=substitution.toFixed(token.precision);return!isNaN(substitution)?substitution:(token.precision>-1?Number(0).toFixed(token.precision):0);},s:function(substitution)
{return substitution;}}
String.vsprintf=function(format,substitutions)
{return String.format(format,substitutions,String.standardFormatters,"",function(a,b){return a+b;}).formattedResult;}
String.format=function(format,substitutions,formatters,initialValue,append,tokenizedFormat)
{if(!format||!substitutions||!substitutions.length)
return{formattedResult:append(initialValue,format),unusedSubstitutions:substitutions};function prettyFunctionName()
{return"String.format(\""+format+"\", \""+Array.prototype.join.call(substitutions,"\", \"")+"\")";}
function warn(msg)
{console.warn(prettyFunctionName()+": "+msg);}
function error(msg)
{console.error(prettyFunctionName()+": "+msg);}
var result=initialValue;var tokens=tokenizedFormat||String.tokenizeFormatString(format,formatters);var usedSubstitutionIndexes={};for(var i=0;i<tokens.length;++i){var token=tokens[i];if(token.type==="string"){result=append(result,token.value);continue;}
if(token.type!=="specifier"){error("Unknown token type \""+token.type+"\" found.");continue;}
if(token.substitutionIndex>=substitutions.length){error("not enough substitution arguments. Had "+substitutions.length+" but needed "+(token.substitutionIndex+1)+", so substitution was skipped.");result=append(result,"%"+(token.precision>-1?token.precision:"")+token.specifier);continue;}
usedSubstitutionIndexes[token.substitutionIndex]=true;if(!(token.specifier in formatters)){warn("unsupported format character \u201C"+token.specifier+"\u201D. Treating as a string.");result=append(result,substitutions[token.substitutionIndex]);continue;}
result=append(result,formatters[token.specifier](substitutions[token.substitutionIndex],token));}
var unusedSubstitutions=[];for(var i=0;i<substitutions.length;++i){if(i in usedSubstitutionIndexes)
continue;unusedSubstitutions.push(substitutions[i]);}
return{formattedResult:result,unusedSubstitutions:unusedSubstitutions};}
function createSearchRegex(query,caseSensitive,isRegex)
{var regexFlags=caseSensitive?"g":"gi";var regexObject;if(isRegex){try{regexObject=new RegExp(query,regexFlags);}catch(e){}}
if(!regexObject)
regexObject=createPlainTextSearchRegex(query,regexFlags);return regexObject;}
function createPlainTextSearchRegex(query,flags)
{var regexSpecialCharacters=String.regexSpecialCharacters();var regex="";for(var i=0;i<query.length;++i){var c=query.charAt(i);if(regexSpecialCharacters.indexOf(c)!=-1)
regex+="\\";regex+=c;}
return new RegExp(regex,flags||"");}
function countRegexMatches(regex,content)
{var text=content;var result=0;var match;while(text&&(match=regex.exec(text))){if(match[0].length>0)
++result;text=text.substring(match.index+1);}
return result;}
function spacesPadding(spacesCount)
{return"\u00a0".repeat(spacesCount);}
function numberToStringWithSpacesPadding(value,symbolsCount)
{var numberString=value.toString();var paddingLength=Math.max(0,symbolsCount-numberString.length);return spacesPadding(paddingLength)+numberString;}
Set.prototype.valuesArray=function()
{return Array.from(this.values());}
Set.prototype.addAll=function(iterable)
{for(var e of iterable)
this.add(e);}
Set.prototype.containsAll=function(iterable)
{for(var e of iterable){if(!this.has(e))
return false;}
return true;}
Map.prototype.remove=function(key)
{var value=this.get(key);this.delete(key);return value;}
Map.prototype.valuesArray=function()
{return Array.from(this.values());}
Map.prototype.keysArray=function()
{return Array.from(this.keys());}
Map.prototype.inverse=function()
{var result=new Multimap();for(var key of this.keys()){var value=this.get(key);result.set(value,key);}
return result;}
var Multimap=function()
{this._map=new Map();}
Multimap.prototype={set:function(key,value)
{var set=this._map.get(key);if(!set){set=new Set();this._map.set(key,set);}
set.add(value);},get:function(key)
{var result=this._map.get(key);if(!result)
result=new Set();return result;},has:function(key)
{return this._map.has(key);},hasValue:function(key,value)
{var set=this._map.get(key);if(!set)
return false;return set.has(value);},get size()
{return this._map.size;},remove:function(key,value)
{var values=this.get(key);values.delete(value);if(!values.size)
this._map.delete(key);},removeAll:function(key)
{this._map.delete(key);},keysArray:function()
{return this._map.keysArray();},valuesArray:function()
{var result=[];var keys=this.keysArray();for(var i=0;i<keys.length;++i)
result.pushAll(this.get(keys[i]).valuesArray());return result;},clear:function()
{this._map.clear();}}
function loadXHR(url)
{return new Promise(load);function load(successCallback,failureCallback)
{function onReadyStateChanged()
{if(xhr.readyState!==XMLHttpRequest.DONE)
return;if(xhr.status!==200){xhr.onreadystatechange=null;failureCallback(new Error(xhr.status));return;}
xhr.onreadystatechange=null;successCallback(xhr.responseText);}
var xhr=new XMLHttpRequest();xhr.withCredentials=false;xhr.open("GET",url,true);xhr.onreadystatechange=onReadyStateChanged;xhr.send(null);}}
function CallbackBarrier()
{this._pendingIncomingCallbacksCount=0;}
CallbackBarrier.prototype={createCallback:function(userCallback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");++this._pendingIncomingCallbacksCount;return this._incomingCallback.bind(this,userCallback);},callWhenDone:function(callback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.callWhenDone() is called multiple times");this._outgoingCallback=callback;if(!this._pendingIncomingCallbacksCount)
this._outgoingCallback();},donePromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callWhenDone(success);}},_incomingCallback:function(userCallback)
{console.assert(this._pendingIncomingCallbacksCount>0);if(userCallback){var args=Array.prototype.slice.call(arguments,1);userCallback.apply(null,args);}
if(!--this._pendingIncomingCallbacksCount&&this._outgoingCallback)
this._outgoingCallback();}}
function suppressUnused(value)
{}
self.setImmediate=function(callback)
{Promise.resolve().then(callback);return 0;}
Promise.prototype.spread=function(callback)
{return this.then(spreadPromise);function spreadPromise(arg)
{return callback.apply(null,arg);}}
Promise.prototype.catchException=function(defaultValue){return this.catch(function(error){console.error(error);return defaultValue;});}
Map.prototype.diff=function(other,isEqual)
{var leftKeys=this.keysArray();var rightKeys=other.keysArray();leftKeys.sort((a,b)=>a-b);rightKeys.sort((a,b)=>a-b);var removed=[];var added=[];var equal=[];var leftIndex=0;var rightIndex=0;while(leftIndex<leftKeys.length&&rightIndex<rightKeys.length){var leftKey=leftKeys[leftIndex];var rightKey=rightKeys[rightIndex];if(leftKey===rightKey&&isEqual(this.get(leftKey),other.get(rightKey))){equal.push(this.get(leftKey));++leftIndex;++rightIndex;continue;}
if(leftKey<=rightKey){removed.push(this.get(leftKey));++leftIndex;continue;}
added.push(other.get(rightKey));++rightIndex;}
while(leftIndex<leftKeys.length){var leftKey=leftKeys[leftIndex++];removed.push(this.get(leftKey));}
while(rightIndex<rightKeys.length){var rightKey=rightKeys[rightIndex++];added.push(other.get(rightKey));}
return{added:added,removed:removed,equal:equal}};self.WebInspector={};WebInspector.UIString=function(string,vararg)
{return String.vsprintf(WebInspector.localize(string),Array.prototype.slice.call(arguments,1));}
WebInspector.UIString.capitalize=function(string,vararg)
{if(WebInspector._useLowerCaseMenuTitles===undefined)
throw"WebInspector.setLocalizationPlatform() has not been called";var localized=WebInspector.localize(string);var capitalized;if(WebInspector._useLowerCaseMenuTitles)
capitalized=localized.replace(/\^(.)/g,"$1");else
capitalized=localized.replace(/\^(.)/g,function(str,char){return char.toUpperCase();});return String.vsprintf(capitalized,Array.prototype.slice.call(arguments,1));}
WebInspector.setLocalizationPlatform=function(platform)
{WebInspector._useLowerCaseMenuTitles=platform==="windows";}
WebInspector.localize=function(string)
{return string;}
WebInspector.UIStringFormat=function(format)
{this._localizedFormat=WebInspector.localize(format);this._tokenizedFormat=String.tokenizeFormatString(this._localizedFormat,String.standardFormatters);}
WebInspector.UIStringFormat._append=function(a,b)
{return a+b;}
WebInspector.UIStringFormat.prototype={format:function(vararg)
{return String.format(this._localizedFormat,arguments,String.standardFormatters,"",WebInspector.UIStringFormat._append,this._tokenizedFormat).formattedResult;}};WebInspector.TextUtils={isStopChar:function(char)
{return(char>" "&&char<"0")||(char>"9"&&char<"A")||(char>"Z"&&char<"_")||(char>"_"&&char<"a")||(char>"z"&&char<="~");},isWordChar:function(char)
{return!WebInspector.TextUtils.isStopChar(char)&&!WebInspector.TextUtils.isSpaceChar(char);},isSpaceChar:function(char)
{return WebInspector.TextUtils._SpaceCharRegex.test(char);},isWord:function(word)
{for(var i=0;i<word.length;++i){if(!WebInspector.TextUtils.isWordChar(word.charAt(i)))
return false;}
return true;},isOpeningBraceChar:function(char)
{return char==="("||char==="{";},isClosingBraceChar:function(char)
{return char===")"||char==="}";},isBraceChar:function(char)
{return WebInspector.TextUtils.isOpeningBraceChar(char)||WebInspector.TextUtils.isClosingBraceChar(char);},textToWords:function(text,isWordChar,wordCallback)
{var startWord=-1;for(var i=0;i<text.length;++i){if(!isWordChar(text.charAt(i))){if(startWord!==-1)
wordCallback(text.substring(startWord,i));startWord=-1;}else if(startWord===-1)
startWord=i;}
if(startWord!==-1)
wordCallback(text.substring(startWord));},lineIndent:function(line)
{var indentation=0;while(indentation<line.length&&WebInspector.TextUtils.isSpaceChar(line.charAt(indentation)))
++indentation;return line.substr(0,indentation);},isUpperCase:function(text)
{return text===text.toUpperCase();},isLowerCase:function(text)
{return text===text.toLowerCase();}}
WebInspector.TextUtils._SpaceCharRegex=/\s/;WebInspector.TextUtils.Indent={TwoSpaces:" ",FourSpaces:" ",EightSpaces:" ",TabCharacter:"\t"}
WebInspector.TextUtils.BalancedJSONTokenizer=function(callback,findMultiple)
{this._callback=callback;this._index=0;this._balance=0;this._buffer="";this._findMultiple=findMultiple||false;this._closingDoubleQuoteRegex=/[^\\](?:\\\\)*"/g;}
WebInspector.TextUtils.BalancedJSONTokenizer.prototype={write:function(chunk)
{this._buffer+=chunk;var lastIndex=this._buffer.length;var buffer=this._buffer;for(var index=this._index;index<lastIndex;++index){var character=buffer[index];if(character==="\""){this._closingDoubleQuoteRegex.lastIndex=index;if(!this._closingDoubleQuoteRegex.test(buffer))
break;index=this._closingDoubleQuoteRegex.lastIndex-1;}else if(character==="{"){++this._balance;}else if(character==="}"){if(--this._balance===0){this._lastBalancedIndex=index+1;if(!this._findMultiple)
break;}}}
this._index=index;this._reportBalanced();},_reportBalanced:function()
{if(!this._lastBalancedIndex)
return;this._callback(this._buffer.slice(0,this._lastBalancedIndex));this._buffer=this._buffer.slice(this._lastBalancedIndex);this._index-=this._lastBalancedIndex;this._lastBalancedIndex=0;},remainder:function()
{return this._buffer;}}
WebInspector.TokenizerFactory=function(){}
WebInspector.TokenizerFactory.prototype={createTokenizer:function(mimeType){}};WebInspector.HeapSnapshotProgressEvent={Update:"ProgressUpdate",BrokenSnapshot:"BrokenSnapshot"};WebInspector.HeapSnapshotCommon={}
WebInspector.HeapSnapshotCommon.baseSystemDistance=100000000;WebInspector.HeapSnapshotCommon.AllocationNodeCallers=function(nodesWithSingleCaller,branchingCallers)
{this.nodesWithSingleCaller=nodesWithSingleCaller;this.branchingCallers=branchingCallers;}
WebInspector.HeapSnapshotCommon.SerializedAllocationNode=function(nodeId,functionName,scriptName,scriptId,line,column,count,size,liveCount,liveSize,hasChildren)
{this.id=nodeId;this.name=functionName;this.scriptName=scriptName;this.scriptId=scriptId;this.line=line;this.column=column;this.count=count;this.size=size;this.liveCount=liveCount;this.liveSize=liveSize;this.hasChildren=hasChildren;}
WebInspector.HeapSnapshotCommon.AllocationStackFrame=function(functionName,scriptName,scriptId,line,column)
{this.functionName=functionName;this.scriptName=scriptName;this.scriptId=scriptId;this.line=line;this.column=column;}
WebInspector.HeapSnapshotCommon.Node=function(id,name,distance,nodeIndex,retainedSize,selfSize,type)
{this.id=id;this.name=name;this.distance=distance;this.nodeIndex=nodeIndex;this.retainedSize=retainedSize;this.selfSize=selfSize;this.type=type;this.canBeQueried=false;this.detachedDOMTreeNode=false;}
WebInspector.HeapSnapshotCommon.Edge=function(name,node,type,edgeIndex)
{this.name=name;this.node=node;this.type=type;this.edgeIndex=edgeIndex;};WebInspector.HeapSnapshotCommon.Aggregate=function()
{this.count;this.distance;this.self;this.maxRet;this.type;this.name;this.idxs;}
WebInspector.HeapSnapshotCommon.AggregateForDiff=function(){this.indexes=[];this.ids=[];this.selfSizes=[];}
WebInspector.HeapSnapshotCommon.Diff=function()
{this.addedCount=0;this.removedCount=0;this.addedSize=0;this.removedSize=0;this.deletedIndexes=[];this.addedIndexes=[];}
WebInspector.HeapSnapshotCommon.DiffForClass=function()
{this.addedCount;this.removedCount;this.addedSize;this.removedSize;this.deletedIndexes;this.addedIndexes;this.countDelta;this.sizeDelta;}
WebInspector.HeapSnapshotCommon.ComparatorConfig=function()
{this.fieldName1;this.ascending1;this.fieldName2;this.ascending2;}
WebInspector.HeapSnapshotCommon.WorkerCommand=function()
{this.callId;this.disposition;this.objectId;this.newObjectId;this.methodName;this.methodArguments;this.source;}
WebInspector.HeapSnapshotCommon.ItemsRange=function(startPosition,endPosition,totalLength,items)
{this.startPosition=startPosition;this.endPosition=endPosition;this.totalLength=totalLength;this.items=items;}
WebInspector.HeapSnapshotCommon.StaticData=function(nodeCount,rootNodeIndex,totalSize,maxJSObjectId)
{this.nodeCount=nodeCount;this.rootNodeIndex=rootNodeIndex;this.totalSize=totalSize;this.maxJSObjectId=maxJSObjectId;}
WebInspector.HeapSnapshotCommon.Statistics=function()
{this.total;this.v8heap;this.native;this.code;this.jsArrays;this.strings;this.system;}
WebInspector.HeapSnapshotCommon.NodeFilter=function(minNodeId,maxNodeId)
{this.minNodeId=minNodeId;this.maxNodeId=maxNodeId;this.allocationNodeId;}
WebInspector.HeapSnapshotCommon.NodeFilter.prototype={equals:function(o)
{return this.minNodeId===o.minNodeId&&this.maxNodeId===o.maxNodeId&&this.allocationNodeId===o.allocationNodeId;}}
WebInspector.HeapSnapshotCommon.SearchConfig=function(query,caseSensitive,isRegex,shouldJump,jumpBackward)
{this.query=query;this.caseSensitive=caseSensitive;this.isRegex=isRegex;this.shouldJump=shouldJump;this.jumpBackward=jumpBackward;}
WebInspector.HeapSnapshotCommon.Samples=function(timestamps,lastAssignedIds,sizes)
{this.timestamps=timestamps;this.lastAssignedIds=lastAssignedIds;this.sizes=sizes;};WebInspector.AllocationProfile=function(profile,liveObjectStats)
{this._strings=profile.strings;this._liveObjectStats=liveObjectStats;this._nextNodeId=1;this._functionInfos=[];this._idToNode={};this._idToTopDownNode={};this._collapsedTopNodeIdToFunctionInfo={};this._traceTops=null;this._buildFunctionAllocationInfos(profile);this._traceTree=this._buildAllocationTree(profile,liveObjectStats);}
WebInspector.AllocationProfile.prototype={_buildFunctionAllocationInfos:function(profile)
{var strings=this._strings;var functionInfoFields=profile.snapshot.meta.trace_function_info_fields;var functionNameOffset=functionInfoFields.indexOf("name");var scriptNameOffset=functionInfoFields.indexOf("script_name");var scriptIdOffset=functionInfoFields.indexOf("script_id");var lineOffset=functionInfoFields.indexOf("line");var columnOffset=functionInfoFields.indexOf("column");var functionInfoFieldCount=functionInfoFields.length;var rawInfos=profile.trace_function_infos;var infoLength=rawInfos.length;var functionInfos=this._functionInfos=new Array(infoLength/functionInfoFieldCount);var index=0;for(var i=0;i<infoLength;i+=functionInfoFieldCount){functionInfos[index++]=new WebInspector.FunctionAllocationInfo(strings[rawInfos[i+functionNameOffset]],strings[rawInfos[i+scriptNameOffset]],rawInfos[i+scriptIdOffset],rawInfos[i+lineOffset],rawInfos[i+columnOffset]);}},_buildAllocationTree:function(profile,liveObjectStats)
{var traceTreeRaw=profile.trace_tree;var functionInfos=this._functionInfos;var idToTopDownNode=this._idToTopDownNode;var traceNodeFields=profile.snapshot.meta.trace_node_fields;var nodeIdOffset=traceNodeFields.indexOf("id");var functionInfoIndexOffset=traceNodeFields.indexOf("function_info_index");var allocationCountOffset=traceNodeFields.indexOf("count");var allocationSizeOffset=traceNodeFields.indexOf("size");var childrenOffset=traceNodeFields.indexOf("children");var nodeFieldCount=traceNodeFields.length;function traverseNode(rawNodeArray,nodeOffset,parent)
{var functionInfo=functionInfos[rawNodeArray[nodeOffset+functionInfoIndexOffset]];var id=rawNodeArray[nodeOffset+nodeIdOffset];var stats=liveObjectStats[id];var liveCount=stats?stats.count:0;var liveSize=stats?stats.size:0;var result=new WebInspector.TopDownAllocationNode(id,functionInfo,rawNodeArray[nodeOffset+allocationCountOffset],rawNodeArray[nodeOffset+allocationSizeOffset],liveCount,liveSize,parent);idToTopDownNode[id]=result;functionInfo.addTraceTopNode(result);var rawChildren=rawNodeArray[nodeOffset+childrenOffset];for(var i=0;i<rawChildren.length;i+=nodeFieldCount){result.children.push(traverseNode(rawChildren,i,result));}
return result;}
return traverseNode(traceTreeRaw,0,null);},serializeTraceTops:function()
{if(this._traceTops)
return this._traceTops;var result=this._traceTops=[];var functionInfos=this._functionInfos;for(var i=0;i<functionInfos.length;i++){var info=functionInfos[i];if(info.totalCount===0)
continue;var nodeId=this._nextNodeId++;var isRoot=i==0;result.push(this._serializeNode(nodeId,info,info.totalCount,info.totalSize,info.totalLiveCount,info.totalLiveSize,!isRoot));this._collapsedTopNodeIdToFunctionInfo[nodeId]=info;}
result.sort(function(a,b){return b.size-a.size;});return result;},serializeCallers:function(nodeId)
{var node=this._ensureBottomUpNode(nodeId);var nodesWithSingleCaller=[];while(node.callers().length===1){node=node.callers()[0];nodesWithSingleCaller.push(this._serializeCaller(node));}
var branchingCallers=[];var callers=node.callers();for(var i=0;i<callers.length;i++){branchingCallers.push(this._serializeCaller(callers[i]));}
return new WebInspector.HeapSnapshotCommon.AllocationNodeCallers(nodesWithSingleCaller,branchingCallers);},serializeAllocationStack:function(traceNodeId)
{var node=this._idToTopDownNode[traceNodeId];var result=[];while(node){var functionInfo=node.functionInfo;result.push(new WebInspector.HeapSnapshotCommon.AllocationStackFrame(functionInfo.functionName,functionInfo.scriptName,functionInfo.scriptId,functionInfo.line,functionInfo.column));node=node.parent;}
return result;},traceIds:function(allocationNodeId)
{return this._ensureBottomUpNode(allocationNodeId).traceTopIds;},_ensureBottomUpNode:function(nodeId)
{var node=this._idToNode[nodeId];if(!node){var functionInfo=this._collapsedTopNodeIdToFunctionInfo[nodeId];node=functionInfo.bottomUpRoot();delete this._collapsedTopNodeIdToFunctionInfo[nodeId];this._idToNode[nodeId]=node;}
return node;},_serializeCaller:function(node)
{var callerId=this._nextNodeId++;this._idToNode[callerId]=node;return this._serializeNode(callerId,node.functionInfo,node.allocationCount,node.allocationSize,node.liveCount,node.liveSize,node.hasCallers());},_serializeNode:function(nodeId,functionInfo,count,size,liveCount,liveSize,hasChildren)
{return new WebInspector.HeapSnapshotCommon.SerializedAllocationNode(nodeId,functionInfo.functionName,functionInfo.scriptName,functionInfo.scriptId,functionInfo.line,functionInfo.column,count,size,liveCount,liveSize,hasChildren);}}
WebInspector.TopDownAllocationNode=function(id,functionInfo,count,size,liveCount,liveSize,parent)
{this.id=id;this.functionInfo=functionInfo;this.allocationCount=count;this.allocationSize=size;this.liveCount=liveCount;this.liveSize=liveSize;this.parent=parent;this.children=[];}
WebInspector.BottomUpAllocationNode=function(functionInfo)
{this.functionInfo=functionInfo;this.allocationCount=0;this.allocationSize=0;this.liveCount=0;this.liveSize=0;this.traceTopIds=[];this._callers=[];}
WebInspector.BottomUpAllocationNode.prototype={addCaller:function(traceNode)
{var functionInfo=traceNode.functionInfo;var result;for(var i=0;i<this._callers.length;i++){var caller=this._callers[i];if(caller.functionInfo===functionInfo){result=caller;break;}}
if(!result){result=new WebInspector.BottomUpAllocationNode(functionInfo);this._callers.push(result);}
return result;},callers:function()
{return this._callers;},hasCallers:function()
{return this._callers.length>0;}}
WebInspector.FunctionAllocationInfo=function(functionName,scriptName,scriptId,line,column)
{this.functionName=functionName;this.scriptName=scriptName;this.scriptId=scriptId;this.line=line;this.column=column;this.totalCount=0;this.totalSize=0;this.totalLiveCount=0;this.totalLiveSize=0;this._traceTops=[];}
WebInspector.FunctionAllocationInfo.prototype={addTraceTopNode:function(node)
{if(node.allocationCount===0)
return;this._traceTops.push(node);this.totalCount+=node.allocationCount;this.totalSize+=node.allocationSize;this.totalLiveCount+=node.liveCount;this.totalLiveSize+=node.liveSize;},bottomUpRoot:function()
{if(!this._traceTops.length)
return null;if(!this._bottomUpTree)
this._buildAllocationTraceTree();return this._bottomUpTree;},_buildAllocationTraceTree:function()
{this._bottomUpTree=new WebInspector.BottomUpAllocationNode(this);for(var i=0;i<this._traceTops.length;i++){var node=this._traceTops[i];var bottomUpNode=this._bottomUpTree;var count=node.allocationCount;var size=node.allocationSize;var liveCount=node.liveCount;var liveSize=node.liveSize;var traceId=node.id;while(true){bottomUpNode.allocationCount+=count;bottomUpNode.allocationSize+=size;bottomUpNode.liveCount+=liveCount;bottomUpNode.liveSize+=liveSize;bottomUpNode.traceTopIds.push(traceId);node=node.parent;if(node===null){break;}
bottomUpNode=bottomUpNode.addCaller(node);}}}};WebInspector.HeapSnapshotItem=function(){}
WebInspector.HeapSnapshotItem.prototype={itemIndex:function(){},serialize:function(){}};WebInspector.HeapSnapshotEdge=function(snapshot,edgeIndex)
{this._snapshot=snapshot;this._edges=snapshot.containmentEdges;this.edgeIndex=edgeIndex||0;}
WebInspector.HeapSnapshotEdge.prototype={clone:function()
{return new WebInspector.HeapSnapshotEdge(this._snapshot,this.edgeIndex);},hasStringName:function()
{throw new Error("Not implemented");},name:function()
{throw new Error("Not implemented");},node:function()
{return this._snapshot.createNode(this.nodeIndex());},nodeIndex:function()
{return this._edges[this.edgeIndex+this._snapshot._edgeToNodeOffset];},toString:function()
{return"HeapSnapshotEdge: "+this.name();},type:function()
{return this._snapshot._edgeTypes[this._type()];},itemIndex:function()
{return this.edgeIndex;},serialize:function()
{return new WebInspector.HeapSnapshotCommon.Edge(this.name(),this.node().serialize(),this.type(),this.edgeIndex);},_type:function()
{return this._edges[this.edgeIndex+this._snapshot._edgeTypeOffset];}};WebInspector.HeapSnapshotItemIterator=function(){}
WebInspector.HeapSnapshotItemIterator.prototype={hasNext:function(){},item:function(){},next:function(){}};WebInspector.HeapSnapshotItemIndexProvider=function(){}
WebInspector.HeapSnapshotItemIndexProvider.prototype={itemForIndex:function(newIndex){},};WebInspector.HeapSnapshotNodeIndexProvider=function(snapshot)
{this._node=snapshot.createNode();}
WebInspector.HeapSnapshotNodeIndexProvider.prototype={itemForIndex:function(index)
{this._node.nodeIndex=index;return this._node;}};WebInspector.HeapSnapshotEdgeIndexProvider=function(snapshot)
{this._edge=snapshot.createEdge(0);}
WebInspector.HeapSnapshotEdgeIndexProvider.prototype={itemForIndex:function(index)
{this._edge.edgeIndex=index;return this._edge;}};WebInspector.HeapSnapshotRetainerEdgeIndexProvider=function(snapshot)
{this._retainerEdge=snapshot.createRetainingEdge(0);}
WebInspector.HeapSnapshotRetainerEdgeIndexProvider.prototype={itemForIndex:function(index)
{this._retainerEdge.setRetainerIndex(index);return this._retainerEdge;}};WebInspector.HeapSnapshotEdgeIterator=function(node)
{this._sourceNode=node;this.edge=node._snapshot.createEdge(node.edgeIndexesStart());}
WebInspector.HeapSnapshotEdgeIterator.prototype={hasNext:function()
{return this.edge.edgeIndex<this._sourceNode.edgeIndexesEnd();},item:function()
{return this.edge;},next:function()
{this.edge.edgeIndex+=this.edge._snapshot._edgeFieldsCount;}};WebInspector.HeapSnapshotRetainerEdge=function(snapshot,retainerIndex)
{this._snapshot=snapshot;this.setRetainerIndex(retainerIndex);}
WebInspector.HeapSnapshotRetainerEdge.prototype={clone:function()
{return new WebInspector.HeapSnapshotRetainerEdge(this._snapshot,this.retainerIndex());},hasStringName:function()
{return this._edge().hasStringName();},name:function()
{return this._edge().name();},node:function()
{return this._node();},nodeIndex:function()
{return this._retainingNodeIndex;},retainerIndex:function()
{return this._retainerIndex;},setRetainerIndex:function(retainerIndex)
{if(retainerIndex===this._retainerIndex)
return;this._retainerIndex=retainerIndex;this._globalEdgeIndex=this._snapshot._retainingEdges[retainerIndex];this._retainingNodeIndex=this._snapshot._retainingNodes[retainerIndex];this._edgeInstance=null;this._nodeInstance=null;},set edgeIndex(edgeIndex)
{this.setRetainerIndex(edgeIndex);},_node:function()
{if(!this._nodeInstance)
this._nodeInstance=this._snapshot.createNode(this._retainingNodeIndex);return this._nodeInstance;},_edge:function()
{if(!this._edgeInstance)
this._edgeInstance=this._snapshot.createEdge(this._globalEdgeIndex);return this._edgeInstance;},toString:function()
{return this._edge().toString();},itemIndex:function()
{return this._retainerIndex;},serialize:function()
{return new WebInspector.HeapSnapshotCommon.Edge(this.name(),this.node().serialize(),this.type(),this._globalEdgeIndex);},type:function()
{return this._edge().type();}}
WebInspector.HeapSnapshotRetainerEdgeIterator=function(retainedNode)
{var snapshot=retainedNode._snapshot;var retainedNodeOrdinal=retainedNode.ordinal();var retainerIndex=snapshot._firstRetainerIndex[retainedNodeOrdinal];this._retainersEnd=snapshot._firstRetainerIndex[retainedNodeOrdinal+1];this.retainer=snapshot.createRetainingEdge(retainerIndex);}
WebInspector.HeapSnapshotRetainerEdgeIterator.prototype={hasNext:function()
{return this.retainer.retainerIndex()<this._retainersEnd;},item:function()
{return this.retainer;},next:function()
{this.retainer.setRetainerIndex(this.retainer.retainerIndex()+1);}};WebInspector.HeapSnapshotNode=function(snapshot,nodeIndex)
{this._snapshot=snapshot;this.nodeIndex=nodeIndex||0;}
WebInspector.HeapSnapshotNode.prototype={distance:function()
{return this._snapshot._nodeDistances[this.nodeIndex/this._snapshot._nodeFieldCount];},className:function()
{throw new Error("Not implemented");},classIndex:function()
{throw new Error("Not implemented");},dominatorIndex:function()
{var nodeFieldCount=this._snapshot._nodeFieldCount;return this._snapshot._dominatorsTree[this.nodeIndex/this._snapshot._nodeFieldCount]*nodeFieldCount;},edges:function()
{return new WebInspector.HeapSnapshotEdgeIterator(this);},edgesCount:function()
{return(this.edgeIndexesEnd()-this.edgeIndexesStart())/this._snapshot._edgeFieldsCount;},id:function()
{throw new Error("Not implemented");},isRoot:function()
{return this.nodeIndex===this._snapshot._rootNodeIndex;},name:function()
{return this._snapshot.strings[this._name()];},retainedSize:function()
{return this._snapshot._retainedSizes[this.ordinal()];},retainers:function()
{return new WebInspector.HeapSnapshotRetainerEdgeIterator(this);},retainersCount:function()
{var snapshot=this._snapshot;var ordinal=this.ordinal();return snapshot._firstRetainerIndex[ordinal+1]-snapshot._firstRetainerIndex[ordinal];},selfSize:function()
{var snapshot=this._snapshot;return snapshot.nodes[this.nodeIndex+snapshot._nodeSelfSizeOffset];},type:function()
{return this._snapshot._nodeTypes[this._type()];},traceNodeId:function()
{var snapshot=this._snapshot;return snapshot.nodes[this.nodeIndex+snapshot._nodeTraceNodeIdOffset];},itemIndex:function()
{return this.nodeIndex;},serialize:function()
{return new WebInspector.HeapSnapshotCommon.Node(this.id(),this.name(),this.distance(),this.nodeIndex,this.retainedSize(),this.selfSize(),this.type());},_name:function()
{var snapshot=this._snapshot;return snapshot.nodes[this.nodeIndex+snapshot._nodeNameOffset];},edgeIndexesStart:function()
{return this._snapshot._firstEdgeIndexes[this.ordinal()];},edgeIndexesEnd:function()
{return this._snapshot._firstEdgeIndexes[this.ordinal()+1];},ordinal:function()
{return this.nodeIndex/this._snapshot._nodeFieldCount;},_nextNodeIndex:function()
{return this.nodeIndex+this._snapshot._nodeFieldCount;},_type:function()
{var snapshot=this._snapshot;return snapshot.nodes[this.nodeIndex+snapshot._nodeTypeOffset];}};WebInspector.HeapSnapshotNodeIterator=function(node)
{this.node=node;this._nodesLength=node._snapshot.nodes.length;}
WebInspector.HeapSnapshotNodeIterator.prototype={hasNext:function()
{return this.node.nodeIndex<this._nodesLength;},item:function()
{return this.node;},next:function()
{this.node.nodeIndex=this.node._nextNodeIndex();}}
WebInspector.HeapSnapshotIndexRangeIterator=function(itemProvider,indexes)
{this._itemProvider=itemProvider;this._indexes=indexes;this._position=0;}
WebInspector.HeapSnapshotIndexRangeIterator.prototype={hasNext:function()
{return this._position<this._indexes.length;},item:function()
{var index=this._indexes[this._position];return this._itemProvider.itemForIndex(index);},next:function()
{++this._position;}}
WebInspector.HeapSnapshotFilteredIterator=function(iterator,filter)
{this._iterator=iterator;this._filter=filter;this._skipFilteredItems();}
WebInspector.HeapSnapshotFilteredIterator.prototype={hasNext:function()
{return this._iterator.hasNext();},item:function()
{return this._iterator.item();},next:function()
{this._iterator.next();this._skipFilteredItems();},_skipFilteredItems:function()
{while(this._iterator.hasNext()&&!this._filter(this._iterator.item())){this._iterator.next();}}}
WebInspector.HeapSnapshotProgress=function(dispatcher)
{this._dispatcher=dispatcher;}
WebInspector.HeapSnapshotProgress.prototype={updateStatus:function(status)
{this._sendUpdateEvent(WebInspector.UIString(status));},updateProgress:function(title,value,total)
{var percentValue=((total?(value/total):0)*100).toFixed(0);this._sendUpdateEvent(WebInspector.UIString(title,percentValue));},reportProblem:function(error)
{if(this._dispatcher)
this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot,error);},_sendUpdateEvent:function(text)
{if(this._dispatcher)
this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgressEvent.Update,text);}}
WebInspector.HeapSnapshotProblemReport=function(title)
{this._errors=[title];}
WebInspector.HeapSnapshotProblemReport.prototype={addError:function(error)
{if(this._errors.length>100)
return;this._errors.push(error);},toString:function()
{return this._errors.join("\n ");}}
WebInspector.HeapSnapshot=function(profile,progress)
{this.nodes=profile.nodes;this.containmentEdges=profile.edges;this._metaNode=profile.snapshot.meta;this._rawSamples=profile.samples;this._samples=null;this.strings=profile.strings;this._progress=progress;this._noDistance=-5;this._rootNodeIndex=0;if(profile.snapshot.root_index)
this._rootNodeIndex=profile.snapshot.root_index;this._snapshotDiffs={};this._aggregatesForDiff=null;this._aggregates={};this._aggregatesSortedFlags={};this._init();if(profile.snapshot.trace_function_count){this._progress.updateStatus("Building allocation statistics\u2026");var nodes=this.nodes;var nodesLength=nodes.length;var nodeFieldCount=this._nodeFieldCount;var node=this.rootNode();var liveObjects={};for(var nodeIndex=0;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){node.nodeIndex=nodeIndex;var traceNodeId=node.traceNodeId();var stats=liveObjects[traceNodeId];if(!stats)
liveObjects[traceNodeId]=stats={count:0,size:0,ids:[]};stats.count++;stats.size+=node.selfSize();stats.ids.push(node.id());}
this._allocationProfile=new WebInspector.AllocationProfile(profile,liveObjects);this._progress.updateStatus("Done");}}
function HeapSnapshotMetainfo()
{this.node_fields=[];this.node_types=[];this.edge_fields=[];this.edge_types=[];this.trace_function_info_fields=[];this.trace_node_fields=[];this.sample_fields=[];this.type_strings={};}
function HeapSnapshotHeader()
{this.title="";this.meta=new HeapSnapshotMetainfo();this.node_count=0;this.edge_count=0;this.trace_function_count=0;}
WebInspector.HeapSnapshot.prototype={_init:function()
{var meta=this._metaNode;this._nodeTypeOffset=meta.node_fields.indexOf("type");this._nodeNameOffset=meta.node_fields.indexOf("name");this._nodeIdOffset=meta.node_fields.indexOf("id");this._nodeSelfSizeOffset=meta.node_fields.indexOf("self_size");this._nodeEdgeCountOffset=meta.node_fields.indexOf("edge_count");this._nodeTraceNodeIdOffset=meta.node_fields.indexOf("trace_node_id");this._nodeFieldCount=meta.node_fields.length;this._nodeTypes=meta.node_types[this._nodeTypeOffset];this._nodeArrayType=this._nodeTypes.indexOf("array");this._nodeHiddenType=this._nodeTypes.indexOf("hidden");this._nodeObjectType=this._nodeTypes.indexOf("object");this._nodeNativeType=this._nodeTypes.indexOf("native");this._nodeConsStringType=this._nodeTypes.indexOf("concatenated string");this._nodeSlicedStringType=this._nodeTypes.indexOf("sliced string");this._nodeCodeType=this._nodeTypes.indexOf("code");this._nodeSyntheticType=this._nodeTypes.indexOf("synthetic");this._edgeFieldsCount=meta.edge_fields.length;this._edgeTypeOffset=meta.edge_fields.indexOf("type");this._edgeNameOffset=meta.edge_fields.indexOf("name_or_index");this._edgeToNodeOffset=meta.edge_fields.indexOf("to_node");this._edgeTypes=meta.edge_types[this._edgeTypeOffset];this._edgeTypes.push("invisible");this._edgeElementType=this._edgeTypes.indexOf("element");this._edgeHiddenType=this._edgeTypes.indexOf("hidden");this._edgeInternalType=this._edgeTypes.indexOf("internal");this._edgeShortcutType=this._edgeTypes.indexOf("shortcut");this._edgeWeakType=this._edgeTypes.indexOf("weak");this._edgeInvisibleType=this._edgeTypes.indexOf("invisible");this.nodeCount=this.nodes.length/this._nodeFieldCount;this._edgeCount=this.containmentEdges.length/this._edgeFieldsCount;this._retainedSizes=new Float64Array(this.nodeCount);this._firstEdgeIndexes=new Uint32Array(this.nodeCount+1);this._retainingNodes=new Uint32Array(this._edgeCount);this._retainingEdges=new Uint32Array(this._edgeCount);this._firstRetainerIndex=new Uint32Array(this.nodeCount+1);this._nodeDistances=new Int32Array(this.nodeCount);this._firstDominatedNodeIndex=new Uint32Array(this.nodeCount+1);this._dominatedNodes=new Uint32Array(this.nodeCount-1);this._progress.updateStatus("Building edge indexes\u2026");this._buildEdgeIndexes();this._progress.updateStatus("Building retainers\u2026");this._buildRetainers();this._progress.updateStatus("Calculating node flags\u2026");this._calculateFlags();this._progress.updateStatus("Calculating distances\u2026");this.calculateDistances();this._progress.updateStatus("Building postorder index\u2026");var result=this._buildPostOrderIndex();this._progress.updateStatus("Building dominator tree\u2026");this._dominatorsTree=this._buildDominatorTree(result.postOrderIndex2NodeOrdinal,result.nodeOrdinal2PostOrderIndex);this._progress.updateStatus("Calculating retained sizes\u2026");this._calculateRetainedSizes(result.postOrderIndex2NodeOrdinal);this._progress.updateStatus("Buiding dominated nodes\u2026");this._buildDominatedNodes();this._progress.updateStatus("Calculating statistics\u2026");this._calculateStatistics();this._progress.updateStatus("Calculating samples\u2026");this._buildSamples();this._progress.updateStatus("Finished processing.");},_buildEdgeIndexes:function()
{var nodes=this.nodes;var nodeCount=this.nodeCount;var firstEdgeIndexes=this._firstEdgeIndexes;var nodeFieldCount=this._nodeFieldCount;var edgeFieldsCount=this._edgeFieldsCount;var nodeEdgeCountOffset=this._nodeEdgeCountOffset;firstEdgeIndexes[nodeCount]=this.containmentEdges.length;for(var nodeOrdinal=0,edgeIndex=0;nodeOrdinal<nodeCount;++nodeOrdinal){firstEdgeIndexes[nodeOrdinal]=edgeIndex;edgeIndex+=nodes[nodeOrdinal*nodeFieldCount+nodeEdgeCountOffset]*edgeFieldsCount;}},_buildRetainers:function()
{var retainingNodes=this._retainingNodes;var retainingEdges=this._retainingEdges;var firstRetainerIndex=this._firstRetainerIndex;var containmentEdges=this.containmentEdges;var edgeFieldsCount=this._edgeFieldsCount;var nodeFieldCount=this._nodeFieldCount;var edgeToNodeOffset=this._edgeToNodeOffset;var firstEdgeIndexes=this._firstEdgeIndexes;var nodeCount=this.nodeCount;for(var toNodeFieldIndex=edgeToNodeOffset,l=containmentEdges.length;toNodeFieldIndex<l;toNodeFieldIndex+=edgeFieldsCount){var toNodeIndex=containmentEdges[toNodeFieldIndex];if(toNodeIndex%nodeFieldCount)
throw new Error("Invalid toNodeIndex "+toNodeIndex);++firstRetainerIndex[toNodeIndex/nodeFieldCount];}
for(var i=0,firstUnusedRetainerSlot=0;i<nodeCount;i++){var retainersCount=firstRetainerIndex[i];firstRetainerIndex[i]=firstUnusedRetainerSlot;retainingNodes[firstUnusedRetainerSlot]=retainersCount;firstUnusedRetainerSlot+=retainersCount;}
firstRetainerIndex[nodeCount]=retainingNodes.length;var nextNodeFirstEdgeIndex=firstEdgeIndexes[0];for(var srcNodeOrdinal=0;srcNodeOrdinal<nodeCount;++srcNodeOrdinal){var firstEdgeIndex=nextNodeFirstEdgeIndex;nextNodeFirstEdgeIndex=firstEdgeIndexes[srcNodeOrdinal+1];var srcNodeIndex=srcNodeOrdinal*nodeFieldCount;for(var edgeIndex=firstEdgeIndex;edgeIndex<nextNodeFirstEdgeIndex;edgeIndex+=edgeFieldsCount){var toNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];if(toNodeIndex%nodeFieldCount)
throw new Error("Invalid toNodeIndex "+toNodeIndex);var firstRetainerSlotIndex=firstRetainerIndex[toNodeIndex/nodeFieldCount];var nextUnusedRetainerSlotIndex=firstRetainerSlotIndex+(--retainingNodes[firstRetainerSlotIndex]);retainingNodes[nextUnusedRetainerSlotIndex]=srcNodeIndex;retainingEdges[nextUnusedRetainerSlotIndex]=edgeIndex;}}},createNode:function(nodeIndex)
{throw new Error("Not implemented");},createEdge:function(edgeIndex)
{throw new Error("Not implemented");},createRetainingEdge:function(retainerIndex)
{throw new Error("Not implemented");},_allNodes:function()
{return new WebInspector.HeapSnapshotNodeIterator(this.rootNode());},rootNode:function()
{return this.createNode(this._rootNodeIndex);},get rootNodeIndex()
{return this._rootNodeIndex;},get totalSize()
{return this.rootNode().retainedSize();},_getDominatedIndex:function(nodeIndex)
{if(nodeIndex%this._nodeFieldCount)
throw new Error("Invalid nodeIndex: "+nodeIndex);return this._firstDominatedNodeIndex[nodeIndex/this._nodeFieldCount];},_createFilter:function(nodeFilter)
{var minNodeId=nodeFilter.minNodeId;var maxNodeId=nodeFilter.maxNodeId;var allocationNodeId=nodeFilter.allocationNodeId;var filter;if(typeof allocationNodeId==="number"){filter=this._createAllocationStackFilter(allocationNodeId);filter.key="AllocationNodeId: "+allocationNodeId;}else if(typeof minNodeId==="number"&&typeof maxNodeId==="number"){filter=this._createNodeIdFilter(minNodeId,maxNodeId);filter.key="NodeIdRange: "+minNodeId+".."+maxNodeId;}
return filter;},search:function(searchConfig,nodeFilter)
{var query=searchConfig.query;function filterString(matchedStringIndexes,string,index)
{if(string.indexOf(query)!==-1)
matchedStringIndexes.add(index);return matchedStringIndexes;}
var regexp=searchConfig.isRegex?new RegExp(query):createPlainTextSearchRegex(query,"i");function filterRegexp(matchedStringIndexes,string,index)
{if(regexp.test(string))
matchedStringIndexes.add(index);return matchedStringIndexes;}
var stringFilter=(searchConfig.isRegex||!searchConfig.caseSensitive)?filterRegexp:filterString;var stringIndexes=this.strings.reduce(stringFilter,new Set());if(!stringIndexes.size)
return[];var filter=this._createFilter(nodeFilter);var nodeIds=[];var nodesLength=this.nodes.length;var nodes=this.nodes;var nodeNameOffset=this._nodeNameOffset;var nodeIdOffset=this._nodeIdOffset;var nodeFieldCount=this._nodeFieldCount;var node=this.rootNode();for(var nodeIndex=0;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){node.nodeIndex=nodeIndex;if(filter&&!filter(node))
continue;if(stringIndexes.has(nodes[nodeIndex+nodeNameOffset]))
nodeIds.push(nodes[nodeIndex+nodeIdOffset]);}
return nodeIds;},aggregatesWithFilter:function(nodeFilter)
{var filter=this._createFilter(nodeFilter);var key=filter?filter.key:"allObjects";return this.aggregates(false,key,filter);},_createNodeIdFilter:function(minNodeId,maxNodeId)
{function nodeIdFilter(node)
{var id=node.id();return id>minNodeId&&id<=maxNodeId;}
return nodeIdFilter;},_createAllocationStackFilter:function(bottomUpAllocationNodeId)
{var traceIds=this._allocationProfile.traceIds(bottomUpAllocationNodeId);if(!traceIds.length)
return undefined;var set={};for(var i=0;i<traceIds.length;i++)
set[traceIds[i]]=true;function traceIdFilter(node)
{return!!set[node.traceNodeId()];};return traceIdFilter;},aggregates:function(sortedIndexes,key,filter)
{var aggregatesByClassName=key&&this._aggregates[key];if(!aggregatesByClassName){var aggregates=this._buildAggregates(filter);this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex,filter);aggregatesByClassName=aggregates.aggregatesByClassName;if(key)
this._aggregates[key]=aggregatesByClassName;}
if(sortedIndexes&&(!key||!this._aggregatesSortedFlags[key])){this._sortAggregateIndexes(aggregatesByClassName);if(key)
this._aggregatesSortedFlags[key]=sortedIndexes;}
return aggregatesByClassName;},allocationTracesTops:function()
{return this._allocationProfile.serializeTraceTops();},allocationNodeCallers:function(nodeId)
{return this._allocationProfile.serializeCallers(nodeId);},allocationStack:function(nodeIndex)
{var node=this.createNode(nodeIndex);var allocationNodeId=node.traceNodeId();if(!allocationNodeId)
return null;return this._allocationProfile.serializeAllocationStack(allocationNodeId);},aggregatesForDiff:function()
{if(this._aggregatesForDiff)
return this._aggregatesForDiff;var aggregatesByClassName=this.aggregates(true,"allObjects");this._aggregatesForDiff={};var node=this.createNode();for(var className in aggregatesByClassName){var aggregate=aggregatesByClassName[className];var indexes=aggregate.idxs;var ids=new Array(indexes.length);var selfSizes=new Array(indexes.length);for(var i=0;i<indexes.length;i++){node.nodeIndex=indexes[i];ids[i]=node.id();selfSizes[i]=node.selfSize();}
this._aggregatesForDiff[className]={indexes:indexes,ids:ids,selfSizes:selfSizes};}
return this._aggregatesForDiff;},isUserRoot:function(node)
{return true;},forEachRoot:function(action,userRootsOnly)
{for(var iter=this.rootNode().edges();iter.hasNext();iter.next()){var node=iter.edge.node();if(!userRootsOnly||this.isUserRoot(node))
action(node);}},calculateDistances:function(filter)
{var nodeCount=this.nodeCount;var distances=this._nodeDistances;var noDistance=this._noDistance;for(var i=0;i<nodeCount;++i)
distances[i]=noDistance;var nodesToVisit=new Uint32Array(this.nodeCount);var nodesToVisitLength=0;function enqueueNode(distance,node)
{var ordinal=node.ordinal();if(distances[ordinal]!==noDistance)
return;distances[ordinal]=distance;nodesToVisit[nodesToVisitLength++]=node.nodeIndex;}
this.forEachRoot(enqueueNode.bind(null,1),true);this._bfs(nodesToVisit,nodesToVisitLength,distances,filter);nodesToVisitLength=0;this.forEachRoot(enqueueNode.bind(null,WebInspector.HeapSnapshotCommon.baseSystemDistance),false);this._bfs(nodesToVisit,nodesToVisitLength,distances,filter);},_bfs:function(nodesToVisit,nodesToVisitLength,distances,filter)
{var edgeFieldsCount=this._edgeFieldsCount;var nodeFieldCount=this._nodeFieldCount;var containmentEdges=this.containmentEdges;var firstEdgeIndexes=this._firstEdgeIndexes;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeTypeOffset=this._edgeTypeOffset;var nodeCount=this.nodeCount;var edgeWeakType=this._edgeWeakType;var noDistance=this._noDistance;var index=0;var edge=this.createEdge(0);var node=this.createNode(0);while(index<nodesToVisitLength){var nodeIndex=nodesToVisit[index++];var nodeOrdinal=nodeIndex/nodeFieldCount;var distance=distances[nodeOrdinal]+1;var firstEdgeIndex=firstEdgeIndexes[nodeOrdinal];var edgesEnd=firstEdgeIndexes[nodeOrdinal+1];node.nodeIndex=nodeIndex;for(var edgeIndex=firstEdgeIndex;edgeIndex<edgesEnd;edgeIndex+=edgeFieldsCount){var edgeType=containmentEdges[edgeIndex+edgeTypeOffset];if(edgeType===edgeWeakType)
continue;var childNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];var childNodeOrdinal=childNodeIndex/nodeFieldCount;if(distances[childNodeOrdinal]!==noDistance)
continue;edge.edgeIndex=edgeIndex;if(filter&&!filter(node,edge))
continue;distances[childNodeOrdinal]=distance;nodesToVisit[nodesToVisitLength++]=childNodeIndex;}}
if(nodesToVisitLength>nodeCount)
throw new Error("BFS failed. Nodes to visit ("+nodesToVisitLength+") is more than nodes count ("+nodeCount+")");},_buildAggregates:function(filter)
{var aggregates={};var aggregatesByClassName={};var classIndexes=[];var nodes=this.nodes;var mapAndFlag=this.userObjectsMapAndFlag();var flags=mapAndFlag?mapAndFlag.map:null;var flag=mapAndFlag?mapAndFlag.flag:0;var nodesLength=nodes.length;var nodeNativeType=this._nodeNativeType;var nodeFieldCount=this._nodeFieldCount;var selfSizeOffset=this._nodeSelfSizeOffset;var nodeTypeOffset=this._nodeTypeOffset;var node=this.rootNode();var nodeDistances=this._nodeDistances;for(var nodeIndex=0;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){var nodeOrdinal=nodeIndex/nodeFieldCount;if(flags&&!(flags[nodeOrdinal]&flag))
continue;node.nodeIndex=nodeIndex;if(filter&&!filter(node))
continue;var selfSize=nodes[nodeIndex+selfSizeOffset];if(!selfSize&&nodes[nodeIndex+nodeTypeOffset]!==nodeNativeType)
continue;var classIndex=node.classIndex();if(!(classIndex in aggregates)){var nodeType=node.type();var nameMatters=nodeType==="object"||nodeType==="native";var value={count:1,distance:nodeDistances[nodeOrdinal],self:selfSize,maxRet:0,type:nodeType,name:nameMatters?node.name():null,idxs:[nodeIndex]};aggregates[classIndex]=value;classIndexes.push(classIndex);aggregatesByClassName[node.className()]=value;}else{var clss=aggregates[classIndex];clss.distance=Math.min(clss.distance,nodeDistances[nodeOrdinal]);++clss.count;clss.self+=selfSize;clss.idxs.push(nodeIndex);}}
for(var i=0,l=classIndexes.length;i<l;++i){var classIndex=classIndexes[i];aggregates[classIndex].idxs=aggregates[classIndex].idxs.slice();}
return{aggregatesByClassName:aggregatesByClassName,aggregatesByClassIndex:aggregates};},_calculateClassesRetainedSize:function(aggregates,filter)
{var rootNodeIndex=this._rootNodeIndex;var node=this.createNode(rootNodeIndex);var list=[rootNodeIndex];var sizes=[-1];var classes=[];var seenClassNameIndexes={};var nodeFieldCount=this._nodeFieldCount;var nodeTypeOffset=this._nodeTypeOffset;var nodeNativeType=this._nodeNativeType;var dominatedNodes=this._dominatedNodes;var nodes=this.nodes;var mapAndFlag=this.userObjectsMapAndFlag();var flags=mapAndFlag?mapAndFlag.map:null;var flag=mapAndFlag?mapAndFlag.flag:0;var firstDominatedNodeIndex=this._firstDominatedNodeIndex;while(list.length){var nodeIndex=list.pop();node.nodeIndex=nodeIndex;var classIndex=node.classIndex();var seen=!!seenClassNameIndexes[classIndex];var nodeOrdinal=nodeIndex/nodeFieldCount;var dominatedIndexFrom=firstDominatedNodeIndex[nodeOrdinal];var dominatedIndexTo=firstDominatedNodeIndex[nodeOrdinal+1];if(!seen&&(!flags||(flags[nodeOrdinal]&flag))&&(!filter||filter(node))&&(node.selfSize()||nodes[nodeIndex+nodeTypeOffset]===nodeNativeType)){aggregates[classIndex].maxRet+=node.retainedSize();if(dominatedIndexFrom!==dominatedIndexTo){seenClassNameIndexes[classIndex]=true;sizes.push(list.length);classes.push(classIndex);}}
for(var i=dominatedIndexFrom;i<dominatedIndexTo;i++)
list.push(dominatedNodes[i]);var l=list.length;while(sizes[sizes.length-1]===l){sizes.pop();classIndex=classes.pop();seenClassNameIndexes[classIndex]=false;}}},_sortAggregateIndexes:function(aggregates)
{var nodeA=this.createNode();var nodeB=this.createNode();for(var clss in aggregates)
aggregates[clss].idxs.sort(function(idxA,idxB){nodeA.nodeIndex=idxA;nodeB.nodeIndex=idxB;return nodeA.id()<nodeB.id()?-1:1;});},_buildPostOrderIndex:function()
{var nodeFieldCount=this._nodeFieldCount;var nodeCount=this.nodeCount;var rootNodeOrdinal=this._rootNodeIndex/nodeFieldCount;var edgeFieldsCount=this._edgeFieldsCount;var edgeTypeOffset=this._edgeTypeOffset;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeShortcutType=this._edgeShortcutType;var edgeWeakType=this._edgeWeakType;var firstEdgeIndexes=this._firstEdgeIndexes;var containmentEdges=this.containmentEdges;var mapAndFlag=this.userObjectsMapAndFlag();var flags=mapAndFlag?mapAndFlag.map:null;var flag=mapAndFlag?mapAndFlag.flag:0;var stackNodes=new Uint32Array(nodeCount);var stackCurrentEdge=new Uint32Array(nodeCount);var postOrderIndex2NodeOrdinal=new Uint32Array(nodeCount);var nodeOrdinal2PostOrderIndex=new Uint32Array(nodeCount);var visited=new Uint8Array(nodeCount);var postOrderIndex=0;var stackTop=0;stackNodes[0]=rootNodeOrdinal;stackCurrentEdge[0]=firstEdgeIndexes[rootNodeOrdinal];visited[rootNodeOrdinal]=1;var iteration=0;while(true){++iteration;while(stackTop>=0){var nodeOrdinal=stackNodes[stackTop];var edgeIndex=stackCurrentEdge[stackTop];var edgesEnd=firstEdgeIndexes[nodeOrdinal+1];if(edgeIndex<edgesEnd){stackCurrentEdge[stackTop]+=edgeFieldsCount;var edgeType=containmentEdges[edgeIndex+edgeTypeOffset];if(edgeType===edgeWeakType||edgeType===edgeShortcutType)
continue;var childNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];var childNodeOrdinal=childNodeIndex/nodeFieldCount;if(visited[childNodeOrdinal])
continue;var nodeFlag=!flags||(flags[nodeOrdinal]&flag);var childNodeFlag=!flags||(flags[childNodeOrdinal]&flag);if(nodeOrdinal!==rootNodeOrdinal&&childNodeFlag&&!nodeFlag)
continue;++stackTop;stackNodes[stackTop]=childNodeOrdinal;stackCurrentEdge[stackTop]=firstEdgeIndexes[childNodeOrdinal];visited[childNodeOrdinal]=1;}else{nodeOrdinal2PostOrderIndex[nodeOrdinal]=postOrderIndex;postOrderIndex2NodeOrdinal[postOrderIndex++]=nodeOrdinal;--stackTop;}}
if(postOrderIndex===nodeCount||iteration>1)
break;var errors=new WebInspector.HeapSnapshotProblemReport("Heap snapshot: "+(nodeCount-postOrderIndex)+" nodes are unreachable from the root. Following nodes have only weak retainers:");var dumpNode=this.rootNode();--postOrderIndex;stackTop=0;stackNodes[0]=rootNodeOrdinal;stackCurrentEdge[0]=firstEdgeIndexes[rootNodeOrdinal+1];for(var i=0;i<nodeCount;++i){if(!visited[i]){dumpNode.nodeIndex=i*nodeFieldCount;if(this._hasOnlyWeakRetainers(i)){stackNodes[++stackTop]=i;stackCurrentEdge[stackTop]=firstEdgeIndexes[i];visited[i]=1;errors.addError(dumpNode.name()+" @"+dumpNode.id());}}}
console.warn(errors.toString());}
if(postOrderIndex!==nodeCount){var errors=new WebInspector.HeapSnapshotProblemReport("Still found "+(nodeCount-postOrderIndex)+" unreachable nodes in heap snapshot:");var dumpNode=this.rootNode();--postOrderIndex;for(var i=0;i<nodeCount;++i){if(visited[i])
continue;dumpNode.nodeIndex=i*nodeFieldCount;errors.addError(dumpNode.name()+" @"+dumpNode.id());nodeOrdinal2PostOrderIndex[i]=postOrderIndex;postOrderIndex2NodeOrdinal[postOrderIndex++]=i;}
nodeOrdinal2PostOrderIndex[rootNodeOrdinal]=postOrderIndex;postOrderIndex2NodeOrdinal[postOrderIndex++]=rootNodeOrdinal;console.warn(errors.toString());}
return{postOrderIndex2NodeOrdinal:postOrderIndex2NodeOrdinal,nodeOrdinal2PostOrderIndex:nodeOrdinal2PostOrderIndex};},_hasOnlyWeakRetainers:function(nodeOrdinal)
{var edgeTypeOffset=this._edgeTypeOffset;var edgeWeakType=this._edgeWeakType;var edgeShortcutType=this._edgeShortcutType;var containmentEdges=this.containmentEdges;var retainingEdges=this._retainingEdges;var beginRetainerIndex=this._firstRetainerIndex[nodeOrdinal];var endRetainerIndex=this._firstRetainerIndex[nodeOrdinal+1];for(var retainerIndex=beginRetainerIndex;retainerIndex<endRetainerIndex;++retainerIndex){var retainerEdgeIndex=retainingEdges[retainerIndex];var retainerEdgeType=containmentEdges[retainerEdgeIndex+edgeTypeOffset];if(retainerEdgeType!==edgeWeakType&&retainerEdgeType!==edgeShortcutType)
return false;}
return true;},_buildDominatorTree:function(postOrderIndex2NodeOrdinal,nodeOrdinal2PostOrderIndex)
{var nodeFieldCount=this._nodeFieldCount;var firstRetainerIndex=this._firstRetainerIndex;var retainingNodes=this._retainingNodes;var retainingEdges=this._retainingEdges;var edgeFieldsCount=this._edgeFieldsCount;var edgeTypeOffset=this._edgeTypeOffset;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeShortcutType=this._edgeShortcutType;var edgeWeakType=this._edgeWeakType;var firstEdgeIndexes=this._firstEdgeIndexes;var containmentEdges=this.containmentEdges;var rootNodeIndex=this._rootNodeIndex;var mapAndFlag=this.userObjectsMapAndFlag();var flags=mapAndFlag?mapAndFlag.map:null;var flag=mapAndFlag?mapAndFlag.flag:0;var nodesCount=postOrderIndex2NodeOrdinal.length;var rootPostOrderedIndex=nodesCount-1;var noEntry=nodesCount;var dominators=new Uint32Array(nodesCount);for(var i=0;i<rootPostOrderedIndex;++i)
dominators[i]=noEntry;dominators[rootPostOrderedIndex]=rootPostOrderedIndex;var affected=new Uint8Array(nodesCount);var nodeOrdinal;{nodeOrdinal=this._rootNodeIndex/nodeFieldCount;var endEdgeIndex=firstEdgeIndexes[nodeOrdinal+1];for(var edgeIndex=firstEdgeIndexes[nodeOrdinal];edgeIndex<endEdgeIndex;edgeIndex+=edgeFieldsCount){var edgeType=containmentEdges[edgeIndex+edgeTypeOffset];if(edgeType===edgeWeakType||edgeType===edgeShortcutType)
continue;var childNodeOrdinal=containmentEdges[edgeIndex+edgeToNodeOffset]/nodeFieldCount;affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]]=1;}}
var changed=true;while(changed){changed=false;for(var postOrderIndex=rootPostOrderedIndex-1;postOrderIndex>=0;--postOrderIndex){if(affected[postOrderIndex]===0)
continue;affected[postOrderIndex]=0;if(dominators[postOrderIndex]===rootPostOrderedIndex)
continue;nodeOrdinal=postOrderIndex2NodeOrdinal[postOrderIndex];var nodeFlag=!flags||(flags[nodeOrdinal]&flag);var newDominatorIndex=noEntry;var beginRetainerIndex=firstRetainerIndex[nodeOrdinal];var endRetainerIndex=firstRetainerIndex[nodeOrdinal+1];var orphanNode=true;for(var retainerIndex=beginRetainerIndex;retainerIndex<endRetainerIndex;++retainerIndex){var retainerEdgeIndex=retainingEdges[retainerIndex];var retainerEdgeType=containmentEdges[retainerEdgeIndex+edgeTypeOffset];if(retainerEdgeType===edgeWeakType||retainerEdgeType===edgeShortcutType)
continue;orphanNode=false;var retainerNodeIndex=retainingNodes[retainerIndex];var retainerNodeOrdinal=retainerNodeIndex/nodeFieldCount;var retainerNodeFlag=!flags||(flags[retainerNodeOrdinal]&flag);if(retainerNodeIndex!==rootNodeIndex&&nodeFlag&&!retainerNodeFlag)
continue;var retanerPostOrderIndex=nodeOrdinal2PostOrderIndex[retainerNodeOrdinal];if(dominators[retanerPostOrderIndex]!==noEntry){if(newDominatorIndex===noEntry)
newDominatorIndex=retanerPostOrderIndex;else{while(retanerPostOrderIndex!==newDominatorIndex){while(retanerPostOrderIndex<newDominatorIndex)
retanerPostOrderIndex=dominators[retanerPostOrderIndex];while(newDominatorIndex<retanerPostOrderIndex)
newDominatorIndex=dominators[newDominatorIndex];}}
if(newDominatorIndex===rootPostOrderedIndex)
break;}}
if(orphanNode)
newDominatorIndex=rootPostOrderedIndex;if(newDominatorIndex!==noEntry&&dominators[postOrderIndex]!==newDominatorIndex){dominators[postOrderIndex]=newDominatorIndex;changed=true;nodeOrdinal=postOrderIndex2NodeOrdinal[postOrderIndex];var beginEdgeToNodeFieldIndex=firstEdgeIndexes[nodeOrdinal]+edgeToNodeOffset;var endEdgeToNodeFieldIndex=firstEdgeIndexes[nodeOrdinal+1];for(var toNodeFieldIndex=beginEdgeToNodeFieldIndex;toNodeFieldIndex<endEdgeToNodeFieldIndex;toNodeFieldIndex+=edgeFieldsCount){var childNodeOrdinal=containmentEdges[toNodeFieldIndex]/nodeFieldCount;affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]]=1;}}}}
var dominatorsTree=new Uint32Array(nodesCount);for(var postOrderIndex=0,l=dominators.length;postOrderIndex<l;++postOrderIndex){nodeOrdinal=postOrderIndex2NodeOrdinal[postOrderIndex];dominatorsTree[nodeOrdinal]=postOrderIndex2NodeOrdinal[dominators[postOrderIndex]];}
return dominatorsTree;},_calculateRetainedSizes:function(postOrderIndex2NodeOrdinal)
{var nodeCount=this.nodeCount;var nodes=this.nodes;var nodeSelfSizeOffset=this._nodeSelfSizeOffset;var nodeFieldCount=this._nodeFieldCount;var dominatorsTree=this._dominatorsTree;var retainedSizes=this._retainedSizes;for(var nodeOrdinal=0;nodeOrdinal<nodeCount;++nodeOrdinal)
retainedSizes[nodeOrdinal]=nodes[nodeOrdinal*nodeFieldCount+nodeSelfSizeOffset];for(var postOrderIndex=0;postOrderIndex<nodeCount-1;++postOrderIndex){var nodeOrdinal=postOrderIndex2NodeOrdinal[postOrderIndex];var dominatorOrdinal=dominatorsTree[nodeOrdinal];retainedSizes[dominatorOrdinal]+=retainedSizes[nodeOrdinal];}},_buildDominatedNodes:function()
{var indexArray=this._firstDominatedNodeIndex;var dominatedNodes=this._dominatedNodes;var nodeFieldCount=this._nodeFieldCount;var dominatorsTree=this._dominatorsTree;var fromNodeOrdinal=0;var toNodeOrdinal=this.nodeCount;var rootNodeOrdinal=this._rootNodeIndex/nodeFieldCount;if(rootNodeOrdinal===fromNodeOrdinal)
fromNodeOrdinal=1;else if(rootNodeOrdinal===toNodeOrdinal-1)
toNodeOrdinal=toNodeOrdinal-1;else
throw new Error("Root node is expected to be either first or last");for(var nodeOrdinal=fromNodeOrdinal;nodeOrdinal<toNodeOrdinal;++nodeOrdinal)
++indexArray[dominatorsTree[nodeOrdinal]];var firstDominatedNodeIndex=0;for(var i=0,l=this.nodeCount;i<l;++i){var dominatedCount=dominatedNodes[firstDominatedNodeIndex]=indexArray[i];indexArray[i]=firstDominatedNodeIndex;firstDominatedNodeIndex+=dominatedCount;}
indexArray[this.nodeCount]=dominatedNodes.length;for(var nodeOrdinal=fromNodeOrdinal;nodeOrdinal<toNodeOrdinal;++nodeOrdinal){var dominatorOrdinal=dominatorsTree[nodeOrdinal];var dominatedRefIndex=indexArray[dominatorOrdinal];dominatedRefIndex+=(--dominatedNodes[dominatedRefIndex]);dominatedNodes[dominatedRefIndex]=nodeOrdinal*nodeFieldCount;}},_buildSamples:function()
{var samples=this._rawSamples;if(!samples||!samples.length)
return;var sampleCount=samples.length/2;var sizeForRange=new Array(sampleCount);var timestamps=new Array(sampleCount);var lastAssignedIds=new Array(sampleCount);var timestampOffset=this._metaNode.sample_fields.indexOf("timestamp_us");var lastAssignedIdOffset=this._metaNode.sample_fields.indexOf("last_assigned_id");for(var i=0;i<sampleCount;i++){sizeForRange[i]=0;timestamps[i]=(samples[2*i+timestampOffset])/1000;lastAssignedIds[i]=samples[2*i+lastAssignedIdOffset];}
var nodes=this.nodes;var nodesLength=nodes.length;var nodeFieldCount=this._nodeFieldCount;var node=this.rootNode();for(var nodeIndex=0;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){node.nodeIndex=nodeIndex;var nodeId=node.id();if(nodeId%2===0)
continue;var rangeIndex=lastAssignedIds.lowerBound(nodeId);if(rangeIndex===sampleCount){continue;}
sizeForRange[rangeIndex]+=node.selfSize();}
this._samples=new WebInspector.HeapSnapshotCommon.Samples(timestamps,lastAssignedIds,sizeForRange);},getSamples:function()
{return this._samples;},_calculateFlags:function()
{throw new Error("Not implemented");},_calculateStatistics:function()
{throw new Error("Not implemented");},userObjectsMapAndFlag:function()
{throw new Error("Not implemented");},calculateSnapshotDiff:function(baseSnapshotId,baseSnapshotAggregates)
{var snapshotDiff=this._snapshotDiffs[baseSnapshotId];if(snapshotDiff)
return snapshotDiff;snapshotDiff={};var aggregates=this.aggregates(true,"allObjects");for(var className in baseSnapshotAggregates){var baseAggregate=baseSnapshotAggregates[className];var diff=this._calculateDiffForClass(baseAggregate,aggregates[className]);if(diff)
snapshotDiff[className]=diff;}
var emptyBaseAggregate=new WebInspector.HeapSnapshotCommon.AggregateForDiff();for(var className in aggregates){if(className in baseSnapshotAggregates)
continue;snapshotDiff[className]=this._calculateDiffForClass(emptyBaseAggregate,aggregates[className]);}
this._snapshotDiffs[baseSnapshotId]=snapshotDiff;return snapshotDiff;},_calculateDiffForClass:function(baseAggregate,aggregate)
{var baseIds=baseAggregate.ids;var baseIndexes=baseAggregate.indexes;var baseSelfSizes=baseAggregate.selfSizes;var indexes=aggregate?aggregate.idxs:[];var i=0,l=baseIds.length;var j=0,m=indexes.length;var diff=new WebInspector.HeapSnapshotCommon.Diff();var nodeB=this.createNode(indexes[j]);while(i<l&&j<m){var nodeAId=baseIds[i];if(nodeAId<nodeB.id()){diff.deletedIndexes.push(baseIndexes[i]);diff.removedCount++;diff.removedSize+=baseSelfSizes[i];++i;}else if(nodeAId>nodeB.id()){diff.addedIndexes.push(indexes[j]);diff.addedCount++;diff.addedSize+=nodeB.selfSize();nodeB.nodeIndex=indexes[++j];}else{++i;nodeB.nodeIndex=indexes[++j];}}
while(i<l){diff.deletedIndexes.push(baseIndexes[i]);diff.removedCount++;diff.removedSize+=baseSelfSizes[i];++i;}
while(j<m){diff.addedIndexes.push(indexes[j]);diff.addedCount++;diff.addedSize+=nodeB.selfSize();nodeB.nodeIndex=indexes[++j];}
diff.countDelta=diff.addedCount-diff.removedCount;diff.sizeDelta=diff.addedSize-diff.removedSize;if(!diff.addedCount&&!diff.removedCount)
return null;return diff;},_nodeForSnapshotObjectId:function(snapshotObjectId)
{for(var it=this._allNodes();it.hasNext();it.next()){if(it.node.id()===snapshotObjectId)
return it.node;}
return null;},nodeClassName:function(snapshotObjectId)
{var node=this._nodeForSnapshotObjectId(snapshotObjectId);if(node)
return node.className();return null;},idsOfObjectsWithName:function(name)
{var ids=[];for(var it=this._allNodes();it.hasNext();it.next()){if(it.item().name()===name)
ids.push(it.item().id());}
return ids;},createEdgesProvider:function(nodeIndex)
{var node=this.createNode(nodeIndex);var filter=this.containmentEdgesFilter();var indexProvider=new WebInspector.HeapSnapshotEdgeIndexProvider(this);return new WebInspector.HeapSnapshotEdgesProvider(this,filter,node.edges(),indexProvider);},createEdgesProviderForTest:function(nodeIndex,filter)
{var node=this.createNode(nodeIndex);var indexProvider=new WebInspector.HeapSnapshotEdgeIndexProvider(this);return new WebInspector.HeapSnapshotEdgesProvider(this,filter,node.edges(),indexProvider);},retainingEdgesFilter:function()
{return null;},containmentEdgesFilter:function()
{return null;},createRetainingEdgesProvider:function(nodeIndex)
{var node=this.createNode(nodeIndex);var filter=this.retainingEdgesFilter();var indexProvider=new WebInspector.HeapSnapshotRetainerEdgeIndexProvider(this);return new WebInspector.HeapSnapshotEdgesProvider(this,filter,node.retainers(),indexProvider);},createAddedNodesProvider:function(baseSnapshotId,className)
{var snapshotDiff=this._snapshotDiffs[baseSnapshotId];var diffForClass=snapshotDiff[className];return new WebInspector.HeapSnapshotNodesProvider(this,null,diffForClass.addedIndexes);},createDeletedNodesProvider:function(nodeIndexes)
{return new WebInspector.HeapSnapshotNodesProvider(this,null,nodeIndexes);},classNodesFilter:function()
{return null;},createNodesProviderForClass:function(className,nodeFilter)
{return new WebInspector.HeapSnapshotNodesProvider(this,this.classNodesFilter(),this.aggregatesWithFilter(nodeFilter)[className].idxs);},_maxJsNodeId:function()
{var nodeFieldCount=this._nodeFieldCount;var nodes=this.nodes;var nodesLength=nodes.length;var id=0;for(var nodeIndex=this._nodeIdOffset;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){var nextId=nodes[nodeIndex];if(nextId%2===0)
continue;if(id<nextId)
id=nextId;}
return id;},updateStaticData:function()
{return new WebInspector.HeapSnapshotCommon.StaticData(this.nodeCount,this._rootNodeIndex,this.totalSize,this._maxJsNodeId());}};WebInspector.HeapSnapshotItemProvider=function(iterator,indexProvider)
{this._iterator=iterator;this._indexProvider=indexProvider;this._isEmpty=!iterator.hasNext();this._iterationOrder=null;this._currentComparator=null;this._sortedPrefixLength=0;this._sortedSuffixLength=0;}
WebInspector.HeapSnapshotItemProvider.prototype={_createIterationOrder:function()
{if(this._iterationOrder)
return;this._iterationOrder=[];for(var iterator=this._iterator;iterator.hasNext();iterator.next())
this._iterationOrder.push(iterator.item().itemIndex());},isEmpty:function()
{return this._isEmpty;},serializeItemsRange:function(begin,end)
{this._createIterationOrder();if(begin>end)
throw new Error("Start position > end position: "+begin+" > "+end);if(end>this._iterationOrder.length)
end=this._iterationOrder.length;if(this._sortedPrefixLength<end&&begin<this._iterationOrder.length-this._sortedSuffixLength){this.sort(this._currentComparator,this._sortedPrefixLength,this._iterationOrder.length-1-this._sortedSuffixLength,begin,end-1);if(begin<=this._sortedPrefixLength)
this._sortedPrefixLength=end;if(end>=this._iterationOrder.length-this._sortedSuffixLength)
this._sortedSuffixLength=this._iterationOrder.length-begin;}
var position=begin;var count=end-begin;var result=new Array(count);for(var i=0;i<count;++i){var itemIndex=this._iterationOrder[position++];var item=this._indexProvider.itemForIndex(itemIndex);result[i]=item.serialize();}
return new WebInspector.HeapSnapshotCommon.ItemsRange(begin,end,this._iterationOrder.length,result);},sortAndRewind:function(comparator)
{this._currentComparator=comparator;this._sortedPrefixLength=0;this._sortedSuffixLength=0;}}
WebInspector.HeapSnapshotEdgesProvider=function(snapshot,filter,edgesIter,indexProvider)
{this.snapshot=snapshot;var iter=filter?new WebInspector.HeapSnapshotFilteredIterator(edgesIter,(filter)):edgesIter;WebInspector.HeapSnapshotItemProvider.call(this,iter,indexProvider);}
WebInspector.HeapSnapshotEdgesProvider.prototype={sort:function(comparator,leftBound,rightBound,windowLeft,windowRight)
{var fieldName1=comparator.fieldName1;var fieldName2=comparator.fieldName2;var ascending1=comparator.ascending1;var ascending2=comparator.ascending2;var edgeA=this._iterator.item().clone();var edgeB=edgeA.clone();var nodeA=this.snapshot.createNode();var nodeB=this.snapshot.createNode();function compareEdgeFieldName(ascending,indexA,indexB)
{edgeA.edgeIndex=indexA;edgeB.edgeIndex=indexB;if(edgeB.name()==="__proto__")return-1;if(edgeA.name()==="__proto__")return 1;var result=edgeA.hasStringName()===edgeB.hasStringName()?(edgeA.name()<edgeB.name()?-1:(edgeA.name()>edgeB.name()?1:0)):(edgeA.hasStringName()?-1:1);return ascending?result:-result;}
function compareNodeField(fieldName,ascending,indexA,indexB)
{edgeA.edgeIndex=indexA;nodeA.nodeIndex=edgeA.nodeIndex();var valueA=nodeA[fieldName]();edgeB.edgeIndex=indexB;nodeB.nodeIndex=edgeB.nodeIndex();var valueB=nodeB[fieldName]();var result=valueA<valueB?-1:(valueA>valueB?1:0);return ascending?result:-result;}
function compareEdgeAndNode(indexA,indexB){var result=compareEdgeFieldName(ascending1,indexA,indexB);if(result===0)
result=compareNodeField(fieldName2,ascending2,indexA,indexB);if(result===0)
return indexA-indexB;return result;}
function compareNodeAndEdge(indexA,indexB){var result=compareNodeField(fieldName1,ascending1,indexA,indexB);if(result===0)
result=compareEdgeFieldName(ascending2,indexA,indexB);if(result===0)
return indexA-indexB;return result;}
function compareNodeAndNode(indexA,indexB){var result=compareNodeField(fieldName1,ascending1,indexA,indexB);if(result===0)
result=compareNodeField(fieldName2,ascending2,indexA,indexB);if(result===0)
return indexA-indexB;return result;}
if(fieldName1==="!edgeName")
this._iterationOrder.sortRange(compareEdgeAndNode,leftBound,rightBound,windowLeft,windowRight);else if(fieldName2==="!edgeName")
this._iterationOrder.sortRange(compareNodeAndEdge,leftBound,rightBound,windowLeft,windowRight);else
this._iterationOrder.sortRange(compareNodeAndNode,leftBound,rightBound,windowLeft,windowRight);},__proto__:WebInspector.HeapSnapshotItemProvider.prototype}
WebInspector.HeapSnapshotNodesProvider=function(snapshot,filter,nodeIndexes)
{this.snapshot=snapshot;var indexProvider=new WebInspector.HeapSnapshotNodeIndexProvider(snapshot);var it=new WebInspector.HeapSnapshotIndexRangeIterator(indexProvider,nodeIndexes);if(filter)
it=new WebInspector.HeapSnapshotFilteredIterator(it,(filter));WebInspector.HeapSnapshotItemProvider.call(this,it,indexProvider);}
WebInspector.HeapSnapshotNodesProvider.prototype={nodePosition:function(snapshotObjectId)
{this._createIterationOrder();var node=this.snapshot.createNode();for(var i=0;i<this._iterationOrder.length;i++){node.nodeIndex=this._iterationOrder[i];if(node.id()===snapshotObjectId)
break;}
if(i===this._iterationOrder.length)
return-1;var targetNodeIndex=this._iterationOrder[i];var smallerCount=0;var compare=this._buildCompareFunction(this._currentComparator);for(var i=0;i<this._iterationOrder.length;i++){if(compare(this._iterationOrder[i],targetNodeIndex)<0)
++smallerCount;}
return smallerCount;},_buildCompareFunction:function(comparator)
{var nodeA=this.snapshot.createNode();var nodeB=this.snapshot.createNode();var fieldAccessor1=nodeA[comparator.fieldName1];var fieldAccessor2=nodeA[comparator.fieldName2];var ascending1=comparator.ascending1?1:-1;var ascending2=comparator.ascending2?1:-1;function sortByNodeField(fieldAccessor,ascending)
{var valueA=fieldAccessor.call(nodeA);var valueB=fieldAccessor.call(nodeB);return valueA<valueB?-ascending:(valueA>valueB?ascending:0);}
function sortByComparator(indexA,indexB)
{nodeA.nodeIndex=indexA;nodeB.nodeIndex=indexB;var result=sortByNodeField(fieldAccessor1,ascending1);if(result===0)
result=sortByNodeField(fieldAccessor2,ascending2);return result||indexA-indexB;}
return sortByComparator;},sort:function(comparator,leftBound,rightBound,windowLeft,windowRight)
{this._iterationOrder.sortRange(this._buildCompareFunction(comparator),leftBound,rightBound,windowLeft,windowRight);},__proto__:WebInspector.HeapSnapshotItemProvider.prototype};WebInspector.HeapSnapshotLoader=function(dispatcher)
{this._reset();this._progress=new WebInspector.HeapSnapshotProgress(dispatcher);}
WebInspector.HeapSnapshotLoader.prototype={dispose:function()
{this._reset();},_reset:function()
{this._json="";this._state="find-snapshot-info";this._snapshot={};},close:function()
{if(this._json)
this._parseStringsArray();},buildSnapshot:function(showHiddenData)
{this._progress.updateStatus("Processing snapshot\u2026");var result=new WebInspector.JSHeapSnapshot(this._snapshot,this._progress,showHiddenData);this._reset();return result;},_parseUintArray:function()
{var index=0;var char0="0".charCodeAt(0),char9="9".charCodeAt(0),closingBracket="]".charCodeAt(0);var length=this._json.length;while(true){while(index<length){var code=this._json.charCodeAt(index);if(char0<=code&&code<=char9)
break;else if(code===closingBracket){this._json=this._json.slice(index+1);return false;}
++index;}
if(index===length){this._json="";return true;}
var nextNumber=0;var startIndex=index;while(index<length){var code=this._json.charCodeAt(index);if(char0>code||code>char9)
break;nextNumber*=10;nextNumber+=(code-char0);++index;}
if(index===length){this._json=this._json.slice(startIndex);return true;}
this._array[this._arrayIndex++]=nextNumber;}},_parseStringsArray:function()
{this._progress.updateStatus("Parsing strings\u2026");var closingBracketIndex=this._json.lastIndexOf("]");if(closingBracketIndex===-1)
throw new Error("Incomplete JSON");this._json=this._json.slice(0,closingBracketIndex+1);this._snapshot.strings=JSON.parse(this._json);},write:function(chunk)
{if(this._json!==null)
this._json+=chunk;while(true){switch(this._state){case"find-snapshot-info":{var snapshotToken="\"snapshot\"";var snapshotTokenIndex=this._json.indexOf(snapshotToken);if(snapshotTokenIndex===-1)
throw new Error("Snapshot token not found");var json=this._json.slice(snapshotTokenIndex+snapshotToken.length+1);this._state="parse-snapshot-info";this._progress.updateStatus("Loading snapshot info\u2026");this._json=null;this._jsonTokenizer=new WebInspector.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this));chunk=json;}
case"parse-snapshot-info":{this._jsonTokenizer.write(chunk);if(this._jsonTokenizer)
return;break;}
case"find-nodes":{var nodesToken="\"nodes\"";var nodesTokenIndex=this._json.indexOf(nodesToken);if(nodesTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",nodesTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex+1);var node_fields_count=this._snapshot.snapshot.meta.node_fields.length;var nodes_length=this._snapshot.snapshot.node_count*node_fields_count;this._array=new Uint32Array(nodes_length);this._arrayIndex=0;this._state="parse-nodes";break;}
case"parse-nodes":{var hasMoreData=this._parseUintArray();this._progress.updateProgress("Loading nodes\u2026 %d%%",this._arrayIndex,this._array.length);if(hasMoreData)
return;this._snapshot.nodes=this._array;this._state="find-edges";this._array=null;break;}
case"find-edges":{var edgesToken="\"edges\"";var edgesTokenIndex=this._json.indexOf(edgesToken);if(edgesTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",edgesTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex+1);var edge_fields_count=this._snapshot.snapshot.meta.edge_fields.length;var edges_length=this._snapshot.snapshot.edge_count*edge_fields_count;this._array=new Uint32Array(edges_length);this._arrayIndex=0;this._state="parse-edges";break;}
case"parse-edges":{var hasMoreData=this._parseUintArray();this._progress.updateProgress("Loading edges\u2026 %d%%",this._arrayIndex,this._array.length);if(hasMoreData)
return;this._snapshot.edges=this._array;this._array=null;if(this._snapshot.snapshot.trace_function_count){this._state="find-trace-function-infos";this._progress.updateStatus("Loading allocation traces\u2026");}else if(this._snapshot.snapshot.meta.sample_fields){this._state="find-samples";this._progress.updateStatus("Loading samples\u2026");}else{this._state="find-strings";}
break;}
case"find-trace-function-infos":{var tracesToken="\"trace_function_infos\"";var tracesTokenIndex=this._json.indexOf(tracesToken);if(tracesTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",tracesTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex+1);var trace_function_info_field_count=this._snapshot.snapshot.meta.trace_function_info_fields.length;var trace_function_info_length=this._snapshot.snapshot.trace_function_count*trace_function_info_field_count;this._array=new Uint32Array(trace_function_info_length);this._arrayIndex=0;this._state="parse-trace-function-infos";break;}
case"parse-trace-function-infos":{if(this._parseUintArray())
return;this._snapshot.trace_function_infos=this._array;this._array=null;this._state="find-trace-tree";break;}
case"find-trace-tree":{var tracesToken="\"trace_tree\"";var tracesTokenIndex=this._json.indexOf(tracesToken);if(tracesTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",tracesTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex);this._state="parse-trace-tree";break;}
case"parse-trace-tree":{var nextToken=this._snapshot.snapshot.meta.sample_fields?"\"samples\"":"\"strings\"";var nextTokenIndex=this._json.indexOf(nextToken);if(nextTokenIndex===-1)
return;var bracketIndex=this._json.lastIndexOf("]",nextTokenIndex);this._snapshot.trace_tree=JSON.parse(this._json.substring(0,bracketIndex+1));this._json=this._json.slice(bracketIndex+1);if(this._snapshot.snapshot.meta.sample_fields){this._state="find-samples";this._progress.updateStatus("Loading samples\u2026");}else{this._state="find-strings";this._progress.updateStatus("Loading strings\u2026");}
break;}
case"find-samples":{var samplesToken="\"samples\"";var samplesTokenIndex=this._json.indexOf(samplesToken);if(samplesTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",samplesTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex+1);this._array=[];this._arrayIndex=0;this._state="parse-samples";break;}
case"parse-samples":{if(this._parseUintArray())
return;this._snapshot.samples=this._array;this._array=null;this._state="find-strings";this._progress.updateStatus("Loading strings\u2026");break;}
case"find-strings":{var stringsToken="\"strings\"";var stringsTokenIndex=this._json.indexOf(stringsToken);if(stringsTokenIndex===-1)
return;var bracketIndex=this._json.indexOf("[",stringsTokenIndex);if(bracketIndex===-1)
return;this._json=this._json.slice(bracketIndex);this._state="accumulate-strings";break;}
case"accumulate-strings":return;}}},_writeBalancedJSON:function(data)
{this._json=this._jsonTokenizer.remainder();this._jsonTokenizer=null;this._state="find-nodes";this._snapshot.snapshot=(JSON.parse(data));}};WebInspector.HeapSnapshotWorkerDispatcher=function(globalObject,postMessage)
{this._objects=[];this._global=globalObject;this._postMessage=postMessage;}
WebInspector.HeapSnapshotWorkerDispatcher.prototype={_findFunction:function(name)
{var path=name.split(".");var result=this._global;for(var i=0;i<path.length;++i)
result=result[path[i]];return result;},sendEvent:function(name,data)
{this._postMessage({eventName:name,data:data});},dispatchMessage:function(event)
{var data=(event.data);var response={callId:data.callId};try{switch(data.disposition){case"create":{var constructorFunction=this._findFunction(data.methodName);this._objects[data.objectId]=new constructorFunction(this);break;}
case"dispose":{delete this._objects[data.objectId];break;}
case"getter":{var object=this._objects[data.objectId];var result=object[data.methodName];response.result=result;break;}
case"factory":{var object=this._objects[data.objectId];var result=object[data.methodName].apply(object,data.methodArguments);if(result)
this._objects[data.newObjectId]=result;response.result=!!result;break;}
case"method":{var object=this._objects[data.objectId];response.result=object[data.methodName].apply(object,data.methodArguments);break;}
case"evaluateForTest":{try{response.result=eval(data.source);}catch(e){response.result=e.toString();}
break;}}}catch(e){response.error=e.toString();response.errorCallStack=e.stack;if(data.methodName)
response.errorMethodName=data.methodName;}
this._postMessage(response);}};;WebInspector.JSHeapSnapshot=function(profile,progress,showHiddenData)
{this._nodeFlags={canBeQueried:1,detachedDOMTreeNode:2,pageObject:4,visitedMarkerMask:0x0ffff,visitedMarker:0x10000};this._lazyStringCache={};this._showHiddenData=showHiddenData;WebInspector.HeapSnapshot.call(this,profile,progress);}
WebInspector.JSHeapSnapshot.prototype={createNode:function(nodeIndex)
{return new WebInspector.JSHeapSnapshotNode(this,nodeIndex===undefined?-1:nodeIndex);},createEdge:function(edgeIndex)
{return new WebInspector.JSHeapSnapshotEdge(this,edgeIndex);},createRetainingEdge:function(retainerIndex)
{return new WebInspector.JSHeapSnapshotRetainerEdge(this,retainerIndex);},classNodesFilter:function()
{var mapAndFlag=this.userObjectsMapAndFlag();if(!mapAndFlag)
return null;var map=mapAndFlag.map;var flag=mapAndFlag.flag;function filter(node)
{return!!(map[node.ordinal()]&flag);}
return filter;},containmentEdgesFilter:function()
{var showHiddenData=this._showHiddenData;function filter(edge)
{if(edge.isInvisible())
return false;if(showHiddenData)
return true;return!edge.isHidden()&&!edge.node().isHidden();}
return filter;},retainingEdgesFilter:function()
{var containmentEdgesFilter=this.containmentEdgesFilter();function filter(edge)
{return containmentEdgesFilter(edge)&&!edge.node().isRoot()&&!edge.isWeak();}
return filter;},_calculateFlags:function()
{this._flags=new Uint32Array(this.nodeCount);this._markDetachedDOMTreeNodes();this._markQueriableHeapObjects();this._markPageOwnedNodes();},calculateDistances:function()
{function filter(node,edge)
{if(node.isHidden())
return edge.name()!=="sloppy_function_map"||node.rawName()!=="system / NativeContext";if(node.isArray()){if(node.rawName()!=="(map descriptors)")
return true;var index=edge.name();return index<2||(index%3)!==1;}
return true;}
WebInspector.HeapSnapshot.prototype.calculateDistances.call(this,filter);},isUserRoot:function(node)
{return node.isUserRoot()||node.isDocumentDOMTreesRoot();},forEachRoot:function(action,userRootsOnly)
{function getChildNodeByName(node,name)
{for(var iter=node.edges();iter.hasNext();iter.next()){var child=iter.edge.node();if(child.name()===name)
return child;}
return null;}
var visitedNodes={};function doAction(node)
{var ordinal=node.ordinal();if(!visitedNodes[ordinal]){action(node);visitedNodes[ordinal]=true;}}
var gcRoots=getChildNodeByName(this.rootNode(),"(GC roots)");if(!gcRoots)
return;if(userRootsOnly){for(var iter=this.rootNode().edges();iter.hasNext();iter.next()){var node=iter.edge.node();if(this.isUserRoot(node))
doAction(node);}}else{for(var iter=gcRoots.edges();iter.hasNext();iter.next()){var subRoot=iter.edge.node();for(var iter2=subRoot.edges();iter2.hasNext();iter2.next())
doAction(iter2.edge.node());doAction(subRoot);}
for(var iter=this.rootNode().edges();iter.hasNext();iter.next())
doAction(iter.edge.node());}},userObjectsMapAndFlag:function()
{return this._showHiddenData?null:{map:this._flags,flag:this._nodeFlags.pageObject};},_flagsOfNode:function(node)
{return this._flags[node.nodeIndex/this._nodeFieldCount];},_markDetachedDOMTreeNodes:function()
{var flag=this._nodeFlags.detachedDOMTreeNode;var detachedDOMTreesRoot;for(var iter=this.rootNode().edges();iter.hasNext();iter.next()){var node=iter.edge.node();if(node.name()==="(Detached DOM trees)"){detachedDOMTreesRoot=node;break;}}
if(!detachedDOMTreesRoot)
return;var detachedDOMTreeRE=/^Detached DOM tree/;for(var iter=detachedDOMTreesRoot.edges();iter.hasNext();iter.next()){var node=iter.edge.node();if(detachedDOMTreeRE.test(node.className())){for(var edgesIter=node.edges();edgesIter.hasNext();edgesIter.next())
this._flags[edgesIter.edge.node().nodeIndex/this._nodeFieldCount]|=flag;}}},_markQueriableHeapObjects:function()
{var flag=this._nodeFlags.canBeQueried;var hiddenEdgeType=this._edgeHiddenType;var internalEdgeType=this._edgeInternalType;var invisibleEdgeType=this._edgeInvisibleType;var weakEdgeType=this._edgeWeakType;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeTypeOffset=this._edgeTypeOffset;var edgeFieldsCount=this._edgeFieldsCount;var containmentEdges=this.containmentEdges;var nodeFieldCount=this._nodeFieldCount;var firstEdgeIndexes=this._firstEdgeIndexes;var flags=this._flags;var list=[];for(var iter=this.rootNode().edges();iter.hasNext();iter.next()){if(iter.edge.node().isUserRoot())
list.push(iter.edge.node().nodeIndex/nodeFieldCount);}
while(list.length){var nodeOrdinal=list.pop();if(flags[nodeOrdinal]&flag)
continue;flags[nodeOrdinal]|=flag;var beginEdgeIndex=firstEdgeIndexes[nodeOrdinal];var endEdgeIndex=firstEdgeIndexes[nodeOrdinal+1];for(var edgeIndex=beginEdgeIndex;edgeIndex<endEdgeIndex;edgeIndex+=edgeFieldsCount){var childNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];var childNodeOrdinal=childNodeIndex/nodeFieldCount;if(flags[childNodeOrdinal]&flag)
continue;var type=containmentEdges[edgeIndex+edgeTypeOffset];if(type===hiddenEdgeType||type===invisibleEdgeType||type===internalEdgeType||type===weakEdgeType)
continue;list.push(childNodeOrdinal);}}},_markPageOwnedNodes:function()
{var edgeShortcutType=this._edgeShortcutType;var edgeElementType=this._edgeElementType;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeTypeOffset=this._edgeTypeOffset;var edgeFieldsCount=this._edgeFieldsCount;var edgeWeakType=this._edgeWeakType;var firstEdgeIndexes=this._firstEdgeIndexes;var containmentEdges=this.containmentEdges;var nodeFieldCount=this._nodeFieldCount;var nodesCount=this.nodeCount;var flags=this._flags;var flag=this._nodeFlags.pageObject;var visitedMarker=this._nodeFlags.visitedMarker;var visitedMarkerMask=this._nodeFlags.visitedMarkerMask;var markerAndFlag=visitedMarker|flag;var nodesToVisit=new Uint32Array(nodesCount);var nodesToVisitLength=0;var rootNodeOrdinal=this._rootNodeIndex/nodeFieldCount;var node=this.rootNode();for(var edgeIndex=firstEdgeIndexes[rootNodeOrdinal],endEdgeIndex=firstEdgeIndexes[rootNodeOrdinal+1];edgeIndex<endEdgeIndex;edgeIndex+=edgeFieldsCount){var edgeType=containmentEdges[edgeIndex+edgeTypeOffset];var nodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];if(edgeType===edgeElementType){node.nodeIndex=nodeIndex;if(!node.isDocumentDOMTreesRoot())
continue;}else if(edgeType!==edgeShortcutType)
continue;var nodeOrdinal=nodeIndex/nodeFieldCount;nodesToVisit[nodesToVisitLength++]=nodeOrdinal;flags[nodeOrdinal]|=visitedMarker;}
while(nodesToVisitLength){var nodeOrdinal=nodesToVisit[--nodesToVisitLength];flags[nodeOrdinal]|=flag;flags[nodeOrdinal]&=visitedMarkerMask;var beginEdgeIndex=firstEdgeIndexes[nodeOrdinal];var endEdgeIndex=firstEdgeIndexes[nodeOrdinal+1];for(var edgeIndex=beginEdgeIndex;edgeIndex<endEdgeIndex;edgeIndex+=edgeFieldsCount){var childNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];var childNodeOrdinal=childNodeIndex/nodeFieldCount;if(flags[childNodeOrdinal]&markerAndFlag)
continue;var type=containmentEdges[edgeIndex+edgeTypeOffset];if(type===edgeWeakType)
continue;nodesToVisit[nodesToVisitLength++]=childNodeOrdinal;flags[childNodeOrdinal]|=visitedMarker;}}},_calculateStatistics:function()
{var nodeFieldCount=this._nodeFieldCount;var nodes=this.nodes;var nodesLength=nodes.length;var nodeTypeOffset=this._nodeTypeOffset;var nodeSizeOffset=this._nodeSelfSizeOffset;;var nodeNativeType=this._nodeNativeType;var nodeCodeType=this._nodeCodeType;var nodeConsStringType=this._nodeConsStringType;var nodeSlicedStringType=this._nodeSlicedStringType;var distances=this._nodeDistances;var sizeNative=0;var sizeCode=0;var sizeStrings=0;var sizeJSArrays=0;var sizeSystem=0;var node=this.rootNode();for(var nodeIndex=0;nodeIndex<nodesLength;nodeIndex+=nodeFieldCount){var nodeSize=nodes[nodeIndex+nodeSizeOffset];var ordinal=nodeIndex/nodeFieldCount;if(distances[ordinal]>=WebInspector.HeapSnapshotCommon.baseSystemDistance){sizeSystem+=nodeSize;continue;}
var nodeType=nodes[nodeIndex+nodeTypeOffset];node.nodeIndex=nodeIndex;if(nodeType===nodeNativeType)
sizeNative+=nodeSize;else if(nodeType===nodeCodeType)
sizeCode+=nodeSize;else if(nodeType===nodeConsStringType||nodeType===nodeSlicedStringType||node.type()==="string")
sizeStrings+=nodeSize;else if(node.name()==="Array")
sizeJSArrays+=this._calculateArraySize(node);}
this._statistics=new WebInspector.HeapSnapshotCommon.Statistics();this._statistics.total=this.totalSize;this._statistics.v8heap=this.totalSize-sizeNative;this._statistics.native=sizeNative;this._statistics.code=sizeCode;this._statistics.jsArrays=sizeJSArrays;this._statistics.strings=sizeStrings;this._statistics.system=sizeSystem;},_calculateArraySize:function(node)
{var size=node.selfSize();var beginEdgeIndex=node.edgeIndexesStart();var endEdgeIndex=node.edgeIndexesEnd();var containmentEdges=this.containmentEdges;var strings=this.strings;var edgeToNodeOffset=this._edgeToNodeOffset;var edgeTypeOffset=this._edgeTypeOffset;var edgeNameOffset=this._edgeNameOffset;var edgeFieldsCount=this._edgeFieldsCount;var edgeInternalType=this._edgeInternalType;for(var edgeIndex=beginEdgeIndex;edgeIndex<endEdgeIndex;edgeIndex+=edgeFieldsCount){var edgeType=containmentEdges[edgeIndex+edgeTypeOffset];if(edgeType!==edgeInternalType)
continue;var edgeName=strings[containmentEdges[edgeIndex+edgeNameOffset]];if(edgeName!=="elements")
continue;var elementsNodeIndex=containmentEdges[edgeIndex+edgeToNodeOffset];node.nodeIndex=elementsNodeIndex;if(node.retainersCount()===1)
size+=node.selfSize();break;}
return size;},getStatistics:function()
{return this._statistics;},__proto__:WebInspector.HeapSnapshot.prototype};WebInspector.JSHeapSnapshotNode=function(snapshot,nodeIndex)
{WebInspector.HeapSnapshotNode.call(this,snapshot,nodeIndex);}
WebInspector.JSHeapSnapshotNode.prototype={canBeQueried:function()
{var flags=this._snapshot._flagsOfNode(this);return!!(flags&this._snapshot._nodeFlags.canBeQueried);},rawName:WebInspector.HeapSnapshotNode.prototype.name,name:function()
{var snapshot=this._snapshot;if(this._type()===snapshot._nodeConsStringType){var string=snapshot._lazyStringCache[this.nodeIndex];if(typeof string==="undefined"){string=this._consStringName();snapshot._lazyStringCache[this.nodeIndex]=string;}
return string;}
return this.rawName();},_consStringName:function()
{var snapshot=this._snapshot;var consStringType=snapshot._nodeConsStringType;var edgeInternalType=snapshot._edgeInternalType;var edgeFieldsCount=snapshot._edgeFieldsCount;var edgeToNodeOffset=snapshot._edgeToNodeOffset;var edgeTypeOffset=snapshot._edgeTypeOffset;var edgeNameOffset=snapshot._edgeNameOffset;var strings=snapshot.strings;var edges=snapshot.containmentEdges;var firstEdgeIndexes=snapshot._firstEdgeIndexes;var nodeFieldCount=snapshot._nodeFieldCount;var nodeTypeOffset=snapshot._nodeTypeOffset;var nodeNameOffset=snapshot._nodeNameOffset;var nodes=snapshot.nodes;var nodesStack=[];nodesStack.push(this.nodeIndex);var name="";while(nodesStack.length&&name.length<1024){var nodeIndex=nodesStack.pop();if(nodes[nodeIndex+nodeTypeOffset]!==consStringType){name+=strings[nodes[nodeIndex+nodeNameOffset]];continue;}
var nodeOrdinal=nodeIndex/nodeFieldCount;var beginEdgeIndex=firstEdgeIndexes[nodeOrdinal];var endEdgeIndex=firstEdgeIndexes[nodeOrdinal+1];var firstNodeIndex=0;var secondNodeIndex=0;for(var edgeIndex=beginEdgeIndex;edgeIndex<endEdgeIndex&&(!firstNodeIndex||!secondNodeIndex);edgeIndex+=edgeFieldsCount){var edgeType=edges[edgeIndex+edgeTypeOffset];if(edgeType===edgeInternalType){var edgeName=strings[edges[edgeIndex+edgeNameOffset]];if(edgeName==="first")
firstNodeIndex=edges[edgeIndex+edgeToNodeOffset];else if(edgeName==="second")
secondNodeIndex=edges[edgeIndex+edgeToNodeOffset];}}
nodesStack.push(secondNodeIndex);nodesStack.push(firstNodeIndex);}
return name;},className:function()
{var type=this.type();switch(type){case"hidden":return"(system)";case"object":case"native":return this.name();case"code":return"(compiled code)";default:return"("+type+")";}},classIndex:function()
{var snapshot=this._snapshot;var nodes=snapshot.nodes;var type=nodes[this.nodeIndex+snapshot._nodeTypeOffset];;if(type===snapshot._nodeObjectType||type===snapshot._nodeNativeType)
return nodes[this.nodeIndex+snapshot._nodeNameOffset];return-1-type;},id:function()
{var snapshot=this._snapshot;return snapshot.nodes[this.nodeIndex+snapshot._nodeIdOffset];},isHidden:function()
{return this._type()===this._snapshot._nodeHiddenType;},isArray:function()
{return this._type()===this._snapshot._nodeArrayType;},isSynthetic:function()
{return this._type()===this._snapshot._nodeSyntheticType;},isUserRoot:function()
{return!this.isSynthetic();},isDocumentDOMTreesRoot:function()
{return this.isSynthetic()&&this.name()==="(Document DOM trees)";},serialize:function()
{var result=WebInspector.HeapSnapshotNode.prototype.serialize.call(this);var flags=this._snapshot._flagsOfNode(this);if(flags&this._snapshot._nodeFlags.canBeQueried)
result.canBeQueried=true;if(flags&this._snapshot._nodeFlags.detachedDOMTreeNode)
result.detachedDOMTreeNode=true;return result;},__proto__:WebInspector.HeapSnapshotNode.prototype};WebInspector.JSHeapSnapshotEdge=function(snapshot,edgeIndex)
{WebInspector.HeapSnapshotEdge.call(this,snapshot,edgeIndex);}
WebInspector.JSHeapSnapshotEdge.prototype={clone:function()
{var snapshot=(this._snapshot);return new WebInspector.JSHeapSnapshotEdge(snapshot,this.edgeIndex);},hasStringName:function()
{if(!this.isShortcut())
return this._hasStringName();return isNaN(parseInt(this._name(),10));},isElement:function()
{return this._type()===this._snapshot._edgeElementType;},isHidden:function()
{return this._type()===this._snapshot._edgeHiddenType;},isWeak:function()
{return this._type()===this._snapshot._edgeWeakType;},isInternal:function()
{return this._type()===this._snapshot._edgeInternalType;},isInvisible:function()
{return this._type()===this._snapshot._edgeInvisibleType;},isShortcut:function()
{return this._type()===this._snapshot._edgeShortcutType;},name:function()
{var name=this._name();if(!this.isShortcut())
return String(name);var numName=parseInt(name,10);return String(isNaN(numName)?name:numName);},toString:function()
{var name=this.name();switch(this.type()){case"context":return"->"+name;case"element":return"["+name+"]";case"weak":return"[["+name+"]]";case"property":return name.indexOf(" ")===-1?"."+name:"[\""+name+"\"]";case"shortcut":if(typeof name==="string")
return name.indexOf(" ")===-1?"."+name:"[\""+name+"\"]";else
return"["+name+"]";case"internal":case"hidden":case"invisible":return"{"+name+"}";};return"?"+name+"?";},_hasStringName:function()
{var type=this._type();var snapshot=this._snapshot;return type!==snapshot._edgeElementType&&type!==snapshot._edgeHiddenType;},_name:function()
{return this._hasStringName()?this._snapshot.strings[this._nameOrIndex()]:this._nameOrIndex();},_nameOrIndex:function()
{return this._edges[this.edgeIndex+this._snapshot._edgeNameOffset];},_type:function()
{return this._edges[this.edgeIndex+this._snapshot._edgeTypeOffset];},__proto__:WebInspector.HeapSnapshotEdge.prototype};WebInspector.JSHeapSnapshotRetainerEdge=function(snapshot,retainerIndex)
{WebInspector.HeapSnapshotRetainerEdge.call(this,snapshot,retainerIndex);}
WebInspector.JSHeapSnapshotRetainerEdge.prototype={clone:function()
{var snapshot=(this._snapshot);return new WebInspector.JSHeapSnapshotRetainerEdge(snapshot,this.retainerIndex());},isHidden:function()
{return this._edge().isHidden();},isInternal:function()
{return this._edge().isInternal();},isInvisible:function()
{return this._edge().isInvisible();},isShortcut:function()
{return this._edge().isShortcut();},isWeak:function()
{return this._edge().isWeak();},__proto__:WebInspector.HeapSnapshotRetainerEdge.prototype};function postMessageWrapper(message)
{postMessage(message);}
var dispatcher=new WebInspector.HeapSnapshotWorkerDispatcher(this,postMessageWrapper);function installMessageEventListener(listener)
{self.addEventListener("message",listener,false);}
installMessageEventListener(dispatcher.dispatchMessage.bind(dispatcher));;applicationDescriptor={"has_html":false,"modules":[{"type":"autostart","name":"heap_snapshot_worker"}]};if(!self.Runtime)
self.importScripts('Runtime.js');Runtime.startWorker("heap_snapshot_worker");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 11043 11044 11045 11046 11047 | 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var allDescriptors=[{"dependencies":["platform","common","host","ui","diff"],"extensions":[{"className":"WebInspector.CommandMenu.ShowActionDelegate","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Shift+P"},{"platform":"mac","shortcut":"Meta+Shift+P"}],"type":"@WebInspector.ActionDelegate","actionId":"commandMenu.show"}],"name":"ui_lazy","scripts":[]},{"experiment":"accessibilityInspection","extensions":[{"className":"WebInspector.AccessibilitySidebarView","type":"@WebInspector.Widget","location":"elements-panel","title":"Accessibility"}],"name":"accessibility","dependencies":["elements"],"scripts":[],"condition":"!v8only"},{"dependencies":["components","source_frame","snippets","ui_lazy","extensions"],"extensions":[{"className":"WebInspector.SourcesPanelFactory","order":30,"type":"@WebInspector.PanelFactory","name":"sources","title":"Sources"},{"className":"WebInspector.SourcesPanel.ContextMenuProvider","contextTypes":["WebInspector.UISourceCode","WebInspector.UILocation","WebInspector.RemoteObject","WebInspector.NetworkRequest"],"type":"@WebInspector.ContextMenu.Provider"},{"category":"Debugger","iconClass":"pause-toolbar-item","className":"WebInspector.SourcesPanel.RevealingActionDelegate","contextTypes":["WebInspector.SourcesPanel","WebInspector.ShortcutRegistry.ForwardedShortcut"],"actionId":"debugger.toggle-pause","bindings":[{"platform":"windows,linux","shortcut":"F8 Ctrl+\\"},{"platform":"mac","shortcut":"F8 Meta+\\"}],"type":"@WebInspector.ActionDelegate","options":[{"value":true,"title":"Pause script execution"},{"value":false,"title":"Resume script execution"}]},{"iconClass":"step-over-toolbar-item","title":"Step over next function call","className":"WebInspector.SourcesPanel.DebuggingActionDelegate","contextTypes":["WebInspector.SourcesPanel"],"actionId":"debugger.step-over","bindings":[{"platform":"windows,linux","shortcut":"F10 Ctrl+'"},{"platform":"mac","shortcut":"F10 Meta+'"}],"type":"@WebInspector.ActionDelegate"},{"iconClass":"step-in-toolbar-item","title":"Step into next function call","className":"WebInspector.SourcesPanel.DebuggingActionDelegate","contextTypes":["WebInspector.SourcesPanel"],"actionId":"debugger.step-into","bindings":[{"platform":"windows,linux","shortcut":"F11 Ctrl+;"},{"platform":"mac","shortcut":"F11 Meta+;"}],"type":"@WebInspector.ActionDelegate"},{"iconClass":"step-out-toolbar-item","title":"Step out of current function","className":"WebInspector.SourcesPanel.DebuggingActionDelegate","contextTypes":["WebInspector.SourcesPanel"],"actionId":"debugger.step-out","bindings":[{"platform":"windows,linux","shortcut":"Shift+F11 Shift+Ctrl+;"},{"platform":"mac","shortcut":"Shift+F11 Shift+Meta+;"}],"type":"@WebInspector.ActionDelegate"},{"iconClass":"play-toolbar-item","title":"Run snippet","className":"WebInspector.SourcesPanel.DebuggingActionDelegate","contextTypes":["WebInspector.SourcesPanel"],"actionId":"debugger.run-snippet","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Enter"},{"platform":"mac","shortcut":"Meta+Enter"}],"type":"@WebInspector.ActionDelegate"},{"category":"DevTools","title":"Search all files","className":"WebInspector.AdvancedSearchView.ActionDelegate","actionId":"sources.search.toggle","bindings":[{"platform":"mac","shortcut":"Meta+Alt+F"},{"platform":"windows,linux","shortcut":"Ctrl+Shift+F"}],"type":"@WebInspector.ActionDelegate"},{"category":"Debugger","iconClass":"breakpoint-toolbar-item","className":"WebInspector.SourcesPanel.DebuggingActionDelegate","contextTypes":["WebInspector.SourcesPanel"],"actionId":"debugger.toggle-breakpoints-active","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+F8"},{"platform":"mac","shortcut":"Meta+F8"}],"type":"@WebInspector.ActionDelegate","options":[{"value":true,"title":"Deactivate breakpoints"},{"value":false,"title":"Activate breakpoints"}]},{"type":"context-menu-item","location":"mainMenu/navigate","actionId":"sources.search.toggle"},{"type":"context-menu-item","location":"navigatorMenu/navigate","actionId":"sources.go-to-source"},{"className":"WebInspector.SourcesPanel.UILocationRevealer","contextTypes":["WebInspector.UILocation"],"type":"@WebInspector.Revealer"},{"className":"WebInspector.SourcesPanel.DebuggerLocationRevealer","contextTypes":["WebInspector.DebuggerModel.Location"],"type":"@WebInspector.Revealer"},{"className":"WebInspector.SourcesPanel.UISourceCodeRevealer","contextTypes":["WebInspector.UISourceCode"],"type":"@WebInspector.Revealer"},{"className":"WebInspector.SourcesPanel.DebuggerPausedDetailsRevealer","contextTypes":["WebInspector.DebuggerPausedDetails"],"type":"@WebInspector.Revealer"},{"className":"WebInspector.InplaceFormatterEditorAction","type":"@WebInspector.SourcesView.EditorAction"},{"className":"WebInspector.ScriptFormatterEditorAction","type":"@WebInspector.SourcesView.EditorAction"},{"name":"sources","title":"Sources","className":"WebInspector.SourcesNavigatorView","type":"navigator-view","order":1,"persistence":"permanent"},{"name":"contentScripts","title":"Content scripts","className":"WebInspector.ContentScriptsNavigatorView","type":"navigator-view","order":2,"persistence":"permanent"},{"name":"snippets","title":"Snippets","className":"WebInspector.SnippetsNavigatorView","type":"navigator-view","order":3,"persistence":"permanent"},{"title":"Go to file...","className":"WebInspector.SourcesPanel.RevealingActionDelegate","actionId":"sources.go-to-source","bindings":[{"platform":"mac","shortcut":"Meta+P Meta+O"},{"platform":"windows,linux","shortcut":"Ctrl+P Ctrl+O"}],"type":"@WebInspector.ActionDelegate","order":100},{"className":"WebInspector.SourcesView.SwitchFileActionDelegate","contextTypes":["WebInspector.SourcesView"],"bindings":[{"shortcut":"Alt+O"}],"type":"@WebInspector.ActionDelegate","actionId":"sources.switch-file"},{"defaultValue":"true","type":"setting","settingName":"navigatorGroupByFolder","settingType":"boolean"},{"category":"Sources","title":"Search in content scripts","defaultValue":false,"settingName":"searchInContentScripts","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Enable JavaScript source maps","defaultValue":true,"settingName":"jsSourceMapsEnabled","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Detect indentation","defaultValue":true,"settingName":"textEditorAutoDetectIndent","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Autocompletion","defaultValue":true,"settingName":"textEditorAutocompletion","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Bracket matching","defaultValue":true,"settingName":"textEditorBracketMatching","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Show whitespace characters:","defaultValue":"original","settingName":"showWhitespacesInEditor","settingType":"enum","type":"setting","options":[{"text":"None","value":"none","title":"Do not show whitespace characters"},{"text":"All","value":"all","title":"Show all whitespace characters"},{"text":"Trailing","value":"trailing","title":"Show trailing whitespace characters"}]},{"category":"Sources","title":"Display variable values inline while debugging","defaultValue":true,"settingName":"inlineVariableValues","settingType":"boolean","type":"setting"},{"category":"Sources","title":"Enable CSS source maps","defaultValue":true,"settingName":"cssSourceMapsEnabled","settingType":"boolean","type":"setting"},{"name":"sources.search","title":"Search","className":"WebInspector.AdvancedSearchView","type":"drawer-view","order":100,"persistence":"closeable"},{"className":"WebInspector.RevisionHistoryView","type":"drawer-view","name":"sources.history","persistence":"temporary","title":"History"},{"name":"sources.quick","title":"Quick source","className":"WebInspector.SourcesPanel.WrapperView","type":"drawer-view","order":1000,"persistence":"closeable"}],"name":"sources","scripts":[]},{"dependencies":["platform","ui","host","components"],"extensions":[{"category":"Mobile","className":"WebInspector.DevicesDialog.ActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"devices.dialog.show","title":"Inspect devices\u2026"},{"actionId":"devices.dialog.show","type":"context-menu-item","location":"mainMenu/tools/open","order":50}],"name":"devices","condition":"!v8only","scripts":[]},{"skip_compilation":["diff_match_patch.js"],"dependencies":["common"],"name":"diff","scripts":[]},{"dependencies":["components","extensions"],"extensions":[{"className":"WebInspector.AuditsPanelFactory","order":90,"type":"@WebInspector.PanelFactory","name":"audits","title":"Audits"}],"name":"audits","condition":"!v8only","scripts":[]},{"dependencies":["sdk","platform","workspace"],"name":"bindings","scripts":[]},{"dependencies":["bindings"],"name":"snippets","scripts":[]},{"experiment":"layersPanel","dependencies":["timeline"],"extensions":[{"className":"WebInspector.LayersPanelFactory","order":100,"type":"@WebInspector.PanelFactory","name":"layers","title":"Layers"},{"className":"WebInspector.LayersPanel.LayerTreeRevealer","contextTypes":["WebInspector.DeferredLayerTree"],"type":"@WebInspector.Revealer"}],"scripts":[],"condition":"!v8only","name":"layers"},{"dependencies":["components","ui_lazy"],"extensions":[{"className":"WebInspector.ConsolePanelFactory","order":20,"type":"@WebInspector.PanelFactory","name":"console","title":"Console"},{"name":"console","title":"Console","className":"WebInspector.ConsolePanel.WrapperView","type":"drawer-view","order":0,"persistence":"permanent"},{"className":"WebInspector.ConsolePanel.ConsoleRevealer","contextTypes":["WebInspector.Console"],"type":"@WebInspector.Revealer"},{"className":"WebInspector.ConsoleView.ActionDelegate","bindings":[{"shortcut":"Ctrl+`"}],"type":"@WebInspector.ActionDelegate","actionId":"console.show"},{"category":"Console","iconClass":"clear-toolbar-item","title":"Clear console","className":"WebInspector.ConsoleView.ActionDelegate","actionId":"console.clear","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+L"},{"platform":"mac","shortcut":"Ctrl+L Meta+K"}],"type":"@WebInspector.ActionDelegate"},{"category":"Console","className":"WebInspector.ConsoleView.ActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"console.clear.history","title":"Clear console history"},{"category":"Console","title":"Hide network messages","defaultValue":false,"settingName":"hideNetworkMessages","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Hide network messages"},{"value":false,"title":"Show network messages"}]},{"category":"Console","title":"Log XMLHttpRequests","defaultValue":false,"settingName":"monitoringXHREnabled","settingType":"boolean","type":"setting"},{"category":"Console","title":"Preserve log upon navigation","defaultValue":false,"settingName":"preserveConsoleLog","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Preserve log upon navigation"},{"value":false,"title":"Do not preserve log upon navigation"}]},{"category":"Console","title":"Show timestamps","defaultValue":false,"settingName":"consoleTimestampsEnabled","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show timestamps"},{"value":false,"title":"Hide timestamps"}]},{"category":"Console","title":"Autocomplete from history","defaultValue":true,"settingName":"consoleHistoryAutocomplete","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Autocomplete from history"},{"value":false,"title":"Do not autocomplete from history"}]}],"name":"console","scripts":[]},{"dependencies":["source_frame","components","components_lazy","ui_lazy"],"extensions":[{"className":"WebInspector.NetworkPanelFactory","order":40,"type":"@WebInspector.PanelFactory","name":"network","title":"Network"},{"className":"WebInspector.NetworkPanel.ContextMenuProvider","contextTypes":["WebInspector.NetworkRequest","WebInspector.Resource","WebInspector.UISourceCode"],"type":"@WebInspector.ContextMenu.Provider"},{"className":"WebInspector.NetworkPanel.RequestRevealer","contextTypes":["WebInspector.NetworkRequest"],"type":"@WebInspector.Revealer"},{"category":"Network","title":"Color-code resource types","defaultValue":false,"tags":"color code, resource type","settingName":"networkColorCodeResourceTypes","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Color code by resource type"},{"value":false,"title":"Use default colors"}]},{"className":"WebInspector.BlockedURLsPane.ActionDelegate","iconClass":"block-toolbar-item","type":"@WebInspector.ActionDelegate","actionId":"network.blocked-urls.show","title":"Block network requests"},{"iconClass":"record-toolbar-item","className":"WebInspector.NetworkPanel.RecordActionDelegate","contextTypes":["WebInspector.NetworkPanel"],"actionId":"network.toggle-recording","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"type":"@WebInspector.ActionDelegate","options":[{"value":true,"title":"Record network log"},{"value":false,"title":"Stop recording network log"}]},{"name":"network.blocked-urls","title":"Request blocking","className":"WebInspector.BlockedURLsPane","experiment":"requestBlocking","type":"drawer-view","order":60,"persistence":"closeable"},{"className":"WebInspector.NetworkConfigView.ShowActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"network.show-config","title":"Network conditions"},{"actionId":"network.show-config","type":"context-menu-item","location":"mainMenu/tools/open","order":60},{"name":"network.config","title":"Network conditions","tags":"disk cache, network throttling, useragent, user agent","className":"WebInspector.NetworkConfigView","type":"drawer-view","order":40,"persistence":"closeable"}],"name":"network","condition":"!v8only","scripts":[]},{"remote":true,"name":"cm_modes","dependencies":["source_frame"],"extensions":[{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-csrc","text/x-c","text/x-chdr","text/x-c++src","text/x-c++hdr","text/x-java","text/x-csharp","text/x-scala","x-shader/x-vertex","x-shader/x-fragment"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"clike.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-coffeescript"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"coffeescript.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["application/x-httpd-php","application/x-httpd-php-open","text/x-php"],"dependencies":["clike.js"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"php.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-python","text/x-cython"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"python.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-sh"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"shell.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-livescript"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"livescript.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-clojure"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"clojure.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/jsx"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"jsx.js"},{"className":"WebInspector.DefaultCodeMirrorMimeMode","mimeTypes":["text/x-styl"],"type":"@WebInspector.CodeMirrorMimeMode","fileName":"stylus.js"}],"scripts":[]},{"dependencies":[],"name":"platform","scripts":[]},{"dependencies":["elements"],"extensions":[{"className":"WebInspector.AnimationTimeline.ButtonProvider","type":"@WebInspector.ToolbarItem.Provider","order":2,"location":"styles-sidebarpane-toolbar"},{"name":"animations","title":"Animations","className":"WebInspector.AnimationTimeline","type":"drawer-view","order":0,"persistence":"closeable"}],"name":"animation","condition":"!v8only","scripts":[]},{"dependencies":["components"],"extensions":[{"className":"WebInspector.CodeMirrorUtils","type":"@WebInspector.InplaceEditor"},{"className":"WebInspector.CodeMirrorUtils.TokenizerFactory","type":"@WebInspector.TokenizerFactory"},{"category":"Sources","title":"Default indentation:","defaultValue":" ","settingName":"textEditorIndent","settingType":"enum","type":"setting","options":[{"text":"2 spaces","value":" ","title":"Set indentation to 2 spaces"},{"text":"4 spaces","value":" ","title":"Set indentation to 4 spaces"},{"text":"8 spaces","value":" ","title":"Set indentation to 8 spaces"},{"text":"Tab character","value":"\t","title":"Set indentation to tab character"}]}],"name":"source_frame","scripts":[],"skip_compilation":["../cm/codemirror.js","../cm/css.js","../cm/javascript.js","../cm/simple.js","../cm/xml.js","../cm/htmlmixed.js","../cm/htmlembedded.js","../cm/matchbrackets.js","../cm/closebrackets.js","../cm/markselection.js","../cm/comment.js","../cm/overlay.js","../cm/activeline.js"]},{"dependencies":["extensions","host","platform","sdk"],"extensions":[{"className":"WebInspector.SimpleAppProvider","type":"@WebInspector.AppProvider","order":10},{"className":"WebInspector.HandlerRegistry.ContextMenuProvider","contextTypes":["WebInspector.UISourceCode","WebInspector.Resource","WebInspector.NetworkRequest","Node"],"type":"@WebInspector.ContextMenu.Provider"},{"category":"Navigation","title":"Reload page","className":"WebInspector.Main.ReloadActionDelegate","actionId":"main.reload","bindings":[{"platform":"windows,linux","shortcut":"F5 Ctrl+R"},{"platform":"mac","shortcut":"Meta+R"}],"type":"@WebInspector.ActionDelegate"},{"category":"Navigation","title":"Hard reload page","className":"WebInspector.Main.ReloadActionDelegate","actionId":"main.hard-reload","bindings":[{"platform":"windows,linux","shortcut":"Shift+F5 Ctrl+F5 Ctrl+Shift+F5 Shift+Ctrl+R"},{"platform":"mac","shortcut":"Shift+Meta+R"}],"type":"@WebInspector.ActionDelegate"},{"category":"Drawer","title":"Toggle drawer","className":"WebInspector.InspectorView.DrawerToggleActionDelegate","actionId":"main.toggle-drawer","bindings":[{"shortcut":"Esc"}],"type":"@WebInspector.ActionDelegate","order":100},{"className":"WebInspector.Main.ReloadActionDelegate","bindings":[{"shortcut":"Alt+R"}],"type":"@WebInspector.ActionDelegate","actionId":"main.debug-reload"},{"category":"DevTools","title":"Restore last dock position","className":"WebInspector.DockController.ToggleDockActionDelegate","actionId":"main.toggle-dock","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Shift+D"},{"platform":"mac","shortcut":"Meta+Shift+D"}],"type":"@WebInspector.ActionDelegate"},{"className":"WebInspector.Main.ZoomActionDelegate","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Plus Ctrl+Shift+Plus Ctrl+NumpadPlus Ctrl+Shift+NumpadPlus"},{"platform":"mac","shortcut":"Meta+Plus Meta+Shift+Plus Meta+NumpadPlus Meta+Shift+NumpadPlus"}],"type":"@WebInspector.ActionDelegate","actionId":"main.zoom-in"},{"className":"WebInspector.Main.ZoomActionDelegate","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Minus Ctrl+Shift+Minus Ctrl+NumpadMinus Ctrl+Shift+NumpadMinus"},{"platform":"mac","shortcut":"Meta+Minus Meta+Shift+Minus Meta+NumpadMinus Meta+Shift+NumpadMinus"}],"type":"@WebInspector.ActionDelegate","actionId":"main.zoom-out"},{"className":"WebInspector.Main.ZoomActionDelegate","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+0 Ctrl+Numpad0"},{"platform":"mac","shortcut":"Meta+0 Meta+Numpad0"}],"type":"@WebInspector.ActionDelegate","actionId":"main.zoom-reset"},{"className":"WebInspector.Main.SearchActionDelegate","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+F"},{"platform":"mac","shortcut":"Meta+F F3"}],"type":"@WebInspector.ActionDelegate","actionId":"main.search-in-panel.find"},{"className":"WebInspector.Main.SearchActionDelegate","bindings":[{"shortcut":"Esc"}],"type":"@WebInspector.ActionDelegate","actionId":"main.search-in-panel.cancel","order":10},{"className":"WebInspector.Main.SearchActionDelegate","bindings":[{"platform":"mac","shortcut":"Meta+G"}],"type":"@WebInspector.ActionDelegate","actionId":"main.search-in-panel.find-next"},{"className":"WebInspector.Main.SearchActionDelegate","bindings":[{"platform":"mac","shortcut":"Meta+Shift+G"}],"type":"@WebInspector.ActionDelegate","actionId":"main.search-in-panel.find-previous"},{"className":"WebInspector.RenderingOptionsView.ShowActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"main.show-rendering-options","title":"Rendering settings"},{"separator":true,"type":"@WebInspector.ToolbarItem.Provider","location":"main-toolbar-left","order":100},{"className":"WebInspector.Main.WarningErrorCounter","type":"@WebInspector.ToolbarItem.Provider","order":1,"location":"main-toolbar-right"},{"separator":true,"type":"@WebInspector.ToolbarItem.Provider","order":98,"location":"main-toolbar-right"},{"className":"WebInspector.Main.MainMenuItem","type":"@WebInspector.ToolbarItem.Provider","order":99,"location":"main-toolbar-right"},{"className":"WebInspector.DockController.CloseButtonProvider","type":"@WebInspector.ToolbarItem.Provider","order":100,"location":"main-toolbar-right"},{"category":"Network","title":"Disable cache (while DevTools is open)","defaultValue":false,"options":[{"value":true,"title":"Disable cache (while DevTools is open)"},{"value":false,"title":"Enable cache"}],"settingName":"cacheDisabled","settingType":"boolean","type":"setting","order":0},{"category":"","title":"Disable JavaScript","defaultValue":false,"settingName":"javaScriptDisabled","settingType":"boolean","type":"setting","order":1},{"category":"DevTools","title":"Auto-open DevTools for popups","defaultValue":false,"options":[{"value":true,"title":"Auto-open DevTools for popups"},{"value":false,"title":"Do not auto-open DevTools for popups"}],"settingName":"autoAttachToCreatedPages","settingType":"boolean","type":"setting","order":2},{"category":"Appearance","title":"Theme:","defaultValue":"default","settingName":"uiTheme","settingType":"enum","type":"setting","options":[{"text":"Default","value":"default","title":"Switch to default theme"},{"text":"Dark","value":"dark","title":"Switch to dark theme"}]},{"category":"Appearance","title":"Panel layout:","defaultValue":"auto","settingName":"sidebarPosition","settingType":"enum","type":"setting","options":[{"text":"horizontal","value":"bottom","title":"Use horizontal panel layout"},{"text":"vertical","value":"right","title":"Use vertical panel layout"},{"text":"auto","value":"auto","title":"Use automatic panel layout"}]},{"category":"Appearance","title-mac":"Enable Cmd + 1-9 shortcut to switch panels","title":"Enable Ctrl + 1-9 shortcut to switch panels","defaultValue":false,"settingName":"shortcutPanelSwitch","settingType":"boolean","type":"setting"},{"category":"Appearance","title":"Don't show Chrome Data Saver warning","defaultValue":false,"settingName":"disableDataSaverInfobar","settingType":"boolean","type":"setting"},{"category":"Appearance","title":"Disable paused state overlay","defaultValue":false,"settingName":"disablePausedStateOverlay","settingType":"boolean","type":"setting"},{"category":"Console","title":"Report input events blocked for too long","defaultValue":true,"settingName":"blockedEventsWarningEnabled","settingType":"boolean","type":"setting"},{"category":"Extensions","className":"WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI","type":"@WebInspector.SettingUI"},{"category":"Elements","className":"WebInspector.ShowMetricsRulersSettingUI","type":"@WebInspector.SettingUI","order":3},{"subMenuId":"mainMenu/tools","order":80,"type":"context-menu-item","location":"mainMenu/navigate","title":"More tools"},{"actionId":"main.show-rendering-options","type":"context-menu-item","location":"mainMenu/tools/open","order":80},{"name":"rendering","title":"Rendering","className":"WebInspector.RenderingOptionsView","type":"drawer-view","order":50,"persistence":"closeable"},{"category":"DevTools","defaultValue":"right","settingName":"currentDockState","settingType":"enum","type":"setting","options":[{"value":"right","title":"Dock to right"},{"value":"bottom","title":"Dock to bottom"},{"value":"undocked","title":"Undock into separate window"}]}],"name":"main","scripts":[]},{"dependencies":["source_frame","ui_lazy","components_lazy"],"extensions":[{"className":"WebInspector.ResourcesPanelFactory","order":70,"type":"@WebInspector.PanelFactory","name":"resources","title":"Application"},{"className":"WebInspector.ResourcesPanel.ResourceRevealer","contextTypes":["WebInspector.Resource"],"type":"@WebInspector.Revealer"}],"name":"resources","condition":"!v8only","scripts":[]},{"dependencies":["components","extensions"],"extensions":[{"className":"WebInspector.ElementsPanelFactory","order":10,"type":"@WebInspector.PanelFactory","name":"elements","title":"Elements"},{"className":"WebInspector.ElementsPanel.ContextMenuProvider","contextTypes":["WebInspector.RemoteObject","WebInspector.DOMNode","WebInspector.DeferredDOMNode"],"type":"@WebInspector.ContextMenu.Provider"},{"className":"WebInspector.ElementsTreeOutline.Renderer","contextTypes":["WebInspector.DOMNode","WebInspector.RemoteObject"],"type":"@WebInspector.Renderer"},{"className":"WebInspector.ElementsPanel.DOMNodeRevealer","contextTypes":["WebInspector.DOMNode","WebInspector.DeferredDOMNode","WebInspector.RemoteObject"],"type":"@WebInspector.Revealer"},{"category":"Elements","title":"Color format:","defaultValue":"original","options":[{"text":"As authored","value":"original","title":"Set color format as authored"},{"raw":true,"text":"HEX: #dac0de","value":"hex","title":"Set color format to HEX"},{"raw":true,"text":"RGB: rgb(128, 255, 255)","value":"rgb","title":"Set color format to RGB"},{"raw":true,"text":"HSL: hsl(300, 80%, 90%)","value":"hsl","title":"Set color format to HSL"}],"settingName":"colorFormat","settingType":"enum","type":"setting","order":0},{"category":"Elements","title":"Show user agent shadow DOM","defaultValue":false,"settingName":"showUAShadowDOM","settingType":"boolean","type":"setting","order":1},{"category":"Elements","title":"Word wrap","defaultValue":true,"options":[{"value":true,"title":"Enable DOM word wrap"},{"value":false,"title":"Disable DOM word wrap"}],"settingName":"domWordWrap","settingType":"boolean","type":"setting","order":2},{"category":"Elements","title":"Reveal DOM node on hover.","defaultValue":true,"settingName":"highlightNodeOnHoverInOverlay","settingType":"boolean","type":"setting","order":4},{"className":"WebInspector.ElementStatePaneWidget.ButtonProvider","type":"@WebInspector.ToolbarItem.Provider","order":1,"location":"styles-sidebarpane-toolbar"},{"className":"WebInspector.ClassesPaneWidget.ButtonProvider","type":"@WebInspector.ToolbarItem.Provider","order":2,"location":"styles-sidebarpane-toolbar"},{"className":"WebInspector.ElementsActionDelegate","contextTypes":["WebInspector.ElementsPanel"],"bindings":[{"shortcut":"H"}],"type":"@WebInspector.ActionDelegate","actionId":"elements.hide-element"},{"className":"WebInspector.ElementsActionDelegate","contextTypes":["WebInspector.ElementsPanel"],"bindings":[{"shortcut":"F2"}],"type":"@WebInspector.ActionDelegate","actionId":"elements.edit-as-html"},{"className":"WebInspector.ElementsPanel.PseudoStateMarkerDecorator","marker":"pseudo-state-marker","type":"@WebInspector.DOMPresentationUtils.MarkerDecorator"},{"className":"WebInspector.DOMPresentationUtils.GenericDecorator","marker":"hidden-marker","type":"@WebInspector.DOMPresentationUtils.MarkerDecorator","color":"#555","title":"Element is hidden"},{"iconClass":"node-search-toolbar-item","title":"Select an element in the page to inspect it","className":"WebInspector.InspectElementModeController.ToggleSearchActionDelegate","actionId":"elements.toggle-element-search","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Shift+C"},{"platform":"mac","shortcut":"Meta+Shift+C"}],"type":"@WebInspector.ActionDelegate"},{"order":0,"type":"@WebInspector.ToolbarItem.Provider","actionId":"elements.toggle-element-search","location":"main-toolbar-left"},{"className":"WebInspector.InspectElementModeController.LayoutEditorButtonProvider","experiment":"layoutEditor","type":"@WebInspector.ToolbarItem.Provider","order":4,"location":"styles-sidebarpane-toolbar"}],"name":"elements","condition":"!v8only","scripts":[]},{"dependencies":["common","host","platform"],"name":"workspace","scripts":[]},{"dependencies":["components","components_lazy","ui_lazy"],"extensions":[{"className":"WebInspector.TimelinePanelFactory","order":50,"type":"@WebInspector.PanelFactory","name":"timeline","title":"Timeline"},{"category":"Profiler","title":"Hide chrome frame in Layers view","defaultValue":false,"settingName":"frameViewerHideChromeWindow","settingType":"boolean","type":"setting"},{"className":"WebInspector.LoadTimelineHandler","type":"@WebInspector.QueryParamHandler","name":"loadTimelineFromURL"},{"iconClass":"record-toolbar-item","className":"WebInspector.TimelinePanel.ActionDelegate","contextTypes":["WebInspector.TimelinePanel"],"actionId":"timeline.toggle-recording","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"type":"@WebInspector.ActionDelegate","options":[{"value":true,"title":"Record"},{"value":false,"title":"Stop"}]},{"className":"WebInspector.TimelinePanel.ActionDelegate","contextTypes":["WebInspector.TimelinePanel"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+S"},{"platform":"mac","shortcut":"Meta+S"}],"type":"@WebInspector.ActionDelegate","actionId":"timeline.save-to-file"},{"className":"WebInspector.TimelinePanel.ActionDelegate","contextTypes":["WebInspector.TimelinePanel"],"actionId":"timeline.load-from-file","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+O"},{"platform":"mac","shortcut":"Meta+O"}],"type":"@WebInspector.ActionDelegate","order":"10"},{"className":"WebInspector.TimelinePanel.ActionDelegate","contextTypes":["WebInspector.TimelinePanel"],"bindings":[{"shortcut":"["}],"type":"@WebInspector.ActionDelegate","actionId":"timeline.jump-to-previous-frame"},{"className":"WebInspector.TimelinePanel.ActionDelegate","contextTypes":["WebInspector.TimelinePanel"],"bindings":[{"shortcut":"]"}],"type":"@WebInspector.ActionDelegate","actionId":"timeline.jump-to-next-frame"}],"name":"timeline","condition":"!v8only","scripts":[]},{"dependencies":["common","platform"],"name":"host","scripts":[]},{"dependencies":["bindings","components","platform","ui"],"extensions":[{"className":"WebInspector.AdvancedAppProvider","type":"@WebInspector.AppProvider","order":0,"condition":"can_dock"},{"category":"Mobile","iconClass":"phone-toolbar-item","title":"Toggle device toolbar","className":"WebInspector.DeviceModeWrapper.ActionDelegate","actionId":"emulation.toggle-device-mode","bindings":[{"platform":"windows,linux","shortcut":"Shift+Ctrl+M"},{"platform":"mac","shortcut":"Shift+Meta+M"}],"type":"@WebInspector.ActionDelegate","condition":"can_dock"},{"category":"Mobile","tags":"device","title":"Capture screenshot","className":"WebInspector.DeviceModeWrapper.ActionDelegate","actionId":"emulation.capture-screenshot","type":"@WebInspector.ActionDelegate"},{"actionId":"emulation.capture-screenshot","type":"context-menu-item","location":"deviceModeMenu/tools","order":12},{"order":1,"type":"@WebInspector.ToolbarItem.Provider","actionId":"emulation.toggle-device-mode","condition":"can_dock","location":"main-toolbar-left"},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"showMediaQueryInspector","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show media queries"},{"value":false,"title":"Hide media queries"}]},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"emulation.showRulers","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show rulers"},{"value":false,"title":"Hide rulers"}]},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"emulation.showDeviceOutline","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show device frame"},{"value":false,"title":"Hide device frame"}]},{"name":"devices","settings":["standardEmulatedDeviceList","customEmulatedDeviceList"],"title":"Devices","className":"WebInspector.DevicesSettingsTab","type":"settings-view","order":"30"},{"className":"WebInspector.SensorsView.ShowActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"emulation.show-sensors","title":"Sensors"},{"actionId":"emulation.show-sensors","type":"context-menu-item","location":"mainMenu/tools/open","order":100},{"name":"sensors","title":"Sensors","tags":"geolocation, accelerometer, device orientation","className":"WebInspector.SensorsView","type":"drawer-view","order":100,"persistence":"closeable"}],"name":"emulation","scripts":[]},{"dependencies":["platform","common","host"],"name":"ui","scripts":[]},{"skip_compilation":["../InspectorBackendCommands.js","../SupportedCSSProperties.js"],"dependencies":["common","host","platform"],"extensions":[{"defaultValue":[],"type":"setting","settingName":"blockedURLs","settingType":"array"},{"defaultValue":"","type":"setting","settingName":"skipStackFramesPattern","settingType":"regex"},{"defaultValue":false,"type":"setting","settingName":"skipContentScripts","settingType":"boolean"},{"category":"Debugger","defaultValue":false,"settingName":"pauseOnExceptionEnabled","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Pause on exceptions"},{"value":false,"title":"Do not pause on exceptions"}]},{"defaultValue":false,"type":"setting","settingName":"pauseOnCaughtException","settingType":"boolean"},{"category":"Debugger","defaultValue":false,"settingName":"enableAsyncStackTraces","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Capture async stack traces"},{"value":false,"title":"Do not capture async stack traces"}]},{"defaultValue":false,"type":"setting","settingName":"showMetricsRulers","settingType":"boolean"}],"name":"sdk","scripts":[]},{"skip_compilation":["../acorn/acorn.js"],"dependencies":["common"],"name":"es_tree","scripts":[]},{"dependencies":["platform","common","diff","sdk"],"extensions":[{"className":"WebInspector.SASSSourceMapFactory","extensions":["scss"],"experiment":"liveSASS","type":"@WebInspector.SourceMapFactory"}],"name":"sass","condition":"!v8only","scripts":[]},{"dependencies":["components"],"extensions":[{"category":"Settings","title":"Settings","className":"WebInspector.SettingsController.ActionDelegate","actionId":"settings.show","bindings":[{"shortcut":"F1 Shift+?"}],"type":"@WebInspector.ActionDelegate"},{"category":"Settings","className":"WebInspector.SettingsController.ActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"settings.help","title":"Help"},{"category":"Settings","className":"WebInspector.SettingsController.ActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"settings.shortcuts","title":"Shortcuts"},{"className":"WebInspector.SettingsController.Revealer","contextTypes":["WebInspector.Setting"],"type":"@WebInspector.Revealer"},{"actionId":"settings.shortcuts","type":"context-menu-item","location":"mainMenu/footer","order":10},{"actionId":"settings.show","type":"context-menu-item","location":"mainMenu/footer","order":20},{"actionId":"settings.help","type":"context-menu-item","location":"mainMenu/footer","order":30}],"name":"settings","scripts":[]},{"dependencies":["sdk","source_frame","sources","ui","ui_lazy"],"extensions":[{"className":"WebInspector.LineLevelProfile.LineDecorator","decoratorType":"performance","type":"@WebInspector.UISourceCodeFrame.LineDecorator"}],"name":"components_lazy","scripts":[]},{"dependencies":["components","components_lazy","ui_lazy"],"extensions":[{"className":"WebInspector.ProfilesPanelFactory","order":60,"type":"@WebInspector.PanelFactory","name":"profiles","title":"Profiles"},{"className":"WebInspector.ProfilesPanel.ContextMenuProvider","contextTypes":["WebInspector.RemoteObject"],"type":"@WebInspector.ContextMenu.Provider"},{"category":"Profiler","title":"Show advanced heap snapshot properties","defaultValue":false,"settingName":"showAdvancedHeapSnapshotProperties","settingType":"boolean","type":"setting"},{"category":"Profiler","title":"Record heap allocation stack traces","defaultValue":false,"settingName":"recordAllocationStacks","settingType":"boolean","type":"setting"},{"category":"Profiler","title":"High resolution CPU profiling","defaultValue":true,"settingName":"highResolutionCpuProfiling","settingType":"boolean","type":"setting"},{"category":"Profiler","title":"Show native functions in JS Profile","defaultValue":false,"settingName":"showNativeFunctionsInJSProfile","settingType":"boolean","type":"setting"},{"iconClass":"record-toolbar-item","className":"WebInspector.ProfilesPanel.RecordActionDelegate","contextTypes":["WebInspector.ProfilesPanel"],"actionId":"profiler.toggle-recording","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"type":"@WebInspector.ActionDelegate"}],"name":"profiler","scripts":[]},{"remote":true,"name":"screencast","dependencies":["components"],"extensions":[{"className":"WebInspector.ScreencastAppProvider","type":"@WebInspector.AppProvider","order":1},{"className":"WebInspector.ScreencastApp.ToolbarButtonProvider","type":"@WebInspector.ToolbarItem.Provider","order":1,"location":"main-toolbar-left"},{"actionId":"components.request-app-banner","type":"context-menu-item","location":"mainMenu/tools","condition":"remoteFrontend","order":10}],"scripts":[],"condition":"remoteFrontend"},{"dependencies":["components"],"name":"extensions","scripts":[]},{"dependencies":["platform"],"name":"common","scripts":[]},{"dependencies":["bindings","platform","ui"],"extensions":[{"category":"Console","title":"Enable custom formatters","defaultValue":false,"settingName":"customFormatters","settingType":"boolean","type":"setting"},{"className":"WebInspector.DOMPresentationUtils.GenericDecorator","marker":"breakpoint-marker","type":"@WebInspector.DOMPresentationUtils.MarkerDecorator","color":"rgb(105, 140, 254)","title":"DOM Breakpoint"},{"defaultValue":[],"type":"setting","settingName":"customNetworkConditions","settingType":"array"},{"category":"Network","tags":"device","title":"Go offline","className":"WebInspector.NetworkConditionsActionDelegate","actionId":"components.network-offline","type":"@WebInspector.ActionDelegate"},{"category":"Network","tags":"device","title":"Go online","className":"WebInspector.NetworkConditionsActionDelegate","actionId":"components.network-online","type":"@WebInspector.ActionDelegate"},{"name":"network-conditions","settings":["customNetworkConditions"],"title":"Throttling","className":"WebInspector.NetworkConditionsSettingsTab","type":"settings-view","order":"35"},{"category":"Mobile","className":"WebInspector.RequestAppBannerActionDelegate","type":"@WebInspector.ActionDelegate","actionId":"components.request-app-banner","title":"Add to homescreen"}],"name":"components","scripts":[]},{"experiment":"securityPanel","extensions":[{"className":"WebInspector.SecurityPanelFactory","order":80,"type":"@WebInspector.PanelFactory","name":"security","title":"Security"}],"name":"security","dependencies":["network","platform","ui","sdk"],"scripts":[],"condition":"!v8only"},{"remote":true,"name":"emulated_devices","dependencies":["emulation"],"extensions":[{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 4","screen":{"horizontal":{"width":480,"height":320},"device-pixel-ratio":2,"vertical":{"width":320,"height":480}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 5","screen":{"horizontal":{"width":568,"outline":{"insets":{"top":25,"right":115,"bottom":28,"left":115},"image":"@url(iPhone5-landscape.svg)"},"height":320},"device-pixel-ratio":2,"vertical":{"width":320,"outline":{"insets":{"top":105,"right":25,"bottom":111,"left":29},"image":"@url(iPhone5-portrait.svg)"},"height":568}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"phone"},"type":"emulated-device","order":40},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 6","screen":{"horizontal":{"width":667,"outline":{"insets":{"top":28,"right":106,"bottom":28,"left":106},"image":"@url(iPhone6-landscape.svg)"},"height":375},"device-pixel-ratio":2,"vertical":{"width":375,"outline":{"insets":{"top":105,"right":28,"bottom":105,"left":28},"image":"@url(iPhone6-portrait.svg)"},"height":667}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"phone"},"type":"emulated-device","order":50},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 6 Plus","screen":{"horizontal":{"width":736,"outline":{"insets":{"top":29,"right":109,"bottom":27,"left":109},"image":"@url(iPhone6Plus-landscape.svg)"},"height":414},"device-pixel-ratio":3,"vertical":{"width":414,"outline":{"insets":{"top":107,"right":30,"bottom":111,"left":26},"image":"@url(iPhone6Plus-portrait.svg)"},"height":736}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"phone"},"type":"emulated-device","order":60},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"BlackBerry Z30","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 4","screen":{"horizontal":{"width":640,"height":384},"device-pixel-ratio":2,"vertical":{"width":384,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":25,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5-vertical-default-1x.png) 1x, @url(google-nexus-5-vertical-default-2x.png) 2x","orientation":"vertical","title":"default"},{"insets":{"top":80,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5-vertical-navigation-1x.png) 1x, @url(google-nexus-5-vertical-navigation-2x.png) 2x","orientation":"vertical","title":"navigation bar"},{"insets":{"top":80,"right":0,"bottom":312,"left":0},"image":"@url(google-nexus-5-vertical-keyboard-1x.png) 1x, @url(google-nexus-5-vertical-keyboard-2x.png) 2x","orientation":"vertical","title":"keyboard"},{"insets":{"top":25,"right":42,"bottom":0,"left":0},"image":"@url(google-nexus-5-horizontal-default-1x.png) 1x, @url(google-nexus-5-horizontal-default-2x.png) 2x","orientation":"horizontal","title":"default"},{"insets":{"top":80,"right":42,"bottom":0,"left":0},"image":"@url(google-nexus-5-horizontal-navigation-1x.png) 1x, @url(google-nexus-5-horizontal-navigation-2x.png) 2x","orientation":"horizontal","title":"navigation bar"},{"insets":{"top":80,"right":42,"bottom":202,"left":0},"image":"@url(google-nexus-5-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5-horizontal-keyboard-2x.png) 2x","orientation":"horizontal","title":"keyboard"}],"title":"Nexus 5","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":24,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5x-vertical-default-1x.png) 1x, @url(google-nexus-5x-vertical-default-2x.png) 2x","orientation":"vertical","title":"default"},{"insets":{"top":80,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5x-vertical-navigation-1x.png) 1x, @url(google-nexus-5x-vertical-navigation-2x.png) 2x","orientation":"vertical","title":"navigation bar"},{"insets":{"top":80,"right":0,"bottom":342,"left":0},"image":"@url(google-nexus-5x-vertical-keyboard-1x.png) 1x, @url(google-nexus-5x-vertical-keyboard-2x.png) 2x","orientation":"vertical","title":"keyboard"},{"insets":{"top":24,"right":48,"bottom":0,"left":0},"image":"@url(google-nexus-5x-horizontal-default-1x.png) 1x, @url(google-nexus-5x-horizontal-default-2x.png) 2x","orientation":"horizontal","title":"default"},{"insets":{"top":80,"right":48,"bottom":0,"left":0},"image":"@url(google-nexus-5x-horizontal-navigation-1x.png) 1x, @url(google-nexus-5x-horizontal-navigation-2x.png) 2x","orientation":"horizontal","title":"navigation bar"},{"insets":{"top":80,"right":48,"bottom":222,"left":0},"image":"@url(google-nexus-5x-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5x-horizontal-keyboard-2x.png) 2x","orientation":"horizontal","title":"keyboard"}],"title":"Nexus 5X","screen":{"horizontal":{"width":732,"outline":{"insets":{"top":23,"right":100,"bottom":20,"left":94},"image":"@url(Nexus5X-landscape.svg)"},"height":412},"device-pixel-ratio":2.625,"vertical":{"width":412,"outline":{"insets":{"top":92,"right":22,"bottom":108,"left":20},"image":"@url(Nexus5X-portrait.svg)"},"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":20},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 6","screen":{"horizontal":{"width":732,"height":412},"device-pixel-ratio":3.5,"vertical":{"width":412,"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 6P","screen":{"horizontal":{"width":732,"outline":{"insets":{"top":48,"right":97,"bottom":48,"left":94},"image":"@url(Nexus6P-landscape.svg)"},"height":412},"device-pixel-ratio":3.5,"vertical":{"width":412,"outline":{"insets":{"top":94,"right":58,"bottom":97,"left":58},"image":"@url(Nexus6P-portrait.svg)"},"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":30},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"LG Optimus L70","screen":{"horizontal":{"width":640,"height":384},"device-pixel-ratio":1.25,"vertical":{"width":384,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nokia N9","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":1,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nokia Lumia 520","screen":{"horizontal":{"width":533,"height":320},"device-pixel-ratio":1.5,"vertical":{"width":320,"height":533}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Microsoft Lumia 550","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":640,"height":360}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Microsoft Lumia 950","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":4,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy S III","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy S5","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":10},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Kindle Fire HDX","screen":{"horizontal":{"width":2560,"height":1600},"device-pixel-ratio":2,"vertical":{"width":1600,"height":2560}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPad Mini","screen":{"horizontal":{"width":1024,"height":768},"device-pixel-ratio":2,"vertical":{"width":768,"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPad","screen":{"horizontal":{"width":1024,"outline":{"insets":{"top":56,"right":116,"bottom":52,"left":112},"image":"@url(iPad-landscape.svg)"},"height":768},"device-pixel-ratio":2,"vertical":{"width":768,"outline":{"insets":{"top":114,"right":55,"bottom":114,"left":52},"image":"@url(iPad-portrait.svg)"},"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1","type":"tablet"},"type":"emulated-device","order":70},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Blackberry PlayBook","screen":{"horizontal":{"width":1024,"height":600},"device-pixel-ratio":1,"vertical":{"width":600,"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 10","screen":{"horizontal":{"width":1280,"height":800},"device-pixel-ratio":2,"vertical":{"width":800,"height":1280}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Safari/537.36","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 7","screen":{"horizontal":{"width":960,"height":600},"device-pixel-ratio":2,"vertical":{"width":600,"height":960}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Safari/537.36","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy Note 3","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy Note II","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with touch","screen":{"horizontal":{"width":1280,"height":950},"device-pixel-ratio":1,"vertical":{"width":950,"height":1280}},"capabilities":["touch"],"user-agent":"","type":"notebook"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with HiDPI screen","screen":{"horizontal":{"width":1440,"height":900},"device-pixel-ratio":2,"vertical":{"width":900,"height":1440}},"capabilities":[],"user-agent":"","type":"notebook"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with MDPI screen","screen":{"horizontal":{"width":1280,"height":800},"device-pixel-ratio":1,"vertical":{"width":800,"height":1280}},"capabilities":[],"user-agent":"","type":"notebook"},"type":"emulated-device"}],"scripts":[],"condition":"!v8only"}];var applicationDescriptor;var _loadedScripts={};for(var k of[]){};function loadResourcePromise(url)
{return new Promise(load);function load(fulfill,reject)
{var xhr=new XMLHttpRequest();xhr.open("GET",url,true);xhr.onreadystatechange=onreadystatechange;function onreadystatechange(e)
{if(xhr.readyState!==4)
return;if([0,200,304].indexOf(xhr.status)===-1)
reject(new Error("While loading from url "+url+" server responded with a status of "+xhr.status));else
fulfill(e.target.response);}
xhr.send(null);}}
function normalizePath(path)
{if(path.indexOf("..")===-1&&path.indexOf(".")===-1)
return path;var normalizedSegments=[];var segments=path.split("/");for(var i=0;i<segments.length;i++){var segment=segments[i];if(segment===".")
continue;else if(segment==="..")
normalizedSegments.pop();else if(segment)
normalizedSegments.push(segment);}
var normalizedPath=normalizedSegments.join("/");if(normalizedPath[normalizedPath.length-1]==="/")
return normalizedPath;if(path[0]==="/"&&normalizedPath)
normalizedPath="/"+normalizedPath;if((path[path.length-1]==="/")||(segments[segments.length-1]===".")||(segments[segments.length-1]===".."))
normalizedPath=normalizedPath+"/";return normalizedPath;}
function loadScriptsPromise(scriptNames,base)
{var promises=[];var urls=[];var sources=new Array(scriptNames.length);var scriptToEval=0;for(var i=0;i<scriptNames.length;++i){var scriptName=scriptNames[i];var sourceURL=(base||self._importScriptPathPrefix)+scriptName;var schemaIndex=sourceURL.indexOf("://")+3;var pathIndex=sourceURL.indexOf("/",schemaIndex);if(pathIndex===-1)
pathIndex=sourceURL.length;sourceURL=sourceURL.substring(0,pathIndex)+normalizePath(sourceURL.substring(pathIndex));if(_loadedScripts[sourceURL])
continue;urls.push(sourceURL);promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null,i),scriptSourceLoaded.bind(null,i,undefined)));}
return Promise.all(promises).then(undefined);function scriptSourceLoaded(scriptNumber,scriptSource)
{sources[scriptNumber]=scriptSource||"";while(typeof sources[scriptToEval]!=="undefined"){evaluateScript(urls[scriptToEval],sources[scriptToEval]);++scriptToEval;}}
function evaluateScript(sourceURL,scriptSource)
{_loadedScripts[sourceURL]=true;if(!scriptSource){console.error("Empty response arrived for script '"+sourceURL+"'");return;}
self.eval(scriptSource+"\n//# sourceURL="+sourceURL);}}
(function(){var baseUrl=self.location?self.location.origin+self.location.pathname:"";self._importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf("/")+1);})();function Runtime(descriptors)
{this._modules=[];this._modulesMap={};this._extensions=[];this._cachedTypeClasses={};this._descriptorsMap={};for(var i=0;i<descriptors.length;++i)
this._registerModule(descriptors[i]);}
Runtime._queryParamsObject={__proto__:null};Runtime.cachedResources={__proto__:null};Runtime.isReleaseMode=function()
{return!!allDescriptors.length;}
Runtime.startApplication=function(appName)
{console.timeStamp("Runtime.startApplication");var allDescriptorsByName={};for(var i=0;Runtime.isReleaseMode()&&i<allDescriptors.length;++i){var d=allDescriptors[i];allDescriptorsByName[d["name"]]=d;}
var applicationPromise;if(applicationDescriptor)
applicationPromise=Promise.resolve(applicationDescriptor);else
applicationPromise=loadResourcePromise(appName+".json").then(JSON.parse.bind(JSON));return applicationPromise.then(parseModuleDescriptors);function parseModuleDescriptors(appDescriptor)
{var configuration=appDescriptor.modules;var moduleJSONPromises=[];var coreModuleNames=[];for(var i=0;i<configuration.length;++i){var descriptor=configuration[i];var name=descriptor["name"];var moduleJSON=allDescriptorsByName[name];if(moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));else
moduleJSONPromises.push(loadResourcePromise(name+"/module.json").then(JSON.parse.bind(JSON)));if(descriptor["type"]==="autostart")
coreModuleNames.push(name);}
return Promise.all(moduleJSONPromises).then(instantiateRuntime);function instantiateRuntime(moduleDescriptors)
{for(var i=0;!Runtime.isReleaseMode()&&i<moduleDescriptors.length;++i){moduleDescriptors[i]["name"]=configuration[i]["name"];moduleDescriptors[i]["condition"]=configuration[i]["condition"];}
self.runtime=new Runtime(moduleDescriptors);if(coreModuleNames)
return(self.runtime._loadAutoStartModules(coreModuleNames));return Promise.resolve();}}}
Runtime.startWorker=function(appName)
{return Runtime.startApplication(appName).then(sendWorkerReady);function sendWorkerReady()
{self.postMessage("workerReady");}}
Runtime._sharedWorkerNewPortCallback=null;Runtime._sharedWorkerConnectedPorts=[];Runtime.startSharedWorker=function(appName)
{var startPromise=Runtime.startApplication(appName);self.onconnect=function(event)
{var newPort=(event.ports[0]);startPromise.then(sendWorkerReadyAndContinue);function sendWorkerReadyAndContinue()
{newPort.postMessage("workerReady");if(Runtime._sharedWorkerNewPortCallback)
Runtime._sharedWorkerNewPortCallback.call(null,newPort);else
Runtime._sharedWorkerConnectedPorts.push(newPort);}}}
Runtime.setSharedWorkerNewPortCallback=function(callback)
{Runtime._sharedWorkerNewPortCallback=callback;while(Runtime._sharedWorkerConnectedPorts.length){var port=Runtime._sharedWorkerConnectedPorts.shift();callback.call(null,port);}}
Runtime.queryParam=function(name)
{return Runtime._queryParamsObject[name]||null;}
Runtime.constructQueryParams=function(banned)
{var params=[];for(var key in Runtime._queryParamsObject){if(!key||banned.indexOf(key)!==-1)
continue;params.push(key+"="+Runtime._queryParamsObject[key]);}
return params.length?"?"+params.join("&"):"";}
Runtime._experimentsSetting=function()
{try{return(JSON.parse(self.localStorage&&self.localStorage["experiments"]?self.localStorage["experiments"]:"{}"));}catch(e){console.error("Failed to parse localStorage['experiments']");return{};}}
Runtime._some=function(promises)
{var all=[];var wasRejected=[];for(var i=0;i<promises.length;++i){var handlerFunction=(handler.bind(promises[i],i));all.push(promises[i].catch(handlerFunction));}
return Promise.all(all).then(filterOutFailuresResults);function filterOutFailuresResults(results)
{var filtered=[];for(var i=0;i<results.length;++i){if(!wasRejected[i])
filtered.push(results[i]);}
return filtered;}
function handler(index,e)
{wasRejected[index]=true;console.error(e.stack);}}
Runtime._console=console;Runtime._originalAssert=console.assert;Runtime._assert=function(value,message)
{if(value)
return;Runtime._originalAssert.call(Runtime._console,value,message+" "+new Error().stack);}
Runtime.prototype={useTestBase:function()
{Runtime._remoteBase="http://localhost:8000/inspector-sources/";},_registerModule:function(descriptor)
{var module=new Runtime.Module(this,descriptor);this._modules.push(module);this._modulesMap[descriptor["name"]]=module;},loadModulePromise:function(moduleName)
{return this._modulesMap[moduleName]._loadPromise();},_loadAutoStartModules:function(moduleNames)
{var promises=[];for(var i=0;i<moduleNames.length;++i){if(Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded=true;else
promises.push(this.loadModulePromise(moduleNames[i]));}
return Promise.all(promises);},_checkExtensionApplicability:function(extension,predicate)
{if(!predicate)
return false;var contextTypes=(extension.descriptor().contextTypes);if(!contextTypes)
return true;for(var i=0;i<contextTypes.length;++i){var contextType=this._resolve(contextTypes[i]);var isMatching=!!contextType&&predicate(contextType);if(isMatching)
return true;}
return false;},isExtensionApplicableToContext:function(extension,context)
{if(!context)
return true;return this._checkExtensionApplicability(extension,isInstanceOf);function isInstanceOf(targetType)
{return context instanceof targetType;}},isExtensionApplicableToContextTypes:function(extension,currentContextTypes)
{if(!extension.descriptor().contextTypes)
return true;return this._checkExtensionApplicability(extension,currentContextTypes?isContextTypeKnown:null);function isContextTypeKnown(targetType)
{return currentContextTypes.has(targetType);}},extensions:function(type,context)
{return this._extensions.filter(filter).sort(orderComparator);function filter(extension)
{if(extension._type!==type&&extension._typeClass()!==type)
return false;if(!extension.enabled())
return false;return!context||extension.isApplicable(context);}
function orderComparator(extension1,extension2)
{var order1=extension1.descriptor()["order"]||0;var order2=extension2.descriptor()["order"]||0;return order1-order2;}},extension:function(type,context)
{return this.extensions(type,context)[0]||null;},instancesPromise:function(type,context)
{var extensions=this.extensions(type,context);var promises=[];for(var i=0;i<extensions.length;++i)
promises.push(extensions[i].instancePromise());return Runtime._some(promises);},instancePromise:function(type,context)
{var extension=this.extension(type,context);if(!extension)
return Promise.reject(new Error("No such extension: "+type+" in given context."));return extension.instancePromise();},_resolve:function(typeName)
{if(!this._cachedTypeClasses[typeName]){var path=typeName.split(".");var object=self;for(var i=0;object&&(i<path.length);++i)
object=object[path[i]];if(object)
this._cachedTypeClasses[typeName]=(object);}
return this._cachedTypeClasses[typeName]||null;}}
Runtime.ModuleDescriptor=function()
{this.name;this.extensions;this.dependencies;this.scripts;this.remote;}
Runtime.ExtensionDescriptor=function()
{this.type;this.className;this.contextTypes;}
Runtime.Module=function(manager,descriptor)
{this._manager=manager;this._descriptor=descriptor;this._name=descriptor.name;this._instanceMap={};var extensions=(descriptor.extensions);for(var i=0;extensions&&i<extensions.length;++i)
this._manager._extensions.push(new Runtime.Extension(this,extensions[i]));this._loaded=false;}
Runtime.Module.prototype={name:function()
{return this._name;},enabled:function()
{return Runtime._isDescriptorEnabled(this._descriptor);},resource:function(name)
{var fullName=this._name+"/"+name;var content=Runtime.cachedResources[fullName];if(!content)
throw new Error(fullName+" not preloaded. Check module.json");return content;},_loadPromise:function()
{if(this._loaded)
return Promise.resolve();if(!this.enabled())
return Promise.reject(new Error("Module "+this._name+" is not enabled"));if(this._pendingLoadPromise)
return this._pendingLoadPromise;var dependencies=this._descriptor.dependencies;var dependencyPromises=[];for(var i=0;dependencies&&i<dependencies.length;++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());this._pendingLoadPromise=Promise.all(dependencyPromises).then(this._loadResources.bind(this)).then(this._loadScripts.bind(this)).then(markAsLoaded.bind(this));return this._pendingLoadPromise;function markAsLoaded()
{delete this._pendingLoadPromise;this._loaded=true;}},_loadResources:function()
{var resources=this._descriptor["resources"];if(!resources)
return Promise.resolve();var promises=[];for(var i=0;i<resources.length;++i){var url=this._modularizeURL(resources[i]);promises.push(loadResourcePromise(url).then(cacheResource.bind(this,url),cacheResource.bind(this,url,undefined)));}
return Promise.all(promises).then(undefined);function cacheResource(path,content)
{if(!content){console.error("Failed to load resource: "+path);return;}
Runtime.cachedResources[path]=content+Runtime.resolveSourceURL(path);}},_loadScripts:function()
{if(!this._descriptor.scripts)
return Promise.resolve();if(Runtime.isReleaseMode())
return loadScriptsPromise([this._name+"_module.js"],this._remoteBase());return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL,this));},_modularizeURL:function(resourceName)
{return normalizePath(this._name+"/"+resourceName);},_remoteBase:function()
{return this._descriptor.remote&&Runtime._remoteBase||undefined;},substituteURL:function(value)
{var base=this._remoteBase()||"";return value.replace(/@url\(([^\)]*?)\)/g,convertURL.bind(this));function convertURL(match,url)
{return base+this._modularizeURL(url);}},_instance:function(className,extension)
{if(className in this._instanceMap)
return this._instanceMap[className];var constructorFunction=self.eval(className);if(!(constructorFunction instanceof Function)){this._instanceMap[className]=null;return null;}
var instance=new constructorFunction(extension);this._instanceMap[className]=instance;return instance;}}
Runtime._isDescriptorEnabled=function(descriptor)
{var activatorExperiment=descriptor["experiment"];if(activatorExperiment&&activatorExperiment.startsWith("!")&&Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;if(activatorExperiment&&!activatorExperiment.startsWith("!")&&!Runtime.experiments.isEnabled(activatorExperiment))
return false;var condition=descriptor["condition"];if(condition&&!condition.startsWith("!")&&!Runtime.queryParam(condition))
return false;if(condition&&condition.startsWith("!")&&Runtime.queryParam(condition.substring(1)))
return false;return true;}
Runtime.Extension=function(module,descriptor)
{this._module=module;this._descriptor=descriptor;this._type=descriptor.type;this._hasTypeClass=this._type.charAt(0)==="@";this._className=descriptor.className||null;}
Runtime.Extension.prototype={descriptor:function()
{return this._descriptor;},module:function()
{return this._module;},enabled:function()
{return this._module.enabled()&&Runtime._isDescriptorEnabled(this.descriptor());},_typeClass:function()
{if(!this._hasTypeClass)
return null;return this._module._manager._resolve(this._type.substring(1));},isApplicable:function(context)
{return this._module._manager.isExtensionApplicableToContext(this,context);},instancePromise:function()
{if(!this._className)
return Promise.reject(new Error("No class name in extension"));var className=this._className;if(this._instance)
return Promise.resolve(this._instance);return this._module._loadPromise().then(constructInstance.bind(this));function constructInstance()
{var result=this._module._instance(className,this);if(!result)
return Promise.reject("Could not instantiate: "+className);return result;}},title:function(platform)
{return this._descriptor["title-"+platform]||this._descriptor["title"];}}
Runtime.ExperimentsSupport=function()
{this._supportEnabled=Runtime.queryParam("experiments")!==null;this._experiments=[];this._experimentNames={};this._enabledTransiently={};}
Runtime.ExperimentsSupport.prototype={allConfigurableExperiments:function()
{var result=[];for(var i=0;i<this._experiments.length;i++){var experiment=this._experiments[i];if(!this._enabledTransiently[experiment.name])
result.push(experiment);}
return result;},supportEnabled:function()
{return this._supportEnabled;},_setExperimentsSetting:function(value)
{if(!self.localStorage)
return;self.localStorage["experiments"]=JSON.stringify(value);},register:function(experimentName,experimentTitle,hidden)
{Runtime._assert(!this._experimentNames[experimentName],"Duplicate registration of experiment "+experimentName);this._experimentNames[experimentName]=true;this._experiments.push(new Runtime.Experiment(this,experimentName,experimentTitle,!!hidden));},isEnabled:function(experimentName)
{this._checkExperiment(experimentName);if(this._enabledTransiently[experimentName])
return true;if(!this.supportEnabled())
return false;return!!Runtime._experimentsSetting()[experimentName];},setEnabled:function(experimentName,enabled)
{this._checkExperiment(experimentName);var experimentsSetting=Runtime._experimentsSetting();experimentsSetting[experimentName]=enabled;this._setExperimentsSetting(experimentsSetting);},setDefaultExperiments:function(experimentNames)
{for(var i=0;i<experimentNames.length;++i){this._checkExperiment(experimentNames[i]);this._enabledTransiently[experimentNames[i]]=true;}},enableForTest:function(experimentName)
{this._checkExperiment(experimentName);this._enabledTransiently[experimentName]=true;},clearForTest:function()
{this._experiments=[];this._experimentNames={};this._enabledTransiently={};},cleanUpStaleExperiments:function()
{var experimentsSetting=Runtime._experimentsSetting();var cleanedUpExperimentSetting={};for(var i=0;i<this._experiments.length;++i){var experimentName=this._experiments[i].name;if(experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName]=true;}
this._setExperimentsSetting(cleanedUpExperimentSetting);},_checkExperiment:function(experimentName)
{Runtime._assert(this._experimentNames[experimentName],"Unknown experiment "+experimentName);}}
Runtime.Experiment=function(experiments,name,title,hidden)
{this.name=name;this.title=title;this.hidden=hidden;this._experiments=experiments;}
Runtime.Experiment.prototype={isEnabled:function()
{return this._experiments.isEnabled(this.name);},setEnabled:function(enabled)
{this._experiments.setEnabled(this.name,enabled);}}
{(function parseQueryParameters()
{var queryParams=location.search;if(!queryParams)
return;var params=queryParams.substring(1).split("&");for(var i=0;i<params.length;++i){var pair=params[i].split("=");var name=pair.shift();Runtime._queryParamsObject[name]=pair.join("=");}})();}
Runtime.experiments=new Runtime.ExperimentsSupport();Runtime._remoteBase=Runtime.queryParam("remoteBase");{(function validateRemoteBase()
{var remoteBaseRegexp=/^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/;if(Runtime._remoteBase&&!remoteBaseRegexp.test(Runtime._remoteBase))
Runtime._remoteBase=null;})();}
Runtime.resolveSourceURL=function(path)
{var sourceURL=self.location.href;if(self.location.search)
sourceURL=sourceURL.replace(self.location.search,"");sourceURL=sourceURL.substring(0,sourceURL.lastIndexOf("/")+1)+path;return"\n/*# sourceURL="+sourceURL+" */";}
var runtime;console=console;console.__originalAssert=console.assert;console.assert=function(value,message)
{if(value)
return;console.__originalAssert(value,message);}
var ArrayLike;Object.isEmpty=function(obj)
{for(var i in obj)
return false;return true;}
Object.values=function(obj)
{var result=Object.keys(obj);var length=result.length;for(var i=0;i<length;++i)
result[i]=obj[result[i]];return result;}
function mod(m,n)
{return((m%n)+n)%n;}
String.prototype.findAll=function(string)
{var matches=[];var i=this.indexOf(string);while(i!==-1){matches.push(i);i=this.indexOf(string,i+string.length);}
return matches;}
String.prototype.replaceControlCharacters=function()
{return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g,"�");}
String.prototype.isWhitespace=function()
{return/^\s*$/.test(this);}
String.prototype.computeLineEndings=function()
{var endings=this.findAll("\n");endings.push(this.length);return endings;}
String.prototype.escapeCharacters=function(chars)
{var foundChar=false;for(var i=0;i<chars.length;++i){if(this.indexOf(chars.charAt(i))!==-1){foundChar=true;break;}}
if(!foundChar)
return String(this);var result="";for(var i=0;i<this.length;++i){if(chars.indexOf(this.charAt(i))!==-1)
result+="\\";result+=this.charAt(i);}
return result;}
String.regexSpecialCharacters=function()
{return"^[]{}()\\.^$*+?|-,";}
String.prototype.escapeForRegExp=function()
{return this.escapeCharacters(String.regexSpecialCharacters());}
String.prototype.escapeHTML=function()
{return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");}
String.prototype.unescapeHTML=function()
{return this.replace(/</g,"<").replace(/>/g,">").replace(/:/g,":").replace(/"/g,"\"").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");}
String.prototype.collapseWhitespace=function()
{return this.replace(/[\s\xA0]+/g," ");}
String.prototype.trimMiddle=function(maxLength)
{if(this.length<=maxLength)
return String(this);var leftHalf=maxLength>>1;var rightHalf=maxLength-leftHalf-1;return this.substr(0,leftHalf)+"\u2026"+this.substr(this.length-rightHalf,rightHalf);}
String.prototype.trimEnd=function(maxLength)
{if(this.length<=maxLength)
return String(this);return this.substr(0,maxLength-1)+"\u2026";}
String.prototype.trimURL=function(baseURLDomain)
{var result=this.replace(/^(https|http|file):\/\//i,"");if(baseURLDomain){if(result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
result=result.substr(baseURLDomain.length);}
return result;}
String.prototype.toTitleCase=function()
{return this.substring(0,1).toUpperCase()+this.substring(1);}
String.prototype.compareTo=function(other)
{if(this>other)
return 1;if(this<other)
return-1;return 0;}
String.prototype.removeURLFragment=function()
{var fragmentIndex=this.indexOf("#");if(fragmentIndex==-1)
fragmentIndex=this.length;return this.substring(0,fragmentIndex);}
String.hashCode=function(string)
{if(!string)
return 0;var p=((1<<30)*4-5);var z=0x5033d967;var z2=0x59d2f15d;var s=0;var zi=1;for(var i=0;i<string.length;i++){var xi=string.charCodeAt(i)*z2;s=(s+zi*xi)%p;zi=(zi*z)%p;}
s=(s+zi*(p-1))%p;return Math.abs(s|0);}
String.isDigitAt=function(string,index)
{var c=string.charCodeAt(index);return(48<=c&&c<=57);}
String.prototype.toBase64=function()
{function encodeBits(b)
{return b<26?b+65:b<52?b+71:b<62?b-4:b===62?43:b===63?47:65;}
var encoder=new TextEncoder();var data=encoder.encode(this.toString());var n=data.length;var encoded="";if(n===0)
return encoded;var shift;var v=0;for(var i=0;i<n;i++){shift=i%3;v|=data[i]<<(16>>>shift&24);if(shift===2){encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),encodeBits(v&63));v=0;}}
if(shift===0)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),61,61);else if(shift===1)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),61);return encoded;}
String.naturalOrderComparator=function(a,b)
{var chunk=/^\d+|^\D+/;var chunka,chunkb,anum,bnum;while(1){if(a){if(!b)
return 1;}else{if(b)
return-1;else
return 0;}
chunka=a.match(chunk)[0];chunkb=b.match(chunk)[0];anum=!isNaN(chunka);bnum=!isNaN(chunkb);if(anum&&!bnum)
return-1;if(bnum&&!anum)
return 1;if(anum&&bnum){var diff=chunka-chunkb;if(diff)
return diff;if(chunka.length!==chunkb.length){if(!+chunka&&!+chunkb)
return chunka.length-chunkb.length;else
return chunkb.length-chunka.length;}}else if(chunka!==chunkb)
return(chunka<chunkb)?-1:1;a=a.substring(chunka.length);b=b.substring(chunkb.length);}}
String.caseInsensetiveComparator=function(a,b)
{a=a.toUpperCase();b=b.toUpperCase();if(a===b)
return 0;return a>b?1:-1;}
Number.constrain=function(num,min,max)
{if(num<min)
num=min;else if(num>max)
num=max;return num;}
Number.gcd=function(a,b)
{if(b===0)
return a;else
return Number.gcd(b,a%b);}
Number.toFixedIfFloating=function(value)
{if(!value||isNaN(value))
return value;var number=Number(value);return number%1?number.toFixed(3):String(number);}
Date.prototype.toISO8601Compact=function()
{function leadZero(x)
{return(x>9?"":"0")+x;}
return this.getFullYear()+
leadZero(this.getMonth()+1)+
leadZero(this.getDate())+"T"+
leadZero(this.getHours())+
leadZero(this.getMinutes())+
leadZero(this.getSeconds());}
Date.prototype.toConsoleTime=function()
{function leadZero2(x)
{return(x>9?"":"0")+x;}
function leadZero3(x)
{return"0".repeat(3-x.toString().length)+x;}
return this.getFullYear()+"-"+
leadZero2(this.getMonth()+1)+"-"+
leadZero2(this.getDate())+" "+
leadZero2(this.getHours())+":"+
leadZero2(this.getMinutes())+":"+
leadZero2(this.getSeconds())+"."+
leadZero3(this.getMilliseconds());}
Object.defineProperty(Array.prototype,"remove",{value:function(value,firstOnly)
{var index=this.indexOf(value);if(index===-1)
return false;if(firstOnly){this.splice(index,1);return true;}
for(var i=index+1,n=this.length;i<n;++i){if(this[i]!==value)
this[index++]=this[i];}
this.length=index;return true;}});Object.defineProperty(Array.prototype,"keySet",{value:function()
{var keys={};for(var i=0;i<this.length;++i)
keys[this[i]]=true;return keys;}});Object.defineProperty(Array.prototype,"pushAll",{value:function(array)
{Array.prototype.push.apply(this,array);}});Object.defineProperty(Array.prototype,"rotate",{value:function(index)
{var result=[];for(var i=index;i<index+this.length;++i)
result.push(this[i%this.length]);return result;}});Object.defineProperty(Array.prototype,"sortNumbers",{value:function()
{function numericComparator(a,b)
{return a-b;}
this.sort(numericComparator);}});Object.defineProperty(Uint32Array.prototype,"sort",{value:Array.prototype.sort});(function(){var partition={value:function(comparator,left,right,pivotIndex)
{function swap(array,i1,i2)
{var temp=array[i1];array[i1]=array[i2];array[i2]=temp;}
var pivotValue=this[pivotIndex];swap(this,right,pivotIndex);var storeIndex=left;for(var i=left;i<right;++i){if(comparator(this[i],pivotValue)<0){swap(this,storeIndex,i);++storeIndex;}}
swap(this,right,storeIndex);return storeIndex;}};Object.defineProperty(Array.prototype,"partition",partition);Object.defineProperty(Uint32Array.prototype,"partition",partition);var sortRange={value:function(comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight)
{function quickSortRange(array,comparator,left,right,sortWindowLeft,sortWindowRight)
{if(right<=left)
return;var pivotIndex=Math.floor(Math.random()*(right-left))+left;var pivotNewIndex=array.partition(comparator,left,right,pivotIndex);if(sortWindowLeft<pivotNewIndex)
quickSortRange(array,comparator,left,pivotNewIndex-1,sortWindowLeft,sortWindowRight);if(pivotNewIndex<sortWindowRight)
quickSortRange(array,comparator,pivotNewIndex+1,right,sortWindowLeft,sortWindowRight);}
if(leftBound===0&&rightBound===(this.length-1)&&sortWindowLeft===0&&sortWindowRight>=rightBound)
this.sort(comparator);else
quickSortRange(this,comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight);return this;}}
Object.defineProperty(Array.prototype,"sortRange",sortRange);Object.defineProperty(Uint32Array.prototype,"sortRange",sortRange);})();Object.defineProperty(Array.prototype,"stableSort",{value:function(comparator)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var indices=new Array(this.length);for(var i=0;i<this.length;++i)
indices[i]=i;var self=this;function indexComparator(a,b)
{var result=comparator(self[a],self[b]);return result?result:a-b;}
indices.sort(indexComparator);for(var i=0;i<this.length;++i){if(indices[i]<0||i===indices[i])
continue;var cyclical=i;var saved=this[i];while(true){var next=indices[cyclical];indices[cyclical]=-1;if(next===i){this[cyclical]=saved;break;}else{this[cyclical]=this[next];cyclical=next;}}}
return this;}});Object.defineProperty(Array.prototype,"qselect",{value:function(k,comparator)
{if(k<0||k>=this.length)
return;if(!comparator)
comparator=function(a,b){return a-b;}
var low=0;var high=this.length-1;for(;;){var pivotPosition=this.partition(comparator,low,high,Math.floor((high+low)/2));if(pivotPosition===k)
return this[k];else if(pivotPosition>k)
high=pivotPosition-1;else
low=pivotPosition+1;}}});Object.defineProperty(Array.prototype,"lowerBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Array.prototype,"upperBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>=0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Uint32Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Uint32Array.prototype,"upperBound",{value:Array.prototype.upperBound});Object.defineProperty(Float64Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Array.prototype,"binaryIndexOf",{value:function(value,comparator)
{var index=this.lowerBound(value,comparator);return index<this.length&&comparator(value,this[index])===0?index:-1;}});Object.defineProperty(Array.prototype,"select",{value:function(field)
{var result=new Array(this.length);for(var i=0;i<this.length;++i)
result[i]=this[i][field];return result;}});Object.defineProperty(Array.prototype,"peekLast",{value:function()
{return this[this.length-1];}});(function(){function mergeOrIntersect(array1,array2,comparator,mergeNotIntersect)
{var result=[];var i=0;var j=0;while(i<array1.length&&j<array2.length){var compareValue=comparator(array1[i],array2[j]);if(mergeNotIntersect||!compareValue)
result.push(compareValue<=0?array1[i]:array2[j]);if(compareValue<=0)
i++;if(compareValue>=0)
j++;}
if(mergeNotIntersect){while(i<array1.length)
result.push(array1[i++]);while(j<array2.length)
result.push(array2[j++]);}
return result;}
Object.defineProperty(Array.prototype,"intersectOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,false);}});Object.defineProperty(Array.prototype,"mergeOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,true);}});})();String.sprintf=function(format,var_arg)
{return String.vsprintf(format,Array.prototype.slice.call(arguments,1));}
String.tokenizeFormatString=function(format,formatters)
{var tokens=[];var substitutionIndex=0;function addStringToken(str)
{if(tokens.length&&tokens[tokens.length-1].type==="string")
tokens[tokens.length-1].value+=str;else
tokens.push({type:"string",value:str});}
function addSpecifierToken(specifier,precision,substitutionIndex)
{tokens.push({type:"specifier",specifier:specifier,precision:precision,substitutionIndex:substitutionIndex});}
var index=0;for(var precentIndex=format.indexOf("%",index);precentIndex!==-1;precentIndex=format.indexOf("%",index)){if(format.length===index)
break;addStringToken(format.substring(index,precentIndex));index=precentIndex+1;if(format[index]==="%"){addStringToken("%");++index;continue;}
if(String.isDigitAt(format,index)){var number=parseInt(format.substring(index),10);while(String.isDigitAt(format,index))
++index;if(number>0&&format[index]==="$"){substitutionIndex=(number-1);++index;}}
var precision=-1;if(format[index]==="."){++index;precision=parseInt(format.substring(index),10);if(isNaN(precision))
precision=0;while(String.isDigitAt(format,index))
++index;}
if(!(format[index]in formatters)){addStringToken(format.substring(precentIndex,index+1));++index;continue;}
addSpecifierToken(format[index],precision,substitutionIndex);++substitutionIndex;++index;}
addStringToken(format.substring(index));return tokens;}
String.standardFormatters={d:function(substitution)
{return!isNaN(substitution)?substitution:0;},f:function(substitution,token)
{if(substitution&&token.precision>-1)
substitution=substitution.toFixed(token.precision);return!isNaN(substitution)?substitution:(token.precision>-1?Number(0).toFixed(token.precision):0);},s:function(substitution)
{return substitution;}}
String.vsprintf=function(format,substitutions)
{return String.format(format,substitutions,String.standardFormatters,"",function(a,b){return a+b;}).formattedResult;}
String.format=function(format,substitutions,formatters,initialValue,append,tokenizedFormat)
{if(!format||!substitutions||!substitutions.length)
return{formattedResult:append(initialValue,format),unusedSubstitutions:substitutions};function prettyFunctionName()
{return"String.format(\""+format+"\", \""+Array.prototype.join.call(substitutions,"\", \"")+"\")";}
function warn(msg)
{console.warn(prettyFunctionName()+": "+msg);}
function error(msg)
{console.error(prettyFunctionName()+": "+msg);}
var result=initialValue;var tokens=tokenizedFormat||String.tokenizeFormatString(format,formatters);var usedSubstitutionIndexes={};for(var i=0;i<tokens.length;++i){var token=tokens[i];if(token.type==="string"){result=append(result,token.value);continue;}
if(token.type!=="specifier"){error("Unknown token type \""+token.type+"\" found.");continue;}
if(token.substitutionIndex>=substitutions.length){error("not enough substitution arguments. Had "+substitutions.length+" but needed "+(token.substitutionIndex+1)+", so substitution was skipped.");result=append(result,"%"+(token.precision>-1?token.precision:"")+token.specifier);continue;}
usedSubstitutionIndexes[token.substitutionIndex]=true;if(!(token.specifier in formatters)){warn("unsupported format character \u201C"+token.specifier+"\u201D. Treating as a string.");result=append(result,substitutions[token.substitutionIndex]);continue;}
result=append(result,formatters[token.specifier](substitutions[token.substitutionIndex],token));}
var unusedSubstitutions=[];for(var i=0;i<substitutions.length;++i){if(i in usedSubstitutionIndexes)
continue;unusedSubstitutions.push(substitutions[i]);}
return{formattedResult:result,unusedSubstitutions:unusedSubstitutions};}
function createSearchRegex(query,caseSensitive,isRegex)
{var regexFlags=caseSensitive?"g":"gi";var regexObject;if(isRegex){try{regexObject=new RegExp(query,regexFlags);}catch(e){}}
if(!regexObject)
regexObject=createPlainTextSearchRegex(query,regexFlags);return regexObject;}
function createPlainTextSearchRegex(query,flags)
{var regexSpecialCharacters=String.regexSpecialCharacters();var regex="";for(var i=0;i<query.length;++i){var c=query.charAt(i);if(regexSpecialCharacters.indexOf(c)!=-1)
regex+="\\";regex+=c;}
return new RegExp(regex,flags||"");}
function countRegexMatches(regex,content)
{var text=content;var result=0;var match;while(text&&(match=regex.exec(text))){if(match[0].length>0)
++result;text=text.substring(match.index+1);}
return result;}
function spacesPadding(spacesCount)
{return"\u00a0".repeat(spacesCount);}
function numberToStringWithSpacesPadding(value,symbolsCount)
{var numberString=value.toString();var paddingLength=Math.max(0,symbolsCount-numberString.length);return spacesPadding(paddingLength)+numberString;}
Set.prototype.valuesArray=function()
{return Array.from(this.values());}
Set.prototype.addAll=function(iterable)
{for(var e of iterable)
this.add(e);}
Set.prototype.containsAll=function(iterable)
{for(var e of iterable){if(!this.has(e))
return false;}
return true;}
Map.prototype.remove=function(key)
{var value=this.get(key);this.delete(key);return value;}
Map.prototype.valuesArray=function()
{return Array.from(this.values());}
Map.prototype.keysArray=function()
{return Array.from(this.keys());}
Map.prototype.inverse=function()
{var result=new Multimap();for(var key of this.keys()){var value=this.get(key);result.set(value,key);}
return result;}
var Multimap=function()
{this._map=new Map();}
Multimap.prototype={set:function(key,value)
{var set=this._map.get(key);if(!set){set=new Set();this._map.set(key,set);}
set.add(value);},get:function(key)
{var result=this._map.get(key);if(!result)
result=new Set();return result;},has:function(key)
{return this._map.has(key);},hasValue:function(key,value)
{var set=this._map.get(key);if(!set)
return false;return set.has(value);},get size()
{return this._map.size;},remove:function(key,value)
{var values=this.get(key);values.delete(value);if(!values.size)
this._map.delete(key);},removeAll:function(key)
{this._map.delete(key);},keysArray:function()
{return this._map.keysArray();},valuesArray:function()
{var result=[];var keys=this.keysArray();for(var i=0;i<keys.length;++i)
result.pushAll(this.get(keys[i]).valuesArray());return result;},clear:function()
{this._map.clear();}}
function loadXHR(url)
{return new Promise(load);function load(successCallback,failureCallback)
{function onReadyStateChanged()
{if(xhr.readyState!==XMLHttpRequest.DONE)
return;if(xhr.status!==200){xhr.onreadystatechange=null;failureCallback(new Error(xhr.status));return;}
xhr.onreadystatechange=null;successCallback(xhr.responseText);}
var xhr=new XMLHttpRequest();xhr.withCredentials=false;xhr.open("GET",url,true);xhr.onreadystatechange=onReadyStateChanged;xhr.send(null);}}
function CallbackBarrier()
{this._pendingIncomingCallbacksCount=0;}
CallbackBarrier.prototype={createCallback:function(userCallback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");++this._pendingIncomingCallbacksCount;return this._incomingCallback.bind(this,userCallback);},callWhenDone:function(callback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.callWhenDone() is called multiple times");this._outgoingCallback=callback;if(!this._pendingIncomingCallbacksCount)
this._outgoingCallback();},donePromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callWhenDone(success);}},_incomingCallback:function(userCallback)
{console.assert(this._pendingIncomingCallbacksCount>0);if(userCallback){var args=Array.prototype.slice.call(arguments,1);userCallback.apply(null,args);}
if(!--this._pendingIncomingCallbacksCount&&this._outgoingCallback)
this._outgoingCallback();}}
function suppressUnused(value)
{}
self.setImmediate=function(callback)
{Promise.resolve().then(callback);return 0;}
Promise.prototype.spread=function(callback)
{return this.then(spreadPromise);function spreadPromise(arg)
{return callback.apply(null,arg);}}
Promise.prototype.catchException=function(defaultValue){return this.catch(function(error){console.error(error);return defaultValue;});}
Map.prototype.diff=function(other,isEqual)
{var leftKeys=this.keysArray();var rightKeys=other.keysArray();leftKeys.sort((a,b)=>a-b);rightKeys.sort((a,b)=>a-b);var removed=[];var added=[];var equal=[];var leftIndex=0;var rightIndex=0;while(leftIndex<leftKeys.length&&rightIndex<rightKeys.length){var leftKey=leftKeys[leftIndex];var rightKey=rightKeys[rightIndex];if(leftKey===rightKey&&isEqual(this.get(leftKey),other.get(rightKey))){equal.push(this.get(leftKey));++leftIndex;++rightIndex;continue;}
if(leftKey<=rightKey){removed.push(this.get(leftKey));++leftIndex;continue;}
added.push(other.get(rightKey));++rightIndex;}
while(leftIndex<leftKeys.length){var leftKey=leftKeys[leftIndex++];removed.push(this.get(leftKey));}
while(rightIndex<rightKeys.length){var rightKey=rightKeys[rightIndex++];added.push(other.get(rightKey));}
return{added:added,removed:removed,equal:equal}};Node.prototype.rangeOfWord=function(offset,stopCharacters,stayWithinNode,direction)
{var startNode;var startOffset=0;var endNode;var endOffset=0;if(!stayWithinNode)
stayWithinNode=this;if(!direction||direction==="backward"||direction==="both"){var node=this;while(node){if(node===stayWithinNode){if(!startNode)
startNode=stayWithinNode;break;}
if(node.nodeType===Node.TEXT_NODE){var start=(node===this?(offset-1):(node.nodeValue.length-1));for(var i=start;i>=0;--i){if(stopCharacters.indexOf(node.nodeValue[i])!==-1){startNode=node;startOffset=i+1;break;}}}
if(startNode)
break;node=node.traversePreviousNode(stayWithinNode);}
if(!startNode){startNode=stayWithinNode;startOffset=0;}}else{startNode=this;startOffset=offset;}
if(!direction||direction==="forward"||direction==="both"){node=this;while(node){if(node===stayWithinNode){if(!endNode)
endNode=stayWithinNode;break;}
if(node.nodeType===Node.TEXT_NODE){var start=(node===this?offset:0);for(var i=start;i<node.nodeValue.length;++i){if(stopCharacters.indexOf(node.nodeValue[i])!==-1){endNode=node;endOffset=i;break;}}}
if(endNode)
break;node=node.traverseNextNode(stayWithinNode);}
if(!endNode){endNode=stayWithinNode;endOffset=stayWithinNode.nodeType===Node.TEXT_NODE?stayWithinNode.nodeValue.length:stayWithinNode.childNodes.length;}}else{endNode=this;endOffset=offset;}
var result=this.ownerDocument.createRange();result.setStart(startNode,startOffset);result.setEnd(endNode,endOffset);return result;}
Node.prototype.traverseNextTextNode=function(stayWithin)
{var node=this.traverseNextNode(stayWithin);if(!node)
return null;var nonTextTags={"STYLE":1,"SCRIPT":1};while(node&&(node.nodeType!==Node.TEXT_NODE||nonTextTags[node.parentElement.nodeName]))
node=node.traverseNextNode(stayWithin);return node;}
Element.prototype.positionAt=function(x,y,relativeTo)
{var shift={x:0,y:0};if(relativeTo)
shift=relativeTo.boxInWindow(this.ownerDocument.defaultView);if(typeof x==="number")
this.style.setProperty("left",(shift.x+x)+"px");else
this.style.removeProperty("left");if(typeof y==="number")
this.style.setProperty("top",(shift.y+y)+"px");else
this.style.removeProperty("top");if(typeof x==="number"||typeof y==="number")
this.style.setProperty("position","absolute");else
this.style.removeProperty("position");}
Element.prototype.isScrolledToBottom=function()
{return Math.abs(this.scrollTop+this.clientHeight-this.scrollHeight)<=2;}
function removeSubsequentNodes(fromNode,toNode)
{for(var node=fromNode;node&&node!==toNode;){var nodeToRemove=node;node=node.nextSibling;nodeToRemove.remove();}}
Element.prototype.containsEventPoint=function(event)
{var box=this.getBoundingClientRect();return box.left<event.x&&event.x<box.right&&box.top<event.y&&event.y<box.bottom;}
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray=function(nameArray)
{for(var node=this;node&&node!==this.ownerDocument;node=node.parentNodeOrShadowHost()){for(var i=0;i<nameArray.length;++i){if(node.nodeName.toLowerCase()===nameArray[i].toLowerCase())
return node;}}
return null;}
Node.prototype.enclosingNodeOrSelfWithNodeName=function(nodeName)
{return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);}
Node.prototype.enclosingNodeOrSelfWithClass=function(className,stayWithin)
{return this.enclosingNodeOrSelfWithClassList([className],stayWithin);}
Node.prototype.enclosingNodeOrSelfWithClassList=function(classNames,stayWithin)
{for(var node=this;node&&node!==stayWithin&&node!==this.ownerDocument;node=node.parentNodeOrShadowHost()){if(node.nodeType===Node.ELEMENT_NODE){var containsAll=true;for(var i=0;i<classNames.length&&containsAll;++i){if(!node.classList.contains(classNames[i]))
containsAll=false;}
if(containsAll)
return(node);}}
return null;}
Node.prototype.parentElementOrShadowHost=function()
{var node=this.parentNode;if(!node)
return null;if(node.nodeType===Node.ELEMENT_NODE)
return(node);if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)
return(node.host);return null;}
Node.prototype.parentNodeOrShadowHost=function()
{return this.parentNode||this.host||null;}
Node.prototype.getComponentSelection=function()
{var parent=this.parentNode;while(parent&&parent.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)
parent=parent.parentNode;return parent instanceof ShadowRoot?parent.getSelection():this.window().getSelection();}
Node.prototype.isComponentSelectionCollapsed=function()
{var selection=this.getComponentSelection();var range=selection&&selection.rangeCount?selection.getRangeAt(0):null;return range?range.collapsed:true;}
Node.prototype.getDeepSelection=function()
{var activeElement=this.ownerDocument.activeElement;var shadowRoot=null;while(activeElement&&activeElement.shadowRoot){shadowRoot=activeElement.shadowRoot;activeElement=shadowRoot.activeElement;}
return shadowRoot?shadowRoot.getSelection():this.window().getSelection();}
Node.prototype.window=function()
{return this.ownerDocument.defaultView;}
Element.prototype.query=function(query)
{return this.ownerDocument.evaluate(query,this,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;}
Element.prototype.removeChildren=function()
{if(this.firstChild)
this.textContent="";}
Element.prototype.isInsertionCaretInside=function()
{var selection=this.getComponentSelection();var selectionRange=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!selectionRange||!selection.isCollapsed)
return false;return selectionRange.startContainer.isSelfOrDescendant(this);}
function createElement(tagName,customElementType)
{return document.createElement(tagName,customElementType||"");}
function createEvent(type,bubbles,cancelable)
{var event=document.createEvent("Event");event.initEvent(type,bubbles,cancelable);return event;}
function createTextNode(data)
{return document.createTextNode(data);}
Document.prototype.createElementWithClass=function(elementName,className,customElementType)
{var element=this.createElement(elementName,customElementType||"");if(className)
element.className=className;return element;}
function createElementWithClass(elementName,className,customElementType)
{return document.createElementWithClass(elementName,className,customElementType);}
Document.prototype.createSVGElement=function(childType,className)
{var element=this.createElementNS("http://www.w3.org/2000/svg",childType);if(className)
element.setAttribute("class",className);return element;}
function createSVGElement(childType,className)
{return document.createSVGElement(childType,className);}
function createDocumentFragment()
{return document.createDocumentFragment();}
Element.prototype.createChild=function(elementName,className,customElementType)
{var element=this.ownerDocument.createElementWithClass(elementName,className,customElementType);this.appendChild(element);return element;}
DocumentFragment.prototype.createChild=Element.prototype.createChild;Element.prototype.createTextChild=function(text)
{var element=this.ownerDocument.createTextNode(text);this.appendChild(element);return element;}
DocumentFragment.prototype.createTextChild=Element.prototype.createTextChild;Element.prototype.createTextChildren=function(var_args)
{for(var i=0,n=arguments.length;i<n;++i)
this.createTextChild(arguments[i]);}
DocumentFragment.prototype.createTextChildren=Element.prototype.createTextChildren;Element.prototype.totalOffsetLeft=function()
{return this.totalOffset().left;}
Element.prototype.totalOffsetTop=function()
{return this.totalOffset().top;}
Element.prototype.totalOffset=function()
{var rect=this.getBoundingClientRect();return{left:rect.left,top:rect.top};}
Element.prototype.scrollOffset=function()
{var curLeft=0;var curTop=0;for(var element=this;element;element=element.scrollParent){curLeft+=element.scrollLeft;curTop+=element.scrollTop;}
return{left:curLeft,top:curTop};}
Element.prototype.createSVGChild=function(childType,className)
{var child=this.ownerDocument.createSVGElement(childType,className);this.appendChild(child);return child;}
function AnchorBox(x,y,width,height)
{this.x=x||0;this.y=y||0;this.width=width||0;this.height=height||0;}
AnchorBox.prototype.relativeTo=function(box)
{return new AnchorBox(this.x-box.x,this.y-box.y,this.width,this.height);}
AnchorBox.prototype.relativeToElement=function(element)
{return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView));}
AnchorBox.prototype.equals=function(anchorBox)
{return!!anchorBox&&this.x===anchorBox.x&&this.y===anchorBox.y&&this.width===anchorBox.width&&this.height===anchorBox.height;}
Element.prototype.offsetRelativeToWindow=function(targetWindow)
{var elementOffset=new AnchorBox();var curElement=this;var curWindow=this.ownerDocument.defaultView;while(curWindow&&curElement){elementOffset.x+=curElement.totalOffsetLeft();elementOffset.y+=curElement.totalOffsetTop();if(curWindow===targetWindow)
break;curElement=curWindow.frameElement;curWindow=curWindow.parent;}
return elementOffset;}
Element.prototype.boxInWindow=function(targetWindow)
{targetWindow=targetWindow||this.ownerDocument.defaultView;var anchorBox=this.offsetRelativeToWindow(window);anchorBox.width=Math.min(this.offsetWidth,window.innerWidth-anchorBox.x);anchorBox.height=Math.min(this.offsetHeight,window.innerHeight-anchorBox.y);return anchorBox;}
Element.prototype.setTextAndTitle=function(text)
{this.textContent=text;this.title=text;}
KeyboardEvent.prototype.__defineGetter__("data",function()
{switch(this.type){case"keypress":if(!this.ctrlKey&&!this.metaKey)
return String.fromCharCode(this.charCode);else
return"";case"keydown":case"keyup":if(!this.ctrlKey&&!this.metaKey&&!this.altKey)
return String.fromCharCode(this.which);else
return"";}});Event.prototype.consume=function(preventDefault)
{this.stopImmediatePropagation();if(preventDefault)
this.preventDefault();this.handled=true;}
Text.prototype.select=function(start,end)
{start=start||0;end=end||this.textContent.length;if(start<0)
start=end+start;var selection=this.getComponentSelection();selection.removeAllRanges();var range=this.ownerDocument.createRange();range.setStart(this,start);range.setEnd(this,end);selection.addRange(range);return this;}
Element.prototype.selectionLeftOffset=function()
{var selection=this.getComponentSelection();if(!selection.containsNode(this,true))
return null;var leftOffset=selection.anchorOffset;var node=selection.anchorNode;while(node!==this){while(node.previousSibling){node=node.previousSibling;leftOffset+=node.textContent.length;}
node=node.parentNodeOrShadowHost();}
return leftOffset;}
HTMLImageElement.prototype.completePromise=function()
{var element=this;if(element.complete)
return Promise.resolve(element);return new Promise(promiseBody);function promiseBody(resolve)
{element.addEventListener("load",oncomplete);element.addEventListener("error",oncomplete);function oncomplete()
{resolve(element);}}}
Node.prototype.appendChildren=function(var_args)
{for(var i=0,n=arguments.length;i<n;++i)
this.appendChild(arguments[i]);}
Node.prototype.deepTextContent=function()
{return this.childTextNodes().map(function(node){return node.textContent;}).join("");}
Node.prototype.childTextNodes=function()
{var node=this.traverseNextTextNode(this);var result=[];var nonTextTags={"STYLE":1,"SCRIPT":1};while(node){if(!nonTextTags[node.parentElement.nodeName])
result.push(node);node=node.traverseNextTextNode(this);}
return result;}
Node.prototype.isAncestor=function(node)
{if(!node)
return false;var currentNode=node.parentNodeOrShadowHost();while(currentNode){if(this===currentNode)
return true;currentNode=currentNode.parentNodeOrShadowHost();}
return false;}
Node.prototype.isDescendant=function(descendant)
{return!!descendant&&descendant.isAncestor(this);}
Node.prototype.isSelfOrAncestor=function(node)
{return!!node&&(node===this||this.isAncestor(node));}
Node.prototype.isSelfOrDescendant=function(node)
{return!!node&&(node===this||this.isDescendant(node));}
Node.prototype.traverseNextNode=function(stayWithin)
{if(this.shadowRoot)
return this.shadowRoot;var distributedNodes=this.getDistributedNodes?this.getDistributedNodes():[];if(distributedNodes.length)
return distributedNodes[0];if(this.firstChild)
return this.firstChild;var node=this;while(node){if(stayWithin&&node===stayWithin)
return null;var sibling=nextSibling(node);if(sibling)
return sibling;node=insertionPoint(node)||node.parentNodeOrShadowHost();}
function nextSibling(node)
{var parent=insertionPoint(node);if(!parent)
return node.nextSibling;var distributedNodes=parent.getDistributedNodes?parent.getDistributedNodes():[];var position=Array.prototype.indexOf.call(distributedNodes,node);if(position+1<distributedNodes.length)
return distributedNodes[position+1];return null;}
function insertionPoint(node)
{var insertionPoints=node.getDestinationInsertionPoints?node.getDestinationInsertionPoints():[];return insertionPoints.length>0?insertionPoints[insertionPoints.length-1]:null;}
return null;}
Node.prototype.traversePreviousNode=function(stayWithin)
{if(stayWithin&&this===stayWithin)
return null;var node=this.previousSibling;while(node&&node.lastChild)
node=node.lastChild;if(node)
return node;return this.parentNodeOrShadowHost();}
Node.prototype.setTextContentTruncatedIfNeeded=function(text,placeholder)
{const maxTextContentLength=10000;if(typeof text==="string"&&text.length>maxTextContentLength){this.textContent=typeof placeholder==="string"?placeholder:text.trimMiddle(maxTextContentLength);return true;}
this.textContent=text;return false;}
Event.prototype.deepElementFromPoint=function()
{var node=this.target;while(node&&node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&node.nodeType!==Node.DOCUMENT_NODE)
node=node.parentNode;if(!node)
return null;node=node.elementFromPoint(this.pageX,this.pageY);while(node&&node.shadowRoot)
node=node.shadowRoot.elementFromPoint(this.pageX,this.pageY);return node;}
Event.prototype.deepActiveElement=function()
{var activeElement=this.target&&this.target.ownerDocument?this.target.ownerDocument.activeElement:null;while(activeElement&&activeElement.shadowRoot)
activeElement=activeElement.shadowRoot.activeElement;return activeElement;}
Document.prototype.deepElementFromPoint=function(x,y)
{var node=this.elementFromPoint(x,y);while(node&&node.shadowRoot)
node=node.shadowRoot.elementFromPoint(x,y);return node;}
function isEnterKey(event)
{return event.keyCode!==229&&event.keyIdentifier==="Enter";}
function isEscKey(event)
{return event.keyCode===27;}
function consumeEvent(e)
{e.consume();}
function runOnWindowLoad(callback)
{function windowLoaded()
{window.removeEventListener("DOMContentLoaded",windowLoaded,false);callback();}
if(document.readyState==="complete"||document.readyState==="interactive")
callback();else
window.addEventListener("DOMContentLoaded",windowLoaded,false);};self.WebInspector={};WebInspector.Worker=function(appName,workerName)
{var url=appName+".js";var remoteBase=Runtime.queryParam("remoteBase");if(remoteBase)
url+="?remoteBase="+remoteBase;var callback;this._workerPromise=new Promise(fulfill=>callback=fulfill);var worker;var isSharedWorker=!!workerName;if(isSharedWorker){worker=new SharedWorker(url,workerName);worker.port.onmessage=onMessage;}else{worker=new Worker(url);worker.onmessage=onMessage;}
function onMessage(event)
{console.assert(event.data==="workerReady");if(isSharedWorker)
worker.port.onmessage=null;else
worker.onmessage=null;callback(worker);}}
WebInspector.Worker.prototype={postMessage:function(message)
{this._workerPromise.then(postToWorker.bind(this));function postToWorker(worker)
{if(!this._disposed)
worker.postMessage(message);}},dispose:function()
{this._disposed=true;this._workerPromise.then(terminate);function terminate(worker)
{worker.terminate();}},terminate:function()
{this.dispose();},set onmessage(listener)
{this._workerPromise.then(setOnMessage);function setOnMessage(worker)
{if(worker.port)
worker.port.onmessage=listener;else
worker.onmessage=listener;}},set onerror(listener)
{this._workerPromise.then(setOnError);function setOnError(worker)
{if(worker.port)
worker.port.onerror=listener;else
worker.onerror=listener;}}};WebInspector.TextDictionary=function()
{this._words={};}
WebInspector.TextDictionary.prototype={addWord:function(word)
{if(!this._words[word])
this._words[word]=1;else
++this._words[word];},removeWord:function(word)
{if(!this._words[word])
return;if(this._words[word]===1)
delete this._words[word];else
--this._words[word];},wordsWithPrefix:function(prefix)
{var words=[];for(var i in this._words){if(i.startsWith(prefix))
words.push(i);}
return words;},hasWord:function(word)
{return!!this._words[word];},wordCount:function(word)
{return this._words[word]?this._words[word]:0;},reset:function()
{this._words={};}};WebInspector.Object=function(){}
WebInspector.Object.prototype={addEventListener:function(eventType,listener,thisObject)
{if(!listener)
console.assert(false);if(!this._listeners)
this._listeners=new Map();if(!this._listeners.has(eventType))
this._listeners.set(eventType,[]);this._listeners.get(eventType).push({thisObject:thisObject,listener:listener});return new WebInspector.EventTarget.EventDescriptor(this,eventType,thisObject,listener);},removeEventListener:function(eventType,listener,thisObject)
{console.assert(listener);if(!this._listeners||!this._listeners.has(eventType))
return;var listeners=this._listeners.get(eventType);for(var i=0;i<listeners.length;++i){if(listeners[i].listener===listener&&listeners[i].thisObject===thisObject)
listeners.splice(i--,1);}
if(!listeners.length)
this._listeners.delete(eventType);},removeAllListeners:function()
{delete this._listeners;},hasEventListeners:function(eventType)
{if(!this._listeners||!this._listeners.has(eventType))
return false;return true;},dispatchEventToListeners:function(eventType,eventData)
{if(!this._listeners||!this._listeners.has(eventType))
return false;var event=new WebInspector.Event(this,eventType,eventData);var listeners=this._listeners.get(eventType).slice(0);for(var i=0;i<listeners.length;++i){listeners[i].listener.call(listeners[i].thisObject,event);if(event._stoppedPropagation)
break;}
return event.defaultPrevented;}}
WebInspector.Event=function(target,type,data)
{this.target=target;this.type=type;this.data=data;this.defaultPrevented=false;this._stoppedPropagation=false;}
WebInspector.Event.prototype={stopPropagation:function()
{this._stoppedPropagation=true;},preventDefault:function()
{this.defaultPrevented=true;},consume:function(preventDefault)
{this.stopPropagation();if(preventDefault)
this.preventDefault();}}
WebInspector.EventTarget=function()
{}
WebInspector.EventTarget.removeEventListeners=function(eventList)
{for(var i=0;i<eventList.length;++i){var eventInfo=eventList[i];eventInfo.eventTarget.removeEventListener(eventInfo.eventType,eventInfo.method,eventInfo.receiver);}}
WebInspector.EventTarget.prototype={addEventListener:function(eventType,listener,thisObject){},removeEventListener:function(eventType,listener,thisObject){},removeAllListeners:function(){},hasEventListeners:function(eventType){},dispatchEventToListeners:function(eventType,eventData){},}
WebInspector.EventTarget.EventDescriptor=function(eventTarget,eventType,receiver,method)
{this.eventTarget=eventTarget;this.eventType=eventType;this.receiver=receiver;this.method=method;};WebInspector.NotificationService=function(){}
WebInspector.NotificationService.prototype={__proto__:WebInspector.Object.prototype}
WebInspector.NotificationService.Events={SelectedNodeChanged:"SelectedNodeChanged"}
WebInspector.notifications=new WebInspector.NotificationService();;WebInspector.Color=function(rgba,format,originalText)
{this._rgba=rgba;this._originalText=originalText||null;this._originalTextIsValid=!!this._originalText;this._format=format;if(typeof this._rgba[3]==="undefined")
this._rgba[3]=1;for(var i=0;i<4;++i){if(this._rgba[i]<0){this._rgba[i]=0;this._originalTextIsValid=false;}
if(this._rgba[i]>1){this._rgba[i]=1;this._originalTextIsValid=false;}}}
WebInspector.Color.Format={Original:"original",Nickname:"nickname",HEX:"hex",ShortHEX:"shorthex",HEXA:"hexa",ShortHEXA:"shorthexa",RGB:"rgb",RGBA:"rgba",HSL:"hsl",HSLA:"hsla"}
WebInspector.Color.parse=function(text)
{var value=text.toLowerCase().replace(/\s+/g,"");var simple=/^(?:#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|rgb\(((?:-?\d+%?,){2}-?\d+%?)\)|(\w+)|hsl\((-?\d+\.?\d*(?:,-?\d+\.?\d*%){2})\))$/i;var match=value.match(simple);if(match){if(match[1]){var hex=match[1].toLowerCase();var format;if(hex.length===3){format=WebInspector.Color.Format.ShortHEX;hex=hex.charAt(0)+hex.charAt(0)+hex.charAt(1)+hex.charAt(1)+hex.charAt(2)+hex.charAt(2);}else if(hex.length===4){format=WebInspector.Color.Format.ShortHEXA;hex=hex.charAt(0)+hex.charAt(0)+hex.charAt(1)+hex.charAt(1)+hex.charAt(2)+hex.charAt(2)+hex.charAt(3)+hex.charAt(3);}else if(hex.length===6){format=WebInspector.Color.Format.HEX;}else{format=WebInspector.Color.Format.HEXA;}
var r=parseInt(hex.substring(0,2),16);var g=parseInt(hex.substring(2,4),16);var b=parseInt(hex.substring(4,6),16);var a=hex.length===8?parseInt(hex.substring(6,8),16)/255:1;return new WebInspector.Color([r/255,g/255,b/255,a],format,text);}
if(match[2]){var rgbString=match[2].split(/\s*,\s*/);var rgba=[WebInspector.Color._parseRgbNumeric(rgbString[0]),WebInspector.Color._parseRgbNumeric(rgbString[1]),WebInspector.Color._parseRgbNumeric(rgbString[2]),1];return new WebInspector.Color(rgba,WebInspector.Color.Format.RGB,text);}
if(match[3]){var nickname=match[3].toLowerCase();if(nickname in WebInspector.Color.Nicknames){var rgba=WebInspector.Color.Nicknames[nickname];var color=WebInspector.Color.fromRGBA(rgba);color._format=WebInspector.Color.Format.Nickname;color._originalText=text;return color;}
return null;}
if(match[4]){var hslString=match[4].replace(/%/g,"").split(/\s*,\s*/);var hsla=[WebInspector.Color._parseHueNumeric(hslString[0]),WebInspector.Color._parseSatLightNumeric(hslString[1]),WebInspector.Color._parseSatLightNumeric(hslString[2]),1];var rgba=[];WebInspector.Color.hsl2rgb(hsla,rgba);return new WebInspector.Color(rgba,WebInspector.Color.Format.HSL,text);}
return null;}
var advanced=/^(?:rgba\(((?:-?\d+%?,){3}-?(?:\d+|\d*\.\d+))\)|hsla\((-?(?:\d+|\d*\.\d+)(?:,-?(?:\d+|\d*\.\d+)*%){2},-?(?:\d+|\d*\.\d+))\))$/;match=value.match(advanced);if(match){if(match[1]){var rgbaString=match[1].split(/\s*,\s*/);var rgba=[WebInspector.Color._parseRgbNumeric(rgbaString[0]),WebInspector.Color._parseRgbNumeric(rgbaString[1]),WebInspector.Color._parseRgbNumeric(rgbaString[2]),WebInspector.Color._parseAlphaNumeric(rgbaString[3])];return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA,text);}
if(match[2]){var hslaString=match[2].replace(/%/g,"").split(/\s*,\s*/);var hsla=[WebInspector.Color._parseHueNumeric(hslaString[0]),WebInspector.Color._parseSatLightNumeric(hslaString[1]),WebInspector.Color._parseSatLightNumeric(hslaString[2]),WebInspector.Color._parseAlphaNumeric(hslaString[3])];var rgba=[];WebInspector.Color.hsl2rgb(hsla,rgba);return new WebInspector.Color(rgba,WebInspector.Color.Format.HSLA,text);}}
return null;}
WebInspector.Color.fromRGBA=function(rgba)
{return new WebInspector.Color([rgba[0]/255,rgba[1]/255,rgba[2]/255,rgba[3]],WebInspector.Color.Format.RGBA);}
WebInspector.Color.fromHSVA=function(hsva)
{var rgba=[];WebInspector.Color.hsva2rgba(hsva,rgba);return new WebInspector.Color(rgba,WebInspector.Color.Format.HSLA);}
WebInspector.Color.prototype={format:function()
{return this._format;},hsla:function()
{if(this._hsla)
return this._hsla;var r=this._rgba[0];var g=this._rgba[1];var b=this._rgba[2];var max=Math.max(r,g,b);var min=Math.min(r,g,b);var diff=max-min;var add=max+min;if(min===max)
var h=0;else if(r===max)
var h=((1/6*(g-b)/diff)+1)%1;else if(g===max)
var h=(1/6*(b-r)/diff)+1/3;else
var h=(1/6*(r-g)/diff)+2/3;var l=0.5*add;if(l===0)
var s=0;else if(l===1)
var s=0;else if(l<=0.5)
var s=diff/add;else
var s=diff/(2-add);this._hsla=[h,s,l,this._rgba[3]];return this._hsla;},canonicalHSLA:function()
{var hsla=this.hsla();return[Math.round(hsla[0]*360),Math.round(hsla[1]*100),Math.round(hsla[2]*100),hsla[3]];},hsva:function()
{var hsla=this.hsla();var h=hsla[0];var s=hsla[1];var l=hsla[2];s*=l<0.5?l:1-l;return[h,s!==0?2*s/(l+s):0,(l+s),hsla[3]];},hasAlpha:function()
{return this._rgba[3]!==1;},detectHEXFormat:function()
{var canBeShort=true;for(var i=0;i<4;++i){var c=Math.round(this._rgba[i]*255);if(c%17)
canBeShort=false;}
var hasAlpha=this.hasAlpha();var cf=WebInspector.Color.Format;if(canBeShort)
return hasAlpha?cf.ShortHEXA:cf.ShortHEX;return hasAlpha?cf.HEXA:cf.HEX;},asString:function(format)
{if(format===this._format&&this._originalTextIsValid)
return this._originalText;if(!format)
format=this._format;function toRgbValue(value)
{return Math.round(value*255);}
function toHexValue(value)
{var hex=Math.round(value*255).toString(16);return hex.length===1?"0"+hex:hex;}
function toShortHexValue(value)
{return(Math.round(value*255)/17).toString(16);}
switch(format){case WebInspector.Color.Format.Original:return this._originalText;case WebInspector.Color.Format.RGB:if(this.hasAlpha())
return null;return String.sprintf("rgb(%d, %d, %d)",toRgbValue(this._rgba[0]),toRgbValue(this._rgba[1]),toRgbValue(this._rgba[2]));case WebInspector.Color.Format.RGBA:return String.sprintf("rgba(%d, %d, %d, %f)",toRgbValue(this._rgba[0]),toRgbValue(this._rgba[1]),toRgbValue(this._rgba[2]),this._rgba[3]);case WebInspector.Color.Format.HSL:if(this.hasAlpha())
return null;var hsl=this.hsla();return String.sprintf("hsl(%d, %d%, %d%)",Math.round(hsl[0]*360),Math.round(hsl[1]*100),Math.round(hsl[2]*100));case WebInspector.Color.Format.HSLA:var hsla=this.hsla();return String.sprintf("hsla(%d, %d%, %d%, %f)",Math.round(hsla[0]*360),Math.round(hsla[1]*100),Math.round(hsla[2]*100),hsla[3]);case WebInspector.Color.Format.HEXA:return String.sprintf("#%s%s%s%s",toHexValue(this._rgba[0]),toHexValue(this._rgba[1]),toHexValue(this._rgba[2]),toHexValue(this._rgba[3])).toLowerCase();case WebInspector.Color.Format.HEX:if(this.hasAlpha())
return null;return String.sprintf("#%s%s%s",toHexValue(this._rgba[0]),toHexValue(this._rgba[1]),toHexValue(this._rgba[2])).toLowerCase();case WebInspector.Color.Format.ShortHEXA:var hexFormat=this.detectHEXFormat();if(hexFormat!==WebInspector.Color.Format.ShortHEXA&&hexFormat!==WebInspector.Color.Format.ShortHEX)
return null;return String.sprintf("#%s%s%s%s",toShortHexValue(this._rgba[0]),toShortHexValue(this._rgba[1]),toShortHexValue(this._rgba[2]),toShortHexValue(this._rgba[3])).toLowerCase();case WebInspector.Color.Format.ShortHEX:if(this.detectHEXFormat()!==WebInspector.Color.Format.ShortHEX)
return null;return String.sprintf("#%s%s%s",toShortHexValue(this._rgba[0]),toShortHexValue(this._rgba[1]),toShortHexValue(this._rgba[2])).toLowerCase();case WebInspector.Color.Format.Nickname:return this.nickname();}
return this._originalText;},rgba:function()
{return this._rgba.slice();},canonicalRGBA:function()
{var rgba=new Array(4);for(var i=0;i<3;++i)
rgba[i]=Math.round(this._rgba[i]*255);rgba[3]=this._rgba[3];return rgba;},nickname:function()
{if(!WebInspector.Color._rgbaToNickname){WebInspector.Color._rgbaToNickname={};for(var nickname in WebInspector.Color.Nicknames){var rgba=WebInspector.Color.Nicknames[nickname];if(rgba.length!==4)
rgba=rgba.concat(1);WebInspector.Color._rgbaToNickname[rgba]=nickname;}}
return WebInspector.Color._rgbaToNickname[this.canonicalRGBA()]||null;},toProtocolRGBA:function()
{var rgba=this.canonicalRGBA();var result={r:rgba[0],g:rgba[1],b:rgba[2]};if(rgba[3]!==1)
result.a=rgba[3];return result;},invert:function()
{var rgba=[];rgba[0]=1-this._rgba[0];rgba[1]=1-this._rgba[1];rgba[2]=1-this._rgba[2];rgba[3]=this._rgba[3];return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA);},setAlpha:function(alpha)
{var rgba=this._rgba.slice();rgba[3]=alpha;return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA);}}
WebInspector.Color._parseRgbNumeric=function(value)
{var parsed=parseInt(value,10);if(value.indexOf("%")!==-1)
parsed/=100;else
parsed/=255;return parsed;}
WebInspector.Color._parseHueNumeric=function(value)
{return isNaN(value)?0:(parseFloat(value)/360)%1;}
WebInspector.Color._parseSatLightNumeric=function(value)
{return Math.min(1,parseFloat(value)/100);}
WebInspector.Color._parseAlphaNumeric=function(value)
{return isNaN(value)?0:parseFloat(value);}
WebInspector.Color._hsva2hsla=function(hsva,out_hsla)
{var h=hsva[0];var s=hsva[1];var v=hsva[2];var t=(2-s)*v;if(v===0||s===0)
s=0;else
s*=v/(t<1?t:2-t);out_hsla[0]=h;out_hsla[1]=s;out_hsla[2]=t/2;out_hsla[3]=hsva[3];}
WebInspector.Color.hsl2rgb=function(hsl,out_rgb)
{var h=hsl[0];var s=hsl[1];var l=hsl[2];function hue2rgb(p,q,h)
{if(h<0)
h+=1;else if(h>1)
h-=1;if((h*6)<1)
return p+(q-p)*h*6;else if((h*2)<1)
return q;else if((h*3)<2)
return p+(q-p)*((2/3)-h)*6;else
return p;}
if(s<0)
s=0;if(l<=0.5)
var q=l*(1+s);else
var q=l+s-(l*s);var p=2*l-q;var tr=h+(1/3);var tg=h;var tb=h-(1/3);out_rgb[0]=hue2rgb(p,q,tr);out_rgb[1]=hue2rgb(p,q,tg);out_rgb[2]=hue2rgb(p,q,tb);out_rgb[3]=hsl[3];}
WebInspector.Color.hsva2rgba=function(hsva,out_rgba)
{WebInspector.Color._hsva2hsla(hsva,WebInspector.Color.hsva2rgba._tmpHSLA);WebInspector.Color.hsl2rgb(WebInspector.Color.hsva2rgba._tmpHSLA,out_rgba);for(var i=0;i<WebInspector.Color.hsva2rgba._tmpHSLA.length;i++)
WebInspector.Color.hsva2rgba._tmpHSLA[i]=0;};WebInspector.Color.hsva2rgba._tmpHSLA=[0,0,0,0];WebInspector.Color.luminance=function(rgba)
{var rSRGB=rgba[0];var gSRGB=rgba[1];var bSRGB=rgba[2];var r=rSRGB<=0.03928?rSRGB/12.92:Math.pow(((rSRGB+0.055)/1.055),2.4);var g=gSRGB<=0.03928?gSRGB/12.92:Math.pow(((gSRGB+0.055)/1.055),2.4);var b=bSRGB<=0.03928?bSRGB/12.92:Math.pow(((bSRGB+0.055)/1.055),2.4);return 0.2126*r+0.7152*g+0.0722*b;}
WebInspector.Color.blendColors=function(fgRGBA,bgRGBA,out_blended)
{var alpha=fgRGBA[3];out_blended[0]=((1-alpha)*bgRGBA[0])+(alpha*fgRGBA[0]);out_blended[1]=((1-alpha)*bgRGBA[1])+(alpha*fgRGBA[1]);out_blended[2]=((1-alpha)*bgRGBA[2])+(alpha*fgRGBA[2]);out_blended[3]=alpha+(bgRGBA[3]*(1-alpha));}
WebInspector.Color.calculateContrastRatio=function(fgRGBA,bgRGBA)
{WebInspector.Color.blendColors(fgRGBA,bgRGBA,WebInspector.Color.calculateContrastRatio._blendedFg);var fgLuminance=WebInspector.Color.luminance(WebInspector.Color.calculateContrastRatio._blendedFg);var bgLuminance=WebInspector.Color.luminance(bgRGBA);var contrastRatio=(Math.max(fgLuminance,bgLuminance)+0.05)/(Math.min(fgLuminance,bgLuminance)+0.05);for(var i=0;i<WebInspector.Color.calculateContrastRatio._blendedFg.length;i++)
WebInspector.Color.calculateContrastRatio._blendedFg[i]=0;return contrastRatio;}
WebInspector.Color.calculateContrastRatio._blendedFg=[0,0,0,0];WebInspector.Color.desiredLuminance=function(luminance,contrast,lighter)
{function computeLuminance()
{if(lighter)
return(luminance+0.05)*contrast-0.05;else
return(luminance+0.05)/contrast-0.05;}
var desiredLuminance=computeLuminance();if(desiredLuminance<0||desiredLuminance>1){lighter=!lighter;desiredLuminance=computeLuminance();}
return desiredLuminance;};WebInspector.Color.Nicknames={"aliceblue":[240,248,255],"antiquewhite":[250,235,215],"aqua":[0,255,255],"aquamarine":[127,255,212],"azure":[240,255,255],"beige":[245,245,220],"bisque":[255,228,196],"black":[0,0,0],"blanchedalmond":[255,235,205],"blue":[0,0,255],"blueviolet":[138,43,226],"brown":[165,42,42],"burlywood":[222,184,135],"cadetblue":[95,158,160],"chartreuse":[127,255,0],"chocolate":[210,105,30],"coral":[255,127,80],"cornflowerblue":[100,149,237],"cornsilk":[255,248,220],"crimson":[237,20,61],"cyan":[0,255,255],"darkblue":[0,0,139],"darkcyan":[0,139,139],"darkgoldenrod":[184,134,11],"darkgray":[169,169,169],"darkgrey":[169,169,169],"darkgreen":[0,100,0],"darkkhaki":[189,183,107],"darkmagenta":[139,0,139],"darkolivegreen":[85,107,47],"darkorange":[255,140,0],"darkorchid":[153,50,204],"darkred":[139,0,0],"darksalmon":[233,150,122],"darkseagreen":[143,188,143],"darkslateblue":[72,61,139],"darkslategray":[47,79,79],"darkslategrey":[47,79,79],"darkturquoise":[0,206,209],"darkviolet":[148,0,211],"deeppink":[255,20,147],"deepskyblue":[0,191,255],"dimgray":[105,105,105],"dimgrey":[105,105,105],"dodgerblue":[30,144,255],"firebrick":[178,34,34],"floralwhite":[255,250,240],"forestgreen":[34,139,34],"fuchsia":[255,0,255],"gainsboro":[220,220,220],"ghostwhite":[248,248,255],"gold":[255,215,0],"goldenrod":[218,165,32],"gray":[128,128,128],"grey":[128,128,128],"green":[0,128,0],"greenyellow":[173,255,47],"honeydew":[240,255,240],"hotpink":[255,105,180],"indianred":[205,92,92],"indigo":[75,0,130],"ivory":[255,255,240],"khaki":[240,230,140],"lavender":[230,230,250],"lavenderblush":[255,240,245],"lawngreen":[124,252,0],"lemonchiffon":[255,250,205],"lightblue":[173,216,230],"lightcoral":[240,128,128],"lightcyan":[224,255,255],"lightgoldenrodyellow":[250,250,210],"lightgreen":[144,238,144],"lightgray":[211,211,211],"lightgrey":[211,211,211],"lightpink":[255,182,193],"lightsalmon":[255,160,122],"lightseagreen":[32,178,170],"lightskyblue":[135,206,250],"lightslategray":[119,136,153],"lightslategrey":[119,136,153],"lightsteelblue":[176,196,222],"lightyellow":[255,255,224],"lime":[0,255,0],"limegreen":[50,205,50],"linen":[250,240,230],"magenta":[255,0,255],"maroon":[128,0,0],"mediumaquamarine":[102,205,170],"mediumblue":[0,0,205],"mediumorchid":[186,85,211],"mediumpurple":[147,112,219],"mediumseagreen":[60,179,113],"mediumslateblue":[123,104,238],"mediumspringgreen":[0,250,154],"mediumturquoise":[72,209,204],"mediumvioletred":[199,21,133],"midnightblue":[25,25,112],"mintcream":[245,255,250],"mistyrose":[255,228,225],"moccasin":[255,228,181],"navajowhite":[255,222,173],"navy":[0,0,128],"oldlace":[253,245,230],"olive":[128,128,0],"olivedrab":[107,142,35],"orange":[255,165,0],"orangered":[255,69,0],"orchid":[218,112,214],"palegoldenrod":[238,232,170],"palegreen":[152,251,152],"paleturquoise":[175,238,238],"palevioletred":[219,112,147],"papayawhip":[255,239,213],"peachpuff":[255,218,185],"peru":[205,133,63],"pink":[255,192,203],"plum":[221,160,221],"powderblue":[176,224,230],"purple":[128,0,128],"rebeccapurple":[102,51,153],"red":[255,0,0],"rosybrown":[188,143,143],"royalblue":[65,105,225],"saddlebrown":[139,69,19],"salmon":[250,128,114],"sandybrown":[244,164,96],"seagreen":[46,139,87],"seashell":[255,245,238],"sienna":[160,82,45],"silver":[192,192,192],"skyblue":[135,206,235],"slateblue":[106,90,205],"slategray":[112,128,144],"slategrey":[112,128,144],"snow":[255,250,250],"springgreen":[0,255,127],"steelblue":[70,130,180],"tan":[210,180,140],"teal":[0,128,128],"thistle":[216,191,216],"tomato":[255,99,71],"turquoise":[64,224,208],"violet":[238,130,238],"wheat":[245,222,179],"white":[255,255,255],"whitesmoke":[245,245,245],"yellow":[255,255,0],"yellowgreen":[154,205,50],"transparent":[0,0,0,0],};WebInspector.Color.PageHighlight={Content:WebInspector.Color.fromRGBA([111,168,220,.66]),ContentLight:WebInspector.Color.fromRGBA([111,168,220,.5]),ContentOutline:WebInspector.Color.fromRGBA([9,83,148]),Padding:WebInspector.Color.fromRGBA([147,196,125,.55]),PaddingLight:WebInspector.Color.fromRGBA([147,196,125,.4]),Border:WebInspector.Color.fromRGBA([255,229,153,.66]),BorderLight:WebInspector.Color.fromRGBA([255,229,153,.5]),Margin:WebInspector.Color.fromRGBA([246,178,107,.66]),MarginLight:WebInspector.Color.fromRGBA([246,178,107,.5]),EventTarget:WebInspector.Color.fromRGBA([255,196,196,.66]),Shape:WebInspector.Color.fromRGBA([96,82,177,0.8]),ShapeMargin:WebInspector.Color.fromRGBA([96,82,127,.6])}
WebInspector.Color.detectColorFormat=function(color)
{const cf=WebInspector.Color.Format;var format;var formatSetting=WebInspector.moduleSetting("colorFormat").get();if(formatSetting===cf.Original)
format=cf.Original;else if(formatSetting===cf.RGB)
format=(color.hasAlpha()?cf.RGBA:cf.RGB);else if(formatSetting===cf.HSL)
format=(color.hasAlpha()?cf.HSLA:cf.HSL);else if(formatSetting===cf.HEX)
format=color.detectHEXFormat();else
format=cf.RGBA;return format;};WebInspector.Geometry={};WebInspector.Geometry._Eps=1e-5;WebInspector.Geometry.Vector=function(x,y,z)
{this.x=x;this.y=y;this.z=z;}
WebInspector.Geometry.Vector.prototype={length:function()
{return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);},normalize:function()
{var length=this.length();if(length<=WebInspector.Geometry._Eps)
return;this.x/=length;this.y/=length;this.z/=length;}}
WebInspector.Geometry.Point=function(x,y){this.x=x;this.y=y;}
WebInspector.Geometry.Point.prototype={distanceTo:function(p)
{return Math.sqrt(Math.pow(p.x-this.x,2)+Math.pow(p.y-this.y,2));},toString:function()
{return Math.round(this.x*100)/100+", "+Math.round(this.y*100)/100;}}
WebInspector.Geometry.CubicBezier=function(point1,point2)
{this.controlPoints=[point1,point2];}
WebInspector.Geometry.CubicBezier.KeywordValues={"linear":"cubic-bezier(0, 0, 1, 1)","ease":"cubic-bezier(0.25, 0.1, 0.25, 1)","ease-in":"cubic-bezier(0.42, 0, 1, 1)","ease-in-out":"cubic-bezier(0.42, 0, 0.58, 1)","ease-out":"cubic-bezier(0, 0, 0.58, 1)"}
WebInspector.Geometry.CubicBezier.parse=function(text)
{var keywordValues=WebInspector.Geometry.CubicBezier.KeywordValues;var value=text.toLowerCase().replace(/\s+/g,"");if(Object.keys(keywordValues).indexOf(value)!=-1)
return WebInspector.Geometry.CubicBezier.parse(keywordValues[value]);var bezierRegex=/^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;var match=value.match(bezierRegex);if(match){var control1=new WebInspector.Geometry.Point(parseFloat(match[1]),parseFloat(match[2]));var control2=new WebInspector.Geometry.Point(parseFloat(match[3]),parseFloat(match[4]));return new WebInspector.Geometry.CubicBezier(control1,control2);}
return null;}
WebInspector.Geometry.CubicBezier.prototype={evaluateAt:function(t)
{function evaluate(v1,v2,t)
{return 3*(1-t)*(1-t)*t*v1+3*(1-t)*t*t*v2+Math.pow(t,3);}
var x=evaluate(this.controlPoints[0].x,this.controlPoints[1].x,t);var y=evaluate(this.controlPoints[0].y,this.controlPoints[1].y,t);return new WebInspector.Geometry.Point(x,y);},asCSSText:function()
{var raw="cubic-bezier("+this.controlPoints.join(", ")+")";var keywordValues=WebInspector.Geometry.CubicBezier.KeywordValues;for(var keyword in keywordValues){if(raw===keywordValues[keyword])
return keyword;}
return raw;}}
WebInspector.Geometry.EulerAngles=function(alpha,beta,gamma)
{this.alpha=alpha;this.beta=beta;this.gamma=gamma;}
WebInspector.Geometry.EulerAngles.fromRotationMatrix=function(rotationMatrix)
{var beta=Math.atan2(rotationMatrix.m23,rotationMatrix.m33);var gamma=Math.atan2(-rotationMatrix.m13,Math.sqrt(rotationMatrix.m11*rotationMatrix.m11+rotationMatrix.m12*rotationMatrix.m12));var alpha=Math.atan2(rotationMatrix.m12,rotationMatrix.m11);return new WebInspector.Geometry.EulerAngles(WebInspector.Geometry.radiansToDegrees(alpha),WebInspector.Geometry.radiansToDegrees(beta),WebInspector.Geometry.radiansToDegrees(gamma));}
WebInspector.Geometry.EulerAngles.prototype={toRotate3DString:function()
{var gammaAxisY=-Math.sin(WebInspector.Geometry.degreesToRadians(this.beta));var gammaAxisZ=Math.cos(WebInspector.Geometry.degreesToRadians(this.beta));var axis={alpha:[0,1,0],beta:[-1,0,0],gamma:[0,gammaAxisY,gammaAxisZ]};return"rotate3d("+axis.alpha.join(",")+","+this.alpha+"deg) "
+"rotate3d("+axis.beta.join(",")+","+this.beta+"deg) "
+"rotate3d("+axis.gamma.join(",")+","+this.gamma+"deg)";}}
WebInspector.Geometry.scalarProduct=function(u,v)
{return u.x*v.x+u.y*v.y+u.z*v.z;}
WebInspector.Geometry.crossProduct=function(u,v)
{var x=u.y*v.z-u.z*v.y;var y=u.z*v.x-u.x*v.z;var z=u.x*v.y-u.y*v.x;return new WebInspector.Geometry.Vector(x,y,z);}
WebInspector.Geometry.subtract=function(u,v)
{var x=u.x-v.x;var y=u.y-v.y;var z=u.z-v.z;return new WebInspector.Geometry.Vector(x,y,z);}
WebInspector.Geometry.multiplyVectorByMatrixAndNormalize=function(v,m)
{var t=v.x*m.m14+v.y*m.m24+v.z*m.m34+m.m44;var x=(v.x*m.m11+v.y*m.m21+v.z*m.m31+m.m41)/t;var y=(v.x*m.m12+v.y*m.m22+v.z*m.m32+m.m42)/t;var z=(v.x*m.m13+v.y*m.m23+v.z*m.m33+m.m43)/t;return new WebInspector.Geometry.Vector(x,y,z);}
WebInspector.Geometry.calculateAngle=function(u,v)
{var uLength=u.length();var vLength=v.length();if(uLength<=WebInspector.Geometry._Eps||vLength<=WebInspector.Geometry._Eps)
return 0;var cos=WebInspector.Geometry.scalarProduct(u,v)/uLength/vLength;if(Math.abs(cos)>1)
return 0;return WebInspector.Geometry.radiansToDegrees(Math.acos(cos));}
WebInspector.Geometry.degreesToRadians=function(deg)
{return deg*Math.PI/180;}
WebInspector.Geometry.radiansToDegrees=function(rad)
{return rad*180/Math.PI;}
WebInspector.Geometry.boundsForTransformedPoints=function(matrix,points,aggregateBounds)
{if(!aggregateBounds)
aggregateBounds={minX:Infinity,maxX:-Infinity,minY:Infinity,maxY:-Infinity};if(points.length%3)
console.assert("Invalid size of points array");for(var p=0;p<points.length;p+=3){var vector=new WebInspector.Geometry.Vector(points[p],points[p+1],points[p+2]);vector=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(vector,matrix);aggregateBounds.minX=Math.min(aggregateBounds.minX,vector.x);aggregateBounds.maxX=Math.max(aggregateBounds.maxX,vector.x);aggregateBounds.minY=Math.min(aggregateBounds.minY,vector.y);aggregateBounds.maxY=Math.max(aggregateBounds.maxY,vector.y);}
return aggregateBounds;}
function Size(width,height)
{this.width=width;this.height=height;}
Size.prototype.isEqual=function(size)
{return!!size&&this.width===size.width&&this.height===size.height;};Size.prototype.widthToMax=function(size)
{return new Size(Math.max(this.width,(typeof size==="number"?size:size.width)),this.height);};Size.prototype.addWidth=function(size)
{return new Size(this.width+(typeof size==="number"?size:size.width),this.height);};Size.prototype.heightToMax=function(size)
{return new Size(this.width,Math.max(this.height,(typeof size==="number"?size:size.height)));};Size.prototype.addHeight=function(size)
{return new Size(this.width,this.height+(typeof size==="number"?size:size.height));};function Insets(left,top,right,bottom)
{this.left=left;this.top=top;this.right=right;this.bottom=bottom;}
Insets.prototype={isEqual:function(insets)
{return!!insets&&this.left===insets.left&&this.top===insets.top&&this.right==insets.right&&this.bottom==insets.bottom;}}
WebInspector.Rect=function(left,top,width,height)
{this.left=left;this.top=top;this.width=width;this.height=height;}
WebInspector.Rect.prototype={isEqual:function(rect)
{return!!rect&&this.left===rect.left&&this.top===rect.top&&this.width==rect.width&&this.height==rect.height;},scale:function(scale)
{return new WebInspector.Rect(this.left*scale,this.top*scale,this.width*scale,this.height*scale);},size:function()
{return new Size(this.width,this.height);}}
function Constraints(minimum,preferred)
{this.minimum=minimum||new Size(0,0);this.preferred=preferred||this.minimum;if(this.minimum.width>this.preferred.width||this.minimum.height>this.preferred.height)
throw new Error("Minimum size is greater than preferred.");}
Constraints.prototype.isEqual=function(constraints)
{return!!constraints&&this.minimum.isEqual(constraints.minimum)&&this.preferred.isEqual(constraints.preferred);}
Constraints.prototype.widthToMax=function(value)
{if(typeof value==="number")
return new Constraints(this.minimum.widthToMax(value),this.preferred.widthToMax(value));return new Constraints(this.minimum.widthToMax(value.minimum),this.preferred.widthToMax(value.preferred));}
Constraints.prototype.addWidth=function(value)
{if(typeof value==="number")
return new Constraints(this.minimum.addWidth(value),this.preferred.addWidth(value));return new Constraints(this.minimum.addWidth(value.minimum),this.preferred.addWidth(value.preferred));}
Constraints.prototype.heightToMax=function(value)
{if(typeof value==="number")
return new Constraints(this.minimum.heightToMax(value),this.preferred.heightToMax(value));return new Constraints(this.minimum.heightToMax(value.minimum),this.preferred.heightToMax(value.preferred));}
Constraints.prototype.addHeight=function(value)
{if(typeof value==="number")
return new Constraints(this.minimum.addHeight(value),this.preferred.addHeight(value));return new Constraints(this.minimum.addHeight(value.minimum),this.preferred.addHeight(value.preferred));};WebInspector.Console=function()
{this._messages=[];}
WebInspector.Console.Events={MessageAdded:"messageAdded"}
WebInspector.Console.MessageLevel={Log:"log",Warning:"warning",Error:"error"}
WebInspector.Console.Message=function(text,level,timestamp,show)
{this.text=text;this.level=level;this.timestamp=(typeof timestamp==="number")?timestamp:Date.now();this.show=show;}
WebInspector.Console.UIDelegate=function()
{}
WebInspector.Console.UIDelegate.prototype={showConsole:function(){}}
WebInspector.Console.prototype={setUIDelegate:function(uiDelegate)
{this._uiDelegate=uiDelegate;},addMessage:function(text,level,show)
{var message=new WebInspector.Console.Message(text,level||WebInspector.Console.MessageLevel.Log,Date.now(),show||false);this._messages.push(message);this.dispatchEventToListeners(WebInspector.Console.Events.MessageAdded,message);},log:function(text)
{this.addMessage(text,WebInspector.Console.MessageLevel.Log);},warn:function(text)
{this.addMessage(text,WebInspector.Console.MessageLevel.Warning);},error:function(text)
{this.addMessage(text,WebInspector.Console.MessageLevel.Error,true);},messages:function()
{return this._messages;},show:function()
{this.showPromise();},showPromise:function()
{if(this._uiDelegate)
return this._uiDelegate.showConsole();return Promise.reject();},__proto__:WebInspector.Object.prototype}
WebInspector.console=new WebInspector.Console();;WebInspector.ContentProvider=function(){}
WebInspector.ContentProvider.prototype={contentURL:function(){},contentType:function(){},requestContent:function(){},searchInContent:function(query,caseSensitive,isRegex,callback){}}
WebInspector.ContentProvider.SearchMatch=function(lineNumber,lineContent){this.lineNumber=lineNumber;this.lineContent=lineContent;}
WebInspector.ContentProvider.performSearchInContent=function(content,query,caseSensitive,isRegex)
{var regex=createSearchRegex(query,caseSensitive,isRegex);var text=new WebInspector.Text(content);var result=[];for(var i=0;i<text.lineCount();++i){var lineContent=text.lineAt(i);regex.lastIndex=0;if(regex.exec(lineContent))
result.push(new WebInspector.ContentProvider.SearchMatch(i,lineContent));}
return result;};WebInspector.ParsedURL=function(url)
{this.isValid=false;this.url=url;this.scheme="";this.host="";this.port="";this.path="";this.queryParams="";this.fragment="";this.folderPathComponents="";this.lastPathComponent="";var match=url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\s\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);if(match){this.isValid=true;this.scheme=match[1].toLowerCase();this.host=match[2];this.port=match[3];this.path=match[4]||"/";this.fragment=match[5];}else{if(this.url.startsWith("data:")){this.scheme="data";return;}
if(this.url==="about:blank"){this.scheme="about";return;}
this.path=this.url;}
var path=this.path;var indexOfQuery=path.indexOf("?");if(indexOfQuery!==-1){this.queryParams=path.substring(indexOfQuery+1);path=path.substring(0,indexOfQuery);}
var lastSlashIndex=path.lastIndexOf("/");if(lastSlashIndex!==-1){this.folderPathComponents=path.substring(0,lastSlashIndex);this.lastPathComponent=path.substring(lastSlashIndex+1);}else
this.lastPathComponent=path;}
WebInspector.ParsedURL.splitURLIntoPathComponents=function(url)
{if(url.startsWith("/"))
url="file://"+url;var parsedURL=new WebInspector.ParsedURL(url);var origin;var folderPath;var name;if(parsedURL.isValid){origin=parsedURL.scheme+"://"+parsedURL.host;if(parsedURL.port)
origin+=":"+parsedURL.port;folderPath=parsedURL.folderPathComponents;name=parsedURL.lastPathComponent;if(parsedURL.queryParams)
name+="?"+parsedURL.queryParams;}else{origin="";folderPath="";name=url;}
var result=[origin];var splittedPath=folderPath.split("/");for(var i=1;i<splittedPath.length;++i){if(!splittedPath[i])
continue;result.push(splittedPath[i]);}
result.push(name);return result;}
WebInspector.ParsedURL.extractOrigin=function(url)
{var parsedURL=new WebInspector.ParsedURL(url);if(!parsedURL.isValid)
return"";var origin=parsedURL.scheme+"://"+parsedURL.host;if(parsedURL.port)
origin+=":"+parsedURL.port;return origin;}
WebInspector.ParsedURL.extractExtension=function(url)
{var lastIndexOfDot=url.lastIndexOf(".");var extension=lastIndexOfDot!==-1?url.substr(lastIndexOfDot+1):"";var indexOfQuestionMark=extension.indexOf("?");if(indexOfQuestionMark!==-1)
extension=extension.substr(0,indexOfQuestionMark);return extension;}
WebInspector.ParsedURL.extractName=function(url)
{var index=url.lastIndexOf("/");return index!==-1?url.substr(index+1):url;}
WebInspector.ParsedURL.completeURL=function(baseURL,href)
{if(href){var trimmedHref=href.trim();if(trimmedHref.startsWith("data:")||trimmedHref.startsWith("blob:")||trimmedHref.startsWith("javascript:"))
return href;var parsedHref=trimmedHref.asParsedURL();if(parsedHref&&parsedHref.scheme)
return trimmedHref;}else{return baseURL;}
var parsedURL=baseURL.asParsedURL();if(parsedURL){if(parsedURL.isDataURL())
return href;var path=href;var query=path.indexOf("?");var postfix="";if(query!==-1){postfix=path.substring(query);path=path.substring(0,query);}else{var fragment=path.indexOf("#");if(fragment!==-1){postfix=path.substring(fragment);path=path.substring(0,fragment);}}
if(!path){var basePath=parsedURL.path;if(postfix.charAt(0)==="?"){var baseQuery=parsedURL.path.indexOf("?");if(baseQuery!==-1)
basePath=basePath.substring(0,baseQuery);}
return parsedURL.scheme+"://"+parsedURL.host+(parsedURL.port?(":"+parsedURL.port):"")+basePath+postfix;}else if(path.charAt(0)!=="/"){var prefix=parsedURL.path;var prefixQuery=prefix.indexOf("?");if(prefixQuery!==-1)
prefix=prefix.substring(0,prefixQuery);prefix=prefix.substring(0,prefix.lastIndexOf("/"))+"/";path=prefix+path;}else if(path.length>1&&path.charAt(1)==="/"){return parsedURL.scheme+":"+path+postfix;}
return parsedURL.scheme+"://"+parsedURL.host+(parsedURL.port?(":"+parsedURL.port):"")+normalizePath(path)+postfix;}
return null;}
WebInspector.ParsedURL.prototype={get displayName()
{if(this._displayName)
return this._displayName;if(this.isDataURL())
return this.dataURLDisplayName();if(this.isAboutBlank())
return this.url;this._displayName=this.lastPathComponent;if(!this._displayName)
this._displayName=(this.host||"")+"/";if(this._displayName==="/")
this._displayName=this.url;return this._displayName;},dataURLDisplayName:function()
{if(this._dataURLDisplayName)
return this._dataURLDisplayName;if(!this.isDataURL())
return"";this._dataURLDisplayName=this.url.trimEnd(20);return this._dataURLDisplayName;},isAboutBlank:function()
{return this.url==="about:blank";},isDataURL:function()
{return this.scheme==="data";},lastPathComponentWithFragment:function()
{return this.lastPathComponent+(this.fragment?"#"+this.fragment:"");},domain:function()
{if(this.isDataURL())
return"data:";return this.host+(this.port?":"+this.port:"");},securityOrigin:function()
{if(this.isDataURL())
return"data:";return this.scheme+"://"+this.domain();},urlWithoutScheme:function()
{if(this.scheme&&this.url.startsWith(this.scheme+"://"))
return this.url.substring(this.scheme.length+3);return this.url;},}
WebInspector.ParsedURL.splitLineAndColumn=function(string)
{var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(string);var lineNumber;var columnNumber;console.assert(lineColumnMatch);if(typeof(lineColumnMatch[1])==="string"){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
if(typeof(lineColumnMatch[2])==="string"){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
return{url:string.substring(0,string.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
WebInspector.ParsedURL.isRelativeURL=function(url)
{return!(/^[A-Za-z][A-Za-z0-9+.-]*:/.test(url));}
String.prototype.asParsedURL=function()
{var parsedURL=new WebInspector.ParsedURL(this.toString());if(parsedURL.isValid)
return parsedURL;return null;};WebInspector.Progress=function()
{}
WebInspector.Progress.prototype={setTotalWork:function(totalWork){},setTitle:function(title){},setWorked:function(worked,title){},worked:function(worked){},done:function(){},isCanceled:function(){return false;},}
WebInspector.CompositeProgress=function(parent)
{this._parent=parent;this._children=[];this._childrenDone=0;this._parent.setTotalWork(1);this._parent.setWorked(0);}
WebInspector.CompositeProgress.prototype={_childDone:function()
{if(++this._childrenDone!==this._children.length)
return;this._parent.done();},createSubProgress:function(weight)
{var child=new WebInspector.SubProgress(this,weight);this._children.push(child);return child;},_update:function()
{var totalWeights=0;var done=0;for(var i=0;i<this._children.length;++i){var child=this._children[i];if(child._totalWork)
done+=child._weight*child._worked/child._totalWork;totalWeights+=child._weight;}
this._parent.setWorked(done/totalWeights);}}
WebInspector.SubProgress=function(composite,weight)
{this._composite=composite;this._weight=weight||1;this._worked=0;}
WebInspector.SubProgress.prototype={isCanceled:function()
{return this._composite._parent.isCanceled();},setTitle:function(title)
{this._composite._parent.setTitle(title);},done:function()
{this.setWorked(this._totalWork);this._composite._childDone();},setTotalWork:function(totalWork)
{this._totalWork=totalWork;this._composite._update();},setWorked:function(worked,title)
{this._worked=worked;if(typeof title!=="undefined")
this.setTitle(title);this._composite._update();},worked:function(worked)
{this.setWorked(this._worked+(worked||1));}}
WebInspector.ProgressProxy=function(delegate,doneCallback)
{this._delegate=delegate;this._doneCallback=doneCallback;}
WebInspector.ProgressProxy.prototype={isCanceled:function()
{return this._delegate?this._delegate.isCanceled():false;},setTitle:function(title)
{if(this._delegate)
this._delegate.setTitle(title);},done:function()
{if(this._delegate)
this._delegate.done();if(this._doneCallback)
this._doneCallback();},setTotalWork:function(totalWork)
{if(this._delegate)
this._delegate.setTotalWork(totalWork);},setWorked:function(worked,title)
{if(this._delegate)
this._delegate.setWorked(worked,title);},worked:function(worked)
{if(this._delegate)
this._delegate.worked(worked);}};WebInspector.ResourceType=function(name,title,category,isTextType)
{this._name=name;this._title=title;this._category=category;this._isTextType=isTextType;}
WebInspector.ResourceType.prototype={name:function()
{return this._name;},title:function()
{return this._title;},category:function()
{return this._category;},isTextType:function()
{return this._isTextType;},isScript:function()
{return this._name==="script"||this._name==="sm-script";},hasScripts:function()
{return this.isScript()||this.isDocument();},isStyleSheet:function()
{return this._name==="stylesheet"||this._name==="sm-stylesheet";},isDocument:function()
{return this._name==="document";},isDocumentOrScriptOrStyleSheet:function()
{return this.isDocument()||this.isScript()||this.isStyleSheet();},isFromSourceMap:function()
{return this._name.startsWith("sm-");},toString:function()
{return this._name;},canonicalMimeType:function()
{if(this.isDocument())
return"text/html";if(this.isScript())
return"text/javascript";if(this.isStyleSheet())
return"text/css";return"";}}
WebInspector.ResourceCategory=function(title,shortTitle)
{this.title=title;this.shortTitle=shortTitle;}
WebInspector.resourceCategories={XHR:new WebInspector.ResourceCategory("XHR and Fetch","XHR"),Script:new WebInspector.ResourceCategory("Scripts","JS"),Stylesheet:new WebInspector.ResourceCategory("Stylesheets","CSS"),Image:new WebInspector.ResourceCategory("Images","Img"),Media:new WebInspector.ResourceCategory("Media","Media"),Font:new WebInspector.ResourceCategory("Fonts","Font"),Document:new WebInspector.ResourceCategory("Documents","Doc"),WebSocket:new WebInspector.ResourceCategory("WebSockets","WS"),Manifest:new WebInspector.ResourceCategory("Manifest","Manifest"),Other:new WebInspector.ResourceCategory("Other","Other")}
WebInspector.resourceTypes={XHR:new WebInspector.ResourceType("xhr","XHR",WebInspector.resourceCategories.XHR,true),Fetch:new WebInspector.ResourceType("fetch","Fetch",WebInspector.resourceCategories.XHR,true),EventSource:new WebInspector.ResourceType("eventsource","EventSource",WebInspector.resourceCategories.XHR,true),Script:new WebInspector.ResourceType("script","Script",WebInspector.resourceCategories.Script,true),Stylesheet:new WebInspector.ResourceType("stylesheet","Stylesheet",WebInspector.resourceCategories.Stylesheet,true),Image:new WebInspector.ResourceType("image","Image",WebInspector.resourceCategories.Image,false),Media:new WebInspector.ResourceType("media","Media",WebInspector.resourceCategories.Media,false),Font:new WebInspector.ResourceType("font","Font",WebInspector.resourceCategories.Font,false),Document:new WebInspector.ResourceType("document","Document",WebInspector.resourceCategories.Document,true),TextTrack:new WebInspector.ResourceType("texttrack","TextTrack",WebInspector.resourceCategories.Other,true),WebSocket:new WebInspector.ResourceType("websocket","WebSocket",WebInspector.resourceCategories.WebSocket,false),Other:new WebInspector.ResourceType("other","Other",WebInspector.resourceCategories.Other,false),SourceMapScript:new WebInspector.ResourceType("sm-script","Script",WebInspector.resourceCategories.Script,false),SourceMapStyleSheet:new WebInspector.ResourceType("sm-stylesheet","Stylesheet",WebInspector.resourceCategories.Stylesheet,false),Manifest:new WebInspector.ResourceType("manifest","Manifest",WebInspector.resourceCategories.Manifest,true),}
WebInspector.ResourceType.mimeFromURL=function(url)
{var name=WebInspector.ParsedURL.extractName(url);if(WebInspector.ResourceType.mimeTypeByName[name]){return WebInspector.ResourceType.mimeTypeByName[name];}
var ext=WebInspector.ParsedURL.extractExtension(url).toLowerCase();return WebInspector.ResourceType.mimeTypeByExtension[ext];}
WebInspector.ResourceType.mimeTypeByName={"Cakefile":"text/x-coffeescript"}
WebInspector.ResourceType.mimeTypeByExtension={"js":"text/javascript","css":"text/css","html":"text/html","htm":"text/html","xml":"application/xml","xsl":"application/xml","asp":"application/x-aspx","aspx":"application/x-aspx","jsp":"application/x-jsp","c":"text/x-c++src","cc":"text/x-c++src","cpp":"text/x-c++src","h":"text/x-c++src","m":"text/x-c++src","mm":"text/x-c++src","coffee":"text/x-coffeescript","dart":"text/javascript","ts":"text/typescript","tsx":"text/typescript","json":"application/json","gyp":"application/json","gypi":"application/json","cs":"text/x-csharp","java":"text/x-java","less":"text/x-less","php":"text/x-php","phtml":"application/x-httpd-php","py":"text/x-python","sh":"text/x-sh","scss":"text/x-scss","vtt":"text/vtt","ls":"text/x-livescript","cljs":"text/x-clojure","cljc":"text/x-clojure","cljx":"text/x-clojure","styl":"text/x-styl","jsx":"text/jsx","jpeg":"image/jpeg","jpg":"image/jpeg","svg":"image/svg","gif":"image/gif","webp":"image/webp","png":"image/png","ico":"image/ico","tiff":"image/tiff","tif":"image/tif","bmp":"image/bmp","ttf":"font/opentype","otf":"font/opentype","ttc":"font/opentype","woff":"application/font-woff"};WebInspector.Settings=function(storage)
{this._settingsStorage=storage;var clearLocalStorage=window.localStorage?window.localStorage.clear.bind(window.localStorage):undefined;this._localStorage=new WebInspector.SettingsStorage(window.localStorage||{},undefined,undefined,clearLocalStorage);this._eventSupport=new WebInspector.Object();this._registry=new Map();this._moduleSettings=new Map();self.runtime.extensions("setting").forEach(this._registerModuleSetting.bind(this));}
WebInspector.Settings.prototype={_registerModuleSetting:function(extension)
{var descriptor=extension.descriptor();var settingName=descriptor["settingName"];var settingType=descriptor["settingType"];var defaultValue=descriptor["defaultValue"];var isLocal=!!descriptor["local"];var setting=settingType==="regex"?this.createRegExpSetting(settingName,defaultValue,undefined,isLocal):this.createSetting(settingName,defaultValue,isLocal);this._moduleSettings.set(settingName,setting);},moduleSetting:function(settingName)
{var setting=this._moduleSettings.get(settingName);if(!setting)
throw new Error("No setting registered: "+settingName);return setting;},settingForTest:function(settingName)
{var setting=this._registry.get(settingName);if(!setting)
throw new Error("No setting registered: "+settingName);return setting;},createSetting:function(key,defaultValue,isLocal)
{if(!this._registry.get(key))
this._registry.set(key,new WebInspector.Setting(this,key,defaultValue,this._eventSupport,isLocal?this._localStorage:this._settingsStorage));return(this._registry.get(key));},createLocalSetting:function(key,defaultValue)
{return this.createSetting(key,defaultValue,true);},createRegExpSetting:function(key,defaultValue,regexFlags,isLocal)
{if(!this._registry.get(key))
this._registry.set(key,new WebInspector.RegExpSetting(this,key,defaultValue,this._eventSupport,isLocal?this._localStorage:this._settingsStorage,regexFlags));return(this._registry.get(key));},clearAll:function()
{this._settingsStorage.removeAll();this._localStorage.removeAll();var versionSetting=WebInspector.settings.createSetting(WebInspector.VersionController._currentVersionName,0);versionSetting.set(WebInspector.VersionController.currentVersion);}}
WebInspector.SettingsStorage=function(object,setCallback,removeCallback,removeAllCallback)
{this._object=object;this._setCallback=setCallback||function(){};this._removeCallback=removeCallback||function(){};this._removeAllCallback=removeAllCallback||function(){};}
WebInspector.SettingsStorage.prototype={set:function(name,value)
{this._object[name]=value;this._setCallback(name,value);},has:function(name)
{return name in this._object;},get:function(name)
{return this._object[name];},remove:function(name)
{delete this._object[name];this._removeCallback(name);},removeAll:function()
{this._object={};this._removeAllCallback();},_dumpSizes:function()
{WebInspector.console.log("Ten largest settings: ");var sizes={__proto__:null};for(var key in this._object)
sizes[key]=this._object[key].length;var keys=Object.keys(sizes);function comparator(key1,key2)
{return sizes[key2]-sizes[key1];}
keys.sort(comparator);for(var i=0;i<10&&i<keys.length;++i)
WebInspector.console.log("Setting: '"+keys[i]+"', size: "+sizes[keys[i]]);}}
WebInspector.Setting=function(settings,name,defaultValue,eventSupport,storage)
{this._settings=settings;this._name=name;this._defaultValue=defaultValue;this._eventSupport=eventSupport;this._storage=storage;}
WebInspector.Setting.prototype={addChangeListener:function(listener,thisObject)
{this._eventSupport.addEventListener(this._name,listener,thisObject);},removeChangeListener:function(listener,thisObject)
{this._eventSupport.removeEventListener(this._name,listener,thisObject);},get name()
{return this._name;},get:function()
{if(typeof this._value!=="undefined")
return this._value;this._value=this._defaultValue;if(this._storage.has(this._name)){try{this._value=JSON.parse(this._storage.get(this._name));}catch(e){this._storage.remove(this._name);}}
return this._value;},set:function(value)
{this._value=value;try{var settingString=JSON.stringify(value);try{this._storage.set(this._name,settingString);}catch(e){this._printSettingsSavingError(e.message,this._name,settingString);}}catch(e){WebInspector.console.error("Cannot stringify setting with name: "+this._name+", error: "+e.message);}
this._eventSupport.dispatchEventToListeners(this._name,value);},remove:function()
{this._settings._registry.delete(this._name);this._settings._moduleSettings.delete(this._name);this._storage.remove(this._name);},_printSettingsSavingError:function(message,name,value)
{var errorMessage="Error saving setting with name: "+this._name+", value length: "+value.length+". Error: "+message;console.error(errorMessage);WebInspector.console.error(errorMessage);this._storage._dumpSizes();}}
WebInspector.RegExpSetting=function(settings,name,defaultValue,eventSupport,storage,regexFlags)
{WebInspector.Setting.call(this,settings,name,defaultValue?[{pattern:defaultValue}]:[],eventSupport,storage);this._regexFlags=regexFlags;}
WebInspector.RegExpSetting.prototype={get:function()
{var result=[];var items=this.getAsArray();for(var i=0;i<items.length;++i){var item=items[i];if(item.pattern&&!item.disabled)
result.push(item.pattern);}
return result.join("|");},getAsArray:function()
{return WebInspector.Setting.prototype.get.call(this);},set:function(value)
{this.setAsArray([{pattern:value}]);},setAsArray:function(value)
{delete this._regex;WebInspector.Setting.prototype.set.call(this,value);},asRegExp:function()
{if(typeof this._regex!=="undefined")
return this._regex;this._regex=null;try{var pattern=this.get();if(pattern)
this._regex=new RegExp(pattern,this._regexFlags||"");}catch(e){}
return this._regex;},__proto__:WebInspector.Setting.prototype}
WebInspector.VersionController=function()
{}
WebInspector.VersionController._currentVersionName="inspectorVersion";WebInspector.VersionController.currentVersion=18;WebInspector.VersionController.prototype={updateVersion:function()
{var localStorageVersion=window.localStorage?window.localStorage[WebInspector.VersionController._currentVersionName]:0;var versionSetting=WebInspector.settings.createSetting(WebInspector.VersionController._currentVersionName,0);var currentVersion=WebInspector.VersionController.currentVersion;var oldVersion=parseInt(localStorageVersion||"0",10)||versionSetting.get();if(oldVersion===0){versionSetting.set(currentVersion);return;}
var methodsToRun=this._methodsToRunToUpdateVersion(oldVersion,currentVersion);for(var i=0;i<methodsToRun.length;++i)
this[methodsToRun[i]].call(this);versionSetting.set(currentVersion);},_methodsToRunToUpdateVersion:function(oldVersion,currentVersion)
{var result=[];for(var i=oldVersion;i<currentVersion;++i)
result.push("_updateVersionFrom"+i+"To"+(i+1));return result;},_updateVersionFrom0To1:function()
{this._clearBreakpointsWhenTooMany(WebInspector.settings.createLocalSetting("breakpoints",[]),500000);},_updateVersionFrom1To2:function()
{WebInspector.settings.createSetting("previouslyViewedFiles",[]).set([]);},_updateVersionFrom2To3:function()
{WebInspector.settings.createSetting("fileSystemMapping",{}).set({});WebInspector.settings.createSetting("fileMappingEntries",[]).remove();},_updateVersionFrom3To4:function()
{var advancedMode=WebInspector.settings.createSetting("showHeaSnapshotObjectsHiddenProperties",false);WebInspector.moduleSetting("showAdvancedHeapSnapshotProperties").set(advancedMode.get());advancedMode.remove();},_updateVersionFrom4To5:function()
{var settingNames={"FileSystemViewSidebarWidth":"fileSystemViewSplitViewState","elementsSidebarWidth":"elementsPanelSplitViewState","StylesPaneSplitRatio":"stylesPaneSplitViewState","heapSnapshotRetainersViewSize":"heapSnapshotSplitViewState","InspectorView.splitView":"InspectorView.splitViewState","InspectorView.screencastSplitView":"InspectorView.screencastSplitViewState","Inspector.drawerSplitView":"Inspector.drawerSplitViewState","layerDetailsSplitView":"layerDetailsSplitViewState","networkSidebarWidth":"networkPanelSplitViewState","sourcesSidebarWidth":"sourcesPanelSplitViewState","scriptsPanelNavigatorSidebarWidth":"sourcesPanelNavigatorSplitViewState","sourcesPanelSplitSidebarRatio":"sourcesPanelDebuggerSidebarSplitViewState","timeline-details":"timelinePanelDetailsSplitViewState","timeline-split":"timelinePanelRecorsSplitViewState","timeline-view":"timelinePanelTimelineStackSplitViewState","auditsSidebarWidth":"auditsPanelSplitViewState","layersSidebarWidth":"layersPanelSplitViewState","profilesSidebarWidth":"profilesPanelSplitViewState","resourcesSidebarWidth":"resourcesPanelSplitViewState"};var empty={};for(var oldName in settingNames){var newName=settingNames[oldName];var oldNameH=oldName+"H";var newValue=null;var oldSetting=WebInspector.settings.createSetting(oldName,empty);if(oldSetting.get()!==empty){newValue=newValue||{};newValue.vertical={};newValue.vertical.size=oldSetting.get();oldSetting.remove();}
var oldSettingH=WebInspector.settings.createSetting(oldNameH,empty);if(oldSettingH.get()!==empty){newValue=newValue||{};newValue.horizontal={};newValue.horizontal.size=oldSettingH.get();oldSettingH.remove();}
if(newValue)
WebInspector.settings.createSetting(newName,{}).set(newValue);}},_updateVersionFrom5To6:function()
{var settingNames={"debuggerSidebarHidden":"sourcesPanelSplitViewState","navigatorHidden":"sourcesPanelNavigatorSplitViewState","WebInspector.Drawer.showOnLoad":"Inspector.drawerSplitViewState"};for(var oldName in settingNames){var oldSetting=WebInspector.settings.createSetting(oldName,null);if(oldSetting.get()===null){oldSetting.remove();continue;}
var newName=settingNames[oldName];var invert=oldName==="WebInspector.Drawer.showOnLoad";var hidden=oldSetting.get()!==invert;oldSetting.remove();var showMode=hidden?"OnlyMain":"Both";var newSetting=WebInspector.settings.createSetting(newName,{});var newValue=newSetting.get()||{};newValue.vertical=newValue.vertical||{};newValue.vertical.showMode=showMode;newValue.horizontal=newValue.horizontal||{};newValue.horizontal.showMode=showMode;newSetting.set(newValue);}},_updateVersionFrom6To7:function()
{var settingNames={"sourcesPanelNavigatorSplitViewState":"sourcesPanelNavigatorSplitViewState","elementsPanelSplitViewState":"elementsPanelSplitViewState","stylesPaneSplitViewState":"stylesPaneSplitViewState","sourcesPanelDebuggerSidebarSplitViewState":"sourcesPanelDebuggerSidebarSplitViewState"};var empty={};for(var name in settingNames){var setting=WebInspector.settings.createSetting(name,empty);var value=setting.get();if(value===empty)
continue;if(value.vertical&&value.vertical.size&&value.vertical.size<1)
value.vertical.size=0;if(value.horizontal&&value.horizontal.size&&value.horizontal.size<1)
value.horizontal.size=0;setting.set(value);}},_updateVersionFrom7To8:function()
{},_updateVersionFrom8To9:function()
{var settingNames=["skipStackFramesPattern","workspaceFolderExcludePattern"];for(var i=0;i<settingNames.length;++i){var setting=WebInspector.settings.createSetting(settingNames[i],"");var value=setting.get();if(!value)
return;if(typeof value==="string")
value=[value];for(var j=0;j<value.length;++j){if(typeof value[j]==="string")
value[j]={pattern:value[j]};}
setting.set(value);}},_updateVersionFrom9To10:function()
{if(!window.localStorage)
return;for(var key in window.localStorage){if(key.startsWith("revision-history"))
window.localStorage.removeItem(key);}},_updateVersionFrom10To11:function()
{var oldSettingName="customDevicePresets";var newSettingName="customEmulatedDeviceList";var oldSetting=WebInspector.settings.createSetting(oldSettingName,undefined);var list=oldSetting.get();if(!Array.isArray(list))
return;var newList=[];for(var i=0;i<list.length;++i){var value=list[i];var device={};device["title"]=value["title"];device["type"]="unknown";device["user-agent"]=value["userAgent"];device["capabilities"]=[];if(value["touch"])
device["capabilities"].push("touch");if(value["mobile"])
device["capabilities"].push("mobile");device["screen"]={};device["screen"]["vertical"]={width:value["width"],height:value["height"]};device["screen"]["horizontal"]={width:value["height"],height:value["width"]};device["screen"]["device-pixel-ratio"]=value["deviceScaleFactor"];device["modes"]=[];device["show-by-default"]=true;device["show"]="Default";newList.push(device);}
if(newList.length)
WebInspector.settings.createSetting(newSettingName,[]).set(newList);oldSetting.remove();},_updateVersionFrom11To12:function()
{this._migrateSettingsFromLocalStorage();},_updateVersionFrom12To13:function()
{this._migrateSettingsFromLocalStorage();WebInspector.settings.createSetting("timelineOverviewMode","").remove();},_updateVersionFrom13To14:function()
{var defaultValue={"throughput":-1,"latency":0};WebInspector.settings.createSetting("networkConditions",defaultValue).set(defaultValue);},_updateVersionFrom14To15:function()
{var setting=WebInspector.settings.createLocalSetting("workspaceExcludedFolders",{});var oldValue=setting.get();var newValue={};for(var fileSystemPath in oldValue){newValue[fileSystemPath]=[];for(var entry of oldValue[fileSystemPath])
newValue[fileSystemPath].push(entry.path);}
setting.set(newValue);},_updateVersionFrom15To16:function()
{var setting=WebInspector.settings.createSetting("InspectorView.panelOrder",{});var tabOrders=setting.get();for(var key of Object.keys(tabOrders))
tabOrders[key]=(tabOrders[key]+1)*10;setting.set(tabOrders);},_updateVersionFrom16To17:function()
{var setting=WebInspector.settings.createSetting("networkConditionsCustomProfiles",[]);var oldValue=setting.get();var newValue=[];if(Array.isArray(oldValue)){for(var preset of oldValue){if(typeof preset.title==="string"&&typeof preset.value==="object"&&typeof preset.value.throughput==="number"&&typeof preset.value.latency==="number")
newValue.push({title:preset.title,value:{download:preset.value.throughput,upload:preset.value.throughput,latency:preset.value.latency}});}}
setting.set(newValue);},_updateVersionFrom17To18:function()
{var setting=WebInspector.settings.createLocalSetting("workspaceExcludedFolders",{});var oldValue=setting.get();var newValue={};for(var oldKey in oldValue){var newKey=oldKey.replace(/\\/g,"/");if(!newKey.startsWith("file://")){if(newKey.startsWith("/"))
newKey="file://"+newKey;else
newKey="file:///"+newKey;}
newValue[newKey]=oldValue[oldKey];}
setting.set(newValue);},_migrateSettingsFromLocalStorage:function()
{var localSettings=["advancedSearchConfig","breakpoints","consoleHistory","domBreakpoints","eventListenerBreakpoints","fileSystemMapping","lastSelectedSourcesSidebarPaneTab","previouslyViewedFiles","savedURLs","watchExpressions","workspaceExcludedFolders","xhrBreakpoints"].keySet();if(!window.localStorage)
return;for(var key in window.localStorage){if(key in localSettings)
continue;var value=window.localStorage[key];window.localStorage.removeItem(key);WebInspector.settings._settingsStorage[key]=value;}},_clearBreakpointsWhenTooMany:function(breakpointsSetting,maxBreakpointsCount)
{if(breakpointsSetting.get().length>maxBreakpointsCount)
breakpointsSetting.set([]);}}
WebInspector.settings;WebInspector.moduleSetting=function(settingName)
{return WebInspector.settings.moduleSetting(settingName);}
WebInspector.settingForTest=function(settingName)
{return WebInspector.settings.settingForTest(settingName);};WebInspector.StaticContentProvider=function(contentURL,contentType,lazyContent)
{this._contentURL=contentURL;this._contentType=contentType;this._lazyContent=lazyContent;}
WebInspector.StaticContentProvider.fromString=function(contentURL,contentType,content)
{var lazyContent=()=>Promise.resolve(content);return new WebInspector.StaticContentProvider(contentURL,contentType,lazyContent);}
WebInspector.StaticContentProvider.prototype={contentURL:function()
{return this._contentURL;},contentType:function()
{return this._contentType;},requestContent:function()
{return(this._lazyContent());},searchInContent:function(query,caseSensitive,isRegex,callback)
{function performSearch(content)
{callback(WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex));}
this._lazyContent().then(performSearch);}};WebInspector.OutputStream=function()
{}
WebInspector.OutputStream.prototype={write:function(data,callback){},close:function(){}}
WebInspector.StringOutputStream=function()
{this._data="";}
WebInspector.StringOutputStream.prototype={write:function(chunk,callback)
{this._data+=chunk;},close:function()
{},data:function()
{return this._data;}};WebInspector.Segment=function(begin,end,data)
{if(begin>end)
console.assert(false,"Invalid segment");this.begin=begin;this.end=end;this.data=data;}
WebInspector.Segment.prototype={intersects:function(that)
{return this.begin<that.end&&that.begin<this.end;}};WebInspector.SegmentedRange=function(mergeCallback)
{this._segments=[];this._mergeCallback=mergeCallback;}
WebInspector.SegmentedRange.prototype={append:function(newSegment)
{var startIndex=this._segments.lowerBound(newSegment,(a,b)=>a.begin-b.begin);var endIndex=startIndex;var merged=null;if(startIndex>0){var precedingSegment=this._segments[startIndex-1];merged=this._tryMerge(precedingSegment,newSegment);if(merged){--startIndex;newSegment=merged;}else if(this._segments[startIndex-1].end>=newSegment.begin){if(newSegment.end<precedingSegment.end)
this._segments.splice(startIndex,0,new WebInspector.Segment(newSegment.end,precedingSegment.end,precedingSegment.data));precedingSegment.end=newSegment.begin;}}
while(endIndex<this._segments.length&&this._segments[endIndex].end<=newSegment.end)
++endIndex;if(endIndex<this._segments.length){merged=this._tryMerge(newSegment,this._segments[endIndex]);if(merged){endIndex++;newSegment=merged;}else if(newSegment.intersects(this._segments[endIndex]))
this._segments[endIndex].begin=newSegment.end;}
this._segments.splice(startIndex,endIndex-startIndex,newSegment);},appendRange:function(that)
{that.segments().forEach(segment=>this.append(segment));},segments:function()
{return this._segments;},_tryMerge:function(first,second)
{var merged=this._mergeCallback&&this._mergeCallback(first,second);if(!merged)
return null;merged.begin=first.begin;merged.end=Math.max(first.end,second.end);return merged;}};WebInspector.Text=function(value)
{this._value=value;}
WebInspector.Text.prototype={lineEndings:function()
{if(!this._lineEndings)
this._lineEndings=this._value.computeLineEndings();return this._lineEndings;},value:function()
{return this._value;},lineCount:function()
{var lineEndings=this.lineEndings();return lineEndings.length;},offsetFromPosition:function(lineNumber,columNumber)
{return(lineNumber?this.lineEndings()[lineNumber-1]+1:0)+columNumber;},lineAt:function(lineNumber)
{var lineEndings=this.lineEndings();var lineStart=lineNumber>0?lineEndings[lineNumber-1]+1:0;var lineEnd=lineEndings[lineNumber];var lineContent=this._value.substring(lineStart,lineEnd);if(lineContent.length>0&&lineContent.charAt(lineContent.length-1)==="\r")
lineContent=lineContent.substring(0,lineContent.length-1);return lineContent;},toSourceRange:function(range)
{var start=this.offsetFromPosition(range.startLine,range.startColumn);var end=this.offsetFromPosition(range.endLine,range.endColumn);return new WebInspector.SourceRange(start,end-start);},toTextRange:function(sourceRange)
{var cursor=new WebInspector.TextCursor(this.lineEndings());var result=WebInspector.TextRange.createFromLocation(0,0);cursor.resetTo(sourceRange.offset);result.startLine=cursor.lineNumber();result.startColumn=cursor.columnNumber();cursor.advance(sourceRange.offset+sourceRange.length);result.endLine=cursor.lineNumber();result.endColumn=cursor.columnNumber();return result;},replaceRange:function(range,replacement)
{var sourceRange=this.toSourceRange(range);return this._value.substring(0,sourceRange.offset)+replacement+this._value.substring(sourceRange.offset+sourceRange.length);},extract:function(range)
{var sourceRange=this.toSourceRange(range);return this._value.substr(sourceRange.offset,sourceRange.length);}}
WebInspector.TextCursor=function(lineEndings)
{this._lineEndings=lineEndings;this._offset=0;this._lineNumber=0;this._columnNumber=0;}
WebInspector.TextCursor.prototype={advance:function(offset)
{this._offset=offset;while(this._lineNumber<this._lineEndings.length&&this._lineEndings[this._lineNumber]<this._offset)
++this._lineNumber;this._columnNumber=this._lineNumber?this._offset-this._lineEndings[this._lineNumber-1]-1:this._offset;},offset:function()
{return this._offset;},resetTo:function(offset)
{this._offset=offset;this._lineNumber=this._lineEndings.lowerBound(offset);this._columnNumber=this._lineNumber?this._offset-this._lineEndings[this._lineNumber-1]-1:this._offset;},lineNumber:function()
{return this._lineNumber;},columnNumber:function()
{return this._columnNumber;}};WebInspector.TextRange=function(startLine,startColumn,endLine,endColumn)
{this.startLine=startLine;this.startColumn=startColumn;this.endLine=endLine;this.endColumn=endColumn;}
WebInspector.TextRange.createFromLocation=function(line,column)
{return new WebInspector.TextRange(line,column,line,column);}
WebInspector.TextRange.fromObject=function(serializedTextRange)
{return new WebInspector.TextRange(serializedTextRange.startLine,serializedTextRange.startColumn,serializedTextRange.endLine,serializedTextRange.endColumn);}
WebInspector.TextRange.comparator=function(range1,range2)
{return range1.compareTo(range2);}
WebInspector.TextRange.prototype={isEmpty:function()
{return this.startLine===this.endLine&&this.startColumn===this.endColumn;},immediatelyPrecedes:function(range)
{if(!range)
return false;return this.endLine===range.startLine&&this.endColumn===range.startColumn;},immediatelyFollows:function(range)
{if(!range)
return false;return range.immediatelyPrecedes(this);},follows:function(range)
{return(range.endLine===this.startLine&&range.endColumn<=this.startColumn)||range.endLine<this.startLine;},get linesCount()
{return this.endLine-this.startLine;},collapseToEnd:function()
{return new WebInspector.TextRange(this.endLine,this.endColumn,this.endLine,this.endColumn);},collapseToStart:function()
{return new WebInspector.TextRange(this.startLine,this.startColumn,this.startLine,this.startColumn);},normalize:function()
{if(this.startLine>this.endLine||(this.startLine===this.endLine&&this.startColumn>this.endColumn))
return new WebInspector.TextRange(this.endLine,this.endColumn,this.startLine,this.startColumn);else
return this.clone();},clone:function()
{return new WebInspector.TextRange(this.startLine,this.startColumn,this.endLine,this.endColumn);},serializeToObject:function()
{var serializedTextRange={};serializedTextRange.startLine=this.startLine;serializedTextRange.startColumn=this.startColumn;serializedTextRange.endLine=this.endLine;serializedTextRange.endColumn=this.endColumn;return serializedTextRange;},compareTo:function(other)
{if(this.startLine>other.startLine)
return 1;if(this.startLine<other.startLine)
return-1;if(this.startColumn>other.startColumn)
return 1;if(this.startColumn<other.startColumn)
return-1;return 0;},compareToPosition:function(lineNumber,columnNumber)
{if(lineNumber<this.startLine||(lineNumber===this.startLine&&columnNumber<this.startColumn))
return-1;if(lineNumber>this.endLine||(lineNumber===this.endLine&&columnNumber>this.endColumn))
return 1;return 0;},equal:function(other)
{return this.startLine===other.startLine&&this.endLine===other.endLine&&this.startColumn===other.startColumn&&this.endColumn===other.endColumn;},relativeTo:function(line,column)
{var relative=this.clone();if(this.startLine==line)
relative.startColumn-=column;if(this.endLine==line)
relative.endColumn-=column;relative.startLine-=line;relative.endLine-=line;return relative;},rebaseAfterTextEdit:function(originalRange,editedRange)
{console.assert(originalRange.startLine===editedRange.startLine);console.assert(originalRange.startColumn===editedRange.startColumn);var rebase=this.clone();if(!this.follows(originalRange))
return rebase;var lineDelta=editedRange.endLine-originalRange.endLine;var columnDelta=editedRange.endColumn-originalRange.endColumn;rebase.startLine+=lineDelta;rebase.endLine+=lineDelta;if(rebase.startLine===editedRange.endLine)
rebase.startColumn+=columnDelta;if(rebase.endLine===editedRange.endLine)
rebase.endColumn+=columnDelta;return rebase;},toString:function()
{return JSON.stringify(this);},containsLocation:function(lineNumber,columnNumber)
{if(this.startLine===this.endLine)
return this.startLine===lineNumber&&this.startColumn<=columnNumber&&columnNumber<=this.endColumn;if(this.startLine===lineNumber)
return this.startColumn<=columnNumber;if(this.endLine===lineNumber)
return columnNumber<=this.endColumn;return this.startLine<lineNumber&&lineNumber<this.endLine;}}
WebInspector.TextRange.fromEdit=function(oldRange,newText)
{var endLine=oldRange.startLine;var endColumn=oldRange.startColumn+newText.length;var lineEndings=newText.computeLineEndings();if(lineEndings.length>1){endLine=oldRange.startLine+lineEndings.length-1;var len=lineEndings.length;endColumn=lineEndings[len-1]-lineEndings[len-2]-1;}
return new WebInspector.TextRange(oldRange.startLine,oldRange.startColumn,endLine,endColumn);}
WebInspector.SourceRange=function(offset,length)
{this.offset=offset;this.length=length;}
WebInspector.SourceEdit=function(sourceURL,oldRange,newText)
{this.sourceURL=sourceURL;this.oldRange=oldRange;this.newText=newText;}
WebInspector.SourceEdit.prototype={newRange:function()
{return WebInspector.TextRange.fromEdit(this.oldRange,this.newText);},}
WebInspector.SourceEdit.comparator=function(edit1,edit2)
{return WebInspector.TextRange.comparator(edit1.oldRange,edit2.oldRange);};WebInspector.TextUtils={isStopChar:function(char)
{return(char>" "&&char<"0")||(char>"9"&&char<"A")||(char>"Z"&&char<"_")||(char>"_"&&char<"a")||(char>"z"&&char<="~");},isWordChar:function(char)
{return!WebInspector.TextUtils.isStopChar(char)&&!WebInspector.TextUtils.isSpaceChar(char);},isSpaceChar:function(char)
{return WebInspector.TextUtils._SpaceCharRegex.test(char);},isWord:function(word)
{for(var i=0;i<word.length;++i){if(!WebInspector.TextUtils.isWordChar(word.charAt(i)))
return false;}
return true;},isOpeningBraceChar:function(char)
{return char==="("||char==="{";},isClosingBraceChar:function(char)
{return char===")"||char==="}";},isBraceChar:function(char)
{return WebInspector.TextUtils.isOpeningBraceChar(char)||WebInspector.TextUtils.isClosingBraceChar(char);},textToWords:function(text,isWordChar,wordCallback)
{var startWord=-1;for(var i=0;i<text.length;++i){if(!isWordChar(text.charAt(i))){if(startWord!==-1)
wordCallback(text.substring(startWord,i));startWord=-1;}else if(startWord===-1)
startWord=i;}
if(startWord!==-1)
wordCallback(text.substring(startWord));},lineIndent:function(line)
{var indentation=0;while(indentation<line.length&&WebInspector.TextUtils.isSpaceChar(line.charAt(indentation)))
++indentation;return line.substr(0,indentation);},isUpperCase:function(text)
{return text===text.toUpperCase();},isLowerCase:function(text)
{return text===text.toLowerCase();}}
WebInspector.TextUtils._SpaceCharRegex=/\s/;WebInspector.TextUtils.Indent={TwoSpaces:" ",FourSpaces:" ",EightSpaces:" ",TabCharacter:"\t"}
WebInspector.TextUtils.BalancedJSONTokenizer=function(callback,findMultiple)
{this._callback=callback;this._index=0;this._balance=0;this._buffer="";this._findMultiple=findMultiple||false;this._closingDoubleQuoteRegex=/[^\\](?:\\\\)*"/g;}
WebInspector.TextUtils.BalancedJSONTokenizer.prototype={write:function(chunk)
{this._buffer+=chunk;var lastIndex=this._buffer.length;var buffer=this._buffer;for(var index=this._index;index<lastIndex;++index){var character=buffer[index];if(character==="\""){this._closingDoubleQuoteRegex.lastIndex=index;if(!this._closingDoubleQuoteRegex.test(buffer))
break;index=this._closingDoubleQuoteRegex.lastIndex-1;}else if(character==="{"){++this._balance;}else if(character==="}"){if(--this._balance===0){this._lastBalancedIndex=index+1;if(!this._findMultiple)
break;}}}
this._index=index;this._reportBalanced();},_reportBalanced:function()
{if(!this._lastBalancedIndex)
return;this._callback(this._buffer.slice(0,this._lastBalancedIndex));this._buffer=this._buffer.slice(this._lastBalancedIndex);this._index-=this._lastBalancedIndex;this._lastBalancedIndex=0;},remainder:function()
{return this._buffer;}}
WebInspector.TokenizerFactory=function(){}
WebInspector.TokenizerFactory.prototype={createTokenizer:function(mimeType){}};WebInspector.Throttler=function(timeout)
{this._timeout=timeout;this._isRunningProcess=false;this._asSoonAsPossible=false;this._process=null;this._lastCompleteTime=0;}
WebInspector.Throttler.prototype={_processCompleted:function()
{this._lastCompleteTime=window.performance.now();this._isRunningProcess=false;if(this._process)
this._innerSchedule(false);this._processCompletedForTests();},_processCompletedForTests:function()
{},_onTimeout:function()
{delete this._processTimeout;this._asSoonAsPossible=false;this._isRunningProcess=true;Promise.resolve().then(this._process).catch(console.error.bind(console)).then(this._processCompleted.bind(this));this._process=null;},schedule:function(process,asSoonAsPossible)
{this._process=process;var hasScheduledTasks=!!this._processTimeout||this._isRunningProcess;var okToFire=window.performance.now()-this._lastCompleteTime>this._timeout;asSoonAsPossible=!!asSoonAsPossible||(!hasScheduledTasks&&okToFire);var forceTimerUpdate=asSoonAsPossible&&!this._asSoonAsPossible;this._asSoonAsPossible=this._asSoonAsPossible||asSoonAsPossible;this._innerSchedule(forceTimerUpdate);},flush:function()
{if(this._process)
this._onTimeout();},_innerSchedule:function(forceTimerUpdate)
{if(this._isRunningProcess)
return;if(this._processTimeout&&!forceTimerUpdate)
return;if(this._processTimeout)
this._clearTimeout(this._processTimeout);var timeout=this._asSoonAsPossible?0:this._timeout;this._processTimeout=this._setTimeout(this._onTimeout.bind(this),timeout);},_clearTimeout:function(timeoutId)
{clearTimeout(timeoutId);},_setTimeout:function(operation,timeout)
{return setTimeout(operation,timeout);}}
WebInspector.Throttler.FinishCallback;;WebInspector.UIString=function(string,vararg)
{return String.vsprintf(WebInspector.localize(string),Array.prototype.slice.call(arguments,1));}
WebInspector.UIString.capitalize=function(string,vararg)
{if(WebInspector._useLowerCaseMenuTitles===undefined)
throw"WebInspector.setLocalizationPlatform() has not been called";var localized=WebInspector.localize(string);var capitalized;if(WebInspector._useLowerCaseMenuTitles)
capitalized=localized.replace(/\^(.)/g,"$1");else
capitalized=localized.replace(/\^(.)/g,function(str,char){return char.toUpperCase();});return String.vsprintf(capitalized,Array.prototype.slice.call(arguments,1));}
WebInspector.setLocalizationPlatform=function(platform)
{WebInspector._useLowerCaseMenuTitles=platform==="windows";}
WebInspector.localize=function(string)
{return string;}
WebInspector.UIStringFormat=function(format)
{this._localizedFormat=WebInspector.localize(format);this._tokenizedFormat=String.tokenizeFormatString(this._localizedFormat,String.standardFormatters);}
WebInspector.UIStringFormat._append=function(a,b)
{return a+b;}
WebInspector.UIStringFormat.prototype={format:function(vararg)
{return String.format(this._localizedFormat,arguments,String.standardFormatters,"",WebInspector.UIStringFormat._append,this._tokenizedFormat).formattedResult;}};WebInspector.Renderer=function()
{}
WebInspector.Renderer.prototype={render:function(object){}}
WebInspector.Renderer.renderPromise=function(object)
{if(!object)
return Promise.reject(new Error("Can't render "+object));return self.runtime.instancePromise(WebInspector.Renderer,object).then(render);function render(renderer)
{return renderer.render(object);}}
WebInspector.Revealer=function()
{}
WebInspector.Revealer.reveal=function(revealable,omitFocus)
{WebInspector.Revealer.revealPromise(revealable,omitFocus);}
WebInspector.Revealer.revealPromise=function(revealable,omitFocus)
{if(!revealable)
return Promise.reject(new Error("Can't reveal "+revealable));return self.runtime.instancesPromise(WebInspector.Revealer,revealable).then(reveal);function reveal(revealers)
{var promises=[];for(var i=0;i<revealers.length;++i)
promises.push(revealers[i].reveal((revealable),omitFocus));return Promise.race(promises);}}
WebInspector.Revealer.prototype={reveal:function(object,omitFocus){}}
WebInspector.App=function()
{}
WebInspector.App.prototype={presentUI:function(document){}}
WebInspector.AppProvider=function()
{}
WebInspector.AppProvider.prototype={createApp:function(){}}
WebInspector.QueryParamHandler=function()
{}
WebInspector.QueryParamHandler.prototype={handleQueryParam:function(value){}};WebInspector.FormatterWorkerPool=function()
{this._taskQueue=[];this._workerTasks=new Map();}
WebInspector.FormatterWorkerPool.MaxWorkers=2;WebInspector.FormatterWorkerPool.prototype={_createWorker:function()
{var worker=new WebInspector.Worker("formatter_worker");worker.onmessage=this._onWorkerMessage.bind(this,worker);worker.onerror=this._onWorkerError.bind(this,worker);return worker;},_processNextTask:function()
{if(!this._taskQueue.length)
return;var freeWorker=this._workerTasks.keysArray().find(worker=>!this._workerTasks.get(worker));if(!freeWorker&&this._workerTasks.size<WebInspector.FormatterWorkerPool.MaxWorkers)
freeWorker=this._createWorker();if(!freeWorker)
return;var task=this._taskQueue.shift();this._workerTasks.set(freeWorker,task);freeWorker.postMessage({method:task.method,params:task.params});},_onWorkerMessage:function(worker,event)
{var task=this._workerTasks.get(worker);if(task.isChunked&&event.data&&!event.data["isLastChunk"]){task.callback(event);return;}
this._workerTasks.set(worker,null);this._processNextTask();task.callback(event.data?event:null);},_onWorkerError:function(worker,event)
{console.error(event);var task=this._workerTasks.get(worker);worker.terminate();this._workerTasks.delete(worker);var newWorker=this._createWorker();this._workerTasks.set(newWorker,null);this._processNextTask();task.callback(null);},runChunkedTask:function(methodName,params,callback)
{var task=new WebInspector.FormatterWorkerPool.Task(methodName,params,callback,true);this._taskQueue.push(task);this._processNextTask();},runTask:function(methodName,params)
{var callback;var promise=new Promise(fulfill=>callback=fulfill);var task=new WebInspector.FormatterWorkerPool.Task(methodName,params,callback,false);this._taskQueue.push(task);this._processNextTask();return promise;},}
WebInspector.FormatterWorkerPool.Task=function(method,params,callback,isChunked)
{this.method=method;this.params=params;this.callback=callback;this.isChunked=isChunked;}
WebInspector.formatterWorkerPool;;function InspectorFrontendHostAPI()
{}
InspectorFrontendHostAPI.ContextMenuDescriptor;InspectorFrontendHostAPI.LoadNetworkResourceResult;InspectorFrontendHostAPI.Events={AddExtensions:"addExtensions",AppendedToURL:"appendedToURL",CanceledSaveURL:"canceledSaveURL",ContextMenuCleared:"contextMenuCleared",ContextMenuItemSelected:"contextMenuItemSelected",DeviceCountUpdated:"deviceCountUpdated",DevicesDiscoveryConfigChanged:"devicesDiscoveryConfigChanged",DevicesPortForwardingStatusChanged:"devicesPortForwardingStatusChanged",DevicesUpdated:"devicesUpdated",DispatchMessage:"dispatchMessage",DispatchMessageChunk:"dispatchMessageChunk",EnterInspectElementMode:"enterInspectElementMode",EvaluateForTestInFrontend:"evaluateForTestInFrontend",FileSystemsLoaded:"fileSystemsLoaded",FileSystemRemoved:"fileSystemRemoved",FileSystemAdded:"fileSystemAdded",FileSystemFilesChanged:"fileSystemFilesChanged",IndexingTotalWorkCalculated:"indexingTotalWorkCalculated",IndexingWorked:"indexingWorked",IndexingDone:"indexingDone",KeyEventUnhandled:"keyEventUnhandled",ReloadInspectedPage:"reloadInspectedPage",RevealSourceLine:"revealSourceLine",SavedURL:"savedURL",SearchCompleted:"searchCompleted",SetInspectedTabId:"setInspectedTabId",SetUseSoftMenu:"setUseSoftMenu",ShowPanel:"showPanel"}
InspectorFrontendHostAPI.EventDescriptors=[[InspectorFrontendHostAPI.Events.AddExtensions,["extensions"]],[InspectorFrontendHostAPI.Events.AppendedToURL,["url"]],[InspectorFrontendHostAPI.Events.CanceledSaveURL,["url"]],[InspectorFrontendHostAPI.Events.ContextMenuCleared,[]],[InspectorFrontendHostAPI.Events.ContextMenuItemSelected,["id"]],[InspectorFrontendHostAPI.Events.DeviceCountUpdated,["count"]],[InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged,["discoverUsbDevices","portForwardingEnabled","portForwardingConfig"]],[InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged,["status"]],[InspectorFrontendHostAPI.Events.DevicesUpdated,["devices"]],[InspectorFrontendHostAPI.Events.DispatchMessage,["messageObject"]],[InspectorFrontendHostAPI.Events.DispatchMessageChunk,["messageChunk","messageSize"]],[InspectorFrontendHostAPI.Events.EnterInspectElementMode,[]],[InspectorFrontendHostAPI.Events.EvaluateForTestInFrontend,["callId","script"]],[InspectorFrontendHostAPI.Events.FileSystemsLoaded,["fileSystems"]],[InspectorFrontendHostAPI.Events.FileSystemRemoved,["fileSystemPath"]],[InspectorFrontendHostAPI.Events.FileSystemAdded,["errorMessage","fileSystem"]],[InspectorFrontendHostAPI.Events.FileSystemFilesChanged,["paths"]],[InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated,["requestId","fileSystemPath","totalWork"]],[InspectorFrontendHostAPI.Events.IndexingWorked,["requestId","fileSystemPath","worked"]],[InspectorFrontendHostAPI.Events.IndexingDone,["requestId","fileSystemPath"]],[InspectorFrontendHostAPI.Events.KeyEventUnhandled,["event"]],[InspectorFrontendHostAPI.Events.ReloadInspectedPage,["hard"]],[InspectorFrontendHostAPI.Events.RevealSourceLine,["url","lineNumber","columnNumber"]],[InspectorFrontendHostAPI.Events.SavedURL,["url"]],[InspectorFrontendHostAPI.Events.SearchCompleted,["requestId","fileSystemPath","files"]],[InspectorFrontendHostAPI.Events.SetInspectedTabId,["tabId"]],[InspectorFrontendHostAPI.Events.SetUseSoftMenu,["useSoftMenu"]],[InspectorFrontendHostAPI.Events.ShowPanel,["panelName"]]];InspectorFrontendHostAPI.prototype={addFileSystem:function(fileSystemPath){},append:function(url,content){},loadCompleted:function(){},indexPath:function(requestId,fileSystemPath){},getSelectionBackgroundColor:function(){},getSelectionForegroundColor:function(){},setInspectedPageBounds:function(bounds){},setWhitelistedShortcuts:function(shortcuts){},inspectElementCompleted:function(){},openInNewTab:function(url){},removeFileSystem:function(fileSystemPath){},requestFileSystems:function(){},save:function(url,content,forceSaveAs){},searchInPath:function(requestId,fileSystemPath,query){},stopIndexing:function(requestId){},bringToFront:function(){},closeWindow:function(){},copyText:function(text){},inspectedURLChanged:function(url){},isolatedFileSystem:function(fileSystemId,registeredName){},loadNetworkResource:function(url,headers,streamId,callback){},getPreferences:function(callback){},setPreference:function(name,value){},removePreference:function(name){},clearPreferences:function(){},upgradeDraggedFileSystemPermissions:function(fileSystem){},platform:function(){},recordEnumeratedHistogram:function(actionName,actionCode,bucketSize){},sendMessageToBackend:function(message){},setDevicesDiscoveryConfig:function(discoverUsbDevices,portForwardingEnabled,portForwardingConfig){},setDevicesUpdatesEnabled:function(enabled){},performActionOnRemotePage:function(pageId,action){},openRemotePage:function(browserId,url){},setInjectedScriptForOrigin:function(origin,script){},setIsDocked:function(isDocked,callback){},zoomFactor:function(){},zoomIn:function(){},zoomOut:function(){},resetZoom:function(){},showContextMenuAtPoint:function(x,y,items,document){},isUnderTest:function(){},readyForTest:function(){},isHostedMode:function(){}};WebInspector.InspectorFrontendHostStub=function()
{function stopEventPropagation(event)
{var zoomModifier=WebInspector.isMac()?event.metaKey:event.ctrlKey;if(zoomModifier&&(event.keyCode===187||event.keyCode===189))
event.stopPropagation();}
document.addEventListener("keydown",stopEventPropagation,true);}
WebInspector.InspectorFrontendHostStub.prototype={getSelectionBackgroundColor:function()
{return"#6e86ff";},getSelectionForegroundColor:function()
{return"#ffffff";},platform:function()
{var match=navigator.userAgent.match(/Windows NT/);if(match)
return"windows";match=navigator.userAgent.match(/Mac OS X/);if(match)
return"mac";return"linux";},loadCompleted:function()
{},bringToFront:function()
{this._windowVisible=true;},closeWindow:function()
{this._windowVisible=false;},setIsDocked:function(isDocked,callback)
{setTimeout(callback,0);},setInspectedPageBounds:function(bounds)
{},inspectElementCompleted:function()
{},setInjectedScriptForOrigin:function(origin,script)
{},inspectedURLChanged:function(url)
{document.title=WebInspector.UIString("Developer Tools - %s",url);},copyText:function(text)
{WebInspector.console.error("Clipboard is not enabled in hosted mode. Please inspect using chrome://inspect");},openInNewTab:function(url)
{window.open(url,"_blank");},save:function(url,content,forceSaveAs)
{WebInspector.console.error("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect");this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.CanceledSaveURL,url);},append:function(url,content)
{WebInspector.console.error("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect");},sendMessageToBackend:function(message)
{},recordEnumeratedHistogram:function(actionName,actionCode,bucketSize)
{},requestFileSystems:function()
{this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemsLoaded,[]);},addFileSystem:function(fileSystemPath)
{},removeFileSystem:function(fileSystemPath)
{},isolatedFileSystem:function(fileSystemId,registeredName)
{return null;},loadNetworkResource:function(url,headers,streamId,callback)
{loadResourcePromise(url).then(function(text){WebInspector.ResourceLoader.streamWrite(streamId,text);callback({statusCode:200});}).catch(function(){callback({statusCode:404});});},getPreferences:function(callback)
{var prefs={};for(var name in window.localStorage)
prefs[name]=window.localStorage[name];callback(prefs);},setPreference:function(name,value)
{window.localStorage[name]=value;},removePreference:function(name)
{delete window.localStorage[name];},clearPreferences:function()
{window.localStorage.clear();},upgradeDraggedFileSystemPermissions:function(fileSystem)
{},indexPath:function(requestId,fileSystemPath)
{},stopIndexing:function(requestId)
{},searchInPath:function(requestId,fileSystemPath,query)
{},zoomFactor:function()
{return 1;},zoomIn:function()
{},zoomOut:function()
{},resetZoom:function()
{},setWhitelistedShortcuts:function(shortcuts)
{},isUnderTest:function()
{return false;},readyForTest:function()
{},setDevicesDiscoveryConfig:function(discoverUsbDevices,portForwardingEnabled,portForwardingConfig)
{},setDevicesUpdatesEnabled:function(enabled)
{},performActionOnRemotePage:function(pageId,action)
{},openRemotePage:function(browserId,url)
{},showContextMenuAtPoint:function(x,y,items,document)
{throw"Soft context menu should be used";},isHostedMode:function()
{return true;}};var InspectorFrontendHost=window.InspectorFrontendHost||null;(function(){function initializeInspectorFrontendHost()
{if(!InspectorFrontendHost){InspectorFrontendHost=new WebInspector.InspectorFrontendHostStub();}else{var proto=WebInspector.InspectorFrontendHostStub.prototype;for(var name in proto){var value=proto[name];if(typeof value!=="function"||InspectorFrontendHost[name])
continue;InspectorFrontendHost[name]=stub.bind(null,name);}}
function stub(name)
{console.error("Incompatible embedder: method InspectorFrontendHost."+name+" is missing. Using stub instead.");var args=Array.prototype.slice.call(arguments,1);return proto[name].apply(InspectorFrontendHost,args);}
InspectorFrontendHost.events=new WebInspector.Object();}
function InspectorFrontendAPIImpl()
{this._debugFrontend=!!Runtime.queryParam("debugFrontend")||(window["InspectorTest"]&&window["InspectorTest"]["debugTest"]);var descriptors=InspectorFrontendHostAPI.EventDescriptors;for(var i=0;i<descriptors.length;++i)
this[descriptors[i][0]]=this._dispatch.bind(this,descriptors[i][0],descriptors[i][1],descriptors[i][2]);}
InspectorFrontendAPIImpl.prototype={_dispatch:function(name,signature,runOnceLoaded)
{var params=Array.prototype.slice.call(arguments,3);if(this._debugFrontend)
setImmediate(innerDispatch);else
innerDispatch();function innerDispatch()
{if(signature.length<2){try{InspectorFrontendHost.events.dispatchEventToListeners(name,params[0]);}catch(e){console.error(e+" "+e.stack);}
return;}
var data={};for(var i=0;i<signature.length;++i)
data[signature[i]]=params[i];try{InspectorFrontendHost.events.dispatchEventToListeners(name,data);}catch(e){console.error(e+" "+e.stack);}}},streamWrite:function(id,chunk)
{WebInspector.ResourceLoader.streamWrite(id,chunk);}}
initializeInspectorFrontendHost();window.InspectorFrontendAPI=new InspectorFrontendAPIImpl();WebInspector.setLocalizationPlatform(InspectorFrontendHost.platform());})();InspectorFrontendHost.events;;WebInspector.platform=function()
{if(!WebInspector._platform)
WebInspector._platform=InspectorFrontendHost.platform();return WebInspector._platform;}
WebInspector.isMac=function()
{if(typeof WebInspector._isMac==="undefined")
WebInspector._isMac=WebInspector.platform()==="mac";return WebInspector._isMac;}
WebInspector.isWin=function()
{if(typeof WebInspector._isWin==="undefined")
WebInspector._isWin=WebInspector.platform()==="windows";return WebInspector._isWin;}
WebInspector.fontFamily=function()
{if(WebInspector._fontFamily)
return WebInspector._fontFamily;switch(WebInspector.platform()){case"linux":WebInspector._fontFamily="Ubuntu, Arial, sans-serif";break;case"mac":WebInspector._fontFamily="'Lucida Grande', sans-serif";break;case"windows":WebInspector._fontFamily="'Segoe UI', Tahoma, sans-serif";break;}
return WebInspector._fontFamily;}
WebInspector.monospaceFontFamily=function()
{if(WebInspector._monospaceFontFamily)
return WebInspector._monospaceFontFamily;switch(WebInspector.platform()){case"linux":WebInspector._monospaceFontFamily="dejavu sans mono, monospace";break;case"mac":WebInspector._monospaceFontFamily="Menlo, monospace";break;case"windows":WebInspector._monospaceFontFamily="Consolas, monospace";break;}
return WebInspector._monospaceFontFamily;};WebInspector.ResourceLoader={}
WebInspector.ResourceLoader._lastStreamId=0;WebInspector.ResourceLoader._boundStreams={};WebInspector.ResourceLoader._bindOutputStream=function(stream)
{WebInspector.ResourceLoader._boundStreams[++WebInspector.ResourceLoader._lastStreamId]=stream;return WebInspector.ResourceLoader._lastStreamId;}
WebInspector.ResourceLoader._discardOutputStream=function(id)
{WebInspector.ResourceLoader._boundStreams[id].close();delete WebInspector.ResourceLoader._boundStreams[id];}
WebInspector.ResourceLoader.streamWrite=function(id,chunk)
{WebInspector.ResourceLoader._boundStreams[id].write(chunk);}
WebInspector.ResourceLoader.load=function(url,headers,callback)
{var stream=new WebInspector.StringOutputStream();WebInspector.ResourceLoader.loadAsStream(url,headers,stream,mycallback);function mycallback(statusCode,headers)
{callback(statusCode,headers,stream.data());}}
WebInspector.ResourceLoader.loadAsStream=function(url,headers,stream,callback)
{var streamId=WebInspector.ResourceLoader._bindOutputStream(stream);var parsedURL=new WebInspector.ParsedURL(url);if(parsedURL.isDataURL()){loadXHR(url).then(dataURLDecodeSuccessful).catch(dataURLDecodeFailed);return;}
var rawHeaders=[];if(headers){for(var key in headers)
rawHeaders.push(key+": "+headers[key]);}
InspectorFrontendHost.loadNetworkResource(url,rawHeaders.join("\r\n"),streamId,finishedCallback);function finishedCallback(response)
{if(callback)
callback(response.statusCode,response.headers||{});WebInspector.ResourceLoader._discardOutputStream(streamId);}
function dataURLDecodeSuccessful(text)
{WebInspector.ResourceLoader.streamWrite(streamId,text);finishedCallback(({statusCode:200}));}
function dataURLDecodeFailed()
{finishedCallback(({statusCode:404}));}};WebInspector.UserMetrics=function()
{}
WebInspector.UserMetrics.Action={WindowDocked:1,WindowUndocked:2,ScriptsBreakpointSet:3,TimelineStarted:4,ProfilesCPUProfileTaken:5,ProfilesHeapProfileTaken:6,AuditsStarted:7,ConsoleEvaluated:8,FileSavedInWorkspace:9,DeviceModeEnabled:10,AnimationsPlaybackRateChanged:11,RevisionApplied:12,FileSystemDirectoryContentReceived:13,StyleRuleEdited:14,CommandEvaluatedInConsolePanel:15,DOMPropertiesExpanded:16,ResizedViewInResponsiveMode:17}
WebInspector.UserMetrics._PanelCodes={elements:1,resources:2,network:3,sources:4,timeline:5,profiles:6,audits:7,console:8,layers:9,"drawer-console":10,"drawer-animations":11,"drawer-network.config":12,"drawer-rendering":13,"drawer-sensors":14,"drawer-sources.search":15,security:16}
WebInspector.UserMetrics.prototype={panelShown:function(panelName)
{var code=WebInspector.UserMetrics._PanelCodes[panelName]||0;var size=Object.keys(WebInspector.UserMetrics._PanelCodes).length+1;InspectorFrontendHost.recordEnumeratedHistogram("DevTools.PanelShown",code,size);},drawerShown:function(drawerId)
{this.panelShown("drawer-"+drawerId);},actionTaken:function(action)
{var size=Object.keys(WebInspector.UserMetrics.Action).length+1;InspectorFrontendHost.recordEnumeratedHistogram("DevTools.ActionTaken",action,size);}}
WebInspector.userMetrics=new WebInspector.UserMetrics();;WebInspector.Widget=function(isWebComponent)
{this.contentElement=createElementWithClass("div","widget");if(isWebComponent){this.element=createElementWithClass("div","vbox flex-auto");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element);this._shadowRoot.appendChild(this.contentElement);}else{this.element=this.contentElement;}
this._isWebComponent=isWebComponent;this.element.__widget=this;this._visible=true;this._isRoot=false;this._isShowing=false;this._children=[];this._hideOnDetach=false;this._notificationDepth=0;}
WebInspector.Widget.prototype={markAsRoot:function()
{WebInspector.Widget.__assert(!this.element.parentElement,"Attempt to mark as root attached node");this._isRoot=true;},parentWidget:function()
{return this._parentWidget;},children:function()
{return this._children;},childWasDetached:function(widget)
{},isShowing:function()
{return this._isShowing;},shouldHideOnDetach:function()
{if(this._hideOnDetach)
return true;for(var child of this._children){if(child.shouldHideOnDetach())
return true;}
return false;},setHideOnDetach:function()
{this._hideOnDetach=true;},_inNotification:function()
{return!!this._notificationDepth||(this._parentWidget&&this._parentWidget._inNotification());},_parentIsShowing:function()
{if(this._isRoot)
return true;return this._parentWidget&&this._parentWidget.isShowing();},_callOnVisibleChildren:function(method)
{var copy=this._children.slice();for(var i=0;i<copy.length;++i){if(copy[i]._parentWidget===this&©[i]._visible)
method.call(copy[i]);}},_processWillShow:function()
{this._callOnVisibleChildren(this._processWillShow);this._isShowing=true;},_processWasShown:function()
{if(this._inNotification())
return;this.restoreScrollPositions();this._notify(this.wasShown);this._callOnVisibleChildren(this._processWasShown);},_processWillHide:function()
{if(this._inNotification())
return;this.storeScrollPositions();this._callOnVisibleChildren(this._processWillHide);this._notify(this.willHide);this._isShowing=false;},_processWasHidden:function()
{this._callOnVisibleChildren(this._processWasHidden);},_processOnResize:function()
{if(this._inNotification())
return;if(!this.isShowing())
return;this._notify(this.onResize);this._callOnVisibleChildren(this._processOnResize);},_notify:function(notification)
{++this._notificationDepth;try{notification.call(this);}finally{--this._notificationDepth;}},wasShown:function()
{},willHide:function()
{},onResize:function()
{},onLayout:function()
{},show:function(parentElement,insertBefore)
{WebInspector.Widget.__assert(parentElement,"Attempt to attach widget with no parent element");if(this.element.parentElement!==parentElement){if(this.element.parentElement)
this.detach();var currentParent=parentElement;while(currentParent&&!currentParent.__widget)
currentParent=currentParent.parentElementOrShadowHost();if(currentParent){this._parentWidget=currentParent.__widget;this._parentWidget._children.push(this);this._isRoot=false;}else
WebInspector.Widget.__assert(this._isRoot,"Attempt to attach widget to orphan node");}else if(this._visible){return;}
this._visible=true;if(this._parentIsShowing())
this._processWillShow();this.element.classList.remove("hidden");if(this.element.parentElement!==parentElement){WebInspector.Widget._incrementWidgetCounter(parentElement,this.element);if(insertBefore)
WebInspector.Widget._originalInsertBefore.call(parentElement,this.element,insertBefore);else
WebInspector.Widget._originalAppendChild.call(parentElement,this.element);}
if(this._parentIsShowing())
this._processWasShown();if(this._parentWidget&&this._hasNonZeroConstraints())
this._parentWidget.invalidateConstraints();else
this._processOnResize();},detach:function(overrideHideOnDetach)
{var parentElement=this.element.parentElement;if(!parentElement)
return;if(this._parentIsShowing())
this._processWillHide();if(!overrideHideOnDetach&&this.shouldHideOnDetach()){this.element.classList.add("hidden");this._visible=false;if(this._parentIsShowing())
this._processWasHidden();if(this._parentWidget&&this._hasNonZeroConstraints())
this._parentWidget.invalidateConstraints();return;}
WebInspector.Widget._decrementWidgetCounter(parentElement,this.element);WebInspector.Widget._originalRemoveChild.call(parentElement,this.element);this._visible=false;if(this._parentIsShowing())
this._processWasHidden();if(this._parentWidget){var childIndex=this._parentWidget._children.indexOf(this);WebInspector.Widget.__assert(childIndex>=0,"Attempt to remove non-child widget");this._parentWidget._children.splice(childIndex,1);this._parentWidget.childWasDetached(this);var parent=this._parentWidget;this._parentWidget=null;if(this._hasNonZeroConstraints())
parent.invalidateConstraints();}else
WebInspector.Widget.__assert(this._isRoot,"Removing non-root widget from DOM");},detachChildWidgets:function()
{var children=this._children.slice();for(var i=0;i<children.length;++i)
children[i].detach();},elementsToRestoreScrollPositionsFor:function()
{return[this.element];},storeScrollPositions:function()
{var elements=this.elementsToRestoreScrollPositionsFor();for(var i=0;i<elements.length;++i){var container=elements[i];container._scrollTop=container.scrollTop;container._scrollLeft=container.scrollLeft;}},restoreScrollPositions:function()
{var elements=this.elementsToRestoreScrollPositionsFor();for(var i=0;i<elements.length;++i){var container=elements[i];if(container._scrollTop)
container.scrollTop=container._scrollTop;if(container._scrollLeft)
container.scrollLeft=container._scrollLeft;}},doResize:function()
{if(!this.isShowing())
return;if(!this._inNotification())
this._callOnVisibleChildren(this._processOnResize);},doLayout:function()
{if(!this.isShowing())
return;this._notify(this.onLayout);this.doResize();},registerRequiredCSS:function(cssFile)
{WebInspector.appendStyle(this._isWebComponent?this._shadowRoot:this.element,cssFile);},printWidgetHierarchy:function()
{var lines=[];this._collectWidgetHierarchy("",lines);console.log(lines.join("\n"));},_collectWidgetHierarchy:function(prefix,lines)
{lines.push(prefix+"["+this.element.className+"]"+(this._children.length?" {":""));for(var i=0;i<this._children.length;++i)
this._children[i]._collectWidgetHierarchy(prefix+" ",lines);if(this._children.length)
lines.push(prefix+"}");},defaultFocusedElement:function()
{return this._defaultFocusedElement||this.element;},setDefaultFocusedElement:function(element)
{this._defaultFocusedElement=element;},focus:function()
{var element=this.defaultFocusedElement();if(!element||element.isAncestor(this.element.ownerDocument.activeElement))
return;WebInspector.setCurrentFocusElement(element);},hasFocus:function()
{var activeElement=this.element.ownerDocument.activeElement;return activeElement&&activeElement.isSelfOrDescendant(this.element);},measurePreferredSize:function()
{var document=this.element.ownerDocument;WebInspector.Widget._originalAppendChild.call(document.body,this.element);this.element.positionAt(0,0);var result=new Size(this.element.offsetWidth,this.element.offsetHeight);this.element.positionAt(undefined,undefined);WebInspector.Widget._originalRemoveChild.call(document.body,this.element);return result;},calculateConstraints:function()
{return new Constraints();},constraints:function()
{if(typeof this._constraints!=="undefined")
return this._constraints;if(typeof this._cachedConstraints==="undefined")
this._cachedConstraints=this.calculateConstraints();return this._cachedConstraints;},setMinimumAndPreferredSizes:function(width,height,preferredWidth,preferredHeight)
{this._constraints=new Constraints(new Size(width,height),new Size(preferredWidth,preferredHeight));this.invalidateConstraints();},setMinimumSize:function(width,height)
{this._constraints=new Constraints(new Size(width,height));this.invalidateConstraints();},_hasNonZeroConstraints:function()
{var constraints=this.constraints();return!!(constraints.minimum.width||constraints.minimum.height||constraints.preferred.width||constraints.preferred.height);},invalidateConstraints:function()
{var cached=this._cachedConstraints;delete this._cachedConstraints;var actual=this.constraints();if(!actual.isEqual(cached)&&this._parentWidget)
this._parentWidget.invalidateConstraints();else
this.doLayout();},invalidateSize:function()
{if(this._parentWidget)
this._parentWidget.doLayout();},__proto__:WebInspector.Object.prototype}
WebInspector.Widget._originalAppendChild=Element.prototype.appendChild;WebInspector.Widget._originalInsertBefore=Element.prototype.insertBefore;WebInspector.Widget._originalRemoveChild=Element.prototype.removeChild;WebInspector.Widget._originalRemoveChildren=Element.prototype.removeChildren;WebInspector.Widget._incrementWidgetCounter=function(parentElement,childElement)
{var count=(childElement.__widgetCounter||0)+(childElement.__widget?1:0);if(!count)
return;while(parentElement){parentElement.__widgetCounter=(parentElement.__widgetCounter||0)+count;parentElement=parentElement.parentElementOrShadowHost();}}
WebInspector.Widget._decrementWidgetCounter=function(parentElement,childElement)
{var count=(childElement.__widgetCounter||0)+(childElement.__widget?1:0);if(!count)
return;while(parentElement){parentElement.__widgetCounter-=count;parentElement=parentElement.parentElementOrShadowHost();}}
WebInspector.Widget.__assert=function(condition,message)
{if(!condition){console.trace();throw new Error(message);}}
WebInspector.VBox=function(isWebComponent)
{WebInspector.Widget.call(this,isWebComponent);this.contentElement.classList.add("vbox");};WebInspector.VBox.prototype={calculateConstraints:function()
{var constraints=new Constraints();function updateForChild()
{var child=this.constraints();constraints=constraints.widthToMax(child);constraints=constraints.addHeight(child);}
this._callOnVisibleChildren(updateForChild);return constraints;},__proto__:WebInspector.Widget.prototype};WebInspector.HBox=function(isWebComponent)
{WebInspector.Widget.call(this,isWebComponent);this.contentElement.classList.add("hbox");};WebInspector.HBox.prototype={calculateConstraints:function()
{var constraints=new Constraints();function updateForChild()
{var child=this.constraints();constraints=constraints.addWidth(child);constraints=constraints.heightToMax(child);}
this._callOnVisibleChildren(updateForChild);return constraints;},__proto__:WebInspector.Widget.prototype};WebInspector.VBoxWithResizeCallback=function(resizeCallback)
{WebInspector.VBox.call(this);this._resizeCallback=resizeCallback;}
WebInspector.VBoxWithResizeCallback.prototype={onResize:function()
{this._resizeCallback();},__proto__:WebInspector.VBox.prototype}
WebInspector.VBoxWithToolbarItems=function()
{WebInspector.VBox.call(this);}
WebInspector.VBoxWithToolbarItems.prototype={toolbarItems:function()
{return[];},__proto__:WebInspector.VBox.prototype}
Element.prototype.appendChild=function(child)
{WebInspector.Widget.__assert(!child.__widget||child.parentElement===this,"Attempt to add widget via regular DOM operation.");return WebInspector.Widget._originalAppendChild.call(this,child);}
Element.prototype.insertBefore=function(child,anchor)
{WebInspector.Widget.__assert(!child.__widget||child.parentElement===this,"Attempt to add widget via regular DOM operation.");return WebInspector.Widget._originalInsertBefore.call(this,child,anchor);}
Element.prototype.removeChild=function(child)
{WebInspector.Widget.__assert(!child.__widgetCounter&&!child.__widget,"Attempt to remove element containing widget via regular DOM operation");return WebInspector.Widget._originalRemoveChild.call(this,child);}
Element.prototype.removeChildren=function()
{WebInspector.Widget.__assert(!this.__widgetCounter,"Attempt to remove element containing widget via regular DOM operation");WebInspector.Widget._originalRemoveChildren.call(this);};function TreeOutline(nonFocusable)
{this._createRootElement();this.selectedTreeElement=null;this.expandTreeElementsWhenArrowing=false;this._comparator=null;this.contentElement=this._rootElement._childrenListNode;this.contentElement.addEventListener("keydown",this._treeKeyDown.bind(this),true);this.setFocusable(!nonFocusable);this.element=this.contentElement;}
TreeOutline.Events={ElementAttached:"ElementAttached",ElementExpanded:"ElementExpanded",ElementCollapsed:"ElementCollapsed",ElementSelected:"ElementSelected"}
TreeOutline.prototype={_createRootElement:function()
{this._rootElement=new TreeElement();this._rootElement.treeOutline=this;this._rootElement.root=true;this._rootElement.selectable=false;this._rootElement.expanded=true;this._rootElement._childrenListNode.classList.remove("children");},rootElement:function()
{return this._rootElement;},firstChild:function()
{return this._rootElement.firstChild();},appendChild:function(child)
{this._rootElement.appendChild(child);},insertChild:function(child,index)
{this._rootElement.insertChild(child,index);},removeChild:function(child)
{this._rootElement.removeChild(child);},removeChildren:function()
{this._rootElement.removeChildren();},treeElementFromPoint:function(x,y)
{var node=this.contentElement.ownerDocument.deepElementFromPoint(x,y);if(!node)
return null;var listNode=node.enclosingNodeOrSelfWithNodeNameInArray(["ol","li"]);if(listNode)
return listNode.parentTreeElement||listNode.treeElement;return null;},treeElementFromEvent:function(event)
{return event?this.treeElementFromPoint(event.pageX,event.pageY):null;},setComparator:function(comparator)
{this._comparator=comparator;},setFocusable:function(focusable)
{if(focusable)
this.contentElement.setAttribute("tabIndex",0);else
this.contentElement.removeAttribute("tabIndex");},focus:function()
{this.contentElement.focus();},_bindTreeElement:function(element)
{if(element.treeOutline)
console.error("Binding element for the second time: "+new Error().stack);element.treeOutline=this;element.onbind();},_unbindTreeElement:function(element)
{if(!element.treeOutline)
console.error("Unbinding element that was not bound: "+new Error().stack);element.deselect();element.onunbind();element.treeOutline=null;},selectPrevious:function()
{var nextSelectedElement=this.selectedTreeElement.traversePreviousTreeElement(true);while(nextSelectedElement&&!nextSelectedElement.selectable)
nextSelectedElement=nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);if(nextSelectedElement){nextSelectedElement.reveal();nextSelectedElement.select(false,true);return true;}
return false;},selectNext:function()
{var nextSelectedElement=this.selectedTreeElement.traverseNextTreeElement(true);while(nextSelectedElement&&!nextSelectedElement.selectable)
nextSelectedElement=nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);if(nextSelectedElement){nextSelectedElement.reveal();nextSelectedElement.select(false,true);return true;}
return false;},_treeKeyDown:function(event)
{if(event.target!==this.contentElement)
return;if(!this.selectedTreeElement||event.shiftKey||event.metaKey||event.ctrlKey)
return;var handled=false;var nextSelectedElement;if(event.keyIdentifier==="Up"&&!event.altKey){handled=this.selectPrevious();}else if(event.keyIdentifier==="Down"&&!event.altKey){handled=this.selectNext();}else if(event.keyIdentifier==="Left"){if(this.selectedTreeElement.expanded){if(event.altKey)
this.selectedTreeElement.collapseRecursively();else
this.selectedTreeElement.collapse();handled=true;}else if(this.selectedTreeElement.parent&&!this.selectedTreeElement.parent.root){handled=true;if(this.selectedTreeElement.parent.selectable){nextSelectedElement=this.selectedTreeElement.parent;while(nextSelectedElement&&!nextSelectedElement.selectable)
nextSelectedElement=nextSelectedElement.parent;handled=nextSelectedElement?true:false;}else if(this.selectedTreeElement.parent)
this.selectedTreeElement.parent.collapse();}}else if(event.keyIdentifier==="Right"){if(!this.selectedTreeElement.revealed()){this.selectedTreeElement.reveal();handled=true;}else if(this.selectedTreeElement._expandable){handled=true;if(this.selectedTreeElement.expanded){nextSelectedElement=this.selectedTreeElement.firstChild();while(nextSelectedElement&&!nextSelectedElement.selectable)
nextSelectedElement=nextSelectedElement.nextSibling;handled=nextSelectedElement?true:false;}else{if(event.altKey)
this.selectedTreeElement.expandRecursively();else
this.selectedTreeElement.expand();}}}else if(event.keyCode===8||event.keyCode===46)
handled=this.selectedTreeElement.ondelete();else if(isEnterKey(event))
handled=this.selectedTreeElement.onenter();else if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Space.code)
handled=this.selectedTreeElement.onspace();if(nextSelectedElement){nextSelectedElement.reveal();nextSelectedElement.select(false,true);}
if(handled)
event.consume(true);},_deferredScrollIntoView:function(treeElement,center)
{if(!this._treeElementToScrollIntoView)
this.element.window().requestAnimationFrame(deferredScrollIntoView.bind(this));this._treeElementToScrollIntoView=treeElement;this._centerUponScrollIntoView=center;function deferredScrollIntoView()
{this._treeElementToScrollIntoView.listItemElement.scrollIntoViewIfNeeded(this._centerUponScrollIntoView);delete this._treeElementToScrollIntoView;delete this._centerUponScrollIntoView;}},__proto__:WebInspector.Object.prototype}
function TreeOutlineInShadow()
{TreeOutline.call(this);this.contentElement.classList.add("tree-outline");this.element=createElement("div");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/treeoutline.css");this._disclosureElement=this._shadowRoot.createChild("div","tree-outline-disclosure");this._disclosureElement.appendChild(this.contentElement);this._renderSelection=true;}
TreeOutlineInShadow.prototype={registerRequiredCSS:function(cssFile)
{WebInspector.appendStyle(this._shadowRoot,cssFile);},hideOverflow:function()
{this._disclosureElement.classList.add("tree-outline-disclosure-hide-overflow");},__proto__:TreeOutline.prototype}
function TreeElement(title,expandable)
{this.treeOutline=null;this.parent=null;this.previousSibling=null;this.nextSibling=null;this._listItemNode=createElement("li");this._listItemNode.treeElement=this;if(title)
this.title=title;this._listItemNode.addEventListener("mousedown",this._handleMouseDown.bind(this),false);this._listItemNode.addEventListener("selectstart",this._treeElementSelectStart.bind(this),false);this._listItemNode.addEventListener("click",this._treeElementToggled.bind(this),false);this._listItemNode.addEventListener("dblclick",this._handleDoubleClick.bind(this),false);this._childrenListNode=createElement("ol");this._childrenListNode.parentTreeElement=this;this._childrenListNode.classList.add("children");this._hidden=false;this._selectable=true;this.expanded=false;this.selected=false;this.setExpandable(expandable||false);this._collapsible=true;}
TreeElement._ArrowToggleWidth=10;TreeElement.prototype={hasAncestor:function(ancestor)
{if(!ancestor)
return false;var currentNode=this.parent;while(currentNode){if(ancestor===currentNode)
return true;currentNode=currentNode.parent;}
return false;},hasAncestorOrSelf:function(ancestor)
{return this===ancestor||this.hasAncestor(ancestor);},children:function()
{return this._children||[];},childCount:function()
{return this._children?this._children.length:0;},firstChild:function()
{return this._children?this._children[0]:null;},lastChild:function()
{return this._children?this._children[this._children.length-1]:null;},childAt:function(index)
{return this._children?this._children[index]:null;},indexOfChild:function(child)
{return this._children?this._children.indexOf(child):-1;},appendChild:function(child)
{if(!this._children)
this._children=[];var insertionIndex;if(this.treeOutline&&this.treeOutline._comparator)
insertionIndex=this._children.lowerBound(child,this.treeOutline._comparator);else
insertionIndex=this._children.length;this.insertChild(child,insertionIndex);},insertChild:function(child,index)
{if(!this._children)
this._children=[];if(!child)
throw"child can't be undefined or null";console.assert(!child.parent,"Attempting to insert a child that is already in the tree, reparenting is not supported.");var previousChild=(index>0?this._children[index-1]:null);if(previousChild){previousChild.nextSibling=child;child.previousSibling=previousChild;}else{child.previousSibling=null;}
var nextChild=this._children[index];if(nextChild){nextChild.previousSibling=child;child.nextSibling=nextChild;}else{child.nextSibling=null;}
this._children.splice(index,0,child);this.setExpandable(true);child.parent=this;if(this.treeOutline)
this.treeOutline._bindTreeElement(child);for(var current=child.firstChild();this.treeOutline&¤t;current=current.traverseNextTreeElement(false,child,true))
this.treeOutline._bindTreeElement(current);child.onattach();child._ensureSelection();if(this.treeOutline)
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementAttached,child);var nextSibling=child.nextSibling?child.nextSibling._listItemNode:null;this._childrenListNode.insertBefore(child._listItemNode,nextSibling);this._childrenListNode.insertBefore(child._childrenListNode,nextSibling);if(child.selected)
child.select();if(child.expanded)
child.expand();},removeChildAtIndex:function(childIndex)
{if(childIndex<0||childIndex>=this._children.length)
throw"childIndex out of range";var child=this._children[childIndex];this._children.splice(childIndex,1);var parent=child.parent;if(this.treeOutline&&this.treeOutline.selectedTreeElement&&this.treeOutline.selectedTreeElement.hasAncestorOrSelf(child)){if(child.nextSibling)
child.nextSibling.select(true);else if(child.previousSibling)
child.previousSibling.select(true);else if(parent)
parent.select(true);}
if(child.previousSibling)
child.previousSibling.nextSibling=child.nextSibling;if(child.nextSibling)
child.nextSibling.previousSibling=child.previousSibling;child.parent=null;if(this.treeOutline)
this.treeOutline._unbindTreeElement(child);for(var current=child.firstChild();this.treeOutline&¤t;current=current.traverseNextTreeElement(false,child,true))
this.treeOutline._unbindTreeElement(current);child._detach();},removeChild:function(child)
{if(!child)
throw"child can't be undefined or null";if(child.parent!==this)
return;var childIndex=this._children.indexOf(child);if(childIndex===-1)
throw"child not found in this node's children";this.removeChildAtIndex(childIndex);},removeChildren:function()
{if(!this.root&&this.treeOutline&&this.treeOutline.selectedTreeElement&&this.treeOutline.selectedTreeElement.hasAncestorOrSelf(this))
this.select(true);for(var i=0;this._children&&i<this._children.length;++i){var child=this._children[i];child.previousSibling=null
child.nextSibling=null;child.parent=null;if(this.treeOutline)
this.treeOutline._unbindTreeElement(child);for(var current=child.firstChild();this.treeOutline&¤t;current=current.traverseNextTreeElement(false,child,true))
this.treeOutline._unbindTreeElement(current);child._detach();}
this._children=[];},get selectable()
{if(this._hidden)
return false;return this._selectable;},set selectable(x)
{this._selectable=x;},get listItemElement()
{return this._listItemNode;},get childrenListElement()
{return this._childrenListNode;},get title()
{return this._title;},set title(x)
{if(this._title===x)
return;this._title=x;if(typeof x==="string"){this._titleElement=createElementWithClass("span","tree-element-title");this._titleElement.textContent=x;this.tooltip=x;}else{this._titleElement=x;this.tooltip="";}
this._listItemNode.removeChildren();if(this._iconElement)
this._listItemNode.appendChild(this._iconElement);this._listItemNode.appendChild(this._titleElement);this._ensureSelection();},titleAsText:function()
{if(!this._title)
return"";if(typeof this._title==="string")
return this._title;return this._title.textContent;},startEditingTitle:function(editingConfig)
{WebInspector.InplaceEditor.startEditing(this._titleElement,editingConfig);this.treeOutline._shadowRoot.getSelection().setBaseAndExtent(this._titleElement,0,this._titleElement,1);},createIcon()
{if(!this._iconElement){this._iconElement=createElementWithClass("div","icon");this._listItemNode.insertBefore(this._iconElement,this._listItemNode.firstChild);this._ensureSelection();}},get tooltip()
{return this._tooltip||"";},set tooltip(x)
{if(this._tooltip===x)
return;this._tooltip=x;this._listItemNode.title=x;},isExpandable:function()
{return this._expandable;},setExpandable:function(expandable)
{if(this._expandable===expandable)
return;this._expandable=expandable;this._listItemNode.classList.toggle("parent",expandable);if(!expandable)
this.collapse();},setCollapsible:function(collapsible)
{if(this._collapsible===collapsible)
return;this._collapsible=collapsible;this._listItemNode.classList.toggle("always-parent",!collapsible);if(!collapsible)
this.expand();},get hidden()
{return this._hidden;},set hidden(x)
{if(this._hidden===x)
return;this._hidden=x;this._listItemNode.classList.toggle("hidden",x);this._childrenListNode.classList.toggle("hidden",x);},invalidateChildren:function()
{if(this._children){this.removeChildren();this._children=null;}},_ensureSelection:function()
{if(!this.treeOutline||!this.treeOutline._renderSelection)
return;if(!this._selectionElement)
this._selectionElement=createElementWithClass("div","selection fill");this._listItemNode.insertBefore(this._selectionElement,this.listItemElement.firstChild);},_treeElementSelectStart:function(event)
{event.currentTarget._selectionStarted=true;},_treeElementToggled:function(event)
{var element=event.currentTarget;if(element._selectionStarted){delete element._selectionStarted;var selection=element.getComponentSelection();if(selection&&!selection.isCollapsed&&element.isSelfOrAncestor(selection.anchorNode)&&element.isSelfOrAncestor(selection.focusNode))
return;}
if(element.treeElement!==this)
return;var toggleOnClick=this.toggleOnClick&&!this.selectable;var isInTriangle=this.isEventWithinDisclosureTriangle(event);if(!toggleOnClick&&!isInTriangle)
return;if(event.target&&event.target.enclosingNodeOrSelfWithNodeName("a"))
return;if(this.expanded){if(event.altKey)
this.collapseRecursively();else
this.collapse();}else{if(event.altKey)
this.expandRecursively();else
this.expand();}
event.consume();},_handleMouseDown:function(event)
{var element=event.currentTarget;if(!element)
return;delete element._selectionStarted;if(!this.selectable)
return;if(element.treeElement!==this)
return;if(this.isEventWithinDisclosureTriangle(event))
return;this.selectOnMouseDown(event);},_handleDoubleClick:function(event)
{var element=event.currentTarget;if(!element||element.treeElement!==this)
return;var handled=this.ondblclick(event);if(handled)
return;if(this._expandable&&!this.expanded)
this.expand();},_detach:function()
{this._listItemNode.remove();this._childrenListNode.remove();},collapse:function()
{if(!this.expanded||!this._collapsible)
return;this._listItemNode.classList.remove("expanded");this._childrenListNode.classList.remove("expanded");this.expanded=false;this.oncollapse();if(this.treeOutline)
this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementCollapsed,this);},collapseRecursively:function()
{var item=this;while(item){if(item.expanded)
item.collapse();item=item.traverseNextTreeElement(false,this,true);}},expand:function()
{if(!this._expandable||(this.expanded&&this._children))
return;this.expanded=true;this._populateIfNeeded();this._listItemNode.classList.add("expanded");this._childrenListNode.classList.add("expanded");if(this.treeOutline){this.onexpand();this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementExpanded,this);}},expandRecursively:function(maxDepth)
{var item=this;var info={};var depth=0;if(isNaN(maxDepth))
maxDepth=3;while(item){if(depth<maxDepth)
item.expand();item=item.traverseNextTreeElement(false,this,(depth>=maxDepth),info);depth+=info.depthChange;}},reveal:function(center)
{var currentAncestor=this.parent;while(currentAncestor&&!currentAncestor.root){if(!currentAncestor.expanded)
currentAncestor.expand();currentAncestor=currentAncestor.parent;}
this.treeOutline._deferredScrollIntoView(this,!!center);},revealed:function()
{var currentAncestor=this.parent;while(currentAncestor&&!currentAncestor.root){if(!currentAncestor.expanded)
return false;currentAncestor=currentAncestor.parent;}
return true;},selectOnMouseDown:function(event)
{if(this.select(false,true))
event.consume(true);},select:function(omitFocus,selectedByUser)
{if(!this.treeOutline||!this.selectable||this.selected)
return false;if(this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.deselect();this.treeOutline.selectedTreeElement=null;if(this.treeOutline._rootElement===this)
return false;this.selected=true;if(!omitFocus)
this.treeOutline.focus();if(!this.treeOutline)
return false;this.treeOutline.selectedTreeElement=this;this._listItemNode.classList.add("selected");this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementSelected,this);return this.onselect(selectedByUser);},revealAndSelect:function(omitFocus)
{this.reveal(true);this.select(omitFocus);},deselect:function(supressOnDeselect)
{if(!this.treeOutline||this.treeOutline.selectedTreeElement!==this||!this.selected)
return;this.selected=false;this.treeOutline.selectedTreeElement=null;this._listItemNode.classList.remove("selected");},_populateIfNeeded:function()
{if(this.treeOutline&&this._expandable&&!this._children){this._children=[];this.onpopulate();}},onpopulate:function()
{},onenter:function()
{return false;},ondelete:function()
{return false;},onspace:function()
{return false;},onbind:function()
{},onunbind:function()
{},onattach:function()
{},onexpand:function()
{},oncollapse:function()
{},ondblclick:function(e)
{return false;},onselect:function(selectedByUser)
{return false;},traverseNextTreeElement:function(skipUnrevealed,stayWithin,dontPopulate,info)
{if(!dontPopulate)
this._populateIfNeeded();if(info)
info.depthChange=0;var element=skipUnrevealed?(this.revealed()?this.firstChild():null):this.firstChild();if(element&&(!skipUnrevealed||(skipUnrevealed&&this.expanded))){if(info)
info.depthChange=1;return element;}
if(this===stayWithin)
return null;element=skipUnrevealed?(this.revealed()?this.nextSibling:null):this.nextSibling;if(element)
return element;element=this;while(element&&!element.root&&!(skipUnrevealed?(element.revealed()?element.nextSibling:null):element.nextSibling)&&element.parent!==stayWithin){if(info)
info.depthChange-=1;element=element.parent;}
if(!element||element.root)
return null;return(skipUnrevealed?(element.revealed()?element.nextSibling:null):element.nextSibling);},traversePreviousTreeElement:function(skipUnrevealed,dontPopulate)
{var element=skipUnrevealed?(this.revealed()?this.previousSibling:null):this.previousSibling;if(!dontPopulate&&element)
element._populateIfNeeded();while(element&&(skipUnrevealed?(element.revealed()&&element.expanded?element.lastChild():null):element.lastChild())){if(!dontPopulate)
element._populateIfNeeded();element=(skipUnrevealed?(element.revealed()&&element.expanded?element.lastChild():null):element.lastChild());}
if(element)
return element;if(!this.parent||this.parent.root)
return null;return this.parent;},isEventWithinDisclosureTriangle:function(event)
{var paddingLeftValue=window.getComputedStyle(this._listItemNode).paddingLeft;console.assert(paddingLeftValue.endsWith("px"));var computedLeftPadding=parseFloat(paddingLeftValue);var left=this._listItemNode.totalOffsetLeft()+computedLeftPadding;return event.pageX>=left&&event.pageX<=left+TreeElement._ArrowToggleWidth&&this._expandable;}};WebInspector.Drawer=function(splitWidget)
{WebInspector.VBox.call(this);this.element.id="drawer-contents";this._splitWidget=splitWidget;splitWidget.hideDefaultResizer();splitWidget.setSidebarWidget(this);this.setMinimumSize(0,27);this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.element.id="drawer-tabbed-pane";this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);var toolbar=new WebInspector.Toolbar("drawer-close-toolbar");var closeButton=new WebInspector.ToolbarButton(WebInspector.UIString("Close drawer"),"delete-toolbar-item");closeButton.addEventListener("click",this.closeDrawer.bind(this));toolbar.appendToolbarItem(closeButton);this._tabbedPane.appendAfterTabStrip(toolbar.element);this._extensibleTabbedPaneController=new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane,"drawer-view");this._extensibleTabbedPaneController.enableMoreTabsButton();splitWidget.installResizer(this._tabbedPane.headerElement());this._lastSelectedViewSetting=WebInspector.settings.createSetting("WebInspector.Drawer.lastSelectedView","console");this._tabbedPane.show(this.element);}
WebInspector.Drawer.prototype={showView:function(id,immediate)
{this._innerShow(immediate);WebInspector.userMetrics.drawerShown(id);return this._extensibleTabbedPaneController.showTab(id);},showDrawer:function()
{this._innerShow();},wasShown:function()
{var id=this._lastSelectedViewSetting.get();if(!this._firstTabSelected&&this._tabbedPane.hasTab(id))
this.showView(id);},willHide:function()
{},_innerShow:function(immediate)
{if(this.isShowing())
return;this._splitWidget.showBoth(!immediate);if(this._visibleView())
this._visibleView().focus();},closeDrawer:function()
{if(!this.isShowing())
return;WebInspector.restoreFocusFromElement(this.element);this._splitWidget.hideSidebar(true);},_visibleView:function()
{return this._tabbedPane.visibleView;},_tabSelected:function(event)
{this._firstTabSelected=true;var tabId=this._tabbedPane.selectedTabId;if(tabId&&event.data["isUserGesture"])
this._lastSelectedViewSetting.set(tabId);},selectedViewId:function()
{return this._tabbedPane.selectedTabId;},initialPanelShown:function()
{this._initialPanelWasShown=true;},__proto__:WebInspector.VBox.prototype};WebInspector.InspectorView=function()
{WebInspector.VBox.call(this);WebInspector.Dialog.setModalHostView(this);WebInspector.GlassPane.DefaultFocusedViewStack.push(this);this.setMinimumSize(240,72);this._drawerSplitWidget=new WebInspector.SplitWidget(false,true,"Inspector.drawerSplitViewState",200,200);this._drawerSplitWidget.hideSidebar();this._drawerSplitWidget.enableShowModeSaving();this._drawerSplitWidget.show(this.element);this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.registerRequiredCSS("ui/inspectorViewTabbedPane.css");this._tabbedPane.element.classList.add("inspector-view-tabbed-pane");this._tabbedPane.setTabSlider(true);this._tabbedPane.setAllowTabReorder(true,false);this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabOrderChanged,this._persistPanelOrder,this);this._tabOrderSetting=WebInspector.settings.createSetting("InspectorView.panelOrder",{});this._drawerSplitWidget.setMainWidget(this._tabbedPane);this._drawer=new WebInspector.Drawer(this._drawerSplitWidget);this._panels={};WebInspector["panels"]=this._panels;this._history=[];this._historyIterator=-1;this._keyDownBound=this._keyDown.bind(this);this._keyPressBound=this._keyPress.bind(this);this._panelDescriptors={};this._panelPromises={};this._openBracketIdentifiers=["U+005B","U+00DB"].keySet();this._closeBracketIdentifiers=["U+005D","U+00DD"].keySet();this._lastActivePanelSetting=WebInspector.settings.createSetting("lastActivePanel","elements");InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ShowPanel,showPanel.bind(this));this._loadPanelDesciptors();function showPanel(event)
{var panelName=(event.data);this.showPanel(panelName);}};WebInspector.InspectorView.prototype={wasShown:function()
{this.element.ownerDocument.addEventListener("keydown",this._keyDownBound,false);this.element.ownerDocument.addEventListener("keypress",this._keyPressBound,false);},willHide:function()
{this.element.ownerDocument.removeEventListener("keydown",this._keyDownBound,false);this.element.ownerDocument.removeEventListener("keypress",this._keyPressBound,false);},_loadPanelDesciptors:function()
{function processPanelExtensions(extension)
{var descriptor=new WebInspector.RuntimeExtensionPanelDescriptor(extension);var weight=this._tabOrderSetting.get()[descriptor.name()];if(weight===undefined)
weight=extension.descriptor()["order"];if(weight===undefined)
weight=10000;panelWeights.set(descriptor,weight);}
function orderComparator(left,right)
{return panelWeights.get(left)>panelWeights.get(right);}
WebInspector.startBatchUpdate();var panelWeights=new Map();self.runtime.extensions(WebInspector.PanelFactory).forEach(processPanelExtensions.bind(this));var sortedPanels=panelWeights.keysArray().sort(orderComparator);for(var panelDescriptor of sortedPanels)
this._innerAddPanel(panelDescriptor);WebInspector.endBatchUpdate();},createToolbars:function()
{this._leftToolbar=new WebInspector.ExtensibleToolbar("main-toolbar-left");this._leftToolbar.element.classList.add("inspector-view-toolbar","inspector-view-toolbar-left");this._tabbedPane.insertBeforeTabStrip(this._leftToolbar.element);var rightToolbarContainer=createElementWithClass("div","hbox flex-none flex-centered");this._tabbedPane.appendAfterTabStrip(rightToolbarContainer);this._rightToolbar=new WebInspector.ExtensibleToolbar("main-toolbar-right");this._rightToolbar.element.classList.add("inspector-view-toolbar","flex-none");rightToolbarContainer.appendChild(this._rightToolbar.element);},_innerAddPanel:function(panelDescriptor,index)
{var panelName=panelDescriptor.name();this._panelDescriptors[panelName]=panelDescriptor;this._tabbedPane.appendTab(panelName,panelDescriptor.title(),new WebInspector.Widget(),undefined,undefined,undefined,index);if(this._lastActivePanelSetting.get()===panelName)
this._tabbedPane.selectTab(panelName);},addPanel:function(panelDescriptor)
{var weight=this._tabOrderSetting.get()[panelDescriptor.name()];if(weight)
weight=Math.max(0,Math.round(weight/10)-1);this._innerAddPanel(panelDescriptor,weight);},hasPanel:function(panelName)
{return!!this._panelDescriptors[panelName];},panel:function(panelName)
{var panelDescriptor=this._panelDescriptors[panelName];if(!panelDescriptor)
return Promise.reject(new Error("Can't load panel without the descriptor: "+panelName));var promise=this._panelPromises[panelName];if(promise)
return promise;promise=panelDescriptor.panel();this._panelPromises[panelName]=promise;promise.then(cachePanel.bind(this));function cachePanel(panel)
{delete this._panelPromises[panelName];this._panels[panelName]=panel;return panel;}
return promise;},onSuspendStateChanged:function(allTargetsSuspended)
{this._currentPanelLocked=allTargetsSuspended;this._tabbedPane.setCurrentTabLocked(this._currentPanelLocked);if(this._leftToolbar)
this._leftToolbar.setEnabled(!this._currentPanelLocked);if(this._rightToolbar)
this._rightToolbar.setEnabled(!this._currentPanelLocked);},showPanel:function(panelName)
{if(this._currentPanelLocked){if(this._currentPanel!==this._panels[panelName])
return Promise.reject(new Error("Current panel locked"));return Promise.resolve(this._currentPanel);}
this._panelForShowPromise=this.panel(panelName);return this._panelForShowPromise.then(setCurrentPanelIfNecessary.bind(this,this._panelForShowPromise));function setCurrentPanelIfNecessary(panelPromise,panel)
{if(this._panelForShowPromise!==panelPromise)
return null;this.setCurrentPanel(panel);return panel;}},setPanelIcon:function(panelName,iconType,iconTooltip)
{this._tabbedPane.setTabIcon(panelName,iconType,iconTooltip);},currentPanel:function()
{return this._currentPanel;},showInitialPanel:function()
{if(InspectorFrontendHost.isUnderTest())
return;this._showInitialPanel();},_showInitialPanel:function()
{this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._tabSelected();this._drawer.initialPanelShown();},showInitialPanelForTest:function(panelName)
{this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this.setCurrentPanel(this._panels[panelName]);this._drawer.initialPanelShown();},_tabSelected:function()
{var panelName=this._tabbedPane.selectedTabId;if(!panelName)
return;this.showPanel(panelName);},setCurrentPanel:function(panel,suppressBringToFront)
{delete this._panelForShowPromise;if(this._currentPanelLocked)
return this._currentPanel;if(!suppressBringToFront)
InspectorFrontendHost.bringToFront();if(this._currentPanel===panel)
return panel;this._currentPanel=panel;if(!this._panels[panel.name])
this._panels[panel.name]=panel;this._tabbedPane.changeTabView(panel.name,panel);this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._tabbedPane.selectTab(panel.name);this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._lastActivePanelSetting.set(panel.name);this._pushToHistory(panel.name);WebInspector.userMetrics.panelShown(panel.name);panel.focus();return panel;},showDrawer:function()
{this._drawer.showDrawer();},drawerVisible:function()
{return this._drawer.isShowing();},showViewInDrawer:function(id,immediate)
{return this._drawer.showView(id,immediate);},selectedViewInDrawer:function()
{return this._drawer.selectedViewId();},closeDrawer:function()
{this._drawer.closeDrawer();},setDrawerMinimized:function(minimized)
{this._drawerSplitWidget.setSidebarMinimized(minimized);this._drawerSplitWidget.setResizable(!minimized);},isDrawerMinimized:function()
{return this._drawerSplitWidget.isSidebarMinimized();},defaultFocusedElement:function()
{return this._currentPanel?this._currentPanel.defaultFocusedElement():null;},_keyPress:function(event)
{if(event.charCode<32&&WebInspector.isWin())
return;clearTimeout(this._keyDownTimer);delete this._keyDownTimer;},_keyDown:function(event)
{if(!WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event))
return;var keyboardEvent=(event);var panelShortcutEnabled=WebInspector.moduleSetting("shortcutPanelSwitch").get();if(panelShortcutEnabled&&!event.shiftKey&&!event.altKey){var panelIndex=-1;if(event.keyCode>0x30&&event.keyCode<0x3A)
panelIndex=event.keyCode-0x31;else if(event.keyCode>0x60&&event.keyCode<0x6A&&keyboardEvent.location===KeyboardEvent.DOM_KEY_LOCATION_NUMPAD)
panelIndex=event.keyCode-0x61;if(panelIndex!==-1){var panelName=this._tabbedPane.allTabs()[panelIndex];if(panelName){if(!WebInspector.Dialog.hasInstance()&&!this._currentPanelLocked)
this.showPanel(panelName);event.consume(true);}
return;}}
if(!WebInspector.isWin()||(!this._openBracketIdentifiers[event.keyIdentifier]&&!this._closeBracketIdentifiers[event.keyIdentifier])){this._keyDownInternal(event);return;}
this._keyDownTimer=setTimeout(this._keyDownInternal.bind(this,event),0);},_keyDownInternal:function(event)
{if(this._currentPanelLocked)
return;var direction=0;if(this._openBracketIdentifiers[event.keyIdentifier])
direction=-1;if(this._closeBracketIdentifiers[event.keyIdentifier])
direction=1;if(!direction)
return;if(!event.shiftKey&&!event.altKey){if(!WebInspector.Dialog.hasInstance())
this._changePanelInDirection(direction);event.consume(true);return;}
if(event.altKey&&this._moveInHistory(direction))
event.consume(true);},_changePanelInDirection:function(direction)
{var panelOrder=this._tabbedPane.allTabs();var index=panelOrder.indexOf(this.currentPanel().name);index=(index+panelOrder.length+direction)%panelOrder.length;this.showPanel(panelOrder[index]);},_moveInHistory:function(move)
{var newIndex=this._historyIterator+move;if(newIndex>=this._history.length||newIndex<0)
return false;this._inHistory=true;this._historyIterator=newIndex;if(!WebInspector.Dialog.hasInstance())
this.setCurrentPanel(this._panels[this._history[this._historyIterator]]);delete this._inHistory;return true;},_pushToHistory:function(panelName)
{if(this._inHistory)
return;this._history.splice(this._historyIterator+1,this._history.length-this._historyIterator-1);if(!this._history.length||this._history[this._history.length-1]!==panelName)
this._history.push(panelName);this._historyIterator=this._history.length-1;},onResize:function()
{WebInspector.Dialog.modalHostRepositioned();},topResizerElement:function()
{return this._tabbedPane.headerElement();},toolbarItemResized:function()
{this._tabbedPane.headerResized();},_persistPanelOrder:function(event)
{var tabs=(event.data);var tabOrders=this._tabOrderSetting.get();for(var i=0;i<tabs.length;i++)
tabOrders[tabs[i].id]=(i+1)*10;this._tabOrderSetting.set(tabOrders);},setOwnerSplit:function(splitWidget)
{this._ownerSplitWidget=splitWidget;},minimize:function()
{if(this._ownerSplitWidget)
this._ownerSplitWidget.setSidebarMinimized(true);},restore:function()
{if(this._ownerSplitWidget)
this._ownerSplitWidget.setSidebarMinimized(false);},__proto__:WebInspector.VBox.prototype};WebInspector.inspectorView;WebInspector.InspectorView.DrawerToggleActionDelegate=function()
{}
WebInspector.InspectorView.DrawerToggleActionDelegate.prototype={handleAction:function(context,actionId)
{if(WebInspector.inspectorView.drawerVisible())
WebInspector.inspectorView.closeDrawer();else
WebInspector.inspectorView.showDrawer();return true;}};WebInspector.ActionRegistry=function()
{this._actionsById=new Map();this._registerActions();}
WebInspector.ActionRegistry.prototype={_registerActions:function()
{self.runtime.extensions(WebInspector.ActionDelegate).forEach(registerExtension,this);function registerExtension(extension)
{var actionId=extension.descriptor()["actionId"];console.assert(actionId);console.assert(!this._actionsById.get(actionId));this._actionsById.set(actionId,new WebInspector.Action(extension));}},availableActions:function()
{return this.applicableActions(this._actionsById.keysArray(),WebInspector.context);},applicableActions:function(actionIds,context)
{var extensions=[];actionIds.forEach(function(actionId){var action=this._actionsById.get(actionId);if(action)
extensions.push(action._extension);},this);return context.applicableExtensions(extensions).valuesArray().map(extensionToAction.bind(this));function extensionToAction(extension)
{return(this.action(extension.descriptor()["actionId"]));}},action:function(actionId)
{return this._actionsById.get(actionId)||null;}}
WebInspector.Action=function(extension)
{WebInspector.Object.call(this);this._extension=extension;this._enabled=true;this._toggled=false;}
WebInspector.Action.Events={Enabled:"Enabled",Toggled:"Toggled"}
WebInspector.Action.prototype={id:function()
{return this._extension.descriptor()["actionId"];},execute:function()
{return this._extension.instancePromise().then(handleAction.bind(this));function handleAction(actionDelegate)
{var actionId=this._extension.descriptor()["actionId"];var delegate=(actionDelegate);return delegate.handleAction(WebInspector.context,actionId);}},icon:function()
{return this._extension.descriptor()["iconClass"]||"";},setEnabled:function(enabled)
{if(this._enabled===enabled)
return;this._enabled=enabled;this.dispatchEventToListeners(WebInspector.Action.Events.Enabled,enabled);},enabled:function()
{return this._enabled;},category:function()
{return this._extension.descriptor()["category"]||"";},tags:function()
{return this._extension.descriptor()["tags"]||"";},title:function()
{var title=this._extension.title(WebInspector.platform());var options=this._extension.descriptor()["options"];if(options){for(var pair of options){if(pair["value"]!==this._toggled)
title=pair["title"];}}
return title;},toggled:function()
{return this._toggled;},setToggled:function(toggled)
{if(this._toggled===toggled)
return;this._toggled=toggled;this.dispatchEventToListeners(WebInspector.Action.Events.Toggled,toggled);},__proto__:WebInspector.Object.prototype}
WebInspector.ActionDelegate=function()
{}
WebInspector.ActionDelegate.prototype={handleAction:function(context,actionId){}}
WebInspector.actionRegistry;;WebInspector.ShortcutRegistry=function(actionRegistry,document)
{this._actionRegistry=actionRegistry;this._defaultKeyToActions=new Multimap();this._defaultActionToShortcut=new Multimap();this._registerBindings(document);}
WebInspector.ShortcutRegistry.prototype={_applicableActions:function(key)
{return this._actionRegistry.applicableActions(this._defaultActionsForKey(key).valuesArray(),WebInspector.context);},_defaultActionsForKey:function(key)
{return this._defaultKeyToActions.get(String(key));},shortcutDescriptorsForAction:function(actionId)
{return this._defaultActionToShortcut.get(actionId).valuesArray();},keysForActions:function(actionIds)
{var result=[];for(var i=0;i<actionIds.length;++i){var descriptors=this.shortcutDescriptorsForAction(actionIds[i]);for(var j=0;j<descriptors.length;++j)
result.push(descriptors[j].key);}
return result;},shortcutTitleForAction:function(actionId)
{var descriptors=this.shortcutDescriptorsForAction(actionId);if(descriptors.length)
return descriptors[0].name;},handleShortcut:function(event)
{this.handleKey(WebInspector.KeyboardShortcut.makeKeyFromEvent(event),event.keyIdentifier,event);},handleKey:function(key,keyIdentifier,event)
{var keyModifiers=key>>8;var actions=this._applicableActions(key);if(!actions.length)
return;if(WebInspector.GlassPane.DefaultFocusedViewStack.length>1){if(event&&!isPossiblyInputKey())
event.consume(true);return;}
if(!isPossiblyInputKey()){if(event)
event.consume(true);processNextAction.call(this,false);}else{this._pendingActionTimer=setTimeout(processNextAction.bind(this,false),0);}
function processNextAction(handled)
{delete this._pendingActionTimer;var action=actions.shift();if(!action||handled)
return;action.execute().then(processNextAction.bind(this));}
function isPossiblyInputKey()
{if(!event||!WebInspector.isEditing()||/^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier))
return false;if(!keyModifiers)
return true;var modifiers=WebInspector.KeyboardShortcut.Modifiers;if((keyModifiers&(modifiers.Ctrl|modifiers.Alt))===(modifiers.Ctrl|modifiers.Alt))
return WebInspector.isWin();return!hasModifier(modifiers.Ctrl)&&!hasModifier(modifiers.Alt)&&!hasModifier(modifiers.Meta);}
function hasModifier(mod)
{return!!(keyModifiers&mod);}},registerShortcut:function(actionId,shortcut)
{var descriptor=WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut(shortcut);if(!descriptor)
return;this._defaultActionToShortcut.set(actionId,descriptor);this._defaultKeyToActions.set(String(descriptor.key),actionId);},dismissPendingShortcutAction:function()
{if(this._pendingActionTimer){clearTimeout(this._pendingActionTimer);delete this._pendingActionTimer;}},_registerBindings:function(document)
{document.addEventListener("input",this.dismissPendingShortcutAction.bind(this),true);var extensions=self.runtime.extensions(WebInspector.ActionDelegate);extensions.forEach(registerExtension,this);function registerExtension(extension)
{var descriptor=extension.descriptor();var bindings=descriptor["bindings"];for(var i=0;bindings&&i<bindings.length;++i){if(!platformMatches(bindings[i].platform))
continue;var shortcuts=bindings[i]["shortcut"].split(/\s+/);shortcuts.forEach(this.registerShortcut.bind(this,descriptor["actionId"]));}}
function platformMatches(platformsString)
{if(!platformsString)
return true;var platforms=platformsString.split(",");var isMatch=false;var currentPlatform=WebInspector.platform();for(var i=0;!isMatch&&i<platforms.length;++i)
isMatch=platforms[i]===currentPlatform;return isMatch;}}}
WebInspector.ShortcutRegistry.ForwardedShortcut=function()
{}
WebInspector.ShortcutRegistry.ForwardedShortcut.instance=new WebInspector.ShortcutRegistry.ForwardedShortcut();WebInspector.shortcutRegistry;;WebInspector.ColorSwatch=function()
{}
WebInspector.ColorSwatch.create=function()
{if(!WebInspector.ColorSwatch._constructor)
WebInspector.ColorSwatch._constructor=registerCustomElement("span","color-swatch",WebInspector.ColorSwatch.prototype);return(new WebInspector.ColorSwatch._constructor());}
WebInspector.ColorSwatch.prototype={color:function()
{return this._color;},setColorText:function(colorText)
{this._color=WebInspector.Color.parse(colorText);console.assert(this._color,"Color text could not be parsed.");this._format=this._color.format();this._colorValueElement.textContent=this._color.asString(this._format);this._swatchInner.style.backgroundColor=colorText;},format:function()
{return this._format;},setFormat:function(format)
{this._format=format;this._colorValueElement.textContent=this._color.asString(this._format);},toggleNextFormat:function()
{do{this._format=WebInspector.ColorSwatch._nextColorFormat(this._color,this._format);var currentValue=this._color.asString(this._format);}while(currentValue===this._colorValueElement.textContent);this._colorValueElement.textContent=currentValue;},iconElement:function()
{return this._iconElement;},createdCallback:function()
{var root=WebInspector.createShadowRootWithCoreStyles(this,"ui/colorSwatch.css");this._iconElement=root.createChild("span","color-swatch");this._iconElement.title=WebInspector.UIString("Shift-click to change color format");this._swatchInner=this._iconElement.createChild("span","color-swatch-inner");this._swatchInner.addEventListener("dblclick",consumeEvent,false);this._swatchInner.addEventListener("mousedown",consumeEvent,false);this._swatchInner.addEventListener("click",this._handleClick.bind(this),true);root.createChild("content");this._colorValueElement=this.createChild("span");this.setColorText("white");},_handleClick:function(event)
{if(!event.shiftKey)
return;event.target.parentNode.parentNode.host.toggleNextFormat();event.consume(true);},__proto__:HTMLSpanElement.prototype}
WebInspector.ColorSwatch._nextColorFormat=function(color,curFormat)
{var cf=WebInspector.Color.Format;switch(curFormat){case cf.Original:return!color.hasAlpha()?cf.RGB:cf.RGBA;case cf.RGB:case cf.RGBA:return!color.hasAlpha()?cf.HSL:cf.HSLA;case cf.HSL:case cf.HSLA:if(color.nickname())
return cf.Nickname;return color.detectHEXFormat();case cf.ShortHEX:return cf.HEX;case cf.ShortHEXA:return cf.HEXA;case cf.HEXA:case cf.HEX:return cf.Original;case cf.Nickname:return color.detectHEXFormat();default:return cf.RGBA;}};WebInspector.Context=function()
{this._flavors=new Map();this._eventDispatchers=new Map();}
WebInspector.Context.Events={FlavorChanged:"FlavorChanged"}
WebInspector.Context.prototype={setFlavor:function(flavorType,flavorValue)
{var value=this._flavors.get(flavorType)||null;if(value===flavorValue)
return;if(flavorValue)
this._flavors.set(flavorType,flavorValue);else
this._flavors.remove(flavorType);this._dispatchFlavorChange(flavorType,flavorValue);},_dispatchFlavorChange:function(flavorType,flavorValue)
{var dispatcher=this._eventDispatchers.get(flavorType);if(!dispatcher)
return;dispatcher.dispatchEventToListeners(WebInspector.Context.Events.FlavorChanged,flavorValue);},addFlavorChangeListener:function(flavorType,listener,thisObject)
{var dispatcher=this._eventDispatchers.get(flavorType);if(!dispatcher){dispatcher=new WebInspector.Object();this._eventDispatchers.set(flavorType,dispatcher);}
dispatcher.addEventListener(WebInspector.Context.Events.FlavorChanged,listener,thisObject);},removeFlavorChangeListener:function(flavorType,listener,thisObject)
{var dispatcher=this._eventDispatchers.get(flavorType);if(!dispatcher)
return;dispatcher.removeEventListener(WebInspector.Context.Events.FlavorChanged,listener,thisObject);if(!dispatcher.hasEventListeners(WebInspector.Context.Events.FlavorChanged))
this._eventDispatchers.remove(flavorType);},flavor:function(flavorType)
{return this._flavors.get(flavorType)||null;},flavors:function()
{return new Set(this._flavors.keys());},applicableExtensions:function(extensions)
{var targetExtensionSet=new Set();var availableFlavors=this.flavors();extensions.forEach(function(extension){if(self.runtime.isExtensionApplicableToContextTypes(extension,availableFlavors))
targetExtensionSet.add(extension);});return targetExtensionSet;}}
WebInspector.context=new WebInspector.Context();;WebInspector.ContextMenuItem=function(topLevelMenu,type,label,disabled,checked)
{this._type=type;this._label=label;this._disabled=disabled;this._checked=checked;this._contextMenu=topLevelMenu;if(type==="item"||type==="checkbox")
this._id=topLevelMenu._nextId();}
WebInspector.ContextMenuItem.prototype={id:function()
{return this._id;},type:function()
{return this._type;},isEnabled:function()
{return!this._disabled;},setEnabled:function(enabled)
{this._disabled=!enabled;},_buildDescriptor:function()
{switch(this._type){case"item":var result={type:"item",id:this._id,label:this._label,enabled:!this._disabled};if(this._customElement)
result.element=this._customElement;if(this._shortcut)
result.shortcut=this._shortcut;return result;case"separator":return{type:"separator"};case"checkbox":return{type:"checkbox",id:this._id,label:this._label,checked:!!this._checked,enabled:!this._disabled};}
throw new Error("Invalid item type:"+this._type);},setShortcut:function(shortcut)
{this._shortcut=shortcut;}}
WebInspector.ContextSubMenuItem=function(topLevelMenu,label,disabled)
{WebInspector.ContextMenuItem.call(this,topLevelMenu,"subMenu",label,disabled);this._items=[];}
WebInspector.ContextSubMenuItem.prototype={appendItem:function(label,handler,disabled)
{var item=new WebInspector.ContextMenuItem(this._contextMenu,"item",label,disabled);this._pushItem(item);this._contextMenu._setHandler(item.id(),handler);return item;},appendCustomItem:function(element)
{var item=new WebInspector.ContextMenuItem(this._contextMenu,"item","<custom>");item._customElement=element;this._pushItem(item);return item;},appendAction:function(actionId,label)
{var action=WebInspector.actionRegistry.action(actionId);if(!label)
label=action.title();var result=this.appendItem(label,action.execute.bind(action));var shortcut=WebInspector.shortcutRegistry.shortcutTitleForAction(actionId);if(shortcut)
result.setShortcut(shortcut);return result;},appendSubMenuItem:function(label,disabled)
{var item=new WebInspector.ContextSubMenuItem(this._contextMenu,label,disabled);this._pushItem(item);return item;},appendCheckboxItem:function(label,handler,checked,disabled)
{var item=new WebInspector.ContextMenuItem(this._contextMenu,"checkbox",label,disabled,checked);this._pushItem(item);this._contextMenu._setHandler(item.id(),handler);return item;},appendSeparator:function()
{if(this._items.length)
this._pendingSeparator=true;},_pushItem:function(item)
{if(this._pendingSeparator){this._items.push(new WebInspector.ContextMenuItem(this._contextMenu,"separator"));delete this._pendingSeparator;}
this._items.push(item);},isEmpty:function()
{return!this._items.length;},_buildDescriptor:function()
{var result={type:"subMenu",label:this._label,enabled:!this._disabled,subItems:[]};for(var i=0;i<this._items.length;++i)
result.subItems.push(this._items[i]._buildDescriptor());return result;},appendItemsAtLocation:function(location)
{function appendExtension(menu,extension)
{var subMenuId=extension.descriptor()["subMenuId"];if(subMenuId){var subMenuItem=menu.appendSubMenuItem(extension.title(WebInspector.platform()));subMenuItem.appendItemsAtLocation(subMenuId);}else{menu.appendAction(extension.descriptor()["actionId"]);}}
var groupWeights=["new","open","clipboard","navigate","footer"];var groups=new Map();var extensions=self.runtime.extensions("context-menu-item");for(var extension of extensions){var itemLocation=extension.descriptor()["location"]||"";if(!itemLocation.startsWith(location+"/"))
continue;var itemGroup=itemLocation.substr(location.length+1);if(!itemGroup||itemGroup.includes("/"))
continue;var group=groups.get(itemGroup);if(!group){group=[];groups.set(itemGroup,group);if(groupWeights.indexOf(itemGroup)===-1)
groupWeights.splice(4,0,itemGroup);}
group.push(extension);}
for(var groupName of groupWeights){var group=groups.get(groupName);if(!group)
continue;group.forEach(appendExtension.bind(null,this));this.appendSeparator();}},__proto__:WebInspector.ContextMenuItem.prototype}
WebInspector.ContextMenu=function(event,useSoftMenu,x,y)
{WebInspector.ContextSubMenuItem.call(this,this,"");this._pendingPromises=[];this._pendingTargets=[];this._event=event;this._useSoftMenu=!!useSoftMenu;this._x=x===undefined?event.x:x;this._y=y===undefined?event.y:y;this._handlers={};this._id=0;}
WebInspector.ContextMenu.initialize=function()
{InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetUseSoftMenu,setUseSoftMenu);function setUseSoftMenu(event)
{WebInspector.ContextMenu._useSoftMenu=(event.data);}}
WebInspector.ContextMenu.installHandler=function(doc)
{doc.body.addEventListener("contextmenu",handler,false);function handler(event)
{var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems((event.deepElementFromPoint()));contextMenu.show();}}
WebInspector.ContextMenu.prototype={_nextId:function()
{return this._id++;},beforeShow:function(callback)
{this._beforeShow=callback;},show:function()
{Promise.all(this._pendingPromises).then(populate.bind(this)).then(this._innerShow.bind(this));WebInspector.ContextMenu._pendingMenu=this;function populate(appendCallResults)
{if(WebInspector.ContextMenu._pendingMenu!==this)
return;delete WebInspector.ContextMenu._pendingMenu;for(var i=0;i<appendCallResults.length;++i){var providers=appendCallResults[i];var target=this._pendingTargets[i];for(var j=0;j<providers.length;++j){var provider=(providers[j]);this.appendSeparator();provider.appendApplicableItems(this._event,this,target);this.appendSeparator();}}
this._pendingPromises=[];this._pendingTargets=[];}
this._event.consume(true);},discard:function()
{if(this._softMenu)
this._softMenu.discard();},_innerShow:function()
{if(typeof this._beforeShow==="function"){this._beforeShow();delete this._beforeShow;}
var menuObject=this._buildDescriptors();WebInspector._contextMenu=this;if(this._useSoftMenu||WebInspector.ContextMenu._useSoftMenu||InspectorFrontendHost.isHostedMode()){this._softMenu=new WebInspector.SoftContextMenu(menuObject,this._itemSelected.bind(this));this._softMenu.show(this._event.target.ownerDocument,this._x,this._y);}else{InspectorFrontendHost.showContextMenuAtPoint(this._x,this._y,menuObject,this._event.target.ownerDocument);function listenToEvents()
{InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ContextMenuCleared,this._menuCleared,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ContextMenuItemSelected,this._onItemSelected,this);}
setImmediate(listenToEvents.bind(this));}},_setHandler:function(id,handler)
{if(handler)
this._handlers[id]=handler;},_buildDescriptors:function()
{var result=[];for(var i=0;i<this._items.length;++i)
result.push(this._items[i]._buildDescriptor());return result;},_onItemSelected:function(event)
{this._itemSelected((event.data));},_itemSelected:function(id)
{if(this._handlers[id])
this._handlers[id].call(this);this._menuCleared();},_menuCleared:function()
{InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.ContextMenuCleared,this._menuCleared,this);InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.ContextMenuItemSelected,this._onItemSelected,this);},appendApplicableItems:function(target)
{this._pendingPromises.push(self.runtime.instancesPromise(WebInspector.ContextMenu.Provider,target));this._pendingTargets.push(target);},__proto__:WebInspector.ContextSubMenuItem.prototype}
WebInspector.ContextMenu.Provider=function(){}
WebInspector.ContextMenu.Provider.prototype={appendApplicableItems:function(event,contextMenu,target){}};WebInspector.Dialog=function()
{WebInspector.Widget.call(this,true);this.markAsRoot();this.registerRequiredCSS("ui/dialog.css");this.contentElement.createChild("content");this.contentElement.tabIndex=0;this.contentElement.addEventListener("focus",this._onFocus.bind(this),false);this.contentElement.addEventListener("keydown",this._onKeyDown.bind(this),false);this._wrapsContent=false;this._dimmed=false;this._tabIndexMap=new Map();}
WebInspector.Dialog.hasInstance=function()
{return!!WebInspector.Dialog._instance;}
WebInspector.Dialog.prototype={show:function()
{if(WebInspector.Dialog._instance)
WebInspector.Dialog._instance.detach();WebInspector.Dialog._instance=this;var document=(WebInspector.Dialog._modalHostView.element.ownerDocument);this._disableTabIndexOnElements(document);this._glassPane=new WebInspector.GlassPane(document,this._dimmed);this._glassPane.element.addEventListener("click",this._onGlassPaneClick.bind(this),false);WebInspector.GlassPane.DefaultFocusedViewStack.push(this);WebInspector.Widget.prototype.show.call(this,this._glassPane.element);this._position();this.focus();},detach:function()
{WebInspector.Widget.prototype.detach.call(this);WebInspector.GlassPane.DefaultFocusedViewStack.pop();this._glassPane.dispose();delete this._glassPane;this._restoreTabIndexOnElements();delete WebInspector.Dialog._instance;},addCloseButton:function()
{var closeButton=this.contentElement.createChild("div","dialog-close-button","dt-close-button");closeButton.gray=true;closeButton.addEventListener("click",this.detach.bind(this,false),false);},setPosition:function(positionX,positionY)
{this._defaultPositionX=positionX;this._defaultPositionY=positionY;},setMaxSize:function(size)
{this._maxSize=size;},setWrapsContent:function(wraps)
{this.element.classList.toggle("wraps-content",wraps);this._wrapsContent=wraps;},setDimmed:function(dimmed)
{this._dimmed=dimmed;},contentResized:function()
{if(this._wrapsContent)
this._position();},_disableTabIndexOnElements:function(document)
{this._tabIndexMap.clear();for(var node=document;node;node=node.traverseNextNode(document)){if(node instanceof HTMLElement){var element=(node);var tabIndex=element.tabIndex;if(tabIndex>=0){this._tabIndexMap.set(element,tabIndex);element.tabIndex=-1;}}}},_restoreTabIndexOnElements:function()
{for(var element of this._tabIndexMap.keys())
element.tabIndex=(this._tabIndexMap.get(element));this._tabIndexMap.clear();},_onFocus:function(event)
{this.focus();},_onGlassPaneClick:function(event)
{if(!this.element.isSelfOrAncestor((event.target)))
this.detach();},_position:function()
{var container=WebInspector.Dialog._modalHostView.element;var width=container.offsetWidth-10;var height=container.offsetHeight-10;if(this._wrapsContent){width=Math.min(width,this.contentElement.offsetWidth);height=Math.min(height,this.contentElement.offsetHeight);}
if(this._maxSize){width=Math.min(width,this._maxSize.width);height=Math.min(height,this._maxSize.height);}
var positionX;if(typeof this._defaultPositionX==="number"){positionX=this._defaultPositionX;}else{positionX=(container.offsetWidth-width)/2;positionX=Number.constrain(positionX,0,container.offsetWidth-width);}
var positionY;if(typeof this._defaultPositionY==="number"){positionY=this._defaultPositionY;}else{positionY=(container.offsetHeight-height)/2;positionY=Number.constrain(positionY,0,container.offsetHeight-height);}
this.element.style.width=width+"px";this.element.style.height=height+"px";this.element.positionAt(positionX,positionY,container);},_onKeyDown:function(event)
{if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code){event.consume(true);this.detach();}},defaultFocusedElement:function()
{var children=this.children();if(children.length)
return children[0].defaultFocusedElement();return this.element;},__proto__:WebInspector.Widget.prototype};WebInspector.Dialog._modalHostView=null;WebInspector.Dialog.setModalHostView=function(view)
{WebInspector.Dialog._modalHostView=view;};WebInspector.Dialog.modalHostView=function()
{return WebInspector.Dialog._modalHostView;};WebInspector.Dialog.modalHostRepositioned=function()
{if(WebInspector.Dialog._instance)
WebInspector.Dialog._instance._position();};;WebInspector.DOMSyntaxHighlighter=function(mimeType,stripExtraWhitespace)
{this._mimeType=mimeType;this._stripExtraWhitespace=stripExtraWhitespace;}
WebInspector.DOMSyntaxHighlighter.prototype={createSpan:function(content,className)
{var span=createElement("span");span.className="cm-"+className;if(this._stripExtraWhitespace&&className!=="whitespace")
content=content.replace(/^[\n\r]*/,"").replace(/\s*$/,"");span.createTextChild(content);return span;},syntaxHighlightNode:function(node)
{var lines=node.textContent.split("\n");var plainTextStart;var line;return self.runtime.instancePromise(WebInspector.TokenizerFactory).then(processTokens.bind(this));function processTokens(tokenizerFactory)
{node.removeChildren();var tokenize=tokenizerFactory.createTokenizer(this._mimeType);for(var i=lines[0].length?0:1;i<lines.length;++i){line=lines[i];plainTextStart=0;tokenize(line,processToken.bind(this));if(plainTextStart<line.length){var plainText=line.substring(plainTextStart,line.length);node.createTextChild(plainText);}
if(i<lines.length-1)
node.createTextChild("\n");}}
function processToken(token,tokenType,column,newColumn)
{if(!tokenType)
return;if(column>plainTextStart){var plainText=line.substring(plainTextStart,column);node.createTextChild(plainText);}
node.appendChild(this.createSpan(token,tokenType));plainTextStart=newColumn;}}};WebInspector.DropDownMenu=function(element)
{this._items=[];element.addEventListener("mousedown",this._onMouseDown.bind(this));}
WebInspector.DropDownMenu.Item;WebInspector.DropDownMenu.Events={ItemSelected:"ItemSelected"}
WebInspector.DropDownMenu.prototype={_onMouseDown:function(event)
{if(event.which!==1)
return;var menu=new WebInspector.ContextMenu(event);for(var item of this._items)
menu.appendCheckboxItem(item.title,this._itemHandler.bind(this,item.id),item.id===this._selectedItemId);menu.show();},_itemHandler:function(id)
{this.dispatchEventToListeners(WebInspector.DropDownMenu.Events.ItemSelected,id);},addItem:function(id,title)
{this._items.push({id:id,title:title});},selectItem:function(id)
{this._selectedItemId=id;},clear:function()
{this._items=[];delete this._selectedItemId;},__proto__:WebInspector.Object.prototype};WebInspector.DropTarget=function(element,transferTypes,messageText,handleDrop)
{element.addEventListener("dragenter",this._onDragEnter.bind(this),true);element.addEventListener("dragover",this._onDragOver.bind(this),true);this._element=element;this._transferTypes=transferTypes;this._messageText=messageText;this._handleDrop=handleDrop;this._enabled=true;}
WebInspector.DropTarget.Types={Files:"Files",URIList:"text/uri-list"}
WebInspector.DropTarget.prototype={setEnabled:function(enabled)
{this._enabled=enabled;},_onDragEnter:function(event)
{if(this._enabled&&this._hasMatchingType(event))
event.consume(true);},_hasMatchingType:function(event)
{for(var type of this._transferTypes){if(event.dataTransfer.types.indexOf(type)!==-1)
return true;}
return false;},_onDragOver:function(event)
{if(!this._enabled||!this._hasMatchingType(event))
return;event.dataTransfer.dropEffect="copy";event.consume(true);if(this._dragMaskElement)
return;this._dragMaskElement=this._element.createChild("div","");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(this._dragMaskElement,"ui/dropTarget.css");shadowRoot.createChild("div","drop-target-message").textContent=this._messageText;this._dragMaskElement.addEventListener("drop",this._onDrop.bind(this),true);this._dragMaskElement.addEventListener("dragleave",this._onDragLeave.bind(this),true);},_onDrop:function(event)
{event.consume(true);this._removeMask();if(this._enabled)
this._handleDrop(event.dataTransfer);},_onDragLeave:function(event)
{event.consume(true);this._removeMask();},_removeMask:function()
{this._dragMaskElement.remove();delete this._dragMaskElement;}};WebInspector.EmptyWidget=function(text)
{WebInspector.VBox.call(this);this.registerRequiredCSS("ui/emptyWidget.css");this.element.classList.add("empty-view");this.textElement=this.element.createChild("span");this._text=text;}
WebInspector.EmptyWidget.prototype={wasShown:function()
{this.textElement.textContent=this._text;},set text(text)
{this._text=text;if(this.isShowing())
this.textElement.textContent=this._text;},__proto__:WebInspector.VBox.prototype};WebInspector.FilterBar=function(name,visibleByDefault)
{WebInspector.HBox.call(this);this.registerRequiredCSS("ui/filter.css");this._filtersShown=false;this._enabled=true;this.element.classList.add("filter-bar");this._filterButton=new WebInspector.ToolbarButton(WebInspector.UIString("Filter"),"filter-toolbar-item");this._filterButton.addEventListener("click",this._handleFilterButtonClick,this);this._filters=[];this._stateSetting=WebInspector.settings.createSetting("filterBar-"+name+"-toggled",!!visibleByDefault);this._setState(this._stateSetting.get());}
WebInspector.FilterBar.FilterBarState={Inactive:"inactive",Active:"active",Shown:"on"};WebInspector.FilterBar.Events={Toggled:"Toggled"};WebInspector.FilterBar.prototype={filterButton:function()
{return this._filterButton;},addFilter:function(filter)
{this._filters.push(filter);this.element.appendChild(filter.element());filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged,this);this._updateFilterButton();},setEnabled:function(enabled)
{this._enabled=enabled;this._filterButton.setEnabled(enabled);this._updateFilterBar();},forceShowFilterBar:function()
{this._alwaysShowFilters=true;this._updateFilterBar();},wasShown:function()
{this._updateFilterBar();},_filterChanged:function(event)
{this._updateFilterButton();},_filterBarState:function()
{if(this._filtersShown)
return WebInspector.FilterBar.FilterBarState.Shown;var isActive=false;for(var i=0;i<this._filters.length;++i){if(this._filters[i].isActive())
return WebInspector.FilterBar.FilterBarState.Active;}
return WebInspector.FilterBar.FilterBarState.Inactive;},_updateFilterBar:function()
{var visible=this._alwaysShowFilters||(this._filtersShown&&this._enabled);this.element.classList.toggle("hidden",!visible);if(visible){for(var i=0;i<this._filters.length;++i){if(this._filters[i]instanceof WebInspector.TextFilterUI){var textFilterUI=(this._filters[i]);textFilterUI.focus();}}}
this.invalidateSize();},_updateFilterButton:function()
{this._filterButton.setState(this._filterBarState());},_handleFilterButtonClick:function(event)
{this._setState(!this._filtersShown);},_setState:function(filtersShown)
{if(this._filtersShown===filtersShown)
return;this._filtersShown=filtersShown;if(this._stateSetting)
this._stateSetting.set(filtersShown);this._updateFilterButton();this._updateFilterBar();this.dispatchEventToListeners(WebInspector.FilterBar.Events.Toggled);},clear:function()
{this.element.removeChildren();this._filters=[];this._updateFilterButton();},__proto__:WebInspector.HBox.prototype}
WebInspector.FilterUI=function()
{}
WebInspector.FilterUI.Events={FilterChanged:"FilterChanged"}
WebInspector.FilterUI.prototype={isActive:function(){},element:function(){}}
WebInspector.TextFilterUI=function(supportRegex)
{this._supportRegex=!!supportRegex;this._regex=null;this._filterElement=createElement("div");this._filterElement.className="filter-text-filter";this._filterInputElement=(this._filterElement.createChild("input","filter-input-field"));this._filterInputElement.placeholder=WebInspector.UIString("Filter");this._filterInputElement.id="filter-input-field";this._filterInputElement.addEventListener("mousedown",this._onFilterFieldManualFocus.bind(this),false);this._filterInputElement.addEventListener("input",this._onInput.bind(this),false);this._filterInputElement.addEventListener("change",this._onChange.bind(this),false);this._filterInputElement.addEventListener("keydown",this._onInputKeyDown.bind(this),true);this._filterInputElement.addEventListener("blur",this._onBlur.bind(this),true);this._suggestionBuilder=null;this._suggestBox=new WebInspector.SuggestBox(this);if(this._supportRegex){this._filterElement.classList.add("supports-regex");var label=createCheckboxLabel(WebInspector.UIString("Regex"));this._regexCheckBox=label.checkboxElement;this._regexCheckBox.id="text-filter-regex";this._regexCheckBox.addEventListener("change",this._onInput.bind(this),false);this._filterElement.appendChild(label);this._regexLabel=this._filterElement.textElement;}}
WebInspector.TextFilterUI.prototype={isActive:function()
{return!!this._filterInputElement.value;},element:function()
{return this._filterElement;},isRegexChecked:function()
{return this._supportRegex?this._regexCheckBox.checked:false;},value:function()
{return this._filterInputElement.value;},setValue:function(value)
{this._filterInputElement.value=value;this._valueChanged(false);},regex:function()
{return this._regex;},_onFilterFieldManualFocus:function(event)
{WebInspector.setCurrentFocusElement((event.target));},_onBlur:function(event)
{this._cancelSuggestion();},_cancelSuggestion:function()
{if(this._suggestionBuilder&&this._suggestBox.visible){this._suggestionBuilder.unapplySuggestion(this._filterInputElement);this._suggestBox.hide();}},_onInput:function()
{this._valueChanged(true);},_onChange:function()
{this._valueChanged(false);},focus:function()
{this._filterInputElement.focus();},setSuggestionBuilder:function(suggestionBuilder)
{this._cancelSuggestion();this._suggestionBuilder=suggestionBuilder;},_updateSuggestions:function()
{if(!this._suggestionBuilder)
return;if(this.isRegexChecked()){if(this._suggestBox.visible())
this._suggestBox.hide();return;}
var suggestions=this._suggestionBuilder.buildSuggestions(this._filterInputElement);if(suggestions&&suggestions.length){if(this._suppressSuggestion)
delete this._suppressSuggestion;else
this._suggestionBuilder.applySuggestion(this._filterInputElement,suggestions[0],true);var anchorBox=this._filterInputElement.boxInWindow().relativeTo(new AnchorBox(-3,0));this._suggestBox.updateSuggestions(anchorBox,suggestions.map(item=>({title:item})),0,true,"");}else{this._suggestBox.hide();}},_valueChanged:function(showSuggestions)
{if(showSuggestions)
this._updateSuggestions();else
this._suggestBox.hide();var filterQuery=this.value();this._regex=null;this._filterInputElement.classList.remove("filter-text-invalid");if(filterQuery){if(this.isRegexChecked()){try{this._regex=new RegExp(filterQuery,"i");}catch(e){this._filterInputElement.classList.add("filter-text-invalid");}}else{this._regex=createPlainTextSearchRegex(filterQuery,"i");}}
this._dispatchFilterChanged();},_dispatchFilterChanged:function()
{this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged,null);},_onInputKeyDown:function(event)
{var handled=false;if(event.keyIdentifier==="U+0008"){this._suppressSuggestion=true;}else if(this._suggestBox.visible()){if(event.keyIdentifier==="U+001B"){this._cancelSuggestion();handled=true;}else if(event.keyIdentifier==="U+0009"){this._suggestBox.acceptSuggestion();this._valueChanged(true);handled=true;}else{handled=this._suggestBox.keyPressed((event));}}
if(handled)
event.consume(true);return handled;},applySuggestion:function(suggestion,isIntermediateSuggestion)
{if(!this._suggestionBuilder)
return;this._suggestionBuilder.applySuggestion(this._filterInputElement,suggestion,!!isIntermediateSuggestion);if(isIntermediateSuggestion)
this._dispatchFilterChanged();},acceptSuggestion:function()
{this._filterInputElement.scrollLeft=this._filterInputElement.scrollWidth;this._valueChanged(true);},__proto__:WebInspector.Object.prototype}
WebInspector.TextFilterUI.SuggestionBuilder=function()
{}
WebInspector.TextFilterUI.SuggestionBuilder.prototype={buildSuggestions:function(input){},applySuggestion:function(input,suggestion,isIntermediate){},unapplySuggestion:function(input){}}
WebInspector.NamedBitSetFilterUI=function(items,setting)
{this._filtersElement=createElementWithClass("div","filter-bitset-filter");this._filtersElement.title=WebInspector.UIString("%sClick to select multiple types",WebInspector.KeyboardShortcut.shortcutToString("",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta));this._allowedTypes={};this._typeFilterElements={};this._addBit(WebInspector.NamedBitSetFilterUI.ALL_TYPES,WebInspector.UIString("All"));this._filtersElement.createChild("div","filter-bitset-filter-divider");for(var i=0;i<items.length;++i)
this._addBit(items[i].name,items[i].label,items[i].title);if(setting){this._setting=setting;setting.addChangeListener(this._settingChanged.bind(this));this._settingChanged();}else{this._toggleTypeFilter(WebInspector.NamedBitSetFilterUI.ALL_TYPES,false);}}
WebInspector.NamedBitSetFilterUI.Item;WebInspector.NamedBitSetFilterUI.ALL_TYPES="all";WebInspector.NamedBitSetFilterUI.prototype={isActive:function()
{return!this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES];},element:function()
{return this._filtersElement;},accept:function(typeName)
{return!!this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES]||!!this._allowedTypes[typeName];},_settingChanged:function()
{var allowedTypes=this._setting.get();this._allowedTypes={};for(var typeName in this._typeFilterElements){if(allowedTypes[typeName])
this._allowedTypes[typeName]=true;}
this._update();},_update:function()
{if((Object.keys(this._allowedTypes).length===0)||this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES]){this._allowedTypes={};this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES]=true;}
for(var typeName in this._typeFilterElements)
this._typeFilterElements[typeName].classList.toggle("selected",this._allowedTypes[typeName]);this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged,null);},_addBit:function(name,label,title)
{var typeFilterElement=this._filtersElement.createChild("li",name);typeFilterElement.typeName=name;typeFilterElement.createTextChild(label);if(title)
typeFilterElement.title=title;typeFilterElement.addEventListener("click",this._onTypeFilterClicked.bind(this),false);this._typeFilterElements[name]=typeFilterElement;},_onTypeFilterClicked:function(e)
{var toggle;if(WebInspector.isMac())
toggle=e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey;else
toggle=e.ctrlKey&&!e.metaKey&&!e.altKey&&!e.shiftKey;this._toggleTypeFilter(e.target.typeName,toggle);},_toggleTypeFilter:function(typeName,allowMultiSelect)
{if(allowMultiSelect&&typeName!==WebInspector.NamedBitSetFilterUI.ALL_TYPES)
this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES]=false;else
this._allowedTypes={};this._allowedTypes[typeName]=!this._allowedTypes[typeName];if(this._setting)
this._setting.set(this._allowedTypes);else
this._update();},__proto__:WebInspector.Object.prototype}
WebInspector.ComboBoxFilterUI=function(options)
{this._filterElement=createElement("div");this._filterElement.className="filter-combobox-filter";this._options=options;this._filterComboBox=new WebInspector.ToolbarComboBox(this._filterChanged.bind(this));for(var i=0;i<options.length;++i){var filterOption=options[i];var option=createElement("option");option.text=filterOption.label;option.title=filterOption.title;this._filterComboBox.addOption(option);this._filterComboBox.element.title=this._filterComboBox.selectedOption().title;}
this._filterElement.appendChild(this._filterComboBox.element);}
WebInspector.ComboBoxFilterUI.prototype={isActive:function()
{return this._filterComboBox.selectedIndex()!==0;},element:function()
{return this._filterElement;},value:function()
{var option=this._options[this._filterComboBox.selectedIndex()];return option.value;},setSelectedIndex:function(index)
{this._filterComboBox.setSelectedIndex(index);},selectedIndex:function(index)
{return this._filterComboBox.selectedIndex();},_filterChanged:function(event)
{var option=this._options[this._filterComboBox.selectedIndex()];this._filterComboBox.element.title=option.title;this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged,null);},__proto__:WebInspector.Object.prototype}
WebInspector.CheckboxFilterUI=function(className,title,activeWhenChecked,setting)
{this._filterElement=createElementWithClass("div","filter-checkbox-filter");this._activeWhenChecked=!!activeWhenChecked;this._label=createCheckboxLabel(title);this._filterElement.appendChild(this._label);this._checkboxElement=this._label.checkboxElement;if(setting)
WebInspector.SettingsUI.bindCheckbox(this._checkboxElement,setting);else
this._checkboxElement.checked=true;this._checkboxElement.addEventListener("change",this._fireUpdated.bind(this),false);}
WebInspector.CheckboxFilterUI.prototype={isActive:function()
{return this._activeWhenChecked===this._checkboxElement.checked;},checked:function()
{return this._checkboxElement.checked;},element:function()
{return this._filterElement;},labelElement:function()
{return this._label;},_fireUpdated:function()
{this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged,null);},setColor:function(backgroundColor,borderColor)
{this._label.backgroundColor=backgroundColor;this._label.borderColor=borderColor;},__proto__:WebInspector.Object.prototype};WebInspector.ForwardedInputEventHandler=function()
{InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.KeyEventUnhandled,this._onKeyEventUnhandled,this);}
WebInspector.ForwardedInputEventHandler.prototype={_onKeyEventUnhandled:function(event)
{var data=event.data;var type=(data.type);var keyIdentifier=(data.keyIdentifier);var keyCode=(data.keyCode);var modifiers=(data.modifiers);if(type!=="keydown")
return;WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut,WebInspector.ShortcutRegistry.ForwardedShortcut.instance);WebInspector.shortcutRegistry.handleKey(WebInspector.KeyboardShortcut.makeKey(keyCode,modifiers),keyIdentifier);WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut,null);}}
WebInspector.forwardedEventHandler=new WebInspector.ForwardedInputEventHandler();;WebInspector.HistoryInput=function()
{}
WebInspector.HistoryInput.create=function()
{if(!WebInspector.HistoryInput._constructor)
WebInspector.HistoryInput._constructor=registerCustomElement("input","history-input",WebInspector.HistoryInput.prototype);return(new WebInspector.HistoryInput._constructor());}
WebInspector.HistoryInput.prototype={createdCallback:function()
{this._history=[""];this._historyPosition=0;this.addEventListener("keydown",this._onKeyDown.bind(this),false);this.addEventListener("input",this._onInput.bind(this),false);},_onInput:function(event)
{if(this._history.length===this._historyPosition+1)
this._history[this._history.length-1]=this.value;},_onKeyDown:function(event)
{if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Up.code){this._historyPosition=Math.max(this._historyPosition-1,0);this.value=this._history[this._historyPosition];this.dispatchEvent(createEvent("input",true,true));event.consume(true);}else if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Down.code){this._historyPosition=Math.min(this._historyPosition+1,this._history.length-1);this.value=this._history[this._historyPosition];this.dispatchEvent(createEvent("input",true,true));event.consume(true);}else if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Enter.code){this._saveToHistory();}},_saveToHistory:function()
{if(this._history.length>1&&this._history[this._history.length-2]===this.value)
return;this._history[this._history.length-1]=this.value;this._historyPosition=this._history.length-1;this._history.push("");},__proto__:HTMLInputElement.prototype};WebInspector.Infobar=function(type,text,disableSetting)
{this.element=createElementWithClass("div","flex-none");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/infobar.css");this._contentElement=this._shadowRoot.createChild("div","infobar infobar-"+type);this._mainRow=this._contentElement.createChild("div","infobar-main-row");this._mainRow.createChild("div",type+"-icon icon");this._mainRowText=this._mainRow.createChild("div","infobar-main-title");this._mainRowText.textContent=text;this._detailsRows=this._contentElement.createChild("div","infobar-details-rows hidden");this._toggleElement=this._mainRow.createChild("div","infobar-toggle hidden");this._toggleElement.addEventListener("click",this._onToggleDetails.bind(this),false);this._toggleElement.textContent=WebInspector.UIString("more");this._disableSetting=disableSetting||null;if(disableSetting){var disableButton=this._mainRow.createChild("div","infobar-toggle");disableButton.textContent=WebInspector.UIString("never show");disableButton.addEventListener("click",this._onDisable.bind(this),false);}
this._closeButton=this._contentElement.createChild("div","close-button","dt-close-button");this._closeButton.addEventListener("click",this.dispose.bind(this),false);this._closeCallback=null;}
WebInspector.Infobar.create=function(type,text,disableSetting)
{if(disableSetting&&disableSetting.get())
return null;return new WebInspector.Infobar(type,text,disableSetting);}
WebInspector.Infobar.Type={Warning:"warning",Info:"info"}
WebInspector.Infobar.prototype={dispose:function()
{this.element.remove();this._onResize();if(this._closeCallback)
this._closeCallback.call(null);},setText:function(text)
{this._mainRowText.textContent=text;this._onResize();},setCloseCallback:function(callback)
{this._closeCallback=callback;},setParentView:function(parentView)
{this._parentView=parentView;},_onResize:function()
{if(this._parentView)
this._parentView.doResize();},_onDisable:function()
{this._disableSetting.set(true);this.dispose();},_onToggleDetails:function()
{this._detailsRows.classList.remove("hidden");this._toggleElement.remove();this._onResize();},createDetailsRowMessage:function(message)
{this._toggleElement.classList.remove("hidden");var infobarDetailsRow=this._detailsRows.createChild("div","infobar-details-row");var detailsRowMessage=infobarDetailsRow.createChild("span","infobar-row-message");detailsRowMessage.textContent=message||"";return detailsRowMessage;}};WebInspector.InplaceEditor=function()
{}
WebInspector.InplaceEditor.Controller;WebInspector.InplaceEditor.startEditing=function(element,config)
{if(!WebInspector.InplaceEditor._defaultInstance)
WebInspector.InplaceEditor._defaultInstance=new WebInspector.InplaceEditor();return WebInspector.InplaceEditor._defaultInstance.startEditing(element,config);}
WebInspector.InplaceEditor.startMultilineEditing=function(element,config)
{return self.runtime.instancePromise(WebInspector.InplaceEditor).then(startEditing);function startEditing(inplaceEditor)
{var controller=(inplaceEditor).startEditing(element,config);if(!controller)
return Promise.reject(new Error("Editing is already in progress"));return controller;}}
WebInspector.InplaceEditor.prototype={editorContent:function(editingContext){var element=editingContext.element;if(element.tagName==="INPUT"&&element.type==="text")
return element.value;return element.textContent;},setUpEditor:function(editingContext)
{var element=editingContext.element;element.classList.add("editing");var oldTabIndex=element.getAttribute("tabIndex");if(typeof oldTabIndex!=="number"||oldTabIndex<0)
element.tabIndex=0;WebInspector.setCurrentFocusElement(element);editingContext.oldTabIndex=oldTabIndex;},closeEditor:function(editingContext)
{var element=editingContext.element;element.classList.remove("editing");if(typeof editingContext.oldTabIndex!=="number")
element.removeAttribute("tabIndex");else
element.tabIndex=editingContext.oldTabIndex;element.scrollTop=0;element.scrollLeft=0;},cancelEditing:function(editingContext)
{var element=editingContext.element;if(element.tagName==="INPUT"&&element.type==="text")
element.value=editingContext.oldText;else
element.textContent=editingContext.oldText;},augmentEditingHandle:function(editingContext,handle)
{},startEditing:function(element,config)
{if(!WebInspector.markBeingEdited(element,true))
return null;config=config||new WebInspector.InplaceEditor.Config(function(){},function(){});var editingContext={element:element,config:config};var committedCallback=config.commitHandler;var cancelledCallback=config.cancelHandler;var pasteCallback=config.pasteHandler;var context=config.context;var isMultiline=config.multiline||false;var moveDirection="";var self=this;function consumeCopy(e)
{e.consume();}
this.setUpEditor(editingContext);editingContext.oldText=isMultiline?config.initialValue:this.editorContent(editingContext);function blurEventListener(e){if(config.blurHandler&&!config.blurHandler(element,e))
return;if(!isMultiline||!e||!e.relatedTarget||!e.relatedTarget.isSelfOrDescendant(element))
editingCommitted.call(element);}
function cleanUpAfterEditing()
{WebInspector.markBeingEdited(element,false);element.removeEventListener("blur",blurEventListener,isMultiline);element.removeEventListener("keydown",keyDownEventListener,true);if(pasteCallback)
element.removeEventListener("paste",pasteEventListener,true);WebInspector.restoreFocusFromElement(element);self.closeEditor(editingContext);}
function editingCancelled()
{self.cancelEditing(editingContext);cleanUpAfterEditing();cancelledCallback(this,context);}
function editingCommitted()
{cleanUpAfterEditing();committedCallback(this,self.editorContent(editingContext),editingContext.oldText,context,moveDirection);}
function defaultFinishHandler(event)
{var isMetaOrCtrl=WebInspector.isMac()?event.metaKey&&!event.shiftKey&&!event.ctrlKey&&!event.altKey:event.ctrlKey&&!event.shiftKey&&!event.metaKey&&!event.altKey;if(isEnterKey(event)&&(event.isMetaOrCtrlForTest||!isMultiline||isMetaOrCtrl))
return"commit";else if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code||event.keyIdentifier==="U+001B")
return"cancel";else if(!isMultiline&&event.keyIdentifier==="U+0009")
return"move-"+(event.shiftKey?"backward":"forward");return"";}
function handleEditingResult(result,event)
{if(result==="commit"){editingCommitted.call(element);event.consume(true);}else if(result==="cancel"){editingCancelled.call(element);event.consume(true);}else if(result&&result.startsWith("move-")){moveDirection=result.substring(5);if(event.keyIdentifier!=="U+0009")
blurEventListener();}}
function pasteEventListener(event)
{var result=pasteCallback(event);handleEditingResult(result,event);}
function keyDownEventListener(event)
{var result=defaultFinishHandler(event);if(!result&&config.postKeydownFinishHandler)
result=config.postKeydownFinishHandler(event);handleEditingResult(result,event);}
element.addEventListener("blur",blurEventListener,isMultiline);element.addEventListener("keydown",keyDownEventListener,true);if(pasteCallback)
element.addEventListener("paste",pasteEventListener,true);var handle={cancel:editingCancelled.bind(element),commit:editingCommitted.bind(element),setWidth:function(){}};this.augmentEditingHandle(editingContext,handle);return handle;}}
WebInspector.InplaceEditor.Config=function(commitHandler,cancelHandler,context,blurHandler)
{this.commitHandler=commitHandler;this.cancelHandler=cancelHandler;this.context=context;this.blurHandler=blurHandler;this.pasteHandler;this.multiline;this.postKeydownFinishHandler;}
WebInspector.InplaceEditor.Config.prototype={setPasteHandler:function(pasteHandler)
{this.pasteHandler=pasteHandler;},setMultilineOptions:function(initialValue,mode,theme,lineWrapping,smartIndent)
{this.multiline=true;this.initialValue=initialValue;this.mode=mode;this.theme=theme;this.lineWrapping=lineWrapping;this.smartIndent=smartIndent;},setPostKeydownFinishHandler:function(postKeydownFinishHandler)
{this.postKeydownFinishHandler=postKeydownFinishHandler;}};WebInspector.KeyboardShortcut=function()
{}
WebInspector.KeyboardShortcut.Modifiers={None:0,Shift:1,Ctrl:2,Alt:4,Meta:8,get CtrlOrMeta()
{return WebInspector.isMac()?this.Meta:this.Ctrl;},get ShiftOrOption()
{return WebInspector.isMac()?this.Alt:this.Shift;}};WebInspector.KeyboardShortcut.Key;WebInspector.KeyboardShortcut.Keys={Backspace:{code:8,name:"\u21a4"},Tab:{code:9,name:{mac:"\u21e5",other:"Tab"}},Enter:{code:13,name:{mac:"\u21a9",other:"Enter"}},Shift:{code:16,name:{mac:"\u21e7",other:"Shift"}},Ctrl:{code:17,name:"Ctrl"},Esc:{code:27,name:"Esc"},Space:{code:32,name:"Space"},PageUp:{code:33,name:{mac:"\u21de",other:"PageUp"}},PageDown:{code:34,name:{mac:"\u21df",other:"PageDown"}},End:{code:35,name:{mac:"\u2197",other:"End"}},Home:{code:36,name:{mac:"\u2196",other:"Home"}},Left:{code:37,name:"\u2190"},Up:{code:38,name:"\u2191"},Right:{code:39,name:"\u2192"},Down:{code:40,name:"\u2193"},Delete:{code:46,name:"Del"},Zero:{code:48,name:"0"},H:{code:72,name:"H"},Meta:{code:91,name:"Meta"},F1:{code:112,name:"F1"},F2:{code:113,name:"F2"},F3:{code:114,name:"F3"},F4:{code:115,name:"F4"},F5:{code:116,name:"F5"},F6:{code:117,name:"F6"},F7:{code:118,name:"F7"},F8:{code:119,name:"F8"},F9:{code:120,name:"F9"},F10:{code:121,name:"F10"},F11:{code:122,name:"F11"},F12:{code:123,name:"F12"},Semicolon:{code:186,name:";"},NumpadPlus:{code:107,name:"Numpad +"},NumpadMinus:{code:109,name:"Numpad -"},Numpad0:{code:96,name:"Numpad 0"},Plus:{code:187,name:"+"},Comma:{code:188,name:","},Minus:{code:189,name:"-"},Period:{code:190,name:"."},Slash:{code:191,name:"/"},QuestionMark:{code:191,name:"?"},Apostrophe:{code:192,name:"`"},Tilde:{code:192,name:"Tilde"},LeftSquareBracket:{code:219,name:"["},RightSquareBracket:{code:221,name:"]"},Backslash:{code:220,name:"\\"},SingleQuote:{code:222,name:"\'"},get CtrlOrMeta()
{return WebInspector.isMac()?this.Meta:this.Ctrl;},};WebInspector.KeyboardShortcut.KeyBindings={};(function(){for(var key in WebInspector.KeyboardShortcut.Keys){var descriptor=WebInspector.KeyboardShortcut.Keys[key];if(typeof descriptor==="object"&&descriptor["code"]){var name=typeof descriptor["name"]==="string"?descriptor["name"]:key;WebInspector.KeyboardShortcut.KeyBindings[name]=descriptor;}}})();WebInspector.KeyboardShortcut.makeKey=function(keyCode,modifiers)
{if(typeof keyCode==="string")
keyCode=keyCode.charCodeAt(0)-(/^[a-z]/.test(keyCode)?32:0);modifiers=modifiers||WebInspector.KeyboardShortcut.Modifiers.None;return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode,modifiers);}
WebInspector.KeyboardShortcut.makeKeyFromEvent=function(keyboardEvent)
{var modifiers=WebInspector.KeyboardShortcut.Modifiers.None;if(keyboardEvent.shiftKey)
modifiers|=WebInspector.KeyboardShortcut.Modifiers.Shift;if(keyboardEvent.ctrlKey)
modifiers|=WebInspector.KeyboardShortcut.Modifiers.Ctrl;if(keyboardEvent.altKey)
modifiers|=WebInspector.KeyboardShortcut.Modifiers.Alt;if(keyboardEvent.metaKey)
modifiers|=WebInspector.KeyboardShortcut.Modifiers.Meta;var keyCode=keyboardEvent.keyCode||keyboardEvent["__keyCode"];return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode,modifiers);}
WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers=function(keyboardEvent)
{var keyCode=keyboardEvent.keyCode||keyboardEvent["__keyCode"];return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode,WebInspector.KeyboardShortcut.Modifiers.None);}
WebInspector.KeyboardShortcut.eventHasCtrlOrMeta=function(event)
{return WebInspector.isMac()?event.metaKey&&!event.ctrlKey:event.ctrlKey&&!event.metaKey;}
WebInspector.KeyboardShortcut.hasNoModifiers=function(event)
{return!event.ctrlKey&&!event.shiftKey&&!event.altKey&&!event.metaKey;}
WebInspector.KeyboardShortcut.Descriptor;WebInspector.KeyboardShortcut.makeDescriptor=function(key,modifiers)
{return{key:WebInspector.KeyboardShortcut.makeKey(typeof key==="string"?key:key.code,modifiers),name:WebInspector.KeyboardShortcut.shortcutToString(key,modifiers)};}
WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut=function(shortcut)
{var parts=shortcut.split(/\+(?!$)/);var modifiers=0;var keyString;for(var i=0;i<parts.length;++i){if(typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]]!=="undefined"){modifiers|=WebInspector.KeyboardShortcut.Modifiers[parts[i]];continue;}
console.assert(i===parts.length-1,"Only one key other than modifier is allowed in shortcut <"+shortcut+">");keyString=parts[i];break;}
console.assert(keyString,"Modifiers-only shortcuts are not allowed (encountered <"+shortcut+">)");if(!keyString)
return null;var key=WebInspector.KeyboardShortcut.Keys[keyString]||WebInspector.KeyboardShortcut.KeyBindings[keyString];if(key&&key.shiftKey)
modifiers|=WebInspector.KeyboardShortcut.Modifiers.Shift;return WebInspector.KeyboardShortcut.makeDescriptor(key?key:keyString,modifiers);}
WebInspector.KeyboardShortcut.shortcutToString=function(key,modifiers)
{return WebInspector.KeyboardShortcut._modifiersToString(modifiers)+WebInspector.KeyboardShortcut._keyName(key);}
WebInspector.KeyboardShortcut._keyName=function(key)
{if(typeof key==="string")
return key.toUpperCase();if(typeof key.name==="string")
return key.name;return key.name[WebInspector.platform()]||key.name.other||"";}
WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers=function(keyCode,modifiers)
{return(keyCode&255)|(modifiers<<8);};WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey=function(key)
{return{keyCode:key&255,modifiers:key>>8};}
WebInspector.KeyboardShortcut._modifiersToString=function(modifiers)
{var isMac=WebInspector.isMac();var m=WebInspector.KeyboardShortcut.Modifiers;var modifierNames=new Map([[m.Ctrl,isMac?"Ctrl\u2004":"Ctrl\u200A+\u200A"],[m.Alt,isMac?"opt\u2004":"Alt\u200A+\u200A"],[m.Shift,isMac?"\u21e7\u2004":"Shift\u200A+\u200A"],[m.Meta,isMac?"\u2318\u2004":"Win\u200A+\u200A"]]);return[m.Meta,m.Ctrl,m.Alt,m.Shift].map(mapModifiers).join("");function mapModifiers(m)
{return modifiers&m?(modifierNames.get(m)):"";}};WebInspector.KeyboardShortcut.SelectAll=WebInspector.KeyboardShortcut.makeKey("a",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);;WebInspector.ListWidget=function(delegate)
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("ui/listWidget.css");this._delegate=delegate;this._list=this.contentElement.createChild("div","list");this._editor=null;this._editItem=null;this._editElement=null;this._emptyPlaceholder=null;this.clear();}
WebInspector.ListWidget.Delegate=function()
{}
WebInspector.ListWidget.Delegate.prototype={renderItem:function(item,editable){},removeItemRequested:function(item,index){},beginEdit:function(item){},commitEdit:function(item,editor,isNew){}}
WebInspector.ListWidget.prototype={clear:function()
{this._items=[];this._editable=[];this._elements=[];this._lastSeparator=false;this._list.removeChildren();this._updatePlaceholder();this._stopEditing();},appendItem:function(item,editable)
{if(this._lastSeparator&&this._items.length)
this._list.appendChild(createElementWithClass("div","list-separator"));this._lastSeparator=false;this._items.push(item);this._editable.push(editable);var element=this._list.createChild("div","list-item");element.appendChild(this._delegate.renderItem(item,editable));if(editable){element.classList.add("editable");element.appendChild(this._createControls(item,element));}
this._elements.push(element);this._updatePlaceholder();},appendSeparator:function()
{this._lastSeparator=true;},removeItem:function(index)
{if(this._editItem===this._items[index])
this._stopEditing();var element=this._elements[index];var previous=element.previousElementSibling;var previousIsSeparator=previous&&previous.classList.contains("list-separator");var next=element.nextElementSibling;var nextIsSeparator=next&&next.classList.contains("list-separator");if(previousIsSeparator&&(nextIsSeparator||!next))
previous.remove();if(nextIsSeparator&&!previous)
next.remove();element.remove();this._elements.splice(index,1);this._items.splice(index,1);this._editable.splice(index,1);this._updatePlaceholder();},addNewItem:function(index,item)
{this._startEditing(item,null,this._elements[index]||null);},setEmptyPlaceholder:function(element)
{this._emptyPlaceholder=element;this._updatePlaceholder();},_createControls:function(item,element)
{var controls=createElementWithClass("div","controls-container fill");var gradient=controls.createChild("div","controls-gradient");var buttons=controls.createChild("div","controls-buttons");var editButton=buttons.createChild("div","edit-button");editButton.title=WebInspector.UIString("Edit");editButton.addEventListener("click",onEditClicked.bind(this),false);var removeButton=buttons.createChild("div","remove-button");removeButton.title=WebInspector.UIString("Remove");removeButton.addEventListener("click",onRemoveClicked.bind(this),false);return controls;function onEditClicked(event)
{event.consume();var index=this._elements.indexOf(element);var insertionPoint=this._elements[index+1]||null;this._startEditing(item,element,insertionPoint);}
function onRemoveClicked(event)
{event.consume();var index=this._elements.indexOf(element);this._delegate.removeItemRequested(this._items[index],index);}},wasShown:function()
{WebInspector.VBox.prototype.wasShown.call(this);this._stopEditing();},_updatePlaceholder:function()
{if(!this._emptyPlaceholder)
return;if(!this._elements.length&&!this._editor)
this._list.appendChild(this._emptyPlaceholder);else
this._emptyPlaceholder.remove();},_startEditing:function(item,element,insertionPoint)
{if(element&&this._editElement===element)
return;this._stopEditing();this._list.classList.add("list-editing");this._editItem=item;this._editElement=element;if(element)
element.classList.add("hidden");var index=element?this._elements.indexOf(element):-1;this._editor=this._delegate.beginEdit(item);this._updatePlaceholder();this._list.insertBefore(this._editor.element,insertionPoint);this._editor.beginEdit(item,index,element?WebInspector.UIString("Save"):WebInspector.UIString("Add"),this._commitEditing.bind(this),this._stopEditing.bind(this));},_commitEditing:function()
{var editItem=this._editItem;var isNew=!this._editElement;var editor=(this._editor);this._stopEditing();this._delegate.commitEdit(editItem,editor,isNew);},_stopEditing:function()
{this._list.classList.remove("list-editing");if(this._editElement)
this._editElement.classList.remove("hidden");if(this._editor&&this._editor.element.parentElement)
this._editor.element.remove();this._editor=null;this._editItem=null;this._editElement=null;this._updatePlaceholder();},__proto__:WebInspector.VBox.prototype}
WebInspector.ListWidget.Editor=function()
{this.element=createElementWithClass("div","editor-container");this.element.addEventListener("keydown",onKeyDown.bind(null,isEscKey,this._cancelClicked.bind(this)),false);this.element.addEventListener("keydown",onKeyDown.bind(null,isEnterKey,this._commitClicked.bind(this)),false);this._contentElement=this.element.createChild("div","editor-content");var buttonsRow=this.element.createChild("div","editor-buttons");this._commitButton=createTextButton("",this._commitClicked.bind(this));buttonsRow.appendChild(this._commitButton);this._cancelButton=createTextButton(WebInspector.UIString("Cancel"),this._cancelClicked.bind(this));this._cancelButton.addEventListener("keydown",onKeyDown.bind(null,isEnterKey,this._cancelClicked.bind(this)),false);buttonsRow.appendChild(this._cancelButton);function onKeyDown(predicate,callback,event)
{if(predicate(event)){event.consume(true);callback();}}
this._controls=[];this._controlByName=new Map();this._validators=[];this._commit=null;this._cancel=null;this._item=null;this._index=-1;}
WebInspector.ListWidget.Editor.prototype={contentElement:function()
{return this._contentElement;},createInput:function(name,type,title,validator)
{var input=(createElement("input"));input.type=type;input.placeholder=title;input.addEventListener("input",this._validateControls.bind(this,false),false);input.addEventListener("blur",this._validateControls.bind(this,false),false);this._controlByName.set(name,input);this._controls.push(input);this._validators.push(validator);return input;},createSelect:function(name,options,validator)
{var select=(createElementWithClass("select","chrome-select"));for(var index=0;index<options.length;++index){var option=select.createChild("option");option.value=options[index];option.textContent=options[index];}
select.addEventListener("input",this._validateControls.bind(this,false),false);select.addEventListener("blur",this._validateControls.bind(this,false),false);this._controlByName.set(name,select);this._controls.push(select);this._validators.push(validator);return select;},control:function(name)
{return(this._controlByName.get(name));},_validateControls:function(forceValid)
{var allValid=true;for(var index=0;index<this._controls.length;++index){var input=this._controls[index];var valid=this._validators[index].call(null,this._item,this._index,input);input.classList.toggle("error-input",!valid&&!forceValid);allValid&=valid;}
this._commitButton.disabled=!allValid;},beginEdit:function(item,index,commitButtonTitle,commit,cancel)
{this._commit=commit;this._cancel=cancel;this._item=item;this._index=index;this._commitButton.textContent=commitButtonTitle;this.element.scrollIntoViewIfNeeded(false);if(this._controls.length)
this._controls[0].focus();this._validateControls(true);},_commitClicked:function()
{if(this._commitButton.disabled)
return;var commit=this._commit;this._commit=null;this._cancel=null;this._item=null;this._index=-1;commit();},_cancelClicked:function()
{var cancel=this._cancel;this._commit=null;this._cancel=null;this._item=null;this._index=-1;cancel();}};WebInspector.Panel=function(name)
{WebInspector.VBox.call(this);this.element.classList.add("panel");this.element.classList.add(name);this._panelName=name;this._shortcuts=({});}
WebInspector.Panel.counterRightMargin=25;WebInspector.Panel.prototype={get name()
{return this._panelName;},reset:function()
{},searchableView:function()
{return null;},elementsToRestoreScrollPositionsFor:function()
{return[];},handleShortcut:function(event)
{var shortcutKey=WebInspector.KeyboardShortcut.makeKeyFromEvent(event);var handler=this._shortcuts[shortcutKey];if(handler&&handler(event))
event.handled=true;},registerShortcuts:function(keys,handler)
{for(var i=0;i<keys.length;++i)
this._shortcuts[keys[i].key]=handler;},showInfobar:function(infobar)
{infobar.setCloseCallback(this._onInfobarClosed.bind(this,infobar));if(this.element.firstChild)
this.element.insertBefore(infobar.element,this.element.firstChild);else
this.element.appendChild(infobar.element);infobar.setParentView(this);this.doResize();},_onInfobarClosed:function(infobar)
{infobar.element.remove();this.doResize();},__proto__:WebInspector.VBox.prototype}
WebInspector.PanelWithSidebar=function(name,defaultWidth)
{WebInspector.Panel.call(this,name);this._panelSplitWidget=new WebInspector.SplitWidget(true,false,this._panelName+"PanelSplitViewState",defaultWidth||200);this._panelSplitWidget.show(this.element);this._mainWidget=new WebInspector.VBox();this._panelSplitWidget.setMainWidget(this._mainWidget);this._sidebarWidget=new WebInspector.VBox();this._sidebarWidget.setMinimumSize(100,25);this._panelSplitWidget.setSidebarWidget(this._sidebarWidget);this._sidebarWidget.element.classList.add("sidebar");}
WebInspector.PanelWithSidebar.prototype={panelSidebarElement:function()
{return this._sidebarWidget.element;},mainElement:function()
{return this._mainWidget.element;},splitWidget:function()
{return this._panelSplitWidget;},__proto__:WebInspector.Panel.prototype}
WebInspector.PanelDescriptor=function()
{}
WebInspector.PanelDescriptor.prototype={name:function(){},title:function(){},panel:function(){}}
WebInspector.PanelFactory=function()
{}
WebInspector.PanelFactory.prototype={createPanel:function(){}}
WebInspector.RuntimeExtensionPanelDescriptor=function(extension)
{this._name=extension.descriptor()["name"];this._title=WebInspector.UIString(extension.descriptor()["title"]);this._extension=extension;}
WebInspector.RuntimeExtensionPanelDescriptor.prototype={name:function()
{return this._name;},title:function()
{return this._title;},panel:function()
{return this._extension.instancePromise().then(createPanel);function createPanel(panelFactory)
{return(panelFactory).createPanel();}}};WebInspector.Popover=function(popoverHelper)
{WebInspector.Widget.call(this);this.markAsRoot();this.element.className=WebInspector.Popover._classNamePrefix;this._containerElement=createElementWithClass("div","fill popover-container");this._popupArrowElement=this.element.createChild("div","arrow");this._contentDiv=this.element.createChild("div","content");this._popoverHelper=popoverHelper;this._hideBound=this.hide.bind(this);}
WebInspector.Popover._classNamePrefix="popover";WebInspector.Popover.prototype={showForAnchor:function(element,anchor,preferredWidth,preferredHeight,arrowDirection)
{this._innerShow(null,element,anchor,preferredWidth,preferredHeight,arrowDirection);},showView:function(view,anchor,preferredWidth,preferredHeight)
{this._innerShow(view,view.element,anchor,preferredWidth,preferredHeight);},_innerShow:function(view,contentElement,anchor,preferredWidth,preferredHeight,arrowDirection)
{if(this._disposed)
return;this._contentElement=contentElement;if(WebInspector.Popover._popover)
WebInspector.Popover._popover.hide();WebInspector.Popover._popover=this;var document=anchor instanceof Element?anchor.ownerDocument:contentElement.ownerDocument;var window=document.defaultView;var preferredSize=view?view.measurePreferredSize():WebInspector.measurePreferredSize(this._contentElement);this._preferredWidth=preferredWidth||preferredSize.width;this._preferredHeight=preferredHeight||preferredSize.height;window.addEventListener("resize",this._hideBound,false);document.body.appendChild(this._containerElement);WebInspector.Widget.prototype.show.call(this,this._containerElement);if(view)
view.show(this._contentDiv);else
this._contentDiv.appendChild(this._contentElement);this.positionElement(anchor,this._preferredWidth,this._preferredHeight,arrowDirection);if(this._popoverHelper){this._contentDiv.addEventListener("mousemove",this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper),true);this.element.addEventListener("mouseout",this._popoverHelper._popoverMouseOut.bind(this._popoverHelper),true);}},hide:function()
{this._containerElement.ownerDocument.defaultView.removeEventListener("resize",this._hideBound,false);this.detach();this._containerElement.remove();delete WebInspector.Popover._popover;},get disposed()
{return this._disposed;},dispose:function()
{if(this.isShowing())
this.hide();this._disposed=true;},setCanShrink:function(canShrink)
{this._hasFixedHeight=!canShrink;this._contentDiv.classList.toggle("fixed-height",this._hasFixedHeight);},setNoMargins:function(noMargins)
{this._hasNoMargins=noMargins;this._contentDiv.classList.toggle("no-margin",this._hasNoMargins);},positionElement:function(anchorElement,preferredWidth,preferredHeight,arrowDirection)
{const borderWidth=this._hasNoMargins?0:8;const scrollerWidth=this._hasFixedHeight?0:14;const arrowHeight=this._hasNoMargins?8:15;const arrowOffset=10;const borderRadius=4;const arrowRadius=6;preferredWidth=preferredWidth||this._preferredWidth;preferredHeight=preferredHeight||this._preferredHeight;preferredWidth=Math.max(preferredWidth,50);const container=WebInspector.Dialog.modalHostView().element;const totalWidth=container.offsetWidth;const totalHeight=container.offsetHeight;var anchorBox=anchorElement instanceof AnchorBox?anchorElement:anchorElement.boxInWindow(window);anchorBox=anchorBox.relativeToElement(container);var newElementPosition={x:0,y:0,width:preferredWidth+scrollerWidth,height:preferredHeight};var verticalAlignment;var roomAbove=anchorBox.y;var roomBelow=totalHeight-anchorBox.y-anchorBox.height;this._popupArrowElement.hidden=false;if((roomAbove>roomBelow)||(arrowDirection===WebInspector.Popover.Orientation.Bottom)){if((anchorBox.y>newElementPosition.height+arrowHeight+borderRadius)||(arrowDirection===WebInspector.Popover.Orientation.Bottom))
newElementPosition.y=anchorBox.y-newElementPosition.height-arrowHeight;else{this._popupArrowElement.hidden=true;newElementPosition.y=borderRadius;newElementPosition.height=anchorBox.y-borderRadius*2-arrowHeight;if(this._hasFixedHeight&&newElementPosition.height<preferredHeight){newElementPosition.y=borderRadius;newElementPosition.height=preferredHeight;}}
verticalAlignment=WebInspector.Popover.Orientation.Bottom;}else{newElementPosition.y=anchorBox.y+anchorBox.height+arrowHeight;if((newElementPosition.y+newElementPosition.height+borderRadius>=totalHeight)&&(arrowDirection!==WebInspector.Popover.Orientation.Top)){this._popupArrowElement.hidden=true;newElementPosition.height=totalHeight-borderRadius-newElementPosition.y;if(this._hasFixedHeight&&newElementPosition.height<preferredHeight){newElementPosition.y=totalHeight-preferredHeight-borderRadius;newElementPosition.height=preferredHeight;}}
verticalAlignment=WebInspector.Popover.Orientation.Top;}
var horizontalAlignment;this._popupArrowElement.removeAttribute("style");if(anchorBox.x+newElementPosition.width<totalWidth){newElementPosition.x=Math.max(borderRadius,anchorBox.x-borderRadius-arrowOffset);horizontalAlignment="left";this._popupArrowElement.style.left=arrowOffset+"px";}else if(newElementPosition.width+borderRadius*2<totalWidth){newElementPosition.x=totalWidth-newElementPosition.width-borderRadius-2*borderWidth;horizontalAlignment="right";var arrowRightPosition=Math.max(0,totalWidth-anchorBox.x-anchorBox.width-borderRadius-arrowOffset);arrowRightPosition+=anchorBox.width/2;arrowRightPosition=Math.min(arrowRightPosition,newElementPosition.width-borderRadius-arrowOffset);this._popupArrowElement.style.right=arrowRightPosition+"px";}else{newElementPosition.x=borderRadius;newElementPosition.width=totalWidth-borderRadius*2;newElementPosition.height+=scrollerWidth;horizontalAlignment="left";if(verticalAlignment===WebInspector.Popover.Orientation.Bottom)
newElementPosition.y-=scrollerWidth;this._popupArrowElement.style.left=Math.max(0,anchorBox.x-newElementPosition.x-borderRadius-arrowRadius+anchorBox.width/2)+"px";}
this.element.className=WebInspector.Popover._classNamePrefix+" "+verticalAlignment+"-"+horizontalAlignment+"-arrow";this.element.positionAt(newElementPosition.x,newElementPosition.y-borderWidth,container);this.element.style.width=newElementPosition.width+borderWidth*2+"px";this.element.style.height=newElementPosition.height+borderWidth*2+"px";},__proto__:WebInspector.Widget.prototype}
WebInspector.PopoverHelper=function(panelElement,getAnchor,showPopover,onHide,disableOnClick)
{this._getAnchor=getAnchor;this._showPopover=showPopover;this._onHide=onHide;this._disableOnClick=!!disableOnClick;panelElement.addEventListener("mousedown",this._mouseDown.bind(this),false);panelElement.addEventListener("mousemove",this._mouseMove.bind(this),false);panelElement.addEventListener("mouseout",this._mouseOut.bind(this),false);this.setTimeout(1000,500);}
WebInspector.PopoverHelper.prototype={setTimeout:function(timeout,hideTimeout)
{this._timeout=timeout;if(typeof hideTimeout==="number")
this._hideTimeout=hideTimeout;else
this._hideTimeout=timeout/2;},_eventInHoverElement:function(event)
{if(!this._hoverElement)
return false;var box=this._hoverElement instanceof AnchorBox?this._hoverElement:this._hoverElement.boxInWindow();return(box.x<=event.clientX&&event.clientX<=box.x+box.width&&box.y<=event.clientY&&event.clientY<=box.y+box.height);},_mouseDown:function(event)
{if(this._disableOnClick||!this._eventInHoverElement(event))
this.hidePopover();else{this._killHidePopoverTimer();this._handleMouseAction(event,true);}},_mouseMove:function(event)
{if(this._eventInHoverElement(event))
return;this._startHidePopoverTimer();this._handleMouseAction(event,false);},_popoverMouseOut:function(event)
{if(!this.isPopoverVisible())
return;if(event.relatedTarget&&!event.relatedTarget.isSelfOrDescendant(this._popover._contentDiv))
this._startHidePopoverTimer();},_mouseOut:function(event)
{if(!this.isPopoverVisible())
return;if(!this._eventInHoverElement(event))
this._startHidePopoverTimer();},_startHidePopoverTimer:function()
{if(!this._popover||this._hidePopoverTimer)
return;function doHide()
{this._hidePopover();delete this._hidePopoverTimer;}
this._hidePopoverTimer=setTimeout(doHide.bind(this),this._hideTimeout);},_handleMouseAction:function(event,isMouseDown)
{this._resetHoverTimer();if(event.which&&this._disableOnClick)
return;this._hoverElement=this._getAnchor(event.target,event);if(!this._hoverElement)
return;const toolTipDelay=isMouseDown?0:(this._popup?this._timeout*0.6:this._timeout);this._hoverTimer=setTimeout(this._mouseHover.bind(this,this._hoverElement),toolTipDelay);},_resetHoverTimer:function()
{if(this._hoverTimer){clearTimeout(this._hoverTimer);delete this._hoverTimer;}},isPopoverVisible:function()
{return!!this._popover;},hidePopover:function()
{this._resetHoverTimer();this._hidePopover();},_hidePopover:function()
{if(!this._popover)
return;if(this._onHide)
this._onHide();this._popover.dispose();delete this._popover;this._hoverElement=null;},_mouseHover:function(element)
{delete this._hoverTimer;this._hoverElement=element;this._hidePopover();this._popover=new WebInspector.Popover(this);this._showPopover(element,this._popover);},_killHidePopoverTimer:function()
{if(this._hidePopoverTimer){clearTimeout(this._hidePopoverTimer);delete this._hidePopoverTimer;this._resetHoverTimer();}}}
WebInspector.Popover.Orientation={Top:"top",Bottom:"bottom"};WebInspector.ProgressIndicator=function()
{this.element=createElementWithClass("div","progress-indicator");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/progressIndicator.css");this._contentElement=this._shadowRoot.createChild("div","progress-indicator-shadow-container");this._labelElement=this._contentElement.createChild("div","title");this._progressElement=this._contentElement.createChild("progress");this._progressElement.value=0;this._stopButton=this._contentElement.createChild("button","progress-indicator-shadow-stop-button");this._stopButton.addEventListener("click",this.cancel.bind(this));this._isCanceled=false;this._worked=0;}
WebInspector.ProgressIndicator.prototype={show:function(parent)
{parent.appendChild(this.element);},done:function()
{if(this._isDone)
return;this._isDone=true;this.element.remove();},cancel:function()
{this._isCanceled=true;},isCanceled:function()
{return this._isCanceled;},setTitle:function(title)
{this._labelElement.textContent=title;},setTotalWork:function(totalWork)
{this._progressElement.max=totalWork;},setWorked:function(worked,title)
{this._worked=worked;this._progressElement.value=worked;if(title)
this.setTitle(title);},worked:function(worked)
{this.setWorked(this._worked+(worked||1));}};WebInspector.ResizerWidget=function()
{WebInspector.Object.call(this);this._isEnabled=true;this._elements=[];this._installDragOnMouseDownBound=this._installDragOnMouseDown.bind(this);this._cursor="nwse-resize";};WebInspector.ResizerWidget.Events={ResizeStart:"ResizeStart",ResizeUpdate:"ResizeUpdate",ResizeEnd:"ResizeEnd"};WebInspector.ResizerWidget.prototype={isEnabled:function()
{return this._isEnabled;},setEnabled:function(enabled)
{this._isEnabled=enabled;this.updateElementCursors();},elements:function()
{return this._elements.slice();},addElement:function(element)
{if(this._elements.indexOf(element)!==-1)
return;this._elements.push(element);element.addEventListener("mousedown",this._installDragOnMouseDownBound,false);this._updateElementCursor(element);},removeElement:function(element)
{if(this._elements.indexOf(element)===-1)
return;this._elements.remove(element);element.removeEventListener("mousedown",this._installDragOnMouseDownBound,false);element.style.removeProperty("cursor");},updateElementCursors:function()
{this._elements.forEach(this._updateElementCursor.bind(this));},_updateElementCursor:function(element)
{if(this._isEnabled)
element.style.setProperty("cursor",this.cursor());else
element.style.removeProperty("cursor");},cursor:function()
{return this._cursor;},setCursor:function(cursor)
{this._cursor=cursor;this.updateElementCursors();},_installDragOnMouseDown:function(event)
{if(this._elements.indexOf(event.target)===-1)
return false;WebInspector.elementDragStart((event.target),this._dragStart.bind(this),this._drag.bind(this),this._dragEnd.bind(this),this.cursor(),event);},_dragStart:function(event)
{if(!this._isEnabled)
return false;this._startX=event.pageX;this._startY=event.pageY;this.sendDragStart(this._startX,this._startY);return true;},sendDragStart:function(x,y)
{this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeStart,{startX:x,currentX:x,startY:y,currentY:y});},_drag:function(event)
{if(!this._isEnabled){this._dragEnd(event);return true;}
this.sendDragMove(this._startX,event.pageX,this._startY,event.pageY,event.shiftKey);event.preventDefault();return false;},sendDragMove:function(startX,currentX,startY,currentY,shiftKey)
{this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate,{startX:startX,currentX:currentX,startY:startY,currentY:currentY,shiftKey:shiftKey});},_dragEnd:function(event)
{this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeEnd);delete this._startX;delete this._startY;},__proto__:WebInspector.Object.prototype};WebInspector.SimpleResizerWidget=function()
{WebInspector.ResizerWidget.call(this);this._isVertical=true;};WebInspector.SimpleResizerWidget.prototype={isVertical:function()
{return this._isVertical;},setVertical:function(vertical)
{this._isVertical=vertical;this.updateElementCursors();},cursor:function()
{return this._isVertical?"ns-resize":"ew-resize";},sendDragStart:function(x,y)
{var position=this._isVertical?y:x;this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeStart,{startPosition:position,currentPosition:position});},sendDragMove:function(startX,currentX,startY,currentY,shiftKey)
{if(this._isVertical)
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate,{startPosition:startY,currentPosition:currentY,shiftKey:shiftKey});else
this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate,{startPosition:startX,currentPosition:currentX,shiftKey:shiftKey});},__proto__:WebInspector.ResizerWidget.prototype};;WebInspector.ReportView=function(title)
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("ui/reportView.css");var contentBox=this.contentElement.createChild("div","report-content-box");this._headerElement=contentBox.createChild("div","report-header vbox");this._headerElement.createChild("div","report-title").textContent=title;this._sectionList=contentBox.createChild("div","vbox");}
WebInspector.ReportView.prototype={setSubtitle:function(subtitle)
{if(this._subtitleElement&&this._subtitleElement.textContent===subtitle)
return;if(!this._subtitleElement)
this._subtitleElement=this._headerElement.createChild("div","report-subtitle");this._subtitleElement.textContent=subtitle;},setURL:function(url)
{if(this._url===url)
return;if(!this._urlElement)
this._urlElement=this._headerElement.createChild("div","report-url link");this._url=url;this._urlElement.removeChildren();if(url)
this._urlElement.appendChild(WebInspector.linkifyURLAsNode(url));},createToolbar:function()
{var toolbar=new WebInspector.Toolbar("");this._headerElement.appendChild(toolbar.element);return toolbar;},appendSection:function(title,className)
{var section=new WebInspector.ReportView.Section(title,className);section.show(this._sectionList);return section;},removeAllSection:function()
{this._sectionList.removeChildren();},__proto__:WebInspector.VBox.prototype}
WebInspector.ReportView.Section=function(title,className)
{WebInspector.VBox.call(this);this.element.classList.add("report-section");if(className)
this.element.classList.add(className);this._headerElement=this.element.createChild("div","report-section-header");this._titleElement=this._headerElement.createChild("div","report-section-title");this._titleElement.textContent=title;this._fieldList=this.element.createChild("div","vbox");this._fieldMap=new Map();}
WebInspector.ReportView.Section.prototype={setTitle:function(title)
{if(this._titleElement.textContent!==title)
this._titleElement.textContent=title;},createToolbar:function()
{var toolbar=new WebInspector.Toolbar("");this._headerElement.appendChild(toolbar.element);return toolbar;},appendField:function(title,textValue)
{var row=this._fieldMap.get(title);if(!row){row=this._fieldList.createChild("div","report-field");row.createChild("div","report-field-name").textContent=title;this._fieldMap.set(title,row);row.createChild("div","report-field-value");}
if(textValue)
row.lastElementChild.textContent=textValue;return(row.lastElementChild);},remove:function()
{this.element.remove();},removeField:function(title)
{var row=this._fieldMap.get(title);if(row)
row.remove();this._fieldMap.delete(title);},setFieldVisible:function(title,visible)
{var row=this._fieldMap.get(title);if(row)
row.classList.toggle("hidden",!visible);},fieldValue:function(title)
{var row=this._fieldMap.get(title);return row?row.lastElementChild:null;},appendRow:function()
{return this._fieldList.createChild("div","report-row");},clearContent:function()
{this._fieldList.removeChildren();this._fieldMap.clear();},__proto__:WebInspector.VBox.prototype};WebInspector.RootView=function()
{WebInspector.VBox.call(this);this.markAsRoot();this.element.classList.add("root-view");this.element.setAttribute("spellcheck",false);}
WebInspector.RootView.prototype={attachToDocument:function(document)
{document.defaultView.addEventListener("resize",this.doResize.bind(this),false);this._window=document.defaultView;this.doResize();this.show(document.body);},doResize:function()
{if(this._window){var size=this.constraints().minimum;var zoom=WebInspector.zoomManager.zoomFactor();var right=Math.min(0,this._window.innerWidth-size.width/zoom);this.element.style.marginRight=right+"px";var bottom=Math.min(0,this._window.innerHeight-size.height/zoom);this.element.style.marginBottom=bottom+"px";}
WebInspector.VBox.prototype.doResize.call(this);},__proto__:WebInspector.VBox.prototype};WebInspector.SearchableView=function(searchable,settingName)
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("ui/searchableView.css");this.element[WebInspector.SearchableView._symbol]=this;this._searchProvider=searchable;this._setting=settingName?WebInspector.settings.createSetting(settingName,{}):null;this.contentElement.createChild("content");this._footerElementContainer=this.contentElement.createChild("div","search-bar hidden");this._footerElementContainer.style.order=100;var toolbar=new WebInspector.Toolbar("search-toolbar",this._footerElementContainer);if(this._searchProvider.supportsCaseSensitiveSearch()){this._caseSensitiveButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Case sensitive"),"");this._caseSensitiveButton.setText("Aa");this._caseSensitiveButton.addEventListener("click",this._toggleCaseSensitiveSearch,this);toolbar.appendToolbarItem(this._caseSensitiveButton);}
if(this._searchProvider.supportsRegexSearch()){this._regexButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Regex"),"");this._regexButton.setText(".*");this._regexButton.addEventListener("click",this._toggleRegexSearch,this);toolbar.appendToolbarItem(this._regexButton);}
this._footerElement=this._footerElementContainer.createChild("table","toolbar-search");this._footerElement.cellSpacing=0;this._firstRowElement=this._footerElement.createChild("tr");this._secondRowElement=this._footerElement.createChild("tr","hidden");var searchControlElementColumn=this._firstRowElement.createChild("td");this._searchControlElement=searchControlElementColumn.createChild("span","toolbar-search-control");this._searchInputElement=WebInspector.HistoryInput.create();this._searchInputElement.classList.add("search-replace");this._searchControlElement.appendChild(this._searchInputElement);this._searchInputElement.id="search-input-field";this._searchInputElement.placeholder=WebInspector.UIString("Find");this._matchesElement=this._searchControlElement.createChild("label","search-results-matches");this._matchesElement.setAttribute("for","search-input-field");this._searchNavigationElement=this._searchControlElement.createChild("div","toolbar-search-navigation-controls");this._searchNavigationPrevElement=this._searchNavigationElement.createChild("div","toolbar-search-navigation toolbar-search-navigation-prev");this._searchNavigationPrevElement.addEventListener("click",this._onPrevButtonSearch.bind(this),false);this._searchNavigationPrevElement.title=WebInspector.UIString("Search Previous");this._searchNavigationNextElement=this._searchNavigationElement.createChild("div","toolbar-search-navigation toolbar-search-navigation-next");this._searchNavigationNextElement.addEventListener("click",this._onNextButtonSearch.bind(this),false);this._searchNavigationNextElement.title=WebInspector.UIString("Search Next");this._searchInputElement.addEventListener("mousedown",this._onSearchFieldManualFocus.bind(this),false);this._searchInputElement.addEventListener("keydown",this._onSearchKeyDown.bind(this),true);this._searchInputElement.addEventListener("input",this._onInput.bind(this),false);this._replaceInputElement=this._secondRowElement.createChild("td").createChild("input","search-replace toolbar-replace-control");this._replaceInputElement.addEventListener("keydown",this._onReplaceKeyDown.bind(this),true);this._replaceInputElement.placeholder=WebInspector.UIString("Replace");this._findButtonElement=this._firstRowElement.createChild("td").createChild("button","search-action-button hidden");this._findButtonElement.textContent=WebInspector.UIString("Find");this._findButtonElement.tabIndex=-1;this._findButtonElement.addEventListener("click",this._onFindClick.bind(this),false);this._replaceButtonElement=this._secondRowElement.createChild("td").createChild("button","search-action-button");this._replaceButtonElement.textContent=WebInspector.UIString("Replace");this._replaceButtonElement.disabled=true;this._replaceButtonElement.tabIndex=-1;this._replaceButtonElement.addEventListener("click",this._replace.bind(this),false);this._prevButtonElement=this._firstRowElement.createChild("td").createChild("button","search-action-button hidden");this._prevButtonElement.textContent=WebInspector.UIString("Previous");this._prevButtonElement.tabIndex=-1;this._prevButtonElement.addEventListener("click",this._onPreviousClick.bind(this),false);this._replaceAllButtonElement=this._secondRowElement.createChild("td").createChild("button","search-action-button");this._replaceAllButtonElement.textContent=WebInspector.UIString("Replace All");this._replaceAllButtonElement.addEventListener("click",this._replaceAll.bind(this),false);this._replaceElement=this._firstRowElement.createChild("td").createChild("span");this._replaceLabelElement=createCheckboxLabel(WebInspector.UIString("Replace"));this._replaceCheckboxElement=this._replaceLabelElement.checkboxElement;this._uniqueId=++WebInspector.SearchableView._lastUniqueId;var replaceCheckboxId="search-replace-trigger"+this._uniqueId;this._replaceCheckboxElement.id=replaceCheckboxId;this._replaceCheckboxElement.addEventListener("change",this._updateSecondRowVisibility.bind(this),false);this._replaceElement.appendChild(this._replaceLabelElement);var cancelButtonElement=this._firstRowElement.createChild("td").createChild("button","search-action-button");cancelButtonElement.textContent=WebInspector.UIString("Cancel");cancelButtonElement.tabIndex=-1;cancelButtonElement.addEventListener("click",this.closeSearch.bind(this),false);this._minimalSearchQuerySize=3;this._loadSetting();}
WebInspector.SearchableView._lastUniqueId=0;WebInspector.SearchableView._symbol=Symbol("searchableView");WebInspector.SearchableView.fromElement=function(element)
{var view=null;while(element&&!view){view=element[WebInspector.SearchableView._symbol];element=element.parentElementOrShadowHost();}
return view;}
WebInspector.SearchableView.prototype={_toggleCaseSensitiveSearch:function()
{this._caseSensitiveButton.setToggled(!this._caseSensitiveButton.toggled());this._saveSetting();this._performSearch(false,true);},_toggleRegexSearch:function()
{this._regexButton.setToggled(!this._regexButton.toggled());this._saveSetting();this._performSearch(false,true);},_saveSetting:function()
{if(!this._setting)
return;var settingValue=this._setting.get()||{};settingValue.caseSensitive=this._caseSensitiveButton.toggled();settingValue.isRegex=this._regexButton.toggled();this._setting.set(settingValue);},_loadSetting:function()
{var settingValue=this._setting?(this._setting.get()||{}):{};if(this._searchProvider.supportsCaseSensitiveSearch())
this._caseSensitiveButton.setToggled(!!settingValue.caseSensitive);if(this._searchProvider.supportsRegexSearch())
this._regexButton.setToggled(!!settingValue.isRegex);},defaultFocusedElement:function()
{var children=this.children();for(var i=0;i<children.length;++i){var element=children[i].defaultFocusedElement();if(element)
return element;}
return WebInspector.Widget.prototype.defaultFocusedElement.call(this);},setMinimalSearchQuerySize:function(minimalSearchQuerySize)
{this._minimalSearchQuerySize=minimalSearchQuerySize;},setPlaceholder:function(placeholder)
{this._searchInputElement.placeholder=placeholder;},setReplaceable:function(replaceable)
{this._replaceable=replaceable;},updateSearchMatchesCount:function(matches)
{this._searchProvider.currentSearchMatches=matches;this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentQuery?matches:0,-1);},updateCurrentMatchIndex:function(currentMatchIndex)
{this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentSearchMatches,currentMatchIndex);},isSearchVisible:function()
{return this._searchIsVisible;},closeSearch:function()
{this.cancelSearch();if(WebInspector.currentFocusElement()&&WebInspector.currentFocusElement().isDescendant(this._footerElementContainer))
this.focus();},_toggleSearchBar:function(toggled)
{this._footerElementContainer.classList.toggle("hidden",!toggled);this.doResize();},cancelSearch:function()
{if(!this._searchIsVisible)
return;this.resetSearch();delete this._searchIsVisible;this._toggleSearchBar(false);},resetSearch:function()
{this._clearSearch();this._updateReplaceVisibility();this._matchesElement.textContent="";},refreshSearch:function()
{if(!this._searchIsVisible)
return;this.resetSearch();this._performSearch(false,false);},handleFindNextShortcut:function()
{if(!this._searchIsVisible)
return false;this._searchProvider.jumpToNextSearchResult();return true;},handleFindPreviousShortcut:function()
{if(!this._searchIsVisible)
return false;this._searchProvider.jumpToPreviousSearchResult();return true;},handleFindShortcut:function()
{this.showSearchField();return true;},handleCancelSearchShortcut:function()
{if(!this._searchIsVisible)
return false;this.closeSearch();return true;},_updateSearchNavigationButtonState:function(enabled)
{this._replaceButtonElement.disabled=!enabled;if(enabled){this._searchNavigationPrevElement.classList.add("enabled");this._searchNavigationNextElement.classList.add("enabled");}else{this._searchNavigationPrevElement.classList.remove("enabled");this._searchNavigationNextElement.classList.remove("enabled");}},_updateSearchMatchesCountAndCurrentMatchIndex:function(matches,currentMatchIndex)
{if(!this._currentQuery)
this._matchesElement.textContent="";else if(matches===0||currentMatchIndex>=0)
this._matchesElement.textContent=WebInspector.UIString("%d of %d",currentMatchIndex+1,matches);else if(matches===1)
this._matchesElement.textContent=WebInspector.UIString("1 match");else
this._matchesElement.textContent=WebInspector.UIString("%d matches",matches);this._updateSearchNavigationButtonState(matches>0);},showSearchField:function()
{if(this._searchIsVisible)
this.cancelSearch();var queryCandidate;if(WebInspector.currentFocusElement()!==this._searchInputElement){var selection=this._searchInputElement.getComponentSelection();if(selection.rangeCount)
queryCandidate=selection.toString().replace(/\r?\n.*/,"");}
this._toggleSearchBar(true);this._updateReplaceVisibility();if(queryCandidate)
this._searchInputElement.value=queryCandidate;this._performSearch(false,false);this._searchInputElement.focus();this._searchInputElement.select();this._searchIsVisible=true;},_updateReplaceVisibility:function()
{this._replaceElement.classList.toggle("hidden",!this._replaceable);if(!this._replaceable){this._replaceCheckboxElement.checked=false;this._updateSecondRowVisibility();}},_onSearchFieldManualFocus:function(event)
{WebInspector.setCurrentFocusElement((event.target));},_onSearchKeyDown:function(event)
{if(!isEnterKey(event))
return;if(!this._currentQuery)
this._performSearch(true,true,event.shiftKey);else
this._jumpToNextSearchResult(event.shiftKey);},_onReplaceKeyDown:function(event)
{if(isEnterKey(event))
this._replace();},_jumpToNextSearchResult:function(isBackwardSearch)
{if(!this._currentQuery||!this._searchNavigationPrevElement.classList.contains("enabled"))
return;if(isBackwardSearch)
this._searchProvider.jumpToPreviousSearchResult();else
this._searchProvider.jumpToNextSearchResult();},_onNextButtonSearch:function(event)
{if(!this._searchNavigationNextElement.classList.contains("enabled"))
return;this._jumpToNextSearchResult();this._searchInputElement.focus();},_onPrevButtonSearch:function(event)
{if(!this._searchNavigationPrevElement.classList.contains("enabled"))
return;this._jumpToNextSearchResult(true);this._searchInputElement.focus();},_onFindClick:function(event)
{if(!this._currentQuery)
this._performSearch(true,true);else
this._jumpToNextSearchResult();this._searchInputElement.focus();},_onPreviousClick:function(event)
{if(!this._currentQuery)
this._performSearch(true,true,true);else
this._jumpToNextSearchResult(true);this._searchInputElement.focus();},_clearSearch:function()
{delete this._currentQuery;if(!!this._searchProvider.currentQuery){delete this._searchProvider.currentQuery;this._searchProvider.searchCanceled();}
this._updateSearchMatchesCountAndCurrentMatchIndex(0,-1);},_performSearch:function(forceSearch,shouldJump,jumpBackwards)
{var query=this._searchInputElement.value;if(!query||(!forceSearch&&query.length<this._minimalSearchQuerySize&&!this._currentQuery)){this._clearSearch();return;}
this._currentQuery=query;this._searchProvider.currentQuery=query;var searchConfig=this._currentSearchConfig();this._searchProvider.performSearch(searchConfig,shouldJump,jumpBackwards);},_currentSearchConfig:function()
{var query=this._searchInputElement.value;var caseSensitive=this._caseSensitiveButton?this._caseSensitiveButton.toggled():false;var isRegex=this._regexButton?this._regexButton.toggled():false;return new WebInspector.SearchableView.SearchConfig(query,caseSensitive,isRegex);},_updateSecondRowVisibility:function()
{var secondRowVisible=this._replaceCheckboxElement.checked;this._footerElementContainer.classList.toggle("replaceable",secondRowVisible);this._footerElement.classList.toggle("toolbar-search-replace",secondRowVisible);this._secondRowElement.classList.toggle("hidden",!secondRowVisible);this._prevButtonElement.classList.toggle("hidden",!secondRowVisible);this._findButtonElement.classList.toggle("hidden",!secondRowVisible);this._replaceCheckboxElement.tabIndex=secondRowVisible?-1:0;if(secondRowVisible)
this._replaceInputElement.focus();else
this._searchInputElement.focus();this.doResize();},_replace:function()
{var searchConfig=this._currentSearchConfig();(this._searchProvider).replaceSelectionWith(searchConfig,this._replaceInputElement.value);delete this._currentQuery;this._performSearch(true,true);},_replaceAll:function()
{var searchConfig=this._currentSearchConfig();(this._searchProvider).replaceAllWith(searchConfig,this._replaceInputElement.value);},_onInput:function(event)
{if(this._valueChangedTimeoutId)
clearTimeout(this._valueChangedTimeoutId);var timeout=this._searchInputElement.value.length<3?200:0;this._valueChangedTimeoutId=setTimeout(this._onValueChanged.bind(this),timeout);},_onValueChanged:function()
{delete this._valueChangedTimeoutId;this._performSearch(false,true);},__proto__:WebInspector.VBox.prototype}
WebInspector.Searchable=function()
{}
WebInspector.Searchable.prototype={searchCanceled:function(){},performSearch:function(searchConfig,shouldJump,jumpBackwards){},jumpToNextSearchResult:function(){},jumpToPreviousSearchResult:function(){},supportsCaseSensitiveSearch:function(){},supportsRegexSearch:function(){}}
WebInspector.Replaceable=function()
{}
WebInspector.Replaceable.prototype={replaceSelectionWith:function(searchConfig,replacement){},replaceAllWith:function(searchConfig,replacement){}}
WebInspector.SearchableView.SearchConfig=function(query,caseSensitive,isRegex)
{this.query=query;this.caseSensitive=caseSensitive;this.isRegex=isRegex;}
WebInspector.SearchableView.SearchConfig.prototype={toSearchRegex:function(global)
{var modifiers=this.caseSensitive?"":"i";if(global)
modifiers+="g";var query=this.isRegex?"/"+this.query+"/":this.query;var regex;try{if(/^\/.+\/$/.test(query)){regex=new RegExp(query.substring(1,query.length-1),modifiers);regex.__fromRegExpQuery=true;}}catch(e){}
if(!regex)
regex=createPlainTextSearchRegex(query,modifiers);return regex;}};WebInspector.Section=function(title,subtitle)
{this.element=createElementWithClass("div","section");this.element._section=this;this.registerRequiredCSS("ui/section.css");this.headerElement=createElementWithClass("div","header monospace");this.titleElement=createElementWithClass("div","title");this.subtitleElement=createElementWithClass("div","subtitle");this.headerElement.appendChild(this.subtitleElement);this.headerElement.appendChild(this.titleElement);this.headerElement.addEventListener("click",this.handleClick.bind(this),false);this.element.appendChild(this.headerElement);this.title=title;if(subtitle){this._subtitle=subtitle;this.subtitleElement.textContent=subtitle;}
this._expanded=false;}
WebInspector.Section.prototype={get title()
{return this._title;},set title(x)
{if(this._title===x)
return;this._title=x;if(x instanceof Node){this.titleElement.removeChildren();this.titleElement.appendChild(x);}else
this.titleElement.textContent=x;},get subtitle()
{return this._subtitle;},get expanded()
{return this._expanded;},repopulate:function()
{this._populated=false;if(this._expanded){this.onpopulate();this._populated=true;}},onpopulate:function()
{},expand:function()
{if(this._expanded)
return;this._expanded=true;this.element.classList.add("expanded");if(!this._populated){this.onpopulate();this._populated=true;}},collapse:function()
{if(!this._expanded)
return;this._expanded=false;this.element.classList.remove("expanded");},registerRequiredCSS:function(cssFile)
{WebInspector.appendStyle(this.element,cssFile);},handleClick:function(event)
{if(this._doNotExpandOnTitleClick)
return;if(this._expanded)
this.collapse();else
this.expand();event.consume();},doNotExpandOnTitleClick:function()
{this._doNotExpandOnTitleClick=true;}}
WebInspector.PropertiesSection=function(title,subtitle)
{WebInspector.Section.call(this,title,subtitle);this.registerRequiredCSS("ui/propertiesSection.css");this.propertiesTreeOutline=new TreeOutline(true);this.propertiesElement=this.propertiesTreeOutline.element;this.propertiesElement.classList.add("properties","properties-tree","monospace");this.propertiesTreeOutline.setFocusable(false);this.propertiesTreeOutline.section=this;this.element.appendChild(this.propertiesElement);}
WebInspector.PropertiesSection.prototype={__proto__:WebInspector.Section.prototype};WebInspector.SettingsUI={}
WebInspector.SettingsUI.createSettingCheckbox=function(name,setting,omitParagraphElement,tooltip)
{var label=createCheckboxLabel(name);if(tooltip)
label.title=tooltip;var input=label.checkboxElement;input.name=name;WebInspector.SettingsUI.bindCheckbox(input,setting);if(omitParagraphElement)
return label;var p=createElement("p");p.appendChild(label);return p;}
WebInspector.SettingsUI.bindCheckbox=function(input,setting)
{function settingChanged()
{if(input.checked!==setting.get())
input.checked=setting.get();}
setting.addChangeListener(settingChanged);settingChanged();function inputChanged()
{if(setting.get()!==input.checked)
setting.set(input.checked);}
input.addEventListener("change",inputChanged,false);}
WebInspector.SettingsUI.createCustomSetting=function(name,element)
{var p=createElement("p");var fieldsetElement=p.createChild("fieldset");fieldsetElement.createChild("label").textContent=name;fieldsetElement.appendChild(element);return p;}
WebInspector.SettingsUI.createSettingFieldset=function(setting)
{var fieldset=createElement("fieldset");fieldset.disabled=!setting.get();setting.addChangeListener(settingChanged);return fieldset;function settingChanged()
{fieldset.disabled=!setting.get();}}
WebInspector.SettingUI=function()
{}
WebInspector.SettingUI.prototype={settingElement:function(){}};WebInspector.SidebarSectionTreeElement=function(title)
{TreeElement.call(this,title.escapeHTML(),true);this.expand();}
WebInspector.SidebarSectionTreeElement.prototype={selectable:false,collapse:function()
{},get smallChildren()
{return this._smallChildren;},set smallChildren(x)
{if(this._smallChildren===x)
return;this._smallChildren=x;this._childrenListNode.classList.toggle("small",this._smallChildren);},onattach:function()
{this.listItemElement.classList.add("sidebar-tree-section");},__proto__:TreeElement.prototype}
WebInspector.SidebarTreeElement=function(className,title,subtitle,expandable)
{TreeElement.call(this,"",expandable);if(expandable)
this.disclosureButton=createElementWithClass("button","disclosure-button");this.iconElement=createElementWithClass("div","icon");this.statusElement=createElementWithClass("div","status");this._titlesElement=createElementWithClass("div","titles");this.titleContainer=this._titlesElement.createChild("span","title-container");this.titleElement=this.titleContainer.createChild("span","title");this.subtitleElement=this._titlesElement.createChild("span","subtitle");this.className=className;this.mainTitle=title;this.subtitle=subtitle;}
WebInspector.SidebarTreeElement.prototype={get small()
{return this._small;},set small(x)
{this._small=x;if(this.listItemElement)
this.listItemElement.classList.toggle("small",this._small);},get mainTitle()
{return this._mainTitle;},set mainTitle(x)
{this._mainTitle=x;this.refreshTitles();},get subtitle()
{return this._subtitle;},set subtitle(x)
{this._subtitle=x;this.refreshTitles();},set wait(x)
{this.listItemElement.classList.toggle("wait",x);},refreshTitles:function()
{var mainTitle=this.mainTitle;if(this.titleElement.textContent!==mainTitle)
this.titleElement.textContent=mainTitle;var subtitle=this.subtitle;if(subtitle){if(this.subtitleElement.textContent!==subtitle)
this.subtitleElement.textContent=subtitle;this._titlesElement.classList.remove("no-subtitle");}else{this.subtitleElement.textContent="";this._titlesElement.classList.add("no-subtitle");}},isEventWithinDisclosureTriangle:function(event)
{return event.target===this.disclosureButton;},onattach:function()
{this.listItemElement.classList.add("sidebar-tree-item");if(this.className)
this.listItemElement.classList.add(this.className);if(this.small)
this.listItemElement.classList.add("small");if(this.isExpandable()&&this.disclosureButton)
this.listItemElement.appendChild(this.disclosureButton);this.listItemElement.appendChildren(this.iconElement,this.statusElement,this._titlesElement);},__proto__:TreeElement.prototype};WebInspector.SoftContextMenu=function(items,itemSelectedCallback,parentMenu)
{this._items=items;this._itemSelectedCallback=itemSelectedCallback;this._parentMenu=parentMenu;}
WebInspector.SoftContextMenu.prototype={show:function(document,x,y)
{if(!this._items.length)
return;this._document=document;this._x=x;this._y=y;this._time=new Date().getTime();this.element=createElementWithClass("div","soft-context-menu");var root=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/softContextMenu.css");this._contextMenuElement=root.createChild("div");this.element.style.top=y+"px";var subMenuOverlap=3;this.element.style.left=(this._parentMenu?x-subMenuOverlap:x)+"px";this._contextMenuElement.tabIndex=0;this._contextMenuElement.addEventListener("mouseup",consumeEvent,false);this._contextMenuElement.addEventListener("keydown",this._menuKeyDown.bind(this),false);for(var i=0;i<this._items.length;++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));if(!this._parentMenu){this._glassPaneElement=createElementWithClass("div","soft-context-menu-glass-pane fill");this._glassPaneElement.tabIndex=0;this._glassPaneElement.addEventListener("mouseup",this._glassPaneMouseUp.bind(this),false);this._glassPaneElement.appendChild(this.element);document.body.appendChild(this._glassPaneElement);this._discardMenuOnResizeListener=this._discardMenu.bind(this,true);document.defaultView.addEventListener("resize",this._discardMenuOnResizeListener,false);}else{this._parentMenu._parentGlassPaneElement().appendChild(this.element);}
if(document.body.offsetWidth<this.element.offsetLeft+this.element.offsetWidth){this.element.style.left=Math.max(WebInspector.Dialog.modalHostView().element.totalOffsetLeft(),this._parentMenu?this._parentMenu.element.offsetLeft-this.element.offsetWidth+subMenuOverlap:document.body.offsetWidth-this.element.offsetWidth)+"px";}
if(this._parentMenu&&document.body.offsetHeight<this.element.offsetTop+this.element.offsetHeight){y=Math.max(WebInspector.Dialog.modalHostView().element.totalOffsetTop(),document.body.offsetHeight-this.element.offsetHeight);this.element.style.top=y+"px";}
var maxHeight=WebInspector.Dialog.modalHostView().element.offsetHeight;maxHeight-=y-WebInspector.Dialog.modalHostView().element.totalOffsetTop();this.element.style.maxHeight=maxHeight+"px";this._focus();},discard:function()
{this._discardMenu(true);},_parentGlassPaneElement:function()
{if(this._glassPaneElement)
return this._glassPaneElement;if(this._parentMenu)
return this._parentMenu._parentGlassPaneElement();return null;},_createMenuItem:function(item)
{if(item.type==="separator")
return this._createSeparator();if(item.type==="subMenu")
return this._createSubMenu(item);var menuItemElement=createElementWithClass("div","soft-context-menu-item");var checkMarkElement=menuItemElement.createChild("div","checkmark");if(!item.checked)
checkMarkElement.style.opacity="0";if(item.element){var wrapper=menuItemElement.createChild("div","soft-context-menu-custom-item");wrapper.appendChild(item.element);menuItemElement._isCustom=true;return menuItemElement;}
if(!item.enabled)
menuItemElement.classList.add("soft-context-menu-disabled");menuItemElement.createTextChild(item.label);menuItemElement.createChild("span","soft-context-menu-shortcut").textContent=item.shortcut;menuItemElement.addEventListener("mousedown",this._menuItemMouseDown.bind(this),false);menuItemElement.addEventListener("mouseup",this._menuItemMouseUp.bind(this),false);menuItemElement.addEventListener("mouseover",this._menuItemMouseOver.bind(this),false);menuItemElement.addEventListener("mouseleave",this._menuItemMouseLeave.bind(this),false);menuItemElement._actionId=item.id;return menuItemElement;},_createSubMenu:function(item)
{var menuItemElement=createElementWithClass("div","soft-context-menu-item");menuItemElement._subItems=item.subItems;var checkMarkElement=menuItemElement.createChild("span","soft-context-menu-item-checkmark checkmark");checkMarkElement.textContent="\u2713 ";checkMarkElement.style.opacity="0";menuItemElement.createTextChild(item.label);var subMenuArrowElement=menuItemElement.createChild("span","soft-context-menu-item-submenu-arrow");subMenuArrowElement.textContent="\u25B6";menuItemElement.addEventListener("mousedown",this._menuItemMouseDown.bind(this),false);menuItemElement.addEventListener("mouseup",this._menuItemMouseUp.bind(this),false);menuItemElement.addEventListener("mouseover",this._menuItemMouseOver.bind(this),false);menuItemElement.addEventListener("mouseleave",this._menuItemMouseLeave.bind(this),false);return menuItemElement;},_createSeparator:function()
{var separatorElement=createElementWithClass("div","soft-context-menu-separator");separatorElement._isSeparator=true;separatorElement.createChild("div","separator-line");return separatorElement;},_menuItemMouseDown:function(event)
{event.consume(true);},_menuItemMouseUp:function(event)
{this._triggerAction(event.target,event);event.consume();},_focus:function()
{this._contextMenuElement.focus();},_triggerAction:function(menuItemElement,event)
{if(!menuItemElement._subItems){this._discardMenu(true,event);if(typeof menuItemElement._actionId!=="undefined"){this._itemSelectedCallback(menuItemElement._actionId);delete menuItemElement._actionId;}
return;}
this._showSubMenu(menuItemElement);event.consume();},_showSubMenu:function(menuItemElement)
{if(menuItemElement._subMenuTimer){clearTimeout(menuItemElement._subMenuTimer);delete menuItemElement._subMenuTimer;}
if(this._subMenu)
return;this._subMenu=new WebInspector.SoftContextMenu(menuItemElement._subItems,this._itemSelectedCallback,this);var topPadding=4;this._subMenu.show(this._document,menuItemElement.totalOffsetLeft()+menuItemElement.offsetWidth,menuItemElement.totalOffsetTop()-1-topPadding);},_hideSubMenu:function()
{if(!this._subMenu)
return;this._subMenu._discardSubMenus();this._focus();},_menuItemMouseOver:function(event)
{this._highlightMenuItem(event.target,true);},_menuItemMouseLeave:function(event)
{if(!this._subMenu||!event.relatedTarget){this._highlightMenuItem(null,true);return;}
var relatedTarget=event.relatedTarget;if(relatedTarget.classList.contains("soft-context-menu-glass-pane"))
this._highlightMenuItem(null,true);},_highlightMenuItem:function(menuItemElement,scheduleSubMenu)
{if(this._highlightedMenuItemElement===menuItemElement)
return;this._hideSubMenu();if(this._highlightedMenuItemElement){this._highlightedMenuItemElement.classList.remove("soft-context-menu-item-mouse-over");if(this._highlightedMenuItemElement._subItems&&this._highlightedMenuItemElement._subMenuTimer){clearTimeout(this._highlightedMenuItemElement._subMenuTimer);delete this._highlightedMenuItemElement._subMenuTimer;}}
this._highlightedMenuItemElement=menuItemElement;if(this._highlightedMenuItemElement){this._highlightedMenuItemElement.classList.add("soft-context-menu-item-mouse-over");this._contextMenuElement.focus();if(scheduleSubMenu&&this._highlightedMenuItemElement._subItems&&!this._highlightedMenuItemElement._subMenuTimer)
this._highlightedMenuItemElement._subMenuTimer=setTimeout(this._showSubMenu.bind(this,this._highlightedMenuItemElement),150);}},_highlightPrevious:function()
{var menuItemElement=this._highlightedMenuItemElement?this._highlightedMenuItemElement.previousSibling:this._contextMenuElement.lastChild;while(menuItemElement&&(menuItemElement._isSeparator||menuItemElement._isCustom))
menuItemElement=menuItemElement.previousSibling;if(menuItemElement)
this._highlightMenuItem(menuItemElement,false);},_highlightNext:function()
{var menuItemElement=this._highlightedMenuItemElement?this._highlightedMenuItemElement.nextSibling:this._contextMenuElement.firstChild;while(menuItemElement&&(menuItemElement._isSeparator||menuItemElement._isCustom))
menuItemElement=menuItemElement.nextSibling;if(menuItemElement)
this._highlightMenuItem(menuItemElement,false);},_menuKeyDown:function(event)
{switch(event.keyIdentifier){case"Up":this._highlightPrevious();break;case"Down":this._highlightNext();break;case"Left":if(this._parentMenu){this._highlightMenuItem(null,false);this._parentMenu._hideSubMenu();}
break;case"Right":if(!this._highlightedMenuItemElement)
break;if(this._highlightedMenuItemElement._subItems){this._showSubMenu(this._highlightedMenuItemElement);this._subMenu._focus();this._subMenu._highlightNext();}
break;case"U+001B":this._discardMenu(false,event);break;case"Enter":if(!isEnterKey(event))
break;case"U+0020":if(this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement,event);if(this._highlightedMenuItemElement._subItems){this._subMenu._focus();this._subMenu._highlightNext();}
break;}
event.consume(true);},_glassPaneMouseUp:function(event)
{if(new Date().getTime()-this._time<300)
return;if(event.target===this.element)
return;this._discardMenu(true,event);event.consume();},_discardMenu:function(closeParentMenus,event)
{if(this._subMenu&&!closeParentMenus)
return;if(this._glassPaneElement){var glassPane=this._glassPaneElement;delete this._glassPaneElement;this._document.body.removeChild(glassPane);if(this._parentMenu){delete this._parentMenu._subMenu;if(closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus,event);else
this._parentMenu._focus();}
if(event)
event.consume(true);}else if(this._parentMenu&&this._contextMenuElement.parentElementOrShadowHost()){this._discardSubMenus();if(closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus,event);else
this._parentMenu._focus();if(event)
event.consume(true);}
if(this._discardMenuOnResizeListener){this._document.defaultView.removeEventListener("resize",this._discardMenuOnResizeListener,false);delete this._discardMenuOnResizeListener;}},_discardSubMenus:function()
{if(this._subMenu)
this._subMenu._discardSubMenus();this.element.remove();if(this._parentMenu)
delete this._parentMenu._subMenu;}};WebInspector.SplitWidget=function(isVertical,secondIsSidebar,settingName,defaultSidebarWidth,defaultSidebarHeight,constraintsInDip)
{WebInspector.Widget.call(this,true);this.element.classList.add("split-widget");this.registerRequiredCSS("ui/splitWidget.css");this.contentElement.classList.add("shadow-split-widget");this._mainElement=this.contentElement.createChild("div","shadow-split-widget-contents shadow-split-widget-main vbox");this._mainElement.createChild("content").select=".insertion-point-main";this._sidebarElement=this.contentElement.createChild("div","shadow-split-widget-contents shadow-split-widget-sidebar vbox");this._sidebarElement.createChild("content").select=".insertion-point-sidebar";this._resizerElement=this.contentElement.createChild("div","shadow-split-widget-resizer");this._resizerWidget=new WebInspector.SimpleResizerWidget();this._resizerWidget.setEnabled(true);this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart,this._onResizeStart,this);this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate,this._onResizeUpdate,this);this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd,this._onResizeEnd,this);this._defaultSidebarWidth=defaultSidebarWidth||200;this._defaultSidebarHeight=defaultSidebarHeight||this._defaultSidebarWidth;this._constraintsInDip=!!constraintsInDip;this._setting=settingName?WebInspector.settings.createSetting(settingName,{}):null;this.setSecondIsSidebar(secondIsSidebar);this._innerSetVertical(isVertical);this._showMode=WebInspector.SplitWidget.ShowMode.Both;this.installResizer(this._resizerElement);}
WebInspector.SplitWidget.SettingForOrientation;WebInspector.SplitWidget.ShowMode={Both:"Both",OnlyMain:"OnlyMain",OnlySidebar:"OnlySidebar"}
WebInspector.SplitWidget.Events={SidebarSizeChanged:"SidebarSizeChanged",ShowModeChanged:"ShowModeChanged"}
WebInspector.SplitWidget.MinPadding=20;WebInspector.SplitWidget.prototype={isVertical:function()
{return this._isVertical;},setVertical:function(isVertical)
{if(this._isVertical===isVertical)
return;this._innerSetVertical(isVertical);if(this.isShowing())
this._updateLayout();},_innerSetVertical:function(isVertical)
{this.contentElement.classList.toggle("vbox",!isVertical);this.contentElement.classList.toggle("hbox",isVertical);this._isVertical=isVertical;delete this._resizerElementSize;this._sidebarSizeDIP=-1;this._restoreSidebarSizeFromSettings();if(this._shouldSaveShowMode)
this._restoreAndApplyShowModeFromSettings();this._updateShowHideSidebarButton();this._resizerWidget.setVertical(!isVertical);this.invalidateConstraints();},_updateLayout:function(animate)
{delete this._totalSizeCSS;delete this._totalSizeOtherDimensionCSS;this._mainElement.style.removeProperty("width");this._mainElement.style.removeProperty("height");this._sidebarElement.style.removeProperty("width");this._sidebarElement.style.removeProperty("height");this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(),!!animate);},setMainWidget:function(widget)
{if(this._mainWidget===widget)
return;if(this._mainWidget)
this._mainWidget.detach();this._mainWidget=widget;if(widget){widget.element.classList.add("insertion-point-main");widget.element.classList.remove("insertion-point-sidebar");if(this._showMode===WebInspector.SplitWidget.ShowMode.OnlyMain||this._showMode===WebInspector.SplitWidget.ShowMode.Both)
widget.show(this.element);}},setSidebarWidget:function(widget)
{if(this._sidebarWidget===widget)
return;if(this._sidebarWidget)
this._sidebarWidget.detach();this._sidebarWidget=widget;if(widget){widget.element.classList.add("insertion-point-sidebar");widget.element.classList.remove("insertion-point-main");if(this._showMode===WebInspector.SplitWidget.ShowMode.OnlySidebar||this._showMode===WebInspector.SplitWidget.ShowMode.Both)
widget.show(this.element);}},mainWidget:function()
{return this._mainWidget;},sidebarWidget:function()
{return this._sidebarWidget;},childWasDetached:function(widget)
{if(this._detaching)
return;if(this._mainWidget===widget)
delete this._mainWidget;if(this._sidebarWidget===widget)
delete this._sidebarWidget;},isSidebarSecond:function()
{return this._secondIsSidebar;},enableShowModeSaving:function()
{this._shouldSaveShowMode=true;this._restoreAndApplyShowModeFromSettings();},showMode:function()
{return this._showMode;},setSecondIsSidebar:function(secondIsSidebar)
{this.contentElement.classList.toggle("shadow-split-widget-first-is-sidebar",!secondIsSidebar);this._secondIsSidebar=secondIsSidebar;},sidebarSide:function()
{if(this._showMode!==WebInspector.SplitWidget.ShowMode.Both)
return null;return this._isVertical?(this._secondIsSidebar?"right":"left"):(this._secondIsSidebar?"bottom":"top");},resizerElement:function()
{return this._resizerElement;},hideMain:function(animate)
{this._showOnly(this._sidebarWidget,this._mainWidget,this._sidebarElement,this._mainElement,animate);this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlySidebar);},hideSidebar:function(animate)
{this._showOnly(this._mainWidget,this._sidebarWidget,this._mainElement,this._sidebarElement,animate);this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlyMain);},setSidebarMinimized:function(minimized)
{this._sidebarMinimized=minimized;this.invalidateConstraints();},isSidebarMinimized:function()
{return this._sidebarMinimized;},_showOnly:function(sideToShow,sideToHide,shadowToShow,shadowToHide,animate)
{this._cancelAnimation();function callback()
{if(sideToShow){if(sideToShow===this._mainWidget)
this._mainWidget.show(this.element,this._sidebarWidget?this._sidebarWidget.element:null);else
this._sidebarWidget.show(this.element);}
if(sideToHide){this._detaching=true;sideToHide.detach();delete this._detaching;}
this._resizerElement.classList.add("hidden");shadowToShow.classList.remove("hidden");shadowToShow.classList.add("maximized");shadowToHide.classList.add("hidden");shadowToHide.classList.remove("maximized");this._removeAllLayoutProperties();this.doResize();}
if(animate)
this._animate(true,callback.bind(this));else
callback.call(this);this._sidebarSizeDIP=-1;this.setResizable(false);},_removeAllLayoutProperties:function()
{this._sidebarElement.style.removeProperty("flexBasis");this._mainElement.style.removeProperty("width");this._mainElement.style.removeProperty("height");this._sidebarElement.style.removeProperty("width");this._sidebarElement.style.removeProperty("height");this._resizerElement.style.removeProperty("left");this._resizerElement.style.removeProperty("right");this._resizerElement.style.removeProperty("top");this._resizerElement.style.removeProperty("bottom");this._resizerElement.style.removeProperty("margin-left");this._resizerElement.style.removeProperty("margin-right");this._resizerElement.style.removeProperty("margin-top");this._resizerElement.style.removeProperty("margin-bottom");},showBoth:function(animate)
{if(this._showMode===WebInspector.SplitWidget.ShowMode.Both)
animate=false;this._cancelAnimation();this._mainElement.classList.remove("maximized","hidden");this._sidebarElement.classList.remove("maximized","hidden");this._resizerElement.classList.remove("hidden");this.setResizable(true);if(this._sidebarWidget)
this._sidebarWidget.show(this.element);if(this._mainWidget)
this._mainWidget.show(this.element,this._sidebarWidget?this._sidebarWidget.element:null);this.setSecondIsSidebar(this._secondIsSidebar);this._sidebarSizeDIP=-1;this._updateShowMode(WebInspector.SplitWidget.ShowMode.Both);this._updateLayout(animate);},setResizable:function(resizable)
{this._resizerWidget.setEnabled(resizable);},isResizable:function()
{return this._resizerWidget.isEnabled();},setSidebarSize:function(size)
{var sizeDIP=WebInspector.zoomManager.cssToDIP(size);this._savedSidebarSizeDIP=sizeDIP;this._saveSetting();this._innerSetSidebarSizeDIP(sizeDIP,false,true);},sidebarSize:function()
{var sizeDIP=Math.max(0,this._sidebarSizeDIP);return WebInspector.zoomManager.dipToCSS(sizeDIP);},_totalSizeDIP:function()
{if(!this._totalSizeCSS){this._totalSizeCSS=this._isVertical?this.contentElement.offsetWidth:this.contentElement.offsetHeight;this._totalSizeOtherDimensionCSS=this._isVertical?this.contentElement.offsetHeight:this.contentElement.offsetWidth;}
return WebInspector.zoomManager.cssToDIP(this._totalSizeCSS);},_updateShowMode:function(showMode)
{this._showMode=showMode;this._saveShowModeToSettings();this._updateShowHideSidebarButton();this.dispatchEventToListeners(WebInspector.SplitWidget.Events.ShowModeChanged,showMode);this.invalidateConstraints();},_innerSetSidebarSizeDIP:function(sizeDIP,animate,userAction)
{if(this._showMode!==WebInspector.SplitWidget.ShowMode.Both||!this.isShowing())
return;sizeDIP=this._applyConstraints(sizeDIP,userAction);if(this._sidebarSizeDIP===sizeDIP)
return;if(!this._resizerElementSize)
this._resizerElementSize=this._isVertical?this._resizerElement.offsetWidth:this._resizerElement.offsetHeight;this._removeAllLayoutProperties();var sidebarSizeValue=WebInspector.zoomManager.dipToCSS(sizeDIP)+"px";var mainSizeValue=(this._totalSizeCSS-WebInspector.zoomManager.dipToCSS(sizeDIP))+"px";this._sidebarElement.style.flexBasis=sidebarSizeValue;if(this._isVertical){this._sidebarElement.style.width=sidebarSizeValue;this._mainElement.style.width=mainSizeValue;this._sidebarElement.style.height=this._totalSizeOtherDimensionCSS+"px";this._mainElement.style.height=this._totalSizeOtherDimensionCSS+"px";}else{this._sidebarElement.style.height=sidebarSizeValue;this._mainElement.style.height=mainSizeValue;this._sidebarElement.style.width=this._totalSizeOtherDimensionCSS+"px";this._mainElement.style.width=this._totalSizeOtherDimensionCSS+"px";}
if(this._isVertical){if(this._secondIsSidebar){this._resizerElement.style.right=sidebarSizeValue;this._resizerElement.style.marginRight=-this._resizerElementSize/2+"px";}else{this._resizerElement.style.left=sidebarSizeValue;this._resizerElement.style.marginLeft=-this._resizerElementSize/2+"px";}}else{if(this._secondIsSidebar){this._resizerElement.style.bottom=sidebarSizeValue;this._resizerElement.style.marginBottom=-this._resizerElementSize/2+"px";}else{this._resizerElement.style.top=sidebarSizeValue;this._resizerElement.style.marginTop=-this._resizerElementSize/2+"px";}}
this._sidebarSizeDIP=sizeDIP;if(animate){this._animate(false);}else{this.doResize();this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSizeChanged,this.sidebarSize());}},_animate:function(reverse,callback)
{var animationTime=50;this._animationCallback=callback;var animatedMarginPropertyName;if(this._isVertical)
animatedMarginPropertyName=this._secondIsSidebar?"margin-right":"margin-left";else
animatedMarginPropertyName=this._secondIsSidebar?"margin-bottom":"margin-top";var marginFrom=reverse?"0":"-"+WebInspector.zoomManager.dipToCSS(this._sidebarSizeDIP)+"px";var marginTo=reverse?"-"+WebInspector.zoomManager.dipToCSS(this._sidebarSizeDIP)+"px":"0";this.contentElement.style.setProperty(animatedMarginPropertyName,marginFrom);if(!reverse){suppressUnused(this._mainElement.offsetWidth);suppressUnused(this._sidebarElement.offsetWidth);}
if(!reverse)
this._sidebarWidget.doResize();this.contentElement.style.setProperty("transition",animatedMarginPropertyName+" "+animationTime+"ms linear");var boundAnimationFrame;var startTime;function animationFrame()
{delete this._animationFrameHandle;if(!startTime){this.contentElement.style.setProperty(animatedMarginPropertyName,marginTo);startTime=window.performance.now();}else if(window.performance.now()<startTime+animationTime){if(this._mainWidget)
this._mainWidget.doResize();}else{this._cancelAnimation();if(this._mainWidget)
this._mainWidget.doResize();this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSizeChanged,this.sidebarSize());return;}
this._animationFrameHandle=this.contentElement.window().requestAnimationFrame(boundAnimationFrame);}
boundAnimationFrame=animationFrame.bind(this);this._animationFrameHandle=this.contentElement.window().requestAnimationFrame(boundAnimationFrame);},_cancelAnimation:function()
{this.contentElement.style.removeProperty("margin-top");this.contentElement.style.removeProperty("margin-right");this.contentElement.style.removeProperty("margin-bottom");this.contentElement.style.removeProperty("margin-left");this.contentElement.style.removeProperty("transition");if(this._animationFrameHandle){this.contentElement.window().cancelAnimationFrame(this._animationFrameHandle);delete this._animationFrameHandle;}
if(this._animationCallback){this._animationCallback();delete this._animationCallback;}},_applyConstraints:function(sidebarSize,userAction)
{var totalSize=this._totalSizeDIP();var zoomFactor=this._constraintsInDip?1:WebInspector.zoomManager.zoomFactor();var constraints=this._sidebarWidget?this._sidebarWidget.constraints():new Constraints();var minSidebarSize=this.isVertical()?constraints.minimum.width:constraints.minimum.height;if(!minSidebarSize)
minSidebarSize=WebInspector.SplitWidget.MinPadding;minSidebarSize*=zoomFactor;if(this._sidebarMinimized)
sidebarSize=minSidebarSize;var preferredSidebarSize=this.isVertical()?constraints.preferred.width:constraints.preferred.height;if(!preferredSidebarSize)
preferredSidebarSize=WebInspector.SplitWidget.MinPadding;preferredSidebarSize*=zoomFactor;if(sidebarSize<preferredSidebarSize)
preferredSidebarSize=Math.max(sidebarSize,minSidebarSize);preferredSidebarSize+=zoomFactor;constraints=this._mainWidget?this._mainWidget.constraints():new Constraints();var minMainSize=this.isVertical()?constraints.minimum.width:constraints.minimum.height;if(!minMainSize)
minMainSize=WebInspector.SplitWidget.MinPadding;minMainSize*=zoomFactor;var preferredMainSize=this.isVertical()?constraints.preferred.width:constraints.preferred.height;if(!preferredMainSize)
preferredMainSize=WebInspector.SplitWidget.MinPadding;preferredMainSize*=zoomFactor;var savedMainSize=this.isVertical()?this._savedVerticalMainSize:this._savedHorizontalMainSize;if(typeof savedMainSize!=="undefined")
preferredMainSize=Math.min(preferredMainSize,savedMainSize*zoomFactor);if(userAction)
preferredMainSize=minMainSize;var totalPreferred=preferredMainSize+preferredSidebarSize;if(totalPreferred<=totalSize)
return Number.constrain(sidebarSize,preferredSidebarSize,totalSize-preferredMainSize);if(minMainSize+minSidebarSize<=totalSize){var delta=totalPreferred-totalSize;var sidebarDelta=delta*preferredSidebarSize/totalPreferred;sidebarSize=preferredSidebarSize-sidebarDelta;return Number.constrain(sidebarSize,minSidebarSize,totalSize-minMainSize);}
return Math.max(0,totalSize-minMainSize);},wasShown:function()
{this._forceUpdateLayout();WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._onZoomChanged,this);},willHide:function()
{WebInspector.zoomManager.removeEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._onZoomChanged,this);},onResize:function()
{this._updateLayout();},onLayout:function()
{this._updateLayout();},calculateConstraints:function()
{if(this._showMode===WebInspector.SplitWidget.ShowMode.OnlyMain)
return this._mainWidget?this._mainWidget.constraints():new Constraints();if(this._showMode===WebInspector.SplitWidget.ShowMode.OnlySidebar)
return this._sidebarWidget?this._sidebarWidget.constraints():new Constraints();var mainConstraints=this._mainWidget?this._mainWidget.constraints():new Constraints();var sidebarConstraints=this._sidebarWidget?this._sidebarWidget.constraints():new Constraints();var min=WebInspector.SplitWidget.MinPadding;if(this._isVertical){mainConstraints=mainConstraints.widthToMax(min).addWidth(1);sidebarConstraints=sidebarConstraints.widthToMax(min);return mainConstraints.addWidth(sidebarConstraints).heightToMax(sidebarConstraints);}else{mainConstraints=mainConstraints.heightToMax(min).addHeight(1);sidebarConstraints=sidebarConstraints.heightToMax(min);return mainConstraints.widthToMax(sidebarConstraints).addHeight(sidebarConstraints);}},_onResizeStart:function(event)
{this._resizeStartSizeDIP=this._sidebarSizeDIP;},_onResizeUpdate:function(event)
{var offset=event.data.currentPosition-event.data.startPosition;var offsetDIP=WebInspector.zoomManager.cssToDIP(offset);var newSizeDIP=this._secondIsSidebar?this._resizeStartSizeDIP-offsetDIP:this._resizeStartSizeDIP+offsetDIP;var constrainedSizeDIP=this._applyConstraints(newSizeDIP,true);this._savedSidebarSizeDIP=constrainedSizeDIP;this._saveSetting();this._innerSetSidebarSizeDIP(constrainedSizeDIP,false,true);if(this.isVertical())
this._savedVerticalMainSize=this._totalSizeDIP()-this._sidebarSizeDIP;else
this._savedHorizontalMainSize=this._totalSizeDIP()-this._sidebarSizeDIP;},_onResizeEnd:function(event)
{delete this._resizeStartSizeDIP;},hideDefaultResizer:function()
{this.uninstallResizer(this._resizerElement);},installResizer:function(resizerElement)
{this._resizerWidget.addElement(resizerElement);},uninstallResizer:function(resizerElement)
{this._resizerWidget.removeElement(resizerElement);},hasCustomResizer:function()
{var elements=this._resizerWidget.elements();return elements.length>1||(elements.length==1&&elements[0]!==this._resizerElement);},toggleResizer:function(resizer,on)
{if(on)
this.installResizer(resizer);else
this.uninstallResizer(resizer);},_settingForOrientation:function()
{var state=this._setting?this._setting.get():{};return this._isVertical?state.vertical:state.horizontal;},_preferredSidebarSizeDIP:function()
{var size=this._savedSidebarSizeDIP;if(!size){size=this._isVertical?this._defaultSidebarWidth:this._defaultSidebarHeight;if(0<size&&size<1)
size*=this._totalSizeDIP();}
return size;},_restoreSidebarSizeFromSettings:function()
{var settingForOrientation=this._settingForOrientation();this._savedSidebarSizeDIP=settingForOrientation?settingForOrientation.size:0;},_restoreAndApplyShowModeFromSettings:function()
{var orientationState=this._settingForOrientation();this._savedShowMode=orientationState&&orientationState.showMode?orientationState.showMode:this._showMode;this._showMode=this._savedShowMode;switch(this._savedShowMode){case WebInspector.SplitWidget.ShowMode.Both:this.showBoth();break;case WebInspector.SplitWidget.ShowMode.OnlyMain:this.hideSidebar();break;case WebInspector.SplitWidget.ShowMode.OnlySidebar:this.hideMain();break;}},_saveShowModeToSettings:function()
{this._savedShowMode=this._showMode;this._saveSetting();},_saveSetting:function()
{if(!this._setting)
return;var state=this._setting.get();var orientationState=(this._isVertical?state.vertical:state.horizontal)||{};orientationState.size=this._savedSidebarSizeDIP;if(this._shouldSaveShowMode)
orientationState.showMode=this._savedShowMode;if(this._isVertical)
state.vertical=orientationState;else
state.horizontal=orientationState;this._setting.set(state);},_forceUpdateLayout:function()
{this._sidebarSizeDIP=-1;this._updateLayout();},_onZoomChanged:function(event)
{this._forceUpdateLayout();},displayShowHideSidebarButton:function(title,className)
{console.assert(this.isVertical(),"Buttons for split widget with horizontal split are not supported yet.");this._showHideSidebarButtonTitle=WebInspector.UIString(title);this._showHideSidebarButton=this._mainElement.createChild("button","sidebar-show-hide-button "+(className||""));this._showHideSidebarButton.addEventListener("click",buttonClicked.bind(this),false);this._updateShowHideSidebarButton();function buttonClicked(event)
{if(this._showMode!==WebInspector.SplitWidget.ShowMode.Both)
this.showBoth(true);else
this.hideSidebar(true);}
return this._showHideSidebarButton;},_updateShowHideSidebarButton:function()
{if(!this._showHideSidebarButton)
return;var sidebarHidden=this._showMode===WebInspector.SplitWidget.ShowMode.OnlyMain;this._showHideSidebarButton.classList.toggle("toggled-show",sidebarHidden);this._showHideSidebarButton.classList.toggle("toggled-hide",!sidebarHidden);this._showHideSidebarButton.classList.toggle("top-sidebar-show-hide-button",!this.isVertical()&&!this.isSidebarSecond());this._showHideSidebarButton.classList.toggle("right-sidebar-show-hide-button",this.isVertical()&&this.isSidebarSecond());this._showHideSidebarButton.classList.toggle("bottom-sidebar-show-hide-button",!this.isVertical()&&this.isSidebarSecond());this._showHideSidebarButton.classList.toggle("left-sidebar-show-hide-button",this.isVertical()&&!this.isSidebarSecond());this._showHideSidebarButton.title=sidebarHidden?WebInspector.UIString("Show %s",this._showHideSidebarButtonTitle):WebInspector.UIString("Hide %s",this._showHideSidebarButtonTitle);},__proto__:WebInspector.Widget.prototype};WebInspector.StackView=function(isVertical)
{WebInspector.VBox.call(this);this._isVertical=isVertical;this._currentSplitWidget=null;}
WebInspector.StackView.prototype={appendView:function(view,sidebarSizeSettingName,defaultSidebarWidth,defaultSidebarHeight)
{var splitWidget=new WebInspector.SplitWidget(this._isVertical,true,sidebarSizeSettingName,defaultSidebarWidth,defaultSidebarHeight);splitWidget.setMainWidget(view);splitWidget.hideSidebar();if(!this._currentSplitWidget){splitWidget.show(this.element);}else{this._currentSplitWidget.setSidebarWidget(splitWidget);this._currentSplitWidget.showBoth();}
var lastSplitWidget=this._currentSplitWidget;this._currentSplitWidget=splitWidget;return lastSplitWidget;},detachChildWidgets:function()
{WebInspector.Widget.prototype.detachChildWidgets.call(this);this._currentSplitWidget=null;},__proto__:WebInspector.VBox.prototype};WebInspector.Toolbar=function(className,parentElement)
{this._items=[];this._reverse=false;this.element=parentElement?parentElement.createChild("div"):createElement("div");this.element.className=className;this.element.classList.add("toolbar");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/toolbar.css");this._contentElement=this._shadowRoot.createChild("div","toolbar-shadow");this._insertionPoint=this._contentElement.createChild("content");}
WebInspector.Toolbar.prototype={makeWrappable:function(reverse)
{this._contentElement.classList.add("wrappable");this._reverse=!!reverse;if(reverse)
this._contentElement.classList.add("wrappable-reverse");},makeVertical:function()
{this._contentElement.classList.add("vertical");},makeBlueOnHover:function()
{this._contentElement.classList.add("toolbar-blue-on-hover");},makeToggledGray:function()
{this._contentElement.classList.add("toolbar-toggled-gray");},renderAsLinks:function()
{this._contentElement.classList.add("toolbar-render-as-links");},setEnabled:function(enabled)
{for(var item of this._items)
item.setEnabled(enabled);},appendToolbarItem:function(item)
{this._items.push(item);item._toolbar=this;if(this._reverse)
this._contentElement.insertBefore(item.element,this._insertionPoint.nextSibling);else
this._contentElement.insertBefore(item.element,this._insertionPoint);this._hideSeparatorDupes();},appendSeparator:function()
{this.appendToolbarItem(new WebInspector.ToolbarSeparator());},appendSpacer:function()
{this.appendToolbarItem(new WebInspector.ToolbarSeparator(true));},appendText:function(text)
{this.appendToolbarItem(new WebInspector.ToolbarText(text));},removeToolbarItems:function()
{for(var item of this._items)
delete item._toolbar;this._items=[];this._contentElement.removeChildren();this._insertionPoint=this._contentElement.createChild("content");},setColor:function(color)
{var style=createElement("style");style.textContent=".toolbar-glyph { background-color: "+color+" !important }";this._shadowRoot.appendChild(style);},setToggledColor:function(color)
{var style=createElement("style");style.textContent=".toolbar-button.toolbar-state-on .toolbar-glyph { background-color: "+color+" !important }";this._shadowRoot.appendChild(style);},_hideSeparatorDupes:function()
{if(!this._items.length)
return;var previousIsSeparator=false;var lastSeparator;var nonSeparatorVisible=false;for(var i=0;i<this._items.length;++i){if(this._items[i]instanceof WebInspector.ToolbarSeparator){this._items[i].setVisible(!previousIsSeparator);previousIsSeparator=true;lastSeparator=this._items[i];continue;}
if(this._items[i].visible()){previousIsSeparator=false;lastSeparator=null;nonSeparatorVisible=true;}}
if(lastSeparator&&lastSeparator!==this._items.peekLast())
lastSeparator.setVisible(false);this.element.classList.toggle("hidden",!!lastSeparator&&lastSeparator.visible()&&!nonSeparatorVisible);}}
WebInspector.ToolbarItem=function(element)
{this.element=element;this.element.classList.add("toolbar-item");this._visible=true;this._enabled=true;this.element.addEventListener("mouseenter",this._mouseEnter.bind(this),false);this.element.addEventListener("mouseleave",this._mouseLeave.bind(this),false);}
WebInspector.ToolbarItem.prototype={setTitle:function(title)
{if(this._title===title)
return;this._title=title;WebInspector.Tooltip.install(this.element,title);},_mouseEnter:function()
{this.element.classList.add("hover");},_mouseLeave:function()
{this.element.classList.remove("hover");},setEnabled:function(value)
{if(this._enabled===value)
return;this._enabled=value;this._applyEnabledState();},_applyEnabledState:function()
{this.element.disabled=!this._enabled;},visible:function()
{return this._visible;},setVisible:function(x)
{if(this._visible===x)
return;this.element.classList.toggle("hidden",!x);this._visible=x;if(this._toolbar&&!(this instanceof WebInspector.ToolbarSeparator))
this._toolbar._hideSeparatorDupes();},__proto__:WebInspector.Object.prototype}
WebInspector.ToolbarText=function(text)
{WebInspector.ToolbarItem.call(this,createElementWithClass("div","toolbar-text"));this.element.classList.add("toolbar-text");this.setText(text||"");}
WebInspector.ToolbarText.prototype={setText:function(text)
{this.element.textContent=text;},__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ToolbarButton=function(title,glyph,text)
{WebInspector.ToolbarItem.call(this,createElementWithClass("button","toolbar-button"));this.element.addEventListener("click",this._clicked.bind(this),false);this.element.addEventListener("mousedown",this._mouseDown.bind(this),false);this.element.addEventListener("mouseup",this._mouseUp.bind(this),false);this._glyphElement=this.element.createChild("div","toolbar-glyph hidden");this._textElement=this.element.createChild("div","toolbar-text hidden");this.setTitle(title);if(glyph)
this.setGlyph(glyph);this.setText(text||"");this._state="";this._title="";}
WebInspector.ToolbarButton.prototype={setText:function(text)
{if(this._text===text)
return;this._textElement.textContent=text;this._textElement.classList.toggle("hidden",!text);this._text=text;},setGlyph:function(glyph)
{if(this._glyph===glyph)
return;if(this._glyph)
this._glyphElement.classList.remove(this._glyph);if(glyph)
this._glyphElement.classList.add(glyph);this._glyphElement.classList.toggle("hidden",!glyph);this.element.classList.toggle("toolbar-has-glyph",!!glyph);this._glyph=glyph;},setBackgroundImage:function(iconURL)
{this.element.style.backgroundImage="url("+iconURL+")";},state:function()
{return this._state;},setState:function(state)
{if(this._state===state)
return;this.element.classList.remove("toolbar-state-"+this._state);this.element.classList.add("toolbar-state-"+state);this._state=state;},turnIntoSelect:function(width)
{this.element.classList.add("toolbar-has-dropdown");this.element.createChild("div","toolbar-dropdown-arrow");if(width)
this.element.style.width=width+"px";},_clicked:function(event)
{var defaultPrevented=this.dispatchEventToListeners("click",event);event.consume(defaultPrevented);},_mouseDown:function(event)
{this.dispatchEventToListeners("mousedown",event);},_mouseUp:function(event)
{this.dispatchEventToListeners("mouseup",event);},__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ToolbarInput=function(placeholder,growFactor)
{WebInspector.ToolbarItem.call(this,createElementWithClass("input","toolbar-item"));this.element.addEventListener("input",this._onChangeCallback.bind(this),false);if(growFactor)
this.element.style.flexGrow=growFactor;if(placeholder)
this.element.setAttribute("placeholder",placeholder);this._value="";}
WebInspector.ToolbarInput.Event={TextChanged:"TextChanged"};WebInspector.ToolbarInput.prototype={setValue:function(value)
{this._value=value;this.element.value=value;},value:function()
{return this.element.value;},_onChangeCallback:function()
{this.dispatchEventToListeners(WebInspector.ToolbarInput.Event.TextChanged,this.element.value);},__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ToolbarToggle=function(title,glyph,text)
{WebInspector.ToolbarButton.call(this,title,glyph,text);this._toggled=false;this.setState("off");}
WebInspector.ToolbarToggle.prototype={toggled:function()
{return this._toggled;},setToggled:function(toggled)
{if(this._toggled===toggled)
return;this._toggled=toggled;this.setState(toggled?"on":"off");},__proto__:WebInspector.ToolbarButton.prototype}
WebInspector.Toolbar.createActionButton=function(action,toggledOptions,untoggledOptions)
{var button=new WebInspector.ToolbarToggle(action.title(),action.icon());button.addEventListener("click",action.execute,action);action.addEventListener(WebInspector.Action.Events.Enabled,enabledChanged);action.addEventListener(WebInspector.Action.Events.Toggled,toggled);var longClickController=null;var longClickButtons=null;var longClickGlyph=null;toggled();return button;function enabledChanged(event)
{button.setEnabled((event.data));}
function toggled()
{button.setToggled(action.toggled());if(action.title())
WebInspector.Tooltip.install(button.element,action.title(),action.id());updateOptions();}
function updateOptions()
{var buttons=action.toggled()?(toggledOptions||null):(untoggledOptions||null);if(buttons&&buttons.length){if(!longClickController){longClickController=new WebInspector.LongClickController(button.element,showOptions);longClickGlyph=button.element.createChild("div","long-click-glyph toolbar-button-theme");longClickButtons=buttons;}}else{if(longClickController){longClickController.dispose();longClickController=null;longClickGlyph.remove();longClickGlyph=null;longClickButtons=null;}}}
function showOptions()
{var buttons=longClickButtons.slice();var mainButtonClone=new WebInspector.ToolbarToggle(action.title(),action.icon());mainButtonClone.addEventListener("click",clicked);function clicked(event)
{button._clicked((event.data));}
mainButtonClone.setToggled(action.toggled());buttons.push(mainButtonClone);var document=button.element.ownerDocument;document.documentElement.addEventListener("mouseup",mouseUp,false);var optionsGlassPane=new WebInspector.GlassPane(document);var optionsBar=new WebInspector.Toolbar("fill",optionsGlassPane.element);optionsBar._contentElement.classList.add("floating");const buttonHeight=26;var hostButtonPosition=button.element.totalOffset();var topNotBottom=hostButtonPosition.top+buttonHeight*buttons.length<document.documentElement.offsetHeight;if(topNotBottom)
buttons=buttons.reverse();optionsBar.element.style.height=(buttonHeight*buttons.length)+"px";if(topNotBottom)
optionsBar.element.style.top=(hostButtonPosition.top+1)+"px";else
optionsBar.element.style.top=(hostButtonPosition.top-(buttonHeight*(buttons.length-1)))+"px";optionsBar.element.style.left=(hostButtonPosition.left+1)+"px";for(var i=0;i<buttons.length;++i){buttons[i].element.addEventListener("mousemove",mouseOver,false);buttons[i].element.addEventListener("mouseout",mouseOut,false);optionsBar.appendToolbarItem(buttons[i]);}
var hostButtonIndex=topNotBottom?0:buttons.length-1;buttons[hostButtonIndex].element.classList.add("emulate-active");function mouseOver(e)
{if(e.which!==1)
return;var buttonElement=e.target.enclosingNodeOrSelfWithClass("toolbar-item");buttonElement.classList.add("emulate-active");}
function mouseOut(e)
{if(e.which!==1)
return;var buttonElement=e.target.enclosingNodeOrSelfWithClass("toolbar-item");buttonElement.classList.remove("emulate-active");}
function mouseUp(e)
{if(e.which!==1)
return;optionsGlassPane.dispose();document.documentElement.removeEventListener("mouseup",mouseUp,false);for(var i=0;i<buttons.length;++i){if(buttons[i].element.classList.contains("emulate-active")){buttons[i].element.classList.remove("emulate-active");buttons[i]._clicked(e);break;}}}}}
WebInspector.ToolbarMenuButton=function(contextMenuHandler,useSoftMenu)
{WebInspector.ToolbarButton.call(this,"","menu-toolbar-item");this._contextMenuHandler=contextMenuHandler;this._useSoftMenu=!!useSoftMenu;}
WebInspector.ToolbarMenuButton.prototype={_mouseDown:function(event)
{if(event.buttons!==1){WebInspector.ToolbarButton.prototype._mouseDown.call(this,event);return;}
if(!this._triggerTimeout)
this._triggerTimeout=setTimeout(this._trigger.bind(this,event),200);},_trigger:function(event)
{delete this._triggerTimeout;var contextMenu=new WebInspector.ContextMenu(event,this._useSoftMenu,this.element.totalOffsetLeft(),this.element.totalOffsetTop()+this.element.offsetHeight);this._contextMenuHandler(contextMenu);contextMenu.show();},_clicked:function(event)
{if(!this._triggerTimeout)
return;clearTimeout(this._triggerTimeout);this._trigger(event);},__proto__:WebInspector.ToolbarButton.prototype}
WebInspector.ToolbarSettingToggle=function(setting,glyph,title,toggledTitle)
{WebInspector.ToolbarToggle.call(this,title,glyph);this._defaultTitle=title;this._toggledTitle=toggledTitle||title;this._setting=setting;this._settingChanged();this._setting.addChangeListener(this._settingChanged,this);}
WebInspector.ToolbarSettingToggle.prototype={_settingChanged:function()
{var toggled=this._setting.get();this.setToggled(toggled);this.setTitle(toggled?this._toggledTitle:this._defaultTitle);},_clicked:function(event)
{this._setting.set(!this.toggled());WebInspector.ToolbarToggle.prototype._clicked.call(this,event);},__proto__:WebInspector.ToolbarToggle.prototype}
WebInspector.ToolbarSeparator=function(spacer)
{WebInspector.ToolbarItem.call(this,createElementWithClass("div",spacer?"toolbar-spacer":"toolbar-divider"));}
WebInspector.ToolbarSeparator.prototype={__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ToolbarItem.Provider=function()
{}
WebInspector.ToolbarItem.Provider.prototype={item:function(){}}
WebInspector.ToolbarComboBox=function(changeHandler,className)
{WebInspector.ToolbarItem.call(this,createElementWithClass("span","toolbar-select-container"));this._selectElement=this.element.createChild("select","toolbar-item");this.element.createChild("div","toolbar-dropdown-arrow");if(changeHandler)
this._selectElement.addEventListener("change",changeHandler,false);if(className)
this._selectElement.classList.add(className);}
WebInspector.ToolbarComboBox.prototype={selectElement:function()
{return(this._selectElement);},size:function()
{return this._selectElement.childElementCount;},options:function()
{return Array.prototype.slice.call(this._selectElement.children,0);},addOption:function(option)
{this._selectElement.appendChild(option);},createOption:function(label,title,value)
{var option=this._selectElement.createChild("option");option.text=label;if(title)
option.title=title;if(typeof value!=="undefined")
option.value=value;return option;},_applyEnabledState:function()
{this._selectElement.disabled=!this._enabled;},removeOption:function(option)
{this._selectElement.removeChild(option);},removeOptions:function()
{this._selectElement.removeChildren();},selectedOption:function()
{if(this._selectElement.selectedIndex>=0)
return this._selectElement[this._selectElement.selectedIndex];return null;},select:function(option)
{this._selectElement.selectedIndex=Array.prototype.indexOf.call((this._selectElement),option);},setSelectedIndex:function(index)
{this._selectElement.selectedIndex=index;},selectedIndex:function()
{return this._selectElement.selectedIndex;},setMaxWidth:function(width)
{this._selectElement.style.maxWidth=width+"px";},__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ToolbarCheckbox=function(text,title,setting,listener)
{WebInspector.ToolbarItem.call(this,createCheckboxLabel(text));this.element.classList.add("checkbox");this.inputElement=this.element.checkboxElement;if(title)
this.element.title=title;if(setting)
WebInspector.SettingsUI.bindCheckbox(this.inputElement,setting);if(listener)
this.inputElement.addEventListener("click",listener,false);}
WebInspector.ToolbarCheckbox.prototype={checked:function()
{return this.inputElement.checked;},setChecked:function(value)
{this.inputElement.checked=value;},__proto__:WebInspector.ToolbarItem.prototype}
WebInspector.ExtensibleToolbar=function(location,parentElement)
{WebInspector.Toolbar.call(this,"",parentElement);this._loadItems(location);}
WebInspector.ExtensibleToolbar.prototype={_loadItems:function(location)
{var extensions=self.runtime.extensions(WebInspector.ToolbarItem.Provider);var promises=[];for(var i=0;i<extensions.length;++i){if(extensions[i].descriptor()["location"]===location)
promises.push(resolveItem(extensions[i]));}
this._promise=Promise.all(promises).then(appendItemsInOrder.bind(this));function resolveItem(extension)
{var descriptor=extension.descriptor();if(descriptor["separator"])
return Promise.resolve((new WebInspector.ToolbarSeparator()));if(descriptor["actionId"]){var action=WebInspector.actionRegistry.action(descriptor["actionId"]);return Promise.resolve((action?WebInspector.Toolbar.createActionButton(action):null));}
return extension.instancePromise().then(fetchItemFromProvider);function fetchItemFromProvider(provider)
{return(provider).item();}}
function appendItemsInOrder(items)
{for(var i=0;i<items.length;++i){var item=items[i];if(item)
this.appendToolbarItem(item);}}},onLoad:function()
{return this._promise;},__proto__:WebInspector.Toolbar.prototype};WebInspector.Tooltip=function(doc)
{this.element=doc.body.createChild("div");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/tooltip.css");this._tooltipElement=this._shadowRoot.createChild("div","tooltip");doc.addEventListener("mousemove",this._mouseMove.bind(this),true);doc.addEventListener("mousedown",this._hide.bind(this,true),true);doc.addEventListener("mouseleave",this._hide.bind(this,false),true);doc.addEventListener("keydown",this._hide.bind(this,true),true);WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._reset,this);doc.defaultView.addEventListener("resize",this._reset.bind(this),false);}
WebInspector.Tooltip.Timing={"InstantThreshold":300,"OpeningDelay":600}
WebInspector.Tooltip.prototype={_mouseMove:function(event)
{var mouseEvent=(event);var path=mouseEvent.path;if(!path||mouseEvent.buttons!==0||(mouseEvent.movementX===0&&mouseEvent.movementY===0))
return;if(this._anchorElement&&path.indexOf(this._anchorElement)===-1)
this._hide(false);for(var element of path){if(element===this._anchorElement){return;}else if(element[WebInspector.Tooltip._symbol]){this._show(element,mouseEvent);return;}}},_show:function(anchorElement,event)
{var tooltip=anchorElement[WebInspector.Tooltip._symbol];this._anchorElement=anchorElement;this._tooltipElement.removeChildren();for(var element of WebInspector.Tooltip._nativeOverrideContainer){if(this._anchorElement.isSelfOrDescendant(element)){Object.defineProperty(this._anchorElement,"title",WebInspector.Tooltip._nativeTitle);this._anchorElement.title=tooltip.content;return;}}
if(typeof tooltip.content==="string")
this._tooltipElement.setTextContentTruncatedIfNeeded(tooltip.content);else
this._tooltipElement.appendChild(tooltip.content);if(tooltip.actionId){var shortcuts=WebInspector.shortcutRegistry.shortcutDescriptorsForAction(tooltip.actionId);for(var shortcut of shortcuts){var shortcutElement=this._tooltipElement.createChild("div","tooltip-shortcut");shortcutElement.textContent=shortcut.name;}}
this._tooltipElement.classList.add("shown");this._tooltipElement.positionAt(0,0);var now=Date.now();var instant=(this._tooltipLastClosed&&now-this._tooltipLastClosed<WebInspector.Tooltip.Timing.InstantThreshold);this._tooltipElement.classList.toggle("instant",instant);this._tooltipLastOpened=instant?now:now+WebInspector.Tooltip.Timing.OpeningDelay;var container=WebInspector.Dialog.modalHostView().element;if(!anchorElement.isDescendant(container))
container=this.element.parentElement;var containerOffset=container.offsetRelativeToWindow(this.element.window());var containerOffsetWidth=container.offsetWidth;var containerOffsetHeight=container.offsetHeight;var anchorBox=this._anchorElement.boxInWindow(this.element.window());const anchorOffset=2;const pageMargin=2;var cursorOffset=10;this._tooltipElement.style.maxWidth=(containerOffsetWidth-pageMargin*2)+"px";this._tooltipElement.style.maxHeight="";var tooltipWidth=this._tooltipElement.offsetWidth;var tooltipHeight=this._tooltipElement.offsetHeight;var anchorTooltipAtElement=this._anchorElement.nodeName==="BUTTON"||this._anchorElement.nodeName==="LABEL";var tooltipX=anchorTooltipAtElement?anchorBox.x:event.x+cursorOffset;tooltipX=Number.constrain(tooltipX,containerOffset.x+pageMargin,containerOffset.x+containerOffsetWidth-tooltipWidth-pageMargin);var tooltipY;if(!anchorTooltipAtElement){tooltipY=event.y+cursorOffset+tooltipHeight<containerOffset.y+containerOffsetHeight?event.y+cursorOffset:event.y-tooltipHeight;}else{var onBottom=anchorBox.y+anchorOffset+anchorBox.height+tooltipHeight<containerOffset.y+containerOffsetHeight;tooltipY=onBottom?anchorBox.y+anchorBox.height+anchorOffset:anchorBox.y-tooltipHeight-anchorOffset;}
this._tooltipElement.positionAt(tooltipX,tooltipY);},_hide:function(removeInstant)
{delete this._anchorElement;this._tooltipElement.classList.remove("shown");if(Date.now()>this._tooltipLastOpened)
this._tooltipLastClosed=Date.now();if(removeInstant)
delete this._tooltipLastClosed;},_reset:function()
{this._hide(true);this._tooltipElement.positionAt(0,0);this._tooltipElement.style.maxWidth="0";this._tooltipElement.style.maxHeight="0";}}
WebInspector.Tooltip._symbol=Symbol("Tooltip");WebInspector.Tooltip.installHandler=function(doc)
{new WebInspector.Tooltip(doc);}
WebInspector.Tooltip.install=function(element,tooltipContent,actionId,options)
{if(typeof tooltipContent==="string"&&tooltipContent===""){delete element[WebInspector.Tooltip._symbol];return;}
element[WebInspector.Tooltip._symbol]={content:tooltipContent,actionId:actionId,options:options||{}};}
WebInspector.Tooltip.addNativeOverrideContainer=function(element)
{WebInspector.Tooltip._nativeOverrideContainer.push(element);}
WebInspector.Tooltip._nativeOverrideContainer=[];WebInspector.Tooltip._nativeTitle=(Object.getOwnPropertyDescriptor(HTMLElement.prototype,"title"));Object.defineProperty(HTMLElement.prototype,"title",{get:function()
{var tooltip=this[WebInspector.Tooltip._symbol];return tooltip?tooltip.content:"";},set:function(x)
{WebInspector.Tooltip.install(this,x);}});;WebInspector.SuggestBoxDelegate=function()
{}
WebInspector.SuggestBoxDelegate.prototype={applySuggestion:function(suggestion,isIntermediateSuggestion){},acceptSuggestion:function(){},}
WebInspector.SuggestBox=function(suggestBoxDelegate,maxItemsHeight)
{this._suggestBoxDelegate=suggestBoxDelegate;this._length=0;this._selectedIndex=-1;this._selectedElement=null;this._maxItemsHeight=maxItemsHeight;this._maybeHideBound=this._maybeHide.bind(this);this._container=createElementWithClass("div","suggest-box-container");this._element=this._container.createChild("div","suggest-box");this._element.addEventListener("mousedown",this._onBoxMouseDown.bind(this),true);this._detailsPopup=this._container.createChild("div","suggest-box details-popup monospace");this._detailsPopup.classList.add("hidden");this._asyncDetailsCallback=null;this._asyncDetailsPromises=new Map();}
WebInspector.SuggestBox.Suggestions;WebInspector.SuggestBox.prototype={visible:function()
{return!!this._container.parentElement;},setPosition:function(anchorBox)
{this._updateBoxPosition(anchorBox);},_updateBoxPosition:function(anchorBox)
{console.assert(this._overlay);if(this._lastAnchorBox&&this._lastAnchorBox.equals(anchorBox))
return;this._lastAnchorBox=anchorBox;var container=WebInspector.Dialog.modalHostView().element;anchorBox=anchorBox.relativeToElement(container);var totalHeight=container.offsetHeight;var aboveHeight=anchorBox.y;var underHeight=totalHeight-anchorBox.y-anchorBox.height;this._overlay.setLeftOffset(anchorBox.x);var under=underHeight>=aboveHeight;if(under)
this._overlay.setVerticalOffset(anchorBox.y+anchorBox.height,true);else
this._overlay.setVerticalOffset(totalHeight-anchorBox.y,false);var rowHeight=17;var spacer=6;var maxHeight=this._maxItemsHeight?this._maxItemsHeight*rowHeight:Math.max(underHeight,aboveHeight)-spacer;this._element.style.maxHeight=maxHeight+"px";},_onBoxMouseDown:function(event)
{if(this._hideTimeoutId){window.clearTimeout(this._hideTimeoutId);delete this._hideTimeoutId;}
event.preventDefault();},_maybeHide:function()
{if(!this._hideTimeoutId)
this._hideTimeoutId=window.setTimeout(this.hide.bind(this),0);},_show:function()
{if(this.visible())
return;this._bodyElement=document.body;this._bodyElement.addEventListener("mousedown",this._maybeHideBound,true);this._overlay=new WebInspector.SuggestBox.Overlay();this._overlay.setContentElement(this._container);},hide:function()
{if(!this.visible())
return;this._bodyElement.removeEventListener("mousedown",this._maybeHideBound,true);delete this._bodyElement;this._container.remove();this._overlay.dispose();delete this._overlay;delete this._selectedElement;this._selectedIndex=-1;delete this._lastAnchorBox;},removeFromElement:function()
{this.hide();},_applySuggestion:function(isIntermediateSuggestion)
{if(!this.visible()||!this._selectedElement)
return false;var suggestion=this._selectedElement.__fullValue;if(!suggestion)
return false;this._suggestBoxDelegate.applySuggestion(suggestion,isIntermediateSuggestion);return true;},acceptSuggestion:function()
{var result=this._applySuggestion();this.hide();if(!result)
return false;this._suggestBoxDelegate.acceptSuggestion();return true;},_selectClosest:function(shift,isCircular)
{if(!this._length)
return false;if(this._selectedIndex===-1&&shift<0)
shift+=1;var index=this._selectedIndex+shift;if(isCircular)
index=(this._length+index)%this._length;else
index=Number.constrain(index,0,this._length-1);this._selectItem(index,true);this._applySuggestion(true);return true;},_onItemMouseDown:function(event)
{this._selectedElement=event.currentTarget;this.acceptSuggestion();event.consume(true);},_createItemElement:function(prefix,text,className,index)
{var element=createElementWithClass("div","suggest-box-content-item source-code "+(className||""));element.tabIndex=-1;if(prefix&&prefix.length&&!text.indexOf(prefix)){element.createChild("span","prefix").textContent=prefix;element.createChild("span","suffix").textContent=text.substring(prefix.length).trimEnd(50);}else{element.createChild("span","suffix").textContent=text.trimEnd(50);}
element.__fullValue=text;element.createChild("span","spacer");element.addEventListener("mousedown",this._onItemMouseDown.bind(this),false);return element;},_updateItems:function(items,userEnteredText,asyncDetails)
{this._length=items.length;this._asyncDetailsPromises.clear();this._asyncDetailsCallback=asyncDetails;this._element.removeChildren();delete this._selectedElement;for(var i=0;i<items.length;++i){var item=items[i];var currentItemElement=this._createItemElement(userEnteredText,item.title,item.className,i);this._element.appendChild(currentItemElement);}},_asyncDetails:function(index)
{if(!this._asyncDetailsCallback)
return Promise.resolve((null));if(!this._asyncDetailsPromises.has(index))
this._asyncDetailsPromises.set(index,this._asyncDetailsCallback(index));return(this._asyncDetailsPromises.get(index));},_showDetailsPopup:function(details)
{this._detailsPopup.removeChildren();if(!details)
return;this._detailsPopup.createChild("section","detail").createTextChild(details.detail);this._detailsPopup.createChild("section","description").createTextChild(details.description);this._detailsPopup.classList.remove("hidden");},_selectItem:function(index,scrollIntoView)
{if(this._selectedElement)
this._selectedElement.classList.remove("selected");this._selectedIndex=index;if(index<0)
return;this._selectedElement=this._element.children[index];this._selectedElement.classList.add("selected");this._detailsPopup.classList.add("hidden");var elem=this._selectedElement;this._asyncDetails(index).then(showDetails.bind(this),function(){});if(scrollIntoView)
this._selectedElement.scrollIntoViewIfNeeded(false);function showDetails(details)
{if(elem===this._selectedElement)
this._showDetailsPopup(details);}},_canShowBox:function(completions,canShowForSingleItem,userEnteredText)
{if(!completions||!completions.length)
return false;if(completions.length>1)
return true;return canShowForSingleItem&&completions[0].title!==userEnteredText;},_ensureRowCountPerViewport:function()
{if(this._rowCountPerViewport)
return;if(!this._element.firstChild)
return;this._rowCountPerViewport=Math.floor(this._element.offsetHeight/this._element.firstChild.offsetHeight);},updateSuggestions:function(anchorBox,completions,selectedIndex,canShowForSingleItem,userEnteredText,asyncDetails)
{if(this._canShowBox(completions,canShowForSingleItem,userEnteredText)){this._updateItems(completions,userEnteredText,asyncDetails);this._show();this._updateBoxPosition(anchorBox);this._selectItem(selectedIndex,selectedIndex>0);delete this._rowCountPerViewport;}else
this.hide();},keyPressed:function(event)
{switch(event.keyIdentifier){case"Up":return this.upKeyPressed();case"Down":return this.downKeyPressed();case"PageUp":return this.pageUpKeyPressed();case"PageDown":return this.pageDownKeyPressed();case"Enter":return this.enterKeyPressed();}
return false;},upKeyPressed:function()
{return this._selectClosest(-1,true);},downKeyPressed:function()
{return this._selectClosest(1,true);},pageUpKeyPressed:function()
{this._ensureRowCountPerViewport();return this._selectClosest(-this._rowCountPerViewport,false);},pageDownKeyPressed:function()
{this._ensureRowCountPerViewport();return this._selectClosest(this._rowCountPerViewport,false);},enterKeyPressed:function()
{var hasSelectedItem=!!this._selectedElement;this.acceptSuggestion();return hasSelectedItem;}}
WebInspector.SuggestBox.Overlay=function()
{this.element=createElementWithClass("div","suggest-box-overlay");var root=WebInspector.createShadowRootWithCoreStyles(this.element,"ui/suggestBox.css");this._leftSpacerElement=root.createChild("div","suggest-box-left-spacer");this._horizontalElement=root.createChild("div","suggest-box-horizontal");this._topSpacerElement=this._horizontalElement.createChild("div","suggest-box-top-spacer");this._bottomSpacerElement=this._horizontalElement.createChild("div","suggest-box-bottom-spacer");this._resize();document.body.appendChild(this.element);}
WebInspector.SuggestBox.Overlay.prototype={setLeftOffset:function(offset)
{this._leftSpacerElement.style.flexBasis=offset+"px";},setVerticalOffset:function(offset,isTopOffset)
{this.element.classList.toggle("under-anchor",isTopOffset);if(isTopOffset){this._bottomSpacerElement.style.flexBasis="auto";this._topSpacerElement.style.flexBasis=offset+"px";}else{this._bottomSpacerElement.style.flexBasis=offset+"px";this._topSpacerElement.style.flexBasis="auto";}},setContentElement:function(element)
{this._horizontalElement.insertBefore(element,this._bottomSpacerElement);},_resize:function()
{var container=WebInspector.Dialog.modalHostView().element;var containerBox=container.boxInWindow(container.ownerDocument.defaultView);this.element.style.left=containerBox.x+"px";this.element.style.top=containerBox.y+"px";this.element.style.height=containerBox.height+"px";this.element.style.width=containerBox.width+"px";},dispose:function()
{this.element.remove();}};WebInspector.TabbedPane=function()
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("ui/tabbedPane.css");this.element.classList.add("tabbed-pane");this.contentElement.classList.add("tabbed-pane-shadow");this.contentElement.tabIndex=-1;this._headerElement=this.contentElement.createChild("div","tabbed-pane-header");this._headerElement.createChild("content").select=".tabbed-pane-header-before";this._headerContentsElement=this._headerElement.createChild("div","tabbed-pane-header-contents");this._tabSlider=createElementWithClass("div","tabbed-pane-tab-slider");this._headerElement.createChild("content").select=".tabbed-pane-header-after";this._tabsElement=this._headerContentsElement.createChild("div","tabbed-pane-header-tabs");this._contentElement=this.contentElement.createChild("div","tabbed-pane-content");this._contentElement.createChild("content");this._tabs=[];this._tabsHistory=[];this._tabsById={};this._currentTabLocked=false;this._dropDownButton=this._createDropDownButton();WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._zoomChanged,this);}
WebInspector.TabbedPane.EventTypes={TabSelected:"TabSelected",TabClosed:"TabClosed",TabOrderChanged:"TabOrderChanged"}
WebInspector.TabbedPane.prototype={setCurrentTabLocked:function(locked)
{this._currentTabLocked=locked;this._headerElement.classList.toggle("locked",this._currentTabLocked);},get visibleView()
{return this._currentTab?this._currentTab.view:null;},tabIds:function()
{return this._tabs.map(tab=>tab._id);},tabViews:function()
{return this._tabs.map(tab=>tab.view);},tabView:function(tabId)
{return this._tabsById[tabId]?this._tabsById[tabId].view:null;},get selectedTabId()
{return this._currentTab?this._currentTab.id:null;},setShrinkableTabs:function(shrinkableTabs)
{this._shrinkableTabs=shrinkableTabs;},setVerticalTabLayout:function(verticalTabLayout)
{this._verticalTabLayout=verticalTabLayout;this.contentElement.classList.add("vertical-tab-layout");this.invalidateConstraints();},setCloseableTabs:function(closeableTabs)
{this._closeableTabs=closeableTabs;},defaultFocusedElement:function()
{return this.visibleView?this.visibleView.defaultFocusedElement():this.contentElement;},focus:function()
{if(this.visibleView)
this.visibleView.focus();else
this.contentElement.focus();},headerElement:function()
{return this._headerElement;},isTabCloseable:function(id)
{var tab=this._tabsById[id];return tab?tab.isCloseable():false;},setTabDelegate:function(delegate)
{var tabs=this._tabs.slice();for(var i=0;i<tabs.length;++i)
tabs[i].setDelegate(delegate);this._delegate=delegate;},appendTab:function(id,tabTitle,view,tabTooltip,userGesture,isCloseable,index)
{isCloseable=typeof isCloseable==="boolean"?isCloseable:this._closeableTabs;var tab=new WebInspector.TabbedPaneTab(this,id,tabTitle,isCloseable,view,tabTooltip);tab.setDelegate(this._delegate);this._tabsById[id]=tab;if(index!==undefined)
this._tabs.splice(index,0,tab);else
this._tabs.push(tab);this._tabsHistory.push(tab);if(this._tabsHistory[0]===tab&&this.isShowing())
this.selectTab(tab.id,userGesture);this._updateTabElements();},closeTab:function(id,userGesture)
{this.closeTabs([id],userGesture);},closeTabs:function(ids,userGesture)
{var focused=this.hasFocus();for(var i=0;i<ids.length;++i)
this._innerCloseTab(ids[i],userGesture);this._updateTabElements();if(this._tabsHistory.length)
this.selectTab(this._tabsHistory[0].id,false);if(focused)
this.focus();},_innerCloseTab:function(id,userGesture)
{if(!this._tabsById[id])
return;if(userGesture&&!this._tabsById[id]._closeable)
return;if(this._currentTab&&this._currentTab.id===id)
this._hideCurrentTab();var tab=this._tabsById[id];delete this._tabsById[id];this._tabsHistory.splice(this._tabsHistory.indexOf(tab),1);this._tabs.splice(this._tabs.indexOf(tab),1);if(tab._shown)
this._hideTabElement(tab);var eventData={tabId:id,view:tab.view,isUserGesture:userGesture};this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed,eventData);return true;},hasTab:function(tabId)
{return!!this._tabsById[tabId];},allTabs:function()
{return this._tabs.map(function(tab){return tab.id;});},otherTabs:function(id)
{var result=[];for(var i=0;i<this._tabs.length;++i){if(this._tabs[i].id!==id)
result.push(this._tabs[i].id);}
return result;},_tabsToTheRight:function(id)
{var index=-1;for(var i=0;i<this._tabs.length;++i){if(this._tabs[i].id===id){index=i;break;}}
if(index===-1)
return[];return this._tabs.slice(index+1).map(function(tab){return tab.id;});},selectTab:function(id,userGesture)
{if(this._currentTabLocked)
return false;var focused=this.hasFocus();var tab=this._tabsById[id];if(!tab)
return false;if(this._currentTab&&this._currentTab.id===id)
return true;this._hideCurrentTab();this._showTab(tab);this._currentTab=tab;this._tabsHistory.splice(this._tabsHistory.indexOf(tab),1);this._tabsHistory.splice(0,0,tab);this._updateTabElements();if(focused)
this.focus();var eventData={tabId:id,view:tab.view,isUserGesture:userGesture};this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected,eventData);return true;},lastOpenedTabIds:function(tabsCount)
{function tabToTabId(tab){return tab.id;}
return this._tabsHistory.slice(0,tabsCount).map(tabToTabId);},setTabIcon:function(id,iconType,iconTooltip)
{var tab=this._tabsById[id];if(tab._setIconType(iconType,iconTooltip))
this._updateTabElements();},setTabEnabled:function(id,enabled)
{var tab=this._tabsById[id];tab.tabElement.classList.toggle("disabled",!enabled);},toggleTabClass:function(id,className,force)
{var tab=this._tabsById[id];if(tab._toggleClass(className,force))
this._updateTabElements();},_zoomChanged:function(event)
{for(var i=0;i<this._tabs.length;++i)
delete this._tabs[i]._measuredWidth;if(this.isShowing())
this._updateTabElements();},changeTabTitle:function(id,tabTitle)
{var tab=this._tabsById[id];if(tab.title===tabTitle)
return;tab.title=tabTitle;this._updateTabElements();},changeTabView:function(id,view)
{var tab=this._tabsById[id];if(this._currentTab&&this._currentTab.id===tab.id){if(tab.view!==view)
this._hideTab(tab);tab.view=view;this._showTab(tab);}else
tab.view=view;},onResize:function()
{this._updateTabElements();},headerResized:function()
{this._updateTabElements();},wasShown:function()
{var effectiveTab=this._currentTab||this._tabsHistory[0];if(effectiveTab)
this.selectTab(effectiveTab.id);},setTabSlider:function(enable)
{this._sliderEnabled=enable;this._tabSlider.classList.toggle("enabled",enable);},calculateConstraints:function()
{var constraints=WebInspector.VBox.prototype.calculateConstraints.call(this);var minContentConstraints=new Constraints(new Size(0,0),new Size(50,50));constraints=constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints);if(this._verticalTabLayout)
constraints=constraints.addWidth(new Constraints(new Size(120,0)));else
constraints=constraints.addHeight(new Constraints(new Size(0,30)));return constraints;},_updateTabElements:function()
{WebInspector.invokeOnceAfterBatchUpdate(this,this._innerUpdateTabElements);},setPlaceholderText:function(text)
{this._noTabsMessage=text;},_innerUpdateTabElements:function()
{if(!this.isShowing())
return;if(!this._tabs.length){this._contentElement.classList.add("has-no-tabs");if(this._noTabsMessage&&!this._noTabsMessageElement){this._noTabsMessageElement=this._contentElement.createChild("div","tabbed-pane-placeholder fill");this._noTabsMessageElement.textContent=this._noTabsMessage;}}else{this._contentElement.classList.remove("has-no-tabs");if(this._noTabsMessageElement){this._noTabsMessageElement.remove();delete this._noTabsMessageElement;}}
this._measureDropDownButton();this._updateWidths();this._updateTabsDropDown();this._updateTabSlider();},_showTabElement:function(index,tab)
{if(index>=this._tabsElement.children.length)
this._tabsElement.appendChild(tab.tabElement);else
this._tabsElement.insertBefore(tab.tabElement,this._tabsElement.children[index]);tab._shown=true;},_hideTabElement:function(tab)
{this._tabsElement.removeChild(tab.tabElement);tab._shown=false;},_createDropDownButton:function()
{var dropDownContainer=createElementWithClass("div","tabbed-pane-header-tabs-drop-down-container");dropDownContainer.createChild("div","glyph");this._dropDownMenu=new WebInspector.DropDownMenu(dropDownContainer);this._dropDownMenu.addEventListener(WebInspector.DropDownMenu.Events.ItemSelected,this._dropDownMenuItemSelected,this);return dropDownContainer;},_dropDownMenuItemSelected:function(event)
{var tabId=(event.data);this._lastSelectedOverflowTab=this._tabsById[tabId];this.selectTab(tabId,true);},_totalWidth:function()
{return this._headerContentsElement.getBoundingClientRect().width;},_numberOfTabsShown:function()
{var numTabsShown=0;for(var tab of this._tabs){if(tab._shown)
numTabsShown++;}
return numTabsShown;},disableOverflowMenu:function()
{this._overflowDisabled=true;},_updateTabsDropDown:function()
{var tabsToShowIndexes=this._tabsToShowIndexes(this._tabs,this._tabsHistory,this._totalWidth(),this._measuredDropDownButtonWidth||0);if(this._lastSelectedOverflowTab&&this._numberOfTabsShown()!==tabsToShowIndexes.length){delete this._lastSelectedOverflowTab;this._updateTabsDropDown();return;}
for(var i=0;i<this._tabs.length;++i){if(this._tabs[i]._shown&&tabsToShowIndexes.indexOf(i)===-1)
this._hideTabElement(this._tabs[i]);}
for(var i=0;i<tabsToShowIndexes.length;++i){var tab=this._tabs[tabsToShowIndexes[i]];if(!tab._shown)
this._showTabElement(i,tab);}
if(!this._overflowDisabled)
this._populateDropDownFromIndex();},_populateDropDownFromIndex:function()
{if(this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);this._dropDownMenu.clear();var tabsToShow=[];for(var i=0;i<this._tabs.length;++i){if(!this._tabs[i]._shown)
tabsToShow.push(this._tabs[i]);}
var selectedId=null;for(var i=0;i<tabsToShow.length;++i){var tab=tabsToShow[i];this._dropDownMenu.addItem(tab.id,tab.title);if(this._tabsHistory[0]===tab)
selectedId=tab.id;}
if(tabsToShow.length){this._headerContentsElement.appendChild(this._dropDownButton);this._dropDownMenu.selectItem(selectedId);}},_measureDropDownButton:function()
{if(this._overflowDisabled||this._measuredDropDownButtonWidth)
return;this._dropDownButton.classList.add("measuring");this._headerContentsElement.appendChild(this._dropDownButton);this._measuredDropDownButtonWidth=this._dropDownButton.getBoundingClientRect().width;this._headerContentsElement.removeChild(this._dropDownButton);this._dropDownButton.classList.remove("measuring");},_updateWidths:function()
{var measuredWidths=this._measureWidths();var maxWidth=this._shrinkableTabs?this._calculateMaxWidth(measuredWidths.slice(),this._totalWidth()):Number.MAX_VALUE;var i=0;for(var tab of this._tabs)
tab.setWidth(this._verticalTabLayout?-1:Math.min(maxWidth,measuredWidths[i++]));},_measureWidths:function()
{this._tabsElement.style.setProperty("width","2000px");var measuringTabElements=[];for(var tab of this._tabs){if(typeof tab._measuredWidth==="number")
continue;var measuringTabElement=tab._createTabElement(true);measuringTabElement.__tab=tab;measuringTabElements.push(measuringTabElement);this._tabsElement.appendChild(measuringTabElement);}
for(var i=0;i<measuringTabElements.length;++i){var width=measuringTabElements[i].getBoundingClientRect().width;measuringTabElements[i].__tab._measuredWidth=Math.ceil(width);}
for(var i=0;i<measuringTabElements.length;++i)
measuringTabElements[i].remove();var measuredWidths=[];for(var tab of this._tabs)
measuredWidths.push(tab._measuredWidth);this._tabsElement.style.removeProperty("width");return measuredWidths;},_calculateMaxWidth:function(measuredWidths,totalWidth)
{if(!measuredWidths.length)
return 0;measuredWidths.sort(function(x,y){return x-y;});var totalMeasuredWidth=0;for(var i=0;i<measuredWidths.length;++i)
totalMeasuredWidth+=measuredWidths[i];if(totalWidth>=totalMeasuredWidth)
return measuredWidths[measuredWidths.length-1];var totalExtraWidth=0;for(var i=measuredWidths.length-1;i>0;--i){var extraWidth=measuredWidths[i]-measuredWidths[i-1];totalExtraWidth+=(measuredWidths.length-i)*extraWidth;if(totalWidth+totalExtraWidth>=totalMeasuredWidth)
return measuredWidths[i-1]+(totalWidth+totalExtraWidth-totalMeasuredWidth)/(measuredWidths.length-i);}
return totalWidth/measuredWidths.length;},_tabsToShowIndexes:function(tabsOrdered,tabsHistory,totalWidth,measuredDropDownButtonWidth)
{var tabsToShowIndexes=[];var totalTabsWidth=0;var tabCount=tabsOrdered.length;var tabsToLookAt=tabsOrdered.slice(0);if(this._currentTab!==undefined)
tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._currentTab),1)[0]);if(this._lastSelectedOverflowTab!==undefined)
tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._lastSelectedOverflowTab),1)[0]);for(var i=0;i<tabCount;++i){var tab=this._automaticReorder?tabsHistory[i]:tabsToLookAt[i];totalTabsWidth+=tab.width();var minimalRequiredWidth=totalTabsWidth;if(i!==tabCount-1)
minimalRequiredWidth+=measuredDropDownButtonWidth;if(!this._verticalTabLayout&&minimalRequiredWidth>totalWidth)
break;tabsToShowIndexes.push(tabsOrdered.indexOf(tab));}
tabsToShowIndexes.sort(function(x,y){return x-y;});return tabsToShowIndexes;},_hideCurrentTab:function()
{if(!this._currentTab)
return;this._hideTab(this._currentTab);delete this._currentTab;},_showTab:function(tab)
{tab.tabElement.classList.add("selected");tab.view.show(this.element);this._updateTabSlider();},_updateTabSlider:function()
{if(!this._currentTab||!this._sliderEnabled)
return;var left=0;for(var i=0;i<this._tabs.length&&this._currentTab!==this._tabs[i]&&this._tabs[i]._shown;i++)
left+=this._tabs[i]._measuredWidth;var sliderWidth=this._currentTab._shown?this._currentTab._measuredWidth:this._dropDownButton.offsetWidth;var scaleFactor=window.devicePixelRatio>=1.5?" scaleY(0.75)":"";this._tabSlider.style.transform="translateX("+left+"px)"+scaleFactor;this._tabSlider.style.width=sliderWidth+"px";if(this._tabSlider.parentElement!==this._headerContentsElement)
this._headerContentsElement.appendChild(this._tabSlider);},_hideTab:function(tab)
{tab.tabElement.classList.remove("selected");tab.view.detach();},elementsToRestoreScrollPositionsFor:function()
{return[this._contentElement];},_insertBefore:function(tab,index)
{this._tabsElement.insertBefore(tab._tabElement||null,this._tabsElement.childNodes[index]);var oldIndex=this._tabs.indexOf(tab);this._tabs.splice(oldIndex,1);if(oldIndex<index)
--index;this._tabs.splice(index,0,tab);this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabOrderChanged,this._tabs);},insertBeforeTabStrip:function(element)
{element.classList.add("tabbed-pane-header-before");this.element.appendChild(element);},appendAfterTabStrip:function(element)
{element.classList.add("tabbed-pane-header-after");this.element.appendChild(element);},renderWithNoHeaderBackground:function()
{this._headerElement.classList.add("tabbed-pane-no-header-background");},setAllowTabReorder:function(allow,automatic)
{this._allowTabReorder=allow;this._automaticReorder=automatic;},__proto__:WebInspector.VBox.prototype}
WebInspector.TabbedPaneTab=function(tabbedPane,id,title,closeable,view,tooltip)
{this._closeable=closeable;this._tabbedPane=tabbedPane;this._id=id;this._title=title;this._tooltip=tooltip;this._view=view;this._shown=false;this._measuredWidth;this._tabElement;}
WebInspector.TabbedPaneTab.prototype={get id()
{return this._id;},get title()
{return this._title;},set title(title)
{if(title===this._title)
return;this._title=title;if(this._titleElement)
this._titleElement.textContent=title;delete this._measuredWidth;},isCloseable:function()
{return this._closeable;},_setIconType:function(iconType,iconTooltip)
{if(iconType===this._iconType&&iconTooltip===this._iconTooltip)
return false;this._iconType=iconType;this._iconTooltip=iconTooltip;if(this._tabElement)
this._createIconElement(this._tabElement,this._titleElement);delete this._measuredWidth;return true;},_toggleClass:function(className,force)
{var element=this.tabElement;var hasClass=element.classList.contains(className);if(hasClass===force)
return false;element.classList.toggle(className,force);delete this._measuredWidth;return true;},get view()
{return this._view;},set view(view)
{this._view=view;},get tooltip()
{return this._tooltip;},set tooltip(tooltip)
{this._tooltip=tooltip;if(this._titleElement)
this._titleElement.title=tooltip||"";},get tabElement()
{if(!this._tabElement)
this._tabElement=this._createTabElement(false);return this._tabElement;},width:function()
{return this._width;},setWidth:function(width)
{this.tabElement.style.width=width===-1?"":(width+"px");this._width=width;},setDelegate:function(delegate)
{this._delegate=delegate;},_createIconElement:function(tabElement,titleElement)
{if(tabElement.__iconElement)
tabElement.__iconElement.remove();if(!this._iconType)
return;var iconElement=createElementWithClass("label","tabbed-pane-header-tab-icon","dt-icon-label");iconElement.type=this._iconType;if(this._iconTooltip)
iconElement.title=this._iconTooltip;tabElement.insertBefore(iconElement,titleElement);tabElement.__iconElement=iconElement;},_createTabElement:function(measuring)
{var tabElement=createElementWithClass("div","tabbed-pane-header-tab");tabElement.id="tab-"+this._id;tabElement.tabIndex=-1;tabElement.selectTabForTest=this._tabbedPane.selectTab.bind(this._tabbedPane,this.id,true);var titleElement=tabElement.createChild("span","tabbed-pane-header-tab-title");titleElement.textContent=this.title;titleElement.title=this.tooltip||"";this._createIconElement(tabElement,titleElement);if(!measuring)
this._titleElement=titleElement;if(this._closeable)
tabElement.createChild("div","tabbed-pane-close-button","dt-close-button").gray=true;if(measuring){tabElement.classList.add("measuring");}else{tabElement.addEventListener("click",this._tabClicked.bind(this),false);tabElement.addEventListener("mousedown",this._tabMouseDown.bind(this),false);tabElement.addEventListener("mouseup",this._tabMouseUp.bind(this),false);tabElement.addEventListener("contextmenu",this._tabContextMenu.bind(this),false);if(this._tabbedPane._allowTabReorder)
WebInspector.installDragHandle(tabElement,this._startTabDragging.bind(this),this._tabDragging.bind(this),this._endTabDragging.bind(this),"-webkit-grabbing","pointer",200);}
return tabElement;},_tabClicked:function(event)
{var middleButton=event.button===1;var shouldClose=this._closeable&&(middleButton||event.target.classList.contains("tabbed-pane-close-button"));if(!shouldClose){this._tabbedPane.focus();return;}
this._closeTabs([this.id]);event.consume(true);},_tabMouseDown:function(event)
{if(event.target.classList.contains("tabbed-pane-close-button")||event.button===1)
return;this._tabbedPane.selectTab(this.id,true);},_tabMouseUp:function(event)
{if(event.button===1)
event.consume(true);},_closeTabs:function(ids)
{if(this._delegate){this._delegate.closeTabs(this._tabbedPane,ids);return;}
this._tabbedPane.closeTabs(ids,true);},_tabContextMenu:function(event)
{function close()
{this._closeTabs([this.id]);}
function closeOthers()
{this._closeTabs(this._tabbedPane.otherTabs(this.id));}
function closeAll()
{this._closeTabs(this._tabbedPane.allTabs());}
function closeToTheRight()
{this._closeTabs(this._tabbedPane._tabsToTheRight(this.id));}
var contextMenu=new WebInspector.ContextMenu(event);if(this._closeable){contextMenu.appendItem(WebInspector.UIString.capitalize("Close"),close.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^others"),closeOthers.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^tabs to the ^right"),closeToTheRight.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^all"),closeAll.bind(this));}
if(this._delegate)
this._delegate.onContextMenu(this.id,contextMenu);contextMenu.show();},_startTabDragging:function(event)
{if(event.target.classList.contains("tabbed-pane-close-button"))
return false;this._dragStartX=event.pageX;this._tabElement.classList.add("dragging");this._tabbedPane._tabSlider.remove();return true;},_tabDragging:function(event)
{var tabElements=this._tabbedPane._tabsElement.childNodes;for(var i=0;i<tabElements.length;++i){var tabElement=tabElements[i];if(tabElement===this._tabElement)
continue;var intersects=tabElement.offsetLeft+tabElement.clientWidth>this._tabElement.offsetLeft&&this._tabElement.offsetLeft+this._tabElement.clientWidth>tabElement.offsetLeft;if(!intersects)
continue;if(Math.abs(event.pageX-this._dragStartX)<tabElement.clientWidth/2+5)
break;if(event.pageX-this._dragStartX>0){tabElement=tabElement.nextSibling;++i;}
var oldOffsetLeft=this._tabElement.offsetLeft;this._tabbedPane._insertBefore(this,i);this._dragStartX+=this._tabElement.offsetLeft-oldOffsetLeft;break;}
if(!this._tabElement.previousSibling&&event.pageX-this._dragStartX<0){this._tabElement.style.setProperty("left","0px");return;}
if(!this._tabElement.nextSibling&&event.pageX-this._dragStartX>0){this._tabElement.style.setProperty("left","0px");return;}
this._tabElement.style.setProperty("left",(event.pageX-this._dragStartX)+"px");},_endTabDragging:function(event)
{this._tabElement.classList.remove("dragging");this._tabElement.style.removeProperty("left");delete this._dragStartX;this._tabbedPane._updateTabSlider();}}
WebInspector.TabbedPaneTabDelegate=function()
{}
WebInspector.TabbedPaneTabDelegate.prototype={closeTabs:function(tabbedPane,ids){},onContextMenu:function(tabId,contextMenu){}}
WebInspector.ExtensibleTabbedPaneController=function(tabbedPane,extensionPoint,viewCallback)
{this._tabbedPane=tabbedPane;this._extensionPoint=extensionPoint;this._viewCallback=viewCallback;this._promiseForId={};this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed,this._tabClosed,this);this._views=new Map();this._closeableTabSetting=WebInspector.settings.createSetting(extensionPoint+"-closeableTabs",{});this._initialize();}
WebInspector.ExtensibleTabbedPaneController.prototype={_initialize:function()
{this._extensions=new Map();var extensions=self.runtime.extensions(this._extensionPoint);for(var i=0;i<extensions.length;++i){var id=extensions[i].descriptor()["name"];this._extensions.set(id,extensions[i]);if(this._isPermanentTab(id))
this._appendTab(extensions[i]);}
for(var i=0;i<extensions.length;i++){var id=extensions[i].descriptor()["name"];if(this._isCloseableTab(id)&&this._closeableTabSetting.get()[id])
this._appendTab(extensions[i]);}},_isPermanentTab:function(id)
{return this._extensions.get(id).descriptor()["persistence"]==="permanent"||!this._extensions.get(id).descriptor()["persistence"];},_isCloseableTab:function(id)
{return this._extensions.get(id).descriptor()["persistence"]==="closeable";},enableMoreTabsButton:function()
{var toolbar=new WebInspector.Toolbar("drawer-toolbar");toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(this._appendTabsToMenu.bind(this)));this._tabbedPane.insertBeforeTabStrip(toolbar.element);this._tabbedPane.disableOverflowMenu();},_appendTabsToMenu:function(contextMenu)
{for(var id of this._extensions.keysArray().filter(this._isPermanentTab.bind(this))){var title=WebInspector.UIString(this._extensions.get(id).title(WebInspector.platform()));contextMenu.appendItem(title,this.showTab.bind(this,id));}
for(var id of this._extensions.keysArray().filter(this._isCloseableTab.bind(this))){var title=WebInspector.UIString(this._extensions.get(id).title(WebInspector.platform()));contextMenu.appendItem(title,this.showTab.bind(this,id));}},_appendTab:function(extension)
{var descriptor=extension.descriptor();var id=descriptor["name"];var title=WebInspector.UIString(extension.title(WebInspector.platform()));var closeable=descriptor["persistence"]==="closeable"||descriptor["persistence"]==="temporary";this._tabbedPane.appendTab(id,title,this._views.get(id)||new WebInspector.Widget(),undefined,false,closeable);},showTab:function(id)
{function viewLoaded(view)
{if(this._pendingView===id)
this._tabbedPane.selectTab(id);delete this._pendingView;return view;}
console.assert(this._extensions.get(id));if(!this._tabbedPane.hasTab(id))
this._appendTab((this._extensions.get(id)));this._tabbedPane.selectTab(id);var descriptor=this._extensions.get(id).descriptor();if(descriptor["persistence"]==="closeable"){var tabs=this._closeableTabSetting.get();if(!tabs[id]){tabs[id]=true;this._closeableTabSetting.set(tabs);}}
this._pendingView=id;return this.viewForId(id).then(viewLoaded.bind(this));},_tabSelected:function(event)
{var tabId=(event.data.tabId);this.viewForId(tabId);},_tabClosed:function(event)
{var tabs=this._closeableTabSetting.get();if(tabs[event.data.tabId]){delete tabs[event.data.tabId];this._closeableTabSetting.set(tabs);}},viewIds:function()
{return this._extensions.keysArray();},viewForId:function(id)
{if(this._views.has(id))
return Promise.resolve((this._views.get(id)));if(!this._extensions.has(id))
return Promise.resolve((null));if(this._promiseForId[id])
return this._promiseForId[id];var promise=this._extensions.get(id).instancePromise();this._promiseForId[id]=(promise);return promise.then(cacheView.bind(this));function cacheView(object)
{var view=(object);delete this._promiseForId[id];this._views.set(id,view);if(this._viewCallback&&view)
this._viewCallback(id,view);var shouldFocus=this._tabbedPane.visibleView.element.isSelfOrAncestor(WebInspector.currentFocusElement());this._tabbedPane.changeTabView(id,view);if(shouldFocus)
view.focus();return view;}}};WebInspector.SidebarPane=function(title)
{WebInspector.Widget.call(this);this.setMinimumSize(25,0);this.element.className="sidebar-pane";this._title=title;this._expandCallback=null;this._paneVisible=true;}
WebInspector.SidebarPane.prototype={toolbar:function()
{if(!this._toolbar){this._toolbar=new WebInspector.Toolbar("");this._toolbar.element.addEventListener("click",consumeEvent);this.element.insertBefore(this._toolbar.element,this.element.firstChild);}
return this._toolbar;},title:function()
{return this._title;},expand:function()
{this.onContentReady();},onContentReady:function()
{if(this._expandCallback)
this._expandCallback();else
this._expandPending=true;},_attached:function(setVisibleCallback,expandCallback)
{this._setVisibleCallback=setVisibleCallback;this._setVisibleCallback(this._paneVisible);this._expandCallback=expandCallback;if(this._expandPending){delete this._expandPending;this._expandCallback();}},setVisible:function(visible)
{this._paneVisible=visible;if(this._setVisibleCallback)
this._setVisibleCallback(visible)},__proto__:WebInspector.Widget.prototype}
WebInspector.SidebarPaneTitle=function(container,pane)
{this._pane=pane;this.element=container.createChild("div","sidebar-pane-title");this.element.textContent=pane.title();this.element.tabIndex=0;this.element.addEventListener("click",this._toggleExpanded.bind(this),false);this.element.addEventListener("keydown",this._onTitleKeyDown.bind(this),false);}
WebInspector.SidebarPaneTitle.prototype={_expand:function()
{this.element.classList.add("expanded");this._pane.show(this.element.parentElement,(this.element.nextSibling));},_collapse:function()
{this.element.classList.remove("expanded");if(this._pane.element.parentNode==this.element.parentNode)
this._pane.detach();},_toggleExpanded:function()
{if(this.element.classList.contains("expanded"))
this._collapse();else
this._pane.expand();},_onTitleKeyDown:function(event)
{if(isEnterKey(event)||event.keyCode===WebInspector.KeyboardShortcut.Keys.Space.code)
this._toggleExpanded();}}
WebInspector.SidebarPaneStack=function()
{WebInspector.Widget.call(this);this.setMinimumSize(25,0);this.element.className="sidebar-pane-stack";this._titleByPane=new Map();}
WebInspector.SidebarPaneStack.prototype={addPane:function(pane)
{var paneTitle=new WebInspector.SidebarPaneTitle(this.element,pane);this._titleByPane.set(pane,paneTitle);if(pane._toolbar)
paneTitle.element.appendChild(pane._toolbar.element);pane._attached(this._setPaneVisible.bind(this,pane),paneTitle._expand.bind(paneTitle));},_setPaneVisible:function(pane,visible)
{var title=this._titleByPane.get(pane);if(!title)
return;title.element.classList.toggle("hidden",!visible);pane.element.classList.toggle("sidebar-pane-hidden",!visible);},__proto__:WebInspector.Widget.prototype}
WebInspector.SidebarTabbedPane=function()
{WebInspector.TabbedPane.call(this);this.element.classList.add("sidebar-tabbed-pane");}
WebInspector.SidebarTabbedPane.prototype={addPane:function(pane)
{var title=pane.title();this.appendTab(title,title,pane);if(pane._toolbar)
pane.element.insertBefore(pane._toolbar.element,pane.element.firstChild);pane._attached(this._setPaneVisible.bind(this,pane),this.selectTab.bind(this,title));},_setPaneVisible:function(pane,visible)
{var title=pane._title;if(visible){if(!this.hasTab(title))
this.appendTab(title,title,pane);}else{if(this.hasTab(title))
this.closeTab(title);}},__proto__:WebInspector.TabbedPane.prototype};WebInspector.TextPrompt=function(completions,stopCharacters)
{this._proxyElement;this._proxyElementDisplay="inline-block";this._loadCompletions=completions;this._completionStopCharacters=stopCharacters||" =:[({;,!+-*/&|^<>.";this._autocompletionTimeout=WebInspector.TextPrompt.DefaultAutocompletionTimeout;this._title="";}
WebInspector.TextPrompt.DefaultAutocompletionTimeout=250;WebInspector.TextPrompt.Events={ItemApplied:"text-prompt-item-applied",ItemAccepted:"text-prompt-item-accepted"};WebInspector.TextPrompt.prototype={setAutocompletionTimeout:function(timeout)
{this._autocompletionTimeout=timeout;},setSuggestBoxEnabled:function(suggestBoxEnabled)
{this._suggestBoxEnabled=suggestBoxEnabled;},renderAsBlock:function()
{this._proxyElementDisplay="block";},attach:function(element)
{return this._attachInternal(element);},attachAndStartEditing:function(element,blurListener)
{var proxyElement=this._attachInternal(element);this._startEditing(blurListener);return proxyElement;},_attachInternal:function(element)
{if(this._proxyElement)
throw"Cannot attach an attached TextPrompt";this._element=element;this._boundOnKeyDown=this.onKeyDown.bind(this);this._boundOnInput=this.onInput.bind(this);this._boundOnMouseWheel=this.onMouseWheel.bind(this);this._boundSelectStart=this._selectStart.bind(this);this._boundRemoveSuggestionAids=this._removeSuggestionAids.bind(this);this._proxyElement=element.ownerDocument.createElement("span");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(this._proxyElement,"ui/textPrompt.css");this._contentElement=shadowRoot.createChild("div");this._contentElement.createChild("content");this._proxyElement.style.display=this._proxyElementDisplay;element.parentElement.insertBefore(this._proxyElement,element);this._proxyElement.appendChild(element);this._element.classList.add("text-prompt");this._element.addEventListener("keydown",this._boundOnKeyDown,false);this._element.addEventListener("input",this._boundOnInput,false);this._element.addEventListener("mousewheel",this._boundOnMouseWheel,false);this._element.addEventListener("selectstart",this._boundSelectStart,false);this._element.addEventListener("blur",this._boundRemoveSuggestionAids,false);this._element.ownerDocument.defaultView.addEventListener("resize",this._boundRemoveSuggestionAids,false);if(this._suggestBoxEnabled)
this._suggestBox=new WebInspector.SuggestBox(this);if(this._title)
this._proxyElement.title=this._title;return this._proxyElement;},detach:function()
{this._removeFromElement();this._proxyElement.parentElement.insertBefore(this._element,this._proxyElement);this._proxyElement.remove();delete this._proxyElement;this._element.classList.remove("text-prompt");WebInspector.restoreFocusFromElement(this._element);},text:function()
{return this._element.textContent;},userEnteredText:function()
{var text=this.text();if(this.autoCompleteElement){var addition=this.autoCompleteElement.textContent;text=text.substring(0,text.length-addition.length);}
return text;},setText:function(x)
{this._removeSuggestionAids();if(!x){this._element.removeChildren();this._element.createChild("br");}else{this._element.textContent=x;}
this.moveCaretToEndOfPrompt();this._element.scrollIntoView();},title:function()
{return this._title;},setTitle:function(title)
{this._title=title;if(this._proxyElement)
this._proxyElement.title=title;},_removeFromElement:function()
{this.clearAutoComplete(true);this._element.removeEventListener("keydown",this._boundOnKeyDown,false);this._element.removeEventListener("input",this._boundOnInput,false);this._element.removeEventListener("selectstart",this._boundSelectStart,false);this._element.removeEventListener("blur",this._boundRemoveSuggestionAids,false);this._element.ownerDocument.defaultView.removeEventListener("resize",this._boundRemoveSuggestionAids,false);if(this._isEditing)
this._stopEditing();if(this._suggestBox)
this._suggestBox.removeFromElement();},_startEditing:function(blurListener)
{this._isEditing=true;this._contentElement.classList.add("text-prompt-editing");if(blurListener){this._blurListener=blurListener;this._element.addEventListener("blur",this._blurListener,false);}
this._oldTabIndex=this._element.tabIndex;if(this._element.tabIndex<0)
this._element.tabIndex=0;WebInspector.setCurrentFocusElement(this._element);if(!this.text())
this._updateAutoComplete();},_stopEditing:function()
{this._element.tabIndex=this._oldTabIndex;if(this._blurListener)
this._element.removeEventListener("blur",this._blurListener,false);this._contentElement.classList.remove("text-prompt-editing");delete this._isEditing;},_removeSuggestionAids:function()
{this.clearAutoComplete();this.hideSuggestBox();},_selectStart:function()
{if(this._selectionTimeout)
clearTimeout(this._selectionTimeout);this._removeSuggestionAids();function moveBackIfOutside()
{delete this._selectionTimeout;if(!this.isCaretInsidePrompt()&&this._element.isComponentSelectionCollapsed()){this.moveCaretToEndOfPrompt();this.autoCompleteSoon();}}
this._selectionTimeout=setTimeout(moveBackIfOutside.bind(this),100);},_updateAutoComplete:function(force)
{this.clearAutoComplete();this.autoCompleteSoon(force);},onMouseWheel:function(event)
{},onKeyDown:function(event)
{if(isEnterKey(event))
return;var handled=false;delete this._needUpdateAutocomplete;switch(event.keyIdentifier){case"U+0009":handled=this.tabKeyPressed(event);break;case"Left":case"Home":this._removeSuggestionAids();break;case"Right":case"End":if(this.isCaretAtEndOfPrompt())
handled=this.acceptAutoComplete();else
this._removeSuggestionAids();break;case"U+001B":if(this.isSuggestBoxVisible()){this._removeSuggestionAids();handled=true;}
break;case"U+0020":if(event.ctrlKey&&!event.metaKey&&!event.altKey&&!event.shiftKey){this._updateAutoComplete(true);handled=true;}
break;case"Alt":case"Meta":case"Shift":case"Control":break;}
if(!handled&&this.isSuggestBoxVisible())
handled=this._suggestBox.keyPressed(event);if(!handled)
this._needUpdateAutocomplete=true;if(handled)
event.consume(true);},onInput:function(event)
{if(this._needUpdateAutocomplete)
this._updateAutoComplete();},acceptAutoComplete:function()
{var result=false;if(this.isSuggestBoxVisible())
result=this._suggestBox.acceptSuggestion();if(!result)
result=this._acceptSuggestionInternal();return result;},clearAutoComplete:function(includeTimeout)
{if(includeTimeout&&this._completeTimeout){clearTimeout(this._completeTimeout);delete this._completeTimeout;}
delete this._waitingForCompletions;if(!this.autoCompleteElement)
return;this.autoCompleteElement.remove();delete this.autoCompleteElement;delete this._userEnteredRange;delete this._userEnteredText;},autoCompleteSoon:function(force)
{var immediately=this.isSuggestBoxVisible()||force;if(!this._completeTimeout)
this._completeTimeout=setTimeout(this.complete.bind(this,force),immediately?0:this._autocompletionTimeout);},complete:function(force,reverse)
{this.clearAutoComplete(true);var selection=this._element.getComponentSelection();var selectionRange=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!selectionRange)
return;var shouldExit;if(!force&&!this.isCaretAtEndOfPrompt()&&!this.isSuggestBoxVisible())
shouldExit=true;else if(!selection.isCollapsed)
shouldExit=true;else if(!force){var wordSuffixRange=selectionRange.startContainer.rangeOfWord(selectionRange.endOffset,this._completionStopCharacters,this._element,"forward");if(wordSuffixRange.toString().length)
shouldExit=true;}
if(shouldExit){this.hideSuggestBox();return;}
var wordPrefixRange=selectionRange.startContainer.rangeOfWord(selectionRange.startOffset,this._completionStopCharacters,this._element,"backward");this._waitingForCompletions=true;this._loadCompletions((this._proxyElement),this.text(),selectionRange.startOffset,wordPrefixRange,force||false,this._completionsReady.bind(this,selection,wordPrefixRange,!!reverse,!!force));},disableDefaultSuggestionForEmptyInput:function()
{this._disableDefaultSuggestionForEmptyInput=true;},_boxForAnchorAtStart:function(selection,textRange)
{var rangeCopy=selection.getRangeAt(0).cloneRange();var anchorElement=createElement("span");anchorElement.textContent="\u200B";textRange.insertNode(anchorElement);var box=anchorElement.boxInWindow(window);anchorElement.remove();selection.removeAllRanges();selection.addRange(rangeCopy);return box;},_buildCommonPrefix:function(completions,wordPrefixLength)
{var commonPrefix=completions[0];for(var i=0;i<completions.length;++i){var completion=completions[i];var lastIndex=Math.min(commonPrefix.length,completion.length);for(var j=wordPrefixLength;j<lastIndex;++j){if(commonPrefix[j]!==completion[j]){commonPrefix=commonPrefix.substr(0,j);break;}}}
return commonPrefix;},_createRange:function()
{return document.createRange();},additionalCompletions:function(prefix)
{return[];},_completionsReady:function(selection,originalWordPrefixRange,reverse,force,completions,selectedIndex)
{var prefix=originalWordPrefixRange.toString();var store=new Set();completions=completions.filter(item=>!store.has(item)&&!!store.add(item));var annotatedCompletions=completions.map(item=>({title:item}));if(prefix||force){if(prefix)
annotatedCompletions=annotatedCompletions.concat(this.additionalCompletions(prefix));else
annotatedCompletions=this.additionalCompletions(prefix).concat(annotatedCompletions);}
if(!this._waitingForCompletions||!annotatedCompletions.length){this.hideSuggestBox();return;}
delete this._waitingForCompletions;var selectionRange=selection.getRangeAt(0);var fullWordRange=this._createRange();fullWordRange.setStart(originalWordPrefixRange.startContainer,originalWordPrefixRange.startOffset);fullWordRange.setEnd(selectionRange.endContainer,selectionRange.endOffset);if(prefix+selectionRange.toString()!==fullWordRange.toString())
return;selectedIndex=(this._disableDefaultSuggestionForEmptyInput&&!this.text())?-1:(selectedIndex||0);this._userEnteredRange=fullWordRange;this._userEnteredText=fullWordRange.toString();if(this._suggestBox)
this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection,fullWordRange),annotatedCompletions,selectedIndex,!this.isCaretAtEndOfPrompt(),this._userEnteredText);if(selectedIndex===-1)
return;var wordPrefixLength=originalWordPrefixRange.toString().length;this._commonPrefix=this._buildCommonPrefix(completions,wordPrefixLength);if(this.isCaretAtEndOfPrompt()){var completionText=annotatedCompletions[selectedIndex].title;var prefixText=this._userEnteredRange.toString();var suffixText=completionText.substring(wordPrefixLength);this._userEnteredRange.deleteContents();this._element.normalize();var finalSelectionRange=this._createRange();var prefixTextNode=createTextNode(prefixText);fullWordRange.insertNode(prefixTextNode);this.autoCompleteElement=createElementWithClass("span","auto-complete-text");this.autoCompleteElement.textContent=suffixText;prefixTextNode.parentNode.insertBefore(this.autoCompleteElement,prefixTextNode.nextSibling);finalSelectionRange.setStart(prefixTextNode,wordPrefixLength);finalSelectionRange.setEnd(prefixTextNode,wordPrefixLength);selection.removeAllRanges();selection.addRange(finalSelectionRange);this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied);}},_completeCommonPrefix:function()
{if(!this.autoCompleteElement||!this._commonPrefix||!this._userEnteredText||!this._commonPrefix.startsWith(this._userEnteredText))
return;if(!this.isSuggestBoxVisible()){this.acceptAutoComplete();return;}
this.autoCompleteElement.textContent=this._commonPrefix.substring(this._userEnteredText.length);this._acceptSuggestionInternal(true);},applySuggestion:function(completionText,isIntermediateSuggestion)
{this._applySuggestion(completionText,isIntermediateSuggestion);},_applySuggestion:function(completionText,isIntermediateSuggestion)
{if(!this._userEnteredRange){return;}
var wordPrefixLength=this._userEnteredText?this._userEnteredText.length:0;this._userEnteredRange.deleteContents();this._element.normalize();var finalSelectionRange=this._createRange();var completionTextNode=createTextNode(completionText);this._userEnteredRange.insertNode(completionTextNode);if(this.autoCompleteElement){this.autoCompleteElement.remove();delete this.autoCompleteElement;}
if(isIntermediateSuggestion)
finalSelectionRange.setStart(completionTextNode,wordPrefixLength);else
finalSelectionRange.setStart(completionTextNode,completionText.length);finalSelectionRange.setEnd(completionTextNode,completionText.length);var selection=this._element.getComponentSelection();selection.removeAllRanges();selection.addRange(finalSelectionRange);if(isIntermediateSuggestion)
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied,{itemText:completionText});},acceptSuggestion:function()
{this._acceptSuggestionInternal();},_acceptSuggestionInternal:function(prefixAccepted)
{if(!this.autoCompleteElement||!this.autoCompleteElement.parentNode)
return false;var text=this.autoCompleteElement.textContent;var textNode=createTextNode(text);this.autoCompleteElement.parentNode.replaceChild(textNode,this.autoCompleteElement);delete this.autoCompleteElement;var finalSelectionRange=this._createRange();finalSelectionRange.setStart(textNode,text.length);finalSelectionRange.setEnd(textNode,text.length);var selection=this._element.getComponentSelection();selection.removeAllRanges();selection.addRange(finalSelectionRange);if(!prefixAccepted){this.hideSuggestBox();this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);}else
this.autoCompleteSoon(true);return true;},hideSuggestBox:function()
{if(this.isSuggestBoxVisible())
this._suggestBox.hide();},isSuggestBoxVisible:function()
{return this._suggestBox&&this._suggestBox.visible();},isCaretInsidePrompt:function()
{return this._element.isInsertionCaretInside();},isCaretAtEndOfPrompt:function()
{var selection=this._element.getComponentSelection();var selectionRange=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!selectionRange||!selection.isCollapsed)
return false;var node=selectionRange.startContainer;if(!node.isSelfOrDescendant(this._element))
return false;if(node.nodeType===Node.TEXT_NODE&&selectionRange.startOffset<node.nodeValue.length)
return false;var foundNextText=false;while(node){if(node.nodeType===Node.TEXT_NODE&&node.nodeValue.length){if(foundNextText&&(!this.autoCompleteElement||!this.autoCompleteElement.isAncestor(node)))
return false;foundNextText=true;}
node=node.traverseNextNode(this._element);}
return true;},isCaretOnFirstLine:function()
{var selection=this._element.getComponentSelection();var focusNode=selection.focusNode;if(!focusNode||focusNode.nodeType!==Node.TEXT_NODE||focusNode.parentNode!==this._element)
return true;if(focusNode.textContent.substring(0,selection.focusOffset).indexOf("\n")!==-1)
return false;focusNode=focusNode.previousSibling;while(focusNode){if(focusNode.nodeType!==Node.TEXT_NODE)
return true;if(focusNode.textContent.indexOf("\n")!==-1)
return false;focusNode=focusNode.previousSibling;}
return true;},isCaretOnLastLine:function()
{var selection=this._element.getComponentSelection();var focusNode=selection.focusNode;if(!focusNode||focusNode.nodeType!==Node.TEXT_NODE||focusNode.parentNode!==this._element)
return true;if(focusNode.textContent.substring(selection.focusOffset).indexOf("\n")!==-1)
return false;focusNode=focusNode.nextSibling;while(focusNode){if(focusNode.nodeType!==Node.TEXT_NODE)
return true;if(focusNode.textContent.indexOf("\n")!==-1)
return false;focusNode=focusNode.nextSibling;}
return true;},moveCaretToEndOfPrompt:function()
{var selection=this._element.getComponentSelection();var selectionRange=this._createRange();var container=this._element;while(container.childNodes.length)
container=container.lastChild;var offset=container.nodeType===Node.TEXT_NODE?container.textContent.length:0;selectionRange.setStart(container,offset);selectionRange.setEnd(container,offset);selection.removeAllRanges();selection.addRange(selectionRange);},tabKeyPressed:function(event)
{this.acceptAutoComplete();return true;},proxyElementForTests:function()
{return this._proxyElement||null;},__proto__:WebInspector.Object.prototype}
WebInspector.TextPromptWithHistory=function(completions,stopCharacters)
{WebInspector.TextPrompt.call(this,completions,stopCharacters);this._data=[];this._historyOffset=1;this._addCompletionsFromHistory=true;}
WebInspector.TextPromptWithHistory.prototype={historyData:function()
{return this._data;},additionalCompletions:function(prefix)
{if(!this._addCompletionsFromHistory||!this.isCaretAtEndOfPrompt())
return[];var result=[];var text=this.text();var set=new Set();for(var i=this._data.length-1;i>=0&&result.length<50;--i){var item=this._data[i];if(!item.startsWith(text))
continue;if(set.has(item))
continue;set.add(item);result.push({title:item.substring(text.length-prefix.length),className:"additional"});}
return result;},setHistoryData:function(data)
{this._data=[].concat(data);this._historyOffset=1;},setAddCompletionsFromHistory:function(value)
{this._addCompletionsFromHistory=value;},pushHistoryItem:function(text)
{if(this._uncommittedIsTop){this._data.pop();delete this._uncommittedIsTop;}
this._historyOffset=1;if(text===this._currentHistoryItem())
return;this._data.push(text);},_pushCurrentText:function()
{if(this._uncommittedIsTop)
this._data.pop();this._uncommittedIsTop=true;this.clearAutoComplete(true);this._data.push(this.text());},_previous:function()
{if(this._historyOffset>this._data.length)
return undefined;if(this._historyOffset===1)
this._pushCurrentText();++this._historyOffset;return this._currentHistoryItem();},_next:function()
{if(this._historyOffset===1)
return undefined;--this._historyOffset;return this._currentHistoryItem();},_currentHistoryItem:function()
{return this._data[this._data.length-this._historyOffset];},onKeyDown:function(event)
{var newText;var isPrevious;switch(event.keyIdentifier){case"Up":if(!this.isCaretOnFirstLine()||this.isSuggestBoxVisible())
break;newText=this._previous();isPrevious=true;break;case"Down":if(!this.isCaretOnLastLine()||this.isSuggestBoxVisible())
break;newText=this._next();break;case"U+0050":if(WebInspector.isMac()&&event.ctrlKey&&!event.metaKey&&!event.altKey&&!event.shiftKey){newText=this._previous();isPrevious=true;}
break;case"U+004E":if(WebInspector.isMac()&&event.ctrlKey&&!event.metaKey&&!event.altKey&&!event.shiftKey)
newText=this._next();break;}
if(newText!==undefined){event.consume(true);this.setText(newText);if(isPrevious){var firstNewlineIndex=this.text().indexOf("\n");if(firstNewlineIndex===-1)
this.moveCaretToEndOfPrompt();else{var selection=this._element.getComponentSelection();var selectionRange=this._createRange();selectionRange.setStart(this._element.firstChild,firstNewlineIndex);selectionRange.setEnd(this._element.firstChild,firstNewlineIndex);selection.removeAllRanges();selection.addRange(selectionRange);}}
return;}
WebInspector.TextPrompt.prototype.onKeyDown.apply(this,arguments);},__proto__:WebInspector.TextPrompt.prototype};WebInspector.highlightedSearchResultClassName="highlighted-search-result";WebInspector.highlightedCurrentSearchResultClassName="current-search-result";WebInspector.installDragHandle=function(element,elementDragStart,elementDrag,elementDragEnd,cursor,hoverCursor,startDelay)
{function onMouseDown(event)
{var dragStart=WebInspector.elementDragStart.bind(WebInspector,element,elementDragStart,elementDrag,elementDragEnd,cursor,event);if(!startDelay)
dragStart();startTimer=setTimeout(dragStart,startDelay||0);}
function onMouseUp()
{if(startTimer)
clearInterval(startTimer);startTimer=null;}
var startTimer;element.addEventListener("mousedown",onMouseDown,false);if(startDelay)
element.addEventListener("mouseup",onMouseUp,false);if(hoverCursor!==null)
element.style.cursor=hoverCursor||cursor;}
WebInspector.elementDragStart=function(targetElement,elementDragStart,elementDrag,elementDragEnd,cursor,event)
{if(event.button||(WebInspector.isMac()&&event.ctrlKey))
return;if(WebInspector._elementDraggingEventListener)
return;if(elementDragStart&&!elementDragStart((event)))
return;if(WebInspector._elementDraggingGlassPane){WebInspector._elementDraggingGlassPane.dispose();delete WebInspector._elementDraggingGlassPane;}
var targetDocument=event.target.ownerDocument;WebInspector._elementDraggingEventListener=elementDrag;WebInspector._elementEndDraggingEventListener=elementDragEnd;WebInspector._mouseOutWhileDraggingTargetDocument=targetDocument;WebInspector._dragEventsTargetDocument=targetDocument;WebInspector._dragEventsTargetDocumentTop=targetDocument.defaultView.top.document;targetDocument.addEventListener("mousemove",WebInspector._elementDragMove,true);targetDocument.addEventListener("mouseup",WebInspector._elementDragEnd,true);targetDocument.addEventListener("mouseout",WebInspector._mouseOutWhileDragging,true);if(targetDocument!==WebInspector._dragEventsTargetDocumentTop)
WebInspector._dragEventsTargetDocumentTop.addEventListener("mouseup",WebInspector._elementDragEnd,true);if(typeof cursor==="string"){WebInspector._restoreCursorAfterDrag=restoreCursor.bind(null,targetElement.style.cursor);targetElement.style.cursor=cursor;targetDocument.body.style.cursor=cursor;}
function restoreCursor(oldCursor)
{targetDocument.body.style.removeProperty("cursor");targetElement.style.cursor=oldCursor;WebInspector._restoreCursorAfterDrag=null;}
event.preventDefault();}
WebInspector._mouseOutWhileDragging=function()
{var document=WebInspector._mouseOutWhileDraggingTargetDocument;WebInspector._unregisterMouseOutWhileDragging();WebInspector._elementDraggingGlassPane=new WebInspector.GlassPane(document);}
WebInspector._unregisterMouseOutWhileDragging=function()
{if(!WebInspector._mouseOutWhileDraggingTargetDocument)
return;WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout",WebInspector._mouseOutWhileDragging,true);delete WebInspector._mouseOutWhileDraggingTargetDocument;}
WebInspector._unregisterDragEvents=function()
{if(!WebInspector._dragEventsTargetDocument)
return;WebInspector._dragEventsTargetDocument.removeEventListener("mousemove",WebInspector._elementDragMove,true);WebInspector._dragEventsTargetDocument.removeEventListener("mouseup",WebInspector._elementDragEnd,true);if(WebInspector._dragEventsTargetDocument!==WebInspector._dragEventsTargetDocumentTop)
WebInspector._dragEventsTargetDocumentTop.removeEventListener("mouseup",WebInspector._elementDragEnd,true);delete WebInspector._dragEventsTargetDocument;delete WebInspector._dragEventsTargetDocumentTop;}
WebInspector._elementDragMove=function(event)
{if(event.buttons!==1){WebInspector._elementDragEnd(event);return;}
if(WebInspector._elementDraggingEventListener((event)))
WebInspector._cancelDragEvents(event);}
WebInspector._cancelDragEvents=function(event)
{WebInspector._unregisterDragEvents();WebInspector._unregisterMouseOutWhileDragging();if(WebInspector._restoreCursorAfterDrag)
WebInspector._restoreCursorAfterDrag();if(WebInspector._elementDraggingGlassPane)
WebInspector._elementDraggingGlassPane.dispose();delete WebInspector._elementDraggingGlassPane;delete WebInspector._elementDraggingEventListener;delete WebInspector._elementEndDraggingEventListener;}
WebInspector._elementDragEnd=function(event)
{var elementDragEnd=WebInspector._elementEndDraggingEventListener;WebInspector._cancelDragEvents((event));event.preventDefault();if(elementDragEnd)
elementDragEnd((event));}
WebInspector.installInertialDragHandle=function(element,elementDragStart,elementDrag,elementDragEnd,cursor,hoverCursor,startDelay,friction)
{WebInspector.installDragHandle(element,drag.bind(null,elementDragStart),drag.bind(null,elementDrag),dragEnd,cursor,hoverCursor,startDelay);if(typeof friction!=="number")
friction=50;var lastX;var lastY;var lastTime;var velocityX;var velocityY;var holding=false;function drag(callback,event)
{lastTime=window.performance.now();lastX=event.pageX;lastY=event.pageY;holding=true;return callback(lastX,lastY,event);}
function dragEnd(event)
{var now=window.performance.now();var duration=now-lastTime||1;const maxVelocity=4;velocityX=Number.constrain((event.pageX-lastX)/duration,-maxVelocity,maxVelocity);velocityY=Number.constrain((event.pageY-lastY)/duration,-maxVelocity,maxVelocity);lastX=event.pageX;lastY=event.pageY;lastTime=now;holding=false;animationStep();}
function animationStep()
{var v2=velocityX*velocityX+velocityY*velocityY;if(v2<0.001||holding){elementDragEnd(lastX,lastY);return;}
element.window().requestAnimationFrame(animationStep);var now=window.performance.now();var duration=now-lastTime;if(!duration)
return;lastTime=now;lastX+=velocityX*duration;lastY+=velocityY*duration;var k=Math.pow(1/(1+friction),duration/1000);velocityX*=k;velocityY*=k;elementDrag(lastX,lastY);}}
WebInspector.GlassPane=function(document,dimmed)
{this.element=createElement("div");var background=dimmed?"rgba(255, 255, 255, 0.5)":"transparent";this._zIndex=WebInspector._glassPane?WebInspector._glassPane._zIndex+1000:3000;this.element.style.cssText="position:absolute;top:0;bottom:0;left:0;right:0;background-color:"+background+";z-index:"+this._zIndex+";overflow:hidden;";document.body.appendChild(this.element);WebInspector._glassPane=this;}
WebInspector.GlassPane.prototype={dispose:function()
{delete WebInspector._glassPane;if(WebInspector.GlassPane.DefaultFocusedViewStack.length)
WebInspector.GlassPane.DefaultFocusedViewStack.peekLast().focus();this.element.remove();}}
WebInspector._glassPane;WebInspector.GlassPane.DefaultFocusedViewStack=[];WebInspector.isBeingEdited=function(node)
{if(!node||node.nodeType!==Node.ELEMENT_NODE)
return false;var element=(node);if(element.classList.contains("text-prompt")||element.nodeName==="INPUT"||element.nodeName==="TEXTAREA")
return true;if(!WebInspector.__editingCount)
return false;while(element){if(element.__editing)
return true;element=element.parentElementOrShadowHost();}
return false;}
WebInspector.isEditing=function()
{if(WebInspector.__editingCount)
return true;var element=WebInspector.currentFocusElement();if(!element)
return false;return element.classList.contains("text-prompt")||element.nodeName==="INPUT"||element.nodeName==="TEXTAREA";}
WebInspector.markBeingEdited=function(element,value)
{if(value){if(element.__editing)
return false;element.classList.add("being-edited");element.__editing=true;WebInspector.__editingCount=(WebInspector.__editingCount||0)+1;}else{if(!element.__editing)
return false;element.classList.remove("being-edited");delete element.__editing;--WebInspector.__editingCount;}
return true;}
WebInspector.CSSNumberRegex=/^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;WebInspector.StyleValueDelimiters=" \xA0\t\n\"':;,/()";WebInspector._valueModificationDirection=function(event)
{var direction=null;if(event.type==="mousewheel"){if(event.wheelDeltaY>0||event.wheelDeltaX>0)
direction="Up";else if(event.wheelDeltaY<0||event.wheelDeltaX<0)
direction="Down";}else{if(event.keyIdentifier==="Up"||event.keyIdentifier==="PageUp")
direction="Up";else if(event.keyIdentifier==="Down"||event.keyIdentifier==="PageDown")
direction="Down";}
return direction;}
WebInspector._modifiedHexValue=function(hexString,event)
{var direction=WebInspector._valueModificationDirection(event);if(!direction)
return hexString;var mouseEvent=(event);var number=parseInt(hexString,16);if(isNaN(number)||!isFinite(number))
return hexString;var hexStrLen=hexString.length;var channelLen=hexStrLen/3;if(channelLen!==1&&channelLen!==2)
return hexString;var delta=0;if(WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent))
delta+=Math.pow(16,channelLen*2);if(mouseEvent.shiftKey)
delta+=Math.pow(16,channelLen);if(mouseEvent.altKey)
delta+=1;if(delta===0)
delta=1;if(direction==="Down")
delta*=-1;var maxValue=Math.pow(16,hexStrLen)-1;var result=Number.constrain(number+delta,0,maxValue);var resultString=result.toString(16).toUpperCase();for(var i=0,lengthDelta=hexStrLen-resultString.length;i<lengthDelta;++i)
resultString="0"+resultString;return resultString;}
WebInspector._modifiedFloatNumber=function(number,event)
{var direction=WebInspector._valueModificationDirection(event);if(!direction)
return number;var mouseEvent=(event);var delta=1;if(WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent))
delta=100;else if(mouseEvent.shiftKey)
delta=10;else if(mouseEvent.altKey)
delta=0.1;if(direction==="Down")
delta*=-1;var result=Number((number+delta).toFixed(6));if(!String(result).match(WebInspector.CSSNumberRegex))
return null;return result;}
WebInspector.createReplacementString=function(wordString,event,customNumberHandler)
{var replacementString;var prefix,suffix,number;var matches;matches=/(.*#)([\da-fA-F]+)(.*)/.exec(wordString);if(matches&&matches.length){prefix=matches[1];suffix=matches[3];number=WebInspector._modifiedHexValue(matches[2],event);replacementString=customNumberHandler?customNumberHandler(prefix,number,suffix):prefix+number+suffix;}else{matches=/(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);if(matches&&matches.length){prefix=matches[1];suffix=matches[3];number=WebInspector._modifiedFloatNumber(parseFloat(matches[2]),event);if(number===null)
return null;replacementString=customNumberHandler?customNumberHandler(prefix,number,suffix):prefix+number+suffix;}}
return replacementString||null;}
WebInspector.handleElementValueModifications=function(event,element,finishHandler,suggestionHandler,customNumberHandler)
{function createRange()
{return document.createRange();}
var arrowKeyOrMouseWheelEvent=(event.keyIdentifier==="Up"||event.keyIdentifier==="Down"||event.type==="mousewheel");var pageKeyPressed=(event.keyIdentifier==="PageUp"||event.keyIdentifier==="PageDown");if(!arrowKeyOrMouseWheelEvent&&!pageKeyPressed)
return false;var selection=element.getComponentSelection();if(!selection.rangeCount)
return false;var selectionRange=selection.getRangeAt(0);if(!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
return false;var originalValue=element.textContent;var wordRange=selectionRange.startContainer.rangeOfWord(selectionRange.startOffset,WebInspector.StyleValueDelimiters,element);var wordString=wordRange.toString();if(suggestionHandler&&suggestionHandler(wordString))
return false;var replacementString=WebInspector.createReplacementString(wordString,event,customNumberHandler);if(replacementString){var replacementTextNode=createTextNode(replacementString);wordRange.deleteContents();wordRange.insertNode(replacementTextNode);var finalSelectionRange=createRange();finalSelectionRange.setStart(replacementTextNode,0);finalSelectionRange.setEnd(replacementTextNode,replacementString.length);selection.removeAllRanges();selection.addRange(finalSelectionRange);event.handled=true;event.preventDefault();if(finishHandler)
finishHandler(originalValue,replacementString);return true;}
return false;}
Number.preciseMillisToString=function(ms,precision)
{precision=precision||0;var format="%."+precision+"f\u2009ms";return WebInspector.UIString(format,ms);}
WebInspector._subMillisFormat=new WebInspector.UIStringFormat("%.2f\u2009ms");WebInspector._millisFormat=new WebInspector.UIStringFormat("%.0f\u2009ms");WebInspector._secondsFormat=new WebInspector.UIStringFormat("%.2f\u2009s");WebInspector._minutesFormat=new WebInspector.UIStringFormat("%.1f\u2009min");WebInspector._hoursFormat=new WebInspector.UIStringFormat("%.1f\u2009hrs");WebInspector._daysFormat=new WebInspector.UIStringFormat("%.1f\u2009days");Number.millisToString=function(ms,higherResolution)
{if(!isFinite(ms))
return"-";if(ms===0)
return"0";if(higherResolution&&ms<1000)
return WebInspector._subMillisFormat.format(ms);else if(ms<1000)
return WebInspector._millisFormat.format(ms);var seconds=ms/1000;if(seconds<60)
return WebInspector._secondsFormat.format(seconds);var minutes=seconds/60;if(minutes<60)
return WebInspector._minutesFormat.format(minutes);var hours=minutes/60;if(hours<24)
return WebInspector._hoursFormat.format(hours);var days=hours/24;return WebInspector._daysFormat.format(days);}
Number.secondsToString=function(seconds,higherResolution)
{if(!isFinite(seconds))
return"-";return Number.millisToString(seconds*1000,higherResolution);}
Number.bytesToString=function(bytes)
{if(bytes<1024)
return WebInspector.UIString("%.0f\u2009B",bytes);var kilobytes=bytes/1024;if(kilobytes<100)
return WebInspector.UIString("%.1f\u2009KB",kilobytes);if(kilobytes<1024)
return WebInspector.UIString("%.0f\u2009KB",kilobytes);var megabytes=kilobytes/1024;if(megabytes<100)
return WebInspector.UIString("%.1f\u2009MB",megabytes);else
return WebInspector.UIString("%.0f\u2009MB",megabytes);}
Number.withThousandsSeparator=function(num)
{var str=num+"";var re=/(\d+)(\d{3})/;while(str.match(re))
str=str.replace(re,"$1\u2009$2");return str;}
WebInspector.formatLocalized=function(format,substitutions)
{var formatters={s:substitution=>substitution};function append(a,b)
{a.appendChild(typeof b==="string"?createTextNode(b):b);return a;}
return String.format(WebInspector.UIString(format),substitutions,formatters,createElement("span"),append).formattedResult;}
WebInspector.openLinkExternallyLabel=function()
{return WebInspector.UIString.capitalize("Open ^link in ^new ^tab");}
WebInspector.copyLinkAddressLabel=function()
{return WebInspector.UIString.capitalize("Copy ^link ^address");}
WebInspector.anotherProfilerActiveLabel=function()
{return WebInspector.UIString("Another profiler is already active");}
WebInspector.asyncStackTraceLabel=function(description)
{if(description)
return description+" "+WebInspector.UIString("(async)");return WebInspector.UIString("Async Call");}
WebInspector.manageBlackboxingSettingsTabLabel=function()
{return WebInspector.UIString("Blackboxing");}
WebInspector.installComponentRootStyles=function(element)
{WebInspector.appendStyle(element,"ui/inspectorCommon.css");WebInspector.themeSupport.injectHighlightStyleSheets(element);element.classList.add("platform-"+WebInspector.platform());}
WebInspector.createShadowRootWithCoreStyles=function(element,cssFile)
{var shadowRoot=element.createShadowRoot();WebInspector.appendStyle(shadowRoot,"ui/inspectorCommon.css");WebInspector.themeSupport.injectHighlightStyleSheets(shadowRoot);if(cssFile)
WebInspector.appendStyle(shadowRoot,cssFile);shadowRoot.addEventListener("focus",WebInspector._focusChanged.bind(WebInspector),true);return shadowRoot;}
WebInspector._windowFocused=function(document,event)
{if(event.target.document.nodeType===Node.DOCUMENT_NODE)
document.body.classList.remove("inactive");}
WebInspector._windowBlurred=function(document,event)
{if(event.target.document.nodeType===Node.DOCUMENT_NODE)
document.body.classList.add("inactive");}
WebInspector.previousFocusElement=function()
{return WebInspector._previousFocusElement;}
WebInspector.currentFocusElement=function()
{return WebInspector._currentFocusElement;}
WebInspector._focusChanged=function(event)
{var node=event.deepActiveElement();WebInspector.setCurrentFocusElement(node);}
WebInspector._documentBlurred=function(document,event)
{if(!event.relatedTarget&&document.activeElement===document.body)
WebInspector.setCurrentFocusElement(null);}
WebInspector._textInputTypes=["text","search","tel","url","email","password"].keySet();WebInspector._isTextEditingElement=function(element)
{if(element instanceof HTMLInputElement)
return element.type in WebInspector._textInputTypes;if(element instanceof HTMLTextAreaElement)
return true;return false;}
WebInspector.setCurrentFocusElement=function(x)
{if(WebInspector._glassPane&&x&&!WebInspector._glassPane.element.isAncestor(x))
return;if(x&&!x.ownerDocument.isAncestor(x))
return;if(WebInspector._currentFocusElement!==x)
WebInspector._previousFocusElement=WebInspector._currentFocusElement;WebInspector._currentFocusElement=x;if(x){x.focus();var selection=x.getComponentSelection();if(!WebInspector._isTextEditingElement(x)&&selection.isCollapsed&&!x.isInsertionCaretInside()){var selectionRange=x.ownerDocument.createRange();selectionRange.setStart(x,0);selectionRange.setEnd(x,0);selection.removeAllRanges();selection.addRange(selectionRange);}}else if(WebInspector._previousFocusElement)
WebInspector._previousFocusElement.blur();}
WebInspector.restoreFocusFromElement=function(element)
{if(element&&element.isSelfOrAncestor(WebInspector.currentFocusElement()))
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());}
WebInspector.highlightSearchResult=function(element,offset,length,domChanges)
{var result=WebInspector.highlightSearchResults(element,[new WebInspector.SourceRange(offset,length)],domChanges);return result.length?result[0]:null;}
WebInspector.highlightSearchResults=function(element,resultRanges,changes)
{return WebInspector.highlightRangesWithStyleClass(element,resultRanges,WebInspector.highlightedSearchResultClassName,changes);}
WebInspector.runCSSAnimationOnce=function(element,className)
{function animationEndCallback()
{element.classList.remove(className);element.removeEventListener("webkitAnimationEnd",animationEndCallback,false);}
if(element.classList.contains(className))
element.classList.remove(className);element.addEventListener("webkitAnimationEnd",animationEndCallback,false);element.classList.add(className);}
WebInspector.highlightRangesWithStyleClass=function(element,resultRanges,styleClass,changes)
{changes=changes||[];var highlightNodes=[];var textNodes=element.childTextNodes();var lineText=textNodes.map(function(node){return node.textContent;}).join("");var ownerDocument=element.ownerDocument;if(textNodes.length===0)
return highlightNodes;var nodeRanges=[];var rangeEndOffset=0;for(var i=0;i<textNodes.length;++i){var range={};range.offset=rangeEndOffset;range.length=textNodes[i].textContent.length;rangeEndOffset=range.offset+range.length;nodeRanges.push(range);}
var startIndex=0;for(var i=0;i<resultRanges.length;++i){var startOffset=resultRanges[i].offset;var endOffset=startOffset+resultRanges[i].length;while(startIndex<textNodes.length&&nodeRanges[startIndex].offset+nodeRanges[startIndex].length<=startOffset)
startIndex++;var endIndex=startIndex;while(endIndex<textNodes.length&&nodeRanges[endIndex].offset+nodeRanges[endIndex].length<endOffset)
endIndex++;if(endIndex===textNodes.length)
break;var highlightNode=ownerDocument.createElement("span");highlightNode.className=styleClass;highlightNode.textContent=lineText.substring(startOffset,endOffset);var lastTextNode=textNodes[endIndex];var lastText=lastTextNode.textContent;lastTextNode.textContent=lastText.substring(endOffset-nodeRanges[endIndex].offset);changes.push({node:lastTextNode,type:"changed",oldText:lastText,newText:lastTextNode.textContent});if(startIndex===endIndex){lastTextNode.parentElement.insertBefore(highlightNode,lastTextNode);changes.push({node:highlightNode,type:"added",nextSibling:lastTextNode,parent:lastTextNode.parentElement});highlightNodes.push(highlightNode);var prefixNode=ownerDocument.createTextNode(lastText.substring(0,startOffset-nodeRanges[startIndex].offset));lastTextNode.parentElement.insertBefore(prefixNode,highlightNode);changes.push({node:prefixNode,type:"added",nextSibling:highlightNode,parent:lastTextNode.parentElement});}else{var firstTextNode=textNodes[startIndex];var firstText=firstTextNode.textContent;var anchorElement=firstTextNode.nextSibling;firstTextNode.parentElement.insertBefore(highlightNode,anchorElement);changes.push({node:highlightNode,type:"added",nextSibling:anchorElement,parent:firstTextNode.parentElement});highlightNodes.push(highlightNode);firstTextNode.textContent=firstText.substring(0,startOffset-nodeRanges[startIndex].offset);changes.push({node:firstTextNode,type:"changed",oldText:firstText,newText:firstTextNode.textContent});for(var j=startIndex+1;j<endIndex;j++){var textNode=textNodes[j];var text=textNode.textContent;textNode.textContent="";changes.push({node:textNode,type:"changed",oldText:text,newText:textNode.textContent});}}
startIndex=endIndex;nodeRanges[startIndex].offset=endOffset;nodeRanges[startIndex].length=lastTextNode.textContent.length;}
return highlightNodes;}
WebInspector.applyDomChanges=function(domChanges)
{for(var i=0,size=domChanges.length;i<size;++i){var entry=domChanges[i];switch(entry.type){case"added":entry.parent.insertBefore(entry.node,entry.nextSibling);break;case"changed":entry.node.textContent=entry.newText;break;}}}
WebInspector.revertDomChanges=function(domChanges)
{for(var i=domChanges.length-1;i>=0;--i){var entry=domChanges[i];switch(entry.type){case"added":entry.node.remove();break;case"changed":entry.node.textContent=entry.oldText;break;}}}
WebInspector.measurePreferredSize=function(element,containerElement)
{containerElement=containerElement||element.ownerDocument.body;containerElement.appendChild(element);element.positionAt(0,0);var result=new Size(element.offsetWidth,element.offsetHeight);element.positionAt(undefined,undefined);element.remove();return result;}
WebInspector.InvokeOnceHandlers=function(autoInvoke)
{this._handlers=null;this._autoInvoke=autoInvoke;}
WebInspector.InvokeOnceHandlers.prototype={add:function(object,method)
{if(!this._handlers){this._handlers=new Map();if(this._autoInvoke)
this.scheduleInvoke();}
var methods=this._handlers.get(object);if(!methods){methods=new Set();this._handlers.set(object,methods);}
methods.add(method);},scheduleInvoke:function()
{if(this._handlers)
requestAnimationFrame(this._invoke.bind(this));},_invoke:function()
{var handlers=this._handlers;this._handlers=null;var keys=handlers.keysArray();for(var i=0;i<keys.length;++i){var object=keys[i];var methods=handlers.get(object).valuesArray();for(var j=0;j<methods.length;++j)
methods[j].call(object);}}}
WebInspector._coalescingLevel=0;WebInspector._postUpdateHandlers=null;WebInspector.startBatchUpdate=function()
{if(!WebInspector._coalescingLevel++)
WebInspector._postUpdateHandlers=new WebInspector.InvokeOnceHandlers(false);}
WebInspector.endBatchUpdate=function()
{if(--WebInspector._coalescingLevel)
return;WebInspector._postUpdateHandlers.scheduleInvoke();WebInspector._postUpdateHandlers=null;}
WebInspector.invokeOnceAfterBatchUpdate=function(object,method)
{if(!WebInspector._postUpdateHandlers)
WebInspector._postUpdateHandlers=new WebInspector.InvokeOnceHandlers(true);WebInspector._postUpdateHandlers.add(object,method);}
WebInspector.animateFunction=function(window,func,params,frames,animationComplete)
{var values=new Array(params.length);var deltas=new Array(params.length);for(var i=0;i<params.length;++i){values[i]=params[i].from;deltas[i]=(params[i].to-params[i].from)/frames;}
var raf=window.requestAnimationFrame(animationStep);var framesLeft=frames;function animationStep()
{if(--framesLeft<0){if(animationComplete)
animationComplete();return;}
for(var i=0;i<params.length;++i){if(params[i].to>params[i].from)
values[i]=Number.constrain(values[i]+deltas[i],params[i].from,params[i].to);else
values[i]=Number.constrain(values[i]+deltas[i],params[i].to,params[i].from);}
func.apply(null,values);raf=window.requestAnimationFrame(animationStep);}
function cancelAnimation()
{window.cancelAnimationFrame(raf);}
return cancelAnimation;}
WebInspector.LongClickController=function(element,callback)
{this._element=element;this._callback=callback;this._enable();}
WebInspector.LongClickController.prototype={reset:function()
{if(this._longClickInterval){clearInterval(this._longClickInterval);delete this._longClickInterval;}},_enable:function()
{if(this._longClickData)
return;var boundMouseDown=mouseDown.bind(this);var boundMouseUp=mouseUp.bind(this);var boundReset=this.reset.bind(this);this._element.addEventListener("mousedown",boundMouseDown,false);this._element.addEventListener("mouseout",boundReset,false);this._element.addEventListener("mouseup",boundMouseUp,false);this._element.addEventListener("click",boundReset,true);this._longClickData={mouseUp:boundMouseUp,mouseDown:boundMouseDown,reset:boundReset};function mouseDown(e)
{if(e.which!==1)
return;var callback=this._callback;this._longClickInterval=setTimeout(callback.bind(null,e),200);}
function mouseUp(e)
{if(e.which!==1)
return;this.reset();}},dispose:function()
{if(!this._longClickData)
return;this._element.removeEventListener("mousedown",this._longClickData.mouseDown,false);this._element.removeEventListener("mouseout",this._longClickData.reset,false);this._element.removeEventListener("mouseup",this._longClickData.mouseUp,false);this._element.addEventListener("click",this._longClickData.reset,true);delete this._longClickData;},__proto__:WebInspector.Object.prototype}
WebInspector.initializeUIUtils=function(document,themeSetting)
{document.defaultView.addEventListener("focus",WebInspector._windowFocused.bind(WebInspector,document),false);document.defaultView.addEventListener("blur",WebInspector._windowBlurred.bind(WebInspector,document),false);document.addEventListener("focus",WebInspector._focusChanged.bind(WebInspector),true);document.addEventListener("blur",WebInspector._documentBlurred.bind(WebInspector,document),true);if(!WebInspector.themeSupport)
WebInspector.themeSupport=new WebInspector.ThemeSupport(themeSetting);WebInspector.themeSupport.applyTheme(document);var body=(document.body);WebInspector.appendStyle(body,"ui/inspectorStyle.css");WebInspector.appendStyle(body,"ui/popover.css");WebInspector.appendStyle(body,"ui/sidebarPane.css");}
WebInspector.beautifyFunctionName=function(name)
{return name||WebInspector.UIString("(anonymous function)");}
function registerCustomElement(localName,typeExtension,prototype)
{return document.registerElement(typeExtension,{prototype:Object.create(prototype),extends:localName});}
function createTextButton(text,clickHandler,className,title)
{var element=createElementWithClass("button",className||"","text-button");element.textContent=text;if(clickHandler)
element.addEventListener("click",clickHandler,false);if(title)
element.title=title;return element;}
function createRadioLabel(name,title,checked)
{var element=createElement("label","dt-radio");element.radioElement.name=name;element.radioElement.checked=!!checked;element.createTextChild(title);return element;}
function createLabel(title,iconClass)
{var element=createElement("label","dt-icon-label");element.createChild("span").textContent=title;element.type=iconClass;return element;}
function createCheckboxLabel(title,checked,subtitle)
{var element=createElement("label","dt-checkbox");element.checkboxElement.checked=!!checked;if(title!==undefined){element.textElement=element.createChild("div","dt-checkbox-text");element.textElement.textContent=title;if(subtitle!==undefined){element.subtitleElement=element.textElement.createChild("div","dt-checkbox-subtitle");element.subtitleElement.textContent=subtitle;}}
return element;}
WebInspector.appendStyle=function(node,cssFile)
{var content=Runtime.cachedResources[cssFile]||"";if(!content)
console.error(cssFile+" not preloaded. Check module.json");var styleElement=createElement("style");styleElement.type="text/css";styleElement.textContent=content;node.appendChild(styleElement);var themeStyleSheet=WebInspector.themeSupport.themeStyleSheet(cssFile,content);if(themeStyleSheet){styleElement=createElement("style");styleElement.type="text/css";styleElement.textContent=themeStyleSheet+"\n"+Runtime.resolveSourceURL(cssFile+".theme");node.appendChild(styleElement);}};(function(){registerCustomElement("button","text-button",{createdCallback:function()
{this.type="button";var root=WebInspector.createShadowRootWithCoreStyles(this,"ui/textButton.css");root.createChild("content");},__proto__:HTMLButtonElement.prototype});registerCustomElement("label","dt-radio",{createdCallback:function()
{this.radioElement=this.createChild("input","dt-radio-button");this.radioElement.type="radio";var root=WebInspector.createShadowRootWithCoreStyles(this,"ui/radioButton.css");root.createChild("content").select=".dt-radio-button";root.createChild("content");this.addEventListener("click",radioClickHandler,false);},__proto__:HTMLLabelElement.prototype});function radioClickHandler(event)
{if(this.radioElement.checked||this.radioElement.disabled)
return;this.radioElement.checked=true;this.radioElement.dispatchEvent(new Event("change"));}
registerCustomElement("label","dt-checkbox",{createdCallback:function()
{this._root=WebInspector.createShadowRootWithCoreStyles(this,"ui/checkboxTextLabel.css");var checkboxElement=createElementWithClass("input","dt-checkbox-button");checkboxElement.type="checkbox";this._root.appendChild(checkboxElement);this.checkboxElement=checkboxElement;this.addEventListener("click",toggleCheckbox.bind(this));function toggleCheckbox(event)
{if(event.target!==checkboxElement&&event.target!==this){event.consume();checkboxElement.click();}}
this._root.createChild("content");},set backgroundColor(color)
{this.checkboxElement.classList.add("dt-checkbox-themed");this.checkboxElement.style.backgroundColor=color;},set checkColor(color)
{this.checkboxElement.classList.add("dt-checkbox-themed");var stylesheet=createElement("style");stylesheet.textContent="input.dt-checkbox-themed:checked:after { background-color: "+color+"}";this._root.appendChild(stylesheet);},set borderColor(color)
{this.checkboxElement.classList.add("dt-checkbox-themed");this.checkboxElement.style.borderColor=color;},__proto__:HTMLLabelElement.prototype});registerCustomElement("label","dt-icon-label",{createdCallback:function()
{var root=WebInspector.createShadowRootWithCoreStyles(this,"ui/smallIcon.css");this._iconElement=root.createChild("div");root.createChild("content");},set type(type)
{this._iconElement.className=type;},__proto__:HTMLLabelElement.prototype});registerCustomElement("div","dt-close-button",{createdCallback:function()
{var root=WebInspector.createShadowRootWithCoreStyles(this,"ui/closeButton.css");this._buttonElement=root.createChild("div","close-button");},set gray(gray)
{this._buttonElement.className=gray?"close-button-gray":"close-button";},__proto__:HTMLDivElement.prototype});})();WebInspector.bindInput=function(input,apply,validate,numeric)
{input.addEventListener("change",onChange,false);input.addEventListener("input",onInput,false);input.addEventListener("keydown",onKeyDown,false);input.addEventListener("focus",input.select.bind(input),false);function onInput()
{input.classList.toggle("error-input",!validate(input.value));}
function onChange()
{var valid=validate(input.value);input.classList.toggle("error-input",!valid);if(valid)
apply(input.value);}
function onKeyDown(event)
{if(isEnterKey(event)){if(validate(input.value))
apply(input.value);return;}
if(!numeric)
return;var increment=event.keyIdentifier==="Up"?1:event.keyIdentifier==="Down"?-1:0;if(!increment)
return;if(event.shiftKey)
increment*=10;var value=input.value;if(!validate(value)||!value)
return;value=(value?Number(value):0)+increment;var stringValue=value?String(value):"";if(!validate(stringValue)||!value)
return;input.value=stringValue;apply(input.value);event.preventDefault();}
function setValue(value)
{if(value===input.value)
return;var valid=validate(value);input.classList.toggle("error-input",!valid);input.value=value;if(input.type!=="number")
input.setSelectionRange(value.length,value.length);}
return setValue;}
WebInspector.StringFormatter=function()
{this._processors=[];this._regexes=[];}
WebInspector.StringFormatter.prototype={addProcessor:function(regex,handler)
{this._regexes.push(regex);this._processors.push(handler);},formatText:function(text)
{return this._runProcessor(0,text);},_runProcessor:function(processorIndex,text)
{if(processorIndex>=this._processors.length)
return createTextNode(text);var container=createDocumentFragment();var regex=this._regexes[processorIndex];var processor=this._processors[processorIndex];var items=text.replace(regex,"\0$1\0").split("\0");for(var i=0;i<items.length;++i){var processedNode=i%2?processor(items[i]):this._runProcessor(processorIndex+1,items[i]);container.appendChild(processedNode);}
return container;}}
WebInspector.ThemeSupport=function(setting)
{this._themeName=setting.get()||"default";this._themableProperties=new Set(["color","box-shadow","text-shadow","outline-color","background-image","background-color","border-left-color","border-right-color","border-top-color","border-bottom-color","-webkit-border-image"]);this._cachedThemePatches=new Map();this._setting=setting;}
WebInspector.ThemeSupport.ColorUsage={Unknown:0,Foreground:1<<0,Background:1<<1,Selection:1<<2,};WebInspector.ThemeSupport.prototype={hasTheme:function()
{return this._themeName!=="default";},injectHighlightStyleSheets:function(element)
{this._injectingStyleSheet=true;WebInspector.appendStyle(element,"ui/inspectorSyntaxHighlight.css");if(this._themeName==="dark")
WebInspector.appendStyle(element,"ui/inspectorSyntaxHighlightDark.css");this._injectingStyleSheet=false;},applyTheme:function(document)
{if(!this.hasTheme())
return;if(this._themeName==="dark")
document.body.classList.add("-theme-with-dark-background");var styleSheets=document.styleSheets;var result=[];for(var i=0;i<styleSheets.length;++i)
result.push(this._patchForTheme(styleSheets[i].href,styleSheets[i]));result.push("/*# sourceURL=inspector.css.theme */");var styleElement=createElement("style");styleElement.type="text/css";styleElement.textContent=result.join("\n");document.head.appendChild(styleElement);},themeStyleSheet:function(id,text)
{if(!this.hasTheme()||this._injectingStyleSheet)
return"";var patch=this._cachedThemePatches.get(id);if(!patch){var styleElement=createElement("style");styleElement.type="text/css";styleElement.textContent=text;document.body.appendChild(styleElement);patch=this._patchForTheme(id,styleElement.sheet);document.body.removeChild(styleElement);}
return patch;},_patchForTheme:function(id,styleSheet)
{var cached=this._cachedThemePatches.get(id);if(cached)
return cached;try{var rules=styleSheet.cssRules;var result=[];for(var j=0;j<rules.length;++j){if(rules[j]instanceof CSSImportRule){result.push(this._patchForTheme(rules[j].styleSheet.href,rules[j].styleSheet));continue;}
var output=[];var style=rules[j].style;var selectorText=rules[j].selectorText;for(var i=0;style&&i<style.length;++i)
this._patchProperty(selectorText,style,style[i],output);if(output.length)
result.push(rules[j].selectorText+"{"+output.join("")+"}");}
var fullText=result.join("\n");this._cachedThemePatches.set(id,fullText);return fullText;}catch(e){this._setting.set("default");return"";}},_patchProperty:function(selectorText,style,name,output)
{if(!this._themableProperties.has(name))
return;var value=style.getPropertyValue(name);if(!value||value==="none"||value==="inherit"||value==="initial"||value==="transparent")
return;if(name==="background-image"&&value.indexOf("gradient")===-1)
return;var isSelection=selectorText.indexOf(".-theme-selection-color")!==-1;if(selectorText.indexOf("-theme-")!==-1&&!isSelection)
return;if(name==="-webkit-border-image"){output.push("-webkit-filter: invert(100%)");return;}
isSelection=isSelection||selectorText.indexOf("selected")!==-1||selectorText.indexOf(".selection")!==-1;var colorUsage=WebInspector.ThemeSupport.ColorUsage.Unknown;if(isSelection)
colorUsage|=WebInspector.ThemeSupport.ColorUsage.Selection;if(name.indexOf("background")===0||name.indexOf("border")===0)
colorUsage|=WebInspector.ThemeSupport.ColorUsage.Background;if(name.indexOf("background")===-1)
colorUsage|=WebInspector.ThemeSupport.ColorUsage.Foreground;var colorRegex=/((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;output.push(name);output.push(":");var items=value.replace(colorRegex,"\0$1\0").split("\0");for(var i=0;i<items.length;++i)
output.push(this.patchColor(items[i],colorUsage));if(style.getPropertyPriority(name))
output.push(" !important");output.push(";");},patchColor:function(text,colorUsage)
{var color=WebInspector.Color.parse(text);if(!color)
return text;var hsla=color.hsla();this._patchHSLA(hsla,colorUsage);var rgba=[];WebInspector.Color.hsl2rgb(hsla,rgba);var outColor=new WebInspector.Color(rgba,color.format());var outText=outColor.asString(null);if(!outText)
outText=outColor.asString(outColor.hasAlpha()?WebInspector.Color.Format.RGBA:WebInspector.Color.Format.RGB);return outText||text;},_patchHSLA:function(hsla,colorUsage)
{var hue=hsla[0];var sat=hsla[1];var lit=hsla[2];var alpha=hsla[3]
switch(this._themeName){case"dark":if(colorUsage&WebInspector.ThemeSupport.ColorUsage.Selection)
hue=(hue+0.5)%1;var minCap=colorUsage&WebInspector.ThemeSupport.ColorUsage.Background?0.14:0;var maxCap=colorUsage&WebInspector.ThemeSupport.ColorUsage.Foreground?0.9:1;lit=1-lit;if(lit<minCap*2)
lit=minCap+lit/2;else if(lit>2*maxCap-1)
lit=maxCap-1/2+lit/2;break;}
hsla[0]=Number.constrain(hue,0,1);hsla[1]=Number.constrain(sat,0,1);hsla[2]=Number.constrain(lit,0,1);hsla[3]=Number.constrain(alpha,0,1);}}
WebInspector.uiLabelForPriority=function(priority)
{var labelMap=WebInspector.uiLabelForPriority._priorityToUILabel;if(!labelMap){labelMap=new Map([[NetworkAgent.ResourcePriority.VeryLow,WebInspector.UIString("Lowest")],[NetworkAgent.ResourcePriority.Low,WebInspector.UIString("Low")],[NetworkAgent.ResourcePriority.Medium,WebInspector.UIString("Medium")],[NetworkAgent.ResourcePriority.High,WebInspector.UIString("High")],[NetworkAgent.ResourcePriority.VeryHigh,WebInspector.UIString("Highest")]]);WebInspector.uiLabelForPriority._priorityToUILabel=labelMap;}
return labelMap.get(priority)||WebInspector.UIString("Unknown");}
WebInspector.linkifyURLAsNode=function(url,linkText,classes,isExternal,tooltipText)
{if(!linkText)
linkText=url;var a=createElementWithClass("a",classes);var href=url;if(url.trim().toLowerCase().startsWith("javascript:"))
href=null;if(isExternal&&WebInspector.ParsedURL.isRelativeURL(url))
href=null;if(href!==null){a.href=href;a.classList.add(isExternal?"webkit-html-external-link":"webkit-html-resource-link");}
if(!tooltipText&&linkText!==url)
a.title=url;else if(tooltipText)
a.title=tooltipText;a.textContent=linkText.trimMiddle(150);if(isExternal)
a.setAttribute("target","_blank");return a;}
WebInspector.linkifyDocumentationURLAsNode=function(article,title)
{return WebInspector.linkifyURLAsNode("https://developers.google.com/web/tools/chrome-devtools/"+article,title,undefined,true);}
WebInspector.themeSupport;;WebInspector.ViewportControl=function(provider)
{this.element=createElement("div");this.element.style.overflow="auto";this._topGapElement=this.element.createChild("div");this._topGapElement.style.height="0px";this._topGapElement.style.color="transparent";this._contentElement=this.element.createChild("div");this._bottomGapElement=this.element.createChild("div");this._bottomGapElement.style.height="0px";this._bottomGapElement.style.color="transparent";this._topGapElement.textContent="\uFEFF";this._bottomGapElement.textContent="\uFEFF";this._provider=provider;this.element.addEventListener("scroll",this._onScroll.bind(this),false);this.element.addEventListener("copy",this._onCopy.bind(this),false);this.element.addEventListener("dragstart",this._onDragStart.bind(this),false);this._firstVisibleIndex=0;this._lastVisibleIndex=-1;this._renderedItems=[];this._anchorSelection=null;this._headSelection=null;this._stickToBottom=false;this._scrolledToBottom=true;this._itemCount=0;}
WebInspector.ViewportControl.Provider=function()
{}
WebInspector.ViewportControl.Provider.prototype={fastHeight:function(index){return 0;},itemCount:function(){return 0;},minimumRowHeight:function(){return 0;},itemElement:function(index){return null;}}
WebInspector.ViewportElement=function(){}
WebInspector.ViewportElement.prototype={willHide:function(){},wasShown:function(){},element:function(){},}
WebInspector.StaticViewportElement=function(element)
{this._element=element;}
WebInspector.StaticViewportElement.prototype={willHide:function(){},wasShown:function(){},element:function()
{return this._element;},}
WebInspector.ViewportControl.prototype={scrolledToBottom:function()
{return this._scrolledToBottom;},setStickToBottom:function(value)
{this._stickToBottom=value;},_onCopy:function(event)
{var text=this._selectedText();if(!text)
return;event.preventDefault();event.clipboardData.setData("text/plain",text);},_onDragStart:function(event)
{var text=this._selectedText();if(!text)
return false;event.dataTransfer.clearData();event.dataTransfer.setData("text/plain",text);event.dataTransfer.effectAllowed="copy";return true;},contentElement:function()
{return this._contentElement;},invalidate:function()
{delete this._cumulativeHeights;delete this._cachedProviderElements;this._itemCount=this._provider.itemCount();this._innerRefresh(false);},_providerElement:function(index)
{if(!this._cachedProviderElements)
this._cachedProviderElements=new Array(this._itemCount);var element=this._cachedProviderElements[index];if(!element){element=this._provider.itemElement(index);this._cachedProviderElements[index]=element;}
return element;},_rebuildCumulativeHeightsIfNeeded:function()
{if(this._cumulativeHeights)
return;if(!this._itemCount)
return;var firstVisibleIndex=this._firstVisibleIndex;var lastVisibleIndex=this._lastVisibleIndex;var height=0;this._cumulativeHeights=new Int32Array(this._itemCount);for(var i=0;i<this._itemCount;++i){if(firstVisibleIndex<=i&&i<=lastVisibleIndex)
height+=this._renderedItems[i-firstVisibleIndex].element().offsetHeight;else
height+=this._provider.fastHeight(i);this._cumulativeHeights[i]=height;}},_cachedItemHeight:function(index)
{return index===0?this._cumulativeHeights[0]:this._cumulativeHeights[index]-this._cumulativeHeights[index-1];},_isSelectionBackwards:function(selection)
{if(!selection||!selection.rangeCount)
return false;var range=document.createRange();range.setStart(selection.anchorNode,selection.anchorOffset);range.setEnd(selection.focusNode,selection.focusOffset);return range.collapsed;},_createSelectionModel:function(itemIndex,node,offset)
{return{item:itemIndex,node:node,offset:offset};},_updateSelectionModel:function(selection)
{var range=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!range||selection.isCollapsed){this._headSelection=null;this._anchorSelection=null;return false;}
var firstSelected=Number.MAX_VALUE;var lastSelected=-1;var hasVisibleSelection=false;for(var i=0;i<this._renderedItems.length;++i){if(range.intersectsNode(this._renderedItems[i].element())){var index=i+this._firstVisibleIndex;firstSelected=Math.min(firstSelected,index);lastSelected=Math.max(lastSelected,index);hasVisibleSelection=true;}}
if(hasVisibleSelection){firstSelected=this._createSelectionModel(firstSelected,(range.startContainer),range.startOffset);lastSelected=this._createSelectionModel(lastSelected,(range.endContainer),range.endOffset);}
var topOverlap=range.intersectsNode(this._topGapElement)&&this._topGapElement._active;var bottomOverlap=range.intersectsNode(this._bottomGapElement)&&this._bottomGapElement._active;if(!topOverlap&&!bottomOverlap&&!hasVisibleSelection){this._headSelection=null;this._anchorSelection=null;return false;}
if(!this._anchorSelection||!this._headSelection){this._anchorSelection=this._createSelectionModel(0,this.element,0);this._headSelection=this._createSelectionModel(this._itemCount-1,this.element,this.element.children.length);this._selectionIsBackward=false;}
var isBackward=this._isSelectionBackwards(selection);var startSelection=this._selectionIsBackward?this._headSelection:this._anchorSelection;var endSelection=this._selectionIsBackward?this._anchorSelection:this._headSelection;if(topOverlap&&bottomOverlap&&hasVisibleSelection){firstSelected=firstSelected.item<startSelection.item?firstSelected:startSelection;lastSelected=lastSelected.item>endSelection.item?lastSelected:endSelection;}else if(!hasVisibleSelection){firstSelected=startSelection;lastSelected=endSelection;}else if(topOverlap)
firstSelected=isBackward?this._headSelection:this._anchorSelection;else if(bottomOverlap)
lastSelected=isBackward?this._anchorSelection:this._headSelection;if(isBackward){this._anchorSelection=lastSelected;this._headSelection=firstSelected;}else{this._anchorSelection=firstSelected;this._headSelection=lastSelected;}
this._selectionIsBackward=isBackward;return true;},_restoreSelection:function(selection)
{var anchorElement=null;var anchorOffset;if(this._firstVisibleIndex<=this._anchorSelection.item&&this._anchorSelection.item<=this._lastVisibleIndex){anchorElement=this._anchorSelection.node;anchorOffset=this._anchorSelection.offset;}else{if(this._anchorSelection.item<this._firstVisibleIndex)
anchorElement=this._topGapElement;else if(this._anchorSelection.item>this._lastVisibleIndex)
anchorElement=this._bottomGapElement;anchorOffset=this._selectionIsBackward?1:0;}
var headElement=null;var headOffset;if(this._firstVisibleIndex<=this._headSelection.item&&this._headSelection.item<=this._lastVisibleIndex){headElement=this._headSelection.node;headOffset=this._headSelection.offset;}else{if(this._headSelection.item<this._firstVisibleIndex)
headElement=this._topGapElement;else if(this._headSelection.item>this._lastVisibleIndex)
headElement=this._bottomGapElement;headOffset=this._selectionIsBackward?0:1;}
selection.setBaseAndExtent(anchorElement,anchorOffset,headElement,headOffset);},refresh:function()
{this._innerRefresh(false);},_innerRefresh:function(isUserGesture)
{if(!this._visibleHeight())
return;if(!this._itemCount){for(var i=0;i<this._renderedItems.length;++i)
this._renderedItems[i].willHide();this._renderedItems=[];this._contentElement.removeChildren();this._topGapElement.style.height="0px";this._bottomGapElement.style.height="0px";this._firstVisibleIndex=-1;this._lastVisibleIndex=-1;return;}
var selection=this.element.getComponentSelection();var shouldRestoreSelection=this._updateSelectionModel(selection);var visibleFrom=this.element.scrollTop;var visibleHeight=this._visibleHeight();this._scrolledToBottom=this.element.isScrolledToBottom();var isInvalidating=!this._cumulativeHeights;for(var i=0;i<this._renderedItems.length;++i){if(this._cumulativeHeights&&Math.abs(this._cachedItemHeight(this._firstVisibleIndex+i)-this._renderedItems[i].element().offsetHeight)>1)
delete this._cumulativeHeights;}
this._rebuildCumulativeHeightsIfNeeded();var oldFirstVisibleIndex=this._firstVisibleIndex;var oldLastVisibleIndex=this._lastVisibleIndex;var shouldStickToBottom=!isUserGesture&&this._stickToBottom&&this._scrolledToBottom;if(shouldStickToBottom){this._lastVisibleIndex=this._itemCount-1;this._firstVisibleIndex=Math.max(this._itemCount-Math.ceil(visibleHeight/this._provider.minimumRowHeight()),0);}else{this._firstVisibleIndex=Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights,visibleFrom+1),0);this._lastVisibleIndex=this._firstVisibleIndex+Math.ceil(visibleHeight/this._provider.minimumRowHeight())-1;this._lastVisibleIndex=Math.min(this._lastVisibleIndex,this._itemCount-1);}
var topGapHeight=this._cumulativeHeights[this._firstVisibleIndex-1]||0;var bottomGapHeight=this._cumulativeHeights[this._cumulativeHeights.length-1]-this._cumulativeHeights[this._lastVisibleIndex];function prepare()
{this._topGapElement.style.height=topGapHeight+"px";this._bottomGapElement.style.height=bottomGapHeight+"px";this._topGapElement._active=!!topGapHeight;this._bottomGapElement._active=!!bottomGapHeight;this._contentElement.style.setProperty("height","10000000px");}
if(isInvalidating)
this._fullViewportUpdate(prepare.bind(this));else
this._partialViewportUpdate(oldFirstVisibleIndex,oldLastVisibleIndex,prepare.bind(this));this._contentElement.style.removeProperty("height");if(shouldRestoreSelection)
this._restoreSelection(selection);if(shouldStickToBottom)
this.element.scrollTop=10000000;},_fullViewportUpdate:function(prepare)
{for(var i=0;i<this._renderedItems.length;++i)
this._renderedItems[i].willHide();prepare();this._renderedItems=[];this._contentElement.removeChildren();for(var i=this._firstVisibleIndex;i<=this._lastVisibleIndex;++i){var viewportElement=this._providerElement(i);this._contentElement.appendChild(viewportElement.element());this._renderedItems.push(viewportElement);}
for(var i=0;i<this._renderedItems.length;++i)
this._renderedItems[i].wasShown();},_partialViewportUpdate:function(oldFirstVisibleIndex,oldLastVisibleIndex,prepare)
{var willBeHidden=[];for(var i=0;i<this._renderedItems.length;++i){var index=oldFirstVisibleIndex+i;if(index<this._firstVisibleIndex||this._lastVisibleIndex<index)
willBeHidden.push(this._renderedItems[i]);}
for(var i=0;i<willBeHidden.length;++i)
willBeHidden[i].willHide();prepare();for(var i=0;i<willBeHidden.length;++i)
willBeHidden[i].element().remove();this._renderedItems=[];var anchor=this._contentElement.firstChild;var wasShown=[];for(var i=this._firstVisibleIndex;i<=this._lastVisibleIndex;++i){var viewportElement=this._providerElement(i);var element=viewportElement.element();if(element!==anchor){this._contentElement.insertBefore(element,anchor);wasShown.push(viewportElement);}else{anchor=anchor.nextSibling;}
this._renderedItems.push(viewportElement);}
for(var i=0;i<wasShown.length;++i)
wasShown[i].wasShown();},_selectedText:function()
{this._updateSelectionModel(this.element.getComponentSelection());if(!this._headSelection||!this._anchorSelection)
return null;var startSelection=null;var endSelection=null;if(this._selectionIsBackward){startSelection=this._headSelection;endSelection=this._anchorSelection;}else{startSelection=this._anchorSelection;endSelection=this._headSelection;}
var textLines=[];for(var i=startSelection.item;i<=endSelection.item;++i)
textLines.push(this._providerElement(i).element().deepTextContent());var endSelectionElement=this._providerElement(endSelection.item).element();if(endSelection.node&&endSelection.node.isSelfOrDescendant(endSelectionElement)){var itemTextOffset=this._textOffsetInNode(endSelectionElement,endSelection.node,endSelection.offset);textLines[textLines.length-1]=textLines.peekLast().substring(0,itemTextOffset);}
var startSelectionElement=this._providerElement(startSelection.item).element();if(startSelection.node&&startSelection.node.isSelfOrDescendant(startSelectionElement)){var itemTextOffset=this._textOffsetInNode(startSelectionElement,startSelection.node,startSelection.offset);textLines[0]=textLines[0].substring(itemTextOffset);}
return textLines.join("\n");},_textOffsetInNode:function(itemElement,container,offset)
{var chars=0;var node=itemElement;while((node=node.traverseNextTextNode())&&node!==container)
chars+=node.textContent.length;return chars+offset;},_onScroll:function(event)
{this._innerRefresh(event.isTrusted);},firstVisibleIndex:function()
{return this._firstVisibleIndex;},lastVisibleIndex:function()
{return this._lastVisibleIndex;},renderedElementAt:function(index)
{if(index<this._firstVisibleIndex)
return null;if(index>this._lastVisibleIndex)
return null;return this._renderedItems[index-this._firstVisibleIndex].element();},scrollItemIntoView:function(index,makeLast)
{if(index>this._firstVisibleIndex&&index<this._lastVisibleIndex)
return;if(makeLast)
this.forceScrollItemToBeLast(index);else if(index<=this._firstVisibleIndex)
this.forceScrollItemToBeFirst(index);else if(index>=this._lastVisibleIndex)
this.forceScrollItemToBeLast(index);},forceScrollItemToBeFirst:function(index)
{this._rebuildCumulativeHeightsIfNeeded();this.element.scrollTop=index>0?this._cumulativeHeights[index-1]:0;this._innerRefresh(false);},forceScrollItemToBeLast:function(index)
{this._rebuildCumulativeHeightsIfNeeded();this.element.scrollTop=this._cumulativeHeights[index]-this._visibleHeight();this._innerRefresh(false);},_visibleHeight:function()
{return this.element.offsetHeight;}};WebInspector.ZoomManager=function(window,frontendHost)
{this._frontendHost=frontendHost;this._zoomFactor=this._frontendHost.zoomFactor();window.addEventListener("resize",this._onWindowResize.bind(this),true);};WebInspector.ZoomManager.Events={ZoomChanged:"ZoomChanged"};WebInspector.ZoomManager.prototype={zoomFactor:function()
{return this._zoomFactor;},cssToDIP:function(value)
{return value*this._zoomFactor;},dipToCSS:function(valueDIP)
{return valueDIP/this._zoomFactor;},_onWindowResize:function()
{var oldZoomFactor=this._zoomFactor;this._zoomFactor=this._frontendHost.zoomFactor();if(oldZoomFactor!==this._zoomFactor)
this.dispatchEventToListeners(WebInspector.ZoomManager.Events.ZoomChanged,{from:oldZoomFactor,to:this._zoomFactor});},__proto__:WebInspector.Object.prototype};WebInspector.zoomManager;;WebInspector.ThrottledWidget=function(isWebComponent)
{WebInspector.Widget.call(this,isWebComponent);this._updateThrottler=new WebInspector.Throttler(100);this._updateWhenVisible=false;}
WebInspector.ThrottledWidget.prototype={doUpdate:function()
{return Promise.resolve();},update:function()
{this._updateWhenVisible=!this.isShowing();if(this._updateWhenVisible)
return;this._updateThrottler.schedule(innerUpdate.bind(this));function innerUpdate()
{if(this.isShowing()){return this.doUpdate();}else{this._updateWhenVisible=true;return Promise.resolve();}}},wasShown:function()
{WebInspector.Widget.prototype.wasShown.call(this);if(this._updateWhenVisible)
this.update();},__proto__:WebInspector.Widget.prototype};function InspectorBackendClass()
{this._agentPrototypes={};this._dispatcherPrototypes={};this._initialized=false;this._initProtocolAgentsConstructor();}
InspectorBackendClass._DevToolsErrorCode=-32000;InspectorBackendClass.DevToolsStubErrorCode=-32015;InspectorBackendClass.reportProtocolError=function(error,messageObject)
{console.error(error+": "+JSON.stringify(messageObject));}
InspectorBackendClass.prototype={isInitialized:function()
{return this._initialized;},_initProtocolAgentsConstructor:function()
{window.Protocol={};window.Protocol.Agents=function(agentsMap){this._agentsMap=agentsMap;};},_addAgentGetterMethodToProtocolAgentsPrototype:function(domain)
{var upperCaseLength=0;while(upperCaseLength<domain.length&&domain[upperCaseLength].toLowerCase()!==domain[upperCaseLength])
++upperCaseLength;var methodName=domain.substr(0,upperCaseLength).toLowerCase()+domain.slice(upperCaseLength)+"Agent";function agentGetter()
{return this._agentsMap[domain];}
window.Protocol.Agents.prototype[methodName]=agentGetter;function registerDispatcher(dispatcher)
{this.registerDispatcher(domain,dispatcher)}
window.Protocol.Agents.prototype["register"+domain+"Dispatcher"]=registerDispatcher;},_agentPrototype:function(domain)
{if(!this._agentPrototypes[domain]){this._agentPrototypes[domain]=new InspectorBackendClass.AgentPrototype(domain);this._addAgentGetterMethodToProtocolAgentsPrototype(domain);}
return this._agentPrototypes[domain];},_dispatcherPrototype:function(domain)
{if(!this._dispatcherPrototypes[domain])
this._dispatcherPrototypes[domain]=new InspectorBackendClass.DispatcherPrototype();return this._dispatcherPrototypes[domain];},registerCommand:function(method,signature,replyArgs,hasErrorData)
{var domainAndMethod=method.split(".");this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1],signature,replyArgs,hasErrorData);this._initialized=true;},registerEnum:function(type,values)
{var domainAndMethod=type.split(".");var agentName=domainAndMethod[0]+"Agent";if(!window[agentName])
window[agentName]={};window[agentName][domainAndMethod[1]]=values;this._initialized=true;},registerEvent:function(eventName,params)
{var domain=eventName.split(".")[0];this._dispatcherPrototype(domain).registerEvent(eventName,params);this._initialized=true;},wrapClientCallback:function(clientCallback,errorPrefix,constructor,defaultValue)
{function callbackWrapper(error,value)
{if(error){console.error(errorPrefix+error);clientCallback(defaultValue);return;}
if(constructor)
clientCallback(new constructor(value));else
clientCallback(value);}
return callbackWrapper;}}
InspectorBackendClass.Connection=function()
{this._lastMessageId=1;this._pendingResponsesCount=0;this._agents={};this._dispatchers={};this._callbacks={};this._initialize(InspectorBackend._agentPrototypes,InspectorBackend._dispatcherPrototypes);this._isConnected=true;}
InspectorBackendClass.Connection.Events={Disconnected:"Disconnected",}
InspectorBackendClass.Connection.prototype={_initialize:function(agentPrototypes,dispatcherPrototypes)
{for(var domain in agentPrototypes){this._agents[domain]=Object.create(agentPrototypes[domain]);this._agents[domain].setConnection(this);}
for(var domain in dispatcherPrototypes)
this._dispatchers[domain]=Object.create(dispatcherPrototypes[domain]);},nextMessageId:function()
{return this._lastMessageId++;},agent:function(domain)
{return this._agents[domain];},agentsMap:function()
{return this._agents;},_wrapCallbackAndSendMessageObject:function(domain,method,params,callback)
{if(!this._isConnected&&callback){this._dispatchConnectionErrorResponse(domain,method,callback);return;}
var messageObject={};var messageId=this.nextMessageId();messageObject.id=messageId;messageObject.method=method;if(params)
messageObject.params=params;var wrappedCallback=this._wrap(callback,domain,method);if(InspectorBackendClass.Options.dumpInspectorProtocolMessages)
this._dumpProtocolMessage("frontend: "+JSON.stringify(messageObject));this.sendMessage(messageObject);++this._pendingResponsesCount;this._callbacks[messageId]=wrappedCallback;},_wrap:function(callback,domain,method)
{if(!callback)
callback=function(){};callback.methodName=method;callback.domain=domain;if(InspectorBackendClass.Options.dumpInspectorTimeStats)
callback.sendRequestTime=Date.now();return callback;},sendMessage:function(messageObject)
{throw"Not implemented";},dispatch:function(message)
{if(InspectorBackendClass.Options.dumpInspectorProtocolMessages)
this._dumpProtocolMessage("backend: "+((typeof message==="string")?message:JSON.stringify(message)));var messageObject=((typeof message==="string")?JSON.parse(message):message);if("id"in messageObject){var callback=this._callbacks[messageObject.id];if(!callback){InspectorBackendClass.reportProtocolError("Protocol Error: the message with wrong id",messageObject);return;}
var processingStartTime;if(InspectorBackendClass.Options.dumpInspectorTimeStats)
processingStartTime=Date.now();this.agent(callback.domain).dispatchResponse(messageObject,callback.methodName,callback);--this._pendingResponsesCount;delete this._callbacks[messageObject.id];if(InspectorBackendClass.Options.dumpInspectorTimeStats)
console.log("time-stats: "+callback.methodName+" = "+(processingStartTime-callback.sendRequestTime)+" + "+(Date.now()-processingStartTime));if(this._scripts&&!this._pendingResponsesCount)
this.deprecatedRunAfterPendingDispatches();return;}else{var method=messageObject.method.split(".");var domainName=method[0];if(!(domainName in this._dispatchers)){InspectorBackendClass.reportProtocolError("Protocol Error: the message "+messageObject.method+" is for non-existing domain '"+domainName+"'",messageObject);return;}
this._dispatchers[domainName].dispatch(method[1],messageObject);}},registerDispatcher:function(domain,dispatcher)
{if(!this._dispatchers[domain])
return;this._dispatchers[domain].setDomainDispatcher(dispatcher);},deprecatedRunAfterPendingDispatches:function(script)
{if(!this._scripts)
this._scripts=[];if(script)
this._scripts.push(script);setTimeout(function(){if(!this._pendingResponsesCount)
this._executeAfterPendingDispatches();else
this.deprecatedRunAfterPendingDispatches();}.bind(this),0);},_executeAfterPendingDispatches:function()
{if(!this._pendingResponsesCount){var scripts=this._scripts;this._scripts=[];for(var id=0;id<scripts.length;++id)
scripts[id].call(this);}},_dumpProtocolMessage:function(message)
{console.log(message);},connectionClosed:function(reason)
{this._isConnected=false;this._runPendingCallbacks();this.dispatchEventToListeners(InspectorBackendClass.Connection.Events.Disconnected,{reason:reason});},_runPendingCallbacks:function()
{var keys=Object.keys(this._callbacks).map(function(num){return parseInt(num,10);});for(var i=0;i<keys.length;++i){var callback=this._callbacks[keys[i]];this._dispatchConnectionErrorResponse(callback.domain,callback.methodName,callback);}
this._callbacks={};},_dispatchConnectionErrorResponse:function(domain,methodName,callback)
{var error={message:"Connection is closed, can't dispatch pending "+methodName,code:InspectorBackendClass._DevToolsErrorCode,data:null};var messageObject={error:error};setTimeout(InspectorBackendClass.AgentPrototype.prototype.dispatchResponse.bind(this.agent(domain),messageObject,methodName,callback),0);},isClosed:function()
{return!this._isConnected;},suppressErrorsForDomains:function(domains)
{domains.forEach(function(domain){this._agents[domain].suppressErrorLogging();},this);},__proto__:WebInspector.Object.prototype}
InspectorBackendClass.AgentPrototype=function(domain)
{this._replyArgs={};this._hasErrorData={};this._domain=domain;this._suppressErrorLogging=false;}
InspectorBackendClass.AgentPrototype.prototype={setConnection:function(connection)
{this._connection=connection;},registerCommand:function(methodName,signature,replyArgs,hasErrorData)
{var domainAndMethod=this._domain+"."+methodName;function sendMessagePromise(vararg)
{var params=Array.prototype.slice.call(arguments);return InspectorBackendClass.AgentPrototype.prototype._sendMessageToBackendPromise.call(this,domainAndMethod,signature,params);}
this[methodName]=sendMessagePromise;function invoke(vararg)
{var params=[domainAndMethod].concat(Array.prototype.slice.call(arguments));InspectorBackendClass.AgentPrototype.prototype._invoke.apply(this,params);}
this["invoke_"+methodName]=invoke;this._replyArgs[domainAndMethod]=replyArgs;if(hasErrorData)
this._hasErrorData[domainAndMethod]=true;},_prepareParameters:function(method,signature,args,allowExtraUndefinedArg,errorCallback)
{var params={};var hasParams=false;for(var i=0;i<signature.length;++i){var param=signature[i];var paramName=param["name"];var typeName=param["type"];var optionalFlag=param["optional"];if(!args.length&&!optionalFlag){errorCallback("Protocol Error: Invalid number of arguments for method '"+method+"' call. It must have the following arguments '"+JSON.stringify(signature)+"'.");return null;}
var value=args.shift();if(optionalFlag&&typeof value==="undefined")
continue;if(typeof value!==typeName){errorCallback("Protocol Error: Invalid type of argument '"+paramName+"' for method '"+method+"' call. It must be '"+typeName+"' but it is '"+typeof value+"'.");return null;}
params[paramName]=value;hasParams=true;}
if(args.length===1&&(!allowExtraUndefinedArg||(typeof args[0]!=="undefined"))){errorCallback("Protocol Error: Optional callback argument for method '"+method+"' call must be a function but its type is '"+typeof args[0]+"'.");return null;}
if(args.length>1){errorCallback("Protocol Error: Extra "+args.length+" arguments in a call to method '"+method+"'.");return null;}
return hasParams?params:null},_sendMessageToBackendPromise:function(method,signature,args)
{var errorMessage;function onError(message)
{console.error(message);errorMessage=message;}
var userCallback=(args.length&&typeof args.peekLast()==="function")?args.pop():null;var params=this._prepareParameters(method,signature,args,!userCallback,onError);if(errorMessage)
return Promise.reject(new Error(errorMessage));else
return new Promise(promiseAction.bind(this));function promiseAction(resolve,reject)
{function callback(vararg)
{var result=userCallback?userCallback.apply(null,arguments):undefined;resolve(result);}
this._connection._wrapCallbackAndSendMessageObject(this._domain,method,params,callback);}},_invoke:function(method,args,callback)
{this._connection._wrapCallbackAndSendMessageObject(this._domain,method,args,callback);},dispatchResponse:function(messageObject,methodName,callback)
{if(messageObject.error&&messageObject.error.code!==InspectorBackendClass._DevToolsErrorCode&&messageObject.error.code!==InspectorBackendClass.DevToolsStubErrorCode&&!InspectorBackendClass.Options.suppressRequestErrors&&!this._suppressErrorLogging){var id=InspectorBackendClass.Options.dumpInspectorProtocolMessages?" with id = "+messageObject.id:"";console.error("Request "+methodName+id+" failed. "+JSON.stringify(messageObject.error));}
var argumentsArray=[];argumentsArray[0]=messageObject.error?messageObject.error.message:null;if(this._hasErrorData[methodName])
argumentsArray[1]=messageObject.error?messageObject.error.data:null;if(messageObject.result){var paramNames=this._replyArgs[methodName]||[];for(var i=0;i<paramNames.length;++i)
argumentsArray.push(messageObject.result[paramNames[i]]);}
callback.apply(null,argumentsArray);},suppressErrorLogging:function()
{this._suppressErrorLogging=true;}}
InspectorBackendClass.DispatcherPrototype=function()
{this._eventArgs={};this._dispatcher=null;}
InspectorBackendClass.DispatcherPrototype.prototype={registerEvent:function(eventName,params)
{this._eventArgs[eventName]=params;},setDomainDispatcher:function(dispatcher)
{this._dispatcher=dispatcher;},dispatch:function(functionName,messageObject)
{if(!this._dispatcher)
return;if(!(functionName in this._dispatcher)){InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unimplemented method '"+messageObject.method+"'",messageObject);return;}
if(!this._eventArgs[messageObject.method]){InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unspecified method '"+messageObject.method+"'",messageObject);return;}
var params=[];if(messageObject.params){var paramNames=this._eventArgs[messageObject.method];for(var i=0;i<paramNames.length;++i)
params.push(messageObject.params[paramNames[i]]);}
var processingStartTime;if(InspectorBackendClass.Options.dumpInspectorTimeStats)
processingStartTime=Date.now();this._dispatcher[functionName].apply(this._dispatcher,params);if(InspectorBackendClass.Options.dumpInspectorTimeStats)
console.log("time-stats: "+messageObject.method+" = "+(Date.now()-processingStartTime));}}
InspectorBackendClass.Options={dumpInspectorTimeStats:false,dumpInspectorProtocolMessages:false,suppressRequestErrors:false}
InspectorBackend=new InspectorBackendClass();;InspectorBackend.registerEvent("Inspector.detached",["reason"]);InspectorBackend.registerEvent("Inspector.targetCrashed",[]);InspectorBackend.registerCommand("Inspector.enable",[],[],false);InspectorBackend.registerCommand("Inspector.disable",[],[],false);InspectorBackend.registerEnum("Memory.PressureLevel",{Moderate:"moderate",Critical:"critical"});InspectorBackend.registerCommand("Memory.getDOMCounters",[],["documents","nodes","jsEventListeners"],false);InspectorBackend.registerCommand("Memory.setPressureNotificationsSuppressed",[{"name":"suppressed","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Memory.simulatePressureNotification",[{"name":"level","type":"string","optional":false}],[],false);InspectorBackend.registerEnum("Page.ResourceType",{Document:"Document",Stylesheet:"Stylesheet",Image:"Image",Media:"Media",Font:"Font",Script:"Script",TextTrack:"TextTrack",XHR:"XHR",Fetch:"Fetch",EventSource:"EventSource",WebSocket:"WebSocket",Manifest:"Manifest",Other:"Other"});InspectorBackend.registerEnum("Page.DialogType",{Alert:"alert",Confirm:"confirm",Prompt:"prompt",Beforeunload:"beforeunload"});InspectorBackend.registerEvent("Page.domContentEventFired",["timestamp"]);InspectorBackend.registerEvent("Page.loadEventFired",["timestamp"]);InspectorBackend.registerEvent("Page.frameAttached",["frameId","parentFrameId"]);InspectorBackend.registerEvent("Page.frameNavigated",["frame"]);InspectorBackend.registerEvent("Page.frameDetached",["frameId"]);InspectorBackend.registerEvent("Page.frameStartedLoading",["frameId"]);InspectorBackend.registerEvent("Page.frameStoppedLoading",["frameId"]);InspectorBackend.registerEvent("Page.frameScheduledNavigation",["frameId","delay"]);InspectorBackend.registerEvent("Page.frameClearedScheduledNavigation",["frameId"]);InspectorBackend.registerEvent("Page.frameResized",[]);InspectorBackend.registerEvent("Page.javascriptDialogOpening",["message","type"]);InspectorBackend.registerEvent("Page.javascriptDialogClosed",["result"]);InspectorBackend.registerEvent("Page.screencastFrame",["data","metadata","sessionId"]);InspectorBackend.registerEvent("Page.screencastVisibilityChanged",["visible"]);InspectorBackend.registerEvent("Page.colorPicked",["color"]);InspectorBackend.registerEvent("Page.interstitialShown",[]);InspectorBackend.registerEvent("Page.interstitialHidden",[]);InspectorBackend.registerCommand("Page.enable",[],[],false);InspectorBackend.registerCommand("Page.disable",[],[],false);InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad",[{"name":"scriptSource","type":"string","optional":false}],["identifier"],false);InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad",[{"name":"identifier","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Page.setAutoAttachToCreatedPages",[{"name":"autoAttach","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Page.reload",[{"name":"ignoreCache","type":"boolean","optional":true},{"name":"scriptToEvaluateOnLoad","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Page.navigate",[{"name":"url","type":"string","optional":false}],["frameId"],false);InspectorBackend.registerCommand("Page.getNavigationHistory",[],["currentIndex","entries"],false);InspectorBackend.registerCommand("Page.navigateToHistoryEntry",[{"name":"entryId","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Page.getCookies",[],["cookies"],false);InspectorBackend.registerCommand("Page.deleteCookie",[{"name":"cookieName","type":"string","optional":false},{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Page.getResourceTree",[],["frameTree"],false);InspectorBackend.registerCommand("Page.getResourceContent",[{"name":"frameId","type":"string","optional":false},{"name":"url","type":"string","optional":false}],["content","base64Encoded"],false);InspectorBackend.registerCommand("Page.searchInResource",[{"name":"frameId","type":"string","optional":false},{"name":"url","type":"string","optional":false},{"name":"query","type":"string","optional":false},{"name":"caseSensitive","type":"boolean","optional":true},{"name":"isRegex","type":"boolean","optional":true}],["result"],false);InspectorBackend.registerCommand("Page.setDocumentContent",[{"name":"frameId","type":"string","optional":false},{"name":"html","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Page.setDeviceMetricsOverride",[{"name":"width","type":"number","optional":false},{"name":"height","type":"number","optional":false},{"name":"deviceScaleFactor","type":"number","optional":false},{"name":"mobile","type":"boolean","optional":false},{"name":"fitWindow","type":"boolean","optional":false},{"name":"scale","type":"number","optional":true},{"name":"offsetX","type":"number","optional":true},{"name":"offsetY","type":"number","optional":true},{"name":"screenWidth","type":"number","optional":true},{"name":"screenHeight","type":"number","optional":true},{"name":"positionX","type":"number","optional":true},{"name":"positionY","type":"number","optional":true},{"name":"screenOrientation","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("Page.clearDeviceMetricsOverride",[],[],false);InspectorBackend.registerCommand("Page.setGeolocationOverride",[{"name":"latitude","type":"number","optional":true},{"name":"longitude","type":"number","optional":true},{"name":"accuracy","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Page.clearGeolocationOverride",[],[],false);InspectorBackend.registerCommand("Page.setDeviceOrientationOverride",[{"name":"alpha","type":"number","optional":false},{"name":"beta","type":"number","optional":false},{"name":"gamma","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride",[],[],false);InspectorBackend.registerCommand("Page.setTouchEmulationEnabled",[{"name":"enabled","type":"boolean","optional":false},{"name":"configuration","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Page.captureScreenshot",[],["data"],false);InspectorBackend.registerCommand("Page.startScreencast",[{"name":"format","type":"string","optional":true},{"name":"quality","type":"number","optional":true},{"name":"maxWidth","type":"number","optional":true},{"name":"maxHeight","type":"number","optional":true},{"name":"everyNthFrame","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Page.stopScreencast",[],[],false);InspectorBackend.registerCommand("Page.screencastFrameAck",[{"name":"sessionId","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Page.handleJavaScriptDialog",[{"name":"accept","type":"boolean","optional":false},{"name":"promptText","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Page.setColorPickerEnabled",[{"name":"enabled","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Page.setOverlayMessage",[{"name":"message","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Page.getAppManifest",[],["url","errors","data"],false);InspectorBackend.registerCommand("Page.requestAppBanner",[],[],false);InspectorBackend.registerCommand("Page.setBlockedEventsWarningThreshold",[{"name":"threshold","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Rendering.setShowPaintRects",[{"name":"result","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Rendering.setShowDebugBorders",[{"name":"show","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Rendering.setShowFPSCounter",[{"name":"show","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Rendering.setShowScrollBottleneckRects",[{"name":"show","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Rendering.setShowViewportSizeOnResize",[{"name":"show","type":"boolean","optional":false}],[],false);InspectorBackend.registerEnum("Emulation.ScreenOrientationType",{PortraitPrimary:"portraitPrimary",PortraitSecondary:"portraitSecondary",LandscapePrimary:"landscapePrimary",LandscapeSecondary:"landscapeSecondary"});InspectorBackend.registerCommand("Emulation.setDeviceMetricsOverride",[{"name":"width","type":"number","optional":false},{"name":"height","type":"number","optional":false},{"name":"deviceScaleFactor","type":"number","optional":false},{"name":"mobile","type":"boolean","optional":false},{"name":"fitWindow","type":"boolean","optional":false},{"name":"scale","type":"number","optional":true},{"name":"offsetX","type":"number","optional":true},{"name":"offsetY","type":"number","optional":true},{"name":"screenWidth","type":"number","optional":true},{"name":"screenHeight","type":"number","optional":true},{"name":"positionX","type":"number","optional":true},{"name":"positionY","type":"number","optional":true},{"name":"screenOrientation","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("Emulation.clearDeviceMetricsOverride",[],[],false);InspectorBackend.registerCommand("Emulation.resetPageScaleFactor",[],[],false);InspectorBackend.registerCommand("Emulation.setPageScaleFactor",[{"name":"pageScaleFactor","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Emulation.setScriptExecutionDisabled",[{"name":"value","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Emulation.setGeolocationOverride",[{"name":"latitude","type":"number","optional":true},{"name":"longitude","type":"number","optional":true},{"name":"accuracy","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Emulation.clearGeolocationOverride",[],[],false);InspectorBackend.registerCommand("Emulation.setTouchEmulationEnabled",[{"name":"enabled","type":"boolean","optional":false},{"name":"configuration","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Emulation.setEmulatedMedia",[{"name":"media","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Emulation.setCPUThrottlingRate",[{"name":"rate","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Emulation.canEmulate",[],["result"],false);InspectorBackend.registerEnum("Runtime.RemoteObjectType",{Object:"object",Function:"function",Undefined:"undefined",String:"string",Number:"number",Boolean:"boolean",Symbol:"symbol"});InspectorBackend.registerEnum("Runtime.RemoteObjectSubtype",{Array:"array",Null:"null",Node:"node",Regexp:"regexp",Date:"date",Map:"map",Set:"set",Iterator:"iterator",Generator:"generator",Error:"error"});InspectorBackend.registerEnum("Runtime.ObjectPreviewType",{Object:"object",Function:"function",Undefined:"undefined",String:"string",Number:"number",Boolean:"boolean",Symbol:"symbol"});InspectorBackend.registerEnum("Runtime.ObjectPreviewSubtype",{Array:"array",Null:"null",Node:"node",Regexp:"regexp",Date:"date",Map:"map",Set:"set",Iterator:"iterator",Generator:"generator",Error:"error"});InspectorBackend.registerEnum("Runtime.PropertyPreviewType",{Object:"object",Function:"function",Undefined:"undefined",String:"string",Number:"number",Boolean:"boolean",Symbol:"symbol",Accessor:"accessor"});InspectorBackend.registerEnum("Runtime.PropertyPreviewSubtype",{Array:"array",Null:"null",Node:"node",Regexp:"regexp",Date:"date",Map:"map",Set:"set",Iterator:"iterator",Generator:"generator",Error:"error"});InspectorBackend.registerEnum("Runtime.CallArgumentType",{Object:"object",Function:"function",Undefined:"undefined",String:"string",Number:"number",Boolean:"boolean",Symbol:"symbol"});InspectorBackend.registerEvent("Runtime.executionContextCreated",["context"]);InspectorBackend.registerEvent("Runtime.executionContextDestroyed",["executionContextId"]);InspectorBackend.registerEvent("Runtime.executionContextsCleared",[]);InspectorBackend.registerEvent("Runtime.inspectRequested",["object","hints"]);InspectorBackend.registerCommand("Runtime.evaluate",[{"name":"expression","type":"string","optional":false},{"name":"objectGroup","type":"string","optional":true},{"name":"includeCommandLineAPI","type":"boolean","optional":true},{"name":"doNotPauseOnExceptionsAndMuteConsole","type":"boolean","optional":true},{"name":"contextId","type":"number","optional":true},{"name":"returnByValue","type":"boolean","optional":true},{"name":"generatePreview","type":"boolean","optional":true},{"name":"userGesture","type":"boolean","optional":true}],["result","wasThrown","exceptionDetails"],false);InspectorBackend.registerCommand("Runtime.callFunctionOn",[{"name":"objectId","type":"string","optional":false},{"name":"functionDeclaration","type":"string","optional":false},{"name":"arguments","type":"object","optional":true},{"name":"doNotPauseOnExceptionsAndMuteConsole","type":"boolean","optional":true},{"name":"returnByValue","type":"boolean","optional":true},{"name":"generatePreview","type":"boolean","optional":true},{"name":"userGesture","type":"boolean","optional":true}],["result","wasThrown"],false);InspectorBackend.registerCommand("Runtime.getProperties",[{"name":"objectId","type":"string","optional":false},{"name":"ownProperties","type":"boolean","optional":true},{"name":"accessorPropertiesOnly","type":"boolean","optional":true},{"name":"generatePreview","type":"boolean","optional":true}],["result","internalProperties","exceptionDetails"],false);InspectorBackend.registerCommand("Runtime.releaseObject",[{"name":"objectId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Runtime.releaseObjectGroup",[{"name":"objectGroup","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Runtime.run",[],[],false);InspectorBackend.registerCommand("Runtime.enable",[],[],false);InspectorBackend.registerCommand("Runtime.disable",[],[],false);InspectorBackend.registerCommand("Runtime.setCustomObjectFormatterEnabled",[{"name":"enabled","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Runtime.compileScript",[{"name":"expression","type":"string","optional":false},{"name":"sourceURL","type":"string","optional":false},{"name":"persistScript","type":"boolean","optional":false},{"name":"executionContextId","type":"number","optional":false}],["scriptId","exceptionDetails"],false);InspectorBackend.registerCommand("Runtime.runScript",[{"name":"scriptId","type":"string","optional":false},{"name":"executionContextId","type":"number","optional":false},{"name":"objectGroup","type":"string","optional":true},{"name":"doNotPauseOnExceptionsAndMuteConsole","type":"boolean","optional":true},{"name":"includeCommandLineAPI","type":"boolean","optional":true}],["result","exceptionDetails"],false);InspectorBackend.registerEnum("Console.ConsoleMessageSource",{XML:"xml",Javascript:"javascript",Network:"network",ConsoleAPI:"console-api",Storage:"storage",Appcache:"appcache",Rendering:"rendering",Security:"security",Other:"other",Deprecation:"deprecation"});InspectorBackend.registerEnum("Console.ConsoleMessageLevel",{Log:"log",Warning:"warning",Error:"error",Debug:"debug",Info:"info",RevokedError:"revokedError"});InspectorBackend.registerEnum("Console.ConsoleMessageType",{Log:"log",Dir:"dir",DirXML:"dirxml",Table:"table",Trace:"trace",Clear:"clear",StartGroup:"startGroup",StartGroupCollapsed:"startGroupCollapsed",EndGroup:"endGroup",Assert:"assert",Profile:"profile",ProfileEnd:"profileEnd"});InspectorBackend.registerEvent("Console.messageAdded",["message"]);InspectorBackend.registerEvent("Console.messageRepeatCountUpdated",["count","timestamp"]);InspectorBackend.registerEvent("Console.messagesCleared",[]);InspectorBackend.registerCommand("Console.enable",[],[],false);InspectorBackend.registerCommand("Console.disable",[],[],false);InspectorBackend.registerCommand("Console.clearMessages",[],[],false);InspectorBackend.registerEnum("Security.SecurityState",{Unknown:"unknown",Neutral:"neutral",Insecure:"insecure",Warning:"warning",Secure:"secure",Info:"info"});InspectorBackend.registerEvent("Security.securityStateChanged",["securityState","explanations","mixedContentStatus","schemeIsCryptographic"]);InspectorBackend.registerCommand("Security.enable",[],[],false);InspectorBackend.registerCommand("Security.disable",[],[],false);InspectorBackend.registerEnum("Network.ResourcePriority",{VeryLow:"VeryLow",Low:"Low",Medium:"Medium",High:"High",VeryHigh:"VeryHigh"});InspectorBackend.registerEnum("Network.RequestMixedContentType",{Blockable:"blockable",OptionallyBlockable:"optionally-blockable",None:"none"});InspectorBackend.registerEnum("Network.BlockedReason",{Csp:"csp",MixedContent:"mixed-content",Origin:"origin",Inspector:"inspector",Other:"other"});InspectorBackend.registerEnum("Network.InitiatorType",{Parser:"parser",Script:"script",Other:"other"});InspectorBackend.registerEnum("Network.CookieSameSite",{Strict:"Strict",Lax:"Lax"});InspectorBackend.registerEvent("Network.resourceChangedPriority",["requestId","newPriority","timestamp"]);InspectorBackend.registerEvent("Network.requestWillBeSent",["requestId","frameId","loaderId","documentURL","request","timestamp","wallTime","initiator","redirectResponse","type"]);InspectorBackend.registerEvent("Network.requestServedFromCache",["requestId"]);InspectorBackend.registerEvent("Network.responseReceived",["requestId","frameId","loaderId","timestamp","type","response"]);InspectorBackend.registerEvent("Network.dataReceived",["requestId","timestamp","dataLength","encodedDataLength"]);InspectorBackend.registerEvent("Network.loadingFinished",["requestId","timestamp","encodedDataLength"]);InspectorBackend.registerEvent("Network.loadingFailed",["requestId","timestamp","type","errorText","canceled","blockedReason"]);InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest",["requestId","timestamp","wallTime","request"]);InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived",["requestId","timestamp","response"]);InspectorBackend.registerEvent("Network.webSocketCreated",["requestId","url"]);InspectorBackend.registerEvent("Network.webSocketClosed",["requestId","timestamp"]);InspectorBackend.registerEvent("Network.webSocketFrameReceived",["requestId","timestamp","response"]);InspectorBackend.registerEvent("Network.webSocketFrameError",["requestId","timestamp","errorMessage"]);InspectorBackend.registerEvent("Network.webSocketFrameSent",["requestId","timestamp","response"]);InspectorBackend.registerEvent("Network.eventSourceMessageReceived",["requestId","timestamp","eventName","eventId","data"]);InspectorBackend.registerCommand("Network.enable",[{"name":"maxTotalBufferSize","type":"number","optional":true},{"name":"maxResourceBufferSize","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Network.disable",[],[],false);InspectorBackend.registerCommand("Network.setUserAgentOverride",[{"name":"userAgent","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Network.setExtraHTTPHeaders",[{"name":"headers","type":"object","optional":false}],[],false);InspectorBackend.registerCommand("Network.getResponseBody",[{"name":"requestId","type":"string","optional":false}],["body","base64Encoded"],false);InspectorBackend.registerCommand("Network.addBlockedURL",[{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Network.removeBlockedURL",[{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Network.replayXHR",[{"name":"requestId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Network.setMonitoringXHREnabled",[{"name":"enabled","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Network.canClearBrowserCache",[],["result"],false);InspectorBackend.registerCommand("Network.clearBrowserCache",[],[],false);InspectorBackend.registerCommand("Network.canClearBrowserCookies",[],["result"],false);InspectorBackend.registerCommand("Network.clearBrowserCookies",[],[],false);InspectorBackend.registerCommand("Network.getCookies",[],["cookies"],false);InspectorBackend.registerCommand("Network.deleteCookie",[{"name":"cookieName","type":"string","optional":false},{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Network.canEmulateNetworkConditions",[],["result"],false);InspectorBackend.registerCommand("Network.emulateNetworkConditions",[{"name":"offline","type":"boolean","optional":false},{"name":"latency","type":"number","optional":false},{"name":"downloadThroughput","type":"number","optional":false},{"name":"uploadThroughput","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Network.setCacheDisabled",[{"name":"cacheDisabled","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Network.setBypassServiceWorker",[{"name":"bypass","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Network.setDataSizeLimitsForTest",[{"name":"maxTotalSize","type":"number","optional":false},{"name":"maxResourceSize","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Network.getCertificateDetails",[{"name":"certificateId","type":"number","optional":false}],["result"],false);InspectorBackend.registerCommand("Network.showCertificateViewer",[{"name":"certificateId","type":"number","optional":false}],[],false);InspectorBackend.registerEvent("Database.addDatabase",["database"]);InspectorBackend.registerCommand("Database.enable",[],[],false);InspectorBackend.registerCommand("Database.disable",[],[],false);InspectorBackend.registerCommand("Database.getDatabaseTableNames",[{"name":"databaseId","type":"string","optional":false}],["tableNames"],false);InspectorBackend.registerCommand("Database.executeSQL",[{"name":"databaseId","type":"string","optional":false},{"name":"query","type":"string","optional":false}],["columnNames","values","sqlError"],false);InspectorBackend.registerEnum("IndexedDB.KeyType",{Number:"number",String:"string",Date:"date",Array:"array"});InspectorBackend.registerEnum("IndexedDB.KeyPathType",{Null:"null",String:"string",Array:"array"});InspectorBackend.registerCommand("IndexedDB.enable",[],[],false);InspectorBackend.registerCommand("IndexedDB.disable",[],[],false);InspectorBackend.registerCommand("IndexedDB.requestDatabaseNames",[{"name":"securityOrigin","type":"string","optional":false}],["databaseNames"],false);InspectorBackend.registerCommand("IndexedDB.requestDatabase",[{"name":"securityOrigin","type":"string","optional":false},{"name":"databaseName","type":"string","optional":false}],["databaseWithObjectStores"],false);InspectorBackend.registerCommand("IndexedDB.requestData",[{"name":"securityOrigin","type":"string","optional":false},{"name":"databaseName","type":"string","optional":false},{"name":"objectStoreName","type":"string","optional":false},{"name":"indexName","type":"string","optional":false},{"name":"skipCount","type":"number","optional":false},{"name":"pageSize","type":"number","optional":false},{"name":"keyRange","type":"object","optional":true}],["objectStoreDataEntries","hasMore"],false);InspectorBackend.registerCommand("IndexedDB.clearObjectStore",[{"name":"securityOrigin","type":"string","optional":false},{"name":"databaseName","type":"string","optional":false},{"name":"objectStoreName","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("CacheStorage.requestCacheNames",[{"name":"securityOrigin","type":"string","optional":false}],["caches"],false);InspectorBackend.registerCommand("CacheStorage.requestEntries",[{"name":"cacheId","type":"string","optional":false},{"name":"skipCount","type":"number","optional":false},{"name":"pageSize","type":"number","optional":false}],["cacheDataEntries","hasMore"],false);InspectorBackend.registerCommand("CacheStorage.deleteCache",[{"name":"cacheId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("CacheStorage.deleteEntry",[{"name":"cacheId","type":"string","optional":false},{"name":"request","type":"string","optional":false}],[],false);InspectorBackend.registerEvent("DOMStorage.domStorageItemsCleared",["storageId"]);InspectorBackend.registerEvent("DOMStorage.domStorageItemRemoved",["storageId","key"]);InspectorBackend.registerEvent("DOMStorage.domStorageItemAdded",["storageId","key","newValue"]);InspectorBackend.registerEvent("DOMStorage.domStorageItemUpdated",["storageId","key","oldValue","newValue"]);InspectorBackend.registerCommand("DOMStorage.enable",[],[],false);InspectorBackend.registerCommand("DOMStorage.disable",[],[],false);InspectorBackend.registerCommand("DOMStorage.getDOMStorageItems",[{"name":"storageId","type":"object","optional":false}],["entries"],false);InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem",[{"name":"storageId","type":"object","optional":false},{"name":"key","type":"string","optional":false},{"name":"value","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem",[{"name":"storageId","type":"object","optional":false},{"name":"key","type":"string","optional":false}],[],false);InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated",["frameId","manifestURL","status"]);InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated",["isNowOnline"]);InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests",[],["frameIds"],false);InspectorBackend.registerCommand("ApplicationCache.enable",[],[],false);InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame",[{"name":"frameId","type":"string","optional":false}],["manifestURL"],false);InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame",[{"name":"frameId","type":"string","optional":false}],["applicationCache"],false);InspectorBackend.registerEnum("DOM.PseudoType",{FirstLine:"first-line",FirstLetter:"first-letter",Before:"before",After:"after",Backdrop:"backdrop",Selection:"selection",FirstLineInherited:"first-line-inherited",Scrollbar:"scrollbar",ScrollbarThumb:"scrollbar-thumb",ScrollbarButton:"scrollbar-button",ScrollbarTrack:"scrollbar-track",ScrollbarTrackPiece:"scrollbar-track-piece",ScrollbarCorner:"scrollbar-corner",Resizer:"resizer",InputListButton:"input-list-button"});InspectorBackend.registerEnum("DOM.ShadowRootType",{UserAgent:"user-agent",Open:"open",Closed:"closed"});InspectorBackend.registerEnum("DOM.InspectMode",{SearchForNode:"searchForNode",SearchForUAShadowDOM:"searchForUAShadowDOM",ShowLayoutEditor:"showLayoutEditor",None:"none"});InspectorBackend.registerEvent("DOM.documentUpdated",[]);InspectorBackend.registerEvent("DOM.inspectNodeRequested",["backendNodeId"]);InspectorBackend.registerEvent("DOM.setChildNodes",["parentId","nodes"]);InspectorBackend.registerEvent("DOM.attributeModified",["nodeId","name","value"]);InspectorBackend.registerEvent("DOM.attributeRemoved",["nodeId","name"]);InspectorBackend.registerEvent("DOM.inlineStyleInvalidated",["nodeIds"]);InspectorBackend.registerEvent("DOM.characterDataModified",["nodeId","characterData"]);InspectorBackend.registerEvent("DOM.childNodeCountUpdated",["nodeId","childNodeCount"]);InspectorBackend.registerEvent("DOM.childNodeInserted",["parentNodeId","previousNodeId","node"]);InspectorBackend.registerEvent("DOM.childNodeRemoved",["parentNodeId","nodeId"]);InspectorBackend.registerEvent("DOM.shadowRootPushed",["hostId","root"]);InspectorBackend.registerEvent("DOM.shadowRootPopped",["hostId","rootId"]);InspectorBackend.registerEvent("DOM.pseudoElementAdded",["parentId","pseudoElement"]);InspectorBackend.registerEvent("DOM.pseudoElementRemoved",["parentId","pseudoElementId"]);InspectorBackend.registerEvent("DOM.distributedNodesUpdated",["insertionPointId","distributedNodes"]);InspectorBackend.registerEvent("DOM.nodeHighlightRequested",["nodeId"]);InspectorBackend.registerCommand("DOM.enable",[],[],false);InspectorBackend.registerCommand("DOM.disable",[],[],false);InspectorBackend.registerCommand("DOM.getDocument",[],["root"],false);InspectorBackend.registerCommand("DOM.requestChildNodes",[{"name":"nodeId","type":"number","optional":false},{"name":"depth","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("DOM.querySelector",[{"name":"nodeId","type":"number","optional":false},{"name":"selector","type":"string","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.querySelectorAll",[{"name":"nodeId","type":"number","optional":false},{"name":"selector","type":"string","optional":false}],["nodeIds"],false);InspectorBackend.registerCommand("DOM.setNodeName",[{"name":"nodeId","type":"number","optional":false},{"name":"name","type":"string","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.setNodeValue",[{"name":"nodeId","type":"number","optional":false},{"name":"value","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOM.removeNode",[{"name":"nodeId","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("DOM.setAttributeValue",[{"name":"nodeId","type":"number","optional":false},{"name":"name","type":"string","optional":false},{"name":"value","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOM.setAttributesAsText",[{"name":"nodeId","type":"number","optional":false},{"name":"text","type":"string","optional":false},{"name":"name","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("DOM.removeAttribute",[{"name":"nodeId","type":"number","optional":false},{"name":"name","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOM.getOuterHTML",[{"name":"nodeId","type":"number","optional":false}],["outerHTML"],false);InspectorBackend.registerCommand("DOM.setOuterHTML",[{"name":"nodeId","type":"number","optional":false},{"name":"outerHTML","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOM.performSearch",[{"name":"query","type":"string","optional":false},{"name":"includeUserAgentShadowDOM","type":"boolean","optional":true}],["searchId","resultCount"],false);InspectorBackend.registerCommand("DOM.getSearchResults",[{"name":"searchId","type":"string","optional":false},{"name":"fromIndex","type":"number","optional":false},{"name":"toIndex","type":"number","optional":false}],["nodeIds"],false);InspectorBackend.registerCommand("DOM.discardSearchResults",[{"name":"searchId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOM.requestNode",[{"name":"objectId","type":"string","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.setInspectMode",[{"name":"mode","type":"string","optional":false},{"name":"highlightConfig","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("DOM.highlightRect",[{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"width","type":"number","optional":false},{"name":"height","type":"number","optional":false},{"name":"color","type":"object","optional":true},{"name":"outlineColor","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("DOM.highlightQuad",[{"name":"quad","type":"object","optional":false},{"name":"color","type":"object","optional":true},{"name":"outlineColor","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("DOM.highlightNode",[{"name":"highlightConfig","type":"object","optional":false},{"name":"nodeId","type":"number","optional":true},{"name":"backendNodeId","type":"number","optional":true},{"name":"objectId","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("DOM.hideHighlight",[],[],false);InspectorBackend.registerCommand("DOM.highlightFrame",[{"name":"frameId","type":"string","optional":false},{"name":"contentColor","type":"object","optional":true},{"name":"contentOutlineColor","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend",[{"name":"path","type":"string","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.pushNodesByBackendIdsToFrontend",[{"name":"backendNodeIds","type":"object","optional":false}],["nodeIds"],false);InspectorBackend.registerCommand("DOM.setInspectedNode",[{"name":"nodeId","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("DOM.resolveNode",[{"name":"nodeId","type":"number","optional":false},{"name":"objectGroup","type":"string","optional":true}],["object"],false);InspectorBackend.registerCommand("DOM.getAttributes",[{"name":"nodeId","type":"number","optional":false}],["attributes"],false);InspectorBackend.registerCommand("DOM.copyTo",[{"name":"nodeId","type":"number","optional":false},{"name":"targetNodeId","type":"number","optional":false},{"name":"insertBeforeNodeId","type":"number","optional":true}],["nodeId"],false);InspectorBackend.registerCommand("DOM.moveTo",[{"name":"nodeId","type":"number","optional":false},{"name":"targetNodeId","type":"number","optional":false},{"name":"insertBeforeNodeId","type":"number","optional":true}],["nodeId"],false);InspectorBackend.registerCommand("DOM.undo",[],[],false);InspectorBackend.registerCommand("DOM.redo",[],[],false);InspectorBackend.registerCommand("DOM.markUndoableState",[],[],false);InspectorBackend.registerCommand("DOM.focus",[{"name":"nodeId","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("DOM.setFileInputFiles",[{"name":"nodeId","type":"number","optional":false},{"name":"files","type":"object","optional":false}],[],false);InspectorBackend.registerCommand("DOM.getBoxModel",[{"name":"nodeId","type":"number","optional":false}],["model"],false);InspectorBackend.registerCommand("DOM.getNodeForLocation",[{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.getRelayoutBoundary",[{"name":"nodeId","type":"number","optional":false}],["nodeId"],false);InspectorBackend.registerCommand("DOM.getHighlightObjectForTest",[{"name":"nodeId","type":"number","optional":false}],["highlight"],false);InspectorBackend.registerEnum("CSS.StyleSheetOrigin",{Injected:"injected",UserAgent:"user-agent",Inspector:"inspector",Regular:"regular"});InspectorBackend.registerEnum("CSS.CSSMediaSource",{MediaRule:"mediaRule",ImportRule:"importRule",LinkedSheet:"linkedSheet",InlineSheet:"inlineSheet"});InspectorBackend.registerEvent("CSS.mediaQueryResultChanged",[]);InspectorBackend.registerEvent("CSS.styleSheetChanged",["styleSheetId"]);InspectorBackend.registerEvent("CSS.styleSheetAdded",["header"]);InspectorBackend.registerEvent("CSS.styleSheetRemoved",["styleSheetId"]);InspectorBackend.registerEvent("CSS.layoutEditorChange",["styleSheetId","changeRange"]);InspectorBackend.registerCommand("CSS.enable",[],[],false);InspectorBackend.registerCommand("CSS.disable",[],[],false);InspectorBackend.registerCommand("CSS.getMatchedStylesForNode",[{"name":"nodeId","type":"number","optional":false}],["inlineStyle","attributesStyle","matchedCSSRules","pseudoElements","inherited","cssKeyframesRules"],false);InspectorBackend.registerCommand("CSS.getInlineStylesForNode",[{"name":"nodeId","type":"number","optional":false}],["inlineStyle","attributesStyle"],false);InspectorBackend.registerCommand("CSS.getComputedStyleForNode",[{"name":"nodeId","type":"number","optional":false}],["computedStyle"],false);InspectorBackend.registerCommand("CSS.getPlatformFontsForNode",[{"name":"nodeId","type":"number","optional":false}],["fonts"],false);InspectorBackend.registerCommand("CSS.getStyleSheetText",[{"name":"styleSheetId","type":"string","optional":false}],["text"],false);InspectorBackend.registerCommand("CSS.setStyleSheetText",[{"name":"styleSheetId","type":"string","optional":false},{"name":"text","type":"string","optional":false}],["sourceMapURL"],false);InspectorBackend.registerCommand("CSS.setRuleSelector",[{"name":"styleSheetId","type":"string","optional":false},{"name":"range","type":"object","optional":false},{"name":"selector","type":"string","optional":false}],["selectorList"],false);InspectorBackend.registerCommand("CSS.setKeyframeKey",[{"name":"styleSheetId","type":"string","optional":false},{"name":"range","type":"object","optional":false},{"name":"keyText","type":"string","optional":false}],["keyText"],false);InspectorBackend.registerCommand("CSS.setStyleTexts",[{"name":"edits","type":"object","optional":false}],["styles"],false);InspectorBackend.registerCommand("CSS.setMediaText",[{"name":"styleSheetId","type":"string","optional":false},{"name":"range","type":"object","optional":false},{"name":"text","type":"string","optional":false}],["media"],false);InspectorBackend.registerCommand("CSS.createStyleSheet",[{"name":"frameId","type":"string","optional":false}],["styleSheetId"],false);InspectorBackend.registerCommand("CSS.addRule",[{"name":"styleSheetId","type":"string","optional":false},{"name":"ruleText","type":"string","optional":false},{"name":"location","type":"object","optional":false}],["rule"],false);InspectorBackend.registerCommand("CSS.forcePseudoState",[{"name":"nodeId","type":"number","optional":false},{"name":"forcedPseudoClasses","type":"object","optional":false}],[],false);InspectorBackend.registerCommand("CSS.getMediaQueries",[],["medias"],false);InspectorBackend.registerCommand("CSS.setEffectivePropertyValueForNode",[{"name":"nodeId","type":"number","optional":false},{"name":"propertyName","type":"string","optional":false},{"name":"value","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("CSS.getBackgroundColors",[{"name":"nodeId","type":"number","optional":false}],["backgroundColors"],false);InspectorBackend.registerCommand("IO.read",[{"name":"handle","type":"string","optional":false},{"name":"offset","type":"number","optional":true},{"name":"size","type":"number","optional":true}],["data","eof"],false);InspectorBackend.registerCommand("IO.close",[{"name":"handle","type":"string","optional":false}],[],false);InspectorBackend.registerEnum("Debugger.GeneratorObjectDetailsStatus",{Running:"running",Suspended:"suspended",Closed:"closed"});InspectorBackend.registerEnum("Debugger.ScopeType",{Global:"global",Local:"local",With:"with",Closure:"closure",Catch:"catch",Block:"block",Script:"script"});InspectorBackend.registerEvent("Debugger.scriptParsed",["scriptId","url","startLine","startColumn","endLine","endColumn","executionContextId","hash","isContentScript","isInternalScript","isLiveEdit","sourceMapURL","hasSourceURL","deprecatedCommentWasUsed"]);InspectorBackend.registerEvent("Debugger.scriptFailedToParse",["scriptId","url","startLine","startColumn","endLine","endColumn","executionContextId","hash","isContentScript","isInternalScript","sourceMapURL","hasSourceURL","deprecatedCommentWasUsed"]);InspectorBackend.registerEvent("Debugger.breakpointResolved",["breakpointId","location"]);InspectorBackend.registerEvent("Debugger.paused",["callFrames","reason","data","hitBreakpoints","asyncStackTrace"]);InspectorBackend.registerEvent("Debugger.resumed",[]);InspectorBackend.registerCommand("Debugger.enable",[],[],false);InspectorBackend.registerCommand("Debugger.disable",[],[],false);InspectorBackend.registerCommand("Debugger.setBreakpointsActive",[{"name":"active","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.setSkipAllPauses",[{"name":"skipped","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.setBreakpointByUrl",[{"name":"lineNumber","type":"number","optional":false},{"name":"url","type":"string","optional":true},{"name":"urlRegex","type":"string","optional":true},{"name":"columnNumber","type":"number","optional":true},{"name":"condition","type":"string","optional":true}],["breakpointId","locations"],false);InspectorBackend.registerCommand("Debugger.setBreakpoint",[{"name":"location","type":"object","optional":false},{"name":"condition","type":"string","optional":true}],["breakpointId","actualLocation"],false);InspectorBackend.registerCommand("Debugger.removeBreakpoint",[{"name":"breakpointId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.continueToLocation",[{"name":"location","type":"object","optional":false},{"name":"interstatementLocation","type":"boolean","optional":true}],[],false);InspectorBackend.registerCommand("Debugger.stepOver",[],[],false);InspectorBackend.registerCommand("Debugger.stepInto",[],[],false);InspectorBackend.registerCommand("Debugger.stepOut",[],[],false);InspectorBackend.registerCommand("Debugger.pause",[],[],false);InspectorBackend.registerCommand("Debugger.resume",[],[],false);InspectorBackend.registerCommand("Debugger.searchInContent",[{"name":"scriptId","type":"string","optional":false},{"name":"query","type":"string","optional":false},{"name":"caseSensitive","type":"boolean","optional":true},{"name":"isRegex","type":"boolean","optional":true}],["result"],false);InspectorBackend.registerCommand("Debugger.canSetScriptSource",[],["result"],false);InspectorBackend.registerCommand("Debugger.setScriptSource",[{"name":"scriptId","type":"string","optional":false},{"name":"scriptSource","type":"string","optional":false},{"name":"preview","type":"boolean","optional":true}],["callFrames","stackChanged","asyncStackTrace","compileError"],false);InspectorBackend.registerCommand("Debugger.restartFrame",[{"name":"callFrameId","type":"string","optional":false}],["callFrames","asyncStackTrace"],false);InspectorBackend.registerCommand("Debugger.getScriptSource",[{"name":"scriptId","type":"string","optional":false}],["scriptSource"],false);InspectorBackend.registerCommand("Debugger.getFunctionDetails",[{"name":"functionId","type":"string","optional":false}],["details"],false);InspectorBackend.registerCommand("Debugger.getGeneratorObjectDetails",[{"name":"objectId","type":"string","optional":false}],["details"],false);InspectorBackend.registerCommand("Debugger.getCollectionEntries",[{"name":"objectId","type":"string","optional":false}],["entries"],false);InspectorBackend.registerCommand("Debugger.setPauseOnExceptions",[{"name":"state","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame",[{"name":"callFrameId","type":"string","optional":false},{"name":"expression","type":"string","optional":false},{"name":"objectGroup","type":"string","optional":true},{"name":"includeCommandLineAPI","type":"boolean","optional":true},{"name":"doNotPauseOnExceptionsAndMuteConsole","type":"boolean","optional":true},{"name":"returnByValue","type":"boolean","optional":true},{"name":"generatePreview","type":"boolean","optional":true}],["result","wasThrown","exceptionDetails"],false);InspectorBackend.registerCommand("Debugger.setVariableValue",[{"name":"scopeNumber","type":"number","optional":false},{"name":"variableName","type":"string","optional":false},{"name":"newValue","type":"object","optional":false},{"name":"callFrameId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.getBacktrace",[],["callFrames","asyncStackTrace"],false);InspectorBackend.registerCommand("Debugger.setAsyncCallStackDepth",[{"name":"maxDepth","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.setBlackboxPatterns",[{"name":"patterns","type":"object","optional":false}],[],false);InspectorBackend.registerCommand("Debugger.setBlackboxedRanges",[{"name":"scriptId","type":"string","optional":false},{"name":"positions","type":"object","optional":false}],[],false);InspectorBackend.registerEnum("DOMDebugger.DOMBreakpointType",{SubtreeModified:"subtree-modified",AttributeModified:"attribute-modified",NodeRemoved:"node-removed"});InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint",[{"name":"nodeId","type":"number","optional":false},{"name":"type","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint",[{"name":"nodeId","type":"number","optional":false},{"name":"type","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint",[{"name":"eventName","type":"string","optional":false},{"name":"targetName","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint",[{"name":"eventName","type":"string","optional":false},{"name":"targetName","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint",[{"name":"eventName","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint",[{"name":"eventName","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint",[{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint",[{"name":"url","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("DOMDebugger.getEventListeners",[{"name":"objectId","type":"string","optional":false}],["listeners"],false);InspectorBackend.registerEvent("Profiler.consoleProfileStarted",["id","location","title"]);InspectorBackend.registerEvent("Profiler.consoleProfileFinished",["id","location","profile","title"]);InspectorBackend.registerCommand("Profiler.enable",[],[],false);InspectorBackend.registerCommand("Profiler.disable",[],[],false);InspectorBackend.registerCommand("Profiler.setSamplingInterval",[{"name":"interval","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Profiler.start",[],[],false);InspectorBackend.registerCommand("Profiler.stop",[],["profile"],false);InspectorBackend.registerEvent("HeapProfiler.addHeapSnapshotChunk",["chunk"]);InspectorBackend.registerEvent("HeapProfiler.resetProfiles",[]);InspectorBackend.registerEvent("HeapProfiler.reportHeapSnapshotProgress",["done","total","finished"]);InspectorBackend.registerEvent("HeapProfiler.lastSeenObjectId",["lastSeenObjectId","timestamp"]);InspectorBackend.registerEvent("HeapProfiler.heapStatsUpdate",["statsUpdate"]);InspectorBackend.registerCommand("HeapProfiler.enable",[],[],false);InspectorBackend.registerCommand("HeapProfiler.disable",[],[],false);InspectorBackend.registerCommand("HeapProfiler.startTrackingHeapObjects",[{"name":"trackAllocations","type":"boolean","optional":true}],[],false);InspectorBackend.registerCommand("HeapProfiler.stopTrackingHeapObjects",[{"name":"reportProgress","type":"boolean","optional":true}],[],false);InspectorBackend.registerCommand("HeapProfiler.takeHeapSnapshot",[{"name":"reportProgress","type":"boolean","optional":true}],[],false);InspectorBackend.registerCommand("HeapProfiler.collectGarbage",[],[],false);InspectorBackend.registerCommand("HeapProfiler.getObjectByHeapObjectId",[{"name":"objectId","type":"string","optional":false},{"name":"objectGroup","type":"string","optional":true}],["result"],false);InspectorBackend.registerCommand("HeapProfiler.addInspectedHeapObject",[{"name":"heapObjectId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("HeapProfiler.getHeapObjectId",[{"name":"objectId","type":"string","optional":false}],["heapSnapshotObjectId"],false);InspectorBackend.registerCommand("HeapProfiler.startSampling",[{"name":"samplingInterval","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("HeapProfiler.stopSampling",[],["profile"],false);InspectorBackend.registerEvent("Worker.workerCreated",["workerId","url","waitingForDebugger"]);InspectorBackend.registerEvent("Worker.workerTerminated",["workerId"]);InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker",["workerId","message"]);InspectorBackend.registerCommand("Worker.enable",[],[],false);InspectorBackend.registerCommand("Worker.disable",[],[],false);InspectorBackend.registerCommand("Worker.sendMessageToWorker",[{"name":"workerId","type":"string","optional":false},{"name":"message","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("Worker.setWaitForDebuggerOnStart",[{"name":"value","type":"boolean","optional":false}],[],false);InspectorBackend.registerEnum("ServiceWorker.ServiceWorkerVersionRunningStatus",{Stopped:"stopped",Starting:"starting",Running:"running",Stopping:"stopping"});InspectorBackend.registerEnum("ServiceWorker.ServiceWorkerVersionStatus",{New:"new",Installing:"installing",Installed:"installed",Activating:"activating",Activated:"activated",Redundant:"redundant"});InspectorBackend.registerEvent("ServiceWorker.workerCreated",["workerId","url","versionId"]);InspectorBackend.registerEvent("ServiceWorker.workerTerminated",["workerId"]);InspectorBackend.registerEvent("ServiceWorker.dispatchMessage",["workerId","message"]);InspectorBackend.registerEvent("ServiceWorker.workerRegistrationUpdated",["registrations"]);InspectorBackend.registerEvent("ServiceWorker.workerVersionUpdated",["versions"]);InspectorBackend.registerEvent("ServiceWorker.workerErrorReported",["errorMessage"]);InspectorBackend.registerCommand("ServiceWorker.enable",[],[],false);InspectorBackend.registerCommand("ServiceWorker.disable",[],[],false);InspectorBackend.registerCommand("ServiceWorker.sendMessage",[{"name":"workerId","type":"string","optional":false},{"name":"message","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.stop",[{"name":"workerId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.unregister",[{"name":"scopeURL","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.updateRegistration",[{"name":"scopeURL","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.startWorker",[{"name":"scopeURL","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.skipWaiting",[{"name":"scopeURL","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.stopWorker",[{"name":"versionId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.inspectWorker",[{"name":"versionId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.setForceUpdateOnPageLoad",[{"name":"forceUpdateOnPageLoad","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.deliverPushMessage",[{"name":"origin","type":"string","optional":false},{"name":"registrationId","type":"string","optional":false},{"name":"data","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("ServiceWorker.getTargetInfo",[{"name":"targetId","type":"string","optional":false}],["targetInfo"],false);InspectorBackend.registerCommand("ServiceWorker.activateTarget",[{"name":"targetId","type":"string","optional":false}],[],false);InspectorBackend.registerEnum("Input.TouchPointState",{TouchPressed:"touchPressed",TouchReleased:"touchReleased",TouchMoved:"touchMoved",TouchStationary:"touchStationary",TouchCancelled:"touchCancelled"});InspectorBackend.registerEnum("Input.GestureSourceType",{Default:"default",Touch:"touch",Mouse:"mouse"});InspectorBackend.registerCommand("Input.dispatchKeyEvent",[{"name":"type","type":"string","optional":false},{"name":"modifiers","type":"number","optional":true},{"name":"timestamp","type":"number","optional":true},{"name":"text","type":"string","optional":true},{"name":"unmodifiedText","type":"string","optional":true},{"name":"keyIdentifier","type":"string","optional":true},{"name":"code","type":"string","optional":true},{"name":"key","type":"string","optional":true},{"name":"windowsVirtualKeyCode","type":"number","optional":true},{"name":"nativeVirtualKeyCode","type":"number","optional":true},{"name":"autoRepeat","type":"boolean","optional":true},{"name":"isKeypad","type":"boolean","optional":true},{"name":"isSystemKey","type":"boolean","optional":true}],[],false);InspectorBackend.registerCommand("Input.dispatchMouseEvent",[{"name":"type","type":"string","optional":false},{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"modifiers","type":"number","optional":true},{"name":"timestamp","type":"number","optional":true},{"name":"button","type":"string","optional":true},{"name":"clickCount","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Input.dispatchTouchEvent",[{"name":"type","type":"string","optional":false},{"name":"touchPoints","type":"object","optional":false},{"name":"modifiers","type":"number","optional":true},{"name":"timestamp","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Input.emulateTouchFromMouseEvent",[{"name":"type","type":"string","optional":false},{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"timestamp","type":"number","optional":false},{"name":"button","type":"string","optional":false},{"name":"deltaX","type":"number","optional":true},{"name":"deltaY","type":"number","optional":true},{"name":"modifiers","type":"number","optional":true},{"name":"clickCount","type":"number","optional":true}],[],false);InspectorBackend.registerCommand("Input.synthesizePinchGesture",[{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"scaleFactor","type":"number","optional":false},{"name":"relativeSpeed","type":"number","optional":true},{"name":"gestureSourceType","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Input.synthesizeScrollGesture",[{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"xDistance","type":"number","optional":true},{"name":"yDistance","type":"number","optional":true},{"name":"xOverscroll","type":"number","optional":true},{"name":"yOverscroll","type":"number","optional":true},{"name":"preventFling","type":"boolean","optional":true},{"name":"speed","type":"number","optional":true},{"name":"gestureSourceType","type":"string","optional":true},{"name":"repeatCount","type":"number","optional":true},{"name":"repeatDelayMs","type":"number","optional":true},{"name":"interactionMarkerName","type":"string","optional":true}],[],false);InspectorBackend.registerCommand("Input.synthesizeTapGesture",[{"name":"x","type":"number","optional":false},{"name":"y","type":"number","optional":false},{"name":"duration","type":"number","optional":true},{"name":"tapCount","type":"number","optional":true},{"name":"gestureSourceType","type":"string","optional":true}],[],false);InspectorBackend.registerEnum("LayerTree.ScrollRectType",{RepaintsOnScroll:"RepaintsOnScroll",TouchEventHandler:"TouchEventHandler",WheelEventHandler:"WheelEventHandler"});InspectorBackend.registerEvent("LayerTree.layerTreeDidChange",["layers"]);InspectorBackend.registerEvent("LayerTree.layerPainted",["layerId","clip"]);InspectorBackend.registerCommand("LayerTree.enable",[],[],false);InspectorBackend.registerCommand("LayerTree.disable",[],[],false);InspectorBackend.registerCommand("LayerTree.compositingReasons",[{"name":"layerId","type":"string","optional":false}],["compositingReasons"],false);InspectorBackend.registerCommand("LayerTree.makeSnapshot",[{"name":"layerId","type":"string","optional":false}],["snapshotId"],false);InspectorBackend.registerCommand("LayerTree.loadSnapshot",[{"name":"tiles","type":"object","optional":false}],["snapshotId"],false);InspectorBackend.registerCommand("LayerTree.releaseSnapshot",[{"name":"snapshotId","type":"string","optional":false}],[],false);InspectorBackend.registerCommand("LayerTree.profileSnapshot",[{"name":"snapshotId","type":"string","optional":false},{"name":"minRepeatCount","type":"number","optional":true},{"name":"minDuration","type":"number","optional":true},{"name":"clipRect","type":"object","optional":true}],["timings"],false);InspectorBackend.registerCommand("LayerTree.replaySnapshot",[{"name":"snapshotId","type":"string","optional":false},{"name":"fromStep","type":"number","optional":true},{"name":"toStep","type":"number","optional":true},{"name":"scale","type":"number","optional":true}],["dataURL"],false);InspectorBackend.registerCommand("LayerTree.snapshotCommandLog",[{"name":"snapshotId","type":"string","optional":false}],["commandLog"],false);InspectorBackend.registerCommand("DeviceOrientation.setDeviceOrientationOverride",[{"name":"alpha","type":"number","optional":false},{"name":"beta","type":"number","optional":false},{"name":"gamma","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("DeviceOrientation.clearDeviceOrientationOverride",[],[],false);InspectorBackend.registerEnum("Tracing.TraceConfigRecordMode",{RecordUntilFull:"recordUntilFull",RecordContinuously:"recordContinuously",RecordAsMuchAsPossible:"recordAsMuchAsPossible",EchoToConsole:"echoToConsole"});InspectorBackend.registerEvent("Tracing.dataCollected",["value"]);InspectorBackend.registerEvent("Tracing.tracingComplete",["stream"]);InspectorBackend.registerEvent("Tracing.bufferUsage",["percentFull","eventCount","value"]);InspectorBackend.registerCommand("Tracing.start",[{"name":"categories","type":"string","optional":true},{"name":"options","type":"string","optional":true},{"name":"bufferUsageReportingInterval","type":"number","optional":true},{"name":"transferMode","type":"string","optional":true},{"name":"traceConfig","type":"object","optional":true}],[],false);InspectorBackend.registerCommand("Tracing.end",[],[],false);InspectorBackend.registerCommand("Tracing.getCategories",[],["categories"],false);InspectorBackend.registerCommand("Tracing.requestMemoryDump",[],["dumpGuid","success"],false);InspectorBackend.registerCommand("Tracing.recordClockSyncMarker",[{"name":"syncId","type":"string","optional":false}],[],false);InspectorBackend.registerEnum("Animation.AnimationType",{CSSTransition:"CSSTransition",CSSAnimation:"CSSAnimation",WebAnimation:"WebAnimation"});InspectorBackend.registerEvent("Animation.animationCreated",["id"]);InspectorBackend.registerEvent("Animation.animationStarted",["animation"]);InspectorBackend.registerEvent("Animation.animationCanceled",["id"]);InspectorBackend.registerCommand("Animation.enable",[],[],false);InspectorBackend.registerCommand("Animation.disable",[],[],false);InspectorBackend.registerCommand("Animation.getPlaybackRate",[],["playbackRate"],false);InspectorBackend.registerCommand("Animation.setPlaybackRate",[{"name":"playbackRate","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Animation.getCurrentTime",[{"name":"id","type":"string","optional":false}],["currentTime"],false);InspectorBackend.registerCommand("Animation.setPaused",[{"name":"animations","type":"object","optional":false},{"name":"paused","type":"boolean","optional":false}],[],false);InspectorBackend.registerCommand("Animation.setTiming",[{"name":"animationId","type":"string","optional":false},{"name":"duration","type":"number","optional":false},{"name":"delay","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Animation.seekAnimations",[{"name":"animations","type":"object","optional":false},{"name":"currentTime","type":"number","optional":false}],[],false);InspectorBackend.registerCommand("Animation.releaseAnimations",[{"name":"animations","type":"object","optional":false}],[],false);InspectorBackend.registerCommand("Animation.resolveAnimation",[{"name":"animationId","type":"string","optional":false}],["remoteObject"],false);InspectorBackend.registerEnum("Accessibility.AXValueType",{Boolean:"boolean",Tristate:"tristate",BooleanOrUndefined:"booleanOrUndefined",Idref:"idref",IdrefList:"idrefList",Integer:"integer",Node:"node",NodeList:"nodeList",Number:"number",String:"string",ComputedString:"computedString",Token:"token",TokenList:"tokenList",DomRelation:"domRelation",Role:"role",InternalRole:"internalRole",ValueUndefined:"valueUndefined"});InspectorBackend.registerEnum("Accessibility.AXValueSourceType",{Attribute:"attribute",Implicit:"implicit",Style:"style",Contents:"contents",Placeholder:"placeholder",RelatedElement:"relatedElement"});InspectorBackend.registerEnum("Accessibility.AXValueNativeSourceType",{Figcaption:"figcaption",Label:"label",Labelfor:"labelfor",Labelwrapped:"labelwrapped",Legend:"legend",Tablecaption:"tablecaption",Title:"title",Other:"other"});InspectorBackend.registerEnum("Accessibility.AXGlobalStates",{Disabled:"disabled",Hidden:"hidden",HiddenRoot:"hiddenRoot",Invalid:"invalid"});InspectorBackend.registerEnum("Accessibility.AXLiveRegionAttributes",{Live:"live",Atomic:"atomic",Relevant:"relevant",Busy:"busy",Root:"root"});InspectorBackend.registerEnum("Accessibility.AXWidgetAttributes",{Autocomplete:"autocomplete",Haspopup:"haspopup",Level:"level",Multiselectable:"multiselectable",Orientation:"orientation",Multiline:"multiline",Readonly:"readonly",Required:"required",Valuemin:"valuemin",Valuemax:"valuemax",Valuetext:"valuetext"});InspectorBackend.registerEnum("Accessibility.AXWidgetStates",{Checked:"checked",Expanded:"expanded",Pressed:"pressed",Selected:"selected"});InspectorBackend.registerEnum("Accessibility.AXRelationshipAttributes",{Activedescendant:"activedescendant",Flowto:"flowto",Controls:"controls",Describedby:"describedby",Labelledby:"labelledby",Owns:"owns"});InspectorBackend.registerCommand("Accessibility.getAXNode",[{"name":"nodeId","type":"number","optional":false}],["accessibilityNode"],false);InspectorBackend.registerEnum("Storage.StorageType",{Appcache:"appcache",Cookies:"cookies",File_systems:"file_systems",Indexeddb:"indexeddb",Local_storage:"local_storage",Shader_cache:"shader_cache",Websql:"websql",Webrtc_indetity:"webrtc_indetity",Service_workers:"service_workers",Cache_storage:"cache_storage",All:"all"});InspectorBackend.registerCommand("Storage.clearDataForOrigin",[{"name":"origin","type":"string","optional":false},{"name":"storageTypes","type":"string","optional":false}],[],false);;WebInspector.InspectorBackendHostedMode={};WebInspector.InspectorBackendHostedMode.loadFromJSONIfNeeded=function(jsonUrl)
{if(InspectorBackend.isInitialized())
return;var xhr=new XMLHttpRequest();xhr.open("GET",jsonUrl,false);xhr.send(null);var schema=JSON.parse(xhr.responseText);var code=WebInspector.InspectorBackendHostedMode.generateCommands(schema);eval(code);}
WebInspector.InspectorBackendHostedMode.generateCommands=function(schema)
{var jsTypes={integer:"number",array:"object"};var rawTypes={};var result=[];var domains=schema["domains"]||[];for(var i=0;i<domains.length;++i){var domain=domains[i];for(var j=0;domain.types&&j<domain.types.length;++j){var type=domain.types[j];rawTypes[domain.domain+"."+type.id]=jsTypes[type.type]||type.type;}}
function toUpperCase(groupIndex,group0,group1)
{return[group0,group1][groupIndex].toUpperCase();}
function generateEnum(enumName,items)
{var members=[];for(var m=0;m<items.length;++m){var value=items[m];var name=value.replace(/-(\w)/g,toUpperCase.bind(null,1)).toTitleCase();name=name.replace(/HTML|XML|WML|API/ig,toUpperCase.bind(null,0));members.push(name+": \""+value+"\"");}
return"InspectorBackend.registerEnum(\""+enumName+"\", {"+members.join(", ")+"});";}
for(var i=0;i<domains.length;++i){var domain=domains[i];var types=domain["types"]||[];for(var j=0;j<types.length;++j){var type=types[j];if((type["type"]==="string")&&type["enum"])
result.push(generateEnum(domain.domain+"."+type.id,type["enum"]));else if(type["type"]==="object"){var properties=type["properties"]||[];for(var k=0;k<properties.length;++k){var property=properties[k];if((property["type"]==="string")&&property["enum"])
result.push(generateEnum(domain.domain+"."+type.id+property["name"].toTitleCase(),property["enum"]));}}}
var commands=domain["commands"]||[];for(var j=0;j<commands.length;++j){var command=commands[j];var parameters=command["parameters"];var paramsText=[];for(var k=0;parameters&&k<parameters.length;++k){var parameter=parameters[k];var type;if(parameter.type)
type=jsTypes[parameter.type]||parameter.type;else{var ref=parameter["$ref"];if(ref.indexOf(".")!==-1)
type=rawTypes[ref];else
type=rawTypes[domain.domain+"."+ref];}
var text="{\"name\": \""+parameter.name+"\", \"type\": \""+type+"\", \"optional\": "+(parameter.optional?"true":"false")+"}";paramsText.push(text);}
var returnsText=[];var returns=command["returns"]||[];for(var k=0;k<returns.length;++k){var parameter=returns[k];returnsText.push("\""+parameter.name+"\"");}
var hasErrorData=String(Boolean(command.error));result.push("InspectorBackend.registerCommand(\""+domain.domain+"."+command.name+"\", ["+paramsText.join(", ")+"], ["+returnsText.join(", ")+"], "+hasErrorData+");");}
for(var j=0;domain.events&&j<domain.events.length;++j){var event=domain.events[j];var paramsText=[];for(var k=0;event.parameters&&k<event.parameters.length;++k){var parameter=event.parameters[k];paramsText.push("\""+parameter.name+"\"");}
result.push("InspectorBackend.registerEvent(\""+domain.domain+"."+event.name+"\", ["+paramsText.join(", ")+"]);");}}
return result.join("\n");}
WebInspector.InspectorBackendHostedMode.loadFromJSONIfNeeded("../protocol.json");;WebInspector.Target=function(targetManager,name,type,connection,parentTarget)
{Protocol.Agents.call(this,connection.agentsMap());this._targetManager=targetManager;this._name=name;this._type=type;this._connection=connection;this._parentTarget=parentTarget;connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected,this._onDisconnect,this);this._id=WebInspector.Target._nextId++;this._modelByConstructor=new Map();}
WebInspector.Target.Type={Page:1,DedicatedWorker:2,ServiceWorker:4}
WebInspector.Target._nextId=1;WebInspector.Target.prototype={id:function()
{return this._id;},name:function()
{return this._name;},type:function()
{return this._type;},targetManager:function()
{return this._targetManager;},decorateLabel:function(label)
{return this.isWorker()?"\u2699 "+label:label;},registerDispatcher:function(domain,dispatcher)
{this._connection.registerDispatcher(domain,dispatcher);},isPage:function()
{return this._type===WebInspector.Target.Type.Page;},isWorker:function()
{return this.isDedicatedWorker()||this.isServiceWorker();},isDedicatedWorker:function()
{return this._type===WebInspector.Target.Type.DedicatedWorker;},isServiceWorker:function()
{return this._type===WebInspector.Target.Type.ServiceWorker;},hasJSContext:function()
{return!this.isServiceWorker();},parentTarget:function()
{return this._parentTarget;},_onDisconnect:function()
{this._targetManager.removeTarget(this);this._dispose();},_dispose:function()
{this._targetManager.dispatchEventToListeners(WebInspector.TargetManager.Events.TargetDisposed,this);this.networkManager.dispose();this.cpuProfilerModel.dispose();WebInspector.ServiceWorkerCacheModel.fromTarget(this).dispose();if(this.workerManager)
this.workerManager.dispose();},isDetached:function()
{return this._connection.isClosed();},model:function(modelClass)
{return this._modelByConstructor.get(modelClass)||null;},models:function()
{return this._modelByConstructor.valuesArray();},__proto__:Protocol.Agents.prototype}
WebInspector.SDKObject=function(target)
{WebInspector.Object.call(this);this._target=target;}
WebInspector.SDKObject.prototype={target:function()
{return this._target;},__proto__:WebInspector.Object.prototype}
WebInspector.SDKModel=function(modelClass,target)
{WebInspector.SDKObject.call(this,target);target._modelByConstructor.set(modelClass,this);}
WebInspector.SDKModel.prototype={suspendModel:function()
{return Promise.resolve();},resumeModel:function()
{return Promise.resolve();},__proto__:WebInspector.SDKObject.prototype};WebInspector.TargetManager=function()
{WebInspector.Object.call(this);this._targets=[];this._observers=[];this._observerTypeSymbol=Symbol("observerType");this._modelListeners={};this._isSuspended=false;}
WebInspector.TargetManager.Events={InspectedURLChanged:"InspectedURLChanged",MainFrameNavigated:"MainFrameNavigated",Load:"Load",PageReloadRequested:"PageReloadRequested",WillReloadPage:"WillReloadPage",TargetDisposed:"TargetDisposed",SuspendStateChanged:"SuspendStateChanged"}
WebInspector.TargetManager.prototype={suspendAllTargets:function()
{if(this._isSuspended)
return;this._isSuspended=true;this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);for(var i=0;i<this._targets.length;++i){for(var model of this._targets[i].models())
model.suspendModel();}},resumeAllTargets:function()
{if(!this._isSuspended)
throw new Error("Not suspended");this._isSuspended=false;this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);var promises=[];for(var i=0;i<this._targets.length;++i){for(var model of this._targets[i].models())
promises.push(model.resumeModel());}
return Promise.all(promises);},suspendAndResumeAllTargets:function()
{this.suspendAllTargets();this.resumeAllTargets();},allTargetsSuspended:function()
{return this._isSuspended;},inspectedPageURL:function()
{if(!this._targets.length)
return"";return this._targets[0].resourceTreeModel.inspectedPageURL();},inspectedPageDomain:function()
{if(!this._targets.length)
return"";return this._targets[0].resourceTreeModel.inspectedPageDomain();},_redispatchEvent:function(event)
{this.dispatchEventToListeners(event.type,event.data);},reloadPage:function(bypassCache,injectedScript)
{if(this._targets.length)
this._targets[0].resourceTreeModel.reloadPage(bypassCache,injectedScript);},addModelListener:function(modelClass,eventType,listener,thisObject)
{for(var i=0;i<this._targets.length;++i){var model=this._targets[i].model(modelClass);if(model)
model.addEventListener(eventType,listener,thisObject);}
if(!this._modelListeners[eventType])
this._modelListeners[eventType]=[];this._modelListeners[eventType].push({modelClass:modelClass,thisObject:thisObject,listener:listener});},removeModelListener:function(modelClass,eventType,listener,thisObject)
{if(!this._modelListeners[eventType])
return;for(var i=0;i<this._targets.length;++i){var model=this._targets[i].model(modelClass);if(model)
model.removeEventListener(eventType,listener,thisObject);}
var listeners=this._modelListeners[eventType];for(var i=0;i<listeners.length;++i){if(listeners[i].modelClass===modelClass&&listeners[i].listener===listener&&listeners[i].thisObject===thisObject)
listeners.splice(i--,1);}
if(!listeners.length)
delete this._modelListeners[eventType];},observeTargets:function(targetObserver,type)
{if(this._observerTypeSymbol in targetObserver)
throw new Error("Observer can only be registered once");targetObserver[this._observerTypeSymbol]=type||0x7fff;this.targets(type).forEach(targetObserver.targetAdded.bind(targetObserver));this._observers.push(targetObserver);},unobserveTargets:function(targetObserver)
{delete targetObserver[this._observerTypeSymbol];this._observers.remove(targetObserver);},createTarget:function(name,type,connection,parentTarget)
{var target=new WebInspector.Target(this,name,type,connection,parentTarget);target.consoleModel=new WebInspector.ConsoleModel(target);target.networkManager=new WebInspector.NetworkManager(target);target.resourceTreeModel=new WebInspector.ResourceTreeModel(target);target.networkLog=new WebInspector.NetworkLog(target);target.runtimeModel=new WebInspector.RuntimeModel(target);if(target.hasJSContext())
new WebInspector.DebuggerModel(target);if(target.type()===WebInspector.Target.Type.Page){new WebInspector.DOMModel(target);new WebInspector.CSSModel(target);}
target.workerManager=!target.isDedicatedWorker()?new WebInspector.WorkerManager(target):null;target.cpuProfilerModel=new WebInspector.CPUProfilerModel(target);target.heapProfilerModel=new WebInspector.HeapProfilerModel(target);target.tracingManager=new WebInspector.TracingManager(target);if(target.isPage())
target.serviceWorkerManager=new WebInspector.ServiceWorkerManager(target);this.addTarget(target);return target;},_observersByType:function(type)
{var result=[];for(var observer of this._observers){if(observer[this._observerTypeSymbol]&type)
result.push(observer);}
return result;},addTarget:function(target)
{this._targets.push(target);if(this._targets.length===1){target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,this._redispatchEvent,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._redispatchEvent,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._redispatchEvent,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.PageReloadRequested,this._redispatchEvent,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage,this._redispatchEvent,this);}
var copy=this._observersByType(target.type());for(var i=0;i<copy.length;++i)
copy[i].targetAdded(target);for(var eventType in this._modelListeners){var listeners=this._modelListeners[eventType];for(var i=0;i<listeners.length;++i){var model=target.model(listeners[i].modelClass);if(model)
model.addEventListener(eventType,listeners[i].listener,listeners[i].thisObject);}}},removeTarget:function(target)
{this._targets.remove(target);if(this._targets.length===0){target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,this._redispatchEvent,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._redispatchEvent,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._redispatchEvent,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage,this._redispatchEvent,this);}
var copy=this._observersByType(target.type());for(var i=0;i<copy.length;++i)
copy[i].targetRemoved(target);for(var eventType in this._modelListeners){var listeners=this._modelListeners[eventType];for(var i=0;i<listeners.length;++i){var model=target.model(listeners[i].modelClass);if(model)
model.removeEventListener(eventType,listeners[i].listener,listeners[i].thisObject);}}},hasTargets:function(type)
{return!!this.targets(type).length;},targets:function(type)
{if(!type)
return this._targets.slice();var result=[];for(var target of this._targets){if(target.type()&type)
result.push(target);}
return result;},targetsWithJSContext:function()
{var result=[];for(var target of this._targets){if(target.hasJSContext())
result.push(target);}
return result;},targetById:function(id)
{for(var i=0;i<this._targets.length;++i){if(this._targets[i].id()===id)
return this._targets[i];}
return null;},mainTarget:function()
{return this._targets[0]||null;},__proto__:WebInspector.Object.prototype}
WebInspector.TargetManager.Observer=function()
{}
WebInspector.TargetManager.Observer.prototype={targetAdded:function(target){},targetRemoved:function(target){},}
WebInspector.targetManager=new WebInspector.TargetManager();;WebInspector.ApplicationCacheModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.ApplicationCacheModel,target);target.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));this._agent=target.applicationCacheAgent();this._agent.enable();target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated,this._frameNavigated,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached,this._frameDetached,this);this._statuses={};this._manifestURLsByFrame={};this._mainFrameNavigated();this._onLine=true;}
WebInspector.ApplicationCacheModel.EventTypes={FrameManifestStatusUpdated:"FrameManifestStatusUpdated",FrameManifestAdded:"FrameManifestAdded",FrameManifestRemoved:"FrameManifestRemoved",FrameManifestsReset:"FrameManifestsReset",NetworkStateChanged:"NetworkStateChanged"}
WebInspector.ApplicationCacheModel.prototype={_frameNavigated:function(event)
{var frame=(event.data);if(frame.isMainFrame()){this._mainFrameNavigated();return;}
this._agent.getManifestForFrame(frame.id,this._manifestForFrameLoaded.bind(this,frame.id));},_frameDetached:function(event)
{var frame=(event.data);this._frameManifestRemoved(frame.id);},reset:function()
{this._statuses={};this._manifestURLsByFrame={};this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestsReset);},_mainFrameNavigated:function()
{this._agent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));},_manifestForFrameLoaded:function(frameId,error,manifestURL)
{if(error){console.error(error);return;}
if(!manifestURL)
this._frameManifestRemoved(frameId);},_framesWithManifestsLoaded:function(error,framesWithManifests)
{if(error){console.error(error);return;}
for(var i=0;i<framesWithManifests.length;++i)
this._frameManifestUpdated(framesWithManifests[i].frameId,framesWithManifests[i].manifestURL,framesWithManifests[i].status);},_frameManifestUpdated:function(frameId,manifestURL,status)
{if(status===applicationCache.UNCACHED){this._frameManifestRemoved(frameId);return;}
if(!manifestURL)
return;if(this._manifestURLsByFrame[frameId]&&manifestURL!==this._manifestURLsByFrame[frameId])
this._frameManifestRemoved(frameId);var statusChanged=this._statuses[frameId]!==status;this._statuses[frameId]=status;if(!this._manifestURLsByFrame[frameId]){this._manifestURLsByFrame[frameId]=manifestURL;this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded,frameId);}
if(statusChanged)
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated,frameId);},_frameManifestRemoved:function(frameId)
{if(!this._manifestURLsByFrame[frameId])
return;delete this._manifestURLsByFrame[frameId];delete this._statuses[frameId];this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved,frameId);},frameManifestURL:function(frameId)
{return this._manifestURLsByFrame[frameId]||"";},frameManifestStatus:function(frameId)
{return this._statuses[frameId]||applicationCache.UNCACHED;},get onLine()
{return this._onLine;},_statusUpdated:function(frameId,manifestURL,status)
{this._frameManifestUpdated(frameId,manifestURL,status);},requestApplicationCache:function(frameId,callback)
{function callbackWrapper(error,applicationCache)
{if(error){console.error(error);callback(null);return;}
callback(applicationCache);}
this._agent.getApplicationCacheForFrame(frameId,callbackWrapper);},_networkStateUpdated:function(isNowOnline)
{this._onLine=isNowOnline;this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged,isNowOnline);},__proto__:WebInspector.SDKModel.prototype}
WebInspector.ApplicationCacheDispatcher=function(applicationCacheModel)
{this._applicationCacheModel=applicationCacheModel;}
WebInspector.ApplicationCacheDispatcher.prototype={applicationCacheStatusUpdated:function(frameId,manifestURL,status)
{this._applicationCacheModel._statusUpdated(frameId,manifestURL,status);},networkStateUpdated:function(isNowOnline)
{this._applicationCacheModel._networkStateUpdated(isNowOnline);}}
WebInspector.ApplicationCacheModel.fromTarget=function(target)
{return(target.model(WebInspector.ApplicationCacheModel));};WebInspector.ConsoleModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.ConsoleModel,target);this._messages=[];this._messageById=new Map();this._warnings=0;this._errors=0;this._revokedErrors=0;this._consoleAgent=target.consoleAgent();target.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));this._enableAgent();}
WebInspector.ConsoleModel.Events={ConsoleCleared:"ConsoleCleared",MessageAdded:"MessageAdded",MessageUpdated:"MessageUpdated",CommandEvaluated:"CommandEvaluated",}
WebInspector.ConsoleModel.prototype={_enableAgent:function()
{this._enablingConsole=true;function callback()
{delete this._enablingConsole;}
this._consoleAgent.enable(callback.bind(this));},addMessage:function(msg)
{if(this._isBlacklisted(msg))
return;if(msg.level===WebInspector.ConsoleMessage.MessageLevel.RevokedError&&msg._relatedMessageId){var relatedMessage=this._messageById.get(msg._relatedMessageId);if(!relatedMessage)
return;this._errors--;this._revokedErrors++;relatedMessage.level=WebInspector.ConsoleMessage.MessageLevel.RevokedError;this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated,relatedMessage);return;}
this._messages.push(msg);if(msg._messageId)
this._messageById.set(msg._messageId,msg);this._incrementErrorWarningCount(msg);this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded,msg);},_incrementErrorWarningCount:function(msg)
{switch(msg.level){case WebInspector.ConsoleMessage.MessageLevel.Warning:this._warnings++;break;case WebInspector.ConsoleMessage.MessageLevel.Error:this._errors++;break;case WebInspector.ConsoleMessage.MessageLevel.RevokedError:this._revokedErrors++;break;}},_isBlacklisted:function(msg)
{if(msg.source!=WebInspector.ConsoleMessage.MessageSource.Network||msg.level!=WebInspector.ConsoleMessage.MessageLevel.Error||!msg.url||!msg.url.startsWith("chrome-extension"))
return false;if(msg.url.includes("://boadgeojelhgndaghljhdicfkmllpafd")||msg.url.includes("://dliochdbjfkdbacpmhlcpmleaejidimm")||msg.url.includes("://pkedcjkdefgpdelpbcmbmeomcjbeemfm")||msg.url.includes("://fjhoaacokmgbjemoflkofnenfaiekifl")||msg.url.includes("://fmfcbgogabcbclcofgocippekhfcmgfj")||msg.url.includes("://enhhojjnijigcajfphajepfemndkmdlo")||msg.url.includes("://ekpaaapppgpmolpcldedioblbkmijaca"))
return true;return false;},messages:function()
{return this._messages;},requestClearMessages:function()
{this._consoleAgent.clearMessages();this._messagesCleared();},_messagesCleared:function()
{this._messages=[];this._messageById.clear();this._errors=0;this._revokedErrors=0;this._warnings=0;this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);},errors:function()
{return this._errors;},revokedErrors:function()
{return this._revokedErrors;},warnings:function()
{return this._warnings;},__proto__:WebInspector.SDKModel.prototype}
WebInspector.ConsoleModel.evaluateCommandInConsole=function(executionContext,text,useCommandLineAPI)
{var target=executionContext.target();var requestedText=text;var commandMessage=new WebInspector.ConsoleMessage(target,WebInspector.ConsoleMessage.MessageSource.JS,null,text,WebInspector.ConsoleMessage.MessageType.Command);commandMessage.setExecutionContextId(executionContext.id);target.consoleModel.addMessage(commandMessage);function printResult(result,wasThrown,valueResult,exceptionDetails)
{if(!result)
return;WebInspector.console.showPromise().then(reportUponEvaluation);function reportUponEvaluation()
{target.consoleModel.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated,{result:result,wasThrown:wasThrown,text:requestedText,commandMessage:commandMessage,exceptionDetails:exceptionDetails});}}
if(/^\s*\{/.test(text)&&/\}\s*$/.test(text))
text="("+text+")";executionContext.evaluate(text,"console",!!useCommandLineAPI,false,false,true,true,printResult);WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ConsoleEvaluated);}
WebInspector.ConsoleModel.clearConsole=function()
{var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i)
targets[i].consoleModel.requestClearMessages();}
WebInspector.ConsoleMessage=function(target,source,level,messageText,type,url,line,column,requestId,parameters,stackTrace,timestamp,executionContextId,scriptId,messageId,relatedMessageId)
{this._target=target;this.source=source;this.level=level;this.messageText=messageText;this.type=type||WebInspector.ConsoleMessage.MessageType.Log;this.url=url||undefined;this.line=line||0;this.column=column||0;this.parameters=parameters;this.stackTrace=stackTrace;this.timestamp=timestamp||Date.now();this.executionContextId=executionContextId||0;this.scriptId=scriptId||null;this._messageId=messageId||0;this._relatedMessageId=relatedMessageId||0;this.request=requestId?target.networkLog.requestForId(requestId):null;if(this.request){var initiator=this.request.initiator();if(initiator){this.stackTrace=initiator.stack||undefined;if(initiator.url){this.url=initiator.url;this.line=initiator.lineNumber||0;}}}}
WebInspector.ConsoleMessage.prototype={target:function()
{return this._target;},setOriginatingMessage:function(originatingMessage)
{this._originatingConsoleMessage=originatingMessage;this.executionContextId=originatingMessage.executionContextId;},setExecutionContextId:function(executionContextId)
{this.executionContextId=executionContextId;},originatingMessage:function()
{return this._originatingConsoleMessage;},isGroupMessage:function()
{return this.type===WebInspector.ConsoleMessage.MessageType.StartGroup||this.type===WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed||this.type===WebInspector.ConsoleMessage.MessageType.EndGroup;},isGroupStartMessage:function()
{return this.type===WebInspector.ConsoleMessage.MessageType.StartGroup||this.type===WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed;},isErrorOrWarning:function()
{return(this.level===WebInspector.ConsoleMessage.MessageLevel.Warning||this.level===WebInspector.ConsoleMessage.MessageLevel.Error);},isEqual:function(msg)
{if(!msg)
return false;if(this._messageId||msg._messageId)
return false;if(this._relatedMessageId||msg._relatedMessageId)
return false;if(!this._isEqualStackTraces(this.stackTrace,msg.stackTrace))
return false;if(this.parameters){if(!msg.parameters||this.parameters.length!==msg.parameters.length)
return false;for(var i=0;i<msg.parameters.length;++i){if(this.parameters[i].type!==msg.parameters[i].type||msg.parameters[i].type==="object"||this.parameters[i].value!==msg.parameters[i].value)
return false;}}
return(this.target()===msg.target())&&(this.source===msg.source)&&(this.type===msg.type)&&(this.level===msg.level)&&(this.line===msg.line)&&(this.url===msg.url)&&(this.messageText===msg.messageText)&&(this.request===msg.request)&&(this.executionContextId===msg.executionContextId)&&(this.scriptId===msg.scriptId);},_isEqualStackTraces:function(stackTrace1,stackTrace2)
{if(!stackTrace1!==!stackTrace2)
return false;if(!stackTrace1)
return true;var callFrames1=stackTrace1.callFrames;var callFrames2=stackTrace2.callFrames;if(callFrames1.length!==callFrames2.length)
return false;for(var i=0,n=callFrames1.length;i<n;++i){if(callFrames1[i].url!==callFrames2[i].url||callFrames1[i].functionName!==callFrames2[i].functionName||callFrames1[i].lineNumber!==callFrames2[i].lineNumber||callFrames1[i].columnNumber!==callFrames2[i].columnNumber)
return false;}
return this._isEqualStackTraces(stackTrace1.parent,stackTrace2.parent);}}
WebInspector.ConsoleMessage.MessageSource={XML:"xml",JS:"javascript",Network:"network",ConsoleAPI:"console-api",Storage:"storage",AppCache:"appcache",Rendering:"rendering",CSS:"css",Security:"security",Other:"other",Deprecation:"deprecation"}
WebInspector.ConsoleMessage.MessageType={Log:"log",Dir:"dir",DirXML:"dirxml",Table:"table",Trace:"trace",Clear:"clear",StartGroup:"startGroup",StartGroupCollapsed:"startGroupCollapsed",EndGroup:"endGroup",Assert:"assert",Result:"result",Profile:"profile",ProfileEnd:"profileEnd",Command:"command"}
WebInspector.ConsoleMessage.MessageLevel={Log:"log",Info:"info",Warning:"warning",Error:"error",Debug:"debug",RevokedError:"revokedError"};WebInspector.ConsoleMessage.timestampComparator=function(a,b)
{return a.timestamp-b.timestamp;}
WebInspector.ConsoleDispatcher=function(console)
{this._console=console;}
WebInspector.ConsoleDispatcher.prototype={messageAdded:function(payload)
{var consoleMessage=new WebInspector.ConsoleMessage(this._console.target(),payload.source,payload.level,payload.text,payload.type,payload.url,payload.line,payload.column,payload.networkRequestId,payload.parameters,payload.stack,payload.timestamp*1000,payload.executionContextId,payload.scriptId,payload.messageId,payload.relatedMessageId);this._console.addMessage(consoleMessage);},messageRepeatCountUpdated:function(count)
{},messagesCleared:function()
{if(!WebInspector.moduleSetting("preserveConsoleLog").get())
this._console._messagesCleared();}}
WebInspector.MultitargetConsoleModel=function()
{WebInspector.targetManager.observeTargets(this);WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel,WebInspector.ConsoleModel.Events.MessageAdded,this._consoleMessageAdded,this);WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel,WebInspector.ConsoleModel.Events.MessageUpdated,this._consoleMessageUpdated,this);WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel,WebInspector.ConsoleModel.Events.CommandEvaluated,this._commandEvaluated,this);}
WebInspector.MultitargetConsoleModel.prototype={targetAdded:function(target)
{if(!this._mainTarget){this._mainTarget=target;target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared,this._consoleCleared,this);}},targetRemoved:function(target)
{if(this._mainTarget===target){delete this._mainTarget;target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared,this._consoleCleared,this);}},messages:function()
{var targets=WebInspector.targetManager.targets();var result=[];for(var i=0;i<targets.length;++i)
result=result.concat(targets[i].consoleModel.messages());return result;},_consoleCleared:function()
{this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);},_consoleMessageAdded:function(event)
{this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded,event.data);},_consoleMessageUpdated:function(event)
{this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated,event.data);},_commandEvaluated:function(event)
{this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated,event.data);},__proto__:WebInspector.Object.prototype}
WebInspector.multitargetConsoleModel;;WebInspector.CompilerSourceMappingContentProvider=function(sourceURL,contentType)
{this._sourceURL=sourceURL;this._contentType=contentType;}
WebInspector.CompilerSourceMappingContentProvider.prototype={contentURL:function()
{return this._sourceURL;},contentType:function()
{return this._contentType;},requestContent:function()
{var callback;var promise=new Promise(fulfill=>callback=fulfill);WebInspector.multitargetNetworkManager.loadResource(this._sourceURL,contentLoaded.bind(this));return promise;function contentLoaded(statusCode,headers,content)
{if(statusCode>=400){console.error("Could not load content for "+this._sourceURL+" : "+"HTTP status code: "+statusCode);callback(null);return;}
callback(content);}},searchInContent:function(query,caseSensitive,isRegex,callback)
{this.requestContent().then(contentLoaded);function contentLoaded(content)
{if(typeof content!=="string"){callback([]);return;}
callback(WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex));}}};WebInspector.CookieParser=function(target)
{this._target=target;}
WebInspector.CookieParser.KeyValue=function(key,value,position)
{this.key=key;this.value=value;this.position=position;}
WebInspector.CookieParser.prototype={cookies:function()
{return this._cookies;},parseCookie:function(cookieHeader)
{if(!this._initialize(cookieHeader))
return null;for(var kv=this._extractKeyValue();kv;kv=this._extractKeyValue()){if(kv.key.charAt(0)==="$"&&this._lastCookie)
this._lastCookie.addAttribute(kv.key.slice(1),kv.value);else if(kv.key.toLowerCase()!=="$version"&&typeof kv.value==="string")
this._addCookie(kv,WebInspector.Cookie.Type.Request);this._advanceAndCheckCookieDelimiter();}
this._flushCookie();return this._cookies;},parseSetCookie:function(setCookieHeader)
{if(!this._initialize(setCookieHeader))
return null;for(var kv=this._extractKeyValue();kv;kv=this._extractKeyValue()){if(this._lastCookie)
this._lastCookie.addAttribute(kv.key,kv.value);else
this._addCookie(kv,WebInspector.Cookie.Type.Response);if(this._advanceAndCheckCookieDelimiter())
this._flushCookie();}
this._flushCookie();return this._cookies;},_initialize:function(headerValue)
{this._input=headerValue;if(typeof headerValue!=="string")
return false;this._cookies=[];this._lastCookie=null;this._originalInputLength=this._input.length;return true;},_flushCookie:function()
{if(this._lastCookie)
this._lastCookie.setSize(this._originalInputLength-this._input.length-this._lastCookiePosition);this._lastCookie=null;},_extractKeyValue:function()
{if(!this._input||!this._input.length)
return null;var keyValueMatch=/^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);if(!keyValueMatch){console.log("Failed parsing cookie header before: "+this._input);return null;}
var result=new WebInspector.CookieParser.KeyValue(keyValueMatch[1],keyValueMatch[2]&&keyValueMatch[2].trim(),this._originalInputLength-this._input.length);this._input=this._input.slice(keyValueMatch[0].length);return result;},_advanceAndCheckCookieDelimiter:function()
{var match=/^\s*[\n;]\s*/.exec(this._input);if(!match)
return false;this._input=this._input.slice(match[0].length);return match[0].match("\n")!==null;},_addCookie:function(keyValue,type)
{if(this._lastCookie)
this._lastCookie.setSize(keyValue.position-this._lastCookiePosition);this._lastCookie=typeof keyValue.value==="string"?new WebInspector.Cookie(this._target,keyValue.key,keyValue.value,type):new WebInspector.Cookie(this._target,"",keyValue.key,type);this._lastCookiePosition=keyValue.position;this._cookies.push(this._lastCookie);}};WebInspector.CookieParser.parseCookie=function(target,header)
{return(new WebInspector.CookieParser(target)).parseCookie(header);}
WebInspector.CookieParser.parseSetCookie=function(target,header)
{return(new WebInspector.CookieParser(target)).parseSetCookie(header);}
WebInspector.Cookie=function(target,name,value,type)
{this._target=target;this._name=name;this._value=value;this._type=type;this._attributes={};}
WebInspector.Cookie.prototype={name:function()
{return this._name;},value:function()
{return this._value;},type:function()
{return this._type;},httpOnly:function()
{return"httponly"in this._attributes;},secure:function()
{return"secure"in this._attributes;},sameSite:function()
{return this._attributes["samesite"];},session:function()
{return!("expires"in this._attributes||"max-age"in this._attributes);},path:function()
{return this._attributes["path"];},port:function()
{return this._attributes["port"];},domain:function()
{return this._attributes["domain"];},expires:function()
{return this._attributes["expires"];},maxAge:function()
{return this._attributes["max-age"];},size:function()
{return this._size;},setSize:function(size)
{this._size=size;},expiresDate:function(requestDate)
{if(this.maxAge()){var targetDate=requestDate===null?new Date():requestDate;return new Date(targetDate.getTime()+1000*this.maxAge());}
if(this.expires())
return new Date(this.expires());return null;},attributes:function()
{return this._attributes;},addAttribute:function(key,value)
{this._attributes[key.toLowerCase()]=value;},remove:function(callback)
{this._target.networkAgent().deleteCookie(this.name(),(this.secure()?"https://":"http://")+this.domain()+this.path(),callback);}}
WebInspector.Cookie.Type={Request:0,Response:1};WebInspector.Cookies={}
WebInspector.Cookies.getCookiesAsync=function(callback)
{var allCookies=[];function mycallback(target,error,cookies)
{if(error){console.error(error);return;}
for(var i=0;i<cookies.length;++i)
allCookies.push(WebInspector.Cookies._parseProtocolCookie(target,cookies[i]));}
var barrier=new CallbackBarrier();for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.networkAgent().getCookies(barrier.createCallback(mycallback.bind(null,target)));barrier.callWhenDone(callback.bind(null,allCookies));}
WebInspector.Cookies._parseProtocolCookie=function(target,protocolCookie)
{var cookie=new WebInspector.Cookie(target,protocolCookie.name,protocolCookie.value,null);cookie.addAttribute("domain",protocolCookie["domain"]);cookie.addAttribute("path",protocolCookie["path"]);cookie.addAttribute("port",protocolCookie["port"]);if(protocolCookie["expires"])
cookie.addAttribute("expires",protocolCookie["expires"]);if(protocolCookie["httpOnly"])
cookie.addAttribute("httpOnly");if(protocolCookie["secure"])
cookie.addAttribute("secure");if(protocolCookie["sameSite"])
cookie.addAttribute("sameSite",protocolCookie["sameSite"]);cookie.setSize(protocolCookie["size"]);return cookie;}
WebInspector.Cookies.cookieMatchesResourceURL=function(cookie,resourceURL)
{var url=resourceURL.asParsedURL();if(!url||!WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain(),url.host))
return false;return(url.path.startsWith(cookie.path())&&(!cookie.port()||url.port==cookie.port())&&(!cookie.secure()||url.scheme==="https"));}
WebInspector.Cookies.cookieDomainMatchesResourceDomain=function(cookieDomain,resourceDomain)
{if(cookieDomain.charAt(0)!==".")
return resourceDomain===cookieDomain;return!!resourceDomain.match(new RegExp("^([^\\.]+\\.)*"+cookieDomain.substring(1).escapeForRegExp()+"$","i"));};WebInspector.ProfileNode=function(functionName,scriptId,url,lineNumber,columnNumber)
{this.frame={functionName:functionName,scriptId:scriptId,url:url,lineNumber:lineNumber,columnNumber:columnNumber};this.callUID;this.self=0;this.total=0;this.id=0;this.parent=null;this.children=[];}
WebInspector.ProfileNode.prototype={get functionName()
{return this.frame.functionName;},get scriptId()
{return this.frame.scriptId;},get url()
{return this.frame.url;},get lineNumber()
{return this.frame.lineNumber;},get columnNumber()
{return this.frame.columnNumber;}}
WebInspector.ProfileTreeModel=function(root)
{this.root=root;this.total=this._calculateTotals(this.root);this._assignDepthsAndParents();}
WebInspector.ProfileTreeModel.prototype={_assignDepthsAndParents:function()
{var root=this.root;root.depth=-1;root.parent=null;this.maxDepth=0;var nodesToTraverse=[root];while(nodesToTraverse.length){var parent=nodesToTraverse.pop();var depth=parent.depth+1;if(depth>this.maxDepth)
this.maxDepth=depth;var children=parent.children;var length=children.length;for(var i=0;i<length;++i){var child=children[i];child.depth=depth;child.parent=parent;if(child.children.length)
nodesToTraverse.push(child);}}},_calculateTotals:function(node)
{node.total=node.children.reduce((acc,child)=>acc+this._calculateTotals(child),node.self);return node.total;}};WebInspector.CPUProfileNode=function(sourceNode,sampleTime)
{WebInspector.ProfileNode.call(this,sourceNode.functionName,sourceNode.scriptId,sourceNode.url,sourceNode.lineNumber,sourceNode.columnNumber);this.id=sourceNode.id;this.self=sourceNode.hitCount*sampleTime;this.callUID=sourceNode.callUID;this.positionTicks=sourceNode.positionTicks;this.deoptReason=sourceNode.deoptReason;}
WebInspector.CPUProfileNode.prototype={__proto__:WebInspector.ProfileNode.prototype}
WebInspector.CPUProfileDataModel=function(profile)
{this.samples=profile.samples;this.timestamps=profile.timestamps;this.profileStartTime=profile.startTime*1000;this.profileEndTime=profile.endTime*1000;this.totalHitCount=0;this.profileHead=this._translateProfileTree(profile.head);WebInspector.ProfileTreeModel.call(this,this.profileHead);this._extractMetaNodes();if(this.samples){this._buildIdToNodeMap();this._sortSamples();this._normalizeTimestamps();}}
WebInspector.CPUProfileDataModel.prototype={_translateProfileTree:function(root)
{function computeHitCountForSubtree(node)
{return node.children.reduce((acc,node)=>acc+computeHitCountForSubtree(node),node.hitCount);}
function isNativeNode(node)
{return!!node.url&&node.url.startsWith("native ");}
this.totalHitCount=computeHitCountForSubtree(root);var sampleTime=(this.profileEndTime-this.profileStartTime)/this.totalHitCount;var keepNatives=!!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();var idMap=new Map([[root.id,root.id]]);var resultRoot=new WebInspector.CPUProfileNode(root,sampleTime);var parentNodeStack=root.children.map(()=>resultRoot);var sourceNodeStack=root.children;while(sourceNodeStack.length){var parentNode=parentNodeStack.pop();var sourceNode=sourceNodeStack.pop();var targetNode=new WebInspector.CPUProfileNode(sourceNode,sampleTime);if(keepNatives||!isNativeNode(sourceNode)){parentNode.children.push(targetNode);parentNode=targetNode;}else{parentNode.self+=targetNode.self;}
idMap.set(sourceNode.id,parentNode.id);parentNodeStack.push.apply(parentNodeStack,sourceNode.children.map(()=>parentNode));sourceNodeStack.push.apply(sourceNodeStack,sourceNode.children);}
if(this.samples)
this.samples=this.samples.map(id=>idMap.get(id));return resultRoot;},_sortSamples:function()
{var timestamps=this.timestamps;if(!timestamps)
return;var samples=this.samples;var indices=timestamps.map((x,index)=>index);indices.sort((a,b)=>timestamps[a]-timestamps[b]);for(var i=0;i<timestamps.length;++i){var index=indices[i];if(index===i)
continue;var savedTimestamp=timestamps[i];var savedSample=samples[i];var currentIndex=i;while(index!==i){samples[currentIndex]=samples[index];timestamps[currentIndex]=timestamps[index];currentIndex=index;index=indices[index];indices[currentIndex]=currentIndex;}
samples[currentIndex]=savedSample;timestamps[currentIndex]=savedTimestamp;}},_normalizeTimestamps:function()
{var timestamps=this.timestamps;if(!timestamps){var profileStartTime=this.profileStartTime;var interval=(this.profileEndTime-profileStartTime)/this.samples.length;timestamps=new Float64Array(this.samples.length+1);for(var i=0;i<timestamps.length;++i)
timestamps[i]=profileStartTime+i*interval;this.timestamps=timestamps;return;}
for(var i=0;i<timestamps.length;++i)
timestamps[i]/=1000;var averageSample=(timestamps.peekLast()-timestamps[0])/(timestamps.length-1);this.timestamps.push(timestamps.peekLast()+averageSample);this.profileStartTime=timestamps[0];this.profileEndTime=timestamps.peekLast();},_buildIdToNodeMap:function()
{this._idToNode=new Map();var idToNode=this._idToNode;var stack=[this.profileHead];while(stack.length){var node=stack.pop();idToNode.set(node.id,node);stack.push.apply(stack,node.children);}},_extractMetaNodes:function()
{var topLevelNodes=this.profileHead.children;for(var i=0;i<topLevelNodes.length&&!(this.gcNode&&this.programNode&&this.idleNode);i++){var node=topLevelNodes[i];if(node.functionName==="(garbage collector)")
this.gcNode=node;else if(node.functionName==="(program)")
this.programNode=node;else if(node.functionName==="(idle)")
this.idleNode=node;}},forEachFrame:function(openFrameCallback,closeFrameCallback,startTime,stopTime)
{if(!this.profileHead||!this.samples)
return;startTime=startTime||0;stopTime=stopTime||Infinity;var samples=this.samples;var timestamps=this.timestamps;var idToNode=this._idToNode;var gcNode=this.gcNode;var samplesCount=samples.length;var startIndex=timestamps.lowerBound(startTime);var stackTop=0;var stackNodes=[];var prevId=this.profileHead.id;var sampleTime=timestamps[samplesCount];var gcParentNode=null;if(!this._stackStartTimes)
this._stackStartTimes=new Float64Array(this.maxDepth+2);var stackStartTimes=this._stackStartTimes;if(!this._stackChildrenDuration)
this._stackChildrenDuration=new Float64Array(this.maxDepth+2);var stackChildrenDuration=this._stackChildrenDuration;for(var sampleIndex=startIndex;sampleIndex<samplesCount;sampleIndex++){sampleTime=timestamps[sampleIndex];if(sampleTime>=stopTime)
break;var id=samples[sampleIndex];if(id===prevId)
continue;var node=idToNode.get(id);var prevNode=idToNode.get(prevId);if(node===gcNode){gcParentNode=prevNode;openFrameCallback(gcParentNode.depth+1,gcNode,sampleTime);stackStartTimes[++stackTop]=sampleTime;stackChildrenDuration[stackTop]=0;prevId=id;continue;}
if(prevNode===gcNode){var start=stackStartTimes[stackTop];var duration=sampleTime-start;stackChildrenDuration[stackTop-1]+=duration;closeFrameCallback(gcParentNode.depth+1,gcNode,start,duration,duration-stackChildrenDuration[stackTop]);--stackTop;prevNode=gcParentNode;prevId=prevNode.id;gcParentNode=null;}
while(node.depth>prevNode.depth){stackNodes.push(node);node=node.parent;}
while(prevNode!==node){var start=stackStartTimes[stackTop];var duration=sampleTime-start;stackChildrenDuration[stackTop-1]+=duration;closeFrameCallback(prevNode.depth,(prevNode),start,duration,duration-stackChildrenDuration[stackTop]);--stackTop;if(node.depth===prevNode.depth){stackNodes.push(node);node=node.parent;}
prevNode=prevNode.parent;}
while(stackNodes.length){node=stackNodes.pop();openFrameCallback(node.depth,node,sampleTime);stackStartTimes[++stackTop]=sampleTime;stackChildrenDuration[stackTop]=0;}
prevId=id;}
if(idToNode.get(prevId)===gcNode){var start=stackStartTimes[stackTop];var duration=sampleTime-start;stackChildrenDuration[stackTop-1]+=duration;closeFrameCallback(gcParentNode.depth+1,node,start,duration,duration-stackChildrenDuration[stackTop]);--stackTop;}
for(var node=idToNode.get(prevId);node.parent;node=node.parent){var start=stackStartTimes[stackTop];var duration=sampleTime-start;stackChildrenDuration[stackTop-1]+=duration;closeFrameCallback(node.depth,(node),start,duration,duration-stackChildrenDuration[stackTop]);--stackTop;}},nodeByIndex:function(index)
{return this._idToNode.get(this.samples[index])||null;},__proto__:WebInspector.ProfileTreeModel.prototype};WebInspector.CPUProfilerModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.CPUProfilerModel,target);this._isRecording=false;target.registerProfilerDispatcher(this);target.profilerAgent().enable();this._configureCpuProfilerSamplingInterval();WebInspector.moduleSetting("highResolutionCpuProfiling").addChangeListener(this._configureCpuProfilerSamplingInterval,this);}
WebInspector.CPUProfilerModel.EventTypes={ConsoleProfileStarted:Symbol("ConsoleProfileStarted"),ConsoleProfileFinished:Symbol("ConsoleProfileFinished")};WebInspector.CPUProfilerModel.EventData;WebInspector.CPUProfilerModel.prototype={_configureCpuProfilerSamplingInterval:function()
{var intervalUs=WebInspector.moduleSetting("highResolutionCpuProfiling").get()?100:1000;this.target().profilerAgent().setSamplingInterval(intervalUs);},consoleProfileStarted:function(id,scriptLocation,title)
{this._dispatchProfileEvent(WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileStarted,id,scriptLocation,title);},consoleProfileFinished:function(id,scriptLocation,cpuProfile,title)
{this._dispatchProfileEvent(WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileFinished,id,scriptLocation,title,cpuProfile);},_dispatchProfileEvent:function(eventName,id,scriptLocation,title,cpuProfile)
{self.runtime.loadModulePromise("profiler").then(_=>{var debuggerModel=(WebInspector.DebuggerModel.fromTarget(this.target()));var debuggerLocation=WebInspector.DebuggerModel.Location.fromPayload(debuggerModel,scriptLocation);var globalId=this.target().id()+"."+id;var data=({id:globalId,scriptLocation:debuggerLocation,cpuProfile:cpuProfile,title:title});this.dispatchEventToListeners(eventName,data);});},isRecordingProfile:function()
{return this._isRecording;},startRecording:function()
{this._isRecording=true;this.target().profilerAgent().start();WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesCPUProfileTaken);},stopRecording:function()
{function extractProfile(error,profile)
{return!error&&profile?profile:null;}
this._isRecording=false;return this.target().profilerAgent().stop(extractProfile);},dispose:function()
{WebInspector.moduleSetting("highResolutionCpuProfiling").removeChangeListener(this._configureCpuProfilerSamplingInterval,this);},__proto__:WebInspector.SDKModel.prototype};WebInspector.CSSMatchedStyles=function(cssModel,node,inlinePayload,attributesPayload,matchedPayload,pseudoPayload,inheritedPayload,animationsPayload)
{this._cssModel=cssModel;this._node=node;this._nodeStyles=[];this._nodeForStyle=new Map();this._inheritedStyles=new Set();this._keyframes=[];this._matchingSelectors=new Map();function addAttributesStyle()
{if(!attributesPayload)
return;var style=new WebInspector.CSSStyleDeclaration(cssModel,null,attributesPayload,WebInspector.CSSStyleDeclaration.Type.Attributes);this._nodeForStyle.set(style,this._node);this._nodeStyles.push(style);}
if(inlinePayload&&this._node.nodeType()===Node.ELEMENT_NODE){var style=new WebInspector.CSSStyleDeclaration(cssModel,null,inlinePayload,WebInspector.CSSStyleDeclaration.Type.Inline);this._nodeForStyle.set(style,this._node);this._nodeStyles.push(style);}
var addedAttributesStyle;for(var i=matchedPayload.length-1;i>=0;--i){var rule=new WebInspector.CSSStyleRule(cssModel,matchedPayload[i].rule);if((rule.isInjected()||rule.isUserAgent())&&!addedAttributesStyle){addedAttributesStyle=true;addAttributesStyle.call(this);}
this._nodeForStyle.set(rule.style,this._node);this._nodeStyles.push(rule.style);addMatchingSelectors.call(this,this._node,rule,matchedPayload[i].matchingSelectors);}
if(!addedAttributesStyle)
addAttributesStyle.call(this);var parentNode=this._node.parentNode;for(var i=0;parentNode&&inheritedPayload&&i<inheritedPayload.length;++i){var entryPayload=inheritedPayload[i];var inheritedInlineStyle=entryPayload.inlineStyle?new WebInspector.CSSStyleDeclaration(cssModel,null,entryPayload.inlineStyle,WebInspector.CSSStyleDeclaration.Type.Inline):null;if(inheritedInlineStyle&&this._containsInherited(inheritedInlineStyle)){this._nodeForStyle.set(inheritedInlineStyle,parentNode);this._nodeStyles.push(inheritedInlineStyle);this._inheritedStyles.add(inheritedInlineStyle);}
var inheritedMatchedCSSRules=entryPayload.matchedCSSRules||[];for(var j=inheritedMatchedCSSRules.length-1;j>=0;--j){var inheritedRule=new WebInspector.CSSStyleRule(cssModel,inheritedMatchedCSSRules[j].rule);addMatchingSelectors.call(this,parentNode,inheritedRule,inheritedMatchedCSSRules[j].matchingSelectors);if(!this._containsInherited(inheritedRule.style))
continue;this._nodeForStyle.set(inheritedRule.style,parentNode);this._nodeStyles.push(inheritedRule.style);this._inheritedStyles.add(inheritedRule.style);}
parentNode=parentNode.parentNode;}
this._pseudoStyles=new Map();if(pseudoPayload){for(var i=0;i<pseudoPayload.length;++i){var entryPayload=pseudoPayload[i];var pseudoElement=this._node.pseudoElements().get(entryPayload.pseudoType)||null;var pseudoStyles=[];var rules=entryPayload.matches||[];for(var j=rules.length-1;j>=0;--j){var pseudoRule=new WebInspector.CSSStyleRule(cssModel,rules[j].rule);pseudoStyles.push(pseudoRule.style);this._nodeForStyle.set(pseudoRule.style,pseudoElement);if(pseudoElement)
addMatchingSelectors.call(this,pseudoElement,pseudoRule,rules[j].matchingSelectors);}
this._pseudoStyles.set(entryPayload.pseudoType,pseudoStyles);}}
if(animationsPayload)
this._keyframes=animationsPayload.map(rule=>new WebInspector.CSSKeyframesRule(cssModel,rule));this.resetActiveProperties();function addMatchingSelectors(node,rule,matchingSelectorIndices)
{for(var matchingSelectorIndex of matchingSelectorIndices){var selector=rule.selectors[matchingSelectorIndex];this._setSelectorMatches(node,selector.text,true);}}}
WebInspector.CSSMatchedStyles.prototype={node:function()
{return this._node;},cssModel:function()
{return this._cssModel;},hasMatchingSelectors:function(rule)
{var matchingSelectors=this.matchingSelectors(rule);return matchingSelectors.length>0&&this.mediaMatches(rule.style);},matchingSelectors:function(rule)
{var node=this.nodeForStyle(rule.style);if(!node)
return[];var map=this._matchingSelectors.get(node.id);if(!map)
return[];var result=[];for(var i=0;i<rule.selectors.length;++i){if(map.get(rule.selectors[i].text))
result.push(i);}
return result;},recomputeMatchingSelectors:function(rule)
{var node=this.nodeForStyle(rule.style);if(!node)
return Promise.resolve();var promises=[];for(var selector of rule.selectors)
promises.push(querySelector.call(this,node,selector.text));return Promise.all(promises);function querySelector(node,selectorText)
{var ownerDocument=node.ownerDocument||null;var map=this._matchingSelectors.get(node.id);if((map&&map.has(selectorText))||!ownerDocument)
return Promise.resolve();var resolve;var promise=new Promise(fulfill=>resolve=fulfill);this._node.domModel().querySelectorAll(ownerDocument.id,selectorText,onQueryComplete.bind(this,node,selectorText,resolve));return promise;}
function onQueryComplete(node,selectorText,callback,matchingNodeIds)
{if(matchingNodeIds)
this._setSelectorMatches(node,selectorText,matchingNodeIds.indexOf(node.id)!==-1);callback();}},addNewRule:function(rule,node)
{this._nodeForStyle.set(rule.style,node);return this.recomputeMatchingSelectors(rule);},_setSelectorMatches:function(node,selectorText,value)
{var map=this._matchingSelectors.get(node.id);if(!map){map=new Map();this._matchingSelectors.set(node.id,map);}
map.set(selectorText,value);},mediaMatches:function(style)
{var media=style.parentRule?style.parentRule.media:[];for(var i=0;media&&i<media.length;++i){if(!media[i].active())
return false;}
return true;},nodeStyles:function()
{return this._nodeStyles;},keyframes:function()
{return this._keyframes;},pseudoStyles:function()
{return this._pseudoStyles;},_containsInherited:function(style)
{var properties=style.allProperties;for(var i=0;i<properties.length;++i){var property=properties[i];if(property.activeInStyle()&&WebInspector.CSSMetadata.isPropertyInherited(property.name))
return true;}
return false;},nodeForStyle:function(style)
{return this._nodeForStyle.get(style)||null;},isInherited:function(style)
{return this._inheritedStyles.has(style);},propertyState:function(property)
{if(this._propertiesState.size===0){this._computeActiveProperties(this._nodeStyles,this._propertiesState);for(var pseudoElementStyles of this._pseudoStyles.valuesArray())
this._computeActiveProperties(pseudoElementStyles,this._propertiesState);}
return this._propertiesState.get(property)||null;},resetActiveProperties:function()
{this._propertiesState=new Map();},_computeActiveProperties:function(styles,result)
{var foundImportantProperties=new Set();var propertyToEffectiveRule=new Map();var inheritedPropertyToNode=new Map();var allUsedProperties=new Set();for(var i=0;i<styles.length;++i){var style=styles[i];var rule=style.parentRule;if(rule&&!(rule instanceof WebInspector.CSSStyleRule))
continue;if(rule&&!this.hasMatchingSelectors(rule))
continue;var styleActiveProperties=new Map();var allProperties=style.allProperties;for(var j=0;j<allProperties.length;++j){var property=allProperties[j];var inherited=this.isInherited(style);if(inherited&&!WebInspector.CSSMetadata.isPropertyInherited(property.name))
continue;if(!property.activeInStyle()){result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);continue;}
var canonicalName=WebInspector.CSSMetadata.canonicalPropertyName(property.name);if(foundImportantProperties.has(canonicalName)){result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);continue;}
if(!property.important&&allUsedProperties.has(canonicalName)){result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);continue;}
var isKnownProperty=propertyToEffectiveRule.has(canonicalName);var inheritedFromNode=inherited?this.nodeForStyle(style):null;if(!isKnownProperty&&inheritedFromNode&&!inheritedPropertyToNode.has(canonicalName))
inheritedPropertyToNode.set(canonicalName,inheritedFromNode);if(property.important){if(inherited&&isKnownProperty&&inheritedFromNode!==inheritedPropertyToNode.get(canonicalName)){result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);continue;}
foundImportantProperties.add(canonicalName);if(isKnownProperty){var overloaded=(propertyToEffectiveRule.get(canonicalName).get(canonicalName));result.set(overloaded,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);propertyToEffectiveRule.get(canonicalName).delete(canonicalName);}}
styleActiveProperties.set(canonicalName,property);allUsedProperties.add(canonicalName);propertyToEffectiveRule.set(canonicalName,styleActiveProperties);result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Active);}
for(var property of style.leadingProperties()){var canonicalName=WebInspector.CSSMetadata.canonicalPropertyName(property.name);if(!styleActiveProperties.has(canonicalName))
continue;var longhands=style.longhandProperties(property.name);if(!longhands.length)
continue;var notUsed=true;for(var longhand of longhands){var longhandCanonicalName=WebInspector.CSSMetadata.canonicalPropertyName(longhand.name);notUsed=notUsed&&!styleActiveProperties.has(longhandCanonicalName);}
if(!notUsed)
continue;styleActiveProperties.delete(canonicalName);allUsedProperties.delete(canonicalName);result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);}}}}
WebInspector.CSSMatchedStyles.PropertyState={Active:"Active",Overloaded:"Overloaded"};WebInspector.CSSMediaQuery=function(payload)
{this._active=payload.active;this._expressions=[];for(var j=0;j<payload.expressions.length;++j)
this._expressions.push(WebInspector.CSSMediaQueryExpression.parsePayload(payload.expressions[j]));}
WebInspector.CSSMediaQuery.parsePayload=function(payload)
{return new WebInspector.CSSMediaQuery(payload);}
WebInspector.CSSMediaQuery.prototype={active:function()
{return this._active;},expressions:function()
{return this._expressions;}}
WebInspector.CSSMediaQueryExpression=function(payload)
{this._value=payload.value;this._unit=payload.unit;this._feature=payload.feature;this._valueRange=payload.valueRange?WebInspector.TextRange.fromObject(payload.valueRange):null;this._computedLength=payload.computedLength||null;}
WebInspector.CSSMediaQueryExpression.parsePayload=function(payload)
{return new WebInspector.CSSMediaQueryExpression(payload);}
WebInspector.CSSMediaQueryExpression.prototype={value:function()
{return this._value;},unit:function()
{return this._unit;},feature:function()
{return this._feature;},valueRange:function()
{return this._valueRange;},computedLength:function()
{return this._computedLength;}}
WebInspector.CSSMedia=function(cssModel,payload)
{this._cssModel=cssModel;this._reinitialize(payload);}
WebInspector.CSSMedia.Source={LINKED_SHEET:"linkedSheet",INLINE_SHEET:"inlineSheet",MEDIA_RULE:"mediaRule",IMPORT_RULE:"importRule"};WebInspector.CSSMedia.parsePayload=function(cssModel,payload)
{return new WebInspector.CSSMedia(cssModel,payload);}
WebInspector.CSSMedia.parseMediaArrayPayload=function(cssModel,payload)
{var result=[];for(var i=0;i<payload.length;++i)
result.push(WebInspector.CSSMedia.parsePayload(cssModel,payload[i]));return result;}
WebInspector.CSSMedia.prototype={_reinitialize:function(payload)
{this.text=payload.text;this.source=payload.source;this.sourceURL=payload.sourceURL||"";this.range=payload.range?WebInspector.TextRange.fromObject(payload.range):null;this.styleSheetId=payload.styleSheetId;this.mediaList=null;if(payload.mediaList){this.mediaList=[];for(var i=0;i<payload.mediaList.length;++i)
this.mediaList.push(WebInspector.CSSMediaQuery.parsePayload(payload.mediaList[i]));}},rebase:function(edit)
{if(this.styleSheetId!==edit.styleSheetId||!this.range)
return;if(edit.oldRange.equal(this.range))
this._reinitialize((edit.payload));else
this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);},equal:function(other)
{if(!this.styleSheetId||!this.range||!other.range)
return false;return this.styleSheetId===other.styleSheetId&&this.range.equal(other.range);},active:function()
{if(!this.mediaList)
return true;for(var i=0;i<this.mediaList.length;++i){if(this.mediaList[i].active())
return true;}
return false;},lineNumberInSource:function()
{if(!this.range)
return undefined;var header=this.header();if(!header)
return undefined;return header.lineNumberInSource(this.range.startLine);},columnNumberInSource:function()
{if(!this.range)
return undefined;var header=this.header();if(!header)
return undefined;return header.columnNumberInSource(this.range.startLine,this.range.startColumn);},header:function()
{return this.styleSheetId?this._cssModel.styleSheetHeaderForId(this.styleSheetId):null;},rawLocation:function()
{var header=this.header();if(!header||this.lineNumberInSource()===undefined)
return null;var lineNumber=Number(this.lineNumberInSource());return new WebInspector.CSSLocation(header,lineNumber,this.columnNumberInSource());}};WebInspector.CSSMetadata=function(properties)
{this._values=([]);this._longhands={};this._shorthands={};for(var i=0;i<properties.length;++i){var property=properties[i];if(typeof property==="string"){this._values.push(property);continue;}
var propertyName=property.name;if(!CSS.supports(propertyName,"initial"))
continue;this._values.push(propertyName);var longhands=properties[i].longhands;if(longhands){this._longhands[propertyName]=longhands;for(var j=0;j<longhands.length;++j){var longhandName=longhands[j];var shorthands=this._shorthands[longhandName];if(!shorthands){shorthands=[];this._shorthands[longhandName]=shorthands;}
shorthands.push(propertyName);}}}
this._values.sort();}
WebInspector.CSSMetadata.cssPropertiesMetainfo=new WebInspector.CSSMetadata([]);WebInspector.CSSMetadata.isColorAwareProperty=function(propertyName)
{return!!WebInspector.CSSMetadata._colorAwareProperties[propertyName.toLowerCase()]||WebInspector.CSSMetadata.isCustomProperty(propertyName.toLowerCase());}
WebInspector.CSSMetadata.isLengthProperty=function(propertyName)
{if(propertyName==="line-height")
return false;if(!WebInspector.CSSMetadata._distancePropertiesKeySet)
WebInspector.CSSMetadata._distancePropertiesKeySet=WebInspector.CSSMetadata._distanceProperties.keySet();return WebInspector.CSSMetadata._distancePropertiesKeySet[propertyName]||propertyName.startsWith("margin")||propertyName.startsWith("padding")||propertyName.indexOf("width")!==-1||propertyName.indexOf("height")!==-1;}
WebInspector.CSSMetadata.isBezierAwareProperty=function(propertyName)
{return!!WebInspector.CSSMetadata._bezierAwareProperties[propertyName.toLowerCase()]||WebInspector.CSSMetadata.isCustomProperty(propertyName.toLowerCase());}
WebInspector.CSSMetadata.isCustomProperty=function(propertyName)
{return propertyName.startsWith("--");}
WebInspector.CSSMetadata.InheritedProperties=["azimuth","border-collapse","border-spacing","caption-side","color","cursor","direction","elevation","empty-cells","font-family","font-size","font-style","font-variant","font-weight","font","letter-spacing","line-height","list-style-image","list-style-position","list-style-type","list-style","orphans","overflow-wrap","pitch-range","pitch","quotes","resize","richness","speak-header","speak-numeral","speak-punctuation","speak","speech-rate","stress","text-align","text-indent","text-transform","text-shadow","-webkit-user-select","visibility","voice-family","volume","white-space","widows","word-spacing","word-wrap","zoom"].keySet();WebInspector.CSSMetadata.NonStandardInheritedProperties=["-webkit-font-smoothing"].keySet();WebInspector.CSSMetadata.canonicalPropertyName=function(name)
{if(!name||name.length<9||name.charAt(0)!=="-")
return name.toLowerCase();var match=name.match(/(?:-webkit-)(.+)/);var propertiesSet=WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet();var hasSupportedProperties=WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length>0;if(!match||(hasSupportedProperties&&!propertiesSet.hasOwnProperty(match[1].toLowerCase())))
return name.toLowerCase();return match[1].toLowerCase();}
WebInspector.CSSMetadata.isCSSPropertyName=function(propertyName)
{if(propertyName.startsWith("-moz-")||propertyName.startsWith("-o-")||propertyName.startsWith("-webkit-")||propertyName.startsWith("-ms-"))
return true;var hasSupportedProperties=WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length>0;return!hasSupportedProperties||WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet().hasOwnProperty(propertyName);}
WebInspector.CSSMetadata.isPropertyInherited=function(propertyName)
{return!!(WebInspector.CSSMetadata.InheritedProperties[WebInspector.CSSMetadata.canonicalPropertyName(propertyName)]||WebInspector.CSSMetadata.NonStandardInheritedProperties[propertyName.toLowerCase()]);}
WebInspector.CSSMetadata._distanceProperties=["background-position","border-spacing","bottom","font-size","height","left","letter-spacing","max-height","max-width","min-height","min-width","right","text-indent","top","width","word-spacing"];WebInspector.CSSMetadata._bezierAwareProperties=["animation","animation-timing-function","transition","transition-timing-function","-webkit-animation","-webkit-animation-timing-function","-webkit-transition","-webkit-transition-timing-function"].keySet();WebInspector.CSSMetadata._colorAwareProperties=["background","background-color","background-image","border","border-color","border-top","border-right","border-bottom","border-left","border-top-color","border-right-color","border-bottom-color","border-left-color","box-shadow","color","fill","outline","outline-color","stroke","text-shadow","-webkit-box-shadow","-webkit-column-rule-color","-webkit-text-decoration-color","-webkit-text-emphasis","-webkit-text-emphasis-color"].keySet();WebInspector.CSSMetadata._propertyDataMap={"table-layout":{values:["auto","fixed"]},"visibility":{values:["hidden","visible","collapse"]},"background-repeat":{values:["repeat","repeat-x","repeat-y","no-repeat","space","round"]},"content":{values:["list-item","close-quote","no-close-quote","no-open-quote","open-quote"]},"list-style-image":{values:["none"]},"clear":{values:["none","left","right","both"]},"overflow-x":{values:["hidden","auto","visible","overlay","scroll"]},"stroke-linejoin":{values:["round","miter","bevel"]},"baseline-shift":{values:["baseline","sub","super"]},"border-bottom-width":{values:["medium","thick","thin"]},"margin-top-collapse":{values:["collapse","separate","discard"]},"max-height":{values:["none"]},"box-orient":{values:["horizontal","vertical","inline-axis","block-axis"],},"font-stretch":{values:["normal","wider","narrower","ultra-condensed","extra-condensed","condensed","semi-condensed","semi-expanded","expanded","extra-expanded","ultra-expanded"]},"border-left-width":{values:["medium","thick","thin"]},"box-shadow":{values:["inset","none"]},"writing-mode":{values:["horizontal-tb","vertical-rl","vertical-lr"]},"-webkit-writing-mode":{values:["lr","rl","tb","lr-tb","rl-tb","tb-rl","horizontal-tb","vertical-rl","vertical-lr"]},"border-collapse":{values:["collapse","separate"]},"page-break-inside":{values:["auto","avoid"]},"border-top-width":{values:["medium","thick","thin"]},"outline-color":{values:["invert"]},"outline-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"cursor":{values:["none","copy","auto","crosshair","default","pointer","move","vertical-text","cell","context-menu","alias","progress","no-drop","not-allowed","-webkit-zoom-in","-webkit-zoom-out","e-resize","ne-resize","nw-resize","n-resize","se-resize","sw-resize","s-resize","w-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","col-resize","row-resize","text","wait","help","all-scroll","-webkit-grab","-webkit-grabbing"]},"border-width":{values:["medium","thick","thin"]},"border-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"size":{values:["a3","a4","a5","b4","b5","landscape","ledger","legal","letter","portrait"]},"background-size":{values:["contain","cover"]},"direction":{values:["ltr","rtl"]},"enable-background":{values:["accumulate","new"]},"float":{values:["none","left","right"]},"overflow-y":{values:["hidden","auto","visible","overlay","scroll"]},"margin-bottom-collapse":{values:["collapse","separate","discard"]},"box-reflect":{values:["left","right","above","below"]},"overflow":{values:["hidden","auto","visible","overlay","scroll"]},"text-rendering":{values:["auto","optimizeSpeed","optimizeLegibility","geometricPrecision"]},"text-align":{values:["-webkit-auto","start","end","left","right","center","justify","-webkit-left","-webkit-right","-webkit-center"]},"list-style-position":{values:["outside","inside","hanging"]},"margin-bottom":{values:["auto"]},"color-interpolation":{values:["linearrgb"]},"background-origin":{values:["border-box","content-box","padding-box"]},"word-wrap":{values:["normal","break-word"]},"font-weight":{values:["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"]},"margin-before-collapse":{values:["collapse","separate","discard"]},"text-transform":{values:["none","capitalize","uppercase","lowercase"]},"border-right-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"border-left-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"-webkit-text-emphasis":{values:["circle","filled","open","dot","double-circle","triangle","sesame"]},"font-style":{values:["italic","oblique","normal"]},"speak":{values:["none","normal","spell-out","digits","literal-punctuation","no-punctuation"]},"color-rendering":{values:["auto","optimizeSpeed","optimizeQuality"]},"list-style-type":{values:["none","inline","disc","circle","square","decimal","decimal-leading-zero","arabic-indic","binary","bengali","cambodian","khmer","devanagari","gujarati","gurmukhi","kannada","lower-hexadecimal","lao","malayalam","mongolian","myanmar","octal","oriya","persian","urdu","telugu","tibetan","thai","upper-hexadecimal","lower-roman","upper-roman","lower-greek","lower-alpha","lower-latin","upper-alpha","upper-latin","afar","ethiopic-halehame-aa-et","ethiopic-halehame-aa-er","amharic","ethiopic-halehame-am-et","amharic-abegede","ethiopic-abegede-am-et","cjk-earthly-branch","cjk-heavenly-stem","ethiopic","ethiopic-halehame-gez","ethiopic-abegede","ethiopic-abegede-gez","hangul-consonant","hangul","lower-norwegian","oromo","ethiopic-halehame-om-et","sidama","ethiopic-halehame-sid-et","somali","ethiopic-halehame-so-et","tigre","ethiopic-halehame-tig","tigrinya-er","ethiopic-halehame-ti-er","tigrinya-er-abegede","ethiopic-abegede-ti-er","tigrinya-et","ethiopic-halehame-ti-et","tigrinya-et-abegede","ethiopic-abegede-ti-et","upper-greek","upper-norwegian","asterisks","footnotes","hebrew","armenian","lower-armenian","upper-armenian","georgian","cjk-ideographic","hiragana","katakana","hiragana-iroha","katakana-iroha"]},"text-combine-upright":{values:["none","all"]},"-webkit-text-combine":{values:["none","horizontal"]},"text-orientation":{values:["mixed","upright","sideways"]},"outline":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"font":{values:["caption","icon","menu","message-box","small-caption","-webkit-mini-control","-webkit-small-control","-webkit-control","status-bar","italic","oblique","small-caps","normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900","xx-small","x-small","small","medium","large","x-large","xx-large","-webkit-xxx-large","smaller","larger","serif","sans-serif","cursive","fantasy","monospace","-webkit-body","-webkit-pictograph"]},"dominant-baseline":{values:["middle","auto","central","text-before-edge","text-after-edge","ideographic","alphabetic","hanging","mathematical","use-script","no-change","reset-size"]},"display":{values:["none","inline","block","list-item","run-in","inline-block","table","inline-table","table-row-group","table-header-group","table-footer-group","table-row","table-column-group","table-column","table-cell","table-caption","-webkit-box","-webkit-inline-box","flex","inline-flex","grid","inline-grid"]},"-webkit-text-emphasis-position":{values:["over","under"]},"image-rendering":{values:["auto","optimizeSpeed","optimizeQuality","pixelated"]},"alignment-baseline":{values:["baseline","middle","auto","before-edge","after-edge","central","text-before-edge","text-after-edge","ideographic","alphabetic","hanging","mathematical"]},"outline-width":{values:["medium","thick","thin"]},"box-align":{values:["baseline","center","stretch","start","end"]},"border-right-width":{values:["medium","thick","thin"]},"border-top-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"line-height":{values:["normal"]},"text-overflow":{values:["clip","ellipsis"]},"overflow-wrap":{values:["normal","break-word"]},"box-direction":{values:["normal","reverse"]},"margin-after-collapse":{values:["collapse","separate","discard"]},"page-break-before":{values:["left","right","auto","always","avoid"]},"border-image":{values:["repeat","stretch"]},"text-decoration":{values:["blink","line-through","overline","underline"]},"position":{values:["absolute","fixed","relative","static"]},"font-family":{values:["serif","sans-serif","cursive","fantasy","monospace","-webkit-body","-webkit-pictograph"]},"text-overflow-mode":{values:["clip","ellipsis"]},"border-bottom-style":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"unicode-bidi":{values:["normal","bidi-override","embed","isolate","isolate-override","plaintext"]},"clip-rule":{values:["nonzero","evenodd"]},"margin-left":{values:["auto"]},"margin-top":{values:["auto"]},"zoom":{values:["normal","document","reset"]},"max-width":{values:["none"]},"caption-side":{values:["top","bottom"]},"empty-cells":{values:["hide","show"]},"pointer-events":{values:["none","all","auto","visible","visiblepainted","visiblefill","visiblestroke","painted","fill","stroke","bounding-box"]},"letter-spacing":{values:["normal"]},"background-clip":{values:["border-box","content-box","padding-box"]},"-webkit-font-smoothing":{values:["none","auto","antialiased","subpixel-antialiased"]},"border":{values:["none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},"font-size":{values:["xx-small","x-small","small","medium","large","x-large","xx-large","-webkit-xxx-large","smaller","larger"]},"font-variant":{values:["small-caps","normal"]},"vertical-align":{values:["baseline","middle","sub","super","text-top","text-bottom","top","bottom","-webkit-baseline-middle"]},"white-space":{values:["normal","nowrap","pre","pre-line","pre-wrap"]},"box-lines":{values:["single","multiple"]},"page-break-after":{values:["left","right","auto","always","avoid"]},"clip-path":{values:["none"]},"margin":{values:["auto"]},"margin-right":{values:["auto"]},"word-break":{values:["normal","break-all","break-word"]},"word-spacing":{values:["normal"]},"-webkit-text-emphasis-style":{values:["circle","filled","open","dot","double-circle","triangle","sesame"]},"transform":{values:["scale","scaleX","scaleY","scale3d","rotate","rotateX","rotateY","rotateZ","rotate3d","skew","skewX","skewY","translate","translateX","translateY","translateZ","translate3d","matrix","matrix3d","perspective"]},"image-resolution":{values:["from-image","snap"]},"box-sizing":{values:["content-box","border-box"]},"clip":{values:["auto"]},"resize":{values:["none","both","horizontal","vertical"]},"align-content":{values:["flex-start","flex-end","center","space-between","space-around","stretch"]},"align-items":{values:["flex-start","flex-end","center","baseline","stretch"]},"align-self":{values:["auto","flex-start","flex-end","center","baseline","stretch"]},"flex-direction":{values:["row","row-reverse","column","column-reverse"]},"justify-content":{values:["flex-start","flex-end","center","space-between","space-around"]},"flex-wrap":{values:["nowrap","wrap","wrap-reverse"]},"perspective":{values:["none"]},"perspective-origin":{values:["left","center","right","top","bottom"]},"transform-origin":{values:["left","center","right","top","bottom"]},"transform-style":{values:["flat","preserve-3d"]},"transition-timing-function":{values:["ease","linear","ease-in","ease-out","ease-in-out","step-start","step-end","steps","cubic-bezier"]},"animation-timing-function":{values:["ease","linear","ease-in","ease-out","ease-in-out","step-start","step-end","steps","cubic-bezier"]},"animation-direction":{values:["normal","reverse","alternate","alternate-reverse"]},"animation-play-state":{values:["running","paused"]},"animation-fill-mode":{values:["none","forwards","backwards","both"]},"-webkit-backface-visibility":{values:["visible","hidden"]},"-webkit-box-decoration-break":{values:["slice","clone"]},"-webkit-column-break-after":{values:["auto","always","avoid","left","right","page","column","avoid-page","avoid-column"]},"-webkit-column-break-before":{values:["auto","always","avoid","left","right","page","column","avoid-page","avoid-column"]},"-webkit-column-break-inside":{values:["auto","avoid","avoid-page","avoid-column"]},"-webkit-column-span":{values:["none","all"]},"-webkit-column-count":{values:["auto"]},"-webkit-column-gap":{values:["normal"]},"-webkit-filter":{values:["url","blur","brightness","contrast","drop-shadow","grayscale","hue-rotate","invert","opacity","saturate","sepia"]},"-webkit-line-break":{values:["auto","loose","normal","strict"]},"-webkit-user-select":{values:["none","text","all"]},"-webkit-user-modify":{values:["read-only","read-write","read-write-plaintext-only"]},"text-align-last":{values:["auto","start","end","left","right","center","justify"]},"-webkit-text-decoration-line":{values:["none","underline","overline","line-through","blink"]},"-webkit-text-decoration-style":{values:["solid","double","dotted","dashed","wavy"]},"-webkit-text-decoration-skip":{values:["none","objects","spaces","ink","edges","box-decoration"]},"mix-blend-mode":{values:["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity","unset"]},"background-blend-mode":{values:["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity","unset"]},}
WebInspector.CSSMetadata.keywordsForProperty=function(propertyName)
{var acceptedKeywords=["inherit","initial"];var descriptor=WebInspector.CSSMetadata.descriptor(propertyName);if(descriptor&&descriptor.values)
acceptedKeywords.push.apply(acceptedKeywords,descriptor.values);if(WebInspector.CSSMetadata.isColorAwareProperty(propertyName)){acceptedKeywords.push("currentColor");for(var color in WebInspector.Color.Nicknames)
acceptedKeywords.push(color);}
return new WebInspector.CSSMetadata(acceptedKeywords);}
WebInspector.CSSMetadata.descriptor=function(propertyName)
{if(!propertyName)
return null;var unprefixedName=propertyName.replace(/^-webkit-/,"");propertyName=propertyName.toLowerCase();var entry=WebInspector.CSSMetadata._propertyDataMap[propertyName];if(!entry&&unprefixedName!==propertyName)
entry=WebInspector.CSSMetadata._propertyDataMap[unprefixedName];return entry||null;}
WebInspector.CSSMetadata.initializeWithSupportedProperties=function(properties)
{WebInspector.CSSMetadata.cssPropertiesMetainfo=new WebInspector.CSSMetadata(properties);}
WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet=function()
{if(!WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet)
WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet=WebInspector.CSSMetadata.cssPropertiesMetainfo.keySet();return WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet;}
WebInspector.CSSMetadata.Weight={"align-content":57,"align-items":129,"align-self":55,"animation":175,"animation-delay":114,"animation-direction":113,"animation-duration":137,"animation-fill-mode":132,"animation-iteration-count":124,"animation-name":139,"animation-play-state":104,"animation-timing-function":141,"backface-visibility":123,"background":260,"background-attachment":119,"background-clip":165,"background-color":259,"background-image":246,"background-origin":107,"background-position":237,"background-position-x":108,"background-position-y":93,"background-repeat":234,"background-size":203,"border":263,"border-bottom":233,"border-bottom-color":190,"border-bottom-left-radius":186,"border-bottom-right-radius":185,"border-bottom-style":150,"border-bottom-width":179,"border-collapse":209,"border-color":226,"border-image":89,"border-image-outset":50,"border-image-repeat":49,"border-image-slice":58,"border-image-source":32,"border-image-width":52,"border-left":221,"border-left-color":174,"border-left-style":142,"border-left-width":172,"border-radius":224,"border-right":223,"border-right-color":182,"border-right-style":130,"border-right-width":178,"border-spacing":198,"border-style":206,"border-top":231,"border-top-color":192,"border-top-left-radius":187,"border-top-right-radius":189,"border-top-style":152,"border-top-width":180,"border-width":214,"bottom":227,"box-shadow":213,"box-sizing":216,"caption-side":96,"clear":229,"clip":173,"clip-rule":5,"color":256,"content":219,"counter-increment":111,"counter-reset":110,"cursor":250,"direction":176,"display":262,"empty-cells":99,"fill":140,"fill-opacity":82,"fill-rule":22,"filter":160,"flex":133,"flex-basis":66,"flex-direction":85,"flex-flow":94,"flex-grow":112,"flex-shrink":61,"flex-wrap":68,"float":252,"font":211,"font-family":254,"font-kerning":18,"font-size":264,"font-stretch":77,"font-style":220,"font-variant":161,"font-weight":257,"height":266,"image-rendering":90,"justify-content":127,"left":248,"letter-spacing":188,"line-height":244,"list-style":215,"list-style-image":145,"list-style-position":149,"list-style-type":199,"margin":267,"margin-bottom":241,"margin-left":243,"margin-right":238,"margin-top":253,"mask":20,"max-height":205,"max-width":225,"min-height":217,"min-width":218,"object-fit":33,"opacity":251,"order":117,"orphans":146,"outline":222,"outline-color":153,"outline-offset":147,"outline-style":151,"outline-width":148,"overflow":255,"overflow-wrap":105,"overflow-x":184,"overflow-y":196,"padding":265,"padding-bottom":230,"padding-left":235,"padding-right":232,"padding-top":240,"page":8,"page-break-after":120,"page-break-before":69,"page-break-inside":121,"perspective":92,"perspective-origin":103,"pointer-events":183,"position":261,"quotes":158,"resize":168,"right":245,"shape-rendering":38,"size":64,"speak":118,"src":170,"stop-color":42,"stop-opacity":31,"stroke":98,"stroke-dasharray":36,"stroke-dashoffset":3,"stroke-linecap":30,"stroke-linejoin":21,"stroke-miterlimit":12,"stroke-opacity":34,"stroke-width":87,"table-layout":171,"tab-size":46,"text-align":260,"text-anchor":35,"text-decoration":247,"text-indent":207,"text-overflow":204,"text-rendering":155,"text-shadow":208,"text-transform":202,"top":258,"touch-action":80,"transform":181,"transform-origin":162,"transform-style":86,"transition":193,"transition-delay":134,"transition-duration":135,"transition-property":131,"transition-timing-function":122,"unicode-bidi":156,"unicode-range":136,"vertical-align":236,"visibility":242,"-webkit-appearance":191,"-webkit-backface-visibility":154,"-webkit-background-clip":164,"-webkit-background-origin":40,"-webkit-background-size":163,"-webkit-border-end":9,"-webkit-border-horizontal-spacing":81,"-webkit-border-image":75,"-webkit-border-radius":212,"-webkit-border-start":10,"-webkit-border-start-color":16,"-webkit-border-start-width":13,"-webkit-border-vertical-spacing":43,"-webkit-box-align":101,"-webkit-box-direction":51,"-webkit-box-flex":128,"-webkit-box-lines":2,"-webkit-box-ordinal-group":91,"-webkit-box-orient":144,"-webkit-box-pack":106,"-webkit-box-reflect":39,"-webkit-box-shadow":210,"-webkit-column-break-inside":60,"-webkit-column-count":84,"-webkit-column-gap":76,"-webkit-column-rule":25,"-webkit-column-rule-color":23,"-webkit-columns":44,"-webkit-column-span":29,"-webkit-column-width":47,"-webkit-filter":159,"-webkit-font-feature-settings":59,"-webkit-font-smoothing":177,"-webkit-highlight":1,"-webkit-line-break":45,"-webkit-line-clamp":126,"-webkit-margin-after":67,"-webkit-margin-before":70,"-webkit-margin-collapse":14,"-webkit-margin-end":65,"-webkit-margin-start":100,"-webkit-margin-top-collapse":78,"-webkit-mask":19,"-webkit-mask-box-image":72,"-webkit-mask-image":88,"-webkit-mask-position":54,"-webkit-mask-repeat":63,"-webkit-mask-size":79,"-webkit-padding-after":15,"-webkit-padding-before":28,"-webkit-padding-end":48,"-webkit-padding-start":73,"-webkit-print-color-adjust":83,"-webkit-rtl-ordering":7,"-webkit-tap-highlight-color":169,"-webkit-text-emphasis-color":11,"-webkit-text-fill-color":71,"-webkit-text-security":17,"-webkit-text-stroke":56,"-webkit-text-stroke-color":37,"-webkit-text-stroke-width":53,"-webkit-user-drag":95,"-webkit-user-modify":62,"-webkit-user-select":194,"-webkit-writing-mode":4,"white-space":228,"widows":115,"width":268,"will-change":74,"word-break":166,"word-spacing":157,"word-wrap":197,"writing-mode":41,"z-index":239,"zoom":200};WebInspector.CSSMetadata.prototype={startsWith:function(prefix)
{var firstIndex=this._firstIndexOfPrefix(prefix);if(firstIndex===-1)
return[];var results=[];while(firstIndex<this._values.length&&this._values[firstIndex].startsWith(prefix))
results.push(this._values[firstIndex++]);return results;},mostUsedOf:function(properties)
{var maxWeight=0;var index=0;for(var i=0;i<properties.length;i++){var weight=WebInspector.CSSMetadata.Weight[properties[i]];if(!weight)
weight=WebInspector.CSSMetadata.Weight[WebInspector.CSSMetadata.canonicalPropertyName(properties[i])];if(weight>maxWeight){maxWeight=weight;index=i;}}
return index;},_firstIndexOfPrefix:function(prefix)
{if(!this._values.length)
return-1;if(!prefix)
return 0;var maxIndex=this._values.length-1;var minIndex=0;var foundIndex;do{var middleIndex=(maxIndex+minIndex)>>1;if(this._values[middleIndex].startsWith(prefix)){foundIndex=middleIndex;break;}
if(this._values[middleIndex]<prefix)
minIndex=middleIndex+1;else
maxIndex=middleIndex-1;}while(minIndex<=maxIndex);if(foundIndex===undefined)
return-1;while(foundIndex&&this._values[foundIndex-1].startsWith(prefix))
foundIndex--;return foundIndex;},keySet:function()
{if(!this._keySet)
this._keySet=this._values.keySet();return this._keySet;},next:function(str,prefix)
{return this._closest(str,prefix,1);},previous:function(str,prefix)
{return this._closest(str,prefix,-1);},_closest:function(str,prefix,shift)
{if(!str)
return"";var index=this._values.indexOf(str);if(index===-1)
return"";if(!prefix){index=(index+this._values.length+shift)%this._values.length;return this._values[index];}
var propertiesWithPrefix=this.startsWith(prefix);var j=propertiesWithPrefix.indexOf(str);j=(j+propertiesWithPrefix.length+shift)%propertiesWithPrefix.length;return propertiesWithPrefix[j];},longhands:function(shorthand)
{return this._longhands[shorthand];},shorthands:function(longhand)
{return this._shorthands[longhand];}}
WebInspector.CSSMetadata.initializeWithSupportedProperties([]);;WebInspector.CSSModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.CSSModel,target);this._domModel=WebInspector.DOMModel.fromTarget(target);this._agent=target.cssAgent();this._styleLoader=new WebInspector.CSSModel.ComputedStyleLoader(this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameNavigated,this);target.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));this._agent.enable().then(this._wasEnabled.bind(this));this._styleSheetIdToHeader=new Map();this._styleSheetIdsForURL=new Map();this._originalStyleSheetText=new Map();this._sourceMapLoadingStyleSheetsIds=new Multimap();this._sourceMapByURL=new Map();this._sourceMapURLToHeaders=new Multimap();WebInspector.moduleSetting("cssSourceMapsEnabled").addChangeListener(this._toggleSourceMapSupport,this);}
WebInspector.CSSModel.Events={LayoutEditorChange:"LayoutEditorChange",MediaQueryResultChanged:"MediaQueryResultChanged",ModelWasEnabled:"ModelWasEnabled",PseudoStateForced:"PseudoStateForced",StyleSheetAdded:"StyleSheetAdded",StyleSheetChanged:"StyleSheetChanged",StyleSheetRemoved:"StyleSheetRemoved",SourceMapAttached:"SourceMapAttached",SourceMapDetached:"SourceMapDetached",SourceMapChanged:"SourceMapChanged"}
WebInspector.CSSModel.MediaTypes=["all","braille","embossed","handheld","print","projection","screen","speech","tty","tv"];WebInspector.CSSModel.PseudoStateMarker="pseudo-state-marker";WebInspector.CSSModel.Edit=function(styleSheetId,oldRange,newText,payload)
{this.styleSheetId=styleSheetId;this.oldRange=oldRange;this.newRange=WebInspector.TextRange.fromEdit(oldRange,newText);this.payload=payload;}
WebInspector.CSSModel.prototype={_toggleSourceMapSupport:function(event)
{var enabled=(event.data);var headers=this.styleSheetHeaders();for(var header of headers){if(enabled)
this._attachSourceMap(header);else
this._detachSourceMap(header);}},sourceMapForHeader:function(header)
{return this._sourceMapByURL.get(header.sourceMapURL)||null;},_sourceMapLoadedForTest:function(){},headersForSourceMap:function(sourceMap)
{return this._sourceMapURLToHeaders.get(sourceMap.url()).valuesArray();},_attachSourceMap:function(header)
{var sourceMapURL=header.sourceMapURL;if(!sourceMapURL||!WebInspector.moduleSetting("cssSourceMapsEnabled").get())
return;if(this._sourceMapByURL.has(sourceMapURL)){attach.call(this,sourceMapURL,header);return;}
if(!this._sourceMapLoadingStyleSheetsIds.has(sourceMapURL)){WebInspector.TextSourceMap.load(sourceMapURL,header.sourceURL).then(onTextSourceMapLoaded.bind(this,sourceMapURL)).then(onSourceMap.bind(this,sourceMapURL));}
this._sourceMapLoadingStyleSheetsIds.set(sourceMapURL,header.id);function onTextSourceMapLoaded(sourceMapURL,sourceMap)
{if(!sourceMap)
return Promise.resolve((null));var factoryExtension=this._factoryForSourceMap(sourceMap);if(!factoryExtension)
return Promise.resolve((sourceMap));return factoryExtension.instancePromise().then(factory=>factory.editableSourceMap(this.target(),sourceMap)).then(map=>map||sourceMap).catchException((null));}
function onSourceMap(sourceMapURL,sourceMap)
{this._sourceMapLoadedForTest();var styleSheetIds=this._sourceMapLoadingStyleSheetsIds.get(sourceMapURL);this._sourceMapLoadingStyleSheetsIds.removeAll(sourceMapURL);if(!sourceMap)
return;var headers=new Set();for(var styleSheetId of styleSheetIds){var header=this.styleSheetHeaderForId(styleSheetId);if(header)
headers.add(header);}
if(!headers.size)
return;this._sourceMapByURL.set(sourceMapURL,sourceMap);for(var header of headers)
attach.call(this,sourceMapURL,header);}
function attach(sourceMapURL,header)
{this._sourceMapURLToHeaders.set(sourceMapURL,header);this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapAttached,header);}},_factoryForSourceMap:function(sourceMap)
{var sourceExtensions=new Set(sourceMap.sourceURLs().map(url=>WebInspector.ParsedURL.extractExtension(url)));for(var runtimeExtension of self.runtime.extensions(WebInspector.SourceMapFactory)){var supportedExtensions=new Set(runtimeExtension.descriptor()["extensions"]);if(supportedExtensions.containsAll(sourceExtensions))
return runtimeExtension;}
return null;},_detachSourceMap:function(header)
{if(!header.sourceMapURL||!this._sourceMapURLToHeaders.hasValue(header.sourceMapURL,header))
return;this._sourceMapURLToHeaders.remove(header.sourceMapURL,header);if(!this._sourceMapURLToHeaders.has(header.sourceMapURL))
this._sourceMapByURL.delete(header.sourceMapURL);this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapDetached,header);},domModel:function()
{return(this._domModel);},setStyleText:function(styleSheetId,range,text,majorChange)
{var original=this._innerSetStyleTexts.bind(this,[styleSheetId],[range],[text],majorChange);var header=this.styleSheetHeaderForId(styleSheetId);if(!header)
return original();var sourceMap=this.sourceMapForHeader(header);if(!sourceMap)
return original();var originalAndDetach=originalAndDetachIfSuccess.bind(this,header);if(!sourceMap.editable())
return originalAndDetach();return(sourceMap.editCompiled([range],[text]).then(onEditingDone.bind(this)).catch(onError.bind(this,header)));function onEditingDone(editResult)
{if(!editResult)
return Promise.resolve(false);var edits=editResult.compiledEdits;if(!edits.length)
return onCSSPatched.call(this,editResult,true);edits.sort(WebInspector.SourceEdit.comparator);edits=edits.reverse();var styleSheetIds=[];var ranges=[];var texts=[];for(var edit of edits){styleSheetIds.push(header.id);ranges.push(edit.oldRange);texts.push(edit.newText);}
return this._innerSetStyleTexts(styleSheetIds,ranges,texts,majorChange).then(onCSSPatched.bind(this,editResult));}
function onCSSPatched(editResult,success)
{if(!success)
return originalAndDetach();this._sourceMapByURL.set(header.sourceMapURL,editResult.map);this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapChanged,{sourceMap:editResult.map,newSources:editResult.newSources});return Promise.resolve(true);}
function onError(header,error)
{WebInspector.console.error(WebInspector.UIString("LiveSASS failed: %s",sourceMap.compiledURL()));console.error(error);this._detachSourceMap(header);return original();}
function originalAndDetachIfSuccess(header)
{return this._innerSetStyleTexts([styleSheetId],[range],[text],majorChange).then(detachIfSuccess.bind(this));function detachIfSuccess(success)
{if(success)
this._detachSourceMap(header);return success;}}},_innerSetStyleTexts:function(styleSheetIds,ranges,texts,majorChange)
{function parsePayload(error,stylePayloads)
{if(error||!stylePayloads||stylePayloads.length!==ranges.length)
return false;if(majorChange)
this._domModel.markUndoableState();for(var i=0;i<ranges.length;++i){var edit=new WebInspector.CSSModel.Edit(styleSheetIds[i],ranges[i],texts[i],stylePayloads[i]);this._fireStyleSheetChanged(styleSheetIds[i],edit);}
return true;}
console.assert(styleSheetIds.length===ranges.length&&ranges.length===texts.length,"Array lengths must be equal");var edits=[];var ensureContentPromises=[];for(var i=0;i<styleSheetIds.length;++i){edits.push({styleSheetId:styleSheetIds[i],range:ranges[i].serializeToObject(),text:texts[i]});ensureContentPromises.push(this._ensureOriginalStyleSheetText(styleSheetIds[i]));}
return Promise.all(ensureContentPromises).then(()=>this._agent.setStyleTexts(edits,parsePayload.bind(this))).catchException(false);},setSelectorText:function(styleSheetId,range,text)
{function callback(error,selectorPayload)
{if(error||!selectorPayload)
return false;this._domModel.markUndoableState();var edit=new WebInspector.CSSModel.Edit(styleSheetId,range,text,selectorPayload);this._fireStyleSheetChangedAndDetach(styleSheetId,edit);return true;}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);return this._ensureOriginalStyleSheetText(styleSheetId).then(()=>this._agent.setRuleSelector(styleSheetId,range,text,callback.bind(this))).catchException(false);},setKeyframeKey:function(styleSheetId,range,text)
{function callback(error,payload)
{if(error||!payload)
return false;this._domModel.markUndoableState();var edit=new WebInspector.CSSModel.Edit(styleSheetId,range,text,payload);this._fireStyleSheetChangedAndDetach(styleSheetId,edit);return true;}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);return this._ensureOriginalStyleSheetText(styleSheetId).then(()=>this._agent.setKeyframeKey(styleSheetId,range,text,callback.bind(this))).catchException(false);},mediaQueriesPromise:function()
{function parsePayload(error,payload)
{return!error&&payload?WebInspector.CSSMedia.parseMediaArrayPayload(this,payload):[];}
return this._agent.getMediaQueries(parsePayload.bind(this));},isEnabled:function()
{return this._isEnabled;},_wasEnabled:function(error)
{if(error){console.error("Failed to enabled CSS agent: "+error);return;}
this._isEnabled=true;this.dispatchEventToListeners(WebInspector.CSSModel.Events.ModelWasEnabled);},matchedStylesPromise:function(nodeId)
{function callback(error,inlinePayload,attributesPayload,matchedPayload,pseudoPayload,inheritedPayload,animationsPayload)
{if(error)
return null;var node=this._domModel.nodeForId(nodeId);if(!node)
return null;return new WebInspector.CSSMatchedStyles(this,node,inlinePayload||null,attributesPayload||null,matchedPayload||[],pseudoPayload||[],inheritedPayload||[],animationsPayload||[]);}
return this._agent.getMatchedStylesForNode(nodeId,callback.bind(this));},computedStylePromise:function(nodeId)
{return this._styleLoader.computedStylePromise(nodeId);},backgroundColorsPromise:function(nodeId)
{function backgroundColorsCallback(error,backgroundColors){return!error&&backgroundColors?backgroundColors:null;}
return this._agent.getBackgroundColors(nodeId,backgroundColorsCallback);},platformFontsPromise:function(nodeId)
{function platformFontsCallback(error,fonts)
{return!error&&fonts?fonts:null;}
return this._agent.getPlatformFontsForNode(nodeId,platformFontsCallback);},allStyleSheets:function()
{var values=this._styleSheetIdToHeader.valuesArray();function styleSheetComparator(a,b)
{if(a.sourceURL<b.sourceURL)
return-1;else if(a.sourceURL>b.sourceURL)
return 1;return a.startLine-b.startLine||a.startColumn-b.startColumn;}
values.sort(styleSheetComparator);return values;},inlineStylesPromise:function(nodeId)
{function callback(error,inlinePayload,attributesStylePayload)
{if(error||!inlinePayload)
return null;var inlineStyle=inlinePayload?new WebInspector.CSSStyleDeclaration(this,null,inlinePayload,WebInspector.CSSStyleDeclaration.Type.Inline):null;var attributesStyle=attributesStylePayload?new WebInspector.CSSStyleDeclaration(this,null,attributesStylePayload,WebInspector.CSSStyleDeclaration.Type.Attributes):null;return new WebInspector.CSSModel.InlineStyleResult(inlineStyle,attributesStyle);}
return this._agent.getInlineStylesForNode(nodeId,callback.bind(this));},forcePseudoState:function(node,pseudoClass,enable)
{var pseudoClasses=node.marker(WebInspector.CSSModel.PseudoStateMarker)||[];if(enable){if(pseudoClasses.indexOf(pseudoClass)>=0)
return false;pseudoClasses.push(pseudoClass);node.setMarker(WebInspector.CSSModel.PseudoStateMarker,pseudoClasses);}else{if(pseudoClasses.indexOf(pseudoClass)<0)
return false;pseudoClasses.remove(pseudoClass);if(pseudoClasses.length)
node.setMarker(WebInspector.CSSModel.PseudoStateMarker,pseudoClasses);else
node.setMarker(WebInspector.CSSModel.PseudoStateMarker,null);}
this._agent.forcePseudoState(node.id,pseudoClasses);this.dispatchEventToListeners(WebInspector.CSSModel.Events.PseudoStateForced,{node:node,pseudoClass:pseudoClass,enable:enable});return true;},pseudoState:function(node)
{return node.marker(WebInspector.CSSModel.PseudoStateMarker)||[];},setMediaText:function(styleSheetId,range,newMediaText)
{function parsePayload(error,mediaPayload)
{if(!mediaPayload)
return false;this._domModel.markUndoableState();var edit=new WebInspector.CSSModel.Edit(styleSheetId,range,newMediaText,mediaPayload);this._fireStyleSheetChangedAndDetach(styleSheetId,edit);return true;}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);return this._ensureOriginalStyleSheetText(styleSheetId).then(()=>this._agent.setMediaText(styleSheetId,range,newMediaText,parsePayload.bind(this))).catchException(false);},addRule:function(styleSheetId,ruleText,ruleLocation)
{return this._ensureOriginalStyleSheetText(styleSheetId).then(()=>this._agent.addRule(styleSheetId,ruleText,ruleLocation,parsePayload.bind(this))).catchException((null))
function parsePayload(error,rulePayload)
{if(error||!rulePayload)
return null;this._domModel.markUndoableState();var edit=new WebInspector.CSSModel.Edit(styleSheetId,ruleLocation,ruleText,rulePayload);this._fireStyleSheetChangedAndDetach(styleSheetId,edit);return new WebInspector.CSSStyleRule(this,rulePayload);}},requestViaInspectorStylesheet:function(node,userCallback)
{var frameId=node.frameId()||this.target().resourceTreeModel.mainFrame.id;var headers=this._styleSheetIdToHeader.valuesArray();for(var i=0;i<headers.length;++i){var styleSheetHeader=headers[i];if(styleSheetHeader.frameId===frameId&&styleSheetHeader.isViaInspector()){userCallback(styleSheetHeader);return;}}
function innerCallback(error,styleSheetId)
{return!error&&styleSheetId?this._styleSheetIdToHeader.get(styleSheetId)||null:null;}
this._agent.createStyleSheet(frameId,innerCallback.bind(this)).catchException(null).then(userCallback)},mediaQueryResultChanged:function()
{this.dispatchEventToListeners(WebInspector.CSSModel.Events.MediaQueryResultChanged);},styleSheetHeaderForId:function(id)
{return this._styleSheetIdToHeader.get(id)||null;},styleSheetHeaders:function()
{return this._styleSheetIdToHeader.valuesArray();},_fireStyleSheetChanged:function(styleSheetId,edit)
{this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged,{styleSheetId:styleSheetId,edit:edit});},_fireStyleSheetChangedAndDetach:function(styleSheetId,edit)
{this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged,{styleSheetId:styleSheetId,edit:edit});var header=this.styleSheetHeaderForId(styleSheetId);if(header)
this._detachSourceMap(header);},_ensureOriginalStyleSheetText:function(styleSheetId)
{var header=this.styleSheetHeaderForId(styleSheetId);if(!header)
return Promise.resolve("");var promise=this._originalStyleSheetText.get(header);if(!promise){promise=this.getStyleSheetText(header.id);this._originalStyleSheetText.set(header,promise);this._originalContentRequestedForTest(header);}
return promise;},_originalContentRequestedForTest:function(header){},originalStyleSheetText:function(header)
{return this._ensureOriginalStyleSheetText(header.id);},_styleSheetAdded:function(header)
{console.assert(!this._styleSheetIdToHeader.get(header.styleSheetId));var styleSheetHeader=new WebInspector.CSSStyleSheetHeader(this,header);this._styleSheetIdToHeader.set(header.styleSheetId,styleSheetHeader);var url=styleSheetHeader.resourceURL();if(!this._styleSheetIdsForURL.get(url))
this._styleSheetIdsForURL.set(url,{});var frameIdToStyleSheetIds=this._styleSheetIdsForURL.get(url);var styleSheetIds=frameIdToStyleSheetIds[styleSheetHeader.frameId];if(!styleSheetIds){styleSheetIds=[];frameIdToStyleSheetIds[styleSheetHeader.frameId]=styleSheetIds;}
styleSheetIds.push(styleSheetHeader.id);this._attachSourceMap(styleSheetHeader);this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetAdded,styleSheetHeader);},_styleSheetRemoved:function(id)
{var header=this._styleSheetIdToHeader.get(id);console.assert(header);if(!header)
return;this._styleSheetIdToHeader.remove(id);var url=header.resourceURL();var frameIdToStyleSheetIds=(this._styleSheetIdsForURL.get(url));console.assert(frameIdToStyleSheetIds,"No frameId to styleSheetId map is available for given style sheet URL.");frameIdToStyleSheetIds[header.frameId].remove(id);if(!frameIdToStyleSheetIds[header.frameId].length){delete frameIdToStyleSheetIds[header.frameId];if(!Object.keys(frameIdToStyleSheetIds).length)
this._styleSheetIdsForURL.remove(url);}
this._originalStyleSheetText.remove(header);this._detachSourceMap(header);this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved,header);},styleSheetIdsForURL:function(url)
{var frameIdToStyleSheetIds=this._styleSheetIdsForURL.get(url);if(!frameIdToStyleSheetIds)
return[];var result=[];for(var frameId in frameIdToStyleSheetIds)
result=result.concat(frameIdToStyleSheetIds[frameId]);return result;},setStyleSheetText:function(styleSheetId,newText,majorChange)
{var header=(this._styleSheetIdToHeader.get(styleSheetId));console.assert(header);newText=WebInspector.CSSModel.trimSourceURL(newText);if(header.hasSourceURL)
newText+="\n/*# sourceURL="+header.sourceURL+" */";return this._ensureOriginalStyleSheetText(styleSheetId).then(()=>this._agent.setStyleSheetText(header.id,newText,callback.bind(this)));function callback(error,sourceMapURL)
{this._detachSourceMap(header);header.setSourceMapURL(sourceMapURL);this._attachSourceMap(header);if(error)
return error;if(majorChange)
this._domModel.markUndoableState();this._fireStyleSheetChanged(styleSheetId);return null;}},getStyleSheetText:function(styleSheetId)
{function textCallback(error,text)
{if(error||text===null){console.error("Failed to get text for stylesheet "+styleSheetId+": "+error)
text="";}
return WebInspector.CSSModel.trimSourceURL(text);}
return this._agent.getStyleSheetText(styleSheetId,textCallback).catchException((""));},_mainFrameNavigated:function()
{this._resetStyleSheets();},_resetStyleSheets:function()
{var headers=this._styleSheetIdToHeader.valuesArray();this._styleSheetIdsForURL.clear();this._styleSheetIdToHeader.clear();for(var i=0;i<headers.length;++i){this._detachSourceMap(headers[i]);this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved,headers[i]);}
this._sourceMapByURL.clear();this._sourceMapURLToHeaders.clear();this._sourceMapLoadingStyleSheetsIds.clear();},suspendModel:function()
{this._isEnabled=false;return this._agent.disable().then(this._resetStyleSheets.bind(this));},resumeModel:function()
{return this._agent.enable().then(this._wasEnabled.bind(this));},_layoutEditorChange:function(id,range)
{this.dispatchEventToListeners(WebInspector.CSSModel.Events.LayoutEditorChange,{id:id,range:range});},setEffectivePropertyValueForNode:function(nodeId,name,value)
{this._agent.setEffectivePropertyValueForNode(nodeId,name,value);},__proto__:WebInspector.SDKModel.prototype}
WebInspector.CSSModel.trimSourceURL=function(text)
{var sourceURLIndex=text.lastIndexOf("/*# sourceURL=");if(sourceURLIndex===-1){sourceURLIndex=text.lastIndexOf("/*@ sourceURL=");if(sourceURLIndex===-1)
return text;}
var sourceURLLineIndex=text.lastIndexOf("\n",sourceURLIndex);if(sourceURLLineIndex===-1)
return text;var sourceURLLine=text.substr(sourceURLLineIndex+1).split("\n",1)[0];var sourceURLRegex=/[\040\t]*\/\*[#@] sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/;if(sourceURLLine.search(sourceURLRegex)===-1)
return text;return text.substr(0,sourceURLLineIndex)+text.substr(sourceURLLineIndex+sourceURLLine.length+1);}
WebInspector.CSSLocation=function(header,lineNumber,columnNumber)
{WebInspector.SDKObject.call(this,header.target());this._header=header;this.styleSheetId=header.id;this.url=header.resourceURL();this.lineNumber=lineNumber;this.columnNumber=columnNumber||0;}
WebInspector.CSSLocation.prototype={cssModel:function()
{return this._header.cssModel();},header:function()
{return this._header;},__proto__:WebInspector.SDKObject.prototype}
WebInspector.CSSDispatcher=function(cssModel)
{this._cssModel=cssModel;}
WebInspector.CSSDispatcher.prototype={mediaQueryResultChanged:function()
{this._cssModel.mediaQueryResultChanged();},styleSheetChanged:function(styleSheetId)
{this._cssModel._fireStyleSheetChangedAndDetach(styleSheetId);},styleSheetAdded:function(header)
{this._cssModel._styleSheetAdded(header);},styleSheetRemoved:function(id)
{this._cssModel._styleSheetRemoved(id);},layoutEditorChange:function(id,range)
{this._cssModel._layoutEditorChange(id,range);},}
WebInspector.CSSModel.ComputedStyleLoader=function(cssModel)
{this._cssModel=cssModel;this._nodeIdToPromise=new Map();}
WebInspector.CSSModel.ComputedStyleLoader.prototype={computedStylePromise:function(nodeId)
{if(!this._nodeIdToPromise.has(nodeId))
this._nodeIdToPromise.set(nodeId,this._cssModel._agent.getComputedStyleForNode(nodeId,parsePayload).then(cleanUp.bind(this)));return(this._nodeIdToPromise.get(nodeId));function parsePayload(error,computedPayload)
{if(error||!computedPayload||!computedPayload.length)
return null;var result=new Map();for(var property of computedPayload)
result.set(property.name,property.value);return result;}
function cleanUp(computedStyle)
{this._nodeIdToPromise.delete(nodeId);return computedStyle;}}}
WebInspector.CSSModel.fromTarget=function(target)
{if(!target.isPage())
return null;return(target.model(WebInspector.CSSModel));}
WebInspector.CSSModel.fromNode=function(node)
{return(WebInspector.CSSModel.fromTarget(node.target()));}
WebInspector.CSSModel.InlineStyleResult=function(inlineStyle,attributesStyle)
{this.inlineStyle=inlineStyle;this.attributesStyle=attributesStyle;};WebInspector.CSSParser=function()
{this._rules=[];this._terminated=false;}
WebInspector.CSSParser.Events={RulesParsed:"RulesParsed"}
WebInspector.CSSParser.prototype={fetchAndParse:function(styleSheetHeader,callback)
{this._lock();this._finishedCallback=callback;styleSheetHeader.requestContent().then(this._innerParse.bind(this));},parse:function(text,callback)
{this._lock();this._finishedCallback=callback;this._innerParse(text);},parsePromise:function(text)
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(succ,fail)
{this.parse(text,succ);}},dispose:function()
{if(this._terminated)
return;this._terminated=true;this._runFinishedCallback([]);},rules:function()
{return this._rules;},_lock:function()
{console.assert(!this._parsingStyleSheet,"Received request to parse stylesheet before previous was completed.");this._parsingStyleSheet=true;},_unlock:function()
{delete this._parsingStyleSheet;},_innerParse:function(text)
{this._rules=[];var params={content:text};WebInspector.formatterWorkerPool.runChunkedTask("parseCSS",params,this._onRuleChunk.bind(this));},_onRuleChunk:function(event)
{if(this._terminated)
return;if(!event){this._onFinishedParsing();this.dispatchEventToListeners(WebInspector.CSSParser.Events.RulesParsed);return;}
var data=(event.data);var chunk=data.chunk;for(var i=0;i<chunk.length;++i)
this._rules.push(chunk[i]);if(data.isLastChunk)
this._onFinishedParsing();this.dispatchEventToListeners(WebInspector.CSSParser.Events.RulesParsed);},_onFinishedParsing:function()
{this._unlock();this._runFinishedCallback(this._rules);},_runFinishedCallback:function(rules)
{var callback=this._finishedCallback;delete this._finishedCallback;if(callback)
callback.call(null,rules);},__proto__:WebInspector.Object.prototype,}
WebInspector.CSSParser.DataChunk;WebInspector.CSSParser.StyleRule=function()
{this.selectorText;this.styleRange;this.lineNumber;this.columnNumber;this.properties;}
WebInspector.CSSParser.AtRule;WebInspector.CSSParser.Rule;WebInspector.CSSParser.Range;WebInspector.CSSParser.Property=function()
{this.name;this.nameRange;this.value;this.valueRange;this.range;this.disabled;};WebInspector.CSSProperty=function(ownerStyle,index,name,value,important,disabled,parsedOk,implicit,text,range)
{this.ownerStyle=ownerStyle;this.index=index;this.name=name;this.value=value;this.important=important;this.disabled=disabled;this.parsedOk=parsedOk;this.implicit=implicit;this.text=text;this.range=range?WebInspector.TextRange.fromObject(range):null;this._active=true;this._nameRange=null;this._valueRange=null;}
WebInspector.CSSProperty.parsePayload=function(ownerStyle,index,payload)
{var result=new WebInspector.CSSProperty(ownerStyle,index,payload.name,payload.value,payload.important||false,payload.disabled||false,("parsedOk"in payload)?!!payload.parsedOk:true,!!payload.implicit,payload.text,payload.range);return result;}
WebInspector.CSSProperty.prototype={_ensureRanges:function()
{if(this._nameRange&&this._valueRange)
return;var range=this.range;var text=this.text?new WebInspector.Text(this.text):null;if(!range||!text)
return;var nameIndex=text.value().indexOf(this.name);var valueIndex=text.value().lastIndexOf(this.value);if(nameIndex===-1||valueIndex===-1||nameIndex>valueIndex)
return;var nameSourceRange=new WebInspector.SourceRange(nameIndex,this.name.length);var valueSourceRange=new WebInspector.SourceRange(valueIndex,this.value.length);this._nameRange=rebase(text.toTextRange(nameSourceRange),range.startLine,range.startColumn);this._valueRange=rebase(text.toTextRange(valueSourceRange),range.startLine,range.startColumn);function rebase(oneLineRange,lineOffset,columnOffset)
{if(oneLineRange.startLine===0){oneLineRange.startColumn+=columnOffset;oneLineRange.endColumn+=columnOffset;}
oneLineRange.startLine+=lineOffset;oneLineRange.endLine+=lineOffset;return oneLineRange;}},nameRange:function()
{this._ensureRanges();return this._nameRange;},valueRange:function()
{this._ensureRanges();return this._valueRange;},rebase:function(edit)
{if(this.ownerStyle.styleSheetId!==edit.styleSheetId)
return;if(this.range)
this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);},_setActive:function(active)
{this._active=active;},get propertyText()
{if(this.text!==undefined)
return this.text;if(this.name==="")
return"";return this.name+": "+this.value+(this.important?" !important":"")+";";},activeInStyle:function()
{return this._active;},setText:function(propertyText,majorChange,overwrite)
{if(!this.ownerStyle)
return Promise.reject(new Error("No ownerStyle for property"));if(!this.ownerStyle.styleSheetId)
return Promise.reject(new Error("No owner style id"));if(!this.range||!this.ownerStyle.range)
return Promise.reject(new Error("Style not editable"));if(majorChange)
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);if(overwrite&&propertyText===this.propertyText){if(majorChange)
this.ownerStyle.cssModel().domModel().markUndoableState();return Promise.resolve(true);}
var range=this.range.relativeTo(this.ownerStyle.range.startLine,this.ownerStyle.range.startColumn);var indentation=this.ownerStyle.cssText?this._detectIndentation(this.ownerStyle.cssText):WebInspector.moduleSetting("textEditorIndent").get();var endIndentation=this.ownerStyle.cssText?indentation.substring(0,this.ownerStyle.range.endColumn):"";var text=new WebInspector.Text(this.ownerStyle.cssText||"");var newStyleText=text.replaceRange(range,String.sprintf(";%s;",propertyText));return self.runtime.instancePromise(WebInspector.TokenizerFactory).then(this._formatStyle.bind(this,newStyleText,indentation,endIndentation)).then(setStyleText.bind(this));function setStyleText(styleText)
{return this.ownerStyle.setText(styleText,majorChange);}},_formatStyle:function(styleText,indentation,endIndentation,tokenizerFactory)
{if(indentation)
indentation="\n"+indentation;var result="";var propertyText;var insideProperty=false;var tokenize=tokenizerFactory.createTokenizer("text/css");tokenize("*{"+styleText+"}",processToken);if(insideProperty)
result+=propertyText;result=result.substring(2,result.length-1).trimRight();return result+(indentation?"\n"+endIndentation:"");function processToken(token,tokenType,column,newColumn)
{if(!insideProperty){var disabledProperty=tokenType&&tokenType.includes("css-comment")&&isDisabledProperty(token);var isPropertyStart=tokenType&&(tokenType.includes("css-string")||tokenType.includes("css-meta")||tokenType.includes("css-property")||tokenType.includes("css-variable-2"));if(disabledProperty){result=result.trimRight()+indentation+token;}else if(isPropertyStart){insideProperty=true;propertyText=token;}else if(token!==";"){result+=token;}
return;}
if(token==="}"||token===";"){result=result.trimRight()+indentation+propertyText.trim()+";";insideProperty=false;if(token==="}")
result+="}";}else{propertyText+=token;}}
function isDisabledProperty(text)
{var colon=text.indexOf(":");if(colon===-1)
return false;var propertyName=text.substring(2,colon).trim();return WebInspector.CSSMetadata.isCSSPropertyName(propertyName);}},_detectIndentation:function(text)
{var lines=text.split("\n");if(lines.length<2)
return"";return WebInspector.TextUtils.lineIndent(lines[1]);},setValue:function(newValue,majorChange,overwrite,userCallback)
{var text=this.name+": "+newValue+(this.important?" !important":"")+";";this.setText(text,majorChange,overwrite).then(userCallback);},setDisabled:function(disabled)
{if(!this.ownerStyle)
return Promise.resolve(false);if(disabled===this.disabled)
return Promise.resolve(true);var propertyText=this.text.trim();var text=disabled?"/* "+propertyText+" */":this.text.substring(2,propertyText.length-2).trim();return this.setText(text,true,true);}};WebInspector.CSSValue=function(payload)
{this.text=payload.text;if(payload.range)
this.range=WebInspector.TextRange.fromObject(payload.range);}
WebInspector.CSSValue.prototype={rebase:function(edit)
{if(!this.range)
return;this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);}}
WebInspector.CSSRule=function(cssModel,payload)
{this._cssModel=cssModel;this.styleSheetId=payload.styleSheetId;if(this.styleSheetId){var styleSheetHeader=cssModel.styleSheetHeaderForId(this.styleSheetId);this.sourceURL=styleSheetHeader.sourceURL;}
this.origin=payload.origin;this.style=new WebInspector.CSSStyleDeclaration(this._cssModel,this,payload.style,WebInspector.CSSStyleDeclaration.Type.Regular);}
WebInspector.CSSRule.prototype={rebase:function(edit)
{if(this.styleSheetId!==edit.styleSheetId)
return;this.style.rebase(edit);},resourceURL:function()
{if(!this.styleSheetId)
return"";var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);return styleSheetHeader.resourceURL();},isUserAgent:function()
{return this.origin===CSSAgent.StyleSheetOrigin.UserAgent;},isInjected:function()
{return this.origin===CSSAgent.StyleSheetOrigin.Injected;},isViaInspector:function()
{return this.origin===CSSAgent.StyleSheetOrigin.Inspector;},isRegular:function()
{return this.origin===CSSAgent.StyleSheetOrigin.Regular;}}
WebInspector.CSSStyleRule=function(cssModel,payload)
{WebInspector.CSSRule.call(this,cssModel,payload);this._reinitializeSelectors(payload.selectorList);this.media=payload.media?WebInspector.CSSMedia.parseMediaArrayPayload(cssModel,payload.media):[];}
WebInspector.CSSStyleRule.createDummyRule=function(cssModel,selectorText)
{var dummyPayload={selectorList:{selectors:[{text:selectorText}],},style:{styleSheetId:"0",range:new WebInspector.TextRange(0,0,0,0),shorthandEntries:[],cssProperties:[]}};return new WebInspector.CSSStyleRule(cssModel,(dummyPayload));}
WebInspector.CSSStyleRule.prototype={_reinitializeSelectors:function(selectorList)
{this.selectors=[];for(var i=0;i<selectorList.selectors.length;++i)
this.selectors.push(new WebInspector.CSSValue(selectorList.selectors[i]));},setSelectorText:function(newSelector)
{var styleSheetId=this.styleSheetId;if(!styleSheetId)
throw"No rule stylesheet id";var range=this.selectorRange();if(!range)
throw"Rule selector is not editable";return this._cssModel.setSelectorText(styleSheetId,range,newSelector);},selectorText:function()
{return this.selectors.select("text").join(", ");},selectorRange:function()
{var firstRange=this.selectors[0].range;if(!firstRange)
return null;var lastRange=this.selectors.peekLast().range;return new WebInspector.TextRange(firstRange.startLine,firstRange.startColumn,lastRange.endLine,lastRange.endColumn);},lineNumberInSource:function(selectorIndex)
{var selector=this.selectors[selectorIndex];if(!selector||!selector.range||!this.styleSheetId)
return 0;var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);return styleSheetHeader.lineNumberInSource(selector.range.startLine);},columnNumberInSource:function(selectorIndex)
{var selector=this.selectors[selectorIndex];if(!selector||!selector.range||!this.styleSheetId)
return undefined;var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);console.assert(styleSheetHeader);return styleSheetHeader.columnNumberInSource(selector.range.startLine,selector.range.startColumn);},rebase:function(edit)
{if(this.styleSheetId!==edit.styleSheetId)
return;if(this.selectorRange().equal(edit.oldRange)){this._reinitializeSelectors((edit.payload));}else{for(var i=0;i<this.selectors.length;++i)
this.selectors[i].rebase(edit);}
for(var media of this.media)
media.rebase(edit);WebInspector.CSSRule.prototype.rebase.call(this,edit);},__proto__:WebInspector.CSSRule.prototype}
WebInspector.CSSKeyframesRule=function(cssModel,payload)
{this._cssModel=cssModel;this._animationName=new WebInspector.CSSValue(payload.animationName);this._keyframes=payload.keyframes.map(keyframeRule=>new WebInspector.CSSKeyframeRule(cssModel,keyframeRule));}
WebInspector.CSSKeyframesRule.prototype={name:function()
{return this._animationName;},keyframes:function()
{return this._keyframes;}}
WebInspector.CSSKeyframeRule=function(cssModel,payload)
{WebInspector.CSSRule.call(this,cssModel,payload);this._reinitializeKey(payload.keyText);}
WebInspector.CSSKeyframeRule.prototype={key:function()
{return this._keyText;},_reinitializeKey:function(payload)
{this._keyText=new WebInspector.CSSValue(payload);},rebase:function(edit)
{if(this.styleSheetId!==edit.styleSheetId||!this._keyText.range)
return;if(edit.oldRange.equal(this._keyText.range))
this._reinitializeKey((edit.payload));else
this._keyText.rebase(edit);WebInspector.CSSRule.prototype.rebase.call(this,edit);},setKeyText:function(newKeyText)
{var styleSheetId=this.styleSheetId;if(!styleSheetId)
throw"No rule stylesheet id";var range=this._keyText.range;if(!range)
throw"Keyframe key is not editable";return this._cssModel.setKeyframeKey(styleSheetId,range,newKeyText);},__proto__:WebInspector.CSSRule.prototype};WebInspector.CSSStyleDeclaration=function(cssModel,parentRule,payload,type)
{this._cssModel=cssModel;this.parentRule=parentRule;this._reinitialize(payload);this.type=type;}
WebInspector.CSSStyleDeclaration.Type={Regular:"Regular",Inline:"Inline",Attributes:"Attributes"}
WebInspector.CSSStyleDeclaration.prototype={rebase:function(edit)
{if(this.styleSheetId!==edit.styleSheetId||!this.range)
return;if(edit.oldRange.equal(this.range)){this._reinitialize((edit.payload));}else{this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);for(var i=0;i<this._allProperties.length;++i)
this._allProperties[i].rebase(edit);}},_reinitialize:function(payload)
{this.styleSheetId=payload.styleSheetId;this.range=payload.range?WebInspector.TextRange.fromObject(payload.range):null;var shorthandEntries=payload.shorthandEntries;this._shorthandValues=new Map();this._shorthandIsImportant=new Set();for(var i=0;i<shorthandEntries.length;++i){this._shorthandValues.set(shorthandEntries[i].name,shorthandEntries[i].value);if(shorthandEntries[i].important)
this._shorthandIsImportant.add(shorthandEntries[i].name);}
this._allProperties=[];for(var i=0;i<payload.cssProperties.length;++i){var property=WebInspector.CSSProperty.parsePayload(this,i,payload.cssProperties[i]);this._allProperties.push(property);}
this._generateSyntheticPropertiesIfNeeded();this._computeInactiveProperties();this._activePropertyMap=new Map();for(var property of this._allProperties){if(!property.activeInStyle())
continue;this._activePropertyMap.set(property.name,property);}
this.cssText=payload.cssText;this._leadingProperties=null;},_generateSyntheticPropertiesIfNeeded:function()
{if(this.range)
return;if(!this._shorthandValues.size)
return;var propertiesSet=new Set();for(var property of this._allProperties)
propertiesSet.add(property.name);var generatedProperties=[];for(var property of this._allProperties){var shorthands=WebInspector.CSSMetadata.cssPropertiesMetainfo.shorthands(property.name)||[];for(var shorthand of shorthands){if(propertiesSet.has(shorthand))
continue;var shorthandValue=this._shorthandValues.get(shorthand);if(!shorthandValue)
continue;var shorthandImportance=!!this._shorthandIsImportant.has(shorthand);var shorthandProperty=new WebInspector.CSSProperty(this,this.allProperties.length,shorthand,shorthandValue,shorthandImportance,false,true,false);generatedProperties.push(shorthandProperty);propertiesSet.add(shorthand);}}
this._allProperties=this._allProperties.concat(generatedProperties);},_computeLeadingProperties:function()
{function propertyHasRange(property)
{return!!property.range;}
if(this.range)
return this._allProperties.filter(propertyHasRange);var leadingProperties=[];for(var property of this._allProperties){var shorthands=WebInspector.CSSMetadata.cssPropertiesMetainfo.shorthands(property.name)||[];var belongToAnyShorthand=false;for(var shorthand of shorthands){if(this._shorthandValues.get(shorthand)){belongToAnyShorthand=true;break;}}
if(!belongToAnyShorthand)
leadingProperties.push(property);}
return leadingProperties;},leadingProperties:function()
{if(!this._leadingProperties)
this._leadingProperties=this._computeLeadingProperties();return this._leadingProperties;},target:function()
{return this._cssModel.target();},cssModel:function()
{return this._cssModel;},_computeInactiveProperties:function()
{var activeProperties={};for(var i=0;i<this._allProperties.length;++i){var property=this._allProperties[i];if(property.disabled||!property.parsedOk){property._setActive(false);continue;}
var canonicalName=WebInspector.CSSMetadata.canonicalPropertyName(property.name);var activeProperty=activeProperties[canonicalName];if(!activeProperty){activeProperties[canonicalName]=property;}else if(!activeProperty.important||property.important){activeProperty._setActive(false);activeProperties[canonicalName]=property;}else{property._setActive(false);}}},get allProperties()
{return this._allProperties;},getPropertyValue:function(name)
{var property=this._activePropertyMap.get(name);return property?property.value:"";},isPropertyImplicit:function(name)
{var property=this._activePropertyMap.get(name);return property?property.implicit:"";},longhandProperties:function(name)
{var longhands=WebInspector.CSSMetadata.cssPropertiesMetainfo.longhands(name);var result=[];for(var i=0;longhands&&i<longhands.length;++i){var property=this._activePropertyMap.get(longhands[i]);if(property)
result.push(property);}
return result;},propertyAt:function(index)
{return(index<this.allProperties.length)?this.allProperties[index]:null;},pastLastSourcePropertyIndex:function()
{for(var i=this.allProperties.length-1;i>=0;--i){if(this.allProperties[i].range)
return i+1;}
return 0;},_insertionRange:function(index)
{var property=this.propertyAt(index);return property&&property.range?property.range.collapseToStart():this.range.collapseToEnd();},newBlankProperty:function(index)
{index=(typeof index==="undefined")?this.pastLastSourcePropertyIndex():index;var property=new WebInspector.CSSProperty(this,index,"","",false,false,true,false,"",this._insertionRange(index));return property;},setText:function(text,majorChange)
{return this._cssModel.setStyleText(this.styleSheetId,this.range,text,majorChange)},insertPropertyAt:function(index,name,value,userCallback)
{this.newBlankProperty(index).setText(name+": "+value+";",false,true).then(userCallback);},appendProperty:function(name,value,userCallback)
{this.insertPropertyAt(this.allProperties.length,name,value,userCallback);}};WebInspector.CSSStyleSheetHeader=function(cssModel,payload)
{this._cssModel=cssModel;this.id=payload.styleSheetId;this.frameId=payload.frameId;this.sourceURL=payload.sourceURL;this.hasSourceURL=!!payload.hasSourceURL;this.origin=payload.origin;this.title=payload.title;this.disabled=payload.disabled;this.isInline=payload.isInline;this.startLine=payload.startLine;this.startColumn=payload.startColumn;if(payload.ownerNode)
this.ownerNode=new WebInspector.DeferredDOMNode(cssModel.target(),payload.ownerNode);this.setSourceMapURL(payload.sourceMapURL);}
WebInspector.CSSStyleSheetHeader.prototype={originalContentProvider:function()
{if(!this._originalContentProvider){var lazyContent=this._cssModel.originalStyleSheetText.bind(this._cssModel,this);this._originalContentProvider=new WebInspector.StaticContentProvider(this.contentURL(),this.contentType(),lazyContent);}
return this._originalContentProvider;},setSourceMapURL:function(sourceMapURL)
{var completeSourceMapURL=this.sourceURL&&sourceMapURL?WebInspector.ParsedURL.completeURL(this.sourceURL,sourceMapURL):null;this.sourceMapURL=completeSourceMapURL;},target:function()
{return this._cssModel.target();},cssModel:function()
{return this._cssModel;},resourceURL:function()
{return this.isViaInspector()?this._viaInspectorResourceURL():this.sourceURL;},_viaInspectorResourceURL:function()
{var frame=this._cssModel.target().resourceTreeModel.frameForId(this.frameId);console.assert(frame);var parsedURL=new WebInspector.ParsedURL(frame.url);var fakeURL="inspector://"+parsedURL.host+parsedURL.folderPathComponents;if(!fakeURL.endsWith("/"))
fakeURL+="/";fakeURL+="inspector-stylesheet";return fakeURL;},lineNumberInSource:function(lineNumberInStyleSheet)
{return this.startLine+lineNumberInStyleSheet;},columnNumberInSource:function(lineNumberInStyleSheet,columnNumberInStyleSheet)
{return(lineNumberInStyleSheet?0:this.startColumn)+columnNumberInStyleSheet;},contentURL:function()
{return this.resourceURL();},contentType:function()
{return WebInspector.resourceTypes.Stylesheet;},requestContent:function()
{return(this._cssModel.getStyleSheetText(this.id));},searchInContent:function(query,caseSensitive,isRegex,callback)
{function performSearch(content)
{callback(WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex));}
this.requestContent().then(performSearch);},isViaInspector:function()
{return this.origin==="inspector";}}
WebInspector.CSSStyleSheetHeader.OriginalContentProvider=function(header)
{this._header=header;}
WebInspector.CSSStyleSheetHeader.OriginalContentProvider.prototype={contentURL:function()
{return this._header.contentURL();},contentType:function()
{return this._header.contentType();},requestContent:function()
{return(this._header.cssModel().originalStyleSheetText(this._header));},searchInContent:function(query,caseSensitive,isRegex,callback)
{function performSearch(content)
{var searchResults=content?WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex):[];callback(searchResults);}
this.requestContent().then(performSearch);}};WebInspector.DOMNode=function(domModel,doc,isInShadowTree,payload)
{WebInspector.SDKObject.call(this,domModel.target());this._domModel=domModel;this._agent=domModel._agent;this.ownerDocument=doc;this._isInShadowTree=isInShadowTree;this.id=payload.nodeId;domModel._idToDOMNode[this.id]=this;this._nodeType=payload.nodeType;this._nodeName=payload.nodeName;this._localName=payload.localName;this._nodeValue=payload.nodeValue;this._pseudoType=payload.pseudoType;this._shadowRootType=payload.shadowRootType;this._frameId=payload.frameId||null;this._xmlVersion=payload.xmlVersion;this._shadowRoots=[];this._attributes=[];this._attributesMap={};if(payload.attributes)
this._setAttributesPayload(payload.attributes);this._markers=new Map();this._subtreeMarkerCount=0;this._childNodeCount=payload.childNodeCount||0;this._children=null;this.nextSibling=null;this.previousSibling=null;this.firstChild=null;this.lastChild=null;this.parentNode=null;if(payload.shadowRoots){for(var i=0;i<payload.shadowRoots.length;++i){var root=payload.shadowRoots[i];var node=new WebInspector.DOMNode(this._domModel,this.ownerDocument,true,root);this._shadowRoots.push(node);node.parentNode=this;}}
if(payload.templateContent){this._templateContent=new WebInspector.DOMNode(this._domModel,this.ownerDocument,true,payload.templateContent);this._templateContent.parentNode=this;}
if(payload.importedDocument){this._importedDocument=new WebInspector.DOMNode(this._domModel,this.ownerDocument,true,payload.importedDocument);this._importedDocument.parentNode=this;}
if(payload.distributedNodes)
this._setDistributedNodePayloads(payload.distributedNodes);if(payload.children)
this._setChildrenPayload(payload.children);this._setPseudoElements(payload.pseudoElements);if(payload.contentDocument){this._contentDocument=new WebInspector.DOMDocument(domModel,payload.contentDocument);this._children=[this._contentDocument];this._renumber();}
if(this._nodeType===Node.ELEMENT_NODE){if(this.ownerDocument&&!this.ownerDocument.documentElement&&this._nodeName==="HTML")
this.ownerDocument.documentElement=this;if(this.ownerDocument&&!this.ownerDocument.body&&this._nodeName==="BODY")
this.ownerDocument.body=this;}else if(this._nodeType===Node.DOCUMENT_TYPE_NODE){this.publicId=payload.publicId;this.systemId=payload.systemId;this.internalSubset=payload.internalSubset;}else if(this._nodeType===Node.ATTRIBUTE_NODE){this.name=payload.name;this.value=payload.value;}}
WebInspector.DOMNode.PseudoElementNames={Before:"before",After:"after"}
WebInspector.DOMNode.ShadowRootTypes={UserAgent:"user-agent",Open:"open",Closed:"closed"}
WebInspector.DOMNode.prototype={domModel:function()
{return this._domModel;},children:function()
{return this._children?this._children.slice():null;},hasAttributes:function()
{return this._attributes.length>0;},childNodeCount:function()
{return this._childNodeCount;},hasShadowRoots:function()
{return!!this._shadowRoots.length;},shadowRoots:function()
{return this._shadowRoots.slice();},templateContent:function()
{return this._templateContent||null;},importedDocument:function()
{return this._importedDocument||null;},nodeType:function()
{return this._nodeType;},nodeName:function()
{return this._nodeName;},pseudoType:function()
{return this._pseudoType;},hasPseudoElements:function()
{return this._pseudoElements.size>0;},pseudoElements:function()
{return this._pseudoElements;},beforePseudoElement:function()
{if(!this._pseudoElements)
return null;return this._pseudoElements.get(WebInspector.DOMNode.PseudoElementNames.Before);},afterPseudoElement:function()
{if(!this._pseudoElements)
return null;return this._pseudoElements.get(WebInspector.DOMNode.PseudoElementNames.After);},isInsertionPoint:function()
{return!this.isXMLNode()&&(this._nodeName==="SHADOW"||this._nodeName==="CONTENT");},distributedNodes:function()
{return this._distributedNodes||[];},isInShadowTree:function()
{return this._isInShadowTree;},ancestorShadowHost:function()
{var ancestorShadowRoot=this.ancestorShadowRoot();return ancestorShadowRoot?ancestorShadowRoot.parentNode:null;},ancestorShadowRoot:function()
{if(!this._isInShadowTree)
return null;var current=this;while(current&&!current.isShadowRoot())
current=current.parentNode;return current;},ancestorUserAgentShadowRoot:function()
{var ancestorShadowRoot=this.ancestorShadowRoot();if(!ancestorShadowRoot)
return null;return ancestorShadowRoot.shadowRootType()===WebInspector.DOMNode.ShadowRootTypes.UserAgent?ancestorShadowRoot:null;},isShadowRoot:function()
{return!!this._shadowRootType;},shadowRootType:function()
{return this._shadowRootType||null;},nodeNameInCorrectCase:function()
{var shadowRootType=this.shadowRootType();if(shadowRootType)
return"#shadow-root ("+shadowRootType+")";return this.isXMLNode()?this.nodeName():this.nodeName().toLowerCase();},setNodeName:function(name,callback)
{this._agent.setNodeName(this.id,name,this._domModel._markRevision(this,callback));},localName:function()
{return this._localName;},nodeValue:function()
{return this._nodeValue;},setNodeValue:function(value,callback)
{this._agent.setNodeValue(this.id,value,this._domModel._markRevision(this,callback));},getAttribute:function(name)
{var attr=this._attributesMap[name];return attr?attr.value:undefined;},setAttribute:function(name,text,callback)
{this._agent.setAttributesAsText(this.id,text,name,this._domModel._markRevision(this,callback));},setAttributeValue:function(name,value,callback)
{this._agent.setAttributeValue(this.id,name,value,this._domModel._markRevision(this,callback));},attributes:function()
{return this._attributes;},removeAttribute:function(name,callback)
{function mycallback(error)
{if(!error){delete this._attributesMap[name];for(var i=0;i<this._attributes.length;++i){if(this._attributes[i].name===name){this._attributes.splice(i,1);break;}}}
this._domModel._markRevision(this,callback)(error);}
this._agent.removeAttribute(this.id,name,mycallback.bind(this));},getChildNodes:function(callback)
{if(this._children){if(callback)
callback(this.children());return;}
function mycallback(error)
{if(callback)
callback(error?null:this.children());}
this._agent.requestChildNodes(this.id,undefined,mycallback.bind(this));},getSubtree:function(depth,callback)
{function mycallback(error)
{if(callback)
callback(error?null:this._children);}
this._agent.requestChildNodes(this.id,depth,mycallback.bind(this));},getOuterHTML:function(callback)
{this._agent.getOuterHTML(this.id,callback);},setOuterHTML:function(html,callback)
{this._agent.setOuterHTML(this.id,html,this._domModel._markRevision(this,callback));},removeNode:function(callback)
{this._agent.removeNode(this.id,this._domModel._markRevision(this,callback));},copyNode:function(callback)
{function copy(error,text)
{if(!error)
InspectorFrontendHost.copyText(text);if(callback)
callback(error?null:text);}
this._agent.getOuterHTML(this.id,copy);},path:function()
{function canPush(node)
{return node&&("index"in node||(node.isShadowRoot()&&node.parentNode))&&node._nodeName.length;}
var path=[];var node=this;while(canPush(node)){var index=typeof node.index==="number"?node.index:(node.shadowRootType()===WebInspector.DOMNode.ShadowRootTypes.UserAgent?"u":"a");path.push([index,node._nodeName]);node=node.parentNode;}
path.reverse();return path.join(",");},isAncestor:function(node)
{if(!node)
return false;var currentNode=node.parentNode;while(currentNode){if(this===currentNode)
return true;currentNode=currentNode.parentNode;}
return false;},isDescendant:function(descendant)
{return descendant!==null&&descendant.isAncestor(this);},frameId:function()
{var node=this;while(!node._frameId&&node.parentNode)
node=node.parentNode;return node._frameId;},_setAttributesPayload:function(attrs)
{var attributesChanged=!this._attributes||attrs.length!==this._attributes.length*2;var oldAttributesMap=this._attributesMap||{};this._attributes=[];this._attributesMap={};for(var i=0;i<attrs.length;i+=2){var name=attrs[i];var value=attrs[i+1];this._addAttribute(name,value);if(attributesChanged)
continue;if(!oldAttributesMap[name]||oldAttributesMap[name].value!==value)
attributesChanged=true;}
return attributesChanged;},_insertChild:function(prev,payload)
{var node=new WebInspector.DOMNode(this._domModel,this.ownerDocument,this._isInShadowTree,payload);this._children.splice(this._children.indexOf(prev)+1,0,node);this._renumber();return node;},_removeChild:function(node)
{if(node.pseudoType()){this._pseudoElements.delete(node.pseudoType());}else{var shadowRootIndex=this._shadowRoots.indexOf(node);if(shadowRootIndex!==-1){this._shadowRoots.splice(shadowRootIndex,1);}else{console.assert(this._children.indexOf(node)!==-1);this._children.splice(this._children.indexOf(node),1);}}
node.parentNode=null;this._subtreeMarkerCount-=node._subtreeMarkerCount;if(node._subtreeMarkerCount)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged,this);this._renumber();},_setChildrenPayload:function(payloads)
{if(this._contentDocument)
return;this._children=[];for(var i=0;i<payloads.length;++i){var payload=payloads[i];var node=new WebInspector.DOMNode(this._domModel,this.ownerDocument,this._isInShadowTree,payload);this._children.push(node);}
this._renumber();},_setPseudoElements:function(payloads)
{this._pseudoElements=new Map();if(!payloads)
return;for(var i=0;i<payloads.length;++i){var node=new WebInspector.DOMNode(this._domModel,this.ownerDocument,this._isInShadowTree,payloads[i]);node.parentNode=this;this._pseudoElements.set(node.pseudoType(),node);}},_setDistributedNodePayloads:function(payloads)
{this._distributedNodes=[];for(var payload of payloads)
this._distributedNodes.push(new WebInspector.DOMNodeShortcut(this._domModel.target(),payload.backendNodeId,payload.nodeType,payload.nodeName));},_renumber:function()
{this._childNodeCount=this._children.length;if(this._childNodeCount==0){this.firstChild=null;this.lastChild=null;return;}
this.firstChild=this._children[0];this.lastChild=this._children[this._childNodeCount-1];for(var i=0;i<this._childNodeCount;++i){var child=this._children[i];child.index=i;child.nextSibling=i+1<this._childNodeCount?this._children[i+1]:null;child.previousSibling=i-1>=0?this._children[i-1]:null;child.parentNode=this;}},_addAttribute:function(name,value)
{var attr={name:name,value:value,_node:this};this._attributesMap[name]=attr;this._attributes.push(attr);},_setAttribute:function(name,value)
{var attr=this._attributesMap[name];if(attr)
attr.value=value;else
this._addAttribute(name,value);},_removeAttribute:function(name)
{var attr=this._attributesMap[name];if(attr){this._attributes.remove(attr);delete this._attributesMap[name];}},copyTo:function(targetNode,anchorNode,callback)
{this._agent.copyTo(this.id,targetNode.id,anchorNode?anchorNode.id:undefined,this._domModel._markRevision(this,callback));},moveTo:function(targetNode,anchorNode,callback)
{this._agent.moveTo(this.id,targetNode.id,anchorNode?anchorNode.id:undefined,this._domModel._markRevision(this,callback));},isXMLNode:function()
{return!!this._xmlVersion;},setMarker:function(name,value)
{if(value===null){if(!this._markers.has(name))
return;this._markers.delete(name);for(var node=this;node;node=node.parentNode)
--node._subtreeMarkerCount;for(var node=this;node;node=node.parentNode)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged,node);return;}
if(this.parentNode&&!this._markers.has(name)){for(var node=this;node;node=node.parentNode)
++node._subtreeMarkerCount;}
this._markers.set(name,value);for(var node=this;node;node=node.parentNode)
this._domModel.dispatchEventToListeners(WebInspector.DOMModel.Events.MarkersChanged,node);},marker:function(name)
{return this._markers.get(name)||null;},traverseMarkers:function(visitor)
{function traverse(node)
{if(!node._subtreeMarkerCount)
return;for(var marker of node._markers.keys())
visitor(node,marker);if(!node._children)
return;for(var child of node._children)
traverse(child);}
traverse(this);},resolveURL:function(url)
{if(!url)
return url;for(var frameOwnerCandidate=this;frameOwnerCandidate;frameOwnerCandidate=frameOwnerCandidate.parentNode){if(frameOwnerCandidate.baseURL)
return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL,url);}
return null;},highlight:function(mode,objectId)
{this._domModel.highlightDOMNode(this.id,mode,undefined,objectId);},highlightForTwoSeconds:function()
{this._domModel.highlightDOMNodeForTwoSeconds(this.id);},resolveToObject:function(objectGroup,callback)
{this._agent.resolveNode(this.id,objectGroup,mycallback.bind(this));function mycallback(error,object)
{if(!callback)
return;if(error||!object)
callback(null);else
callback(this.target().runtimeModel.createRemoteObject(object));}},resolveToObjectPromise:function(objectGroup)
{return new Promise(resolveToObject.bind(this));function resolveToObject(fulfill,reject)
{this.resolveToObject(objectGroup,mycallback);function mycallback(object)
{if(object)
fulfill(object)
else
reject(null);}}},boxModel:function(callback)
{this._agent.getBoxModel(this.id,this._domModel._wrapClientCallback(callback));},setAsInspectedNode:function()
{var node=this;while(true){var ancestor=node.ancestorUserAgentShadowRoot();if(!ancestor)
break;ancestor=node.ancestorShadowHost();if(!ancestor)
break
node=ancestor;}
this._agent.setInspectedNode(node.id);},__proto__:WebInspector.SDKObject.prototype}
WebInspector.DeferredDOMNode=function(target,backendNodeId)
{this._domModel=WebInspector.DOMModel.fromTarget(target);this._backendNodeId=backendNodeId;}
WebInspector.DeferredDOMNode.prototype={resolve:function(callback)
{if(!this._domModel){callback(null);return;}
this._domModel.pushNodesByBackendIdsToFrontend(new Set([this._backendNodeId]),onGotNode.bind(this));function onGotNode(nodeIds)
{callback(nodeIds&&(nodeIds.get(this._backendNodeId)||null));}},resolvePromise:function()
{function resolveNode(fulfill,reject)
{function mycallback(node)
{fulfill(node)}
this.resolve(mycallback);}
return new Promise(resolveNode.bind(this));},backendNodeId:function()
{return this._backendNodeId;},highlight:function()
{if(this._domModel)
this._domModel.highlightDOMNode(undefined,undefined,this._backendNodeId);}}
WebInspector.DOMNodeShortcut=function(target,backendNodeId,nodeType,nodeName)
{this.nodeType=nodeType;this.nodeName=nodeName;this.deferredNode=new WebInspector.DeferredDOMNode(target,backendNodeId);}
WebInspector.DOMDocument=function(domModel,payload)
{WebInspector.DOMNode.call(this,domModel,this,false,payload);this.documentURL=payload.documentURL||"";this.baseURL=payload.baseURL||"";this._listeners={};}
WebInspector.DOMDocument.prototype={__proto__:WebInspector.DOMNode.prototype}
WebInspector.DOMModel=function(target){WebInspector.SDKModel.call(this,WebInspector.DOMModel,target);this._agent=target.domAgent();this._idToDOMNode={};this._document=null;this._attributeLoadNodeIds={};target.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));this._inspectModeEnabled=false;this._defaultHighlighter=new WebInspector.DefaultDOMNodeHighlighter(this._agent);this._highlighter=this._defaultHighlighter;this._agent.enable();}
WebInspector.DOMModel.Events={AttrModified:"AttrModified",AttrRemoved:"AttrRemoved",CharacterDataModified:"CharacterDataModified",DOMMutated:"DOMMutated",NodeInserted:"NodeInserted",NodeInspected:"NodeInspected",NodeHighlightedInOverlay:"NodeHighlightedInOverlay",NodeRemoved:"NodeRemoved",DocumentUpdated:"DocumentUpdated",ChildNodeCountUpdated:"ChildNodeCountUpdated",UndoRedoRequested:"UndoRedoRequested",UndoRedoCompleted:"UndoRedoCompleted",DistributedNodesChanged:"DistributedNodesChanged",ModelSuspended:"ModelSuspended",InspectModeWillBeToggled:"InspectModeWillBeToggled",MarkersChanged:"MarkersChanged"}
WebInspector.DOMModel.highlightObjectAsDOMNode=function(object)
{var domModel=WebInspector.DOMModel.fromTarget(object.target());if(domModel)
domModel.highlightDOMNode(undefined,undefined,undefined,object.objectId);}
WebInspector.DOMModel.instances=function()
{var result=[];for(var target of WebInspector.targetManager.targets()){var domModel=WebInspector.DOMModel.fromTarget(target);if(domModel)
result.push(domModel);}
return result;}
WebInspector.DOMModel.hideDOMNodeHighlight=function()
{for(var domModel of WebInspector.DOMModel.instances())
domModel.highlightDOMNode(0);}
WebInspector.DOMModel.muteHighlight=function()
{WebInspector.DOMModel.hideDOMNodeHighlight();WebInspector.DOMModel._highlightDisabled=true;}
WebInspector.DOMModel.unmuteHighlight=function()
{WebInspector.DOMModel._highlightDisabled=false;}
WebInspector.DOMModel.cancelSearch=function()
{for(var domModel of WebInspector.DOMModel.instances())
domModel._cancelSearch();}
WebInspector.DOMModel.prototype={_scheduleMutationEvent:function(node)
{if(!this.hasEventListeners(WebInspector.DOMModel.Events.DOMMutated))
return;this._lastMutationId=(this._lastMutationId||0)+1;Promise.resolve().then(callObserve.bind(this,node,this._lastMutationId));function callObserve(node,mutationId)
{if(!this.hasEventListeners(WebInspector.DOMModel.Events.DOMMutated)||this._lastMutationId!==mutationId)
return;this.dispatchEventToListeners(WebInspector.DOMModel.Events.DOMMutated,node);}},requestDocument:function(callback)
{if(this._document){if(callback)
callback(this._document);return;}
if(this._pendingDocumentRequestCallbacks){this._pendingDocumentRequestCallbacks.push(callback);return;}
this._pendingDocumentRequestCallbacks=[callback];function onDocumentAvailable(error,root)
{if(!error)
this._setDocument(root);for(var i=0;i<this._pendingDocumentRequestCallbacks.length;++i){var callback=this._pendingDocumentRequestCallbacks[i];if(callback)
callback(this._document);}
delete this._pendingDocumentRequestCallbacks;}
this._agent.getDocument(onDocumentAvailable.bind(this));},existingDocument:function()
{return this._document;},pushNodeToFrontend:function(objectId,callback)
{function mycallback(nodeId)
{callback(nodeId?this.nodeForId(nodeId):null);}
this._dispatchWhenDocumentAvailable(this._agent.requestNode.bind(this._agent,objectId),mycallback.bind(this));},pushNodeByPathToFrontend:function(path,callback)
{this._dispatchWhenDocumentAvailable(this._agent.pushNodeByPathToFrontend.bind(this._agent,path),callback);},pushNodesByBackendIdsToFrontend:function(backendNodeIds,callback)
{var backendNodeIdsArray=Array.from(backendNodeIds.values());function mycallback(nodeIds)
{if(!nodeIds){callback(null);return;}
var map=new Map();for(var i=0;i<nodeIds.length;++i){if(nodeIds[i])
map.set(backendNodeIdsArray[i],this.nodeForId(nodeIds[i]));}
callback(map);}
this._dispatchWhenDocumentAvailable(this._agent.pushNodesByBackendIdsToFrontend.bind(this._agent,backendNodeIdsArray),mycallback.bind(this));},_wrapClientCallback:function(callback)
{if(!callback)
return;var wrapper=function(error,result)
{callback(error?null:result);};return wrapper;},_dispatchWhenDocumentAvailable:function(func,callback)
{var callbackWrapper=this._wrapClientCallback(callback);function onDocumentAvailable()
{if(this._document)
func(callbackWrapper);else{if(callbackWrapper)
callbackWrapper("No document");}}
this.requestDocument(onDocumentAvailable.bind(this));},_attributeModified:function(nodeId,name,value)
{var node=this._idToDOMNode[nodeId];if(!node)
return;node._setAttribute(name,value);this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified,{node:node,name:name});this._scheduleMutationEvent(node);},_attributeRemoved:function(nodeId,name)
{var node=this._idToDOMNode[nodeId];if(!node)
return;node._removeAttribute(name);this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrRemoved,{node:node,name:name});this._scheduleMutationEvent(node);},_inlineStyleInvalidated:function(nodeIds)
{for(var i=0;i<nodeIds.length;++i)
this._attributeLoadNodeIds[nodeIds[i]]=true;if("_loadNodeAttributesTimeout"in this)
return;this._loadNodeAttributesTimeout=setTimeout(this._loadNodeAttributes.bind(this),20);},_loadNodeAttributes:function()
{function callback(nodeId,error,attributes)
{if(error){return;}
var node=this._idToDOMNode[nodeId];if(node){if(node._setAttributesPayload(attributes)){this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified,{node:node,name:"style"});this._scheduleMutationEvent(node);}}}
delete this._loadNodeAttributesTimeout;for(var nodeId in this._attributeLoadNodeIds){var nodeIdAsNumber=parseInt(nodeId,10);this._agent.getAttributes(nodeIdAsNumber,callback.bind(this,nodeIdAsNumber));}
this._attributeLoadNodeIds={};},_characterDataModified:function(nodeId,newValue)
{var node=this._idToDOMNode[nodeId];node._nodeValue=newValue;this.dispatchEventToListeners(WebInspector.DOMModel.Events.CharacterDataModified,node);this._scheduleMutationEvent(node);},nodeForId:function(nodeId)
{return this._idToDOMNode[nodeId]||null;},_documentUpdated:function()
{this._setDocument(null);},_setDocument:function(payload)
{this._idToDOMNode={};if(payload&&"nodeId"in payload)
this._document=new WebInspector.DOMDocument(this,payload);else
this._document=null;this.dispatchEventToListeners(WebInspector.DOMModel.Events.DocumentUpdated,this._document);},_setDetachedRoot:function(payload)
{if(payload.nodeName==="#document")
new WebInspector.DOMDocument(this,payload);else
new WebInspector.DOMNode(this,null,false,payload);},_setChildNodes:function(parentId,payloads)
{if(!parentId&&payloads.length){this._setDetachedRoot(payloads[0]);return;}
var parent=this._idToDOMNode[parentId];parent._setChildrenPayload(payloads);},_childNodeCountUpdated:function(nodeId,newValue)
{var node=this._idToDOMNode[nodeId];node._childNodeCount=newValue;this.dispatchEventToListeners(WebInspector.DOMModel.Events.ChildNodeCountUpdated,node);this._scheduleMutationEvent(node);},_childNodeInserted:function(parentId,prevId,payload)
{var parent=this._idToDOMNode[parentId];var prev=this._idToDOMNode[prevId];var node=parent._insertChild(prev,payload);this._idToDOMNode[node.id]=node;this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted,node);this._scheduleMutationEvent(node);},_childNodeRemoved:function(parentId,nodeId)
{var parent=this._idToDOMNode[parentId];var node=this._idToDOMNode[nodeId];parent._removeChild(node);this._unbind(node);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved,{node:node,parent:parent});this._scheduleMutationEvent(node);},_shadowRootPushed:function(hostId,root)
{var host=this._idToDOMNode[hostId];if(!host)
return;var node=new WebInspector.DOMNode(this,host.ownerDocument,true,root);node.parentNode=host;this._idToDOMNode[node.id]=node;host._shadowRoots.unshift(node);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted,node);this._scheduleMutationEvent(node);},_shadowRootPopped:function(hostId,rootId)
{var host=this._idToDOMNode[hostId];if(!host)
return;var root=this._idToDOMNode[rootId];if(!root)
return;host._removeChild(root);this._unbind(root);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved,{node:root,parent:host});this._scheduleMutationEvent(root);},_pseudoElementAdded:function(parentId,pseudoElement)
{var parent=this._idToDOMNode[parentId];if(!parent)
return;var node=new WebInspector.DOMNode(this,parent.ownerDocument,false,pseudoElement);node.parentNode=parent;this._idToDOMNode[node.id]=node;console.assert(!parent._pseudoElements.get(node.pseudoType()));parent._pseudoElements.set(node.pseudoType(),node);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted,node);this._scheduleMutationEvent(node);},_pseudoElementRemoved:function(parentId,pseudoElementId)
{var parent=this._idToDOMNode[parentId];if(!parent)
return;var pseudoElement=this._idToDOMNode[pseudoElementId];if(!pseudoElement)
return;parent._removeChild(pseudoElement);this._unbind(pseudoElement);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved,{node:pseudoElement,parent:parent});this._scheduleMutationEvent(pseudoElement);},_distributedNodesUpdated:function(insertionPointId,distributedNodes)
{var insertionPoint=this._idToDOMNode[insertionPointId];if(!insertionPoint)
return;insertionPoint._setDistributedNodePayloads(distributedNodes);this.dispatchEventToListeners(WebInspector.DOMModel.Events.DistributedNodesChanged,insertionPoint);this._scheduleMutationEvent(insertionPoint);},_unbind:function(node)
{delete this._idToDOMNode[node.id];for(var i=0;node._children&&i<node._children.length;++i)
this._unbind(node._children[i]);for(var i=0;i<node._shadowRoots.length;++i)
this._unbind(node._shadowRoots[i]);var pseudoElements=node.pseudoElements();for(var value of pseudoElements.values())
this._unbind(value);if(node._templateContent)
this._unbind(node._templateContent);},_inspectNodeRequested:function(backendNodeId)
{var deferredNode=new WebInspector.DeferredDOMNode(this.target(),backendNodeId);this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInspected,deferredNode);},performSearch:function(query,includeUserAgentShadowDOM,searchCallback)
{WebInspector.DOMModel.cancelSearch();function callback(error,searchId,resultsCount)
{this._searchId=searchId;searchCallback(resultsCount);}
this._agent.performSearch(query,includeUserAgentShadowDOM,callback.bind(this));},performSearchPromise:function(query,includeUserAgentShadowDOM)
{return new Promise(performSearch.bind(this));function performSearch(resolve)
{this._agent.performSearch(query,includeUserAgentShadowDOM,callback.bind(this));function callback(error,searchId,resultsCount)
{if(!error)
this._searchId=searchId;resolve(error?0:resultsCount);}}},searchResult:function(index,callback)
{if(this._searchId)
this._agent.getSearchResults(this._searchId,index,index+1,searchResultsCallback.bind(this));else
callback(null);function searchResultsCallback(error,nodeIds)
{if(error){console.error(error);callback(null);return;}
if(nodeIds.length!=1)
return;callback(this.nodeForId(nodeIds[0]));}},_cancelSearch:function()
{if(this._searchId){this._agent.discardSearchResults(this._searchId);delete this._searchId;}},querySelector:function(nodeId,selectors,callback)
{this._agent.querySelector(nodeId,selectors,this._wrapClientCallback(callback));},querySelectorAll:function(nodeId,selectors,callback)
{this._agent.querySelectorAll(nodeId,selectors,this._wrapClientCallback(callback));},highlightDOMNode:function(nodeId,mode,backendNodeId,objectId)
{this.highlightDOMNodeWithConfig(nodeId,{mode:mode},backendNodeId,objectId);},highlightDOMNodeWithConfig:function(nodeId,config,backendNodeId,objectId)
{if(WebInspector.DOMModel._highlightDisabled)
return;config=config||{mode:"all",showInfo:undefined,selectors:undefined};if(this._hideDOMNodeHighlightTimeout){clearTimeout(this._hideDOMNodeHighlightTimeout);delete this._hideDOMNodeHighlightTimeout;}
var highlightConfig=this._buildHighlightConfig(config.mode);if(typeof config.showInfo!=="undefined")
highlightConfig.showInfo=config.showInfo;if(typeof config.selectors!=="undefined")
highlightConfig.selectorList=config.selectors;this._highlighter.highlightDOMNode(this.nodeForId(nodeId||0),highlightConfig,backendNodeId,objectId);},highlightDOMNodeForTwoSeconds:function(nodeId)
{this.highlightDOMNode(nodeId);this._hideDOMNodeHighlightTimeout=setTimeout(WebInspector.DOMModel.hideDOMNodeHighlight.bind(WebInspector.DOMModel),2000);},highlightFrame:function(frameId)
{if(WebInspector.DOMModel._highlightDisabled)
return;this._highlighter.highlightFrame(frameId);},setInspectMode:function(mode,callback)
{function onDocumentAvailable()
{this._inspectModeEnabled=mode!==DOMAgent.InspectMode.None;this.dispatchEventToListeners(WebInspector.DOMModel.Events.InspectModeWillBeToggled,this._inspectModeEnabled);this._highlighter.setInspectMode(mode,this._buildHighlightConfig(),callback);}
this.requestDocument(onDocumentAvailable.bind(this));},inspectModeEnabled:function()
{return this._inspectModeEnabled;},_buildHighlightConfig:function(mode)
{mode=mode||"all";var showRulers=WebInspector.moduleSetting("showMetricsRulers").get();var highlightConfig={showInfo:mode==="all",showRulers:showRulers,showExtensionLines:showRulers};if(mode==="all"||mode==="content")
highlightConfig.contentColor=WebInspector.Color.PageHighlight.Content.toProtocolRGBA();if(mode==="all"||mode==="padding")
highlightConfig.paddingColor=WebInspector.Color.PageHighlight.Padding.toProtocolRGBA();if(mode==="all"||mode==="border")
highlightConfig.borderColor=WebInspector.Color.PageHighlight.Border.toProtocolRGBA();if(mode==="all"||mode==="margin")
highlightConfig.marginColor=WebInspector.Color.PageHighlight.Margin.toProtocolRGBA();if(mode==="all"){highlightConfig.eventTargetColor=WebInspector.Color.PageHighlight.EventTarget.toProtocolRGBA();highlightConfig.shapeColor=WebInspector.Color.PageHighlight.Shape.toProtocolRGBA();highlightConfig.shapeMarginColor=WebInspector.Color.PageHighlight.ShapeMargin.toProtocolRGBA();highlightConfig.displayAsMaterial=Runtime.experiments.isEnabled("inspectTooltip");}
return highlightConfig;},_markRevision:function(node,callback)
{function wrapperFunction(error)
{if(!error)
this.markUndoableState();if(callback)
callback.apply(this,arguments);}
return wrapperFunction.bind(this);},markUndoableState:function()
{this._agent.markUndoableState();},undo:function(callback)
{function mycallback(error)
{this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);callback(error);}
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);this._agent.undo(callback);},redo:function(callback)
{function mycallback(error)
{this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);callback(error);}
this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);this._agent.redo(callback);},setHighlighter:function(highlighter)
{this._highlighter=highlighter||this._defaultHighlighter;},nodeForLocation:function(x,y,callback)
{this._agent.getNodeForLocation(x,y,mycallback.bind(this));function mycallback(error,nodeId)
{if(error){callback(null);return;}
callback(this.nodeForId(nodeId));}},pushObjectAsNodeToFrontend:function(object,callback)
{if(object.isNode())
this.pushNodeToFrontend(object.objectId,callback);else
callback(null);},suspendModel:function()
{return new Promise(promiseBody.bind(this));function promiseBody(fulfill)
{this._agent.disable(callback.bind(this));function callback()
{this._setDocument(null);fulfill();}}},resumeModel:function()
{return new Promise(promiseBody.bind(this));function promiseBody(fulfill)
{this._agent.enable(fulfill);}},nodeHighlightRequested:function(nodeId)
{var node=this.nodeForId(nodeId);if(!node)
return;this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeHighlightedInOverlay,node);},__proto__:WebInspector.SDKModel.prototype}
WebInspector.DOMDispatcher=function(domModel)
{this._domModel=domModel;}
WebInspector.DOMDispatcher.prototype={documentUpdated:function()
{this._domModel._documentUpdated();},inspectNodeRequested:function(nodeId)
{this._domModel._inspectNodeRequested(nodeId);},attributeModified:function(nodeId,name,value)
{this._domModel._attributeModified(nodeId,name,value);},attributeRemoved:function(nodeId,name)
{this._domModel._attributeRemoved(nodeId,name);},inlineStyleInvalidated:function(nodeIds)
{this._domModel._inlineStyleInvalidated(nodeIds);},characterDataModified:function(nodeId,characterData)
{this._domModel._characterDataModified(nodeId,characterData);},setChildNodes:function(parentId,payloads)
{this._domModel._setChildNodes(parentId,payloads);},childNodeCountUpdated:function(nodeId,childNodeCount)
{this._domModel._childNodeCountUpdated(nodeId,childNodeCount);},childNodeInserted:function(parentNodeId,previousNodeId,payload)
{this._domModel._childNodeInserted(parentNodeId,previousNodeId,payload);},childNodeRemoved:function(parentNodeId,nodeId)
{this._domModel._childNodeRemoved(parentNodeId,nodeId);},shadowRootPushed:function(hostId,root)
{this._domModel._shadowRootPushed(hostId,root);},shadowRootPopped:function(hostId,rootId)
{this._domModel._shadowRootPopped(hostId,rootId);},pseudoElementAdded:function(parentId,pseudoElement)
{this._domModel._pseudoElementAdded(parentId,pseudoElement);},pseudoElementRemoved:function(parentId,pseudoElementId)
{this._domModel._pseudoElementRemoved(parentId,pseudoElementId);},distributedNodesUpdated:function(insertionPointId,distributedNodes)
{this._domModel._distributedNodesUpdated(insertionPointId,distributedNodes);},nodeHighlightRequested:function(nodeId)
{this._domModel.nodeHighlightRequested(nodeId);}}
WebInspector.DOMNodeHighlighter=function(){}
WebInspector.DOMNodeHighlighter.prototype={highlightDOMNode:function(node,config,backendNodeId,objectId){},setInspectMode:function(mode,config,callback){},highlightFrame:function(frameId){}}
WebInspector.DefaultDOMNodeHighlighter=function(agent)
{this._agent=agent;}
WebInspector.DefaultDOMNodeHighlighter.prototype={highlightDOMNode:function(node,config,backendNodeId,objectId)
{if(objectId||node||backendNodeId)
this._agent.highlightNode(config,(objectId||backendNodeId)?undefined:node.id,backendNodeId,objectId);else
this._agent.hideHighlight();},setInspectMode:function(mode,config,callback)
{this._agent.setInspectMode(mode,config,callback);},highlightFrame:function(frameId)
{this._agent.highlightFrame(frameId,WebInspector.Color.PageHighlight.Content.toProtocolRGBA(),WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());}}
WebInspector.DOMModel.fromTarget=function(target)
{return(target.model(WebInspector.DOMModel));};WebInspector.DebuggerModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.DebuggerModel,target);target.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));this._agent=target.debuggerAgent();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.TargetDisposed,this._targetDisposed,this);this._debuggerPausedDetails=null;this._scripts={};this._scriptsBySourceURL=new Map();this._breakpointResolvedEventTarget=new WebInspector.Object();this._isPausing=false;WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this._pauseOnExceptionStateChanged,this);WebInspector.moduleSetting("pauseOnCaughtException").addChangeListener(this._pauseOnExceptionStateChanged,this);WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this.asyncStackTracesStateChanged,this);this.enableDebugger();}
WebInspector.DebuggerModel.FunctionDetails;WebInspector.DebuggerModel.GeneratorObjectDetails;WebInspector.DebuggerModel.PauseOnExceptionsState={DontPauseOnExceptions:"none",PauseOnAllExceptions:"all",PauseOnUncaughtExceptions:"uncaught"};WebInspector.DebuggerModel.Events={DebuggerWasEnabled:"DebuggerWasEnabled",DebuggerWasDisabled:"DebuggerWasDisabled",BeforeDebuggerPaused:"BeforeDebuggerPaused",DebuggerPaused:"DebuggerPaused",DebuggerResumed:"DebuggerResumed",ParsedScriptSource:"ParsedScriptSource",FailedToParseScriptSource:"FailedToParseScriptSource",GlobalObjectCleared:"GlobalObjectCleared",CallFrameSelected:"CallFrameSelected",ConsoleCommandEvaluatedInSelectedCallFrame:"ConsoleCommandEvaluatedInSelectedCallFrame"}
WebInspector.DebuggerModel.BreakReason={DOM:"DOM",EventListener:"EventListener",XHR:"XHR",Exception:"exception",PromiseRejection:"promiseRejection",Assert:"assert",CSPViolation:"CSPViolation",DebugCommand:"debugCommand",Other:"other"}
WebInspector.DebuggerModel.fromOneBased=function(value)
{return value?value-1:0;}
WebInspector.DebuggerModel.prototype={debuggerEnabled:function()
{return!!this._debuggerEnabled;},enableDebugger:function(callback)
{if(this._debuggerEnabled){if(callback)
callback();return;}
this._agent.enable(callback);this._debuggerEnabled=true;this._pauseOnExceptionStateChanged();this.asyncStackTracesStateChanged();this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasEnabled);},disableDebugger:function(callback)
{if(!this._debuggerEnabled){if(callback)
callback();return;}
this._agent.disable(callback);this._debuggerEnabled=false;this._isPausing=false;this.asyncStackTracesStateChanged();this.globalObjectCleared();this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);},_skipAllPauses:function(skip)
{if(this._skipAllPausesTimeout){clearTimeout(this._skipAllPausesTimeout);delete this._skipAllPausesTimeout;}
this._agent.setSkipAllPauses(skip);},skipAllPausesUntilReloadOrTimeout:function(timeout)
{if(this._skipAllPausesTimeout)
clearTimeout(this._skipAllPausesTimeout);this._agent.setSkipAllPauses(true);this._skipAllPausesTimeout=setTimeout(this._skipAllPauses.bind(this,false),timeout);},_pauseOnExceptionStateChanged:function()
{var state;if(!WebInspector.moduleSetting("pauseOnExceptionEnabled").get()){state=WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions;}else if(WebInspector.moduleSetting("pauseOnCaughtException").get()){state=WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions;}else{state=WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions;}
this._agent.setPauseOnExceptions(state);},asyncStackTracesStateChanged:function()
{const maxAsyncStackChainDepth=4;var enabled=WebInspector.moduleSetting("enableAsyncStackTraces").get()&&this._debuggerEnabled;this._agent.setAsyncCallStackDepth(enabled?maxAsyncStackChainDepth:0);},stepInto:function()
{this._agent.stepInto();},stepOver:function()
{this._agent.stepOver();},stepOut:function()
{this._agent.stepOut();},resume:function()
{this._agent.resume();this._isPausing=false;},pause:function()
{this._isPausing=true;this._skipAllPauses(false);this._agent.pause();},setBreakpointsActive:function(active)
{this._agent.setBreakpointsActive(active);},setBreakpointByURL:function(url,lineNumber,columnNumber,condition,callback)
{var minColumnNumber=0;var scripts=this._scriptsBySourceURL.get(url)||[];for(var i=0,l=scripts.length;i<l;++i){var script=scripts[i];if(lineNumber===script.lineOffset)
minColumnNumber=minColumnNumber?Math.min(minColumnNumber,script.columnOffset):script.columnOffset;}
columnNumber=Math.max(columnNumber,minColumnNumber);var target=this.target();function didSetBreakpoint(error,breakpointId,locations)
{if(callback){var rawLocations=locations?locations.map(WebInspector.DebuggerModel.Location.fromPayload.bind(WebInspector.DebuggerModel.Location,this)):[];callback(error?null:breakpointId,rawLocations);}}
this._agent.setBreakpointByUrl(lineNumber,url,undefined,columnNumber,condition,didSetBreakpoint.bind(this));},setBreakpointBySourceId:function(rawLocation,condition,callback)
{var target=this.target();function didSetBreakpoint(error,breakpointId,actualLocation)
{if(callback){var location=WebInspector.DebuggerModel.Location.fromPayload(this,actualLocation);callback(error?null:breakpointId,[location]);}}
this._agent.setBreakpoint(rawLocation.payload(),condition,didSetBreakpoint.bind(this));},removeBreakpoint:function(breakpointId,callback)
{this._agent.removeBreakpoint(breakpointId,innerCallback);function innerCallback(error)
{if(error)
console.error("Failed to remove breakpoint: "+error);if(callback)
callback();}},getCollectionEntries:function(objectId,callback)
{this._agent.getCollectionEntries(objectId,innerCallback);function innerCallback(error,response)
{if(error){console.error(error);callback(null);return;}
callback(response);}},_breakpointResolved:function(breakpointId,location)
{this._breakpointResolvedEventTarget.dispatchEventToListeners(breakpointId,WebInspector.DebuggerModel.Location.fromPayload(this,location));},globalObjectCleared:function()
{this._setDebuggerPausedDetails(null);this._reset();this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObjectCleared);},_reset:function()
{this._scripts={};this._scriptsBySourceURL.clear();},get scripts()
{return this._scripts;},scriptForId:function(scriptId)
{return this._scripts[scriptId]||null;},scriptsForSourceURL:function(sourceURL)
{if(!sourceURL)
return[];return this._scriptsBySourceURL.get(sourceURL)||[];},setScriptSource:function(scriptId,newSource,callback)
{this._scripts[scriptId].editSource(newSource,this._didEditScriptSource.bind(this,scriptId,newSource,callback));},_didEditScriptSource:function(scriptId,newSource,callback,error,errorData,callFrames,asyncStackTrace,needsStepIn)
{if(needsStepIn){this.stepInto();this._pendingLiveEditCallback=callback.bind(this,error,errorData);return;}
if(!error&&callFrames&&callFrames.length)
this._pausedScript(callFrames,this._debuggerPausedDetails.reason,this._debuggerPausedDetails.auxData,this._debuggerPausedDetails.breakpointIds,asyncStackTrace);callback(error,errorData);},get callFrames()
{return this._debuggerPausedDetails?this._debuggerPausedDetails.callFrames:null;},debuggerPausedDetails:function()
{return this._debuggerPausedDetails;},_setDebuggerPausedDetails:function(debuggerPausedDetails)
{this._isPausing=false;this._debuggerPausedDetails=debuggerPausedDetails;if(this._debuggerPausedDetails){if(Runtime.experiments.isEnabled("emptySourceMapAutoStepping")){if(this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BeforeDebuggerPaused,this._debuggerPausedDetails)){return false;}}
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused,this._debuggerPausedDetails);}
if(debuggerPausedDetails)
this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);else
this.setSelectedCallFrame(null);return true;},_pausedScript:function(callFrames,reason,auxData,breakpointIds,asyncStackTrace)
{var pausedDetails=new WebInspector.DebuggerPausedDetails(this,callFrames,reason,auxData,breakpointIds,asyncStackTrace);if(this._setDebuggerPausedDetails(pausedDetails)){if(this._pendingLiveEditCallback){var callback=this._pendingLiveEditCallback;delete this._pendingLiveEditCallback;callback();}}else{this._agent.stepInto();}},_resumedScript:function()
{this._setDebuggerPausedDetails(null);this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);},_parsedScriptSource:function(scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,isContentScript,isInternalScript,isLiveEdit,sourceMapURL,hasSourceURL,deprecatedCommentWasUsed,hasSyntaxError)
{var script=new WebInspector.Script(this,scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,isContentScript,isInternalScript,isLiveEdit,sourceMapURL,hasSourceURL);this._registerScript(script);if(!hasSyntaxError)
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource,script);else
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource,script);if(deprecatedCommentWasUsed){var text=WebInspector.UIString("'//@ sourceURL' and '//@ sourceMappingURL' are deprecated, please use '//# sourceURL=' and '//# sourceMappingURL=' instead.");var msg=new WebInspector.ConsoleMessage(this.target(),WebInspector.ConsoleMessage.MessageSource.JS,WebInspector.ConsoleMessage.MessageLevel.Warning,text,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,scriptId);var consoleModel=this.target().consoleModel;if(consoleModel)
consoleModel.addMessage(msg);}
return script;},_registerScript:function(script)
{this._scripts[script.scriptId]=script;if(script.isAnonymousScript())
return;var scripts=this._scriptsBySourceURL.get(script.sourceURL);if(!scripts){scripts=[];this._scriptsBySourceURL.set(script.sourceURL,scripts);}
scripts.push(script);},createRawLocation:function(script,lineNumber,columnNumber)
{if(script.sourceURL)
return this.createRawLocationByURL(script.sourceURL,lineNumber,columnNumber);return new WebInspector.DebuggerModel.Location(this,script.scriptId,lineNumber,columnNumber);},createRawLocationByURL:function(sourceURL,lineNumber,columnNumber)
{var closestScript=null;var scripts=this._scriptsBySourceURL.get(sourceURL)||[];for(var i=0,l=scripts.length;i<l;++i){var script=scripts[i];if(!closestScript)
closestScript=script;if(script.lineOffset>lineNumber||(script.lineOffset===lineNumber&&script.columnOffset>columnNumber))
continue;if(script.endLine<lineNumber||(script.endLine===lineNumber&&script.endColumn<=columnNumber))
continue;closestScript=script;break;}
return closestScript?new WebInspector.DebuggerModel.Location(this,closestScript.scriptId,lineNumber,columnNumber):null;},createRawLocationByScriptId:function(scriptId,lineNumber,columnNumber)
{var script=this.scriptForId(scriptId);return script?this.createRawLocation(script,lineNumber,columnNumber):null;},createRawLocationsByStackTrace:function(stackTrace)
{var frames=[];while(stackTrace){for(var frame of stackTrace.callFrames)
frames.push(frame);stackTrace=stackTrace.parent;}
var rawLocations=[];for(var frame of frames){var rawLocation=this.createRawLocationByScriptId(frame.scriptId,WebInspector.DebuggerModel.fromOneBased(frame.lineNumber),WebInspector.DebuggerModel.fromOneBased(frame.columnNumber));if(rawLocation)
rawLocations.push(rawLocation);}
return rawLocations;},isPaused:function()
{return!!this.debuggerPausedDetails();},isPausing:function()
{return this._isPausing;},setSelectedCallFrame:function(callFrame)
{this._selectedCallFrame=callFrame;if(!this._selectedCallFrame)
return;this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFrameSelected,callFrame);},selectedCallFrame:function()
{return this._selectedCallFrame;},evaluateOnSelectedCallFrame:function(code,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,callback)
{function didEvaluate(result,wasThrown,exceptionDetails)
{if(!result)
callback(null,false);else if(returnByValue)
callback(null,!!wasThrown,wasThrown?null:result,exceptionDetails);else
callback(this.target().runtimeModel.createRemoteObject(result),!!wasThrown,undefined,exceptionDetails);if(objectGroup==="console")
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);}
this.selectedCallFrame().evaluate(code,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,didEvaluate.bind(this));},functionDetails:function(remoteObject,callback)
{this._agent.getFunctionDetails(remoteObject.objectId,didGetDetails.bind(this));function didGetDetails(error,response)
{if(error){callback(null);return;}
var location=response.location;var script=this.scriptForId(location.scriptId);var rawLocation=script?this.createRawLocation(script,location.lineNumber,location.columnNumber||0):null;var sourceURL=script?script.contentURL():null;callback({location:rawLocation,sourceURL:sourceURL,functionName:response.functionName,scopeChain:response.scopeChain||null});}},setVariableValue:function(scopeNumber,variableName,newValue,callFrameId,callback)
{this._agent.setVariableValue(scopeNumber,variableName,newValue,callFrameId,innerCallback);function innerCallback(error)
{if(error){console.error(error);if(callback)
callback(error);return;}
if(callback)
callback();}},generatorObjectDetails:function(remoteObject,callback)
{this._agent.getGeneratorObjectDetails(remoteObject.objectId,didGetDetails.bind(this));function didGetDetails(error,response)
{if(error){console.error(error);callback(null);return;}
var location=response.location;var script=location&&this.scriptForId(location.scriptId);var rawLocation=script?this.createRawLocation(script,location.lineNumber,location.columnNumber||0):null;var sourceURL=script?script.contentURL():null;callback({location:rawLocation,sourceURL:sourceURL,functionName:response.functionName,status:response.status});}},addBreakpointListener:function(breakpointId,listener,thisObject)
{this._breakpointResolvedEventTarget.addEventListener(breakpointId,listener,thisObject)},removeBreakpointListener:function(breakpointId,listener,thisObject)
{this._breakpointResolvedEventTarget.removeEventListener(breakpointId,listener,thisObject);},setBlackboxPatterns:function(patterns)
{var callback;var promise=new Promise(fulfill=>callback=fulfill);this._agent.setBlackboxPatterns(patterns,patternsUpdated);return promise;function patternsUpdated(error)
{if(error)
console.error(error);callback(!error);}},_targetDisposed:function(event)
{var target=(event.data);if(target!=this.target())
return;WebInspector.moduleSetting("pauseOnExceptionEnabled").removeChangeListener(this._pauseOnExceptionStateChanged,this);WebInspector.moduleSetting("pauseOnCaughtException").removeChangeListener(this._pauseOnExceptionStateChanged,this);WebInspector.moduleSetting("enableAsyncStackTraces").removeChangeListener(this.asyncStackTracesStateChanged,this);},suspendModel:function()
{return new Promise(promiseBody.bind(this));function promiseBody(fulfill)
{this.disableDebugger(fulfill);}},resumeModel:function()
{return new Promise(promiseBody.bind(this));function promiseBody(fulfill)
{this.enableDebugger(fulfill);}},__proto__:WebInspector.SDKModel.prototype}
WebInspector.DebuggerEventTypes={JavaScriptPause:0,JavaScriptBreakpoint:1,NativeBreakpoint:2};WebInspector.DebuggerDispatcher=function(debuggerModel)
{this._debuggerModel=debuggerModel;}
WebInspector.DebuggerDispatcher.prototype={paused:function(callFrames,reason,auxData,breakpointIds,asyncStackTrace)
{this._debuggerModel._pausedScript(callFrames,reason,auxData,breakpointIds||[],asyncStackTrace);},resumed:function()
{this._debuggerModel._resumedScript();},scriptParsed:function(scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,isContentScript,isInternalScript,isLiveEdit,sourceMapURL,hasSourceURL,deprecatedCommentWasUsed)
{this._debuggerModel._parsedScriptSource(scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,!!isContentScript,!!isInternalScript,!!isLiveEdit,sourceMapURL,hasSourceURL,deprecatedCommentWasUsed,false);},scriptFailedToParse:function(scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,isContentScript,isInternalScript,sourceMapURL,hasSourceURL,deprecatedCommentWasUsed)
{this._debuggerModel._parsedScriptSource(scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,!!isContentScript,!!isInternalScript,false,sourceMapURL,hasSourceURL,deprecatedCommentWasUsed,true);},breakpointResolved:function(breakpointId,location)
{this._debuggerModel._breakpointResolved(breakpointId,location);}}
WebInspector.DebuggerModel.Location=function(debuggerModel,scriptId,lineNumber,columnNumber)
{WebInspector.SDKObject.call(this,debuggerModel.target());this._debuggerModel=debuggerModel;this.scriptId=scriptId;this.lineNumber=lineNumber;this.columnNumber=columnNumber||0;}
WebInspector.DebuggerModel.Location.fromPayload=function(debuggerModel,payload)
{return new WebInspector.DebuggerModel.Location(debuggerModel,payload.scriptId,payload.lineNumber,payload.columnNumber);}
WebInspector.DebuggerModel.Location.prototype={payload:function()
{return{scriptId:this.scriptId,lineNumber:this.lineNumber,columnNumber:this.columnNumber};},script:function()
{return this._debuggerModel.scriptForId(this.scriptId);},continueToLocation:function()
{this._debuggerModel._agent.continueToLocation(this.payload());},id:function()
{return this.target().id()+":"+this.scriptId+":"+this.lineNumber+":"+this.columnNumber;},__proto__:WebInspector.SDKObject.prototype}
WebInspector.DebuggerModel.CallFrame=function(debuggerModel,script,payload)
{var target=debuggerModel.target();WebInspector.SDKObject.call(this,target);this.debuggerModel=debuggerModel;this._debuggerAgent=debuggerModel._agent;this._script=script;this._payload=payload;this._location=WebInspector.DebuggerModel.Location.fromPayload(debuggerModel,payload.location);this._scopeChain=[];this._localScope=null;for(var i=0;i<payload.scopeChain.length;++i){var scope=new WebInspector.DebuggerModel.Scope(this,i);this._scopeChain.push(scope);if(scope.type()===DebuggerAgent.ScopeType.Local)
this._localScope=scope;}
if(payload.functionLocation)
this._functionLocation=WebInspector.DebuggerModel.Location.fromPayload(debuggerModel,payload.functionLocation);}
WebInspector.DebuggerModel.CallFrame.fromPayloadArray=function(debuggerModel,callFrames)
{var result=[];for(var i=0;i<callFrames.length;++i){var callFrame=callFrames[i];var script=debuggerModel.scriptForId(callFrame.location.scriptId);if(script)
result.push(new WebInspector.DebuggerModel.CallFrame(debuggerModel,script,callFrame));}
return result;}
WebInspector.DebuggerModel.CallFrame.prototype={get script()
{return this._script;},get id()
{return this._payload.callFrameId;},scopeChain:function()
{return this._scopeChain;},localScope:function()
{return this._localScope;},thisObject:function()
{return this._payload.this?this.target().runtimeModel.createRemoteObject(this._payload.this):null;},returnValue:function()
{return this._payload.returnValue?this.target().runtimeModel.createRemoteObject(this._payload.returnValue):null;},get functionName()
{return this._payload.functionName;},location:function()
{return this._location;},functionLocation:function()
{return this._functionLocation||null;},evaluate:function(code,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,callback)
{function didEvaluateOnCallFrame(error,result,wasThrown,exceptionDetails)
{if(error){console.error(error);callback(null,false);return;}
callback(result,wasThrown,exceptionDetails);}
this._debuggerAgent.evaluateOnCallFrame(this._payload.callFrameId,code,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,didEvaluateOnCallFrame);},restart:function(callback)
{function protocolCallback(error,callFrames,asyncStackTrace)
{if(!error)
this.debuggerModel.stepInto();if(callback)
callback(error);}
this._debuggerAgent.restartFrame(this._payload.callFrameId,protocolCallback.bind(this));},variableNames:function(callback)
{var result={this:true};function propertiesCollected(properties)
{for(var i=0;properties&&i<properties.length;++i)
result[properties[i].name]=true;if(--pendingRequests==0)
callback(result);}
var scopeChain=this.scopeChain();var pendingRequests=scopeChain.length;for(var i=0;i<scopeChain.length;++i){var scope=scopeChain[i];var object=scope.object();object.getAllProperties(false,propertiesCollected);}},__proto__:WebInspector.SDKObject.prototype}
WebInspector.DebuggerModel.Scope=function(callFrame,ordinal)
{this._callFrame=callFrame;this._payload=callFrame._payload.scopeChain[ordinal];this._type=this._payload.type;this._name=this._payload.name;this._ordinal=ordinal;this._startLocation=this._payload.startLocation?WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel,this._payload.startLocation):null;this._endLocation=this._payload.endLocation?WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel,this._payload.endLocation):null;}
WebInspector.DebuggerModel.Scope.prototype={callFrame:function()
{return this._callFrame;},type:function()
{return this._type;},name:function()
{return this._name;},startLocation:function()
{return this._startLocation;},endLocation:function()
{return this._endLocation;},object:function()
{if(this._object)
return this._object;var runtimeModel=this._callFrame.target().runtimeModel;var declarativeScope=this._type!==DebuggerAgent.ScopeType.With&&this._type!==DebuggerAgent.ScopeType.Global;if(declarativeScope)
this._object=runtimeModel.createScopeRemoteObject(this._payload.object,new WebInspector.ScopeRef(this._ordinal,this._callFrame.id));else
this._object=runtimeModel.createRemoteObject(this._payload.object);return this._object;},description:function()
{var declarativeScope=this._type!==DebuggerAgent.ScopeType.With&&this._type!==DebuggerAgent.ScopeType.Global;return declarativeScope?"":(this._payload.object.description||"");}}
WebInspector.DebuggerPausedDetails=function(debuggerModel,callFrames,reason,auxData,breakpointIds,asyncStackTrace)
{WebInspector.SDKObject.call(this,debuggerModel.target());this.debuggerModel=debuggerModel;this.callFrames=WebInspector.DebuggerModel.CallFrame.fromPayloadArray(debuggerModel,callFrames);this.reason=reason;this.auxData=auxData;this.breakpointIds=breakpointIds;this.asyncStackTrace=asyncStackTrace;}
WebInspector.DebuggerPausedDetails.prototype={exception:function()
{if(this.reason!==WebInspector.DebuggerModel.BreakReason.Exception&&this.reason!==WebInspector.DebuggerModel.BreakReason.PromiseRejection)
return null;return this.target().runtimeModel.createRemoteObject((this.auxData));},__proto__:WebInspector.SDKObject.prototype}
WebInspector.DebuggerModel.instances=function()
{var result=[];for(var target of WebInspector.targetManager.targets()){var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel)
result.push(debuggerModel);}
return result;}
WebInspector.DebuggerModel.fromTarget=function(target)
{if(!target||!target.hasJSContext())
return null;return(target.model(WebInspector.DebuggerModel));};WebInspector.HAREntry=function(request)
{this._request=request;}
WebInspector.HAREntry.prototype={build:function()
{var ipAddress=this._request.remoteAddress();var portPositionInString=ipAddress.lastIndexOf(":");if(portPositionInString!==-1)
ipAddress=ipAddress.substr(0,portPositionInString);var entry={startedDateTime:WebInspector.HARLog.pseudoWallTime(this._request,this._request.startTime),time:this._request.timing?WebInspector.HAREntry._toMilliseconds(this._request.duration):0,request:this._buildRequest(),response:this._buildResponse(),cache:{},timings:this._buildTimings(),serverIPAddress:ipAddress};if(this._request.connectionId!=="0")
entry.connection=this._request.connectionId;var page=this._request.target().networkLog.pageLoadForRequest(this._request);if(page)
entry.pageref="page_"+page.id;return entry;},_buildRequest:function()
{var headersText=this._request.requestHeadersText();var res={method:this._request.requestMethod,url:this._buildRequestURL(this._request.url),httpVersion:this._request.requestHttpVersion(),headers:this._request.requestHeaders(),queryString:this._buildParameters(this._request.queryParameters||[]),cookies:this._buildCookies(this._request.requestCookies||[]),headersSize:headersText?headersText.length:-1,bodySize:this.requestBodySize};if(this._request.requestFormData)
res.postData=this._buildPostData();return res;},_buildResponse:function()
{var headersText=this._request.responseHeadersText;return{status:this._request.statusCode,statusText:this._request.statusText,httpVersion:this._request.responseHttpVersion(),headers:this._request.responseHeaders,cookies:this._buildCookies(this._request.responseCookies||[]),content:this._buildContent(),redirectURL:this._request.responseHeaderValue("Location")||"",headersSize:headersText?headersText.length:-1,bodySize:this.responseBodySize,_transferSize:this._request.transferSize,_error:this._request.localizedFailDescription};},_buildContent:function()
{var content={size:this._request.resourceSize,mimeType:this._request.mimeType||"x-unknown",};var compression=this.responseCompression;if(typeof compression==="number")
content.compression=compression;return content;},_buildTimings:function()
{var timing=this._request.timing;if(!timing)
return{blocked:-1,dns:-1,connect:-1,send:0,wait:0,receive:0,ssl:-1};function firstNonNegative(values)
{for(var i=0;i<values.length;++i){if(values[i]>=0)
return values[i];}
console.assert(false,"Incomplete request timing information.");}
var blocked=firstNonNegative([timing.dnsStart,timing.connectStart,timing.sendStart]);var dns=-1;if(timing.dnsStart>=0)
dns=firstNonNegative([timing.connectStart,timing.sendStart])-timing.dnsStart;var connect=-1;if(timing.connectStart>=0)
connect=timing.sendStart-timing.connectStart;var send=timing.sendEnd-timing.sendStart;var wait=timing.receiveHeadersEnd-timing.sendEnd;var receive=WebInspector.HAREntry._toMilliseconds(this._request.duration)-timing.receiveHeadersEnd;var ssl=-1;if(timing.sslStart>=0&&timing.sslEnd>=0)
ssl=timing.sslEnd-timing.sslStart;return{blocked:blocked,dns:dns,connect:connect,send:send,wait:wait,receive:receive,ssl:ssl};},_buildPostData:function()
{var res={mimeType:this._request.requestContentType(),text:this._request.requestFormData};if(this._request.formParameters)
res.params=this._buildParameters(this._request.formParameters);return res;},_buildParameters:function(parameters)
{return parameters.slice();},_buildRequestURL:function(url)
{return url.split("#",2)[0];},_buildCookies:function(cookies)
{return cookies.map(this._buildCookie.bind(this));},_buildCookie:function(cookie)
{var c={name:cookie.name(),value:cookie.value(),path:cookie.path(),domain:cookie.domain(),expires:cookie.expiresDate(WebInspector.HARLog.pseudoWallTime(this._request,this._request.startTime)),httpOnly:cookie.httpOnly(),secure:cookie.secure()};if(cookie.sameSite())
c.sameSite=cookie.sameSite();return c;},get requestBodySize()
{return!this._request.requestFormData?0:this._request.requestFormData.length;},get responseBodySize()
{if(this._request.cached()||this._request.statusCode===304)
return 0;if(!this._request.responseHeadersText)
return-1;return this._request.transferSize-this._request.responseHeadersText.length;},get responseCompression()
{if(this._request.cached()||this._request.statusCode===304||this._request.statusCode===206)
return;if(!this._request.responseHeadersText)
return;return this._request.resourceSize-this.responseBodySize;}}
WebInspector.HAREntry._toMilliseconds=function(time)
{return time===-1?-1:time*1000;}
WebInspector.HARLog=function(requests)
{this._requests=requests;}
WebInspector.HARLog.pseudoWallTime=function(request,monotonicTime)
{return new Date(request.pseudoWallTime(monotonicTime)*1000);}
WebInspector.HARLog.prototype={build:function()
{return{version:"1.2",creator:this._creator(),pages:this._buildPages(),entries:this._requests.map(this._convertResource.bind(this))}},_creator:function()
{var webKitVersion=/AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);return{name:"WebInspector",version:webKitVersion?webKitVersion[1]:"n/a"};},_buildPages:function()
{var seenIdentifiers={};var pages=[];for(var i=0;i<this._requests.length;++i){var request=this._requests[i];var page=request.target().networkLog.pageLoadForRequest(request);if(!page||seenIdentifiers[page.id])
continue;seenIdentifiers[page.id]=true;pages.push(this._convertPage(page,request));}
return pages;},_convertPage:function(page,request)
{return{startedDateTime:WebInspector.HARLog.pseudoWallTime(request,page.startTime),id:"page_"+page.id,title:page.url,pageTimings:{onContentLoad:this._pageEventTime(page,page.contentLoadTime),onLoad:this._pageEventTime(page,page.loadTime)}}},_convertResource:function(request)
{return(new WebInspector.HAREntry(request)).build();},_pageEventTime:function(page,time)
{var startTime=page.startTime;if(time===-1||startTime===-1)
return-1;return WebInspector.HAREntry._toMilliseconds(time-startTime);}};WebInspector.NetworkLog=function(target)
{WebInspector.SDKObject.call(this,target);this._requests=[];this._requestForId={};target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted,this._onRequestStarted,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._onMainFrameNavigated,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._onLoad,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded,this._onDOMContentLoaded,this);}
WebInspector.NetworkLog.requestForURL=function(url)
{for(var target of WebInspector.targetManager.targets()){var result=target.networkLog.requestForURL(url);if(result)
return result;}
return null;}
WebInspector.NetworkLog.requests=function()
{var result=[];for(var target of WebInspector.targetManager.targets()){result=result.concat(target.networkLog.requests());}
return result;}
WebInspector.NetworkLog.prototype={requests:function()
{return this._requests;},requestForURL:function(url)
{for(var i=0;i<this._requests.length;++i){if(this._requests[i].url===url)
return this._requests[i];}
return null;},pageLoadForRequest:function(request)
{return request.__page;},_onMainFrameNavigated:function(event)
{var mainFrame=event.data;this._currentPageLoad=null;var oldRequests=this._requests.splice(0,this._requests.length);this._requestForId={};for(var i=0;i<oldRequests.length;++i){var request=oldRequests[i];if(request.loaderId===mainFrame.loaderId){if(!this._currentPageLoad)
this._currentPageLoad=new WebInspector.PageLoad(request);this._requests.push(request);this._requestForId[request.requestId]=request;request.__page=this._currentPageLoad;}}},_onRequestStarted:function(event)
{var request=(event.data);this._requests.push(request);this._requestForId[request.requestId]=request;request.__page=this._currentPageLoad;},_onDOMContentLoaded:function(event)
{if(this._currentPageLoad)
this._currentPageLoad.contentLoadTime=event.data;},_onLoad:function(event)
{if(this._currentPageLoad)
this._currentPageLoad.loadTime=event.data;},requestForId:function(requestId)
{return this._requestForId[requestId];},__proto__:WebInspector.SDKObject.prototype}
WebInspector.PageLoad=function(mainRequest)
{this.id=++WebInspector.PageLoad._lastIdentifier;this.url=mainRequest.url;this.startTime=mainRequest.startTime;}
WebInspector.PageLoad._lastIdentifier=0;;WebInspector.ServiceWorkerManager=function(target)
{WebInspector.SDKObject.call(this,target);target.registerServiceWorkerDispatcher(new WebInspector.ServiceWorkerDispatcher(this));this._lastAnonymousTargetId=0;this._agent=target.serviceWorkerAgent();this._workers=new Map();this._registrations=new Map();this.enable();this._forceUpdateSetting=WebInspector.settings.createSetting("serviceWorkerUpdateOnReload",false);if(this._forceUpdateSetting.get())
this._forceUpdateSettingChanged();this._forceUpdateSetting.addChangeListener(this._forceUpdateSettingChanged,this);WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextCreated,this._executionContextCreated,this);}
WebInspector.ServiceWorkerManager.Events={WorkersUpdated:"WorkersUpdated",RegistrationUpdated:"RegistrationUpdated",RegistrationErrorAdded:"RegistrationErrorAdded",RegistrationDeleted:"RegistrationDeleted"}
WebInspector.ServiceWorkerManager.prototype={enable:function()
{if(this._enabled)
return;this._enabled=true;this._agent.enable();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._mainFrameNavigated,this);},disable:function()
{if(!this._enabled)
return;this._enabled=false;for(var worker of this._workers.values())
worker._connection.close();this._workers.clear();this._registrations.clear();this._agent.disable();WebInspector.targetManager.removeEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._mainFrameNavigated,this);},workers:function()
{return this._workers.values();},targetForVersionId:function(versionId)
{for(var pair of this._workers){if(pair[1]._versionId===versionId)
return pair[1]._target;}
return null;},hasWorkers:function()
{return!!this._workers.size;},registrations:function()
{return this._registrations;},findVersion:function(versionId)
{for(var registration of this.registrations().values()){var version=registration.versions.get(versionId);if(version)
return version;}
return null;},deleteRegistration:function(registrationId)
{var registration=this._registrations.get(registrationId);if(!registration)
return;if(registration._isRedundant()){this._registrations.delete(registrationId);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted,registration);return;}
registration._deleting=true;for(var version of registration.versions.values())
this.stopWorker(version.id);this._unregister(registration.scopeURL);},updateRegistration:function(registrationId)
{var registration=this._registrations.get(registrationId);if(!registration)
return;this._agent.updateRegistration(registration.scopeURL);},deliverPushMessage:function(registrationId,data)
{var registration=this._registrations.get(registrationId);if(!registration)
return;var origin=WebInspector.ParsedURL.extractOrigin(registration.scopeURL);this._agent.deliverPushMessage(origin,registrationId,data);},activateTarget:function(targetId)
{this._agent.activateTarget(targetId);},_unregister:function(scope)
{this._agent.unregister(scope);},startWorker:function(scope)
{this._agent.startWorker(scope);},skipWaiting:function(scope)
{this._agent.skipWaiting(scope);},stopWorker:function(versionId)
{this._agent.stopWorker(versionId);},inspectWorker:function(versionId)
{this._agent.inspectWorker(versionId);},getTargetInfo:function(targetId,callback)
{function innerCallback(error,targetInfo)
{if(error){console.error(error);callback(null);return;}
if(targetInfo)
callback(new WebInspector.TargetInfo(targetInfo));else
callback(null)}
this._agent.getTargetInfo(targetId,innerCallback);},_workerCreated:function(workerId,url,versionId)
{new WebInspector.ServiceWorker(this,workerId,url,versionId);this._updateWorkerStatuses();},_workerTerminated:function(workerId)
{var worker=this._workers.get(workerId);if(!worker)
return;worker._closeConnection();this._workers.delete(workerId);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.WorkersUpdated);},_dispatchMessage:function(workerId,message)
{var worker=this._workers.get(workerId);if(worker)
worker._connection.dispatch(message);},_workerRegistrationUpdated:function(registrations)
{for(var payload of registrations){var registration=this._registrations.get(payload.registrationId);if(!registration){registration=new WebInspector.ServiceWorkerRegistration(payload);this._registrations.set(payload.registrationId,registration);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated,registration);continue;}
registration._update(payload);if(registration._shouldBeRemoved()){this._registrations.delete(registration.id);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted,registration);}else{this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated,registration);}}},_workerVersionUpdated:function(versions)
{var registrations=new Set();for(var payload of versions){var registration=this._registrations.get(payload.registrationId);if(!registration)
continue;registration._updateVersion(payload);registrations.add(registration);}
for(var registration of registrations){if(registration._shouldBeRemoved()){this._registrations.delete(registration.id);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted,registration);}else{this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated,registration);}}
this._updateWorkerStatuses();},_updateWorkerStatuses:function()
{var versionById=new Map();for(var registration of this._registrations.valuesArray()){for(var version of registration.versions.valuesArray())
versionById.set(version.id,version.status);}
for(var worker of this._workers.valuesArray()){var status=versionById.get(worker.versionId());if(status)
worker.setStatus(status);}},_workerErrorReported:function(payload)
{var registration=this._registrations.get(payload.registrationId);if(!registration)
return;registration.errors.push(payload);this.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.RegistrationErrorAdded,{registration:registration,error:payload});},_mainFrameNavigated:function(event)
{},forceUpdateOnReloadSetting:function()
{return this._forceUpdateSetting;},_forceUpdateSettingChanged:function()
{this._agent.setForceUpdateOnPageLoad(this._forceUpdateSetting.get());},_executionContextCreated:function(event)
{var executionContext=(event.data);var target=executionContext.target();if(!target.parentTarget())
return;var worker=target.parentTarget()[WebInspector.ServiceWorker.Symbol];if(worker)
worker._setContextLabelFor(executionContext);},__proto__:WebInspector.SDKObject.prototype}
WebInspector.ServiceWorker=function(manager,workerId,url,versionId)
{this._manager=manager;this._agent=manager.target().serviceWorkerAgent();this._workerId=workerId;this._connection=new WebInspector.ServiceWorkerConnection(this._agent,workerId);this._url=url;this._versionId=versionId;var parsedURL=url.asParsedURL();this._name=parsedURL?parsedURL.lastPathComponentWithFragment():"#"+(++WebInspector.ServiceWorker._lastAnonymousTargetId);this._scope=parsedURL.host+parsedURL.folderPathComponents;this._manager._workers.set(workerId,this);this._target=WebInspector.targetManager.createTarget(this._name,WebInspector.Target.Type.ServiceWorker,this._connection,manager.target());this._target[WebInspector.ServiceWorker.Symbol]=this;this._manager.dispatchEventToListeners(WebInspector.ServiceWorkerManager.Events.WorkersUpdated);this._target.runtimeAgent().run();}
WebInspector.ServiceWorker.Symbol=Symbol("serviceWorker");WebInspector.ServiceWorker._lastAnonymousTargetId=0;WebInspector.ServiceWorker.prototype={name:function()
{return this._name;},url:function()
{return this._url;},versionId:function()
{return this._versionId;},scope:function()
{return this._scope;},stop:function()
{this._agent.stop(this._workerId);},setStatus:function(status)
{if(this._status===status)
return;this._status=status;for(var target of WebInspector.targetManager.targets()){if(target.parentTarget()!==this._target)
continue;for(var context of target.runtimeModel.executionContexts())
this._setContextLabelFor(context);}},_setContextLabelFor:function(context)
{var parsedUrl=context.origin.asParsedURL();var label=parsedUrl?parsedUrl.lastPathComponentWithFragment():context.name;if(this._status)
context.setLabel(label+" #"+this._versionId+" ("+this._status+")");else
context.setLabel(label);},_closeConnection:function()
{this._connection._close();delete this._connection;}}
WebInspector.ServiceWorkerDispatcher=function(manager)
{this._manager=manager;}
WebInspector.ServiceWorkerDispatcher.prototype={workerCreated:function(workerId,url,versionId)
{this._manager._workerCreated(workerId,url,versionId);},workerTerminated:function(workerId)
{this._manager._workerTerminated(workerId);},dispatchMessage:function(workerId,message)
{this._manager._dispatchMessage(workerId,message);},workerRegistrationUpdated:function(registrations)
{this._manager._workerRegistrationUpdated(registrations);},workerVersionUpdated:function(versions)
{this._manager._workerVersionUpdated(versions);},workerErrorReported:function(errorMessage)
{this._manager._workerErrorReported(errorMessage);}}
WebInspector.ServiceWorkerConnection=function(agent,workerId)
{InspectorBackendClass.Connection.call(this);this.suppressErrorsForDomains(["Worker","Page","CSS","DOM","DOMStorage","Database","Network","IndexedDB"]);this._agent=agent;this._workerId=workerId;}
WebInspector.ServiceWorkerConnection.prototype={sendMessage:function(messageObject)
{this._agent.sendMessage(this._workerId,JSON.stringify(messageObject));},_close:function()
{this.connectionClosed("worker_terminated");},__proto__:InspectorBackendClass.Connection.prototype}
WebInspector.TargetInfo=function(payload)
{this.id=payload.id;this.type=payload.type;this.title=payload.title;this.url=payload.url;}
WebInspector.TargetInfo.prototype={isWebContents:function()
{return this.type=="web_contents";},isFrame:function()
{return this.type=="frame";},}
WebInspector.ServiceWorkerVersion=function(registration,payload)
{this.registration=registration;this._update(payload);}
WebInspector.ServiceWorkerVersion.Modes={Installing:"installing",Waiting:"waiting",Active:"active",Redundant:"redundant"}
WebInspector.ServiceWorkerVersion.prototype={_update:function(payload)
{this.id=payload.versionId;this.scriptURL=payload.scriptURL;this.securityOrigin=payload.scriptURL.asParsedURL().securityOrigin();this.runningStatus=payload.runningStatus;this.status=payload.status;this.scriptLastModified=payload.scriptLastModified;this.scriptResponseTime=payload.scriptResponseTime;this.controlledClients=[];for(var i=0;i<payload.controlledClients.length;++i)
this.controlledClients.push(payload.controlledClients[i]);},isStartable:function()
{return!this.registration.isDeleted&&this.isActivated()&&this.isStopped();},isStoppedAndRedundant:function()
{return this.runningStatus==ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped&&this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;},isStopped:function()
{return this.runningStatus==ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped;},isStarting:function()
{return this.runningStatus==ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Starting;},isRunning:function()
{return this.runningStatus==ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Running;},isStopping:function()
{return this.runningStatus==ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopping;},isNew:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.New;},isInstalling:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Installing;},isInstalled:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Installed;},isActivating:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Activating;},isActivated:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Activated;},isRedundant:function()
{return this.status==ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;},mode:function()
{if(this.isNew()||this.isInstalling())
return WebInspector.ServiceWorkerVersion.Modes.Installing;else if(this.isInstalled())
return WebInspector.ServiceWorkerVersion.Modes.Waiting;else if(this.isActivating()||this.isActivated())
return WebInspector.ServiceWorkerVersion.Modes.Active;return WebInspector.ServiceWorkerVersion.Modes.Redundant;}}
WebInspector.ServiceWorkerRegistration=function(payload)
{this._update(payload);this.versions=new Map();this._deleting=false;this.errors=[];}
WebInspector.ServiceWorkerRegistration.prototype={_update:function(payload)
{this._fingerprint=Symbol("fingerprint");this.id=payload.registrationId;this.scopeURL=payload.scopeURL;this.securityOrigin=payload.scopeURL.asParsedURL().securityOrigin();this.isDeleted=payload.isDeleted;this.forceUpdateOnPageLoad=payload.forceUpdateOnPageLoad;},fingerprint:function()
{return this._fingerprint;},versionsByMode:function()
{var result=new Map();for(var version of this.versions.values())
result.set(version.mode(),version);return result;},_updateVersion:function(payload)
{this._fingerprint=Symbol("fingerprint");var version=this.versions.get(payload.versionId);if(!version){version=new WebInspector.ServiceWorkerVersion(this,payload);this.versions.set(payload.versionId,version);return version;}
version._update(payload);return version;},_isRedundant:function()
{for(var version of this.versions.values()){if(!version.isStoppedAndRedundant())
return false;}
return true;},_shouldBeRemoved:function()
{return this._isRedundant()&&(!this.errors.length||this._deleting);},clearErrors:function()
{this._fingerprint=Symbol("fingerprint");this.errors=[];}};WebInspector.TracingManagerClient=function()
{}
WebInspector.TracingManagerClient.prototype={tracingStarted:function(){},traceEventsCollected:function(events){},tracingComplete:function(){},tracingBufferUsage:function(usage){},eventsRetrievalProgress:function(progress){}}
WebInspector.TracingManager=function(target)
{this._target=target;target.registerTracingDispatcher(new WebInspector.TracingDispatcher(this));this._activeClient=null;this._eventBufferSize=0;this._eventsRetrieved=0;}
WebInspector.TracingManager.EventPayload;WebInspector.TracingManager.TransferMode={ReportEvents:"ReportEvents",ReturnAsStream:"ReturnAsStream"};WebInspector.TracingManager.prototype={target:function()
{return this._target;},_bufferUsage:function(usage,eventCount,percentFull)
{this._eventBufferSize=eventCount;this._activeClient.tracingBufferUsage(usage||percentFull||0);},_eventsCollected:function(events)
{this._activeClient.traceEventsCollected(events);this._eventsRetrieved+=events.length;if(!this._eventBufferSize)
return;if(this._eventsRetrieved>this._eventBufferSize)
this._eventsRetrieved=this._eventBufferSize;this._activeClient.eventsRetrievalProgress(this._eventsRetrieved/this._eventBufferSize);},_tracingComplete:function()
{this._eventBufferSize=0;this._eventsRetrieved=0;this._activeClient.tracingComplete();this._activeClient=null;this._finishing=false;},start:function(client,categoryFilter,options,callback)
{if(this._activeClient)
throw new Error("Tracing is already started");var bufferUsageReportingIntervalMs=500;this._activeClient=client;this._target.tracingAgent().start(categoryFilter,options,bufferUsageReportingIntervalMs,WebInspector.TracingManager.TransferMode.ReportEvents,callback);this._activeClient.tracingStarted();},stop:function()
{if(!this._activeClient)
throw new Error("Tracing is not started");if(this._finishing)
throw new Error("Tracing is already being stopped");this._finishing=true;this._target.tracingAgent().end();}}
WebInspector.TracingDispatcher=function(tracingManager)
{this._tracingManager=tracingManager;}
WebInspector.TracingDispatcher.prototype={bufferUsage:function(usage,eventCount,percentFull)
{this._tracingManager._bufferUsage(usage,eventCount,percentFull);},dataCollected:function(data)
{this._tracingManager._eventsCollected(data);},tracingComplete:function()
{this._tracingManager._tracingComplete();}};WebInspector.TracingModel=function(backingStorage)
{this._backingStorage=backingStorage;this._firstWritePending=true;this.reset();}
WebInspector.TracingModel.Phase={Begin:"B",End:"E",Complete:"X",Instant:"I",AsyncBegin:"S",AsyncStepInto:"T",AsyncStepPast:"p",AsyncEnd:"F",NestableAsyncBegin:"b",NestableAsyncEnd:"e",NestableAsyncInstant:"n",FlowBegin:"s",FlowStep:"t",FlowEnd:"f",Metadata:"M",Counter:"C",Sample:"P",CreateObject:"N",SnapshotObject:"O",DeleteObject:"D"};WebInspector.TracingModel.MetadataEvent={ProcessSortIndex:"process_sort_index",ProcessName:"process_name",ThreadSortIndex:"thread_sort_index",ThreadName:"thread_name"}
WebInspector.TracingModel.TopLevelEventCategory="toplevel";WebInspector.TracingModel.DevToolsMetadataEventCategory="disabled-by-default-devtools.timeline";WebInspector.TracingModel.DevToolsTimelineEventCategory="disabled-by-default-devtools.timeline";WebInspector.TracingModel.FrameLifecycleEventCategory="cc,devtools";WebInspector.TracingModel.isNestableAsyncPhase=function(phase)
{return phase==="b"||phase==="e"||phase==="n";}
WebInspector.TracingModel.isAsyncBeginPhase=function(phase)
{return phase==="S"||phase==="b";}
WebInspector.TracingModel.isAsyncPhase=function(phase)
{return WebInspector.TracingModel.isNestableAsyncPhase(phase)||phase==="S"||phase==="T"||phase==="F"||phase==="p";}
WebInspector.TracingModel.isFlowPhase=function(phase)
{return phase==="s"||phase==="t"||phase==="f";}
WebInspector.TracingModel.isTopLevelEvent=function(event)
{return event.hasCategory(WebInspector.TracingModel.TopLevelEventCategory)||event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory)&&event.name==="Program";}
WebInspector.BackingStorage=function()
{}
WebInspector.BackingStorage.prototype={appendString:function(string){},appendAccessibleString:function(string){},finishWriting:function(){},reset:function(){},}
WebInspector.TracingModel.prototype={devToolsMetadataEvents:function()
{return this._devToolsMetadataEvents;},setEventsForTest:function(events)
{this.reset();this.addEvents(events);this.tracingComplete();},addEvents:function(events)
{for(var i=0;i<events.length;++i)
this._addEvent(events[i]);},tracingComplete:function()
{this._processPendingAsyncEvents();this._backingStorage.appendString(this._firstWritePending?"[]":"]");this._backingStorage.finishWriting();this._firstWritePending=false;for(var process of Object.values(this._processById)){for(var thread of Object.values(process._threads))
thread.tracingComplete();}},reset:function()
{this._processById={};this._processByName=new Map();this._minimumRecordTime=0;this._maximumRecordTime=0;this._devToolsMetadataEvents=[];if(!this._firstWritePending)
this._backingStorage.reset();this._firstWritePending=true;this._asyncEvents=[];this._openAsyncEvents=new Map();this._openNestableAsyncEvents=new Map();this._parsedCategories=new Map();},_addEvent:function(payload)
{var process=this._processById[payload.pid];if(!process){process=new WebInspector.TracingModel.Process(this,payload.pid);this._processById[payload.pid]=process;}
var eventsDelimiter=",\n";this._backingStorage.appendString(this._firstWritePending?"[":eventsDelimiter);this._firstWritePending=false;var stringPayload=JSON.stringify(payload);var isAccessible=payload.ph===WebInspector.TracingModel.Phase.SnapshotObject;var backingStorage=null;var keepStringsLessThan=10000;if(isAccessible&&stringPayload.length>keepStringsLessThan)
backingStorage=this._backingStorage.appendAccessibleString(stringPayload);else
this._backingStorage.appendString(stringPayload);var timestamp=payload.ts/1000;if(timestamp&&(!this._minimumRecordTime||timestamp<this._minimumRecordTime))
this._minimumRecordTime=timestamp;var endTimeStamp=(payload.ts+(payload.dur||0))/1000;this._maximumRecordTime=Math.max(this._maximumRecordTime,endTimeStamp);var event=process._addEvent(payload);if(!event)
return;if(WebInspector.TracingModel.isAsyncPhase(payload.ph))
this._asyncEvents.push(event);event._setBackingStorage(backingStorage);if(event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory))
this._devToolsMetadataEvents.push(event);if(payload.ph!==WebInspector.TracingModel.Phase.Metadata)
return;switch(payload.name){case WebInspector.TracingModel.MetadataEvent.ProcessSortIndex:process._setSortIndex(payload.args["sort_index"]);break;case WebInspector.TracingModel.MetadataEvent.ProcessName:var processName=payload.args["name"];process._setName(processName);this._processByName.set(processName,process);break;case WebInspector.TracingModel.MetadataEvent.ThreadSortIndex:process.threadById(payload.tid)._setSortIndex(payload.args["sort_index"]);break;case WebInspector.TracingModel.MetadataEvent.ThreadName:process.threadById(payload.tid)._setName(payload.args["name"]);break;}},minimumRecordTime:function()
{return this._minimumRecordTime;},maximumRecordTime:function()
{return this._maximumRecordTime;},sortedProcesses:function()
{return WebInspector.TracingModel.NamedObject._sort(Object.values(this._processById));},processByName:function(name)
{return this._processByName.get(name);},threadByName:function(processName,threadName)
{var process=this.processByName(processName);return process&&process.threadByName(threadName);},_processPendingAsyncEvents:function()
{this._asyncEvents.sort(WebInspector.TracingModel.Event.compareStartTime);for(var i=0;i<this._asyncEvents.length;++i){var event=this._asyncEvents[i];if(WebInspector.TracingModel.isNestableAsyncPhase(event.phase))
this._addNestableAsyncEvent(event);else
this._addAsyncEvent(event);}
this._asyncEvents=[];this._closeOpenAsyncEvents();},_closeOpenAsyncEvents:function()
{for(var event of this._openAsyncEvents.values()){event.setEndTime(this._maximumRecordTime);event.steps[0].setEndTime(this._maximumRecordTime);}
this._openAsyncEvents.clear();for(var eventStack of this._openNestableAsyncEvents.values()){while(eventStack.length)
eventStack.pop().setEndTime(this._maximumRecordTime);}
this._openNestableAsyncEvents.clear();},_addNestableAsyncEvent:function(event)
{var phase=WebInspector.TracingModel.Phase;var key=event.categoriesString+"."+event.id;var openEventsStack=this._openNestableAsyncEvents.get(key);switch(event.phase){case phase.NestableAsyncBegin:if(!openEventsStack){openEventsStack=[];this._openNestableAsyncEvents.set(key,openEventsStack);}
var asyncEvent=new WebInspector.TracingModel.AsyncEvent(event);openEventsStack.push(asyncEvent);event.thread._addAsyncEvent(asyncEvent);break;case phase.NestableAsyncInstant:if(openEventsStack&&openEventsStack.length)
openEventsStack.peekLast()._addStep(event);break;case phase.NestableAsyncEnd:if(!openEventsStack||!openEventsStack.length)
break;var top=openEventsStack.pop();if(top.name!==event.name){console.error("Begin/end event mismatch for nestable async event, "+top.name+" vs. "+event.name);break;}
top._addStep(event);}},_addAsyncEvent:function(event)
{var phase=WebInspector.TracingModel.Phase;var key=event.categoriesString+"."+event.name+"."+event.id;var asyncEvent=this._openAsyncEvents.get(key);if(event.phase===phase.AsyncBegin){if(asyncEvent){console.error("Event "+event.name+" has already been started");return;}
asyncEvent=new WebInspector.TracingModel.AsyncEvent(event);this._openAsyncEvents.set(key,asyncEvent);event.thread._addAsyncEvent(asyncEvent);return;}
if(!asyncEvent){return;}
if(event.phase===phase.AsyncEnd){asyncEvent._addStep(event);this._openAsyncEvents.delete(key);return;}
if(event.phase===phase.AsyncStepInto||event.phase===phase.AsyncStepPast){var lastStep=asyncEvent.steps.peekLast();if(lastStep.phase!==phase.AsyncBegin&&lastStep.phase!==event.phase){console.assert(false,"Async event step phase mismatch: "+lastStep.phase+" at "+lastStep.startTime+" vs. "+event.phase+" at "+event.startTime);return;}
asyncEvent._addStep(event);return;}
console.assert(false,"Invalid async event phase");},_parsedCategoriesForString:function(str)
{var parsedCategories=this._parsedCategories.get(str);if(!parsedCategories){parsedCategories=new Set(str.split(","));this._parsedCategories.set(str,parsedCategories);}
return parsedCategories;}}
WebInspector.TracingModel.Event=function(categories,name,phase,startTime,thread)
{this.categoriesString=categories;this._parsedCategories=thread._model._parsedCategoriesForString(categories);this.name=name;this.phase=phase;this.startTime=startTime;this.thread=thread;this.args={};this.warning=null;this.initiator=null;this.stackTrace=null;this.previewElement=null;this.url=null;this.backendNodeId=0;this.selfTime=0;}
WebInspector.TracingModel.Event.fromPayload=function(payload,thread)
{var event=new WebInspector.TracingModel.Event(payload.cat,payload.name,(payload.ph),payload.ts/1000,thread);if(payload.args)
event.addArgs(payload.args);else
console.error("Missing mandatory event argument 'args' at "+payload.ts/1000);if(typeof payload.dur==="number")
event.setEndTime((payload.ts+payload.dur)/1000);if(payload.id)
event.id=payload.id;if(payload.bind_id)
event.bind_id=payload.bind_id;return event;}
WebInspector.TracingModel.Event.prototype={hasCategory:function(categoryName)
{return this._parsedCategories.has(categoryName);},setEndTime:function(endTime)
{if(endTime<this.startTime){console.assert(false,"Event out of order: "+this.name);return;}
this.endTime=endTime;this.duration=endTime-this.startTime;},addArgs:function(args)
{for(var name in args){if(name in this.args)
console.error("Same argument name ("+name+") is used for begin and end phases of "+this.name);this.args[name]=args[name];}},_complete:function(endEvent)
{if(endEvent.args)
this.addArgs(endEvent.args);else
console.error("Missing mandatory event argument 'args' at "+endEvent.startTime);this.setEndTime(endEvent.startTime);},_setBackingStorage:function(backingStorage)
{}}
WebInspector.TracingModel.Event.compareStartTime=function(a,b)
{return a.startTime-b.startTime;}
WebInspector.TracingModel.Event.compareStartAndEndTime=function(a,b)
{return a.startTime-b.startTime||(b.endTime!=undefined&&a.endTime!==undefined&&b.endTime-a.endTime)||0;}
WebInspector.TracingModel.Event.orderedCompareStartTime=function(a,b)
{return a.startTime-b.startTime||a.ordinal-b.ordinal||-1;}
WebInspector.TracingModel.ObjectSnapshot=function(category,name,startTime,thread)
{WebInspector.TracingModel.Event.call(this,category,name,WebInspector.TracingModel.Phase.SnapshotObject,startTime,thread);}
WebInspector.TracingModel.ObjectSnapshot.fromPayload=function(payload,thread)
{var snapshot=new WebInspector.TracingModel.ObjectSnapshot(payload.cat,payload.name,payload.ts/1000,thread);if(payload.id)
snapshot.id=payload.id;if(!payload.args||!payload.args["snapshot"]){console.error("Missing mandatory 'snapshot' argument at "+payload.ts/1000);return snapshot;}
if(payload.args)
snapshot.addArgs(payload.args);return snapshot;}
WebInspector.TracingModel.ObjectSnapshot.prototype={requestObject:function(callback)
{var snapshot=this.args["snapshot"];if(snapshot){callback(snapshot);return;}
this._backingStorage().then(onRead,callback.bind(null,null));function onRead(result)
{if(!result){callback(null);return;}
try{var payload=JSON.parse(result);callback(payload["args"]["snapshot"]);}catch(e){WebInspector.console.error("Malformed event data in backing storage");callback(null);}}},objectPromise:function()
{if(!this._objectPromise)
this._objectPromise=new Promise(this.requestObject.bind(this));return this._objectPromise;},_setBackingStorage:function(backingStorage)
{if(!backingStorage)
return;this._backingStorage=backingStorage;this.args={};},__proto__:WebInspector.TracingModel.Event.prototype}
WebInspector.TracingModel.AsyncEvent=function(startEvent)
{WebInspector.TracingModel.Event.call(this,startEvent.categoriesString,startEvent.name,startEvent.phase,startEvent.startTime,startEvent.thread)
this.addArgs(startEvent.args);this.steps=[startEvent];}
WebInspector.TracingModel.AsyncEvent.prototype={_addStep:function(event)
{this.steps.push(event);if(event.phase===WebInspector.TracingModel.Phase.AsyncEnd||event.phase===WebInspector.TracingModel.Phase.NestableAsyncEnd){this.setEndTime(event.startTime);this.steps[0].setEndTime(event.startTime);}},__proto__:WebInspector.TracingModel.Event.prototype}
WebInspector.TracingModel.NamedObject=function()
{}
WebInspector.TracingModel.NamedObject.prototype={_setName:function(name)
{this._name=name;},name:function()
{return this._name;},_setSortIndex:function(sortIndex)
{this._sortIndex=sortIndex;},}
WebInspector.TracingModel.NamedObject._sort=function(array)
{function comparator(a,b)
{return a._sortIndex!==b._sortIndex?a._sortIndex-b._sortIndex:a.name().localeCompare(b.name());}
return array.sort(comparator);}
WebInspector.TracingModel.Process=function(model,id)
{WebInspector.TracingModel.NamedObject.call(this);this._setName("Process "+id);this._id=id;this._threads={};this._threadByName=new Map();this._model=model;}
WebInspector.TracingModel.Process.prototype={id:function()
{return this._id;},threadById:function(id)
{var thread=this._threads[id];if(!thread){thread=new WebInspector.TracingModel.Thread(this,id);this._threads[id]=thread;}
return thread;},threadByName:function(name)
{return this._threadByName.get(name)||null;},_setThreadByName:function(name,thread)
{this._threadByName.set(name,thread);},_addEvent:function(payload)
{return this.threadById(payload.tid)._addEvent(payload);},sortedThreads:function()
{return WebInspector.TracingModel.NamedObject._sort(Object.values(this._threads));},__proto__:WebInspector.TracingModel.NamedObject.prototype}
WebInspector.TracingModel.Thread=function(process,id)
{WebInspector.TracingModel.NamedObject.call(this);this._process=process;this._setName("Thread "+id);this._events=[];this._asyncEvents=[];this._id=id;this._model=process._model;}
WebInspector.TracingModel.Thread.prototype={tracingComplete:function()
{this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartAndEndTime);this._events.stableSort(WebInspector.TracingModel.Event.compareStartTime);var phases=WebInspector.TracingModel.Phase;var stack=[];for(var i=0;i<this._events.length;++i){var e=this._events[i];e.ordinal=i;switch(e.phase){case phases.End:this._events[i]=null;if(!stack.length)
continue;var top=stack.pop();if(top.name!==e.name||top.categoriesString!==e.categoriesString)
console.error("B/E events mismatch at "+top.startTime+" ("+top.name+") vs. "+e.startTime+" ("+e.name+")");else
top._complete(e);break;case phases.Begin:stack.push(e);break;}}
this._events.remove(null,false);},_addEvent:function(payload)
{var event=payload.ph===WebInspector.TracingModel.Phase.SnapshotObject?WebInspector.TracingModel.ObjectSnapshot.fromPayload(payload,this):WebInspector.TracingModel.Event.fromPayload(payload,this);if(WebInspector.TracingModel.isTopLevelEvent(event)){if(this._lastTopLevelEvent&&this._lastTopLevelEvent.endTime>event.startTime)
return null;this._lastTopLevelEvent=event;}
this._events.push(event);return event;},_addAsyncEvent:function(asyncEvent)
{this._asyncEvents.push(asyncEvent);},_setName:function(name)
{WebInspector.TracingModel.NamedObject.prototype._setName.call(this,name);this._process._setThreadByName(name,this);},id:function()
{return this._id;},process:function()
{return this._process;},events:function()
{return this._events;},asyncEvents:function()
{return this._asyncEvents;},__proto__:WebInspector.TracingModel.NamedObject.prototype};WebInspector.WorkerManager=function(target)
{WebInspector.SDKObject.call(this,target);target.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));this._lastAnonymousTargetId=0;this._connections=new Map();this._targetsByWorkerId=new Map();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged,this);this._onSuspendStateChanged();this.enable();}
WebInspector.WorkerManager.prototype={enable:function()
{if(this._enabled)
return;this._enabled=true;this.target().workerAgent().enable();this.target().resourceTreeModel.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._mainFrameNavigated,this);},disable:function()
{if(!this._enabled)
return;this._enabled=false;this._reset();this.target().workerAgent().disable();this.target().resourceTreeModel.removeEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._mainFrameNavigated,this);},dispose:function()
{this._reset();},_reset:function()
{for(var connection of this._connections.values())
connection._close();this._connections.clear();this._targetsByWorkerId.clear();},_onSuspendStateChanged:function()
{var suspended=WebInspector.targetManager.allTargetsSuspended();this.target().workerAgent().setWaitForDebuggerOnStart(!suspended);},_workerCreated:function(workerId,url,waitingForDebugger)
{var connection=new WebInspector.WorkerConnection(this,workerId);this._connections.set(workerId,connection);var parsedURL=url.asParsedURL();var workerName=parsedURL?parsedURL.lastPathComponentWithFragment():"#"+(++this._lastAnonymousTargetId);var target=WebInspector.targetManager.createTarget(workerName,WebInspector.Target.Type.DedicatedWorker,connection,this.target());this._targetsByWorkerId.set(workerId,target);var mainIsServiceWorker=WebInspector.targetManager.mainTarget().isServiceWorker();if(mainIsServiceWorker&&waitingForDebugger)
target.debuggerAgent().pause();target.runtimeAgent().run();},_workerTerminated:function(workerId)
{var connection=this._connections.get(workerId);if(connection)
connection._close();this._connections.delete(workerId);this._targetsByWorkerId.delete(workerId);},_dispatchMessageFromWorker:function(workerId,message)
{var connection=this._connections.get(workerId);if(connection)
connection.dispatch(message);},_mainFrameNavigated:function(event)
{this._reset();},targetByWorkerId:function(workerId)
{return this._targetsByWorkerId.get(workerId)||null;},__proto__:WebInspector.SDKObject.prototype}
WebInspector.WorkerDispatcher=function(workerManager)
{this._workerManager=workerManager;}
WebInspector.WorkerDispatcher.prototype={workerCreated:function(workerId,url,waitingForDebugger)
{this._workerManager._workerCreated(workerId,url,waitingForDebugger);},workerTerminated:function(workerId)
{this._workerManager._workerTerminated(workerId);},dispatchMessageFromWorker:function(workerId,message)
{this._workerManager._dispatchMessageFromWorker(workerId,message);}}
WebInspector.WorkerConnection=function(workerManager,workerId)
{InspectorBackendClass.Connection.call(this);this.suppressErrorsForDomains(["Worker","Page","CSS","DOM","DOMStorage","Database","Network","IndexedDB"]);this._agent=workerManager.target().workerAgent();this._workerId=workerId;}
WebInspector.WorkerConnection.prototype={sendMessage:function(messageObject)
{this._agent.sendMessageToWorker(this._workerId,JSON.stringify(messageObject));},_close:function()
{this.connectionClosed("worker_terminated");},__proto__:InspectorBackendClass.Connection.prototype};WebInspector.RuntimeModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.RuntimeModel,target);this._agent=target.runtimeAgent();this.target().registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));if(target.hasJSContext())
this._agent.enable();this._executionContextById={};if(WebInspector.moduleSetting("customFormatters").get())
this._agent.setCustomObjectFormatterEnabled(true);WebInspector.moduleSetting("customFormatters").addChangeListener(this._customFormattersStateChanged.bind(this));}
WebInspector.RuntimeModel.Events={ExecutionContextCreated:"ExecutionContextCreated",ExecutionContextDestroyed:"ExecutionContextDestroyed",ExecutionContextChanged:"ExecutionContextChanged"}
WebInspector.RuntimeModel._privateScript="private script";WebInspector.RuntimeModel.prototype={executionContexts:function()
{return Object.values(this._executionContextById);},defaultExecutionContext:function()
{for(var context of Object.values(this._executionContextById)){if(context.isDefault)
return context;}
return null;},executionContext:function(id)
{return this._executionContextById[id]||null;},_executionContextCreated:function(context)
{if(context.name==WebInspector.RuntimeModel._privateScript&&!context.origin&&!Runtime.experiments.isEnabled("privateScriptInspection")){return;}
var executionContext=new WebInspector.ExecutionContext(this.target(),context.id,context.name,context.origin,context.isDefault,context.frameId);this._executionContextById[executionContext.id]=executionContext;this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextCreated,executionContext);},_executionContextDestroyed:function(executionContextId)
{var executionContext=this._executionContextById[executionContextId];if(!executionContext)
return;delete this._executionContextById[executionContextId];this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed,executionContext);},_executionContextsCleared:function()
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(this.target());if(debuggerModel)
debuggerModel.globalObjectCleared();var contexts=this.executionContexts();this._executionContextById={};for(var i=0;i<contexts.length;++i)
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed,contexts[i]);},createRemoteObject:function(payload)
{console.assert(typeof payload==="object","Remote object payload should only be an object");return new WebInspector.RemoteObjectImpl(this.target(),payload.objectId,payload.type,payload.subtype,payload.value,payload.description,payload.preview,payload.customPreview);},createScopeRemoteObject:function(payload,scopeRef)
{return new WebInspector.ScopeRemoteObject(this.target(),payload.objectId,scopeRef,payload.type,payload.subtype,payload.value,payload.description,payload.preview);},createRemoteObjectFromPrimitiveValue:function(value)
{return new WebInspector.RemoteObjectImpl(this.target(),undefined,typeof value,undefined,value);},createRemotePropertyFromPrimitiveValue:function(name,value)
{return new WebInspector.RemoteObjectProperty(name,this.createRemoteObjectFromPrimitiveValue(value));},_customFormattersStateChanged:function(event)
{var enabled=(event.data);this._agent.setCustomObjectFormatterEnabled(enabled);},compileScript:function(expression,sourceURL,persistScript,executionContextId,callback)
{this._agent.compileScript(expression,sourceURL,persistScript,executionContextId,innerCallback);function innerCallback(error,scriptId,exceptionDetails)
{if(error){console.error(error);return;}
if(callback)
callback(scriptId,exceptionDetails);}},runScript:function(scriptId,executionContextId,objectGroup,doNotPauseOnExceptionsAndMuteConsole,includeCommandLineAPI,callback)
{this._agent.runScript(scriptId,executionContextId,objectGroup,doNotPauseOnExceptionsAndMuteConsole,includeCommandLineAPI,innerCallback);function innerCallback(error,result,exceptionDetails)
{if(error){console.error(error);return;}
if(callback)
callback(result,exceptionDetails);}},_inspectRequested:function(payload,hints)
{var object=this.createRemoteObject(payload);if(hints.copyToClipboard){this._copyRequested(object);return;}
if(object.isNode()){WebInspector.Revealer.revealPromise(object).then(object.release.bind(object));return;}
if(object.type==="function"){WebInspector.RemoteFunction.objectAsFunction(object).targetFunctionDetails().then(didGetDetails);return;}
function didGetDetails(response)
{object.release();if(!response||!response.location)
return;WebInspector.Revealer.reveal(response.location);}
object.release();},_copyRequested:function(object)
{if(!object.objectId){InspectorFrontendHost.copyText(object.value);return;}
object.callFunctionJSON(toStringForClipboard,[{value:object.subtype}],InspectorFrontendHost.copyText.bind(InspectorFrontendHost));function toStringForClipboard(subtype)
{if(subtype==="node")
return this.outerHTML;if(subtype&&typeof this==="undefined")
return subtype+"";try{return JSON.stringify(this,null," ");}catch(e){return""+this;}}},__proto__:WebInspector.SDKModel.prototype}
WebInspector.RuntimeDispatcher=function(runtimeModel)
{this._runtimeModel=runtimeModel;}
WebInspector.RuntimeDispatcher.prototype={executionContextCreated:function(context)
{this._runtimeModel._executionContextCreated(context);},executionContextDestroyed:function(executionContextId)
{this._runtimeModel._executionContextDestroyed(executionContextId);},executionContextsCleared:function()
{this._runtimeModel._executionContextsCleared();},inspectRequested:function(payload,hints)
{this._runtimeModel._inspectRequested(payload,hints);}}
WebInspector.ExecutionContext=function(target,id,name,origin,isDefault,frameId)
{WebInspector.SDKObject.call(this,target);this.id=id;this.name=name;this.origin=origin;this.isDefault=isDefault;this.runtimeModel=target.runtimeModel;this.debuggerModel=WebInspector.DebuggerModel.fromTarget(target);this.frameId=frameId;var parsedUrl=origin.asParsedURL();this._label=parsedUrl?parsedUrl.lastPathComponentWithFragment():name;}
WebInspector.ExecutionContext.comparator=function(a,b)
{function targetWeight(target)
{if(target.isPage())
return 3;if(target.isDedicatedWorker())
return 2;return 1;}
var weightDiff=targetWeight(a.target())-targetWeight(b.target());if(weightDiff)
return-weightDiff;var frameIdDiff=String.hashCode(a.frameId)-String.hashCode(b.frameId);if(frameIdDiff)
return frameIdDiff;if(a.isDefault)
return-1;if(b.isDefault)
return+1;return a.name.localeCompare(b.name);}
WebInspector.ExecutionContext.prototype={evaluate:function(expression,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,userGesture,callback)
{if(this.debuggerModel.selectedCallFrame()){this.debuggerModel.evaluateOnSelectedCallFrame(expression,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,callback);return;}
this._evaluateGlobal.apply(this,arguments);},globalObject:function(objectGroup,returnByValue,generatePreview,callback)
{this._evaluateGlobal("this",objectGroup,false,true,returnByValue,generatePreview,false,callback);},_evaluateGlobal:function(expression,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,returnByValue,generatePreview,userGesture,callback)
{if(!expression){expression="this";}
function evalCallback(error,result,wasThrown,exceptionDetails)
{if(error){console.error(error);callback(null,false);return;}
if(returnByValue)
callback(null,!!wasThrown,wasThrown?null:result,exceptionDetails);else
callback(this.runtimeModel.createRemoteObject(result),!!wasThrown,undefined,exceptionDetails);}
this.target().runtimeAgent().evaluate(expression,objectGroup,includeCommandLineAPI,doNotPauseOnExceptionsAndMuteConsole,this.id,returnByValue,generatePreview,userGesture,evalCallback.bind(this));},completionsForExpression:function(expressionString,text,cursorOffset,prefix,force,completionsReadyCallback)
{var lastIndex=expressionString.length-1;var dotNotation=(expressionString[lastIndex]===".");var bracketNotation=(expressionString[lastIndex]==="[");if(dotNotation||bracketNotation)
expressionString=expressionString.substr(0,lastIndex);if(expressionString&&parseInt(expressionString,10)==expressionString){completionsReadyCallback([]);return;}
if(!prefix&&!expressionString&&!force){completionsReadyCallback([]);return;}
if(!expressionString&&this.debuggerModel.selectedCallFrame())
this.debuggerModel.selectedCallFrame().variableNames(receivedPropertyNames.bind(this));else
this.evaluate(expressionString,"completion",true,true,false,false,false,evaluated.bind(this));function evaluated(result,wasThrown)
{if(!result||wasThrown){completionsReadyCallback([]);return;}
function extractTarget(object)
{if(!object)
return Promise.resolve((null));if(object.type!=="object"||object.subtype!=="proxy")
return Promise.resolve((object));return object.getOwnPropertiesPromise().then(extractTargetFromProperties).then(extractTarget);}
function extractTargetFromProperties(properties)
{var internalProperties=properties.internalProperties||[];var target=internalProperties.find(property=>property.name==="[[Target]]");return target?target.value:null;}
function getCompletions(type)
{var object;if(type==="string")
object=new String("");else if(type==="number")
object=new Number(0);else if(type==="boolean")
object=new Boolean(false);else
object=this;var resultSet={};try{for(var o=object;o;o=Object.getPrototypeOf(o)){if(type==="array"&&o===object&&ArrayBuffer.isView(o)&&o.length>9999)
continue;var names=Object.getOwnPropertyNames(o);var isArray=Array.isArray(o);for(var i=0;i<names.length;++i){if(isArray&&/^[0-9]/.test(names[i]))
continue;resultSet[names[i]]=true;}}}catch(e){}
return resultSet;}
function completionsForObject(object)
{if(!object)
receivedPropertyNames.call(this,null);else if(object.type==="object"||object.type==="function")
object.callFunctionJSON(getCompletions,[WebInspector.RemoteObject.toCallArgument(object.subtype)],receivedPropertyNames.bind(this));else if(object.type==="string"||object.type==="number"||object.type==="boolean")
this.evaluate("("+getCompletions+")(\""+result.type+"\")","completion",false,true,true,false,false,receivedPropertyNamesFromEval.bind(this));}
extractTarget(result).then(completionsForObject.bind(this));}
function receivedPropertyNamesFromEval(notRelevant,wasThrown,result)
{this.target().runtimeAgent().releaseObjectGroup("completion");if(result&&!wasThrown)
receivedPropertyNames.call(this,(result.value));else
completionsReadyCallback([]);}
function receivedPropertyNames(propertyNames)
{this.target().runtimeAgent().releaseObjectGroup("completion");if(!propertyNames){completionsReadyCallback([]);return;}
var includeCommandLineAPI=(!dotNotation&&!bracketNotation);if(includeCommandLineAPI){const commandLineAPI=["dir","dirxml","keys","values","profile","profileEnd","monitorEvents","unmonitorEvents","inspect","copy","clear","getEventListeners","debug","undebug","monitor","unmonitor","table","$","$$","$x"];for(var i=0;i<commandLineAPI.length;++i)
propertyNames[commandLineAPI[i]]=true;}
this._reportCompletions(completionsReadyCallback,dotNotation,bracketNotation,expressionString,prefix,Object.keys(propertyNames));}},_reportCompletions:function(completionsReadyCallback,dotNotation,bracketNotation,expressionString,prefix,properties){if(bracketNotation){if(prefix.length&&prefix[0]==="'")
var quoteUsed="'";else
var quoteUsed="\"";}
var results=[];if(!expressionString){const keywords=["break","case","catch","continue","default","delete","do","else","finally","for","function","if","in","instanceof","new","return","switch","this","throw","try","typeof","var","void","while","with"];properties=properties.concat(keywords);}
properties.sort();for(var i=0;i<properties.length;++i){var property=properties[i];if(dotNotation&&!/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/.test(property))
continue;if(bracketNotation){if(!/^[0-9]+$/.test(property))
property=quoteUsed+property.escapeCharacters(quoteUsed+"\\")+quoteUsed;property+="]";}
if(property.length<prefix.length)
continue;if(prefix.length&&!property.startsWith(prefix))
continue;results.push(property.split("\n").join("\\n"));}
completionsReadyCallback(results);},label:function()
{return this._label;},setLabel:function(label)
{this._label=label;this.runtimeModel.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextChanged,this);},__proto__:WebInspector.SDKObject.prototype}
WebInspector.EventListener=function(target,type,useCapture,passive,handler,originalHandler,location,removeFunction,listenerType)
{WebInspector.SDKObject.call(this,target);this._type=type;this._useCapture=useCapture;this._passive=passive;this._handler=handler;this._originalHandler=originalHandler||handler;this._location=location;var script=location.script();this._sourceURL=script?script.contentURL():"";this._removeFunction=removeFunction;this._listenerType=listenerType||"normal";}
WebInspector.EventListener.prototype={type:function()
{return this._type;},useCapture:function()
{return this._useCapture;},passive:function()
{return this._passive;},handler:function()
{return this._handler;},location:function()
{return this._location;},sourceURL:function()
{return this._sourceURL;},originalHandler:function()
{return this._originalHandler;},removeFunction:function()
{return this._removeFunction;},remove:function()
{if(!this._removeFunction)
return Promise.resolve();return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this._removeFunction.callFunction(callCustomRemove,[WebInspector.RemoteObject.toCallArgument(this._removeFunction),WebInspector.RemoteObject.toCallArgument(this._type),WebInspector.RemoteObject.toCallArgument(this._originalHandler),WebInspector.RemoteObject.toCallArgument(this._useCapture),WebInspector.RemoteObject.toCallArgument(this._passive),],success);function callCustomRemove(func,type,listener,useCapture,passive)
{func.call(null,type,listener,useCapture,passive);}}},listenerType:function()
{return this._listenerType;},setListenerType:function(listenerType)
{this._listenerType=listenerType;},__proto__:WebInspector.SDKObject.prototype};WebInspector.Script=function(debuggerModel,scriptId,sourceURL,startLine,startColumn,endLine,endColumn,executionContextId,hash,isContentScript,isInternalScript,isLiveEdit,sourceMapURL,hasSourceURL)
{WebInspector.SDKObject.call(this,debuggerModel.target());this.debuggerModel=debuggerModel;this.scriptId=scriptId;this.sourceURL=sourceURL;this.lineOffset=startLine;this.columnOffset=startColumn;this.endLine=endLine;this.endColumn=endColumn;this._executionContextId=executionContextId;this.hash=hash;this._isContentScript=isContentScript;this._isInternalScript=isInternalScript;this._isLiveEdit=isLiveEdit;this.sourceMapURL=sourceMapURL;this.hasSourceURL=hasSourceURL;}
WebInspector.Script.Events={ScriptEdited:"ScriptEdited",SourceMapURLAdded:"SourceMapURLAdded"}
WebInspector.Script.sourceURLRegex=/^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;WebInspector.Script._trimSourceURLComment=function(source)
{var sourceURLIndex=source.lastIndexOf("//# sourceURL=");if(sourceURLIndex===-1){sourceURLIndex=source.lastIndexOf("//@ sourceURL=");if(sourceURLIndex===-1)
return source;}
var sourceURLLineIndex=source.lastIndexOf("\n",sourceURLIndex);if(sourceURLLineIndex===-1)
return source;var sourceURLLine=source.substr(sourceURLLineIndex+1).split("\n",1)[0];if(sourceURLLine.search(WebInspector.Script.sourceURLRegex)===-1)
return source;return source.substr(0,sourceURLLineIndex)+source.substr(sourceURLLineIndex+sourceURLLine.length+1);}
WebInspector.Script.prototype={isContentScript:function()
{return this._isContentScript;},isInternalScript:function()
{return this._isInternalScript;},executionContext:function()
{return this.target().runtimeModel.executionContext(this._executionContextId);},isLiveEdit:function()
{return this._isLiveEdit;},contentURL:function()
{return this.sourceURL;},contentType:function()
{return WebInspector.resourceTypes.Script;},requestContent:function()
{if(this._source)
return Promise.resolve(this._source);if(!this.scriptId)
return Promise.resolve((""));var callback;var promise=new Promise(fulfill=>callback=fulfill);this.target().debuggerAgent().getScriptSource(this.scriptId,didGetScriptSource.bind(this));return promise;function didGetScriptSource(error,source)
{this._source=WebInspector.Script._trimSourceURLComment(error?"":source);callback(this._source);}},searchInContent:function(query,caseSensitive,isRegex,callback)
{function innerCallback(error,searchMatches)
{if(error){console.error(error);callback([]);return;}
var result=[];for(var i=0;i<searchMatches.length;++i){var searchMatch=new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber,searchMatches[i].lineContent);result.push(searchMatch);}
callback(result||[]);}
if(this.scriptId){this.target().debuggerAgent().searchInContent(this.scriptId,query,caseSensitive,isRegex,innerCallback);}else{callback([]);}},_appendSourceURLCommentIfNeeded:function(source)
{if(!this.hasSourceURL)
return source;return source+"\n //# sourceURL="+this.sourceURL;},editSource:function(newSource,callback)
{function didEditScriptSource(error,callFrames,stackChanged,asyncStackTrace,compileError)
{if(!error&&!compileError)
this._source=newSource;var needsStepIn=!!stackChanged;callback(error,compileError,callFrames,asyncStackTrace,needsStepIn);}
newSource=WebInspector.Script._trimSourceURLComment(newSource);newSource=this._appendSourceURLCommentIfNeeded(newSource);if(this.scriptId)
this.target().debuggerAgent().setScriptSource(this.scriptId,newSource,undefined,didEditScriptSource.bind(this));else
callback("Script failed to parse");},rawLocation:function(lineNumber,columnNumber)
{return new WebInspector.DebuggerModel.Location(this.debuggerModel,this.scriptId,lineNumber,columnNumber||0);},isInlineScript:function()
{var startsAtZero=!this.lineOffset&&!this.columnOffset;return!!this.sourceURL&&!startsAtZero;},addSourceMapURL:function(sourceMapURL)
{if(this.sourceMapURL)
return;this.sourceMapURL=sourceMapURL;this.dispatchEventToListeners(WebInspector.Script.Events.SourceMapURLAdded,this.sourceMapURL);},isAnonymousScript:function()
{return!this.sourceURL;},isInlineScriptWithSourceURL:function()
{return!!this.hasSourceURL&&this.isInlineScript();},setBlackboxedRanges:function(positions)
{return new Promise(setBlackboxedRanges.bind(this));function setBlackboxedRanges(fulfill,reject)
{this.target().debuggerAgent().setBlackboxedRanges(this.scriptId,positions,callback);function callback(error)
{if(error)
console.error(error);fulfill(!error);}}},__proto__:WebInspector.SDKObject.prototype};WebInspector.ServiceWorkerCacheModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.ServiceWorkerCacheModel,target);this._caches=new Map();this._agent=target.cacheStorageAgent();this._enabled=false;}
WebInspector.ServiceWorkerCacheModel.EventTypes={CacheAdded:"CacheAdded",CacheRemoved:"CacheRemoved"}
WebInspector.ServiceWorkerCacheModel.prototype={enable:function()
{if(this._enabled)
return;this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,this._securityOriginAdded,this);this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,this._securityOriginRemoved,this);var securityOrigins=this.target().resourceTreeModel.securityOrigins();for(var i=0;i<securityOrigins.length;++i)
this._addOrigin(securityOrigins[i]);this._enabled=true;},clearForOrigin:function(origin)
{this._removeOrigin(origin);this._addOrigin(origin);},refreshCacheNames:function()
{for(var cache of this._caches.values())
this._cacheRemoved(cache);this._caches.clear();var securityOrigins=this.target().resourceTreeModel.securityOrigins();for(var securityOrigin of securityOrigins)
this._loadCacheNames(securityOrigin);},deleteCache:function(cache)
{function callback(error)
{if(error){console.error("ServiceWorkerCacheAgent error deleting cache ",cache.toString(),": ",error);return;}
this._caches.delete(cache.cacheId);this._cacheRemoved(cache);}
this._agent.deleteCache(cache.cacheId,callback.bind(this));},deleteCacheEntry:function(cache,request,callback)
{function myCallback(error)
{if(error){WebInspector.console.error(WebInspector.UIString("ServiceWorkerCacheAgent error deleting cache entry %s in cache: %s",cache.toString(),error));return;}
callback();}
this._agent.deleteEntry(cache.cacheId,request,myCallback);},loadCacheData:function(cache,skipCount,pageSize,callback)
{this._requestEntries(cache,skipCount,pageSize,callback);},caches:function()
{var caches=new Array();for(var cache of this._caches.values())
caches.push(cache);return caches;},dispose:function()
{for(var cache of this._caches.values())
this._cacheRemoved(cache);this._caches.clear();if(this._enabled){this.target().resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,this._securityOriginAdded,this);this.target().resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,this._securityOriginRemoved,this);}},_addOrigin:function(securityOrigin)
{this._loadCacheNames(securityOrigin);},_removeOrigin:function(securityOrigin)
{for(var opaqueId of this._caches.keys()){var cache=this._caches.get(opaqueId);if(cache.securityOrigin==securityOrigin){this._caches.delete(opaqueId);this._cacheRemoved(cache);}}},_loadCacheNames:function(securityOrigin)
{function callback(error,caches)
{if(error){console.error("ServiceWorkerCacheAgent error while loading caches: ",error);return;}
this._updateCacheNames(securityOrigin,caches);}
this._agent.requestCacheNames(securityOrigin,callback.bind(this));},_updateCacheNames:function(securityOrigin,cachesJson)
{function deleteAndSaveOldCaches(cache)
{if(cache.securityOrigin==securityOrigin&&!updatingCachesIds.has(cache.cacheId)){oldCaches.set(cache.cacheId,cache);this._caches.delete(cache.cacheId);}}
var updatingCachesIds=new Set();var newCaches=new Map();var oldCaches=new Map();for(var cacheJson of cachesJson){var cache=new WebInspector.ServiceWorkerCacheModel.Cache(cacheJson.securityOrigin,cacheJson.cacheName,cacheJson.cacheId);updatingCachesIds.add(cache.cacheId);if(this._caches.has(cache.cacheId))
continue;newCaches.set(cache.cacheId,cache);this._caches.set(cache.cacheId,cache);}
this._caches.forEach(deleteAndSaveOldCaches,this);newCaches.forEach(this._cacheAdded,this);oldCaches.forEach(this._cacheRemoved,this);},_securityOriginAdded:function(event)
{var securityOrigin=(event.data);this._addOrigin(securityOrigin);},_securityOriginRemoved:function(event)
{var securityOrigin=(event.data);this._removeOrigin(securityOrigin);},_cacheAdded:function(cache)
{this.dispatchEventToListeners(WebInspector.ServiceWorkerCacheModel.EventTypes.CacheAdded,cache);},_cacheRemoved:function(cache)
{this.dispatchEventToListeners(WebInspector.ServiceWorkerCacheModel.EventTypes.CacheRemoved,cache);},_requestEntries:function(cache,skipCount,pageSize,callback)
{function innerCallback(error,dataEntries,hasMore)
{if(error){console.error("ServiceWorkerCacheAgent error while requesting entries: ",error);return;}
var entries=[];for(var i=0;i<dataEntries.length;++i){entries.push(new WebInspector.ServiceWorkerCacheModel.Entry(dataEntries[i].request,dataEntries[i].response));}
callback(entries,hasMore);}
this._agent.requestEntries(cache.cacheId,skipCount,pageSize,innerCallback);},__proto__:WebInspector.SDKModel.prototype}
WebInspector.ServiceWorkerCacheModel.Entry=function(request,response)
{this.request=request;this.response=response;}
WebInspector.ServiceWorkerCacheModel.Cache=function(securityOrigin,cacheName,cacheId)
{this.securityOrigin=securityOrigin;this.cacheName=cacheName;this.cacheId=cacheId;}
WebInspector.ServiceWorkerCacheModel.Cache.prototype={equals:function(cache)
{return this.cacheId==cache.cacheId;},toString:function()
{return this.securityOrigin+this.cacheName;}}
WebInspector.ServiceWorkerCacheModel._symbol=Symbol("CacheStorageModel");WebInspector.ServiceWorkerCacheModel.fromTarget=function(target)
{if(!target[WebInspector.ServiceWorkerCacheModel._symbol])
target[WebInspector.ServiceWorkerCacheModel._symbol]=new WebInspector.ServiceWorkerCacheModel(target);return target[WebInspector.ServiceWorkerCacheModel._symbol];};WebInspector.CallFunctionResult;WebInspector.RemoteObject=function(){}
WebInspector.RemoteObject.prototype={customPreview:function()
{return null;},get type()
{throw"Not implemented";},get subtype()
{throw"Not implemented";},get description()
{throw"Not implemented";},get hasChildren()
{throw"Not implemented";},arrayLength:function()
{throw"Not implemented";},getOwnProperties:function(callback)
{throw"Not implemented";},getOwnPropertiesPromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.getOwnProperties(getOwnPropertiesCallback.bind(null,success));}
function getOwnPropertiesCallback(callback,properties,internalProperties)
{callback({properties:properties,internalProperties:internalProperties});}},getAllProperties:function(accessorPropertiesOnly,callback)
{throw"Not implemented";},getAllPropertiesPromise:function(accessorPropertiesOnly)
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.getAllProperties(accessorPropertiesOnly,getAllPropertiesCallback.bind(null,success));}
function getAllPropertiesCallback(callback,properties,internalProperties)
{callback({properties:properties,internalProperties:internalProperties});}},eventListeners:function()
{throw"Not implemented";},deleteProperty:function(name,callback)
{throw"Not implemented";},setPropertyValue:function(name,value,callback)
{throw"Not implemented";},callFunction:function(functionDeclaration,args,callback)
{throw"Not implemented";},callFunctionPromise:function(functionDeclaration,args)
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callFunction(functionDeclaration,args,callFunctionCallback.bind(null,success));}
function callFunctionCallback(callback,object,wasThrown)
{callback({object:object,wasThrown:wasThrown});}},callFunctionJSON:function(functionDeclaration,args,callback)
{throw"Not implemented";},callFunctionJSONPromise:function(functionDeclaration,args)
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callFunctionJSON(functionDeclaration,args,success);}},target:function()
{throw new Error("Target-less object");},debuggerModel:function()
{throw new Error("DebuggerModel-less object");},isNode:function()
{return false;},functionDetails:function(callback)
{callback(null);},functionDetailsPromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.functionDetails(success);}},generatorObjectDetails:function(callback)
{callback(null);},collectionEntries:function(callback)
{callback(null);}}
WebInspector.RemoteObject.fromLocalObject=function(value)
{return new WebInspector.LocalJSONObject(value);}
WebInspector.RemoteObject.type=function(remoteObject)
{if(remoteObject===null)
return"null";var type=typeof remoteObject;if(type!=="object"&&type!=="function")
return type;return remoteObject.type;}
WebInspector.RemoteObject.arrayLength=function(object)
{if(object.subtype!=="array")
return 0;var matches=object.description.match(/\[([0-9]+)\]/);if(!matches)
return 0;return parseInt(matches[1],10);}
WebInspector.RemoteObject.toCallArgument=function(object)
{var type=typeof object;var value=object;var objectId=undefined;var description=String(object);if(type==="number"&&value===0&&1/value<0)
description="-0";switch(type){case"number":case"string":case"boolean":case"undefined":break;default:if(object){type=object.type;value=object.value;objectId=object.objectId;description=object.description;}
break;}
if(type==="number"){switch(description){case"NaN":case"Infinity":case"-Infinity":case"-0":value=description;break;}}
return{value:value,objectId:objectId,type:(type)};}
WebInspector.RemoteObjectImpl=function(target,objectId,type,subtype,value,description,preview,customPreview)
{WebInspector.RemoteObject.call(this);this._target=target;this._runtimeAgent=target.runtimeAgent();this._debuggerModel=WebInspector.DebuggerModel.fromTarget(target);this._type=type;this._subtype=subtype;if(objectId){this._objectId=objectId;this._description=description;this._hasChildren=(type!=="symbol");this._preview=preview;}else{this._description=description||(value+"");this._hasChildren=false;if(type==="number"&&typeof value!=="number")
this.value=Number(value);else
this.value=value;}
this._customPreview=customPreview||null;}
WebInspector.RemoteObjectImpl.prototype={customPreview:function()
{return this._customPreview;},get objectId()
{return this._objectId;},get type()
{return this._type;},get subtype()
{return this._subtype;},get description()
{return this._description;},get hasChildren()
{return this._hasChildren;},get preview()
{return this._preview;},getOwnProperties:function(callback)
{this.doGetProperties(true,false,false,callback);},getAllProperties:function(accessorPropertiesOnly,callback)
{this.doGetProperties(false,accessorPropertiesOnly,false,callback);},eventListeners:function()
{return new Promise(eventListeners.bind(this));function eventListeners(fulfill,reject)
{if(!this.target().isPage()){fulfill([]);return;}
if(!this._objectId){reject(null);return;}
var removeFunction=null;this.callFunctionPromise(nodeRemoveEventListener).then(storeRemoveFunction.bind(this));function storeRemoveFunction(result)
{if(!result.wasThrown&&result.object)
removeFunction=result.object;this.target().domdebuggerAgent().getEventListeners(this._objectId,mycallback.bind(this));}
function mycallback(error,payloads)
{if(error){reject(null);return;}
fulfill(payloads.map(createEventListener.bind(this)));}
function nodeRemoveEventListener()
{return removeEventListenerWrapper.bind(this);function removeEventListenerWrapper(type,handler,useCapture,passive)
{function eventListenerOptions()
{if(passive&&useCapture)
return{"capture":useCapture,"passive":passive};else if(passive)
return{"passive":passive};else if(useCapture)
return{"capture":useCapture};else
return{};}
this.removeEventListener(type,handler,eventListenerOptions());if(this["on"+type])
this["on"+type]=null;}}
function createEventListener(payload)
{return new WebInspector.EventListener(this._target,payload.type,payload.useCapture,payload.passive,payload.handler?this.target().runtimeModel.createRemoteObject(payload.handler):null,payload.originalHandler?this.target().runtimeModel.createRemoteObject(payload.originalHandler):null,WebInspector.DebuggerModel.Location.fromPayload(this._debuggerModel,payload.location),removeFunction);}}},getProperty:function(propertyPath,callback)
{function remoteFunction(arrayStr)
{var result=this;var properties=JSON.parse(arrayStr);for(var i=0,n=properties.length;i<n;++i)
result=result[properties[i]];return result;}
var args=[{value:JSON.stringify(propertyPath)}];this.callFunction(remoteFunction,args,callback);},doGetProperties:function(ownProperties,accessorPropertiesOnly,generatePreview,callback)
{if(!this._objectId){callback(null,null);return;}
function remoteObjectBinder(error,properties,internalProperties,exceptionDetails)
{if(error){callback(null,null);return;}
if(exceptionDetails){var msg=new WebInspector.ConsoleMessage(this._target,WebInspector.ConsoleMessage.MessageSource.JS,WebInspector.ConsoleMessage.MessageLevel.Error,exceptionDetails.text);this._target.consoleModel.addMessage(msg);callback(null,null);return;}
var result=[];for(var i=0;properties&&i<properties.length;++i){var property=properties[i];var propertyValue=property.value?this._target.runtimeModel.createRemoteObject(property.value):null;var propertySymbol=property.symbol?this._target.runtimeModel.createRemoteObject(property.symbol):null;var remoteProperty=new WebInspector.RemoteObjectProperty(property.name,propertyValue,!!property.enumerable,!!property.writable,!!property.isOwn,!!property.wasThrown,propertySymbol);if(typeof property.value==="undefined"){if(property.get&&property.get.type!=="undefined")
remoteProperty.getter=this._target.runtimeModel.createRemoteObject(property.get);if(property.set&&property.set.type!=="undefined")
remoteProperty.setter=this._target.runtimeModel.createRemoteObject(property.set);}
result.push(remoteProperty);}
var internalPropertiesResult=null;if(internalProperties){internalPropertiesResult=[];for(var i=0;i<internalProperties.length;i++){var property=internalProperties[i];if(!property.value)
continue;var propertyValue=this._target.runtimeModel.createRemoteObject(property.value);internalPropertiesResult.push(new WebInspector.RemoteObjectProperty(property.name,propertyValue,true,false));}}
callback(result,internalPropertiesResult);}
this._runtimeAgent.getProperties(this._objectId,ownProperties,accessorPropertiesOnly,generatePreview,remoteObjectBinder.bind(this));},setPropertyValue:function(name,value,callback)
{if(!this._objectId){callback("Can't set a property of non-object.");return;}
this._runtimeAgent.invoke_evaluate({expression:value,doNotPauseOnExceptionsAndMuteConsole:true},evaluatedCallback.bind(this));function evaluatedCallback(error,result,wasThrown)
{if(error||wasThrown){callback(error||(result.type!=="string"?result.description:(result.value)));return;}
if(typeof name==="string")
name=WebInspector.RemoteObject.toCallArgument(name);this.doSetObjectPropertyValue(result,name,callback);if(result.objectId)
this._runtimeAgent.releaseObject(result.objectId);}},doSetObjectPropertyValue:function(result,name,callback)
{var setPropertyValueFunction="function(a, b) { this[a] = b; }";var argv=[name,WebInspector.RemoteObject.toCallArgument(result)];this._runtimeAgent.callFunctionOn(this._objectId,setPropertyValueFunction,argv,true,undefined,undefined,undefined,propertySetCallback);function propertySetCallback(error,result,wasThrown)
{if(error||wasThrown){callback(error||result.description);return;}
callback();}},deleteProperty:function(name,callback)
{if(!this._objectId){callback("Can't delete a property of non-object.");return;}
var deletePropertyFunction="function(a) { delete this[a]; return !(a in this); }";this._runtimeAgent.callFunctionOn(this._objectId,deletePropertyFunction,[name],true,undefined,undefined,undefined,deletePropertyCallback);function deletePropertyCallback(error,result,wasThrown)
{if(error||wasThrown){callback(error||result.description);return;}
if(!result.value)
callback("Failed to delete property.");else
callback();}},callFunction:function(functionDeclaration,args,callback)
{function mycallback(error,result,wasThrown)
{if(!callback)
return;if(error)
callback(null,false);else
callback(this.target().runtimeModel.createRemoteObject(result),wasThrown);}
this._runtimeAgent.callFunctionOn(this._objectId,functionDeclaration.toString(),args,true,undefined,undefined,undefined,mycallback.bind(this));},callFunctionJSON:function(functionDeclaration,args,callback)
{function mycallback(error,result,wasThrown)
{callback((error||wasThrown)?null:result.value);}
this._runtimeAgent.callFunctionOn(this._objectId,functionDeclaration.toString(),args,true,true,false,undefined,mycallback);},release:function()
{if(!this._objectId)
return;this._runtimeAgent.releaseObject(this._objectId);},arrayLength:function()
{return WebInspector.RemoteObject.arrayLength(this);},target:function()
{return this._target;},debuggerModel:function()
{return this._debuggerModel;},isNode:function()
{return!!this._objectId&&this.type==="object"&&this.subtype==="node";},functionDetails:function(callback)
{this._debuggerModel.functionDetails(this,callback);},generatorObjectDetails:function(callback)
{this._debuggerModel.generatorObjectDetails(this,callback);},collectionEntries:function(callback)
{if(!this._objectId){callback(null);return;}
this._debuggerModel.getCollectionEntries(this._objectId,callback);},__proto__:WebInspector.RemoteObject.prototype};WebInspector.RemoteObject.loadFromObjectPerProto=function(object,callback)
{var savedOwnProperties;var savedAccessorProperties;var savedInternalProperties;var resultCounter=2;function processCallback()
{if(--resultCounter)
return;if(savedOwnProperties&&savedAccessorProperties){var propertiesMap=new Map();var propertySymbols=[];for(var i=0;i<savedAccessorProperties.length;i++){var property=savedAccessorProperties[i];if(property.symbol)
propertySymbols.push(property);else
propertiesMap.set(property.name,property);}
for(var i=0;i<savedOwnProperties.length;i++){var property=savedOwnProperties[i];if(property.isAccessorProperty())
continue;if(property.symbol)
propertySymbols.push(property);else
propertiesMap.set(property.name,property);}
return callback(propertiesMap.valuesArray().concat(propertySymbols),savedInternalProperties?savedInternalProperties:null);}else{callback(null,null);}}
function allAccessorPropertiesCallback(properties,internalProperties)
{savedAccessorProperties=properties;processCallback();}
function ownPropertiesCallback(properties,internalProperties)
{savedOwnProperties=properties;savedInternalProperties=internalProperties;processCallback();}
object.getAllProperties(true,allAccessorPropertiesCallback);object.getOwnProperties(ownPropertiesCallback);};WebInspector.ScopeRemoteObject=function(target,objectId,scopeRef,type,subtype,value,description,preview)
{WebInspector.RemoteObjectImpl.call(this,target,objectId,type,subtype,value,description,preview);this._scopeRef=scopeRef;this._savedScopeProperties=undefined;};WebInspector.ScopeRemoteObject.prototype={doGetProperties:function(ownProperties,accessorPropertiesOnly,generatePreview,callback)
{if(accessorPropertiesOnly){callback([],[]);return;}
if(this._savedScopeProperties){callback(this._savedScopeProperties.slice(),[]);return;}
function wrappedCallback(properties,internalProperties)
{if(this._scopeRef&&Array.isArray(properties)){this._savedScopeProperties=properties.slice();if(!this._scopeRef.callFrameId){for(var property of this._savedScopeProperties)
property.writable=false;}}
callback(properties,internalProperties);}
generatePreview=true;WebInspector.RemoteObjectImpl.prototype.doGetProperties.call(this,ownProperties,accessorPropertiesOnly,generatePreview,wrappedCallback.bind(this));},doSetObjectPropertyValue:function(result,argumentName,callback)
{var name=(argumentName.value);this._debuggerModel.setVariableValue(this._scopeRef.number,name,WebInspector.RemoteObject.toCallArgument(result),this._scopeRef.callFrameId,setVariableValueCallback.bind(this));function setVariableValueCallback(error)
{if(error){callback(error);return;}
if(this._savedScopeProperties){for(var i=0;i<this._savedScopeProperties.length;i++){if(this._savedScopeProperties[i].name===name)
this._savedScopeProperties[i].value=this._target.runtimeModel.createRemoteObject(result);}}
callback();}},__proto__:WebInspector.RemoteObjectImpl.prototype};WebInspector.ScopeRef=function(number,callFrameId)
{this.number=number;this.callFrameId=callFrameId;}
WebInspector.RemoteObjectProperty=function(name,value,enumerable,writable,isOwn,wasThrown,symbol,synthetic)
{this.name=name;if(value!==null)
this.value=value;this.enumerable=typeof enumerable!=="undefined"?enumerable:true;this.writable=typeof writable!=="undefined"?writable:true;this.isOwn=!!isOwn;this.wasThrown=!!wasThrown;if(symbol)
this.symbol=symbol;this.synthetic=!!synthetic;}
WebInspector.RemoteObjectProperty.prototype={isAccessorProperty:function()
{return!!(this.getter||this.setter);}};WebInspector.LocalJSONObject=function(value)
{WebInspector.RemoteObject.call(this);this._value=value;}
WebInspector.LocalJSONObject.prototype={get description()
{if(this._cachedDescription)
return this._cachedDescription;function formatArrayItem(property)
{return this._formatValue(property.value);}
function formatObjectItem(property)
{var name=property.name;if(/^\s|\s$|^$|\n/.test(name))
name="\""+name.replace(/\n/g,"\u21B5")+"\"";return name+": "+this._formatValue(property.value);}
if(this.type==="object"){switch(this.subtype){case"array":this._cachedDescription=this._concatenate("[","]",formatArrayItem.bind(this));break;case"date":this._cachedDescription=""+this._value;break;case"null":this._cachedDescription="null";break;default:this._cachedDescription=this._concatenate("{","}",formatObjectItem.bind(this));}}else{this._cachedDescription=String(this._value);}
return this._cachedDescription;},_formatValue:function(value)
{if(!value)
return"undefined";var description=value.description||"";if(value.type==="string")
return"\""+description.replace(/\n/g,"\u21B5")+"\"";return description;},_concatenate:function(prefix,suffix,formatProperty)
{var previewChars=100;var buffer=prefix;var children=this._children();for(var i=0;i<children.length;++i){var itemDescription=formatProperty(children[i]);if(buffer.length+itemDescription.length>previewChars){buffer+=",\u2026";break;}
if(i)
buffer+=", ";buffer+=itemDescription;}
buffer+=suffix;return buffer;},get type()
{return typeof this._value;},get subtype()
{if(this._value===null)
return"null";if(Array.isArray(this._value))
return"array";if(this._value instanceof Date)
return"date";return undefined;},get hasChildren()
{if((typeof this._value!=="object")||(this._value===null))
return false;return!!Object.keys((this._value)).length;},getOwnProperties:function(callback)
{callback(this._children(),null);},getAllProperties:function(accessorPropertiesOnly,callback)
{if(accessorPropertiesOnly)
callback([],null);else
callback(this._children(),null);},_children:function()
{if(!this.hasChildren)
return[];var value=(this._value);function buildProperty(propName)
{var propValue=value[propName];if(!(propValue instanceof WebInspector.RemoteObject))
propValue=WebInspector.RemoteObject.fromLocalObject(propValue);return new WebInspector.RemoteObjectProperty(propName,propValue);}
if(!this._cachedChildren)
this._cachedChildren=Object.keys(value).map(buildProperty);return this._cachedChildren;},isError:function()
{return false;},arrayLength:function()
{return Array.isArray(this._value)?this._value.length:0;},callFunction:function(functionDeclaration,args,callback)
{var target=(this._value);var rawArgs=args?args.map(function(arg){return arg.value;}):[];var result;var wasThrown=false;try{result=functionDeclaration.apply(target,rawArgs);}catch(e){wasThrown=true;}
if(!callback)
return;callback(WebInspector.RemoteObject.fromLocalObject(result),wasThrown);},callFunctionJSON:function(functionDeclaration,args,callback)
{var target=(this._value);var rawArgs=args?args.map(function(arg){return arg.value;}):[];var result;try{result=functionDeclaration.apply(target,rawArgs);}catch(e){result=null;}
callback(result);},__proto__:WebInspector.RemoteObject.prototype}
WebInspector.RemoteArray=function(object)
{this._object=object;};WebInspector.RemoteArray.objectAsArray=function(object)
{if(!object||object.type!=="object"||object.subtype!=="array")
throw new Error("Object is empty or not an array");return new WebInspector.RemoteArray(object);}
WebInspector.RemoteArray.createFromRemoteObjects=function(objects)
{if(!objects.length)
throw new Error("Input array is empty");var objectArguments=[];for(var i=0;i<objects.length;++i)
objectArguments.push(WebInspector.RemoteObject.toCallArgument(objects[i]))
return objects[0].callFunctionPromise(createArray,objectArguments).then(returnRemoteArray);function createArray()
{if(arguments.length>1)
return new Array(arguments);return[arguments[0]];}
function returnRemoteArray(result)
{if(result.wasThrown||!result.object)
throw new Error("Call function throws exceptions or returns empty value");return WebInspector.RemoteArray.objectAsArray(result.object);}}
WebInspector.RemoteArray.prototype={at:function(index)
{if(index<0||index>this._object.arrayLength())
throw new Error("Out of range");return this._object.callFunctionPromise(at,[WebInspector.RemoteObject.toCallArgument(index)]).then(assertCallFunctionResult);function at(index)
{return this[index];}
function assertCallFunctionResult(result)
{if(result.wasThrown||!result.object)
throw new Error("Exception in callFunction or result value is empty");return result.object;}},length:function()
{return this._object.arrayLength();},map:function(func)
{var promises=[];for(var i=0;i<this.length();++i)
promises.push(this.at(i).then(func));return Promise.all(promises);},object:function()
{return this._object;}}
WebInspector.RemoteFunction=function(object)
{this._object=object;}
WebInspector.RemoteFunction.objectAsFunction=function(object)
{if(!object||object.type!=="function")
throw new Error("Object is empty or not a function");return new WebInspector.RemoteFunction(object);}
WebInspector.RemoteFunction.prototype={targetFunction:function()
{return this._object.getOwnPropertiesPromise().then(targetFunction.bind(this));function targetFunction(ownProperties)
{if(!ownProperties.internalProperties)
return this._object;var internalProperties=ownProperties.internalProperties;for(var property of internalProperties){if(property.name==="[[TargetFunction]]")
return property.value;}
return this._object;}},targetFunctionDetails:function()
{return this.targetFunction().then(functionDetails.bind(this));function functionDetails(targetFunction)
{var boundReleaseFunctionDetails=releaseTargetFunction.bind(null,this._object!==targetFunction?targetFunction:null);return targetFunction.functionDetailsPromise().then(boundReleaseFunctionDetails);}
function releaseTargetFunction(targetFunction,functionDetails)
{if(targetFunction)
targetFunction.release();return functionDetails;}},object:function()
{return this._object;}}
WebInspector.MapEntryLocalJSONObject=function(value)
{WebInspector.LocalJSONObject.call(this,value);}
WebInspector.MapEntryLocalJSONObject.prototype={get description()
{if(!this._cachedDescription){var children=this._children();this._cachedDescription="{"+this._formatValue(children[0].value)+" => "+this._formatValue(children[1].value)+"}";}
return this._cachedDescription;},__proto__:WebInspector.LocalJSONObject.prototype};WebInspector.Resource=function(target,request,url,documentURL,frameId,loaderId,type,mimeType,isHidden)
{WebInspector.SDKObject.call(this,target);this._request=request;this.url=url;this._documentURL=documentURL;this._frameId=frameId;this._loaderId=loaderId;this._type=type||WebInspector.resourceTypes.Other;this._mimeType=mimeType;this._isHidden=isHidden;this._content;this._contentEncoded;this._pendingContentCallbacks=[];if(this._request&&!this._request.finished)
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._requestFinished,this);}
WebInspector.Resource.contentAsDataURL=function(content,mimeType,contentEncoded,charset)
{const maxDataUrlSize=1024*1024;if(content===null||content.length>maxDataUrlSize)
return null;return"data:"+mimeType+(charset?";charset="+charset:"")+(contentEncoded?";base64":"")+","+content;}
WebInspector.Resource.populateImageSource=function(url,mimeType,contentProvider,image)
{function onResourceContent(content)
{var imageSrc=WebInspector.Resource.contentAsDataURL(content,mimeType,true);if(imageSrc===null)
imageSrc=url;image.src=imageSrc;}
contentProvider.requestContent().then(onResourceContent);}
WebInspector.Resource.prototype={get request()
{return this._request;},get url()
{return this._url;},set url(x)
{this._url=x;this._parsedURL=new WebInspector.ParsedURL(x);},get parsedURL()
{return this._parsedURL;},get documentURL()
{return this._documentURL;},get frameId()
{return this._frameId;},get loaderId()
{return this._loaderId;},get displayName()
{return this._parsedURL.displayName;},resourceType:function()
{return this._request?this._request.resourceType():this._type;},get mimeType()
{return this._request?this._request.mimeType:this._mimeType;},get content()
{return this._content;},get contentEncoded()
{return this._contentEncoded;},contentURL:function()
{return this._url;},contentType:function()
{if(this.resourceType()===WebInspector.resourceTypes.Document&&this.mimeType.indexOf("javascript")!==-1)
return WebInspector.resourceTypes.Script;return this.resourceType();},requestContent:function()
{if(typeof this._content!=="undefined")
return Promise.resolve(this._content);var callback;var promise=new Promise(fulfill=>callback=fulfill);this._pendingContentCallbacks.push(callback);if(!this._request||this._request.finished)
this._innerRequestContent();return promise;},canonicalMimeType:function()
{return this.contentType().canonicalMimeType()||this.mimeType;},searchInContent:function(query,caseSensitive,isRegex,callback)
{function callbackWrapper(error,searchMatches)
{callback(searchMatches||[]);}
if(this.frameId)
this.target().pageAgent().searchInResource(this.frameId,this.url,query,caseSensitive,isRegex,callbackWrapper);else
callback([]);},populateImageSource:function(image)
{WebInspector.Resource.populateImageSource(this._url,this._mimeType,this,image);},_requestFinished:function()
{this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._requestFinished,this);if(this._pendingContentCallbacks.length)
this._innerRequestContent();},_innerRequestContent:function()
{if(this._contentRequested)
return;this._contentRequested=true;function contentLoaded(error,content,contentEncoded)
{if(error||content===null){replyWithContent.call(this,null,false);return;}
replyWithContent.call(this,content,contentEncoded);}
function replyWithContent(content,contentEncoded)
{this._content=content;this._contentEncoded=contentEncoded;var callbacks=this._pendingContentCallbacks.slice();for(var i=0;i<callbacks.length;++i)
callbacks[i](this._content);this._pendingContentCallbacks.length=0;delete this._contentRequested;}
function resourceContentLoaded(error,content,contentEncoded)
{contentLoaded.call(this,error,content,contentEncoded);}
if(this.request){this.request.requestContent().then(requestContentLoaded.bind(this));return;}
function requestContentLoaded(content)
{contentLoaded.call(this,null,content,this.request.contentEncoded);}
this.target().pageAgent().getResourceContent(this.frameId,this.url,resourceContentLoaded.bind(this));},isHidden:function()
{return!!this._isHidden;},hasTextContent:function()
{if(this._type.isTextType())
return true;if(this._type===WebInspector.resourceTypes.Other)
return!!this._content&&!this._contentEncoded;return false;},__proto__:WebInspector.SDKObject.prototype};WebInspector.ResourceTreeModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.ResourceTreeModel,target);target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped,this._onRequestUpdateDropped,this);this._agent=target.pageAgent();this._agent.enable();this._fetchResourceTree();target.registerPageDispatcher(new WebInspector.PageDispatcher(this));this._securityOriginFrameCount={};this._inspectedPageURL="";this._pendingReloadOptions=null;this._reloadSuspensionCount=0;}
WebInspector.ResourceTreeModel.EventTypes={FrameAdded:"FrameAdded",FrameNavigated:"FrameNavigated",FrameDetached:"FrameDetached",FrameResized:"FrameResized",FrameWillNavigate:"FrameWillNavigate",MainFrameNavigated:"MainFrameNavigated",ResourceAdded:"ResourceAdded",WillLoadCachedResources:"WillLoadCachedResources",CachedResourcesLoaded:"CachedResourcesLoaded",DOMContentLoaded:"DOMContentLoaded",Load:"Load",PageReloadRequested:"PageReloadRequested",WillReloadPage:"WillReloadPage",InspectedURLChanged:"InspectedURLChanged",SecurityOriginAdded:"SecurityOriginAdded",SecurityOriginRemoved:"SecurityOriginRemoved",ScreencastFrame:"ScreencastFrame",ScreencastVisibilityChanged:"ScreencastVisibilityChanged",ColorPicked:"ColorPicked"}
WebInspector.ResourceTreeModel.frames=function()
{var result=[];for(var target of WebInspector.targetManager.targets())
result=result.concat(Object.values(target.resourceTreeModel._frames));return result;}
WebInspector.ResourceTreeModel.resourceForURL=function(url)
{for(var target of WebInspector.targetManager.targets()){var mainFrame=target.resourceTreeModel.mainFrame;var result=mainFrame?mainFrame.resourceForURL(url):null;if(result)
return result;}
return null;}
WebInspector.ResourceTreeModel.prototype={_fetchResourceTree:function()
{this._frames={};this._cachedResourcesProcessed=false;this._agent.getResourceTree(this._processCachedResources.bind(this));},_processCachedResources:function(error,mainFramePayload)
{if(error){this._cachedResourcesProcessed=true;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);return;}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);this._inspectedPageURL=mainFramePayload.frame.url;if(this.target().isPage())
this._addFramesRecursively(null,mainFramePayload);else
this._addSecurityOrigin(mainFramePayload.frame.securityOrigin);this._dispatchInspectedURLChanged();this._cachedResourcesProcessed=true;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);},inspectedPageURL:function()
{return this._inspectedPageURL;},inspectedPageDomain:function()
{var parsedURL=this._inspectedPageURL?this._inspectedPageURL.asParsedURL():null;return parsedURL?parsedURL.host:"";},cachedResourcesLoaded:function()
{return this._cachedResourcesProcessed;},_dispatchInspectedURLChanged:function()
{InspectorFrontendHost.inspectedURLChanged(this._inspectedPageURL);this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,this._inspectedPageURL);},_addFrame:function(frame,aboutToNavigate)
{this._frames[frame.id]=frame;if(frame.isMainFrame())
this.mainFrame=frame;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded,frame);if(!aboutToNavigate)
this._addSecurityOrigin(frame.securityOrigin);},_addSecurityOrigin:function(securityOrigin)
{if(!this._securityOriginFrameCount[securityOrigin]){this._securityOriginFrameCount[securityOrigin]=1;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,securityOrigin);return;}
this._securityOriginFrameCount[securityOrigin]+=1;},_removeSecurityOrigin:function(securityOrigin)
{if(typeof securityOrigin==="undefined")
return;if(this._securityOriginFrameCount[securityOrigin]===1){delete this._securityOriginFrameCount[securityOrigin];this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,securityOrigin);return;}
this._securityOriginFrameCount[securityOrigin]-=1;},securityOrigins:function()
{return Object.keys(this._securityOriginFrameCount);},_handleMainFrameDetached:function(mainFrame)
{function removeOriginForFrame(frame)
{for(var i=0;i<frame.childFrames.length;++i)
removeOriginForFrame.call(this,frame.childFrames[i]);if(!frame.isMainFrame())
this._removeSecurityOrigin(frame.securityOrigin);}
removeOriginForFrame.call(this,mainFrame);},_frameAttached:function(frameId,parentFrameId)
{if(!this._cachedResourcesProcessed&&parentFrameId)
return null;if(this._frames[frameId])
return null;var parentFrame=parentFrameId?this._frames[parentFrameId]:null;var frame=new WebInspector.ResourceTreeFrame(this,parentFrame,frameId);if(frame.isMainFrame()&&this.mainFrame){this._handleMainFrameDetached(this.mainFrame);this._frameDetached(this.mainFrame.id);}
this._addFrame(frame,true);return frame;},_frameNavigated:function(framePayload)
{if(!this._cachedResourcesProcessed&&framePayload.parentId)
return;var frame=this._frames[framePayload.id];if(!frame){console.assert(!framePayload.parentId,"Main frame shouldn't have parent frame id.");frame=this._frameAttached(framePayload.id,framePayload.parentId||"");console.assert(frame);}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameWillNavigate,frame);this._removeSecurityOrigin(frame.securityOrigin);frame._navigate(framePayload);var addedOrigin=frame.securityOrigin;if(frame.isMainFrame())
this._inspectedPageURL=frame.url;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated,frame);if(frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,frame);if(addedOrigin)
this._addSecurityOrigin(addedOrigin);var resources=frame.resources();for(var i=0;i<resources.length;++i)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,resources[i]);if(frame.isMainFrame())
this._dispatchInspectedURLChanged();},_frameDetached:function(frameId)
{if(!this._cachedResourcesProcessed)
return;var frame=this._frames[frameId];if(!frame)
return;this._removeSecurityOrigin(frame.securityOrigin);if(frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);else
frame._remove();},_onRequestFinished:function(event)
{if(!this._cachedResourcesProcessed)
return;var request=(event.data);if(request.failed||request.resourceType()===WebInspector.resourceTypes.XHR)
return;var frame=this._frames[request.frameId];if(frame)
frame._addRequest(request);},_onRequestUpdateDropped:function(event)
{if(!this._cachedResourcesProcessed)
return;var frameId=event.data.frameId;var frame=this._frames[frameId];if(!frame)
return;var url=event.data.url;if(frame._resourcesMap[url])
return;var resource=new WebInspector.Resource(this.target(),null,url,frame.url,frameId,event.data.loaderId,WebInspector.resourceTypes[event.data.resourceType],event.data.mimeType);frame.addResource(resource);},frameForId:function(frameId)
{return this._frames[frameId];},forAllResources:function(callback)
{if(this.mainFrame)
return this.mainFrame._callForFrameResources(callback);return false;},frames:function()
{return Object.values(this._frames);},resourceForURL:function(url)
{return this.mainFrame?this.mainFrame.resourceForURL(url):null;},_addFramesRecursively:function(parentFrame,frameTreePayload)
{var framePayload=frameTreePayload.frame;var frame=new WebInspector.ResourceTreeFrame(this,parentFrame,framePayload.id,framePayload);this._addFrame(frame);var frameResource=this._createResourceFromFramePayload(framePayload,framePayload.url,WebInspector.resourceTypes.Document,framePayload.mimeType);if(frame.isMainFrame())
this._inspectedPageURL=frameResource.url;frame.addResource(frameResource);for(var i=0;frameTreePayload.childFrames&&i<frameTreePayload.childFrames.length;++i)
this._addFramesRecursively(frame,frameTreePayload.childFrames[i]);for(var i=0;i<frameTreePayload.resources.length;++i){var subresource=frameTreePayload.resources[i];var resource=this._createResourceFromFramePayload(framePayload,subresource.url,WebInspector.resourceTypes[subresource.type],subresource.mimeType);frame.addResource(resource);}},_createResourceFromFramePayload:function(frame,url,type,mimeType)
{return new WebInspector.Resource(this.target(),null,url,frame.url,frame.id,frame.loaderId,type,mimeType);},suspendReload:function()
{this._reloadSuspensionCount++;},resumeReload:function()
{this._reloadSuspensionCount--;console.assert(this._reloadSuspensionCount>=0,"Unbalanced call to ResourceTreeModel.resumeReload()");if(!this._reloadSuspensionCount&&this._pendingReloadOptions)
this.reloadPage.apply(this,this._pendingReloadOptions);},reloadPage:function(bypassCache,scriptToEvaluateOnLoad)
{if(!this._pendingReloadOptions)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.PageReloadRequested);if(this._reloadSuspensionCount){this._pendingReloadOptions=[bypassCache,scriptToEvaluateOnLoad];return;}
this._pendingReloadOptions=null;this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage);this._agent.reload(bypassCache,scriptToEvaluateOnLoad);},fetchAppManifest:function(callback)
{this._agent.getAppManifest(myCallback);function myCallback(protocolError,url,errors,data)
{if(protocolError){callback(url,null,[]);return;}
callback(url,data||null,errors);}},__proto__:WebInspector.SDKModel.prototype}
WebInspector.ResourceTreeFrame=function(model,parentFrame,frameId,payload)
{this._model=model;this._parentFrame=parentFrame;this._id=frameId;this._url="";if(payload){this._loaderId=payload.loaderId;this._name=payload.name;this._url=payload.url;this._securityOrigin=payload.securityOrigin;this._mimeType=payload.mimeType;}
this._childFrames=[];this._resourcesMap={};if(this._parentFrame)
this._parentFrame._childFrames.push(this);}
WebInspector.ResourceTreeFrame.fromScript=function(script)
{var executionContext=script.executionContext();if(!executionContext||!executionContext.frameId)
return null;return script.target().resourceTreeModel.frameForId(executionContext.frameId);}
WebInspector.ResourceTreeFrame.fromStyleSheet=function(header)
{return header.target().resourceTreeModel.frameForId(header.frameId);}
WebInspector.ResourceTreeFrame.fromResource=function(resource)
{return resource.target().resourceTreeModel.frameForId(resource.frameId);}
WebInspector.ResourceTreeFrame.prototype={target:function()
{return this._model.target();},get id()
{return this._id;},get name()
{return this._name||"";},get url()
{return this._url;},get securityOrigin()
{return this._securityOrigin;},get loaderId()
{return this._loaderId;},get parentFrame()
{return this._parentFrame;},get childFrames()
{return this._childFrames;},isMainFrame:function()
{return!this._parentFrame;},_navigate:function(framePayload)
{this._loaderId=framePayload.loaderId;this._name=framePayload.name;this._url=framePayload.url;this._securityOrigin=framePayload.securityOrigin;this._mimeType=framePayload.mimeType;var mainResource=this._resourcesMap[this._url];this._resourcesMap={};this._removeChildFrames();if(mainResource&&mainResource.loaderId===this._loaderId)
this.addResource(mainResource);},get mainResource()
{return this._resourcesMap[this._url];},_removeChildFrame:function(frame)
{this._childFrames.remove(frame);frame._remove();},_removeChildFrames:function()
{var frames=this._childFrames;this._childFrames=[];for(var i=0;i<frames.length;++i)
frames[i]._remove();},_remove:function()
{this._removeChildFrames();delete this._model._frames[this.id];this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached,this);},addResource:function(resource)
{if(this._resourcesMap[resource.url]===resource){return;}
this._resourcesMap[resource.url]=resource;this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,resource);},_addRequest:function(request)
{var resource=this._resourcesMap[request.url];if(resource&&resource.request===request){return resource;}
resource=new WebInspector.Resource(this.target(),request,request.url,request.documentURL,request.frameId,request.loaderId,request.resourceType(),request.mimeType);this._resourcesMap[resource.url]=resource;this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,resource);return resource;},resources:function()
{var result=[];for(var url in this._resourcesMap)
result.push(this._resourcesMap[url]);return result;},resourceForURL:function(url)
{var result;function filter(resource)
{if(resource.url===url){result=resource;return true;}}
this._callForFrameResources(filter);return result||null;},_callForFrameResources:function(callback)
{for(var url in this._resourcesMap){if(callback(this._resourcesMap[url]))
return true;}
for(var i=0;i<this._childFrames.length;++i){if(this._childFrames[i]._callForFrameResources(callback))
return true;}
return false;},displayName:function()
{if(!this._parentFrame)
return WebInspector.UIString("top");var subtitle=new WebInspector.ParsedURL(this._url).displayName;if(subtitle){if(!this._name)
return subtitle;return this._name+" ("+subtitle+")";}
return WebInspector.UIString("<iframe>");}}
WebInspector.PageDispatcher=function(resourceTreeModel)
{this._resourceTreeModel=resourceTreeModel;}
WebInspector.PageDispatcher.prototype={domContentEventFired:function(time)
{this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded,time);},loadEventFired:function(time)
{this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.Load,time);},frameAttached:function(frameId,parentFrameId)
{this._resourceTreeModel._frameAttached(frameId,parentFrameId);},frameNavigated:function(frame)
{this._resourceTreeModel._frameNavigated(frame);},frameDetached:function(frameId)
{this._resourceTreeModel._frameDetached(frameId);},frameStartedLoading:function(frameId)
{},frameStoppedLoading:function(frameId)
{},frameScheduledNavigation:function(frameId,delay)
{},frameClearedScheduledNavigation:function(frameId)
{},frameResized:function()
{this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameResized,null);},javascriptDialogOpening:function(message,dialogType)
{},javascriptDialogClosed:function(result)
{},screencastFrame:function(data,metadata,sessionId)
{this._resourceTreeModel._agent.screencastFrameAck(sessionId);this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame,{data:data,metadata:metadata});},screencastVisibilityChanged:function(visible)
{this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged,{visible:visible});},colorPicked:function(color)
{this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ColorPicked,color);},interstitialShown:function()
{},interstitialHidden:function()
{}};function SourceMapV3()
{this.version;this.file;this.sources;this.sections;this.mappings;this.sourceRoot;this.names;}
SourceMapV3.Section=function()
{this.map;this.offset;}
SourceMapV3.Offset=function()
{this.line;this.column;}
WebInspector.SourceMapEntry=function(lineNumber,columnNumber,sourceURL,sourceLineNumber,sourceColumnNumber,name)
{this.lineNumber=lineNumber;this.columnNumber=columnNumber;this.sourceURL=sourceURL;this.sourceLineNumber=sourceLineNumber;this.sourceColumnNumber=sourceColumnNumber;this.name=name;}
WebInspector.SourceMap=function(){}
WebInspector.SourceMap.prototype={compiledURL:function(){},url:function(){},sourceURLs:function(){},sourceContentProvider:function(sourceURL,contentType){},findEntry:function(lineNumber,columnNumber){},editable:function(){},editCompiled:function(ranges,texts){},}
WebInspector.SourceMap.EditResult=function(map,compiledEdits,newSources)
{this.map=map;this.compiledEdits=compiledEdits;this.newSources=newSources;}
WebInspector.SourceMapFactory=function(){}
WebInspector.SourceMapFactory.prototype={editableSourceMap:function(target,sourceMap){},}
WebInspector.TextSourceMap=function(compiledURL,sourceMappingURL,payload)
{if(!WebInspector.TextSourceMap.prototype._base64Map){const base64Digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";WebInspector.TextSourceMap.prototype._base64Map={};for(var i=0;i<base64Digits.length;++i)
WebInspector.TextSourceMap.prototype._base64Map[base64Digits.charAt(i)]=i;}
this._compiledURL=compiledURL;this._sourceMappingURL=sourceMappingURL;this._reverseMappingsBySourceURL=new Map();this._mappings=[];this._sources={};this._sourceContentByURL={};this._parseMappingPayload(payload);}
WebInspector.TextSourceMap.load=function(sourceMapURL,compiledURL)
{var callback;var promise=new Promise(fulfill=>callback=fulfill);WebInspector.multitargetNetworkManager.loadResource(sourceMapURL,contentLoaded);return promise;function contentLoaded(statusCode,headers,content)
{if(!content||statusCode>=400){callback(null);return;}
if(content.slice(0,3)===")]}")
content=content.substring(content.indexOf("\n"));try{var payload=(JSON.parse(content));var baseURL=sourceMapURL.startsWith("data:")?compiledURL:sourceMapURL;callback(new WebInspector.TextSourceMap(compiledURL,baseURL,payload));}catch(e){console.error(e);WebInspector.console.error("Failed to parse SourceMap: "+sourceMapURL);callback(null);}}}
WebInspector.TextSourceMap.prototype={compiledURL:function()
{return this._compiledURL;},url:function()
{return this._sourceMappingURL;},sourceURLs:function()
{return Object.keys(this._sources);},sourceContentProvider:function(sourceURL,contentType)
{var sourceContent=this._sourceContentByURL[sourceURL];if(sourceContent)
return WebInspector.StaticContentProvider.fromString(sourceURL,contentType,sourceContent);return new WebInspector.CompilerSourceMappingContentProvider(sourceURL,contentType);},editable:function()
{return false;},editCompiled:function(ranges,texts)
{return Promise.resolve((null));},_parseMappingPayload:function(mappingPayload)
{if(mappingPayload.sections)
this._parseSections(mappingPayload.sections);else
this._parseMap(mappingPayload,0,0);},_parseSections:function(sections)
{for(var i=0;i<sections.length;++i){var section=sections[i];this._parseMap(section.map,section.offset.line,section.offset.column);}},findEntry:function(lineNumber,columnNumber)
{var first=0;var count=this._mappings.length;while(count>1){var step=count>>1;var middle=first+step;var mapping=this._mappings[middle];if(lineNumber<mapping.lineNumber||(lineNumber===mapping.lineNumber&&columnNumber<mapping.columnNumber))
count=step;else{first=middle;count-=step;}}
var entry=this._mappings[first];if(!first&&entry&&(lineNumber<entry.lineNumber||(lineNumber===entry.lineNumber&&columnNumber<entry.columnNumber)))
return null;return entry;},firstSourceLineMapping:function(sourceURL,lineNumber)
{var mappings=this._reversedMappings(sourceURL);var index=mappings.lowerBound(lineNumber,lineComparator);if(index>=mappings.length||mappings[index].sourceLineNumber!==lineNumber)
return null;return mappings[index];function lineComparator(lineNumber,mapping)
{return lineNumber-mapping.sourceLineNumber;}},mappings:function()
{return this._mappings;},_reversedMappings:function(sourceURL)
{var mappings=this._reverseMappingsBySourceURL.get(sourceURL);if(!mappings)
return[];if(!mappings._sorted){mappings.sort(sourceMappingComparator);mappings._sorted=true;}
return mappings;function sourceMappingComparator(a,b)
{if(a.sourceLineNumber!==b.sourceLineNumber)
return a.sourceLineNumber-b.sourceLineNumber;if(a.sourceColumnNumber!==b.sourceColumnNumber)
return a.sourceColumnNumber-b.sourceColumnNumber;if(a.lineNumber!==b.lineNumber)
return a.lineNumber-b.lineNumber;return a.columnNumber-b.columnNumber;}},_parseMap:function(map,lineNumber,columnNumber)
{var sourceIndex=0;var sourceLineNumber=0;var sourceColumnNumber=0;var nameIndex=0;var sources=[];var names=map.names||[];var sourceRoot=map.sourceRoot||"";if(sourceRoot&&!sourceRoot.endsWith("/"))
sourceRoot+="/";for(var i=0;i<map.sources.length;++i){var href=sourceRoot+map.sources[i];var url=WebInspector.ParsedURL.completeURL(this._sourceMappingURL,href)||href;var hasSource=map.sourcesContent&&map.sourcesContent[i];if(url===this._compiledURL&&hasSource)
url+=WebInspector.UIString(" [sm]");sources.push(url);this._sources[url]=true;if(hasSource)
this._sourceContentByURL[url]=map.sourcesContent[i];}
var stringCharIterator=new WebInspector.TextSourceMap.StringCharIterator(map.mappings);var sourceURL=sources[sourceIndex];while(true){if(stringCharIterator.peek()===",")
stringCharIterator.next();else{while(stringCharIterator.peek()===";"){lineNumber+=1;columnNumber=0;stringCharIterator.next();}
if(!stringCharIterator.hasNext())
break;}
columnNumber+=this._decodeVLQ(stringCharIterator);if(!stringCharIterator.hasNext()||this._isSeparator(stringCharIterator.peek())){this._mappings.push(new WebInspector.SourceMapEntry(lineNumber,columnNumber));continue;}
var sourceIndexDelta=this._decodeVLQ(stringCharIterator);if(sourceIndexDelta){sourceIndex+=sourceIndexDelta;sourceURL=sources[sourceIndex];}
sourceLineNumber+=this._decodeVLQ(stringCharIterator);sourceColumnNumber+=this._decodeVLQ(stringCharIterator);if(!this._isSeparator(stringCharIterator.peek()))
nameIndex+=this._decodeVLQ(stringCharIterator);this._mappings.push(new WebInspector.SourceMapEntry(lineNumber,columnNumber,sourceURL,sourceLineNumber,sourceColumnNumber,names[nameIndex]));}
for(var i=0;i<this._mappings.length;++i){var mapping=this._mappings[i];var url=mapping.sourceURL;if(!url)
continue;if(!this._reverseMappingsBySourceURL.has(url))
this._reverseMappingsBySourceURL.set(url,[]);var reverseMappings=this._reverseMappingsBySourceURL.get(url);reverseMappings.push(mapping);}},_isSeparator:function(char)
{return char===","||char===";";},_decodeVLQ:function(stringCharIterator)
{var result=0;var shift=0;do{var digit=this._base64Map[stringCharIterator.next()];result+=(digit&this._VLQ_BASE_MASK)<<shift;shift+=this._VLQ_BASE_SHIFT;}while(digit&this._VLQ_CONTINUATION_MASK);var negative=result&1;result>>=1;return negative?-result:result;},reverseMapTextRange:function(url,textRange)
{function comparator(position,mapping)
{if(position.lineNumber!==mapping.sourceLineNumber)
return position.lineNumber-mapping.sourceLineNumber;return position.columnNumber-mapping.sourceColumnNumber;}
var mappings=this._reversedMappings(url);var startIndex=mappings.lowerBound({lineNumber:textRange.startLine,columnNumber:textRange.startColumn},comparator);var endIndex=mappings.upperBound({lineNumber:textRange.endLine,columnNumber:textRange.endColumn},comparator);var startMapping=mappings[startIndex];var endMapping=mappings[endIndex];return new WebInspector.TextRange(startMapping.lineNumber,startMapping.columnNumber,endMapping.lineNumber,endMapping.columnNumber);},_VLQ_BASE_SHIFT:5,_VLQ_BASE_MASK:(1<<5)-1,_VLQ_CONTINUATION_MASK:1<<5}
WebInspector.TextSourceMap.StringCharIterator=function(string)
{this._string=string;this._position=0;}
WebInspector.TextSourceMap.StringCharIterator.prototype={next:function()
{return this._string.charAt(this._position++);},peek:function()
{return this._string.charAt(this._position);},hasNext:function()
{return this._position<this._string.length;}};WebInspector.NetworkManager=function(target)
{WebInspector.SDKModel.call(this,WebInspector.NetworkManager,target);this._dispatcher=new WebInspector.NetworkDispatcher(this);this._target=target;this._networkAgent=target.networkAgent();target.registerNetworkDispatcher(this._dispatcher);if(WebInspector.moduleSetting("cacheDisabled").get())
this._networkAgent.setCacheDisabled(true);if(WebInspector.moduleSetting("monitoringXHREnabled").get())
this._networkAgent.setMonitoringXHREnabled(true);if(Runtime.queryParam("remoteFrontend")||Runtime.queryParam("ws"))
this._networkAgent.enable(10000000,5000000);else
this._networkAgent.enable();this._certificateDetailsCache=new Map();this._bypassServiceWorkerSetting=WebInspector.settings.createSetting("bypassServiceWorker",false);if(this._bypassServiceWorkerSetting.get())
this._bypassServiceWorkerChanged();this._bypassServiceWorkerSetting.addChangeListener(this._bypassServiceWorkerChanged,this);WebInspector.moduleSetting("cacheDisabled").addChangeListener(this._cacheDisabledSettingChanged,this);}
WebInspector.NetworkManager.EventTypes={RequestStarted:"RequestStarted",RequestUpdated:"RequestUpdated",RequestFinished:"RequestFinished",RequestUpdateDropped:"RequestUpdateDropped",ResponseReceived:"ResponseReceived"}
WebInspector.NetworkManager._MIMETypes={"text/html":{"document":true},"text/xml":{"document":true},"text/plain":{"document":true},"application/xhtml+xml":{"document":true},"image/svg+xml":{"document":true},"text/css":{"stylesheet":true},"text/xsl":{"stylesheet":true},"text/vtt":{"texttrack":true},}
WebInspector.NetworkManager.Conditions;WebInspector.NetworkManager.NoThrottlingConditions={title:WebInspector.UIString("No throttling"),download:-1,upload:-1,latency:0};WebInspector.NetworkManager.OfflineConditions={title:WebInspector.UIString("Offline"),download:0,upload:0,latency:0};WebInspector.NetworkManager.prototype={inflightRequestForURL:function(url)
{return this._dispatcher._inflightRequestsByURL[url];},_cacheDisabledSettingChanged:function(event)
{var enabled=(event.data);this._networkAgent.setCacheDisabled(enabled);},dispose:function()
{WebInspector.moduleSetting("cacheDisabled").removeChangeListener(this._cacheDisabledSettingChanged,this);},certificateDetailsPromise:function(certificateId)
{var cachedPromise=this._certificateDetailsCache.get(certificateId);if(cachedPromise)
return cachedPromise;function executor(resolve,reject){function innerCallback(error,certificateDetails)
{if(error){console.error("Unable to get certificate details from the browser (for certificate ID ",certificateId,"): ",error);reject();}else{resolve(certificateDetails);}}
this._networkAgent.getCertificateDetails(certificateId,innerCallback);}
var promise=new Promise(executor.bind(this));this._certificateDetailsCache.set(certificateId,promise);return promise;},bypassServiceWorkerSetting:function()
{return this._bypassServiceWorkerSetting;},_bypassServiceWorkerChanged:function()
{this._networkAgent.setBypassServiceWorker(this._bypassServiceWorkerSetting.get());},__proto__:WebInspector.SDKModel.prototype}
WebInspector.NetworkDispatcher=function(manager)
{this._manager=manager;this._inflightRequestsById={};this._inflightRequestsByURL={};}
WebInspector.NetworkDispatcher.prototype={_headersMapToHeadersArray:function(headersMap)
{var result=[];for(var name in headersMap){var values=headersMap[name].split("\n");for(var i=0;i<values.length;++i)
result.push({name:name,value:values[i]});}
return result;},_updateNetworkRequestWithRequest:function(networkRequest,request)
{networkRequest.requestMethod=request.method;networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));networkRequest.requestFormData=request.postData;networkRequest.setInitialPriority(request.initialPriority);networkRequest.mixedContentType=request.mixedContentType||NetworkAgent.RequestMixedContentType.None;},_updateNetworkRequestWithResponse:function(networkRequest,response)
{if(response.url&&networkRequest.url!==response.url)
networkRequest.url=response.url;networkRequest.mimeType=response.mimeType;networkRequest.statusCode=response.status;networkRequest.statusText=response.statusText;networkRequest.responseHeaders=this._headersMapToHeadersArray(response.headers);if(response.encodedDataLength>=0)
networkRequest.setTransferSize(response.encodedDataLength);if(response.headersText)
networkRequest.responseHeadersText=response.headersText;if(response.requestHeaders){networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));networkRequest.setRequestHeadersText(response.requestHeadersText||"");}
networkRequest.connectionReused=response.connectionReused;networkRequest.connectionId=String(response.connectionId);if(response.remoteIPAddress)
networkRequest.setRemoteAddress(response.remoteIPAddress,response.remotePort||-1);if(response.fromServiceWorker)
networkRequest.fetchedViaServiceWorker=true;if(response.fromDiskCache)
networkRequest.setFromDiskCache();networkRequest.timing=response.timing;networkRequest.protocol=response.protocol;networkRequest.setSecurityState(response.securityState);if(!this._mimeTypeIsConsistentWithType(networkRequest)){var consoleModel=this._manager._target.consoleModel;consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(),WebInspector.ConsoleMessage.MessageSource.Network,WebInspector.ConsoleMessage.MessageLevel.Log,WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".",networkRequest.resourceType().title(),networkRequest.mimeType,networkRequest.url),WebInspector.ConsoleMessage.MessageType.Log,"",0,0,networkRequest.requestId));}
if(response.securityDetails)
networkRequest.setSecurityDetails(response.securityDetails);},_mimeTypeIsConsistentWithType:function(networkRequest)
{if(networkRequest.hasErrorStatusCode()||networkRequest.statusCode===304||networkRequest.statusCode===204)
return true;var resourceType=networkRequest.resourceType();if(resourceType!==WebInspector.resourceTypes.Stylesheet&&resourceType!==WebInspector.resourceTypes.Document&&resourceType!==WebInspector.resourceTypes.TextTrack){return true;}
if(!networkRequest.mimeType)
return true;if(networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
return resourceType.name()in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];return false;},resourceChangedPriority:function(requestId,newPriority,timestamp)
{var networkRequest=this._inflightRequestsById[requestId];if(networkRequest)
networkRequest.setPriority(newPriority);},requestWillBeSent:function(requestId,frameId,loaderId,documentURL,request,time,wallTime,initiator,redirectResponse,resourceType)
{var networkRequest=this._inflightRequestsById[requestId];if(networkRequest){if(!redirectResponse)
return;this.responseReceived(requestId,frameId,loaderId,time,PageAgent.ResourceType.Other,redirectResponse);networkRequest=this._appendRedirect(requestId,time,request.url);}else
networkRequest=this._createNetworkRequest(requestId,frameId,loaderId,request.url,documentURL,initiator);networkRequest.hasNetworkData=true;this._updateNetworkRequestWithRequest(networkRequest,request);networkRequest.setIssueTime(time,wallTime);networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);this._startNetworkRequest(networkRequest);},requestServedFromCache:function(requestId)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.setFromMemoryCache();},responseReceived:function(requestId,frameId,loaderId,time,resourceType,response)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest){var eventData={};eventData.url=response.url;eventData.frameId=frameId;eventData.loaderId=loaderId;eventData.resourceType=resourceType;eventData.mimeType=response.mimeType;this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped,eventData);return;}
networkRequest.responseReceivedTime=time;networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);this._updateNetworkRequestWithResponse(networkRequest,response);this._updateNetworkRequest(networkRequest);this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResponseReceived,networkRequest);},dataReceived:function(requestId,time,dataLength,encodedDataLength)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.resourceSize+=dataLength;if(encodedDataLength!=-1)
networkRequest.increaseTransferSize(encodedDataLength);networkRequest.endTime=time;this._updateNetworkRequest(networkRequest);},loadingFinished:function(requestId,finishTime,encodedDataLength)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;this._finishNetworkRequest(networkRequest,finishTime,encodedDataLength);},loadingFailed:function(requestId,time,resourceType,localizedDescription,canceled,blockedReason)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.failed=true;networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);networkRequest.canceled=canceled;if(blockedReason){networkRequest.setBlockedReason(blockedReason);if(blockedReason===NetworkAgent.BlockedReason.Inspector){var consoleModel=this._manager._target.consoleModel;consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(),WebInspector.ConsoleMessage.MessageSource.Network,WebInspector.ConsoleMessage.MessageLevel.Warning,WebInspector.UIString("Request was blocked by DevTools: \"%s\".",networkRequest.url),WebInspector.ConsoleMessage.MessageType.Log,"",0,0,networkRequest.requestId));}}
networkRequest.localizedFailDescription=localizedDescription;this._finishNetworkRequest(networkRequest,time,-1);},webSocketCreated:function(requestId,requestURL)
{var networkRequest=new WebInspector.NetworkRequest(this._manager._target,requestId,requestURL,"","","",null);networkRequest.setResourceType(WebInspector.resourceTypes.WebSocket);this._startNetworkRequest(networkRequest);},webSocketWillSendHandshakeRequest:function(requestId,time,wallTime,request)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.requestMethod="GET";networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));networkRequest.setIssueTime(time,wallTime);this._updateNetworkRequest(networkRequest);},webSocketHandshakeResponseReceived:function(requestId,time,response)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.statusCode=response.status;networkRequest.statusText=response.statusText;networkRequest.responseHeaders=this._headersMapToHeadersArray(response.headers);networkRequest.responseHeadersText=response.headersText;if(response.requestHeaders)
networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));if(response.requestHeadersText)
networkRequest.setRequestHeadersText(response.requestHeadersText);networkRequest.responseReceivedTime=time;networkRequest.protocol="websocket";this._updateNetworkRequest(networkRequest);},webSocketFrameReceived:function(requestId,time,response)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.addFrame(response,time);networkRequest.responseReceivedTime=time;this._updateNetworkRequest(networkRequest);},webSocketFrameSent:function(requestId,time,response)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.addFrame(response,time,true);networkRequest.responseReceivedTime=time;this._updateNetworkRequest(networkRequest);},webSocketFrameError:function(requestId,time,errorMessage)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.addFrameError(errorMessage,time);networkRequest.responseReceivedTime=time;this._updateNetworkRequest(networkRequest);},webSocketClosed:function(requestId,time)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;this._finishNetworkRequest(networkRequest,time,-1);},eventSourceMessageReceived:function(requestId,time,eventName,eventId,data)
{var networkRequest=this._inflightRequestsById[requestId];if(!networkRequest)
return;networkRequest.addEventSourceMessage(time,eventName,eventId,data);},_appendRedirect:function(requestId,time,redirectURL)
{var originalNetworkRequest=this._inflightRequestsById[requestId];var previousRedirects=originalNetworkRequest.redirects||[];originalNetworkRequest.requestId=requestId+":redirected."+previousRedirects.length;delete originalNetworkRequest.redirects;if(previousRedirects.length>0)
originalNetworkRequest.redirectSource=previousRedirects[previousRedirects.length-1];this._finishNetworkRequest(originalNetworkRequest,time,-1);var newNetworkRequest=this._createNetworkRequest(requestId,originalNetworkRequest.frameId,originalNetworkRequest.loaderId,redirectURL,originalNetworkRequest.documentURL,originalNetworkRequest.initiator());newNetworkRequest.redirects=previousRedirects.concat(originalNetworkRequest);return newNetworkRequest;},_startNetworkRequest:function(networkRequest)
{this._inflightRequestsById[networkRequest.requestId]=networkRequest;this._inflightRequestsByURL[networkRequest.url]=networkRequest;this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted,networkRequest);},_updateNetworkRequest:function(networkRequest)
{this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated,networkRequest);},_finishNetworkRequest:function(networkRequest,finishTime,encodedDataLength)
{networkRequest.endTime=finishTime;networkRequest.finished=true;if(encodedDataLength>=0)
networkRequest.setTransferSize(encodedDataLength);this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished,networkRequest);delete this._inflightRequestsById[networkRequest.requestId];delete this._inflightRequestsByURL[networkRequest.url];},_dispatchEventToListeners:function(eventType,networkRequest)
{this._manager.dispatchEventToListeners(eventType,networkRequest);},_createNetworkRequest:function(requestId,frameId,loaderId,url,documentURL,initiator)
{return new WebInspector.NetworkRequest(this._manager._target,requestId,url,documentURL,frameId,loaderId,initiator);}}
WebInspector.MultitargetNetworkManager=function()
{WebInspector.Object.call(this);WebInspector.targetManager.observeTargets(this);this._blockedURLs=new Set();this._blockedSetting=WebInspector.moduleSetting("blockedURLs");this._blockedSetting.addChangeListener(this._updateBlockedURLs,this);this._blockedSetting.set([]);this._updateBlockedURLs();this._userAgentOverride="";this._agentsCapableOfEmulation=new Set();this._networkConditions=WebInspector.NetworkManager.NoThrottlingConditions;}
WebInspector.MultitargetNetworkManager.Events={ConditionsChanged:"ConditionsChanged",UserAgentChanged:"UserAgentChanged"}
WebInspector.MultitargetNetworkManager.prototype={targetAdded:function(target)
{var networkAgent=target.networkAgent();if(this._extraHeaders)
networkAgent.setExtraHTTPHeaders(this._extraHeaders);if(this._currentUserAgent())
networkAgent.setUserAgentOverride(this._currentUserAgent());for(var url of this._blockedURLs)
networkAgent.addBlockedURL(url);networkAgent.canEmulateNetworkConditions(callback.bind(this));function callback(error,canEmulate)
{if(error||!canEmulate)
return;this._agentsCapableOfEmulation.add(networkAgent);if(this.isThrottling())
this._updateNetworkConditions(networkAgent);}},targetRemoved:function(target)
{this._agentsCapableOfEmulation.delete(target.networkAgent());},isThrottling:function()
{return this._networkConditions.download>=0||this._networkConditions.upload>=0||this._networkConditions.latency>0;},isOffline:function()
{return!this._networkConditions.download&&!this._networkConditions.upload;},setNetworkConditions:function(conditions)
{this._networkConditions=conditions;for(var agent of this._agentsCapableOfEmulation)
this._updateNetworkConditions(agent);this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged);},networkConditions:function()
{return this._networkConditions;},_updateNetworkConditions:function(networkAgent)
{var conditions=this._networkConditions;if(!this.isThrottling()){networkAgent.emulateNetworkConditions(false,0,0,0);}else{networkAgent.emulateNetworkConditions(this.isOffline(),conditions.latency,conditions.download<0?0:conditions.download,conditions.upload<0?0:conditions.upload);}},setExtraHTTPHeaders:function(headers)
{this._extraHeaders=headers;for(var target of WebInspector.targetManager.targets())
target.networkAgent().setExtraHTTPHeaders(this._extraHeaders);},_currentUserAgent:function()
{return this._customUserAgent?this._customUserAgent:this._userAgentOverride;},_updateUserAgentOverride:function()
{var userAgent=this._currentUserAgent();WebInspector.ResourceLoader.targetUserAgent=userAgent;for(var target of WebInspector.targetManager.targets())
target.networkAgent().setUserAgentOverride(userAgent);},setUserAgentOverride:function(userAgent)
{if(this._userAgentOverride===userAgent)
return;this._userAgentOverride=userAgent;if(!this._customUserAgent)
this._updateUserAgentOverride();this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.UserAgentChanged);},userAgentOverride:function()
{return this._userAgentOverride;},setCustomUserAgentOverride:function(userAgent)
{this._customUserAgent=userAgent;this._updateUserAgentOverride();},_updateBlockedURLs:function()
{var blocked=this._blockedSetting.get();for(var url of blocked){if(!this._blockedURLs.has(url))
this._addBlockedURL(url);}
for(var url of this._blockedURLs){if(blocked.indexOf(url)===-1)
this._removeBlockedURL(url);}},_addBlockedURL:function(url)
{this._blockedURLs.add(url);for(var target of WebInspector.targetManager.targets())
target.networkAgent().addBlockedURL(url);},_removeBlockedURL:function(url)
{this._blockedURLs.delete(url);for(var target of WebInspector.targetManager.targets())
target.networkAgent().removeBlockedURL(url);},clearBrowserCache:function()
{for(var target of WebInspector.targetManager.targets())
target.networkAgent().clearBrowserCache();},clearBrowserCookies:function()
{for(var target of WebInspector.targetManager.targets())
target.networkAgent().clearBrowserCookies();},showCertificateViewer:function(certificateId)
{var target=WebInspector.targetManager.mainTarget();if(target)
target.networkAgent().showCertificateViewer(certificateId);},loadResource:function(url,callback)
{var headers={};var currentUserAgent=this._currentUserAgent();if(currentUserAgent)
headers["User-Agent"]=currentUserAgent;if(WebInspector.moduleSetting("cacheDisabled").get())
headers["Cache-Control"]="no-cache";WebInspector.ResourceLoader.load(url,headers,callback);},__proto__:WebInspector.Object.prototype}
WebInspector.multitargetNetworkManager;;WebInspector.NetworkRequest=function(target,requestId,url,documentURL,frameId,loaderId,initiator)
{WebInspector.SDKObject.call(this,target);this._requestId=requestId;this.url=url;this._documentURL=documentURL;this._frameId=frameId;this._loaderId=loaderId;this._initiator=initiator;this._issueTime=-1;this._startTime=-1;this._endTime=-1;this._blockedReason=undefined;this.statusCode=0;this.statusText="";this.requestMethod="";this.requestTime=0;this.protocol="";this.mixedContentType=NetworkAgent.RequestMixedContentType.None;this._initialPriority=null;this._currentPriority=null;this._resourceType=WebInspector.resourceTypes.Other;this._contentEncoded=false;this._pendingContentCallbacks=[];this._frames=[];this._eventSourceMessages=[];this._responseHeaderValues={};this._remoteAddress="";this._securityState=SecurityAgent.SecurityState.Unknown;this._securityDetails=null;this.connectionId="0";}
WebInspector.NetworkRequest.Events={FinishedLoading:"FinishedLoading",TimingChanged:"TimingChanged",RemoteAddressChanged:"RemoteAddressChanged",RequestHeadersChanged:"RequestHeadersChanged",ResponseHeadersChanged:"ResponseHeadersChanged",WebsocketFrameAdded:"WebsocketFrameAdded",EventSourceMessageAdded:"EventSourceMessageAdded",}
WebInspector.NetworkRequest.InitiatorType={Other:"other",Parser:"parser",Redirect:"redirect",Script:"script"}
WebInspector.NetworkRequest.NameValue;WebInspector.NetworkRequest.WebSocketFrameType={Send:"send",Receive:"receive",Error:"error"}
WebInspector.NetworkRequest.WebSocketFrame;WebInspector.NetworkRequest.EventSourceMessage;WebInspector.NetworkRequest.prototype={indentityCompare:function(other)
{if(this._requestId>other._requestId)
return 1;if(this._requestId<other._requestId)
return-1;return 0;},get requestId()
{return this._requestId;},set requestId(requestId)
{this._requestId=requestId;},get url()
{return this._url;},set url(x)
{if(this._url===x)
return;this._url=x;this._parsedURL=new WebInspector.ParsedURL(x);delete this._queryString;delete this._parsedQueryParameters;delete this._name;delete this._path;},get documentURL()
{return this._documentURL;},get parsedURL()
{return this._parsedURL;},get frameId()
{return this._frameId;},get loaderId()
{return this._loaderId;},setRemoteAddress:function(ip,port)
{this._remoteAddress=ip+":"+port;this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged,this);},remoteAddress:function()
{return this._remoteAddress;},securityState:function()
{return this._securityState;},setSecurityState:function(securityState)
{this._securityState=securityState;},securityDetails:function()
{return this._securityDetails;},setSecurityDetails:function(securityDetails)
{this._securityDetails=securityDetails;},get startTime()
{return this._startTime||-1;},setIssueTime:function(monotonicTime,wallTime)
{this._issueTime=monotonicTime;this._wallIssueTime=wallTime;this._startTime=monotonicTime;},issueTime:function()
{return this._issueTime;},pseudoWallTime:function(monotonicTime)
{return this._wallIssueTime?this._wallIssueTime-this._issueTime+monotonicTime:monotonicTime;},get responseReceivedTime()
{return this._responseReceivedTime||-1;},set responseReceivedTime(x)
{this._responseReceivedTime=x;},get endTime()
{return this._endTime||-1;},set endTime(x)
{if(this.timing&&this.timing.requestTime){this._endTime=Math.max(x,this.responseReceivedTime);}else{this._endTime=x;if(this._responseReceivedTime>x)
this._responseReceivedTime=x;}
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged,this);},get duration()
{if(this._endTime===-1||this._startTime===-1)
return-1;return this._endTime-this._startTime;},get latency()
{if(this._responseReceivedTime===-1||this._startTime===-1)
return-1;return this._responseReceivedTime-this._startTime;},get resourceSize()
{return this._resourceSize||0;},set resourceSize(x)
{this._resourceSize=x;},get transferSize()
{return this._transferSize||0;},increaseTransferSize:function(x)
{this._transferSize=(this._transferSize||0)+x;},setTransferSize:function(x)
{this._transferSize=x;},get finished()
{return this._finished;},set finished(x)
{if(this._finished===x)
return;this._finished=x;if(x){this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading,this);if(this._pendingContentCallbacks.length)
this._innerRequestContent();}},get failed()
{return this._failed;},set failed(x)
{this._failed=x;},get canceled()
{return this._canceled;},set canceled(x)
{this._canceled=x;},blockedReason:function()
{return this._blockedReason;},setBlockedReason:function(reason)
{this._blockedReason=reason;},wasBlocked:function()
{return!!this._blockedReason;},cached:function()
{return(!!this._fromMemoryCache||!!this._fromDiskCache)&&!this._transferSize;},setFromMemoryCache:function()
{this._fromMemoryCache=true;delete this._timing;},setFromDiskCache:function()
{this._fromDiskCache=true;},get fetchedViaServiceWorker()
{return this._fetchedViaServiceWorker;},set fetchedViaServiceWorker(x)
{this._fetchedViaServiceWorker=x;},get timing()
{return this._timing;},set timing(x)
{if(x&&!this._fromMemoryCache){this._startTime=x.requestTime;this._responseReceivedTime=x.requestTime+x.receiveHeadersEnd/1000.0;this._timing=x;this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged,this);}},get mimeType()
{return this._mimeType;},set mimeType(x)
{this._mimeType=x;},get displayName()
{return this._parsedURL.displayName;},name:function()
{if(this._name)
return this._name;this._parseNameAndPathFromURL();return this._name;},path:function()
{if(this._path)
return this._path;this._parseNameAndPathFromURL();return this._path;},_parseNameAndPathFromURL:function()
{if(this._parsedURL.isDataURL()){this._name=this._parsedURL.dataURLDisplayName();this._path="";}else if(this._parsedURL.isAboutBlank()){this._name=this._parsedURL.url;this._path="";}else{this._path=this._parsedURL.host+this._parsedURL.folderPathComponents;this._path=this._path.trimURL(this.target().resourceTreeModel.inspectedPageDomain());if(this._parsedURL.lastPathComponent||this._parsedURL.queryParams)
this._name=this._parsedURL.lastPathComponent+(this._parsedURL.queryParams?"?"+this._parsedURL.queryParams:"");else if(this._parsedURL.folderPathComponents){this._name=this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/")+1)+"/";this._path=this._path.substring(0,this._path.lastIndexOf("/"));}else{this._name=this._parsedURL.host;this._path="";}}},get folder()
{var path=this._parsedURL.path;var indexOfQuery=path.indexOf("?");if(indexOfQuery!==-1)
path=path.substring(0,indexOfQuery);var lastSlashIndex=path.lastIndexOf("/");return lastSlashIndex!==-1?path.substring(0,lastSlashIndex):"";},resourceType:function()
{return this._resourceType;},setResourceType:function(resourceType)
{this._resourceType=resourceType;},get domain()
{return this._parsedURL.host;},get scheme()
{return this._parsedURL.scheme;},get redirectSource()
{if(this.redirects&&this.redirects.length>0)
return this.redirects[this.redirects.length-1];return this._redirectSource;},set redirectSource(x)
{this._redirectSource=x;delete this._initiatorInfo;},requestHeaders:function()
{return this._requestHeaders||[];},setRequestHeaders:function(headers)
{this._requestHeaders=headers;delete this._requestCookies;this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);},requestHeadersText:function()
{return this._requestHeadersText;},setRequestHeadersText:function(text)
{this._requestHeadersText=text;this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);},requestHeaderValue:function(headerName)
{return this._headerValue(this.requestHeaders(),headerName);},get requestCookies()
{if(!this._requestCookies)
this._requestCookies=WebInspector.CookieParser.parseCookie(this.target(),this.requestHeaderValue("Cookie"));return this._requestCookies;},get requestFormData()
{return this._requestFormData;},set requestFormData(x)
{this._requestFormData=x;delete this._parsedFormParameters;},requestHttpVersion:function()
{var headersText=this.requestHeadersText();if(!headersText)
return this.requestHeaderValue("version")||this.requestHeaderValue(":version")||"unknown";var firstLine=headersText.split(/\r\n/)[0];var match=firstLine.match(/(HTTP\/\d+\.\d+)$/);return match?match[1]:"HTTP/0.9";},get responseHeaders()
{return this._responseHeaders||[];},set responseHeaders(x)
{this._responseHeaders=x;delete this._sortedResponseHeaders;delete this._responseCookies;this._responseHeaderValues={};this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);},get responseHeadersText()
{return this._responseHeadersText;},set responseHeadersText(x)
{this._responseHeadersText=x;this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);},get sortedResponseHeaders()
{if(this._sortedResponseHeaders!==undefined)
return this._sortedResponseHeaders;this._sortedResponseHeaders=this.responseHeaders.slice();this._sortedResponseHeaders.sort(function(a,b){return a.name.toLowerCase().compareTo(b.name.toLowerCase());});return this._sortedResponseHeaders;},responseHeaderValue:function(headerName)
{var value=this._responseHeaderValues[headerName];if(value===undefined){value=this._headerValue(this.responseHeaders,headerName);this._responseHeaderValues[headerName]=(value!==undefined)?value:null;}
return(value!==null)?value:undefined;},get responseCookies()
{if(!this._responseCookies)
this._responseCookies=WebInspector.CookieParser.parseSetCookie(this.target(),this.responseHeaderValue("Set-Cookie"));return this._responseCookies;},queryString:function()
{if(this._queryString!==undefined)
return this._queryString;var queryString=null;var url=this.url;var questionMarkPosition=url.indexOf("?");if(questionMarkPosition!==-1){queryString=url.substring(questionMarkPosition+1);var hashSignPosition=queryString.indexOf("#");if(hashSignPosition!==-1)
queryString=queryString.substring(0,hashSignPosition);}
this._queryString=queryString;return this._queryString;},get queryParameters()
{if(this._parsedQueryParameters)
return this._parsedQueryParameters;var queryString=this.queryString();if(!queryString)
return null;this._parsedQueryParameters=this._parseParameters(queryString);return this._parsedQueryParameters;},get formParameters()
{if(this._parsedFormParameters)
return this._parsedFormParameters;if(!this.requestFormData)
return null;var requestContentType=this.requestContentType();if(!requestContentType||!requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return null;this._parsedFormParameters=this._parseParameters(this.requestFormData);return this._parsedFormParameters;},responseHttpVersion:function()
{var headersText=this._responseHeadersText;if(!headersText)
return this.responseHeaderValue("version")||this.responseHeaderValue(":version")||"unknown";var firstLine=headersText.split(/\r\n/)[0];var match=firstLine.match(/^(HTTP\/\d+\.\d+)/);return match?match[1]:"HTTP/0.9";},_parseParameters:function(queryString)
{function parseNameValue(pair)
{var position=pair.indexOf("=");if(position===-1)
return{name:pair,value:""};else
return{name:pair.substring(0,position),value:pair.substring(position+1)};}
return queryString.split("&").map(parseNameValue);},_headerValue:function(headers,headerName)
{headerName=headerName.toLowerCase();var values=[];for(var i=0;i<headers.length;++i){if(headers[i].name.toLowerCase()===headerName)
values.push(headers[i].value);}
if(!values.length)
return undefined;if(headerName==="set-cookie")
return values.join("\n");return values.join(", ");},get content()
{return this._content;},contentError:function()
{return this._contentError;},get contentEncoded()
{return this._contentEncoded;},contentURL:function()
{return this._url;},contentType:function()
{return this._resourceType;},requestContent:function()
{if(this._resourceType===WebInspector.resourceTypes.WebSocket)
return Promise.resolve((null));if(typeof this._content!=="undefined")
return Promise.resolve((this.content||null));var callback;var promise=new Promise(fulfill=>callback=fulfill);this._pendingContentCallbacks.push(callback);if(this.finished)
this._innerRequestContent();return promise;},searchInContent:function(query,caseSensitive,isRegex,callback)
{callback([]);},isHttpFamily:function()
{return!!this.url.match(/^https?:/i);},requestContentType:function()
{return this.requestHeaderValue("Content-Type");},hasErrorStatusCode:function()
{return this.statusCode>=400;},setInitialPriority:function(priority)
{this._initialPriority=priority;},initialPriority:function()
{return this._initialPriority;},setPriority:function(priority)
{this._currentPriority=priority;},priority:function()
{return this._currentPriority||this._initialPriority||null;},populateImageSource:function(image)
{WebInspector.Resource.populateImageSource(this._url,this._mimeType,this,image);},asDataURL:function()
{var content=this._content;var charset=null;if(!this._contentEncoded){content=content.toBase64();charset="utf-8";}
return WebInspector.Resource.contentAsDataURL(content,this.mimeType,true,charset);},_innerRequestContent:function()
{if(this._contentRequested)
return;this._contentRequested=true;function onResourceContent(error,content,contentEncoded)
{this._content=error?null:content;this._contentError=error;this._contentEncoded=contentEncoded;var callbacks=this._pendingContentCallbacks.slice();for(var i=0;i<callbacks.length;++i)
callbacks[i](this._content);this._pendingContentCallbacks.length=0;delete this._contentRequested;}
this.target().networkAgent().getResponseBody(this._requestId,onResourceContent.bind(this));},initiator:function()
{return this._initiator;},initiatorInfo:function()
{if(this._initiatorInfo)
return this._initiatorInfo;var type=WebInspector.NetworkRequest.InitiatorType.Other;var url="";var lineNumber=-Infinity;var columnNumber=-Infinity;var scriptId=null;var initiator=this._initiator;if(this.redirectSource){type=WebInspector.NetworkRequest.InitiatorType.Redirect;url=this.redirectSource.url;}else if(initiator){if(initiator.type===NetworkAgent.InitiatorType.Parser){type=WebInspector.NetworkRequest.InitiatorType.Parser;url=initiator.url?initiator.url:url;lineNumber=initiator.lineNumber?initiator.lineNumber:lineNumber;}else if(initiator.type===NetworkAgent.InitiatorType.Script){for(var stack=initiator.stack;stack;stack=stack.parent){var topFrame=stack.callFrames.length?stack.callFrames[0]:null;if(!topFrame)
continue;type=WebInspector.NetworkRequest.InitiatorType.Script;url=topFrame.url||WebInspector.UIString("<anonymous>");lineNumber=topFrame.lineNumber;columnNumber=topFrame.columnNumber;scriptId=topFrame.scriptId;break;}}}
this._initiatorInfo={type:type,url:url,lineNumber:lineNumber,columnNumber:columnNumber,scriptId:scriptId};return this._initiatorInfo;},initiatorRequest:function()
{if(this._initiatorRequest===undefined)
this._initiatorRequest=this.target().networkLog.requestForURL(this.initiatorInfo().url);return this._initiatorRequest;},initiatorChain:function()
{if(this._initiatorChain)
return this._initiatorChain;this._initiatorChain=new Set();var request=this;while(request){this._initiatorChain.add(request);request=request.initiatorRequest();}
return this._initiatorChain;},frames:function()
{return this._frames;},addFrameError:function(errorMessage,time)
{this._addFrame({type:WebInspector.NetworkRequest.WebSocketFrameType.Error,text:errorMessage,time:this.pseudoWallTime(time),opCode:-1,mask:false});},addFrame:function(response,time,sent)
{var type=sent?WebInspector.NetworkRequest.WebSocketFrameType.Send:WebInspector.NetworkRequest.WebSocketFrameType.Receive;this._addFrame({type:type,text:response.payloadData,time:this.pseudoWallTime(time),opCode:response.opcode,mask:response.mask});},_addFrame:function(frame)
{this._frames.push(frame);this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.WebsocketFrameAdded,frame);},eventSourceMessages:function()
{return this._eventSourceMessages;},addEventSourceMessage:function(time,eventName,eventId,data)
{var message={time:this.pseudoWallTime(time),eventName:eventName,eventId:eventId,data:data};this._eventSourceMessages.push(message);this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.EventSourceMessageAdded,message);},replayXHR:function()
{this.target().networkAgent().replayXHR(this.requestId);},__proto__:WebInspector.SDKObject.prototype};WebInspector.PictureFragment;WebInspector.PaintProfilerSnapshot=function(target,snapshotId)
{this._target=target;this._id=snapshotId;}
WebInspector.PaintProfilerSnapshot.loadFromFragments=function(target,fragments,callback)
{var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.loadSnapshot(): ",WebInspector.PaintProfilerSnapshot.bind(null,target));target.layerTreeAgent().loadSnapshot(fragments,wrappedCallback);}
WebInspector.PaintProfilerSnapshot.load=function(target,encodedPicture,callback)
{var fragment={x:0,y:0,picture:encodedPicture};WebInspector.PaintProfilerSnapshot.loadFromFragments(target,[fragment],callback);}
WebInspector.PaintProfilerSnapshot.prototype={dispose:function()
{this._target.layerTreeAgent().releaseSnapshot(this._id);},target:function()
{return this._target;},requestImage:function(firstStep,lastStep,scale,callback)
{var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.replaySnapshot(): ");this._target.layerTreeAgent().replaySnapshot(this._id,firstStep||undefined,lastStep||undefined,scale||1.0,wrappedCallback);},profile:function(clipRect,callback)
{var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.profileSnapshot(): ");this._target.layerTreeAgent().profileSnapshot(this._id,5,1,clipRect||undefined,wrappedCallback);},commandLog:function(callback)
{function callbackWrapper(error,log)
{if(error){console.error("LayerTreeAgent.snapshotCommandLog(): "+error);callback();return;}
var logItems=log.map((entry,index)=>new WebInspector.PaintProfilerLogItem(entry,index));callback(logItems);}
this._target.layerTreeAgent().snapshotCommandLog(this._id,callbackWrapper);}};WebInspector.RawPaintProfilerLogItem;WebInspector.PaintProfilerLogItem=function(rawEntry,commandIndex)
{this.method=rawEntry.method;this.params=rawEntry.params;this.commandIndex=commandIndex;};WebInspector.HeapProfilerModel=function(target)
{WebInspector.SDKModel.call(this,WebInspector.HeapProfilerModel,target);target.registerHeapProfilerDispatcher(new WebInspector.HeapProfilerDispatcher(this));this._enabled=false;this._heapProfilerAgent=target.heapProfilerAgent();}
WebInspector.HeapProfilerModel.Events={HeapStatsUpdate:"HeapStatsUpdate",LastSeenObjectId:"LastSeenObjectId",AddHeapSnapshotChunk:"AddHeapSnapshotChunk",ReportHeapSnapshotProgress:"ReportHeapSnapshotProgress",ResetProfiles:"ResetProfiles"}
WebInspector.HeapProfilerModel.prototype={enable:function()
{if(this._enabled)
return;this._enabled=true;this._heapProfilerAgent.enable();},startSampling:function()
{var defaultSamplingIntervalInBytes=16384;this._heapProfilerAgent.startSampling(defaultSamplingIntervalInBytes);},stopSampling:function()
{this._isRecording=false;var currentProfile=null;return this._heapProfilerAgent.stopSampling((error,profile)=>{currentProfile=!error?profile:null;}).then(()=>currentProfile);},heapStatsUpdate:function(samples)
{this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate,samples);},lastSeenObjectId:function(lastSeenObjectId,timestamp)
{this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.LastSeenObjectId,{lastSeenObjectId:lastSeenObjectId,timestamp:timestamp});},addHeapSnapshotChunk:function(chunk)
{this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk,chunk);},reportHeapSnapshotProgress:function(done,total,finished)
{this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress,{done:done,total:total,finished:finished});},resetProfiles:function()
{this.dispatchEventToListeners(WebInspector.HeapProfilerModel.Events.ResetProfiles);},__proto__:WebInspector.SDKModel.prototype}
WebInspector.HeapProfilerDispatcher=function(model)
{this._heapProfilerModel=model;}
WebInspector.HeapProfilerDispatcher.prototype={heapStatsUpdate:function(samples)
{this._heapProfilerModel.heapStatsUpdate(samples);},lastSeenObjectId:function(lastSeenObjectId,timestamp)
{this._heapProfilerModel.lastSeenObjectId(lastSeenObjectId,timestamp);},addHeapSnapshotChunk:function(chunk)
{this._heapProfilerModel.addHeapSnapshotChunk(chunk);},reportHeapSnapshotProgress:function(done,total,finished)
{this._heapProfilerModel.reportHeapSnapshotProgress(done,total,finished);},resetProfiles:function()
{this._heapProfilerModel.resetProfiles();}};WebInspector.CSSMetadata.initializeWithSupportedProperties([{"name":"color"},{"name":"direction"},{"name":"font-family"},{"name":"font-kerning"},{"name":"font-size"},{"name":"font-size-adjust"},{"name":"font-stretch"},{"name":"font-style"},{"name":"font-variant-ligatures"},{"name":"font-variant-caps"},{"name":"font-variant-numeric"},{"name":"font-weight"},{"name":"font-feature-settings"},{"name":"-webkit-font-smoothing"},{"name":"-webkit-locale"},{"name":"text-orientation"},{"name":"-webkit-text-orientation"},{"name":"writing-mode"},{"name":"-webkit-writing-mode"},{"name":"text-rendering"},{"name":"zoom"},{"name":"align-content"},{"name":"align-items"},{"name":"alignment-baseline"},{"name":"align-self"},{"name":"animation-delay"},{"name":"animation-direction"},{"name":"animation-duration"},{"name":"animation-fill-mode"},{"name":"animation-iteration-count"},{"name":"animation-name"},{"name":"animation-play-state"},{"name":"animation-timing-function"},{"name":"backdrop-filter"},{"name":"backface-visibility"},{"name":"background-attachment"},{"name":"background-blend-mode"},{"name":"background-clip"},{"name":"background-color"},{"name":"background-image"},{"name":"background-origin"},{"name":"background-position-x"},{"name":"background-position-y"},{"name":"background-repeat-x"},{"name":"background-repeat-y"},{"name":"background-size"},{"name":"baseline-shift"},{"name":"border-bottom-color"},{"name":"border-bottom-left-radius"},{"name":"border-bottom-right-radius"},{"name":"border-bottom-style"},{"name":"border-bottom-width"},{"name":"border-collapse"},{"name":"border-image-outset"},{"name":"border-image-repeat"},{"name":"border-image-slice"},{"name":"border-image-source"},{"name":"border-image-width"},{"name":"border-left-color"},{"name":"border-left-style"},{"name":"border-left-width"},{"name":"border-right-color"},{"name":"border-right-style"},{"name":"border-right-width"},{"name":"border-top-color"},{"name":"border-top-left-radius"},{"name":"border-top-right-radius"},{"name":"border-top-style"},{"name":"border-top-width"},{"name":"bottom"},{"name":"box-shadow"},{"name":"box-sizing"},{"name":"break-after"},{"name":"break-before"},{"name":"break-inside"},{"name":"buffered-rendering"},{"name":"caption-side"},{"name":"clear"},{"name":"clip"},{"name":"clip-path"},{"name":"clip-rule"},{"name":"color-interpolation"},{"name":"color-interpolation-filters"},{"name":"color-rendering"},{"name":"column-fill"},{"name":"contain"},{"name":"content"},{"name":"counter-increment"},{"name":"counter-reset"},{"name":"cursor"},{"name":"cx"},{"name":"cy"},{"name":"d"},{"name":"display"},{"name":"dominant-baseline"},{"name":"empty-cells"},{"name":"fill"},{"name":"fill-opacity"},{"name":"fill-rule"},{"name":"filter"},{"name":"flex-basis"},{"name":"flex-direction"},{"name":"flex-grow"},{"name":"flex-shrink"},{"name":"flex-wrap"},{"name":"float"},{"name":"flood-color"},{"name":"flood-opacity"},{"name":"grid-auto-columns"},{"name":"grid-auto-flow"},{"name":"grid-auto-rows"},{"name":"grid-column-end"},{"name":"grid-column-gap"},{"name":"grid-column-start"},{"name":"grid-row-end"},{"name":"grid-row-gap"},{"name":"grid-row-start"},{"name":"grid-template-areas"},{"name":"grid-template-columns"},{"name":"grid-template-rows"},{"name":"height"},{"name":"hyphens"},{"name":"image-rendering"},{"name":"image-orientation"},{"name":"isolation"},{"name":"justify-content"},{"name":"justify-items"},{"name":"justify-self"},{"name":"left"},{"name":"letter-spacing"},{"name":"lighting-color"},{"name":"line-height"},{"name":"list-style-image"},{"name":"list-style-position"},{"name":"list-style-type"},{"name":"margin-bottom"},{"name":"margin-left"},{"name":"margin-right"},{"name":"margin-top"},{"name":"marker-end"},{"name":"marker-mid"},{"name":"marker-start"},{"name":"mask"},{"name":"mask-source-type"},{"name":"mask-type"},{"name":"max-height"},{"name":"max-width"},{"name":"min-height"},{"name":"min-width"},{"name":"mix-blend-mode"},{"name":"motion-offset"},{"name":"motion-path"},{"name":"motion-rotation"},{"name":"object-fit"},{"name":"object-position"},{"name":"opacity"},{"name":"order"},{"name":"orphans"},{"name":"outline-color"},{"name":"outline-offset"},{"name":"outline-style"},{"name":"outline-width"},{"name":"overflow-wrap"},{"name":"overflow-x"},{"name":"overflow-y"},{"name":"padding-bottom"},{"name":"padding-left"},{"name":"padding-right"},{"name":"padding-top"},{"name":"paint-order"},{"name":"perspective"},{"name":"perspective-origin"},{"name":"pointer-events"},{"name":"position"},{"name":"quotes"},{"name":"resize"},{"name":"right"},{"name":"r"},{"name":"rx"},{"name":"ry"},{"name":"scroll-behavior"},{"name":"scroll-snap-type"},{"name":"scroll-snap-points-x"},{"name":"scroll-snap-points-y"},{"name":"scroll-snap-destination"},{"name":"scroll-snap-coordinate"},{"name":"shape-image-threshold"},{"name":"shape-margin"},{"name":"shape-outside"},{"name":"shape-rendering"},{"name":"size"},{"name":"snap-height"},{"name":"speak"},{"name":"stop-color"},{"name":"stop-opacity"},{"name":"stroke"},{"name":"stroke-dasharray"},{"name":"stroke-dashoffset"},{"name":"stroke-linecap"},{"name":"stroke-linejoin"},{"name":"stroke-miterlimit"},{"name":"stroke-opacity"},{"name":"stroke-width"},{"name":"table-layout"},{"name":"tab-size"},{"name":"text-align"},{"name":"text-align-last"},{"name":"text-anchor"},{"name":"text-combine-upright"},{"longhands":["text-decoration-line","text-decoration-style","text-decoration-color"],"name":"text-decoration"},{"name":"text-decoration-color"},{"name":"text-decoration-line"},{"name":"text-decoration-style"},{"name":"text-indent"},{"name":"text-justify"},{"name":"text-overflow"},{"name":"text-shadow"},{"name":"text-transform"},{"name":"text-underline-position"},{"name":"top"},{"name":"touch-action"},{"name":"transform"},{"name":"transform-origin"},{"name":"transform-style"},{"name":"translate"},{"name":"rotate"},{"name":"scale"},{"name":"transition-delay"},{"name":"transition-duration"},{"name":"transition-property"},{"name":"transition-timing-function"},{"name":"unicode-bidi"},{"name":"vector-effect"},{"name":"vertical-align"},{"name":"visibility"},{"name":"x"},{"name":"y"},{"name":"-webkit-appearance"},{"name":"-webkit-app-region"},{"name":"-webkit-background-clip"},{"name":"-webkit-background-origin"},{"name":"-webkit-border-horizontal-spacing"},{"name":"-webkit-border-image"},{"name":"-webkit-border-vertical-spacing"},{"name":"-webkit-box-align"},{"name":"-webkit-box-decoration-break"},{"name":"-webkit-box-direction"},{"name":"-webkit-box-flex"},{"name":"-webkit-box-flex-group"},{"name":"-webkit-box-lines"},{"name":"-webkit-box-ordinal-group"},{"name":"-webkit-box-orient"},{"name":"-webkit-box-pack"},{"name":"-webkit-box-reflect"},{"name":"-webkit-clip-path"},{"name":"column-count"},{"name":"column-gap"},{"name":"column-rule-color"},{"name":"column-rule-style"},{"name":"column-rule-width"},{"name":"column-span"},{"name":"column-width"},{"name":"-webkit-filter"},{"name":"-webkit-highlight"},{"name":"-webkit-hyphenate-character"},{"name":"-webkit-line-break"},{"name":"-webkit-line-clamp"},{"name":"-webkit-margin-after-collapse"},{"name":"-webkit-margin-before-collapse"},{"name":"-webkit-margin-bottom-collapse"},{"name":"-webkit-margin-top-collapse"},{"name":"-webkit-mask-box-image-outset"},{"name":"-webkit-mask-box-image-repeat"},{"name":"-webkit-mask-box-image-slice"},{"name":"-webkit-mask-box-image-source"},{"name":"-webkit-mask-box-image-width"},{"name":"-webkit-mask-clip"},{"name":"-webkit-mask-composite"},{"name":"-webkit-mask-image"},{"name":"-webkit-mask-origin"},{"name":"-webkit-mask-position-x"},{"name":"-webkit-mask-position-y"},{"name":"-webkit-mask-repeat-x"},{"name":"-webkit-mask-repeat-y"},{"name":"-webkit-mask-size"},{"name":"-webkit-perspective-origin-x"},{"name":"-webkit-perspective-origin-y"},{"name":"-webkit-print-color-adjust"},{"name":"-webkit-rtl-ordering"},{"name":"-webkit-ruby-position"},{"name":"-webkit-tap-highlight-color"},{"name":"-webkit-text-combine"},{"name":"-webkit-text-emphasis-color"},{"name":"-webkit-text-emphasis-position"},{"name":"-webkit-text-emphasis-style"},{"name":"-webkit-text-fill-color"},{"name":"-webkit-text-security"},{"name":"-webkit-text-stroke-color"},{"name":"-webkit-text-stroke-width"},{"name":"-webkit-transform-origin-x"},{"name":"-webkit-transform-origin-y"},{"name":"-webkit-transform-origin-z"},{"name":"-webkit-user-drag"},{"name":"-webkit-user-modify"},{"name":"-webkit-user-select"},{"name":"white-space"},{"name":"widows"},{"name":"width"},{"name":"will-change"},{"name":"word-break"},{"name":"word-spacing"},{"name":"word-wrap"},{"name":"z-index"},{"name":"-webkit-border-end-color"},{"name":"-webkit-border-end-style"},{"name":"-webkit-border-end-width"},{"name":"-webkit-border-start-color"},{"name":"-webkit-border-start-style"},{"name":"-webkit-border-start-width"},{"name":"-webkit-border-before-color"},{"name":"-webkit-border-before-style"},{"name":"-webkit-border-before-width"},{"name":"-webkit-border-after-color"},{"name":"-webkit-border-after-style"},{"name":"-webkit-border-after-width"},{"name":"-webkit-margin-end"},{"name":"-webkit-margin-start"},{"name":"-webkit-margin-before"},{"name":"-webkit-margin-after"},{"name":"-webkit-padding-end"},{"name":"-webkit-padding-start"},{"name":"-webkit-padding-before"},{"name":"-webkit-padding-after"},{"name":"-webkit-logical-width"},{"name":"-webkit-logical-height"},{"name":"-webkit-min-logical-width"},{"name":"-webkit-min-logical-height"},{"name":"-webkit-max-logical-width"},{"name":"-webkit-max-logical-height"},{"name":"all"},{"name":"font-display"},{"name":"max-zoom"},{"name":"min-zoom"},{"name":"orientation"},{"name":"page"},{"name":"src"},{"name":"unicode-range"},{"name":"user-zoom"},{"name":"-webkit-font-size-delta"},{"name":"-webkit-text-decorations-in-effect"},{"longhands":["animation-name","animation-duration","animation-timing-function","animation-delay","animation-iteration-count","animation-direction","animation-fill-mode","animation-play-state"],"name":"animation"},{"longhands":["background-image","background-position-x","background-position-y","background-size","background-repeat-x","background-repeat-y","background-attachment","background-origin","background-clip","background-color"],"name":"background"},{"longhands":["background-position-x","background-position-y"],"name":"background-position"},{"longhands":["background-repeat-x","background-repeat-y"],"name":"background-repeat"},{"longhands":["border-top-color","border-top-style","border-top-width","border-right-color","border-right-style","border-right-width","border-bottom-color","border-bottom-style","border-bottom-width","border-left-color","border-left-style","border-left-width","border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"],"name":"border"},{"longhands":["border-bottom-width","border-bottom-style","border-bottom-color"],"name":"border-bottom"},{"longhands":["border-top-color","border-right-color","border-bottom-color","border-left-color"],"name":"border-color"},{"longhands":["border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"],"name":"border-image"},{"longhands":["border-left-width","border-left-style","border-left-color"],"name":"border-left"},{"longhands":["border-top-left-radius","border-top-right-radius","border-bottom-right-radius","border-bottom-left-radius"],"name":"border-radius"},{"longhands":["border-right-width","border-right-style","border-right-color"],"name":"border-right"},{"longhands":["-webkit-border-horizontal-spacing","-webkit-border-vertical-spacing"],"name":"border-spacing"},{"longhands":["border-top-style","border-right-style","border-bottom-style","border-left-style"],"name":"border-style"},{"longhands":["border-top-width","border-top-style","border-top-color"],"name":"border-top"},{"longhands":["border-top-width","border-right-width","border-bottom-width","border-left-width"],"name":"border-width"},{"longhands":["flex-grow","flex-shrink","flex-basis"],"name":"flex"},{"longhands":["flex-direction","flex-wrap"],"name":"flex-flow"},{"longhands":["font-style","font-variant-ligatures","font-variant-caps","font-variant-numeric","font-weight","font-stretch","font-size","line-height","font-family"],"name":"font"},{"longhands":["font-variant-ligatures","font-variant-caps","font-variant-numeric"],"name":"font-variant"},{"longhands":["grid-template-rows","grid-template-columns","grid-template-areas","grid-auto-flow","grid-auto-rows","grid-auto-columns","grid-column-gap","grid-row-gap"],"name":"grid"},{"longhands":["grid-row-start","grid-column-start","grid-row-end","grid-column-end"],"name":"grid-area"},{"longhands":["grid-column-start","grid-column-end"],"name":"grid-column"},{"longhands":["grid-row-gap","grid-column-gap"],"name":"grid-gap"},{"longhands":["grid-row-start","grid-row-end"],"name":"grid-row"},{"longhands":["grid-template-rows","grid-template-columns","grid-template-areas"],"name":"grid-template"},{"longhands":["list-style-type","list-style-position","list-style-image"],"name":"list-style"},{"longhands":["margin-top","margin-right","margin-bottom","margin-left"],"name":"margin"},{"longhands":["marker-start","marker-mid","marker-end"],"name":"marker"},{"longhands":["motion-path","motion-offset","motion-rotation"],"name":"motion"},{"longhands":["outline-color","outline-style","outline-width"],"name":"outline"},{"longhands":["overflow-x","overflow-y"],"name":"overflow"},{"longhands":["padding-top","padding-right","padding-bottom","padding-left"],"name":"padding"},{"longhands":["break-after"],"name":"page-break-after"},{"longhands":["break-before"],"name":"page-break-before"},{"longhands":["break-inside"],"name":"page-break-inside"},{"longhands":["transition-property","transition-duration","transition-timing-function","transition-delay"],"name":"transition"},{"longhands":["-webkit-border-after-width","-webkit-border-after-style","-webkit-border-after-color"],"name":"-webkit-border-after"},{"longhands":["-webkit-border-before-width","-webkit-border-before-style","-webkit-border-before-color"],"name":"-webkit-border-before"},{"longhands":["-webkit-border-end-width","-webkit-border-end-style","-webkit-border-end-color"],"name":"-webkit-border-end"},{"longhands":["-webkit-border-start-width","-webkit-border-start-style","-webkit-border-start-color"],"name":"-webkit-border-start"},{"longhands":["break-after"],"name":"-webkit-column-break-after"},{"longhands":["break-before"],"name":"-webkit-column-break-before"},{"longhands":["break-inside"],"name":"-webkit-column-break-inside"},{"longhands":["column-rule-width","column-rule-style","column-rule-color"],"name":"column-rule"},{"longhands":["column-width","column-count"],"name":"columns"},{"longhands":["-webkit-margin-before-collapse","-webkit-margin-after-collapse"],"name":"-webkit-margin-collapse"},{"longhands":["-webkit-mask-image","-webkit-mask-position-x","-webkit-mask-position-y","-webkit-mask-size","-webkit-mask-repeat-x","-webkit-mask-repeat-y","-webkit-mask-origin","-webkit-mask-clip"],"name":"-webkit-mask"},{"longhands":["-webkit-mask-box-image-source","-webkit-mask-box-image-slice","-webkit-mask-box-image-width","-webkit-mask-box-image-outset","-webkit-mask-box-image-repeat"],"name":"-webkit-mask-box-image"},{"longhands":["-webkit-mask-position-x","-webkit-mask-position-y"],"name":"-webkit-mask-position"},{"longhands":["-webkit-mask-repeat-x","-webkit-mask-repeat-y"],"name":"-webkit-mask-repeat"},{"longhands":["-webkit-text-emphasis-style","-webkit-text-emphasis-color"],"name":"-webkit-text-emphasis"},{"longhands":["-webkit-text-stroke-width","-webkit-text-stroke-color"],"name":"-webkit-text-stroke"}]);;WebInspector.FileManager=function()
{this._savedURLsSetting=WebInspector.settings.createLocalSetting("savedURLs",{});this._saveCallbacks={};InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SavedURL,this._savedURL,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.CanceledSaveURL,this._canceledSaveURL,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.AppendedToURL,this._appendedToURL,this);}
WebInspector.FileManager.EventTypes={SavedURL:"SavedURL",AppendedToURL:"AppendedToURL"}
WebInspector.FileManager.prototype={save:function(url,content,forceSaveAs,callback)
{var savedURLs=this._savedURLsSetting.get();delete savedURLs[url];this._savedURLsSetting.set(savedURLs);this._saveCallbacks[url]=callback||null;InspectorFrontendHost.save(url,content,forceSaveAs);},_savedURL:function(event)
{var url=(event.data);var savedURLs=this._savedURLsSetting.get();savedURLs[url]=true;this._savedURLsSetting.set(savedURLs);this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL,url);this._invokeSaveCallback(url,true);},_invokeSaveCallback:function(url,accepted)
{var callback=this._saveCallbacks[url];delete this._saveCallbacks[url];if(callback)
callback(accepted);},_canceledSaveURL:function(event)
{var url=(event.data);this._invokeSaveCallback(url,false);},isURLSaved:function(url)
{var savedURLs=this._savedURLsSetting.get();return savedURLs[url];},append:function(url,content)
{InspectorFrontendHost.append(url,content);},close:function(url)
{},_appendedToURL:function(event)
{var url=(event.data);this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL,url);},__proto__:WebInspector.Object.prototype}
WebInspector.fileManager=null;;WebInspector.FileSystemMapping=function()
{WebInspector.Object.call(this);this._fileSystemMappingSetting=WebInspector.settings.createLocalSetting("fileSystemMapping",{});this._fileSystemMappings={};this._loadFromSettings();}
WebInspector.FileSystemMapping.Events={FileMappingAdded:"FileMappingAdded",FileMappingRemoved:"FileMappingRemoved"}
WebInspector.FileSystemMapping.prototype={_loadFromSettings:function()
{var savedMapping=this._fileSystemMappingSetting.get();this._fileSystemMappings={};for(var fileSystemPath in savedMapping){var savedFileSystemMappings=savedMapping[fileSystemPath];fileSystemPath=WebInspector.IsolatedFileSystemManager.normalizePath(fileSystemPath);this._fileSystemMappings[fileSystemPath]=[];var fileSystemMappings=this._fileSystemMappings[fileSystemPath];for(var i=0;i<savedFileSystemMappings.length;++i){var savedEntry=savedFileSystemMappings[i];var entry=new WebInspector.FileSystemMapping.Entry(fileSystemPath,savedEntry.urlPrefix,savedEntry.pathPrefix,true);fileSystemMappings.push(entry);}}
this._rebuildIndexes();},_saveToSettings:function()
{var setting={};for(var fileSystemPath in this._fileSystemMappings){setting[fileSystemPath]=[];var entries=this._fileSystemMappings[fileSystemPath];for(var entry of entries){if(entry.configurable)
setting[fileSystemPath].push(entry);}}
this._fileSystemMappingSetting.set(setting);},_rebuildIndexes:function()
{this._mappingForURLPrefix={};this._urlPrefixes=[];for(var fileSystemPath in this._fileSystemMappings){var fileSystemMapping=this._fileSystemMappings[fileSystemPath];for(var i=0;i<fileSystemMapping.length;++i){var entry=fileSystemMapping[i];if(this._mappingForURLPrefix[entry.urlPrefix]&&!entry.configurable)
continue;this._mappingForURLPrefix[entry.urlPrefix]=entry;if(this._urlPrefixes.indexOf(entry.urlPrefix)===-1)
this._urlPrefixes.push(entry.urlPrefix);}}
this._urlPrefixes.sort();},addFileSystem:function(fileSystemPath)
{if(this._fileSystemMappings[fileSystemPath])
return;this._fileSystemMappings[fileSystemPath]=[];this._saveToSettings();},removeFileSystem:function(fileSystemPath)
{if(!this._fileSystemMappings[fileSystemPath])
return;delete this._fileSystemMappings[fileSystemPath];this._rebuildIndexes();this._saveToSettings();},addFileMapping:function(fileSystemPath,urlPrefix,pathPrefix)
{if(!urlPrefix.endsWith("/"))
urlPrefix+="/";if(!pathPrefix.endsWith("/"))
pathPrefix+="/";if(!pathPrefix.startsWith("/"))
pathPrefix="/"+pathPrefix;this._innerAddFileMapping(fileSystemPath,urlPrefix,pathPrefix,true);this._saveToSettings();},addNonConfigurableFileMapping:function(fileSystemPath,urlPrefix,pathPrefix)
{this._innerAddFileMapping(fileSystemPath,urlPrefix,pathPrefix,false);},_innerAddFileMapping:function(fileSystemPath,urlPrefix,pathPrefix,configurable)
{var entry=new WebInspector.FileSystemMapping.Entry(fileSystemPath,urlPrefix,pathPrefix,configurable);this._fileSystemMappings[fileSystemPath].push(entry);this._rebuildIndexes();this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingAdded,entry);},removeFileMapping:function(fileSystemPath,urlPrefix,pathPrefix)
{var entry=this._configurableMappingEntryForPathPrefix(fileSystemPath,pathPrefix);if(!entry)
return;this._fileSystemMappings[fileSystemPath].remove(entry);this._rebuildIndexes();this._saveToSettings();this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingRemoved,entry);},_mappingEntryForURL:function(url)
{for(var i=this._urlPrefixes.length-1;i>=0;--i){var urlPrefix=this._urlPrefixes[i];if(url.startsWith(urlPrefix))
return this._mappingForURLPrefix[urlPrefix];}
return null;},_mappingEntryForPath:function(fileSystemPath,filePath)
{var entries=this._fileSystemMappings[fileSystemPath];if(!entries)
return null;var entry=null;for(var i=0;i<entries.length;++i){var pathPrefix=entries[i].pathPrefix;if(entry&&entry.configurable&&!entries[i].configurable)
continue;if(entry&&entry.pathPrefix.length>pathPrefix.length)
continue;if(filePath.startsWith(pathPrefix))
entry=entries[i];}
return entry;},_configurableMappingEntryForPathPrefix:function(fileSystemPath,pathPrefix)
{var entries=this._fileSystemMappings[fileSystemPath];for(var i=0;i<entries.length;++i){if(entries[i].configurable&&pathPrefix===entries[i].pathPrefix)
return entries[i];}
return null;},mappingEntries:function(fileSystemPath)
{return this._fileSystemMappings[fileSystemPath].slice();},hasMappingForNetworkURL:function(url)
{return!!this._mappingEntryForURL(url);},fileForURL:function(url)
{var entry=this._mappingEntryForURL(url);if(!entry)
return null;var file={};file.fileSystemPath=entry.fileSystemPath;file.fileURL=entry.fileSystemPath+entry.pathPrefix+url.substr(entry.urlPrefix.length);return file;},networkURLForFileSystemURL:function(fileSystemPath,filePath)
{var relativePath=filePath.substring(fileSystemPath.length);var entry=this._mappingEntryForPath(fileSystemPath,relativePath);if(!entry)
return"";return entry.urlPrefix+relativePath.substring(entry.pathPrefix.length);},removeMappingForURL:function(url)
{var entry=this._mappingEntryForURL(url);if(!entry||!entry.configurable)
return;this._fileSystemMappings[entry.fileSystemPath].remove(entry);this._saveToSettings();},addMappingForResource:function(url,fileSystemPath,filePath)
{var commonPathSuffixLength=0;for(var i=0;i<filePath.length;++i){var filePathCharacter=filePath[filePath.length-1-i];var urlCharacter=url[url.length-1-i];if(filePathCharacter!==urlCharacter)
break;if(filePathCharacter==="/")
commonPathSuffixLength=i;}
var from=fileSystemPath.length;var to=filePath.length-commonPathSuffixLength;var pathPrefix=filePath.substring(from,to);var urlPrefix=url.substr(0,url.length-commonPathSuffixLength);if(to>=from)
this.addFileMapping(fileSystemPath,urlPrefix,pathPrefix);else
this.addFileMapping(fileSystemPath,urlPrefix+pathPrefix,"/");},resetForTesting:function()
{this._fileSystemMappings={};},__proto__:WebInspector.Object.prototype}
WebInspector.FileSystemMapping.Entry=function(fileSystemPath,urlPrefix,pathPrefix,configurable)
{this.fileSystemPath=fileSystemPath;this.urlPrefix=urlPrefix;this.pathPrefix=pathPrefix;this.configurable=configurable;}
WebInspector.fileSystemMapping;;WebInspector.IsolatedFileSystem=function(manager,path,embedderPath,domFileSystem)
{this._manager=manager;this._path=path;this._embedderPath=embedderPath;this._domFileSystem=domFileSystem;this._excludedFoldersSetting=WebInspector.settings.createLocalSetting("workspaceExcludedFolders",{});this._excludedFolders=new Set(this._excludedFoldersSetting.get()[path]||[]);this._nonConfigurableExcludedFolders=new Set();}
WebInspector.IsolatedFileSystem.ImageExtensions=new Set(["jpeg","jpg","svg","gif","webp","png","ico","tiff","tif","bmp"]);WebInspector.IsolatedFileSystem.create=function(manager,path,embedderPath,name,rootURL)
{return new Promise(promiseBody);function promiseBody(resolve,reject)
{var domFileSystem=InspectorFrontendHost.isolatedFileSystem(name,rootURL);if(!domFileSystem){resolve(null);return;}
var fileSystem=new WebInspector.IsolatedFileSystem(manager,path,embedderPath,domFileSystem);fileSystem.requestFileContent(".devtools",onConfigAvailable);function onConfigAvailable(projectText)
{if(projectText){try{var projectObject=JSON.parse(projectText);fileSystem._initializeProject(typeof projectObject==="object"?(projectObject):null);}catch(e){WebInspector.console.error("Invalid project file: "+projectText);}}
resolve(fileSystem);}}}
WebInspector.IsolatedFileSystem.errorMessage=function(error)
{return WebInspector.UIString("File system error: %s",error.message);}
WebInspector.IsolatedFileSystem.prototype={path:function()
{return this._path;},embedderPath:function()
{return this._embedderPath;},_initializeProject:function(projectObject)
{this._projectObject=projectObject;var projectExcludes=this.projectProperty("excludes");if(Array.isArray(projectExcludes)){for(var folder of(projectExcludes)){if(typeof folder==="string")
this._nonConfigurableExcludedFolders.add(folder);}}},projectProperty:function(key)
{return this._projectObject?this._projectObject[key]:null;},requestFilesRecursive:function(path,fileCallback,finishedCallback)
{var pendingRequests=1;this._requestEntries(path,innerCallback.bind(this));function innerCallback(entries)
{for(var i=0;i<entries.length;++i){var entry=entries[i];if(!entry.isDirectory){if(this._isFileExcluded(entry.fullPath))
continue;fileCallback(entry.fullPath.substr(1));}else{if(this._isFileExcluded(entry.fullPath+"/"))
continue;++pendingRequests;this._requestEntries(entry.fullPath,innerCallback.bind(this));}}
if(finishedCallback&&(--pendingRequests===0))
finishedCallback();}},createFile:function(path,name,callback)
{var newFileIndex=1;if(!name)
name="NewFile";var nameCandidate;this._domFileSystem.root.getDirectory(path,null,dirEntryLoaded.bind(this),errorHandler.bind(this));function dirEntryLoaded(dirEntry)
{var nameCandidate=name;if(newFileIndex>1)
nameCandidate+=newFileIndex;++newFileIndex;dirEntry.getFile(nameCandidate,{create:true,exclusive:true},fileCreated,fileCreationError.bind(this));function fileCreated(entry)
{callback(entry.fullPath.substr(1));}
function fileCreationError(error)
{if(error.code===FileError.INVALID_MODIFICATION_ERR){dirEntryLoaded.call(this,dirEntry);return;}
var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when testing if file exists '"+(this._path+"/"+path+"/"+nameCandidate)+"'");callback(null);}}
function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);var filePath=this._path+"/"+path;if(nameCandidate)
filePath+="/"+nameCandidate;console.error(errorMessage+" when getting content for file '"+(filePath)+"'");callback(null);}},deleteFile:function(path)
{this._domFileSystem.root.getFile(path,null,fileEntryLoaded.bind(this),errorHandler.bind(this));function fileEntryLoaded(fileEntry)
{fileEntry.remove(fileEntryRemoved,errorHandler.bind(this));}
function fileEntryRemoved()
{}
function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when deleting file '"+(this._path+"/"+path)+"'");}},requestFileContent:function(path,callback)
{this._domFileSystem.root.getFile(path,null,fileEntryLoaded.bind(this),errorHandler.bind(this));function fileEntryLoaded(entry)
{entry.file(fileLoaded,errorHandler.bind(this));}
function fileLoaded(file)
{var reader=new FileReader();reader.onloadend=readerLoadEnd;if(WebInspector.IsolatedFileSystem.ImageExtensions.has(WebInspector.ParsedURL.extractExtension(path)))
reader.readAsDataURL(file);else
reader.readAsText(file);}
function readerLoadEnd()
{var string=null;try{string=(this.result);}catch(e){console.error("Can't read file: "+path+": "+e);}
callback(string);}
function errorHandler(error)
{if(error.code===FileError.NOT_FOUND_ERR){callback(null);return;}
var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when getting content for file '"+(this._path+"/"+path)+"'");callback(null);}},setFileContent:function(path,content,callback)
{WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.FileSavedInWorkspace);this._domFileSystem.root.getFile(path,{create:true},fileEntryLoaded.bind(this),errorHandler.bind(this));function fileEntryLoaded(entry)
{entry.createWriter(fileWriterCreated.bind(this),errorHandler.bind(this));}
function fileWriterCreated(fileWriter)
{fileWriter.onerror=errorHandler.bind(this);fileWriter.onwriteend=fileWritten;var blob=new Blob([content],{type:"text/plain"});fileWriter.write(blob);function fileWritten()
{fileWriter.onwriteend=callback;fileWriter.truncate(blob.size);}}
function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when setting content for file '"+(this._path+"/"+path)+"'");callback();}},renameFile:function(path,newName,callback)
{newName=newName?newName.trim():newName;if(!newName||newName.indexOf("/")!==-1){callback(false);return;}
var fileEntry;var dirEntry;this._domFileSystem.root.getFile(path,null,fileEntryLoaded.bind(this),errorHandler.bind(this));function fileEntryLoaded(entry)
{if(entry.name===newName){callback(false);return;}
fileEntry=entry;fileEntry.getParent(dirEntryLoaded.bind(this),errorHandler.bind(this));}
function dirEntryLoaded(entry)
{dirEntry=entry;dirEntry.getFile(newName,null,newFileEntryLoaded,newFileEntryLoadErrorHandler.bind(this));}
function newFileEntryLoaded(entry)
{callback(false);}
function newFileEntryLoadErrorHandler(error)
{if(error.code!==FileError.NOT_FOUND_ERR){callback(false);return;}
fileEntry.moveTo(dirEntry,newName,fileRenamed,errorHandler.bind(this));}
function fileRenamed(entry)
{callback(true,entry.name);}
function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when renaming file '"+(this._path+"/"+path)+"' to '"+newName+"'");callback(false);}},_readDirectory:function(dirEntry,callback)
{var dirReader=dirEntry.createReader();var entries=[];function innerCallback(results)
{if(!results.length){callback(entries.sort());}else{entries=entries.concat(toArray(results));dirReader.readEntries(innerCallback,errorHandler);}}
function toArray(list)
{return Array.prototype.slice.call(list||[],0);}
dirReader.readEntries(innerCallback,errorHandler);function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when reading directory '"+dirEntry.fullPath+"'");callback([]);}},_requestEntries:function(path,callback)
{this._domFileSystem.root.getDirectory(path,null,innerCallback.bind(this),errorHandler);function innerCallback(dirEntry)
{this._readDirectory(dirEntry,callback);}
function errorHandler(error)
{var errorMessage=WebInspector.IsolatedFileSystem.errorMessage(error);console.error(errorMessage+" when requesting entry '"+path+"'");callback([]);}},_saveExcludedFolders:function()
{var settingValue=this._excludedFoldersSetting.get();settingValue[this._path]=Array.from(this._excludedFolders.values());this._excludedFoldersSetting.set(settingValue);},addExcludedFolder:function(path)
{this._excludedFolders.add(path);this._saveExcludedFolders();this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderAdded,path);},removeExcludedFolder:function(path)
{this._excludedFolders.delete(path);this._saveExcludedFolders();this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderRemoved,path);},fileSystemRemoved:function()
{var settingValue=this._excludedFoldersSetting.get();delete settingValue[this._path];this._excludedFoldersSetting.set(settingValue);},_isFileExcluded:function(folderPath)
{if(this._nonConfigurableExcludedFolders.has(folderPath)||this._excludedFolders.has(folderPath))
return true;var regex=this._manager.workspaceFolderExcludePatternSetting().asRegExp();return!!(regex&®ex.test(folderPath));},excludedFolders:function()
{return this._excludedFolders;},nonConfigurableExcludedFolders:function()
{return this._nonConfigurableExcludedFolders;},searchInPath:function(query,progress,callback)
{var requestId=this._manager.registerCallback(innerCallback);InspectorFrontendHost.searchInPath(requestId,this._embedderPath,query);function innerCallback(files)
{files=files.map(embedderPath=>WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath));progress.worked(1);callback(files);}},indexContent:function(progress)
{progress.setTotalWork(1);var requestId=this._manager.registerProgress(progress);InspectorFrontendHost.indexPath(requestId,this._embedderPath);}};WebInspector.IsolatedFileSystemManager=function()
{this._fileSystems={};this._callbacks={};this._progresses={};InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemsLoaded,this._onFileSystemsLoaded,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemRemoved,this._onFileSystemRemoved,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemAdded,this._onFileSystemAdded,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FileSystemFilesChanged,this._onFileSystemFilesChanged,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated,this._onIndexingTotalWorkCalculated,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingWorked,this._onIndexingWorked,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.IndexingDone,this._onIndexingDone,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SearchCompleted,this._onSearchCompleted,this);this._initExcludePatterSetting();}
WebInspector.IsolatedFileSystemManager.FileSystem;WebInspector.IsolatedFileSystemManager.Events={FileSystemAdded:"FileSystemAdded",FileSystemRemoved:"FileSystemRemoved",FileSystemsLoaded:"FileSystemsLoaded",FileSystemFilesChanged:"FileSystemFilesChanged",ExcludedFolderAdded:"ExcludedFolderAdded",ExcludedFolderRemoved:"ExcludedFolderRemoved"}
WebInspector.IsolatedFileSystemManager._lastRequestId=0;WebInspector.IsolatedFileSystemManager.normalizePath=function(fileSystemPath)
{fileSystemPath=fileSystemPath.replace(/\\/g,"/");if(!fileSystemPath.startsWith("file://")){if(fileSystemPath.startsWith("/"))
fileSystemPath="file://"+fileSystemPath;else
fileSystemPath="file:///"+fileSystemPath;}
return fileSystemPath;}
WebInspector.IsolatedFileSystemManager.prototype={initialize:function(callback)
{this._initializeCallback=callback;InspectorFrontendHost.requestFileSystems();},addFileSystem:function()
{InspectorFrontendHost.addFileSystem("");},removeFileSystem:function(fileSystem)
{InspectorFrontendHost.removeFileSystem(fileSystem.embedderPath());},_onFileSystemsLoaded:function(event)
{var fileSystems=(event.data);var promises=[];for(var i=0;i<fileSystems.length;++i)
promises.push(this._innerAddFileSystem(fileSystems[i]));Promise.all(promises).then(fireFileSystemsLoaded.bind(this));function fireFileSystemsLoaded()
{this._initializeCallback();delete this._initializeCallback;this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemsLoaded);}},fileSystemsLoaded:function()
{return!this._initializeCallback;},_innerAddFileSystem:function(fileSystem)
{var embedderPath=fileSystem.fileSystemPath;var fileSystemPath=WebInspector.IsolatedFileSystemManager.normalizePath(fileSystem.fileSystemPath);var promise=WebInspector.IsolatedFileSystem.create(this,fileSystemPath,embedderPath,fileSystem.fileSystemName,fileSystem.rootURL);return promise.then(storeFileSystem.bind(this));function storeFileSystem(fileSystem)
{if(!fileSystem)
return;this._fileSystems[fileSystemPath]=fileSystem;this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,fileSystem);}},_onFileSystemAdded:function(event)
{var errorMessage=(event.data["errorMessage"]);var fileSystem=(event.data["fileSystem"]);if(errorMessage)
WebInspector.console.error(errorMessage);else if(fileSystem)
this._innerAddFileSystem(fileSystem);},_onFileSystemRemoved:function(event)
{this._fileSystemRemoved((event.data));},_onFileSystemFilesChanged:function(event)
{var embedderPaths=(event.data);var paths=embedderPaths.map(embedderPath=>WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath));this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemFilesChanged,paths);},_fileSystemRemoved:function(embedderPath)
{var fileSystemPath=WebInspector.IsolatedFileSystemManager.normalizePath(embedderPath);var isolatedFileSystem=this._fileSystems[fileSystemPath];delete this._fileSystems[fileSystemPath];if(isolatedFileSystem){isolatedFileSystem.fileSystemRemoved();this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,isolatedFileSystem);}},fileSystemPaths:function()
{return Object.keys(this._fileSystems);},fileSystem:function(fileSystemPath)
{return this._fileSystems[fileSystemPath];},_initExcludePatterSetting:function()
{var defaultCommonExcludedFolders=["/\\.devtools","/\\.git/","/\\.sass-cache/","/\\.hg/","/\\.idea/","/\\.svn/","/\\.cache/","/\\.project/"];var defaultWinExcludedFolders=["/Thumbs.db$","/ehthumbs.db$","/Desktop.ini$","/\\$RECYCLE.BIN/"];var defaultMacExcludedFolders=["/\\.DS_Store$","/\\.Trashes$","/\\.Spotlight-V100$","/\\.AppleDouble$","/\\.LSOverride$","/Icon$","/\\._.*$"];var defaultLinuxExcludedFolders=["/.*~$"];var defaultExcludedFolders=defaultCommonExcludedFolders;if(WebInspector.isWin())
defaultExcludedFolders=defaultExcludedFolders.concat(defaultWinExcludedFolders);else if(WebInspector.isMac())
defaultExcludedFolders=defaultExcludedFolders.concat(defaultMacExcludedFolders);else
defaultExcludedFolders=defaultExcludedFolders.concat(defaultLinuxExcludedFolders);var defaultExcludedFoldersPattern=defaultExcludedFolders.join("|");this._workspaceFolderExcludePatternSetting=WebInspector.settings.createRegExpSetting("workspaceFolderExcludePattern",defaultExcludedFoldersPattern,WebInspector.isWin()?"i":"");},workspaceFolderExcludePatternSetting:function()
{return this._workspaceFolderExcludePatternSetting;},registerCallback:function(callback)
{var requestId=++WebInspector.IsolatedFileSystemManager._lastRequestId;this._callbacks[requestId]=callback;return requestId;},registerProgress:function(progress)
{var requestId=++WebInspector.IsolatedFileSystemManager._lastRequestId;this._progresses[requestId]=progress;return requestId;},_onIndexingTotalWorkCalculated:function(event)
{var requestId=(event.data["requestId"]);var totalWork=(event.data["totalWork"]);var progress=this._progresses[requestId];if(!progress)
return;progress.setTotalWork(totalWork);},_onIndexingWorked:function(event)
{var requestId=(event.data["requestId"]);var worked=(event.data["worked"]);var progress=this._progresses[requestId];if(!progress)
return;progress.worked(worked);if(progress.isCanceled()){InspectorFrontendHost.stopIndexing(requestId);this._onIndexingDone(event);}},_onIndexingDone:function(event)
{var requestId=(event.data["requestId"]);var progress=this._progresses[requestId];if(!progress)
return;progress.done();delete this._progresses[requestId];},_onSearchCompleted:function(event)
{var requestId=(event.data["requestId"]);var files=(event.data["files"]);var callback=this._callbacks[requestId];if(!callback)
return;callback.call(null,files);delete this._callbacks[requestId];},dispose:function()
{InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated,this._onIndexingTotalWorkCalculated,this);InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingWorked,this._onIndexingWorked,this);InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.IndexingDone,this._onIndexingDone,this);InspectorFrontendHost.events.removeEventListener(InspectorFrontendHostAPI.Events.SearchCompleted,this._onSearchCompleted,this);},__proto__:WebInspector.Object.prototype}
WebInspector.isolatedFileSystemManager;;WebInspector.SearchConfig=function(query,ignoreCase,isRegex)
{this._query=query;this._ignoreCase=ignoreCase;this._isRegex=isRegex;this._parse();}
WebInspector.SearchConfig.RegexQuery;WebInspector.SearchConfig.fromPlainObject=function(object)
{return new WebInspector.SearchConfig(object.query,object.ignoreCase,object.isRegex);}
WebInspector.SearchConfig.prototype={query:function()
{return this._query;},ignoreCase:function()
{return this._ignoreCase;},isRegex:function()
{return this._isRegex;},toPlainObject:function()
{return{query:this.query(),ignoreCase:this.ignoreCase(),isRegex:this.isRegex()};},_parse:function()
{var filePattern="-?f(ile)?:(([^\\\\ ]|\\\\.)+)";var quotedPattern="\"(([^\\\\\"]|\\\\.)+)\"";var unquotedWordPattern="(\\s*(?!-?f(ile)?:)[^\\\\ ]|\\\\.)+";var unquotedPattern=unquotedWordPattern+"( +"+unquotedWordPattern+")*";var pattern="("+filePattern+")|("+quotedPattern+")|("+unquotedPattern+")";var regexp=new RegExp(pattern,"g");var queryParts=this._query.match(regexp)||[];this._fileQueries=[];this._queries=[];for(var i=0;i<queryParts.length;++i){var queryPart=queryParts[i];if(!queryPart)
continue;var fileQuery=this._parseFileQuery(queryPart);if(fileQuery){this._fileQueries.push(fileQuery);this._fileRegexQueries=this._fileRegexQueries||[];this._fileRegexQueries.push({regex:new RegExp(fileQuery.text,this.ignoreCase?"i":""),isNegative:fileQuery.isNegative});continue;}
if(this._isRegex){this._queries.push(queryPart);continue;}
if(queryPart.startsWith("\"")){if(!queryPart.endsWith("\""))
continue;this._queries.push(this._parseQuotedQuery(queryPart));continue;}
this._queries.push(this._parseUnquotedQuery(queryPart));}},filePathMatchesFileQuery:function(filePath)
{if(!this._fileRegexQueries)
return true;for(var i=0;i<this._fileRegexQueries.length;++i){if(!!filePath.match(this._fileRegexQueries[i].regex)===this._fileRegexQueries[i].isNegative)
return false;}
return true;},queries:function()
{return this._queries;},_parseUnquotedQuery:function(query)
{return query.replace(/\\(.)/g,"$1");},_parseQuotedQuery:function(query)
{return query.substring(1,query.length-1).replace(/\\(.)/g,"$1");},_parseFileQuery:function(query)
{var match=query.match(/^(-)?f(ile)?:/);if(!match)
return null;var isNegative=!!match[1];query=query.substr(match[0].length);var result="";for(var i=0;i<query.length;++i){var char=query[i];if(char==="*"){result+=".*";}else if(char==="\\"){++i;var nextChar=query[i];if(nextChar===" ")
result+=" ";}else{if(String.regexSpecialCharacters().indexOf(query.charAt(i))!==-1)
result+="\\";result+=query.charAt(i);}}
return new WebInspector.SearchConfig.QueryTerm(result,isNegative);}}
WebInspector.SearchConfig.QueryTerm=function(text,isNegative)
{this.text=text;this.isNegative=isNegative;};WebInspector.UISourceCode=function(project,url,contentType)
{this._project=project;this._url=url;var pathComponents=WebInspector.ParsedURL.splitURLIntoPathComponents(url);this._origin=pathComponents[0];this._parentURL=pathComponents.slice(0,-1).join("/");this._name=pathComponents[pathComponents.length-1];this._contentType=contentType;this._requestContentCallback=null;this._requestContentPromise=null;this._lineDecorations=new Map();this.history=[];this._hasUnsavedCommittedChanges=false;this._messages=[];}
WebInspector.UISourceCode.Events={WorkingCopyChanged:"WorkingCopyChanged",WorkingCopyCommitted:"WorkingCopyCommitted",TitleChanged:"TitleChanged",SourceMappingChanged:"SourceMappingChanged",MessageAdded:"MessageAdded",MessageRemoved:"MessageRemoved",LineDecorationAdded:"LineDecorationAdded",LineDecorationRemoved:"LineDecorationRemoved"}
WebInspector.UISourceCode.prototype={name:function()
{return this._name;},url:function()
{return this._url;},parentURL:function()
{return this._parentURL;},origin:function()
{return this._origin;},fullDisplayName:function()
{var parentPath=this._parentURL.replace(/^(?:https?|file)\:\/\//,"");try{parentPath=decodeURI(parentPath);}catch(e){}
return parentPath+"/"+this.displayName(true);},displayName:function(skipTrim)
{if(!this._name)
return WebInspector.UIString("(index)");var name=this._name;try{name=decodeURI(name);}catch(e){}
return skipTrim?name:name.trimEnd(100);},isFromServiceProject:function()
{return WebInspector.Project.isServiceProject(this._project);},canRename:function()
{return this._project.canRename();},rename:function(newName,callback)
{this._project.rename(this,newName,innerCallback.bind(this));function innerCallback(success,newName,newURL,newContentType)
{if(success)
this._updateName((newName),(newURL),(newContentType));callback(success);}},remove:function()
{this._project.deleteFile(this.url());},_updateName:function(name,url,contentType)
{var oldURД=this.url();this._url=this._url.substring(0,this._url.length-this._name.length)+name;this._name=name;if(url)
this._url=url;if(contentType)
this._contentType=contentType;this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged,oldURД);},contentURL:function()
{return this.url();},contentType:function()
{return this._contentType;},project:function()
{return this._project;},requestContent:function()
{if(this._content||this._contentLoaded)
return Promise.resolve(this._content);var promise=this._requestContentPromise;if(!promise){promise=new Promise(fulfill=>this._requestContentCallback=fulfill);this._requestContentPromise=promise;this._project.requestFileContent(this,this._fireContentAvailable.bind(this));}
return promise;},_pushCheckContentUpdatedCallback:function(callback)
{if(!this._checkContentUpdatedCallbacks)
this._checkContentUpdatedCallbacks=[];this._checkContentUpdatedCallbacks.push(callback);},_terminateContentCheck:function()
{delete this._checkingContent;if(this._checkContentUpdatedCallbacks){this._checkContentUpdatedCallbacks.forEach(function(callback){callback();});delete this._checkContentUpdatedCallbacks;}},checkContentUpdated:function(forceLoad,callback)
{callback=callback||function(){};forceLoad=forceLoad||this._forceLoadOnCheckContent;if(!this.contentLoaded()&&!forceLoad){callback();return;}
if(!this._project.canSetFileContent()){callback();return;}
this._pushCheckContentUpdatedCallback(callback);if(this._checkingContent)
return;this._checkingContent=true;this._project.requestFileContent(this,contentLoaded.bind(this));function contentLoaded(updatedContent)
{if(updatedContent===null){var workingCopy=this.workingCopy();this._contentCommitted("",true,false);this.setWorkingCopy(workingCopy);this._terminateContentCheck();return;}
if(typeof this._lastAcceptedContent==="string"&&this._lastAcceptedContent===updatedContent){this._terminateContentCheck();return;}
if(this._content===updatedContent){delete this._lastAcceptedContent;this._terminateContentCheck();return;}
if(!this.isDirty()||this._workingCopy===updatedContent){this._contentCommitted(updatedContent,true,false);this._terminateContentCheck();return;}
var shouldUpdate=window.confirm(WebInspector.UIString("This file was changed externally. Would you like to reload it?"));if(shouldUpdate)
this._contentCommitted(updatedContent,true,false);else
this._lastAcceptedContent=updatedContent;this._terminateContentCheck();}},forceLoadOnCheckContent:function()
{this._forceLoadOnCheckContent=true;},requestOriginalContent:function()
{var callback;var promise=new Promise(fulfill=>callback=fulfill);this._project.requestFileContent(this,callback);return promise;},_commitContent:function(content)
{var wasPersisted=false;if(this._project.canSetFileContent()){this._project.setFileContent(this,content,function(){});wasPersisted=true;}else if(this._project.workspace().hasResourceContentTrackingExtensions()){wasPersisted=true;}else if(this._url&&WebInspector.fileManager.isURLSaved(this._url)){WebInspector.fileManager.save(this._url,content,false,function(){});WebInspector.fileManager.close(this._url);wasPersisted=true;}
this._contentCommitted(content,wasPersisted,true);},_contentCommitted:function(content,wasPersisted,committedByUser)
{delete this._lastAcceptedContent;this._content=content;this._contentLoaded=true;var lastRevision=this.history.length?this.history[this.history.length-1]:null;if(!lastRevision||lastRevision._content!==this._content){var revision=new WebInspector.Revision(this,this._content,new Date());this.history.push(revision);}
this._innerResetWorkingCopy();this._hasUnsavedCommittedChanges=!wasPersisted;this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCommitted);this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyCommitted,{uiSourceCode:this,content:content});if(committedByUser)
this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyCommittedByUser,{uiSourceCode:this,content:content});},saveAs:function()
{WebInspector.fileManager.save(this._url,this.workingCopy(),true,callback.bind(this));WebInspector.fileManager.close(this._url);function callback(accepted)
{if(accepted)
this._contentCommitted(this.workingCopy(),true,true);}},hasUnsavedCommittedChanges:function()
{return this._hasUnsavedCommittedChanges;},addRevision:function(content)
{this._commitContent(content);},revertToOriginal:function()
{function callback(content)
{if(typeof content!=="string")
return;this.addRevision(content);}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);return this.requestOriginalContent().then(callback.bind(this));},revertAndClearHistory:function(callback)
{function revert(content)
{if(typeof content!=="string")
return;this.addRevision(content);this.history=[];callback(this);}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);this.requestOriginalContent().then(revert.bind(this));},workingCopy:function()
{if(this._workingCopyGetter){this._workingCopy=this._workingCopyGetter();delete this._workingCopyGetter;}
if(this.isDirty())
return this._workingCopy;return this._content;},resetWorkingCopy:function()
{this._innerResetWorkingCopy();this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);},_innerResetWorkingCopy:function()
{delete this._workingCopy;delete this._workingCopyGetter;},setWorkingCopy:function(newWorkingCopy)
{this._workingCopy=newWorkingCopy;delete this._workingCopyGetter;this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyChanged,{uiSourceCode:this});},setWorkingCopyGetter:function(workingCopyGetter)
{this._workingCopyGetter=workingCopyGetter;this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);this._project.workspace().dispatchEventToListeners(WebInspector.Workspace.Events.WorkingCopyChanged,{uiSourceCode:this});},removeWorkingCopyGetter:function()
{if(!this._workingCopyGetter)
return;this._workingCopy=this._workingCopyGetter();delete this._workingCopyGetter;},commitWorkingCopy:function()
{if(this.isDirty())
this._commitContent(this.workingCopy());},isDirty:function()
{return typeof this._workingCopy!=="undefined"||typeof this._workingCopyGetter!=="undefined";},extension:function()
{return WebInspector.ParsedURL.extractExtension(this._name);},content:function()
{return this._content;},searchInContent:function(query,caseSensitive,isRegex,callback)
{var content=this.content();if(!content){this._project.searchInFileContent(this,query,caseSensitive,isRegex,callback);return;}
setTimeout(doSearch.bind(null,content),0);function doSearch(content)
{callback(WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex));}},_fireContentAvailable:function(content)
{this._contentLoaded=true;this._content=content;var callback=this._requestContentCallback;this._requestContentCallback=null;this._requestContentPromise=null;callback.call(null,content);},contentLoaded:function()
{return this._contentLoaded;},uiLocation:function(lineNumber,columnNumber)
{if(typeof columnNumber==="undefined")
columnNumber=0;return new WebInspector.UILocation(this,lineNumber,columnNumber);},messages:function()
{return this._messages.slice();},addLineMessage:function(level,text,lineNumber,columnNumber)
{return this.addMessage(level,text,new WebInspector.TextRange(lineNumber,columnNumber||0,lineNumber,columnNumber||0));},addMessage:function(level,text,range)
{var message=new WebInspector.UISourceCode.Message(this,level,text,range);this._messages.push(message);this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageAdded,message);return message;},removeMessage:function(message)
{if(this._messages.remove(message))
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemoved,message);},removeAllMessages:function()
{var messages=this._messages;this._messages=[];for(var message of messages)
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemoved,message);},addLineDecoration:function(lineNumber,type,data)
{var markers=this._lineDecorations.get(type);if(!markers){markers=new Map();this._lineDecorations.set(type,markers);}
var marker=new WebInspector.UISourceCode.LineMarker(lineNumber,type,data);markers.set(lineNumber,marker);this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationAdded,marker);},removeLineDecoration:function(lineNumber,type)
{var markers=this._lineDecorations.get(type);if(!markers)
return;var marker=markers.get(lineNumber);if(!marker)
return;markers.delete(lineNumber);this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationRemoved,marker);if(!markers.size)
this._lineDecorations.delete(type);},removeAllLineDecorations:function(type)
{var markers=this._lineDecorations.get(type);if(!markers)
return;this._lineDecorations.delete(type);markers.forEach(marker=>{this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorationRemoved,marker);});},lineDecorations:function(type)
{return this._lineDecorations.get(type)||null;},__proto__:WebInspector.Object.prototype}
WebInspector.UILocation=function(uiSourceCode,lineNumber,columnNumber)
{this.uiSourceCode=uiSourceCode;this.lineNumber=lineNumber;this.columnNumber=columnNumber;}
WebInspector.UILocation.prototype={linkText:function()
{var linkText=this.uiSourceCode.displayName();if(typeof this.lineNumber==="number")
linkText+=":"+(this.lineNumber+1);return linkText;},id:function()
{return this.uiSourceCode.project().id()+":"+this.uiSourceCode.url()+":"+this.lineNumber+":"+this.columnNumber;},toUIString:function()
{return this.uiSourceCode.url()+":"+(this.lineNumber+1);}}
WebInspector.Revision=function(uiSourceCode,content,timestamp)
{this._uiSourceCode=uiSourceCode;this._content=content;this._timestamp=timestamp;}
WebInspector.Revision.prototype={get uiSourceCode()
{return this._uiSourceCode;},get timestamp()
{return this._timestamp;},get content()
{return this._content||null;},revertToThis:function()
{function revert(content)
{if(content&&this._uiSourceCode._content!==content)
this._uiSourceCode.addRevision(content);}
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.RevisionApplied);return this.requestContent().then(revert.bind(this));},contentURL:function()
{return this._uiSourceCode.url();},contentType:function()
{return this._uiSourceCode.contentType();},requestContent:function()
{return Promise.resolve((this._content||""));},searchInContent:function(query,caseSensitive,isRegex,callback)
{callback([]);}}
WebInspector.UISourceCode.Message=function(uiSourceCode,level,text,range)
{this._uiSourceCode=uiSourceCode;this._level=level;this._text=text;this._range=range;}
WebInspector.UISourceCode.Message.Level={Error:"Error",Warning:"Warning"}
WebInspector.UISourceCode.Message.prototype={uiSourceCode:function()
{return this._uiSourceCode;},level:function()
{return this._level;},text:function()
{return this._text;},range:function()
{return this._range;},lineNumber:function()
{return this._range.startLine;},columnNumber:function()
{return this._range.startColumn;},isEqual:function(another)
{return this._uiSourceCode===another._uiSourceCode&&this.text()===another.text()&&this.level()===another.level()&&this.range().equal(another.range());},remove:function()
{this._uiSourceCode.removeMessage(this);}}
WebInspector.UISourceCode.LineMarker=function(line,type,data)
{this._line=line;this._type=type;this._data=data;}
WebInspector.UISourceCode.LineMarker.prototype={line:function()
{return this._line;},type:function()
{return this._type;},data:function()
{return this._data;}};WebInspector.ProjectSearchConfig=function(){}
WebInspector.ProjectSearchConfig.prototype={query:function(){},ignoreCase:function(){},isRegex:function(){},queries:function(){},filePathMatchesFileQuery:function(filePath){}}
WebInspector.Project=function(){}
WebInspector.Project.isServiceProject=function(project)
{return project.type()===WebInspector.projectTypes.Debugger||project.type()===WebInspector.projectTypes.Formatter||project.type()===WebInspector.projectTypes.Service;}
WebInspector.Project.prototype={workspace:function(){},id:function(){},type:function(){},displayName:function(){},requestFileContent:function(uiSourceCode,callback){},canSetFileContent:function(){},setFileContent:function(uiSourceCode,newContent,callback){},canRename:function(){},rename:function(uiSourceCode,newName,callback){},refresh:function(path,callback){},excludeFolder:function(path){},createFile:function(path,name,content,callback){},deleteFile:function(path){},remove:function(){},searchInFileContent:function(uiSourceCode,query,caseSensitive,isRegex,callback){},findFilesMatchingSearchRequest:function(searchConfig,filesMathingFileQuery,progress,callback){},indexContent:function(progress){},uiSourceCodeForURL:function(url){},uiSourceCodes:function(){}}
WebInspector.projectTypes={Debugger:"debugger",Formatter:"formatter",Network:"network",Snippets:"snippets",FileSystem:"filesystem",ContentScripts:"contentscripts",Service:"service"}
WebInspector.ProjectStore=function(workspace,id,type,displayName)
{this._workspace=workspace;this._id=id;this._type=type;this._displayName=displayName;this._uiSourceCodesMap=new Map();this._uiSourceCodesList=[];this._project=(this);}
WebInspector.ProjectStore.prototype={id:function()
{return this._id;},type:function()
{return this._type;},displayName:function()
{return this._displayName;},workspace:function()
{return this._workspace;},createUISourceCode:function(url,contentType)
{return new WebInspector.UISourceCode(this._project,url,contentType);},addUISourceCode:function(uiSourceCode,replace)
{var url=uiSourceCode.url();if(this.uiSourceCodeForURL(url)){if(replace)
this.removeUISourceCode(url);else
return false;}
this._uiSourceCodesMap.set(url,{uiSourceCode:uiSourceCode,index:this._uiSourceCodesList.length});this._uiSourceCodesList.push(uiSourceCode);this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeAdded,uiSourceCode);return true;},removeUISourceCode:function(url)
{var uiSourceCode=this.uiSourceCodeForURL(url);if(!uiSourceCode)
return;var entry=this._uiSourceCodesMap.get(url);var movedUISourceCode=this._uiSourceCodesList[this._uiSourceCodesList.length-1];this._uiSourceCodesList[entry.index]=movedUISourceCode;var movedEntry=this._uiSourceCodesMap.get(movedUISourceCode.url());movedEntry.index=entry.index;this._uiSourceCodesList.splice(this._uiSourceCodesList.length-1,1);this._uiSourceCodesMap.delete(url);this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeRemoved,entry.uiSourceCode);},removeProject:function()
{this._workspace._removeProject(this._project);this._uiSourceCodesMap=new Map();this._uiSourceCodesList=[];},uiSourceCodeForURL:function(url)
{var entry=this._uiSourceCodesMap.get(url);return entry?entry.uiSourceCode:null;},uiSourceCodes:function()
{return this._uiSourceCodesList;},renameUISourceCode:function(uiSourceCode,newName)
{var oldPath=uiSourceCode.url();var newPath=uiSourceCode.parentURL()?uiSourceCode.parentURL()+"/"+newName:newName;var value=(this._uiSourceCodesMap.get(oldPath));this._uiSourceCodesMap.set(newPath,value);this._uiSourceCodesMap.delete(oldPath);}}
WebInspector.Workspace=function()
{this._projects=new Map();this._hasResourceContentTrackingExtensions=false;}
WebInspector.Workspace.Events={UISourceCodeAdded:"UISourceCodeAdded",UISourceCodeRemoved:"UISourceCodeRemoved",WorkingCopyChanged:"WorkingCopyChanged",WorkingCopyCommitted:"WorkingCopyCommitted",WorkingCopyCommittedByUser:"WorkingCopyCommittedByUser",ProjectAdded:"ProjectAdded",ProjectRemoved:"ProjectRemoved"}
WebInspector.Workspace.prototype={unsavedSourceCodes:function()
{function filterUnsaved(sourceCode)
{return sourceCode.isDirty();}
var unsavedSourceCodes=[];var projects=this.projectsForType(WebInspector.projectTypes.FileSystem);for(var i=0;i<projects.length;++i)
unsavedSourceCodes=unsavedSourceCodes.concat(projects[i].uiSourceCodes().filter(filterUnsaved));return unsavedSourceCodes;},uiSourceCode:function(projectId,url)
{var project=this._projects.get(projectId);return project?project.uiSourceCodeForURL(url):null;},uiSourceCodeForURL:function(url)
{for(var project of this._projects.values()){var uiSourceCode=project.uiSourceCodeForURL(url);if(uiSourceCode)
return uiSourceCode;}
return null;},uiSourceCodesForProjectType:function(type)
{var result=[];for(var project of this._projects.values()){if(project.type()===type)
result=result.concat(project.uiSourceCodes());}
return result;},addProject:function(project)
{this._projects.set(project.id(),project);this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectAdded,project);},_removeProject:function(project)
{this._projects.delete(project.id());this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved,project);},project:function(projectId)
{return this._projects.get(projectId)||null;},projects:function()
{return Array.from(this._projects.values());},projectsForType:function(type)
{function filterByType(project)
{return project.type()===type;}
return this.projects().filter(filterByType);},uiSourceCodes:function()
{var result=[];for(var project of this._projects.values())
result=result.concat(project.uiSourceCodes());return result;},setHasResourceContentTrackingExtensions:function(hasExtensions)
{this._hasResourceContentTrackingExtensions=hasExtensions;},hasResourceContentTrackingExtensions:function()
{return this._hasResourceContentTrackingExtensions;},__proto__:WebInspector.Object.prototype}
WebInspector.workspace;;WebInspector.LiveLocation=function(){}
WebInspector.LiveLocation.prototype={update:function(){},uiLocation:function(){},dispose:function(){},isBlackboxed:function(){}}
WebInspector.LiveLocationWithPool=function(updateDelegate,locationPool)
{this._updateDelegate=updateDelegate;this._locationPool=locationPool;this._locationPool._add(this);}
WebInspector.LiveLocationWithPool.prototype={update:function()
{this._updateDelegate(this);},uiLocation:function()
{throw"Not implemented";},dispose:function()
{this._locationPool._delete(this);this._updateDelegate=null;},isBlackboxed:function()
{throw"Not implemented";}}
WebInspector.LiveLocationPool=function()
{this._locations=new Set();}
WebInspector.LiveLocationPool.prototype={_add:function(location)
{this._locations.add(location);},_delete:function(location)
{this._locations.delete(location);},disposeAll:function()
{for(var location of this._locations)
location.dispose();}};WebInspector.CompilerScriptMapping=function(debuggerModel,workspace,networkMapping,networkProject,debuggerWorkspaceBinding)
{this._target=debuggerModel.target();this._debuggerModel=debuggerModel;this._workspace=workspace;this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAddedToWorkspace,this);this._networkMapping=networkMapping;this._networkProject=networkProject;this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._sourceMapLoadingPromises=new Map();this._sourceMapForScriptId=new Map();this._scriptForSourceMap=new Map();this._sourceMapForURL=new Map();this._stubUISourceCodes=new Map();this._stubProjectID="compiler-script-project";this._stubProject=new WebInspector.ContentProviderBasedProject(this._workspace,this._stubProjectID,WebInspector.projectTypes.Service,"");debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);}
WebInspector.CompilerScriptMapping.StubProjectID="compiler-script-project";WebInspector.CompilerScriptMapping._originSymbol=Symbol("origin");WebInspector.CompilerScriptMapping.uiSourceCodeOrigin=function(uiSourceCode)
{return uiSourceCode[WebInspector.CompilerScriptMapping._originSymbol]||null;}
WebInspector.CompilerScriptMapping.prototype={mapsToSourceCode:function(rawLocation){var sourceMap=this._sourceMapForScriptId.get(rawLocation.scriptId);if(!sourceMap){return true;}
return!!sourceMap.findEntry(rawLocation.lineNumber,rawLocation.columnNumber);},rawLocationToUILocation:function(rawLocation)
{var debuggerModelLocation=(rawLocation);var stubUISourceCode=this._stubUISourceCodes.get(debuggerModelLocation.scriptId);if(stubUISourceCode)
return new WebInspector.UILocation(stubUISourceCode,rawLocation.lineNumber,rawLocation.columnNumber);var sourceMap=this._sourceMapForScriptId.get(debuggerModelLocation.scriptId);if(!sourceMap)
return null;var lineNumber=debuggerModelLocation.lineNumber;var columnNumber=debuggerModelLocation.columnNumber||0;var entry=sourceMap.findEntry(lineNumber,columnNumber);if(!entry||!entry.sourceURL)
return null;var uiSourceCode=this._networkMapping.uiSourceCodeForScriptURL((entry.sourceURL),rawLocation.script());if(!uiSourceCode)
return null;return uiSourceCode.uiLocation((entry.sourceLineNumber),(entry.sourceColumnNumber));},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{if(uiSourceCode.project().type()===WebInspector.projectTypes.Service)
return null;var networkURL=this._networkMapping.networkURL(uiSourceCode);if(!networkURL)
return null;var sourceMap=this._sourceMapForURL.get(networkURL);if(!sourceMap)
return null;var script=(this._scriptForSourceMap.get(sourceMap));console.assert(script);var entry=sourceMap.firstSourceLineMapping(networkURL,lineNumber);if(!entry)
return null;return this._debuggerModel.createRawLocation(script,entry.lineNumber,entry.columnNumber);},addScript:function(script)
{if(!script.sourceMapURL){script.addEventListener(WebInspector.Script.Events.SourceMapURLAdded,this._sourceMapURLAdded.bind(this));return;}
this._processScript(script);},sourceMapForScript:function(script)
{return this._sourceMapForScriptId.get(script.scriptId)||null;},maybeLoadSourceMap:function(script)
{if(!script.sourceMapURL)
return;if(this._sourceMapLoadingPromises.has(script.sourceMapURL))
return;if(this._sourceMapForScriptId.has(script.scriptId))
return;this._processScript(script);},_sourceMapURLAdded:function(event)
{var script=(event.target);if(!script.sourceMapURL)
return;this._processScript(script);},_processScript:function(script)
{if(WebInspector.blackboxManager.isBlackboxedURL(script.sourceURL,script.isContentScript()))
return;var stubUISourceCode=this._stubProject.addContentProvider(script.sourceURL,WebInspector.StaticContentProvider.fromString(script.sourceURL,WebInspector.resourceTypes.Script,"\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!"));this._stubUISourceCodes.set(script.scriptId,stubUISourceCode);this._debuggerWorkspaceBinding.pushSourceMapping(script,this);this._loadSourceMapForScript(script).then(this._sourceMapLoaded.bind(this,script,stubUISourceCode.url()));},_sourceMapLoaded:function(script,uiSourceCodePath,sourceMap)
{WebInspector.blackboxManager.sourceMapLoaded(script,sourceMap);this._stubUISourceCodes.delete(script.scriptId);this._stubProject.removeFile(uiSourceCodePath);if(!sourceMap){this._debuggerWorkspaceBinding.updateLocations(script);return;}
if(this._scriptForSourceMap.get(sourceMap)){this._sourceMapForScriptId.set(script.scriptId,sourceMap);this._debuggerWorkspaceBinding.updateLocations(script);return;}
this._sourceMapForScriptId.set(script.scriptId,sourceMap);this._scriptForSourceMap.set(sourceMap,script);var sourceURLs=sourceMap.sourceURLs();var missingSources=[];for(var i=0;i<sourceURLs.length;++i){var sourceURL=sourceURLs[i];if(this._sourceMapForURL.get(sourceURL))
continue;this._sourceMapForURL.set(sourceURL,sourceMap);var uiSourceCode=this._networkMapping.uiSourceCodeForScriptURL(sourceURL,script);if(!uiSourceCode&&!this._networkMapping.hasMappingForNetworkURL(sourceURL)){var contentProvider=sourceMap.sourceContentProvider(sourceURL,WebInspector.resourceTypes.SourceMapScript);uiSourceCode=this._networkProject.addFile(contentProvider,WebInspector.ResourceTreeFrame.fromScript(script),script.isContentScript());uiSourceCode[WebInspector.CompilerScriptMapping._originSymbol]=script.sourceURL;}
if(uiSourceCode){this._bindUISourceCode(uiSourceCode);}else{if(missingSources.length<3)
missingSources.push(sourceURL);else if(missingSources.peekLast()!=="\u2026")
missingSources.push("\u2026");}}
if(missingSources.length){WebInspector.console.warn(WebInspector.UIString("Source map %s points to the files missing from the workspace: [%s]",sourceMap.url(),missingSources.join(", ")));}
this._debuggerWorkspaceBinding.updateLocations(script);},isIdentity:function()
{return false;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{var networkURL=this._networkMapping.networkURL(uiSourceCode);if(!networkURL)
return true;var sourceMap=this._sourceMapForURL.get(networkURL);if(!sourceMap)
return true;return!!sourceMap.firstSourceLineMapping(networkURL,lineNumber);},_bindUISourceCode:function(uiSourceCode)
{this._debuggerWorkspaceBinding.setSourceMapping(this._target,uiSourceCode,this);},_unbindUISourceCode:function(uiSourceCode)
{this._debuggerWorkspaceBinding.setSourceMapping(this._target,uiSourceCode,null);},_uiSourceCodeAddedToWorkspace:function(event)
{var uiSourceCode=(event.data);var networkURL=this._networkMapping.networkURL(uiSourceCode);if(!networkURL||!this._sourceMapForURL.get(networkURL))
return;this._bindUISourceCode(uiSourceCode);},_loadSourceMapForScript:function(script)
{var scriptURL=WebInspector.ParsedURL.completeURL(this._target.resourceTreeModel.inspectedPageURL(),script.sourceURL);if(!scriptURL)
return Promise.resolve((null));console.assert(script.sourceMapURL);var scriptSourceMapURL=(script.sourceMapURL);var sourceMapURL=WebInspector.ParsedURL.completeURL(scriptURL,scriptSourceMapURL);if(!sourceMapURL)
return Promise.resolve((null));var loadingPromise=this._sourceMapLoadingPromises.get(sourceMapURL);if(!loadingPromise){loadingPromise=WebInspector.TextSourceMap.load(sourceMapURL,scriptURL).then(sourceMapLoaded.bind(this,sourceMapURL));this._sourceMapLoadingPromises.set(sourceMapURL,loadingPromise);}
return loadingPromise;function sourceMapLoaded(url,sourceMap)
{if(!sourceMap){this._sourceMapLoadingPromises.delete(url);return null;}
return sourceMap;}},_debuggerReset:function()
{function unbindSourceMapSources(sourceMap)
{var script=this._scriptForSourceMap.get(sourceMap);if(!script)
return;var sourceURLs=sourceMap.sourceURLs();for(var i=0;i<sourceURLs.length;++i){var uiSourceCode=this._networkMapping.uiSourceCodeForScriptURL(sourceURLs[i],script);if(uiSourceCode)
this._unbindUISourceCode(uiSourceCode);}}
this._sourceMapForURL.valuesArray().forEach(unbindSourceMapSources.bind(this));this._sourceMapLoadingPromises.clear();this._sourceMapForScriptId.clear()
this._scriptForSourceMap.clear();this._sourceMapForURL.clear();},dispose:function()
{this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAddedToWorkspace,this);}};WebInspector.ResourceScriptMapping=function(debuggerModel,workspace,networkMapping,debuggerWorkspaceBinding)
{this._target=debuggerModel.target();this._debuggerModel=debuggerModel;this._workspace=workspace;this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);this._networkMapping=networkMapping;this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._boundUISourceCodes=[];this._uiSourceCodeToScriptFile=new Map();debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);}
WebInspector.ResourceScriptMapping.prototype={rawLocationToUILocation:function(rawLocation)
{var debuggerModelLocation=(rawLocation);var script=debuggerModelLocation.script();var uiSourceCode=this._workspaceUISourceCodeForScript(script);if(!uiSourceCode)
return null;var scriptFile=this.scriptFile(uiSourceCode);if(scriptFile&&((scriptFile.hasDivergedFromVM()&&!scriptFile.isMergingToVM())||scriptFile.isDivergingFromVM()))
return null;var lineNumber=debuggerModelLocation.lineNumber-(script.isInlineScriptWithSourceURL()?script.lineOffset:0);var columnNumber=debuggerModelLocation.columnNumber||0;if(script.isInlineScriptWithSourceURL()&&!lineNumber&&columnNumber)
columnNumber-=script.columnOffset;return uiSourceCode.uiLocation(lineNumber,columnNumber);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{var scripts=this._scriptsForUISourceCode(uiSourceCode);console.assert(scripts.length);var script=scripts[0];if(script.isInlineScriptWithSourceURL())
return this._debuggerModel.createRawLocation(script,lineNumber+script.lineOffset,lineNumber?columnNumber:columnNumber+script.columnOffset);return this._debuggerModel.createRawLocation(script,lineNumber,columnNumber);},addScript:function(script)
{if(script.isAnonymousScript())
return;this._debuggerWorkspaceBinding.pushSourceMapping(script,this);var uiSourceCode=this._workspaceUISourceCodeForScript(script);if(!uiSourceCode)
return;this._bindUISourceCodeToScripts(uiSourceCode,[script]);},isIdentity:function()
{return true;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{return true;},scriptFile:function(uiSourceCode)
{return this._uiSourceCodeToScriptFile.get(uiSourceCode)||null;},_setScriptFile:function(uiSourceCode,scriptFile)
{if(scriptFile)
this._uiSourceCodeToScriptFile.set(uiSourceCode,scriptFile);else
this._uiSourceCodeToScriptFile.remove(uiSourceCode);},_uiSourceCodeAdded:function(event)
{var uiSourceCode=(event.data);if(!this._networkMapping.networkURL(uiSourceCode))
return;if(uiSourceCode.isFromServiceProject())
return;var scripts=this._scriptsForUISourceCode(uiSourceCode);if(!scripts.length)
return;this._bindUISourceCodeToScripts(uiSourceCode,scripts);},_uiSourceCodeRemoved:function(event)
{var uiSourceCode=(event.data);if(!this._networkMapping.networkURL(uiSourceCode))
return;if(uiSourceCode.isFromServiceProject())
return;this._unbindUISourceCode(uiSourceCode);},_updateLocations:function(uiSourceCode)
{var scripts=this._scriptsForUISourceCode(uiSourceCode);if(!scripts.length)
return;for(var i=0;i<scripts.length;++i)
this._debuggerWorkspaceBinding.updateLocations(scripts[i]);},_workspaceUISourceCodeForScript:function(script)
{if(script.isAnonymousScript())
return null;return this._networkMapping.uiSourceCodeForScriptURL(script.sourceURL,script);},_scriptsForUISourceCode:function(uiSourceCode)
{var target=WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);if(target&&target!==this._debuggerModel.target())
return[];if(!this._networkMapping.networkURL(uiSourceCode))
return[];return this._debuggerModel.scriptsForSourceURL(this._networkMapping.networkURL(uiSourceCode));},_bindUISourceCodeToScripts:function(uiSourceCode,scripts)
{console.assert(scripts.length);var boundScriptFile=this.scriptFile(uiSourceCode);if(boundScriptFile&&boundScriptFile._hasScripts(scripts))
return;var scriptFile=new WebInspector.ResourceScriptFile(this,uiSourceCode,scripts);this._setScriptFile(uiSourceCode,scriptFile);for(var i=0;i<scripts.length;++i)
this._debuggerWorkspaceBinding.updateLocations(scripts[i]);this._debuggerWorkspaceBinding.setSourceMapping(this._target,uiSourceCode,this);this._boundUISourceCodes.push(uiSourceCode);},_unbindUISourceCode:function(uiSourceCode)
{var scriptFile=this.scriptFile(uiSourceCode);if(scriptFile){scriptFile.dispose();this._setScriptFile(uiSourceCode,null);}
this._debuggerWorkspaceBinding.setSourceMapping(this._target,uiSourceCode,null);this._boundUISourceCodes.remove(uiSourceCode);},_debuggerReset:function()
{var sourceCodes=this._boundUISourceCodes;this._boundUISourceCodes=[];sourceCodes.forEach(this._unbindUISourceCode.bind(this));console.assert(!this._uiSourceCodeToScriptFile.size);},dispose:function()
{this._debuggerReset();this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);}}
WebInspector.ResourceScriptFile=function(resourceScriptMapping,uiSourceCode,scripts)
{console.assert(scripts.length);this._resourceScriptMapping=resourceScriptMapping;this._uiSourceCode=uiSourceCode;this._uiSourceCode.forceLoadOnCheckContent();if(this._uiSourceCode.contentType().isScript())
this._script=scripts[0];this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);}
WebInspector.ResourceScriptFile.Events={DidMergeToVM:"DidMergeToVM",DidDivergeFromVM:"DidDivergeFromVM",}
WebInspector.ResourceScriptFile.prototype={_hasScripts:function(scripts)
{return this._script&&this._script===scripts[0];},_isDiverged:function()
{if(this._uiSourceCode.isDirty())
return true;if(!this._script)
return false;if(typeof this._scriptSource==="undefined")
return false;if(!this._uiSourceCode.workingCopy().startsWith(this._scriptSource.trimRight()))
return true;var suffix=this._uiSourceCode.workingCopy().substr(this._scriptSource.length);return!!suffix.length&&!suffix.match(WebInspector.Script.sourceURLRegex);},_workingCopyChanged:function(event)
{this._update();},_workingCopyCommitted:function(event)
{if(this._uiSourceCode.project().type()===WebInspector.projectTypes.Snippets)
return;if(!this._script)
return;var debuggerModel=this._resourceScriptMapping._debuggerModel;var source=this._uiSourceCode.workingCopy();debuggerModel.setScriptSource(this._script.scriptId,source,scriptSourceWasSet.bind(this));function scriptSourceWasSet(error,errorData)
{if(!error&&!errorData)
this._scriptSource=source;this._update();if(!error&&!errorData)
return;var warningLevel=WebInspector.Console.MessageLevel.Warning;if(!errorData){WebInspector.console.addMessage(WebInspector.UIString("LiveEdit failed: %s",error),warningLevel);return;}
if(errorData){var messageText=WebInspector.UIString("LiveEdit compile failed: %s",errorData.message);this._uiSourceCode.addLineMessage(WebInspector.UISourceCode.Message.Level.Error,messageText,errorData.lineNumber-1,errorData.columnNumber+1);}else{WebInspector.console.addMessage(WebInspector.UIString("Unknown LiveEdit error: %s; %s",JSON.stringify(errorData),error),warningLevel);}}},_update:function()
{if(this._isDiverged()&&!this._hasDivergedFromVM)
this._divergeFromVM();else if(!this._isDiverged()&&this._hasDivergedFromVM)
this._mergeToVM();},_divergeFromVM:function()
{this._isDivergingFromVM=true;this._resourceScriptMapping._updateLocations(this._uiSourceCode);delete this._isDivergingFromVM;this._hasDivergedFromVM=true;this.dispatchEventToListeners(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM,this._uiSourceCode);},_mergeToVM:function()
{delete this._hasDivergedFromVM;this._isMergingToVM=true;this._resourceScriptMapping._updateLocations(this._uiSourceCode);delete this._isMergingToVM;this.dispatchEventToListeners(WebInspector.ResourceScriptFile.Events.DidMergeToVM,this._uiSourceCode);},hasDivergedFromVM:function()
{return this._hasDivergedFromVM;},isDivergingFromVM:function()
{return this._isDivergingFromVM;},isMergingToVM:function()
{return this._isMergingToVM;},checkMapping:function()
{if(!this._script||typeof this._scriptSource!=="undefined"){this._mappingCheckedForTest();return;}
this._script.requestContent().then(callback.bind(this));function callback(source)
{this._scriptSource=source;this._update();this._mappingCheckedForTest();}},_mappingCheckedForTest:function(){},target:function()
{if(!this._script)
return null;return this._script.target();},dispose:function()
{this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);},addSourceMapURL:function(sourceMapURL)
{if(!this._script)
return;this._script.addSourceMapURL(sourceMapURL);},hasSourceMapURL:function()
{return this._script&&!!this._script.sourceMapURL;},__proto__:WebInspector.Object.prototype};WebInspector.SASSSourceMapping=function(cssModel,networkMapping,networkProject)
{this._cssModel=cssModel;this._networkProject=networkProject;this._networkMapping=networkMapping;this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapAttached,this._sourceMapAttached,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapDetached,this._sourceMapDetached,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapChanged,this._sourceMapChanged,this);}
WebInspector.SASSSourceMapping.prototype={_sourceMapAttached:function(event)
{var header=(event.data);var sourceMap=this._cssModel.sourceMapForHeader(header);for(var sassURL of sourceMap.sourceURLs()){if(!this._networkMapping.hasMappingForNetworkURL(sassURL)){var contentProvider=sourceMap.sourceContentProvider(sassURL,WebInspector.resourceTypes.SourceMapStyleSheet);this._networkProject.addFile(contentProvider,WebInspector.ResourceTreeFrame.fromStyleSheet(header));}}
WebInspector.cssWorkspaceBinding.updateLocations(header);},_sourceMapDetached:function(event)
{var header=(event.data);WebInspector.cssWorkspaceBinding.updateLocations(header);},_sourceMapChanged:function(event)
{var sourceMap=(event.data.sourceMap);var newSources=(event.data.newSources);var headers=this._cssModel.headersForSourceMap(sourceMap);var handledUISourceCodes=new Set();for(var header of headers){WebInspector.cssWorkspaceBinding.updateLocations(header);for(var sourceURL of newSources.keys()){var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(sourceURL,header);if(!uiSourceCode){console.error("Failed to update source for "+sourceURL);continue;}
if(handledUISourceCodes.has(uiSourceCode))
continue;handledUISourceCodes.add(uiSourceCode);var sassText=(newSources.get(sourceURL));uiSourceCode.setWorkingCopy(sassText);}}},addHeader:function(header)
{if(!header.sourceMapURL)
return;WebInspector.cssWorkspaceBinding.pushSourceMapping(header,this);},removeHeader:function(header)
{if(!header.sourceMapURL)
return;WebInspector.cssWorkspaceBinding.updateLocations(header);},rawLocationToUILocation:function(rawLocation)
{var sourceMap=this._cssModel.sourceMapForHeader(rawLocation.header());if(!sourceMap)
return null;var entry=sourceMap.findEntry(rawLocation.lineNumber,rawLocation.columnNumber);if(!entry||!entry.sourceURL)
return null;var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(entry.sourceURL,rawLocation.header());if(!uiSourceCode)
return null;return uiSourceCode.uiLocation(entry.sourceLineNumber||0,entry.sourceColumnNumber);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{return null;},isIdentity:function()
{return false;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{return true;},target:function()
{return this._cssModel.target();}};WebInspector.StylesSourceMapping=function(cssModel,workspace,networkMapping)
{this._cssModel=cssModel;this._workspace=workspace;this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAddedToWorkspace,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);this._networkMapping=networkMapping;cssModel.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._unbindAllUISourceCodes,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged,this._styleSheetChanged,this);this._urlToHeadersByFrameId=new Map();this._styleFiles=new Map();}
WebInspector.StylesSourceMapping.ChangeUpdateTimeoutMs=200;WebInspector.StylesSourceMapping.prototype={rawLocationToUILocation:function(rawLocation)
{var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(rawLocation.url,rawLocation.header());if(!uiSourceCode)
return null;var lineNumber=rawLocation.lineNumber;var columnNumber=rawLocation.columnNumber;var header=this._cssModel.styleSheetHeaderForId(rawLocation.styleSheetId);if(header&&header.isInline&&header.hasSourceURL){lineNumber-=header.lineNumberInSource(0);columnNumber-=header.columnNumberInSource(lineNumber,0);}
return uiSourceCode.uiLocation(lineNumber,columnNumber);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{return null;},isIdentity:function()
{return true;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{return true;},target:function()
{return this._cssModel.target();},addHeader:function(header)
{var url=header.resourceURL();if(!url)
return;WebInspector.cssWorkspaceBinding.pushSourceMapping(header,this);var map=this._urlToHeadersByFrameId.get(url);if(!map){map=(new Map());this._urlToHeadersByFrameId.set(url,map);}
var headersById=map.get(header.frameId);if(!headersById){headersById=(new Map());map.set(header.frameId,headersById);}
headersById.set(header.id,header);var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(url,header);if(uiSourceCode)
this._bindUISourceCode(uiSourceCode,header);},removeHeader:function(header)
{var url=header.resourceURL();if(!url)
return;var map=this._urlToHeadersByFrameId.get(url);console.assert(map);var headersById=map.get(header.frameId);console.assert(headersById);headersById.delete(header.id);if(!headersById.size){map.delete(header.frameId);if(!map.size){this._urlToHeadersByFrameId.delete(url);var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(url,header);if(uiSourceCode)
this._unbindUISourceCode(uiSourceCode);}}},_unbindUISourceCode:function(uiSourceCode)
{var styleFile=this._styleFiles.get(uiSourceCode);if(!styleFile)
return;styleFile.dispose();this._styleFiles.delete(uiSourceCode);},_unbindAllUISourceCodes:function()
{for(var styleFile of this._styleFiles.values())
styleFile.dispose();this._styleFiles.clear();this._urlToHeadersByFrameId=new Map();},_uiSourceCodeAddedToWorkspace:function(event)
{var uiSourceCode=(event.data);var networkURL=this._networkMapping.networkURL(uiSourceCode);if(!networkURL||!this._urlToHeadersByFrameId.has(networkURL))
return;this._bindUISourceCode(uiSourceCode,this._urlToHeadersByFrameId.get(networkURL).valuesArray()[0].valuesArray()[0]);},_bindUISourceCode:function(uiSourceCode,header)
{if(this._styleFiles.get(uiSourceCode)||(header.isInline&&!header.hasSourceURL))
return;this._styleFiles.set(uiSourceCode,new WebInspector.StyleFile(uiSourceCode,this));WebInspector.cssWorkspaceBinding.updateLocations(header);},_projectRemoved:function(event)
{var project=(event.data);var uiSourceCodes=project.uiSourceCodes();for(var i=0;i<uiSourceCodes.length;++i)
this._unbindUISourceCode(uiSourceCodes[i]);},_uiSourceCodeRemoved:function(event)
{var uiSourceCode=(event.data);this._unbindUISourceCode(uiSourceCode);},_setStyleContent:function(uiSourceCode,content,majorChange)
{var networkURL=this._networkMapping.networkURL(uiSourceCode);var styleSheetIds=this._cssModel.styleSheetIdsForURL(networkURL);if(!styleSheetIds.length)
return Promise.resolve(("No stylesheet found: "+networkURL));this._isSettingContent=true;function callback(error)
{delete this._isSettingContent;return error||null;}
var promises=[];for(var i=0;i<styleSheetIds.length;++i)
promises.push(this._cssModel.setStyleSheetText(styleSheetIds[i],content,majorChange));return Promise.all(promises).spread(callback.bind(this));},_styleSheetChanged:function(event)
{if(this._isSettingContent)
return;this._updateStyleSheetTextSoon(event.data.styleSheetId);},_updateStyleSheetTextSoon:function(styleSheetId)
{if(this._updateStyleSheetTextTimer)
clearTimeout(this._updateStyleSheetTextTimer);this._updateStyleSheetTextTimer=setTimeout(this._updateStyleSheetText.bind(this,styleSheetId),WebInspector.StylesSourceMapping.ChangeUpdateTimeoutMs);},_updateStyleSheetText:function(styleSheetId)
{if(this._updateStyleSheetTextTimer){clearTimeout(this._updateStyleSheetTextTimer);delete this._updateStyleSheetTextTimer;}
var header=this._cssModel.styleSheetHeaderForId(styleSheetId);if(!header)
return;var styleSheetURL=header.resourceURL();if(!styleSheetURL)
return;var uiSourceCode=this._networkMapping.uiSourceCodeForStyleURL(styleSheetURL,header);if(!uiSourceCode)
return;header.requestContent().then(callback.bind(this,uiSourceCode));function callback(uiSourceCode,content)
{var styleFile=this._styleFiles.get(uiSourceCode);if(styleFile)
styleFile.addRevision(content||"");}}}
WebInspector.StyleFile=function(uiSourceCode,mapping)
{this._uiSourceCode=uiSourceCode;this._mapping=mapping;this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);this._uiSourceCode.forceLoadOnCheckContent();this._commitThrottler=new WebInspector.Throttler(WebInspector.StyleFile.updateTimeout);}
WebInspector.StyleFile.updateTimeout=200;WebInspector.StyleFile.prototype={_workingCopyCommitted:function(event)
{if(this._isAddingRevision)
return;this._isMajorChangePending=true;this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this),true);},_workingCopyChanged:function(event)
{if(this._isAddingRevision)
return;this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this),false);},_commitIncrementalEdit:function()
{var promise=this._mapping._setStyleContent(this._uiSourceCode,this._uiSourceCode.workingCopy(),this._isMajorChangePending).then(this._styleContentSet.bind(this))
this._isMajorChangePending=false;return promise;},_styleContentSet:function(error)
{if(error)
console.error(error);},addRevision:function(content)
{this._isAddingRevision=true;this._uiSourceCode.addRevision(content);delete this._isAddingRevision;},dispose:function()
{this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);}};WebInspector.CSSWorkspaceBinding=function(targetManager,workspace,networkMapping)
{this._workspace=workspace;this._networkMapping=networkMapping;this._modelToTargetInfo=new Map();targetManager.observeTargets(this);targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameCreatedOrNavigated,this);}
WebInspector.CSSWorkspaceBinding.prototype={targetAdded:function(target)
{var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel)
this._modelToTargetInfo.set(cssModel,new WebInspector.CSSWorkspaceBinding.TargetInfo(cssModel,this._workspace,this._networkMapping));},targetRemoved:function(target)
{var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel)
this._modelToTargetInfo.remove(cssModel)._dispose();},pushSourceMapping:function(header,mapping)
{this._ensureInfoForHeader(header)._pushSourceMapping(mapping);},_headerInfo:function(header)
{var map=this._modelToTargetInfo.get(header.cssModel());return map._headerInfo(header.id)||null;},_ensureInfoForHeader:function(header)
{var targetInfo=this._modelToTargetInfo.get(header.cssModel());if(!targetInfo){targetInfo=new WebInspector.CSSWorkspaceBinding.TargetInfo(header.cssModel(),this._workspace,this._networkMapping);this._modelToTargetInfo.set(header.cssModel(),targetInfo);}
return targetInfo._ensureInfoForHeader(header);},_mainFrameCreatedOrNavigated:function(event)
{var target=(event.target).target();var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel)
this._modelToTargetInfo.get(cssModel)._reset();},updateLocations:function(header)
{var info=this._headerInfo(header);if(info)
info._updateLocations();},createLiveLocation:function(rawLocation,updateDelegate,locationPool)
{var header=rawLocation.styleSheetId?rawLocation.cssModel().styleSheetHeaderForId(rawLocation.styleSheetId):null;return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.cssModel(),header,rawLocation,this,updateDelegate,locationPool);},_addLiveLocation:function(location)
{this._ensureInfoForHeader(location._header)._addLocation(location);},_removeLiveLocation:function(location)
{var info=this._headerInfo(location._header);if(info)
info._removeLocation(location);},propertyUILocation:function(cssProperty,forName)
{var style=cssProperty.ownerStyle;if(!style||style.type!==WebInspector.CSSStyleDeclaration.Type.Regular||!style.styleSheetId)
return null;var header=style.cssModel().styleSheetHeaderForId(style.styleSheetId);if(!header)
return null;var range=forName?cssProperty.nameRange():cssProperty.valueRange();if(!range)
return null;var lineNumber=range.startLine;var columnNumber=range.startColumn;var rawLocation=new WebInspector.CSSLocation(header,header.lineNumberInSource(lineNumber),header.columnNumberInSource(lineNumber,columnNumber));return this.rawLocationToUILocation(rawLocation);},rawLocationToUILocation:function(rawLocation)
{if(!rawLocation)
return null;var header=rawLocation.cssModel().styleSheetHeaderForId(rawLocation.styleSheetId);if(!header)
return null;var info=this._headerInfo(header);return info?info._rawLocationToUILocation(rawLocation.lineNumber,rawLocation.columnNumber):null;}}
WebInspector.CSSWorkspaceBinding.TargetInfo=function(cssModel,workspace,networkMapping)
{this._cssModel=cssModel;this._stylesSourceMapping=new WebInspector.StylesSourceMapping(cssModel,workspace,networkMapping);this._sassSourceMapping=new WebInspector.SASSSourceMapping(cssModel,networkMapping,WebInspector.NetworkProject.forTarget(cssModel.target()));this._headerInfoById=new Map();cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);}
WebInspector.CSSWorkspaceBinding.TargetInfo.prototype={_styleSheetAdded:function(event)
{var header=(event.data);this._stylesSourceMapping.addHeader(header);this._sassSourceMapping.addHeader(header);},_styleSheetRemoved:function(event)
{var header=(event.data);this._stylesSourceMapping.removeHeader(header);this._sassSourceMapping.removeHeader(header);this._headerInfoById.remove(header.id);},_headerInfo:function(id)
{return this._headerInfoById.get(id);},_ensureInfoForHeader:function(header)
{var info=this._headerInfoById.get(header.id);if(!info){info=new WebInspector.CSSWorkspaceBinding.HeaderInfo(header);this._headerInfoById.set(header.id,info);}
return info;},_dispose:function()
{this._reset();this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);},_reset:function()
{this._headerInfoById.clear();}}
WebInspector.CSSWorkspaceBinding.HeaderInfo=function(header)
{this._header=header;this._sourceMappings=[];this._locations=new Set();}
WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype={_addLocation:function(location)
{this._locations.add(location);location.update();},_removeLocation:function(location)
{this._locations.delete(location);},_updateLocations:function()
{var items=this._locations.valuesArray();for(var i=0;i<items.length;++i)
items[i].update();},_rawLocationToUILocation:function(lineNumber,columnNumber)
{var uiLocation=null;var rawLocation=new WebInspector.CSSLocation(this._header,lineNumber,columnNumber);for(var i=this._sourceMappings.length-1;!uiLocation&&i>=0;--i)
uiLocation=this._sourceMappings[i].rawLocationToUILocation(rawLocation);return uiLocation;},_pushSourceMapping:function(sourceMapping)
{if(this._sourceMappings.indexOf(sourceMapping)!==-1)
return;this._sourceMappings.push(sourceMapping);this._updateLocations();}}
WebInspector.CSSWorkspaceBinding.LiveLocation=function(cssModel,header,rawLocation,binding,updateDelegate,locationPool)
{WebInspector.LiveLocationWithPool.call(this,updateDelegate,locationPool);this._cssModel=cssModel;this._rawLocation=rawLocation;this._binding=binding;if(!header)
this._clearStyleSheet();else
this._setStyleSheet(header);}
WebInspector.CSSWorkspaceBinding.LiveLocation.prototype={_styleSheetAdded:function(event)
{console.assert(!this._header);var header=(event.data);if(header.sourceURL&&header.sourceURL===this._rawLocation.url)
this._setStyleSheet(header);},_styleSheetRemoved:function(event)
{console.assert(this._header);var header=(event.data);if(this._header!==header)
return;this._binding._removeLiveLocation(this);this._clearStyleSheet();},_setStyleSheet:function(header)
{this._header=header;this._binding._addLiveLocation(this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);},_clearStyleSheet:function()
{delete this._header;this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);},uiLocation:function()
{var cssLocation=this._rawLocation;if(this._header){var headerInfo=this._binding._headerInfo(this._header);return headerInfo._rawLocationToUILocation(cssLocation.lineNumber,cssLocation.columnNumber);}
var uiSourceCode=this._binding._networkMapping.uiSourceCodeForStyleURL(cssLocation.url,cssLocation.header());if(!uiSourceCode)
return null;return uiSourceCode.uiLocation(cssLocation.lineNumber,cssLocation.columnNumber);},dispose:function()
{WebInspector.LiveLocationWithPool.prototype.dispose.call(this);if(this._header)
this._binding._removeLiveLocation(this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);},isBlackboxed:function()
{return false;},__proto__:WebInspector.LiveLocationWithPool.prototype}
WebInspector.CSSSourceMapping=function()
{}
WebInspector.CSSSourceMapping.prototype={rawLocationToUILocation:function(rawLocation){},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber){},isIdentity:function(){},uiLineHasMapping:function(uiSourceCode,lineNumber){}}
WebInspector.cssWorkspaceBinding;;WebInspector.DebuggerWorkspaceBinding=function(targetManager,workspace,networkMapping)
{this._workspace=workspace;this._networkMapping=networkMapping;this._targetToData=new Map();targetManager.observeTargets(this);targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._globalObjectCleared,this);targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.BeforeDebuggerPaused,this._beforeDebuggerPaused,this);targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerResumed,this._debuggerResumed,this);workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);}
WebInspector.DebuggerWorkspaceBinding.prototype={targetAdded:function(target)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel)
this._targetToData.set(target,new WebInspector.DebuggerWorkspaceBinding.TargetData(debuggerModel,this));},targetRemoved:function(target)
{if(!WebInspector.DebuggerModel.fromTarget(target))
return;var targetData=this._targetToData.get(target);targetData._dispose();this._targetToData.remove(target);},_uiSourceCodeRemoved:function(event)
{var uiSourceCode=(event.data);var targetDatas=this._targetToData.valuesArray();for(var i=0;i<targetDatas.length;++i)
targetDatas[i]._uiSourceCodeRemoved(uiSourceCode);},_projectRemoved:function(event)
{var project=(event.data);var targetDatas=this._targetToData.valuesArray();var uiSourceCodes=project.uiSourceCodes();for(var i=0;i<targetDatas.length;++i){for(var j=0;j<uiSourceCodes.length;++j)
targetDatas[i]._uiSourceCodeRemoved(uiSourceCodes[j]);}},pushSourceMapping:function(script,sourceMapping)
{var info=this._ensureInfoForScript(script);info._pushSourceMapping(sourceMapping);},popSourceMapping:function(script)
{var info=this._infoForScript(script.target(),script.scriptId);console.assert(info);return info._popSourceMapping();},setSourceMapping:function(target,uiSourceCode,sourceMapping)
{var data=this._targetToData.get(target);if(data)
data._setSourceMapping(uiSourceCode,sourceMapping);},updateLocations:function(script)
{var info=this._infoForScript(script.target(),script.scriptId);if(info)
info._updateLocations();},createLiveLocation:function(rawLocation,updateDelegate,locationPool)
{var info=this._infoForScript(rawLocation.target(),rawLocation.scriptId);console.assert(info);var location=new WebInspector.DebuggerWorkspaceBinding.Location(info._script,rawLocation,this,updateDelegate,locationPool);info._addLocation(location);return location;},createStackTraceTopFrameLiveLocation:function(rawLocations,updateDelegate,locationPool)
{console.assert(rawLocations.length);var location=new WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation(rawLocations,this,updateDelegate,locationPool);location.update();return location;},createCallFrameLiveLocation:function(location,updateDelegate,locationPool)
{var target=location.target();this._ensureInfoForScript(location.script());var liveLocation=this.createLiveLocation(location,updateDelegate,locationPool);this._registerCallFrameLiveLocation(target,liveLocation);return liveLocation;},rawLocationToUILocation:function(rawLocation)
{var info=this._infoForScript(rawLocation.target(),rawLocation.scriptId);console.assert(info);return info._rawLocationToUILocation(rawLocation);},uiLocationToRawLocation:function(target,uiSourceCode,lineNumber,columnNumber)
{var targetData=this._targetToData.get(target);return targetData?(targetData._uiLocationToRawLocation(uiSourceCode,lineNumber,columnNumber)):null;},uiLocationToRawLocations:function(uiSourceCode,lineNumber,columnNumber)
{var result=[];var targetDatas=this._targetToData.valuesArray();for(var i=0;i<targetDatas.length;++i){var rawLocation=targetDatas[i]._uiLocationToRawLocation(uiSourceCode,lineNumber,columnNumber);if(rawLocation)
result.push(rawLocation);}
return result;},normalizeUILocation:function(uiLocation)
{var target=WebInspector.NetworkProject.targetForUISourceCode(uiLocation.uiSourceCode);if(target){var rawLocation=this.uiLocationToRawLocation(target,uiLocation.uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber);if(rawLocation)
return this.rawLocationToUILocation(rawLocation);}
return uiLocation;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{var targetDatas=this._targetToData.valuesArray();for(var i=0;i<targetDatas.length;++i){if(!targetDatas[i]._uiLineHasMapping(uiSourceCode,lineNumber))
return false;}
return true;},scriptFile:function(uiSourceCode,target)
{var targetData=this._targetToData.get(target);return targetData?targetData._resourceMapping.scriptFile(uiSourceCode):null;},sourceMapForScript:function(script)
{var targetData=this._targetToData.get(script.target());if(!targetData)
return null;return targetData._compilerMapping.sourceMapForScript(script);},maybeLoadSourceMap:function(script)
{var targetData=this._targetToData.get(script.target());if(!targetData)
return;targetData._compilerMapping.maybeLoadSourceMap(script);},_globalObjectCleared:function(event)
{var debuggerModel=(event.target);this._reset(debuggerModel.target());},_reset:function(target)
{var targetData=this._targetToData.get(target);targetData.callFrameLocations.valuesArray().forEach((location)=>this._removeLiveLocation(location));targetData.callFrameLocations.clear();},_ensureInfoForScript:function(script)
{var scriptDataMap=this._targetToData.get(script.target()).scriptDataMap;var info=scriptDataMap.get(script.scriptId);if(!info){info=new WebInspector.DebuggerWorkspaceBinding.ScriptInfo(script);scriptDataMap.set(script.scriptId,info);}
return info;},_infoForScript:function(target,scriptId)
{var data=this._targetToData.get(target);if(!data)
return null;return data.scriptDataMap.get(scriptId)||null;},_registerCallFrameLiveLocation:function(target,location)
{var locations=this._targetToData.get(target).callFrameLocations;locations.add(location);},_removeLiveLocation:function(location)
{var info=this._infoForScript(location._script.target(),location._script.scriptId);if(info)
info._removeLocation(location);},_debuggerResumed:function(event)
{var debuggerModel=(event.target);this._reset(debuggerModel.target());},_beforeDebuggerPaused:function(event)
{var rawLocation=event.data.callFrames[0].location();var targetData=this._targetToData.get(rawLocation.target());if(!targetData._compilerMapping.mapsToSourceCode(rawLocation)){event.stopPropagation();event.preventDefault();}}}
WebInspector.DebuggerWorkspaceBinding.TargetData=function(debuggerModel,debuggerWorkspaceBinding)
{this._target=debuggerModel.target();this.scriptDataMap=new Map();this.callFrameLocations=new Set();var workspace=debuggerWorkspaceBinding._workspace;var networkMapping=debuggerWorkspaceBinding._networkMapping;this._defaultMapping=new WebInspector.DefaultScriptMapping(debuggerModel,workspace,debuggerWorkspaceBinding);this._resourceMapping=new WebInspector.ResourceScriptMapping(debuggerModel,workspace,networkMapping,debuggerWorkspaceBinding);this._compilerMapping=new WebInspector.CompilerScriptMapping(debuggerModel,workspace,networkMapping,WebInspector.NetworkProject.forTarget(this._target),debuggerWorkspaceBinding);this._uiSourceCodeToSourceMapping=new Map();debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource,this._parsedScriptSource,this);debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource,this._parsedScriptSource,this);}
WebInspector.DebuggerWorkspaceBinding.TargetData.prototype={_parsedScriptSource:function(event)
{var script=(event.data);this._defaultMapping.addScript(script);this._resourceMapping.addScript(script);if(WebInspector.moduleSetting("jsSourceMapsEnabled").get())
this._compilerMapping.addScript(script);},_setSourceMapping:function(uiSourceCode,sourceMapping)
{if(this._uiSourceCodeToSourceMapping.get(uiSourceCode)===sourceMapping)
return;if(sourceMapping)
this._uiSourceCodeToSourceMapping.set(uiSourceCode,sourceMapping);else
this._uiSourceCodeToSourceMapping.remove(uiSourceCode);uiSourceCode.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged,{target:this._target,isIdentity:sourceMapping?sourceMapping.isIdentity():false});},_uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{var sourceMapping=this._uiSourceCodeToSourceMapping.get(uiSourceCode);return sourceMapping?sourceMapping.uiLocationToRawLocation(uiSourceCode,lineNumber,columnNumber):null;},_uiLineHasMapping:function(uiSourceCode,lineNumber)
{var sourceMapping=this._uiSourceCodeToSourceMapping.get(uiSourceCode);return sourceMapping?sourceMapping.uiLineHasMapping(uiSourceCode,lineNumber):true;},_uiSourceCodeRemoved:function(uiSourceCode)
{this._uiSourceCodeToSourceMapping.remove(uiSourceCode);},_dispose:function()
{this._compilerMapping.dispose();this._resourceMapping.dispose();this._defaultMapping.dispose();this._uiSourceCodeToSourceMapping.clear();}}
WebInspector.DebuggerWorkspaceBinding.ScriptInfo=function(script)
{this._script=script;this._sourceMappings=[];this._locations=new Set();}
WebInspector.DebuggerWorkspaceBinding.ScriptInfo.prototype={_pushSourceMapping:function(sourceMapping)
{this._sourceMappings.push(sourceMapping);this._updateLocations();},_popSourceMapping:function()
{var sourceMapping=this._sourceMappings.pop();this._updateLocations();return sourceMapping;},_addLocation:function(location)
{this._locations.add(location);location.update();},_removeLocation:function(location)
{this._locations.delete(location);},_updateLocations:function()
{for(var location of this._locations)
location.update();},_rawLocationToUILocation:function(rawLocation)
{var uiLocation;for(var i=this._sourceMappings.length-1;!uiLocation&&i>=0;--i)
uiLocation=this._sourceMappings[i].rawLocationToUILocation(rawLocation);console.assert(uiLocation,"Script raw location cannot be mapped to any UI location.");return(uiLocation);}}
WebInspector.DebuggerWorkspaceBinding.Location=function(script,rawLocation,binding,updateDelegate,locationPool)
{WebInspector.LiveLocationWithPool.call(this,updateDelegate,locationPool);this._script=script;this._rawLocation=rawLocation;this._binding=binding;}
WebInspector.DebuggerWorkspaceBinding.Location.prototype={uiLocation:function()
{var debuggerModelLocation=this._rawLocation;return this._binding.rawLocationToUILocation(debuggerModelLocation);},dispose:function()
{WebInspector.LiveLocationWithPool.prototype.dispose.call(this);this._binding._removeLiveLocation(this);},isBlackboxed:function()
{return WebInspector.blackboxManager.isBlackboxedRawLocation(this._rawLocation);},__proto__:WebInspector.LiveLocationWithPool.prototype}
WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation=function(rawLocations,binding,updateDelegate,locationPool)
{WebInspector.LiveLocationWithPool.call(this,updateDelegate,locationPool);this._updateScheduled=true;this._locations=new Set();for(var location of rawLocations)
this._locations.add(binding.createCallFrameLiveLocation(location,this._scheduleUpdate.bind(this),locationPool));this._updateLocation();}
WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation.prototype={uiLocation:function()
{return this._current.uiLocation();},isBlackboxed:function()
{return this._current.isBlackboxed();},dispose:function()
{WebInspector.LiveLocationWithPool.prototype.dispose.call(this);for(var location of this._locations)
location.dispose();},_scheduleUpdate:function()
{if(!this._updateScheduled){this._updateScheduled=true;setImmediate(this._updateLocation.bind(this));}},_updateLocation:function()
{this._updateScheduled=false;this._current=this._locations.values().next().value;for(var current of this._locations){if(!current.isBlackboxed()){this._current=current;break;}}
this.update();},__proto__:WebInspector.LiveLocationWithPool.prototype}
WebInspector.DebuggerSourceMapping=function()
{}
WebInspector.DebuggerSourceMapping.prototype={rawLocationToUILocation:function(rawLocation){},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber){},isIdentity:function(){},uiLineHasMapping:function(uiSourceCode,lineNumber){}}
WebInspector.debuggerWorkspaceBinding;;WebInspector.BreakpointManager=function(breakpointsSetting,workspace,networkMapping,targetManager,debuggerWorkspaceBinding)
{this._storage=new WebInspector.BreakpointManager.Storage(this,breakpointsSetting);this._workspace=workspace;this._networkMapping=networkMapping;this._targetManager=targetManager;this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._breakpointsActive=true;this._breakpointsForUISourceCode=new Map();this._breakpointsForPrimaryUISourceCode=new Map();this._provisionalBreakpoints=new Multimap();this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);}
WebInspector.BreakpointManager.Events={BreakpointAdded:"breakpoint-added",BreakpointRemoved:"breakpoint-removed",BreakpointsActiveStateChanged:"BreakpointsActiveStateChanged"}
WebInspector.BreakpointManager._breakpointStorageId=function(sourceFileId,lineNumber,columnNumber)
{if(!sourceFileId)
return"";return sourceFileId+":"+lineNumber+":"+columnNumber;}
WebInspector.BreakpointManager.prototype={_sourceFileId:function(uiSourceCode)
{var networkURL=this._networkMapping.networkURL(uiSourceCode)
if(!networkURL)
return"";return uiSourceCode.url();},targetAdded:function(target)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel&&!this._breakpointsActive)
debuggerModel.setBreakpointsActive(this._breakpointsActive);},targetRemoved:function(target){},_provisionalBreakpointsForSourceFileId:function(sourceFileId)
{var result=new Map();var breakpoints=this._provisionalBreakpoints.get(sourceFileId).valuesArray();for(var i=0;i<breakpoints.length;++i)
result.set(breakpoints[i]._breakpointStorageId(),breakpoints[i]);return result;},removeProvisionalBreakpointsForTest:function()
{var breakpoints=this._provisionalBreakpoints.valuesArray();for(var i=0;i<breakpoints.length;++i)
breakpoints[i].remove();this._provisionalBreakpoints.clear();},_restoreBreakpoints:function(uiSourceCode)
{var sourceFileId=this._sourceFileId(uiSourceCode);if(!sourceFileId)
return;this._storage.mute();var breakpointItems=this._storage.breakpointItems(this._sourceFileId(uiSourceCode));var provisionalBreakpoints=this._provisionalBreakpointsForSourceFileId(sourceFileId);for(var i=0;i<breakpointItems.length;++i){var breakpointItem=breakpointItems[i];var itemStorageId=WebInspector.BreakpointManager._breakpointStorageId(breakpointItem.sourceFileId,breakpointItem.lineNumber,breakpointItem.columnNumber);var provisionalBreakpoint=provisionalBreakpoints.get(itemStorageId);if(provisionalBreakpoint){if(!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.set(uiSourceCode,[]);this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(provisionalBreakpoint);provisionalBreakpoint._updateBreakpoint();}else{this._innerSetBreakpoint(uiSourceCode,breakpointItem.lineNumber,breakpointItem.columnNumber,breakpointItem.condition,breakpointItem.enabled);}}
this._provisionalBreakpoints.removeAll(sourceFileId);this._storage.unmute();},_uiSourceCodeAdded:function(event)
{var uiSourceCode=(event.data);this._restoreBreakpoints(uiSourceCode);if(uiSourceCode.contentType().hasScripts())
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged,this._uiSourceCodeMappingChanged,this);},_uiSourceCodeRemoved:function(event)
{var uiSourceCode=(event.data);this._removeUISourceCode(uiSourceCode);},_uiSourceCodeMappingChanged:function(event)
{var uiSourceCode=(event.target);var isIdentity=(event.data.isIdentity);var target=(event.data.target);if(isIdentity)
return;var breakpoints=this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)||[];for(var i=0;i<breakpoints.length;++i)
breakpoints[i]._updateInDebuggerForTarget(target);},_removeUISourceCode:function(uiSourceCode)
{var breakpoints=this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)||[];var sourceFileId=this._sourceFileId(uiSourceCode);for(var i=0;i<breakpoints.length;++i){breakpoints[i]._resetLocations();if(breakpoints[i].enabled())
this._provisionalBreakpoints.set(sourceFileId,breakpoints[i]);}
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged,this._uiSourceCodeMappingChanged,this);this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode);},setBreakpoint:function(uiSourceCode,lineNumber,columnNumber,condition,enabled)
{var uiLocation=new WebInspector.UILocation(uiSourceCode,lineNumber,columnNumber);var normalizedLocation=this._debuggerWorkspaceBinding.normalizeUILocation(uiLocation);if(normalizedLocation.id()!==uiLocation.id()){WebInspector.Revealer.reveal(normalizedLocation);uiLocation=normalizedLocation;}
this.setBreakpointsActive(true);return this._innerSetBreakpoint(uiLocation.uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber,condition,enabled);},_innerSetBreakpoint:function(uiSourceCode,lineNumber,columnNumber,condition,enabled)
{var breakpoint=this.findBreakpoint(uiSourceCode,lineNumber,columnNumber);if(breakpoint){breakpoint._updateState(condition,enabled);return breakpoint;}
var projectId=uiSourceCode.project().id();var path=uiSourceCode.url();var sourceFileId=this._sourceFileId(uiSourceCode);breakpoint=new WebInspector.BreakpointManager.Breakpoint(this,projectId,path,sourceFileId,lineNumber,columnNumber,condition,enabled);if(!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.set(uiSourceCode,[]);this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoint);return breakpoint;},findBreakpoint:function(uiSourceCode,lineNumber,columnNumber)
{var breakpoints=this._breakpointsForUISourceCode.get(uiSourceCode);var lineBreakpoints=breakpoints?breakpoints.get(String(lineNumber)):null;var columnBreakpoints=lineBreakpoints?lineBreakpoints.get(String(columnNumber)):null;return columnBreakpoints?columnBreakpoints[0]:null;},findBreakpointOnLine:function(uiSourceCode,lineNumber)
{var breakpoints=this._breakpointsForUISourceCode.get(uiSourceCode);var lineBreakpoints=breakpoints?breakpoints.get(String(lineNumber)):null;return lineBreakpoints?lineBreakpoints.valuesArray()[0][0]:null;},breakpointsForUISourceCode:function(uiSourceCode)
{var result=[];var uiSourceCodeBreakpoints=this._breakpointsForUISourceCode.get(uiSourceCode);var breakpoints=uiSourceCodeBreakpoints?uiSourceCodeBreakpoints.valuesArray():[];for(var i=0;i<breakpoints.length;++i){var lineBreakpoints=breakpoints[i];var columnBreakpointArrays=lineBreakpoints?lineBreakpoints.valuesArray():[];result=result.concat.apply(result,columnBreakpointArrays);}
return result;},allBreakpoints:function()
{var result=[];var uiSourceCodes=this._breakpointsForUISourceCode.keysArray();for(var i=0;i<uiSourceCodes.length;++i)
result=result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i]));return result;},breakpointLocationsForUISourceCode:function(uiSourceCode)
{var uiSourceCodeBreakpoints=this._breakpointsForUISourceCode.get(uiSourceCode);var lineNumbers=uiSourceCodeBreakpoints?uiSourceCodeBreakpoints.keysArray():[];var result=[];for(var i=0;i<lineNumbers.length;++i){var lineBreakpoints=uiSourceCodeBreakpoints.get(lineNumbers[i]);var columnNumbers=lineBreakpoints.keysArray();for(var j=0;j<columnNumbers.length;++j){var columnBreakpoints=lineBreakpoints.get(columnNumbers[j]);var lineNumber=parseInt(lineNumbers[i],10);var columnNumber=parseInt(columnNumbers[j],10);for(var k=0;k<columnBreakpoints.length;++k){var breakpoint=columnBreakpoints[k];var uiLocation=uiSourceCode.uiLocation(lineNumber,columnNumber);result.push({breakpoint:breakpoint,uiLocation:uiLocation});}}}
return result;},allBreakpointLocations:function()
{var result=[];var uiSourceCodes=this._breakpointsForUISourceCode.keysArray();for(var i=0;i<uiSourceCodes.length;++i)
result=result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i]));return result;},toggleAllBreakpoints:function(toggleState)
{var breakpoints=this.allBreakpoints();for(var i=0;i<breakpoints.length;++i)
breakpoints[i].setEnabled(toggleState);},removeAllBreakpoints:function()
{var breakpoints=this.allBreakpoints();for(var i=0;i<breakpoints.length;++i)
breakpoints[i].remove();},_projectRemoved:function(event)
{var project=(event.data);var uiSourceCodes=project.uiSourceCodes();for(var i=0;i<uiSourceCodes.length;++i)
this._removeUISourceCode(uiSourceCodes[i]);},_removeBreakpoint:function(breakpoint,removeFromStorage)
{var uiSourceCode=breakpoint.uiSourceCode();var breakpoints=uiSourceCode?this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)||[]:[];breakpoints.remove(breakpoint);if(removeFromStorage)
this._storage._removeBreakpoint(breakpoint);this._provisionalBreakpoints.remove(breakpoint._sourceFileId,breakpoint);},_uiLocationAdded:function(breakpoint,uiLocation)
{var breakpoints=this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);if(!breakpoints){breakpoints=new Map();this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode,breakpoints);}
var lineBreakpoints=breakpoints.get(String(uiLocation.lineNumber));if(!lineBreakpoints){lineBreakpoints=new Map();breakpoints.set(String(uiLocation.lineNumber),lineBreakpoints);}
var columnBreakpoints=lineBreakpoints.get(String(uiLocation.columnNumber));if(!columnBreakpoints){columnBreakpoints=[];lineBreakpoints.set(String(uiLocation.columnNumber),columnBreakpoints);}
columnBreakpoints.push(breakpoint);this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded,{breakpoint:breakpoint,uiLocation:uiLocation});},_uiLocationRemoved:function(breakpoint,uiLocation)
{var breakpoints=this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);if(!breakpoints)
return;var lineBreakpoints=breakpoints.get(String(uiLocation.lineNumber));if(!lineBreakpoints)
return;var columnBreakpoints=lineBreakpoints.get(String(uiLocation.columnNumber));if(!columnBreakpoints)
return;columnBreakpoints.remove(breakpoint);if(!columnBreakpoints.length)
lineBreakpoints.remove(String(uiLocation.columnNumber));if(!lineBreakpoints.size)
breakpoints.remove(String(uiLocation.lineNumber));if(!breakpoints.size)
this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved,{breakpoint:breakpoint,uiLocation:uiLocation});},setBreakpointsActive:function(active)
{if(this._breakpointsActive===active)
return;this._breakpointsActive=active;var debuggerModels=WebInspector.DebuggerModel.instances();for(var i=0;i<debuggerModels.length;++i)
debuggerModels[i].setBreakpointsActive(active);this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged,active);},breakpointsActive:function()
{return this._breakpointsActive;},__proto__:WebInspector.Object.prototype}
WebInspector.BreakpointManager.Breakpoint=function(breakpointManager,projectId,path,sourceFileId,lineNumber,columnNumber,condition,enabled)
{this._breakpointManager=breakpointManager;this._projectId=projectId;this._path=path;this._lineNumber=lineNumber;this._columnNumber=columnNumber;this._sourceFileId=sourceFileId;this._numberOfDebuggerLocationForUILocation={};this._condition;this._enabled;this._isRemoved;this._fakePrimaryLocation;this._currentState=null;this._targetBreakpoints=new Map();this._updateState(condition,enabled);this._breakpointManager._targetManager.observeTargets(this);}
WebInspector.BreakpointManager.Breakpoint.prototype={targetAdded:function(target)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel)
return;var networkMapping=this._breakpointManager._networkMapping;var debuggerWorkspaceBinding=this._breakpointManager._debuggerWorkspaceBinding;this._targetBreakpoints.set(target,new WebInspector.BreakpointManager.TargetBreakpoint(debuggerModel,this,networkMapping,debuggerWorkspaceBinding));},targetRemoved:function(target)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel)
return;var targetBreakpoint=this._targetBreakpoints.remove(target);targetBreakpoint._cleanUpAfterDebuggerIsGone();targetBreakpoint._removeEventListeners();},projectId:function()
{return this._projectId;},path:function()
{return this._path;},lineNumber:function()
{return this._lineNumber;},columnNumber:function()
{return this._columnNumber;},uiSourceCode:function()
{return this._breakpointManager._workspace.uiSourceCode(this._projectId,this._path);},_replaceUILocation:function(oldUILocation,newUILocation)
{if(this._isRemoved)
return;this._removeUILocation(oldUILocation,true);this._removeFakeBreakpointAtPrimaryLocation();if(!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
this._numberOfDebuggerLocationForUILocation[newUILocation.id()]=0;if(++this._numberOfDebuggerLocationForUILocation[newUILocation.id()]===1)
this._breakpointManager._uiLocationAdded(this,newUILocation);},_removeUILocation:function(uiLocation,muteCreationFakeBreakpoint)
{if(!uiLocation||--this._numberOfDebuggerLocationForUILocation[uiLocation.id()]!==0)
return;delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];this._breakpointManager._uiLocationRemoved(this,uiLocation);if(!muteCreationFakeBreakpoint)
this._fakeBreakpointAtPrimaryLocation();},enabled:function()
{return this._enabled;},setEnabled:function(enabled)
{this._updateState(this._condition,enabled);},condition:function()
{return this._condition;},setCondition:function(condition)
{this._updateState(condition,this._enabled);},_updateState:function(condition,enabled)
{if(this._enabled===enabled&&this._condition===condition)
return;this._enabled=enabled;this._condition=condition;this._breakpointManager._storage._updateBreakpoint(this);this._updateBreakpoint();},_updateBreakpoint:function()
{this._removeFakeBreakpointAtPrimaryLocation();this._fakeBreakpointAtPrimaryLocation();var targetBreakpoints=this._targetBreakpoints.valuesArray();for(var i=0;i<targetBreakpoints.length;++i)
targetBreakpoints[i]._scheduleUpdateInDebugger();},remove:function(keepInStorage)
{this._isRemoved=true;var removeFromStorage=!keepInStorage;this._removeFakeBreakpointAtPrimaryLocation();var targetBreakpoints=this._targetBreakpoints.valuesArray();for(var i=0;i<targetBreakpoints.length;++i){targetBreakpoints[i]._scheduleUpdateInDebugger();targetBreakpoints[i]._removeEventListeners();}
this._breakpointManager._removeBreakpoint(this,removeFromStorage);this._breakpointManager._targetManager.unobserveTargets(this);},_updateInDebuggerForTarget:function(target)
{this._targetBreakpoints.get(target)._scheduleUpdateInDebugger();},_breakpointStorageId:function()
{return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId,this._lineNumber,this._columnNumber);},_fakeBreakpointAtPrimaryLocation:function()
{if(this._isRemoved||!Object.isEmpty(this._numberOfDebuggerLocationForUILocation)||this._fakePrimaryLocation)
return;var uiSourceCode=this._breakpointManager._workspace.uiSourceCode(this._projectId,this._path);if(!uiSourceCode)
return;this._fakePrimaryLocation=uiSourceCode.uiLocation(this._lineNumber,this._columnNumber);if(this._fakePrimaryLocation)
this._breakpointManager._uiLocationAdded(this,this._fakePrimaryLocation);},_removeFakeBreakpointAtPrimaryLocation:function()
{if(this._fakePrimaryLocation){this._breakpointManager._uiLocationRemoved(this,this._fakePrimaryLocation);delete this._fakePrimaryLocation;}},_resetLocations:function()
{this._removeFakeBreakpointAtPrimaryLocation();var targetBreakpoints=this._targetBreakpoints.valuesArray();for(var i=0;i<targetBreakpoints.length;++i)
targetBreakpoints[i]._resetLocations();}}
WebInspector.BreakpointManager.TargetBreakpoint=function(debuggerModel,breakpoint,networkMapping,debuggerWorkspaceBinding)
{WebInspector.SDKObject.call(this,debuggerModel.target());this._debuggerModel=debuggerModel;this._breakpoint=breakpoint;this._networkMapping=networkMapping;this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._liveLocations=new WebInspector.LiveLocationPool();this._uiLocations={};this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled,this._cleanUpAfterDebuggerIsGone,this);this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled,this._scheduleUpdateInDebugger,this);this._hasPendingUpdate=false;this._isUpdating=false;this._cancelCallback=false;this._currentState=null;if(this._debuggerModel.debuggerEnabled())
this._scheduleUpdateInDebugger();}
WebInspector.BreakpointManager.TargetBreakpoint.prototype={_resetLocations:function()
{var uiLocations=Object.values(this._uiLocations);for(var i=0;i<uiLocations.length;++i)
this._breakpoint._removeUILocation(uiLocations[i]);this._uiLocations={};this._liveLocations.disposeAll();},_scheduleUpdateInDebugger:function()
{if(this._isUpdating){this._hasPendingUpdate=true;return;}
this._isUpdating=true;this._updateInDebugger(this._didUpdateInDebugger.bind(this));},_didUpdateInDebugger:function()
{this._isUpdating=false;if(this._hasPendingUpdate){this._hasPendingUpdate=false;this._scheduleUpdateInDebugger();}},_scriptDiverged:function()
{var uiSourceCode=this._breakpoint.uiSourceCode();if(!uiSourceCode)
return false;var scriptFile=this._debuggerWorkspaceBinding.scriptFile(uiSourceCode,this.target());return!!scriptFile&&scriptFile.hasDivergedFromVM();},_updateInDebugger:function(callback)
{if(this.target().isDetached()){this._cleanUpAfterDebuggerIsGone();callback();return;}
var uiSourceCode=this._breakpoint.uiSourceCode();var lineNumber=this._breakpoint._lineNumber;var columnNumber=this._breakpoint._columnNumber;var condition=this._breakpoint.condition();var debuggerLocation=uiSourceCode?this._debuggerWorkspaceBinding.uiLocationToRawLocation(this.target(),uiSourceCode,lineNumber,columnNumber):null;var newState;if(this._breakpoint._isRemoved||!this._breakpoint.enabled()||this._scriptDiverged())
newState=null;else if(debuggerLocation){var script=debuggerLocation.script();if(script.sourceURL)
newState=new WebInspector.BreakpointManager.Breakpoint.State(script.sourceURL,null,debuggerLocation.lineNumber,debuggerLocation.columnNumber,condition);else
newState=new WebInspector.BreakpointManager.Breakpoint.State(null,debuggerLocation.scriptId,debuggerLocation.lineNumber,debuggerLocation.columnNumber,condition);}else if(this._breakpoint._currentState&&this._breakpoint._currentState.url){var position=this._breakpoint._currentState;newState=new WebInspector.BreakpointManager.Breakpoint.State(position.url,null,position.lineNumber,position.columnNumber,condition);}else if(uiSourceCode){var networkURL=this._networkMapping.networkURL(uiSourceCode);if(networkURL)
newState=new WebInspector.BreakpointManager.Breakpoint.State(networkURL,null,lineNumber,columnNumber,condition);}
if(this._debuggerId&&WebInspector.BreakpointManager.Breakpoint.State.equals(newState,this._currentState)){callback();return;}
this._breakpoint._currentState=newState;if(this._debuggerId){this._resetLocations();this._debuggerModel.removeBreakpoint(this._debuggerId,this._didRemoveFromDebugger.bind(this,callback));this._scheduleUpdateInDebugger();this._currentState=null;return;}
if(!newState){callback();return;}
var updateCallback=this._didSetBreakpointInDebugger.bind(this,callback);if(newState.url)
this._debuggerModel.setBreakpointByURL(newState.url,newState.lineNumber,newState.columnNumber,this._breakpoint.condition(),updateCallback);else if(newState.scriptId)
this._debuggerModel.setBreakpointBySourceId((debuggerLocation),condition,updateCallback);this._currentState=newState;},_didSetBreakpointInDebugger:function(callback,breakpointId,locations)
{if(this._cancelCallback){this._cancelCallback=false;callback();return;}
if(!breakpointId){this._breakpoint.remove(true);callback();return;}
this._debuggerId=breakpointId;this._debuggerModel.addBreakpointListener(this._debuggerId,this._breakpointResolved,this);for(var i=0;i<locations.length;++i){if(!this._addResolvedLocation(locations[i]))
break;}
callback();},_didRemoveFromDebugger:function(callback)
{if(this._cancelCallback){this._cancelCallback=false;callback();return;}
this._resetLocations();this._debuggerModel.removeBreakpointListener(this._debuggerId,this._breakpointResolved,this);delete this._debuggerId;callback();},_breakpointResolved:function(event)
{this._addResolvedLocation((event.data));},_locationUpdated:function(location,liveLocation)
{var uiLocation=liveLocation.uiLocation();if(!uiLocation)
return;var oldUILocation=this._uiLocations[location.id()]||null;this._uiLocations[location.id()]=uiLocation;this._breakpoint._replaceUILocation(oldUILocation,uiLocation);},_addResolvedLocation:function(location)
{var uiLocation=this._debuggerWorkspaceBinding.rawLocationToUILocation(location);var breakpoint=this._breakpoint._breakpointManager.findBreakpoint(uiLocation.uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber);if(breakpoint&&breakpoint!==this._breakpoint){this._breakpoint.remove();return false;}
this._debuggerWorkspaceBinding.createLiveLocation(location,this._locationUpdated.bind(this,location),this._liveLocations);return true;},_cleanUpAfterDebuggerIsGone:function()
{if(this._isUpdating)
this._cancelCallback=true;this._resetLocations();this._currentState=null;if(this._debuggerId)
this._didRemoveFromDebugger(function(){});},_removeEventListeners:function()
{this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled,this._cleanUpAfterDebuggerIsGone,this);this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled,this._scheduleUpdateInDebugger,this);},__proto__:WebInspector.SDKObject.prototype}
WebInspector.BreakpointManager.Breakpoint.State=function(url,scriptId,lineNumber,columnNumber,condition)
{this.url=url;this.scriptId=scriptId;this.lineNumber=lineNumber;this.columnNumber=columnNumber;this.condition=condition;}
WebInspector.BreakpointManager.Breakpoint.State.equals=function(stateA,stateB)
{if(!stateA||!stateB)
return false;if(stateA.scriptId||stateB.scriptId)
return false;return stateA.url===stateB.url&&stateA.lineNumber===stateB.lineNumber&&stateA.columnNumber===stateB.columnNumber&&stateA.condition===stateB.condition;}
WebInspector.BreakpointManager.Storage=function(breakpointManager,setting)
{this._breakpointManager=breakpointManager;this._setting=setting||WebInspector.settings.createLocalSetting("breakpoints",[]);var breakpoints=this._setting.get();this._breakpoints={};for(var i=0;i<breakpoints.length;++i){var breakpoint=(breakpoints[i]);breakpoint.columnNumber=breakpoint.columnNumber||0;this._breakpoints[breakpoint.sourceFileId+":"+breakpoint.lineNumber+":"+breakpoint.columnNumber]=breakpoint;}}
WebInspector.BreakpointManager.Storage.prototype={mute:function()
{this._muted=true;},unmute:function()
{delete this._muted;},breakpointItems:function(sourceFileId)
{var result=[];for(var id in this._breakpoints){var breakpoint=this._breakpoints[id];if(breakpoint.sourceFileId===sourceFileId)
result.push(breakpoint);}
return result;},_updateBreakpoint:function(breakpoint)
{if(this._muted||!breakpoint._breakpointStorageId())
return;this._breakpoints[breakpoint._breakpointStorageId()]=new WebInspector.BreakpointManager.Storage.Item(breakpoint);this._save();},_removeBreakpoint:function(breakpoint)
{if(this._muted)
return;delete this._breakpoints[breakpoint._breakpointStorageId()];this._save();},_save:function()
{var breakpointsArray=[];for(var id in this._breakpoints)
breakpointsArray.push(this._breakpoints[id]);this._setting.set(breakpointsArray);}}
WebInspector.BreakpointManager.Storage.Item=function(breakpoint)
{this.sourceFileId=breakpoint._sourceFileId;this.lineNumber=breakpoint.lineNumber();this.columnNumber=breakpoint.columnNumber();this.condition=breakpoint.condition();this.enabled=breakpoint.enabled();}
WebInspector.breakpointManager;;WebInspector.ContentProviderBasedProject=function(workspace,id,type,displayName)
{WebInspector.ProjectStore.call(this,workspace,id,type,displayName);this._contentProviders={};workspace.addProject(this);}
WebInspector.ContentProviderBasedProject.prototype={requestFileContent:function(uiSourceCode,callback)
{var contentProvider=this._contentProviders[uiSourceCode.url()];contentProvider.requestContent().then(callback);},canSetFileContent:function()
{return false;},setFileContent:function(uiSourceCode,newContent,callback)
{callback(null);},canRename:function()
{return false;},rename:function(uiSourceCode,newName,callback)
{var path=uiSourceCode.url();this.performRename(path,newName,innerCallback.bind(this));function innerCallback(success,newName)
{if(success&&newName){var copyOfPath=path.split("/");copyOfPath[copyOfPath.length-1]=newName;var newPath=copyOfPath.join("/");this._contentProviders[newPath]=this._contentProviders[path];delete this._contentProviders[path];this.renameUISourceCode(uiSourceCode,newName);}
callback(success,newName);}},refresh:function(path,callback)
{if(callback)
callback();},excludeFolder:function(path)
{},createFile:function(path,name,content,callback)
{},deleteFile:function(path)
{},remove:function()
{},performRename:function(path,newName,callback)
{callback(false);},searchInFileContent:function(uiSourceCode,query,caseSensitive,isRegex,callback)
{var contentProvider=this._contentProviders[uiSourceCode.url()];contentProvider.searchInContent(query,caseSensitive,isRegex,callback);},findFilesMatchingSearchRequest:function(searchConfig,filesMathingFileQuery,progress,callback)
{var result=[];var paths=filesMathingFileQuery;var totalCount=paths.length;if(totalCount===0){setTimeout(doneCallback,0);return;}
var barrier=new CallbackBarrier();progress.setTotalWork(paths.length);for(var i=0;i<paths.length;++i)
searchInContent.call(this,paths[i],barrier.createCallback(searchInContentCallback.bind(null,paths[i])));barrier.callWhenDone(doneCallback);function searchInContent(path,callback)
{var queriesToRun=searchConfig.queries().slice();searchNextQuery.call(this);function searchNextQuery()
{if(!queriesToRun.length){callback(true);return;}
var query=queriesToRun.shift();this._contentProviders[path].searchInContent(query,!searchConfig.ignoreCase(),searchConfig.isRegex(),contentCallback.bind(this));}
function contentCallback(searchMatches)
{if(!searchMatches.length){callback(false);return;}
searchNextQuery.call(this);}}
function searchInContentCallback(path,matches)
{if(matches)
result.push(path);progress.worked(1);}
function doneCallback()
{callback(result);progress.done();}},indexContent:function(progress)
{setImmediate(progress.done.bind(progress));},addUISourceCodeWithProvider:function(uiSourceCode,contentProvider)
{this._contentProviders[uiSourceCode.url()]=contentProvider;this.addUISourceCode(uiSourceCode,true);},addContentProvider:function(url,contentProvider)
{var uiSourceCode=this.createUISourceCode(url,contentProvider.contentType());this.addUISourceCodeWithProvider(uiSourceCode,contentProvider);return uiSourceCode;},removeFile:function(path)
{delete this._contentProviders[path];this.removeUISourceCode(path);},reset:function()
{this._contentProviders={};this.removeProject();this.workspace().addProject(this);},dispose:function()
{this._contentProviders={};this.removeProject();},__proto__:WebInspector.ProjectStore.prototype};WebInspector.DefaultScriptMapping=function(debuggerModel,workspace,debuggerWorkspaceBinding)
{this._debuggerModel=debuggerModel;this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._workspace=workspace;this._projectId=WebInspector.DefaultScriptMapping.projectIdForTarget(debuggerModel.target());this._project=new WebInspector.ContentProviderBasedProject(this._workspace,this._projectId,WebInspector.projectTypes.Debugger,"");debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);this._debuggerReset();}
WebInspector.DefaultScriptMapping._scriptSymbol=Symbol("symbol");WebInspector.DefaultScriptMapping.scriptForUISourceCode=function(uiSourceCode)
{return uiSourceCode[WebInspector.DefaultScriptMapping._scriptSymbol]||null;}
WebInspector.DefaultScriptMapping.prototype={rawLocationToUILocation:function(rawLocation)
{var debuggerModelLocation=(rawLocation);var script=debuggerModelLocation.script();var uiSourceCode=this._uiSourceCodeForScriptId.get(script.scriptId);var lineNumber=debuggerModelLocation.lineNumber-(script.isInlineScriptWithSourceURL()?script.lineOffset:0);var columnNumber=debuggerModelLocation.columnNumber||0;if(script.isInlineScriptWithSourceURL()&&!lineNumber&&columnNumber)
columnNumber-=script.columnOffset;return uiSourceCode.uiLocation(lineNumber,columnNumber);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber)
{var scriptId=this._scriptIdForUISourceCode.get(uiSourceCode);var script=this._debuggerModel.scriptForId(scriptId);if(script.isInlineScriptWithSourceURL())
return this._debuggerModel.createRawLocation(script,lineNumber+script.lineOffset,lineNumber?columnNumber:columnNumber+script.columnOffset);return this._debuggerModel.createRawLocation(script,lineNumber,columnNumber);},addScript:function(script)
{var name=WebInspector.ParsedURL.extractName(script.sourceURL);var url="debugger:///VM"+script.scriptId+(name?" "+name:"");var uiSourceCode=this._project.createUISourceCode(url,WebInspector.resourceTypes.Script);uiSourceCode[WebInspector.DefaultScriptMapping._scriptSymbol]=script;this._uiSourceCodeForScriptId.set(script.scriptId,uiSourceCode);this._scriptIdForUISourceCode.set(uiSourceCode,script.scriptId);this._project.addUISourceCodeWithProvider(uiSourceCode,script);this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel.target(),uiSourceCode,this);this._debuggerWorkspaceBinding.pushSourceMapping(script,this);},isIdentity:function()
{return true;},uiLineHasMapping:function(uiSourceCode,lineNumber)
{return true;},_debuggerReset:function()
{this._uiSourceCodeForScriptId=new Map();this._scriptIdForUISourceCode=new Map();this._project.reset();},dispose:function()
{this._project.dispose();}}
WebInspector.DefaultScriptMapping.projectIdForTarget=function(target)
{return"debugger:"+target.id();};WebInspector.FileSystemWorkspaceBinding=function(isolatedFileSystemManager,workspace)
{this._isolatedFileSystemManager=isolatedFileSystemManager;this._workspace=workspace;this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,this._fileSystemAdded,this);this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,this._fileSystemRemoved,this);this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemFilesChanged,this._fileSystemFilesChanged,this);this._boundFileSystems=new Map();}
WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions=new Set(["css","scss","sass","less"]);WebInspector.FileSystemWorkspaceBinding._documentExtensions=new Set(["htm","html","asp","aspx","phtml","jsp"]);WebInspector.FileSystemWorkspaceBinding._scriptExtensions=new Set(["asp","aspx","c","cc","cljs","coffee","cpp","cs","dart","java","js","jsp","jsx","h","m","mm","py","sh","ts","tsx"]);WebInspector.FileSystemWorkspaceBinding._imageExtensions=WebInspector.IsolatedFileSystem.ImageExtensions;WebInspector.FileSystemWorkspaceBinding.projectId=function(fileSystemPath)
{return fileSystemPath;}
WebInspector.FileSystemWorkspaceBinding.relativePath=function(uiSourceCode)
{var baseURL=(uiSourceCode.project())._fileSystemBaseURL;return uiSourceCode.url().substring(baseURL.length).split("/");}
WebInspector.FileSystemWorkspaceBinding.completeURL=function(project,relativePath)
{var fsProject=(project);return fsProject._fileSystemBaseURL+relativePath;}
WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension=function(extension)
{if(WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions.has(extension))
return WebInspector.resourceTypes.Stylesheet;if(WebInspector.FileSystemWorkspaceBinding._documentExtensions.has(extension))
return WebInspector.resourceTypes.Document;if(WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(extension))
return WebInspector.resourceTypes.Image;if(WebInspector.FileSystemWorkspaceBinding._scriptExtensions.has(extension))
return WebInspector.resourceTypes.Script;return WebInspector.resourceTypes.Other;}
WebInspector.FileSystemWorkspaceBinding.prototype={fileSystemManager:function()
{return this._isolatedFileSystemManager;},_fileSystemAdded:function(event)
{var fileSystem=(event.data);var boundFileSystem=new WebInspector.FileSystemWorkspaceBinding.FileSystem(this,fileSystem,this._workspace);this._boundFileSystems.set(fileSystem.path(),boundFileSystem);},_fileSystemRemoved:function(event)
{var fileSystem=(event.data);var boundFileSystem=this._boundFileSystems.get(fileSystem.path());boundFileSystem.dispose();this._boundFileSystems.remove(fileSystem.path());},_fileSystemFilesChanged:function(event)
{var paths=(event.data);for(var path of paths){for(var key of this._boundFileSystems.keys()){if(!path.startsWith(key))
continue;this._boundFileSystems.get(key)._fileChanged(path);}}},fileSystemPath:function(projectId)
{return projectId;},dispose:function()
{this._isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,this._fileSystemAdded,this);this._isolatedFileSystemManager.removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,this._fileSystemRemoved,this);this._isolatedFileSystemManager.dispose();for(var fileSystem of this._boundFileSystems.values()){fileSystem.dispose();this._boundFileSystems.remove(fileSystem._fileSystem.path());}}}
WebInspector.FileSystemWorkspaceBinding.FileSystem=function(fileSystemWorkspaceBinding,isolatedFileSystem,workspace)
{this._fileSystemWorkspaceBinding=fileSystemWorkspaceBinding;this._fileSystem=isolatedFileSystem;this._fileSystemBaseURL=this._fileSystem.path()+"/";this._fileSystemPath=this._fileSystem.path();var id=WebInspector.FileSystemWorkspaceBinding.projectId(this._fileSystemPath);console.assert(!workspace.project(id));var displayName=this._fileSystemPath.substr(this._fileSystemPath.lastIndexOf("/")+1);WebInspector.ProjectStore.call(this,workspace,id,WebInspector.projectTypes.FileSystem,displayName);workspace.addProject(this);this.populate();}
WebInspector.FileSystemWorkspaceBinding.FileSystem.prototype={fileSystemPath:function()
{return this._fileSystemPath;},_filePathForUISourceCode:function(uiSourceCode)
{return uiSourceCode.url().substring(this._fileSystemPath.length);},requestFileContent:function(uiSourceCode,callback)
{var filePath=this._filePathForUISourceCode(uiSourceCode);var isImage=WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(WebInspector.ParsedURL.extractExtension(filePath));this._fileSystem.requestFileContent(filePath,isImage?base64CallbackWrapper:callback);function base64CallbackWrapper(result)
{if(!result){callback(result);return;}
var index=result.indexOf(",");callback(result.substring(index+1));}},canSetFileContent:function()
{return true;},setFileContent:function(uiSourceCode,newContent,callback)
{var filePath=this._filePathForUISourceCode(uiSourceCode);this._fileSystem.setFileContent(filePath,newContent,callback.bind(this,""));},canRename:function()
{return true;},rename:function(uiSourceCode,newName,callback)
{if(newName===uiSourceCode.name()){callback(true,uiSourceCode.name(),uiSourceCode.url(),uiSourceCode.contentType());return;}
var filePath=this._filePathForUISourceCode(uiSourceCode);this._fileSystem.renameFile(filePath,newName,innerCallback.bind(this));function innerCallback(success,newName)
{if(!success||!newName){callback(false,newName);return;}
console.assert(newName);var slash=filePath.lastIndexOf("/");var parentPath=filePath.substring(0,slash);filePath=parentPath+"/"+newName;filePath=filePath.substr(1);var extension=this._extensionForPath(newName);var newURL=this._fileSystemBaseURL+filePath;var newContentType=WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(extension);this.renameUISourceCode(uiSourceCode,newName);callback(true,newName,newURL,newContentType);}},searchInFileContent:function(uiSourceCode,query,caseSensitive,isRegex,callback)
{var filePath=this._filePathForUISourceCode(uiSourceCode);this._fileSystem.requestFileContent(filePath,contentCallback);function contentCallback(content)
{var result=[];if(content!==null)
result=WebInspector.ContentProvider.performSearchInContent(content,query,caseSensitive,isRegex);callback(result);}},findFilesMatchingSearchRequest:function(searchConfig,filesMathingFileQuery,progress,callback)
{var result=filesMathingFileQuery;var queriesToRun=searchConfig.queries().slice();if(!queriesToRun.length)
queriesToRun.push("");progress.setTotalWork(queriesToRun.length);searchNextQuery.call(this);function searchNextQuery()
{if(!queriesToRun.length){progress.done();callback(result);return;}
var query=queriesToRun.shift();this._fileSystem.searchInPath(searchConfig.isRegex()?"":query,progress,innerCallback.bind(this));}
function innerCallback(files)
{files=files.sort();progress.worked(1);result=result.intersectOrdered(files,String.naturalOrderComparator);searchNextQuery.call(this);}},indexContent:function(progress)
{this._fileSystem.indexContent(progress);},_extensionForPath:function(path)
{var extensionIndex=path.lastIndexOf(".");if(extensionIndex===-1)
return"";return path.substring(extensionIndex+1).toLowerCase();},populate:function()
{this._fileSystem.requestFilesRecursive("",this._addFile.bind(this));},refresh:function(path,callback)
{this._fileSystem.requestFilesRecursive(path,this._addFile.bind(this),callback);},excludeFolder:function(url)
{var relativeFolder=url.substring(this._fileSystemBaseURL.length);if(!relativeFolder.startsWith("/"))
relativeFolder="/"+relativeFolder;if(!relativeFolder.endsWith("/"))
relativeFolder+="/";this._fileSystem.addExcludedFolder(relativeFolder);var uiSourceCodes=this.uiSourceCodes().slice();for(var i=0;i<uiSourceCodes.length;++i){var uiSourceCode=uiSourceCodes[i];if(uiSourceCode.url().startsWith(url))
this.removeUISourceCode(uiSourceCode.url());}},createFile:function(path,name,content,callback)
{this._fileSystem.createFile(path,name,innerCallback.bind(this));var createFilePath;function innerCallback(filePath)
{if(!filePath){callback(null);return;}
createFilePath=filePath;if(!content){contentSet.call(this);return;}
this._fileSystem.setFileContent(filePath,content,contentSet.bind(this));}
function contentSet()
{callback(this._addFile(createFilePath));}},deleteFile:function(path)
{this._fileSystem.deleteFile(path);this.removeUISourceCode(path);},remove:function()
{this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSystem(this._fileSystem);},_addFile:function(filePath)
{if(!filePath)
console.assert(false);var extension=this._extensionForPath(filePath);var contentType=WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(extension);var uiSourceCode=this.createUISourceCode(this._fileSystemBaseURL+filePath,contentType);this.addUISourceCode(uiSourceCode);return uiSourceCode;},_fileChanged:function(path)
{var uiSourceCode=this.uiSourceCodeForURL(path);if(!uiSourceCode){var contentType=WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension(this._extensionForPath(path));this.addUISourceCode(this.createUISourceCode(path,contentType));return;}
uiSourceCode.checkContentUpdated();},dispose:function()
{this.removeProject();},__proto__:WebInspector.ProjectStore.prototype};WebInspector.OutputStreamDelegate=function()
{}
WebInspector.OutputStreamDelegate.prototype={onTransferStarted:function(){},onTransferFinished:function(){},onChunkTransferred:function(reader){},onError:function(reader,event){},}
WebInspector.ChunkedReader=function()
{}
WebInspector.ChunkedReader.prototype={fileSize:function(){},loadedSize:function(){},fileName:function(){},cancel:function(){}}
WebInspector.ChunkedFileReader=function(file,chunkSize,delegate)
{this._file=file;this._fileSize=file.size;this._loadedSize=0;this._chunkSize=chunkSize;this._delegate=delegate;this._decoder=new TextDecoder();this._isCanceled=false;}
WebInspector.ChunkedFileReader.prototype={start:function(output)
{this._output=output;this._reader=new FileReader();this._reader.onload=this._onChunkLoaded.bind(this);this._reader.onerror=this._delegate.onError.bind(this._delegate,this);this._delegate.onTransferStarted();this._loadChunk();},cancel:function()
{this._isCanceled=true;},loadedSize:function()
{return this._loadedSize;},fileSize:function()
{return this._fileSize;},fileName:function()
{return this._file.name;},_onChunkLoaded:function(event)
{if(this._isCanceled)
return;if(event.target.readyState!==FileReader.DONE)
return;var buffer=event.target.result;this._loadedSize+=buffer.byteLength;var endOfFile=this._loadedSize===this._fileSize;var decodedString=this._decoder.decode(buffer,{stream:!endOfFile});this._output.write(decodedString);if(this._isCanceled)
return;this._delegate.onChunkTransferred(this);if(endOfFile){this._file=null;this._reader=null;this._output.close();this._delegate.onTransferFinished();return;}
this._loadChunk();},_loadChunk:function()
{var chunkStart=this._loadedSize;var chunkEnd=Math.min(this._fileSize,chunkStart+this._chunkSize);var nextPart=this._file.slice(chunkStart,chunkEnd);this._reader.readAsArrayBuffer(nextPart);}}
WebInspector.createFileSelectorElement=function(callback)
{var fileSelectorElement=createElement("input");fileSelectorElement.type="file";fileSelectorElement.style.display="none";fileSelectorElement.setAttribute("tabindex",-1);fileSelectorElement.onchange=onChange;function onChange(event)
{callback(fileSelectorElement.files[0]);};return fileSelectorElement;}
WebInspector.FileOutputStream=function()
{}
WebInspector.FileOutputStream.prototype={open:function(fileName,callback)
{this._closed=false;this._writeCallbacks=[];this._fileName=fileName;function callbackWrapper(accepted)
{if(accepted)
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.AppendedToURL,this._onAppendDone,this);callback(accepted);}
WebInspector.fileManager.save(this._fileName,"",true,callbackWrapper.bind(this));},write:function(data,callback)
{this._writeCallbacks.push(callback);WebInspector.fileManager.append(this._fileName,data);},close:function()
{this._closed=true;if(this._writeCallbacks.length)
return;WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL,this._onAppendDone,this);WebInspector.fileManager.close(this._fileName);},_onAppendDone:function(event)
{if(event.data!==this._fileName)
return;var callback=this._writeCallbacks.shift();if(callback)
callback(this);if(!this._writeCallbacks.length){if(this._closed){WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL,this._onAppendDone,this);WebInspector.fileManager.close(this._fileName);}}}};WebInspector.BlackboxManager=function(debuggerWorkspaceBinding,networkMapping)
{this._debuggerWorkspaceBinding=debuggerWorkspaceBinding;this._networkMapping=networkMapping;WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.ParsedScriptSource,this._parsedScriptSource,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._globalObjectCleared,this);WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._patternChanged.bind(this));WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._patternChanged.bind(this));this._debuggerModelData=new Map();this._isBlackboxedURLCache=new Map();WebInspector.targetManager.observeTargets(this);}
WebInspector.BlackboxManager.prototype={addChangeListener:function(listener,thisObject)
{WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(listener,thisObject);},removeChangeListener:function(listener,thisObject)
{WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListener(listener,thisObject);},targetAdded:function(target)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel)
this._setBlackboxPatterns(debuggerModel);},targetRemoved:function(target)
{},_setBlackboxPatterns:function(debuggerModel)
{var regexPatterns=WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();var patterns=([]);for(var item of regexPatterns){if(!item.disabled&&item.pattern)
patterns.push(item.pattern);}
return debuggerModel.setBlackboxPatterns(patterns);},isBlackboxedRawLocation:function(location)
{var positions=this._scriptPositions(location.script());if(!positions)
return this._isBlackboxedScript(location.script());var index=positions.lowerBound(location,comparator);return!!(index%2);function comparator(a,b)
{if(a.lineNumber!==b.line)
return a.lineNumber-b.line;return a.columnNumber-b.column;}},isBlackboxedUISourceCode:function(uiSourceCode)
{var projectType=uiSourceCode.project().type();var isContentScript=projectType===WebInspector.projectTypes.ContentScripts;if(isContentScript&&WebInspector.moduleSetting("skipContentScripts").get())
return true;var url=this._uiSourceCodeURL(uiSourceCode);return url?this.isBlackboxedURL(url):false;},isBlackboxedURL:function(url,isContentScript)
{if(this._isBlackboxedURLCache.has(url))
return!!this._isBlackboxedURLCache.get(url);if(isContentScript&&WebInspector.moduleSetting("skipContentScripts").get())
return true;var regex=WebInspector.moduleSetting("skipStackFramesPattern").asRegExp();var isBlackboxed=regex&®ex.test(url);this._isBlackboxedURLCache.set(url,isBlackboxed);return isBlackboxed;},sourceMapLoaded:function(script,sourceMap)
{if(!sourceMap)
return Promise.resolve();var previousScriptState=this._scriptPositions(script);if(!previousScriptState)
return Promise.resolve();var mappings=sourceMap.mappings().slice();mappings.sort(mappingComparator);if(!mappings.length){if(previousScriptState.length>0)
return this._setScriptState(script,[]);return Promise.resolve();}
var currentBlackboxed=false;var isBlackboxed=false;var positions=[];if(mappings[0].lineNumber!==0||mappings[0].columnNumber!==0){positions.push({line:0,column:0});currentBlackboxed=true;}
for(var mapping of mappings){if(mapping.sourceURL&¤tBlackboxed!==this.isBlackboxedURL(mapping.sourceURL)){positions.push({line:mapping.lineNumber,column:mapping.columnNumber});currentBlackboxed=!currentBlackboxed;}
isBlackboxed=currentBlackboxed||isBlackboxed;}
return this._setScriptState(script,!isBlackboxed?[]:positions);function mappingComparator(a,b)
{if(a.lineNumber!==b.lineNumber)
return a.lineNumber-b.lineNumber;return a.columnNumber-b.columnNumber;}},_uiSourceCodeURL:function(uiSourceCode)
{var networkURL=this._networkMapping.networkURL(uiSourceCode);var projectType=uiSourceCode.project().type();if(projectType===WebInspector.projectTypes.Debugger)
return null;var url=projectType===WebInspector.projectTypes.Formatter?uiSourceCode.url():networkURL;return url?url:null;},canBlackboxUISourceCode:function(uiSourceCode)
{var url=this._uiSourceCodeURL(uiSourceCode);return url?!!this._urlToRegExpString(url):false;},blackboxUISourceCode:function(uiSourceCode)
{var url=this._uiSourceCodeURL(uiSourceCode);if(url)
this._blackboxURL(url);},unblackboxUISourceCode:function(uiSourceCode)
{var url=this._uiSourceCodeURL(uiSourceCode);if(url)
this._unblackboxURL(url);},blackboxContentScripts:function()
{WebInspector.moduleSetting("skipContentScripts").set(true);},unblackboxContentScripts:function()
{WebInspector.moduleSetting("skipContentScripts").set(false);},_blackboxURL:function(url)
{var regexPatterns=WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();var regexValue=this._urlToRegExpString(url);if(!regexValue)
return;var found=false;for(var i=0;i<regexPatterns.length;++i){var item=regexPatterns[i];if(item.pattern===regexValue){item.disabled=false;found=true;break;}}
if(!found)
regexPatterns.push({pattern:regexValue});WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);},_unblackboxURL:function(url)
{var regexPatterns=WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();var regexValue=WebInspector.blackboxManager._urlToRegExpString(url);if(!regexValue)
return;regexPatterns=regexPatterns.filter(function(item){return item.pattern!==regexValue;});for(var i=0;i<regexPatterns.length;++i){var item=regexPatterns[i];if(item.disabled)
continue;try{var regex=new RegExp(item.pattern);if(regex.test(url))
item.disabled=true;}catch(e){}}
WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);},_patternChanged:function()
{this._isBlackboxedURLCache.clear();var promises=[];for(var debuggerModel of WebInspector.DebuggerModel.instances()){promises.push(this._setBlackboxPatterns.bind(this,debuggerModel));for(var scriptId in debuggerModel.scripts){var script=debuggerModel.scripts[scriptId];promises.push(this._addScript(script).then(loadSourceMap.bind(this,script)));}}
Promise.all(promises).then(this._patternChangeFinishedForTests.bind(this));function loadSourceMap(script)
{return this.sourceMapLoaded(script,this._debuggerWorkspaceBinding.sourceMapForScript(script));}},_patternChangeFinishedForTests:function()
{},_globalObjectCleared:function(event)
{var debuggerModel=(event.target);this._debuggerModelData.delete(debuggerModel);this._isBlackboxedURLCache.clear();},_parsedScriptSource:function(event)
{var script=(event.data);this._addScript(script);},_addScript:function(script)
{var blackboxed=this._isBlackboxedScript(script);return this._setScriptState(script,blackboxed?[{line:0,column:0}]:[]);},_isBlackboxedScript:function(script)
{return this.isBlackboxedURL(script.sourceURL,script.isContentScript());},_scriptPositions:function(script)
{if(this._debuggerModelData.has(script.debuggerModel))
return this._debuggerModelData.get(script.debuggerModel).get(script.scriptId)||null;return null;},_setScriptPositions:function(script,positions)
{var debuggerModel=script.debuggerModel;if(!this._debuggerModelData.has(debuggerModel))
this._debuggerModelData.set(debuggerModel,new Map());this._debuggerModelData.get(debuggerModel).set(script.scriptId,positions);},_setScriptState:function(script,positions)
{var previousScriptState=this._scriptPositions(script);if(previousScriptState){var hasChanged=false;hasChanged=previousScriptState.length!==positions.length;for(var i=0;!hasChanged&&i<positions.length;++i)
hasChanged=positions[i].line!==previousScriptState[i].line||positions[i].column!==previousScriptState[i].column;if(!hasChanged)
return Promise.resolve();}else{if(positions.length===0)
return Promise.resolve().then(updateState.bind(this,false));}
return script.setBlackboxedRanges(positions).then(updateState.bind(this));function updateState(success)
{if(success){this._setScriptPositions(script,positions);this._debuggerWorkspaceBinding.updateLocations(script);var isBlackboxed=positions.length!==0;if(!isBlackboxed&&script.sourceMapURL)
this._debuggerWorkspaceBinding.maybeLoadSourceMap(script);}else{var hasPositions=!!this._scriptPositions(script);if(!hasPositions)
this._setScriptPositions(script,[]);}}},_urlToRegExpString:function(url)
{var parsedURL=new WebInspector.ParsedURL(url);if(parsedURL.isAboutBlank()||parsedURL.isDataURL())
return"";if(!parsedURL.isValid)
return"^"+url.escapeForRegExp()+"$";var name=parsedURL.lastPathComponent;if(name)
name="/"+name;else if(parsedURL.folderPathComponents)
name=parsedURL.folderPathComponents+"/";if(!name)
name=parsedURL.host;if(!name)
return"";var scheme=parsedURL.scheme;var prefix="";if(scheme&&scheme!=="http"&&scheme!=="https"){prefix="^"+scheme+"://";if(scheme==="chrome-extension")
prefix+=parsedURL.host+"\\b";prefix+=".*";}
return prefix+name.escapeForRegExp()+(url.endsWith(name)?"$":"\\b");}}
WebInspector.blackboxManager;;WebInspector.NetworkMapping=function(targetManager,workspace,fileSystemWorkspaceBinding,fileSystemMapping)
{this._targetManager=targetManager;this._workspace=workspace;this._fileSystemWorkspaceBinding=fileSystemWorkspaceBinding;this._fileSystemMapping=fileSystemMapping;InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.RevealSourceLine,this._revealSourceLine,this);var fileSystemManager=fileSystemWorkspaceBinding.fileSystemManager();for(var path of fileSystemManager.fileSystemPaths()){var fileSystem=fileSystemManager.fileSystem(path);this._fileSystemAdded(new WebInspector.Event(fileSystemManager,WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,fileSystem));}
if(fileSystemManager.fileSystemsLoaded())
this._fileSystemsLoaded();fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,this._fileSystemAdded,this);fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,this._fileSystemRemoved,this);fileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemsLoaded,this._fileSystemsLoaded,this);this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded,this._fileSystemMappingChanged,this);this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved,this._fileSystemMappingChanged,this);}
WebInspector.NetworkMapping.prototype={_fileSystemAdded:function(event)
{this._addingFileSystem=true;var fileSystem=(event.data);this._fileSystemMapping.addFileSystem(fileSystem.path());var mappings=fileSystem.projectProperty("mappings");for(var i=0;Array.isArray(mappings)&&i<mappings.length;++i){var mapping=mappings[i];if(!mapping||typeof mapping!=="object")
continue;var folder=mapping["folder"];var url=mapping["url"];if(typeof folder!=="string"||typeof url!=="string")
continue;this._fileSystemMapping.addNonConfigurableFileMapping(fileSystem.path(),url,folder);}
this._addingFileSystem=false;this._fileSystemMappingChanged();},_fileSystemRemoved:function(event)
{var fileSystem=(event.data);this._fileSystemMapping.removeFileSystem(fileSystem.path());this._fileSystemMappingChanged();},networkURL:function(uiSourceCode)
{if(uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem){var fileSystemPath=this._fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());return this._networkURLForFileSystemURL(fileSystemPath,uiSourceCode.url());}
return uiSourceCode.url();},hasMappingForNetworkURL:function(url)
{return this._fileSystemMapping.hasMappingForNetworkURL(url);},_networkUISourceCodeForURL:function(target,frame,url)
{return this._workspace.uiSourceCode(WebInspector.NetworkProject.projectId(target,frame,false),url);},_contentScriptUISourceCodeForURL:function(target,frame,url)
{return this._workspace.uiSourceCode(WebInspector.NetworkProject.projectId(target,frame,true),url);},_fileSystemUISourceCodeForURL:function(url)
{var file=this._fileSystemMapping.fileForURL(url);if(file){var projectId=WebInspector.FileSystemWorkspaceBinding.projectId(file.fileSystemPath);return this._workspace.uiSourceCode(projectId,file.fileURL);}
return null;},_uiSourceCodeForURL:function(target,frame,url)
{return this._fileSystemUISourceCodeForURL(url)||this._networkUISourceCodeForURL(target,frame,url)||this._contentScriptUISourceCodeForURL(target,frame,url);},uiSourceCodeForScriptURL:function(url,script)
{var frame=WebInspector.ResourceTreeFrame.fromScript(script);return this._uiSourceCodeForURL(script.target(),frame,url);},uiSourceCodeForStyleURL:function(url,header)
{var frame=WebInspector.ResourceTreeFrame.fromStyleSheet(header);return this._uiSourceCodeForURL(header.target(),frame,url);},uiSourceCodeForURLForAnyTarget:function(url)
{return this._fileSystemUISourceCodeForURL(url)||WebInspector.workspace.uiSourceCodeForURL(url);},_networkURLForFileSystemURL:function(fileSystemPath,filePath)
{return this._fileSystemMapping.networkURLForFileSystemURL(fileSystemPath,filePath);},addMapping:function(networkUISourceCode,uiSourceCode)
{var url=this.networkURL(networkUISourceCode);var path=uiSourceCode.url();var fileSystemPath=this._fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());this._fileSystemMapping.addMappingForResource(url,fileSystemPath,path);},removeMapping:function(uiSourceCode)
{var networkURL=this.networkURL(uiSourceCode);this._fileSystemMapping.removeMappingForURL(networkURL);},_revealSourceLine:function(event)
{var url=(event.data["url"]);var lineNumber=(event.data["lineNumber"]);var columnNumber=(event.data["columnNumber"]);var uiSourceCode=this.uiSourceCodeForURLForAnyTarget(url);if(uiSourceCode){WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber,columnNumber));return;}
function listener(event)
{var uiSourceCode=(event.data);if(this.networkURL(uiSourceCode)===url){WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber,columnNumber));this._workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,listener,this);}}
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,listener,this);},_fileSystemsLoaded:function()
{this._fileSystemsReady=true;},_fileSystemMappingChanged:function()
{if(!this._fileSystemsReady||this._addingFileSystem)
return;this._targetManager.suspendAndResumeAllTargets();},dispose:function()
{this._fileSystemWorkspaceBinding.fileSystemManager().removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,this._fileSystemAdded,this);this._fileSystemWorkspaceBinding.fileSystemManager().removeEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,this._fileSystemRemoved,this);this._fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded,this._fileSystemMappingChanged,this);this._fileSystemMapping.removeEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved,this._fileSystemMappingChanged,this);}}
WebInspector.networkMapping;;WebInspector.NetworkProjectManager=function(targetManager,workspace,networkMapping)
{this._workspace=workspace;this._networkMapping=networkMapping;targetManager.observeTargets(this);}
WebInspector.NetworkProjectManager.prototype={targetAdded:function(target)
{new WebInspector.NetworkProject(target,this._workspace,this._networkMapping);},targetRemoved:function(target)
{WebInspector.NetworkProject.forTarget(target)._dispose();}}
WebInspector.NetworkProject=function(target,workspace,networkMapping)
{WebInspector.SDKObject.call(this,target);this._workspace=workspace;this._networkMapping=networkMapping;this._workspaceProjects=new Map();target[WebInspector.NetworkProject._networkProjectSymbol]=this;target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,this._resourceAdded,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameWillNavigate,this._frameWillNavigate,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameNavigated,this);var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel){debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource,this._parsedScriptSource,this);debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource,this._parsedScriptSource,this);}
var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel){cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);}
target.targetManager().addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._suspendStateChanged,this);}
WebInspector.NetworkProject._networkProjectSymbol=Symbol("networkProject");WebInspector.NetworkProject._resourceSymbol=Symbol("resource");WebInspector.NetworkProject._scriptSymbol=Symbol("script");WebInspector.NetworkProject._styleSheetSymbol=Symbol("styleSheet");WebInspector.NetworkProject._targetSymbol=Symbol("target");WebInspector.NetworkProject._frameSymbol=Symbol("frame");WebInspector.NetworkProject.projectId=function(target,frame,isContentScripts)
{return target.id()+":"+(frame?frame.id:"")+":"+(isContentScripts?"contentscripts":"");}
WebInspector.NetworkProject.forTarget=function(target)
{return target[WebInspector.NetworkProject._networkProjectSymbol];}
WebInspector.NetworkProject.targetForProject=function(project)
{return project[WebInspector.NetworkProject._targetSymbol]||null;}
WebInspector.NetworkProject.frameForProject=function(project)
{return project[WebInspector.NetworkProject._frameSymbol]||null;}
WebInspector.NetworkProject.targetForUISourceCode=function(uiSourceCode)
{return uiSourceCode[WebInspector.NetworkProject._targetSymbol]||null;}
WebInspector.NetworkProject.uiSourceCodeMimeType=function(uiSourceCode)
{if(uiSourceCode[WebInspector.NetworkProject._scriptSymbol]||uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol]){return uiSourceCode.contentType().canonicalMimeType();}
var resource=uiSourceCode[WebInspector.NetworkProject._resourceSymbol];if(resource)
return resource.mimeType;var mimeType=WebInspector.ResourceType.mimeFromURL(uiSourceCode.url());return mimeType||uiSourceCode.contentType().canonicalMimeType();}
WebInspector.NetworkProject.uiSourceCodeFrame=function(uiSourceCode)
{var target=uiSourceCode[WebInspector.NetworkProject._targetSymbol];if(!target)
return null;var frameId;var script=uiSourceCode[WebInspector.NetworkProject._scriptSymbol];if(script){var executionContext=script.executionContext();if(executionContext)
frameId=executionContext.frameId;}
if(!frameId){var header=uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol];if(header)
frameId=header.frameId;}
if(!frameId){var resource=uiSourceCode[WebInspector.NetworkProject._resourceSymbol];if(resource)
frameId=resource.frameId;}
return frameId?target.resourceTreeModel.frameForId(frameId):null;}
WebInspector.NetworkProject.prototype={_workspaceProject:function(frame,isContentScripts)
{var projectId=WebInspector.NetworkProject.projectId(this.target(),frame,isContentScripts);var projectType=isContentScripts?WebInspector.projectTypes.ContentScripts:WebInspector.projectTypes.Network;var project=this._workspaceProjects.get(projectId);if(project)
return project;project=new WebInspector.ContentProviderBasedProject(this._workspace,projectId,projectType,"");project[WebInspector.NetworkProject._targetSymbol]=this.target();project[WebInspector.NetworkProject._frameSymbol]=frame;this._workspaceProjects.set(projectId,project);return project;},addFile:function(contentProvider,frame,isContentScript)
{var uiSourceCode=this._createFile(contentProvider,frame,isContentScript||false);if(uiSourceCode)
this._addUISourceCodeWithProvider(uiSourceCode,contentProvider);return uiSourceCode;},_removeFileForURL:function(frame,url)
{var project=this._workspaceProjects.get(WebInspector.NetworkProject.projectId(this.target(),frame,false));if(!project)
return;project.removeFile(url);},_populate:function()
{function populateFrame(frame)
{for(var i=0;i<frame.childFrames.length;++i)
populateFrame.call(this,frame.childFrames[i]);var resources=frame.resources();for(var i=0;i<resources.length;++i)
this._addResource(resources[i]);}
var mainFrame=this.target().resourceTreeModel.mainFrame;if(mainFrame)
populateFrame.call(this,mainFrame);},_addUISourceCodeWithProvider:function(uiSourceCode,contentProvider)
{(uiSourceCode.project()).addUISourceCodeWithProvider(uiSourceCode,contentProvider);},_parsedScriptSource:function(event)
{var script=(event.data);if(!script.sourceURL||script.isLiveEdit()||(script.isInlineScript()&&!script.hasSourceURL))
return;if(script.isContentScript()&&!script.hasSourceURL){var parsedURL=new WebInspector.ParsedURL(script.sourceURL);if(!parsedURL.isValid)
return;}
var uiSourceCode=this._createFile(script,WebInspector.ResourceTreeFrame.fromScript(script),script.isContentScript());if(uiSourceCode){uiSourceCode[WebInspector.NetworkProject._scriptSymbol]=script;this._addUISourceCodeWithProvider(uiSourceCode,script);}},_styleSheetAdded:function(event)
{var header=(event.data);if(header.isInline&&!header.hasSourceURL&&header.origin!=="inspector")
return;var originalContentProvider=header.originalContentProvider();var uiSourceCode=this._createFile(originalContentProvider,WebInspector.ResourceTreeFrame.fromStyleSheet(header),false);if(uiSourceCode){uiSourceCode[WebInspector.NetworkProject._styleSheetSymbol]=header;this._addUISourceCodeWithProvider(uiSourceCode,originalContentProvider);}},_styleSheetRemoved:function(event)
{var header=(event.data);if(header.isInline&&!header.hasSourceURL&&header.origin!=="inspector")
return;this._removeFileForURL(WebInspector.ResourceTreeFrame.fromStyleSheet(header),header.resourceURL());},_resourceAdded:function(event)
{var resource=(event.data);this._addResource(resource);},_addResource:function(resource)
{var resourceType=resource.resourceType();if(resourceType!==WebInspector.resourceTypes.Image&&resourceType!==WebInspector.resourceTypes.Font&&resourceType!==WebInspector.resourceTypes.Document&&resourceType!==WebInspector.resourceTypes.Manifest){return;}
if(resourceType===WebInspector.resourceTypes.Image&&resource.mimeType&&!resource.mimeType.startsWith("image"))
return;if(resourceType===WebInspector.resourceTypes.Font&&resource.mimeType&&!resource.mimeType.includes("font"))
return;if((resourceType===WebInspector.resourceTypes.Image||resourceType===WebInspector.resourceTypes.Font)&&resource.contentURL().startsWith("data:"))
return;if(this._workspace.uiSourceCodeForURL(resource.url))
return;var uiSourceCode=this._createFile(resource,WebInspector.ResourceTreeFrame.fromResource(resource),false);if(uiSourceCode){uiSourceCode[WebInspector.NetworkProject._resourceSymbol]=resource;this._addUISourceCodeWithProvider(uiSourceCode,resource);}},_frameWillNavigate:function(event)
{var frame=(event.data);var project=this._workspaceProject(frame,false);for(var resource of frame.resources())
project.removeUISourceCode(resource.url);project=this._workspaceProject(frame,true);for(var resource of frame.resources())
project.removeUISourceCode(resource.url);},_mainFrameNavigated:function(event)
{this._reset();this._populate();},_suspendStateChanged:function()
{if(this.target().targetManager().allTargetsSuspended())
this._reset();else
this._populate();},_createFile:function(contentProvider,frame,isContentScript)
{var url=contentProvider.contentURL();if(this._networkMapping.hasMappingForNetworkURL(url))
return null;var project=this._workspaceProject(frame,isContentScript);var uiSourceCode=project.createUISourceCode(url,contentProvider.contentType());uiSourceCode[WebInspector.NetworkProject._targetSymbol]=this.target();return uiSourceCode;},_dispose:function()
{this._reset();var target=this.target();target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,this._resourceAdded,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameNavigated,this);var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel){debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource,this._parsedScriptSource,this);debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource,this._parsedScriptSource,this);}
var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel){cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._styleSheetAdded,this);cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._styleSheetRemoved,this);}
delete target[WebInspector.NetworkProject._networkProjectSymbol];},_reset:function()
{for(var project of this._workspaceProjects.values())
project.reset();this._workspaceProjects.clear();},__proto__:WebInspector.SDKObject.prototype};WebInspector.PresentationConsoleMessageHelper=function(workspace)
{this._workspace=workspace;this._pendingConsoleMessages={};this._presentationConsoleMessages=[];WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared,this._consoleCleared,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded,this._onConsoleMessageAdded,this);WebInspector.multitargetConsoleModel.messages().forEach(this._consoleMessageAdded,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.ParsedScriptSource,this._parsedScriptSource,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.FailedToParseScriptSource,this._parsedScriptSource,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);this._locationPool=new WebInspector.LiveLocationPool();}
WebInspector.PresentationConsoleMessageHelper.prototype={_onConsoleMessageAdded:function(event)
{var message=(event.data);this._consoleMessageAdded(message);},_consoleMessageAdded:function(message)
{if(!message.url||!message.isErrorOrWarning())
return;var rawLocation=this._rawLocation(message);if(rawLocation)
this._addConsoleMessageToScript(message,rawLocation);else
this._addPendingConsoleMessage(message);},_rawLocation:function(message)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(message.target());if(!debuggerModel)
return null;var callFrame=message.stackTrace&&message.stackTrace.callFrames?message.stackTrace.callFrames[0]:null;var lineNumber=callFrame?callFrame.lineNumber-1:message.line-1;var columnNumber=message.column?message.column-1:0;if(callFrame&&callFrame.columnNumber)
columnNumber=callFrame.columnNumber-1;if(message.scriptId)
return debuggerModel.createRawLocationByScriptId(message.scriptId,lineNumber,columnNumber);return debuggerModel.createRawLocationByURL(message.url||"",lineNumber,columnNumber);},_addConsoleMessageToScript:function(message,rawLocation)
{this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message,rawLocation,this._locationPool));},_addPendingConsoleMessage:function(message)
{if(!message.url)
return;if(!this._pendingConsoleMessages[message.url])
this._pendingConsoleMessages[message.url]=[];this._pendingConsoleMessages[message.url].push(message);},_parsedScriptSource:function(event)
{var script=(event.data);var messages=this._pendingConsoleMessages[script.sourceURL];if(!messages)
return;var pendingMessages=[];for(var i=0;i<messages.length;i++){var message=messages[i];var rawLocation=this._rawLocation(message);if(!rawLocation)
continue;if(script.target()===message.target()&&script.scriptId===rawLocation.scriptId)
this._addConsoleMessageToScript(message,rawLocation);else
pendingMessages.push(message);}
if(pendingMessages.length)
this._pendingConsoleMessages[script.sourceURL]=pendingMessages;else
delete this._pendingConsoleMessages[script.sourceURL];},_consoleCleared:function()
{this._pendingConsoleMessages={};for(var i=0;i<this._presentationConsoleMessages.length;++i)
this._presentationConsoleMessages[i].dispose();this._presentationConsoleMessages=[];this._locationPool.disposeAll();},_debuggerReset:function()
{this._consoleCleared();}}
WebInspector.PresentationConsoleMessage=function(message,rawLocation,locationPool)
{this._text=message.messageText;this._level=message.level===WebInspector.ConsoleMessage.MessageLevel.Error?WebInspector.UISourceCode.Message.Level.Error:WebInspector.UISourceCode.Message.Level.Warning;WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation,this._updateLocation.bind(this),locationPool);}
WebInspector.PresentationConsoleMessage.prototype={_updateLocation:function(liveLocation)
{if(this._uiMessage)
this._uiMessage.remove();var uiLocation=liveLocation.uiLocation();if(!uiLocation)
return;this._uiMessage=uiLocation.uiSourceCode.addLineMessage(this._level,this._text,uiLocation.lineNumber,uiLocation.columnNumber);},dispose:function()
{if(this._uiMessage)
this._uiMessage.remove();}}
WebInspector.presentationConsoleMessageHelper;;WebInspector.resourceForURL=function(url)
{var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i){var resource=targets[i].resourceTreeModel.resourceForURL(url);if(resource)
return resource;}
return null;}
WebInspector.forAllResources=function(callback)
{var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i)
targets[i].resourceTreeModel.forAllResources(callback);}
WebInspector.displayNameForURL=function(url)
{if(!url)
return"";var resource=WebInspector.resourceForURL(url);if(resource)
return resource.displayName;var uiSourceCode=WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);if(uiSourceCode)
return uiSourceCode.displayName();if(!WebInspector.targetManager.inspectedPageURL())
return url.trimURL("");var parsedURL=WebInspector.targetManager.inspectedPageURL().asParsedURL();var lastPathComponent=parsedURL?parsedURL.lastPathComponent:parsedURL;var index=WebInspector.targetManager.inspectedPageURL().indexOf(lastPathComponent);if(index!==-1&&index+lastPathComponent.length===WebInspector.targetManager.inspectedPageURL().length){var baseURL=WebInspector.targetManager.inspectedPageURL().substring(0,index);if(url.startsWith(baseURL))
return url.substring(index);}
if(!parsedURL)
return url;var displayName=url.trimURL(parsedURL.host);return displayName==="/"?parsedURL.host+"/":displayName;};window.requestFileSystem=window.requestFileSystem||window.webkitRequestFileSystem;WebInspector.TempFile=function()
{this._fileEntry=null;this._writer=null;}
WebInspector.TempFile.create=function(dirPath,name)
{var file=new WebInspector.TempFile();function requestTempFileSystem()
{return new Promise(window.requestFileSystem.bind(window,window.TEMPORARY,10));}
function getDirectoryEntry(fs)
{return new Promise(fs.root.getDirectory.bind(fs.root,dirPath,{create:true}));}
function getFileEntry(dir)
{return new Promise(dir.getFile.bind(dir,name,{create:true}));}
function createFileWriter(fileEntry)
{file._fileEntry=fileEntry;return new Promise(fileEntry.createWriter.bind(fileEntry));}
function truncateFile(writer)
{if(!writer.length){file._writer=writer;return Promise.resolve(file);}
function truncate(fulfill,reject)
{writer.onwriteend=fulfill;writer.onerror=reject;writer.truncate(0);}
function didTruncate()
{file._writer=writer;writer.onwriteend=null;writer.onerror=null;return Promise.resolve(file);}
function onTruncateError(e)
{writer.onwriteend=null;writer.onerror=null;throw e;}
return new Promise(truncate).then(didTruncate,onTruncateError);}
return WebInspector.TempFile.ensureTempStorageCleared().then(requestTempFileSystem).then(getDirectoryEntry).then(getFileEntry).then(createFileWriter).then(truncateFile);}
WebInspector.TempFile.prototype={write:function(strings,callback)
{var blob=new Blob(strings,{type:"text/plain"});this._writer.onerror=function(e)
{WebInspector.console.error("Failed to write into a temp file: "+e.target.error.message);callback(-1);}
this._writer.onwriteend=function(e)
{callback(e.target.length);}
this._writer.write(blob);},finishWriting:function()
{this._writer=null;},read:function(callback)
{this.readRange(undefined,undefined,callback);},readRange:function(startOffset,endOffset,callback)
{function didGetFile(file)
{var reader=new FileReader();if(typeof startOffset==="number"||typeof endOffset==="number")
file=file.slice((startOffset),(endOffset));reader.onloadend=function(e)
{callback((this.result));};reader.onerror=function(error)
{WebInspector.console.error("Failed to read from temp file: "+error.message);};reader.readAsText(file);}
function didFailToGetFile(error)
{WebInspector.console.error("Failed to load temp file: "+error.message);callback(null);}
this._fileEntry.file(didGetFile,didFailToGetFile);},copyToOutputStream:function(outputStream,delegate)
{function didGetFile(file)
{var reader=new WebInspector.ChunkedFileReader(file,10*1000*1000,delegate);reader.start(outputStream);}
function didFailToGetFile(error)
{WebInspector.console.error("Failed to load temp file: "+error.message);outputStream.close();}
this._fileEntry.file(didGetFile,didFailToGetFile);},remove:function()
{if(this._fileEntry)
this._fileEntry.remove(function(){});}}
WebInspector.DeferredTempFile=function(dirPath,name)
{this._chunks=[];this._tempFile=null;this._isWriting=false;this._finishCallback=null;this._finishedWriting=false;this._callsPendingOpen=[];this._pendingReads=[];WebInspector.TempFile.create(dirPath,name).then(this._didCreateTempFile.bind(this),this._failedToCreateTempFile.bind(this));}
WebInspector.DeferredTempFile.prototype={write:function(strings,callback)
{if(this._finishCallback)
throw new Error("No writes are allowed after close.");this._chunks.push({strings:strings,callback:callback||null});if(this._tempFile&&!this._isWriting)
this._writeNextChunk();},finishWriting:function(callback)
{this._finishCallback=callback;if(this._finishedWriting)
callback(this._tempFile);else if(!this._isWriting&&!this._chunks.length)
this._notifyFinished();},_failedToCreateTempFile:function(e)
{WebInspector.console.error("Failed to create temp file "+e.code+" : "+e.message);this._notifyFinished();},_didCreateTempFile:function(tempFile)
{this._tempFile=tempFile;var callsPendingOpen=this._callsPendingOpen;this._callsPendingOpen=null;for(var i=0;i<callsPendingOpen.length;++i)
callsPendingOpen[i]();if(this._chunks.length)
this._writeNextChunk();},_writeNextChunk:function()
{if(!this._tempFile)
return;var chunk=this._chunks.shift();this._isWriting=true;this._tempFile.write((chunk.strings),this._didWriteChunk.bind(this,chunk.callback));},_didWriteChunk:function(callback,size)
{this._isWriting=false;if(size===-1){this._tempFile=null;this._notifyFinished();return;}
if(callback)
callback(size);if(this._chunks.length)
this._writeNextChunk();else if(this._finishCallback)
this._notifyFinished();},_notifyFinished:function()
{this._finishedWriting=true;if(this._tempFile)
this._tempFile.finishWriting();var chunks=this._chunks;this._chunks=[];for(var i=0;i<chunks.length;++i){if(chunks[i].callback)
chunks[i].callback(-1);}
if(this._finishCallback)
this._finishCallback(this._tempFile);var pendingReads=this._pendingReads;this._pendingReads=[];for(var i=0;i<pendingReads.length;++i)
pendingReads[i]();},readRange:function(startOffset,endOffset,callback)
{if(!this._finishedWriting){this._pendingReads.push(this.readRange.bind(this,startOffset,endOffset,callback));return;}
if(!this._tempFile){callback(null);return;}
this._tempFile.readRange(startOffset,endOffset,callback);},copyToOutputStream:function(outputStream,delegate)
{if(!this._finishedWriting){this._pendingReads.push(this.copyToOutputStream.bind(this,outputStream,delegate));return;}
if(this._tempFile)
this._tempFile.copyToOutputStream(outputStream,delegate);},remove:function()
{if(this._callsPendingOpen){this._callsPendingOpen.push(this.remove.bind(this));return;}
if(this._tempFile)
this._tempFile.remove();this._tempFile=null;}}
WebInspector.TempFile._clearTempStorage=function(fulfill,reject)
{function handleError(event)
{WebInspector.console.error(WebInspector.UIString("Failed to clear temp storage: %s",event.data));reject(event.data);}
function handleMessage(event)
{if(event.data.type==="tempStorageCleared"){if(event.data.error)
WebInspector.console.error(event.data.error);else
fulfill(undefined);return;}
reject(event.data);}
try{var worker=new WebInspector.Worker("temp_storage_shared_worker","TempStorageCleaner");worker.onerror=handleError;worker.onmessage=handleMessage;}catch(e){if(e.name==="URLMismatchError")
console.log("Shared worker wasn't started due to url difference. "+e);else
throw e;}}
WebInspector.TempFile.ensureTempStorageCleared=function()
{if(!WebInspector.TempFile._storageCleanerPromise)
WebInspector.TempFile._storageCleanerPromise=new Promise(WebInspector.TempFile._clearTempStorage);return WebInspector.TempFile._storageCleanerPromise;}
WebInspector.TempFileBackingStorage=function(dirName)
{this._dirName=dirName;this.reset();}
WebInspector.TempFileBackingStorage.Chunk;WebInspector.TempFileBackingStorage.prototype={appendString:function(string)
{this._strings.push(string);this._stringsLength+=string.length;var flushStringLength=10*1024*1024;if(this._stringsLength>flushStringLength)
this._flush(false);},appendAccessibleString:function(string)
{this._flush(false);this._strings.push(string);var chunk=(this._flush(true));function readString(chunk,file)
{if(chunk.string)
return(Promise.resolve(chunk.string));console.assert(chunk.endOffset);if(!chunk.endOffset)
return Promise.reject("Nor string nor offset to the string in the file were found.");function readRange(fulfill,reject)
{file.readRange(chunk.startOffset,chunk.endOffset,fulfill);}
return new Promise(readRange);}
return readString.bind(null,chunk,this._file);},_flush:function(createChunk)
{if(!this._strings.length)
return null;var chunk=null;if(createChunk){console.assert(this._strings.length===1);chunk={string:this._strings[0],startOffset:0,endOffset:0};}
function didWrite(chunk,fileSize)
{if(fileSize===-1)
return;if(chunk){chunk.startOffset=this._fileSize;chunk.endOffset=fileSize;chunk.string=null;}
this._fileSize=fileSize;}
this._file.write(this._strings,didWrite.bind(this,chunk));this._strings=[];this._stringsLength=0;return chunk;},finishWriting:function()
{this._flush(false);this._file.finishWriting(function(){});},reset:function()
{if(this._file)
this._file.remove();this._file=new WebInspector.DeferredTempFile(this._dirName,String(Date.now()));this._strings=[];this._stringsLength=0;this._fileSize=0;},writeToStream:function(outputStream,delegate)
{this._file.copyToOutputStream(outputStream,delegate);}};WebInspector.BreakpointsSidebarPaneBase=function(title)
{WebInspector.SidebarPane.call(this,title);this.registerRequiredCSS("components/breakpointsList.css");this.listElement=createElement("ol");this.listElement.className="breakpoint-list";this.emptyElement=createElement("div");this.emptyElement.className="info";this.emptyElement.textContent=WebInspector.UIString("No Breakpoints");this.element.appendChild(this.emptyElement);}
WebInspector.BreakpointsSidebarPaneBase.prototype={addListElement:function(element,beforeNode)
{if(beforeNode){this.listElement.insertBefore(element,beforeNode);}else{if(!this.listElement.firstChild){this.element.removeChild(this.emptyElement);this.element.appendChild(this.listElement);}
this.listElement.appendChild(element);}},removeListElement:function(element)
{this.listElement.removeChild(element);if(!this.listElement.firstChild){this.element.removeChild(this.listElement);this.element.appendChild(this.emptyElement);}},reset:function()
{this.listElement.removeChildren();if(this.listElement.parentElement){this.element.removeChild(this.listElement);this.element.appendChild(this.emptyElement);}},__proto__:WebInspector.SidebarPane.prototype};WebInspector.CustomPreviewSection=function(object)
{this._sectionElement=createElementWithClass("span","custom-expandable-section");this._object=object;this._expanded=false;this._cachedContent=null;var customPreview=object.customPreview();try{var headerJSON=JSON.parse(customPreview.header);}catch(e){WebInspector.console.error("Broken formatter: header is invalid json "+e);return;}
this._header=this._renderJSONMLTag(headerJSON);if(this._header.nodeType===Node.TEXT_NODE){WebInspector.console.error("Broken formatter: header should be an element node.");return;}
if(customPreview.hasBody){this._header.classList.add("custom-expandable-section-header");this._header.addEventListener("click",this._onClick.bind(this),false);}
this._sectionElement.appendChild(this._header);}
WebInspector.CustomPreviewComponent=function(object)
{this._object=object;this._customPreviewSection=new WebInspector.CustomPreviewSection(object);this.element=createElementWithClass("span","source-code");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"components/customPreviewSection.css");this.element.addEventListener("contextmenu",this._contextMenuEventFired.bind(this),false);shadowRoot.appendChild(this._customPreviewSection.element());}
WebInspector.CustomPreviewComponent.prototype={expandIfPossible:function()
{if(this._object.customPreview().hasBody&&this._customPreviewSection)
this._customPreviewSection._loadBody();},_contextMenuEventFired:function(event)
{var contextMenu=new WebInspector.ContextMenu(event);if(this._customPreviewSection)
contextMenu.appendItem(WebInspector.UIString.capitalize("Show as Javascript ^object"),this._disassemble.bind(this));contextMenu.appendApplicableItems(this._object);contextMenu.show();},_disassemble:function()
{this.element.shadowRoot.textContent="";this._customPreviewSection=null;this.element.shadowRoot.appendChild(WebInspector.ObjectPropertiesSection.defaultObjectPresentation(this._object));}}
WebInspector.CustomPreviewSection._tagsWhiteList=new Set(["span","div","ol","li","table","tr","td"]);WebInspector.CustomPreviewSection.prototype={element:function()
{return this._sectionElement;},_renderJSONMLTag:function(jsonML)
{if(!Array.isArray(jsonML))
return createTextNode(jsonML+"");var array=(jsonML);if(array[0]==="object")
return this._layoutObjectTag(array);else
return this._renderElement(array);},_renderElement:function(object)
{var tagName=object.shift();if(!WebInspector.CustomPreviewSection._tagsWhiteList.has(tagName)){WebInspector.console.error("Broken formatter: element "+tagName+" is not allowed!");return createElement("span");}
var element=createElement((tagName));if((typeof object[0]=="object")&&!Array.isArray(object[0])){var attributes=object.shift();for(var key in attributes){var value=attributes[key];if((key!=="style")||(typeof value!=="string"))
continue;element.setAttribute(key,value);}}
this._appendJsonMLTags(element,object);return element;},_layoutObjectTag:function(objectTag)
{objectTag.shift();var attributes=objectTag.shift();var remoteObject=this._object.target().runtimeModel.createRemoteObject((attributes));if(remoteObject.customPreview())
return(new WebInspector.CustomPreviewSection(remoteObject)).element();var sectionElement=WebInspector.ObjectPropertiesSection.defaultObjectPresentation(remoteObject);sectionElement.classList.toggle("custom-expandable-section-standard-section",remoteObject.hasChildren);return sectionElement;},_appendJsonMLTags:function(parentElement,jsonMLTags)
{for(var i=0;i<jsonMLTags.length;++i)
parentElement.appendChild(this._renderJSONMLTag(jsonMLTags[i]));},_onClick:function(event)
{event.consume(true);if(this._cachedContent)
this._toggleExpand();else
this._loadBody();},_toggleExpand:function()
{this._expanded=!this._expanded;this._header.classList.toggle("expanded",this._expanded);this._cachedContent.classList.toggle("hidden",!this._expanded);},_loadBody:function()
{function load(bindRemoteObject,formatter,config)
{function substituteObjectTagsInCustomPreview(jsonMLObject)
{if(!jsonMLObject||(typeof jsonMLObject!=="object")||(typeof jsonMLObject.splice!=="function"))
return;var obj=jsonMLObject.length;if(!(typeof obj==="number"&&obj>>>0===obj&&(obj>0||1/obj>0)))
return;var startIndex=1;if(jsonMLObject[0]==="object"){var attributes=jsonMLObject[1];var originObject=attributes["object"];var config=attributes["config"];if(typeof originObject==="undefined")
throw"Illegal format: obligatory attribute \"object\" isn't specified";jsonMLObject[1]=bindRemoteObject(originObject,config);startIndex=2;}
for(var i=startIndex;i<jsonMLObject.length;++i)
substituteObjectTagsInCustomPreview(jsonMLObject[i]);}
try{var body=formatter.body(this,config);substituteObjectTagsInCustomPreview(body);return body;}catch(e){console.error("Custom Formatter Failed: "+e);return null;}}
var customPreview=this._object.customPreview();var args=[{objectId:customPreview.bindRemoteObjectFunctionId},{objectId:customPreview.formatterObjectId}];if(customPreview.configObjectId)
args.push({objectId:customPreview.configObjectId});this._object.callFunctionJSON(load,args,onBodyLoaded.bind(this));function onBodyLoaded(bodyJsonML)
{if(!bodyJsonML)
return;this._cachedContent=this._renderJSONMLTag(bodyJsonML);this._sectionElement.appendChild(this._cachedContent);this._toggleExpand();}}};WebInspector.DataSaverInfobar=function()
{WebInspector.Infobar.call(this,WebInspector.Infobar.Type.Warning,WebInspector.UIString("Consider disabling Chrome Data Saver while debugging."),WebInspector.settings.moduleSetting("disableDataSaverInfobar"));var message=this.createDetailsRowMessage();message.createTextChild("More information about ");message.appendChild(WebInspector.linkifyURLAsNode("https://support.google.com/chrome/answer/2392284?hl=en","Chrome Data Saver",undefined,true));message.createTextChild(".");}
WebInspector.DataSaverInfobar._infobars=[];WebInspector.DataSaverInfobar.maybeShowInPanel=function(panel)
{if(Runtime.queryParam("remoteFrontend")){var infobar=new WebInspector.DataSaverInfobar();WebInspector.DataSaverInfobar._infobars.push(infobar);panel.showInfobar(infobar);}}
WebInspector.DataSaverInfobar.prototype={dispose:function()
{for(var infobar of WebInspector.DataSaverInfobar._infobars)
WebInspector.Infobar.prototype.dispose.call(infobar);},__proto__:WebInspector.Infobar.prototype};WebInspector.DOMBreakpointsSidebarPane=function()
{WebInspector.BreakpointsSidebarPaneBase.call(this,WebInspector.UIString("DOM Breakpoints"));this._domBreakpointsSetting=WebInspector.settings.createLocalSetting("domBreakpoints",[]);this.listElement.classList.add("dom-breakpoints-list");this._breakpointElements={};this._breakpointTypes={SubtreeModified:"subtree-modified",AttributeModified:"attribute-modified",NodeRemoved:"node-removed"};this._breakpointTypeLabels={};this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified]=WebInspector.UIString("Subtree Modified");this._breakpointTypeLabels[this._breakpointTypes.AttributeModified]=WebInspector.UIString("Attribute Modified");this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved]=WebInspector.UIString("Node Removed");this._contextMenuLabels={};this._contextMenuLabels[this._breakpointTypes.SubtreeModified]=WebInspector.UIString.capitalize("Subtree ^modifications");this._contextMenuLabels[this._breakpointTypes.AttributeModified]=WebInspector.UIString.capitalize("Attributes ^modifications");this._contextMenuLabels[this._breakpointTypes.NodeRemoved]=WebInspector.UIString.capitalize("Node ^removal");WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,this._inspectedURLChanged,this);WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.NodeRemoved,this._nodeRemoved,this);}
WebInspector.DOMBreakpointsSidebarPane.Marker="breakpoint-marker";WebInspector.DOMBreakpointsSidebarPane.prototype={_inspectedURLChanged:function(event)
{this._breakpointElements={};this.reset();var url=(event.data);this._inspectedURL=url.removeURLFragment();},populateNodeContextMenu:function(node,contextMenu,createSubMenu)
{if(node.pseudoType())
return;var nodeBreakpoints=this._nodeBreakpoints(node);function toggleBreakpoint(type)
{if(!nodeBreakpoints[type])
this._setBreakpoint(node,type,true);else
this._removeBreakpoint(node,type);this._saveBreakpoints();}
var breakpointsMenu=createSubMenu?contextMenu.appendSubMenuItem(WebInspector.UIString("Break on...")):contextMenu;for(var key in this._breakpointTypes){var type=this._breakpointTypes[key];var label=this._contextMenuLabels[type];breakpointsMenu.appendCheckboxItem(label,toggleBreakpoint.bind(this,type),nodeBreakpoints[type]);}},_nodeBreakpoints:function(node)
{var nodeBreakpoints={};for(var id in this._breakpointElements){var element=this._breakpointElements[id];if(element._node===node&&element._checkboxElement.checked)
nodeBreakpoints[element._type]=true;}
return nodeBreakpoints;},hasBreakpoints:function(node)
{for(var id in this._breakpointElements){var element=this._breakpointElements[id];if(element._node===node&&element._checkboxElement.checked)
return true;}
return false;},createBreakpointHitStatusMessage:function(details,callback)
{var auxData=(details.auxData);var domModel=WebInspector.DOMModel.fromTarget(details.target());if(!domModel)
return;if(auxData.type===this._breakpointTypes.SubtreeModified){var targetNodeObject=details.target().runtimeModel.createRemoteObject(auxData["targetNode"]);domModel.pushObjectAsNodeToFrontend(targetNodeObject,didPushNodeToFrontend.bind(this));}else{this._doCreateBreakpointHitStatusMessage(auxData,domModel.nodeForId(auxData.nodeId),null,callback);}
function didPushNodeToFrontend(targetNode)
{if(targetNode)
targetNodeObject.release();this._doCreateBreakpointHitStatusMessage(auxData,domModel.nodeForId(auxData.nodeId),targetNode,callback);}},_doCreateBreakpointHitStatusMessage:function(auxData,node,targetNode,callback)
{var message;var typeLabel=this._breakpointTypeLabels[auxData.type];var linkifiedNode=WebInspector.DOMPresentationUtils.linkifyNodeReference(node);var substitutions=[typeLabel,linkifiedNode];var targetNodeLink="";if(targetNode)
targetNodeLink=WebInspector.DOMPresentationUtils.linkifyNodeReference(targetNode);if(auxData.type===this._breakpointTypes.SubtreeModified){if(auxData.insertion){if(targetNode!==node){message="Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";substitutions.push(targetNodeLink);}else
message="Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";}else{message="Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";substitutions.push(targetNodeLink);}}else
message="Paused on a \"%s\" breakpoint set on %s.";var element=WebInspector.formatLocalized(message,substitutions);callback(element);},_nodeRemoved:function(event)
{var node=event.data.node;this._removeBreakpointsForNode(event.data.node);var children=node.children();if(!children)
return;for(var i=0;i<children.length;++i)
this._removeBreakpointsForNode(children[i]);this._saveBreakpoints();},_removeBreakpointsForNode:function(node)
{for(var id in this._breakpointElements){var element=this._breakpointElements[id];if(element._node===node)
this._removeBreakpoint(element._node,element._type);}},_setBreakpoint:function(node,type,enabled)
{var breakpointId=this._createBreakpointId(node.id,type);var breakpointElement=this._breakpointElements[breakpointId];if(!breakpointElement){breakpointElement=this._createBreakpointElement(node,type,enabled);this._breakpointElements[breakpointId]=breakpointElement;}else{breakpointElement._checkboxElement.checked=enabled;}
if(enabled)
node.target().domdebuggerAgent().setDOMBreakpoint(node.id,type);node.setMarker(WebInspector.DOMBreakpointsSidebarPane.Marker,true);},_createBreakpointElement:function(node,type,enabled)
{var element=createElement("li");element._node=node;element._type=type;element.addEventListener("contextmenu",this._contextMenu.bind(this,node,type),true);var checkboxLabel=createCheckboxLabel("",enabled);checkboxLabel.addEventListener("click",this._checkboxClicked.bind(this,node,type),false);element._checkboxElement=checkboxLabel.checkboxElement;element.appendChild(checkboxLabel);var labelElement=createElementWithClass("div","dom-breakpoint");element.appendChild(labelElement);var linkifiedNode=WebInspector.DOMPresentationUtils.linkifyNodeReference(node);linkifiedNode.classList.add("monospace");linkifiedNode.style.display="block";labelElement.appendChild(linkifiedNode);var description=createElement("div");description.textContent=this._breakpointTypeLabels[type];labelElement.appendChild(description);var currentElement=this.listElement.firstChild;while(currentElement){if(currentElement._type&¤tElement._type<element._type)
break;currentElement=currentElement.nextSibling;}
this.addListElement(element,currentElement);return element;},_removeAllBreakpoints:function()
{for(var id in this._breakpointElements){var element=this._breakpointElements[id];this._removeBreakpoint(element._node,element._type);}
this._saveBreakpoints();},_removeBreakpoint:function(node,type)
{var breakpointId=this._createBreakpointId(node.id,type);var element=this._breakpointElements[breakpointId];if(!element)
return;this.removeListElement(element);delete this._breakpointElements[breakpointId];if(element._checkboxElement.checked)
node.target().domdebuggerAgent().removeDOMBreakpoint(node.id,type);node.setMarker(WebInspector.DOMBreakpointsSidebarPane.Marker,this.hasBreakpoints(node)?true:null);},_contextMenu:function(node,type,event)
{var contextMenu=new WebInspector.ContextMenu(event);function removeBreakpoint()
{this._removeBreakpoint(node,type);this._saveBreakpoints();}
contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"),removeBreakpoint.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all DOM breakpoints"),this._removeAllBreakpoints.bind(this));contextMenu.show();},_checkboxClicked:function(node,type,event)
{if(event.target.checked)
node.target().domdebuggerAgent().setDOMBreakpoint(node.id,type);else
node.target().domdebuggerAgent().removeDOMBreakpoint(node.id,type);this._saveBreakpoints();},highlightBreakpoint:function(auxData)
{var breakpointId=this._createBreakpointId(auxData.nodeId,auxData.type);var element=this._breakpointElements[breakpointId];if(!element)
return;this.expand();element.classList.add("breakpoint-hit");this._highlightedElement=element;},clearBreakpointHighlight:function()
{if(this._highlightedElement){this._highlightedElement.classList.remove("breakpoint-hit");delete this._highlightedElement;}},_createBreakpointId:function(nodeId,type)
{return nodeId+":"+type;},_saveBreakpoints:function()
{var breakpoints=[];var storedBreakpoints=this._domBreakpointsSetting.get();for(var i=0;i<storedBreakpoints.length;++i){var breakpoint=storedBreakpoints[i];if(breakpoint.url!==this._inspectedURL)
breakpoints.push(breakpoint);}
for(var id in this._breakpointElements){var element=this._breakpointElements[id];breakpoints.push({url:this._inspectedURL,path:element._node.path(),type:element._type,enabled:element._checkboxElement.checked});}
this._domBreakpointsSetting.set(breakpoints);},restoreBreakpoints:function(domModel)
{var pathToBreakpoints={};function didPushNodeByPathToFrontend(path,nodeId)
{var node=nodeId?domModel.nodeForId(nodeId):null;if(!node)
return;var breakpoints=pathToBreakpoints[path];for(var i=0;i<breakpoints.length;++i)
this._setBreakpoint(node,breakpoints[i].type,breakpoints[i].enabled);}
var breakpoints=this._domBreakpointsSetting.get();for(var i=0;i<breakpoints.length;++i){var breakpoint=breakpoints[i];if(breakpoint.url!==this._inspectedURL)
continue;var path=breakpoint.path;if(!pathToBreakpoints[path]){pathToBreakpoints[path]=[];domModel.pushNodeByPathToFrontend(path,didPushNodeByPathToFrontend.bind(this,path));}
pathToBreakpoints[path].push(breakpoint);}},createProxy:function(panel)
{var proxy=new WebInspector.DOMBreakpointsSidebarPane.Proxy(this,panel);if(!this._proxies)
this._proxies=[];this._proxies.push(proxy);return proxy;},onContentReady:function()
{for(var i=0;i!=this._proxies.length;i++)
this._proxies[i].onContentReady();},__proto__:WebInspector.BreakpointsSidebarPaneBase.prototype}
WebInspector.DOMBreakpointsSidebarPane.Proxy=function(pane,panel)
{WebInspector.SidebarPane.call(this,pane.title());this.registerRequiredCSS("components/breakpointsList.css");this._wrappedPane=pane;this._panel=panel;}
WebInspector.DOMBreakpointsSidebarPane.Proxy.prototype={expand:function()
{this._wrappedPane.expand();},onContentReady:function()
{if(this._panel.isShowing())
this._reattachBody();WebInspector.SidebarPane.prototype.onContentReady.call(this);},wasShown:function()
{WebInspector.SidebarPane.prototype.wasShown.call(this);this._reattachBody();},_reattachBody:function()
{if(this._wrappedPane.element.parentNode!==this.element)
this._wrappedPane.show(this.element);},__proto__:WebInspector.SidebarPane.prototype}
WebInspector.domBreakpointsSidebarPane;;WebInspector.DOMPresentationUtils={}
WebInspector.DOMPresentationUtils.decorateNodeLabel=function(node,parentElement)
{var originalNode=node;var isPseudo=node.nodeType()===Node.ELEMENT_NODE&&node.pseudoType();if(isPseudo&&node.parentNode)
node=node.parentNode;var title=node.nodeNameInCorrectCase();var nameElement=parentElement.createChild("span","node-label-name");nameElement.textContent=title;var idAttribute=node.getAttribute("id");if(idAttribute){var idElement=parentElement.createChild("span","node-label-id");var part="#"+idAttribute;title+=part;idElement.createTextChild(part);nameElement.classList.add("extra");}
var classAttribute=node.getAttribute("class");if(classAttribute){var classes=classAttribute.split(/\s+/);var foundClasses={};if(classes.length){var classesElement=parentElement.createChild("span","extra node-label-class");for(var i=0;i<classes.length;++i){var className=classes[i];if(className&&!(className in foundClasses)){var part="."+className;title+=part;classesElement.createTextChild(part);foundClasses[className]=true;}}}}
if(isPseudo){var pseudoElement=parentElement.createChild("span","extra node-label-pseudo");var pseudoText="::"+originalNode.pseudoType();pseudoElement.createTextChild(pseudoText);title+=pseudoText;}
parentElement.title=title;}
WebInspector.DOMPresentationUtils.createSpansForNodeTitle=function(container,nodeTitle)
{var match=nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);container.createChild("span","webkit-html-tag-name").textContent=match[1];if(match[2])
container.createChild("span","webkit-html-attribute-value").textContent=match[2];if(match[3])
container.createChild("span","webkit-html-attribute-name").textContent=match[3];}
WebInspector.DOMPresentationUtils.linkifyNodeReference=function(node,idref)
{if(!node)
return createTextNode(WebInspector.UIString("<node>"));var root=createElementWithClass("span","monospace");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(root,"components/domUtils.css");var link=shadowRoot.createChild("div","node-link");if(idref)
link.createChild("span","node-label-id").createTextChild("#"+idref);else
WebInspector.DOMPresentationUtils.decorateNodeLabel(node,link);link.addEventListener("click",WebInspector.Revealer.reveal.bind(WebInspector.Revealer,node,undefined),false);link.addEventListener("mouseover",node.highlight.bind(node,undefined,undefined),false);link.addEventListener("mouseleave",WebInspector.DOMModel.hideDOMNodeHighlight.bind(WebInspector.DOMModel),false);return root;}
WebInspector.DOMPresentationUtils.linkifyDeferredNodeReference=function(deferredNode)
{var root=createElement("div");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(root,"components/domUtils.css");var link=shadowRoot.createChild("div","node-link");link.createChild("content");link.addEventListener("click",deferredNode.resolve.bind(deferredNode,onDeferredNodeResolved),false);link.addEventListener("mousedown",consumeEvent,false);function onDeferredNodeResolved(node)
{WebInspector.Revealer.reveal(node);}
return root;}
WebInspector.DOMPresentationUtils.buildImagePreviewContents=function(target,originalImageURL,showDimensions,userCallback,precomputedFeatures)
{var resource=target.resourceTreeModel.resourceForURL(originalImageURL);var imageURL=originalImageURL;if(!isImageResource(resource)&&precomputedFeatures&&precomputedFeatures.currentSrc){imageURL=precomputedFeatures.currentSrc;resource=target.resourceTreeModel.resourceForURL(imageURL);}
if(!isImageResource(resource)){userCallback();return;}
var imageElement=createElement("img");imageElement.addEventListener("load",buildContent,false);imageElement.addEventListener("error",errorCallback,false);resource.populateImageSource(imageElement);function errorCallback()
{userCallback();}
function isImageResource(resource)
{return!!resource&&resource.resourceType()===WebInspector.resourceTypes.Image;}
function buildContent()
{var container=createElement("table");container.className="image-preview-container";var naturalWidth=precomputedFeatures?precomputedFeatures.naturalWidth:imageElement.naturalWidth;var naturalHeight=precomputedFeatures?precomputedFeatures.naturalHeight:imageElement.naturalHeight;var offsetWidth=precomputedFeatures?precomputedFeatures.offsetWidth:naturalWidth;var offsetHeight=precomputedFeatures?precomputedFeatures.offsetHeight:naturalHeight;var description;if(showDimensions){if(offsetHeight===naturalHeight&&offsetWidth===naturalWidth)
description=WebInspector.UIString("%d \xd7 %d pixels",offsetWidth,offsetHeight);else
description=WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)",offsetWidth,offsetHeight,naturalWidth,naturalHeight);}
container.createChild("tr").createChild("td","image-container").appendChild(imageElement);if(description)
container.createChild("tr").createChild("td").createChild("span","description").textContent=description;if(imageURL!==originalImageURL)
container.createChild("tr").createChild("td").createChild("span","description").textContent=String.sprintf("currentSrc: %s",imageURL.trimMiddle(100));userCallback(container);}}
WebInspector.DOMPresentationUtils.buildStackTracePreviewContents=function(target,linkifier,stackTrace)
{var element=createElement("span");element.style.display="inline-block";var shadowRoot=WebInspector.createShadowRootWithCoreStyles(element,"components/domUtils.css");var contentElement=shadowRoot.createChild("table","stack-preview-container");function appendStackTrace(stackTrace)
{for(var stackFrame of stackTrace.callFrames){var row=createElement("tr");row.createChild("td","function-name").textContent=WebInspector.beautifyFunctionName(stackFrame.functionName);row.createChild("td").textContent=" @ ";row.createChild("td").appendChild(linkifier.linkifyConsoleCallFrame(target,stackFrame));contentElement.appendChild(row);}}
if(!stackTrace)
return element;appendStackTrace(stackTrace);var asyncStackTrace=stackTrace.parent;while(asyncStackTrace){if(!asyncStackTrace.callFrames.length){asyncStackTrace=asyncStackTrace.parent;continue;}
var row=contentElement.createChild("tr");row.createChild("td","stack-preview-async-description").textContent=WebInspector.asyncStackTraceLabel(asyncStackTrace.description);row.createChild("td");row.createChild("td");appendStackTrace(asyncStackTrace);asyncStackTrace=asyncStackTrace.parent;}
return element;}
WebInspector.DOMPresentationUtils.fullQualifiedSelector=function(node,justSelector)
{if(node.nodeType()!==Node.ELEMENT_NODE)
return node.localName()||node.nodeName().toLowerCase();return WebInspector.DOMPresentationUtils.cssPath(node,justSelector);}
WebInspector.DOMPresentationUtils.simpleSelector=function(node)
{var lowerCaseName=node.localName()||node.nodeName().toLowerCase();if(node.nodeType()!==Node.ELEMENT_NODE)
return lowerCaseName;if(lowerCaseName==="input"&&node.getAttribute("type")&&!node.getAttribute("id")&&!node.getAttribute("class"))
return lowerCaseName+"[type=\""+node.getAttribute("type")+"\"]";if(node.getAttribute("id"))
return lowerCaseName+"#"+node.getAttribute("id");if(node.getAttribute("class"))
return(lowerCaseName==="div"?"":lowerCaseName)+"."+node.getAttribute("class").trim().replace(/\s+/g,".");return lowerCaseName;}
WebInspector.DOMPresentationUtils.cssPath=function(node,optimized)
{if(node.nodeType()!==Node.ELEMENT_NODE)
return"";var steps=[];var contextNode=node;while(contextNode){var step=WebInspector.DOMPresentationUtils._cssPathStep(contextNode,!!optimized,contextNode===node);if(!step)
break;steps.push(step);if(step.optimized)
break;contextNode=contextNode.parentNode;}
steps.reverse();return steps.join(" > ");}
WebInspector.DOMPresentationUtils._cssPathStep=function(node,optimized,isTargetNode)
{if(node.nodeType()!==Node.ELEMENT_NODE)
return null;var id=node.getAttribute("id");if(optimized){if(id)
return new WebInspector.DOMNodePathStep(idSelector(id),true);var nodeNameLower=node.nodeName().toLowerCase();if(nodeNameLower==="body"||nodeNameLower==="head"||nodeNameLower==="html")
return new WebInspector.DOMNodePathStep(node.nodeNameInCorrectCase(),true);}
var nodeName=node.nodeNameInCorrectCase();if(id)
return new WebInspector.DOMNodePathStep(nodeName+idSelector(id),true);var parent=node.parentNode;if(!parent||parent.nodeType()===Node.DOCUMENT_NODE)
return new WebInspector.DOMNodePathStep(nodeName,true);function prefixedElementClassNames(node)
{var classAttribute=node.getAttribute("class");if(!classAttribute)
return[];return classAttribute.split(/\s+/g).filter(Boolean).map(function(name){return"$"+name;});}
function idSelector(id)
{return"#"+escapeIdentifierIfNeeded(id);}
function escapeIdentifierIfNeeded(ident)
{if(isCSSIdentifier(ident))
return ident;var shouldEscapeFirst=/^(?:[0-9]|-[0-9-]?)/.test(ident);var lastIndex=ident.length-1;return ident.replace(/./g,function(c,i){return((shouldEscapeFirst&&i===0)||!isCSSIdentChar(c))?escapeAsciiChar(c,i===lastIndex):c;});}
function escapeAsciiChar(c,isLast)
{return"\\"+toHexByte(c)+(isLast?"":" ");}
function toHexByte(c)
{var hexByte=c.charCodeAt(0).toString(16);if(hexByte.length===1)
hexByte="0"+hexByte;return hexByte;}
function isCSSIdentChar(c)
{if(/[a-zA-Z0-9_-]/.test(c))
return true;return c.charCodeAt(0)>=0xA0;}
function isCSSIdentifier(value)
{return/^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);}
var prefixedOwnClassNamesArray=prefixedElementClassNames(node);var needsClassNames=false;var needsNthChild=false;var ownIndex=-1;var elementIndex=-1;var siblings=parent.children();for(var i=0;(ownIndex===-1||!needsNthChild)&&i<siblings.length;++i){var sibling=siblings[i];if(sibling.nodeType()!==Node.ELEMENT_NODE)
continue;elementIndex+=1;if(sibling===node){ownIndex=elementIndex;continue;}
if(needsNthChild)
continue;if(sibling.nodeNameInCorrectCase()!==nodeName)
continue;needsClassNames=true;var ownClassNames=prefixedOwnClassNamesArray.keySet();var ownClassNameCount=0;for(var name in ownClassNames)
++ownClassNameCount;if(ownClassNameCount===0){needsNthChild=true;continue;}
var siblingClassNamesArray=prefixedElementClassNames(sibling);for(var j=0;j<siblingClassNamesArray.length;++j){var siblingClass=siblingClassNamesArray[j];if(!ownClassNames.hasOwnProperty(siblingClass))
continue;delete ownClassNames[siblingClass];if(!--ownClassNameCount){needsNthChild=true;break;}}}
var result=nodeName;if(isTargetNode&&nodeName.toLowerCase()==="input"&&node.getAttribute("type")&&!node.getAttribute("id")&&!node.getAttribute("class"))
result+="[type=\""+node.getAttribute("type")+"\"]";if(needsNthChild){result+=":nth-child("+(ownIndex+1)+")";}else if(needsClassNames){for(var prefixedName in prefixedOwnClassNamesArray.keySet())
result+="."+escapeIdentifierIfNeeded(prefixedName.substr(1));}
return new WebInspector.DOMNodePathStep(result,false);}
WebInspector.DOMPresentationUtils.xPath=function(node,optimized)
{if(node.nodeType()===Node.DOCUMENT_NODE)
return"/";var steps=[];var contextNode=node;while(contextNode){var step=WebInspector.DOMPresentationUtils._xPathValue(contextNode,optimized);if(!step)
break;steps.push(step);if(step.optimized)
break;contextNode=contextNode.parentNode;}
steps.reverse();return(steps.length&&steps[0].optimized?"":"/")+steps.join("/");}
WebInspector.DOMPresentationUtils._xPathValue=function(node,optimized)
{var ownValue;var ownIndex=WebInspector.DOMPresentationUtils._xPathIndex(node);if(ownIndex===-1)
return null;switch(node.nodeType()){case Node.ELEMENT_NODE:if(optimized&&node.getAttribute("id"))
return new WebInspector.DOMNodePathStep("//*[@id=\""+node.getAttribute("id")+"\"]",true);ownValue=node.localName();break;case Node.ATTRIBUTE_NODE:ownValue="@"+node.nodeName();break;case Node.TEXT_NODE:case Node.CDATA_SECTION_NODE:ownValue="text()";break;case Node.PROCESSING_INSTRUCTION_NODE:ownValue="processing-instruction()";break;case Node.COMMENT_NODE:ownValue="comment()";break;case Node.DOCUMENT_NODE:ownValue="";break;default:ownValue="";break;}
if(ownIndex>0)
ownValue+="["+ownIndex+"]";return new WebInspector.DOMNodePathStep(ownValue,node.nodeType()===Node.DOCUMENT_NODE);}
WebInspector.DOMPresentationUtils._xPathIndex=function(node)
{function areNodesSimilar(left,right)
{if(left===right)
return true;if(left.nodeType()===Node.ELEMENT_NODE&&right.nodeType()===Node.ELEMENT_NODE)
return left.localName()===right.localName();if(left.nodeType()===right.nodeType())
return true;var leftType=left.nodeType()===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:left.nodeType();var rightType=right.nodeType()===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:right.nodeType();return leftType===rightType;}
var siblings=node.parentNode?node.parentNode.children():null;if(!siblings)
return 0;var hasSameNamedElements;for(var i=0;i<siblings.length;++i){if(areNodesSimilar(node,siblings[i])&&siblings[i]!==node){hasSameNamedElements=true;break;}}
if(!hasSameNamedElements)
return 0;var ownIndex=1;for(var i=0;i<siblings.length;++i){if(areNodesSimilar(node,siblings[i])){if(siblings[i]===node)
return ownIndex;++ownIndex;}}
return-1;}
WebInspector.DOMNodePathStep=function(value,optimized)
{this.value=value;this.optimized=optimized||false;}
WebInspector.DOMNodePathStep.prototype={toString:function()
{return this.value;}}
WebInspector.DOMPresentationUtils.MarkerDecorator=function()
{}
WebInspector.DOMPresentationUtils.MarkerDecorator.prototype={decorate:function(node){}}
WebInspector.DOMPresentationUtils.GenericDecorator=function(extension)
{this._title=WebInspector.UIString(extension.title(WebInspector.platform()));this._color=extension.descriptor()["color"];}
WebInspector.DOMPresentationUtils.GenericDecorator.prototype={decorate:function(node)
{return{title:this._title,color:this._color};}};WebInspector.DockController=function(canDock)
{this._canDock=canDock;this._closeButton=new WebInspector.ToolbarButton(WebInspector.UIString("Close"),"delete-toolbar-item");this._closeButton.addEventListener("click",InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost));if(!canDock){this._dockSide=WebInspector.DockController.State.Undocked;this._updateUI();return;}
this._states=[WebInspector.DockController.State.DockedToRight,WebInspector.DockController.State.DockedToBottom,WebInspector.DockController.State.Undocked];this._currentDockStateSetting=WebInspector.settings.moduleSetting("currentDockState");this._currentDockStateSetting.addChangeListener(this._dockSideChanged,this);this._lastDockStateSetting=WebInspector.settings.createSetting("lastDockState","bottom");if(this._states.indexOf(this._currentDockStateSetting.get())===-1)
this._currentDockStateSetting.set("right");if(this._states.indexOf(this._lastDockStateSetting.get())===-1)
this._currentDockStateSetting.set("bottom");}
WebInspector.DockController.State={DockedToBottom:"bottom",DockedToRight:"right",Undocked:"undocked"}
WebInspector.DockController.Events={BeforeDockSideChanged:"BeforeDockSideChanged",DockSideChanged:"DockSideChanged",AfterDockSideChanged:"AfterDockSideChanged"}
WebInspector.DockController.prototype={initialize:function()
{if(!this._canDock)
return;this._titles=[WebInspector.UIString("Dock to right"),WebInspector.UIString("Dock to bottom"),WebInspector.UIString("Undock into separate window")];this._dockSideChanged();},_dockSideChanged:function()
{this.setDockSide(this._currentDockStateSetting.get());},dockSide:function()
{return this._dockSide;},canDock:function()
{return this._canDock;},isVertical:function()
{return this._dockSide===WebInspector.DockController.State.DockedToRight;},setDockSide:function(dockSide)
{if(this._states.indexOf(dockSide)===-1)
dockSide=this._states[0];if(this._dockSide===dockSide)
return;if(this._dockSide)
this._lastDockStateSetting.set(this._dockSide);var eventData={from:this._dockSide,to:dockSide};this.dispatchEventToListeners(WebInspector.DockController.Events.BeforeDockSideChanged,eventData);console.timeStamp("DockController.setIsDocked");this._dockSide=dockSide;this._currentDockStateSetting.set(dockSide);InspectorFrontendHost.setIsDocked(dockSide!==WebInspector.DockController.State.Undocked,this._setIsDockedResponse.bind(this,eventData));this._updateUI();this.dispatchEventToListeners(WebInspector.DockController.Events.DockSideChanged,eventData);},_setIsDockedResponse:function(eventData)
{this.dispatchEventToListeners(WebInspector.DockController.Events.AfterDockSideChanged,eventData);},_updateUI:function()
{var body=document.body;switch(this._dockSide){case WebInspector.DockController.State.DockedToBottom:body.classList.remove("undocked");body.classList.remove("dock-to-right");body.classList.add("dock-to-bottom");break;case WebInspector.DockController.State.DockedToRight:body.classList.remove("undocked");body.classList.add("dock-to-right");body.classList.remove("dock-to-bottom");break;case WebInspector.DockController.State.Undocked:body.classList.add("undocked");body.classList.remove("dock-to-right");body.classList.remove("dock-to-bottom");break;}
this._closeButton.setVisible(this._dockSide!==WebInspector.DockController.State.Undocked);},_toggleDockSide:function()
{if(this._lastDockStateSetting.get()===this._currentDockStateSetting.get()){var index=this._states.indexOf(this._currentDockStateSetting.get())||0;this._lastDockStateSetting.set(this._states[(index+1)%this._states.length]);}
this.setDockSide(this._lastDockStateSetting.get());},__proto__:WebInspector.Object.prototype}
WebInspector.DockController.ToggleDockActionDelegate=function()
{}
WebInspector.DockController.ToggleDockActionDelegate.prototype={handleAction:function(context,actionId)
{WebInspector.dockController._toggleDockSide();return true;}}
WebInspector.DockController.CloseButtonProvider=function()
{}
WebInspector.DockController.CloseButtonProvider.prototype={item:function()
{return WebInspector.dockController._closeButton;}}
WebInspector.dockController;;WebInspector.ExecutionContextSelector=function(targetManager,context)
{targetManager.observeTargets(this);context.addFlavorChangeListener(WebInspector.ExecutionContext,this._executionContextChanged,this);context.addFlavorChangeListener(WebInspector.Target,this._targetChanged,this);targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextCreated,this._onExecutionContextCreated,this);targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextDestroyed,this._onExecutionContextDestroyed,this);this._targetManager=targetManager;this._context=context;}
WebInspector.ExecutionContextSelector.prototype={targetAdded:function(target)
{if(!target.hasJSContext())
return;setImmediate(deferred.bind(this));function deferred()
{if(!this._context.flavor(WebInspector.Target))
this._context.setFlavor(WebInspector.Target,target);}},targetRemoved:function(target)
{if(!target.hasJSContext())
return;var currentExecutionContext=this._context.flavor(WebInspector.ExecutionContext);if(currentExecutionContext&¤tExecutionContext.target()===target)
this._currentExecutionContextGone();var targets=this._targetManager.targetsWithJSContext();if(this._context.flavor(WebInspector.Target)===target&&targets.length)
this._context.setFlavor(WebInspector.Target,targets[0]);},_executionContextChanged:function(event)
{var newContext=(event.data);if(newContext){this._context.setFlavor(WebInspector.Target,newContext.target());if(!this._contextIsGoingAway)
this._lastSelectedContextId=this._contextPersistentId(newContext);}},_contextPersistentId:function(executionContext)
{return executionContext.isDefault?executionContext.target().name()+":"+executionContext.frameId:"";},_targetChanged:function(event)
{var newTarget=(event.data);var currentContext=this._context.flavor(WebInspector.ExecutionContext);if(!newTarget||(currentContext&¤tContext.target()===newTarget))
return;var executionContexts=newTarget.runtimeModel.executionContexts();if(!executionContexts.length)
return;var newContext=executionContexts[0];for(var i=1;i<executionContexts.length;++i){if(executionContexts[i].isDefault)
newContext=executionContexts[i];}
this._context.setFlavor(WebInspector.ExecutionContext,newContext);},_onExecutionContextCreated:function(event)
{var executionContext=(event.data);if(!this._context.flavor(WebInspector.ExecutionContext)||(this._lastSelectedContextId&&this._lastSelectedContextId===this._contextPersistentId(executionContext)))
this._context.setFlavor(WebInspector.ExecutionContext,executionContext);},_onExecutionContextDestroyed:function(event)
{var executionContext=(event.data);if(this._context.flavor(WebInspector.ExecutionContext)===executionContext)
this._currentExecutionContextGone();},_currentExecutionContextGone:function()
{var targets=this._targetManager.targetsWithJSContext();var newContext=null;for(var i=0;i<targets.length;++i){if(targets[i].isServiceWorker())
continue;var executionContexts=targets[i].runtimeModel.executionContexts();if(executionContexts.length){newContext=executionContexts[0];break;}}
this._contextIsGoingAway=true;this._context.setFlavor(WebInspector.ExecutionContext,newContext);this._contextIsGoingAway=false;}}
WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext=function(proxyElement,text,cursorOffset,wordRange,force,completionsReadyCallback)
{var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!executionContext){completionsReadyCallback([]);return;}
var expressionRange=wordRange.startContainer.rangeOfWord(wordRange.startOffset," =:({;,!+-*/&|^<>",proxyElement,"backward");var expressionString=expressionRange.toString();var pos=expressionString.lastIndexOf("[",expressionString.length-2);if(pos!==-1)
expressionString=expressionString.substr(pos+1);var prefix=wordRange.toString();executionContext.completionsForExpression(expressionString,text,cursorOffset,prefix,force,completionsReadyCallback);};WebInspector.HandlerRegistry=function(setting)
{WebInspector.Object.call(this);this._handlers={};this._setting=setting;this._activeHandler=this._setting.get();}
WebInspector.HandlerRegistry.prototype={get handlerNames()
{return Object.getOwnPropertyNames(this._handlers);},get activeHandler()
{return this._activeHandler;},set activeHandler(value)
{this._activeHandler=value;this._setting.set(value);},dispatch:function(data)
{return this.dispatchToHandler(this._activeHandler,data);},dispatchToHandler:function(name,data)
{var handler=this._handlers[name];var result=handler&&handler(data);return!!result;},registerHandler:function(name,handler)
{this._handlers[name]=handler;this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);},unregisterHandler:function(name)
{delete this._handlers[name];this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);},_openInNewTab:function(url)
{InspectorFrontendHost.openInNewTab(url);},_appendContentProviderItems:function(contextMenu,target)
{if(!(target instanceof WebInspector.UISourceCode||target instanceof WebInspector.Resource||target instanceof WebInspector.NetworkRequest))
return;var contentProvider=(target);if(!contentProvider.contentURL())
return;contextMenu.appendItem(WebInspector.openLinkExternallyLabel(),this._openInNewTab.bind(this,contentProvider.contentURL()));for(var i=1;i<this.handlerNames.length;++i){var handler=this.handlerNames[i];contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^using %s",handler),this.dispatchToHandler.bind(this,handler,{url:contentProvider.contentURL()}));}
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(),InspectorFrontendHost.copyText.bind(InspectorFrontendHost,contentProvider.contentURL()));if(!contentProvider.contentURL())
return;if(!contentProvider.contentType().isDocumentOrScriptOrStyleSheet())
return;function doSave(forceSaveAs,content)
{var url=contentProvider.contentURL();WebInspector.fileManager.save(url,(content),forceSaveAs);WebInspector.fileManager.close(url);}
function save(forceSaveAs)
{if(contentProvider instanceof WebInspector.UISourceCode){var uiSourceCode=(contentProvider);if(forceSaveAs)
uiSourceCode.saveAs();else
uiSourceCode.commitWorkingCopy();return;}
contentProvider.requestContent().then(doSave.bind(null,forceSaveAs));}
contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("Save"),save.bind(null,false));if(contentProvider instanceof WebInspector.UISourceCode){var uiSourceCode=(contentProvider);if(uiSourceCode.project().type()!==WebInspector.projectTypes.FileSystem&&uiSourceCode.project().type()!==WebInspector.projectTypes.Snippets)
contextMenu.appendItem(WebInspector.UIString.capitalize("Save ^as..."),save.bind(null,true));}},_appendHrefItems:function(contextMenu,target)
{if(!(target instanceof Node))
return;var targetNode=(target);var anchorElement=targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link")||targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");if(!anchorElement)
return;var uiLocation=WebInspector.Linkifier.uiLocationByAnchor(anchorElement);var resourceURL=uiLocation?uiLocation.uiSourceCode.contentURL():anchorElement.href;var uiSourceCode=uiLocation?uiLocation.uiSourceCode:(resourceURL?WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(resourceURL):null);function open()
{WebInspector.Revealer.reveal(uiSourceCode);}
if(uiSourceCode)
contextMenu.appendItem("Open",open);if(!resourceURL)
return;contextMenu.appendItem(WebInspector.openLinkExternallyLabel(),this._openInNewTab.bind(this,resourceURL));function openInResourcesPanel(resourceURL)
{var resource=WebInspector.resourceForURL(resourceURL);if(resource)
WebInspector.Revealer.reveal(resource);else
InspectorFrontendHost.openInNewTab(resourceURL);}
if(!targetNode.enclosingNodeOrSelfWithClassList(["resources","panel"])&&WebInspector.resourceForURL(resourceURL))
contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^link in Resources ^panel"),openInResourcesPanel.bind(null,resourceURL));contextMenu.appendItem(WebInspector.copyLinkAddressLabel(),InspectorFrontendHost.copyText.bind(InspectorFrontendHost,resourceURL));},__proto__:WebInspector.Object.prototype}
WebInspector.HandlerRegistry.EventTypes={HandlersUpdated:"HandlersUpdated"}
WebInspector.HandlerSelector=function(handlerRegistry)
{this._handlerRegistry=handlerRegistry;this.element=createElementWithClass("select","chrome-select");this.element.addEventListener("change",this._onChange.bind(this),false);this._update();this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated,this._update.bind(this));}
WebInspector.HandlerSelector.prototype={_update:function()
{this.element.removeChildren();var names=this._handlerRegistry.handlerNames;var activeHandler=this._handlerRegistry.activeHandler;for(var i=0;i<names.length;++i){var option=createElement("option");option.textContent=names[i];option.selected=activeHandler===names[i];this.element.appendChild(option);}
this.element.disabled=names.length<=1;},_onChange:function(event)
{var value=event.target.value;this._handlerRegistry.activeHandler=value;}}
WebInspector.HandlerRegistry.ContextMenuProvider=function()
{}
WebInspector.HandlerRegistry.ContextMenuProvider.prototype={appendApplicableItems:function(event,contextMenu,target)
{WebInspector.openAnchorLocationRegistry._appendContentProviderItems(contextMenu,target);WebInspector.openAnchorLocationRegistry._appendHrefItems(contextMenu,target);}}
WebInspector.HandlerRegistry.LinkHandler=function()
{}
WebInspector.HandlerRegistry.LinkHandler.prototype={handleLink:function(url,lineNumber)
{return WebInspector.openAnchorLocationRegistry.dispatch({url:url,lineNumber:lineNumber});}}
WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI=function()
{}
WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI.prototype={settingElement:function()
{if(!WebInspector.openAnchorLocationRegistry.handlerNames.length)
return null;var handlerSelector=new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);return WebInspector.SettingsUI.createCustomSetting(WebInspector.UIString("Link handling:"),handlerSelector.element);}}
WebInspector.openAnchorLocationRegistry;;WebInspector.LinkifierFormatter=function()
{}
WebInspector.LinkifierFormatter.prototype={formatLiveAnchor:function(anchor,uiLocation,isBlackboxed){}}
WebInspector.Linkifier=function(formatter)
{this._formatter=formatter||new WebInspector.Linkifier.DefaultFormatter(WebInspector.Linkifier.MaxLengthForDisplayedURLs);this._anchorsByTarget=new Map();this._locationPoolByTarget=new Map();WebInspector.targetManager.observeTargets(this);}
WebInspector.Linkifier.setLinkHandler=function(handler)
{WebInspector.Linkifier._linkHandler=handler;}
WebInspector.Linkifier.handleLink=function(url,lineNumber)
{if(!WebInspector.Linkifier._linkHandler)
return false;return WebInspector.Linkifier._linkHandler.handleLink(url,lineNumber);}
WebInspector.Linkifier.linkifyUsingRevealer=function(revealable,text,fallbackHref,fallbackLineNumber,title,classes)
{var a=createElement("a");a.className=(classes||"")+" webkit-html-resource-link";a.textContent=text.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs);a.title=title||text;if(fallbackHref){a.href=fallbackHref;a.lineNumber=fallbackLineNumber;}
function clickHandler(event)
{event.stopImmediatePropagation();event.preventDefault();if(fallbackHref&&WebInspector.Linkifier.handleLink(fallbackHref,fallbackLineNumber))
return;WebInspector.Revealer.reveal(this);}
a.addEventListener("click",clickHandler.bind(revealable),false);return a;}
WebInspector.Linkifier._uiLocationSymbol=Symbol("uiLocation");WebInspector.Linkifier._fallbackAnchorSymbol=Symbol("fallbackAnchor");WebInspector.Linkifier._liveLocationSymbol=Symbol("liveLocation");WebInspector.Linkifier.prototype={targetAdded:function(target)
{this._anchorsByTarget.set(target,[]);this._locationPoolByTarget.set(target,new WebInspector.LiveLocationPool());},targetRemoved:function(target)
{var locationPool=(this._locationPoolByTarget.remove(target));locationPool.disposeAll();var anchors=this._anchorsByTarget.remove(target);for(var anchor of anchors){delete anchor[WebInspector.Linkifier._liveLocationSymbol];var fallbackAnchor=anchor[WebInspector.Linkifier._fallbackAnchorSymbol];if(fallbackAnchor){anchor.href=fallbackAnchor.href;anchor.lineNumber=fallbackAnchor.lineNumber;anchor.title=fallbackAnchor.title;anchor.className=fallbackAnchor.className;anchor.textContent=fallbackAnchor.textContent;delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol];}}},linkifyScriptLocation:function(target,scriptId,sourceURL,lineNumber,columnNumber,classes)
{var fallbackAnchor=WebInspector.linkifyResourceAsNode(sourceURL,lineNumber,columnNumber,classes);if(!target||target.isDetached())
return fallbackAnchor;var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel)
return fallbackAnchor;var rawLocation=scriptId?debuggerModel.createRawLocationByScriptId(scriptId,lineNumber,columnNumber||0):debuggerModel.createRawLocationByURL(sourceURL,lineNumber,columnNumber||0);if(!rawLocation)
return fallbackAnchor;var anchor=this._createAnchor(classes);var liveLocation=WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation,this._updateAnchor.bind(this,anchor),(this._locationPoolByTarget.get(rawLocation.target())));var anchors=(this._anchorsByTarget.get(rawLocation.target()));anchors.push(anchor);anchor[WebInspector.Linkifier._liveLocationSymbol]=liveLocation;anchor[WebInspector.Linkifier._fallbackAnchorSymbol]=fallbackAnchor;return anchor;},linkifyRawLocation:function(rawLocation,fallbackUrl,classes)
{return this.linkifyScriptLocation(rawLocation.target(),rawLocation.scriptId,fallbackUrl,rawLocation.lineNumber,rawLocation.columnNumber,classes);},linkifyConsoleCallFrame:function(target,callFrame,classes)
{return this.linkifyScriptLocation(target,callFrame.scriptId,callFrame.url,WebInspector.DebuggerModel.fromOneBased(callFrame.lineNumber),WebInspector.DebuggerModel.fromOneBased(callFrame.columnNumber),classes);},linkifyStackTraceTopFrame:function(target,stackTrace,classes)
{console.assert(stackTrace.callFrames&&stackTrace.callFrames.length);var topFrame=stackTrace.callFrames[0];var fallbackAnchor=WebInspector.linkifyResourceAsNode(topFrame.url,WebInspector.DebuggerModel.fromOneBased(topFrame.lineNumber),WebInspector.DebuggerModel.fromOneBased(topFrame.columnNumber),classes);if(target.isDetached())
return fallbackAnchor;var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);var rawLocations=debuggerModel.createRawLocationsByStackTrace(stackTrace);if(rawLocations.length===0)
return fallbackAnchor;var anchor=this._createAnchor(classes);var liveLocation=WebInspector.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(rawLocations,this._updateAnchor.bind(this,anchor),(this._locationPoolByTarget.get(target)));var anchors=(this._anchorsByTarget.get(target));anchors.push(anchor);anchor[WebInspector.Linkifier._liveLocationSymbol]=liveLocation;anchor[WebInspector.Linkifier._fallbackAnchorSymbol]=fallbackAnchor;return anchor;},linkifyCSSLocation:function(rawLocation,classes)
{var anchor=this._createAnchor(classes);var liveLocation=WebInspector.cssWorkspaceBinding.createLiveLocation(rawLocation,this._updateAnchor.bind(this,anchor),(this._locationPoolByTarget.get(rawLocation.target())));var anchors=(this._anchorsByTarget.get(rawLocation.target()));anchors.push(anchor);anchor[WebInspector.Linkifier._liveLocationSymbol]=liveLocation;return anchor;},disposeAnchor:function(target,anchor)
{delete anchor[WebInspector.Linkifier._uiLocationSymbol];delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol];var liveLocation=anchor[WebInspector.Linkifier._liveLocationSymbol];if(liveLocation)
liveLocation.dispose();delete anchor[WebInspector.Linkifier._liveLocationSymbol];},_createAnchor:function(classes)
{var anchor=createElement("a");anchor.className=(classes||"")+" webkit-html-resource-link";function clickHandler(event)
{var uiLocation=anchor[WebInspector.Linkifier._uiLocationSymbol];if(!uiLocation)
return;event.consume(true);var networkURL=WebInspector.networkMapping.networkURL(uiLocation.uiSourceCode);if(WebInspector.Linkifier.handleLink(networkURL,uiLocation.lineNumber))
return;WebInspector.Revealer.reveal(uiLocation);}
anchor.addEventListener("click",clickHandler,false);return anchor;},reset:function()
{for(var target of this._anchorsByTarget.keysArray()){this.targetRemoved(target);this.targetAdded(target);}},dispose:function()
{for(var target of this._anchorsByTarget.keysArray())
this.targetRemoved(target);WebInspector.targetManager.unobserveTargets(this);},_updateAnchor:function(anchor,liveLocation)
{var uiLocation=liveLocation.uiLocation();if(!uiLocation)
return;anchor[WebInspector.Linkifier._uiLocationSymbol]=uiLocation;this._formatter.formatLiveAnchor(anchor,uiLocation,liveLocation.isBlackboxed());}}
WebInspector.Linkifier.uiLocationByAnchor=function(anchor)
{return anchor[WebInspector.Linkifier._uiLocationSymbol];}
WebInspector.Linkifier.DefaultFormatter=function(maxLength)
{this._maxLength=maxLength;}
WebInspector.Linkifier.DefaultFormatter.prototype={formatLiveAnchor:function(anchor,uiLocation,isBlackboxed)
{var text=uiLocation.linkText();text=text.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g,"$1\u2026");if(this._maxLength)
text=text.trimMiddle(this._maxLength);anchor.textContent=text;var titleText=uiLocation.uiSourceCode.url();if(typeof uiLocation.lineNumber==="number")
titleText+=":"+(uiLocation.lineNumber+1);anchor.title=titleText;anchor.classList.toggle("webkit-html-blackbox-link",isBlackboxed);}}
WebInspector.Linkifier.DefaultCSSFormatter=function()
{WebInspector.Linkifier.DefaultFormatter.call(this,WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs);}
WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs=30;WebInspector.Linkifier.DefaultCSSFormatter.prototype={formatLiveAnchor:function(anchor,uiLocation,isBlackboxed)
{WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call(this,anchor,uiLocation,isBlackboxed);anchor.classList.add("webkit-html-resource-link");anchor.setAttribute("data-uncopyable",anchor.textContent);anchor.textContent="";},__proto__:WebInspector.Linkifier.DefaultFormatter.prototype}
WebInspector.Linkifier.MaxLengthForDisplayedURLs=150;WebInspector.Linkifier.LinkHandler=function()
{}
WebInspector.Linkifier.LinkHandler.prototype={handleLink:function(url,lineNumber){}}
WebInspector.Linkifier.liveLocationText=function(target,scriptId,lineNumber,columnNumber)
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel)
return"";var script=debuggerModel.scriptForId(scriptId);if(!script)
return"";var location=(debuggerModel.createRawLocation(script,lineNumber,columnNumber||0));var uiLocation=(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location));return uiLocation.linkText();}
WebInspector.linkifyStringAsFragmentWithCustomLinkifier=function(string,linkifier)
{var container=createDocumentFragment();var linkStringRegEx=/(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|data:|www\.)[\w$\-_+*'=\|\/\\(){}[\]^%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({^%@&#~]/;while(string&&string.length<10000){var linkString=linkStringRegEx.exec(string);if(!linkString)
break;linkString=linkString[0];var linkIndex=string.indexOf(linkString);var nonLink=string.substring(0,linkIndex);container.appendChild(createTextNode(nonLink));var title=linkString;var realURL=(linkString.startsWith("www.")?"http://"+linkString:linkString);var splitResult=WebInspector.ParsedURL.splitLineAndColumn(realURL);var linkNode;if(splitResult)
linkNode=linkifier(title,splitResult.url,splitResult.lineNumber,splitResult.columnNumber);else
linkNode=linkifier(title,realURL);container.appendChild(linkNode);string=string.substring(linkIndex+linkString.length,string.length);}
if(string)
container.appendChild(createTextNode(string));return container;}
WebInspector.linkifyStringAsFragment=function(string)
{function linkifier(title,url,lineNumber,columnNumber)
{var isExternal=!WebInspector.resourceForURL(url)&&!WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);var urlNode=WebInspector.linkifyURLAsNode(url,title,undefined,isExternal);if(typeof lineNumber!=="undefined"){urlNode.lineNumber=lineNumber;if(typeof columnNumber!=="undefined")
urlNode.columnNumber=columnNumber;}
return urlNode;}
return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string,linkifier);}
WebInspector.linkifyResourceAsNode=function(url,lineNumber,columnNumber,classes,tooltipText,urlDisplayName)
{var linkText=urlDisplayName?urlDisplayName:url?WebInspector.displayNameForURL(url):WebInspector.UIString("(program)");if(typeof lineNumber==="number")
linkText+=":"+(lineNumber+1);var anchor=WebInspector.linkifyURLAsNode(url,linkText,classes,false,tooltipText);anchor.lineNumber=lineNumber;anchor.columnNumber=columnNumber;return anchor;}
WebInspector.linkifyRequestAsNode=function(request)
{var anchor=WebInspector.linkifyURLAsNode(request.url);anchor.requestId=request.requestId;return anchor;};WebInspector.NetworkConditionsSelector=function(populateCallback,selectCallback)
{this._populateCallback=populateCallback;this._selectCallback=selectCallback;this._customSetting=WebInspector.moduleSetting("customNetworkConditions");this._customSetting.addChangeListener(this._populateOptions,this);this._manager=WebInspector.multitargetNetworkManager;this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged,this._conditionsChanged,this);this._populateOptions();}
WebInspector.NetworkConditionsGroup;WebInspector.NetworkConditionsSelector._throughputText=function(throughput,plainText)
{if(throughput<0)
return"";var throughputInKbps=throughput/(1024/8);var delimiter=plainText?"":" ";if(throughputInKbps<1024)
return WebInspector.UIString("%d%skb/s",throughputInKbps,delimiter);if(throughputInKbps<1024*10)
return WebInspector.UIString("%.1f%sMb/s",throughputInKbps/1024,delimiter);return WebInspector.UIString("%d%sMb/s",(throughputInKbps/1024)|0,delimiter);}
WebInspector.NetworkConditionsSelector._presets=[WebInspector.NetworkManager.OfflineConditions,{title:"GPRS",download:50*1024/8,upload:20*1024/8,latency:500},{title:"Regular 2G",download:250*1024/8,upload:50*1024/8,latency:300},{title:"Good 2G",download:450*1024/8,upload:150*1024/8,latency:150},{title:"Regular 3G",download:750*1024/8,upload:250*1024/8,latency:100},{title:"Good 3G",download:1.5*1024*1024/8,upload:750*1024/8,latency:40},{title:"Regular 4G",download:4*1024*1024/8,upload:3*1024*1024/8,latency:20},{title:"DSL",download:2*1024*1024/8,upload:1*1024*1024/8,latency:5},{title:"WiFi",download:30*1024*1024/8,upload:15*1024*1024/8,latency:2}];WebInspector.NetworkConditionsSelector._conditionsTitle=function(conditions,plainText)
{var downloadInKbps=conditions.download/(1024/8);var uploadInKbps=conditions.upload/(1024/8);var isThrottling=(downloadInKbps>=0)||(uploadInKbps>=0)||(conditions.latency>0);var conditionTitle=WebInspector.UIString(conditions.title);if(!isThrottling)
return{text:conditionTitle,title:conditionTitle};var downloadText=WebInspector.NetworkConditionsSelector._throughputText(conditions.download,plainText);var uploadText=WebInspector.NetworkConditionsSelector._throughputText(conditions.upload,plainText);var pattern=plainText?"%s (%dms, %s, %s)":"%s (%dms RTT, %s\u2b07, %s\u2b06)";var title=WebInspector.UIString(pattern,conditionTitle,conditions.latency,downloadText,uploadText);return{text:title,title:WebInspector.UIString("Maximum download throughput: %s.\r\nMaximum upload throughput: %s.\r\nMinimum round-trip time: %dms.",downloadText,uploadText,conditions.latency)};}
WebInspector.NetworkConditionsSelector.prototype={_populateOptions:function()
{var customGroup={title:WebInspector.UIString("Custom"),items:this._customSetting.get()};var presetsGroup={title:WebInspector.UIString("Presets"),items:WebInspector.NetworkConditionsSelector._presets};var disabledGroup={title:WebInspector.UIString("Disabled"),items:[WebInspector.NetworkManager.NoThrottlingConditions]};this._options=this._populateCallback([customGroup,presetsGroup,disabledGroup]);if(!this._conditionsChanged()){for(var i=this._options.length-1;i>=0;i--){if(this._options[i]){this.optionSelected((this._options[i]));break;}}}},revealAndUpdate:function()
{WebInspector.Revealer.reveal(this._customSetting);this._conditionsChanged();},optionSelected:function(conditions)
{this._manager.setNetworkConditions(conditions);},_conditionsChanged:function()
{var value=this._manager.networkConditions();for(var index=0;index<this._options.length;++index){var option=this._options[index];if(option&&option.download===value.download&&option.upload===value.upload&&option.latency===value.latency&&option.title===value.title){this._selectCallback(index);return true;}}
return false;}}
WebInspector.NetworkConditionsSelector.decorateSelect=function(selectElement)
{var options=[];var selector=new WebInspector.NetworkConditionsSelector(populate,select);selectElement.addEventListener("change",optionSelected,false);function populate(groups)
{selectElement.removeChildren();options=[];for(var i=0;i<groups.length;++i){var group=groups[i];var groupElement=selectElement.createChild("optgroup");groupElement.label=group.title;if(!i){groupElement.appendChild(new Option(WebInspector.UIString("Add\u2026"),WebInspector.UIString("Add\u2026")));options.push(null);}
for(var conditions of group.items){var title=WebInspector.NetworkConditionsSelector._conditionsTitle(conditions,true);var option=new Option(title.text,title.text);option.title=title.title;groupElement.appendChild(option);options.push(conditions);}}
return options;}
function optionSelected()
{if(selectElement.selectedIndex===0)
selector.revealAndUpdate();else
selector.optionSelected(options[selectElement.selectedIndex]);}
function select(index)
{if(selectElement.selectedIndex!==index)
selectElement.selectedIndex=index;}}
WebInspector.NetworkConditionsSelector.createToolbarMenuButton=function()
{var button=new WebInspector.ToolbarMenuButton(appendItems);button.setGlyph("");button.turnIntoSelect();var options=[];var selectedIndex=-1;var selector=new WebInspector.NetworkConditionsSelector(populate,select);return button;function appendItems(contextMenu)
{for(var index=0;index<options.length;++index){var conditions=options[index];if(!conditions)
contextMenu.appendSeparator();else
contextMenu.appendCheckboxItem(WebInspector.NetworkConditionsSelector._conditionsTitle(conditions,true).text,selector.optionSelected.bind(selector,conditions),selectedIndex===index);}
contextMenu.appendItem(WebInspector.UIString("Edit\u2026"),selector.revealAndUpdate.bind(selector));}
function populate(groups)
{options=[];for(var group of groups){for(var conditions of group.items)
options.push(conditions);options.push(null);}
return options;}
function select(index)
{selectedIndex=index;button.setText(options[index].title);}}
WebInspector.NetworkConditionsSelector.createOfflineToolbarCheckbox=function()
{var checkbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Offline"),WebInspector.UIString("Force disconnected from network"),undefined,forceOffline);WebInspector.multitargetNetworkManager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged,networkConditionsChanged);checkbox.setChecked(WebInspector.multitargetNetworkManager.networkConditions()===WebInspector.NetworkManager.OfflineConditions);var lastNetworkConditions;function forceOffline()
{if(checkbox.checked()){lastNetworkConditions=WebInspector.multitargetNetworkManager.networkConditions();WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.OfflineConditions);}else{WebInspector.multitargetNetworkManager.setNetworkConditions(lastNetworkConditions);}}
function networkConditionsChanged()
{var conditions=WebInspector.multitargetNetworkManager.networkConditions();if(conditions!==WebInspector.NetworkManager.OfflineConditions)
lastNetworkConditions=conditions;checkbox.setChecked(conditions===WebInspector.NetworkManager.OfflineConditions);}
return checkbox;}
WebInspector.NetworkConditionsSettingsTab=function()
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("components/networkConditionsSettingsTab.css");this.contentElement.createChild("div","header").textContent=WebInspector.UIString("Network Throttling Profiles");var addButton=createTextButton(WebInspector.UIString("Add custom profile..."),this._addButtonClicked.bind(this),"add-conditions-button");this.contentElement.appendChild(addButton);this._list=new WebInspector.ListWidget(this);this._list.element.classList.add("conditions-list");this._list.registerRequiredCSS("components/networkConditionsSettingsTab.css");this._list.show(this.contentElement);this._customSetting=WebInspector.moduleSetting("customNetworkConditions");this._customSetting.addChangeListener(this._conditionsUpdated,this);this.setDefaultFocusedElement(addButton);this.contentElement.tabIndex=0;}
WebInspector.NetworkConditionsSettingsTab.prototype={wasShown:function()
{WebInspector.VBox.prototype.wasShown.call(this);this._conditionsUpdated();},_conditionsUpdated:function()
{this._list.clear();var conditions=this._customSetting.get();for(var i=0;i<conditions.length;++i)
this._list.appendItem(conditions[i],true);this._list.appendSeparator();conditions=WebInspector.NetworkConditionsSelector._presets;for(var i=0;i<conditions.length;++i)
this._list.appendItem(conditions[i],false);},_addButtonClicked:function()
{this._list.addNewItem(this._customSetting.get().length,{title:"",download:-1,upload:-1,latency:0});},renderItem:function(item,editable)
{var conditions=(item);var element=createElementWithClass("div","conditions-list-item");var title=element.createChild("div","conditions-list-text conditions-list-title");var titleText=title.createChild("div","conditions-list-title-text");titleText.textContent=conditions.title;titleText.title=conditions.title;element.createChild("div","conditions-list-separator");element.createChild("div","conditions-list-text").textContent=WebInspector.NetworkConditionsSelector._throughputText(conditions.download);element.createChild("div","conditions-list-separator");element.createChild("div","conditions-list-text").textContent=WebInspector.NetworkConditionsSelector._throughputText(conditions.upload);element.createChild("div","conditions-list-separator");element.createChild("div","conditions-list-text").textContent=WebInspector.UIString("%dms",conditions.latency);return element;},removeItemRequested:function(item,index)
{var list=this._customSetting.get();list.splice(index,1);this._customSetting.set(list);},commitEdit:function(item,editor,isNew)
{var conditions=(item);conditions.title=editor.control("title").value.trim();var download=editor.control("download").value.trim();conditions.download=download?parseInt(download,10)*(1024/8):-1;var upload=editor.control("upload").value.trim();conditions.upload=upload?parseInt(upload,10)*(1024/8):-1;var latency=editor.control("latency").value.trim();conditions.latency=latency?parseInt(latency,10):0;var list=this._customSetting.get();if(isNew)
list.push(conditions);this._customSetting.set(list);},beginEdit:function(item)
{var conditions=(item);var editor=this._createEditor();editor.control("title").value=conditions.title;editor.control("download").value=conditions.download<=0?"":String(conditions.download/(1024/8));editor.control("upload").value=conditions.upload<=0?"":String(conditions.upload/(1024/8));editor.control("latency").value=conditions.latency?String(conditions.latency):"";return editor;},_createEditor:function()
{if(this._editor)
return this._editor;var editor=new WebInspector.ListWidget.Editor();this._editor=editor;var content=editor.contentElement();var titles=content.createChild("div","conditions-edit-row");titles.createChild("div","conditions-list-text conditions-list-title").textContent=WebInspector.UIString("Profile Name");titles.createChild("div","conditions-list-separator conditions-list-separator-invisible");titles.createChild("div","conditions-list-text").textContent=WebInspector.UIString("Download");titles.createChild("div","conditions-list-separator conditions-list-separator-invisible");titles.createChild("div","conditions-list-text").textContent=WebInspector.UIString("Upload");titles.createChild("div","conditions-list-separator conditions-list-separator-invisible");titles.createChild("div","conditions-list-text").textContent=WebInspector.UIString("Latency");var fields=content.createChild("div","conditions-edit-row");fields.createChild("div","conditions-list-text conditions-list-title").appendChild(editor.createInput("title","text","",titleValidator));fields.createChild("div","conditions-list-separator conditions-list-separator-invisible");var cell=fields.createChild("div","conditions-list-text");cell.appendChild(editor.createInput("download","text",WebInspector.UIString("kb/s"),throughputValidator));cell.createChild("div","conditions-edit-optional").textContent=WebInspector.UIString("optional");fields.createChild("div","conditions-list-separator conditions-list-separator-invisible");cell=fields.createChild("div","conditions-list-text");cell.appendChild(editor.createInput("upload","text",WebInspector.UIString("kb/s"),throughputValidator));cell.createChild("div","conditions-edit-optional").textContent=WebInspector.UIString("optional");fields.createChild("div","conditions-list-separator conditions-list-separator-invisible");cell=fields.createChild("div","conditions-list-text");cell.appendChild(editor.createInput("latency","text",WebInspector.UIString("ms"),latencyValidator));cell.createChild("div","conditions-edit-optional").textContent=WebInspector.UIString("optional");return editor;function titleValidator(item,index,input)
{var value=input.value.trim();return value.length>0&&value.length<50;}
function throughputValidator(item,index,input)
{var value=input.value.trim();return!value||(/^[\d]+(\.\d+)?|\.\d+$/.test(value)&&value>=0&&value<=10000000);}
function latencyValidator(item,index,input)
{var value=input.value.trim();return!value||(/^[\d]+$/.test(value)&&value>=0&&value<=1000000);}},__proto__:WebInspector.VBox.prototype}
WebInspector.NetworkConditionsActionDelegate=function()
{}
WebInspector.NetworkConditionsActionDelegate.prototype={handleAction:function(context,actionId)
{if(actionId==="components.network-online"){WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.NoThrottlingConditions);return true;}
if(actionId==="components.network-offline"){WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.OfflineConditions);return true;}
return false;}};WebInspector.ObjectPopoverHelper=function(panelElement,getAnchor,queryObject,onHide,disableOnClick)
{WebInspector.PopoverHelper.call(this,panelElement,getAnchor,this._showObjectPopover.bind(this),this._onHideObjectPopover.bind(this),disableOnClick);this._queryObject=queryObject;this._onHideCallback=onHide;this._popoverObjectGroup="popover";panelElement.addEventListener("scroll",this.hidePopover.bind(this),true);};WebInspector.ObjectPopoverHelper.MaxPopoverTextLength=10000;WebInspector.ObjectPopoverHelper.prototype={_showObjectPopover:function(element,popover)
{function didGetFunctionProperties(funcObject,popoverContentElement,popoverValueElement,anchorElement,properties,internalProperties)
{if(internalProperties){for(var i=0;i<internalProperties.length;i++){if(internalProperties[i].name==="[[TargetFunction]]"){funcObject=internalProperties[i].value;break;}}}
WebInspector.ObjectPropertiesSection.formatObjectAsFunction(funcObject,popoverValueElement,true);funcObject.functionDetails(didGetFunctionDetails.bind(this,popoverContentElement,anchorElement));}
function didGetFunctionDetails(popoverContentElement,anchorElement,response)
{if(!response||popover.disposed)
return;var container=createElementWithClass("div","object-popover-container");var title=container.createChild("div","function-popover-title source-code");var functionName=title.createChild("span","function-name");functionName.textContent=WebInspector.beautifyFunctionName(response.functionName);var rawLocation=response.location;var sourceURL=response.sourceURL;var linkContainer=title.createChild("div","function-title-link-container");if(rawLocation&&Runtime.experiments.isEnabled("continueToFirstInvocation")){var sectionToolbar=new WebInspector.Toolbar("function-location-step-into",linkContainer);var stepInto=new WebInspector.ToolbarButton(WebInspector.UIString("Continue to first invocation"),"step-in-toolbar-item");stepInto.addEventListener("click",()=>rawLocation.continueToLocation());sectionToolbar.appendToolbarItem(stepInto);}
if(rawLocation&&sourceURL){var link=this._lazyLinkifier().linkifyRawLocation(rawLocation,sourceURL);linkContainer.appendChild(link);}
container.appendChild(popoverContentElement);popover.showForAnchor(container,anchorElement);}
function didGetGeneratorObjectDetails(response)
{if(!response||popover.disposed)
return;var rawLocation=response.location;var sourceURL=response.sourceURL;if(rawLocation&&sourceURL){var link=this._lazyLinkifier().linkifyRawLocation(rawLocation,sourceURL,"function-location-link");this._titleElement.appendChild(link);}}
function didQueryObject(result,wasThrown,anchorOverride)
{if(popover.disposed)
return;if(wasThrown){this.hidePopover();return;}
this._objectTarget=result.target();var anchorElement=anchorOverride||element;var description=result.description.trimEnd(WebInspector.ObjectPopoverHelper.MaxPopoverTextLength);var popoverContentElement=null;if(result.type!=="object"){popoverContentElement=createElement("span");WebInspector.appendStyle(popoverContentElement,"components/objectValue.css");var valueElement=popoverContentElement.createChild("span","monospace object-value-"+result.type);valueElement.style.whiteSpace="pre";if(result.type==="string")
valueElement.createTextChildren("\"",description,"\"");else if(result.type!=="function")
valueElement.textContent=description;if(result.type==="function"){result.getOwnProperties(didGetFunctionProperties.bind(this,result,popoverContentElement,valueElement,anchorElement));return;}
popover.showForAnchor(popoverContentElement,anchorElement);}else{if(result.subtype==="node"){WebInspector.DOMModel.highlightObjectAsDOMNode(result);this._resultHighlightedAsDOM=true;}
if(result.customPreview()){var customPreviewComponent=new WebInspector.CustomPreviewComponent(result);customPreviewComponent.expandIfPossible();popoverContentElement=customPreviewComponent.element;}else{popoverContentElement=createElement("div");this._titleElement=popoverContentElement.createChild("div","monospace");this._titleElement.createChild("span","source-frame-popover-title").textContent=description;var section=new WebInspector.ObjectPropertiesSection(result,"");section.element.classList.add("source-frame-popover-tree");section.titleLessMode();popoverContentElement.appendChild(section.element);if(result.subtype==="generator")
result.generatorObjectDetails(didGetGeneratorObjectDetails.bind(this));}
var popoverWidth=300;var popoverHeight=250;popover.showForAnchor(popoverContentElement,anchorElement,popoverWidth,popoverHeight);}}
this._queryObject(element,didQueryObject.bind(this),this._popoverObjectGroup);},_onHideObjectPopover:function()
{if(this._resultHighlightedAsDOM){WebInspector.DOMModel.hideDOMNodeHighlight();delete this._resultHighlightedAsDOM;}
if(this._linkifier){this._linkifier.dispose();delete this._linkifier;}
if(this._onHideCallback)
this._onHideCallback();if(this._objectTarget){this._objectTarget.runtimeAgent().releaseObjectGroup(this._popoverObjectGroup);delete this._objectTarget;}},_lazyLinkifier:function()
{if(!this._linkifier)
this._linkifier=new WebInspector.Linkifier();return this._linkifier;},__proto__:WebInspector.PopoverHelper.prototype};WebInspector.ObjectPropertiesSection=function(object,title,emptyPlaceholder,ignoreHasOwnProperty,extraProperties)
{this._object=object;this._editable=true;TreeOutlineInShadow.call(this);this.hideOverflow();this.setFocusable(false);this._objectTreeElement=new WebInspector.ObjectPropertiesSection.RootElement(object,emptyPlaceholder,ignoreHasOwnProperty,extraProperties);this.appendChild(this._objectTreeElement);if(typeof title==="string"||!title)
this.element.createChild("span").textContent=title||"";else
this.element.appendChild(title);this.element._section=this;this.registerRequiredCSS("components/objectValue.css");this.registerRequiredCSS("components/objectPropertiesSection.css");this.rootElement().childrenListElement.classList.add("source-code","object-properties-section");}
WebInspector.ObjectPropertiesSection._arrayLoadThreshold=100;WebInspector.ObjectPropertiesSection.defaultObjectPresentation=function(object,skipProto)
{var componentRoot=createElementWithClass("span","source-code");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(componentRoot,"components/objectValue.css");shadowRoot.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(object,false));if(!object.hasChildren)
return componentRoot;var objectPropertiesSection=new WebInspector.ObjectPropertiesSection(object,componentRoot);objectPropertiesSection.editable=false;if(skipProto)
objectPropertiesSection.skipProto();return objectPropertiesSection.element;}
WebInspector.ObjectPropertiesSection.prototype={skipProto:function()
{this._skipProto=true;},expand:function()
{this._objectTreeElement.expand();},setEditable:function(value)
{this._editable=value;},objectTreeElement:function()
{return this._objectTreeElement;},enableContextMenu:function()
{this.element.addEventListener("contextmenu",this._contextMenuEventFired.bind(this),false);},_contextMenuEventFired:function(event)
{var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems(this._object);contextMenu.show();},titleLessMode:function()
{this._objectTreeElement.listItemElement.classList.add("hidden");this._objectTreeElement.childrenListElement.classList.add("title-less-mode");this._objectTreeElement.expand();},__proto__:TreeOutlineInShadow.prototype}
WebInspector.ObjectPropertiesSection.CompareProperties=function(propertyA,propertyB)
{var a=propertyA.name;var b=propertyB.name;if(a==="__proto__")
return 1;if(b==="__proto__")
return-1;if(propertyA.symbol&&!propertyB.symbol)
return 1;if(propertyB.symbol&&!propertyA.symbol)
return-1;return String.naturalOrderComparator(a,b);}
WebInspector.ObjectPropertiesSection.RootElement=function(object,emptyPlaceholder,ignoreHasOwnProperty,extraProperties)
{this._object=object;this._extraProperties=extraProperties||[];this._ignoreHasOwnProperty=!!ignoreHasOwnProperty;this._emptyPlaceholder=emptyPlaceholder;var contentElement=createElement("content");TreeElement.call(this,contentElement);this.setExpandable(true);this.selectable=false;this.toggleOnClick=true;this.listItemElement.classList.add("object-properties-section-root-element");}
WebInspector.ObjectPropertiesSection.RootElement.prototype={onexpand:function()
{if(this.treeOutline)
this.treeOutline.element.classList.add("expanded");},oncollapse:function()
{if(this.treeOutline)
this.treeOutline.element.classList.remove("expanded");},ondblclick:function(e)
{return true;},onpopulate:function()
{WebInspector.ObjectPropertyTreeElement._populate(this,this._object,!!this.treeOutline._skipProto,this._emptyPlaceholder,this._ignoreHasOwnProperty,this._extraProperties);},__proto__:TreeElement.prototype}
WebInspector.ObjectPropertyTreeElement=function(property)
{this.property=property;TreeElement.call(this);this.toggleOnClick=true;this.selectable=false;this._highlightChanges=[];}
WebInspector.ObjectPropertyTreeElement.prototype={setSearchRegex:function(regex,additionalCssClassName){var cssClasses=WebInspector.highlightedSearchResultClassName;if(additionalCssClassName)
cssClasses+=" "+additionalCssClassName;this.revertHighlightChanges();this._applySearch(regex,this.nameElement,cssClasses);var valueType=this.property.value.type;if(valueType!=="object"&&valueType!=="array")
this._applySearch(regex,this.valueElement,cssClasses);return!!this._highlightChanges.length;},_applySearch:function(regex,element,cssClassName)
{var ranges=[];var content=element.textContent;regex.lastIndex=0;var match=regex.exec(content);while(match){ranges.push(new WebInspector.SourceRange(match.index,match[0].length));match=regex.exec(content);}
if(ranges.length)
WebInspector.highlightRangesWithStyleClass(element,ranges,cssClassName,this._highlightChanges);},revertHighlightChanges:function()
{WebInspector.revertDomChanges(this._highlightChanges);this._highlightChanges=[];},onpopulate:function()
{var propertyValue=(this.property.value);console.assert(propertyValue);var skipProto=this.treeOutline?this.treeOutline._skipProto:true;var targetValue=this.property.name!=="__proto__"?propertyValue:this.property.parentObject;WebInspector.ObjectPropertyTreeElement._populate(this,propertyValue,skipProto,undefined,undefined,undefined,targetValue);},ondblclick:function(event)
{var editableElement=this.valueElement;if(!this.property.value.customPreview()&&(this.property.writable||this.property.setter)&&event.target.isSelfOrDescendant(editableElement))
this._startEditing();return false;},onattach:function()
{this.update();this._updateExpandable();},update:function()
{this.nameElement=WebInspector.ObjectPropertiesSection.createNameElement(this.property.name);if(!this.property.enumerable)
this.nameElement.classList.add("object-properties-section-dimmed");if(this.property.isAccessorProperty())
this.nameElement.classList.add("properties-accessor-property-name");if(this.property.synthetic)
this.nameElement.classList.add("synthetic-property");this._updatePropertyPath();this.nameElement.addEventListener("contextmenu",this._contextMenuFired.bind(this,this.property),false);var separatorElement=createElementWithClass("span","object-properties-section-separator");separatorElement.textContent=": ";if(this.property.value){this.valueElement=WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(this.property.value,this.property.wasThrown,this.listItemElement);this.valueElement.addEventListener("contextmenu",this._contextMenuFired.bind(this,this.property),false);}else if(this.property.getter){this.valueElement=WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(this.property.parentObject,[this.property.name],this._onInvokeGetterClick.bind(this));}else{this.valueElement=createElementWithClass("span","object-value-undefined");this.valueElement.textContent=WebInspector.UIString("<unreadable>");this.valueElement.title=WebInspector.UIString("No property getter");}
this.listItemElement.removeChildren();this.listItemElement.appendChildren(this.nameElement,separatorElement,this.valueElement);},_updatePropertyPath:function()
{if(this.nameElement.title)
return;var useDotNotation=/^(_|\$|[A-Z])(_|\$|[A-Z]|\d)*$/i;var isInteger=/^[1-9]\d*$/;var name=this.property.name;var parentPath=this.parent.nameElement?this.parent.nameElement.title:"";if(useDotNotation.test(name))
this.nameElement.title=parentPath+"."+name;else if(isInteger.test(name))
this.nameElement.title=parentPath+"["+name+"]";else
this.nameElement.title=parentPath+"[\""+name+"\"]";},_contextMenuFired:function(property,event)
{var contextMenu=new WebInspector.ContextMenu(event);if(property.symbol)
contextMenu.appendApplicableItems(property.symbol);if(property.value)
contextMenu.appendApplicableItems(property.value);var copyPathHandler=InspectorFrontendHost.copyText.bind(InspectorFrontendHost,this.nameElement.title);contextMenu.beforeShow(()=>{contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^property ^path"),copyPathHandler);});contextMenu.show();},_startEditing:function()
{if(this._prompt||!this.treeOutline._editable||this._readOnly)
return;this._editableDiv=this.listItemElement.createChild("span");var text=this.property.value.description;if(this.property.value.type==="string"&&typeof text==="string")
text="\""+text+"\"";this._editableDiv.setTextContentTruncatedIfNeeded(text,WebInspector.UIString("<string is too large to edit>"));var originalContent=this._editableDiv.textContent;this.valueElement.classList.add("hidden");this.setExpandable(false);this.listItemElement.classList.add("editing-sub-part");this._prompt=new WebInspector.ObjectPropertyPrompt();var proxyElement=this._prompt.attachAndStartEditing(this._editableDiv,this._editingCommitted.bind(this,originalContent));this.listItemElement.getComponentSelection().setBaseAndExtent(this._editableDiv,0,this._editableDiv,1);proxyElement.addEventListener("keydown",this._promptKeyDown.bind(this,originalContent),false);},_editingEnded:function()
{this._prompt.detach();delete this._prompt;this._editableDiv.remove();this._updateExpandable();this.listItemElement.scrollLeft=0;this.listItemElement.classList.remove("editing-sub-part");},_editingCancelled:function()
{this.valueElement.classList.remove("hidden");this._editingEnded();},_editingCommitted:function(originalContent)
{var userInput=this._prompt.text();if(userInput===originalContent){this._editingCancelled();return;}
this._editingEnded();this._applyExpression(userInput);},_promptKeyDown:function(originalContent,event)
{if(isEnterKey(event)){event.consume(true);this._editingCommitted(originalContent);return;}
if(event.keyIdentifier==="U+001B"){event.consume();this._editingCancelled();return;}},_applyExpression:function(expression)
{var property=WebInspector.RemoteObject.toCallArgument(this.property.symbol||this.property.name);expression=expression.trim();if(expression)
this.property.parentObject.setPropertyValue(property,expression,callback.bind(this));else
this.property.parentObject.deleteProperty(property,callback.bind(this));function callback(error)
{if(error){this.update();return;}
if(!expression){this.parent.removeChild(this);}else{var parent=this.parent;parent.invalidateChildren();parent.expand();}};},_onInvokeGetterClick:function(result,wasThrown)
{if(!result)
return;this.property.value=result;this.property.wasThrown=wasThrown;this.update();this.invalidateChildren();this._updateExpandable();},_updateExpandable:function()
{if(this.property.value)
this.setExpandable(!this.property.value.customPreview()&&this.property.value.hasChildren&&!this.property.wasThrown);else
this.setExpandable(false);},__proto__:TreeElement.prototype}
WebInspector.ObjectPropertyTreeElement._populate=function(treeElement,value,skipProto,emptyPlaceholder,flattenProtoChain,extraProperties,targetValue)
{if(value.arrayLength()>WebInspector.ObjectPropertiesSection._arrayLoadThreshold){treeElement.removeChildren();WebInspector.ArrayGroupingTreeElement._populateArray(treeElement,value,0,value.arrayLength()-1);return;}
function callback(properties,internalProperties)
{treeElement.removeChildren();if(!properties)
return;extraProperties=extraProperties||[];for(var i=0;i<extraProperties.length;++i)
properties.push(extraProperties[i]);WebInspector.ObjectPropertyTreeElement.populateWithProperties(treeElement,properties,internalProperties,skipProto,targetValue||value,emptyPlaceholder);}
if(flattenProtoChain)
value.getAllProperties(false,callback);else
WebInspector.RemoteObject.loadFromObjectPerProto(value,callback);}
WebInspector.ObjectPropertyTreeElement.populateWithProperties=function(treeNode,properties,internalProperties,skipProto,value,emptyPlaceholder){properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);for(var i=0;i<properties.length;++i){var property=properties[i];if(skipProto&&property.name==="__proto__")
continue;if(property.isAccessorProperty()){if(property.name!=="__proto__"&&property.getter){property.parentObject=value;treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(property));}
if(property.isOwn){if(property.getter){var getterProperty=new WebInspector.RemoteObjectProperty("get "+property.name,property.getter);getterProperty.parentObject=value;treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(getterProperty));}
if(property.setter){var setterProperty=new WebInspector.RemoteObjectProperty("set "+property.name,property.setter);setterProperty.parentObject=value;treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(setterProperty));}}}else{property.parentObject=value;treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(property));}}
if(internalProperties){for(var i=0;i<internalProperties.length;i++){internalProperties[i].parentObject=value;treeNode.appendChild(new WebInspector.ObjectPropertyTreeElement(internalProperties[i]));}}
if(value&&value.type==="function"){var hasTargetFunction=false;if(internalProperties){for(var i=0;i<internalProperties.length;i++){if(internalProperties[i].name=="[[TargetFunction]]"){hasTargetFunction=true;break;}}}
if(!hasTargetFunction)
treeNode.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));}
if(value&&value.type==="object"&&(value.subtype==="map"||value.subtype==="set"||value.subtype==="iterator"))
treeNode.appendChild(new WebInspector.CollectionEntriesMainTreeElement(value));WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(treeNode,emptyPlaceholder);}
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded=function(treeNode,emptyPlaceholder)
{if(treeNode.childCount())
return;var title=createElementWithClass("div","info");title.textContent=emptyPlaceholder||WebInspector.UIString("No Properties");var infoElement=new TreeElement(title);treeNode.appendChild(infoElement);}
WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan=function(object,propertyPath,callback)
{var rootElement=createElement("span");var element=rootElement.createChild("span");element.textContent=WebInspector.UIString("(...)");if(!object)
return rootElement;element.classList.add("object-value-calculate-value-button");element.title=WebInspector.UIString("Invoke property getter");element.addEventListener("click",onInvokeGetterClick,false);function onInvokeGetterClick(event)
{event.consume();object.getProperty(propertyPath,callback);}
return rootElement;}
WebInspector.FunctionScopeMainTreeElement=function(remoteObject)
{TreeElement.call(this,"<function scope>",true);this.toggleOnClick=true;this.selectable=false;this._remoteObject=remoteObject;}
WebInspector.FunctionScopeMainTreeElement.prototype={onpopulate:function()
{function didGetDetails(response)
{if(!response)
return;this.removeChildren();var scopeChain=response.scopeChain||[];for(var i=0;i<scopeChain.length;++i){var scope=scopeChain[i];var title=null;var isTrueObject=false;switch(scope.type){case DebuggerAgent.ScopeType.Local:title=WebInspector.UIString("Local");break;case DebuggerAgent.ScopeType.Closure:title=WebInspector.UIString("Closure");break;case DebuggerAgent.ScopeType.Catch:title=WebInspector.UIString("Catch");break;case DebuggerAgent.ScopeType.Block:title=WebInspector.UIString("Block");break;case DebuggerAgent.ScopeType.Script:title=WebInspector.UIString("Script");break;case DebuggerAgent.ScopeType.With:title=WebInspector.UIString("With Block");isTrueObject=true;break;case DebuggerAgent.ScopeType.Global:title=WebInspector.UIString("Global");isTrueObject=true;break;default:console.error("Unknown scope type: "+scope.type);continue;}
var runtimeModel=this._remoteObject.target().runtimeModel;if(isTrueObject){var remoteObject=runtimeModel.createRemoteObject(scope.object);var property=new WebInspector.RemoteObjectProperty(title,remoteObject);property.writable=false;property.parentObject=null;this.appendChild(new WebInspector.ObjectPropertyTreeElement(property));}else{var scopeRef=new WebInspector.ScopeRef(i,undefined);var remoteObject=runtimeModel.createScopeRemoteObject(scope.object,scopeRef);var scopeTreeElement=new WebInspector.ScopeTreeElement(title,remoteObject);this.appendChild(scopeTreeElement);}}
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(this,WebInspector.UIString("No Scopes"));}
this._remoteObject.functionDetails(didGetDetails.bind(this));},__proto__:TreeElement.prototype}
WebInspector.CollectionEntriesMainTreeElement=function(remoteObject)
{TreeElement.call(this,"<entries>",true);this.toggleOnClick=true;this.selectable=false;this._remoteObject=remoteObject;this.expand();}
WebInspector.CollectionEntriesMainTreeElement.prototype={onpopulate:function()
{function didGetCollectionEntries(entries)
{if(!entries)
return;this.removeChildren();var entriesLocalObject=[];var runtimeModel=this._remoteObject.target().runtimeModel;for(var i=0;i<entries.length;++i){var entry=entries[i];if(entry.key){entriesLocalObject.push(new WebInspector.MapEntryLocalJSONObject({key:runtimeModel.createRemoteObject(entry.key),value:runtimeModel.createRemoteObject(entry.value)}));}else{entriesLocalObject.push(runtimeModel.createRemoteObject(entry.value));}}
WebInspector.ObjectPropertyTreeElement._populate(this,WebInspector.RemoteObject.fromLocalObject(entriesLocalObject),true,WebInspector.UIString("No Entries"));this.title="<entries>["+entriesLocalObject.length+"]";}
this._remoteObject.collectionEntries(didGetCollectionEntries.bind(this));},__proto__:TreeElement.prototype}
WebInspector.ScopeTreeElement=function(title,remoteObject)
{TreeElement.call(this,title,true);this.toggleOnClick=true;this.selectable=false;this._remoteObject=remoteObject;}
WebInspector.ScopeTreeElement.prototype={onpopulate:function()
{WebInspector.ObjectPropertyTreeElement._populate(this,this._remoteObject,false);},__proto__:TreeElement.prototype}
WebInspector.ArrayGroupingTreeElement=function(object,fromIndex,toIndex,propertyCount)
{TreeElement.call(this,String.sprintf("[%d \u2026 %d]",fromIndex,toIndex),true);this.toggleOnClick=true;this.selectable=false;this._fromIndex=fromIndex;this._toIndex=toIndex;this._object=object;this._readOnly=true;this._propertyCount=propertyCount;}
WebInspector.ArrayGroupingTreeElement._bucketThreshold=100;WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold=250000;WebInspector.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold=500000;WebInspector.ArrayGroupingTreeElement._populateArray=function(treeNode,object,fromIndex,toIndex)
{WebInspector.ArrayGroupingTreeElement._populateRanges(treeNode,object,fromIndex,toIndex,true);}
WebInspector.ArrayGroupingTreeElement._populateRanges=function(treeNode,object,fromIndex,toIndex,topLevel)
{object.callFunctionJSON(packRanges,[{value:fromIndex},{value:toIndex},{value:WebInspector.ArrayGroupingTreeElement._bucketThreshold},{value:WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold},{value:WebInspector.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold}],callback);function packRanges(fromIndex,toIndex,bucketThreshold,sparseIterationThreshold,getOwnPropertyNamesThreshold)
{var ownPropertyNames=null;var consecutiveRange=(toIndex-fromIndex>=sparseIterationThreshold)&&ArrayBuffer.isView(this);var skipGetOwnPropertyNames=consecutiveRange&&(toIndex-fromIndex>=getOwnPropertyNamesThreshold);function*arrayIndexes(object)
{if(toIndex-fromIndex<sparseIterationThreshold){for(var i=fromIndex;i<=toIndex;++i){if(i in object)
yield i;}}else{ownPropertyNames=ownPropertyNames||Object.getOwnPropertyNames(object);for(var i=0;i<ownPropertyNames.length;++i){var name=ownPropertyNames[i];var index=name>>>0;if((""+index)===name&&fromIndex<=index&&index<=toIndex)
yield index;}}}
var count=0;if(consecutiveRange){count=toIndex-fromIndex+1;}else{for(var i of arrayIndexes(this))
++count;}
var bucketSize=count;if(count<=bucketThreshold)
bucketSize=count;else
bucketSize=Math.pow(bucketThreshold,Math.ceil(Math.log(count)/Math.log(bucketThreshold))-1);var ranges=[];if(consecutiveRange){for(var i=fromIndex;i<=toIndex;i+=bucketSize){var groupStart=i;var groupEnd=groupStart+bucketSize-1;if(groupEnd>toIndex)
groupEnd=toIndex;ranges.push([groupStart,groupEnd,groupEnd-groupStart+1]);}}else{count=0;var groupStart=-1;var groupEnd=0;for(var i of arrayIndexes(this)){if(groupStart===-1)
groupStart=i;groupEnd=i;if(++count===bucketSize){ranges.push([groupStart,groupEnd,count]);count=0;groupStart=-1;}}
if(count>0)
ranges.push([groupStart,groupEnd,count]);}
return{ranges:ranges,skipGetOwnPropertyNames:skipGetOwnPropertyNames};}
function callback(result)
{if(!result)
return;var ranges=(result.ranges);if(ranges.length==1){WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode,object,ranges[0][0],ranges[0][1]);}else{for(var i=0;i<ranges.length;++i){var fromIndex=ranges[i][0];var toIndex=ranges[i][1];var count=ranges[i][2];if(fromIndex==toIndex)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode,object,fromIndex,toIndex);else
treeNode.appendChild(new WebInspector.ArrayGroupingTreeElement(object,fromIndex,toIndex,count));}}
if(topLevel)
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeNode,object,result.skipGetOwnPropertyNames);}}
WebInspector.ArrayGroupingTreeElement._populateAsFragment=function(treeNode,object,fromIndex,toIndex)
{object.callFunction(buildArrayFragment,[{value:fromIndex},{value:toIndex},{value:WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}],processArrayFragment.bind(this));function buildArrayFragment(fromIndex,toIndex,sparseIterationThreshold)
{var result=Object.create(null);if(toIndex-fromIndex<sparseIterationThreshold){for(var i=fromIndex;i<=toIndex;++i){if(i in this)
result[i]=this[i];}}else{var ownPropertyNames=Object.getOwnPropertyNames(this);for(var i=0;i<ownPropertyNames.length;++i){var name=ownPropertyNames[i];var index=name>>>0;if(String(index)===name&&fromIndex<=index&&index<=toIndex)
result[index]=this[index];}}
return result;}
function processArrayFragment(arrayFragment,wasThrown)
{if(!arrayFragment||wasThrown)
return;arrayFragment.getAllProperties(false,processProperties.bind(this));}
function processProperties(properties,internalProperties)
{if(!properties)
return;properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);for(var i=0;i<properties.length;++i){properties[i].parentObject=this._object;var childTreeElement=new WebInspector.ObjectPropertyTreeElement(properties[i]);childTreeElement._readOnly=true;treeNode.appendChild(childTreeElement);}}}
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties=function(treeNode,object,skipGetOwnPropertyNames)
{object.callFunction(buildObjectFragment,[{value:skipGetOwnPropertyNames}],processObjectFragment.bind(this));function buildObjectFragment(skipGetOwnPropertyNames)
{var result={__proto__:this.__proto__};if(skipGetOwnPropertyNames)
return result;var names=Object.getOwnPropertyNames(this);for(var i=0;i<names.length;++i){var name=names[i];if(String(name>>>0)===name&&name>>>0!==0xffffffff)
continue;var descriptor=Object.getOwnPropertyDescriptor(this,name);if(descriptor)
Object.defineProperty(result,name,descriptor);}
return result;}
function processObjectFragment(arrayFragment,wasThrown)
{if(!arrayFragment||wasThrown)
return;arrayFragment.getOwnProperties(processProperties.bind(this));}
function processProperties(properties,internalProperties)
{if(!properties)
return;properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);for(var i=0;i<properties.length;++i){properties[i].parentObject=this._object;var childTreeElement=new WebInspector.ObjectPropertyTreeElement(properties[i]);childTreeElement._readOnly=true;treeNode.appendChild(childTreeElement);}}}
WebInspector.ArrayGroupingTreeElement.prototype={onpopulate:function()
{if(this._propertyCount>=WebInspector.ArrayGroupingTreeElement._bucketThreshold){WebInspector.ArrayGroupingTreeElement._populateRanges(this,this._object,this._fromIndex,this._toIndex,false);return;}
WebInspector.ArrayGroupingTreeElement._populateAsFragment(this,this._object,this._fromIndex,this._toIndex);},onattach:function()
{this.listItemElement.classList.add("object-properties-section-name");},__proto__:TreeElement.prototype}
WebInspector.ObjectPropertyPrompt=function()
{WebInspector.TextPrompt.call(this,WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);this.setSuggestBoxEnabled(true);}
WebInspector.ObjectPropertyPrompt.prototype={__proto__:WebInspector.TextPrompt.prototype}
WebInspector.ObjectPropertiesSection.createNameElement=function(name)
{var nameElement=createElementWithClass("span","name");if(/^\s|\s$|^$|\n/.test(name))
nameElement.createTextChildren("\"",name.replace(/\n/g,"\u21B5"),"\"");else
nameElement.textContent=name;return nameElement;}
WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription=function(description)
{var text=description.replace(/^function [gs]et /,"function ");var matches=/function\s([^)]*)/.exec(text);if(!matches){matches=/[^(]*(\([^)]*)/.exec(text);}
var match=matches?matches[1]:null;return match?match.replace(/\n/g," ")+")":(text||"");}
WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport=function(value,wasThrown,parentElement)
{if(value.customPreview()){var result=(new WebInspector.CustomPreviewComponent(value)).element;result.classList.add("object-properties-section-custom-section");return result}
return WebInspector.ObjectPropertiesSection.createValueElement(value,wasThrown,parentElement);}
WebInspector.ObjectPropertiesSection.createValueElement=function(value,wasThrown,parentElement)
{var valueElement=createElementWithClass("span","value");var type=value.type;var subtype=value.subtype;var description=value.description;var prefix;var valueText;var suffix;if(wasThrown){prefix="[Exception: ";valueText=description;suffix="]";}else if(type==="string"&&typeof description==="string"){prefix="\"";valueText=description.replace(/\n/g,"\u21B5");suffix="\"";}else if(type==="function"){valueText=WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription(description);}else if(type!=="object"||subtype!=="node"){valueText=description;}
if(type!=="number"||valueText.indexOf("e")===-1){valueElement.setTextContentTruncatedIfNeeded(valueText||"");if(prefix)
valueElement.insertBefore(createTextNode(prefix),valueElement.firstChild);if(suffix)
valueElement.createTextChild(suffix);}else{var numberParts=valueText.split("e");var mantissa=valueElement.createChild("span","object-value-scientific-notation-mantissa");mantissa.textContent=numberParts[0];var exponent=valueElement.createChild("span","object-value-scientific-notation-exponent");exponent.textContent="e"+numberParts[1];valueElement.classList.add("object-value-scientific-notation-number");if(parentElement)
parentElement.classList.add("hbox");}
if(wasThrown)
valueElement.classList.add("error");if(subtype||type)
valueElement.classList.add("object-value-"+(subtype||type));if(type==="object"&&subtype==="node"&&description){WebInspector.DOMPresentationUtils.createSpansForNodeTitle(valueElement,description);valueElement.addEventListener("click",mouseClick,false);valueElement.addEventListener("mousemove",mouseMove,false);valueElement.addEventListener("mouseleave",mouseLeave,false);}else{valueElement.title=description||"";}
function mouseMove()
{WebInspector.DOMModel.highlightObjectAsDOMNode(value);}
function mouseLeave()
{WebInspector.DOMModel.hideDOMNodeHighlight();}
function mouseClick(event)
{WebInspector.Revealer.reveal(value);event.consume(true);}
return valueElement;}
WebInspector.ObjectPropertiesSection.formatObjectAsFunction=function(func,element,linkify,includePreview)
{func.functionDetails(didGetDetails);function didGetDetails(response)
{if(!response){var valueText=WebInspector.ObjectPropertiesSection.valueTextForFunctionDescription(func.description);element.createTextChild(valueText);return;}
if(linkify&&response&&response.location){var anchor=createElement("span");element.classList.add("linkified");element.appendChild(anchor);element.addEventListener("click",WebInspector.Revealer.reveal.bind(WebInspector.Revealer,response.location,undefined));element=anchor;}
var text=func.description.substring(0,200);if(includePreview){element.textContent=text.replace(/^function /,"")+(func.description.length>200?"\u2026":"");return;}
self.runtime.instancePromise(WebInspector.TokenizerFactory).then(processTokens);var params=null;var functionName=response?response.functionName:"";function processTokens(tokenizerFactory)
{var tokenize=tokenizerFactory.createTokenizer("text/javascript");tokenize(text,processToken);element.textContent=(functionName||"anonymous")+"("+(params||[]).join(", ")+")";}
var doneProcessing=false;function processToken(token,tokenType,column,newColumn)
{if(!params&&tokenType==="js-def"&&!functionName)
functionName=token;doneProcessing=doneProcessing||token===")";if(doneProcessing)
return;if(token==="("){params=[];return;}
if(params&&tokenType==="js-def")
params.push(token);}}}
WebInspector.ObjectPropertiesSectionExpandController=function()
{this._expandedProperties=new Set();}
WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol=Symbol("cachedPath");WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId=Symbol("treeOutlineId");WebInspector.ObjectPropertiesSectionExpandController.prototype={watchSection:function(id,section)
{section.addEventListener(TreeOutline.Events.ElementAttached,this._elementAttached,this);section.addEventListener(TreeOutline.Events.ElementExpanded,this._elementExpanded,this);section.addEventListener(TreeOutline.Events.ElementCollapsed,this._elementCollapsed,this);section[WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId]=id;if(this._expandedProperties.has(id))
section.expand();},stopWatchSectionsWithId:function(id)
{for(var property of this._expandedProperties){if(property.startsWith(id+":"))
this._expandedProperties.delete(property);}},_elementAttached:function(event)
{var element=(event.data);if(element.isExpandable()&&this._expandedProperties.has(this._propertyPath(element)))
element.expand();},_elementExpanded:function(event)
{var element=(event.data);this._expandedProperties.add(this._propertyPath(element));},_elementCollapsed:function(event)
{var element=(event.data);this._expandedProperties.delete(this._propertyPath(element));},_propertyPath:function(treeElement)
{var cachedPropertyPath=treeElement[WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol];if(cachedPropertyPath)
return cachedPropertyPath;var current=treeElement;var rootElement=treeElement.treeOutline.objectTreeElement();var result;while(current!==rootElement){var currentName="";if(current.property)
currentName=current.property.name;else
currentName=typeof current.title==="string"?current.title:current.title.textContent;result=currentName+(result?"."+result:"");current=current.parent;}
var treeOutlineId=treeElement.treeOutline[WebInspector.ObjectPropertiesSectionExpandController._treeOutlineId];result=treeOutlineId+(result?":"+result:"");treeElement[WebInspector.ObjectPropertiesSectionExpandController._cachedPathSymbol]=result;return result;}};WebInspector.RemoteObjectPreviewFormatter=function()
{}
WebInspector.RemoteObjectPreviewFormatter.prototype={appendObjectPreview:function(parentElement,preview)
{var description=preview.description;if(preview.type!=="object"||preview.subtype==="null"){parentElement.appendChild(this.renderPropertyPreview(preview.type,preview.subtype,description));return;}
if(description&&preview.subtype!=="array"){var text=preview.subtype?description:this._abbreviateFullQualifiedClassName(description);parentElement.createTextChildren(text," ");}
if(preview.entries)
this._appendEntriesPreview(parentElement,preview);else
this._appendPropertiesPreview(parentElement,preview);},_abbreviateFullQualifiedClassName:function(description)
{var abbreviatedDescription=description.split(".");for(var i=0;i<abbreviatedDescription.length-1;++i)
abbreviatedDescription[i]=abbreviatedDescription[i].trimMiddle(3);return abbreviatedDescription.join(".");},_appendPropertiesPreview:function(parentElement,preview)
{var isArray=preview.subtype==="array";var arrayLength=WebInspector.RemoteObject.arrayLength(preview);var properties=preview.properties;if(isArray)
properties=properties.slice().stableSort(compareIndexesFirst);function compareIndexesFirst(a,b)
{var index1=toArrayIndex(a.name);var index2=toArrayIndex(b.name);if(index1<0)
return index2<0?0:1;return index2<0?-1:index1-index2;}
function toArrayIndex(name)
{var index=name>>>0;if(String(index)===name&&index<arrayLength)
return index;return-1;}
parentElement.createTextChild(isArray?"[":"{");for(var i=0;i<properties.length;++i){if(i>0)
parentElement.createTextChild(", ");var property=properties[i];var name=property.name;if(!isArray||name!=i||i>=arrayLength){if(/^\s|\s$|^$|\n/.test(name))
parentElement.createChild("span","name").createTextChildren("\"",name.replace(/\n/g,"\u21B5"),"\"");else
parentElement.createChild("span","name").textContent=name;parentElement.createTextChild(": ");}
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));}
if(preview.overflow)
parentElement.createChild("span").textContent="\u2026";parentElement.createTextChild(isArray?"]":"}");},_appendEntriesPreview:function(parentElement,preview)
{parentElement.createTextChild("{");for(var i=0;i<preview.entries.length;++i){if(i>0)
parentElement.createTextChild(", ");var entry=preview.entries[i];if(entry.key){this.appendObjectPreview(parentElement,entry.key);parentElement.createTextChild(" => ");}
this.appendObjectPreview(parentElement,entry.value);}
if(preview.overflow)
parentElement.createChild("span").textContent="\u2026";parentElement.createTextChild("}");},_renderPropertyPreviewOrAccessor:function(propertyPath)
{var property=propertyPath.peekLast();return this.renderPropertyPreview(property.type,(property.subtype),property.value);},renderPropertyPreview:function(type,subtype,description)
{var span=createElementWithClass("span","object-value-"+(subtype||type));description=description||"";if(type==="function"){span.textContent="function";return span;}
if(type==="object"&&subtype==="node"&&description){span.classList.add("object-value-preview-node");WebInspector.DOMPresentationUtils.createSpansForNodeTitle(span,description);return span;}
if(type==="string"){span.createTextChildren("\"",description.replace(/\n/g,"\u21B5"),"\"");return span;}
if(type==="object"&&!subtype){span.textContent=this._abbreviateFullQualifiedClassName(description);return span;}
span.textContent=description;return span;}};WebInspector.RequestAppBannerActionDelegate=function()
{}
WebInspector.RequestAppBannerActionDelegate.prototype={handleAction:function(context,actionId)
{var target=WebInspector.targetManager.mainTarget();if(target&&target.isPage()){target.pageAgent().requestAppBanner();WebInspector.console.show();}
return true;}};WebInspector.ShortcutsScreen=function()
{this._sections={};}
WebInspector.ShortcutsScreen.prototype={section:function(name)
{var section=this._sections[name];if(!section)
this._sections[name]=section=new WebInspector.ShortcutsSection(name);return section;},createShortcutsTabView:function()
{var orderedSections=[];for(var section in this._sections)
orderedSections.push(this._sections[section]);function compareSections(a,b)
{return a.order-b.order;}
orderedSections.sort(compareSections);var widget=new WebInspector.Widget();widget.element.className="settings-tab-container";widget.element.createChild("header").createChild("h3").createTextChild(WebInspector.UIString("Shortcuts"));var scrollPane=widget.element.createChild("div","help-container-wrapper");var container=scrollPane.createChild("div");container.className="help-content help-container";for(var i=0;i<orderedSections.length;++i)
orderedSections[i].renderSection(container);var note=scrollPane.createChild("p","help-footnote");note.appendChild(WebInspector.linkifyDocumentationURLAsNode("iterate/inspect-styles/shortcuts",WebInspector.UIString("Full list of DevTools keyboard shortcuts and gestures")));return widget;}}
WebInspector.shortcutsScreen;WebInspector.ShortcutsSection=function(name)
{this.name=name;this._lines=([]);this.order=++WebInspector.ShortcutsSection._sequenceNumber;};WebInspector.ShortcutsSection._sequenceNumber=0;WebInspector.ShortcutsSection.prototype={addKey:function(key,description)
{this._addLine(this._renderKey(key),description);},addRelatedKeys:function(keys,description)
{this._addLine(this._renderSequence(keys,"/"),description);},addAlternateKeys:function(keys,description)
{this._addLine(this._renderSequence(keys,WebInspector.UIString("or")),description);},_addLine:function(keyElement,description)
{this._lines.push({key:keyElement,text:description});},renderSection:function(container)
{var parent=container.createChild("div","help-block");var headLine=parent.createChild("div","help-line");headLine.createChild("div","help-key-cell");headLine.createChild("div","help-section-title help-cell").textContent=this.name;for(var i=0;i<this._lines.length;++i){var line=parent.createChild("div","help-line");var keyCell=line.createChild("div","help-key-cell");keyCell.appendChild(this._lines[i].key);keyCell.appendChild(this._createSpan("help-key-delimiter",":"));line.createChild("div","help-cell").textContent=this._lines[i].text;}},_renderSequence:function(sequence,delimiter)
{var delimiterSpan=this._createSpan("help-key-delimiter",delimiter);return this._joinNodes(sequence.map(this._renderKey.bind(this)),delimiterSpan);},_renderKey:function(key)
{var keyName=key.name;var plus=this._createSpan("help-combine-keys","+");return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this,"help-key")),plus);},_createSpan:function(className,textContent)
{var node=createElement("span");node.className=className;node.textContent=textContent;return node;},_joinNodes:function(nodes,delimiter)
{var result=createDocumentFragment();for(var i=0;i<nodes.length;++i){if(i>0)
result.appendChild(delimiter.cloneNode(true));result.appendChild(nodes[i]);}
return result;}}
WebInspector.ShortcutsScreen.registerShortcuts=function()
{var elementsSection=WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));var navigate=WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateUp.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateDown);elementsSection.addRelatedKeys(navigate,WebInspector.UIString("Navigate elements"));var expandCollapse=WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Expand.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Collapse);elementsSection.addRelatedKeys(expandCollapse,WebInspector.UIString("Expand/collapse"));elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.EditAttribute,WebInspector.UIString("Edit attribute"));elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.HideElement,WebInspector.UIString("Hide element"));elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.ToggleEditAsHTML,WebInspector.UIString("Toggle edit as HTML"));var stylesPaneSection=WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));var nextPreviousProperty=WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NextProperty.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.PreviousProperty);stylesPaneSection.addRelatedKeys(nextPreviousProperty,WebInspector.UIString("Next/previous property"));stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementValue,WebInspector.UIString("Increment value"));stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementValue,WebInspector.UIString("Decrement value"));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy10,WebInspector.UIString("Increment by %f",10));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy10,WebInspector.UIString("Decrement by %f",10));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy100,WebInspector.UIString("Increment by %f",100));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy100,WebInspector.UIString("Decrement by %f",100));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy01,WebInspector.UIString("Increment by %f",0.1));stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy01,WebInspector.UIString("Decrement by %f",0.1));var section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Debugger"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.toggle-pause"),WebInspector.UIString("Pause/ Continue"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-over"),WebInspector.UIString("Step over"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-into"),WebInspector.UIString("Step into"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.step-out"),WebInspector.UIString("Step out"));var nextAndPrevFrameKeys=WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame.concat(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame);section.addRelatedKeys(nextAndPrevFrameKeys,WebInspector.UIString("Next/previous call frame"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.EvaluateSelectionInConsole,WebInspector.UIString("Evaluate selection in console"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.AddSelectionToWatch,WebInspector.UIString("Add selection to watch"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint,WebInspector.UIString("Toggle breakpoint"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("debugger.toggle-breakpoints-active"),WebInspector.UIString("Toggle all breakpoints"));section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Text Editor"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember,WebInspector.UIString("Go to member"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleAutocompletion,WebInspector.UIString("Autocompletion"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine,WebInspector.UIString("Go to line"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation,WebInspector.UIString("Jump to previous editing location"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation,WebInspector.UIString("Jump to next editing location"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment,WebInspector.UIString("Toggle comment"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByOne,WebInspector.UIString("Increment CSS unit by 1"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByOne,WebInspector.UIString("Decrement CSS unit by 1"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByTen,WebInspector.UIString("Increment CSS unit by 10"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByTen,WebInspector.UIString("Decrement CSS unit by 10"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SelectNextOccurrence,WebInspector.UIString("Select next occurrence"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SoftUndo,WebInspector.UIString("Soft undo"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GotoMatchingBracket,WebInspector.UIString("Go to matching bracket"));section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab,WebInspector.UIString("Close editor tab"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("sources.switch-file"),WebInspector.UIString("Switch between files with the same name and different extensions."));section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Timeline Panel"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.toggle-recording"),WebInspector.UIString("Start/stop recording"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload"),WebInspector.UIString("Record page reload"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.save-to-file"),WebInspector.UIString("Save timeline data"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.load-from-file"),WebInspector.UIString("Load timeline data"));section.addRelatedKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.jump-to-previous-frame").concat(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.jump-to-next-frame")),WebInspector.UIString("Jump to previous/next frame"));section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Profiles Panel"));section.addAlternateKeys(WebInspector.shortcutRegistry.shortcutDescriptorsForAction("profiler.toggle-recording"),WebInspector.UIString("Start/stop recording"));if(Runtime.experiments.isEnabled("layersPanel")){section=WebInspector.shortcutsScreen.section(WebInspector.UIString("Layers Panel"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView,WebInspector.UIString("Reset view"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanMode,WebInspector.UIString("Switch to pan mode"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateMode,WebInspector.UIString("Switch to rotate mode"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.TogglePanRotate,WebInspector.UIString("Temporarily toggle pan/rotate mode while held"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn,WebInspector.UIString("Zoom in"));section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut,WebInspector.UIString("Zoom out"));section.addRelatedKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Up.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Down),WebInspector.UIString("Pan or rotate up/down"));section.addRelatedKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Left.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Right),WebInspector.UIString("Pan or rotate left/right"));}}
WebInspector.ShortcutsScreen.ElementsPanelShortcuts={NavigateUp:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)],NavigateDown:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)],Expand:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right)],Collapse:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left)],EditAttribute:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter)],HideElement:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.H)],ToggleEditAsHTML:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F2)],NextProperty:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab)],PreviousProperty:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab,WebInspector.KeyboardShortcut.Modifiers.Shift)],IncrementValue:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)],DecrementValue:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)],IncrementBy10:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp),WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up,WebInspector.KeyboardShortcut.Modifiers.Shift)],DecrementBy10:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown),WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down,WebInspector.KeyboardShortcut.Modifiers.Shift)],IncrementBy100:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp,WebInspector.KeyboardShortcut.Modifiers.Shift)],DecrementBy100:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown,WebInspector.KeyboardShortcut.Modifiers.Shift)],IncrementBy01:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up,WebInspector.KeyboardShortcut.Modifiers.Alt)],DecrementBy01:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down,WebInspector.KeyboardShortcut.Modifiers.Alt)]};WebInspector.ShortcutsScreen.SourcesPanelShortcuts={SelectNextOccurrence:[WebInspector.KeyboardShortcut.makeDescriptor("d",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)],SoftUndo:[WebInspector.KeyboardShortcut.makeDescriptor("u",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)],GotoMatchingBracket:[WebInspector.KeyboardShortcut.makeDescriptor("m",WebInspector.KeyboardShortcut.Modifiers.Ctrl)],ToggleAutocompletion:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Space,WebInspector.KeyboardShortcut.Modifiers.Ctrl)],IncreaseCSSUnitByOne:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up,WebInspector.KeyboardShortcut.Modifiers.Alt)],DecreaseCSSUnitByOne:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down,WebInspector.KeyboardShortcut.Modifiers.Alt)],IncreaseCSSUnitByTen:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp,WebInspector.KeyboardShortcut.Modifiers.Alt)],DecreaseCSSUnitByTen:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown,WebInspector.KeyboardShortcut.Modifiers.Alt)],EvaluateSelectionInConsole:[WebInspector.KeyboardShortcut.makeDescriptor("e",WebInspector.KeyboardShortcut.Modifiers.Shift|WebInspector.KeyboardShortcut.Modifiers.Ctrl)],AddSelectionToWatch:[WebInspector.KeyboardShortcut.makeDescriptor("a",WebInspector.KeyboardShortcut.Modifiers.Shift|WebInspector.KeyboardShortcut.Modifiers.Ctrl)],GoToMember:[WebInspector.KeyboardShortcut.makeDescriptor("o",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta|WebInspector.KeyboardShortcut.Modifiers.Shift)],GoToLine:[WebInspector.KeyboardShortcut.makeDescriptor("g",WebInspector.KeyboardShortcut.Modifiers.Ctrl)],ToggleBreakpoint:[WebInspector.KeyboardShortcut.makeDescriptor("b",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)],NextCallFrame:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period,WebInspector.KeyboardShortcut.Modifiers.Ctrl)],PrevCallFrame:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma,WebInspector.KeyboardShortcut.Modifiers.Ctrl)],ToggleComment:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash,WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)],JumpToPreviousLocation:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus,WebInspector.KeyboardShortcut.Modifiers.Alt)],JumpToNextLocation:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus,WebInspector.KeyboardShortcut.Modifiers.Alt)],CloseEditorTab:[WebInspector.KeyboardShortcut.makeDescriptor("w",WebInspector.KeyboardShortcut.Modifiers.Alt)],Save:[WebInspector.KeyboardShortcut.makeDescriptor("s",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)],SaveAll:[WebInspector.KeyboardShortcut.makeDescriptor("s",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta|WebInspector.KeyboardShortcut.Modifiers.ShiftOrOption)],};WebInspector.ShortcutsScreen.LayersPanelShortcuts={ResetView:[WebInspector.KeyboardShortcut.makeDescriptor("0")],PanMode:[WebInspector.KeyboardShortcut.makeDescriptor("x")],RotateMode:[WebInspector.KeyboardShortcut.makeDescriptor("v")],TogglePanRotate:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Shift)],ZoomIn:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus,WebInspector.KeyboardShortcut.Modifiers.Shift),WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadPlus)],ZoomOut:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus,WebInspector.KeyboardShortcut.Modifiers.Shift),WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadMinus)],Up:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up),WebInspector.KeyboardShortcut.makeDescriptor("w")],Down:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down),WebInspector.KeyboardShortcut.makeDescriptor("s")],Left:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left),WebInspector.KeyboardShortcut.makeDescriptor("a")],Right:[WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right),WebInspector.KeyboardShortcut.makeDescriptor("d")]};WebInspector.FrameworkEventListenersObject;WebInspector.EventListenerObjectInInspectedPage;WebInspector.EventListener.frameworkEventListeners=function(object)
{if(!object.target().isPage()){return Promise.resolve(({eventListeners:[],internalHandlers:null}));}
var listenersResult=({eventListeners:[]});return object.callFunctionPromise(frameworkEventListeners,undefined).then(assertCallFunctionResult).then(getOwnProperties).then(createEventListeners).then(returnResult).catchException(listenersResult);function getOwnProperties(object)
{return object.getOwnPropertiesPromise();}
function createEventListeners(result)
{if(!result.properties)
throw new Error("Object properties is empty");var promises=[];for(var property of result.properties){if(property.name==="eventListeners"&&property.value)
promises.push(convertToEventListeners(property.value).then(storeEventListeners));if(property.name==="internalHandlers"&&property.value)
promises.push(convertToInternalHandlers(property.value).then(storeInternalHandlers));if(property.name==="errorString"&&property.value)
printErrorString(property.value);}
return(Promise.all(promises));}
function convertToEventListeners(pageEventListenersObject)
{return WebInspector.RemoteArray.objectAsArray(pageEventListenersObject).map(toEventListener).then(filterOutEmptyObjects);function toEventListener(listenerObject)
{var type;var useCapture;var passive;var handler=null;var originalHandler=null;var location=null;var removeFunctionObject=null;var promises=[];promises.push(listenerObject.callFunctionJSONPromise(truncatePageEventListener,undefined).then(storeTruncatedListener));function truncatePageEventListener()
{return{type:this.type,useCapture:this.useCapture,passive:this.passive};}
function storeTruncatedListener(truncatedListener)
{type=truncatedListener.type;useCapture=truncatedListener.useCapture;passive=truncatedListener.passive;}
promises.push(listenerObject.callFunctionPromise(handlerFunction).then(assertCallFunctionResult).then(storeOriginalHandler).then(toTargetFunction).then(storeFunctionWithDetails));function handlerFunction()
{return this.handler;}
function storeOriginalHandler(functionObject)
{originalHandler=functionObject;return originalHandler;}
function storeFunctionWithDetails(functionObject)
{handler=functionObject;return(functionObject.functionDetailsPromise().then(storeFunctionDetails));}
function storeFunctionDetails(functionDetails)
{location=functionDetails?functionDetails.location:null;}
promises.push(listenerObject.callFunctionPromise(getRemoveFunction).then(assertCallFunctionResult).then(storeRemoveFunction));function getRemoveFunction()
{return this.remove;}
function storeRemoveFunction(functionObject)
{if(functionObject.type!=="function")
return;removeFunctionObject=functionObject;}
return Promise.all(promises).then(createEventListener).catchException((null));function createEventListener()
{if(!location)
throw new Error("Empty event listener's location");return new WebInspector.EventListener(handler._target,type,useCapture,passive,handler,originalHandler,location,removeFunctionObject,"frameworkUser");}}}
function convertToInternalHandlers(pageInternalHandlersObject)
{return WebInspector.RemoteArray.objectAsArray(pageInternalHandlersObject).map(toTargetFunction).then(WebInspector.RemoteArray.createFromRemoteObjects);}
function toTargetFunction(functionObject)
{return WebInspector.RemoteFunction.objectAsFunction(functionObject).targetFunction();}
function storeEventListeners(eventListeners)
{listenersResult.eventListeners=eventListeners;}
function storeInternalHandlers(internalHandlers)
{listenersResult.internalHandlers=internalHandlers;}
function printErrorString(errorString)
{WebInspector.console.error(errorString.value);}
function returnResult()
{return listenersResult;}
function assertCallFunctionResult(result)
{if(result.wasThrown||!result.object)
throw new Error("Exception in callFunction or empty result");return result.object;}
function filterOutEmptyObjects(objects)
{return objects.filter(filterOutEmpty);function filterOutEmpty(object)
{return!!object;}}
function frameworkEventListeners()
{var errorLines=[];var eventListeners=[];var internalHandlers=[];var fetchers=[jQueryFetcher];try{if(self.devtoolsFrameworkEventListeners&&isArrayLike(self.devtoolsFrameworkEventListeners))
fetchers=fetchers.concat(self.devtoolsFrameworkEventListeners);}catch(e){errorLines.push("devtoolsFrameworkEventListeners call produced error: "+toString(e));}
for(var i=0;i<fetchers.length;++i){try{var fetcherResult=fetchers[i](this);if(fetcherResult.eventListeners&&isArrayLike(fetcherResult.eventListeners)){eventListeners=eventListeners.concat(fetcherResult.eventListeners.map(checkEventListener).filter(nonEmptyObject));}
if(fetcherResult.internalHandlers&&isArrayLike(fetcherResult.internalHandlers))
internalHandlers=internalHandlers.concat(fetcherResult.internalHandlers.map(checkInternalHandler).filter(nonEmptyObject));}catch(e){errorLines.push("fetcher call produced error: "+toString(e));}}
var result={eventListeners:eventListeners};if(internalHandlers.length)
result.internalHandlers=internalHandlers;if(errorLines.length){var errorString="Framework Event Listeners API Errors:\n\t"+errorLines.join("\n\t");errorString=errorString.substr(0,errorString.length-1);result.errorString=errorString;}
return result;function isArrayLike(obj)
{if(!obj||typeof obj!=="object")
return false;try{if(typeof obj.splice==="function"){var len=obj.length;return typeof len==="number"&&(len>>>0===len&&(len>0||1/len>0));}}catch(e){}
return false;}
function checkEventListener(eventListener)
{try{var errorString="";if(!eventListener)
errorString+="empty event listener, ";var type=eventListener.type;if(!type||(typeof type!=="string"))
errorString+="event listener's type isn't string or empty, ";var useCapture=eventListener.useCapture;if(typeof useCapture!=="boolean")
errorString+="event listener's useCapture isn't boolean or undefined, ";var passive=eventListener.passive;if(typeof passive!=="boolean")
errorString+="event listener's passive isn't boolean or undefined, ";var handler=eventListener.handler;if(!handler||(typeof handler!=="function"))
errorString+="event listener's handler isn't a function or empty, ";var remove=eventListener.remove;if(remove&&(typeof remove!=="function"))
errorString+="event listener's remove isn't a function, ";if(!errorString){return{type:type,useCapture:useCapture,passive:passive,handler:handler,remove:remove};}else{errorLines.push(errorString.substr(0,errorString.length-2));return null;}}catch(e){errorLines.push(toString(e));return null;}}
function checkInternalHandler(handler)
{if(handler&&(typeof handler==="function"))
return handler;errorLines.push("internal handler isn't a function or empty");return null;}
function toString(obj)
{try{return""+obj;}catch(e){return"<error>";}}
function nonEmptyObject(obj)
{return!!obj;}
function jQueryFetcher(node)
{if(!node||!(node instanceof Node))
return{eventListeners:[]};var jQuery=(window["jQuery"]);if(!jQuery||!jQuery.fn)
return{eventListeners:[]};var jQueryFunction=(jQuery);var data=jQuery._data||jQuery.data;var eventListeners=[];var internalHandlers=[];if(typeof data==="function"){var events=data(node,"events");for(var type in events){for(var key in events[type]){var frameworkListener=events[type][key];if(typeof frameworkListener==="object"||typeof frameworkListener==="function"){var listener={handler:frameworkListener.handler||frameworkListener,useCapture:true,passive:false,type:type};listener.remove=jQueryRemove.bind(node,frameworkListener.selector);eventListeners.push(listener);}}}
var nodeData=data(node);if(nodeData&&typeof nodeData.handle==="function")
internalHandlers.push(nodeData.handle);}
var entry=jQueryFunction(node)[0];if(entry){var entryEvents=entry["$events"];for(var type in entryEvents){var events=entryEvents[type];for(var key in events){if(typeof events[key]==="function"){var listener={handler:events[key],useCapture:true,passive:false,type:type};eventListeners.push(listener);}}}
if(entry&&entry["$handle"])
internalHandlers.push(entry["$handle"]);}
return{eventListeners:eventListeners,internalHandlers:internalHandlers};}
function jQueryRemove(selector,type,handler)
{if(!this||!(this instanceof Node))
return;var node=(this);var jQuery=(window["jQuery"]);if(!jQuery||!jQuery.fn)
return;var jQueryFunction=(jQuery);jQueryFunction(node).off(type,selector,handler);}}};WebInspector.EventListenersResult;WebInspector.EventListenersView=function(element)
{this._element=element;this._treeOutline=new TreeOutlineInShadow();this._treeOutline.hideOverflow();this._treeOutline.registerRequiredCSS("components/objectValue.css");this._treeOutline.registerRequiredCSS("components/eventListenersView.css");this._treeOutline.setComparator(WebInspector.EventListenersTreeElement.comparator);this._treeOutline.element.classList.add("monospace");this._element.appendChild(this._treeOutline.element)
this._emptyHolder=createElementWithClass("div","info");this._emptyHolder.textContent=WebInspector.UIString("No Event Listeners");this._linkifier=new WebInspector.Linkifier();this._treeItemMap=new Map();}
WebInspector.EventListenersView.prototype={addObjects:function(objects)
{this.reset();var promises=[];for(var object of objects)
promises.push(this._addObject(object));return Promise.all(promises).then(this.addEmptyHolderIfNeeded.bind(this)).then(this._eventListenersArrivedForTest.bind(this));},_addObject:function(object)
{var eventListeners=null;var frameworkEventListenersObject=null;var promises=[];promises.push(object.eventListeners().then(storeEventListeners));promises.push(WebInspector.EventListener.frameworkEventListeners(object).then(storeFrameworkEventListenersObject));return Promise.all(promises).then(markInternalEventListeners).then(addEventListeners.bind(this));function storeEventListeners(result)
{eventListeners=result;}
function storeFrameworkEventListenersObject(result)
{frameworkEventListenersObject=result;}
function markInternalEventListeners()
{if(!eventListeners||!frameworkEventListenersObject.internalHandlers)
return Promise.resolve(undefined);return frameworkEventListenersObject.internalHandlers.object().callFunctionJSONPromise(isInternalEventListener,eventListeners.map(handlerArgument)).then(setIsInternal);function handlerArgument(listener)
{return WebInspector.RemoteObject.toCallArgument(listener.handler());}
function isInternalEventListener()
{var isInternal=[];var internalHandlersSet=new Set(this);for(var handler of arguments)
isInternal.push(internalHandlersSet.has(handler));return isInternal;}
function setIsInternal(isInternal)
{for(var i=0;i<eventListeners.length;++i){if(isInternal[i])
eventListeners[i].setListenerType("frameworkInternal");}}}
function addEventListeners()
{this._addObjectEventListeners(object,eventListeners);this._addObjectEventListeners(object,frameworkEventListenersObject.eventListeners);}},_addObjectEventListeners:function(object,eventListeners)
{if(!eventListeners)
return;for(var eventListener of eventListeners){var treeItem=this._getOrCreateTreeElementForType(eventListener.type());treeItem.addObjectEventListener(eventListener,object);}},showFrameworkListeners:function(showFramework,showPassive,showBlocking)
{var eventTypes=this._treeOutline.rootElement().children();for(var eventType of eventTypes){var hiddenEventType=true;for(var listenerElement of eventType.children()){var listenerType=listenerElement.eventListener().listenerType();var hidden=false;if(listenerType==="frameworkUser"&&!showFramework)
hidden=true;if(listenerType==="frameworkInternal"&&showFramework)
hidden=true;if(!showPassive&&listenerElement.eventListener().passive())
hidden=true;if(!showBlocking&&!listenerElement.eventListener().passive())
hidden=true;listenerElement.hidden=hidden;hiddenEventType=hiddenEventType&&hidden;}
eventType.hidden=hiddenEventType;}},_getOrCreateTreeElementForType:function(type)
{var treeItem=this._treeItemMap.get(type);if(!treeItem){treeItem=new WebInspector.EventListenersTreeElement(type,this._linkifier);this._treeItemMap.set(type,treeItem);treeItem.hidden=true;this._treeOutline.appendChild(treeItem);}
this._emptyHolder.remove();return treeItem;},addEmptyHolderIfNeeded:function()
{var allHidden=true;for(var eventType of this._treeOutline.rootElement().children()){eventType.hidden=!eventType.firstChild();allHidden=allHidden&&eventType.hidden;}
if(allHidden&&!this._emptyHolder.parentNode)
this._element.appendChild(this._emptyHolder);},reset:function()
{var eventTypes=this._treeOutline.rootElement().children();for(var eventType of eventTypes)
eventType.removeChildren();this._linkifier.reset();},_eventListenersArrivedForTest:function()
{}}
WebInspector.EventListenersTreeElement=function(type,linkifier)
{TreeElement.call(this,type);this.toggleOnClick=true;this.selectable=false;this._linkifier=linkifier;}
WebInspector.EventListenersTreeElement.comparator=function(element1,element2){if(element1.title===element2.title)
return 0;return element1.title>element2.title?1:-1;}
WebInspector.EventListenersTreeElement.prototype={addObjectEventListener:function(eventListener,object)
{var treeElement=new WebInspector.ObjectEventListenerBar(eventListener,object,this._linkifier);this.appendChild((treeElement));},__proto__:TreeElement.prototype}
WebInspector.ObjectEventListenerBar=function(eventListener,object,linkifier)
{TreeElement.call(this,"",true);this._eventListener=eventListener;this.editable=false;this.selectable=false;this._setTitle(object,linkifier);}
WebInspector.ObjectEventListenerBar.prototype={onpopulate:function()
{var properties=[];var eventListener=this._eventListener;var runtimeModel=eventListener.target().runtimeModel;properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("useCapture",eventListener.useCapture()));properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("passive",eventListener.passive()));if(typeof eventListener.handler()!=="undefined")
properties.push(new WebInspector.RemoteObjectProperty("handler",eventListener.handler()));WebInspector.ObjectPropertyTreeElement.populateWithProperties(this,properties,[],true,null);},_setTitle:function(object,linkifier)
{var title=this.listItemElement.createChild("span");var subtitle=this.listItemElement.createChild("span","event-listener-tree-subtitle");subtitle.appendChild(linkifier.linkifyRawLocation(this._eventListener.location(),this._eventListener.sourceURL()));title.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(object,false));if(this._eventListener.removeFunction()){var deleteButton=title.createChild("span","event-listener-delete-button");deleteButton.textContent=WebInspector.UIString("Remove");deleteButton.title=WebInspector.UIString("Delete event listener");deleteButton.addEventListener("click",removeListener.bind(this),false);title.appendChild(deleteButton);}
function removeListener(event)
{event.consume();this._removeListenerBar();this._eventListener.remove();}},_removeListenerBar:function()
{var parent=this.parent;parent.removeChild(this);if(!parent.childCount()){parent.parent.removeChild(parent);return;}
var allHidden=true;for(var i=0;i<parent.childCount();++i)
if(!parent.childAt(i).hidden)
allHidden=false;parent.hidden=allHidden;},eventListener:function()
{return this._eventListener;},__proto__:TreeElement.prototype};WebInspector.reload=function()
{if(WebInspector.dockController.canDock()&&WebInspector.dockController.dockSide()===WebInspector.DockController.State.Undocked)
InspectorFrontendHost.setIsDocked(true,function(){});window.location.reload();};function defineCommonExtensionSymbols(apiPrivate)
{if(!apiPrivate.audits)
apiPrivate.audits={};apiPrivate.audits.Severity={Info:"info",Warning:"warning",Severe:"severe"};if(!apiPrivate.panels)
apiPrivate.panels={};apiPrivate.panels.SearchAction={CancelSearch:"cancelSearch",PerformSearch:"performSearch",NextSearchResult:"nextSearchResult",PreviousSearchResult:"previousSearchResult"};apiPrivate.Events={AuditStarted:"audit-started-",ButtonClicked:"button-clicked-",PanelObjectSelected:"panel-objectSelected-",NetworkRequestFinished:"network-request-finished",OpenResource:"open-resource",PanelSearch:"panel-search-",ResourceAdded:"resource-added",ResourceContentCommitted:"resource-content-committed",ViewShown:"view-shown-",ViewHidden:"view-hidden-"};apiPrivate.Commands={AddAuditCategory:"addAuditCategory",AddAuditResult:"addAuditResult",AddRequestHeaders:"addRequestHeaders",ApplyStyleSheet:"applyStyleSheet",CreatePanel:"createPanel",CreateSidebarPane:"createSidebarPane",CreateToolbarButton:"createToolbarButton",EvaluateOnInspectedPage:"evaluateOnInspectedPage",ForwardKeyboardEvent:"_forwardKeyboardEvent",GetHAR:"getHAR",GetPageResources:"getPageResources",GetRequestContent:"getRequestContent",GetResourceContent:"getResourceContent",InspectedURLChanged:"inspectedURLChanged",OpenResource:"openResource",Reload:"Reload",Subscribe:"subscribe",SetOpenResourceHandler:"setOpenResourceHandler",SetResourceContent:"setResourceContent",SetSidebarContent:"setSidebarContent",SetSidebarPage:"setSidebarPage",ShowPanel:"showPanel",StopAuditCategoryRun:"stopAuditCategoryRun",Unsubscribe:"unsubscribe",UpdateAuditProgress:"updateAuditProgress",UpdateButton:"updateButton"};}
function injectedExtensionAPI(injectedScriptId)
{var apiPrivate={};defineCommonExtensionSymbols(apiPrivate);var commands=apiPrivate.Commands;var events=apiPrivate.Events;var userAction=false;function EventSinkImpl(type,customDispatch)
{this._type=type;this._listeners=[];this._customDispatch=customDispatch;}
EventSinkImpl.prototype={addListener:function(callback)
{if(typeof callback!=="function")
throw"addListener: callback is not a function";if(this._listeners.length===0)
extensionServer.sendRequest({command:commands.Subscribe,type:this._type});this._listeners.push(callback);extensionServer.registerHandler("notify-"+this._type,this._dispatch.bind(this));},removeListener:function(callback)
{var listeners=this._listeners;for(var i=0;i<listeners.length;++i){if(listeners[i]===callback){listeners.splice(i,1);break;}}
if(this._listeners.length===0)
extensionServer.sendRequest({command:commands.Unsubscribe,type:this._type});},_fire:function(vararg)
{var listeners=this._listeners.slice();for(var i=0;i<listeners.length;++i)
listeners[i].apply(null,arguments);},_dispatch:function(request)
{if(this._customDispatch)
this._customDispatch.call(this,request);else
this._fire.apply(this,request.arguments);}}
function InspectorExtensionAPI()
{this.audits=new Audits();this.inspectedWindow=new InspectedWindow();this.panels=new Panels();this.network=new Network();defineDeprecatedProperty(this,"webInspector","resources","network");}
function Network()
{function dispatchRequestEvent(message)
{var request=message.arguments[1];request.__proto__=new Request(message.arguments[0]);this._fire(request);}
this.onRequestFinished=new EventSink(events.NetworkRequestFinished,dispatchRequestEvent);defineDeprecatedProperty(this,"network","onFinished","onRequestFinished");this.onNavigated=new EventSink(events.InspectedURLChanged);}
Network.prototype={getHAR:function(callback)
{function callbackWrapper(result)
{var entries=(result&&result.entries)||[];for(var i=0;i<entries.length;++i){entries[i].__proto__=new Request(entries[i]._requestId);delete entries[i]._requestId;}
callback(result);}
extensionServer.sendRequest({command:commands.GetHAR},callback&&callbackWrapper);},addRequestHeaders:function(headers)
{extensionServer.sendRequest({command:commands.AddRequestHeaders,headers:headers,extensionId:window.location.hostname});}}
function RequestImpl(id)
{this._id=id;}
RequestImpl.prototype={getContent:function(callback)
{function callbackWrapper(response)
{callback(response.content,response.encoding);}
extensionServer.sendRequest({command:commands.GetRequestContent,id:this._id},callback&&callbackWrapper);}}
function Panels()
{var panels={elements:new ElementsPanel(),sources:new SourcesPanel(),};function panelGetter(name)
{return panels[name];}
for(var panel in panels)
this.__defineGetter__(panel,panelGetter.bind(null,panel));this.applyStyleSheet=function(styleSheet){extensionServer.sendRequest({command:commands.ApplyStyleSheet,styleSheet:styleSheet});};}
Panels.prototype={create:function(title,icon,page,callback)
{var id="extension-panel-"+extensionServer.nextObjectId();var request={command:commands.CreatePanel,id:id,title:title,icon:icon,page:page};extensionServer.sendRequest(request,callback&&callback.bind(this,new ExtensionPanel(id)));},setOpenResourceHandler:function(callback)
{var hadHandler=extensionServer.hasHandler(events.OpenResource);function callbackWrapper(message)
{userAction=true;try{callback.call(null,new Resource(message.resource),message.lineNumber);}finally{userAction=false;}}
if(!callback)
extensionServer.unregisterHandler(events.OpenResource);else
extensionServer.registerHandler(events.OpenResource,callbackWrapper);if(hadHandler===!callback)
extensionServer.sendRequest({command:commands.SetOpenResourceHandler,"handlerPresent":!!callback});},openResource:function(url,lineNumber,callback)
{extensionServer.sendRequest({command:commands.OpenResource,"url":url,"lineNumber":lineNumber},callback);},get SearchAction()
{return apiPrivate.panels.SearchAction;}}
function ExtensionViewImpl(id)
{this._id=id;function dispatchShowEvent(message)
{var frameIndex=message.arguments[0];if(typeof frameIndex==="number")
this._fire(window.parent.frames[frameIndex]);else
this._fire();}
if(id){this.onShown=new EventSink(events.ViewShown+id,dispatchShowEvent);this.onHidden=new EventSink(events.ViewHidden+id);}}
function PanelWithSidebarImpl(hostPanelName)
{ExtensionViewImpl.call(this,null);this._hostPanelName=hostPanelName;this.onSelectionChanged=new EventSink(events.PanelObjectSelected+hostPanelName);}
PanelWithSidebarImpl.prototype={createSidebarPane:function(title,callback)
{var id="extension-sidebar-"+extensionServer.nextObjectId();var request={command:commands.CreateSidebarPane,panel:this._hostPanelName,id:id,title:title};function callbackWrapper()
{callback(new ExtensionSidebarPane(id));}
extensionServer.sendRequest(request,callback&&callbackWrapper);},__proto__:ExtensionViewImpl.prototype}
function declareInterfaceClass(implConstructor)
{return function()
{var impl={__proto__:implConstructor.prototype};implConstructor.apply(impl,arguments);populateInterfaceClass(this,impl);};}
function defineDeprecatedProperty(object,className,oldName,newName)
{var warningGiven=false;function getter()
{if(!warningGiven){console.warn(className+"."+oldName+" is deprecated. Use "+className+"."+newName+" instead");warningGiven=true;}
return object[newName];}
object.__defineGetter__(oldName,getter);}
function defineDeprecatedMethod(object,className,oldName)
{var warningGiven=false;function noop()
{if(warningGiven)
return;console.warn(className+"."+oldName+" is deprecated, please don't use it. It is a no-op.");warningGiven=true;}
object[oldName]=noop;}
function extractCallbackArgument(args)
{var lastArgument=args[args.length-1];return typeof lastArgument==="function"?lastArgument:undefined;}
var AuditCategory=declareInterfaceClass(AuditCategoryImpl);var AuditResult=declareInterfaceClass(AuditResultImpl);var Button=declareInterfaceClass(ButtonImpl);var EventSink=declareInterfaceClass(EventSinkImpl);var ExtensionPanel=declareInterfaceClass(ExtensionPanelImpl);var ExtensionSidebarPane=declareInterfaceClass(ExtensionSidebarPaneImpl);var PanelWithSidebar=declareInterfaceClass(PanelWithSidebarImpl);var Request=declareInterfaceClass(RequestImpl);var Resource=declareInterfaceClass(ResourceImpl);function ElementsPanel()
{PanelWithSidebar.call(this,"elements");}
ElementsPanel.prototype={__proto__:PanelWithSidebar.prototype}
function SourcesPanel()
{PanelWithSidebar.call(this,"sources");}
SourcesPanel.prototype={__proto__:PanelWithSidebar.prototype}
function ExtensionPanelImpl(id)
{ExtensionViewImpl.call(this,id);this.onSearch=new EventSink(events.PanelSearch+id);}
ExtensionPanelImpl.prototype={createStatusBarButton:function(iconPath,tooltipText,disabled)
{var id="button-"+extensionServer.nextObjectId();var request={command:commands.CreateToolbarButton,panel:this._id,id:id,icon:iconPath,tooltip:tooltipText,disabled:!!disabled};extensionServer.sendRequest(request);return new Button(id);},show:function()
{if(!userAction)
return;var request={command:commands.ShowPanel,id:this._id};extensionServer.sendRequest(request);},__proto__:ExtensionViewImpl.prototype}
function ExtensionSidebarPaneImpl(id)
{ExtensionViewImpl.call(this,id);defineDeprecatedMethod(this,"ExtensionSidebarPane","setHeight");}
ExtensionSidebarPaneImpl.prototype={setExpression:function(expression,rootTitle,evaluateOptions)
{var request={command:commands.SetSidebarContent,id:this._id,expression:expression,rootTitle:rootTitle,evaluateOnPage:true,};if(typeof evaluateOptions==="object")
request.evaluateOptions=evaluateOptions;extensionServer.sendRequest(request,extractCallbackArgument(arguments));},setObject:function(jsonObject,rootTitle,callback)
{extensionServer.sendRequest({command:commands.SetSidebarContent,id:this._id,expression:jsonObject,rootTitle:rootTitle},callback);},setPage:function(page)
{extensionServer.sendRequest({command:commands.SetSidebarPage,id:this._id,page:page});},__proto__:ExtensionViewImpl.prototype}
function ButtonImpl(id)
{this._id=id;this.onClicked=new EventSink(events.ButtonClicked+id);}
ButtonImpl.prototype={update:function(iconPath,tooltipText,disabled)
{var request={command:commands.UpdateButton,id:this._id,icon:iconPath,tooltip:tooltipText,disabled:!!disabled};extensionServer.sendRequest(request);}};function Audits()
{}
Audits.prototype={addCategory:function(displayName,resultCount)
{var id="extension-audit-category-"+extensionServer.nextObjectId();if(typeof resultCount!=="undefined")
console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");extensionServer.sendRequest({command:commands.AddAuditCategory,id:id,displayName:displayName,resultCount:resultCount});return new AuditCategory(id);}}
function AuditCategoryImpl(id)
{function dispatchAuditEvent(request)
{var auditResult=new AuditResult(request.arguments[0]);try{this._fire(auditResult);}catch(e){console.error("Uncaught exception in extension audit event handler: "+e);auditResult.done();}}
this._id=id;this.onAuditStarted=new EventSink(events.AuditStarted+id,dispatchAuditEvent);}
function AuditResultImpl(id)
{this._id=id;this.createURL=this._nodeFactory.bind(this,"url");this.createSnippet=this._nodeFactory.bind(this,"snippet");this.createText=this._nodeFactory.bind(this,"text");this.createObject=this._nodeFactory.bind(this,"object");this.createNode=this._nodeFactory.bind(this,"node");}
AuditResultImpl.prototype={addResult:function(displayName,description,severity,details)
{if(details&&!(details instanceof AuditResultNode))
details=new AuditResultNode(Array.isArray(details)?details:[details]);var request={command:commands.AddAuditResult,resultId:this._id,displayName:displayName,description:description,severity:severity,details:details};extensionServer.sendRequest(request);},createResult:function()
{return new AuditResultNode(Array.prototype.slice.call(arguments));},updateProgress:function(worked,totalWork)
{extensionServer.sendRequest({command:commands.UpdateAuditProgress,resultId:this._id,progress:worked/totalWork});},done:function()
{extensionServer.sendRequest({command:commands.StopAuditCategoryRun,resultId:this._id});},get Severity()
{return apiPrivate.audits.Severity;},createResourceLink:function(url,lineNumber)
{return{type:"resourceLink",arguments:[url,lineNumber&&lineNumber-1]};},_nodeFactory:function(type)
{return{type:type,arguments:Array.prototype.slice.call(arguments,1)};}}
function AuditResultNode(contents)
{this.contents=contents;this.children=[];this.expanded=false;}
AuditResultNode.prototype={addChild:function()
{var node=new AuditResultNode(Array.prototype.slice.call(arguments));this.children.push(node);return node;}};function InspectedWindow()
{function dispatchResourceEvent(message)
{this._fire(new Resource(message.arguments[0]));}
function dispatchResourceContentEvent(message)
{this._fire(new Resource(message.arguments[0]),message.arguments[1]);}
this.onResourceAdded=new EventSink(events.ResourceAdded,dispatchResourceEvent);this.onResourceContentCommitted=new EventSink(events.ResourceContentCommitted,dispatchResourceContentEvent);}
InspectedWindow.prototype={reload:function(optionsOrUserAgent)
{var options=null;if(typeof optionsOrUserAgent==="object"){options=optionsOrUserAgent;}else if(typeof optionsOrUserAgent==="string"){options={userAgent:optionsOrUserAgent};console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. "+"Use inspectedWindow.reload({ userAgent: value}) instead.");}
extensionServer.sendRequest({command:commands.Reload,options:options});},eval:function(expression,evaluateOptions)
{var callback=extractCallbackArgument(arguments);function callbackWrapper(result)
{if(result.isError||result.isException)
callback(undefined,result);else
callback(result.value);}
var request={command:commands.EvaluateOnInspectedPage,expression:expression};if(typeof evaluateOptions==="object")
request.evaluateOptions=evaluateOptions;extensionServer.sendRequest(request,callback&&callbackWrapper);return null;},getResources:function(callback)
{function wrapResource(resourceData)
{return new Resource(resourceData);}
function callbackWrapper(resources)
{callback(resources.map(wrapResource));}
extensionServer.sendRequest({command:commands.GetPageResources},callback&&callbackWrapper);}}
function ResourceImpl(resourceData)
{this._url=resourceData.url;this._type=resourceData.type;}
ResourceImpl.prototype={get url()
{return this._url;},get type()
{return this._type;},getContent:function(callback)
{function callbackWrapper(response)
{callback(response.content,response.encoding);}
extensionServer.sendRequest({command:commands.GetResourceContent,url:this._url},callback&&callbackWrapper);},setContent:function(content,commit,callback)
{extensionServer.sendRequest({command:commands.SetResourceContent,url:this._url,content:content,commit:commit},callback);}}
var keyboardEventRequestQueue=[];var forwardTimer=null;function forwardKeyboardEvent(event)
{const Esc="U+001B";if(!event.ctrlKey&&!event.altKey&&!event.metaKey&&!/^F\d+$/.test(event.keyIdentifier)&&event.keyIdentifier!==Esc)
return;var requestPayload={eventType:event.type,ctrlKey:event.ctrlKey,altKey:event.altKey,metaKey:event.metaKey,keyIdentifier:event.keyIdentifier,location:event.location,keyCode:event.keyCode};keyboardEventRequestQueue.push(requestPayload);if(!forwardTimer)
forwardTimer=setTimeout(forwardEventQueue,0);}
function forwardEventQueue()
{forwardTimer=null;var request={command:commands.ForwardKeyboardEvent,entries:keyboardEventRequestQueue};extensionServer.sendRequest(request);keyboardEventRequestQueue=[];}
document.addEventListener("keydown",forwardKeyboardEvent,false);document.addEventListener("keypress",forwardKeyboardEvent,false);function ExtensionServerClient()
{this._callbacks={};this._handlers={};this._lastRequestId=0;this._lastObjectId=0;this.registerHandler("callback",this._onCallback.bind(this));var channel=new MessageChannel();this._port=channel.port1;this._port.addEventListener("message",this._onMessage.bind(this),false);this._port.start();window.parent.postMessage("registerExtension",[channel.port2],"*");}
ExtensionServerClient.prototype={sendRequest:function(message,callback)
{if(typeof callback==="function")
message.requestId=this._registerCallback(callback);this._port.postMessage(message);},hasHandler:function(command)
{return!!this._handlers[command];},registerHandler:function(command,handler)
{this._handlers[command]=handler;},unregisterHandler:function(command)
{delete this._handlers[command];},nextObjectId:function()
{return injectedScriptId.toString()+"_"+ ++this._lastObjectId;},_registerCallback:function(callback)
{var id=++this._lastRequestId;this._callbacks[id]=callback;return id;},_onCallback:function(request)
{if(request.requestId in this._callbacks){var callback=this._callbacks[request.requestId];delete this._callbacks[request.requestId];callback(request.result);}},_onMessage:function(event)
{var request=event.data;var handler=this._handlers[request.command];if(handler)
handler.call(this,request);}}
function populateInterfaceClass(interfaze,implementation)
{for(var member in implementation){if(member.charAt(0)==="_")
continue;var descriptor=null;for(var owner=implementation;owner&&!descriptor;owner=owner.__proto__)
descriptor=Object.getOwnPropertyDescriptor(owner,member);if(!descriptor)
continue;if(typeof descriptor.value==="function")
interfaze[member]=descriptor.value.bind(implementation);else if(typeof descriptor.get==="function")
interfaze.__defineGetter__(member,descriptor.get.bind(implementation));else
Object.defineProperty(interfaze,member,descriptor);}}
if(!extensionServer)
extensionServer=new ExtensionServerClient();return new InspectorExtensionAPI();}
function platformExtensionAPI(coreAPI)
{function getTabId()
{return tabId;}
var chrome=window.chrome||{};var devtools_descriptor=Object.getOwnPropertyDescriptor(chrome,"devtools");if(!devtools_descriptor||devtools_descriptor.get)
Object.defineProperty(chrome,"devtools",{value:{},enumerable:true});chrome.devtools.inspectedWindow={};chrome.devtools.inspectedWindow.__defineGetter__("tabId",getTabId);chrome.devtools.inspectedWindow.__proto__=coreAPI.inspectedWindow;chrome.devtools.network=coreAPI.network;chrome.devtools.panels=coreAPI.panels;if(extensionInfo.exposeExperimentalAPIs!==false){chrome.experimental=chrome.experimental||{};chrome.experimental.devtools=chrome.experimental.devtools||{};var properties=Object.getOwnPropertyNames(coreAPI);for(var i=0;i<properties.length;++i){var descriptor=Object.getOwnPropertyDescriptor(coreAPI,properties[i]);Object.defineProperty(chrome.experimental.devtools,properties[i],descriptor);}
chrome.experimental.devtools.inspectedWindow=chrome.devtools.inspectedWindow;}
if(extensionInfo.exposeWebInspectorNamespace)
window.webInspector=coreAPI;}
function buildPlatformExtensionAPI(extensionInfo,inspectedTabId)
{return"var extensionInfo = "+JSON.stringify(extensionInfo)+";"+"var tabId = "+inspectedTabId+";"+
platformExtensionAPI.toString();}
function buildExtensionAPIInjectedScript(extensionInfo,inspectedTabId)
{return"(function(injectedScriptId){ "+"var extensionServer;"+
defineCommonExtensionSymbols.toString()+";"+
injectedExtensionAPI.toString()+";"+
buildPlatformExtensionAPI(extensionInfo,inspectedTabId)+";"+"platformExtensionAPI(injectedExtensionAPI(injectedScriptId));"+"return {};"+"})";};WebInspector.ExtensionAuditCategory=function(extensionOrigin,id,displayName,ruleCount)
{this.extensionOrigin=extensionOrigin;this.id=id;this.displayName=displayName;this.ruleCount=ruleCount;}
WebInspector.ExtensionAuditCategoryResults=function()
{}
WebInspector.ExtensionAuditCategoryResults.prototype={id:function(){},addResult:function(displayName,description,severity,details){},updateProgress:function(progress){},done:function(){}};if(!window.InspectorExtensionRegistry){WebInspector.InspectorExtensionRegistryStub=function()
{}
WebInspector.InspectorExtensionRegistryStub.prototype={getExtensionsAsync:function()
{}}
var InspectorExtensionRegistry=new WebInspector.InspectorExtensionRegistryStub();};WebInspector.ExtensionServer=function()
{this._clientObjects={};this._handlers={};this._subscribers={};this._subscriptionStartHandlers={};this._subscriptionStopHandlers={};this._extraHeaders={};this._requests={};this._lastRequestId=0;this._registeredExtensions={};this._status=new WebInspector.ExtensionStatus();this._sidebarPanes=[];this._auditCategories=[];var commands=WebInspector.extensionAPI.Commands;this._registerHandler(commands.AddAuditCategory,this._onAddAuditCategory.bind(this));this._registerHandler(commands.AddAuditResult,this._onAddAuditResult.bind(this));this._registerHandler(commands.AddRequestHeaders,this._onAddRequestHeaders.bind(this));this._registerHandler(commands.ApplyStyleSheet,this._onApplyStyleSheet.bind(this));this._registerHandler(commands.CreatePanel,this._onCreatePanel.bind(this));this._registerHandler(commands.CreateSidebarPane,this._onCreateSidebarPane.bind(this));this._registerHandler(commands.CreateToolbarButton,this._onCreateToolbarButton.bind(this));this._registerHandler(commands.EvaluateOnInspectedPage,this._onEvaluateOnInspectedPage.bind(this));this._registerHandler(commands.ForwardKeyboardEvent,this._onForwardKeyboardEvent.bind(this));this._registerHandler(commands.GetHAR,this._onGetHAR.bind(this));this._registerHandler(commands.GetPageResources,this._onGetPageResources.bind(this));this._registerHandler(commands.GetRequestContent,this._onGetRequestContent.bind(this));this._registerHandler(commands.GetResourceContent,this._onGetResourceContent.bind(this));this._registerHandler(commands.Reload,this._onReload.bind(this));this._registerHandler(commands.SetOpenResourceHandler,this._onSetOpenResourceHandler.bind(this));this._registerHandler(commands.SetResourceContent,this._onSetResourceContent.bind(this));this._registerHandler(commands.SetSidebarContent,this._onSetSidebarContent.bind(this));this._registerHandler(commands.SetSidebarPage,this._onSetSidebarPage.bind(this));this._registerHandler(commands.ShowPanel,this._onShowPanel.bind(this));this._registerHandler(commands.StopAuditCategoryRun,this._onStopAuditCategoryRun.bind(this));this._registerHandler(commands.Subscribe,this._onSubscribe.bind(this));this._registerHandler(commands.OpenResource,this._onOpenResource.bind(this));this._registerHandler(commands.Unsubscribe,this._onUnsubscribe.bind(this));this._registerHandler(commands.UpdateButton,this._onUpdateButton.bind(this));this._registerHandler(commands.UpdateAuditProgress,this._onUpdateAuditProgress.bind(this));window.addEventListener("message",this._onWindowMessage.bind(this),false);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.AddExtensions,this._addExtensions,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetInspectedTabId,this._setInspectedTabId,this);this._initExtensions();}
WebInspector.ExtensionServer.Events={SidebarPaneAdded:"SidebarPaneAdded",AuditCategoryAdded:"AuditCategoryAdded"}
WebInspector.ExtensionServer.prototype={initializeExtensions:function()
{this._initializeCommandIssued=true;if(this._pendingExtensionInfos){this._pendingExtensionInfos.forEach(this._addExtension,this);delete this._pendingExtensionInfos;}},hasExtensions:function()
{return!!Object.keys(this._registeredExtensions).length;},notifySearchAction:function(panelId,action,searchString)
{this._postNotification(WebInspector.extensionAPI.Events.PanelSearch+panelId,action,searchString);},notifyViewShown:function(identifier,frameIndex)
{this._postNotification(WebInspector.extensionAPI.Events.ViewShown+identifier,frameIndex);},notifyViewHidden:function(identifier)
{this._postNotification(WebInspector.extensionAPI.Events.ViewHidden+identifier);},notifyButtonClicked:function(identifier)
{this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked+identifier);},_inspectedURLChanged:function(event)
{this._requests={};var url=event.data;this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged,url);},startAuditRun:function(categoryId,auditResults)
{this._clientObjects[auditResults.id()]=auditResults;this._postNotification("audit-started-"+categoryId,auditResults.id());},stopAuditRun:function(auditResults)
{delete this._clientObjects[auditResults.id()];},hasSubscribers:function(type)
{return!!this._subscribers[type];},_postNotification:function(type,vararg)
{var subscribers=this._subscribers[type];if(!subscribers)
return;var message={command:"notify-"+type,arguments:Array.prototype.slice.call(arguments,1)};for(var i=0;i<subscribers.length;++i)
subscribers[i].postMessage(message);},_onSubscribe:function(message,port)
{var subscribers=this._subscribers[message.type];if(subscribers)
subscribers.push(port);else{this._subscribers[message.type]=[port];if(this._subscriptionStartHandlers[message.type])
this._subscriptionStartHandlers[message.type]();}},_onUnsubscribe:function(message,port)
{var subscribers=this._subscribers[message.type];if(!subscribers)
return;subscribers.remove(port);if(!subscribers.length){delete this._subscribers[message.type];if(this._subscriptionStopHandlers[message.type])
this._subscriptionStopHandlers[message.type]();}},_onAddRequestHeaders:function(message)
{var id=message.extensionId;if(typeof id!=="string")
return this._status.E_BADARGTYPE("extensionId",typeof id,"string");var extensionHeaders=this._extraHeaders[id];if(!extensionHeaders){extensionHeaders={};this._extraHeaders[id]=extensionHeaders;}
for(var name in message.headers)
extensionHeaders[name]=message.headers[name];var allHeaders=({});for(var extension in this._extraHeaders){var headers=this._extraHeaders[extension];for(name in headers){if(typeof headers[name]==="string")
allHeaders[name]=headers[name];}}
WebInspector.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);},_onApplyStyleSheet:function(message)
{if(!Runtime.experiments.isEnabled("applyCustomStylesheet"))
return;var styleSheet=createElement("style");styleSheet.textContent=message.styleSheet;document.head.appendChild(styleSheet);},_onCreatePanel:function(message,port)
{var id=message.id;if(id in this._clientObjects||WebInspector.inspectorView.hasPanel(id))
return this._status.E_EXISTS(id);var page=this._expandResourcePath(port._extensionOrigin,message.page);var persistentId=port._extensionOrigin+message.title;persistentId=persistentId.replace(/\s/g,"");var panelDescriptor=new WebInspector.ExtensionServerPanelDescriptor(persistentId,message.title,new WebInspector.ExtensionPanel(this,persistentId,id,page));this._clientObjects[id]=panelDescriptor;WebInspector.inspectorView.addPanel(panelDescriptor);return this._status.OK();},_onShowPanel:function(message)
{var panelName=message.id;var panelDescriptor=this._clientObjects[message.id];if(panelDescriptor&&panelDescriptor instanceof WebInspector.ExtensionServerPanelDescriptor)
panelName=panelDescriptor.name();WebInspector.inspectorView.showPanel(panelName);},_onCreateToolbarButton:function(message,port)
{var panelDescriptor=this._clientObjects[message.panel];if(!panelDescriptor||!(panelDescriptor instanceof WebInspector.ExtensionServerPanelDescriptor))
return this._status.E_NOTFOUND(message.panel);var button=new WebInspector.ExtensionButton(this,message.id,this._expandResourcePath(port._extensionOrigin,message.icon),message.tooltip,message.disabled);this._clientObjects[message.id]=button;panelDescriptor.panel().then(appendButton);function appendButton(panel)
{(panel).addToolbarItem(button.toolbarButton());}
return this._status.OK();},_onUpdateButton:function(message,port)
{var button=this._clientObjects[message.id];if(!button||!(button instanceof WebInspector.ExtensionButton))
return this._status.E_NOTFOUND(message.id);button.update(this._expandResourcePath(port._extensionOrigin,message.icon),message.tooltip,message.disabled);return this._status.OK();},_onCreateSidebarPane:function(message)
{if(message.panel!=="elements"&&message.panel!=="sources")
return this._status.E_NOTFOUND(message.panel);var id=message.id;var sidebar=new WebInspector.ExtensionSidebarPane(this,message.panel,message.title,id);this._sidebarPanes.push(sidebar);this._clientObjects[id]=sidebar;this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.SidebarPaneAdded,sidebar);return this._status.OK();},sidebarPanes:function()
{return this._sidebarPanes;},_onSetSidebarContent:function(message,port)
{var sidebar=this._clientObjects[message.id];if(!sidebar)
return this._status.E_NOTFOUND(message.id);function callback(error)
{var result=error?this._status.E_FAILED(error):this._status.OK();this._dispatchCallback(message.requestId,port,result);}
if(message.evaluateOnPage)
return sidebar.setExpression(message.expression,message.rootTitle,message.evaluateOptions,port._extensionOrigin,callback.bind(this));sidebar.setObject(message.expression,message.rootTitle,callback.bind(this));},_onSetSidebarPage:function(message,port)
{var sidebar=this._clientObjects[message.id];if(!sidebar)
return this._status.E_NOTFOUND(message.id);sidebar.setPage(this._expandResourcePath(port._extensionOrigin,message.page));},_onOpenResource:function(message)
{var uiSourceCode=WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(message.url);if(uiSourceCode){WebInspector.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber,0));return this._status.OK();}
var resource=WebInspector.resourceForURL(message.url);if(resource){WebInspector.Revealer.reveal(resource);return this._status.OK();}
var request=WebInspector.NetworkLog.requestForURL(message.url);if(request){WebInspector.Revealer.reveal(request);return this._status.OK();}
return this._status.E_NOTFOUND(message.url);},_onSetOpenResourceHandler:function(message,port)
{var name=this._registeredExtensions[port._extensionOrigin].name||("Extension "+port._extensionOrigin);if(message.handlerPresent)
WebInspector.openAnchorLocationRegistry.registerHandler(name,this._handleOpenURL.bind(this,port));else
WebInspector.openAnchorLocationRegistry.unregisterHandler(name);},_handleOpenURL:function(port,details)
{var url=(details.url);var contentProvider=WebInspector.workspace.uiSourceCodeForURL(url)||WebInspector.resourceForURL(url);if(!contentProvider)
return false;var lineNumber=details.lineNumber;if(typeof lineNumber==="number")
lineNumber+=1;port.postMessage({command:"open-resource",resource:this._makeResource(contentProvider),lineNumber:lineNumber});return true;},_onReload:function(message)
{var options=(message.options||{});WebInspector.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent==="string"?options.userAgent:"");var injectedScript;if(options.injectedScript)
injectedScript="(function(){"+options.injectedScript+"})()";WebInspector.targetManager.reloadPage(!!options.ignoreCache,injectedScript);return this._status.OK();},_onEvaluateOnInspectedPage:function(message,port)
{function callback(error,remoteObject,wasThrown)
{var result;if(error||!remoteObject)
result=this._status.E_PROTOCOLERROR(error.toString());else if(wasThrown)
result={isException:true,value:remoteObject.description};else
result={value:remoteObject.value};this._dispatchCallback(message.requestId,port,result);}
return this.evaluate(message.expression,true,true,message.evaluateOptions,port._extensionOrigin,callback.bind(this));},_onGetHAR:function()
{var requests=WebInspector.NetworkLog.requests();var harLog=(new WebInspector.HARLog(requests)).build();for(var i=0;i<harLog.entries.length;++i)
harLog.entries[i]._requestId=this._requestId(requests[i]);return harLog;},_makeResource:function(contentProvider)
{return{url:contentProvider.contentURL(),type:contentProvider.contentType().name()};},_onGetPageResources:function()
{var resources={};function pushResourceData(contentProvider)
{if(!resources[contentProvider.contentURL()])
resources[contentProvider.contentURL()]=this._makeResource(contentProvider);}
var uiSourceCodes=WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);uiSourceCodes=uiSourceCodes.concat(WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.ContentScripts));uiSourceCodes.forEach(pushResourceData.bind(this));for(var target of WebInspector.targetManager.targets())
target.resourceTreeModel.forAllResources(pushResourceData.bind(this));return Object.values(resources);},_getResourceContent:function(contentProvider,message,port)
{function onContentAvailable(content)
{var contentEncoded=false;if(contentProvider instanceof WebInspector.Resource)
contentEncoded=contentProvider.contentEncoded;if(contentProvider instanceof WebInspector.NetworkRequest)
contentEncoded=contentProvider.contentEncoded;var response={encoding:contentEncoded&&content?"base64":"",content:content};this._dispatchCallback(message.requestId,port,response);}
contentProvider.requestContent().then(onContentAvailable.bind(this));},_onGetRequestContent:function(message,port)
{var request=this._requestById(message.id);if(!request)
return this._status.E_NOTFOUND(message.id);this._getResourceContent(request,message,port);},_onGetResourceContent:function(message,port)
{var url=(message.url);var contentProvider=WebInspector.workspace.uiSourceCodeForURL(url)||WebInspector.resourceForURL(url);if(!contentProvider)
return this._status.E_NOTFOUND(url);this._getResourceContent(contentProvider,message,port);},_onSetResourceContent:function(message,port)
{function callbackWrapper(error)
{var response=error?this._status.E_FAILED(error):this._status.OK();this._dispatchCallback(message.requestId,port,response);}
var url=(message.url);var uiSourceCode=WebInspector.workspace.uiSourceCodeForURL(url);if(!uiSourceCode||!uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()){var resource=WebInspector.ResourceTreeModel.resourceForURL(url);if(!resource)
return this._status.E_NOTFOUND(url);return this._status.E_NOTSUPPORTED("Resource is not editable");}
uiSourceCode.setWorkingCopy(message.content);if(message.commit)
uiSourceCode.commitWorkingCopy();callbackWrapper.call(this,null);},_requestId:function(request)
{if(!request._extensionRequestId){request._extensionRequestId=++this._lastRequestId;this._requests[request._extensionRequestId]=request;}
return request._extensionRequestId;},_requestById:function(id)
{return this._requests[id];},_onAddAuditCategory:function(message,port)
{var category=new WebInspector.ExtensionAuditCategory(port._extensionOrigin,message.id,message.displayName,message.resultCount);this._clientObjects[message.id]=category;this._auditCategories.push(category);this.dispatchEventToListeners(WebInspector.ExtensionServer.Events.AuditCategoryAdded,category);},auditCategories:function()
{return this._auditCategories;},_onAddAuditResult:function(message)
{var auditResult=(this._clientObjects[message.resultId]);if(!auditResult)
return this._status.E_NOTFOUND(message.resultId);try{auditResult.addResult(message.displayName,message.description,message.severity,message.details);}catch(e){return e;}
return this._status.OK();},_onUpdateAuditProgress:function(message)
{var auditResult=(this._clientObjects[message.resultId]);if(!auditResult)
return this._status.E_NOTFOUND(message.resultId);auditResult.updateProgress(Math.min(Math.max(0,message.progress),1));},_onStopAuditCategoryRun:function(message)
{var auditRun=(this._clientObjects[message.resultId]);if(!auditRun)
return this._status.E_NOTFOUND(message.resultId);auditRun.done();},_onForwardKeyboardEvent:function(message)
{const Esc="U+001B";message.entries.forEach(handleEventEntry);function handleEventEntry(entry)
{if(!entry.ctrlKey&&!entry.altKey&&!entry.metaKey&&!/^F\d+$/.test(entry.keyIdentifier)&&entry.keyIdentifier!==Esc)
return;var event=new window.KeyboardEvent(entry.eventType,{keyIdentifier:entry.keyIdentifier,location:entry.location,ctrlKey:entry.ctrlKey,altKey:entry.altKey,shiftKey:entry.shiftKey,metaKey:entry.metaKey});event.__keyCode=keyCodeForEntry(entry);document.dispatchEvent(event);}
function keyCodeForEntry(entry)
{var keyCode=entry.keyCode;if(!keyCode){var match=entry.keyIdentifier.match(/^U\+([\dA-Fa-f]+)$/);if(match)
keyCode=parseInt(match[1],16);}
return keyCode||0;}},_dispatchCallback:function(requestId,port,result)
{if(requestId)
port.postMessage({command:"callback",requestId:requestId,result:result});},_initExtensions:function()
{this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,WebInspector.workspace,WebInspector.Workspace.Events.UISourceCodeAdded,this._notifyResourceAdded);this._registerAutosubscriptionTargetManagerHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._notifyRequestFinished);function onElementsSubscriptionStarted()
{WebInspector.notifications.addEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged,this._notifyElementsSelectionChanged,this);}
function onElementsSubscriptionStopped()
{WebInspector.notifications.removeEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged,this._notifyElementsSelectionChanged,this);}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected+"elements",onElementsSubscriptionStarted.bind(this),onElementsSubscriptionStopped.bind(this));this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,this._inspectedURLChanged,this);InspectorExtensionRegistry.getExtensionsAsync();},_notifyResourceAdded:function(event)
{var uiSourceCode=(event.data);this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded,this._makeResource(uiSourceCode));},_notifyUISourceCodeContentCommitted:function(event)
{var uiSourceCode=(event.data.uiSourceCode);var content=(event.data.content);this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted,this._makeResource(uiSourceCode),content);},_notifyRequestFinished:function(event)
{var request=(event.data);this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished,this._requestId(request),(new WebInspector.HAREntry(request)).build());},_notifyElementsSelectionChanged:function()
{this._postNotification(WebInspector.extensionAPI.Events.PanelObjectSelected+"elements");},_addExtensions:function(event)
{if(WebInspector.extensionServer._overridePlatformExtensionAPIForTest)
window.buildPlatformExtensionAPI=WebInspector.extensionServer._overridePlatformExtensionAPIForTest;var extensionInfos=(event.data);if(this._initializeCommandIssued)
extensionInfos.forEach(this._addExtension,this);else
this._pendingExtensionInfos=extensionInfos;},_setInspectedTabId:function(event)
{this._inspectedTabId=(event.data);},_addExtension:function(extensionInfo)
{const urlOriginRegExp=new RegExp("([^:]+:\/\/[^/]*)\/");var startPage=extensionInfo.startPage;var name=extensionInfo.name;try{var originMatch=urlOriginRegExp.exec(startPage);if(!originMatch){console.error("Skipping extension with invalid URL: "+startPage);return false;}
var extensionOrigin=originMatch[1];if(!this._registeredExtensions[extensionOrigin]){InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin,buildExtensionAPIInjectedScript(extensionInfo,this._inspectedTabId));this._registeredExtensions[extensionOrigin]={name:name};}
var iframe=createElement("iframe");iframe.src=startPage;iframe.style.display="none";document.body.appendChild(iframe);}catch(e){console.error("Failed to initialize extension "+startPage+":"+e);return false;}
return true;},_registerExtension:function(origin,port)
{if(!this._registeredExtensions.hasOwnProperty(origin)){if(origin!==window.location.origin)
console.error("Ignoring unauthorized client request from "+origin);return;}
port._extensionOrigin=origin;port.addEventListener("message",this._onmessage.bind(this),false);port.start();},_onWindowMessage:function(event)
{if(event.data==="registerExtension")
this._registerExtension(event.origin,event.ports[0]);},_onmessage:function(event)
{var message=event.data;var result;if(message.command in this._handlers)
result=this._handlers[message.command](message,event.target);else
result=this._status.E_NOTSUPPORTED(message.command);if(result&&message.requestId)
this._dispatchCallback(message.requestId,event.target,result);},_registerHandler:function(command,callback)
{console.assert(command);this._handlers[command]=callback;},_registerSubscriptionHandler:function(eventTopic,onSubscribeFirst,onUnsubscribeLast)
{this._subscriptionStartHandlers[eventTopic]=onSubscribeFirst;this._subscriptionStopHandlers[eventTopic]=onUnsubscribeLast;},_registerAutosubscriptionHandler:function(eventTopic,eventTarget,frontendEventType,handler)
{this._registerSubscriptionHandler(eventTopic,eventTarget.addEventListener.bind(eventTarget,frontendEventType,handler,this),eventTarget.removeEventListener.bind(eventTarget,frontendEventType,handler,this));},_registerAutosubscriptionTargetManagerHandler:function(eventTopic,modelClass,frontendEventType,handler)
{this._registerSubscriptionHandler(eventTopic,WebInspector.targetManager.addModelListener.bind(WebInspector.targetManager,modelClass,frontendEventType,handler,this),WebInspector.targetManager.removeModelListener.bind(WebInspector.targetManager,modelClass,frontendEventType,handler,this));},_registerResourceContentCommittedHandler:function(handler)
{function addFirstEventListener()
{WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser,handler,this);WebInspector.workspace.setHasResourceContentTrackingExtensions(true);}
function removeLastEventListener()
{WebInspector.workspace.setHasResourceContentTrackingExtensions(false);WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser,handler,this);}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,addFirstEventListener.bind(this),removeLastEventListener.bind(this));},_expandResourcePath:function(extensionPath,resourcePath)
{if(!resourcePath)
return;return extensionPath+this._normalizePath(resourcePath);},_normalizePath:function(path)
{var source=path.split("/");var result=[];for(var i=0;i<source.length;++i){if(source[i]===".")
continue;if(source[i]==="")
continue;if(source[i]==="..")
result.pop();else
result.push(source[i]);}
return"/"+result.join("/");},evaluate:function(expression,exposeCommandLineAPI,returnByValue,options,securityOrigin,callback)
{var contextId;function resolveURLToFrame(url)
{var found;function hasMatchingURL(frame)
{found=(frame.url===url)?frame:null;return found;}
WebInspector.ResourceTreeModel.frames().some(hasMatchingURL);return found;}
if(typeof options==="object"){var frame=options.frameURL?resolveURLToFrame(options.frameURL):WebInspector.targetManager.mainTarget().resourceTreeModel.mainFrame;if(!frame){if(options.frameURL)
console.warn("evaluate: there is no frame with URL "+options.frameURL);else
console.warn("evaluate: the main frame is not yet available");return this._status.E_NOTFOUND(options.frameURL||"<top>");}
var contextSecurityOrigin;if(options.useContentScriptContext)
contextSecurityOrigin=securityOrigin;else if(options.scriptExecutionContext)
contextSecurityOrigin=options.scriptExecutionContext;var context;var executionContexts=frame.target().runtimeModel.executionContexts();if(contextSecurityOrigin){for(var i=0;i<executionContexts.length;++i){var executionContext=executionContexts[i];if(executionContext.frameId===frame.id&&executionContext.origin===contextSecurityOrigin&&!executionContext.isDefault)
context=executionContext;}
if(!context){console.warn("The JavaScript context "+contextSecurityOrigin+" was not found in the frame "+frame.url)
return this._status.E_NOTFOUND(contextSecurityOrigin)}}else{for(var i=0;i<executionContexts.length;++i){var executionContext=executionContexts[i];if(executionContext.frameId===frame.id&&executionContext.isDefault)
context=executionContext;}
if(!context)
return this._status.E_FAILED(frame.url+" has no execution context");}
contextId=context.id;}
var target=target?target:WebInspector.targetManager.mainTarget();if(!target)
return;target.runtimeAgent().evaluate(expression,"extension",exposeCommandLineAPI,true,contextId,returnByValue,false,false,onEvalute);function onEvalute(error,result,wasThrown)
{if(error){callback(error,null,wasThrown);return;}
callback(error,target.runtimeModel.createRemoteObject(result),wasThrown);}},__proto__:WebInspector.Object.prototype}
WebInspector.ExtensionServerPanelDescriptor=function(name,title,panel)
{this._name=name;this._title=title;this._panel=panel;}
WebInspector.ExtensionServerPanelDescriptor.prototype={name:function()
{return this._name;},title:function()
{return this._title;},panel:function()
{return Promise.resolve(this._panel);}}
WebInspector.ExtensionStatus=function()
{function makeStatus(code,description)
{var details=Array.prototype.slice.call(arguments,2);var status={code:code,description:description,details:details};if(code!=="OK"){status.isError=true;console.log("Extension server error: "+String.vsprintf(description,details));}
return status;}
this.OK=makeStatus.bind(null,"OK","OK");this.E_EXISTS=makeStatus.bind(null,"E_EXISTS","Object already exists: %s");this.E_BADARG=makeStatus.bind(null,"E_BADARG","Invalid argument %s: %s");this.E_BADARGTYPE=makeStatus.bind(null,"E_BADARGTYPE","Invalid type for argument %s: got %s, expected %s");this.E_NOTFOUND=makeStatus.bind(null,"E_NOTFOUND","Object not found: %s");this.E_NOTSUPPORTED=makeStatus.bind(null,"E_NOTSUPPORTED","Object does not support requested operation: %s");this.E_PROTOCOLERROR=makeStatus.bind(null,"E_PROTOCOLERROR","Inspector protocol error: %s");this.E_FAILED=makeStatus.bind(null,"E_FAILED","Operation failed: %s");}
WebInspector.ExtensionStatus.Record;WebInspector.extensionAPI={};defineCommonExtensionSymbols(WebInspector.extensionAPI);WebInspector.extensionServer;;WebInspector.ExtensionPanel=function(server,panelName,id,pageURL)
{WebInspector.Panel.call(this,panelName);this._server=server;this._id=id;this.setHideOnDetach();this._panelToolbar=new WebInspector.Toolbar("hidden",this.element);this._searchableView=new WebInspector.SearchableView(this);this._searchableView.show(this.element);var extensionView=new WebInspector.ExtensionView(server,this._id,pageURL,"extension");extensionView.show(this._searchableView.element);this.setDefaultFocusedElement(extensionView.defaultFocusedElement());}
WebInspector.ExtensionPanel.prototype={defaultFocusedElement:function()
{return WebInspector.Widget.prototype.defaultFocusedElement.call(this);},addToolbarItem:function(item)
{this._panelToolbar.element.classList.remove("hidden");this._panelToolbar.appendToolbarItem(item);},searchCanceled:function()
{this._server.notifySearchAction(this._id,WebInspector.extensionAPI.panels.SearchAction.CancelSearch);this._searchableView.updateSearchMatchesCount(0);},searchableView:function()
{return this._searchableView;},performSearch:function(searchConfig,shouldJump,jumpBackwards)
{var query=searchConfig.query;this._server.notifySearchAction(this._id,WebInspector.extensionAPI.panels.SearchAction.PerformSearch,query);},jumpToNextSearchResult:function()
{this._server.notifySearchAction(this._id,WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);},jumpToPreviousSearchResult:function()
{this._server.notifySearchAction(this._id,WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);},supportsCaseSensitiveSearch:function()
{return false;},supportsRegexSearch:function()
{return false;},__proto__:WebInspector.Panel.prototype}
WebInspector.ExtensionButton=function(server,id,iconURL,tooltip,disabled)
{this._id=id;this._toolbarButton=new WebInspector.ToolbarButton("","");this._toolbarButton.addEventListener("click",server.notifyButtonClicked.bind(server,this._id));this.update(iconURL,tooltip,disabled);}
WebInspector.ExtensionButton.prototype={update:function(iconURL,tooltip,disabled)
{if(typeof iconURL==="string")
this._toolbarButton.setBackgroundImage(iconURL);if(typeof tooltip==="string")
this._toolbarButton.setTitle(tooltip);if(typeof disabled==="boolean")
this._toolbarButton.setEnabled(!disabled);},toolbarButton:function()
{return this._toolbarButton;}}
WebInspector.ExtensionSidebarPane=function(server,panelName,title,id)
{WebInspector.SidebarPane.call(this,title);this.element.classList.add("fill");this._panelName=panelName;this._server=server;this._id=id;}
WebInspector.ExtensionSidebarPane.prototype={id:function()
{return this._id;},panelName:function()
{return this._panelName;},setObject:function(object,title,callback)
{this._createObjectPropertiesView();this._setObject(WebInspector.RemoteObject.fromLocalObject(object),title,callback);},setExpression:function(expression,title,evaluateOptions,securityOrigin,callback)
{this._createObjectPropertiesView();this._server.evaluate(expression,true,false,evaluateOptions,securityOrigin,this._onEvaluate.bind(this,title,callback));},setPage:function(url)
{if(this._objectPropertiesView){this._objectPropertiesView.detach();delete this._objectPropertiesView;}
if(this._extensionView)
this._extensionView.detach(true);this._extensionView=new WebInspector.ExtensionView(this._server,this._id,url,"extension fill");this._extensionView.show(this.element);},_onEvaluate:function(title,callback,error,result,wasThrown)
{if(error)
callback(error.toString());else
this._setObject((result),title,callback);},_createObjectPropertiesView:function()
{if(this._objectPropertiesView)
return;if(this._extensionView){this._extensionView.detach(true);delete this._extensionView;}
this._objectPropertiesView=new WebInspector.ExtensionNotifierView(this._server,this._id);this._objectPropertiesView.show(this.element);},_setObject:function(object,title,callback)
{if(!this._objectPropertiesView){callback("operation cancelled");return;}
this._objectPropertiesView.element.removeChildren();var section=new WebInspector.ObjectPropertiesSection(object,title);if(!title)
section.titleLessMode();section.expand();section.editable=false;this._objectPropertiesView.element.appendChild(section.element);callback();},__proto__:WebInspector.SidebarPane.prototype};WebInspector.ExtensionView=function(server,id,src,className)
{WebInspector.Widget.call(this);this.setHideOnDetach();this.element.className="vbox flex-auto";this._server=server;this._id=id;this._iframe=createElement("iframe");this._iframe.addEventListener("load",this._onLoad.bind(this),false);this._iframe.src=src;this._iframe.className=className;this.setDefaultFocusedElement(this._iframe);this.element.appendChild(this._iframe);}
WebInspector.ExtensionView.prototype={wasShown:function()
{if(typeof this._frameIndex==="number")
this._server.notifyViewShown(this._id,this._frameIndex);},willHide:function()
{if(typeof this._frameIndex==="number")
this._server.notifyViewHidden(this._id);},_onLoad:function()
{var frames=(window.frames);this._frameIndex=Array.prototype.indexOf.call(frames,this._iframe.contentWindow);if(this.isShowing())
this._server.notifyViewShown(this._id,this._frameIndex);},__proto__:WebInspector.Widget.prototype}
WebInspector.ExtensionNotifierView=function(server,id)
{WebInspector.VBox.call(this);this._server=server;this._id=id;}
WebInspector.ExtensionNotifierView.prototype={wasShown:function()
{this._server.notifyViewShown(this._id);},willHide:function()
{this._server.notifyViewHidden(this._id);},__proto__:WebInspector.VBox.prototype};WebInspector.RenderingOptionsView=function()
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("main/renderingOptions.css");this._settings=new Map();var options=[{label:WebInspector.UIString("Paint Flashing"),subtitle:WebInspector.UIString("Highlights areas of the page that need to be repainted"),setterName:"setShowPaintRects"},{label:WebInspector.UIString("Layer Borders"),subtitle:WebInspector.UIString("Shows layer borders (orange/olive) and tiles (cyan)"),setterName:"setShowDebugBorders"},{label:WebInspector.UIString("FPS Meter"),subtitle:WebInspector.UIString("Plots frames per second, frame rate distribution, and GPU memory"),setterName:"setShowFPSCounter"},{label:WebInspector.UIString("Scrolling Performance Issues"),subtitle:WebInspector.UIString("Shows areas of the page that slow down scrolling"),setterName:"setShowScrollBottleneckRects",tooltip:"Touch and mousewheel event listeners can delay scrolling.\nSome areas need to repaint their content when scrolled."}];for(var i=0;i<options.length;i++)
this._appendCheckbox(options[i].label,options[i].setterName,options[i].subtitle,options[i].tooltip);this.contentElement.createChild("div").classList.add("panel-section-separator");var cssMediaSubtitle=WebInspector.UIString("Forces media type for testing print and screen styles");var checkboxLabel=createCheckboxLabel(WebInspector.UIString("Emulate CSS Media"),false,cssMediaSubtitle);this._mediaCheckbox=checkboxLabel.checkboxElement;this._mediaCheckbox.addEventListener("click",this._mediaToggled.bind(this),false);this.contentElement.appendChild(checkboxLabel);var mediaRow=this.contentElement.createChild("div","media-row");this._mediaSelect=mediaRow.createChild("select","chrome-select");this._mediaSelect.appendChild(new Option(WebInspector.UIString("print"),"print"));this._mediaSelect.appendChild(new Option(WebInspector.UIString("screen"),"screen"));this._mediaSelect.addEventListener("change",this._mediaToggled.bind(this),false);this._mediaSelect.disabled=true;WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);}
WebInspector.RenderingOptionsView.prototype={_appendCheckbox:function(label,setterName,subtitle,tooltip)
{var checkboxLabel=createCheckboxLabel(label,false,subtitle);this._settings.set(setterName,checkboxLabel.checkboxElement);checkboxLabel.checkboxElement.addEventListener("click",this._settingToggled.bind(this,setterName));if(tooltip)
checkboxLabel.title=tooltip;this.contentElement.appendChild(checkboxLabel);},_settingToggled:function(setterName)
{var enabled=this._settings.get(setterName).checked;var targets=WebInspector.targetManager.targets(WebInspector.Target.Type.Page);for(var i=0;i<targets.length;++i)
targets[i].renderingAgent()[setterName](enabled);},targetAdded:function(target)
{for(var setterName of this._settings.keysArray()){if(this._settings.get(setterName).checked)
target.renderingAgent()[setterName](true);}
if(this._mediaCheckbox.checked)
this._applyPrintMediaOverride(target);},_mediaToggled:function()
{this._mediaSelect.disabled=!this._mediaCheckbox.checked;var targets=WebInspector.targetManager.targets(WebInspector.Target.Type.Page);for(var target of targets)
this._applyPrintMediaOverride(target);},_applyPrintMediaOverride:function(target)
{target.emulationAgent().setEmulatedMedia(this._mediaCheckbox.checked?this._mediaSelect.value:"");var cssModel=WebInspector.CSSModel.fromTarget(target);if(cssModel)
cssModel.mediaQueryResultChanged();},targetRemoved:function(target)
{},__proto__:WebInspector.VBox.prototype}
WebInspector.RenderingOptionsView.instance=function()
{if(!WebInspector.RenderingOptionsView._instanceObject)
WebInspector.RenderingOptionsView._instanceObject=new WebInspector.RenderingOptionsView();return WebInspector.RenderingOptionsView._instanceObject;}
WebInspector.RenderingOptionsView.ShowActionDelegate=function()
{}
WebInspector.RenderingOptionsView.ShowActionDelegate.prototype={handleAction:function(context,actionId)
{WebInspector.inspectorView.showViewInDrawer("rendering");return true;}};WebInspector.SimpleApp=function()
{};WebInspector.SimpleApp.prototype={presentUI:function(document)
{var rootView=new WebInspector.RootView();WebInspector.inspectorView.show(rootView.element);WebInspector.inspectorView.showInitialPanel();rootView.attachToDocument(document);}};WebInspector.SimpleAppProvider=function()
{};WebInspector.SimpleAppProvider.prototype={createApp:function()
{return new WebInspector.SimpleApp();}};;WebInspector.OverlayController=function()
{WebInspector.moduleSetting("disablePausedStateOverlay").addChangeListener(this._updateOverlayMessage,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerPaused,this._updateOverlayMessage,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerResumed,this._updateOverlayMessage,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._updateOverlayMessage,this);}
WebInspector.OverlayController.prototype={_updateOverlayMessage:function(event)
{var debuggerModel=(event.target);var message=debuggerModel.isPaused()&&!WebInspector.moduleSetting("disablePausedStateOverlay").get()?WebInspector.UIString("Paused in debugger"):undefined;debuggerModel.target().pageAgent().setOverlayMessage(message);}};WebInspector.MainConnection=function()
{InspectorBackendClass.Connection.call(this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DispatchMessage,this._dispatchMessage,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DispatchMessageChunk,this._dispatchMessageChunk,this);}
WebInspector.MainConnection.prototype={sendMessage:function(messageObject)
{var message=JSON.stringify(messageObject);InspectorFrontendHost.sendMessageToBackend(message);},_dispatchMessage:function(event)
{this.dispatch((event.data));},_dispatchMessageChunk:function(event)
{var messageChunk=(event.data["messageChunk"]);var messageSize=(event.data["messageSize"]);if(messageSize){this._messageBuffer="";this._messageSize=messageSize;}
this._messageBuffer+=messageChunk;if(this._messageBuffer.length===this._messageSize){this.dispatch(this._messageBuffer);this._messageBuffer="";this._messageSize=0;}},__proto__:InspectorBackendClass.Connection.prototype}
WebInspector.WebSocketConnection=function(url,onConnectionReady)
{InspectorBackendClass.Connection.call(this);this._socket=new WebSocket(url);this._socket.onmessage=this._onMessage.bind(this);this._socket.onerror=this._onError.bind(this);this._socket.onopen=onConnectionReady.bind(null,this);this._socket.onclose=this.connectionClosed.bind(this,"websocket_closed");}
WebInspector.WebSocketConnection.Create=function(url,onConnectionReady)
{new WebInspector.WebSocketConnection(url,onConnectionReady);}
WebInspector.WebSocketConnection.prototype={_onMessage:function(message)
{var data=(message.data);this.dispatch(data);},_onError:function(error)
{console.error(error);},sendMessage:function(messageObject)
{var message=JSON.stringify(messageObject);this._socket.send(message);},__proto__:InspectorBackendClass.Connection.prototype}
WebInspector.StubConnection=function()
{InspectorBackendClass.Connection.call(this);}
WebInspector.StubConnection.prototype={sendMessage:function(messageObject)
{setTimeout(this._respondWithError.bind(this,messageObject),0);},_respondWithError:function(messageObject)
{var error={message:"This is a stub connection, can't dispatch message.",code:InspectorBackendClass.DevToolsStubErrorCode,data:messageObject};this.dispatch({id:messageObject.id,error:error});},__proto__:InspectorBackendClass.Connection.prototype};WebInspector.Main=function()
{WebInspector.console.setUIDelegate(this);WebInspector.Main._instanceForTest=this;runOnWindowLoad(this._loaded.bind(this));}
WebInspector.Main.prototype={showConsole:function()
{return WebInspector.Revealer.revealPromise(WebInspector.console);},_loaded:function()
{console.timeStamp("Main._loaded");if(InspectorFrontendHost.isUnderTest())
self.runtime.useTestBase();InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));},_gotPreferences:function(prefs)
{console.timeStamp("Main._gotPreferences");this._createSettings(prefs);this._createAppUI();},_createSettings:function(prefs)
{var settingsParam=Runtime.queryParam("settings");if(settingsParam){try{var settings=JSON.parse(window.decodeURI(settingsParam));for(var key in settings)
prefs[key]=settings[key];}catch(e){}}
this._initializeExperiments(prefs);WebInspector.settings=new WebInspector.Settings(new WebInspector.SettingsStorage(prefs,InspectorFrontendHost.setPreference,InspectorFrontendHost.removePreference,InspectorFrontendHost.clearPreferences));if(!InspectorFrontendHost.isUnderTest())
new WebInspector.VersionController().updateVersion();},_initializeExperiments:function(prefs)
{Runtime.experiments.register("accessibilityInspection","Accessibility Inspection");Runtime.experiments.register("applyCustomStylesheet","Allow custom UI themes");Runtime.experiments.register("blackboxJSFramesOnTimeline","Blackbox JavaScript frames on Timeline",true);Runtime.experiments.register("colorContrastRatio","Contrast ratio line in color picker",true);Runtime.experiments.register("continueToFirstInvocation","Continue to first invocation");Runtime.experiments.register("cpuThrottling","CPU throttling");Runtime.experiments.register("emptySourceMapAutoStepping","Empty sourcemap auto-stepping");Runtime.experiments.register("inputEventsOnTimelineOverview","Input events on Timeline overview",true);Runtime.experiments.register("layersPanel","Layers panel");Runtime.experiments.register("layoutEditor","Layout editor",true);Runtime.experiments.register("inspectTooltip","Dark inspect element tooltip");Runtime.experiments.register("liveSASS","Live SASS",true);Runtime.experiments.register("privateScriptInspection","Private script inspection");Runtime.experiments.register("requestBlocking","Request blocking",true);Runtime.experiments.register("resolveVariableNames","Resolve variable names");Runtime.experiments.register("timelineShowAllEvents","Show all events on Timeline",true);Runtime.experiments.register("securityPanel","Security panel");Runtime.experiments.register("sourceDiff","Source diff");Runtime.experiments.register("timelineFlowEvents","Timeline flow events",true);Runtime.experiments.register("timelineInvalidationTracking","Timeline invalidation tracking",true);Runtime.experiments.register("timelineRecordingPerspectives","Timeline recording perspectives UI");Runtime.experiments.register("timelineTracingJSProfile","Timeline tracing based JS profiler",true);Runtime.experiments.cleanUpStaleExperiments();if(InspectorFrontendHost.isUnderTest()){var testPath=JSON.parse(prefs["testPath"]||"\"\"");if(testPath.indexOf("layers/")!==-1)
Runtime.experiments.enableForTest("layersPanel");if(testPath.indexOf("timeline/")!==-1||testPath.indexOf("layers/")!==-1)
Runtime.experiments.enableForTest("layersPanel");if(testPath.indexOf("security/")!==-1)
Runtime.experiments.enableForTest("securityPanel");}
Runtime.experiments.setDefaultExperiments(["inspectTooltip","securityPanel","resolveVariableNames"]);},_createAppUI:function()
{console.timeStamp("Main._createApp");WebInspector.isolatedFileSystemManager=new WebInspector.IsolatedFileSystemManager();WebInspector.isolatedFileSystemManager.initialize(this._didInitializeFileSystemManager.bind(this));var themeSetting=WebInspector.settings.createSetting("uiTheme","default");WebInspector.initializeUIUtils(document,themeSetting);themeSetting.addChangeListener(WebInspector.reload.bind(WebInspector));WebInspector.installComponentRootStyles((document.body));this._addMainEventListeners(document);var canDock=!!Runtime.queryParam("can_dock");WebInspector.zoomManager=new WebInspector.ZoomManager(window,InspectorFrontendHost);WebInspector.inspectorView=new WebInspector.InspectorView();WebInspector.ContextMenu.initialize();WebInspector.ContextMenu.installHandler(document);WebInspector.Tooltip.installHandler(document);WebInspector.dockController=new WebInspector.DockController(canDock);WebInspector.multitargetConsoleModel=new WebInspector.MultitargetConsoleModel();WebInspector.multitargetNetworkManager=new WebInspector.MultitargetNetworkManager();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged.bind(this));WebInspector.shortcutsScreen=new WebInspector.ShortcutsScreen();WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));WebInspector.shortcutsScreen.section(WebInspector.UIString("Debugger"));WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));WebInspector.fileManager=new WebInspector.FileManager();WebInspector.workspace=new WebInspector.Workspace();WebInspector.formatterWorkerPool=new WebInspector.FormatterWorkerPool();WebInspector.fileSystemMapping=new WebInspector.FileSystemMapping();var fileSystemWorkspaceBinding=new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager,WebInspector.workspace);WebInspector.networkMapping=new WebInspector.NetworkMapping(WebInspector.targetManager,WebInspector.workspace,fileSystemWorkspaceBinding,WebInspector.fileSystemMapping);WebInspector.networkProjectManager=new WebInspector.NetworkProjectManager(WebInspector.targetManager,WebInspector.workspace,WebInspector.networkMapping);WebInspector.presentationConsoleMessageHelper=new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);WebInspector.cssWorkspaceBinding=new WebInspector.CSSWorkspaceBinding(WebInspector.targetManager,WebInspector.workspace,WebInspector.networkMapping);WebInspector.debuggerWorkspaceBinding=new WebInspector.DebuggerWorkspaceBinding(WebInspector.targetManager,WebInspector.workspace,WebInspector.networkMapping);WebInspector.breakpointManager=new WebInspector.BreakpointManager(null,WebInspector.workspace,WebInspector.networkMapping,WebInspector.targetManager,WebInspector.debuggerWorkspaceBinding);WebInspector.extensionServer=new WebInspector.ExtensionServer();new WebInspector.OverlayController();new WebInspector.ExecutionContextSelector(WebInspector.targetManager,WebInspector.context);WebInspector.blackboxManager=new WebInspector.BlackboxManager(WebInspector.debuggerWorkspaceBinding,WebInspector.networkMapping);var autoselectPanel=WebInspector.UIString("auto");var openAnchorLocationSetting=WebInspector.settings.createSetting("openLinkHandler",autoselectPanel);WebInspector.openAnchorLocationRegistry=new WebInspector.HandlerRegistry(openAnchorLocationSetting);WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel,function(){return false;});WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());new WebInspector.Main.PauseListener();new WebInspector.Main.InspectedNodeRevealer();new WebInspector.NetworkPanelIndicator();new WebInspector.SourcesPanelIndicator();new WebInspector.BackendSettingsSync();WebInspector.domBreakpointsSidebarPane=new WebInspector.DOMBreakpointsSidebarPane();WebInspector.actionRegistry=new WebInspector.ActionRegistry();WebInspector.shortcutRegistry=new WebInspector.ShortcutRegistry(WebInspector.actionRegistry,document);WebInspector.ShortcutsScreen.registerShortcuts();this._registerForwardedShortcuts();this._registerMessageSinkListener();var appExtension=self.runtime.extensions(WebInspector.AppProvider)[0];appExtension.instancePromise().then(this._showAppUI.bind(this));},_showAppUI:function(appProvider)
{var app=(appProvider).createApp();WebInspector.dockController.initialize();console.timeStamp("Main._presentUI");app.presentUI(document);var toggleSearchNodeAction=WebInspector.actionRegistry.action("elements.toggle-element-search");if(toggleSearchNodeAction)
InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.EnterInspectElementMode,toggleSearchNodeAction.execute.bind(toggleSearchNodeAction),this);WebInspector.inspectorView.createToolbars();InspectorFrontendHost.loadCompleted();var extensions=self.runtime.extensions(WebInspector.QueryParamHandler);for(var extension of extensions){var value=Runtime.queryParam(extension.descriptor()["name"]);if(value!==null)
extension.instancePromise().then(handleQueryParam.bind(null,value));}
function handleQueryParam(value,handler)
{handler.handleQueryParam(value);}
this._appUIShown=true;if(this._fileSystemManagerInitialized){setTimeout(this._createConnection.bind(this),0);}},_didInitializeFileSystemManager:function()
{this._fileSystemManagerInitialized=true;if(this._appUIShown)
this._createConnection();},_createConnection:function()
{console.timeStamp("Main._createConnection");if(Runtime.queryParam("ws")){var ws="ws://"+Runtime.queryParam("ws");WebInspector.WebSocketConnection.Create(ws,this._connectionEstablished.bind(this));return;}
if(!InspectorFrontendHost.isHostedMode()){this._connectionEstablished(new WebInspector.MainConnection());return;}
this._connectionEstablished(new WebInspector.StubConnection());},_connectionEstablished:function(connection)
{console.timeStamp("Main._connectionEstablished");this._mainConnection=connection;connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected,onDisconnected);function onDisconnected(event)
{if(WebInspector._disconnectedScreenWithReasonWasShown)
return;WebInspector.RemoteDebuggingTerminatedScreen.show(event.data.reason);}
var targetType=Runtime.queryParam("isSharedWorker")?WebInspector.Target.Type.ServiceWorker:WebInspector.Target.Type.Page;this._mainTarget=WebInspector.targetManager.createTarget(WebInspector.UIString("Main"),targetType,connection,null);console.timeStamp("Main._mainTargetCreated");this._registerShortcuts();this._mainTarget.registerInspectorDispatcher(this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ReloadInspectedPage,this._reloadInspectedPage,this);InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.EvaluateForTestInFrontend,this._evaluateForTestInFrontend,this);if(this._mainTarget.isServiceWorker()||this._mainTarget.isPage())
this._mainTarget.runtimeAgent().run();this._mainTarget.inspectorAgent().enable();InspectorFrontendHost.readyForTest();setTimeout(lateInitialization,0);function lateInitialization()
{console.timeStamp("Main.lateInitialization");WebInspector.extensionServer.initializeExtensions();}},_registerForwardedShortcuts:function()
{var forwardedActions=["main.toggle-dock","debugger.toggle-breakpoints-active","debugger.toggle-pause","commandMenu.show"];var actionKeys=WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey);InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));},_registerMessageSinkListener:function()
{WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded,messageAdded);function messageAdded(event)
{var message=(event.data);if(message.show)
WebInspector.console.show();}},_documentClick:function(event)
{var target=event.target;if(target.shadowRoot)
target=event.deepElementFromPoint();if(!target)
return;var anchor=target.enclosingNodeOrSelfWithNodeName("a");if(!anchor||!anchor.href)
return;event.consume(true);if(anchor.preventFollow)
return;function followLink()
{if(WebInspector.isBeingEdited(target))
return;if(WebInspector.openAnchorLocationRegistry.dispatch({url:anchor.href,lineNumber:anchor.lineNumber}))
return;var uiSourceCode=WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(anchor.href);if(uiSourceCode){WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber||0,anchor.columnNumber||0));return;}
var resource=WebInspector.resourceForURL(anchor.href);if(resource){WebInspector.Revealer.reveal(resource);return;}
var request=WebInspector.NetworkLog.requestForURL(anchor.href);if(request){WebInspector.Revealer.reveal(request);return;}
InspectorFrontendHost.openInNewTab(anchor.href);}
if(WebInspector.followLinkTimeout)
clearTimeout(WebInspector.followLinkTimeout);if(anchor.preventFollowOnDoubleClick){if(event.detail===1)
WebInspector.followLinkTimeout=setTimeout(followLink,333);return;}
if(!anchor.classList.contains("webkit-html-external-link"))
followLink();else
InspectorFrontendHost.openInNewTab(anchor.href);},_registerShortcuts:function()
{var shortcut=WebInspector.KeyboardShortcut;var section=WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));var keys=[shortcut.makeDescriptor("[",shortcut.Modifiers.CtrlOrMeta),shortcut.makeDescriptor("]",shortcut.Modifiers.CtrlOrMeta)];section.addRelatedKeys(keys,WebInspector.UIString("Go to the panel to the left/right"));keys=[shortcut.makeDescriptor("[",shortcut.Modifiers.CtrlOrMeta|shortcut.Modifiers.Alt),shortcut.makeDescriptor("]",shortcut.Modifiers.CtrlOrMeta|shortcut.Modifiers.Alt)];section.addRelatedKeys(keys,WebInspector.UIString("Go back/forward in panel history"));var toggleConsoleLabel=WebInspector.UIString("Show console");section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde,shortcut.Modifiers.Ctrl),toggleConsoleLabel);section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc),WebInspector.UIString("Toggle drawer"));if(WebInspector.dockController.canDock()){section.addKey(shortcut.makeDescriptor("M",shortcut.Modifiers.CtrlOrMeta|shortcut.Modifiers.Shift),WebInspector.UIString("Toggle device mode"));section.addKey(shortcut.makeDescriptor("D",shortcut.Modifiers.CtrlOrMeta|shortcut.Modifiers.Shift),WebInspector.UIString("Toggle dock side"));}
section.addKey(shortcut.makeDescriptor("f",shortcut.Modifiers.CtrlOrMeta),WebInspector.UIString("Search"));var advancedSearchShortcutModifier=WebInspector.isMac()?WebInspector.KeyboardShortcut.Modifiers.Meta|WebInspector.KeyboardShortcut.Modifiers.Alt:WebInspector.KeyboardShortcut.Modifiers.Ctrl|WebInspector.KeyboardShortcut.Modifiers.Shift;var advancedSearchShortcut=shortcut.makeDescriptor("f",advancedSearchShortcutModifier);section.addKey(advancedSearchShortcut,WebInspector.UIString("Search across all sources"));var inspectElementModeShortcuts=WebInspector.shortcutRegistry.shortcutDescriptorsForAction("elements.toggle-element-search");if(inspectElementModeShortcuts.length)
section.addKey(inspectElementModeShortcuts[0],WebInspector.UIString("Select node to inspect"));var openResourceShortcut=WebInspector.KeyboardShortcut.makeDescriptor("p",WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);section.addKey(openResourceShortcut,WebInspector.UIString("Go to source"));if(WebInspector.isMac()){keys=[shortcut.makeDescriptor("g",shortcut.Modifiers.Meta),shortcut.makeDescriptor("g",shortcut.Modifiers.Meta|shortcut.Modifiers.Shift)];section.addRelatedKeys(keys,WebInspector.UIString("Find next/previous"));}},_postDocumentKeyDown:function(event)
{if(event.handled)
return;var target=event.deepActiveElement();if(target){var anchor=target.enclosingNodeOrSelfWithNodeName("a");if(anchor&&anchor.preventFollow)
event.preventDefault();}
if(!WebInspector.Dialog.hasInstance()&&WebInspector.inspectorView.currentPanel()){WebInspector.inspectorView.currentPanel().handleShortcut(event);if(event.handled){event.consume(true);return;}}
WebInspector.shortcutRegistry.handleShortcut(event);},_documentCanCopy:function(event)
{var panel=WebInspector.inspectorView.currentPanel();if(panel&&panel["handleCopyEvent"])
event.preventDefault();},_documentCopy:function(event)
{var panel=WebInspector.inspectorView.currentPanel();if(panel&&panel["handleCopyEvent"])
panel["handleCopyEvent"](event);},_documentCut:function(event)
{var panel=WebInspector.inspectorView.currentPanel();if(panel&&panel["handleCutEvent"])
panel["handleCutEvent"](event);},_documentPaste:function(event)
{var panel=WebInspector.inspectorView.currentPanel();if(panel&&panel["handlePasteEvent"])
panel["handlePasteEvent"](event);},_contextMenuEventFired:function(event)
{if(event.handled||event.target.classList.contains("popup-glasspane"))
event.preventDefault();},_addMainEventListeners:function(document)
{document.addEventListener("keydown",this._postDocumentKeyDown.bind(this),false);document.addEventListener("beforecopy",this._documentCanCopy.bind(this),true);document.addEventListener("copy",this._documentCopy.bind(this),false);document.addEventListener("cut",this._documentCut.bind(this),false);document.addEventListener("paste",this._documentPaste.bind(this),false);document.addEventListener("contextmenu",this._contextMenuEventFired.bind(this),true);document.addEventListener("click",this._documentClick.bind(this),false);},_reloadInspectedPage:function(event)
{var hard=(event.data);WebInspector.Main._reloadPage(hard);},detached:function(reason)
{WebInspector._disconnectedScreenWithReasonWasShown=true;WebInspector.RemoteDebuggingTerminatedScreen.show(reason);},targetCrashed:function()
{var debuggerModel=WebInspector.DebuggerModel.fromTarget(this._mainTarget);if(debuggerModel)
WebInspector.TargetCrashedScreen.show(debuggerModel);},_onSuspendStateChanged:function()
{var suspended=WebInspector.targetManager.allTargetsSuspended();WebInspector.inspectorView.onSuspendStateChanged(suspended);},_evaluateForTestInFrontend:function(event)
{if(!InspectorFrontendHost.isUnderTest())
return;var callId=(event.data["callId"]);var script=(event.data["script"]);function invokeMethod()
{try{script=script+"//# sourceURL=evaluateInWebInspector"+callId+".js";window.eval(script);}catch(e){console.error(e.stack);}}
this._mainConnection.deprecatedRunAfterPendingDispatches(invokeMethod);}}
WebInspector.Main.ReloadActionDelegate=function()
{}
WebInspector.Main.ReloadActionDelegate.prototype={handleAction:function(context,actionId)
{switch(actionId){case"main.reload":WebInspector.Main._reloadPage(false);return true;case"main.hard-reload":WebInspector.Main._reloadPage(true);return true;case"main.debug-reload":WebInspector.reload();return true;}
return false;}}
WebInspector.Main.ZoomActionDelegate=function()
{}
WebInspector.Main.ZoomActionDelegate.prototype={handleAction:function(context,actionId)
{if(InspectorFrontendHost.isHostedMode())
return false;switch(actionId){case"main.zoom-in":InspectorFrontendHost.zoomIn();return true;case"main.zoom-out":InspectorFrontendHost.zoomOut();return true;case"main.zoom-reset":InspectorFrontendHost.resetZoom();return true;}
return false;}}
WebInspector.Main.SearchActionDelegate=function()
{}
WebInspector.Main.SearchActionDelegate.prototype={handleAction:function(context,actionId)
{var searchableView=WebInspector.SearchableView.fromElement(WebInspector.currentFocusElement())||WebInspector.inspectorView.currentPanel().searchableView();if(!searchableView)
return false;switch(actionId){case"main.search-in-panel.find":return searchableView.handleFindShortcut();case"main.search-in-panel.cancel":return searchableView.handleCancelSearchShortcut();case"main.search-in-panel.find-next":return searchableView.handleFindNextShortcut();case"main.search-in-panel.find-previous":return searchableView.handleFindPreviousShortcut();}
return false;}}
WebInspector.Main._reloadPage=function(hard)
{if(!WebInspector.targetManager.hasTargets())
return;if(WebInspector.targetManager.mainTarget().isServiceWorker())
return;WebInspector.targetManager.reloadPage(hard);}
WebInspector.Main._addWebSocketTarget=function(ws)
{function callback(connection)
{WebInspector.targetManager.createTarget(ws,WebInspector.Target.Type.Page,connection,null);}
new WebInspector.WebSocketConnection(ws,callback);}
WebInspector.Main.WarningErrorCounter=function()
{WebInspector.Main.WarningErrorCounter._instanceForTest=this;this._counter=createElement("div");this._counter.addEventListener("click",WebInspector.console.show.bind(WebInspector.console),false);this._toolbarItem=new WebInspector.ToolbarItem(this._counter);var shadowRoot=WebInspector.createShadowRootWithCoreStyles(this._counter,"main/errorWarningCounter.css");this._errors=this._createItem(shadowRoot,"error-icon");this._revokedErrors=this._createItem(shadowRoot,"revokedError-icon");this._warnings=this._createItem(shadowRoot,"warning-icon");this._titles=[];WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared,this._update,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded,this._update,this);WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageUpdated,this._update,this);this._update();}
WebInspector.Main.WarningErrorCounter.prototype={_createItem:function(shadowRoot,iconType)
{var item=createElementWithClass("span","counter-item");var icon=item.createChild("label","","dt-icon-label");icon.type=iconType;var text=icon.createChild("span");shadowRoot.appendChild(item);return{item:item,text:text};},_updateItem:function(item,count,first,title)
{item.item.classList.toggle("hidden",!count);item.item.classList.toggle("counter-item-first",first);item.text.textContent=count;if(count)
this._titles.push(title);},_update:function()
{var errors=0;var revokedErrors=0;var warnings=0;var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i){errors+=targets[i].consoleModel.errors();revokedErrors+=targets[i].consoleModel.revokedErrors();warnings+=targets[i].consoleModel.warnings();}
this._titles=[];this._toolbarItem.setVisible(!!(errors||revokedErrors||warnings));this._updateItem(this._errors,errors,false,WebInspector.UIString(errors===1?"%d error":"%d errors",errors));this._updateItem(this._revokedErrors,revokedErrors,!errors,WebInspector.UIString(revokedErrors===1?"%d handled promise rejection":"%d handled promise rejections",revokedErrors));this._updateItem(this._warnings,warnings,!errors&&!revokedErrors,WebInspector.UIString(warnings===1?"%d warning":"%d warnings",warnings));this._counter.title=this._titles.join(", ");WebInspector.inspectorView.toolbarItemResized();},item:function()
{return this._toolbarItem;}}
WebInspector.Main.MainMenuItem=function()
{this._item=new WebInspector.ToolbarButton(WebInspector.UIString("Customize and control DevTools"),"menu-toolbar-item");this._item.addEventListener("mousedown",this._mouseDown,this);}
WebInspector.Main.MainMenuItem.prototype={item:function()
{return this._item;},_mouseDown:function(event)
{var contextMenu=new WebInspector.ContextMenu((event.data),true,this._item.element.totalOffsetLeft(),this._item.element.totalOffsetTop()+this._item.element.offsetHeight);if(WebInspector.dockController.canDock()){var dockItemElement=createElementWithClass("div","flex-centered flex-auto");var titleElement=dockItemElement.createChild("span","flex-auto");titleElement.textContent=WebInspector.UIString("Dock side");var toggleDockSideShorcuts=WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.toggle-dock");titleElement.title=WebInspector.UIString("Placement of DevTools relative to the page. (%s to restore last position)",toggleDockSideShorcuts[0].name);dockItemElement.appendChild(titleElement);var dockItemToolbar=new WebInspector.Toolbar("",dockItemElement);dockItemToolbar.makeBlueOnHover();var undock=new WebInspector.ToolbarToggle(WebInspector.UIString("Undock into separate window"),"dock-toolbar-item-undock");var bottom=new WebInspector.ToolbarToggle(WebInspector.UIString("Dock to bottom"),"dock-toolbar-item-bottom");var right=new WebInspector.ToolbarToggle(WebInspector.UIString("Dock to right"),"dock-toolbar-item-right");undock.addEventListener("mouseup",setDockSide.bind(null,WebInspector.DockController.State.Undocked));bottom.addEventListener("mouseup",setDockSide.bind(null,WebInspector.DockController.State.DockedToBottom));right.addEventListener("mouseup",setDockSide.bind(null,WebInspector.DockController.State.DockedToRight));undock.setToggled(WebInspector.dockController.dockSide()===WebInspector.DockController.State.Undocked);bottom.setToggled(WebInspector.dockController.dockSide()===WebInspector.DockController.State.DockedToBottom);right.setToggled(WebInspector.dockController.dockSide()===WebInspector.DockController.State.DockedToRight);dockItemToolbar.appendToolbarItem(undock);dockItemToolbar.appendToolbarItem(bottom);dockItemToolbar.appendToolbarItem(right);contextMenu.appendCustomItem(dockItemElement);contextMenu.appendSeparator();}
function setDockSide(side)
{WebInspector.dockController.setDockSide(side);contextMenu.discard();}
contextMenu.appendAction("main.toggle-drawer",WebInspector.inspectorView.drawerVisible()?WebInspector.UIString("Hide console"):WebInspector.UIString("Show console"));contextMenu.appendItemsAtLocation("mainMenu");contextMenu.show();}}
WebInspector.NetworkPanelIndicator=function()
{if(!WebInspector.inspectorView.hasPanel("network"))
return;var manager=WebInspector.multitargetNetworkManager;manager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged,updateVisibility);var blockedURLsSetting=WebInspector.moduleSetting("blockedURLs");blockedURLsSetting.addChangeListener(updateVisibility);updateVisibility();function updateVisibility()
{if(manager.isThrottling()){WebInspector.inspectorView.setPanelIcon("network","warning-icon",WebInspector.UIString("Network throttling is enabled"));}else if(blockedURLsSetting.get().length){WebInspector.inspectorView.setPanelIcon("network","warning-icon",WebInspector.UIString("Requests may be blocked"));}else{WebInspector.inspectorView.setPanelIcon("network","","");}}}
WebInspector.SourcesPanelIndicator=function()
{WebInspector.moduleSetting("javaScriptDisabled").addChangeListener(javaScriptDisabledChanged);javaScriptDisabledChanged();function javaScriptDisabledChanged()
{var javaScriptDisabled=WebInspector.moduleSetting("javaScriptDisabled").get();if(javaScriptDisabled){WebInspector.inspectorView.setPanelIcon("sources","warning-icon",WebInspector.UIString("JavaScript is disabled"));}else{WebInspector.inspectorView.setPanelIcon("sources","","");}}}
WebInspector.Main.PauseListener=function()
{WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerPaused,this._debuggerPaused,this);}
WebInspector.Main.PauseListener.prototype={_debuggerPaused:function(event)
{WebInspector.targetManager.removeModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerPaused,this._debuggerPaused,this);var debuggerPausedDetails=(event.data);var debuggerModel=(event.target);WebInspector.context.setFlavor(WebInspector.Target,debuggerModel.target());WebInspector.Revealer.reveal(debuggerPausedDetails);}}
WebInspector.Main.InspectedNodeRevealer=function()
{WebInspector.targetManager.addModelListener(WebInspector.DOMModel,WebInspector.DOMModel.Events.NodeInspected,this._inspectNode,this);}
WebInspector.Main.InspectedNodeRevealer.prototype={_inspectNode:function(event)
{var deferredNode=(event.data);WebInspector.Revealer.reveal(deferredNode);}}
WebInspector.RemoteDebuggingTerminatedScreen=function(reason)
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("main/remoteDebuggingTerminatedScreen.css");var message=this.contentElement.createChild("div","message");message.createChild("span").textContent=WebInspector.UIString("Debugging connection was closed. Reason: ");message.createChild("span","reason").textContent=reason;this.contentElement.createChild("div","message").textContent=WebInspector.UIString("Reconnect when ready by reopening DevTools.");}
WebInspector.RemoteDebuggingTerminatedScreen.show=function(reason)
{var dialog=new WebInspector.Dialog();dialog.setWrapsContent(true);dialog.addCloseButton();dialog.setDimmed(true);new WebInspector.RemoteDebuggingTerminatedScreen(reason).show(dialog.element);dialog.show();}
WebInspector.RemoteDebuggingTerminatedScreen.prototype={__proto__:WebInspector.VBox.prototype}
WebInspector.TargetCrashedScreen=function(hideCallback)
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("main/targetCrashedScreen.css");this.contentElement.createChild("div","message").textContent=WebInspector.UIString("DevTools was disconnected from the page.");this.contentElement.createChild("div","message").textContent=WebInspector.UIString("Once page is reloaded, DevTools will automatically reconnect.");this._hideCallback=hideCallback;}
WebInspector.TargetCrashedScreen.show=function(debuggerModel)
{var dialog=new WebInspector.Dialog();dialog.setWrapsContent(true);dialog.addCloseButton();dialog.setDimmed(true);var hideBound=dialog.detach.bind(dialog,false);debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,hideBound);new WebInspector.TargetCrashedScreen(onHide).show(dialog.element);dialog.show();function onHide()
{debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,hideBound);}}
WebInspector.TargetCrashedScreen.prototype={willHide:function()
{this._hideCallback.call(null);},__proto__:WebInspector.VBox.prototype}
WebInspector.BackendSettingsSync=function()
{this._autoAttachSetting=WebInspector.settings.moduleSetting("autoAttachToCreatedPages");this._autoAttachSetting.addChangeListener(this._update,this);this._disableJavascriptSetting=WebInspector.settings.moduleSetting("javaScriptDisabled");this._disableJavascriptSetting.addChangeListener(this._update,this);this._blockedEventsWarningSetting=WebInspector.settings.moduleSetting("blockedEventsWarningEnabled");this._blockedEventsWarningSetting.addChangeListener(this._update,this);WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);}
WebInspector.BackendSettingsSync.prototype={_updateTarget:function(target)
{var blockedEventsWarningThresholdSeconds=0.1;target.pageAgent().setBlockedEventsWarningThreshold(this._blockedEventsWarningSetting.get()?blockedEventsWarningThresholdSeconds:0);target.pageAgent().setAutoAttachToCreatedPages(this._autoAttachSetting.get());target.emulationAgent().setScriptExecutionDisabled(this._disableJavascriptSetting.get());},_update:function()
{WebInspector.targetManager.targets(WebInspector.Target.Type.Page).forEach(this._updateTarget,this);},targetAdded:function(target)
{this._updateTarget(target);target.renderingAgent().setShowViewportSizeOnResize(true);},targetRemoved:function(target)
{}}
WebInspector.ShowMetricsRulersSettingUI=function()
{}
WebInspector.ShowMetricsRulersSettingUI.prototype={settingElement:function()
{return WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show rulers"),WebInspector.moduleSetting("showMetricsRulers"));}}
new WebInspector.Main();;WebInspector.AdvancedApp=function()
{WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged,this._openToolboxWindow,this);};WebInspector.AdvancedApp.prototype={presentUI:function(document)
{var rootView=new WebInspector.RootView();this._rootSplitWidget=new WebInspector.SplitWidget(false,true,"InspectorView.splitViewState",555,300,true);this._rootSplitWidget.show(rootView.element);this._rootSplitWidget.setSidebarWidget(WebInspector.inspectorView);WebInspector.inspectorView.setOwnerSplit(this._rootSplitWidget);this._inspectedPagePlaceholder=new WebInspector.InspectedPagePlaceholder();this._inspectedPagePlaceholder.addEventListener(WebInspector.InspectedPagePlaceholder.Events.Update,this._onSetInspectedPageBounds.bind(this),this);this._deviceModeView=new WebInspector.DeviceModeWrapper(this._inspectedPagePlaceholder);WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged,this._onBeforeDockSideChange,this);WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged,this._onDockSideChange,this);WebInspector.dockController.addEventListener(WebInspector.DockController.Events.AfterDockSideChanged,this._onAfterDockSideChange,this);this._onDockSideChange();WebInspector.inspectorView.showInitialPanel();console.timeStamp("AdvancedApp.attachToBody");rootView.attachToDocument(document);this._inspectedPagePlaceholder.update();},_openToolboxWindow:function(event)
{if((event.data.to)!==WebInspector.DockController.State.Undocked)
return;if(this._toolboxWindow)
return;var url=window.location.href.replace("inspector.html","toolbox.html");this._toolboxWindow=window.open(url,undefined);},toolboxLoaded:function(toolboxDocument)
{WebInspector.initializeUIUtils(toolboxDocument,WebInspector.settings.createSetting("uiTheme","default"));WebInspector.installComponentRootStyles((toolboxDocument.body));WebInspector.ContextMenu.installHandler(toolboxDocument);WebInspector.Tooltip.installHandler(toolboxDocument);this._toolboxRootView=new WebInspector.RootView();this._toolboxRootView.attachToDocument(toolboxDocument);this._updateDeviceModeView();},_updateDeviceModeView:function()
{if(this._isDocked())
this._rootSplitWidget.setMainWidget(this._deviceModeView);else if(this._toolboxRootView)
this._deviceModeView.show(this._toolboxRootView.element);},_onBeforeDockSideChange:function(event)
{if((event.data.to)===WebInspector.DockController.State.Undocked&&this._toolboxRootView){this._rootSplitWidget.hideSidebar();this._inspectedPagePlaceholder.update();}
this._changingDockSide=true;},_onDockSideChange:function(event)
{this._updateDeviceModeView();var toDockSide=event?(event.data.to):WebInspector.dockController.dockSide();if(toDockSide===WebInspector.DockController.State.Undocked){this._updateForUndocked();}else if(this._toolboxRootView&&event&&(event.data.from)===WebInspector.DockController.State.Undocked){this._rootSplitWidget.hideSidebar();}else{this._updateForDocked(toDockSide);}},_onAfterDockSideChange:function(event)
{if(!this._changingDockSide)
return;if((event.data.from)===WebInspector.DockController.State.Undocked){this._updateForDocked((event.data.to));}
this._changingDockSide=false;this._inspectedPagePlaceholder.update();},_updateForDocked:function(dockSide)
{this._rootSplitWidget.setVertical(dockSide===WebInspector.DockController.State.DockedToRight);this._rootSplitWidget.setSecondIsSidebar(dockSide===WebInspector.DockController.State.DockedToRight||dockSide===WebInspector.DockController.State.DockedToBottom);this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(),true);this._rootSplitWidget.toggleResizer(WebInspector.inspectorView.topResizerElement(),dockSide===WebInspector.DockController.State.DockedToBottom);this._rootSplitWidget.showBoth();},_updateForUndocked:function()
{this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(),false);this._rootSplitWidget.toggleResizer(WebInspector.inspectorView.topResizerElement(),false);this._rootSplitWidget.hideMain();},_isDocked:function()
{return WebInspector.dockController.dockSide()!==WebInspector.DockController.State.Undocked;},_onSetInspectedPageBounds:function(event)
{if(this._changingDockSide)
return;var window=this._inspectedPagePlaceholder.element.window();if(!window.innerWidth||!window.innerHeight)
return;if(!this._inspectedPagePlaceholder.isShowing())
return;var bounds=(event.data);console.timeStamp("AdvancedApp.setInspectedPageBounds");InspectorFrontendHost.setInspectedPageBounds(bounds);}};WebInspector.AdvancedApp._appInstance;WebInspector.AdvancedApp._instance=function()
{if(!WebInspector.AdvancedApp._appInstance)
WebInspector.AdvancedApp._appInstance=new WebInspector.AdvancedApp();return WebInspector.AdvancedApp._appInstance;};WebInspector.AdvancedAppProvider=function()
{};WebInspector.AdvancedAppProvider.prototype={createApp:function()
{return WebInspector.AdvancedApp._instance();}};;WebInspector.EmulatedDevice=function()
{this.title="";this.type=WebInspector.EmulatedDevice.Type.Unknown;this.vertical={width:0,height:0,outlineInsets:null,outlineImage:null};this.horizontal={width:0,height:0,outlineInsets:null,outlineImage:null};this.deviceScaleFactor=1;this.capabilities=[WebInspector.EmulatedDevice.Capability.Touch,WebInspector.EmulatedDevice.Capability.Mobile];this.userAgent="";this.modes=[];this._show=WebInspector.EmulatedDevice._Show.Default;this._showByDefault=true;this._extension=null;}
WebInspector.EmulatedDevice.Mode;WebInspector.EmulatedDevice.Orientation;WebInspector.EmulatedDevice.Horizontal="horizontal";WebInspector.EmulatedDevice.Vertical="vertical";WebInspector.EmulatedDevice.Type={Phone:"phone",Tablet:"tablet",Notebook:"notebook",Desktop:"desktop",Unknown:"unknown"}
WebInspector.EmulatedDevice.Capability={Touch:"touch",Mobile:"mobile"}
WebInspector.EmulatedDevice._Show={Always:"Always",Default:"Default",Never:"Never"}
WebInspector.EmulatedDevice.fromJSONV1=function(json)
{try{function parseValue(object,key,type,defaultValue)
{if(typeof object!=="object"||object===null||!object.hasOwnProperty(key)){if(typeof defaultValue!=="undefined")
return defaultValue;throw new Error("Emulated device is missing required property '"+key+"'");}
var value=object[key];if(typeof value!==type||value===null)
throw new Error("Emulated device property '"+key+"' has wrong type '"+typeof value+"'");return value;}
function parseIntValue(object,key)
{var value=(parseValue(object,key,"number"));if(value!==Math.abs(value))
throw new Error("Emulated device value '"+key+"' must be integer");return value;}
function parseInsets(json)
{return new Insets(parseIntValue(json,"left"),parseIntValue(json,"top"),parseIntValue(json,"right"),parseIntValue(json,"bottom"));}
function parseOrientation(json)
{var result={};result.width=parseIntValue(json,"width");if(result.width<0||result.width>WebInspector.DeviceModeModel.MaxDeviceSize||result.width<WebInspector.DeviceModeModel.MinDeviceSize)
throw new Error("Emulated device has wrong width: "+result.width);result.height=parseIntValue(json,"height");if(result.height<0||result.height>WebInspector.DeviceModeModel.MaxDeviceSize||result.height<WebInspector.DeviceModeModel.MinDeviceSize)
throw new Error("Emulated device has wrong height: "+result.height);var outlineInsets=parseValue(json["outline"],"insets","object",null);if(outlineInsets){result.outlineInsets=parseInsets(outlineInsets);if(result.outlineInsets.left<0||result.outlineInsets.top<0)
throw new Error("Emulated device has wrong outline insets");result.outlineImage=(parseValue(json["outline"],"image","string"));}
return(result);}
var result=new WebInspector.EmulatedDevice();result.title=(parseValue(json,"title","string"));result.type=(parseValue(json,"type","string"));result.userAgent=(parseValue(json,"user-agent","string"));var capabilities=parseValue(json,"capabilities","object",[]);if(!Array.isArray(capabilities))
throw new Error("Emulated device capabilities must be an array");result.capabilities=[];for(var i=0;i<capabilities.length;++i){if(typeof capabilities[i]!=="string")
throw new Error("Emulated device capability must be a string");result.capabilities.push(capabilities[i]);}
result.deviceScaleFactor=(parseValue(json["screen"],"device-pixel-ratio","number"));if(result.deviceScaleFactor<0||result.deviceScaleFactor>100)
throw new Error("Emulated device has wrong deviceScaleFactor: "+result.deviceScaleFactor);result.vertical=parseOrientation(parseValue(json["screen"],"vertical","object"));result.horizontal=parseOrientation(parseValue(json["screen"],"horizontal","object"));var modes=parseValue(json,"modes","object",[]);if(!Array.isArray(modes))
throw new Error("Emulated device modes must be an array");result.modes=[];for(var i=0;i<modes.length;++i){var mode={};mode.title=(parseValue(modes[i],"title","string"));mode.orientation=(parseValue(modes[i],"orientation","string"));if(mode.orientation!==WebInspector.EmulatedDevice.Vertical&&mode.orientation!==WebInspector.EmulatedDevice.Horizontal)
throw new Error("Emulated device mode has wrong orientation '"+mode.orientation+"'");var orientation=result.orientationByName(mode.orientation);mode.insets=parseInsets(parseValue(modes[i],"insets","object"));if(mode.insets.top<0||mode.insets.left<0||mode.insets.right<0||mode.insets.bottom<0||mode.insets.top+mode.insets.bottom>orientation.height||mode.insets.left+mode.insets.right>orientation.width){throw new Error("Emulated device mode '"+mode.title+"'has wrong mode insets");}
mode.image=(parseValue(modes[i],"image","string",null));result.modes.push(mode);}
result._showByDefault=(parseValue(json,"show-by-default","boolean",undefined));result._show=(parseValue(json,"show","string",WebInspector.EmulatedDevice._Show.Default));return result;}catch(e){return null;}}
WebInspector.EmulatedDevice.deviceComparator=function(device1,device2)
{var order1=(device1._extension&&device1._extension.descriptor()["order"])||-1;var order2=(device2._extension&&device2._extension.descriptor()["order"])||-1;if(order1>order2)
return 1;if(order2>order1)
return-1;return device1.title<device2.title?-1:(device1.title>device2.title?1:0);}
WebInspector.EmulatedDevice.prototype={extension:function()
{return this._extension;},setExtension:function(extension)
{this._extension=extension;},modesForOrientation:function(orientation)
{var result=[];for(var index=0;index<this.modes.length;index++){if(this.modes[index].orientation===orientation)
result.push(this.modes[index]);}
return result;},_toJSON:function()
{var json={};json["title"]=this.title;json["type"]=this.type;json["user-agent"]=this.userAgent;json["capabilities"]=this.capabilities;json["screen"]={};json["screen"]["device-pixel-ratio"]=this.deviceScaleFactor;json["screen"]["vertical"]=this._orientationToJSON(this.vertical);json["screen"]["horizontal"]=this._orientationToJSON(this.horizontal);json["modes"]=[];for(var i=0;i<this.modes.length;++i){var mode={};mode["title"]=this.modes[i].title;mode["orientation"]=this.modes[i].orientation;mode["insets"]={};mode["insets"]["left"]=this.modes[i].insets.left;mode["insets"]["top"]=this.modes[i].insets.top;mode["insets"]["right"]=this.modes[i].insets.right;mode["insets"]["bottom"]=this.modes[i].insets.bottom;if(this.modes[i].image)
mode["image"]=this.modes[i].image;json["modes"].push(mode);}
json["show-by-default"]=this._showByDefault;json["show"]=this._show;return json;},_orientationToJSON:function(orientation)
{var json={};json["width"]=orientation.width;json["height"]=orientation.height;if(orientation.outlineInsets){json["outline"]={};json["outline"]["insets"]={};json["outline"]["insets"]["left"]=orientation.outlineInsets.left;json["outline"]["insets"]["top"]=orientation.outlineInsets.top;json["outline"]["insets"]["right"]=orientation.outlineInsets.right;json["outline"]["insets"]["bottom"]=orientation.outlineInsets.bottom;json["outline"]["image"]=orientation.outlineImage;}
return json;},modeImage:function(mode)
{if(!mode.image)
return"";if(!this._extension)
return mode.image;return this._extension.module().substituteURL(mode.image);},outlineImage:function(mode)
{var orientation=this.orientationByName(mode.orientation);if(!orientation.outlineImage)
return"";if(!this._extension)
return orientation.outlineImage;return this._extension.module().substituteURL(orientation.outlineImage);},orientationByName:function(name)
{return name===WebInspector.EmulatedDevice.Vertical?this.vertical:this.horizontal;},show:function()
{if(this._show===WebInspector.EmulatedDevice._Show.Default)
return this._showByDefault;return this._show===WebInspector.EmulatedDevice._Show.Always;},setShow:function(show)
{this._show=show?WebInspector.EmulatedDevice._Show.Always:WebInspector.EmulatedDevice._Show.Never;},copyShowFrom:function(other)
{this._show=other._show;},touch:function()
{return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Touch)!==-1;},mobile:function()
{return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Mobile)!==-1;}}
WebInspector.EmulatedDevicesList=function()
{WebInspector.Object.call(this);this._standardSetting=WebInspector.settings.createSetting("standardEmulatedDeviceList",[]);this._standard=[];this._listFromJSONV1(this._standardSetting.get(),this._standard);this._updateStandardDevices();this._customSetting=WebInspector.settings.createSetting("customEmulatedDeviceList",[]);this._custom=[];if(!this._listFromJSONV1(this._customSetting.get(),this._custom))
this.saveCustomDevices();}
WebInspector.EmulatedDevicesList.Events={CustomDevicesUpdated:"CustomDevicesUpdated",StandardDevicesUpdated:"StandardDevicesUpdated"}
WebInspector.EmulatedDevicesList.prototype={_updateStandardDevices:function()
{var devices=[];var extensions=self.runtime.extensions("emulated-device");for(var i=0;i<extensions.length;++i){var device=WebInspector.EmulatedDevice.fromJSONV1(extensions[i].descriptor()["device"]);device.setExtension(extensions[i]);devices.push(device);}
this._copyShowValues(this._standard,devices);this._standard=devices;this.saveStandardDevices();},_listFromJSONV1:function(jsonArray,result)
{if(!Array.isArray(jsonArray))
return false;var success=true;for(var i=0;i<jsonArray.length;++i){var device=WebInspector.EmulatedDevice.fromJSONV1(jsonArray[i]);if(device){result.push(device);if(!device.modes.length){device.modes.push({title:"",orientation:WebInspector.EmulatedDevice.Horizontal,insets:new Insets(0,0,0,0),image:null});device.modes.push({title:"",orientation:WebInspector.EmulatedDevice.Vertical,insets:new Insets(0,0,0,0),image:null});}}else{success=false;}}
return success;},standard:function()
{return this._standard;},custom:function()
{return this._custom;},revealCustomSetting:function()
{WebInspector.Revealer.reveal(this._customSetting);},addCustomDevice:function(device)
{this._custom.push(device);this.saveCustomDevices();},removeCustomDevice:function(device)
{this._custom.remove(device);this.saveCustomDevices();},saveCustomDevices:function()
{var json=this._custom.map(function(device){return device._toJSON();});this._customSetting.set(json);this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated);},saveStandardDevices:function()
{var json=this._standard.map(function(device){return device._toJSON();});this._standardSetting.set(json);this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated);},_copyShowValues:function(from,to)
{var deviceById=new Map();for(var i=0;i<from.length;++i)
deviceById.set(from[i].title,from[i]);for(var i=0;i<to.length;++i){var title=to[i].title;if(deviceById.has(title))
to[i].copyShowFrom((deviceById.get(title)));}},__proto__:WebInspector.Object.prototype}
WebInspector.EmulatedDevicesList._instance;WebInspector.EmulatedDevicesList.instance=function()
{if(!WebInspector.EmulatedDevicesList._instance)
WebInspector.EmulatedDevicesList._instance=new WebInspector.EmulatedDevicesList();return(WebInspector.EmulatedDevicesList._instance);};WebInspector.DevicesSettingsTab=function()
{WebInspector.VBox.call(this);this.element.classList.add("settings-tab-container");this.element.classList.add("devices-settings-tab");this.registerRequiredCSS("emulation/devicesSettingsTab.css");var header=this.element.createChild("header");header.createChild("h3").createTextChild(WebInspector.UIString("Emulated Devices"));this.containerElement=this.element.createChild("div","help-container-wrapper").createChild("div","settings-tab help-content help-container");var buttonsRow=this.containerElement.createChild("div","devices-button-row");this._addCustomButton=createTextButton(WebInspector.UIString("Add custom device..."),this._addCustomDevice.bind(this));buttonsRow.appendChild(this._addCustomButton);this._list=new WebInspector.ListWidget(this);this._list.registerRequiredCSS("emulation/devicesSettingsTab.css");this._list.element.classList.add("devices-list");this._list.show(this.containerElement);this._muteUpdate=false;this._emulatedDevicesList=WebInspector.EmulatedDevicesList.instance();this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated,this._devicesUpdated,this);this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated,this._devicesUpdated,this);this.setDefaultFocusedElement(this._addCustomButton);}
WebInspector.DevicesSettingsTab.prototype={wasShown:function()
{WebInspector.VBox.prototype.wasShown.call(this);this._devicesUpdated();},_devicesUpdated:function()
{if(this._muteUpdate)
return;this._list.clear();var devices=this._emulatedDevicesList.custom().slice();for(var i=0;i<devices.length;++i)
this._list.appendItem(devices[i],true);this._list.appendSeparator();devices=this._emulatedDevicesList.standard().slice();devices.sort(WebInspector.EmulatedDevice.deviceComparator);for(var i=0;i<devices.length;++i)
this._list.appendItem(devices[i],false);},_muteAndSaveDeviceList:function(custom)
{this._muteUpdate=true;if(custom)
this._emulatedDevicesList.saveCustomDevices();else
this._emulatedDevicesList.saveStandardDevices();this._muteUpdate=false;},_addCustomDevice:function()
{var device=new WebInspector.EmulatedDevice();device.deviceScaleFactor=0;device.horizontal.width=700;device.horizontal.height=400;device.vertical.width=400;device.vertical.height=700;this._list.addNewItem(this._emulatedDevicesList.custom().length,device);},_toNumericInputValue:function(value)
{return value?String(value):"";},renderItem:function(item,editable)
{var device=(item);var element=createElementWithClass("div","devices-list-item");var checkbox=element.createChild("input","devices-list-checkbox");checkbox.type="checkbox";checkbox.checked=device.show();element.createChild("div","devices-list-title").textContent=device.title;element.addEventListener("click",onItemClicked.bind(this),false);return element;function onItemClicked(event)
{var show=!checkbox.checked;device.setShow(show);this._muteAndSaveDeviceList(editable);checkbox.checked=show;event.consume();}},removeItemRequested:function(item,index)
{this._emulatedDevicesList.removeCustomDevice((item));},commitEdit:function(item,editor,isNew)
{var device=(item);device.title=editor.control("title").value.trim();device.vertical.width=editor.control("width").value?parseInt(editor.control("width").value,10):0;device.vertical.height=editor.control("height").value?parseInt(editor.control("height").value,10):0;device.horizontal.width=device.vertical.height;device.horizontal.height=device.vertical.width;device.deviceScaleFactor=editor.control("scale").value?parseFloat(editor.control("scale").value):0;device.userAgent=editor.control("user-agent").value;device.modes=[];device.modes.push({title:"",orientation:WebInspector.EmulatedDevice.Vertical,insets:new Insets(0,0,0,0),image:null});device.modes.push({title:"",orientation:WebInspector.EmulatedDevice.Horizontal,insets:new Insets(0,0,0,0),image:null});device.capabilities=[];var uaType=editor.control("ua-type").value;if(uaType===WebInspector.DeviceModeModel.UA.Mobile||uaType===WebInspector.DeviceModeModel.UA.MobileNoTouch)
device.capabilities.push(WebInspector.EmulatedDevice.Capability.Mobile);if(uaType===WebInspector.DeviceModeModel.UA.Mobile||uaType===WebInspector.DeviceModeModel.UA.DesktopTouch)
device.capabilities.push(WebInspector.EmulatedDevice.Capability.Touch);if(isNew)
this._emulatedDevicesList.addCustomDevice(device);else
this._emulatedDevicesList.saveCustomDevices();this._addCustomButton.scrollIntoViewIfNeeded();this._addCustomButton.focus();},beginEdit:function(item)
{var device=(item);var editor=this._createEditor();editor.control("title").value=device.title;editor.control("width").value=this._toNumericInputValue(device.vertical.width);editor.control("height").value=this._toNumericInputValue(device.vertical.height);editor.control("scale").value=this._toNumericInputValue(device.deviceScaleFactor);editor.control("user-agent").value=device.userAgent;var uaType;if(device.mobile())
uaType=device.touch()?WebInspector.DeviceModeModel.UA.Mobile:WebInspector.DeviceModeModel.UA.MobileNoTouch;else
uaType=device.touch()?WebInspector.DeviceModeModel.UA.DesktopTouch:WebInspector.DeviceModeModel.UA.Desktop;editor.control("ua-type").value=uaType;return editor;},_createEditor:function()
{if(this._editor)
return this._editor;var editor=new WebInspector.ListWidget.Editor();this._editor=editor;var content=editor.contentElement();var fields=content.createChild("div","devices-edit-fields");fields.createChild("div","hbox").appendChild(editor.createInput("title","text",WebInspector.UIString("Device name"),titleValidator));var screen=fields.createChild("div","hbox");screen.appendChild(editor.createInput("width","text",WebInspector.UIString("Width"),sizeValidator));screen.appendChild(editor.createInput("height","text",WebInspector.UIString("height"),sizeValidator));var dpr=editor.createInput("scale","text",WebInspector.UIString("Device pixel ratio"),scaleValidator);dpr.classList.add("device-edit-fixed");screen.appendChild(dpr);var ua=fields.createChild("div","hbox");ua.appendChild(editor.createInput("user-agent","text",WebInspector.UIString("User agent string"),()=>true));var uaType=editor.createSelect("ua-type",[WebInspector.DeviceModeModel.UA.Mobile,WebInspector.DeviceModeModel.UA.MobileNoTouch,WebInspector.DeviceModeModel.UA.Desktop,WebInspector.DeviceModeModel.UA.DesktopTouch],()=>true);uaType.classList.add("device-edit-fixed");ua.appendChild(uaType);return editor;function titleValidator(item,index,input)
{var value=input.value.trim();return value.length>0&&value.length<50;}
function sizeValidator(item,index,input)
{return WebInspector.DeviceModeModel.deviceSizeValidator(input.value);}
function scaleValidator(item,index,input)
{return WebInspector.DeviceModeModel.deviceScaleFactorValidator(input.value);}},__proto__:WebInspector.VBox.prototype};WebInspector.DeviceOrientation=function(alpha,beta,gamma)
{this.alpha=alpha;this.beta=beta;this.gamma=gamma;}
WebInspector.DeviceOrientation.prototype={toSetting:function()
{return JSON.stringify(this);},apply:function()
{for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.deviceOrientationAgent().setDeviceOrientationOverride(this.alpha,this.beta,this.gamma);},clear:function()
{for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.deviceOrientationAgent().clearDeviceOrientationOverride();}}
WebInspector.DeviceOrientation.parseSetting=function(value)
{if(value){var jsonObject=JSON.parse(value);return new WebInspector.DeviceOrientation(jsonObject.alpha,jsonObject.beta,jsonObject.gamma);}
return new WebInspector.DeviceOrientation(0,0,0);}
WebInspector.DeviceOrientation.parseUserInput=function(alphaString,betaString,gammaString)
{if(!alphaString&&!betaString&&!gammaString)
return null;var isAlphaValid=WebInspector.DeviceOrientation.validator(alphaString);var isBetaValid=WebInspector.DeviceOrientation.validator(betaString);var isGammaValid=WebInspector.DeviceOrientation.validator(gammaString);if(!isAlphaValid&&!isBetaValid&&!isGammaValid)
return null;var alpha=isAlphaValid?parseFloat(alphaString):-1;var beta=isBetaValid?parseFloat(betaString):-1;var gamma=isGammaValid?parseFloat(gammaString):-1;return new WebInspector.DeviceOrientation(alpha,beta,gamma);}
WebInspector.DeviceOrientation.validator=function(value)
{return/^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value);};WebInspector.Geolocation=function(latitude,longitude,error)
{this.latitude=latitude;this.longitude=longitude;this.error=error;}
WebInspector.Geolocation.prototype={toSetting:function()
{return(typeof this.latitude==="number"&&typeof this.longitude==="number"&&typeof this.error==="string")?this.latitude+"@"+this.longitude+":"+this.error:"";},apply:function()
{for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page)){if(this.error)
target.emulationAgent().setGeolocationOverride();else
target.emulationAgent().setGeolocationOverride(this.latitude,this.longitude,WebInspector.Geolocation.DefaultMockAccuracy);}},clear:function()
{for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
target.emulationAgent().clearGeolocationOverride();}}
WebInspector.Geolocation.parseSetting=function(value)
{if(value){var splitError=value.split(":");if(splitError.length===2){var splitPosition=splitError[0].split("@");if(splitPosition.length===2)
return new WebInspector.Geolocation(parseFloat(splitPosition[0]),parseFloat(splitPosition[1]),splitError[1]);}}
return new WebInspector.Geolocation(0,0,false);}
WebInspector.Geolocation.parseUserInput=function(latitudeString,longitudeString,errorStatus)
{if(!latitudeString&&!longitudeString)
return null;var isLatitudeValid=WebInspector.Geolocation.latitudeValidator(latitudeString);var isLongitudeValid=WebInspector.Geolocation.longitudeValidator(longitudeString);if(!isLatitudeValid&&!isLongitudeValid)
return null;var latitude=isLatitudeValid?parseFloat(latitudeString):-1;var longitude=isLongitudeValid?parseFloat(longitudeString):-1;return new WebInspector.Geolocation(latitude,longitude,!!errorStatus);}
WebInspector.Geolocation.latitudeValidator=function(value)
{var numValue=parseFloat(value);return/^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value)&&numValue>=-90&&numValue<=90;}
WebInspector.Geolocation.longitudeValidator=function(value)
{var numValue=parseFloat(value);return/^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value)&&numValue>=-180&&numValue<=180;}
WebInspector.Geolocation.DefaultMockAccuracy=150;;WebInspector.InspectedPagePlaceholder=function()
{WebInspector.Widget.call(this);this.element.classList.add("inspected-page-placeholder");WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._scheduleUpdate,this);this._margins={top:0,right:0,bottom:0,left:0};this.restoreMinimumSizeAndMargins();};WebInspector.InspectedPagePlaceholder.Events={Update:"Update"};WebInspector.InspectedPagePlaceholder.MarginValue=3;WebInspector.InspectedPagePlaceholder.prototype={_findMargins:function()
{var margins={top:0,right:0,bottom:0,left:0};if(this._useMargins){var adjacent={top:true,right:true,bottom:true,left:true};var widget=this;while(widget.parentWidget()){var parent=widget.parentWidget();if(parent instanceof WebInspector.SplitWidget){var side=parent.sidebarSide();if(adjacent[side]&&!parent.hasCustomResizer()&&parent.isResizable())
margins[side]=WebInspector.InspectedPagePlaceholder.MarginValue;adjacent[side]=false;}
widget=parent;}}
if(this._margins.top!==margins.top||this._margins.left!==margins.left||this._margins.right!==margins.right||this._margins.bottom!==margins.bottom){this._margins=margins;this._scheduleUpdate();}},onResize:function()
{this._findMargins();this._scheduleUpdate();},_scheduleUpdate:function()
{if(this._updateId)
this.element.window().cancelAnimationFrame(this._updateId);this._updateId=this.element.window().requestAnimationFrame(this.update.bind(this));},restoreMinimumSizeAndMargins:function()
{this._useMargins=true;this.setMinimumSize(150,150);this._findMargins();},clearMinimumSizeAndMargins:function()
{this._useMargins=false;this.setMinimumSize(1,1);this._findMargins();},_dipPageRect:function()
{var zoomFactor=WebInspector.zoomManager.zoomFactor();var rect=this.element.getBoundingClientRect();var bodyRect=this.element.ownerDocument.body.getBoundingClientRect();var left=Math.max(rect.left*zoomFactor+this._margins.left,bodyRect.left*zoomFactor);var top=Math.max(rect.top*zoomFactor+this._margins.top,bodyRect.top*zoomFactor);var bottom=Math.min(rect.bottom*zoomFactor-this._margins.bottom,bodyRect.bottom*zoomFactor);var right=Math.min(rect.right*zoomFactor-this._margins.right,bodyRect.right*zoomFactor);return{x:left,y:top,width:right-left,height:bottom-top};},update:function()
{delete this._updateId;var rect=this._dipPageRect();var bounds={x:Math.round(rect.x),y:Math.round(rect.y),height:Math.max(1,Math.round(rect.height)),width:Math.max(1,Math.round(rect.width))};this.dispatchEventToListeners(WebInspector.InspectedPagePlaceholder.Events.Update,bounds);},__proto__:WebInspector.Widget.prototype};;WebInspector.MediaQueryInspector=function(getWidthCallback,setWidthCallback)
{WebInspector.Widget.call(this,true);this.registerRequiredCSS("emulation/mediaQueryInspector.css");this.contentElement.classList.add("media-inspector-view");this.contentElement.addEventListener("click",this._onMediaQueryClicked.bind(this),false);this.contentElement.addEventListener("contextmenu",this._onContextMenu.bind(this),false);this._mediaThrottler=new WebInspector.Throttler(0);this._getWidthCallback=getWidthCallback;this._setWidthCallback=setWidthCallback;this._scale=1;WebInspector.targetManager.observeTargets(this);WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._renderMediaQueries.bind(this),this);}
WebInspector.MediaQueryInspector.Section={Max:0,MinMax:1,Min:2}
WebInspector.MediaQueryInspector.prototype={targetAdded:function(target)
{if(this._cssModel)
return;this._cssModel=WebInspector.CSSModel.fromTarget(target);if(!this._cssModel)
return;this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.StyleSheetChanged,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged,this._scheduleMediaQueriesUpdate,this);},targetRemoved:function(target)
{if(WebInspector.CSSModel.fromTarget(target)!==this._cssModel)
return;this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetRemoved,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetChanged,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(WebInspector.CSSModel.Events.MediaQueryResultChanged,this._scheduleMediaQueriesUpdate,this);delete this._cssModel;},setAxisTransform:function(scale)
{if(Math.abs(this._scale-scale)<1e-8)
return;this._scale=scale;this._renderMediaQueries();},_onMediaQueryClicked:function(event)
{var mediaQueryMarker=event.target.enclosingNodeOrSelfWithClass("media-inspector-bar");if(!mediaQueryMarker)
return;var model=mediaQueryMarker._model;if(model.section()===WebInspector.MediaQueryInspector.Section.Max){this._setWidthCallback(model.maxWidthExpression().computedLength());return;}
if(model.section()===WebInspector.MediaQueryInspector.Section.Min){this._setWidthCallback(model.minWidthExpression().computedLength());return;}
var currentWidth=this._getWidthCallback();if(currentWidth!==model.minWidthExpression().computedLength())
this._setWidthCallback(model.minWidthExpression().computedLength());else
this._setWidthCallback(model.maxWidthExpression().computedLength());},_onContextMenu:function(event)
{if(!this._cssModel||!this._cssModel.isEnabled())
return;var mediaQueryMarker=event.target.enclosingNodeOrSelfWithClass("media-inspector-bar");if(!mediaQueryMarker)
return;var locations=mediaQueryMarker._locations;var uiLocations=new Map();for(var i=0;i<locations.length;++i){var uiLocation=WebInspector.cssWorkspaceBinding.rawLocationToUILocation(locations[i]);if(!uiLocation)
continue;var descriptor=String.sprintf("%s:%d:%d",uiLocation.uiSourceCode.url(),uiLocation.lineNumber+1,uiLocation.columnNumber+1);uiLocations.set(descriptor,uiLocation);}
var contextMenuItems=uiLocations.keysArray().sort();var contextMenu=new WebInspector.ContextMenu(event);var subMenuItem=contextMenu.appendSubMenuItem(WebInspector.UIString.capitalize("Reveal in ^source ^code"));for(var i=0;i<contextMenuItems.length;++i){var title=contextMenuItems[i];subMenuItem.appendItem(title,this._revealSourceLocation.bind(this,(uiLocations.get(title))));}
contextMenu.show();},_revealSourceLocation:function(location)
{WebInspector.Revealer.reveal(location);},_scheduleMediaQueriesUpdate:function()
{if(!this.isShowing())
return;this._mediaThrottler.schedule(this._refetchMediaQueries.bind(this));},_refetchMediaQueries:function()
{if(!this.isShowing()||!this._cssModel)
return Promise.resolve();return this._cssModel.mediaQueriesPromise().then(this._rebuildMediaQueries.bind(this))},_squashAdjacentEqual:function(models)
{var filtered=[];for(var i=0;i<models.length;++i){var last=filtered.peekLast();if(!last||!last.equals(models[i]))
filtered.push(models[i]);}
return filtered;},_rebuildMediaQueries:function(cssMedias)
{var queryModels=[];for(var i=0;i<cssMedias.length;++i){var cssMedia=cssMedias[i];if(!cssMedia.mediaList)
continue;for(var j=0;j<cssMedia.mediaList.length;++j){var mediaQuery=cssMedia.mediaList[j];var queryModel=WebInspector.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery(cssMedia,mediaQuery);if(queryModel&&queryModel.rawLocation())
queryModels.push(queryModel);}}
queryModels.sort(compareModels);queryModels=this._squashAdjacentEqual(queryModels);var allEqual=this._cachedQueryModels&&this._cachedQueryModels.length==queryModels.length;for(var i=0;allEqual&&i<queryModels.length;++i)
allEqual=allEqual&&this._cachedQueryModels[i].equals(queryModels[i]);if(allEqual)
return;this._cachedQueryModels=queryModels;this._renderMediaQueries();function compareModels(model1,model2)
{return model1.compareTo(model2);}},_renderMediaQueries:function()
{if(!this._cachedQueryModels||!this.isShowing())
return;var markers=[];var lastMarker=null;for(var i=0;i<this._cachedQueryModels.length;++i){var model=this._cachedQueryModels[i];if(lastMarker&&lastMarker.model.dimensionsEqual(model)){lastMarker.locations.push(model.rawLocation());lastMarker.active=lastMarker.active||model.active();}else{lastMarker={active:model.active(),model:model,locations:[model.rawLocation()]};markers.push(lastMarker);}}
this.contentElement.removeChildren();var container=null;for(var i=0;i<markers.length;++i){if(!i||markers[i].model.section()!==markers[i-1].model.section())
container=this.contentElement.createChild("div","media-inspector-marker-container");var marker=markers[i];var bar=this._createElementFromMediaQueryModel(marker.model);bar._model=marker.model;bar._locations=marker.locations;bar.classList.toggle("media-inspector-marker-inactive",!marker.active);container.appendChild(bar);}},_zoomFactor:function()
{return WebInspector.zoomManager.zoomFactor()/this._scale;},wasShown:function()
{this._scheduleMediaQueriesUpdate();},_createElementFromMediaQueryModel:function(model)
{var zoomFactor=this._zoomFactor();var minWidthValue=model.minWidthExpression()?model.minWidthExpression().computedLength()/zoomFactor:0;var maxWidthValue=model.maxWidthExpression()?model.maxWidthExpression().computedLength()/zoomFactor:0;var result=createElementWithClass("div","media-inspector-bar");if(model.section()===WebInspector.MediaQueryInspector.Section.Max){result.createChild("div","media-inspector-marker-spacer");var markerElement=result.createChild("div","media-inspector-marker media-inspector-marker-max-width");markerElement.style.width=maxWidthValue+"px";markerElement.title=model.mediaText();appendLabel(markerElement,model.maxWidthExpression(),false,false);appendLabel(markerElement,model.maxWidthExpression(),true,true);result.createChild("div","media-inspector-marker-spacer");}
if(model.section()===WebInspector.MediaQueryInspector.Section.MinMax){result.createChild("div","media-inspector-marker-spacer");var leftElement=result.createChild("div","media-inspector-marker media-inspector-marker-min-max-width");leftElement.style.width=(maxWidthValue-minWidthValue)*0.5+"px";leftElement.title=model.mediaText();appendLabel(leftElement,model.minWidthExpression(),true,false);appendLabel(leftElement,model.maxWidthExpression(),false,true);result.createChild("div","media-inspector-marker-spacer").style.flex="0 0 "+minWidthValue+"px";var rightElement=result.createChild("div","media-inspector-marker media-inspector-marker-min-max-width");rightElement.style.width=(maxWidthValue-minWidthValue)*0.5+"px";rightElement.title=model.mediaText();appendLabel(rightElement,model.minWidthExpression(),true,false);appendLabel(rightElement,model.maxWidthExpression(),false,true);result.createChild("div","media-inspector-marker-spacer");}
if(model.section()===WebInspector.MediaQueryInspector.Section.Min){var leftElement=result.createChild("div","media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-left");leftElement.title=model.mediaText();appendLabel(leftElement,model.minWidthExpression(),false,false);result.createChild("div","media-inspector-marker-spacer").style.flex="0 0 "+minWidthValue+"px";var rightElement=result.createChild("div","media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-right");rightElement.title=model.mediaText();appendLabel(rightElement,model.minWidthExpression(),true,true);}
function appendLabel(marker,expression,atLeft,leftAlign)
{marker.createChild("div","media-inspector-marker-label-container "+(atLeft?"media-inspector-marker-label-container-left":"media-inspector-marker-label-container-right")).createChild("span","media-inspector-marker-label "+(leftAlign?"media-inspector-label-left":"media-inspector-label-right")).textContent=expression.value()+expression.unit();}
return result;},__proto__:WebInspector.Widget.prototype};WebInspector.MediaQueryInspector.MediaQueryUIModel=function(cssMedia,minWidthExpression,maxWidthExpression,active)
{this._cssMedia=cssMedia;this._minWidthExpression=minWidthExpression;this._maxWidthExpression=maxWidthExpression;this._active=active;if(maxWidthExpression&&!minWidthExpression)
this._section=WebInspector.MediaQueryInspector.Section.Max;else if(minWidthExpression&&maxWidthExpression)
this._section=WebInspector.MediaQueryInspector.Section.MinMax;else
this._section=WebInspector.MediaQueryInspector.Section.Min;}
WebInspector.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery=function(cssMedia,mediaQuery)
{var maxWidthExpression=null;var maxWidthPixels=Number.MAX_VALUE;var minWidthExpression=null;var minWidthPixels=Number.MIN_VALUE;var expressions=mediaQuery.expressions();for(var i=0;i<expressions.length;++i){var expression=expressions[i];var feature=expression.feature();if(feature.indexOf("width")===-1)
continue;var pixels=expression.computedLength();if(feature.startsWith("max-")&&pixels<maxWidthPixels){maxWidthExpression=expression;maxWidthPixels=pixels;}else if(feature.startsWith("min-")&&pixels>minWidthPixels){minWidthExpression=expression;minWidthPixels=pixels;}}
if(minWidthPixels>maxWidthPixels||(!maxWidthExpression&&!minWidthExpression))
return null;return new WebInspector.MediaQueryInspector.MediaQueryUIModel(cssMedia,minWidthExpression,maxWidthExpression,mediaQuery.active());}
WebInspector.MediaQueryInspector.MediaQueryUIModel.prototype={equals:function(other)
{return this.compareTo(other)===0;},dimensionsEqual:function(other)
{return this.section()===other.section()&&(!this.minWidthExpression()||(this.minWidthExpression().computedLength()===other.minWidthExpression().computedLength()))&&(!this.maxWidthExpression()||(this.maxWidthExpression().computedLength()===other.maxWidthExpression().computedLength()));},compareTo:function(other)
{if(this.section()!==other.section())
return this.section()-other.section();if(this.dimensionsEqual(other)){var myLocation=this.rawLocation();var otherLocation=other.rawLocation();if(!myLocation&&!otherLocation)
return this.mediaText().compareTo(other.mediaText());if(myLocation&&!otherLocation)
return 1;if(!myLocation&&otherLocation)
return-1;if(this.active()!==other.active())
return this.active()?-1:1;return myLocation.url.compareTo(otherLocation.url)||myLocation.lineNumber-otherLocation.lineNumber||myLocation.columnNumber-otherLocation.columnNumber;}
if(this.section()===WebInspector.MediaQueryInspector.Section.Max)
return other.maxWidthExpression().computedLength()-this.maxWidthExpression().computedLength();if(this.section()===WebInspector.MediaQueryInspector.Section.Min)
return this.minWidthExpression().computedLength()-other.minWidthExpression().computedLength();return this.minWidthExpression().computedLength()-other.minWidthExpression().computedLength()||other.maxWidthExpression().computedLength()-this.maxWidthExpression().computedLength();},section:function()
{return this._section;},mediaText:function()
{return this._cssMedia.text;},rawLocation:function()
{if(!this._rawLocation)
this._rawLocation=this._cssMedia.rawLocation();return this._rawLocation;},minWidthExpression:function()
{return this._minWidthExpression;},maxWidthExpression:function()
{return this._maxWidthExpression;},active:function()
{return this._active;}};WebInspector.SensorsView=function()
{WebInspector.VBox.call(this,true);this.registerRequiredCSS("emulation/sensors.css");this.contentElement.classList.add("sensors-view");this._geolocationSetting=WebInspector.settings.createSetting("emulation.geolocationOverride","");this._geolocation=WebInspector.Geolocation.parseSetting(this._geolocationSetting.get());this._geolocationOverrideEnabled=false;this._createGeolocationSection(this._geolocation);this.contentElement.createChild("div").classList.add("panel-section-separator");this._deviceOrientationSetting=WebInspector.settings.createSetting("emulation.deviceOrientationOverride","");this._deviceOrientation=WebInspector.DeviceOrientation.parseSetting(this._deviceOrientationSetting.get());this._deviceOrientationOverrideEnabled=false;this._createDeviceOrientationSection();this.contentElement.createChild("div").classList.add("panel-section-separator");this._appendTouchControl();}
WebInspector.SensorsView.prototype={_createGeolocationSection:function(geolocation)
{var geogroup=this.contentElement.createChild("section","sensors-group");geogroup.createChild("div","sensors-group-title").textContent=WebInspector.UIString("Geolocation");var fields=geogroup.createChild("div","geo-fields");const noOverrideOption={title:WebInspector.UIString("No override"),location:WebInspector.SensorsView.NonPresetOptions.NoOverride};const customLocationOption={title:WebInspector.UIString("Custom location..."),location:WebInspector.SensorsView.NonPresetOptions.Custom};this._locationSelectElement=this.contentElement.createChild("select","chrome-select");this._locationSelectElement.appendChild(new Option(noOverrideOption.title,noOverrideOption.location));this._locationSelectElement.appendChild(new Option(customLocationOption.title,customLocationOption.location));var locationGroups=WebInspector.SensorsView.PresetLocations;for(var i=0;i<locationGroups.length;++i){var group=locationGroups[i].value;var groupElement=this._locationSelectElement.createChild("optgroup");groupElement.label=locationGroups[i].title;for(var j=0;j<group.length;++j)
groupElement.appendChild(new Option(group[j].title,group[j].location));}
this._locationSelectElement.selectedIndex=0;fields.appendChild(this._locationSelectElement);this._locationSelectElement.addEventListener("change",this._geolocationSelectChanged.bind(this));this._fieldsetElement=fields.createChild("fieldset");this._fieldsetElement.disabled=!this._geolocationOverrideEnabled;this._fieldsetElement.id="geolocation-override-section";var latitudeGroup=this._fieldsetElement.createChild("div","latlong-group");var longitudeGroup=this._fieldsetElement.createChild("div","latlong-group");this._latitudeInput=latitudeGroup.createChild("input");this._latitudeInput.setAttribute("type","number");this._latitudeInput.value=0;this._latitudeSetter=WebInspector.bindInput(this._latitudeInput,this._applyGeolocationUserInput.bind(this),WebInspector.Geolocation.latitudeValidator,true);this._latitudeSetter(String(geolocation.latitude));this._longitudeInput=longitudeGroup.createChild("input");this._longitudeInput.setAttribute("type","number");this._longitudeInput.value=0;this._longitudeSetter=WebInspector.bindInput(this._longitudeInput,this._applyGeolocationUserInput.bind(this),WebInspector.Geolocation.longitudeValidator,true);this._longitudeSetter(String(geolocation.longitude));latitudeGroup.createChild("div","latlong-title").textContent=WebInspector.UIString("Latitude");longitudeGroup.createChild("div","latlong-title").textContent=WebInspector.UIString("Longitude");},_geolocationSelectChanged:function()
{this._fieldsetElement.disabled=false;var value=this._locationSelectElement.options[this._locationSelectElement.selectedIndex].value;if(value===WebInspector.SensorsView.NonPresetOptions.NoOverride){this._geolocationOverrideEnabled=false;this._fieldsetElement.disabled=true;}else if(value===WebInspector.SensorsView.NonPresetOptions.Custom){this._geolocationOverrideEnabled=true;}else if(value===WebInspector.SensorsView.NonPresetOptions.Unavailable){this._geolocationOverrideEnabled=true;this._geolocation=new WebInspector.Geolocation(0,0,true);}else{this._geolocationOverrideEnabled=true;var coordinates=JSON.parse(value);this._geolocation=new WebInspector.Geolocation(coordinates[0],coordinates[1],false);this._latitudeSetter(coordinates[0]);this._longitudeSetter(coordinates[1]);}
this._applyGeolocation();if(value===WebInspector.SensorsView.NonPresetOptions.Custom)
this._latitudeInput.focus();},_applyGeolocationUserInput:function()
{var geolocation=WebInspector.Geolocation.parseUserInput(this._latitudeInput.value.trim(),this._longitudeInput.value.trim(),"");if(!geolocation)
return;this._setSelectElementLabel(this._locationSelectElement,WebInspector.SensorsView.NonPresetOptions.Custom);this._geolocation=geolocation;this._applyGeolocation();},_applyGeolocation:function()
{if(this._geolocationOverrideEnabled){this._geolocationSetting.set(this._geolocation.toSetting());this._geolocation.apply();}else{this._geolocation.clear();}},_createDeviceOrientationSection:function()
{var orientationGroup=this.contentElement.createChild("section","sensors-group");orientationGroup.createChild("div","sensors-group-title").textContent=WebInspector.UIString("Orientation");var orientationContent=orientationGroup.createChild("div","orientation-content");var fields=orientationContent.createChild("div","orientation-fields");const orientationOffOption={title:WebInspector.UIString("Off"),orientation:WebInspector.SensorsView.NonPresetOptions.NoOverride};const customOrientationOption={title:WebInspector.UIString("Custom orientation..."),orientation:WebInspector.SensorsView.NonPresetOptions.Custom};this._orientationSelectElement=this.contentElement.createChild("select","chrome-select");this._orientationSelectElement.appendChild(new Option(orientationOffOption.title,orientationOffOption.orientation));this._orientationSelectElement.appendChild(new Option(customOrientationOption.title,customOrientationOption.orientation));var orientationGroups=WebInspector.SensorsView.PresetOrientations;for(var i=0;i<orientationGroups.length;++i){var groupElement=this._orientationSelectElement.createChild("optgroup");groupElement.label=orientationGroups[i].title;var group=orientationGroups[i].value;for(var j=0;j<group.length;++j)
groupElement.appendChild(new Option(group[j].title,group[j].orientation));}
this._orientationSelectElement.selectedIndex=0;fields.appendChild(this._orientationSelectElement);this._orientationSelectElement.addEventListener("change",this._orientationSelectChanged.bind(this));this._deviceOrientationFieldset=this._createDeviceOrientationOverrideElement(this._deviceOrientation);this._stageElement=orientationContent.createChild("div","orientation-stage");this._stageElement.title=WebInspector.UIString("Shift+drag horizontally to rotate around the y-axis");this._orientationLayer=this._stageElement.createChild("div","orientation-layer");this._boxElement=this._orientationLayer.createChild("section","orientation-box orientation-element");this._boxElement.createChild("section","orientation-front orientation-element");this._boxElement.createChild("section","orientation-top orientation-element");this._boxElement.createChild("section","orientation-back orientation-element");this._boxElement.createChild("section","orientation-left orientation-element");this._boxElement.createChild("section","orientation-right orientation-element");this._boxElement.createChild("section","orientation-bottom orientation-element");WebInspector.installDragHandle(this._stageElement,this._onBoxDragStart.bind(this),this._onBoxDrag.bind(this),null,"-webkit-grabbing","-webkit-grab");fields.appendChild(this._deviceOrientationFieldset);this._enableOrientationFields(true);this._setBoxOrientation(this._deviceOrientation,false);},_enableOrientationFields:function(disable)
{if(disable){this._deviceOrientationFieldset.disabled=true;this._stageElement.classList.add("disabled");}else{this._deviceOrientationFieldset.disabled=false;this._stageElement.classList.remove("disabled");}},_orientationSelectChanged:function()
{var value=this._orientationSelectElement.options[this._orientationSelectElement.selectedIndex].value;this._enableOrientationFields(false);if(value===WebInspector.SensorsView.NonPresetOptions.NoOverride){this._deviceOrientationOverrideEnabled=false;this._enableOrientationFields(true);}else if(value===WebInspector.SensorsView.NonPresetOptions.Custom){this._deviceOrientationOverrideEnabled=true;this._alphaElement.focus();}else{var parsedValue=JSON.parse(value);this._deviceOrientationOverrideEnabled=true;this._deviceOrientation=new WebInspector.DeviceOrientation(parsedValue[0],parsedValue[1],parsedValue[2]);this._setDeviceOrientation(this._deviceOrientation,WebInspector.SensorsView.DeviceOrientationModificationSource.SelectPreset);}},_applyDeviceOrientation:function()
{if(this._deviceOrientationOverrideEnabled){this._deviceOrientationSetting.set(this._deviceOrientation.toSetting());this._deviceOrientation.apply();}else{this._deviceOrientation.clear();}},_setSelectElementLabel:function(selectElement,labelValue)
{var optionValues=Array.prototype.map.call(selectElement.options,x=>x.value);selectElement.selectedIndex=optionValues.indexOf(labelValue);},_applyDeviceOrientationUserInput:function()
{this._setDeviceOrientation(WebInspector.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(),this._betaElement.value.trim(),this._gammaElement.value.trim()),WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput);this._setSelectElementLabel(this._orientationSelectElement,WebInspector.SensorsView.NonPresetOptions.Custom);},_resetDeviceOrientation:function()
{this._setDeviceOrientation(new WebInspector.DeviceOrientation(0,90,0),WebInspector.SensorsView.DeviceOrientationModificationSource.ResetButton);this._setSelectElementLabel(this._orientationSelectElement,"[0, 90, 0]");},_setDeviceOrientation:function(deviceOrientation,modificationSource)
{if(!deviceOrientation)
return;function roundAngle(angle)
{return Math.round(angle*10000)/10000;}
if(modificationSource!=WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput){this._alphaSetter(roundAngle(deviceOrientation.alpha));this._betaSetter(roundAngle(deviceOrientation.beta));this._gammaSetter(roundAngle(deviceOrientation.gamma));}
var animate=modificationSource!==WebInspector.SensorsView.DeviceOrientationModificationSource.UserDrag;this._setBoxOrientation(deviceOrientation,animate);this._deviceOrientation=deviceOrientation;this._applyDeviceOrientation();},_createAxisInput:function(parentElement,input,label)
{var div=parentElement.createChild("div","orientation-axis-input-container");div.appendChild(input);div.createTextChild(label);input.type="number";return WebInspector.bindInput(input,this._applyDeviceOrientationUserInput.bind(this),WebInspector.DeviceOrientation.validator,true);},_createDeviceOrientationOverrideElement:function(deviceOrientation)
{var fieldsetElement=createElement("fieldset");fieldsetElement.classList.add("device-orientation-override-section");var cellElement=fieldsetElement.createChild("td","orientation-inputs-cell");this._alphaElement=createElement("input");this._alphaSetter=this._createAxisInput(cellElement,this._alphaElement,WebInspector.UIString("\u03B1 (alpha)"));this._alphaSetter(String(deviceOrientation.alpha));this._betaElement=createElement("input");this._betaSetter=this._createAxisInput(cellElement,this._betaElement,WebInspector.UIString("\u03B2 (beta)"));this._betaSetter(String(deviceOrientation.beta));this._gammaElement=createElement("input");this._gammaSetter=this._createAxisInput(cellElement,this._gammaElement,WebInspector.UIString("\u03B3 (gamma)"));this._gammaSetter(String(deviceOrientation.gamma));cellElement.appendChild(createTextButton(WebInspector.UIString("Reset"),this._resetDeviceOrientation.bind(this),"orientation-reset-button"));return fieldsetElement;},_setBoxOrientation:function(deviceOrientation,animate)
{if(animate)
this._stageElement.classList.add("is-animating");else
this._stageElement.classList.remove("is-animating");var matrix=new WebKitCSSMatrix();this._boxMatrix=matrix.rotate(-deviceOrientation.beta,deviceOrientation.gamma,-deviceOrientation.alpha);var eulerAngles=new WebInspector.Geometry.EulerAngles(deviceOrientation.alpha,deviceOrientation.beta,deviceOrientation.gamma);this._orientationLayer.style.transform=eulerAngles.toRotate3DString();},_onBoxDrag:function(event)
{var mouseMoveVector=this._calculateRadiusVector(event.x,event.y);if(!mouseMoveVector)
return true;event.consume(true);var axis,angle;if(event.shiftKey){axis=new WebInspector.Geometry.Vector(0,0,-1);angle=(this._mouseDownVector.x-mouseMoveVector.x)*WebInspector.SensorsView.ShiftDragOrientationSpeed;}else{axis=WebInspector.Geometry.crossProduct(this._mouseDownVector,mouseMoveVector);angle=WebInspector.Geometry.calculateAngle(this._mouseDownVector,mouseMoveVector);}
var currentMatrix=new WebKitCSSMatrix();currentMatrix=currentMatrix.rotate(-90,0,0).rotateAxisAngle(axis.x,axis.y,axis.z,angle).rotate(90,0,0).multiply(this._originalBoxMatrix);var eulerAngles=WebInspector.Geometry.EulerAngles.fromRotationMatrix(currentMatrix);var newOrientation=new WebInspector.DeviceOrientation(-eulerAngles.alpha,-eulerAngles.beta,eulerAngles.gamma);this._setDeviceOrientation(newOrientation,WebInspector.SensorsView.DeviceOrientationModificationSource.UserDrag);this._setSelectElementLabel(this._orientationSelectElement,WebInspector.SensorsView.NonPresetOptions.Custom);return false;},_onBoxDragStart:function(event)
{if(!this._deviceOrientationOverrideEnabled)
return false;this._mouseDownVector=this._calculateRadiusVector(event.x,event.y);this._originalBoxMatrix=this._boxMatrix;if(!this._mouseDownVector)
return false;event.consume(true);return true;},_calculateRadiusVector:function(x,y)
{var rect=this._stageElement.getBoundingClientRect();var radius=Math.max(rect.width,rect.height)/2;var sphereX=(x-rect.left-rect.width/2)/radius;var sphereY=(y-rect.top-rect.height/2)/radius;var sqrSum=sphereX*sphereX+sphereY*sphereY;if(sqrSum>0.5)
return new WebInspector.Geometry.Vector(sphereX,sphereY,0.5/Math.sqrt(sqrSum));return new WebInspector.Geometry.Vector(sphereX,sphereY,Math.sqrt(1-sqrSum));},_appendTouchControl:function()
{var groupElement=this.contentElement.createChild("div","sensors-group");var title=groupElement.createChild("div","sensors-group-title");var fieldsElement=groupElement.createChild("div","sensors-group-fields");title.textContent=WebInspector.UIString("Touch");var select=fieldsElement.createChild("select","chrome-select");select.appendChild(new Option(WebInspector.UIString("Device-based"),"auto"));select.appendChild(new Option(WebInspector.UIString("Force enabled"),"enabled"));select.addEventListener("change",applyTouch,false);function applyTouch()
{WebInspector.MultitargetTouchModel.instance().setCustomTouchEnabled(select.value==="enabled");}},__proto__:WebInspector.VBox.prototype}
WebInspector.SensorsView.DeviceOrientationModificationSource={UserInput:"userInput",UserDrag:"userDrag",ResetButton:"resetButton",SelectPreset:"selectPreset"}
WebInspector.SensorsView.NonPresetOptions={"NoOverride":"noOverride","Custom":"custom","Unavailable":"unavailable"}
WebInspector.SensorsView.PresetLocations=[{title:"Presets",value:[{title:WebInspector.UIString("Berlin"),location:"[52.520007, 13.404954]"},{title:WebInspector.UIString("London"),location:"[51.507351, -0.127758]"},{title:WebInspector.UIString("Moscow"),location:"[55.755826, 37.617300]"},{title:WebInspector.UIString("Mountain View"),location:"[37.386052, -122.083851]"},{title:WebInspector.UIString("Mumbai"),location:"[19.075984, 72.877656]"},{title:WebInspector.UIString("San Francisco"),location:"[37.774929, -122.419416]"},{title:WebInspector.UIString("Shanghai"),location:"[31.230416, 121.473701]"},{title:WebInspector.UIString("São Paulo"),location:"[-23.550520, -46.633309]"},{title:WebInspector.UIString("Tokyo"),location:"[35.689487, 139.691706]"},]},{title:"Error",value:[{title:WebInspector.UIString("Location unavailable"),location:WebInspector.SensorsView.NonPresetOptions.Unavailable}]}]
WebInspector.SensorsView.PresetOrientations=[{title:"Presets",value:[{title:WebInspector.UIString("Portrait"),orientation:"[0, 90, 0]"},{title:WebInspector.UIString("Portrait upside down"),orientation:"[180, -90, 0]"},{title:WebInspector.UIString("Landscape left"),orientation:"[0, 90, -90]"},{title:WebInspector.UIString("Landscape right"),orientation:"[0, 90, 90]"},{title:WebInspector.UIString("Display up"),orientation:"[0, 0, 0]"},{title:WebInspector.UIString("Display down"),orientation:"[0, 180, 0]"}]}]
WebInspector.SensorsView.instance=function()
{if(!WebInspector.SensorsView._instanceObject)
WebInspector.SensorsView._instanceObject=new WebInspector.SensorsView();return WebInspector.SensorsView._instanceObject;}
WebInspector.SensorsView.ShowActionDelegate=function()
{}
WebInspector.SensorsView.ShowActionDelegate.prototype={handleAction:function(context,actionId)
{WebInspector.inspectorView.showViewInDrawer("sensors");return true;}}
WebInspector.SensorsView.ShiftDragOrientationSpeed=16;;WebInspector.MultitargetTouchModel=function()
{this._touchEnabled=false;this._touchMobile=false;this._customTouchEnabled=false;WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);}
WebInspector.MultitargetTouchModel._symbol=Symbol("MultitargetTouchModel.symbol");WebInspector.MultitargetTouchModel.prototype={setTouchEnabled:function(enabled,mobile)
{this._touchEnabled=enabled;this._touchMobile=mobile;this._updateAllTargets();},setCustomTouchEnabled:function(enabled)
{this._customTouchEnabled=enabled;this._updateAllTargets();},_updateAllTargets:function()
{for(var target of WebInspector.targetManager.targets(WebInspector.Target.Type.Page))
this._applyToTarget(target);},_applyToTarget:function(target)
{var current={enabled:this._touchEnabled,configuration:this._touchMobile?"mobile":"desktop"};if(this._customTouchEnabled)
current={enabled:true,configuration:"mobile"};var domModel=WebInspector.DOMModel.fromTarget(target);var inspectModeEnabled=domModel?domModel.inspectModeEnabled():false;if(inspectModeEnabled)
current={enabled:false,configuration:"mobile"};const injectedFunction=function(){const touchEvents=["ontouchstart","ontouchend","ontouchmove","ontouchcancel"];var recepients=[window.__proto__,document.__proto__];for(var i=0;i<touchEvents.length;++i){for(var j=0;j<recepients.length;++j){if(!(touchEvents[i]in recepients[j]))
Object.defineProperty(recepients[j],touchEvents[i],{value:null,writable:true,configurable:true,enumerable:true});}}};var symbol=WebInspector.MultitargetTouchModel._symbol;var previous=target[symbol]||{enabled:false,configuration:"mobile",scriptId:""};if(previous.enabled===current.enabled&&(!current.enabled||previous.configuration===current.configuration))
return;if(previous.scriptId){target.pageAgent().removeScriptToEvaluateOnLoad(previous.scriptId);target[symbol].scriptId="";}
target[symbol]=current;target[symbol].scriptId="";if(current.enabled)
target.pageAgent().addScriptToEvaluateOnLoad("("+injectedFunction.toString()+")()",scriptAddedCallback);function scriptAddedCallback(error,scriptId)
{(target[symbol]||{}).scriptId=error?"":scriptId;}
target.emulationAgent().setTouchEmulationEnabled(current.enabled,current.configuration);},_inspectModeToggled:function(event)
{var domModel=(event.target);this._applyToTarget(domModel.target());},targetAdded:function(target)
{var domModel=WebInspector.DOMModel.fromTarget(target);if(domModel)
domModel.addEventListener(WebInspector.DOMModel.Events.InspectModeWillBeToggled,this._inspectModeToggled,this);this._applyToTarget(target);},targetRemoved:function(target)
{var domModel=WebInspector.DOMModel.fromTarget(target);if(domModel)
domModel.removeEventListener(WebInspector.DOMModel.Events.InspectModeWillBeToggled,this._inspectModeToggled,this);}}
WebInspector.MultitargetTouchModel._instance=null;WebInspector.MultitargetTouchModel.instance=function()
{if(!WebInspector.MultitargetTouchModel._instance)
WebInspector.MultitargetTouchModel._instance=new WebInspector.MultitargetTouchModel();return(WebInspector.MultitargetTouchModel._instance);};WebInspector.DeviceModeModel=function(updateCallback)
{this._updateCallback=updateCallback;this._screenRect=new WebInspector.Rect(0,0,1,1);this._visiblePageRect=new WebInspector.Rect(0,0,1,1);this._availableSize=new Size(1,1);this._preferredSize=new Size(1,1);this._initialized=false;this._deviceMetricsThrottler=new WebInspector.Throttler(0);this._appliedDeviceSize=new Size(1,1);this._appliedDeviceScaleFactor=window.devicePixelRatio;this._appliedUserAgentType=WebInspector.DeviceModeModel.UA.Desktop;this._scaleSetting=WebInspector.settings.createSetting("emulation.deviceScale",1);if(!this._scaleSetting.get())
this._scaleSetting.set(1);this._scaleSetting.addChangeListener(this._scaleSettingChanged,this);this._widthSetting=WebInspector.settings.createSetting("emulation.deviceWidth",400);if(this._widthSetting.get()<WebInspector.DeviceModeModel.MinDeviceSize)
this._widthSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);if(this._widthSetting.get()>WebInspector.DeviceModeModel.MaxDeviceSize)
this._widthSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);this._widthSetting.addChangeListener(this._widthSettingChanged,this);this._heightSetting=WebInspector.settings.createSetting("emulation.deviceHeight",0);if(this._heightSetting.get()&&this._heightSetting.get()<WebInspector.DeviceModeModel.MinDeviceSize)
this._heightSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);if(this._heightSetting.get()>WebInspector.DeviceModeModel.MaxDeviceSize)
this._heightSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);this._heightSetting.addChangeListener(this._heightSettingChanged,this);this._uaSetting=WebInspector.settings.createSetting("emulation.deviceUA",WebInspector.DeviceModeModel.UA.Mobile);this._uaSetting.addChangeListener(this._uaSettingChanged,this);this._deviceScaleFactorSetting=WebInspector.settings.createSetting("emulation.deviceScaleFactor",0);this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSettingChanged,this);this._deviceOutlineSetting=WebInspector.settings.moduleSetting("emulation.showDeviceOutline");this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChanged,this);this._type=WebInspector.DeviceModeModel.Type.None;this._device=null;this._mode=null;this._fitScale=1;this._target=null;this._onTargetAvailable=null;WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);}
WebInspector.DeviceModeModel.Type={None:"None",Responsive:"Responsive",Device:"Device"}
WebInspector.DeviceModeModel.UA={Mobile:WebInspector.UIString("Mobile"),MobileNoTouch:WebInspector.UIString("Mobile (no touch)"),Desktop:WebInspector.UIString("Desktop"),DesktopTouch:WebInspector.UIString("Desktop (touch)")}
WebInspector.DeviceModeModel.MinDeviceSize=50;WebInspector.DeviceModeModel.MaxDeviceSize=9999;WebInspector.DeviceModeModel.deviceSizeValidator=function(value)
{if(/^[\d]+$/.test(value)&&value>=WebInspector.DeviceModeModel.MinDeviceSize&&value<=WebInspector.DeviceModeModel.MaxDeviceSize)
return true;return false;}
WebInspector.DeviceModeModel.deviceScaleFactorValidator=function(value)
{if(!value||(/^[\d]+(\.\d+)?|\.\d+$/.test(value)&&value>=0&&value<=10))
return true;return false;}
WebInspector.DeviceModeModel._defaultMobileUserAgent="Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36";WebInspector.DeviceModeModel.defaultMobileScaleFactor=2;WebInspector.DeviceModeModel.prototype={setAvailableSize:function(availableSize,preferredSize)
{this._availableSize=availableSize;this._preferredSize=preferredSize;this._initialized=true;this._calculateAndEmulate(false);},emulate:function(type,device,mode)
{var resetPageScaleFactor=this._type!==type||this._device!==device||this._mode!==mode;this._type=type;if(type===WebInspector.DeviceModeModel.Type.Device){console.assert(device&&mode,"Must pass device and mode for device emulation");this._device=device;this._mode=mode;if(this._initialized){var orientation=device.orientationByName(mode.orientation);this._scaleSetting.set(this._calculateFitScale(orientation.width,orientation.height,this._currentOutline()));}}else{this._device=null;this._mode=null;}
if(type!==WebInspector.DeviceModeModel.Type.None)
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.DeviceModeEnabled);this._calculateAndEmulate(resetPageScaleFactor);},setWidth:function(width)
{var max=Math.min(WebInspector.DeviceModeModel.MaxDeviceSize,this._preferredScaledWidth());width=Math.max(Math.min(width,max),1);this._widthSetting.set(width);},setWidthAndScaleToFit:function(width)
{width=Math.max(Math.min(width,WebInspector.DeviceModeModel.MaxDeviceSize),1);this._scaleSetting.set(this._calculateFitScale(width,this._heightSetting.get()));this._widthSetting.set(width);},setHeight:function(height)
{var max=Math.min(WebInspector.DeviceModeModel.MaxDeviceSize,this._preferredScaledHeight());height=Math.max(Math.min(height,max),0);if(height===this._preferredScaledHeight())
height=0;this._heightSetting.set(height);},setHeightAndScaleToFit:function(height)
{height=Math.max(Math.min(height,WebInspector.DeviceModeModel.MaxDeviceSize),0);this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(),height));this._heightSetting.set(height);},setScale:function(scale)
{this._scaleSetting.set(scale);},device:function()
{return this._device;},mode:function()
{return this._mode;},type:function()
{return this._type;},screenImage:function()
{return(this._device&&this._mode)?this._device.modeImage(this._mode):"";},outlineImage:function()
{return(this._device&&this._mode&&this._deviceOutlineSetting.get())?this._device.outlineImage(this._mode):"";},outlineRect:function()
{return this._outlineRect;},screenRect:function()
{return this._screenRect;},visiblePageRect:function()
{return this._visiblePageRect;},scale:function()
{return this._scale;},fitScale:function()
{return this._fitScale;},appliedDeviceSize:function()
{return this._appliedDeviceSize;},appliedDeviceScaleFactor:function()
{return this._appliedDeviceScaleFactor;},appliedUserAgentType:function()
{return this._appliedUserAgentType;},isFullHeight:function()
{return!this._heightSetting.get();},scaleSetting:function()
{return this._scaleSetting;},uaSetting:function()
{return this._uaSetting;},deviceScaleFactorSetting:function()
{return this._deviceScaleFactorSetting;},deviceOutlineSetting:function()
{return this._deviceOutlineSetting;},reset:function()
{this._deviceScaleFactorSetting.set(0);this._scaleSetting.set(1);this.setWidth(400);this.setHeight(0);this._uaSetting.set(WebInspector.DeviceModeModel.UA.Mobile);},targetAdded:function(target)
{if(!this._target){this._target=target;if(this._onTargetAvailable){var callback=this._onTargetAvailable;this._onTargetAvailable=null;callback();}}},targetRemoved:function(target)
{if(this._target===target)
this._target=null;},_scaleSettingChanged:function()
{this._calculateAndEmulate(false);},_widthSettingChanged:function()
{this._calculateAndEmulate(false);},_heightSettingChanged:function()
{this._calculateAndEmulate(false);},_uaSettingChanged:function()
{this._calculateAndEmulate(true);},_deviceScaleFactorSettingChanged:function()
{this._calculateAndEmulate(false);},_deviceOutlineSettingChanged:function()
{this._calculateAndEmulate(false);},_preferredScaledWidth:function()
{return Math.floor(this._preferredSize.width/(this._scaleSetting.get()||1));},_preferredScaledHeight:function()
{return Math.floor(this._preferredSize.height/(this._scaleSetting.get()||1));},_currentOutline:function()
{var outline=new Insets(0,0,0,0);if(this._type!==WebInspector.DeviceModeModel.Type.Device)
return outline;var orientation=this._device.orientationByName(this._mode.orientation);if(this._deviceOutlineSetting.get())
outline=orientation.outlineInsets||outline;return outline;},_calculateAndEmulate:function(resetPageScaleFactor)
{if(!this._target)
this._onTargetAvailable=this._calculateAndEmulate.bind(this,resetPageScaleFactor);if(this._type===WebInspector.DeviceModeModel.Type.Device){var orientation=this._device.orientationByName(this._mode.orientation);var outline=this._currentOutline();this._fitScale=this._calculateFitScale(orientation.width,orientation.height,outline);if(this._device.mobile())
this._appliedUserAgentType=this._device.touch()?WebInspector.DeviceModeModel.UA.Mobile:WebInspector.DeviceModeModel.UA.MobileNoTouch;else
this._appliedUserAgentType=this._device.touch()?WebInspector.DeviceModeModel.UA.DesktopTouch:WebInspector.DeviceModeModel.UA.Desktop;this._applyDeviceMetrics(new Size(orientation.width,orientation.height),this._mode.insets,outline,this._scaleSetting.get(),this._device.deviceScaleFactor,this._device.mobile(),this._mode.orientation==WebInspector.EmulatedDevice.Horizontal?"landscapePrimary":"portraitPrimary",resetPageScaleFactor);this._applyUserAgent(this._device.userAgent);this._applyTouch(this._device.touch(),this._device.mobile());}else if(this._type===WebInspector.DeviceModeModel.Type.None){this._fitScale=this._calculateFitScale(this._availableSize.width,this._availableSize.height);this._appliedUserAgentType=WebInspector.DeviceModeModel.UA.Desktop;this._applyDeviceMetrics(this._availableSize,new Insets(0,0,0,0),new Insets(0,0,0,0),1,0,false,"",resetPageScaleFactor);this._applyUserAgent("");this._applyTouch(false,false);}else if(this._type===WebInspector.DeviceModeModel.Type.Responsive){var screenWidth=this._widthSetting.get();if(!screenWidth||screenWidth>this._preferredScaledWidth())
screenWidth=this._preferredScaledWidth();var screenHeight=this._heightSetting.get();if(!screenHeight||screenHeight>this._preferredScaledHeight())
screenHeight=this._preferredScaledHeight();var mobile=this._uaSetting.get()===WebInspector.DeviceModeModel.UA.Mobile||this._uaSetting.get()===WebInspector.DeviceModeModel.UA.MobileNoTouch;var defaultDeviceScaleFactor=mobile?WebInspector.DeviceModeModel.defaultMobileScaleFactor:0;this._fitScale=this._calculateFitScale(this._widthSetting.get(),this._heightSetting.get());this._appliedUserAgentType=this._uaSetting.get();this._applyDeviceMetrics(new Size(screenWidth,screenHeight),new Insets(0,0,0,0),new Insets(0,0,0,0),this._scaleSetting.get(),this._deviceScaleFactorSetting.get()||defaultDeviceScaleFactor,mobile,screenHeight>=screenWidth?"portraitPrimary":"landscapePrimary",resetPageScaleFactor);this._applyUserAgent(mobile?WebInspector.DeviceModeModel._defaultMobileUserAgent:"");this._applyTouch(this._uaSetting.get()===WebInspector.DeviceModeModel.UA.DesktopTouch||this._uaSetting.get()===WebInspector.DeviceModeModel.UA.Mobile,this._uaSetting.get()===WebInspector.DeviceModeModel.UA.Mobile);}
if(this._target)
this._target.renderingAgent().setShowViewportSizeOnResize(this._type===WebInspector.DeviceModeModel.Type.None);this._updateCallback.call(null);},_calculateFitScale:function(screenWidth,screenHeight,outline)
{var outlineWidth=outline?outline.left+outline.right:0;var outlineHeight=outline?outline.top+outline.bottom:0;var scale=Math.min(screenWidth?this._preferredSize.width/(screenWidth+outlineWidth):1,screenHeight?this._preferredSize.height/(screenHeight+outlineHeight):1);return Math.min(scale,1);},setSizeAndScaleToFit:function(width,height)
{this._scaleSetting.set(this._calculateFitScale(width,height));this.setWidth(width);},_applyUserAgent:function(userAgent)
{WebInspector.multitargetNetworkManager.setUserAgentOverride(userAgent);},_applyDeviceMetrics:function(screenSize,insets,outline,scale,deviceScaleFactor,mobile,screenOrientation,resetPageScaleFactor)
{screenSize.width=Math.max(1,Math.floor(screenSize.width));screenSize.height=Math.max(1,Math.floor(screenSize.height));var pageWidth=screenSize.width-insets.left-insets.right;var pageHeight=screenSize.height-insets.top-insets.bottom;var positionX=insets.left;var positionY=insets.top;var screenOrientationAngle=screenOrientation==="landscapePrimary"?90:0;this._appliedDeviceSize=screenSize;this._appliedDeviceScaleFactor=deviceScaleFactor||window.devicePixelRatio;this._screenRect=new WebInspector.Rect(Math.max(0,(this._availableSize.width-screenSize.width*scale)/2),outline.top*scale,screenSize.width*scale,screenSize.height*scale);this._outlineRect=new WebInspector.Rect(this._screenRect.left-outline.left*scale,0,(outline.left+screenSize.width+outline.right)*scale,(outline.top+screenSize.height+outline.bottom)*scale);this._visiblePageRect=new WebInspector.Rect(positionX*scale,positionY*scale,Math.min(pageWidth*scale,this._availableSize.width-this._screenRect.left-positionX*scale),Math.min(pageHeight*scale,this._availableSize.height-this._screenRect.top-positionY*scale));this._scale=scale;if(scale===1&&this._availableSize.width>=screenSize.width&&this._availableSize.height>=screenSize.height){pageWidth=0;pageHeight=0;}
if(this._visiblePageRect.width===pageWidth*scale&&this._visiblePageRect.height===pageHeight*scale){pageWidth=0;pageHeight=0;}
this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this));function setDeviceMetricsOverride()
{if(!this._target)
return Promise.resolve();var clear=!pageWidth&&!pageHeight&&!mobile&&!deviceScaleFactor&&scale===1&&!screenOrientation;var allPromises=[];if(resetPageScaleFactor)
allPromises.push(this._target.emulationAgent().resetPageScaleFactor());var setDevicePromise;if(clear){setDevicePromise=this._target.emulationAgent().clearDeviceMetricsOverride(this._deviceMetricsOverrideAppliedForTest.bind(this));}else{var params={width:pageWidth,height:pageHeight,deviceScaleFactor:deviceScaleFactor,mobile:mobile,fitWindow:false,scale:scale,screenWidth:screenSize.width,screenHeight:screenSize.height,positionX:positionX,positionY:positionY};if(screenOrientation)
params.screenOrientation={type:screenOrientation,angle:screenOrientationAngle};setDevicePromise=this._target.emulationAgent().invoke_setDeviceMetricsOverride(params,this._deviceMetricsOverrideAppliedForTest.bind(this));}
allPromises.push(setDevicePromise);return Promise.all(allPromises);}},_deviceMetricsOverrideAppliedForTest:function()
{},_applyTouch:function(touchEnabled,mobile)
{WebInspector.MultitargetTouchModel.instance().setTouchEnabled(touchEnabled,mobile);}};WebInspector.DeviceModeToolbar=function(model,showMediaInspectorSetting,showRulersSetting)
{this._model=model;this._showMediaInspectorSetting=showMediaInspectorSetting;this._showRulersSetting=showRulersSetting;this._deviceOutlineSetting=this._model.deviceOutlineSetting();this._showDeviceScaleFactorSetting=WebInspector.settings.createSetting("emulation.showDeviceScaleFactor",false);this._showDeviceScaleFactorSetting.addChangeListener(this._updateDeviceScaleFactorVisibility,this);this._showUserAgentTypeSetting=WebInspector.settings.createSetting("emulation.showUserAgentType",false);this._showUserAgentTypeSetting.addChangeListener(this._updateUserAgentTypeVisibility,this);this._showNetworkConditionsSetting=WebInspector.settings.createSetting("emulation.showNetworkConditions",false);this._showNetworkConditionsSetting.addChangeListener(this._updateNetworkConditionsVisibility,this);this._lastMode=new Map();this._element=createElementWithClass("div","device-mode-toolbar");var leftContainer=this._element.createChild("div","device-mode-toolbar-spacer");leftContainer.createChild("div","device-mode-toolbar-spacer");var leftToolbar=new WebInspector.Toolbar("",leftContainer);leftToolbar.makeWrappable();this._fillLeftToolbar(leftToolbar);var mainToolbar=new WebInspector.Toolbar("",this._element);mainToolbar.makeWrappable();this._fillMainToolbar(mainToolbar);var rightContainer=this._element.createChild("div","device-mode-toolbar-spacer");var rightToolbar=new WebInspector.Toolbar("device-mode-toolbar-fixed-size",rightContainer);rightToolbar.makeWrappable();this._fillRightToolbar(rightToolbar);var modeToolbar=new WebInspector.Toolbar("device-mode-toolbar-fixed-size",rightContainer);modeToolbar.makeWrappable();this._fillModeToolbar(modeToolbar);rightContainer.createChild("div","device-mode-toolbar-spacer");var optionsToolbar=new WebInspector.Toolbar("",rightContainer);optionsToolbar.makeWrappable(true);this._fillOptionsToolbar(optionsToolbar);this._emulatedDevicesList=WebInspector.EmulatedDevicesList.instance();this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated,this._deviceListChanged,this);this._emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated,this._deviceListChanged,this);this._persistenceSetting=WebInspector.settings.createSetting("emulation.deviceModeValue",{device:"",orientation:"",mode:""});}
WebInspector.DeviceModeToolbar.prototype={_fillLeftToolbar:function(toolbar)
{toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));this._deviceSelectItem=new WebInspector.ToolbarMenuButton(this._appendDeviceMenuItems.bind(this));this._deviceSelectItem.setGlyph("");this._deviceSelectItem.turnIntoSelect(95);toolbar.appendToolbarItem(this._deviceSelectItem);},_fillMainToolbar:function(toolbar)
{var widthInput=createElementWithClass("input","device-mode-size-input");widthInput.maxLength=4;widthInput.type="text";widthInput.title=WebInspector.UIString("Width");this._updateWidthInput=WebInspector.bindInput(widthInput,applyWidth.bind(this),WebInspector.DeviceModeModel.deviceSizeValidator,true);this._widthInput=widthInput;this._widthItem=this._wrapToolbarItem(widthInput);toolbar.appendToolbarItem(this._widthItem);var xElement=createElementWithClass("div","device-mode-x");xElement.textContent="\u00D7";this._xItem=this._wrapToolbarItem(xElement);toolbar.appendToolbarItem(this._xItem);var heightInput=createElementWithClass("input","device-mode-size-input");heightInput.maxLength=4;heightInput.type="text";heightInput.title=WebInspector.UIString("Height (leave empty for full)");this._updateHeightInput=WebInspector.bindInput(heightInput,applyHeight.bind(this),validateHeight,true);this._heightInput=heightInput;this._heightItem=this._wrapToolbarItem(heightInput);toolbar.appendToolbarItem(this._heightItem);function validateHeight(value)
{return!value||WebInspector.DeviceModeModel.deviceSizeValidator(value);}
function applyWidth(value)
{var width=value?Number(value):0;this._model.setWidthAndScaleToFit(width);}
function applyHeight(value)
{var height=value?Number(value):0;this._model.setHeightAndScaleToFit(height);}},_fillRightToolbar:function(toolbar)
{toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));this._scaleItem=new WebInspector.ToolbarMenuButton(this._appendScaleMenuItems.bind(this));this._scaleItem.setTitle(WebInspector.UIString("Zoom"));this._scaleItem.setGlyph("");this._scaleItem.turnIntoSelect();toolbar.appendToolbarItem(this._scaleItem);toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));this._deviceScaleItem=new WebInspector.ToolbarMenuButton(this._appendDeviceScaleMenuItems.bind(this));this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());this._deviceScaleItem.setTitle(WebInspector.UIString("Device pixel ratio"));this._deviceScaleItem.setGlyph("");this._deviceScaleItem.turnIntoSelect();this._deviceScaleItem.element.style.padding="0 5px";toolbar.appendToolbarItem(this._deviceScaleItem);toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));this._uaItem=new WebInspector.ToolbarMenuButton(this._appendUserAgentMenuItems.bind(this));this._uaItem.setVisible(this._showUserAgentTypeSetting.get());this._uaItem.setTitle(WebInspector.UIString("Device type"));this._uaItem.setGlyph("");this._uaItem.turnIntoSelect();this._uaItem.element.style.padding="0 5px";toolbar.appendToolbarItem(this._uaItem);},_fillModeToolbar:function(toolbar)
{toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));this._modeButton=new WebInspector.ToolbarButton("","rotate-screen-toolbar-item");this._modeButton.addEventListener("click",this._modeMenuClicked,this);toolbar.appendToolbarItem(this._modeButton);},_fillOptionsToolbar:function(toolbar)
{this._networkConditionsItem=WebInspector.NetworkConditionsSelector.createToolbarMenuButton();this._networkConditionsItem.setVisible(this._showNetworkConditionsSetting.get());this._networkConditionsItem.setTitle(WebInspector.UIString("Network throttling"));this._networkConditionsItem.element.style.padding="0 5px";this._networkConditionsItem.element.style.maxWidth="140px";toolbar.appendToolbarItem(this._networkConditionsItem);var moreOptionsButton=new WebInspector.ToolbarMenuButton(this._appendOptionsMenuItems.bind(this));moreOptionsButton.setTitle(WebInspector.UIString("More options"));toolbar.appendToolbarItem(moreOptionsButton);toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass("div","device-mode-empty-toolbar-element")));},_appendScaleMenuItems:function(contextMenu)
{var scaleSetting=this._model.scaleSetting();if(this._model.type()===WebInspector.DeviceModeModel.Type.Device){contextMenu.appendItem(WebInspector.UIString("Fit to window (%.0f%%)",this._model.fitScale()*100),scaleSetting.set.bind(scaleSetting,this._model.fitScale()),false);contextMenu.appendSeparator();}
appendScaleItem(WebInspector.UIString("50%"),0.5);appendScaleItem(WebInspector.UIString("75%"),0.75);appendScaleItem(WebInspector.UIString("100%"),1);appendScaleItem(WebInspector.UIString("125%"),1.25);appendScaleItem(WebInspector.UIString("150%"),1.5);function appendScaleItem(title,value)
{contextMenu.appendCheckboxItem(title,scaleSetting.set.bind(scaleSetting,value),scaleSetting.get()===value,false);}},_appendDeviceScaleMenuItems:function(contextMenu)
{var deviceScaleFactorSetting=this._model.deviceScaleFactorSetting();var defaultValue=this._model.uaSetting().get()===WebInspector.DeviceModeModel.UA.Mobile||this._model.uaSetting().get()===WebInspector.DeviceModeModel.UA.MobileNoTouch?WebInspector.DeviceModeModel.defaultMobileScaleFactor:window.devicePixelRatio;appendDeviceScaleFactorItem(WebInspector.UIString("Default: %.1f",defaultValue),0);contextMenu.appendSeparator();appendDeviceScaleFactorItem(WebInspector.UIString("1"),1);appendDeviceScaleFactorItem(WebInspector.UIString("2"),2);appendDeviceScaleFactorItem(WebInspector.UIString("3"),3);function appendDeviceScaleFactorItem(title,value)
{contextMenu.appendCheckboxItem(title,deviceScaleFactorSetting.set.bind(deviceScaleFactorSetting,value),deviceScaleFactorSetting.get()===value);}},_appendUserAgentMenuItems:function(contextMenu)
{var uaSetting=this._model.uaSetting();appendUAItem(WebInspector.DeviceModeModel.UA.Mobile,WebInspector.DeviceModeModel.UA.Mobile);appendUAItem(WebInspector.DeviceModeModel.UA.MobileNoTouch,WebInspector.DeviceModeModel.UA.MobileNoTouch);appendUAItem(WebInspector.DeviceModeModel.UA.Desktop,WebInspector.DeviceModeModel.UA.Desktop);appendUAItem(WebInspector.DeviceModeModel.UA.DesktopTouch,WebInspector.DeviceModeModel.UA.DesktopTouch);function appendUAItem(title,value)
{contextMenu.appendCheckboxItem(title,uaSetting.set.bind(uaSetting,value),uaSetting.get()===value);}},_appendOptionsMenuItems:function(contextMenu)
{var model=this._model;appendToggleItem(this._deviceOutlineSetting,WebInspector.UIString("Hide device frame"),WebInspector.UIString("Show device frame"),model.type()!==WebInspector.DeviceModeModel.Type.Device);appendToggleItem(this._showMediaInspectorSetting,WebInspector.UIString("Hide media queries"),WebInspector.UIString("Show media queries"));appendToggleItem(this._showRulersSetting,WebInspector.UIString("Hide rulers"),WebInspector.UIString("Show rulers"));contextMenu.appendSeparator();appendToggleItem(this._showDeviceScaleFactorSetting,WebInspector.UIString("Remove device pixel ratio"),WebInspector.UIString("Add device pixel ratio"));appendToggleItem(this._showUserAgentTypeSetting,WebInspector.UIString("Remove device type"),WebInspector.UIString("Add device type"));appendToggleItem(this._showNetworkConditionsSetting,WebInspector.UIString("Remove network throttling"),WebInspector.UIString("Add network throttling"));contextMenu.appendSeparator();contextMenu.appendItemsAtLocation("deviceModeMenu");contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("Reset to defaults"),this._reset.bind(this));function appendToggleItem(setting,title1,title2,disabled)
{if(typeof disabled==="undefined")
disabled=model.type()===WebInspector.DeviceModeModel.Type.None;contextMenu.appendItem(setting.get()?title1:title2,setting.set.bind(setting,!setting.get()),disabled);}},_reset:function()
{this._deviceOutlineSetting.set(false);this._showDeviceScaleFactorSetting.set(false);this._showUserAgentTypeSetting.set(false);this._showMediaInspectorSetting.set(false);this._showRulersSetting.set(false);this._showNetworkConditionsSetting.set(false);this._model.reset();},_wrapToolbarItem:function(element)
{var container=createElement("div");var shadowRoot=WebInspector.createShadowRootWithCoreStyles(container,"emulation/deviceModeToolbar.css");shadowRoot.appendChild(element);return new WebInspector.ToolbarItem(container);},_emulateDevice:function(device)
{this._model.emulate(WebInspector.DeviceModeModel.Type.Device,device,this._lastMode.get(device)||device.modes[0]);},_switchToResponsive:function()
{this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive,null,null);},_filterDevices:function(devices)
{devices=devices.filter(function(d){return d.show();});devices.sort(WebInspector.EmulatedDevice.deviceComparator);return devices;},_standardDevices:function()
{return this._filterDevices(this._emulatedDevicesList.standard());},_customDevices:function()
{return this._filterDevices(this._emulatedDevicesList.custom());},_allDevices:function()
{return this._standardDevices().concat(this._customDevices());},_appendDeviceMenuItems:function(contextMenu)
{contextMenu.appendCheckboxItem(WebInspector.UIString("Responsive"),this._switchToResponsive.bind(this),this._model.type()===WebInspector.DeviceModeModel.Type.Responsive,false);appendGroup.call(this,this._standardDevices());appendGroup.call(this,this._customDevices());contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("Edit\u2026"),this._emulatedDevicesList.revealCustomSetting.bind(this._emulatedDevicesList),false);function appendGroup(devices)
{if(!devices.length)
return;contextMenu.appendSeparator();for(var device of devices)
contextMenu.appendCheckboxItem(device.title,this._emulateDevice.bind(this,device),this._model.device()===device,false);}},_deviceListChanged:function()
{var device=this._model.device();if(!device)
return;var devices=this._allDevices();if(devices.indexOf(device)===-1){if(devices.length)
this._emulateDevice(devices[0]);else
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive,null,null);}},_updateDeviceScaleFactorVisibility:function()
{this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());},_updateUserAgentTypeVisibility:function()
{this._uaItem.setVisible(this._showUserAgentTypeSetting.get());},_updateNetworkConditionsVisibility:function()
{this._networkConditionsItem.setVisible(this._showNetworkConditionsSetting.get());},_modeMenuClicked:function(event)
{var device=this._model.device();var model=this._model;if(device.modes.length===2&&device.modes[0].orientation!==device.modes[1].orientation){model.emulate(model.type(),model.device(),model.mode()===device.modes[0]?device.modes[1]:device.modes[0]);return;}
var contextMenu=new WebInspector.ContextMenu((event.data),false,event.target.element.totalOffsetLeft(),event.target.element.totalOffsetTop()+event.target.element.offsetHeight);addOrientation(WebInspector.EmulatedDevice.Vertical,WebInspector.UIString("Portrait"));addOrientation(WebInspector.EmulatedDevice.Horizontal,WebInspector.UIString("Landscape"));contextMenu.show();function addOrientation(orientation,title)
{var modes=device.modesForOrientation(orientation);if(!modes.length)
return;if(modes.length===1){addMode(modes[0],title);}else{for(var index=0;index<modes.length;index++)
addMode(modes[index],title+" \u2013 "+modes[index].title);}}
function addMode(mode,title)
{contextMenu.appendCheckboxItem(title,applyMode.bind(null,mode),model.mode()===mode,false);}
function applyMode(mode)
{model.emulate(model.type(),model.device(),mode);}},element:function()
{return this._element;},update:function()
{if(this._model.type()!==this._cachedModelType){this._cachedModelType=this._model.type();this._widthInput.disabled=this._model.type()!==WebInspector.DeviceModeModel.Type.Responsive;this._heightInput.disabled=this._model.type()!==WebInspector.DeviceModeModel.Type.Responsive;this._deviceScaleItem.setEnabled(this._model.type()===WebInspector.DeviceModeModel.Type.Responsive);this._uaItem.setEnabled(this._model.type()===WebInspector.DeviceModeModel.Type.Responsive);}
var size=this._model.appliedDeviceSize();this._updateHeightInput(this._model.type()===WebInspector.DeviceModeModel.Type.Responsive&&this._model.isFullHeight()?"":String(size.height));this._updateWidthInput(String(size.width));this._heightInput.placeholder=size.height;if(this._model.scale()!==this._cachedScale){this._scaleItem.setText(WebInspector.UIString("%.0f%%",this._model.scale()*100));this._cachedScale=this._model.scale();}
var deviceScale=this._model.appliedDeviceScaleFactor();if(deviceScale!==this._cachedDeviceScale){this._deviceScaleItem.setText(WebInspector.UIString("DPR: %.1f",deviceScale));this._cachedDeviceScale=deviceScale;}
var uaType=this._model.appliedUserAgentType();if(uaType!==this._cachedUaType){this._uaItem.setText(uaType);this._cachedUaType=uaType;}
var deviceItemTitle=WebInspector.UIString("None");if(this._model.type()===WebInspector.DeviceModeModel.Type.Responsive)
deviceItemTitle=WebInspector.UIString("Responsive");if(this._model.type()===WebInspector.DeviceModeModel.Type.Device)
deviceItemTitle=this._model.device().title;this._deviceSelectItem.setText(deviceItemTitle);if(this._model.device()!==this._cachedModelDevice){var device=this._model.device();this._modeButton.setVisible(!!device);if(device){var modeCount=device?device.modes.length:0;this._modeButton.setEnabled(modeCount>=2);this._modeButton.setTitle(modeCount===2?WebInspector.UIString("Rotate"):WebInspector.UIString("Screen options"));}
this._cachedModelDevice=device;}
if(this._model.type()===WebInspector.DeviceModeModel.Type.Device)
this._lastMode.set((this._model.device()),(this._model.mode()));if(this._model.mode()!==this._cachedModelMode&&this._model.type()!==WebInspector.DeviceModeModel.Type.None){this._cachedModelMode=this._model.mode();var value=this._persistenceSetting.get();if(this._model.device()){value.device=this._model.device().title;value.orientation=this._model.mode()?this._model.mode().orientation:"";value.mode=this._model.mode()?this._model.mode().title:"";}else{value.device="";value.orientation="";value.mode="";}
this._persistenceSetting.set(value);}},restore:function()
{for(var device of this._allDevices()){if(device.title===this._persistenceSetting.get().device){for(var mode of device.modes){if(mode.orientation===this._persistenceSetting.get().orientation&&mode.title===this._persistenceSetting.get().mode){this._lastMode.set(device,mode);this._emulateDevice(device);return;}}}}
this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive,null,null);}};WebInspector.DeviceModeView=function()
{WebInspector.VBox.call(this,true);this.setMinimumSize(150,150);this.element.classList.add("device-mode-view");this.registerRequiredCSS("emulation/deviceModeView.css");WebInspector.Tooltip.addNativeOverrideContainer(this.contentElement);this._model=new WebInspector.DeviceModeModel(this._updateUI.bind(this));this._mediaInspector=new WebInspector.MediaQueryInspector(()=>this._model.appliedDeviceSize().width,this._model.setWidth.bind(this._model));this._showMediaInspectorSetting=WebInspector.settings.moduleSetting("showMediaQueryInspector");this._showMediaInspectorSetting.addChangeListener(this._updateUI,this);this._showRulersSetting=WebInspector.settings.moduleSetting("emulation.showRulers");this._showRulersSetting.addChangeListener(this._updateUI,this);this._topRuler=new WebInspector.DeviceModeView.Ruler(true,this._model.setWidthAndScaleToFit.bind(this._model));this._topRuler.element.classList.add("device-mode-ruler-top");this._leftRuler=new WebInspector.DeviceModeView.Ruler(false,this._model.setHeightAndScaleToFit.bind(this._model));this._leftRuler.element.classList.add("device-mode-ruler-left");this._createUI();WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged,this._zoomChanged,this);};WebInspector.DeviceModeView.prototype={_createUI:function()
{this._toolbar=new WebInspector.DeviceModeToolbar(this._model,this._showMediaInspectorSetting,this._showRulersSetting);this.contentElement.appendChild(this._toolbar.element());this._contentClip=this.contentElement.createChild("div","device-mode-content-clip vbox");this._responsivePresetsContainer=this._contentClip.createChild("div","device-mode-presets-container");this._populatePresetsContainer();this._mediaInspectorContainer=this._contentClip.createChild("div","device-mode-media-container");this._contentArea=this._contentClip.createChild("div","device-mode-content-area");this._outlineImage=this._contentArea.createChild("img","device-mode-outline-image hidden fill");this._outlineImage.addEventListener("load",this._onImageLoaded.bind(this,this._outlineImage,true),false);this._outlineImage.addEventListener("error",this._onImageLoaded.bind(this,this._outlineImage,false),false);this._screenArea=this._contentArea.createChild("div","device-mode-screen-area");this._screenImage=this._screenArea.createChild("img","device-mode-screen-image hidden");this._screenImage.addEventListener("load",this._onImageLoaded.bind(this,this._screenImage,true),false);this._screenImage.addEventListener("error",this._onImageLoaded.bind(this,this._screenImage,false),false);this._bottomRightResizerElement=this._screenArea.createChild("div","device-mode-resizer device-mode-bottom-right-resizer");this._bottomRightResizerElement.createChild("div","");this._createResizer(this._bottomRightResizerElement,2,1);this._bottomLeftResizerElement=this._screenArea.createChild("div","device-mode-resizer device-mode-bottom-left-resizer");this._bottomLeftResizerElement.createChild("div","");this._createResizer(this._bottomLeftResizerElement,-2,1);this._rightResizerElement=this._screenArea.createChild("div","device-mode-resizer device-mode-right-resizer");this._rightResizerElement.createChild("div","");this._createResizer(this._rightResizerElement,2,0);this._leftResizerElement=this._screenArea.createChild("div","device-mode-resizer device-mode-left-resizer");this._leftResizerElement.createChild("div","");this._createResizer(this._leftResizerElement,-2,0);this._bottomResizerElement=this._screenArea.createChild("div","device-mode-resizer device-mode-bottom-resizer");this._bottomResizerElement.createChild("div","");this._createResizer(this._bottomResizerElement,0,1);this._bottomResizerElement.addEventListener("dblclick",this._model.setHeight.bind(this._model,0),false);this._bottomResizerElement.title=WebInspector.UIString("Double-click for full height");this._pageArea=this._screenArea.createChild("div","device-mode-page-area");this._pageArea.createChild("content");},_populatePresetsContainer:function()
{var sizes=[320,375,425,768,1024,1440,2560];var titles=[WebInspector.UIString("Mobile S"),WebInspector.UIString("Mobile M"),WebInspector.UIString("Mobile L"),WebInspector.UIString("Tablet"),WebInspector.UIString("Laptop"),WebInspector.UIString("Laptop L"),WebInspector.UIString("4K")];this._presetBlocks=[];var inner=this._responsivePresetsContainer.createChild("div","device-mode-presets-container-inner");for(var i=sizes.length-1;i>=0;--i){var outer=inner.createChild("div","fill device-mode-preset-bar-outer");var block=outer.createChild("div","device-mode-preset-bar");block.createChild("span").textContent=titles[i]+" \u2013 "+sizes[i]+"px";block.addEventListener("click",applySize.bind(this,sizes[i]),false);block.__width=sizes[i];this._presetBlocks.push(block);}
function applySize(width,e)
{this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive,null,null);this._model.setSizeAndScaleToFit(width,0);e.consume();}},_createResizer:function(element,widthFactor,heightFactor)
{var resizer=new WebInspector.ResizerWidget();resizer.addElement(element);var cursor=widthFactor?"ew-resize":"ns-resize";if(widthFactor*heightFactor>0)
cursor="nwse-resize";if(widthFactor*heightFactor<0)
cursor="nesw-resize";resizer.setCursor(cursor);resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart,this._onResizeStart,this);resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate,this._onResizeUpdate.bind(this,widthFactor,heightFactor));resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd,this._onResizeEnd,this);return resizer;},_onResizeStart:function(event)
{this._slowPositionStart=null;this._resizeStart=this._model.screenRect().size();},_onResizeUpdate:function(widthFactor,heightFactor,event)
{if(event.data.shiftKey!==!!this._slowPositionStart)
this._slowPositionStart=event.data.shiftKey?{x:event.data.currentX,y:event.data.currentY}:null;var cssOffsetX=event.data.currentX-event.data.startX;var cssOffsetY=event.data.currentY-event.data.startY;if(this._slowPositionStart){cssOffsetX=(event.data.currentX-this._slowPositionStart.x)/10+this._slowPositionStart.x-event.data.startX;cssOffsetY=(event.data.currentY-this._slowPositionStart.y)/10+this._slowPositionStart.y-event.data.startY;}
if(widthFactor){var dipOffsetX=cssOffsetX*WebInspector.zoomManager.zoomFactor();var newWidth=this._resizeStart.width+dipOffsetX*widthFactor;newWidth=Math.round(newWidth/this._model.scale());if(newWidth>=WebInspector.DeviceModeModel.MinDeviceSize&&newWidth<=WebInspector.DeviceModeModel.MaxDeviceSize)
this._model.setWidth(newWidth);}
if(heightFactor){var dipOffsetY=cssOffsetY*WebInspector.zoomManager.zoomFactor();var newHeight=this._resizeStart.height+dipOffsetY*heightFactor;newHeight=Math.round(newHeight/this._model.scale());if(newHeight>=WebInspector.DeviceModeModel.MinDeviceSize&&newHeight<=WebInspector.DeviceModeModel.MaxDeviceSize)
this._model.setHeight(newHeight);}},_onResizeEnd:function(event)
{delete this._resizeStart;WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ResizedViewInResponsiveMode);},_updateUI:function()
{function applyRect(element,rect)
{element.style.left=rect.left+"px";element.style.top=rect.top+"px";element.style.width=rect.width+"px";element.style.height=rect.height+"px";}
if(!this.isShowing())
return;var zoomFactor=WebInspector.zoomManager.zoomFactor();var callDoResize=false;var showRulers=this._showRulersSetting.get()&&this._model.type()!==WebInspector.DeviceModeModel.Type.None;var contentAreaResized=false;var updateRulers=false;var cssScreenRect=this._model.screenRect().scale(1/zoomFactor);if(!cssScreenRect.isEqual(this._cachedCssScreenRect)){applyRect(this._screenArea,cssScreenRect);updateRulers=true;callDoResize=true;this._cachedCssScreenRect=cssScreenRect;}
var cssVisiblePageRect=this._model.visiblePageRect().scale(1/zoomFactor);if(!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)){applyRect(this._pageArea,cssVisiblePageRect);callDoResize=true;this._cachedCssVisiblePageRect=cssVisiblePageRect;}
var outlineRect=this._model.outlineRect().scale(1/zoomFactor);if(!outlineRect.isEqual(this._cachedOutlineRect)){applyRect(this._outlineImage,outlineRect);callDoResize=true;this._cachedOutlineRect=outlineRect;}
this._contentClip.classList.toggle("device-mode-outline-visible",!!this._model.outlineImage());var resizable=this._model.type()===WebInspector.DeviceModeModel.Type.Responsive;if(resizable!==this._cachedResizable){this._rightResizerElement.classList.toggle("hidden",!resizable);this._leftResizerElement.classList.toggle("hidden",!resizable);this._bottomResizerElement.classList.toggle("hidden",!resizable);this._bottomRightResizerElement.classList.toggle("hidden",!resizable);this._bottomLeftResizerElement.classList.toggle("hidden",!resizable);this._cachedResizable=resizable;}
var mediaInspectorVisible=this._showMediaInspectorSetting.get()&&this._model.type()!==WebInspector.DeviceModeModel.Type.None;if(mediaInspectorVisible!==this._cachedMediaInspectorVisible){if(mediaInspectorVisible)
this._mediaInspector.show(this._mediaInspectorContainer);else
this._mediaInspector.detach();contentAreaResized=true;callDoResize=true;this._cachedMediaInspectorVisible=mediaInspectorVisible;}
if(showRulers!==this._cachedShowRulers){this._contentClip.classList.toggle("device-mode-rulers-visible",showRulers);if(showRulers){this._topRuler.show(this._contentArea);this._leftRuler.show(this._contentArea);}else{this._topRuler.detach();this._leftRuler.detach();}
contentAreaResized=true;callDoResize=true;this._cachedShowRulers=showRulers;}
if(this._model.scale()!==this._cachedScale){updateRulers=true;callDoResize=true;for(var block of this._presetBlocks)
block.style.width=block.__width*this._model.scale()+"px";this._cachedScale=this._model.scale();}
this._toolbar.update();this._loadImage(this._screenImage,this._model.screenImage());this._loadImage(this._outlineImage,this._model.outlineImage());this._mediaInspector.setAxisTransform(this._model.scale());if(callDoResize)
this.doResize();if(updateRulers){this._topRuler.render(this._model.scale());this._leftRuler.render(this._model.scale());this._topRuler.element.positionAt(this._cachedCssScreenRect?this._cachedCssScreenRect.left:0,this._cachedCssScreenRect?this._cachedCssScreenRect.top:0);this._leftRuler.element.positionAt(this._cachedCssScreenRect?this._cachedCssScreenRect.left:0,this._cachedCssScreenRect?this._cachedCssScreenRect.top:0);}
if(contentAreaResized)
this._contentAreaResized();},_loadImage:function(element,srcset)
{if(element.getAttribute("srcset")===srcset)
return;element.setAttribute("srcset",srcset);if(!srcset)
element.classList.toggle("hidden",true);},_onImageLoaded:function(element,success)
{element.classList.toggle("hidden",!success);},_contentAreaResized:function()
{var zoomFactor=WebInspector.zoomManager.zoomFactor();var rect=this._contentArea.getBoundingClientRect();var availableSize=new Size(Math.max(rect.width*zoomFactor,1),Math.max(rect.height*zoomFactor,1));var preferredSize=new Size(Math.max((rect.width-2*this._handleWidth)*zoomFactor,1),Math.max((rect.height-this._handleHeight)*zoomFactor,1));this._model.setAvailableSize(availableSize,preferredSize);},_measureHandles:function()
{var hidden=this._rightResizerElement.classList.contains("hidden");this._rightResizerElement.classList.toggle("hidden",false);this._bottomResizerElement.classList.toggle("hidden",false);this._handleWidth=this._rightResizerElement.offsetWidth;this._handleHeight=this._bottomResizerElement.offsetHeight;this._rightResizerElement.classList.toggle("hidden",hidden);this._bottomResizerElement.classList.toggle("hidden",hidden);},_zoomChanged:function()
{delete this._handleWidth;delete this._handleHeight;if(this.isShowing()){this._measureHandles();this._contentAreaResized();}},onResize:function()
{if(this.isShowing())
this._contentAreaResized();},wasShown:function()
{this._measureHandles();this._toolbar.restore();},willHide:function()
{this._model.emulate(WebInspector.DeviceModeModel.Type.None,null,null);},captureScreenshot:function()
{var mainTarget=WebInspector.targetManager.mainTarget();if(!mainTarget)
return;WebInspector.DOMModel.muteHighlight();var zoomFactor=WebInspector.zoomManager.zoomFactor();var rect=this._contentArea.getBoundingClientRect();var availableSize=new Size(Math.max(rect.width*zoomFactor,1),Math.max(rect.height*zoomFactor,1));var outlineVisible=this._model.deviceOutlineSetting().get();if(availableSize.width<this._model.screenRect().width||availableSize.height<this._model.screenRect().height){WebInspector.inspectorView.minimize();this._model.deviceOutlineSetting().set(false);}
mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this));function screenshotCaptured(error,content)
{this._model.deviceOutlineSetting().set(outlineVisible);var dpr=window.devicePixelRatio;var outlineRect=this._model.outlineRect().scale(dpr);var screenRect=this._model.screenRect().scale(dpr);screenRect.left-=outlineRect.left;screenRect.top-=outlineRect.top;var visiblePageRect=this._model.visiblePageRect().scale(dpr);visiblePageRect.left+=screenRect.left;visiblePageRect.top+=screenRect.top;outlineRect.left=0;outlineRect.top=0;WebInspector.DOMModel.unmuteHighlight();WebInspector.inspectorView.restore();if(error){console.error(error);return;}
var canvas=createElement("canvas");var ctx=canvas.getContext("2d");canvas.width=outlineRect.width;canvas.height=outlineRect.height;var promise=Promise.resolve();if(this._model.outlineImage())
promise=promise.then(paintImage.bind(null,this._model.outlineImage(),outlineRect));promise=promise.then(drawBorder);if(this._model.screenImage())
promise=promise.then(paintImage.bind(null,this._model.screenImage(),screenRect));promise.then(paintScreenshot.bind(this));function paintImage(src,rect)
{var callback;var promise=new Promise(fulfill=>callback=fulfill);var image=new Image();image.crossOrigin="Anonymous";image.srcset=src;image.onload=onImageLoad;image.onerror=callback;return promise;function onImageLoad()
{ctx.drawImage(image,rect.left,rect.top,rect.width,rect.height);callback();}}
function drawBorder()
{ctx.strokeStyle="hsla(0, 0%, 98%, 0.5)";ctx.lineWidth=1;ctx.setLineDash([10,10]);ctx.strokeRect(screenRect.left+1,screenRect.top+1,screenRect.width-2,screenRect.height-2);}
function paintScreenshot()
{var pageImage=new Image();pageImage.src="data:image/png;base64,"+content;ctx.drawImage(pageImage,visiblePageRect.left,visiblePageRect.top,Math.min(pageImage.naturalWidth,screenRect.width),Math.min(pageImage.naturalHeight,screenRect.height));var mainFrame=mainTarget.resourceTreeModel.mainFrame;var fileName=mainFrame?mainFrame.url.trimURL().removeURLFragment():"";if(this._model.type()===WebInspector.DeviceModeModel.Type.Device)
fileName+=WebInspector.UIString("(%s)",this._model.device().title);var link=createElement("a");link.download=fileName+".png";link.href=canvas.toDataURL("image/png");link.click();}}},__proto__:WebInspector.VBox.prototype}
WebInspector.DeviceModeView.Ruler=function(horizontal,applyCallback)
{WebInspector.VBox.call(this);this.element.classList.add("device-mode-ruler");this._contentElement=this.element.createChild("div","device-mode-ruler-content").createChild("div","device-mode-ruler-inner");this._horizontal=horizontal;this._scale=1;this._count=0;this._throttler=new WebInspector.Throttler(0);this._applyCallback=applyCallback;}
WebInspector.DeviceModeView.Ruler.prototype={render:function(scale)
{this._scale=scale;this._throttler.schedule(this._update.bind(this));},onResize:function()
{this._throttler.schedule(this._update.bind(this));},_update:function()
{var zoomFactor=WebInspector.zoomManager.zoomFactor();var size=this._horizontal?this._contentElement.offsetWidth:this._contentElement.offsetHeight;if(this._scale!==this._renderedScale||zoomFactor!==this._renderedZoomFactor){this._contentElement.removeChildren();this._count=0;this._renderedScale=this._scale;this._renderedZoomFactor=zoomFactor;}
var dipSize=size*zoomFactor/this._scale;var count=Math.ceil(dipSize/5);var step=1;if(this._scale<0.8)
step=2;if(this._scale<0.6)
step=4;if(this._scale<0.4)
step=8;for(var i=count;i<this._count;i++){if(!(i%step))
this._contentElement.lastChild.remove();}
for(var i=this._count;i<count;i++){if(i%step)
continue;var marker=this._contentElement.createChild("div","device-mode-ruler-marker");if(i){if(this._horizontal)
marker.style.left=(5*i)*this._scale/zoomFactor+"px";else
marker.style.top=(5*i)*this._scale/zoomFactor+"px";if(!(i%20)){var text=marker.createChild("div","device-mode-ruler-text");text.textContent=i*5;text.addEventListener("click",this._onMarkerClick.bind(this,i*5),false);}}
if(!(i%10))
marker.classList.add("device-mode-ruler-marker-large");else if(!(i%5))
marker.classList.add("device-mode-ruler-marker-medium");}
this._count=count;return Promise.resolve();},_onMarkerClick:function(size)
{this._applyCallback.call(null,size);},__proto__:WebInspector.VBox.prototype};WebInspector.DeviceModeWrapper=function(inspectedPagePlaceholder)
{WebInspector.VBox.call(this);WebInspector.DeviceModeView._wrapperInstance=this;this._inspectedPagePlaceholder=inspectedPagePlaceholder;this._deviceModeView=null;this._toggleDeviceModeAction=WebInspector.actionRegistry.action("emulation.toggle-device-mode");this._showDeviceModeSetting=WebInspector.settings.createSetting("emulation.showDeviceMode",false);this._showDeviceModeSetting.addChangeListener(this._update.bind(this,false));this._update(true);}
WebInspector.DeviceModeView._wrapperInstance;WebInspector.DeviceModeWrapper.prototype={_toggleDeviceMode:function()
{this._showDeviceModeSetting.set(!this._showDeviceModeSetting.get());},_captureScreenshot:function()
{if(!this._deviceModeView)
return false;this._deviceModeView.captureScreenshot();return true;},_update:function(force)
{this._toggleDeviceModeAction.setToggled(this._showDeviceModeSetting.get());if(!force){var showing=this._deviceModeView&&this._deviceModeView.isShowing();if(this._showDeviceModeSetting.get()===showing)
return;}
if(this._showDeviceModeSetting.get()){if(!this._deviceModeView)
this._deviceModeView=new WebInspector.DeviceModeView();this._deviceModeView.show(this.element);this._inspectedPagePlaceholder.clearMinimumSizeAndMargins();this._inspectedPagePlaceholder.show(this._deviceModeView.element);}else{if(this._deviceModeView)
this._deviceModeView.detach();this._inspectedPagePlaceholder.restoreMinimumSizeAndMargins();this._inspectedPagePlaceholder.show(this.element);}},__proto__:WebInspector.VBox.prototype}
WebInspector.DeviceModeWrapper.ActionDelegate=function()
{}
WebInspector.DeviceModeWrapper.ActionDelegate.prototype={handleAction:function(context,actionId)
{if(WebInspector.DeviceModeView._wrapperInstance){if(actionId==="emulation.toggle-device-mode"){WebInspector.DeviceModeView._wrapperInstance._toggleDeviceMode();return true;}
if(actionId==="emulation.capture-screenshot")
return WebInspector.DeviceModeView._wrapperInstance._captureScreenshot();}
return false;}};applicationDescriptor={"has_html":true,"modules":[{"name":"ui_lazy"},{"name":"accessibility","condition":"!v8only"},{"name":"sources"},{"name":"devices","condition":"!v8only"},{"name":"diff"},{"name":"audits","condition":"!v8only"},{"type":"autostart","name":"bindings"},{"name":"snippets"},{"name":"layers","condition":"!v8only"},{"name":"console"},{"name":"network","condition":"!v8only"},{"type":"remote","name":"cm_modes"},{"type":"autostart","name":"platform"},{"name":"animation","condition":"!v8only"},{"name":"source_frame"},{"type":"autostart","name":"main"},{"name":"resources","condition":"!v8only"},{"name":"elements","condition":"!v8only"},{"type":"autostart","name":"workspace"},{"name":"timeline","condition":"!v8only"},{"type":"autostart","name":"host"},{"type":"autostart","name":"emulation"},{"type":"autostart","name":"ui"},{"type":"autostart","name":"sdk"},{"name":"es_tree"},{"name":"sass","condition":"!v8only"},{"name":"settings"},{"name":"components_lazy"},{"name":"profiler"},{"type":"remote","name":"screencast","condition":"remoteFrontend"},{"type":"autostart","name":"extensions"},{"type":"autostart","name":"common"},{"type":"autostart","name":"components"},{"name":"security","condition":"!v8only"},{"type":"remote","name":"emulated_devices","condition":"!v8only"}]};Runtime.cachedResources["ui/checkboxTextLabel.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n padding: 0;\n margin: 0;\n display: inline-flex;\n flex-shrink: 0;\n align-items: center !important;\n}\n\ninput {\n height: 12px;\n width: 12px;\n flex-shrink: 0;\n}\n\ninput.dt-checkbox-themed {\n -webkit-appearance: none;\n margin: 0 5px auto 2px;\n border: 1px solid rgb(45, 45, 45);\n border-radius: 3px;\n background-color: rgb(102, 102, 102);\n position: relative;\n top: 1px;\n}\n\ninput.dt-checkbox-themed:after {\n content: '';\n line-height: 10px;\n position: absolute;\n cursor: pointer;\n width: 12px;\n height: 12px;\n background: none;\n}\n\ninput.dt-checkbox-themed:checked:after {\n background-color: #333;\n}\n\ninput.dt-checkbox-themed:after {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n -webkit-mask-position: -128px -110px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\ninput.dt-checkbox-themed:after {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n\n} /* media */\n\n::content .dt-checkbox-text {\n margin-left: 3px;\n}\n\n::content .dt-checkbox-subtitle {\n color: gray;\n}\n\n/*# sourceURL=ui/checkboxTextLabel.css */";Runtime.cachedResources["ui/closeButton.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\ndiv {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\ndiv {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.close-button {\n width: 14px;\n height: 14px;\n background-position: -128px -96px;\n cursor: default;\n}\n\n.close-button:hover {\n background-position: -96px -96px;\n}\n\n.close-button:active {\n background-position: -111px -96px;\n}\n\n.close-button-gray {\n width: 13px;\n height: 13px;\n background-position: -175px -96px;\n}\n\n.close-button-gray:hover {\n background-position: -143px -96px;\n}\n\n.close-button-gray:active {\n background-position: -160px -96px;\n}\n\n/*# sourceURL=ui/closeButton.css */";Runtime.cachedResources["ui/colorSwatch.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n white-space: nowrap;\n}\n\n.color-swatch {\n position: relative;\n margin-left: 1px;\n margin-right: 2px;\n width: 10px;\n height: 10px;\n top: 1px;\n display: inline-block;\n -webkit-user-select: none;\n background-image: url(Images/checker.png);\n line-height: 10px;\n}\n\n.color-swatch-inner {\n width: 100%;\n height: 100%;\n display: inline-block;\n border: 1px solid rgba(128, 128, 128, 0.6);\n}\n\n.color-swatch-inner:hover {\n border: 1px solid rgba(64, 64, 64, 0.8);\n}\n\n\n/*# sourceURL=ui/colorSwatch.css */";Runtime.cachedResources["ui/dialog.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n position: absolute;\n border: 1px solid rgb(204, 204, 204);\n box-shadow: rgb(140, 140, 140) 0 3px 14px;\n background: white;\n justify-content: flex-start;\n align-items: stretch;\n}\n\n.widget {\n display: flex;\n flex: auto;\n justify-content: flex-start;\n align-items: stretch;\n}\n\n:host-context(.wraps-content) {\n justify-content: center;\n align-items: flex-start;\n overflow: hidden;\n}\n\n:host-context(.wraps-content) .widget {\n flex: none !important;\n justify-content: center;\n align-items: center;\n}\n\n.dialog-close-button {\n position: absolute;\n right: 9px;\n top: 9px;\n}\n/*# sourceURL=ui/dialog.css */";Runtime.cachedResources["ui/dropTarget.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n display: flex;\n background-color: rgba(255,255,255,0.8);\n z-index: 1000;\n}\n\n.drop-target-message {\n flex: auto;\n font-size: 30px;\n color: #999;\n display: flex;\n justify-content: center;\n align-items: center;\n margin: 20px;\n border: 4px dashed #ddd;\n pointer-events: none;\n}\n\n/*# sourceURL=ui/dropTarget.css */";Runtime.cachedResources["ui/emptyWidget.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.empty-view {\n font-size: 24px;\n color: rgb(75%, 75%, 75%);\n font-weight: bold;\n padding: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: auto;\n}\n\n/*# sourceURL=ui/emptyWidget.css */";Runtime.cachedResources["ui/filter.css"]="/*\n * Copyright (C) 2013 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.filter-bar {\n background-color: #f3f3f3;\n padding: 4px 0 4px 0;\n flex: none;\n flex-wrap: wrap;\n align-items: center;\n border-bottom: 1px solid #dadada;\n}\n\n.filter-text-filter {\n display: inline-flex;\n margin-left: 1px;\n margin-right: 2px;\n min-width: 40px;\n max-width: 200px;\n height: 24px;\n align-items: center;\n}\n\n.filter-text-filter label {\n margin: auto 0;\n}\n\n.filter-bitset-filter {\n padding: 2px;\n display: inline-flex;\n overflow: hidden;\n height: 24px;\n position: relative;\n}\n\n.filter-bitset-filter li {\n display: inline-block;\n flex: none;\n margin: auto 2px;\n padding: 3px 6px 3px 3px;\n background: transparent;\n text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.filter-bitset-filter-divider {\n background-color: #ccc;\n height: 16px;\n width: 1px;\n margin: auto 2px;\n display: inline-block;\n}\n\n.filter-bitset-filter li.selected,\n.filter-bitset-filter li:hover,\n.filter-bitset-filter li:active {\n color: white;\n text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;\n}\n\n.filter-bitset-filter li:hover {\n background: rgba(0, 0, 0, 0.2);\n}\n\n.filter-bitset-filter li.selected {\n background: rgba(0, 0, 0, 0.3);\n}\n\n.filter-bitset-filter li:active {\n background: rgba(0, 0, 0, 0.5);\n}\n\n.filter-combobox-filter {\n margin-left: 5px;\n margin-right: 2px;\n flex: 0 0 auto;\n display: inline-block;\n}\n\n.filter-checkbox-filter {\n padding-left: 4px;\n padding-right: 2px;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n display: inline-flex;\n vertical-align: middle;\n height: 24px;\n position: relative;\n}\n\n.filter-checkbox-filter > label {\n display: flex;\n margin: auto 0;\n}\n\n.filter-text-invalid {\n background-color: rgb(255, 200, 200);\n}\n\n.filter-checkbox-filter .checkbox-filter-checkbox {\n width: 10px;\n height: 10px;\n margin: auto 3px;\n padding: 0;\n border-radius: 2px;\n border: solid 1px;\n display: inline-block;\n overflow: visible;\n opacity: 0.8;\n flex-shrink: 0;\n}\n\n.filter-input-field {\n -webkit-appearance: none;\n border: 1px solid rgb(163, 163, 163);\n border-radius: 2px;\n padding: 1px 3px 0;\n margin: 0 0 0 1px;\n width: 253px;\n height: 20px;\n line-height: 17px;\n flex: 1;\n}\n\n/*# sourceURL=ui/filter.css */";Runtime.cachedResources["ui/infobar.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.infobar {\n color: rgb(34, 34, 34);\n display: flex;\n flex: auto;\n border-bottom: 1px solid rgb(171, 171, 171);\n flex-direction: column;\n align-items: stretch;\n position: relative;\n}\n\n.infobar-warning {\n background-color: rgb(253, 242, 192);\n}\n\n.infobar-info {\n background-color: rgb(255, 255, 255);\n}\n\n.infobar-main-row {\n display: flex;\n flex-direction: row;\n flex: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n justify-content: space-between;\n margin-right: 20px;\n min-height: 25px;\n align-items: center;\n padding-left: 4px;\n}\n\n.infobar-main-row > * {\n flex: none;\n padding: 0 3px;\n}\n\n.infobar-main-title {\n flex: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.infobar-details-rows {\n padding: 5px 5px 0 5px;\n}\n\n.infobar-details-row {\n display: flex;\n flex-direction: column;\n line-height: 18px;\n padding-bottom: 6px;\n}\n\n.close-button {\n position: absolute;\n top: 5px;\n right: 6px;\n}\n\n.infobar-toggle {\n color: hsl(214, 92%, 50%);\n cursor: pointer;\n}\n\n.infobar-toggle:hover {\n color: hsl(214, 92%, 30%);\n}\n\n.info-icon {\n -webkit-mask-image: url(Images/ic_info_black_18dp.svg);\n background-color: hsl(214, 92%, 50%);\n}\n\n.warning-icon {\n -webkit-mask-image: url(Images/ic_warning_black_18dp.svg);\n background-color: hsl(44, 92%, 50%);\n}\n\n.icon {\n -webkit-mask-size: 18px 18px;\n width: 18px;\n height: 19px;\n}\n\n/*# sourceURL=ui/infobar.css */";Runtime.cachedResources["ui/inspectorCommon.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n* {\n /* This is required for correct sizing of flex items because we rely\n * on an old version of the flexbox spec.\n * Longer-term we should remove this, see crbug.com/473625 */\n min-width: 0;\n min-height: 0;\n}\n\n:host-context(.platform-mac) .monospace,\n:host-context(.platform-mac) .source-code,\n.platform-mac .monospace,\n.platform-mac .source-code {\n font-size: 11px !important;\n font-family: Menlo, monospace;\n}\n\n:host-context(.platform-windows) .monospace,\n:host-context(.platform-windows) .source-code,\n.platform-windows .monospace,\n.platform-windows .source-code {\n font-size: 12px !important;\n font-family: Consolas, Lucida Console, monospace;\n}\n\n:host-context(.platform-linux) .monospace,\n:host-context(.platform-linux) .source-code,\n.platform-linux .monospace,\n.platform-linux .source-code {\n font-size: 11px !important;\n font-family: dejavu sans mono, monospace;\n}\n\n.source-code {\n font-family: monospace;\n font-size: 11px !important;\n white-space: pre-wrap;\n}\n\n* {\n box-sizing: border-box;\n}\n\n:focus {\n outline: none;\n}\n\nimg {\n -webkit-user-drag: none;\n}\n\niframe,\na img {\n border: none;\n}\n\n.fill {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\niframe.fill {\n width: 100%;\n height: 100%;\n}\n\n.widget {\n position: relative;\n flex: auto;\n}\n\n.hbox {\n display: flex;\n flex-direction: row !important;\n position: relative;\n}\n\n.vbox {\n display: flex;\n flex-direction: column !important;\n position: relative;\n}\n\n.flex-auto {\n flex: auto;\n}\n\n.flex-auto-important {\n flex: auto !important;\n}\n\n.flex-none {\n flex: none;\n}\n\n.flex-centered {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\niframe.widget {\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n}\n\n.hidden {\n display: none !important;\n}\n\n.monospace {\n font-size: 10px !important;\n font-family: monospace;\n}\n\n.highlighted-search-result {\n border-radius: 1px;\n padding: 1px;\n margin: -1px;\n background-color: rgba(255, 255, 0, 0.8);\n}\n\n.-theme-with-dark-background .highlighted-search-result,\n:host-context(.-theme-with-dark-background) .highlighted-search-result {\n background-color: hsl(133, 100%, 30%);\n color: #333;\n}\n\n.link {\n cursor: pointer;\n text-decoration: underline;\n color: rgb(17, 85, 204);\n}\n\nbutton,\ninput,\nselect {\n font-family: inherit;\n font-size: inherit;\n color: inherit;\n}\n\ninput {\n background-color: white;\n}\n\n:host-context(.-theme-with-dark-background) input[type=\"checkbox\"] {\n -webkit-filter: invert(80%);\n}\n\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus {\n outline: auto rgb(56, 121, 217);\n}\n\n\n.highlighted-search-result.current-search-result {\n border-radius: 1px;\n padding: 1px;\n margin: -1px;\n background-color: rgba(255, 127, 0, 0.8);\n}\n\n.dimmed {\n opacity: 0.6;\n}\n\n.editing {\n -webkit-user-select: text;\n box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;\n outline: 1px solid rgb(66%, 66%, 66%) !important;\n background-color: white;\n -webkit-user-modify: read-write-plaintext-only;\n text-overflow: clip !important;\n padding-left: 2px;\n margin-left: -2px;\n padding-right: 2px;\n margin-right: -2px;\n margin-bottom: -1px;\n padding-bottom: 1px;\n opacity: 1.0 !important;\n}\n\n.editing,\n.editing * {\n color: #222 !important;\n text-decoration: none !important;\n}\n\n.error-input {\n outline: auto 2px red !important;\n}\n\n.chrome-select {\n -webkit-appearance: none;\n -webkit-user-select: none;\n border: 1px solid rgb(160, 160, 160);\n border-radius: 2px;\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),\n inset 0 1px 2px rgba(255, 255, 255, 0.75);\n color: #444;\n font: inherit;\n margin: 0 1px 0 0;\n outline: none;\n text-shadow: 0 1px 0 rgb(240, 240, 240);\n padding-right: 20px;\n padding-left: 6px;\n background-image: -webkit-image-set(url(Images/chromeSelect.png) 1x, url(Images/chromeSelect_2x.png) 2x), linear-gradient(#ededed, #ededed 38%, #dedede);\n background-position: right center;\n background-repeat: no-repeat;\n min-height: 24px;\n}\n\n.chrome-select:enabled:hover {\n background-image: -webkit-image-set(url(Images/chromeSelect.png) 1x, url(Images/chromeSelect_2x.png) 2x), linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);\n border-color: rgba(0, 0, 0, 0.3);\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12),\n inset 0 1px 2px rgba(255, 255, 255, 0.95);\n color: black;\n}\n\n.chrome-select:enabled:active {\n background-image: -webkit-image-set(url(Images/chromeSelect.png) 1x, url(Images/chromeSelect_2x.png) 2x), linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);\n box-shadow: none;\n text-shadow: none;\n}\n\n.chrome-select:enabled:focus {\n /* OVERRIDE */\n -webkit-transition: border-color 200ms;\n /* We use border color because it follows the border radius (unlike outline).\n * This is particularly noticeable on mac. */\n border-color: rgb(77, 144, 254);\n outline: none;\n}\n\nbody.inactive select.chrome-select,\n.chrome-select:disabled {\n background-image: -webkit-image-set(url(Images/chromeDisabledSelect.png) 1x, url(Images/chromeDisabledSelect_2x.png) 2x), linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);\n border-color: rgba(80, 80, 80, 0.2);\n box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08),\n inset 0 1px 2px rgba(255, 255, 255, 0.75);\n color: #aaa;\n}\n\n:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar,\n:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar {\n width: 14px;\n}\n\n:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar-track,\n:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar-track {\n -webkit-box-shadow: inset 0 0 1px rgba(255,255,255,0.3);\n}\n\n:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar-thumb,\n:host-context(:not(.platform-mac).-theme-with-dark-background) .-theme-with-dark-background ::-webkit-scrollbar-thumb {\n border-radius: 2px;\n background-color: #333;\n -webkit-box-shadow: inset 0 0 1px rgba(255,255,255,0.5);\n}\n\nlabel[is=dt-icon-label] {\n flex: none;\n}\n\n/*# sourceURL=ui/inspectorCommon.css */";Runtime.cachedResources["ui/inspectorStyle.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nhtml {\n height: 100%;\n overflow: hidden;\n}\n\nbody {\n height: 100%;\n width: 100%;\n position: relative;\n overflow: hidden;\n margin: 0;\n cursor: default;\n font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;\n font-size: 12px;\n tab-size: 4;\n -webkit-user-select: none;\n color: #222;\n}\n\n.platform-linux {\n color: rgb(48, 57, 66);\n font-family: Ubuntu, Arial, sans-serif;\n}\n\n.platform-mac {\n color: rgb(48, 57, 66);\n font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;\n}\n\n.platform-windows {\n font-family: 'Segoe UI', Tahoma, sans-serif;\n}\n\nlabel:hover input {\n box-shadow: 0 0 3px highlight;\n}\n\nfieldset[disabled] label:hover input {\n box-shadow: none;\n}\n\n.object-popover-container {\n display: inline-block;\n}\n\n.inspected-page-placeholder {\n background-color: white;\n}\n\n.toolbar-background {\n padding-left: 1px;\n border-bottom: 1px solid rgb(64%, 64%, 64%);\n background-origin: padding-box;\n background-clip: padding-box;\n}\n\n.bubble-repeat-count {\n display: inline-block;\n height: 14px;\n background-color: rgb(128, 151, 189);\n vertical-align: middle;\n white-space: nowrap;\n padding: 1px 4px;\n text-align: left;\n font-size: 11px;\n line-height: normal;\n font-weight: bold;\n text-shadow: none;\n color: white;\n margin-top: -1px;\n border-radius: 7px;\n}\n\n.error-message {\n color: red;\n}\n\n.-theme-with-dark-background .error-message {\n color: hsl(0, 100%, 65%);\n}\n\n.panel {\n display: flex;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 0;\n}\n\niframe.extension {\n flex: auto;\n width: 100%;\n height: 100%;\n}\n\niframe.panel.extension {\n display: block;\n height: 100%;\n}\n\n.outline-disclosure {\n padding: 0 0 0 4px;\n margin: 0;\n}\n\n.outline-disclosure li {\n position: relative;\n}\n\n.outline-disclosure li.hovered:not(.selected) .selection {\n display: block;\n left: 3px;\n right: 3px;\n background-color: rgba(56, 121, 217, 0.1);\n border-radius: 5px;\n}\n\n.outline-disclosure li .selection {\n display: none;\n z-index: -1;\n margin-left: -10000px;\n}\n\n.outline-disclosure li.selected .selection {\n display: block;\n background-color: #dadada;\n}\n\n.outline-disclosure li.in-clipboard .highlight {\n outline: 1px dotted darkgrey;\n}\n\n.outline-disclosure li.elements-drag-over .selection {\n display: block;\n margin-top: -2px;\n border-top: 2px solid rgb(56, 121, 217);\n}\n\nol.outline-disclosure:focus li.selected .selection {\n background-color: rgb(56, 121, 217);\n}\n\nol.outline-disclosure:focus li.parent.selected::before {\n background-color: white;\n}\n\nol.outline-disclosure,\n.outline-disclosure ol {\n list-style-type: none;\n}\n\n.outline-disclosure-no-padding {\n padding: 0;\n}\n\n.outline-disclosure ol {\n padding-left: 12px;\n}\n\n.outline-disclosure li {\n margin-top: 1px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\nol.outline-disclosure:focus li.selected {\n color: white;\n}\n\nol.outline-disclosure:focus li.selected * {\n color: inherit;\n}\n\n.outline-disclosure li::before {\n -webkit-user-select: none;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n content: \"aa\";\n color: transparent;\n text-shadow: none;\n margin-right: -2px;\n}\n\n.outline-disclosure li:not(.parent)::before {\n background-color: transparent;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.outline-disclosure li::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.outline-disclosure li::before {\n -webkit-mask-position: -4px -96px;\n background-color: rgb(110, 110, 110);\n}\n\n.outline-disclosure li.parent.expanded::before {\n -webkit-mask-position: -20px -96px;\n}\n\n.outline-disclosure ol.children {\n display: none;\n}\n\n.outline-disclosure ol.children.expanded {\n display: block;\n}\n\n.properties-accessor-property-name {\n font-style: italic;\n}\n\n.child-editing {\n color: #222 !important;\n text-decoration: none !important;\n overflow: visible !important;\n}\n\n.sidebar {\n overflow-x: hidden;\n background-color: #f3f3f3;\n}\n\n.pane-title-button {\n color: rgb(6, 6, 6);\n background-color: transparent;\n border: 1px solid rgb(165, 165, 165);\n background-color: #eee;\n background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));\n border-radius: 12px;\n -webkit-appearance: none;\n}\n\n.pane-title-button:active {\n background-color: rgb(215, 215, 215);\n background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));\n}\n\n.sidebar-tree,\n.sidebar-tree .children {\n position: relative;\n padding: 0;\n margin: 0;\n list-style: none;\n}\n\n.sidebar-tree-section {\n position: relative;\n height: 18px;\n padding: 1px 10px 6px 10px;\n white-space: nowrap;\n margin-top: 1px;\n color: rgb(92, 110, 129);\n text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;\n}\n\n.sidebar-tree-item {\n position: relative;\n height: 36px;\n padding: 0 5px 0 5px;\n white-space: nowrap;\n overflow-x: hidden;\n overflow-y: hidden;\n margin-top: 1px;\n line-height: 34px;\n border-top: 1px solid transparent;\n}\n\n.sidebar-tree .children {\n display: none;\n}\n\n.sidebar-tree .children.expanded {\n display: block;\n}\n\n.sidebar-tree-section + .children > .sidebar-tree-item {\n padding-left: 10px !important;\n}\n\n.sidebar-tree-section + .children.small > .sidebar-tree-item {\n padding-left: 17px !important;\n}\n\n.sidebar-tree > .children > .sidebar-tree-item {\n padding-left: 37px;\n}\n\n.sidebar-tree > .children > .children > .sidebar-tree-item {\n padding-left: 37px;\n}\n\n.sidebar-tree.some-expandable > .sidebar-tree-item:not(.parent) .icon {\n margin-left: 16px;\n}\n\n.sidebar-tree-item .disclosure-button {\n float: left;\n width: 10px;\n height: 10px;\n border: 0;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n -webkit-appearance: none;\n background-color: rgba(0, 0, 0, 0.75);\n position: relative;\n top: 10px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.sidebar-tree-item .disclosure-button {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.sidebar-tree-item .disclosure-button {\n -webkit-mask-position: -4px -96px;\n}\n\n.sidebar-tree-item.selected .disclosure-button {\n background-color: white;\n -webkit-mask-position: -4px -96px;\n}\n\n.sidebar-tree-item.expanded .disclosure-button {\n -webkit-mask-position: -20px -96px;\n}\n\n.sidebar-tree-item.selected.expanded .disclosure-button {\n background-color: white;\n -webkit-mask-position: -20px -96px;\n}\n\n.sidebar-tree-item .icon {\n float: left;\n width: 32px;\n height: 32px;\n margin-top: 1px;\n margin-right: 3px;\n}\n\n.sidebar-tree-item.wait .icon {\n content: none;\n}\n\n.spinner-icon::before,\n.sidebar-tree-item.wait .icon::before {\n display: block;\n width: 24px;\n height: 24px;\n margin: 4px;\n border: 3px solid grey;\n border-radius: 12px;\n clip: rect(0, 15px, 15px, 0);\n content: \"\";\n position: absolute;\n -webkit-animation: spinner-animation 1s linear infinite;\n box-sizing: border-box;\n}\n\n.spinner-icon.small::before,\n.sidebar-tree-item.wait.small .icon::before {\n width: 14px;\n height: 14px;\n margin: 1px;\n clip: rect(0, 9px, 9px, 0);\n border-width: 2px;\n}\n\n.sidebar-tree-item.wait.selected .icon::before {\n border-color: white;\n}\n\n@-webkit-keyframes spinner-animation {\n from { transform: rotate(0); }\n to { transform: rotate(360deg); }\n}\n\nli .status {\n float: right;\n height: 16px;\n margin-top: 9px;\n margin-left: 4px;\n line-height: 1em;\n}\n\nli .status:empty {\n display: none;\n}\n\nli .status .bubble-repeat-count:empty {\n display: none;\n}\n\nli.selected .status .bubble-repeat-count {\n background-color: white !important;\n color: rgb(132, 154, 190) !important;\n}\n\n:focus li.selected .status .bubble-repeat-count {\n color: rgb(36, 98, 172) !important;\n}\n\nbody.inactive li.selected .status .bubble-repeat-count {\n color: rgb(159, 159, 159) !important;\n}\n\n.sidebar-tree.small .sidebar-tree-item,\n.sidebar-tree .children.small .sidebar-tree-item,\n.sidebar-tree-item.small {\n height: 20px;\n}\n\n.sidebar-tree.small .sidebar-tree-item .icon,\n.sidebar-tree .children.small .sidebar-tree-item .icon,\n.sidebar-tree-item.small .icon {\n width: 16px;\n height: 16px;\n}\n\n.sidebar-tree.small .sidebar-tree-item .status,\n.sidebar-tree .children.small .sidebar-tree-item .status,\n.sidebar-tree-item.small .status {\n margin-top: 1px;\n}\n\n.sidebar-tree-item.selected,\n.-theme-selection-color {\n color: white;\n background-origin: padding-box;\n background-clip: padding-box;\n background-color: rgb(56, 121, 217);\n}\n\n:focus .sidebar-tree-item.selected {\n background-color: rgb(56, 121, 217);\n}\n\nbody.inactive .sidebar-tree-item.selected {\n background-color: rgb(180,180,180);\n}\n\n.sidebar-tree-item .titles {\n display: flex;\n flex-direction: column;\n position: relative;\n top: 5px;\n line-height: 12px;\n padding-bottom: 1px;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.titles > .title-container {\n display: flex;\n}\n\n.sidebar-tree-item .titles.no-subtitle {\n top: 10px;\n}\n\n.sidebar-tree.small .sidebar-tree-item .titles,\n.sidebar-tree .children.small .sidebar-tree-item .titles,\n.sidebar-tree-item.small .titles {\n top: 2px;\n line-height: normal;\n}\n\n.sidebar-tree:not(.small) .sidebar-tree-item:not(.small) .title::after,\n.sidebar-tree .children:not(.small) .sidebar-tree-item .title::after {\n content: \"\\A\";\n white-space: pre;\n}\n\n.sidebar-tree-item .subtitle {\n font-size: 80%;\n}\n\n.sidebar-tree.small .sidebar-tree-item .subtitle,\n.sidebar-tree .children.small .sidebar-tree-item .subtitle,\n.sidebar-tree-item.small .subtitle {\n display: none;\n}\n\n.sidebar-tree-item.selected .subtitle {\n color: white;\n}\n\n.bubble-repeat-count.debug,\n.console-debug-level .bubble-repeat-count {\n background-color: rgb(0, 0, 255) !important;\n}\n\n.bubble-repeat-count.warning,\n.console-warning-level .bubble-repeat-count {\n background-color: rgb(232, 164, 0) !important;\n}\n\n.bubble-repeat-count.error,\n.console-error-level .bubble-repeat-count {\n background-color: rgb(216, 35, 35) !important;\n}\n\n.soft-context-menu-glass-pane {\n z-index: 20000;\n}\n\n.root-view {\n background-color: white;\n overflow: hidden;\n position: absolute !important;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n}\n\n.drawer-toolbar {\n margin-right: -6px;\n}\n\n/*# sourceURL=ui/inspectorStyle.css */";Runtime.cachedResources["ui/inspectorSyntaxHighlight.css"]="/*\n * Copyright (C) 2009 Apple Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n.cm-js-keyword {color: rgb(170, 13, 145);}\n.cm-js-number {color: rgb(28, 0, 207);}\n.cm-js-comment {color: rgb(0, 116, 0);}\n.cm-js-string {color: rgb(196, 26, 22);}\n.cm-js-string-2 {color: rgb(196, 26, 22);}\n\n.cm-css-keyword { color: rgb(7, 144, 154);}\n.cm-css-number {color: rgb(50, 0, 255);}\n.cm-css-comment {color: rgb(0, 116, 0);}\n.cm-css-def {color: rgb(200, 0, 0);}\n.cm-css-meta {color: rgb(200, 0, 0);}\n.cm-css-atom {color: rgb(7, 144, 154);}\n.cm-css-string {color: rgb(7, 144, 154);}\n.cm-css-string-2 {color: rgb(7, 144, 154);}\n.cm-css-link {color: rgb(7, 144, 154);}\n.cm-css-variable {color: rgb(200, 0, 0);}\n.cm-css-variable-2 {color: rgb(0, 0, 128);}\n.cm-css-property, .webkit-css-property {color: rgb(200, 0, 0);}\n\n.cm-xml-meta {color: rgb(192, 192, 192);}\n.cm-xml-comment {color: rgb(35, 110, 37);}\n.cm-xml-string {color: rgb(26, 26, 166);}\n.cm-xml-tag {color: rgb(136, 18, 128);}\n.cm-xml-attribute {color: rgb(153, 69, 0);}\n.cm-xml-link {color: #00e;}\n\n.webkit-html-comment {\n /* Keep this in sync with view-source.css (.webkit-html-comment) */\n color: rgb(35, 110, 37);\n}\n\n.webkit-html-tag {\n color: rgb(168, 148, 166);\n}\n\n.webkit-html-tag-name, .webkit-html-close-tag-name {\n /* Keep this in sync with view-source.css (.webkit-html-tag) */\n color: rgb(136, 18, 128);\n}\n\n.webkit-html-pseudo-element {\n /* This one is non-standard. */\n color: brown;\n}\n\n.webkit-html-js-node,\n.webkit-html-css-node {\n white-space: pre-wrap;\n}\n\n.webkit-html-text-node {\n unicode-bidi: -webkit-isolate;\n}\n\n.webkit-html-entity-value {\n /* This one is non-standard. */\n background-color: rgba(0, 0, 0, 0.15);\n unicode-bidi: -webkit-isolate;\n}\n\n.webkit-html-doctype {\n /* Keep this in sync with view-source.css (.webkit-html-doctype) */\n color: rgb(192, 192, 192);\n}\n\n.webkit-html-attribute-name {\n /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */\n color: rgb(153, 69, 0);\n unicode-bidi: -webkit-isolate;\n}\n\n.webkit-html-attribute-value {\n /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */\n color: rgb(26, 26, 166);\n unicode-bidi: -webkit-isolate;\n}\n\n.webkit-html-external-link,\n.webkit-html-resource-link {\n /* Keep this in sync with view-source.css (.webkit-html-external-link, .webkit-html-resource-link) */\n color: rgb(17, 85, 204);\n}\n\n.-theme-with-dark-background .webkit-html-external-link,\n.-theme-with-dark-background .webkit-html-resource-link,\n:host-context(.-theme-with-dark-background) .webkit-html-external-link,\n:host-context(.-theme-with-dark-background) .webkit-html-resource-link {\n color: hsl(0, 0%, 67%);\n}\n\n.webkit-html-resource-link {\n /* Required for consistency with view-source.css, since anchors may not have href attributes */\n text-decoration: underline;\n cursor: pointer;\n}\n\n.webkit-html-external-link {\n /* Keep this in sync with view-source.css (.webkit-html-external-link) */\n text-decoration: none;\n}\n\n.webkit-html-external-link:hover {\n /* Keep this in sync with view-source.css (.webkit-html-external-link:hover) */\n text-decoration: underline;\n}\n\n.webkit-html-end-of-file {\n /* Keep this in sync with view-source.css (.webkit-html-end-of-file) */\n color: rgb(255, 0, 0);\n font-weight: bold;\n}\n\n/*# sourceURL=ui/inspectorSyntaxHighlight.css */";Runtime.cachedResources["ui/inspectorSyntaxHighlightDark.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.cm-js-atom{color:rgb(161, 247, 181);}\n.cm-js-attribute{color:rgb(97, 148, 198);}\n.cm-js-builtin{color:rgb(159, 180, 214);}\n.cm-js-comment{color:rgb(116, 116, 116);}\n.cm-js-def{color:rgb(93, 176, 215);}\n.cm-js-keyword{color:rgb(154, 127, 213);}\n.cm-js-link{color:rgb(159, 180, 214);}\n.cm-js-meta{color:rgb(221, 251, 85);}\n.cm-js-number{color:rgb(161, 247, 181);}\n.cm-js-operator{color:rgb(210, 192, 87);}\n.cm-js-property{color:rgb(210, 192, 87);}\n.cm-js-string{color:rgb(242, 139, 84);}\n.cm-js-string-2{color:rgb(242, 139, 84);}\n.cm-js-tag{color:rgb(93, 176, 215);}\n.cm-js-variable{color:rgb(217, 217, 217);}\n.cm-js-variable-2{color:rgb(217, 217, 217);}\n.cm-atom{color:rgb(161, 247, 181);}\n.cm-comment{color:rgb(116, 116, 116);}\n.cm-variable{color:rgb(217, 217, 217);}\n.cm-string{color:rgb(242, 139, 84);}\n.cm-keyword{color:rgb(154, 127, 213);}\n.cm-number{color:rgb(161, 247, 181);}\n.cm-operator{color:rgb(210, 192, 87);}\n.cm-css-atom{color:rgb(217, 217, 217);}\n.cm-css-builtin{color:rgb(255, 163, 79);}\n.cm-css-def{color:rgb(255, 163, 79);}\n.cm-css-comment{color:rgb(116, 116, 116);}\n.cm-css-meta{color:rgb(132, 240, 255);}\n.cm-css-number{color:rgb(217, 217, 217);}\n.cm-css-operator{color:rgb(217, 217, 217);}\n.cm-css-property{color:rgb(132, 240, 255);}\n.cm-css-qualifier{color:rgb(255, 163, 79);}\n.cm-css-string{color:rgb(231, 194, 111);}\n.cm-css-string-2{color:rgb(217, 217, 217);}\n.cm-css-tag{color:rgb(255, 163, 79);}\n.cm-css-variable{color:rgb(255, 163, 79);}\n.cm-css-variable-2{color:rgb(255, 163, 79);}\n.cm-xml-comment{color:rgb(137, 137, 137);}\n.cm-xml-error{color:rgb(198, 95, 95);}\n.cm-xml-string{color:rgb(242, 151, 102);}\n.cm-xml-tag{color:rgb(93, 176, 215);}\n.cm-xml-attribute{color:rgb(155, 187, 220);}\n.cm-xml-link{color:rgb(231, 194, 111);}\n\n.webkit-html-attribute-name{color:rgb(155, 187, 220);}\n.webkit-html-attribute-value{color:rgb(242, 151, 102);}\n.webkit-html-comment{color:rgb(137, 137, 137);}\n.webkit-html-resource-link{color:rgb(231, 194, 111);}\n.webkit-html-external-link{color:rgb(231, 194, 111);}\n.webkit-html-tag{color:rgb(93, 176, 215);}\n.webkit-html-tag-name{color:rgb(93, 176, 215);}\n.webkit-html-close-tag-name{color:rgb(93, 176, 215);}\n.webkit-html-text-node{color:rgb(207, 208, 208);}\n.webkit-html-css-node{color:rgb(207, 208, 208);}\n.webkit-html-js-node{color:rgb(207, 208, 208);}\n.webkit-html-pseudo-element{color:rgb(93, 175, 215);}\n.webkit-css-selector{color:rgb(255, 163, 79);}\n.webkit-css-at-rule{color:rgb(188, 164, 197);}\n.webkit-css-color{color:rgb(255, 163, 79);}\n.webkit-css-comment{color:rgb(116, 116, 116);}\n.webkit-css-important{color:rgb(255, 26, 26);}\n.webkit-css-keyword{color:rgb(255, 163, 79);}\n.webkit-css-number{color:rgb(217, 217, 217);}\n.webkit-css-property{color: rgb(53, 212, 199);}\n.webkit-css-string{color:rgb(231, 194, 111);}\n.webkit-css-url{color:rgb(231, 194, 111);}\n\n/*# sourceURL=ui/inspectorSyntaxHighlightDark.css */";Runtime.cachedResources["ui/inspectorViewTabbedPane.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.tabbed-pane-header-tab,\n.tabbed-pane-header-tab.selected {\n height: 26px;\n margin: 0;\n background: #f3f3f3;\n border: none;\n border-left: 2px solid transparent;\n border-right: 2px solid transparent;\n padding: 0 6px;\n}\n\n.tabbed-pane-header-tab.selected {\n border-width: 0 2px 0 2px;\n}\n\n.tabbed-pane-header-contents {\n margin-left: 0;\n}\n\n/*# sourceURL=ui/inspectorViewTabbedPane.css */";Runtime.cachedResources["ui/listWidget.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.list {\n flex: auto 0 1;\n overflow-y: auto;\n border: 1px solid rgb(231, 231, 231);\n flex-direction: column;\n}\n\n.list-separator {\n background: rgb(231, 231, 231);\n height: 1px;\n}\n\n.list-item {\n flex: none;\n min-height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.list-item:hover {\n background: hsl(0, 0%, 96%);\n}\n\n.controls-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n align-items: stretch;\n pointer-events: none;\n}\n\n.controls-gradient {\n flex: 0 1 50px;\n}\n\n.list-item:hover .controls-gradient {\n background-image: linear-gradient(90deg, transparent, hsl(0, 0%, 96%));\n}\n\n.controls-buttons {\n flex: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n pointer-events: auto;\n}\n\n.list-item:hover .controls-buttons {\n background-color: hsl(0, 0%, 96%);\n}\n\n.remove-button,\n.edit-button {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n width: 32px;\n height: 24px;\n opacity: 0.5;\n cursor: pointer;\n flex: none;\n visibility: hidden;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.remove-button,\n.edit-button {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.list-item:hover .remove-button,\n.list-item:hover .edit-button {\n visibility: visible;\n}\n\n.remove-button:hover,\n.edit-button:hover {\n opacity: 0.7;\n}\n\n.remove-button {\n background-position: -128px -24px;\n}\n\n.edit-button {\n background-position: -160px 0px;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n flex: none;\n background: hsl(0, 0%, 96%);\n overflow: hidden;\n}\n\n.editor-content {\n flex: auto;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n}\n\n.editor-buttons {\n flex: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n padding: 5px;\n}\n\n.editor-buttons > button {\n flex: none;\n margin-right: 10px;\n}\n\n.editor-content input {\n margin-right: 10px;\n}\n\n.editor-content input.error-input {\n background-color: white;\n}\n\n/*# sourceURL=ui/listWidget.css */";Runtime.cachedResources["ui/panelEnablerView.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.panel-enabler-view {\n background-color: white;\n font-size: 13px;\n text-align: center;\n overflow-x: hidden;\n overflow-y: overlay;\n flex: auto;\n display: flex;\n}\n\n.panel-enabler-view h1 {\n color: rgb(110, 116, 128);\n font-size: 16px;\n line-height: 20px;\n font-weight: normal;\n margin-top: 0;\n}\n\n.panel-enabler-view img {\n height: 100%;\n min-height: 200px;\n max-width: 100%;\n top: 0;\n bottom: 0;\n padding: 20px 0 20px 20px;\n margin: auto;\n vertical-align: middle;\n}\n\n.panel-enabler-view img.hidden {\n display: initial !important;\n width: 0;\n}\n\n.panel-enabler-view .flexible-space {\n -webkit-flex: 1;\n}\n\n.panel-enabler-view form {\n display: inline-block;\n vertical-align: middle;\n width: 330px;\n margin: 0;\n padding: 15px;\n white-space: normal;\n}\n\n.panel-enabler-view label {\n position: relative;\n display: block;\n text-align: left;\n word-break: break-word;\n margin: 0 0 5px 20px;\n}\n\n/*# sourceURL=ui/panelEnablerView.css */";Runtime.cachedResources["ui/popover.css"]=".popover-container {\n pointer-events: none;\n overflow: hidden;\n}\n\n.popover {\n position: absolute;\n z-index: 600;\n pointer-events: none;\n display: flex;\n background-color: white;\n box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.3), 0 2px 2px 0 rgba(0, 0, 0, 0.2), 0 1px 4px 0 rgba(0, 0, 0, 0.37);\n border-radius: 2px;\n}\n\n.popover .content {\n pointer-events: auto;\n overflow: auto;\n -webkit-user-select: text;\n line-height: 11px;\n flex: auto;\n margin: 6px;\n}\n\n.popover .content.no-margin {\n margin: 0;\n overflow: hidden;\n}\n\n.popover .arrow {\n position: absolute;\n background-image: url(Images/popoverArrows.png);\n width: 19px;\n height: 19px;\n margin-top: -19px;\n top: 0;\n left: 0;\n}\n\n.-theme-with-dark-background .popover .arrow {\n -webkit-filter: invert(80%);\n}\n\n.popover.top-left-arrow .arrow {\n /* The default is top-left, no styles needed. */\n}\n\n.popover.top-right-arrow .arrow {\n right: 19px;\n left: auto;\n}\n\n.popover.bottom-left-arrow .arrow {\n top: auto;\n bottom: 0;\n margin-top: 0;\n margin-bottom: -19px;\n background-position: 0 -19px;\n}\n\n.popover.bottom-right-arrow .arrow {\n right: 15px;\n left: auto;\n top: auto;\n bottom: 0;\n margin-top: 0;\n margin-bottom: -19px;\n background-position: 0 -19px;\n}\n\n.source-frame-popover-title {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n font-weight: bold;\n padding-left: 18px;\n}\n\n.source-frame-popover-tree {\n border-top: 1px solid rgb(184, 184, 184);\n overflow: auto;\n position: absolute;\n top: 21px;\n bottom: 5px;\n left: 5px;\n right: 5px;\n margin-top: 1px;\n}\n\n/*# sourceURL=ui/popover.css */";Runtime.cachedResources["ui/progressIndicator.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.progress-indicator-shadow-stop-button {\n background-color: rgb(216, 0, 0) !important;\n border: 0;\n width: 10px;\n height: 12px;\n border-radius: 2px;\n}\n\n.progress-indicator-shadow-container {\n display: flex;\n flex: 1 0 auto;\n align-items: center;\n}\n\n.progress-indicator-shadow-container .title {\n text-overflow: ellipsis;\n overflow: hidden;\n max-width: 150px;\n margin-right: 2px;\n color: #777;\n}\n\n.progress-indicator-shadow-container progress {\n flex: auto;\n margin: 0 2px;\n width: 100px\n}\n\n/*# sourceURL=ui/progressIndicator.css */";Runtime.cachedResources["ui/propertiesSection.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.properties-tree {\n margin: 0;\n padding: 0 6px 2px;\n list-style: none;\n min-height: 18px;\n}\n\n.properties-tree ol {\n display: none;\n margin: 0;\n -webkit-padding-start: 12px;\n list-style: none;\n}\n\n.properties-tree ol.expanded {\n display: block;\n}\n\n.properties-tree li {\n margin-left: 12px;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n -webkit-user-select: text;\n cursor: default;\n padding-top: 2px;\n line-height: 12px;\n}\n\n.properties-tree li.parent {\n margin-left: 1px;\n}\n\n.properties-tree li.parent::before {\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n content: \"a\";\n width: 8px;\n float: left;\n margin-right: 4px;\n color: transparent;\n text-shadow: none;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.properties-tree li.parent::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.properties-tree li.parent::before {\n background-position: -4px -96px;\n}\n\n.properties-tree li.parent.expanded::before {\n background-position: -20px -96px;\n}\n\n.properties-tree li .info {\n padding-top: 4px;\n padding-bottom: 3px;\n}\n\n.properties-tree li.editing {\n margin-left: 10px;\n text-overflow: clip;\n}\n\n.properties-tree li.editing-sub-part {\n padding: 3px 6px 8px 18px;\n margin: -1px -6px -8px -6px;\n text-overflow: clip;\n}\n\n.properties-tree .name {\n color: rgb(136, 19, 145);\n flex-shrink: 0;\n}\n\n.properties-tree .separator {\n flex-shrink: 0;\n}\n\n.properties-tree .dimmed {\n opacity: 0.6;\n}\n\n.properties-tree .value.error {\n color: red;\n}\n\n.properties-tree .number {\n color: blue;\n}\n\n.properties-tree .keyword {\n color: rgb(136, 19, 79);\n}\n\n.properties-tree .color {\n color: rgb(118, 15, 21);\n}\n\n/*# sourceURL=ui/propertiesSection.css */";Runtime.cachedResources["ui/radioButton.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n::content .dt-radio-button {\n height: 17px;\n width: 17px;\n min-width: 17px;\n border: 1px solid rgb(165, 165, 165);\n background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));\n border-radius: 8px;\n -webkit-appearance: none;\n vertical-align: middle;\n margin: 0 5px 5px 0;\n}\n\n::content .dt-radio-button:active:not(:disabled) {\n background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));\n}\n\n::content .dt-radio-button:checked {\n background: url(Images/radioDot.png) center no-repeat,\n linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));\n}\n\n::content .dt-radio-button:checked:active {\n background: url(Images/radioDot.png) center no-repeat,\n linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));\n}\n\n/*# sourceURL=ui/radioButton.css */";Runtime.cachedResources["ui/reportView.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n background-color: #f9f9f9;\n}\n\n.report-content-box {\n background-color: white;\n white-space: nowrap;\n overflow: auto;\n}\n\n.report-header {\n border-bottom: 1px solid rgb(230, 230, 230);\n padding: 12px 24px;\n}\n\n.report-header .toolbar {\n margin-bottom: -8px;\n}\n\n.report-header .toolbar {\n margin-top: 5px;\n margin-left: -8px;\n}\n\n.report-title {\n font-size: 15px;\n}\n\n.report-url, .report-subtitle {\n font-size: 12px;\n margin-top: 10px;\n}\n\n.report-section {\n display: flex;\n padding: 12px;\n border-bottom: 1px solid rgb(230, 230, 230);\n flex-direction: column;\n}\n\n.report-section-header {\n margin-left: 18px;\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.report-section-title {\n flex: auto;\n text-overflow: ellipsis;\n overflow: hidden;\n font-weight: bold;\n color: #555;\n}\n\n.report-field {\n margin-top: 8px;\n display: flex;\n line-height: 20px;\n}\n\n.report-row {\n margin: 10px 0 2px 18px;\n}\n\n.report-field-name {\n color: #888;\n flex: 0 0 128px;\n text-align: right;\n padding: 0 6px;\n white-space: pre;\n}\n\n.report-field-value {\n flex: auto;\n padding: 0 6px;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: pre;\n}\n\n.report-field-value-subtitle {\n color: #888;\n line-height: 14px;\n}\n\n/*# sourceURL=ui/reportView.css */";Runtime.cachedResources["ui/searchableView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.search-bar {\n flex: 0 0 23px;\n background-color: #eee;\n border-top: 1px solid #ccc;\n display: flex;\n overflow: hidden;\n}\n\n.search-bar.replaceable {\n flex: 0 0 44px;\n}\n\n.search-toolbar {\n margin-top: -2px;\n}\n\n.search-replace {\n -webkit-appearance: none;\n border: 0;\n padding: 0 3px;\n margin: 0;\n flex: 1;\n}\n\n.search-replace:focus {\n outline: none;\n}\n\n.toolbar-search {\n border-spacing: 1px;\n}\n\n.toolbar-search td {\n padding: 0 5px 0 0;\n}\n\n.toolbar-search td > span {\n display: flex;\n align-items: baseline;\n line-height: 17px;\n}\n\n.toolbar-search-navigation-controls {\n align-self: stretch;\n background-image: linear-gradient(rgb(228, 228, 228), rgb(206, 206, 206));\n}\n\n.toolbar-search-navigation {\n display: inline-block;\n width: 18px;\n height: 18px;\n background-repeat: no-repeat;\n background-position: 4px 7px;\n border-left: 1px solid rgb(170, 170, 170);\n opacity: 0.3;\n}\n\n.toolbar-search-navigation.enabled {\n opacity: 1.0;\n}\n\n.toolbar-search button.search-action-button {\n border: 1px solid rgb(163, 163, 163);\n border-radius: 8px;\n margin: 0;\n background-image: linear-gradient(rgb(241, 241, 241), rgb(220, 220, 220));\n width: 100%;\n height: 20px;\n}\n\n.toolbar-search button.search-action-button:active {\n background-image: linear-gradient(rgb(185, 185, 185), rgb(156, 156, 156));\n}\n\n.toolbar-search-control {\n display: -webkit-flex;\n position: relative;\n background-color: white;\n}\n\n.toolbar-replace-control,\n#search-input-field {\n padding-top: 1px;\n line-height: 17px;\n}\n\n.toolbar-search-control, .toolbar-replace-control {\n border: 1px solid rgb(163, 163, 163);\n height: 20px;\n border-radius: 2px;\n width: 253px;\n margin-left: 1px;\n}\n\n.toolbar-search-navigation.enabled:active {\n background-position: 4px 7px, 0 0;\n}\n\n.toolbar-search-navigation.toolbar-search-navigation-prev {\n background-image: url(Images/searchPrev.png);\n border-left: 1px solid rgb(163, 163, 163);\n}\n\n:host-context(.-theme-with-dark-background) .toolbar-search-navigation {\n -webkit-filter: invert(90%);\n}\n\n.toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active {\n background-image: url(Images/searchPrev.png), linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));\n}\n\n.toolbar-search-navigation.toolbar-search-navigation-next {\n background-image: url(Images/searchNext.png);\n border-left: 1px solid rgb(230, 230, 230);\n}\n\n.toolbar-search-navigation.toolbar-search-navigation-next.enabled:active {\n background-image: url(Images/searchNext.png), linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));\n}\n\n.search-results-matches {\n display: inline-block;\n text-align: right;\n font-size: 11px;\n padding: 0 4px;\n color: rgb(165, 165, 165);\n}\n\n/*# sourceURL=ui/searchableView.css */";Runtime.cachedResources["ui/section.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.section {\n position: relative;\n margin-top: 1px;\n}\n\n.section > .header {\n padding: 0 8px 0 5px;\n min-height: 18px;\n white-space: nowrap;\n background-origin: padding-box;\n background-clip: padding-box;\n}\n\n.section > .header::before {\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n content: \"a\";\n color: transparent;\n text-shadow: none;\n float: left;\n width: 8px;\n margin-right: 4px;\n margin-top: 2px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.section > .header::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.section > .header::before {\n background-position: -4px -96px;\n}\n\n.section.expanded > .header::before {\n background-position: -20px -96px;\n}\n\n.section > .header .title {\n font-weight: normal;\n word-wrap: break-word;\n white-space: normal;\n line-height: 18px;\n}\n\n.section > .header label {\n display: none;\n}\n\n.section.expanded .header label {\n display: inline;\n}\n\n.section > .header .subtitle {\n float: right;\n margin-left: 5px;\n max-width: 55%;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.section > .header .subtitle a {\n color: inherit;\n}\n\n.section > .properties {\n display: none;\n}\n\n.section.expanded > .properties {\n display: block;\n}\n\n/*# sourceURL=ui/section.css */";Runtime.cachedResources["ui/sidebarPane.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.sidebar-pane {\n position: relative;\n flex-direction: column;\n display: flex;\n flex: none;\n}\n\n.sidebar-pane-hidden {\n display: none;\n}\n\n.sidebar-pane .info {\n text-align: center;\n font-style: italic;\n padding: 6px;\n color: #888;\n}\n\n.sidebar-pane .section .properties-tree {\n padding-left: 16px;\n}\n\n.sidebar-tabbed-pane .tabbed-pane-header {\n border-bottom: 1px solid rgb(202, 202, 202);\n background-color: #eee;\n}\n\n.sidebar-pane-title {\n display: flex;\n align-items: center;\n background-color: #eee;\n height: 20px;\n padding: 0 5px;\n border-top: 1px solid #dadada;\n white-space: nowrap;\n overflow: hidden;\n position: relative;\n}\n\n.sidebar-pane-title.expanded,\n.sidebar-pane-title:last-child {\n border-bottom: 1px solid #ddd;\n}\n\n.sidebar-pane-title::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n background-color: #888;\n float: left;\n width: 11px;\n height: 11px;\n margin-right: 2px;\n content: \"a\";\n color: transparent;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.sidebar-pane-title::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.sidebar-pane-title::before {\n -webkit-mask-position: -4px -96px;\n}\n\n.sidebar-pane-title.expanded::before {\n -webkit-mask-position: -20px -96px;\n}\n\n.sidebar-pane > .toolbar {\n border-bottom: 1px solid #eee;\n}\n\n.sidebar-pane > .toolbar > * {\n pointer-events: auto;\n}\n\n.sidebar-pane-title > .toolbar {\n position: absolute;\n right: 0;\n top: -3px;\n}\n\n.section > .header input[type=checkbox] {\n height: 1em;\n width: 1em;\n margin-left: 0;\n margin-top: 0;\n margin-bottom: 0.25em;\n vertical-align: bottom;\n}\n\n.hidden-callframes-message {\n text-align: center;\n font-style: italic;\n padding: 4px;\n color: #888;\n background-color: #FFFFC2;\n}\n\n\n/*# sourceURL=ui/sidebarPane.css */";Runtime.cachedResources["ui/smallIcon.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\ndiv {\n width: 10px;\n height: 10px;\n margin-right: 4px;\n display: inline-block;\n flex-shrink: 0;\n}\n\ndiv.error-icon,\ndiv.revokedError-icon,\ndiv.warning-icon,\ndiv.info-icon,\ndiv.device-icon,\ndiv.red-ball,\ndiv.green-ball,\ndiv.orange-ball {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\ndiv.error-icon,\ndiv.revokedError-icon,\ndiv.warning-icon,\ndiv.info-icon,\ndiv.device-icon,\ndiv.red-ball,\ndiv.green-ball,\ndiv.orange-ball {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\ndiv.error-icon {\n background-position: -213px -96px;\n}\n\ndiv.revokedError-icon {\n background-position: -245px -107px;\n}\n\ndiv.warning-icon {\n background-position: -202px -107px;\n}\n\ndiv.info-icon {\n background-position: -213px -107px;\n}\n\ndiv.device-icon {\n background-position: -224px -107px;\n}\n\ndiv.red-ball {\n background-position: -224px -96px;\n}\n\ndiv.green-ball {\n background-position: -235px -96px;\n}\n\ndiv.orange-ball {\n background-position: -246px -96px;\n}\n\n/*# sourceURL=ui/smallIcon.css */";Runtime.cachedResources["ui/softContextMenu.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n position: absolute;\n border: 1px solid rgba(196, 196, 196, 0.9);\n border-top: 1px solid rgba(196, 196, 196, 0.5);\n /* NOTE: Keep padding top in sync with topPadding in SoftContextMenu.js */\n padding: 4px 0 4px 0;\n border-radius: 4px;\n background-color: rgb(240, 240, 240);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);\n overflow-y: auto;\n min-width: 160px !important;\n}\n\n.soft-context-menu-item {\n display: flex;\n width: 100%;\n line-height: 14px;\n font-size: 12px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n padding: 2px 7px 2px 8px;\n margin: 0 13px 0 0;\n white-space: nowrap;\n}\n\n.soft-context-menu-disabled {\n color: #999;\n pointer-events: none;\n}\n\n.soft-context-menu-separator {\n height: 10px;\n margin: 0 1px;\n}\n\n.soft-context-menu-separator > .separator-line {\n margin: 0;\n height: 5px;\n border-bottom: 1px solid rgb(222, 222, 222);\n pointer-events: none;\n}\n\n.soft-context-menu-item-mouse-over,\n.-theme-selection-color {\n border-top: 1px solid rgb(56, 121, 217);\n border-bottom: 1px solid rgb(56, 121, 217);\n background-color: rgb(56, 121, 217);\n color: white;\n}\n\n:host-context(.platform-mac) .soft-context-menu-item-mouse-over,\n.-theme-selection-color {\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n background-image: linear-gradient(to right, hsl(214, 81%, 60%), hsl(214, 100%, 56%));\n}\n\n:host-context(.platform-mac) .separator-line {\n border-width: 2px;\n}\n\n.soft-context-menu-item-submenu-arrow {\n color: #222;\n pointer-events: none;\n font-size: 11px;\n flex: 1 1 auto;\n text-align: right;\n}\n\n.soft-context-menu-item-mouse-over .soft-context-menu-item-checkmark {\n color: white;\n}\n\n.soft-context-menu-custom-item {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n flex: auto;\n}\n\n.soft-context-menu-shortcut {\n color: gray;\n pointer-events: none;\n flex: 1 1 auto;\n text-align: right;\n padding-left: 10px;\n}\n\n.soft-context-menu-item-mouse-over .soft-context-menu-shortcut {\n color: inherit;\n}\n\n.checkmark {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.7;\n width: 10px;\n height: 10px;\n background-position: -128px -109px;\n display: inline-block;\n pointer-events: none;\n margin: auto 5px auto 0px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.checkmark {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n}\n\n/*# sourceURL=ui/softContextMenu.css */";Runtime.cachedResources["ui/splitWidget.css"]="/*\n * Copyright (C) 2011 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.\n * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n:host {\n overflow: hidden;\n}\n\n.shadow-split-widget {\n display: flex;\n overflow: hidden;\n}\n\n.shadow-split-widget-contents {\n display: flex;\n position: relative;\n flex-direction: column;\n}\n\n.shadow-split-widget-sidebar {\n flex: none;\n}\n\n.shadow-split-widget-main, .shadow-split-widget-sidebar.maximized {\n flex: auto;\n}\n\n.shadow-split-widget.hbox > .shadow-split-widget-resizer {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 6px;\n z-index: 500;\n}\n\n.shadow-split-widget.vbox > .shadow-split-widget-resizer {\n position: absolute;\n left: 0;\n right: 0;\n height: 6px;\n z-index: 500;\n}\n\n.shadow-split-widget.hbox.shadow-split-widget-first-is-sidebar {\n flex-direction: row-reverse !important;\n}\n\n.shadow-split-widget.vbox.shadow-split-widget-first-is-sidebar {\n flex-direction: column-reverse !important;\n}\n\n.shadow-split-widget-resizer-border {\n pointer-events: none;\n}\n\n.shadow-split-widget.vbox > .shadow-split-widget-sidebar:not(.maximized) {\n border: 0;\n border-top: 1px solid rgb(64%, 64%, 64%);\n}\n\n.shadow-split-widget.vbox.shadow-split-widget-first-is-sidebar > .shadow-split-widget-sidebar:not(.maximized) {\n border: 0;\n border-bottom: 1px solid rgb(64%, 64%, 64%);\n}\n\n.shadow-split-widget.hbox > .shadow-split-widget-sidebar:not(.maximized) {\n border: 0;\n border-left: 1px solid rgb(64%, 64%, 64%);\n}\n\n.shadow-split-widget.hbox.shadow-split-widget-first-is-sidebar > .shadow-split-widget-sidebar:not(.maximized) {\n border: 0;\n border-right: 1px solid rgb(64%, 64%, 64%);\n}\n\n.shadow-split-widget button.sidebar-show-hide-button {\n position: absolute;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n height: 16px;\n width: 16px;\n border: none;\n z-index: 20;\n background-color: #5a5a5a;\n}\n\n.shadow-split-widget button.sidebar-show-hide-button:hover {\n background-color: #333;\n}\n\n.shadow-split-widget button.sidebar-show-hide-button:active {\n background-color: #5a5a5a;\n}\n\n.shadow-split-widget button.sidebar-show-hide-button:disabled {\n background-color: rgba(0, 0, 0, 0.35);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.shadow-split-widget button.sidebar-show-hide-button {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.shadow-split-widget button.left-sidebar-show-hide-button,\n.shadow-split-widget button.top-sidebar-show-hide-button {\n top: 5px;\n left: 5px;\n}\n\n.shadow-split-widget button.right-sidebar-show-hide-button {\n top: 5px;\n right:4px;\n}\n\n.shadow-split-widget button.bottom-sidebar-show-hide-button {\n bottom: 5px;\n right: 3px;\n}\n\n.shadow-split-widget button.left-sidebar-show-hide-button.toggled-show {\n -webkit-mask-position: -168px -76px; /* |> */\n}\n\n.shadow-split-widget button.left-sidebar-show-hide-button.toggled-hide {\n -webkit-mask-position: -199px -76px; /* |< */\n}\n\n.shadow-split-widget button.right-sidebar-show-hide-button.toggled-show {\n -webkit-mask-position: -296px -76px; /* <| */\n}\n\n.shadow-split-widget button.right-sidebar-show-hide-button.toggled-hide {\n -webkit-mask-position: -264px -76px; /* >| */\n}\n\n.shadow-split-widget button.top-sidebar-show-hide-button.toggled-show {\n -webkit-mask-position: -168px -76px; /* |> */\n transform: rotate(90deg);\n}\n\n.shadow-split-widget button.top-sidebar-show-hide-button.toggled-hide {\n -webkit-mask-position: -199px -76px; /* |< */\n transform: rotate(90deg);\n}\n\n.shadow-split-widget button.bottom-sidebar-show-hide-button.toggled-show {\n -webkit-mask-position: -296px -76px; /* <| */\n transform: rotate(90deg);\n}\n\n.shadow-split-widget button.bottom-sidebar-show-hide-button.toggled-hide {\n -webkit-mask-position: -264px -76px; /* >| */\n transform: rotate(90deg);\n}\n\n/*# sourceURL=ui/splitWidget.css */";Runtime.cachedResources["ui/toolbar.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n flex: none;\n padding: 0 2px;\n}\n\n.toolbar-shadow {\n position: relative;\n white-space: nowrap;\n height: 26px;\n overflow: hidden;\n z-index: 12;\n display: flex;\n flex: none;\n align-items: center;\n}\n\n.toolbar-shadow.wrappable {\n flex-wrap: wrap;\n}\n\n.toolbar-shadow.wrappable-reverse {\n flex-direction: row-reverse;\n}\n\n.toolbar-shadow.vertical {\n flex-direction: column;\n height: auto;\n width: 26px;\n}\n\n.toolbar-item {\n position: relative;\n display: flex;\n background-color: transparent;\n flex: none;\n align-items: center;\n justify-content: center;\n padding: 0;\n height: 26px;\n border: none;\n color: #5a5a5a;\n}\n\n.toolbar-dropdown-arrow {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n -webkit-mask-position: -18px -96px;\n background-color: #6D6D6D;\n width: 12px;\n height: 12px;\n display: inline-block;\n pointer-events: none;\n margin: auto 0;\n flex: none;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n .toolbar-dropdown-arrow {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n }\n} /* media */\n\n/* Toolbar item */\n\n.toolbar-button {\n white-space: nowrap;\n overflow: hidden;\n min-width: 28px;\n background: transparent;\n}\n\n.toolbar-text {\n margin: 0 5px;\n flex: none;\n color: #5a5a5a;\n}\n\n.toolbar-has-dropdown {\n justify-content: space-between;\n}\n\n.toolbar-has-dropdown .toolbar-text {\n margin: 0 4px 0 0;\n text-overflow: ellipsis;\n flex: auto;\n overflow: hidden;\n text-align: right;\n color: #333 !important;\n}\n\n.toolbar-button .toolbar-dropdown-arrow {\n background-color: #333 !important;\n}\n\n.toolbar-has-glyph .toolbar-text {\n margin-left: 0;\n}\n\n.toolbar-button:not(.toolbar-has-glyph):not(.toolbar-has-dropdown):not(.menu-toolbar-item) {\n font-weight: bold;\n}\n\n.toolbar-render-as-links * {\n font-weight: initial;\n color: rgb(17, 85, 204);\n text-decoration: underline;\n cursor: pointer;\n}\n\n:not(.toolbar-render-as-links) .toolbar-button:not(.toolbar-has-glyph):not(.toolbar-has-dropdown):not(.menu-toolbar-item).hover {\n background-color: #f3f3f3;\n}\n\n.toolbar-glyph {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n background-color: #5a5a5a;\n width: 28px;\n height: 24px;\n flex: none;\n transform: translateX(-2px);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.toolbar-glyph {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n/* Button */\n\n.toolbar-button:disabled {\n opacity: 0.5;\n}\n\n:not(.toolbar-render-as-links) .toolbar-button:enabled.hover:not(:active) .toolbar-glyph {\n background-color: #333;\n}\n\n:not(.toolbar-render-as-links) .toolbar-button:enabled.hover:not(:active) .toolbar-text {\n color: #333;\n}\n\n.toolbar-button.toolbar-state-on .toolbar-glyph,\n.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled.hover:not(:active),\n.-theme-selection-color {\n background-color: hsl(218, 81%, 59%);\n}\n\n.toolbar-button.toolbar-state-on .toolbar-text,\n.-theme-selection-color {\n color: hsl(218, 81%, 59%);\n}\n\n.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled.hover .toolbar-glyph {\n background-color: white;\n}\n\n.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled.hover .toolbar-text {\n color: white;\n}\n\n.toolbar-button.toolbar-state-on:enabled.hover:not(:active) .toolbar-glyph,\n.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:active.hover,\n.-theme-selection-color {\n background-color: hsl(218, 96%, 54%);\n}\n\n.toolbar-button.toolbar-state-on:enabled.hover:not(:active) .toolbar-text,\n.-theme-selection-color {\n color: hsl(218, 96%, 54%);\n}\n\n.toolbar-toggled-gray .toolbar-button.toolbar-state-on {\n background-color: #f3f3f3 !important;\n}\n\n/* Checkbox */\n\n.toolbar-item.checkbox {\n padding: 0 5px 0 2px;\n}\n\n.toolbar-item.checkbox.hover {\n color: #333;\n}\n\n/* Select */\n\n.toolbar-select-container {\n display: inline-flex;\n flex-shrink: 0;\n margin-right: 6px;\n}\n\nselect.toolbar-item {\n min-width: 48px;\n -webkit-appearance: none;\n border: 0;\n border-radius: 0;\n padding: 0 15px 0 5px;\n margin-right: -10px;\n position: relative;\n}\n\n/* Input */\n\ninput.toolbar-item {\n width: 200px;\n height: 20px;\n padding: 3px;\n margin: 1px 3px;\n background-color: white;\n border: solid 1px #d8d8d8;\n}\n\ninput.toolbar-item:focus,\ninput.toolbar-item.hover {\n border: solid 1px rgb(202, 202, 202);\n}\n\n/* Separator */\n\n.toolbar-divider {\n background-color: #ccc;\n width: 1px;\n margin: 5px 4px;\n height: 16px;\n}\n\n.toolbar-spacer {\n flex: auto;\n}\n\n/* Long click */\n\n.long-click-glyph {\n position: absolute;\n background-color: #5a5a5a;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-position: -290px -46px;\n -webkit-mask-size: 352px 168px;\n width: 28px;\n height: 24px;\n top: 0;\n left: 0;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.long-click-glyph {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.toolbar-button.emulate-active {\n background-color: rgb(163, 163, 163);\n}\n\n.toolbar-shadow.floating {\n flex-direction: column;\n height: auto;\n background-color: white;\n border: 1px solid #ccc;\n margin-top: -1px;\n width: 28px;\n left: -2px;\n}\n\n/* Predefined items */\n\n.dock-toolbar-item-undock.toolbar-glyph {\n -webkit-mask-position: 0 -48px;\n}\n\n.dock-toolbar-item-bottom.toolbar-glyph {\n -webkit-mask-position: -32px -24px;\n}\n\n.dock-toolbar-item-right.toolbar-glyph {\n -webkit-mask-position: -256px -48px;\n}\n\n.menu-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -192px -24px;\n}\n\n.node-search-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -320px -120px;\n}\n\n.delete-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px 0;\n}\n\n.clear-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -64px 0;\n}\n\n.refresh-toolbar-item.toolbar-glyph {\n -webkit-mask-position: 0 0;\n}\n\n.visibility-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -96px 0;\n}\n\n.large-list-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -224px 0;\n}\n\n.record-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -288px 0;\n}\n\n.toolbar-state-on .record-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -288px -24px;\n}\n\n.camera-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -96px -24px;\n}\n\n.step-in-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -64px -72px;\n}\n\n.step-out-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -96px -72px;\n}\n\n.step-over-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px -72px;\n}\n\n.play-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -64px -48px;\n}\n\n.play-backwards-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -64px -48px;\n transform: scaleX(-1);\n}\n\n.stop-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -96px -48px;\n}\n\n.pause-on-exceptions-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -256px 0;\n}\n\n.pause-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -32px -72px;\n}\n\n.toolbar-state-on .pause-toolbar-item.toolbar-glyph {\n -webkit-mask-position: 0 -72px;\n}\n\n.toolbar-state-on .breakpoint-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -32px 0;\n}\n\n.breakpoint-toolbar-item.toolbar-glyph {\n -webkit-mask-position: 0 -24px;\n}\n\n.notification-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -32px -120px;\n}\n\n.format-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -256px -24px;\n}\n\n.garbage-collect-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px -24px;\n}\n\n.filter-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -32px -48px;\n}\n\n.waterfall-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px -48px;\n}\n\n.pan-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -98px -120px;\n}\n\n.center-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px -120px;\n}\n\n.rotate-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -160px -120px;\n}\n\n.pin-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -256px -120px;\n}\n\n.animation-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -192px -120px;\n}\n\n.eyedropper-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -288px -120px;\n}\n\n.add-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -224px -120px;\n}\n\n.toolbar-state-pause-outline .animation-control-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -320px 0px;\n}\n\n.toolbar-state-replay-outline .animation-control-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -320px -24px;\n background-color: rgb(66, 129, 235) !important;\n}\n\n.toolbar-state-play-outline .animation-control-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -320px -48px;\n background-color: rgb(66, 129, 235) !important;\n}\n\n.background-color-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -96px -144px;\n}\n\n.foreground-color-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -128px -144px;\n}\n\n.layout-editor-toolbar-item.toolbar-glyph {\n -webkit-mask-position: 0 -144px;\n}\n\n.block-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -32px -144px;\n}\n\n.phone-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -320px -96px;\n}\n\n.rotate-screen-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -192px -144px;\n}\n\n.enter-fullscreen-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -256px -96px;\n}\n\n.responsive-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -288px -96px;\n}\n\n.frame-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -256px -144px;\n}\n\n.domain-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -160px -144px;\n}\n\n.folder-toolbar-item.toolbar-glyph {\n -webkit-mask-position: -224px -144px;\n}\n\n.goto-source-toolbar-item.toolbar-glyph {\n -webkit-mask-position: 0 -120px;\n}\n\n.toolbar-state-on .record-toolbar-item.toolbar-glyph,\n.toolbar-state-active .filter-toolbar-item.toolbar-glyph,\n.toolbar-state-active .block-toolbar-item.toolbar-glyph {\n background-color: rgb(216, 0, 0) !important;\n}\n\n:host-context(.-theme-with-dark-background) .toolbar-state-active .filter-toolbar-item.toolbar-glyph,\n:host-context(.-theme-with-dark-background) .toolbar-state-active .block-toolbar-item.toolbar-glyph,\n:host-context(.-theme-with-dark-background) .toolbar-state-on .record-toolbar-item.toolbar-glyph {\n background-color: hsl(0, 100%, 65%) !important;\n}\n\n/*# sourceURL=ui/toolbar.css */";Runtime.cachedResources["ui/suggestBox.css"]="/*\n * Copyright (C) 2011 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n:host {\n position: absolute;\n background-color: transparent;\n z-index: 1000;\n pointer-events: none;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n}\n\n.suggest-box-left-spacer {\n flex: 0 1 auto;\n}\n\n.suggest-box-horizontal {\n display: flex;\n flex-direction: column;\n flex: 0 0 auto;\n max-width: 300px;\n}\n\n.suggest-box-top-spacer {\n flex: auto;\n}\n\n:host(.under-anchor) .suggest-box-top-spacer,\n:host(:not(.under-anchor)) .suggest-box-bottom-spacer {\n flex: 0 0 auto;\n}\n\n.suggest-box-container {\n display: flex;\n flex-direction: row;\n}\n\n.suggest-box {\n background-color: #FFFFFF;\n border: 1px solid rgb(66%, 66%, 66%);\n pointer-events: auto;\n margin-left: -3px;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n flex: 0 0 auto;\n border-radius: 5px 5px 5px 0;\n}\n\n:host(.under-anchor) .suggest-box {\n border-radius: 0 5px 5px 5px;\n}\n\n.suggest-box .suggest-box-content-item {\n padding: 1px;\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid transparent;\n flex: 0 0 auto;\n padding-right: 0;\n white-space: nowrap;\n}\n\n.suggest-box .suggest-box-content-item.additional {\n background-color: #f9f9f9;\n}\n\n.suggest-box .suggest-box-content-item.additional::before {\n display: inline-block;\n content: \"\";\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n width: 10px;\n height: 10px;\n position: relative;\n top: 2px;\n margin-right: 4px;\n background-position: -192px -96px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.suggest-box .suggest-box-content-item.additional::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.suggest-box .suggest-box-content-item .prefix {\n font-weight: bold;\n}\n\n.suggest-box .suggest-box-content-item .spacer {\n display: inline-block;\n width: 20px;\n}\n\n.suggest-box .suggest-box-content-item.selected {\n background-color: rgba(56, 121, 217, 0.1);\n}\n\n.suggest-box .suggest-box-content-item:hover:not(.selected) {\n border: 1px solid rgb(204, 204, 204);\n}\n\n.suggest-box .details-popup {\n padding: 17px;\n pointer-events: auto;\n margin-left: 3px;\n max-width: 750px;\n word-wrap: normal;\n}\n\n.suggest-box .details-popup .description {\n margin-top: 22px;\n color: #808080;\n}\n\n/*# sourceURL=ui/suggestBox.css */";Runtime.cachedResources["ui/tabbedPane.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n * Copyright (C) 2011 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.\n * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.tabbed-pane {\n flex: auto;\n overflow: hidden;\n}\n\n.tabbed-pane-content {\n position: relative;\n overflow: auto;\n flex: auto;\n display: flex;\n flex-direction: column;\n}\n\n.tabbed-pane-content.has-no-tabs {\n background-color: lightgray;\n}\n\n.tabbed-pane-placeholder {\n font-size: 14px;\n text-align: center;\n margin-top: 20px;\n text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;\n}\n\n.tabbed-pane-header {\n display: flex;\n flex: 0 0 27px;\n border-bottom: 1px solid #ccc;\n overflow: visible;\n width: 100%;\n background-color: #f3f3f3;\n}\n\n.tabbed-pane-header-contents {\n flex: auto;\n pointer-events: none;\n margin-left: 5px;\n position: relative;\n}\n\n.tabbed-pane-header-contents > * {\n pointer-events: initial;\n}\n\n.tabbed-pane-header-tab-icon {\n margin-right: 2px;\n}\n\n.tabbed-pane-header-tab {\n float: left;\n margin-top: 2px;\n padding: 2px 4px 2px 4px;\n height: 24px;\n border: 1px solid transparent;\n border-bottom: none;\n line-height: 15px;\n white-space: nowrap;\n cursor: default;\n display: flex;\n align-items: center;\n color: #5a5a5a;\n}\n\n.tabbed-pane-header-tab:hover,\n.tabbed-pane-header-tab.selected:hover {\n color: #333;\n background-color: #e5e5e5;\n}\n\n.tabbed-pane-header-tab-title {\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.tabbed-pane-header-tab.measuring {\n visibility: hidden;\n}\n\n.tabbed-pane-header-tab.selected {\n border: 1px solid #ccc;\n border-bottom: none;\n color: #333;\n}\n\n.tabbed-pane-header-tab.selected {\n background-color: white;\n border-top-color: #ccc;\n}\n\n.tabbed-pane-header-tab.dragging {\n position: relative;\n box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37);\n background-color: #e5e5e5;\n}\n\n.tabbed-pane-header-tab .tabbed-pane-close-button {\n display: inline-block;\n position: relative;\n top: 2px;\n left: 1px;\n margin-left: 2px;\n margin-top: -3px;\n visibility: hidden;\n}\n\n.tabbed-pane-header-tab:hover .tabbed-pane-close-button,\n.tabbed-pane-header-tab.selected .tabbed-pane-close-button {\n visibility: visible;\n}\n\n.tabbed-pane-header-tabs-drop-down-container {\n float: left;\n position: relative;\n vertical-align: bottom;\n line-height: 24px;\n opacity: 0.8;\n color: inherit;\n font-size: 133%;\n cursor: pointer;\n}\n\n.tabbed-pane-header-tabs-drop-down-container > .glyph {\n height: 26px;\n background-color: hsla(0,0%,20%,1);\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-position: -68px -143px;\n -webkit-mask-size: 352px 168px;\n width: 24px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.tabbed-pane-header-tabs-drop-down-container > .glyph {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.tabbed-pane-header-tabs-drop-down-container:hover {\n background-color: rgb(229, 229, 229);\n}\n\n.tabbed-pane-header-tabs-drop-down-container.measuring {\n visibility: hidden;\n}\n\n.tabbed-pane-header-tabs-drop-down-container:hover {\n opacity: 1.0;\n}\n\n.tabbed-pane-header-tabs-drop-down-container:active {\n opacity: 0.8;\n}\n\n/* Web page style */\n\n.tabbed-pane-shadow.vertical-tab-layout {\n flex-direction: row !important;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header {\n background-color: transparent;\n border: none transparent !important;\n width: auto;\n flex: 0 0 auto;\n flex-direction: column;\n padding-top: 10px;\n overflow: hidden;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-content {\n padding: 10px 10px 10px 0;\n overflow-x: hidden;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-contents {\n margin: 0;\n flex: none;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tabs {\n display: flex;\n flex-direction: column;\n width: 120px;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab {\n background-color: transparent;\n border: none transparent;\n font-weight: normal;\n text-shadow: none;\n color: #777;\n height: 26px;\n padding-left: 10px;\n border-left: 6px solid transparent;\n margin: 0;\n display: flex;\n align-items: center;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab:not(.selected) {\n cursor: pointer !important;\n}\n\n.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab.selected {\n color: inherit;\n border: none transparent;\n border-left: 6px solid #666;\n}\n\n.tabbed-pane-tab-slider,\n.-theme-selection-color {\n height: 2px;\n position: absolute;\n bottom: -1px;\n background-color: #3E82F7;\n left: 0;\n z-index: 50;\n transform-origin: 0 100%;\n transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);\n visibility: hidden;\n border-top: 1px solid hsl(218, 82%, 78%);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n .tabbed-pane-tab-slider {\n border-top: none;\n }\n}\n\n.tabbed-pane-tab-slider.enabled {\n visibility: visible;\n}\n\n.tabbed-pane-header-tab.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.tabbed-pane-header.tabbed-pane-no-header-background {\n background-color: transparent;\n}\n\n/*# sourceURL=ui/tabbedPane.css */";Runtime.cachedResources["ui/textButton.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n background-image: linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));\n border: 1px solid hsla(0, 0%, 0%, 0.25);\n border-radius: 2px;\n box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.08), inset 0 1px 2px hsla(0, 100%, 100%, 0.75);\n color: hsl(0, 0%, 27%);\n font-size: 12px;\n margin: 0 1px 0 0;\n text-shadow: 0 1px 0 hsl(0, 0%, 94%);\n min-height: 2em !important;\n padding-left: 10px;\n padding-right: 10px;\n -webkit-user-select: none;\n flex: none;\n}\n\n:host-context(body.inactive),\n:host(:disabled) {\n background-image: linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);\n border-color: rgba(80, 80, 80, 0.2);\n box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.75);\n color: #aaa;\n}\n\n:host(:not(:disabled):hover) {\n background-image: linear-gradient(hsl(0, 0%, 94%), hsl(0, 0%, 94%) 38%, hsl(0, 0%, 88%));\n border-color: hsla(0, 0%, 0%, 0.3);\n box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.12), inset 0 1px 2px hsla(0, 100%, 100%, 0.95);\n color: hsl(0, 0%, 0%);\n}\n\n:host(:not(:disabled):active) {\n background-image: linear-gradient(hsl(0, 0%, 91%), hsl(0, 0%, 91%) 38%, hsl(0, 0%, 84%));\n box-shadow: none;\n text-shadow: none;\n}\n\n:host(:not(:disabled):focus) {\n -webkit-transition: border-color 200ms;\n border-color: rgb(77, 144, 254);\n outline: none;\n}\n\n/*# sourceURL=ui/textButton.css */";Runtime.cachedResources["ui/textPrompt.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.text-prompt-editing {\n -webkit-user-select: text;\n box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;\n outline: 1px solid rgb(66%, 66%, 66%) !important;\n background-color: white;\n -webkit-user-modify: read-write-plaintext-only;\n text-overflow: clip !important;\n padding-left: 2px;\n margin-left: -2px;\n padding-right: 2px;\n margin-right: -2px;\n margin-bottom: -1px;\n padding-bottom: 1px;\n opacity: 1.0 !important;\n}\n\n.text-prompt-editing,\n.text-prompt-editing ::content * {\n color: #222 !important;\n text-decoration: none !important;\n -webkit-user-modify: read-write-plaintext-only;\n white-space: pre;\n}\n\n::content .auto-complete-text,\n.text-prompt-editing ::content .auto-complete-text {\n color: rgb(128, 128, 128) !important;\n -webkit-user-select: none;\n -webkit-user-modify: read-only;\n}\n\n.text-prompt-editing ::content br {\n display: none;\n}\n\n/*# sourceURL=ui/textPrompt.css */";Runtime.cachedResources["ui/tooltip.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.tooltip {\n background: hsl(0, 0%, 95%);\n border-radius: 2px;\n color: hsl(0, 0%, 20%);\n padding: 5px 8px;\n font-size: 11px;\n line-height: 14px;\n display: flex;\n align-items: center;\n -webkit-filter: drop-shadow(0 1px 2px hsla(0, 0%, 0%, 0.3));\n border: 1px solid hsla(0, 0%, 0%, 0.1);\n background-clip: padding-box;\n box-sizing: border-box;\n position: absolute;\n visibility: hidden;\n transition: visibility 0s 100ms, opacity 150ms cubic-bezier(0, 0, .2, 1);\n z-index: 20001;\n top: 0;\n left: 0;\n opacity: 0;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.tooltip.shown {\n visibility: visible;\n transition-delay: 600ms;\n opacity: 1;\n}\n\n.tooltip.shown.instant {\n transition-delay: 0s;\n}\n\n.tooltip-shortcut {\n color: hsl(0, 0%, 45%);\n display: inline-block;\n margin-left: 8px;\n flex: 0 0 auto;\n}\n\n/*# sourceURL=ui/tooltip.css */";Runtime.cachedResources["ui/treeoutline.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n flex: 1 1;\n padding: 2px 0 0 0;\n}\n\n.tree-outline-disclosure:not(.tree-outline-disclosure-hide-overflow) {\n min-width: 100%;\n display: inline-block;\n}\n\n.tree-outline {\n padding: 0 0 4px 4px;\n margin: 0;\n z-index: 0;\n position: relative;\n}\n\n.tree-outline li.hovered:not(.selected) .selection {\n display: block;\n left: 3px;\n right: 3px;\n background-color: rgba(56, 121, 217, 0.1);\n border-radius: 5px;\n}\n\n.tree-outline li .selection {\n display: none;\n z-index: -1;\n margin-left: -10000px;\n}\n\n.tree-outline li.selected .selection {\n display: block;\n background-color: #ddd;\n}\n\n.tree-outline li.in-clipboard .highlight {\n outline: 1px dotted darkgrey;\n}\n\n.tree-outline li.elements-drag-over .selection {\n display: block;\n margin-top: -2px;\n border-top: 2px solid rgb(56, 121, 217);\n}\n\nol.tree-outline:focus li.selected .selection {\n background-color: rgb(56, 121, 217);\n}\n\nol.tree-outline:focus li.parent.selected::before {\n background-color: white;\n}\n\nol.tree-outline,\n.tree-outline ol {\n list-style-type: none;\n}\n\n.tree-outline-no-padding {\n padding: 0;\n}\n\n.tree-outline ol {\n padding-left: 12px;\n}\n\n.tree-outline li {\n text-overflow: ellipsis;\n white-space: nowrap;\n position: relative;\n display: flex;\n align-items: center;\n min-height: 16px;\n}\n\nol.tree-outline:focus li.selected {\n color: white;\n}\n\nol.tree-outline:focus li.selected * {\n color: inherit;\n}\n\n.tree-outline li::before {\n -webkit-user-select: none;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n content: \"aa\";\n color: transparent;\n text-shadow: none;\n margin-right: -2px;\n height: 12px;\n}\n\n.tree-outline li:not(.parent)::before {\n background-color: transparent;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.tree-outline li::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.tree-outline li::before {\n -webkit-mask-position: -4px -96px;\n background-color: rgb(110, 110, 110);\n}\n\n.tree-outline li.parent.expanded::before {\n -webkit-mask-position: -20px -96px;\n}\n\n.tree-outline ol.children {\n display: none;\n}\n\n.tree-outline ol.children.expanded {\n display: block;\n}\n\n/*# sourceURL=ui/treeoutline.css */";Runtime.cachedResources["components/breakpointsList.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.sidebar-pane .breakpoint-condition {\n display: block;\n margin-top: 4px;\n margin-bottom: 4px;\n margin-left: 23px;\n margin-right: 8px;\n}\n\n.breakpoint-list .editing.being-edited {\n overflow: hidden;\n white-space: nowrap;\n}\n\n#breakpoint-condition-input {\n display: block;\n margin-left: 0;\n margin-right: 0;\n outline: none !important;\n border: 1px solid rgb(66%, 66%, 66%);\n}\n\nol.breakpoint-list {\n -webkit-padding-start: 0;\n list-style: none;\n margin: 0;\n padding-bottom: 3px;\n}\n\n.breakpoints-list-deactivated {\n background-color: #eee;\n opacity: 0.3;\n}\n\n.breakpoint-list li {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n padding: 2px 0;\n}\n\n.breakpoint-list li:hover {\n background-color: #eee;\n}\n\n.breakpoint-list .source-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin: 2px 0 0 20px;\n}\n\n.sidebar-pane .breakpoint-hit {\n background-color: rgb(255, 255, 194);\n}\n\n.-theme-with-dark-background .sidebar-pane .breakpoint-hit {\n background-color: hsl(46, 98%, 22%);\n color: #ccc;\n}\n\nli.breakpoint-hit .breakpoint-hit-marker {\n background-color: rgb(255, 255, 194);\n height: 18px;\n left: 0;\n margin-top: -16px;\n position: absolute;\n right: 0;\n z-index: -1;\n}\n\n.event-listener-breakpoints {\n margin-top: 0;\n padding: 2px 6px;\n list-style: none;\n min-height: 18px;\n}\n\n.event-listener-breakpoints ol {\n display: none;\n margin: 0;\n -webkit-padding-start: 12px;\n list-style: none;\n}\n\n.event-listener-breakpoints ol.expanded {\n display: block;\n}\n\n.event-listener-breakpoints li {\n margin-left: 12px;\n text-overflow: ellipsis;\n -webkit-user-select: text;\n cursor: default;\n}\n\n.event-listener-breakpoints li.parent {\n margin-left: 1px;\n}\n\n.event-listener-breakpoints li.parent::before {\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n content: \"a\";\n width: 8px;\n float: left;\n margin: 2px 2px 0 -2px;\n color: transparent;\n text-shadow: none;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.event-listener-breakpoints li.parent::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.event-listener-breakpoints li.parent::before {\n background-position: -4px -96px;\n}\n\n.event-listener-breakpoints li.parent.expanded::before {\n background-position: -20px -96px;\n}\n\n.event-listener-breakpoints .children li {\n margin-left: 12px;\n}\n\n.async-operations li > label {\n float: left;\n}\n\n.async-operations li > div {\n float: right;\n margin: 2px 3px 0 2px;\n}\n\n.dom-breakpoints-list > li {\n display: flex;\n}\n\n.dom-breakpoints-list .dom-breakpoint > div {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/*# sourceURL=components/breakpointsList.css */";Runtime.cachedResources["components/customPreviewSection.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.custom-expandable-section {\n display: inline-flex;\n flex-direction: column;\n}\n\n.custom-expandable-section-header::before {\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n content: \"a\";\n width: 8px;\n margin-right: 4px;\n padding-right: 2px;\n color: transparent;\n text-shadow: none;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n .custom-expandable-section-header::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n }\n} /* media */\n\n\n.custom-expandable-section-header::before {\n background-position: -4px -96px;\n}\n\n.custom-expandable-section-header.expanded::before {\n background-position: -20px -96px;\n}\n\n.custom-expandable-section-standard-section {\n display: inline-flex;\n}\n/*# sourceURL=components/customPreviewSection.css */";Runtime.cachedResources["components/eventListenersView.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.tree-outline-disclosure li {\n padding: 2px 0 0 5px;\n overflow: hidden;\n display: list-item;\n min-height: 16px;\n}\n\n.tree-outline-disclosure > li {\n border-top: 1px solid #f0f0f0;\n}\n\n.tree-outline-disclosure > li:first-of-type {\n border-top: none;\n}\n\n.tree-outline-disclosure {\n padding-left: 0 !important;\n padding-right: 3px;\n}\n\n.tree-outline-disclosure li.parent::before {\n top: 0 !important;\n}\n\n.tree-outline-disclosure .name {\n color: rgb(136, 19, 145);\n}\n\n.event-listener-tree-subtitle {\n float: right;\n margin-left: 5px;\n}\n\n.event-listener-delete-button {\n padding: 0 3px;\n background-color: #f2f2f2;\n border-radius: 3px;\n border: 1px solid #c3c3c3;\n margin-left: 10px;\n display: none;\n cursor: pointer;\n}\n\n.event-listener-delete-button:hover {\n background-color: #e0e0e0;\n}\n\n.tree-outline-disclosure li:hover .event-listener-delete-button {\n display: inline;\n}\n\n/*# sourceURL=components/eventListenersView.css */";Runtime.cachedResources["components/domUtils.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n display: inline;\n}\n\n.node-link {\n cursor: pointer;\n display: inline;\n pointer-events: auto;\n}\n\n.stack-preview-async-description {\n padding: 3px 0 1px;\n font-style: italic;\n}\n\n.stack-preview-container .webkit-html-blackbox-link {\n opacity: 0.6;\n}\n\n.stack-preview-container > tr {\n height: 16px;\n line-height: 16px;\n}\n\n.stack-preview-container td {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.stack-preview-container .function-name {\n max-width: 80em;\n}\n\n.node-label-name {\n color: rgb(136, 18, 128);\n}\n\n.node-label-id {\n color: rgb(26, 26, 166);\n}\n\n.node-label-class, .node-label-pseudo {\n color: rgb(153, 69, 0);\n}\n\n/*# sourceURL=components/domUtils.css */";Runtime.cachedResources["components/networkConditionsSettingsTab.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow:hidden;\n}\n\n.header {\n padding: 0 0 6px;\n border-bottom: 1px solid #EEEEEE;\n font-size: 18px;\n font-weight: normal;\n flex: none;\n}\n\n.add-conditions-button {\n flex: none;\n margin: 10px 0;\n min-width: 140px;\n align-self: flex-start;\n}\n\n.conditions-list {\n max-width: 500px;\n min-width: 340px;\n flex: auto;\n}\n\n.conditions-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n flex: auto 1 1;\n}\n\n.conditions-list-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: 0 0 70px;\n -webkit-user-select: none;\n color: #222;\n text-align: end;\n position: relative;\n}\n\n.conditions-list-title {\n text-align: start;\n flex: auto;\n display: flex;\n align-items: flex-start;\n}\n\n.conditions-list-title-text {\n overflow: hidden;\n flex: auto;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.conditions-list-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.conditions-list-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.conditions-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n}\n\n.conditions-edit-row input {\n width: 100%;\n text-align: inherit;\n}\n\n.conditions-edit-optional {\n position: absolute;\n bottom: -20px;\n right: 0;\n color: rgb(128, 128, 128);\n}\n\n/*# sourceURL=components/networkConditionsSettingsTab.css */";Runtime.cachedResources["components/objectPropertiesSection.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.object-properties-section .name {\n color: rgb(136, 19, 145);\n flex-shrink: 0;\n}\n\n.object-properties-section-separator {\n flex-shrink: 0;\n padding-right: 5px;\n}\n\n.object-properties-section-dimmed {\n opacity: 0.6;\n}\n\n.object-properties-section {\n padding: 0 0 0px 0px;\n color: rgb(33,33,33) !important;\n display: flex;\n flex-direction: column;\n}\n\n.object-properties-section li {\n -webkit-user-select: text;\n}\n\n.object-properties-section li::before {\n top: -1px;\n}\n\n.object-properties-section li.editing-sub-part {\n padding: 3px 6px 8px;\n margin: -1px -6px -8px -6px;\n text-overflow: clip;\n}\n\n.object-properties-section li.editing {\n margin-left: 10px;\n text-overflow: clip;\n}\n\n.tree-outline ol.title-less-mode {\n padding-left: 0px;\n}\n\n.object-properties-section .synthetic-property {\n font-style: italic;\n}\n\n.object-properties-section-root-element {\n display: flex;\n flex-direction: row;\n}\n\n.object-properties-section-root-element::before {\n -webkit-mask-position: -4px -97px !important;\n}\n\n.object-properties-section-root-element.expanded::before {\n -webkit-mask-position: -20px -97px !important;\n}\n\n/*# sourceURL=components/objectPropertiesSection.css */";Runtime.cachedResources["components/objectValue.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.object-value-scientific-notation-exponent {\n flex-shrink: 0;\n}\n\n.object-value-scientific-notation-mantissa {\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 1;\n min-width: 1ex;\n}\n\n.object-value-scientific-notation-number {\n display: flex !important;\n}\n\n.object-value-node:hover {\n background-color: rgba(56, 121, 217, 0.1);\n}\n\n.object-value-function::before {\n content: \"function\";\n color: rgb(170, 13, 145);\n padding-right: 5px;\n}\n\n.object-value-function {\n font-style: italic;\n}\n\n.object-value-function.linkified:hover {\n background-color: rgba(0, 0, 0, 0.1);\n cursor: pointer;\n}\n\n.object-value-object,\n.object-value-map,\n.object-value-set,\n.object-value-iterator,\n.object-value-generator,\n.object-value-node,\n.object-value-array {\n position: relative;\n vertical-align: top;\n color: inherit;\n display: inline-block;\n}\n\n.object-value-number,\n.object-value-boolean {\n color: rgb(28, 0, 207);\n}\n\n.object-value-string,\n.object-value-regexp,\n.object-value-symbol {\n color: rgb(196, 26, 22);\n white-space: pre;\n unicode-bidi: -webkit-isolate;\n}\n\n.object-value-node {\n color: rgb(136, 18, 128);\n}\n\n.object-value-null,\n.object-value-undefined {\n color: rgb(128, 128, 128);\n}\n\n.object-value {\n text-overflow: ellipsis;\n overflow: hidden;\n -webkit-user-select: text;\n}\n\n.object-value-calculate-value-button:hover {\n text-decoration: underline;\n}\n\n.object-value-object .section,\n.object-formatted-map .section,\n.object-value-set .section,\n.object-value-iterator .section,\n.object-value-generator .section,\n.object-value-node .section,\n.object-value-array .section {\n position: static;\n}\n.object-value-object .section > .header::before {\n margin-top: 0;\n}\n\n\n.object-value-object .properties-tree,\n.object-value-map .properties-tree,\n.object-value-set .properties-tree,\n.object-value-iterator .properties-tree,\n.object-value-generator .properties-tree,\n.object-value-node .properties-tree {\n padding-left: 0 !important;\n}\n\n.object-value-preview-node,\n.section .object-value-node {\n color: rgb(136, 18, 128);\n}\n\n.object-properties-section-custom-section {\n display: inline-flex;\n flex-direction: column;\n}\n\n.-theme-with-dark-background .object-value-number,\n:host-context(.-theme-with-dark-background) .object-value-number,\n.-theme-with-dark-background .object-value-boolean,\n:host-context(.-theme-with-dark-background) .object-value-boolean {\n color: hsl(252, 100%, 75%);\n}\n\n/*# sourceURL=components/objectValue.css */";Runtime.cachedResources["main/errorWarningCounter.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n cursor: pointer;\n padding: 0 2px;\n min-width: 26px;\n}\n\n:host:hover {\n color: #333;\n}\n\n.counter-item {\n margin-left: 6px;\n}\n\n.counter-item label {\n cursor: inherit;\n}\n\n.counter-item.counter-item-first {\n margin-left: 0;\n}\n\n/*# sourceURL=main/errorWarningCounter.css */";Runtime.cachedResources["main/remoteDebuggingTerminatedScreen.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.widget {\n padding: 25px;\n}\n\n.message {\n font-size: larger;\n white-space: pre;\n margin: 5px;\n}\n\n.reason {\n color: #8b0000;\n}\n\n/*# sourceURL=main/remoteDebuggingTerminatedScreen.css */";Runtime.cachedResources["main/renderingOptions.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n padding: 12px;\n }\n\nlabel {\n margin: 0px 0px 10px 0px;\n flex: none;\n}\n\n.media-row {\n margin-left: 25px;\n}\n\n.panel-section-separator {\n height: 1px;\n margin-bottom: 10px;\n background: #f0f0f0;\n flex: none;\n}\n\n/*# sourceURL=main/renderingOptions.css */";Runtime.cachedResources["main/targetCrashedScreen.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.widget {\n padding: 25px;\n}\n\n.message {\n font-size: larger;\n white-space: pre;\n margin: 5px;\n}\n\n/*# sourceURL=main/targetCrashedScreen.css */";Runtime.cachedResources["emulation/devicesSettingsTab.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.devices-settings-tab .settings-tab.help-content {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n height: 100%;\n margin: 0;\n}\n\n.devices-settings-tab .devices-title {\n font-size: 120%;\n color: #222;\n flex: none;\n}\n\n.devices-settings-tab .devices-button-row {\n flex: none;\n display: flex;\n}\n\n.devices-settings-tab .devices-button-row button {\n margin-right: 10px;\n min-width: 120px;\n flex: none;\n}\n\n.devices-settings-tab .devices-list {\n width: 350px;\n margin-top: 10px;\n}\n\n.devices-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n flex: auto 1 1;\n cursor: pointer;\n}\n\n.devices-list-checkbox {\n height: 12px;\n width: 12px;\n margin: 3px 5px 2px 2px;\n flex: none;\n pointer-events: none;\n}\n\n.devices-list-title {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: auto;\n -webkit-user-select: none;\n color: #222;\n}\n\n.devices-edit-fields {\n flex: auto;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n margin-bottom: 5px;\n}\n\n.devices-edit-fields input {\n flex: auto;\n margin: 8px 5px 0 5px;\n height: 22px;\n border: 1px solid rgb(213, 213, 213);\n border-radius: 2px;\n color: #444444;\n padding: 3px;\n}\n\n.devices-edit-fields .device-edit-fixed {\n flex: 0 0 140px;\n}\n\n.devices-edit-fields select {\n margin: 8px 5px 0 5px;\n}\n\n/*# sourceURL=emulation/devicesSettingsTab.css */";Runtime.cachedResources["emulation/deviceModeToolbar.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.device-mode-size-input {\n background: hsl(0, 0%, 100%);\n border: none;\n padding: 2px 0;\n width: 34px !important;\n margin: 0 2px;\n text-align: center;\n box-shadow: 0px 0px 1px 0px hsla(0, 0%, 0%, 0.13);\n border-radius: 1px;\n height: 18px;\n color: hsl(210, 16%, 22%);\n}\n\n.device-mode-size-input:focus::-webkit-input-placeholder {\n color: transparent;\n}\n\n.device-mode-size-input:disabled {\n background: transparent;\n box-shadow: none;\n -webkit-user-select: none;\n}\n\n.device-mode-x {\n margin: 0 1px;\n font-size: 16px;\n}\n\n.device-mode-empty-toolbar-element {\n width: 0;\n}\n\n/*# sourceURL=emulation/deviceModeToolbar.css */";Runtime.cachedResources["emulation/deviceModeView.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow: hidden;\n align-items: stretch;\n flex: auto;\n background-color: hsl(0, 0%, 98%);\n}\n\n.device-mode-toolbar {\n flex: none;\n background-color: hsl(0, 0%, 98%);\n border-bottom: 1px solid #ccc;\n display: flex;\n flex-direction: row;\n align-items: stretch;\n}\n\n.device-mode-toolbar .toolbar {\n overflow: hidden;\n flex: 0 100000 auto;\n padding: 0 5px;\n}\n\n.device-mode-toolbar .toolbar.device-mode-toolbar-fixed-size {\n flex: 0 1 auto;\n}\n\n.device-mode-toolbar-spacer {\n flex: 1 1 0;\n display: flex;\n flex-direction: row;\n overflow: hidden;\n}\n\n.device-mode-content-clip {\n overflow: hidden;\n flex: auto;\n}\n\n.device-mode-media-container {\n flex: none;\n overflow: hidden;\n box-shadow: inset 0 -1px #ccc;\n}\n\n.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-media-container {\n margin-bottom: 20px;\n}\n\n.device-mode-presets-container {\n flex: 0 0 20px;\n display: flex;\n}\n\n.device-mode-presets-container-inner {\n flex: auto;\n justify-content: center;\n position: relative;\n background-color: hsl(0, 0%, 90%);\n border: 2px solid hsl(0, 0%, 98%);\n border-bottom: 2px solid hsl(0, 0%, 98%);\n }\n\n.device-mode-presets-container:hover {\n transition: opacity 0.1s;\n transition-delay: 50ms;\n opacity: 1;\n}\n\n.device-mode-preset-bar-outer {\n pointer-events: none;\n display: flex;\n justify-content: center;\n}\n\n.device-mode-preset-bar {\n border-left: 2px solid hsl(0, 0%, 98%);\n border-right: 2px solid hsl(0, 0%, 98%);\n pointer-events: auto;\n text-align: center;\n flex: none;\n cursor: pointer;\n color: #5A5A5A;\n display: flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n margin-bottom: 1px;\n}\n\n.device-mode-preset-bar:hover {\n transition: background-color 0.1s;\n transition-delay: 50ms;\n background-color: #d6d6d6;\n}\n\n.device-mode-preset-bar > span {\n visibility: hidden;\n}\n\n.device-mode-preset-bar:hover > span {\n transition: visibility 0.1s;\n transition-delay: 50ms;\n visibility: visible;\n}\n\n.device-mode-content-area {\n flex: auto;\n position: relative;\n margin: 0;\n}\n\n.device-mode-screen-area {\n position: absolute;\n left: 0;\n right: 0;\n width: 0;\n height: 0;\n background-color: #171717;\n}\n\n.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area {\n box-shadow: hsl(240, 3%, 84%) 0 0 0 0.5px, hsla(0, 0%, 80%, 0.4) 0 0 20px;\n}\n\n.device-mode-screen-image {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n}\n\n.device-mode-resizer {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: background-color 0.1s ease, opacity 0.1s ease;\n}\n\n.device-mode-resizer:hover {\n background-color: hsla(0, 0%, 0%, 0.1);\n opacity: 1;\n}\n\n.device-mode-resizer > div {\n pointer-events: none;\n}\n\n.device-mode-right-resizer {\n top: 0;\n bottom: -1px;\n right: -20px;\n width: 20px;\n}\n\n.device-mode-left-resizer {\n top: 0;\n bottom: -1px;\n left: -20px;\n width: 20px;\n opacity: 0;\n}\n\n.device-mode-bottom-resizer {\n left: 0;\n right: -1px;\n bottom: -20px;\n height: 20px;\n}\n\n.device-mode-bottom-right-resizer {\n left: 0;\n top: 0;\n right: -20px;\n bottom: -20px;\n background-color: hsla(0, 0%, 0%, 0.02);\n}\n\n.device-mode-bottom-left-resizer {\n left: -20px;\n top: 0;\n right: 0;\n bottom: -20px;\n opacity: 0;\n}\n\n.device-mode-right-resizer > div {\n content: url(Images/resizeHorizontal.png);\n width: 6px;\n height: 26px;\n}\n\n.device-mode-left-resizer > div {\n content: url(Images/resizeHorizontal.png);\n width: 6px;\n height: 26px;\n}\n\n.device-mode-bottom-resizer > div {\n content: url(Images/resizeVertical.png);\n margin-bottom: -2px;\n width: 26px;\n height: 6px;\n}\n\n.device-mode-bottom-right-resizer > div {\n position: absolute;\n bottom: 3px;\n right: 3px;\n width: 13px;\n height: 13px;\n content: url(Images/resizeDiagonal.png);\n}\n\n.device-mode-bottom-left-resizer > div {\n position: absolute;\n bottom: 3px;\n left: 3px;\n width: 13px;\n height: 13px;\n content: url(Images/resizeDiagonal.png);\n transform: rotate(90deg);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n .device-mode-right-resizer > div {\n content: url(Images/resizeHorizontal_2x.png);\n }\n\n .device-mode-left-resizer > div {\n content: url(Images/resizeHorizontal_2x.png);\n }\n\n .device-mode-bottom-resizer > div {\n content: url(Images/resizeVertical_2x.png);\n }\n\n .device-mode-bottom-right-resizer > div {\n content: url(Images/resizeDiagonal_2x.png);\n }\n\n .device-mode-bottom-left-resizer > div {\n content: url(Images/resizeDiagonal_2x.png);\n }\n} /* media */\n\n.device-mode-page-area {\n position: absolute;\n left: 0;\n right: 0;\n width: 0;\n height: 0;\n display: flex;\n background-color: #fcfcfc;\n}\n\n.device-mode-ruler {\n position: absolute;\n overflow: visible;\n}\n\n.device-mode-ruler-top {\n height: 20px;\n right: 0;\n}\n\n.device-mode-ruler-left {\n width: 20px;\n bottom: 0;\n}\n\n.device-mode-ruler-content {\n pointer-events: none;\n position: absolute;\n left: -20px;\n top: -20px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-content {\n border-top: 1px solid transparent;\n right: 0;\n bottom: 20px;\n background-color: hsla(0, 0%, 98%, 0.9);\n}\n\n.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-top .device-mode-ruler-content {\n border-top: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-left .device-mode-ruler-content {\n border-left: 1px solid transparent;\n border-top: 1px solid transparent;\n right: 20px;\n bottom: 0;\n}\n\n.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-left .device-mode-ruler-content {\n border-left: 1px solid hsl(0, 0%, 50%);\n border-top: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-inner {\n position: absolute;\n}\n\n.device-mode-ruler-top .device-mode-ruler-inner {\n top: 0;\n bottom: 0;\n left: 20px;\n right: 0;\n border-bottom: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-left .device-mode-ruler-inner {\n left: 0;\n right: 0;\n top: 19px;\n bottom: 0;\n border-right: 1px solid hsl(0, 0%, 50%);\n background-color: hsla(0, 0%, 98%, 0.9);\n}\n\n.device-mode-ruler-marker {\n position: absolute;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker {\n width: 0;\n height: 5px;\n bottom: 0;\n border-right: 1px solid hsl(0, 0%, 50%);\n margin-right: -1px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-medium {\n height: 10px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-large {\n height: 15px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker {\n height: 0;\n width: 5px;\n right: 0;\n border-bottom: 1px solid hsl(0, 0%, 50%);\n margin-bottom: -1px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-medium {\n width: 10px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-large {\n width: 15px;\n}\n\n.device-mode-ruler-text {\n font-size: 11px;\n color: hsl(0, 0%, 50%);\n position: relative;\n pointer-events: auto;\n}\n\n.device-mode-ruler-text:hover {\n color: hsl(0, 0%, 10%);\n}\n\n.device-mode-ruler-top .device-mode-ruler-text {\n left: 2px;\n top: -2px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-text {\n left: -4px;\n top: -15px;\n transform: rotate(270deg);\n}\n\n/*# sourceURL=emulation/deviceModeView.css */";Runtime.cachedResources["emulation/mediaQueryInspector.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n/* Media query bars */\n\n.media-inspector-view {\n height: 50px;\n}\n\n.media-inspector-marker-container {\n height: 14px;\n margin: 2px 0;\n position: relative;\n}\n\n.media-inspector-bar {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n pointer-events: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n}\n\n.media-inspector-marker {\n flex: none;\n pointer-events: auto;\n margin: 1px 0;\n white-space: nowrap;\n z-index: auto;\n position: relative;\n}\n\n.media-inspector-marker-spacer {\n flex: auto;\n}\n\n.media-inspector-marker:hover {\n margin: -1px 0;\n opacity: 1;\n}\n\n.media-inspector-marker-max-width {\n background-color: hsl(207, 90%, 77%);\n border-right: 2px solid hsl(207, 90%, 61%);\n border-left: 2px solid hsl(207, 90%, 61%);\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-max-width:not(:hover) {\n background-color: hsl(199, 94%, 94%);\n}\n\n.media-inspector-marker-min-max-width {\n background-color: hsl(88, 50%, 76%);\n border-left: 2px solid #689F38;\n border-right: 2px solid hsl(92, 48%, 42%);\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-min-max-width:not(:hover) {\n background-color: hsl(125, 39%, 94%);\n}\n\n.media-inspector-marker-min-max-width:hover {\n z-index: 1;\n}\n\n.media-inspector-marker-min-width {\n background-color: hsl(36, 100%, 75%);\n flex: auto;\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-min-width:not(:hover) {\n background-color: hsl(37, 100%, 94%);\n}\n\n.media-inspector-marker-min-width-right {\n border-left: 2px solid hsl(30, 100%, 48%);\n}\n\n.media-inspector-marker-min-width-left {\n border-right: 2px solid hsl(30, 100%, 48%);\n}\n\n/* Media query labels */\n\n.media-inspector-marker:not(:hover) .media-inspector-marker-label-container {\n display: none;\n}\n\n.media-inspector-marker-label-container {\n position: absolute;\n z-index: 1;\n}\n\n.media-inspector-marker-label-container-left {\n left: -2px;\n}\n\n.media-inspector-marker-label-container-right {\n right: -2px;\n}\n\n.media-inspector-marker-label {\n color: #222;\n position: absolute;\n top: 1px;\n bottom: 0;\n font-size: 12px;\n pointer-events: none;\n}\n\n.media-inspector-label-right {\n right: 4px;\n}\n\n.media-inspector-label-left {\n left: 4px;\n}\n\n/*# sourceURL=emulation/mediaQueryInspector.css */";Runtime.cachedResources["emulation/sensors.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.sensors-view {\n padding: 12px;\n display: block;\n}\n\n.sensors-view label {\n margin-bottom: 10px;\n}\n\n.sensors-view input {\n text-align: right;\n width: 80px;\n}\n\n.sensors-view input:not(.error-input):enabled:focus,\n.sensors-view select:enabled:focus {\n border-color: rgb(77, 144, 254);\n outline: none;\n}\n\n.sensors-view input,\n.sensors-view select {\n border: 1px solid #bfbfbf;\n border-radius: 2px;\n box-sizing: border-box;\n color: #444;\n font: inherit;\n border-width: 1px;\n text-align: left;\n}\n\n.sensors-view input {\n min-height: 2em;\n padding: 3px;\n width: 100%;\n max-width: 100px;\n margin: -5px 10px 0px 0px;\n text-align: end;\n}\n\n.sensors-view input[readonly] {\n background-color: rgb(235, 235, 228);\n}\n\n.sensors-view fieldset {\n border: none;\n padding: 10px 0px;\n margin-left: 0;\n flex: 0 0 auto;\n margin: 0;\n}\n\n.sensors-view fieldset[disabled] {\n opacity: 0.5;\n}\n\n.sensors-view .field-error-message {\n display: none;\n}\n\n.sensors-view input:focus::-webkit-input-placeholder {\n color: transparent !important;\n}\n\n.sensors-view .chrome-select {\n width: 200px;\n}\n\n.sensors-group-title {\n width: 80px;\n line-height: 24px;\n}\n\n.sensors-group {\n display: flex;\n flex-wrap: wrap;\n margin-bottom: 10px;\n}\n\n.geo-fields {\n flex: 2 0 200px;\n}\n\n.latlong-group {\n display: flex;\n margin-bottom: 10px;\n}\n\n.latlong-title {\n width: 70px;\n}\n\n/* Device Orientation */\n\n.orientation-content {\n display: flex;\n flex-wrap: wrap;\n}\n\n.orientation-fields {\n margin-right: 10px;\n}\n\n.orientation-stage {\n -webkit-perspective: 700px;\n -webkit-perspective-origin: 50% 50%;\n width: 160px;\n height: 150px;\n background: linear-gradient(#E1F5FE 0%, #E1F5FE 64%, #b0Ebf3 64%, #DEF6F9 100%);\n transition: 0.2s ease opacity, 0.2s ease -webkit-filter;\n overflow: hidden;\n margin-bottom: 10px;\n}\n\n.orientation-stage.disabled {\n -webkit-filter: grayscale();\n opacity: 0.5;\n cursor: default !important;\n}\n\n.orientation-element,\n.orientation-element::before,\n.orientation-element::after\n{\n position: absolute;\n box-sizing: border-box;\n transform-style: preserve-3d;\n background: no-repeat;\n background-size: cover;\n backface-visibility: hidden;\n}\n\n.orientation-box {\n width: 66px;\n height: 122px;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n margin: auto;\n transform: rotate3d(1, 0, 0, 90deg);\n}\n\n.orientation-box.is-animating, .is-animating .orientation-layer {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\n}\n\n.orientation-layer {\n width: 100%;\n height: 100%;\n transform-style: preserve-3d;\n}\n\n.orientation-front,\n.orientation-back\n{\n width: 66px;\n height: 122px;\n border-radius: 8px;\n}\n\n.orientation-front {\n background-image: url(Images/accelerometer-front.png);\n}\n\n.orientation-back {\n transform: rotateY(180deg) translateZ(12px);\n background-image: url(Images/accelerometer-back.png);\n}\n\n\n.orientation-left,\n.orientation-right {\n width: 12px;\n height: 106px;\n top: 8px;\n background-position: center center;\n}\n\n.orientation-left {\n left: -12px;\n transform-origin: right center;\n transform: rotateY(-90deg);\n background-image: url(Images/accelerometer-left.png);\n}\n\n\n.orientation-right {\n right: -12px;\n transform-origin: left center;\n transform: rotateY(90deg);\n background-image: url(Images/accelerometer-right.png);\n}\n\n.orientation-left::before,\n.orientation-left::after,\n.orientation-right::before,\n.orientation-right::after\n{\n content: '';\n width: 12px;\n height: 6px;\n}\n\n.orientation-left::before,\n.orientation-left::after\n{\n background-image: url(Images/accelerometer-left.png);\n}\n\n.orientation-right::before,\n.orientation-right::after\n{\n background-image: url(Images/accelerometer-right.png);\n}\n\n.orientation-left::before,\n.orientation-right::before {\n top: -6px;\n transform-origin: center bottom;\n transform: rotateX(26deg);\n background-position: center top;\n}\n\n.orientation-left::after,\n.orientation-right::after {\n bottom: -6px;\n transform-origin: center top;\n transform: rotateX(-25deg);\n background-position: center bottom;\n}\n\n.orientation-top,\n.orientation-bottom {\n width: 50px;\n height: 12px;\n left: 8px;\n background-position: center center;\n}\n\n.orientation-top {\n top: -12px;\n transform-origin: center bottom;\n transform: rotateX(90deg);\n background-image: url(Images/accelerometer-top.png);\n}\n\n\n.orientation-bottom {\n bottom: -12px;\n transform-origin: center top;\n transform: rotateX(-90deg);\n background-image: url(Images/accelerometer-bottom.png);\n}\n\n\n.orientation-top::before,\n.orientation-top::after,\n.orientation-bottom::before,\n.orientation-bottom::after\n{\n content: '';\n width: 8px;\n height: 12px;\n}\n\n.orientation-top::before,\n.orientation-top::after\n{\n background-image: url(Images/accelerometer-top.png);\n}\n\n.orientation-bottom::before,\n.orientation-bottom::after\n{\n background-image: url(Images/accelerometer-bottom.png);\n}\n\n.orientation-top::before,\n.orientation-bottom::before {\n left: -6px;\n transform-origin: right center;\n transform: rotateY(-26deg);\n background-position: left center;\n}\n\n.orientation-top::after,\n.orientation-bottom::after {\n right: -6px;\n transform-origin: left center;\n transform: rotateY(26deg);\n background-position: right center;\n}\n\n.orientation-axis-input-container {\n margin-bottom: 10px;\n}\n\n.orientation-axis-input-container input {\n max-width: 100px;\n}\n\n.orientation-reset-button {\n min-width: 80px;\n}\n\nfieldset.device-orientation-override-section {\n margin: 0;\n display: flex;\n}\n\n.touch-label {\n margin-top: 10px;\n}\n\n.touch-label select {\n margin-left: 10px;\n}\n\n.panel-section-separator {\n height: 2px;\n margin-bottom: 12px;\n background: #f1f1f1;\n}\n\n/*# sourceURL=emulation/sensors.css */";Runtime.startApplication("inspector");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 2 1 1 | WebInspector.LayerPaintProfilerView=function(showImageForLayerCallback) {WebInspector.SplitWidget.call(this,true,false);this._showImageForLayerCallback=showImageForLayerCallback;this._logTreeView=new WebInspector.PaintProfilerCommandLogView();this.setSidebarWidget(this._logTreeView);this._paintProfilerView=new WebInspector.PaintProfilerView(this._showImage.bind(this));this.setMainWidget(this._paintProfilerView);this._paintProfilerView.addEventListener(WebInspector.PaintProfilerView.Events.WindowChanged,this._onWindowChanged,this);} WebInspector.LayerPaintProfilerView.prototype={profileLayer:function(layer) {this._logTreeView.setCommandLog(null,[]);this._paintProfilerView.setSnapshotAndLog(null,[],null);(layer).requestSnapshot(onSnapshotDone.bind(this));function onSnapshotDone(snapshot) {this._layer=layer;snapshot.commandLog(onCommandLogDone.bind(this,snapshot));} function onCommandLogDone(snapshot,log) {this._logTreeView.setCommandLog(snapshot.target(),log||[]);this._paintProfilerView.setSnapshotAndLog(snapshot||null,log||[],null);}},_onWindowChanged:function() {var window=this._paintProfilerView.windowBoundaries();this._logTreeView.updateWindow(window.left,window.right);},_showImage:function(imageURL) {this._showImageForLayerCallback(this._layer,imageURL);},__proto__:WebInspector.SplitWidget.prototype};;WebInspector.LayersPanel=function() {WebInspector.PanelWithSidebar.call(this,"layers",225);this.registerRequiredCSS("timeline/timelinePanel.css");this._model=null;WebInspector.targetManager.observeTargets(this);this._layerViewHost=new WebInspector.LayerViewHost();this._layerTreeOutline=new WebInspector.LayerTreeOutline(this._layerViewHost);this.panelSidebarElement().appendChild(this._layerTreeOutline.element);this.setDefaultFocusedElement(this._layerTreeOutline.element);this._rightSplitWidget=new WebInspector.SplitWidget(false,true,"layerDetailsSplitViewState");this.splitWidget().setMainWidget(this._rightSplitWidget);this._layers3DView=new WebInspector.Layers3DView(this._layerViewHost);this._rightSplitWidget.setMainWidget(this._layers3DView);this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerSnapshotRequested,this._onSnapshotRequested,this);this._tabbedPane=new WebInspector.TabbedPane();this._rightSplitWidget.setSidebarWidget(this._tabbedPane);this._layerDetailsView=new WebInspector.LayerDetailsView(this._layerViewHost);this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Details,WebInspector.UIString("Details"),this._layerDetailsView);this._paintProfilerView=new WebInspector.LayerPaintProfilerView(this._layers3DView.showImageForLayer.bind(this._layers3DView));this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler,WebInspector.UIString("Profiler"),this._paintProfilerView);} WebInspector.LayersPanel.DetailsViewTabs={Details:"details",Profiler:"profiler"};WebInspector.LayersPanel.prototype={focus:function() {this._layerTreeOutline.focus();},wasShown:function() {WebInspector.Panel.prototype.wasShown.call(this);if(this._model) this._model.enable();this._layerTreeOutline.focus();},willHide:function() {if(this._model) this._model.disable();WebInspector.Panel.prototype.willHide.call(this);},targetAdded:function(target) {if(this._model) return;this._model=WebInspector.LayerTreeModel.fromTarget(target);if(!this._model) return;this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged,this._onLayerTreeUpdated,this);this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted,this._onLayerPainted,this);if(this.isShowing()) this._model.enable();},targetRemoved:function(target) {if(!this._model||this._model.target()!==target) return;this._model.removeEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged,this._onLayerTreeUpdated,this);this._model.removeEventListener(WebInspector.LayerTreeModel.Events.LayerPainted,this._onLayerPainted,this);this._model.disable();this._model=null;},_showLayerTree:function(deferredLayerTree) {deferredLayerTree.resolve(this._layerViewHost.setLayerTree.bind(this._layerViewHost));},_onLayerTreeUpdated:function() {if(this._model) this._layerViewHost.setLayerTree(this._model.layerTree());},_onLayerPainted:function(event) {if(!this._model) return;this._layers3DView.setLayerTree(this._model.layerTree());if(this._layerViewHost.selection()&&this._layerViewHost.selection().layer()===event.data) this._layerDetailsView.update();},_onSnapshotRequested:function(event) {var layer=(event.data);this._tabbedPane.selectTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler);this._paintProfilerView.profileLayer(layer);},__proto__:WebInspector.PanelWithSidebar.prototype} WebInspector.LayersPanel.LayerTreeRevealer=function() {} WebInspector.LayersPanel.LayerTreeRevealer.prototype={reveal:function(snapshotData) {if(!(snapshotData instanceof WebInspector.DeferredLayerTree)) return Promise.reject(new Error("Internal error: not a WebInspector.DeferredLayerTree"));var panel=WebInspector.LayersPanel._instance();WebInspector.inspectorView.setCurrentPanel(panel);panel._showLayerTree((snapshotData));return Promise.resolve();}} WebInspector.LayersPanel._instance=function() {if(!WebInspector.LayersPanel._instanceObject) WebInspector.LayersPanel._instanceObject=new WebInspector.LayersPanel();return WebInspector.LayersPanel._instanceObject;} WebInspector.LayersPanelFactory=function() {} WebInspector.LayersPanelFactory.prototype={createPanel:function() {return WebInspector.LayersPanel._instance();}}; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.BlockedURLsPane=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("network/blockedURLsPane.css");this.contentElement.classList.add("blocked-urls-pane");WebInspector.BlockedURLsPane._instance=this;this._blockedURLsSetting=WebInspector.moduleSetting("blockedURLs");this._blockedURLsSetting.addChangeListener(this._update,this);this._toolbar=new WebInspector.Toolbar("",this.contentElement);this._toolbar.element.addEventListener("click",consumeEvent);var addButton=new WebInspector.ToolbarButton(WebInspector.UIString("Add pattern"),"add-toolbar-item");addButton.addEventListener("click",this._addButtonClicked.bind(this));this._toolbar.appendToolbarItem(addButton);var clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Remove all"),"clear-toolbar-item");clearButton.addEventListener("click",this._removeAll.bind(this));this._toolbar.appendToolbarItem(clearButton);this._emptyElement=this.contentElement.createChild("div","no-blocked-urls");this._emptyElement.createChild("span").textContent=WebInspector.UIString("Requests are not blocked. ");var addLink=this._emptyElement.createChild("span","link");addLink.textContent=WebInspector.UIString("Add pattern.");addLink.href="";addLink.addEventListener("click",this._addButtonClicked.bind(this),false);this._emptyElement.addEventListener("contextmenu",this._emptyElementContextMenu.bind(this),true);this._listElement=this.contentElement.createChild("div","blocked-urls-list");this._blockedCountForUrl=new Map();WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);this._updateThrottler=new WebInspector.Throttler(200);this._update();} WebInspector.BlockedURLsPane.prototype={_emptyElementContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^pattern"),this._addButtonClicked.bind(this));contextMenu.show();},_addButtonClicked:function() {this._emptyElement.classList.add("hidden");var element=this._createElement("",this._blockedURLsSetting.get().length);this._listElement.appendChild(element);element.scrollIntoViewIfNeeded();this._edit("",element,this._addBlockedURL.bind(this));},_edit:function(content,element,onAccept) {this._editing=true;element.classList.add("blocked-url-editing");var input=element.createChild("input");input.setAttribute("type","text");input.value=content;input.placeholder=WebInspector.UIString("Text pattern to block matching requests; use * for wildcard");input.addEventListener("blur",commit.bind(this),false);input.addEventListener("keydown",keydown.bind(this),false);input.focus();function finish() {this._editing=false;element.removeChild(input);element.classList.remove("blocked-url-editing");} function commit() {if(!this._editing) return;var text=input.value.trim();finish.call(this);if(text) onAccept(text);else this._update();} function keydown(event) {if(isEnterKey(event)){event.consume();commit.call(this);}else if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code||event.keyIdentifier==="U+001B"){event.consume();finish.call(this);this._update();}}},_addBlockedURL:function(url) {var blocked=this._blockedURLsSetting.get();blocked.push(url);this._blockedURLsSetting.set(blocked);},_removeBlockedURL:function(index) {var blocked=this._blockedURLsSetting.get();blocked.splice(index,1);this._blockedURLsSetting.set(blocked);},_changeBlockedURL:function(index,url) {var blocked=this._blockedURLsSetting.get();blocked.splice(index,1,url);this._blockedURLsSetting.set(blocked);},_removeAll:function() {this._blockedURLsSetting.set([]);},_contextMenu:function(index,event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^pattern"),this._addButtonClicked.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^pattern"),this._removeBlockedURL.bind(this,index));contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all"),this._removeAll.bind(this));contextMenu.show();},_update:function() {if(this._editing) return Promise.resolve();this._listElement.removeChildren();var blocked=this._blockedURLsSetting.get();for(var index=0;index<blocked.length;index++) this._listElement.appendChild(this._createElement(blocked[index],index));this._emptyElement.classList.toggle("hidden",!!blocked.length);return Promise.resolve();},_createElement:function(url,index) {var element=createElementWithClass("div","blocked-url");var label=element.createChild("div","blocked-url-text");label.textContent=url;var count=this._blockedRequestsCount(url);var countElement=element.createChild("div","blocked-count monospace");countElement.textContent=String.sprintf("[%d]",count);countElement.title=WebInspector.UIString(count===1?"%d request blocked by this pattern":"%d requests blocked by this pattern",count);var removeButton=element.createChild("div","remove-button");removeButton.title=WebInspector.UIString("Remove");removeButton.addEventListener("click",this._removeBlockedURL.bind(this,index),false);element.addEventListener("contextmenu",this._contextMenu.bind(this,index),true);element.addEventListener("dblclick",this._edit.bind(this,url,element,this._changeBlockedURL.bind(this,index)),false);return element;},_blockedRequestsCount:function(url) {if(!url) return 0;var result=0;for(var blockedUrl of this._blockedCountForUrl.keys()){if(this._matches(url,blockedUrl)) result+=this._blockedCountForUrl.get(blockedUrl);} return result;},_matches:function(pattern,url) {var pos=0;var parts=pattern.split("*");for(var index=0;index<parts.length;index++){var part=parts[index];if(!part.length) continue;pos=url.indexOf(part,pos);if(pos===-1) return false;pos+=part.length;} return true;},reset:function() {this._blockedCountForUrl.clear();},_onRequestFinished:function(event) {var request=(event.data);if(request.wasBlocked()){var count=this._blockedCountForUrl.get(request.url)||0;this._blockedCountForUrl.set(request.url,count+1);this._updateThrottler.schedule(this._update.bind(this));}},__proto__:WebInspector.VBox.prototype} WebInspector.BlockedURLsPane._instance=null;WebInspector.BlockedURLsPane.reset=function() {if(WebInspector.BlockedURLsPane._instance) WebInspector.BlockedURLsPane._instance.reset();} WebInspector.BlockedURLsPane.ActionDelegate=function() {} WebInspector.BlockedURLsPane.ActionDelegate.prototype={handleAction:function(context,actionId) {WebInspector.inspectorView.showViewInDrawer("network.blocked-urls");return true;}};WebInspector.EventSourceMessagesView=function(request) {WebInspector.VBox.call(this);this.registerRequiredCSS("network/eventSourceMessagesView.css");this.element.classList.add("event-source-messages-view");this._request=request;var columns=[{id:"id",title:WebInspector.UIString("Id"),sortable:true,weight:8},{id:"type",title:WebInspector.UIString("Type"),sortable:true,weight:8},{id:"data",title:WebInspector.UIString("Data"),sortable:false,weight:88},{id:"time",title:WebInspector.UIString("Time"),sortable:true,weight:8}];this._dataGrid=new WebInspector.SortableDataGrid(columns);this._dataGrid.setStickToBottom(true);this._dataGrid.markColumnAsSortedBy("time",WebInspector.DataGrid.Order.Ascending);this._sortItems();this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortItems,this);this._dataGrid.setName("EventSourceMessagesView");this._dataGrid.asWidget().show(this.element);} WebInspector.EventSourceMessagesView.prototype={wasShown:function() {this._dataGrid.rootNode().removeChildren();var messages=this._request.eventSourceMessages();for(var i=0;i<messages.length;++i) this._dataGrid.insertChild(new WebInspector.EventSourceMessageNode(messages[i]));this._request.addEventListener(WebInspector.NetworkRequest.Events.EventSourceMessageAdded,this._messageAdded,this);},willHide:function() {this._request.removeEventListener(WebInspector.NetworkRequest.Events.EventSourceMessageAdded,this._messageAdded,this);},_messageAdded:function(event) {var message=(event.data);this._dataGrid.insertChild(new WebInspector.EventSourceMessageNode(message));},_sortItems:function() {var sortColumnIdentifier=this._dataGrid.sortColumnIdentifier();if(!sortColumnIdentifier) return;var comparator=WebInspector.EventSourceMessageNode.Comparators[sortColumnIdentifier];if(!comparator) return;this._dataGrid.sortNodes(comparator,!this._dataGrid.isSortOrderAscending());},__proto__:WebInspector.VBox.prototype} WebInspector.EventSourceMessageNode=function(message) {this._message=message;var time=new Date(message.time*1000);var timeText=("0"+time.getHours()).substr(-2)+":"+("0"+time.getMinutes()).substr(-2)+":"+("0"+time.getSeconds()).substr(-2)+"."+("00"+time.getMilliseconds()).substr(-3);var timeNode=createElement("div");timeNode.createTextChild(timeText);timeNode.title=time.toLocaleString();WebInspector.SortableDataGridNode.call(this,{id:message.eventId,type:message.eventName,data:message.data,time:timeNode});} WebInspector.EventSourceMessageNode.prototype={__proto__:WebInspector.SortableDataGridNode.prototype} WebInspector.EventSourceMessageNodeComparator=function(field,a,b) {var aValue=a._message[field];var bValue=b._message[field];return aValue<bValue?-1:aValue>bValue?1:0;} WebInspector.EventSourceMessageNode.Comparators={"id":WebInspector.EventSourceMessageNodeComparator.bind(null,"eventId"),"type":WebInspector.EventSourceMessageNodeComparator.bind(null,"eventName"),"time":WebInspector.EventSourceMessageNodeComparator.bind(null,"time")};;WebInspector.FilterSuggestionBuilder=function(keys) {this._keys=keys;this._valueSets={};this._valueLists={};} WebInspector.FilterSuggestionBuilder.Filter;WebInspector.FilterSuggestionBuilder.prototype={buildSuggestions:function(input) {var text=input.value;var end=input.selectionEnd;if(end!=text.length) return null;var start=input.selectionStart;text=text.substring(0,start);var prefixIndex=text.lastIndexOf(" ")+1;var prefix=text.substring(prefixIndex);if(!prefix) return[];var negative=prefix.startsWith("-");if(negative) prefix=prefix.substring(1);var modifier=negative?"-":"";var valueDelimiterIndex=prefix.indexOf(":");var suggestions=[];if(valueDelimiterIndex===-1){var matcher=new RegExp("^"+prefix.escapeForRegExp(),"i");for(var j=0;j<this._keys.length;++j){if(this._keys[j].match(matcher)) suggestions.push(modifier+this._keys[j]+":");}}else{var key=prefix.substring(0,valueDelimiterIndex).toLowerCase();var value=prefix.substring(valueDelimiterIndex+1);var matcher=new RegExp("^"+value.escapeForRegExp(),"i");var items=this._values(key);for(var i=0;i<items.length;++i){if(items[i].match(matcher)&&(items[i]!==value)) suggestions.push(modifier+key+":"+items[i]);}} return suggestions;},applySuggestion:function(input,suggestion,isIntermediate) {var text=input.value;var start=input.selectionStart;text=text.substring(0,start);var prefixIndex=text.lastIndexOf(" ")+1;if(isIntermediate){text=text+suggestion.substring(text.length-prefixIndex);input.value=text;}else{text=text.substring(0,prefixIndex)+suggestion;input.value=text;start=text.length;} input.setSelectionRange(start,text.length);},unapplySuggestion:function(input) {var start=input.selectionStart;var end=input.selectionEnd;var text=input.value;if(start!==end&&end===text.length) input.value=text.substring(0,start);},_values:function(key) {var result=this._valueLists[key];if(!result) return[];result.sort();return result;},addItem:function(key,value) {if(!value) return;var set=this._valueSets[key];var list=this._valueLists[key];if(!set){set={};this._valueSets[key]=set;list=[];this._valueLists[key]=list;} if(set[value]) return;set[value]=true;list.push(value);},parseQuery:function(query) {var filters=[];var text=[];var parts=query.split(/\s+/);for(var i=0;i<parts.length;++i){var part=parts[i];if(!part) continue;var colonIndex=part.indexOf(":");if(colonIndex===-1){text.push(part);continue;} var key=part.substring(0,colonIndex);var negative=key.startsWith("-");if(negative) key=key.substring(1);if(this._keys.indexOf(key)==-1){text.push(part);continue;} var value=part.substring(colonIndex+1);filters.push({type:key,data:value,negative:negative});} return{text:text,filters:filters};}};;WebInspector.HARWriter=function() {} WebInspector.HARWriter.prototype={write:function(stream,requests,progress) {this._stream=stream;this._harLog=(new WebInspector.HARLog(requests)).build();this._pendingRequests=1;var entries=this._harLog.entries;for(var i=0;i<entries.length;++i){var content=requests[i].content;if(typeof content==="undefined"&&requests[i].finished){++this._pendingRequests;requests[i].requestContent().then(this._onContentAvailable.bind(this,entries[i],requests[i]));}else if(content!==null) this._setEntryContent(entries[i],requests[i]);} var compositeProgress=new WebInspector.CompositeProgress(progress);this._writeProgress=compositeProgress.createSubProgress();if(--this._pendingRequests){this._requestsProgress=compositeProgress.createSubProgress();this._requestsProgress.setTitle(WebInspector.UIString("Collecting content…"));this._requestsProgress.setTotalWork(this._pendingRequests);}else this._beginWrite();},_setEntryContent:function(entry,request) {if(request.content!==null) entry.response.content.text=request.content;if(request.contentEncoded) entry.response.content.encoding="base64";},_onContentAvailable:function(entry,request,content) {this._setEntryContent(entry,request);if(this._requestsProgress) this._requestsProgress.worked();if(!--this._pendingRequests){this._requestsProgress.done();this._beginWrite();}},_beginWrite:function() {const jsonIndent=2;this._text=JSON.stringify({log:this._harLog},null,jsonIndent);this._writeProgress.setTitle(WebInspector.UIString("Writing file…"));this._writeProgress.setTotalWork(this._text.length);this._bytesWritten=0;this._writeNextChunk(this._stream);},_writeNextChunk:function(stream,error) {if(this._bytesWritten>=this._text.length||error){stream.close();this._writeProgress.done();return;} const chunkSize=100000;var text=this._text.substring(this._bytesWritten,this._bytesWritten+chunkSize);this._bytesWritten+=text.length;stream.write(text,this._writeNextChunk.bind(this));this._writeProgress.setWorked(this._bytesWritten);}};WebInspector.JSONView=function(parsedJSON) {WebInspector.VBox.call(this);this._parsedJSON=parsedJSON;this.element.classList.add("json-view");this._searchableView;this._treeOutline;this._currentSearchFocusIndex=0;this._currentSearchTreeElements=[];this._searchRegex=null;} WebInspector.JSONView.createSearchableView=function(parsedJSON) {var jsonView=new WebInspector.JSONView(parsedJSON);var searchableView=new WebInspector.SearchableView(jsonView);searchableView.setPlaceholder(WebInspector.UIString("Find"));jsonView._searchableView=searchableView;jsonView.show(searchableView.element);jsonView.element.setAttribute("tabIndex",0);return searchableView;} WebInspector.JSONView.parseJSON=function(text) {var returnObj=null;if(text) returnObj=WebInspector.JSONView._extractJSON((text));if(!returnObj) return Promise.resolve((null));return WebInspector.formatterWorkerPool.runTask("relaxedJSONParser",{content:returnObj.data}).then(handleReturnedJSON) function handleReturnedJSON(event) {if(!event||!event.data) return null;returnObj.data=event.data;return returnObj;}} WebInspector.JSONView._extractJSON=function(text) {if(text.startsWith("<")) return null;var inner=WebInspector.JSONView._findBrackets(text,"{","}");var inner2=WebInspector.JSONView._findBrackets(text,"[","]");inner=inner2.length>inner.length?inner2:inner;if(inner.length===-1||text.length-inner.length>80) return null;var prefix=text.substring(0,inner.start);var suffix=text.substring(inner.end+1);text=text.substring(inner.start,inner.end+1);if(suffix.trim().length&&!(suffix.trim().startsWith(")")&&prefix.trim().endsWith("("))) return null;return new WebInspector.ParsedJSON(text,prefix,suffix);} WebInspector.JSONView._findBrackets=function(text,open,close) {var start=text.indexOf(open);var end=text.lastIndexOf(close);var length=end-start-1;if(start==-1||end==-1||end<start) length=-1;return{start:start,end:end,length:length};} WebInspector.JSONView.prototype={wasShown:function() {this._initialize();},_initialize:function() {if(this._initialized) return;this._initialized=true;var obj=WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.data);var title=this._parsedJSON.prefix+obj.description+this._parsedJSON.suffix;this._treeOutline=new WebInspector.ObjectPropertiesSection(obj,title);this._treeOutline.setEditable(false);this._treeOutline.expand();this.element.appendChild(this._treeOutline.element);},_jumpToMatch:function(index) {if(!this._searchRegex) return;var previousFocusElement=this._currentSearchTreeElements[this._currentSearchFocusIndex];if(previousFocusElement) previousFocusElement.setSearchRegex(this._searchRegex);var newFocusElement=this._currentSearchTreeElements[index];if(newFocusElement){this._updateSearchIndex(index);newFocusElement.setSearchRegex(this._searchRegex,WebInspector.highlightedCurrentSearchResultClassName);newFocusElement.reveal();}else{this._updateSearchIndex(0);}},_updateSearchCount:function(count) {if(!this._searchableView) return;this._searchableView.updateSearchMatchesCount(count);},_updateSearchIndex:function(index) {this._currentSearchFocusIndex=index;if(!this._searchableView) return;this._searchableView.updateCurrentMatchIndex(index);},searchCanceled:function() {this._searchRegex=null;this._currentSearchTreeElements=[];for(var element=this._treeOutline.rootElement();element;element=element.traverseNextTreeElement(false)){if(!(element instanceof WebInspector.ObjectPropertyTreeElement)) continue;element.revertHighlightChanges();} this._updateSearchCount(0);this._updateSearchIndex(0);},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var newIndex=this._currentSearchFocusIndex;var previousSearchFocusElement=this._currentSearchTreeElements[newIndex];this.searchCanceled();this._searchRegex=searchConfig.toSearchRegex(true);for(var element=this._treeOutline.rootElement();element;element=element.traverseNextTreeElement(false)){if(!(element instanceof WebInspector.ObjectPropertyTreeElement)) continue;var hasMatch=element.setSearchRegex(this._searchRegex);if(hasMatch) this._currentSearchTreeElements.push(element);if(previousSearchFocusElement===element){var currentIndex=this._currentSearchTreeElements.length-1;if(hasMatch||jumpBackwards) newIndex=currentIndex;else newIndex=currentIndex+1;}} this._updateSearchCount(this._currentSearchTreeElements.length);if(!this._currentSearchTreeElements.length){this._updateSearchIndex(0);return;} newIndex=mod(newIndex,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex);},jumpToNextSearchResult:function() {if(!this._currentSearchTreeElements.length) return;var newIndex=mod(this._currentSearchFocusIndex+1,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex);},jumpToPreviousSearchResult:function() {if(!this._currentSearchTreeElements.length) return;var newIndex=mod(this._currentSearchFocusIndex-1,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex);},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return true;},__proto__:WebInspector.VBox.prototype} WebInspector.ParsedJSON=function(data,prefix,suffix) {this.data=data;this.prefix=prefix;this.suffix=suffix;};WebInspector.RequestView=function(request) {WebInspector.VBox.call(this);this.element.classList.add("request-view");this.request=request;} WebInspector.RequestView.prototype={__proto__:WebInspector.VBox.prototype} WebInspector.RequestView.hasTextContent=function(request) {if(request.resourceType().isTextType()) return true;if(request.resourceType()===WebInspector.resourceTypes.Other||request.hasErrorStatusCode()) return!!request.content&&!request.contentEncoded;return false;} WebInspector.RequestView.nonSourceViewForRequest=function(request) {switch(request.resourceType()){case WebInspector.resourceTypes.Image:return new WebInspector.ImageView(request.mimeType,request);case WebInspector.resourceTypes.Font:return new WebInspector.FontView(request.mimeType,request);default:return new WebInspector.RequestView(request);}};WebInspector.NetworkConfigView=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("network/networkConfigView.css");this.contentElement.classList.add("network-config");this._createCacheSection();this.contentElement.createChild("div").classList.add("panel-section-separator");this._createNetworkThrottlingSection();this.contentElement.createChild("div").classList.add("panel-section-separator");this._createUserAgentSection();} WebInspector.NetworkConfigView.prototype={_createSection:function(title,className) {var section=this.contentElement.createChild("section","network-config-group");if(className) section.classList.add(className);section.createChild("div","network-config-title").textContent=title;return section.createChild("div","network-config-fields");},_createCacheSection:function() {var section=this._createSection(WebInspector.UIString("Caching"),"network-config-disable-cache");section.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Disable cache"),WebInspector.moduleSetting("cacheDisabled"),true));},_createNetworkThrottlingSection:function() {var section=this._createSection(WebInspector.UIString("Network throttling"),"network-config-throttling");WebInspector.NetworkConditionsSelector.decorateSelect((section.createChild("select","chrome-select")));},_createUserAgentSection:function() {var section=this._createSection(WebInspector.UIString("User agent"),"network-config-ua");var checkboxLabel=createCheckboxLabel(WebInspector.UIString("Select automatically"),true);section.appendChild(checkboxLabel);this._autoCheckbox=checkboxLabel.checkboxElement;this._autoCheckbox.addEventListener("change",this._userAgentTypeChanged.bind(this));this._customUserAgentSetting=WebInspector.settings.createSetting("customUserAgent","");this._customUserAgentSetting.addChangeListener(this._customUserAgentChanged,this);this._customUserAgent=section.createChild("div","network-config-ua-custom");this._customSelectAndInput=WebInspector.NetworkConfigView.createUserAgentSelectAndInput();this._customSelectAndInput.select.classList.add("chrome-select");this._customUserAgent.appendChild(this._customSelectAndInput.select);this._customUserAgent.appendChild(this._customSelectAndInput.input);this._userAgentTypeChanged();},_customUserAgentChanged:function() {if(this._autoCheckbox.checked) return;WebInspector.multitargetNetworkManager.setCustomUserAgentOverride(this._customUserAgentSetting.get());},_userAgentTypeChanged:function() {var useCustomUA=!this._autoCheckbox.checked;this._customUserAgent.classList.toggle("checked",useCustomUA);this._customSelectAndInput.select.disabled=!useCustomUA;this._customSelectAndInput.input.disabled=!useCustomUA;var customUA=useCustomUA?this._customUserAgentSetting.get():"";WebInspector.multitargetNetworkManager.setCustomUserAgentOverride(customUA);},__proto__:WebInspector.VBox.prototype} WebInspector.NetworkConfigView.createUserAgentSelectAndInput=function() {var userAgentSetting=WebInspector.settings.createSetting("customUserAgent","");var userAgentSelectElement=createElement("select");const customOverride={title:WebInspector.UIString("Custom..."),value:"custom"};userAgentSelectElement.appendChild(new Option(customOverride.title,customOverride.value));var groups=WebInspector.NetworkConfigView._userAgentGroups;for(var userAgentDescriptor of WebInspector.NetworkConfigView._userAgentGroups){var groupElement=userAgentSelectElement.createChild("optgroup");groupElement.label=userAgentDescriptor.title;for(var userAgentVersion of userAgentDescriptor.values) groupElement.appendChild(new Option(userAgentVersion.title,userAgentVersion.value));} userAgentSelectElement.selectedIndex=0;var otherUserAgentElement=createElement("input");otherUserAgentElement.type="text";otherUserAgentElement.value=userAgentSetting.get();otherUserAgentElement.title=userAgentSetting.get();settingChanged();userAgentSelectElement.addEventListener("change",userAgentSelected,false);otherUserAgentElement.addEventListener("input",textChanged,false);function userAgentSelected() {var value=userAgentSelectElement.options[userAgentSelectElement.selectedIndex].value;if(value!==customOverride.value){userAgentSetting.set(value);otherUserAgentElement.value=value;otherUserAgentElement.title=value;}else{otherUserAgentElement.select();}} function settingChanged() {var value=userAgentSetting.get();var options=userAgentSelectElement.options;var selectionRestored=false;for(var i=0;i<options.length;++i){if(options[i].value===value){userAgentSelectElement.selectedIndex=i;selectionRestored=true;break;}} if(!selectionRestored) userAgentSelectElement.selectedIndex=0;} function textChanged() {if(userAgentSetting.get()!==otherUserAgentElement.value){userAgentSetting.set(otherUserAgentElement.value);otherUserAgentElement.title=otherUserAgentElement.value;settingChanged();}} return{select:userAgentSelectElement,input:otherUserAgentElement};} WebInspector.NetworkConfigView._userAgentGroups=[{title:"Android",values:[{title:"Android (4.0.2) Browser \u2014 Galaxy Nexus",value:"Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"},{title:"Android (2.3) Browser \u2014 Nexus S",value:"Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"}]},{title:"BlackBerry",values:[{title:"BlackBerry \u2014 BB10",value:"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+"},{title:"BlackBerry \u2014 PlayBook 2.1",value:"Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+"},{title:"BlackBerry \u2014 9900",value:"Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+"}]},{title:"Chrome",values:[{title:"Chrome 52 \u2014 Android Mobile",value:"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2725.0 Mobile Safari/537.36"},{title:"Chrome 52 \u2014 Android Tablet",value:"Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2725.0 Safari/537.36"},{title:"Chrome 52 \u2014 iPhone",value:"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/52.0.2725.0 Mobile/13B143 Safari/601.1.46"},{title:"Chrome 52 \u2014 iPad",value:"Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/52.0.2725.0 Mobile/13B143 Safari/601.1.46"},{title:"Chrome 52 \u2014 Mac",value:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2725.0 Safari/537.36"},{title:"Chrome 52 \u2014 Windows",value:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2725.0 Safari/537.36"}]},{title:"Edge",values:[{title:"Edge \u2014 Windows",value:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"},{title:"Edge \u2014 Mobile",value:"Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 640 XL LTE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.10166"},{title:"Edge \u2014 XBox",value:"Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586"}]},{title:"Firefox",values:[{title:"Firefox 46 \u2014 Android Mobile",value:"Mozilla/5.0 (Android 4.4; Mobile; rv:46.0) Gecko/46.0 Firefox/46.0"},{title:"Firefox 46 \u2014 Android Tablet",value:"Mozilla/5.0 (Android 4.4; Tablet; rv:46.0) Gecko/46.0 Firefox/46.0"},{title:"Firefox 46 \u2014 iPhone",value:"Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4"},{title:"Firefox 46 \u2014 iPad",value:"Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4"},{title:"Firefox 46 \u2014 Mac",value:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0"},{title:"Firefox 46 \u2014 Windows",value:"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"}]},{title:"Googlebot",values:[{title:"Googlebot",value:"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"},{title:"Googlebot Smartphone",value:"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"}]},{title:"Internet Explorer",values:[{title:"Internet Explorer 11",value:"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"},{title:"Internet Explorer 10",value:"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"},{title:"Internet Explorer 9",value:"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"},{title:"Internet Explorer 8",value:"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"},{title:"Internet Explorer 7",value:"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"}]},{title:"Opera",values:[{title:"Opera 37 \u2014 Mac",value:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.31"},{title:"Opera 37 \u2014 Windows",value:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.31"},{title:"Opera 12 \u2014 Mac",value:"Opera/9.80 (Macintosh; Intel Mac OS X 10.9.1) Presto/2.12.388 Version/12.16"},{title:"Opera 12 \u2014 Windows",value:"Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16"},{title:"Opera Mobile \u2014 Android Mobile",value:"Opera/12.02 (Android 4.1; Linux; Opera Mobi/ADR-1111101157; U; en-US) Presto/2.9.201 Version/12.02"},{title:"Opera Mini \u2014 iOS",value:"Opera/9.80 (iPhone; Opera Mini/8.0.0/34.2336; U; en) Presto/2.8.119 Version/11.10"}]},{title:"Safari",values:[{title:"Safari \u2014 iPad iOS 9",value:"Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1"},{title:"Safari \u2014 iPhone iOS 9",value:"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1"},{title:"Safari \u2014 Mac",value:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A"}]}] WebInspector.NetworkConfigView.ShowActionDelegate=function() {} WebInspector.NetworkConfigView.ShowActionDelegate.prototype={handleAction:function(context,actionId) {WebInspector.inspectorView.showViewInDrawer("network.config");return true;}};WebInspector.NetworkDataGridNode=function(parentView,request) {WebInspector.SortableDataGridNode.call(this,{});this._parentView=parentView;this._request=request;this._staleGraph=true;this._isNavigationRequest=false;this.selectable=true;} WebInspector.NetworkDataGridNode._hoveredRowSymbol=Symbol("hoveredRow");WebInspector.NetworkDataGridNode.prototype={displayType:function() {var mimeType=this._request.mimeType||this._request.requestContentType()||"";var resourceType=this._request.resourceType();var simpleType=resourceType.name();if(resourceType==WebInspector.resourceTypes.Other||resourceType==WebInspector.resourceTypes.Image) simpleType=mimeType.replace(/^(application|image)\//,"");return simpleType;},request:function() {return this._request;},markAsNavigationRequest:function() {this._isNavigationRequest=true;this.refresh();},nodeSelfHeight:function() {return this._parentView.rowHeight();},createCells:function() {this._showTiming=!WebInspector.moduleSetting("networkColorCodeResourceTypes").get()&&!this._parentView.calculator().startAtZero;this._nameCell=null;this._timelineCell=null;this._initiatorCell=null;this._element.classList.toggle("network-error-row",this._isFailed());this._element.classList.toggle("network-navigation-row",this._isNavigationRequest);WebInspector.SortableDataGridNode.prototype.createCells.call(this);this._updateGraph();},createCell:function(columnIdentifier) {var cell=this.createTD(columnIdentifier);switch(columnIdentifier){case"name":this._renderNameCell(cell);break;case"timeline":this._createTimelineBar(cell);break;case"method":cell.setTextAndTitle(this._request.requestMethod);break;case"status":this._renderStatusCell(cell);break;case"protocol":cell.setTextAndTitle(this._request.protocol);break;case"scheme":cell.setTextAndTitle(this._request.scheme);break;case"domain":cell.setTextAndTitle(this._request.domain);break;case"remoteAddress":cell.setTextAndTitle(this._request.remoteAddress());break;case"cookies":cell.setTextAndTitle(this._arrayLength(this._request.requestCookies));break;case"setCookies":cell.setTextAndTitle(this._arrayLength(this._request.responseCookies));break;case"priority":cell.setTextAndTitle(WebInspector.uiLabelForPriority(this._request.initialPriority()));break;case"connectionId":cell.setTextAndTitle(this._request.connectionId);break;case"type":this._renderTypeCell(cell);break;case"initiator":this._renderInitiatorCell(cell);break;case"size":this._renderSizeCell(cell);break;case"time":this._renderTimeCell(cell);break;default:cell.setTextAndTitle(this._request.responseHeaderValue(columnIdentifier)||"");break;} return cell;},_arrayLength:function(array) {return array?""+array.length:"";},willAttach:function() {if(this._staleGraph) this._updateGraph();if(this._initiatorCell&&this._request.initiatorInfo().type===WebInspector.NetworkRequest.InitiatorType.Script) this._initiatorCell.insertBefore(this._linkifiedInitiatorAnchor,this._initiatorCell.firstChild);},wasDetached:function() {if(this._linkifiedInitiatorAnchor) this._linkifiedInitiatorAnchor.remove();},dispose:function() {if(this._linkifiedInitiatorAnchor) this._parentView.linkifier.disposeAnchor(this._request.target(),this._linkifiedInitiatorAnchor);},select:function() {WebInspector.SortableDataGridNode.prototype.select.apply(this,arguments);this._parentView.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RequestSelected,this._request);},highlightMatchedSubstring:function(regexp) {this.element();var domChanges=[];var matchInfo=this._nameCell.textContent.match(regexp);if(matchInfo) WebInspector.highlightSearchResult(this._nameCell,matchInfo.index,matchInfo[0].length,domChanges);return domChanges;},_openInNewTab:function() {InspectorFrontendHost.openInNewTab(this._request.url);},_createTimelineBar:function(cell) {cell=cell.createChild("div");this._timelineCell=cell;cell.className="network-graph-side";this._barAreaElement=cell.createChild("div","network-graph-bar-area");this._barAreaElement.request=this._request;if(this._showTiming) return;var type=this._request.resourceType().name();var cached=this._request.cached();this._barLeftElement=this._barAreaElement.createChild("div","network-graph-bar");this._barLeftElement.classList.add(type,"waiting");this._barLeftElement.classList.toggle("cached",cached);this._barRightElement=this._barAreaElement.createChild("div","network-graph-bar");this._barRightElement.classList.add(type);this._barRightElement.classList.toggle("cached",cached);this._labelLeftElement=this._barAreaElement.createChild("div","network-graph-label");this._labelLeftElement.classList.add("waiting");this._labelRightElement=this._barAreaElement.createChild("div","network-graph-label");cell.addEventListener("mouseover",this._onMouseOver.bind(this),false);},_onMouseOver:function(event) {this._refreshLabelPositions();this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol]=this;},_isFailed:function() {return(this._request.failed&&!this._request.statusCode)||(this._request.statusCode>=400);},_renderNameCell:function(cell) {this._nameCell=cell;cell.addEventListener("dblclick",this._openInNewTab.bind(this),false);var iconElement;if(this._request.resourceType()===WebInspector.resourceTypes.Image){var previewImage=createElementWithClass("img","image-network-icon-preview");this._request.populateImageSource(previewImage);iconElement=createElementWithClass("div","icon");iconElement.appendChild(previewImage);}else{iconElement=createElementWithClass("img","icon");} iconElement.classList.add(this._request.resourceType().name());cell.appendChild(iconElement);cell.createTextChild(this._request.target().decorateLabel(this._request.name()));this._appendSubtitle(cell,this._request.path());cell.title=this._request.url;},_renderStatusCell:function(cell) {cell.classList.toggle("network-dim-cell",!this._isFailed()&&(this._request.cached()||!this._request.statusCode));if(this._request.failed&&!this._request.canceled&&!this._request.wasBlocked()){var failText=WebInspector.UIString("(failed)");if(this._request.localizedFailDescription){cell.createTextChild(failText);this._appendSubtitle(cell,this._request.localizedFailDescription);cell.title=failText+" "+this._request.localizedFailDescription;}else cell.setTextAndTitle(failText);}else if(this._request.statusCode){cell.createTextChild(""+this._request.statusCode);this._appendSubtitle(cell,this._request.statusText);cell.title=this._request.statusCode+" "+this._request.statusText;}else if(this._request.parsedURL.isDataURL()){cell.setTextAndTitle(WebInspector.UIString("(data)"));}else if(this._request.canceled){cell.setTextAndTitle(WebInspector.UIString("(canceled)"));}else if(this._request.wasBlocked()){var reason=WebInspector.UIString("other");switch(this._request.blockedReason()){case NetworkAgent.BlockedReason.Csp:reason=WebInspector.UIString("csp");break;case NetworkAgent.BlockedReason.MixedContent:reason=WebInspector.UIString("mixed-content");break;case NetworkAgent.BlockedReason.Origin:reason=WebInspector.UIString("origin");break;case NetworkAgent.BlockedReason.Inspector:reason=WebInspector.UIString("devtools");break;case NetworkAgent.BlockedReason.Other:reason=WebInspector.UIString("other");break;} cell.setTextAndTitle(WebInspector.UIString("(blocked:%s)",reason));}else if(this._request.finished){cell.setTextAndTitle(WebInspector.UIString("Finished"));}else{cell.setTextAndTitle(WebInspector.UIString("(pending)"));}},_renderTypeCell:function(cell) {cell.setTextAndTitle(this.displayType());},_renderInitiatorCell:function(cell) {this._initiatorCell=cell;var request=this._request;var initiator=request.initiatorInfo();if(request.timing&&request.timing.pushStart) cell.appendChild(createTextNode(WebInspector.UIString("Push / ")));switch(initiator.type){case WebInspector.NetworkRequest.InitiatorType.Parser:cell.title=initiator.url+":"+initiator.lineNumber;var uiSourceCode=WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(initiator.url);cell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url,initiator.lineNumber-1,initiator.columnNumber-1,undefined,undefined,uiSourceCode?uiSourceCode.displayName():undefined));this._appendSubtitle(cell,WebInspector.UIString("Parser"));break;case WebInspector.NetworkRequest.InitiatorType.Redirect:cell.title=initiator.url;console.assert(request.redirectSource);var redirectSource=(request.redirectSource);cell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));this._appendSubtitle(cell,WebInspector.UIString("Redirect"));break;case WebInspector.NetworkRequest.InitiatorType.Script:if(!this._linkifiedInitiatorAnchor){this._linkifiedInitiatorAnchor=this._parentView.linkifier.linkifyScriptLocation(request.target(),initiator.scriptId,initiator.url,initiator.lineNumber-1,initiator.columnNumber-1);this._linkifiedInitiatorAnchor.title="";} cell.appendChild(this._linkifiedInitiatorAnchor);this._appendSubtitle(cell,WebInspector.UIString("Script"));cell.classList.add("network-script-initiated");cell.request=request;break;default:cell.title=WebInspector.UIString("Other");cell.classList.add("network-dim-cell");cell.appendChild(createTextNode(WebInspector.UIString("Other")));}},_renderSizeCell:function(cell) {if(this._request.fetchedViaServiceWorker){cell.setTextAndTitle(WebInspector.UIString("(from ServiceWorker)"));cell.classList.add("network-dim-cell");}else if(this._request.cached()){cell.setTextAndTitle(WebInspector.UIString("(from cache)"));cell.classList.add("network-dim-cell");}else{var resourceSize=Number.bytesToString(this._request.resourceSize);var transferSize=Number.bytesToString(this._request.transferSize);cell.setTextAndTitle(transferSize);this._appendSubtitle(cell,resourceSize);}},_renderTimeCell:function(cell) {if(this._request.duration>0){cell.setTextAndTitle(Number.secondsToString(this._request.duration));this._appendSubtitle(cell,Number.secondsToString(this._request.latency));}else{cell.classList.add("network-dim-cell");cell.setTextAndTitle(WebInspector.UIString("Pending"));}},_appendSubtitle:function(cellElement,subtitleText) {var subtitleElement=createElement("div");subtitleElement.className="network-cell-subtitle";subtitleElement.textContent=subtitleText;cellElement.appendChild(subtitleElement);},refreshGraph:function() {if(!this._timelineCell) return;this._staleGraph=true;if(this.attached()) this.dataGrid.scheduleUpdate();},_updateTimingGraph:function() {var calculator=this._parentView.calculator();var timeRanges=WebInspector.RequestTimingView.calculateRequestTimeRanges(this._request,calculator.minimumBoundary());var right=timeRanges[0].end;var container=this._barAreaElement;var nextBar=container.firstChild;for(var i=0;i<timeRanges.length;++i){var range=timeRanges[i];var start=calculator.computePercentageFromEventTime(range.start);var end=(range.end!==Number.MAX_VALUE)?calculator.computePercentageFromEventTime(range.end):100;if(!nextBar) nextBar=container.createChild("div");nextBar.className="network-graph-bar request-timing";nextBar.classList.add(range.name);nextBar.style.setProperty("left",start+"%");nextBar.style.setProperty("right",(100-end)+"%");nextBar=nextBar.nextSibling;} while(nextBar){var nextSibling=nextBar.nextSibling;nextBar.remove();nextBar=nextSibling;}},_updateGraph:function() {this._staleGraph=false;if(!this._timelineCell) return;if(this._showTiming){this._updateTimingGraph();return;} var calculator=this._parentView.calculator();var percentages=calculator.computeBarGraphPercentages(this._request);this._percentages=percentages;this._barAreaElement.classList.remove("hidden");this._barLeftElement.style.setProperty("left",percentages.start+"%");this._barLeftElement.style.setProperty("right",(100-percentages.middle)+"%");this._barRightElement.style.setProperty("left",percentages.middle+"%");this._barRightElement.style.setProperty("right",(100-percentages.end)+"%");var labels=calculator.computeBarGraphLabels(this._request);this._labelLeftElement.textContent=labels.left;this._labelRightElement.textContent=labels.right;var tooltip=(labels.tooltip||"");this._barLeftElement.title=tooltip;this._labelLeftElement.title=tooltip;this._labelRightElement.title=tooltip;this._barRightElement.title=tooltip;if(this._parentView[WebInspector.NetworkDataGridNode._hoveredRowSymbol]===this) this._refreshLabelPositions();},_refreshLabelPositions:function() {if(!this._percentages) return;this._labelLeftElement.style.removeProperty("left");this._labelLeftElement.style.removeProperty("right");this._labelLeftElement.classList.remove("before");this._labelLeftElement.classList.remove("hidden");this._labelRightElement.style.removeProperty("left");this._labelRightElement.style.removeProperty("right");this._labelRightElement.classList.remove("after");this._labelRightElement.classList.remove("hidden");const labelPadding=10;const barRightElementOffsetWidth=this._barRightElement.offsetWidth;const barLeftElementOffsetWidth=this._barLeftElement.offsetWidth;if(this._barLeftElement){var leftBarWidth=barLeftElementOffsetWidth-labelPadding;var rightBarWidth=(barRightElementOffsetWidth-barLeftElementOffsetWidth)-labelPadding;}else{var leftBarWidth=(barLeftElementOffsetWidth-barRightElementOffsetWidth)-labelPadding;var rightBarWidth=barRightElementOffsetWidth-labelPadding;} const labelLeftElementOffsetWidth=this._labelLeftElement.offsetWidth;const labelRightElementOffsetWidth=this._labelRightElement.offsetWidth;const labelBefore=(labelLeftElementOffsetWidth>leftBarWidth);const labelAfter=(labelRightElementOffsetWidth>rightBarWidth);const graphElementOffsetWidth=this._timelineCell.offsetWidth;if(labelBefore&&(graphElementOffsetWidth*(this._percentages.start/100))<(labelLeftElementOffsetWidth+10)) var leftHidden=true;if(labelAfter&&(graphElementOffsetWidth*((100-this._percentages.end)/100))<(labelRightElementOffsetWidth+10)) var rightHidden=true;if(barLeftElementOffsetWidth==barRightElementOffsetWidth){if(labelBefore&&!labelAfter) leftHidden=true;else if(labelAfter&&!labelBefore) rightHidden=true;} if(labelBefore){if(leftHidden) this._labelLeftElement.classList.add("hidden");this._labelLeftElement.style.setProperty("right",(100-this._percentages.start)+"%");this._labelLeftElement.classList.add("before");}else{this._labelLeftElement.style.setProperty("left",this._percentages.start+"%");this._labelLeftElement.style.setProperty("right",(100-this._percentages.middle)+"%");} if(labelAfter){if(rightHidden) this._labelRightElement.classList.add("hidden");this._labelRightElement.style.setProperty("left",this._percentages.end+"%");this._labelRightElement.classList.add("after");}else{this._labelRightElement.style.setProperty("left",this._percentages.middle+"%");this._labelRightElement.style.setProperty("right",(100-this._percentages.end)+"%");}},__proto__:WebInspector.SortableDataGridNode.prototype} WebInspector.NetworkDataGridNode.NameComparator=function(a,b) {var aFileName=a._request.name();var bFileName=b._request.name();if(aFileName>bFileName) return 1;if(bFileName>aFileName) return-1;return a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.RemoteAddressComparator=function(a,b) {var aRemoteAddress=a._request.remoteAddress();var bRemoteAddress=b._request.remoteAddress();if(aRemoteAddress>bRemoteAddress) return 1;if(bRemoteAddress>aRemoteAddress) return-1;return a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.SizeComparator=function(a,b) {if(b._request.cached()&&!a._request.cached()) return 1;if(a._request.cached()&&!b._request.cached()) return-1;return(a._request.transferSize-b._request.transferSize)||a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.TypeComparator=function(a,b) {var aSimpleType=a.displayType();var bSimpleType=b.displayType();if(aSimpleType>bSimpleType) return 1;if(bSimpleType>aSimpleType) return-1;return a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.InitiatorComparator=function(a,b) {var aInitiator=a._request.initiatorInfo();var bInitiator=b._request.initiatorInfo();if(aInitiator.type<bInitiator.type) return-1;if(aInitiator.type>bInitiator.type) return 1;if(typeof aInitiator.__source==="undefined") aInitiator.__source=WebInspector.displayNameForURL(aInitiator.url);if(typeof bInitiator.__source==="undefined") bInitiator.__source=WebInspector.displayNameForURL(bInitiator.url);if(aInitiator.__source<bInitiator.__source) return-1;if(aInitiator.__source>bInitiator.__source) return 1;if(aInitiator.lineNumber<bInitiator.lineNumber) return-1;if(aInitiator.lineNumber>bInitiator.lineNumber) return 1;if(aInitiator.columnNumber<bInitiator.columnNumber) return-1;if(aInitiator.columnNumber>bInitiator.columnNumber) return 1;return a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.RequestCookiesCountComparator=function(a,b) {var aScore=a._request.requestCookies?a._request.requestCookies.length:0;var bScore=b._request.requestCookies?b._request.requestCookies.length:0;return(aScore-bScore)||a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator=function(a,b) {var aScore=a._request.responseCookies?a._request.responseCookies.length:0;var bScore=b._request.responseCookies?b._request.responseCookies.length:0;return(aScore-bScore)||a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.InitialPriorityComparator=function(a,b) {var priorityMap=WebInspector.NetworkDataGridNode._symbolicToNumericPriority;if(!priorityMap){WebInspector.NetworkDataGridNode._symbolicToNumericPriority=new Map();priorityMap=WebInspector.NetworkDataGridNode._symbolicToNumericPriority;priorityMap.set(NetworkAgent.ResourcePriority.VeryLow,1);priorityMap.set(NetworkAgent.ResourcePriority.Low,2);priorityMap.set(NetworkAgent.ResourcePriority.Medium,3);priorityMap.set(NetworkAgent.ResourcePriority.High,4);priorityMap.set(NetworkAgent.ResourcePriority.VeryHigh,5);} var aScore=priorityMap.get(a._request.initialPriority())||0;var bScore=priorityMap.get(b._request.initialPriority())||0;return aScore-bScore||a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.RequestPropertyComparator=function(propertyName,a,b) {var aValue=a._request[propertyName];var bValue=b._request[propertyName];if(aValue==bValue) return a._request.indentityCompare(b._request);return aValue>bValue?1:-1;} WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator=function(propertyName,a,b) {var aValue=String(a._request.responseHeaderValue(propertyName)||"");var bValue=String(b._request.responseHeaderValue(propertyName)||"");return aValue.localeCompare(bValue)||a._request.indentityCompare(b._request);} WebInspector.NetworkDataGridNode.ResponseHeaderNumberComparator=function(propertyName,a,b) {var aValue=(a._request.responseHeaderValue(propertyName)!==undefined)?parseFloat(a._request.responseHeaderValue(propertyName)):-Infinity;var bValue=(b._request.responseHeaderValue(propertyName)!==undefined)?parseFloat(b._request.responseHeaderValue(propertyName)):-Infinity;if(aValue==bValue) return a._request.indentityCompare(b._request);return aValue>bValue?1:-1;} WebInspector.NetworkDataGridNode.ResponseHeaderDateComparator=function(propertyName,a,b) {var aHeader=a._request.responseHeaderValue(propertyName);var bHeader=b._request.responseHeaderValue(propertyName);var aValue=aHeader?new Date(aHeader).getTime():-Infinity;var bValue=bHeader?new Date(bHeader).getTime():-Infinity;if(aValue==bValue) return a._request.indentityCompare(b._request);return aValue>bValue?1:-1;};WebInspector.NetworkItemView=function(request,calculator) {WebInspector.TabbedPane.call(this);this.renderWithNoHeaderBackground();this.element.classList.add("network-item-view");this._resourceViewTabSetting=WebInspector.settings.createSetting("resourceViewTab","preview");var headersView=new WebInspector.RequestHeadersView(request);this.appendTab("headers",WebInspector.UIString("Headers"),headersView);this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);if(request.resourceType()===WebInspector.resourceTypes.WebSocket){var frameView=new WebInspector.ResourceWebSocketFrameView(request);this.appendTab("webSocketFrames",WebInspector.UIString("Frames"),frameView);}else if(request.mimeType==="text/event-stream"){this.appendTab("eventSource",WebInspector.UIString("EventStream"),new WebInspector.EventSourceMessagesView(request));}else{var responseView=new WebInspector.RequestResponseView(request);var previewView=new WebInspector.RequestPreviewView(request,responseView);this.appendTab("preview",WebInspector.UIString("Preview"),previewView);this.appendTab("response",WebInspector.UIString("Response"),responseView);} if(request.requestCookies||request.responseCookies){this._cookiesView=new WebInspector.RequestCookiesView(request);this.appendTab("cookies",WebInspector.UIString("Cookies"),this._cookiesView);} this.appendTab("timing",WebInspector.UIString("Timing"),new WebInspector.RequestTimingView(request,calculator));this._request=request;} WebInspector.NetworkItemView.prototype={wasShown:function() {WebInspector.TabbedPane.prototype.wasShown.call(this);this._selectTab();},_selectTab:function(tabId) {if(!tabId) tabId=this._resourceViewTabSetting.get();if(!this.selectTab(tabId)) this.selectTab("headers");},_tabSelected:function(event) {if(!event.data.isUserGesture) return;this._resourceViewTabSetting.set(event.data.tabId);},request:function() {return this._request;},__proto__:WebInspector.TabbedPane.prototype} WebInspector.RequestContentView=function(request) {WebInspector.RequestView.call(this,request);} WebInspector.RequestContentView.prototype={get innerView() {return this._innerView;},set innerView(innerView) {this._innerView=innerView;},wasShown:function() {this._ensureInnerViewShown();},_ensureInnerViewShown:function() {if(this._innerViewShowRequested) return;this._innerViewShowRequested=true;function callback(content) {this._innerViewShowRequested=false;this.contentLoaded();} this.request.requestContent().then(callback.bind(this));},contentLoaded:function() {},__proto__:WebInspector.RequestView.prototype};WebInspector.NetworkTimeBoundary=function(minimum,maximum) {this.minimum=minimum;this.maximum=maximum;} WebInspector.NetworkTimeBoundary.prototype={equals:function(other) {return(this.minimum===other.minimum)&&(this.maximum===other.maximum);}} WebInspector.NetworkTimeCalculator=function(startAtZero) {this.startAtZero=startAtZero;this._boundryChangedEventThrottler=new WebInspector.Throttler(0);this._window=null;} WebInspector.NetworkTimeCalculator.Events={BoundariesChanged:"BoundariesChanged"} WebInspector.NetworkTimeCalculator._latencyDownloadTotalFormat=new WebInspector.UIStringFormat("%s latency, %s download (%s total)");WebInspector.NetworkTimeCalculator._latencyFormat=new WebInspector.UIStringFormat("%s latency");WebInspector.NetworkTimeCalculator._downloadFormat=new WebInspector.UIStringFormat("%s download");WebInspector.NetworkTimeCalculator._fromServiceWorkerFormat=new WebInspector.UIStringFormat("%s (from ServiceWorker)");WebInspector.NetworkTimeCalculator._fromCacheFormat=new WebInspector.UIStringFormat("%s (from cache)");WebInspector.NetworkTimeCalculator.prototype={setWindow:function(window) {this._window=window;this._boundaryChanged();},setInitialUserFriendlyBoundaries:function() {this._minimumBoundary=0;this._maximumBoundary=1;},paddingLeft:function() {return 0;},computePosition:function(time) {return(time-this.minimumBoundary())/this.boundarySpan()*this._workingArea;},formatValue:function(value,precision) {return Number.secondsToString(value,!!precision);},minimumBoundary:function() {return this._window?this._window.minimum:this._minimumBoundary;},zeroTime:function() {return this._minimumBoundary;},maximumBoundary:function() {return this._window?this._window.maximum:this._maximumBoundary;},boundary:function() {return new WebInspector.NetworkTimeBoundary(this.minimumBoundary(),this.maximumBoundary());},boundarySpan:function() {return this.maximumBoundary()-this.minimumBoundary();},reset:function() {delete this._minimumBoundary;delete this._maximumBoundary;this._boundaryChanged();},_value:function(item) {return 0;},setDisplayWindow:function(clientWidth) {this._workingArea=clientWidth;},computeBarGraphPercentages:function(request) {if(request.startTime!==-1) var start=((request.startTime-this.minimumBoundary())/this.boundarySpan())*100;else var start=0;if(request.responseReceivedTime!==-1) var middle=((request.responseReceivedTime-this.minimumBoundary())/this.boundarySpan())*100;else var middle=(this.startAtZero?start:100);if(request.endTime!==-1) var end=((request.endTime-this.minimumBoundary())/this.boundarySpan())*100;else var end=(this.startAtZero?middle:100);if(this.startAtZero){end-=start;middle-=start;start=0;} return{start:start,middle:middle,end:end};},computePercentageFromEventTime:function(eventTime) {if(eventTime!==-1&&!this.startAtZero) return((eventTime-this.minimumBoundary())/this.boundarySpan())*100;return 0;},percentageToTime:function(percentage) {return percentage*this.boundarySpan()/100+this.minimumBoundary();},_boundaryChanged:function() {this._boundryChangedEventThrottler.schedule(dispatchEvent.bind(this));function dispatchEvent() {this.dispatchEventToListeners(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged);return Promise.resolve();}},updateBoundariesForEventTime:function(eventTime) {if(eventTime===-1||this.startAtZero) return;if(this._maximumBoundary===undefined||eventTime>this._maximumBoundary){this._maximumBoundary=eventTime;this._boundaryChanged();}},computeBarGraphLabels:function(request) {var rightLabel="";if(request.responseReceivedTime!==-1&&request.endTime!==-1) rightLabel=Number.secondsToString(request.endTime-request.responseReceivedTime);var hasLatency=request.latency>0;if(hasLatency) var leftLabel=Number.secondsToString(request.latency);else var leftLabel=rightLabel;if(request.timing) return{left:leftLabel,right:rightLabel};if(hasLatency&&rightLabel){var total=Number.secondsToString(request.duration);var tooltip=WebInspector.NetworkTimeCalculator._latencyDownloadTotalFormat.format(leftLabel,rightLabel,total);}else if(hasLatency){var tooltip=WebInspector.NetworkTimeCalculator._latencyFormat.format(leftLabel);}else if(rightLabel){var tooltip=WebInspector.NetworkTimeCalculator._downloadFormat.format(rightLabel);} if(request.fetchedViaServiceWorker) tooltip=WebInspector.NetworkTimeCalculator._fromServiceWorkerFormat.format(tooltip);else if(request.cached()) tooltip=WebInspector.NetworkTimeCalculator._fromCacheFormat.format(tooltip);return{left:leftLabel,right:rightLabel,tooltip:tooltip};},updateBoundaries:function(request) {var lowerBound=this._lowerBound(request);var upperBound=this._upperBound(request);var changed=false;if(lowerBound!==-1||this.startAtZero) changed=this._extendBoundariesToIncludeTimestamp(this.startAtZero?0:lowerBound);if(upperBound!==-1) changed=this._extendBoundariesToIncludeTimestamp(upperBound)||changed;if(changed) this._boundaryChanged();},_extendBoundariesToIncludeTimestamp:function(timestamp) {var previousMinimumBoundary=this._minimumBoundary;var previousMaximumBoundary=this._maximumBoundary;if(typeof this._minimumBoundary==="undefined"||typeof this._maximumBoundary==="undefined"){this._minimumBoundary=timestamp;this._maximumBoundary=timestamp+1;}else{this._minimumBoundary=Math.min(timestamp,this._minimumBoundary);this._maximumBoundary=Math.max(timestamp,this._minimumBoundary+1,this._maximumBoundary);} return previousMinimumBoundary!==this._minimumBoundary||previousMaximumBoundary!==this._maximumBoundary;},_lowerBound:function(request) {return 0;},_upperBound:function(request) {return 0;},__proto__:WebInspector.Object.prototype} WebInspector.NetworkTransferTimeCalculator=function() {WebInspector.NetworkTimeCalculator.call(this,false);} WebInspector.NetworkTransferTimeCalculator.prototype={formatValue:function(value,precision) {return Number.secondsToString(value-this.zeroTime(),!!precision);},_lowerBound:function(request) {return request.issueTime();},_upperBound:function(request) {return request.endTime;},__proto__:WebInspector.NetworkTimeCalculator.prototype} WebInspector.NetworkTransferDurationCalculator=function() {WebInspector.NetworkTimeCalculator.call(this,true);} WebInspector.NetworkTransferDurationCalculator.prototype={formatValue:function(value,precision) {return Number.secondsToString(value,!!precision);},_upperBound:function(request) {return request.duration;},__proto__:WebInspector.NetworkTimeCalculator.prototype};WebInspector.NetworkLogView=function(filterBar,progressBarContainer,networkLogLargeRowsSetting) {WebInspector.VBox.call(this);this.setMinimumSize(50,64);this.registerRequiredCSS("network/networkLogView.css");this._networkHideDataURLSetting=WebInspector.settings.createSetting("networkHideDataURL",false);this._networkResourceTypeFiltersSetting=WebInspector.settings.createSetting("networkResourceTypeFilters",{});this._networkShowPrimaryLoadWaterfallSetting=WebInspector.settings.createSetting("networkShowPrimaryLoadWaterfall",false);this._filterBar=filterBar;this._progressBarContainer=progressBarContainer;this._networkLogLargeRowsSetting=networkLogLargeRowsSetting;var defaultColumnsVisibility=WebInspector.NetworkLogView._defaultColumnsVisibility;this._columnsVisibilitySetting=WebInspector.settings.createSetting("networkLogColumnsVisibility",defaultColumnsVisibility);var savedColumnsVisibility=this._columnsVisibilitySetting.get();var columnsVisibility={};for(var columnId in defaultColumnsVisibility) columnsVisibility[columnId]=savedColumnsVisibility.hasOwnProperty(columnId)?savedColumnsVisibility[columnId]:defaultColumnsVisibility[columnId];this._columnsVisibilitySetting.set(columnsVisibility);this._nodesByRequestId=new Map();this._staleRequestIds={};this._mainRequestLoadTime=-1;this._mainRequestDOMContentLoadedTime=-1;this._matchedRequestCount=0;this._eventDividers=[];this._highlightedSubstringChanges=[];this._filters=[];this._timeFilter=null;this._currentMatchedRequestNode=null;this._currentMatchedRequestIndex=-1;this._popupLinkifier=new WebInspector.Linkifier();this.linkifier=new WebInspector.Linkifier();this._gridMode=true;this._recording=false;this._preserveLog=false;this._rowHeight=0;this._addFilters();this._resetSuggestionBuilder();this._initializeView();WebInspector.moduleSetting("networkColorCodeResourceTypes").addChangeListener(this._invalidateAllItems,this);this._networkLogLargeRowsSetting.addChangeListener(this._updateRowsSize,this);WebInspector.targetManager.observeTargets(this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestStarted,this._onRequestStarted,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestUpdated,this._onRequestUpdated,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestUpdated,this);} WebInspector.NetworkLogView._isFilteredOutSymbol=Symbol("isFilteredOut");WebInspector.NetworkLogView._isMatchingSearchQuerySymbol=Symbol("isMatchingSearchQuery");WebInspector.NetworkLogView.HTTPSchemas={"http":true,"https":true,"ws":true,"wss":true};WebInspector.NetworkLogView._responseHeaderColumns=["Cache-Control","Connection","Content-Encoding","Content-Length","ETag","Keep-Alive","Last-Modified","Server","Vary"];WebInspector.NetworkLogView._defaultColumnsVisibility={method:false,status:true,protocol:false,scheme:false,domain:false,remoteAddress:false,type:true,initiator:true,cookies:false,setCookies:false,size:true,time:true,priority:false,connectionId:false,"Cache-Control":false,"Connection":false,"Content-Encoding":false,"Content-Length":false,"ETag":false,"Keep-Alive":false,"Last-Modified":false,"Server":false,"Vary":false};WebInspector.NetworkLogView._defaultRefreshDelay=200;WebInspector.NetworkLogView._waterfallMinOvertime=1;WebInspector.NetworkLogView._waterfallMaxOvertime=3;WebInspector.NetworkLogView.FilterType={Domain:"domain",HasResponseHeader:"has-response-header",Is:"is",LargerThan:"larger-than",Method:"method",MimeType:"mime-type",MixedContent:"mixed-content",Scheme:"scheme",SetCookieDomain:"set-cookie-domain",SetCookieName:"set-cookie-name",SetCookieValue:"set-cookie-value",StatusCode:"status-code"};WebInspector.NetworkLogView.MixedContentFilterValues={All:"all",Displayed:"displayed",Blocked:"blocked",BlockOverridden:"block-overridden"} WebInspector.NetworkLogView.IsFilterType={Running:"running"};WebInspector.NetworkLogView._searchKeys=Object.values(WebInspector.NetworkLogView.FilterType);WebInspector.NetworkLogView._columnTitles={"name":WebInspector.UIString("Name"),"method":WebInspector.UIString("Method"),"status":WebInspector.UIString("Status"),"protocol":WebInspector.UIString("Protocol"),"scheme":WebInspector.UIString("Scheme"),"domain":WebInspector.UIString("Domain"),"remoteAddress":WebInspector.UIString("Remote Address"),"type":WebInspector.UIString("Type"),"initiator":WebInspector.UIString("Initiator"),"cookies":WebInspector.UIString("Cookies"),"setCookies":WebInspector.UIString("Set-Cookies"),"size":WebInspector.UIString("Size"),"time":WebInspector.UIString("Time"),"connectionId":WebInspector.UIString("Connection Id"),"priority":WebInspector.UIString("Priority"),"timeline":WebInspector.UIString("Timeline"),"Cache-Control":WebInspector.UIString("Cache-Control"),"Connection":WebInspector.UIString("Connection"),"Content-Encoding":WebInspector.UIString("Content-Encoding"),"Content-Length":WebInspector.UIString("Content-Length"),"ETag":WebInspector.UIString("ETag"),"Keep-Alive":WebInspector.UIString("Keep-Alive"),"Last-Modified":WebInspector.UIString("Last-Modified"),"Server":WebInspector.UIString("Server"),"Vary":WebInspector.UIString("Vary")};WebInspector.NetworkLogView.prototype={setRecording:function(recording) {this._recording=recording;this._updateSummaryBar();},setPreserveLog:function(preserveLog) {this._preserveLog=preserveLog;},targetAdded:function(target) {if(!target.parentTarget()){target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameNavigated,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._loadEventFired,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded,this._domContentLoadedEventFired,this);} target.networkLog.requests().forEach(this._appendRequest.bind(this));},targetRemoved:function(target) {if(!target.parentTarget()){target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._mainFrameNavigated,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._loadEventFired,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded,this._domContentLoadedEventFired,this);}},setWindow:function(start,end) {if(!start&&!end){this._timeFilter=null;this._timeCalculator.setWindow(null);}else{this._timeFilter=WebInspector.NetworkLogView._requestTimeFilter.bind(null,start,end);this._timeCalculator.setWindow(new WebInspector.NetworkTimeBoundary(start,end));} this._updateDividersIfNeeded();this._filterRequests();},clearSelection:function() {if(this._dataGrid.selectedNode) this._dataGrid.selectedNode.deselect();},_addFilters:function() {this._textFilterUI=new WebInspector.TextFilterUI(true);this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged,this);this._filterBar.addFilter(this._textFilterUI);var dataURLSetting=this._networkHideDataURLSetting;this._dataURLFilterUI=new WebInspector.CheckboxFilterUI("hide-data-url",WebInspector.UIString("Hide data URLs"),true,dataURLSetting);this._dataURLFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged.bind(this),this);this._filterBar.addFilter(this._dataURLFilterUI);var filterItems=[];for(var categoryId in WebInspector.resourceCategories){var category=WebInspector.resourceCategories[categoryId];filterItems.push({name:category.title,label:category.shortTitle,title:category.title});} this._resourceCategoryFilterUI=new WebInspector.NamedBitSetFilterUI(filterItems,this._networkResourceTypeFiltersSetting);this._resourceCategoryFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,this._filterChanged.bind(this),this);this._filterBar.addFilter(this._resourceCategoryFilterUI);},_resetSuggestionBuilder:function() {this._suggestionBuilder=new WebInspector.FilterSuggestionBuilder(WebInspector.NetworkLogView._searchKeys);this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Is,WebInspector.NetworkLogView.IsFilterType.Running);this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan,"100");this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan,"10k");this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.LargerThan,"1M");this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);},_filterChanged:function(event) {this._removeAllNodeHighlights();this._parseFilterQuery(this._textFilterUI.value());this._filterRequests();},_initializeView:function() {this.element.id="network-container";this._createSortingFunctions();this._createCalculators();this._createTable();this._createTimelineGrid();this._summaryBarElement=this.element.createChild("div","network-summary-bar");this._updateRowsSize();this._popoverHelper=new WebInspector.PopoverHelper(this.element,this._getPopoverAnchor.bind(this),this._showPopover.bind(this),this._onHidePopover.bind(this));this.switchViewMode(true);},_showRecordingHint:function() {this._hideRecordingHint();this._recordingHint=this.element.createChild("div","network-status-pane fill");var hintText=this._recordingHint.createChild("div","recording-hint");var reloadShortcutNode=this._recordingHint.createChild("b");reloadShortcutNode.textContent=WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name;if(this._recording){var recordingText=hintText.createChild("span");recordingText.textContent=WebInspector.UIString("Recording network activity\u2026");hintText.createChild("br");hintText.appendChild(WebInspector.formatLocalized("Perform a request or hit %s to record the reload.",[reloadShortcutNode]));}else{var recordNode=hintText.createChild("b");recordNode.textContent=WebInspector.shortcutRegistry.shortcutTitleForAction("network.toggle-recording");hintText.appendChild(WebInspector.formatLocalized("Record (%s) or reload (%s) to display network activity.",[recordNode,reloadShortcutNode]));}},_hideRecordingHint:function() {if(this._recordingHint) this._recordingHint.remove();delete this._recordingHint;},elementsToRestoreScrollPositionsFor:function() {if(!this._dataGrid) return[];return[this._dataGrid.scrollContainer];},_createTimelineGrid:function() {this._timelineGrid=new WebInspector.TimelineGrid();this._timelineGrid.element.classList.add("network-timeline-grid");this._dataGrid.element.appendChild(this._timelineGrid.element);},_createTable:function() {var columns=[];columns.push({id:"name",titleDOMFragment:this._makeHeaderFragment(WebInspector.UIString("Name"),WebInspector.UIString("Path")),title:WebInspector.NetworkLogView._columnTitles["name"],weight:20});columns.push({id:"method",title:WebInspector.NetworkLogView._columnTitles["method"],weight:6});columns.push({id:"status",titleDOMFragment:this._makeHeaderFragment(WebInspector.UIString("Status"),WebInspector.UIString("Text")),title:WebInspector.NetworkLogView._columnTitles["status"],weight:6});columns.push({id:"protocol",title:WebInspector.NetworkLogView._columnTitles["protocol"],weight:6});columns.push({id:"scheme",title:WebInspector.NetworkLogView._columnTitles["scheme"],weight:6});columns.push({id:"domain",title:WebInspector.NetworkLogView._columnTitles["domain"],weight:6});columns.push({id:"remoteAddress",title:WebInspector.NetworkLogView._columnTitles["remoteAddress"],weight:10,align:WebInspector.DataGrid.Align.Right});columns.push({id:"type",title:WebInspector.NetworkLogView._columnTitles["type"],weight:6});columns.push({id:"initiator",title:WebInspector.NetworkLogView._columnTitles["initiator"],weight:10});columns.push({id:"cookies",title:WebInspector.NetworkLogView._columnTitles["cookies"],weight:6,align:WebInspector.DataGrid.Align.Right});columns.push({id:"setCookies",title:WebInspector.NetworkLogView._columnTitles["setCookies"],weight:6,align:WebInspector.DataGrid.Align.Right});columns.push({id:"size",titleDOMFragment:this._makeHeaderFragment(WebInspector.UIString("Size"),WebInspector.UIString("Content")),title:WebInspector.NetworkLogView._columnTitles["size"],weight:6,align:WebInspector.DataGrid.Align.Right});columns.push({id:"time",titleDOMFragment:this._makeHeaderFragment(WebInspector.UIString("Time"),WebInspector.UIString("Latency")),title:WebInspector.NetworkLogView._columnTitles["time"],weight:6,align:WebInspector.DataGrid.Align.Right});columns.push({id:"priority",title:WebInspector.NetworkLogView._columnTitles["priority"],weight:6});columns.push({id:"connectionId",title:WebInspector.NetworkLogView._columnTitles["connectionId"],weight:6});var responseHeaderColumns=WebInspector.NetworkLogView._responseHeaderColumns;for(var i=0;i<responseHeaderColumns.length;++i){var headerName=responseHeaderColumns[i];var descriptor={id:headerName,title:WebInspector.NetworkLogView._columnTitles[headerName],weight:6};if(headerName==="Content-Length") descriptor.align=WebInspector.DataGrid.Align.Right;columns.push(descriptor);} columns.push({id:"timeline",title:WebInspector.NetworkLogView._columnTitles["timeline"],sortable:false,weight:40,sort:WebInspector.DataGrid.Order.Ascending});for(var column of columns){column.sortable=column.id!=="timeline";column.nonSelectable=column.id!=="name";} this._dataGrid=new WebInspector.SortableDataGrid(columns);this._dataGrid.setStickToBottom(true);this._updateColumns();this._dataGrid.setName("networkLog");this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);this._dataGrid.element.classList.add("network-log-grid");this._dataGrid.element.addEventListener("contextmenu",this._contextMenu.bind(this),true);this._dataGrid.element.addEventListener("mousedown",this._dataGridMouseDown.bind(this),true);this._dataGrid.element.addEventListener("mousemove",this._dataGridMouseMove.bind(this),true);this._dataGrid.element.addEventListener("mouseleave",this._highlightInitiatorChain.bind(this,null),true);this._dataGrid.asWidget().show(this.element);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortItems,this);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.ColumnsResized,this._updateDividersIfNeeded,this);this._patchTimelineHeader();this._dataGrid.sortNodes(this._sortingFunctions.startTime,false);},_dataGridMouseDown:function(event) {if((!this._dataGrid.selectedNode&&event.button)||event.target.enclosingNodeOrSelfWithNodeName("a")) event.consume();},_dataGridMouseMove:function(event) {var node=event.shiftKey?this._dataGrid.dataGridNodeFromNode(event.target):null;this._highlightInitiatorChain(node?node.request():null);},_highlightInitiatorChain:function(request) {if(this._requestWithHighlightedInitiators===request) return;this._requestWithHighlightedInitiators=request;if(!request){for(var node of this._nodesByRequestId.values()){if(!node.dataGrid) continue;node.element().classList.remove("network-node-on-initiator-path","network-node-on-initiated-path");} return;} var initiators=request.initiatorChain();var initiated=new Set();for(var node of this._nodesByRequestId.values()){if(!node.dataGrid) continue;var localInitiators=node.request().initiatorChain();if(localInitiators.has(request)) initiated.add(node.request());} for(var node of this._nodesByRequestId.values()){if(!node.dataGrid) continue;node.element().classList.toggle("network-node-on-initiator-path",node.request()!==request&&initiators.has(node.request()));node.element().classList.toggle("network-node-on-initiated-path",node.request()!==request&&initiated.has(node.request()));}},_makeHeaderFragment:function(title,subtitle) {var fragment=createDocumentFragment();fragment.createTextChild(title);var subtitleDiv=fragment.createChild("div","network-header-subtitle");subtitleDiv.createTextChild(subtitle);return fragment;},_patchTimelineHeader:function() {var timelineSorting=createElement("select");var option=createElement("option");option.value="startTime";option.label=WebInspector.UIString("Timeline");option.disabled=true;timelineSorting.appendChild(option);option=createElement("option");option.value="startTime";option.label=WebInspector.UIString("Timeline \u2013 Start Time");option.sortOrder=WebInspector.DataGrid.Order.Ascending;timelineSorting.appendChild(option);option=createElement("option");option.value="responseTime";option.label=WebInspector.UIString("Timeline \u2013 Response Time");option.sortOrder=WebInspector.DataGrid.Order.Ascending;timelineSorting.appendChild(option);option=createElement("option");option.value="endTime";option.label=WebInspector.UIString("Timeline \u2013 End Time");option.sortOrder=WebInspector.DataGrid.Order.Ascending;timelineSorting.appendChild(option);option=createElement("option");option.value="duration";option.label=WebInspector.UIString("Timeline \u2013 Total Duration");option.sortOrder=WebInspector.DataGrid.Order.Descending;timelineSorting.appendChild(option);option=createElement("option");option.value="latency";option.label=WebInspector.UIString("Timeline \u2013 Latency");option.sortOrder=WebInspector.DataGrid.Order.Descending;timelineSorting.appendChild(option);var header=this._dataGrid.headerTableHeader("timeline");header.replaceChild(timelineSorting,header.firstChild);header.createChild("div","sort-order-icon-container").createChild("div","sort-order-icon");timelineSorting.selectedIndex=1;timelineSorting.addEventListener("click",function(event){event.consume();},false);timelineSorting.addEventListener("change",this._sortByTimeline.bind(this),false);this._timelineSortSelector=timelineSorting;},_createSortingFunctions:function() {this._sortingFunctions={};this._sortingFunctions.name=WebInspector.NetworkDataGridNode.NameComparator;this._sortingFunctions.method=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"requestMethod");this._sortingFunctions.status=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"statusCode");this._sortingFunctions.protocol=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"protocol");this._sortingFunctions.scheme=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"scheme");this._sortingFunctions.domain=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"domain");this._sortingFunctions.remoteAddress=WebInspector.NetworkDataGridNode.RemoteAddressComparator;this._sortingFunctions.type=WebInspector.NetworkDataGridNode.TypeComparator;this._sortingFunctions.initiator=WebInspector.NetworkDataGridNode.InitiatorComparator;this._sortingFunctions.cookies=WebInspector.NetworkDataGridNode.RequestCookiesCountComparator;this._sortingFunctions.setCookies=WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator;this._sortingFunctions.size=WebInspector.NetworkDataGridNode.SizeComparator;this._sortingFunctions.time=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"duration");this._sortingFunctions.connectionId=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"connectionId");this._sortingFunctions.priority=WebInspector.NetworkDataGridNode.InitialPriorityComparator;this._sortingFunctions.timeline=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"startTime");this._sortingFunctions.startTime=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"startTime");this._sortingFunctions.endTime=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"endTime");this._sortingFunctions.responseTime=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"responseReceivedTime");this._sortingFunctions.duration=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"duration");this._sortingFunctions.latency=WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null,"latency");this._sortingFunctions["Cache-Control"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Cache-Control");this._sortingFunctions["Connection"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Connection");this._sortingFunctions["Content-Encoding"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Content-Encoding");this._sortingFunctions["Content-Length"]=WebInspector.NetworkDataGridNode.ResponseHeaderNumberComparator.bind(null,"Content-Length");this._sortingFunctions["ETag"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"ETag");this._sortingFunctions["Keep-Alive"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Keep-Alive");this._sortingFunctions["Last-Modified"]=WebInspector.NetworkDataGridNode.ResponseHeaderDateComparator.bind(null,"Last-Modified");this._sortingFunctions["Server"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Server");this._sortingFunctions["Vary"]=WebInspector.NetworkDataGridNode.ResponseHeaderStringComparator.bind(null,"Vary");},_createCalculators:function() {this._timeCalculator=new WebInspector.NetworkTransferTimeCalculator();this._durationCalculator=new WebInspector.NetworkTransferDurationCalculator();this._calculators={};this._calculators.timeline=this._timeCalculator;this._calculators.startTime=this._timeCalculator;this._calculators.endTime=this._timeCalculator;this._calculators.responseTime=this._timeCalculator;this._calculators.duration=this._durationCalculator;this._calculators.latency=this._durationCalculator;this._calculator=this._timeCalculator;},_sortItems:function() {this._removeAllNodeHighlights();var columnIdentifier=this._dataGrid.sortColumnIdentifier();if(columnIdentifier==="timeline"){this._sortByTimeline();return;} var sortingFunction=this._sortingFunctions[columnIdentifier];if(!sortingFunction) return;this._dataGrid.sortNodes(sortingFunction,!this._dataGrid.isSortOrderAscending());this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode),false);this._timelineSortSelector.selectedIndex=0;},_sortByTimeline:function() {this._removeAllNodeHighlights();var selectedIndex=this._timelineSortSelector.selectedIndex;if(!selectedIndex) selectedIndex=1;var selectedOption=this._timelineSortSelector[selectedIndex];var value=selectedOption.value;this._setCalculator(this._calculators[value]);var sortingFunction=this._sortingFunctions[value];this._dataGrid.sortNodes(sortingFunction);this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode),false);this._dataGrid.markColumnAsSortedBy("timeline",selectedOption.sortOrder);},_updateSummaryBar:function() {var requestsNumber=this._nodesByRequestId.size;if(!requestsNumber){this._showRecordingHint();return;} this._hideRecordingHint();var transferSize=0;var selectedRequestsNumber=0;var selectedTransferSize=0;var baseTime=-1;var maxTime=-1;var nodes=this._nodesByRequestId.valuesArray();for(var i=0;i<nodes.length;++i){var request=nodes[i].request();var requestTransferSize=request.transferSize;transferSize+=requestTransferSize;if(!nodes[i][WebInspector.NetworkLogView._isFilteredOutSymbol]){selectedRequestsNumber++;selectedTransferSize+=requestTransferSize;} if(request.url===request.target().resourceTreeModel.inspectedPageURL()&&request.resourceType()===WebInspector.resourceTypes.Document) baseTime=request.startTime;if(request.endTime>maxTime) maxTime=request.endTime;} var summaryBar=this._summaryBarElement;summaryBar.removeChildren();var separator="\u2002\u2758\u2002";var text="";function appendChunk(chunk) {var span=summaryBar.createChild("span");span.textContent=chunk;text+=chunk;return span;} if(selectedRequestsNumber!==requestsNumber){appendChunk(WebInspector.UIString("%d / %d requests",selectedRequestsNumber,requestsNumber));appendChunk(separator);appendChunk(WebInspector.UIString("%s / %s transferred",Number.bytesToString(selectedTransferSize),Number.bytesToString(transferSize)));}else{appendChunk(WebInspector.UIString("%d requests",requestsNumber));appendChunk(separator);appendChunk(WebInspector.UIString("%s transferred",Number.bytesToString(transferSize)));} if(baseTime!==-1&&maxTime!==-1){appendChunk(separator);appendChunk(WebInspector.UIString("Finish: %s",Number.secondsToString(maxTime-baseTime)));if(this._mainRequestDOMContentLoadedTime!==-1&&this._mainRequestDOMContentLoadedTime>baseTime){appendChunk(separator);var domContentLoadedText=WebInspector.UIString("DOMContentLoaded: %s",Number.secondsToString(this._mainRequestDOMContentLoadedTime-baseTime));appendChunk(domContentLoadedText).classList.add("summary-blue");} if(this._mainRequestLoadTime!==-1){appendChunk(separator);var loadText=WebInspector.UIString("Load: %s",Number.secondsToString(this._mainRequestLoadTime-baseTime));appendChunk(loadText).classList.add("summary-red");}} summaryBar.title=text;},_scheduleRefresh:function() {if(this._needsRefresh) return;this._needsRefresh=true;if(this.isShowing()&&!this._refreshTimeout) this._refreshTimeout=setTimeout(this.refresh.bind(this),WebInspector.NetworkLogView._defaultRefreshDelay);},_updateDividersIfNeeded:function() {if(!this.isShowing()){this._scheduleRefresh();return;} var timelineOffset=this._dataGrid.columnOffset("timeline");if(timelineOffset) this._timelineGrid.element.style.left=timelineOffset+"px";var calculator=this.calculator();calculator.setDisplayWindow(this._timelineGrid.dividersElement.clientWidth);this._timelineGrid.updateDividers(calculator,75);if(calculator.startAtZero){return;} this._updateEventDividers();},addFilmStripFrames:function(times) {this._addEventDividers(times,"network-frame-divider");},selectFilmStripFrame:function(time) {for(var divider of this._eventDividers) divider.element.classList.toggle("network-frame-divider-selected",divider.time===time);},clearFilmStripFrame:function() {for(var divider of this._eventDividers) divider.element.classList.toggle("network-frame-divider-selected",false);},_addEventDividers:function(times,className) {for(var i=0;i<times.length;++i){var element=createElementWithClass("div","network-event-divider "+className);this._timelineGrid.addEventDivider(element);this._eventDividers.push({time:times[i],element:element});} this._updateEventDividers();this._scheduleRefresh();},_updateEventDividers:function() {var calculator=this.calculator();for(var divider of this._eventDividers){var timePercent=calculator.computePercentageFromEventTime(divider.time);divider.element.classList.toggle("invisible",timePercent<0);divider.element.style.left=timePercent+"%";}},_refreshIfNeeded:function() {if(this._needsRefresh) this.refresh();},_invalidateAllItems:function() {var requestIds=this._nodesByRequestId.keysArray();for(var i=0;i<requestIds.length;++i) this._staleRequestIds[requestIds[i]]=true;this.refresh();},timeCalculator:function() {return this._timeCalculator;},calculator:function() {return this._calculator;},_setCalculator:function(x) {if(!x||this._calculator===x) return;this._calculator=x;this._calculator.reset();if(this._calculator.startAtZero) this._timelineGrid.hideEventDividers();else this._timelineGrid.showEventDividers();this._invalidateAllItems();},_loadEventFired:function(event) {if(!this._recording) return;var data=(event.data);if(data){this._mainRequestLoadTime=data;this._addEventDividers([data],"network-red-divider");}},_domContentLoadedEventFired:function(event) {if(!this._recording) return;var data=(event.data);if(data){this._mainRequestDOMContentLoadedTime=data;this._addEventDividers([data],"network-blue-divider");}},wasShown:function() {this._refreshIfNeeded();},willHide:function() {this._popoverHelper.hidePopover();},refresh:function() {this._needsRefresh=false;if(this._refreshTimeout){clearTimeout(this._refreshTimeout);delete this._refreshTimeout;} this._removeAllNodeHighlights();var oldBoundary=this.calculator().boundary();this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);var dataGrid=this._dataGrid;var rootNode=dataGrid.rootNode();var nodesToInsert=[];var nodesToRefresh=[];for(var requestId in this._staleRequestIds){var node=this._nodesByRequestId.get(requestId);if(!node) continue;var isFilteredOut=!this._applyFilter(node);if(node[WebInspector.NetworkLogView._isFilteredOutSymbol]!==isFilteredOut){if(!node[WebInspector.NetworkLogView._isFilteredOutSymbol]) rootNode.removeChild(node);node[WebInspector.NetworkLogView._isFilteredOutSymbol]=isFilteredOut;if(!node[WebInspector.NetworkLogView._isFilteredOutSymbol]) nodesToInsert.push(node);} if(!isFilteredOut) nodesToRefresh.push(node);var request=node.request();this._timeCalculator.updateBoundaries(request);this._durationCalculator.updateBoundaries(request);} for(var i=0;i<nodesToInsert.length;++i){var node=nodesToInsert[i];var request=node.request();dataGrid.insertChild(node);node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]=this._matchRequest(request);} for(var node of nodesToRefresh) node.refresh();this._highlightNthMatchedRequestForSearch(this._updateMatchCountAndFindMatchIndex(this._currentMatchedRequestNode),false);if(!this.calculator().boundary().equals(oldBoundary)){this._updateDividersIfNeeded();var nodes=this._nodesByRequestId.valuesArray();for(var i=0;i<nodes.length;++i) nodes[i].refreshGraph();} this._staleRequestIds={};this._updateSummaryBar();},reset:function() {this._requestWithHighlightedInitiators=null;this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RequestSelected,null);this._clearSearchMatchedList();if(this._popoverHelper) this._popoverHelper.hidePopover();this._timeFilter=null;this._calculator.reset();this._timeCalculator.setWindow(null);var nodes=this._nodesByRequestId.valuesArray();for(var i=0;i<nodes.length;++i) nodes[i].dispose();this._nodesByRequestId.clear();this._staleRequestIds={};this._resetSuggestionBuilder();this._mainRequestLoadTime=-1;this._mainRequestDOMContentLoadedTime=-1;this._eventDividers=[];this._timelineGrid.removeEventDividers();if(this._dataGrid){this._dataGrid.rootNode().removeChildren();this._updateDividersIfNeeded();this._updateSummaryBar();}},setTextFilterValue:function(filterString) {this._textFilterUI.setValue(filterString);},_onRequestStarted:function(event) {if(!this._recording) return;var request=(event.data);this._appendRequest(request);},_appendRequest:function(request) {var node=new WebInspector.NetworkDataGridNode(this,request);node[WebInspector.NetworkLogView._isFilteredOutSymbol]=true;node[WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]=false;var originalRequestNode=this._nodesByRequestId.get(request.requestId);if(originalRequestNode) this._nodesByRequestId.set(originalRequestNode.request().requestId,originalRequestNode);this._nodesByRequestId.set(request.requestId,node);if(request.redirects){for(var i=0;i<request.redirects.length;++i) this._refreshRequest(request.redirects[i]);} this._refreshRequest(request);},_onRequestUpdated:function(event) {var request=(event.data);this._refreshRequest(request);},_refreshRequest:function(request) {if(!this._nodesByRequestId.get(request.requestId)) return;WebInspector.NetworkLogView._subdomains(request.domain).forEach(this._suggestionBuilder.addItem.bind(this._suggestionBuilder,WebInspector.NetworkLogView.FilterType.Domain));this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Method,request.requestMethod);this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MimeType,request.mimeType);this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.Scheme,""+request.scheme);this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.StatusCode,""+request.statusCode);if(request.mixedContentType!=="none"){this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent,WebInspector.NetworkLogView.MixedContentFilterValues.All);} if(request.mixedContentType==="optionally-blockable"){this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent,WebInspector.NetworkLogView.MixedContentFilterValues.Displayed);} if(request.mixedContentType==="blockable"){var suggestion=request.wasBlocked()?WebInspector.NetworkLogView.MixedContentFilterValues.Blocked:WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden;this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.MixedContent,suggestion);} var responseHeaders=request.responseHeaders;for(var i=0,l=responseHeaders.length;i<l;++i) this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.HasResponseHeader,responseHeaders[i].name);var cookies=request.responseCookies;for(var i=0,l=cookies?cookies.length:0;i<l;++i){var cookie=cookies[i];this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieDomain,cookie.domain());this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieName,cookie.name());this._suggestionBuilder.addItem(WebInspector.NetworkLogView.FilterType.SetCookieValue,cookie.value());} this._staleRequestIds[request.requestId]=true;this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.UpdateRequest,request);this._scheduleRefresh();},_mainFrameNavigated:function(event) {if(!this._recording) return;var frame=(event.data);var loaderId=frame.loaderId;var requestsToPick=[];var requests=frame.target().networkLog.requests();for(var i=0;i<requests.length;++i){var request=requests[i];if(request.loaderId===loaderId) requestsToPick.push(request);} if(!this._preserveLog){this.reset();for(var i=0;i<requestsToPick.length;++i) this._appendRequest(requestsToPick[i]);} for(var i=0;i<requestsToPick.length;++i){var request=requestsToPick[i];var node=this._nodesByRequestId.get(request.requestId);if(node){node.markAsNavigationRequest();break;}}},switchViewMode:function(gridMode) {if(this._gridMode===gridMode) return;this._gridMode=gridMode;if(gridMode){if(this._dataGrid.selectedNode) this._dataGrid.selectedNode.selected=false;}else{this._removeAllNodeHighlights();this._popoverHelper.hidePopover();} this.element.classList.toggle("brief-mode",!gridMode);this._updateColumns();},rowHeight:function() {return this._rowHeight;},_updateRowsSize:function() {var largeRows=!!this._networkLogLargeRowsSetting.get();this._rowHeight=largeRows?41:21;this._dataGrid.element.classList.toggle("small",!largeRows);this._timelineGrid.element.classList.toggle("small",!largeRows);this._dataGrid.scheduleUpdate();},_getPopoverAnchor:function(element,event) {if(!this._gridMode) return;var anchor=element.enclosingNodeOrSelfWithClass("network-graph-bar")||element.enclosingNodeOrSelfWithClass("network-graph-label");if(anchor&&anchor.parentElement.request&&anchor.parentElement.request.timing) return anchor;anchor=element.enclosingNodeOrSelfWithClass("network-script-initiated");if(anchor&&anchor.request){var initiator=(anchor.request).initiator();if(initiator&&initiator.stack) return anchor;}},_showPopover:function(anchor,popover) {var content;if(anchor.classList.contains("network-script-initiated")){var request=(anchor.request);var initiator=(request.initiator());content=WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(request.target(),this._popupLinkifier,initiator.stack);popover.setCanShrink(true);}else{content=WebInspector.RequestTimingView.createTimingTable(anchor.parentElement.request,this._timeCalculator.minimumBoundary());popover.setCanShrink(false);} popover.showForAnchor(content,anchor);},_onHidePopover:function() {this._popupLinkifier.reset();},_updateColumns:function() {if(!this._dataGrid) return;var gridMode=this._gridMode;var visibleColumns={"name":true};if(gridMode) visibleColumns["timeline"]=true;if(gridMode){var columnsVisibility=this._columnsVisibilitySetting.get();for(var columnIdentifier in columnsVisibility) visibleColumns[columnIdentifier]=columnsVisibility[columnIdentifier];} this._dataGrid.setColumnsVisiblity(visibleColumns);},_toggleColumnVisibility:function(columnIdentifier) {var columnsVisibility=this._columnsVisibilitySetting.get();columnsVisibility[columnIdentifier]=!columnsVisibility[columnIdentifier];this._columnsVisibilitySetting.set(columnsVisibility);this._updateColumns();},_getConfigurableColumnIDs:function() {if(this._configurableColumnIDs) return this._configurableColumnIDs;var columnTitles=WebInspector.NetworkLogView._columnTitles;function compare(id1,id2) {return columnTitles[id1].compareTo(columnTitles[id2]);} var columnIDs=Object.keys(this._columnsVisibilitySetting.get());this._configurableColumnIDs=columnIDs.sort(compare);return this._configurableColumnIDs;},_contextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);if(this._gridMode&&event.target.isSelfOrDescendant(this._dataGrid.headerTableBody)){var columnsVisibility=this._columnsVisibilitySetting.get();var columnIDs=this._getConfigurableColumnIDs();var columnTitles=WebInspector.NetworkLogView._columnTitles;for(var i=0;i<columnIDs.length;++i){var columnIdentifier=columnIDs[i];contextMenu.appendCheckboxItem(columnTitles[columnIdentifier],this._toggleColumnVisibility.bind(this,columnIdentifier),!!columnsVisibility[columnIdentifier]);} contextMenu.show();return;} var gridNode=this._dataGrid.dataGridNodeFromNode(event.target);var request=gridNode&&gridNode.request();function openResourceInNewTab(url) {InspectorFrontendHost.openInNewTab(url);} if(request){contextMenu.appendApplicableItems(request);if(request.requestHeadersText()) contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^request ^headers"),this._copyRequestHeaders.bind(this,request));if(request.responseHeadersText) contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^response ^headers"),this._copyResponseHeaders.bind(this,request));if(request.finished) contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^response"),this._copyResponse.bind(this,request));if(WebInspector.isWin()){contextMenu.appendItem(WebInspector.UIString("Copy as cURL (cmd)"),this._copyCurlCommand.bind(this,request,"win"));contextMenu.appendItem(WebInspector.UIString("Copy as cURL (bash)"),this._copyCurlCommand.bind(this,request,"unix"));}else{contextMenu.appendItem(WebInspector.UIString("Copy as cURL"),this._copyCurlCommand.bind(this,request,"unix"));}} contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^all as HAR"),this._copyAll.bind(this));contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString.capitalize("Save as HAR with ^content"),this._exportAll.bind(this));contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cache"),this._clearBrowserCache.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^browser ^cookies"),this._clearBrowserCookies.bind(this));var blockedSetting=WebInspector.moduleSetting("blockedURLs");if(request&&Runtime.experiments.isEnabled("requestBlocking")){contextMenu.appendSeparator();var urlWithoutScheme=request.parsedURL.urlWithoutScheme();if(urlWithoutScheme&&blockedSetting.get().indexOf(urlWithoutScheme)===-1) contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^request URL"),addBlockedURL.bind(null,urlWithoutScheme));var domain=request.parsedURL.domain();if(domain&&blockedSetting.get().indexOf(domain)===-1) contextMenu.appendItem(WebInspector.UIString.capitalize("Block ^request ^domain"),addBlockedURL.bind(null,domain));function addBlockedURL(url) {var list=blockedSetting.get();list.push(url);blockedSetting.set(list);WebInspector.inspectorView.showViewInDrawer("network.blocked-urls");}} if(request&&request.resourceType()===WebInspector.resourceTypes.XHR){contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("Replay XHR"),request.replayXHR.bind(request));contextMenu.appendSeparator();} contextMenu.show();},_harRequests:function() {var requests=this._nodesByRequestId.valuesArray().map(function(node){return node.request();});var httpRequests=requests.filter(WebInspector.NetworkLogView.HTTPRequestsFilter);return httpRequests.filter(WebInspector.NetworkLogView.FinishedRequestsFilter);},_copyAll:function() {var harArchive={log:(new WebInspector.HARLog(this._harRequests())).build()};InspectorFrontendHost.copyText(JSON.stringify(harArchive,null,2));},_copyRequestHeaders:function(request) {InspectorFrontendHost.copyText(request.requestHeadersText());},_copyResponse:function(request) {function callback(content) {if(request.contentEncoded) content=request.asDataURL();InspectorFrontendHost.copyText(content||"");} request.requestContent().then(callback);},_copyResponseHeaders:function(request) {InspectorFrontendHost.copyText(request.responseHeadersText);},_copyCurlCommand:function(request,platform) {InspectorFrontendHost.copyText(this._generateCurlCommand(request,platform));},_exportAll:function() {var filename=WebInspector.targetManager.inspectedPageDomain()+".har";var stream=new WebInspector.FileOutputStream();stream.open(filename,openCallback.bind(this));function openCallback(accepted) {if(!accepted) return;var progressIndicator=new WebInspector.ProgressIndicator();this._progressBarContainer.appendChild(progressIndicator.element);var harWriter=new WebInspector.HARWriter();harWriter.write(stream,this._harRequests(),progressIndicator);}},_clearBrowserCache:function() {if(confirm(WebInspector.UIString("Are you sure you want to clear browser cache?"))) WebInspector.multitargetNetworkManager.clearBrowserCache();},_clearBrowserCookies:function() {if(confirm(WebInspector.UIString("Are you sure you want to clear browser cookies?"))) WebInspector.multitargetNetworkManager.clearBrowserCookies();},_matchRequest:function(request) {var re=this._searchRegExp;if(!re) return false;return re.test(request.name())||(this._networkLogLargeRowsSetting.get()&&re.test(request.path()));},_clearSearchMatchedList:function() {this._matchedRequestCount=-1;this._currentMatchedRequestNode=null;this._removeAllHighlights();},_removeAllHighlights:function() {this._removeAllNodeHighlights();for(var i=0;i<this._highlightedSubstringChanges.length;++i) WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);this._highlightedSubstringChanges=[];},_highlightNthMatchedRequestForSearch:function(n,reveal) {this._removeAllHighlights();var nodes=this._dataGrid.rootNode().children;var matchCount=0;var node=null;for(var i=0;i<nodes.length;++i){if(nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]){if(matchCount===n){node=nodes[i];break;} matchCount++;}} if(!node){this._currentMatchedRequestNode=null;return;} var request=node.request();if(reveal) WebInspector.Revealer.reveal(request);var highlightedSubstringChanges=node.highlightMatchedSubstring(this._searchRegExp);this._highlightedSubstringChanges.push(highlightedSubstringChanges);this._currentMatchedRequestNode=node;this._currentMatchedRequestIndex=n;this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated,n);},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var query=searchConfig.query;var currentMatchedRequestNode=this._currentMatchedRequestNode;this._clearSearchMatchedList();this._searchRegExp=createPlainTextSearchRegex(query,"i");var nodes=this._dataGrid.rootNode().children;for(var i=0;i<nodes.length;++i) nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]=this._matchRequest(nodes[i].request());var newMatchedRequestIndex=this._updateMatchCountAndFindMatchIndex(currentMatchedRequestNode);if(!newMatchedRequestIndex&&jumpBackwards) newMatchedRequestIndex=this._matchedRequestCount-1;this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex,shouldJump);},supportsCaseSensitiveSearch:function() {return false;},supportsRegexSearch:function() {return true;},_updateMatchCountAndFindMatchIndex:function(node) {var nodes=this._dataGrid.rootNode().children;var matchCount=0;var matchIndex=0;for(var i=0;i<nodes.length;++i){if(!nodes[i][WebInspector.NetworkLogView._isMatchingSearchQuerySymbol]) continue;if(node===nodes[i]) matchIndex=matchCount;matchCount++;} if(this._matchedRequestCount!==matchCount){this._matchedRequestCount=matchCount;this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated,matchCount);} return matchIndex;},_normalizeSearchResultIndex:function(index) {return(index+this._matchedRequestCount)%this._matchedRequestCount;},_applyFilter:function(node) {var request=node.request();if(this._timeFilter&&!this._timeFilter(request)) return false;var categoryName=request.resourceType().category().title;if(!this._resourceCategoryFilterUI.accept(categoryName)) return false;if(this._dataURLFilterUI.checked()&&request.parsedURL.isDataURL()) return false;if(request.statusText==="Service Worker Fallback Required") return false;for(var i=0;i<this._filters.length;++i){if(!this._filters[i](request)) return false;} return true;},_parseFilterQuery:function(query) {var parsedQuery;if(this._textFilterUI.isRegexChecked()&&query!=="") parsedQuery={text:[query],filters:[]};else parsedQuery=this._suggestionBuilder.parseQuery(query);this._filters=parsedQuery.text.map(this._createTextFilter,this);var n=parsedQuery.filters.length;for(var i=0;i<n;++i){var filter=parsedQuery.filters[i];var filterType=(filter.type.toLowerCase());this._filters.push(this._createFilter(filterType,filter.data,filter.negative));}},_createTextFilter:function(text) {var negative=false;if(!this._textFilterUI.isRegexChecked()&&text[0]==="-"&&text.length>1){negative=true;text=text.substring(1);} var regexp=this._textFilterUI.regex();var filter=WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null,regexp);if(negative) filter=WebInspector.NetworkLogView._negativeFilter.bind(null,filter);return filter;},_createFilter:function(type,value,negative) {var filter=this._createSpecialFilter(type,value);if(!filter) return this._createTextFilter((negative?"-":"")+type+":"+value);if(negative) return WebInspector.NetworkLogView._negativeFilter.bind(null,filter);return filter;},_createSpecialFilter:function(type,value) {switch(type){case WebInspector.NetworkLogView.FilterType.Domain:return WebInspector.NetworkLogView._createRequestDomainFilter(value);case WebInspector.NetworkLogView.FilterType.HasResponseHeader:return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.Is:if(value.toLowerCase()===WebInspector.NetworkLogView.IsFilterType.Running) return WebInspector.NetworkLogView._runningRequestFilter;break;case WebInspector.NetworkLogView.FilterType.LargerThan:return this._createSizeFilter(value.toLowerCase());case WebInspector.NetworkLogView.FilterType.Method:return WebInspector.NetworkLogView._requestMethodFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.MimeType:return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.MixedContent:return WebInspector.NetworkLogView._requestMixedContentFilter.bind(null,(value));case WebInspector.NetworkLogView.FilterType.Scheme:return WebInspector.NetworkLogView._requestSchemeFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.SetCookieDomain:return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.SetCookieName:return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.SetCookieValue:return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind(null,value);case WebInspector.NetworkLogView.FilterType.StatusCode:return WebInspector.NetworkLogView._statusCodeFilter.bind(null,value);} return null;},_createSizeFilter:function(value) {var multiplier=1;if(value.endsWith("k")){multiplier=1024;value=value.substring(0,value.length-1);}else if(value.endsWith("m")){multiplier=1024*1024;value=value.substring(0,value.length-1);} var quantity=Number(value);if(isNaN(quantity)) return null;return WebInspector.NetworkLogView._requestSizeLargerThanFilter.bind(null,quantity*multiplier);},_filterRequests:function() {this._removeAllHighlights();this._invalidateAllItems();},jumpToPreviousSearchResult:function() {if(!this._matchedRequestCount) return;var index=this._normalizeSearchResultIndex(this._currentMatchedRequestIndex-1);this._highlightNthMatchedRequestForSearch(index,true);},jumpToNextSearchResult:function() {if(!this._matchedRequestCount) return;var index=this._normalizeSearchResultIndex(this._currentMatchedRequestIndex+1);this._highlightNthMatchedRequestForSearch(index,true);},searchCanceled:function() {delete this._searchRegExp;this._clearSearchMatchedList();this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated,0);},revealAndHighlightRequest:function(request) {this._removeAllNodeHighlights();var node=this._nodesByRequestId.get(request.requestId);if(node){node.reveal();this._highlightNode(node);}},_removeAllNodeHighlights:function() {if(this._highlightedNode){this._highlightedNode.element().classList.remove("highlighted-row");delete this._highlightedNode;}},_highlightNode:function(node) {WebInspector.runCSSAnimationOnce(node.element(),"highlighted-row");this._highlightedNode=node;},_generateCurlCommand:function(request,platform) {var command=["curl"];var ignoredHeaders={"host":1,"method":1,"path":1,"scheme":1,"version":1};function escapeStringWin(str) {return"\""+str.replace(/"/g,"\"\"").replace(/%/g,"\"%\"").replace(/\\/g,"\\\\").replace(/[\r\n]+/g,"\"^$&\"")+"\"";} function escapeStringPosix(str) {function escapeCharacter(x) {var code=x.charCodeAt(0);if(code<256){return code<16?"\\x0"+code.toString(16):"\\x"+code.toString(16);} code=code.toString(16);return"\\u"+("0000"+code).substr(code.length,4);} if(/[^\x20-\x7E]|\'/.test(str)){return"$\'"+str.replace(/\\/g,"\\\\").replace(/\'/g,"\\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[^\x20-\x7E]/g,escapeCharacter)+"'";}else{return"'"+str+"'";}} var escapeString=platform==="win"?escapeStringWin:escapeStringPosix;command.push(escapeString(request.url).replace(/[[{}\]]/g,"\\$&"));var inferredMethod="GET";var data=[];var requestContentType=request.requestContentType();if(requestContentType&&requestContentType.startsWith("application/x-www-form-urlencoded")&&request.requestFormData){data.push("--data");data.push(escapeString(request.requestFormData));ignoredHeaders["content-length"]=true;inferredMethod="POST";}else if(request.requestFormData){data.push("--data-binary");data.push(escapeString(request.requestFormData));ignoredHeaders["content-length"]=true;inferredMethod="POST";} if(request.requestMethod!==inferredMethod){command.push("-X");command.push(request.requestMethod);} var requestHeaders=request.requestHeaders();for(var i=0;i<requestHeaders.length;i++){var header=requestHeaders[i];var name=header.name.replace(/^:/,"");if(name.toLowerCase()in ignoredHeaders) continue;command.push("-H");command.push(escapeString(name+": "+header.value));} command=command.concat(data);command.push("--compressed");if(request.securityState()===SecurityAgent.SecurityState.Insecure) command.push("--insecure");return command.join(" ");},__proto__:WebInspector.VBox.prototype} WebInspector.NetworkLogView.Filter;WebInspector.NetworkLogView._negativeFilter=function(filter,request) {return!filter(request);} WebInspector.NetworkLogView._requestNameOrPathFilter=function(regex,request) {if(!regex) return false;return regex.test(request.name())||regex.test(request.path());} WebInspector.NetworkLogView._subdomains=function(domain) {var result=[domain];var indexOfPeriod=domain.indexOf(".");while(indexOfPeriod!==-1){result.push("*"+domain.substring(indexOfPeriod));indexOfPeriod=domain.indexOf(".",indexOfPeriod+1);} return result;} WebInspector.NetworkLogView._createRequestDomainFilter=function(value) {function escapeForRegExp(string) {return string.escapeForRegExp();} var escapedPattern=value.split("*").map(escapeForRegExp).join(".*");return WebInspector.NetworkLogView._requestDomainFilter.bind(null,new RegExp("^"+escapedPattern+"$","i"));} WebInspector.NetworkLogView._requestDomainFilter=function(regex,request) {return regex.test(request.domain);} WebInspector.NetworkLogView._runningRequestFilter=function(request) {return!request.finished;} WebInspector.NetworkLogView._requestResponseHeaderFilter=function(value,request) {return request.responseHeaderValue(value)!==undefined;} WebInspector.NetworkLogView._requestMethodFilter=function(value,request) {return request.requestMethod===value;} WebInspector.NetworkLogView._requestMimeTypeFilter=function(value,request) {return request.mimeType===value;} WebInspector.NetworkLogView._requestMixedContentFilter=function(value,request) {if(value===WebInspector.NetworkLogView.MixedContentFilterValues.Displayed){return request.mixedContentType==="optionally-blockable";}else if(value===WebInspector.NetworkLogView.MixedContentFilterValues.Blocked){return request.mixedContentType==="blockable"&&request.wasBlocked();}else if(value===WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden){return request.mixedContentType==="blockable"&&!request.wasBlocked();}else if(value===WebInspector.NetworkLogView.MixedContentFilterValues.All){return request.mixedContentType!=="none";} return false;} WebInspector.NetworkLogView._requestSchemeFilter=function(value,request) {return request.scheme===value;} WebInspector.NetworkLogView._requestSetCookieDomainFilter=function(value,request) {var cookies=request.responseCookies;for(var i=0,l=cookies?cookies.length:0;i<l;++i){if(cookies[i].domain()===value) return true;} return false;} WebInspector.NetworkLogView._requestSetCookieNameFilter=function(value,request) {var cookies=request.responseCookies;for(var i=0,l=cookies?cookies.length:0;i<l;++i){if(cookies[i].name()===value) return true;} return false;} WebInspector.NetworkLogView._requestSetCookieValueFilter=function(value,request) {var cookies=request.responseCookies;for(var i=0,l=cookies?cookies.length:0;i<l;++i){if(cookies[i].value()===value) return true;} return false;} WebInspector.NetworkLogView._requestSizeLargerThanFilter=function(value,request) {return request.transferSize>=value;} WebInspector.NetworkLogView._statusCodeFilter=function(value,request) {return(""+request.statusCode)===value;} WebInspector.NetworkLogView.HTTPRequestsFilter=function(request) {return request.parsedURL.isValid&&(request.scheme in WebInspector.NetworkLogView.HTTPSchemas);} WebInspector.NetworkLogView.FinishedRequestsFilter=function(request) {return request.finished;} WebInspector.NetworkLogView._requestTimeFilter=function(windowStart,windowEnd,request) {if(request.issueTime()>windowEnd) return false;if(request.endTime!==-1&&request.endTime<windowStart) return false;return true;} WebInspector.NetworkLogView.EventTypes={RequestSelected:"RequestSelected",SearchCountUpdated:"SearchCountUpdated",SearchIndexUpdated:"SearchIndexUpdated",UpdateRequest:"UpdateRequest"};;WebInspector.NetworkOverview=function() {WebInspector.TimelineOverviewBase.call(this);this.element.classList.add("network-overview");this._numBands=1;this._windowStart=0;this._windowEnd=0;this._restoringWindow=false;this._updateScheduled=false;this._canvasWidth=0;this._canvasHeight=0;WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.Load,this._loadEventFired,this);WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded,this._domContentLoadedEventFired,this);this.reset();} WebInspector.NetworkOverview._bandHeight=3;WebInspector.NetworkOverview.Window;WebInspector.NetworkOverview.prototype={setFilmStripModel:function(filmStripModel) {this._filmStripModel=filmStripModel;this.scheduleUpdate();},selectFilmStripFrame:function(time) {this._selectedFilmStripTime=time;this.scheduleUpdate();},clearFilmStripFrame:function() {this._selectedFilmStripTime=-1;this.scheduleUpdate();},_loadEventFired:function(event) {var data=(event.data);if(data) this._loadEvents.push(data*1000);this.scheduleUpdate();},_domContentLoadedEventFired:function(event) {var data=(event.data);if(data) this._domContentLoadedEvents.push(data*1000);this.scheduleUpdate();},_bandId:function(connectionId) {if(!connectionId||connectionId==="0") return-1;if(this._bandMap.has(connectionId)) return(this._bandMap.get(connectionId));var result=this._nextBand++;this._bandMap.set(connectionId,result);return result;},updateRequest:function(request) {if(!this._requestsSet.has(request)){this._requestsSet.add(request);this._requestsList.push(request);} this.scheduleUpdate();},wasShown:function() {this.onResize();},onResize:function() {var width=this.element.offsetWidth;var height=this.element.offsetHeight;this._calculator.setDisplayWindow(width);this.resetCanvas();var numBands=(((height-1)/WebInspector.NetworkOverview._bandHeight)-1)|0;this._numBands=(numBands>0)?numBands:1;this.scheduleUpdate();},reset:function() {this._windowStart=0;this._windowEnd=0;this._filmStripModel=null;this._span=1;this._lastBoundary=null;this._nextBand=0;this._bandMap=new Map();this._requestsList=[];this._requestsSet=new Set();this._loadEvents=[];this._domContentLoadedEvents=[];this.resetCanvas();},scheduleUpdate:function() {if(this._updateScheduled||!this.isShowing()) return;this._updateScheduled=true;this.element.window().requestAnimationFrame(this.update.bind(this));},update:function() {this._updateScheduled=false;var newBoundary=new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(),this._calculator.maximumBoundary());if(!this._lastBoundary||!newBoundary.equals(this._lastBoundary)){var span=this._calculator.boundarySpan();while(this._span<span) this._span*=1.25;this._calculator.setBounds(this._calculator.minimumBoundary(),this._calculator.minimumBoundary()+this._span);this._lastBoundary=new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(),this._calculator.maximumBoundary());if(this._windowStart||this._windowEnd){this._restoringWindow=true;var startTime=this._calculator.minimumBoundary();var totalTime=this._calculator.boundarySpan();var left=(this._windowStart-startTime)/totalTime;var right=(this._windowEnd-startTime)/totalTime;this._restoringWindow=false;}} var context=this._canvas.getContext("2d");var calculator=this._calculator;var linesByType={};var paddingTop=2;function drawLines(type,strokeStyle) {var lines=linesByType[type];if(!lines) return;var n=lines.length;context.beginPath();context.strokeStyle=strokeStyle;for(var i=0;i<n;){var y=lines[i++]*WebInspector.NetworkOverview._bandHeight+paddingTop;var startTime=lines[i++];var endTime=lines[i++];if(endTime===Number.MAX_VALUE) endTime=calculator.maximumBoundary();context.moveTo(calculator.computePosition(startTime),y);context.lineTo(calculator.computePosition(endTime)+1,y);} context.stroke();} function addLine(type,y,start,end) {var lines=linesByType[type];if(!lines){lines=[];linesByType[type]=lines;} lines.push(y,start,end);} var requests=this._requestsList;var n=requests.length;for(var i=0;i<n;++i){var request=requests[i];var band=this._bandId(request.connectionId);var y=(band===-1)?0:(band%this._numBands+1);var timeRanges=WebInspector.RequestTimingView.calculateRequestTimeRanges(request,this._calculator.minimumBoundary());for(var j=0;j<timeRanges.length;++j){var type=timeRanges[j].name;if(band!==-1||type===WebInspector.RequestTimeRangeNames.Total) addLine(type,y,timeRanges[j].start*1000,timeRanges[j].end*1000);}} context.clearRect(0,0,this._canvas.width,this._canvas.height);context.save();context.scale(window.devicePixelRatio,window.devicePixelRatio);context.lineWidth=2;drawLines(WebInspector.RequestTimeRangeNames.Total,"#CCCCCC");drawLines(WebInspector.RequestTimeRangeNames.Blocking,"#AAAAAA");drawLines(WebInspector.RequestTimeRangeNames.Connecting,"#FF9800");drawLines(WebInspector.RequestTimeRangeNames.ServiceWorker,"#FF9800");drawLines(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation,"#FF9800");drawLines(WebInspector.RequestTimeRangeNames.Push,"#8CDBff");drawLines(WebInspector.RequestTimeRangeNames.Proxy,"#A1887F");drawLines(WebInspector.RequestTimeRangeNames.DNS,"#009688");drawLines(WebInspector.RequestTimeRangeNames.SSL,"#9C27B0");drawLines(WebInspector.RequestTimeRangeNames.Sending,"#B0BEC5");drawLines(WebInspector.RequestTimeRangeNames.Waiting,"#00C853");drawLines(WebInspector.RequestTimeRangeNames.Receiving,"#03A9F4");var height=this.element.offsetHeight;context.lineWidth=1;context.beginPath();context.strokeStyle="#8080FF";for(var i=this._domContentLoadedEvents.length-1;i>=0;--i){var x=Math.round(calculator.computePosition(this._domContentLoadedEvents[i]))+0.5;context.moveTo(x,0);context.lineTo(x,height);} context.stroke();context.beginPath();context.strokeStyle="#FF8080";for(var i=this._loadEvents.length-1;i>=0;--i){var x=Math.round(calculator.computePosition(this._loadEvents[i]))+0.5;context.moveTo(x,0);context.lineTo(x,height);} context.stroke();if(this._selectedFilmStripTime!==-1){context.lineWidth=2;context.beginPath();context.strokeStyle="#FCCC49";var x=Math.round(calculator.computePosition(this._selectedFilmStripTime));context.moveTo(x,0);context.lineTo(x,height);context.stroke();} context.restore();},__proto__:WebInspector.TimelineOverviewBase.prototype};WebInspector.RequestCookiesView=function(request) {WebInspector.VBox.call(this);this.registerRequiredCSS("network/requestCookiesView.css");this.element.classList.add("request-cookies-view");this._request=request;} WebInspector.RequestCookiesView.prototype={wasShown:function() {this._request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged,this._refreshCookies,this);this._request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged,this._refreshCookies,this);if(!this._gotCookies){if(!this._emptyWidget){this._emptyWidget=new WebInspector.EmptyWidget(WebInspector.UIString("This request has no cookies."));this._emptyWidget.show(this.element);} return;} if(!this._cookiesTable) this._buildCookiesTable();},willHide:function() {this._request.removeEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged,this._refreshCookies,this);this._request.removeEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged,this._refreshCookies,this);},get _gotCookies() {return(this._request.requestCookies&&this._request.requestCookies.length)||(this._request.responseCookies&&this._request.responseCookies.length);},_buildCookiesTable:function() {this.detachChildWidgets();this._cookiesTable=new WebInspector.CookiesTable(true);this._cookiesTable.setCookieFolders([{folderName:WebInspector.UIString("Request Cookies"),cookies:this._request.requestCookies},{folderName:WebInspector.UIString("Response Cookies"),cookies:this._request.responseCookies}]);this._cookiesTable.show(this.element);},_refreshCookies:function() {delete this._cookiesTable;if(!this._gotCookies||!this.isShowing()) return;this._buildCookiesTable();},__proto__:WebInspector.VBox.prototype};WebInspector.RequestHeadersView=function(request) {WebInspector.VBox.call(this);this.registerRequiredCSS("network/requestHeadersView.css");this.element.classList.add("request-headers-view");this._request=request;this._decodeRequestParameters=true;this._showRequestHeadersText=false;this._showResponseHeadersText=false;var root=new TreeOutline(true);root.element.classList.add("outline-disclosure");root.expandTreeElementsWhenArrowing=true;this.element.appendChild(root.element);var generalCategory=new WebInspector.RequestHeadersView.Category(root,"general",WebInspector.UIString("General"));generalCategory.hidden=false;this._urlItem=generalCategory.createLeaf();this._requestMethodItem=generalCategory.createLeaf();this._statusCodeItem=generalCategory.createLeaf();this._remoteAddressItem=generalCategory.createLeaf();this._remoteAddressItem.hidden=true;this._responseHeadersCategory=new WebInspector.RequestHeadersView.Category(root,"responseHeaders","");this._requestHeadersCategory=new WebInspector.RequestHeadersView.Category(root,"requestHeaders","");this._queryStringCategory=new WebInspector.RequestHeadersView.Category(root,"queryString","");this._formDataCategory=new WebInspector.RequestHeadersView.Category(root,"formData","");this._requestPayloadCategory=new WebInspector.RequestHeadersView.Category(root,"requestPayload",WebInspector.UIString("Request Payload"));} WebInspector.RequestHeadersView.prototype={wasShown:function() {this._request.addEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged,this._refreshRemoteAddress,this);this._request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged,this._refreshRequestHeaders,this);this._request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged,this._refreshResponseHeaders,this);this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._refreshHTTPInformation,this);this._refreshURL();this._refreshQueryString();this._refreshRequestHeaders();this._refreshResponseHeaders();this._refreshHTTPInformation();this._refreshRemoteAddress();},willHide:function() {this._request.removeEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged,this._refreshRemoteAddress,this);this._request.removeEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged,this._refreshRequestHeaders,this);this._request.removeEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged,this._refreshResponseHeaders,this);this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._refreshHTTPInformation,this);},_formatHeader:function(name,value) {var fragment=createDocumentFragment();fragment.createChild("div","header-name").textContent=name+":";fragment.createChild("div","header-value source-code").textContent=value;return fragment;},_formatParameter:function(value,className,decodeParameters) {var errorDecoding=false;if(decodeParameters){value=value.replace(/\+/g," ");if(value.indexOf("%")>=0){try{value=decodeURIComponent(value);}catch(e){errorDecoding=true;}}} var div=createElementWithClass("div",className);if(value==="") div.classList.add("empty-value");if(errorDecoding) div.createChild("span","error-message").textContent=WebInspector.UIString("(unable to decode value)");else div.textContent=value;return div;},_refreshURL:function() {this._urlItem.title=this._formatHeader(WebInspector.UIString("Request URL"),this._request.url);},_refreshQueryString:function() {var queryString=this._request.queryString();var queryParameters=this._request.queryParameters;this._queryStringCategory.hidden=!queryParameters;if(queryParameters) this._refreshParams(WebInspector.UIString("Query String Parameters"),queryParameters,queryString,this._queryStringCategory);},_refreshFormData:function() {this._formDataCategory.hidden=true;this._requestPayloadCategory.hidden=true;var formData=this._request.requestFormData;if(!formData) return;var formParameters=this._request.formParameters;if(formParameters){this._formDataCategory.hidden=false;this._refreshParams(WebInspector.UIString("Form Data"),formParameters,formData,this._formDataCategory);}else{this._requestPayloadCategory.hidden=false;try{var json=JSON.parse(formData);this._refreshRequestJSONPayload(json,formData);}catch(e){this._populateTreeElementWithSourceText(this._requestPayloadCategory,formData);}}},_populateTreeElementWithSourceText:function(treeElement,sourceText) {var sourceTextElement=createElementWithClass("span","header-value source-code");sourceTextElement.textContent=String(sourceText||"").trim();var sourceTreeElement=new TreeElement(sourceTextElement);sourceTreeElement.selectable=false;treeElement.removeChildren();treeElement.appendChild(sourceTreeElement);},_refreshParams:function(title,params,sourceText,paramsTreeElement) {paramsTreeElement.removeChildren();paramsTreeElement.listItemElement.removeChildren();paramsTreeElement.listItemElement.createTextChild(title);var headerCount=createElementWithClass("span","header-count");headerCount.textContent=WebInspector.UIString("\u00A0(%d)",params.length);paramsTreeElement.listItemElement.appendChild(headerCount);function toggleViewSource(event) {paramsTreeElement._viewSource=!paramsTreeElement._viewSource;this._refreshParams(title,params,sourceText,paramsTreeElement);event.consume();} paramsTreeElement.listItemElement.appendChild(this._createViewSourceToggle(paramsTreeElement._viewSource,toggleViewSource.bind(this)));if(paramsTreeElement._viewSource){this._populateTreeElementWithSourceText(paramsTreeElement,sourceText);return;} var toggleTitle=this._decodeRequestParameters?WebInspector.UIString("view URL encoded"):WebInspector.UIString("view decoded");var toggleButton=this._createToggleButton(toggleTitle);toggleButton.addEventListener("click",this._toggleURLDecoding.bind(this),false);paramsTreeElement.listItemElement.appendChild(toggleButton);for(var i=0;i<params.length;++i){var paramNameValue=createDocumentFragment();if(params[i].name!==""){var name=this._formatParameter(params[i].name+":","header-name",this._decodeRequestParameters);var value=this._formatParameter(params[i].value,"header-value source-code",this._decodeRequestParameters);paramNameValue.appendChild(name);paramNameValue.appendChild(value);}else{paramNameValue.appendChild(this._formatParameter(WebInspector.UIString("(empty)"),"empty-request-header",this._decodeRequestParameters));} var paramTreeElement=new TreeElement(paramNameValue);paramTreeElement.selectable=false;paramsTreeElement.appendChild(paramTreeElement);}},_refreshRequestJSONPayload:function(parsedObject,sourceText) {var treeElement=this._requestPayloadCategory;treeElement.removeChildren();var listItem=this._requestPayloadCategory.listItemElement;listItem.removeChildren();listItem.createTextChild(this._requestPayloadCategory.title);function toggleViewSource(event) {treeElement._viewSource=!treeElement._viewSource;this._refreshRequestJSONPayload(parsedObject,sourceText);event.consume();} listItem.appendChild(this._createViewSourceToggle(treeElement._viewSource,toggleViewSource.bind(this)));if(treeElement._viewSource){this._populateTreeElementWithSourceText(this._requestPayloadCategory,sourceText);}else{var object=WebInspector.RemoteObject.fromLocalObject(parsedObject);var section=new WebInspector.ObjectPropertiesSection(object,object.description);section.expand();section.editable=false;treeElement.appendChild(new TreeElement(section.element));}},_createViewSourceToggle:function(viewSource,handler) {var viewSourceToggleTitle=viewSource?WebInspector.UIString("view parsed"):WebInspector.UIString("view source");var viewSourceToggleButton=this._createToggleButton(viewSourceToggleTitle);viewSourceToggleButton.addEventListener("click",handler,false);return viewSourceToggleButton;},_toggleURLDecoding:function(event) {this._decodeRequestParameters=!this._decodeRequestParameters;this._refreshQueryString();this._refreshFormData();event.consume();},_refreshRequestHeaders:function() {var treeElement=this._requestHeadersCategory;var headers=this._request.requestHeaders().slice();headers.sort(function(a,b){return a.name.toLowerCase().compareTo(b.name.toLowerCase());});var headersText=this._request.requestHeadersText();if(this._showRequestHeadersText&&headersText) this._refreshHeadersText(WebInspector.UIString("Request Headers"),headers.length,headersText,treeElement);else this._refreshHeaders(WebInspector.UIString("Request Headers"),headers,treeElement,headersText===undefined);if(headersText){var toggleButton=this._createHeadersToggleButton(this._showRequestHeadersText);toggleButton.addEventListener("click",this._toggleRequestHeadersText.bind(this),false);treeElement.listItemElement.appendChild(toggleButton);} this._refreshFormData();},_refreshResponseHeaders:function() {var treeElement=this._responseHeadersCategory;var headers=this._request.sortedResponseHeaders.slice();var headersText=this._request.responseHeadersText;if(this._showResponseHeadersText) this._refreshHeadersText(WebInspector.UIString("Response Headers"),headers.length,headersText,treeElement);else this._refreshHeaders(WebInspector.UIString("Response Headers"),headers,treeElement);if(headersText){var toggleButton=this._createHeadersToggleButton(this._showResponseHeadersText);toggleButton.addEventListener("click",this._toggleResponseHeadersText.bind(this),false);treeElement.listItemElement.appendChild(toggleButton);}},_refreshHTTPInformation:function() {var requestMethodElement=this._requestMethodItem;requestMethodElement.hidden=!this._request.statusCode;var statusCodeElement=this._statusCodeItem;statusCodeElement.hidden=!this._request.statusCode;if(this._request.statusCode){var statusCodeFragment=createDocumentFragment();statusCodeFragment.createChild("div","header-name").textContent=WebInspector.UIString("Status Code")+":";var statusCodeImage=statusCodeFragment.createChild("label","resource-status-image","dt-icon-label");statusCodeImage.title=this._request.statusCode+" "+this._request.statusText;if(this._request.statusCode<300||this._request.statusCode===304) statusCodeImage.type="green-ball";else if(this._request.statusCode<400) statusCodeImage.type="orange-ball";else statusCodeImage.type="red-ball";requestMethodElement.title=this._formatHeader(WebInspector.UIString("Request Method"),this._request.requestMethod);var statusTextElement=statusCodeFragment.createChild("div","header-value source-code");var statusText=this._request.statusCode+" "+this._request.statusText;if(this._request.fetchedViaServiceWorker){statusText+=" "+WebInspector.UIString("(from ServiceWorker)");statusTextElement.classList.add("status-from-cache");}else if(this._request.cached()){statusText+=" "+WebInspector.UIString("(from cache)");statusTextElement.classList.add("status-from-cache");} statusTextElement.textContent=statusText;statusCodeElement.title=statusCodeFragment;}},_refreshHeadersTitle:function(title,headersTreeElement,headersLength) {headersTreeElement.listItemElement.removeChildren();headersTreeElement.listItemElement.createTextChild(title);var headerCount=WebInspector.UIString("\u00A0(%d)",headersLength);headersTreeElement.listItemElement.createChild("span","header-count").textContent=headerCount;},_refreshHeaders:function(title,headers,headersTreeElement,provisionalHeaders) {headersTreeElement.removeChildren();var length=headers.length;this._refreshHeadersTitle(title,headersTreeElement,length);if(provisionalHeaders){var cautionText=WebInspector.UIString("Provisional headers are shown");var cautionFragment=createDocumentFragment();cautionFragment.createChild("label","","dt-icon-label").type="warning-icon";cautionFragment.createChild("div","caution").textContent=cautionText;var cautionTreeElement=new TreeElement(cautionFragment);cautionTreeElement.selectable=false;headersTreeElement.appendChild(cautionTreeElement);} headersTreeElement.hidden=!length&&!provisionalHeaders;for(var i=0;i<length;++i){var headerTreeElement=new TreeElement(this._formatHeader(headers[i].name,headers[i].value));headerTreeElement.selectable=false;headersTreeElement.appendChild(headerTreeElement);}},_refreshHeadersText:function(title,count,headersText,headersTreeElement) {this._populateTreeElementWithSourceText(headersTreeElement,headersText);this._refreshHeadersTitle(title,headersTreeElement,count);},_refreshRemoteAddress:function() {var remoteAddress=this._request.remoteAddress();var treeElement=this._remoteAddressItem;treeElement.hidden=!remoteAddress;if(remoteAddress) treeElement.title=this._formatHeader(WebInspector.UIString("Remote Address"),remoteAddress);},_toggleRequestHeadersText:function(event) {this._showRequestHeadersText=!this._showRequestHeadersText;this._refreshRequestHeaders();event.consume();},_toggleResponseHeadersText:function(event) {this._showResponseHeadersText=!this._showResponseHeadersText;this._refreshResponseHeaders();event.consume();},_createToggleButton:function(title) {var button=createElementWithClass("span","header-toggle");button.textContent=title;return button;},_createHeadersToggleButton:function(isHeadersTextShown) {var toggleTitle=isHeadersTextShown?WebInspector.UIString("view parsed"):WebInspector.UIString("view source");return this._createToggleButton(toggleTitle);},__proto__:WebInspector.VBox.prototype} WebInspector.RequestHeadersView.Category=function(root,name,title) {TreeElement.call(this,title||"",true);this.selectable=false;this.toggleOnClick=true;this.hidden=true;this._expandedSetting=WebInspector.settings.createSetting("request-info-"+name+"-category-expanded",true);this.expanded=this._expandedSetting.get();root.appendChild(this);} WebInspector.RequestHeadersView.Category.prototype={createLeaf:function() {var leaf=new TreeElement();leaf.selectable=false;this.appendChild(leaf);return leaf;},onexpand:function() {this._expandedSetting.set(true);},oncollapse:function() {this._expandedSetting.set(false);},__proto__:TreeElement.prototype};WebInspector.RequestHTMLView=function(request,dataURL) {WebInspector.RequestView.call(this,request);this._dataURL=dataURL;this.element.classList.add("html");} WebInspector.RequestHTMLView.prototype={wasShown:function() {this._createIFrame();},willHide:function(parentElement) {this.element.removeChildren();},_createIFrame:function() {this.element.removeChildren();var iframe=createElement("iframe");iframe.setAttribute("sandbox","");iframe.setAttribute("src",this._dataURL);this.element.appendChild(iframe);},__proto__:WebInspector.RequestView.prototype};WebInspector.RequestPreviewView=function(request,responseView) {WebInspector.RequestContentView.call(this,request);this._responseView=responseView;} WebInspector.RequestPreviewView.prototype={contentLoaded:function() {if(!this.request.content&&!this.request.contentError()){if(!this._emptyWidget){this._emptyWidget=this._createEmptyWidget();this._emptyWidget.show(this.element);this.innerView=this._emptyWidget;}}else{if(this._emptyWidget){this._emptyWidget.detach();delete this._emptyWidget;} if(!this._previewView) this._createPreviewView(handlePreviewView.bind(this));else this.innerView=this._previewView;} function handlePreviewView(view){this._previewView=view;this._previewView.show(this.element);if(this._previewView instanceof WebInspector.VBoxWithToolbarItems){var toolbar=new WebInspector.Toolbar("network-item-preview-toolbar",this.element);for(var item of(this._previewView).toolbarItems()) toolbar.appendToolbarItem(item);} this.innerView=this._previewView;this._previewViewHandledForTest(this._previewView);}},_previewViewHandledForTest:function(view){},_createEmptyWidget:function() {return this._createMessageView(WebInspector.UIString("This request has no preview available."));},_createMessageView:function(message) {return new WebInspector.EmptyWidget(message);},_requestContent:function() {var content=this.request.content;return this.request.contentEncoded?window.atob(content||""):(content||"");},_jsonView:function(parsedJSON) {if(!parsedJSON||typeof parsedJSON.data!=="object") return null;return WebInspector.JSONView.createSearchableView((parsedJSON));},_xmlView:function() {var parsedXML=WebInspector.XMLView.parseXML(this._requestContent(),this.request.mimeType);return parsedXML?WebInspector.XMLView.createSearchableView(parsedXML):null;},_htmlErrorPreview:function() {var whitelist=["text/html","text/plain","application/xhtml+xml"];if(whitelist.indexOf(this.request.mimeType)===-1) return null;var dataURL=this.request.asDataURL();if(dataURL===null) return null;return new WebInspector.RequestHTMLView(this.request,dataURL);},_createPreviewView:function(callback) {if(this.request.contentError()){callback(this._createMessageView(WebInspector.UIString("Failed to load response data")));return;} var xmlView=this._xmlView();if(xmlView){callback(xmlView);return;} WebInspector.JSONView.parseJSON(this._requestContent()).then(chooseView.bind(this)).then(callback);function chooseView(jsonData) {if(jsonData){var jsonView=this._jsonView(jsonData);if(jsonView) return jsonView;} if(this.request.hasErrorStatusCode()||this.request.resourceType()===WebInspector.resourceTypes.XHR){var htmlErrorPreview=this._htmlErrorPreview();if(htmlErrorPreview) return htmlErrorPreview;} if(this._responseView.sourceView) return this._responseView.sourceView;if(this.request.resourceType()===WebInspector.resourceTypes.Other) return this._createEmptyWidget();return WebInspector.RequestView.nonSourceViewForRequest(this.request);}},__proto__:WebInspector.RequestContentView.prototype};WebInspector.RequestResponseView=function(request) {WebInspector.RequestContentView.call(this,request);} WebInspector.RequestResponseView.prototype={get sourceView() {if(this._sourceView||!WebInspector.RequestView.hasTextContent(this.request)) return this._sourceView;var contentProvider=new WebInspector.RequestResponseView.ContentProvider(this.request);var highlighterType=this.request.resourceType().canonicalMimeType()||this.request.mimeType;this._sourceView=WebInspector.ResourceSourceFrame.createSearchableView(contentProvider,highlighterType);;return this._sourceView;},_createMessageView:function(message) {return new WebInspector.EmptyWidget(message);},contentLoaded:function() {if((!this.request.content||!this.sourceView)&&!this.request.contentError()){if(!this._emptyWidget){this._emptyWidget=this._createMessageView(WebInspector.UIString("This request has no response data available."));this._emptyWidget.show(this.element);this.innerView=this._emptyWidget;}}else{if(this._emptyWidget){this._emptyWidget.detach();delete this._emptyWidget;} if(this.request.content&&this.sourceView){this.sourceView.show(this.element);this.innerView=this.sourceView;}else{if(!this._errorView) this._errorView=this._createMessageView(WebInspector.UIString("Failed to load response data"));this._errorView.show(this.element);this.innerView=this._errorView;}}},__proto__:WebInspector.RequestContentView.prototype} WebInspector.RequestResponseView.ContentProvider=function(request){this._request=request;} WebInspector.RequestResponseView.ContentProvider.prototype={contentURL:function() {return this._request.contentURL();},contentType:function() {return this._request.resourceType();},requestContent:function() {function decodeContent(content) {return this._request.contentEncoded?window.atob(content||""):content;} return this._request.requestContent().then(decodeContent.bind(this));},searchInContent:function(query,caseSensitive,isRegex,callback) {this._request.searchInContent(query,caseSensitive,isRegex,callback);}};WebInspector.RequestTimingView=function(request,calculator) {WebInspector.VBox.call(this);this.element.classList.add("resource-timing-view");this._request=request;this._calculator=calculator;} WebInspector.RequestTimingView.prototype={wasShown:function() {this._request.addEventListener(WebInspector.NetworkRequest.Events.TimingChanged,this._refresh,this);this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._refresh,this);this._calculator.addEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged,this._refresh,this);this._refresh();},willHide:function() {this._request.removeEventListener(WebInspector.NetworkRequest.Events.TimingChanged,this._refresh,this);this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading,this._refresh,this);this._calculator.removeEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged,this._refresh,this);},_refresh:function() {if(this._tableElement) this._tableElement.remove();this._tableElement=WebInspector.RequestTimingView.createTimingTable(this._request,this._calculator.minimumBoundary());this.element.appendChild(this._tableElement);},__proto__:WebInspector.VBox.prototype} WebInspector.RequestTimeRangeNames={Push:"push",Queueing:"queueing",Blocking:"blocking",Connecting:"connecting",DNS:"dns",Proxy:"proxy",Receiving:"receiving",ReceivingPush:"receiving-push",Sending:"sending",ServiceWorker:"serviceworker",ServiceWorkerPreparation:"serviceworker-preparation",SSL:"ssl",Total:"total",Waiting:"waiting"};WebInspector.RequestTimingView.ConnectionSetupRangeNames=[WebInspector.RequestTimeRangeNames.Queueing,WebInspector.RequestTimeRangeNames.Blocking,WebInspector.RequestTimeRangeNames.Connecting,WebInspector.RequestTimeRangeNames.DNS,WebInspector.RequestTimeRangeNames.Proxy,WebInspector.RequestTimeRangeNames.SSL].keySet();WebInspector.RequestTimeRange;WebInspector.RequestTimingView._timeRangeTitle=function(name) {switch(name){case WebInspector.RequestTimeRangeNames.Push:return WebInspector.UIString("Receiving Push");case WebInspector.RequestTimeRangeNames.Queueing:return WebInspector.UIString("Queueing");case WebInspector.RequestTimeRangeNames.Blocking:return WebInspector.UIString("Stalled");case WebInspector.RequestTimeRangeNames.Connecting:return WebInspector.UIString("Initial connection");case WebInspector.RequestTimeRangeNames.DNS:return WebInspector.UIString("DNS Lookup");case WebInspector.RequestTimeRangeNames.Proxy:return WebInspector.UIString("Proxy negotiation");case WebInspector.RequestTimeRangeNames.ReceivingPush:return WebInspector.UIString("Reading Push");case WebInspector.RequestTimeRangeNames.Receiving:return WebInspector.UIString("Content Download");case WebInspector.RequestTimeRangeNames.Sending:return WebInspector.UIString("Request sent");case WebInspector.RequestTimeRangeNames.ServiceWorker:return WebInspector.UIString("Request to ServiceWorker");case WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation:return WebInspector.UIString("ServiceWorker Preparation");case WebInspector.RequestTimeRangeNames.SSL:return WebInspector.UIString("SSL");case WebInspector.RequestTimeRangeNames.Total:return WebInspector.UIString("Total");case WebInspector.RequestTimeRangeNames.Waiting:return WebInspector.UIString("Waiting (TTFB)");default:return WebInspector.UIString(name);}} WebInspector.RequestTimingView.calculateRequestTimeRanges=function(request,navigationStart) {var result=[];function addRange(name,start,end) {if(start<Number.MAX_VALUE&&start<=end) result.push({name:name,start:start,end:end});} function firstPositive(numbers) {for(var i=0;i<numbers.length;++i){if(numbers[i]>0) return numbers[i];} return undefined;} function addOffsetRange(name,start,end) {if(start>=0&&end>=0) addRange(name,startTime+(start/1000),startTime+(end/1000));} var timing=request.timing;if(!timing){var start=request.issueTime()!==-1?request.issueTime():request.startTime!==-1?request.startTime:0;var middle=(request.responseReceivedTime===-1)?Number.MAX_VALUE:request.responseReceivedTime;var end=(request.endTime===-1)?Number.MAX_VALUE:request.endTime;addRange(WebInspector.RequestTimeRangeNames.Total,start,end);addRange(WebInspector.RequestTimeRangeNames.Blocking,start,middle);addRange(WebInspector.RequestTimeRangeNames.Receiving,middle,end);return result;} var issueTime=request.issueTime();var startTime=timing.requestTime;var endTime=firstPositive([request.endTime,request.responseReceivedTime])||startTime;addRange(WebInspector.RequestTimeRangeNames.Total,issueTime<startTime?issueTime:startTime,endTime);if(timing.pushStart){var pushEnd=timing.pushEnd||endTime;if(pushEnd>navigationStart) addRange(WebInspector.RequestTimeRangeNames.Push,Math.max(timing.pushStart,navigationStart),pushEnd);} if(issueTime<startTime) addRange(WebInspector.RequestTimeRangeNames.Queueing,issueTime,startTime);if(request.fetchedViaServiceWorker){addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking,0,timing.workerStart);addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation,timing.workerStart,timing.workerReady);addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorker,timing.workerReady,timing.sendEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting,timing.sendEnd,timing.receiveHeadersEnd);}else if(!timing.pushStart){var blocking=firstPositive([timing.dnsStart,timing.connectStart,timing.sendStart])||0;addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking,0,blocking);addOffsetRange(WebInspector.RequestTimeRangeNames.Proxy,timing.proxyStart,timing.proxyEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.DNS,timing.dnsStart,timing.dnsEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.Connecting,timing.connectStart,timing.connectEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.SSL,timing.sslStart,timing.sslEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.Sending,timing.sendStart,timing.sendEnd);addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting,timing.sendEnd,timing.receiveHeadersEnd);} if(request.endTime!==-1) addRange(timing.pushStart?WebInspector.RequestTimeRangeNames.ReceivingPush:WebInspector.RequestTimeRangeNames.Receiving,request.responseReceivedTime,endTime);return result;} WebInspector.RequestTimingView.createTimingTable=function(request,navigationStart) {var tableElement=createElementWithClass("table","network-timing-table");var colgroup=tableElement.createChild("colgroup");colgroup.createChild("col","labels");colgroup.createChild("col","bars");colgroup.createChild("col","duration");var timeRanges=WebInspector.RequestTimingView.calculateRequestTimeRanges(request,navigationStart);var startTime=timeRanges.map(r=>r.start).reduce((a,b)=>Math.min(a,b));var endTime=timeRanges.map(r=>r.end).reduce((a,b)=>Math.max(a,b));var scale=100/(endTime-startTime);var connectionHeader;var dataHeader;var totalDuration=0;for(var i=0;i<timeRanges.length;++i){var range=timeRanges[i];var rangeName=range.name;if(rangeName===WebInspector.RequestTimeRangeNames.Total){totalDuration=range.end-range.start;continue;} if(rangeName===WebInspector.RequestTimeRangeNames.Push){createHeader(WebInspector.UIString("Server Push"));}else if(WebInspector.RequestTimingView.ConnectionSetupRangeNames[rangeName]){if(!connectionHeader) connectionHeader=createHeader(WebInspector.UIString("Connection Setup"));}else{if(!dataHeader) dataHeader=createHeader(WebInspector.UIString("Request/Response"));} var left=(scale*(range.start-startTime));var right=(scale*(endTime-range.end));var duration=range.end-range.start;var tr=tableElement.createChild("tr");tr.createChild("td").createTextChild(WebInspector.RequestTimingView._timeRangeTitle(rangeName));var row=tr.createChild("td").createChild("div","network-timing-row");var bar=row.createChild("span","network-timing-bar "+rangeName);bar.style.left=left+"%";bar.style.right=right+"%";bar.textContent="\u200B";var label=tr.createChild("td").createChild("div","network-timing-bar-title");label.textContent=Number.secondsToString(duration,true);} if(!request.finished){var cell=tableElement.createChild("tr").createChild("td","caution");cell.colSpan=3;cell.createTextChild(WebInspector.UIString("CAUTION: request is not finished yet!"));} var footer=tableElement.createChild("tr","network-timing-footer");var note=footer.createChild("td");note.colSpan=2;note.appendChild(WebInspector.linkifyDocumentationURLAsNode("profile/network-performance/resource-loading#view-network-timing-details-for-a-specific-resource",WebInspector.UIString("Explanation")));footer.createChild("td").createTextChild(Number.secondsToString(totalDuration,true));return tableElement;function createHeader(title) {var dataHeader=tableElement.createChild("tr","network-timing-table-header");dataHeader.createChild("td").createTextChild(title);dataHeader.createChild("td").createTextChild("");dataHeader.createChild("td").createTextChild(WebInspector.UIString("TIME"));return dataHeader;}};WebInspector.ResourceWebSocketFrameView=function(request) {WebInspector.VBox.call(this);this.registerRequiredCSS("network/webSocketFrameView.css");this.element.classList.add("websocket-frame-view");this._request=request;this._splitWidget=new WebInspector.SplitWidget(false,true,"resourceWebSocketFrameSplitViewState");this._splitWidget.show(this.element);var columns=[{id:"data",title:WebInspector.UIString("Data"),sortable:false,weight:88},{id:"length",title:WebInspector.UIString("Length"),sortable:false,align:WebInspector.DataGrid.Align.Right,weight:5},{id:"time",title:WebInspector.UIString("Time"),sortable:true,weight:7}];this._dataGrid=new WebInspector.SortableDataGrid(columns,undefined,undefined,undefined,this._onContextMenu.bind(this));this._dataGrid.setStickToBottom(true);this._dataGrid.setCellClass("websocket-frame-view-td");this._timeComparator=(WebInspector.ResourceWebSocketFrameNodeTimeComparator);this._dataGrid.sortNodes(this._timeComparator,false);this._dataGrid.markColumnAsSortedBy("time",WebInspector.DataGrid.Order.Ascending);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortItems,this);this._dataGrid.setName("ResourceWebSocketFrameView");this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._onFrameSelected,this);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.DeselectedNode,this._onFrameDeselected,this);this._splitWidget.setMainWidget(this._dataGrid.asWidget());var view=new WebInspector.EmptyWidget("Select frame to browse its content.");this._splitWidget.setSidebarWidget(view);this._selectedNode=null;} WebInspector.ResourceWebSocketFrameView.OpCodes={ContinuationFrame:0,TextFrame:1,BinaryFrame:2,ConnectionCloseFrame:8,PingFrame:9,PongFrame:10};WebInspector.ResourceWebSocketFrameView.opCodeDescriptions=(function() {var opCodes=WebInspector.ResourceWebSocketFrameView.OpCodes;var map=[];map[opCodes.ContinuationFrame]="Continuation Frame";map[opCodes.TextFrame]="Text Frame";map[opCodes.BinaryFrame]="Binary Frame";map[opCodes.ContinuationFrame]="Connection Close Frame";map[opCodes.PingFrame]="Ping Frame";map[opCodes.PongFrame]="Pong Frame";return map;})();WebInspector.ResourceWebSocketFrameView.opCodeDescription=function(opCode,mask) {var rawDescription=WebInspector.ResourceWebSocketFrameView.opCodeDescriptions[opCode]||"";var localizedDescription=WebInspector.UIString(rawDescription);return WebInspector.UIString("%s (Opcode %d%s)",localizedDescription,opCode,(mask?", mask":""));} WebInspector.ResourceWebSocketFrameView.prototype={wasShown:function() {this.refresh();this._request.addEventListener(WebInspector.NetworkRequest.Events.WebsocketFrameAdded,this._frameAdded,this);},willHide:function() {this._request.removeEventListener(WebInspector.NetworkRequest.Events.WebsocketFrameAdded,this._frameAdded,this);},_frameAdded:function(event) {var frame=(event.data);this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(this._request.url,frame));},_onFrameSelected:function(event) {var selectedNode=(event.target.selectedNode);this._currentSelectedNode=selectedNode;var contentProvider=selectedNode.contentProvider();contentProvider.requestContent().then(contentHandler.bind(this));function contentHandler(content){if(this._currentSelectedNode!==selectedNode) return;WebInspector.JSONView.parseJSON(content).then(handleJSONData.bind(this));} function handleJSONData(parsedJSON) {if(this._currentSelectedNode!==selectedNode) return;if(parsedJSON) this._splitWidget.setSidebarWidget(WebInspector.JSONView.createSearchableView(parsedJSON));else this._splitWidget.setSidebarWidget(new WebInspector.ResourceSourceFrame(contentProvider));}},_onFrameDeselected:function(event) {this._currentSelectedNode=null;},refresh:function() {this._dataGrid.rootNode().removeChildren();var frames=this._request.frames();for(var i=0;i<frames.length;++i) this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(this._request.url,frames[i]));},_onContextMenu:function(contextMenu,node) {contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^message"),this._copyMessage.bind(this,node.data));},_copyMessage:function(row) {InspectorFrontendHost.copyText(row.data);},_sortItems:function() {this._dataGrid.sortNodes(this._timeComparator,!this._dataGrid.isSortOrderAscending());},__proto__:WebInspector.VBox.prototype} WebInspector.ResourceWebSocketFrameNode=function(url,frame) {this._frame=frame;this._dataText=frame.text;this._url=url;var length=frame.text.length;var time=new Date(frame.time*1000);var timeText=("0"+time.getHours()).substr(-2)+":"+("0"+time.getMinutes()).substr(-2)+":"+("0"+time.getSeconds()).substr(-2)+"."+("00"+time.getMilliseconds()).substr(-3);var timeNode=createElement("div");timeNode.createTextChild(timeText);timeNode.title=time.toLocaleString();this._isTextFrame=frame.opCode===WebInspector.ResourceWebSocketFrameView.OpCodes.TextFrame;if(!this._isTextFrame) this._dataText=WebInspector.ResourceWebSocketFrameView.opCodeDescription(frame.opCode,frame.mask);WebInspector.SortableDataGridNode.call(this,{data:this._dataText,length:length,time:timeNode});} WebInspector.ResourceWebSocketFrameNode.prototype={createCells:function() {var element=this._element;element.classList.toggle("websocket-frame-view-row-error",this._frame.type===WebInspector.NetworkRequest.WebSocketFrameType.Error);element.classList.toggle("websocket-frame-view-row-outcoming",this._frame.type===WebInspector.NetworkRequest.WebSocketFrameType.Send);element.classList.toggle("websocket-frame-view-row-opcode",!this._isTextFrame);WebInspector.SortableDataGridNode.prototype.createCells.call(this);},nodeSelfHeight:function() {return 17;},contentProvider:function() {return WebInspector.StaticContentProvider.fromString(this._url,WebInspector.resourceTypes.WebSocket,this._dataText);},__proto__:WebInspector.SortableDataGridNode.prototype} WebInspector.ResourceWebSocketFrameNodeTimeComparator=function(a,b) {return a._frame.time-b._frame.time;};WebInspector.NetworkPanel=function() {WebInspector.Panel.call(this,"network");this.registerRequiredCSS("network/networkPanel.css");this._networkLogShowOverviewSetting=WebInspector.settings.createSetting("networkLogShowOverview",true);this._networkLogLargeRowsSetting=WebInspector.settings.createSetting("networkLogLargeRows",false);this._networkRecordFilmStripSetting=WebInspector.settings.createSetting("networkRecordFilmStripSetting",false);this._toggleRecordAction=(WebInspector.actionRegistry.action("network.toggle-recording"));this._filmStripView=null;this._filmStripRecorder=null;this._panelToolbar=new WebInspector.Toolbar("",this.element);this._filterBar=new WebInspector.FilterBar("networkPanel",true);this._filterBar.show(this.element);this._overviewPane=new WebInspector.TimelineOverviewPane("network");this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged,this._onWindowChanged.bind(this));this._overviewPane.element.id="network-overview-panel";this._networkOverview=new WebInspector.NetworkOverview();this._overviewPane.setOverviewControls([this._networkOverview]);this._calculator=new WebInspector.NetworkTransferTimeCalculator();this._splitWidget=new WebInspector.SplitWidget(true,false,"networkPanelSplitViewState");this._splitWidget.hideMain();this._splitWidget.show(this.element);this._progressBarContainer=createElement("div");this._createToolbarButtons();this._searchableView=new WebInspector.SearchableView(this);this._searchableView.setPlaceholder(WebInspector.UIString("Find by filename or path"));this._networkLogView=new WebInspector.NetworkLogView(this._filterBar,this._progressBarContainer,this._networkLogLargeRowsSetting);this._networkLogView.show(this._searchableView.element);this._splitWidget.setSidebarWidget(this._searchableView);this._detailsWidget=new WebInspector.VBox();this._detailsWidget.element.classList.add("network-details-view");this._splitWidget.setMainWidget(this._detailsWidget);this._closeButtonElement=createElementWithClass("div","network-close-button","dt-close-button");this._closeButtonElement.addEventListener("click",this._showRequest.bind(this,null),false);this._networkLogShowOverviewSetting.addChangeListener(this._toggleShowOverview,this);this._networkLogLargeRowsSetting.addChangeListener(this._toggleLargerRequests,this);this._networkRecordFilmStripSetting.addChangeListener(this._toggleRecordFilmStrip,this);this._toggleRecord(true);this._toggleShowOverview();this._toggleLargerRequests();this._toggleRecordFilmStrip();this._updateUI();WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.WillReloadPage,this._willReloadPage,this);WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.Load,this._load,this);this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.RequestSelected,this._onRequestSelected,this);this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated,this._onSearchCountUpdated,this);this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated,this._onSearchIndexUpdated,this);this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.UpdateRequest,this._onUpdateRequest,this);WebInspector.DataSaverInfobar.maybeShowInPanel(this);} WebInspector.NetworkPanel.prototype={_onWindowChanged:function(event) {var startTime=Math.max(this._calculator.minimumBoundary(),event.data.startTime/1000);var endTime=Math.min(this._calculator.maximumBoundary(),event.data.endTime/1000);this._networkLogView.setWindow(startTime,endTime);},_createToolbarButtons:function() {this._panelToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleRecordAction));this._clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear"),"clear-toolbar-item");this._clearButton.addEventListener("click",this._onClearButtonClicked,this);this._panelToolbar.appendToolbarItem(this._clearButton);this._panelToolbar.appendSeparator();var recordFilmStripButton=new WebInspector.ToolbarSettingToggle(this._networkRecordFilmStripSetting,"camera-toolbar-item",WebInspector.UIString("Capture screenshots"));this._panelToolbar.appendToolbarItem(recordFilmStripButton);this._panelToolbar.appendToolbarItem(this._filterBar.filterButton());this._panelToolbar.appendSeparator();this._panelToolbar.appendText(WebInspector.UIString("View:"));var largerRequestsButton=new WebInspector.ToolbarSettingToggle(this._networkLogLargeRowsSetting,"large-list-toolbar-item",WebInspector.UIString("Use large request rows"),WebInspector.UIString("Use small request rows"));this._panelToolbar.appendToolbarItem(largerRequestsButton);var showOverviewButton=new WebInspector.ToolbarSettingToggle(this._networkLogShowOverviewSetting,"waterfall-toolbar-item",WebInspector.UIString("Show overview"),WebInspector.UIString("Hide overview"));this._panelToolbar.appendToolbarItem(showOverviewButton);this._panelToolbar.appendSeparator();this._preserveLogCheckbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Preserve log"),WebInspector.UIString("Do not clear log on page reload / navigation"));this._preserveLogCheckbox.inputElement.addEventListener("change",this._onPreserveLogCheckboxChanged.bind(this),false);this._panelToolbar.appendToolbarItem(this._preserveLogCheckbox);this._disableCacheCheckbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Disable cache"),WebInspector.UIString("Disable cache (while DevTools is open)"),WebInspector.moduleSetting("cacheDisabled"));this._panelToolbar.appendToolbarItem(this._disableCacheCheckbox);this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(this._createBlockedURLsButton());this._panelToolbar.appendToolbarItem(WebInspector.NetworkConditionsSelector.createOfflineToolbarCheckbox());this._panelToolbar.appendToolbarItem(this._createNetworkConditionsSelect());this._panelToolbar.appendToolbarItem(new WebInspector.ToolbarItem(this._progressBarContainer));},_createBlockedURLsButton:function() {var setting=WebInspector.moduleSetting("blockedURLs");setting.addChangeListener(updateAction);var action=(WebInspector.actionRegistry.action("network.blocked-urls.show"));var button=WebInspector.Toolbar.createActionButton(action);button.setVisible(Runtime.experiments.isEnabled("requestBlocking"));updateAction();return button;function updateAction() {action.setToggled(!!setting.get().length);}},_createNetworkConditionsSelect:function() {var toolbarItem=new WebInspector.ToolbarComboBox(null);toolbarItem.setMaxWidth(140);WebInspector.NetworkConditionsSelector.decorateSelect(toolbarItem.selectElement());return toolbarItem;},_toggleRecording:function() {if(!this._preserveLogCheckbox.checked()&&!this._toggleRecordAction.toggled()) this._reset();this._toggleRecord(!this._toggleRecordAction.toggled());},_toggleRecord:function(toggled) {this._toggleRecordAction.setToggled(toggled);this._networkLogView.setRecording(toggled);if(!toggled&&this._filmStripRecorder) this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));},_filmStripAvailable:function(filmStripModel) {if(!filmStripModel) return;var calculator=this._networkLogView.timeCalculator();this._filmStripView.setModel(filmStripModel,calculator.minimumBoundary()*1000,calculator.boundarySpan()*1000);this._networkOverview.setFilmStripModel(filmStripModel);var timestamps=filmStripModel.frames().map(mapTimestamp);function mapTimestamp(frame) {return frame.timestamp/1000;} this._networkLogView.addFilmStripFrames(timestamps);},_onPreserveLogCheckboxChanged:function(event) {this._networkLogView.setPreserveLog(this._preserveLogCheckbox.checked());},_onClearButtonClicked:function(event) {this._reset();},_reset:function() {this._calculator.reset();this._overviewPane.reset();this._networkLogView.reset();WebInspector.BlockedURLsPane.reset();if(this._filmStripView) this._resetFilmStripView();},_willReloadPage:function(event) {if(!this._preserveLogCheckbox.checked()) this._reset();this._toggleRecord(true);if(this._pendingStopTimer){clearTimeout(this._pendingStopTimer);delete this._pendingStopTimer;} if(this.isShowing()&&this._filmStripRecorder) this._filmStripRecorder.startRecording();},_load:function(event) {if(this._filmStripRecorder&&this._filmStripRecorder.isRecording()) this._pendingStopTimer=setTimeout(this._toggleRecord.bind(this,false),1000);},_toggleLargerRequests:function() {this._updateUI();},_toggleShowOverview:function() {var toggled=this._networkLogShowOverviewSetting.get();if(toggled) this._overviewPane.show(this.element,this._splitWidget.element);else this._overviewPane.detach();this.doResize();},_toggleRecordFilmStrip:function() {var toggled=this._networkRecordFilmStripSetting.get();if(toggled&&!this._filmStripRecorder){this._filmStripView=new WebInspector.FilmStripView();this._filmStripView.setMode(WebInspector.FilmStripView.Modes.FrameBased);this._filmStripView.element.classList.add("network-film-strip");this._filmStripRecorder=new WebInspector.NetworkPanel.FilmStripRecorder(this._networkLogView.timeCalculator(),this._filmStripView);this._filmStripView.show(this.element,this.element.firstElementChild);this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameSelected,this._onFilmFrameSelected,this);this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameEnter,this._onFilmFrameEnter,this);this._filmStripView.addEventListener(WebInspector.FilmStripView.Events.FrameExit,this._onFilmFrameExit,this);this._resetFilmStripView();} if(!toggled&&this._filmStripRecorder){this._filmStripView.detach();this._filmStripView=null;this._filmStripRecorder=null;}},_resetFilmStripView:function() {this._filmStripView.reset();this._filmStripView.setStatusText(WebInspector.UIString("Hit %s to reload and capture filmstrip.",WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name));},elementsToRestoreScrollPositionsFor:function() {return this._networkLogView.elementsToRestoreScrollPositionsFor();},searchableView:function() {return this._searchableView;},handleShortcut:function(event) {if(this._networkItemView&&event.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code){this._showRequest(null);event.handled=true;return;} WebInspector.Panel.prototype.handleShortcut.call(this,event);},wasShown:function() {WebInspector.context.setFlavor(WebInspector.NetworkPanel,this);},willHide:function() {WebInspector.context.setFlavor(WebInspector.NetworkPanel,null);},revealAndHighlightRequest:function(request) {this._showRequest(null);if(request) this._networkLogView.revealAndHighlightRequest(request);},_onRowSizeChanged:function(event) {this._updateUI();},_onSearchCountUpdated:function(event) {var count=(event.data);this._searchableView.updateSearchMatchesCount(count);},_onSearchIndexUpdated:function(event) {var index=(event.data);this._searchableView.updateCurrentMatchIndex(index);},_onRequestSelected:function(event) {var request=(event.data);this._showRequest(request);},_showRequest:function(request) {if(this._networkItemView){this._networkItemView.detach();this._networkItemView=null;} if(request){this._networkItemView=new WebInspector.NetworkItemView(request,this._networkLogView.timeCalculator());this._networkItemView.insertBeforeTabStrip(this._closeButtonElement);this._networkItemView.show(this._detailsWidget.element);this._splitWidget.showBoth();}else{this._splitWidget.hideMain();this._networkLogView.clearSelection();} this._updateUI();},_updateUI:function() {this._detailsWidget.element.classList.toggle("network-details-view-tall-header",this._networkLogLargeRowsSetting.get());this._networkLogView.switchViewMode(!this._splitWidget.isResizable());},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this._networkLogView.performSearch(searchConfig,shouldJump,jumpBackwards);},jumpToPreviousSearchResult:function() {this._networkLogView.jumpToPreviousSearchResult();},supportsCaseSensitiveSearch:function() {return false;},supportsRegexSearch:function() {return false;},jumpToNextSearchResult:function() {this._networkLogView.jumpToNextSearchResult();},searchCanceled:function() {this._networkLogView.searchCanceled();},appendApplicableItems:function(event,contextMenu,target) {function reveal(request) {WebInspector.inspectorView.setCurrentPanel(this);this.revealAndHighlightRequest(request);} function appendRevealItem(request) {contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Network ^panel"),reveal.bind(this,request));} if(event.target.isSelfOrDescendant(this.element)) return;if(target instanceof WebInspector.Resource){var resource=(target);if(resource.request) appendRevealItem.call(this,resource.request);return;} if(target instanceof WebInspector.UISourceCode){var uiSourceCode=(target);var resource=WebInspector.resourceForURL(WebInspector.networkMapping.networkURL(uiSourceCode));if(resource&&resource.request) appendRevealItem.call(this,resource.request);return;} if(!(target instanceof WebInspector.NetworkRequest)) return;var request=(target);if(this._networkItemView&&this._networkItemView.isShowing()&&this._networkItemView.request()===request) return;appendRevealItem.call(this,request);},_onFilmFrameSelected:function(event) {var timestamp=(event.data);this._overviewPane.requestWindowTimes(0,timestamp);},_onFilmFrameEnter:function(event) {var timestamp=(event.data);this._networkOverview.selectFilmStripFrame(timestamp);this._networkLogView.selectFilmStripFrame(timestamp/1000);},_onFilmFrameExit:function(event) {this._networkOverview.clearFilmStripFrame();this._networkLogView.clearFilmStripFrame();},_onUpdateRequest:function(event) {var request=(event.data);this._calculator.updateBoundaries(request);this._overviewPane.setBounds(this._calculator.minimumBoundary()*1000,this._calculator.maximumBoundary()*1000);this._networkOverview.updateRequest(request);this._overviewPane.scheduleUpdate();},__proto__:WebInspector.Panel.prototype} WebInspector.NetworkPanel.ContextMenuProvider=function() {} WebInspector.NetworkPanel.ContextMenuProvider.prototype={appendApplicableItems:function(event,contextMenu,target) {WebInspector.NetworkPanel._instance().appendApplicableItems(event,contextMenu,target);}} WebInspector.NetworkPanel.RequestRevealer=function() {} WebInspector.NetworkPanel.RequestRevealer.prototype={reveal:function(request) {if(!(request instanceof WebInspector.NetworkRequest)) return Promise.reject(new Error("Internal error: not a network request"));var panel=WebInspector.NetworkPanel._instance();WebInspector.inspectorView.setCurrentPanel(panel);panel.revealAndHighlightRequest(request);return Promise.resolve();}} WebInspector.NetworkPanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.NetworkPanel._instance());} WebInspector.NetworkPanel.revealAndFilter=function(filters) {var panel=WebInspector.NetworkPanel._instance();var filterString="";for(var filter of filters) filterString+=`${filter.filterType}:${filter.filterValue}`;panel._networkLogView.setTextFilterValue(filterString);WebInspector.inspectorView.setCurrentPanel(panel);} WebInspector.NetworkPanel._instance=function() {if(!WebInspector.NetworkPanel._instanceObject) WebInspector.NetworkPanel._instanceObject=new WebInspector.NetworkPanel();return WebInspector.NetworkPanel._instanceObject;} WebInspector.NetworkPanelFactory=function() {} WebInspector.NetworkPanelFactory.prototype={createPanel:function() {return WebInspector.NetworkPanel._instance();}} WebInspector.NetworkPanel.FilmStripRecorder=function(timeCalculator,filmStripView) {this._timeCalculator=timeCalculator;this._filmStripView=filmStripView;} WebInspector.NetworkPanel.FilmStripRecorder.prototype={tracingStarted:function() {},traceEventsCollected:function(events) {if(this._tracingModel) this._tracingModel.addEvents(events);},tracingComplete:function() {if(!this._tracingModel) return;this._tracingModel.tracingComplete();var resourceTreeModel=this._target.resourceTreeModel;this._target=null;setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel));this._callback(new WebInspector.FilmStripModel(this._tracingModel,this._timeCalculator.minimumBoundary()*1000));delete this._callback;},tracingBufferUsage:function() {},eventsRetrievalProgress:function(progress) {},startRecording:function() {this._filmStripView.reset();this._filmStripView.setStatusText(WebInspector.UIString("Recording frames..."));if(this._target) return;this._target=WebInspector.targetManager.mainTarget();if(this._tracingModel) this._tracingModel.reset();else this._tracingModel=new WebInspector.TracingModel(new WebInspector.TempFileBackingStorage("tracing"));this._target.tracingManager.start(this,"-*,disabled-by-default-devtools.screenshot","");},isRecording:function() {return!!this._target;},stopRecording:function(callback) {if(!this._target) return;this._target.tracingManager.stop();this._target.resourceTreeModel.suspendReload();this._callback=callback;this._filmStripView.setStatusText(WebInspector.UIString("Fetching frames..."));}} WebInspector.NetworkPanel.RecordActionDelegate=function() {} WebInspector.NetworkPanel.RecordActionDelegate.prototype={handleAction:function(context,actionId) {var panel=WebInspector.context.flavor(WebInspector.NetworkPanel);console.assert(panel&&panel instanceof WebInspector.NetworkPanel);panel._toggleRecording();return true;}};WebInspector.XMLView=function(parsedXML) {WebInspector.Widget.call(this,true);this.registerRequiredCSS("network/xmlView.css");this.contentElement.classList.add("shadow-xml-view","source-code");this._treeOutline=new TreeOutline();this.contentElement.appendChild(this._treeOutline.element);this._searchableView;this._currentSearchFocusIndex=0;this._currentSearchTreeElements=[];this._searchConfig;WebInspector.XMLView.Node.populate(this._treeOutline,parsedXML,this);} WebInspector.XMLView.createSearchableView=function(parsedXML) {var xmlView=new WebInspector.XMLView(parsedXML);var searchableView=new WebInspector.SearchableView(xmlView);searchableView.setPlaceholder(WebInspector.UIString("Find"));xmlView._searchableView=searchableView;xmlView.show(searchableView.element);xmlView.contentElement.setAttribute("tabIndex",0);return searchableView;} WebInspector.XMLView.parseXML=function(text,mimeType) {var parsedXML;try{parsedXML=(new DOMParser()).parseFromString(text,mimeType);}catch(e){return null;} if(parsedXML.body) return null;return parsedXML;} WebInspector.XMLView.prototype={_jumpToMatch:function(index,shouldJump) {if(!this._searchConfig) return;var regex=this._searchConfig.toSearchRegex(true);var previousFocusElement=this._currentSearchTreeElements[this._currentSearchFocusIndex];if(previousFocusElement) previousFocusElement.setSearchRegex(regex);var newFocusElement=this._currentSearchTreeElements[index];if(newFocusElement){this._updateSearchIndex(index);if(shouldJump) newFocusElement.reveal(true);newFocusElement.setSearchRegex(regex,WebInspector.highlightedCurrentSearchResultClassName);}else{this._updateSearchIndex(0);}},_updateSearchCount:function(count) {if(!this._searchableView) return;this._searchableView.updateSearchMatchesCount(count);},_updateSearchIndex:function(index) {this._currentSearchFocusIndex=index;if(!this._searchableView) return;this._searchableView.updateCurrentMatchIndex(index);},_innerPerformSearch:function(shouldJump,jumpBackwards) {if(!this._searchConfig) return;var newIndex=this._currentSearchFocusIndex;var previousSearchFocusElement=this._currentSearchTreeElements[newIndex];this._innerSearchCanceled();this._currentSearchTreeElements=[];var regex=this._searchConfig.toSearchRegex(true);for(var element=this._treeOutline.rootElement();element;element=element.traverseNextTreeElement(false)){if(!(element instanceof WebInspector.XMLView.Node)) continue;var hasMatch=element.setSearchRegex(regex);if(hasMatch) this._currentSearchTreeElements.push(element);if(previousSearchFocusElement===element){var currentIndex=this._currentSearchTreeElements.length-1;if(hasMatch||jumpBackwards) newIndex=currentIndex;else newIndex=currentIndex+1;}} this._updateSearchCount(this._currentSearchTreeElements.length);if(!this._currentSearchTreeElements.length){this._updateSearchIndex(0);return;} newIndex=mod(newIndex,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex,shouldJump);},_innerSearchCanceled:function() {for(var element=this._treeOutline.rootElement();element;element=element.traverseNextTreeElement(false)){if(!(element instanceof WebInspector.XMLView.Node)) continue;element.revertHighlightChanges();} this._updateSearchCount(0);this._updateSearchIndex(0);},searchCanceled:function() {this._searchConfig=null;this._currentSearchTreeElements=[];this._innerSearchCanceled();},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this._searchConfig=searchConfig;this._innerPerformSearch(shouldJump,jumpBackwards);},jumpToNextSearchResult:function() {if(!this._currentSearchTreeElements.length) return;var newIndex=mod(this._currentSearchFocusIndex+1,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex,true);},jumpToPreviousSearchResult:function() {if(!this._currentSearchTreeElements.length) return;var newIndex=mod(this._currentSearchFocusIndex-1,this._currentSearchTreeElements.length);this._jumpToMatch(newIndex,true);},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return true;},__proto__:WebInspector.Widget.prototype} WebInspector.XMLView.Node=function(node,closeTag,xmlView) {TreeElement.call(this,"",!closeTag&&!!node.childElementCount);this._node=node;this._closeTag=closeTag;this.selectable=false;this._highlightChanges=[];this._xmlView=xmlView;this._updateTitle();} WebInspector.XMLView.Node.populate=function(root,xmlNode,xmlView) {var node=xmlNode.firstChild;while(node){var currentNode=node;node=node.nextSibling;var nodeType=currentNode.nodeType;if(nodeType===3&¤tNode.nodeValue.match(/\s+/)) continue;if((nodeType!==1)&&(nodeType!==3)&&(nodeType!==4)&&(nodeType!==7)&&(nodeType!==8)) continue;root.appendChild(new WebInspector.XMLView.Node(currentNode,false,xmlView));}} WebInspector.XMLView.Node.prototype={setSearchRegex:function(regex,additionalCssClassName){this.revertHighlightChanges();if(!regex) return false;if(this._closeTag&&this.parent&&!this.parent.expanded) return false;regex.lastIndex=0;var cssClasses=WebInspector.highlightedSearchResultClassName;if(additionalCssClassName) cssClasses+=" "+additionalCssClassName;var content=this.listItemElement.textContent.replace(/\xA0/g," ");var match=regex.exec(content);var ranges=[];while(match){ranges.push(new WebInspector.SourceRange(match.index,match[0].length));match=regex.exec(content);} if(ranges.length) WebInspector.highlightRangesWithStyleClass(this.listItemElement,ranges,cssClasses,this._highlightChanges);return!!this._highlightChanges.length;},revertHighlightChanges:function() {WebInspector.revertDomChanges(this._highlightChanges);this._highlightChanges=[];},_updateTitle:function() {var node=this._node;switch(node.nodeType){case 1:var tag=node.tagName;if(this._closeTag){this._setTitle(["</"+tag+">","shadow-xml-view-tag"]);return;} var titleItems=["<"+tag,"shadow-xml-view-tag"];var attributes=node.attributes;for(var i=0;i<attributes.length;++i){var attributeNode=attributes.item(i);titleItems.push("\u00a0","shadow-xml-view-tag",attributeNode.name,"shadow-xml-view-attribute-name","=\"","shadow-xml-view-tag",attributeNode.value,"shadow-xml-view-attribute-value","\"","shadow-xml-view-tag")} if(!this.expanded){if(node.childElementCount){titleItems.push(">","shadow-xml-view-tag","\u2026","shadow-xml-view-comment","</"+tag,"shadow-xml-view-tag");}else if(this._node.textContent){titleItems.push(">","shadow-xml-view-tag",node.textContent,"shadow-xml-view-text","</"+tag,"shadow-xml-view-tag");}else{titleItems.push(" /","shadow-xml-view-tag");}} titleItems.push(">","shadow-xml-view-tag");this._setTitle(titleItems);return;case 3:this._setTitle([node.nodeValue,"shadow-xml-view-text"]);return;case 4:this._setTitle(["<![CDATA[","shadow-xml-view-cdata",node.nodeValue,"shadow-xml-view-text","]]>","shadow-xml-view-cdata"]);return;case 7:this._setTitle(["<?"+node.nodeName+" "+node.nodeValue+"?>","shadow-xml-view-processing-instruction"]);return;case 8:this._setTitle(["<!--"+node.nodeValue+"-->","shadow-xml-view-comment"]);return;}},_setTitle:function(items) {var titleFragment=createDocumentFragment();for(var i=0;i<items.length;i+=2) titleFragment.createChild("span",items[i+1]).textContent=items[i];this.title=titleFragment;this._xmlView._innerPerformSearch(false,false);},onattach:function() {this.listItemElement.classList.toggle("shadow-xml-view-close-tag",this._closeTag);},onexpand:function() {this._updateTitle();},oncollapse:function() {this._updateTitle();},onpopulate:function() {WebInspector.XMLView.Node.populate(this,this._node,this._xmlView);this.appendChild(new WebInspector.XMLView.Node(this._node,true,this._xmlView));},__proto__:TreeElement.prototype};Runtime.cachedResources["network/blockedURLsPane.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.blocked-urls-pane {\n overflow: hidden;\n}\n\n.toolbar {\n border-bottom: 1px solid #dadada;\n}\n\n.no-blocked-urls, .blocked-urls-list {\n font-size: 11px;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.no-blocked-urls {\n display: flex;\n justify-content: center;\n padding: 3px;\n}\n\n.no-blocked-urls > span {\n white-space: pre;\n}\n\n.blocked-url {\n flex: none;\n display: flex;\n align-items: center;\n padding: 3px 10px 3px 9px;\n position: relative;\n}\n\n.blocked-url:not(.blocked-url-editing):hover {\n background-color: #dadada;\n}\n\n.blocked-url .blocked-count {\n flex: 30px 0 0;\n font-size: smaller !important;\n padding-right: 5px;\n}\n\n.blocked-url > input {\n position: absolute;\n left: 6px;\n right: 6px;\n top: 0;\n bottom: 0;\n width: calc(100% - 12px);\n}\n\n.blocked-url-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n flex: auto;\n margin-right: 5px;\n}\n\n.blocked-url .remove-button {\n width: 13px;\n height: 13px;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n background-position: -175px -96px;\n visibility: hidden;\n flex: none;\n opacity: 0.7;\n cursor: default;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.blocked-url .remove-button {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.blocked-url:hover .remove-button {\n visibility: visible;\n}\n\n.blocked-url .remove-button:hover {\n opacity: 1.0;\n}\n/*# sourceURL=network/blockedURLsPane.css */";Runtime.cachedResources["network/eventSourceMessagesView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.event-source-messages-view .data-grid {\n flex: auto;\n border: none;\n}\n\n/*# sourceURL=network/eventSourceMessagesView.css */";Runtime.cachedResources["network/networkConfigView.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.network-config {\n padding: 12px;\n display: block;\n}\n\n.network-config-group {\n display: flex;\n margin-bottom: 10px;\n flex-wrap: wrap;\n flex: 0 0 auto;\n min-height: 30px;\n}\n\n.network-config-title {\n margin-right: 16px;\n width: 130px;\n}\n\n.network-config-fields {\n flex: 2 0 200px;\n}\n\n.panel-section-separator {\n height: 1px;\n margin-bottom: 10px;\n background: #f0f0f0;\n}\n\n/* Disable cache */\n\n.network-config-disable-cache {\n line-height: 28px;\n border-top: none;\n padding-top: 0;\n}\n\n/* Network throttling */\n\n.network-config-throttling .chrome-select {\n width: 100%;\n max-width: 250px;\n}\n\n.network-config-throttling > .network-config-title {\n line-height: 24px;\n}\n\n/* User agent */\n\n.network-config-ua > .network-config-title {\n line-height: 20px;\n}\n\n.network-config-ua label[is=\"dt-radio\"].checked > * {\n display: none\n}\n\n.network-config-ua input:not(.dt-radio-button) {\n display: block;\n width: calc(100% - 20px);\n max-width: 250px;\n border: 1px solid #bfbfbf;\n border-radius: 2px;\n box-sizing: border-box;\n color: #444;\n font: inherit;\n border-width: 1px;\n min-height: 2em;\n padding: 3px;\n}\n\n.network-config-ua input[readonly] {\n background-color: rgb(235, 235, 228);\n}\n\n.network-config-ua input[type=text], .network-config-ua .chrome-select {\n margin-top: 8px;\n}\n\n.network-config-ua .chrome-select {\n width: calc(100% - 20px);\n max-width: 250px;\n}\n\n.network-config-ua label[is=\"dt-radio\"] {\n display: block;\n}\n\n.network-config-ua-auto, .network-config-ua-custom {\n opacity: 0.5;\n}\n\n.network-config-ua-auto.checked, .network-config-ua-custom.checked {\n opacity: 1;\n}\n\n/*# sourceURL=network/networkConfigView.css */";Runtime.cachedResources["network/networkLogView.css"]="/*\n * Copyright (C) 2013 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.network-log-grid.data-grid {\n border: none;\n flex: auto;\n}\n\n.network-summary-bar {\n flex: 0 0 27px;\n line-height: 27px;\n padding-left: 5px;\n background-color: #eee;\n border-top: 1px solid #ccc;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.network-summary-bar label[is=dt-icon-label] {\n margin-right: 6px;\n}\n\n.network-summary-bar > * {\n flex: none;\n}\n\n.network-log-grid.data-grid table.data {\n background: transparent;\n}\n\n.network-log-grid .odd {\n background: #f5f5f5;\n}\n\n.network-log-grid .network-navigation-row,\n.network-log-grid .network-navigation-row.odd {\n background: #def;\n}\n\n.network-log-grid.data-grid td {\n line-height: 17px;\n height: 41px;\n border-left: 1px solid #e1e1e1;\n vertical-align: middle;\n}\n\n.network-log-grid.data-grid.small td {\n height: 21px;\n}\n\n.network-log-grid.data-grid th {\n border-bottom: 1px solid rgb(205, 205, 205);\n border-left: 1px solid rgb(205, 205, 205);\n background: white;\n}\n\n.network-log-grid.data-grid .header-container {\n height: 31px;\n}\n\n.network-log-grid.data-grid .data-container {\n top: 31px;\n}\n\n.network-log-grid.data-grid.small .header-container {\n height: 27px;\n}\n\n.network-log-grid.data-grid.small .data-container {\n top: 27px;\n}\n\n.network-log-grid.data-grid select {\n -webkit-appearance: none;\n background-color: transparent;\n border: none;\n width: 100%;\n color: inherit;\n}\n\n.network-log-grid.data-grid .name-column {\n cursor: pointer;\n}\n\n.network-log-grid.data-grid .timeline-column {\n padding: 1px 0;\n}\n\n.network-log-grid.data-grid .timeline-column .sort-order-icon-container {\n right: 15px;\n pointer-events: none;\n}\n\n#network-container:not(.brief-mode) .network-log-grid.data-grid td.name-column:hover {\n text-decoration: underline;\n}\n\n.network-log-grid.data-grid.small .network-graph-side {\n height: 19px;\n}\n\n.network-log-grid.data-grid th.sortable:active {\n background-image: none !important;\n}\n\n.network-cell-subtitle {\n font-weight: normal;\n color: gray;\n}\n\n.network-error-row,\n.network-error-row .network-cell-subtitle {\n color: rgb(230, 0, 0);\n}\n\n.initiator-column a {\n color: inherit;\n}\n\n.network-log-grid.data-grid tr.selected,\n.network-log-grid.data-grid tr.selected .network-cell-subtitle,\n.network-log-grid.data-grid tr.selected .network-dim-cell {\n color: inherit !important;\n}\n\n.network-log-grid.data-grid:focus tr.selected,\n.network-log-grid.data-grid:focus tr.selected .network-cell-subtitle,\n.network-log-grid.data-grid:focus tr.selected .network-dim-cell {\n color: white !important;\n}\n\n.network-log-grid tr.highlighted-row {\n -webkit-animation: network-row-highlight-fadeout 2s 0s;\n}\n\n@-webkit-keyframes network-row-highlight-fadeout {\n from {background-color: rgba(255, 255, 120, 1); }\n to { background-color: rgba(255, 255, 120, 0); }\n}\n\n.network-header-subtitle {\n color: gray;\n}\n\n.network-log-grid.data-grid.small .network-cell-subtitle,\n.network-log-grid.data-grid.small .network-header-subtitle {\n display: none;\n}\n\n/* Resource preview icons */\n\n.network-log-grid.data-grid .icon {\n content: url(Images/resourcePlainIcon.png);\n}\n\n.network-log-grid.data-grid.small .icon {\n content: url(Images/resourcePlainIconSmall.png);\n}\n\n.network-log-grid.data-grid .icon.script {\n content: url(Images/resourceJSIcon.png);\n}\n\n.network-log-grid.data-grid.small .icon.script {\n content: url(Images/resourceDocumentIconSmall.png);\n}\n\n.network-log-grid.data-grid .icon.document {\n content: url(Images/resourceDocumentIcon.png);\n}\n\n.network-log-grid.data-grid.small .icon.document {\n content: url(Images/resourceDocumentIconSmall.png);\n}\n\n.network-log-grid.data-grid .icon.stylesheet {\n content: url(Images/resourceCSSIcon.png);\n}\n\n.network-log-grid.data-grid.small .icon.stylesheet {\n content: url(Images/resourceDocumentIconSmall.png);\n}\n\n.network-log-grid.data-grid .icon.media {\n content: url(Images/resourcePlainIcon.png); /* FIXME: media icon */\n}\n\n.network-log-grid.data-grid.small .icon.media {\n content: url(Images/resourcePlainIconSmall.png); /* FIXME: media icon */\n}\n.network-log-grid.data-grid .icon.texttrack {\n content: url(Images/resourcePlainIcon.png); /* FIXME: vtt icon */\n}\n\n.network-log-grid.data-grid.small .icon.texttrack {\n content: url(Images/resourcePlainIconSmall.png); /* FIXME: vtt icon */\n}\n\n.network-log-grid.data-grid .icon.image {\n position: relative;\n background-image: url(Images/resourcePlainIcon.png);\n background-repeat: no-repeat;\n content: \"\";\n}\n\n.network-log-grid.data-grid.small .icon.image {\n background-image: url(Images/resourcePlainIconSmall.png);\n content: \"\";\n}\n\n.network-log-grid.data-grid .icon {\n float: left;\n width: 32px;\n height: 32px;\n margin-top: 1px;\n margin-right: 3px;\n}\n\n.network-log-grid.data-grid.small .icon {\n width: 16px;\n height: 16px;\n}\n\n.network-log-grid.data-grid .image-network-icon-preview {\n position: absolute;\n margin: auto;\n top: 3px;\n bottom: 4px;\n left: 5px;\n right: 5px;\n max-width: 18px;\n max-height: 21px;\n min-width: 1px;\n min-height: 1px;\n}\n\n.network-log-grid.data-grid.small .image-network-icon-preview {\n top: 2px;\n bottom: 1px;\n left: 3px;\n right: 3px;\n max-width: 8px;\n max-height: 11px;\n}\n\n/* Graph styles */\n\n.network-graph-side {\n position: relative;\n height: 39px;\n padding: 0;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.network-graph-bar-area {\n position: absolute;\n top: 0;\n bottom: 0;\n}\n\n.network-graph-bar-area,\n.network-timeline-grid .resources-dividers,\n.network-timeline-grid .resources-event-dividers,\n.network-timeline-grid .resources-dividers-label-bar {\n right: 12px;\n left: 12px;\n}\n\n.network-timeline-grid .resources-event-dividers {\n margin-left: 1px;\n}\n\n.network-graph-label {\n position: absolute;\n top: 0;\n bottom: 0;\n height: 13px;\n line-height: 13px;\n margin: auto;\n font-size: 90%;\n color: rgba(0, 0, 0, 0.75);\n text-shadow: rgba(255, 255, 255, 0.25) 1px 0 0, rgba(255, 255, 255, 0.25) -1px 0 0, rgba(255, 255, 255, 0.333) 0 1px 0, rgba(255, 255, 255, 0.25) 0 -1px 0;\n z-index: 150;\n overflow: hidden;\n text-align: center;\n visibility: hidden;\n}\n\n.network-graph-side:hover .network-graph-label {\n visibility: visible;\n}\n\n.network-graph-label:empty {\n display: none;\n}\n\n.network-graph-label.waiting {\n margin-right: 5px;\n}\n\n.network-graph-label.before {\n color: rgba(0, 0, 0, 0.7);\n text-shadow: none;\n text-align: right;\n margin-right: -1px;\n}\n\n.network-graph-label.before::after {\n padding-left: 2px;\n height: 6px;\n content: url(Images/graphLabelCalloutLeft.png);\n}\n\n.network-graph-label.after {\n color: rgba(0, 0, 0, 0.7);\n text-shadow: none;\n text-align: left;\n margin-left: -1px;\n}\n\n.network-graph-label.after::before {\n padding-right: 2px;\n height: 6px;\n content: url(Images/graphLabelCalloutRight.png);\n}\n\n.small .network-graph-bar {\n top: 3px;\n bottom: 3px;\n}\n\n.network-graph-bar {\n position: absolute;\n top: 13px;\n bottom: 13px;\n min-width: 3px;\n}\n\n.network-graph-bar:not(.request-timing) {\n border-width: 1px;\n border-style: solid;\n border-color: hsl(0, 0%, 75%);\n background: linear-gradient(0deg, hsl(0, 0%, 85%), hsl(0, 0%, 95%));\n}\n\n.network-graph-bar.waiting:not(.request-timing) {\n opacity: 0.5;\n}\n\n/* Resource categories */\n\n.network-graph-bar.request-timing.queueing,\n.network-graph-bar.request-timing.total,\n.network-graph-bar.request-timing.proxy,\n.network-graph-bar.request-timing.dns,\n.network-graph-bar.request-timing.ssl,\n.network-graph-bar.request-timing.connecting,\n.network-graph-bar.request-timing.blocking,\n.network-graph-bar.request-timing.push {\n margin: 3px 0;\n}\n\n.network-graph-bar.request-timing.queueing,\n.network-graph-bar.request-timing.total, -theme-preserve {\n border: solid 1px #AAAAAA;\n}\n\n.network-graph-bar.request-timing.receiving, -theme-preserve,\n.network-graph-bar.request-timing.receiving-push, -theme-preserve {\n background-color: #03A9F4;\n}\n\n.network-graph-bar.request-timing.waiting, -theme-preserve {\n background-color: #00C853;\n}\n\n.network-graph-bar.request-timing.connecting, -theme-preserve {\n background-color: #FF9800;\n}\n\n.network-graph-bar.request-timing.ssl, -theme-preserve {\n background-color: #9C27B0;\n}\n\n.network-graph-bar.request-timing.dns, -theme-preserve {\n background-color: #009688;\n}\n\n.network-graph-bar.request-timing.proxy, -theme-preserve {\n background-color: #A1887F;\n}\n\n.network-graph-bar.request-timing.blocking, -theme-preserve {\n background-color: #AAAAAA;\n}\n\n.network-graph-bar.request-timing.push, -theme-preserve {\n background-color: #8CDBff;\n}\n\n.network-graph-bar.cached {\n background: hsl(0, 0%, 90%);\n}\n\n.network-graph-bar.document {\n border-color: hsl(215, 49%, 60%);\n background: linear-gradient(0deg, hsl(215, 72%, 65%), hsl(215, 100%, 80%));\n}\n\n.network-graph-bar.cached.document {\n background: hsl(215, 99%, 80%);\n}\n\n.network-graph-bar.stylesheet {\n border-color: hsl(99, 34%, 60%);\n background: linear-gradient(0deg, hsl(100, 50%, 65%), hsl(90, 50%, 80%));\n}\n\n.network-graph-bar.cached.stylesheet {\n background: hsl(99, 100%, 80%);\n}\n\n.network-graph-bar.image {\n border-color: hsl(272, 31%, 60%);\n background: linear-gradient(0deg, hsl(272, 46%, 65%), hsl(272, 64%, 80%));\n}\n\n.network-graph-bar.cached.image {\n background: hsl(272, 65%, 80%);\n}\n\n.network-graph-bar.media {\n border-color: hsl(272, 31%, 60%);\n background: linear-gradient(0deg, hsl(272, 46%, 65%), hsl(272, 64%, 80%));\n}\n\n.network-graph-bar.cached.media {\n background: hsl(272, 65%, 80%);\n}\n\n.network-graph-bar.font {\n border-color: hsl(8, 49%, 60%);\n background: linear-gradient(0deg, hsl(8, 72%, 65%), hsl(8, 100%, 80%));\n}\n\n.network-graph-bar.cached.font {\n background: hsl(8, 100%, 80%);\n}\n\n.network-graph-bar.texttrack {\n border-color: hsl(8, 49%, 60%);\n background: linear-gradient(0deg, hsl(8, 72%, 65%), hsl(8, 100%, 80%));\n}\n\n.network-graph-bar.cached.texttrack {\n background: hsl(8, 100%, 80%);\n}\n\n.network-graph-bar.script {\n border-color: hsl(31, 49%, 60%);\n background: linear-gradient(0deg, hsl(31, 72%, 65%), hsl(31, 100%, 80%));\n}\n\n.network-graph-bar.cached.script {\n background: hsl(31, 100%, 80%);\n}\n\n.network-graph-bar.xhr {\n border-color: hsl(53, 49%, 60%);\n background: linear-gradient(0deg, hsl(53, 72%, 65%), hsl(53, 100%, 80%));\n}\n\n.network-graph-bar.cached.xhr {\n background: hsl(53, 100%, 80%);\n}\n\n.network-graph-bar.websocket {\n border-color: hsl(0, 0%, 60%);\n background: linear-gradient(0deg, hsl(0, 0%, 65%), hsl(0, 0%, 80%));\n}\n\n.network-graph-bar.cached.websocket {\n background: hsl(0, 0%, 80%);\n}\n\n.network-dim-cell {\n color: grey;\n}\n\n/* Dividers */\n\n.network-timeline-grid {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 14px; /* Keep in sync with td.corner width */\n pointer-events: none;\n}\n\n.network-event-divider {\n position: absolute;\n width: 1px;\n margin-left: -1px;\n top: 31px;\n bottom: 0;\n z-index: 300;\n}\n\n.network-event-divider.invisible {\n visibility: hidden;\n}\n\n.network-timeline-grid.small .network-event-divider {\n top: 23px;\n}\n\n.network-red-divider {\n background-color: rgba(255, 0, 0, 0.5);\n}\n\n.-theme-with-dark-background .network-red-divider {\n background-color: hsla(0, 100%, 80%, 0.7);\n}\n\n.network-summary-bar .summary-red {\n color: red;\n}\n\n.-theme-with-dark-background .network-blue-divider {\n background-color: hsla(240, 100%, 80%, 0.7);\n}\n\n.network-frame-divider {\n width: 2px;\n background-color: #FCCC49;\n z-index: 10;\n visibility: hidden;\n}\n\n.network-frame-divider-selected {\n visibility: visible;\n}\n\n.network-summary-bar .summary-blue {\n color: blue;\n}\n\n.network-log-grid.data-grid .resources-dividers {\n z-index: 0;\n}\n\n.network-log-grid.data-grid .resources-dividers-label-bar {\n background-color: transparent;\n border: none;\n height: 30px;\n pointer-events: none;\n}\n\n.network-timeline-grid.small .resources-dividers-label-bar {\n height: 23px;\n}\n\n.network-timeline-grid .resources-divider-label {\n top: 0;\n margin-top: -5px;\n}\n\n.network-timeline-grid .resources-dividers-label-bar .resources-divider {\n top: 23px;\n}\n\n.network-timeline-grid.small .resources-dividers-label-bar .resources-divider {\n top: 15px;\n}\n\n.network-timeline-grid .resources-divider:first-child .resources-divider-label {\n display: none;\n}\n\n.network-timeline-grid .resources-dividers-label-bar .resources-divider:first-child {\n background-color: transparent;\n}\n\n#network-container {\n overflow: hidden;\n}\n\n/* Brief mode peculiarities. */\n#network-container.brief-mode .network-timeline-grid {\n display: none;\n}\n\n.network-log-grid.data-grid .data-container tr:not(.data-grid-filler-row):not(.selected):hover {\n background-color: rgba(56, 121, 217, 0.1);\n}\n\n.network-log-grid .network-node-on-initiator-path {\n background-color: hsla(120, 68%, 54%, 0.2) !important;\n}\n\n.network-log-grid .network-node-on-initiated-path {\n background-color: hsla(0, 68%, 54%, 0.2) !important;\n}\n\n.network-status-pane {\n color: #777;\n background-color: white;\n z-index: 500;\n display: flex;\n justify-content: center;\n align-items: center;\n text-align: center;\n padding: 0 20px;\n overflow: auto;\n}\n\n.network-status-pane > .recording-hint {\n font-size: 14px;\n text-align: center;\n line-height: 28px;\n}\n\n/*# sourceURL=network/networkLogView.css */";Runtime.cachedResources["network/networkPanel.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.panel.network > .toolbar {\n position: relative;\n border-bottom: 1px solid #dadada;\n}\n\n.network-details-view {\n background: rgb(203, 203, 203);\n}\n\n.network-close-button {\n margin: auto -1px auto 4px;\n}\n\n.network-details-view-tall-header {\n margin-top: 4px;\n}\n\n.network-item-view {\n display: flex;\n background: white;\n}\n\n.network-item-preview-toolbar {\n border-top: 1px solid #ccc;\n background-color: #eee;\n}\n\n.resource-timing-view {\n display: block;\n margin: 6px;\n color: rgb(30%, 30%, 30%);\n}\n\n/* Network timing is shared between popover and network item view pane */\n\n.network-timing-table {\n width: 380px;\n border-spacing: 0;\n padding-left: 10px;\n padding-right: 10px;\n}\n\n.network-timing-table-header td {\n color: #bbb;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n}\n\n.network-timing-table-header td:last-child {\n text-align: right;\n}\n\n.network-timing-table col.labels {\n width: 120px;\n}\n\n.network-timing-table col.duration {\n width: 80px;\n}\n\n.network-timing-table td {\n padding: 2px 0;\n}\n\n.network-timing-table td.caution {\n font-weight: bold;\n color: rgb(255, 128, 0);\n padding: 2px 0;\n}\n\n.network-timing-footer td {\n border-top: 8px solid transparent;\n}\n\n.network-timing-footer td:last-child {\n font-weight: bold;\n text-align: right;\n}\n\n.network-timing-row {\n position: relative;\n height: 15px;\n}\n\n.network-timing-bar {\n position: absolute;\n min-width: 1px;\n top: 0;\n bottom: 0;\n}\n\n.network-timing-bar-title {\n color: #222;\n white-space: nowrap;\n text-align: right;\n}\n\n.network-timing-bar.queueing,\n.network-timing-bar.total {\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.network-timing-bar.blocking, -theme-preserve {\n background-color: #AAAAAA;\n}\n\n.network-timing-bar.proxy, -theme-preserve {\n background-color: #A1887F;\n}\n\n.network-timing-bar.dns, -theme-preserve {\n background-color: #009688;\n}\n\n.network-timing-bar.connecting,\n.network-timing-bar.serviceworker,\n.network-timing-bar.serviceworker-preparation, -theme-preserve {\n background-color: #FF9800;\n}\n\n.network-timing-bar.ssl, -theme-preserve {\n background-color: #9C27B0;\n}\n\n.network-timing-bar.sending, -theme-preserve {\n background-color: #B0BEC5;\n}\n\n.network-timing-bar.waiting, -theme-preserve {\n background-color: #00C853;\n}\n\n.network-timing-bar.receiving, -theme-preserve,\n.network-timing-bar.receiving-push, -theme-preserve {\n background-color: #03A9F4;\n}\n\n.network-timing-bar.push, -theme-preserve {\n background-color: #8CDBff;\n}\n\n.network-timing-bar.proxy,\n.network-timing-bar.dns,\n.network-timing-bar.ssl,\n.network-timing-bar.connecting,\n.network-timing-bar.blocking {\n height: 10px;\n margin: auto;\n}\n\n.resource-timing-view .network-timing-table {\n width: 100%;\n}\n\n#network-overview-panel {\n flex: none;\n position: relative;\n}\n\n#network-overview-container {\n overflow: hidden;\n flex: auto;\n display: flex;\n flex-direction: column;\n position: relative;\n border-bottom: 1px solid #CDCDCD;\n}\n\n#network-overview-container canvas {\n width: 100%;\n height: 100%;\n}\n\n#network-overview-grid .resources-dividers-label-bar {\n pointer-events: auto;\n}\n\n.network .network-overview {\n flex: 0 0 60px;\n}\n\n.network-overview .overview-grid-window,\n.network-overview .overview-grid-dividers-background {\n height: 100%;\n}\n\n.network-overview .resources-dividers-label-bar {\n background-color: rgba(255, 255, 255, 0.95);\n}\n\n.network-overview .resources-dividers-label-bar .resources-divider {\n background-color: transparent;\n}\n\n.network-overview .resources-dividers {\n z-index: 250;\n}\n\n.json-view {\n padding: 2px 6px;\n overflow: auto;\n}\n\n.request-view.html iframe {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.network-film-strip {\n border-bottom: solid 1px #cdcdcd;\n flex: none !important;\n}\n\n.network-blocked-urls {\n border-top: 1px solid #dadada;\n flex: 104px 0 0;\n}\n\n/*# sourceURL=network/networkPanel.css */";Runtime.cachedResources["network/requestCookiesView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.request-cookies-view {\n display: flex;\n overflow: auto;\n margin: 12px;\n height: 100%;\n}\n\n.request-cookies-view .data-grid {\n flex: auto;\n height: 100%;\n}\n\n.request-cookies-view .data-grid .row-group {\n font-weight: bold;\n font-size: 11px;\n}\n\n/*# sourceURL=network/requestCookiesView.css */";Runtime.cachedResources["network/requestHeadersView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.request-headers-view {\n -webkit-user-select: text;\n overflow: auto;\n}\n\n.request-headers-view .outline-disclosure {\n -webkit-padding-start: 4px;\n flex-grow: 1;\n overflow-y: auto;\n}\n\n.request-headers-view .outline-disclosure > ol {\n padding-bottom: 5px;\n}\n\n.request-headers-view .outline-disclosure > .parent {\n -webkit-user-select: none;\n font-weight: bold;\n color: #616161;\n margin-top: -1px;\n height: 20px;\n border-top: solid 1px #e0e0e0;\n display: flex;\n align-items: center;\n}\n\n.request-headers-view .outline-disclosure li.parent::before {\n position: static;\n width: 13px;\n height: 9px;\n -webkit-mask-position: -4px -98px;\n background-image: none;\n opacity: 1;\n}\n\n.request-headers-view .outline-disclosure li.parent.expanded::before {\n -webkit-mask-position: -20px -98px;\n}\n\n.request-headers-view .properties-tree li.parent {\n margin-left: 10px;\n}\n\n.request-headers-view .outline-disclosure .children li {\n white-space: nowrap;\n margin-left: 10px;\n}\n\n.request-headers-view .outline-disclosure .children li::before {\n display: none;\n}\n\n.request-headers-view .outline-disclosure .caution {\n margin-left: 4px;\n display: inline-block;\n font-weight: bold;\n}\n\n.request-headers-view .outline-disclosure li.expanded .header-count {\n display: none;\n}\n\n.request-headers-view .outline-disclosure li .header-toggle {\n display: none;\n}\n\n.request-headers-view .outline-disclosure li .status-from-cache {\n color: gray;\n}\n\n.request-headers-view .outline-disclosure li.expanded .header-toggle {\n display: inline;\n margin-left: 30px;\n font-weight: normal;\n color: rgb(45%, 45%, 45%);\n}\n\n.request-headers-view .outline-disclosure li .header-toggle:hover {\n color: rgb(20%, 20%, 45%);\n cursor: pointer;\n}\n\n.request-headers-view .outline-disclosure .header-name {\n color: rgb(33%, 33%, 33%);\n display: inline-block;\n margin-right: 0.5em;\n font-weight: bold;\n vertical-align: top;\n white-space: pre-wrap;\n}\n\n.request-headers-view .outline-disclosure .header-value {\n display: inline;\n margin-right: 1em;\n white-space: pre-wrap;\n word-break: break-all;\n margin-top: 1px;\n}\n\n.request-headers-view .outline-disclosure .empty-request-header {\n color: rgba(33%, 33%, 33%, 0.5);\n}\n\n.resource-status-image {\n margin-top: -2px;\n margin-right: 3px;\n}\n\n.request-headers-view .filter-input {\n outline: none !important;\n border: none;\n border-bottom: solid 1px #ccc;\n flex: 0 0 19px;\n padding: 0 4px;\n}\n\n/*# sourceURL=network/requestHeadersView.css */";Runtime.cachedResources["network/webSocketFrameView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.websocket-frame-view {\n -webkit-user-select: text;\n}\n\n.websocket-frame-view .data-grid {\n flex: auto;\n border: none;\n}\n\n.websocket-frame-view .data-grid .data {\n background-image: none;\n}\n\n.websocket-frame-view-td {\n border-bottom: 1px solid #ccc;\n}\n\n.websocket-frame-view .data-grid tr.selected {\n background-color: #def;\n}\n\n.websocket-frame-view .data-grid td,\n.websocket-frame-view .data-grid th {\n border-left-color: #ccc;\n}\n\n.websocket-frame-view-row-outcoming {\n background-color: rgb(226, 247, 218);\n}\n\n.websocket-frame-view-row-opcode {\n background-color: rgb(255, 255, 232);\n color: rgb(170, 111, 71);\n}\n\n.websocket-frame-view-row-error {\n background-color: rgb(255, 237, 237);\n color: rgb(182, 0, 0);\n}\n\n/*# sourceURL=network/webSocketFrameView.css */";Runtime.cachedResources["network/xmlView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.shadow-xml-view {\n -webkit-user-select: text;\n overflow: auto;\n padding: 2px 4px;\n}\n\n.shadow-xml-view ol {\n list-style: none;\n padding: 0;\n margin: 0;\n -webkit-padding-start: 16px;/* step width + arrow width */\n}\n\n.shadow-xml-view > ol {\n -webkit-padding-start: 0;\n}\n\n.shadow-xml-view ol.children:not(.expanded) {\n display: none;\n}\n\n.shadow-xml-view li.parent::before {\n -webkit-user-select: none;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n -webkit-mask-position: -4px -97px;\n background-color: rgb(110, 110, 110);\n content: \" \";\n width: 10px;/* arrow width */\n height: 10px;\n display: inline-block;\n position: relative;\n top: 2px;\n}\n\n.shadow-xml-view li.parent.expanded::before {\n -webkit-mask-position: -20px -97px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.shadow-xml-view li.parent::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.shadow-xml-view li:not(.parent) {\n margin-left: 10px; /* arrow width */\n}\n\n.shadow-xml-view li.shadow-xml-view-close-tag {\n margin-left: -6px; /* step width */\n}\n\n.shadow-xml-view-tag {\n color: rgb(136, 18, 128);\n}\n\n.shadow-xml-view-comment {\n color: rgb(35, 110, 37);\n}\n\n.shadow-xml-view-processing-instruction {\n color: rgb(35, 110, 37);\n}\n\n.shadow-xml-view-attribute-name {\n color: rgb(153, 69, 0);\n}\n\n.shadow-xml-view-attribute-value {\n color: rgb(26, 26, 166);\n}\n\n.shadow-xml-view-text {\n color: rgb(0, 0, 0);\n white-space: pre;\n}\n\n.shadow-xml-view-cdata {\n color: rgb(0, 0, 0);\n}\n\n/*# sourceURL=network/xmlView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.ProfileType=function(id,name) {WebInspector.Object.call(this);this._id=id;this._name=name;this._profiles=[];this._profileBeingRecorded=null;this._nextProfileUid=1;if(!window.opener) window.addEventListener("unload",this._clearTempStorage.bind(this),false);} WebInspector.ProfileType.Events={AddProfileHeader:"add-profile-header",ProfileComplete:"profile-complete",RemoveProfileHeader:"remove-profile-header",ViewUpdated:"view-updated"} WebInspector.ProfileType.prototype={typeName:function() {return"";},nextProfileUid:function() {return this._nextProfileUid;},hasTemporaryView:function() {return false;},fileExtension:function() {return null;},toolbarItems:function() {return[];},get buttonTooltip() {return"";},get id() {return this._id;},get treeItemTitle() {return this._name;},get name() {return this._name;},buttonClicked:function() {return false;},get description() {return"";},isInstantProfile:function() {return false;},isEnabled:function() {return true;},getProfiles:function() {function isFinished(profile) {return this._profileBeingRecorded!==profile;} return this._profiles.filter(isFinished.bind(this));},decorationElement:function() {return null;},getProfile:function(uid) {for(var i=0;i<this._profiles.length;++i){if(this._profiles[i].uid===uid) return this._profiles[i];} return null;},loadFromFile:function(file) {var name=file.name;var fileExtension=this.fileExtension();if(fileExtension&&name.endsWith(fileExtension)) name=name.substr(0,name.length-fileExtension.length);var profile=this.createProfileLoadedFromFile(name);profile.setFromFile();this.setProfileBeingRecorded(profile);this.addProfile(profile);profile.loadFromFile(file);},createProfileLoadedFromFile:function(title) {throw new Error("Needs implemented.");},addProfile:function(profile) {this._profiles.push(profile);this.dispatchEventToListeners(WebInspector.ProfileType.Events.AddProfileHeader,profile);},removeProfile:function(profile) {var index=this._profiles.indexOf(profile);if(index===-1) return;this._profiles.splice(index,1);this._disposeProfile(profile);},_clearTempStorage:function() {for(var i=0;i<this._profiles.length;++i) this._profiles[i].removeTempFile();},profileBeingRecorded:function() {return this._profileBeingRecorded;},setProfileBeingRecorded:function(profile) {this._profileBeingRecorded=profile;},profileBeingRecordedRemoved:function() {},_reset:function() {var profiles=this._profiles.slice(0);for(var i=0;i<profiles.length;++i) this._disposeProfile(profiles[i]);this._profiles=[];this._nextProfileUid=1;},_disposeProfile:function(profile) {this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProfileHeader,profile);profile.dispose();if(this._profileBeingRecorded===profile){this.profileBeingRecordedRemoved();this.setProfileBeingRecorded(null);}},__proto__:WebInspector.Object.prototype} WebInspector.ProfileType.DataDisplayDelegate=function() {} WebInspector.ProfileType.DataDisplayDelegate.prototype={showProfile:function(profile){},showObject:function(snapshotObjectId,perspectiveName){}} WebInspector.ProfileHeader=function(target,profileType,title) {this._target=target;this._profileType=profileType;this.title=title;this.uid=profileType._nextProfileUid++;this._fromFile=false;} WebInspector.ProfileHeader.StatusUpdate=function(subtitle,wait) {this.subtitle=subtitle;this.wait=wait;} WebInspector.ProfileHeader.Events={UpdateStatus:"UpdateStatus",ProfileReceived:"ProfileReceived"} WebInspector.ProfileHeader.prototype={target:function() {return this._target;},profileType:function() {return this._profileType;},updateStatus:function(subtitle,wait) {this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.UpdateStatus,new WebInspector.ProfileHeader.StatusUpdate(subtitle,wait));},createSidebarTreeElement:function(dataDisplayDelegate) {throw new Error("Needs implemented.");},createView:function(dataDisplayDelegate) {throw new Error("Not implemented.");},removeTempFile:function() {if(this._tempFile) this._tempFile.remove();},dispose:function() {},canSaveToFile:function() {return false;},saveToFile:function() {throw new Error("Needs implemented");},loadFromFile:function(file) {throw new Error("Needs implemented");},fromFile:function() {return this._fromFile;},setFromFile:function() {this._fromFile=true;},__proto__:WebInspector.Object.prototype} WebInspector.ProfilesPanel=function() {WebInspector.PanelWithSidebar.call(this,"profiles");this.registerRequiredCSS("ui/panelEnablerView.css");this.registerRequiredCSS("profiler/heapProfiler.css");this.registerRequiredCSS("profiler/profilesPanel.css");this.registerRequiredCSS("components/objectValue.css");var mainContainer=new WebInspector.VBox();this.splitWidget().setMainWidget(mainContainer);this.profilesItemTreeElement=new WebInspector.ProfilesSidebarTreeElement(this);this._sidebarTree=new TreeOutline();this._sidebarTree.element.classList.add("sidebar-tree");this.panelSidebarElement().appendChild(this._sidebarTree.element);this.setDefaultFocusedElement(this._sidebarTree.element);this._sidebarTree.appendChild(this.profilesItemTreeElement);this.profileViews=createElement("div");this.profileViews.id="profile-views";this.profileViews.classList.add("vbox");mainContainer.element.appendChild(this.profileViews);this._toolbarElement=createElementWithClass("div","profiles-toolbar");mainContainer.element.insertBefore(this._toolbarElement,mainContainer.element.firstChild);this.panelSidebarElement().classList.add("profiles-sidebar-tree-box");var toolbarContainerLeft=createElementWithClass("div","profiles-toolbar");this.panelSidebarElement().insertBefore(toolbarContainerLeft,this.panelSidebarElement().firstChild);var toolbar=new WebInspector.Toolbar("",toolbarContainerLeft);this._toggleRecordAction=(WebInspector.actionRegistry.action("profiler.toggle-recording"));this._toggleRecordButton=WebInspector.Toolbar.createActionButton(this._toggleRecordAction);toolbar.appendToolbarItem(this._toggleRecordButton);this.clearResultsButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear all profiles"),"clear-toolbar-item");this.clearResultsButton.addEventListener("click",this._reset,this);toolbar.appendToolbarItem(this.clearResultsButton);this._profileTypeToolbar=new WebInspector.Toolbar("",this._toolbarElement);this._profileViewToolbar=new WebInspector.Toolbar("",this._toolbarElement);this._profileGroups={};this._launcherView=new WebInspector.MultiProfileLauncherView(this);this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected,this._onProfileTypeSelected,this);this._profileToView=[];this._typeIdToSidebarSection={};var types=WebInspector.ProfileTypeRegistry.instance.profileTypes();for(var i=0;i<types.length;i++) this._registerProfileType(types[i]);this._launcherView.restoreSelectedProfileType();this.profilesItemTreeElement.select();this._showLauncherView();this._createFileSelectorElement();this.element.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);this.contentElement.addEventListener("keydown",this._onKeyDown.bind(this),false);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged,this);} WebInspector.ProfilesPanel.prototype={_onKeyDown:function(event) {var handled=false;if(event.keyIdentifier==="Down"&&!event.altKey) handled=this._sidebarTree.selectNext();else if(event.keyIdentifier==="Up"&&!event.altKey) handled=this._sidebarTree.selectPrevious();if(handled) event.consume(true);},searchableView:function() {return this.visibleView&&this.visibleView.searchableView?this.visibleView.searchableView():null;},_createFileSelectorElement:function() {if(this._fileSelectorElement) this.element.removeChild(this._fileSelectorElement);this._fileSelectorElement=WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));this.element.appendChild(this._fileSelectorElement);},_findProfileTypeByExtension:function(fileName) {var types=WebInspector.ProfileTypeRegistry.instance.profileTypes();for(var i=0;i<types.length;i++){var type=types[i];var extension=type.fileExtension();if(!extension) continue;if(fileName.endsWith(type.fileExtension())) return type;} return null;},_loadFromFile:function(file) {this._createFileSelectorElement();var profileType=this._findProfileTypeByExtension(file.name);if(!profileType){var extensions=[];var types=WebInspector.ProfileTypeRegistry.instance.profileTypes();for(var i=0;i<types.length;i++){var extension=types[i].fileExtension();if(!extension||extensions.indexOf(extension)!==-1) continue;extensions.push(extension);} WebInspector.console.error(WebInspector.UIString("Can't load file. Only files with extensions '%s' can be loaded.",extensions.join("', '")));return;} if(!!profileType.profileBeingRecorded()){WebInspector.console.error(WebInspector.UIString("Can't load profile while another profile is recording."));return;} profileType.loadFromFile(file);},toggleRecord:function() {if(!this._toggleRecordAction.enabled()) return true;var type=this._selectedProfileType;var isProfiling=type.buttonClicked();this._updateToggleRecordAction(isProfiling);if(isProfiling){this._launcherView.profileStarted();if(type.hasTemporaryView()) this.showProfile(type.profileBeingRecorded());}else{this._launcherView.profileFinished();} return true;},_onSuspendStateChanged:function() {this._updateToggleRecordAction(this._toggleRecordAction.toggled());},_updateToggleRecordAction:function(toggled) {var enable=toggled||!WebInspector.targetManager.allTargetsSuspended();this._toggleRecordAction.setEnabled(enable);this._toggleRecordAction.setToggled(toggled);if(enable) this._toggleRecordButton.setTitle(this._selectedProfileType?this._selectedProfileType.buttonTooltip:"");else this._toggleRecordButton.setTitle(WebInspector.anotherProfilerActiveLabel());if(this._selectedProfileType) this._launcherView.updateProfileType(this._selectedProfileType,enable);},_profileBeingRecordedRemoved:function() {this._updateToggleRecordAction(false);this._launcherView.profileFinished();},_onProfileTypeSelected:function(event) {this._selectedProfileType=(event.data);this._updateProfileTypeSpecificUI();},_updateProfileTypeSpecificUI:function() {this._updateToggleRecordAction(this._toggleRecordAction.toggled());this._profileTypeToolbar.removeToolbarItems();var toolbarItems=this._selectedProfileType.toolbarItems();for(var i=0;i<toolbarItems.length;++i) this._profileTypeToolbar.appendToolbarItem(toolbarItems[i]);},_reset:function() {WebInspector.Panel.prototype.reset.call(this);var types=WebInspector.ProfileTypeRegistry.instance.profileTypes();for(var i=0;i<types.length;i++) types[i]._reset();delete this.visibleView;this._profileGroups={};this._updateToggleRecordAction(false);this._launcherView.profileFinished();this._sidebarTree.element.classList.remove("some-expandable");this._launcherView.detach();this.profileViews.removeChildren();this._profileViewToolbar.removeToolbarItems();this.removeAllListeners();this._profileViewToolbar.element.classList.remove("hidden");this.clearResultsButton.element.classList.remove("hidden");this.profilesItemTreeElement.select();this._showLauncherView();},_showLauncherView:function() {this.closeVisibleView();this._profileViewToolbar.removeToolbarItems();this._launcherView.show(this.profileViews);this.visibleView=this._launcherView;},_registerProfileType:function(profileType) {this._launcherView.addProfileType(profileType);var profileTypeSection=new WebInspector.ProfileTypeSidebarSection(this,profileType);this._typeIdToSidebarSection[profileType.id]=profileTypeSection;this._sidebarTree.appendChild(profileTypeSection);profileTypeSection.childrenListElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);function onAddProfileHeader(event) {this._addProfileHeader((event.data));} function onRemoveProfileHeader(event) {this._removeProfileHeader((event.data));} function profileComplete(event) {this.showProfile((event.data));} profileType.addEventListener(WebInspector.ProfileType.Events.ViewUpdated,this._updateProfileTypeSpecificUI,this);profileType.addEventListener(WebInspector.ProfileType.Events.AddProfileHeader,onAddProfileHeader,this);profileType.addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader,onRemoveProfileHeader,this);profileType.addEventListener(WebInspector.ProfileType.Events.ProfileComplete,profileComplete,this);var profiles=profileType.getProfiles();for(var i=0;i<profiles.length;i++) this._addProfileHeader(profiles[i]);},_handleContextMenuEvent:function(event) {var element=event.srcElement;while(element&&!element.treeElement&&element!==this.element) element=element.parentElement;if(!element) return;if(element.treeElement&&element.treeElement.handleContextMenuEvent){element.treeElement.handleContextMenuEvent(event,this);return;} var contextMenu=new WebInspector.ContextMenu(event);if(this.visibleView instanceof WebInspector.HeapSnapshotView){this.visibleView.populateContextMenu(contextMenu,event);} if(element!==this.element||event.srcElement===this.panelSidebarElement()){contextMenu.appendItem(WebInspector.UIString("Load\u2026"),this._fileSelectorElement.click.bind(this._fileSelectorElement));} contextMenu.show();},showLoadFromFileDialog:function() {this._fileSelectorElement.click();},_addProfileHeader:function(profile) {var profileType=profile.profileType();var typeId=profileType.id;this._typeIdToSidebarSection[typeId].addProfileHeader(profile);if(!this.visibleView||this.visibleView===this._launcherView) this.showProfile(profile);},_removeProfileHeader:function(profile) {if(profile.profileType()._profileBeingRecorded===profile) this._profileBeingRecordedRemoved();var i=this._indexOfViewForProfile(profile);if(i!==-1) this._profileToView.splice(i,1);var profileType=profile.profileType();var typeId=profileType.id;var sectionIsEmpty=this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);if(sectionIsEmpty){this.profilesItemTreeElement.select();this._showLauncherView();}},showProfile:function(profile) {if(!profile||(profile.profileType().profileBeingRecorded()===profile)&&!profile.profileType().hasTemporaryView()) return null;var view=this._viewForProfile(profile);if(view===this.visibleView) return view;this.closeVisibleView();view.show(this.profileViews);view.focus();this.visibleView=view;var profileTypeSection=this._typeIdToSidebarSection[profile.profileType().id];var sidebarElement=profileTypeSection.sidebarElementForProfile(profile);sidebarElement.revealAndSelect();this._profileViewToolbar.removeToolbarItems();var toolbarItems=view.toolbarItems();for(var i=0;i<toolbarItems.length;++i) this._profileViewToolbar.appendToolbarItem(toolbarItems[i]);return view;},showObject:function(snapshotObjectId,perspectiveName) {var heapProfiles=WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();for(var i=0;i<heapProfiles.length;i++){var profile=heapProfiles[i];if(profile.maxJSObjectId>=snapshotObjectId){this.showProfile(profile);var view=this._viewForProfile(profile);view.selectLiveObject(perspectiveName,snapshotObjectId);break;}}},_viewForProfile:function(profile) {var index=this._indexOfViewForProfile(profile);if(index!==-1) return this._profileToView[index].view;var view=profile.createView(this);view.element.classList.add("profile-view");this._profileToView.push({profile:profile,view:view});return view;},_indexOfViewForProfile:function(profile) {for(var i=0;i<this._profileToView.length;i++){if(this._profileToView[i].profile===profile) return i;} return-1;},closeVisibleView:function() {if(this.visibleView) this.visibleView.detach();delete this.visibleView;},appendApplicableItems:function(event,contextMenu,target) {if(!(target instanceof WebInspector.RemoteObject)) return;if(WebInspector.inspectorView.currentPanel()!==this) return;var object=(target);var objectId=object.objectId;if(!objectId) return;var heapProfiles=WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();if(!heapProfiles.length) return;function revealInView(viewName) {object.target().heapProfilerAgent().getHeapObjectId(objectId,didReceiveHeapObjectId.bind(this,viewName));} function didReceiveHeapObjectId(viewName,error,result) {if(WebInspector.inspectorView.currentPanel()!==this) return;if(!error) this.showObject(result,viewName);} contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Summary ^view"),revealInView.bind(this,"Summary"));},wasShown:function() {WebInspector.context.setFlavor(WebInspector.ProfilesPanel,this);},willHide:function() {WebInspector.context.setFlavor(WebInspector.ProfilesPanel,null);},__proto__:WebInspector.PanelWithSidebar.prototype} WebInspector.ProfileTypeSidebarSection=function(dataDisplayDelegate,profileType) {WebInspector.SidebarSectionTreeElement.call(this,profileType.treeItemTitle);this._dataDisplayDelegate=dataDisplayDelegate;this._profileTreeElements=[];this._profileGroups={};this.hidden=true;} WebInspector.ProfileTypeSidebarSection.ProfileGroup=function() {this.profileSidebarTreeElements=[];this.sidebarTreeElement=null;} WebInspector.ProfileTypeSidebarSection.prototype={addProfileHeader:function(profile) {this.hidden=false;var profileType=profile.profileType();var sidebarParent=this;var profileTreeElement=profile.createSidebarTreeElement(this._dataDisplayDelegate);this._profileTreeElements.push(profileTreeElement);if(!profile.fromFile()&&profileType.profileBeingRecorded()!==profile){var profileTitle=profile.title;var group=this._profileGroups[profileTitle];if(!group){group=new WebInspector.ProfileTypeSidebarSection.ProfileGroup();this._profileGroups[profileTitle]=group;} group.profileSidebarTreeElements.push(profileTreeElement);var groupSize=group.profileSidebarTreeElements.length;if(groupSize===2){group.sidebarTreeElement=new WebInspector.ProfileGroupSidebarTreeElement(this._dataDisplayDelegate,profile.title);var firstProfileTreeElement=group.profileSidebarTreeElements[0];var index=this.children().indexOf(firstProfileTreeElement);this.insertChild(group.sidebarTreeElement,index);var selected=firstProfileTreeElement.selected;this.removeChild(firstProfileTreeElement);group.sidebarTreeElement.appendChild(firstProfileTreeElement);if(selected) firstProfileTreeElement.revealAndSelect();firstProfileTreeElement.small=true;firstProfileTreeElement.mainTitle=WebInspector.UIString("Run %d",1);this.treeOutline.element.classList.add("some-expandable");} if(groupSize>=2){sidebarParent=group.sidebarTreeElement;profileTreeElement.small=true;profileTreeElement.mainTitle=WebInspector.UIString("Run %d",groupSize);}} sidebarParent.appendChild(profileTreeElement);},removeProfileHeader:function(profile) {var index=this._sidebarElementIndex(profile);if(index===-1) return false;var profileTreeElement=this._profileTreeElements[index];this._profileTreeElements.splice(index,1);var sidebarParent=this;var group=this._profileGroups[profile.title];if(group){var groupElements=group.profileSidebarTreeElements;groupElements.splice(groupElements.indexOf(profileTreeElement),1);if(groupElements.length===1){var pos=sidebarParent.children().indexOf(group.sidebarTreeElement);group.sidebarTreeElement.removeChild(groupElements[0]);this.insertChild(groupElements[0],pos);groupElements[0].small=false;groupElements[0].mainTitle=group.sidebarTreeElement.title;this.removeChild(group.sidebarTreeElement);} if(groupElements.length!==0) sidebarParent=group.sidebarTreeElement;} sidebarParent.removeChild(profileTreeElement);profileTreeElement.dispose();if(this.childCount()) return false;this.hidden=true;return true;},sidebarElementForProfile:function(profile) {var index=this._sidebarElementIndex(profile);return index===-1?null:this._profileTreeElements[index];},_sidebarElementIndex:function(profile) {var elements=this._profileTreeElements;for(var i=0;i<elements.length;i++){if(elements[i].profile===profile) return i;} return-1;},__proto__:WebInspector.SidebarSectionTreeElement.prototype} WebInspector.ProfilesPanel.ContextMenuProvider=function() {} WebInspector.ProfilesPanel.ContextMenuProvider.prototype={appendApplicableItems:function(event,contextMenu,target) {WebInspector.ProfilesPanel._instance().appendApplicableItems(event,contextMenu,target);}} WebInspector.ProfileSidebarTreeElement=function(dataDisplayDelegate,profile,className) {this._dataDisplayDelegate=dataDisplayDelegate;this.profile=profile;WebInspector.SidebarTreeElement.call(this,className,profile.title);this.refreshTitles();profile.addEventListener(WebInspector.ProfileHeader.Events.UpdateStatus,this._updateStatus,this);if(profile.canSaveToFile()) this._createSaveLink();else profile.addEventListener(WebInspector.ProfileHeader.Events.ProfileReceived,this._onProfileReceived,this);} WebInspector.ProfileSidebarTreeElement.prototype={_createSaveLink:function() {this._saveLinkElement=this.titleContainer.createChild("span","save-link");this._saveLinkElement.textContent=WebInspector.UIString("Save");this._saveLinkElement.addEventListener("click",this._saveProfile.bind(this),false);},_onProfileReceived:function(event) {this._createSaveLink();},_updateStatus:function(event) {var statusUpdate=event.data;if(statusUpdate.subtitle!==null) this.subtitle=statusUpdate.subtitle;if(typeof statusUpdate.wait==="boolean") this.wait=statusUpdate.wait;this.refreshTitles();},dispose:function() {this.profile.removeEventListener(WebInspector.ProfileHeader.Events.UpdateStatus,this._updateStatus,this);this.profile.removeEventListener(WebInspector.ProfileHeader.Events.ProfileReceived,this._onProfileReceived,this);},onselect:function() {this._dataDisplayDelegate.showProfile(this.profile);return true;},ondelete:function() {this.profile.profileType().removeProfile(this.profile);return true;},handleContextMenuEvent:function(event,panel) {var profile=this.profile;var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Load\u2026"),panel._fileSelectorElement.click.bind(panel._fileSelectorElement));if(profile.canSaveToFile()) contextMenu.appendItem(WebInspector.UIString("Save\u2026"),profile.saveToFile.bind(profile));contextMenu.appendItem(WebInspector.UIString("Delete"),this.ondelete.bind(this));contextMenu.show();},_saveProfile:function(event) {this.profile.saveToFile();},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.ProfileGroupSidebarTreeElement=function(dataDisplayDelegate,title,subtitle) {WebInspector.SidebarTreeElement.call(this,"profile-group-sidebar-tree-item",title,subtitle,true);this._dataDisplayDelegate=dataDisplayDelegate;} WebInspector.ProfileGroupSidebarTreeElement.prototype={onselect:function() {var hasChildren=this.childCount()>0;if(hasChildren) this._dataDisplayDelegate.showProfile(this.lastChild().profile);return hasChildren;},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.ProfilesSidebarTreeElement=function(panel) {this._panel=panel;this.small=false;WebInspector.SidebarTreeElement.call(this,"profile-launcher-view-tree-item",WebInspector.UIString("Profiles"));} WebInspector.ProfilesSidebarTreeElement.prototype={onselect:function() {this._panel._showLauncherView();return true;},get selectable() {return true;},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.ProfilesPanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.ProfilesPanel._instance());} WebInspector.ProfilesPanel._instance=function() {if(!WebInspector.ProfilesPanel._instanceObject) WebInspector.ProfilesPanel._instanceObject=new WebInspector.ProfilesPanel();return WebInspector.ProfilesPanel._instanceObject;} WebInspector.ProfilesPanelFactory=function() {} WebInspector.ProfilesPanelFactory.prototype={createPanel:function() {return WebInspector.ProfilesPanel._instance();}} WebInspector.ProfilesPanel.RecordActionDelegate=function() {} WebInspector.ProfilesPanel.RecordActionDelegate.prototype={handleAction:function(context,actionId) {var panel=WebInspector.context.flavor(WebInspector.ProfilesPanel);console.assert(panel&&panel instanceof WebInspector.ProfilesPanel);panel.toggleRecord();return true;}};WebInspector.ProfileView=function(nodeFormatter,viewTypes) {WebInspector.VBox.call(this);this._searchableView=new WebInspector.SearchableView(this);this._searchableView.setPlaceholder(WebInspector.UIString("Find by cost (>50ms), name or file"));this._searchableView.show(this.element);viewTypes=viewTypes||[WebInspector.ProfileView.ViewTypes.Flame,WebInspector.ProfileView.ViewTypes.Heavy,WebInspector.ProfileView.ViewTypes.Tree];this._viewType=WebInspector.settings.createSetting("profileView",WebInspector.ProfileView.ViewTypes.Heavy);this._nodeFormatter=nodeFormatter;var columns=[];columns.push({id:"self",title:this.columnHeader("self"),width:"120px",sort:WebInspector.DataGrid.Order.Descending,sortable:true});columns.push({id:"total",title:this.columnHeader("total"),width:"120px",sortable:true});columns.push({id:"function",title:WebInspector.UIString("Function"),disclosure:true,sortable:true});this.dataGrid=new WebInspector.DataGrid(columns);this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortProfile,this);this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._nodeSelected.bind(this,true));this.dataGrid.addEventListener(WebInspector.DataGrid.Events.DeselectedNode,this._nodeSelected.bind(this,false));this.viewSelectComboBox=new WebInspector.ToolbarComboBox(this._changeView.bind(this));var optionNames=new Map([[WebInspector.ProfileView.ViewTypes.Flame,WebInspector.UIString("Chart")],[WebInspector.ProfileView.ViewTypes.Heavy,WebInspector.UIString("Heavy (Bottom Up)")],[WebInspector.ProfileView.ViewTypes.Tree,WebInspector.UIString("Tree (Top Down)")],]);var options=new Map(viewTypes.map(type=>[type,this.viewSelectComboBox.createOption(optionNames.get(type),"",type)]));var optionName=this._viewType.get()||viewTypes[0];var option=options.get(optionName)||options.get(viewTypes[0]);this.viewSelectComboBox.select(option);this.focusButton=new WebInspector.ToolbarButton(WebInspector.UIString("Focus selected function"),"visibility-toolbar-item");this.focusButton.setEnabled(false);this.focusButton.addEventListener("click",this._focusClicked,this);this.excludeButton=new WebInspector.ToolbarButton(WebInspector.UIString("Exclude selected function"),"delete-toolbar-item");this.excludeButton.setEnabled(false);this.excludeButton.addEventListener("click",this._excludeClicked,this);this.resetButton=new WebInspector.ToolbarButton(WebInspector.UIString("Restore all functions"),"refresh-toolbar-item");this.resetButton.setEnabled(false);this.resetButton.addEventListener("click",this._resetClicked,this);this._linkifier=new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultFormatter(30));this._changeView();if(this._flameChart) this._flameChart.update();} WebInspector.ProfileView.ViewTypes={Flame:"Flame",Tree:"Tree",Heavy:"Heavy"} WebInspector.ProfileView.prototype={focus:function() {if(this._flameChart) this._flameChart.focus();else WebInspector.Widget.prototype.focus.call(this);},columnHeader:function(columnId) {throw"Not implemented";},target:function() {return this._profileHeader.target();},selectRange:function(timeLeft,timeRight) {if(!this._flameChart) return;this._flameChart.selectRange(timeLeft,timeRight);},toolbarItems:function() {return[this.viewSelectComboBox,this.focusButton,this.excludeButton,this.resetButton];},_getBottomUpProfileDataGridTree:function() {if(!this._bottomUpProfileDataGridTree) this._bottomUpProfileDataGridTree=new WebInspector.BottomUpProfileDataGridTree(this._nodeFormatter,this._searchableView,this.profile.root,this.adjustedTotal);return this._bottomUpProfileDataGridTree;},_getTopDownProfileDataGridTree:function() {if(!this._topDownProfileDataGridTree) this._topDownProfileDataGridTree=new WebInspector.TopDownProfileDataGridTree(this._nodeFormatter,this._searchableView,this.profile.root,this.adjustedTotal);return this._topDownProfileDataGridTree;},willHide:function() {this._currentSearchResultIndex=-1;},refresh:function() {var selectedProfileNode=this.dataGrid.selectedNode?this.dataGrid.selectedNode.profileNode:null;this.dataGrid.rootNode().removeChildren();var children=this.profileDataGridTree.children;var count=children.length;for(var index=0;index<count;++index) this.dataGrid.rootNode().appendChild(children[index]);if(selectedProfileNode) selectedProfileNode.selected=true;},refreshVisibleData:function() {var child=this.dataGrid.rootNode().children[0];while(child){child.refresh();child=child.traverseNextNode(false,null,true);}},searchableView:function() {return this._searchableView;},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return false;},searchCanceled:function() {this._searchableElement.searchCanceled();},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this._searchableElement.performSearch(searchConfig,shouldJump,jumpBackwards);},jumpToNextSearchResult:function() {this._searchableElement.jumpToNextSearchResult();},jumpToPreviousSearchResult:function() {this._searchableElement.jumpToPreviousSearchResult();},linkifier:function() {return this._linkifier;},createFlameChartDataProvider:function() {throw"Not implemented";},_ensureFlameChartCreated:function() {if(this._flameChart) return;this._dataProvider=this.createFlameChartDataProvider();this._flameChart=new WebInspector.CPUProfileFlameChart(this._searchableView,this._dataProvider);this._flameChart.addEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onEntrySelected.bind(this));},_onEntrySelected:function(event) {var entryIndex=event.data;var node=this._dataProvider._entryNodes[entryIndex];var debuggerModel=this._profileHeader._debuggerModel;if(!node||!node.scriptId||!debuggerModel) return;var script=debuggerModel.scriptForId(node.scriptId);if(!script) return;var location=(debuggerModel.createRawLocation(script,node.lineNumber-1,node.columnNumber?node.columnNumber-1:node.columnNumber));WebInspector.Revealer.reveal(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location));},_changeView:function() {if(!this.profile) return;this._searchableView.closeSearch();if(this._visibleView) this._visibleView.detach();this._viewType.set(this.viewSelectComboBox.selectedOption().value);switch(this._viewType.get()){case WebInspector.ProfileView.ViewTypes.Flame:this._ensureFlameChartCreated();this._visibleView=this._flameChart;this._searchableElement=this._flameChart;break;case WebInspector.ProfileView.ViewTypes.Tree:this.profileDataGridTree=this._getTopDownProfileDataGridTree();this._sortProfile();this._visibleView=this.dataGrid.asWidget();this._searchableElement=this.profileDataGridTree;break;case WebInspector.ProfileView.ViewTypes.Heavy:this.profileDataGridTree=this._getBottomUpProfileDataGridTree();this._sortProfile();this._visibleView=this.dataGrid.asWidget();this._searchableElement=this.profileDataGridTree;break;} var isFlame=this._viewType.get()===WebInspector.ProfileView.ViewTypes.Flame;this.focusButton.setVisible(!isFlame);this.excludeButton.setVisible(!isFlame);this.resetButton.setVisible(!isFlame);this._visibleView.show(this._searchableView.element);},_nodeSelected:function(selected) {this.focusButton.setEnabled(selected);this.excludeButton.setEnabled(selected);},_focusClicked:function(event) {if(!this.dataGrid.selectedNode) return;this.resetButton.setEnabled(true);this.profileDataGridTree.focus(this.dataGrid.selectedNode);this.refresh();this.refreshVisibleData();},_excludeClicked:function(event) {var selectedNode=this.dataGrid.selectedNode;if(!selectedNode) return;selectedNode.deselect();this.resetButton.setEnabled(true);this.profileDataGridTree.exclude(selectedNode);this.refresh();this.refreshVisibleData();},_resetClicked:function(event) {this.resetButton.setEnabled(false);this.profileDataGridTree.restore();this._linkifier.reset();this.refresh();this.refreshVisibleData();},_sortProfile:function() {var sortAscending=this.dataGrid.isSortOrderAscending();var sortColumnIdentifier=this.dataGrid.sortColumnIdentifier();var sortProperty=sortColumnIdentifier==="function"?"functionName":sortColumnIdentifier||"";this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyComparator(sortProperty,sortAscending));this.refresh();},__proto__:WebInspector.VBox.prototype} WebInspector.WritableProfileHeader=function(target,type,title) {WebInspector.ProfileHeader.call(this,target,type,title||WebInspector.UIString("Profile %d",type.nextProfileUid()));this._debuggerModel=WebInspector.DebuggerModel.fromTarget(target);this._tempFile=null;} WebInspector.WritableProfileHeader.prototype={onTransferStarted:function() {this._jsonifiedProfile="";this.updateStatus(WebInspector.UIString("Loading\u2026 %s",Number.bytesToString(this._jsonifiedProfile.length)),true);},onChunkTransferred:function(reader) {this.updateStatus(WebInspector.UIString("Loading\u2026 %d%%",Number.bytesToString(this._jsonifiedProfile.length)));},onTransferFinished:function() {this.updateStatus(WebInspector.UIString("Parsing\u2026"),true);this._profile=JSON.parse(this._jsonifiedProfile);this._jsonifiedProfile=null;this.updateStatus(WebInspector.UIString("Loaded"),false);if(this._profileType.profileBeingRecorded()===this) this._profileType.setProfileBeingRecorded(null);},onError:function(reader,e) {var subtitle;switch(e.target.error.code){case e.target.error.NOT_FOUND_ERR:subtitle=WebInspector.UIString("'%s' not found.",reader.fileName());break;case e.target.error.NOT_READABLE_ERR:subtitle=WebInspector.UIString("'%s' is not readable",reader.fileName());break;case e.target.error.ABORT_ERR:return;default:subtitle=WebInspector.UIString("'%s' error %d",reader.fileName(),e.target.error.code);} this.updateStatus(subtitle);},write:function(text) {this._jsonifiedProfile+=text;},close:function(){},dispose:function() {this.removeTempFile();},createSidebarTreeElement:function(panel) {return new WebInspector.ProfileSidebarTreeElement(panel,this,"profile-sidebar-tree-item");},canSaveToFile:function() {return!this.fromFile()&&this._protocolProfile;},saveToFile:function() {var fileOutputStream=new WebInspector.FileOutputStream();function onOpenForSave(accepted) {if(!accepted) return;function didRead(data) {if(data) fileOutputStream.write(data,fileOutputStream.close.bind(fileOutputStream));else fileOutputStream.close();} if(this._failedToCreateTempFile){WebInspector.console.error("Failed to open temp file with heap snapshot");fileOutputStream.close();}else if(this._tempFile){this._tempFile.read(didRead);}else{this._onTempFileReady=onOpenForSave.bind(this,accepted);}} this._fileName=this._fileName||`${this._profileType.typeName()}-${new Date().toISO8601Compact()}${this._profileType.fileExtension()}`;fileOutputStream.open(this._fileName,onOpenForSave.bind(this));},loadFromFile:function(file) {this.updateStatus(WebInspector.UIString("Loading\u2026"),true);var fileReader=new WebInspector.ChunkedFileReader(file,10000000,this);fileReader.start(this);},setProtocolProfile:function(profile) {this._protocolProfile=profile;this._saveProfileDataToTempFile(profile);if(this.canSaveToFile()) this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);},_saveProfileDataToTempFile:function(data) {var serializedData=JSON.stringify(data);function didCreateTempFile(tempFile) {this._writeToTempFile(tempFile,serializedData);} WebInspector.TempFile.create("cpu-profiler",String(this.uid)).then(didCreateTempFile.bind(this));},_writeToTempFile:function(tempFile,serializedData) {this._tempFile=tempFile;if(!tempFile){this._failedToCreateTempFile=true;this._notifyTempFileReady();return;} function didWriteToTempFile(fileSize) {if(!fileSize) this._failedToCreateTempFile=true;tempFile.finishWriting();this._notifyTempFileReady();} tempFile.write([serializedData],didWriteToTempFile.bind(this));},_notifyTempFileReady:function() {if(this._onTempFileReady){this._onTempFileReady();this._onTempFileReady=null;}},__proto__:WebInspector.ProfileHeader.prototype};WebInspector.ProfileDataGridNode=function(profileNode,owningTree,hasChildren) {this.profileNode=profileNode;WebInspector.DataGridNode.call(this,null,hasChildren);this.tree=owningTree;this.childrenByCallUID={};this.lastComparator=null;this.callUID=profileNode.callUID;this.self=profileNode.self;this.total=profileNode.total;this.functionName=WebInspector.beautifyFunctionName(profileNode.functionName);this._deoptReason=profileNode.deoptReason&&profileNode.deoptReason!=="no reason"?profileNode.deoptReason:"";this.url=profileNode.url;} WebInspector.ProfileDataGridNode.prototype={createCell:function(columnId) {var cell;switch(columnId){case"self":cell=this._createValueCell(this.self,this.selfPercent);cell.classList.toggle("highlight",this._searchMatchedSelfColumn);break;case"total":cell=this._createValueCell(this.total,this.totalPercent);cell.classList.toggle("highlight",this._searchMatchedTotalColumn);break;case"function":cell=this.createTD(columnId);cell.classList.toggle("highlight",this._searchMatchedFunctionColumn);if(this._deoptReason){cell.classList.add("not-optimized");cell.createChild("span","profile-warn-marker").title=WebInspector.UIString("Not optimized: %s",this._deoptReason);} cell.createTextChild(this.functionName);if(this.profileNode.scriptId==="0") break;var urlElement=this.tree._formatter.linkifyNode(this);urlElement.style.maxWidth="75%";cell.appendChild(urlElement);break;default:cell=WebInspector.DataGridNode.prototype.createCell.call(this,columnId);break;} return cell;},_createValueCell:function(value,percent) {var cell=createElementWithClass("td","numeric-column");var div=cell.createChild("div","profile-multiple-values");div.createChild("span").textContent=this.tree._formatter.formatValue(value,this);div.createChild("span","percent-column").textContent=this.tree._formatter.formatPercent(percent,this);return cell;},sort:function(comparator,force) {var gridNodeGroups=[[this]];for(var gridNodeGroupIndex=0;gridNodeGroupIndex<gridNodeGroups.length;++gridNodeGroupIndex){var gridNodes=gridNodeGroups[gridNodeGroupIndex];var count=gridNodes.length;for(var index=0;index<count;++index){var gridNode=gridNodes[index];if(!force&&(!gridNode.expanded||gridNode.lastComparator===comparator)){if(gridNode.children.length) gridNode.shouldRefreshChildren=true;continue;} gridNode.lastComparator=comparator;var children=gridNode.children;var childCount=children.length;if(childCount){children.sort(comparator);for(var childIndex=0;childIndex<childCount;++childIndex) children[childIndex].recalculateSiblings(childIndex);gridNodeGroups.push(children);}}}},insertChild:function(profileDataGridNode,index) {WebInspector.DataGridNode.prototype.insertChild.call(this,profileDataGridNode,index);this.childrenByCallUID[profileDataGridNode.callUID]=(profileDataGridNode);},removeChild:function(profileDataGridNode) {WebInspector.DataGridNode.prototype.removeChild.call(this,profileDataGridNode);delete this.childrenByCallUID[(profileDataGridNode).callUID];},removeChildren:function() {WebInspector.DataGridNode.prototype.removeChildren.call(this);this.childrenByCallUID={};},findChild:function(node) {if(!node) return null;return this.childrenByCallUID[node.callUID];},get selfPercent() {return this.self/this.tree.total*100.0;},get totalPercent() {return this.total/this.tree.total*100.0;},populate:function() {WebInspector.ProfileDataGridNode.populate(this);},populateChildren:function() {},save:function() {if(this._savedChildren) return;this._savedSelf=this.self;this._savedTotal=this.total;this._savedChildren=this.children.slice();},restore:function() {if(!this._savedChildren) return;this.self=this._savedSelf;this.total=this._savedTotal;this.removeChildren();var children=this._savedChildren;var count=children.length;for(var index=0;index<count;++index){children[index].restore();this.appendChild(children[index]);}},merge:function(child,shouldAbsorb) {WebInspector.ProfileDataGridNode.merge(this,child,shouldAbsorb);},__proto__:WebInspector.DataGridNode.prototype} WebInspector.ProfileDataGridNode.merge=function(container,child,shouldAbsorb) {container.self+=child.self;if(!shouldAbsorb) container.total+=child.total;var children=container.children.slice();container.removeChildren();var count=children.length;for(var index=0;index<count;++index){if(!shouldAbsorb||children[index]!==child) container.appendChild(children[index]);} children=child.children.slice();count=children.length;for(var index=0;index<count;++index){var orphanedChild=children[index];var existingChild=container.childrenByCallUID[orphanedChild.callUID];if(existingChild) existingChild.merge(orphanedChild,false);else container.appendChild(orphanedChild);}} WebInspector.ProfileDataGridNode.populate=function(container) {if(container._populated) return;container._populated=true;container.populateChildren();var currentComparator=container.tree.lastComparator;if(currentComparator) container.sort(currentComparator,true);} WebInspector.ProfileDataGridTree=function(formatter,searchableView,total) {this.tree=this;this.children=[];this._formatter=formatter;this._searchableView=searchableView;this.total=total;this.lastComparator=null;this.childrenByCallUID={};} WebInspector.ProfileDataGridTree.prototype={get expanded() {return true;},appendChild:function(child) {this.insertChild(child,this.children.length);},insertChild:function(child,index) {this.children.splice(index,0,child);this.childrenByCallUID[child.callUID]=child;},removeChildren:function() {this.children=[];this.childrenByCallUID={};},populateChildren:function() {},findChild:WebInspector.ProfileDataGridNode.prototype.findChild,sort:WebInspector.ProfileDataGridNode.prototype.sort,save:function() {if(this._savedChildren) return;this._savedTotal=this.total;this._savedChildren=this.children.slice();},restore:function() {if(!this._savedChildren) return;this.children=this._savedChildren;this.total=this._savedTotal;var children=this.children;var count=children.length;for(var index=0;index<count;++index) children[index].restore();this._savedChildren=null;},_matchFunction:function(searchConfig) {var query=searchConfig.query.trim();if(!query.length) return null;var greaterThan=(query.startsWith(">"));var lessThan=(query.startsWith("<"));var equalTo=(query.startsWith("=")||((greaterThan||lessThan)&&query.indexOf("=")===1));var percentUnits=(query.endsWith("%"));var millisecondsUnits=(query.length>2&&query.endsWith("ms"));var secondsUnits=(!millisecondsUnits&&query.endsWith("s"));var queryNumber=parseFloat(query);if(greaterThan||lessThan||equalTo){if(equalTo&&(greaterThan||lessThan)) queryNumber=parseFloat(query.substring(2));else queryNumber=parseFloat(query.substring(1));} var queryNumberMilliseconds=(secondsUnits?(queryNumber*1000):queryNumber);if(!isNaN(queryNumber)&&!(greaterThan||lessThan)) equalTo=true;var matcher=createPlainTextSearchRegex(query,"i");function matchesQuery(profileDataGridNode) {delete profileDataGridNode._searchMatchedSelfColumn;delete profileDataGridNode._searchMatchedTotalColumn;delete profileDataGridNode._searchMatchedFunctionColumn;if(percentUnits){if(lessThan){if(profileDataGridNode.selfPercent<queryNumber) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.totalPercent<queryNumber) profileDataGridNode._searchMatchedTotalColumn=true;}else if(greaterThan){if(profileDataGridNode.selfPercent>queryNumber) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.totalPercent>queryNumber) profileDataGridNode._searchMatchedTotalColumn=true;} if(equalTo){if(profileDataGridNode.selfPercent==queryNumber) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.totalPercent==queryNumber) profileDataGridNode._searchMatchedTotalColumn=true;}}else if(millisecondsUnits||secondsUnits){if(lessThan){if(profileDataGridNode.self<queryNumberMilliseconds) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.total<queryNumberMilliseconds) profileDataGridNode._searchMatchedTotalColumn=true;}else if(greaterThan){if(profileDataGridNode.self>queryNumberMilliseconds) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.total>queryNumberMilliseconds) profileDataGridNode._searchMatchedTotalColumn=true;} if(equalTo){if(profileDataGridNode.self==queryNumberMilliseconds) profileDataGridNode._searchMatchedSelfColumn=true;if(profileDataGridNode.total==queryNumberMilliseconds) profileDataGridNode._searchMatchedTotalColumn=true;}} if(profileDataGridNode.functionName.match(matcher)||(profileDataGridNode.url&&profileDataGridNode.url.match(matcher))) profileDataGridNode._searchMatchedFunctionColumn=true;if(profileDataGridNode._searchMatchedSelfColumn||profileDataGridNode._searchMatchedTotalColumn||profileDataGridNode._searchMatchedFunctionColumn){profileDataGridNode.refresh();return true;} return false;} return matchesQuery;},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this.searchCanceled();var matchesQuery=this._matchFunction(searchConfig);if(!matchesQuery) return;this._searchResults=[];for(var current=this.children[0];current;current=current.traverseNextNode(false,null,false)){if(matchesQuery(current)) this._searchResults.push({profileNode:current});} this._searchResultIndex=jumpBackwards?0:this._searchResults.length-1;this._searchableView.updateSearchMatchesCount(this._searchResults.length);this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);},searchCanceled:function() {if(this._searchResults){for(var i=0;i<this._searchResults.length;++i){var profileNode=this._searchResults[i].profileNode;delete profileNode._searchMatchedSelfColumn;delete profileNode._searchMatchedTotalColumn;delete profileNode._searchMatchedFunctionColumn;profileNode.refresh();}} this._searchResults=[];this._searchResultIndex=-1;},jumpToNextSearchResult:function() {if(!this._searchResults||!this._searchResults.length) return;this._searchResultIndex=(this._searchResultIndex+1)%this._searchResults.length;this._jumpToSearchResult(this._searchResultIndex);},jumpToPreviousSearchResult:function() {if(!this._searchResults||!this._searchResults.length) return;this._searchResultIndex=(this._searchResultIndex-1+this._searchResults.length)%this._searchResults.length;this._jumpToSearchResult(this._searchResultIndex);},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return false;},_jumpToSearchResult:function(index) {var searchResult=this._searchResults[index];if(!searchResult) return;var profileNode=searchResult.profileNode;profileNode.revealAndSelect();this._searchableView.updateCurrentMatchIndex(index);}} WebInspector.ProfileDataGridTree.propertyComparators=[{},{}];WebInspector.ProfileDataGridTree.propertyComparator=function(property,isAscending) {var comparator=WebInspector.ProfileDataGridTree.propertyComparators[(isAscending?1:0)][property];if(!comparator){if(isAscending){comparator=function(lhs,rhs) {if(lhs[property]<rhs[property]) return-1;if(lhs[property]>rhs[property]) return 1;return 0;};}else{comparator=function(lhs,rhs) {if(lhs[property]>rhs[property]) return-1;if(lhs[property]<rhs[property]) return 1;return 0;};} WebInspector.ProfileDataGridTree.propertyComparators[(isAscending?1:0)][property]=comparator;} return comparator;} WebInspector.ProfileDataGridNode.Formatter=function(){} WebInspector.ProfileDataGridNode.Formatter.prototype={formatValue:function(value,node){},formatPercent:function(value,node){},linkifyNode:function(node){}};WebInspector.BottomUpProfileDataGridNode=function(profileNode,owningTree) {WebInspector.ProfileDataGridNode.call(this,profileNode,owningTree,this._willHaveChildren(profileNode));this._remainingNodeInfos=[];} WebInspector.BottomUpProfileDataGridNode.prototype={_takePropertiesFromProfileDataGridNode:function(profileDataGridNode) {this.save();this.self=profileDataGridNode.self;this.total=profileDataGridNode.total;},_keepOnlyChild:function(child) {this.save();this.removeChildren();this.appendChild(child);},_exclude:function(aCallUID) {if(this._remainingNodeInfos) this.populate();this.save();var children=this.children;var index=this.children.length;while(index--) children[index]._exclude(aCallUID);var child=this.childrenByCallUID[aCallUID];if(child) this.merge(child,true);},restore:function() {WebInspector.ProfileDataGridNode.prototype.restore.call(this);if(!this.children.length) this.hasChildren=this._willHaveChildren(this.profileNode);},merge:function(child,shouldAbsorb) {this.self-=child.self;WebInspector.ProfileDataGridNode.prototype.merge.call(this,child,shouldAbsorb);},populateChildren:function() {WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this);},_willHaveChildren:function(profileNode) {return!!(profileNode.parent&&profileNode.parent.parent);},__proto__:WebInspector.ProfileDataGridNode.prototype} WebInspector.BottomUpProfileDataGridNode._sharedPopulate=function(container) {var remainingNodeInfos=container._remainingNodeInfos;var count=remainingNodeInfos.length;for(var index=0;index<count;++index){var nodeInfo=remainingNodeInfos[index];var ancestor=nodeInfo.ancestor;var focusNode=nodeInfo.focusNode;var child=container.findChild(ancestor);if(child){var totalAccountedFor=nodeInfo.totalAccountedFor;child.self+=focusNode.self;if(!totalAccountedFor) child.total+=focusNode.total;}else{child=new WebInspector.BottomUpProfileDataGridNode(ancestor,(container.tree));if(ancestor!==focusNode){child.self=focusNode.self;child.total=focusNode.total;} container.appendChild(child);} var parent=ancestor.parent;if(parent&&parent.parent){nodeInfo.ancestor=parent;child._remainingNodeInfos.push(nodeInfo);}} delete container._remainingNodeInfos;} WebInspector.BottomUpProfileDataGridTree=function(formatter,searchableView,rootProfileNode,total) {WebInspector.ProfileDataGridTree.call(this,formatter,searchableView,total);var profileNodeUIDs=0;var profileNodeGroups=[[],[rootProfileNode]];var visitedProfileNodesForCallUID={};this._remainingNodeInfos=[];for(var profileNodeGroupIndex=0;profileNodeGroupIndex<profileNodeGroups.length;++profileNodeGroupIndex){var parentProfileNodes=profileNodeGroups[profileNodeGroupIndex];var profileNodes=profileNodeGroups[++profileNodeGroupIndex];var count=profileNodes.length;for(var index=0;index<count;++index){var profileNode=profileNodes[index];if(!profileNode.UID) profileNode.UID=++profileNodeUIDs;if(profileNode.parent){var visitedNodes=visitedProfileNodesForCallUID[profileNode.callUID];var totalAccountedFor=false;if(!visitedNodes){visitedNodes={};visitedProfileNodesForCallUID[profileNode.callUID]=visitedNodes;}else{var parentCount=parentProfileNodes.length;for(var parentIndex=0;parentIndex<parentCount;++parentIndex){if(visitedNodes[parentProfileNodes[parentIndex].UID]){totalAccountedFor=true;break;}}} visitedNodes[profileNode.UID]=true;this._remainingNodeInfos.push({ancestor:profileNode,focusNode:profileNode,totalAccountedFor:totalAccountedFor});} var children=profileNode.children;if(children.length){profileNodeGroups.push(parentProfileNodes.concat([profileNode]));profileNodeGroups.push(children);}}} WebInspector.ProfileDataGridNode.populate(this);return this;} WebInspector.BottomUpProfileDataGridTree.prototype={focus:function(profileDataGridNode) {if(!profileDataGridNode) return;this.save();var currentNode=profileDataGridNode;var focusNode=profileDataGridNode;while(currentNode.parent&&(currentNode instanceof WebInspector.ProfileDataGridNode)){currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);focusNode=currentNode;currentNode=currentNode.parent;if(currentNode instanceof WebInspector.ProfileDataGridNode) currentNode._keepOnlyChild(focusNode);} this.children=[focusNode];this.total=profileDataGridNode.total;},exclude:function(profileDataGridNode) {if(!profileDataGridNode) return;this.save();var excludedCallUID=profileDataGridNode.callUID;var excludedTopLevelChild=this.childrenByCallUID[excludedCallUID];if(excludedTopLevelChild) this.children.remove(excludedTopLevelChild);var children=this.children;var count=children.length;for(var index=0;index<count;++index) children[index]._exclude(excludedCallUID);if(this.lastComparator) this.sort(this.lastComparator,true);},performSearch:function(searchConfig,shouldJump,jumpBackwards) {this.searchCanceled();var matchesQuery=this._matchFunction(searchConfig);if(!matchesQuery) return;this._searchResults=[];for(var current=this.children[0];current;current=current.traverseNextNode(true,null,true)){if(matchesQuery(current)) this._searchResults.push({profileNode:current});} this._searchResultIndex=jumpBackwards?0:this._searchResults.length-1;this._searchableView.updateSearchMatchesCount(this._searchResults.length);this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);},populateChildren:function() {WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this);},__proto__:WebInspector.ProfileDataGridTree.prototype};WebInspector.TopDownProfileDataGridNode=function(profileNode,owningTree) {var hasChildren=!!(profileNode.children&&profileNode.children.length);WebInspector.ProfileDataGridNode.call(this,profileNode,owningTree,hasChildren);this._remainingChildren=profileNode.children;} WebInspector.TopDownProfileDataGridNode.prototype={populateChildren:function() {WebInspector.TopDownProfileDataGridNode._sharedPopulate(this);},__proto__:WebInspector.ProfileDataGridNode.prototype} WebInspector.TopDownProfileDataGridNode._sharedPopulate=function(container) {var children=container._remainingChildren;var childrenLength=children.length;for(var i=0;i<childrenLength;++i) container.appendChild(new WebInspector.TopDownProfileDataGridNode(children[i],(container.tree)));container._remainingChildren=null;} WebInspector.TopDownProfileDataGridNode._excludeRecursively=function(container,aCallUID) {if(container._remainingChildren) container.populate();container.save();var children=container.children;var index=container.children.length;while(index--) WebInspector.TopDownProfileDataGridNode._excludeRecursively(children[index],aCallUID);var child=container.childrenByCallUID[aCallUID];if(child) WebInspector.ProfileDataGridNode.merge(container,child,true);} WebInspector.TopDownProfileDataGridTree=function(formatter,searchableView,rootProfileNode,total) {WebInspector.ProfileDataGridTree.call(this,formatter,searchableView,total);this._remainingChildren=rootProfileNode.children;WebInspector.ProfileDataGridNode.populate(this);} WebInspector.TopDownProfileDataGridTree.prototype={focus:function(profileDataGridNode) {if(!profileDataGridNode) return;this.save();profileDataGridNode.savePosition();this.children=[profileDataGridNode];this.total=profileDataGridNode.total;},exclude:function(profileDataGridNode) {if(!profileDataGridNode) return;this.save();WebInspector.TopDownProfileDataGridNode._excludeRecursively(this,profileDataGridNode.callUID);if(this.lastComparator) this.sort(this.lastComparator,true);},restore:function() {if(!this._savedChildren) return;this.children[0].restorePosition();WebInspector.ProfileDataGridTree.prototype.restore.call(this);},populateChildren:function() {WebInspector.TopDownProfileDataGridNode._sharedPopulate(this);},__proto__:WebInspector.ProfileDataGridTree.prototype};WebInspector.ProfileFlameChartDataProvider=function(target) {WebInspector.FlameChartDataProvider.call(this);this._target=target;this._colorGenerator=WebInspector.ProfileFlameChartDataProvider.colorGenerator();} WebInspector.ProfileFlameChartDataProvider.prototype={barHeight:function() {return 15;},textBaseline:function() {return 4;},textPadding:function() {return 2;},dividerOffsets:function(startTime,endTime) {return null;},minimumBoundary:function() {return this._cpuProfile.profileStartTime;},totalTime:function() {return this._cpuProfile.profileHead.total;},formatValue:function(value,precision) {return Number.preciseMillisToString(value,precision);},maxStackDepth:function() {return this._maxStackDepth;},timelineData:function() {return this._timelineData||this._calculateTimelineData();},_calculateTimelineData:function() {throw"Not implemented.";},prepareHighlightedEntryInfo:function(entryIndex) {throw"Not implemented.";},canJumpToEntry:function(entryIndex) {return this._entryNodes[entryIndex].scriptId!=="0";},entryTitle:function(entryIndex) {var node=this._entryNodes[entryIndex];return WebInspector.beautifyFunctionName(node.functionName);},entryFont:function(entryIndex) {if(!this._font){this._font=(this.barHeight()-4)+"px "+WebInspector.fontFamily();this._boldFont="bold "+this._font;} var node=this._entryNodes[entryIndex];var reason=node.deoptReason;return(reason&&reason!=="no reason")?this._boldFont:this._font;},entryColor:function(entryIndex) {var node=this._entryNodes[entryIndex];return this._colorGenerator.colorForID(node.url||(node.scriptId!=="0"?node.scriptId:node.functionName));},decorateEntry:function(entryIndex,context,text,barX,barY,barWidth,barHeight) {return false;},forceDecoration:function(entryIndex) {return false;},highlightTimeRange:function(entryIndex) {var startTime=this._timelineData.entryStartTimes[entryIndex];return{startTime:startTime,endTime:startTime+this._timelineData.entryTotalTimes[entryIndex]};},paddingLeft:function() {return 0;},textColor:function(entryIndex) {return"#333";}} WebInspector.ProfileFlameChartDataProvider.colorGenerator=function() {if(!WebInspector.ProfileFlameChartDataProvider._colorGenerator){var colorGenerator=new WebInspector.FlameChart.ColorGenerator({min:30,max:330},{min:50,max:80,count:5},{min:80,max:90,count:3});colorGenerator.setColorForID("(idle)","hsl(0, 0%, 94%)");colorGenerator.setColorForID("(program)","hsl(0, 0%, 80%)");colorGenerator.setColorForID("(garbage collector)","hsl(0, 0%, 80%)");WebInspector.ProfileFlameChartDataProvider._colorGenerator=colorGenerator;} return WebInspector.ProfileFlameChartDataProvider._colorGenerator;} WebInspector.CPUProfileFlameChart=function(searchableView,dataProvider) {WebInspector.VBox.call(this);this.element.id="cpu-flame-chart";this._searchableView=searchableView;this._overviewPane=new WebInspector.CPUProfileFlameChart.OverviewPane(dataProvider);this._overviewPane.show(this.element);this._mainPane=new WebInspector.FlameChart(dataProvider,this._overviewPane);this._mainPane.show(this.element);this._mainPane.addEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onEntrySelected,this);this._overviewPane.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);this._dataProvider=dataProvider;this._searchResults=[];} WebInspector.CPUProfileFlameChart.prototype={focus:function() {this._mainPane.focus();},_onWindowChanged:function(event) {var windowLeft=event.data.windowTimeLeft;var windowRight=event.data.windowTimeRight;this._mainPane.setWindowTimes(windowLeft,windowRight);},selectRange:function(timeLeft,timeRight) {this._overviewPane._selectRange(timeLeft,timeRight);},_onEntrySelected:function(event) {this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected,event.data);},update:function() {this._overviewPane.update();this._mainPane.update();},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var matcher=createPlainTextSearchRegex(searchConfig.query,searchConfig.caseSensitive?"":"i");var selectedEntryIndex=this._searchResultIndex!==-1?this._searchResults[this._searchResultIndex]:-1;this._searchResults=[];var entriesCount=this._dataProvider._entryNodes.length;for(var index=0;index<entriesCount;++index){if(this._dataProvider.entryTitle(index).match(matcher)) this._searchResults.push(index);} if(this._searchResults.length){this._searchResultIndex=this._searchResults.indexOf(selectedEntryIndex);if(this._searchResultIndex===-1) this._searchResultIndex=jumpBackwards?this._searchResults.length-1:0;this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);}else{this.searchCanceled();} this._searchableView.updateSearchMatchesCount(this._searchResults.length);this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);},searchCanceled:function() {this._mainPane.setSelectedEntry(-1);this._searchResults=[];this._searchResultIndex=-1;},jumpToNextSearchResult:function() {this._searchResultIndex=(this._searchResultIndex+1)%this._searchResults.length;this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);},jumpToPreviousSearchResult:function() {this._searchResultIndex=(this._searchResultIndex-1+this._searchResults.length)%this._searchResults.length;this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return false;},__proto__:WebInspector.VBox.prototype};WebInspector.CPUProfileFlameChart.OverviewCalculator=function(dataProvider) {this._dataProvider=dataProvider;} WebInspector.CPUProfileFlameChart.OverviewCalculator.prototype={paddingLeft:function() {return 0;},_updateBoundaries:function(overviewPane) {this._minimumBoundaries=overviewPane._dataProvider.minimumBoundary();var totalTime=overviewPane._dataProvider.totalTime();this._maximumBoundaries=this._minimumBoundaries+totalTime;this._xScaleFactor=overviewPane._overviewContainer.clientWidth/totalTime;},computePosition:function(time) {return(time-this._minimumBoundaries)*this._xScaleFactor;},formatValue:function(value,precision) {return this._dataProvider.formatValue(value-this._minimumBoundaries,precision);},maximumBoundary:function() {return this._maximumBoundaries;},minimumBoundary:function() {return this._minimumBoundaries;},zeroTime:function() {return this._minimumBoundaries;},boundarySpan:function() {return this._maximumBoundaries-this._minimumBoundaries;}} WebInspector.CPUProfileFlameChart.OverviewPane=function(dataProvider) {WebInspector.VBox.call(this);this.element.classList.add("cpu-profile-flame-chart-overview-pane");this._overviewContainer=this.element.createChild("div","cpu-profile-flame-chart-overview-container");this._overviewGrid=new WebInspector.OverviewGrid("cpu-profile-flame-chart");this._overviewGrid.element.classList.add("fill");this._overviewCanvas=this._overviewContainer.createChild("canvas","cpu-profile-flame-chart-overview-canvas");this._overviewContainer.appendChild(this._overviewGrid.element);this._overviewCalculator=new WebInspector.CPUProfileFlameChart.OverviewCalculator(dataProvider);this._dataProvider=dataProvider;this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);} WebInspector.CPUProfileFlameChart.OverviewPane.prototype={requestWindowTimes:function(windowStartTime,windowEndTime) {this._selectRange(windowStartTime,windowEndTime);},updateRangeSelection:function(startTime,endTime) {},_selectRange:function(timeLeft,timeRight) {var startTime=this._dataProvider.minimumBoundary();var totalTime=this._dataProvider.totalTime();this._overviewGrid.setWindow((timeLeft-startTime)/totalTime,(timeRight-startTime)/totalTime);},_onWindowChanged:function(event) {var startTime=this._dataProvider.minimumBoundary();var totalTime=this._dataProvider.totalTime();var data={windowTimeLeft:startTime+this._overviewGrid.windowLeft()*totalTime,windowTimeRight:startTime+this._overviewGrid.windowRight()*totalTime};this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged,data);},_timelineData:function() {return this._dataProvider.timelineData();},onResize:function() {this._scheduleUpdate();},_scheduleUpdate:function() {if(this._updateTimerId) return;this._updateTimerId=this.element.window().requestAnimationFrame(this.update.bind(this));},update:function() {this._updateTimerId=0;var timelineData=this._timelineData();if(!timelineData) return;this._resetCanvas(this._overviewContainer.clientWidth,this._overviewContainer.clientHeight-WebInspector.FlameChart.DividersBarHeight);this._overviewCalculator._updateBoundaries(this);this._overviewGrid.updateDividers(this._overviewCalculator);this._drawOverviewCanvas();},_drawOverviewCanvas:function() {var canvasWidth=this._overviewCanvas.width;var canvasHeight=this._overviewCanvas.height;var drawData=this._calculateDrawData(canvasWidth);var context=this._overviewCanvas.getContext("2d");var ratio=window.devicePixelRatio;var offsetFromBottom=ratio;var lineWidth=1;var yScaleFactor=canvasHeight/(this._dataProvider.maxStackDepth()*1.1);context.lineWidth=lineWidth;context.translate(0.5,0.5);context.strokeStyle="rgba(20,0,0,0.4)";context.fillStyle="rgba(214,225,254,0.8)";context.moveTo(-lineWidth,canvasHeight+lineWidth);context.lineTo(-lineWidth,Math.round(canvasHeight-drawData[0]*yScaleFactor-offsetFromBottom));var value;for(var x=0;x<canvasWidth;++x){value=Math.round(canvasHeight-drawData[x]*yScaleFactor-offsetFromBottom);context.lineTo(x,value);} context.lineTo(canvasWidth+lineWidth,value);context.lineTo(canvasWidth+lineWidth,canvasHeight+lineWidth);context.fill();context.stroke();context.closePath();},_calculateDrawData:function(width) {var dataProvider=this._dataProvider;var timelineData=this._timelineData();var entryStartTimes=timelineData.entryStartTimes;var entryTotalTimes=timelineData.entryTotalTimes;var entryLevels=timelineData.entryLevels;var length=entryStartTimes.length;var minimumBoundary=this._dataProvider.minimumBoundary();var drawData=new Uint8Array(width);var scaleFactor=width/dataProvider.totalTime();for(var entryIndex=0;entryIndex<length;++entryIndex){var start=Math.floor((entryStartTimes[entryIndex]-minimumBoundary)*scaleFactor);var finish=Math.floor((entryStartTimes[entryIndex]-minimumBoundary+entryTotalTimes[entryIndex])*scaleFactor);for(var x=start;x<=finish;++x) drawData[x]=Math.max(drawData[x],entryLevels[entryIndex]+1);} return drawData;},_resetCanvas:function(width,height) {var ratio=window.devicePixelRatio;this._overviewCanvas.width=width*ratio;this._overviewCanvas.height=height*ratio;this._overviewCanvas.style.width=width+"px";this._overviewCanvas.style.height=height+"px";},__proto__:WebInspector.VBox.prototype};WebInspector.CPUProfileView=function(profileHeader) {this._profileHeader=profileHeader;this.profile=new WebInspector.CPUProfileDataModel(profileHeader._profile||profileHeader.protocolProfile());this.adjustedTotal=this.profile.profileHead.total;this.adjustedTotal-=this.profile.idleNode?this.profile.idleNode.total:0;WebInspector.ProfileView.call(this,new WebInspector.CPUProfileView.NodeFormatter(this));} WebInspector.CPUProfileView.prototype={wasShown:function() {WebInspector.ProfileView.prototype.wasShown.call(this);var lineLevelProfile=WebInspector.LineLevelProfile.instance();lineLevelProfile.reset();lineLevelProfile.appendCPUProfile(this.profile);},columnHeader:function(columnId) {switch(columnId){case"self":return WebInspector.UIString("Self Time");case"total":return WebInspector.UIString("Total Time");} return"";},createFlameChartDataProvider:function() {return new WebInspector.CPUFlameChartDataProvider(this.profile,this._profileHeader.target());},__proto__:WebInspector.ProfileView.prototype} WebInspector.CPUProfileType=function() {WebInspector.ProfileType.call(this,WebInspector.CPUProfileType.TypeId,WebInspector.UIString("Record JavaScript CPU Profile"));this._recording=false;this._nextAnonymousConsoleProfileNumber=1;this._anonymousConsoleProfileIdToTitle={};WebInspector.CPUProfileType.instance=this;WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel,WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileStarted,this._consoleProfileStarted,this);WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel,WebInspector.CPUProfilerModel.EventTypes.ConsoleProfileFinished,this._consoleProfileFinished,this);} WebInspector.CPUProfileType.TypeId="CPU";WebInspector.CPUProfileType.prototype={typeName:function() {return"CPU";},fileExtension:function() {return".cpuprofile";},get buttonTooltip() {return this._recording?WebInspector.UIString("Stop CPU profiling"):WebInspector.UIString("Start CPU profiling");},buttonClicked:function() {if(this._recording){this.stopRecordingProfile();return false;}else{this.startRecordingProfile();return true;}},get treeItemTitle() {return WebInspector.UIString("CPU PROFILES");},get description() {return WebInspector.UIString("CPU profiles show where the execution time is spent in your page's JavaScript functions.");},_consoleProfileStarted:function(event) {var data=(event.data);var resolvedTitle=data.title;if(!resolvedTitle){resolvedTitle=WebInspector.UIString("Profile %s",this._nextAnonymousConsoleProfileNumber++);this._anonymousConsoleProfileIdToTitle[data.id]=resolvedTitle;} this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profile,data.scriptLocation,WebInspector.UIString("Profile '%s' started.",resolvedTitle));},_consoleProfileFinished:function(event) {var data=(event.data);var cpuProfile=(data.cpuProfile);var resolvedTitle=data.title;if(typeof resolvedTitle==="undefined"){resolvedTitle=this._anonymousConsoleProfileIdToTitle[data.id];delete this._anonymousConsoleProfileIdToTitle[data.id];} var profile=new WebInspector.CPUProfileHeader(data.scriptLocation.target(),this,resolvedTitle);profile.setProtocolProfile(cpuProfile);this.addProfile(profile);this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.ProfileEnd,data.scriptLocation,WebInspector.UIString("Profile '%s' finished.",resolvedTitle));},_addMessageToConsole:function(type,scriptLocation,messageText) {var script=scriptLocation.script();var target=scriptLocation.target();var message=new WebInspector.ConsoleMessage(target,WebInspector.ConsoleMessage.MessageSource.ConsoleAPI,WebInspector.ConsoleMessage.MessageLevel.Debug,messageText,type,undefined,undefined,undefined,undefined,[{functionName:"",scriptId:scriptLocation.scriptId,url:script?script.contentURL():"",lineNumber:scriptLocation.lineNumber,columnNumber:scriptLocation.columnNumber||0}]);target.consoleModel.addMessage(message);},startRecordingProfile:function() {var target=WebInspector.context.flavor(WebInspector.Target);if(this._profileBeingRecorded||!target) return;var profile=new WebInspector.CPUProfileHeader(target,this);this.setProfileBeingRecorded(profile);WebInspector.targetManager.suspendAllTargets();this.addProfile(profile);profile.updateStatus(WebInspector.UIString("Recording\u2026"));this._recording=true;target.cpuProfilerModel.startRecording();},stopRecordingProfile:function() {this._recording=false;if(!this._profileBeingRecorded||!this._profileBeingRecorded.target()) return;var recordedProfile;function didStopProfiling(profile) {if(!this._profileBeingRecorded) return;console.assert(profile);this._profileBeingRecorded.setProtocolProfile(profile);this._profileBeingRecorded.updateStatus("");recordedProfile=this._profileBeingRecorded;this.setProfileBeingRecorded(null);} function fireEvent() {this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete,recordedProfile);} this._profileBeingRecorded.target().cpuProfilerModel.stopRecording().then(didStopProfiling.bind(this)).then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targetManager)).then(fireEvent.bind(this));},createProfileLoadedFromFile:function(title) {return new WebInspector.CPUProfileHeader(null,this,title);},profileBeingRecordedRemoved:function() {this.stopRecordingProfile();},__proto__:WebInspector.ProfileType.prototype} WebInspector.CPUProfileHeader=function(target,type,title) {WebInspector.WritableProfileHeader.call(this,target,type,title);} WebInspector.CPUProfileHeader.prototype={createView:function() {return new WebInspector.CPUProfileView(this);},protocolProfile:function() {return this._protocolProfile;},__proto__:WebInspector.WritableProfileHeader.prototype} WebInspector.CPUProfileView.NodeFormatter=function(profileView) {this._profileView=profileView;} WebInspector.CPUProfileView.NodeFormatter.prototype={formatValue:function(value) {return WebInspector.UIString("%.1f\u2009ms",value);},formatPercent:function(value,node) {return node.profileNode===this._profileView.profile.idleNode?"":WebInspector.UIString("%.2f\u2009%%",value);},linkifyNode:function(node) {var callFrame=node.profileNode.frame;return this._profileView.linkifier().linkifyConsoleCallFrame(this._profileView.target(),callFrame,"profile-node-file");}} WebInspector.CPUFlameChartDataProvider=function(cpuProfile,target) {WebInspector.ProfileFlameChartDataProvider.call(this,target);this._cpuProfile=cpuProfile;} WebInspector.CPUFlameChartDataProvider.prototype={_calculateTimelineData:function() {function ChartEntry(depth,duration,startTime,selfTime,node) {this.depth=depth;this.duration=duration;this.startTime=startTime;this.selfTime=selfTime;this.node=node;} var entries=[];var stack=[];var maxDepth=5;function onOpenFrame() {stack.push(entries.length);entries.push(null);} function onCloseFrame(depth,node,startTime,totalTime,selfTime) {var index=stack.pop();entries[index]=new ChartEntry(depth,totalTime,startTime,selfTime,node);maxDepth=Math.max(maxDepth,depth);} this._cpuProfile.forEachFrame(onOpenFrame,onCloseFrame);var entryNodes=new Array(entries.length);var entryLevels=new Uint8Array(entries.length);var entryTotalTimes=new Float32Array(entries.length);var entrySelfTimes=new Float32Array(entries.length);var entryStartTimes=new Float64Array(entries.length);var minimumBoundary=this.minimumBoundary();for(var i=0;i<entries.length;++i){var entry=entries[i];entryNodes[i]=entry.node;entryLevels[i]=entry.depth;entryTotalTimes[i]=entry.duration;entryStartTimes[i]=entry.startTime;entrySelfTimes[i]=entry.selfTime;} this._maxStackDepth=maxDepth;this._timelineData=new WebInspector.FlameChart.TimelineData(entryLevels,entryTotalTimes,entryStartTimes,null);this._entryNodes=entryNodes;this._entrySelfTimes=entrySelfTimes;return this._timelineData;},prepareHighlightedEntryInfo:function(entryIndex) {var timelineData=this._timelineData;var node=this._entryNodes[entryIndex];if(!node) return null;var entryInfo=[];function pushEntryInfoRow(title,value) {entryInfo.push({title:title,value:value});} function millisecondsToString(ms) {if(ms===0) return"0";if(ms<1000) return WebInspector.UIString("%.1f\u2009ms",ms);return Number.secondsToString(ms/1000,true);} var name=WebInspector.beautifyFunctionName(node.functionName);pushEntryInfoRow(WebInspector.UIString("Name"),name);var selfTime=millisecondsToString(this._entrySelfTimes[entryIndex]);var totalTime=millisecondsToString(timelineData.entryTotalTimes[entryIndex]);pushEntryInfoRow(WebInspector.UIString("Self time"),selfTime);pushEntryInfoRow(WebInspector.UIString("Total time"),totalTime);var callFrame=(node);var linkifier=new WebInspector.Linkifier();var text=linkifier.linkifyConsoleCallFrame(this._target,callFrame).textContent;linkifier.dispose();pushEntryInfoRow(WebInspector.UIString("URL"),text);pushEntryInfoRow(WebInspector.UIString("Aggregated self time"),Number.secondsToString(node.selfTime/1000,true));pushEntryInfoRow(WebInspector.UIString("Aggregated total time"),Number.secondsToString(node.totalTime/1000,true));if(node.deoptReason&&node.deoptReason!=="no reason") pushEntryInfoRow(WebInspector.UIString("Not optimized"),node.deoptReason);return entryInfo;},__proto__:WebInspector.ProfileFlameChartDataProvider.prototype};WebInspector.HeapProfileView=function(profileHeader) {this._profileHeader=profileHeader;this.profile=new WebInspector.SamplingHeapProfileModel(profileHeader._profile||profileHeader.protocolProfile());this.adjustedTotal=this.profile.total;var views=[WebInspector.ProfileView.ViewTypes.Flame,WebInspector.ProfileView.ViewTypes.Heavy,WebInspector.ProfileView.ViewTypes.Tree];WebInspector.ProfileView.call(this,new WebInspector.HeapProfileView.NodeFormatter(this),views);} WebInspector.HeapProfileView.prototype={columnHeader:function(columnId) {switch(columnId){case"self":return WebInspector.UIString("Self Size (bytes)");case"total":return WebInspector.UIString("Total Size (bytes)");} return"";},createFlameChartDataProvider:function() {return new WebInspector.HeapFlameChartDataProvider(this.profile,this._profileHeader.target());},__proto__:WebInspector.ProfileView.prototype} WebInspector.SamplingHeapProfileType=function() {WebInspector.ProfileType.call(this,WebInspector.SamplingHeapProfileType.TypeId,WebInspector.UIString("Record Allocation Profile"));this._recording=false;WebInspector.SamplingHeapProfileType.instance=this;} WebInspector.SamplingHeapProfileType.TypeId="SamplingHeap";WebInspector.SamplingHeapProfileType.prototype={typeName:function() {return"Heap";},fileExtension:function() {return".heapprofile";},get buttonTooltip() {return this._recording?WebInspector.UIString("Stop heap profiling"):WebInspector.UIString("Start heap profiling");},buttonClicked:function() {var wasRecording=this._recording;if(wasRecording) this.stopRecordingProfile();else this.startRecordingProfile();return!wasRecording;},get treeItemTitle() {return WebInspector.UIString("ALLOCATION PROFILES");},get description() {return WebInspector.UIString("Allocation profiles show memory allocations from your JavaScript functions.");},startRecordingProfile:function() {var target=WebInspector.context.flavor(WebInspector.Target);if(this._profileBeingRecorded||!target) return;var profile=new WebInspector.SamplingHeapProfileHeader(target,this);this.setProfileBeingRecorded(profile);WebInspector.targetManager.suspendAllTargets();this.addProfile(profile);profile.updateStatus(WebInspector.UIString("Recording\u2026"));this._recording=true;target.heapProfilerModel.startSampling();},stopRecordingProfile:function() {this._recording=false;if(!this._profileBeingRecorded||!this._profileBeingRecorded.target()) return;var recordedProfile;function didStopProfiling(profile) {if(!this._profileBeingRecorded) return;console.assert(profile);this._profileBeingRecorded.setProtocolProfile(profile);this._profileBeingRecorded.updateStatus("");recordedProfile=this._profileBeingRecorded;this.setProfileBeingRecorded(null);} function fireEvent() {this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete,recordedProfile);} this._profileBeingRecorded.target().heapProfilerModel.stopSampling().then(didStopProfiling.bind(this)).then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targetManager)).then(fireEvent.bind(this));},createProfileLoadedFromFile:function(title) {return new WebInspector.SamplingHeapProfileHeader(null,this,title);},profileBeingRecordedRemoved:function() {this.stopRecordingProfile();},__proto__:WebInspector.ProfileType.prototype} WebInspector.SamplingHeapProfileHeader=function(target,type,title) {WebInspector.WritableProfileHeader.call(this,target,type,title||WebInspector.UIString("Profile %d",type.nextProfileUid()));} WebInspector.SamplingHeapProfileHeader.prototype={createView:function() {return new WebInspector.HeapProfileView(this);},protocolProfile:function() {return this._protocolProfile;},__proto__:WebInspector.WritableProfileHeader.prototype} WebInspector.SamplingHeapProfileNode=function(node) {WebInspector.ProfileNode.call(this,node.functionName,node.scriptId,node.url,node.lineNumber,node.columnNumber);this.self=node.selfSize;this.callUID=`${this.frame.functionName}@${this.frame.scriptId}:${this.frame.lineNumber}`;} WebInspector.SamplingHeapProfileNode.prototype={__proto__:WebInspector.ProfileNode.prototype} WebInspector.SamplingHeapProfileModel=function(profile) {WebInspector.ProfileTreeModel.call(this,this._translateProfileTree(profile.head));} WebInspector.SamplingHeapProfileModel.prototype={_translateProfileTree:function(root) {var resultRoot=new WebInspector.SamplingHeapProfileNode(root);var targetNodeStack=[resultRoot];var sourceNodeStack=[root];while(sourceNodeStack.length){var sourceNode=sourceNodeStack.pop();var parentNode=targetNodeStack.pop();parentNode.children=sourceNode.children.map(child=>new WebInspector.SamplingHeapProfileNode(child));sourceNodeStack.push.apply(sourceNodeStack,sourceNode.children);targetNodeStack.push.apply(targetNodeStack,parentNode.children);} return resultRoot;},__proto__:WebInspector.ProfileTreeModel.prototype} WebInspector.HeapProfileView.NodeFormatter=function(profileView) {this._profileView=profileView;} WebInspector.HeapProfileView.NodeFormatter.prototype={formatValue:function(value) {return Number.withThousandsSeparator(value);},formatPercent:function(value,node) {return WebInspector.UIString("%.2f\u2009%%",value);},linkifyNode:function(node) {var callFrame=node.profileNode.frame;return this._profileView.linkifier().linkifyConsoleCallFrame(this._profileView.target(),callFrame,"profile-node-file");}} WebInspector.HeapFlameChartDataProvider=function(profile,target) {WebInspector.ProfileFlameChartDataProvider.call(this,target);this._profile=profile;} WebInspector.HeapFlameChartDataProvider.prototype={minimumBoundary:function() {return 0;},totalTime:function() {return this._profile.root.total;},formatValue:function(value,precision) {return WebInspector.UIString("%s\u2009KB",Number.withThousandsSeparator(value/1e3));},_calculateTimelineData:function() {function nodesCount(node) {return node.children.reduce((count,node)=>count+nodesCount(node),1);} var count=nodesCount(this._profile.root);var entryNodes=new Array(count);var entryLevels=new Uint8Array(count);var entryTotalTimes=new Float32Array(count);var entryStartTimes=new Float64Array(count);var depth=0;var maxDepth=0;var position=0;var index=0;function addNode(node) {var start=position;entryNodes[index]=node;entryLevels[index]=depth;entryTotalTimes[index]=node.total;entryStartTimes[index]=position;++index;++depth;node.children.forEach(addNode);--depth;maxDepth=Math.max(maxDepth,depth);position=start+node.total;} addNode(this._profile.root);this._maxStackDepth=maxDepth+1;this._entryNodes=entryNodes;this._timelineData=new WebInspector.FlameChart.TimelineData(entryLevels,entryTotalTimes,entryStartTimes,null);return this._timelineData;},prepareHighlightedEntryInfo:function(entryIndex) {var node=this._entryNodes[entryIndex];if(!node) return null;var entryInfo=[];function pushEntryInfoRow(title,value) {entryInfo.push({title:title,value:value});} pushEntryInfoRow(WebInspector.UIString("Name"),WebInspector.beautifyFunctionName(node.functionName));pushEntryInfoRow(WebInspector.UIString("Self size"),Number.bytesToString(node.self));pushEntryInfoRow(WebInspector.UIString("Total size"),Number.bytesToString(node.total));var linkifier=new WebInspector.Linkifier();var text=(new WebInspector.Linkifier()).linkifyConsoleCallFrame(this._target,node.frame).textContent;linkifier.dispose();pushEntryInfoRow(WebInspector.UIString("URL"),text);return entryInfo;},__proto__:WebInspector.ProfileFlameChartDataProvider.prototype};WebInspector.HeapSnapshotProgressEvent={Update:"ProgressUpdate",BrokenSnapshot:"BrokenSnapshot"};WebInspector.HeapSnapshotCommon={} WebInspector.HeapSnapshotCommon.baseSystemDistance=100000000;WebInspector.HeapSnapshotCommon.AllocationNodeCallers=function(nodesWithSingleCaller,branchingCallers) {this.nodesWithSingleCaller=nodesWithSingleCaller;this.branchingCallers=branchingCallers;} WebInspector.HeapSnapshotCommon.SerializedAllocationNode=function(nodeId,functionName,scriptName,scriptId,line,column,count,size,liveCount,liveSize,hasChildren) {this.id=nodeId;this.name=functionName;this.scriptName=scriptName;this.scriptId=scriptId;this.line=line;this.column=column;this.count=count;this.size=size;this.liveCount=liveCount;this.liveSize=liveSize;this.hasChildren=hasChildren;} WebInspector.HeapSnapshotCommon.AllocationStackFrame=function(functionName,scriptName,scriptId,line,column) {this.functionName=functionName;this.scriptName=scriptName;this.scriptId=scriptId;this.line=line;this.column=column;} WebInspector.HeapSnapshotCommon.Node=function(id,name,distance,nodeIndex,retainedSize,selfSize,type) {this.id=id;this.name=name;this.distance=distance;this.nodeIndex=nodeIndex;this.retainedSize=retainedSize;this.selfSize=selfSize;this.type=type;this.canBeQueried=false;this.detachedDOMTreeNode=false;} WebInspector.HeapSnapshotCommon.Edge=function(name,node,type,edgeIndex) {this.name=name;this.node=node;this.type=type;this.edgeIndex=edgeIndex;};WebInspector.HeapSnapshotCommon.Aggregate=function() {this.count;this.distance;this.self;this.maxRet;this.type;this.name;this.idxs;} WebInspector.HeapSnapshotCommon.AggregateForDiff=function(){this.indexes=[];this.ids=[];this.selfSizes=[];} WebInspector.HeapSnapshotCommon.Diff=function() {this.addedCount=0;this.removedCount=0;this.addedSize=0;this.removedSize=0;this.deletedIndexes=[];this.addedIndexes=[];} WebInspector.HeapSnapshotCommon.DiffForClass=function() {this.addedCount;this.removedCount;this.addedSize;this.removedSize;this.deletedIndexes;this.addedIndexes;this.countDelta;this.sizeDelta;} WebInspector.HeapSnapshotCommon.ComparatorConfig=function() {this.fieldName1;this.ascending1;this.fieldName2;this.ascending2;} WebInspector.HeapSnapshotCommon.WorkerCommand=function() {this.callId;this.disposition;this.objectId;this.newObjectId;this.methodName;this.methodArguments;this.source;} WebInspector.HeapSnapshotCommon.ItemsRange=function(startPosition,endPosition,totalLength,items) {this.startPosition=startPosition;this.endPosition=endPosition;this.totalLength=totalLength;this.items=items;} WebInspector.HeapSnapshotCommon.StaticData=function(nodeCount,rootNodeIndex,totalSize,maxJSObjectId) {this.nodeCount=nodeCount;this.rootNodeIndex=rootNodeIndex;this.totalSize=totalSize;this.maxJSObjectId=maxJSObjectId;} WebInspector.HeapSnapshotCommon.Statistics=function() {this.total;this.v8heap;this.native;this.code;this.jsArrays;this.strings;this.system;} WebInspector.HeapSnapshotCommon.NodeFilter=function(minNodeId,maxNodeId) {this.minNodeId=minNodeId;this.maxNodeId=maxNodeId;this.allocationNodeId;} WebInspector.HeapSnapshotCommon.NodeFilter.prototype={equals:function(o) {return this.minNodeId===o.minNodeId&&this.maxNodeId===o.maxNodeId&&this.allocationNodeId===o.allocationNodeId;}} WebInspector.HeapSnapshotCommon.SearchConfig=function(query,caseSensitive,isRegex,shouldJump,jumpBackward) {this.query=query;this.caseSensitive=caseSensitive;this.isRegex=isRegex;this.shouldJump=shouldJump;this.jumpBackward=jumpBackward;} WebInspector.HeapSnapshotCommon.Samples=function(timestamps,lastAssignedIds,sizes) {this.timestamps=timestamps;this.lastAssignedIds=lastAssignedIds;this.sizes=sizes;};WebInspector.HeapSnapshotWorkerProxy=function(eventHandler) {this._eventHandler=eventHandler;this._nextObjectId=1;this._nextCallId=1;this._callbacks=new Map();this._previousCallbacks=new Set();this._worker=new WebInspector.Worker("heap_snapshot_worker");this._worker.onmessage=this._messageReceived.bind(this);} WebInspector.HeapSnapshotWorkerProxy.prototype={createLoader:function(profileUid,snapshotReceivedCallback) {var objectId=this._nextObjectId++;var proxy=new WebInspector.HeapSnapshotLoaderProxy(this,objectId,profileUid,snapshotReceivedCallback);this._postMessage({callId:this._nextCallId++,disposition:"create",objectId:objectId,methodName:"WebInspector.HeapSnapshotLoader"});return proxy;},dispose:function() {this._worker.terminate();if(this._interval) clearInterval(this._interval);},disposeObject:function(objectId) {this._postMessage({callId:this._nextCallId++,disposition:"dispose",objectId:objectId});},evaluateForTest:function(script,callback) {var callId=this._nextCallId++;this._callbacks.set(callId,callback);this._postMessage({callId:callId,disposition:"evaluateForTest",source:script});},callFactoryMethod:function(callback,objectId,methodName,proxyConstructor) {var callId=this._nextCallId++;var methodArguments=Array.prototype.slice.call(arguments,4);var newObjectId=this._nextObjectId++;function wrapCallback(remoteResult) {callback(remoteResult?new proxyConstructor(this,newObjectId):null);} if(callback){this._callbacks.set(callId,wrapCallback.bind(this));this._postMessage({callId:callId,disposition:"factory",objectId:objectId,methodName:methodName,methodArguments:methodArguments,newObjectId:newObjectId});return null;}else{this._postMessage({callId:callId,disposition:"factory",objectId:objectId,methodName:methodName,methodArguments:methodArguments,newObjectId:newObjectId});return new proxyConstructor(this,newObjectId);}},callMethod:function(callback,objectId,methodName) {var callId=this._nextCallId++;var methodArguments=Array.prototype.slice.call(arguments,3);if(callback) this._callbacks.set(callId,callback);this._postMessage({callId:callId,disposition:"method",objectId:objectId,methodName:methodName,methodArguments:methodArguments});},startCheckingForLongRunningCalls:function() {if(this._interval) return;this._checkLongRunningCalls();this._interval=setInterval(this._checkLongRunningCalls.bind(this),300);},_checkLongRunningCalls:function() {for(var callId of this._previousCallbacks) if(!this._callbacks.has(callId)) this._previousCallbacks.delete(callId);var hasLongRunningCalls=!!this._previousCallbacks.size;this.dispatchEventToListeners("wait",hasLongRunningCalls);for(var callId of this._callbacks.keysArray()) this._previousCallbacks.add(callId);},_messageReceived:function(event) {var data=event.data;if(data.eventName){if(this._eventHandler) this._eventHandler(data.eventName,data.data);return;} if(data.error){if(data.errorMethodName) WebInspector.console.error(WebInspector.UIString("An error occurred when a call to method '%s' was requested",data.errorMethodName));WebInspector.console.error(data["errorCallStack"]);this._callbacks.delete(data.callId);return;} if(!this._callbacks.has(data.callId)) return;var callback=this._callbacks.get(data.callId);this._callbacks.delete(data.callId);callback(data.result);},_postMessage:function(message) {this._worker.postMessage(message);},__proto__:WebInspector.Object.prototype} WebInspector.HeapSnapshotProxyObject=function(worker,objectId) {this._worker=worker;this._objectId=objectId;} WebInspector.HeapSnapshotProxyObject.prototype={_callWorker:function(workerMethodName,args) {args.splice(1,0,this._objectId);return this._worker[workerMethodName].apply(this._worker,args);},dispose:function() {this._worker.disposeObject(this._objectId);},disposeWorker:function() {this._worker.dispose();},callFactoryMethod:function(callback,methodName,proxyConstructor,var_args) {return this._callWorker("callFactoryMethod",Array.prototype.slice.call(arguments,0));},callMethod:function(callback,methodName,var_args) {return this._callWorker("callMethod",Array.prototype.slice.call(arguments,0));},_callMethodPromise:function(methodName,var_args) {function action(args,fulfill) {this._callWorker("callMethod",[fulfill].concat(args));} return new Promise(action.bind(this,Array.prototype.slice.call(arguments)));}};WebInspector.HeapSnapshotLoaderProxy=function(worker,objectId,profileUid,snapshotReceivedCallback) {WebInspector.HeapSnapshotProxyObject.call(this,worker,objectId);this._profileUid=profileUid;this._snapshotReceivedCallback=snapshotReceivedCallback;} WebInspector.HeapSnapshotLoaderProxy.prototype={write:function(chunk,callback) {this.callMethod(callback,"write",chunk);},close:function(callback) {function buildSnapshot() {if(callback) callback();var showHiddenData=WebInspector.moduleSetting("showAdvancedHeapSnapshotProperties").get();this.callFactoryMethod(updateStaticData.bind(this),"buildSnapshot",WebInspector.HeapSnapshotProxy,showHiddenData);} function updateStaticData(snapshotProxy) {this.dispose();snapshotProxy.setProfileUid(this._profileUid);snapshotProxy.updateStaticData(this._snapshotReceivedCallback.bind(this));} this.callMethod(buildSnapshot.bind(this),"close");},__proto__:WebInspector.HeapSnapshotProxyObject.prototype} WebInspector.HeapSnapshotProxy=function(worker,objectId) {WebInspector.HeapSnapshotProxyObject.call(this,worker,objectId);this._staticData=null;} WebInspector.HeapSnapshotProxy.prototype={search:function(searchConfig,filter) {return this._callMethodPromise("search",searchConfig,filter);},aggregatesWithFilter:function(filter,callback) {this.callMethod(callback,"aggregatesWithFilter",filter);},aggregatesForDiff:function(callback) {this.callMethod(callback,"aggregatesForDiff");},calculateSnapshotDiff:function(baseSnapshotId,baseSnapshotAggregates,callback) {this.callMethod(callback,"calculateSnapshotDiff",baseSnapshotId,baseSnapshotAggregates);},nodeClassName:function(snapshotObjectId) {return this._callMethodPromise("nodeClassName",snapshotObjectId);},createEdgesProvider:function(nodeIndex) {return this.callFactoryMethod(null,"createEdgesProvider",WebInspector.HeapSnapshotProviderProxy,nodeIndex);},createRetainingEdgesProvider:function(nodeIndex) {return this.callFactoryMethod(null,"createRetainingEdgesProvider",WebInspector.HeapSnapshotProviderProxy,nodeIndex);},createAddedNodesProvider:function(baseSnapshotId,className) {return this.callFactoryMethod(null,"createAddedNodesProvider",WebInspector.HeapSnapshotProviderProxy,baseSnapshotId,className);},createDeletedNodesProvider:function(nodeIndexes) {return this.callFactoryMethod(null,"createDeletedNodesProvider",WebInspector.HeapSnapshotProviderProxy,nodeIndexes);},createNodesProvider:function(filter) {return this.callFactoryMethod(null,"createNodesProvider",WebInspector.HeapSnapshotProviderProxy,filter);},createNodesProviderForClass:function(className,nodeFilter) {return this.callFactoryMethod(null,"createNodesProviderForClass",WebInspector.HeapSnapshotProviderProxy,className,nodeFilter);},allocationTracesTops:function(callback) {this.callMethod(callback,"allocationTracesTops");},allocationNodeCallers:function(nodeId,callback) {this.callMethod(callback,"allocationNodeCallers",nodeId);},allocationStack:function(nodeIndex,callback) {this.callMethod(callback,"allocationStack",nodeIndex);},dispose:function() {throw new Error("Should never be called");},get nodeCount() {return this._staticData.nodeCount;},get rootNodeIndex() {return this._staticData.rootNodeIndex;},updateStaticData:function(callback) {function dataReceived(staticData) {this._staticData=staticData;callback(this);} this.callMethod(dataReceived.bind(this),"updateStaticData");},getStatistics:function() {return this._callMethodPromise("getStatistics");},getSamples:function() {return this._callMethodPromise("getSamples");},get totalSize() {return this._staticData.totalSize;},get uid() {return this._profileUid;},setProfileUid:function(profileUid) {this._profileUid=profileUid;},maxJSObjectId:function() {return this._staticData.maxJSObjectId;},__proto__:WebInspector.HeapSnapshotProxyObject.prototype} WebInspector.HeapSnapshotProviderProxy=function(worker,objectId) {WebInspector.HeapSnapshotProxyObject.call(this,worker,objectId);} WebInspector.HeapSnapshotProviderProxy.prototype={nodePosition:function(snapshotObjectId) {return this._callMethodPromise("nodePosition",snapshotObjectId);},isEmpty:function(callback) {this.callMethod(callback,"isEmpty");},serializeItemsRange:function(startPosition,endPosition,callback) {this.callMethod(callback,"serializeItemsRange",startPosition,endPosition);},sortAndRewind:function(comparator) {return this._callMethodPromise("sortAndRewind",comparator);},__proto__:WebInspector.HeapSnapshotProxyObject.prototype};WebInspector.HeapSnapshotSortableDataGrid=function(dataDisplayDelegate,columns) {WebInspector.DataGrid.call(this,columns);this._dataDisplayDelegate=dataDisplayDelegate;this._recursiveSortingDepth=0;this._highlightedNode=null;this._populatedAndSorted=false;this._nameFilter=null;this._nodeFilter=new WebInspector.HeapSnapshotCommon.NodeFilter();this.addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete,this._sortingComplete,this);this.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this.sortingChanged,this);} WebInspector.HeapSnapshotSortableDataGrid.Events={ContentShown:"ContentShown",SortingComplete:"SortingComplete"} WebInspector.HeapSnapshotSortableDataGrid.prototype={nodeFilter:function() {return this._nodeFilter;},setNameFilter:function(nameFilter) {this._nameFilter=nameFilter;},defaultPopulateCount:function() {return 100;},_disposeAllNodes:function() {var children=this.topLevelNodes();for(var i=0,l=children.length;i<l;++i) children[i].dispose();},wasShown:function() {if(this._nameFilter){this._nameFilter.addEventListener(WebInspector.ToolbarInput.Event.TextChanged,this._onNameFilterChanged,this);this.updateVisibleNodes(true);} if(this._populatedAndSorted) this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown,this);},_sortingComplete:function() {this.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete,this._sortingComplete,this);this._populatedAndSorted=true;this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown,this);},willHide:function() {if(this._nameFilter) this._nameFilter.removeEventListener(WebInspector.ToolbarInput.Event.TextChanged,this._onNameFilterChanged,this);this._clearCurrentHighlight();},populateContextMenu:function(contextMenu,event) {var td=event.target.enclosingNodeOrSelfWithNodeName("td");if(!td) return;var node=td.heapSnapshotNode;function revealInSummaryView() {this._dataDisplayDelegate.showObject(node.snapshotNodeId,"Summary");} if(node instanceof WebInspector.HeapSnapshotRetainingObjectNode) contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Summary ^view"),revealInSummaryView.bind(this));},resetSortingCache:function() {delete this._lastSortColumnIdentifier;delete this._lastSortAscending;},topLevelNodes:function() {return this.rootNode().children;},revealObjectByHeapSnapshotId:function(heapSnapshotObjectId) {return Promise.resolve((null));},highlightNode:function(node) {this._clearCurrentHighlight();this._highlightedNode=node;WebInspector.runCSSAnimationOnce(this._highlightedNode.element(),"highlighted-row");},nodeWasDetached:function(node) {if(this._highlightedNode===node) this._clearCurrentHighlight();},_clearCurrentHighlight:function() {if(!this._highlightedNode) return this._highlightedNode.element().classList.remove("highlighted-row");this._highlightedNode=null;},resetNameFilter:function() {this._nameFilter.setValue("");},_onNameFilterChanged:function() {this.updateVisibleNodes(true);},sortingChanged:function() {var sortAscending=this.isSortOrderAscending();var sortColumnIdentifier=this.sortColumnIdentifier();if(this._lastSortColumnIdentifier===sortColumnIdentifier&&this._lastSortAscending===sortAscending) return;this._lastSortColumnIdentifier=sortColumnIdentifier;this._lastSortAscending=sortAscending;var sortFields=this._sortFields(sortColumnIdentifier,sortAscending);function SortByTwoFields(nodeA,nodeB) {var field1=nodeA[sortFields[0]];var field2=nodeB[sortFields[0]];var result=field1<field2?-1:(field1>field2?1:0);if(!sortFields[1]) result=-result;if(result!==0) return result;field1=nodeA[sortFields[2]];field2=nodeB[sortFields[2]];result=field1<field2?-1:(field1>field2?1:0);if(!sortFields[3]) result=-result;return result;} this._performSorting(SortByTwoFields);},_performSorting:function(sortFunction) {this.recursiveSortingEnter();var children=this.allChildren(this.rootNode());this.rootNode().removeChildren();children.sort(sortFunction);for(var i=0,l=children.length;i<l;++i){var child=children[i];this.appendChildAfterSorting(child);if(child.expanded) child.sort();} this.recursiveSortingLeave();},appendChildAfterSorting:function(child) {var revealed=child.revealed;this.rootNode().appendChild(child);child.revealed=revealed;},recursiveSortingEnter:function() {++this._recursiveSortingDepth;},recursiveSortingLeave:function() {if(!this._recursiveSortingDepth) return;if(--this._recursiveSortingDepth) return;this.updateVisibleNodes(true);this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);},updateVisibleNodes:function(force) {},allChildren:function(parent) {return parent.children;},insertChild:function(parent,node,index) {parent.insertChild(node,index);},removeChildByIndex:function(parent,index) {parent.removeChild(parent.children[index]);},removeAllChildren:function(parent) {parent.removeChildren();},__proto__:WebInspector.DataGrid.prototype} WebInspector.HeapSnapshotViewportDataGrid=function(dataDisplayDelegate,columns) {WebInspector.HeapSnapshotSortableDataGrid.call(this,dataDisplayDelegate,columns);this.scrollContainer.addEventListener("scroll",this._onScroll.bind(this),true);this._topPaddingHeight=0;this._bottomPaddingHeight=0;} WebInspector.HeapSnapshotViewportDataGrid.prototype={topLevelNodes:function() {return this.allChildren(this.rootNode());},appendChildAfterSorting:function(child) {},updateVisibleNodes:function(force) {var guardZoneHeight=40;var scrollHeight=this.scrollContainer.scrollHeight;var scrollTop=this.scrollContainer.scrollTop;var scrollBottom=scrollHeight-scrollTop-this.scrollContainer.offsetHeight;scrollTop=Math.max(0,scrollTop-guardZoneHeight);scrollBottom=Math.max(0,scrollBottom-guardZoneHeight);var viewPortHeight=scrollHeight-scrollTop-scrollBottom;if(!force&&scrollTop>=this._topPaddingHeight&&scrollBottom>=this._bottomPaddingHeight) return;var hysteresisHeight=500;scrollTop-=hysteresisHeight;viewPortHeight+=2*hysteresisHeight;var selectedNode=this.selectedNode;this.rootNode().removeChildren();this._topPaddingHeight=0;this._bottomPaddingHeight=0;this._addVisibleNodes(this.rootNode(),scrollTop,scrollTop+viewPortHeight);this.setVerticalPadding(this._topPaddingHeight,this._bottomPaddingHeight);if(selectedNode){if(selectedNode.parent) selectedNode.select(true);else this.selectedNode=selectedNode;}},_addVisibleNodes:function(parentNode,topBound,bottomBound) {if(!parentNode.expanded) return 0;var children=this.allChildren(parentNode);var topPadding=0;var nameFilterValue=this._nameFilter?this._nameFilter.value().toLowerCase():"";for(var i=0;i<children.length;++i){var child=children[i];if(nameFilterValue&&child.filteredOut&&child.filteredOut(nameFilterValue)) continue;var newTop=topPadding+this._nodeHeight(child);if(newTop>topBound) break;topPadding=newTop;} var position=topPadding;for(;i<children.length&&position<bottomBound;++i){var child=children[i];if(nameFilterValue&&child.filteredOut&&child.filteredOut(nameFilterValue)) continue;var hasChildren=child.hasChildren;child.removeChildren();child.hasChildren=hasChildren;child.revealed=true;parentNode.appendChild(child);position+=child.nodeSelfHeight();position+=this._addVisibleNodes(child,topBound-position,bottomBound-position);} var bottomPadding=0;for(;i<children.length;++i){var child=children[i];if(nameFilterValue&&child.filteredOut&&child.filteredOut(nameFilterValue)) continue;bottomPadding+=this._nodeHeight(child);} this._topPaddingHeight+=topPadding;this._bottomPaddingHeight+=bottomPadding;return position+bottomPadding;},_nodeHeight:function(node) {if(!node.revealed) return 0;var result=node.nodeSelfHeight();if(!node.expanded) return result;var children=this.allChildren(node);for(var i=0;i<children.length;i++) result+=this._nodeHeight(children[i]);return result;},revealTreeNode:function(pathToReveal) {var height=this._calculateOffset(pathToReveal);var node=(pathToReveal.peekLast());var scrollTop=this.scrollContainer.scrollTop;var scrollBottom=scrollTop+this.scrollContainer.offsetHeight;if(height>=scrollTop&&height<scrollBottom) return Promise.resolve(node);var scrollGap=40;this.scrollContainer.scrollTop=Math.max(0,height-scrollGap);return new Promise(this._scrollTo.bind(this,node));},_scrollTo:function(node,fulfill) {console.assert(!this._scrollToResolveCallback);this._scrollToResolveCallback=fulfill.bind(null,node);},_calculateOffset:function(pathToReveal) {var parentNode=this.rootNode();var height=0;for(var i=0;i<pathToReveal.length;++i){var node=pathToReveal[i];var children=this.allChildren(parentNode);for(var j=0;j<children.length;++j){var child=children[j];if(node===child){height+=node.nodeSelfHeight();break;} height+=this._nodeHeight(child);} parentNode=node;} return height-pathToReveal.peekLast().nodeSelfHeight();},allChildren:function(parent) {return parent._allChildren||(parent._allChildren=[]);},appendNode:function(parent,node) {this.allChildren(parent).push(node);},insertChild:function(parent,node,index) {this.allChildren(parent).splice(index,0,(node));},removeChildByIndex:function(parent,index) {this.allChildren(parent).splice(index,1);},removeAllChildren:function(parent) {parent._allChildren=[];},removeTopLevelNodes:function() {this._disposeAllNodes();this.rootNode().removeChildren();this.rootNode()._allChildren=[];},_isScrolledIntoView:function(element) {var viewportTop=this.scrollContainer.scrollTop;var viewportBottom=viewportTop+this.scrollContainer.clientHeight;var elemTop=element.offsetTop;var elemBottom=elemTop+element.offsetHeight;return elemBottom<=viewportBottom&&elemTop>=viewportTop;},onResize:function() {WebInspector.HeapSnapshotSortableDataGrid.prototype.onResize.call(this);this.updateVisibleNodes(false);},_onScroll:function(event) {this.updateVisibleNodes(false);if(this._scrollToResolveCallback){this._scrollToResolveCallback();this._scrollToResolveCallback=null;}},__proto__:WebInspector.HeapSnapshotSortableDataGrid.prototype} WebInspector.HeapSnapshotContainmentDataGrid=function(dataDisplayDelegate,columns) {columns=columns||[{id:"object",title:WebInspector.UIString("Object"),disclosure:true,sortable:true},{id:"distance",title:WebInspector.UIString("Distance"),width:"80px",sortable:true},{id:"shallowSize",title:WebInspector.UIString("Shallow Size"),width:"120px",sortable:true},{id:"retainedSize",title:WebInspector.UIString("Retained Size"),width:"120px",sortable:true,sort:WebInspector.DataGrid.Order.Descending}];WebInspector.HeapSnapshotSortableDataGrid.call(this,dataDisplayDelegate,columns);} WebInspector.HeapSnapshotContainmentDataGrid.prototype={setDataSource:function(snapshot,nodeIndex) {this.snapshot=snapshot;var node={nodeIndex:nodeIndex||snapshot.rootNodeIndex};var fakeEdge={node:node};this.setRootNode(this._createRootNode(snapshot,fakeEdge));this.rootNode().sort();},_createRootNode:function(snapshot,fakeEdge) {return new WebInspector.HeapSnapshotObjectNode(this,snapshot,fakeEdge,null);},sortingChanged:function() {var rootNode=this.rootNode();if(rootNode.hasChildren) rootNode.sort();},__proto__:WebInspector.HeapSnapshotSortableDataGrid.prototype} WebInspector.HeapSnapshotRetainmentDataGrid=function(dataDisplayDelegate) {var columns=[{id:"object",title:WebInspector.UIString("Object"),disclosure:true,sortable:true},{id:"distance",title:WebInspector.UIString("Distance"),width:"80px",sortable:true,sort:WebInspector.DataGrid.Order.Ascending},{id:"shallowSize",title:WebInspector.UIString("Shallow Size"),width:"120px",sortable:true},{id:"retainedSize",title:WebInspector.UIString("Retained Size"),width:"120px",sortable:true}];WebInspector.HeapSnapshotContainmentDataGrid.call(this,dataDisplayDelegate,columns);} WebInspector.HeapSnapshotRetainmentDataGrid.Events={ExpandRetainersComplete:"ExpandRetainersComplete"} WebInspector.HeapSnapshotRetainmentDataGrid.prototype={_createRootNode:function(snapshot,fakeEdge) {return new WebInspector.HeapSnapshotRetainingObjectNode(this,snapshot,fakeEdge,null);},_sortFields:function(sortColumn,sortAscending) {return{object:["_name",sortAscending,"_count",false],count:["_count",sortAscending,"_name",true],shallowSize:["_shallowSize",sortAscending,"_name",true],retainedSize:["_retainedSize",sortAscending,"_name",true],distance:["_distance",sortAscending,"_name",true]}[sortColumn];},reset:function() {this.rootNode().removeChildren();this.resetSortingCache();},setDataSource:function(snapshot,nodeIndex) {WebInspector.HeapSnapshotContainmentDataGrid.prototype.setDataSource.call(this,snapshot,nodeIndex);this.rootNode().expand();},__proto__:WebInspector.HeapSnapshotContainmentDataGrid.prototype} WebInspector.HeapSnapshotConstructorsDataGrid=function(dataDisplayDelegate) {var columns=[{id:"object",title:WebInspector.UIString("Constructor"),disclosure:true,sortable:true},{id:"distance",title:WebInspector.UIString("Distance"),width:"90px",sortable:true},{id:"count",title:WebInspector.UIString("Objects Count"),width:"90px",sortable:true},{id:"shallowSize",title:WebInspector.UIString("Shallow Size"),width:"120px",sortable:true},{id:"retainedSize",title:WebInspector.UIString("Retained Size"),width:"120px",sort:WebInspector.DataGrid.Order.Descending,sortable:true}];WebInspector.HeapSnapshotViewportDataGrid.call(this,dataDisplayDelegate,columns);this._profileIndex=-1;this._objectIdToSelect=null;} WebInspector.HeapSnapshotConstructorsDataGrid.prototype={_sortFields:function(sortColumn,sortAscending) {return{object:["_name",sortAscending,"_count",false],distance:["_distance",sortAscending,"_retainedSize",true],count:["_count",sortAscending,"_name",true],shallowSize:["_shallowSize",sortAscending,"_name",true],retainedSize:["_retainedSize",sortAscending,"_name",true]}[sortColumn];},revealObjectByHeapSnapshotId:function(id) {if(!this.snapshot){this._objectIdToSelect=id;return Promise.resolve((null));} function didPopulateNode(nodes) {return nodes.length?this.revealTreeNode(nodes):null;} function didGetClassName(className) {if(!className) return null;var constructorNodes=this.topLevelNodes();for(var i=0;i<constructorNodes.length;i++){var parent=constructorNodes[i];if(parent._name===className) return parent.populateNodeBySnapshotObjectId(parseInt(id,10)).then(didPopulateNode.bind(this));} return null;} return this.snapshot.nodeClassName(parseInt(id,10)).then(didGetClassName.bind(this));},clear:function() {this._nextRequestedFilter=null;this._lastFilter=null;this.removeTopLevelNodes();},setDataSource:function(snapshot) {this.snapshot=snapshot;if(this._profileIndex===-1) this._populateChildren();if(this._objectIdToSelect){this.revealObjectByHeapSnapshotId(this._objectIdToSelect);this._objectIdToSelect=null;}},setSelectionRange:function(minNodeId,maxNodeId) {this._nodeFilter=new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId,maxNodeId);this._populateChildren(this._nodeFilter);},setAllocationNodeId:function(allocationNodeId) {this._nodeFilter=new WebInspector.HeapSnapshotCommon.NodeFilter();this._nodeFilter.allocationNodeId=allocationNodeId;this._populateChildren(this._nodeFilter);},_aggregatesReceived:function(nodeFilter,aggregates) {this._filterInProgress=null;if(this._nextRequestedFilter){this.snapshot.aggregatesWithFilter(this._nextRequestedFilter,this._aggregatesReceived.bind(this,this._nextRequestedFilter));this._filterInProgress=this._nextRequestedFilter;this._nextRequestedFilter=null;} this.removeTopLevelNodes();this.resetSortingCache();for(var constructor in aggregates) this.appendNode(this.rootNode(),new WebInspector.HeapSnapshotConstructorNode(this,constructor,aggregates[constructor],nodeFilter));this.sortingChanged();this._lastFilter=nodeFilter;},_populateChildren:function(nodeFilter) {nodeFilter=nodeFilter||new WebInspector.HeapSnapshotCommon.NodeFilter();if(this._filterInProgress){this._nextRequestedFilter=this._filterInProgress.equals(nodeFilter)?null:nodeFilter;return;} if(this._lastFilter&&this._lastFilter.equals(nodeFilter)) return;this._filterInProgress=nodeFilter;this.snapshot.aggregatesWithFilter(nodeFilter,this._aggregatesReceived.bind(this,nodeFilter));},filterSelectIndexChanged:function(profiles,profileIndex) {this._profileIndex=profileIndex;this._nodeFilter=undefined;if(profileIndex!==-1){var minNodeId=profileIndex>0?profiles[profileIndex-1].maxJSObjectId:0;var maxNodeId=profiles[profileIndex].maxJSObjectId;this._nodeFilter=new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId,maxNodeId);} this._populateChildren(this._nodeFilter);},__proto__:WebInspector.HeapSnapshotViewportDataGrid.prototype} WebInspector.HeapSnapshotDiffDataGrid=function(dataDisplayDelegate) {var columns=[{id:"object",title:WebInspector.UIString("Constructor"),disclosure:true,sortable:true},{id:"addedCount",title:WebInspector.UIString("# New"),width:"72px",sortable:true},{id:"removedCount",title:WebInspector.UIString("# Deleted"),width:"72px",sortable:true},{id:"countDelta",title:WebInspector.UIString("# Delta"),width:"64px",sortable:true},{id:"addedSize",title:WebInspector.UIString("Alloc. Size"),width:"72px",sortable:true,sort:WebInspector.DataGrid.Order.Descending},{id:"removedSize",title:WebInspector.UIString("Freed Size"),width:"72px",sortable:true},{id:"sizeDelta",title:WebInspector.UIString("Size Delta"),width:"72px",sortable:true}];WebInspector.HeapSnapshotViewportDataGrid.call(this,dataDisplayDelegate,columns);} WebInspector.HeapSnapshotDiffDataGrid.prototype={defaultPopulateCount:function() {return 50;},_sortFields:function(sortColumn,sortAscending) {return{object:["_name",sortAscending,"_count",false],addedCount:["_addedCount",sortAscending,"_name",true],removedCount:["_removedCount",sortAscending,"_name",true],countDelta:["_countDelta",sortAscending,"_name",true],addedSize:["_addedSize",sortAscending,"_name",true],removedSize:["_removedSize",sortAscending,"_name",true],sizeDelta:["_sizeDelta",sortAscending,"_name",true]}[sortColumn];},setDataSource:function(snapshot) {this.snapshot=snapshot;},setBaseDataSource:function(baseSnapshot) {this.baseSnapshot=baseSnapshot;this.removeTopLevelNodes();this.resetSortingCache();if(this.baseSnapshot===this.snapshot){this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);return;} this._populateChildren();},_populateChildren:function() {function aggregatesForDiffReceived(aggregatesForDiff) {this.snapshot.calculateSnapshotDiff(this.baseSnapshot.uid,aggregatesForDiff,didCalculateSnapshotDiff.bind(this));function didCalculateSnapshotDiff(diffByClassName) {for(var className in diffByClassName){var diff=diffByClassName[className];this.appendNode(this.rootNode(),new WebInspector.HeapSnapshotDiffNode(this,className,diff));} this.sortingChanged();}} this.baseSnapshot.aggregatesForDiff(aggregatesForDiffReceived.bind(this));},__proto__:WebInspector.HeapSnapshotViewportDataGrid.prototype} WebInspector.AllocationDataGrid=function(target,dataDisplayDelegate) {var columns=[{id:"liveCount",title:WebInspector.UIString("Live Count"),width:"72px",sortable:true},{id:"count",title:WebInspector.UIString("Count"),width:"72px",sortable:true},{id:"liveSize",title:WebInspector.UIString("Live Size"),width:"72px",sortable:true},{id:"size",title:WebInspector.UIString("Size"),width:"72px",sortable:true,sort:WebInspector.DataGrid.Order.Descending},{id:"name",title:WebInspector.UIString("Function"),disclosure:true,sortable:true},];WebInspector.HeapSnapshotViewportDataGrid.call(this,dataDisplayDelegate,columns);this._target=target;this._linkifier=new WebInspector.Linkifier();} WebInspector.AllocationDataGrid.prototype={target:function() {return this._target;},dispose:function() {this._linkifier.reset();},setDataSource:function(snapshot) {this.snapshot=snapshot;this.snapshot.allocationTracesTops(didReceiveAllocationTracesTops.bind(this));function didReceiveAllocationTracesTops(tops) {this._topNodes=tops;this._populateChildren();}},_populateChildren:function() {this.removeTopLevelNodes();var root=this.rootNode();var tops=this._topNodes;for(var i=0;i<tops.length;i++) this.appendNode(root,new WebInspector.AllocationGridNode(this,tops[i]));this.updateVisibleNodes(true);},sortingChanged:function() {this._topNodes.sort(this._createComparator());this.rootNode().removeChildren();this._populateChildren();},_createComparator:function() {var fieldName=this.sortColumnIdentifier();var compareResult=(this.sortOrder()===WebInspector.DataGrid.Order.Ascending)?+1:-1;function compare(a,b) {if(a[fieldName]>b[fieldName]) return compareResult;if(a[fieldName]<b[fieldName]) return-compareResult;return 0;} return compare;},__proto__:WebInspector.HeapSnapshotViewportDataGrid.prototype};WebInspector.HeapSnapshotGridNode=function(tree,hasChildren) {WebInspector.DataGridNode.call(this,null,hasChildren);this._dataGrid=tree;this._instanceCount=0;this._savedChildren=null;this._retrievedChildrenRanges=[];this._providerObject=null;} WebInspector.HeapSnapshotGridNode.Events={PopulateComplete:"PopulateComplete"} WebInspector.HeapSnapshotGridNode.createComparator=function(fieldNames) {return({fieldName1:fieldNames[0],ascending1:fieldNames[1],fieldName2:fieldNames[2],ascending2:fieldNames[3]});} WebInspector.HeapSnapshotGridNode.ChildrenProvider=function(){} WebInspector.HeapSnapshotGridNode.ChildrenProvider.prototype={dispose:function(){},nodePosition:function(snapshotObjectId){},isEmpty:function(callback){},serializeItemsRange:function(startPosition,endPosition,callback){},sortAndRewind:function(comparator){}} WebInspector.HeapSnapshotGridNode.prototype={heapSnapshotDataGrid:function() {return this._dataGrid;},createProvider:function() {throw new Error("Not implemented.");},retainersDataSource:function() {return null;},_provider:function() {if(!this._providerObject) this._providerObject=this.createProvider();return this._providerObject;},createCell:function(columnIdentifier) {var cell=WebInspector.DataGridNode.prototype.createCell.call(this,columnIdentifier);if(this._searchMatched) cell.classList.add("highlight");return cell;},collapse:function() {WebInspector.DataGridNode.prototype.collapse.call(this);this._dataGrid.updateVisibleNodes(true);},expand:function() {WebInspector.DataGridNode.prototype.expand.call(this);this._dataGrid.updateVisibleNodes(true);},dispose:function() {if(this._providerObject) this._providerObject.dispose();for(var node=this.children[0];node;node=node.traverseNextNode(true,this,true)) if(node.dispose) node.dispose();},_reachableFromWindow:false,queryObjectContent:function(callback) {},wasDetached:function() {this._dataGrid.nodeWasDetached(this);},_toPercentString:function(num) {return num.toFixed(0)+"\u2009%";},_toUIDistance:function(distance) {var baseSystemDistance=WebInspector.HeapSnapshotCommon.baseSystemDistance;return distance>=0&&distance<baseSystemDistance?WebInspector.UIString("%d",distance):WebInspector.UIString("\u2212");},allChildren:function() {return this._dataGrid.allChildren(this);},removeChildByIndex:function(index) {this._dataGrid.removeChildByIndex(this,index);},childForPosition:function(nodePosition) {var indexOfFirstChildInRange=0;for(var i=0;i<this._retrievedChildrenRanges.length;i++){var range=this._retrievedChildrenRanges[i];if(range.from<=nodePosition&&nodePosition<range.to){var childIndex=indexOfFirstChildInRange+nodePosition-range.from;return this.allChildren()[childIndex];} indexOfFirstChildInRange+=range.to-range.from+1;} return null;},_createValueCell:function(columnIdentifier) {var cell=createElement("td");cell.className="numeric-column";if(this.dataGrid.snapshot.totalSize!==0){var div=createElement("div");var valueSpan=createElement("span");valueSpan.textContent=this.data[columnIdentifier];div.appendChild(valueSpan);var percentColumn=columnIdentifier+"-percent";if(percentColumn in this.data){var percentSpan=createElement("span");percentSpan.className="percent-column";percentSpan.textContent=this.data[percentColumn];div.appendChild(percentSpan);div.classList.add("profile-multiple-values");} cell.appendChild(div);} return cell;},populate:function(event) {if(this._populated) return;this._populated=true;this._provider().sortAndRewind(this.comparator()).then(this._populateChildren.bind(this));},expandWithoutPopulate:function() {this._populated=true;this.expand();return this._provider().sortAndRewind(this.comparator());},_populateChildren:function(fromPosition,toPosition,afterPopulate) {fromPosition=fromPosition||0;toPosition=toPosition||fromPosition+this._dataGrid.defaultPopulateCount();var firstNotSerializedPosition=fromPosition;function serializeNextChunk() {if(firstNotSerializedPosition>=toPosition) return;var end=Math.min(firstNotSerializedPosition+this._dataGrid.defaultPopulateCount(),toPosition);this._provider().serializeItemsRange(firstNotSerializedPosition,end,childrenRetrieved.bind(this));firstNotSerializedPosition=end;} function insertRetrievedChild(item,insertionIndex) {if(this._savedChildren){var hash=this._childHashForEntity(item);if(hash in this._savedChildren){this._dataGrid.insertChild(this,this._savedChildren[hash],insertionIndex);return;}} this._dataGrid.insertChild(this,this._createChildNode(item),insertionIndex);} function insertShowMoreButton(from,to,insertionIndex) {var button=new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this),from,to,this._dataGrid.defaultPopulateCount());this._dataGrid.insertChild(this,button,insertionIndex);} function childrenRetrieved(itemsRange) {var itemIndex=0;var itemPosition=itemsRange.startPosition;var items=itemsRange.items;var insertionIndex=0;if(!this._retrievedChildrenRanges.length){if(itemsRange.startPosition>0){this._retrievedChildrenRanges.push({from:0,to:0});insertShowMoreButton.call(this,0,itemsRange.startPosition,insertionIndex++);} this._retrievedChildrenRanges.push({from:itemsRange.startPosition,to:itemsRange.endPosition});for(var i=0,l=items.length;i<l;++i) insertRetrievedChild.call(this,items[i],insertionIndex++);if(itemsRange.endPosition<itemsRange.totalLength) insertShowMoreButton.call(this,itemsRange.endPosition,itemsRange.totalLength,insertionIndex++);}else{var rangeIndex=0;var found=false;var range;while(rangeIndex<this._retrievedChildrenRanges.length){range=this._retrievedChildrenRanges[rangeIndex];if(range.to>=itemPosition){found=true;break;} insertionIndex+=range.to-range.from;if(range.to<itemsRange.totalLength) insertionIndex+=1;++rangeIndex;} if(!found||itemsRange.startPosition<range.from){this.allChildren()[insertionIndex-1].setEndPosition(itemsRange.startPosition);insertShowMoreButton.call(this,itemsRange.startPosition,found?range.from:itemsRange.totalLength,insertionIndex);range={from:itemsRange.startPosition,to:itemsRange.startPosition};if(!found) rangeIndex=this._retrievedChildrenRanges.length;this._retrievedChildrenRanges.splice(rangeIndex,0,range);}else{insertionIndex+=itemPosition-range.from;} while(range.to<itemsRange.endPosition){var skipCount=range.to-itemPosition;insertionIndex+=skipCount;itemIndex+=skipCount;itemPosition=range.to;var nextRange=this._retrievedChildrenRanges[rangeIndex+1];var newEndOfRange=nextRange?nextRange.from:itemsRange.totalLength;if(newEndOfRange>itemsRange.endPosition) newEndOfRange=itemsRange.endPosition;while(itemPosition<newEndOfRange){insertRetrievedChild.call(this,items[itemIndex++],insertionIndex++);++itemPosition;} if(nextRange&&newEndOfRange===nextRange.from){range.to=nextRange.to;this.removeChildByIndex(insertionIndex);this._retrievedChildrenRanges.splice(rangeIndex+1,1);}else{range.to=newEndOfRange;if(newEndOfRange===itemsRange.totalLength) this.removeChildByIndex(insertionIndex);else this.allChildren()[insertionIndex].setStartPosition(itemsRange.endPosition);}}} this._instanceCount+=items.length;if(firstNotSerializedPosition<toPosition){serializeNextChunk.call(this);return;} if(this.expanded) this._dataGrid.updateVisibleNodes(true);if(afterPopulate) afterPopulate();this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete);} serializeNextChunk.call(this);},_saveChildren:function() {this._savedChildren=null;var children=this.allChildren();for(var i=0,l=children.length;i<l;++i){var child=children[i];if(!child.expanded) continue;if(!this._savedChildren) this._savedChildren={};this._savedChildren[this._childHashForNode(child)]=child;}},sort:function() {this._dataGrid.recursiveSortingEnter();function afterSort() {this._saveChildren();this._dataGrid.removeAllChildren(this);this._retrievedChildrenRanges=[];function afterPopulate() {var children=this.allChildren();for(var i=0,l=children.length;i<l;++i){var child=children[i];if(child.expanded) child.sort();} this._dataGrid.recursiveSortingLeave();} var instanceCount=this._instanceCount;this._instanceCount=0;this._populateChildren(0,instanceCount,afterPopulate.bind(this));} this._provider().sortAndRewind(this.comparator()).then(afterSort.bind(this));},__proto__:WebInspector.DataGridNode.prototype} WebInspector.HeapSnapshotGenericObjectNode=function(dataGrid,node) {WebInspector.HeapSnapshotGridNode.call(this,dataGrid,false);if(!node) return;this._name=node.name;this._type=node.type;this._distance=node.distance;this._shallowSize=node.selfSize;this._retainedSize=node.retainedSize;this.snapshotNodeId=node.id;this.snapshotNodeIndex=node.nodeIndex;if(this._type==="string") this._reachableFromWindow=true;else if(this._type==="object"&&this._name.startsWith("Window")){this._name=this.shortenWindowURL(this._name,false);this._reachableFromWindow=true;}else if(node.canBeQueried) this._reachableFromWindow=true;if(node.detachedDOMTreeNode) this.detachedDOMTreeNode=true;var snapshot=dataGrid.snapshot;var shallowSizePercent=this._shallowSize/snapshot.totalSize*100.0;var retainedSizePercent=this._retainedSize/snapshot.totalSize*100.0;this.data={"distance":this._toUIDistance(this._distance),"shallowSize":Number.withThousandsSeparator(this._shallowSize),"retainedSize":Number.withThousandsSeparator(this._retainedSize),"shallowSize-percent":this._toPercentString(shallowSizePercent),"retainedSize-percent":this._toPercentString(retainedSizePercent)};};WebInspector.HeapSnapshotGenericObjectNode.prototype={retainersDataSource:function() {return{snapshot:this._dataGrid.snapshot,snapshotNodeIndex:this.snapshotNodeIndex};},createCell:function(columnIdentifier) {var cell=columnIdentifier!=="object"?this._createValueCell(columnIdentifier):this._createObjectCell();if(this._searchMatched) cell.classList.add("highlight");return cell;},_createObjectCell:function() {var value=this._name;var valueStyle="object";switch(this._type){case"concatenated string":case"string":value="\""+value+"\"";valueStyle="string";break;case"regexp":value="/"+value+"/";valueStyle="string";break;case"closure":value=value+"()";valueStyle="function";break;case"number":valueStyle="number";break;case"hidden":valueStyle="null";break;case"array":value=(value||"")+"[]";break;};if(this._reachableFromWindow) valueStyle+=" highlight";if(value==="Object") value="";if(this.detachedDOMTreeNode) valueStyle+=" detached-dom-tree-node";return this._createObjectCellWithValue(valueStyle,value);},_createObjectCellWithValue:function(valueStyle,value) {var cell=createElement("td");cell.className="object-column";var div=createElement("div");div.className="source-code event-properties";div.style.overflow="visible";this._prefixObjectCell(div);var valueSpan=createElement("span");valueSpan.className="value object-value-"+valueStyle;valueSpan.textContent=value;div.appendChild(valueSpan);var idSpan=createElement("span");idSpan.className="object-value-id";idSpan.textContent=" @"+this.snapshotNodeId;div.appendChild(idSpan);cell.appendChild(div);cell.classList.add("disclosure");if(this.depth) cell.style.setProperty("padding-left",(this.depth*this.dataGrid.indentWidth)+"px");cell.heapSnapshotNode=this;return cell;},_prefixObjectCell:function(div) {},queryObjectContent:function(target,callback,objectGroupName) {function formatResult(error,object) {if(!error&&object.type) callback(target.runtimeModel.createRemoteObject(object));else callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(WebInspector.UIString("Preview is not available")));} if(this._type==="string") callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(this._name));else target.heapProfilerAgent().getObjectByHeapObjectId(String(this.snapshotNodeId),objectGroupName,formatResult);},updateHasChildren:function() {function isEmptyCallback(isEmpty) {this.hasChildren=!isEmpty;} this._provider().isEmpty(isEmptyCallback.bind(this));},shortenWindowURL:function(fullName,hasObjectId) {var startPos=fullName.indexOf("/");var endPos=hasObjectId?fullName.indexOf("@"):fullName.length;if(startPos!==-1&&endPos!==-1){var fullURL=fullName.substring(startPos+1,endPos).trimLeft();var url=fullURL.trimURL();if(url.length>40) url=url.trimMiddle(40);return fullName.substr(0,startPos+2)+url+fullName.substr(endPos);}else return fullName;},__proto__:WebInspector.HeapSnapshotGridNode.prototype} WebInspector.HeapSnapshotObjectNode=function(dataGrid,snapshot,edge,parentObjectNode) {WebInspector.HeapSnapshotGenericObjectNode.call(this,dataGrid,edge.node);this._referenceName=edge.name;this._referenceType=edge.type;this._edgeIndex=edge.edgeIndex;this._snapshot=snapshot;this._parentObjectNode=parentObjectNode;this._cycledWithAncestorGridNode=this._findAncestorWithSameSnapshotNodeId();if(!this._cycledWithAncestorGridNode) this.updateHasChildren();var data=this.data;data["count"]="";data["addedCount"]="";data["removedCount"]="";data["countDelta"]="";data["addedSize"]="";data["removedSize"]="";data["sizeDelta"]="";} WebInspector.HeapSnapshotObjectNode.prototype={retainersDataSource:function() {return{snapshot:this._snapshot,snapshotNodeIndex:this.snapshotNodeIndex};},createProvider:function() {return this._snapshot.createEdgesProvider(this.snapshotNodeIndex);},_findAncestorWithSameSnapshotNodeId:function() {var ancestor=this._parentObjectNode;while(ancestor){if(ancestor.snapshotNodeId===this.snapshotNodeId) return ancestor;ancestor=ancestor._parentObjectNode;} return null;},_createChildNode:function(item) {return new WebInspector.HeapSnapshotObjectNode(this._dataGrid,this._snapshot,item,this);},_childHashForEntity:function(edge) {return edge.edgeIndex;},_childHashForNode:function(childNode) {return childNode._edgeIndex;},comparator:function() {var sortAscending=this._dataGrid.isSortOrderAscending();var sortColumnIdentifier=this._dataGrid.sortColumnIdentifier();var sortFields={object:["!edgeName",sortAscending,"retainedSize",false],count:["!edgeName",true,"retainedSize",false],shallowSize:["selfSize",sortAscending,"!edgeName",true],retainedSize:["retainedSize",sortAscending,"!edgeName",true],distance:["distance",sortAscending,"_name",true]}[sortColumnIdentifier]||["!edgeName",true,"retainedSize",false];return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);},_prefixObjectCell:function(div) {var name=this._referenceName||"(empty)";var nameClass="name";switch(this._referenceType){case"context":nameClass="object-value-number";break;case"internal":case"hidden":case"weak":nameClass="object-value-null";break;case"element":name="["+name+"]";break;} if(this._cycledWithAncestorGridNode) div.className+=" cycled-ancessor-node";var nameSpan=createElement("span");nameSpan.className=nameClass;nameSpan.textContent=name;div.appendChild(nameSpan);var separatorSpan=createElement("span");separatorSpan.className="grayed";separatorSpan.textContent=this._edgeNodeSeparator();div.appendChild(separatorSpan);},_edgeNodeSeparator:function() {return" :: ";},__proto__:WebInspector.HeapSnapshotGenericObjectNode.prototype} WebInspector.HeapSnapshotRetainingObjectNode=function(dataGrid,snapshot,edge,parentRetainingObjectNode) {WebInspector.HeapSnapshotObjectNode.call(this,dataGrid,snapshot,edge,parentRetainingObjectNode);} WebInspector.HeapSnapshotRetainingObjectNode.prototype={createProvider:function() {return this._snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex);},_createChildNode:function(item) {return new WebInspector.HeapSnapshotRetainingObjectNode(this._dataGrid,this._snapshot,item,this);},_edgeNodeSeparator:function() {return" in ";},expand:function() {this._expandRetainersChain(20);},_expandRetainersChain:function(maxExpandLevels) {function populateComplete() {this.removeEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete,populateComplete,this);this._expandRetainersChain(maxExpandLevels);} if(!this._populated){this.addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete,populateComplete,this);this.populate();return;} WebInspector.HeapSnapshotGenericObjectNode.prototype.expand.call(this);if(--maxExpandLevels>0&&this.children.length>0){var retainer=this.children[0];if(retainer._distance>1){retainer._expandRetainersChain(maxExpandLevels);return;}} this._dataGrid.dispatchEventToListeners(WebInspector.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);},__proto__:WebInspector.HeapSnapshotObjectNode.prototype} WebInspector.HeapSnapshotInstanceNode=function(dataGrid,snapshot,node,isDeletedNode) {WebInspector.HeapSnapshotGenericObjectNode.call(this,dataGrid,node);this._baseSnapshotOrSnapshot=snapshot;this._isDeletedNode=isDeletedNode;this.updateHasChildren();var data=this.data;data["count"]="";data["countDelta"]="";data["sizeDelta"]="";if(this._isDeletedNode){data["addedCount"]="";data["addedSize"]="";data["removedCount"]="\u2022";data["removedSize"]=Number.withThousandsSeparator(this._shallowSize);}else{data["addedCount"]="\u2022";data["addedSize"]=Number.withThousandsSeparator(this._shallowSize);data["removedCount"]="";data["removedSize"]="";}};WebInspector.HeapSnapshotInstanceNode.prototype={retainersDataSource:function() {return{snapshot:this._baseSnapshotOrSnapshot,snapshotNodeIndex:this.snapshotNodeIndex};},createProvider:function() {return this._baseSnapshotOrSnapshot.createEdgesProvider(this.snapshotNodeIndex);},_createChildNode:function(item) {return new WebInspector.HeapSnapshotObjectNode(this._dataGrid,this._baseSnapshotOrSnapshot,item,null);},_childHashForEntity:function(edge) {return edge.edgeIndex;},_childHashForNode:function(childNode) {return childNode._edgeIndex;},comparator:function() {var sortAscending=this._dataGrid.isSortOrderAscending();var sortColumnIdentifier=this._dataGrid.sortColumnIdentifier();var sortFields={object:["!edgeName",sortAscending,"retainedSize",false],distance:["distance",sortAscending,"retainedSize",false],count:["!edgeName",true,"retainedSize",false],addedSize:["selfSize",sortAscending,"!edgeName",true],removedSize:["selfSize",sortAscending,"!edgeName",true],shallowSize:["selfSize",sortAscending,"!edgeName",true],retainedSize:["retainedSize",sortAscending,"!edgeName",true]}[sortColumnIdentifier]||["!edgeName",true,"retainedSize",false];return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);},__proto__:WebInspector.HeapSnapshotGenericObjectNode.prototype} WebInspector.HeapSnapshotConstructorNode=function(dataGrid,className,aggregate,nodeFilter) {WebInspector.HeapSnapshotGridNode.call(this,dataGrid,aggregate.count>0);this._name=className;this._nodeFilter=nodeFilter;this._distance=aggregate.distance;this._count=aggregate.count;this._shallowSize=aggregate.self;this._retainedSize=aggregate.maxRet;var snapshot=dataGrid.snapshot;var countPercent=this._count/snapshot.nodeCount*100.0;var retainedSizePercent=this._retainedSize/snapshot.totalSize*100.0;var shallowSizePercent=this._shallowSize/snapshot.totalSize*100.0;this.data={"object":className,"count":Number.withThousandsSeparator(this._count),"distance":this._toUIDistance(this._distance),"shallowSize":Number.withThousandsSeparator(this._shallowSize),"retainedSize":Number.withThousandsSeparator(this._retainedSize),"count-percent":this._toPercentString(countPercent),"shallowSize-percent":this._toPercentString(shallowSizePercent),"retainedSize-percent":this._toPercentString(retainedSizePercent)};} WebInspector.HeapSnapshotConstructorNode.prototype={createProvider:function() {return this._dataGrid.snapshot.createNodesProviderForClass(this._name,this._nodeFilter)},populateNodeBySnapshotObjectId:function(snapshotObjectId) {function didExpand() {return this._provider().nodePosition(snapshotObjectId).then(didGetNodePosition.bind(this));} function didGetNodePosition(nodePosition) {if(nodePosition===-1){this.collapse();return Promise.resolve([]);}else{function action(fulfill) {this._populateChildren(nodePosition,null,didPopulateChildren.bind(this,nodePosition,fulfill));} return new Promise(action.bind(this));}} function didPopulateChildren(nodePosition,callback) {var node=(this.childForPosition(nodePosition));callback(node?[this,node]:[]);} this._dataGrid.resetNameFilter();return this.expandWithoutPopulate().then(didExpand.bind(this));},filteredOut:function(filterValue) {return this._name.toLowerCase().indexOf(filterValue)===-1;},createCell:function(columnIdentifier) {var cell=columnIdentifier!=="object"?this._createValueCell(columnIdentifier):WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this,columnIdentifier);if(this._searchMatched) cell.classList.add("highlight");return cell;},_createChildNode:function(item) {return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid,this._dataGrid.snapshot,item,false);},comparator:function() {var sortAscending=this._dataGrid.isSortOrderAscending();var sortColumnIdentifier=this._dataGrid.sortColumnIdentifier();var sortFields={object:["name",sortAscending,"id",true],distance:["distance",sortAscending,"retainedSize",false],count:["name",true,"id",true],shallowSize:["selfSize",sortAscending,"id",true],retainedSize:["retainedSize",sortAscending,"id",true]}[sortColumnIdentifier];return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);},_childHashForEntity:function(node) {return node.id;},_childHashForNode:function(childNode) {return childNode.snapshotNodeId;},__proto__:WebInspector.HeapSnapshotGridNode.prototype} WebInspector.HeapSnapshotDiffNodesProvider=function(addedNodesProvider,deletedNodesProvider,addedCount,removedCount) {this._addedNodesProvider=addedNodesProvider;this._deletedNodesProvider=deletedNodesProvider;this._addedCount=addedCount;this._removedCount=removedCount;} WebInspector.HeapSnapshotDiffNodesProvider.prototype={dispose:function() {this._addedNodesProvider.dispose();this._deletedNodesProvider.dispose();},nodePosition:function(snapshotObjectId) {throw new Error("Unreachable");},isEmpty:function(callback) {callback(false);},serializeItemsRange:function(beginPosition,endPosition,callback) {function didReceiveAllItems(items) {items.totalLength=this._addedCount+this._removedCount;callback(items);} function didReceiveDeletedItems(addedItems,itemsRange) {var items=itemsRange.items;if(!addedItems.items.length) addedItems.startPosition=this._addedCount+itemsRange.startPosition;for(var i=0;i<items.length;i++){items[i].isAddedNotRemoved=false;addedItems.items.push(items[i]);} addedItems.endPosition=this._addedCount+itemsRange.endPosition;didReceiveAllItems.call(this,addedItems);} function didReceiveAddedItems(itemsRange) {var items=itemsRange.items;for(var i=0;i<items.length;i++) items[i].isAddedNotRemoved=true;if(itemsRange.endPosition<endPosition) return this._deletedNodesProvider.serializeItemsRange(0,endPosition-itemsRange.endPosition,didReceiveDeletedItems.bind(this,itemsRange));itemsRange.totalLength=this._addedCount+this._removedCount;didReceiveAllItems.call(this,itemsRange);} if(beginPosition<this._addedCount){this._addedNodesProvider.serializeItemsRange(beginPosition,endPosition,didReceiveAddedItems.bind(this));}else{var emptyRange=new WebInspector.HeapSnapshotCommon.ItemsRange(0,0,0,[]);this._deletedNodesProvider.serializeItemsRange(beginPosition-this._addedCount,endPosition-this._addedCount,didReceiveDeletedItems.bind(this,emptyRange));}},sortAndRewind:function(comparator) {function afterSort() {return this._deletedNodesProvider.sortAndRewind(comparator);} return this._addedNodesProvider.sortAndRewind(comparator).then(afterSort.bind(this));}};WebInspector.HeapSnapshotDiffNode=function(dataGrid,className,diffForClass) {WebInspector.HeapSnapshotGridNode.call(this,dataGrid,true);this._name=className;this._addedCount=diffForClass.addedCount;this._removedCount=diffForClass.removedCount;this._countDelta=diffForClass.countDelta;this._addedSize=diffForClass.addedSize;this._removedSize=diffForClass.removedSize;this._sizeDelta=diffForClass.sizeDelta;this._deletedIndexes=diffForClass.deletedIndexes;this.data={"object":className,"addedCount":Number.withThousandsSeparator(this._addedCount),"removedCount":Number.withThousandsSeparator(this._removedCount),"countDelta":this._signForDelta(this._countDelta)+Number.withThousandsSeparator(Math.abs(this._countDelta)),"addedSize":Number.withThousandsSeparator(this._addedSize),"removedSize":Number.withThousandsSeparator(this._removedSize),"sizeDelta":this._signForDelta(this._sizeDelta)+Number.withThousandsSeparator(Math.abs(this._sizeDelta))};} WebInspector.HeapSnapshotDiffNode.prototype={createProvider:function() {var tree=this._dataGrid;return new WebInspector.HeapSnapshotDiffNodesProvider(tree.snapshot.createAddedNodesProvider(tree.baseSnapshot.uid,this._name),tree.baseSnapshot.createDeletedNodesProvider(this._deletedIndexes),this._addedCount,this._removedCount);},createCell:function(columnIdentifier) {var cell=WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this,columnIdentifier);if(columnIdentifier!=="object") cell.classList.add("numeric-column");return cell;},_createChildNode:function(item) {if(item.isAddedNotRemoved) return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid,this._dataGrid.snapshot,item,false);else return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid,this._dataGrid.baseSnapshot,item,true);},_childHashForEntity:function(node) {return node.id;},_childHashForNode:function(childNode) {return childNode.snapshotNodeId;},comparator:function() {var sortAscending=this._dataGrid.isSortOrderAscending();var sortColumnIdentifier=this._dataGrid.sortColumnIdentifier();var sortFields={object:["name",sortAscending,"id",true],addedCount:["name",true,"id",true],removedCount:["name",true,"id",true],countDelta:["name",true,"id",true],addedSize:["selfSize",sortAscending,"id",true],removedSize:["selfSize",sortAscending,"id",true],sizeDelta:["selfSize",sortAscending,"id",true]}[sortColumnIdentifier];return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);},filteredOut:function(filterValue) {return this._name.toLowerCase().indexOf(filterValue)===-1;},_signForDelta:function(delta) {if(delta===0) return"";if(delta>0) return"+";else return"\u2212";},__proto__:WebInspector.HeapSnapshotGridNode.prototype} WebInspector.AllocationGridNode=function(dataGrid,data) {WebInspector.HeapSnapshotGridNode.call(this,dataGrid,data.hasChildren);this._populated=false;this._allocationNode=data;this.data={"liveCount":Number.withThousandsSeparator(data.liveCount),"count":Number.withThousandsSeparator(data.count),"liveSize":Number.withThousandsSeparator(data.liveSize),"size":Number.withThousandsSeparator(data.size),"name":data.name};} WebInspector.AllocationGridNode.prototype={populate:function() {if(this._populated) return;this._populated=true;this._dataGrid.snapshot.allocationNodeCallers(this._allocationNode.id,didReceiveCallers.bind(this));function didReceiveCallers(callers) {var callersChain=callers.nodesWithSingleCaller;var parentNode=this;var dataGrid=(this._dataGrid);for(var i=0;i<callersChain.length;i++){var child=new WebInspector.AllocationGridNode(dataGrid,callersChain[i]);dataGrid.appendNode(parentNode,child);parentNode=child;parentNode._populated=true;if(this.expanded) parentNode.expand();} var callersBranch=callers.branchingCallers;callersBranch.sort(this._dataGrid._createComparator());for(var i=0;i<callersBranch.length;i++) dataGrid.appendNode(parentNode,new WebInspector.AllocationGridNode(dataGrid,callersBranch[i]));dataGrid.updateVisibleNodes(true);}},expand:function() {WebInspector.HeapSnapshotGridNode.prototype.expand.call(this);if(this.children.length===1) this.children[0].expand();},createCell:function(columnIdentifier) {if(columnIdentifier!=="name") return this._createValueCell(columnIdentifier);var cell=WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this,columnIdentifier);var allocationNode=this._allocationNode;var target=this._dataGrid.target();if(allocationNode.scriptId){var linkifier=this._dataGrid._linkifier;var urlElement=linkifier.linkifyScriptLocation(target,String(allocationNode.scriptId),allocationNode.scriptName,allocationNode.line-1,allocationNode.column-1,"profile-node-file");urlElement.style.maxWidth="75%";cell.insertBefore(urlElement,cell.firstChild);} return cell;},allocationNodeId:function() {return this._allocationNode.id;},__proto__:WebInspector.HeapSnapshotGridNode.prototype};WebInspector.HeapSnapshotView=function(dataDisplayDelegate,profile) {WebInspector.VBox.call(this);this.element.classList.add("heap-snapshot-view");profile.profileType().addEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived,this._onReceiveSnapshot,this);profile.profileType().addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader,this._onProfileHeaderRemoved,this);var isHeapTimeline=profile.profileType().id===WebInspector.TrackingHeapSnapshotProfileType.TypeId;if(isHeapTimeline){this._trackingOverviewGrid=new WebInspector.HeapTrackingOverviewGrid(profile);this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged,this._onIdsRangeChanged.bind(this));} this._parentDataDisplayDelegate=dataDisplayDelegate;this._searchableView=new WebInspector.SearchableView(this);this._searchableView.show(this.element);this._splitWidget=new WebInspector.SplitWidget(false,true,"heapSnapshotSplitViewState",200,200);this._splitWidget.show(this._searchableView.element);this._containmentDataGrid=new WebInspector.HeapSnapshotContainmentDataGrid(this);this._containmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._selectionChanged,this);this._containmentWidget=this._containmentDataGrid.asWidget();this._containmentWidget.setMinimumSize(50,25);this._statisticsView=new WebInspector.HeapSnapshotStatisticsView();this._constructorsDataGrid=new WebInspector.HeapSnapshotConstructorsDataGrid(this);this._constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._selectionChanged,this);this._constructorsWidget=this._constructorsDataGrid.asWidget();this._constructorsWidget.setMinimumSize(50,25);this._diffDataGrid=new WebInspector.HeapSnapshotDiffDataGrid(this);this._diffDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._selectionChanged,this);this._diffWidget=this._diffDataGrid.asWidget();this._diffWidget.setMinimumSize(50,25);if(isHeapTimeline&&WebInspector.moduleSetting("recordAllocationStacks").get()){this._allocationDataGrid=new WebInspector.AllocationDataGrid(profile.target(),this);this._allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._onSelectAllocationNode,this);this._allocationWidget=this._allocationDataGrid.asWidget();this._allocationWidget.setMinimumSize(50,25);this._allocationStackView=new WebInspector.HeapAllocationStackView(profile.target());this._allocationStackView.setMinimumSize(50,25);this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.headerElement().classList.add("heap-object-details-header");} this._retainmentDataGrid=new WebInspector.HeapSnapshotRetainmentDataGrid(this);this._retainmentWidget=this._retainmentDataGrid.asWidget();this._retainmentWidget.setMinimumSize(50,21);this._retainmentWidget.element.classList.add("retaining-paths-view");var splitWidgetResizer;if(this._allocationStackView){this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.headerElement().classList.add("heap-object-details-header");this._tabbedPane.appendTab("retainers",WebInspector.UIString("Retainers"),this._retainmentWidget);this._tabbedPane.appendTab("allocation-stack",WebInspector.UIString("Allocation stack"),this._allocationStackView);splitWidgetResizer=this._tabbedPane.headerElement();this._objectDetailsView=this._tabbedPane;}else{var retainmentViewHeader=createElementWithClass("div","heap-snapshot-view-resizer");var retainingPathsTitleDiv=retainmentViewHeader.createChild("div","title");var retainingPathsTitle=retainingPathsTitleDiv.createChild("span");retainingPathsTitle.textContent=WebInspector.UIString("Retainers");splitWidgetResizer=retainmentViewHeader;this._objectDetailsView=new WebInspector.VBox();this._objectDetailsView.element.appendChild(retainmentViewHeader);this._retainmentWidget.show(this._objectDetailsView.element);} this._splitWidget.hideDefaultResizer();this._splitWidget.installResizer(splitWidgetResizer);this._retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._inspectedObjectChanged,this);this._retainmentDataGrid.reset();this._perspectives=[];this._perspectives.push(new WebInspector.HeapSnapshotView.SummaryPerspective());if(profile.profileType()!==WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) this._perspectives.push(new WebInspector.HeapSnapshotView.ComparisonPerspective());this._perspectives.push(new WebInspector.HeapSnapshotView.ContainmentPerspective());if(this._allocationWidget) this._perspectives.push(new WebInspector.HeapSnapshotView.AllocationPerspective());this._perspectives.push(new WebInspector.HeapSnapshotView.StatisticsPerspective());this._perspectiveSelect=new WebInspector.ToolbarComboBox(this._onSelectedPerspectiveChanged.bind(this));for(var i=0;i<this._perspectives.length;++i) this._perspectiveSelect.createOption(this._perspectives[i].title());this._profile=profile;this._baseSelect=new WebInspector.ToolbarComboBox(this._changeBase.bind(this));this._baseSelect.setVisible(false);this._updateBaseOptions();this._filterSelect=new WebInspector.ToolbarComboBox(this._changeFilter.bind(this));this._filterSelect.setVisible(false);this._updateFilterOptions();this._classNameFilter=new WebInspector.ToolbarInput("Class filter");this._classNameFilter.setVisible(false);this._constructorsDataGrid.setNameFilter(this._classNameFilter);this._diffDataGrid.setNameFilter(this._classNameFilter);this._selectedSizeText=new WebInspector.ToolbarText();this._popoverHelper=new WebInspector.ObjectPopoverHelper(this.element,this._getHoverAnchor.bind(this),this._resolveObjectForPopover.bind(this),undefined,true);this._currentPerspectiveIndex=0;this._currentPerspective=this._perspectives[0];this._currentPerspective.activate(this);this._dataGrid=this._currentPerspective.masterGrid(this);this._populate();this._searchThrottler=new WebInspector.Throttler(0);} WebInspector.HeapSnapshotView.Perspective=function(title) {this._title=title;} WebInspector.HeapSnapshotView.Perspective.prototype={activate:function(heapSnapshotView){},deactivate:function(heapSnapshotView) {heapSnapshotView._baseSelect.setVisible(false);heapSnapshotView._filterSelect.setVisible(false);heapSnapshotView._classNameFilter.setVisible(false);if(heapSnapshotView._trackingOverviewGrid) heapSnapshotView._trackingOverviewGrid.detach();if(heapSnapshotView._allocationWidget) heapSnapshotView._allocationWidget.detach();if(heapSnapshotView._statisticsView) heapSnapshotView._statisticsView.detach();heapSnapshotView._splitWidget.detach();heapSnapshotView._splitWidget.detachChildWidgets();},masterGrid:function(heapSnapshotView) {return null;},title:function() {return this._title;},supportsSearch:function() {return false;}} WebInspector.HeapSnapshotView.SummaryPerspective=function() {WebInspector.HeapSnapshotView.Perspective.call(this,WebInspector.UIString("Summary"));} WebInspector.HeapSnapshotView.SummaryPerspective.prototype={activate:function(heapSnapshotView) {heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);heapSnapshotView._filterSelect.setVisible(true);heapSnapshotView._classNameFilter.setVisible(true);if(heapSnapshotView._trackingOverviewGrid){heapSnapshotView._trackingOverviewGrid.show(heapSnapshotView._searchableView.element,heapSnapshotView._splitWidget.element);heapSnapshotView._trackingOverviewGrid.update();heapSnapshotView._trackingOverviewGrid._updateGrid();}},masterGrid:function(heapSnapshotView) {return heapSnapshotView._constructorsDataGrid;},supportsSearch:function() {return true;},__proto__:WebInspector.HeapSnapshotView.Perspective.prototype} WebInspector.HeapSnapshotView.ComparisonPerspective=function() {WebInspector.HeapSnapshotView.Perspective.call(this,WebInspector.UIString("Comparison"));} WebInspector.HeapSnapshotView.ComparisonPerspective.prototype={activate:function(heapSnapshotView) {heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget);heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);heapSnapshotView._baseSelect.setVisible(true);heapSnapshotView._classNameFilter.setVisible(true);},masterGrid:function(heapSnapshotView) {return heapSnapshotView._diffDataGrid;},supportsSearch:function() {return true;},__proto__:WebInspector.HeapSnapshotView.Perspective.prototype} WebInspector.HeapSnapshotView.ContainmentPerspective=function() {WebInspector.HeapSnapshotView.Perspective.call(this,WebInspector.UIString("Containment"));} WebInspector.HeapSnapshotView.ContainmentPerspective.prototype={activate:function(heapSnapshotView) {heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget);heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);},masterGrid:function(heapSnapshotView) {return heapSnapshotView._containmentDataGrid;},__proto__:WebInspector.HeapSnapshotView.Perspective.prototype} WebInspector.HeapSnapshotView.AllocationPerspective=function() {WebInspector.HeapSnapshotView.Perspective.call(this,WebInspector.UIString("Allocation"));this._allocationSplitWidget=new WebInspector.SplitWidget(false,true,"heapSnapshotAllocationSplitViewState",200,200);this._allocationSplitWidget.setSidebarWidget(new WebInspector.VBox());} WebInspector.HeapSnapshotView.AllocationPerspective.prototype={activate:function(heapSnapshotView) {this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget);heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);var allocatedObjectsView=new WebInspector.VBox();var resizer=createElementWithClass("div","heap-snapshot-view-resizer");var title=resizer.createChild("div","title").createChild("span");title.textContent=WebInspector.UIString("Live objects");this._allocationSplitWidget.hideDefaultResizer();this._allocationSplitWidget.installResizer(resizer);allocatedObjectsView.element.appendChild(resizer);heapSnapshotView._splitWidget.show(allocatedObjectsView.element);this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView);this._allocationSplitWidget.show(heapSnapshotView._searchableView.element);heapSnapshotView._constructorsDataGrid.clear();var selectedNode=heapSnapshotView._allocationDataGrid.selectedNode;if(selectedNode) heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());},deactivate:function(heapSnapshotView) {this._allocationSplitWidget.detach();WebInspector.HeapSnapshotView.Perspective.prototype.deactivate.call(this,heapSnapshotView);},masterGrid:function(heapSnapshotView) {return heapSnapshotView._allocationDataGrid;},__proto__:WebInspector.HeapSnapshotView.Perspective.prototype} WebInspector.HeapSnapshotView.StatisticsPerspective=function() {WebInspector.HeapSnapshotView.Perspective.call(this,WebInspector.UIString("Statistics"));} WebInspector.HeapSnapshotView.StatisticsPerspective.prototype={activate:function(heapSnapshotView) {heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element);},masterGrid:function(heapSnapshotView) {return null;},__proto__:WebInspector.HeapSnapshotView.Perspective.prototype} WebInspector.HeapSnapshotView.prototype={searchableView:function() {return this._searchableView;},showProfile:function(profile) {return this._parentDataDisplayDelegate.showProfile(profile);},showObject:function(snapshotObjectId,perspectiveName) {if(snapshotObjectId<=this._profile.maxJSObjectId) this.selectLiveObject(perspectiveName,snapshotObjectId);else this._parentDataDisplayDelegate.showObject(snapshotObjectId,perspectiveName);},_populate:function() {this._profile._loadPromise.then(heapSnapshotProxy=>{heapSnapshotProxy.getStatistics().then(this._gotStatistics.bind(this));this._dataGrid.setDataSource(heapSnapshotProxy);if(this._profile.profileType().id===WebInspector.TrackingHeapSnapshotProfileType.TypeId&&this._profile.fromFile()) return heapSnapshotProxy.getSamples().then(samples=>this._trackingOverviewGrid._setSamples(samples));}).then(_=>{var list=this._profiles();var profileIndex=list.indexOf(this._profile);this._baseSelect.setSelectedIndex(Math.max(0,profileIndex-1));if(this._trackingOverviewGrid) this._trackingOverviewGrid._updateGrid();});},_gotStatistics:function(statistics) {this._statisticsView.setTotal(statistics.total);this._statisticsView.addRecord(statistics.code,WebInspector.UIString("Code"),"#f77");this._statisticsView.addRecord(statistics.strings,WebInspector.UIString("Strings"),"#5e5");this._statisticsView.addRecord(statistics.jsArrays,WebInspector.UIString("JS Arrays"),"#7af");this._statisticsView.addRecord(statistics.native,WebInspector.UIString("Typed Arrays"),"#fc5");this._statisticsView.addRecord(statistics.system,WebInspector.UIString("System Objects"),"#98f");this._statisticsView.addRecord(statistics.total,WebInspector.UIString("Total"));},_onIdsRangeChanged:function(event) {var minId=event.data.minId;var maxId=event.data.maxId;this._selectedSizeText.setText(WebInspector.UIString("Selected size: %s",Number.bytesToString(event.data.size)));if(this._constructorsDataGrid.snapshot) this._constructorsDataGrid.setSelectionRange(minId,maxId);},toolbarItems:function() {var result=[this._perspectiveSelect,this._classNameFilter];if(this._profile.profileType()!==WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) result.push(this._baseSelect,this._filterSelect);result.push(this._selectedSizeText);return result;},wasShown:function() {this._profile._loadPromise.then(this._profile._wasShown.bind(this._profile));},willHide:function() {this._currentSearchResultIndex=-1;this._popoverHelper.hidePopover();if(this.helpPopover&&this.helpPopover.isShowing()) this.helpPopover.hide();},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return false;},searchCanceled:function() {this._currentSearchResultIndex=-1;this._searchResults=[];},_selectRevealedNode:function(node) {if(node) node.select();},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var nextQuery=new WebInspector.HeapSnapshotCommon.SearchConfig(searchConfig.query.trim(),searchConfig.caseSensitive,searchConfig.isRegex,shouldJump,jumpBackwards||false);this._searchThrottler.schedule(this._performSearch.bind(this,nextQuery));},_performSearch:function(nextQuery) {this.searchCanceled();if(!this._currentPerspective.supportsSearch()) return Promise.resolve();this.currentQuery=nextQuery;var query=nextQuery.query.trim();if(!query) return Promise.resolve();if(query.charAt(0)==="@"){var snapshotNodeId=parseInt(query.substring(1),10);if(isNaN(snapshotNodeId)) return Promise.resolve();return this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId)).then(this._selectRevealedNode.bind(this));} function didSearch(entryIds) {this._searchResults=entryIds;this._searchableView.updateSearchMatchesCount(this._searchResults.length);if(this._searchResults.length) this._currentSearchResultIndex=nextQuery.jumpBackwards?this._searchResults.length-1:0;return this._jumpToSearchResult(this._currentSearchResultIndex);} return this._profile._snapshotProxy.search(this.currentQuery,this._dataGrid.nodeFilter()).then(didSearch.bind(this));},jumpToNextSearchResult:function() {if(!this._searchResults.length) return;this._currentSearchResultIndex=(this._currentSearchResultIndex+1)%this._searchResults.length;this._searchThrottler.schedule(this._jumpToSearchResult.bind(this,this._currentSearchResultIndex));},jumpToPreviousSearchResult:function() {if(!this._searchResults.length) return;this._currentSearchResultIndex=(this._currentSearchResultIndex+this._searchResults.length-1)%this._searchResults.length;this._searchThrottler.schedule(this._jumpToSearchResult.bind(this,this._currentSearchResultIndex));},_jumpToSearchResult:function(searchResultIndex) {this._searchableView.updateCurrentMatchIndex(searchResultIndex);return this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex])).then(this._selectRevealedNode.bind(this));},refreshVisibleData:function() {if(!this._dataGrid) return;var child=this._dataGrid.rootNode().children[0];while(child){child.refresh();child=child.traverseNextNode(false,null,true);}},_changeBase:function() {if(this._baseProfile===this._profiles()[this._baseSelect.selectedIndex()]) return;this._baseProfile=this._profiles()[this._baseSelect.selectedIndex()];var dataGrid=(this._dataGrid);if(dataGrid.snapshot) this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid));if(!this.currentQuery||!this._searchResults) return;this.performSearch(this.currentQuery,false);},_changeFilter:function() {var profileIndex=this._filterSelect.selectedIndex()-1;this._dataGrid.filterSelectIndexChanged(this._profiles(),profileIndex);if(!this.currentQuery||!this._searchResults) return;this.performSearch(this.currentQuery,false);},_profiles:function() {return this._profile.profileType().getProfiles();},populateContextMenu:function(contextMenu,event) {if(this._dataGrid) this._dataGrid.populateContextMenu(contextMenu,event);},_selectionChanged:function(event) {var selectedNode=event.target.selectedNode;this._setSelectedNodeForDetailsView(selectedNode);this._inspectedObjectChanged(event);},_onSelectAllocationNode:function(event) {var selectedNode=event.target.selectedNode;this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());this._setSelectedNodeForDetailsView(null);},_inspectedObjectChanged:function(event) {var selectedNode=event.target.selectedNode;var target=this._profile.target();if(target&&selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode) target.heapProfilerAgent().addInspectedHeapObject(String(selectedNode.snapshotNodeId));},_setSelectedNodeForDetailsView:function(nodeItem) {var dataSource=nodeItem&&nodeItem.retainersDataSource();if(dataSource){this._retainmentDataGrid.setDataSource(dataSource.snapshot,dataSource.snapshotNodeIndex);if(this._allocationStackView) this._allocationStackView.setAllocatedObject(dataSource.snapshot,dataSource.snapshotNodeIndex);}else{if(this._allocationStackView) this._allocationStackView.clear();this._retainmentDataGrid.reset();}},_changePerspectiveAndWait:function(perspectiveTitle,callback) {var perspectiveIndex=null;for(var i=0;i<this._perspectives.length;++i){if(this._perspectives[i].title()===perspectiveTitle){perspectiveIndex=i;break;}} if(this._currentPerspectiveIndex===perspectiveIndex||perspectiveIndex===null){setTimeout(callback,0);return;} function dataGridContentShown(event) {var dataGrid=event.data;dataGrid.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown,dataGridContentShown,this);if(dataGrid===this._dataGrid) callback();} this._perspectives[perspectiveIndex].masterGrid(this).addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown,dataGridContentShown,this);this._perspectiveSelect.setSelectedIndex(perspectiveIndex);this._changePerspective(perspectiveIndex);},_updateDataSourceAndView:function() {var dataGrid=this._dataGrid;if(!dataGrid||dataGrid.snapshot) return;this._profile._loadPromise.then(didLoadSnapshot.bind(this));function didLoadSnapshot(snapshotProxy) {if(this._dataGrid!==dataGrid) return;if(dataGrid.snapshot!==snapshotProxy) dataGrid.setDataSource(snapshotProxy);if(dataGrid===this._diffDataGrid){if(!this._baseProfile) this._baseProfile=this._profiles()[this._baseSelect.selectedIndex()];this._baseProfile._loadPromise.then(didLoadBaseSnaphot.bind(this));}} function didLoadBaseSnaphot(baseSnapshotProxy) {if(this._diffDataGrid.baseSnapshot!==baseSnapshotProxy) this._diffDataGrid.setBaseDataSource(baseSnapshotProxy);}},_onSelectedPerspectiveChanged:function(event) {this._changePerspective(event.target.selectedIndex);},_changePerspective:function(selectedIndex) {if(selectedIndex===this._currentPerspectiveIndex) return;this._currentPerspectiveIndex=selectedIndex;this._currentPerspective.deactivate(this);var perspective=this._perspectives[selectedIndex];this._currentPerspective=perspective;this._dataGrid=perspective.masterGrid(this);perspective.activate(this);this.refreshVisibleData();if(this._dataGrid) this._dataGrid.updateWidths();this._updateDataSourceAndView();if(!this.currentQuery||!this._searchResults) return;this.performSearch(this.currentQuery,false);},selectLiveObject:function(perspectiveName,snapshotObjectId) {this._changePerspectiveAndWait(perspectiveName,didChangePerspective.bind(this));function didChangePerspective() {this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId,didRevealObject);} function didRevealObject(node) {if(node) node.select();else WebInspector.console.error("Cannot find corresponding heap snapshot node");}},_getHoverAnchor:function(target) {var span=target.enclosingNodeOrSelfWithNodeName("span");if(!span) return;var row=target.enclosingNodeOrSelfWithNodeName("tr");if(!row) return;span.node=row._dataGridNode;return span;},_resolveObjectForPopover:function(element,showCallback,objectGroupName) {if(!this._profile.target()) return;if(!element.node) return;element.node.queryObjectContent(this._profile.target(),showCallback,objectGroupName);},_updateBaseOptions:function() {var list=this._profiles();if(this._baseSelect.size()===list.length) return;for(var i=this._baseSelect.size(),n=list.length;i<n;++i){var title=list[i].title;this._baseSelect.createOption(title);}},_updateFilterOptions:function() {var list=this._profiles();if(this._filterSelect.size()-1===list.length) return;if(!this._filterSelect.size()) this._filterSelect.createOption(WebInspector.UIString("All objects"));for(var i=this._filterSelect.size()-1,n=list.length;i<n;++i){var title=list[i].title;if(!i) title=WebInspector.UIString("Objects allocated before %s",title);else title=WebInspector.UIString("Objects allocated between %s and %s",list[i-1].title,title);this._filterSelect.createOption(title);}},_updateControls:function() {this._updateBaseOptions();this._updateFilterOptions();},_onReceiveSnapshot:function(event) {this._updateControls();},_onProfileHeaderRemoved:function(event) {var profile=event.data;if(this._profile===profile){this.detach();this._profile.profileType().removeEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived,this._onReceiveSnapshot,this);this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader,this._onProfileHeaderRemoved,this);this.dispose();}else{this._updateControls();}},dispose:function() {if(this._allocationStackView){this._allocationStackView.clear();this._allocationDataGrid.dispose();} if(this._trackingOverviewGrid) this._trackingOverviewGrid.dispose();},__proto__:WebInspector.VBox.prototype} WebInspector.HeapSnapshotProfileType=function(id,title) {WebInspector.ProfileType.call(this,id||WebInspector.HeapSnapshotProfileType.TypeId,title||WebInspector.UIString("Take Heap Snapshot"));WebInspector.targetManager.observeTargets(this);WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel,WebInspector.HeapProfilerModel.Events.ResetProfiles,this._resetProfiles,this);WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel,WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk,this._addHeapSnapshotChunk,this);WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel,WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress,this._reportHeapSnapshotProgress,this);} WebInspector.HeapSnapshotProfileType.TypeId="HEAP";WebInspector.HeapSnapshotProfileType.SnapshotReceived="SnapshotReceived";WebInspector.HeapSnapshotProfileType.prototype={targetAdded:function(target) {target.heapProfilerModel.enable();},targetRemoved:function(target) {},fileExtension:function() {return".heapsnapshot";},get buttonTooltip() {return WebInspector.UIString("Take heap snapshot");},isInstantProfile:function() {return true;},buttonClicked:function() {this._takeHeapSnapshot(function(){});WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesHeapProfileTaken);return false;},get treeItemTitle() {return WebInspector.UIString("HEAP SNAPSHOTS");},get description() {return WebInspector.UIString("Heap snapshot profiles show memory distribution among your page's JavaScript objects and related DOM nodes.");},createProfileLoadedFromFile:function(title) {return new WebInspector.HeapProfileHeader(null,this,title);},_takeHeapSnapshot:function(callback) {if(this.profileBeingRecorded()) return;var target=(WebInspector.context.flavor(WebInspector.Target));var profile=new WebInspector.HeapProfileHeader(target,this);this.setProfileBeingRecorded(profile);this.addProfile(profile);profile.updateStatus(WebInspector.UIString("Snapshotting\u2026"));function didTakeHeapSnapshot(error) {var profile=this._profileBeingRecorded;profile.title=WebInspector.UIString("Snapshot %d",profile.uid);profile._finishLoad();this.setProfileBeingRecorded(null);this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete,profile);callback();} target.heapProfilerAgent().takeHeapSnapshot(true,didTakeHeapSnapshot.bind(this));},_addHeapSnapshotChunk:function(event) {if(!this.profileBeingRecorded()) return;var chunk=(event.data);this.profileBeingRecorded().transferChunk(chunk);},_reportHeapSnapshotProgress:function(event) {var profile=this.profileBeingRecorded();if(!profile) return;var data=(event.data);profile.updateStatus(WebInspector.UIString("%.0f%%",(data.done/data.total)*100),true);if(data.finished) profile._prepareToLoad();},_resetProfiles:function() {this._reset();},_snapshotReceived:function(profile) {if(this._profileBeingRecorded===profile) this.setProfileBeingRecorded(null);this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived,profile);},__proto__:WebInspector.ProfileType.prototype} WebInspector.TrackingHeapSnapshotProfileType=function() {WebInspector.HeapSnapshotProfileType.call(this,WebInspector.TrackingHeapSnapshotProfileType.TypeId,WebInspector.UIString("Record Allocation Timeline"));} WebInspector.TrackingHeapSnapshotProfileType.TypeId="HEAP-RECORD";WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate="HeapStatsUpdate";WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted="TrackingStarted";WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped="TrackingStopped";WebInspector.TrackingHeapSnapshotProfileType.Samples=function() {this.sizes=[];this.ids=[];this.timestamps=[];this.max=[];this.totalTime=30000;} WebInspector.TrackingHeapSnapshotProfileType.prototype={targetAdded:function(target) {WebInspector.HeapSnapshotProfileType.prototype.targetAdded.call(this,target);target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate,this._heapStatsUpdate,this);target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId,this._lastSeenObjectId,this);},targetRemoved:function(target) {WebInspector.HeapSnapshotProfileType.prototype.targetRemoved.call(this,target);target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate,this._heapStatsUpdate,this);target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId,this._lastSeenObjectId,this);},_heapStatsUpdate:function(event) {if(!this._profileSamples) return;var samples=(event.data);var index;for(var i=0;i<samples.length;i+=3){index=samples[i];var size=samples[i+2];this._profileSamples.sizes[index]=size;if(!this._profileSamples.max[index]) this._profileSamples.max[index]=size;}},_lastSeenObjectId:function(event) {var profileSamples=this._profileSamples;if(!profileSamples) return;var data=(event.data);var currentIndex=Math.max(profileSamples.ids.length,profileSamples.max.length-1);profileSamples.ids[currentIndex]=data.lastSeenObjectId;if(!profileSamples.max[currentIndex]){profileSamples.max[currentIndex]=0;profileSamples.sizes[currentIndex]=0;} profileSamples.timestamps[currentIndex]=data.timestamp;if(profileSamples.totalTime<data.timestamp-profileSamples.timestamps[0]) profileSamples.totalTime*=2;this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate,this._profileSamples);this._profileBeingRecorded.updateStatus(null,true);},hasTemporaryView:function() {return true;},get buttonTooltip() {return this._recording?WebInspector.UIString("Stop recording heap profile"):WebInspector.UIString("Start recording heap profile");},isInstantProfile:function() {return false;},buttonClicked:function() {return this._toggleRecording();},_startRecordingProfile:function() {if(this.profileBeingRecorded()) return;this._addNewProfile();var recordAllocationStacks=WebInspector.moduleSetting("recordAllocationStacks").get();this.profileBeingRecorded().target().heapProfilerAgent().startTrackingHeapObjects(recordAllocationStacks);},_addNewProfile:function() {var target=WebInspector.context.flavor(WebInspector.Target);this.setProfileBeingRecorded(new WebInspector.HeapProfileHeader(target,this,undefined));this._profileSamples=new WebInspector.TrackingHeapSnapshotProfileType.Samples();this._profileBeingRecorded._profileSamples=this._profileSamples;this._recording=true;this.addProfile(this._profileBeingRecorded);this._profileBeingRecorded.updateStatus(WebInspector.UIString("Recording\u2026"));this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted);},_stopRecordingProfile:function() {this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026"));function didTakeHeapSnapshot(error) {var profile=this.profileBeingRecorded();if(!profile) return;profile._finishLoad();this._profileSamples=null;this.setProfileBeingRecorded(null);this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete,profile);} this._profileBeingRecorded.target().heapProfilerAgent().stopTrackingHeapObjects(true,didTakeHeapSnapshot.bind(this));this._recording=false;this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped);},_toggleRecording:function() {if(this._recording) this._stopRecordingProfile();else this._startRecordingProfile();return this._recording;},fileExtension:function() {return".heaptimeline";},get treeItemTitle() {return WebInspector.UIString("ALLOCATION TIMELINES");},get description() {return WebInspector.UIString("Allocation timelines show memory allocations from your heap over time. Use this profile type to isolate memory leaks.");},_resetProfiles:function() {var wasRecording=this._recording;this.setProfileBeingRecorded(null);WebInspector.HeapSnapshotProfileType.prototype._resetProfiles.call(this);this._profileSamples=null;if(wasRecording) this._addNewProfile();},profileBeingRecordedRemoved:function() {this._stopRecordingProfile();this._profileSamples=null;},__proto__:WebInspector.HeapSnapshotProfileType.prototype} WebInspector.HeapProfileHeader=function(target,type,title) {WebInspector.ProfileHeader.call(this,target,type,title||WebInspector.UIString("Snapshot %d",type.nextProfileUid()));this.maxJSObjectId=-1;this._workerProxy=null;this._receiver=null;this._snapshotProxy=null;this._loadPromise=new Promise(loadResolver.bind(this));this._totalNumberOfChunks=0;this._bufferedWriter=null;function loadResolver(fulfill) {this._fulfillLoad=fulfill;}} WebInspector.HeapProfileHeader.prototype={createSidebarTreeElement:function(dataDisplayDelegate) {return new WebInspector.ProfileSidebarTreeElement(dataDisplayDelegate,this,"heap-snapshot-sidebar-tree-item");},createView:function(dataDisplayDelegate) {return new WebInspector.HeapSnapshotView(dataDisplayDelegate,this);},_prepareToLoad:function() {console.assert(!this._receiver,"Already loading");this._setupWorker();this.updateStatus(WebInspector.UIString("Loading\u2026"),true);},_finishLoad:function() {if(!this._wasDisposed) this._receiver.close();if(this._bufferedWriter){this._bufferedWriter.finishWriting(this._didWriteToTempFile.bind(this));this._bufferedWriter=null;}},_didWriteToTempFile:function(tempFile) {if(this._wasDisposed){if(tempFile) tempFile.remove();return;} this._tempFile=tempFile;if(!tempFile) this._failedToCreateTempFile=true;if(this._onTempFileReady){this._onTempFileReady();this._onTempFileReady=null;}},_setupWorker:function() {function setProfileWait(event) {this.updateStatus(null,event.data);} console.assert(!this._workerProxy,"HeapSnapshotWorkerProxy already exists");this._workerProxy=new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));this._workerProxy.addEventListener("wait",setProfileWait,this);this._receiver=this._workerProxy.createLoader(this.uid,this._snapshotReceived.bind(this));},_handleWorkerEvent:function(eventName,data) {if(WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot===eventName){var error=(data);WebInspector.console.error(error);return;} if(WebInspector.HeapSnapshotProgressEvent.Update!==eventName) return;var subtitle=(data);this.updateStatus(subtitle);},dispose:function() {if(this._workerProxy) this._workerProxy.dispose();this.removeTempFile();this._wasDisposed=true;},_didCompleteSnapshotTransfer:function() {if(!this._snapshotProxy) return;this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize),false);},transferChunk:function(chunk) {if(!this._bufferedWriter) this._bufferedWriter=new WebInspector.DeferredTempFile("heap-profiler",String(this.uid));this._bufferedWriter.write([chunk]);++this._totalNumberOfChunks;this._receiver.write(chunk);},_snapshotReceived:function(snapshotProxy) {if(this._wasDisposed) return;this._receiver=null;this._snapshotProxy=snapshotProxy;this.maxJSObjectId=snapshotProxy.maxJSObjectId();this._didCompleteSnapshotTransfer();this._workerProxy.startCheckingForLongRunningCalls();this.notifySnapshotReceived();},notifySnapshotReceived:function() {this._fulfillLoad(this._snapshotProxy);this._profileType._snapshotReceived(this);if(this.canSaveToFile()) this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);},_wasShown:function() {},canSaveToFile:function() {return!this.fromFile()&&!!this._snapshotProxy;},saveToFile:function() {var fileOutputStream=new WebInspector.FileOutputStream();function onOpen(accepted) {if(!accepted) return;if(this._failedToCreateTempFile){WebInspector.console.error("Failed to open temp file with heap snapshot");fileOutputStream.close();}else if(this._tempFile){var delegate=new WebInspector.SaveSnapshotOutputStreamDelegate(this);this._tempFile.copyToOutputStream(fileOutputStream,delegate);}else{this._onTempFileReady=onOpen.bind(this,accepted);this._updateSaveProgress(0,1);}} this._fileName=this._fileName||"Heap-"+new Date().toISO8601Compact()+this._profileType.fileExtension();fileOutputStream.open(this._fileName,onOpen.bind(this));},_updateSaveProgress:function(value,total) {var percentValue=((total?(value/total):0)*100).toFixed(0);this.updateStatus(WebInspector.UIString("Saving\u2026 %d%%",percentValue));},loadFromFile:function(file) {this.updateStatus(WebInspector.UIString("Loading\u2026"),true);this._setupWorker();var delegate=new WebInspector.HeapSnapshotLoadFromFileDelegate(this);var fileReader=this._createFileReader(file,delegate);fileReader.start(this._receiver);},_createFileReader:function(file,delegate) {return new WebInspector.ChunkedFileReader(file,10000000,delegate);},__proto__:WebInspector.ProfileHeader.prototype} WebInspector.HeapSnapshotLoadFromFileDelegate=function(snapshotHeader) {this._snapshotHeader=snapshotHeader;} WebInspector.HeapSnapshotLoadFromFileDelegate.prototype={onTransferStarted:function() {},onChunkTransferred:function(reader) {},onTransferFinished:function() {},onError:function(reader,e) {var subtitle;switch(e.target.error.code){case e.target.error.NOT_FOUND_ERR:subtitle=WebInspector.UIString("'%s' not found.",reader.fileName());break;case e.target.error.NOT_READABLE_ERR:subtitle=WebInspector.UIString("'%s' is not readable",reader.fileName());break;case e.target.error.ABORT_ERR:return;default:subtitle=WebInspector.UIString("'%s' error %d",reader.fileName(),e.target.error.code);} this._snapshotHeader.updateStatus(subtitle);}} WebInspector.SaveSnapshotOutputStreamDelegate=function(profileHeader) {this._profileHeader=profileHeader;} WebInspector.SaveSnapshotOutputStreamDelegate.prototype={onTransferStarted:function() {this._profileHeader._updateSaveProgress(0,1);},onTransferFinished:function() {this._profileHeader._didCompleteSnapshotTransfer();},onChunkTransferred:function(reader) {this._profileHeader._updateSaveProgress(reader.loadedSize(),reader.fileSize());},onError:function(reader,event) {WebInspector.console.error("Failed to read heap snapshot from temp file: "+(event).message);this.onTransferFinished();}} WebInspector.HeapTrackingOverviewGrid=function(heapProfileHeader) {WebInspector.VBox.call(this);this.element.id="heap-recording-view";this.element.classList.add("heap-tracking-overview");this._overviewContainer=this.element.createChild("div","heap-overview-container");this._overviewGrid=new WebInspector.OverviewGrid("heap-recording");this._overviewGrid.element.classList.add("fill");this._overviewCanvas=this._overviewContainer.createChild("canvas","heap-recording-overview-canvas");this._overviewContainer.appendChild(this._overviewGrid.element);this._overviewCalculator=new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator();this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);this._profileSamples=heapProfileHeader.fromFile()?new WebInspector.TrackingHeapSnapshotProfileType.Samples():heapProfileHeader._profileSamples;this._profileType=heapProfileHeader.profileType();if(!heapProfileHeader.fromFile()&&heapProfileHeader.profileType().profileBeingRecorded()===heapProfileHeader){this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate,this._onHeapStatsUpdate,this);this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped,this._onStopTracking,this);} this._windowLeft=0.0;this._windowRight=1.0;this._overviewGrid.setWindow(this._windowLeft,this._windowRight);this._yScale=new WebInspector.HeapTrackingOverviewGrid.SmoothScale();this._xScale=new WebInspector.HeapTrackingOverviewGrid.SmoothScale();} WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged="IdsRangeChanged";WebInspector.HeapTrackingOverviewGrid.prototype={dispose:function() {this._onStopTracking();},_onStopTracking:function() {this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate,this._onHeapStatsUpdate,this);this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped,this._onStopTracking,this);},_onHeapStatsUpdate:function(event) {this._profileSamples=event.data;this._scheduleUpdate();},_setSamples:function(samples) {if(!samples) return;console.assert(!this._profileSamples.timestamps.length,"Should only call this method when loading from file.");console.assert(samples.timestamps.length);this._profileSamples=new WebInspector.TrackingHeapSnapshotProfileType.Samples();this._profileSamples.sizes=samples.sizes;this._profileSamples.ids=samples.lastAssignedIds;this._profileSamples.timestamps=samples.timestamps;this._profileSamples.max=samples.sizes;this._profileSamples.totalTime=(samples.timestamps.peekLast());this.update();},_drawOverviewCanvas:function(width,height) {if(!this._profileSamples) return;var profileSamples=this._profileSamples;var sizes=profileSamples.sizes;var topSizes=profileSamples.max;var timestamps=profileSamples.timestamps;var startTime=timestamps[0];var endTime=timestamps[timestamps.length-1];var scaleFactor=this._xScale.nextScale(width/profileSamples.totalTime);var maxSize=0;function aggregateAndCall(sizes,callback) {var size=0;var currentX=0;for(var i=1;i<timestamps.length;++i){var x=Math.floor((timestamps[i]-startTime)*scaleFactor);if(x!==currentX){if(size) callback(currentX,size);size=0;currentX=x;} size+=sizes[i];} callback(currentX,size);} function maxSizeCallback(x,size) {maxSize=Math.max(maxSize,size);} aggregateAndCall(sizes,maxSizeCallback);var yScaleFactor=this._yScale.nextScale(maxSize?height/(maxSize*1.1):0.0);this._overviewCanvas.width=width*window.devicePixelRatio;this._overviewCanvas.height=height*window.devicePixelRatio;this._overviewCanvas.style.width=width+"px";this._overviewCanvas.style.height=height+"px";var context=this._overviewCanvas.getContext("2d");context.scale(window.devicePixelRatio,window.devicePixelRatio);context.beginPath();context.lineWidth=2;context.strokeStyle="rgba(192, 192, 192, 0.6)";var currentX=(endTime-startTime)*scaleFactor;context.moveTo(currentX,height-1);context.lineTo(currentX,0);context.stroke();context.closePath();var gridY;var gridValue;var gridLabelHeight=14;if(yScaleFactor){const maxGridValue=(height-gridLabelHeight)/yScaleFactor;gridValue=Math.pow(1024,Math.floor(Math.log(maxGridValue)/Math.log(1024)));gridValue*=Math.pow(10,Math.floor(Math.log(maxGridValue/gridValue)/Math.LN10));if(gridValue*5<=maxGridValue) gridValue*=5;gridY=Math.round(height-gridValue*yScaleFactor-0.5)+0.5;context.beginPath();context.lineWidth=1;context.strokeStyle="rgba(0, 0, 0, 0.2)";context.moveTo(0,gridY);context.lineTo(width,gridY);context.stroke();context.closePath();} function drawBarCallback(x,size) {context.moveTo(x,height-1);context.lineTo(x,Math.round(height-size*yScaleFactor-1));} context.beginPath();context.lineWidth=2;context.strokeStyle="rgba(192, 192, 192, 0.6)";aggregateAndCall(topSizes,drawBarCallback);context.stroke();context.closePath();context.beginPath();context.lineWidth=2;context.strokeStyle="rgba(0, 0, 192, 0.8)";aggregateAndCall(sizes,drawBarCallback);context.stroke();context.closePath();if(gridValue){var label=Number.bytesToString(gridValue);var labelPadding=4;var labelX=0;var labelY=gridY-0.5;var labelWidth=2*labelPadding+context.measureText(label).width;context.beginPath();context.textBaseline="bottom";context.font="10px "+window.getComputedStyle(this.element,null).getPropertyValue("font-family");context.fillStyle="rgba(255, 255, 255, 0.75)";context.fillRect(labelX,labelY-gridLabelHeight,labelWidth,gridLabelHeight);context.fillStyle="rgb(64, 64, 64)";context.fillText(label,labelX+labelPadding,labelY);context.fill();context.closePath();}},onResize:function() {this._updateOverviewCanvas=true;this._scheduleUpdate();},_onWindowChanged:function() {if(!this._updateGridTimerId) this._updateGridTimerId=setTimeout(this._updateGrid.bind(this),10);},_scheduleUpdate:function() {if(this._updateTimerId) return;this._updateTimerId=setTimeout(this.update.bind(this),10);},_updateBoundaries:function() {this._windowLeft=this._overviewGrid.windowLeft();this._windowRight=this._overviewGrid.windowRight();this._windowWidth=this._windowRight-this._windowLeft;},update:function() {this._updateTimerId=null;if(!this.isShowing()) return;this._updateBoundaries();this._overviewCalculator._updateBoundaries(this);this._overviewGrid.updateDividers(this._overviewCalculator);this._drawOverviewCanvas(this._overviewContainer.clientWidth,this._overviewContainer.clientHeight-20);},_updateGrid:function() {this._updateGridTimerId=0;this._updateBoundaries();var ids=this._profileSamples.ids;var timestamps=this._profileSamples.timestamps;var sizes=this._profileSamples.sizes;var startTime=timestamps[0];var totalTime=this._profileSamples.totalTime;var timeLeft=startTime+totalTime*this._windowLeft;var timeRight=startTime+totalTime*this._windowRight;var minId=0;var maxId=ids[ids.length-1]+1;var size=0;for(var i=0;i<timestamps.length;++i){if(!timestamps[i]) continue;if(timestamps[i]>timeRight) break;maxId=ids[i];if(timestamps[i]<timeLeft){minId=ids[i];continue;} size+=sizes[i];} this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged,{minId:minId,maxId:maxId,size:size});},__proto__:WebInspector.VBox.prototype} WebInspector.HeapTrackingOverviewGrid.SmoothScale=function() {this._lastUpdate=0;this._currentScale=0.0;} WebInspector.HeapTrackingOverviewGrid.SmoothScale.prototype={nextScale:function(target){target=target||this._currentScale;if(this._currentScale){var now=Date.now();var timeDeltaMs=now-this._lastUpdate;this._lastUpdate=now;var maxChangePerSec=20;var maxChangePerDelta=Math.pow(maxChangePerSec,timeDeltaMs/1000);var scaleChange=target/this._currentScale;this._currentScale*=Number.constrain(scaleChange,1/maxChangePerDelta,maxChangePerDelta);}else{this._currentScale=target;} return this._currentScale;}} WebInspector.HeapTrackingOverviewGrid.OverviewCalculator=function() {} WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype={paddingLeft:function() {return 0;},_updateBoundaries:function(chart) {this._minimumBoundaries=0;this._maximumBoundaries=chart._profileSamples.totalTime;this._xScaleFactor=chart._overviewContainer.clientWidth/this._maximumBoundaries;},computePosition:function(time) {return(time-this._minimumBoundaries)*this._xScaleFactor;},formatValue:function(value,precision) {return Number.secondsToString(value/1000,!!precision);},maximumBoundary:function() {return this._maximumBoundaries;},minimumBoundary:function() {return this._minimumBoundaries;},zeroTime:function() {return this._minimumBoundaries;},boundarySpan:function() {return this._maximumBoundaries-this._minimumBoundaries;}} WebInspector.HeapSnapshotStatisticsView=function() {WebInspector.VBox.call(this);this.setMinimumSize(50,25);this._pieChart=new WebInspector.PieChart(150,WebInspector.HeapSnapshotStatisticsView._valueFormatter,true);this._pieChart.element.classList.add("heap-snapshot-stats-pie-chart");this.element.appendChild(this._pieChart.element);this._labels=this.element.createChild("div","heap-snapshot-stats-legend");} WebInspector.HeapSnapshotStatisticsView._valueFormatter=function(value) {return WebInspector.UIString("%s KB",Number.withThousandsSeparator(Math.round(value/1024)));} WebInspector.HeapSnapshotStatisticsView.prototype={setTotal:function(value) {this._pieChart.setTotal(value);},addRecord:function(value,name,color) {if(color) this._pieChart.addSlice(value,color);var node=this._labels.createChild("div");var swatchDiv=node.createChild("div","heap-snapshot-stats-swatch");var nameDiv=node.createChild("div","heap-snapshot-stats-name");var sizeDiv=node.createChild("div","heap-snapshot-stats-size");if(color) swatchDiv.style.backgroundColor=color;else swatchDiv.classList.add("heap-snapshot-stats-empty-swatch");nameDiv.textContent=name;sizeDiv.textContent=WebInspector.HeapSnapshotStatisticsView._valueFormatter(value);},__proto__:WebInspector.VBox.prototype} WebInspector.HeapAllocationStackView=function(target) {WebInspector.Widget.call(this);this._target=target;;this._linkifier=new WebInspector.Linkifier();} WebInspector.HeapAllocationStackView.prototype={setAllocatedObject:function(snapshot,snapshotNodeIndex) {this.clear();snapshot.allocationStack(snapshotNodeIndex,this._didReceiveAllocationStack.bind(this));},clear:function() {this.element.removeChildren();this._linkifier.reset();},_didReceiveAllocationStack:function(frames) {if(!frames){var stackDiv=this.element.createChild("div","no-heap-allocation-stack");stackDiv.createTextChild(WebInspector.UIString("Stack was not recorded for this object because it had been allocated before this profile recording started."));return;} var stackDiv=this.element.createChild("div","heap-allocation-stack");for(var i=0;i<frames.length;i++){var frame=frames[i];var frameDiv=stackDiv.createChild("div","stack-frame");var name=frameDiv.createChild("div");name.textContent=WebInspector.beautifyFunctionName(frame.functionName);if(frame.scriptId){var urlElement=this._linkifier.linkifyScriptLocation(this._target,String(frame.scriptId),frame.scriptName,frame.line-1,frame.column-1);frameDiv.appendChild(urlElement);}}},__proto__:WebInspector.Widget.prototype};WebInspector.ProfileLauncherView=function(profilesPanel) {WebInspector.VBox.call(this);this._panel=profilesPanel;this.element.classList.add("profile-launcher-view");this.element.classList.add("panel-enabler-view");this._contentElement=this.element.createChild("div","profile-launcher-view-content");this._innerContentElement=this._contentElement.createChild("div");var targetSpan=this._contentElement.createChild("span");var selectTargetText=targetSpan.createChild("span");selectTargetText.textContent=WebInspector.UIString("Target:");var targetsSelect=targetSpan.createChild("select","chrome-select");new WebInspector.TargetsComboBoxController(targetsSelect,targetSpan);this._controlButton=createTextButton("",this._controlButtonClicked.bind(this),"control-profiling");this._contentElement.appendChild(this._controlButton);this._recordButtonEnabled=true;this._loadButton=createTextButton(WebInspector.UIString("Load"),this._loadButtonClicked.bind(this),"load-profile");this._contentElement.appendChild(this._loadButton);WebInspector.targetManager.observeTargets(this);} WebInspector.ProfileLauncherView.prototype={searchableView:function() {return null;},targetAdded:function(target) {this._updateLoadButtonLayout();},targetRemoved:function(target) {this._updateLoadButtonLayout();},_updateLoadButtonLayout:function() {this._loadButton.classList.toggle("multi-target",WebInspector.targetManager.targetsWithJSContext().length>1);},addProfileType:function(profileType) {var descriptionElement=this._innerContentElement.createChild("h1");descriptionElement.textContent=profileType.description;var decorationElement=profileType.decorationElement();if(decorationElement) this._innerContentElement.appendChild(decorationElement);this._isInstantProfile=profileType.isInstantProfile();this._isEnabled=profileType.isEnabled();},_controlButtonClicked:function() {this._panel.toggleRecord();},_loadButtonClicked:function() {this._panel.showLoadFromFileDialog();},_updateControls:function() {if(this._isEnabled&&this._recordButtonEnabled) this._controlButton.removeAttribute("disabled");else this._controlButton.setAttribute("disabled","");this._controlButton.title=this._recordButtonEnabled?"":WebInspector.anotherProfilerActiveLabel();if(this._isInstantProfile){this._controlButton.classList.remove("running");this._controlButton.textContent=WebInspector.UIString("Take Snapshot");}else if(this._isProfiling){this._controlButton.classList.add("running");this._controlButton.textContent=WebInspector.UIString("Stop");}else{this._controlButton.classList.remove("running");this._controlButton.textContent=WebInspector.UIString("Start");}},profileStarted:function() {this._isProfiling=true;this._updateControls();},profileFinished:function() {this._isProfiling=false;this._updateControls();},updateProfileType:function(profileType,recordButtonEnabled) {this._isInstantProfile=profileType.isInstantProfile();this._recordButtonEnabled=recordButtonEnabled;this._isEnabled=profileType.isEnabled();this._updateControls();},__proto__:WebInspector.VBox.prototype} WebInspector.MultiProfileLauncherView=function(profilesPanel) {WebInspector.ProfileLauncherView.call(this,profilesPanel);this._selectedProfileTypeSetting=WebInspector.settings.createSetting("selectedProfileType","CPU");var header=this._innerContentElement.createChild("h1");header.textContent=WebInspector.UIString("Select profiling type");this._profileTypeSelectorForm=this._innerContentElement.createChild("form");this._innerContentElement.createChild("div","flexible-space");this._typeIdToOptionElement={};} WebInspector.MultiProfileLauncherView.EventTypes={ProfileTypeSelected:"profile-type-selected"} WebInspector.MultiProfileLauncherView.prototype={addProfileType:function(profileType) {var labelElement=createRadioLabel("profile-type",profileType.name);this._profileTypeSelectorForm.appendChild(labelElement);var optionElement=labelElement.radioElement;this._typeIdToOptionElement[profileType.id]=optionElement;optionElement._profileType=profileType;optionElement.style.hidden=true;optionElement.addEventListener("change",this._profileTypeChanged.bind(this,profileType),false);var descriptionElement=labelElement.createChild("p");descriptionElement.textContent=profileType.description;var decorationElement=profileType.decorationElement();if(decorationElement) labelElement.appendChild(decorationElement);},restoreSelectedProfileType:function() {var typeId=this._selectedProfileTypeSetting.get();if(!(typeId in this._typeIdToOptionElement)) typeId=Object.keys(this._typeIdToOptionElement)[0];this._typeIdToOptionElement[typeId].checked=true;var type=this._typeIdToOptionElement[typeId]._profileType;this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected,type);},_controlButtonClicked:function() {this._panel.toggleRecord();},_updateControls:function() {WebInspector.ProfileLauncherView.prototype._updateControls.call(this);var items=this._profileTypeSelectorForm.elements;for(var i=0;i<items.length;++i){if(items[i].type==="radio") items[i].disabled=this._isProfiling;}},_profileTypeChanged:function(profileType) {this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected,profileType);this._isInstantProfile=profileType.isInstantProfile();this._isEnabled=profileType.isEnabled();this._updateControls();this._selectedProfileTypeSetting.set(profileType.id);},profileStarted:function() {this._isProfiling=true;this._updateControls();},profileFinished:function() {this._isProfiling=false;this._updateControls();},__proto__:WebInspector.ProfileLauncherView.prototype};WebInspector.ProfileTypeRegistry=function() {this._profileTypes=[];this.cpuProfileType=new WebInspector.CPUProfileType();this._addProfileType(this.cpuProfileType);this.heapSnapshotProfileType=new WebInspector.HeapSnapshotProfileType();this._addProfileType(this.heapSnapshotProfileType);this.trackingHeapSnapshotProfileType=new WebInspector.TrackingHeapSnapshotProfileType();this._addProfileType(this.trackingHeapSnapshotProfileType);this.samplingHeapProfileType=new WebInspector.SamplingHeapProfileType();this._addProfileType(this.samplingHeapProfileType);} WebInspector.ProfileTypeRegistry.prototype={_addProfileType:function(profileType) {this._profileTypes.push(profileType);},profileTypes:function() {return this._profileTypes;}} WebInspector.ProfileTypeRegistry.instance=new WebInspector.ProfileTypeRegistry();;WebInspector.TargetsComboBoxController=function(selectElement,elementToHide) {elementToHide.classList.add("hidden");selectElement.addEventListener("change",this._onComboBoxSelectionChange.bind(this),false);this._selectElement=selectElement;this._elementToHide=elementToHide;this._targetToOption=new Map();WebInspector.context.addFlavorChangeListener(WebInspector.Target,this._targetChangedExternally,this);WebInspector.targetManager.observeTargets(this);} WebInspector.TargetsComboBoxController.prototype={targetAdded:function(target) {if(!target.hasJSContext()) return;var option=this._selectElement.createChild("option");option.text=target.name();option.__target=target;this._targetToOption.set(target,option);if(WebInspector.context.flavor(WebInspector.Target)===target) this._selectElement.selectedIndex=Array.prototype.indexOf.call((this._selectElement),option);this._updateVisibility();},targetRemoved:function(target) {if(!target.hasJSContext()) return;var option=this._targetToOption.remove(target);this._selectElement.removeChild(option);this._updateVisibility();},_onComboBoxSelectionChange:function() {var selectedOption=this._selectElement[this._selectElement.selectedIndex];if(!selectedOption) return;WebInspector.context.setFlavor(WebInspector.Target,selectedOption.__target);},_updateVisibility:function() {var hidden=this._selectElement.childElementCount===1;this._elementToHide.classList.toggle("hidden",hidden);},_targetChangedExternally:function(event) {var target=(event.data);if(target){var option=(this._targetToOption.get(target));this._select(option);}},_select:function(option) {this._selectElement.selectedIndex=Array.prototype.indexOf.call((this._selectElement),option);}};Runtime.cachedResources["profiler/heapProfiler.css"]="/*\n * Copyright (C) 2009 Google Inc. All rights reserved.\n * Copyright (C) 2010 Apple Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.heap-snapshot-sidebar-tree-item .icon {\n content: url(Images/profileIcon.png);\n}\n\n.heap-snapshot-sidebar-tree-item.small .icon {\n content: url(Images/profileSmallIcon.png);\n}\n\n.heap-snapshot-view {\n overflow: hidden;\n}\n\n.heap-snapshot-view .data-grid {\n border: none;\n}\n\n.heap-snapshot-view .data-grid tr:empty {\n height: 16px;\n visibility: hidden;\n}\n\n.heap-snapshot-view .data-grid span.percent-column {\n width: 32px;\n}\n\n.heap-snapshot-view .object-value-object,\n.object-value-node {\n display: inline;\n position: static;\n}\n\n.detached-dom-tree-node {\n background-color: #FF9999;\n}\n\n.heap-snapshot-view .object-value-string {\n white-space: nowrap;\n}\n\n.heap-snapshot-view tr:not(.selected) .object-value-id {\n color: grey;\n}\n\n.heap-snapshot-view .data-grid {\n flex: auto;\n}\n\n.heap-snapshot-view .heap-tracking-overview {\n flex: 0 0 80px;\n height: 80px;\n}\n\n.heap-snapshot-view .retaining-paths-view {\n overflow: hidden;\n}\n\n.heap-snapshot-view .heap-snapshot-view-resizer {\n background-image: url(Images/toolbarResizerVertical.png);\n background-color: #eee;\n border-bottom: 1px solid rgb(179, 179, 179);\n background-repeat: no-repeat;\n background-position: right center, center;\n flex: 0 0 21px;\n}\n\n.heap-snapshot-view .heap-snapshot-view-resizer .title > span {\n display: inline-block;\n padding-top: 3px;\n vertical-align: middle;\n margin-left: 4px;\n margin-right: 8px;\n}\n\n.heap-snapshot-view .heap-snapshot-view-resizer * {\n pointer-events: none;\n}\n\n.heap-snapshot-view .heap-object-details-header {\n background-color: #eee;\n}\n\n.heap-snapshot-view tr:not(.selected) td.object-column span.highlight {\n background-color: rgb(255, 255, 200);\n}\n\n.heap-snapshot-view td.object-column span.grayed {\n color: gray;\n}\n\n.cycled-ancessor-node {\n opacity: 0.6;\n}\n\n#heap-recording-view .heap-snapshot-view {\n top: 80px;\n}\n\n.heap-overview-container {\n overflow: hidden;\n position: absolute;\n top: 0;\n width: 100%;\n height: 80px;\n}\n\n#heap-recording-overview-grid .resources-dividers-label-bar {\n pointer-events: auto;\n}\n\n#heap-recording-overview-container {\n border-bottom: 1px solid rgba(0, 0, 0, 0.3);\n}\n\n.heap-recording-overview-canvas {\n position: absolute;\n top: 20px;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\n.heap-snapshot-stats-pie-chart {\n margin: 12px 30px;\n}\n\n.heap-snapshot-stats-legend {\n margin-left: 24px;\n}\n\n.heap-snapshot-stats-legend > div {\n margin-top: 1px;\n width: 170px;\n}\n\n.heap-snapshot-stats-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border: 1px solid rgba(100, 100, 100, 0.3);\n}\n\n.heap-snapshot-stats-swatch.heap-snapshot-stats-empty-swatch {\n border: none;\n}\n\n.heap-snapshot-stats-name,\n.heap-snapshot-stats-size {\n display: inline-block;\n margin-left: 6px;\n}\n\n.heap-snapshot-stats-size {\n float: right;\n text-align: right;\n}\n\n.heap-allocation-stack .stack-frame {\n display: flex;\n justify-content: space-between;\n border-bottom: 1px solid rgb(240, 240, 240);\n padding: 2px;\n}\n\n.heap-allocation-stack .stack-frame a {\n color: rgb(33%, 33%, 33%);\n}\n\n.no-heap-allocation-stack {\n padding: 5px;\n}\n\n/*# sourceURL=profiler/heapProfiler.css */";Runtime.cachedResources["profiler/profilesPanel.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* Profiler Style */\n\n#profile-views {\n flex: auto;\n position: relative;\n}\n\n.profile-view .data-grid table.data {\n background: white;\n}\n\n.profile-view .data-grid tr:not(.selected) .highlight {\n background-color: rgb(255, 230, 179);\n}\n\n.profile-view .data-grid tr:hover td:not(.bottom-filler-td) {\n background-color: rgba(0, 0, 0, 0.1);\n}\n\n.profile-view .data-grid td.numeric-column {\n text-align: right;\n}\n\n.profile-view .data-grid div.profile-multiple-values {\n float: right;\n}\n\n.profile-view .data-grid span.percent-column {\n color: #999;\n width: 48px;\n display: inline-block;\n}\n\n.profile-view .data-grid tr.selected span {\n color: inherit;\n}\n\n.profiles-toolbar {\n display: flex;\n background-color: #f3f3f3;\n flex: 0 0 25px;\n flex-direction: row;\n border-bottom: 1px solid rgb(202, 202, 202);\n}\n\n.profile-launcher-view-tree-item > .icon {\n width: 4px !important;\n visibility: hidden;\n}\n\n.profiles-sidebar-tree-box {\n overflow: auto;\n flex: auto;\n}\n\n.profiles-sidebar-tree-box > ol {\n overflow: auto;\n flex: auto;\n}\n\n.profile-sidebar-tree-item .icon {\n content: url(Images/profileIcon.png);\n}\n\n.profile-sidebar-tree-item.small .icon {\n content: url(Images/profileSmallIcon.png);\n}\n\n.profile-group-sidebar-tree-item .icon {\n content: url(Images/profileGroupIcon.png);\n}\n\n.sidebar-tree-item .title-container > .save-link {\n text-decoration: underline;\n margin-left: auto;\n display: none;\n}\n\n.sidebar-tree-item.selected .title-container > .save-link {\n display: block;\n}\n\n.profile-view {\n display: flex;\n overflow: hidden;\n}\n\n.profile-view .data-grid {\n border: none;\n flex: auto;\n}\n\n.profile-view .data-grid th.self-column,\n.profile-view .data-grid th.total-column {\n text-align: center;\n}\n\n.profile-node-file {\n float: right;\n color: gray;\n}\n\n.profile-warn-marker {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n background-position: -202px -107px;\n width: 10px;\n height: 10px;\n vertical-align: -1px;\n margin-right: 2px;\n display: inline-block;\n}\n\n.data-grid tr.selected .profile-node-file {\n color: rgb(33%, 33%, 33%);\n}\n\n.data-grid:focus tr.selected .profile-node-file {\n color: white;\n}\n\n.profile-launcher-view-content {\n padding: 0 16px;\n text-align: left;\n}\n\n.control-profiling {\n -webkit-align-self: flex-start;\n margin-right: 50px;\n}\n\n.profile-launcher-view-content h1 {\n padding: 15px 0 10px;\n}\n\n.panel-enabler-view.profile-launcher-view form {\n padding: 0;\n font-size: 13px;\n width: 100%;\n}\n\n.panel-enabler-view.profile-launcher-view label {\n margin: 0;\n}\n\n.profile-launcher-view-content p {\n color: grey;\n margin-top: 1px;\n margin-left: 22px;\n}\n\n.profile-launcher-view-content button.running {\n color: hsl(0, 100%, 58%);\n}\n\n.profile-launcher-view-content button.running:hover {\n color: hsl(0, 100%, 42%);\n}\n\nbody.inactive .profile-launcher-view-content button.running:not(.toolbar-item) {\n color: rgb(220, 130, 130);\n}\n\n.highlighted-row {\n -webkit-animation: row_highlight 2s 0s;\n}\n\n@-webkit-keyframes row_highlight {\n from {background-color: rgba(255, 255, 120, 1); }\n to { background-color: rgba(255, 255, 120, 0); }\n}\n\n.profile-canvas-decoration label[is=dt-icon-label] {\n margin-right: 4px;\n}\n\n.profile-canvas-decoration {\n color: red;\n margin: -14px 0 13px 22px;\n padding-left: 14px;\n}\n\n.profile-canvas-decoration button {\n margin: 0 0 0 10px !important;\n}\n\n.profiles.panel select.chrome-select {\n font-size: 12px;\n width: 150px;\n margin-left: 10px;\n margin-right: 10px;\n}\n\nbutton.load-profile {\n margin-left: 20px;\n}\n\nbutton.load-profile.multi-target {\n display: block;\n margin-top: 14px;\n margin-left: 0;\n}\n\n.cpu-profile-flame-chart-overview-container {\n overflow: hidden;\n position: absolute;\n top: 0;\n width: 100%;\n height: 80px;\n}\n\n#cpu-profile-flame-chart-overview-container {\n border-bottom: 1px solid rgba(0, 0, 0, 0.3);\n}\n\n.cpu-profile-flame-chart-overview-canvas {\n position: absolute;\n top: 20px;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\n#cpu-profile-flame-chart-overview-grid .resources-dividers-label-bar {\n pointer-events: auto;\n}\n\n.cpu-profile-flame-chart-overview-pane {\n flex: 0 0 80px !important;\n}\n\n/*# sourceURL=profiler/profilesPanel.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.AppManifestView=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("resources/appManifestView.css");this._reportView=new WebInspector.ReportView(WebInspector.UIString("App Manifest"));this._reportView.show(this.contentElement);this._errorsSection=this._reportView.appendSection(WebInspector.UIString("Errors and warnings"));this._identitySection=this._reportView.appendSection(WebInspector.UIString("Identity"));var toolbar=this._identitySection.createToolbar();toolbar.renderAsLinks();var addToHomeScreen=new WebInspector.ToolbarButton(WebInspector.UIString("Add to homescreen"),undefined,WebInspector.UIString("Add to homescreen"));addToHomeScreen.addEventListener("click",this._addToHomescreen.bind(this));toolbar.appendToolbarItem(addToHomeScreen);this._presentationSection=this._reportView.appendSection(WebInspector.UIString("Presentation"));this._iconsSection=this._reportView.appendSection(WebInspector.UIString("Icons"));this._nameField=this._identitySection.appendField(WebInspector.UIString("Name"));this._shortNameField=this._identitySection.appendField(WebInspector.UIString("Short name"));this._startURLField=this._presentationSection.appendField(WebInspector.UIString("Start URL"));var themeColorField=this._presentationSection.appendField(WebInspector.UIString("Theme color"));this._themeColorSwatch=WebInspector.ColorSwatch.create();themeColorField.appendChild(this._themeColorSwatch);var backgroundColorField=this._presentationSection.appendField(WebInspector.UIString("Background color"));this._backgroundColorSwatch=WebInspector.ColorSwatch.create();backgroundColorField.appendChild(this._backgroundColorSwatch);this._orientationField=this._presentationSection.appendField(WebInspector.UIString("Orientation"));this._displayField=this._presentationSection.appendField(WebInspector.UIString("Display"));WebInspector.targetManager.observeTargets(this);} WebInspector.AppManifestView.prototype={targetAdded:function(target) {if(this._target) return;this._target=target;this._updateManifest();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._updateManifest,this);},targetRemoved:function(target) {},_updateManifest:function() {this._target.resourceTreeModel.fetchAppManifest(this._renderManifest.bind(this));},_renderManifest:function(url,data,errors) {this._reportView.setURL(url);this._errorsSection.clearContent();this._errorsSection.element.classList.toggle("hidden",!errors.length);for(var error of errors) this._errorsSection.appendRow().appendChild(createLabel(error.message,error.critical?"error-icon":"warning-icon"));if(!data) data="{}";var parsedManifest=JSON.parse(data);this._nameField.textContent=stringProperty("name");this._shortNameField.textContent=stringProperty("short_name");this._startURLField.removeChildren();var startURL=stringProperty("start_url");if(startURL) this._startURLField.appendChild(WebInspector.linkifyResourceAsNode((WebInspector.ParsedURL.completeURL(url,startURL)),undefined,undefined,undefined,undefined,startURL));this._themeColorSwatch.classList.toggle("hidden",!stringProperty("theme_color"));this._themeColorSwatch.setColorText(stringProperty("theme_color")||"white");this._backgroundColorSwatch.classList.toggle("hidden",!stringProperty("background_color"));this._backgroundColorSwatch.setColorText(stringProperty("background_color")||"white");this._orientationField.textContent=stringProperty("orientation");this._displayField.textContent=stringProperty("display");var icons=parsedManifest["icons"]||[];this._iconsSection.clearContent();for(var icon of icons){var title=(icon["sizes"]||"")+"\n"+(icon["type"]||"");var field=this._iconsSection.appendField(title);var imageElement=field.createChild("img");imageElement.style.maxWidth="200px";imageElement.style.maxHeight="200px";imageElement.src=WebInspector.ParsedURL.completeURL(url,icon["src"]);} function stringProperty(name) {var value=parsedManifest[name];if(typeof value!=="string") return"";return value;}},_addToHomescreen:function() {var target=WebInspector.targetManager.mainTarget();if(target&&target.isPage()){target.pageAgent().requestAppBanner();WebInspector.console.show();}},__proto__:WebInspector.VBox.prototype};WebInspector.ApplicationCacheItemsView=function(model,frameId) {WebInspector.VBox.call(this);this._model=model;this.element.classList.add("storage-view","table");this._deleteButton=new WebInspector.ToolbarButton(WebInspector.UIString("Delete"),"delete-toolbar-item");this._deleteButton.setVisible(false);this._deleteButton.addEventListener("click",this._deleteButtonClicked,this);this._connectivityIcon=createElement("label","dt-icon-label");this._connectivityIcon.style.margin="0 2px 0 5px";this._statusIcon=createElement("label","dt-icon-label");this._statusIcon.style.margin="0 2px 0 5px";this._frameId=frameId;this._emptyWidget=new WebInspector.EmptyWidget(WebInspector.UIString("No Application Cache information available."));this._emptyWidget.show(this.element);this._markDirty();var status=this._model.frameManifestStatus(frameId);this.updateStatus(status);this.updateNetworkState(this._model.onLine);this._deleteButton.element.style.display="none";} WebInspector.ApplicationCacheItemsView.prototype={toolbarItems:function() {return[this._deleteButton,new WebInspector.ToolbarItem(this._connectivityIcon),new WebInspector.ToolbarSeparator(),new WebInspector.ToolbarItem(this._statusIcon)];},wasShown:function() {this._maybeUpdate();},willHide:function() {this._deleteButton.setVisible(false);},_maybeUpdate:function() {if(!this.isShowing()||!this._viewDirty) return;this._update();this._viewDirty=false;},_markDirty:function() {this._viewDirty=true;},updateStatus:function(status) {var oldStatus=this._status;this._status=status;var statusInformation={};statusInformation[applicationCache.UNCACHED]={type:"red-ball",text:"UNCACHED"};statusInformation[applicationCache.IDLE]={type:"green-ball",text:"IDLE"};statusInformation[applicationCache.CHECKING]={type:"orange-ball",text:"CHECKING"};statusInformation[applicationCache.DOWNLOADING]={type:"orange-ball",text:"DOWNLOADING"};statusInformation[applicationCache.UPDATEREADY]={type:"green-ball",text:"UPDATEREADY"};statusInformation[applicationCache.OBSOLETE]={type:"red-ball",text:"OBSOLETE"};var info=statusInformation[status]||statusInformation[applicationCache.UNCACHED];this._statusIcon.type=info.type;this._statusIcon.textContent=info.text;if(this.isShowing()&&this._status===applicationCache.IDLE&&(oldStatus===applicationCache.UPDATEREADY||!this._resources)) this._markDirty();this._maybeUpdate();},updateNetworkState:function(isNowOnline) {if(isNowOnline){this._connectivityIcon.type="green-ball";this._connectivityIcon.textContent=WebInspector.UIString("Online");}else{this._connectivityIcon.type="red-ball";this._connectivityIcon.textContent=WebInspector.UIString("Offline");}},_update:function() {this._model.requestApplicationCache(this._frameId,this._updateCallback.bind(this));},_updateCallback:function(applicationCache) {if(!applicationCache||!applicationCache.manifestURL){delete this._manifest;delete this._creationTime;delete this._updateTime;delete this._size;delete this._resources;this._emptyWidget.show(this.element);this._deleteButton.setVisible(false);if(this._dataGrid) this._dataGrid.element.classList.add("hidden");return;} this._manifest=applicationCache.manifestURL;this._creationTime=applicationCache.creationTime;this._updateTime=applicationCache.updateTime;this._size=applicationCache.size;this._resources=applicationCache.resources;if(!this._dataGrid) this._createDataGrid();this._populateDataGrid();this._dataGrid.autoSizeColumns(20,80);this._dataGrid.element.classList.remove("hidden");this._emptyWidget.detach();this._deleteButton.setVisible(true);},_createDataGrid:function() {var columns=[{title:WebInspector.UIString("Resource"),sort:WebInspector.DataGrid.Order.Ascending,sortable:true},{title:WebInspector.UIString("Type"),sortable:true},{title:WebInspector.UIString("Size"),align:WebInspector.DataGrid.Align.Right,sortable:true}];this._dataGrid=new WebInspector.DataGrid(columns);this._dataGrid.asWidget().show(this.element);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._populateDataGrid,this);},_populateDataGrid:function() {var selectedResource=this._dataGrid.selectedNode?this._dataGrid.selectedNode.resource:null;var sortDirection=this._dataGrid.isSortOrderAscending()?1:-1;function numberCompare(field,resource1,resource2) {return sortDirection*(resource1[field]-resource2[field]);} function localeCompare(field,resource1,resource2) {return sortDirection*(resource1[field]+"").localeCompare(resource2[field]+"");} var comparator;switch(parseInt(this._dataGrid.sortColumnIdentifier(),10)){case 0:comparator=localeCompare.bind(null,"name");break;case 1:comparator=localeCompare.bind(null,"type");break;case 2:comparator=numberCompare.bind(null,"size");break;default:localeCompare.bind(null,"resource");} this._resources.sort(comparator);this._dataGrid.rootNode().removeChildren();var nodeToSelect;for(var i=0;i<this._resources.length;++i){var data={};var resource=this._resources[i];data[0]=resource.url;data[1]=resource.type;data[2]=Number.bytesToString(resource.size);var node=new WebInspector.DataGridNode(data);node.resource=resource;node.selectable=true;this._dataGrid.rootNode().appendChild(node);if(resource===selectedResource){nodeToSelect=node;nodeToSelect.selected=true;}} if(!nodeToSelect&&this._dataGrid.rootNode().children.length) this._dataGrid.rootNode().children[0].selected=true;},_deleteButtonClicked:function(event) {if(!this._dataGrid||!this._dataGrid.selectedNode) return;this._deleteCallback(this._dataGrid.selectedNode);},_deleteCallback:function(node) {},__proto__:WebInspector.VBox.prototype};WebInspector.ClearStorageView=function(resourcesPanel) {WebInspector.VBox.call(this,true);this._resourcesPanel=resourcesPanel;this._reportView=new WebInspector.ReportView(WebInspector.UIString("Clear storage"));this._reportView.registerRequiredCSS("resources/clearStorageView.css");this._reportView.element.classList.add("clear-storage-header");this._reportView.show(this.contentElement);this._settings=new Map();for(var type of[StorageAgent.StorageType.Appcache,StorageAgent.StorageType.Cache_storage,StorageAgent.StorageType.Cookies,StorageAgent.StorageType.Indexeddb,StorageAgent.StorageType.Local_storage,StorageAgent.StorageType.Service_workers,StorageAgent.StorageType.Websql]){this._settings.set(type,WebInspector.settings.createSetting("clear-storage-"+type,true));} var application=this._reportView.appendSection(WebInspector.UIString("Application"));this._appendItem(application,WebInspector.UIString("Unregister service workers"),"service_workers");var storage=this._reportView.appendSection(WebInspector.UIString("Storage"));this._appendItem(storage,WebInspector.UIString("Local and session storage"),"local_storage");this._appendItem(storage,WebInspector.UIString("Indexed DB"),"indexeddb");this._appendItem(storage,WebInspector.UIString("Web SQL"),"websql");this._appendItem(storage,WebInspector.UIString("Cookies"),"cookies");var caches=this._reportView.appendSection(WebInspector.UIString("Cache"));this._appendItem(caches,WebInspector.UIString("Cache storage"),"cache_storage");this._appendItem(caches,WebInspector.UIString("Application cache"),"appcache");WebInspector.targetManager.observeTargets(this);var footer=this._reportView.appendSection("","clear-storage-button").appendRow();this._clearButton=createTextButton(WebInspector.UIString("Clear site data"),this._clear.bind(this),WebInspector.UIString("Clear site data"));footer.appendChild(this._clearButton);} WebInspector.ClearStorageView.prototype={_appendItem:function(section,title,settingName) {var row=section.appendRow();row.appendChild(WebInspector.SettingsUI.createSettingCheckbox(title,this._settings.get(settingName),true));},targetAdded:function(target) {if(this._target) return;this._target=target;this._updateOrigin(target.resourceTreeModel.mainFrame?target.resourceTreeModel.mainFrame.url:"");WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._updateFrame,this);},_updateFrame:function(event) {var frame=(event.data);this._updateOrigin(frame.url);},_updateOrigin:function(url) {this._securityOrigin=new WebInspector.ParsedURL(url).securityOrigin();this._reportView.setSubtitle(this._securityOrigin);},_clear:function() {var storageTypes=[];for(var type of this._settings.keys()){if(this._settings.get(type).get()) storageTypes.push(type);} this._target.storageAgent().clearDataForOrigin(this._securityOrigin,storageTypes.join(","));var set=new Set(storageTypes);var hasAll=set.has(StorageAgent.StorageType.All);if(set.has(StorageAgent.StorageType.Cookies)||hasAll) this._resourcesPanel.clearCookies(this._securityOrigin);if(set.has(StorageAgent.StorageType.Indexeddb)||hasAll){for(var target of WebInspector.targetManager.targets()){var indexedDBModel=WebInspector.IndexedDBModel.fromTarget(target);if(indexedDBModel) indexedDBModel.clearForOrigin(this._securityOrigin);}} if(set.has(StorageAgent.StorageType.Local_storage)||hasAll){var storageModel=WebInspector.DOMStorageModel.fromTarget(this._target);if(storageModel) storageModel.clearForOrigin(this._securityOrigin);} if(set.has(StorageAgent.StorageType.Websql)||hasAll){var databaseModel=WebInspector.DatabaseModel.fromTarget(this._target);if(databaseModel){databaseModel.disable();databaseModel.enable();}} if(set.has(StorageAgent.StorageType.Cache_storage)||hasAll){var target=WebInspector.targetManager.mainTarget();if(target){var model=WebInspector.ServiceWorkerCacheModel.fromTarget(target);if(model) model.clearForOrigin(this._securityOrigin);}} if(set.has(StorageAgent.StorageType.Appcache)||hasAll){var appcacheModel=WebInspector.ApplicationCacheModel.fromTarget(this._target);if(appcacheModel) appcacheModel.reset();} this._clearButton.disabled=true;this._clearButton.textContent=WebInspector.UIString("Clearing...");setTimeout(()=>{this._clearButton.disabled=false;this._clearButton.textContent=WebInspector.UIString("Clear selected");},500);},targetRemoved:function(target) {},__proto__:WebInspector.VBox.prototype};WebInspector.CookieItemsView=function(treeElement,cookieDomain) {WebInspector.VBox.call(this);this.element.classList.add("storage-view");this._deleteButton=new WebInspector.ToolbarButton(WebInspector.UIString("Delete"),"delete-toolbar-item");this._deleteButton.setVisible(false);this._deleteButton.addEventListener("click",this._deleteButtonClicked,this);this._clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear"),"clear-toolbar-item");this._clearButton.setVisible(false);this._clearButton.addEventListener("click",this._clearButtonClicked,this);this._refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this._refreshButton.addEventListener("click",this._refreshButtonClicked,this);this._treeElement=treeElement;this._cookieDomain=cookieDomain;this._emptyWidget=new WebInspector.EmptyWidget(cookieDomain?WebInspector.UIString("This site has no cookies."):WebInspector.UIString("By default cookies are disabled for local files.\nYou could override this by starting the browser with --enable-file-cookies command line flag."));this._emptyWidget.show(this.element);this.element.addEventListener("contextmenu",this._contextMenu.bind(this),true);} WebInspector.CookieItemsView.prototype={toolbarItems:function() {return[this._refreshButton,this._clearButton,this._deleteButton];},wasShown:function() {this._update();},willHide:function() {this._deleteButton.setVisible(false);},_update:function() {WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));},_updateWithCookies:function(allCookies) {this._cookies=this._filterCookiesForDomain(allCookies);if(!this._cookies.length){this._emptyWidget.show(this.element);this._clearButton.setVisible(false);this._deleteButton.setVisible(false);if(this._cookiesTable) this._cookiesTable.detach();return;} if(!this._cookiesTable) this._cookiesTable=new WebInspector.CookiesTable(false,this._update.bind(this),this._showDeleteButton.bind(this));this._cookiesTable.setCookies(this._cookies);this._emptyWidget.detach();this._cookiesTable.show(this.element);this._treeElement.subtitle=String.sprintf(WebInspector.UIString("%d cookies (%s)"),this._cookies.length,Number.bytesToString(this._totalSize));this._clearButton.setVisible(true);this._deleteButton.setVisible(!!this._cookiesTable.selectedCookie());},_filterCookiesForDomain:function(allCookies) {var cookies=[];var resourceURLsForDocumentURL=[];this._totalSize=0;function populateResourcesForDocuments(resource) {var url=resource.documentURL.asParsedURL();if(url&&url.securityOrigin()==this._cookieDomain) resourceURLsForDocumentURL.push(resource.url);} WebInspector.forAllResources(populateResourcesForDocuments.bind(this));for(var i=0;i<allCookies.length;++i){var pushed=false;var size=allCookies[i].size();for(var j=0;j<resourceURLsForDocumentURL.length;++j){var resourceURL=resourceURLsForDocumentURL[j];if(WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i],resourceURL)){this._totalSize+=size;if(!pushed){pushed=true;cookies.push(allCookies[i]);}}}} return cookies;},clear:function() {this._cookiesTable.clear();this._update();},_clearButtonClicked:function() {this.clear();},_showDeleteButton:function() {this._deleteButton.setVisible(true);},_deleteButtonClicked:function() {var selectedCookie=this._cookiesTable.selectedCookie();if(selectedCookie){selectedCookie.remove();this._update();}},_refreshButtonClicked:function(event) {this._update();},_contextMenu:function(event) {if(!this._cookies.length){var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Refresh"),this._update.bind(this));contextMenu.show();}},__proto__:WebInspector.VBox.prototype};WebInspector.Database=function(model,id,domain,name,version) {this._model=model;this._id=id;this._domain=domain;this._name=name;this._version=version;} WebInspector.Database.prototype={get id() {return this._id;},get name() {return this._name;},set name(x) {this._name=x;},get version() {return this._version;},set version(x) {this._version=x;},get domain() {return this._domain;},set domain(x) {this._domain=x;},getTableNames:function(callback) {function sortingCallback(error,names) {if(!error) callback(names.sort());} this._model._agent.getDatabaseTableNames(this._id,sortingCallback);},executeSql:function(query,onSuccess,onError) {function callback(error,columnNames,values,errorObj) {if(error){onError(error);return;} if(errorObj){var message;if(errorObj.message) message=errorObj.message;else if(errorObj.code==2) message=WebInspector.UIString("Database no longer has expected version.");else message=WebInspector.UIString("An unexpected error %s occurred.",errorObj.code);onError(message);return;} onSuccess(columnNames,values);} this._model._agent.executeSQL(this._id,query,callback);}} WebInspector.DatabaseModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.DatabaseModel,target);this._databases=[];this._agent=target.databaseAgent();this.target().registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));} WebInspector.DatabaseModel.Events={DatabaseAdded:"DatabaseAdded",DatabasesRemoved:"DatabasesRemoved"} WebInspector.DatabaseModel.prototype={enable:function() {if(this._enabled) return;this._agent.enable();this._enabled=true;},disable:function() {if(!this._enabled) return;this._enabled=false;this._databases=[];this._agent.disable();this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabasesRemoved);},databases:function() {var result=[];for(var database of this._databases) result.push(database);return result;},_addDatabase:function(database) {this._databases.push(database);this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded,database);},__proto__:WebInspector.SDKModel.prototype} WebInspector.DatabaseDispatcher=function(model) {this._model=model;} WebInspector.DatabaseDispatcher.prototype={addDatabase:function(payload) {this._model._addDatabase(new WebInspector.Database(this._model,payload.id,payload.domain,payload.name,payload.version));}} WebInspector.DatabaseModel._symbol=Symbol("DatabaseModel");WebInspector.DatabaseModel.fromTarget=function(target) {if(!target[WebInspector.DatabaseModel._symbol]) target[WebInspector.DatabaseModel._symbol]=new WebInspector.DatabaseModel(target);return target[WebInspector.DatabaseModel._symbol];};WebInspector.DOMStorage=function(model,securityOrigin,isLocalStorage) {this._model=model;this._securityOrigin=securityOrigin;this._isLocalStorage=isLocalStorage;} WebInspector.DOMStorage.storageId=function(securityOrigin,isLocalStorage) {return{securityOrigin:securityOrigin,isLocalStorage:isLocalStorage};} WebInspector.DOMStorage.Events={DOMStorageItemsCleared:"DOMStorageItemsCleared",DOMStorageItemRemoved:"DOMStorageItemRemoved",DOMStorageItemAdded:"DOMStorageItemAdded",DOMStorageItemUpdated:"DOMStorageItemUpdated"} WebInspector.DOMStorage.prototype={get id() {return WebInspector.DOMStorage.storageId(this._securityOrigin,this._isLocalStorage);},get securityOrigin() {return this._securityOrigin;},get isLocalStorage() {return this._isLocalStorage;},getItems:function(callback) {this._model._agent.getDOMStorageItems(this.id,callback);},setItem:function(key,value) {this._model._agent.setDOMStorageItem(this.id,key,value);},removeItem:function(key) {this._model._agent.removeDOMStorageItem(this.id,key);},__proto__:WebInspector.Object.prototype} WebInspector.DOMStorageModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.DOMStorageModel,target);this._storages={};this._agent=target.domstorageAgent();} WebInspector.DOMStorageModel.Events={DOMStorageAdded:"DOMStorageAdded",DOMStorageRemoved:"DOMStorageRemoved"} WebInspector.DOMStorageModel.prototype={enable:function() {if(this._enabled) return;this.target().registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,this._securityOriginAdded,this);this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,this._securityOriginRemoved,this);this._agent.enable();var securityOrigins=this.target().resourceTreeModel.securityOrigins();for(var i=0;i<securityOrigins.length;++i) this._addOrigin(securityOrigins[i]);this._enabled=true;},clearForOrigin:function(origin) {if(!this._enabled) return;this._removeOrigin(origin);this._addOrigin(origin);},_securityOriginAdded:function(event) {this._addOrigin((event.data));},_addOrigin:function(securityOrigin) {var localStorageKey=this._storageKey(securityOrigin,true);console.assert(!this._storages[localStorageKey]);var localStorage=new WebInspector.DOMStorage(this,securityOrigin,true);this._storages[localStorageKey]=localStorage;this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded,localStorage);var sessionStorageKey=this._storageKey(securityOrigin,false);console.assert(!this._storages[sessionStorageKey]);var sessionStorage=new WebInspector.DOMStorage(this,securityOrigin,false);this._storages[sessionStorageKey]=sessionStorage;this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded,sessionStorage);},_securityOriginRemoved:function(event) {this._removeOrigin((event.data));},_removeOrigin:function(securityOrigin) {var localStorageKey=this._storageKey(securityOrigin,true);var localStorage=this._storages[localStorageKey];console.assert(localStorage);delete this._storages[localStorageKey];this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved,localStorage);var sessionStorageKey=this._storageKey(securityOrigin,false);var sessionStorage=this._storages[sessionStorageKey];console.assert(sessionStorage);delete this._storages[sessionStorageKey];this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved,sessionStorage);},_storageKey:function(securityOrigin,isLocalStorage) {return JSON.stringify(WebInspector.DOMStorage.storageId(securityOrigin,isLocalStorage));},_domStorageItemsCleared:function(storageId) {var domStorage=this.storageForId(storageId);if(!domStorage) return;var eventData={};domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemsCleared,eventData);},_domStorageItemRemoved:function(storageId,key) {var domStorage=this.storageForId(storageId);if(!domStorage) return;var eventData={key:key};domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemRemoved,eventData);},_domStorageItemAdded:function(storageId,key,value) {var domStorage=this.storageForId(storageId);if(!domStorage) return;var eventData={key:key,value:value};domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemAdded,eventData);},_domStorageItemUpdated:function(storageId,key,oldValue,value) {var domStorage=this.storageForId(storageId);if(!domStorage) return;var eventData={key:key,oldValue:oldValue,value:value};domStorage.dispatchEventToListeners(WebInspector.DOMStorage.Events.DOMStorageItemUpdated,eventData);},storageForId:function(storageId) {return this._storages[JSON.stringify(storageId)];},storages:function() {var result=[];for(var id in this._storages) result.push(this._storages[id]);return result;},__proto__:WebInspector.SDKModel.prototype} WebInspector.DOMStorageDispatcher=function(model) {this._model=model;} WebInspector.DOMStorageDispatcher.prototype={domStorageItemsCleared:function(storageId) {this._model._domStorageItemsCleared(storageId);},domStorageItemRemoved:function(storageId,key) {this._model._domStorageItemRemoved(storageId,key);},domStorageItemAdded:function(storageId,key,value) {this._model._domStorageItemAdded(storageId,key,value);},domStorageItemUpdated:function(storageId,key,oldValue,value) {this._model._domStorageItemUpdated(storageId,key,oldValue,value);},} WebInspector.DOMStorageModel._symbol=Symbol("DomStorage");WebInspector.DOMStorageModel.fromTarget=function(target) {if(!target[WebInspector.DOMStorageModel._symbol]) target[WebInspector.DOMStorageModel._symbol]=new WebInspector.DOMStorageModel(target);return target[WebInspector.DOMStorageModel._symbol];};WebInspector.DOMStorageItemsView=function(domStorage) {WebInspector.VBox.call(this);this.domStorage=domStorage;this.element.classList.add("storage-view","table");this.deleteButton=new WebInspector.ToolbarButton(WebInspector.UIString("Delete"),"delete-toolbar-item");this.deleteButton.setVisible(false);this.deleteButton.addEventListener("click",this._deleteButtonClicked,this);this.refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this.refreshButton.addEventListener("click",this._refreshButtonClicked,this);this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemsCleared,this._domStorageItemsCleared,this);this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemRemoved,this._domStorageItemRemoved,this);this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemAdded,this._domStorageItemAdded,this);this.domStorage.addEventListener(WebInspector.DOMStorage.Events.DOMStorageItemUpdated,this._domStorageItemUpdated,this);} WebInspector.DOMStorageItemsView.prototype={toolbarItems:function() {return[this.refreshButton,this.deleteButton];},wasShown:function() {this._update();},willHide:function() {this.deleteButton.setVisible(false);},_domStorageItemsCleared:function(event) {if(!this.isShowing()||!this._dataGrid) return;this._dataGrid.rootNode().removeChildren();this._dataGrid.addCreationNode(false);this.deleteButton.setVisible(false);event.consume(true);},_domStorageItemRemoved:function(event) {if(!this.isShowing()||!this._dataGrid) return;var storageData=event.data;var rootNode=this._dataGrid.rootNode();var children=rootNode.children;event.consume(true);for(var i=0;i<children.length;++i){var childNode=children[i];if(childNode.data.key===storageData.key){rootNode.removeChild(childNode);this.deleteButton.setVisible(children.length>1);return;}}},_domStorageItemAdded:function(event) {if(!this.isShowing()||!this._dataGrid) return;var storageData=event.data;var rootNode=this._dataGrid.rootNode();var children=rootNode.children;event.consume(true);this.deleteButton.setVisible(true);for(var i=0;i<children.length;++i) if(children[i].data.key===storageData.key) return;var childNode=new WebInspector.DataGridNode({key:storageData.key,value:storageData.value},false);rootNode.insertChild(childNode,children.length-1);},_domStorageItemUpdated:function(event) {if(!this.isShowing()||!this._dataGrid) return;var storageData=event.data;var rootNode=this._dataGrid.rootNode();var children=rootNode.children;event.consume(true);var keyFound=false;for(var i=0;i<children.length;++i){var childNode=children[i];if(childNode.data.key===storageData.key){if(keyFound){rootNode.removeChild(childNode);return;} keyFound=true;if(childNode.data.value!==storageData.value){childNode.data.value=storageData.value;childNode.refresh();childNode.select();childNode.reveal();} this.deleteButton.setVisible(true);}}},_update:function() {this.detachChildWidgets();this.domStorage.getItems(this._showDOMStorageItems.bind(this));},_showDOMStorageItems:function(error,items) {if(error) return;this._dataGrid=this._dataGridForDOMStorageItems(items);this._dataGrid.asWidget().show(this.element);this.deleteButton.setVisible(this._dataGrid.rootNode().children.length>1);},_dataGridForDOMStorageItems:function(items) {var columns=[{id:"key",title:WebInspector.UIString("Key"),editable:true,weight:50},{id:"value",title:WebInspector.UIString("Value"),editable:true,weight:50}];var nodes=[];var keys=[];var length=items.length;for(var i=0;i<items.length;i++){var key=items[i][0];var value=items[i][1];var node=new WebInspector.DataGridNode({key:key,value:value},false);node.selectable=true;nodes.push(node);keys.push(key);} var dataGrid=new WebInspector.DataGrid(columns,this._editingCallback.bind(this),this._deleteCallback.bind(this));dataGrid.setName("DOMStorageItemsView");length=nodes.length;for(var i=0;i<length;++i) dataGrid.rootNode().appendChild(nodes[i]);dataGrid.addCreationNode(false);if(length>0) nodes[0].selected=true;return dataGrid;},_deleteButtonClicked:function(event) {if(!this._dataGrid||!this._dataGrid.selectedNode) return;this._deleteCallback(this._dataGrid.selectedNode);},_refreshButtonClicked:function(event) {this._update();},_editingCallback:function(editingNode,columnIdentifier,oldText,newText) {var domStorage=this.domStorage;if(columnIdentifier==="key"){if(typeof oldText==="string") domStorage.removeItem(oldText);domStorage.setItem(newText,editingNode.data.value||"");this._removeDupes(editingNode);}else domStorage.setItem(editingNode.data.key||"",newText);},_removeDupes:function(masterNode) {var rootNode=this._dataGrid.rootNode();var children=rootNode.children;for(var i=children.length-1;i>=0;--i){var childNode=children[i];if((childNode.data.key===masterNode.data.key)&&(masterNode!==childNode)) rootNode.removeChild(childNode);}},_deleteCallback:function(node) {if(!node||node.isCreationNode) return;if(this.domStorage) this.domStorage.removeItem(node.data.key);},__proto__:WebInspector.VBox.prototype};WebInspector.DatabaseQueryView=function(database) {WebInspector.VBox.call(this);this.database=database;this.element.classList.add("storage-view","query","monospace");this.element.addEventListener("selectstart",this._selectStart.bind(this),false);this._promptElement=createElement("div");this._promptElement.className="database-query-prompt";this._promptElement.appendChild(createElement("br"));this._promptElement.addEventListener("keydown",this._promptKeyDown.bind(this),true);this.element.appendChild(this._promptElement);this._prompt=new WebInspector.TextPromptWithHistory(this.completions.bind(this)," ");this._proxyElement=this._prompt.attach(this._promptElement);this.element.addEventListener("click",this._messagesClicked.bind(this),true);} WebInspector.DatabaseQueryView.Events={SchemaUpdated:"SchemaUpdated"} WebInspector.DatabaseQueryView.prototype={toolbarItems:function() {return[];},_messagesClicked:function() {if(!this._prompt.isCaretInsidePrompt()&&this.element.isComponentSelectionCollapsed()) this._prompt.moveCaretToEndOfPrompt();},completions:function(proxyElement,text,cursorOffset,wordRange,force,completionsReadyCallback) {var prefix=wordRange.toString().toLowerCase();if(!prefix) return;var results=[];function accumulateMatches(textArray) {for(var i=0;i<textArray.length;++i){var text=textArray[i].toLowerCase();if(text.length<prefix.length) continue;if(!text.startsWith(prefix)) continue;results.push(textArray[i]);}} function tableNamesCallback(tableNames) {accumulateMatches(tableNames.map(function(name){return name+" ";}));accumulateMatches(["SELECT ","FROM ","WHERE ","LIMIT ","DELETE FROM ","CREATE ","DROP ","TABLE ","INDEX ","UPDATE ","INSERT INTO ","VALUES ("]);completionsReadyCallback(results);} this.database.getTableNames(tableNamesCallback);},_selectStart:function(event) {if(this._selectionTimeout) clearTimeout(this._selectionTimeout);this._prompt.clearAutoComplete();function moveBackIfOutside() {delete this._selectionTimeout;if(!this._prompt.isCaretInsidePrompt()&&this.element.isComponentSelectionCollapsed()) this._prompt.moveCaretToEndOfPrompt();this._prompt.autoCompleteSoon();} this._selectionTimeout=setTimeout(moveBackIfOutside.bind(this),100);},_promptKeyDown:function(event) {if(isEnterKey(event)){this._enterKeyPressed(event);return;}},_enterKeyPressed:function(event) {event.consume(true);this._prompt.clearAutoComplete(true);var query=this._prompt.text();if(!query.length) return;this._prompt.pushHistoryItem(query);this._prompt.setText("");this.database.executeSql(query,this._queryFinished.bind(this,query),this._queryError.bind(this,query));},_queryFinished:function(query,columnNames,values) {var dataGrid=WebInspector.SortableDataGrid.create(columnNames,values);var trimmedQuery=query.trim();if(dataGrid){dataGrid.renderInline();this._appendViewQueryResult(trimmedQuery,dataGrid.asWidget());dataGrid.autoSizeColumns(5);} if(trimmedQuery.match(/^create /i)||trimmedQuery.match(/^drop table /i)) this.dispatchEventToListeners(WebInspector.DatabaseQueryView.Events.SchemaUpdated,this.database);},_queryError:function(query,errorMessage) {this._appendErrorQueryResult(query,errorMessage);},_appendViewQueryResult:function(query,view) {var resultElement=this._appendQueryResult(query);view.show(resultElement);this._promptElement.scrollIntoView(false);},_appendErrorQueryResult:function(query,errorText) {var resultElement=this._appendQueryResult(query);resultElement.classList.add("error");resultElement.textContent=errorText;this._promptElement.scrollIntoView(false);},_appendQueryResult:function(query) {var element=createElement("div");element.className="database-user-query";this.element.insertBefore(element,this._proxyElement);var commandTextElement=createElement("span");commandTextElement.className="database-query-text";commandTextElement.textContent=query;element.appendChild(commandTextElement);var resultElement=createElement("div");resultElement.className="database-query-result";element.appendChild(resultElement);return resultElement;},__proto__:WebInspector.VBox.prototype};WebInspector.DatabaseTableView=function(database,tableName) {WebInspector.VBox.call(this);this.database=database;this.tableName=tableName;this.element.classList.add("storage-view","table");this._visibleColumnsSetting=WebInspector.settings.createSetting("databaseTableViewVisibleColumns",{});this.refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this.refreshButton.addEventListener("click",this._refreshButtonClicked,this);this._visibleColumnsInput=new WebInspector.ToolbarInput(WebInspector.UIString("Visible columns"),1);this._visibleColumnsInput.addEventListener(WebInspector.ToolbarInput.Event.TextChanged,this._onVisibleColumnsChanged,this);} WebInspector.DatabaseTableView.prototype={wasShown:function() {this.update();},toolbarItems:function() {return[this.refreshButton,this._visibleColumnsInput];},_escapeTableName:function(tableName) {return tableName.replace(/\"/g,"\"\"");},update:function() {this.database.executeSql("SELECT rowid, * FROM \""+this._escapeTableName(this.tableName)+"\"",this._queryFinished.bind(this),this._queryError.bind(this));},_queryFinished:function(columnNames,values) {this.detachChildWidgets();this.element.removeChildren();this._dataGrid=WebInspector.SortableDataGrid.create(columnNames,values);this._visibleColumnsInput.setVisible(!!this._dataGrid);if(!this._dataGrid){this._emptyWidget=new WebInspector.EmptyWidget(WebInspector.UIString("The “%s”\ntable is empty.",this.tableName));this._emptyWidget.show(this.element);return;} this._dataGrid.asWidget().show(this.element);this._dataGrid.autoSizeColumns(5);this._columnsMap=new Map();for(var i=1;i<columnNames.length;++i) this._columnsMap.set(columnNames[i],String(i));this._lastVisibleColumns="";var visibleColumnsText=this._visibleColumnsSetting.get()[this.tableName]||"";this._visibleColumnsInput.setValue(visibleColumnsText);this._onVisibleColumnsChanged();},_onVisibleColumnsChanged:function() {if(!this._dataGrid) return;var text=this._visibleColumnsInput.value();var parts=text.split(/[\s,]+/);var matches=new Set();var columnsVisibility={};columnsVisibility["0"]=true;for(var i=0;i<parts.length;++i){var part=parts[i];if(this._columnsMap.has(part)){matches.add(part);columnsVisibility[this._columnsMap.get(part)]=true;}} var newVisibleColumns=matches.valuesArray().sort().join(", ");if(newVisibleColumns.length===0){for(var v of this._columnsMap.values()) columnsVisibility[v]=true;} if(newVisibleColumns===this._lastVisibleColumns) return;var visibleColumnsRegistry=this._visibleColumnsSetting.get();visibleColumnsRegistry[this.tableName]=text;this._visibleColumnsSetting.set(visibleColumnsRegistry);this._dataGrid.setColumnsVisiblity(columnsVisibility);this._lastVisibleColumns=newVisibleColumns;},_queryError:function(error) {this.detachChildWidgets();this.element.removeChildren();var errorMsgElement=createElement("div");errorMsgElement.className="storage-table-error";errorMsgElement.textContent=WebInspector.UIString("An error occurred trying to\nread the “%s” table.",this.tableName);this.element.appendChild(errorMsgElement);},_refreshButtonClicked:function(event) {this.update();},__proto__:WebInspector.VBox.prototype};WebInspector.IndexedDBModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.IndexedDBModel,target);this._agent=target.indexedDBAgent();this._databases=new Map();this._databaseNamesBySecurityOrigin={};} WebInspector.IndexedDBModel.KeyTypes={NumberType:"number",StringType:"string",DateType:"date",ArrayType:"array"};WebInspector.IndexedDBModel.KeyPathTypes={NullType:"null",StringType:"string",ArrayType:"array"};WebInspector.IndexedDBModel.keyFromIDBKey=function(idbKey) {if(typeof(idbKey)==="undefined"||idbKey===null) return null;var key={};switch(typeof(idbKey)){case"number":key.number=idbKey;key.type=WebInspector.IndexedDBModel.KeyTypes.NumberType;break;case"string":key.string=idbKey;key.type=WebInspector.IndexedDBModel.KeyTypes.StringType;break;case"object":if(idbKey instanceof Date){key.date=idbKey.getTime();key.type=WebInspector.IndexedDBModel.KeyTypes.DateType;}else if(Array.isArray(idbKey)){key.array=[];for(var i=0;i<idbKey.length;++i) key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));key.type=WebInspector.IndexedDBModel.KeyTypes.ArrayType;} break;default:return null;} return key;} WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange=function(idbKeyRange) {if(typeof idbKeyRange==="undefined"||idbKeyRange===null) return null;var keyRange={};keyRange.lower=WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);keyRange.upper=WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);keyRange.lowerOpen=idbKeyRange.lowerOpen;keyRange.upperOpen=idbKeyRange.upperOpen;return keyRange;} WebInspector.IndexedDBModel.idbKeyPathFromKeyPath=function(keyPath) {var idbKeyPath;switch(keyPath.type){case WebInspector.IndexedDBModel.KeyPathTypes.NullType:idbKeyPath=null;break;case WebInspector.IndexedDBModel.KeyPathTypes.StringType:idbKeyPath=keyPath.string;break;case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:idbKeyPath=keyPath.array;break;} return idbKeyPath;} WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath=function(idbKeyPath) {if(typeof idbKeyPath==="string") return"\""+idbKeyPath+"\"";if(idbKeyPath instanceof Array) return"[\""+idbKeyPath.join("\", \"")+"\"]";return null;} WebInspector.IndexedDBModel.EventTypes={DatabaseAdded:"DatabaseAdded",DatabaseRemoved:"DatabaseRemoved",DatabaseLoaded:"DatabaseLoaded"} WebInspector.IndexedDBModel.prototype={enable:function() {if(this._enabled) return;this._agent.enable();this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,this._securityOriginAdded,this);this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,this._securityOriginRemoved,this);var securityOrigins=this.target().resourceTreeModel.securityOrigins();for(var i=0;i<securityOrigins.length;++i) this._addOrigin(securityOrigins[i]);this._enabled=true;},clearForOrigin:function(origin) {if(!this._enabled) return;this._removeOrigin(origin);this._addOrigin(origin);},refreshDatabaseNames:function() {for(var securityOrigin in this._databaseNamesBySecurityOrigin) this._loadDatabaseNames(securityOrigin);},refreshDatabase:function(databaseId) {this._loadDatabase(databaseId);},clearObjectStore:function(databaseId,objectStoreName,callback) {this._agent.clearObjectStore(databaseId.securityOrigin,databaseId.name,objectStoreName,callback);},_securityOriginAdded:function(event) {var securityOrigin=(event.data);this._addOrigin(securityOrigin);},_securityOriginRemoved:function(event) {var securityOrigin=(event.data);this._removeOrigin(securityOrigin);},_addOrigin:function(securityOrigin) {console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]);this._databaseNamesBySecurityOrigin[securityOrigin]=[];this._loadDatabaseNames(securityOrigin);},_removeOrigin:function(securityOrigin) {console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]);for(var i=0;i<this._databaseNamesBySecurityOrigin[securityOrigin].length;++i) this._databaseRemoved(securityOrigin,this._databaseNamesBySecurityOrigin[securityOrigin][i]);delete this._databaseNamesBySecurityOrigin[securityOrigin];},_updateOriginDatabaseNames:function(securityOrigin,databaseNames) {var newDatabaseNames=databaseNames.keySet();var oldDatabaseNames=this._databaseNamesBySecurityOrigin[securityOrigin].keySet();this._databaseNamesBySecurityOrigin[securityOrigin]=databaseNames;for(var databaseName in oldDatabaseNames){if(!newDatabaseNames[databaseName]) this._databaseRemoved(securityOrigin,databaseName);} for(var databaseName in newDatabaseNames){if(!oldDatabaseNames[databaseName]) this._databaseAdded(securityOrigin,databaseName);}},databases:function() {var result=[];for(var securityOrigin in this._databaseNamesBySecurityOrigin){var databaseNames=this._databaseNamesBySecurityOrigin[securityOrigin];for(var i=0;i<databaseNames.length;++i){result.push(new WebInspector.IndexedDBModel.DatabaseId(securityOrigin,databaseNames[i]));}} return result;},_databaseAdded:function(securityOrigin,databaseName) {var databaseId=new WebInspector.IndexedDBModel.DatabaseId(securityOrigin,databaseName);this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded,databaseId);},_databaseRemoved:function(securityOrigin,databaseName) {var databaseId=new WebInspector.IndexedDBModel.DatabaseId(securityOrigin,databaseName);this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved,databaseId);},_loadDatabaseNames:function(securityOrigin) {function callback(error,databaseNames) {if(error){console.error("IndexedDBAgent error: "+error);return;} if(!this._databaseNamesBySecurityOrigin[securityOrigin]) return;this._updateOriginDatabaseNames(securityOrigin,databaseNames);} this._agent.requestDatabaseNames(securityOrigin,callback.bind(this));},_loadDatabase:function(databaseId) {function callback(error,databaseWithObjectStores) {if(error){console.error("IndexedDBAgent error: "+error);return;} if(!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) return;var databaseModel=new WebInspector.IndexedDBModel.Database(databaseId,databaseWithObjectStores.version);this._databases.set(databaseId,databaseModel);for(var i=0;i<databaseWithObjectStores.objectStores.length;++i){var objectStore=databaseWithObjectStores.objectStores[i];var objectStoreIDBKeyPath=WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);var objectStoreModel=new WebInspector.IndexedDBModel.ObjectStore(objectStore.name,objectStoreIDBKeyPath,objectStore.autoIncrement);for(var j=0;j<objectStore.indexes.length;++j){var index=objectStore.indexes[j];var indexIDBKeyPath=WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);var indexModel=new WebInspector.IndexedDBModel.Index(index.name,indexIDBKeyPath,index.unique,index.multiEntry);objectStoreModel.indexes[indexModel.name]=indexModel;} databaseModel.objectStores[objectStoreModel.name]=objectStoreModel;} this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded,databaseModel);} this._agent.requestDatabase(databaseId.securityOrigin,databaseId.name,callback.bind(this));},loadObjectStoreData:function(databaseId,objectStoreName,idbKeyRange,skipCount,pageSize,callback) {this._requestData(databaseId,databaseId.name,objectStoreName,"",idbKeyRange,skipCount,pageSize,callback);},loadIndexData:function(databaseId,objectStoreName,indexName,idbKeyRange,skipCount,pageSize,callback) {this._requestData(databaseId,databaseId.name,objectStoreName,indexName,idbKeyRange,skipCount,pageSize,callback);},_requestData:function(databaseId,databaseName,objectStoreName,indexName,idbKeyRange,skipCount,pageSize,callback) {function innerCallback(error,dataEntries,hasMore) {if(error){console.error("IndexedDBAgent error: "+error);return;} if(!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) return;var entries=[];for(var i=0;i<dataEntries.length;++i){var key=WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].key));var primaryKey=WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].primaryKey));var value=WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].value));entries.push(new WebInspector.IndexedDBModel.Entry(key,primaryKey,value));} callback(entries,hasMore);} var keyRange=WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);this._agent.requestData(databaseId.securityOrigin,databaseName,objectStoreName,indexName,skipCount,pageSize,keyRange?keyRange:undefined,innerCallback.bind(this));},__proto__:WebInspector.SDKModel.prototype} WebInspector.IndexedDBModel.Entry=function(key,primaryKey,value) {this.key=key;this.primaryKey=primaryKey;this.value=value;} WebInspector.IndexedDBModel.DatabaseId=function(securityOrigin,name) {this.securityOrigin=securityOrigin;this.name=name;} WebInspector.IndexedDBModel.DatabaseId.prototype={equals:function(databaseId) {return this.name===databaseId.name&&this.securityOrigin===databaseId.securityOrigin;},} WebInspector.IndexedDBModel.Database=function(databaseId,version) {this.databaseId=databaseId;this.version=version;this.objectStores={};} WebInspector.IndexedDBModel.ObjectStore=function(name,keyPath,autoIncrement) {this.name=name;this.keyPath=keyPath;this.autoIncrement=autoIncrement;this.indexes={};} WebInspector.IndexedDBModel.ObjectStore.prototype={get keyPathString() {return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);}} WebInspector.IndexedDBModel.Index=function(name,keyPath,unique,multiEntry) {this.name=name;this.keyPath=keyPath;this.unique=unique;this.multiEntry=multiEntry;} WebInspector.IndexedDBModel.Index.prototype={get keyPathString() {return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);}} WebInspector.IndexedDBModel.fromTarget=function(target) {var model=(target.model(WebInspector.IndexedDBModel));if(!model) model=new WebInspector.IndexedDBModel(target);return model;};WebInspector.IDBDatabaseView=function(database) {WebInspector.VBox.call(this);this.registerRequiredCSS("resources/indexedDBViews.css");this.element.classList.add("indexed-db-database-view");this.element.classList.add("storage-view");this._headersTreeOutline=new TreeOutline();this._headersTreeOutline.element.classList.add("outline-disclosure");this.element.appendChild(this._headersTreeOutline.element);this._headersTreeOutline.expandTreeElementsWhenArrowing=true;this._securityOriginTreeElement=new TreeElement();this._securityOriginTreeElement.selectable=false;this._headersTreeOutline.appendChild(this._securityOriginTreeElement);this._nameTreeElement=new TreeElement();this._nameTreeElement.selectable=false;this._headersTreeOutline.appendChild(this._nameTreeElement);this._versionTreeElement=new TreeElement();this._versionTreeElement.selectable=false;this._headersTreeOutline.appendChild(this._versionTreeElement);this.update(database);} WebInspector.IDBDatabaseView.prototype={toolbarItems:function() {return[];},_formatHeader:function(name,value) {var fragment=createDocumentFragment();fragment.createChild("div","attribute-name").textContent=name+":";fragment.createChild("div","attribute-value source-code").textContent=value;return fragment;},_refreshDatabase:function() {this._securityOriginTreeElement.title=this._formatHeader(WebInspector.UIString("Security origin"),this._database.databaseId.securityOrigin);this._nameTreeElement.title=this._formatHeader(WebInspector.UIString("Name"),this._database.databaseId.name);this._versionTreeElement.title=this._formatHeader(WebInspector.UIString("Version"),this._database.version);},update:function(database) {this._database=database;this._refreshDatabase();},__proto__:WebInspector.VBox.prototype} WebInspector.IDBDataView=function(model,databaseId,objectStore,index) {WebInspector.VBox.call(this);this.registerRequiredCSS("resources/indexedDBViews.css");this._model=model;this._databaseId=databaseId;this._isIndex=!!index;this.element.classList.add("indexed-db-data-view");this._createEditorToolbar();this._refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this._refreshButton.addEventListener("click",this._refreshButtonClicked,this);this._clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear object store"),"clear-toolbar-item");this._clearButton.addEventListener("click",this._clearButtonClicked,this);this._pageSize=50;this._skipCount=0;this.update(objectStore,index);this._entries=[];} WebInspector.IDBDataView.prototype={_createDataGrid:function() {var keyPath=this._isIndex?this._index.keyPath:this._objectStore.keyPath;var columns=[];columns.push({id:"number",title:WebInspector.UIString("#"),width:"50px"});columns.push({id:"key",titleDOMFragment:this._keyColumnHeaderFragment(WebInspector.UIString("Key"),keyPath)});if(this._isIndex) columns.push({id:"primaryKey",titleDOMFragment:this._keyColumnHeaderFragment(WebInspector.UIString("Primary key"),this._objectStore.keyPath)});columns.push({id:"value",title:WebInspector.UIString("Value")});var dataGrid=new WebInspector.DataGrid(columns);return dataGrid;},_keyColumnHeaderFragment:function(prefix,keyPath) {var keyColumnHeaderFragment=createDocumentFragment();keyColumnHeaderFragment.createTextChild(prefix);if(keyPath===null) return keyColumnHeaderFragment;keyColumnHeaderFragment.createTextChild(" ("+WebInspector.UIString("Key path: "));if(Array.isArray(keyPath)){keyColumnHeaderFragment.createTextChild("[");for(var i=0;i<keyPath.length;++i){if(i!=0) keyColumnHeaderFragment.createTextChild(", ");keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));} keyColumnHeaderFragment.createTextChild("]");}else{var keyPathString=(keyPath);keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPathString));} keyColumnHeaderFragment.createTextChild(")");return keyColumnHeaderFragment;},_keyPathStringFragment:function(keyPathString) {var keyPathStringFragment=createDocumentFragment();keyPathStringFragment.createTextChild("\"");var keyPathSpan=keyPathStringFragment.createChild("span","source-code indexed-db-key-path");keyPathSpan.textContent=keyPathString;keyPathStringFragment.createTextChild("\"");return keyPathStringFragment;},_createEditorToolbar:function() {var editorToolbar=new WebInspector.Toolbar("data-view-toolbar",this.element);this._pageBackButton=new WebInspector.ToolbarButton(WebInspector.UIString("Show previous page"),"play-backwards-toolbar-item");this._pageBackButton.addEventListener("click",this._pageBackButtonClicked,this);editorToolbar.appendToolbarItem(this._pageBackButton);this._pageForwardButton=new WebInspector.ToolbarButton(WebInspector.UIString("Show next page"),"play-toolbar-item");this._pageForwardButton.setEnabled(false);this._pageForwardButton.addEventListener("click",this._pageForwardButtonClicked,this);editorToolbar.appendToolbarItem(this._pageForwardButton);this._keyInputElement=editorToolbar.element.createChild("input","key-input");this._keyInputElement.placeholder=WebInspector.UIString("Start from key");this._keyInputElement.addEventListener("paste",this._keyInputChanged.bind(this),false);this._keyInputElement.addEventListener("cut",this._keyInputChanged.bind(this),false);this._keyInputElement.addEventListener("keypress",this._keyInputChanged.bind(this),false);this._keyInputElement.addEventListener("keydown",this._keyInputChanged.bind(this),false);},_pageBackButtonClicked:function() {this._skipCount=Math.max(0,this._skipCount-this._pageSize);this._updateData(false);},_pageForwardButtonClicked:function() {this._skipCount=this._skipCount+this._pageSize;this._updateData(false);},_keyInputChanged:function() {window.setTimeout(this._updateData.bind(this,false),0);},update:function(objectStore,index) {this._objectStore=objectStore;this._index=index;if(this._dataGrid) this._dataGrid.asWidget().detach();this._dataGrid=this._createDataGrid();this._dataGrid.asWidget().show(this.element);this._skipCount=0;this._updateData(true);},_parseKey:function(keyString) {var result;try{result=JSON.parse(keyString);}catch(e){result=keyString;} return result;},_updateData:function(force) {var key=this._parseKey(this._keyInputElement.value);var pageSize=this._pageSize;var skipCount=this._skipCount;this._refreshButton.setEnabled(false);this._clearButton.setEnabled(!this._isIndex);if(!force&&this._lastKey===key&&this._lastPageSize===pageSize&&this._lastSkipCount===skipCount) return;if(this._lastKey!==key||this._lastPageSize!==pageSize){skipCount=0;this._skipCount=0;} this._lastKey=key;this._lastPageSize=pageSize;this._lastSkipCount=skipCount;function callback(entries,hasMore) {this._refreshButton.setEnabled(true);this.clear();this._entries=entries;for(var i=0;i<entries.length;++i){var data={};data["number"]=i+skipCount;data["key"]=entries[i].key;data["primaryKey"]=entries[i].primaryKey;data["value"]=entries[i].value;var node=new WebInspector.IDBDataGridNode(data);this._dataGrid.rootNode().appendChild(node);} this._pageBackButton.setEnabled(!!skipCount);this._pageForwardButton.setEnabled(hasMore);} var idbKeyRange=key?window.IDBKeyRange.lowerBound(key):null;if(this._isIndex) this._model.loadIndexData(this._databaseId,this._objectStore.name,this._index.name,idbKeyRange,skipCount,pageSize,callback.bind(this));else this._model.loadObjectStoreData(this._databaseId,this._objectStore.name,idbKeyRange,skipCount,pageSize,callback.bind(this));},_refreshButtonClicked:function(event) {this._updateData(true);},_clearButtonClicked:function(event) {function cleared(){this._clearButton.setEnabled(true);this._updateData(true);} this._clearButton.setEnabled(false);this._model.clearObjectStore(this._databaseId,this._objectStore.name,cleared.bind(this));},toolbarItems:function() {return[this._refreshButton,this._clearButton];},clear:function() {this._dataGrid.rootNode().removeChildren();this._entries=[];},__proto__:WebInspector.VBox.prototype} WebInspector.IDBDataGridNode=function(data) {WebInspector.DataGridNode.call(this,data,false);this.selectable=false;} WebInspector.IDBDataGridNode.prototype={createCell:function(columnIdentifier) {var cell=WebInspector.DataGridNode.prototype.createCell.call(this,columnIdentifier);var value=this.data[columnIdentifier];switch(columnIdentifier){case"value":case"key":case"primaryKey":cell.removeChildren();var objectElement=WebInspector.ObjectPropertiesSection.defaultObjectPresentation(value,true);cell.appendChild(objectElement);break;default:} return cell;},__proto__:WebInspector.DataGridNode.prototype};WebInspector.ResourcesPanel=function() {WebInspector.PanelWithSidebar.call(this,"resources");this.registerRequiredCSS("resources/resourcesPanel.css");this._resourcesLastSelectedItemSetting=WebInspector.settings.createSetting("resourcesLastSelectedItem",{});this._sidebarTree=new TreeOutlineInShadow();this._sidebarTree.element.classList.add("resources-sidebar");this._sidebarTree.registerRequiredCSS("resources/resourcesSidebar.css");this._sidebarTree.element.classList.add("filter-all","outline-disclosure");this.panelSidebarElement().appendChild(this._sidebarTree.element);this.setDefaultFocusedElement(this._sidebarTree.element);this._applicationTreeElement=this._addSidebarSection(WebInspector.UIString("Application"));this._manifestTreeElement=new WebInspector.AppManifestTreeElement(this);this._applicationTreeElement.appendChild(this._manifestTreeElement);this.serviceWorkersTreeElement=new WebInspector.ServiceWorkersTreeElement(this);this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement);var clearStorageTreeElement=new WebInspector.ClearStorageTreeElement(this);this._applicationTreeElement.appendChild(clearStorageTreeElement);var storageTreeElement=this._addSidebarSection(WebInspector.UIString("Storage"));this.localStorageListTreeElement=new WebInspector.StorageCategoryTreeElement(this,WebInspector.UIString("Local Storage"),"LocalStorage",["table-tree-item","resource-tree-item"]);storageTreeElement.appendChild(this.localStorageListTreeElement);this.sessionStorageListTreeElement=new WebInspector.StorageCategoryTreeElement(this,WebInspector.UIString("Session Storage"),"SessionStorage",["table-tree-item","resource-tree-item"]);storageTreeElement.appendChild(this.sessionStorageListTreeElement);this.indexedDBListTreeElement=new WebInspector.IndexedDBTreeElement(this);storageTreeElement.appendChild(this.indexedDBListTreeElement);this.databasesListTreeElement=new WebInspector.StorageCategoryTreeElement(this,WebInspector.UIString("Web SQL"),"Databases",["database-tree-item","resource-tree-item"]);storageTreeElement.appendChild(this.databasesListTreeElement);this.cookieListTreeElement=new WebInspector.StorageCategoryTreeElement(this,WebInspector.UIString("Cookies"),"Cookies",["cookie-tree-item","resource-tree-item"]);storageTreeElement.appendChild(this.cookieListTreeElement);var cacheTreeElement=this._addSidebarSection(WebInspector.UIString("Cache"));this.cacheStorageListTreeElement=new WebInspector.ServiceWorkerCacheTreeElement(this);cacheTreeElement.appendChild(this.cacheStorageListTreeElement);this.applicationCacheListTreeElement=new WebInspector.StorageCategoryTreeElement(this,WebInspector.UIString("Application Cache"),"ApplicationCache",["appcache-tree-item","table-tree-item","resource-tree-item"]);cacheTreeElement.appendChild(this.applicationCacheListTreeElement);this.resourcesListTreeElement=this._addSidebarSection(WebInspector.UIString("Frames"));var mainContainer=new WebInspector.VBox();this.storageViews=mainContainer.element.createChild("div","vbox flex-auto");this._storageViewToolbar=new WebInspector.Toolbar("resources-toolbar",mainContainer.element);this.splitWidget().setMainWidget(mainContainer);this._databaseTableViews=new Map();this._databaseQueryViews=new Map();this._databaseTreeElements=new Map();this._domStorageViews=new Map();this._domStorageTreeElements=new Map();this._cookieViews={};this._domains={};this.panelSidebarElement().addEventListener("mousemove",this._onmousemove.bind(this),false);this.panelSidebarElement().addEventListener("mouseleave",this._onmouseleave.bind(this),false);WebInspector.targetManager.observeTargets(this);} WebInspector.ResourcesPanel.prototype={_addSidebarSection:function(title) {var treeElement=new TreeElement(title,true);treeElement.listItemElement.classList.add("storage-group-list-item");treeElement.setCollapsible(false);treeElement.selectable=false;this._sidebarTree.appendChild(treeElement);return treeElement;},targetAdded:function(target) {if(this._target) return;this._target=target;this._databaseModel=WebInspector.DatabaseModel.fromTarget(target);this._domStorageModel=WebInspector.DOMStorageModel.fromTarget(target);if(target.resourceTreeModel.cachedResourcesLoaded()) this._initialize();target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded,this._initialize,this);target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources,this._resetWithFrames,this);this._databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded,this._databaseAdded,this);this._databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabasesRemoved,this._resetWebSQL,this);},targetRemoved:function(target) {if(target!==this._target) return;delete this._target;target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded,this._initialize,this);target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources,this._resetWithFrames,this);this._databaseModel.removeEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded,this._databaseAdded,this);this._databaseModel.removeEventListener(WebInspector.DatabaseModel.Events.DatabasesRemoved,this._resetWebSQL,this);this._resetWithFrames();},_initialize:function() {this._databaseModel.enable();this._domStorageModel.enable();var indexedDBModel=WebInspector.IndexedDBModel.fromTarget(this._target);if(indexedDBModel) indexedDBModel.enable();var cacheStorageModel=WebInspector.ServiceWorkerCacheModel.fromTarget(this._target);if(cacheStorageModel) cacheStorageModel.enable();if(this._target.isPage()) this._populateResourceTree();this._populateDOMStorageTree();this._populateApplicationCacheTree();this.indexedDBListTreeElement._initialize();this.cacheStorageListTreeElement._initialize();this._initDefaultSelection();},_initDefaultSelection:function() {var itemURL=this._resourcesLastSelectedItemSetting.get();if(itemURL){var rootElement=this._sidebarTree.rootElement();for(var treeElement=rootElement.firstChild();treeElement;treeElement=treeElement.traverseNextTreeElement(false,rootElement,true)){if(treeElement.itemURL===itemURL){treeElement.revealAndSelect(true);return;}}} this._manifestTreeElement.select();},_resetWithFrames:function() {this.resourcesListTreeElement.removeChildren();this._treeElementForFrameId={};this._reset();},_resetWebSQL:function() {if(this.visibleView instanceof WebInspector.DatabaseQueryView||this.visibleView instanceof WebInspector.DatabaseTableView){this.visibleView.detach();delete this.visibleView;} var queryViews=this._databaseQueryViews.valuesArray();for(var i=0;i<queryViews.length;++i) queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated,this._updateDatabaseTables,this);this._databaseTableViews.clear();this._databaseQueryViews.clear();this._databaseTreeElements.clear();this.databasesListTreeElement.removeChildren();this.databasesListTreeElement.setExpandable(false);},_resetDOMStorage:function() {if(this.visibleView instanceof WebInspector.DOMStorageItemsView){this.visibleView.detach();delete this.visibleView;} this._domStorageViews.clear();this._domStorageTreeElements.clear();this.localStorageListTreeElement.removeChildren();this.sessionStorageListTreeElement.removeChildren();},_resetCookies:function() {if(this.visibleView instanceof WebInspector.CookieItemsView){this.visibleView.detach();delete this.visibleView;} this._cookieViews={};this.cookieListTreeElement.removeChildren();},_resetCacheStorage:function() {if(this.visibleView instanceof WebInspector.ServiceWorkerCacheView){this.visibleView.detach();delete this.visibleView;} this.cacheStorageListTreeElement.removeChildren();this.cacheStorageListTreeElement.setExpandable(false);},_resetAppCache:function() {for(var frameId of Object.keys(this._applicationCacheFrameElements)) this._applicationCacheFrameManifestRemoved({data:frameId});this.applicationCacheListTreeElement.setExpandable(false);},_reset:function() {this._domains={};this._resetWebSQL();this._resetDOMStorage();this._resetCookies();this._resetCacheStorage();if((this.visibleView instanceof WebInspector.ResourceSourceFrame)||(this.visibleView instanceof WebInspector.ImageView)||(this.visibleView instanceof WebInspector.FontView)){this.visibleView.detach();delete this.visibleView;} this._storageViewToolbar.removeToolbarItems();if(this._sidebarTree.selectedTreeElement) this._sidebarTree.selectedTreeElement.deselect();},_populateResourceTree:function() {this._treeElementForFrameId={};this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded,this._frameAdded,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated,this._frameNavigated,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached,this._frameDetached,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded,this._resourceAdded,this);function populateFrame(frame) {this._frameAdded({data:frame});for(var i=0;i<frame.childFrames.length;++i) populateFrame.call(this,frame.childFrames[i]);var resources=frame.resources();for(var i=0;i<resources.length;++i) this._resourceAdded({data:resources[i]});} populateFrame.call(this,this._target.resourceTreeModel.mainFrame);},_frameAdded:function(event) {var frame=event.data;var parentFrame=frame.parentFrame;var parentTreeElement=parentFrame?this._treeElementForFrameId[parentFrame.id]:this.resourcesListTreeElement;if(!parentTreeElement){console.warn("No frame to route "+frame.url+" to.");return;} var frameTreeElement=new WebInspector.FrameTreeElement(this,frame);this._treeElementForFrameId[frame.id]=frameTreeElement;parentTreeElement.appendChild(frameTreeElement);},_frameDetached:function(event) {var frame=event.data;var frameTreeElement=this._treeElementForFrameId[frame.id];if(!frameTreeElement) return;delete this._treeElementForFrameId[frame.id];if(frameTreeElement.parent) frameTreeElement.parent.removeChild(frameTreeElement);},_resourceAdded:function(event) {var resource=event.data;var frameId=resource.frameId;if(resource.statusCode>=301&&resource.statusCode<=303) return;var frameTreeElement=this._treeElementForFrameId[frameId];if(!frameTreeElement){return;} frameTreeElement.appendResource(resource);},_frameNavigated:function(event) {var frame=event.data;if(!frame.parentFrame) this._reset();var frameId=frame.id;var frameTreeElement=this._treeElementForFrameId[frameId];if(frameTreeElement) frameTreeElement.frameNavigated(frame);var applicationCacheFrameTreeElement=this._applicationCacheFrameElements[frameId];if(applicationCacheFrameTreeElement) applicationCacheFrameTreeElement.frameNavigated(frame);},_databaseAdded:function(event) {var database=(event.data);this._addDatabase(database);},_addDatabase:function(database) {var databaseTreeElement=new WebInspector.DatabaseTreeElement(this,database);this._databaseTreeElements.set(database,databaseTreeElement);this.databasesListTreeElement.appendChild(databaseTreeElement);},addDocumentURL:function(url) {var parsedURL=url.asParsedURL();if(!parsedURL) return;var domain=parsedURL.securityOrigin();if(!this._domains[domain]){this._domains[domain]=true;var cookieDomainTreeElement=new WebInspector.CookieTreeElement(this,domain);this.cookieListTreeElement.appendChild(cookieDomainTreeElement);}},_domStorageAdded:function(event) {var domStorage=(event.data);this._addDOMStorage(domStorage);},_addDOMStorage:function(domStorage) {console.assert(!this._domStorageTreeElements.get(domStorage));var domStorageTreeElement=new WebInspector.DOMStorageTreeElement(this,domStorage);this._domStorageTreeElements.set(domStorage,domStorageTreeElement);if(domStorage.isLocalStorage) this.localStorageListTreeElement.appendChild(domStorageTreeElement);else this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);},_domStorageRemoved:function(event) {var domStorage=(event.data);this._removeDOMStorage(domStorage);},_removeDOMStorage:function(domStorage) {var treeElement=this._domStorageTreeElements.get(domStorage);if(!treeElement) return;var wasSelected=treeElement.selected;var parentListTreeElement=treeElement.parent;parentListTreeElement.removeChild(treeElement);if(wasSelected) parentListTreeElement.select();this._domStorageTreeElements.remove(domStorage);this._domStorageViews.remove(domStorage);},selectDatabase:function(database) {if(database){this._showDatabase(database);this._databaseTreeElements.get(database).select();}},selectDOMStorage:function(domStorage) {if(domStorage){this._showDOMStorage(domStorage);this._domStorageTreeElements.get(domStorage).select();}},showResource:function(resource,line,column) {var resourceTreeElement=this._findTreeElementForResource(resource);if(resourceTreeElement) resourceTreeElement.revealAndSelect(true);if(typeof line==="number"){var resourceSourceFrame=this._resourceSourceFrameViewForResource(resource);if(resourceSourceFrame) resourceSourceFrame.revealPosition(line,column,true);} return true;},_showResourceView:function(resource) {var view=this._resourceViewForResource(resource);if(!view){this.visibleView.detach();return;} this._innerShowView(view);},_resourceViewForResource:function(resource) {if(resource.hasTextContent()){var treeElement=this._findTreeElementForResource(resource);if(!treeElement) return null;return treeElement.sourceView();} switch(resource.resourceType()){case WebInspector.resourceTypes.Image:return new WebInspector.ImageView(resource.mimeType,resource);case WebInspector.resourceTypes.Font:return new WebInspector.FontView(resource.mimeType,resource);default:return new WebInspector.EmptyWidget(resource.url);}},_resourceSourceFrameViewForResource:function(resource) {var resourceView=this._resourceViewForResource(resource);if(resourceView&&resourceView instanceof WebInspector.ResourceSourceFrame) return(resourceView);return null;},_showDatabase:function(database,tableName) {if(!database) return;var view;if(tableName){var tableViews=this._databaseTableViews.get(database);if(!tableViews){tableViews=({});this._databaseTableViews.set(database,tableViews);} view=tableViews[tableName];if(!view){view=new WebInspector.DatabaseTableView(database,tableName);tableViews[tableName]=view;}}else{view=this._databaseQueryViews.get(database);if(!view){view=new WebInspector.DatabaseQueryView(database);this._databaseQueryViews.set(database,view);view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated,this._updateDatabaseTables,this);}} this._innerShowView(view);},_showDOMStorage:function(domStorage) {if(!domStorage) return;var view;view=this._domStorageViews.get(domStorage);if(!view){view=new WebInspector.DOMStorageItemsView(domStorage);this._domStorageViews.set(domStorage,view);} this._innerShowView(view);},showCookies:function(treeElement,cookieDomain) {var view=this._cookieViews[cookieDomain];if(!view){view=new WebInspector.CookieItemsView(treeElement,cookieDomain);this._cookieViews[cookieDomain]=view;} this._innerShowView(view);},clearCookies:function(cookieDomain) {if(this._cookieViews[cookieDomain]) this._cookieViews[cookieDomain].clear();},showApplicationCache:function(frameId) {if(!this._applicationCacheViews[frameId]) this._applicationCacheViews[frameId]=new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel,frameId);this._innerShowView(this._applicationCacheViews[frameId]);},showFileSystem:function(view) {this._innerShowView(view);},showCategoryView:function(categoryName) {if(!this._categoryView) this._categoryView=new WebInspector.StorageCategoryView();this._categoryView.setText(categoryName);this._innerShowView(this._categoryView);},_innerShowView:function(view) {if(this.visibleView===view) return;if(this.visibleView) this.visibleView.detach();view.show(this.storageViews);this.visibleView=view;this._storageViewToolbar.removeToolbarItems();var toolbarItems=view.toolbarItems?view.toolbarItems():null;for(var i=0;toolbarItems&&i<toolbarItems.length;++i) this._storageViewToolbar.appendToolbarItem(toolbarItems[i]);},closeVisibleView:function() {if(!this.visibleView) return;this.visibleView.detach();delete this.visibleView;},_updateDatabaseTables:function(event) {var database=event.data;if(!database) return;var databasesTreeElement=this._databaseTreeElements.get(database);if(!databasesTreeElement) return;databasesTreeElement.invalidateChildren();var tableViews=this._databaseTableViews.get(database);if(!tableViews) return;var tableNamesHash={};var self=this;function tableNamesCallback(tableNames) {var tableNamesLength=tableNames.length;for(var i=0;i<tableNamesLength;++i) tableNamesHash[tableNames[i]]=true;for(var tableName in tableViews){if(!(tableName in tableNamesHash)){if(self.visibleView===tableViews[tableName]) self.closeVisibleView();delete tableViews[tableName];}}} database.getTableNames(tableNamesCallback);},_populateDOMStorageTree:function() {this._domStorageModel.storages().forEach(this._addDOMStorage.bind(this));this._domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded,this._domStorageAdded,this);this._domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved,this._domStorageRemoved,this);},_populateApplicationCacheTree:function() {this._applicationCacheModel=new WebInspector.ApplicationCacheModel(this._target);this._applicationCacheViews={};this._applicationCacheFrameElements={};this._applicationCacheManifestElements={};this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded,this._applicationCacheFrameManifestAdded,this);this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved,this._applicationCacheFrameManifestRemoved,this);this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestsReset,this._resetAppCache,this);this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated,this._applicationCacheFrameManifestStatusChanged,this);this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged,this._applicationCacheNetworkStateChanged,this);},_applicationCacheFrameManifestAdded:function(event) {var frameId=event.data;var manifestURL=this._applicationCacheModel.frameManifestURL(frameId);var manifestTreeElement=this._applicationCacheManifestElements[manifestURL];if(!manifestTreeElement){manifestTreeElement=new WebInspector.ApplicationCacheManifestTreeElement(this,manifestURL);this.applicationCacheListTreeElement.appendChild(manifestTreeElement);this._applicationCacheManifestElements[manifestURL]=manifestTreeElement;} var frameTreeElement=new WebInspector.ApplicationCacheFrameTreeElement(this,frameId,manifestURL);manifestTreeElement.appendChild(frameTreeElement);manifestTreeElement.expand();this._applicationCacheFrameElements[frameId]=frameTreeElement;},_applicationCacheFrameManifestRemoved:function(event) {var frameId=event.data;var frameTreeElement=this._applicationCacheFrameElements[frameId];if(!frameTreeElement) return;var manifestURL=frameTreeElement.manifestURL;delete this._applicationCacheFrameElements[frameId];delete this._applicationCacheViews[frameId];frameTreeElement.parent.removeChild(frameTreeElement);var manifestTreeElement=this._applicationCacheManifestElements[manifestURL];if(manifestTreeElement.childCount()) return;delete this._applicationCacheManifestElements[manifestURL];manifestTreeElement.parent.removeChild(manifestTreeElement);},_applicationCacheFrameManifestStatusChanged:function(event) {var frameId=event.data;var status=this._applicationCacheModel.frameManifestStatus(frameId);if(this._applicationCacheViews[frameId]) this._applicationCacheViews[frameId].updateStatus(status);},_applicationCacheNetworkStateChanged:function(event) {var isNowOnline=event.data;for(var manifestURL in this._applicationCacheViews) this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);},_findTreeElementForResource:function(resource) {return resource[WebInspector.FrameResourceTreeElement._symbol];},showView:function(view) {if(view) this.showResource(view.resource);},_onmousemove:function(event) {var nodeUnderMouse=event.target;if(!nodeUnderMouse) return;var listNode=nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");if(!listNode) return;var element=listNode.treeElement;if(this._previousHoveredElement===element) return;if(this._previousHoveredElement){this._previousHoveredElement.hovered=false;delete this._previousHoveredElement;} if(element instanceof WebInspector.FrameTreeElement){this._previousHoveredElement=element;element.hovered=true;}},_onmouseleave:function(event) {if(this._previousHoveredElement){this._previousHoveredElement.hovered=false;delete this._previousHoveredElement;}},__proto__:WebInspector.PanelWithSidebar.prototype} WebInspector.ResourcesPanel.ResourceRevealer=function() {} WebInspector.ResourcesPanel.ResourceRevealer.prototype={reveal:function(resource) {if(!(resource instanceof WebInspector.Resource)) return Promise.reject(new Error("Internal error: not a resource"));var panel=WebInspector.ResourcesPanel._instance();WebInspector.inspectorView.setCurrentPanel(panel);panel.showResource(resource);return Promise.resolve();}} WebInspector.BaseStorageTreeElement=function(storagePanel,title,iconClasses,expandable,noIcon) {TreeElement.call(this,title,expandable);this._storagePanel=storagePanel;for(var i=0;iconClasses&&i<iconClasses.length;++i) this.listItemElement.classList.add(iconClasses[i]);this._iconClasses=iconClasses;if(!noIcon) this.createIcon();} WebInspector.BaseStorageTreeElement.prototype={onselect:function(selectedByUser) {if(!selectedByUser) return false;var itemURL=this.itemURL;if(itemURL) this._storagePanel._resourcesLastSelectedItemSetting.set(itemURL);return false;},__proto__:TreeElement.prototype} WebInspector.StorageCategoryTreeElement=function(storagePanel,categoryName,settingsKey,iconClasses,noIcon) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,categoryName,iconClasses,false,noIcon);this._expandedSetting=WebInspector.settings.createSetting("resources"+settingsKey+"Expanded",settingsKey==="Frames");this._categoryName=categoryName;} WebInspector.StorageCategoryTreeElement.prototype={target:function() {return this._storagePanel._target;},get itemURL() {return"category://"+this._categoryName;},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel.showCategoryView(this._categoryName);return false;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);if(this._expandedSetting.get()) this.expand();},onexpand:function() {this._expandedSetting.set(true);},oncollapse:function() {this._expandedSetting.set(false);},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.FrameTreeElement=function(storagePanel,frame) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,"",["navigator-tree-item","navigator-frame-tree-item"]);this._frame=frame;this.frameNavigated(frame);} WebInspector.FrameTreeElement.prototype={frameNavigated:function(frame) {this.removeChildren();this._frameId=frame.id;this.title=frame.displayName();this._categoryElements={};this._treeElementForResource={};this._storagePanel.addDocumentURL(frame.url);},get itemURL() {return"frame://"+encodeURI(this.titleAsText());},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel.showCategoryView(this.titleAsText());this.listItemElement.classList.remove("hovered");WebInspector.DOMModel.hideDOMNodeHighlight();return false;},set hovered(hovered) {if(hovered){this.listItemElement.classList.add("hovered");var domModel=WebInspector.DOMModel.fromTarget(this._frame.target());if(domModel) domModel.highlightFrame(this._frameId);}else{this.listItemElement.classList.remove("hovered");WebInspector.DOMModel.hideDOMNodeHighlight();}},appendResource:function(resource) {if(resource.isHidden()) return;var resourceType=resource.resourceType();var categoryName=resourceType.name();var categoryElement=resourceType===WebInspector.resourceTypes.Document?this:this._categoryElements[categoryName];if(!categoryElement){categoryElement=new WebInspector.StorageCategoryTreeElement(this._storagePanel,resource.resourceType().category().title,categoryName,null,true);this._categoryElements[resourceType.name()]=categoryElement;this._insertInPresentationOrder(this,categoryElement);} var resourceTreeElement=new WebInspector.FrameResourceTreeElement(this._storagePanel,resource);this._insertInPresentationOrder(categoryElement,resourceTreeElement);this._treeElementForResource[resource.url]=resourceTreeElement;},resourceByURL:function(url) {var treeElement=this._treeElementForResource[url];return treeElement?treeElement._resource:null;},appendChild:function(treeElement) {this._insertInPresentationOrder(this,treeElement);},_insertInPresentationOrder:function(parentTreeElement,childTreeElement) {function typeWeight(treeElement) {if(treeElement instanceof WebInspector.StorageCategoryTreeElement) return 2;if(treeElement instanceof WebInspector.FrameTreeElement) return 1;return 3;} function compare(treeElement1,treeElement2) {var typeWeight1=typeWeight(treeElement1);var typeWeight2=typeWeight(treeElement2);var result;if(typeWeight1>typeWeight2) result=1;else if(typeWeight1<typeWeight2) result=-1;else result=treeElement1.titleAsText().localeCompare(treeElement2.titleAsText());return result;} var childCount=parentTreeElement.childCount();var i;for(i=0;i<childCount;++i){if(compare(childTreeElement,parentTreeElement.childAt(i))<0) break;} parentTreeElement.insertChild(childTreeElement,i);},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.FrameResourceTreeElement=function(storagePanel,resource) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,resource.displayName,["navigator-tree-item","navigator-file-tree-item","navigator-"+resource.resourceType().name()+"-tree-item"]);this._resource=resource;this.tooltip=resource.url;this._resource[WebInspector.FrameResourceTreeElement._symbol]=this;} WebInspector.FrameResourceTreeElement._symbol=Symbol("treeElement");WebInspector.FrameResourceTreeElement.prototype={get itemURL() {return this._resource.url;},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel._showResourceView(this._resource);return false;},ondblclick:function(event) {InspectorFrontendHost.openInNewTab(this._resource.url);return false;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);this.listItemElement.draggable=true;this.listItemElement.addEventListener("dragstart",this._ondragstart.bind(this),false);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_ondragstart:function(event) {event.dataTransfer.setData("text/plain",this._resource.content||"");event.dataTransfer.effectAllowed="copy";return true;},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems(this._resource);contextMenu.show();},sourceView:function() {if(!this._sourceView){var sourceFrame=new WebInspector.ResourceSourceFrame(this._resource);sourceFrame.setHighlighterType(this._resource.canonicalMimeType());this._sourceView=sourceFrame;} return this._sourceView;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.DatabaseTreeElement=function(storagePanel,database) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,database.name,["database-tree-item","resource-tree-item"],true);this._database=database;} WebInspector.DatabaseTreeElement.prototype={get itemURL() {return"database://"+encodeURI(this._database.name);},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel._showDatabase(this._database);return false;},onexpand:function() {this._updateChildren();},_updateChildren:function() {this.removeChildren();function tableNamesCallback(tableNames) {var tableNamesLength=tableNames.length;for(var i=0;i<tableNamesLength;++i) this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel,this._database,tableNames[i]));} this._database.getTableNames(tableNamesCallback.bind(this));},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.DatabaseTableTreeElement=function(storagePanel,database,tableName) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,tableName,["table-tree-item","resource-tree-item"]);this._database=database;this._tableName=tableName;} WebInspector.DatabaseTableTreeElement.prototype={get itemURL() {return"database://"+encodeURI(this._database.name)+"/"+encodeURI(this._tableName);},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel._showDatabase(this._database,this._tableName);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.ServiceWorkerCacheTreeElement=function(storagePanel) {WebInspector.StorageCategoryTreeElement.call(this,storagePanel,WebInspector.UIString("Cache Storage"),"CacheStorage",["database-tree-item","resource-tree-item"]);} WebInspector.ServiceWorkerCacheTreeElement.prototype={_initialize:function() {this._swCacheTreeElements=[];var target=this._storagePanel._target;if(target){var model=WebInspector.ServiceWorkerCacheModel.fromTarget(target);var caches=model.caches();for(var cache of caches) this._addCache(model,cache);} WebInspector.targetManager.addModelListener(WebInspector.ServiceWorkerCacheModel,WebInspector.ServiceWorkerCacheModel.EventTypes.CacheAdded,this._cacheAdded,this);WebInspector.targetManager.addModelListener(WebInspector.ServiceWorkerCacheModel,WebInspector.ServiceWorkerCacheModel.EventTypes.CacheRemoved,this._cacheRemoved,this);},onattach:function() {WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Refresh Caches"),this._refreshCaches.bind(this));contextMenu.show();},_refreshCaches:function() {var target=this._storagePanel._target;if(target){var model=WebInspector.ServiceWorkerCacheModel.fromTarget(target);model.refreshCacheNames();}},_cacheAdded:function(event) {var cache=(event.data);var model=(event.target);this._addCache(model,cache);},_addCache:function(model,cache) {var swCacheTreeElement=new WebInspector.SWCacheTreeElement(this._storagePanel,model,cache);this._swCacheTreeElements.push(swCacheTreeElement);this.appendChild(swCacheTreeElement);},_cacheRemoved:function(event) {var cache=(event.data);var model=(event.target);var swCacheTreeElement=this._cacheTreeElement(model,cache);if(!swCacheTreeElement) return;swCacheTreeElement.clear();this.removeChild(swCacheTreeElement);this._swCacheTreeElements.remove(swCacheTreeElement);},_cacheTreeElement:function(model,cache) {var index=-1;for(var i=0;i<this._swCacheTreeElements.length;++i){if(this._swCacheTreeElements[i]._cache.equals(cache)&&this._swCacheTreeElements[i]._model===model){index=i;break;}} if(index!==-1) return this._swCacheTreeElements[i];return null;},__proto__:WebInspector.StorageCategoryTreeElement.prototype} WebInspector.SWCacheTreeElement=function(storagePanel,model,cache) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,cache.cacheName+" - "+cache.securityOrigin,["table-tree-item","resource-tree-item"]);this._model=model;this._cache=cache;} WebInspector.SWCacheTreeElement.prototype={get itemURL() {return"cache://"+this._cache.cacheId;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Delete"),this._clearCache.bind(this));contextMenu.show();},_clearCache:function() {this._model.deleteCache(this._cache);},update:function(cache) {this._cache=cache;if(this._view) this._view.update(cache);},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.ServiceWorkerCacheView(this._model,this._cache);this._storagePanel._innerShowView(this._view);return false;},clear:function() {if(this._view) this._view.clear();},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.ServiceWorkersTreeElement=function(storagePanel) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,WebInspector.UIString("Service Workers"),["service-worker-tree-item","resource-tree-item"],false);} WebInspector.ServiceWorkersTreeElement.prototype={get itemURL() {return"service-workers://";},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.ServiceWorkersView();this._storagePanel._innerShowView(this._view);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.AppManifestTreeElement=function(storagePanel) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,WebInspector.UIString("Manifest"),["manifest-tree-item","resource-tree-item"],false,false);} WebInspector.AppManifestTreeElement.prototype={get itemURL() {return"manifest://";},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.AppManifestView();this._storagePanel._innerShowView(this._view);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.ClearStorageTreeElement=function(storagePanel) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,WebInspector.UIString("Clear storage"),["clear-storage-tree-item","resource-tree-item"],false,false);} WebInspector.ClearStorageTreeElement.prototype={get itemURL() {return"clear-storage://";},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.ClearStorageView(this._storagePanel);this._storagePanel._innerShowView(this._view);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.IndexedDBTreeElement=function(storagePanel) {WebInspector.StorageCategoryTreeElement.call(this,storagePanel,WebInspector.UIString("IndexedDB"),"IndexedDB",["database-tree-item","resource-tree-item"]);} WebInspector.IndexedDBTreeElement.prototype={_initialize:function() {WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel,WebInspector.IndexedDBModel.EventTypes.DatabaseAdded,this._indexedDBAdded,this);WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel,WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved,this._indexedDBRemoved,this);WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel,WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded,this._indexedDBLoaded,this);this._idbDatabaseTreeElements=[];var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i){var indexedDBModel=WebInspector.IndexedDBModel.fromTarget(targets[i]);var databases=indexedDBModel.databases();for(var j=0;j<databases.length;++j) this._addIndexedDB(indexedDBModel,databases[j]);}},onattach:function() {WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"),this.refreshIndexedDB.bind(this));contextMenu.show();},refreshIndexedDB:function() {var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i) WebInspector.IndexedDBModel.fromTarget(targets[i]).refreshDatabaseNames();},_indexedDBAdded:function(event) {var databaseId=(event.data);var model=(event.target);this._addIndexedDB(model,databaseId);},_addIndexedDB:function(model,databaseId) {var idbDatabaseTreeElement=new WebInspector.IDBDatabaseTreeElement(this._storagePanel,model,databaseId);this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);this.appendChild(idbDatabaseTreeElement);model.refreshDatabase(databaseId);},_indexedDBRemoved:function(event) {var databaseId=(event.data);var model=(event.target);var idbDatabaseTreeElement=this._idbDatabaseTreeElement(model,databaseId) if(!idbDatabaseTreeElement) return;idbDatabaseTreeElement.clear();this.removeChild(idbDatabaseTreeElement);this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);},_indexedDBLoaded:function(event) {var database=(event.data);var model=(event.target);var idbDatabaseTreeElement=this._idbDatabaseTreeElement(model,database.databaseId);if(!idbDatabaseTreeElement) return;idbDatabaseTreeElement.update(database);},_idbDatabaseTreeElement:function(model,databaseId) {var index=-1;for(var i=0;i<this._idbDatabaseTreeElements.length;++i){if(this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId)&&this._idbDatabaseTreeElements[i]._model===model){index=i;break;}} if(index!==-1) return this._idbDatabaseTreeElements[i];return null;},__proto__:WebInspector.StorageCategoryTreeElement.prototype} WebInspector.IDBDatabaseTreeElement=function(storagePanel,model,databaseId) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,databaseId.name+" - "+databaseId.securityOrigin,["database-tree-item","resource-tree-item"]);this._model=model;this._databaseId=databaseId;this._idbObjectStoreTreeElements={};} WebInspector.IDBDatabaseTreeElement.prototype={get itemURL() {return"indexedDB://"+this._databaseId.securityOrigin+"/"+this._databaseId.name;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"),this._refreshIndexedDB.bind(this));contextMenu.show();},_refreshIndexedDB:function() {this._model.refreshDatabaseNames();},update:function(database) {this._database=database;var objectStoreNames={};for(var objectStoreName in this._database.objectStores){var objectStore=this._database.objectStores[objectStoreName];objectStoreNames[objectStore.name]=true;if(!this._idbObjectStoreTreeElements[objectStore.name]){var idbObjectStoreTreeElement=new WebInspector.IDBObjectStoreTreeElement(this._storagePanel,this._model,this._databaseId,objectStore);this._idbObjectStoreTreeElements[objectStore.name]=idbObjectStoreTreeElement;this.appendChild(idbObjectStoreTreeElement);} this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);} for(var objectStoreName in this._idbObjectStoreTreeElements){if(!objectStoreNames[objectStoreName]) this._objectStoreRemoved(objectStoreName);} if(this._view) this._view.update(database);this._updateTooltip();},_updateTooltip:function() {this.tooltip=WebInspector.UIString("Version")+": "+this._database.version;},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.IDBDatabaseView(this._database);this._storagePanel._innerShowView(this._view);return false;},_objectStoreRemoved:function(objectStoreName) {var objectStoreTreeElement=this._idbObjectStoreTreeElements[objectStoreName];objectStoreTreeElement.clear();this.removeChild(objectStoreTreeElement);delete this._idbObjectStoreTreeElements[objectStoreName];},clear:function() {for(var objectStoreName in this._idbObjectStoreTreeElements) this._objectStoreRemoved(objectStoreName);},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.IDBObjectStoreTreeElement=function(storagePanel,model,databaseId,objectStore) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,objectStore.name,["table-tree-item","resource-tree-item"]);this._model=model;this._databaseId=databaseId;this._idbIndexTreeElements={};} WebInspector.IDBObjectStoreTreeElement.prototype={get itemURL() {return"indexedDB://"+this._databaseId.securityOrigin+"/"+this._databaseId.name+"/"+this._objectStore.name;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Clear"),this._clearObjectStore.bind(this));contextMenu.show();},_clearObjectStore:function() {function callback(){this.update(this._objectStore);} this._model.clearObjectStore(this._databaseId,this._objectStore.name,callback.bind(this));},update:function(objectStore) {this._objectStore=objectStore;var indexNames={};for(var indexName in this._objectStore.indexes){var index=this._objectStore.indexes[indexName];indexNames[index.name]=true;if(!this._idbIndexTreeElements[index.name]){var idbIndexTreeElement=new WebInspector.IDBIndexTreeElement(this._storagePanel,this._model,this._databaseId,this._objectStore,index);this._idbIndexTreeElements[index.name]=idbIndexTreeElement;this.appendChild(idbIndexTreeElement);} this._idbIndexTreeElements[index.name].update(index);} for(var indexName in this._idbIndexTreeElements){if(!indexNames[indexName]) this._indexRemoved(indexName);} for(var indexName in this._idbIndexTreeElements){if(!indexNames[indexName]){this.removeChild(this._idbIndexTreeElements[indexName]);delete this._idbIndexTreeElements[indexName];}} if(this.childCount()) this.expand();if(this._view) this._view.update(this._objectStore);this._updateTooltip();},_updateTooltip:function() {var keyPathString=this._objectStore.keyPathString;var tooltipString=keyPathString!==null?(WebInspector.UIString("Key path: ")+keyPathString):"";if(this._objectStore.autoIncrement) tooltipString+="\n"+WebInspector.UIString("autoIncrement");this.tooltip=tooltipString;},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.IDBDataView(this._model,this._databaseId,this._objectStore,null);this._storagePanel._innerShowView(this._view);return false;},_indexRemoved:function(indexName) {var indexTreeElement=this._idbIndexTreeElements[indexName];indexTreeElement.clear();this.removeChild(indexTreeElement);delete this._idbIndexTreeElements[indexName];},clear:function() {for(var indexName in this._idbIndexTreeElements) this._indexRemoved(indexName);if(this._view) this._view.clear();},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.IDBIndexTreeElement=function(storagePanel,model,databaseId,objectStore,index) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,index.name,["index-tree-item","resource-tree-item"]);this._model=model;this._databaseId=databaseId;this._objectStore=objectStore;this._index=index;} WebInspector.IDBIndexTreeElement.prototype={get itemURL() {return"indexedDB://"+this._databaseId.securityOrigin+"/"+this._databaseId.name+"/"+this._objectStore.name+"/"+this._index.name;},update:function(index) {this._index=index;if(this._view) this._view.update(this._index);this._updateTooltip();},_updateTooltip:function() {var tooltipLines=[];var keyPathString=this._index.keyPathString;tooltipLines.push(WebInspector.UIString("Key path: ")+keyPathString);if(this._index.unique) tooltipLines.push(WebInspector.UIString("unique"));if(this._index.multiEntry) tooltipLines.push(WebInspector.UIString("multiEntry"));this.tooltip=tooltipLines.join("\n");},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);if(!this._view) this._view=new WebInspector.IDBDataView(this._model,this._databaseId,this._objectStore,this._index);this._storagePanel._innerShowView(this._view);return false;},clear:function() {if(this._view) this._view.clear();},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.DOMStorageTreeElement=function(storagePanel,domStorage) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,domStorage.securityOrigin?domStorage.securityOrigin:WebInspector.UIString("Local Files"),["table-tree-item","resource-tree-item"]);this._domStorage=domStorage;} WebInspector.DOMStorageTreeElement.prototype={get itemURL() {return"storage://"+this._domStorage.securityOrigin+"/"+(this._domStorage.isLocalStorage?"local":"session");},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel._showDOMStorage(this._domStorage);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.CookieTreeElement=function(storagePanel,cookieDomain) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,cookieDomain?cookieDomain:WebInspector.UIString("Local Files"),["cookie-tree-item","resource-tree-item"]);this._cookieDomain=cookieDomain;} WebInspector.CookieTreeElement.prototype={get itemURL() {return"cookies://"+this._cookieDomain;},onattach:function() {WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),true);},_handleContextMenuEvent:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Clear"),this._clearCookies.bind(this));contextMenu.show();},_clearCookies:function(domain) {this._storagePanel.clearCookies(this._cookieDomain);},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel.showCookies(this,this._cookieDomain);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.ApplicationCacheManifestTreeElement=function(storagePanel,manifestURL) {var title=new WebInspector.ParsedURL(manifestURL).displayName;WebInspector.BaseStorageTreeElement.call(this,storagePanel,title,["application-cache-storage-tree-item"]);this.tooltip=manifestURL;this._manifestURL=manifestURL;} WebInspector.ApplicationCacheManifestTreeElement.prototype={get itemURL() {return"appcache://"+this._manifestURL;},get manifestURL() {return this._manifestURL;},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel.showCategoryView(this._manifestURL);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.ApplicationCacheFrameTreeElement=function(storagePanel,frameId,manifestURL) {WebInspector.BaseStorageTreeElement.call(this,storagePanel,"",["navigator-tree-item","navigator-folder-tree-item"]);this._frameId=frameId;this._manifestURL=manifestURL;this._refreshTitles();} WebInspector.ApplicationCacheFrameTreeElement.prototype={get itemURL() {return"appcache://"+this._manifestURL+"/"+encodeURI(this.titleAsText());},get frameId() {return this._frameId;},get manifestURL() {return this._manifestURL;},_refreshTitles:function() {var frame=this._storagePanel._target.resourceTreeModel.frameForId(this._frameId);this.title=frame.displayName();},frameNavigated:function() {this._refreshTitles();},onselect:function(selectedByUser) {WebInspector.BaseStorageTreeElement.prototype.onselect.call(this,selectedByUser);this._storagePanel.showApplicationCache(this._frameId);return false;},__proto__:WebInspector.BaseStorageTreeElement.prototype} WebInspector.StorageCategoryView=function() {WebInspector.VBox.call(this);this.element.classList.add("storage-view");this._emptyWidget=new WebInspector.EmptyWidget("");this._emptyWidget.show(this.element);} WebInspector.StorageCategoryView.prototype={toolbarItems:function() {return[];},setText:function(text) {this._emptyWidget.text=text;},__proto__:WebInspector.VBox.prototype} WebInspector.ResourcesPanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.ResourcesPanel._instance());} WebInspector.ResourcesPanel._instance=function() {if(!WebInspector.ResourcesPanel._instanceObject) WebInspector.ResourcesPanel._instanceObject=new WebInspector.ResourcesPanel();return WebInspector.ResourcesPanel._instanceObject;} WebInspector.ResourcesPanelFactory=function() {} WebInspector.ResourcesPanelFactory.prototype={createPanel:function() {return WebInspector.ResourcesPanel._instance();}};WebInspector.ServiceWorkerCacheView=function(model,cache) {WebInspector.VBox.call(this);this.registerRequiredCSS("resources/serviceWorkerCacheViews.css");this._model=model;this.element.classList.add("service-worker-cache-data-view");this.element.classList.add("storage-view");this._createEditorToolbar();this._refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this._refreshButton.addEventListener("click",this._refreshButtonClicked,this);this._pageSize=50;this._skipCount=0;this.update(cache);this._entries=[];} WebInspector.ServiceWorkerCacheView.prototype={_createDataGrid:function() {var columns=[];columns.push({id:"number",title:WebInspector.UIString("#"),width:"50px"});columns.push({id:"request",title:WebInspector.UIString("Request")});columns.push({id:"response",title:WebInspector.UIString("Response")});var dataGrid=new WebInspector.DataGrid(columns,undefined,this._deleteButtonClicked.bind(this),this._updateData.bind(this,true));return dataGrid;},_createEditorToolbar:function() {var editorToolbar=new WebInspector.Toolbar("data-view-toolbar",this.element);this._pageBackButton=new WebInspector.ToolbarButton(WebInspector.UIString("Show previous page"),"play-backwards-toolbar-item");this._pageBackButton.addEventListener("click",this._pageBackButtonClicked,this);editorToolbar.appendToolbarItem(this._pageBackButton);this._pageForwardButton=new WebInspector.ToolbarButton(WebInspector.UIString("Show next page"),"play-toolbar-item");this._pageForwardButton.setEnabled(false);this._pageForwardButton.addEventListener("click",this._pageForwardButtonClicked,this);editorToolbar.appendToolbarItem(this._pageForwardButton);},_pageBackButtonClicked:function() {this._skipCount=Math.max(0,this._skipCount-this._pageSize);this._updateData(false);},_pageForwardButtonClicked:function() {this._skipCount=this._skipCount+this._pageSize;this._updateData(false);},_deleteButtonClicked:function(node) {this._model.deleteCacheEntry(this._cache,node.data["request"],node.remove.bind(node));},update:function(cache) {this._cache=cache;if(this._dataGrid) this._dataGrid.asWidget().detach();this._dataGrid=this._createDataGrid();this._dataGrid.asWidget().show(this.element);this._skipCount=0;this._updateData(true);},_updateDataCallback(skipCount,entries,hasMore) {this._refreshButton.setEnabled(true);this.clear();this._entries=entries;for(var i=0;i<entries.length;++i){var data={};data["number"]=i+skipCount;data["request"]=entries[i].request;data["response"]=entries[i].response;var node=new WebInspector.DataGridNode(data);node.selectable=true;this._dataGrid.rootNode().appendChild(node);} this._pageBackButton.setEnabled(!!skipCount);this._pageForwardButton.setEnabled(hasMore);},_updateData:function(force) {var pageSize=this._pageSize;var skipCount=this._skipCount;this._refreshButton.setEnabled(false);if(!force&&this._lastPageSize===pageSize&&this._lastSkipCount===skipCount) return;if(this._lastPageSize!==pageSize){skipCount=0;this._skipCount=0;} this._lastPageSize=pageSize;this._lastSkipCount=skipCount;this._model.loadCacheData(this._cache,skipCount,pageSize,this._updateDataCallback.bind(this,skipCount));},_refreshButtonClicked:function(event) {this._updateData(true);},toolbarItems:function() {return[this._refreshButton];},clear:function() {this._dataGrid.rootNode().removeChildren();this._entries=[];},__proto__:WebInspector.VBox.prototype};WebInspector.ServiceWorkersView=function() {WebInspector.VBox.call(this,true);this._reportView=new WebInspector.ReportView(WebInspector.UIString("Service Workers"));this._reportView.show(this.contentElement);this._toolbar=this._reportView.createToolbar();this._sections=new Map();WebInspector.targetManager.observeTargets(this);} WebInspector.ServiceWorkersView.prototype={targetAdded:function(target) {if(this._target||!target.serviceWorkerManager) return;this._target=target;this._manager=this._target.serviceWorkerManager;this._toolbar.appendToolbarItem(WebInspector.NetworkConditionsSelector.createOfflineToolbarCheckbox());var forceUpdate=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Update on reload"),WebInspector.UIString("Force update Service Worker on page reload"),this._manager.forceUpdateOnReloadSetting());this._toolbar.appendToolbarItem(forceUpdate);var fallbackToNetwork=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Bypass for network"),WebInspector.UIString("Bypass Service Worker and load resources from the network"),target.networkManager.bypassServiceWorkerSetting());this._toolbar.appendToolbarItem(fallbackToNetwork);this._toolbar.appendSpacer();this._showAllCheckbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString("Show all"),WebInspector.UIString("Show all Service Workers regardless of the origin"));this._showAllCheckbox.inputElement.addEventListener("change",this._updateSectionVisibility.bind(this),false);this._toolbar.appendToolbarItem(this._showAllCheckbox);for(var registration of this._manager.registrations().values()) this._updateRegistration(registration);this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationUpdated,this._registrationUpdated,this);this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationDeleted,this._registrationDeleted,this);this._manager.addEventListener(WebInspector.ServiceWorkerManager.Events.RegistrationErrorAdded,this._registrationErrorAdded,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded,this._updateSectionVisibility,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved,this._updateSectionVisibility,this);},targetRemoved:function(target) {if(target!==this._target) return;delete this._target;},_updateSectionVisibility:function() {var securityOrigins=new Set(this._target.resourceTreeModel.securityOrigins());for(var section of this._sections.values()){var visible=this._showAllCheckbox.checked()||securityOrigins.has(section._registration.securityOrigin);section._section.element.classList.toggle("hidden",!visible);}},_registrationUpdated:function(event) {var registration=(event.data);this._updateRegistration(registration);},_registrationErrorAdded:function(event) {var registration=(event.data["registration"]);var error=(event.data["error"]);var section=this._sections.get(registration);if(!section) return;section._addError(error);},_updateRegistration:function(registration) {var section=this._sections.get(registration);if(!section){section=new WebInspector.ServiceWorkersView.Section(this._manager,this._reportView.appendSection(""),registration);this._sections.set(registration,section);} this._updateSectionVisibility();section._scheduleUpdate();},_registrationDeleted:function(event) {var registration=(event.data);var section=this._sections.get(registration);if(section) section._section.remove();this._sections.delete(registration);},__proto__:WebInspector.VBox.prototype} WebInspector.ServiceWorkersView.Section=function(manager,section,registration) {this._manager=manager;this._section=section;this._registration=registration;this._toolbar=section.createToolbar();this._toolbar.renderAsLinks();this._updateButton=new WebInspector.ToolbarButton(WebInspector.UIString("Update"),undefined,WebInspector.UIString("Update"));this._updateButton.addEventListener("click",this._updateButtonClicked.bind(this));this._toolbar.appendToolbarItem(this._updateButton);this._pushButton=new WebInspector.ToolbarButton(WebInspector.UIString("Emulate push event"),undefined,WebInspector.UIString("Push"));this._pushButton.addEventListener("click",this._pushButtonClicked.bind(this));this._toolbar.appendToolbarItem(this._pushButton);this._deleteButton=new WebInspector.ToolbarButton(WebInspector.UIString("Unregister service worker"),undefined,WebInspector.UIString("Unregister"));this._deleteButton.addEventListener("click",this._unregisterButtonClicked.bind(this));this._toolbar.appendToolbarItem(this._deleteButton);this._section.appendField(WebInspector.UIString("Source"));this._section.appendField(WebInspector.UIString("Status"));this._section.appendField(WebInspector.UIString("Clients"));this._section.appendField(WebInspector.UIString("Errors"));this._errorsList=this._wrapWidget(this._section.appendRow());this._errorsList.classList.add("service-worker-error-stack","monospace","hidden");this._linkifier=new WebInspector.Linkifier();this._clientInfoCache=new Map();for(var error of registration.errors) this._addError(error);this._throttler=new WebInspector.Throttler(500);} WebInspector.ServiceWorkersView.Section.prototype={_scheduleUpdate:function() {if(WebInspector.ServiceWorkersView._noThrottle){this._update();return;} this._throttler.schedule(this._update.bind(this));},_update:function() {var fingerprint=this._registration.fingerprint();if(fingerprint===this._fingerprint) return Promise.resolve();this._fingerprint=fingerprint;this._toolbar.setEnabled(!this._registration.isDeleted);var versions=this._registration.versionsByMode();var title=this._registration.isDeleted?WebInspector.UIString("%s - deleted",this._registration.scopeURL):this._registration.scopeURL;this._section.setTitle(title);var active=versions.get(WebInspector.ServiceWorkerVersion.Modes.Active);var waiting=versions.get(WebInspector.ServiceWorkerVersion.Modes.Waiting);var installing=versions.get(WebInspector.ServiceWorkerVersion.Modes.Installing);var statusValue=this._wrapWidget(this._section.appendField(WebInspector.UIString("Status")));statusValue.removeChildren();var versionsStack=statusValue.createChild("div","service-worker-version-stack");versionsStack.createChild("div","service-worker-version-stack-bar");if(active){var scriptElement=this._section.appendField(WebInspector.UIString("Source"));scriptElement.removeChildren();var fileName=WebInspector.ParsedURL.extractName(active.scriptURL);scriptElement.appendChild(WebInspector.linkifyURLAsNode(active.scriptURL,fileName));scriptElement.createChild("div","report-field-value-subtitle").textContent=WebInspector.UIString("Received %s",new Date(active.scriptResponseTime*1000).toLocaleString());var activeEntry=versionsStack.createChild("div","service-worker-version");activeEntry.createChild("div","service-worker-active-circle");activeEntry.createChild("span").textContent=WebInspector.UIString("#%s activated and is %s",active.id,active.runningStatus);if(active.isRunning()||active.isStarting()){createLink(activeEntry,WebInspector.UIString("stop"),this._stopButtonClicked.bind(this,active.id));if(!this._manager.targetForVersionId(active.id)) createLink(activeEntry,WebInspector.UIString("inspect"),this._inspectButtonClicked.bind(this,active.id));}else if(active.isStartable()){createLink(activeEntry,WebInspector.UIString("start"),this._startButtonClicked.bind(this));} var clientsList=this._wrapWidget(this._section.appendField(WebInspector.UIString("Clients")));clientsList.removeChildren();this._section.setFieldVisible(WebInspector.UIString("Clients"),active.controlledClients.length);for(var client of active.controlledClients){var clientLabelText=clientsList.createChild("div","service-worker-client");if(this._clientInfoCache.has(client)) this._updateClientInfo(clientLabelText,(this._clientInfoCache.get(client)));this._manager.getTargetInfo(client,this._onClientInfo.bind(this,clientLabelText));}} if(waiting){var waitingEntry=versionsStack.createChild("div","service-worker-version");waitingEntry.createChild("div","service-worker-waiting-circle");waitingEntry.createChild("span").textContent=WebInspector.UIString("#%s waiting to activate",waiting.id);createLink(waitingEntry,WebInspector.UIString("skipWaiting"),this._skipButtonClicked.bind(this));waitingEntry.createChild("div","service-worker-subtitle").textContent=new Date(waiting.scriptResponseTime*1000).toLocaleString();if(!this._manager.targetForVersionId(waiting.id)&&(waiting.isRunning()||waiting.isStarting())) createLink(waitingEntry,WebInspector.UIString("inspect"),this._inspectButtonClicked.bind(this,waiting.id));} if(installing){var installingEntry=versionsStack.createChild("div","service-worker-version");installingEntry.createChild("div","service-worker-installing-circle");installingEntry.createChild("span").textContent=WebInspector.UIString("#%s installing",installing.id);installingEntry.createChild("div","service-worker-subtitle").textContent=new Date(installing.scriptResponseTime*1000).toLocaleString();if(!this._manager.targetForVersionId(installing.id)&&(installing.isRunning()||installing.isStarting())) createLink(installingEntry,WebInspector.UIString("inspect"),this._inspectButtonClicked.bind(this,installing.id));} this._section.setFieldVisible(WebInspector.UIString("Errors"),!!this._registration.errors.length);var errorsValue=this._wrapWidget(this._section.appendField(WebInspector.UIString("Errors")));var errorsLabel=createLabel(String(this._registration.errors.length),"error-icon");errorsLabel.classList.add("service-worker-errors-label");errorsValue.appendChild(errorsLabel);this._moreButton=createLink(errorsValue,this._errorsList.classList.contains("hidden")?WebInspector.UIString("details"):WebInspector.UIString("hide"),this._moreErrorsButtonClicked.bind(this));createLink(errorsValue,WebInspector.UIString("clear"),this._clearErrorsButtonClicked.bind(this));function createLink(parent,title,listener) {var span=parent.createChild("span","link");span.textContent=title;span.addEventListener("click",listener,false);return span;} return Promise.resolve();},_addError:function(error) {var target=this._manager.targetForVersionId(error.versionId);var message=this._errorsList.createChild("div");if(this._errorsList.childElementCount>100) this._errorsList.firstElementChild.remove();message.appendChild(this._linkifier.linkifyScriptLocation(target,null,error.sourceURL,error.lineNumber));message.appendChild(createLabel("#"+error.versionId+": "+error.errorMessage,"error-icon"));},_unregisterButtonClicked:function() {this._manager.deleteRegistration(this._registration.id);},_updateButtonClicked:function() {this._manager.updateRegistration(this._registration.id);},_pushButtonClicked:function() {var data="Test push message from DevTools." this._manager.deliverPushMessage(this._registration.id,data);},_onClientInfo:function(element,targetInfo) {if(!targetInfo) return;this._clientInfoCache.set(targetInfo.id,targetInfo);this._updateClientInfo(element,targetInfo);},_updateClientInfo:function(element,targetInfo) {if(!(targetInfo.isWebContents()||targetInfo.isFrame())){element.createTextChild(WebInspector.UIString("Worker: %s",targetInfo.url));return;} element.removeChildren();element.createTextChild(targetInfo.url);var focusLabel=element.createChild("label","link");focusLabel.createTextChild("focus");focusLabel.addEventListener("click",this._activateTarget.bind(this,targetInfo.id),true);},_activateTarget:function(targetId) {this._manager.activateTarget(targetId);},_startButtonClicked:function() {this._manager.startWorker(this._registration.scopeURL);},_skipButtonClicked:function() {this._manager.skipWaiting(this._registration.scopeURL);},_stopButtonClicked:function(versionId) {this._manager.stopWorker(versionId);},_moreErrorsButtonClicked:function() {var newVisible=this._errorsList.classList.contains("hidden");this._moreButton.textContent=newVisible?WebInspector.UIString("hide"):WebInspector.UIString("details");this._errorsList.classList.toggle("hidden",!newVisible);},_clearErrorsButtonClicked:function() {this._errorsList.removeChildren();this._registration.clearErrors();this._scheduleUpdate();if(!this._errorsList.classList.contains("hidden")) this._moreErrorsButtonClicked();},_inspectButtonClicked:function(versionId) {this._manager.inspectWorker(versionId);},_wrapWidget:function(container) {var shadowRoot=WebInspector.createShadowRootWithCoreStyles(container);WebInspector.appendStyle(shadowRoot,"resources/serviceWorkersView.css");var contentElement=createElement("div");shadowRoot.appendChild(contentElement);return contentElement;},_dispose:function() {this._linkifier.dispose();if(this._pendingUpdate) clearTimeout(this._pendingUpdate);}};Runtime.cachedResources["resources/appManifestView.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n/*# sourceURL=resources/appManifestView.css */";Runtime.cachedResources["resources/clearStorageView.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.report-row {\n display: flex;\n align-items: center;\n}\n\n.clear-storage-button .report-row {\n margin: 0 0 0 20px;\n display: flex;\n}\n\n.link {\n margin-left: 10px;\n display: none;\n}\n\n.report-row:hover .link {\n display: inline;\n}\n\n/*# sourceURL=resources/clearStorageView.css */";Runtime.cachedResources["resources/indexedDBViews.css"]="/*\n * Copyright (C) 2012 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.indexed-db-database-view {\n -webkit-user-select: text;\n margin-top: 5px;\n}\n\n.indexed-db-database-view .outline-disclosure {\n padding-left: 0;\n}\n\n.indexed-db-database-view .outline-disclosure li {\n white-space: nowrap;\n}\n\n.indexed-db-database-view .outline-disclosure .attribute-name {\n color: rgb(33%, 33%, 33%);\n display: inline-block;\n margin-right: 0.5em;\n font-weight: bold;\n vertical-align: top;\n}\n\n.indexed-db-database-view .outline-disclosure .attribute-value {\n display: inline;\n margin-top: 1px;\n}\n\n.indexed-db-data-view .data-view-toolbar {\n position: relative;\n background-color: #eee;\n border-bottom: 1px solid #ccc;\n}\n\n.indexed-db-data-view .data-view-toolbar .key-input {\n font-size: 11px;\n margin: auto 0;\n width: 200px;\n}\n\n.indexed-db-data-view .data-grid {\n flex: auto;\n}\n\n.indexed-db-data-view .data-grid .data-container tr:nth-child(even) {\n background-color: white;\n}\n\n.indexed-db-data-view .data-grid .data-container tr:nth-child(odd) {\n background-color: #EAF3FF;\n}\n\n.indexed-db-data-view .data-grid .data-container tr:nth-last-child(1) {\n background-color: white;\n}\n\n.indexed-db-data-view .data-grid .data-container tr:nth-last-child(1) td {\n border: 0;\n}\n\n.indexed-db-data-view .data-grid .data-container tr:nth-last-child(2) td {\n border-bottom: 1px solid #aaa;\n}\n\n.indexed-db-data-view .section,\n.indexed-db-data-view .section > .header,\n.indexed-db-data-view .section > .header .title {\n margin: 0;\n min-height: inherit;\n line-height: inherit;\n}\n\n.indexed-db-data-view .primitive-value {\n padding-top: 1px;\n}\n\n.indexed-db-data-view .data-grid .data-container td .section .header .title {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.indexed-db-key-path {\n color: rgb(196, 26, 22);\n white-space: pre-wrap;\n unicode-bidi: -webkit-isolate;\n}\n\n/*# sourceURL=resources/indexedDBViews.css */";Runtime.cachedResources["resources/resourcesPanel.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.resources.panel .sidebar {\n padding-left: 0;\n z-index: 10;\n display: block;\n}\n\n.resources.panel .sidebar li {\n height: 18px;\n white-space: nowrap;\n padding-top: 1px;\n padding: 16px 0;\n}\n\n.resources.panel .sidebar li.selected {\n color: white;\n}\n\n.resources.panel .sidebar li.selected .selection {\n background-color: rgb(160, 160, 160);\n border-top: 1px solid #979797;\n}\n\n.resources.panel .sidebar :focus li.selected .selection {\n background-color: rgb(56, 121, 217);\n border-top: 1px solid rgb(68, 128, 200);\n}\n\n.resources.panel .sidebar .icon {\n width: 16px;\n height: 16px;\n position: relative;\n top: 3px;\n margin-top: -3px;\n display: inline-block;\n}\n\n.resources-toolbar {\n border-top: 1px solid #ccc;\n background-color: #eee;\n}\n\nli.selected .base-storage-tree-element-subtitle {\n color: white;\n}\n\n.base-storage-tree-element-subtitle {\n padding-left: 2px;\n color: rgb(80, 80, 80);\n text-shadow: none;\n}\n\n.resources.panel .status {\n float: right;\n height: 16px;\n margin-top: 1px;\n margin-left: 4px;\n line-height: 1em;\n}\n\n.storage-view {\n display: flex;\n overflow: hidden;\n}\n\n.storage-view {\n overflow: hidden;\n}\n\n.storage-view .data-grid:not(.inline) {\n border: none;\n flex: auto;\n}\n\n.storage-view .storage-table-error {\n color: rgb(66%, 33%, 33%);\n font-size: 24px;\n font-weight: bold;\n padding: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.storage-view.query {\n padding: 2px 0;\n overflow-y: overlay;\n overflow-x: hidden;\n}\n\n.database-query-prompt {\n position: relative;\n padding: 1px 22px 1px 24px;\n min-height: 16px;\n white-space: pre-wrap;\n -webkit-user-modify: read-write-plaintext-only;\n -webkit-user-select: text;\n}\n\n.database-user-query::before,\n.database-query-prompt::before,\n.database-query-result::before {\n position: absolute;\n display: block;\n content: \"\";\n left: 7px;\n top: 0.8em;\n width: 10px;\n height: 10px;\n margin-top: -7px;\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.database-user-query::before,\n.database-query-prompt::before,\n.database-query-result::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.database-query-prompt::before {\n background-position: -192px -96px;\n}\n\n.database-user-query {\n position: relative;\n border-bottom: 1px solid rgb(245, 245, 245);\n padding: 1px 22px 1px 24px;\n min-height: 16px;\n flex-shrink: 0;\n}\n\n.database-user-query::before {\n background-position: -192px -107px;\n}\n\n.database-query-text {\n color: rgb(0, 128, 255);\n -webkit-user-select: text;\n}\n\n.database-query-result {\n position: relative;\n padding: 1px 22px 1px 24px;\n min-height: 16px;\n margin-left: -24px;\n padding-right: 0;\n}\n\n.database-query-result.error {\n color: red;\n -webkit-user-select: text;\n}\n\n.database-query-result.error::before {\n background-position: -213px -96px;\n}\n\n.resource-sidebar-tree-item .icon {\n content: url(Images/resourcePlainIconSmall.png);\n}\n\n.resource-sidebar-tree-item.resources-type-image .icon {\n position: relative;\n background-image: url(Images/resourcePlainIcon.png);\n background-repeat: no-repeat;\n content: \"\";\n}\n\n.resources-type-image .image-resource-icon-preview {\n position: absolute;\n margin: auto;\n min-width: 1px;\n min-height: 1px;\n top: 2px;\n bottom: 1px;\n left: 3px;\n right: 3px;\n max-width: 8px;\n max-height: 11px;\n overflow: hidden;\n}\n\n.resources-sidebar {\n padding-left: 0;\n}\n\n/*# sourceURL=resources/resourcesPanel.css */";Runtime.cachedResources["resources/resourcesSidebar.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.tree-outline {\n padding-left: 0;\n color: rgb(90, 90, 90);\n}\n\n.tree-outline > ol {\n padding-bottom: 10px;\n}\n\n.icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n}\n\n.tree-outline-disclosure li {\n min-height: 20px;\n}\n\nli.storage-group-list-item {\n border-top: 1px solid rgb(230, 230, 230);\n padding: 10px 8px 6px 8px;\n}\n\nli.storage-group-list-item::before {\n display: none;\n}\n\n.navigator-tree-item .icon {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n width: 32px;\n height: 20px;\n -webkit-mask-position: -224px -72px;\n position: relative;\n top: -2px;\n margin-right: -3px;\n margin-left: -9px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.navigator-tree-item .icon {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.navigator-file-tree-item .icon {\n -webkit-mask-position: -224px -72px;\n background: linear-gradient(45deg, hsl(0, 0%, 50%), hsl(0, 0%, 70%));\n}\n\n:focus .navigator-file-tree-item.selected .icon,\n:focus .navigator-folder-tree-item.selected .icon,\n:focus .navigator-frame-tree-item.selected .icon {\n background: white !important;\n}\n\n.navigator-folder-tree-item .icon {\n -webkit-mask-position: -64px -120px;\n background: linear-gradient(45deg, hsl(210, 82%, 65%), hsl(210, 82%, 80%));\n}\n\n.navigator-domain-tree-item .icon {\n -webkit-mask-position: -160px -144px;\n}\n\n.navigator-frame-tree-item .icon {\n -webkit-mask-position: -256px -144px;\n background-color: #5a5a5a;\n}\n\n.navigator-script-tree-item .icon {\n background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));\n}\n\n.navigator-stylesheet-tree-item .icon {\n background: linear-gradient(45deg, hsl(256, 50%, 50%), hsl(256, 50%, 70%));\n}\n\n.navigator-image-tree-item .icon,\n.navigator-font-tree-item .icon {\n background: linear-gradient(45deg, hsl(109, 33%, 50%), hsl(109, 33%, 70%));\n}\n\n.resource-tree-item .icon {\n -webkit-mask: url(Images/resourceGlyphs.png) no-repeat 0 0;\n -webkit-mask-size: 140px 20px;\n background: rgba(90, 90, 90, .7);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.resource-tree-item .icon {\n -webkit-mask-image: url(Images/resourceGlyphs_2x.png);\n}\n} /* media */\n\n:focus .resource-tree-item.selected .icon {\n background: white !important;\n}\n\n.database-tree-item .icon {\n -webkit-mask-position: -60px 0;\n}\n\n.table-tree-item .icon {\n -webkit-mask-position: -80px 0;\n}\n\n:focus .service-workers-tree-item.selected .icon {\n -webkit-filter: invert();\n}\n\n.-theme-with-dark-background .service-workers-tree-item .icon,\n{\n -webkit-filter: invert(70%);\n}\n\n.cookie-tree-item .icon {\n -webkit-mask-position: -120px 0;\n}\n\n.manifest-tree-item .icon {\n -webkit-mask-position: 0 0;\n}\n\n.service-worker-tree-item .icon {\n -webkit-mask-position: -20px 0;\n}\n\n.clear-storage-tree-item .icon {\n -webkit-mask-position: -40px 0;\n}\n\n/*# sourceURL=resources/resourcesSidebar.css */";Runtime.cachedResources["resources/serviceWorkerCacheViews.css"]="/*\n * Copyright 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.service-worker-cache-data-view .data-view-toolbar {\n position: relative;\n background-color: #eee;\n border-bottom: 1px solid #ccc;\n}\n\n.service-worker-cache-data-view .data-view-toolbar .key-input {\n font-size: 11px;\n margin: auto 0;\n width: 200px;\n}\n\n.service-worker-cache-data-view .data-grid {\n flex: auto;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr:nth-child(even) {\n background-color: white;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr:nth-child(odd) {\n background-color: #EAF3FF;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr:nth-last-child(1) {\n background-color: white;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr:nth-last-child(1) td {\n border: 0;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr:nth-last-child(2) td {\n border-bottom: 1px solid #aaa;\n}\n\n.service-worker-cache-data-view .data-grid .data-container tr.selected {\n background-color: rgb(212, 212, 212);\n color: inherit;\n}\n\n.service-worker-cache-data-view .data-grid:focus .data-container tr.selected {\n background-color: rgb(56, 121, 217);\n color: white;\n}\n\n.service-worker-cache-data-view .section,\n.service-worker-cache-data-view .section > .header,\n.service-worker-cache-data-view .section > .header .title {\n margin: 0;\n min-height: inherit;\n line-height: inherit;\n}\n\n.service-worker-cache-data-view .primitive-value {\n padding-top: 1px;\n}\n\n.service-worker-cache-data-view .data-grid .data-container td .section .header .title {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n/*# sourceURL=resources/serviceWorkerCacheViews.css */";Runtime.cachedResources["resources/serviceWorkersView.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.service-worker-error-stack {\n max-height: 200px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n border: 1px solid #ccc;\n background-color: #fff0f0;\n color: red;\n line-height: 18px;\n margin: 10px 2px 0 -14px;\n white-space: initial;\n}\n\n.service-worker-error-stack > div {\n flex: none;\n padding: 3px 4px;\n}\n\n.service-worker-error-stack > div:not(:last-child) {\n border-bottom: 1px solid #ffd7d7;\n}\n\n.service-worker-error-stack label {\n flex: auto;\n}\n\n.service-worker-error-stack a {\n float: right;\n color: rgb(33%, 33%, 33%);\n cursor: pointer;\n}\n\n.service-worker-version-stack {\n position: relative;\n}\n\n.service-worker-version-stack-bar {\n position: absolute;\n top: 10px;\n bottom: 20px;\n left: 4px;\n content: \"\";\n border-left: 1px solid #888;\n z-index: 0;\n}\n\n.service-worker-version:not(:last-child) {\n margin-bottom: 7px;\n}\n\n.service-worker-active-circle,\n.service-worker-waiting-circle,\n.service-worker-installing-circle {\n position: relative;\n display: inline-block;\n width: 10px;\n height: 10px;\n z-index: 10;\n margin-right: 5px;\n border-radius: 50%;\n border: 1px solid #555;\n}\n\n.service-worker-active-circle {\n background-color: #50B04F;\n}\n.service-worker-waiting-circle {\n background-color: #F38E24;\n\n}\n.service-worker-installing-circle {\n background-color: white;\n}\n\n\n.service-worker-subtitle {\n padding-left: 14px;\n line-height: 14px;\n color: #888;\n}\n\n.link {\n margin-left: 10px;\n}\n\n/*# sourceURL=resources/serviceWorkersView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.SASSSupport={}
WebInspector.SASSSupport.parseSCSS=function(url,content)
{var text=new WebInspector.Text(content);var document=new WebInspector.SASSSupport.ASTDocument(url,text);return WebInspector.formatterWorkerPool.runTask("parseSCSS",{content:content}).then(onParsed);function onParsed(event)
{if(!event)
return new WebInspector.SASSSupport.AST(document,[]);var data=(event.data);var rules=[];for(var i=0;i<data.length;++i){var rulePayload=data[i];var selectors=rulePayload.selectors.map(createTextNode);var properties=rulePayload.properties.map(createProperty);var range=WebInspector.TextRange.fromObject(rulePayload.styleRange);var rule=new WebInspector.SASSSupport.Rule(document,selectors,range,properties);rules.push(rule);}
return new WebInspector.SASSSupport.AST(document,rules);}
function createTextNode(payload)
{var range=WebInspector.TextRange.fromObject(payload);var value=text.extract(range);return new WebInspector.SASSSupport.TextNode(document,text.extract(range),range);}
function createProperty(payload)
{var name=createTextNode(payload.name);var value=createTextNode(payload.value);return new WebInspector.SASSSupport.Property(document,name,value,WebInspector.TextRange.fromObject(payload.range),payload.disabled);}}
WebInspector.SASSSupport.ASTDocument=function(url,text)
{this.url=url;this.text=text;this.edits=[];}
WebInspector.SASSSupport.ASTDocument.prototype={clone:function()
{return new WebInspector.SASSSupport.ASTDocument(this.url,this.text);},hasChanged:function()
{return!!this.edits.length;},newText:function()
{this.edits.stableSort(sequentialOrder);var text=this.text;for(var i=this.edits.length-1;i>=0;--i){var range=this.edits[i].oldRange;var newText=this.edits[i].newText;text=new WebInspector.Text(text.replaceRange(range,newText));}
return text;function sequentialOrder(edit1,edit2)
{var range1=edit1.oldRange.collapseToStart();var range2=edit2.oldRange.collapseToStart();if(range1.equal(range2))
return 0;return range1.follows(range2)?1:-1;}},}
WebInspector.SASSSupport.Node=function(document)
{this.document=document;}
WebInspector.SASSSupport.TextNode=function(document,text,range)
{WebInspector.SASSSupport.Node.call(this,document);this.text=text;this.range=range;}
WebInspector.SASSSupport.TextNode.prototype={setText:function(newText)
{if(this.text===newText)
return;this.text=newText;this.document.edits.push(new WebInspector.SourceEdit(this.document.url,this.range,newText));},clone:function(document)
{return new WebInspector.SASSSupport.TextNode(document,this.text,this.range.clone());},match:function(other,outNodeMapping)
{if(this.text.trim()!==other.text.trim())
return false;if(outNodeMapping)
outNodeMapping.set(this,other);return true;},__proto__:WebInspector.SASSSupport.Node.prototype}
WebInspector.SASSSupport.Property=function(document,name,value,range,disabled)
{WebInspector.SASSSupport.Node.call(this,document);this.name=name;this.value=value;this.range=range;this.name.parent=this;this.value.parent=this;this.disabled=disabled;}
WebInspector.SASSSupport.Property.prototype={clone:function(document)
{return new WebInspector.SASSSupport.Property(document,this.name.clone(document),this.value.clone(document),this.range.clone(),this.disabled);},visit:function(callback)
{callback(this);callback(this.name);callback(this.value);},match:function(other,outNodeMapping)
{if(this.disabled!==other.disabled)
return false;if(outNodeMapping)
outNodeMapping.set(this,other);return this.name.match(other.name,outNodeMapping)&&this.value.match(other.value,outNodeMapping);},setDisabled:function(disabled)
{if(this.disabled===disabled)
return;this.disabled=disabled;if(disabled){var oldRange1=WebInspector.TextRange.createFromLocation(this.range.startLine,this.range.startColumn);var edit1=new WebInspector.SourceEdit(this.document.url,oldRange1,"/* ");var oldRange2=WebInspector.TextRange.createFromLocation(this.range.endLine,this.range.endColumn);var edit2=new WebInspector.SourceEdit(this.document.url,oldRange2," */");this.document.edits.push(edit1,edit2);return;}
var oldRange1=new WebInspector.TextRange(this.range.startLine,this.range.startColumn,this.range.startLine,this.name.range.startColumn);var edit1=new WebInspector.SourceEdit(this.document.url,oldRange1,"");var oldRange2=new WebInspector.TextRange(this.range.endLine,this.range.endColumn-2,this.range.endLine,this.range.endColumn);var edit2=new WebInspector.SourceEdit(this.document.url,oldRange2,"");this.document.edits.push(edit1,edit2);},remove:function()
{console.assert(this.parent);var rule=this.parent;var index=rule.properties.indexOf(this);rule.properties.splice(index,1);this.parent=null;var lineRange=new WebInspector.TextRange(this.range.startLine,0,this.range.endLine+1,0);var oldRange;if(this.document.text.extract(lineRange).trim()===this.document.text.extract(this.range).trim())
oldRange=lineRange;else
oldRange=this.range;this.document.edits.push(new WebInspector.SourceEdit(this.document.url,oldRange,""));},__proto__:WebInspector.SASSSupport.Node.prototype}
WebInspector.SASSSupport.Rule=function(document,selectors,styleRange,properties)
{WebInspector.SASSSupport.Node.call(this,document);this.selectors=selectors;this.properties=properties;this.styleRange=styleRange;var blockStartRange=styleRange.collapseToStart();blockStartRange.startColumn-=1;this.blockStart=new WebInspector.SASSSupport.TextNode(document,this.document.text.extract(blockStartRange),blockStartRange);this.blockStart.parent=this;for(var i=0;i<this.properties.length;++i)
this.properties[i].parent=this;this._hasTrailingSemicolon=!this.properties.length||this.document.text.extract(this.properties.peekLast().range).endsWith(";");}
WebInspector.SASSSupport.Rule.prototype={clone:function(document)
{var properties=[];for(var i=0;i<this.properties.length;++i)
properties.push(this.properties[i].clone(document));var selectors=[];for(var i=0;i<this.selectors.length;++i)
selectors.push(this.selectors[i].clone(document));return new WebInspector.SASSSupport.Rule(document,selectors,this.styleRange.clone(),properties);},visit:function(callback)
{callback(this);for(var i=0;i<this.selectors.length;++i)
callback(this.selectors[i]);callback(this.blockStart);for(var i=0;i<this.properties.length;++i)
this.properties[i].visit(callback);},match:function(other,outNodeMapping)
{if(this.selectors.length!==other.selectors.length)
return false;if(this.properties.length!==other.properties.length)
return false;if(outNodeMapping)
outNodeMapping.set(this,other);var result=this.blockStart.match(other.blockStart,outNodeMapping);for(var i=0;result&&i<this.selectors.length;++i)
result=result&&this.selectors[i].match(other.selectors[i],outNodeMapping);for(var i=0;result&&i<this.properties.length;++i)
result=result&&this.properties[i].match(other.properties[i],outNodeMapping);return result;},_addTrailingSemicolon:function()
{if(this._hasTrailingSemicolon||!this.properties)
return;this._hasTrailingSemicolon=true;this.document.edits.push(new WebInspector.SourceEdit(this.document.url,this.properties.peekLast().range.collapseToEnd(),";"))},insertProperties:function(anchorProperty,nameTexts,valueTexts,disabledStates)
{console.assert(nameTexts.length===valueTexts.length&&valueTexts.length===disabledStates.length,"Input array should be of the same size.");this._addTrailingSemicolon();var newProperties=[];var index=anchorProperty?this.properties.indexOf(anchorProperty):-1;for(var i=0;i<nameTexts.length;++i){var nameText=nameTexts[i];var valueText=valueTexts[i];var disabled=disabledStates[i];this.document.edits.push(this._insertPropertyEdit(anchorProperty,nameText,valueText,disabled));var name=new WebInspector.SASSSupport.TextNode(this.document,nameText,WebInspector.TextRange.createFromLocation(0,0));var value=new WebInspector.SASSSupport.TextNode(this.document,valueText,WebInspector.TextRange.createFromLocation(0,0));var newProperty=new WebInspector.SASSSupport.Property(this.document,name,value,WebInspector.TextRange.createFromLocation(0,0),disabled);this.properties.splice(index+i+1,0,newProperty);newProperty.parent=this;newProperties.push(newProperty);}
return newProperties;},_insertPropertyEdit:function(anchorProperty,nameText,valueText,disabled)
{var anchorRange=anchorProperty?anchorProperty.range:this.blockStart.range;var indent=this._computePropertyIndent();var leftComment=disabled?"/* ":"";var rightComment=disabled?" */":"";var newText=String.sprintf("\n%s%s%s: %s;%s",indent,leftComment,nameText,valueText,rightComment);return new WebInspector.SourceEdit(this.document.url,anchorRange.collapseToEnd(),newText);},_computePropertyIndent:function()
{var indentProperty=this.properties.find(property=>!property.range.isEmpty());var result="";if(indentProperty){result=this.document.text.extract(new WebInspector.TextRange(indentProperty.range.startLine,0,indentProperty.range.startLine,indentProperty.range.startColumn));}else{var lineNumber=this.blockStart.range.startLine;var columnNumber=this.blockStart.range.startColumn;var baseLine=this.document.text.extract(new WebInspector.TextRange(lineNumber,0,lineNumber,columnNumber));result=WebInspector.TextUtils.lineIndent(baseLine)+WebInspector.moduleSetting("textEditorIndent").get();}
return result.isWhitespace()?result:"";},__proto__:WebInspector.SASSSupport.Node.prototype}
WebInspector.SASSSupport.AST=function(document,rules)
{WebInspector.SASSSupport.Node.call(this,document);this.rules=rules;for(var i=0;i<rules.length;++i)
rules[i].parent=this;}
WebInspector.SASSSupport.AST.prototype={clone:function()
{var document=this.document.clone();var rules=[];for(var i=0;i<this.rules.length;++i)
rules.push(this.rules[i].clone(document));return new WebInspector.SASSSupport.AST(document,rules);},match:function(other,outNodeMapping)
{if(other.document.url!==this.document.url)
return false;if(other.rules.length!==this.rules.length)
return false;if(outNodeMapping)
outNodeMapping.set(this,other);var result=true;for(var i=0;result&&i<this.rules.length;++i)
result=result&&this.rules[i].match(other.rules[i],outNodeMapping);return result;},visit:function(callback)
{callback(this);for(var i=0;i<this.rules.length;++i)
this.rules[i].visit(callback);},findNodeForPosition:function(lineNumber,columnNumber)
{this._ensureNodePositionsIndex();var index=this._sortedTextNodes.lowerBound({lineNumber:lineNumber,columnNumber:columnNumber},nodeComparator);var node=this._sortedTextNodes[index];if(!node)
return null;return node.range.containsLocation(lineNumber,columnNumber)?node:null;function nodeComparator(position,textNode)
{return textNode.range.compareToPosition(position.lineNumber,position.columnNumber);}},_ensureNodePositionsIndex:function()
{if(this._sortedTextNodes)
return;this._sortedTextNodes=[];this.visit(onNode.bind(this));this._sortedTextNodes.sort(nodeComparator);function onNode(node)
{if(!(node instanceof WebInspector.SASSSupport.TextNode))
return;this._sortedTextNodes.push(node);}
function nodeComparator(text1,text2)
{return WebInspector.TextRange.comparator(text1.range,text2.range);}},__proto__:WebInspector.SASSSupport.Node.prototype}
WebInspector.SASSSupport.PropertyChangeType={PropertyAdded:"PropertyAdded",PropertyRemoved:"PropertyRemoved",PropertyToggled:"PropertyToggled",ValueChanged:"ValueChanged",NameChanged:"NameChanged"}
WebInspector.SASSSupport.PropertyChange=function(type,oldRule,newRule,oldPropertyIndex,newPropertyIndex)
{this.type=type;this.oldRule=oldRule;this.newRule=newRule;this.oldPropertyIndex=oldPropertyIndex;this.newPropertyIndex=newPropertyIndex;}
WebInspector.SASSSupport.PropertyChange.prototype={oldProperty:function()
{return this.oldRule.properties[this.oldPropertyIndex]||null;},newProperty:function()
{return this.newRule.properties[this.newPropertyIndex]||null;}}
WebInspector.SASSSupport.ASTDiff=function(url,oldAST,newAST,mapping,changes)
{this.url=url;this.mapping=mapping;this.changes=changes;this.oldAST=oldAST;this.newAST=newAST;}
WebInspector.SASSSupport.diffModels=function(oldAST,newAST)
{console.assert(oldAST.rules.length===newAST.rules.length,"Not implemented for rule diff.");console.assert(oldAST.document.url===newAST.document.url,"Diff makes sense for models with the same url.");var T=WebInspector.SASSSupport.PropertyChangeType;var changes=[];var mapping=new Map();for(var i=0;i<oldAST.rules.length;++i){var oldRule=oldAST.rules[i];var newRule=newAST.rules[i];computeRuleDiff(mapping,oldRule,newRule);}
return new WebInspector.SASSSupport.ASTDiff(oldAST.document.url,oldAST,newAST,mapping,changes);function addChange(type,oldRule,newRule,oldPropertyIndex,newPropertyIndex)
{changes.push(new WebInspector.SASSSupport.PropertyChange(type,oldRule,newRule,oldPropertyIndex,newPropertyIndex));}
function computeRuleDiff(mapping,oldRule,newRule)
{var oldLines=[];for(var i=0;i<oldRule.properties.length;++i)
oldLines.push(oldRule.properties[i].name.text.trim()+":"+oldRule.properties[i].value.text.trim());var newLines=[];for(var i=0;i<newRule.properties.length;++i)
newLines.push(newRule.properties[i].name.text.trim()+":"+newRule.properties[i].value.text.trim());var diff=WebInspector.Diff.lineDiff(oldLines,newLines);diff=WebInspector.Diff.convertToEditDiff(diff);var p1=0,p2=0;for(var i=0;i<diff.length;++i){var token=diff[i];if(token[0]===WebInspector.Diff.Operation.Delete){for(var j=0;j<token[1];++j)
addChange(T.PropertyRemoved,oldRule,newRule,p1++,p2);}else if(token[0]===WebInspector.Diff.Operation.Insert){for(var j=0;j<token[1];++j)
addChange(T.PropertyAdded,oldRule,newRule,p1,p2++);}else{for(var j=0;j<token[1];++j)
computePropertyDiff(mapping,oldRule,newRule,p1++,p2++);}}}
function computePropertyDiff(mapping,oldRule,newRule,oldPropertyIndex,newPropertyIndex)
{var oldProperty=oldRule.properties[oldPropertyIndex];var newProperty=newRule.properties[newPropertyIndex];mapping.set(oldProperty.name,newProperty.name);mapping.set(oldProperty.value,newProperty.value);if(oldProperty.name.text.trim()!==newProperty.name.text.trim())
addChange(T.NameChanged,oldRule,newRule,oldPropertyIndex,newPropertyIndex);if(oldProperty.value.text.trim()!==newProperty.value.text.trim())
addChange(T.ValueChanged,oldRule,newRule,oldPropertyIndex,newPropertyIndex);if(oldProperty.disabled!==newProperty.disabled)
addChange(T.PropertyToggled,oldRule,newRule,oldPropertyIndex,newPropertyIndex);}};WebInspector.ASTService=function()
{}
WebInspector.ASTService.prototype={parseCSS:function(url,text)
{return WebInspector.SASSSupport.parseSCSS(url,text);},parseSCSS:function(url,text)
{return WebInspector.SASSSupport.parseSCSS(url,text);},};WebInspector.SASSProcessor=function(astService,map,editOperations)
{this._astService=astService;this._map=map;this._editOperations=editOperations;}
WebInspector.SASSProcessor.prototype={_mutate:function()
{var changedCSSRules=new Set();for(var editOperation of this._editOperations){var rules=editOperation.perform();changedCSSRules.addAll(rules);}
var promises=[];for(var ast of this._map.models().values()){if(!ast.document.hasChanged())
continue;var promise;if(ast.document.url===this._map.compiledURL())
promise=this._astService.parseCSS(ast.document.url,ast.document.newText().value());else
promise=this._astService.parseSCSS(ast.document.url,ast.document.newText().value());promises.push(promise);}
return Promise.all(promises).then(this._onFinished.bind(this,changedCSSRules));},_onFinished:function(changedCSSRules,changedModels)
{var nodeMapping=new Map();var map=this._map.rebase(changedModels,nodeMapping);if(!map)
return null;var cssEdits=[];for(var rule of changedCSSRules){var oldRange=rule.styleRange;var newRule=nodeMapping.get(rule);var newText=newRule.document.text.extract(newRule.styleRange);cssEdits.push(new WebInspector.SourceEdit(newRule.document.url,oldRange,newText));}
var newSASSSources=new Map();for(var model of changedModels){if(model.document.url===map.compiledURL())
continue;newSASSSources.set(model.document.url,model.document.text.value());}
return new WebInspector.SourceMap.EditResult(map,cssEdits,newSASSSources);}}
WebInspector.SASSProcessor._toSASSProperty=function(map,cssProperty)
{var sassName=map.toSourceNode(cssProperty.name);return sassName?sassName.parent:null;}
WebInspector.SASSProcessor._toCSSProperties=function(map,sassProperty)
{return map.toCompiledNodes(sassProperty.name).map(name=>name.parent);}
WebInspector.SASSProcessor.processCSSEdits=function(astService,map,ranges,newTexts)
{console.assert(ranges.length===newTexts.length);var cssURL=map.compiledURL();var cssText=map.compiledModel().document.text;for(var i=0;i<ranges.length;++i)
cssText=new WebInspector.Text(cssText.replaceRange(ranges[i],newTexts[i]));return astService.parseCSS(cssURL,cssText.value()).then(onCSSParsed);function onCSSParsed(newCSSAST)
{if(newCSSAST.rules.length!==map.compiledModel().rules.length)
return Promise.resolve((null));var cssDiff=WebInspector.SASSSupport.diffModels(map.compiledModel(),newCSSAST);var edits=WebInspector.SASSProcessor._editsFromCSSDiff(cssDiff,map);var changedURLs=new Set(edits.map(edit=>edit.sassURL));changedURLs.add(map.compiledURL());var clonedModels=[];for(var url of changedURLs)
clonedModels.push(map.modelForURL(url).clone());var nodeMapping=new Map();var rebasedMap=(map.rebase(clonedModels,nodeMapping));console.assert(rebasedMap);var rebasedEdits=edits.map(edit=>edit.rebase(rebasedMap,nodeMapping));return new WebInspector.SASSProcessor(astService,rebasedMap,rebasedEdits)._mutate();}}
WebInspector.SASSProcessor._editsFromCSSDiff=function(cssDiff,map)
{var T=WebInspector.SASSSupport.PropertyChangeType;var operations=[];for(var i=0;i<cssDiff.changes.length;++i){var change=cssDiff.changes[i];var operation=null;if(change.type===T.ValueChanged||change.type===T.NameChanged)
operation=WebInspector.SASSProcessor.SetTextOperation.fromCSSChange(change,map);else if(change.type===T.PropertyToggled)
operation=WebInspector.SASSProcessor.TogglePropertyOperation.fromCSSChange(change,map);else if(change.type===T.PropertyRemoved)
operation=WebInspector.SASSProcessor.RemovePropertyOperation.fromCSSChange(change,map);else if(change.type===T.PropertyAdded)
operation=WebInspector.SASSProcessor.InsertPropertiesOperation.fromCSSChange(change,map);if(!operation){WebInspector.console.error("Operation ignored: "+change.type);continue;}
var merged=false;for(var j=0;!merged&&j<operations.length;++j)
merged=operations[j].merge(operation);if(!merged)
operations.push(operation);}
return operations;}
WebInspector.SASSProcessor.EditOperation=function(map,sassURL)
{this.map=map;this.sassURL=sassURL;}
WebInspector.SASSProcessor.EditOperation.prototype={merge:function(other)
{return false;},perform:function()
{return[];},rebase:function(newMap,nodeMapping)
{return this;},}
WebInspector.SASSProcessor.SetTextOperation=function(map,sassNode,newText)
{WebInspector.SASSProcessor.EditOperation.call(this,map,sassNode.document.url);this._sassNode=sassNode;this._newText=newText;}
WebInspector.SASSProcessor.SetTextOperation.fromCSSChange=function(change,map)
{var oldProperty=(change.oldProperty());var newProperty=(change.newProperty());console.assert(oldProperty&&newProperty,"SetTextOperation must have both oldProperty and newProperty");var newValue=null;var sassNode=null;if(change.type===WebInspector.SASSSupport.PropertyChangeType.NameChanged){newValue=newProperty.name.text;sassNode=map.toSourceNode(oldProperty.name);}else{newValue=newProperty.value.text;sassNode=map.toSourceNode(oldProperty.value);}
if(!sassNode)
return null;return new WebInspector.SASSProcessor.SetTextOperation(map,sassNode,newValue);}
WebInspector.SASSProcessor.SetTextOperation.prototype={merge:function(other)
{if(!(other instanceof WebInspector.SASSProcessor.SetTextOperation))
return false;return this._sassNode===other._sassNode;},perform:function()
{this._sassNode.setText(this._newText);var nodes=this.map.toCompiledNodes(this._sassNode);for(var node of nodes)
node.setText(this._newText);var cssRules=nodes.map(textNode=>textNode.parent.parent);return cssRules;},rebase:function(newMap,nodeMapping)
{var sassNode=(nodeMapping.get(this._sassNode))||this._sassNode;return new WebInspector.SASSProcessor.SetTextOperation(newMap,sassNode,this._newText);},__proto__:WebInspector.SASSProcessor.EditOperation.prototype}
WebInspector.SASSProcessor.TogglePropertyOperation=function(map,sassProperty,newDisabled)
{WebInspector.SASSProcessor.EditOperation.call(this,map,sassProperty.document.url);this._sassProperty=sassProperty;this._newDisabled=newDisabled;}
WebInspector.SASSProcessor.TogglePropertyOperation.fromCSSChange=function(change,map)
{var oldCSSProperty=(change.oldProperty());console.assert(oldCSSProperty,"TogglePropertyOperation must have old CSS property");var sassProperty=WebInspector.SASSProcessor._toSASSProperty(map,oldCSSProperty);if(!sassProperty)
return null;var newDisabled=change.newProperty().disabled;return new WebInspector.SASSProcessor.TogglePropertyOperation(map,sassProperty,newDisabled);}
WebInspector.SASSProcessor.TogglePropertyOperation.prototype={merge:function(other)
{if(!(other instanceof WebInspector.SASSProcessor.TogglePropertyOperation))
return false;return this._sassProperty===other._sassProperty;},perform:function()
{this._sassProperty.setDisabled(this._newDisabled);var cssProperties=WebInspector.SASSProcessor._toCSSProperties(this.map,this._sassProperty);for(var property of cssProperties)
property.setDisabled(this._newDisabled);var cssRules=cssProperties.map(property=>property.parent);return cssRules;},rebase:function(newMap,nodeMapping)
{var sassProperty=(nodeMapping.get(this._sassProperty))||this._sassProperty;return new WebInspector.SASSProcessor.TogglePropertyOperation(newMap,sassProperty,this._newDisabled);},__proto__:WebInspector.SASSProcessor.EditOperation.prototype}
WebInspector.SASSProcessor.RemovePropertyOperation=function(map,sassProperty)
{WebInspector.SASSProcessor.EditOperation.call(this,map,sassProperty.document.url);this._sassProperty=sassProperty;}
WebInspector.SASSProcessor.RemovePropertyOperation.fromCSSChange=function(change,map)
{var removedProperty=(change.oldProperty());console.assert(removedProperty,"RemovePropertyOperation must have removed CSS property");var sassProperty=WebInspector.SASSProcessor._toSASSProperty(map,removedProperty);if(!sassProperty)
return null;return new WebInspector.SASSProcessor.RemovePropertyOperation(map,sassProperty);}
WebInspector.SASSProcessor.RemovePropertyOperation.prototype={merge:function(other)
{if(!(other instanceof WebInspector.SASSProcessor.RemovePropertyOperation))
return false;return this._sassProperty===other._sassProperty;},perform:function()
{var cssProperties=WebInspector.SASSProcessor._toCSSProperties(this.map,this._sassProperty);var cssRules=cssProperties.map(property=>property.parent);this._sassProperty.remove();for(var cssProperty of cssProperties){cssProperty.remove();this.map.removeMapping(cssProperty.name,this._sassProperty.name);this.map.removeMapping(cssProperty.value,this._sassProperty.value);}
return cssRules;},rebase:function(newMap,nodeMapping)
{var sassProperty=(nodeMapping.get(this._sassProperty))||this._sassProperty;return new WebInspector.SASSProcessor.RemovePropertyOperation(newMap,sassProperty);},__proto__:WebInspector.SASSProcessor.EditOperation.prototype}
WebInspector.SASSProcessor.InsertPropertiesOperation=function(map,sassRule,afterSASSProperty,propertyNames,propertyValues,disabledStates)
{console.assert(propertyNames.length===propertyValues.length&&propertyValues.length===disabledStates.length);WebInspector.SASSProcessor.EditOperation.call(this,map,sassRule.document.url);this._sassRule=sassRule;this._afterSASSProperty=afterSASSProperty
this._nameTexts=propertyNames;this._valueTexts=propertyValues;this._disabledStates=disabledStates;}
WebInspector.SASSProcessor.InsertPropertiesOperation.fromCSSChange=function(change,map)
{var sassRule=null;var afterSASSProperty=null;if(change.oldPropertyIndex){var cssAnchor=change.oldRule.properties[change.oldPropertyIndex-1].name;var sassAnchor=map.toSourceNode(cssAnchor);afterSASSProperty=sassAnchor?sassAnchor.parent:null;sassRule=afterSASSProperty?afterSASSProperty.parent:null;}else{var cssAnchor=change.oldRule.blockStart;var sassAnchor=map.toSourceNode(cssAnchor);sassRule=sassAnchor?sassAnchor.parent:null;}
if(!sassRule)
return null;var insertedProperty=(change.newProperty());console.assert(insertedProperty,"InsertPropertiesOperation must have inserted CSS property");var names=[insertedProperty.name.text];var values=[insertedProperty.value.text];var disabledStates=[insertedProperty.disabled];return new WebInspector.SASSProcessor.InsertPropertiesOperation(map,sassRule,afterSASSProperty,names,values,disabledStates);}
WebInspector.SASSProcessor.InsertPropertiesOperation.prototype={merge:function(other)
{if(!(other instanceof WebInspector.SASSProcessor.InsertPropertiesOperation))
return false;if(this._sassRule!==other._sassRule||this._afterSASSProperty!==other._afterSASSProperty)
return false;var names=new Set(this._nameTexts);for(var i=0;i<other._nameTexts.length;++i){var nameText=other._nameTexts[i];if(names.has(nameText))
continue;this._nameTexts.push(nameText);this._valueTexts.push(other._valueTexts[i]);this._disabledStates.push(other._disabledStates[i]);}
return true;},perform:function()
{var newSASSProperties=this._sassRule.insertProperties(this._afterSASSProperty,this._nameTexts,this._valueTexts,this._disabledStates);var cssRules=[];var afterCSSProperties=[];if(this._afterSASSProperty){afterCSSProperties=WebInspector.SASSProcessor._toCSSProperties(this.map,this._afterSASSProperty);cssRules=afterCSSProperties.map(property=>property.parent);}else{cssRules=this.map.toCompiledNodes(this._sassRule.blockStart).map(blockStart=>blockStart.parent);}
for(var i=0;i<cssRules.length;++i){var cssRule=cssRules[i];var afterCSSProperty=afterCSSProperties.length?afterCSSProperties[i]:null;var newCSSProperties=cssRule.insertProperties(afterCSSProperty,this._nameTexts,this._valueTexts,this._disabledStates);for(var j=0;j<newCSSProperties.length;++j){this.map.addMapping(newCSSProperties[j].name,newSASSProperties[j].name);this.map.addMapping(newCSSProperties[j].value,newSASSProperties[j].value);}}
return cssRules;},rebase:function(newMap,nodeMapping)
{var sassRule=(nodeMapping.get(this._sassRule))||this._sassRule;var afterSASSProperty=this._afterSASSProperty?(nodeMapping.get(this._afterSASSProperty))||this._afterSASSProperty:null;return new WebInspector.SASSProcessor.InsertPropertiesOperation(newMap,sassRule,afterSASSProperty,this._nameTexts,this._valueTexts,this._disabledStates);},__proto__:WebInspector.SASSProcessor.EditOperation.prototype};WebInspector.ASTSourceMap=function(compiledURL,sourceMapURL,models,editCallback)
{this._editCallback=editCallback;this._compiledURL=compiledURL;this._sourceMapURL=sourceMapURL;this._models=models;this._compiledToSource=new Map();this._sourceToCompiled=new Multimap();}
WebInspector.ASTSourceMap.prototype={compiledURL:function()
{return this._compiledURL;},url:function()
{return this._sourceMapURL;},sourceURLs:function()
{return this._models.keysArray().filter(url=>url!==this._compiledURL);},sourceContentProvider:function(sourceURL,contentType)
{var model=this.modelForURL(sourceURL);var sourceContent=model?model.document.text.value():"";return WebInspector.StaticContentProvider.fromString(sourceURL,contentType,sourceContent);},findEntry:function(lineNumber,columnNumber)
{columnNumber=columnNumber||0;var compiledNode=this.compiledModel().findNodeForPosition(lineNumber,columnNumber);if(!compiledNode)
return null;var sourceNode=this.toSourceNode(compiledNode);if(!sourceNode)
return null;return new WebInspector.SourceMapEntry(lineNumber,columnNumber,sourceNode.document.url,sourceNode.range.startLine,sourceNode.range.startColumn);},editable:function()
{return!!this._editCallback;},editCompiled:function(ranges,texts)
{return this._editCallback.call(null,this,ranges,texts);},compiledModel:function()
{return(this._models.get(this._compiledURL));},sourceModels:function()
{var sourceModels=(new Map(this._models));sourceModels.delete(this._compiledURL);return sourceModels;},models:function()
{return(new Map(this._models));},modelForURL:function(url)
{return this._models.get(url)||null;},addMapping:function(compiled,source)
{this._compiledToSource.set(compiled,source);this._sourceToCompiled.set(source,compiled);},removeMapping:function(compiled,source)
{this._compiledToSource.delete(compiled);this._sourceToCompiled.remove(source,compiled);},toSourceNode:function(compiled)
{return this._compiledToSource.get(compiled)||null;},toCompiledNodes:function(source)
{var compiledNodes=this._sourceToCompiled.get(source);return compiledNodes?compiledNodes.valuesArray():[];},rebase:function(updated,outNodeMapping)
{outNodeMapping=outNodeMapping||new Map();outNodeMapping.clear();var models=(new Map(this._models));for(var newAST of updated){var oldAST=models.get(newAST.document.url);if(!oldAST.match(newAST,outNodeMapping))
return null;models.set(newAST.document.url,newAST);}
var newMap=new WebInspector.ASTSourceMap(this._compiledURL,this._sourceMapURL,models,this._editCallback);var compiledNodes=this._compiledToSource.keysArray();for(var i=0;i<compiledNodes.length;++i){var compiledNode=compiledNodes[i];var sourceNode=(this._compiledToSource.get(compiledNode));var mappedCompiledNode=(outNodeMapping.get(compiledNode)||compiledNode);var mappedSourceNode=(outNodeMapping.get(sourceNode)||sourceNode);newMap.addMapping(mappedCompiledNode,mappedSourceNode);}
return newMap;}};WebInspector.SASSSourceMapFactory=function()
{this._astService=new WebInspector.ASTService();}
WebInspector.SASSSourceMapFactory.prototype={editableSourceMap:function(target,sourceMap)
{var cssModel=WebInspector.CSSModel.fromTarget(target);if(!cssModel)
return Promise.resolve((null));var header=cssModel.styleSheetHeaders().find(styleSheetHeader=>styleSheetHeader.sourceMapURL===sourceMap.url());if(!header)
return Promise.resolve((null));var models=new Map();var promises=[];for(let url of sourceMap.sourceURLs()){var contentProvider=sourceMap.sourceContentProvider(url,WebInspector.resourceTypes.SourceMapStyleSheet);var sassPromise=contentProvider.requestContent().then(text=>this._astService.parseSCSS(url,text||"")).then(ast=>models.set(ast.document.url,ast));promises.push(sassPromise);}
var cssURL=sourceMap.compiledURL();var cssPromise=header.originalContentProvider().requestContent().then(text=>this._astService.parseCSS(cssURL,text||"")).then(ast=>models.set(ast.document.url,ast));promises.push(cssPromise);return Promise.all(promises).then(this._onSourcesParsed.bind(this,sourceMap,models)).catchException((null));},_onSourcesParsed:function(sourceMap,models)
{var editCallback=WebInspector.SASSProcessor.processCSSEdits.bind(WebInspector.SASSProcessor,this._astService);var map=new WebInspector.ASTSourceMap(sourceMap.compiledURL(),sourceMap.url(),models,editCallback);var valid=true;map.compiledModel().visit(onNode);return valid?map:null;function onNode(cssNode)
{if(!valid)
return;if(!(cssNode instanceof WebInspector.SASSSupport.TextNode))
return;var entry=sourceMap.findEntry(cssNode.range.startLine,cssNode.range.startColumn);if(!entry||!entry.sourceURL||typeof entry.sourceLineNumber==="undefined"||typeof entry.sourceColumnNumber==="undefined")
return;var sassAST=models.get(entry.sourceURL);if(!sassAST)
return;var sassNode=sassAST.findNodeForPosition(entry.sourceLineNumber,entry.sourceColumnNumber);if(!sassNode)
return;if(cssNode.parent&&(cssNode.parent instanceof WebInspector.SASSSupport.Property)&&cssNode===cssNode.parent.name&&cssNode.text.trim()!==sassNode.text.trim()){valid=false;reportError(cssNode,sassNode);return;}
map.addMapping(cssNode,sassNode);}
function reportError(cssNode,sassNode)
{var text=WebInspector.UIString("LiveSASS failed to start: %s",sourceMap.url());text+=WebInspector.UIString("\nSourceMap is misaligned: %s != %s",cssNode.text.trim(),sassNode.text.trim());text+="\ncompiled: "+cssNode.document.url+":"+(cssNode.range.startLine+1)+":"+(cssNode.range.startColumn+1);text+="\nsource: "+sassNode.document.url+":"+(sassNode.range.startLine+1)+":"+(sassNode.range.startColumn+1);WebInspector.console.error(text);}},};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 2 1 1 1 | WebInspector.ScreencastApp=function() {this._enabledSetting=WebInspector.settings.createSetting("screencastEnabled",true);this._toggleButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Toggle screencast"),"phone-toolbar-item");this._toggleButton.setToggled(this._enabledSetting.get());this._toggleButton.addEventListener("click",this._toggleButtonClicked,this);WebInspector.targetManager.observeTargets(this);};WebInspector.ScreencastApp.prototype={presentUI:function(document) {var rootView=new WebInspector.RootView();this._rootSplitWidget=new WebInspector.SplitWidget(false,true,"InspectorView.screencastSplitViewState",300,300);this._rootSplitWidget.setVertical(true);this._rootSplitWidget.setSecondIsSidebar(true);this._rootSplitWidget.show(rootView.element);this._rootSplitWidget.hideMain();this._rootSplitWidget.setSidebarWidget(WebInspector.inspectorView);WebInspector.inspectorView.showInitialPanel();rootView.attachToDocument(document);},targetAdded:function(target) {if(this._target) return;this._target=target;if(target.isPage()){this._screencastView=new WebInspector.ScreencastView(target);this._rootSplitWidget.setMainWidget(this._screencastView);this._screencastView.initialize();}else{this._toggleButton.setEnabled(false);} this._onScreencastEnabledChanged();},targetRemoved:function(target) {if(this._target===target){delete this._target;if(!this._screencastView) return;this._toggleButton.setEnabled(false);this._screencastView.detach();delete this._screencastView;this._onScreencastEnabledChanged();}},_toggleButtonClicked:function() {var enabled=!this._toggleButton.toggled();this._enabledSetting.set(enabled);this._onScreencastEnabledChanged();},_onScreencastEnabledChanged:function() {if(!this._rootSplitWidget) return;var enabled=this._enabledSetting.get()&&this._screencastView;this._toggleButton.setToggled(enabled);if(enabled) this._rootSplitWidget.showBoth();else this._rootSplitWidget.hideMain();}};WebInspector.ScreencastApp._appInstance;WebInspector.ScreencastApp._instance=function() {if(!WebInspector.ScreencastApp._appInstance) WebInspector.ScreencastApp._appInstance=new WebInspector.ScreencastApp();return WebInspector.ScreencastApp._appInstance;};WebInspector.ScreencastApp.ToolbarButtonProvider=function() {} WebInspector.ScreencastApp.ToolbarButtonProvider.prototype={item:function() {return WebInspector.ScreencastApp._instance()._toggleButton;}} WebInspector.ScreencastAppProvider=function() {};WebInspector.ScreencastAppProvider.prototype={createApp:function() {return WebInspector.ScreencastApp._instance();}};;WebInspector.ScreencastView=function(target) {WebInspector.VBox.call(this);this._target=target;this._domModel=WebInspector.DOMModel.fromTarget(target);this.setMinimumSize(150,150);this.registerRequiredCSS("screencast/screencastView.css");};WebInspector.ScreencastView._bordersSize=44;WebInspector.ScreencastView._navBarHeight=29;WebInspector.ScreencastView._HttpRegex=/^http:\/\/(.+)/;WebInspector.ScreencastView._SchemeRegex=/^(https?|about|chrome):/;WebInspector.ScreencastView.prototype={initialize:function() {this.element.classList.add("screencast");this._createNavigationBar();this._viewportElement=this.element.createChild("div","screencast-viewport hidden");this._canvasContainerElement=this._viewportElement.createChild("div","screencast-canvas-container");this._glassPaneElement=this._canvasContainerElement.createChild("div","screencast-glasspane fill hidden");this._canvasElement=this._canvasContainerElement.createChild("canvas");this._canvasElement.tabIndex=1;this._canvasElement.addEventListener("mousedown",this._handleMouseEvent.bind(this),false);this._canvasElement.addEventListener("mouseup",this._handleMouseEvent.bind(this),false);this._canvasElement.addEventListener("mousemove",this._handleMouseEvent.bind(this),false);this._canvasElement.addEventListener("mousewheel",this._handleMouseEvent.bind(this),false);this._canvasElement.addEventListener("click",this._handleMouseEvent.bind(this),false);this._canvasElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),false);this._canvasElement.addEventListener("keydown",this._handleKeyEvent.bind(this),false);this._canvasElement.addEventListener("keyup",this._handleKeyEvent.bind(this),false);this._canvasElement.addEventListener("keypress",this._handleKeyEvent.bind(this),false);this._canvasElement.addEventListener("blur",this._handleBlurEvent.bind(this),false);this._titleElement=this._canvasContainerElement.createChild("div","screencast-element-title monospace hidden");this._tagNameElement=this._titleElement.createChild("span","screencast-tag-name");this._nodeIdElement=this._titleElement.createChild("span","screencast-node-id");this._classNameElement=this._titleElement.createChild("span","screencast-class-name");this._titleElement.createTextChild(" ");this._nodeWidthElement=this._titleElement.createChild("span");this._titleElement.createChild("span","screencast-px").textContent="px";this._titleElement.createTextChild(" \u00D7 ");this._nodeHeightElement=this._titleElement.createChild("span");this._titleElement.createChild("span","screencast-px").textContent="px";this._titleElement.style.top="0";this._titleElement.style.left="0";this._imageElement=new Image();this._isCasting=false;this._context=this._canvasElement.getContext("2d");this._checkerboardPattern=this._createCheckerboardPattern(this._context);this._shortcuts=({});this._shortcuts[WebInspector.KeyboardShortcut.makeKey("l",WebInspector.KeyboardShortcut.Modifiers.Ctrl)]=this._focusNavigationBar.bind(this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame,this._screencastFrame,this);this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged,this._screencastVisibilityChanged,this);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChange,this);this._updateGlasspane();},wasShown:function() {this._startCasting();},willHide:function() {this._stopCasting();},_startCasting:function() {if(WebInspector.targetManager.allTargetsSuspended()) return;if(this._isCasting) return;this._isCasting=true;const maxImageDimension=2048;var dimensions=this._viewportDimensions();if(dimensions.width<0||dimensions.height<0){this._isCasting=false;return;} dimensions.width*=window.devicePixelRatio;dimensions.height*=window.devicePixelRatio;this._target.pageAgent().startScreencast("jpeg",80,Math.min(maxImageDimension,dimensions.width),Math.min(maxImageDimension,dimensions.height));this._target.emulationAgent().setTouchEmulationEnabled(true);this._domModel.setHighlighter(this);},_stopCasting:function() {if(!this._isCasting) return;this._isCasting=false;this._target.pageAgent().stopScreencast();this._target.emulationAgent().setTouchEmulationEnabled(false);this._domModel.setHighlighter(null);},_screencastFrame:function(event) {var metadata=(event.data.metadata);var base64Data=(event.data.data);this._imageElement.src="data:image/jpg;base64,"+base64Data;this._pageScaleFactor=metadata.pageScaleFactor;this._screenOffsetTop=metadata.offsetTop;this._scrollOffsetX=metadata.scrollOffsetX;this._scrollOffsetY=metadata.scrollOffsetY;var deviceSizeRatio=metadata.deviceHeight/metadata.deviceWidth;var dimensionsCSS=this._viewportDimensions();this._imageZoom=Math.min(dimensionsCSS.width/this._imageElement.naturalWidth,dimensionsCSS.height/(this._imageElement.naturalWidth*deviceSizeRatio));this._viewportElement.classList.remove("hidden");var bordersSize=WebInspector.ScreencastView._bordersSize;if(this._imageZoom<1.01/window.devicePixelRatio) this._imageZoom=1/window.devicePixelRatio;this._screenZoom=this._imageElement.naturalWidth*this._imageZoom/metadata.deviceWidth;this._viewportElement.style.width=metadata.deviceWidth*this._screenZoom+bordersSize+"px";this._viewportElement.style.height=metadata.deviceHeight*this._screenZoom+bordersSize+"px";this.highlightDOMNode(this._highlightNode,this._highlightConfig);},_isGlassPaneActive:function() {return!this._glassPaneElement.classList.contains("hidden");},_screencastVisibilityChanged:function(event) {this._targetInactive=!event.data.visible;this._updateGlasspane();},_onSuspendStateChange:function(event) {if(WebInspector.targetManager.allTargetsSuspended()) this._stopCasting();else this._startCasting();this._updateGlasspane();},_updateGlasspane:function() {if(this._targetInactive){this._glassPaneElement.textContent=WebInspector.UIString("The tab is inactive");this._glassPaneElement.classList.remove("hidden");}else if(WebInspector.targetManager.allTargetsSuspended()){this._glassPaneElement.textContent=WebInspector.UIString("Profiling in progress");this._glassPaneElement.classList.remove("hidden");}else{this._glassPaneElement.classList.add("hidden");}},_handleMouseEvent:function(event) {if(this._isGlassPaneActive()){event.consume();return;} if(!this._pageScaleFactor) return;if(!this._inspectModeConfig||event.type==="mousewheel"){this._simulateTouchForMouseEvent(event);event.preventDefault();if(event.type==="mousedown") this._canvasElement.focus();return;} var position=this._convertIntoScreenSpace(event);this._domModel.nodeForLocation(position.x/this._pageScaleFactor+this._scrollOffsetX,position.y/this._pageScaleFactor+this._scrollOffsetY,callback.bind(this));function callback(node) {if(!node) return;if(event.type==="mousemove"){this.highlightDOMNode(node,this._inspectModeConfig);this._domModel.nodeHighlightRequested(node.id);}else if(event.type==="click"){WebInspector.Revealer.reveal(node);}}},_handleKeyEvent:function(event) {if(this._isGlassPaneActive()){event.consume();return;} var shortcutKey=WebInspector.KeyboardShortcut.makeKeyFromEvent((event));var handler=this._shortcuts[shortcutKey];if(handler&&handler(event)){event.consume();return;} var type;switch(event.type){case"keydown":type="keyDown";break;case"keyup":type="keyUp";break;case"keypress":type="char";break;default:return;} var text=event.type==="keypress"?String.fromCharCode(event.charCode):undefined;this._target.inputAgent().invoke_dispatchKeyEvent({type:type,modifiers:this._modifiersForEvent(event),timestamp:event.timeStamp/1000,text:text,unmodifiedText:text?text.toLowerCase():undefined,keyIdentifier:event.keyIdentifier,code:event.code,key:event.key,windowsVirtualKeyCode:event.keyCode,nativeVirtualKeyCode:event.keyCode,autoRepeat:false,isKeypad:false,isSystemKey:false});event.consume();this._canvasElement.focus();},_handleContextMenuEvent:function(event) {event.consume(true);},_simulateTouchForMouseEvent:function(event) {const buttons={0:"none",1:"left",2:"middle",3:"right"};const types={"mousedown":"mousePressed","mouseup":"mouseReleased","mousemove":"mouseMoved","mousewheel":"mouseWheel"};if(!(event.type in types)||!(event.which in buttons)) return;if(event.type!=="mousewheel"&&buttons[event.which]==="none") return;if(event.type==="mousedown"||typeof this._eventScreenOffsetTop==="undefined") this._eventScreenOffsetTop=this._screenOffsetTop;var modifiers=(event.altKey?1:0)|(event.ctrlKey?2:0)|(event.metaKey?4:0)|(event.shiftKey?8:0);var convertedPosition=this._zoomIntoScreenSpace(event);convertedPosition.y=Math.round(convertedPosition.y-this._eventScreenOffsetTop);var params={type:types[event.type],x:convertedPosition.x,y:convertedPosition.y,modifiers:modifiers,timestamp:event.timeStamp/1000,button:buttons[event.which],clickCount:0};if(event.type==="mousewheel"){params.deltaX=event.wheelDeltaX/this._screenZoom;params.deltaY=event.wheelDeltaY/this._screenZoom;}else{this._eventParams=params;} if(event.type==="mouseup") delete this._eventScreenOffsetTop;this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params);},_handleBlurEvent:function(event) {if(typeof this._eventScreenOffsetTop!=="undefined"){var params=this._eventParams;delete this._eventParams;params.type="mouseReleased";this._target.inputAgent().invoke_emulateTouchFromMouseEvent(params);}},_zoomIntoScreenSpace:function(event) {var position={};position.x=Math.round(event.offsetX/this._screenZoom);position.y=Math.round(event.offsetY/this._screenZoom);return position;},_convertIntoScreenSpace:function(event) {var position=this._zoomIntoScreenSpace(event);position.y=Math.round(position.y-this._screenOffsetTop);return position;},_modifiersForEvent:function(event) {var modifiers=0;if(event.altKey) modifiers=1;if(event.ctrlKey) modifiers+=2;if(event.metaKey) modifiers+=4;if(event.shiftKey) modifiers+=8;return modifiers;},onResize:function() {if(this._deferredCasting){clearTimeout(this._deferredCasting);delete this._deferredCasting;} this._stopCasting();this._deferredCasting=setTimeout(this._startCasting.bind(this),100);},highlightDOMNode:function(node,config,backendNodeId,objectId) {this._highlightNode=node;this._highlightConfig=config;if(!node){this._model=null;this._config=null;this._node=null;this._titleElement.classList.add("hidden");this._repaint();return;} this._node=node;node.boxModel(callback.bind(this));function callback(model) {if(!model||!this._pageScaleFactor){this._repaint();return;} this._model=this._scaleModel(model);this._config=config;this._repaint();}},_scaleModel:function(model) {function scaleQuad(quad) {for(var i=0;i<quad.length;i+=2){quad[i]=quad[i]*this._screenZoom;quad[i+1]=(quad[i+1]+this._screenOffsetTop)*this._screenZoom;}} scaleQuad.call(this,model.content);scaleQuad.call(this,model.padding);scaleQuad.call(this,model.border);scaleQuad.call(this,model.margin);return model;},_repaint:function() {var model=this._model;var config=this._config;var canvasWidth=this._canvasElement.getBoundingClientRect().width;var canvasHeight=this._canvasElement.getBoundingClientRect().height;this._canvasElement.width=window.devicePixelRatio*canvasWidth;this._canvasElement.height=window.devicePixelRatio*canvasHeight;this._context.save();this._context.scale(window.devicePixelRatio,window.devicePixelRatio);this._context.save();this._context.fillStyle=this._checkerboardPattern;this._context.fillRect(0,0,canvasWidth,this._screenOffsetTop*this._screenZoom);this._context.fillRect(0,this._screenOffsetTop*this._screenZoom+this._imageElement.naturalHeight*this._imageZoom,canvasWidth,canvasHeight);this._context.restore();if(model&&config){this._context.save();const transparentColor="rgba(0, 0, 0, 0)";var quads=[];if(model.content&&config.contentColor!==transparentColor) quads.push({quad:model.content,color:config.contentColor});if(model.padding&&config.paddingColor!==transparentColor) quads.push({quad:model.padding,color:config.paddingColor});if(model.border&&config.borderColor!==transparentColor) quads.push({quad:model.border,color:config.borderColor});if(model.margin&&config.marginColor!==transparentColor) quads.push({quad:model.margin,color:config.marginColor});for(var i=quads.length-1;i>0;--i) this._drawOutlinedQuadWithClip(quads[i].quad,quads[i-1].quad,quads[i].color);if(quads.length>0) this._drawOutlinedQuad(quads[0].quad,quads[0].color);this._context.restore();this._drawElementTitle();this._context.globalCompositeOperation="destination-over";} this._context.drawImage(this._imageElement,0,this._screenOffsetTop*this._screenZoom,this._imageElement.naturalWidth*this._imageZoom,this._imageElement.naturalHeight*this._imageZoom);this._context.restore();},_cssColor:function(color) {if(!color) return"transparent";return WebInspector.Color.fromRGBA([color.r,color.g,color.b,color.a]).asString(WebInspector.Color.Format.RGBA)||"";},_quadToPath:function(quad) {this._context.beginPath();this._context.moveTo(quad[0],quad[1]);this._context.lineTo(quad[2],quad[3]);this._context.lineTo(quad[4],quad[5]);this._context.lineTo(quad[6],quad[7]);this._context.closePath();return this._context;},_drawOutlinedQuad:function(quad,fillColor) {this._context.save();this._context.lineWidth=2;this._quadToPath(quad).clip();this._context.fillStyle=this._cssColor(fillColor);this._context.fill();this._context.restore();},_drawOutlinedQuadWithClip:function(quad,clipQuad,fillColor) {this._context.fillStyle=this._cssColor(fillColor);this._context.save();this._context.lineWidth=0;this._quadToPath(quad).fill();this._context.globalCompositeOperation="destination-out";this._context.fillStyle="red";this._quadToPath(clipQuad).fill();this._context.restore();},_drawElementTitle:function() {if(!this._node) return;var canvasWidth=this._canvasElement.getBoundingClientRect().width;var canvasHeight=this._canvasElement.getBoundingClientRect().height;var lowerCaseName=this._node.localName()||this._node.nodeName().toLowerCase();this._tagNameElement.textContent=lowerCaseName;this._nodeIdElement.textContent=this._node.getAttribute("id")?"#"+this._node.getAttribute("id"):"";this._nodeIdElement.textContent=this._node.getAttribute("id")?"#"+this._node.getAttribute("id"):"";var className=this._node.getAttribute("class");if(className&&className.length>50) className=className.substring(0,50)+"\u2026";this._classNameElement.textContent=className||"";this._nodeWidthElement.textContent=this._model.width;this._nodeHeightElement.textContent=this._model.height;this._titleElement.classList.remove("hidden");var titleWidth=this._titleElement.offsetWidth+6;var titleHeight=this._titleElement.offsetHeight+4;var anchorTop=this._model.margin[1];var anchorBottom=this._model.margin[7];const arrowHeight=7;var renderArrowUp=false;var renderArrowDown=false;var boxX=Math.max(2,this._model.margin[0]);if(boxX+titleWidth>canvasWidth) boxX=canvasWidth-titleWidth-2;var boxY;if(anchorTop>canvasHeight){boxY=canvasHeight-titleHeight-arrowHeight;renderArrowDown=true;}else if(anchorBottom<0){boxY=arrowHeight;renderArrowUp=true;}else if(anchorBottom+titleHeight+arrowHeight<canvasHeight){boxY=anchorBottom+arrowHeight-4;renderArrowUp=true;}else if(anchorTop-titleHeight-arrowHeight>0){boxY=anchorTop-titleHeight-arrowHeight+3;renderArrowDown=true;}else boxY=arrowHeight;this._context.save();this._context.translate(0.5,0.5);this._context.beginPath();this._context.moveTo(boxX,boxY);if(renderArrowUp){this._context.lineTo(boxX+2*arrowHeight,boxY);this._context.lineTo(boxX+3*arrowHeight,boxY-arrowHeight);this._context.lineTo(boxX+4*arrowHeight,boxY);} this._context.lineTo(boxX+titleWidth,boxY);this._context.lineTo(boxX+titleWidth,boxY+titleHeight);if(renderArrowDown){this._context.lineTo(boxX+4*arrowHeight,boxY+titleHeight);this._context.lineTo(boxX+3*arrowHeight,boxY+titleHeight+arrowHeight);this._context.lineTo(boxX+2*arrowHeight,boxY+titleHeight);} this._context.lineTo(boxX,boxY+titleHeight);this._context.closePath();this._context.fillStyle="rgb(255, 255, 194)";this._context.fill();this._context.strokeStyle="rgb(128, 128, 128)";this._context.stroke();this._context.restore();this._titleElement.style.top=(boxY+3)+"px";this._titleElement.style.left=(boxX+3)+"px";},_viewportDimensions:function() {const gutterSize=30;const bordersSize=WebInspector.ScreencastView._bordersSize;var width=this.element.offsetWidth-bordersSize-gutterSize;var height=this.element.offsetHeight-bordersSize-gutterSize-WebInspector.ScreencastView._navBarHeight;return{width:width,height:height};},setInspectMode:function(mode,config,callback) {this._inspectModeConfig=mode!==DOMAgent.InspectMode.None?config:null;if(callback) callback(null);},highlightFrame:function(frameId) {},_createCheckerboardPattern:function(context) {var pattern=(createElement("canvas"));const size=32;pattern.width=size*2;pattern.height=size*2;var pctx=pattern.getContext("2d");pctx.fillStyle="rgb(195, 195, 195)";pctx.fillRect(0,0,size*2,size*2);pctx.fillStyle="rgb(225, 225, 225)";pctx.fillRect(0,0,size,size);pctx.fillRect(size,size,size,size);return context.createPattern(pattern,"repeat");},_createNavigationBar:function() {this._navigationBar=this.element.createChild("div","toolbar-background screencast-navigation");if(Runtime.queryParam("hideNavigation")) this._navigationBar.classList.add("hidden");this._navigationBack=this._navigationBar.createChild("button","back");this._navigationBack.disabled=true;this._navigationBack.addEventListener("click",this._navigateToHistoryEntry.bind(this,-1),false);this._navigationForward=this._navigationBar.createChild("button","forward");this._navigationForward.disabled=true;this._navigationForward.addEventListener("click",this._navigateToHistoryEntry.bind(this,1),false);this._navigationReload=this._navigationBar.createChild("button","reload");this._navigationReload.addEventListener("click",this._navigateReload.bind(this),false);this._navigationUrl=this._navigationBar.createChild("input");this._navigationUrl.type="text";this._navigationUrl.addEventListener("keyup",this._navigationUrlKeyUp.bind(this),true);this._navigationProgressBar=new WebInspector.ScreencastView.ProgressTracker(this._navigationBar.createChild("div","progress"));this._requestNavigationHistory();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,this._requestNavigationHistory,this);},_navigateToHistoryEntry:function(offset) {var newIndex=this._historyIndex+offset;if(newIndex<0||newIndex>=this._historyEntries.length) return;this._target.pageAgent().navigateToHistoryEntry(this._historyEntries[newIndex].id);this._requestNavigationHistory();},_navigateReload:function() {this._target.resourceTreeModel.reloadPage();},_navigationUrlKeyUp:function(event) {if(event.keyIdentifier!="Enter") return;var url=this._navigationUrl.value;if(!url) return;if(!url.match(WebInspector.ScreencastView._SchemeRegex)) url="http://"+url;this._target.pageAgent().navigate(url);this._canvasElement.focus();},_requestNavigationHistory:function() {this._target.pageAgent().getNavigationHistory(this._onNavigationHistory.bind(this));},_onNavigationHistory:function(error,currentIndex,entries) {if(error) return;this._historyIndex=currentIndex;this._historyEntries=entries;this._navigationBack.disabled=currentIndex==0;this._navigationForward.disabled=currentIndex==(entries.length-1);var url=entries[currentIndex].url;var match=url.match(WebInspector.ScreencastView._HttpRegex);if(match) url=match[1];InspectorFrontendHost.inspectedURLChanged(url);this._navigationUrl.value=url;},_focusNavigationBar:function() {this._navigationUrl.focus();this._navigationUrl.select();return true;},__proto__:WebInspector.VBox.prototype} WebInspector.ScreencastView.ProgressTracker=function(element) {this._element=element;WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._onMainFrameNavigated,this);WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.Load,this._onLoad,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestStarted,this._onRequestStarted,this);WebInspector.targetManager.addModelListener(WebInspector.NetworkManager,WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);} WebInspector.ScreencastView.ProgressTracker.prototype={_onMainFrameNavigated:function() {this._requestIds={};this._startedRequests=0;this._finishedRequests=0;this._maxDisplayedProgress=0;this._updateProgress(0.1);},_onLoad:function() {delete this._requestIds;this._updateProgress(1);setTimeout(function(){if(!this._navigationProgressVisible()) this._displayProgress(0);}.bind(this),500);},_navigationProgressVisible:function() {return!!this._requestIds;},_onRequestStarted:function(event) {if(!this._navigationProgressVisible()) return;var request=(event.data);if(request.type===WebInspector.resourceTypes.WebSocket) return;this._requestIds[request.requestId]=request;++this._startedRequests;},_onRequestFinished:function(event) {if(!this._navigationProgressVisible()) return;var request=(event.data);if(!(request.requestId in this._requestIds)) return;++this._finishedRequests;setTimeout(function(){this._updateProgress(this._finishedRequests/this._startedRequests*0.9);}.bind(this),500);},_updateProgress:function(progress) {if(!this._navigationProgressVisible()) return;if(this._maxDisplayedProgress>=progress) return;this._maxDisplayedProgress=progress;this._displayProgress(progress);},_displayProgress:function(progress) {this._element.style.width=(100*progress)+"%";}};;Runtime.cachedResources["screencast/screencastView.css"]="/*\n * Copyright (C) 2013 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.screencast {\n overflow: hidden;\n}\n\n.screencast-navigation {\n flex-direction: row;\n display: flex;\n flex: 24px 0 0;\n position: relative;\n}\n\n.screencast-navigation button {\n border-radius: 2px;\n background-color: transparent;\n background-image: -webkit-image-set(\n url(Images/navigationControls.png) 1x,\n url(Images/navigationControls_2x.png) 2x);\n background-clip: content-box;\n background-origin: content-box;\n background-repeat: no-repeat;\n border: 1px solid transparent;\n height: 23px;\n padding: 2px;\n width: 23px;\n}\n\n.screencast-navigation button:hover {\n border-color: #ccc;\n}\n\n.screencast-navigation button:active {\n border-color: #aaa;\n}\n\n.screencast-navigation button[disabled] {\n opacity: 0.5;\n}\n\n.screencast-navigation button.back {\n background-position-x: -1px;\n}\n\n.screencast-navigation button.forward {\n background-position-x: -18px;\n}\n\n.screencast-navigation button.reload {\n background-position-x: -37px;\n}\n\n.screencast-navigation input {\n -webkit-flex: 1;\n border: 1px solid #aaa;\n border-radius: 2px;\n margin: 1px;\n padding-left: 5px;\n}\n\n.screencast-navigation input:focus {\n border: 1px solid #aaa;\n outline: none !important;\n}\n\n.screencast-navigation .progress {\n background-color: rgb(66, 129, 235);\n height: 3px;\n left: 0;\n position: absolute;\n top: 100%; /* Align with the bottom edge of the parent. */\n width: 0;\n z-index: 2; /* Above .screencast-glasspane. */\n}\n\n.screencast-viewport {\n display: flex;\n border: 1px solid #999;\n border-radius: 20px;\n flex: none;\n padding: 20px;\n margin: 10px;\n background-color: #eee;\n}\n\n.screencast-canvas-container {\n flex: auto;\n display: flex;\n border: 1px solid #999;\n position: relative;\n cursor: -webkit-image-set(url(Images/touchCursor.png) 1x, url(Images/touchCursor_2x.png) 2x), default;\n}\n\n.screencast canvas {\n flex: auto;\n position: relative;\n}\n\n.screencast-px {\n color: rgb(128, 128, 128);\n}\n\n.screencast-element-title {\n position: absolute;\n z-index: 10;\n}\n\n.screencast-tag-name {\n /* Keep this in sync with view-source.css (.webkit-html-tag) */\n color: rgb(136, 18, 128);\n}\n\n.screencast-node-id {\n /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */\n color: rgb(26, 26, 166);\n}\n\n.screencast-class-name {\n /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */\n color: rgb(153, 69, 0);\n}\n\n.screencast-glasspane {\n background-color: rgba(255, 255, 255, 0.8);\n font-size: 30px;\n z-index: 100;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/*# sourceURL=screencast/screencastView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 2 1 1 1 1 1 1 1 1 | WebInspector.SecurityModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.SecurityModel,target);this._dispatcher=new WebInspector.SecurityDispatcher(this);this._securityAgent=target.securityAgent();target.registerSecurityDispatcher(this._dispatcher);this._securityAgent.enable();} WebInspector.SecurityModel.EventTypes={SecurityStateChanged:"SecurityStateChanged"} WebInspector.SecurityModel.prototype={__proto__:WebInspector.SDKModel.prototype} WebInspector.SecurityModel.fromTarget=function(target) {var model=(target.model(WebInspector.SecurityModel));if(!model) model=new WebInspector.SecurityModel(target);return model;} WebInspector.SecurityModel.SecurityStateComparator=function(a,b) {var securityStateMap;if(WebInspector.SecurityModel._symbolicToNumericSecurityState){securityStateMap=WebInspector.SecurityModel._symbolicToNumericSecurityState;}else{securityStateMap=new Map();var ordering=[SecurityAgent.SecurityState.Info,SecurityAgent.SecurityState.Insecure,SecurityAgent.SecurityState.Neutral,SecurityAgent.SecurityState.Warning,SecurityAgent.SecurityState.Secure,SecurityAgent.SecurityState.Unknown];for(var i=0;i<ordering.length;i++) securityStateMap.set(ordering[i],i+1);WebInspector.SecurityModel._symbolicToNumericSecurityState=securityStateMap;} var aScore=securityStateMap.get(a)||0;var bScore=securityStateMap.get(b)||0;return aScore-bScore;} WebInspector.PageSecurityState=function(securityState,explanations,mixedContentStatus,schemeIsCryptographic){this.securityState=securityState;this.explanations=explanations;this.mixedContentStatus=mixedContentStatus;this.schemeIsCryptographic=schemeIsCryptographic;} WebInspector.SecurityDispatcher=function(model) {this._model=model;} WebInspector.SecurityDispatcher.prototype={securityStateChanged:function(securityState,explanations,mixedContentStatus,schemeIsCryptographic) {var pageSecurityState=new WebInspector.PageSecurityState(securityState,explanations||[],mixedContentStatus||null,schemeIsCryptographic||false);this._model.dispatchEventToListeners(WebInspector.SecurityModel.EventTypes.SecurityStateChanged,pageSecurityState);}};WebInspector.SecurityPanel=function() {WebInspector.PanelWithSidebar.call(this,"security");this._mainView=new WebInspector.SecurityMainView(this);this._sidebarMainViewElement=new WebInspector.SecurityPanelSidebarTreeElement(WebInspector.UIString("Overview"),this._setVisibleView.bind(this,this._mainView),"security-main-view-sidebar-tree-item","lock-icon");this._sidebarTree=new WebInspector.SecurityPanelSidebarTree(this._sidebarMainViewElement,this.showOrigin.bind(this));this.panelSidebarElement().appendChild(this._sidebarTree.element);this.setDefaultFocusedElement(this._sidebarTree.contentElement);this._lastResponseReceivedForLoaderId=new Map();this._origins=new Map();this._filterRequestCounts=new Map();WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);} WebInspector.SecurityPanel.Origin;WebInspector.SecurityPanel.OriginState;WebInspector.SecurityPanel.prototype={setRanInsecureContentStyle:function(securityState) {this._ranInsecureContentStyle=securityState;},setDisplayedInsecureContentStyle:function(securityState) {this._displayedInsecureContentStyle=securityState;},_updateSecurityState:function(newSecurityState,explanations,mixedContentStatus,schemeIsCryptographic) {this._sidebarMainViewElement.setSecurityState(newSecurityState);this._mainView.updateSecurityState(newSecurityState,explanations,mixedContentStatus,schemeIsCryptographic);},_onSecurityStateChanged:function(event) {var data=(event.data);var securityState=(data.securityState);var explanations=(data.explanations);var mixedContentStatus=(data.mixedContentStatus);var schemeIsCryptographic=(data.schemeIsCryptographic);this._updateSecurityState(securityState,explanations,mixedContentStatus,schemeIsCryptographic);},selectAndSwitchToMainView:function() {this._sidebarMainViewElement.select();},showOrigin:function(origin) {var originState=this._origins.get(origin);if(!originState.originView) originState.originView=new WebInspector.SecurityOriginView(this,origin,originState);this._setVisibleView(originState.originView);},wasShown:function() {WebInspector.Panel.prototype.wasShown.call(this);if(!this._visibleView) this.selectAndSwitchToMainView();},_setVisibleView:function(view) {if(this._visibleView===view) return;if(this._visibleView) this._visibleView.detach();this._visibleView=view;if(view) this.splitWidget().setMainWidget(view);},_onResponseReceived:function(event) {var request=(event.data);if(request.resourceType()==WebInspector.resourceTypes.Document) this._lastResponseReceivedForLoaderId.set(request.loaderId,request);},_processRequest:function(request) {var origin=WebInspector.ParsedURL.extractOrigin(request.url);if(!origin){return;} var securityState=(request.securityState());if(request.mixedContentType===NetworkAgent.RequestMixedContentType.Blockable&&this._ranInsecureContentStyle) securityState=this._ranInsecureContentStyle;else if(request.mixedContentType===NetworkAgent.RequestMixedContentType.OptionallyBlockable&&this._displayedInsecureContentStyle) securityState=this._displayedInsecureContentStyle;if(this._origins.has(origin)){var originState=this._origins.get(origin);var oldSecurityState=originState.securityState;originState.securityState=this._securityStateMin(oldSecurityState,securityState);if(oldSecurityState!=originState.securityState){this._sidebarTree.updateOrigin(origin,securityState);if(originState.originView) originState.originView.setSecurityState(securityState);}}else{var originState={};originState.securityState=securityState;var securityDetails=request.securityDetails();if(securityDetails){originState.securityDetails=securityDetails;originState.certificateDetailsPromise=request.target().networkManager.certificateDetailsPromise(securityDetails.certificateId);} this._origins.set(origin,originState);this._sidebarTree.addOrigin(origin,securityState);}},_onRequestFinished:function(event) {var request=(event.data);this._updateFilterRequestCounts(request);this._processRequest(request);},_updateFilterRequestCounts:function(request) {if(request.mixedContentType===NetworkAgent.RequestMixedContentType.None) return;var filterKey=WebInspector.NetworkLogView.MixedContentFilterValues.All;if(request.wasBlocked()) filterKey=WebInspector.NetworkLogView.MixedContentFilterValues.Blocked;else if(request.mixedContentType===NetworkAgent.RequestMixedContentType.Blockable) filterKey=WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden;else if(request.mixedContentType===NetworkAgent.RequestMixedContentType.OptionallyBlockable) filterKey=WebInspector.NetworkLogView.MixedContentFilterValues.Displayed;if(!this._filterRequestCounts.has(filterKey)) this._filterRequestCounts.set(filterKey,1);else this._filterRequestCounts.set(filterKey,this._filterRequestCounts.get(filterKey)+1);this._mainView.refreshExplanations();},filterRequestCount:function(filterKey) {return this._filterRequestCounts.get(filterKey)||0;},_securityStateMin:function(stateA,stateB) {return WebInspector.SecurityModel.SecurityStateComparator(stateA,stateB)<0?stateA:stateB;},targetAdded:function(target) {if(this._target) return;this._target=target;target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated,this._onMainFrameNavigated,this);target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResponseReceived,this._onResponseReceived,this);target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);var securityModel=WebInspector.SecurityModel.fromTarget(target);securityModel.addEventListener(WebInspector.SecurityModel.EventTypes.SecurityStateChanged,this._onSecurityStateChanged,this);},targetRemoved:function(target) {},_clearOrigins:function() {this.selectAndSwitchToMainView();this._sidebarTree.clearOrigins();this._origins.clear();this._lastResponseReceivedForLoaderId.clear();this._filterRequestCounts.clear();},_onMainFrameNavigated:function(event){var frame=(event.data);var request=this._lastResponseReceivedForLoaderId.get(frame.loaderId);this._clearOrigins();if(request){var origin=WebInspector.ParsedURL.extractOrigin(request.url);this._sidebarTree.setMainOrigin(origin);this._processRequest(request);}},__proto__:WebInspector.PanelWithSidebar.prototype} WebInspector.SecurityPanel._instance=function() {if(!WebInspector.SecurityPanel._instanceObject) WebInspector.SecurityPanel._instanceObject=new WebInspector.SecurityPanel();return WebInspector.SecurityPanel._instanceObject;} WebInspector.SecurityPanel.createCertificateViewerButton=function(text,certificateId) {function showCertificateViewer(e) {e.consume();WebInspector.multitargetNetworkManager.showCertificateViewer((certificateId));} return createTextButton(text,showCertificateViewer,"security-certificate-button");} WebInspector.SecurityPanelSidebarTree=function(mainViewElement,showOriginInPanel) {this._showOriginInPanel=showOriginInPanel;this._mainOrigin=null;TreeOutlineInShadow.call(this);this.element.classList.add("sidebar-tree");this.registerRequiredCSS("security/sidebar.css");this.registerRequiredCSS("security/lockIcon.css");this.appendChild(mainViewElement);this._originGroups=new Map();for(var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName){var originGroupName=WebInspector.SecurityPanelSidebarTree.OriginGroupName[key];var originGroup=new WebInspector.SidebarSectionTreeElement(WebInspector.UIString(originGroupName));originGroup.listItemElement.classList.add("security-sidebar-origins");this._originGroups.set(originGroupName,originGroup);this.appendChild(originGroup);} this._clearOriginGroups();var mainViewReloadMessage=new WebInspector.SidebarTreeElement("security-main-view-reload-message",WebInspector.UIString("Reload to view details"));mainViewReloadMessage.selectable=false;this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin).appendChild(mainViewReloadMessage);this._elementsByOrigin=new Map();} WebInspector.SecurityPanelSidebarTree.prototype={addOrigin:function(origin,securityState) {var originElement=new WebInspector.SecurityPanelSidebarTreeElement(origin,this._showOriginInPanel.bind(this,origin),"security-sidebar-tree-item","security-property");originElement.listItemElement.title=origin;this._elementsByOrigin.set(origin,originElement);this.updateOrigin(origin,securityState);},setMainOrigin:function(origin) {this._mainOrigin=origin;},updateOrigin:function(origin,securityState) {var originElement=(this._elementsByOrigin.get(origin));originElement.setSecurityState(securityState);var newParent;if(origin===this._mainOrigin){newParent=this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin);}else{switch(securityState){case SecurityAgent.SecurityState.Secure:newParent=this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.Secure);break;case SecurityAgent.SecurityState.Unknown:newParent=this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.Unknown);break;default:newParent=this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.NonSecure);break;}} var oldParent=originElement.parent;if(oldParent!==newParent){if(oldParent){oldParent.removeChild(originElement);if(oldParent.childCount()===0) oldParent.hidden=true;} newParent.appendChild(originElement);newParent.hidden=false;}},_clearOriginGroups:function() {for(var originGroup of this._originGroups.values()){originGroup.removeChildren();originGroup.hidden=true;} this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName.MainOrigin).hidden=false;},clearOrigins:function() {this._clearOriginGroups();this._elementsByOrigin.clear();},__proto__:TreeOutlineInShadow.prototype} WebInspector.SecurityPanelSidebarTree.OriginGroupName={MainOrigin:"Main Origin",NonSecure:"Non-Secure Origins",Secure:"Secure Origins",Unknown:"Unknown / Canceled"} WebInspector.SecurityPanelSidebarTreeElement=function(text,selectCallback,className,cssPrefix) {this._selectCallback=selectCallback;this._cssPrefix=cssPrefix;WebInspector.SidebarTreeElement.call(this,className,text);this.iconElement.classList.add(this._cssPrefix);this.setSecurityState(SecurityAgent.SecurityState.Unknown);} WebInspector.SecurityPanelSidebarTreeElement.prototype={setSecurityState:function(newSecurityState) {if(this._securityState) this.iconElement.classList.remove(this._cssPrefix+"-"+this._securityState) this._securityState=newSecurityState;this.iconElement.classList.add(this._cssPrefix+"-"+newSecurityState);},securityState:function() {return this._securityState;},onselect:function() {this._selectCallback();return true;},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.SecurityPanelSidebarTreeElement.SecurityStateComparator=function(a,b) {return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(),b.securityState());} WebInspector.SecurityPanelFactory=function() {} WebInspector.SecurityPanelFactory.prototype={createPanel:function() {return WebInspector.SecurityPanel._instance();}} WebInspector.SecurityMainView=function(panel) {WebInspector.VBox.call(this,true);this.registerRequiredCSS("security/mainView.css");this.registerRequiredCSS("security/lockIcon.css");this.setMinimumSize(200,100);this.contentElement.classList.add("security-main-view");this._panel=panel;this._summarySection=this.contentElement.createChild("div","security-summary");this._securityExplanations=this.contentElement.createChild("div","security-explanation-list");this._summarySection.createChild("div","security-summary-section-title").textContent=WebInspector.UIString("Security Overview");var lockSpectrum=this._summarySection.createChild("div","lock-spectrum");lockSpectrum.createChild("div","lock-icon lock-icon-secure").title=WebInspector.UIString("Secure");lockSpectrum.createChild("div","security-summary-lock-spacer");lockSpectrum.createChild("div","lock-icon lock-icon-neutral").title=WebInspector.UIString("Not Secure");lockSpectrum.createChild("div","security-summary-lock-spacer");lockSpectrum.createChild("div","lock-icon lock-icon-insecure").title=WebInspector.UIString("Insecure (Broken)");this._summarySection.createChild("div","triangle-pointer-container").createChild("div","triangle-pointer-wrapper").createChild("div","triangle-pointer");this._summaryText=this._summarySection.createChild("div","security-summary-text");} WebInspector.SecurityMainView.prototype={_addExplanation:function(explanation) {var explanationSection=this._securityExplanations.createChild("div","security-explanation");explanationSection.classList.add("security-explanation-"+explanation.securityState);explanationSection.createChild("div","security-property").classList.add("security-property-"+explanation.securityState);var text=explanationSection.createChild("div","security-explanation-text");text.createChild("div","security-explanation-title").textContent=explanation.summary;text.createChild("div").textContent=explanation.description;if(explanation.certificateId){text.appendChild(WebInspector.SecurityPanel.createCertificateViewerButton(WebInspector.UIString("View certificate"),explanation.certificateId));} return text;},updateSecurityState:function(newSecurityState,explanations,mixedContentStatus,schemeIsCryptographic) {this._summarySection.classList.remove("security-summary-"+this._securityState);this._securityState=newSecurityState;this._summarySection.classList.add("security-summary-"+this._securityState);var summaryExplanationStrings={"unknown":WebInspector.UIString("This security of this page is unknown."),"insecure":WebInspector.UIString("This page is insecure (broken HTTPS)."),"neutral":WebInspector.UIString("This page is not secure."),"secure":WebInspector.UIString("This page is secure (valid HTTPS).")} this._summaryText.textContent=summaryExplanationStrings[this._securityState];this._explanations=explanations,this._mixedContentStatus=mixedContentStatus;this._schemeIsCryptographic=schemeIsCryptographic;this._panel.setRanInsecureContentStyle(mixedContentStatus.ranInsecureContentStyle);this._panel.setDisplayedInsecureContentStyle(mixedContentStatus.displayedInsecureContentStyle);this.refreshExplanations();},refreshExplanations:function() {this._securityExplanations.removeChildren();for(var explanation of this._explanations) this._addExplanation(explanation);this._addMixedContentExplanations();},_addMixedContentExplanations:function() {if(!this._schemeIsCryptographic) return;if(this._mixedContentStatus&&(this._mixedContentStatus.ranInsecureContent||this._mixedContentStatus.displayedInsecureContent)){if(this._mixedContentStatus.ranInsecureContent) this._addMixedContentExplanation(this._mixedContentStatus.ranInsecureContentStyle,WebInspector.UIString("Active Mixed Content"),WebInspector.UIString("You have recently allowed insecure content (such as scripts or iframes) to run on this site."),WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden,showBlockOverriddenMixedContentInNetworkPanel);if(this._mixedContentStatus.displayedInsecureContent) this._addMixedContentExplanation(this._mixedContentStatus.displayedInsecureContentStyle,WebInspector.UIString("Mixed Content"),WebInspector.UIString("The site includes HTTP resources."),WebInspector.NetworkLogView.MixedContentFilterValues.Displayed,showDisplayedMixedContentInNetworkPanel);} if(this._mixedContentStatus&&(!this._mixedContentStatus.displayedInsecureContent&&!this._mixedContentStatus.ranInsecureContent)){this._addExplanation(({"securityState":SecurityAgent.SecurityState.Secure,"summary":WebInspector.UIString("Secure Resources"),"description":WebInspector.UIString("All resources on this page are served securely.")}));} if(this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedContentFilterValues.Blocked)>0) this._addMixedContentExplanation(SecurityAgent.SecurityState.Info,WebInspector.UIString("Blocked mixed content"),WebInspector.UIString("Your page requested insecure resources that were blocked."),WebInspector.NetworkLogView.MixedContentFilterValues.Blocked,showBlockedMixedContentInNetworkPanel);function showDisplayedMixedContentInNetworkPanel(e) {e.consume();WebInspector.NetworkPanel.revealAndFilter([{filterType:WebInspector.NetworkLogView.FilterType.MixedContent,filterValue:WebInspector.NetworkLogView.MixedContentFilterValues.Displayed}]);} function showBlockOverriddenMixedContentInNetworkPanel(e) {e.consume();WebInspector.NetworkPanel.revealAndFilter([{filterType:WebInspector.NetworkLogView.FilterType.MixedContent,filterValue:WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden}]);} function showBlockedMixedContentInNetworkPanel(e) {e.consume();WebInspector.NetworkPanel.revealAndFilter([{filterType:WebInspector.NetworkLogView.FilterType.MixedContent,filterValue:WebInspector.NetworkLogView.MixedContentFilterValues.Blocked}]);}},_addMixedContentExplanation:function(securityState,summary,description,filterKey,networkFilterFn) {var mixedContentExplanation=({"securityState":securityState,"summary":summary,"description":description});var filterRequestCount=this._panel.filterRequestCount(filterKey);var requestsAnchor=this._addExplanation(mixedContentExplanation).createChild("div","security-mixed-content link");if(filterRequestCount>0){requestsAnchor.textContent=WebInspector.UIString("View %d request%s in Network Panel",filterRequestCount,(filterRequestCount>1?"s":""));}else{requestsAnchor.textContent=WebInspector.UIString("View requests in Network Panel");} requestsAnchor.href="";requestsAnchor.addEventListener("click",networkFilterFn);},__proto__:WebInspector.VBox.prototype} WebInspector.SecurityOriginView=function(panel,origin,originState) {this._panel=panel;WebInspector.VBox.call(this);this.setMinimumSize(200,100);this.element.classList.add("security-origin-view");this.registerRequiredCSS("security/originView.css");this.registerRequiredCSS("security/lockIcon.css");var titleSection=this.element.createChild("div","title-section");var originDisplay=titleSection.createChild("div","origin-display");this._originLockIcon=originDisplay.createChild("span","security-property");this._originLockIcon.classList.add("security-property-"+originState.securityState);originDisplay.createChild("span","origin").textContent=origin;var originNetworkLink=titleSection.createChild("div","link");originNetworkLink.textContent=WebInspector.UIString("View requests in Network Panel");function showOriginRequestsInNetworkPanel() {var parsedURL=new WebInspector.ParsedURL(origin);WebInspector.NetworkPanel.revealAndFilter([{filterType:WebInspector.NetworkLogView.FilterType.Domain,filterValue:parsedURL.host},{filterType:WebInspector.NetworkLogView.FilterType.Scheme,filterValue:parsedURL.scheme}]);} originNetworkLink.addEventListener("click",showOriginRequestsInNetworkPanel,false);if(originState.securityDetails){var connectionSection=this.element.createChild("div","origin-view-section");connectionSection.createChild("div","origin-view-section-title").textContent=WebInspector.UIString("Connection");var table=new WebInspector.SecurityDetailsTable();connectionSection.appendChild(table.element());table.addRow("Protocol",originState.securityDetails.protocol);table.addRow("Key Exchange",originState.securityDetails.keyExchange);table.addRow("Cipher Suite",originState.securityDetails.cipher+(originState.securityDetails.mac?" with "+originState.securityDetails.mac:""));var certificateSection=this.element.createChild("div","origin-view-section");certificateSection.createChild("div","origin-view-section-title").textContent=WebInspector.UIString("Certificate");function displayCertificateDetails(certificateDetails) {var sanDiv=this._createSanDiv(certificateDetails.subject);var validFromString=new Date(1000*certificateDetails.validFrom).toUTCString();var validUntilString=new Date(1000*certificateDetails.validTo).toUTCString();var table=new WebInspector.SecurityDetailsTable();certificateSection.appendChild(table.element());table.addRow(WebInspector.UIString("Subject"),certificateDetails.subject.name);table.addRow(WebInspector.UIString("SAN"),sanDiv);table.addRow(WebInspector.UIString("Valid From"),validFromString);table.addRow(WebInspector.UIString("Valid Until"),validUntilString);table.addRow(WebInspector.UIString("Issuer"),certificateDetails.issuer);table.addRow(WebInspector.UIString("SCTs"),this.sctSummary(originState.securityDetails.certificateValidationDetails));table.addRow("",WebInspector.SecurityPanel.createCertificateViewerButton(WebInspector.UIString("Open full certificate details"),originState.securityDetails.certificateId));} function displayCertificateDetailsUnavailable() {certificateSection.createChild("div").textContent=WebInspector.UIString("Certificate details unavailable.");} originState.certificateDetailsPromise.then(displayCertificateDetails.bind(this),displayCertificateDetailsUnavailable);var noteSection=this.element.createChild("div","origin-view-section");noteSection.createChild("div").textContent=WebInspector.UIString("The security details above are from the first inspected response.");}else if(originState.securityState!==SecurityAgent.SecurityState.Unknown){var notSecureSection=this.element.createChild("div","origin-view-section");notSecureSection.createChild("div","origin-view-section-title").textContent=WebInspector.UIString("Not Secure");notSecureSection.createChild("div").textContent=WebInspector.UIString("Your connection to this origin is not secure.");}else{var noInfoSection=this.element.createChild("div","origin-view-section");noInfoSection.createChild("div","origin-view-section-title").textContent=WebInspector.UIString("No Security Information");noInfoSection.createChild("div").textContent=WebInspector.UIString("No security details are available for this origin.");}} WebInspector.SecurityOriginView.prototype={_createSanDiv:function(certificateSubject) {var sanDiv=createElement("div");var sanList=certificateSubject.sanDnsNames.concat(certificateSubject.sanIpAddresses);if(sanList.length===0){sanDiv.textContent=WebInspector.UIString("(N/A)");sanDiv.classList.add("empty-san");}else{var truncatedNumToShow=2;var listIsTruncated=sanList.length>truncatedNumToShow;for(var i=0;i<sanList.length;i++){var span=sanDiv.createChild("span","san-entry");span.textContent=sanList[i];if(listIsTruncated&&i>=truncatedNumToShow) span.classList.add("truncated-entry");} if(listIsTruncated){var truncatedSANToggle=sanDiv.createChild("div","link");truncatedSANToggle.href="";function toggleSANTruncation() {if(sanDiv.classList.contains("truncated-san")){sanDiv.classList.remove("truncated-san") truncatedSANToggle.textContent=WebInspector.UIString("Show less");}else{sanDiv.classList.add("truncated-san");truncatedSANToggle.textContent=WebInspector.UIString("Show more (%d total)",sanList.length);}} truncatedSANToggle.addEventListener("click",toggleSANTruncation,false);toggleSANTruncation();}} return sanDiv;},setSecurityState:function(newSecurityState) {for(var className of Array.prototype.slice.call(this._originLockIcon.classList)){if(className.startsWith("security-property-")) this._originLockIcon.classList.remove(className);} this._originLockIcon.classList.add("security-property-"+newSecurityState);},sctSummary:function(details) {if(!details) return WebInspector.UIString("N/A");var sctTypeList=[];if(details.numValidScts) sctTypeList.push(WebInspector.UIString("%d valid SCT%s",details.numValidScts,(details.numValidScts>1)?"s":""));if(details.numInvalidScts) sctTypeList.push(WebInspector.UIString("%d invalid SCT%s",details.numInvalidScts,(details.numInvalidScts>1)?"s":""));if(details.numUnknownScts) sctTypeList.push(WebInspector.UIString("%d SCT%s from unknown logs",details.numUnknownScts,(details.numUnknownScts>1)?"s":""));return sctTypeList.length?sctTypeList.join(", "):WebInspector.UIString("0 SCTs");},__proto__:WebInspector.VBox.prototype} WebInspector.SecurityDetailsTable=function() {this._element=createElement("table");this._element.classList.add("details-table");} WebInspector.SecurityDetailsTable.prototype={element:function() {return this._element;},addRow:function(key,value) {var row=this._element.createChild("div","details-table-row");row.createChild("div").textContent=key;var valueDiv=row.createChild("div");if(typeof value==="string"){valueDiv.textContent=value;}else{valueDiv.appendChild(value);}}};Runtime.cachedResources["security/lockIcon.css"]="/* Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.lock-icon,\n.security-property {\n background-size: cover;\n height: 16px;\n width: 16px;\n}\n\n.lock-icon-unknown {\n background-image: url(Images/securityStateNeutral.svg);\n}\n\n.lock-icon-neutral {\n background-image: url(Images/securityStateNeutral.svg);\n}\n\n.lock-icon-insecure {\n background-image: url(Images/securityStateInsecure.svg);\n}\n\n.lock-icon-secure {\n background-image: url(Images/securityStateSecure.svg);\n}\n\n.security-property-insecure {\n background-image: url(Images/securityPropertyInsecure.svg);\n}\n\n.security-property-neutral {\n background-image: url(Images/securityPropertyWarning.svg);\n}\n\n.security-property-warning {\n background-image: url(Images/securityPropertyWarning.svg);\n}\n\n.security-property-unknown {\n background-image: url(Images/securityPropertyUnknown.svg);\n}\n\n.security-property-secure {\n background-image: url(Images/securityPropertySecure.svg);\n}\n\n.security-property-info {\n background-image: url(Images/securityPropertyInfo.svg);\n}\n\n/*# sourceURL=security/lockIcon.css */";Runtime.cachedResources["security/mainView.css"]="/* Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.security-main-view {\n -webkit-user-select: text;\n overflow-x: hidden;\n overflow-y: auto;\n background-color: #f9f9f9;\n}\n\n.security-main-view > div {\n flex-shrink: 0;\n}\n\n.security-summary {\n background-color: #fff;\n}\n\n.security-summary-section-title {\n font-size: 14px;\n margin: 12px 24px;\n}\n\n.lock-spectrum {\n min-width: 180px;\n max-width: 240px;\n margin: 6px 12px;\n display: flex;\n align-items: center;\n}\n\n.security-summary .lock-icon {\n flex: none;\n width: 32px;\n height: 32px;\n margin: 0 12px;\n background-position: center center;\n\n /* Defaults for dynamic properties. */\n opacity: 0.5;\n}\n\n/* Shrink the margin for the page lock icon. */\n.security-summary .lock-icon-neutral {\n margin: 0 6px;\n}\n\n.security-summary-secure .lock-icon-secure,\n.security-summary-neutral .lock-icon-neutral,\n.security-summary-insecure .lock-icon-insecure {\n opacity: 1;\n}\n\n.security-summary-lock-spacer {\n flex: 1 1 auto;\n height: 1px;\n background: rgb(217, 217, 217);\n}\n\n.triangle-pointer-container {\n /* Let (lock width) = (horizonal width of 1 lock icon, including both margins) */\n /* Horizontal margin is (lock width)/2 + (lock-spectrum horizontal margin) */\n margin: 8px 40px 0px;\n /* Width is (lock spectrum width) - (lock width) */\n min-width: 124px;\n max-width: 184px;\n}\n\n.triangle-pointer-wrapper {\n /* Defaults for dynamic properties. */\n transform: translateX(50%);\n transition: transform 0.3s;\n}\n\n.triangle-pointer {\n width: 12px;\n height: 12px;\n margin-bottom: -6px;\n margin-left: -6px;\n transform: rotate(-45deg);\n border-style: solid;\n border-width: 1px 1px 0 0;\n\n /* Defaults for dynamic properties. */\n background: rgb(243, 243, 243);\n border-color: rgb(217, 217, 217);\n}\n\n.security-summary-secure .triangle-pointer-wrapper {\n transform: translateX(0%);\n}\n\n.security-summary-neutral .triangle-pointer-wrapper {\n transform: translateX(50%);\n}\n\n.security-summary-insecure .triangle-pointer-wrapper {\n transform: translateX(100%);\n}\n\n.security-summary-text {\n padding: 12px 24px;\n border-style: solid;\n border-width: 1px 0;\n\n /* Defaults for dynamic properties. */\n background: rgb(243, 243, 243);\n border-color: rgb(217, 217, 217);\n color: rgb(127, 127, 127);\n}\n\n.security-summary-secure .triangle-pointer,\n.security-summary-secure .security-summary-text {\n background: rgb(243, 252, 244);\n border-color: rgb(137, 222, 144);\n color: rgb(42, 194, 57);\n}\n\n.security-summary-neutral .triangle-pointer,\n.security-summary-neutral .security-summary-text {\n background: rgb(255, 251, 243);\n border-color: rgb(253, 214, 129);\n color: rgb(253, 177, 48);\n}\n\n.security-summary-insecure .triangle-pointer,\n.security-summary-insecure .security-summary-text {\n background: rgb(253, 245, 245);\n border-color: rgb(243, 157, 151);\n color: rgb(216, 70, 60);\n}\n\n.security-explanation {\n padding: 12px;\n border-bottom: 1px solid rgb(230, 230, 230);\n background-color: #fff;\n\n display: flex;\n white-space: nowrap;\n}\n\n.security-explanation-text {\n flex: auto;\n white-space: normal;\n}\n\n.security-explanation-info {\n border-bottom: none;\n background-color: transparent;\n}\n\n.security-certificate-button {\n margin-top: 8px;\n}\n\n.security-explanation .security-property {\n flex: none;\n width: 18px;\n height: 18px;\n margin-left: 10px;\n margin-right: 18px;\n}\n\n.security-explanation-title {\n color: rgb(90, 90, 90);\n margin-top: 1px;\n margin-bottom: 8px;\n}\n\n.security-explanation-neutral .security-section-title,\n.security-explanation-warning .security-section-title\n{\n color: rgb(253, 177, 48);\n font-weight: bold;\n}\n.security-explanation-insecure .security-section-title\n{\n color: rgb(216, 71, 60);\n font-weight: bold;\n}\n\n.security-mixed-content {\n margin-top: 8px;\n}\n\n/*# sourceURL=security/mainView.css */";Runtime.cachedResources["security/originView.css"]="/* Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.title-section {\n padding: 12px 0;\n border-bottom: 1px solid rgb(230, 230, 230);\n}\n\n.security-origin-view {\n overflow-x: hidden;\n overflow-y: scroll;\n display: block;\n -webkit-user-select: text;\n}\n\n.security-origin-view .origin-view-section {\n border-bottom: 1px solid rgb(230, 230, 230);\n padding: 12px 6px 12px 18px;\n}\n\n.security-origin-view .origin-display {\n font-size: 15px;\n padding-left: 38px;\n display: flex;\n align-items: center;\n}\n\n.title-section > .link {\n padding: 6px 0 0 39px\n}\n\n.security-origin-view .origin-display .security-property {\n display: inline-block;\n vertical-align: middle;\n position: absolute;\n left: 18px;\n}\n\n.security-origin-view .origin-view-section-title {\n margin-bottom: 10px;\n padding-left: 18px;\n}\n\n.security-origin-view .details-table-row {\n display: flex;\n white-space: nowrap;\n overflow: hidden;\n line-height: 22px;\n}\n\n.security-origin-view .details-table-row > div {\n align-items: flex-start;\n}\n\n.security-origin-view .details-table-row > div:first-child {\n color: rgb(140, 140, 140);\n width: 128px;\n margin-right: 1em;\n flex: none;\n display: flex;\n justify-content: flex-end;\n}\n.security-origin-view .details-table-row > div:nth-child(2) {\n flex: auto;\n white-space: normal;\n}\n\n.security-origin-view .details-table .empty-san {\n color: rgb(140, 140, 140);\n}\n\n.security-origin-view .details-table .san-entry {\n display: block;\n}\n\n.security-origin-view .truncated-san .truncated-entry {\n display: none;\n}\n\n.security-certificate-button {\n margin-top: 4px;\n}\n\n/*# sourceURL=security/originView.css */";Runtime.cachedResources["security/sidebar.css"]="/* Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.tree-outline {\n padding: 0;\n}\n\n.tree-outline li {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.tree-outline:focus li.selected .lock-icon-neutral {\n background-color: #fff;\n}\n\n.tree-outline .security-main-view-sidebar-tree-item {\n border-bottom: 1px solid rgb(230, 230, 230);\n padding: 16px 0;\n}\n\n.tree-outline .security-sidebar-origins {\n padding: 1px 8px 6px 8px;\n margin-top: 1em;\n margin-bottom: 0.5em;\n color: rgb(90, 90, 90);\n}\n\n.tree-outline ol {\n padding-left: 0;\n}\n\n.tree-outline li::before {\n content: none;\n}\n\n.tree-outline .security-main-view-sidebar-tree-item,\n.tree-outline .security-sidebar-origins,\n.tree-outline .sidebar-tree-section + .children > .sidebar-tree-item {\n padding-left: 16px;\n}\n\n.tree-outline .sidebar-tree-item .lock-icon,\n.tree-outline .sidebar-tree-item .security-property {\n margin-right: 2px;\n flex: none;\n}\n\n.tree-outline:focus .security-sidebar-tree-item.selected .icon:not(.security-property-unknown) {\n background-image: none;\n background-color: #fff;\n}\n\n.security-sidebar-tree-item {\n padding: 2px 0;\n}\n\n.security-sidebar-tree-item .titles {\n overflow: hidden;\n margin-right: 5px;\n}\n\n.tree-outline li.selected .lock-icon-neutral {\n background-image: none;\n background-color: #5a5a5a;\n -webkit-mask-image: url(Images/securityStateNeutral.svg);\n -webkit-mask-size: cover;\n}\n\n.tree-outline .security-sidebar-tree-item.selected .security-property-insecure {\n -webkit-mask-image: url(Images/securityPropertyInsecure.svg);\n}\n\n.security-sidebar-tree-item.selected .security-property-neutral,\n.security-sidebar-tree-item.selected .security-property-warning {\n -webkit-mask-image: url(Images/securityPropertyWarning.svg);\n}\n\n.tree-outline .security-sidebar-tree-item.selected .security-property-unknown {\n -webkit-mask-image: url(Images/securityPropertyUnknown.svg);\n}\n\n.security-sidebar-tree-item.selected .security-property-secure {\n -webkit-mask-image: url(Images/securityPropertySecure.svg);\n}\n\n.sidebar-tree-item.security-main-view-reload-message .title {\n color: rgba(0, 0, 0, 0.5);\n padding-left: 8px;\n}\n\n/*# sourceURL=security/sidebar.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.EditFileSystemView=function(fileSystemPath) {WebInspector.VBox.call(this,true);this.registerRequiredCSS("settings/editFileSystemView.css");this._fileSystemPath=fileSystemPath;this._eventListeners=[WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingAdded,this._update,this),WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved,this._update,this),WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderAdded,this._update,this),WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.ExcludedFolderRemoved,this._update,this)];var mappingsHeader=this.contentElement.createChild("div","file-system-header");mappingsHeader.createChild("div","file-system-header-text").textContent=WebInspector.UIString("Mappings");mappingsHeader.appendChild(createTextButton(WebInspector.UIString("Add"),this._addMappingButtonClicked.bind(this),"add-button"));this._mappingsList=new WebInspector.ListWidget(this);this._mappingsList.element.classList.add("file-system-list");this._mappingsList.registerRequiredCSS("settings/editFileSystemView.css");var mappingsPlaceholder=createElementWithClass("div","file-system-list-empty");mappingsPlaceholder.textContent=WebInspector.UIString("No mappings");this._mappingsList.setEmptyPlaceholder(mappingsPlaceholder);this._mappingsList.show(this.contentElement);var excludedFoldersHeader=this.contentElement.createChild("div","file-system-header");excludedFoldersHeader.createChild("div","file-system-header-text").textContent=WebInspector.UIString("Excluded folders");excludedFoldersHeader.appendChild(createTextButton(WebInspector.UIString("Add"),this._addExcludedFolderButtonClicked.bind(this),"add-button"));this._excludedFoldersList=new WebInspector.ListWidget(this);this._excludedFoldersList.element.classList.add("file-system-list");this._excludedFoldersList.registerRequiredCSS("settings/editFileSystemView.css");var excludedFoldersPlaceholder=createElementWithClass("div","file-system-list-empty");excludedFoldersPlaceholder.textContent=WebInspector.UIString("No excluded folders");this._excludedFoldersList.setEmptyPlaceholder(excludedFoldersPlaceholder);this._excludedFoldersList.show(this.contentElement);this.contentElement.tabIndex=0;this._update();} WebInspector.EditFileSystemView.prototype={dispose:function() {WebInspector.EventTarget.removeEventListeners(this._eventListeners);},_update:function() {if(this._muteUpdate) return;this._mappingsList.clear();this._mappings=[];var mappings=WebInspector.fileSystemMapping.mappingEntries(this._fileSystemPath);for(var entry of mappings){if(entry.configurable){this._mappingsList.appendItem(entry,true);this._mappings.push(entry);}} for(var entry of mappings){if(!entry.configurable){this._mappingsList.appendItem(entry,false);this._mappings.push(entry);}} this._excludedFoldersList.clear();this._excludedFolders=[];for(var folder of WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).excludedFolders().values()){this._excludedFolders.push(folder);this._excludedFoldersList.appendItem(folder,true);} for(var folder of WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).nonConfigurableExcludedFolders().values()){this._excludedFolders.push(folder);this._excludedFoldersList.appendItem(folder,false);}},_addMappingButtonClicked:function() {var entry=new WebInspector.FileSystemMapping.Entry(this._fileSystemPath,"","",true);this._mappingsList.addNewItem(0,entry);},_addExcludedFolderButtonClicked:function() {this._excludedFoldersList.addNewItem(0,"");},renderItem:function(item,editable) {var element=createElementWithClass("div","file-system-list-item");if(!editable) element.classList.add("locked");if(item instanceof WebInspector.FileSystemMapping.Entry){var entry=(item);var urlPrefix=entry.configurable?entry.urlPrefix:WebInspector.UIString("%s (via .devtools)",entry.urlPrefix);var urlPrefixElement=element.createChild("div","file-system-value");urlPrefixElement.textContent=urlPrefix;urlPrefixElement.title=urlPrefix;element.createChild("div","file-system-separator");var pathPrefixElement=element.createChild("div","file-system-value");pathPrefixElement.textContent=entry.pathPrefix;pathPrefixElement.title=entry.pathPrefix;}else{var pathPrefix=(editable?item:WebInspector.UIString("%s (via .devtools)",item));var pathPrefixElement=element.createChild("div","file-system-value");pathPrefixElement.textContent=pathPrefix;pathPrefixElement.title=pathPrefix;} element.createChild("div","file-system-locked").title=WebInspector.UIString("From .devtools file");return element;},removeItemRequested:function(item,index) {if(item instanceof WebInspector.FileSystemMapping.Entry){var entry=this._mappings[index];WebInspector.fileSystemMapping.removeFileMapping(entry.fileSystemPath,entry.urlPrefix,entry.pathPrefix);}else{WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).removeExcludedFolder(this._excludedFolders[index]);}},commitEdit:function(item,editor,isNew) {this._muteUpdate=true;if(item instanceof WebInspector.FileSystemMapping.Entry){var entry=(item);if(!isNew) WebInspector.fileSystemMapping.removeFileMapping(this._fileSystemPath,entry.urlPrefix,entry.pathPrefix);WebInspector.fileSystemMapping.addFileMapping(this._fileSystemPath,this._normalizePrefix(editor.control("urlPrefix").value),this._normalizePrefix(editor.control("pathPrefix").value));}else{if(!isNew) WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).removeExcludedFolder((item));WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).addExcludedFolder(this._normalizePrefix(editor.control("pathPrefix").value));} this._muteUpdate=false;this._update();},beginEdit:function(item) {if(item instanceof WebInspector.FileSystemMapping.Entry){var entry=(item);var editor=this._createMappingEditor();editor.control("urlPrefix").value=entry.urlPrefix;editor.control("pathPrefix").value=entry.pathPrefix;return editor;}else{var editor=this._createExcludedFolderEditor();editor.control("pathPrefix").value=item;return editor;}},_createMappingEditor:function() {if(this._mappingEditor) return this._mappingEditor;var editor=new WebInspector.ListWidget.Editor();this._mappingEditor=editor;var content=editor.contentElement();var titles=content.createChild("div","file-system-edit-row");titles.createChild("div","file-system-value").textContent=WebInspector.UIString("URL prefix");titles.createChild("div","file-system-separator file-system-separator-invisible");titles.createChild("div","file-system-value").textContent=WebInspector.UIString("Folder path");var fields=content.createChild("div","file-system-edit-row");fields.createChild("div","file-system-value").appendChild(editor.createInput("urlPrefix","text","http://localhost:8000/url",urlPrefixValidator.bind(this)));fields.createChild("div","file-system-separator file-system-separator-invisible");fields.createChild("div","file-system-value").appendChild(editor.createInput("pathPrefix","text","/path/to/folder/",pathPrefixValidator.bind(this)));return editor;function urlPrefixValidator(item,index,input) {var prefix=this._normalizePrefix(input.value);for(var i=0;i<this._mappings.length;++i){if(i!==index&&this._mappings[i].configurable&&this._mappings[i].urlPrefix===prefix) return false;} return!!prefix;} function pathPrefixValidator(item,index,input) {var prefix=this._normalizePrefix(input.value);for(var i=0;i<this._mappings.length;++i){if(i!==index&&this._mappings[i].configurable&&this._mappings[i].pathPrefix===prefix) return false;} return!!prefix;}},_createExcludedFolderEditor:function() {if(this._excludedFolderEditor) return this._excludedFolderEditor;var editor=new WebInspector.ListWidget.Editor();this._excludedFolderEditor=editor;var content=editor.contentElement();var titles=content.createChild("div","file-system-edit-row");titles.createChild("div","file-system-value").textContent=WebInspector.UIString("Folder path");var fields=content.createChild("div","file-system-edit-row");fields.createChild("div","file-system-value").appendChild(editor.createInput("pathPrefix","text","/path/to/folder/",pathPrefixValidator.bind(this)));return editor;function pathPrefixValidator(item,index,input) {var prefix=this._normalizePrefix(input.value);var configurableCount=WebInspector.isolatedFileSystemManager.fileSystem(this._fileSystemPath).excludedFolders().size;for(var i=0;i<configurableCount;++i){if(i!==index&&this._excludedFolders[i]===prefix) return false;} return!!prefix;}},_normalizePrefix:function(prefix) {if(!prefix) return"";return prefix+(prefix[prefix.length-1]==="/"?"":"/");},__proto__:WebInspector.VBox.prototype};WebInspector.SettingsScreen=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("settings/settingsScreen.css");this.contentElement.tabIndex=0;this.contentElement.classList.add("help-window-main");this.contentElement.classList.add("vbox");var settingsLabelElement=createElementWithClass("div","help-window-label");settingsLabelElement.createTextChild(WebInspector.UIString("Settings"));this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.insertBeforeTabStrip(settingsLabelElement);this._tabbedPane.setShrinkableTabs(false);this._tabbedPane.setVerticalTabLayout(true);this._tabbedPane.appendTab("preferences",WebInspector.UIString("Preferences"),new WebInspector.GenericSettingsTab());this._tabbedPane.appendTab("workspace",WebInspector.UIString("Workspace"),new WebInspector.WorkspaceSettingsTab());this._tabbedPane.appendTab("blackbox",WebInspector.manageBlackboxingSettingsTabLabel(),new WebInspector.FrameworkBlackboxSettingsTab());if(Runtime.experiments.supportEnabled()) this._tabbedPane.appendTab("experiments",WebInspector.UIString("Experiments"),new WebInspector.ExperimentsSettingsTab());this._tabbedPaneController=new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane,"settings-view");this._tabbedPane.appendTab("shortcuts",WebInspector.UIString("Shortcuts"),WebInspector.shortcutsScreen.createShortcutsTabView());this.element.addEventListener("keydown",this._keyDown.bind(this),false);this._developerModeCounter=0;this.setDefaultFocusedElement(this.contentElement);} WebInspector.SettingsScreen.prototype={wasShown:function() {this._tabbedPane.selectTab("preferences");this._tabbedPane.show(this.contentElement);WebInspector.VBox.prototype.wasShown.call(this);},selectTab:function(name) {this._tabbedPane.selectTab(name);},_keyDown:function(event) {var shiftKeyCode=16;if(event.keyCode===shiftKeyCode&&++this._developerModeCounter>5) this.contentElement.classList.add("settings-developer-mode");},__proto__:WebInspector.VBox.prototype} WebInspector.SettingsTab=function(name,id) {WebInspector.VBox.call(this);this.element.classList.add("settings-tab-container");if(id) this.element.id=id;var header=this.element.createChild("header");header.createChild("h3").createTextChild(name);this.containerElement=this.element.createChild("div","help-container-wrapper").createChild("div","settings-tab help-content help-container");} WebInspector.SettingsTab.prototype={_appendSection:function(name) {var block=this.containerElement.createChild("div","help-block");if(name) block.createChild("div","help-section-title").textContent=name;return block;},_createSelectSetting:function(name,options,setting) {var p=createElement("p");p.createChild("label").textContent=name;var select=p.createChild("select","chrome-select");var settingValue=setting.get();for(var i=0;i<options.length;++i){var option=options[i];select.add(new Option(option[0],option[1]));if(settingValue===option[1]) select.selectedIndex=i;} function changeListener(e) {setting.set(options[select.selectedIndex][1]);} select.addEventListener("change",changeListener,false);return p;},__proto__:WebInspector.VBox.prototype} WebInspector.GenericSettingsTab=function() {WebInspector.SettingsTab.call(this,WebInspector.UIString("Preferences"),"preferences-tab-content");var explicitSectionOrder=["","Appearance","Elements","Sources","Network","Profiler","Console","Extensions"];this._nameToSection=new Map();this._nameToSettingElement=new Map();for(var sectionName of explicitSectionOrder) this._sectionElement(sectionName);self.runtime.extensions("setting").forEach(this._addSetting.bind(this));self.runtime.extensions(WebInspector.SettingUI).forEach(this._addSettingUI.bind(this));this._appendSection().appendChild(createTextButton(WebInspector.UIString("Restore defaults and reload"),restoreAndReload));function restoreAndReload() {WebInspector.settings.clearAll();WebInspector.reload();}} WebInspector.GenericSettingsTab.isSettingVisible=function(extension) {var descriptor=extension.descriptor();if(!("title"in descriptor)) return false;if(!("category"in descriptor)) return false;return true;} WebInspector.GenericSettingsTab.prototype={_addSetting:function(extension) {if(!WebInspector.GenericSettingsTab.isSettingVisible(extension)) return;var descriptor=extension.descriptor();var sectionName=descriptor["category"];var settingName=descriptor["settingName"];var setting=WebInspector.moduleSetting(settingName);var uiTitle=WebInspector.UIString(extension.title(WebInspector.platform()));var sectionElement=this._sectionElement(sectionName);var settingControl;switch(descriptor["settingType"]){case"boolean":settingControl=WebInspector.SettingsUI.createSettingCheckbox(uiTitle,setting);break;case"enum":var descriptorOptions=descriptor["options"];var options=new Array(descriptorOptions.length);for(var i=0;i<options.length;++i){var optionName=descriptorOptions[i]["raw"]?descriptorOptions[i]["text"]:WebInspector.UIString(descriptorOptions[i]["text"]);options[i]=[optionName,descriptorOptions[i]["value"]];} settingControl=this._createSelectSetting(uiTitle,options,setting);break;default:console.error("Invalid setting type: "+descriptor["settingType"]);return;} this._nameToSettingElement.set(settingName,settingControl);sectionElement.appendChild((settingControl));},_addSettingUI:function(extension) {var descriptor=extension.descriptor();var sectionName=descriptor["category"]||"";extension.instancePromise().then(appendCustomSetting.bind(this));function appendCustomSetting(object) {var settingUI=(object);var element=settingUI.settingElement();if(element) this._sectionElement(sectionName).appendChild(element);}},_sectionElement:function(sectionName) {var sectionElement=this._nameToSection.get(sectionName);if(!sectionElement){var uiSectionName=sectionName&&WebInspector.UIString(sectionName);sectionElement=this._appendSection(uiSectionName);this._nameToSection.set(sectionName,sectionElement);} return sectionElement;},__proto__:WebInspector.SettingsTab.prototype} WebInspector.WorkspaceSettingsTab=function() {WebInspector.SettingsTab.call(this,WebInspector.UIString("Workspace"),"workspace-tab-content");WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded,this._fileSystemAdded,this);WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved,this._fileSystemRemoved,this);var folderExcludePatternInput=this._createFolderExcludePatternInput();folderExcludePatternInput.classList.add("folder-exclude-pattern");this.containerElement.appendChild(folderExcludePatternInput);this._fileSystemsListContainer=this.containerElement.createChild("div","");this.containerElement.appendChild(createTextButton(WebInspector.UIString("Add folder\u2026"),this._addFileSystemClicked.bind(this)));this._elementByPath=new Map();this._mappingViewByPath=new Map();var fileSystemPaths=WebInspector.isolatedFileSystemManager.fileSystemPaths();for(var i=0;i<fileSystemPaths.length;++i) this._addItem((WebInspector.isolatedFileSystemManager.fileSystem(fileSystemPaths[i])));} WebInspector.WorkspaceSettingsTab.prototype={_createFolderExcludePatternInput:function() {var p=createElement("p");var labelElement=p.createChild("label");labelElement.textContent=WebInspector.UIString("Folder exclude pattern");var inputElement=p.createChild("input");inputElement.type="text";inputElement.style.width="270px";var folderExcludeSetting=WebInspector.isolatedFileSystemManager.workspaceFolderExcludePatternSetting();var setValue=WebInspector.bindInput(inputElement,folderExcludeSetting.set.bind(folderExcludeSetting),regexValidator,false);folderExcludeSetting.addChangeListener(()=>setValue.call(null,folderExcludeSetting.get()));setValue(folderExcludeSetting.get());return p;function regexValidator(value) {var regex;try{regex=new RegExp(value);}catch(e){} return!!regex;}},_addItem:function(fileSystem) {var element=this._renderFileSystem(fileSystem);this._elementByPath.set(fileSystem.path(),element);this._fileSystemsListContainer.appendChild(element);var mappingView=new WebInspector.EditFileSystemView(fileSystem.path());this._mappingViewByPath.set(fileSystem.path(),mappingView);mappingView.element.classList.add("file-system-mapping-view");mappingView.show(element);},_renderFileSystem:function(fileSystem) {var fileSystemPath=fileSystem.path();var lastIndexOfSlash=fileSystemPath.lastIndexOf(WebInspector.isWin()?"\\":"/");var folderName=fileSystemPath.substr(lastIndexOfSlash+1);var element=createElementWithClass("div","file-system-container");var header=element.createChild("div","file-system-header");header.createChild("div","file-system-name").textContent=folderName;var path=header.createChild("div","file-system-path");path.textContent=fileSystemPath;path.title=fileSystemPath;var toolbar=new WebInspector.Toolbar("");var button=new WebInspector.ToolbarButton(WebInspector.UIString("Remove"),"delete-toolbar-item");button.addEventListener("click",this._removeFileSystemClicked.bind(this,fileSystem));toolbar.appendToolbarItem(button);header.appendChild(toolbar.element);return element;},_removeFileSystemClicked:function(fileSystem) {WebInspector.isolatedFileSystemManager.removeFileSystem(fileSystem);},_addFileSystemClicked:function() {WebInspector.isolatedFileSystemManager.addFileSystem();},_fileSystemAdded:function(event) {var fileSystem=(event.data);this._addItem(fileSystem);},_fileSystemRemoved:function(event) {var fileSystem=(event.data);var mappingView=this._mappingViewByPath.get(fileSystem.path());if(mappingView){mappingView.dispose();this._mappingViewByPath.delete(fileSystem.path());} var element=this._elementByPath.get(fileSystem.path());if(element){this._elementByPath.delete(fileSystem.path());element.remove();}},__proto__:WebInspector.SettingsTab.prototype} WebInspector.ExperimentsSettingsTab=function() {WebInspector.SettingsTab.call(this,WebInspector.UIString("Experiments"),"experiments-tab-content");var experiments=Runtime.experiments.allConfigurableExperiments();if(experiments.length){var experimentsSection=this._appendSection();experimentsSection.appendChild(this._createExperimentsWarningSubsection());for(var i=0;i<experiments.length;++i) experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));}} WebInspector.ExperimentsSettingsTab.prototype={_createExperimentsWarningSubsection:function() {var subsection=createElement("div");var warning=subsection.createChild("span","settings-experiments-warning-subsection-warning");warning.textContent=WebInspector.UIString("WARNING:");subsection.createTextChild(" ");var message=subsection.createChild("span","settings-experiments-warning-subsection-message");message.textContent=WebInspector.UIString("These experiments could be dangerous and may require restart.");return subsection;},_createExperimentCheckbox:function(experiment) {var label=createCheckboxLabel(WebInspector.UIString(experiment.title),experiment.isEnabled());var input=label.checkboxElement;input.name=experiment.name;function listener() {experiment.setEnabled(input.checked);} input.addEventListener("click",listener,false);var p=createElement("p");p.className=experiment.hidden&&!experiment.isEnabled()?"settings-experiment-hidden":"";p.appendChild(label);return p;},__proto__:WebInspector.SettingsTab.prototype} WebInspector.SettingsController=function() {this._settingsScreen;} WebInspector.SettingsController.prototype={showSettingsScreen:function(name) {if(!this._settingsScreen) this._settingsScreen=new WebInspector.SettingsScreen();var dialog=new WebInspector.Dialog();dialog.addCloseButton();this._settingsScreen.show(dialog.element);dialog.show();if(name) this._settingsScreen.selectTab(name);}} WebInspector.SettingsController.ActionDelegate=function(){} WebInspector.SettingsController.ActionDelegate.prototype={handleAction:function(context,actionId) {switch(actionId){case"settings.show":WebInspector._settingsController.showSettingsScreen();return true;case"settings.help":InspectorFrontendHost.openInNewTab("https://developers.google.com/web/tools/chrome-devtools/");return true;case"settings.shortcuts":WebInspector._settingsController.showSettingsScreen("shortcuts");return true;} return false;}} WebInspector.SettingsController.Revealer=function(){} WebInspector.SettingsController.Revealer.prototype={reveal:function(object) {console.assert(object instanceof WebInspector.Setting);var setting=(object);var success=false;self.runtime.extensions("setting").forEach(revealModuleSetting);self.runtime.extensions(WebInspector.SettingUI).forEach(revealSettingUI);self.runtime.extensions("settings-view").forEach(revealSettingsView);return success?Promise.resolve():Promise.reject();function revealModuleSetting(extension) {if(!WebInspector.GenericSettingsTab.isSettingVisible(extension)) return;if(extension.descriptor()["settingName"]===setting.name){WebInspector._settingsController.showSettingsScreen("preferences");success=true;}} function revealSettingUI(extension) {var settings=extension.descriptor()["settings"];if(settings&&settings.indexOf(setting.name)!==-1){WebInspector._settingsController.showSettingsScreen("preferences");success=true;}} function revealSettingsView(extension) {var settings=extension.descriptor()["settings"];if(settings&&settings.indexOf(setting.name)!==-1){WebInspector._settingsController.showSettingsScreen(extension.descriptor()["name"]);success=true;}}}} WebInspector._settingsController=new WebInspector.SettingsController();;WebInspector.FrameworkBlackboxSettingsTab=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("settings/frameworkBlackboxSettingsTab.css");this.contentElement.createChild("div","header").textContent=WebInspector.UIString("Framework Blackbox Patterns");this.contentElement.createChild("div","blackbox-content-scripts").appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Blackbox content scripts"),WebInspector.moduleSetting("skipContentScripts"),true));this._blackboxLabel=WebInspector.UIString("Blackbox");this._disabledLabel=WebInspector.UIString("Disabled");this._list=new WebInspector.ListWidget(this);this._list.element.classList.add("blackbox-list");this._list.registerRequiredCSS("settings/frameworkBlackboxSettingsTab.css");var placeholder=createElementWithClass("div","blackbox-list-empty");placeholder.textContent=WebInspector.UIString("No blackboxed patterns");this._list.setEmptyPlaceholder(placeholder);this._list.show(this.contentElement);this.contentElement.appendChild(createTextButton(WebInspector.UIString("Add pattern..."),this._addButtonClicked.bind(this),"add-button"));this._setting=WebInspector.moduleSetting("skipStackFramesPattern");this._setting.addChangeListener(this._settingUpdated,this);this.contentElement.tabIndex=0;} WebInspector.FrameworkBlackboxSettingsTab.prototype={wasShown:function() {WebInspector.SettingsTab.prototype.wasShown.call(this);this._settingUpdated();},_settingUpdated:function() {this._list.clear();var patterns=this._setting.getAsArray();for(var i=0;i<patterns.length;++i) this._list.appendItem(patterns[i],true);},_addButtonClicked:function() {this._list.addNewItem(this._setting.getAsArray().length,{pattern:"",disabled:false});},renderItem:function(item,editable) {var element=createElementWithClass("div","blackbox-list-item");var pattern=element.createChild("div","blackbox-pattern");pattern.textContent=item.pattern;pattern.title=item.pattern;element.createChild("div","blackbox-separator");element.createChild("div","blackbox-behavior").textContent=item.disabled?this._disabledLabel:this._blackboxLabel;if(item.disabled) element.classList.add("blackbox-disabled");return element;},removeItemRequested:function(item,index) {var patterns=this._setting.getAsArray();patterns.splice(index,1);this._setting.setAsArray(patterns);},commitEdit:function(item,editor,isNew) {item.pattern=editor.control("pattern").value.trim();item.disabled=editor.control("behavior").value===this._disabledLabel;var list=this._setting.getAsArray();if(isNew) list.push(item);this._setting.setAsArray(list);},beginEdit:function(item) {var editor=this._createEditor();editor.control("pattern").value=item.pattern;editor.control("behavior").value=item.disabled?this._disabledLabel:this._blackboxLabel;return editor;},_createEditor:function() {if(this._editor) return this._editor;var editor=new WebInspector.ListWidget.Editor();this._editor=editor;var content=editor.contentElement();var titles=content.createChild("div","blackbox-edit-row");titles.createChild("div","blackbox-pattern").textContent=WebInspector.UIString("Pattern");titles.createChild("div","blackbox-separator blackbox-separator-invisible");titles.createChild("div","blackbox-behavior").textContent=WebInspector.UIString("Behavior");var fields=content.createChild("div","blackbox-edit-row");fields.createChild("div","blackbox-pattern").appendChild(editor.createInput("pattern","text","/framework\\.js$",patternValidator.bind(this)));fields.createChild("div","blackbox-separator blackbox-separator-invisible");fields.createChild("div","blackbox-behavior").appendChild(editor.createSelect("behavior",[this._blackboxLabel,this._disabledLabel],behaviorValidator));return editor;function patternValidator(item,index,input) {var pattern=input.value.trim();var patterns=this._setting.getAsArray();for(var i=0;i<patterns.length;++i){if(i!==index&&patterns[i].pattern===pattern) return false;} var regex;try{regex=new RegExp(pattern);}catch(e){} return!!(pattern&®ex);} function behaviorValidator(item,index,input) {return true;}},__proto__:WebInspector.VBox.prototype};Runtime.cachedResources["settings/editFileSystemView.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.file-system-header {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex: auto;\n margin: 10px 0;\n}\n\n.file-system-header-text {\n font-size: 14px;\n flex: auto;\n}\n\n.add-button {\n margin-left: 10px;\n align-self: flex-start;\n}\n\n.file-system-list {\n flex: auto;\n}\n\n.file-system-list-empty {\n flex: auto;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.file-system-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n flex: auto 1 1;\n}\n\n.file-system-value {\n white-space: nowrap;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n color: #222;\n flex: 1 1 0px;\n overflow: hidden;\n}\n\n.file-system-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.file-system-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.file-system-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n align-items: center;\n}\n\n.file-system-edit-row input {\n width: 100%;\n text-align: inherit;\n}\n\n.file-system-locked {\n flex: none;\n visibility: hidden;\n}\n\n.file-system-locked:after {\n content: \"\\1F512\";\n}\n\n.file-system-list-item.locked .file-system-locked {\n visibility: visible;\n}\n\n/*# sourceURL=settings/editFileSystemView.css */";Runtime.cachedResources["settings/frameworkBlackboxSettingsTab.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow:hidden;\n}\n\n.header {\n padding: 0 0 6px;\n border-bottom: 1px solid #EEEEEE;\n font-size: 18px;\n font-weight: normal;\n flex: none;\n}\n\n.blackbox-content-scripts {\n margin-top: 10px;\n flex: none;\n}\n\n.add-button {\n margin: 10px 0;\n align-self: flex-start;\n flex: none;\n}\n\n.blackbox-list {\n margin-top: 10px;\n max-width: 500px;\n flex: 0 1 auto;\n min-height: 30px;\n}\n\n.blackbox-list-empty {\n flex: auto;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.blackbox-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n flex: auto 1 1;\n}\n\n.blackbox-pattern {\n white-space: nowrap;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n color: #222;\n flex: auto;\n overflow: hidden;\n}\n\n.blackbox-list-item.blackbox-disabled .blackbox-pattern {\n text-decoration: line-through;\n}\n\n.blackbox-behavior {\n flex: 0 0 100px;\n padding-left: 10px;\n}\n\n.blackbox-behavior > select {\n margin-left: -10px;\n}\n\n.blackbox-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.blackbox-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.blackbox-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n align-items: center;\n}\n\n.blackbox-edit-row input,\n.blackbox-edit-row select {\n width: 100%;\n text-align: inherit;\n}\n\n/*# sourceURL=settings/frameworkBlackboxSettingsTab.css */";Runtime.cachedResources["settings/settingsScreen.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.help-window-main {\n color: rgb(48, 57, 66);\n background-color: white;\n padding: 11px 0 0 0;\n}\n\n.help-window-caption {\n border-bottom: solid 1px rgb(153, 153, 153);\n margin: 0 8px;\n padding: 0 2px;\n line-height: 28px;\n}\n\n.help-content {\n overflow-y: auto;\n overflow-x: hidden;\n margin: 8px 8px 8px 0;\n padding: 0 4px;\n flex: auto;\n}\n\n.help-footnote {\n border-top: 1px solid #EEEEEE;\n margin: 0;\n padding: 12px;\n}\n\n.help-window-main .help-container-wrapper::-webkit-scrollbar {\n width: 11px;\n}\n\n.help-window-main .help-container-wrapper::-webkit-scrollbar-corner,\n.help-window-main .help-container-wrapper::-webkit-resizer {\n display: none;\n}\n\n.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical {\n background: linear-gradient(to right, rgb(128, 128, 128), rgb(96, 96, 96) 40%, rgb(128, 128, 128));\n border-radius: 5px;\n min-height: 20px;\n}\n\n.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical:hover,\n.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical:active {\n background: linear-gradient(to right, rgb(176, 176, 176), rgb(144, 144, 144) 40%, rgb(176, 176, 176));\n}\n\n.help-window-main .help-container-wrapper::-webkit-scrollbar-track:vertical {\n background: linear-gradient(to right, rgb(10, 10, 10), rgb(32, 32, 32) 25%, rgb(32, 32, 32));\n border-radius: 5px;\n}\n\n.help-container {\n width: 100%;\n -webkit-user-select: auto;\n -webkit-column-width: 288px;\n}\n\n.help-no-columns {\n -webkit-column-width: initial !important;\n}\n\n.help-block {\n display: block;\n padding-bottom: 9px;\n width: 288px;\n -webkit-column-break-inside: avoid;\n}\n\n.settings-tab.help-container {\n -webkit-column-width: 308px;\n}\n\n.settings-tab .help-block {\n margin-left: 20px;\n}\n\n.settings-tab .field-error-message {\n color: DarkRed;\n height: 0; /* Avoid changing element height when content is set. */\n}\n\n.help-line {\n padding-bottom: 5px;\n margin-bottom: 5px;\n}\n\n.help-key-cell {\n display: inline-block;\n width: 153px;\n white-space: nowrap;\n text-align: right;\n vertical-align: middle;\n padding-right: 6px;\n}\n\n.help-cell {\n display: inline-block;\n width: 135px;\n vertical-align: middle;\n}\n\n.help-section-title {\n font-size: 120%;\n text-align: left;\n}\n\n.help-key {\n padding: 0.1em 0.6em;\n border: 1px solid #ccc;\n font-size: 11px;\n background-color: #f7f7f7;\n color: #333;\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset;\n border-radius: 3px;\n display: inline-block;\n margin: 0 0.1em;\n text-shadow: 0 1px 0 #fff;\n line-height: 1.5;\n white-space: nowrap;\n}\n\n.help-combine-keys,\n.help-key-delimiter {\n font-size: 9px;\n}\n\n.help-combine-keys {\n margin: 0 0.3em;\n}\n\n.help-key-delimiter {\n margin: 0 0.5em;\n display: none;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.settings-tab label {\n padding-right: 4px;\n display: inline-flex;\n}\n\n#general-tab-content .help-block fieldset legend {\n font-size: 14px;\n}\n\n.help-block p p {\n padding-left: 30px;\n}\n\n.help-content p.help-section {\n margin: 0 0 15px 0;\n}\n\n.settings-experiments-warning-subsection-warning {\n color: rgb(200, 0, 0);\n}\n\n.settings-experiments-warning-subsection-message {\n color: inherit;\n}\n\n.help-content input[type=checkbox] {\n margin: 1px 7px 1px 2px;\n}\n\n.help-content option {\n background-color: #EEEEEE;\n color: #222;\n}\n\n.help-window-label {\n font-size: 18px;\n color: inherit;\n padding: 1px 0 15px 17px;\n flex: none;\n}\n\n.help-container-wrapper {\n position: absolute;\n top: 40px;\n left: 0px;\n right: 0;\n bottom: 0;\n overflow: auto;\n}\n\n.settings-tab.help-content {\n margin: 0;\n padding: 0;\n}\n\n.settings-tab input:not([type]),\n.settings-tab input[type=\"text\"] {\n border: 1px solid rgb(213, 213, 213);\n border-radius: 2px;\n color: #444444;\n padding: 3px;\n}\n\n.settings-tab input.numeric {\n text-align: right;\n}\n\n.settings-tab-container {\n flex: auto;\n overflow: hidden;\n}\n\n.settings-tab-container header {\n padding: 0 0 6px;\n border-bottom: 1px solid #EEEEEE;\n}\n\n#experiments-tab-content .help-container {\n -webkit-column-width: 470px;\n}\n\n#experiments-tab-content .help-block {\n width: 470px;\n margin-left: 0;\n}\n\n.settings-tab-container header > h3 {\n font-size: 18px;\n font-weight: normal;\n margin: 0;\n padding-bottom: 3px;\n}\n\n.settings-tab .help-section-title {\n margin-left: -20px;\n color: #222;\n}\n\n.settings-tab .help-block fieldset:disabled label:hover {\n color: inherit;\n}\n\n.settings-tab .help-block label:hover {\n color: #222;\n}\n\n.settings-tab p {\n margin: 12px 0;\n}\n\n.settings-tab select {\n margin-left: 10px;\n}\n\n#workspace-tab-content .settings-tab.help-content.help-container {\n -webkit-column-width: initial;\n overflow: hidden;\n}\n\n\n#workspace-tab-content .button:hover {\n opacity: 1.0 !important;\n}\n\n#workspace-tab-content .help-block {\n width: auto;\n margin-right: 20px;\n}\n\np.folder-exclude-pattern {\n margin-top: 0 !important;\n}\n\n.folder-exclude-pattern input {\n margin-top: 10px;\n}\n\n.file-system-mapping-view {\n margin-left: 30px;\n margin-right: 10px;\n}\n\n.settings-tab .file-system-container {\n margin-bottom: 18px;\n padding: 0 8px;\n border-left: 1px solid hsl(0, 0%, 90%);\n max-width: 800px;\n}\n\n.settings-tab .file-system-header {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.settings-tab .file-system-name {\n font-weight: bold;\n flex: none;\n margin-right: 10px;\n font-size: 15px;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.settings-tab .file-system-path {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: auto;\n}\n\n.settings-tab .file-system-remove {\n flex: none;\n margin-left: 10px;\n}\n\n.help-indent-labels label {\n padding-left: 10px;\n}\n\n.settings-experiment-hidden {\n display: none;\n}\n\n.settings-experiment-hidden label {\n background-color: #ddd;\n}\n\n.settings-developer-mode .settings-experiment-hidden {\n display: block;\n}\n\n/*# sourceURL=settings/settingsScreen.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 2 1 1 1 | WebInspector.SnippetStorage=function(settingPrefix,namePrefix) {this._snippets={};this._lastSnippetIdentifierSetting=WebInspector.settings.createSetting(settingPrefix+"Snippets_lastIdentifier",0);this._snippetsSetting=WebInspector.settings.createSetting(settingPrefix+"Snippets",[]);this._namePrefix=namePrefix;this._loadSettings();} WebInspector.SnippetStorage.prototype={get namePrefix() {return this._namePrefix;},_saveSettings:function() {var savedSnippets=[];for(var id in this._snippets) savedSnippets.push(this._snippets[id].serializeToObject());this._snippetsSetting.set(savedSnippets);},snippets:function() {var result=[];for(var id in this._snippets) result.push(this._snippets[id]);return result;},snippetForId:function(id) {return this._snippets[id];},snippetForName:function(name) {var snippets=Object.values(this._snippets);for(var i=0;i<snippets.length;++i) if(snippets[i].name===name) return snippets[i];return null;},_loadSettings:function() {var savedSnippets=this._snippetsSetting.get();for(var i=0;i<savedSnippets.length;++i) this._snippetAdded(WebInspector.Snippet.fromObject(this,savedSnippets[i]));},deleteSnippet:function(snippet) {delete this._snippets[snippet.id];this._saveSettings();},createSnippet:function() {var nextId=this._lastSnippetIdentifierSetting.get()+1;var snippetId=String(nextId);this._lastSnippetIdentifierSetting.set(nextId);var snippet=new WebInspector.Snippet(this,snippetId);this._snippetAdded(snippet);this._saveSettings();return snippet;},_snippetAdded:function(snippet) {this._snippets[snippet.id]=snippet;},__proto__:WebInspector.Object.prototype} WebInspector.Snippet=function(storage,id,name,content) {this._storage=storage;this._id=id;this._name=name||storage.namePrefix+id;this._content=content||"";} WebInspector.Snippet.fromObject=function(storage,serializedSnippet) {return new WebInspector.Snippet(storage,serializedSnippet.id,serializedSnippet.name,serializedSnippet.content);} WebInspector.Snippet.prototype={get id() {return this._id;},get name() {return this._name;},set name(name) {if(this._name===name) return;this._name=name;this._storage._saveSettings();},get content() {return this._content;},set content(content) {if(this._content===content) return;this._content=content;this._storage._saveSettings();},serializeToObject:function() {var serializedSnippet={};serializedSnippet.id=this.id;serializedSnippet.name=this.name;serializedSnippet.content=this.content;return serializedSnippet;},__proto__:WebInspector.Object.prototype};WebInspector.ScriptSnippetModel=function(workspace) {this._workspace=workspace;this._uiSourceCodeForSnippetId={};this._snippetIdForUISourceCode=new Map();this._mappingForTarget=new Map();this._snippetStorage=new WebInspector.SnippetStorage("script","Script snippet #");this._lastSnippetEvaluationIndexSetting=WebInspector.settings.createSetting("lastSnippetEvaluationIndex",0);this._project=new WebInspector.SnippetsProject(workspace,this);this._loadSnippets();WebInspector.targetManager.observeTargets(this);} WebInspector.ScriptSnippetModel.snippetSourceURLPrefix="snippets:///";WebInspector.ScriptSnippetModel.prototype={targetAdded:function(target) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel) this._mappingForTarget.set(target,new WebInspector.SnippetScriptMapping(debuggerModel,this));},targetRemoved:function(target) {if(WebInspector.DebuggerModel.fromTarget(target)) this._mappingForTarget.remove(target);},snippetScriptMapping:function(target) {return this._mappingForTarget.get(target);},project:function() {return this._project;},_loadSnippets:function() {var snippets=this._snippetStorage.snippets();for(var i=0;i<snippets.length;++i) this._addScriptSnippet(snippets[i]);},createScriptSnippet:function(content) {var snippet=this._snippetStorage.createSnippet();snippet.content=content;return this._addScriptSnippet(snippet);},_addScriptSnippet:function(snippet) {var uiSourceCode=this._project.addSnippet(snippet.name,new WebInspector.SnippetContentProvider(snippet));uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._snippetIdForUISourceCode.set(uiSourceCode,snippet.id);var breakpointLocations=this._removeBreakpoints(uiSourceCode);this._restoreBreakpoints(uiSourceCode,breakpointLocations);this._uiSourceCodeForSnippetId[snippet.id]=uiSourceCode;return uiSourceCode;},_workingCopyChanged:function(event) {var uiSourceCode=(event.target);this._scriptSnippetEdited(uiSourceCode);},deleteScriptSnippet:function(url) {var uiSourceCode=this._project.uiSourceCodeForURL(url);if(!uiSourceCode) return;var snippetId=this._snippetIdForUISourceCode.get(uiSourceCode)||"";var snippet=this._snippetStorage.snippetForId(snippetId);this._snippetStorage.deleteSnippet(snippet);this._removeBreakpoints(uiSourceCode);this._releaseSnippetScript(uiSourceCode);delete this._uiSourceCodeForSnippetId[snippet.id];this._snippetIdForUISourceCode.remove(uiSourceCode);this._project.removeFile(snippet.name);},renameScriptSnippet:function(name,newName,callback) {newName=newName.trim();if(!newName||newName.indexOf("/")!==-1||name===newName||this._snippetStorage.snippetForName(newName)){callback(false);return;} var snippet=this._snippetStorage.snippetForName(name);console.assert(snippet,"Snippet '"+name+"' was not found.");var uiSourceCode=this._uiSourceCodeForSnippetId[snippet.id];console.assert(uiSourceCode,"No uiSourceCode was found for snippet '"+name+"'.");var breakpointLocations=this._removeBreakpoints(uiSourceCode);snippet.name=newName;this._restoreBreakpoints(uiSourceCode,breakpointLocations);callback(true,newName);},_setScriptSnippetContent:function(name,newContent) {var snippet=this._snippetStorage.snippetForName(name);snippet.content=newContent;},_scriptSnippetEdited:function(uiSourceCode) {var breakpointLocations=this._removeBreakpoints(uiSourceCode);this._releaseSnippetScript(uiSourceCode);this._restoreBreakpoints(uiSourceCode,breakpointLocations);this._mappingForTarget.valuesArray().forEach(function(mapping){mapping._restoreBreakpoints(uiSourceCode,breakpointLocations);});},_nextEvaluationIndex:function() {var evaluationIndex=this._lastSnippetEvaluationIndexSetting.get()+1;this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);return evaluationIndex;},evaluateScriptSnippet:function(executionContext,uiSourceCode) {var breakpointLocations=this._removeBreakpoints(uiSourceCode);this._releaseSnippetScript(uiSourceCode);this._restoreBreakpoints(uiSourceCode,breakpointLocations);var target=executionContext.target();var runtimeModel=target.runtimeModel;var evaluationIndex=this._nextEvaluationIndex();var mapping=this._mappingForTarget.get(target);mapping._setEvaluationIndex(evaluationIndex,uiSourceCode);var evaluationUrl=mapping._evaluationSourceURL(uiSourceCode);var expression=uiSourceCode.workingCopy();WebInspector.console.show();runtimeModel.compileScript(expression,"",true,executionContext.id,compileCallback.bind(this));function compileCallback(scriptId,exceptionDetails) {var mapping=this._mappingForTarget.get(target);if(mapping.evaluationIndex(uiSourceCode)!==evaluationIndex) return;if(!scriptId){this._printRunOrCompileScriptResultFailure(target,exceptionDetails,evaluationUrl);return;} mapping._addScript(executionContext.debuggerModel.scriptForId(scriptId),uiSourceCode);var breakpointLocations=this._removeBreakpoints(uiSourceCode);this._restoreBreakpoints(uiSourceCode,breakpointLocations);this._runScript(scriptId,executionContext,evaluationUrl);}},_runScript:function(scriptId,executionContext,sourceURL) {var target=executionContext.target();target.runtimeModel.runScript(scriptId,executionContext.id,"console",false,true,runCallback.bind(this,target));function runCallback(target,result,exceptionDetails) {if(!exceptionDetails) this._printRunScriptResult(target,result,sourceURL);else this._printRunOrCompileScriptResultFailure(target,exceptionDetails,sourceURL);}},_printRunScriptResult:function(target,result,sourceURL) {var consoleMessage=new WebInspector.ConsoleMessage(target,WebInspector.ConsoleMessage.MessageSource.JS,WebInspector.ConsoleMessage.MessageLevel.Log,"",undefined,sourceURL,undefined,undefined,undefined,[result],undefined);target.consoleModel.addMessage(consoleMessage);},_printRunOrCompileScriptResultFailure:function(target,exceptionDetails,sourceURL) {var consoleMessage=new WebInspector.ConsoleMessage(target,exceptionDetails.source,WebInspector.ConsoleMessage.MessageLevel.Error,exceptionDetails.text,undefined,sourceURL,exceptionDetails.line,exceptionDetails.column,undefined,undefined,exceptionDetails.stack);target.consoleModel.addMessage(consoleMessage);},_removeBreakpoints:function(uiSourceCode) {var breakpointLocations=WebInspector.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);for(var i=0;i<breakpointLocations.length;++i) breakpointLocations[i].breakpoint.remove();return breakpointLocations;},_restoreBreakpoints:function(uiSourceCode,breakpointLocations) {for(var i=0;i<breakpointLocations.length;++i){var uiLocation=breakpointLocations[i].uiLocation;var breakpoint=breakpointLocations[i].breakpoint;WebInspector.breakpointManager.setBreakpoint(uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber,breakpoint.condition(),breakpoint.enabled());}},_releaseSnippetScript:function(uiSourceCode) {this._mappingForTarget.valuesArray().forEach(function(mapping){mapping._releaseSnippetScript(uiSourceCode);});},_snippetIdForSourceURL:function(sourceURL) {var snippetPrefix=WebInspector.ScriptSnippetModel.snippetSourceURLPrefix;if(!sourceURL.startsWith(snippetPrefix)) return null;var splitURL=sourceURL.substring(snippetPrefix.length).split("_");var snippetId=splitURL[0];return snippetId;},__proto__:WebInspector.Object.prototype} WebInspector.SnippetScriptMapping=function(debuggerModel,scriptSnippetModel) {this._target=debuggerModel.target();this._debuggerModel=debuggerModel;this._scriptSnippetModel=scriptSnippetModel;this._uiSourceCodeForScriptId={};this._scriptForUISourceCode=new Map();this._evaluationIndexForUISourceCode=new Map();debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._reset,this);} WebInspector.SnippetScriptMapping.prototype={_releaseSnippetScript:function(uiSourceCode) {var script=this._scriptForUISourceCode.get(uiSourceCode);if(!script) return;delete this._uiSourceCodeForScriptId[script.scriptId];this._scriptForUISourceCode.remove(uiSourceCode);this._evaluationIndexForUISourceCode.remove(uiSourceCode);},_setEvaluationIndex:function(evaluationIndex,uiSourceCode) {this._evaluationIndexForUISourceCode.set(uiSourceCode,evaluationIndex);},evaluationIndex:function(uiSourceCode) {return this._evaluationIndexForUISourceCode.get(uiSourceCode);},_evaluationSourceURL:function(uiSourceCode) {var evaluationSuffix="_"+this._evaluationIndexForUISourceCode.get(uiSourceCode);var snippetId=this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);return WebInspector.ScriptSnippetModel.snippetSourceURLPrefix+snippetId+evaluationSuffix;},_reset:function() {this._uiSourceCodeForScriptId={};this._scriptForUISourceCode.clear();this._evaluationIndexForUISourceCode.clear();},rawLocationToUILocation:function(rawLocation) {var debuggerModelLocation=(rawLocation);var uiSourceCode=this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];if(!uiSourceCode) return null;return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber,debuggerModelLocation.columnNumber||0);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber) {var script=this._scriptForUISourceCode.get(uiSourceCode);if(!script) return null;return this._debuggerModel.createRawLocation(script,lineNumber,columnNumber);},_addScript:function(script,uiSourceCode) {console.assert(!this._scriptForUISourceCode.get(uiSourceCode));WebInspector.debuggerWorkspaceBinding.setSourceMapping(this._target,uiSourceCode,this);this._uiSourceCodeForScriptId[script.scriptId]=uiSourceCode;this._scriptForUISourceCode.set(uiSourceCode,script);WebInspector.debuggerWorkspaceBinding.pushSourceMapping(script,this);},_restoreBreakpoints:function(uiSourceCode,breakpointLocations) {var script=this._scriptForUISourceCode.get(uiSourceCode);if(!script) return;var rawLocation=(this._debuggerModel.createRawLocation(script,0,0));var scriptUISourceCode=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation).uiSourceCode;if(scriptUISourceCode) this._scriptSnippetModel._restoreBreakpoints(scriptUISourceCode,breakpointLocations);},isIdentity:function() {return false;},uiLineHasMapping:function(uiSourceCode,lineNumber) {return true;}} WebInspector.SnippetContentProvider=function(snippet) {this._snippet=snippet;} WebInspector.SnippetContentProvider.prototype={contentURL:function() {return"";},contentType:function() {return WebInspector.resourceTypes.Script;},requestContent:function() {return Promise.resolve((this._snippet.content));},searchInContent:function(query,caseSensitive,isRegex,callback) {function performSearch() {callback(WebInspector.ContentProvider.performSearchInContent(this._snippet.content,query,caseSensitive,isRegex));} window.setTimeout(performSearch.bind(this),0);}} WebInspector.SnippetsProject=function(workspace,model) {WebInspector.ContentProviderBasedProject.call(this,workspace,"snippets:",WebInspector.projectTypes.Snippets,"");this._model=model;} WebInspector.SnippetsProject.prototype={addSnippet:function(name,contentProvider) {return this.addContentProvider(name,contentProvider);},canSetFileContent:function() {return true;},setFileContent:function(uiSourceCode,newContent,callback) {this._model._setScriptSnippetContent(uiSourceCode.url(),newContent);callback("");},canRename:function() {return true;},performRename:function(url,newName,callback) {this._model.renameScriptSnippet(url,newName,callback);},createFile:function(url,name,content,callback) {callback(this._model.createScriptSnippet(content));},deleteFile:function(url) {this._model.deleteScriptSnippet(url);},__proto__:WebInspector.ContentProviderBasedProject.prototype} WebInspector.scriptSnippetModel=new WebInspector.ScriptSnippetModel(WebInspector.workspace);; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 | 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | (function(mod){Eif(typeof exports=="object"&&typeof module=="object")
module.exports=mod();else if(typeof define=="function"&&define.amd)
return define([],mod);else
this.CodeMirror=mod();})(function(){"use strict";var gecko=/gecko\/\d/i.test(navigator.userAgent);var ie_upto10=/MSIE \d/.test(navigator.userAgent);var ie_11up=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);var ie=ie_upto10||ie_11up;var ie_version=ie&&(ie_upto10?document.documentMode||6:ie_11up[1]);var webkit=/WebKit\//.test(navigator.userAgent);var qtwebkit=webkit&&/Qt\/\d+\.\d+/.test(navigator.userAgent);var chrome=/Chrome\//.test(navigator.userAgent);var presto=/Opera\//.test(navigator.userAgent);var safari=/Apple Computer/.test(navigator.vendor);var khtml=/KHTML\//.test(navigator.userAgent);var mac_geMountainLion=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);var phantom=/PhantomJS/.test(navigator.userAgent);var ios=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent);var mobile=ios||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);var mac=ios||/Mac/.test(navigator.platform);var windows=/win/i.test(navigator.platform);var presto_version=presto&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);if(presto_version)presto_version=Number(presto_version[1]);if(presto_version&&presto_version>=15){presto=false;webkit=true;}
var flipCtrlCmd=mac&&(qtwebkit||presto&&(presto_version==null||presto_version<12.11));var captureRightClick=gecko||(ie&&ie_version>=9);var sawReadOnlySpans=false,sawCollapsedSpans=false;function CodeMirror(place,options){if(!(this instanceof CodeMirror))return new CodeMirror(place,options);this.options=options=options?copyObj(options):{};copyObj(defaults,options,false);setGuttersForLineNumbers(options);var doc=options.value;if(typeof doc=="string")doc=new Doc(doc,options.mode);this.doc=doc;var display=this.display=new Display(place,doc);display.wrapper.CodeMirror=this;updateGutters(this);themeChanged(this);if(options.lineWrapping)
this.display.wrapper.className+=" CodeMirror-wrap";if(options.autofocus&&!mobile)focusInput(this);initScrollbars(this);this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:false,focused:false,suppressEdits:false,pasteIncoming:false,cutIncoming:false,draggingText:false,highlight:new Delayed(),keySeq:null};if(ie&&ie_version<11)setTimeout(bind(resetInput,this,true),20);registerEventHandlers(this);ensureGlobalHandlers();startOperation(this);this.curOp.forceUpdate=true;attachDoc(this,doc);if((options.autofocus&&!mobile)||activeElt()==display.input)
setTimeout(bind(onFocus,this),20);else
onBlur(this);for(var opt in optionHandlers)if(optionHandlers.hasOwnProperty(opt))
optionHandlers[opt](this,options[opt],Init);maybeUpdateLineNumberWidth(this);for(var i=0;i<initHooks.length;++i)initHooks[i](this);endOperation(this);if(webkit&&options.lineWrapping&&getComputedStyle(display.lineDiv).textRendering=="optimizelegibility")
display.lineDiv.style.textRendering="auto";}
function Display(place,doc){var d=this;var input=d.input=elt("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none");if(webkit)input.style.width="1000px";else input.setAttribute("wrap","off");if(ios)input.style.border="1px solid black";input.setAttribute("autocorrect","off");input.setAttribute("autocapitalize","off");input.setAttribute("spellcheck","false");d.inputDiv=elt("div",[input],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");d.scrollbarFiller=elt("div",null,"CodeMirror-scrollbar-filler");d.scrollbarFiller.setAttribute("not-content","true");d.gutterFiller=elt("div",null,"CodeMirror-gutter-filler");d.gutterFiller.setAttribute("not-content","true");d.lineDiv=elt("div",null,"CodeMirror-code");d.selectionDiv=elt("div",null,null,"position: relative; z-index: 1");d.cursorDiv=elt("div",null,"CodeMirror-cursors");d.measure=elt("div",null,"CodeMirror-measure");d.lineMeasure=elt("div",null,"CodeMirror-measure");d.lineSpace=elt("div",[d.measure,d.lineMeasure,d.selectionDiv,d.cursorDiv,d.lineDiv],null,"position: relative; outline: none");d.mover=elt("div",[elt("div",[d.lineSpace],"CodeMirror-lines")],null,"position: relative");d.sizer=elt("div",[d.mover],"CodeMirror-sizer");d.sizerWidth=null;d.heightForcer=elt("div",null,null,"position: absolute; height: "+scrollerGap+"px; width: 1px;");d.gutters=elt("div",null,"CodeMirror-gutters");d.lineGutter=null;d.scroller=elt("div",[d.sizer,d.heightForcer,d.gutters],"CodeMirror-scroll");d.scroller.setAttribute("tabIndex","-1");d.wrapper=elt("div",[d.inputDiv,d.scrollbarFiller,d.gutterFiller,d.scroller],"CodeMirror");if(ie&&ie_version<8){d.gutters.style.zIndex=-1;d.scroller.style.paddingRight=0;}
if(ios)input.style.width="0px";if(!webkit)d.scroller.draggable=true;if(khtml){d.inputDiv.style.height="1px";d.inputDiv.style.position="absolute";}
if(place){if(place.appendChild)place.appendChild(d.wrapper);else place(d.wrapper);}
d.viewFrom=d.viewTo=doc.first;d.reportedViewFrom=d.reportedViewTo=doc.first;d.view=[];d.renderedView=null;d.externalMeasured=null;d.viewOffset=0;d.lastWrapHeight=d.lastWrapWidth=0;d.updateLineNumbers=null;d.nativeBarWidth=d.barHeight=d.barWidth=0;d.scrollbarsClipped=false;d.lineNumWidth=d.lineNumInnerWidth=d.lineNumChars=null;d.prevInput="";d.alignWidgets=false;d.pollingFast=false;d.poll=new Delayed();d.cachedCharWidth=d.cachedTextHeight=d.cachedPaddingH=null;d.inaccurateSelection=false;d.maxLine=null;d.maxLineLength=0;d.maxLineChanged=false;d.wheelDX=d.wheelDY=d.wheelStartX=d.wheelStartY=null;d.shift=false;d.selForContextMenu=null;}
function loadMode(cm){cm.doc.mode=CodeMirror.getMode(cm.options,cm.doc.modeOption);resetModeState(cm);}
function resetModeState(cm){cm.doc.iter(function(line){if(line.stateAfter)line.stateAfter=null;if(line.styles)line.styles=null;});cm.doc.frontier=cm.doc.first;startWorker(cm,100);cm.state.modeGen++;if(cm.curOp)regChange(cm);}
function wrappingChanged(cm){if(cm.options.lineWrapping){addClass(cm.display.wrapper,"CodeMirror-wrap");cm.display.sizer.style.minWidth="";cm.display.sizerWidth=null;}else{rmClass(cm.display.wrapper,"CodeMirror-wrap");findMaxLine(cm);}
estimateLineHeights(cm);regChange(cm);clearCaches(cm);setTimeout(function(){updateScrollbars(cm);},100);}
function estimateHeight(cm){var th=textHeight(cm.display),wrapping=cm.options.lineWrapping;var perLine=wrapping&&Math.max(5,cm.display.scroller.clientWidth/charWidth(cm.display)-3);return function(line){if(lineIsHidden(cm.doc,line))return 0;var widgetsHeight=0;if(line.widgets)for(var i=0;i<line.widgets.length;i++){if(line.widgets[i].height)widgetsHeight+=line.widgets[i].height;}
if(wrapping)
return widgetsHeight+(Math.ceil(line.text.length/perLine)||1)*th;else
return widgetsHeight+th;};}
function estimateLineHeights(cm){var doc=cm.doc,est=estimateHeight(cm);doc.iter(function(line){var estHeight=est(line);if(estHeight!=line.height)updateLineHeight(line,estHeight);});}
function themeChanged(cm){cm.display.wrapper.className=cm.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+
cm.options.theme.replace(/(^|\s)\s*/g," cm-s-");clearCaches(cm);}
function guttersChanged(cm){updateGutters(cm);regChange(cm);setTimeout(function(){alignHorizontally(cm);},20);}
function updateGutters(cm){var gutters=cm.display.gutters,specs=cm.options.gutters;removeChildren(gutters);for(var i=0;i<specs.length;++i){var gutterClass=specs[i];var gElt=gutters.appendChild(elt("div",null,"CodeMirror-gutter "+gutterClass));if(gutterClass=="CodeMirror-linenumbers"){cm.display.lineGutter=gElt;gElt.style.width=(cm.display.lineNumWidth||1)+"px";}}
gutters.style.display=i?"":"none";updateGutterSpace(cm);}
function updateGutterSpace(cm){var width=cm.display.gutters.offsetWidth;cm.display.sizer.style.marginLeft=width+"px";}
function lineLength(line){if(line.height==0)return 0;var len=line.text.length,merged,cur=line;while(merged=collapsedSpanAtStart(cur)){var found=merged.find(0,true);cur=found.from.line;len+=found.from.ch-found.to.ch;}
cur=line;while(merged=collapsedSpanAtEnd(cur)){var found=merged.find(0,true);len-=cur.text.length-found.from.ch;cur=found.to.line;len+=cur.text.length-found.to.ch;}
return len;}
function findMaxLine(cm){var d=cm.display,doc=cm.doc;d.maxLine=getLine(doc,doc.first);d.maxLineLength=lineLength(d.maxLine);d.maxLineChanged=true;doc.iter(function(line){var len=lineLength(line);if(len>d.maxLineLength){d.maxLineLength=len;d.maxLine=line;}});}
function setGuttersForLineNumbers(options){var found=indexOf(options.gutters,"CodeMirror-linenumbers");if(found==-1&&options.lineNumbers){options.gutters=options.gutters.concat(["CodeMirror-linenumbers"]);}else if(found>-1&&!options.lineNumbers){options.gutters=options.gutters.slice(0);options.gutters.splice(found,1);}}
function measureForScrollbars(cm){var d=cm.display,gutterW=d.gutters.offsetWidth;var docH=Math.round(cm.doc.height+paddingVert(cm.display));return{clientHeight:d.scroller.clientHeight,viewHeight:d.wrapper.clientHeight,scrollWidth:d.scroller.scrollWidth,clientWidth:d.scroller.clientWidth,viewWidth:d.wrapper.clientWidth,barLeft:cm.options.fixedGutter?gutterW:0,docHeight:docH,scrollHeight:docH+scrollGap(cm)+d.barHeight,nativeBarWidth:d.nativeBarWidth,gutterWidth:gutterW};}
function NativeScrollbars(place,scroll,cm){this.cm=cm;var vert=this.vert=elt("div",[elt("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar");var horiz=this.horiz=elt("div",[elt("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");place(vert);place(horiz);on(vert,"scroll",function(){if(vert.clientHeight)scroll(vert.scrollTop,"vertical");});on(horiz,"scroll",function(){if(horiz.clientWidth)scroll(horiz.scrollLeft,"horizontal");});this.checkedOverlay=false;if(ie&&ie_version<8)this.horiz.style.minHeight=this.vert.style.minWidth="18px";}
NativeScrollbars.prototype=copyObj({update:function(measure){var needsH=measure.scrollWidth>measure.clientWidth+1;var needsV=measure.scrollHeight>measure.clientHeight+1;var sWidth=measure.nativeBarWidth;if(needsV){this.vert.style.display="block";this.vert.style.bottom=needsH?sWidth+"px":"0";var totalHeight=measure.viewHeight-(needsH?sWidth:0);this.vert.firstChild.style.height=Math.max(0,measure.scrollHeight-measure.clientHeight+totalHeight)+"px";}else{this.vert.style.display="";this.vert.firstChild.style.height="0";}
if(needsH){this.horiz.style.display="block";this.horiz.style.right=needsV?sWidth+"px":"0";this.horiz.style.left=measure.barLeft+"px";var totalWidth=measure.viewWidth-measure.barLeft-(needsV?sWidth:0);this.horiz.firstChild.style.width=(measure.scrollWidth-measure.clientWidth+totalWidth)+"px";}else{this.horiz.style.display="";this.horiz.firstChild.style.width="0";}
if(!this.checkedOverlay&&measure.clientHeight>0){if(sWidth==0)this.overlayHack();this.checkedOverlay=true;}
return{right:needsV?sWidth:0,bottom:needsH?sWidth:0};},setScrollLeft:function(pos){if(this.horiz.scrollLeft!=pos)this.horiz.scrollLeft=pos;},setScrollTop:function(pos){if(this.vert.scrollTop!=pos)this.vert.scrollTop=pos;},overlayHack:function(){var w=mac&&!mac_geMountainLion?"12px":"18px";this.horiz.style.minHeight=this.vert.style.minWidth=w;var self=this;var barMouseDown=function(e){if(e_target(e)!=self.vert&&e_target(e)!=self.horiz)
operation(self.cm,onMouseDown)(e);};on(this.vert,"mousedown",barMouseDown);on(this.horiz,"mousedown",barMouseDown);},clear:function(){var parent=this.horiz.parentNode;parent.removeChild(this.horiz);parent.removeChild(this.vert);}},NativeScrollbars.prototype);function NullScrollbars(){}
NullScrollbars.prototype=copyObj({update:function(){return{bottom:0,right:0};},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},NullScrollbars.prototype);CodeMirror.scrollbarModel={"native":NativeScrollbars,"null":NullScrollbars};function initScrollbars(cm){if(cm.display.scrollbars){cm.display.scrollbars.clear();if(cm.display.scrollbars.addClass)
rmClass(cm.display.wrapper,cm.display.scrollbars.addClass);}
cm.display.scrollbars=new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node){cm.display.wrapper.insertBefore(node,cm.display.scrollbarFiller);on(node,"mousedown",function(){if(cm.state.focused)setTimeout(bind(focusInput,cm),0);});node.setAttribute("not-content","true");},function(pos,axis){if(axis=="horizontal")setScrollLeft(cm,pos);else setScrollTop(cm,pos);},cm);if(cm.display.scrollbars.addClass)
addClass(cm.display.wrapper,cm.display.scrollbars.addClass);}
function updateScrollbars(cm,measure){if(!measure)measure=measureForScrollbars(cm);var startWidth=cm.display.barWidth,startHeight=cm.display.barHeight;updateScrollbarsInner(cm,measure);for(var i=0;i<4&&startWidth!=cm.display.barWidth||startHeight!=cm.display.barHeight;i++){if(startWidth!=cm.display.barWidth&&cm.options.lineWrapping)
updateHeightsInViewport(cm);updateScrollbarsInner(cm,measureForScrollbars(cm));startWidth=cm.display.barWidth;startHeight=cm.display.barHeight;}}
function updateScrollbarsInner(cm,measure){var d=cm.display;var sizes=d.scrollbars.update(measure);d.sizer.style.paddingRight=(d.barWidth=sizes.right)+"px";d.sizer.style.paddingBottom=(d.barHeight=sizes.bottom)+"px";if(sizes.right&&sizes.bottom){d.scrollbarFiller.style.display="block";d.scrollbarFiller.style.height=sizes.bottom+"px";d.scrollbarFiller.style.width=sizes.right+"px";}else d.scrollbarFiller.style.display="";if(sizes.bottom&&cm.options.coverGutterNextToScrollbar&&cm.options.fixedGutter){d.gutterFiller.style.display="block";d.gutterFiller.style.height=sizes.bottom+"px";d.gutterFiller.style.width=measure.gutterWidth+"px";}else d.gutterFiller.style.display="";}
function visibleLines(display,doc,viewport){var top=viewport&&viewport.top!=null?Math.max(0,viewport.top):display.scroller.scrollTop;top=Math.floor(top-paddingTop(display));var bottom=viewport&&viewport.bottom!=null?viewport.bottom:top+display.wrapper.clientHeight;var from=lineAtHeight(doc,top),to=lineAtHeight(doc,bottom);if(viewport&&viewport.ensure){var ensureFrom=viewport.ensure.from.line,ensureTo=viewport.ensure.to.line;if(ensureFrom<from){from=ensureFrom;to=lineAtHeight(doc,heightAtLine(getLine(doc,ensureFrom))+display.wrapper.clientHeight);}else if(Math.min(ensureTo,doc.lastLine())>=to){from=lineAtHeight(doc,heightAtLine(getLine(doc,ensureTo))-display.wrapper.clientHeight);to=ensureTo;}}
return{from:from,to:Math.max(to,from+1)};}
function alignHorizontally(cm){var display=cm.display,view=display.view;if(!display.alignWidgets&&(!display.gutters.firstChild||!cm.options.fixedGutter))return;var comp=compensateForHScroll(display)-display.scroller.scrollLeft+cm.doc.scrollLeft;var gutterW=display.gutters.offsetWidth,left=comp+"px";for(var i=0;i<view.length;i++)if(!view[i].hidden){if(cm.options.fixedGutter&&view[i].gutter)
view[i].gutter.style.left=left;var align=view[i].alignable;if(align)for(var j=0;j<align.length;j++)
align[j].style.left=left;}
if(cm.options.fixedGutter)
display.gutters.style.left=(comp+gutterW)+"px";}
function maybeUpdateLineNumberWidth(cm){if(!cm.options.lineNumbers)return false;var doc=cm.doc,last=lineNumberFor(cm.options,doc.first+doc.size-1),display=cm.display;if(last.length!=display.lineNumChars){var test=display.measure.appendChild(elt("div",[elt("div",last)],"CodeMirror-linenumber CodeMirror-gutter-elt"));var innerW=test.firstChild.offsetWidth,padding=test.offsetWidth-innerW;display.lineGutter.style.width="";display.lineNumInnerWidth=Math.max(innerW,display.lineGutter.offsetWidth-padding);display.lineNumWidth=display.lineNumInnerWidth+padding;display.lineNumChars=display.lineNumInnerWidth?last.length:-1;display.lineGutter.style.width=display.lineNumWidth+"px";updateGutterSpace(cm);return true;}
return false;}
function lineNumberFor(options,i){return String(options.lineNumberFormatter(i+options.firstLineNumber));}
function compensateForHScroll(display){return display.scroller.getBoundingClientRect().left-display.sizer.getBoundingClientRect().left;}
function DisplayUpdate(cm,viewport,force){var display=cm.display;this.viewport=viewport;this.visible=visibleLines(display,cm.doc,viewport);this.editorIsHidden=!display.wrapper.offsetWidth;this.wrapperHeight=display.wrapper.clientHeight;this.wrapperWidth=display.wrapper.clientWidth;this.oldDisplayWidth=displayWidth(cm);this.force=force;this.dims=getDimensions(cm);}
function maybeClipScrollbars(cm){var display=cm.display;if(!display.scrollbarsClipped&&display.scroller.offsetWidth){display.nativeBarWidth=display.scroller.offsetWidth-display.scroller.clientWidth;display.heightForcer.style.height=scrollGap(cm)+"px";display.sizer.style.marginBottom=-display.nativeBarWidth+"px";display.sizer.style.borderRightWidth=scrollGap(cm)+"px";display.scrollbarsClipped=true;}}
function updateDisplayIfNeeded(cm,update){var display=cm.display,doc=cm.doc;if(update.editorIsHidden){resetView(cm);return false;}
if(!update.force&&update.visible.from>=display.viewFrom&&update.visible.to<=display.viewTo&&(display.updateLineNumbers==null||display.updateLineNumbers>=display.viewTo)&&display.renderedView==display.view&&countDirtyView(cm)==0)
return false;if(maybeUpdateLineNumberWidth(cm)){resetView(cm);update.dims=getDimensions(cm);}
var end=doc.first+doc.size;var from=Math.max(update.visible.from-cm.options.viewportMargin,doc.first);var to=Math.min(end,update.visible.to+cm.options.viewportMargin);if(display.viewFrom<from&&from-display.viewFrom<20)from=Math.max(doc.first,display.viewFrom);if(display.viewTo>to&&display.viewTo-to<20)to=Math.min(end,display.viewTo);if(sawCollapsedSpans){from=visualLineNo(cm.doc,from);to=visualLineEndNo(cm.doc,to);}
var different=from!=display.viewFrom||to!=display.viewTo||display.lastWrapHeight!=update.wrapperHeight||display.lastWrapWidth!=update.wrapperWidth;adjustView(cm,from,to);display.viewOffset=heightAtLine(getLine(cm.doc,display.viewFrom));cm.display.mover.style.top=display.viewOffset+"px";var toUpdate=countDirtyView(cm);if(!different&&toUpdate==0&&!update.force&&display.renderedView==display.view&&(display.updateLineNumbers==null||display.updateLineNumbers>=display.viewTo))
return false;var focused=activeElt();if(toUpdate>4)display.lineDiv.style.display="none";patchDisplay(cm,display.updateLineNumbers,update.dims);if(toUpdate>4)display.lineDiv.style.display="";display.renderedView=display.view;if(focused&&activeElt()!=focused&&focused.offsetHeight)focused.focus();removeChildren(display.cursorDiv);removeChildren(display.selectionDiv);display.gutters.style.height=0;if(different){display.lastWrapHeight=update.wrapperHeight;display.lastWrapWidth=update.wrapperWidth;startWorker(cm,400);}
display.updateLineNumbers=null;return true;}
function postUpdateDisplay(cm,update){var force=update.force,viewport=update.viewport;for(var first=true;;first=false){if(first&&cm.options.lineWrapping&&update.oldDisplayWidth!=displayWidth(cm)){force=true;}else{force=false;if(viewport&&viewport.top!=null)
viewport={top:Math.min(cm.doc.height+paddingVert(cm.display)-displayHeight(cm),viewport.top)};update.visible=visibleLines(cm.display,cm.doc,viewport);if(update.visible.from>=cm.display.viewFrom&&update.visible.to<=cm.display.viewTo)
break;}
if(!updateDisplayIfNeeded(cm,update))break;updateHeightsInViewport(cm);var barMeasure=measureForScrollbars(cm);updateSelection(cm);setDocumentHeight(cm,barMeasure);updateScrollbars(cm,barMeasure);}
signalLater(cm,"update",cm);if(cm.display.viewFrom!=cm.display.reportedViewFrom||cm.display.viewTo!=cm.display.reportedViewTo){signalLater(cm,"viewportChange",cm,cm.display.viewFrom,cm.display.viewTo);cm.display.reportedViewFrom=cm.display.viewFrom;cm.display.reportedViewTo=cm.display.viewTo;}}
function updateDisplaySimple(cm,viewport){var update=new DisplayUpdate(cm,viewport);if(updateDisplayIfNeeded(cm,update)){updateHeightsInViewport(cm);postUpdateDisplay(cm,update);var barMeasure=measureForScrollbars(cm);updateSelection(cm);setDocumentHeight(cm,barMeasure);updateScrollbars(cm,barMeasure);}}
function setDocumentHeight(cm,measure){cm.display.sizer.style.minHeight=measure.docHeight+"px";var total=measure.docHeight+cm.display.barHeight;cm.display.heightForcer.style.top=total+"px";cm.display.gutters.style.height=Math.max(total+scrollGap(cm),measure.clientHeight)+"px";}
function updateHeightsInViewport(cm){var display=cm.display;var prevBottom=display.lineDiv.offsetTop;for(var i=0;i<display.view.length;i++){var cur=display.view[i],height;if(cur.hidden)continue;if(ie&&ie_version<8){var bot=cur.node.offsetTop+cur.node.offsetHeight;height=bot-prevBottom;prevBottom=bot;}else{var box=cur.node.getBoundingClientRect();height=box.bottom-box.top;}
var diff=cur.line.height-height;if(height<2)height=textHeight(display);if(diff>.001||diff<-.001){updateLineHeight(cur.line,height);updateWidgetHeight(cur.line);if(cur.rest)for(var j=0;j<cur.rest.length;j++)
updateWidgetHeight(cur.rest[j]);}}}
function updateWidgetHeight(line){if(line.widgets)for(var i=0;i<line.widgets.length;++i)
line.widgets[i].height=line.widgets[i].node.offsetHeight;}
function getDimensions(cm){var d=cm.display,left={},width={};var gutterLeft=d.gutters.clientLeft;for(var n=d.gutters.firstChild,i=0;n;n=n.nextSibling,++i){left[cm.options.gutters[i]]=n.offsetLeft+n.clientLeft+gutterLeft;width[cm.options.gutters[i]]=n.clientWidth;}
return{fixedPos:compensateForHScroll(d),gutterTotalWidth:d.gutters.offsetWidth,gutterLeft:left,gutterWidth:width,wrapperWidth:d.wrapper.clientWidth};}
function patchDisplay(cm,updateNumbersFrom,dims){var display=cm.display,lineNumbers=cm.options.lineNumbers;var container=display.lineDiv,cur=container.firstChild;function rm(node){var next=node.nextSibling;if(webkit&&mac&&cm.display.currentWheelTarget==node)
node.style.display="none";else
node.parentNode.removeChild(node);return next;}
var view=display.view,lineN=display.viewFrom;for(var i=0;i<view.length;i++){var lineView=view[i];if(lineView.hidden){}else if(!lineView.node){var node=buildLineElement(cm,lineView,lineN,dims);container.insertBefore(node,cur);}else{while(cur!=lineView.node)cur=rm(cur);var updateNumber=lineNumbers&&updateNumbersFrom!=null&&updateNumbersFrom<=lineN&&lineView.lineNumber;if(lineView.changes){if(indexOf(lineView.changes,"gutter")>-1)updateNumber=false;updateLineForChanges(cm,lineView,lineN,dims);}
if(updateNumber){removeChildren(lineView.lineNumber);lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options,lineN)));}
cur=lineView.node.nextSibling;}
lineN+=lineView.size;}
while(cur)cur=rm(cur);}
function updateLineForChanges(cm,lineView,lineN,dims){for(var j=0;j<lineView.changes.length;j++){var type=lineView.changes[j];if(type=="text")updateLineText(cm,lineView);else if(type=="gutter")updateLineGutter(cm,lineView,lineN,dims);else if(type=="class")updateLineClasses(lineView);else if(type=="widget")updateLineWidgets(lineView,dims);}
lineView.changes=null;}
function ensureLineWrapped(lineView){if(lineView.node==lineView.text){lineView.node=elt("div",null,null,"position: relative");if(lineView.text.parentNode)
lineView.text.parentNode.replaceChild(lineView.node,lineView.text);lineView.node.appendChild(lineView.text);if(ie&&ie_version<8)lineView.node.style.zIndex=2;}
return lineView.node;}
function updateLineBackground(lineView){var cls=lineView.bgClass?lineView.bgClass+" "+(lineView.line.bgClass||""):lineView.line.bgClass;if(cls)cls+=" CodeMirror-linebackground";if(lineView.background){if(cls)lineView.background.className=cls;else{lineView.background.parentNode.removeChild(lineView.background);lineView.background=null;}}else if(cls){var wrap=ensureLineWrapped(lineView);lineView.background=wrap.insertBefore(elt("div",null,cls),wrap.firstChild);}}
function getLineContent(cm,lineView){var ext=cm.display.externalMeasured;if(ext&&ext.line==lineView.line){cm.display.externalMeasured=null;lineView.measure=ext.measure;return ext.built;}
return buildLineContent(cm,lineView);}
function updateLineText(cm,lineView){var cls=lineView.text.className;var built=getLineContent(cm,lineView);if(lineView.text==lineView.node)lineView.node=built.pre;lineView.text.parentNode.replaceChild(built.pre,lineView.text);lineView.text=built.pre;if(built.bgClass!=lineView.bgClass||built.textClass!=lineView.textClass){lineView.bgClass=built.bgClass;lineView.textClass=built.textClass;updateLineClasses(lineView);}else if(cls){lineView.text.className=cls;}}
function updateLineClasses(lineView){updateLineBackground(lineView);if(lineView.line.wrapClass)
ensureLineWrapped(lineView).className=lineView.line.wrapClass;else if(lineView.node!=lineView.text)
lineView.node.className="";var textClass=lineView.textClass?lineView.textClass+" "+(lineView.line.textClass||""):lineView.line.textClass;lineView.text.className=textClass||"";}
function updateLineGutter(cm,lineView,lineN,dims){if(lineView.gutter){lineView.node.removeChild(lineView.gutter);lineView.gutter=null;}
var markers=lineView.line.gutterMarkers;if(cm.options.lineNumbers||markers){var wrap=ensureLineWrapped(lineView);var gutterWrap=lineView.gutter=wrap.insertBefore(elt("div",null,"CodeMirror-gutter-wrapper","left: "+
(cm.options.fixedGutter?dims.fixedPos:-dims.gutterTotalWidth)+"px; width: "+dims.gutterTotalWidth+"px"),lineView.text);if(lineView.line.gutterClass)
gutterWrap.className+=" "+lineView.line.gutterClass;if(cm.options.lineNumbers&&(!markers||!markers["CodeMirror-linenumbers"]))
lineView.lineNumber=gutterWrap.appendChild(elt("div",lineNumberFor(cm.options,lineN),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+dims.gutterLeft["CodeMirror-linenumbers"]+"px; width: "
+cm.display.lineNumInnerWidth+"px"));if(markers)for(var k=0;k<cm.options.gutters.length;++k){var id=cm.options.gutters[k],found=markers.hasOwnProperty(id)&&markers[id];if(found)
gutterWrap.appendChild(elt("div",[found],"CodeMirror-gutter-elt","left: "+
dims.gutterLeft[id]+"px; width: "+dims.gutterWidth[id]+"px"));}}}
function updateLineWidgets(lineView,dims){if(lineView.alignable)lineView.alignable=null;for(var node=lineView.node.firstChild,next;node;node=next){var next=node.nextSibling;if(node.className=="CodeMirror-linewidget")
lineView.node.removeChild(node);}
insertLineWidgets(lineView,dims);}
function buildLineElement(cm,lineView,lineN,dims){var built=getLineContent(cm,lineView);lineView.text=lineView.node=built.pre;if(built.bgClass)lineView.bgClass=built.bgClass;if(built.textClass)lineView.textClass=built.textClass;updateLineClasses(lineView);updateLineGutter(cm,lineView,lineN,dims);insertLineWidgets(lineView,dims);return lineView.node;}
function insertLineWidgets(lineView,dims){insertLineWidgetsFor(lineView.line,lineView,dims,true);if(lineView.rest)for(var i=0;i<lineView.rest.length;i++)
insertLineWidgetsFor(lineView.rest[i],lineView,dims,false);}
function insertLineWidgetsFor(line,lineView,dims,allowAbove){if(!line.widgets)return;var wrap=ensureLineWrapped(lineView);for(var i=0,ws=line.widgets;i<ws.length;++i){var widget=ws[i],node=elt("div",[widget.node],"CodeMirror-linewidget");if(!widget.handleMouseEvents)node.setAttribute("cm-ignore-events","true");positionLineWidget(widget,node,lineView,dims);if(allowAbove&&widget.above)
wrap.insertBefore(node,lineView.gutter||lineView.text);else
wrap.appendChild(node);signalLater(widget,"redraw");}}
function positionLineWidget(widget,node,lineView,dims){if(widget.noHScroll){(lineView.alignable||(lineView.alignable=[])).push(node);var width=dims.wrapperWidth;node.style.left=dims.fixedPos+"px";if(!widget.coverGutter){width-=dims.gutterTotalWidth;node.style.paddingLeft=dims.gutterTotalWidth+"px";}
node.style.width=width+"px";}
if(widget.coverGutter){node.style.zIndex=5;node.style.position="relative";if(!widget.noHScroll)node.style.marginLeft=-dims.gutterTotalWidth+"px";}}
var Pos=CodeMirror.Pos=function(line,ch){if(!(this instanceof Pos))return new Pos(line,ch);this.line=line;this.ch=ch;};var cmp=CodeMirror.cmpPos=function(a,b){return a.line-b.line||a.ch-b.ch;};function copyPos(x){return Pos(x.line,x.ch);}
function maxPos(a,b){return cmp(a,b)<0?b:a;}
function minPos(a,b){return cmp(a,b)<0?a:b;}
function Selection(ranges,primIndex){this.ranges=ranges;this.primIndex=primIndex;}
Selection.prototype={primary:function(){return this.ranges[this.primIndex];},equals:function(other){if(other==this)return true;if(other.primIndex!=this.primIndex||other.ranges.length!=this.ranges.length)return false;for(var i=0;i<this.ranges.length;i++){var here=this.ranges[i],there=other.ranges[i];if(cmp(here.anchor,there.anchor)!=0||cmp(here.head,there.head)!=0)return false;}
return true;},deepCopy:function(){for(var out=[],i=0;i<this.ranges.length;i++)
out[i]=new Range(copyPos(this.ranges[i].anchor),copyPos(this.ranges[i].head));return new Selection(out,this.primIndex);},somethingSelected:function(){for(var i=0;i<this.ranges.length;i++)
if(!this.ranges[i].empty())return true;return false;},contains:function(pos,end){if(!end)end=pos;for(var i=0;i<this.ranges.length;i++){var range=this.ranges[i];if(cmp(end,range.from())>=0&&cmp(pos,range.to())<=0)
return i;}
return-1;}};function Range(anchor,head){this.anchor=anchor;this.head=head;}
Range.prototype={from:function(){return minPos(this.anchor,this.head);},to:function(){return maxPos(this.anchor,this.head);},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch;}};function normalizeSelection(ranges,primIndex){var prim=ranges[primIndex];ranges.sort(function(a,b){return cmp(a.from(),b.from());});primIndex=indexOf(ranges,prim);for(var i=1;i<ranges.length;i++){var cur=ranges[i],prev=ranges[i-1];if(cmp(prev.to(),cur.from())>=0){var from=minPos(prev.from(),cur.from()),to=maxPos(prev.to(),cur.to());var inv=prev.empty()?cur.from()==cur.head:prev.from()==prev.head;if(i<=primIndex)--primIndex;ranges.splice(--i,2,new Range(inv?to:from,inv?from:to));}}
return new Selection(ranges,primIndex);}
function simpleSelection(anchor,head){return new Selection([new Range(anchor,head||anchor)],0);}
function clipLine(doc,n){return Math.max(doc.first,Math.min(n,doc.first+doc.size-1));}
function clipPos(doc,pos){if(pos.line<doc.first)return Pos(doc.first,0);var last=doc.first+doc.size-1;if(pos.line>last)return Pos(last,getLine(doc,last).text.length);return clipToLen(pos,getLine(doc,pos.line).text.length);}
function clipToLen(pos,linelen){var ch=pos.ch;if(ch==null||ch>linelen)return Pos(pos.line,linelen);else if(ch<0)return Pos(pos.line,0);else return pos;}
function isLine(doc,l){return l>=doc.first&&l<doc.first+doc.size;}
function clipPosArray(doc,array){for(var out=[],i=0;i<array.length;i++)out[i]=clipPos(doc,array[i]);return out;}
function extendRange(doc,range,head,other){if(doc.cm&&doc.cm.display.shift||doc.extend){var anchor=range.anchor;if(other){var posBefore=cmp(head,anchor)<0;if(posBefore!=(cmp(other,anchor)<0)){anchor=head;head=other;}else if(posBefore!=(cmp(head,other)<0)){head=other;}}
return new Range(anchor,head);}else{return new Range(other||head,head);}}
function extendSelection(doc,head,other,options){setSelection(doc,new Selection([extendRange(doc,doc.sel.primary(),head,other)],0),options);}
function extendSelections(doc,heads,options){for(var out=[],i=0;i<doc.sel.ranges.length;i++)
out[i]=extendRange(doc,doc.sel.ranges[i],heads[i],null);var newSel=normalizeSelection(out,doc.sel.primIndex);setSelection(doc,newSel,options);}
function replaceOneSelection(doc,i,range,options){var ranges=doc.sel.ranges.slice(0);ranges[i]=range;setSelection(doc,normalizeSelection(ranges,doc.sel.primIndex),options);}
function setSimpleSelection(doc,anchor,head,options){setSelection(doc,simpleSelection(anchor,head),options);}
function filterSelectionChange(doc,sel){var obj={ranges:sel.ranges,update:function(ranges){this.ranges=[];for(var i=0;i<ranges.length;i++)
this.ranges[i]=new Range(clipPos(doc,ranges[i].anchor),clipPos(doc,ranges[i].head));}};signal(doc,"beforeSelectionChange",doc,obj);if(doc.cm)signal(doc.cm,"beforeSelectionChange",doc.cm,obj);if(obj.ranges!=sel.ranges)return normalizeSelection(obj.ranges,obj.ranges.length-1);else return sel;}
function setSelectionReplaceHistory(doc,sel,options){var done=doc.history.done,last=lst(done);if(last&&last.ranges){done[done.length-1]=sel;setSelectionNoUndo(doc,sel,options);}else{setSelection(doc,sel,options);}}
function setSelection(doc,sel,options){setSelectionNoUndo(doc,sel,options);addSelectionToHistory(doc,doc.sel,doc.cm?doc.cm.curOp.id:NaN,options);}
function setSelectionNoUndo(doc,sel,options){if(hasHandler(doc,"beforeSelectionChange")||doc.cm&&hasHandler(doc.cm,"beforeSelectionChange"))
sel=filterSelectionChange(doc,sel);var bias=options&&options.bias||(cmp(sel.primary().head,doc.sel.primary().head)<0?-1:1);setSelectionInner(doc,skipAtomicInSelection(doc,sel,bias,true));if(!(options&&options.scroll===false)&&doc.cm)
ensureCursorVisible(doc.cm);}
function setSelectionInner(doc,sel){if(sel.equals(doc.sel))return;doc.sel=sel;if(doc.cm){doc.cm.curOp.updateInput=doc.cm.curOp.selectionChanged=true;signalCursorActivity(doc.cm);}
signalLater(doc,"cursorActivity",doc);}
function reCheckSelection(doc){setSelectionInner(doc,skipAtomicInSelection(doc,doc.sel,null,false),sel_dontScroll);}
function skipAtomicInSelection(doc,sel,bias,mayClear){var out;for(var i=0;i<sel.ranges.length;i++){var range=sel.ranges[i];var newAnchor=skipAtomic(doc,range.anchor,bias,mayClear);var newHead=skipAtomic(doc,range.head,bias,mayClear);if(out||newAnchor!=range.anchor||newHead!=range.head){if(!out)out=sel.ranges.slice(0,i);out[i]=new Range(newAnchor,newHead);}}
return out?normalizeSelection(out,sel.primIndex):sel;}
function skipAtomic(doc,pos,bias,mayClear){var flipped=false,curPos=pos;var dir=bias||1;doc.cantEdit=false;search:for(;;){var line=getLine(doc,curPos.line);if(line.markedSpans){for(var i=0;i<line.markedSpans.length;++i){var sp=line.markedSpans[i],m=sp.marker;if((sp.from==null||(m.inclusiveLeft?sp.from<=curPos.ch:sp.from<curPos.ch))&&(sp.to==null||(m.inclusiveRight?sp.to>=curPos.ch:sp.to>curPos.ch))){if(mayClear){signal(m,"beforeCursorEnter");if(m.explicitlyCleared){if(!line.markedSpans)break;else{--i;continue;}}}
if(!m.atomic)continue;var newPos=m.find(dir<0?-1:1);if(cmp(newPos,curPos)==0){newPos.ch+=dir;if(newPos.ch<0){if(newPos.line>doc.first)newPos=clipPos(doc,Pos(newPos.line-1));else newPos=null;}else if(newPos.ch>line.text.length){if(newPos.line<doc.first+doc.size-1)newPos=Pos(newPos.line+1,0);else newPos=null;}
if(!newPos){if(flipped){if(!mayClear)return skipAtomic(doc,pos,bias,true);doc.cantEdit=true;return Pos(doc.first,0);}
flipped=true;newPos=pos;dir=-dir;}}
curPos=newPos;continue search;}}}
return curPos;}}
function drawSelection(cm){var display=cm.display,doc=cm.doc,result={};var curFragment=result.cursors=document.createDocumentFragment();var selFragment=result.selection=document.createDocumentFragment();for(var i=0;i<doc.sel.ranges.length;i++){var range=doc.sel.ranges[i];var collapsed=range.empty();if(collapsed||cm.options.showCursorWhenSelecting)
drawSelectionCursor(cm,range,curFragment);if(!collapsed)
drawSelectionRange(cm,range,selFragment);}
if(cm.options.moveInputWithCursor){var headPos=cursorCoords(cm,doc.sel.primary().head,"div");var wrapOff=display.wrapper.getBoundingClientRect(),lineOff=display.lineDiv.getBoundingClientRect();result.teTop=Math.max(0,Math.min(display.wrapper.clientHeight-10,headPos.top+lineOff.top-wrapOff.top));result.teLeft=Math.max(0,Math.min(display.wrapper.clientWidth-10,headPos.left+lineOff.left-wrapOff.left));}
return result;}
function showSelection(cm,drawn){removeChildrenAndAdd(cm.display.cursorDiv,drawn.cursors);removeChildrenAndAdd(cm.display.selectionDiv,drawn.selection);if(drawn.teTop!=null){cm.display.inputDiv.style.top=drawn.teTop+"px";cm.display.inputDiv.style.left=drawn.teLeft+"px";}}
function updateSelection(cm){showSelection(cm,drawSelection(cm));}
function drawSelectionCursor(cm,range,output){var pos=cursorCoords(cm,range.head,"div",null,null,!cm.options.singleCursorHeightPerLine);var cursor=output.appendChild(elt("div","\u00a0","CodeMirror-cursor"));cursor.style.left=pos.left+"px";cursor.style.top=pos.top+"px";cursor.style.height=Math.max(0,pos.bottom-pos.top)*cm.options.cursorHeight+"px";if(pos.other){var otherCursor=output.appendChild(elt("div","\u00a0","CodeMirror-cursor CodeMirror-secondarycursor"));otherCursor.style.display="";otherCursor.style.left=pos.other.left+"px";otherCursor.style.top=pos.other.top+"px";otherCursor.style.height=(pos.other.bottom-pos.other.top)*.85+"px";}}
function drawSelectionRange(cm,range,output){var display=cm.display,doc=cm.doc;var fragment=document.createDocumentFragment();var padding=paddingH(cm.display),leftSide=padding.left;var rightSide=Math.max(display.sizerWidth,displayWidth(cm)-display.sizer.offsetLeft)-padding.right;function add(left,top,width,bottom){if(top<0)top=0;top=Math.round(top);bottom=Math.round(bottom);fragment.appendChild(elt("div",null,"CodeMirror-selected","position: absolute; left: "+left+"px; top: "+top+"px; width: "+(width==null?rightSide-left:width)+"px; height: "+(bottom-top)+"px"));}
function drawForLine(line,fromArg,toArg){var lineObj=getLine(doc,line);var lineLen=lineObj.text.length;var start,end;function coords(ch,bias){return charCoords(cm,Pos(line,ch),"div",lineObj,bias);}
iterateBidiSections(getOrder(lineObj),fromArg||0,toArg==null?lineLen:toArg,function(from,to,dir){var leftPos=coords(from,"left"),rightPos,left,right;if(from==to){rightPos=leftPos;left=right=leftPos.left;}else{rightPos=coords(to-1,"right");if(dir=="rtl"){var tmp=leftPos;leftPos=rightPos;rightPos=tmp;}
left=leftPos.left;right=rightPos.right;}
if(fromArg==null&&from==0)left=leftSide;if(rightPos.top-leftPos.top>3){add(left,leftPos.top,null,leftPos.bottom);left=leftSide;if(leftPos.bottom<rightPos.top)add(left,leftPos.bottom,null,rightPos.top);}
if(toArg==null&&to==lineLen)right=rightSide;if(!start||leftPos.top<start.top||leftPos.top==start.top&&leftPos.left<start.left)
start=leftPos;if(!end||rightPos.bottom>end.bottom||rightPos.bottom==end.bottom&&rightPos.right>end.right)
end=rightPos;if(left<leftSide+1)left=leftSide;add(left,rightPos.top,right-left,rightPos.bottom);});return{start:start,end:end};}
var sFrom=range.from(),sTo=range.to();if(sFrom.line==sTo.line){drawForLine(sFrom.line,sFrom.ch,sTo.ch);}else{var fromLine=getLine(doc,sFrom.line),toLine=getLine(doc,sTo.line);var singleVLine=visualLine(fromLine)==visualLine(toLine);var leftEnd=drawForLine(sFrom.line,sFrom.ch,singleVLine?fromLine.text.length+1:null).end;var rightStart=drawForLine(sTo.line,singleVLine?0:null,sTo.ch).start;if(singleVLine){if(leftEnd.top<rightStart.top-2){add(leftEnd.right,leftEnd.top,null,leftEnd.bottom);add(leftSide,rightStart.top,rightStart.left,rightStart.bottom);}else{add(leftEnd.right,leftEnd.top,rightStart.left-leftEnd.right,leftEnd.bottom);}}
if(leftEnd.bottom<rightStart.top)
add(leftSide,leftEnd.bottom,null,rightStart.top);}
output.appendChild(fragment);}
function restartBlink(cm){if(!cm.state.focused)return;var display=cm.display;clearInterval(display.blinker);var on=true;display.cursorDiv.style.visibility="";if(cm.options.cursorBlinkRate>0)
display.blinker=setInterval(function(){display.cursorDiv.style.visibility=(on=!on)?"":"hidden";},cm.options.cursorBlinkRate);else if(cm.options.cursorBlinkRate<0)
display.cursorDiv.style.visibility="hidden";}
function startWorker(cm,time){if(cm.doc.mode.startState&&cm.doc.frontier<cm.display.viewTo)
cm.state.highlight.set(time,bind(highlightWorker,cm));}
function highlightWorker(cm){var doc=cm.doc;if(doc.frontier<doc.first)doc.frontier=doc.first;if(doc.frontier>=cm.display.viewTo)return;var end=+new Date+cm.options.workTime;var state=copyState(doc.mode,getStateBefore(cm,doc.frontier));var changedLines=[];doc.iter(doc.frontier,Math.min(doc.first+doc.size,cm.display.viewTo+500),function(line){if(doc.frontier>=cm.display.viewFrom){var oldStyles=line.styles;var highlighted=highlightLine(cm,line,state,true);line.styles=highlighted.styles;var oldCls=line.styleClasses,newCls=highlighted.classes;if(newCls)line.styleClasses=newCls;else if(oldCls)line.styleClasses=null;var ischange=!oldStyles||oldStyles.length!=line.styles.length||oldCls!=newCls&&(!oldCls||!newCls||oldCls.bgClass!=newCls.bgClass||oldCls.textClass!=newCls.textClass);for(var i=0;!ischange&&i<oldStyles.length;++i)ischange=oldStyles[i]!=line.styles[i];if(ischange)changedLines.push(doc.frontier);line.stateAfter=copyState(doc.mode,state);}else{processLine(cm,line.text,state);line.stateAfter=doc.frontier%5==0?copyState(doc.mode,state):null;}
++doc.frontier;if(+new Date>end){startWorker(cm,cm.options.workDelay);return true;}});if(changedLines.length)runInOp(cm,function(){for(var i=0;i<changedLines.length;i++)
regLineChange(cm,changedLines[i],"text");});}
function findStartLine(cm,n,precise){var minindent,minline,doc=cm.doc;var lim=precise?-1:n-(cm.doc.mode.innerMode?1000:100);for(var search=n;search>lim;--search){if(search<=doc.first)return doc.first;var line=getLine(doc,search-1);if(line.stateAfter&&(!precise||search<=doc.frontier))return search;var indented=countColumn(line.text,null,cm.options.tabSize);if(minline==null||minindent>indented){minline=search-1;minindent=indented;}}
return minline;}
function getStateBefore(cm,n,precise){var doc=cm.doc,display=cm.display;if(!doc.mode.startState)return true;var pos=findStartLine(cm,n,precise),state=pos>doc.first&&getLine(doc,pos-1).stateAfter;if(!state)state=startState(doc.mode);else state=copyState(doc.mode,state);doc.iter(pos,n,function(line){processLine(cm,line.text,state);var save=pos==n-1||pos%5==0||pos>=display.viewFrom&&pos<display.viewTo;line.stateAfter=save?copyState(doc.mode,state):null;++pos;});if(precise)doc.frontier=pos;return state;}
function paddingTop(display){return display.lineSpace.offsetTop;}
function paddingVert(display){return display.mover.offsetHeight-display.lineSpace.offsetHeight;}
function paddingH(display){if(display.cachedPaddingH)return display.cachedPaddingH;var e=removeChildrenAndAdd(display.measure,elt("pre","x"));var style=window.getComputedStyle?window.getComputedStyle(e):e.currentStyle;var data={left:parseInt(style.paddingLeft),right:parseInt(style.paddingRight)};if(!isNaN(data.left)&&!isNaN(data.right))display.cachedPaddingH=data;return data;}
function scrollGap(cm){return scrollerGap-cm.display.nativeBarWidth;}
function displayWidth(cm){return cm.display.scroller.clientWidth-scrollGap(cm)-cm.display.barWidth;}
function displayHeight(cm){return cm.display.scroller.clientHeight-scrollGap(cm)-cm.display.barHeight;}
function ensureLineHeights(cm,lineView,rect){var wrapping=cm.options.lineWrapping;var curWidth=wrapping&&displayWidth(cm);if(!lineView.measure.heights||wrapping&&lineView.measure.width!=curWidth){var heights=lineView.measure.heights=[];if(wrapping){lineView.measure.width=curWidth;var rects=lineView.text.firstChild.getClientRects();for(var i=0;i<rects.length-1;i++){var cur=rects[i],next=rects[i+1];if(Math.abs(cur.bottom-next.bottom)>2)
heights.push((cur.bottom+next.top)/2-rect.top);}}
heights.push(rect.bottom-rect.top);}}
function mapFromLineView(lineView,line,lineN){if(lineView.line==line)
return{map:lineView.measure.map,cache:lineView.measure.cache};for(var i=0;i<lineView.rest.length;i++)
if(lineView.rest[i]==line)
return{map:lineView.measure.maps[i],cache:lineView.measure.caches[i]};for(var i=0;i<lineView.rest.length;i++)
if(lineNo(lineView.rest[i])>lineN)
return{map:lineView.measure.maps[i],cache:lineView.measure.caches[i],before:true};}
function updateExternalMeasurement(cm,line){line=visualLine(line);var lineN=lineNo(line);var view=cm.display.externalMeasured=new LineView(cm.doc,line,lineN);view.lineN=lineN;var built=view.built=buildLineContent(cm,view);view.text=built.pre;removeChildrenAndAdd(cm.display.lineMeasure,built.pre);return view;}
function measureChar(cm,line,ch,bias){return measureCharPrepared(cm,prepareMeasureForLine(cm,line),ch,bias);}
function findViewForLine(cm,lineN){if(lineN>=cm.display.viewFrom&&lineN<cm.display.viewTo)
return cm.display.view[findViewIndex(cm,lineN)];var ext=cm.display.externalMeasured;if(ext&&lineN>=ext.lineN&&lineN<ext.lineN+ext.size)
return ext;}
function prepareMeasureForLine(cm,line){var lineN=lineNo(line);var view=findViewForLine(cm,lineN);if(view&&!view.text)
view=null;else if(view&&view.changes)
updateLineForChanges(cm,view,lineN,getDimensions(cm));if(!view)
view=updateExternalMeasurement(cm,line);var info=mapFromLineView(view,line,lineN);return{line:line,view:view,rect:null,map:info.map,cache:info.cache,before:info.before,hasHeights:false};}
function measureCharPrepared(cm,prepared,ch,bias,varHeight){if(prepared.before)ch=-1;var key=ch+(bias||""),found;if(prepared.cache.hasOwnProperty(key)){found=prepared.cache[key];}else{if(!prepared.rect)
prepared.rect=prepared.view.text.getBoundingClientRect();if(!prepared.hasHeights){ensureLineHeights(cm,prepared.view,prepared.rect);prepared.hasHeights=true;}
found=measureCharInner(cm,prepared,ch,bias);if(!found.bogus)prepared.cache[key]=found;}
return{left:found.left,right:found.right,top:varHeight?found.rtop:found.top,bottom:varHeight?found.rbottom:found.bottom};}
var nullRect={left:0,right:0,top:0,bottom:0};function measureCharInner(cm,prepared,ch,bias){var map=prepared.map;var node,start,end,collapse;for(var i=0;i<map.length;i+=3){var mStart=map[i],mEnd=map[i+1];if(ch<mStart){start=0;end=1;collapse="left";}else if(ch<mEnd){start=ch-mStart;end=start+1;}else if(i==map.length-3||ch==mEnd&&map[i+3]>ch){end=mEnd-mStart;start=end-1;if(ch>=mEnd)collapse="right";}
if(start!=null){node=map[i+2];if(mStart==mEnd&&bias==(node.insertLeft?"left":"right"))
collapse=bias;if(bias=="left"&&start==0)
while(i&&map[i-2]==map[i-3]&&map[i-1].insertLeft){node=map[(i-=3)+2];collapse="left";}
if(bias=="right"&&start==mEnd-mStart)
while(i<map.length-3&&map[i+3]==map[i+4]&&!map[i+5].insertLeft){node=map[(i+=3)+2];collapse="right";}
break;}}
var rect;if(node.nodeType==3){for(var i=0;i<4;i++){while(start&&isExtendingChar(prepared.line.text.charAt(mStart+start)))--start;while(mStart+end<mEnd&&isExtendingChar(prepared.line.text.charAt(mStart+end)))++end;if(ie&&ie_version<9&&start==0&&end==mEnd-mStart){rect=node.parentNode.getBoundingClientRect();}else if(ie&&cm.options.lineWrapping){var rects=range(node,start,end).getClientRects();if(rects.length)
rect=rects[bias=="right"?rects.length-1:0];else
rect=nullRect;}else{rect=range(node,start,end).getBoundingClientRect()||nullRect;}
if(rect.left||rect.right||start==0)break;end=start;start=start-1;collapse="right";}
if(ie&&ie_version<11)rect=maybeUpdateRectForZooming(cm.display.measure,rect);}else{if(start>0)collapse=bias="right";var rects;if(cm.options.lineWrapping&&(rects=node.getClientRects()).length>1)
rect=rects[bias=="right"?rects.length-1:0];else
rect=node.getBoundingClientRect();}
if(ie&&ie_version<9&&!start&&(!rect||!rect.left&&!rect.right)){var rSpan=node.parentNode.getClientRects()[0];if(rSpan)
rect={left:rSpan.left,right:rSpan.left+charWidth(cm.display),top:rSpan.top,bottom:rSpan.bottom};else
rect=nullRect;}
var rtop=rect.top-prepared.rect.top,rbot=rect.bottom-prepared.rect.top;var mid=(rtop+rbot)/2;var heights=prepared.view.measure.heights;for(var i=0;i<heights.length-1;i++)
if(mid<heights[i])break;var top=i?heights[i-1]:0,bot=heights[i];var result={left:(collapse=="right"?rect.right:rect.left)-prepared.rect.left,right:(collapse=="left"?rect.left:rect.right)-prepared.rect.left,top:top,bottom:bot};if(!rect.left&&!rect.right)result.bogus=true;if(!cm.options.singleCursorHeightPerLine){result.rtop=rtop;result.rbottom=rbot;}
return result;}
function maybeUpdateRectForZooming(measure,rect){if(!window.screen||screen.logicalXDPI==null||screen.logicalXDPI==screen.deviceXDPI||!hasBadZoomedRects(measure))
return rect;var scaleX=screen.logicalXDPI/screen.deviceXDPI;var scaleY=screen.logicalYDPI/screen.deviceYDPI;return{left:rect.left*scaleX,right:rect.right*scaleX,top:rect.top*scaleY,bottom:rect.bottom*scaleY};}
function clearLineMeasurementCacheFor(lineView){if(lineView.measure){lineView.measure.cache={};lineView.measure.heights=null;if(lineView.rest)for(var i=0;i<lineView.rest.length;i++)
lineView.measure.caches[i]={};}}
function clearLineMeasurementCache(cm){cm.display.externalMeasure=null;removeChildren(cm.display.lineMeasure);for(var i=0;i<cm.display.view.length;i++)
clearLineMeasurementCacheFor(cm.display.view[i]);}
function clearCaches(cm){clearLineMeasurementCache(cm);cm.display.cachedCharWidth=cm.display.cachedTextHeight=cm.display.cachedPaddingH=null;if(!cm.options.lineWrapping)cm.display.maxLineChanged=true;cm.display.lineNumChars=null;}
function pageScrollX(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft;}
function pageScrollY(){return window.pageYOffset||(document.documentElement||document.body).scrollTop;}
function intoCoordSystem(cm,lineObj,rect,context){if(lineObj.widgets)for(var i=0;i<lineObj.widgets.length;++i)if(lineObj.widgets[i].above){var size=widgetHeight(lineObj.widgets[i]);rect.top+=size;rect.bottom+=size;}
if(context=="line")return rect;if(!context)context="local";var yOff=heightAtLine(lineObj);if(context=="local")yOff+=paddingTop(cm.display);else yOff-=cm.display.viewOffset;if(context=="page"||context=="window"){var lOff=cm.display.lineSpace.getBoundingClientRect();yOff+=lOff.top+(context=="window"?0:pageScrollY());var xOff=lOff.left+(context=="window"?0:pageScrollX());rect.left+=xOff;rect.right+=xOff;}
rect.top+=yOff;rect.bottom+=yOff;return rect;}
function fromCoordSystem(cm,coords,context){if(context=="div")return coords;var left=coords.left,top=coords.top;if(context=="page"){left-=pageScrollX();top-=pageScrollY();}else if(context=="local"||!context){var localBox=cm.display.sizer.getBoundingClientRect();left+=localBox.left;top+=localBox.top;}
var lineSpaceBox=cm.display.lineSpace.getBoundingClientRect();return{left:left-lineSpaceBox.left,top:top-lineSpaceBox.top};}
function charCoords(cm,pos,context,lineObj,bias){if(!lineObj)lineObj=getLine(cm.doc,pos.line);return intoCoordSystem(cm,lineObj,measureChar(cm,lineObj,pos.ch,bias),context);}
function cursorCoords(cm,pos,context,lineObj,preparedMeasure,varHeight){lineObj=lineObj||getLine(cm.doc,pos.line);if(!preparedMeasure)preparedMeasure=prepareMeasureForLine(cm,lineObj);function get(ch,right){var m=measureCharPrepared(cm,preparedMeasure,ch,right?"right":"left",varHeight);if(right)m.left=m.right;else m.right=m.left;return intoCoordSystem(cm,lineObj,m,context);}
function getBidi(ch,partPos){var part=order[partPos],right=part.level%2;if(ch==bidiLeft(part)&&partPos&&part.level<order[partPos-1].level){part=order[--partPos];ch=bidiRight(part)-(part.level%2?0:1);right=true;}else if(ch==bidiRight(part)&&partPos<order.length-1&&part.level<order[partPos+1].level){part=order[++partPos];ch=bidiLeft(part)-part.level%2;right=false;}
if(right&&ch==part.to&&ch>part.from)return get(ch-1);return get(ch,right);}
var order=getOrder(lineObj),ch=pos.ch;if(!order)return get(ch);var partPos=getBidiPartAt(order,ch);var val=getBidi(ch,partPos);if(bidiOther!=null)val.other=getBidi(ch,bidiOther);return val;}
function estimateCoords(cm,pos){var left=0,pos=clipPos(cm.doc,pos);if(!cm.options.lineWrapping)left=charWidth(cm.display)*pos.ch;var lineObj=getLine(cm.doc,pos.line);var top=heightAtLine(lineObj)+paddingTop(cm.display);return{left:left,right:left,top:top,bottom:top+lineObj.height};}
function PosWithInfo(line,ch,outside,xRel){var pos=Pos(line,ch);pos.xRel=xRel;if(outside)pos.outside=true;return pos;}
function coordsChar(cm,x,y){var doc=cm.doc;y+=cm.display.viewOffset;if(y<0)return PosWithInfo(doc.first,0,true,-1);var lineN=lineAtHeight(doc,y),last=doc.first+doc.size-1;if(lineN>last)
return PosWithInfo(doc.first+doc.size-1,getLine(doc,last).text.length,true,1);if(x<0)x=0;var lineObj=getLine(doc,lineN);for(;;){var found=coordsCharInner(cm,lineObj,lineN,x,y);var merged=collapsedSpanAtEnd(lineObj);var mergedPos=merged&&merged.find(0,true);if(merged&&(found.ch>mergedPos.from.ch||found.ch==mergedPos.from.ch&&found.xRel>0))
lineN=lineNo(lineObj=mergedPos.to.line);else
return found;}}
function coordsCharInner(cm,lineObj,lineNo,x,y){var innerOff=y-heightAtLine(lineObj);var wrongLine=false,adjust=2*cm.display.wrapper.clientWidth;var preparedMeasure=prepareMeasureForLine(cm,lineObj);function getX(ch){var sp=cursorCoords(cm,Pos(lineNo,ch),"line",lineObj,preparedMeasure);wrongLine=true;if(innerOff>sp.bottom)return sp.left-adjust;else if(innerOff<sp.top)return sp.left+adjust;else wrongLine=false;return sp.left;}
var bidi=getOrder(lineObj),dist=lineObj.text.length;var from=lineLeft(lineObj),to=lineRight(lineObj);var fromX=getX(from),fromOutside=wrongLine,toX=getX(to),toOutside=wrongLine;if(x>toX)return PosWithInfo(lineNo,to,toOutside,1);for(;;){if(bidi?to==from||to==moveVisually(lineObj,from,1):to-from<=1){var ch=x<fromX||x-fromX<=toX-x?from:to;var xDiff=x-(ch==from?fromX:toX);while(isExtendingChar(lineObj.text.charAt(ch)))++ch;var pos=PosWithInfo(lineNo,ch,ch==from?fromOutside:toOutside,xDiff<-1?-1:xDiff>1?1:0);return pos;}
var step=Math.ceil(dist/2),middle=from+step;if(bidi){middle=from;for(var i=0;i<step;++i)middle=moveVisually(lineObj,middle,1);}
var middleX=getX(middle);if(middleX>x){to=middle;toX=middleX;if(toOutside=wrongLine)toX+=1000;dist=step;}
else{from=middle;fromX=middleX;fromOutside=wrongLine;dist-=step;}}}
var measureText;function textHeight(display){if(display.cachedTextHeight!=null)return display.cachedTextHeight;if(measureText==null){measureText=elt("pre");for(var i=0;i<49;++i){measureText.appendChild(document.createTextNode("x"));measureText.appendChild(elt("br"));}
measureText.appendChild(document.createTextNode("x"));}
removeChildrenAndAdd(display.measure,measureText);var height=measureText.offsetHeight/50;if(height>3)display.cachedTextHeight=height;removeChildren(display.measure);return height||1;}
function charWidth(display){if(display.cachedCharWidth!=null)return display.cachedCharWidth;var anchor=elt("span","xxxxxxxxxx");var pre=elt("pre",[anchor]);removeChildrenAndAdd(display.measure,pre);var rect=anchor.getBoundingClientRect(),width=(rect.right-rect.left)/10;if(width>2)display.cachedCharWidth=width;return width||10;}
var operationGroup=null;var nextOpId=0;function startOperation(cm){cm.curOp={cm:cm,viewChanged:false,startHeight:cm.doc.height,forceUpdate:false,updateInput:null,typing:false,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:false,updateMaxLine:false,scrollLeft:null,scrollTop:null,scrollToPos:null,id:++nextOpId};if(operationGroup){operationGroup.ops.push(cm.curOp);}else{cm.curOp.ownsGroup=operationGroup={ops:[cm.curOp],delayedCallbacks:[]};}}
function fireCallbacksForOps(group){var callbacks=group.delayedCallbacks,i=0;do{for(;i<callbacks.length;i++)
callbacks[i]();for(var j=0;j<group.ops.length;j++){var op=group.ops[j];if(op.cursorActivityHandlers)
while(op.cursorActivityCalled<op.cursorActivityHandlers.length)
op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);}}while(i<callbacks.length);}
function endOperation(cm){var op=cm.curOp,group=op.ownsGroup;if(!group)return;try{fireCallbacksForOps(group);}
finally{operationGroup=null;for(var i=0;i<group.ops.length;i++)
group.ops[i].cm.curOp=null;endOperations(group);}}
function endOperations(group){var ops=group.ops;for(var i=0;i<ops.length;i++)
endOperation_R1(ops[i]);for(var i=0;i<ops.length;i++)
endOperation_W1(ops[i]);for(var i=0;i<ops.length;i++)
endOperation_R2(ops[i]);for(var i=0;i<ops.length;i++)
endOperation_W2(ops[i]);for(var i=0;i<ops.length;i++)
endOperation_finish(ops[i]);}
function endOperation_R1(op){var cm=op.cm,display=cm.display;maybeClipScrollbars(cm);if(op.updateMaxLine)findMaxLine(cm);op.mustUpdate=op.viewChanged||op.forceUpdate||op.scrollTop!=null||op.scrollToPos&&(op.scrollToPos.from.line<display.viewFrom||op.scrollToPos.to.line>=display.viewTo)||display.maxLineChanged&&cm.options.lineWrapping;op.update=op.mustUpdate&&new DisplayUpdate(cm,op.mustUpdate&&{top:op.scrollTop,ensure:op.scrollToPos},op.forceUpdate);}
function endOperation_W1(op){op.updatedDisplay=op.mustUpdate&&updateDisplayIfNeeded(op.cm,op.update);}
function endOperation_R2(op){var cm=op.cm,display=cm.display;if(op.updatedDisplay)updateHeightsInViewport(cm);op.barMeasure=measureForScrollbars(cm);if(display.maxLineChanged&&!cm.options.lineWrapping){op.adjustWidthTo=measureChar(cm,display.maxLine,display.maxLine.text.length).left+3;cm.display.sizerWidth=op.adjustWidthTo;op.barMeasure.scrollWidth=Math.max(display.scroller.clientWidth,display.sizer.offsetLeft+op.adjustWidthTo+scrollGap(cm)+cm.display.barWidth);op.maxScrollLeft=Math.max(0,display.sizer.offsetLeft+op.adjustWidthTo-displayWidth(cm));}
if(op.updatedDisplay||op.selectionChanged)
op.newSelectionNodes=drawSelection(cm);}
function endOperation_W2(op){var cm=op.cm;if(op.adjustWidthTo!=null){cm.display.sizer.style.minWidth=op.adjustWidthTo+"px";if(op.maxScrollLeft<cm.doc.scrollLeft)
setScrollLeft(cm,Math.min(cm.display.scroller.scrollLeft,op.maxScrollLeft),true);cm.display.maxLineChanged=false;}
if(op.newSelectionNodes)
showSelection(cm,op.newSelectionNodes);if(op.updatedDisplay)
setDocumentHeight(cm,op.barMeasure);if(op.updatedDisplay||op.startHeight!=cm.doc.height)
updateScrollbars(cm,op.barMeasure);if(op.selectionChanged)restartBlink(cm);if(cm.state.focused&&op.updateInput)
resetInput(cm,op.typing);}
function endOperation_finish(op){var cm=op.cm,display=cm.display,doc=cm.doc;if(op.updatedDisplay)postUpdateDisplay(cm,op.update);if(display.wheelStartX!=null&&(op.scrollTop!=null||op.scrollLeft!=null||op.scrollToPos))
display.wheelStartX=display.wheelStartY=null;if(op.scrollTop!=null&&(display.scroller.scrollTop!=op.scrollTop||op.forceScroll)){doc.scrollTop=Math.max(0,Math.min(display.scroller.scrollHeight-display.scroller.clientHeight,op.scrollTop));display.scrollbars.setScrollTop(doc.scrollTop);display.scroller.scrollTop=doc.scrollTop;}
if(op.scrollLeft!=null&&(display.scroller.scrollLeft!=op.scrollLeft||op.forceScroll)){doc.scrollLeft=Math.max(0,Math.min(display.scroller.scrollWidth-displayWidth(cm),op.scrollLeft));display.scrollbars.setScrollLeft(doc.scrollLeft);display.scroller.scrollLeft=doc.scrollLeft;alignHorizontally(cm);}
if(op.scrollToPos){var coords=scrollPosIntoView(cm,clipPos(doc,op.scrollToPos.from),clipPos(doc,op.scrollToPos.to),op.scrollToPos.margin);if(op.scrollToPos.isCursor&&cm.state.focused)maybeScrollWindow(cm,coords);}
var hidden=op.maybeHiddenMarkers,unhidden=op.maybeUnhiddenMarkers;if(hidden)for(var i=0;i<hidden.length;++i)
if(!hidden[i].lines.length)signal(hidden[i],"hide");if(unhidden)for(var i=0;i<unhidden.length;++i)
if(unhidden[i].lines.length)signal(unhidden[i],"unhide");if(display.wrapper.offsetHeight)
doc.scrollTop=cm.display.scroller.scrollTop;if(op.changeObjs)
signal(cm,"changes",cm,op.changeObjs);}
function runInOp(cm,f){if(cm.curOp)return f();startOperation(cm);try{return f();}
finally{endOperation(cm);}}
function operation(cm,f){return function(){if(cm.curOp)return f.apply(cm,arguments);startOperation(cm);try{return f.apply(cm,arguments);}
finally{endOperation(cm);}};}
function methodOp(f){return function(){if(this.curOp)return f.apply(this,arguments);startOperation(this);try{return f.apply(this,arguments);}
finally{endOperation(this);}};}
function docMethodOp(f){return function(){var cm=this.cm;if(!cm||cm.curOp)return f.apply(this,arguments);startOperation(cm);try{return f.apply(this,arguments);}
finally{endOperation(cm);}};}
function LineView(doc,line,lineN){this.line=line;this.rest=visualLineContinued(line);this.size=this.rest?lineNo(lst(this.rest))-lineN+1:1;this.node=this.text=null;this.hidden=lineIsHidden(doc,line);}
function buildViewArray(cm,from,to){var array=[],nextPos;for(var pos=from;pos<to;pos=nextPos){var view=new LineView(cm.doc,getLine(cm.doc,pos),pos);nextPos=pos+view.size;array.push(view);}
return array;}
function regChange(cm,from,to,lendiff){if(from==null)from=cm.doc.first;if(to==null)to=cm.doc.first+cm.doc.size;if(!lendiff)lendiff=0;var display=cm.display;if(lendiff&&to<display.viewTo&&(display.updateLineNumbers==null||display.updateLineNumbers>from))
display.updateLineNumbers=from;cm.curOp.viewChanged=true;if(from>=display.viewTo){if(sawCollapsedSpans&&visualLineNo(cm.doc,from)<display.viewTo)
resetView(cm);}else if(to<=display.viewFrom){if(sawCollapsedSpans&&visualLineEndNo(cm.doc,to+lendiff)>display.viewFrom){resetView(cm);}else{display.viewFrom+=lendiff;display.viewTo+=lendiff;}}else if(from<=display.viewFrom&&to>=display.viewTo){resetView(cm);}else if(from<=display.viewFrom){var cut=viewCuttingPoint(cm,to,to+lendiff,1);if(cut){display.view=display.view.slice(cut.index);display.viewFrom=cut.lineN;display.viewTo+=lendiff;}else{resetView(cm);}}else if(to>=display.viewTo){var cut=viewCuttingPoint(cm,from,from,-1);if(cut){display.view=display.view.slice(0,cut.index);display.viewTo=cut.lineN;}else{resetView(cm);}}else{var cutTop=viewCuttingPoint(cm,from,from,-1);var cutBot=viewCuttingPoint(cm,to,to+lendiff,1);if(cutTop&&cutBot){display.view=display.view.slice(0,cutTop.index).concat(buildViewArray(cm,cutTop.lineN,cutBot.lineN)).concat(display.view.slice(cutBot.index));display.viewTo+=lendiff;}else{resetView(cm);}}
var ext=display.externalMeasured;if(ext){if(to<ext.lineN)
ext.lineN+=lendiff;else if(from<ext.lineN+ext.size)
display.externalMeasured=null;}}
function regLineChange(cm,line,type){cm.curOp.viewChanged=true;var display=cm.display,ext=cm.display.externalMeasured;if(ext&&line>=ext.lineN&&line<ext.lineN+ext.size)
display.externalMeasured=null;if(line<display.viewFrom||line>=display.viewTo)return;var lineView=display.view[findViewIndex(cm,line)];if(lineView.node==null)return;var arr=lineView.changes||(lineView.changes=[]);if(indexOf(arr,type)==-1)arr.push(type);}
function resetView(cm){cm.display.viewFrom=cm.display.viewTo=cm.doc.first;cm.display.view=[];cm.display.viewOffset=0;}
function findViewIndex(cm,n){if(n>=cm.display.viewTo)return null;n-=cm.display.viewFrom;if(n<0)return null;var view=cm.display.view;for(var i=0;i<view.length;i++){n-=view[i].size;if(n<0)return i;}}
function viewCuttingPoint(cm,oldN,newN,dir){var index=findViewIndex(cm,oldN),diff,view=cm.display.view;if(!sawCollapsedSpans||newN==cm.doc.first+cm.doc.size)
return{index:index,lineN:newN};for(var i=0,n=cm.display.viewFrom;i<index;i++)
n+=view[i].size;if(n!=oldN){if(dir>0){if(index==view.length-1)return null;diff=(n+view[index].size)-oldN;index++;}else{diff=n-oldN;}
oldN+=diff;newN+=diff;}
while(visualLineNo(cm.doc,newN)!=newN){if(index==(dir<0?0:view.length-1))return null;newN+=dir*view[index-(dir<0?1:0)].size;index+=dir;}
return{index:index,lineN:newN};}
function adjustView(cm,from,to){var display=cm.display,view=display.view;if(view.length==0||from>=display.viewTo||to<=display.viewFrom){display.view=buildViewArray(cm,from,to);display.viewFrom=from;}else{if(display.viewFrom>from)
display.view=buildViewArray(cm,from,display.viewFrom).concat(display.view);else if(display.viewFrom<from)
display.view=display.view.slice(findViewIndex(cm,from));display.viewFrom=from;if(display.viewTo<to)
display.view=display.view.concat(buildViewArray(cm,display.viewTo,to));else if(display.viewTo>to)
display.view=display.view.slice(0,findViewIndex(cm,to));}
display.viewTo=to;}
function countDirtyView(cm){var view=cm.display.view,dirty=0;for(var i=0;i<view.length;i++){var lineView=view[i];if(!lineView.hidden&&(!lineView.node||lineView.changes))++dirty;}
return dirty;}
function slowPoll(cm){if(cm.display.pollingFast)return;cm.display.poll.set(cm.options.pollInterval,function(){readInput(cm);if(cm.state.focused)slowPoll(cm);});}
function fastPoll(cm){var missed=false;cm.display.pollingFast=true;function p(){var changed=readInput(cm);if(!changed&&!missed){missed=true;cm.display.poll.set(60,p);}
else{cm.display.pollingFast=false;slowPoll(cm);}}
cm.display.poll.set(20,p);}
var lastCopied=null;function readInput(cm){var input=cm.display.input,prevInput=cm.display.prevInput,doc=cm.doc;if(!cm.state.focused||(hasSelection(input)&&!prevInput)||isReadOnly(cm)||cm.options.disableInput||cm.state.keySeq)
return false;if(cm.state.pasteIncoming&&cm.state.fakedLastChar){input.value=input.value.substring(0,input.value.length-1);cm.state.fakedLastChar=false;}
var text=input.value;if(text==prevInput&&!cm.somethingSelected())return false;if(ie&&ie_version>=9&&cm.display.inputHasSelection===text||mac&&/[\uf700-\uf7ff]/.test(text)){resetInput(cm);return false;}
var withOp=!cm.curOp;if(withOp)startOperation(cm);cm.display.shift=false;if(text.charCodeAt(0)==0x200b&&doc.sel==cm.display.selForContextMenu&&!prevInput)
prevInput="\u200b";var same=0,l=Math.min(prevInput.length,text.length);while(same<l&&prevInput.charCodeAt(same)==text.charCodeAt(same))++same;var inserted=text.slice(same),textLines=splitLines(inserted);var multiPaste=null;if(cm.state.pasteIncoming&&doc.sel.ranges.length>1){if(lastCopied&&lastCopied.join("\n")==inserted)
multiPaste=doc.sel.ranges.length%lastCopied.length==0&&map(lastCopied,splitLines);else if(textLines.length==doc.sel.ranges.length)
multiPaste=map(textLines,function(l){return[l];});}
for(var i=doc.sel.ranges.length-1;i>=0;i--){var range=doc.sel.ranges[i];var from=range.from(),to=range.to();if(same<prevInput.length)
from=Pos(from.line,from.ch-(prevInput.length-same));else if(cm.state.overwrite&&range.empty()&&!cm.state.pasteIncoming)
to=Pos(to.line,Math.min(getLine(doc,to.line).text.length,to.ch+lst(textLines).length));var updateInput=cm.curOp.updateInput;var changeEvent={from:from,to:to,text:multiPaste?multiPaste[i%multiPaste.length]:textLines,origin:cm.state.pasteIncoming?"paste":cm.state.cutIncoming?"cut":"+input"};makeChange(cm.doc,changeEvent);signalLater(cm,"inputRead",cm,changeEvent);if(inserted&&!cm.state.pasteIncoming&&cm.options.electricChars&&cm.options.smartIndent&&range.head.ch<100&&(!i||doc.sel.ranges[i-1].head.line!=range.head.line)){var mode=cm.getModeAt(range.head);var end=changeEnd(changeEvent);if(mode.electricChars){for(var j=0;j<mode.electricChars.length;j++)
if(inserted.indexOf(mode.electricChars.charAt(j))>-1){indentLine(cm,end.line,"smart");break;}}else if(mode.electricInput){if(mode.electricInput.test(getLine(doc,end.line).text.slice(0,end.ch)))
indentLine(cm,end.line,"smart");}}}
ensureCursorVisible(cm);cm.curOp.updateInput=updateInput;cm.curOp.typing=true;if(text.length>1000||text.indexOf("\n")>-1)input.value=cm.display.prevInput="";else cm.display.prevInput=text;if(withOp)endOperation(cm);cm.state.pasteIncoming=cm.state.cutIncoming=false;return true;}
function resetInput(cm,typing){if(cm.display.contextMenuPending)return;var minimal,selected,doc=cm.doc;if(cm.somethingSelected()){cm.display.prevInput="";var range=doc.sel.primary();minimal=hasCopyEvent&&(range.to().line-range.from().line>100||(selected=cm.getSelection()).length>1000);var content=minimal?"-":selected||cm.getSelection();cm.display.input.value=content;if(cm.state.focused)selectInput(cm.display.input);if(ie&&ie_version>=9)cm.display.inputHasSelection=content;}else if(!typing){cm.display.prevInput=cm.display.input.value="";if(ie&&ie_version>=9)cm.display.inputHasSelection=null;}
cm.display.inaccurateSelection=minimal;}
function focusInput(cm){if(cm.options.readOnly!="nocursor"&&(!mobile||activeElt()!=cm.display.input))
cm.display.input.focus();}
function ensureFocus(cm){if(!cm.state.focused){focusInput(cm);onFocus(cm);}}
function isReadOnly(cm){return cm.options.readOnly||cm.doc.cantEdit;}
function registerEventHandlers(cm){var d=cm.display;on(d.scroller,"mousedown",operation(cm,onMouseDown));if(ie&&ie_version<11)
on(d.scroller,"dblclick",operation(cm,function(e){if(signalDOMEvent(cm,e))return;var pos=posFromMouse(cm,e);if(!pos||clickInGutter(cm,e)||eventInWidget(cm.display,e))return;e_preventDefault(e);var word=cm.findWordAt(pos);extendSelection(cm.doc,word.anchor,word.head);}));else
on(d.scroller,"dblclick",function(e){signalDOMEvent(cm,e)||e_preventDefault(e);});on(d.lineSpace,"selectstart",function(e){if(!eventInWidget(d,e))e_preventDefault(e);});if(!captureRightClick)on(d.scroller,"contextmenu",function(e){onContextMenu(cm,e);});on(d.scroller,"scroll",function(){if(d.scroller.clientHeight){setScrollTop(cm,d.scroller.scrollTop);setScrollLeft(cm,d.scroller.scrollLeft,true);signal(cm,"scroll",cm);}});on(d.scroller,"mousewheel",function(e){onScrollWheel(cm,e);});on(d.scroller,"DOMMouseScroll",function(e){onScrollWheel(cm,e);});on(d.wrapper,"scroll",function(){d.wrapper.scrollTop=d.wrapper.scrollLeft=0;});on(d.input,"keyup",function(e){onKeyUp.call(cm,e);});on(d.input,"input",function(){if(ie&&ie_version>=9&&cm.display.inputHasSelection)cm.display.inputHasSelection=null;readInput(cm);});on(d.input,"keydown",operation(cm,onKeyDown));on(d.input,"keypress",operation(cm,onKeyPress));on(d.input,"focus",bind(onFocus,cm));on(d.input,"blur",bind(onBlur,cm));function drag_(e){if(!signalDOMEvent(cm,e))e_stop(e);}
if(cm.options.dragDrop){on(d.scroller,"dragstart",function(e){onDragStart(cm,e);});on(d.scroller,"dragenter",drag_);on(d.scroller,"dragover",drag_);on(d.scroller,"drop",operation(cm,onDrop));}
on(d.scroller,"paste",function(e){if(eventInWidget(d,e))return;cm.state.pasteIncoming=true;focusInput(cm);fastPoll(cm);});on(d.input,"paste",function(){if(webkit&&!cm.state.fakedLastChar&&!(new Date-cm.state.lastMiddleDown<200)){var start=d.input.selectionStart,end=d.input.selectionEnd;d.input.value+="$";d.input.selectionEnd=end;d.input.selectionStart=start;cm.state.fakedLastChar=true;}
cm.state.pasteIncoming=true;fastPoll(cm);});function prepareCopyCut(e){if(cm.somethingSelected()){lastCopied=cm.getSelections();if(d.inaccurateSelection){d.prevInput="";d.inaccurateSelection=false;d.input.value=lastCopied.join("\n");selectInput(d.input);}}else{var text=[],ranges=[];for(var i=0;i<cm.doc.sel.ranges.length;i++){var line=cm.doc.sel.ranges[i].head.line;var lineRange={anchor:Pos(line,0),head:Pos(line+1,0)};ranges.push(lineRange);text.push(cm.getRange(lineRange.anchor,lineRange.head));}
if(e.type=="cut"){cm.setSelections(ranges,null,sel_dontScroll);}else{d.prevInput="";d.input.value=text.join("\n");selectInput(d.input);}
lastCopied=text;}
if(e.type=="cut")cm.state.cutIncoming=true;}
on(d.input,"cut",prepareCopyCut);on(d.input,"copy",prepareCopyCut);if(khtml)on(d.sizer,"mouseup",function(){if(activeElt()==d.input)d.input.blur();focusInput(cm);});}
function onResize(cm){var d=cm.display;if(d.lastWrapHeight==d.wrapper.clientHeight&&d.lastWrapWidth==d.wrapper.clientWidth)
return;d.cachedCharWidth=d.cachedTextHeight=d.cachedPaddingH=null;d.scrollbarsClipped=false;cm.setSize();}
function eventInWidget(display,e){for(var n=e_target(e);n!=display.wrapper;n=n.parentNode){if(!n||(n.nodeType==1&&n.getAttribute("cm-ignore-events")=="true")||(n.parentNode==display.sizer&&n!=display.mover))
return true;}}
function posFromMouse(cm,e,liberal,forRect){var display=cm.display;if(!liberal&&e_target(e).getAttribute("not-content")=="true")return null;var x,y,space=display.lineSpace.getBoundingClientRect();try{x=e.clientX-space.left;y=e.clientY-space.top;}
catch(e){return null;}
var coords=coordsChar(cm,x,y),line;if(forRect&&coords.xRel==1&&(line=getLine(cm.doc,coords.line).text).length==coords.ch){var colDiff=countColumn(line,line.length,cm.options.tabSize)-line.length;coords=Pos(coords.line,Math.max(0,Math.round((x-paddingH(cm.display).left)/charWidth(cm.display))-colDiff));}
return coords;}
function onMouseDown(e){if(signalDOMEvent(this,e))return;var cm=this,display=cm.display;display.shift=e.shiftKey;if(eventInWidget(display,e)){if(!webkit){display.scroller.draggable=false;setTimeout(function(){display.scroller.draggable=true;},100);}
return;}
if(clickInGutter(cm,e))return;var start=posFromMouse(cm,e);window.focus();switch(e_button(e)){case 1:if(start)
leftButtonDown(cm,e,start);else if(e_target(e)==display.scroller)
e_preventDefault(e);break;case 2:if(webkit)cm.state.lastMiddleDown=+new Date;if(start)extendSelection(cm.doc,start);setTimeout(bind(focusInput,cm),20);e_preventDefault(e);break;case 3:if(captureRightClick)onContextMenu(cm,e);break;}}
var lastClick,lastDoubleClick;function leftButtonDown(cm,e,start){setTimeout(bind(ensureFocus,cm),0);var now=+new Date,type;if(lastDoubleClick&&lastDoubleClick.time>now-400&&cmp(lastDoubleClick.pos,start)==0){type="triple";}else if(lastClick&&lastClick.time>now-400&&cmp(lastClick.pos,start)==0){type="double";lastDoubleClick={time:now,pos:start};}else{type="single";lastClick={time:now,pos:start};}
var sel=cm.doc.sel,modifier=mac?e.metaKey:e.ctrlKey,contained;if(cm.options.dragDrop&&dragAndDrop&&!isReadOnly(cm)&&type=="single"&&(contained=sel.contains(start))>-1&&!sel.ranges[contained].empty())
leftButtonStartDrag(cm,e,start,modifier);else
leftButtonSelect(cm,e,start,type,modifier);}
function leftButtonStartDrag(cm,e,start,modifier){var display=cm.display;var dragEnd=operation(cm,function(e2){if(webkit)display.scroller.draggable=false;cm.state.draggingText=false;off(document,"mouseup",dragEnd);off(display.scroller,"drop",dragEnd);if(Math.abs(e.clientX-e2.clientX)+Math.abs(e.clientY-e2.clientY)<10){e_preventDefault(e2);if(!modifier)
extendSelection(cm.doc,start);focusInput(cm);if(ie&&ie_version==9)
setTimeout(function(){document.body.focus();focusInput(cm);},20);}});if(webkit)display.scroller.draggable=true;cm.state.draggingText=dragEnd;if(display.scroller.dragDrop)display.scroller.dragDrop();on(document,"mouseup",dragEnd);on(display.scroller,"drop",dragEnd);}
function leftButtonSelect(cm,e,start,type,addNew){var display=cm.display,doc=cm.doc;e_preventDefault(e);var ourRange,ourIndex,startSel=doc.sel,ranges=startSel.ranges;if(addNew&&!e.shiftKey){ourIndex=doc.sel.contains(start);if(ourIndex>-1)
ourRange=ranges[ourIndex];else
ourRange=new Range(start,start);}else{ourRange=doc.sel.primary();}
if(e.altKey){type="rect";if(!addNew)ourRange=new Range(start,start);start=posFromMouse(cm,e,true,true);ourIndex=-1;}else if(type=="double"){var word=cm.findWordAt(start);if(cm.display.shift||doc.extend)
ourRange=extendRange(doc,ourRange,word.anchor,word.head);else
ourRange=word;}else if(type=="triple"){var line=new Range(Pos(start.line,0),clipPos(doc,Pos(start.line+1,0)));if(cm.display.shift||doc.extend)
ourRange=extendRange(doc,ourRange,line.anchor,line.head);else
ourRange=line;}else{ourRange=extendRange(doc,ourRange,start);}
if(!addNew){ourIndex=0;setSelection(doc,new Selection([ourRange],0),sel_mouse);startSel=doc.sel;}else if(ourIndex==-1){ourIndex=ranges.length;setSelection(doc,normalizeSelection(ranges.concat([ourRange]),ourIndex),{scroll:false,origin:"*mouse"});}else if(ranges.length>1&&ranges[ourIndex].empty()&&type=="single"){setSelection(doc,normalizeSelection(ranges.slice(0,ourIndex).concat(ranges.slice(ourIndex+1)),0));startSel=doc.sel;}else{replaceOneSelection(doc,ourIndex,ourRange,sel_mouse);}
var lastPos=start;function extendTo(pos){if(cmp(lastPos,pos)==0)return;lastPos=pos;if(type=="rect"){var ranges=[],tabSize=cm.options.tabSize;var startCol=countColumn(getLine(doc,start.line).text,start.ch,tabSize);var posCol=countColumn(getLine(doc,pos.line).text,pos.ch,tabSize);var left=Math.min(startCol,posCol),right=Math.max(startCol,posCol);for(var line=Math.min(start.line,pos.line),end=Math.min(cm.lastLine(),Math.max(start.line,pos.line));line<=end;line++){var text=getLine(doc,line).text,leftPos=findColumn(text,left,tabSize);if(left==right)
ranges.push(new Range(Pos(line,leftPos),Pos(line,leftPos)));else if(text.length>leftPos)
ranges.push(new Range(Pos(line,leftPos),Pos(line,findColumn(text,right,tabSize))));}
if(!ranges.length)ranges.push(new Range(start,start));setSelection(doc,normalizeSelection(startSel.ranges.slice(0,ourIndex).concat(ranges),ourIndex),{origin:"*mouse",scroll:false});cm.scrollIntoView(pos);}else{var oldRange=ourRange;var anchor=oldRange.anchor,head=pos;if(type!="single"){if(type=="double")
var range=cm.findWordAt(pos);else
var range=new Range(Pos(pos.line,0),clipPos(doc,Pos(pos.line+1,0)));if(cmp(range.anchor,anchor)>0){head=range.head;anchor=minPos(oldRange.from(),range.anchor);}else{head=range.anchor;anchor=maxPos(oldRange.to(),range.head);}}
var ranges=startSel.ranges.slice(0);ranges[ourIndex]=new Range(clipPos(doc,anchor),head);setSelection(doc,normalizeSelection(ranges,ourIndex),sel_mouse);}}
var editorSize=display.wrapper.getBoundingClientRect();var counter=0;function extend(e){var curCount=++counter;var cur=posFromMouse(cm,e,true,type=="rect");if(!cur)return;if(cmp(cur,lastPos)!=0){ensureFocus(cm);extendTo(cur);var visible=visibleLines(display,doc);if(cur.line>=visible.to||cur.line<visible.from)
setTimeout(operation(cm,function(){if(counter==curCount)extend(e);}),150);}else{var outside=e.clientY<editorSize.top?-20:e.clientY>editorSize.bottom?20:0;if(outside)setTimeout(operation(cm,function(){if(counter!=curCount)return;display.scroller.scrollTop+=outside;extend(e);}),50);}}
function done(e){counter=Infinity;e_preventDefault(e);focusInput(cm);off(document,"mousemove",move);off(document,"mouseup",up);doc.history.lastSelOrigin=null;}
var move=operation(cm,function(e){if(!e_button(e))done(e);else extend(e);});var up=operation(cm,done);on(document,"mousemove",move);on(document,"mouseup",up);}
function gutterEvent(cm,e,type,prevent,signalfn){try{var mX=e.clientX,mY=e.clientY;}
catch(e){return false;}
if(mX>=Math.floor(cm.display.gutters.getBoundingClientRect().right))return false;if(prevent)e_preventDefault(e);var display=cm.display;var lineBox=display.lineDiv.getBoundingClientRect();if(mY>lineBox.bottom||!hasHandler(cm,type))return e_defaultPrevented(e);mY-=lineBox.top-display.viewOffset;for(var i=0;i<cm.options.gutters.length;++i){var g=display.gutters.childNodes[i];if(g&&g.getBoundingClientRect().right>=mX){var line=lineAtHeight(cm.doc,mY);var gutter=cm.options.gutters[i];signalfn(cm,type,cm,line,gutter,e);return e_defaultPrevented(e);}}}
function clickInGutter(cm,e){return gutterEvent(cm,e,"gutterClick",true,signalLater);}
var lastDrop=0;function onDrop(e){var cm=this;if(signalDOMEvent(cm,e)||eventInWidget(cm.display,e))
return;e_preventDefault(e);if(ie)lastDrop=+new Date;var pos=posFromMouse(cm,e,true),files=e.dataTransfer.files;if(!pos||isReadOnly(cm))return;if(files&&files.length&&window.FileReader&&window.File){var n=files.length,text=Array(n),read=0;var loadFile=function(file,i){var reader=new FileReader;reader.onload=operation(cm,function(){text[i]=reader.result;if(++read==n){pos=clipPos(cm.doc,pos);var change={from:pos,to:pos,text:splitLines(text.join("\n")),origin:"paste"};makeChange(cm.doc,change);setSelectionReplaceHistory(cm.doc,simpleSelection(pos,changeEnd(change)));}});reader.readAsText(file);};for(var i=0;i<n;++i)loadFile(files[i],i);}else{if(cm.state.draggingText&&cm.doc.sel.contains(pos)>-1){cm.state.draggingText(e);setTimeout(bind(focusInput,cm),20);return;}
try{var text=e.dataTransfer.getData("Text");if(text){if(cm.state.draggingText&&!(mac?e.metaKey:e.ctrlKey))
var selected=cm.listSelections();setSelectionNoUndo(cm.doc,simpleSelection(pos,pos));if(selected)for(var i=0;i<selected.length;++i)
replaceRange(cm.doc,"",selected[i].anchor,selected[i].head,"drag");cm.replaceSelection(text,"around","paste");focusInput(cm);}}
catch(e){}}}
function onDragStart(cm,e){if(ie&&(!cm.state.draggingText||+new Date-lastDrop<100)){e_stop(e);return;}
if(signalDOMEvent(cm,e)||eventInWidget(cm.display,e))return;e.dataTransfer.setData("Text",cm.getSelection());if(e.dataTransfer.setDragImage&&!safari){var img=elt("img",null,null,"position: fixed; left: 0; top: 0;");img.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";if(presto){img.width=img.height=1;cm.display.wrapper.appendChild(img);img._top=img.offsetTop;}
e.dataTransfer.setDragImage(img,0,0);if(presto)img.parentNode.removeChild(img);}}
function setScrollTop(cm,val){if(Math.abs(cm.doc.scrollTop-val)<2)return;cm.doc.scrollTop=val;if(!gecko)updateDisplaySimple(cm,{top:val});if(cm.display.scroller.scrollTop!=val)cm.display.scroller.scrollTop=val;cm.display.scrollbars.setScrollTop(val);if(gecko)updateDisplaySimple(cm);startWorker(cm,100);}
function setScrollLeft(cm,val,isScroller){if(isScroller?val==cm.doc.scrollLeft:Math.abs(cm.doc.scrollLeft-val)<2)return;val=Math.min(val,cm.display.scroller.scrollWidth-cm.display.scroller.clientWidth);cm.doc.scrollLeft=val;alignHorizontally(cm);if(cm.display.scroller.scrollLeft!=val)cm.display.scroller.scrollLeft=val;cm.display.scrollbars.setScrollLeft(val);}
var wheelSamples=0,wheelPixelsPerUnit=null;if(ie)wheelPixelsPerUnit=-.53;else if(gecko)wheelPixelsPerUnit=15;else if(chrome)wheelPixelsPerUnit=-.7;else if(safari)wheelPixelsPerUnit=-1/3;var wheelEventDelta=function(e){var dx=e.wheelDeltaX,dy=e.wheelDeltaY;if(dx==null&&e.detail&&e.axis==e.HORIZONTAL_AXIS)dx=e.detail;if(dy==null&&e.detail&&e.axis==e.VERTICAL_AXIS)dy=e.detail;else if(dy==null)dy=e.wheelDelta;return{x:dx,y:dy};};CodeMirror.wheelEventPixels=function(e){var delta=wheelEventDelta(e);delta.x*=wheelPixelsPerUnit;delta.y*=wheelPixelsPerUnit;return delta;};function onScrollWheel(cm,e){var delta=wheelEventDelta(e),dx=delta.x,dy=delta.y;var display=cm.display,scroll=display.scroller;if(!(dx&&scroll.scrollWidth>scroll.clientWidth||dy&&scroll.scrollHeight>scroll.clientHeight))return;if(dy&&mac&&webkit){outer:for(var cur=e.target,view=display.view;cur!=scroll;cur=cur.parentNode){for(var i=0;i<view.length;i++){if(view[i].node==cur){cm.display.currentWheelTarget=cur;break outer;}}}}
if(dx&&!gecko&&!presto&&wheelPixelsPerUnit!=null){if(dy)
setScrollTop(cm,Math.max(0,Math.min(scroll.scrollTop+dy*wheelPixelsPerUnit,scroll.scrollHeight-scroll.clientHeight)));setScrollLeft(cm,Math.max(0,Math.min(scroll.scrollLeft+dx*wheelPixelsPerUnit,scroll.scrollWidth-scroll.clientWidth)));e_preventDefault(e);display.wheelStartX=null;return;}
if(dy&&wheelPixelsPerUnit!=null){var pixels=dy*wheelPixelsPerUnit;var top=cm.doc.scrollTop,bot=top+display.wrapper.clientHeight;if(pixels<0)top=Math.max(0,top+pixels-50);else bot=Math.min(cm.doc.height,bot+pixels+50);updateDisplaySimple(cm,{top:top,bottom:bot});}
if(wheelSamples<20){if(display.wheelStartX==null){display.wheelStartX=scroll.scrollLeft;display.wheelStartY=scroll.scrollTop;display.wheelDX=dx;display.wheelDY=dy;setTimeout(function(){if(display.wheelStartX==null)return;var movedX=scroll.scrollLeft-display.wheelStartX;var movedY=scroll.scrollTop-display.wheelStartY;var sample=(movedY&&display.wheelDY&&movedY/display.wheelDY)||(movedX&&display.wheelDX&&movedX/display.wheelDX);display.wheelStartX=display.wheelStartY=null;if(!sample)return;wheelPixelsPerUnit=(wheelPixelsPerUnit*wheelSamples+sample)/(wheelSamples+1);++wheelSamples;},200);}else{display.wheelDX+=dx;display.wheelDY+=dy;}}}
function doHandleBinding(cm,bound,dropShift){if(typeof bound=="string"){bound=commands[bound];if(!bound)return false;}
if(cm.display.pollingFast&&readInput(cm))cm.display.pollingFast=false;var prevShift=cm.display.shift,done=false;try{if(isReadOnly(cm))cm.state.suppressEdits=true;if(dropShift)cm.display.shift=false;done=bound(cm)!=Pass;}finally{cm.display.shift=prevShift;cm.state.suppressEdits=false;}
return done;}
function lookupKeyForEditor(cm,name,handle){for(var i=0;i<cm.state.keyMaps.length;i++){var result=lookupKey(name,cm.state.keyMaps[i],handle,cm);if(result)return result;}
return(cm.options.extraKeys&&lookupKey(name,cm.options.extraKeys,handle,cm))||lookupKey(name,cm.options.keyMap,handle,cm);}
var stopSeq=new Delayed;function dispatchKey(cm,name,e,handle){var seq=cm.state.keySeq;if(seq){if(isModifierKey(name))return"handled";stopSeq.set(50,function(){if(cm.state.keySeq==seq){cm.state.keySeq=null;resetInput(cm);}});name=seq+" "+name;}
var result=lookupKeyForEditor(cm,name,handle);if(result=="multi")
cm.state.keySeq=name;if(result=="handled")
signalLater(cm,"keyHandled",cm,name,e);if(result=="handled"||result=="multi"){e_preventDefault(e);restartBlink(cm);}
if(seq&&!result&&/\'$/.test(name)){e_preventDefault(e);return true;}
return!!result;}
function handleKeyBinding(cm,e){var name=keyName(e,true);if(!name)return false;if(e.shiftKey&&!cm.state.keySeq){return dispatchKey(cm,"Shift-"+name,e,function(b){return doHandleBinding(cm,b,true);})||dispatchKey(cm,name,e,function(b){if(typeof b=="string"?/^go[A-Z]/.test(b):b.motion)
return doHandleBinding(cm,b);});}else{return dispatchKey(cm,name,e,function(b){return doHandleBinding(cm,b);});}}
function handleCharBinding(cm,e,ch){return dispatchKey(cm,"'"+ch+"'",e,function(b){return doHandleBinding(cm,b,true);});}
var lastStoppedKey=null;function onKeyDown(e){var cm=this;ensureFocus(cm);if(signalDOMEvent(cm,e))return;if(ie&&ie_version<11&&e.keyCode==27)e.returnValue=false;var code=e.keyCode;cm.display.shift=code==16||e.shiftKey;var handled=handleKeyBinding(cm,e);if(presto){lastStoppedKey=handled?code:null;if(!handled&&code==88&&!hasCopyEvent&&(mac?e.metaKey:e.ctrlKey))
cm.replaceSelection("",null,"cut");}
if(code==18&&!/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
showCrossHair(cm);}
function showCrossHair(cm){var lineDiv=cm.display.lineDiv;addClass(lineDiv,"CodeMirror-crosshair");function up(e){if(e.keyCode==18||!e.altKey){rmClass(lineDiv,"CodeMirror-crosshair");off(document,"keyup",up);off(document,"mouseover",up);}}
on(document,"keyup",up);on(document,"mouseover",up);}
function onKeyUp(e){if(e.keyCode==16)this.doc.sel.shift=false;signalDOMEvent(this,e);}
function onKeyPress(e){var cm=this;if(signalDOMEvent(cm,e)||e.ctrlKey&&!e.altKey||mac&&e.metaKey)return;var keyCode=e.keyCode,charCode=e.charCode;if(presto&&keyCode==lastStoppedKey){lastStoppedKey=null;e_preventDefault(e);return;}
if(((presto&&(!e.which||e.which<10))||khtml)&&handleKeyBinding(cm,e))return;var ch=String.fromCharCode(charCode==null?keyCode:charCode);if(handleCharBinding(cm,e,ch))return;if(ie&&ie_version>=9)cm.display.inputHasSelection=null;fastPoll(cm);}
function onFocus(cm){if(cm.options.readOnly=="nocursor")return;if(!cm.state.focused){signal(cm,"focus",cm);cm.state.focused=true;addClass(cm.display.wrapper,"CodeMirror-focused");if(!cm.curOp&&cm.display.selForContextMenu!=cm.doc.sel){resetInput(cm);if(webkit)setTimeout(bind(resetInput,cm,true),0);}}
slowPoll(cm);restartBlink(cm);}
function onBlur(cm){if(cm.state.focused){signal(cm,"blur",cm);cm.state.focused=false;rmClass(cm.display.wrapper,"CodeMirror-focused");}
clearInterval(cm.display.blinker);setTimeout(function(){if(!cm.state.focused)cm.display.shift=false;},150);}
function onContextMenu(cm,e){if(signalDOMEvent(cm,e,"contextmenu"))return;var display=cm.display;if(eventInWidget(display,e)||contextMenuInGutter(cm,e))return;var pos=posFromMouse(cm,e),scrollPos=display.scroller.scrollTop;if(!pos||presto)return;var reset=cm.options.resetSelectionOnContextMenu;if(reset&&cm.doc.sel.contains(pos)==-1)
operation(cm,setSelection)(cm.doc,simpleSelection(pos),sel_dontScroll);var oldCSS=display.input.style.cssText;display.inputDiv.style.position="absolute";display.input.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(e.clientY-5)+"px; left: "+(e.clientX-5)+"px; z-index: 1000; background: "+
(ie?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";if(webkit)var oldScrollY=window.scrollY;focusInput(cm);if(webkit)window.scrollTo(null,oldScrollY);resetInput(cm);if(!cm.somethingSelected())display.input.value=display.prevInput=" ";display.contextMenuPending=true;display.selForContextMenu=cm.doc.sel;clearTimeout(display.detectingSelectAll);function prepareSelectAllHack(){if(display.input.selectionStart!=null){var selected=cm.somethingSelected();var extval=display.input.value="\u200b"+(selected?display.input.value:"");display.prevInput=selected?"":"\u200b";display.input.selectionStart=1;display.input.selectionEnd=extval.length;display.selForContextMenu=cm.doc.sel;}}
function rehide(){display.contextMenuPending=false;display.inputDiv.style.position="relative";display.input.style.cssText=oldCSS;if(ie&&ie_version<9)display.scrollbars.setScrollTop(display.scroller.scrollTop=scrollPos);slowPoll(cm);if(display.input.selectionStart!=null){if(!ie||(ie&&ie_version<9))prepareSelectAllHack();var i=0,poll=function(){if(display.selForContextMenu==cm.doc.sel&&display.input.selectionStart==0)
operation(cm,commands.selectAll)(cm);else if(i++<10)display.detectingSelectAll=setTimeout(poll,500);else resetInput(cm);};display.detectingSelectAll=setTimeout(poll,200);}}
if(ie&&ie_version>=9)prepareSelectAllHack();if(captureRightClick){e_stop(e);var mouseup=function(){off(window,"mouseup",mouseup);setTimeout(rehide,20);};on(window,"mouseup",mouseup);}else{setTimeout(rehide,50);}}
function contextMenuInGutter(cm,e){if(!hasHandler(cm,"gutterContextMenu"))return false;return gutterEvent(cm,e,"gutterContextMenu",false,signal);}
var changeEnd=CodeMirror.changeEnd=function(change){if(!change.text)return change.to;return Pos(change.from.line+change.text.length-1,lst(change.text).length+(change.text.length==1?change.from.ch:0));};function adjustForChange(pos,change){if(cmp(pos,change.from)<0)return pos;if(cmp(pos,change.to)<=0)return changeEnd(change);var line=pos.line+change.text.length-(change.to.line-change.from.line)-1,ch=pos.ch;if(pos.line==change.to.line)ch+=changeEnd(change).ch-change.to.ch;return Pos(line,ch);}
function computeSelAfterChange(doc,change){var out=[];for(var i=0;i<doc.sel.ranges.length;i++){var range=doc.sel.ranges[i];out.push(new Range(adjustForChange(range.anchor,change),adjustForChange(range.head,change)));}
return normalizeSelection(out,doc.sel.primIndex);}
function offsetPos(pos,old,nw){if(pos.line==old.line)
return Pos(nw.line,pos.ch-old.ch+nw.ch);else
return Pos(nw.line+(pos.line-old.line),pos.ch);}
function computeReplacedSel(doc,changes,hint){var out=[];var oldPrev=Pos(doc.first,0),newPrev=oldPrev;for(var i=0;i<changes.length;i++){var change=changes[i];var from=offsetPos(change.from,oldPrev,newPrev);var to=offsetPos(changeEnd(change),oldPrev,newPrev);oldPrev=change.to;newPrev=to;if(hint=="around"){var range=doc.sel.ranges[i],inv=cmp(range.head,range.anchor)<0;out[i]=new Range(inv?to:from,inv?from:to);}else{out[i]=new Range(from,from);}}
return new Selection(out,doc.sel.primIndex);}
function filterChange(doc,change,update){var obj={canceled:false,from:change.from,to:change.to,text:change.text,origin:change.origin,cancel:function(){this.canceled=true;}};if(update)obj.update=function(from,to,text,origin){if(from)this.from=clipPos(doc,from);if(to)this.to=clipPos(doc,to);if(text)this.text=text;if(origin!==undefined)this.origin=origin;};signal(doc,"beforeChange",doc,obj);if(doc.cm)signal(doc.cm,"beforeChange",doc.cm,obj);if(obj.canceled)return null;return{from:obj.from,to:obj.to,text:obj.text,origin:obj.origin};}
function makeChange(doc,change,ignoreReadOnly){if(doc.cm){if(!doc.cm.curOp)return operation(doc.cm,makeChange)(doc,change,ignoreReadOnly);if(doc.cm.state.suppressEdits)return;}
if(hasHandler(doc,"beforeChange")||doc.cm&&hasHandler(doc.cm,"beforeChange")){change=filterChange(doc,change,true);if(!change)return;}
var split=sawReadOnlySpans&&!ignoreReadOnly&&removeReadOnlyRanges(doc,change.from,change.to);if(split){for(var i=split.length-1;i>=0;--i)
makeChangeInner(doc,{from:split[i].from,to:split[i].to,text:i?[""]:change.text});}else{makeChangeInner(doc,change);}}
function makeChangeInner(doc,change){if(change.text.length==1&&change.text[0]==""&&cmp(change.from,change.to)==0)return;var selAfter=computeSelAfterChange(doc,change);addChangeToHistory(doc,change,selAfter,doc.cm?doc.cm.curOp.id:NaN);makeChangeSingleDoc(doc,change,selAfter,stretchSpansOverChange(doc,change));var rebased=[];linkedDocs(doc,function(doc,sharedHist){if(!sharedHist&&indexOf(rebased,doc.history)==-1){rebaseHist(doc.history,change);rebased.push(doc.history);}
makeChangeSingleDoc(doc,change,null,stretchSpansOverChange(doc,change));});}
function makeChangeFromHistory(doc,type,allowSelectionOnly){if(doc.cm&&doc.cm.state.suppressEdits)return;var hist=doc.history,event,selAfter=doc.sel;var source=type=="undo"?hist.done:hist.undone,dest=type=="undo"?hist.undone:hist.done;for(var i=0;i<source.length;i++){event=source[i];if(allowSelectionOnly?event.ranges&&!event.equals(doc.sel):!event.ranges)
break;}
if(i==source.length)return;hist.lastOrigin=hist.lastSelOrigin=null;for(;;){event=source.pop();if(event.ranges){pushSelectionToHistory(event,dest);if(allowSelectionOnly&&!event.equals(doc.sel)){setSelection(doc,event,{clearRedo:false});return;}
selAfter=event;}
else break;}
var antiChanges=[];pushSelectionToHistory(selAfter,dest);dest.push({changes:antiChanges,generation:hist.generation});hist.generation=event.generation||++hist.maxGeneration;var filter=hasHandler(doc,"beforeChange")||doc.cm&&hasHandler(doc.cm,"beforeChange");for(var i=event.changes.length-1;i>=0;--i){var change=event.changes[i];change.origin=type;if(filter&&!filterChange(doc,change,false)){source.length=0;return;}
antiChanges.push(historyChangeFromChange(doc,change));var after=i?computeSelAfterChange(doc,change):lst(source);makeChangeSingleDoc(doc,change,after,mergeOldSpans(doc,change));if(!i&&doc.cm)doc.cm.scrollIntoView({from:change.from,to:changeEnd(change)});var rebased=[];linkedDocs(doc,function(doc,sharedHist){if(!sharedHist&&indexOf(rebased,doc.history)==-1){rebaseHist(doc.history,change);rebased.push(doc.history);}
makeChangeSingleDoc(doc,change,null,mergeOldSpans(doc,change));});}}
function shiftDoc(doc,distance){if(distance==0)return;doc.first+=distance;doc.sel=new Selection(map(doc.sel.ranges,function(range){return new Range(Pos(range.anchor.line+distance,range.anchor.ch),Pos(range.head.line+distance,range.head.ch));}),doc.sel.primIndex);if(doc.cm){regChange(doc.cm,doc.first,doc.first-distance,distance);for(var d=doc.cm.display,l=d.viewFrom;l<d.viewTo;l++)
regLineChange(doc.cm,l,"gutter");}}
function makeChangeSingleDoc(doc,change,selAfter,spans){if(doc.cm&&!doc.cm.curOp)
return operation(doc.cm,makeChangeSingleDoc)(doc,change,selAfter,spans);if(change.to.line<doc.first){shiftDoc(doc,change.text.length-1-(change.to.line-change.from.line));return;}
if(change.from.line>doc.lastLine())return;if(change.from.line<doc.first){var shift=change.text.length-1-(doc.first-change.from.line);shiftDoc(doc,shift);change={from:Pos(doc.first,0),to:Pos(change.to.line+shift,change.to.ch),text:[lst(change.text)],origin:change.origin};}
var last=doc.lastLine();if(change.to.line>last){change={from:change.from,to:Pos(last,getLine(doc,last).text.length),text:[change.text[0]],origin:change.origin};}
change.removed=getBetween(doc,change.from,change.to);if(!selAfter)selAfter=computeSelAfterChange(doc,change);if(doc.cm)makeChangeSingleDocInEditor(doc.cm,change,spans);else updateDoc(doc,change,spans);setSelectionNoUndo(doc,selAfter,sel_dontScroll);}
function makeChangeSingleDocInEditor(cm,change,spans){var doc=cm.doc,display=cm.display,from=change.from,to=change.to;var recomputeMaxLength=false,checkWidthStart=from.line;if(!cm.options.lineWrapping){checkWidthStart=lineNo(visualLine(getLine(doc,from.line)));doc.iter(checkWidthStart,to.line+1,function(line){if(line==display.maxLine){recomputeMaxLength=true;return true;}});}
if(doc.sel.contains(change.from,change.to)>-1)
signalCursorActivity(cm);updateDoc(doc,change,spans,estimateHeight(cm));if(!cm.options.lineWrapping){doc.iter(checkWidthStart,from.line+change.text.length,function(line){var len=lineLength(line);if(len>display.maxLineLength){display.maxLine=line;display.maxLineLength=len;display.maxLineChanged=true;recomputeMaxLength=false;}});if(recomputeMaxLength)cm.curOp.updateMaxLine=true;}
doc.frontier=Math.min(doc.frontier,from.line);startWorker(cm,400);var lendiff=change.text.length-(to.line-from.line)-1;if(change.full)
regChange(cm);else if(from.line==to.line&&change.text.length==1&&!isWholeLineUpdate(cm.doc,change))
regLineChange(cm,from.line,"text");else
regChange(cm,from.line,to.line+1,lendiff);var changesHandler=hasHandler(cm,"changes"),changeHandler=hasHandler(cm,"change");if(changeHandler||changesHandler){var obj={from:from,to:to,text:change.text,removed:change.removed,origin:change.origin};if(changeHandler)signalLater(cm,"change",cm,obj);if(changesHandler)(cm.curOp.changeObjs||(cm.curOp.changeObjs=[])).push(obj);}
cm.display.selForContextMenu=null;}
function replaceRange(doc,code,from,to,origin){if(!to)to=from;if(cmp(to,from)<0){var tmp=to;to=from;from=tmp;}
if(typeof code=="string")code=splitLines(code);makeChange(doc,{from:from,to:to,text:code,origin:origin});}
function maybeScrollWindow(cm,coords){if(signalDOMEvent(cm,"scrollCursorIntoView"))return;var display=cm.display,box=display.sizer.getBoundingClientRect(),doScroll=null;if(coords.top+box.top<0)doScroll=true;else if(coords.bottom+box.top>(window.innerHeight||document.documentElement.clientHeight))doScroll=false;if(doScroll!=null&&!phantom){var scrollNode=elt("div","\u200b",null,"position: absolute; top: "+
(coords.top-display.viewOffset-paddingTop(cm.display))+"px; height: "+
(coords.bottom-coords.top+scrollGap(cm)+display.barHeight)+"px; left: "+
coords.left+"px; width: 2px;");cm.display.lineSpace.appendChild(scrollNode);scrollNode.scrollIntoView(doScroll);cm.display.lineSpace.removeChild(scrollNode);}}
function scrollPosIntoView(cm,pos,end,margin){if(margin==null)margin=0;for(var limit=0;limit<5;limit++){var changed=false,coords=cursorCoords(cm,pos);var endCoords=!end||end==pos?coords:cursorCoords(cm,end);var scrollPos=calculateScrollPos(cm,Math.min(coords.left,endCoords.left),Math.min(coords.top,endCoords.top)-margin,Math.max(coords.left,endCoords.left),Math.max(coords.bottom,endCoords.bottom)+margin);var startTop=cm.doc.scrollTop,startLeft=cm.doc.scrollLeft;if(scrollPos.scrollTop!=null){setScrollTop(cm,scrollPos.scrollTop);if(Math.abs(cm.doc.scrollTop-startTop)>1)changed=true;}
if(scrollPos.scrollLeft!=null){setScrollLeft(cm,scrollPos.scrollLeft);if(Math.abs(cm.doc.scrollLeft-startLeft)>1)changed=true;}
if(!changed)break;}
return coords;}
function scrollIntoView(cm,x1,y1,x2,y2){var scrollPos=calculateScrollPos(cm,x1,y1,x2,y2);if(scrollPos.scrollTop!=null)setScrollTop(cm,scrollPos.scrollTop);if(scrollPos.scrollLeft!=null)setScrollLeft(cm,scrollPos.scrollLeft);}
function calculateScrollPos(cm,x1,y1,x2,y2){var display=cm.display,snapMargin=textHeight(cm.display);if(y1<0)y1=0;var screentop=cm.curOp&&cm.curOp.scrollTop!=null?cm.curOp.scrollTop:display.scroller.scrollTop;var screen=displayHeight(cm),result={};if(y2-y1>screen)y2=y1+screen;var docBottom=cm.doc.height+paddingVert(display);var atTop=y1<snapMargin,atBottom=y2>docBottom-snapMargin;if(y1<screentop){result.scrollTop=atTop?0:y1;}else if(y2>screentop+screen){var newTop=Math.min(y1,(atBottom?docBottom:y2)-screen);if(newTop!=screentop)result.scrollTop=newTop;}
var screenleft=cm.curOp&&cm.curOp.scrollLeft!=null?cm.curOp.scrollLeft:display.scroller.scrollLeft;var screenw=displayWidth(cm)-(cm.options.fixedGutter?display.gutters.offsetWidth:0);var tooWide=x2-x1>screenw;if(tooWide)x2=x1+screenw;if(x1<10)
result.scrollLeft=0;else if(x1<screenleft)
result.scrollLeft=Math.max(0,x1-(tooWide?0:10));else if(x2>screenw+screenleft-3)
result.scrollLeft=x2+(tooWide?0:10)-screenw;return result;}
function addToScrollPos(cm,left,top){if(left!=null||top!=null)resolveScrollToPos(cm);if(left!=null)
cm.curOp.scrollLeft=(cm.curOp.scrollLeft==null?cm.doc.scrollLeft:cm.curOp.scrollLeft)+left;if(top!=null)
cm.curOp.scrollTop=(cm.curOp.scrollTop==null?cm.doc.scrollTop:cm.curOp.scrollTop)+top;}
function ensureCursorVisible(cm){resolveScrollToPos(cm);var cur=cm.getCursor(),from=cur,to=cur;if(!cm.options.lineWrapping){from=cur.ch?Pos(cur.line,cur.ch-1):cur;to=Pos(cur.line,cur.ch+1);}
cm.curOp.scrollToPos={from:from,to:to,margin:cm.options.cursorScrollMargin,isCursor:true};}
function resolveScrollToPos(cm){var range=cm.curOp.scrollToPos;if(range){cm.curOp.scrollToPos=null;var from=estimateCoords(cm,range.from),to=estimateCoords(cm,range.to);var sPos=calculateScrollPos(cm,Math.min(from.left,to.left),Math.min(from.top,to.top)-range.margin,Math.max(from.right,to.right),Math.max(from.bottom,to.bottom)+range.margin);cm.scrollTo(sPos.scrollLeft,sPos.scrollTop);}}
function indentLine(cm,n,how,aggressive){var doc=cm.doc,state;if(how==null)how="add";if(how=="smart"){if(!doc.mode.indent)how="prev";else state=getStateBefore(cm,n);}
var tabSize=cm.options.tabSize;var line=getLine(doc,n),curSpace=countColumn(line.text,null,tabSize);if(line.stateAfter)line.stateAfter=null;var curSpaceString=line.text.match(/^\s*/)[0],indentation;if(!aggressive&&!/\S/.test(line.text)){indentation=0;how="not";}else if(how=="smart"){indentation=doc.mode.indent(state,line.text.slice(curSpaceString.length),line.text);if(indentation==Pass||indentation>150){if(!aggressive)return;how="prev";}}
if(how=="prev"){if(n>doc.first)indentation=countColumn(getLine(doc,n-1).text,null,tabSize);else indentation=0;}else if(how=="add"){indentation=curSpace+cm.options.indentUnit;}else if(how=="subtract"){indentation=curSpace-cm.options.indentUnit;}else if(typeof how=="number"){indentation=curSpace+how;}
indentation=Math.max(0,indentation);var indentString="",pos=0;if(cm.options.indentWithTabs)
for(var i=Math.floor(indentation/tabSize);i;--i){pos+=tabSize;indentString+="\t";}
if(pos<indentation)indentString+=spaceStr(indentation-pos);if(indentString!=curSpaceString){replaceRange(doc,indentString,Pos(n,0),Pos(n,curSpaceString.length),"+input");}else{for(var i=0;i<doc.sel.ranges.length;i++){var range=doc.sel.ranges[i];if(range.head.line==n&&range.head.ch<curSpaceString.length){var pos=Pos(n,curSpaceString.length);replaceOneSelection(doc,i,new Range(pos,pos));break;}}}
line.stateAfter=null;}
function changeLine(doc,handle,changeType,op){var no=handle,line=handle;if(typeof handle=="number")line=getLine(doc,clipLine(doc,handle));else no=lineNo(handle);if(no==null)return null;if(op(line,no)&&doc.cm)regLineChange(doc.cm,no,changeType);return line;}
function deleteNearSelection(cm,compute){var ranges=cm.doc.sel.ranges,kill=[];for(var i=0;i<ranges.length;i++){var toKill=compute(ranges[i]);while(kill.length&&cmp(toKill.from,lst(kill).to)<=0){var replaced=kill.pop();if(cmp(replaced.from,toKill.from)<0){toKill.from=replaced.from;break;}}
kill.push(toKill);}
runInOp(cm,function(){for(var i=kill.length-1;i>=0;i--)
replaceRange(cm.doc,"",kill[i].from,kill[i].to,"+delete");ensureCursorVisible(cm);});}
function findPosH(doc,pos,dir,unit,visually){var line=pos.line,ch=pos.ch,origDir=dir;var lineObj=getLine(doc,line);var possible=true;function findNextLine(){var l=line+dir;if(l<doc.first||l>=doc.first+doc.size)return(possible=false);line=l;return lineObj=getLine(doc,l);}
function moveOnce(boundToLine){var next=(visually?moveVisually:moveLogically)(lineObj,ch,dir,true);if(next==null){if(!boundToLine&&findNextLine()){if(visually)ch=(dir<0?lineRight:lineLeft)(lineObj);else ch=dir<0?lineObj.text.length:0;}else return(possible=false);}else ch=next;return true;}
if(unit=="char")moveOnce();else if(unit=="column")moveOnce(true);else if(unit=="word"||unit=="group"){var sawType=null,group=unit=="group";var helper=doc.cm&&doc.cm.getHelper(pos,"wordChars");for(var first=true;;first=false){if(dir<0&&!moveOnce(!first))break;var cur=lineObj.text.charAt(ch)||"\n";var type=isWordChar(cur,helper)?"w":group&&cur=="\n"?"n":!group||/\s/.test(cur)?null:"p";if(group&&!first&&!type)type="s";if(sawType&&sawType!=type){if(dir<0){dir=1;moveOnce();}
break;}
if(type)sawType=type;if(dir>0&&!moveOnce(!first))break;}}
var result=skipAtomic(doc,Pos(line,ch),origDir,true);if(!possible)result.hitSide=true;return result;}
function findPosV(cm,pos,dir,unit){var doc=cm.doc,x=pos.left,y;if(unit=="page"){var pageSize=Math.min(cm.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);y=pos.top+dir*(pageSize-(dir<0?1.5:.5)*textHeight(cm.display));}else if(unit=="line"){y=dir>0?pos.bottom+3:pos.top-3;}
for(;;){var target=coordsChar(cm,x,y);if(!target.outside)break;if(dir<0?y<=0:y>=doc.height){target.hitSide=true;break;}
y+=dir*5;}
return target;}
CodeMirror.prototype={constructor:CodeMirror,focus:function(){window.focus();focusInput(this);fastPoll(this);},setOption:function(option,value){var options=this.options,old=options[option];if(options[option]==value&&option!="mode")return;options[option]=value;if(optionHandlers.hasOwnProperty(option))
operation(this,optionHandlers[option])(this,value,old);},getOption:function(option){return this.options[option];},getDoc:function(){return this.doc;},addKeyMap:function(map,bottom){this.state.keyMaps[bottom?"push":"unshift"](getKeyMap(map));},removeKeyMap:function(map){var maps=this.state.keyMaps;for(var i=0;i<maps.length;++i)
if(maps[i]==map||maps[i].name==map){maps.splice(i,1);return true;}},addOverlay:methodOp(function(spec,options){var mode=spec.token?spec:CodeMirror.getMode(this.options,spec);if(mode.startState)throw new Error("Overlays may not be stateful.");this.state.overlays.push({mode:mode,modeSpec:spec,opaque:options&&options.opaque});this.state.modeGen++;regChange(this);}),removeOverlay:methodOp(function(spec){var overlays=this.state.overlays;for(var i=0;i<overlays.length;++i){var cur=overlays[i].modeSpec;if(cur==spec||typeof spec=="string"&&cur.name==spec){overlays.splice(i,1);this.state.modeGen++;regChange(this);return;}}}),indentLine:methodOp(function(n,dir,aggressive){if(typeof dir!="string"&&typeof dir!="number"){if(dir==null)dir=this.options.smartIndent?"smart":"prev";else dir=dir?"add":"subtract";}
if(isLine(this.doc,n))indentLine(this,n,dir,aggressive);}),indentSelection:methodOp(function(how){var ranges=this.doc.sel.ranges,end=-1;for(var i=0;i<ranges.length;i++){var range=ranges[i];if(!range.empty()){var from=range.from(),to=range.to();var start=Math.max(end,from.line);end=Math.min(this.lastLine(),to.line-(to.ch?0:1))+1;for(var j=start;j<end;++j)
indentLine(this,j,how);var newRanges=this.doc.sel.ranges;if(from.ch==0&&ranges.length==newRanges.length&&newRanges[i].from().ch>0)
replaceOneSelection(this.doc,i,new Range(from,newRanges[i].to()),sel_dontScroll);}else if(range.head.line>end){indentLine(this,range.head.line,how,true);end=range.head.line;if(i==this.doc.sel.primIndex)ensureCursorVisible(this);}}}),getTokenAt:function(pos,precise){return takeToken(this,pos,precise);},getLineTokens:function(line,precise){return takeToken(this,Pos(line),precise,true);},getTokenTypeAt:function(pos){pos=clipPos(this.doc,pos);var styles=getLineStyles(this,getLine(this.doc,pos.line));var before=0,after=(styles.length-1)/2,ch=pos.ch;var type;if(ch==0)type=styles[2];else for(;;){var mid=(before+after)>>1;if((mid?styles[mid*2-1]:0)>=ch)after=mid;else if(styles[mid*2+1]<ch)before=mid+1;else{type=styles[mid*2+2];break;}}
var cut=type?type.indexOf("cm-overlay "):-1;return cut<0?type:cut==0?null:type.slice(0,cut-1);},getModeAt:function(pos){var mode=this.doc.mode;if(!mode.innerMode)return mode;return CodeMirror.innerMode(mode,this.getTokenAt(pos).state).mode;},getHelper:function(pos,type){return this.getHelpers(pos,type)[0];},getHelpers:function(pos,type){var found=[];if(!helpers.hasOwnProperty(type))return helpers;var help=helpers[type],mode=this.getModeAt(pos);if(typeof mode[type]=="string"){if(help[mode[type]])found.push(help[mode[type]]);}else if(mode[type]){for(var i=0;i<mode[type].length;i++){var val=help[mode[type][i]];if(val)found.push(val);}}else if(mode.helperType&&help[mode.helperType]){found.push(help[mode.helperType]);}else if(help[mode.name]){found.push(help[mode.name]);}
for(var i=0;i<help._global.length;i++){var cur=help._global[i];if(cur.pred(mode,this)&&indexOf(found,cur.val)==-1)
found.push(cur.val);}
return found;},getStateAfter:function(line,precise){var doc=this.doc;line=clipLine(doc,line==null?doc.first+doc.size-1:line);return getStateBefore(this,line+1,precise);},cursorCoords:function(start,mode){var pos,range=this.doc.sel.primary();if(start==null)pos=range.head;else if(typeof start=="object")pos=clipPos(this.doc,start);else pos=start?range.from():range.to();return cursorCoords(this,pos,mode||"page");},charCoords:function(pos,mode){return charCoords(this,clipPos(this.doc,pos),mode||"page");},coordsChar:function(coords,mode){coords=fromCoordSystem(this,coords,mode||"page");return coordsChar(this,coords.left,coords.top);},lineAtHeight:function(height,mode){height=fromCoordSystem(this,{top:height,left:0},mode||"page").top;return lineAtHeight(this.doc,height+this.display.viewOffset);},heightAtLine:function(line,mode){var end=false,last=this.doc.first+this.doc.size-1;if(line<this.doc.first)line=this.doc.first;else if(line>last){line=last;end=true;}
var lineObj=getLine(this.doc,line);return intoCoordSystem(this,lineObj,{top:0,left:0},mode||"page").top+
(end?this.doc.height-heightAtLine(lineObj):0);},defaultTextHeight:function(){return textHeight(this.display);},defaultCharWidth:function(){return charWidth(this.display);},setGutterMarker:methodOp(function(line,gutterID,value){return changeLine(this.doc,line,"gutter",function(line){var markers=line.gutterMarkers||(line.gutterMarkers={});markers[gutterID]=value;if(!value&&isEmpty(markers))line.gutterMarkers=null;return true;});}),clearGutter:methodOp(function(gutterID){var cm=this,doc=cm.doc,i=doc.first;doc.iter(function(line){if(line.gutterMarkers&&line.gutterMarkers[gutterID]){line.gutterMarkers[gutterID]=null;regLineChange(cm,i,"gutter");if(isEmpty(line.gutterMarkers))line.gutterMarkers=null;}
++i;});}),addLineWidget:methodOp(function(handle,node,options){return addLineWidget(this,handle,node,options);}),removeLineWidget:function(widget){widget.clear();},lineInfo:function(line){if(typeof line=="number"){if(!isLine(this.doc,line))return null;var n=line;line=getLine(this.doc,line);if(!line)return null;}else{var n=lineNo(line);if(n==null)return null;}
return{line:n,handle:line,text:line.text,gutterMarkers:line.gutterMarkers,textClass:line.textClass,bgClass:line.bgClass,wrapClass:line.wrapClass,widgets:line.widgets};},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo};},addWidget:function(pos,node,scroll,vert,horiz){var display=this.display;pos=cursorCoords(this,clipPos(this.doc,pos));var top=pos.bottom,left=pos.left;node.style.position="absolute";node.setAttribute("cm-ignore-events","true");display.sizer.appendChild(node);if(vert=="over"){top=pos.top;}else if(vert=="above"||vert=="near"){var vspace=Math.max(display.wrapper.clientHeight,this.doc.height),hspace=Math.max(display.sizer.clientWidth,display.lineSpace.clientWidth);if((vert=='above'||pos.bottom+node.offsetHeight>vspace)&&pos.top>node.offsetHeight)
top=pos.top-node.offsetHeight;else if(pos.bottom+node.offsetHeight<=vspace)
top=pos.bottom;if(left+node.offsetWidth>hspace)
left=hspace-node.offsetWidth;}
node.style.top=top+"px";node.style.left=node.style.right="";if(horiz=="right"){left=display.sizer.clientWidth-node.offsetWidth;node.style.right="0px";}else{if(horiz=="left")left=0;else if(horiz=="middle")left=(display.sizer.clientWidth-node.offsetWidth)/2;node.style.left=left+"px";}
if(scroll)
scrollIntoView(this,left,top,left+node.offsetWidth,top+node.offsetHeight);},triggerOnKeyDown:methodOp(onKeyDown),triggerOnKeyPress:methodOp(onKeyPress),triggerOnKeyUp:onKeyUp,execCommand:function(cmd){if(commands.hasOwnProperty(cmd))
return commands[cmd](this);},findPosH:function(from,amount,unit,visually){var dir=1;if(amount<0){dir=-1;amount=-amount;}
for(var i=0,cur=clipPos(this.doc,from);i<amount;++i){cur=findPosH(this.doc,cur,dir,unit,visually);if(cur.hitSide)break;}
return cur;},moveH:methodOp(function(dir,unit){var cm=this;cm.extendSelectionsBy(function(range){if(cm.display.shift||cm.doc.extend||range.empty())
return findPosH(cm.doc,range.head,dir,unit,cm.options.rtlMoveVisually);else
return dir<0?range.from():range.to();},sel_move);}),deleteH:methodOp(function(dir,unit){var sel=this.doc.sel,doc=this.doc;if(sel.somethingSelected())
doc.replaceSelection("",null,"+delete");else
deleteNearSelection(this,function(range){var other=findPosH(doc,range.head,dir,unit,false);return dir<0?{from:other,to:range.head}:{from:range.head,to:other};});}),findPosV:function(from,amount,unit,goalColumn){var dir=1,x=goalColumn;if(amount<0){dir=-1;amount=-amount;}
for(var i=0,cur=clipPos(this.doc,from);i<amount;++i){var coords=cursorCoords(this,cur,"div");if(x==null)x=coords.left;else coords.left=x;cur=findPosV(this,coords,dir,unit);if(cur.hitSide)break;}
return cur;},moveV:methodOp(function(dir,unit){var cm=this,doc=this.doc,goals=[];var collapse=!cm.display.shift&&!doc.extend&&doc.sel.somethingSelected();doc.extendSelectionsBy(function(range){if(collapse)
return dir<0?range.from():range.to();var headPos=cursorCoords(cm,range.head,"div");if(range.goalColumn!=null)headPos.left=range.goalColumn;goals.push(headPos.left);var pos=findPosV(cm,headPos,dir,unit);if(unit=="page"&&range==doc.sel.primary())
addToScrollPos(cm,null,charCoords(cm,pos,"div").top-headPos.top);return pos;},sel_move);if(goals.length)for(var i=0;i<doc.sel.ranges.length;i++)
doc.sel.ranges[i].goalColumn=goals[i];}),findWordAt:function(pos){var doc=this.doc,line=getLine(doc,pos.line).text;var start=pos.ch,end=pos.ch;if(line){var helper=this.getHelper(pos,"wordChars");if((pos.xRel<0||end==line.length)&&start)--start;else++end;var startChar=line.charAt(start);var check=isWordChar(startChar,helper)?function(ch){return isWordChar(ch,helper);}:/\s/.test(startChar)?function(ch){return/\s/.test(ch);}:function(ch){return!/\s/.test(ch)&&!isWordChar(ch);};while(start>0&&check(line.charAt(start-1)))--start;while(end<line.length&&check(line.charAt(end)))++end;}
return new Range(Pos(pos.line,start),Pos(pos.line,end));},toggleOverwrite:function(value){if(value!=null&&value==this.state.overwrite)return;if(this.state.overwrite=!this.state.overwrite)
addClass(this.display.cursorDiv,"CodeMirror-overwrite");else
rmClass(this.display.cursorDiv,"CodeMirror-overwrite");signal(this,"overwriteToggle",this,this.state.overwrite);},hasFocus:function(){return activeElt()==this.display.input;},scrollTo:methodOp(function(x,y){if(x!=null||y!=null)resolveScrollToPos(this);if(x!=null)this.curOp.scrollLeft=x;if(y!=null)this.curOp.scrollTop=y;}),getScrollInfo:function(){var scroller=this.display.scroller;return{left:scroller.scrollLeft,top:scroller.scrollTop,height:scroller.scrollHeight-scrollGap(this)-this.display.barHeight,width:scroller.scrollWidth-scrollGap(this)-this.display.barWidth,clientHeight:displayHeight(this),clientWidth:displayWidth(this)};},scrollIntoView:methodOp(function(range,margin){if(range==null){range={from:this.doc.sel.primary().head,to:null};if(margin==null)margin=this.options.cursorScrollMargin;}else if(typeof range=="number"){range={from:Pos(range,0),to:null};}else if(range.from==null){range={from:range,to:null};}
if(!range.to)range.to=range.from;range.margin=margin||0;if(range.from.line!=null){resolveScrollToPos(this);this.curOp.scrollToPos=range;}else{var sPos=calculateScrollPos(this,Math.min(range.from.left,range.to.left),Math.min(range.from.top,range.to.top)-range.margin,Math.max(range.from.right,range.to.right),Math.max(range.from.bottom,range.to.bottom)+range.margin);this.scrollTo(sPos.scrollLeft,sPos.scrollTop);}}),setSize:methodOp(function(width,height){var cm=this;function interpret(val){return typeof val=="number"||/^\d+$/.test(String(val))?val+"px":val;}
if(width!=null)cm.display.wrapper.style.width=interpret(width);if(height!=null)cm.display.wrapper.style.height=interpret(height);if(cm.options.lineWrapping)clearLineMeasurementCache(this);var lineNo=cm.display.viewFrom;cm.doc.iter(lineNo,cm.display.viewTo,function(line){if(line.widgets)for(var i=0;i<line.widgets.length;i++)
if(line.widgets[i].noHScroll){regLineChange(cm,lineNo,"widget");break;}
++lineNo;});cm.curOp.forceUpdate=true;signal(cm,"refresh",this);}),operation:function(f){return runInOp(this,f);},refresh:methodOp(function(){var oldHeight=this.display.cachedTextHeight;regChange(this);this.curOp.forceUpdate=true;clearCaches(this);this.scrollTo(this.doc.scrollLeft,this.doc.scrollTop);updateGutterSpace(this);if(oldHeight==null||Math.abs(oldHeight-textHeight(this.display))>.5)
estimateLineHeights(this);signal(this,"refresh",this);}),swapDoc:methodOp(function(doc){var old=this.doc;old.cm=null;attachDoc(this,doc);clearCaches(this);resetInput(this);this.scrollTo(doc.scrollLeft,doc.scrollTop);this.curOp.forceScroll=true;signalLater(this,"swapDoc",this,old);return old;}),getInputField:function(){return this.display.input;},getWrapperElement:function(){return this.display.wrapper;},getScrollerElement:function(){return this.display.scroller;},getGutterElement:function(){return this.display.gutters;}};eventMixin(CodeMirror);var defaults=CodeMirror.defaults={};var optionHandlers=CodeMirror.optionHandlers={};function option(name,deflt,handle,notOnInit){CodeMirror.defaults[name]=deflt;if(handle)optionHandlers[name]=notOnInit?function(cm,val,old){if(old!=Init)handle(cm,val,old);}:handle;}
var Init=CodeMirror.Init={toString:function(){return"CodeMirror.Init";}};option("value","",function(cm,val){cm.setValue(val);},true);option("mode",null,function(cm,val){cm.doc.modeOption=val;loadMode(cm);},true);option("indentUnit",2,loadMode,true);option("indentWithTabs",false);option("smartIndent",true);option("tabSize",4,function(cm){resetModeState(cm);clearCaches(cm);regChange(cm);},true);option("specialChars",/[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(cm,val){cm.options.specialChars=new RegExp(val.source+(val.test("\t")?"":"|\t"),"g");cm.refresh();},true);option("specialCharPlaceholder",defaultSpecialCharPlaceholder,function(cm){cm.refresh();},true);option("electricChars",true);option("rtlMoveVisually",!windows);option("wholeLineUpdateBefore",true);option("theme","default",function(cm){themeChanged(cm);guttersChanged(cm);},true);option("keyMap","default",function(cm,val,old){var next=getKeyMap(val);var prev=old!=CodeMirror.Init&&getKeyMap(old);if(prev&&prev.detach)prev.detach(cm,next);if(next.attach)next.attach(cm,prev||null);});option("extraKeys",null);option("lineWrapping",false,wrappingChanged,true);option("gutters",[],function(cm){setGuttersForLineNumbers(cm.options);guttersChanged(cm);},true);option("fixedGutter",true,function(cm,val){cm.display.gutters.style.left=val?compensateForHScroll(cm.display)+"px":"0";cm.refresh();},true);option("coverGutterNextToScrollbar",false,function(cm){updateScrollbars(cm);},true);option("scrollbarStyle","native",function(cm){initScrollbars(cm);updateScrollbars(cm);cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);},true);option("lineNumbers",false,function(cm){setGuttersForLineNumbers(cm.options);guttersChanged(cm);},true);option("firstLineNumber",1,guttersChanged,true);option("lineNumberFormatter",function(integer){return integer;},guttersChanged,true);option("showCursorWhenSelecting",false,updateSelection,true);option("resetSelectionOnContextMenu",true);option("readOnly",false,function(cm,val){if(val=="nocursor"){onBlur(cm);cm.display.input.blur();cm.display.disabled=true;}else{cm.display.disabled=false;if(!val)resetInput(cm);}});option("disableInput",false,function(cm,val){if(!val)resetInput(cm);},true);option("dragDrop",true);option("cursorBlinkRate",530);option("cursorScrollMargin",0);option("cursorHeight",1,updateSelection,true);option("singleCursorHeightPerLine",true,updateSelection,true);option("workTime",100);option("workDelay",100);option("flattenSpans",true,resetModeState,true);option("addModeClass",false,resetModeState,true);option("pollInterval",100);option("undoDepth",200,function(cm,val){cm.doc.history.undoDepth=val;});option("historyEventDelay",1250);option("viewportMargin",10,function(cm){cm.refresh();},true);option("maxHighlightLength",10000,resetModeState,true);option("moveInputWithCursor",true,function(cm,val){if(!val)cm.display.inputDiv.style.top=cm.display.inputDiv.style.left=0;});option("tabindex",null,function(cm,val){cm.display.input.tabIndex=val||"";});option("autofocus",null);var modes=CodeMirror.modes={},mimeModes=CodeMirror.mimeModes={};CodeMirror.defineMode=function(name,mode){if(!CodeMirror.defaults.mode&&name!="null")CodeMirror.defaults.mode=name;if(arguments.length>2)
mode.dependencies=Array.prototype.slice.call(arguments,2);modes[name]=mode;};CodeMirror.defineMIME=function(mime,spec){mimeModes[mime]=spec;};CodeMirror.resolveMode=function(spec){if(typeof spec=="string"&&mimeModes.hasOwnProperty(spec)){spec=mimeModes[spec];}else if(spec&&typeof spec.name=="string"&&mimeModes.hasOwnProperty(spec.name)){var found=mimeModes[spec.name];if(typeof found=="string")found={name:found};spec=createObj(found,spec);spec.name=found.name;}else if(typeof spec=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(spec)){return CodeMirror.resolveMode("application/xml");}
if(typeof spec=="string")return{name:spec};else return spec||{name:"null"};};CodeMirror.getMode=function(options,spec){var spec=CodeMirror.resolveMode(spec);var mfactory=modes[spec.name];if(!mfactory)return CodeMirror.getMode(options,"text/plain");var modeObj=mfactory(options,spec);if(modeExtensions.hasOwnProperty(spec.name)){var exts=modeExtensions[spec.name];for(var prop in exts){if(!exts.hasOwnProperty(prop))continue;if(modeObj.hasOwnProperty(prop))modeObj["_"+prop]=modeObj[prop];modeObj[prop]=exts[prop];}}
modeObj.name=spec.name;if(spec.helperType)modeObj.helperType=spec.helperType;if(spec.modeProps)for(var prop in spec.modeProps)
modeObj[prop]=spec.modeProps[prop];return modeObj;};CodeMirror.defineMode("null",function(){return{token:function(stream){stream.skipToEnd();}};});CodeMirror.defineMIME("text/plain","null");var modeExtensions=CodeMirror.modeExtensions={};CodeMirror.extendMode=function(mode,properties){var exts=modeExtensions.hasOwnProperty(mode)?modeExtensions[mode]:(modeExtensions[mode]={});copyObj(properties,exts);};CodeMirror.defineExtension=function(name,func){CodeMirror.prototype[name]=func;};CodeMirror.defineDocExtension=function(name,func){Doc.prototype[name]=func;};CodeMirror.defineOption=option;var initHooks=[];CodeMirror.defineInitHook=function(f){initHooks.push(f);};var helpers=CodeMirror.helpers={};CodeMirror.registerHelper=function(type,name,value){if(!helpers.hasOwnProperty(type))helpers[type]=CodeMirror[type]={_global:[]};helpers[type][name]=value;};CodeMirror.registerGlobalHelper=function(type,name,predicate,value){CodeMirror.registerHelper(type,name,value);helpers[type]._global.push({pred:predicate,val:value});};var copyState=CodeMirror.copyState=function(mode,state){if(state===true)return state;if(mode.copyState)return mode.copyState(state);var nstate={};for(var n in state){var val=state[n];if(val instanceof Array)val=val.concat([]);nstate[n]=val;}
return nstate;};var startState=CodeMirror.startState=function(mode,a1,a2){return mode.startState?mode.startState(a1,a2):true;};CodeMirror.innerMode=function(mode,state){while(mode.innerMode){var info=mode.innerMode(state);if(!info||info.mode==mode)break;state=info.state;mode=info.mode;}
return info||{mode:mode,state:state};};var commands=CodeMirror.commands={selectAll:function(cm){cm.setSelection(Pos(cm.firstLine(),0),Pos(cm.lastLine()),sel_dontScroll);},singleSelection:function(cm){cm.setSelection(cm.getCursor("anchor"),cm.getCursor("head"),sel_dontScroll);},killLine:function(cm){deleteNearSelection(cm,function(range){if(range.empty()){var len=getLine(cm.doc,range.head.line).text.length;if(range.head.ch==len&&range.head.line<cm.lastLine())
return{from:range.head,to:Pos(range.head.line+1,0)};else
return{from:range.head,to:Pos(range.head.line,len)};}else{return{from:range.from(),to:range.to()};}});},deleteLine:function(cm){deleteNearSelection(cm,function(range){return{from:Pos(range.from().line,0),to:clipPos(cm.doc,Pos(range.to().line+1,0))};});},delLineLeft:function(cm){deleteNearSelection(cm,function(range){return{from:Pos(range.from().line,0),to:range.from()};});},delWrappedLineLeft:function(cm){deleteNearSelection(cm,function(range){var top=cm.charCoords(range.head,"div").top+5;var leftPos=cm.coordsChar({left:0,top:top},"div");return{from:leftPos,to:range.from()};});},delWrappedLineRight:function(cm){deleteNearSelection(cm,function(range){var top=cm.charCoords(range.head,"div").top+5;var rightPos=cm.coordsChar({left:cm.display.lineDiv.offsetWidth+100,top:top},"div");return{from:range.from(),to:rightPos};});},undo:function(cm){cm.undo();},redo:function(cm){cm.redo();},undoSelection:function(cm){cm.undoSelection();},redoSelection:function(cm){cm.redoSelection();},goDocStart:function(cm){cm.extendSelection(Pos(cm.firstLine(),0));},goDocEnd:function(cm){cm.extendSelection(Pos(cm.lastLine()));},goLineStart:function(cm){cm.extendSelectionsBy(function(range){return lineStart(cm,range.head.line);},{origin:"+move",bias:1});},goLineStartSmart:function(cm){cm.extendSelectionsBy(function(range){return lineStartSmart(cm,range.head);},{origin:"+move",bias:1});},goLineEnd:function(cm){cm.extendSelectionsBy(function(range){return lineEnd(cm,range.head.line);},{origin:"+move",bias:-1});},goLineRight:function(cm){cm.extendSelectionsBy(function(range){var top=cm.charCoords(range.head,"div").top+5;return cm.coordsChar({left:cm.display.lineDiv.offsetWidth+100,top:top},"div");},sel_move);},goLineLeft:function(cm){cm.extendSelectionsBy(function(range){var top=cm.charCoords(range.head,"div").top+5;return cm.coordsChar({left:0,top:top},"div");},sel_move);},goLineLeftSmart:function(cm){cm.extendSelectionsBy(function(range){var top=cm.charCoords(range.head,"div").top+5;var pos=cm.coordsChar({left:0,top:top},"div");if(pos.ch<cm.getLine(pos.line).search(/\S/))return lineStartSmart(cm,range.head);return pos;},sel_move);},goLineUp:function(cm){cm.moveV(-1,"line");},goLineDown:function(cm){cm.moveV(1,"line");},goPageUp:function(cm){cm.moveV(-1,"page");},goPageDown:function(cm){cm.moveV(1,"page");},goCharLeft:function(cm){cm.moveH(-1,"char");},goCharRight:function(cm){cm.moveH(1,"char");},goColumnLeft:function(cm){cm.moveH(-1,"column");},goColumnRight:function(cm){cm.moveH(1,"column");},goWordLeft:function(cm){cm.moveH(-1,"word");},goGroupRight:function(cm){cm.moveH(1,"group");},goGroupLeft:function(cm){cm.moveH(-1,"group");},goWordRight:function(cm){cm.moveH(1,"word");},delCharBefore:function(cm){cm.deleteH(-1,"char");},delCharAfter:function(cm){cm.deleteH(1,"char");},delWordBefore:function(cm){cm.deleteH(-1,"word");},delWordAfter:function(cm){cm.deleteH(1,"word");},delGroupBefore:function(cm){cm.deleteH(-1,"group");},delGroupAfter:function(cm){cm.deleteH(1,"group");},indentAuto:function(cm){cm.indentSelection("smart");},indentMore:function(cm){cm.indentSelection("add");},indentLess:function(cm){cm.indentSelection("subtract");},insertTab:function(cm){cm.replaceSelection("\t");},insertSoftTab:function(cm){var spaces=[],ranges=cm.listSelections(),tabSize=cm.options.tabSize;for(var i=0;i<ranges.length;i++){var pos=ranges[i].from();var col=countColumn(cm.getLine(pos.line),pos.ch,tabSize);spaces.push(new Array(tabSize-col%tabSize+1).join(" "));}
cm.replaceSelections(spaces);},defaultTab:function(cm){if(cm.somethingSelected())cm.indentSelection("add");else cm.execCommand("insertTab");},transposeChars:function(cm){runInOp(cm,function(){var ranges=cm.listSelections(),newSel=[];for(var i=0;i<ranges.length;i++){var cur=ranges[i].head,line=getLine(cm.doc,cur.line).text;if(line){if(cur.ch==line.length)cur=new Pos(cur.line,cur.ch-1);if(cur.ch>0){cur=new Pos(cur.line,cur.ch+1);cm.replaceRange(line.charAt(cur.ch-1)+line.charAt(cur.ch-2),Pos(cur.line,cur.ch-2),cur,"+transpose");}else if(cur.line>cm.doc.first){var prev=getLine(cm.doc,cur.line-1).text;if(prev)
cm.replaceRange(line.charAt(0)+"\n"+prev.charAt(prev.length-1),Pos(cur.line-1,prev.length-1),Pos(cur.line,1),"+transpose");}}
newSel.push(new Range(cur,cur));}
cm.setSelections(newSel);});},newlineAndIndent:function(cm){runInOp(cm,function(){var len=cm.listSelections().length;for(var i=0;i<len;i++){var range=cm.listSelections()[i];cm.replaceRange("\n",range.anchor,range.head,"+input");cm.indentLine(range.from().line+1,null,true);ensureCursorVisible(cm);}});},toggleOverwrite:function(cm){cm.toggleOverwrite();}};var keyMap=CodeMirror.keyMap={};keyMap.basic={"Left":"goCharLeft","Right":"goCharRight","Up":"goLineUp","Down":"goLineDown","End":"goLineEnd","Home":"goLineStartSmart","PageUp":"goPageUp","PageDown":"goPageDown","Delete":"delCharAfter","Backspace":"delCharBefore","Shift-Backspace":"delCharBefore","Tab":"defaultTab","Shift-Tab":"indentAuto","Enter":"newlineAndIndent","Insert":"toggleOverwrite","Esc":"singleSelection"};keyMap.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"};keyMap.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"};keyMap.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]};keyMap["default"]=mac?keyMap.macDefault:keyMap.pcDefault;function normalizeKeyName(name){var parts=name.split(/-(?!$)/),name=parts[parts.length-1];var alt,ctrl,shift,cmd;for(var i=0;i<parts.length-1;i++){var mod=parts[i];if(/^(cmd|meta|m)$/i.test(mod))cmd=true;else if(/^a(lt)?$/i.test(mod))alt=true;else if(/^(c|ctrl|control)$/i.test(mod))ctrl=true;else if(/^s(hift)$/i.test(mod))shift=true;else throw new Error("Unrecognized modifier name: "+mod);}
if(alt)name="Alt-"+name;if(ctrl)name="Ctrl-"+name;if(cmd)name="Cmd-"+name;if(shift)name="Shift-"+name;return name;}
CodeMirror.normalizeKeyMap=function(keymap){var copy={};for(var keyname in keymap)if(keymap.hasOwnProperty(keyname)){var value=keymap[keyname];if(/^(name|fallthrough|(de|at)tach)$/.test(keyname))continue;if(value=="..."){delete keymap[keyname];continue;}
var keys=map(keyname.split(" "),normalizeKeyName);for(var i=0;i<keys.length;i++){var val,name;if(i==keys.length-1){name=keyname;val=value;}else{name=keys.slice(0,i+1).join(" ");val="...";}
var prev=copy[name];if(!prev)copy[name]=val;else if(prev!=val)throw new Error("Inconsistent bindings for "+name);}
delete keymap[keyname];}
for(var prop in copy)keymap[prop]=copy[prop];return keymap;};var lookupKey=CodeMirror.lookupKey=function(key,map,handle,context){map=getKeyMap(map);var found=map.call?map.call(key,context):map[key];if(found===false)return"nothing";if(found==="...")return"multi";if(found!=null&&handle(found))return"handled";if(map.fallthrough){if(Object.prototype.toString.call(map.fallthrough)!="[object Array]")
return lookupKey(key,map.fallthrough,handle,context);for(var i=0;i<map.fallthrough.length;i++){var result=lookupKey(key,map.fallthrough[i],handle,context);if(result)return result;}}};var isModifierKey=CodeMirror.isModifierKey=function(value){var name=typeof value=="string"?value:keyNames[value.keyCode];return name=="Ctrl"||name=="Alt"||name=="Shift"||name=="Mod";};var keyName=CodeMirror.keyName=function(event,noShift){if(presto&&event.keyCode==34&&event["char"])return false;var base=keyNames[event.keyCode],name=base;if(name==null||event.altGraphKey)return false;if(event.altKey&&base!="Alt")name="Alt-"+name;if((flipCtrlCmd?event.metaKey:event.ctrlKey)&&base!="Ctrl")name="Ctrl-"+name;if((flipCtrlCmd?event.ctrlKey:event.metaKey)&&base!="Cmd")name="Cmd-"+name;if(!noShift&&event.shiftKey&&base!="Shift")name="Shift-"+name;return name;};function getKeyMap(val){return typeof val=="string"?keyMap[val]:val;}
CodeMirror.fromTextArea=function(textarea,options){if(!options)options={};options.value=textarea.value;if(!options.tabindex&&textarea.tabindex)
options.tabindex=textarea.tabindex;if(!options.placeholder&&textarea.placeholder)
options.placeholder=textarea.placeholder;if(options.autofocus==null){var hasFocus=activeElt();options.autofocus=hasFocus==textarea||textarea.getAttribute("autofocus")!=null&&hasFocus==document.body;}
function save(){textarea.value=cm.getValue();}
if(textarea.form){on(textarea.form,"submit",save);if(!options.leaveSubmitMethodAlone){var form=textarea.form,realSubmit=form.submit;try{var wrappedSubmit=form.submit=function(){save();form.submit=realSubmit;form.submit();form.submit=wrappedSubmit;};}catch(e){}}}
textarea.style.display="none";var cm=CodeMirror(function(node){textarea.parentNode.insertBefore(node,textarea.nextSibling);},options);cm.save=save;cm.getTextArea=function(){return textarea;};cm.toTextArea=function(){cm.toTextArea=isNaN;save();textarea.parentNode.removeChild(cm.getWrapperElement());textarea.style.display="";if(textarea.form){off(textarea.form,"submit",save);if(typeof textarea.form.submit=="function")
textarea.form.submit=realSubmit;}};return cm;};var StringStream=CodeMirror.StringStream=function(string,tabSize){this.pos=this.start=0;this.string=string;this.tabSize=tabSize||8;this.lastColumnPos=this.lastColumnValue=0;this.lineStart=0;};StringStream.prototype={eol:function(){return this.pos>=this.string.length;},sol:function(){return this.pos==this.lineStart;},peek:function(){return this.string.charAt(this.pos)||undefined;},next:function(){if(this.pos<this.string.length)
return this.string.charAt(this.pos++);},eat:function(match){var ch=this.string.charAt(this.pos);if(typeof match=="string")var ok=ch==match;else var ok=ch&&(match.test?match.test(ch):match(ch));if(ok){++this.pos;return ch;}},eatWhile:function(match){var start=this.pos;while(this.eat(match)){}
return this.pos>start;},eatSpace:function(){var start=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>start;},skipToEnd:function(){this.pos=this.string.length;},skipTo:function(ch){var found=this.string.indexOf(ch,this.pos);if(found>-1){this.pos=found;return true;}},backUp:function(n){this.pos-=n;},column:function(){if(this.lastColumnPos<this.start){this.lastColumnValue=countColumn(this.string,this.start,this.tabSize,this.lastColumnPos,this.lastColumnValue);this.lastColumnPos=this.start;}
return this.lastColumnValue-(this.lineStart?countColumn(this.string,this.lineStart,this.tabSize):0);},indentation:function(){return countColumn(this.string,null,this.tabSize)-
(this.lineStart?countColumn(this.string,this.lineStart,this.tabSize):0);},match:function(pattern,consume,caseInsensitive){if(typeof pattern=="string"){var cased=function(str){return caseInsensitive?str.toLowerCase():str;};var substr=this.string.substr(this.pos,pattern.length);if(cased(substr)==cased(pattern)){if(consume!==false)this.pos+=pattern.length;return true;}}else{var match=this.string.slice(this.pos).match(pattern);if(match&&match.index>0)return null;if(match&&consume!==false)this.pos+=match[0].length;return match;}},current:function(){return this.string.slice(this.start,this.pos);},hideFirstChars:function(n,inner){this.lineStart+=n;try{return inner();}
finally{this.lineStart-=n;}}};var TextMarker=CodeMirror.TextMarker=function(doc,type){this.lines=[];this.type=type;this.doc=doc;};eventMixin(TextMarker);TextMarker.prototype.clear=function(){if(this.explicitlyCleared)return;var cm=this.doc.cm,withOp=cm&&!cm.curOp;if(withOp)startOperation(cm);if(hasHandler(this,"clear")){var found=this.find();if(found)signalLater(this,"clear",found.from,found.to);}
var min=null,max=null;for(var i=0;i<this.lines.length;++i){var line=this.lines[i];var span=getMarkedSpanFor(line.markedSpans,this);if(cm&&!this.collapsed)regLineChange(cm,lineNo(line),"text");else if(cm){if(span.to!=null)max=lineNo(line);if(span.from!=null)min=lineNo(line);}
line.markedSpans=removeMarkedSpan(line.markedSpans,span);if(span.from==null&&this.collapsed&&!lineIsHidden(this.doc,line)&&cm)
updateLineHeight(line,textHeight(cm.display));}
if(cm&&this.collapsed&&!cm.options.lineWrapping)for(var i=0;i<this.lines.length;++i){var visual=visualLine(this.lines[i]),len=lineLength(visual);if(len>cm.display.maxLineLength){cm.display.maxLine=visual;cm.display.maxLineLength=len;cm.display.maxLineChanged=true;}}
if(min!=null&&cm&&this.collapsed)regChange(cm,min,max+1);this.lines.length=0;this.explicitlyCleared=true;if(this.atomic&&this.doc.cantEdit){this.doc.cantEdit=false;if(cm)reCheckSelection(cm.doc);}
if(cm)signalLater(cm,"markerCleared",cm,this);if(withOp)endOperation(cm);if(this.parent)this.parent.clear();};TextMarker.prototype.find=function(side,lineObj){if(side==null&&this.type=="bookmark")side=1;var from,to;for(var i=0;i<this.lines.length;++i){var line=this.lines[i];var span=getMarkedSpanFor(line.markedSpans,this);if(span.from!=null){from=Pos(lineObj?line:lineNo(line),span.from);if(side==-1)return from;}
if(span.to!=null){to=Pos(lineObj?line:lineNo(line),span.to);if(side==1)return to;}}
return from&&{from:from,to:to};};TextMarker.prototype.changed=function(){var pos=this.find(-1,true),widget=this,cm=this.doc.cm;if(!pos||!cm)return;runInOp(cm,function(){var line=pos.line,lineN=lineNo(pos.line);var view=findViewForLine(cm,lineN);if(view){clearLineMeasurementCacheFor(view);cm.curOp.selectionChanged=cm.curOp.forceUpdate=true;}
cm.curOp.updateMaxLine=true;if(!lineIsHidden(widget.doc,line)&&widget.height!=null){var oldHeight=widget.height;widget.height=null;var dHeight=widgetHeight(widget)-oldHeight;if(dHeight)
updateLineHeight(line,line.height+dHeight);}});};TextMarker.prototype.attachLine=function(line){if(!this.lines.length&&this.doc.cm){var op=this.doc.cm.curOp;if(!op.maybeHiddenMarkers||indexOf(op.maybeHiddenMarkers,this)==-1)
(op.maybeUnhiddenMarkers||(op.maybeUnhiddenMarkers=[])).push(this);}
this.lines.push(line);};TextMarker.prototype.detachLine=function(line){this.lines.splice(indexOf(this.lines,line),1);if(!this.lines.length&&this.doc.cm){var op=this.doc.cm.curOp;(op.maybeHiddenMarkers||(op.maybeHiddenMarkers=[])).push(this);}};var nextMarkerId=0;function markText(doc,from,to,options,type){if(options&&options.shared)return markTextShared(doc,from,to,options,type);if(doc.cm&&!doc.cm.curOp)return operation(doc.cm,markText)(doc,from,to,options,type);var marker=new TextMarker(doc,type),diff=cmp(from,to);if(options)copyObj(options,marker,false);if(diff>0||diff==0&&marker.clearWhenEmpty!==false)
return marker;if(marker.replacedWith){marker.collapsed=true;marker.widgetNode=elt("span",[marker.replacedWith],"CodeMirror-widget");if(!options.handleMouseEvents)marker.widgetNode.setAttribute("cm-ignore-events","true");if(options.insertLeft)marker.widgetNode.insertLeft=true;}
if(marker.collapsed){if(conflictingCollapsedRange(doc,from.line,from,to,marker)||from.line!=to.line&&conflictingCollapsedRange(doc,to.line,from,to,marker))
throw new Error("Inserting collapsed marker partially overlapping an existing one");sawCollapsedSpans=true;}
if(marker.addToHistory)
addChangeToHistory(doc,{from:from,to:to,origin:"markText"},doc.sel,NaN);var curLine=from.line,cm=doc.cm,updateMaxLine;doc.iter(curLine,to.line+1,function(line){if(cm&&marker.collapsed&&!cm.options.lineWrapping&&visualLine(line)==cm.display.maxLine)
updateMaxLine=true;if(marker.collapsed&&curLine!=from.line)updateLineHeight(line,0);addMarkedSpan(line,new MarkedSpan(marker,curLine==from.line?from.ch:null,curLine==to.line?to.ch:null));++curLine;});if(marker.collapsed)doc.iter(from.line,to.line+1,function(line){if(lineIsHidden(doc,line))updateLineHeight(line,0);});if(marker.clearOnEnter)on(marker,"beforeCursorEnter",function(){marker.clear();});if(marker.readOnly){sawReadOnlySpans=true;if(doc.history.done.length||doc.history.undone.length)
doc.clearHistory();}
if(marker.collapsed){marker.id=++nextMarkerId;marker.atomic=true;}
if(cm){if(updateMaxLine)cm.curOp.updateMaxLine=true;if(marker.collapsed)
regChange(cm,from.line,to.line+1);else if(marker.className||marker.title||marker.startStyle||marker.endStyle||marker.css)
for(var i=from.line;i<=to.line;i++)regLineChange(cm,i,"text");if(marker.atomic)reCheckSelection(cm.doc);signalLater(cm,"markerAdded",cm,marker);}
return marker;}
var SharedTextMarker=CodeMirror.SharedTextMarker=function(markers,primary){this.markers=markers;this.primary=primary;for(var i=0;i<markers.length;++i)
markers[i].parent=this;};eventMixin(SharedTextMarker);SharedTextMarker.prototype.clear=function(){if(this.explicitlyCleared)return;this.explicitlyCleared=true;for(var i=0;i<this.markers.length;++i)
this.markers[i].clear();signalLater(this,"clear");};SharedTextMarker.prototype.find=function(side,lineObj){return this.primary.find(side,lineObj);};function markTextShared(doc,from,to,options,type){options=copyObj(options);options.shared=false;var markers=[markText(doc,from,to,options,type)],primary=markers[0];var widget=options.widgetNode;linkedDocs(doc,function(doc){if(widget)options.widgetNode=widget.cloneNode(true);markers.push(markText(doc,clipPos(doc,from),clipPos(doc,to),options,type));for(var i=0;i<doc.linked.length;++i)
if(doc.linked[i].isParent)return;primary=lst(markers);});return new SharedTextMarker(markers,primary);}
function findSharedMarkers(doc){return doc.findMarks(Pos(doc.first,0),doc.clipPos(Pos(doc.lastLine())),function(m){return m.parent;});}
function copySharedMarkers(doc,markers){for(var i=0;i<markers.length;i++){var marker=markers[i],pos=marker.find();var mFrom=doc.clipPos(pos.from),mTo=doc.clipPos(pos.to);if(cmp(mFrom,mTo)){var subMark=markText(doc,mFrom,mTo,marker.primary,marker.primary.type);marker.markers.push(subMark);subMark.parent=marker;}}}
function detachSharedMarkers(markers){for(var i=0;i<markers.length;i++){var marker=markers[i],linked=[marker.primary.doc];;linkedDocs(marker.primary.doc,function(d){linked.push(d);});for(var j=0;j<marker.markers.length;j++){var subMarker=marker.markers[j];if(indexOf(linked,subMarker.doc)==-1){subMarker.parent=null;marker.markers.splice(j--,1);}}}}
function MarkedSpan(marker,from,to){this.marker=marker;this.from=from;this.to=to;}
function getMarkedSpanFor(spans,marker){if(spans)for(var i=0;i<spans.length;++i){var span=spans[i];if(span.marker==marker)return span;}}
function removeMarkedSpan(spans,span){for(var r,i=0;i<spans.length;++i)
if(spans[i]!=span)(r||(r=[])).push(spans[i]);return r;}
function addMarkedSpan(line,span){line.markedSpans=line.markedSpans?line.markedSpans.concat([span]):[span];span.marker.attachLine(line);}
function markedSpansBefore(old,startCh,isInsert){if(old)for(var i=0,nw;i<old.length;++i){var span=old[i],marker=span.marker;var startsBefore=span.from==null||(marker.inclusiveLeft?span.from<=startCh:span.from<startCh);if(startsBefore||span.from==startCh&&marker.type=="bookmark"&&(!isInsert||!span.marker.insertLeft)){var endsAfter=span.to==null||(marker.inclusiveRight?span.to>=startCh:span.to>startCh);(nw||(nw=[])).push(new MarkedSpan(marker,span.from,endsAfter?null:span.to));}}
return nw;}
function markedSpansAfter(old,endCh,isInsert){if(old)for(var i=0,nw;i<old.length;++i){var span=old[i],marker=span.marker;var endsAfter=span.to==null||(marker.inclusiveRight?span.to>=endCh:span.to>endCh);if(endsAfter||span.from==endCh&&marker.type=="bookmark"&&(!isInsert||span.marker.insertLeft)){var startsBefore=span.from==null||(marker.inclusiveLeft?span.from<=endCh:span.from<endCh);(nw||(nw=[])).push(new MarkedSpan(marker,startsBefore?null:span.from-endCh,span.to==null?null:span.to-endCh));}}
return nw;}
function stretchSpansOverChange(doc,change){if(change.full)return null;var oldFirst=isLine(doc,change.from.line)&&getLine(doc,change.from.line).markedSpans;var oldLast=isLine(doc,change.to.line)&&getLine(doc,change.to.line).markedSpans;if(!oldFirst&&!oldLast)return null;var startCh=change.from.ch,endCh=change.to.ch,isInsert=cmp(change.from,change.to)==0;var first=markedSpansBefore(oldFirst,startCh,isInsert);var last=markedSpansAfter(oldLast,endCh,isInsert);var sameLine=change.text.length==1,offset=lst(change.text).length+(sameLine?startCh:0);if(first){for(var i=0;i<first.length;++i){var span=first[i];if(span.to==null){var found=getMarkedSpanFor(last,span.marker);if(!found)span.to=startCh;else if(sameLine)span.to=found.to==null?null:found.to+offset;}}}
if(last){for(var i=0;i<last.length;++i){var span=last[i];if(span.to!=null)span.to+=offset;if(span.from==null){var found=getMarkedSpanFor(first,span.marker);if(!found){span.from=offset;if(sameLine)(first||(first=[])).push(span);}}else{span.from+=offset;if(sameLine)(first||(first=[])).push(span);}}}
if(first)first=clearEmptySpans(first);if(last&&last!=first)last=clearEmptySpans(last);var newMarkers=[first];if(!sameLine){var gap=change.text.length-2,gapMarkers;if(gap>0&&first)
for(var i=0;i<first.length;++i)
if(first[i].to==null)
(gapMarkers||(gapMarkers=[])).push(new MarkedSpan(first[i].marker,null,null));for(var i=0;i<gap;++i)
newMarkers.push(gapMarkers);newMarkers.push(last);}
return newMarkers;}
function clearEmptySpans(spans){for(var i=0;i<spans.length;++i){var span=spans[i];if(span.from!=null&&span.from==span.to&&span.marker.clearWhenEmpty!==false)
spans.splice(i--,1);}
if(!spans.length)return null;return spans;}
function mergeOldSpans(doc,change){var old=getOldSpans(doc,change);var stretched=stretchSpansOverChange(doc,change);if(!old)return stretched;if(!stretched)return old;for(var i=0;i<old.length;++i){var oldCur=old[i],stretchCur=stretched[i];if(oldCur&&stretchCur){spans:for(var j=0;j<stretchCur.length;++j){var span=stretchCur[j];for(var k=0;k<oldCur.length;++k)
if(oldCur[k].marker==span.marker)continue spans;oldCur.push(span);}}else if(stretchCur){old[i]=stretchCur;}}
return old;}
function removeReadOnlyRanges(doc,from,to){var markers=null;doc.iter(from.line,to.line+1,function(line){if(line.markedSpans)for(var i=0;i<line.markedSpans.length;++i){var mark=line.markedSpans[i].marker;if(mark.readOnly&&(!markers||indexOf(markers,mark)==-1))
(markers||(markers=[])).push(mark);}});if(!markers)return null;var parts=[{from:from,to:to}];for(var i=0;i<markers.length;++i){var mk=markers[i],m=mk.find(0);for(var j=0;j<parts.length;++j){var p=parts[j];if(cmp(p.to,m.from)<0||cmp(p.from,m.to)>0)continue;var newParts=[j,1],dfrom=cmp(p.from,m.from),dto=cmp(p.to,m.to);if(dfrom<0||!mk.inclusiveLeft&&!dfrom)
newParts.push({from:p.from,to:m.from});if(dto>0||!mk.inclusiveRight&&!dto)
newParts.push({from:m.to,to:p.to});parts.splice.apply(parts,newParts);j+=newParts.length-1;}}
return parts;}
function detachMarkedSpans(line){var spans=line.markedSpans;if(!spans)return;for(var i=0;i<spans.length;++i)
spans[i].marker.detachLine(line);line.markedSpans=null;}
function attachMarkedSpans(line,spans){if(!spans)return;for(var i=0;i<spans.length;++i)
spans[i].marker.attachLine(line);line.markedSpans=spans;}
function extraLeft(marker){return marker.inclusiveLeft?-1:0;}
function extraRight(marker){return marker.inclusiveRight?1:0;}
function compareCollapsedMarkers(a,b){var lenDiff=a.lines.length-b.lines.length;if(lenDiff!=0)return lenDiff;var aPos=a.find(),bPos=b.find();var fromCmp=cmp(aPos.from,bPos.from)||extraLeft(a)-extraLeft(b);if(fromCmp)return-fromCmp;var toCmp=cmp(aPos.to,bPos.to)||extraRight(a)-extraRight(b);if(toCmp)return toCmp;return b.id-a.id;}
function collapsedSpanAtSide(line,start){var sps=sawCollapsedSpans&&line.markedSpans,found;if(sps)for(var sp,i=0;i<sps.length;++i){sp=sps[i];if(sp.marker.collapsed&&(start?sp.from:sp.to)==null&&(!found||compareCollapsedMarkers(found,sp.marker)<0))
found=sp.marker;}
return found;}
function collapsedSpanAtStart(line){return collapsedSpanAtSide(line,true);}
function collapsedSpanAtEnd(line){return collapsedSpanAtSide(line,false);}
function conflictingCollapsedRange(doc,lineNo,from,to,marker){var line=getLine(doc,lineNo);var sps=sawCollapsedSpans&&line.markedSpans;if(sps)for(var i=0;i<sps.length;++i){var sp=sps[i];if(!sp.marker.collapsed)continue;var found=sp.marker.find(0);var fromCmp=cmp(found.from,from)||extraLeft(sp.marker)-extraLeft(marker);var toCmp=cmp(found.to,to)||extraRight(sp.marker)-extraRight(marker);if(fromCmp>=0&&toCmp<=0||fromCmp<=0&&toCmp>=0)continue;if(fromCmp<=0&&(cmp(found.to,from)>0||(sp.marker.inclusiveRight&&marker.inclusiveLeft))||fromCmp>=0&&(cmp(found.from,to)<0||(sp.marker.inclusiveLeft&&marker.inclusiveRight)))
return true;}}
function visualLine(line){var merged;while(merged=collapsedSpanAtStart(line))
line=merged.find(-1,true).line;return line;}
function visualLineContinued(line){var merged,lines;while(merged=collapsedSpanAtEnd(line)){line=merged.find(1,true).line;(lines||(lines=[])).push(line);}
return lines;}
function visualLineNo(doc,lineN){var line=getLine(doc,lineN),vis=visualLine(line);if(line==vis)return lineN;return lineNo(vis);}
function visualLineEndNo(doc,lineN){if(lineN>doc.lastLine())return lineN;var line=getLine(doc,lineN),merged;if(!lineIsHidden(doc,line))return lineN;while(merged=collapsedSpanAtEnd(line))
line=merged.find(1,true).line;return lineNo(line)+1;}
function lineIsHidden(doc,line){var sps=sawCollapsedSpans&&line.markedSpans;if(sps)for(var sp,i=0;i<sps.length;++i){sp=sps[i];if(!sp.marker.collapsed)continue;if(sp.from==null)return true;if(sp.marker.widgetNode)continue;if(sp.from==0&&sp.marker.inclusiveLeft&&lineIsHiddenInner(doc,line,sp))
return true;}}
function lineIsHiddenInner(doc,line,span){if(span.to==null){var end=span.marker.find(1,true);return lineIsHiddenInner(doc,end.line,getMarkedSpanFor(end.line.markedSpans,span.marker));}
if(span.marker.inclusiveRight&&span.to==line.text.length)
return true;for(var sp,i=0;i<line.markedSpans.length;++i){sp=line.markedSpans[i];if(sp.marker.collapsed&&!sp.marker.widgetNode&&sp.from==span.to&&(sp.to==null||sp.to!=span.from)&&(sp.marker.inclusiveLeft||span.marker.inclusiveRight)&&lineIsHiddenInner(doc,line,sp))return true;}}
var LineWidget=CodeMirror.LineWidget=function(cm,node,options){if(options)for(var opt in options)if(options.hasOwnProperty(opt))
this[opt]=options[opt];this.cm=cm;this.node=node;};eventMixin(LineWidget);function adjustScrollWhenAboveVisible(cm,line,diff){if(heightAtLine(line)<((cm.curOp&&cm.curOp.scrollTop)||cm.doc.scrollTop))
addToScrollPos(cm,null,diff);}
LineWidget.prototype.clear=function(){var cm=this.cm,ws=this.line.widgets,line=this.line,no=lineNo(line);if(no==null||!ws)return;for(var i=0;i<ws.length;++i)if(ws[i]==this)ws.splice(i--,1);if(!ws.length)line.widgets=null;var height=widgetHeight(this);runInOp(cm,function(){adjustScrollWhenAboveVisible(cm,line,-height);regLineChange(cm,no,"widget");updateLineHeight(line,Math.max(0,line.height-height));});};LineWidget.prototype.changed=function(){var oldH=this.height,cm=this.cm,line=this.line;this.height=null;var diff=widgetHeight(this)-oldH;if(!diff)return;runInOp(cm,function(){cm.curOp.forceUpdate=true;adjustScrollWhenAboveVisible(cm,line,diff);updateLineHeight(line,line.height+diff);});};function widgetHeight(widget){if(widget.height!=null)return widget.height;if(!contains(document.body,widget.node)){var parentStyle="position: relative;";if(widget.coverGutter)
parentStyle+="margin-left: -"+widget.cm.display.gutters.offsetWidth+"px;";if(widget.noHScroll)
parentStyle+="width: "+widget.cm.display.wrapper.clientWidth+"px;";removeChildrenAndAdd(widget.cm.display.measure,elt("div",[widget.node],null,parentStyle));}
return widget.height=widget.node.offsetHeight;}
function addLineWidget(cm,handle,node,options){var widget=new LineWidget(cm,node,options);if(widget.noHScroll)cm.display.alignWidgets=true;changeLine(cm.doc,handle,"widget",function(line){var widgets=line.widgets||(line.widgets=[]);if(widget.insertAt==null)widgets.push(widget);else widgets.splice(Math.min(widgets.length-1,Math.max(0,widget.insertAt)),0,widget);widget.line=line;if(!lineIsHidden(cm.doc,line)){var aboveVisible=heightAtLine(line)<cm.doc.scrollTop;updateLineHeight(line,line.height+widgetHeight(widget));if(aboveVisible)addToScrollPos(cm,null,widget.height);cm.curOp.forceUpdate=true;}
return true;});return widget;}
var Line=CodeMirror.Line=function(text,markedSpans,estimateHeight){this.text=text;attachMarkedSpans(this,markedSpans);this.height=estimateHeight?estimateHeight(this):1;};eventMixin(Line);Line.prototype.lineNo=function(){return lineNo(this);};function updateLine(line,text,markedSpans,estimateHeight){line.text=text;if(line.stateAfter)line.stateAfter=null;if(line.styles)line.styles=null;if(line.order!=null)line.order=null;detachMarkedSpans(line);attachMarkedSpans(line,markedSpans);var estHeight=estimateHeight?estimateHeight(line):1;if(estHeight!=line.height)updateLineHeight(line,estHeight);}
function cleanUpLine(line){line.parent=null;detachMarkedSpans(line);}
function extractLineClasses(type,output){if(type)for(;;){var lineClass=type.match(/(?:^|\s+)line-(background-)?(\S+)/);if(!lineClass)break;type=type.slice(0,lineClass.index)+type.slice(lineClass.index+lineClass[0].length);var prop=lineClass[1]?"bgClass":"textClass";if(output[prop]==null)
output[prop]=lineClass[2];else if(!(new RegExp("(?:^|\s)"+lineClass[2]+"(?:$|\s)")).test(output[prop]))
output[prop]+=" "+lineClass[2];}
return type;}
function callBlankLine(mode,state){if(mode.blankLine)return mode.blankLine(state);if(!mode.innerMode)return;var inner=CodeMirror.innerMode(mode,state);if(inner.mode.blankLine)return inner.mode.blankLine(inner.state);}
function readToken(mode,stream,state,inner){for(var i=0;i<10;i++){if(inner)inner[0]=CodeMirror.innerMode(mode,state).mode;var style=mode.token(stream,state);if(stream.pos>stream.start)return style;}
throw new Error("Mode "+mode.name+" failed to advance stream.");}
function takeToken(cm,pos,precise,asArray){function getObj(copy){return{start:stream.start,end:stream.pos,string:stream.current(),type:style||null,state:copy?copyState(doc.mode,state):state};}
var doc=cm.doc,mode=doc.mode,style;pos=clipPos(doc,pos);var line=getLine(doc,pos.line),state=getStateBefore(cm,pos.line,precise);var stream=new StringStream(line.text,cm.options.tabSize),tokens;if(asArray)tokens=[];while((asArray||stream.pos<pos.ch)&&!stream.eol()){stream.start=stream.pos;style=readToken(mode,stream,state);if(asArray)tokens.push(getObj(true));}
return asArray?tokens:getObj();}
function runMode(cm,text,mode,state,f,lineClasses,forceToEnd){var flattenSpans=mode.flattenSpans;if(flattenSpans==null)flattenSpans=cm.options.flattenSpans;var curStart=0,curStyle=null;var stream=new StringStream(text,cm.options.tabSize),style;var inner=cm.options.addModeClass&&[null];if(text=="")extractLineClasses(callBlankLine(mode,state),lineClasses);while(!stream.eol()){if(stream.pos>cm.options.maxHighlightLength){flattenSpans=false;if(forceToEnd)processLine(cm,text,state,stream.pos);stream.pos=text.length;style=null;}else{style=extractLineClasses(readToken(mode,stream,state,inner),lineClasses);}
if(inner){var mName=inner[0].name;if(mName)style="m-"+(style?mName+" "+style:mName);}
if(!flattenSpans||curStyle!=style){while(curStart<stream.start){curStart=Math.min(stream.start,curStart+50000);f(curStart,curStyle);}
curStyle=style;}
stream.start=stream.pos;}
while(curStart<stream.pos){var pos=Math.min(stream.pos,curStart+50000);f(pos,curStyle);curStart=pos;}}
function highlightLine(cm,line,state,forceToEnd){var st=[cm.state.modeGen],lineClasses={};runMode(cm,line.text,cm.doc.mode,state,function(end,style){st.push(end,style);},lineClasses,forceToEnd);for(var o=0;o<cm.state.overlays.length;++o){var overlay=cm.state.overlays[o],i=1,at=0;runMode(cm,line.text,overlay.mode,true,function(end,style){var start=i;while(at<end){var i_end=st[i];if(i_end>end)
st.splice(i,1,end,st[i+1],i_end);i+=2;at=Math.min(end,i_end);}
if(!style)return;if(overlay.opaque){st.splice(start,i-start,end,"cm-overlay "+style);i=start+2;}else{for(;start<i;start+=2){var cur=st[start+1];st[start+1]=(cur?cur+" ":"")+"cm-overlay "+style;}}},lineClasses);}
return{styles:st,classes:lineClasses.bgClass||lineClasses.textClass?lineClasses:null};}
function getLineStyles(cm,line,updateFrontier){if(!line.styles||line.styles[0]!=cm.state.modeGen){var result=highlightLine(cm,line,line.stateAfter=getStateBefore(cm,lineNo(line)));line.styles=result.styles;if(result.classes)line.styleClasses=result.classes;else if(line.styleClasses)line.styleClasses=null;if(updateFrontier===cm.doc.frontier)cm.doc.frontier++;}
return line.styles;}
function processLine(cm,text,state,startAt){var mode=cm.doc.mode;var stream=new StringStream(text,cm.options.tabSize);stream.start=stream.pos=startAt||0;if(text=="")callBlankLine(mode,state);while(!stream.eol()&&stream.pos<=cm.options.maxHighlightLength){readToken(mode,stream,state);stream.start=stream.pos;}}
var styleToClassCache={},styleToClassCacheWithMode={};function interpretTokenStyle(style,options){if(!style||/^\s*$/.test(style))return null;var cache=options.addModeClass?styleToClassCacheWithMode:styleToClassCache;return cache[style]||(cache[style]=style.replace(/\S+/g,"cm-$&"));}
function buildLineContent(cm,lineView){var content=elt("span",null,null,webkit?"padding-right: .1px":null);var builder={pre:elt("pre",[content]),content:content,col:0,pos:0,cm:cm};lineView.measure={};for(var i=0;i<=(lineView.rest?lineView.rest.length:0);i++){var line=i?lineView.rest[i-1]:lineView.line,order;builder.pos=0;builder.addToken=buildToken;if((ie||webkit)&&cm.getOption("lineWrapping"))
builder.addToken=buildTokenSplitSpaces(builder.addToken);if(hasBadBidiRects(cm.display.measure)&&(order=getOrder(line)))
builder.addToken=buildTokenBadBidi(builder.addToken,order);builder.map=[];var allowFrontierUpdate=lineView!=cm.display.externalMeasured&&lineNo(line);insertLineContent(line,builder,getLineStyles(cm,line,allowFrontierUpdate));if(line.styleClasses){if(line.styleClasses.bgClass)
builder.bgClass=joinClasses(line.styleClasses.bgClass,builder.bgClass||"");if(line.styleClasses.textClass)
builder.textClass=joinClasses(line.styleClasses.textClass,builder.textClass||"");}
if(builder.map.length==0)
builder.map.push(0,0,builder.content.appendChild(zeroWidthElement(cm.display.measure)));if(i==0){lineView.measure.map=builder.map;lineView.measure.cache={};}else{(lineView.measure.maps||(lineView.measure.maps=[])).push(builder.map);(lineView.measure.caches||(lineView.measure.caches=[])).push({});}}
if(webkit&&/\bcm-tab\b/.test(builder.content.lastChild.className))
builder.content.className="cm-tab-wrap-hack";signal(cm,"renderLine",cm,lineView.line,builder.pre);if(builder.pre.className)
builder.textClass=joinClasses(builder.pre.className,builder.textClass||"");return builder;}
function defaultSpecialCharPlaceholder(ch){var token=elt("span","\u2022","cm-invalidchar");token.title="\\u"+ch.charCodeAt(0).toString(16);return token;}
function buildToken(builder,text,style,startStyle,endStyle,title,css){if(!text)return;var special=builder.cm.options.specialChars,mustWrap=false;if(!special.test(text)){builder.col+=text.length;var content=document.createTextNode(text);builder.map.push(builder.pos,builder.pos+text.length,content);if(ie&&ie_version<9)mustWrap=true;builder.pos+=text.length;}else{var content=document.createDocumentFragment(),pos=0;while(true){special.lastIndex=pos;var m=special.exec(text);var skipped=m?m.index-pos:text.length-pos;if(skipped){var txt=document.createTextNode(text.slice(pos,pos+skipped));if(ie&&ie_version<9)content.appendChild(elt("span",[txt]));else content.appendChild(txt);builder.map.push(builder.pos,builder.pos+skipped,txt);builder.col+=skipped;builder.pos+=skipped;}
if(!m)break;pos+=skipped+1;if(m[0]=="\t"){var tabSize=builder.cm.options.tabSize,tabWidth=tabSize-builder.col%tabSize;var txt=content.appendChild(elt("span",spaceStr(tabWidth),"cm-tab"));builder.col+=tabWidth;}else{var txt=builder.cm.options.specialCharPlaceholder(m[0]);if(ie&&ie_version<9)content.appendChild(elt("span",[txt]));else content.appendChild(txt);builder.col+=1;}
builder.map.push(builder.pos,builder.pos+1,txt);builder.pos++;}}
if(style||startStyle||endStyle||mustWrap||css){var fullStyle=style||"";if(startStyle)fullStyle+=startStyle;if(endStyle)fullStyle+=endStyle;var token=elt("span",[content],fullStyle,css);if(title)token.title=title;return builder.content.appendChild(token);}
builder.content.appendChild(content);}
function buildTokenSplitSpaces(inner){function split(old){var out=" ";for(var i=0;i<old.length-2;++i)out+=i%2?" ":"\u00a0";out+=" ";return out;}
return function(builder,text,style,startStyle,endStyle,title){inner(builder,text.replace(/ {3,}/g,split),style,startStyle,endStyle,title);};}
function buildTokenBadBidi(inner,order){return function(builder,text,style,startStyle,endStyle,title){style=style?style+" cm-force-border":"cm-force-border";var start=builder.pos,end=start+text.length;for(;;){for(var i=0;i<order.length;i++){var part=order[i];if(part.to>start&&part.from<=start)break;}
if(part.to>=end)return inner(builder,text,style,startStyle,endStyle,title);inner(builder,text.slice(0,part.to-start),style,startStyle,null,title);startStyle=null;text=text.slice(part.to-start);start=part.to;}};}
function buildCollapsedSpan(builder,size,marker,ignoreWidget){var widget=!ignoreWidget&&marker.widgetNode;if(widget){builder.map.push(builder.pos,builder.pos+size,widget);builder.content.appendChild(widget);}
builder.pos+=size;}
function insertLineContent(line,builder,styles){var spans=line.markedSpans,allText=line.text,at=0;if(!spans){for(var i=1;i<styles.length;i+=2)
builder.addToken(builder,allText.slice(at,at=styles[i]),interpretTokenStyle(styles[i+1],builder.cm.options));return;}
var len=allText.length,pos=0,i=1,text="",style,css;var nextChange=0,spanStyle,spanEndStyle,spanStartStyle,title,collapsed;for(;;){if(nextChange==pos){spanStyle=spanEndStyle=spanStartStyle=title=css="";collapsed=null;nextChange=Infinity;var foundBookmarks=[];for(var j=0;j<spans.length;++j){var sp=spans[j],m=sp.marker;if(sp.from<=pos&&(sp.to==null||sp.to>pos)){if(sp.to!=null&&nextChange>sp.to){nextChange=sp.to;spanEndStyle="";}
if(m.className)spanStyle+=" "+m.className;if(m.css)css=m.css;if(m.startStyle&&sp.from==pos)spanStartStyle+=" "+m.startStyle;if(m.endStyle&&sp.to==nextChange)spanEndStyle+=" "+m.endStyle;if(m.title&&!title)title=m.title;if(m.collapsed&&(!collapsed||compareCollapsedMarkers(collapsed.marker,m)<0))
collapsed=sp;}else if(sp.from>pos&&nextChange>sp.from){nextChange=sp.from;}
if(m.type=="bookmark"&&sp.from==pos&&m.widgetNode)foundBookmarks.push(m);}
if(collapsed&&(collapsed.from||0)==pos){buildCollapsedSpan(builder,(collapsed.to==null?len+1:collapsed.to)-pos,collapsed.marker,collapsed.from==null);if(collapsed.to==null)return;}
if(!collapsed&&foundBookmarks.length)for(var j=0;j<foundBookmarks.length;++j)
buildCollapsedSpan(builder,0,foundBookmarks[j]);}
if(pos>=len)break;var upto=Math.min(len,nextChange);while(true){if(text){var end=pos+text.length;if(!collapsed){var tokenText=end>upto?text.slice(0,upto-pos):text;builder.addToken(builder,tokenText,style?style+spanStyle:spanStyle,spanStartStyle,pos+tokenText.length==nextChange?spanEndStyle:"",title,css);}
if(end>=upto){text=text.slice(upto-pos);pos=upto;break;}
pos=end;spanStartStyle="";}
text=allText.slice(at,at=styles[i++]);style=interpretTokenStyle(styles[i++],builder.cm.options);}}}
function isWholeLineUpdate(doc,change){return change.from.ch==0&&change.to.ch==0&&lst(change.text)==""&&(!doc.cm||doc.cm.options.wholeLineUpdateBefore);}
function updateDoc(doc,change,markedSpans,estimateHeight){function spansFor(n){return markedSpans?markedSpans[n]:null;}
function update(line,text,spans){updateLine(line,text,spans,estimateHeight);signalLater(line,"change",line,change);}
function linesFor(start,end){for(var i=start,result=[];i<end;++i)
result.push(new Line(text[i],spansFor(i),estimateHeight));return result;}
var from=change.from,to=change.to,text=change.text;var firstLine=getLine(doc,from.line),lastLine=getLine(doc,to.line);var lastText=lst(text),lastSpans=spansFor(text.length-1),nlines=to.line-from.line;if(change.full){doc.insert(0,linesFor(0,text.length));doc.remove(text.length,doc.size-text.length);}else if(isWholeLineUpdate(doc,change)){var added=linesFor(0,text.length-1);update(lastLine,lastLine.text,lastSpans);if(nlines)doc.remove(from.line,nlines);if(added.length)doc.insert(from.line,added);}else if(firstLine==lastLine){if(text.length==1){update(firstLine,firstLine.text.slice(0,from.ch)+lastText+firstLine.text.slice(to.ch),lastSpans);}else{var added=linesFor(1,text.length-1);added.push(new Line(lastText+firstLine.text.slice(to.ch),lastSpans,estimateHeight));update(firstLine,firstLine.text.slice(0,from.ch)+text[0],spansFor(0));doc.insert(from.line+1,added);}}else if(text.length==1){update(firstLine,firstLine.text.slice(0,from.ch)+text[0]+lastLine.text.slice(to.ch),spansFor(0));doc.remove(from.line+1,nlines);}else{update(firstLine,firstLine.text.slice(0,from.ch)+text[0],spansFor(0));update(lastLine,lastText+lastLine.text.slice(to.ch),lastSpans);var added=linesFor(1,text.length-1);if(nlines>1)doc.remove(from.line+1,nlines-1);doc.insert(from.line+1,added);}
signalLater(doc,"change",doc,change);}
function LeafChunk(lines){this.lines=lines;this.parent=null;for(var i=0,height=0;i<lines.length;++i){lines[i].parent=this;height+=lines[i].height;}
this.height=height;}
LeafChunk.prototype={chunkSize:function(){return this.lines.length;},removeInner:function(at,n){for(var i=at,e=at+n;i<e;++i){var line=this.lines[i];this.height-=line.height;cleanUpLine(line);signalLater(line,"delete");}
this.lines.splice(at,n);},collapse:function(lines){lines.push.apply(lines,this.lines);},insertInner:function(at,lines,height){this.height+=height;this.lines=this.lines.slice(0,at).concat(lines).concat(this.lines.slice(at));for(var i=0;i<lines.length;++i)lines[i].parent=this;},iterN:function(at,n,op){for(var e=at+n;at<e;++at)
if(op(this.lines[at]))return true;}};function BranchChunk(children){this.children=children;var size=0,height=0;for(var i=0;i<children.length;++i){var ch=children[i];size+=ch.chunkSize();height+=ch.height;ch.parent=this;}
this.size=size;this.height=height;this.parent=null;}
BranchChunk.prototype={chunkSize:function(){return this.size;},removeInner:function(at,n){this.size-=n;for(var i=0;i<this.children.length;++i){var child=this.children[i],sz=child.chunkSize();if(at<sz){var rm=Math.min(n,sz-at),oldHeight=child.height;child.removeInner(at,rm);this.height-=oldHeight-child.height;if(sz==rm){this.children.splice(i--,1);child.parent=null;}
if((n-=rm)==0)break;at=0;}else at-=sz;}
if(this.size-n<25&&(this.children.length>1||!(this.children[0]instanceof LeafChunk))){var lines=[];this.collapse(lines);this.children=[new LeafChunk(lines)];this.children[0].parent=this;}},collapse:function(lines){for(var i=0;i<this.children.length;++i)this.children[i].collapse(lines);},insertInner:function(at,lines,height){this.size+=lines.length;this.height+=height;for(var i=0;i<this.children.length;++i){var child=this.children[i],sz=child.chunkSize();if(at<=sz){child.insertInner(at,lines,height);if(child.lines&&child.lines.length>50){while(child.lines.length>50){var spilled=child.lines.splice(child.lines.length-25,25);var newleaf=new LeafChunk(spilled);child.height-=newleaf.height;this.children.splice(i+1,0,newleaf);newleaf.parent=this;}
this.maybeSpill();}
break;}
at-=sz;}},maybeSpill:function(){if(this.children.length<=10)return;var me=this;do{var spilled=me.children.splice(me.children.length-5,5);var sibling=new BranchChunk(spilled);if(!me.parent){var copy=new BranchChunk(me.children);copy.parent=me;me.children=[copy,sibling];me=copy;}else{me.size-=sibling.size;me.height-=sibling.height;var myIndex=indexOf(me.parent.children,me);me.parent.children.splice(myIndex+1,0,sibling);}
sibling.parent=me.parent;}while(me.children.length>10);me.parent.maybeSpill();},iterN:function(at,n,op){for(var i=0;i<this.children.length;++i){var child=this.children[i],sz=child.chunkSize();if(at<sz){var used=Math.min(n,sz-at);if(child.iterN(at,used,op))return true;if((n-=used)==0)break;at=0;}else at-=sz;}}};var nextDocId=0;var Doc=CodeMirror.Doc=function(text,mode,firstLine){if(!(this instanceof Doc))return new Doc(text,mode,firstLine);if(firstLine==null)firstLine=0;BranchChunk.call(this,[new LeafChunk([new Line("",null)])]);this.first=firstLine;this.scrollTop=this.scrollLeft=0;this.cantEdit=false;this.cleanGeneration=1;this.frontier=firstLine;var start=Pos(firstLine,0);this.sel=simpleSelection(start);this.history=new History(null);this.id=++nextDocId;this.modeOption=mode;if(typeof text=="string")text=splitLines(text);updateDoc(this,{from:start,to:start,text:text});setSelection(this,simpleSelection(start),sel_dontScroll);};Doc.prototype=createObj(BranchChunk.prototype,{constructor:Doc,iter:function(from,to,op){if(op)this.iterN(from-this.first,to-from,op);else this.iterN(this.first,this.first+this.size,from);},insert:function(at,lines){var height=0;for(var i=0;i<lines.length;++i)height+=lines[i].height;this.insertInner(at-this.first,lines,height);},remove:function(at,n){this.removeInner(at-this.first,n);},getValue:function(lineSep){var lines=getLines(this,this.first,this.first+this.size);if(lineSep===false)return lines;return lines.join(lineSep||"\n");},setValue:docMethodOp(function(code){var top=Pos(this.first,0),last=this.first+this.size-1;makeChange(this,{from:top,to:Pos(last,getLine(this,last).text.length),text:splitLines(code),origin:"setValue",full:true},true);setSelection(this,simpleSelection(top));}),replaceRange:function(code,from,to,origin){from=clipPos(this,from);to=to?clipPos(this,to):from;replaceRange(this,code,from,to,origin);},getRange:function(from,to,lineSep){var lines=getBetween(this,clipPos(this,from),clipPos(this,to));if(lineSep===false)return lines;return lines.join(lineSep||"\n");},getLine:function(line){var l=this.getLineHandle(line);return l&&l.text;},getLineHandle:function(line){if(isLine(this,line))return getLine(this,line);},getLineNumber:function(line){return lineNo(line);},getLineHandleVisualStart:function(line){if(typeof line=="number")line=getLine(this,line);return visualLine(line);},lineCount:function(){return this.size;},firstLine:function(){return this.first;},lastLine:function(){return this.first+this.size-1;},clipPos:function(pos){return clipPos(this,pos);},getCursor:function(start){var range=this.sel.primary(),pos;if(start==null||start=="head")pos=range.head;else if(start=="anchor")pos=range.anchor;else if(start=="end"||start=="to"||start===false)pos=range.to();else pos=range.from();return pos;},listSelections:function(){return this.sel.ranges;},somethingSelected:function(){return this.sel.somethingSelected();},setCursor:docMethodOp(function(line,ch,options){setSimpleSelection(this,clipPos(this,typeof line=="number"?Pos(line,ch||0):line),null,options);}),setSelection:docMethodOp(function(anchor,head,options){setSimpleSelection(this,clipPos(this,anchor),clipPos(this,head||anchor),options);}),extendSelection:docMethodOp(function(head,other,options){extendSelection(this,clipPos(this,head),other&&clipPos(this,other),options);}),extendSelections:docMethodOp(function(heads,options){extendSelections(this,clipPosArray(this,heads,options));}),extendSelectionsBy:docMethodOp(function(f,options){extendSelections(this,map(this.sel.ranges,f),options);}),setSelections:docMethodOp(function(ranges,primary,options){if(!ranges.length)return;for(var i=0,out=[];i<ranges.length;i++)
out[i]=new Range(clipPos(this,ranges[i].anchor),clipPos(this,ranges[i].head));if(primary==null)primary=Math.min(ranges.length-1,this.sel.primIndex);setSelection(this,normalizeSelection(out,primary),options);}),addSelection:docMethodOp(function(anchor,head,options){var ranges=this.sel.ranges.slice(0);ranges.push(new Range(clipPos(this,anchor),clipPos(this,head||anchor)));setSelection(this,normalizeSelection(ranges,ranges.length-1),options);}),getSelection:function(lineSep){var ranges=this.sel.ranges,lines;for(var i=0;i<ranges.length;i++){var sel=getBetween(this,ranges[i].from(),ranges[i].to());lines=lines?lines.concat(sel):sel;}
if(lineSep===false)return lines;else return lines.join(lineSep||"\n");},getSelections:function(lineSep){var parts=[],ranges=this.sel.ranges;for(var i=0;i<ranges.length;i++){var sel=getBetween(this,ranges[i].from(),ranges[i].to());if(lineSep!==false)sel=sel.join(lineSep||"\n");parts[i]=sel;}
return parts;},replaceSelection:function(code,collapse,origin){var dup=[];for(var i=0;i<this.sel.ranges.length;i++)
dup[i]=code;this.replaceSelections(dup,collapse,origin||"+input");},replaceSelections:docMethodOp(function(code,collapse,origin){var changes=[],sel=this.sel;for(var i=0;i<sel.ranges.length;i++){var range=sel.ranges[i];changes[i]={from:range.from(),to:range.to(),text:splitLines(code[i]),origin:origin};}
var newSel=collapse&&collapse!="end"&&computeReplacedSel(this,changes,collapse);for(var i=changes.length-1;i>=0;i--)
makeChange(this,changes[i]);if(newSel)setSelectionReplaceHistory(this,newSel);else if(this.cm)ensureCursorVisible(this.cm);}),undo:docMethodOp(function(){makeChangeFromHistory(this,"undo");}),redo:docMethodOp(function(){makeChangeFromHistory(this,"redo");}),undoSelection:docMethodOp(function(){makeChangeFromHistory(this,"undo",true);}),redoSelection:docMethodOp(function(){makeChangeFromHistory(this,"redo",true);}),setExtending:function(val){this.extend=val;},getExtending:function(){return this.extend;},historySize:function(){var hist=this.history,done=0,undone=0;for(var i=0;i<hist.done.length;i++)if(!hist.done[i].ranges)++done;for(var i=0;i<hist.undone.length;i++)if(!hist.undone[i].ranges)++undone;return{undo:done,redo:undone};},clearHistory:function(){this.history=new History(this.history.maxGeneration);},markClean:function(){this.cleanGeneration=this.changeGeneration(true);},changeGeneration:function(forceSplit){if(forceSplit)
this.history.lastOp=this.history.lastSelOp=this.history.lastOrigin=null;return this.history.generation;},isClean:function(gen){return this.history.generation==(gen||this.cleanGeneration);},getHistory:function(){return{done:copyHistoryArray(this.history.done),undone:copyHistoryArray(this.history.undone)};},setHistory:function(histData){var hist=this.history=new History(this.history.maxGeneration);hist.done=copyHistoryArray(histData.done.slice(0),null,true);hist.undone=copyHistoryArray(histData.undone.slice(0),null,true);},addLineClass:docMethodOp(function(handle,where,cls){return changeLine(this,handle,where=="gutter"?"gutter":"class",function(line){var prop=where=="text"?"textClass":where=="background"?"bgClass":where=="gutter"?"gutterClass":"wrapClass";if(!line[prop])line[prop]=cls;else if(classTest(cls).test(line[prop]))return false;else line[prop]+=" "+cls;return true;});}),removeLineClass:docMethodOp(function(handle,where,cls){return changeLine(this,handle,where=="gutter"?"gutter":"class",function(line){var prop=where=="text"?"textClass":where=="background"?"bgClass":where=="gutter"?"gutterClass":"wrapClass";var cur=line[prop];if(!cur)return false;else if(cls==null)line[prop]=null;else{var found=cur.match(classTest(cls));if(!found)return false;var end=found.index+found[0].length;line[prop]=cur.slice(0,found.index)+(!found.index||end==cur.length?"":" ")+cur.slice(end)||null;}
return true;});}),markText:function(from,to,options){return markText(this,clipPos(this,from),clipPos(this,to),options,"range");},setBookmark:function(pos,options){var realOpts={replacedWith:options&&(options.nodeType==null?options.widget:options),insertLeft:options&&options.insertLeft,clearWhenEmpty:false,shared:options&&options.shared};pos=clipPos(this,pos);return markText(this,pos,pos,realOpts,"bookmark");},findMarksAt:function(pos){pos=clipPos(this,pos);var markers=[],spans=getLine(this,pos.line).markedSpans;if(spans)for(var i=0;i<spans.length;++i){var span=spans[i];if((span.from==null||span.from<=pos.ch)&&(span.to==null||span.to>=pos.ch))
markers.push(span.marker.parent||span.marker);}
return markers;},findMarks:function(from,to,filter){from=clipPos(this,from);to=clipPos(this,to);var found=[],lineNo=from.line;this.iter(from.line,to.line+1,function(line){var spans=line.markedSpans;if(spans)for(var i=0;i<spans.length;i++){var span=spans[i];if(!(lineNo==from.line&&from.ch>span.to||span.from==null&&lineNo!=from.line||lineNo==to.line&&span.from>to.ch)&&(!filter||filter(span.marker)))
found.push(span.marker.parent||span.marker);}
++lineNo;});return found;},getAllMarks:function(){var markers=[];this.iter(function(line){var sps=line.markedSpans;if(sps)for(var i=0;i<sps.length;++i)
if(sps[i].from!=null)markers.push(sps[i].marker);});return markers;},posFromIndex:function(off){var ch,lineNo=this.first;this.iter(function(line){var sz=line.text.length+1;if(sz>off){ch=off;return true;}
off-=sz;++lineNo;});return clipPos(this,Pos(lineNo,ch));},indexFromPos:function(coords){coords=clipPos(this,coords);var index=coords.ch;if(coords.line<this.first||coords.ch<0)return 0;this.iter(this.first,coords.line,function(line){index+=line.text.length+1;});return index;},copy:function(copyHistory){var doc=new Doc(getLines(this,this.first,this.first+this.size),this.modeOption,this.first);doc.scrollTop=this.scrollTop;doc.scrollLeft=this.scrollLeft;doc.sel=this.sel;doc.extend=false;if(copyHistory){doc.history.undoDepth=this.history.undoDepth;doc.setHistory(this.getHistory());}
return doc;},linkedDoc:function(options){if(!options)options={};var from=this.first,to=this.first+this.size;if(options.from!=null&&options.from>from)from=options.from;if(options.to!=null&&options.to<to)to=options.to;var copy=new Doc(getLines(this,from,to),options.mode||this.modeOption,from);if(options.sharedHist)copy.history=this.history;(this.linked||(this.linked=[])).push({doc:copy,sharedHist:options.sharedHist});copy.linked=[{doc:this,isParent:true,sharedHist:options.sharedHist}];copySharedMarkers(copy,findSharedMarkers(this));return copy;},unlinkDoc:function(other){if(other instanceof CodeMirror)other=other.doc;if(this.linked)for(var i=0;i<this.linked.length;++i){var link=this.linked[i];if(link.doc!=other)continue;this.linked.splice(i,1);other.unlinkDoc(this);detachSharedMarkers(findSharedMarkers(this));break;}
if(other.history==this.history){var splitIds=[other.id];linkedDocs(other,function(doc){splitIds.push(doc.id);},true);other.history=new History(null);other.history.done=copyHistoryArray(this.history.done,splitIds);other.history.undone=copyHistoryArray(this.history.undone,splitIds);}},iterLinkedDocs:function(f){linkedDocs(this,f);},getMode:function(){return this.mode;},getEditor:function(){return this.cm;}});Doc.prototype.eachLine=Doc.prototype.iter;var dontDelegate="iter insert remove copy getEditor".split(" ");for(var prop in Doc.prototype)if(Doc.prototype.hasOwnProperty(prop)&&indexOf(dontDelegate,prop)<0)
CodeMirror.prototype[prop]=(function(method){return function(){return method.apply(this.doc,arguments);};})(Doc.prototype[prop]);eventMixin(Doc);function linkedDocs(doc,f,sharedHistOnly){function propagate(doc,skip,sharedHist){if(doc.linked)for(var i=0;i<doc.linked.length;++i){var rel=doc.linked[i];if(rel.doc==skip)continue;var shared=sharedHist&&rel.sharedHist;if(sharedHistOnly&&!shared)continue;f(rel.doc,shared);propagate(rel.doc,doc,shared);}}
propagate(doc,null,true);}
function attachDoc(cm,doc){if(doc.cm)throw new Error("This document is already in use.");cm.doc=doc;doc.cm=cm;estimateLineHeights(cm);loadMode(cm);if(!cm.options.lineWrapping)findMaxLine(cm);cm.options.mode=doc.modeOption;regChange(cm);}
function getLine(doc,n){n-=doc.first;if(n<0||n>=doc.size)throw new Error("There is no line "+(n+doc.first)+" in the document.");for(var chunk=doc;!chunk.lines;){for(var i=0;;++i){var child=chunk.children[i],sz=child.chunkSize();if(n<sz){chunk=child;break;}
n-=sz;}}
return chunk.lines[n];}
function getBetween(doc,start,end){var out=[],n=start.line;doc.iter(start.line,end.line+1,function(line){var text=line.text;if(n==end.line)text=text.slice(0,end.ch);if(n==start.line)text=text.slice(start.ch);out.push(text);++n;});return out;}
function getLines(doc,from,to){var out=[];doc.iter(from,to,function(line){out.push(line.text);});return out;}
function updateLineHeight(line,height){var diff=height-line.height;if(diff)for(var n=line;n;n=n.parent)n.height+=diff;}
function lineNo(line){if(line.parent==null)return null;var cur=line.parent,no=indexOf(cur.lines,line);for(var chunk=cur.parent;chunk;cur=chunk,chunk=chunk.parent){for(var i=0;;++i){if(chunk.children[i]==cur)break;no+=chunk.children[i].chunkSize();}}
return no+cur.first;}
function lineAtHeight(chunk,h){var n=chunk.first;outer:do{for(var i=0;i<chunk.children.length;++i){var child=chunk.children[i],ch=child.height;if(h<ch){chunk=child;continue outer;}
h-=ch;n+=child.chunkSize();}
return n;}while(!chunk.lines);for(var i=0;i<chunk.lines.length;++i){var line=chunk.lines[i],lh=line.height;if(h<lh)break;h-=lh;}
return n+i;}
function heightAtLine(lineObj){lineObj=visualLine(lineObj);var h=0,chunk=lineObj.parent;for(var i=0;i<chunk.lines.length;++i){var line=chunk.lines[i];if(line==lineObj)break;else h+=line.height;}
for(var p=chunk.parent;p;chunk=p,p=chunk.parent){for(var i=0;i<p.children.length;++i){var cur=p.children[i];if(cur==chunk)break;else h+=cur.height;}}
return h;}
function getOrder(line){var order=line.order;if(order==null)order=line.order=bidiOrdering(line.text);return order;}
function History(startGen){this.done=[];this.undone=[];this.undoDepth=Infinity;this.lastModTime=this.lastSelTime=0;this.lastOp=this.lastSelOp=null;this.lastOrigin=this.lastSelOrigin=null;this.generation=this.maxGeneration=startGen||1;}
function historyChangeFromChange(doc,change){var histChange={from:copyPos(change.from),to:changeEnd(change),text:getBetween(doc,change.from,change.to)};attachLocalSpans(doc,histChange,change.from.line,change.to.line+1);linkedDocs(doc,function(doc){attachLocalSpans(doc,histChange,change.from.line,change.to.line+1);},true);return histChange;}
function clearSelectionEvents(array){while(array.length){var last=lst(array);if(last.ranges)array.pop();else break;}}
function lastChangeEvent(hist,force){if(force){clearSelectionEvents(hist.done);return lst(hist.done);}else if(hist.done.length&&!lst(hist.done).ranges){return lst(hist.done);}else if(hist.done.length>1&&!hist.done[hist.done.length-2].ranges){hist.done.pop();return lst(hist.done);}}
function addChangeToHistory(doc,change,selAfter,opId){var hist=doc.history;hist.undone.length=0;var time=+new Date,cur;if((hist.lastOp==opId||hist.lastOrigin==change.origin&&change.origin&&((change.origin.charAt(0)=="+"&&doc.cm&&hist.lastModTime>time-doc.cm.options.historyEventDelay)||change.origin.charAt(0)=="*"))&&(cur=lastChangeEvent(hist,hist.lastOp==opId))){var last=lst(cur.changes);if(cmp(change.from,change.to)==0&&cmp(change.from,last.to)==0){last.to=changeEnd(change);}else{cur.changes.push(historyChangeFromChange(doc,change));}}else{var before=lst(hist.done);if(!before||!before.ranges)
pushSelectionToHistory(doc.sel,hist.done);cur={changes:[historyChangeFromChange(doc,change)],generation:hist.generation};hist.done.push(cur);while(hist.done.length>hist.undoDepth){hist.done.shift();if(!hist.done[0].ranges)hist.done.shift();}}
hist.done.push(selAfter);hist.generation=++hist.maxGeneration;hist.lastModTime=hist.lastSelTime=time;hist.lastOp=hist.lastSelOp=opId;hist.lastOrigin=hist.lastSelOrigin=change.origin;if(!last)signal(doc,"historyAdded");}
function selectionEventCanBeMerged(doc,origin,prev,sel){var ch=origin.charAt(0);return ch=="*"||ch=="+"&&prev.ranges.length==sel.ranges.length&&prev.somethingSelected()==sel.somethingSelected()&&new Date-doc.history.lastSelTime<=(doc.cm?doc.cm.options.historyEventDelay:500);}
function addSelectionToHistory(doc,sel,opId,options){var hist=doc.history,origin=options&&options.origin;if(opId==hist.lastSelOp||(origin&&hist.lastSelOrigin==origin&&(hist.lastModTime==hist.lastSelTime&&hist.lastOrigin==origin||selectionEventCanBeMerged(doc,origin,lst(hist.done),sel))))
hist.done[hist.done.length-1]=sel;else
pushSelectionToHistory(sel,hist.done);hist.lastSelTime=+new Date;hist.lastSelOrigin=origin;hist.lastSelOp=opId;if(options&&options.clearRedo!==false)
clearSelectionEvents(hist.undone);}
function pushSelectionToHistory(sel,dest){var top=lst(dest);if(!(top&&top.ranges&&top.equals(sel)))
dest.push(sel);}
function attachLocalSpans(doc,change,from,to){var existing=change["spans_"+doc.id],n=0;doc.iter(Math.max(doc.first,from),Math.min(doc.first+doc.size,to),function(line){if(line.markedSpans)
(existing||(existing=change["spans_"+doc.id]={}))[n]=line.markedSpans;++n;});}
function removeClearedSpans(spans){if(!spans)return null;for(var i=0,out;i<spans.length;++i){if(spans[i].marker.explicitlyCleared){if(!out)out=spans.slice(0,i);}
else if(out)out.push(spans[i]);}
return!out?spans:out.length?out:null;}
function getOldSpans(doc,change){var found=change["spans_"+doc.id];if(!found)return null;for(var i=0,nw=[];i<change.text.length;++i)
nw.push(removeClearedSpans(found[i]));return nw;}
function copyHistoryArray(events,newGroup,instantiateSel){for(var i=0,copy=[];i<events.length;++i){var event=events[i];if(event.ranges){copy.push(instantiateSel?Selection.prototype.deepCopy.call(event):event);continue;}
var changes=event.changes,newChanges=[];copy.push({changes:newChanges});for(var j=0;j<changes.length;++j){var change=changes[j],m;newChanges.push({from:change.from,to:change.to,text:change.text});if(newGroup)for(var prop in change)if(m=prop.match(/^spans_(\d+)$/)){if(indexOf(newGroup,Number(m[1]))>-1){lst(newChanges)[prop]=change[prop];delete change[prop];}}}}
return copy;}
function rebaseHistSelSingle(pos,from,to,diff){if(to<pos.line){pos.line+=diff;}else if(from<pos.line){pos.line=from;pos.ch=0;}}
function rebaseHistArray(array,from,to,diff){for(var i=0;i<array.length;++i){var sub=array[i],ok=true;if(sub.ranges){if(!sub.copied){sub=array[i]=sub.deepCopy();sub.copied=true;}
for(var j=0;j<sub.ranges.length;j++){rebaseHistSelSingle(sub.ranges[j].anchor,from,to,diff);rebaseHistSelSingle(sub.ranges[j].head,from,to,diff);}
continue;}
for(var j=0;j<sub.changes.length;++j){var cur=sub.changes[j];if(to<cur.from.line){cur.from=Pos(cur.from.line+diff,cur.from.ch);cur.to=Pos(cur.to.line+diff,cur.to.ch);}else if(from<=cur.to.line){ok=false;break;}}
if(!ok){array.splice(0,i+1);i=0;}}}
function rebaseHist(hist,change){var from=change.from.line,to=change.to.line,diff=change.text.length-(to-from)-1;rebaseHistArray(hist.done,from,to,diff);rebaseHistArray(hist.undone,from,to,diff);}
var e_preventDefault=CodeMirror.e_preventDefault=function(e){if(e.preventDefault)e.preventDefault();else e.returnValue=false;};var e_stopPropagation=CodeMirror.e_stopPropagation=function(e){if(e.stopPropagation)e.stopPropagation();else e.cancelBubble=true;};function e_defaultPrevented(e){return e.defaultPrevented!=null?e.defaultPrevented:e.returnValue==false;}
var e_stop=CodeMirror.e_stop=function(e){e_preventDefault(e);e_stopPropagation(e);};function e_target(e){return e.target||e.srcElement;}
function e_button(e){var b=e.which;if(b==null){if(e.button&1)b=1;else if(e.button&2)b=3;else if(e.button&4)b=2;}
if(mac&&e.ctrlKey&&b==1)b=3;return b;}
var on=CodeMirror.on=function(emitter,type,f){if(emitter.addEventListener)
emitter.addEventListener(type,f,false);else if(emitter.attachEvent)
emitter.attachEvent("on"+type,f);else{var map=emitter._handlers||(emitter._handlers={});var arr=map[type]||(map[type]=[]);arr.push(f);}};var off=CodeMirror.off=function(emitter,type,f){if(emitter.removeEventListener)
emitter.removeEventListener(type,f,false);else if(emitter.detachEvent)
emitter.detachEvent("on"+type,f);else{var arr=emitter._handlers&&emitter._handlers[type];if(!arr)return;for(var i=0;i<arr.length;++i)
if(arr[i]==f){arr.splice(i,1);break;}}};var signal=CodeMirror.signal=function(emitter,type){var arr=emitter._handlers&&emitter._handlers[type];if(!arr)return;var args=Array.prototype.slice.call(arguments,2);for(var i=0;i<arr.length;++i)arr[i].apply(null,args);};var orphanDelayedCallbacks=null;function signalLater(emitter,type){var arr=emitter._handlers&&emitter._handlers[type];if(!arr)return;var args=Array.prototype.slice.call(arguments,2),list;if(operationGroup){list=operationGroup.delayedCallbacks;}else if(orphanDelayedCallbacks){list=orphanDelayedCallbacks;}else{list=orphanDelayedCallbacks=[];setTimeout(fireOrphanDelayed,0);}
function bnd(f){return function(){f.apply(null,args);};};for(var i=0;i<arr.length;++i)
list.push(bnd(arr[i]));}
function fireOrphanDelayed(){var delayed=orphanDelayedCallbacks;orphanDelayedCallbacks=null;for(var i=0;i<delayed.length;++i)delayed[i]();}
function signalDOMEvent(cm,e,override){if(typeof e=="string")
e={type:e,preventDefault:function(){this.defaultPrevented=true;}};signal(cm,override||e.type,cm,e);return e_defaultPrevented(e)||e.codemirrorIgnore;}
function signalCursorActivity(cm){var arr=cm._handlers&&cm._handlers.cursorActivity;if(!arr)return;var set=cm.curOp.cursorActivityHandlers||(cm.curOp.cursorActivityHandlers=[]);for(var i=0;i<arr.length;++i)if(indexOf(set,arr[i])==-1)
set.push(arr[i]);}
function hasHandler(emitter,type){var arr=emitter._handlers&&emitter._handlers[type];return arr&&arr.length>0;}
function eventMixin(ctor){ctor.prototype.on=function(type,f){on(this,type,f);};ctor.prototype.off=function(type,f){off(this,type,f);};}
var scrollerGap=30;var Pass=CodeMirror.Pass={toString:function(){return"CodeMirror.Pass";}};var sel_dontScroll={scroll:false},sel_mouse={origin:"*mouse"},sel_move={origin:"+move"};function Delayed(){this.id=null;}
Delayed.prototype.set=function(ms,f){clearTimeout(this.id);this.id=setTimeout(f,ms);};var countColumn=CodeMirror.countColumn=function(string,end,tabSize,startIndex,startValue){if(end==null){end=string.search(/[^\s\u00a0]/);if(end==-1)end=string.length;}
for(var i=startIndex||0,n=startValue||0;;){var nextTab=string.indexOf("\t",i);if(nextTab<0||nextTab>=end)
return n+(end-i);n+=nextTab-i;n+=tabSize-(n%tabSize);i=nextTab+1;}};function findColumn(string,goal,tabSize){for(var pos=0,col=0;;){var nextTab=string.indexOf("\t",pos);if(nextTab==-1)nextTab=string.length;var skipped=nextTab-pos;if(nextTab==string.length||col+skipped>=goal)
return pos+Math.min(skipped,goal-col);col+=nextTab-pos;col+=tabSize-(col%tabSize);pos=nextTab+1;if(col>=goal)return pos;}}
var spaceStrs=[""];function spaceStr(n){while(spaceStrs.length<=n)
spaceStrs.push(lst(spaceStrs)+" ");return spaceStrs[n];}
function lst(arr){return arr[arr.length-1];}
var selectInput=function(node){node.select();};if(ios)
selectInput=function(node){node.selectionStart=0;node.selectionEnd=node.value.length;};else if(ie)
selectInput=function(node){try{node.select();}catch(_e){}};function indexOf(array,elt){for(var i=0;i<array.length;++i)
if(array[i]==elt)return i;return-1;}
function map(array,f){var out=[];for(var i=0;i<array.length;i++)out[i]=f(array[i],i);return out;}
function createObj(base,props){var inst;if(Object.create){inst=Object.create(base);}else{var ctor=function(){};ctor.prototype=base;inst=new ctor();}
if(props)copyObj(props,inst);return inst;};function copyObj(obj,target,overwrite){if(!target)target={};for(var prop in obj)
if(obj.hasOwnProperty(prop)&&(overwrite!==false||!target.hasOwnProperty(prop)))
target[prop]=obj[prop];return target;}
function bind(f){var args=Array.prototype.slice.call(arguments,1);return function(){return f.apply(null,args);};}
var nonASCIISingleCaseWordChar=/[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;var isWordCharBasic=CodeMirror.isWordChar=function(ch){return/\w/.test(ch)||ch>"\x80"&&(ch.toUpperCase()!=ch.toLowerCase()||nonASCIISingleCaseWordChar.test(ch));};function isWordChar(ch,helper){if(!helper)return isWordCharBasic(ch);if(helper.source.indexOf("\\w")>-1&&isWordCharBasic(ch))return true;return helper.test(ch);}
function isEmpty(obj){for(var n in obj)if(obj.hasOwnProperty(n)&&obj[n])return false;return true;}
var extendingChars=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function isExtendingChar(ch){return ch.charCodeAt(0)>=768&&extendingChars.test(ch);}
function elt(tag,content,className,style){var e=document.createElement(tag);if(className)e.className=className;if(style)e.style.cssText=style;if(typeof content=="string")e.appendChild(document.createTextNode(content));else if(content)for(var i=0;i<content.length;++i)e.appendChild(content[i]);return e;}
var range;if(document.createRange)range=function(node,start,end){var r=document.createRange();r.setEnd(node,end);r.setStart(node,start);return r;};else range=function(node,start,end){var r=document.body.createTextRange();try{r.moveToElementText(node.parentNode);}
catch(e){return r;}
r.collapse(true);r.moveEnd("character",end);r.moveStart("character",start);return r;};function removeChildren(e){for(var count=e.childNodes.length;count>0;--count)
e.removeChild(e.firstChild);return e;}
function removeChildrenAndAdd(parent,e){return removeChildren(parent).appendChild(e);}
function contains(parent,child){if(parent.contains)
return parent.contains(child);while(child=child.parentNode)
if(child==parent)return true;}
function activeElt(){return document.activeElement;}
if(ie&&ie_version<11)activeElt=function(){try{return document.activeElement;}
catch(e){return document.body;}};function classTest(cls){return new RegExp("(^|\\s)"+cls+"(?:$|\\s)\\s*");}
var rmClass=CodeMirror.rmClass=function(node,cls){var current=node.className;var match=classTest(cls).exec(current);if(match){var after=current.slice(match.index+match[0].length);node.className=current.slice(0,match.index)+(after?match[1]+after:"");}};var addClass=CodeMirror.addClass=function(node,cls){var current=node.className;if(!classTest(cls).test(current))node.className+=(current?" ":"")+cls;};function joinClasses(a,b){var as=a.split(" ");for(var i=0;i<as.length;i++)
if(as[i]&&!classTest(as[i]).test(b))b+=" "+as[i];return b;}
function forEachCodeMirror(f){if(!document.body.getElementsByClassName)return;var byClass=document.body.getElementsByClassName("CodeMirror");for(var i=0;i<byClass.length;i++){var cm=byClass[i].CodeMirror;if(cm)f(cm);}}
var globalsRegistered=false;function ensureGlobalHandlers(){if(globalsRegistered)return;registerGlobalHandlers();globalsRegistered=true;}
function registerGlobalHandlers(){var resizeTimer;on(window,"resize",function(){if(resizeTimer==null)resizeTimer=setTimeout(function(){resizeTimer=null;forEachCodeMirror(onResize);},100);});on(window,"blur",function(){forEachCodeMirror(onBlur);});}
var dragAndDrop=function(){if(ie&&ie_version<9)return false;var div=elt('div');return"draggable"in div||"dragDrop"in div;}();var zwspSupported;function zeroWidthElement(measure){if(zwspSupported==null){var test=elt("span","\u200b");removeChildrenAndAdd(measure,elt("span",[test,document.createTextNode("x")]));if(measure.firstChild.offsetHeight!=0)
zwspSupported=test.offsetWidth<=1&&test.offsetHeight>2&&!(ie&&ie_version<8);}
if(zwspSupported)return elt("span","\u200b");else return elt("span","\u00a0",null,"display: inline-block; width: 1px; margin-right: -1px");}
var badBidiRects;function hasBadBidiRects(measure){if(badBidiRects!=null)return badBidiRects;var txt=removeChildrenAndAdd(measure,document.createTextNode("A\u062eA"));var r0=range(txt,0,1).getBoundingClientRect();if(!r0||r0.left==r0.right)return false;var r1=range(txt,1,2).getBoundingClientRect();return badBidiRects=(r1.right-r0.right<3);}
var splitLines=CodeMirror.splitLines="\n\nb".split(/\n/).length!=3?function(string){var pos=0,result=[],l=string.length;while(pos<=l){var nl=string.indexOf("\n",pos);if(nl==-1)nl=string.length;var line=string.slice(pos,string.charAt(nl-1)=="\r"?nl-1:nl);var rt=line.indexOf("\r");if(rt!=-1){result.push(line.slice(0,rt));pos+=rt+1;}else{result.push(line);pos=nl+1;}}
return result;}:function(string){return string.split(/\r\n?|\n/);};var hasSelection=window.getSelection?function(te){try{return te.selectionStart!=te.selectionEnd;}
catch(e){return false;}}:function(te){try{var range=te.ownerDocument.selection.createRange();}
catch(e){}
if(!range||range.parentElement()!=te)return false;return range.compareEndPoints("StartToEnd",range)!=0;};var hasCopyEvent=(function(){var e=elt("div");if("oncopy"in e)return true;e.setAttribute("oncopy","return;");return typeof e.oncopy=="function";})();var badZoomedRects=null;function hasBadZoomedRects(measure){if(badZoomedRects!=null)return badZoomedRects;var node=removeChildrenAndAdd(measure,elt("span","x"));var normal=node.getBoundingClientRect();var fromRange=range(node,0,1).getBoundingClientRect();return badZoomedRects=Math.abs(normal.left-fromRange.left)>1;}
var keyNames={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"=",91:"Mod",92:"Mod",93:"Mod",107:"=",109:"-",127:"Delete",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};CodeMirror.keyNames=keyNames;(function(){for(var i=0;i<10;i++)keyNames[i+48]=keyNames[i+96]=String(i);for(var i=65;i<=90;i++)keyNames[i]=String.fromCharCode(i);for(var i=1;i<=12;i++)keyNames[i+111]=keyNames[i+63235]="F"+i;})();function iterateBidiSections(order,from,to,f){if(!order)return f(from,to,"ltr");var found=false;for(var i=0;i<order.length;++i){var part=order[i];if(part.from<to&&part.to>from||from==to&&part.to==from){f(Math.max(part.from,from),Math.min(part.to,to),part.level==1?"rtl":"ltr");found=true;}}
if(!found)f(from,to,"ltr");}
function bidiLeft(part){return part.level%2?part.to:part.from;}
function bidiRight(part){return part.level%2?part.from:part.to;}
function lineLeft(line){var order=getOrder(line);return order?bidiLeft(order[0]):0;}
function lineRight(line){var order=getOrder(line);if(!order)return line.text.length;return bidiRight(lst(order));}
function lineStart(cm,lineN){var line=getLine(cm.doc,lineN);var visual=visualLine(line);if(visual!=line)lineN=lineNo(visual);var order=getOrder(visual);var ch=!order?0:order[0].level%2?lineRight(visual):lineLeft(visual);return Pos(lineN,ch);}
function lineEnd(cm,lineN){var merged,line=getLine(cm.doc,lineN);while(merged=collapsedSpanAtEnd(line)){line=merged.find(1,true).line;lineN=null;}
var order=getOrder(line);var ch=!order?line.text.length:order[0].level%2?lineLeft(line):lineRight(line);return Pos(lineN==null?lineNo(line):lineN,ch);}
function lineStartSmart(cm,pos){var start=lineStart(cm,pos.line);var line=getLine(cm.doc,start.line);var order=getOrder(line);if(!order||order[0].level==0){var firstNonWS=Math.max(0,line.text.search(/\S/));var inWS=pos.line==start.line&&pos.ch<=firstNonWS&&pos.ch;return Pos(start.line,inWS?0:firstNonWS);}
return start;}
function compareBidiLevel(order,a,b){var linedir=order[0].level;if(a==linedir)return true;if(b==linedir)return false;return a<b;}
var bidiOther;function getBidiPartAt(order,pos){bidiOther=null;for(var i=0,found;i<order.length;++i){var cur=order[i];if(cur.from<pos&&cur.to>pos)return i;if((cur.from==pos||cur.to==pos)){if(found==null){found=i;}else if(compareBidiLevel(order,cur.level,order[found].level)){if(cur.from!=cur.to)bidiOther=found;return i;}else{if(cur.from!=cur.to)bidiOther=i;return found;}}}
return found;}
function moveInLine(line,pos,dir,byUnit){if(!byUnit)return pos+dir;do pos+=dir;while(pos>0&&isExtendingChar(line.text.charAt(pos)));return pos;}
function moveVisually(line,start,dir,byUnit){var bidi=getOrder(line);if(!bidi)return moveLogically(line,start,dir,byUnit);var pos=getBidiPartAt(bidi,start),part=bidi[pos];var target=moveInLine(line,start,part.level%2?-dir:dir,byUnit);for(;;){if(target>part.from&&target<part.to)return target;if(target==part.from||target==part.to){if(getBidiPartAt(bidi,target)==pos)return target;part=bidi[pos+=dir];return(dir>0)==part.level%2?part.to:part.from;}else{part=bidi[pos+=dir];if(!part)return null;if((dir>0)==part.level%2)
target=moveInLine(line,part.to,-1,byUnit);else
target=moveInLine(line,part.from,1,byUnit);}}}
function moveLogically(line,start,dir,byUnit){var target=start+dir;if(byUnit)while(target>0&&isExtendingChar(line.text.charAt(target)))target+=dir;return target<0||target>line.text.length?null:target;}
var bidiOrdering=(function(){var lowTypes="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";var arabicTypes="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";function charType(code){if(code<=0xf7)return lowTypes.charAt(code);else if(0x590<=code&&code<=0x5f4)return"R";else if(0x600<=code&&code<=0x6ed)return arabicTypes.charAt(code-0x600);else if(0x6ee<=code&&code<=0x8ac)return"r";else if(0x2000<=code&&code<=0x200b)return"w";else if(code==0x200c)return"b";else return"L";}
var bidiRE=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;var isNeutral=/[stwN]/,isStrong=/[LRr]/,countsAsLeft=/[Lb1n]/,countsAsNum=/[1n]/;var outerType="L";function BidiSpan(level,from,to){this.level=level;this.from=from;this.to=to;}
return function(str){if(!bidiRE.test(str))return false;var len=str.length,types=[];for(var i=0,type;i<len;++i)
types.push(type=charType(str.charCodeAt(i)));for(var i=0,prev=outerType;i<len;++i){var type=types[i];if(type=="m")types[i]=prev;else prev=type;}
for(var i=0,cur=outerType;i<len;++i){var type=types[i];if(type=="1"&&cur=="r")types[i]="n";else if(isStrong.test(type)){cur=type;if(type=="r")types[i]="R";}}
for(var i=1,prev=types[0];i<len-1;++i){var type=types[i];if(type=="+"&&prev=="1"&&types[i+1]=="1")types[i]="1";else if(type==","&&prev==types[i+1]&&(prev=="1"||prev=="n"))types[i]=prev;prev=type;}
for(var i=0;i<len;++i){var type=types[i];if(type==",")types[i]="N";else if(type=="%"){for(var end=i+1;end<len&&types[end]=="%";++end){}
var replace=(i&&types[i-1]=="!")||(end<len&&types[end]=="1")?"1":"N";for(var j=i;j<end;++j)types[j]=replace;i=end-1;}}
for(var i=0,cur=outerType;i<len;++i){var type=types[i];if(cur=="L"&&type=="1")types[i]="L";else if(isStrong.test(type))cur=type;}
for(var i=0;i<len;++i){if(isNeutral.test(types[i])){for(var end=i+1;end<len&&isNeutral.test(types[end]);++end){}
var before=(i?types[i-1]:outerType)=="L";var after=(end<len?types[end]:outerType)=="L";var replace=before||after?"L":"R";for(var j=i;j<end;++j)types[j]=replace;i=end-1;}}
var order=[],m;for(var i=0;i<len;){if(countsAsLeft.test(types[i])){var start=i;for(++i;i<len&&countsAsLeft.test(types[i]);++i){}
order.push(new BidiSpan(0,start,i));}else{var pos=i,at=order.length;for(++i;i<len&&types[i]!="L";++i){}
for(var j=pos;j<i;){if(countsAsNum.test(types[j])){if(pos<j)order.splice(at,0,new BidiSpan(1,pos,j));var nstart=j;for(++j;j<i&&countsAsNum.test(types[j]);++j){}
order.splice(at,0,new BidiSpan(2,nstart,j));pos=j;}else++j;}
if(pos<i)order.splice(at,0,new BidiSpan(1,pos,i));}}
if(order[0].level==1&&(m=str.match(/^\s+/))){order[0].from=m[0].length;order.unshift(new BidiSpan(0,0,m[0].length));}
if(lst(order).level==1&&(m=str.match(/\s+$/))){lst(order).to-=m[0].length;order.push(new BidiSpan(0,len-m[0].length,len));}
if(order[0].level!=lst(order).level)
order.push(new BidiSpan(order[0].level,len,len));return order;};})();CodeMirror.version="4.12.0";return CodeMirror;});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineMode("css",function(config,parserConfig){var inline=parserConfig.inline
if(!parserConfig.propertyKeywords)parserConfig=CodeMirror.resolveMode("text/css");var indentUnit=config.indentUnit,tokenHooks=parserConfig.tokenHooks,documentTypes=parserConfig.documentTypes||{},mediaTypes=parserConfig.mediaTypes||{},mediaFeatures=parserConfig.mediaFeatures||{},mediaValueKeywords=parserConfig.mediaValueKeywords||{},propertyKeywords=parserConfig.propertyKeywords||{},nonStandardPropertyKeywords=parserConfig.nonStandardPropertyKeywords||{},fontProperties=parserConfig.fontProperties||{},counterDescriptors=parserConfig.counterDescriptors||{},colorKeywords=parserConfig.colorKeywords||{},valueKeywords=parserConfig.valueKeywords||{},allowNested=parserConfig.allowNested,supportsAtComponent=parserConfig.supportsAtComponent===true;var type,override;function ret(style,tp){type=tp;return style;}
function tokenBase(stream,state){var ch=stream.next();if(tokenHooks[ch]){var result=tokenHooks[ch](stream,state);if(result!==false)return result;}
if(ch=="@"){stream.eatWhile(/[\w\\\-]/);return ret("def",stream.current());}else if(ch=="="||(ch=="~"||ch=="|")&&stream.eat("=")){return ret(null,"compare");}else if(ch=="\""||ch=="'"){state.tokenize=tokenString(ch);return state.tokenize(stream,state);}else if(ch=="#"){stream.eatWhile(/[\w\\\-]/);return ret("atom","hash");}else if(ch=="!"){stream.match(/^\s*\w*/);return ret("keyword","important");}else if(/\d/.test(ch)||ch=="."&&stream.eat(/\d/)){stream.eatWhile(/[\w.%]/);return ret("number","unit");}else if(ch==="-"){if(/[\d.]/.test(stream.peek())){stream.eatWhile(/[\w.%]/);return ret("number","unit");}else if(stream.match(/^-[\w\\\-]+/)){stream.eatWhile(/[\w\\\-]/);if(stream.match(/^\s*:/,false))
return ret("variable-2","variable-definition");return ret("variable-2","variable");}else if(stream.match(/^\w+-/)){return ret("meta","meta");}}else if(/[,+>*\/]/.test(ch)){return ret(null,"select-op");}else if(ch=="."&&stream.match(/^-?[_a-z][_a-z0-9-]*/i)){return ret("qualifier","qualifier");}else if(/[:;{}\[\]\(\)]/.test(ch)){return ret(null,ch);}else if((ch=="u"&&stream.match(/rl(-prefix)?\(/))||(ch=="d"&&stream.match("omain("))||(ch=="r"&&stream.match("egexp("))){stream.backUp(1);state.tokenize=tokenParenthesized;return ret("property","word");}else if(/[\w\\\-]/.test(ch)){stream.eatWhile(/[\w\\\-]/);return ret("property","word");}else{return ret(null,null);}}
function tokenString(quote){return function(stream,state){var escaped=false,ch;while((ch=stream.next())!=null){if(ch==quote&&!escaped){if(quote==")")stream.backUp(1);break;}
escaped=!escaped&&ch=="\\";}
if(ch==quote||!escaped&"e!=")")state.tokenize=null;return ret("string","string");};}
function tokenParenthesized(stream,state){stream.next();if(!stream.match(/\s*[\"\')]/,false))
state.tokenize=tokenString(")");else
state.tokenize=null;return ret(null,"(");}
function Context(type,indent,prev){this.type=type;this.indent=indent;this.prev=prev;}
function pushContext(state,stream,type,indent){state.context=new Context(type,stream.indentation()+(indent===false?0:indentUnit),state.context);return type;}
function popContext(state){if(state.context.prev)
state.context=state.context.prev;return state.context.type;}
function pass(type,stream,state){return states[state.context.type](type,stream,state);}
function popAndPass(type,stream,state,n){for(var i=n||1;i>0;i--)
state.context=state.context.prev;return pass(type,stream,state);}
function wordAsValue(stream){var word=stream.current().toLowerCase();if(valueKeywords.hasOwnProperty(word))
override="atom";else if(colorKeywords.hasOwnProperty(word))
override="keyword";else
override="variable";}
var states={};states.top=function(type,stream,state){if(type=="{"){return pushContext(state,stream,"block");}else if(type=="}"&&state.context.prev){return popContext(state);}else if(supportsAtComponent&&/@component/.test(type)){return pushContext(state,stream,"atComponentBlock");}else if(/^@(-moz-)?document$/.test(type)){return pushContext(state,stream,"documentTypes");}else if(/^@(media|supports|(-moz-)?document|import)$/.test(type)){return pushContext(state,stream,"atBlock");}else if(/^@(font-face|counter-style)/.test(type)){state.stateArg=type;return"restricted_atBlock_before";}else if(/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)){return"keyframes";}else if(type&&type.charAt(0)=="@"){return pushContext(state,stream,"at");}else if(type=="hash"){override="builtin";}else if(type=="word"){override="tag";}else if(type=="variable-definition"){return"maybeprop";}else if(type=="interpolation"){return pushContext(state,stream,"interpolation");}else if(type==":"){return"pseudo";}else if(allowNested&&type=="("){return pushContext(state,stream,"parens");}
return state.context.type;};states.block=function(type,stream,state){if(type=="word"){var word=stream.current().toLowerCase();if(propertyKeywords.hasOwnProperty(word)){override="property";return"maybeprop";}else if(nonStandardPropertyKeywords.hasOwnProperty(word)){override="string-2";return"maybeprop";}else if(allowNested){override=stream.match(/^\s*:(?:\s|$)/,false)?"property":"tag";return"block";}else{override+=" error";return"maybeprop";}}else if(type=="meta"){return"block";}else if(!allowNested&&(type=="hash"||type=="qualifier")){override="error";return"block";}else{return states.top(type,stream,state);}};states.maybeprop=function(type,stream,state){if(type==":")return pushContext(state,stream,"prop");return pass(type,stream,state);};states.prop=function(type,stream,state){if(type==";")return popContext(state);if(type=="{"&&allowNested)return pushContext(state,stream,"propBlock");if(type=="}"||type=="{")return popAndPass(type,stream,state);if(type=="(")return pushContext(state,stream,"parens");if(type=="hash"&&!/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())){override+=" error";}else if(type=="word"){wordAsValue(stream);}else if(type=="interpolation"){return pushContext(state,stream,"interpolation");}
return"prop";};states.propBlock=function(type,_stream,state){if(type=="}")return popContext(state);if(type=="word"){override="property";return"maybeprop";}
return state.context.type;};states.parens=function(type,stream,state){if(type=="{"||type=="}")return popAndPass(type,stream,state);if(type==")")return popContext(state);if(type=="(")return pushContext(state,stream,"parens");if(type=="interpolation")return pushContext(state,stream,"interpolation");if(type=="word")wordAsValue(stream);return"parens";};states.pseudo=function(type,stream,state){if(type=="word"){override="variable-3";return state.context.type;}
return pass(type,stream,state);};states.documentTypes=function(type,stream,state){if(type=="word"&&documentTypes.hasOwnProperty(stream.current())){override="tag";return state.context.type;}else{return states.atBlock(type,stream,state);}};states.atBlock=function(type,stream,state){if(type=="(")return pushContext(state,stream,"atBlock_parens");if(type=="}"||type==";")return popAndPass(type,stream,state);if(type=="{")return popContext(state)&&pushContext(state,stream,allowNested?"block":"top");if(type=="interpolation")return pushContext(state,stream,"interpolation");if(type=="word"){var word=stream.current().toLowerCase();if(word=="only"||word=="not"||word=="and"||word=="or")
override="keyword";else if(mediaTypes.hasOwnProperty(word))
override="attribute";else if(mediaFeatures.hasOwnProperty(word))
override="property";else if(mediaValueKeywords.hasOwnProperty(word))
override="keyword";else if(propertyKeywords.hasOwnProperty(word))
override="property";else if(nonStandardPropertyKeywords.hasOwnProperty(word))
override="string-2";else if(valueKeywords.hasOwnProperty(word))
override="atom";else if(colorKeywords.hasOwnProperty(word))
override="keyword";else
override="error";}
return state.context.type;};states.atComponentBlock=function(type,stream,state){if(type=="}")
return popAndPass(type,stream,state);if(type=="{")
return popContext(state)&&pushContext(state,stream,allowNested?"block":"top",false);if(type=="word")
override="error";return state.context.type;};states.atBlock_parens=function(type,stream,state){if(type==")")return popContext(state);if(type=="{"||type=="}")return popAndPass(type,stream,state,2);return states.atBlock(type,stream,state);};states.restricted_atBlock_before=function(type,stream,state){if(type=="{")
return pushContext(state,stream,"restricted_atBlock");if(type=="word"&&state.stateArg=="@counter-style"){override="variable";return"restricted_atBlock_before";}
return pass(type,stream,state);};states.restricted_atBlock=function(type,stream,state){if(type=="}"){state.stateArg=null;return popContext(state);}
if(type=="word"){if((state.stateArg=="@font-face"&&!fontProperties.hasOwnProperty(stream.current().toLowerCase()))||(state.stateArg=="@counter-style"&&!counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override="error";else
override="property";return"maybeprop";}
return"restricted_atBlock";};states.keyframes=function(type,stream,state){if(type=="word"){override="variable";return"keyframes";}
if(type=="{")return pushContext(state,stream,"top");return pass(type,stream,state);};states.at=function(type,stream,state){if(type==";")return popContext(state);if(type=="{"||type=="}")return popAndPass(type,stream,state);if(type=="word")override="tag";else if(type=="hash")override="builtin";return"at";};states.interpolation=function(type,stream,state){if(type=="}")return popContext(state);if(type=="{"||type==";")return popAndPass(type,stream,state);if(type=="word")override="variable";else if(type!="variable"&&type!="("&&type!=")")override="error";return"interpolation";};return{startState:function(base){return{tokenize:null,state:inline?"block":"top",stateArg:null,context:new Context(inline?"block":"top",base||0,null)};},token:function(stream,state){if(!state.tokenize&&stream.eatSpace())return null;var style=(state.tokenize||tokenBase)(stream,state);if(style&&typeof style=="object"){type=style[1];style=style[0];}
override=style;state.state=states[state.state](type,stream,state);return override;},indent:function(state,textAfter){var cx=state.context,ch=textAfter&&textAfter.charAt(0);var indent=cx.indent;if(cx.type=="prop"&&(ch=="}"||ch==")"))cx=cx.prev;if(cx.prev){if(ch=="}"&&(cx.type=="block"||cx.type=="top"||cx.type=="interpolation"||cx.type=="restricted_atBlock")){cx=cx.prev;indent=cx.indent;}else if(ch==")"&&(cx.type=="parens"||cx.type=="atBlock_parens")||ch=="{"&&(cx.type=="at"||cx.type=="atBlock")){indent=Math.max(0,cx.indent-indentUnit);cx=cx.prev;}}
return indent;},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",fold:"brace"};});function keySet(array){var keys={};for(var i=0;i<array.length;++i){keys[array[i]]=true;}
return keys;}
var documentTypes_=["domain","regexp","url","url-prefix"],documentTypes=keySet(documentTypes_);var mediaTypes_=["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"],mediaTypes=keySet(mediaTypes_);var mediaFeatures_=["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","orientation","device-pixel-ratio","min-device-pixel-ratio","max-device-pixel-ratio","pointer","any-pointer","hover","any-hover"],mediaFeatures=keySet(mediaFeatures_);var mediaValueKeywords_=["landscape","portrait","none","coarse","fine","on-demand","hover","interlace","progressive"],mediaValueKeywords=keySet(mediaValueKeywords_);var propertyKeywords_=["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode"],propertyKeywords=keySet(propertyKeywords_);var nonStandardPropertyKeywords_=["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"],nonStandardPropertyKeywords=keySet(nonStandardPropertyKeywords_);var fontProperties_=["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"],fontProperties=keySet(fontProperties_);var counterDescriptors_=["additive-symbols","fallback","negative","pad","prefix","range","speak-as","suffix","symbols","system"],counterDescriptors=keySet(counterDescriptors_);var colorKeywords_=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],colorKeywords=keySet(colorKeywords_);var valueKeywords_=["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","color","color-burn","color-dodge","column","column-reverse","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","darken","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","difference","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","exclusion","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hard-light","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","hue","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","lighten","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","luminosity","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","multiply","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","saturation","scale","scale3d","scaleX","scaleY","scaleZ","screen","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","soft-light","solid","somali","source-atop","source-in","source-out","source-over","space","space-around","space-between","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"],valueKeywords=keySet(valueKeywords_);var allWords=documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_).concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);CodeMirror.registerHelper("hintWords","css",allWords);function tokenCComment(stream,state){var maybeEnd=false,ch;while((ch=stream.next())!=null){if(maybeEnd&&ch=="/"){state.tokenize=null;break;}
maybeEnd=(ch=="*");}
return["comment","comment"];}
CodeMirror.defineMIME("text/css",{documentTypes:documentTypes,mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,fontProperties:fontProperties,counterDescriptors:counterDescriptors,colorKeywords:colorKeywords,valueKeywords:valueKeywords,tokenHooks:{"/":function(stream,state){if(!stream.eat("*"))return false;state.tokenize=tokenCComment;return tokenCComment(stream,state);}},name:"css"});CodeMirror.defineMIME("text/x-scss",{mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,fontProperties:fontProperties,allowNested:true,tokenHooks:{"/":function(stream,state){if(stream.eat("/")){stream.skipToEnd();return["comment","comment"];}else if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}else{return["operator","operator"];}},":":function(stream){if(stream.match(/\s*\{/))
return[null,"{"];return false;},"$":function(stream){stream.match(/^[\w-]+/);if(stream.match(/^\s*:/,false))
return["variable-2","variable-definition"];return["variable-2","variable"];},"#":function(stream){if(!stream.eat("{"))return false;return[null,"interpolation"];}},name:"css",helperType:"scss"});CodeMirror.defineMIME("text/x-less",{mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,mediaValueKeywords:mediaValueKeywords,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,fontProperties:fontProperties,allowNested:true,tokenHooks:{"/":function(stream,state){if(stream.eat("/")){stream.skipToEnd();return["comment","comment"];}else if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}else{return["operator","operator"];}},"@":function(stream){if(stream.eat("{"))return[null,"interpolation"];if(stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/,false))return false;stream.eatWhile(/[\w\\\-]/);if(stream.match(/^\s*:/,false))
return["variable-2","variable-definition"];return["variable-2","variable"];},"&":function(){return["atom","atom"];}},name:"css",helperType:"less"});CodeMirror.defineMIME("text/x-gss",{documentTypes:documentTypes,mediaTypes:mediaTypes,mediaFeatures:mediaFeatures,propertyKeywords:propertyKeywords,nonStandardPropertyKeywords:nonStandardPropertyKeywords,fontProperties:fontProperties,counterDescriptors:counterDescriptors,colorKeywords:colorKeywords,valueKeywords:valueKeywords,supportsAtComponent:true,tokenHooks:{"/":function(stream,state){if(!stream.eat("*"))return false;state.tokenize=tokenCComment;return tokenCComment(stream,state);}},name:"css",helperType:"gss"});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";function expressionAllowed(stream,state,backUp){return/^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType)||(state.lastType=="quasi"&&/\{\s*$/.test(stream.string.slice(0,stream.pos-(backUp||0))))}
CodeMirror.defineMode("javascript",function(config,parserConfig){var indentUnit=config.indentUnit;var statementIndent=parserConfig.statementIndent;var jsonldMode=parserConfig.jsonld;var jsonMode=parserConfig.json||jsonldMode;var isTS=parserConfig.typescript;var wordRE=parserConfig.wordCharacters||/[\w$\xa1-\uffff]/;var keywords=function(){function kw(type){return{type:type,style:"keyword"};}
var A=kw("keyword a"),B=kw("keyword b"),C=kw("keyword c");var operator=kw("operator"),atom={type:"atom",style:"atom"};var jsKeywords={"if":kw("if"),"while":A,"with":A,"else":B,"do":B,"try":B,"finally":B,"return":C,"break":C,"continue":C,"new":kw("new"),"delete":C,"throw":C,"debugger":C,"var":kw("var"),"const":kw("var"),"let":kw("var"),"function":kw("function"),"catch":kw("catch"),"for":kw("for"),"switch":kw("switch"),"case":kw("case"),"default":kw("default"),"in":operator,"typeof":operator,"instanceof":operator,"true":atom,"false":atom,"null":atom,"undefined":atom,"NaN":atom,"Infinity":atom,"this":kw("this"),"class":kw("class"),"super":kw("atom"),"yield":C,"export":kw("export"),"import":kw("import"),"extends":C};if(isTS){var type={type:"variable",style:"variable-3"};var tsKeywords={"interface":kw("class"),"implements":C,"namespace":C,"module":kw("module"),"enum":kw("module"),"public":kw("modifier"),"private":kw("modifier"),"protected":kw("modifier"),"abstract":kw("modifier"),"as":operator,"string":type,"number":type,"boolean":type,"any":type};for(var attr in tsKeywords){jsKeywords[attr]=tsKeywords[attr];}}
return jsKeywords;}();var isOperatorChar=/[+\-*&%=<>!?|~^]/;var isJsonldKeyword=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;function readRegexp(stream){var escaped=false,next,inSet=false;while((next=stream.next())!=null){if(!escaped){if(next=="/"&&!inSet)return;if(next=="[")inSet=true;else if(inSet&&next=="]")inSet=false;}
escaped=!escaped&&next=="\\";}}
var type,content;function ret(tp,style,cont){type=tp;content=cont;return style;}
function tokenBase(stream,state){var ch=stream.next();if(ch=='"'||ch=="'"){state.tokenize=tokenString(ch);return state.tokenize(stream,state);}else if(ch=="."&&stream.match(/^\d+(?:[eE][+\-]?\d+)?/)){return ret("number","number");}else if(ch=="."&&stream.match("..")){return ret("spread","meta");}else if(/[\[\]{}\(\),;\:\.]/.test(ch)){return ret(ch);}else if(ch=="="&&stream.eat(">")){return ret("=>","operator");}else if(ch=="0"&&stream.eat(/x/i)){stream.eatWhile(/[\da-f]/i);return ret("number","number");}else if(ch=="0"&&stream.eat(/o/i)){stream.eatWhile(/[0-7]/i);return ret("number","number");}else if(ch=="0"&&stream.eat(/b/i)){stream.eatWhile(/[01]/i);return ret("number","number");}else if(/\d/.test(ch)){stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);return ret("number","number");}else if(ch=="/"){if(stream.eat("*")){state.tokenize=tokenComment;return tokenComment(stream,state);}else if(stream.eat("/")){stream.skipToEnd();return ret("comment","comment");}else if(expressionAllowed(stream,state,1)){readRegexp(stream);stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);return ret("regexp","string-2");}else{stream.eatWhile(isOperatorChar);return ret("operator","operator",stream.current());}}else if(ch=="`"){state.tokenize=tokenQuasi;return tokenQuasi(stream,state);}else if(ch=="#"){stream.skipToEnd();return ret("error","error");}else if(isOperatorChar.test(ch)){stream.eatWhile(isOperatorChar);return ret("operator","operator",stream.current());}else if(wordRE.test(ch)){stream.eatWhile(wordRE);var word=stream.current(),known=keywords.propertyIsEnumerable(word)&&keywords[word];return(known&&state.lastType!=".")?ret(known.type,known.style,word):ret("variable","variable",word);}}
function tokenString(quote){return function(stream,state){var escaped=false,next;if(jsonldMode&&stream.peek()=="@"&&stream.match(isJsonldKeyword)){state.tokenize=tokenBase;return ret("jsonld-keyword","meta");}
while((next=stream.next())!=null){if(next==quote&&!escaped)break;escaped=!escaped&&next=="\\";}
if(!escaped)state.tokenize=tokenBase;return ret("string","string");};}
function tokenComment(stream,state){var maybeEnd=false,ch;while(ch=stream.next()){if(ch=="/"&&maybeEnd){state.tokenize=tokenBase;break;}
maybeEnd=(ch=="*");}
return ret("comment","comment");}
function tokenQuasi(stream,state){var escaped=false,next;while((next=stream.next())!=null){if(!escaped&&(next=="`"||next=="$"&&stream.eat("{"))){state.tokenize=tokenBase;break;}
escaped=!escaped&&next=="\\";}
return ret("quasi","string-2",stream.current());}
var brackets="([{}])";function findFatArrow(stream,state){if(state.fatArrowAt)state.fatArrowAt=null;var arrow=stream.string.indexOf("=>",stream.start);if(arrow<0)return;var depth=0,sawSomething=false;for(var pos=arrow-1;pos>=0;--pos){var ch=stream.string.charAt(pos);var bracket=brackets.indexOf(ch);if(bracket>=0&&bracket<3){if(!depth){++pos;break;}
if(--depth==0)break;}else if(bracket>=3&&bracket<6){++depth;}else if(wordRE.test(ch)){sawSomething=true;}else if(/["'\/]/.test(ch)){return;}else if(sawSomething&&!depth){++pos;break;}}
if(sawSomething&&!depth)state.fatArrowAt=pos;}
var atomicTypes={"atom":true,"number":true,"variable":true,"string":true,"regexp":true,"this":true,"jsonld-keyword":true};function JSLexical(indented,column,type,align,prev,info){this.indented=indented;this.column=column;this.type=type;this.prev=prev;this.info=info;if(align!=null)this.align=align;}
function inScope(state,varname){for(var v=state.localVars;v;v=v.next)
if(v.name==varname)return true;for(var cx=state.context;cx;cx=cx.prev){for(var v=cx.vars;v;v=v.next)
if(v.name==varname)return true;}}
function parseJS(state,style,type,content,stream){var cc=state.cc;cx.state=state;cx.stream=stream;cx.marked=null,cx.cc=cc;cx.style=style;if(!state.lexical.hasOwnProperty("align"))
state.lexical.align=true;while(true){var combinator=cc.length?cc.pop():jsonMode?expression:statement;if(combinator(type,content)){while(cc.length&&cc[cc.length-1].lex)
cc.pop()();if(cx.marked)return cx.marked;if(type=="variable"&&inScope(state,content))return"variable-2";return style;}}}
var cx={state:null,column:null,marked:null,cc:null};function pass(){for(var i=arguments.length-1;i>=0;i--)cx.cc.push(arguments[i]);}
function cont(){pass.apply(null,arguments);return true;}
function register(varname){function inList(list){for(var v=list;v;v=v.next)
if(v.name==varname)return true;return false;}
var state=cx.state;cx.marked="def";if(state.context){if(inList(state.localVars))return;state.localVars={name:varname,next:state.localVars};}else{if(inList(state.globalVars))return;if(parserConfig.globalVars)
state.globalVars={name:varname,next:state.globalVars};}}
var defaultVars={name:"this",next:{name:"arguments"}};function pushcontext(){cx.state.context={prev:cx.state.context,vars:cx.state.localVars};cx.state.localVars=defaultVars;}
function popcontext(){cx.state.localVars=cx.state.context.vars;cx.state.context=cx.state.context.prev;}
function pushlex(type,info){var result=function(){var state=cx.state,indent=state.indented;if(state.lexical.type=="stat")indent=state.lexical.indented;else for(var outer=state.lexical;outer&&outer.type==")"&&outer.align;outer=outer.prev)
indent=outer.indented;state.lexical=new JSLexical(indent,cx.stream.column(),type,null,state.lexical,info);};result.lex=true;return result;}
function poplex(){var state=cx.state;if(state.lexical.prev){if(state.lexical.type==")")
state.indented=state.lexical.indented;state.lexical=state.lexical.prev;}}
poplex.lex=true;function expect(wanted){function exp(type){if(type==wanted)return cont();else if(wanted==";")return pass();else return cont(exp);};return exp;}
function statement(type,value){if(type=="var")return cont(pushlex("vardef",value.length),vardef,expect(";"),poplex);if(type=="keyword a")return cont(pushlex("form"),expression,statement,poplex);if(type=="keyword b")return cont(pushlex("form"),statement,poplex);if(type=="{")return cont(pushlex("}"),block,poplex);if(type==";")return cont();if(type=="if"){if(cx.state.lexical.info=="else"&&cx.state.cc[cx.state.cc.length-1]==poplex)
cx.state.cc.pop()();return cont(pushlex("form"),expression,statement,poplex,maybeelse);}
if(type=="function")return cont(functiondef);if(type=="for")return cont(pushlex("form"),forspec,statement,poplex);if(type=="variable")return cont(pushlex("stat"),maybelabel);if(type=="switch")return cont(pushlex("form"),expression,pushlex("}","switch"),expect("{"),block,poplex,poplex);if(type=="case")return cont(expression,expect(":"));if(type=="default")return cont(expect(":"));if(type=="catch")return cont(pushlex("form"),pushcontext,expect("("),funarg,expect(")"),statement,poplex,popcontext);if(type=="class")return cont(pushlex("form"),className,poplex);if(type=="export")return cont(pushlex("stat"),afterExport,poplex);if(type=="import")return cont(pushlex("stat"),afterImport,poplex);if(type=="module")return cont(pushlex("form"),pattern,pushlex("}"),expect("{"),block,poplex,poplex)
return pass(pushlex("stat"),expression,expect(";"),poplex);}
function expression(type){return expressionInner(type,false);}
function expressionNoComma(type){return expressionInner(type,true);}
function expressionInner(type,noComma){if(cx.state.fatArrowAt==cx.stream.start){var body=noComma?arrowBodyNoComma:arrowBody;if(type=="(")return cont(pushcontext,pushlex(")"),commasep(pattern,")"),poplex,expect("=>"),body,popcontext);else if(type=="variable")return pass(pushcontext,pattern,expect("=>"),body,popcontext);}
var maybeop=noComma?maybeoperatorNoComma:maybeoperatorComma;if(atomicTypes.hasOwnProperty(type))return cont(maybeop);if(type=="function")return cont(functiondef,maybeop);if(type=="keyword c")return cont(noComma?maybeexpressionNoComma:maybeexpression);if(type=="(")return cont(pushlex(")"),maybeexpression,comprehension,expect(")"),poplex,maybeop);if(type=="operator"||type=="spread")return cont(noComma?expressionNoComma:expression);if(type=="[")return cont(pushlex("]"),arrayLiteral,poplex,maybeop);if(type=="{")return contCommasep(objprop,"}",null,maybeop);if(type=="quasi")return pass(quasi,maybeop);if(type=="new")return cont(maybeTarget(noComma));return cont();}
function maybeexpression(type){if(type.match(/[;\}\)\],]/))return pass();return pass(expression);}
function maybeexpressionNoComma(type){if(type.match(/[;\}\)\],]/))return pass();return pass(expressionNoComma);}
function maybeoperatorComma(type,value){if(type==",")return cont(expression);return maybeoperatorNoComma(type,value,false);}
function maybeoperatorNoComma(type,value,noComma){var me=noComma==false?maybeoperatorComma:maybeoperatorNoComma;var expr=noComma==false?expression:expressionNoComma;if(type=="=>")return cont(pushcontext,noComma?arrowBodyNoComma:arrowBody,popcontext);if(type=="operator"){if(/\+\+|--/.test(value))return cont(me);if(value=="?")return cont(expression,expect(":"),expr);return cont(expr);}
if(type=="quasi"){return pass(quasi,me);}
if(type==";")return;if(type=="(")return contCommasep(expressionNoComma,")","call",me);if(type==".")return cont(property,me);if(type=="[")return cont(pushlex("]"),maybeexpression,expect("]"),poplex,me);}
function quasi(type,value){if(type!="quasi")return pass();if(value.slice(value.length-2)!="${")return cont(quasi);return cont(expression,continueQuasi);}
function continueQuasi(type){if(type=="}"){cx.marked="string-2";cx.state.tokenize=tokenQuasi;return cont(quasi);}}
function arrowBody(type){findFatArrow(cx.stream,cx.state);return pass(type=="{"?statement:expression);}
function arrowBodyNoComma(type){findFatArrow(cx.stream,cx.state);return pass(type=="{"?statement:expressionNoComma);}
function maybeTarget(noComma){return function(type){if(type==".")return cont(noComma?targetNoComma:target);else return pass(noComma?expressionNoComma:expression);};}
function target(_,value){if(value=="target"){cx.marked="keyword";return cont(maybeoperatorComma);}}
function targetNoComma(_,value){if(value=="target"){cx.marked="keyword";return cont(maybeoperatorNoComma);}}
function maybelabel(type){if(type==":")return cont(poplex,statement);return pass(maybeoperatorComma,expect(";"),poplex);}
function property(type){if(type=="variable"){cx.marked="property";return cont();}}
function objprop(type,value){if(type=="variable"||cx.style=="keyword"){cx.marked="property";if(value=="get"||value=="set")return cont(getterSetter);return cont(afterprop);}else if(type=="number"||type=="string"){cx.marked=jsonldMode?"property":(cx.style+" property");return cont(afterprop);}else if(type=="jsonld-keyword"){return cont(afterprop);}else if(type=="modifier"){return cont(objprop)}else if(type=="["){return cont(expression,expect("]"),afterprop);}else if(type=="spread"){return cont(expression);}}
function getterSetter(type){if(type!="variable")return pass(afterprop);cx.marked="property";return cont(functiondef);}
function afterprop(type){if(type==":")return cont(expressionNoComma);if(type=="(")return pass(functiondef);}
function commasep(what,end){function proceed(type){if(type==","){var lex=cx.state.lexical;if(lex.info=="call")lex.pos=(lex.pos||0)+1;return cont(what,proceed);}
if(type==end)return cont();return cont(expect(end));}
return function(type){if(type==end)return cont();return pass(what,proceed);};}
function contCommasep(what,end,info){for(var i=3;i<arguments.length;i++)
cx.cc.push(arguments[i]);return cont(pushlex(end,info),commasep(what,end),poplex);}
function block(type){if(type=="}")return cont();return pass(statement,block);}
function maybetype(type){if(isTS&&type==":")return cont(typedef);}
function maybedefault(_,value){if(value=="=")return cont(expressionNoComma);}
function typedef(type){if(type=="variable"){cx.marked="variable-3";return cont();}}
function vardef(){return pass(pattern,maybetype,maybeAssign,vardefCont);}
function pattern(type,value){if(type=="modifier")return cont(pattern)
if(type=="variable"){register(value);return cont();}
if(type=="spread")return cont(pattern);if(type=="[")return contCommasep(pattern,"]");if(type=="{")return contCommasep(proppattern,"}");}
function proppattern(type,value){if(type=="variable"&&!cx.stream.match(/^\s*:/,false)){register(value);return cont(maybeAssign);}
if(type=="variable")cx.marked="property";if(type=="spread")return cont(pattern);if(type=="}")return pass();return cont(expect(":"),pattern,maybeAssign);}
function maybeAssign(_type,value){if(value=="=")return cont(expressionNoComma);}
function vardefCont(type){if(type==",")return cont(vardef);}
function maybeelse(type,value){if(type=="keyword b"&&value=="else")return cont(pushlex("form","else"),statement,poplex);}
function forspec(type){if(type=="(")return cont(pushlex(")"),forspec1,expect(")"),poplex);}
function forspec1(type){if(type=="var")return cont(vardef,expect(";"),forspec2);if(type==";")return cont(forspec2);if(type=="variable")return cont(formaybeinof);return pass(expression,expect(";"),forspec2);}
function formaybeinof(_type,value){if(value=="in"||value=="of"){cx.marked="keyword";return cont(expression);}
return cont(maybeoperatorComma,forspec2);}
function forspec2(type,value){if(type==";")return cont(forspec3);if(value=="in"||value=="of"){cx.marked="keyword";return cont(expression);}
return pass(expression,expect(";"),forspec3);}
function forspec3(type){if(type!=")")cont(expression);}
function functiondef(type,value){if(value=="*"){cx.marked="keyword";return cont(functiondef);}
if(type=="variable"){register(value);return cont(functiondef);}
if(type=="(")return cont(pushcontext,pushlex(")"),commasep(funarg,")"),poplex,statement,popcontext);}
function funarg(type){if(type=="spread")return cont(funarg);return pass(pattern,maybetype,maybedefault);}
function className(type,value){if(type=="variable"){register(value);return cont(classNameAfter);}}
function classNameAfter(type,value){if(value=="extends")return cont(expression,classNameAfter);if(type=="{")return cont(pushlex("}"),classBody,poplex);}
function classBody(type,value){if(type=="variable"||cx.style=="keyword"){if(value=="static"){cx.marked="keyword";return cont(classBody);}
cx.marked="property";if(value=="get"||value=="set")return cont(classGetterSetter,functiondef,classBody);return cont(functiondef,classBody);}
if(value=="*"){cx.marked="keyword";return cont(classBody);}
if(type==";")return cont(classBody);if(type=="}")return cont();}
function classGetterSetter(type){if(type!="variable")return pass();cx.marked="property";return cont();}
function afterExport(_type,value){if(value=="*"){cx.marked="keyword";return cont(maybeFrom,expect(";"));}
if(value=="default"){cx.marked="keyword";return cont(expression,expect(";"));}
return pass(statement);}
function afterImport(type){if(type=="string")return cont();return pass(importSpec,maybeFrom);}
function importSpec(type,value){if(type=="{")return contCommasep(importSpec,"}");if(type=="variable")register(value);if(value=="*")cx.marked="keyword";return cont(maybeAs);}
function maybeAs(_type,value){if(value=="as"){cx.marked="keyword";return cont(importSpec);}}
function maybeFrom(_type,value){if(value=="from"){cx.marked="keyword";return cont(expression);}}
function arrayLiteral(type){if(type=="]")return cont();return pass(expressionNoComma,maybeArrayComprehension);}
function maybeArrayComprehension(type){if(type=="for")return pass(comprehension,expect("]"));if(type==",")return cont(commasep(maybeexpressionNoComma,"]"));return pass(commasep(expressionNoComma,"]"));}
function comprehension(type){if(type=="for")return cont(forspec,comprehension);if(type=="if")return cont(expression,comprehension);}
function isContinuedStatement(state,textAfter){return state.lastType=="operator"||state.lastType==","||isOperatorChar.test(textAfter.charAt(0))||/[,.]/.test(textAfter.charAt(0));}
return{startState:function(basecolumn){var state={tokenize:tokenBase,lastType:"sof",cc:[],lexical:new JSLexical((basecolumn||0)-indentUnit,0,"block",false),localVars:parserConfig.localVars,context:parserConfig.localVars&&{vars:parserConfig.localVars},indented:basecolumn||0};if(parserConfig.globalVars&&typeof parserConfig.globalVars=="object")
state.globalVars=parserConfig.globalVars;return state;},token:function(stream,state){if(stream.sol()){if(!state.lexical.hasOwnProperty("align"))
state.lexical.align=false;state.indented=stream.indentation();findFatArrow(stream,state);}
if(state.tokenize!=tokenComment&&stream.eatSpace())return null;var style=state.tokenize(stream,state);if(type=="comment")return style;state.lastType=type=="operator"&&(content=="++"||content=="--")?"incdec":type;return parseJS(state,style,type,content,stream);},indent:function(state,textAfter){if(state.tokenize==tokenComment)return CodeMirror.Pass;if(state.tokenize!=tokenBase)return 0;var firstChar=textAfter&&textAfter.charAt(0),lexical=state.lexical;if(!/^\s*else\b/.test(textAfter))for(var i=state.cc.length-1;i>=0;--i){var c=state.cc[i];if(c==poplex)lexical=lexical.prev;else if(c!=maybeelse)break;}
if(lexical.type=="stat"&&firstChar=="}")lexical=lexical.prev;if(statementIndent&&lexical.type==")"&&lexical.prev.type=="stat")
lexical=lexical.prev;var type=lexical.type,closing=firstChar==type;if(type=="vardef")return lexical.indented+(state.lastType=="operator"||state.lastType==","?lexical.info+1:0);else if(type=="form"&&firstChar=="{")return lexical.indented;else if(type=="form")return lexical.indented+indentUnit;else if(type=="stat")
return lexical.indented+(isContinuedStatement(state,textAfter)?statementIndent||indentUnit:0);else if(lexical.info=="switch"&&!closing&&parserConfig.doubleIndentSwitch!=false)
return lexical.indented+(/^(?:case|default)\b/.test(textAfter)?indentUnit:2*indentUnit);else if(lexical.align)return lexical.column+(closing?0:1);else return lexical.indented+(closing?0:indentUnit);},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:jsonMode?null:"/*",blockCommentEnd:jsonMode?null:"*/",lineComment:jsonMode?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:jsonMode?"json":"javascript",jsonldMode:jsonldMode,jsonMode:jsonMode,expressionAllowed:expressionAllowed,skipExpression:function(state){var top=state.cc[state.cc.length-1]
if(top==expression||top==expressionNoComma)state.cc.pop()}};});CodeMirror.registerHelper("wordChars","javascript",/[\w$]/);CodeMirror.defineMIME("text/javascript","javascript");CodeMirror.defineMIME("text/ecmascript","javascript");CodeMirror.defineMIME("application/javascript","javascript");CodeMirror.defineMIME("application/x-javascript","javascript");CodeMirror.defineMIME("application/ecmascript","javascript");CodeMirror.defineMIME("application/json",{name:"javascript",json:true});CodeMirror.defineMIME("application/x-json",{name:"javascript",json:true});CodeMirror.defineMIME("application/ld+json",{name:"javascript",jsonld:true});CodeMirror.defineMIME("text/typescript",{name:"javascript",typescript:true});CodeMirror.defineMIME("application/typescript",{name:"javascript",typescript:true});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineSimpleMode=function(name,states){CodeMirror.defineMode(name,function(config){return CodeMirror.simpleMode(config,states);});};CodeMirror.simpleMode=function(config,states){ensureState(states,"start");var states_={},meta=states.meta||{},hasIndentation=false;for(var state in states)if(state!=meta&&states.hasOwnProperty(state)){var list=states_[state]=[],orig=states[state];for(var i=0;i<orig.length;i++){var data=orig[i];list.push(new Rule(data,states));if(data.indent||data.dedent)hasIndentation=true;}}
var mode={startState:function(){return{state:"start",pending:null,local:null,localState:null,indent:hasIndentation?[]:null};},copyState:function(state){var s={state:state.state,pending:state.pending,local:state.local,localState:null,indent:state.indent&&state.indent.slice(0)};if(state.localState)
s.localState=CodeMirror.copyState(state.local.mode,state.localState);if(state.stack)
s.stack=state.stack.slice(0);for(var pers=state.persistentStates;pers;pers=pers.next)
s.persistentStates={mode:pers.mode,spec:pers.spec,state:pers.state==state.localState?s.localState:CodeMirror.copyState(pers.mode,pers.state),next:s.persistentStates};return s;},token:tokenFunction(states_,config),innerMode:function(state){return state.local&&{mode:state.local.mode,state:state.localState};},indent:indentFunction(states_,meta)};if(meta)for(var prop in meta)if(meta.hasOwnProperty(prop))
mode[prop]=meta[prop];return mode;};function ensureState(states,name){if(!states.hasOwnProperty(name))
throw new Error("Undefined state "+name+"in simple mode");}
function toRegex(val,caret){if(!val)return/(?:)/;var flags="";if(val instanceof RegExp){if(val.ignoreCase)flags="i";val=val.source;}else{val=String(val);}
return new RegExp((caret===false?"":"^")+"(?:"+val+")",flags);}
function asToken(val){if(!val)return null;if(typeof val=="string")return val.replace(/\./g," ");var result=[];for(var i=0;i<val.length;i++)
result.push(val[i]&&val[i].replace(/\./g," "));return result;}
function Rule(data,states){if(data.next||data.push)ensureState(states,data.next||data.push);this.regex=toRegex(data.regex);this.token=asToken(data.token);this.data=data;}
function tokenFunction(states,config){return function(stream,state){if(state.pending){var pend=state.pending.shift();if(state.pending.length==0)state.pending=null;stream.pos+=pend.text.length;return pend.token;}
if(state.local){if(state.local.end&&stream.match(state.local.end)){var tok=state.local.endToken||null;state.local=state.localState=null;return tok;}else{var tok=state.local.mode.token(stream,state.localState),m;if(state.local.endScan&&(m=state.local.endScan.exec(stream.current())))
stream.pos=stream.start+m.index;return tok;}}
var curState=states[state.state];for(var i=0;i<curState.length;i++){var rule=curState[i];var matches=(!rule.data.sol||stream.sol())&&stream.match(rule.regex);if(matches){if(rule.data.next){state.state=rule.data.next;}else if(rule.data.push){(state.stack||(state.stack=[])).push(state.state);state.state=rule.data.push;}else if(rule.data.pop&&state.stack&&state.stack.length){state.state=state.stack.pop();}
if(rule.data.mode)
enterLocalMode(config,state,rule.data.mode,rule.token);if(rule.data.indent)
state.indent.push(stream.indentation()+config.indentUnit);if(rule.data.dedent)
state.indent.pop();if(matches.length>2){state.pending=[];for(var j=2;j<matches.length;j++)
if(matches[j])
state.pending.push({text:matches[j],token:rule.token[j-1]});stream.backUp(matches[0].length-(matches[1]?matches[1].length:0));return rule.token[0];}else if(rule.token&&rule.token.join){return rule.token[0];}else{return rule.token;}}}
stream.next();return null;};}
function cmp(a,b){if(a===b)return true;if(!a||typeof a!="object"||!b||typeof b!="object")return false;var props=0;for(var prop in a)if(a.hasOwnProperty(prop)){if(!b.hasOwnProperty(prop)||!cmp(a[prop],b[prop]))return false;props++;}
for(var prop in b)if(b.hasOwnProperty(prop))props--;return props==0;}
function enterLocalMode(config,state,spec,token){var pers;if(spec.persistent)for(var p=state.persistentStates;p&&!pers;p=p.next)
if(spec.spec?cmp(spec.spec,p.spec):spec.mode==p.mode)pers=p;var mode=pers?pers.mode:spec.mode||CodeMirror.getMode(config,spec.spec);var lState=pers?pers.state:CodeMirror.startState(mode);if(spec.persistent&&!pers)
state.persistentStates={mode:mode,spec:spec.spec,state:lState,next:state.persistentStates};state.localState=lState;state.local={mode:mode,end:spec.end&&toRegex(spec.end),endScan:spec.end&&spec.forceEnd!==false&&toRegex(spec.end,false),endToken:token&&token.join?token[token.length-1]:token};}
function indexOf(val,arr){for(var i=0;i<arr.length;i++)if(arr[i]===val)return true;}
function indentFunction(states,meta){return function(state,textAfter,line){if(state.local&&state.local.mode.indent)
return state.local.mode.indent(state.localState,textAfter,line);if(state.indent==null||state.local||meta.dontIndentStates&&indexOf(state.state,meta.dontIndentStates)>-1)
return CodeMirror.Pass;var pos=state.indent.length-1,rules=states[state.state];scan:for(;;){for(var i=0;i<rules.length;i++){var rule=rules[i];if(rule.data.dedent&&rule.data.dedentIfLineStart!==false){var m=rule.regex.exec(textAfter);if(m&&m[0]){pos--;if(rule.next||rule.push)rules=states[rule.next||rule.push];textAfter=textAfter.slice(m[0].length);continue scan;}}}
break;}
return pos<0?0:state.indent[pos];};}});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";var htmlConfig={autoSelfClosers:{'area':true,'base':true,'br':true,'col':true,'command':true,'embed':true,'frame':true,'hr':true,'img':true,'input':true,'keygen':true,'link':true,'meta':true,'param':true,'source':true,'track':true,'wbr':true,'menuitem':true},implicitlyClosed:{'dd':true,'li':true,'optgroup':true,'option':true,'p':true,'rp':true,'rt':true,'tbody':true,'td':true,'tfoot':true,'th':true,'tr':true},contextGrabbers:{'dd':{'dd':true,'dt':true},'dt':{'dd':true,'dt':true},'li':{'li':true},'option':{'option':true,'optgroup':true},'optgroup':{'optgroup':true},'p':{'address':true,'article':true,'aside':true,'blockquote':true,'dir':true,'div':true,'dl':true,'fieldset':true,'footer':true,'form':true,'h1':true,'h2':true,'h3':true,'h4':true,'h5':true,'h6':true,'header':true,'hgroup':true,'hr':true,'menu':true,'nav':true,'ol':true,'p':true,'pre':true,'section':true,'table':true,'ul':true},'rp':{'rp':true,'rt':true},'rt':{'rp':true,'rt':true},'tbody':{'tbody':true,'tfoot':true},'td':{'td':true,'th':true},'tfoot':{'tbody':true},'th':{'td':true,'th':true},'thead':{'tbody':true,'tfoot':true},'tr':{'tr':true}},doNotIndent:{"pre":true},allowUnquoted:true,allowMissing:true,caseFold:true}
var xmlConfig={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:false,allowMissing:false,caseFold:false}
CodeMirror.defineMode("xml",function(editorConf,config_){var indentUnit=editorConf.indentUnit
var config={}
var defaults=config_.htmlMode?htmlConfig:xmlConfig
for(var prop in defaults)config[prop]=defaults[prop]
for(var prop in config_)config[prop]=config_[prop]
var type,setStyle;function inText(stream,state){function chain(parser){state.tokenize=parser;return parser(stream,state);}
var ch=stream.next();if(ch=="<"){if(stream.eat("!")){if(stream.eat("[")){if(stream.match("CDATA["))return chain(inBlock("atom","]]>"));else return null;}else if(stream.match("--")){return chain(inBlock("comment","-->"));}else if(stream.match("DOCTYPE",true,true)){stream.eatWhile(/[\w\._\-]/);return chain(doctype(1));}else{return null;}}else if(stream.eat("?")){stream.eatWhile(/[\w\._\-]/);state.tokenize=inBlock("meta","?>");return"meta";}else{type=stream.eat("/")?"closeTag":"openTag";state.tokenize=inTag;return"tag bracket";}}else if(ch=="&"){var ok;if(stream.eat("#")){if(stream.eat("x")){ok=stream.eatWhile(/[a-fA-F\d]/)&&stream.eat(";");}else{ok=stream.eatWhile(/[\d]/)&&stream.eat(";");}}else{ok=stream.eatWhile(/[\w\.\-:]/)&&stream.eat(";");}
return ok?"atom":"error";}else{stream.eatWhile(/[^&<]/);return null;}}
inText.isInText=true;function inTag(stream,state){var ch=stream.next();if(ch==">"||(ch=="/"&&stream.eat(">"))){state.tokenize=inText;type=ch==">"?"endTag":"selfcloseTag";return"tag bracket";}else if(ch=="="){type="equals";return null;}else if(ch=="<"){state.tokenize=inText;state.state=baseState;state.tagName=state.tagStart=null;var next=state.tokenize(stream,state);return next?next+" tag error":"tag error";}else if(/[\'\"]/.test(ch)){state.tokenize=inAttribute(ch);state.stringStartCol=stream.column();return state.tokenize(stream,state);}else{stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);return"word";}}
function inAttribute(quote){var closure=function(stream,state){while(!stream.eol()){if(stream.next()==quote){state.tokenize=inTag;break;}}
return"string";};closure.isInAttribute=true;return closure;}
function inBlock(style,terminator){return function(stream,state){while(!stream.eol()){if(stream.match(terminator)){state.tokenize=inText;break;}
stream.next();}
return style;};}
function doctype(depth){return function(stream,state){var ch;while((ch=stream.next())!=null){if(ch=="<"){state.tokenize=doctype(depth+1);return state.tokenize(stream,state);}else if(ch==">"){if(depth==1){state.tokenize=inText;break;}else{state.tokenize=doctype(depth-1);return state.tokenize(stream,state);}}}
return"meta";};}
function Context(state,tagName,startOfLine){this.prev=state.context;this.tagName=tagName;this.indent=state.indented;this.startOfLine=startOfLine;if(config.doNotIndent.hasOwnProperty(tagName)||(state.context&&state.context.noIndent))
this.noIndent=true;}
function popContext(state){if(state.context)state.context=state.context.prev;}
function maybePopContext(state,nextTagName){var parentTagName;while(true){if(!state.context){return;}
parentTagName=state.context.tagName;if(!config.contextGrabbers.hasOwnProperty(parentTagName)||!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)){return;}
popContext(state);}}
function baseState(type,stream,state){if(type=="openTag"){state.tagStart=stream.column();return tagNameState;}else if(type=="closeTag"){return closeTagNameState;}else{return baseState;}}
function tagNameState(type,stream,state){if(type=="word"){state.tagName=stream.current();setStyle="tag";return attrState;}else{setStyle="error";return tagNameState;}}
function closeTagNameState(type,stream,state){if(type=="word"){var tagName=stream.current();if(state.context&&state.context.tagName!=tagName&&config.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);if((state.context&&state.context.tagName==tagName)||config.matchClosing===false){setStyle="tag";return closeState;}else{setStyle="tag error";return closeStateErr;}}else{setStyle="error";return closeStateErr;}}
function closeState(type,_stream,state){if(type!="endTag"){setStyle="error";return closeState;}
popContext(state);return baseState;}
function closeStateErr(type,stream,state){setStyle="error";return closeState(type,stream,state);}
function attrState(type,_stream,state){if(type=="word"){setStyle="attribute";return attrEqState;}else if(type=="endTag"||type=="selfcloseTag"){var tagName=state.tagName,tagStart=state.tagStart;state.tagName=state.tagStart=null;if(type=="selfcloseTag"||config.autoSelfClosers.hasOwnProperty(tagName)){maybePopContext(state,tagName);}else{maybePopContext(state,tagName);state.context=new Context(state,tagName,tagStart==state.indented);}
return baseState;}
setStyle="error";return attrState;}
function attrEqState(type,stream,state){if(type=="equals")return attrValueState;if(!config.allowMissing)setStyle="error";return attrState(type,stream,state);}
function attrValueState(type,stream,state){if(type=="string")return attrContinuedState;if(type=="word"&&config.allowUnquoted){setStyle="string";return attrState;}
setStyle="error";return attrState(type,stream,state);}
function attrContinuedState(type,stream,state){if(type=="string")return attrContinuedState;return attrState(type,stream,state);}
return{startState:function(baseIndent){var state={tokenize:inText,state:baseState,indented:baseIndent||0,tagName:null,tagStart:null,context:null}
if(baseIndent!=null)state.baseIndent=baseIndent
return state},token:function(stream,state){if(!state.tagName&&stream.sol())
state.indented=stream.indentation();if(stream.eatSpace())return null;type=null;var style=state.tokenize(stream,state);if((style||type)&&style!="comment"){setStyle=null;state.state=state.state(type||style,stream,state);if(setStyle)
style=setStyle=="error"?style+" error":setStyle;}
return style;},indent:function(state,textAfter,fullLine){var context=state.context;if(state.tokenize.isInAttribute){if(state.tagStart==state.indented)
return state.stringStartCol+1;else
return state.indented+indentUnit;}
if(context&&context.noIndent)return CodeMirror.Pass;if(state.tokenize!=inTag&&state.tokenize!=inText)
return fullLine?fullLine.match(/^(\s*)/)[0].length:0;if(state.tagName){if(config.multilineTagIndentPastTag!==false)
return state.tagStart+state.tagName.length+2;else
return state.tagStart+indentUnit*(config.multilineTagIndentFactor||1);}
if(config.alignCDATA&&/<!\[CDATA\[/.test(textAfter))return 0;var tagAfter=textAfter&&/^<(\/)?([\w_:\.-]*)/.exec(textAfter);if(tagAfter&&tagAfter[1]){while(context){if(context.tagName==tagAfter[2]){context=context.prev;break;}else if(config.implicitlyClosed.hasOwnProperty(context.tagName)){context=context.prev;}else{break;}}}else if(tagAfter){while(context){var grabbers=config.contextGrabbers[context.tagName];if(grabbers&&grabbers.hasOwnProperty(tagAfter[2]))
context=context.prev;else
break;}}
while(context&&context.prev&&!context.startOfLine)
context=context.prev;if(context)return context.indent+indentUnit;else return state.baseIndent||0;},electricInput:/<\/[\s\w:]+>$/,blockCommentStart:"<!--",blockCommentEnd:"-->",configuration:config.htmlMode?"html":"xml",helperType:config.htmlMode?"html":"xml",skipAttribute:function(state){if(state.state==attrValueState)
state.state=attrState}};});CodeMirror.defineMIME("text/xml","xml");CodeMirror.defineMIME("application/xml","xml");if(!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:true});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"),require("../xml/xml"),require("../javascript/javascript"),require("../css/css"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror","../xml/xml","../javascript/javascript","../css/css"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineMode("htmlmixed",function(config,parserConfig){var htmlMode=CodeMirror.getMode(config,{name:"xml",htmlMode:true,multilineTagIndentFactor:parserConfig.multilineTagIndentFactor,multilineTagIndentPastTag:parserConfig.multilineTagIndentPastTag});var cssMode=CodeMirror.getMode(config,"css");var scriptTypes=[],scriptTypesConf=parserConfig&&parserConfig.scriptTypes;scriptTypes.push({matches:/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,mode:CodeMirror.getMode(config,"javascript")});if(scriptTypesConf)for(var i=0;i<scriptTypesConf.length;++i){var conf=scriptTypesConf[i];scriptTypes.push({matches:conf.matches,mode:conf.mode&&CodeMirror.getMode(config,conf.mode)});}
scriptTypes.push({matches:/./,mode:CodeMirror.getMode(config,"text/plain")});function html(stream,state){var tagName=state.htmlState.tagName;if(tagName)tagName=tagName.toLowerCase();var style=htmlMode.token(stream,state.htmlState);if(tagName=="script"&&/\btag\b/.test(style)&&stream.current()==">"){var scriptType=stream.string.slice(Math.max(0,stream.pos-100),stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);scriptType=scriptType?scriptType[1]:"";if(scriptType&&/[\"\']/.test(scriptType.charAt(0)))scriptType=scriptType.slice(1,scriptType.length-1);for(var i=0;i<scriptTypes.length;++i){var tp=scriptTypes[i];if(typeof tp.matches=="string"?scriptType==tp.matches:tp.matches.test(scriptType)){if(tp.mode){state.token=script;state.localMode=tp.mode;state.localState=tp.mode.startState&&tp.mode.startState(htmlMode.indent(state.htmlState,""));}
break;}}}else if(tagName=="style"&&/\btag\b/.test(style)&&stream.current()==">"){state.token=css;state.localMode=cssMode;state.localState=cssMode.startState(htmlMode.indent(state.htmlState,""));}
return style;}
function maybeBackup(stream,pat,style){var cur=stream.current();var close=cur.search(pat),m;if(close>-1)stream.backUp(cur.length-close);else if(m=cur.match(/<\/?$/)){stream.backUp(cur.length);if(!stream.match(pat,false))stream.match(cur);}
return style;}
function script(stream,state){if(stream.match(/^<\/\s*script\s*>/i,false)){state.token=html;state.localState=state.localMode=null;return html(stream,state);}
return maybeBackup(stream,/<\/\s*script\s*>/,state.localMode.token(stream,state.localState));}
function css(stream,state){if(stream.match(/^<\/\s*style\s*>/i,false)){state.token=html;state.localState=state.localMode=null;return html(stream,state);}
return maybeBackup(stream,/<\/\s*style\s*>/,cssMode.token(stream,state.localState));}
return{startState:function(){var state=htmlMode.startState();return{token:html,localMode:null,localState:null,htmlState:state};},copyState:function(state){if(state.localState)
var local=CodeMirror.copyState(state.localMode,state.localState);return{token:state.token,localMode:state.localMode,localState:local,htmlState:CodeMirror.copyState(htmlMode,state.htmlState)};},token:function(stream,state){return state.token(stream,state);},indent:function(state,textAfter){if(!state.localMode||/^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState,textAfter);else if(state.localMode.indent)
return state.localMode.indent(state.localState,textAfter);else
return CodeMirror.Pass;},innerMode:function(state){return{state:state.localState||state.htmlState,mode:state.localMode||htmlMode};}};},"xml","javascript","css");CodeMirror.defineMIME("text/html","htmlmixed");});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"),require("../htmlmixed/htmlmixed"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror","../htmlmixed/htmlmixed"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineMode("htmlembedded",function(config,parserConfig){var scriptStartRegex=parserConfig.scriptStartRegex||/^<%/i,scriptEndRegex=parserConfig.scriptEndRegex||/^%>/i;var scriptingMode,htmlMixedMode;function htmlDispatch(stream,state){if(stream.match(scriptStartRegex,false)){state.token=scriptingDispatch;return scriptingMode.token(stream,state.scriptState);}
else
return htmlMixedMode.token(stream,state.htmlState);}
function scriptingDispatch(stream,state){if(stream.match(scriptEndRegex,false)){state.token=htmlDispatch;return htmlMixedMode.token(stream,state.htmlState);}
else
return scriptingMode.token(stream,state.scriptState);}
return{startState:function(){scriptingMode=scriptingMode||CodeMirror.getMode(config,parserConfig.scriptingModeSpec);htmlMixedMode=htmlMixedMode||CodeMirror.getMode(config,"htmlmixed");return{token:parserConfig.startOpen?scriptingDispatch:htmlDispatch,htmlState:CodeMirror.startState(htmlMixedMode),scriptState:CodeMirror.startState(scriptingMode)};},token:function(stream,state){return state.token(stream,state);},indent:function(state,textAfter){if(state.token==htmlDispatch)
return htmlMixedMode.indent(state.htmlState,textAfter);else if(scriptingMode.indent)
return scriptingMode.indent(state.scriptState,textAfter);},copyState:function(state){return{token:state.token,htmlState:CodeMirror.copyState(htmlMixedMode,state.htmlState),scriptState:CodeMirror.copyState(scriptingMode,state.scriptState)};},innerMode:function(state){if(state.token==scriptingDispatch)return{state:state.scriptState,mode:scriptingMode};else return{state:state.htmlState,mode:htmlMixedMode};}};},"htmlmixed");CodeMirror.defineMIME("application/x-ejs",{name:"htmlembedded",scriptingModeSpec:"javascript"});CodeMirror.defineMIME("application/x-aspx",{name:"htmlembedded",scriptingModeSpec:"text/x-csharp"});CodeMirror.defineMIME("application/x-jsp",{name:"htmlembedded",scriptingModeSpec:"text/x-java"});CodeMirror.defineMIME("application/x-erb",{name:"htmlembedded",scriptingModeSpec:"ruby"});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){var ie_lt8=/MSIE \d/.test(navigator.userAgent)&&(document.documentMode==null||document.documentMode<8);var Pos=CodeMirror.Pos;var matching={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function findMatchingBracket(cm,where,strict,config){var line=cm.getLineHandle(where.line),pos=where.ch-1;var match=(pos>=0&&matching[line.text.charAt(pos)])||matching[line.text.charAt(++pos)];if(!match)return null;var dir=match.charAt(1)==">"?1:-1;if(strict&&(dir>0)!=(pos==where.ch))return null;var style=cm.getTokenTypeAt(Pos(where.line,pos+1));var found=scanForBracket(cm,Pos(where.line,pos+(dir>0?1:0)),dir,style||null,config);if(found==null)return null;return{from:Pos(where.line,pos),to:found&&found.pos,match:found&&found.ch==match.charAt(0),forward:dir>0};}
function scanForBracket(cm,where,dir,style,config){var maxScanLen=(config&&config.maxScanLineLength)||10000;var maxScanLines=(config&&config.maxScanLines)||1000;var stack=[];var re=config&&config.bracketRegex?config.bracketRegex:/[(){}[\]]/;var lineEnd=dir>0?Math.min(where.line+maxScanLines,cm.lastLine()+1):Math.max(cm.firstLine()-1,where.line-maxScanLines);for(var lineNo=where.line;lineNo!=lineEnd;lineNo+=dir){var line=cm.getLine(lineNo);if(!line)continue;var pos=dir>0?0:line.length-1,end=dir>0?line.length:-1;if(line.length>maxScanLen)continue;if(lineNo==where.line)pos=where.ch-(dir<0?1:0);for(;pos!=end;pos+=dir){var ch=line.charAt(pos);if(re.test(ch)&&(style===undefined||cm.getTokenTypeAt(Pos(lineNo,pos+1))==style)){var match=matching[ch];if((match.charAt(1)==">")==(dir>0))stack.push(ch);else if(!stack.length)return{pos:Pos(lineNo,pos),ch:ch};else stack.pop();}}}
return lineNo-dir==(dir>0?cm.lastLine():cm.firstLine())?false:null;}
function matchBrackets(cm,autoclear,config){var maxHighlightLen=cm.state.matchBrackets.maxHighlightLineLength||1000;var marks=[],ranges=cm.listSelections();for(var i=0;i<ranges.length;i++){var match=ranges[i].empty()&&findMatchingBracket(cm,ranges[i].head,false,config);if(match&&cm.getLine(match.from.line).length<=maxHighlightLen){var style=match.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket";marks.push(cm.markText(match.from,Pos(match.from.line,match.from.ch+1),{className:style}));if(match.to&&cm.getLine(match.to.line).length<=maxHighlightLen)
marks.push(cm.markText(match.to,Pos(match.to.line,match.to.ch+1),{className:style}));}}
if(marks.length){if(ie_lt8&&cm.state.focused)cm.display.input.focus();var clear=function(){cm.operation(function(){for(var i=0;i<marks.length;i++)marks[i].clear();});};if(autoclear)setTimeout(clear,800);else return clear;}}
var currentlyHighlighted=null;function doMatchBrackets(cm){cm.operation(function(){if(currentlyHighlighted){currentlyHighlighted();currentlyHighlighted=null;}
currentlyHighlighted=matchBrackets(cm,false,cm.state.matchBrackets);});}
CodeMirror.defineOption("matchBrackets",false,function(cm,val,old){if(old&&old!=CodeMirror.Init)
cm.off("cursorActivity",doMatchBrackets);if(val){cm.state.matchBrackets=typeof val=="object"?val:{};cm.on("cursorActivity",doMatchBrackets);}});CodeMirror.defineExtension("matchBrackets",function(){matchBrackets(this,true);});CodeMirror.defineExtension("findMatchingBracket",function(pos,strict,config){return findMatchingBracket(this,pos,strict,config);});CodeMirror.defineExtension("scanForBracket",function(pos,dir,style,config){return scanForBracket(this,pos,dir,style,config);});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){var DEFAULT_BRACKETS="()[]{}''\"\"";var DEFAULT_EXPLODE_ON_ENTER="[]{}";var SPACE_CHAR_REGEX=/\s/;var Pos=CodeMirror.Pos;CodeMirror.defineOption("autoCloseBrackets",false,function(cm,val,old){if(old!=CodeMirror.Init&&old)
cm.removeKeyMap("autoCloseBrackets");if(!val)return;var pairs=DEFAULT_BRACKETS,explode=DEFAULT_EXPLODE_ON_ENTER;if(typeof val=="string")pairs=val;else if(typeof val=="object"){if(val.pairs!=null)pairs=val.pairs;if(val.explode!=null)explode=val.explode;}
var map=buildKeymap(pairs);if(explode)map.Enter=buildExplodeHandler(explode);cm.addKeyMap(map);});function charsAround(cm,pos){var str=cm.getRange(Pos(pos.line,pos.ch-1),Pos(pos.line,pos.ch+1));return str.length==2?str:null;}
function buildKeymap(pairs){var map={name:"autoCloseBrackets",Backspace:function(cm){if(cm.getOption("disableInput"))return CodeMirror.Pass;var ranges=cm.listSelections();for(var i=0;i<ranges.length;i++){if(!ranges[i].empty())return CodeMirror.Pass;var around=charsAround(cm,ranges[i].head);if(!around||pairs.indexOf(around)%2!=0)return CodeMirror.Pass;}
for(var i=ranges.length-1;i>=0;i--){var cur=ranges[i].head;cm.replaceRange("",Pos(cur.line,cur.ch-1),Pos(cur.line,cur.ch+1));}}};var closingBrackets="";for(var i=0;i<pairs.length;i+=2)(function(left,right){if(left!=right)closingBrackets+=right;map["'"+left+"'"]=function(cm){if(cm.getOption("disableInput"))return CodeMirror.Pass;var ranges=cm.listSelections(),type,next;for(var i=0;i<ranges.length;i++){var range=ranges[i],cur=range.head,curType;if(left=="'"&&cm.getTokenTypeAt(cur)=="comment")
return CodeMirror.Pass;var next=cm.getRange(cur,Pos(cur.line,cur.ch+1));if(!range.empty())
curType="surround";else if(left==right&&next==right){if(cm.getRange(cur,Pos(cur.line,cur.ch+3))==left+left+left)
curType="skipThree";else
curType="skip";}else if(left==right&&cur.ch>1&&cm.getRange(Pos(cur.line,cur.ch-2),cur)==left+left&&(cur.ch<=2||cm.getRange(Pos(cur.line,cur.ch-3),Pos(cur.line,cur.ch-2))!=left))
curType="addFour";else if(left==right&&CodeMirror.isWordChar(next))
return CodeMirror.Pass;else if(cm.getLine(cur.line).length==cur.ch||closingBrackets.indexOf(next)>=0||SPACE_CHAR_REGEX.test(next))
curType="both";else
return CodeMirror.Pass;if(!type)type=curType;else if(type!=curType)return CodeMirror.Pass;}
cm.operation(function(){if(type=="skip"){cm.execCommand("goCharRight");}else if(type=="skipThree"){for(var i=0;i<3;i++)
cm.execCommand("goCharRight");}else if(type=="surround"){var sels=cm.getSelections();for(var i=0;i<sels.length;i++)
sels[i]=left+sels[i]+right;cm.replaceSelections(sels,"around");}else if(type=="both"){cm.replaceSelection(left+right,null);cm.execCommand("goCharLeft");}else if(type=="addFour"){cm.replaceSelection(left+left+left+left,"before");cm.execCommand("goCharRight");}});};if(left!=right)map["'"+right+"'"]=function(cm){var ranges=cm.listSelections();for(var i=0;i<ranges.length;i++){var range=ranges[i];if(!range.empty()||cm.getRange(range.head,Pos(range.head.line,range.head.ch+1))!=right)
return CodeMirror.Pass;}
cm.execCommand("goCharRight");};})(pairs.charAt(i),pairs.charAt(i+1));return map;}
function buildExplodeHandler(pairs){return function(cm){if(cm.getOption("disableInput"))return CodeMirror.Pass;var ranges=cm.listSelections();for(var i=0;i<ranges.length;i++){if(!ranges[i].empty())return CodeMirror.Pass;var around=charsAround(cm,ranges[i].head);if(!around||pairs.indexOf(around)%2!=0)return CodeMirror.Pass;}
cm.operation(function(){cm.replaceSelection("\n\n",null);cm.execCommand("goCharLeft");ranges=cm.listSelections();for(var i=0;i<ranges.length;i++){var line=ranges[i].head.line;cm.indentLine(line,null,true);cm.indentLine(line+1,null,true);}});};}});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineOption("styleSelectedText",false,function(cm,val,old){var prev=old&&old!=CodeMirror.Init;if(val&&!prev){cm.state.markedSelection=[];cm.state.markedSelectionStyle=typeof val=="string"?val:"CodeMirror-selectedtext";reset(cm);cm.on("cursorActivity",onCursorActivity);cm.on("change",onChange);}else if(!val&&prev){cm.off("cursorActivity",onCursorActivity);cm.off("change",onChange);clear(cm);cm.state.markedSelection=cm.state.markedSelectionStyle=null;}});function onCursorActivity(cm){cm.operation(function(){update(cm);});}
function onChange(cm){if(cm.state.markedSelection.length)
cm.operation(function(){clear(cm);});}
var CHUNK_SIZE=8;var Pos=CodeMirror.Pos;var cmp=CodeMirror.cmpPos;function coverRange(cm,from,to,addAt){if(cmp(from,to)==0)return;var array=cm.state.markedSelection;var cls=cm.state.markedSelectionStyle;for(var line=from.line;;){var start=line==from.line?from:Pos(line,0);var endLine=line+CHUNK_SIZE,atEnd=endLine>=to.line;var end=atEnd?to:Pos(endLine,0);var mark=cm.markText(start,end,{className:cls});if(addAt==null)array.push(mark);else array.splice(addAt++,0,mark);if(atEnd)break;line=endLine;}}
function clear(cm){var array=cm.state.markedSelection;for(var i=0;i<array.length;++i)array[i].clear();array.length=0;}
function reset(cm){clear(cm);var ranges=cm.listSelections();for(var i=0;i<ranges.length;i++)
coverRange(cm,ranges[i].from(),ranges[i].to());}
function update(cm){if(!cm.somethingSelected())return clear(cm);if(cm.listSelections().length>1)return reset(cm);var from=cm.getCursor("start"),to=cm.getCursor("end");var array=cm.state.markedSelection;if(!array.length)return coverRange(cm,from,to);var coverStart=array[0].find(),coverEnd=array[array.length-1].find();if(!coverStart||!coverEnd||to.line-from.line<CHUNK_SIZE||cmp(from,coverEnd.to)>=0||cmp(to,coverStart.from)<=0)
return reset(cm);while(cmp(from,coverStart.from)>0){array.shift().clear();coverStart=array[0].find();}
if(cmp(from,coverStart.from)<0){if(coverStart.to.line-from.line<CHUNK_SIZE){array.shift().clear();coverRange(cm,from,coverStart.to,0);}else{coverRange(cm,from,coverStart.from,0);}}
while(cmp(to,coverEnd.to)<0){array.pop().clear();coverEnd=array[array.length-1].find();}
if(cmp(to,coverEnd.to)>0){if(to.line-coverEnd.from.line<CHUNK_SIZE){array.pop().clear();coverRange(cm,coverEnd.from,to);}else{coverRange(cm,coverEnd.to,to);}}}});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";var noOptions={};var nonWS=/[^\s\u00a0]/;var Pos=CodeMirror.Pos;function firstNonWS(str){var found=str.search(nonWS);return found==-1?0:found;}
CodeMirror.commands.toggleComment=function(cm){var minLine=Infinity,ranges=cm.listSelections(),mode=null;for(var i=ranges.length-1;i>=0;i--){var from=ranges[i].from(),to=ranges[i].to();if(from.line>=minLine)continue;if(to.line>=minLine)to=Pos(minLine,0);minLine=from.line;if(mode==null){if(cm.uncomment(from,to))mode="un";else{cm.lineComment(from,to);mode="line";}}else if(mode=="un"){cm.uncomment(from,to);}else{cm.lineComment(from,to);}}};CodeMirror.defineExtension("lineComment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=self.getModeAt(from);var commentString=options.lineComment||mode.lineComment;if(!commentString){if(options.blockCommentStart||mode.blockCommentStart){options.fullLines=true;self.blockComment(from,to,options);}
return;}
var firstLine=self.getLine(from.line);if(firstLine==null)return;var end=Math.min(to.ch!=0||to.line==from.line?to.line+1:to.line,self.lastLine()+1);var pad=options.padding==null?" ":options.padding;var blankLines=options.commentBlankLines||from.line==to.line;self.operation(function(){if(options.indent){var baseString=firstLine.slice(0,firstNonWS(firstLine));for(var i=from.line;i<end;++i){var line=self.getLine(i),cut=baseString.length;if(!blankLines&&!nonWS.test(line))continue;if(line.slice(0,cut)!=baseString)cut=firstNonWS(line);self.replaceRange(baseString+commentString+pad,Pos(i,0),Pos(i,cut));}}else{for(var i=from.line;i<end;++i){if(blankLines||nonWS.test(self.getLine(i)))
self.replaceRange(commentString+pad,Pos(i,0));}}});});CodeMirror.defineExtension("blockComment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=self.getModeAt(from);var startString=options.blockCommentStart||mode.blockCommentStart;var endString=options.blockCommentEnd||mode.blockCommentEnd;if(!startString||!endString){if((options.lineComment||mode.lineComment)&&options.fullLines!=false)
self.lineComment(from,to,options);return;}
var end=Math.min(to.line,self.lastLine());if(end!=from.line&&to.ch==0&&nonWS.test(self.getLine(end)))--end;var pad=options.padding==null?" ":options.padding;if(from.line>end)return;self.operation(function(){if(options.fullLines!=false){var lastLineHasText=nonWS.test(self.getLine(end));self.replaceRange(pad+endString,Pos(end));self.replaceRange(startString+pad,Pos(from.line,0));var lead=options.blockCommentLead||mode.blockCommentLead;if(lead!=null)for(var i=from.line+1;i<=end;++i)
if(i!=end||lastLineHasText)
self.replaceRange(lead+pad,Pos(i,0));}else{self.replaceRange(endString,to);self.replaceRange(startString,from);}});});CodeMirror.defineExtension("uncomment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=self.getModeAt(from);var end=Math.min(to.ch!=0||to.line==from.line?to.line:to.line-1,self.lastLine()),start=Math.min(from.line,end);var lineString=options.lineComment||mode.lineComment,lines=[];var pad=options.padding==null?" ":options.padding,didSomething;lineComment:{if(!lineString)break lineComment;for(var i=start;i<=end;++i){var line=self.getLine(i);var found=line.indexOf(lineString);if(found>-1&&!/comment/.test(self.getTokenTypeAt(Pos(i,found+1))))found=-1;if(found==-1&&(i!=end||i==start)&&nonWS.test(line))break lineComment;if(found>-1&&nonWS.test(line.slice(0,found)))break lineComment;lines.push(line);}
self.operation(function(){for(var i=start;i<=end;++i){var line=lines[i-start];var pos=line.indexOf(lineString),endPos=pos+lineString.length;if(pos<0)continue;if(line.slice(endPos,endPos+pad.length)==pad)endPos+=pad.length;didSomething=true;self.replaceRange("",Pos(i,pos),Pos(i,endPos));}});if(didSomething)return true;}
var startString=options.blockCommentStart||mode.blockCommentStart;var endString=options.blockCommentEnd||mode.blockCommentEnd;if(!startString||!endString)return false;var lead=options.blockCommentLead||mode.blockCommentLead;var startLine=self.getLine(start),endLine=end==start?startLine:self.getLine(end);var open=startLine.indexOf(startString),close=endLine.lastIndexOf(endString);if(close==-1&&start!=end){endLine=self.getLine(--end);close=endLine.lastIndexOf(endString);}
if(open==-1||close==-1||!/comment/.test(self.getTokenTypeAt(Pos(start,open+1)))||!/comment/.test(self.getTokenTypeAt(Pos(end,close+1))))
return false;var lastStart=startLine.lastIndexOf(startString,from.ch);var firstEnd=lastStart==-1?-1:startLine.slice(0,from.ch).indexOf(endString,lastStart+startString.length);if(lastStart!=-1&&firstEnd!=-1&&firstEnd+endString.length!=from.ch)return false;firstEnd=endLine.indexOf(endString,to.ch);var almostLastStart=endLine.slice(to.ch).lastIndexOf(startString,firstEnd-to.ch);lastStart=(firstEnd==-1||almostLastStart==-1)?-1:to.ch+almostLastStart;if(firstEnd!=-1&&lastStart!=-1&&lastStart!=to.ch)return false;self.operation(function(){self.replaceRange("",Pos(end,close-(pad&&endLine.slice(close-pad.length,close)==pad?pad.length:0)),Pos(end,close+endString.length));var openEnd=open+startString.length;if(pad&&startLine.slice(openEnd,openEnd+pad.length)==pad)openEnd+=pad.length;self.replaceRange("",Pos(start,open),Pos(start,openEnd));if(lead)for(var i=start+1;i<=end;++i){var line=self.getLine(i),found=line.indexOf(lead);if(found==-1||nonWS.test(line.slice(0,found)))continue;var foundEnd=found+lead.length;if(pad&&line.slice(foundEnd,foundEnd+pad.length)==pad)foundEnd+=pad.length;self.replaceRange("",Pos(i,found),Pos(i,foundEnd));}});return true;});});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.overlayMode=function(base,overlay,combine){return{startState:function(){return{base:CodeMirror.startState(base),overlay:CodeMirror.startState(overlay),basePos:0,baseCur:null,overlayPos:0,overlayCur:null,lineSeen:null};},copyState:function(state){return{base:CodeMirror.copyState(base,state.base),overlay:CodeMirror.copyState(overlay,state.overlay),basePos:state.basePos,baseCur:null,overlayPos:state.overlayPos,overlayCur:null};},token:function(stream,state){if(stream.sol()||stream.string!=state.lineSeen||Math.min(state.basePos,state.overlayPos)<stream.start){state.lineSeen=stream.string;state.basePos=state.overlayPos=stream.start;}
if(stream.start==state.basePos){state.baseCur=base.token(stream,state.base);state.basePos=stream.pos;}
if(stream.start==state.overlayPos){stream.pos=stream.start;state.overlayCur=overlay.token(stream,state.overlay);state.overlayPos=stream.pos;}
stream.pos=Math.min(state.basePos,state.overlayPos);if(state.overlayCur==null)return state.baseCur;else if(state.baseCur!=null&&state.overlay.combineTokens||combine&&state.overlay.combineTokens==null)
return state.baseCur+" "+state.overlayCur;else return state.overlayCur;},indent:base.indent&&function(state,textAfter){return base.indent(state.base,textAfter);},electricChars:base.electricChars,innerMode:function(state){return{state:state.base,mode:base};},blankLine:function(state){if(base.blankLine)base.blankLine(state.base);if(overlay.blankLine)overlay.blankLine(state.overlay);}};};});;(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod);else
mod(CodeMirror);})(function(CodeMirror){"use strict";var WRAP_CLASS="CodeMirror-activeline";var BACK_CLASS="CodeMirror-activeline-background";CodeMirror.defineOption("styleActiveLine",false,function(cm,val,old){var prev=old&&old!=CodeMirror.Init;if(val&&!prev){cm.state.activeLines=[];updateActiveLines(cm,cm.listSelections());cm.on("beforeSelectionChange",selectionChange);}else if(!val&&prev){cm.off("beforeSelectionChange",selectionChange);clearActiveLines(cm);delete cm.state.activeLines;}});function clearActiveLines(cm){for(var i=0;i<cm.state.activeLines.length;i++){cm.removeLineClass(cm.state.activeLines[i],"wrap",WRAP_CLASS);cm.removeLineClass(cm.state.activeLines[i],"background",BACK_CLASS);}}
function sameArray(a,b){if(a.length!=b.length)return false;for(var i=0;i<a.length;i++)
if(a[i]!=b[i])return false;return true;}
function updateActiveLines(cm,ranges){var active=[];for(var i=0;i<ranges.length;i++){var range=ranges[i];if(!range.empty())continue;var line=cm.getLineHandleVisualStart(range.head.line);if(active[active.length-1]!=line)active.push(line);}
if(sameArray(cm.state.activeLines,active))return;cm.operation(function(){clearActiveLines(cm);for(var i=0;i<active.length;i++){cm.addLineClass(active[i],"wrap",WRAP_CLASS);cm.addLineClass(active[i],"background",BACK_CLASS);}
cm.state.activeLines=active;});}
function selectionChange(cm,sel){updateActiveLines(cm,sel.ranges);}});;WebInspector.CodeMirrorUtils=function()
{WebInspector.InplaceEditor.call(this);}
WebInspector.CodeMirrorUtils.toPos=function(range)
{return{start:new CodeMirror.Pos(range.startLine,range.startColumn),end:new CodeMirror.Pos(range.endLine,range.endColumn)};}
WebInspector.CodeMirrorUtils.toRange=function(start,end)
{return new WebInspector.TextRange(start.line,start.ch,end.line,end.ch);}
WebInspector.CodeMirrorUtils.changeObjectToEditOperation=function(changeObject)
{var oldRange=WebInspector.CodeMirrorUtils.toRange(changeObject.from,changeObject.to);var newRange=oldRange.clone();var linesAdded=changeObject.text.length;if(linesAdded===0){newRange.endLine=newRange.startLine;newRange.endColumn=newRange.startColumn;}else if(linesAdded===1){newRange.endLine=newRange.startLine;newRange.endColumn=newRange.startColumn+changeObject.text[0].length;}else{newRange.endLine=newRange.startLine+linesAdded-1;newRange.endColumn=changeObject.text[linesAdded-1].length;}
return{oldRange:oldRange,newRange:newRange};}
WebInspector.CodeMirrorUtils.pullLines=function(codeMirror,linesCount)
{var lines=[];codeMirror.eachLine(0,linesCount,onLineHandle);return lines;function onLineHandle(lineHandle)
{lines.push(lineHandle.text);}}
WebInspector.CodeMirrorUtils.prototype={editorContent:function(editingContext){return editingContext.codeMirror.getValue();},_consumeCopy:function(e)
{e.consume();},setUpEditor:function(editingContext)
{var element=editingContext.element;var config=editingContext.config;editingContext.cssLoadView=new WebInspector.CodeMirrorCSSLoadView();editingContext.cssLoadView.show(element);WebInspector.setCurrentFocusElement(element);element.addEventListener("copy",this._consumeCopy,false);var codeMirror=new window.CodeMirror(element,{mode:config.mode,lineWrapping:config.lineWrapping,smartIndent:config.smartIndent,autofocus:true,theme:config.theme,value:config.initialValue});codeMirror.getWrapperElement().classList.add("source-code");codeMirror.on("cursorActivity",function(cm){cm.display.cursorDiv.scrollIntoViewIfNeeded(false);});editingContext.codeMirror=codeMirror;},closeEditor:function(editingContext)
{editingContext.element.removeEventListener("copy",this._consumeCopy,false);editingContext.cssLoadView.detach();},cancelEditing:function(editingContext)
{editingContext.codeMirror.setValue(editingContext.oldText);},augmentEditingHandle:function(editingContext,handle)
{function setWidth(editingContext,width)
{var padding=30;var codeMirror=editingContext.codeMirror;codeMirror.getWrapperElement().style.width=(width-codeMirror.getWrapperElement().offsetLeft-padding)+"px";codeMirror.refresh();}
handle.codeMirror=editingContext.codeMirror;handle.setWidth=setWidth.bind(null,editingContext);},__proto__:WebInspector.InplaceEditor.prototype}
WebInspector.CodeMirrorUtils.TokenizerFactory=function(){}
WebInspector.CodeMirrorUtils.TokenizerFactory.prototype={createTokenizer:function(mimeType)
{var mode=CodeMirror.getMode({indentUnit:2},mimeType);var state=CodeMirror.startState(mode);function tokenize(line,callback)
{var stream=new CodeMirror.StringStream(line);while(!stream.eol()){var style=mode.token(stream,state);var value=stream.current();callback(value,style,stream.start,stream.start+value.length);stream.start=stream.pos;}}
return tokenize;}}
WebInspector.CodeMirrorCSSLoadView=function()
{WebInspector.VBox.call(this);this.element.classList.add("hidden");this.registerRequiredCSS("cm/codemirror.css");this.registerRequiredCSS("source_frame/cmdevtools.css");WebInspector.CodeMirrorUtils.appendThemeStyle(this.element);}
WebInspector.CodeMirrorCSSLoadView.prototype={__proto__:WebInspector.VBox.prototype}
WebInspector.CodeMirrorUtils.appendThemeStyle=function(element)
{if(WebInspector.themeSupport.hasTheme())
return;var backgroundColor=InspectorFrontendHost.getSelectionBackgroundColor();var backgroundColorRule=backgroundColor?".CodeMirror .CodeMirror-selected { background-color: "+backgroundColor+";}":"";var foregroundColor=InspectorFrontendHost.getSelectionForegroundColor();var foregroundColorRule=foregroundColor?".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: "+foregroundColor+"!important;}":"";var style=createElement("style");if(foregroundColorRule||backgroundColorRule)
style.textContent=backgroundColorRule+foregroundColorRule;element.appendChild(style);};WebInspector.CodeMirrorDictionary=function(codeMirror,additionalWordChars)
{this._codeMirror=codeMirror;this._additionalWordChars=new Set((additionalWordChars));this._dictionary=new WebInspector.TextDictionary();this._addText(this._codeMirror.getValue());this._changes=this._changes.bind(this);this._beforeChange=this._beforeChange.bind(this);this._codeMirror.on("beforeChange",this._beforeChange);this._codeMirror.on("changes",this._changes);}
WebInspector.CodeMirrorDictionary.prototype={_beforeChange:function(codeMirror,changeObject)
{this._updatedLines=this._updatedLines||{};for(var i=changeObject.from.line;i<=changeObject.to.line;++i)
this._updatedLines[i]=this._codeMirror.getLine(i);},_changes:function(codeMirror,changes)
{if(!changes.length||!this._updatedLines)
return;for(var lineNumber in this._updatedLines)
this._removeText(this._updatedLines[lineNumber]);delete this._updatedLines;var linesToUpdate={};for(var changeIndex=0;changeIndex<changes.length;++changeIndex){var changeObject=changes[changeIndex];var editInfo=WebInspector.CodeMirrorUtils.changeObjectToEditOperation(changeObject);for(var i=editInfo.newRange.startLine;i<=editInfo.newRange.endLine;++i)
linesToUpdate[i]=this._codeMirror.getLine(i);}
for(var lineNumber in linesToUpdate)
this._addText(linesToUpdate[lineNumber]);},_validWord:function(word)
{return!!word.length&&(word[0]<"0"||word[0]>"9");},_addText:function(text)
{WebInspector.TextUtils.textToWords(text,this.isWordChar.bind(this),addWord.bind(this));function addWord(word)
{if(this._validWord(word))
this._dictionary.addWord(word);}},_removeText:function(text)
{WebInspector.TextUtils.textToWords(text,this.isWordChar.bind(this),removeWord.bind(this));function removeWord(word)
{if(this._validWord(word))
this._dictionary.removeWord(word);}},isWordChar:function(char)
{return WebInspector.TextUtils.isWordChar(char)||this._additionalWordChars.has(char);},wordsWithPrefix:function(prefix)
{return this._dictionary.wordsWithPrefix(prefix);},hasWord:function(word)
{return this._dictionary.hasWord(word);},wordCount:function(word)
{return this._dictionary.wordCount(word);},dispose:function()
{this._codeMirror.off("beforeChange",this._beforeChange);this._codeMirror.off("changes",this._changes);this._dictionary.reset();},};WebInspector.TextEditorAutocompleteController=function(textEditor,codeMirror)
{this._textEditor=textEditor;this._codeMirror=codeMirror;this._onScroll=this._onScroll.bind(this);this._onCursorActivity=this._onCursorActivity.bind(this);this._changes=this._changes.bind(this);this._blur=this._blur.bind(this);this._codeMirror.on("changes",this._changes);this._enabled=true;this._initialized=false;}
WebInspector.TextEditorAutocompleteController.prototype={_initializeIfNeeded:function()
{if(this._initialized)
return;this._initialized=true;this._codeMirror.on("scroll",this._onScroll);this._codeMirror.on("cursorActivity",this._onCursorActivity);this._codeMirror.on("blur",this._blur);this._delegate.initialize(this._textEditor);},setDelegate:function(delegate)
{if(this._delegate)
this._delegate.dispose();this._delegate=delegate;},setEnabled:function(enabled)
{if(enabled===this._enabled)
return;this._enabled=enabled;if(!this._delegate)
return;if(!enabled)
this._delegate.dispose();else
this._delegate.initialize();},_changes:function(codeMirror,changes)
{if(!changes.length||!this._enabled||!this._delegate)
return;var singleCharInput=false;for(var changeIndex=0;changeIndex<changes.length;++changeIndex){var changeObject=changes[changeIndex];singleCharInput=(changeObject.origin==="+input"&&changeObject.text.length===1&&changeObject.text[0].length===1)||(this._suggestBox&&changeObject.origin==="+delete"&&changeObject.removed.length===1&&changeObject.removed[0].length===1);}
if(singleCharInput)
setImmediate(this.autocomplete.bind(this));},_blur:function()
{this.finishAutocomplete();},_validateSelectionsContexts:function(mainSelection)
{var selections=this._codeMirror.listSelections();if(selections.length<=1)
return true;var mainSelectionContext=this._textEditor.copyRange(mainSelection);for(var i=0;i<selections.length;++i){var wordRange=this._delegate.substituteRange(this._textEditor,selections[i].head.line,selections[i].head.ch);if(!wordRange)
return false;var context=this._textEditor.copyRange(wordRange);if(context!==mainSelectionContext)
return false;}
return true;},autocomplete:function()
{if(!this._enabled||!this._delegate)
return;this._initializeIfNeeded();if(this._codeMirror.somethingSelected()){this.finishAutocomplete();return;}
var cursor=this._codeMirror.getCursor("head");var substituteRange=this._delegate.substituteRange(this._textEditor,cursor.line,cursor.ch);if(!substituteRange||!this._validateSelectionsContexts(substituteRange)){this.finishAutocomplete();return;}
var prefixRange=substituteRange.clone();prefixRange.endColumn=cursor.ch;var wordsWithPrefix=this._delegate.wordsWithPrefix(this._textEditor,prefixRange,substituteRange);if(!wordsWithPrefix.length){this.finishAutocomplete();return;}
if(!this._suggestBox)
this._suggestBox=new WebInspector.SuggestBox(this,6);var oldPrefixRange=this._prefixRange;this._prefixRange=prefixRange;if(!oldPrefixRange||prefixRange.startLine!==oldPrefixRange.startLine||prefixRange.startColumn!==oldPrefixRange.startColumn)
this._updateAnchorBox();this._suggestBox.updateSuggestions(this._anchorBox,wordsWithPrefix.map(item=>({title:item})),0,true,this._textEditor.copyRange(prefixRange));if(!this._suggestBox.visible())
this.finishAutocomplete();this._onSuggestionsShownForTest(wordsWithPrefix);},_onSuggestionsShownForTest:function(suggestions){},finishAutocomplete:function()
{if(!this._suggestBox)
return;this._suggestBox.hide();this._suggestBox=null;this._prefixRange=null;this._anchorBox=null;},keyDown:function(e)
{if(!this._suggestBox)
return false;if(e.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code){this.finishAutocomplete();return true;}
if(e.keyCode===WebInspector.KeyboardShortcut.Keys.Tab.code){this._suggestBox.acceptSuggestion();this.finishAutocomplete();return true;}
return this._suggestBox.keyPressed(e);},applySuggestion:function(suggestion,isIntermediateSuggestion)
{this._currentSuggestion=suggestion;},acceptSuggestion:function()
{if(this._prefixRange.endColumn-this._prefixRange.startColumn===this._currentSuggestion.length)
return;var selections=this._codeMirror.listSelections().slice();var prefixLength=this._prefixRange.endColumn-this._prefixRange.startColumn;for(var i=selections.length-1;i>=0;--i){var start=selections[i].head;var end=new CodeMirror.Pos(start.line,start.ch-prefixLength);this._codeMirror.replaceRange(this._currentSuggestion,start,end,"+autocomplete");}},_onScroll:function()
{if(!this._suggestBox)
return;var cursor=this._codeMirror.getCursor();var scrollInfo=this._codeMirror.getScrollInfo();var topmostLineNumber=this._codeMirror.lineAtHeight(scrollInfo.top,"local");var bottomLine=this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");if(cursor.line<topmostLineNumber||cursor.line>bottomLine)
this.finishAutocomplete();else{this._updateAnchorBox();this._suggestBox.setPosition(this._anchorBox);}},_onCursorActivity:function()
{if(!this._suggestBox)
return;var cursor=this._codeMirror.getCursor();if(cursor.line!==this._prefixRange.startLine||cursor.ch>this._prefixRange.endColumn||cursor.ch<=this._prefixRange.startColumn)
this.finishAutocomplete();},_updateAnchorBox:function()
{var line=this._prefixRange.startLine;var column=this._prefixRange.startColumn;var metrics=this._textEditor.cursorPositionToCoordinates(line,column);this._anchorBox=metrics?new AnchorBox(metrics.x,metrics.y,0,metrics.height):null;},}
WebInspector.TextEditorAutocompleteDelegate=function(){}
WebInspector.TextEditorAutocompleteDelegate.prototype={substituteRange:function(editor,lineNumber,columnNumber){},wordsWithPrefix:function(editor,prefixRange,substituteRange){},initialize:function(editor){},dispose:function(){}}
WebInspector.SimpleAutocompleteDelegate=function(additionalWordChars)
{this._additionalWordChars=additionalWordChars;}
WebInspector.SimpleAutocompleteDelegate.prototype={initialize:function(editor)
{if(this._dictionary)
this._dictionary.dispose();this._dictionary=editor.createTextDictionary(this._additionalWordChars);},dispose:function()
{if(this._dictionary){this._dictionary.dispose();delete this._dictionary;}},substituteRange:function(editor,lineNumber,columnNumber)
{return editor.wordRangeForCursorPosition(lineNumber,columnNumber,this._dictionary.isWordChar.bind(this._dictionary));},wordsWithPrefix:function(editor,prefixRange,substituteRange)
{if(prefixRange.startColumn===prefixRange.endColumn)
return[];var dictionary=this._dictionary;var completions=dictionary.wordsWithPrefix(editor.copyRange(prefixRange));var substituteWord=editor.copyRange(substituteRange);if(dictionary.wordCount(substituteWord)===1)
completions=completions.filter(excludeFilter.bind(null,substituteWord));completions.sort(sortSuggestions);return completions;function sortSuggestions(a,b)
{return dictionary.wordCount(b)-dictionary.wordCount(a)||a.length-b.length;}
function excludeFilter(excludeWord,word)
{return word!==excludeWord;}}};WebInspector.CodeMirrorTextEditor=function(url,delegate)
{WebInspector.VBox.call(this);this._delegate=delegate;this._url=url;this._gutters=["CodeMirror-linenumbers"];this.registerRequiredCSS("cm/codemirror.css");this.registerRequiredCSS("source_frame/cmdevtools.css");WebInspector.CodeMirrorUtils.appendThemeStyle(this.element);this._codeMirror=new window.CodeMirror(this.element,{lineNumbers:true,gutters:["CodeMirror-linenumbers"],matchBrackets:true,smartIndent:false,styleSelectedText:true,electricChars:false,styleActiveLine:true});this._codeMirrorElement=this.element.lastElementChild;this._codeMirror._codeMirrorTextEditor=this;CodeMirror.keyMap["devtools-common"]={"Left":"goCharLeft","Right":"goCharRight","Up":"goLineUp","Down":"goLineDown","End":"goLineEnd","Home":"goLineStartSmart","PageUp":"goPageUp","PageDown":"goPageDown","Delete":"delCharAfter","Backspace":"delCharBefore","Tab":"defaultTab","Shift-Tab":"indentLess","Enter":"smartNewlineAndIndent","Ctrl-Space":"autocomplete","Esc":"dismissMultipleSelections","Ctrl-M":"gotoMatchingBracket"};CodeMirror.keyMap["devtools-pc"]={"Ctrl-A":"selectAll","Ctrl-Z":"undoAndReveal","Shift-Ctrl-Z":"redoAndReveal","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"moveCamelLeft","Alt-Right":"moveCamelRight","Shift-Alt-Left":"selectCamelLeft","Shift-Alt-Right":"selectCamelRight","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-/":"toggleComment","Ctrl-D":"selectNextOccurrence","Ctrl-U":"undoLastSelection",fallthrough:"devtools-common"};CodeMirror.keyMap["devtools-mac"]={"Cmd-A":"selectAll","Cmd-Z":"undoAndReveal","Shift-Cmd-Z":"redoAndReveal","Cmd-Up":"goDocStart","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Ctrl-Left":"moveCamelLeft","Ctrl-Right":"moveCamelRight","Shift-Ctrl-Left":"selectCamelLeft","Shift-Ctrl-Right":"selectCamelRight","Cmd-Left":"goLineStartSmart","Cmd-Right":"goLineEnd","Cmd-Backspace":"delLineLeft","Alt-Backspace":"delGroupBefore","Alt-Delete":"delGroupAfter","Cmd-/":"toggleComment","Cmd-D":"selectNextOccurrence","Cmd-U":"undoLastSelection",fallthrough:"devtools-common"};WebInspector.moduleSetting("textEditorIndent").addChangeListener(this._onUpdateEditorIndentation,this);WebInspector.moduleSetting("textEditorAutoDetectIndent").addChangeListener(this._onUpdateEditorIndentation,this);this._onUpdateEditorIndentation();WebInspector.moduleSetting("showWhitespacesInEditor").addChangeListener(this._updateCodeMirrorMode,this);WebInspector.moduleSetting("textEditorBracketMatching").addChangeListener(this._enableBracketMatchingIfNeeded,this);this._enableBracketMatchingIfNeeded();this._codeMirror.setOption("keyMap",WebInspector.isMac()?"devtools-mac":"devtools-pc");this._codeMirror.addKeyMap({"'":"maybeAvoidSmartSingleQuotes","'\"'":"maybeAvoidSmartDoubleQuotes"});this._codeMirror.setOption("flattenSpans",false);this._codeMirror.setOption("maxHighlightLength",WebInspector.CodeMirrorTextEditor.maxHighlightLength);this._codeMirror.setOption("mode",null);this._codeMirror.setOption("crudeMeasuringFrom",1000);this._shouldClearHistory=true;this._lineSeparator="\n";this._autocompleteController=new WebInspector.TextEditorAutocompleteController(this,this._codeMirror);this._tokenHighlighter=new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this,this._codeMirror);this._blockIndentController=new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);this._fixWordMovement=new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);this._selectNextOccurrenceController=new WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController(this,this._codeMirror);WebInspector.moduleSetting("textEditorAutocompletion").addChangeListener(this._enableAutocompletionIfNeeded,this);this._enableAutocompletionIfNeeded();this._codeMirror.on("changes",this._changes.bind(this));this._codeMirror.on("gutterClick",this._gutterClick.bind(this));this._codeMirror.on("cursorActivity",this._cursorActivity.bind(this));this._codeMirror.on("beforeSelectionChange",this._beforeSelectionChange.bind(this));this._codeMirror.on("scroll",this._scroll.bind(this));this._codeMirror.on("focus",this._focus.bind(this));this._codeMirror.on("keyHandled",this._onKeyHandled.bind(this));this.element.addEventListener("contextmenu",this._contextMenu.bind(this),false);function updateAnticipateJumpFlag(value)
{this._isHandlingMouseDownEvent=value;}
this.element.addEventListener("mousedown",updateAnticipateJumpFlag.bind(this,true),true);this.element.addEventListener("mousedown",updateAnticipateJumpFlag.bind(this,false),false);this.element.style.overflow="hidden";this._codeMirrorElement.classList.add("source-code");this._codeMirrorElement.classList.add("fill");this._elementToWidget=new Map();this._nestedUpdatesCounter=0;this.element.addEventListener("focus",this._handleElementFocus.bind(this),false);this.element.addEventListener("keydown",this._handleKeyDown.bind(this),true);this.element.addEventListener("keydown",this._handlePostKeyDown.bind(this),false);this.element.tabIndex=0;this._setupWhitespaceHighlight();}
WebInspector.CodeMirrorTextEditor.maxHighlightLength=1000;WebInspector.CodeMirrorTextEditor.autocompleteCommand=function(codeMirror)
{codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();}
CodeMirror.commands.autocomplete=WebInspector.CodeMirrorTextEditor.autocompleteCommand;WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand=function(codeMirror)
{codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.undoLastSelection();}
CodeMirror.commands.undoLastSelection=WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand;WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand=function(codeMirror)
{codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.selectNextOccurrence();}
CodeMirror.commands.selectNextOccurrence=WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand;WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand=function(shift,codeMirror)
{codeMirror._codeMirrorTextEditor._doCamelCaseMovement(-1,shift);}
CodeMirror.commands.moveCamelLeft=WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null,false);CodeMirror.commands.selectCamelLeft=WebInspector.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null,true);WebInspector.CodeMirrorTextEditor.moveCamelRightCommand=function(shift,codeMirror)
{codeMirror._codeMirrorTextEditor._doCamelCaseMovement(1,shift);}
CodeMirror.commands.moveCamelRight=WebInspector.CodeMirrorTextEditor.moveCamelRightCommand.bind(null,false);CodeMirror.commands.selectCamelRight=WebInspector.CodeMirrorTextEditor.moveCamelRightCommand.bind(null,true);CodeMirror.commands.smartNewlineAndIndent=function(codeMirror)
{codeMirror.operation(innerSmartNewlineAndIndent.bind(null,codeMirror));function innerSmartNewlineAndIndent(codeMirror)
{var selections=codeMirror.listSelections();var replacements=[];for(var i=0;i<selections.length;++i){var selection=selections[i];var cur=CodeMirror.cmpPos(selection.head,selection.anchor)<0?selection.head:selection.anchor;var line=codeMirror.getLine(cur.line);var indent=WebInspector.TextUtils.lineIndent(line);replacements.push("\n"+indent.substring(0,Math.min(cur.ch,indent.length)));}
codeMirror.replaceSelections(replacements);codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();}}
CodeMirror.commands.gotoMatchingBracket=function(codeMirror)
{var updatedSelections=[];var selections=codeMirror.listSelections();for(var i=0;i<selections.length;++i){var selection=selections[i];var cursor=selection.head;var matchingBracket=codeMirror.findMatchingBracket(cursor,false,{maxScanLines:10000});var updatedHead=cursor;if(matchingBracket&&matchingBracket.match){var columnCorrection=CodeMirror.cmpPos(matchingBracket.from,cursor)===0?1:0;updatedHead=new CodeMirror.Pos(matchingBracket.to.line,matchingBracket.to.ch+columnCorrection);}
updatedSelections.push({anchor:updatedHead,head:updatedHead});}
codeMirror.setSelections(updatedSelections);}
CodeMirror.commands.undoAndReveal=function(codemirror)
{var scrollInfo=codemirror.getScrollInfo();codemirror.execCommand("undo");var cursor=codemirror.getCursor("start");codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line,scrollInfo);codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();}
CodeMirror.commands.redoAndReveal=function(codemirror)
{var scrollInfo=codemirror.getScrollInfo();codemirror.execCommand("redo");var cursor=codemirror.getCursor("start");codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line,scrollInfo);codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();}
CodeMirror.commands.dismissMultipleSelections=function(codemirror)
{var selections=codemirror.listSelections();var selection=selections[0];if(selections.length===1){if(codemirror._codeMirrorTextEditor._isSearchActive())
return CodeMirror.Pass;if(WebInspector.CodeMirrorUtils.toRange(selection.anchor,selection.head).isEmpty())
return CodeMirror.Pass;codemirror.setSelection(selection.anchor,selection.anchor,{scroll:false});codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);return;}
codemirror.setSelection(selection.anchor,selection.head,{scroll:false});codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);}
WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes=function(quoteCharacter,codeMirror)
{var textEditor=codeMirror._codeMirrorTextEditor;if(!WebInspector.moduleSetting("textEditorBracketMatching").get())
return CodeMirror.Pass;var selections=textEditor.selections();if(selections.length!==1||!selections[0].isEmpty())
return CodeMirror.Pass;var selection=selections[0];var token=textEditor.tokenAtTextPosition(selection.startLine,selection.startColumn);if(!token||!token.type||token.type.indexOf("string")===-1)
return CodeMirror.Pass;var line=textEditor.line(selection.startLine);var tokenValue=line.substring(token.startColumn,token.endColumn);if(tokenValue[0]===tokenValue[tokenValue.length-1]&&(tokenValue[0]==="'"||tokenValue[0]==="\""))
return CodeMirror.Pass;codeMirror.replaceSelection(quoteCharacter);}
CodeMirror.commands.maybeAvoidSmartSingleQuotes=WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes.bind(null,"'");CodeMirror.commands.maybeAvoidSmartDoubleQuotes=WebInspector.CodeMirrorTextEditor._maybeAvoidSmartQuotes.bind(null,"\"");WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold=2000;WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan=16;WebInspector.CodeMirrorTextEditor.MaxEditableTextSize=1024*1024*10;WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing=1000;WebInspector.CodeMirrorTextEditor._guessIndentationLevel=function(lines)
{var tabRegex=/^\t+/;var tabLines=0;var indents={};for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var text=lines[lineNumber];if(text.length===0||!WebInspector.TextUtils.isSpaceChar(text[0]))
continue;if(tabRegex.test(text)){++tabLines;continue;}
var i=0;while(i<text.length&&WebInspector.TextUtils.isSpaceChar(text[i]))
++i;if(i%2!==0)
continue;indents[i]=1+(indents[i]||0);}
var linesCountPerIndentThreshold=3*lines.length/100;if(tabLines&&tabLines>linesCountPerIndentThreshold)
return"\t";var minimumIndent=Infinity;for(var i in indents){if(indents[i]<linesCountPerIndentThreshold)
continue;var indent=parseInt(i,10);if(minimumIndent>indent)
minimumIndent=indent;}
if(minimumIndent===Infinity)
return WebInspector.moduleSetting("textEditorIndent").get();return" ".repeat(minimumIndent);}
WebInspector.CodeMirrorTextEditor.prototype={createTextDictionary:function(additionalWordChars)
{return new WebInspector.CodeMirrorDictionary(this._codeMirror,additionalWordChars);},_enableAutocompletionIfNeeded:function()
{this._autocompleteController.setEnabled(WebInspector.moduleSetting("textEditorAutocompletion").get());},_onKeyHandled:function()
{WebInspector.shortcutRegistry.dismissPendingShortcutAction();},_onAutoAppendedSpaces:function()
{this._autoAppendedSpaces=this._autoAppendedSpaces||[];for(var i=0;i<this._autoAppendedSpaces.length;++i){var position=this._autoAppendedSpaces[i].resolve();if(!position)
continue;var line=this.line(position.lineNumber);if(line.length===position.columnNumber&&WebInspector.TextUtils.lineIndent(line).length===line.length)
this._codeMirror.replaceRange("",new CodeMirror.Pos(position.lineNumber,0),new CodeMirror.Pos(position.lineNumber,position.columnNumber));}
this._autoAppendedSpaces=[];var selections=this.selections();for(var i=0;i<selections.length;++i){var selection=selections[i];this._autoAppendedSpaces.push(this.textEditorPositionHandle(selection.startLine,selection.startColumn));}},_normalizePositionForOverlappingColumn:function(lineNumber,lineLength,charNumber)
{var linesCount=this._codeMirror.lineCount();var columnNumber=charNumber;if(charNumber<0&&lineNumber>0){--lineNumber;columnNumber=this.line(lineNumber).length;}else if(charNumber>=lineLength&&lineNumber<linesCount-1){++lineNumber;columnNumber=0;}else{columnNumber=Number.constrain(charNumber,0,lineLength);}
return{lineNumber:lineNumber,columnNumber:columnNumber};},_camelCaseMoveFromPosition:function(lineNumber,columnNumber,direction)
{function valid(charNumber,length)
{return charNumber>=0&&charNumber<length;}
function isWordStart(text,charNumber)
{var position=charNumber;var nextPosition=charNumber+1;return valid(position,text.length)&&valid(nextPosition,text.length)&&WebInspector.TextUtils.isWordChar(text[position])&&WebInspector.TextUtils.isWordChar(text[nextPosition])&&WebInspector.TextUtils.isUpperCase(text[position])&&WebInspector.TextUtils.isLowerCase(text[nextPosition]);}
function isWordEnd(text,charNumber)
{var position=charNumber;var prevPosition=charNumber-1;return valid(position,text.length)&&valid(prevPosition,text.length)&&WebInspector.TextUtils.isWordChar(text[position])&&WebInspector.TextUtils.isWordChar(text[prevPosition])&&WebInspector.TextUtils.isUpperCase(text[position])&&WebInspector.TextUtils.isLowerCase(text[prevPosition]);}
function constrainPosition(lineNumber,lineLength,columnNumber)
{return{lineNumber:lineNumber,columnNumber:Number.constrain(columnNumber,0,lineLength)};}
var text=this.line(lineNumber);var length=text.length;if((columnNumber===length&&direction===1)||(columnNumber===0&&direction===-1))
return this._normalizePositionForOverlappingColumn(lineNumber,length,columnNumber+direction);var charNumber=direction===1?columnNumber:columnNumber-1;while(valid(charNumber,length)&&WebInspector.TextUtils.isSpaceChar(text[charNumber]))
charNumber+=direction;if(!valid(charNumber,length))
return constrainPosition(lineNumber,length,charNumber);if(WebInspector.TextUtils.isStopChar(text[charNumber])){while(valid(charNumber,length)&&WebInspector.TextUtils.isStopChar(text[charNumber]))
charNumber+=direction;if(!valid(charNumber,length))
return constrainPosition(lineNumber,length,charNumber);return{lineNumber:lineNumber,columnNumber:direction===-1?charNumber+1:charNumber};}
charNumber+=direction;while(valid(charNumber,length)&&!isWordStart(text,charNumber)&&!isWordEnd(text,charNumber)&&WebInspector.TextUtils.isWordChar(text[charNumber]))
charNumber+=direction;if(!valid(charNumber,length))
return constrainPosition(lineNumber,length,charNumber);if(isWordStart(text,charNumber)||isWordEnd(text,charNumber)){return{lineNumber:lineNumber,columnNumber:charNumber};}
return{lineNumber:lineNumber,columnNumber:direction===-1?charNumber+1:charNumber};},_doCamelCaseMovement:function(direction,shift)
{var selections=this.selections();for(var i=0;i<selections.length;++i){var selection=selections[i];var move=this._camelCaseMoveFromPosition(selection.endLine,selection.endColumn,direction);selection.endLine=move.lineNumber;selection.endColumn=move.columnNumber;if(!shift)
selections[i]=selection.collapseToEnd();}
this.setSelections(selections);},dispose:function()
{WebInspector.moduleSetting("textEditorIndent").removeChangeListener(this._onUpdateEditorIndentation,this);WebInspector.moduleSetting("textEditorAutoDetectIndent").removeChangeListener(this._onUpdateEditorIndentation,this);WebInspector.moduleSetting("showWhitespacesInEditor").removeChangeListener(this._updateCodeMirrorMode,this);WebInspector.moduleSetting("textEditorBracketMatching").removeChangeListener(this._enableBracketMatchingIfNeeded,this);WebInspector.moduleSetting("textEditorAutocompletion").removeChangeListener(this._enableAutocompletionIfNeeded,this);},_enableBracketMatchingIfNeeded:function()
{this._codeMirror.setOption("autoCloseBrackets",WebInspector.moduleSetting("textEditorBracketMatching").get()?{explode:false}:false);},wasShown:function()
{if(this._wasOnceShown)
return;this._wasOnceShown=true;this._codeMirror.refresh();},willHide:function()
{delete this._editorSizeInSync;},_onUpdateEditorIndentation:function()
{this._setEditorIndentation(WebInspector.CodeMirrorUtils.pullLines(this._codeMirror,WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing));},_setEditorIndentation:function(lines)
{var extraKeys={};var indent=WebInspector.moduleSetting("textEditorIndent").get();if(WebInspector.moduleSetting("textEditorAutoDetectIndent").get())
indent=WebInspector.CodeMirrorTextEditor._guessIndentationLevel(lines);if(indent===WebInspector.TextUtils.Indent.TabCharacter){this._codeMirror.setOption("indentWithTabs",true);this._codeMirror.setOption("indentUnit",4);}else{this._codeMirror.setOption("indentWithTabs",false);this._codeMirror.setOption("indentUnit",indent.length);extraKeys.Tab=function(codeMirror)
{if(codeMirror.somethingSelected())
return CodeMirror.Pass;var pos=codeMirror.getCursor("head");codeMirror.replaceRange(indent.substring(pos.ch%indent.length),codeMirror.getCursor());}}
this._codeMirror.setOption("extraKeys",extraKeys);this._indentationLevel=indent;},indent:function()
{return this._indentationLevel;},_isSearchActive:function()
{return!!this._tokenHighlighter.highlightedRegex();},highlightSearchResults:function(regex,range)
{function innerHighlightRegex()
{if(range){this._revealLine(range.startLine);if(range.endColumn>WebInspector.CodeMirrorTextEditor.maxHighlightLength)
this.setSelection(range);else
this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine,range.startColumn));}
this._tokenHighlighter.highlightSearchResults(regex,range);}
if(!this._selectionBeforeSearch)
this._selectionBeforeSearch=this.selection();this._codeMirror.operation(innerHighlightRegex.bind(this));},cancelSearchResultsHighlight:function()
{this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));if(this._selectionBeforeSearch){this._reportJump(this._selectionBeforeSearch,this.selection());delete this._selectionBeforeSearch;}},undo:function()
{this._codeMirror.undo();},redo:function()
{this._codeMirror.redo();},_setupWhitespaceHighlight:function()
{var doc=this.element.ownerDocument;if(doc._codeMirrorWhitespaceStyleInjected||!WebInspector.moduleSetting("showWhitespacesInEditor").get())
return;doc._codeMirrorWhitespaceStyleInjected=true;const classBase=".show-whitespaces .CodeMirror .cm-whitespace-";const spaceChar="·";var spaceChars="";var rules="";for(var i=1;i<=WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan;++i){spaceChars+=spaceChar;var rule=classBase+i+"::before { content: '"+spaceChars+"';}\n";rules+=rule;}
var style=doc.createElement("style");style.textContent=rules;doc.head.appendChild(style);},_handleKeyDown:function(e)
{if(this._autocompleteController.keyDown(e))
e.consume(true);},_handlePostKeyDown:function(e)
{if(e.defaultPrevented)
e.consume(true);},setAutocompleteDelegate:function(delegate)
{this._autocompleteController.setDelegate(delegate);},cursorPositionToCoordinates:function(lineNumber,column)
{if(lineNumber>=this._codeMirror.lineCount()||lineNumber<0||column<0||column>this._codeMirror.getLine(lineNumber).length)
return null;var metrics=this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber,column));return{x:metrics.left,y:metrics.top,height:metrics.bottom-metrics.top};},coordinatesToCursorPosition:function(x,y)
{var element=this.element.ownerDocument.elementFromPoint(x,y);if(!element||!element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
return null;var gutterBox=this._codeMirror.getGutterElement().boxInWindow();if(x>=gutterBox.x&&x<=gutterBox.x+gutterBox.width&&y>=gutterBox.y&&y<=gutterBox.y+gutterBox.height)
return null;var coords=this._codeMirror.coordsChar({left:x,top:y});return WebInspector.CodeMirrorUtils.toRange(coords,coords);},tokenAtTextPosition:function(lineNumber,column)
{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
return null;var token=this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber,(column||0)+1));if(!token)
return null;return{startColumn:token.start,endColumn:token.end,type:token.type};},copyRange:function(textRange)
{var pos=WebInspector.CodeMirrorUtils.toPos(textRange.normalize());return this._codeMirror.getRange(pos.start,pos.end);},isClean:function()
{return this._codeMirror.isClean();},markClean:function()
{this._codeMirror.markClean();},_hasLongLines:function()
{function lineIterator(lineHandle)
{if(lineHandle.text.length>WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold)
hasLongLines=true;return hasLongLines;}
var hasLongLines=false;this._codeMirror.eachLine(lineIterator);return hasLongLines;},_allWhitespaceOverlayMode:function(mimeType)
{var modeName=CodeMirror.mimeModes[mimeType]?(CodeMirror.mimeModes[mimeType].name||CodeMirror.mimeModes[mimeType]):CodeMirror.mimeModes["text/plain"];modeName+="+all-whitespaces";if(CodeMirror.modes[modeName])
return modeName;function modeConstructor(config,parserConfig)
{function nextToken(stream)
{if(stream.peek()===" "){var spaces=0;while(spaces<WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan&&stream.peek()===" "){++spaces;stream.next();}
return"whitespace whitespace-"+spaces;}
while(!stream.eol()&&stream.peek()!==" ")
stream.next();return null;}
var whitespaceMode={token:nextToken};return CodeMirror.overlayMode(CodeMirror.getMode(config,mimeType),whitespaceMode,false);}
CodeMirror.defineMode(modeName,modeConstructor);return modeName;},_trailingWhitespaceOverlayMode:function(mimeType)
{var modeName=CodeMirror.mimeModes[mimeType]?(CodeMirror.mimeModes[mimeType].name||CodeMirror.mimeModes[mimeType]):CodeMirror.mimeModes["text/plain"];modeName+="+trailing-whitespaces";if(CodeMirror.modes[modeName])
return modeName;function modeConstructor(config,parserConfig)
{function nextToken(stream)
{var pos=stream.pos;if(stream.match(/^\s+$/,true))
return true?"trailing-whitespace":null;do{stream.next();}while(!stream.eol()&&stream.peek()!==" ");return null;}
var whitespaceMode={token:nextToken};return CodeMirror.overlayMode(CodeMirror.getMode(config,mimeType),whitespaceMode,false);}
CodeMirror.defineMode(modeName,modeConstructor);return modeName;},_enableLongLinesMode:function()
{this._codeMirror.setOption("styleSelectedText",false);},_disableLongLinesMode:function()
{this._codeMirror.setOption("styleSelectedText",true);},_updateCodeMirrorMode:function()
{this._setupWhitespaceHighlight();var whitespaceMode=WebInspector.moduleSetting("showWhitespacesInEditor").get();this.element.classList.toggle("show-whitespaces",whitespaceMode==="all");var mimeType=this._mimeType;if(whitespaceMode==="all")
mimeType=this._allWhitespaceOverlayMode(this._mimeType);else if(whitespaceMode==="trailing")
mimeType=this._trailingWhitespaceOverlayMode(this._mimeType);this._codeMirror.setOption("mode",mimeType);WebInspector.CodeMirrorTextEditor._loadMimeTypeModes(this._mimeType,this._mimeTypeModesLoaded.bind(this));},_mimeTypeModesLoaded:function()
{this._updateCodeMirrorMode();},setMimeType:function(mimeType)
{this._mimeType=mimeType;if(this._hasLongLines())
this._enableLongLinesMode();else
this._disableLongLinesMode();this._updateCodeMirrorMode();},setReadOnly:function(readOnly)
{this.element.classList.toggle("CodeMirror-readonly",readOnly);this._codeMirror.setOption("readOnly",readOnly);},readOnly:function()
{return!!this._codeMirror.getOption("readOnly");},removeHighlight:function(highlightDescriptor)
{highlightDescriptor.clear();},highlightRange:function(range,cssClass)
{cssClass="CodeMirror-persist-highlight "+cssClass;var pos=WebInspector.CodeMirrorUtils.toPos(range);++pos.end.ch;return this._codeMirror.markText(pos.start,pos.end,{className:cssClass,startStyle:cssClass+"-start",endStyle:cssClass+"-end"});},defaultFocusedElement:function()
{return this.element;},focus:function()
{this._codeMirror.focus();},_handleElementFocus:function()
{this._codeMirror.focus();},operation:function(operation)
{this._codeMirror.operation(operation);},_revealLine:function(lineNumber)
{this._innerRevealLine(lineNumber,this._codeMirror.getScrollInfo());},_innerRevealLine:function(lineNumber,scrollInfo)
{var topLine=this._codeMirror.lineAtHeight(scrollInfo.top,"local");var bottomLine=this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");var linesPerScreen=bottomLine-topLine+1;if(lineNumber<topLine){var topLineToReveal=Math.max(lineNumber-(linesPerScreen/2)+1,0)|0;this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal,0));}else if(lineNumber>bottomLine){var bottomLineToReveal=Math.min(lineNumber+(linesPerScreen/2)-1,this.linesCount-1)|0;this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal,0));}},_gutterClick:function(instance,lineNumber,gutter,event)
{this.dispatchEventToListeners(WebInspector.CodeMirrorTextEditor.Events.GutterClick,{lineNumber:lineNumber,event:event});},_contextMenu:function(event)
{var contextMenu=new WebInspector.ContextMenu(event);event.consume(true);var target=event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt");var promise;if(target)
promise=this._delegate.populateLineGutterContextMenu(contextMenu,parseInt(target.textContent,10)-1);else{var textSelection=this.selection();promise=this._delegate.populateTextAreaContextMenu(contextMenu,textSelection.startLine,textSelection.startColumn);}
promise.then(showAsync.bind(this));function showAsync()
{contextMenu.appendApplicableItems(this);contextMenu.show();}},addBreakpoint:function(lineNumber,disabled,conditional)
{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
return;var className="cm-breakpoint"+(conditional?" cm-breakpoint-conditional":"")+(disabled?" cm-breakpoint-disabled":"");this._codeMirror.addLineClass(lineNumber,"wrap",className);},removeBreakpoint:function(lineNumber)
{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
return;var wrapClasses=this._codeMirror.getLineHandle(lineNumber).wrapClass;if(!wrapClasses)
return;var classes=wrapClasses.split(" ");for(var i=0;i<classes.length;++i){if(classes[i].startsWith("cm-breakpoint"))
this._codeMirror.removeLineClass(lineNumber,"wrap",classes[i]);}},installGutter:function(type,leftToNumbers)
{if(this._gutters.indexOf(type)!==-1)
return;if(leftToNumbers)
this._gutters.unshift(type);else
this._gutters.push(type);this._codeMirror.setOption("gutters",this._gutters.slice());this._codeMirror.refresh();},uninstallGutter:function(type)
{this._gutters=this._gutters.filter(gutter=>gutter!==type);this._codeMirror.setOption("gutters",this._gutters.slice());this._codeMirror.refresh();},setGutterDecoration:function(lineNumber,type,element)
{console.assert(this._gutters.indexOf(type)!==-1,"Cannot decorate unexisting gutter.")
this._codeMirror.setGutterMarker(lineNumber,type,element);},setExecutionLocation:function(lineNumber,columnNumber)
{this.clearPositionHighlight();this._executionLine=this._codeMirror.getLineHandle(lineNumber);if(!this._executionLine)
return;this._codeMirror.addLineClass(this._executionLine,"wrap","cm-execution-line");this._executionLineTailMarker=this._codeMirror.markText({line:lineNumber,ch:columnNumber},{line:lineNumber,ch:this._codeMirror.getLine(lineNumber).length},{className:"cm-execution-line-tail"});},clearExecutionLine:function()
{this.clearPositionHighlight();if(this._executionLine)
this._codeMirror.removeLineClass(this._executionLine,"wrap","cm-execution-line");delete this._executionLine;if(this._executionLineTailMarker)
this._executionLineTailMarker.clear();delete this._executionLineTailMarker;},toggleLineClass:function(lineNumber,className,toggled)
{if(this.hasLineClass(lineNumber,className)===toggled)
return;var lineHandle=this._codeMirror.getLineHandle(lineNumber);if(!lineHandle)
return;if(toggled)
this._codeMirror.addLineClass(lineHandle,"wrap",className);else
this._codeMirror.removeLineClass(lineHandle,"wrap",className);},hasLineClass:function(lineNumber,className)
{var lineInfo=this._codeMirror.lineInfo(lineNumber);var wrapClass=lineInfo.wrapClass||"";var classNames=wrapClass.split(" ");return classNames.indexOf(className)!==-1;},addDecoration:function(lineNumber,element)
{var widget=this._codeMirror.addLineWidget(lineNumber,element);this._elementToWidget.set(element,widget);},removeDecoration:function(lineNumber,element)
{var widget=this._elementToWidget.remove(element);if(widget)
this._codeMirror.removeLineWidget(widget);},revealPosition:function(lineNumber,columnNumber,shouldHighlight)
{lineNumber=Number.constrain(lineNumber,0,this._codeMirror.lineCount()-1);if(typeof columnNumber!=="number")
columnNumber=0;columnNumber=Number.constrain(columnNumber,0,this._codeMirror.getLine(lineNumber).length);this.clearPositionHighlight();this._highlightedLine=this._codeMirror.getLineHandle(lineNumber);if(!this._highlightedLine)
return;this._revealLine(lineNumber);if(shouldHighlight){this._codeMirror.addLineClass(this._highlightedLine,null,"cm-highlight");this._clearHighlightTimeout=setTimeout(this.clearPositionHighlight.bind(this),2000);}
this.setSelection(WebInspector.TextRange.createFromLocation(lineNumber,columnNumber));},clearPositionHighlight:function()
{if(this._clearHighlightTimeout)
clearTimeout(this._clearHighlightTimeout);delete this._clearHighlightTimeout;if(this._highlightedLine)
this._codeMirror.removeLineClass(this._highlightedLine,null,"cm-highlight");delete this._highlightedLine;},elementsToRestoreScrollPositionsFor:function()
{return[];},_updatePaddingBottom:function(width,height)
{var scrollInfo=this._codeMirror.getScrollInfo();var newPaddingBottom;var linesElement=this._codeMirrorElement.querySelector(".CodeMirror-lines");var lineCount=this._codeMirror.lineCount();if(lineCount<=1)
newPaddingBottom=0;else
newPaddingBottom=Math.max(scrollInfo.clientHeight-this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height,0);newPaddingBottom+="px";linesElement.style.paddingBottom=newPaddingBottom;this._codeMirror.setSize(width,height);},_resizeEditor:function()
{var parentElement=this.element.parentElement;if(!parentElement||!this.isShowing())
return;var scrollLeft=this._codeMirror.doc.scrollLeft;var scrollTop=this._codeMirror.doc.scrollTop;var width=parentElement.offsetWidth;var height=parentElement.offsetHeight-this.element.offsetTop;this._codeMirror.setSize(width,height);this._updatePaddingBottom(width,height);this._codeMirror.scrollTo(scrollLeft,scrollTop);},onResize:function()
{this._autocompleteController.finishAutocomplete();this._resizeEditor();this._editorSizeInSync=true;if(this._selectionSetScheduled){delete this._selectionSetScheduled;this.setSelection(this._lastSelection);}},editRange:function(range,text)
{var pos=WebInspector.CodeMirrorUtils.toPos(range);this._codeMirror.replaceRange(text,pos.start,pos.end);var newRange=WebInspector.CodeMirrorUtils.toRange(pos.start,this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start)+text.length));this._delegate.onTextChanged(range,newRange);if(WebInspector.moduleSetting("textEditorAutoDetectIndent").get())
this._onUpdateEditorIndentation();return newRange;},wordRangeForCursorPosition:function(lineNumber,column,isWordChar)
{var line=this.line(lineNumber);var wordStart=column;if(column!==0&&isWordChar(line.charAt(column-1))){wordStart=column-1;while(wordStart>0&&isWordChar(line.charAt(wordStart-1)))
--wordStart;}
var wordEnd=column;while(wordEnd<line.length&&isWordChar(line.charAt(wordEnd)))
++wordEnd;return new WebInspector.TextRange(lineNumber,wordStart,lineNumber,wordEnd);},_changes:function(codeMirror,changes)
{if(!changes.length)
return;var hasOneLine=this._codeMirror.lineCount()===1;if(hasOneLine!==this._hasOneLine)
this._resizeEditor();this._hasOneLine=hasOneLine;var widgets=this._elementToWidget.valuesArray();for(var i=0;i<widgets.length;++i)
this._codeMirror.removeLineWidget(widgets[i]);this._elementToWidget.clear();for(var changeIndex=0;changeIndex<changes.length;++changeIndex){var changeObject=changes[changeIndex];var editInfo=WebInspector.CodeMirrorUtils.changeObjectToEditOperation(changeObject);if(!this._muteTextChangedEvent)
this._delegate.onTextChanged(editInfo.oldRange,editInfo.newRange);}},_cursorActivity:function()
{var start=this._codeMirror.getCursor("anchor");var end=this._codeMirror.getCursor("head");this._delegate.selectionChanged(WebInspector.CodeMirrorUtils.toRange(start,end));if(!this._isSearchActive())
this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));},_beforeSelectionChange:function(codeMirror,selection)
{this._selectNextOccurrenceController.selectionWillChange();if(!this._isHandlingMouseDownEvent)
return;if(!selection.ranges.length)
return;var primarySelection=selection.ranges[0];this._reportJump(this.selection(),WebInspector.CodeMirrorUtils.toRange(primarySelection.anchor,primarySelection.head));},_reportJump:function(from,to)
{if(from&&to&&from.equal(to))
return;this._delegate.onJumpToPosition(from,to);},_scroll:function()
{if(this._scrollTimer)
clearTimeout(this._scrollTimer);var topmostLineNumber=this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top,"local");this._scrollTimer=setTimeout(this._delegate.scrollChanged.bind(this._delegate,topmostLineNumber),100);},_focus:function()
{this._delegate.editorFocused();},scrollToLine:function(lineNumber)
{var pos=new CodeMirror.Pos(lineNumber,0);var coords=this._codeMirror.charCoords(pos,"local");this._codeMirror.scrollTo(0,coords.top);},firstVisibleLine:function()
{return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top,"local");},scrollTop:function()
{return this._codeMirror.getScrollInfo().top;},setScrollTop:function(scrollTop)
{this._codeMirror.scrollTo(0,scrollTop);},lastVisibleLine:function()
{var scrollInfo=this._codeMirror.getScrollInfo();return this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");},selection:function()
{var start=this._codeMirror.getCursor("anchor");var end=this._codeMirror.getCursor("head");return WebInspector.CodeMirrorUtils.toRange(start,end);},selections:function()
{var selectionList=this._codeMirror.listSelections();var result=[];for(var i=0;i<selectionList.length;++i){var selection=selectionList[i];result.push(WebInspector.CodeMirrorUtils.toRange(selection.anchor,selection.head));}
return result;},lastSelection:function()
{return this._lastSelection;},setSelection:function(textRange)
{this._lastSelection=textRange;if(!this._editorSizeInSync){this._selectionSetScheduled=true;return;}
var pos=WebInspector.CodeMirrorUtils.toPos(textRange);this._codeMirror.setSelection(pos.start,pos.end);},setSelections:function(ranges,primarySelectionIndex)
{var selections=[];for(var i=0;i<ranges.length;++i){var selection=WebInspector.CodeMirrorUtils.toPos(ranges[i]);selections.push({anchor:selection.start,head:selection.end});}
primarySelectionIndex=primarySelectionIndex||0;this._codeMirror.setSelections(selections,primarySelectionIndex,{scroll:false});},_detectLineSeparator:function(text)
{this._lineSeparator=text.indexOf("\r\n")>=0?"\r\n":"\n";},setText:function(text)
{this._muteTextChangedEvent=true;if(text.length>WebInspector.CodeMirrorTextEditor.MaxEditableTextSize){this._autocompleteController.setEnabled(false);this.setReadOnly(true);}
this._setEditorIndentation(text.split("\n").slice(0,WebInspector.CodeMirrorTextEditor.LinesToScanForIndentationGuessing));this._codeMirror.setValue(text);if(this._shouldClearHistory){this._codeMirror.clearHistory();this._shouldClearHistory=false;}
this._detectLineSeparator(text);delete this._muteTextChangedEvent;},text:function()
{return this._codeMirror.getValue().replace(/\n/g,this._lineSeparator);},range:function()
{var lineCount=this.linesCount;var lastLine=this._codeMirror.getLine(lineCount-1);return WebInspector.CodeMirrorUtils.toRange(new CodeMirror.Pos(0,0),new CodeMirror.Pos(lineCount-1,lastLine.length));},line:function(lineNumber)
{return this._codeMirror.getLine(lineNumber);},get linesCount()
{return this._codeMirror.lineCount();},setAttribute:function(line,name,value)
{if(line<0||line>=this._codeMirror.lineCount())
return;var handle=this._codeMirror.getLineHandle(line);if(handle.attributes===undefined)handle.attributes={};handle.attributes[name]=value;},getAttribute:function(line,name)
{if(line<0||line>=this._codeMirror.lineCount())
return null;var handle=this._codeMirror.getLineHandle(line);return handle.attributes&&handle.attributes[name]!==undefined?handle.attributes[name]:null;},removeAttribute:function(line,name)
{if(line<0||line>=this._codeMirror.lineCount())
return;var handle=this._codeMirror.getLineHandle(line);if(handle&&handle.attributes)
delete handle.attributes[name];},textEditorPositionHandle:function(lineNumber,columnNumber)
{return new WebInspector.CodeMirrorPositionHandle(this._codeMirror,new CodeMirror.Pos(lineNumber,columnNumber));},__proto__:WebInspector.VBox.prototype}
WebInspector.CodeMirrorPositionHandle=function(codeMirror,pos)
{this._codeMirror=codeMirror;this._lineHandle=codeMirror.getLineHandle(pos.line);this._columnNumber=pos.ch;}
WebInspector.CodeMirrorPositionHandle.prototype={resolve:function()
{var lineNumber=this._codeMirror.getLineNumber(this._lineHandle);if(typeof lineNumber!=="number")
return null;return{lineNumber:lineNumber,columnNumber:this._columnNumber};},equal:function(positionHandle)
{return positionHandle._lineHandle===this._lineHandle&&positionHandle._columnNumber==this._columnNumber&&positionHandle._codeMirror===this._codeMirror;}}
WebInspector.CodeMirrorTextEditor.TokenHighlighter=function(textEditor,codeMirror)
{this._textEditor=textEditor;this._codeMirror=codeMirror;}
WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype={highlightSearchResults:function(regex,range)
{var oldRegex=this._highlightRegex;this._highlightRegex=regex;this._highlightRange=range;if(this._searchResultMarker){this._searchResultMarker.clear();delete this._searchResultMarker;}
if(this._highlightDescriptor&&this._highlightDescriptor.selectionStart)
this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line,"wrap","cm-line-with-selection");var selectionStart=this._highlightRange?new CodeMirror.Pos(this._highlightRange.startLine,this._highlightRange.startColumn):null;if(selectionStart)
this._codeMirror.addLineClass(selectionStart.line,"wrap","cm-line-with-selection");if(this._highlightRegex===oldRegex){if(this._highlightDescriptor)
this._highlightDescriptor.selectionStart=selectionStart;}else{this._removeHighlight();this._setHighlighter(this._searchHighlighter.bind(this,this._highlightRegex),selectionStart);}
if(this._highlightRange){var pos=WebInspector.CodeMirrorUtils.toPos(this._highlightRange);this._searchResultMarker=this._codeMirror.markText(pos.start,pos.end,{className:"cm-column-with-selection"});}},highlightedRegex:function()
{return this._highlightRegex;},highlightSelectedTokens:function()
{delete this._highlightRegex;delete this._highlightRange;if(this._highlightDescriptor&&this._highlightDescriptor.selectionStart)
this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line,"wrap","cm-line-with-selection");this._removeHighlight();var selectionStart=this._codeMirror.getCursor("start");var selectionEnd=this._codeMirror.getCursor("end");if(selectionStart.line!==selectionEnd.line)
return;if(selectionStart.ch===selectionEnd.ch)
return;var selections=this._codeMirror.getSelections();if(selections.length>1)
return;var selectedText=selections[0];if(this._isWord(selectedText,selectionStart.line,selectionStart.ch,selectionEnd.ch)){if(selectionStart)
this._codeMirror.addLineClass(selectionStart.line,"wrap","cm-line-with-selection");this._setHighlighter(this._tokenHighlighter.bind(this,selectedText,selectionStart),selectionStart);}},_isWord:function(selectedText,lineNumber,startColumn,endColumn)
{var line=this._codeMirror.getLine(lineNumber);var leftBound=startColumn===0||!WebInspector.TextUtils.isWordChar(line.charAt(startColumn-1));var rightBound=endColumn===line.length||!WebInspector.TextUtils.isWordChar(line.charAt(endColumn));return leftBound&&rightBound&&WebInspector.TextUtils.isWord(selectedText);},_removeHighlight:function()
{if(this._highlightDescriptor){this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);delete this._highlightDescriptor;}},_searchHighlighter:function(regex,stream)
{if(stream.column()===0)
delete this._searchMatchLength;if(this._searchMatchLength){if(this._searchMatchLength>2){for(var i=0;i<this._searchMatchLength-2;++i)
stream.next();this._searchMatchLength=1;return"search-highlight";}else{stream.next();delete this._searchMatchLength;return"search-highlight search-highlight-end";}}
var match=stream.match(regex,false);if(match){stream.next();var matchLength=match[0].length;if(matchLength===1)
return"search-highlight search-highlight-full";this._searchMatchLength=matchLength;return"search-highlight search-highlight-start";}
while(!stream.match(regex,false)&&stream.next()){}},_tokenHighlighter:function(token,selectionStart,stream)
{var tokenFirstChar=token.charAt(0);if(stream.match(token)&&(stream.eol()||!WebInspector.TextUtils.isWordChar(stream.peek())))
return stream.column()===selectionStart.ch?"token-highlight column-with-selection":"token-highlight";var eatenChar;do{eatenChar=stream.next();}while(eatenChar&&(WebInspector.TextUtils.isWordChar(eatenChar)||stream.peek()!==tokenFirstChar));},_setHighlighter:function(highlighter,selectionStart)
{var overlayMode={token:highlighter};this._codeMirror.addOverlay(overlayMode);this._highlightDescriptor={overlay:overlayMode,selectionStart:selectionStart};}}
WebInspector.CodeMirrorTextEditor.BlockIndentController=function(codeMirror)
{codeMirror.addKeyMap(this);}
WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype={name:"blockIndentKeymap",Enter:function(codeMirror)
{var selections=codeMirror.listSelections();var replacements=[];var allSelectionsAreCollapsedBlocks=false;for(var i=0;i<selections.length;++i){var selection=selections[i];var start=CodeMirror.cmpPos(selection.head,selection.anchor)<0?selection.head:selection.anchor;var line=codeMirror.getLine(start.line);var indent=WebInspector.TextUtils.lineIndent(line);var indentToInsert="\n"+indent+codeMirror._codeMirrorTextEditor.indent();var isCollapsedBlock=false;if(selection.head.ch===0)
return CodeMirror.Pass;if(line.substr(selection.head.ch-1,2)==="{}"){indentToInsert+="\n"+indent;isCollapsedBlock=true;}else if(line.substr(selection.head.ch-1,1)!=="{"){return CodeMirror.Pass;}
if(i>0&&allSelectionsAreCollapsedBlocks!==isCollapsedBlock)
return CodeMirror.Pass;replacements.push(indentToInsert);allSelectionsAreCollapsedBlocks=isCollapsedBlock;}
codeMirror.replaceSelections(replacements);if(!allSelectionsAreCollapsedBlocks){codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();return;}
selections=codeMirror.listSelections();var updatedSelections=[];for(var i=0;i<selections.length;++i){var selection=selections[i];var line=codeMirror.getLine(selection.head.line-1);var position=new CodeMirror.Pos(selection.head.line-1,line.length);updatedSelections.push({head:position,anchor:position});}
codeMirror.setSelections(updatedSelections);codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();},"'}'":function(codeMirror)
{if(codeMirror.somethingSelected())
return CodeMirror.Pass;var selections=codeMirror.listSelections();var replacements=[];for(var i=0;i<selections.length;++i){var selection=selections[i];var line=codeMirror.getLine(selection.head.line);if(line!==WebInspector.TextUtils.lineIndent(line))
return CodeMirror.Pass;replacements.push("}");}
codeMirror.replaceSelections(replacements);selections=codeMirror.listSelections();replacements=[];var updatedSelections=[];for(var i=0;i<selections.length;++i){var selection=selections[i];var matchingBracket=codeMirror.findMatchingBracket(selection.head);if(!matchingBracket||!matchingBracket.match)
return;updatedSelections.push({head:selection.head,anchor:new CodeMirror.Pos(selection.head.line,0)});var line=codeMirror.getLine(matchingBracket.to.line);var indent=WebInspector.TextUtils.lineIndent(line);replacements.push(indent+"}");}
codeMirror.setSelections(updatedSelections);codeMirror.replaceSelections(replacements);}}
WebInspector.CodeMirrorTextEditor.FixWordMovement=function(codeMirror)
{function moveLeft(shift,codeMirror)
{codeMirror.setExtending(shift);var cursor=codeMirror.getCursor("head");codeMirror.execCommand("goGroupLeft");var newCursor=codeMirror.getCursor("head");if(newCursor.ch===0&&newCursor.line!==0){codeMirror.setExtending(false);return;}
var skippedText=codeMirror.getRange(newCursor,cursor,"#");if(/^\s+$/.test(skippedText))
codeMirror.execCommand("goGroupLeft");codeMirror.setExtending(false);}
function moveRight(shift,codeMirror)
{codeMirror.setExtending(shift);var cursor=codeMirror.getCursor("head");codeMirror.execCommand("goGroupRight");var newCursor=codeMirror.getCursor("head");if(newCursor.ch===0&&newCursor.line!==0){codeMirror.setExtending(false);return;}
var skippedText=codeMirror.getRange(cursor,newCursor,"#");if(/^\s+$/.test(skippedText))
codeMirror.execCommand("goGroupRight");codeMirror.setExtending(false);}
var modifierKey=WebInspector.isMac()?"Alt":"Ctrl";var leftKey=modifierKey+"-Left";var rightKey=modifierKey+"-Right";var keyMap={};keyMap[leftKey]=moveLeft.bind(null,false);keyMap[rightKey]=moveRight.bind(null,false);keyMap["Shift-"+leftKey]=moveLeft.bind(null,true);keyMap["Shift-"+rightKey]=moveRight.bind(null,true);codeMirror.addKeyMap(keyMap);}
WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController=function(textEditor,codeMirror)
{this._textEditor=textEditor;this._codeMirror=codeMirror;}
WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController.prototype={selectionWillChange:function()
{if(!this._muteSelectionListener)
delete this._fullWordSelection;},_findRange:function(selections,range)
{for(var i=0;i<selections.length;++i){if(range.equal(selections[i]))
return true;}
return false;},undoLastSelection:function()
{this._muteSelectionListener=true;this._codeMirror.execCommand("undoSelection");this._muteSelectionListener=false;},selectNextOccurrence:function()
{var selections=this._textEditor.selections();var anyEmptySelection=false;for(var i=0;i<selections.length;++i){var selection=selections[i];anyEmptySelection=anyEmptySelection||selection.isEmpty();if(selection.startLine!==selection.endLine)
return;}
if(anyEmptySelection){this._expandSelectionsToWords(selections);return;}
var last=selections[selections.length-1];var next=last;do{next=this._findNextOccurrence(next,!!this._fullWordSelection);}while(next&&this._findRange(selections,next)&&!next.equal(last));if(!next)
return;selections.push(next);this._muteSelectionListener=true;this._textEditor.setSelections(selections,selections.length-1);delete this._muteSelectionListener;this._textEditor._revealLine(next.startLine);},_expandSelectionsToWords:function(selections)
{var newSelections=[];for(var i=0;i<selections.length;++i){var selection=selections[i];var startRangeWord=this._textEditor.wordRangeForCursorPosition(selection.startLine,selection.startColumn,WebInspector.TextUtils.isWordChar)||WebInspector.TextRange.createFromLocation(selection.startLine,selection.startColumn);var endRangeWord=this._textEditor.wordRangeForCursorPosition(selection.endLine,selection.endColumn,WebInspector.TextUtils.isWordChar)||WebInspector.TextRange.createFromLocation(selection.endLine,selection.endColumn);var newSelection=new WebInspector.TextRange(startRangeWord.startLine,startRangeWord.startColumn,endRangeWord.endLine,endRangeWord.endColumn);newSelections.push(newSelection);}
this._textEditor.setSelections(newSelections,newSelections.length-1);this._fullWordSelection=true;},_findNextOccurrence:function(range,fullWord)
{range=range.normalize();var matchedLineNumber;var matchedColumnNumber;var textToFind=this._textEditor.copyRange(range);function findWordInLine(wordRegex,lineNumber,lineText,from,to)
{if(typeof matchedLineNumber==="number")
return true;wordRegex.lastIndex=from;var result=wordRegex.exec(lineText);if(!result||result.index+textToFind.length>to)
return false;matchedLineNumber=lineNumber;matchedColumnNumber=result.index;return true;}
var iteratedLineNumber;function lineIterator(regex,lineHandle)
{if(findWordInLine(regex,iteratedLineNumber++,lineHandle.text,0,lineHandle.text.length))
return true;}
var regexSource=textToFind.escapeForRegExp();if(fullWord)
regexSource="\\b"+regexSource+"\\b";var wordRegex=new RegExp(regexSource,"g");var currentLineText=this._codeMirror.getLine(range.startLine);findWordInLine(wordRegex,range.startLine,currentLineText,range.endColumn,currentLineText.length);iteratedLineNumber=range.startLine+1;this._codeMirror.eachLine(range.startLine+1,this._codeMirror.lineCount(),lineIterator.bind(null,wordRegex));iteratedLineNumber=0;this._codeMirror.eachLine(0,range.startLine,lineIterator.bind(null,wordRegex));findWordInLine(wordRegex,range.startLine,currentLineText,0,range.startColumn);if(typeof matchedLineNumber!=="number")
return null;return new WebInspector.TextRange(matchedLineNumber,matchedColumnNumber,matchedLineNumber,matchedColumnNumber+textToFind.length);}}
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens=function(modeName,tokenPrefix)
{var oldModeName=modeName+"-old";if(CodeMirror.modes[oldModeName])
return;CodeMirror.defineMode(oldModeName,CodeMirror.modes[modeName]);CodeMirror.defineMode(modeName,modeConstructor);function modeConstructor(config,parserConfig)
{var innerConfig={};for(var i in parserConfig)
innerConfig[i]=parserConfig[i];innerConfig.name=oldModeName;var codeMirrorMode=CodeMirror.getMode(config,innerConfig);codeMirrorMode.name=modeName;codeMirrorMode.token=tokenOverride.bind(null,codeMirrorMode.token);return codeMirrorMode;}
function tokenOverride(superToken,stream,state)
{var token=superToken(stream,state);return token?tokenPrefix+token.split(/ +/).join(" "+tokenPrefix):token;}}
WebInspector.TextEditorPositionHandle=function(){}
WebInspector.TextEditorPositionHandle.prototype={resolve:function(){},equal:function(positionHandle){}}
WebInspector.TextEditorDelegate=function(){}
WebInspector.TextEditorDelegate.prototype={onTextChanged:function(oldRange,newRange){},selectionChanged:function(textRange){},scrollChanged:function(lineNumber){},editorFocused:function(){},populateLineGutterContextMenu:function(contextMenu,lineNumber){},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber){},onJumpToPosition:function(from,to){}}
WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("css","css-");WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("javascript","js-");WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("xml","xml-");WebInspector.CodeMirrorTextEditor.GutterClickEventData;WebInspector.CodeMirrorTextEditor.Events={GutterClick:"GutterClick"}
WebInspector.CodeMirrorTextEditor._loadedMimeModeExtensions=new Set();WebInspector.CodeMirrorTextEditor._loadMimeTypeModes=function(mimeType,callback)
{var installed=WebInspector.CodeMirrorTextEditor._loadedMimeModeExtensions;var nameToExtension=new Map();var extensions=self.runtime.extensions(WebInspector.CodeMirrorMimeMode);for(var extension of extensions)
nameToExtension.set(extension.descriptor()["fileName"],extension);var modesToLoad=new Set();for(var extension of extensions){var descriptor=extension.descriptor();if(installed.has(extension)||descriptor["mimeTypes"].indexOf(mimeType)===-1)
continue;modesToLoad.add(extension);var deps=descriptor["dependencies"]||[];for(var i=0;i<deps.length;++i){var extension=nameToExtension.get(deps[i]);if(extension&&!installed.has(extension))
modesToLoad.add(extension);}}
var promises=[];for(var extension of modesToLoad)
promises.push(extension.instancePromise().then(installMode.bind(null,extension)));if(promises.length)
Promise.all(promises).then(callback);function installMode(extension,instance)
{if(installed.has(extension))
return;var mode=(instance);mode.install(extension);installed.add(extension);}}
WebInspector.CodeMirrorMimeMode=function()
{}
WebInspector.CodeMirrorMimeMode.prototype={install:function(extension){}};WebInspector.FontView=function(mimeType,contentProvider)
{WebInspector.VBoxWithToolbarItems.call(this);this.registerRequiredCSS("source_frame/fontView.css");this.element.classList.add("font-view");this._url=contentProvider.contentURL();this._mimeType=mimeType;this._contentProvider=contentProvider;this._mimeTypeLabel=new WebInspector.ToolbarText(mimeType);}
WebInspector.FontView._fontPreviewLines=["ABCDEFGHIJKLM","NOPQRSTUVWXYZ","abcdefghijklm","nopqrstuvwxyz","1234567890"];WebInspector.FontView._fontId=0;WebInspector.FontView._measureFontSize=50;WebInspector.FontView.prototype={toolbarItems:function()
{return[this._mimeTypeLabel];},_onFontContentLoaded:function(uniqueFontName,content)
{var url=content?WebInspector.Resource.contentAsDataURL(content,this._mimeType,true):this._url;this.fontStyleElement.textContent=String.sprintf("@font-face { font-family: \"%s\"; src: url(%s); }",uniqueFontName,url);},_createContentIfNeeded:function()
{if(this.fontPreviewElement)
return;var uniqueFontName="WebInspectorFontPreview"+(++WebInspector.FontView._fontId);this.fontStyleElement=createElement("style");this._contentProvider.requestContent().then(this._onFontContentLoaded.bind(this,uniqueFontName));this.element.appendChild(this.fontStyleElement);var fontPreview=createElement("div");for(var i=0;i<WebInspector.FontView._fontPreviewLines.length;++i){if(i>0)
fontPreview.createChild("br");fontPreview.createTextChild(WebInspector.FontView._fontPreviewLines[i]);}
this.fontPreviewElement=fontPreview.cloneNode(true);this.fontPreviewElement.style.setProperty("font-family",uniqueFontName);this.fontPreviewElement.style.setProperty("visibility","hidden");this._dummyElement=fontPreview;this._dummyElement.style.visibility="hidden";this._dummyElement.style.zIndex="-1";this._dummyElement.style.display="inline";this._dummyElement.style.position="absolute";this._dummyElement.style.setProperty("font-family",uniqueFontName);this._dummyElement.style.setProperty("font-size",WebInspector.FontView._measureFontSize+"px");this.element.appendChild(this.fontPreviewElement);},wasShown:function()
{this._createContentIfNeeded();this.updateFontPreviewSize();},onResize:function()
{if(this._inResize)
return;this._inResize=true;try{this.updateFontPreviewSize();}finally{delete this._inResize;}},_measureElement:function()
{this.element.appendChild(this._dummyElement);var result={width:this._dummyElement.offsetWidth,height:this._dummyElement.offsetHeight};this.element.removeChild(this._dummyElement);return result;},updateFontPreviewSize:function()
{if(!this.fontPreviewElement||!this.isShowing())
return;this.fontPreviewElement.style.removeProperty("visibility");var dimension=this._measureElement();const height=dimension.height;const width=dimension.width;const containerWidth=this.element.offsetWidth-50;const containerHeight=this.element.offsetHeight-30;if(!height||!width||!containerWidth||!containerHeight){this.fontPreviewElement.style.removeProperty("font-size");return;}
var widthRatio=containerWidth/width;var heightRatio=containerHeight/height;var finalFontSize=Math.floor(WebInspector.FontView._measureFontSize*Math.min(widthRatio,heightRatio))-2;this.fontPreviewElement.style.setProperty("font-size",finalFontSize+"px",null);},__proto__:WebInspector.VBoxWithToolbarItems.prototype};WebInspector.ImageView=function(mimeType,contentProvider)
{WebInspector.VBoxWithToolbarItems.call(this);this.registerRequiredCSS("source_frame/imageView.css");this.element.classList.add("image-view");this._url=contentProvider.contentURL();this._parsedURL=new WebInspector.ParsedURL(this._url);this._mimeType=mimeType;this._contentProvider=contentProvider;this._sizeLabel=new WebInspector.ToolbarText();this._dimensionsLabel=new WebInspector.ToolbarText();this._mimeTypeLabel=new WebInspector.ToolbarText(mimeType);}
WebInspector.ImageView.prototype={toolbarItems:function()
{return[this._sizeLabel,new WebInspector.ToolbarSeparator(),this._dimensionsLabel,new WebInspector.ToolbarSeparator(),this._mimeTypeLabel];},wasShown:function()
{this._createContentIfNeeded();},_createContentIfNeeded:function()
{if(this._container)
return;this._container=this.element.createChild("div","image");var imagePreviewElement=this._container.createChild("img","resource-image-view");imagePreviewElement.addEventListener("contextmenu",this._contextMenu.bind(this),true);WebInspector.Resource.populateImageSource(this._url,this._mimeType,this._contentProvider,imagePreviewElement);this._contentProvider.requestContent().then(onContentAvailable.bind(this));function onContentAvailable(content)
{this._sizeLabel.setText(Number.bytesToString(this._base64ToSize(content)));this._dimensionsLabel.setText(WebInspector.UIString("%d × %d",imagePreviewElement.naturalWidth,imagePreviewElement.naturalHeight));}
this._imagePreviewElement=imagePreviewElement;},_base64ToSize:function(content)
{if(!content||!content.length)
return 0;var size=(content.length||0)*3/4;if(content.length>0&&content[content.length-1]==="=")
size--;if(content.length>1&&content[content.length-2]==="=")
size--;return size;},_contextMenu:function(event)
{var contextMenu=new WebInspector.ContextMenu(event);if(!this._parsedURL.isDataURL())
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^image URL"),this._copyImageURL.bind(this));if(this._imagePreviewElement.src)
contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^image as Data URI"),this._copyImageAsDataURL.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^image in ^new ^tab"),this._openInNewTab.bind(this));contextMenu.show();},_copyImageAsDataURL:function()
{InspectorFrontendHost.copyText(this._imagePreviewElement.src);},_copyImageURL:function()
{InspectorFrontendHost.copyText(this._url);},_openInNewTab:function()
{InspectorFrontendHost.openInNewTab(this._url);},__proto__:WebInspector.VBoxWithToolbarItems.prototype};WebInspector.SourceFrame=function(url,lazyContent)
{WebInspector.VBoxWithToolbarItems.call(this);this._url=url;this._lazyContent=lazyContent;var textEditorDelegate=new WebInspector.TextEditorDelegateForSourceFrame(this);this._textEditor=new WebInspector.CodeMirrorTextEditor(this._url,textEditorDelegate);this._currentSearchResultIndex=-1;this._searchResults=[];this._textEditor.setReadOnly(!this.canEditSource());this._shortcuts={};this.element.addEventListener("keydown",this._handleKeyDown.bind(this),false);this._sourcePosition=new WebInspector.ToolbarText();this._searchableView=null;}
WebInspector.SourceFrame.Events={ScrollChanged:"ScrollChanged",SelectionChanged:"SelectionChanged",JumpHappened:"JumpHappened"}
WebInspector.SourceFrame.prototype={addShortcut:function(key,handler)
{this._shortcuts[key]=handler;},wasShown:function()
{this._ensureContentLoaded();this._textEditor.show(this.element);this._editorAttached=true;this._wasShownOrLoaded();},isEditorShowing:function()
{return this.isShowing()&&this._editorAttached;},willHide:function()
{WebInspector.Widget.prototype.willHide.call(this);this._clearPositionToReveal();},toolbarItems:function()
{return[this._sourcePosition];},defaultFocusedElement:function()
{return this._textEditor.defaultFocusedElement();},get loaded()
{return this._loaded;},get textEditor()
{return this._textEditor;},_ensureContentLoaded:function()
{if(!this._contentRequested){this._contentRequested=true;this._lazyContent().then(this.setContent.bind(this));}},revealPosition:function(line,column,shouldHighlight)
{this._clearLineToScrollTo();this._clearSelectionToSet();this._positionToReveal={line:line,column:column,shouldHighlight:shouldHighlight};this._innerRevealPositionIfNeeded();},_innerRevealPositionIfNeeded:function()
{if(!this._positionToReveal)
return;if(!this.loaded||!this.isEditorShowing())
return;this._textEditor.revealPosition(this._positionToReveal.line,this._positionToReveal.column,this._positionToReveal.shouldHighlight);delete this._positionToReveal;},_clearPositionToReveal:function()
{this._textEditor.clearPositionHighlight();delete this._positionToReveal;},scrollToLine:function(line)
{this._clearPositionToReveal();this._lineToScrollTo=line;this._innerScrollToLineIfNeeded();},_innerScrollToLineIfNeeded:function()
{if(typeof this._lineToScrollTo==="number"){if(this.loaded&&this.isEditorShowing()){this._textEditor.scrollToLine(this._lineToScrollTo);delete this._lineToScrollTo;}}},_clearLineToScrollTo:function()
{delete this._lineToScrollTo;},selection:function()
{return this.textEditor.selection();},setSelection:function(textRange)
{this._selectionToSet=textRange;this._innerSetSelectionIfNeeded();},_innerSetSelectionIfNeeded:function()
{if(this._selectionToSet&&this.loaded&&this.isEditorShowing()){this._textEditor.setSelection(this._selectionToSet);delete this._selectionToSet;}},_clearSelectionToSet:function()
{delete this._selectionToSet;},_wasShownOrLoaded:function()
{this._innerRevealPositionIfNeeded();this._innerSetSelectionIfNeeded();this._innerScrollToLineIfNeeded();},onTextChanged:function(oldRange,newRange)
{if(this._searchConfig&&this._searchableView)
this.performSearch(this._searchConfig,false,false);},_simplifyMimeType:function(content,mimeType)
{if(!mimeType)
return"";if(mimeType.indexOf("javascript")>=0||mimeType.indexOf("jscript")>=0||mimeType.indexOf("ecmascript")>=0)
return"text/javascript";if(mimeType==="text/x-php"&&content.match(/\<\?.*\?\>/g))
return"application/x-httpd-php";return mimeType;},setHighlighterType:function(highlighterType)
{this._highlighterType=highlighterType;this._updateHighlighterType("");},_updateHighlighterType:function(content)
{this._textEditor.setMimeType(this._simplifyMimeType(content,this._highlighterType));},setContent:function(content)
{if(!this._loaded){this._loaded=true;this._textEditor.setText(content||"");this._textEditor.markClean();}else{var scrollTop=this._textEditor.scrollTop();var selection=this._textEditor.selection();this._textEditor.setText(content||"");this._textEditor.setScrollTop(scrollTop);this._textEditor.setSelection(selection);}
this._updateHighlighterType(content||"");this._wasShownOrLoaded();if(this._delayedFindSearchMatches){this._delayedFindSearchMatches();delete this._delayedFindSearchMatches;}
this.onTextEditorContentLoaded();},onTextEditorContentLoaded:function(){},setSearchableView:function(view)
{this._searchableView=view;},_doFindSearchMatches:function(searchConfig,shouldJump,jumpBackwards)
{this._currentSearchResultIndex=-1;this._searchResults=[];var regex=searchConfig.toSearchRegex();this._searchRegex=regex;this._searchResults=this._collectRegexMatches(regex);if(this._searchableView)
this._searchableView.updateSearchMatchesCount(this._searchResults.length);if(!this._searchResults.length)
this._textEditor.cancelSearchResultsHighlight();else if(shouldJump&&jumpBackwards)
this.jumpToPreviousSearchResult();else if(shouldJump)
this.jumpToNextSearchResult();else
this._textEditor.highlightSearchResults(regex,null);},performSearch:function(searchConfig,shouldJump,jumpBackwards)
{if(this._searchableView)
this._searchableView.updateSearchMatchesCount(0);this._resetSearch();this._searchConfig=searchConfig;if(this.loaded)
this._doFindSearchMatches(searchConfig,shouldJump,!!jumpBackwards)
else
this._delayedFindSearchMatches=this._doFindSearchMatches.bind(this,searchConfig,shouldJump,!!jumpBackwards);this._ensureContentLoaded();},_editorFocused:function()
{this._resetCurrentSearchResultIndex();},_resetCurrentSearchResultIndex:function()
{if(!this._searchResults.length)
return;this._currentSearchResultIndex=-1;if(this._searchableView)
this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);this._textEditor.highlightSearchResults(this._searchRegex,null);},_resetSearch:function()
{delete this._searchConfig;delete this._delayedFindSearchMatches;this._currentSearchResultIndex=-1;this._searchResults=[];delete this._searchRegex;},searchCanceled:function()
{var range=this._currentSearchResultIndex!==-1?this._searchResults[this._currentSearchResultIndex]:null;this._resetSearch();if(!this.loaded)
return;this._textEditor.cancelSearchResultsHighlight();if(range)
this.setSelection(range);},hasSearchResults:function()
{return this._searchResults.length>0;},jumpToFirstSearchResult:function()
{this.jumpToSearchResult(0);},jumpToLastSearchResult:function()
{this.jumpToSearchResult(this._searchResults.length-1);},_searchResultIndexForCurrentSelection:function()
{return this._searchResults.lowerBound(this._textEditor.selection().collapseToEnd(),WebInspector.TextRange.comparator);},jumpToNextSearchResult:function()
{var currentIndex=this._searchResultIndexForCurrentSelection();var nextIndex=this._currentSearchResultIndex===-1?currentIndex:currentIndex+1;this.jumpToSearchResult(nextIndex);},jumpToPreviousSearchResult:function()
{var currentIndex=this._searchResultIndexForCurrentSelection();this.jumpToSearchResult(currentIndex-1);},supportsCaseSensitiveSearch:function()
{return true;},supportsRegexSearch:function()
{return true;},get currentSearchResultIndex()
{return this._currentSearchResultIndex;},jumpToSearchResult:function(index)
{if(!this.loaded||!this._searchResults.length)
return;this._currentSearchResultIndex=(index+this._searchResults.length)%this._searchResults.length;if(this._searchableView)
this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);this._textEditor.highlightSearchResults(this._searchRegex,this._searchResults[this._currentSearchResultIndex]);},replaceSelectionWith:function(searchConfig,replacement)
{var range=this._searchResults[this._currentSearchResultIndex];if(!range)
return;this._textEditor.highlightSearchResults(this._searchRegex,null);var oldText=this._textEditor.copyRange(range);var regex=searchConfig.toSearchRegex();var text;if(regex.__fromRegExpQuery)
text=oldText.replace(regex,replacement);else
text=oldText.replace(regex,function(){return replacement;});var newRange=this._textEditor.editRange(range,text);this._textEditor.setSelection(newRange.collapseToEnd());},replaceAllWith:function(searchConfig,replacement)
{this._resetCurrentSearchResultIndex();var text=this._textEditor.text();var range=this._textEditor.range();var regex=searchConfig.toSearchRegex(true);if(regex.__fromRegExpQuery)
text=text.replace(regex,replacement);else
text=text.replace(regex,function(){return replacement;});var ranges=this._collectRegexMatches(regex);if(!ranges.length)
return;var currentRangeIndex=ranges.lowerBound(this._textEditor.selection(),WebInspector.TextRange.comparator);var lastRangeIndex=mod(currentRangeIndex-1,ranges.length);var lastRange=ranges[lastRangeIndex];var replacementLineEndings=replacement.computeLineEndings();var replacementLineCount=replacementLineEndings.length;var lastLineNumber=lastRange.startLine+replacementLineEndings.length-1;var lastColumnNumber=lastRange.startColumn;if(replacementLineEndings.length>1)
lastColumnNumber=replacementLineEndings[replacementLineCount-1]-replacementLineEndings[replacementLineCount-2]-1;this._textEditor.editRange(range,text);this._textEditor.revealPosition(lastLineNumber,lastColumnNumber);this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(lastLineNumber,lastColumnNumber));},_collectRegexMatches:function(regexObject)
{var ranges=[];for(var i=0;i<this._textEditor.linesCount;++i){var line=this._textEditor.line(i);var offset=0;do{var match=regexObject.exec(line);if(match){var matchEndIndex=match.index+Math.max(match[0].length,1);if(match[0].length)
ranges.push(new WebInspector.TextRange(i,offset+match.index,i,offset+matchEndIndex));offset+=matchEndIndex;line=line.substring(matchEndIndex);}}while(match&&line);}
return ranges;},populateLineGutterContextMenu:function(contextMenu,lineNumber)
{return Promise.resolve();},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber)
{return Promise.resolve();},onJumpToPosition:function(from,to)
{this.dispatchEventToListeners(WebInspector.SourceFrame.Events.JumpHappened,{from:from,to:to});},canEditSource:function()
{return false;},selectionChanged:function(textRange)
{this._updateSourcePosition();this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged,textRange);WebInspector.notifications.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged,textRange);},_updateSourcePosition:function()
{var selections=this._textEditor.selections();if(!selections.length)
return;if(selections.length>1){this._sourcePosition.setText(WebInspector.UIString("%d selection regions",selections.length));return;}
var textRange=selections[0];if(textRange.isEmpty()){this._sourcePosition.setText(WebInspector.UIString("Line %d, Column %d",textRange.endLine+1,textRange.endColumn+1));return;}
textRange=textRange.normalize();var selectedText=this._textEditor.copyRange(textRange);if(textRange.startLine===textRange.endLine)
this._sourcePosition.setText(WebInspector.UIString("%d characters selected",selectedText.length));else
this._sourcePosition.setText(WebInspector.UIString("%d lines, %d characters selected",textRange.endLine-textRange.startLine+1,selectedText.length));},scrollChanged:function(lineNumber)
{this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged,lineNumber);},_handleKeyDown:function(e)
{var shortcutKey=WebInspector.KeyboardShortcut.makeKeyFromEvent(e);var handler=this._shortcuts[shortcutKey];if(handler&&handler())
e.consume(true);},__proto__:WebInspector.VBoxWithToolbarItems.prototype}
WebInspector.TextEditorDelegateForSourceFrame=function(sourceFrame)
{this._sourceFrame=sourceFrame;}
WebInspector.TextEditorDelegateForSourceFrame.prototype={onTextChanged:function(oldRange,newRange)
{this._sourceFrame.onTextChanged(oldRange,newRange);},selectionChanged:function(textRange)
{this._sourceFrame.selectionChanged(textRange);},scrollChanged:function(lineNumber)
{this._sourceFrame.scrollChanged(lineNumber);},editorFocused:function()
{this._sourceFrame._editorFocused();},populateLineGutterContextMenu:function(contextMenu,lineNumber)
{return this._sourceFrame.populateLineGutterContextMenu(contextMenu,lineNumber);},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber)
{return this._sourceFrame.populateTextAreaContextMenu(contextMenu,lineNumber,columnNumber);},onJumpToPosition:function(from,to)
{this._sourceFrame.onJumpToPosition(from,to);}};WebInspector.ResourceSourceFrame=function(resource)
{this._resource=resource;WebInspector.SourceFrame.call(this,resource.contentURL(),resource.requestContent.bind(resource));}
WebInspector.ResourceSourceFrame.createSearchableView=function(resource,highlighterType)
{var sourceFrame=new WebInspector.ResourceSourceFrame(resource);sourceFrame.setHighlighterType(highlighterType);var searchableView=new WebInspector.SearchableView(sourceFrame);searchableView.setPlaceholder(WebInspector.UIString("Find"));sourceFrame.show(searchableView.element);sourceFrame.setSearchableView(searchableView);return searchableView;}
WebInspector.ResourceSourceFrame.prototype={get resource()
{return this._resource;},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber)
{contextMenu.appendApplicableItems(this._resource);return Promise.resolve();},__proto__:WebInspector.SourceFrame.prototype};Runtime.cachedResources["cm/codemirror.css"]="/* BASICS */\n\n.CodeMirror {\n /* Set height, width, borders, and global font properties here */\n font-family: monospace;\n height: 300px;\n}\n\n/* PADDING */\n\n.CodeMirror-lines {\n padding: 4px 0; /* Vertical padding around content */\n}\n.CodeMirror pre {\n padding: 0 4px; /* Horizontal padding of content */\n}\n\n.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n background-color: white; /* The little square between H and V scrollbars */\n}\n\n/* GUTTER */\n\n.CodeMirror-gutters {\n border-right: 1px solid #ddd;\n background-color: #f7f7f7;\n white-space: nowrap;\n}\n.CodeMirror-linenumbers {}\n.CodeMirror-linenumber {\n padding: 0 3px 0 5px;\n min-width: 20px;\n text-align: right;\n color: #999;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\n\n.CodeMirror-guttermarker { color: black; }\n.CodeMirror-guttermarker-subtle { color: #999; }\n\n/* CURSOR */\n\n.CodeMirror div.CodeMirror-cursor {\n border-left: 1px solid black;\n}\n/* Shown when moving in bi-directional text */\n.CodeMirror div.CodeMirror-secondarycursor {\n border-left: 1px solid silver;\n}\n.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {\n width: auto;\n border: 0;\n background: #7e7;\n}\n.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {\n z-index: 1;\n}\n\n.cm-animate-fat-cursor {\n width: auto;\n border: 0;\n -webkit-animation: blink 1.06s steps(1) infinite;\n -moz-animation: blink 1.06s steps(1) infinite;\n animation: blink 1.06s steps(1) infinite;\n}\n@-moz-keyframes blink {\n 0% { background: #7e7; }\n 50% { background: none; }\n 100% { background: #7e7; }\n}\n@-webkit-keyframes blink {\n 0% { background: #7e7; }\n 50% { background: none; }\n 100% { background: #7e7; }\n}\n@keyframes blink {\n 0% { background: #7e7; }\n 50% { background: none; }\n 100% { background: #7e7; }\n}\n\n/* Can style cursor different in overwrite (non-insert) mode */\ndiv.CodeMirror-overwrite div.CodeMirror-cursor {}\n\n.cm-tab { display: inline-block; text-decoration: inherit; }\n\n.CodeMirror-ruler {\n border-left: 1px solid #ccc;\n position: absolute;\n}\n\n/* DEFAULT THEME */\n\n.cm-s-default .cm-keyword {color: #708;}\n.cm-s-default .cm-atom {color: #219;}\n.cm-s-default .cm-number {color: #164;}\n.cm-s-default .cm-def {color: #00f;}\n.cm-s-default .cm-variable,\n.cm-s-default .cm-punctuation,\n.cm-s-default .cm-property,\n.cm-s-default .cm-operator {}\n.cm-s-default .cm-variable-2 {color: #05a;}\n.cm-s-default .cm-variable-3 {color: #085;}\n.cm-s-default .cm-comment {color: #a50;}\n.cm-s-default .cm-string {color: #a11;}\n.cm-s-default .cm-string-2 {color: #f50;}\n.cm-s-default .cm-meta {color: #555;}\n.cm-s-default .cm-qualifier {color: #555;}\n.cm-s-default .cm-builtin {color: #30a;}\n.cm-s-default .cm-bracket {color: #997;}\n.cm-s-default .cm-tag {color: #170;}\n.cm-s-default .cm-attribute {color: #00c;}\n.cm-s-default .cm-header {color: blue;}\n.cm-s-default .cm-quote {color: #090;}\n.cm-s-default .cm-hr {color: #999;}\n.cm-s-default .cm-link {color: #00c;}\n\n.cm-negative {color: #d44;}\n.cm-positive {color: #292;}\n.cm-header, .cm-strong {font-weight: bold;}\n.cm-em {font-style: italic;}\n.cm-link {text-decoration: underline;}\n.cm-strikethrough {text-decoration: line-through;}\n\n.cm-s-default .cm-error {color: #f00;}\n.cm-invalidchar {color: #f00;}\n\n/* Default styles for common addons */\n\ndiv.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}\ndiv.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}\n.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }\n.CodeMirror-activeline-background { background: #e8f2ff; }\n\n/* STOP */\n\n/* The rest of this file contains styles related to the mechanics of\n the editor. You probably shouldn't touch them. */\n\n.CodeMirror {\n line-height: 1;\n position: relative;\n overflow: hidden;\n background: white;\n color: black;\n}\n\n.CodeMirror-scroll {\n overflow: scroll !important; /* Things will break if this is overridden */\n /* 30px is the magic margin used to hide the element's real scrollbars */\n /* See overflow: hidden in .CodeMirror */\n margin-bottom: -30px; margin-right: -30px;\n padding-bottom: 30px;\n height: 100%;\n outline: none; /* Prevent dragging from highlighting the element */\n position: relative;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\n.CodeMirror-sizer {\n position: relative;\n border-right: 30px solid transparent;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\n\n/* The fake, visible scrollbars. Used to force redraw during scrolling\n before actuall scrolling happens, thus preventing shaking and\n flickering artifacts. */\n.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n position: absolute;\n z-index: 6;\n display: none;\n}\n.CodeMirror-vscrollbar {\n right: 0; top: 0;\n overflow-x: hidden;\n overflow-y: scroll;\n}\n.CodeMirror-hscrollbar {\n bottom: 0; left: 0;\n overflow-y: hidden;\n overflow-x: scroll;\n}\n.CodeMirror-scrollbar-filler {\n right: 0; bottom: 0;\n}\n.CodeMirror-gutter-filler {\n left: 0; bottom: 0;\n}\n\n.CodeMirror-gutters {\n position: absolute; left: 0; top: 0;\n z-index: 3;\n}\n.CodeMirror-gutter {\n white-space: normal;\n height: 100%;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n display: inline-block;\n margin-bottom: -30px;\n /* Hack to make IE7 behave */\n *zoom:1;\n *display:inline;\n}\n.CodeMirror-gutter-wrapper {\n position: absolute;\n z-index: 4;\n height: 100%;\n}\n.CodeMirror-gutter-elt {\n position: absolute;\n cursor: default;\n z-index: 4;\n}\n\n.CodeMirror-lines {\n cursor: text;\n min-height: 1px; /* prevents collapsing before first draw */\n}\n.CodeMirror pre {\n /* Reset some styles that the rest of the page might have set */\n -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\n border-width: 0;\n background: transparent;\n font-family: inherit;\n font-size: inherit;\n margin: 0;\n white-space: pre;\n word-wrap: normal;\n line-height: inherit;\n color: inherit;\n z-index: 2;\n position: relative;\n overflow: visible;\n}\n.CodeMirror-wrap pre {\n word-wrap: break-word;\n white-space: pre-wrap;\n word-break: normal;\n}\n\n.CodeMirror-linebackground {\n position: absolute;\n left: 0; right: 0; top: 0; bottom: 0;\n z-index: 0;\n}\n\n.CodeMirror-linewidget {\n position: relative;\n z-index: 2;\n overflow: auto;\n}\n\n.CodeMirror-widget {}\n\n.CodeMirror-measure {\n position: absolute;\n width: 100%;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n}\n.CodeMirror-measure pre { position: static; }\n\n.CodeMirror div.CodeMirror-cursor {\n position: absolute;\n border-right: none;\n width: 0;\n}\n\ndiv.CodeMirror-cursors {\n visibility: hidden;\n position: relative;\n z-index: 3;\n}\n.CodeMirror-focused div.CodeMirror-cursors {\n visibility: visible;\n}\n\n.CodeMirror-selected { background: #d9d9d9; }\n.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }\n.CodeMirror-crosshair { cursor: crosshair; }\n\n.cm-searching {\n background: #ffa;\n background: rgba(255, 255, 0, .4);\n}\n\n/* IE7 hack to prevent it from returning funny offsetTops on the spans */\n.CodeMirror span { *vertical-align: text-bottom; }\n\n/* Used to force a border model for a node */\n.cm-force-border { padding-right: .1px; }\n\n@media print {\n /* Hide the cursor when printing */\n .CodeMirror div.CodeMirror-cursors {\n visibility: hidden;\n }\n}\n\n/* See issue #2901 */\n.cm-tab-wrap-hack:after { content: ''; }\n\n/* Help users use markselection to safely style text background */\nspan.CodeMirror-selectedtext { background: none; }\n\n/*# sourceURL=cm/codemirror.css */";Runtime.cachedResources["source_frame/cmdevtools.css"]=".CodeMirror {\n line-height: 1.2em !important;\n background-color: transparent !important;\n}\n\n.CodeMirror-linewidget {\n overflow: visible !important;\n}\n\n.CodeMirror-gutter-performance {\n width: 74px;\n background-color: white;\n margin-left: 3px;\n}\n\n.CodeMirror .source-frame-eval-expression {\n outline: 0;\n border: 1px solid rgb(163, 41, 34);\n border-left-width: 0;\n border-right-width: 0;\n background-color: rgb(255, 255, 194);\n}\n\n.CodeMirror .source-frame-eval-expression-end {\n border-right-width: 1px;\n margin-right: -1px;\n}\n\n.CodeMirror .source-frame-eval-expression-start {\n border-left-width: 1px;\n margin-left: -1px;\n}\n\n.CodeMirror-readonly .CodeMirror-cursor {\n display: none;\n}\n\n.CodeMirror .CodeMirror-gutters {\n border-right: 1px solid rgb(187, 187, 187);\n background-color: #eee;\n}\n\n.CodeMirror .CodeMirror-linenumber {\n color: rgb(128, 128, 128);\n}\n\n.CodeMirror-linenumber {\n min-width: 22px !important;\n}\n\n.cm-highlight {\n -webkit-animation: fadeout 2s 0s;\n}\n.-theme-with-dark-background .cm-highlight {\n -webkit-animation: fadeout-dark 2s 0s;\n}\n@-webkit-keyframes fadeout {\n from {background-color: rgb(255, 255, 120); }\n to { background-color: white; }\n}\n@-webkit-keyframes fadeout-dark {\n from {background-color: hsla(133, 100%, 30%, 0.5); }\n to { background-color: transparent; }\n}\n\n.cm-highlight.cm-execution-line {\n -webkit-animation: fadeout-execution-line 1s 0s;\n}\n@-webkit-keyframes fadeout-execution-line {\n from {background-color: rgb(121, 141, 254); }\n to { background-color: rgb(171, 191, 254); }\n}\n\n.cm-breakpoint .CodeMirror-linenumber {\n color: white;\n border-width: 1px 4px 1px 1px !important;\n -webkit-border-image: url(Images/breakpoint.png) 1 4 1 1;\n margin: 0 0 0 3px !important;\n padding-right: 3px;\n padding-left: 1px;\n height: 11px;\n line-height: 12px !important;\n border-style: solid;\n}\n\n.cm-line-without-source-mapping {\n background-color: #fafafa;\n}\n\n.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {\n -webkit-border-image: url(Images/breakpointConditional.png) 1 4 1 1;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.cm-breakpoint .CodeMirror-linenumber {\n -webkit-border-image: url(Images/breakpoint_2x.png) 2 8 2 2;\n}\n.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {\n -webkit-border-image: url(Images/breakpointConditional_2x.png) 2 8 2 2;\n}\n} /* media */\n\n.cm-breakpoint-disabled .CodeMirror-linenumber {\n opacity: 0.5;\n}\n\n.breakpoints-deactivated .cm-breakpoint .CodeMirror-linenumber {\n opacity: 0.5;\n}\n\n.breakpoints-deactivated .cm-breakpoint-disabled .CodeMirror-linenumber {\n opacity: 0.3;\n}\n\n.CodeMirror-matchingbracket {\n border-bottom: 1px solid black;\n color: #222 !important;\n}\n\n.CodeMirror-nonmatchingbracket {\n color: #222 !important;\n}\n\n.cm-whitespace::before {\n position: absolute;\n pointer-events: none;\n color: rgb(175, 175, 175);\n}\n\n.cm-tab {\n position: relative;\n}\n\n.cm-tab:before {\n display: none;\n content: \".\";\n color: transparent;\n border-bottom: 1px solid rgb(175, 175, 175);\n position: absolute;\n width: 90%;\n bottom: 50%;\n left: 5%;\n}\n\n.show-whitespaces .CodeMirror .cm-tab:before {\n display: block !important;\n}\n\n.cm-execution-line,\n.-theme-selection-color {\n background-color: rgb(230, 236, 255);\n outline: 1px solid rgb(64, 115, 244);\n}\n\n.cm-execution-line-tail,\n.-theme-selection-color {\n background-color: rgb(171, 191, 254);\n}\n\n.cm-execution-line .CodeMirror-linenumber,\n.-theme-selection-color {\n border-right: 1px solid rgb(64, 115, 244);\n}\n\n.cm-token-highlight {\n position: relative;\n}\n\n.cm-token-highlight:before {\n position: absolute;\n border: 1px solid gray;\n border-radius: 3px;\n top: 0;\n bottom: -1px;\n left: 0;\n right: 0;\n content: \"\";\n}\n\n.cm-line-with-selection .cm-column-with-selection:before {\n border: none;\n}\n\n.cm-search-highlight {\n position: relative;\n}\n\n.cm-search-highlight:before {\n position: absolute;\n border-top-style: solid;\n border-bottom-style: solid;\n border-top-color: gray;\n border-bottom-color: gray;\n border-top-width: 1px;\n border-bottom-width: 1px;\n top: -1px;\n bottom: 0;\n left: 0;\n right: 0;\n content: \"\";\n}\n\n.cm-search-highlight-full:before {\n border: 1px solid gray;\n border-radius: 3px;\n}\n\n.cm-search-highlight-start:before {\n border-left-width: 1px;\n border-top-left-radius: 2px;\n border-bottom-left-radius: 2px;\n border-left-style: solid;\n border-left-color: gray;\n}\n\n.cm-search-highlight-end:before {\n border-right-width: 1px;\n border-top-right-radius: 2px;\n border-bottom-right-radius: 2px;\n border-right-style: solid;\n border-right-color: gray;\n}\n\n.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-full:before {\n border-radius: 1px;\n}\n\n.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-start:before {\n border-top-left-radius: 1px;\n border-bottom-left-radius: 1px;\n}\n\n.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-end:before {\n border-top-right-radius: 1px;\n border-bottom-right-radius: 1px;\n}\n\n.cm-line-with-selection .cm-column-with-selection.cm-search-highlight:before {\n margin: -1px -1px -1px -1px;\n background-color: rgb(241, 234, 0);\n z-index: -1;\n}\n\n.-theme-with-dark-background .cm-line-with-selection .cm-column-with-selection.cm-search-highlight:before {\n background-color: hsl(133, 100%, 30%);\n}\n\n.-theme-with-dark-background .cm-line-with-selection .cm-search-highlight {\n color: #eee;\n}\n\n.CodeMirror .text-editor-line-marker-performance {\n text-align: right;\n padding-right: 3px;\n}\n\n.CodeMirror .text-editor-line-decoration {\n position: absolute;\n}\n\n.CodeMirror .text-editor-line-decoration-wave {\n position: absolute;\n top: -2px;\n cursor: pointer;\n height: 4px;\n}\n\n.CodeMirror .text-editor-value-decoration {\n position: absolute;\n bottom: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 1000px;\n opacity: 0.8;\n background-color: #FFE3C7;\n margin-left: 10px;\n padding-left: 5px;\n color: #222;\n -webkit-user-select: text;\n}\n\n.CodeMirror .cm-execution-line .text-editor-value-decoration {\n background-color: transparent;\n opacity: 0.5;\n}\n\n.text-editor-messages-description-container {\n display: inline-block;\n}\n\n.text-editor-row-message:first-child {\n border-top-width: 0;\n}\n\n.text-editor-row-message {\n border-top: 1px solid rgb(215, 215, 215);\n line-height: 1.2;\n white-space: nowrap;\n display: flex;\n}\n\n.text-editor-row-message .bubble-repeat-count {\n margin-right: 1ex;\n margin-top: -1px;\n}\n\n.CodeMirror .text-editor-line-decoration-icon {\n position: absolute;\n cursor: pointer;\n right: -16px;\n top: -9px;\n}\n\n.CodeMirror .text-editor-line-with-warning:not(.cm-execution-line) {\n background-color: rgba(241, 230, 0, 0.1);\n}\n\n.CodeMirror .text-editor-line-with-error:not(.cm-execution-line) {\n background-color: rgba(255, 0, 0, 0.05);\n}\n\n.CodeMirror .text-editor-line-decoration-wave {\n background-image: url(Images/errorWave.png);\n background-repeat: repeat-x;\n background-size: contain;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.CodeMirror .text-editor-line-decoration-wave {\n background-image: url(Images/errorWave_2x.png);\n}\n} /* media */\n\n/** @see crbug.com/358161 */\n.CodeMirror .CodeMirror-vscrollbar, .CodeMirror .CodeMirror-hscrollbar {\n transform: translateZ(0);\n}\n\n.CodeMirror .CodeMirror-activeline-background {\n background-color: transparent;\n}\n\n.cm-trailing-whitespace {\n background-color: rgba(255, 0, 0, 0.05);\n}\n\n.CodeMirror-activeline .cm-trailing-whitespace {\n background-color: transparent;\n}\n\n.-theme-with-dark-background .CodeMirror .CodeMirror-selected {\n background-color: #454545;\n}\n\n/*# sourceURL=source_frame/cmdevtools.css */";Runtime.cachedResources["source_frame/fontView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.font-view {\n font-size: 60px;\n white-space: pre-wrap;\n word-wrap: break-word;\n text-align: center;\n padding: 15px;\n}\n\n/*# sourceURL=source_frame/fontView.css */";Runtime.cachedResources["source_frame/imageView.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.image-view {\n overflow: auto;\n}\n\n.image-view > .image {\n padding: 20px 20px 10px 20px;\n text-align: center;\n}\n\n.image-view img.resource-image-view {\n max-width: 100%;\n max-height: 1000px;\n background-image: url(Images/checker.png);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5);\n -webkit-user-select: text;\n -webkit-user-drag: auto;\n}\n\n/*# sourceURL=source_frame/imageView.css */";
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.UIList=function() {WebInspector.VBox.call(this,true);this.registerRequiredCSS("sources/uiList.css");this._items=[];} WebInspector.UIList._Key=Symbol("ownerList");WebInspector.UIList.prototype={addItem:function(item,beforeItem) {item[WebInspector.UIList._Key]=this;var beforeElement=beforeItem?beforeItem.element:null;this.contentElement.insertBefore(item.element,beforeElement);var index=beforeItem?this._items.indexOf(beforeItem):this._items.length;console.assert(index>=0,"Anchor item not found in UIList");this._items.splice(index,0,item);},removeItem:function(item) {var index=this._items.indexOf(item);console.assert(index>=0);this._items.splice(index,1);item.element.remove();},clear:function() {this.contentElement.removeChildren();this._items=[];},__proto__:WebInspector.VBox.prototype} WebInspector.UIList.Item=function(title,subtitle,isLabel) {this.element=createElementWithClass("div","list-item");if(isLabel) this.element.classList.add("label");this.subtitleElement=this.element.createChild("div","subtitle");this.titleElement=this.element.createChild("div","title");this._hidden=false;this._isLabel=!!isLabel;this.setTitle(title);this.setSubtitle(subtitle);this.setSelected(false);} WebInspector.UIList.Item.prototype={nextSibling:function() {var list=this[WebInspector.UIList._Key];var index=list._items.indexOf(this);console.assert(index>=0);return list._items[index+1]||null;},title:function() {return this._title;},setTitle:function(x) {if(this._title===x) return;this._title=x;this.titleElement.textContent=x;},subtitle:function() {return this._subtitle;},setSubtitle:function(x) {if(this._subtitle===x) return;this._subtitle=x;this.subtitleElement.textContent=x;},isSelected:function() {return this._selected;},setSelected:function(x) {if(x) this.select();else this.deselect();},select:function() {if(this._selected) return;this._selected=true;this.element.classList.add("selected");},deselect:function() {if(!this._selected) return;this._selected=false;this.element.classList.remove("selected");},toggleSelected:function() {this.setSelected(!this.isSelected());},isHidden:function() {return this._hidden;},setHidden:function(x) {if(this._hidden===x) return;this._hidden=x;this.element.classList.toggle("hidden",x);},isLabel:function() {return this._isLabel;},setDimmed:function(x) {this.element.classList.toggle("dimmed",x);},discard:function() {},setHoverable:function(hoverable) {this.element.classList.toggle("ignore-hover",!hoverable);},};WebInspector.AddSourceMapURLDialog=function(callback) {WebInspector.HBox.call(this,true);this.registerRequiredCSS("sources/addSourceMapURLDialog.css");this.contentElement.createChild("label").textContent=WebInspector.UIString("Source map URL: ");this._input=this.contentElement.createChild("input");this._input.setAttribute("type","text");this._input.addEventListener("keydown",this._onKeyDown.bind(this),false);var addButton=this.contentElement.createChild("button");addButton.textContent=WebInspector.UIString("Add");addButton.addEventListener("click",this._apply.bind(this),false);this.setDefaultFocusedElement(this._input);this._callback=callback;this.contentElement.tabIndex=0;} WebInspector.AddSourceMapURLDialog.show=function(callback) {var dialog=new WebInspector.Dialog();var addSourceMapURLDialog=new WebInspector.AddSourceMapURLDialog(done);addSourceMapURLDialog.show(dialog.element);dialog.setWrapsContent(true);dialog.show();function done(value) {dialog.detach();callback(value);}} WebInspector.AddSourceMapURLDialog.prototype={_apply:function() {this._callback(this._input.value);},_onKeyDown:function(event) {if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Enter.code){event.preventDefault();this._apply();}},__proto__:WebInspector.HBox.prototype};WebInspector.CallStackSidebarPane=function() {WebInspector.SidebarPane.call(this,WebInspector.UIString("Call Stack"));this.element.addEventListener("keydown",this._keyDown.bind(this),true);this.element.tabIndex=0;this.callFrameList=new WebInspector.UIList();this.callFrameList.show(this.element);this._linkifier=new WebInspector.Linkifier();WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this._asyncStackTracesStateChanged,this);WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._blackboxingStateChanged,this);this.callFrames=[];this._locationPool=new WebInspector.LiveLocationPool();} WebInspector.CallStackSidebarPane.Events={CallFrameSelected:"CallFrameSelected",} WebInspector.CallStackSidebarPane.prototype={update:function(details) {this.callFrameList.detach();this.callFrameList.clear();this._linkifier.reset();this.element.removeChildren();this._locationPool.disposeAll();if(!details){var infoElement=this.element.createChild("div","callstack-info");infoElement.textContent=WebInspector.UIString("Not Paused");return;} this.callFrameList.show(this.element);this._debuggerModel=details.debuggerModel;var asyncStackTrace=details.asyncStackTrace;delete this._statusMessageElement;delete this._hiddenCallFramesMessageElement;this.callFrames=[];this._hiddenCallFrames=0;this._appendSidebarCallFrames(this._callFramesFromDebugger(details.callFrames));var topStackHidden=(this._hiddenCallFrames===this.callFrames.length);while(asyncStackTrace){var title=WebInspector.asyncStackTraceLabel(asyncStackTrace.description);var asyncCallFrame=new WebInspector.UIList.Item(title,"",true);asyncCallFrame.setHoverable(false);asyncCallFrame.element.addEventListener("contextmenu",this._asyncCallFrameContextMenu.bind(this,this.callFrames.length),true);this._appendSidebarCallFrames(this._callFramesFromRuntime(asyncStackTrace.callFrames,asyncCallFrame),asyncCallFrame);asyncStackTrace=asyncStackTrace.parent;} if(topStackHidden) this._revealHiddenCallFrames();if(this._hiddenCallFrames){var element=createElementWithClass("div","hidden-callframes-message");if(this._hiddenCallFrames===1) element.textContent=WebInspector.UIString("1 stack frame is hidden (black-boxed).");else element.textContent=WebInspector.UIString("%d stack frames are hidden (black-boxed).",this._hiddenCallFrames);element.createTextChild(" ");var showAllLink=element.createChild("span","link");showAllLink.textContent=WebInspector.UIString("Show");showAllLink.addEventListener("click",this._revealHiddenCallFrames.bind(this),false);this.element.insertBefore(element,this.element.firstChild);this._hiddenCallFramesMessageElement=element;}},_callFramesFromDebugger:function(callFrames) {var callFrameItems=[];for(var i=0,n=callFrames.length;i<n;++i){var callFrame=callFrames[i];var callFrameItem=new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName,callFrame.location(),this._linkifier,callFrame,this._locationPool);callFrameItem.element.addEventListener("click",this._callFrameSelected.bind(this,callFrameItem),false);callFrameItems.push(callFrameItem);} return callFrameItems;},_callFramesFromRuntime:function(callFrames,asyncCallFrameItem) {var callFrameItems=[];for(var i=0,n=callFrames.length;i<n;++i){var callFrame=callFrames[i];var lineNumber=callFrame.lineNumber?callFrame.lineNumber-1:0;var columnNumber=callFrame.columnNumber?callFrame.columnNumber-1:0;var location=new WebInspector.DebuggerModel.Location(this._debuggerModel,callFrame.scriptId,lineNumber,columnNumber);var callFrameItem=new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName,location,this._linkifier,null,this._locationPool,asyncCallFrameItem);callFrameItem.element.addEventListener("click",this._asyncCallFrameClicked.bind(this,callFrameItem),false);callFrameItems.push(callFrameItem);} return callFrameItems;},_appendSidebarCallFrames:function(callFrames,asyncCallFrameItem) {if(asyncCallFrameItem) this.callFrameList.addItem(asyncCallFrameItem);var allCallFramesHidden=true;for(var i=0,n=callFrames.length;i<n;++i){var callFrameItem=callFrames[i];callFrameItem.element.addEventListener("contextmenu",this._callFrameContextMenu.bind(this,callFrameItem),true);this.callFrames.push(callFrameItem);if(WebInspector.blackboxManager.isBlackboxedRawLocation(callFrameItem._location)){callFrameItem.setHidden(true);callFrameItem.setDimmed(true);++this._hiddenCallFrames;}else{this.callFrameList.addItem(callFrameItem);allCallFramesHidden=false;}} if(allCallFramesHidden&&asyncCallFrameItem){asyncCallFrameItem.setHidden(true);asyncCallFrameItem.element.remove();}},_revealHiddenCallFrames:function() {if(!this._hiddenCallFrames) return;this._hiddenCallFrames=0;this.callFrameList.clear();for(var i=0;i<this.callFrames.length;++i){var callFrame=this.callFrames[i];if(callFrame._asyncCallFrame){callFrame._asyncCallFrame.setHidden(false);if(i&&callFrame._asyncCallFrame!==this.callFrames[i-1]._asyncCallFrame) this.callFrameList.addItem(callFrame._asyncCallFrame);} callFrame.setHidden(false);this.callFrameList.addItem(callFrame);} if(this._hiddenCallFramesMessageElement){this._hiddenCallFramesMessageElement.remove();delete this._hiddenCallFramesMessageElement;}},_callFrameContextMenu:function(callFrame,event) {var contextMenu=new WebInspector.ContextMenu(event);var debuggerCallFrame=callFrame._debuggerCallFrame;if(debuggerCallFrame) contextMenu.appendItem(WebInspector.UIString.capitalize("Restart ^frame"),debuggerCallFrame.restart.bind(debuggerCallFrame));contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^stack ^trace"),this._copyStackTrace.bind(this));var uiLocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrame._location);this.appendBlackboxURLContextMenuItems(contextMenu,uiLocation.uiSourceCode);contextMenu.show();},_asyncCallFrameContextMenu:function(index,event) {for(;index<this.callFrames.length;++index){var callFrame=this.callFrames[index];if(!callFrame.isHidden()){this._callFrameContextMenu(callFrame,event);break;}}},appendBlackboxURLContextMenuItems:function(contextMenu,uiSourceCode) {var canBlackbox=WebInspector.blackboxManager.canBlackboxUISourceCode(uiSourceCode);var isBlackboxed=WebInspector.blackboxManager.isBlackboxedUISourceCode(uiSourceCode);var isContentScript=uiSourceCode.project().type()===WebInspector.projectTypes.ContentScripts;var manager=WebInspector.blackboxManager;if(canBlackbox){if(isBlackboxed) contextMenu.appendItem(WebInspector.UIString.capitalize("Stop ^blackboxing"),manager.unblackboxUISourceCode.bind(manager,uiSourceCode));else contextMenu.appendItem(WebInspector.UIString.capitalize("Blackbox ^script"),manager.blackboxUISourceCode.bind(manager,uiSourceCode));} if(isContentScript){if(isBlackboxed) contextMenu.appendItem(WebInspector.UIString.capitalize("Stop blackboxing ^all ^content ^scripts"),manager.blackboxContentScripts.bind(manager));else contextMenu.appendItem(WebInspector.UIString.capitalize("Blackbox ^all ^content ^scripts"),manager.unblackboxContentScripts.bind(manager));}},_blackboxingStateChanged:function() {if(!this._debuggerModel) return;var details=this._debuggerModel.debuggerPausedDetails();if(!details) return;this.update(details);var selectedCallFrame=this._debuggerModel.selectedCallFrame();if(selectedCallFrame) this.setSelectedCallFrame(selectedCallFrame);},_asyncStackTracesStateChanged:function() {var enabled=WebInspector.moduleSetting("enableAsyncStackTraces").get();if(!enabled&&this.callFrames) this._removeAsyncCallFrames();},_removeAsyncCallFrames:function() {var shouldSelectTopFrame=false;var lastSyncCallFrameIndex=-1;for(var i=0;i<this.callFrames.length;++i){var callFrame=this.callFrames[i];if(callFrame._asyncCallFrame){if(callFrame.isSelected()) shouldSelectTopFrame=true;callFrame._asyncCallFrame.element.remove();callFrame.element.remove();}else{lastSyncCallFrameIndex=i;}} this.callFrames.length=lastSyncCallFrameIndex+1;if(shouldSelectTopFrame) this._selectNextVisibleCallFrame(0);},setSelectedCallFrame:function(x) {for(var i=0;i<this.callFrames.length;++i){var callFrame=this.callFrames[i];callFrame.setSelected(callFrame._debuggerCallFrame===x);if(callFrame.isSelected()&&callFrame.isHidden()) this._revealHiddenCallFrames();}},_selectNextCallFrameOnStack:function() {var index=this._selectedCallFrameIndex();if(index===-1) return false;return this._selectNextVisibleCallFrame(index+1);},_selectPreviousCallFrameOnStack:function() {var index=this._selectedCallFrameIndex();if(index===-1) return false;return this._selectNextVisibleCallFrame(index-1,true);},_selectNextVisibleCallFrame:function(index,backward) {while(0<=index&&index<this.callFrames.length){var callFrame=this.callFrames[index];if(!callFrame.isHidden()&&!callFrame.isLabel()&&!callFrame._asyncCallFrame){this._callFrameSelected(callFrame);return true;} index+=backward?-1:1;} return false;},_selectedCallFrameIndex:function() {if(!this._debuggerModel) return-1;var selectedCallFrame=this._debuggerModel.selectedCallFrame();if(!selectedCallFrame) return-1;for(var i=0;i<this.callFrames.length;++i){if(this.callFrames[i]._debuggerCallFrame===selectedCallFrame) return i;} return-1;},_asyncCallFrameClicked:function(callFrameItem) {var uiLocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrameItem._location);WebInspector.Revealer.reveal(uiLocation);},_callFrameSelected:function(callFrameItem) {callFrameItem.element.scrollIntoViewIfNeeded();var callFrame=callFrameItem._debuggerCallFrame;if(callFrame) this.dispatchEventToListeners(WebInspector.CallStackSidebarPane.Events.CallFrameSelected,callFrame);},_copyStackTrace:function() {var text="";var lastCallFrame=null;for(var i=0;i<this.callFrames.length;++i){var callFrame=this.callFrames[i];if(callFrame.isHidden()) continue;if(lastCallFrame&&callFrame._asyncCallFrame!==lastCallFrame._asyncCallFrame) text+=callFrame._asyncCallFrame.title()+"\n";text+=callFrame.title()+" ("+callFrame.subtitle()+")\n";lastCallFrame=callFrame;} InspectorFrontendHost.copyText(text);},registerShortcuts:function(registerShortcutDelegate) {registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame,this._selectNextCallFrameOnStack.bind(this));registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame,this._selectPreviousCallFrameOnStack.bind(this));},setStatus:function(status) {if(!this._statusMessageElement) this._statusMessageElement=this.element.createChild("div","callstack-info status");if(typeof status==="string"){this._statusMessageElement.textContent=status;}else{this._statusMessageElement.removeChildren();this._statusMessageElement.appendChild(status);}},_keyDown:function(event) {if(event.altKey||event.shiftKey||event.metaKey||event.ctrlKey) return;if(event.keyIdentifier==="Up"&&this._selectPreviousCallFrameOnStack()||event.keyIdentifier==="Down"&&this._selectNextCallFrameOnStack()) event.consume(true);},__proto__:WebInspector.SidebarPane.prototype} WebInspector.CallStackSidebarPane.CallFrame=function(functionName,location,linkifier,debuggerCallFrame,locationPool,asyncCallFrame) {WebInspector.UIList.Item.call(this,WebInspector.beautifyFunctionName(functionName),"");this._location=location;this._debuggerCallFrame=debuggerCallFrame;this._asyncCallFrame=asyncCallFrame;if(asyncCallFrame){var locationElement=linkifier.linkifyRawLocation(location,location.script().sourceURL);this.subtitleElement.appendChild(locationElement);}else{this._liveLocationPool=new WebInspector.LiveLocationPool();WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(location,this._update.bind(this),locationPool);}} WebInspector.CallStackSidebarPane.CallFrame.prototype={_update:function(liveLocation) {var uiLocation=liveLocation.uiLocation();if(!uiLocation) return;var text=uiLocation.linkText();this.setSubtitle(text.trimMiddle(30));this.subtitleElement.title=text;},__proto__:WebInspector.UIList.Item.prototype};WebInspector.HistoryEntry=function(){} WebInspector.HistoryEntry.prototype={valid:function(){},reveal:function(){}};WebInspector.SimpleHistoryManager=function(historyDepth) {this._entries=[];this._activeEntryIndex=-1;this._coalescingReadonly=0;this._historyDepth=historyDepth;} WebInspector.SimpleHistoryManager.prototype={readOnlyLock:function() {++this._coalescingReadonly;},releaseReadOnlyLock:function() {--this._coalescingReadonly;},readOnly:function() {return!!this._coalescingReadonly;},filterOut:function(filterOutCallback) {if(this.readOnly()) return;var filteredEntries=[];var removedBeforeActiveEntry=0;for(var i=0;i<this._entries.length;++i){if(!filterOutCallback(this._entries[i])){filteredEntries.push(this._entries[i]);}else if(i<=this._activeEntryIndex) ++removedBeforeActiveEntry;} this._entries=filteredEntries;this._activeEntryIndex=Math.max(0,this._activeEntryIndex-removedBeforeActiveEntry);},empty:function() {return!this._entries.length;},active:function() {return this.empty()?null:this._entries[this._activeEntryIndex];},push:function(entry) {if(this.readOnly()) return;if(!this.empty()) this._entries.splice(this._activeEntryIndex+1);this._entries.push(entry);if(this._entries.length>this._historyDepth) this._entries.shift();this._activeEntryIndex=this._entries.length-1;},rollback:function() {if(this.empty()) return false;var revealIndex=this._activeEntryIndex-1;while(revealIndex>=0&&!this._entries[revealIndex].valid()) --revealIndex;if(revealIndex<0) return false;this.readOnlyLock();this._entries[revealIndex].reveal();this.releaseReadOnlyLock();this._activeEntryIndex=revealIndex;return true;},rollover:function() {var revealIndex=this._activeEntryIndex+1;while(revealIndex<this._entries.length&&!this._entries[revealIndex].valid()) ++revealIndex;if(revealIndex>=this._entries.length) return false;this.readOnlyLock();this._entries[revealIndex].reveal();this.releaseReadOnlyLock();this._activeEntryIndex=revealIndex;return true;},};;WebInspector.EditingLocationHistoryManager=function(sourcesView,currentSourceFrameCallback) {this._sourcesView=sourcesView;this._historyManager=new WebInspector.SimpleHistoryManager(WebInspector.EditingLocationHistoryManager.HistoryDepth);this._currentSourceFrameCallback=currentSourceFrameCallback;} WebInspector.EditingLocationHistoryManager.HistoryDepth=20;WebInspector.EditingLocationHistoryManager.prototype={trackSourceFrameCursorJumps:function(sourceFrame) {sourceFrame.addEventListener(WebInspector.SourceFrame.Events.JumpHappened,this._onJumpHappened.bind(this));},_onJumpHappened:function(event) {if(event.data.from) this._updateActiveState(event.data.from);if(event.data.to) this._pushActiveState(event.data.to);},rollback:function() {this._historyManager.rollback();},rollover:function() {this._historyManager.rollover();},updateCurrentState:function() {var sourceFrame=this._currentSourceFrameCallback();if(!sourceFrame) return;this._updateActiveState(sourceFrame.textEditor.selection());},pushNewState:function() {var sourceFrame=this._currentSourceFrameCallback();if(!sourceFrame) return;this._pushActiveState(sourceFrame.textEditor.selection());},_updateActiveState:function(selection) {var active=this._historyManager.active();if(!active) return;var sourceFrame=this._currentSourceFrameCallback();if(!sourceFrame) return;var entry=new WebInspector.EditingLocationHistoryEntry(this._sourcesView,this,sourceFrame,selection);active.merge(entry);},_pushActiveState:function(selection) {var sourceFrame=this._currentSourceFrameCallback();if(!sourceFrame) return;var entry=new WebInspector.EditingLocationHistoryEntry(this._sourcesView,this,sourceFrame,selection);this._historyManager.push(entry);},removeHistoryForSourceCode:function(uiSourceCode) {function filterOut(entry) {return entry._projectId===uiSourceCode.project().id()&&entry._url===uiSourceCode.url();} this._historyManager.filterOut(filterOut);},} WebInspector.EditingLocationHistoryEntry=function(sourcesView,editingLocationManager,sourceFrame,selection) {this._sourcesView=sourcesView;this._editingLocationManager=editingLocationManager;var uiSourceCode=sourceFrame.uiSourceCode();this._projectId=uiSourceCode.project().id();this._url=uiSourceCode.url();var position=this._positionFromSelection(selection);this._positionHandle=sourceFrame.textEditor.textEditorPositionHandle(position.lineNumber,position.columnNumber);} WebInspector.EditingLocationHistoryEntry.prototype={merge:function(entry) {if(this._projectId!==entry._projectId||this._url!==entry._url) return;this._positionHandle=entry._positionHandle;},_positionFromSelection:function(selection) {return{lineNumber:selection.endLine,columnNumber:selection.endColumn};},valid:function() {var position=this._positionHandle.resolve();var uiSourceCode=WebInspector.workspace.uiSourceCode(this._projectId,this._url);return!!(position&&uiSourceCode);},reveal:function() {var position=this._positionHandle.resolve();var uiSourceCode=WebInspector.workspace.uiSourceCode(this._projectId,this._url);if(!position||!uiSourceCode) return;this._editingLocationManager.updateCurrentState();this._sourcesView.showSourceLocation(uiSourceCode,position.lineNumber,position.columnNumber);}};WebInspector.EventListenerBreakpointsSidebarPane=function() {WebInspector.SidebarPane.call(this,WebInspector.UIString("Event Listener Breakpoints"));this.registerRequiredCSS("components/breakpointsList.css");this._eventListenerBreakpointsSetting=WebInspector.settings.createLocalSetting("eventListenerBreakpoints",[]);this._categoriesTreeOutline=new TreeOutline();this._categoriesTreeOutline.element.tabIndex=0;this._categoriesTreeOutline.element.classList.add("event-listener-breakpoints");this.element.appendChild(this._categoriesTreeOutline.element);this._categoryItems=[];this._createCategory(WebInspector.UIString("Animation"),["requestAnimationFrame","cancelAnimationFrame","animationFrameFired"],true);this._createCategory(WebInspector.UIString("Clipboard"),["copy","cut","paste","beforecopy","beforecut","beforepaste"]);this._createCategory(WebInspector.UIString("Control"),["resize","scroll","zoom","focus","blur","select","change","submit","reset"]);this._createCategory(WebInspector.UIString("Device"),["deviceorientation","devicemotion"]);this._createCategory(WebInspector.UIString("DOM Mutation"),["DOMActivate","DOMFocusIn","DOMFocusOut","DOMAttrModified","DOMCharacterDataModified","DOMNodeInserted","DOMNodeInsertedIntoDocument","DOMNodeRemoved","DOMNodeRemovedFromDocument","DOMSubtreeModified","DOMContentLoaded"]);this._createCategory(WebInspector.UIString("Drag / drop"),["dragenter","dragover","dragleave","drop"]);this._createCategory(WebInspector.UIString("Keyboard"),["keydown","keyup","keypress","input"]);this._createCategory(WebInspector.UIString("Load"),["load","beforeunload","unload","abort","error","hashchange","popstate"]);this._createCategory(WebInspector.UIString("Media"),["play","pause","playing","canplay","canplaythrough","seeking","seeked","timeupdate","ended","ratechange","durationchange","volumechange","loadstart","progress","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","waiting"],false,["audio","video"]);this._createCategory(WebInspector.UIString("Mouse"),["click","dblclick","mousedown","mouseup","mouseover","mousemove","mouseout","mouseenter","mouseleave","mousewheel","wheel","contextmenu"]);this._createCategory(WebInspector.UIString("Parse"),["setInnerHTML"],true);this._createCategory(WebInspector.UIString("Pointer"),["pointerover","pointerout","pointerenter","pointerleave","pointerdown","pointerup","pointermove","pointercancel","gotpointercapture","lostpointercapture"]);this._createCategory(WebInspector.UIString("Script"),["scriptFirstStatement"],true);this._createCategory(WebInspector.UIString("Timer"),["setTimer","clearTimer","timerFired"],true);this._createCategory(WebInspector.UIString("Touch"),["touchstart","touchmove","touchend","touchcancel"]);this._createCategory(WebInspector.UIString("WebGL"),["webglErrorFired","webglWarningFired"],true);this._createCategory(WebInspector.UIString("Window"),["close"],true);this._createCategory(WebInspector.UIString("XHR"),["readystatechange","load","loadstart","loadend","abort","error","progress","timeout"],false,["XMLHttpRequest","XMLHttpRequestUpload"]);WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);} WebInspector.EventListenerBreakpointsSidebarPane.categoryListener="listener:";WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation="instrumentation:";WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny="*";WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI=function(eventName,auxData) {if(!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI){WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI={"instrumentation:setTimer":WebInspector.UIString("Set Timer"),"instrumentation:clearTimer":WebInspector.UIString("Clear Timer"),"instrumentation:timerFired":WebInspector.UIString("Timer Fired"),"instrumentation:scriptFirstStatement":WebInspector.UIString("Script First Statement"),"instrumentation:requestAnimationFrame":WebInspector.UIString("Request Animation Frame"),"instrumentation:cancelAnimationFrame":WebInspector.UIString("Cancel Animation Frame"),"instrumentation:animationFrameFired":WebInspector.UIString("Animation Frame Fired"),"instrumentation:webglErrorFired":WebInspector.UIString("WebGL Error Fired"),"instrumentation:webglWarningFired":WebInspector.UIString("WebGL Warning Fired"),"instrumentation:setInnerHTML":WebInspector.UIString("Set innerHTML"),};} if(auxData){if(eventName==="instrumentation:webglErrorFired"&&auxData["webglErrorName"]){var errorName=auxData["webglErrorName"];errorName=errorName.replace(/^.*(0x[0-9a-f]+).*$/i,"$1");return WebInspector.UIString("WebGL Error Fired (%s)",errorName);}} return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eventName]||eventName.substring(eventName.indexOf(":")+1);} WebInspector.EventListenerBreakpointsSidebarPane.prototype={targetAdded:function(target) {this._restoreBreakpoints(target);},targetRemoved:function(target){},_createCategory:function(name,eventNames,isInstrumentationEvent,targetNames) {var labelNode=createCheckboxLabel(name);var categoryItem={};categoryItem.element=new TreeElement(labelNode);this._categoriesTreeOutline.appendChild(categoryItem.element);categoryItem.element.listItemElement.classList.add("event-category");categoryItem.element.selectable=true;categoryItem.checkbox=labelNode.checkboxElement;categoryItem.checkbox.addEventListener("click",this._categoryCheckboxClicked.bind(this,categoryItem),true);categoryItem.targetNames=this._stringArrayToLowerCase(targetNames||[WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny]);categoryItem.children={};var category=(isInstrumentationEvent?WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation:WebInspector.EventListenerBreakpointsSidebarPane.categoryListener);for(var i=0;i<eventNames.length;++i){var eventName=category+eventNames[i];var breakpointItem={};var title=WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);labelNode=createCheckboxLabel(title);labelNode.classList.add("source-code");breakpointItem.element=new TreeElement(labelNode);categoryItem.element.appendChild(breakpointItem.element);breakpointItem.element.listItemElement.createChild("div","breakpoint-hit-marker");breakpointItem.element.selectable=false;breakpointItem.checkbox=labelNode.checkboxElement;breakpointItem.checkbox.addEventListener("click",this._breakpointCheckboxClicked.bind(this,eventName,categoryItem.targetNames),true);breakpointItem.parent=categoryItem;categoryItem.children[eventName]=breakpointItem;} this._categoryItems.push(categoryItem);},_stringArrayToLowerCase:function(array) {return array.map(function(value){return value.toLowerCase();});},_categoryCheckboxClicked:function(categoryItem) {var checked=categoryItem.checkbox.checked;for(var eventName in categoryItem.children){var breakpointItem=categoryItem.children[eventName];if(breakpointItem.checkbox.checked===checked) continue;if(checked) this._setBreakpoint(eventName,categoryItem.targetNames);else this._removeBreakpoint(eventName,categoryItem.targetNames);} this._saveBreakpoints();},_breakpointCheckboxClicked:function(eventName,targetNames,event) {if(event.target.checked) this._setBreakpoint(eventName,targetNames);else this._removeBreakpoint(eventName,targetNames);this._saveBreakpoints();},_setBreakpoint:function(eventName,eventTargetNames,target) {eventTargetNames=eventTargetNames||[WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];for(var i=0;i<eventTargetNames.length;++i){var eventTargetName=eventTargetNames[i];var breakpointItem=this._findBreakpointItem(eventName,eventTargetName);if(!breakpointItem) continue;breakpointItem.checkbox.checked=true;breakpointItem.parent.dirtyCheckbox=true;this._updateBreakpointOnTarget(eventName,eventTargetName,true,target);} this._updateCategoryCheckboxes();},_removeBreakpoint:function(eventName,eventTargetNames,target) {eventTargetNames=eventTargetNames||[WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];for(var i=0;i<eventTargetNames.length;++i){var eventTargetName=eventTargetNames[i];var breakpointItem=this._findBreakpointItem(eventName,eventTargetName);if(!breakpointItem) continue;breakpointItem.checkbox.checked=false;breakpointItem.parent.dirtyCheckbox=true;this._updateBreakpointOnTarget(eventName,eventTargetName,false,target);} this._updateCategoryCheckboxes();},_updateBreakpointOnTarget:function(eventName,eventTargetName,enable,target) {var targets=target?[target]:WebInspector.targetManager.targets(WebInspector.Target.Type.Page);for(var i=0;i<targets.length;++i){if(eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener)){var protocolEventName=eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener.length);if(enable) targets[i].domdebuggerAgent().setEventListenerBreakpoint(protocolEventName,eventTargetName);else targets[i].domdebuggerAgent().removeEventListenerBreakpoint(protocolEventName,eventTargetName);}else if(eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation)){var protocolEventName=eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation.length);if(enable) targets[i].domdebuggerAgent().setInstrumentationBreakpoint(protocolEventName);else targets[i].domdebuggerAgent().removeInstrumentationBreakpoint(protocolEventName);}}},_updateCategoryCheckboxes:function() {for(var i=0;i<this._categoryItems.length;++i){var categoryItem=this._categoryItems[i];if(!categoryItem.dirtyCheckbox) continue;categoryItem.dirtyCheckbox=false;var hasEnabled=false;var hasDisabled=false;for(var eventName in categoryItem.children){var breakpointItem=categoryItem.children[eventName];if(breakpointItem.checkbox.checked) hasEnabled=true;else hasDisabled=true;} categoryItem.checkbox.checked=hasEnabled;categoryItem.checkbox.indeterminate=hasEnabled&&hasDisabled;}},_findBreakpointItem:function(eventName,targetName) {targetName=(targetName||WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny).toLowerCase();for(var i=0;i<this._categoryItems.length;++i){var categoryItem=this._categoryItems[i];if(categoryItem.targetNames.indexOf(targetName)===-1) continue;var breakpointItem=categoryItem.children[eventName];if(breakpointItem) return breakpointItem;} return null;},highlightBreakpoint:function(eventName,targetName) {var breakpointItem=this._findBreakpointItem(eventName,targetName);if(!breakpointItem||!breakpointItem.checkbox.checked) breakpointItem=this._findBreakpointItem(eventName,WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny);if(!breakpointItem) return;this.expand();breakpointItem.parent.element.expand();breakpointItem.element.listItemElement.classList.add("breakpoint-hit");this._highlightedElement=breakpointItem.element.listItemElement;},clearBreakpointHighlight:function() {if(this._highlightedElement){this._highlightedElement.classList.remove("breakpoint-hit");delete this._highlightedElement;}},_saveBreakpoints:function() {var breakpoints=[];for(var i=0;i<this._categoryItems.length;++i){var categoryItem=this._categoryItems[i];for(var eventName in categoryItem.children){var breakpointItem=categoryItem.children[eventName];if(breakpointItem.checkbox.checked) breakpoints.push({eventName:eventName,targetNames:categoryItem.targetNames});}} this._eventListenerBreakpointsSetting.set(breakpoints);},_restoreBreakpoints:function(target) {var breakpoints=this._eventListenerBreakpointsSetting.get();for(var i=0;i<breakpoints.length;++i){var breakpoint=breakpoints[i];if(breakpoint&&typeof breakpoint.eventName==="string") this._setBreakpoint(breakpoint.eventName,breakpoint.targetNames,target);}},__proto__:WebInspector.SidebarPane.prototype};WebInspector.FilePathScoreFunction=function(query) {this._query=query;this._queryUpperCase=query.toUpperCase();this._score=null;this._sequence=null;this._dataUpperCase="";this._fileNameIndex=0;} WebInspector.FilePathScoreFunction.prototype={score:function(data,matchIndexes) {if(!data||!this._query) return 0;var n=this._query.length;var m=data.length;if(!this._score||this._score.length<n*m){this._score=new Int32Array(n*m*2);this._sequence=new Int32Array(n*m*2);} var score=this._score;var sequence=(this._sequence);this._dataUpperCase=data.toUpperCase();this._fileNameIndex=data.lastIndexOf("/");for(var i=0;i<n;++i){for(var j=0;j<m;++j){var skipCharScore=j===0?0:score[i*m+j-1];var prevCharScore=i===0||j===0?0:score[(i-1)*m+j-1];var consecutiveMatch=i===0||j===0?0:sequence[(i-1)*m+j-1];var pickCharScore=this._match(this._query,data,i,j,consecutiveMatch);if(pickCharScore&&prevCharScore+pickCharScore>=skipCharScore){sequence[i*m+j]=consecutiveMatch+1;score[i*m+j]=(prevCharScore+pickCharScore);}else{sequence[i*m+j]=0;score[i*m+j]=skipCharScore;}}} if(matchIndexes) this._restoreMatchIndexes(sequence,n,m,matchIndexes);return score[n*m-1];},_testWordStart:function(data,j) {var prevChar=data.charAt(j-1);return j===0||prevChar==="_"||prevChar==="-"||prevChar==="/"||(data[j-1]!==this._dataUpperCase[j-1]&&data[j]===this._dataUpperCase[j]);},_restoreMatchIndexes:function(sequence,n,m,out) {var i=n-1,j=m-1;while(i>=0&&j>=0){switch(sequence[i*m+j]){case 0:--j;break;default:out.push(j);--i;--j;break;}} out.reverse();},_singleCharScore:function(query,data,i,j) {var isWordStart=this._testWordStart(data,j);var isFileName=j>this._fileNameIndex;var isPathTokenStart=j===0||data[j-1]==="/";var isCapsMatch=query[i]===data[j]&&query[i]==this._queryUpperCase[i];var score=10;if(isPathTokenStart) score+=4;if(isWordStart) score+=2;if(isCapsMatch) score+=6;if(isFileName) score+=4;if(j===this._fileNameIndex+1&&i===0) score+=5;if(isFileName&&isWordStart) score+=3;return score;},_sequenceCharScore:function(query,data,i,j,sequenceLength) {var isFileName=j>this._fileNameIndex;var isPathTokenStart=j===0||data[j-1]==="/";var score=10;if(isFileName) score+=4;if(isPathTokenStart) score+=5;score+=sequenceLength*4;return score;},_match:function(query,data,i,j,consecutiveMatch) {if(this._queryUpperCase[i]!==this._dataUpperCase[j]) return 0;if(!consecutiveMatch) return this._singleCharScore(query,data,i,j);else return this._sequenceCharScore(query,data,i,j-consecutiveMatch,consecutiveMatch);}};WebInspector.FilteredUISourceCodeListDelegate=function(defaultScores,history) {WebInspector.FilteredListWidget.Delegate.call(this,history||[]);this._populate();this._defaultScores=defaultScores;this._scorer=new WebInspector.FilePathScoreFunction("");WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);} WebInspector.FilteredUISourceCodeListDelegate.prototype={_projectRemoved:function(event) {var project=(event.data);this._populate(project);this.refresh();},_populate:function(skipProject) {this._uiSourceCodes=[];var projects=WebInspector.workspace.projects().filter(this.filterProject.bind(this));for(var i=0;i<projects.length;++i){if(skipProject&&projects[i]===skipProject) continue;this._uiSourceCodes=this._uiSourceCodes.concat(projects[i].uiSourceCodes());}},uiSourceCodeSelected:function(uiSourceCode,lineNumber,columnNumber) {},filterProject:function(project) {return true;},itemCount:function() {return this._uiSourceCodes.length;},itemKeyAt:function(itemIndex) {return this._uiSourceCodes[itemIndex].url();},itemScoreAt:function(itemIndex,query) {var uiSourceCode=this._uiSourceCodes[itemIndex];var score=this._defaultScores?(this._defaultScores.get(uiSourceCode)||0):0;if(!query||query.length<2) return score;if(this._query!==query){this._query=query;this._scorer=new WebInspector.FilePathScoreFunction(query);} var url=uiSourceCode.url();return score+10*this._scorer.score(url,null);},renderItem:function(itemIndex,query,titleElement,subtitleElement) {query=this.rewriteQuery(query);var uiSourceCode=this._uiSourceCodes[itemIndex];var fullDisplayName=uiSourceCode.fullDisplayName();var indexes=[];var score=new WebInspector.FilePathScoreFunction(query).score(fullDisplayName,indexes);var fileNameIndex=fullDisplayName.lastIndexOf("/");titleElement.textContent=uiSourceCode.displayName()+(this._queryLineNumberAndColumnNumber||"");this._renderSubtitleElement(subtitleElement,fullDisplayName);subtitleElement.title=fullDisplayName;var ranges=[];for(var i=0;i<indexes.length;++i) ranges.push({offset:indexes[i],length:1});if(indexes[0]>fileNameIndex){for(var i=0;i<ranges.length;++i) ranges[i].offset-=fileNameIndex+1;WebInspector.highlightRangesWithStyleClass(titleElement,ranges,"highlight");}else{WebInspector.highlightRangesWithStyleClass(subtitleElement,ranges,"highlight");}},_renderSubtitleElement:function(element,text) {element.removeChildren();var splitPosition=text.lastIndexOf("/");if(text.length>55) splitPosition=text.length-55;var first=element.createChild("div","first-part");first.textContent=text.substring(0,splitPosition);var second=element.createChild("div","second-part");second.textContent=text.substring(splitPosition);element.title=text;},selectItem:function(itemIndex,promptValue) {var parsedExpression=promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);if(!parsedExpression) return;var lineNumber;var columnNumber;if(parsedExpression[2]) lineNumber=parseInt(parsedExpression[2].substr(1),10)-1;if(parsedExpression[3]) columnNumber=parseInt(parsedExpression[3].substr(1),10)-1;var uiSourceCode=itemIndex!==null?this._uiSourceCodes[itemIndex]:null;this.uiSourceCodeSelected(uiSourceCode,lineNumber,columnNumber);},rewriteQuery:function(query) {if(!query) return query;query=query.trim();var lineNumberMatch=query.match(/^([^:]+)((?::[^:]*){0,2})$/);this._queryLineNumberAndColumnNumber=lineNumberMatch?lineNumberMatch[2]:"";return lineNumberMatch?lineNumberMatch[1]:query;},_uiSourceCodeAdded:function(event) {var uiSourceCode=(event.data);if(!this.filterProject(uiSourceCode.project())) return;this._uiSourceCodes.push(uiSourceCode);this.refresh();},dispose:function() {WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);},__proto__:WebInspector.FilteredListWidget.Delegate.prototype};WebInspector.UISourceCodeFrame=function(uiSourceCode) {this._uiSourceCode=uiSourceCode;WebInspector.SourceFrame.call(this,uiSourceCode.contentURL(),workingCopy);if(Runtime.experiments.isEnabled("sourceDiff")) this._diff=new WebInspector.SourceCodeDiff(uiSourceCode,this.textEditor);this.textEditor.setAutocompleteDelegate(new WebInspector.SimpleAutocompleteDelegate());this._rowMessageBuckets={};this._typeDecorationsPending=new Set();this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._onWorkingCopyChanged,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._onWorkingCopyCommitted,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.MessageAdded,this._onMessageAdded,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.MessageRemoved,this._onMessageRemoved,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDecorationAdded,this._onLineDecorationAdded,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDecorationRemoved,this._onLineDecorationRemoved,this);this._updateStyle();this._errorPopoverHelper=new WebInspector.PopoverHelper(this.element,this._getErrorAnchor.bind(this),this._showErrorPopover.bind(this));this._errorPopoverHelper.setTimeout(100,100);function workingCopy() {if(uiSourceCode.isDirty()) return(Promise.resolve(uiSourceCode.workingCopy()));return uiSourceCode.requestContent();}} WebInspector.UISourceCodeFrame.prototype={uiSourceCode:function() {return this._uiSourceCode;},wasShown:function() {WebInspector.SourceFrame.prototype.wasShown.call(this);this._boundWindowFocused=this._windowFocused.bind(this);this.element.ownerDocument.defaultView.addEventListener("focus",this._boundWindowFocused,false);this._checkContentUpdated();setImmediate(this._updateBucketDecorations.bind(this));},willHide:function() {WebInspector.SourceFrame.prototype.willHide.call(this);this.element.ownerDocument.defaultView.removeEventListener("focus",this._boundWindowFocused,false);delete this._boundWindowFocused;this._uiSourceCode.removeWorkingCopyGetter();},canEditSource:function() {var projectType=this._uiSourceCode.project().type();if(projectType===WebInspector.projectTypes.Service||projectType===WebInspector.projectTypes.Debugger||projectType===WebInspector.projectTypes.Formatter) return false;if(projectType===WebInspector.projectTypes.Network&&this._uiSourceCode.contentType()===WebInspector.resourceTypes.Document) return false;return true;},_windowFocused:function(event) {this._checkContentUpdated();},_checkContentUpdated:function() {if(!this.loaded||!this.isShowing()) return;this._uiSourceCode.checkContentUpdated(true);},commitEditing:function() {if(!this._uiSourceCode.isDirty()) return;this._muteSourceCodeEvents=true;this._uiSourceCode.commitWorkingCopy();delete this._muteSourceCodeEvents;},onTextEditorContentLoaded:function() {WebInspector.SourceFrame.prototype.onTextEditorContentLoaded.call(this);for(var message of this._uiSourceCode.messages()) this._addMessageToSource(message);this._decorateAllTypes();},onTextChanged:function(oldRange,newRange) {WebInspector.SourceFrame.prototype.onTextChanged.call(this,oldRange,newRange);this._clearMessages();if(this._isSettingContent) return;this._muteSourceCodeEvents=true;if(this._textEditor.isClean()) this._uiSourceCode.resetWorkingCopy();else this._uiSourceCode.setWorkingCopyGetter(this._textEditor.text.bind(this._textEditor));delete this._muteSourceCodeEvents;},_onWorkingCopyChanged:function(event) {if(this._diff) this._diff.updateDiffMarkersWhenPossible();if(this._muteSourceCodeEvents) return;this._innerSetContent(this._uiSourceCode.workingCopy());this.onUISourceCodeContentChanged();},_onWorkingCopyCommitted:function(event) {if(!this._muteSourceCodeEvents){this._innerSetContent(this._uiSourceCode.workingCopy());this.onUISourceCodeContentChanged();} this._textEditor.markClean();this._updateStyle();if(this._diff) this._diff.updateDiffMarkersWhenPossible();},_updateStyle:function() {this.element.classList.toggle("source-frame-unsaved-committed-changes",this._uiSourceCode.hasUnsavedCommittedChanges());},onUISourceCodeContentChanged:function() {},_innerSetContent:function(content) {this._isSettingContent=true;if(this._diff){var oldContent=this._textEditor.text();this.setContent(content);this._diff.updateDiffMarkersImmediately();this._diff.highlightModifiedLines(oldContent,content);}else{this.setContent(content);} delete this._isSettingContent;},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber) {function appendItems() {contextMenu.appendApplicableItems(this._uiSourceCode);contextMenu.appendApplicableItems(new WebInspector.UILocation(this._uiSourceCode,lineNumber,columnNumber));contextMenu.appendSeparator();} return WebInspector.SourceFrame.prototype.populateTextAreaContextMenu.call(this,contextMenu,lineNumber,columnNumber).then(appendItems.bind(this));},attachInfobars:function(infobars) {for(var i=infobars.length-1;i>=0;--i){var infobar=infobars[i];if(!infobar) continue;this.element.insertBefore(infobar.element,this.element.children[0]);infobar.setParentView(this);} this.doResize();},dispose:function() {this._textEditor.dispose();this.detach();},_onMessageAdded:function(event) {if(!this.loaded) return;var message=(event.data);this._addMessageToSource(message);},_addMessageToSource:function(message) {var lineNumber=message.lineNumber();if(lineNumber>=this._textEditor.linesCount) lineNumber=this._textEditor.linesCount-1;if(lineNumber<0) lineNumber=0;if(!this._rowMessageBuckets[lineNumber]) this._rowMessageBuckets[lineNumber]=new WebInspector.UISourceCodeFrame.RowMessageBucket(this,this._textEditor,lineNumber);var messageBucket=this._rowMessageBuckets[lineNumber];messageBucket.addMessage(message);},_onMessageRemoved:function(event) {if(!this.loaded) return;var message=(event.data);this._removeMessageFromSource(message);},_removeMessageFromSource:function(message) {var lineNumber=message.lineNumber();if(lineNumber>=this._textEditor.linesCount) lineNumber=this._textEditor.linesCount-1;if(lineNumber<0) lineNumber=0;var messageBucket=this._rowMessageBuckets[lineNumber];if(!messageBucket) return;messageBucket.removeMessage(message);if(!messageBucket.uniqueMessagesCount()){messageBucket.detachFromEditor();delete this._rowMessageBuckets[lineNumber];}},_clearMessages:function() {for(var line in this._rowMessageBuckets){var bubble=this._rowMessageBuckets[line];bubble.detachFromEditor();} this._rowMessageBuckets={};this._errorPopoverHelper.hidePopover();this._uiSourceCode.removeAllMessages();},_getErrorAnchor:function(target,event) {var element=target.enclosingNodeOrSelfWithClass("text-editor-line-decoration-icon")||target.enclosingNodeOrSelfWithClass("text-editor-line-decoration-wave");if(!element) return;this._errorWavePopoverAnchor=new AnchorBox(event.clientX,event.clientY,1,1);return element;},_showErrorPopover:function(anchor,popover) {var messageBucket=anchor.enclosingNodeOrSelfWithClass("text-editor-line-decoration")._messageBucket;var messagesOutline=messageBucket.messagesDescription();var popoverAnchor=anchor.enclosingNodeOrSelfWithClass("text-editor-line-decoration-icon")?anchor:this._errorWavePopoverAnchor;popover.showForAnchor(messagesOutline,popoverAnchor);},_updateBucketDecorations:function() {for(var line in this._rowMessageBuckets){var bucket=this._rowMessageBuckets[line];bucket._updateDecoration();}},_onLineDecorationAdded:function(event) {var marker=(event.data);this._decorateTypeThrottled(marker.type());},_onLineDecorationRemoved:function(event) {var marker=(event.data);this._decorateTypeThrottled(marker.type());},_decorateTypeThrottled:function(type) {if(this._typeDecorationsPending.has(type)) return;this._typeDecorationsPending.add(type);self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator).find(extension=>extension.descriptor()["decoratorType"]===type).instancePromise().then(decorator=>{this._typeDecorationsPending.delete(type);decorator.decorate(this.uiSourceCode(),this._textEditor);});},_decorateAllTypes:function() {var extensions=self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator);extensions.forEach(extension=>this._decorateTypeThrottled(extension.descriptor()["decoratorType"]));},__proto__:WebInspector.SourceFrame.prototype} WebInspector.UISourceCodeFrame._iconClassPerLevel={};WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Message.Level.Error]="error-icon";WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Message.Level.Warning]="warning-icon";WebInspector.UISourceCodeFrame._lineClassPerLevel={};WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Message.Level.Error]="text-editor-line-with-error";WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Message.Level.Warning]="text-editor-line-with-warning";WebInspector.UISourceCodeFrame.LineDecorator=function(){} WebInspector.UISourceCodeFrame.LineDecorator.prototype={decorate:function(uiSourceCode,textEditor){}} WebInspector.UISourceCodeFrame.RowMessage=function(message) {this._message=message;this._repeatCount=1;this.element=createElementWithClass("div","text-editor-row-message");this._icon=this.element.createChild("label","","dt-icon-label");this._icon.type=WebInspector.UISourceCodeFrame._iconClassPerLevel[message.level()];this._repeatCountElement=this.element.createChild("span","bubble-repeat-count hidden error");var linesContainer=this.element.createChild("div","text-editor-row-message-lines");var lines=this._message.text().split("\n");for(var i=0;i<lines.length;++i){var messageLine=linesContainer.createChild("div");messageLine.textContent=lines[i];}} WebInspector.UISourceCodeFrame.RowMessage.prototype={message:function() {return this._message;},repeatCount:function() {return this._repeatCount;},setRepeatCount:function(repeatCount) {if(this._repeatCount===repeatCount) return;this._repeatCount=repeatCount;this._updateMessageRepeatCount();},_updateMessageRepeatCount:function() {this._repeatCountElement.textContent=this._repeatCount;var showRepeatCount=this._repeatCount>1;this._repeatCountElement.classList.toggle("hidden",!showRepeatCount);this._icon.classList.toggle("hidden",showRepeatCount);}} WebInspector.UISourceCodeFrame.RowMessageBucket=function(sourceFrame,textEditor,lineNumber) {this._sourceFrame=sourceFrame;this._textEditor=textEditor;this._lineHandle=textEditor.textEditorPositionHandle(lineNumber,0);this._decoration=createElementWithClass("div","text-editor-line-decoration");this._decoration._messageBucket=this;this._wave=this._decoration.createChild("div","text-editor-line-decoration-wave");this._icon=this._wave.createChild("label","text-editor-line-decoration-icon","dt-icon-label");this._textEditor.addDecoration(lineNumber,this._decoration);this._messagesDescriptionElement=createElementWithClass("div","text-editor-messages-description-container");this._messages=[];this._level=null;} WebInspector.UISourceCodeFrame.RowMessageBucket.prototype={_updateWavePosition:function(lineNumber,columnNumber) {lineNumber=Math.min(lineNumber,this._textEditor.linesCount-1);var lineText=this._textEditor.line(lineNumber);columnNumber=Math.min(columnNumber,lineText.length);var lineIndent=WebInspector.TextUtils.lineIndent(lineText).length;var base=this._textEditor.cursorPositionToCoordinates(lineNumber,0);var start=this._textEditor.cursorPositionToCoordinates(lineNumber,Math.max(columnNumber-1,lineIndent));var end=this._textEditor.cursorPositionToCoordinates(lineNumber,lineText.length);var codeMirrorLinesLeftPadding=4;this._wave.style.left=(start.x-base.x+codeMirrorLinesLeftPadding)+"px";this._wave.style.width=(end.x-start.x)+"px";},messagesDescription:function() {this._messagesDescriptionElement.removeChildren();for(var i=0;i<this._messages.length;++i){this._messagesDescriptionElement.appendChild(this._messages[i].element);} return this._messagesDescriptionElement;},detachFromEditor:function() {var position=this._lineHandle.resolve();if(!position) return;var lineNumber=position.lineNumber;if(this._level) this._textEditor.toggleLineClass(lineNumber,WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level],false);this._textEditor.removeDecoration(lineNumber,this._decoration);},uniqueMessagesCount:function() {return this._messages.length;},addMessage:function(message) {for(var i=0;i<this._messages.length;++i){var rowMessage=this._messages[i];if(rowMessage.message().isEqual(message)){rowMessage.setRepeatCount(rowMessage.repeatCount()+1);return;}} var rowMessage=new WebInspector.UISourceCodeFrame.RowMessage(message);this._messages.push(rowMessage);this._updateDecoration();},removeMessage:function(message) {for(var i=0;i<this._messages.length;++i){var rowMessage=this._messages[i];if(!rowMessage.message().isEqual(message)) continue;rowMessage.setRepeatCount(rowMessage.repeatCount()-1);if(!rowMessage.repeatCount()) this._messages.splice(i,1);this._updateDecoration();return;}},_updateDecoration:function() {if(!this._sourceFrame.isEditorShowing()) return;if(!this._messages.length) return;var position=this._lineHandle.resolve();if(!position) return;var lineNumber=position.lineNumber;var columnNumber=Number.MAX_VALUE;var maxMessage=null;for(var i=0;i<this._messages.length;++i){var message=this._messages[i].message();columnNumber=Math.min(columnNumber,message.columnNumber());if(!maxMessage||WebInspector.UISourceCode.Message.messageLevelComparator(maxMessage,message)<0) maxMessage=message;} this._updateWavePosition(lineNumber,columnNumber);if(this._level){this._textEditor.toggleLineClass(lineNumber,WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level],false);this._icon.type="";} this._level=maxMessage.level();if(!this._level) return;this._textEditor.toggleLineClass(lineNumber,WebInspector.UISourceCodeFrame._lineClassPerLevel[this._level],true);this._icon.type=WebInspector.UISourceCodeFrame._iconClassPerLevel[this._level];}} WebInspector.UISourceCode.Message._messageLevelPriority={"Warning":3,"Error":4};WebInspector.UISourceCode.Message.messageLevelComparator=function(a,b) {return WebInspector.UISourceCode.Message._messageLevelPriority[a.level()]-WebInspector.UISourceCode.Message._messageLevelPriority[b.level()];};WebInspector.SourceMapNamesResolver={};WebInspector.SourceMapNamesResolver._cachedMapSymbol=Symbol("cache");WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol=Symbol("cachedIdentifiers");WebInspector.SourceMapNamesResolver.Identifier=function(name,lineNumber,columnNumber) {this.name=name;this.lineNumber=lineNumber;this.columnNumber=columnNumber;} WebInspector.SourceMapNamesResolver._scopeIdentifiers=function(scope) {var startLocation=scope.startLocation();var endLocation=scope.endLocation();if(scope.type()===DebuggerAgent.ScopeType.Global||!startLocation||!endLocation||!startLocation.script().sourceMapURL||(startLocation.script()!==endLocation.script())) return Promise.resolve(([]));var script=startLocation.script();return script.requestContent().then(onContent);function onContent(content) {if(!content) return Promise.resolve(([]));var text=new WebInspector.Text(content);var scopeRange=new WebInspector.TextRange(startLocation.lineNumber,startLocation.columnNumber,endLocation.lineNumber,endLocation.columnNumber) var scopeText=text.extract(scopeRange);var scopeStart=text.toSourceRange(scopeRange).offset;var prefix="function fui";return WebInspector.formatterWorkerPool.runTask("javaScriptIdentifiers",{content:prefix+scopeText}).then(onIdentifiers.bind(null,text,scopeStart,prefix));} function onIdentifiers(text,scopeStart,prefix,event) {var identifiers=event?(event.data):[];var result=[];var cursor=new WebInspector.TextCursor(text.lineEndings());var promises=[];for(var i=0;i<identifiers.length;++i){var id=identifiers[i];if(id.offset<prefix.length) continue;var start=scopeStart+id.offset-prefix.length;cursor.resetTo(start);result.push(new WebInspector.SourceMapNamesResolver.Identifier(id.name,cursor.lineNumber(),cursor.columnNumber()));} return result;}} WebInspector.SourceMapNamesResolver._resolveScope=function(scope) {var identifiersPromise=scope[WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol];if(identifiersPromise) return identifiersPromise;var script=scope.callFrame().script;var sourceMap=WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);if(!sourceMap) return Promise.resolve(new Map());var textCache=new Map();identifiersPromise=WebInspector.SourceMapNamesResolver._scopeIdentifiers(scope).then(onIdentifiers);scope[WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol]=identifiersPromise;return identifiersPromise;function onIdentifiers(identifiers) {var namesMapping=new Map();for(var i=0;i<identifiers.length;++i){var id=identifiers[i];var entry=sourceMap.findEntry(id.lineNumber,id.columnNumber);if(entry&&entry.name) namesMapping.set(id.name,entry.name);} var promises=[];for(var i=0;i<identifiers.length;++i){var id=identifiers[i];if(namesMapping.has(id.name)) continue;var promise=resolveSourceName(id).then(onSourceNameResolved.bind(null,namesMapping,id));promises.push(promise);} return Promise.all(promises).then(()=>WebInspector.SourceMapNamesResolver._scopeResolvedForTest()).then(()=>namesMapping)} function onSourceNameResolved(namesMapping,id,sourceName) {if(!sourceName) return;namesMapping.set(id.name,sourceName);} function resolveSourceName(id) {var startEntry=sourceMap.findEntry(id.lineNumber,id.columnNumber);var endEntry=sourceMap.findEntry(id.lineNumber,id.columnNumber+id.name.length);if(!startEntry||!endEntry||!startEntry.sourceURL||startEntry.sourceURL!==endEntry.sourceURL||!startEntry.sourceLineNumber||!startEntry.sourceColumnNumber||!endEntry.sourceLineNumber||!endEntry.sourceColumnNumber) return Promise.resolve((null));var sourceTextRange=new WebInspector.TextRange(startEntry.sourceLineNumber,startEntry.sourceColumnNumber,endEntry.sourceLineNumber,endEntry.sourceColumnNumber);var uiSourceCode=WebInspector.networkMapping.uiSourceCodeForScriptURL(startEntry.sourceURL,script);if(!uiSourceCode) return Promise.resolve((null));return uiSourceCode.requestContent().then(onSourceContent.bind(null,sourceTextRange));} function onSourceContent(sourceTextRange,content) {if(!content) return null;var text=textCache.get(content);if(!text){text=new WebInspector.Text(content);textCache.set(content,text);} var originalIdentifier=text.extract(sourceTextRange).trim();return/[a-zA-Z0-9_$]+/.test(originalIdentifier)?originalIdentifier:null;}} WebInspector.SourceMapNamesResolver._scopeResolvedForTest=function(){} WebInspector.SourceMapNamesResolver._allVariablesInCallFrame=function(callFrame) {var cached=callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol];if(cached) return Promise.resolve(cached);var promises=[];var scopeChain=callFrame.scopeChain();for(var i=0;i<scopeChain.length;++i) promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeChain[i]));return Promise.all(promises).then(mergeVariables);function mergeVariables(nameMappings) {var reverseMapping=new Map();for(var map of nameMappings){for(var compiledName of map.keys()){var originalName=map.get(compiledName);if(!reverseMapping.has(originalName)) reverseMapping.set(originalName,compiledName);}} callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol]=reverseMapping;return reverseMapping;}} WebInspector.SourceMapNamesResolver.resolveExpression=function(callFrame,originalText,uiSourceCode,lineNumber,startColumnNumber,endColumnNumber) {if(!Runtime.experiments.isEnabled("resolveVariableNames")||!uiSourceCode.contentType().isFromSourceMap()) return Promise.resolve("");return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName);function findCompiledName(reverseMapping) {if(reverseMapping.has(originalText)) return Promise.resolve(reverseMapping.get(originalText)||"");return WebInspector.SourceMapNamesResolver._resolveExpression(callFrame,uiSourceCode,lineNumber,startColumnNumber,endColumnNumber);}} WebInspector.SourceMapNamesResolver._resolveExpression=function(callFrame,uiSourceCode,lineNumber,startColumnNumber,endColumnNumber) {var target=callFrame.target();var rawLocation=WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocation(target,uiSourceCode,lineNumber,startColumnNumber);if(!rawLocation) return Promise.resolve("");var script=rawLocation.script();var sourceMap=WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);if(!sourceMap) return Promise.resolve("");return script.requestContent().then(onContent);function onContent(content) {if(!content) return Promise.resolve("");var text=new WebInspector.Text(content);var textRange=sourceMap.reverseMapTextRange(uiSourceCode.url(),new WebInspector.TextRange(lineNumber,startColumnNumber,lineNumber,endColumnNumber));var originalText=text.extract(textRange);if(!originalText) return Promise.resolve("");return WebInspector.formatterWorkerPool.runTask("evaluatableJavaScriptSubstring",{content:originalText}).then(onResult);} function onResult(event) {return event?(event.data):"";}} WebInspector.SourceMapNamesResolver.resolveThisObject=function(callFrame) {if(!callFrame) return Promise.resolve((null));if(!Runtime.experiments.isEnabled("resolveVariableNames")||!callFrame.scopeChain().length) return Promise.resolve(callFrame.thisObject());return WebInspector.SourceMapNamesResolver._resolveScope(callFrame.scopeChain()[0]).then(onScopeResolved);function onScopeResolved(namesMapping) {var thisMappings=namesMapping.inverse().get("this");if(!thisMappings||thisMappings.size!==1) return Promise.resolve(callFrame.thisObject());var thisMapping=thisMappings.valuesArray()[0];var callback;var promise=new Promise(fulfill=>callback=fulfill);callFrame.evaluate(thisMapping,"backtrace",false,true,false,true,onEvaluated.bind(null,callback));return promise;} function onEvaluated(callback,evaluateResult) {var remoteObject=evaluateResult?callFrame.target().runtimeModel.createRemoteObject(evaluateResult):callFrame.thisObject();callback(remoteObject);}} WebInspector.SourceMapNamesResolver.resolveScopeInObject=function(scope) {if(!Runtime.experiments.isEnabled("resolveVariableNames")) return scope.object();var startLocation=scope.startLocation();var endLocation=scope.endLocation();if(scope.type()===DebuggerAgent.ScopeType.Global||!startLocation||!endLocation||!startLocation.script().sourceMapURL||startLocation.script()!==endLocation.script()) return scope.object();return new WebInspector.SourceMapNamesResolver.RemoteObject(scope);} WebInspector.SourceMapNamesResolver.RemoteObject=function(scope) {WebInspector.RemoteObject.call(this);this._scope=scope;this._object=scope.object();};WebInspector.SourceMapNamesResolver.RemoteObject.prototype={customPreview:function() {return this._object.customPreview();},get type() {return this._object.type;},get subtype() {return this._object.subtype;},get description() {return this._object.description;},get hasChildren() {return this._object.hasChildren;},arrayLength:function() {return this._object.arrayLength();},getOwnProperties:function(callback) {this._object.getOwnProperties(callback);},getAllProperties:function(accessorPropertiesOnly,callback) {function wrappedCallback(properties,internalProperties) {WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(resolveNames.bind(null,properties,internalProperties))} function resolveNames(properties,internalProperties,namesMapping) {var newProperties=[];if(properties){for(var i=0;i<properties.length;++i){var property=properties[i];var name=namesMapping.get(property.name)||properties[i].name;newProperties.push(new WebInspector.RemoteObjectProperty(name,property.value,property.enumerable,property.writable,property.isOwn,property.wasThrown,property.symbol,property.synthetic));}} callback(newProperties,internalProperties);} this._object.getAllProperties(accessorPropertiesOnly,wrappedCallback.bind(this));},setPropertyValue:function(argumentName,value,callback) {WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(resolveName.bind(this));function resolveName(namesMapping) {var name;if(typeof argumentName==="string") name=argumentName;else name=(argumentName.value);var actualName=name;for(var compiledName of namesMapping.keys()){if(namesMapping.get(compiledName)===name){actualName=compiledName;break;}} this._object.setPropertyValue(actualName,value,callback);}},eventListeners:function() {return this._object.eventListeners();},deleteProperty:function(name,callback) {this._object.deleteProperty(name,callback);},callFunction:function(functionDeclaration,args,callback) {this._object.callFunction(functionDeclaration,args,callback);},callFunctionJSON:function(functionDeclaration,args,callback) {this._object.callFunctionJSON(functionDeclaration,args,callback);},target:function() {return this._object.target();},debuggerModel:function() {return this._object.debuggerModel();},isNode:function() {return this._object.isNode();},functionDetails:function(callback) {this._object.functionDetails(callback);},generatorObjectDetails:function(callback) {this._object.generatorObjectDetails(callback);},collectionEntries:function(callback) {this._object.collectionEntries(callback);},__proto__:WebInspector.RemoteObject.prototype};WebInspector.JavaScriptBreakpointsSidebarPane=function(breakpointManager,showSourceLineDelegate) {WebInspector.SidebarPane.call(this,WebInspector.UIString("Breakpoints"));this.registerRequiredCSS("components/breakpointsList.css");this._breakpointManager=breakpointManager;this._showSourceLineDelegate=showSourceLineDelegate;this.listElement=createElementWithClass("ol","breakpoint-list");this.emptyElement=this.element.createChild("div","info");this.emptyElement.textContent=WebInspector.UIString("No Breakpoints");this._items=new Map();var breakpointLocations=this._breakpointManager.allBreakpointLocations();for(var i=0;i<breakpointLocations.length;++i) this._addBreakpoint(breakpointLocations[i].breakpoint,breakpointLocations[i].uiLocation);this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded,this._breakpointAdded,this);this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved,this._breakpointRemoved,this);this.emptyElement.addEventListener("contextmenu",this._emptyElementContextMenu.bind(this),true);} WebInspector.JavaScriptBreakpointsSidebarPane.prototype={_emptyElementContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);this._appendBreakpointActiveItem(contextMenu);contextMenu.show();},_appendBreakpointActiveItem:function(contextMenu) {var breakpointActive=this._breakpointManager.breakpointsActive();var breakpointActiveTitle=breakpointActive?WebInspector.UIString.capitalize("Deactivate ^breakpoints"):WebInspector.UIString.capitalize("Activate ^breakpoints");contextMenu.appendItem(breakpointActiveTitle,this._breakpointManager.setBreakpointsActive.bind(this._breakpointManager,!breakpointActive));},_breakpointAdded:function(event) {this._breakpointRemoved(event);var breakpoint=(event.data.breakpoint);var uiLocation=(event.data.uiLocation);this._addBreakpoint(breakpoint,uiLocation);},_addBreakpoint:function(breakpoint,uiLocation) {var element=createElementWithClass("li","cursor-pointer");element.addEventListener("contextmenu",this._breakpointContextMenu.bind(this,breakpoint),true);element.addEventListener("click",this._breakpointClicked.bind(this,uiLocation),false);var checkboxLabel=createCheckboxLabel(uiLocation.linkText(),breakpoint.enabled());element.appendChild(checkboxLabel);checkboxLabel.addEventListener("click",this._breakpointCheckboxClicked.bind(this,breakpoint),false);var snippetElement=element.createChild("div","source-text monospace");function didRequestContent(content) {var lineNumber=uiLocation.lineNumber var columnNumber=uiLocation.columnNumber;var text=new WebInspector.Text(content||"");if(lineNumber<text.lineCount()){var lineText=text.lineAt(lineNumber);var maxSnippetLength=200;var snippetStartIndex=columnNumber>100?columnNumber:0;snippetElement.textContent=lineText.substr(snippetStartIndex).trimEnd(maxSnippetLength);} this.didReceiveBreakpointLineForTest(uiLocation.uiSourceCode);} uiLocation.uiSourceCode.requestContent().then(didRequestContent.bind(this));element._data=uiLocation;var currentElement=this.listElement.firstChild;while(currentElement){if(currentElement._data&&this._compareBreakpoints(currentElement._data,element._data)>0) break;currentElement=currentElement.nextSibling;} this._addListElement(element,currentElement);var breakpointItem={element:element,checkbox:checkboxLabel.checkboxElement};this._items.set(breakpoint,breakpointItem);this.expand();},didReceiveBreakpointLineForTest:function(uiSourceCode) {},_breakpointRemoved:function(event) {var breakpoint=(event.data.breakpoint);var breakpointItem=this._items.get(breakpoint);if(!breakpointItem) return;this._items.remove(breakpoint);this._removeListElement(breakpointItem.element);},highlightBreakpoint:function(breakpoint) {var breakpointItem=this._items.get(breakpoint);if(!breakpointItem) return;breakpointItem.element.classList.add("breakpoint-hit");this._highlightedBreakpointItem=breakpointItem;},clearBreakpointHighlight:function() {if(this._highlightedBreakpointItem){this._highlightedBreakpointItem.element.classList.remove("breakpoint-hit");delete this._highlightedBreakpointItem;}},_breakpointClicked:function(uiLocation,event) {this._showSourceLineDelegate(uiLocation.uiSourceCode,uiLocation.lineNumber);},_breakpointCheckboxClicked:function(breakpoint,event) {event.consume();breakpoint.setEnabled(event.target.checkboxElement.checked);},_breakpointContextMenu:function(breakpoint,event) {var breakpoints=this._items.valuesArray();var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"),breakpoint.remove.bind(breakpoint));if(breakpoints.length>1){var removeAllTitle=WebInspector.UIString.capitalize("Remove ^all ^breakpoints");contextMenu.appendItem(removeAllTitle,this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager));} contextMenu.appendSeparator();this._appendBreakpointActiveItem(contextMenu);function enabledBreakpointCount(breakpoints) {var count=0;for(var i=0;i<breakpoints.length;++i){if(breakpoints[i].checkbox.checked) count++;} return count;} if(breakpoints.length>1){var enableBreakpointCount=enabledBreakpointCount(breakpoints);var enableTitle=WebInspector.UIString.capitalize("Enable ^all ^breakpoints");var disableTitle=WebInspector.UIString.capitalize("Disable ^all ^breakpoints");contextMenu.appendSeparator();contextMenu.appendItem(enableTitle,this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager,true),!(enableBreakpointCount!=breakpoints.length));contextMenu.appendItem(disableTitle,this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager,false),!(enableBreakpointCount>1));} contextMenu.show();},_addListElement:function(element,beforeElement) {if(beforeElement) this.listElement.insertBefore(element,beforeElement);else{if(!this.listElement.firstChild){this.element.removeChild(this.emptyElement);this.element.appendChild(this.listElement);} this.listElement.appendChild(element);}},_removeListElement:function(element) {this.listElement.removeChild(element);if(!this.listElement.firstChild){this.element.removeChild(this.listElement);this.element.appendChild(this.emptyElement);}},_compare:function(x,y) {if(x!==y) return x<y?-1:1;return 0;},_compareBreakpoints:function(b1,b2) {return this._compare(b1.uiSourceCode.url(),b2.uiSourceCode.url())||this._compare(b1.lineNumber,b2.lineNumber);},reset:function() {this.listElement.removeChildren();if(this.listElement.parentElement){this.element.removeChild(this.listElement);this.element.appendChild(this.emptyElement);} this._items.clear();},__proto__:WebInspector.SidebarPane.prototype};WebInspector.JavaScriptOutlineDialog=function(uiSourceCode,selectItemCallback) {WebInspector.FilteredListWidget.Delegate.call(this,[]);this._functionItems=[];this._selectItemCallback=selectItemCallback;WebInspector.formatterWorkerPool.runChunkedTask("javaScriptOutline",{content:uiSourceCode.workingCopy()},this._didBuildOutlineChunk.bind(this));} WebInspector.JavaScriptOutlineDialog.show=function(uiSourceCode,selectItemCallback) {new WebInspector.FilteredListWidget(new WebInspector.JavaScriptOutlineDialog(uiSourceCode,selectItemCallback)).showAsDialog();} WebInspector.JavaScriptOutlineDialog.prototype={_didBuildOutlineChunk:function(event) {if(!event){this.dispose();this.refresh();return;} var data=(event.data);var chunk=data.chunk;for(var i=0;i<chunk.length;++i) this._functionItems.push(chunk[i]);if(data.isLastChunk) this.dispose();this.refresh();},itemCount:function() {return this._functionItems.length;},itemKeyAt:function(itemIndex) {var item=this._functionItems[itemIndex];return item.name+(item.arguments?item.arguments:"");},itemScoreAt:function(itemIndex,query) {var item=this._functionItems[itemIndex];return-item.line;},renderItem:function(itemIndex,query,titleElement,subtitleElement) {var item=this._functionItems[itemIndex];titleElement.textContent=item.name+(item.arguments?item.arguments:"");this.highlightRanges(titleElement,query);subtitleElement.textContent=":"+(item.line+1);},selectItem:function(itemIndex,promptValue) {if(itemIndex===null) return;var lineNumber=this._functionItems[itemIndex].line;if(!isNaN(lineNumber)&&lineNumber>=0) this._selectItemCallback(lineNumber,this._functionItems[itemIndex].column);},dispose:function() {},__proto__:WebInspector.FilteredListWidget.Delegate.prototype} WebInspector.JavaScriptOutlineDialog.MessageEventData;;WebInspector.SourceCodeDiff=function(uiSourceCode,textEditor) {this._uiSourceCode=uiSourceCode;this._textEditor=textEditor;this._decorations=[];this._textEditor.installGutter(WebInspector.SourceCodeDiff.DiffGutterType,true);this._diffBaseline=this._uiSourceCode.requestOriginalContent();this._animatedLines=[];} WebInspector.SourceCodeDiff.UpdateTimeout=200;WebInspector.SourceCodeDiff.DiffGutterType="CodeMirror-gutter-diff";WebInspector.SourceCodeDiff.prototype={updateDiffMarkersWhenPossible:function() {if(this._updateTimeout) clearTimeout(this._updateTimeout);this._updateTimeout=setTimeout(this.updateDiffMarkersImmediately.bind(this),WebInspector.SourceCodeDiff.UpdateTimeout);},updateDiffMarkersImmediately:function() {if(this._updateTimeout) clearTimeout(this._updateTimeout);this._updateTimeout=null;this._diffBaseline.then(this._innerUpdate.bind(this));},highlightModifiedLines:function(oldContent,newContent) {if(typeof oldContent!=="string"||typeof newContent!=="string") return;var diff=this._computeDiff(oldContent,newContent);var changedLines=[];for(var i=0;i<diff.length;++i){var diffEntry=diff[i];if(diffEntry.type===WebInspector.SourceCodeDiff.GutterDecorationType.Delete) continue;for(var lineNumber=diffEntry.from;lineNumber<diffEntry.to;++lineNumber){var position=this._textEditor.textEditorPositionHandle(lineNumber,0);if(position) changedLines.push(position);}} this._updateHighlightedLines(changedLines);this._animationTimeout=setTimeout(this._updateHighlightedLines.bind(this,[]),400);},_updateHighlightedLines:function(newLines) {if(this._animationTimeout) clearTimeout(this._animationTimeout);this._animationTimeout=null;this._textEditor.operation(operation.bind(this));function operation() {toggleLines.call(this,false);this._animatedLines=newLines;toggleLines.call(this,true);} function toggleLines(value) {for(var i=0;i<this._animatedLines.length;++i){var location=this._animatedLines[i].resolve();if(location) this._textEditor.toggleLineClass(location.lineNumber,"highlight-line-modification",value);}}},_updateDecorations:function(removed,added) {this._textEditor.operation(operation);function operation() {for(var decoration of removed) decoration.remove();for(var decoration of added) decoration.install();}},_computeDiff:function(baseline,current) {var diff=WebInspector.Diff.lineDiff(baseline.split("\n"),current.split("\n"));var result=[];var hasAdded=false;var hasRemoved=false;var blockStartLineNumber=0;var currentLineNumber=0;var isInsideBlock=false;for(var i=0;i<diff.length;++i){var token=diff[i];if(token[0]===WebInspector.Diff.Operation.Equal){if(isInsideBlock) flush();currentLineNumber+=token[1].length;continue;} if(!isInsideBlock){isInsideBlock=true;blockStartLineNumber=currentLineNumber;} if(token[0]===WebInspector.Diff.Operation.Delete){hasRemoved=true;}else{currentLineNumber+=token[1].length;hasAdded=true;}} if(isInsideBlock) flush();if(result.length>1&&result[0].from===0&&result[1].from===0){var merged={type:WebInspector.SourceCodeDiff.GutterDecorationType.Modify,from:0,to:result[1].to};result.splice(0,2,merged);} return result;function flush() {var type=WebInspector.SourceCodeDiff.GutterDecorationType.Insert;var from=blockStartLineNumber;var to=currentLineNumber;if(hasAdded&&hasRemoved){type=WebInspector.SourceCodeDiff.GutterDecorationType.Modify;}else if(!hasAdded&&hasRemoved&&from===0&&to===0){type=WebInspector.SourceCodeDiff.GutterDecorationType.Modify;to=1;}else if(!hasAdded&&hasRemoved){type=WebInspector.SourceCodeDiff.GutterDecorationType.Delete;from-=1;} result.push({type:type,from:from,to:to});isInsideBlock=false;hasAdded=false;hasRemoved=false;}},_innerUpdate:function(baseline) {var current=this._uiSourceCode.workingCopy();if(typeof current!=="string"||typeof baseline!=="string"){this._updateDecorations(this._decorations,[]);this._decorations=[];return;} var diff=this._computeDiff(baseline,current);var oldDecorations=new Map();for(var i=0;i<this._decorations.length;++i){var decoration=this._decorations[i];var lineNumber=decoration.lineNumber();if(lineNumber===-1) continue;oldDecorations.set(lineNumber,decoration);} var newDecorations=new Map();for(var i=0;i<diff.length;++i){var diffEntry=diff[i];for(var lineNumber=diffEntry.from;lineNumber<diffEntry.to;++lineNumber) newDecorations.set(lineNumber,{lineNumber:lineNumber,type:diffEntry.type});} var decorationDiff=oldDecorations.diff(newDecorations,(e1,e2)=>e1.type===e2.type);var addedDecorations=decorationDiff.added.map(entry=>new WebInspector.SourceCodeDiff.GutterDecoration(this._textEditor,entry.lineNumber,entry.type));this._decorations=decorationDiff.equal.concat(addedDecorations);this._updateDecorations(decorationDiff.removed,addedDecorations);},} WebInspector.SourceCodeDiff.GutterDecorationType={Insert:"Insert",Delete:"Delete",Modify:"Modify",} WebInspector.SourceCodeDiff.GutterDecoration=function(textEditor,lineNumber,type) {this._textEditor=textEditor;this._position=this._textEditor.textEditorPositionHandle(lineNumber,0);this._className="";if(type===WebInspector.SourceCodeDiff.GutterDecorationType.Insert) this._className="diff-entry-insert";else if(type===WebInspector.SourceCodeDiff.GutterDecorationType.Delete) this._className="diff-entry-delete";else if(type===WebInspector.SourceCodeDiff.GutterDecorationType.Modify) this._className="diff-entry-modify";this.type=type;} WebInspector.SourceCodeDiff.GutterDecoration.prototype={lineNumber:function() {var location=this._position.resolve();if(!location) return-1;return location.lineNumber;},install:function() {var location=this._position.resolve();if(!location) return;var element=createElementWithClass("div","diff-marker");element.textContent="\u00A0";this._textEditor.setGutterDecoration(location.lineNumber,WebInspector.SourceCodeDiff.DiffGutterType,element);this._textEditor.toggleLineClass(location.lineNumber,this._className,true);},remove:function() {var location=this._position.resolve();if(!location) return;this._textEditor.setGutterDecoration(location.lineNumber,WebInspector.SourceCodeDiff.DiffGutterType,null);this._textEditor.toggleLineClass(location.lineNumber,this._className,false);}};WebInspector.JavaScriptSourceFrame=function(scriptsPanel,uiSourceCode) {this._scriptsPanel=scriptsPanel;this._breakpointManager=WebInspector.breakpointManager;WebInspector.UISourceCodeFrame.call(this,uiSourceCode);if(uiSourceCode.project().type()===WebInspector.projectTypes.Debugger) this.element.classList.add("source-frame-debugger-script");this._popoverHelper=new WebInspector.ObjectPopoverHelper(scriptsPanel.element,this._getPopoverAnchor.bind(this),this._resolveObjectForPopover.bind(this),this._onHidePopover.bind(this),true);this._popoverHelper.setTimeout(250,250);this.textEditor.element.addEventListener("keydown",this._onKeyDown.bind(this),true);this.textEditor.addEventListener(WebInspector.CodeMirrorTextEditor.Events.GutterClick,this._handleGutterClick.bind(this),this);this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded,this._breakpointAdded,this);this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved,this._breakpointRemoved,this);this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged,this._onSourceMappingChanged,this);this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);this.uiSourceCode().addEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._showBlackboxInfobarIfNeeded,this);this._scriptFileForTarget=new Map();this._registerShortcuts();var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i){var scriptFile=WebInspector.debuggerWorkspaceBinding.scriptFile(uiSourceCode,targets[i]);if(scriptFile) this._updateScriptFile(targets[i]);} if(this._scriptFileForTarget.size||uiSourceCode.extension()==="js") this._compiler=new WebInspector.JavaScriptCompiler(this);WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._showBlackboxInfobarIfNeeded,this);WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._showBlackboxInfobarIfNeeded,this);this._showBlackboxInfobarIfNeeded();this._valueWidgets=new Map();} WebInspector.JavaScriptSourceFrame.prototype={toolbarItems:function() {var result=WebInspector.UISourceCodeFrame.prototype.toolbarItems.call(this);var originURL=WebInspector.CompilerScriptMapping.uiSourceCodeOrigin(this.uiSourceCode());if(originURL){var parsedURL=originURL.asParsedURL();if(parsedURL) result.push(new WebInspector.ToolbarText(WebInspector.UIString("(source mapped from %s)",parsedURL.displayName)));} return result;},_updateInfobars:function() {this.attachInfobars([this._blackboxInfobar,this._divergedInfobar]);},_showDivergedInfobar:function() {if(!this.uiSourceCode().contentType().isScript()) return;if(this._divergedInfobar) this._divergedInfobar.dispose();var infobar=new WebInspector.Infobar(WebInspector.Infobar.Type.Warning,WebInspector.UIString("Workspace mapping mismatch"));this._divergedInfobar=infobar;var fileURL=this.uiSourceCode().url();infobar.createDetailsRowMessage(WebInspector.UIString("The content of this file on the file system:\u00a0")).appendChild(WebInspector.linkifyURLAsNode(fileURL,fileURL,"source-frame-infobar-details-url",true));var scriptURL=WebInspector.networkMapping.networkURL(this.uiSourceCode());infobar.createDetailsRowMessage(WebInspector.UIString("does not match the loaded script:\u00a0")).appendChild(WebInspector.linkifyURLAsNode(scriptURL,scriptURL,"source-frame-infobar-details-url",true));infobar.createDetailsRowMessage();infobar.createDetailsRowMessage(WebInspector.UIString("Possible solutions are:"));if(WebInspector.moduleSetting("cacheDisabled").get()) infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Reload inspected page"));else infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Check \"Disable cache\" in settings and reload inspected page (recommended setup for authoring and debugging)"));infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Check that your file and script are both loaded from the correct source and their contents match"));this._updateInfobars();},_hideDivergedInfobar:function() {if(!this._divergedInfobar) return;this._divergedInfobar.dispose();delete this._divergedInfobar;},_showBlackboxInfobarIfNeeded:function() {var uiSourceCode=this.uiSourceCode();if(!uiSourceCode.contentType().hasScripts()) return;var projectType=uiSourceCode.project().type();if(projectType===WebInspector.projectTypes.Snippets) return;var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);var url=projectType===WebInspector.projectTypes.Formatter?uiSourceCode.url():networkURL;var isContentScript=projectType===WebInspector.projectTypes.ContentScripts;if(!WebInspector.blackboxManager.isBlackboxedUISourceCode(uiSourceCode)){this._hideBlackboxInfobar();return;} if(this._blackboxInfobar) this._blackboxInfobar.dispose();var infobar=new WebInspector.Infobar(WebInspector.Infobar.Type.Warning,WebInspector.UIString("This script is blackboxed in debugger"));this._blackboxInfobar=infobar;infobar.createDetailsRowMessage(WebInspector.UIString("Debugger will skip stepping through this script, and will not stop on exceptions"));var scriptFile=this._scriptFileForTarget.size?this._scriptFileForTarget.valuesArray()[0]:null;if(scriptFile&&scriptFile.hasSourceMapURL()) infobar.createDetailsRowMessage(WebInspector.UIString("Source map found, but ignored for blackboxed file."));infobar.createDetailsRowMessage();infobar.createDetailsRowMessage(WebInspector.UIString("Possible ways to cancel this behavior are:"));infobar.createDetailsRowMessage(" - ").createTextChild(WebInspector.UIString("Go to \"%s\" tab in settings",WebInspector.manageBlackboxingSettingsTabLabel()));var unblackboxLink=infobar.createDetailsRowMessage(" - ").createChild("span","link");unblackboxLink.textContent=WebInspector.UIString("Unblackbox this script");unblackboxLink.addEventListener("click",unblackbox,false);function unblackbox() {WebInspector.blackboxManager.unblackboxUISourceCode(uiSourceCode);if(projectType===WebInspector.projectTypes.ContentScripts) WebInspector.blackboxManager.unblackboxContentScripts();} this._updateInfobars();},_hideBlackboxInfobar:function() {if(!this._blackboxInfobar) return;this._blackboxInfobar.dispose();delete this._blackboxInfobar;},_registerShortcuts:function() {var shortcutKeys=WebInspector.ShortcutsScreen.SourcesPanelShortcuts;for(var i=0;i<shortcutKeys.EvaluateSelectionInConsole.length;++i){var keyDescriptor=shortcutKeys.EvaluateSelectionInConsole[i];this.addShortcut(keyDescriptor.key,this._evaluateSelectionInConsole.bind(this));} for(var i=0;i<shortcutKeys.AddSelectionToWatch.length;++i){var keyDescriptor=shortcutKeys.AddSelectionToWatch[i];this.addShortcut(keyDescriptor.key,this._addCurrentSelectionToWatch.bind(this));}},_addCurrentSelectionToWatch:function() {var textSelection=this.textEditor.selection();if(textSelection&&!textSelection.isEmpty()) this._innerAddToWatch(this.textEditor.copyRange(textSelection));return true;},_innerAddToWatch:function(expression) {this._scriptsPanel.addToWatch(expression);},_evaluateSelectionInConsole:function() {var selection=this.textEditor.selection();if(!selection||selection.isEmpty()) return true;this._evaluateInConsole(this.textEditor.copyRange(selection));return true;},_evaluateInConsole:function(expression) {var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(currentExecutionContext) WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext,expression);},wasShown:function() {WebInspector.UISourceCodeFrame.prototype.wasShown.call(this);if(this._executionLocation&&this.loaded){setImmediate(this._generateValuesInSource.bind(this));}},willHide:function() {WebInspector.UISourceCodeFrame.prototype.willHide.call(this);this._popoverHelper.hidePopover();},onUISourceCodeContentChanged:function() {this._removeAllBreakpoints();WebInspector.UISourceCodeFrame.prototype.onUISourceCodeContentChanged.call(this);},onTextChanged:function(oldRange,newRange) {this._scriptsPanel.updateLastModificationTime();WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this,oldRange,newRange);if(this._compiler) this._compiler.scheduleCompile();},populateLineGutterContextMenu:function(contextMenu,lineNumber) {function populate(resolve,reject) {var uiLocation=new WebInspector.UILocation(this.uiSourceCode(),lineNumber,0);this._scriptsPanel.appendUILocationItems(contextMenu,uiLocation);var breakpoint=this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(),lineNumber);if(!breakpoint){contextMenu.appendItem(WebInspector.UIString("Add breakpoint"),this._createNewBreakpoint.bind(this,lineNumber,0,"",true));contextMenu.appendItem(WebInspector.UIString("Add conditional breakpoint…"),this._editBreakpointCondition.bind(this,lineNumber));contextMenu.appendItem(WebInspector.UIString("Never pause here"),this._createNewBreakpoint.bind(this,lineNumber,0,"false",true));}else{contextMenu.appendItem(WebInspector.UIString("Remove breakpoint"),breakpoint.remove.bind(breakpoint));contextMenu.appendItem(WebInspector.UIString("Edit breakpoint…"),this._editBreakpointCondition.bind(this,lineNumber,breakpoint));if(breakpoint.enabled()) contextMenu.appendItem(WebInspector.UIString("Disable breakpoint"),breakpoint.setEnabled.bind(breakpoint,false));else contextMenu.appendItem(WebInspector.UIString("Enable breakpoint"),breakpoint.setEnabled.bind(breakpoint,true));} resolve();} return new Promise(populate.bind(this));},populateTextAreaContextMenu:function(contextMenu,lineNumber,columnNumber) {var textSelection=this.textEditor.selection();if(textSelection&&!textSelection.isEmpty()){var selection=this.textEditor.copyRange(textSelection);var addToWatchLabel=WebInspector.UIString.capitalize("Add to ^watch");contextMenu.appendItem(addToWatchLabel,this._innerAddToWatch.bind(this,selection));var evaluateLabel=WebInspector.UIString.capitalize("Evaluate in ^console");contextMenu.appendItem(evaluateLabel,this._evaluateInConsole.bind(this,selection));contextMenu.appendSeparator();} function addSourceMapURL(scriptFile) {WebInspector.AddSourceMapURLDialog.show(addSourceMapURLDialogCallback.bind(null,scriptFile));} function addSourceMapURLDialogCallback(scriptFile,url) {if(!url) return;scriptFile.addSourceMapURL(url);} function populateSourceMapMembers() {if(this.uiSourceCode().project().type()===WebInspector.projectTypes.Network&&WebInspector.moduleSetting("jsSourceMapsEnabled").get()&&!WebInspector.blackboxManager.isBlackboxedUISourceCode(this.uiSourceCode())){if(this._scriptFileForTarget.size){var scriptFile=this._scriptFileForTarget.valuesArray()[0];var addSourceMapURLLabel=WebInspector.UIString.capitalize("Add ^source ^map\u2026");contextMenu.appendItem(addSourceMapURLLabel,addSourceMapURL.bind(null,scriptFile));contextMenu.appendSeparator();}}} return WebInspector.UISourceCodeFrame.prototype.populateTextAreaContextMenu.call(this,contextMenu,lineNumber,columnNumber).then(populateSourceMapMembers.bind(this));},_workingCopyChanged:function(event) {if(this._supportsEnabledBreakpointsWhileEditing()||this._scriptFileForTarget.size) return;if(this.uiSourceCode().isDirty()) this._muteBreakpointsWhileEditing();else this._restoreBreakpointsAfterEditing();},_workingCopyCommitted:function(event) {this._scriptsPanel.updateLastModificationTime();if(this._supportsEnabledBreakpointsWhileEditing()) return;if(!this._scriptFileForTarget.size) this._restoreBreakpointsAfterEditing();},_didMergeToVM:function() {if(this._supportsEnabledBreakpointsWhileEditing()) return;this._updateDivergedInfobar();this._restoreBreakpointsIfConsistentScripts();},_didDivergeFromVM:function() {if(this._supportsEnabledBreakpointsWhileEditing()) return;this._updateDivergedInfobar();this._muteBreakpointsWhileEditing();},_muteBreakpointsWhileEditing:function() {if(this._muted) return;for(var lineNumber=0;lineNumber<this._textEditor.linesCount;++lineNumber){var breakpointDecoration=this._textEditor.getAttribute(lineNumber,"breakpoint");if(!breakpointDecoration) continue;this._removeBreakpointDecoration(lineNumber);this._addBreakpointDecoration(lineNumber,breakpointDecoration.columnNumber,breakpointDecoration.condition,breakpointDecoration.enabled,true);} this._muted=true;},_updateDivergedInfobar:function() {if(this.uiSourceCode().project().type()!==WebInspector.projectTypes.FileSystem){this._hideDivergedInfobar();return;} var scriptFiles=this._scriptFileForTarget.valuesArray();var hasDivergedScript=false;for(var i=0;i<scriptFiles.length;++i) hasDivergedScript=hasDivergedScript||scriptFiles[i].hasDivergedFromVM();if(this._divergedInfobar){if(!hasDivergedScript) this._hideDivergedInfobar();}else{if(hasDivergedScript&&!this.uiSourceCode().isDirty()) this._showDivergedInfobar();}},_supportsEnabledBreakpointsWhileEditing:function() {return this.uiSourceCode().project().type()===WebInspector.projectTypes.Snippets;},_restoreBreakpointsIfConsistentScripts:function() {var scriptFiles=this._scriptFileForTarget.valuesArray();for(var i=0;i<scriptFiles.length;++i) if(scriptFiles[i].hasDivergedFromVM()||scriptFiles[i].isMergingToVM()) return;this._restoreBreakpointsAfterEditing();},_restoreBreakpointsAfterEditing:function() {delete this._muted;var breakpoints={};for(var lineNumber=0;lineNumber<this._textEditor.linesCount;++lineNumber){var breakpointDecoration=this._textEditor.getAttribute(lineNumber,"breakpoint");if(breakpointDecoration){breakpoints[lineNumber]=breakpointDecoration;this._removeBreakpointDecoration(lineNumber);}} this._removeAllBreakpoints();for(var lineNumberString in breakpoints){var lineNumber=parseInt(lineNumberString,10);if(isNaN(lineNumber)) continue;var breakpointDecoration=breakpoints[lineNumberString];this._setBreakpoint(lineNumber,breakpointDecoration.columnNumber,breakpointDecoration.condition,breakpointDecoration.enabled);}},_removeAllBreakpoints:function() {var breakpoints=this._breakpointManager.breakpointsForUISourceCode(this.uiSourceCode());for(var i=0;i<breakpoints.length;++i) breakpoints[i].remove();},_isIdentifier:function(tokenType) {return tokenType.startsWith("js-variable")||tokenType.startsWith("js-property")||tokenType=="js-def";},_getPopoverAnchor:function(element,event) {var target=WebInspector.context.flavor(WebInspector.Target);var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel||!debuggerModel.isPaused()) return;var textPosition=this.textEditor.coordinatesToCursorPosition(event.x,event.y);if(!textPosition) return;var mouseLine=textPosition.startLine;var mouseColumn=textPosition.startColumn;var textSelection=this.textEditor.selection().normalize();if(textSelection&&!textSelection.isEmpty()){if(textSelection.startLine!==textSelection.endLine||textSelection.startLine!==mouseLine||mouseColumn<textSelection.startColumn||mouseColumn>textSelection.endColumn) return;var leftCorner=this.textEditor.cursorPositionToCoordinates(textSelection.startLine,textSelection.startColumn);var rightCorner=this.textEditor.cursorPositionToCoordinates(textSelection.endLine,textSelection.endColumn);var anchorBox=new AnchorBox(leftCorner.x,leftCorner.y,rightCorner.x-leftCorner.x,leftCorner.height);anchorBox.highlight={lineNumber:textSelection.startLine,startColumn:textSelection.startColumn,endColumn:textSelection.endColumn-1};anchorBox.forSelection=true;return anchorBox;} var token=this.textEditor.tokenAtTextPosition(textPosition.startLine,textPosition.startColumn);if(!token||!token.type) return;var lineNumber=textPosition.startLine;var line=this.textEditor.line(lineNumber);var tokenContent=line.substring(token.startColumn,token.endColumn);var isIdentifier=this._isIdentifier(token.type);if(!isIdentifier&&(token.type!=="js-keyword"||tokenContent!=="this")) return;var leftCorner=this.textEditor.cursorPositionToCoordinates(lineNumber,token.startColumn);var rightCorner=this.textEditor.cursorPositionToCoordinates(lineNumber,token.endColumn-1);var anchorBox=new AnchorBox(leftCorner.x,leftCorner.y,rightCorner.x-leftCorner.x,leftCorner.height);anchorBox.highlight={lineNumber:lineNumber,startColumn:token.startColumn,endColumn:token.endColumn-1};return anchorBox;},_resolveObjectForPopover:function(anchorBox,showCallback,objectGroupName) {var target=WebInspector.context.flavor(WebInspector.Target);var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel||!debuggerModel.isPaused()){this._popoverHelper.hidePopover();return;} var lineNumber=anchorBox.highlight.lineNumber;var startHighlight=anchorBox.highlight.startColumn;var endHighlight=anchorBox.highlight.endColumn;var line=this.textEditor.line(lineNumber);if(!anchorBox.forSelection){while(startHighlight>1&&line.charAt(startHighlight-1)==="."){var token=this.textEditor.tokenAtTextPosition(lineNumber,startHighlight-2);if(!token||!token.type){this._popoverHelper.hidePopover();return;} startHighlight=token.startColumn;}} var evaluationText=line.substring(startHighlight,endHighlight+1);var selectedCallFrame=(debuggerModel.selectedCallFrame());WebInspector.SourceMapNamesResolver.resolveExpression(selectedCallFrame,evaluationText,this.uiSourceCode(),lineNumber,startHighlight,endHighlight).then(onResolve.bind(this));function onResolve(text) {selectedCallFrame.evaluate(text||evaluationText,objectGroupName,false,true,false,false,showObjectPopover.bind(this));} function showObjectPopover(result,wasThrown) {var target=WebInspector.context.flavor(WebInspector.Target);if(selectedCallFrame.target()!=target||!debuggerModel.isPaused()||!result){this._popoverHelper.hidePopover();return;} this._popoverAnchorBox=anchorBox;showCallback(target.runtimeModel.createRemoteObject(result),wasThrown,this._popoverAnchorBox);if(this._popoverAnchorBox){var highlightRange=new WebInspector.TextRange(lineNumber,startHighlight,lineNumber,endHighlight);this._popoverAnchorBox._highlightDescriptor=this.textEditor.highlightRange(highlightRange,"source-frame-eval-expression");}}},_onHidePopover:function() {if(!this._popoverAnchorBox) return;if(this._popoverAnchorBox._highlightDescriptor) this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescriptor);delete this._popoverAnchorBox;},_addBreakpointDecoration:function(lineNumber,columnNumber,condition,enabled,mutedWhileEditing) {var breakpoint={condition:condition,enabled:enabled,columnNumber:columnNumber};this.textEditor.setAttribute(lineNumber,"breakpoint",breakpoint);var disabled=!enabled||mutedWhileEditing;this.textEditor.addBreakpoint(lineNumber,disabled,!!condition);},_removeBreakpointDecoration:function(lineNumber) {this.textEditor.removeAttribute(lineNumber,"breakpoint");this.textEditor.removeBreakpoint(lineNumber);},_onKeyDown:function(event) {if(event.keyIdentifier==="U+001B"){if(this._popoverHelper.isPopoverVisible()){this._popoverHelper.hidePopover();event.consume();}}},_editBreakpointCondition:function(lineNumber,breakpoint) {this._conditionElement=this._createConditionElement(lineNumber);this.textEditor.addDecoration(lineNumber,this._conditionElement);function finishEditing(committed,element,newText) {this.textEditor.removeDecoration(lineNumber,this._conditionElement);delete this._conditionEditorElement;delete this._conditionElement;if(!committed) return;if(breakpoint) breakpoint.setCondition(newText);else this._createNewBreakpoint(lineNumber,0,newText,true);} var config=new WebInspector.InplaceEditor.Config(finishEditing.bind(this,true),finishEditing.bind(this,false));WebInspector.InplaceEditor.startEditing(this._conditionEditorElement,config);this._conditionEditorElement.value=breakpoint?breakpoint.condition():"";this._conditionEditorElement.select();},_createConditionElement:function(lineNumber) {var conditionElement=createElementWithClass("div","source-frame-breakpoint-condition");var labelElement=conditionElement.createChild("label","source-frame-breakpoint-message");labelElement.htmlFor="source-frame-breakpoint-condition";labelElement.createTextChild(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:",lineNumber+1));var editorElement=conditionElement.createChild("input","monospace");editorElement.id="source-frame-breakpoint-condition";editorElement.type="text";this._conditionEditorElement=editorElement;return conditionElement;},setExecutionLocation:function(uiLocation) {this._executionLocation=uiLocation;if(!this.loaded) return;this.textEditor.setExecutionLocation(uiLocation.lineNumber,uiLocation.columnNumber);if(this.isShowing()){setImmediate(this._generateValuesInSource.bind(this));}},_generateValuesInSource:function() {if(!WebInspector.moduleSetting("inlineVariableValues").get()) return;var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!executionContext) return;var callFrame=executionContext.debuggerModel.selectedCallFrame();if(!callFrame) return;var localScope=callFrame.localScope();var functionLocation=callFrame.functionLocation();if(localScope&&functionLocation) WebInspector.SourceMapNamesResolver.resolveScopeInObject(localScope).getAllProperties(false,this._prepareScopeVariables.bind(this,callFrame));if(this._clearValueWidgetsTimer){clearTimeout(this._clearValueWidgetsTimer);delete this._clearValueWidgetsTimer;}},_prepareScopeVariables:function(callFrame,properties,internalProperties) {if(!properties||!properties.length||properties.length>500){this._clearValueWidgets();return;} var functionUILocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation((callFrame.functionLocation()));var executionUILocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(callFrame.location());if(functionUILocation.uiSourceCode!==this.uiSourceCode()||executionUILocation.uiSourceCode!==this.uiSourceCode()){this._clearValueWidgets();return;} var fromLine=functionUILocation.lineNumber;var fromColumn=functionUILocation.columnNumber;var toLine=executionUILocation.lineNumber;if(this._valueWidgets){for(var line of this._valueWidgets.keys()) toLine=Math.max(toLine,line+1);} if(fromLine>=toLine||toLine-fromLine>500||fromLine<0||toLine>=this.textEditor.linesCount){this._clearValueWidgets();return;} var valuesMap=new Map();for(var property of properties) valuesMap.set(property.name,property.value);var namesPerLine=new Map();var tokenizer=new WebInspector.CodeMirrorUtils.TokenizerFactory().createTokenizer("text/javascript");tokenizer(this.textEditor.line(fromLine).substring(fromColumn),processToken.bind(this,fromLine));for(var i=fromLine+1;i<toLine;++i) tokenizer(this.textEditor.line(i),processToken.bind(this,i));function processToken(lineNumber,tokenValue,tokenType,column,newColumn) {if(tokenType&&this._isIdentifier(tokenType)&&valuesMap.get(tokenValue)){var names=namesPerLine.get(lineNumber);if(!names){names=new Set();namesPerLine.set(lineNumber,names);} names.add(tokenValue);}} this.textEditor.operation(this._renderDecorations.bind(this,valuesMap,namesPerLine,fromLine,toLine));},_renderDecorations:function(valuesMap,namesPerLine,fromLine,toLine) {var formatter=new WebInspector.RemoteObjectPreviewFormatter();for(var i=fromLine;i<toLine;++i){var names=namesPerLine.get(i);var oldWidget=this._valueWidgets.get(i);if(!names){if(oldWidget){this._valueWidgets.delete(i);this.textEditor.removeDecoration(i,oldWidget);} continue;} var widget=createElementWithClass("div","text-editor-value-decoration");var base=this.textEditor.cursorPositionToCoordinates(i,0);var offset=this.textEditor.cursorPositionToCoordinates(i,this.textEditor.line(i).length);var codeMirrorLinesLeftPadding=4;var left=offset.x-base.x+codeMirrorLinesLeftPadding;widget.style.left=left+"px";widget.__nameToToken=new Map();widget.__lineNumber=i;var renderedNameCount=0;for(var name of names){if(renderedNameCount>10) break;if(namesPerLine.get(i-1)&&namesPerLine.get(i-1).has(name)) continue;if(renderedNameCount) widget.createTextChild(", ");var nameValuePair=widget.createChild("span");widget.__nameToToken.set(name,nameValuePair);nameValuePair.createTextChild(name+" = ");var value=valuesMap.get(name);var propertyCount=value.preview?value.preview.properties.length:0;var entryCount=value.preview&&value.preview.entries?value.preview.entries.length:0;if(value.preview&&propertyCount+entryCount<10) formatter.appendObjectPreview(nameValuePair,value.preview);else nameValuePair.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(value,false));++renderedNameCount;} var widgetChanged=true;if(oldWidget){widgetChanged=false;for(var name of widget.__nameToToken.keys()){var oldText=oldWidget.__nameToToken.get(name)?oldWidget.__nameToToken.get(name).textContent:"";var newText=widget.__nameToToken.get(name)?widget.__nameToToken.get(name).textContent:"";if(newText!==oldText){widgetChanged=true;WebInspector.runCSSAnimationOnce((widget.__nameToToken.get(name)),"source-frame-value-update-highlight");}} if(widgetChanged){this._valueWidgets.delete(i);this.textEditor.removeDecoration(i,oldWidget);}} if(widgetChanged){this._valueWidgets.set(i,widget);this.textEditor.addDecoration(i,widget);}}},clearExecutionLine:function() {if(this.loaded&&this._executionLocation) this.textEditor.clearExecutionLine();delete this._executionLocation;this._clearValueWidgetsTimer=setTimeout(this._clearValueWidgets.bind(this),1000);},_clearValueWidgets:function() {delete this._clearValueWidgetsTimer;for(var line of this._valueWidgets.keys()) this.textEditor.removeDecoration(line,this._valueWidgets.get(line));this._valueWidgets.clear();},_shouldIgnoreExternalBreakpointEvents:function() {if(this._supportsEnabledBreakpointsWhileEditing()) return false;if(this._muted) return true;var scriptFiles=this._scriptFileForTarget.valuesArray();for(var i=0;i<scriptFiles.length;++i){if(scriptFiles[i].isDivergingFromVM()||scriptFiles[i].isMergingToVM()) return true;} return false;},_breakpointAdded:function(event) {var uiLocation=(event.data.uiLocation);if(uiLocation.uiSourceCode!==this.uiSourceCode()) return;if(this._shouldIgnoreExternalBreakpointEvents()) return;var breakpoint=(event.data.breakpoint);if(this.loaded) this._addBreakpointDecoration(uiLocation.lineNumber,uiLocation.columnNumber,breakpoint.condition(),breakpoint.enabled(),false);},_breakpointRemoved:function(event) {var uiLocation=(event.data.uiLocation);if(uiLocation.uiSourceCode!==this.uiSourceCode()) return;if(this._shouldIgnoreExternalBreakpointEvents()) return;var remainingBreakpoint=this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(),uiLocation.lineNumber);if(!remainingBreakpoint&&this.loaded) this._removeBreakpointDecoration(uiLocation.lineNumber);},_onSourceMappingChanged:function(event) {var data=(event.data);this._updateScriptFile(data.target);this._updateLinesWithoutMappingHighlight();},_updateLinesWithoutMappingHighlight:function() {var linesCount=this.textEditor.linesCount;for(var i=0;i<linesCount;++i){var lineHasMapping=WebInspector.debuggerWorkspaceBinding.uiLineHasMapping(this.uiSourceCode(),i);if(!lineHasMapping) this._hasLineWithoutMapping=true;if(this._hasLineWithoutMapping) this.textEditor.toggleLineClass(i,"cm-line-without-source-mapping",!lineHasMapping);}},_updateScriptFile:function(target) {var oldScriptFile=this._scriptFileForTarget.get(target);var newScriptFile=WebInspector.debuggerWorkspaceBinding.scriptFile(this.uiSourceCode(),target);this._scriptFileForTarget.remove(target);if(oldScriptFile){oldScriptFile.removeEventListener(WebInspector.ResourceScriptFile.Events.DidMergeToVM,this._didMergeToVM,this);oldScriptFile.removeEventListener(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM,this._didDivergeFromVM,this);if(this._muted&&!this.uiSourceCode().isDirty()) this._restoreBreakpointsIfConsistentScripts();} if(newScriptFile) this._scriptFileForTarget.set(target,newScriptFile);this._updateDivergedInfobar();if(newScriptFile){newScriptFile.addEventListener(WebInspector.ResourceScriptFile.Events.DidMergeToVM,this._didMergeToVM,this);newScriptFile.addEventListener(WebInspector.ResourceScriptFile.Events.DidDivergeFromVM,this._didDivergeFromVM,this);if(this.loaded) newScriptFile.checkMapping();if(newScriptFile.hasSourceMapURL()){var sourceMapInfobar=WebInspector.Infobar.create(WebInspector.Infobar.Type.Info,WebInspector.UIString("Source Map detected."),WebInspector.settings.createSetting("sourceMapInfobarDisabled",false));if(sourceMapInfobar){sourceMapInfobar.createDetailsRowMessage(WebInspector.UIString("Associated files should be added to the file tree. You can debug these resolved source files as regular JavaScript files."));sourceMapInfobar.createDetailsRowMessage(WebInspector.UIString("Associated files are available via file tree or %s.",WebInspector.shortcutRegistry.shortcutTitleForAction("sources.go-to-source")));this.attachInfobars([sourceMapInfobar]);}}}},onTextEditorContentLoaded:function() {WebInspector.UISourceCodeFrame.prototype.onTextEditorContentLoaded.call(this);if(this._executionLocation) this.setExecutionLocation(this._executionLocation);var breakpointLocations=this._breakpointManager.breakpointLocationsForUISourceCode(this.uiSourceCode());for(var i=0;i<breakpointLocations.length;++i) this._breakpointAdded({data:breakpointLocations[i]});var scriptFiles=this._scriptFileForTarget.valuesArray();for(var i=0;i<scriptFiles.length;++i) scriptFiles[i].checkMapping();this._updateLinesWithoutMappingHighlight();this._detectMinified();},_detectMinified:function() {if(this._prettyPrintInfobar) return;var minified=false;for(var i=0;i<10&&i<this.textEditor.linesCount;++i){var line=this.textEditor.line(i);if(line.startsWith("//#")) continue;if(line.length>500){minified=true;break;}} if(!minified) return;this._prettyPrintInfobar=WebInspector.Infobar.create(WebInspector.Infobar.Type.Info,WebInspector.UIString("Pretty-print this minified file?"),WebInspector.settings.createSetting("prettyPrintInfobarDisabled",false));if(!this._prettyPrintInfobar) return;this._prettyPrintInfobar.setCloseCallback(()=>delete this._prettyPrintInfobar);var toolbar=new WebInspector.Toolbar("");var button=new WebInspector.ToolbarButton("","format-toolbar-item") toolbar.appendToolbarItem(button);toolbar.element.style.display="inline-block";toolbar.element.style.verticalAlign="middle";toolbar.element.style.marginBottom="3px";toolbar.element.style.pointerEvents="none";var element=this._prettyPrintInfobar.createDetailsRowMessage();element.appendChild(WebInspector.formatLocalized("You can click the %s button on the bottom status bar, and continue debugging with the new formatted source.",[toolbar.element]));this.attachInfobars([this._prettyPrintInfobar]);},_handleGutterClick:function(event) {if(this._muted) return;var eventData=(event.data);var lineNumber=eventData.lineNumber;var eventObject=eventData.event;if(eventObject.button!=0||eventObject.altKey||eventObject.ctrlKey||eventObject.metaKey) return;this._toggleBreakpoint(lineNumber,eventObject.shiftKey);eventObject.consume(true);},_toggleBreakpoint:function(lineNumber,onlyDisable) {var breakpoint=this._breakpointManager.findBreakpointOnLine(this.uiSourceCode(),lineNumber);if(breakpoint){if(onlyDisable) breakpoint.setEnabled(!breakpoint.enabled());else breakpoint.remove();}else this._createNewBreakpoint(lineNumber,0,"",true);},_createNewBreakpoint:function(lineNumber,columnNumber,condition,enabled) {this._setBreakpoint(lineNumber,columnNumber,condition,enabled);WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ScriptsBreakpointSet);},toggleBreakpointOnCurrentLine:function() {if(this._muted) return;var selection=this.textEditor.selection();if(!selection) return;this._toggleBreakpoint(selection.startLine,false);},_setBreakpoint:function(lineNumber,columnNumber,condition,enabled) {this._breakpointManager.setBreakpoint(this.uiSourceCode(),lineNumber,columnNumber,condition,enabled);},dispose:function() {this._breakpointManager.removeEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded,this._breakpointAdded,this);this._breakpointManager.removeEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved,this._breakpointRemoved,this);this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged,this._onSourceMappingChanged,this);this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);this.uiSourceCode().removeEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._showBlackboxInfobarIfNeeded,this);WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListener(this._showBlackboxInfobarIfNeeded,this);WebInspector.moduleSetting("skipContentScripts").removeChangeListener(this._showBlackboxInfobarIfNeeded,this);WebInspector.UISourceCodeFrame.prototype.dispose.call(this);},__proto__:WebInspector.UISourceCodeFrame.prototype};WebInspector.CSSSourceFrame=function(uiSourceCode) {WebInspector.UISourceCodeFrame.call(this,uiSourceCode);this.textEditor.setAutocompleteDelegate(new WebInspector.CSSSourceFrame.AutocompleteDelegate());this._registerShortcuts();} WebInspector.CSSSourceFrame.prototype={_registerShortcuts:function() {var shortcutKeys=WebInspector.ShortcutsScreen.SourcesPanelShortcuts;for(var i=0;i<shortcutKeys.IncreaseCSSUnitByOne.length;++i) this.addShortcut(shortcutKeys.IncreaseCSSUnitByOne[i].key,this._handleUnitModification.bind(this,1));for(var i=0;i<shortcutKeys.DecreaseCSSUnitByOne.length;++i) this.addShortcut(shortcutKeys.DecreaseCSSUnitByOne[i].key,this._handleUnitModification.bind(this,-1));for(var i=0;i<shortcutKeys.IncreaseCSSUnitByTen.length;++i) this.addShortcut(shortcutKeys.IncreaseCSSUnitByTen[i].key,this._handleUnitModification.bind(this,10));for(var i=0;i<shortcutKeys.DecreaseCSSUnitByTen.length;++i) this.addShortcut(shortcutKeys.DecreaseCSSUnitByTen[i].key,this._handleUnitModification.bind(this,-10));},_modifyUnit:function(unit,change) {var unitValue=parseInt(unit,10);if(isNaN(unitValue)) return null;var tail=unit.substring((unitValue).toString().length);return String.sprintf("%d%s",unitValue+change,tail);},_handleUnitModification:function(change) {var selection=this.textEditor.selection().normalize();var token=this.textEditor.tokenAtTextPosition(selection.startLine,selection.startColumn);if(!token){if(selection.startColumn>0) token=this.textEditor.tokenAtTextPosition(selection.startLine,selection.startColumn-1);if(!token) return false;} if(token.type!=="css-number") return false;var cssUnitRange=new WebInspector.TextRange(selection.startLine,token.startColumn,selection.startLine,token.endColumn);var cssUnitText=this.textEditor.copyRange(cssUnitRange);var newUnitText=this._modifyUnit(cssUnitText,change);if(!newUnitText) return false;this.textEditor.editRange(cssUnitRange,newUnitText);selection.startColumn=token.startColumn;selection.endColumn=selection.startColumn+newUnitText.length;this.textEditor.setSelection(selection);return true;},__proto__:WebInspector.UISourceCodeFrame.prototype} WebInspector.CSSSourceFrame.AutocompleteDelegate=function() {this._simpleDelegate=new WebInspector.SimpleAutocompleteDelegate(".-$");} WebInspector.CSSSourceFrame._backtrackDepth=10;WebInspector.CSSSourceFrame.AutocompleteDelegate.prototype={initialize:function(editor) {this._simpleDelegate.initialize(editor);},dispose:function() {this._simpleDelegate.dispose();},substituteRange:function(editor,lineNumber,columnNumber) {return this._simpleDelegate.substituteRange(editor,lineNumber,columnNumber);},_backtrackPropertyToken:function(editor,lineNumber,columnNumber) {var tokenPosition=columnNumber;var line=editor.line(lineNumber);var seenColumn=false;for(var i=0;i<WebInspector.CSSSourceFrame._backtrackDepth&&tokenPosition>=0;++i){var token=editor.tokenAtTextPosition(lineNumber,tokenPosition);if(!token) return null;if(token.type==="css-property") return seenColumn?token:null;if(token.type&&!(token.type.indexOf("whitespace")!==-1||token.type.startsWith("css-comment"))) return null;if(!token.type&&line.substring(token.startColumn,token.endColumn)===":"){if(!seenColumn) seenColumn=true;else return null;} tokenPosition=token.startColumn-1;} return null;},wordsWithPrefix:function(editor,prefixRange,substituteRange) {var prefix=editor.copyRange(prefixRange);if(prefix.startsWith("$")) return this._simpleDelegate.wordsWithPrefix(editor,prefixRange,substituteRange);var propertyToken=this._backtrackPropertyToken(editor,prefixRange.startLine,prefixRange.startColumn-1);if(!propertyToken) return this._simpleDelegate.wordsWithPrefix(editor,prefixRange,substituteRange);var line=editor.line(prefixRange.startLine);var tokenContent=line.substring(propertyToken.startColumn,propertyToken.endColumn);var keywords=WebInspector.CSSMetadata.keywordsForProperty(tokenContent);return keywords.startsWith(prefix);},};WebInspector.NavigatorView=function() {WebInspector.VBox.call(this);this._scriptsTree=new TreeOutlineInShadow();this._scriptsTree.registerRequiredCSS("sources/navigatorView.css");this._scriptsTree.setComparator(WebInspector.NavigatorView._treeElementsCompare);this.element.appendChild(this._scriptsTree.element);this.setDefaultFocusedElement(this._scriptsTree.element);this._uiSourceCodeNodes=new Map();this._subfolderNodes=new Map();this._rootNode=new WebInspector.NavigatorRootTreeNode(this);this._rootNode.populate();this._frameNodes=new Map();this.element.addEventListener("contextmenu",this.handleContextMenu.bind(this),false);this._navigatorGroupByFolderSetting=WebInspector.moduleSetting("navigatorGroupByFolder");this._navigatorGroupByFolderSetting.addChangeListener(this._groupingChanged.bind(this));this._initGrouping();WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.FrameNavigated,this._frameNavigated,this);WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,WebInspector.ResourceTreeModel.EventTypes.FrameDetached,this._frameDetached,this);WebInspector.targetManager.observeTargets(this);} WebInspector.NavigatorView.Events={ItemSelected:"ItemSelected",ItemRenamed:"ItemRenamed",} WebInspector.NavigatorView.Types={Category:"category",Domain:"domain",File:"file",FileSystem:"fs",FileSystemFolder:"fs-folder",Frame:"frame",NetworkFolder:"nw-folder",Root:"root",SourceMapFolder:"sm-folder",Worker:"worker"} WebInspector.NavigatorView._treeElementOrder=function(treeElement) {if(treeElement._boostOrder) return 0;if(!WebInspector.NavigatorView._typeOrders){var weights={};var types=WebInspector.NavigatorView.Types;weights[types.Root]=1;weights[types.Category]=1;weights[types.Domain]=10;weights[types.FileSystemFolder]=1;weights[types.NetworkFolder]=1;weights[types.SourceMapFolder]=2;weights[types.File]=10;weights[types.Frame]=70;weights[types.Worker]=90;weights[types.FileSystem]=100;WebInspector.NavigatorView._typeOrders=weights;} var order=WebInspector.NavigatorView._typeOrders[treeElement._nodeType];if(treeElement._uiSourceCode){var contentType=treeElement._uiSourceCode.contentType();if(contentType.isDocument()) order+=3;else if(contentType.isScript()) order+=5;else if(contentType.isStyleSheet()) order+=10;else order+=15;} return order;} WebInspector.NavigatorView.appendAddFolderItem=function(contextMenu) {function addFolder() {WebInspector.isolatedFileSystemManager.addFileSystem();} var addFolderLabel=WebInspector.UIString.capitalize("Add ^folder to ^workspace");contextMenu.appendItem(addFolderLabel,addFolder);} WebInspector.NavigatorView.appendSearchItem=function(contextMenu,path) {function searchPath() {WebInspector.AdvancedSearchView.openSearch("",path.trim());} var searchLabel=WebInspector.UIString.capitalize("Search in ^folder");if(!path||!path.trim()){path="*";searchLabel=WebInspector.UIString.capitalize("Search in ^all ^files");} contextMenu.appendItem(searchLabel,searchPath);} WebInspector.NavigatorView.prototype={setWorkspace:function(workspace) {this._workspace=workspace;this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved.bind(this),this);},wasShown:function() {if(this._loaded) return;this._loaded=true;this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));},accept:function(uiSourceCode) {return!uiSourceCode.isFromServiceProject();},_uiSourceCodeFrame:function(uiSourceCode) {var target=WebInspector.NetworkProject.targetForProject(uiSourceCode.project());if(!target) return null;return WebInspector.NetworkProject.frameForProject(uiSourceCode.project())||target.resourceTreeModel.mainFrame;},_addUISourceCode:function(uiSourceCode) {if(!this.accept(uiSourceCode)) return;var isFromSourceMap=uiSourceCode.contentType().isFromSourceMap();var path;if(uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem) path=WebInspector.FileSystemWorkspaceBinding.relativePath(uiSourceCode).slice(0,-1);else path=WebInspector.ParsedURL.splitURLIntoPathComponents(uiSourceCode.url()).slice(1,-1);var project=uiSourceCode.project();var target=WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);var frame=this._uiSourceCodeFrame(uiSourceCode);var folderNode=this._folderNode(uiSourceCode,project,target,frame,uiSourceCode.origin(),path,isFromSourceMap);var uiSourceCodeNode=new WebInspector.NavigatorUISourceCodeTreeNode(this,uiSourceCode);this._uiSourceCodeNodes.set(uiSourceCode,uiSourceCodeNode);folderNode.appendChild(uiSourceCodeNode);this.uiSourceCodeAdded(uiSourceCode);},uiSourceCodeAdded:function(uiSourceCode) {},_uiSourceCodeAdded:function(event) {var uiSourceCode=(event.data);this._addUISourceCode(uiSourceCode);},_uiSourceCodeRemoved:function(event) {var uiSourceCode=(event.data);this._removeUISourceCode(uiSourceCode);},_projectRemoved:function(event) {var project=(event.data);var frame=WebInspector.NetworkProject.frameForProject(project);if(frame) this._discardFrame(frame);var uiSourceCodes=project.uiSourceCodes();for(var i=0;i<uiSourceCodes.length;++i) this._removeUISourceCode(uiSourceCodes[i]);},_folderNodeId:function(project,target,frame,projectOrigin,path) {var targetId=target?target.id():"";var projectId=project.type()===WebInspector.projectTypes.FileSystem?project.id():"";var frameId=this._groupByFrame&&frame?frame.id:"";return targetId+":"+projectId+":"+frameId+":"+projectOrigin+":"+path;},_folderNode:function(uiSourceCode,project,target,frame,projectOrigin,path,fromSourceMap) {if(project.type()===WebInspector.projectTypes.Snippets) return this._rootNode;if(target&&!this._groupByFolder&&!fromSourceMap) return this._domainNode(uiSourceCode,project,target,frame,projectOrigin);var folderPath=path.join("/");var folderId=this._folderNodeId(project,target,frame,projectOrigin,folderPath);var folderNode=this._subfolderNodes.get(folderId);if(folderNode) return folderNode;if(!path.length){if(target) return this._domainNode(uiSourceCode,project,target,frame,projectOrigin);var fileSystemNode=this._rootNode.child(project.id());if(!fileSystemNode){fileSystemNode=new WebInspector.NavigatorGroupTreeNode(this,project,project.id(),WebInspector.NavigatorView.Types.FileSystem,project.displayName());this._rootNode.appendChild(fileSystemNode);} return fileSystemNode;} var parentNode=this._folderNode(uiSourceCode,project,target,frame,projectOrigin,path.slice(0,-1),fromSourceMap);var type=fromSourceMap?WebInspector.NavigatorView.Types.SourceMapFolder:WebInspector.NavigatorView.Types.NetworkFolder;if(project.type()===WebInspector.projectTypes.FileSystem) type=WebInspector.NavigatorView.Types.FileSystemFolder;var name=path[path.length-1];folderNode=new WebInspector.NavigatorFolderTreeNode(this,project,folderId,type,folderPath,name);this._subfolderNodes.set(folderId,folderNode);parentNode.appendChild(folderNode);return folderNode;},_domainNode:function(uiSourceCode,project,target,frame,projectOrigin) {var frameNode=this._frameNode(project,target,frame);if(!this._groupByDomain) return frameNode;var domainNode=frameNode.child(projectOrigin);if(domainNode) return domainNode;domainNode=new WebInspector.NavigatorGroupTreeNode(this,project,projectOrigin,WebInspector.NavigatorView.Types.Domain,this._computeProjectDisplayName(target,projectOrigin));if(frame&&projectOrigin===WebInspector.ParsedURL.extractOrigin(frame.url)) domainNode.treeNode()._boostOrder=true;frameNode.appendChild(domainNode);return domainNode;},_frameNode:function(project,target,frame) {if(!this._groupByFrame||!frame) return this._targetNode(project,target);var frameNode=this._frameNodes.get(frame);if(frameNode) return frameNode;frameNode=new WebInspector.NavigatorGroupTreeNode(this,project,target.id()+":"+frame.id,WebInspector.NavigatorView.Types.Frame,frame.displayName());frameNode.setHoverCallback(hoverCallback);this._frameNodes.set(frame,frameNode);this._frameNode(project,target,frame.parentFrame).appendChild(frameNode);if(!frame.parentFrame) frameNode.treeNode()._boostOrder=true;function hoverCallback(hovered) {if(hovered){var domModel=WebInspector.DOMModel.fromTarget(target);if(domModel) domModel.highlightFrame(frame.id);}else{WebInspector.DOMModel.hideDOMNodeHighlight();}} return frameNode;},_targetNode:function(project,target) {if(target===WebInspector.targetManager.mainTarget()) return this._rootNode;var targetNode=this._rootNode.child("target:"+target.id());if(!targetNode){targetNode=new WebInspector.NavigatorGroupTreeNode(this,project,"target:"+target.id(),target.isWorker()?WebInspector.NavigatorView.Types.Worker:WebInspector.NavigatorView.Types.NetworkFolder,target.name());this._rootNode.appendChild(targetNode);} return targetNode;},_computeProjectDisplayName:function(target,projectOrigin) {for(var context of target.runtimeModel.executionContexts()){if(context.name&&context.origin&&projectOrigin.startsWith(context.origin)) return context.name;} if(!projectOrigin) return WebInspector.UIString("(no domain)");var parsedURL=new WebInspector.ParsedURL(projectOrigin);var prettyURL=parsedURL.isValid?parsedURL.host+(parsedURL.port?(":"+parsedURL.port):""):"";return(prettyURL||projectOrigin);},revealUISourceCode:function(uiSourceCode,select) {var node=this._uiSourceCodeNodes.get(uiSourceCode);if(!node) return;if(this._scriptsTree.selectedTreeElement) this._scriptsTree.selectedTreeElement.deselect();this._lastSelectedUISourceCode=uiSourceCode;node.reveal(select);},_sourceSelected:function(uiSourceCode,focusSource) {this._lastSelectedUISourceCode=uiSourceCode;var data={uiSourceCode:uiSourceCode,focusSource:focusSource};this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemSelected,data);},sourceDeleted:function(uiSourceCode) {},_removeUISourceCode:function(uiSourceCode) {var node=this._uiSourceCodeNodes.get(uiSourceCode);if(!node) return;var project=uiSourceCode.project();var target=WebInspector.NetworkProject.targetForUISourceCode(uiSourceCode);var frame=this._uiSourceCodeFrame(uiSourceCode);var parentNode=node.parent;this._uiSourceCodeNodes.delete(uiSourceCode);parentNode.removeChild(node);node=parentNode;while(node){parentNode=node.parent;if(!parentNode||!node.isEmpty()) break;if(!(node instanceof WebInspector.NavigatorGroupTreeNode||node instanceof WebInspector.NavigatorFolderTreeNode)) break;var folderId=this._folderNodeId(project,target,frame,uiSourceCode.origin(),node._folderPath);this._subfolderNodes.delete(folderId);parentNode.removeChild(node);node=parentNode;}},reset:function() {var nodes=this._uiSourceCodeNodes.valuesArray();for(var i=0;i<nodes.length;++i) nodes[i].dispose();this._scriptsTree.removeChildren();this._uiSourceCodeNodes.clear();this._subfolderNodes.clear();this._frameNodes.clear();this._rootNode.reset();},handleContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);WebInspector.NavigatorView.appendAddFolderItem(contextMenu);contextMenu.show();},_handleContextMenuRefresh:function(project,path) {project.refresh(path);},_handleContextMenuCreate:function(project,path,uiSourceCode) {this.create(project,path,uiSourceCode);},_handleContextMenuRename:function(uiSourceCode) {this.rename(uiSourceCode,false);},_handleContextMenuExclude:function(project,path) {var shouldExclude=window.confirm(WebInspector.UIString("Are you sure you want to exclude this folder?"));if(shouldExclude){WebInspector.startBatchUpdate();project.excludeFolder(WebInspector.FileSystemWorkspaceBinding.completeURL(project,path));WebInspector.endBatchUpdate();}},_handleContextMenuDelete:function(uiSourceCode) {var shouldDelete=window.confirm(WebInspector.UIString("Are you sure you want to delete this file?"));if(shouldDelete) uiSourceCode.project().deleteFile(uiSourceCode.url());},handleFileContextMenu:function(event,uiSourceCode) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendApplicableItems(uiSourceCode);contextMenu.appendSeparator();var project=uiSourceCode.project();if(project.type()===WebInspector.projectTypes.FileSystem){var parentURL=uiSourceCode.parentURL();contextMenu.appendItem(WebInspector.UIString.capitalize("Rename\u2026"),this._handleContextMenuRename.bind(this,uiSourceCode));contextMenu.appendItem(WebInspector.UIString.capitalize("Make a ^copy\u2026"),this._handleContextMenuCreate.bind(this,project,parentURL,uiSourceCode));contextMenu.appendItem(WebInspector.UIString.capitalize("Delete"),this._handleContextMenuDelete.bind(this,uiSourceCode));contextMenu.appendSeparator();} contextMenu.show();},handleFolderContextMenu:function(event,node) {var path=node._folderPath;var project=node._project;var contextMenu=new WebInspector.ContextMenu(event);WebInspector.NavigatorView.appendSearchItem(contextMenu,path);contextMenu.appendSeparator();if(project&&project.type()===WebInspector.projectTypes.FileSystem){contextMenu.appendItem(WebInspector.UIString.capitalize("Refresh"),this._handleContextMenuRefresh.bind(this,project,path));if(node instanceof WebInspector.NavigatorFolderTreeNode){contextMenu.appendItem(WebInspector.UIString.capitalize("New ^file"),this._handleContextMenuCreate.bind(this,project,path));contextMenu.appendItem(WebInspector.UIString.capitalize("Exclude ^folder"),this._handleContextMenuExclude.bind(this,project,path));}} contextMenu.appendSeparator();WebInspector.NavigatorView.appendAddFolderItem(contextMenu);function removeFolder() {var shouldRemove=window.confirm(WebInspector.UIString("Are you sure you want to remove this folder?"));if(shouldRemove) project.remove();} if(project&&project.type()===WebInspector.projectTypes.FileSystem){var removeFolderLabel=WebInspector.UIString.capitalize("Remove ^folder from ^workspace");contextMenu.appendItem(removeFolderLabel,removeFolder);} contextMenu.show();},rename:function(uiSourceCode,deleteIfCanceled) {var node=this._uiSourceCodeNodes.get(uiSourceCode);console.assert(node);node.rename(callback.bind(this));function callback(committed) {if(!committed){if(deleteIfCanceled) uiSourceCode.remove();return;} this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemRenamed,uiSourceCode);this._sourceSelected(uiSourceCode,true);}},create:function(project,path,uiSourceCodeToCopy) {var filePath;var uiSourceCode;function contentLoaded(content) {createFile.call(this,content||"");} if(uiSourceCodeToCopy) uiSourceCodeToCopy.requestContent().then(contentLoaded.bind(this));else createFile.call(this);function createFile(content) {project.createFile(path,null,content||"",fileCreated.bind(this));} function fileCreated(uiSourceCode) {if(!uiSourceCode) return;this._sourceSelected(uiSourceCode,false);this.revealUISourceCode(uiSourceCode,true);this.rename(uiSourceCode,true);}},_groupingChanged:function() {this.reset();this._initGrouping();this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));},_initGrouping:function() {this._groupByFrame=true;this._groupByDomain=this._navigatorGroupByFolderSetting.get();this._groupByFolder=this._groupByDomain;},_resetForTest:function() {this.reset();this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));},_frameNavigated:function(event) {var frame=(event.data);var node=this._frameNodes.get(frame);if(!node) return;node.treeNode().title=frame.displayName();for(var child of frame.childFrames) this._discardFrame(child);},_frameDetached:function(event) {var frame=(event.data);this._discardFrame(frame);},_discardFrame:function(frame) {var node=this._frameNodes.get(frame);if(!node) return;if(node.parent) node.parent.removeChild(node);this._frameNodes.delete(frame);for(var child of frame.childFrames) this._discardFrame(child);},targetAdded:function(target) {},targetRemoved:function(target) {var targetNode=this._rootNode.child("target:"+target.id());if(targetNode) this._rootNode.removeChild(targetNode);},__proto__:WebInspector.VBox.prototype} WebInspector.NavigatorView._treeElementsCompare=function compare(treeElement1,treeElement2) {var typeWeight1=WebInspector.NavigatorView._treeElementOrder(treeElement1);var typeWeight2=WebInspector.NavigatorView._treeElementOrder(treeElement2);var result;if(typeWeight1>typeWeight2) return 1;if(typeWeight1<typeWeight2) return-1;var title1=(treeElement1.title);var title2=(treeElement2.title);return title1.compareTo(title2);} WebInspector.NavigatorFolderTreeElement=function(navigatorView,type,title,hoverCallback) {TreeElement.call(this,"",true);this.listItemElement.classList.add("navigator-"+type+"-tree-item","navigator-folder-tree-item");this._nodeType=type;this.title=title;this.tooltip=title;this.createIcon();this._navigatorView=navigatorView;this._hoverCallback=hoverCallback;} WebInspector.NavigatorFolderTreeElement.prototype={onpopulate:function() {this._node.populate();},onattach:function() {this.collapse();this._node.onattach();this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),false);this.listItemElement.addEventListener("mousemove",this._mouseMove.bind(this),false);this.listItemElement.addEventListener("mouseleave",this._mouseLeave.bind(this),false);},setNode:function(node) {this._node=node;var paths=[];while(node&&!node.isRoot()){paths.push(node._title);node=node.parent;} paths.reverse();this.tooltip=paths.join("/");},_handleContextMenuEvent:function(event) {if(!this._node) return;this.select();this._navigatorView.handleFolderContextMenu(event,this._node);},_mouseMove:function(event) {if(this._hovered||!this._hoverCallback) return;this._hovered=true;this._hoverCallback(true);},_mouseLeave:function(event) {if(!this._hoverCallback) return;this._hovered=false;this._hoverCallback(false);},__proto__:TreeElement.prototype} WebInspector.NavigatorSourceTreeElement=function(navigatorView,uiSourceCode,title) {TreeElement.call(this,"",false);this._nodeType=WebInspector.NavigatorView.Types.File;this.title=title;this.listItemElement.classList.add("navigator-"+uiSourceCode.contentType().name()+"-tree-item","navigator-file-tree-item");this.tooltip=uiSourceCode.url();this.createIcon();this._navigatorView=navigatorView;this._uiSourceCode=uiSourceCode;} WebInspector.NavigatorSourceTreeElement.prototype={get uiSourceCode() {return this._uiSourceCode;},onattach:function() {this.listItemElement.draggable=true;this.listItemElement.addEventListener("click",this._onclick.bind(this),false);this.listItemElement.addEventListener("contextmenu",this._handleContextMenuEvent.bind(this),false);this.listItemElement.addEventListener("mousedown",this._onmousedown.bind(this),false);this.listItemElement.addEventListener("dragstart",this._ondragstart.bind(this),false);},_onmousedown:function(event) {if(event.which===1) this._uiSourceCode.requestContent().then(callback.bind(this));function callback(content) {this._warmedUpContent=content;}},_shouldRenameOnMouseDown:function() {if(!this._uiSourceCode.canRename()) return false;var isSelected=this===this.treeOutline.selectedTreeElement;var document=this.treeOutline.element.ownerDocument;var isFocused=this.treeOutline.element.isSelfOrAncestor(document.activeElement);return isSelected&&isFocused&&!WebInspector.isBeingEdited(this.treeOutline.element);},selectOnMouseDown:function(event) {if(event.which!==1||!this._shouldRenameOnMouseDown()){TreeElement.prototype.selectOnMouseDown.call(this,event);return;} setTimeout(rename.bind(this),300);function rename() {if(this._shouldRenameOnMouseDown()) this._navigatorView.rename(this.uiSourceCode,false);}},_ondragstart:function(event) {event.dataTransfer.setData("text/plain",this._warmedUpContent);event.dataTransfer.effectAllowed="copy";return true;},onspace:function() {this._navigatorView._sourceSelected(this.uiSourceCode,true);return true;},_onclick:function(event) {this._navigatorView._sourceSelected(this.uiSourceCode,false);},ondblclick:function(event) {var middleClick=event.button===1;this._navigatorView._sourceSelected(this.uiSourceCode,!middleClick);return false;},onenter:function() {this._navigatorView._sourceSelected(this.uiSourceCode,true);return true;},ondelete:function() {this._navigatorView.sourceDeleted(this.uiSourceCode);return true;},_handleContextMenuEvent:function(event) {this.select();this._navigatorView.handleFileContextMenu(event,this._uiSourceCode);},__proto__:TreeElement.prototype} WebInspector.NavigatorTreeNode=function(id,type) {this.id=id;this._type=type;this._children=new Map();} WebInspector.NavigatorTreeNode.prototype={treeNode:function(){throw"Not implemented";},dispose:function(){},isRoot:function() {return false;},hasChildren:function() {return true;},onattach:function() {},populate:function() {if(this.isPopulated()) return;if(this.parent) this.parent.populate();this._populated=true;this.wasPopulated();},wasPopulated:function() {var children=this.children();for(var i=0;i<children.length;++i) this.treeNode().appendChild((children[i].treeNode()));},didAddChild:function(node) {if(this.isPopulated()) this.treeNode().appendChild((node.treeNode()));},willRemoveChild:function(node) {if(this.isPopulated()) this.treeNode().removeChild((node.treeNode()));},isPopulated:function() {return this._populated;},isEmpty:function() {return!this._children.size;},children:function() {return this._children.valuesArray();},child:function(id) {return this._children.get(id)||null;},appendChild:function(node) {this._children.set(node.id,node);node.parent=this;this.didAddChild(node);},removeChild:function(node) {this.willRemoveChild(node);this._children.remove(node.id);delete node.parent;node.dispose();},reset:function() {this._children.clear();}} WebInspector.NavigatorRootTreeNode=function(navigatorView) {WebInspector.NavigatorTreeNode.call(this,"",WebInspector.NavigatorView.Types.Root);this._navigatorView=navigatorView;} WebInspector.NavigatorRootTreeNode.prototype={isRoot:function() {return true;},treeNode:function() {return this._navigatorView._scriptsTree.rootElement();},__proto__:WebInspector.NavigatorTreeNode.prototype} WebInspector.NavigatorUISourceCodeTreeNode=function(navigatorView,uiSourceCode) {WebInspector.NavigatorTreeNode.call(this,uiSourceCode.project().id()+":"+uiSourceCode.url(),WebInspector.NavigatorView.Types.File);this._navigatorView=navigatorView;this._uiSourceCode=uiSourceCode;this._treeElement=null;} WebInspector.NavigatorUISourceCodeTreeNode.prototype={uiSourceCode:function() {return this._uiSourceCode;},treeNode:function() {if(this._treeElement) return this._treeElement;this._treeElement=new WebInspector.NavigatorSourceTreeElement(this._navigatorView,this._uiSourceCode,"");this.updateTitle();this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._titleChanged,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);return this._treeElement;},updateTitle:function(ignoreIsDirty) {if(!this._treeElement) return;var titleText=this._uiSourceCode.displayName();if(!ignoreIsDirty&&(this._uiSourceCode.isDirty()||this._uiSourceCode.hasUnsavedCommittedChanges())) titleText="*"+titleText;this._treeElement.title=titleText;var tooltip=this._uiSourceCode.url();if(this._uiSourceCode.contentType().isFromSourceMap()) tooltip=WebInspector.UIString("%s (from source map)",this._uiSourceCode.displayName());this._treeElement.tooltip=tooltip;},hasChildren:function() {return false;},dispose:function() {if(!this._treeElement) return;this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._titleChanged,this);this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this);this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this);},_titleChanged:function(event) {this.updateTitle();},_workingCopyChanged:function(event) {this.updateTitle();},_workingCopyCommitted:function(event) {this.updateTitle();},reveal:function(select) {this.parent.populate();this.parent.treeNode().expand();this._treeElement.reveal();if(select) this._treeElement.select(true);},rename:function(callback) {if(!this._treeElement) return;var treeOutlineElement=this._treeElement.treeOutline.element;WebInspector.markBeingEdited(treeOutlineElement,true);function commitHandler(element,newTitle,oldTitle) {if(newTitle!==oldTitle){this._treeElement.title=newTitle;this._uiSourceCode.rename(newTitle,renameCallback.bind(this));return;} afterEditing.call(this,true);} function renameCallback(success) {if(!success){WebInspector.markBeingEdited(treeOutlineElement,false);this.updateTitle();this.rename(callback);return;} afterEditing.call(this,true);} function afterEditing(committed) {WebInspector.markBeingEdited(treeOutlineElement,false);this.updateTitle();this._treeElement.treeOutline.focus();if(callback) callback(committed);} this.updateTitle(true);this._treeElement.startEditingTitle(new WebInspector.InplaceEditor.Config(commitHandler.bind(this),afterEditing.bind(this,false)));},__proto__:WebInspector.NavigatorTreeNode.prototype} WebInspector.NavigatorFolderTreeNode=function(navigatorView,project,id,type,folderPath,title) {WebInspector.NavigatorTreeNode.call(this,id,type);this._navigatorView=navigatorView;this._project=project;this._folderPath=folderPath;this._title=title;} WebInspector.NavigatorFolderTreeNode.prototype={treeNode:function() {if(this._treeElement) return this._treeElement;this._treeElement=this._createTreeElement(this._title,this);return this._treeElement;},_createTreeElement:function(title,node) {if(this._project.type()!==WebInspector.projectTypes.FileSystem){try{title=decodeURI(title);}catch(e){}} var treeElement=new WebInspector.NavigatorFolderTreeElement(this._navigatorView,this._type,title);treeElement.setNode(node);return treeElement;},wasPopulated:function() {if(!this._treeElement||this._treeElement._node!==this) return;this._addChildrenRecursive();},_addChildrenRecursive:function() {var children=this.children();for(var i=0;i<children.length;++i){var child=children[i];this.didAddChild(child);if(child instanceof WebInspector.NavigatorFolderTreeNode) child._addChildrenRecursive();}},_shouldMerge:function(node) {return this._type!==WebInspector.NavigatorView.Types.Domain&&node instanceof WebInspector.NavigatorFolderTreeNode;},didAddChild:function(node) {function titleForNode(node) {return node._title;} if(!this._treeElement) return;var children=this.children();if(children.length===1&&this._shouldMerge(node)){node._isMerged=true;this._treeElement.title=this._treeElement.title+"/"+node._title;node._treeElement=this._treeElement;this._treeElement.setNode(node);return;} var oldNode;if(children.length===2) oldNode=children[0]!==node?children[0]:children[1];if(oldNode&&oldNode._isMerged){delete oldNode._isMerged;var mergedToNodes=[];mergedToNodes.push(this);var treeNode=this;while(treeNode._isMerged){treeNode=treeNode.parent;mergedToNodes.push(treeNode);} mergedToNodes.reverse();var titleText=mergedToNodes.map(titleForNode).join("/");var nodes=[];treeNode=oldNode;do{nodes.push(treeNode);children=treeNode.children();treeNode=children.length===1?children[0]:null;}while(treeNode&&treeNode._isMerged);if(!this.isPopulated()){this._treeElement.title=titleText;this._treeElement.setNode(this);for(var i=0;i<nodes.length;++i){delete nodes[i]._treeElement;delete nodes[i]._isMerged;} return;} var oldTreeElement=this._treeElement;var treeElement=this._createTreeElement(titleText,this);for(var i=0;i<mergedToNodes.length;++i) mergedToNodes[i]._treeElement=treeElement;oldTreeElement.parent.appendChild(treeElement);oldTreeElement.setNode(nodes[nodes.length-1]);oldTreeElement.title=nodes.map(titleForNode).join("/");oldTreeElement.parent.removeChild(oldTreeElement);this._treeElement.appendChild(oldTreeElement);if(oldTreeElement.expanded) treeElement.expand();} if(this.isPopulated()) this._treeElement.appendChild(node.treeNode());},willRemoveChild:function(node) {if(node._isMerged||!this.isPopulated()) return;this._treeElement.removeChild(node._treeElement);},__proto__:WebInspector.NavigatorTreeNode.prototype} WebInspector.NavigatorGroupTreeNode=function(navigatorView,project,id,type,title) {WebInspector.NavigatorTreeNode.call(this,id,type);this._project=project;this._navigatorView=navigatorView;this._title=title;this.populate();} WebInspector.NavigatorGroupTreeNode.prototype={setHoverCallback:function(hoverCallback) {this._hoverCallback=hoverCallback;},treeNode:function() {if(this._treeElement) return this._treeElement;this._treeElement=new WebInspector.NavigatorFolderTreeElement(this._navigatorView,this._type,this._title,this._hoverCallback);this._treeElement.setNode(this);return this._treeElement;},__proto__:WebInspector.NavigatorTreeNode.prototype};WebInspector.RevisionHistoryView=function() {WebInspector.VBox.call(this);this.registerRequiredCSS("sources/revisionHistory.css");this.element.classList.add("revision-history-drawer");this._uiSourceCodeItems=new Map();this._treeOutline=new TreeOutline();this._treeOutline.element.classList.add("outline-disclosure");this.element.appendChild(this._treeOutline.element);function populateRevisions(uiSourceCode) {if(uiSourceCode.history.length) this._createUISourceCodeItem(uiSourceCode);} WebInspector.workspace.uiSourceCodes().forEach(populateRevisions.bind(this));WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommittedByUser,this._revisionAdded,this);WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved,this);} WebInspector.RevisionHistoryView.showHistory=function(uiSourceCode) {function revealSource(view) {console.assert(view&&view instanceof WebInspector.RevisionHistoryView);var historyView=(view);historyView._revealUISourceCode(uiSourceCode);} WebInspector.inspectorView.showViewInDrawer("sources.history").then(revealSource);} WebInspector.RevisionHistoryView.prototype={_createUISourceCodeItem:function(uiSourceCode) {var uiSourceCodeItem=new TreeElement(uiSourceCode.displayName(),true);uiSourceCodeItem.selectable=false;var rootElement=this._treeOutline.rootElement();for(var i=0;i<rootElement.childCount();++i){if(rootElement.childAt(i).title.localeCompare(uiSourceCode.displayName())>0){rootElement.insertChild(uiSourceCodeItem,i);break;}} if(i===rootElement.childCount()) rootElement.appendChild(uiSourceCodeItem);this._uiSourceCodeItems.set(uiSourceCode,uiSourceCodeItem);var revisionCount=uiSourceCode.history.length;for(var i=revisionCount-1;i>=0;--i){var revision=uiSourceCode.history[i];var historyItem=new WebInspector.RevisionHistoryTreeElement(revision,uiSourceCode.history[i-1],i!==revisionCount-1);uiSourceCodeItem.appendChild(historyItem);} var linkItem=new TreeElement();linkItem.selectable=false;uiSourceCodeItem.appendChild(linkItem);var revertToOriginal=linkItem.listItemElement.createChild("span","revision-history-link revision-history-link-row");revertToOriginal.textContent=WebInspector.UIString("apply original content");revertToOriginal.addEventListener("click",this._revertToOriginal.bind(this,uiSourceCode));var clearHistoryElement=uiSourceCodeItem.listItemElement.createChild("span","revision-history-link");clearHistoryElement.textContent=WebInspector.UIString("revert");clearHistoryElement.addEventListener("click",this._clearHistory.bind(this,uiSourceCode));return uiSourceCodeItem;},_revertToOriginal:function(uiSourceCode) {uiSourceCode.revertToOriginal();},_clearHistory:function(uiSourceCode) {uiSourceCode.revertAndClearHistory(this._removeUISourceCode.bind(this));},_revisionAdded:function(event) {var uiSourceCode=(event.data.uiSourceCode);var uiSourceCodeItem=this._uiSourceCodeItems.get(uiSourceCode);if(!uiSourceCodeItem){uiSourceCodeItem=this._createUISourceCodeItem(uiSourceCode);return;} var historyLength=uiSourceCode.history.length;var historyItem=new WebInspector.RevisionHistoryTreeElement(uiSourceCode.history[historyLength-1],uiSourceCode.history[historyLength-2],false);if(uiSourceCodeItem.firstChild()) uiSourceCodeItem.firstChild().allowRevert();uiSourceCodeItem.insertChild(historyItem,0);},_revealUISourceCode:function(uiSourceCode) {var uiSourceCodeItem=this._uiSourceCodeItems.get(uiSourceCode);if(uiSourceCodeItem){uiSourceCodeItem.reveal();uiSourceCodeItem.expand();}},_uiSourceCodeRemoved:function(event) {var uiSourceCode=(event.data);this._removeUISourceCode(uiSourceCode);},_removeUISourceCode:function(uiSourceCode) {var uiSourceCodeItem=this._uiSourceCodeItems.get(uiSourceCode);if(!uiSourceCodeItem) return;this._treeOutline.removeChild(uiSourceCodeItem);this._uiSourceCodeItems.remove(uiSourceCode);},_projectRemoved:function(event) {var project=event.data;project.uiSourceCodes().forEach(this._removeUISourceCode.bind(this));},__proto__:WebInspector.VBox.prototype} WebInspector.RevisionHistoryTreeElement=function(revision,baseRevision,allowRevert) {TreeElement.call(this,revision.timestamp.toLocaleTimeString(),true);this.selectable=false;this._revision=revision;this._baseRevision=baseRevision;this._revertElement=createElement("span");this._revertElement.className="revision-history-link";this._revertElement.textContent=WebInspector.UIString("apply revision content");this._revertElement.addEventListener("click",event=>{this._revision.revertToThis();},false);if(!allowRevert) this._revertElement.classList.add("hidden");} WebInspector.RevisionHistoryTreeElement.prototype={onattach:function() {this.listItemElement.classList.add("revision-history-revision");},onpopulate:function() {this.listItemElement.appendChild(this._revertElement);this.childrenListElement.classList.add("source-code");Promise.all([this._baseRevision?this._baseRevision.requestContent():this._revision.uiSourceCode.requestOriginalContent(),this._revision.requestContent()]).spread(diff.bind(this));function diff(baseContent,newContent) {var baseLines=baseContent.split("\n");var newLines=newContent.split("\n");var opcodes=WebInspector.Diff.lineDiff(baseLines,newLines);var lastWasSeparator=false;var baseLineNumber=0;var newLineNumber=0;for(var idx=0;idx<opcodes.length;idx++){var code=opcodes[idx][0];var rowCount=opcodes[idx][1].length;if(code===WebInspector.Diff.Operation.Equal){baseLineNumber+=rowCount;newLineNumber+=rowCount;if(!lastWasSeparator) this._createLine(null,null," \u2026","separator");lastWasSeparator=true;}else if(code===WebInspector.Diff.Operation.Delete){lastWasSeparator=false;for(var i=0;i<rowCount;++i) this._createLine(baseLineNumber+i,null,baseLines[baseLineNumber+i],"removed");baseLineNumber+=rowCount;}else if(code===WebInspector.Diff.Operation.Insert){lastWasSeparator=false;for(var i=0;i<rowCount;++i) this._createLine(null,newLineNumber+i,newLines[newLineNumber+i],"added");newLineNumber+=rowCount;}}}},oncollapse:function() {this._revertElement.remove();},_createLine:function(baseLineNumber,newLineNumber,lineContent,changeType) {var child=new TreeElement();child.selectable=false;this.appendChild(child);function appendLineNumber(lineNumber) {var numberString=lineNumber!==null?numberToStringWithSpacesPadding(lineNumber+1,4):spacesPadding(4);var lineNumberSpan=createElement("span");lineNumberSpan.classList.add("webkit-line-number");lineNumberSpan.textContent=numberString;child.listItemElement.appendChild(lineNumberSpan);} appendLineNumber(baseLineNumber);appendLineNumber(newLineNumber);var contentSpan=createElement("span");contentSpan.textContent=lineContent;child.listItemElement.appendChild(contentSpan);child.listItemElement.classList.add("revision-history-line");contentSpan.classList.add("revision-history-line-"+changeType);},allowRevert:function() {this._revertElement.classList.remove("hidden");},__proto__:TreeElement.prototype};WebInspector.ScopeChainSidebarPane=function() {WebInspector.SidebarPane.call(this,WebInspector.UIString("Scope"));this._expandController=new WebInspector.ObjectPropertiesSectionExpandController();} WebInspector.ScopeChainSidebarPane._pathSymbol=Symbol("path");WebInspector.ScopeChainSidebarPane.prototype={update:function(callFrame) {WebInspector.SourceMapNamesResolver.resolveThisObject(callFrame).then(this._innerUpdate.bind(this,callFrame));},_innerUpdate:function(callFrame,thisObject) {this.element.removeChildren();if(!callFrame){var infoElement=createElement("div");infoElement.className="info";infoElement.textContent=WebInspector.UIString("Not Paused");this.element.appendChild(infoElement);return;} var foundLocalScope=false;var scopeChain=callFrame.scopeChain();for(var i=0;i<scopeChain.length;++i){var scope=scopeChain[i];var title=null;var emptyPlaceholder=null;var extraProperties=[];switch(scope.type()){case DebuggerAgent.ScopeType.Local:foundLocalScope=true;title=WebInspector.UIString("Local");emptyPlaceholder=WebInspector.UIString("No Variables");if(thisObject) extraProperties.push(new WebInspector.RemoteObjectProperty("this",thisObject));if(i==0){var details=callFrame.debuggerModel.debuggerPausedDetails();var exception=details.exception();if(exception) extraProperties.push(new WebInspector.RemoteObjectProperty(WebInspector.UIString.capitalize("Exception"),exception,undefined,undefined,undefined,undefined,undefined,true));var returnValue=callFrame.returnValue();if(returnValue) extraProperties.push(new WebInspector.RemoteObjectProperty(WebInspector.UIString.capitalize("Return ^value"),returnValue,undefined,undefined,undefined,undefined,undefined,true));} break;case DebuggerAgent.ScopeType.Closure:var scopeName=scope.name();if(scopeName) title=WebInspector.UIString("Closure (%s)",WebInspector.beautifyFunctionName(scopeName));else title=WebInspector.UIString("Closure");emptyPlaceholder=WebInspector.UIString("No Variables");break;case DebuggerAgent.ScopeType.Catch:title=WebInspector.UIString("Catch");break;case DebuggerAgent.ScopeType.Block:title=WebInspector.UIString("Block");break;case DebuggerAgent.ScopeType.Script:title=WebInspector.UIString("Script");break;case DebuggerAgent.ScopeType.With:title=WebInspector.UIString("With Block");break;case DebuggerAgent.ScopeType.Global:title=WebInspector.UIString("Global");break;} var subtitle=scope.description();if(!title||title===subtitle) subtitle=undefined;var titleElement=createElementWithClass("div","scope-chain-sidebar-pane-section-header");titleElement.createChild("div","scope-chain-sidebar-pane-section-subtitle").textContent=subtitle;titleElement.createChild("div","scope-chain-sidebar-pane-section-title").textContent=title;var section=new WebInspector.ObjectPropertiesSection(WebInspector.SourceMapNamesResolver.resolveScopeInObject(scope),titleElement,emptyPlaceholder,true,extraProperties);this._expandController.watchSection(title+(subtitle?":"+subtitle:""),section);if(scope.type()===DebuggerAgent.ScopeType.Global) section.objectTreeElement().collapse();else if(!foundLocalScope||scope.type()===DebuggerAgent.ScopeType.Local) section.objectTreeElement().expand();section.element.classList.add("scope-chain-sidebar-pane-section");this.element.appendChild(section.element);} this._sidebarPaneUpdatedForTest();},_sidebarPaneUpdatedForTest:function(){},__proto__:WebInspector.SidebarPane.prototype};WebInspector.SourcesNavigator=function(workspace) {WebInspector.Object.call(this);this._workspace=workspace;this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.setShrinkableTabs(true);this._tabbedPane.element.classList.add("navigator-tabbed-pane");this._tabbedPaneController=new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane,"navigator-view",this._navigatorViewCreated.bind(this));this._navigatorViews=new Map();var toolbar=new WebInspector.Toolbar("");var menuButton=new WebInspector.ToolbarMenuButton(this._populateMenu.bind(this),true);menuButton.setTitle(WebInspector.UIString("More options"));toolbar.appendToolbarItem(menuButton);this._tabbedPane.appendAfterTabStrip(toolbar.element);} WebInspector.SourcesNavigator.Events={SourceSelected:"SourceSelected",SourceRenamed:"SourceRenamed"} WebInspector.SourcesNavigator.prototype={_navigatorViewCreated:function(id,view) {var navigatorView=(view);navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected,this._sourceSelected,this);navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamed,this._sourceRenamed,this);this._navigatorViews.set(id,navigatorView);navigatorView.setWorkspace(this._workspace);},get view() {return this._tabbedPane;},revealUISourceCode:function(uiSourceCode) {var ids=this._tabbedPaneController.viewIds();var promises=[];for(var i=0;i<ids.length;++i) promises.push(this._tabbedPaneController.viewForId(ids[i]));Promise.all(promises).then(filterNavigators.bind(this));function filterNavigators(objects) {for(var i=0;i<objects.length;++i){var navigatorView=(objects[i]);if(navigatorView.accept(uiSourceCode)){this._tabbedPane.selectTab(ids[i]);navigatorView.revealUISourceCode(uiSourceCode,true);}}}},_sourceSelected:function(event) {this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceSelected,event.data);},_sourceRenamed:function(event) {this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceRenamed,event.data);},_populateMenu:function(contextMenu) {var groupByFolderSetting=WebInspector.moduleSetting("navigatorGroupByFolder");contextMenu.appendItemsAtLocation("navigatorMenu");contextMenu.appendSeparator();contextMenu.appendCheckboxItem(WebInspector.UIString("Group by folder"),()=>groupByFolderSetting.set(!groupByFolderSetting.get()),groupByFolderSetting.get());},__proto__:WebInspector.Object.prototype} WebInspector.SourcesNavigatorView=function() {WebInspector.NavigatorView.call(this);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.InspectedURLChanged,this._inspectedURLChanged,this);} WebInspector.SourcesNavigatorView.prototype={accept:function(uiSourceCode) {if(!WebInspector.NavigatorView.prototype.accept(uiSourceCode)) return false;return uiSourceCode.project().type()!==WebInspector.projectTypes.ContentScripts&&uiSourceCode.project().type()!==WebInspector.projectTypes.Snippets;},_inspectedURLChanged:function(event) {var nodes=this._uiSourceCodeNodes.valuesArray();for(var i=0;i<nodes.length;++i){var uiSourceCode=nodes[i].uiSourceCode();var inspectedPageURL=WebInspector.targetManager.inspectedPageURL();if(inspectedPageURL&&WebInspector.networkMapping.networkURL(uiSourceCode)===inspectedPageURL) this.revealUISourceCode(uiSourceCode,true);}},uiSourceCodeAdded:function(uiSourceCode) {var inspectedPageURL=WebInspector.targetManager.inspectedPageURL();if(inspectedPageURL&&WebInspector.networkMapping.networkURL(uiSourceCode)===inspectedPageURL) this.revealUISourceCode(uiSourceCode,true);},__proto__:WebInspector.NavigatorView.prototype} WebInspector.ContentScriptsNavigatorView=function() {WebInspector.NavigatorView.call(this);} WebInspector.ContentScriptsNavigatorView.prototype={accept:function(uiSourceCode) {if(!WebInspector.NavigatorView.prototype.accept(uiSourceCode)) return false;return uiSourceCode.project().type()===WebInspector.projectTypes.ContentScripts;},__proto__:WebInspector.NavigatorView.prototype} WebInspector.SnippetsNavigatorView=function() {WebInspector.NavigatorView.call(this);} WebInspector.SnippetsNavigatorView.prototype={accept:function(uiSourceCode) {if(!WebInspector.NavigatorView.prototype.accept(uiSourceCode)) return false;return uiSourceCode.project().type()===WebInspector.projectTypes.Snippets;},handleContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("New"),this._handleCreateSnippet.bind(this));contextMenu.show();},handleFileContextMenu:function(event,uiSourceCode) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Run"),this._handleEvaluateSnippet.bind(this,uiSourceCode));contextMenu.appendItem(WebInspector.UIString("Rename"),this.rename.bind(this,uiSourceCode));contextMenu.appendItem(WebInspector.UIString("Remove"),this._handleRemoveSnippet.bind(this,uiSourceCode));contextMenu.appendSeparator();contextMenu.appendItem(WebInspector.UIString("New"),this._handleCreateSnippet.bind(this));contextMenu.show();},_handleEvaluateSnippet:function(uiSourceCode) {var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(uiSourceCode.project().type()!==WebInspector.projectTypes.Snippets||!executionContext) return;WebInspector.scriptSnippetModel.evaluateScriptSnippet(executionContext,uiSourceCode);},_handleRemoveSnippet:function(uiSourceCode) {if(uiSourceCode.project().type()!==WebInspector.projectTypes.Snippets) return;uiSourceCode.remove();},_handleCreateSnippet:function() {this.create(WebInspector.scriptSnippetModel.project(),"");},sourceDeleted:function(uiSourceCode) {this._handleRemoveSnippet(uiSourceCode);},__proto__:WebInspector.NavigatorView.prototype};WebInspector.StyleSheetOutlineDialog=function(uiSourceCode,selectItemCallback) {WebInspector.FilteredListWidget.Delegate.call(this,[]);this._selectItemCallback=selectItemCallback;this._cssParser=new WebInspector.CSSParser();this._cssParser.addEventListener(WebInspector.CSSParser.Events.RulesParsed,this.refresh.bind(this));this._cssParser.parse(uiSourceCode.workingCopy());} WebInspector.StyleSheetOutlineDialog.show=function(uiSourceCode,selectItemCallback) {WebInspector.StyleSheetOutlineDialog._instanceForTests=new WebInspector.StyleSheetOutlineDialog(uiSourceCode,selectItemCallback);new WebInspector.FilteredListWidget(WebInspector.StyleSheetOutlineDialog._instanceForTests).showAsDialog();} WebInspector.StyleSheetOutlineDialog.prototype={itemCount:function() {return this._cssParser.rules().length;},itemKeyAt:function(itemIndex) {var rule=this._cssParser.rules()[itemIndex];return rule.selectorText||rule.atRule;},itemScoreAt:function(itemIndex,query) {var rule=this._cssParser.rules()[itemIndex];return-rule.lineNumber;},renderItem:function(itemIndex,query,titleElement,subtitleElement) {var rule=this._cssParser.rules()[itemIndex];titleElement.textContent=rule.selectorText||rule.atRule;this.highlightRanges(titleElement,query);subtitleElement.textContent=":"+(rule.lineNumber+1);},selectItem:function(itemIndex,promptValue) {var rule=this._cssParser.rules()[itemIndex];var lineNumber=rule.lineNumber;if(!isNaN(lineNumber)&&lineNumber>=0) this._selectItemCallback(lineNumber,rule.columnNumber);},dispose:function() {this._cssParser.dispose();},__proto__:WebInspector.FilteredListWidget.Delegate.prototype};WebInspector.TabbedEditorContainerDelegate=function(){} WebInspector.TabbedEditorContainerDelegate.prototype={viewForFile:function(uiSourceCode){},} WebInspector.TabbedEditorContainer=function(delegate,setting,placeholderText) {WebInspector.Object.call(this);this._delegate=delegate;this._tabbedPane=new WebInspector.TabbedPane();this._tabbedPane.setPlaceholderText(placeholderText);this._tabbedPane.setTabDelegate(new WebInspector.EditorContainerTabDelegate(this));this._tabbedPane.setCloseableTabs(true);this._tabbedPane.setAllowTabReorder(true,true);this._tabbedPane.insertBeforeTabStrip(createElementWithClass("div","sources-editor-tabstrip-left"));this._tabbedPane.appendAfterTabStrip(createElementWithClass("div","sources-editor-tabstrip-right"));this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed,this._tabClosed,this);this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._tabIds=new Map();this._files={};this._previouslyViewedFilesSetting=setting;this._history=WebInspector.TabbedEditorContainer.History.fromObject(this._previouslyViewedFilesSetting.get());} WebInspector.TabbedEditorContainer.Events={EditorSelected:"EditorSelected",EditorClosed:"EditorClosed"} WebInspector.TabbedEditorContainer._tabId=0;WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount=30;WebInspector.TabbedEditorContainer.prototype={get view() {return this._tabbedPane;},get visibleView() {return this._tabbedPane.visibleView;},fileViews:function() {return(this._tabbedPane.tabViews());},show:function(parentElement) {this._tabbedPane.show(parentElement);},showFile:function(uiSourceCode) {this._innerShowFile(uiSourceCode,true);},closeFile:function(uiSourceCode) {var tabId=this._tabIds.get(uiSourceCode);if(!tabId) return;this._closeTabs([tabId]);},historyUISourceCodes:function() {var uriToUISourceCode={};for(var id in this._files){var uiSourceCode=this._files[id];uriToUISourceCode[uiSourceCode.url()]=uiSourceCode;} var result=[];var uris=this._history._urls();for(var i=0;i<uris.length;++i){var uiSourceCode=uriToUISourceCode[uris[i]];if(uiSourceCode) result.push(uiSourceCode);} return result;},_addViewListeners:function() {if(!this._currentView) return;this._currentView.addEventListener(WebInspector.SourceFrame.Events.ScrollChanged,this._scrollChanged,this);this._currentView.addEventListener(WebInspector.SourceFrame.Events.SelectionChanged,this._selectionChanged,this);},_removeViewListeners:function() {if(!this._currentView) return;this._currentView.removeEventListener(WebInspector.SourceFrame.Events.ScrollChanged,this._scrollChanged,this);this._currentView.removeEventListener(WebInspector.SourceFrame.Events.SelectionChanged,this._selectionChanged,this);},_scrollChanged:function(event) {var lineNumber=(event.data);this._history.updateScrollLineNumber(this._currentFile.url(),lineNumber);this._history.save(this._previouslyViewedFilesSetting);},_selectionChanged:function(event) {var range=(event.data);this._history.updateSelectionRange(this._currentFile.url(),range);this._history.save(this._previouslyViewedFilesSetting);},_innerShowFile:function(uiSourceCode,userGesture) {if(this._currentFile===uiSourceCode) return;this._removeViewListeners();this._currentFile=uiSourceCode;var tabId=this._tabIds.get(uiSourceCode)||this._appendFileTab(uiSourceCode,userGesture);this._tabbedPane.selectTab(tabId,userGesture);if(userGesture) this._editorSelectedByUserAction();this._currentView=this.visibleView;this._addViewListeners();var eventData={currentFile:this._currentFile,userGesture:userGesture};this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorSelected,eventData);},_titleForFile:function(uiSourceCode) {var maxDisplayNameLength=30;var title=uiSourceCode.displayName(true).trimMiddle(maxDisplayNameLength);if(uiSourceCode.isDirty()||uiSourceCode.hasUnsavedCommittedChanges()) title+="*";return title;},_maybeCloseTab:function(id,nextTabId) {var uiSourceCode=this._files[id];var shouldPrompt=uiSourceCode.isDirty()&&uiSourceCode.project().canSetFileContent();if(!shouldPrompt||confirm(WebInspector.UIString("Are you sure you want to close unsaved file: %s?",uiSourceCode.name()))){uiSourceCode.resetWorkingCopy();if(nextTabId) this._tabbedPane.selectTab(nextTabId,true);this._tabbedPane.closeTab(id,true);return true;} return false;},_closeTabs:function(ids) {var dirtyTabs=[];var cleanTabs=[];for(var i=0;i<ids.length;++i){var id=ids[i];var uiSourceCode=this._files[id];if(uiSourceCode.isDirty()) dirtyTabs.push(id);else cleanTabs.push(id);} if(dirtyTabs.length) this._tabbedPane.selectTab(dirtyTabs[0],true);this._tabbedPane.closeTabs(cleanTabs,true);for(var i=0;i<dirtyTabs.length;++i){var nextTabId=i+1<dirtyTabs.length?dirtyTabs[i+1]:null;if(!this._maybeCloseTab(dirtyTabs[i],nextTabId)) break;}},_onContextMenu:function(tabId,contextMenu) {var uiSourceCode=this._files[tabId];if(uiSourceCode) contextMenu.appendApplicableItems(uiSourceCode);},addUISourceCode:function(uiSourceCode) {var uri=uiSourceCode.url();var index=this._history.index(uri);if(index===-1) return;if(!this._tabIds.has(uiSourceCode)) this._appendFileTab(uiSourceCode,false);if(!index){this._innerShowFile(uiSourceCode,false);return;} if(!this._currentFile) return;var currentProjectType=this._currentFile.project().type();var addedProjectType=uiSourceCode.project().type();var snippetsProjectType=WebInspector.projectTypes.Snippets;if(this._history.index(this._currentFile.url())&¤tProjectType===snippetsProjectType&&addedProjectType!==snippetsProjectType) this._innerShowFile(uiSourceCode,false);},removeUISourceCode:function(uiSourceCode) {this.removeUISourceCodes([uiSourceCode]);},removeUISourceCodes:function(uiSourceCodes) {var tabIds=[];for(var i=0;i<uiSourceCodes.length;++i){var uiSourceCode=uiSourceCodes[i];var tabId=this._tabIds.get(uiSourceCode);if(tabId) tabIds.push(tabId);} this._tabbedPane.closeTabs(tabIds);},_editorClosedByUserAction:function(uiSourceCode) {this._history.remove(uiSourceCode.url());this._updateHistory();},_editorSelectedByUserAction:function() {this._updateHistory();},_updateHistory:function() {var tabIds=this._tabbedPane.lastOpenedTabIds(WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount);function tabIdToURI(tabId) {return this._files[tabId].url();} this._history.update(tabIds.map(tabIdToURI.bind(this)));this._history.save(this._previouslyViewedFilesSetting);},_tooltipForFile:function(uiSourceCode) {return uiSourceCode.url();},_appendFileTab:function(uiSourceCode,userGesture) {var view=this._delegate.viewForFile(uiSourceCode);var sourceFrame=view instanceof WebInspector.SourceFrame?(view):null;var title=this._titleForFile(uiSourceCode);var tooltip=this._tooltipForFile(uiSourceCode);var tabId=this._generateTabId();this._tabIds.set(uiSourceCode,tabId);this._files[tabId]=uiSourceCode;var savedSelectionRange=this._history.selectionRange(uiSourceCode.url());if(sourceFrame&&savedSelectionRange) sourceFrame.setSelection(savedSelectionRange);var savedScrollLineNumber=this._history.scrollLineNumber(uiSourceCode.url());if(sourceFrame&&savedScrollLineNumber) sourceFrame.scrollToLine(savedScrollLineNumber);this._tabbedPane.appendTab(tabId,title,view,tooltip,userGesture);this._updateFileTitle(uiSourceCode);this._addUISourceCodeListeners(uiSourceCode);return tabId;},_tabClosed:function(event) {var tabId=(event.data.tabId);var userGesture=(event.data.isUserGesture);var uiSourceCode=this._files[tabId];if(this._currentFile===uiSourceCode){this._removeViewListeners();delete this._currentView;delete this._currentFile;} this._tabIds.remove(uiSourceCode);delete this._files[tabId];this._removeUISourceCodeListeners(uiSourceCode);this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorClosed,uiSourceCode);if(userGesture) this._editorClosedByUserAction(uiSourceCode);},_tabSelected:function(event) {var tabId=(event.data.tabId);var userGesture=(event.data.isUserGesture);var uiSourceCode=this._files[tabId];this._innerShowFile(uiSourceCode,userGesture);},_addUISourceCodeListeners:function(uiSourceCode) {uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._uiSourceCodeTitleChanged,this);uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._uiSourceCodeWorkingCopyChanged,this);uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._uiSourceCodeWorkingCopyCommitted,this);},_removeUISourceCodeListeners:function(uiSourceCode) {uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleChanged,this._uiSourceCodeTitleChanged,this);uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged,this._uiSourceCodeWorkingCopyChanged,this);uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted,this._uiSourceCodeWorkingCopyCommitted,this);},_updateFileTitle:function(uiSourceCode) {var tabId=this._tabIds.get(uiSourceCode);if(tabId){var title=this._titleForFile(uiSourceCode);this._tabbedPane.changeTabTitle(tabId,title);if(uiSourceCode.hasUnsavedCommittedChanges()) this._tabbedPane.setTabIcon(tabId,"warning-icon",WebInspector.UIString("Changes to this file were not saved to file system."));else this._tabbedPane.setTabIcon(tabId,"");}},_uiSourceCodeTitleChanged:function(event) {var uiSourceCode=(event.target);this._updateFileTitle(uiSourceCode);this._updateHistory();},_uiSourceCodeWorkingCopyChanged:function(event) {var uiSourceCode=(event.target);this._updateFileTitle(uiSourceCode);},_uiSourceCodeWorkingCopyCommitted:function(event) {var uiSourceCode=(event.target);this._updateFileTitle(uiSourceCode);},_generateTabId:function() {return"tab_"+(WebInspector.TabbedEditorContainer._tabId++);},currentFile:function() {return this._currentFile;},__proto__:WebInspector.Object.prototype} WebInspector.TabbedEditorContainer.HistoryItem=function(url,selectionRange,scrollLineNumber) {this.url=url;this._isSerializable=url.length<WebInspector.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit;this.selectionRange=selectionRange;this.scrollLineNumber=scrollLineNumber;} WebInspector.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit=4096;WebInspector.TabbedEditorContainer.HistoryItem.fromObject=function(serializedHistoryItem) {var selectionRange=serializedHistoryItem.selectionRange?WebInspector.TextRange.fromObject(serializedHistoryItem.selectionRange):undefined;return new WebInspector.TabbedEditorContainer.HistoryItem(serializedHistoryItem.url,selectionRange,serializedHistoryItem.scrollLineNumber);} WebInspector.TabbedEditorContainer.HistoryItem.prototype={serializeToObject:function() {if(!this._isSerializable) return null;var serializedHistoryItem={};serializedHistoryItem.url=this.url;serializedHistoryItem.selectionRange=this.selectionRange;serializedHistoryItem.scrollLineNumber=this.scrollLineNumber;return serializedHistoryItem;}} WebInspector.TabbedEditorContainer.History=function(items) {this._items=items;this._rebuildItemIndex();} WebInspector.TabbedEditorContainer.History.fromObject=function(serializedHistory) {var items=[];for(var i=0;i<serializedHistory.length;++i) items.push(WebInspector.TabbedEditorContainer.HistoryItem.fromObject(serializedHistory[i]));return new WebInspector.TabbedEditorContainer.History(items);} WebInspector.TabbedEditorContainer.History.prototype={index:function(url) {return this._itemsIndex.has(url)?(this._itemsIndex.get(url)):-1;},_rebuildItemIndex:function() {this._itemsIndex=new Map();for(var i=0;i<this._items.length;++i){console.assert(!this._itemsIndex.has(this._items[i].url));this._itemsIndex.set(this._items[i].url,i);}},selectionRange:function(url) {var index=this.index(url);return index!==-1?this._items[index].selectionRange:undefined;},updateSelectionRange:function(url,selectionRange) {if(!selectionRange) return;var index=this.index(url);if(index===-1) return;this._items[index].selectionRange=selectionRange;},scrollLineNumber:function(url) {var index=this.index(url);return index!==-1?this._items[index].scrollLineNumber:undefined;},updateScrollLineNumber:function(url,scrollLineNumber) {var index=this.index(url);if(index===-1) return;this._items[index].scrollLineNumber=scrollLineNumber;},update:function(urls) {for(var i=urls.length-1;i>=0;--i){var index=this.index(urls[i]);var item;if(index!==-1){item=this._items[index];this._items.splice(index,1);}else item=new WebInspector.TabbedEditorContainer.HistoryItem(urls[i]);this._items.unshift(item);this._rebuildItemIndex();}},remove:function(url) {var index=this.index(url);if(index!==-1){this._items.splice(index,1);this._rebuildItemIndex();}},save:function(setting) {setting.set(this._serializeToObject());},_serializeToObject:function() {var serializedHistory=[];for(var i=0;i<this._items.length;++i){var serializedItem=this._items[i].serializeToObject();if(serializedItem) serializedHistory.push(serializedItem);if(serializedHistory.length===WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount) break;} return serializedHistory;},_urls:function() {var result=[];for(var i=0;i<this._items.length;++i) result.push(this._items[i].url);return result;}} WebInspector.EditorContainerTabDelegate=function(editorContainer) {this._editorContainer=editorContainer;} WebInspector.EditorContainerTabDelegate.prototype={closeTabs:function(tabbedPane,ids) {this._editorContainer._closeTabs(ids);},onContextMenu:function(tabId,contextMenu) {this._editorContainer._onContextMenu(tabId,contextMenu);}};WebInspector.WatchExpressionsSidebarPane=function() {WebInspector.SidebarPane.call(this,WebInspector.UIString("Watch"));this.registerRequiredCSS("components/objectValue.css");this._requiresUpdate=true;this._watchExpressions=[];this._watchExpressionsSetting=WebInspector.settings.createLocalSetting("watchExpressions",[]);var addButton=new WebInspector.ToolbarButton(WebInspector.UIString("Add expression"),"add-toolbar-item");addButton.addEventListener("click",this._addButtonClicked.bind(this));this.toolbar().appendToolbarItem(addButton);var refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");refreshButton.addEventListener("click",this._refreshButtonClicked.bind(this));this.toolbar().appendToolbarItem(refreshButton);this._bodyElement=this.element.createChild("div","vbox watch-expressions");this._bodyElement.addEventListener("contextmenu",this._contextMenu.bind(this),false);this._expandController=new WebInspector.ObjectPropertiesSectionExpandController();WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext,this.refreshExpressions,this);} WebInspector.WatchExpressionsSidebarPane.prototype={wasShown:function() {this._refreshExpressionsIfNeeded();},refreshExpressions:function() {this._requiresUpdate=true;this._refreshExpressionsIfNeeded();},addExpression:function(expressionString) {this.expand();if(this._requiresUpdate){this._rebuildWatchExpressions();delete this._requiresUpdate;} this._createWatchExpression(expressionString);this._saveExpressions();},expandIfNecessary:function() {if(this._watchExpressionsSetting.get().length) this.expand();},_saveExpressions:function() {var toSave=[];for(var i=0;i<this._watchExpressions.length;i++) if(this._watchExpressions[i].expression()) toSave.push(this._watchExpressions[i].expression());this._watchExpressionsSetting.set(toSave);},_refreshExpressionsIfNeeded:function() {if(this._requiresUpdate&&this.isShowing()){this._rebuildWatchExpressions();delete this._requiresUpdate;}else this._requiresUpdate=true;},_addButtonClicked:function(event) {if(event) event.consume(true);this.expand();this._createWatchExpression(null).startEditing();},_refreshButtonClicked:function(event) {event.consume();this.refreshExpressions();},_rebuildWatchExpressions:function() {this._bodyElement.removeChildren();this._watchExpressions=[];this._emptyElement=this._bodyElement.createChild("div","info");this._emptyElement.textContent=WebInspector.UIString("No Watch Expressions");var watchExpressionStrings=this._watchExpressionsSetting.get();for(var i=0;i<watchExpressionStrings.length;++i){var expression=watchExpressionStrings[i];if(!expression) continue;this._createWatchExpression(expression);}},_createWatchExpression:function(expression) {this._emptyElement.classList.add("hidden");var watchExpression=new WebInspector.WatchExpression(expression,this._expandController);watchExpression.addEventListener(WebInspector.WatchExpression.Events.ExpressionUpdated,this._watchExpressionUpdated.bind(this));this._bodyElement.appendChild(watchExpression.element());this._watchExpressions.push(watchExpression);return watchExpression;},_watchExpressionUpdated:function(event) {var watchExpression=(event.target);if(!watchExpression.expression()){this._watchExpressions.remove(watchExpression);this._bodyElement.removeChild(watchExpression.element());this._emptyElement.classList.toggle("hidden",!!this._watchExpressions.length);} this._saveExpressions();},_contextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);this._populateContextMenu(contextMenu,event);contextMenu.show();},_populateContextMenu:function(contextMenu,event) {var isEditing=false;for(var watchExpression of this._watchExpressions) isEditing|=watchExpression.isEditing();if(!isEditing) contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^watch ^expression"),this._addButtonClicked.bind(this));if(this._watchExpressions.length>1) contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^all ^watch ^expressions"),this._deleteAllButtonClicked.bind(this));for(var watchExpression of this._watchExpressions) if(watchExpression.element().containsEventPoint(event)) watchExpression._populateContextMenu(contextMenu,event);},_deleteAllButtonClicked:function() {this._watchExpressions=[];this._saveExpressions();this._rebuildWatchExpressions();},__proto__:WebInspector.SidebarPane.prototype} WebInspector.WatchExpression=function(expression,expandController) {this._expression=expression;this._expandController=expandController;this._element=createElementWithClass("div","watch-expression monospace");this._editing=false;this._createWatchExpression(null,false);this.update();} WebInspector.WatchExpression._watchObjectGroupId="watch-group";WebInspector.WatchExpression.Events={ExpressionUpdated:"ExpressionUpdated"} WebInspector.WatchExpression.prototype={element:function() {return this._element;},expression:function() {return this._expression;},update:function() {var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(currentExecutionContext&&this._expression) currentExecutionContext.evaluate(this._expression,WebInspector.WatchExpression._watchObjectGroupId,false,true,false,false,false,this._createWatchExpression.bind(this));},startEditing:function() {this._editing=true;this._element.removeChild(this._objectPresentationElement);var newDiv=this._element.createChild("div");newDiv.textContent=this._nameElement.textContent;this._textPrompt=new WebInspector.ObjectPropertyPrompt();this._textPrompt.renderAsBlock();var proxyElement=this._textPrompt.attachAndStartEditing(newDiv,this._finishEditing.bind(this));proxyElement.classList.add("watch-expression-text-prompt-proxy");proxyElement.addEventListener("keydown",this._promptKeyDown.bind(this),false);this._element.getComponentSelection().setBaseAndExtent(newDiv,0,newDiv,1);},isEditing:function() {return!!this._editing;},_finishEditing:function(event,canceled) {if(event) event.consume(true);this._editing=false;this._textPrompt.detach();var newExpression=canceled?this._expression:this._textPrompt.text();delete this._textPrompt;this._element.removeChildren();this._element.appendChild(this._objectPresentationElement);this._updateExpression(newExpression);},_dblClickOnWatchExpression:function(event) {event.consume();if(!this.isEditing()) this.startEditing();},_updateExpression:function(newExpression) {if(this._expression) this._expandController.stopWatchSectionsWithId(this._expression);this._expression=newExpression;this.update();this.dispatchEventToListeners(WebInspector.WatchExpression.Events.ExpressionUpdated);},_deleteWatchExpression:function(event) {event.consume(true);this._updateExpression(null);},_createWatchExpression:function(result,wasThrown) {this._result=result;var headerElement=createElementWithClass("div","watch-expression-header");var deleteButton=headerElement.createChild("button","watch-expression-delete-button");deleteButton.title=WebInspector.UIString("Delete watch expression");deleteButton.addEventListener("click",this._deleteWatchExpression.bind(this),false);var titleElement=headerElement.createChild("div","watch-expression-title");this._nameElement=WebInspector.ObjectPropertiesSection.createNameElement(this._expression);if(wasThrown||!result){this._valueElement=createElementWithClass("span","error-message value");titleElement.classList.add("dimmed");this._valueElement.textContent=WebInspector.UIString("<not available>");}else{this._valueElement=WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(result,wasThrown,titleElement);} var separatorElement=createElementWithClass("span","watch-expressions-separator");separatorElement.textContent=": ";titleElement.appendChildren(this._nameElement,separatorElement,this._valueElement);this._element.removeChildren();this._objectPropertiesSection=null;if(!wasThrown&&result&&result.hasChildren&&!result.customPreview()){headerElement.classList.add("watch-expression-object-header");this._objectPropertiesSection=new WebInspector.ObjectPropertiesSection(result,headerElement);this._objectPresentationElement=this._objectPropertiesSection.element;this._expandController.watchSection((this._expression),this._objectPropertiesSection);var objectTreeElement=this._objectPropertiesSection.objectTreeElement();objectTreeElement.toggleOnClick=false;objectTreeElement.listItemElement.addEventListener("click",this._onSectionClick.bind(this),false);objectTreeElement.listItemElement.addEventListener("dblclick",this._dblClickOnWatchExpression.bind(this));}else{this._objectPresentationElement=headerElement;this._objectPresentationElement.addEventListener("dblclick",this._dblClickOnWatchExpression.bind(this));} this._element.appendChild(this._objectPresentationElement);},_onSectionClick:function(event) {event.consume(true);if(event.detail==1){this._preventClickTimeout=setTimeout(handleClick.bind(this),333);}else{clearTimeout(this._preventClickTimeout);delete this._preventClickTimeout;} function handleClick() {if(!this._objectPropertiesSection) return;var objectTreeElement=this._objectPropertiesSection.objectTreeElement();if(objectTreeElement.expanded) objectTreeElement.collapse();else objectTreeElement.expand();}},_promptKeyDown:function(event) {if(isEnterKey(event)||isEscKey(event)) this._finishEditing(event,isEscKey(event));},_populateContextMenu:function(contextMenu,event) {if(!this.isEditing()) contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^watch ^expression"),this._updateExpression.bind(this,null));if(!this.isEditing()&&this._result&&(this._result.type==="number"||this._result.type==="string")) contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^value"),this._copyValueButtonClicked.bind(this));if(this._valueElement.containsEventPoint(event)) contextMenu.appendApplicableItems(this._result);},_copyValueButtonClicked:function() {InspectorFrontendHost.copyText(this._valueElement.textContent);},__proto__:WebInspector.Object.prototype};WebInspector.ThreadsSidebarPane=function() {WebInspector.SidebarPane.call(this,WebInspector.UIString("Threads"));this.setVisible(false);this._debuggerModelToListItems=new Map();this._listItemsToTargets=new Map();this._selectedListItem=null;this.threadList=new WebInspector.UIList();this.threadList.show(this.element);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerPaused,this._onDebuggerStateChanged,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerResumed,this._onDebuggerStateChanged,this);WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel,WebInspector.RuntimeModel.Events.ExecutionContextChanged,this._onExecutionContextChanged,this);WebInspector.context.addFlavorChangeListener(WebInspector.Target,this._targetChanged,this);WebInspector.targetManager.observeTargets(this);} WebInspector.ThreadsSidebarPane.prototype={targetAdded:function(target) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target) if(!debuggerModel){this._updateVisibility();return;} var executionContext=target.runtimeModel.defaultExecutionContext();var label=executionContext&&executionContext.label()?executionContext.label():target.name();var listItem=new WebInspector.UIList.Item(label,"");listItem.element.addEventListener("click",this._onListItemClick.bind(this,listItem),false);var currentTarget=WebInspector.context.flavor(WebInspector.Target);if(currentTarget===target) this._selectListItem(listItem);this._debuggerModelToListItems.set(debuggerModel,listItem);this._listItemsToTargets.set(listItem,target);this.threadList.addItem(listItem);this._updateDebuggerState(debuggerModel);this._updateVisibility();},_updateVisibility:function() {this._wasVisibleAtLeastOnce=this._wasVisibleAtLeastOnce||this._debuggerModelToListItems.size>1;this.setVisible(this._wasVisibleAtLeastOnce);},targetRemoved:function(target) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target) if(!debuggerModel) return;var listItem=this._debuggerModelToListItems.remove(debuggerModel);if(listItem){this._listItemsToTargets.remove(listItem);this.threadList.removeItem(listItem);} this._updateVisibility();},_targetChanged:function(event) {var newTarget=(event.data);var debuggerModel=WebInspector.DebuggerModel.fromTarget(newTarget) if(!debuggerModel) return;var listItem=(this._debuggerModelToListItems.get(debuggerModel));this._selectListItem(listItem);},_onDebuggerStateChanged:function(event) {var debuggerModel=(event.target);this._updateDebuggerState(debuggerModel);},_onExecutionContextChanged:function(event) {var executionContext=(event.data);if(!executionContext.isDefault) return;var debuggerModel=(WebInspector.DebuggerModel.fromTarget(executionContext.target()));var listItem=this._debuggerModelToListItems.get(debuggerModel);if(listItem&&executionContext.label()) listItem.setTitle(executionContext.label());},_updateDebuggerState:function(debuggerModel) {var listItem=this._debuggerModelToListItems.get(debuggerModel);listItem.setSubtitle(WebInspector.UIString(debuggerModel.isPaused()?"paused":""));},_selectListItem:function(listItem) {if(listItem===this._selectedListItem) return;if(this._selectedListItem) this._selectedListItem.setSelected(false);this._selectedListItem=listItem;listItem.setSelected(true);},_onListItemClick:function(listItem) {WebInspector.context.setFlavor(WebInspector.Target,this._listItemsToTargets.get(listItem));listItem.element.scrollIntoViewIfNeeded();},__proto__:WebInspector.SidebarPane.prototype};WebInspector.FormatterScriptMapping=function(debuggerModel,editorAction) {this._debuggerModel=debuggerModel;this._editorAction=editorAction;} WebInspector.FormatterScriptMapping.prototype={rawLocationToUILocation:function(rawLocation) {var debuggerModelLocation=(rawLocation);var script=debuggerModelLocation.script();var uiSourceCode=this._editorAction._uiSourceCodes.get(script);if(!uiSourceCode) return null;var formatData=this._editorAction._formatData.get(uiSourceCode);if(!formatData) return null;var mapping=formatData.mapping;var lineNumber=debuggerModelLocation.lineNumber;var columnNumber=debuggerModelLocation.columnNumber||0;var formattedLocation=mapping.originalToFormatted(lineNumber,columnNumber);return uiSourceCode.uiLocation(formattedLocation[0],formattedLocation[1]);},uiLocationToRawLocation:function(uiSourceCode,lineNumber,columnNumber) {var formatData=this._editorAction._formatData.get(uiSourceCode);if(!formatData) return null;var originalLocation=formatData.mapping.formattedToOriginal(lineNumber,columnNumber);for(var i=0;i<formatData.scripts.length;++i){if(formatData.scripts[i].debuggerModel===this._debuggerModel) return this._debuggerModel.createRawLocation(formatData.scripts[i],originalLocation[0],originalLocation[1]);} return null;},isIdentity:function() {return false;},uiLineHasMapping:function(uiSourceCode,lineNumber) {return true;}} WebInspector.FormatterScriptMapping.FormatData=function(projectId,path,mapping,scripts) {this.projectId=projectId;this.path=path;this.mapping=mapping;this.scripts=scripts;} WebInspector.ScriptFormatterEditorAction=function() {this._projectId="formatter:";this._project=new WebInspector.ContentProviderBasedProject(WebInspector.workspace,this._projectId,WebInspector.projectTypes.Formatter,"formatter");this._uiSourceCodes=new Map();this._formattedPaths=new Map();this._formatData=new Map();this._pathsToFormatOnLoad=new Set();this._scriptMappingByTarget=new Map();this._workspace=WebInspector.workspace;WebInspector.targetManager.observeTargets(this);} WebInspector.ScriptFormatterEditorAction.prototype={targetAdded:function(target) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel) return;this._scriptMappingByTarget.set(target,new WebInspector.FormatterScriptMapping(debuggerModel,this));debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);},targetRemoved:function(target) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel) return;this._scriptMappingByTarget.remove(target);this._cleanForTarget(target);debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);},_editorSelected:function(event) {var uiSourceCode=(event.data);this._updateButton(uiSourceCode);var path=uiSourceCode.project().id()+":"+uiSourceCode.url();var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);if(this._isFormatableScript(uiSourceCode)&&networkURL&&this._pathsToFormatOnLoad.has(path)&&!this._formattedPaths.get(path)) this._formatUISourceCodeScript(uiSourceCode);},_editorClosed:function(event) {var uiSourceCode=(event.data.uiSourceCode);var wasSelected=(event.data.wasSelected);if(wasSelected) this._updateButton(null);this._discardFormattedUISourceCodeScript(uiSourceCode);},_updateButton:function(uiSourceCode) {this._button.element.classList.toggle("hidden",!this._isFormatableScript(uiSourceCode));},button:function(sourcesView) {if(this._button) return this._button;this._sourcesView=sourcesView;this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected,this._editorSelected.bind(this));this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed,this._editorClosed.bind(this));this._button=new WebInspector.ToolbarButton(WebInspector.UIString("Pretty print"),"format-toolbar-item");this._button.addEventListener("click",this._toggleFormatScriptSource,this);this._updateButton(sourcesView.currentUISourceCode());return this._button;},_isFormatableScript:function(uiSourceCode) {if(!uiSourceCode) return false;var supportedProjectTypes=[WebInspector.projectTypes.Network,WebInspector.projectTypes.Debugger,WebInspector.projectTypes.ContentScripts];if(supportedProjectTypes.indexOf(uiSourceCode.project().type())===-1) return false;return uiSourceCode.contentType().hasScripts();},_toggleFormatScriptSource:function() {var uiSourceCode=this._sourcesView.currentUISourceCode();if(this._isFormatableScript(uiSourceCode)) this._formatUISourceCodeScript(uiSourceCode);},_showIfNeeded:function(uiSourceCode,formattedUISourceCode,mapping) {if(uiSourceCode!==this._sourcesView.currentUISourceCode()) return;var sourceFrame=this._sourcesView.viewForFile(uiSourceCode);var start=[0,0];if(sourceFrame){var selection=sourceFrame.selection();start=mapping.originalToFormatted(selection.startLine,selection.startColumn);} this._sourcesView.showSourceLocation(formattedUISourceCode,start[0],start[1]);this._updateButton(formattedUISourceCode);},_discardFormattedUISourceCodeScript:function(formattedUISourceCode) {var formatData=this._formatData.get(formattedUISourceCode);if(!formatData) return;this._formatData.remove(formattedUISourceCode);var path=formatData.projectId+":"+formatData.path;this._formattedPaths.remove(path);this._pathsToFormatOnLoad.delete(path);for(var i=0;i<formatData.scripts.length;++i){this._uiSourceCodes.remove(formatData.scripts[i]);WebInspector.debuggerWorkspaceBinding.popSourceMapping(formatData.scripts[i]);} this._project.removeFile(formattedUISourceCode.url());},_cleanForTarget:function(target) {var uiSourceCodes=this._formatData.keysArray();for(var i=0;i<uiSourceCodes.length;++i){WebInspector.debuggerWorkspaceBinding.setSourceMapping(target,uiSourceCodes[i],null);var formatData=this._formatData.get(uiSourceCodes[i]);var scripts=[];for(var j=0;j<formatData.scripts.length;++j){if(formatData.scripts[j].target()===target) this._uiSourceCodes.remove(formatData.scripts[j]);else scripts.push(formatData.scripts[j]);} if(scripts.length) formatData.scripts=scripts;else{this._formattedPaths.remove(formatData.projectId+":"+formatData.path);this._formatData.remove(uiSourceCodes[i]);this._project.removeFile(uiSourceCodes[i].url());}}},_debuggerReset:function(event) {var debuggerModel=(event.target);this._cleanForTarget(debuggerModel.target());},_scriptsForUISourceCode:function(uiSourceCode) {function isInlineScript(script) {return script.isInlineScript()&&!script.hasSourceURL;} if(uiSourceCode.contentType()===WebInspector.resourceTypes.Document){var scripts=[];var debuggerModels=WebInspector.DebuggerModel.instances();for(var i=0;i<debuggerModels.length;++i){var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);scripts.pushAll(debuggerModels[i].scriptsForSourceURL(networkURL));} return scripts.filter(isInlineScript);} if(uiSourceCode.contentType().isScript()){var rawLocations=WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode,0,0);return rawLocations.map(function(rawLocation){return rawLocation.script();});} return[];},_formatUISourceCodeScript:function(uiSourceCode) {var formattedPath=this._formattedPaths.get(uiSourceCode.project().id()+":"+uiSourceCode.url());if(formattedPath){var uiSourceCodePath=formattedPath;var formattedUISourceCode=this._workspace.uiSourceCode(this._projectId,uiSourceCodePath);var formatData=formattedUISourceCode?this._formatData.get(formattedUISourceCode):null;if(formatData) this._showIfNeeded(uiSourceCode,(formattedUISourceCode),formatData.mapping);return;} uiSourceCode.requestContent().then(contentLoaded.bind(this));function contentLoaded(content) {var highlighterType=WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode);WebInspector.Formatter.format(uiSourceCode.contentType(),highlighterType,content||"",innerCallback.bind(this));} function innerCallback(formattedContent,formatterMapping) {var scripts=this._scriptsForUISourceCode(uiSourceCode);var formattedURL=uiSourceCode.url()+":formatted";var contentProvider=WebInspector.StaticContentProvider.fromString(formattedURL,uiSourceCode.contentType(),formattedContent);var formattedUISourceCode=this._project.addContentProvider(formattedURL,contentProvider);var formattedPath=formattedUISourceCode.url();var formatData=new WebInspector.FormatterScriptMapping.FormatData(uiSourceCode.project().id(),uiSourceCode.url(),formatterMapping,scripts);this._formatData.set(formattedUISourceCode,formatData);var path=uiSourceCode.project().id()+":"+uiSourceCode.url();this._formattedPaths.set(path,formattedPath);this._pathsToFormatOnLoad.add(path);for(var i=0;i<scripts.length;++i){this._uiSourceCodes.set(scripts[i],formattedUISourceCode);var scriptMapping=(this._scriptMappingByTarget.get(scripts[i].target()));WebInspector.debuggerWorkspaceBinding.pushSourceMapping(scripts[i],scriptMapping);} var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i){var scriptMapping=(this._scriptMappingByTarget.get(targets[i]));WebInspector.debuggerWorkspaceBinding.setSourceMapping(targets[i],formattedUISourceCode,scriptMapping);} this._showIfNeeded(uiSourceCode,formattedUISourceCode,formatterMapping);}}};WebInspector.InplaceFormatterEditorAction=function() {} WebInspector.InplaceFormatterEditorAction.prototype={_editorSelected:function(event) {var uiSourceCode=(event.data);this._updateButton(uiSourceCode);},_editorClosed:function(event) {var wasSelected=(event.data.wasSelected);if(wasSelected) this._updateButton(null);},_updateButton:function(uiSourceCode) {this._button.element.classList.toggle("hidden",!this._isFormattable(uiSourceCode));},button:function(sourcesView) {if(this._button) return this._button;this._sourcesView=sourcesView;this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected,this._editorSelected.bind(this));this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed,this._editorClosed.bind(this));this._button=new WebInspector.ToolbarButton(WebInspector.UIString("Format"),"format-toolbar-item");this._button.addEventListener("click",this._formatSourceInPlace,this);this._updateButton(sourcesView.currentUISourceCode());return this._button;},_isFormattable:function(uiSourceCode) {if(!uiSourceCode) return false;if(uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem) return true;return uiSourceCode.contentType().isStyleSheet()||uiSourceCode.project().type()===WebInspector.projectTypes.Snippets;},_formatSourceInPlace:function() {var uiSourceCode=this._sourcesView.currentUISourceCode();if(!this._isFormattable(uiSourceCode)) return;if(uiSourceCode.isDirty()) contentLoaded.call(this,uiSourceCode.workingCopy());else uiSourceCode.requestContent().then(contentLoaded.bind(this));function contentLoaded(content) {var highlighterType=WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode);WebInspector.Formatter.format(uiSourceCode.contentType(),highlighterType,content||"",innerCallback.bind(this));} function innerCallback(formattedContent,formatterMapping) {if(uiSourceCode.workingCopy()===formattedContent) return;var sourceFrame=this._sourcesView.viewForFile(uiSourceCode);var start=[0,0];if(sourceFrame){var selection=sourceFrame.selection();start=formatterMapping.originalToFormatted(selection.startLine,selection.startColumn);} uiSourceCode.setWorkingCopy(formattedContent);this._sourcesView.showSourceLocation(uiSourceCode,start[0],start[1]);}},};WebInspector.Formatter=function() {} WebInspector.Formatter.format=function(contentType,mimeType,content,callback) {if(contentType.isDocumentOrScriptOrStyleSheet()) new WebInspector.ScriptFormatter(mimeType,content,callback);else new WebInspector.IdentityFormatter(mimeType,content,callback);} WebInspector.Formatter.locationToPosition=function(lineEndings,lineNumber,columnNumber) {var position=lineNumber?lineEndings[lineNumber-1]+1:0;return position+columnNumber;} WebInspector.Formatter.positionToLocation=function(lineEndings,position) {var lineNumber=lineEndings.upperBound(position-1);if(!lineNumber) var columnNumber=position;else var columnNumber=position-lineEndings[lineNumber-1]-1;return[lineNumber,columnNumber];} WebInspector.ScriptFormatter=function(mimeType,content,callback) {content=content.replace(/\r\n?|[\n\u2028\u2029]/g,"\n").replace(/^\uFEFF/,"");this._callback=callback;this._originalContent=content;var parameters={mimeType:mimeType,content:content,indentString:WebInspector.moduleSetting("textEditorIndent").get()};WebInspector.formatterWorkerPool.runTask("format",parameters).then(this._didFormatContent.bind(this));} WebInspector.ScriptFormatter.prototype={_didFormatContent:function(event) {var formattedContent="";var mapping=[];if(event){formattedContent=event.data.content;mapping=event.data["mapping"];} var sourceMapping=new WebInspector.FormatterSourceMappingImpl(this._originalContent.computeLineEndings(),formattedContent.computeLineEndings(),mapping);this._callback(formattedContent,sourceMapping);}} WebInspector.IdentityFormatter=function(mimeType,content,callback) {callback(content,new WebInspector.IdentityFormatterSourceMapping());} WebInspector.FormatterMappingPayload;WebInspector.FormatterSourceMapping=function() {} WebInspector.FormatterSourceMapping.prototype={originalToFormatted:function(lineNumber,columnNumber){},formattedToOriginal:function(lineNumber,columnNumber){}} WebInspector.IdentityFormatterSourceMapping=function() {} WebInspector.IdentityFormatterSourceMapping.prototype={originalToFormatted:function(lineNumber,columnNumber) {return[lineNumber,columnNumber||0];},formattedToOriginal:function(lineNumber,columnNumber) {return[lineNumber,columnNumber||0];}} WebInspector.FormatterSourceMappingImpl=function(originalLineEndings,formattedLineEndings,mapping) {this._originalLineEndings=originalLineEndings;this._formattedLineEndings=formattedLineEndings;this._mapping=mapping;} WebInspector.FormatterSourceMappingImpl.prototype={originalToFormatted:function(lineNumber,columnNumber) {var originalPosition=WebInspector.Formatter.locationToPosition(this._originalLineEndings,lineNumber,columnNumber||0);var formattedPosition=this._convertPosition(this._mapping.original,this._mapping.formatted,originalPosition||0);return WebInspector.Formatter.positionToLocation(this._formattedLineEndings,formattedPosition);},formattedToOriginal:function(lineNumber,columnNumber) {var formattedPosition=WebInspector.Formatter.locationToPosition(this._formattedLineEndings,lineNumber,columnNumber||0);var originalPosition=this._convertPosition(this._mapping.formatted,this._mapping.original,formattedPosition);return WebInspector.Formatter.positionToLocation(this._originalLineEndings,originalPosition||0);},_convertPosition:function(positions1,positions2,position) {var index=positions1.upperBound(position)-1;var convertedPosition=positions2[index]+position-positions1[index];if(index<positions2.length-1&&convertedPosition>positions2[index+1]) convertedPosition=positions2[index+1];return convertedPosition;}};WebInspector.OpenResourceDialog=function(sourcesView,defaultScores,history) {WebInspector.FilteredUISourceCodeListDelegate.call(this,defaultScores,history);this._sourcesView=sourcesView;} WebInspector.OpenResourceDialog.prototype={uiSourceCodeSelected:function(uiSourceCode,lineNumber,columnNumber) {if(!uiSourceCode) uiSourceCode=this._sourcesView.currentUISourceCode();if(!uiSourceCode) return;this._sourcesView.showSourceLocation(uiSourceCode,lineNumber,columnNumber);},shouldShowMatchingItems:function(query) {return!query.startsWith(":");},filterProject:function(project) {return!WebInspector.Project.isServiceProject(project);},renderAsTwoRows:function() {return true;},__proto__:WebInspector.FilteredUISourceCodeListDelegate.prototype} WebInspector.OpenResourceDialog.show=function(sourcesView,query,defaultScores,history) {var filteredItemSelectionDialog=new WebInspector.FilteredListWidget(new WebInspector.OpenResourceDialog(sourcesView,defaultScores,history));filteredItemSelectionDialog.showAsDialog();filteredItemSelectionDialog.setQuery(query);} WebInspector.SelectUISourceCodeForProjectTypesDialog=function(types,callback) {this._types=types;WebInspector.FilteredUISourceCodeListDelegate.call(this);this._callback=callback;} WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype={uiSourceCodeSelected:function(uiSourceCode,lineNumber,columnNumber) {this._callback(uiSourceCode);},filterProject:function(project) {return this._types.indexOf(project.type())!==-1;},renderAsTwoRows:function() {return true;},__proto__:WebInspector.FilteredUISourceCodeListDelegate.prototype} WebInspector.SelectUISourceCodeForProjectTypesDialog.show=function(name,types,callback) {var filteredItemSelectionDialog=new WebInspector.FilteredListWidget(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types,callback));filteredItemSelectionDialog.showAsDialog();filteredItemSelectionDialog.setQuery(name);};WebInspector.SourcesView=function(workspace,sourcesPanel) {WebInspector.VBox.call(this);this.registerRequiredCSS("sources/sourcesView.css");this.element.id="sources-panel-sources-view";this.setMinimumAndPreferredSizes(50,52,150,100);this._workspace=workspace;this._sourcesPanel=sourcesPanel;this._searchableView=new WebInspector.SearchableView(this,"sourcesViewSearchConfig");this._searchableView.setMinimalSearchQuerySize(0);this._searchableView.show(this.element);this._sourceViewByUISourceCode=new Map();var tabbedEditorPlaceholderText=WebInspector.isMac()?WebInspector.UIString("Hit Cmd+P to open a file"):WebInspector.UIString("Hit Ctrl+P to open a file");this._editorContainer=new WebInspector.TabbedEditorContainer(this,WebInspector.settings.createLocalSetting("previouslyViewedFiles",[]),tabbedEditorPlaceholderText);this._editorContainer.show(this._searchableView.element);this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected,this._editorSelected,this);this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed,this._editorClosed,this);this._historyManager=new WebInspector.EditingLocationHistoryManager(this,this.currentSourceFrame.bind(this));this._toolbarContainerElement=this.element.createChild("div","sources-toolbar");this._toolbarEditorActions=new WebInspector.Toolbar("",this._toolbarContainerElement);self.runtime.instancesPromise(WebInspector.SourcesView.EditorAction).then(appendButtonsForExtensions.bind(this));function appendButtonsForExtensions(actions) {for(var i=0;i<actions.length;++i) this._toolbarEditorActions.appendToolbarItem(actions[i].button(this));} this._scriptViewToolbar=new WebInspector.Toolbar("",this._toolbarContainerElement);WebInspector.startBatchUpdate();this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));WebInspector.endBatchUpdate();this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,this._uiSourceCodeAdded,this);this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved,this._uiSourceCodeRemoved,this);this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved,this._projectRemoved.bind(this),this);function handleBeforeUnload(event) {if(event.returnValue) return;var unsavedSourceCodes=WebInspector.workspace.unsavedSourceCodes();if(!unsavedSourceCodes.length) return;event.returnValue=WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());for(var i=0;i<unsavedSourceCodes.length;++i) WebInspector.Revealer.reveal(unsavedSourceCodes[i]);} if(!window.opener) window.addEventListener("beforeunload",handleBeforeUnload,true);this._shortcuts={};this.element.addEventListener("keydown",this._handleKeyDown.bind(this),false);} WebInspector.SourcesView.Events={EditorClosed:"EditorClosed",EditorSelected:"EditorSelected",} WebInspector.SourcesView.prototype={registerShortcuts:function(registerShortcutDelegate) {function registerShortcut(shortcuts,handler) {registerShortcutDelegate(shortcuts,handler);this._registerShortcuts(shortcuts,handler);} registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation,this._onJumpToPreviousLocation.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation,this._onJumpToNextLocation.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab,this._onCloseEditorTab.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine,this._showGoToLineDialog.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember,this._showOutlineDialog.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint,this._toggleBreakpoint.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.Save,this._save.bind(this));registerShortcut.call(this,WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SaveAll,this._saveAll.bind(this));},_registerShortcuts:function(keys,handler) {for(var i=0;i<keys.length;++i) this._shortcuts[keys[i].key]=handler;},_handleKeyDown:function(event) {var shortcutKey=WebInspector.KeyboardShortcut.makeKeyFromEvent(event);var handler=this._shortcuts[shortcutKey];if(handler&&handler()) event.consume(true);},wasShown:function() {WebInspector.VBox.prototype.wasShown.call(this);WebInspector.context.setFlavor(WebInspector.SourcesView,this);},willHide:function() {WebInspector.context.setFlavor(WebInspector.SourcesView,null);WebInspector.VBox.prototype.willHide.call(this);},toolbarContainerElement:function() {return this._toolbarContainerElement;},defaultFocusedElement:function() {return this._editorContainer.view.defaultFocusedElement();},searchableView:function() {return this._searchableView;},visibleView:function() {return this._editorContainer.visibleView;},currentSourceFrame:function() {var view=this.visibleView();if(!(view instanceof WebInspector.UISourceCodeFrame)) return null;return(view);},currentUISourceCode:function() {return this._currentUISourceCode;},_onCloseEditorTab:function(event) {var uiSourceCode=this.currentUISourceCode();if(!uiSourceCode) return false;this._editorContainer.closeFile(uiSourceCode);return true;},_onJumpToPreviousLocation:function(event) {this._historyManager.rollback();return true;},_onJumpToNextLocation:function(event) {this._historyManager.rollover();return true;},_uiSourceCodeAdded:function(event) {var uiSourceCode=(event.data);this._addUISourceCode(uiSourceCode);},_addUISourceCode:function(uiSourceCode) {if(uiSourceCode.isFromServiceProject()) return;this._editorContainer.addUISourceCode(uiSourceCode);var currentUISourceCode=this._currentUISourceCode;if(!currentUISourceCode) return;var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);var currentNetworkURL=WebInspector.networkMapping.networkURL(currentUISourceCode);if(currentUISourceCode.isFromServiceProject()&¤tUISourceCode!==uiSourceCode&¤tNetworkURL===networkURL&&networkURL){this._showFile(uiSourceCode);this._editorContainer.removeUISourceCode(currentUISourceCode);}},_uiSourceCodeRemoved:function(event) {var uiSourceCode=(event.data);this._removeUISourceCodes([uiSourceCode]);},_removeUISourceCodes:function(uiSourceCodes) {this._editorContainer.removeUISourceCodes(uiSourceCodes);for(var i=0;i<uiSourceCodes.length;++i){this._removeSourceFrame(uiSourceCodes[i]);this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);}},_projectRemoved:function(event) {var project=event.data;var uiSourceCodes=project.uiSourceCodes();this._removeUISourceCodes(uiSourceCodes);},_updateScriptViewToolbarItems:function() {this._scriptViewToolbar.removeToolbarItems();var view=(this.visibleView());if(view){for(var item of view.toolbarItems()) this._scriptViewToolbar.appendToolbarItem(item);}},showSourceLocation:function(uiSourceCode,lineNumber,columnNumber,omitFocus,omitHighlight) {this._historyManager.updateCurrentState();var sourceView=this._showFile(uiSourceCode);if(typeof lineNumber==="number"&&sourceView instanceof WebInspector.UISourceCodeFrame) (sourceView).revealPosition(lineNumber,columnNumber,!omitHighlight);this._historyManager.pushNewState();if(!omitFocus) sourceView.focus();},_showFile:function(uiSourceCode) {var sourceView=this._getOrCreateSourceView(uiSourceCode);if(this._currentUISourceCode===uiSourceCode) return sourceView;var currentFrame=this.currentSourceFrame();if(currentFrame) currentFrame.setSearchableView(null);this._currentUISourceCode=uiSourceCode;this._editorContainer.showFile(uiSourceCode);this._updateScriptViewToolbarItems();currentFrame=this.currentSourceFrame();if(currentFrame) currentFrame.setSearchableView(this._searchableView);return sourceView;},_createSourceView:function(uiSourceCode) {var sourceFrame;var sourceView;var contentType=uiSourceCode.contentType();if(contentType.hasScripts()) sourceFrame=new WebInspector.JavaScriptSourceFrame(this._sourcesPanel,uiSourceCode);else if(contentType.isStyleSheet()) sourceFrame=new WebInspector.CSSSourceFrame(uiSourceCode);else if(contentType===WebInspector.resourceTypes.Image) sourceView=new WebInspector.ImageView(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode),uiSourceCode);else if(contentType===WebInspector.resourceTypes.Font) sourceView=new WebInspector.FontView(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode),uiSourceCode);else sourceFrame=new WebInspector.UISourceCodeFrame(uiSourceCode);if(sourceFrame){sourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode));this._historyManager.trackSourceFrameCursorJumps(sourceFrame);} this._sourceViewByUISourceCode.set(uiSourceCode,(sourceFrame||sourceView));return(sourceFrame||sourceView);},_getOrCreateSourceView:function(uiSourceCode) {return this._sourceViewByUISourceCode.get(uiSourceCode)||this._createSourceView(uiSourceCode);},_sourceFrameMatchesUISourceCode:function(sourceFrame,uiSourceCode) {if(uiSourceCode.contentType().hasScripts()) return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;if(uiSourceCode.contentType().isStyleSheet()) return sourceFrame instanceof WebInspector.CSSSourceFrame;return!(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);},_recreateSourceFrameIfNeeded:function(uiSourceCode) {var oldSourceView=this._sourceViewByUISourceCode.get(uiSourceCode);if(!oldSourceView||!(oldSourceView instanceof WebInspector.UISourceCodeFrame)) return;var oldSourceFrame=(oldSourceView);if(this._sourceFrameMatchesUISourceCode(oldSourceFrame,uiSourceCode)){oldSourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCodeMimeType(uiSourceCode));}else{this._editorContainer.removeUISourceCode(uiSourceCode);this._removeSourceFrame(uiSourceCode);}},viewForFile:function(uiSourceCode) {return this._getOrCreateSourceView(uiSourceCode);},_removeSourceFrame:function(uiSourceCode) {var sourceView=this._sourceViewByUISourceCode.get(uiSourceCode);this._sourceViewByUISourceCode.remove(uiSourceCode);if(sourceView&&sourceView instanceof WebInspector.UISourceCodeFrame) (sourceView).dispose();},clearCurrentExecutionLine:function() {if(this._executionSourceFrame) this._executionSourceFrame.clearExecutionLine();delete this._executionSourceFrame;},setExecutionLocation:function(uiLocation) {var sourceView=this._getOrCreateSourceView(uiLocation.uiSourceCode);if(sourceView instanceof WebInspector.UISourceCodeFrame){var sourceFrame=(sourceView);sourceFrame.setExecutionLocation(uiLocation);this._executionSourceFrame=sourceFrame;}},_editorClosed:function(event) {var uiSourceCode=(event.data);this._historyManager.removeHistoryForSourceCode(uiSourceCode);var wasSelected=false;if(this._currentUISourceCode===uiSourceCode){delete this._currentUISourceCode;wasSelected=true;} this._updateScriptViewToolbarItems();this._searchableView.resetSearch();var data={};data.uiSourceCode=uiSourceCode;data.wasSelected=wasSelected;this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClosed,data);},_editorSelected:function(event) {var uiSourceCode=(event.data.currentFile);var shouldUseHistoryManager=uiSourceCode!==this._currentUISourceCode&&event.data.userGesture;if(shouldUseHistoryManager) this._historyManager.updateCurrentState();var sourceView=this._showFile(uiSourceCode);if(shouldUseHistoryManager) this._historyManager.pushNewState();this._searchableView.setReplaceable(sourceView instanceof WebInspector.UISourceCodeFrame&&(sourceView).canEditSource());this._searchableView.refreshSearch();this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSelected,uiSourceCode);},sourceRenamed:function(uiSourceCode) {this._recreateSourceFrameIfNeeded(uiSourceCode);},searchCanceled:function() {if(this._searchView) this._searchView.searchCanceled();delete this._searchView;delete this._searchConfig;},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var sourceFrame=this.currentSourceFrame();if(!sourceFrame) return;this._searchView=sourceFrame;this._searchConfig=searchConfig;this._searchView.performSearch(this._searchConfig,shouldJump,jumpBackwards);},jumpToNextSearchResult:function() {if(!this._searchView) return;if(this._searchView!==this.currentSourceFrame()){this.performSearch(this._searchConfig,true);return;} this._searchView.jumpToNextSearchResult();},jumpToPreviousSearchResult:function() {if(!this._searchView) return;if(this._searchView!==this.currentSourceFrame()){this.performSearch(this._searchConfig,true);if(this._searchView) this._searchView.jumpToLastSearchResult();return;} this._searchView.jumpToPreviousSearchResult();},supportsCaseSensitiveSearch:function() {return true;},supportsRegexSearch:function() {return true;},replaceSelectionWith:function(searchConfig,replacement) {var sourceFrame=this.currentSourceFrame();if(!sourceFrame){console.assert(sourceFrame);return;} sourceFrame.replaceSelectionWith(searchConfig,replacement);},replaceAllWith:function(searchConfig,replacement) {var sourceFrame=this.currentSourceFrame();if(!sourceFrame){console.assert(sourceFrame);return;} sourceFrame.replaceAllWith(searchConfig,replacement);},_showOutlineDialog:function(event) {var uiSourceCode=this._editorContainer.currentFile();if(!uiSourceCode) return false;if(uiSourceCode.contentType().hasScripts()){WebInspector.JavaScriptOutlineDialog.show(uiSourceCode,this.showSourceLocation.bind(this,uiSourceCode));return true;} if(uiSourceCode.contentType().isStyleSheet()){WebInspector.StyleSheetOutlineDialog.show(uiSourceCode,this.showSourceLocation.bind(this,uiSourceCode));return true;} return true;},showOpenResourceDialog:function(query) {var uiSourceCodes=this._editorContainer.historyUISourceCodes();var defaultScores=new Map();for(var i=1;i<uiSourceCodes.length;++i) defaultScores.set(uiSourceCodes[i],uiSourceCodes.length-i);if(!this._openResourceDialogHistory) this._openResourceDialogHistory=[];WebInspector.OpenResourceDialog.show(this,query||"",defaultScores,this._openResourceDialogHistory);},_showGoToLineDialog:function(event) {if(this._currentUISourceCode) this.showOpenResourceDialog(":");return true;},_save:function() {this._saveSourceFrame(this.currentSourceFrame());return true;},_saveAll:function() {var sourceFrames=this._editorContainer.fileViews();sourceFrames.forEach(this._saveSourceFrame.bind(this));return true;},_saveSourceFrame:function(sourceFrame) {if(!(sourceFrame instanceof WebInspector.UISourceCodeFrame)) return;var uiSourceCodeFrame=(sourceFrame);uiSourceCodeFrame.commitEditing();},_toggleBreakpoint:function() {var sourceFrame=this.currentSourceFrame();if(!sourceFrame) return false;if(sourceFrame instanceof WebInspector.JavaScriptSourceFrame){var javaScriptSourceFrame=(sourceFrame);javaScriptSourceFrame.toggleBreakpointOnCurrentLine();return true;} return false;},toggleBreakpointsActiveState:function(active) {this._editorContainer.view.element.classList.toggle("breakpoints-deactivated",!active);},__proto__:WebInspector.VBox.prototype} WebInspector.SourcesView.EditorAction=function() {} WebInspector.SourcesView.EditorAction.prototype={button:function(sourcesView){}} WebInspector.SourcesView.SwitchFileActionDelegate=function() {} WebInspector.SourcesView.SwitchFileActionDelegate._nextFile=function(currentUISourceCode) {function fileNamePrefix(name) {var lastDotIndex=name.lastIndexOf(".");var namePrefix=name.substr(0,lastDotIndex!==-1?lastDotIndex:name.length);return namePrefix.toLowerCase();} var uiSourceCodes=currentUISourceCode.project().uiSourceCodes();var candidates=[];var url=currentUISourceCode.parentURL();var name=currentUISourceCode.name();var namePrefix=fileNamePrefix(name);for(var i=0;i<uiSourceCodes.length;++i){var uiSourceCode=uiSourceCodes[i];if(url!==uiSourceCode.parentURL()) continue;if(fileNamePrefix(uiSourceCode.name())===namePrefix) candidates.push(uiSourceCode.name());} candidates.sort(String.naturalOrderComparator);var index=mod(candidates.indexOf(name)+1,candidates.length);var fullURL=(url?url+"/":"")+candidates[index];var nextUISourceCode=currentUISourceCode.project().uiSourceCodeForURL(fullURL);return nextUISourceCode!==currentUISourceCode?nextUISourceCode:null;} WebInspector.SourcesView.SwitchFileActionDelegate.prototype={handleAction:function(context,actionId) {var sourcesView=WebInspector.context.flavor(WebInspector.SourcesView);var currentUISourceCode=sourcesView.currentUISourceCode();if(!currentUISourceCode) return false;var nextUISourceCode=WebInspector.SourcesView.SwitchFileActionDelegate._nextFile(currentUISourceCode);if(!nextUISourceCode) return false;sourcesView.showSourceLocation(nextUISourceCode);return true;}};WebInspector.AdvancedSearchView=function() {WebInspector.VBox.call(this,true);this.setMinimumSize(0,40);this.registerRequiredCSS("sources/sourcesSearch.css");this._searchId=0;this.contentElement.classList.add("search-view");this._searchPanelElement=this.contentElement.createChild("div","search-drawer-header");this._searchPanelElement.addEventListener("keydown",this._onKeyDown.bind(this),false);this._searchPanelElement.addEventListener("input",this._onInput.bind(this),false);this._searchResultsElement=this.contentElement.createChild("div");this._searchResultsElement.className="search-results";this._search=WebInspector.HistoryInput.create();this._searchPanelElement.appendChild(this._search);this._search.placeholder=WebInspector.UIString("Search all sources (use \"file:\" to filter by path)\u200e");this._search.setAttribute("type","text");this._search.classList.add("search-config-search");this._search.setAttribute("results","0");this._search.setAttribute("size",42);this._searchPanelElement.createChild("div","search-icon");this._searchInputClearElement=this._searchPanelElement.createChild("div","search-cancel-button");this._searchInputClearElement.hidden=true;this._searchInputClearElement.addEventListener("click",this._onSearchInputClear.bind(this),false);this._ignoreCaseLabel=createCheckboxLabel(WebInspector.UIString("Ignore case"));this._ignoreCaseLabel.classList.add("search-config-label");this._searchPanelElement.appendChild(this._ignoreCaseLabel);this._ignoreCaseCheckbox=this._ignoreCaseLabel.checkboxElement;this._ignoreCaseCheckbox.classList.add("search-config-checkbox");this._regexLabel=createCheckboxLabel(WebInspector.UIString("Regular expression"));this._regexLabel.classList.add("search-config-label");this._searchPanelElement.appendChild(this._regexLabel);this._regexCheckbox=this._regexLabel.checkboxElement;this._regexCheckbox.classList.add("search-config-checkbox");this._searchToolbarElement=this.contentElement.createChild("div","search-toolbar-summary");this._searchMessageElement=this._searchToolbarElement.createChild("div","search-message");this._searchProgressPlaceholderElement=this._searchToolbarElement.createChild("div","flex-centered");this._searchResultsMessageElement=this._searchToolbarElement.createChild("div","search-message");this._advancedSearchConfig=WebInspector.settings.createLocalSetting("advancedSearchConfig",new WebInspector.SearchConfig("",true,false).toPlainObject());this._load();this._searchScope=new WebInspector.SourcesSearchScope();} WebInspector.AdvancedSearchView.prototype={_buildSearchConfig:function() {return new WebInspector.SearchConfig(this._search.value,this._ignoreCaseCheckbox.checked,this._regexCheckbox.checked);},_toggle:function(queryCandidate) {if(queryCandidate) this._search.value=queryCandidate;this.focus();this._startIndexing();},_onIndexingFinished:function() {var finished=!this._progressIndicator.isCanceled();this._progressIndicator.done();delete this._progressIndicator;delete this._isIndexing;this._indexingFinished(finished);if(!finished) delete this._pendingSearchConfig;if(!this._pendingSearchConfig) return;var searchConfig=this._pendingSearchConfig;delete this._pendingSearchConfig;this._innerStartSearch(searchConfig);},_startIndexing:function() {this._isIndexing=true;if(this._progressIndicator) this._progressIndicator.done();this._progressIndicator=new WebInspector.ProgressIndicator();this._searchMessageElement.textContent=WebInspector.UIString("Indexing\u2026");this._progressIndicator.show(this._searchProgressPlaceholderElement);this._searchScope.performIndexing(new WebInspector.ProgressProxy(this._progressIndicator,this._onIndexingFinished.bind(this)));},_onSearchInputClear:function() {this._search.value="";this.focus();this._searchInputClearElement.hidden=true;},_onSearchResult:function(searchId,searchResult) {if(searchId!==this._searchId||!this._progressIndicator) return;if(this._progressIndicator&&this._progressIndicator.isCanceled()){this._onIndexingFinished();return;} this._addSearchResult(searchResult);if(!searchResult.searchMatches.length) return;if(!this._searchResultsPane) this._searchResultsPane=this._searchScope.createSearchResultsPane(this._searchConfig);this._resetResults();this._searchResultsElement.appendChild(this._searchResultsPane.element);this._searchResultsPane.addSearchResult(searchResult);},_onSearchFinished:function(searchId,finished) {if(searchId!==this._searchId||!this._progressIndicator) return;if(!this._searchResultsPane) this._nothingFound();this._searchFinished(finished);delete this._searchConfig;},_startSearch:function(searchConfig) {this._resetSearch();++this._searchId;if(!this._isIndexing) this._startIndexing();this._pendingSearchConfig=searchConfig;},_innerStartSearch:function(searchConfig) {this._searchConfig=searchConfig;if(this._progressIndicator) this._progressIndicator.done();this._progressIndicator=new WebInspector.ProgressIndicator();this._searchStarted(this._progressIndicator);this._searchScope.performSearch(searchConfig,this._progressIndicator,this._onSearchResult.bind(this,this._searchId),this._onSearchFinished.bind(this,this._searchId));},_resetSearch:function() {this._stopSearch();if(this._searchResultsPane){this._resetResults();delete this._searchResultsPane;}},_stopSearch:function() {if(this._progressIndicator&&!this._isIndexing) this._progressIndicator.cancel();if(this._searchScope) this._searchScope.stopSearch();delete this._searchConfig;},_searchStarted:function(progressIndicator) {this._resetResults();this._resetCounters();this._searchMessageElement.textContent=WebInspector.UIString("Searching\u2026");progressIndicator.show(this._searchProgressPlaceholderElement);this._updateSearchResultsMessage();if(!this._searchingView) this._searchingView=new WebInspector.EmptyWidget(WebInspector.UIString("Searching\u2026"));this._searchingView.show(this._searchResultsElement);},_indexingFinished:function(finished) {this._searchMessageElement.textContent=finished?"":WebInspector.UIString("Indexing interrupted.");},_updateSearchResultsMessage:function() {if(this._searchMatchesCount&&this._searchResultsCount) this._searchResultsMessageElement.textContent=WebInspector.UIString("Found %d matches in %d files.",this._searchMatchesCount,this._nonEmptySearchResultsCount);else this._searchResultsMessageElement.textContent="";},_resetResults:function() {if(this._searchingView) this._searchingView.detach();if(this._notFoundView) this._notFoundView.detach();this._searchResultsElement.removeChildren();},_resetCounters:function() {this._searchMatchesCount=0;this._searchResultsCount=0;this._nonEmptySearchResultsCount=0;},_nothingFound:function() {this._resetResults();if(!this._notFoundView) this._notFoundView=new WebInspector.EmptyWidget(WebInspector.UIString("No matches found."));this._notFoundView.show(this._searchResultsElement);this._searchResultsMessageElement.textContent=WebInspector.UIString("No matches found.");},_addSearchResult:function(searchResult) {this._searchMatchesCount+=searchResult.searchMatches.length;this._searchResultsCount++;if(searchResult.searchMatches.length) this._nonEmptySearchResultsCount++;this._updateSearchResultsMessage();},_searchFinished:function(finished) {this._searchMessageElement.textContent=finished?WebInspector.UIString("Search finished."):WebInspector.UIString("Search interrupted.");},focus:function() {WebInspector.setCurrentFocusElement(this._search);this._search.select();},willHide:function() {this._stopSearch();},_onKeyDown:function(event) {switch(event.keyCode){case WebInspector.KeyboardShortcut.Keys.Enter.code:this._onAction();break;}},_onInput:function() {if(this._search.value&&this._search.value.length) this._searchInputClearElement.hidden=false;else this._searchInputClearElement.hidden=true;},_save:function() {this._advancedSearchConfig.set(this._buildSearchConfig().toPlainObject());},_load:function() {var searchConfig=WebInspector.SearchConfig.fromPlainObject(this._advancedSearchConfig.get());this._search.value=searchConfig.query();this._ignoreCaseCheckbox.checked=searchConfig.ignoreCase();this._regexCheckbox.checked=searchConfig.isRegex();if(this._search.value&&this._search.value.length) this._searchInputClearElement.hidden=false;},_onAction:function() {var searchConfig=this._buildSearchConfig();if(!searchConfig.query()||!searchConfig.query().length) return;this._save();this._startSearch(searchConfig);},__proto__:WebInspector.VBox.prototype} WebInspector.AdvancedSearchView.openSearch=function(query,filePath) {function updateSearchBox(view) {console.assert(view&&view instanceof WebInspector.AdvancedSearchView);var searchView=(view);if(searchView._search!==searchView.element.window().document.activeElement){WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());var fileMask=filePath?" file:"+filePath:"";searchView._toggle(query+fileMask);searchView.focus();} return searchView;} return WebInspector.inspectorView.showViewInDrawer("sources.search").then(updateSearchBox);} WebInspector.SearchResultsPane=function(searchConfig) {this._searchConfig=searchConfig;this.element=createElement("div");} WebInspector.SearchResultsPane.prototype={get searchConfig() {return this._searchConfig;},addSearchResult:function(searchResult){}} WebInspector.AdvancedSearchView.ActionDelegate=function() {} WebInspector.AdvancedSearchView.ActionDelegate.prototype={handleAction:function(context,actionId) {this._showSearch();return true;},_showSearch:function() {var selection=WebInspector.inspectorView.element.getDeepSelection();var queryCandidate="";if(selection.rangeCount) queryCandidate=selection.toString().replace(/\r?\n.*/,"");return WebInspector.AdvancedSearchView.openSearch(queryCandidate);},} WebInspector.FileBasedSearchResult=function(uiSourceCode,searchMatches){this.uiSourceCode=uiSourceCode;this.searchMatches=searchMatches;} WebInspector.SearchScope=function() {} WebInspector.SearchScope.prototype={performSearch:function(searchConfig,progress,searchResultCallback,searchFinishedCallback){},performIndexing:function(progress){},stopSearch:function(){},createSearchResultsPane:function(searchConfig){}};WebInspector.FileBasedSearchResultsPane=function(searchConfig) {WebInspector.SearchResultsPane.call(this,searchConfig);this._searchResults=[];this.element.id="search-results-pane-file-based";this._treeOutline=new TreeOutline();this._treeOutline.element.classList.add("search-results-outline-disclosure");this.element.appendChild(this._treeOutline.element);this._matchesExpandedCount=0;} WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount=20;WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce=20;WebInspector.FileBasedSearchResultsPane.prototype={addSearchResult:function(searchResult) {this._searchResults.push(searchResult);var uiSourceCode=searchResult.uiSourceCode;if(!uiSourceCode) return;this._addFileTreeElement(searchResult);},_addFileTreeElement:function(searchResult) {var fileTreeElement=new WebInspector.FileBasedSearchResultsPane.FileTreeElement(this._searchConfig,searchResult);this._treeOutline.appendChild(fileTreeElement);if(this._matchesExpandedCount<WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount) fileTreeElement.expand();this._matchesExpandedCount+=searchResult.searchMatches.length;},__proto__:WebInspector.SearchResultsPane.prototype} WebInspector.FileBasedSearchResultsPane.FileTreeElement=function(searchConfig,searchResult) {TreeElement.call(this,"",true);this._searchConfig=searchConfig;this._searchResult=searchResult;this.toggleOnClick=true;this.selectable=false;} WebInspector.FileBasedSearchResultsPane.FileTreeElement.prototype={onexpand:function() {if(this._initialized) return;this._updateMatchesUI();this._initialized=true;},_updateMatchesUI:function() {this.removeChildren();var toIndex=Math.min(this._searchResult.searchMatches.length,WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);if(toIndex<this._searchResult.searchMatches.length){this._appendSearchMatches(0,toIndex-1);this._appendShowMoreMatchesElement(toIndex-1);}else{this._appendSearchMatches(0,toIndex);}},onattach:function() {this._updateSearchMatches();},_updateSearchMatches:function() {this.listItemElement.classList.add("search-result");var fileNameSpan=createElement("span");fileNameSpan.className="search-result-file-name";fileNameSpan.textContent=this._searchResult.uiSourceCode.fullDisplayName();this.listItemElement.appendChild(fileNameSpan);var matchesCountSpan=createElement("span");matchesCountSpan.className="search-result-matches-count";var searchMatchesCount=this._searchResult.searchMatches.length;if(searchMatchesCount===1) matchesCountSpan.textContent=WebInspector.UIString("(%d match)",searchMatchesCount);else matchesCountSpan.textContent=WebInspector.UIString("(%d matches)",searchMatchesCount);this.listItemElement.appendChild(matchesCountSpan);if(this.expanded) this._updateMatchesUI();},_appendSearchMatches:function(fromIndex,toIndex) {var searchResult=this._searchResult;var uiSourceCode=searchResult.uiSourceCode;var searchMatches=searchResult.searchMatches;var queries=this._searchConfig.queries();var regexes=[];for(var i=0;i<queries.length;++i) regexes.push(createSearchRegex(queries[i],!this._searchConfig.ignoreCase(),this._searchConfig.isRegex()));for(var i=fromIndex;i<toIndex;++i){var lineNumber=searchMatches[i].lineNumber;var lineContent=searchMatches[i].lineContent;var matchRanges=[];for(var j=0;j<regexes.length;++j) matchRanges=matchRanges.concat(this._regexMatchRanges(lineContent,regexes[j]));var anchor=this._createAnchor(uiSourceCode,lineNumber,matchRanges[0].offset);var numberString=numberToStringWithSpacesPadding(lineNumber+1,4);var lineNumberSpan=createElement("span");lineNumberSpan.classList.add("search-match-line-number");lineNumberSpan.textContent=numberString;anchor.appendChild(lineNumberSpan);var contentSpan=this._createContentSpan(lineContent,matchRanges);anchor.appendChild(contentSpan);var searchMatchElement=new TreeElement();searchMatchElement.selectable=false;this.appendChild(searchMatchElement);searchMatchElement.listItemElement.className="search-match source-code";searchMatchElement.listItemElement.appendChild(anchor);}},_appendShowMoreMatchesElement:function(startMatchIndex) {var matchesLeftCount=this._searchResult.searchMatches.length-startMatchIndex;var showMoreMatchesText=WebInspector.UIString("Show all matches (%d more).",matchesLeftCount);this._showMoreMatchesTreeElement=new TreeElement(showMoreMatchesText);this.appendChild(this._showMoreMatchesTreeElement);this._showMoreMatchesTreeElement.listItemElement.classList.add("show-more-matches");this._showMoreMatchesTreeElement.onselect=this._showMoreMatchesElementSelected.bind(this,startMatchIndex);},_createAnchor:function(uiSourceCode,lineNumber,columnNumber) {return WebInspector.Linkifier.linkifyUsingRevealer(uiSourceCode.uiLocation(lineNumber,columnNumber),"");},_createContentSpan:function(lineContent,matchRanges) {var contentSpan=createElement("span");contentSpan.className="search-match-content";contentSpan.textContent=lineContent;WebInspector.highlightRangesWithStyleClass(contentSpan,matchRanges,"highlighted-match");return contentSpan;},_regexMatchRanges:function(lineContent,regex) {regex.lastIndex=0;var match;var matchRanges=[];while((regex.lastIndex<lineContent.length)&&(match=regex.exec(lineContent))) matchRanges.push(new WebInspector.SourceRange(match.index,match[0].length));return matchRanges;},_showMoreMatchesElementSelected:function(startMatchIndex) {this.removeChild(this._showMoreMatchesTreeElement);this._appendSearchMatches(startMatchIndex,this._searchResult.searchMatches.length);return false;},__proto__:TreeElement.prototype};WebInspector.SourcesSearchScope=function() {this._searchId=0;} WebInspector.SourcesSearchScope._filesComparator=function(uiSourceCode1,uiSourceCode2) {if(uiSourceCode1.isDirty()&&!uiSourceCode2.isDirty()) return-1;if(!uiSourceCode1.isDirty()&&uiSourceCode2.isDirty()) return 1;var networkURL1=WebInspector.networkMapping.networkURL(uiSourceCode1);var networkURL2=WebInspector.networkMapping.networkURL(uiSourceCode2);if(networkURL1&&!networkURL2) return-1;if(!networkURL1&&networkURL2) return 1;return String.naturalOrderComparator(uiSourceCode1.fullDisplayName(),uiSourceCode2.fullDisplayName());} WebInspector.SourcesSearchScope.prototype={performIndexing:function(progress) {this.stopSearch();var projects=this._projects();var compositeProgress=new WebInspector.CompositeProgress(progress);for(var i=0;i<projects.length;++i){var project=projects[i];var projectProgress=compositeProgress.createSubProgress(project.uiSourceCodes().length);project.indexContent(projectProgress);}},_projects:function() {function filterOutServiceProjects(project) {return project.type()!==WebInspector.projectTypes.Service;} function filterOutContentScriptsIfNeeded(project) {return WebInspector.moduleSetting("searchInContentScripts").get()||project.type()!==WebInspector.projectTypes.ContentScripts;} return WebInspector.workspace.projects().filter(filterOutServiceProjects).filter(filterOutContentScriptsIfNeeded);},performSearch:function(searchConfig,progress,searchResultCallback,searchFinishedCallback) {this.stopSearch();this._searchResultCandidates=[];this._searchResultCallback=searchResultCallback;this._searchFinishedCallback=searchFinishedCallback;this._searchConfig=searchConfig;var projects=this._projects();var barrier=new CallbackBarrier();var compositeProgress=new WebInspector.CompositeProgress(progress);var searchContentProgress=compositeProgress.createSubProgress();var findMatchingFilesProgress=new WebInspector.CompositeProgress(compositeProgress.createSubProgress());for(var i=0;i<projects.length;++i){var project=projects[i];var weight=project.uiSourceCodes().length;var findMatchingFilesInProjectProgress=findMatchingFilesProgress.createSubProgress(weight);var barrierCallback=barrier.createCallback();var filesMathingFileQuery=this._projectFilesMatchingFileQuery(project,searchConfig);var callback=this._processMatchingFilesForProject.bind(this,this._searchId,project,filesMathingFileQuery,barrierCallback);project.findFilesMatchingSearchRequest(searchConfig,filesMathingFileQuery,findMatchingFilesInProjectProgress,callback);} barrier.callWhenDone(this._processMatchingFiles.bind(this,this._searchId,searchContentProgress,this._searchFinishedCallback.bind(this,true)));},_projectFilesMatchingFileQuery:function(project,searchConfig,dirtyOnly) {var result=[];var uiSourceCodes=project.uiSourceCodes();for(var i=0;i<uiSourceCodes.length;++i){var uiSourceCode=uiSourceCodes[i];if(dirtyOnly&&!uiSourceCode.isDirty()) continue;if(this._searchConfig.filePathMatchesFileQuery(uiSourceCode.fullDisplayName())) result.push(uiSourceCode.url());} result.sort(String.naturalOrderComparator);return result;},_processMatchingFilesForProject:function(searchId,project,filesMathingFileQuery,callback,files) {if(searchId!==this._searchId){this._searchFinishedCallback(false);return;} files.sort(String.naturalOrderComparator);files=files.intersectOrdered(filesMathingFileQuery,String.naturalOrderComparator);var dirtyFiles=this._projectFilesMatchingFileQuery(project,this._searchConfig,true);files=files.mergeOrdered(dirtyFiles,String.naturalOrderComparator);var uiSourceCodes=[];for(var i=0;i<files.length;++i){var uiSourceCode=project.uiSourceCodeForURL(files[i]);if(uiSourceCode){var script=WebInspector.DefaultScriptMapping.scriptForUISourceCode(uiSourceCode);if(script&&(script.isInternalScript()||!script.isAnonymousScript())) continue;uiSourceCodes.push(uiSourceCode);}} uiSourceCodes.sort(WebInspector.SourcesSearchScope._filesComparator);this._searchResultCandidates=this._searchResultCandidates.mergeOrdered(uiSourceCodes,WebInspector.SourcesSearchScope._filesComparator);callback();},_processMatchingFiles:function(searchId,progress,callback) {if(searchId!==this._searchId){this._searchFinishedCallback(false);return;} var files=this._searchResultCandidates;if(!files.length){progress.done();callback();return;} progress.setTotalWork(files.length);var fileIndex=0;var maxFileContentRequests=20;var callbacksLeft=0;for(var i=0;i<maxFileContentRequests&&i<files.length;++i) scheduleSearchInNextFileOrFinish.call(this);function searchInNextFile(uiSourceCode) {if(uiSourceCode.isDirty()) contentLoaded.call(this,uiSourceCode,uiSourceCode.workingCopy());else uiSourceCode.checkContentUpdated(true,contentUpdated.bind(this,uiSourceCode));} function contentUpdated(uiSourceCode) {uiSourceCode.requestContent().then(contentLoaded.bind(this,uiSourceCode));} function scheduleSearchInNextFileOrFinish() {if(fileIndex>=files.length){if(!callbacksLeft){progress.done();callback();return;} return;} ++callbacksLeft;var uiSourceCode=files[fileIndex++];setTimeout(searchInNextFile.bind(this,uiSourceCode),0);} function contentLoaded(uiSourceCode,content) {function matchesComparator(a,b) {return a.lineNumber-b.lineNumber;} progress.worked(1);var matches=[];var queries=this._searchConfig.queries();if(content!==null){for(var i=0;i<queries.length;++i){var nextMatches=WebInspector.ContentProvider.performSearchInContent(content,queries[i],!this._searchConfig.ignoreCase(),this._searchConfig.isRegex());matches=matches.mergeOrdered(nextMatches,matchesComparator);}} if(matches){var searchResult=new WebInspector.FileBasedSearchResult(uiSourceCode,matches);this._searchResultCallback(searchResult);} --callbacksLeft;scheduleSearchInNextFileOrFinish.call(this);}},stopSearch:function() {++this._searchId;},createSearchResultsPane:function(searchConfig) {return new WebInspector.FileBasedSearchResultsPane(searchConfig);}};WebInspector.SourcesPanel=function(workspaceForTest) {WebInspector.Panel.call(this,"sources");this.registerRequiredCSS("sources/sourcesPanel.css");new WebInspector.DropTarget(this.element,[WebInspector.DropTarget.Types.Files],WebInspector.UIString("Drop workspace folder here"),this._handleDrop.bind(this));this._workspace=workspaceForTest||WebInspector.workspace;this._networkMapping=WebInspector.networkMapping;this._runSnippetAction=(WebInspector.actionRegistry.action("debugger.run-snippet"));this._togglePauseAction=(WebInspector.actionRegistry.action("debugger.toggle-pause"));this._stepOverAction=(WebInspector.actionRegistry.action("debugger.step-over"));this._stepIntoAction=(WebInspector.actionRegistry.action("debugger.step-into"));this._stepOutAction=(WebInspector.actionRegistry.action("debugger.step-out"));this._toggleBreakpointsActiveAction=(WebInspector.actionRegistry.action("debugger.toggle-breakpoints-active"));this._debugToolbar=this._createDebugToolbar();this._debugToolbarDrawer=this._createDebugToolbarDrawer();const initialDebugSidebarWidth=225;this._splitWidget=new WebInspector.SplitWidget(true,true,"sourcesPanelSplitViewState",initialDebugSidebarWidth);this._splitWidget.enableShowModeSaving();this._splitWidget.show(this.element);const initialNavigatorWidth=225;this.editorView=new WebInspector.SplitWidget(true,false,"sourcesPanelNavigatorSplitViewState",initialNavigatorWidth);this.editorView.enableShowModeSaving();this.editorView.element.tabIndex=0;this._splitWidget.setMainWidget(this.editorView);this._navigator=new WebInspector.SourcesNavigator(this._workspace);this._navigator.view.setMinimumSize(100,25);this.editorView.setSidebarWidget(this._navigator.view);this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected,this._sourceSelected,this);this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceRenamed,this._sourceRenamed,this);this._sourcesView=new WebInspector.SourcesView(this._workspace,this);this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected,this._editorSelected.bind(this));this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed,this._editorClosed.bind(this));this._sourcesView.registerShortcuts(this.registerShortcuts.bind(this));this.editorView.setMainWidget(this._sourcesView);this.sidebarPanes={};this.sidebarPanes.threads=new WebInspector.ThreadsSidebarPane();this.sidebarPanes.watchExpressions=new WebInspector.WatchExpressionsSidebarPane();this.sidebarPanes.callstack=new WebInspector.CallStackSidebarPane();this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected,this._callFrameSelectedInSidebar.bind(this));this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));this.sidebarPanes.scopechain=new WebInspector.ScopeChainSidebarPane();this.sidebarPanes.jsBreakpoints=new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager,this.showUISourceCode.bind(this));this.sidebarPanes.domBreakpoints=WebInspector.domBreakpointsSidebarPane.createProxy(this);this.sidebarPanes.xhrBreakpoints=new WebInspector.XHRBreakpointsSidebarPane();this.sidebarPanes.eventListenerBreakpoints=new WebInspector.EventListenerBreakpointsSidebarPane();this.sidebarPanes.objectEventListeners=new WebInspector.ObjectEventListenersSidebarPane();this._lastSelectedTabSetting=WebInspector.settings.createLocalSetting("lastSelectedSourcesSidebarPaneTab",this.sidebarPanes.scopechain.title());this._installDebuggerSidebarController();WebInspector.moduleSetting("sidebarPosition").addChangeListener(this._updateSidebarPosition.bind(this));this._updateSidebarPosition();this._updateDebuggerButtons();this._pauseOnExceptionEnabledChanged();WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this._pauseOnExceptionEnabledChanged,this);this._liveLocationPool=new WebInspector.LiveLocationPool();this._setTarget(WebInspector.context.flavor(WebInspector.Target));WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged,this._breakpointsActiveStateChanged,this);WebInspector.context.addFlavorChangeListener(WebInspector.Target,this._onCurrentTargetChanged,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerWasEnabled,this._debuggerWasEnabled,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerPaused,this._debuggerPaused,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.DebuggerResumed,this._debuggerResumed,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.CallFrameSelected,this._callFrameSelected,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame,this._consoleCommandEvaluatedInSelectedCallFrame,this);WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel,WebInspector.DebuggerModel.Events.GlobalObjectCleared,this._debuggerReset,this);new WebInspector.WorkspaceMappingTip(this,this._workspace);WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.SidebarPaneAdded,this._extensionSidebarPaneAdded,this);WebInspector.DataSaverInfobar.maybeShowInPanel(this);} WebInspector.SourcesPanel._lastModificationTimeout=200;WebInspector.SourcesPanel.minToolbarWidth=215;WebInspector.SourcesPanel.prototype={_setTarget:function(target) {if(!target) return;var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel) return;if(debuggerModel.isPaused()){this._showDebuggerPausedDetails((debuggerModel.debuggerPausedDetails()));var callFrame=debuggerModel.selectedCallFrame();if(callFrame) this._selectCallFrame(callFrame);}else{this._paused=false;this._clearInterface();this._toggleDebuggerSidebarButton.disabled=false;}},_onCurrentTargetChanged:function(event) {var target=(event.data);this._setTarget(target);},defaultFocusedElement:function() {return this._sourcesView.defaultFocusedElement();},paused:function() {return this._paused;},wasShown:function() {WebInspector.context.setFlavor(WebInspector.SourcesPanel,this);WebInspector.Panel.prototype.wasShown.call(this);var wrapper=WebInspector.SourcesPanel.WrapperView._instance;if(wrapper&&wrapper.isShowing()){WebInspector.inspectorView.setDrawerMinimized(true);WebInspector.SourcesPanel.updateResizer(this);} this.editorView.setMainWidget(this._sourcesView);},willHide:function() {WebInspector.Panel.prototype.willHide.call(this);WebInspector.context.setFlavor(WebInspector.SourcesPanel,null);if(WebInspector.SourcesPanel.WrapperView.isShowing()){WebInspector.SourcesPanel.WrapperView._instance._showViewInWrapper();WebInspector.inspectorView.setDrawerMinimized(false);WebInspector.SourcesPanel.updateResizer(this);}},_ensureSourcesViewVisible:function() {if(WebInspector.SourcesPanel.WrapperView.isShowing()) return true;return this===WebInspector.inspectorView.setCurrentPanel(this);},onResize:function() {if(WebInspector.moduleSetting("sidebarPosition").get()==="auto") this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this));},searchableView:function() {return this._sourcesView.searchableView();},_consoleCommandEvaluatedInSelectedCallFrame:function(event) {var debuggerModel=(event.target);var target=debuggerModel.target();if(WebInspector.context.flavor(WebInspector.Target)!==target) return;this.sidebarPanes.scopechain.update(debuggerModel.selectedCallFrame());},_debuggerPaused:function(event) {var details=(event.data);if(!this._paused) WebInspector.inspectorView.setCurrentPanel(this);if(WebInspector.context.flavor(WebInspector.Target)===details.target()) this._showDebuggerPausedDetails(details);else if(!this._paused) WebInspector.context.setFlavor(WebInspector.Target,details.target());},_showDebuggerPausedDetails:function(details) {this._paused=true;this._updateDebuggerButtons();this.sidebarPanes.callstack.update(details);function didCreateBreakpointHitStatusMessage(element) {this.sidebarPanes.callstack.setStatus(element);} function didGetUILocation(liveLocation) {var uiLocation=liveLocation.uiLocation();if(!uiLocation) return;var breakpoint=WebInspector.breakpointManager.findBreakpointOnLine(uiLocation.uiSourceCode,uiLocation.lineNumber);if(!breakpoint) return;this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));} if(details.reason===WebInspector.DebuggerModel.BreakReason.DOM){WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details,didCreateBreakpointHitStatusMessage.bind(this));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.EventListener){var eventName=details.auxData["eventName"];var targetName=details.auxData["targetName"];this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(eventName,targetName);var eventNameForUI=WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName,details.auxData);this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.",eventNameForUI));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.XHR){this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.Exception){var description=details.auxData["description"]||"";this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.",description.split("\n",1)[0]));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.PromiseRejection){var description=details.auxData["description"]||"";this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on promise rejection: '%s'.",description.split("\n",1)[0]));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.Assert){this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.CSPViolation){this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".",details.auxData["directiveText"]));}else if(details.reason===WebInspector.DebuggerModel.BreakReason.DebugCommand){this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function."));}else{if(details.callFrames.length) WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(details.callFrames[0].location(),didGetUILocation.bind(this),this._liveLocationPool);else console.warn("ScriptsPanel paused, but callFrames.length is zero.");} this._splitWidget.showBoth(true);this._toggleDebuggerSidebarButton.disabled=true;window.focus();InspectorFrontendHost.bringToFront();},_debuggerResumed:function(event) {var debuggerModel=(event.target);var target=debuggerModel.target();if(WebInspector.context.flavor(WebInspector.Target)!==target) return;this._paused=false;this._clearInterface();this._toggleDebuggerSidebarButton.disabled=false;this._switchToPausedTargetTimeout=setTimeout(this._switchToPausedTarget.bind(this,debuggerModel),500);},_debuggerWasEnabled:function(event) {var target=(event.target.target());if(WebInspector.context.flavor(WebInspector.Target)!==target) return;this._updateDebuggerButtons();},_debuggerReset:function(event) {this._debuggerResumed(event);},get visibleView() {return this._sourcesView.visibleView();},showUISourceCode:function(uiSourceCode,lineNumber,columnNumber,omitFocus) {if(omitFocus){var wrapperShowing=WebInspector.SourcesPanel.WrapperView._instance&&WebInspector.SourcesPanel.WrapperView._instance.isShowing();if(!this.isShowing()&&!wrapperShowing) return;}else{this._showEditor();} this._sourcesView.showSourceLocation(uiSourceCode,lineNumber,columnNumber,omitFocus);},_showEditor:function() {if(WebInspector.SourcesPanel.WrapperView._instance&&WebInspector.SourcesPanel.WrapperView._instance.isShowing()) return;WebInspector.inspectorView.setCurrentPanel(this);},showUILocation:function(uiLocation,omitFocus) {this.showUISourceCode(uiLocation.uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber,omitFocus);},_revealInNavigator:function(uiSourceCode) {this._navigator.revealUISourceCode(uiSourceCode);},setIgnoreExecutionLineEvents:function(ignoreExecutionLineEvents) {this._ignoreExecutionLineEvents=ignoreExecutionLineEvents;},updateLastModificationTime:function() {this._lastModificationTime=window.performance.now();},_executionLineChanged:function(liveLocation) {var uiLocation=liveLocation.uiLocation();if(!uiLocation) return;this._sourcesView.clearCurrentExecutionLine();this._sourcesView.setExecutionLocation(uiLocation);if(window.performance.now()-this._lastModificationTime<WebInspector.SourcesPanel._lastModificationTimeout) return;this._sourcesView.showSourceLocation(uiLocation.uiSourceCode,uiLocation.lineNumber,uiLocation.columnNumber,undefined,true);},_lastModificationTimeoutPassedForTest:function() {WebInspector.SourcesPanel._lastModificationTimeout=Number.MIN_VALUE;},_updateLastModificationTimeForTest:function() {WebInspector.SourcesPanel._lastModificationTimeout=Number.MAX_VALUE;},_callFrameSelected:function(event) {var callFrame=(event.data);if(!callFrame||callFrame.target()!==WebInspector.context.flavor(WebInspector.Target)) return;this._selectCallFrame(callFrame);},_selectCallFrame:function(callFrame) {this.sidebarPanes.scopechain.update(callFrame);this.sidebarPanes.watchExpressions.refreshExpressions();this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame.location(),this._executionLineChanged.bind(this),this._liveLocationPool);},_sourceSelected:function(event) {var uiSourceCode=(event.data.uiSourceCode);this._sourcesView.showSourceLocation(uiSourceCode,undefined,undefined,!event.data.focusSource)},_sourceRenamed:function(event) {var uiSourceCode=(event.data);this._sourcesView.sourceRenamed(uiSourceCode);},_pauseOnExceptionEnabledChanged:function() {var enabled=WebInspector.moduleSetting("pauseOnExceptionEnabled").get();this._pauseOnExceptionButton.setToggled(enabled);this._pauseOnExceptionButton.setTitle(WebInspector.UIString(enabled?"Don't pause on exceptions":"Pause on exceptions"));this._debugToolbarDrawer.classList.toggle("expanded",enabled);},_updateDebuggerButtons:function() {var currentTarget=WebInspector.context.flavor(WebInspector.Target);var currentDebuggerModel=WebInspector.DebuggerModel.fromTarget(currentTarget);if(!currentDebuggerModel){this._togglePauseAction.setEnabled(false);this._stepOverAction.setEnabled(false);this._stepIntoAction.setEnabled(false);this._stepOutAction.setEnabled(false);}else if(this._paused){this._togglePauseAction.setToggled(true);this._togglePauseAction.setEnabled(true);this._stepOverAction.setEnabled(true);this._stepIntoAction.setEnabled(true);this._stepOutAction.setEnabled(true);}else{this._togglePauseAction.setToggled(false);this._togglePauseAction.setEnabled(!currentDebuggerModel.isPausing());this._stepOverAction.setEnabled(false);this._stepIntoAction.setEnabled(false);this._stepOutAction.setEnabled(false);}},_clearInterface:function() {this.sidebarPanes.callstack.update(null);this.sidebarPanes.scopechain.update(null);this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();if(this.sidebarPanes.asyncOperationBreakpoints) this.sidebarPanes.asyncOperationBreakpoints.clearBreakpointHighlight();this._sourcesView.clearCurrentExecutionLine();this._updateDebuggerButtons();if(this._switchToPausedTargetTimeout) clearTimeout(this._switchToPausedTargetTimeout);this._liveLocationPool.disposeAll();},_switchToPausedTarget:function(debuggerModel) {delete this._switchToPausedTargetTimeout;if(this._paused) return;var target=WebInspector.context.flavor(WebInspector.Target);if(debuggerModel.isPaused()) return;var debuggerModels=WebInspector.DebuggerModel.instances();for(var i=0;i<debuggerModels.length;++i){if(debuggerModels[i].isPaused()){WebInspector.context.setFlavor(WebInspector.Target,debuggerModels[i].target());break;}}},_togglePauseOnExceptions:function() {WebInspector.moduleSetting("pauseOnExceptionEnabled").set(!this._pauseOnExceptionButton.toggled());},_runSnippet:function() {var uiSourceCode=this._sourcesView.currentUISourceCode();if(uiSourceCode.project().type()!==WebInspector.projectTypes.Snippets) return false;var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!currentExecutionContext) return false;WebInspector.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext,uiSourceCode);return true;},_editorSelected:function(event) {var uiSourceCode=(event.data);this._editorChanged(uiSourceCode);},_editorClosed:function(event) {var wasSelected=(event.data.wasSelected);if(wasSelected) this._editorChanged(null);},_editorChanged:function(uiSourceCode) {var isSnippet=uiSourceCode&&uiSourceCode.project().type()===WebInspector.projectTypes.Snippets;this._runSnippetButton.setVisible(isSnippet);},_togglePause:function() {var target=WebInspector.context.flavor(WebInspector.Target);if(!target) return true;var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(!debuggerModel) return true;if(this._paused){this._paused=false;debuggerModel.resume();}else{debuggerModel.pause();} this._clearInterface();return true;},_prepareToResume:function() {if(!this._paused) return null;this._paused=false;this._clearInterface();var target=WebInspector.context.flavor(WebInspector.Target);return target?WebInspector.DebuggerModel.fromTarget(target):null;},_longResume:function() {var debuggerModel=this._prepareToResume();if(!debuggerModel) return true;debuggerModel.skipAllPausesUntilReloadOrTimeout(500);debuggerModel.resume();return true;},_stepOver:function() {var debuggerModel=this._prepareToResume();if(!debuggerModel) return true;debuggerModel.stepOver();return true;},_stepInto:function() {var debuggerModel=this._prepareToResume();if(!debuggerModel) return true;debuggerModel.stepInto();return true;},_stepOut:function() {var debuggerModel=this._prepareToResume();if(!debuggerModel) return true;debuggerModel.stepOut();return true;},_callFrameSelectedInSidebar:function(event) {var callFrame=(event.data);callFrame.debuggerModel.setSelectedCallFrame(callFrame);},_continueToLocation:function(uiLocation) {var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!executionContext) return;var rawLocation=WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocation(executionContext.target(),uiLocation.uiSourceCode,uiLocation.lineNumber,0);if(!rawLocation) return;if(!this._prepareToResume()) return;rawLocation.continueToLocation();},_toggleBreakpointsActive:function() {WebInspector.breakpointManager.setBreakpointsActive(!WebInspector.breakpointManager.breakpointsActive());},_breakpointsActiveStateChanged:function(event) {var active=event.data;this._toggleBreakpointsActiveAction.setToggled(!active);this.sidebarPanes.jsBreakpoints.listElement.classList.toggle("breakpoints-list-deactivated",!active);this._sourcesView.toggleBreakpointsActiveState(active);},_createDebugToolbar:function() {var debugToolbar=new WebInspector.Toolbar("scripts-debug-toolbar");this._runSnippetButton=WebInspector.Toolbar.createActionButton(this._runSnippetAction);debugToolbar.appendToolbarItem(this._runSnippetButton);this._runSnippetButton.setVisible(false);var longResumeButton=new WebInspector.ToolbarButton(WebInspector.UIString("Resume with all pauses blocked for 500 ms"),"play-toolbar-item");longResumeButton.addEventListener("click",this._longResume.bind(this),this);debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._togglePauseAction,[longResumeButton],[]));debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepOverAction));debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepIntoAction));debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._stepOutAction));debugToolbar.appendSeparator();debugToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleBreakpointsActiveAction));this._pauseOnExceptionButton=new WebInspector.ToolbarToggle("","pause-on-exceptions-toolbar-item");this._pauseOnExceptionButton.addEventListener("click",this._togglePauseOnExceptions,this);debugToolbar.appendToolbarItem(this._pauseOnExceptionButton);debugToolbar.appendSeparator();debugToolbar.appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Async"),WebInspector.UIString("Capture async stack traces"),WebInspector.moduleSetting("enableAsyncStackTraces")));return debugToolbar;},_createDebugToolbarDrawer:function() {var debugToolbarDrawer=createElementWithClass("div","scripts-debug-toolbar-drawer");var label=WebInspector.UIString("Pause On Caught Exceptions");var setting=WebInspector.moduleSetting("pauseOnCaughtException");debugToolbarDrawer.appendChild(WebInspector.SettingsUI.createSettingCheckbox(label,setting,true));return debugToolbarDrawer;},addToWatch:function(expression) {this.sidebarPanes.watchExpressions.addExpression(expression);},_installDebuggerSidebarController:function() {this.editorView.displayShowHideSidebarButton("navigator");this._toggleDebuggerSidebarButton=this._splitWidget.displayShowHideSidebarButton("debugger","scripts-debugger-show-hide-button");},_showLocalHistory:function(uiSourceCode) {WebInspector.RevisionHistoryView.showHistory(uiSourceCode);},appendApplicableItems:function(event,contextMenu,target) {this._appendUISourceCodeItems(event,contextMenu,target);this.appendUILocationItems(contextMenu,target);this._appendRemoteObjectItems(contextMenu,target);this._appendNetworkRequestItems(contextMenu,target);},mapFileSystemToNetwork:function(uiSourceCode) {WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(),[WebInspector.projectTypes.Network,WebInspector.projectTypes.ContentScripts],mapFileSystemToNetwork.bind(this));function mapFileSystemToNetwork(networkUISourceCode) {if(!networkUISourceCode) return;this._networkMapping.addMapping(networkUISourceCode,uiSourceCode);}},mapNetworkToFileSystem:function(networkUISourceCode) {WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(),[WebInspector.projectTypes.FileSystem],mapNetworkToFileSystem.bind(this));function mapNetworkToFileSystem(uiSourceCode) {if(!uiSourceCode) return;this._networkMapping.addMapping(networkUISourceCode,uiSourceCode);}},_removeNetworkMapping:function(uiSourceCode) {this._networkMapping.removeMapping(uiSourceCode);},_appendUISourceCodeMappingItems:function(contextMenu,uiSourceCode) {WebInspector.NavigatorView.appendAddFolderItem(contextMenu);if(uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem){var hasMappings=!!this._networkMapping.networkURL(uiSourceCode);if(!hasMappings) contextMenu.appendItem(WebInspector.UIString.capitalize("Map to ^network ^resource\u2026"),this.mapFileSystemToNetwork.bind(this,uiSourceCode));else contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^network ^mapping"),this._removeNetworkMapping.bind(this,uiSourceCode));} function filterProject(project) {return project.type()===WebInspector.projectTypes.FileSystem;} if(uiSourceCode.project().type()===WebInspector.projectTypes.Network||uiSourceCode.project().type()===WebInspector.projectTypes.ContentScripts){if(!this._workspace.projects().filter(filterProject).length) return;var networkURL=this._networkMapping.networkURL(uiSourceCode);if(this._networkMapping.uiSourceCodeForURLForAnyTarget(networkURL)===uiSourceCode) contextMenu.appendItem(WebInspector.UIString.capitalize("Map to ^file ^system ^resource\u2026"),this.mapNetworkToFileSystem.bind(this,uiSourceCode));}},_appendUISourceCodeItems:function(event,contextMenu,target) {if(!(target instanceof WebInspector.UISourceCode)) return;var uiSourceCode=(target);var projectType=uiSourceCode.project().type();if(projectType!==WebInspector.projectTypes.Debugger&&!event.target.isSelfOrDescendant(this._navigator.view.element)){contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in ^navigator"),this._handleContextMenuReveal.bind(this,uiSourceCode));contextMenu.appendSeparator();} this._appendUISourceCodeMappingItems(contextMenu,uiSourceCode);if(projectType!==WebInspector.projectTypes.FileSystem) contextMenu.appendItem(WebInspector.UIString.capitalize("Local ^modifications\u2026"),this._showLocalHistory.bind(this,uiSourceCode));},appendUILocationItems:function(contextMenu,object) {if(!(object instanceof WebInspector.UILocation)) return;var uiLocation=(object);var uiSourceCode=uiLocation.uiSourceCode;var projectType=uiSourceCode.project().type();var contentType=uiSourceCode.contentType();if(contentType.hasScripts()){var target=WebInspector.context.flavor(WebInspector.Target);var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);if(debuggerModel&&debuggerModel.isPaused()) contextMenu.appendItem(WebInspector.UIString.capitalize("Continue to ^here"),this._continueToLocation.bind(this,uiLocation));} if(contentType.hasScripts()&&projectType!==WebInspector.projectTypes.Snippets) this.sidebarPanes.callstack.appendBlackboxURLContextMenuItems(contextMenu,uiSourceCode);},_handleContextMenuReveal:function(uiSourceCode) {this.editorView.showBoth();this._revealInNavigator(uiSourceCode);},_appendRemoteObjectItems:function(contextMenu,target) {if(!(target instanceof WebInspector.RemoteObject)) return;var remoteObject=(target);contextMenu.appendItem(WebInspector.UIString.capitalize("Store as ^global ^variable"),this._saveToTempVariable.bind(this,remoteObject));if(remoteObject.type==="function") contextMenu.appendItem(WebInspector.UIString.capitalize("Show ^function ^definition"),this._showFunctionDefinition.bind(this,remoteObject));if(remoteObject.subtype==="generator") contextMenu.appendItem(WebInspector.UIString.capitalize("Show ^generator ^location"),this._showGeneratorLocation.bind(this,remoteObject));},_appendNetworkRequestItems:function(contextMenu,target) {if(!(target instanceof WebInspector.NetworkRequest)) return;var request=(target);var uiSourceCode=this._networkMapping.uiSourceCodeForURLForAnyTarget(request.url);if(!uiSourceCode) return;var openText=WebInspector.UIString.capitalize("Open in Sources ^panel");contextMenu.appendItem(openText,this.showUILocation.bind(this,uiSourceCode.uiLocation(0,0)));},_saveToTempVariable:function(remoteObject) {var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!currentExecutionContext) return;currentExecutionContext.globalObject("",false,false,didGetGlobalObject);function didGetGlobalObject(global,wasThrown) {function remoteFunction(value) {var prefix="temp";var index=1;while((prefix+index)in this) ++index;var name=prefix+index;this[name]=value;return name;} if(wasThrown||!global) failedToSave(global);else global.callFunction(remoteFunction,[WebInspector.RemoteObject.toCallArgument(remoteObject)],didSave.bind(null,global));} function didSave(global,result,wasThrown) {global.release();if(wasThrown||!result||result.type!=="string") failedToSave(result);else WebInspector.ConsoleModel.evaluateCommandInConsole((currentExecutionContext),result.value);} function failedToSave(result) {var message=WebInspector.UIString("Failed to save to temp variable.");if(result){message+=" "+result.description;result.release();} WebInspector.console.error(message);}},_showFunctionDefinition:function(remoteObject) {remoteObject.debuggerModel().functionDetails(remoteObject,this._didGetFunctionOrGeneratorObjectDetails.bind(this));},_showGeneratorLocation:function(remoteObject) {remoteObject.debuggerModel().generatorObjectDetails(remoteObject,this._didGetFunctionOrGeneratorObjectDetails.bind(this));},_didGetFunctionOrGeneratorObjectDetails:function(response) {if(!response||!response.location) return;var location=response.location;if(!location) return;var uiLocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location);if(uiLocation) this.showUILocation(uiLocation);},showGoToSourceDialog:function() {this._sourcesView.showOpenResourceDialog();},_updateSidebarPosition:function() {var vertically;var position=WebInspector.moduleSetting("sidebarPosition").get();if(position==="right") vertically=false;else if(position==="bottom") vertically=true;else vertically=WebInspector.inspectorView.element.offsetWidth<680;if(this.sidebarPaneView&&vertically===!this._splitWidget.isVertical()) return;if(this.sidebarPaneView&&this.sidebarPaneView.shouldHideOnDetach()) return;if(this.sidebarPaneView) this.sidebarPaneView.detach();this._splitWidget.setVertical(!vertically);this._splitWidget.element.classList.toggle("sources-split-view-vertical",vertically);WebInspector.SourcesPanel.updateResizer(this);var vbox=new WebInspector.VBox();vbox.element.appendChild(this._debugToolbarDrawer);vbox.setMinimumAndPreferredSizes(25,25,WebInspector.SourcesPanel.minToolbarWidth,100);var sidebarPaneStack=new WebInspector.SidebarPaneStack();sidebarPaneStack.element.classList.add("flex-auto");sidebarPaneStack.show(vbox.element);vbox.element.appendChild(this._debugToolbar.element);if(!vertically){for(var pane in this.sidebarPanes) sidebarPaneStack.addPane(this.sidebarPanes[pane]);this._extensionSidebarPanesContainer=sidebarPaneStack;this.sidebarPaneView=vbox;this.sidebarPanes.scopechain.expand();this.sidebarPanes.watchExpressions.expandIfNecessary();}else{var splitWidget=new WebInspector.SplitWidget(true,true,"sourcesPanelDebuggerSidebarSplitViewState",0.5);splitWidget.setMainWidget(vbox);sidebarPaneStack.addPane(this.sidebarPanes.threads);sidebarPaneStack.addPane(this.sidebarPanes.callstack);sidebarPaneStack.addPane(this.sidebarPanes.jsBreakpoints);sidebarPaneStack.addPane(this.sidebarPanes.domBreakpoints);sidebarPaneStack.addPane(this.sidebarPanes.xhrBreakpoints);sidebarPaneStack.addPane(this.sidebarPanes.eventListenerBreakpoints);sidebarPaneStack.addPane(this.sidebarPanes.objectEventListeners);var tabbedPane=new WebInspector.SidebarTabbedPane();splitWidget.setSidebarWidget(tabbedPane);tabbedPane.addPane(this.sidebarPanes.scopechain);tabbedPane.addPane(this.sidebarPanes.watchExpressions);if(this.sidebarPanes.serviceWorkers) tabbedPane.addPane(this.sidebarPanes.serviceWorkers);tabbedPane.selectTab(this._lastSelectedTabSetting.get());tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);this._extensionSidebarPanesContainer=tabbedPane;this.sidebarPaneView=splitWidget;} var extensionSidebarPanes=WebInspector.extensionServer.sidebarPanes();for(var i=0;i<extensionSidebarPanes.length;++i) this._addExtensionSidebarPane(extensionSidebarPanes[i]);this._splitWidget.setSidebarWidget(this.sidebarPaneView);this.sidebarPanes.threads.expand();this.sidebarPanes.jsBreakpoints.expand();this.sidebarPanes.callstack.expand();},_tabSelected:function(event) {this._lastSelectedTabSetting.set(event.data.tabId);},_extensionSidebarPaneAdded:function(event) {var pane=(event.data);this._addExtensionSidebarPane(pane);},_addExtensionSidebarPane:function(pane) {if(pane.panelName()===this.name) this._extensionSidebarPanesContainer.addPane(pane);},sourcesView:function() {return this._sourcesView;},_handleDrop:function(dataTransfer) {var items=dataTransfer.items;if(!items.length) return;var entry=items[0].webkitGetAsEntry();if(!entry.isDirectory) return;InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);},__proto__:WebInspector.Panel.prototype} WebInspector.SourcesPanel.ContextMenuProvider=function() {} WebInspector.SourcesPanel.ContextMenuProvider.prototype={appendApplicableItems:function(event,contextMenu,target) {WebInspector.SourcesPanel.instance().appendApplicableItems(event,contextMenu,target);}} WebInspector.SourcesPanel.UILocationRevealer=function() {} WebInspector.SourcesPanel.UILocationRevealer.prototype={reveal:function(uiLocation,omitFocus) {if(!(uiLocation instanceof WebInspector.UILocation)) return Promise.reject(new Error("Internal error: not a ui location"));WebInspector.SourcesPanel.instance().showUILocation(uiLocation,omitFocus);return Promise.resolve();}} WebInspector.SourcesPanel.DebuggerLocationRevealer=function() {} WebInspector.SourcesPanel.DebuggerLocationRevealer.prototype={reveal:function(rawLocation,omitFocus) {if(!(rawLocation instanceof WebInspector.DebuggerModel.Location)) return Promise.reject(new Error("Internal error: not a debugger location"));WebInspector.SourcesPanel.instance().showUILocation(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation),omitFocus);return Promise.resolve();}} WebInspector.SourcesPanel.UISourceCodeRevealer=function() {} WebInspector.SourcesPanel.UISourceCodeRevealer.prototype={reveal:function(uiSourceCode,omitFocus) {if(!(uiSourceCode instanceof WebInspector.UISourceCode)) return Promise.reject(new Error("Internal error: not a ui source code"));WebInspector.SourcesPanel.instance().showUISourceCode(uiSourceCode,undefined,undefined,omitFocus);return Promise.resolve();}} WebInspector.SourcesPanel.DebuggerPausedDetailsRevealer=function() {} WebInspector.SourcesPanel.DebuggerPausedDetailsRevealer.prototype={reveal:function(object) {WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());return Promise.resolve();}} WebInspector.SourcesPanel.RevealingActionDelegate=function(){} WebInspector.SourcesPanel.RevealingActionDelegate.prototype={handleAction:function(context,actionId) {var panel=WebInspector.SourcesPanel.instance();if(!panel._ensureSourcesViewVisible()) return false;switch(actionId){case"debugger.toggle-pause":panel._togglePause();return true;case"sources.go-to-source":panel.showGoToSourceDialog();return true;} return false;}} WebInspector.SourcesPanel.DebuggingActionDelegate=function() {} WebInspector.SourcesPanel.DebuggingActionDelegate.prototype={handleAction:function(context,actionId) {var panel=WebInspector.SourcesPanel.instance();switch(actionId){case"debugger.step-over":panel._stepOver();return true;case"debugger.step-into":panel._stepInto();return true;case"debugger.step-out":panel._stepOut();return true;case"debugger.run-snippet":panel._runSnippet();return true;case"debugger.toggle-breakpoints-active":panel._toggleBreakpointsActive();return true;} return false;}} WebInspector.SourcesPanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());} WebInspector.SourcesPanel.instance=function() {if(!WebInspector.SourcesPanel._instanceObject) WebInspector.SourcesPanel._instanceObject=new WebInspector.SourcesPanel();return WebInspector.SourcesPanel._instanceObject;} WebInspector.SourcesPanel.updateResizer=function(panel) {if(panel._splitWidget.isVertical()||(WebInspector.SourcesPanel.WrapperView.isShowing()&&!WebInspector.inspectorView.isDrawerMinimized())) panel._splitWidget.uninstallResizer(panel._sourcesView.toolbarContainerElement());else panel._splitWidget.installResizer(panel._sourcesView.toolbarContainerElement());} WebInspector.SourcesPanelFactory=function() {} WebInspector.SourcesPanelFactory.prototype={createPanel:function() {return WebInspector.SourcesPanel.instance();}} WebInspector.SourcesPanel.WrapperView=function() {WebInspector.VBox.call(this);this.element.classList.add("sources-view-wrapper");WebInspector.SourcesPanel.WrapperView._instance=this;this._view=WebInspector.SourcesPanel.instance()._sourcesView;} WebInspector.SourcesPanel.WrapperView.prototype={wasShown:function() {if(WebInspector.inspectorView.currentPanel()&&WebInspector.inspectorView.currentPanel().name!=="sources") this._showViewInWrapper();else WebInspector.inspectorView.setDrawerMinimized(true);WebInspector.SourcesPanel.updateResizer(WebInspector.SourcesPanel.instance());},willHide:function() {WebInspector.inspectorView.setDrawerMinimized(false);setImmediate(()=>WebInspector.SourcesPanel.updateResizer(WebInspector.SourcesPanel.instance()));},defaultFocusedElement:function() {return this._view.defaultFocusedElement();},focus:function() {this._view.focus();},_showViewInWrapper:function() {this._view.show(this.element);},__proto__:WebInspector.VBox.prototype} WebInspector.SourcesPanel.WrapperView.isShowing=function() {return!!WebInspector.SourcesPanel.WrapperView._instance&&WebInspector.SourcesPanel.WrapperView._instance.isShowing();};WebInspector.WorkspaceMappingTip=function(sourcesPanel,workspace) {this._sourcesPanel=sourcesPanel;this._workspace=workspace;this._sourcesView=this._sourcesPanel.sourcesView();this._workspaceInfobarDisabledSetting=WebInspector.settings.createSetting("workspaceInfobarDisabled",false);this._workspaceMappingInfobarDisabledSetting=WebInspector.settings.createSetting("workspaceMappingInfobarDisabled",false);if(this._workspaceInfobarDisabledSetting.get()&&this._workspaceMappingInfobarDisabledSetting.get()) return;this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected,this._editorSelected.bind(this));} WebInspector.WorkspaceMappingTip._infobarSymbol=Symbol("infobar");WebInspector.WorkspaceMappingTip.prototype={_editorSelected:function(event) {var uiSourceCode=(event.data);if(this._editorSelectedTimer) clearTimeout(this._editorSelectedTimer);this._editorSelectedTimer=setTimeout(this._updateSuggestedMappingInfobar.bind(this,uiSourceCode),3000);},_updateSuggestedMappingInfobar:function(uiSourceCode) {var uiSourceCodeFrame=this._sourcesView.viewForFile(uiSourceCode);if(!uiSourceCodeFrame.isShowing()) return;if(uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol]) return;if(!this._workspaceMappingInfobarDisabledSetting.get()&&uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem){var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);var hasMappings=!!networkURL;if(hasMappings) return;var networkProjects=this._workspace.projectsForType(WebInspector.projectTypes.Network);networkProjects=networkProjects.concat(this._workspace.projectsForType(WebInspector.projectTypes.ContentScripts));for(var i=0;i<networkProjects.length;++i){var name=uiSourceCode.name();var networkUiSourceCodes=networkProjects[i].uiSourceCodes();for(var j=0;j<networkUiSourceCodes.length;++j){if(networkUiSourceCodes[j].name()===name&&this._isLocalHost(networkUiSourceCodes[j].url())){this._showMappingInfobar(uiSourceCode,false);return;}}}} if(uiSourceCode.project().type()===WebInspector.projectTypes.Network||uiSourceCode.project().type()===WebInspector.projectTypes.ContentScripts){if(!this._isLocalHost(uiSourceCode.url())) return;var networkURL=WebInspector.networkMapping.networkURL(uiSourceCode);if(WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(networkURL)!==uiSourceCode) return;var filesystemProjects=this._workspace.projectsForType(WebInspector.projectTypes.FileSystem);for(var i=0;i<filesystemProjects.length;++i){var name=uiSourceCode.name();var fsUiSourceCodes=filesystemProjects[i].uiSourceCodes();for(var j=0;j<fsUiSourceCodes.length;++j){if(fsUiSourceCodes[j].name()===name){this._showMappingInfobar(uiSourceCode,true);return;}}} this._showWorkspaceInfobar(uiSourceCode);}},_isLocalHost:function(url) {var parsedURL=url.asParsedURL();return!!parsedURL&&parsedURL.host==="localhost";},_showWorkspaceInfobar:function(uiSourceCode) {var infobar=WebInspector.Infobar.create(WebInspector.Infobar.Type.Info,WebInspector.UIString("Serving from the file system? Add your files into the workspace."),this._workspaceInfobarDisabledSetting);if(!infobar) return;infobar.createDetailsRowMessage(WebInspector.UIString("If you add files into your DevTools workspace, your changes will be persisted to disk."));infobar.createDetailsRowMessage(WebInspector.UIString("To add a folder into the workspace, drag and drop it into the Sources panel."));this._appendInfobar(uiSourceCode,infobar);},_showMappingInfobar:function(uiSourceCode,isNetwork) {var title;if(isNetwork) title=WebInspector.UIString("Map network resource '%s' to workspace?",uiSourceCode.url());else title=WebInspector.UIString("Map workspace resource '%s' to network?",uiSourceCode.url());var infobar=WebInspector.Infobar.create(WebInspector.Infobar.Type.Info,title,this._workspaceMappingInfobarDisabledSetting);if(!infobar) return;infobar.createDetailsRowMessage(WebInspector.UIString("You can map files in your workspace to the ones loaded over the network. As a result, changes made in DevTools will be persisted to disk."));infobar.createDetailsRowMessage(WebInspector.UIString("Use context menu to establish the mapping at any time."));var anchor=createElementWithClass("a","link");anchor.textContent=WebInspector.UIString("Establish the mapping now...");anchor.addEventListener("click",this._establishTheMapping.bind(this,uiSourceCode),false);infobar.createDetailsRowMessage("").appendChild(anchor);this._appendInfobar(uiSourceCode,infobar);},_establishTheMapping:function(uiSourceCode,event) {event.consume(true);if(uiSourceCode.project().type()===WebInspector.projectTypes.FileSystem) this._sourcesPanel.mapFileSystemToNetwork(uiSourceCode);else this._sourcesPanel.mapNetworkToFileSystem(uiSourceCode);},_appendInfobar:function(uiSourceCode,infobar) {var uiSourceCodeFrame=this._sourcesView.viewForFile(uiSourceCode);var rowElement=infobar.createDetailsRowMessage(WebInspector.UIString("For more information on workspaces, refer to the "));rowElement.appendChild(WebInspector.linkifyDocumentationURLAsNode("../setup/setup-workflow",WebInspector.UIString("workspaces documentation")));rowElement.createTextChild(".");uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol]=infobar;uiSourceCodeFrame.attachInfobars([infobar]);WebInspector.runCSSAnimationOnce(infobar.element,"source-frame-infobar-animation");}};WebInspector.XHRBreakpointsSidebarPane=function() {WebInspector.BreakpointsSidebarPaneBase.call(this,WebInspector.UIString("XHR Breakpoints"));this._xhrBreakpointsSetting=WebInspector.settings.createLocalSetting("xhrBreakpoints",[]);this._breakpointElements=new Map();var addButton=new WebInspector.ToolbarButton(WebInspector.UIString("Add breakpoint"),"add-toolbar-item");addButton.addEventListener("click",this._addButtonClicked.bind(this));this.toolbar().appendToolbarItem(addButton);this.emptyElement.addEventListener("contextmenu",this._emptyElementContextMenu.bind(this),true);WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);} WebInspector.XHRBreakpointsSidebarPane.prototype={targetAdded:function(target) {this._restoreBreakpoints(target);},targetRemoved:function(target){},_emptyElementContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint"),this._addButtonClicked.bind(this));contextMenu.show();},_addButtonClicked:function(event) {if(event) event.consume();this.expand();var inputElementContainer=createElementWithClass("p","breakpoint-condition");inputElementContainer.textContent=WebInspector.UIString("Break when URL contains:");var inputElement=inputElementContainer.createChild("span","editing");inputElement.id="breakpoint-condition-input";this.addListElement(inputElementContainer,(this.listElement.firstChild));function finishEditing(accept,e,text) {this.removeListElement(inputElementContainer);if(accept){this._setBreakpoint(text,true);this._saveBreakpoints();}} var config=new WebInspector.InplaceEditor.Config(finishEditing.bind(this,true),finishEditing.bind(this,false));WebInspector.InplaceEditor.startEditing(inputElement,config);},_setBreakpoint:function(url,enabled,target) {if(enabled) this._updateBreakpointOnTarget(url,true,target);if(this._breakpointElements.has(url)) return;var element=createElement("li");element._url=url;element.addEventListener("contextmenu",this._contextMenu.bind(this,url),true);var title=url?WebInspector.UIString("URL contains \"%s\"",url):WebInspector.UIString("Any XHR");var label=createCheckboxLabel(title,enabled);element.appendChild(label);label.checkboxElement.addEventListener("click",this._checkboxClicked.bind(this,url),false);element._checkboxElement=label.checkboxElement;label.textElement.classList.add("cursor-auto");label.textElement.addEventListener("dblclick",this._labelClicked.bind(this,url),false);var currentElement=(this.listElement.firstChild);while(currentElement){if(currentElement._url&¤tElement._url<element._url) break;currentElement=(currentElement.nextSibling);} this.addListElement(element,currentElement);this._breakpointElements.set(url,element);},_removeBreakpoint:function(url,target) {var element=this._breakpointElements.get(url);if(!element) return;this.removeListElement(element);this._breakpointElements.delete(url);if(element._checkboxElement.checked) this._updateBreakpointOnTarget(url,false,target);},_updateBreakpointOnTarget:function(url,enable,target) {var targets=target?[target]:WebInspector.targetManager.targets(WebInspector.Target.Type.Page);for(var i=0;i<targets.length;++i){if(enable) targets[i].domdebuggerAgent().setXHRBreakpoint(url);else targets[i].domdebuggerAgent().removeXHRBreakpoint(url);}},_contextMenu:function(url,event) {var contextMenu=new WebInspector.ContextMenu(event);function removeBreakpoint() {this._removeBreakpoint(url);this._saveBreakpoints();} function removeAllBreakpoints() {for(var url of this._breakpointElements.keys()) this._removeBreakpoint(url);this._saveBreakpoints();} var removeAllTitle=WebInspector.UIString.capitalize("Remove ^all ^breakpoints");contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint"),this._addButtonClicked.bind(this));contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpoint"),removeBreakpoint.bind(this));contextMenu.appendItem(removeAllTitle,removeAllBreakpoints.bind(this));contextMenu.show();},_checkboxClicked:function(url,event) {this._updateBreakpointOnTarget(url,event.target.checked);this._saveBreakpoints();},_labelClicked:function(url) {var element=this._breakpointElements.get(url)||null;var inputElement=createElementWithClass("span","breakpoint-condition editing");inputElement.textContent=url;this.listElement.insertBefore(inputElement,element);element.classList.add("hidden");function finishEditing(accept,e,text) {this.removeListElement(inputElement);if(accept){this._removeBreakpoint(url);this._setBreakpoint(text,element._checkboxElement.checked);this._saveBreakpoints();}else element.classList.remove("hidden");} WebInspector.InplaceEditor.startEditing(inputElement,new WebInspector.InplaceEditor.Config(finishEditing.bind(this,true),finishEditing.bind(this,false)));},highlightBreakpoint:function(url) {var element=this._breakpointElements.get(url);if(!element) return;this.expand();element.classList.add("breakpoint-hit");this._highlightedElement=element;},clearBreakpointHighlight:function() {if(this._highlightedElement){this._highlightedElement.classList.remove("breakpoint-hit");delete this._highlightedElement;}},_saveBreakpoints:function() {var breakpoints=[];for(var url of this._breakpointElements.keys()) breakpoints.push({url:url,enabled:this._breakpointElements.get(url)._checkboxElement.checked});this._xhrBreakpointsSetting.set(breakpoints);},_restoreBreakpoints:function(target) {var breakpoints=this._xhrBreakpointsSetting.get();for(var i=0;i<breakpoints.length;++i){var breakpoint=breakpoints[i];if(breakpoint&&typeof breakpoint.url==="string") this._setBreakpoint(breakpoint.url,breakpoint.enabled,target);}},__proto__:WebInspector.BreakpointsSidebarPaneBase.prototype};WebInspector.JavaScriptCompiler=function(sourceFrame) {this._sourceFrame=sourceFrame;this._compiling=false;} WebInspector.JavaScriptCompiler.CompileDelay=1000;WebInspector.JavaScriptCompiler.prototype={scheduleCompile:function() {if(this._compiling){this._recompileScheduled=true;return;} if(this._timeout) clearTimeout(this._timeout);this._timeout=setTimeout(this._compile.bind(this),WebInspector.JavaScriptCompiler.CompileDelay);},_findTarget:function() {var targets=WebInspector.targetManager.targets();var sourceCode=this._sourceFrame.uiSourceCode();for(var i=0;i<targets.length;++i){var scriptFile=WebInspector.debuggerWorkspaceBinding.scriptFile(sourceCode,targets[i]);if(scriptFile) return targets[i];} return WebInspector.targetManager.mainTarget();},_compile:function() {var target=this._findTarget();if(!target) return;var runtimeModel=target.runtimeModel;var currentExecutionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!currentExecutionContext) return;this._compiling=true;var code=this._sourceFrame.textEditor.text();runtimeModel.compileScript(code,"",false,currentExecutionContext.id,compileCallback.bind(this,target));function compileCallback(target,scriptId,exceptionDetails) {this._compiling=false;if(this._recompileScheduled){delete this._recompileScheduled;this.scheduleCompile();return;} if(!exceptionDetails) return;this._sourceFrame.uiSourceCode().addLineMessage(WebInspector.UISourceCode.Message.Level.Error,exceptionDetails.text,exceptionDetails.line-1,exceptionDetails.column+1);this._compilationFinishedForTest();}},_compilationFinishedForTest:function(){}};WebInspector.ObjectEventListenersSidebarPane=function() {WebInspector.SidebarPane.call(this,"Event Listeners");this.element.classList.add("event-listeners-sidebar-pane");this._refreshButton=new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"),"refresh-toolbar-item");this._refreshButton.addEventListener("click",this._refreshClick.bind(this));this._refreshButton.setEnabled(false);this.toolbar().appendToolbarItem(this._refreshButton);this._eventListenersView=new WebInspector.EventListenersView(this.element);} WebInspector.ObjectEventListenersSidebarPane._objectGroupName="object-event-listeners-sidebar-pane";WebInspector.ObjectEventListenersSidebarPane.prototype={update:function() {if(this._lastRequestedContext){this._lastRequestedContext.target().runtimeAgent().releaseObjectGroup(WebInspector.ObjectEventListenersSidebarPane._objectGroupName);delete this._lastRequestedContext;} var executionContext=WebInspector.context.flavor(WebInspector.ExecutionContext);if(!executionContext){this._eventListenersView.reset();this._eventListenersView.addEmptyHolderIfNeeded();return;} this._lastRequestedContext=executionContext;Promise.all([this._windowObjectInContext(executionContext)]).then(this._eventListenersView.addObjects.bind(this._eventListenersView));},wasShown:function() {WebInspector.SidebarPane.prototype.wasShown.call(this);WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext,this.update,this);this._refreshButton.setEnabled(true);this.update();},willHide:function() {WebInspector.SidebarPane.prototype.willHide.call(this);WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionContext,this.update,this);this._refreshButton.setEnabled(false);},_windowObjectInContext:function(executionContext) {return new Promise(windowObjectInContext);function windowObjectInContext(fulfill,reject) {executionContext.evaluate("self",WebInspector.ObjectEventListenersSidebarPane._objectGroupName,false,true,false,false,false,mycallback);function mycallback(object) {if(object) fulfill(object);else reject(null);}}},_refreshClick:function(event) {event.consume();this.update();},__proto__:WebInspector.SidebarPane.prototype};Runtime.cachedResources["sources/addSourceMapURLDialog.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n padding: 10px;\n}\n\n.widget {\n align-items: center;\n}\n\nlabel {\n white-space: nowrap;\n}\n\ninput[type=text] {\n font-size: inherit;\n height: 24px;\n padding-left: 2px;\n margin: 0 5px;\n}\n\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus {\n outline: none;\n}\n\nbutton {\n background-image: linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));\n border: 1px solid hsla(0, 0%, 0%, 0.25);\n border-radius: 2px;\n box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.08), inset 0 1px 2px hsla(0, 100%, 100%, 0.75);\n color: hsl(0, 0%, 27%);\n font-size: 12px;\n margin: 0 6px 0 6px;\n text-shadow: 0 1px 0 hsl(0, 0%, 94%);\n min-height: 2em;\n padding-left: 10px;\n padding-right: 10px;\n}\n\nbutton:active {\n background-color: rgb(215, 215, 215);\n background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));\n}\n\n/*# sourceURL=sources/addSourceMapURLDialog.css */";Runtime.cachedResources["sources/uiList.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.list-item {\n padding: 2px 8px 3px 8px;\n position: relative;\n min-height: 18px;\n white-space: nowrap;\n}\n\n.list-item:nth-of-type(2n) {\n background-color: #f8f8f8;\n}\n\n.list-item.selected {\n background-color: #dadada;\n}\n\n.list-item.selected > .title {\n font-weight: bold;\n}\n\n.list-item:not(.ignore-hover):hover {\n background-color: #eee;\n}\n\n.list-item > .title {\n font-weight: normal;\n word-wrap: break-word;\n white-space: normal;\n}\n\n.list-item > .subtitle {\n margin-left: 5px;\n color: rgba(0, 0, 0, 0.7);\n text-overflow: ellipsis;\n overflow: hidden;\n float: right;\n}\n\n.list-item > .subtitle a {\n color: inherit;\n}\n\n.list-item.label {\n text-align: center;\n}\n\n.list-item.label .title,\n.list-item.label .subtitle {\n font-style: italic;\n font-weight: bold;\n color: #999;\n}\n\n.list-item.dimmed {\n opacity: 0.6;\n font-style: italic;\n}\n\n/*# sourceURL=sources/uiList.css */";Runtime.cachedResources["sources/navigatorView.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.icon {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-size: 352px 168px;\n width: 32px;\n height: 24px;\n margin: -3px -3px -3px -7px;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.icon {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.navigator-file-tree-item .icon {\n -webkit-mask-position: -224px -72px;\n background: linear-gradient(45deg, hsl(0, 0%, 50%), hsl(0, 0%, 70%));\n}\n\n:focus .navigator-file-tree-item.selected .icon {\n background: white !important;\n}\n\n:focus .navigator-folder-tree-item.selected .icon {\n background: white !important;\n}\n\n.tree-outline li {\n min-height: 20px;\n}\n\n.navigator-folder-tree-item .icon {\n -webkit-mask-position: -64px -120px;\n background-color: #555;\n}\n\n.navigator-domain-tree-item .icon {\n -webkit-mask-position: -160px -144px;\n}\n\n.navigator-frame-tree-item .icon {\n -webkit-mask-position: -256px -144px;\n}\n\n.navigator-sm-folder-tree-item .icon,\n.navigator-fs-tree-item .icon,\n.navigator-fs-folder-tree-item .icon {\n background: linear-gradient(45deg, hsl(28, 75%, 50%), hsl(28, 75%, 70%));\n}\n\n.navigator-nw-folder-tree-item .icon {\n background: linear-gradient(45deg, hsl(210, 82%, 65%), hsl(210, 82%, 80%));\n}\n\n.navigator-worker-tree-item .icon {\n -webkit-mask-position: -320px -144px;\n}\n\n.navigator-sm-script-tree-item .icon,\n.navigator-script-tree-item .icon {\n background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));\n}\n\n.navigator-sm-stylesheet-tree-item .icon,\n.navigator-stylesheet-tree-item .icon {\n background: linear-gradient(45deg, hsl(256, 50%, 50%), hsl(256, 50%, 70%));\n}\n\n.navigator-image-tree-item .icon,\n.navigator-font-tree-item .icon {\n background: linear-gradient(45deg, hsl(109, 33%, 50%), hsl(109, 33%, 70%));\n}\n\n.navigator-sm-folder-tree-item .tree-element-title,\n.navigator-sm-script-tree-item .tree-element-title,\n.navigator-sm-stylesheet-tree-item .tree-element-title {\n font-style: italic;\n}\n\n/*# sourceURL=sources/navigatorView.css */";Runtime.cachedResources["sources/revisionHistory.css"]="/*\n * Copyright (C) 2012 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.outline-disclosure.revision-history-drawer {\n -webkit-padding-start: 0;\n overflow: auto;\n}\n\n.outline-disclosure.revision-history-drawer ol {\n margin-top: 2px;\n -webkit-padding-start: 0;\n padding-left: 0 !important;\n}\n\n.outline-disclosure.revision-history-drawer > ol {\n padding-left: 0;\n}\n\n.outline-disclosure.revision-history-drawer li {\n padding-left: 6px;\n margin-top: 0;\n margin-bottom: 0;\n height: 13px;\n}\n\n.outline-disclosure.revision-history-drawer li.parent {\n margin-left: 4px;\n}\n\n.revision-history-link {\n text-decoration: underline;\n cursor: pointer;\n color: #00e;\n padding: 0 4px;\n}\n\n.revision-history-link-row {\n padding-left: 16px;\n}\n\n.outline-disclosure.revision-history-drawer .revision-history-line {\n padding-left: 0;\n -webkit-user-select: text;\n}\n\n.revision-history-drawer .webkit-line-number {\n border-right: 1px solid #BBB;\n background-color: #F0F0F0;\n}\n\n.revision-history-drawer li.revision-history-revision {\n padding-left: 16px;\n}\n\n.revision-history-line-added {\n background-color: rgb(153, 238, 153);\n}\n\n.revision-history-line-removed {\n background-color: rgb(255, 221, 221);\n}\n\n.revision-history-line-separator .webkit-line-number {\n color: transparent;\n}\n\n.revision-history-line {\n white-space: nowrap;\n}\n\n/*# sourceURL=sources/revisionHistory.css */";Runtime.cachedResources["sources/serviceWorkersSidebar.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.service-worker {\n padding: 5px 5px 5px 8px;\n border-bottom: 1px solid #aaa;\n display: flex;\n align-items: center;\n}\n\n.service-worker:last-child {\n border-bottom: none;\n}\n\n.service-worker-scope {\n color: #777;\n flex: auto;\n margin: 5px 5px 0 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/*# sourceURL=sources/serviceWorkersSidebar.css */";Runtime.cachedResources["sources/sourcesPanel.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.scripts-debug-toolbar {\n position: absolute;\n top: 0;\n width: 100%;\n background-color: #f3f3f3;\n border-bottom: 1px solid #ccc;\n overflow: hidden;\n}\n\n.scripts-debug-toolbar-drawer {\n flex: 0 0 52px;\n -webkit-transition: margin-top 0.1s ease-in-out;\n margin-top: -26px;\n padding-top: 25px;\n background-color: white;\n overflow: hidden;\n}\n\n.scripts-debug-toolbar-drawer.expanded {\n margin-top: 0;\n}\n\n.scripts-debug-toolbar-drawer > label {\n display: flex;\n padding-left: 3px;\n height: 28px;\n}\n\n.sources-editor-tabstrip-left {\n width: 22px;\n}\n\n.sources-editor-tabstrip-right {\n width: 36px;\n}\n\n.function-location-link {\n float: right;\n margin-left: 10px;\n}\n\n.function-location-step-into {\n position: relative;\n height: 14px;\n transform: rotate(-90deg);\n}\n\n.function-popover-title {\n border-bottom: 1px solid #AAA;\n margin-bottom: 3px;\n padding-bottom: 2px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.function-title-link-container {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.function-popover-title .function-name {\n font-weight: bold;\n}\n\n.panel.sources .sidebar-pane-stack {\n overflow: auto;\n}\n\n.cursor-pointer {\n cursor: pointer;\n}\n\n.cursor-auto {\n cursor: auto;\n}\n\n.callstack-info {\n text-align: center;\n font-style: italic;\n font-size: 90%;\n padding: 6px;\n color: #888;\n pointer-events: none;\n}\n\n.callstack-info.status {\n border-top: 1px solid rgb(189, 189, 189);\n background-color: rgb(255, 255, 194);\n}\n\n.-theme-with-dark-background .callstack-info.status {\n background-color: hsl(46, 98%, 22%);\n color: #ccc;\n}\n\n.watch-expression-delete-button {\n width: 10px;\n height: 10px;\n background-image: url(Images/deleteIcon.png);\n background-position: 0 0;\n background-color: transparent;\n background-repeat: no-repeat;\n border: 0 none transparent;\n position: absolute;\n right: 3px;\n display: none;\n}\n\n.watch-expression-header:hover .watch-expression-delete-button {\n display: inline;\n}\n\n.watch-expressions {\n overflow-x: hidden;\n padding: 3px 6px 6px 0px;\n}\n\n.watch-expressions .dimmed {\n opacity: 0.6;\n}\n\n.watch-expression-title {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n line-height: 12px;\n margin-left: 11px;\n}\n\n.watch-expression-object-header .watch-expression-title {\n margin-left: 1px;\n}\n\n.watch-expression {\n position: relative;\n padding: 1px 0px 1px 6px;\n flex: none;\n}\n\n.watch-expressions .name {\n color: rgb(136, 19, 145);\n flex: none;\n white-space: nowrap;\n text-overflow: ellipsis ;\n overflow: hidden;\n}\n\n.watch-expressions-separator {\n flex: none;\n}\n\n.watch-expressions .value {\n white-space: nowrap;\n display: inline;\n}\n\n.watch-expression .text-prompt {\n text-overflow: clip;\n overflow: hidden;\n white-space: nowrap;\n padding-left: 4px;\n -webkit-user-select: text;\n}\n\n.watch-expression-text-prompt-proxy {\n margin-left: 12px;\n}\n\n.watch-expression-header {\n flex: auto;\n}\n\n.watch-expression-object-header {\n margin-left: -12px;\n padding-left: 12px;\n}\n\n.watch-expression-header:hover {\n background-color: #F0F0F0;\n padding-right: 14px;\n}\n\n.sidebar-pane-stack .watch-expressions {\n margin-top: 0px;\n}\n\n.scope-chain-sidebar-pane-section-header {\n flex: auto;\n}\n\n.scope-chain-sidebar-pane-section-subtitle {\n float: right;\n margin-left: 5px;\n max-width: 55%;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.scope-chain-sidebar-pane-section-title {\n font-weight: normal;\n word-wrap: break-word;\n white-space: normal;\n}\n\n.scope-chain-sidebar-pane-section {\n padding: 2px 4px 2px 4px;\n}\n\n.scope-chain-sidebar-pane-section-subtitle {\n float: right;\n margin-left: 5px;\n max-width: 55%;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.scope-chain-sidebar-pane-section-title {\n font-weight: normal;\n word-wrap: break-word;\n white-space: normal;\n}\n\n.scope-chain-sidebar-pane-section {\n padding: 2px 4px 2px 4px;\n overflow: hidden;\n}\n\n/*# sourceURL=sources/sourcesPanel.css */";Runtime.cachedResources["sources/sourcesSearch.css"]="/*\n * Copyright 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.search-drawer-header {\n flex: none;\n display: flex;\n border-bottom: 2px solid #e8e8e8;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.search-drawer-header input.search-config-search {\n padding: 0 28px;\n margin: 1px 0px 1px 1px;\n height: 28px;\n border-radius: 2px;\n color: #303030;\n border: none;\n min-width: 95px;\n}\n\n.search-drawer-header .search-icon {\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n background-position: -234px 138px;\n left: 10px;\n top: 10px;\n width: 12px;\n height: 12px;\n position: absolute;\n}\n\n.search-config-search::-webkit-search-cancel-button {\n -webkit-appearance: none;\n}\n\n.search-drawer-header .search-cancel-button {\n position: relative;\n left: -22px;\n top: 9px;\n}\n\n.search-drawer-header .search-cancel-button::before {\n content: '';\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n left: 0;\n top: 0;\n width: 13px;\n height: 13px;\n background-position: -143px -96px;\n position: absolute;\n}\n\n:host-context(.platform-mac) .search-drawer-header input.search-config-search {\n top: 1px;\n}\n\n.search-drawer-header label.search-config-label:first-of-type {\n border-left: 1px solid #dadada;\n margin: 0px 0px 0px 1px;\n padding-left: 10px;\n}\n\n.search-drawer-header label.search-config-label {\n margin: 2px 4px;\n margin-left: 8px;\n color: #303030;\n display: flex;\n}\n\n.search-toolbar-summary {\n background-color: #eee;\n border-top: 1px solid #ccc;\n padding-left: 5px;\n flex: 0 0 19px;\n display: flex;\n padding-right: 5px;\n}\n\n.search-toolbar-summary .search-message {\n padding-top: 2px;\n padding-left: 1ex;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n\n#search-results-pane-file-based li {\n list-style: none;\n}\n\n#search-results-pane-file-based ol {\n -webkit-padding-start: 0;\n margin-top: 0;\n}\n\n#search-results-pane-file-based ol.children {\n display: none;\n}\n\n#search-results-pane-file-based ol.children.expanded {\n display: block;\n}\n\n#search-results-pane-file-based li.parent::before {\n -webkit-user-select: none;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n width: 12px;\n content: \"a\";\n color: transparent;\n margin-left: -5px;\n padding-right: 4px;\n display: inline-block;\n box-sizing: border-box;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.search-drawer-header .search-icon {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n\n.search-drawer-header .search-cancel-button::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n\n#search-results-pane-file-based li.parent::before {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n#search-results-pane-file-based li.parent::before {\n background-position: -4px -96px;\n}\n\n#search-results-pane-file-based li.parent.expanded::before {\n background-position: -20px -96px;\n}\n\n#search-results-pane-file-based .search-result {\n font-size: 11px;\n padding: 2px 0 2px 10px;\n word-wrap: normal;\n white-space: pre;\n cursor: pointer;\n}\n\n#search-results-pane-file-based .search-result:hover {\n background-color: rgba(121, 121, 121, 0.1);\n}\n\n#search-results-pane-file-based .search-result .search-result-file-name {\n font-weight: bold;\n color: #222;\n}\n\n#search-results-pane-file-based .search-result .search-result-matches-count {\n margin-left: 5px;\n color: #222;\n}\n\n#search-results-pane-file-based .show-more-matches {\n padding: 4px 0;\n color: #222;\n cursor: pointer;\n font-size: 11px;\n margin-left: 20px;\n}\n\n#search-results-pane-file-based .show-more-matches:hover {\n text-decoration: underline;\n}\n\n#search-results-pane-file-based .search-match {\n word-wrap: normal;\n white-space: pre;\n}\n\n#search-results-pane-file-based .search-match .search-match-line-number {\n color: rgb(128, 128, 128);\n text-align: right;\n vertical-align: top;\n word-break: normal;\n padding-right: 4px;\n padding-left: 6px;\n margin-right: 5px;\n border-right: 1px solid #BBB;\n}\n\n#search-results-pane-file-based .search-match:not(:hover) .search-match-line-number {\n background-color: #F0F0F0;\n}\n\n#search-results-pane-file-based .search-match:hover {\n background-color: rgba(56, 121, 217, 0.1);\n}\n\n#search-results-pane-file-based .search-match .highlighted-match {\n background-color: #F1EA00;\n}\n\n:host-context(.-theme-with-dark-background) #search-results-pane-file-based .search-match .highlighted-match {\n background-color: hsl(133, 100%, 30%) !important;\n}\n\n#search-results-pane-file-based a {\n text-decoration: none;\n display: block;\n}\n\n#search-results-pane-file-based .search-match .search-match-content {\n color: #000;\n}\n\n.search-view .search-results {\n overflow-y: auto;\n display: flex;\n flex: auto;\n}\n\n.search-results .empty-view {\n pointer-events: none;\n}\n\n.empty-view {\n font-size: 24px;\n color: rgb(75%, 75%, 75%);\n font-weight: bold;\n padding: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/*# sourceURL=sources/sourcesSearch.css */";Runtime.cachedResources["sources/sourcesView.css"]="/*\n * Copyright (C) 2013 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#sources-panel-sources-view {\n flex: auto;\n position: relative;\n}\n\n#sources-panel-sources-view .sources-toolbar {\n display: flex;\n flex: 0 0 27px;\n background-color: #f3f3f3;\n border-top: 1px solid #dadada;\n overflow: hidden;\n}\n\n.sources-toolbar .toolbar {\n cursor: default;\n}\n\n.source-frame-debugger-script {\n background-color: rgba(255, 255, 194, 0.5);\n}\n\n.-theme-with-dark-background .source-frame-debugger-script {\n background-color: #444;\n}\n\n.source-frame-unsaved-committed-changes {\n background-color: rgba(255, 225, 205, 0.40);\n}\n\n.source-frame-breakpoint-condition {\n z-index: 30;\n padding: 4px;\n background-color: rgb(203, 226, 255);\n border-radius: 7px;\n border: 2px solid rgb(169, 172, 203);\n width: 90%;\n pointer-events: auto;\n}\n\n.source-frame-breakpoint-message {\n background-color: transparent;\n font-weight: normal;\n font-size: 11px;\n text-align: left;\n text-shadow: none;\n color: rgb(85, 85, 85);\n cursor: default;\n margin: 0 0 2px 0;\n}\n\n#source-frame-breakpoint-condition {\n margin: 0;\n border: 1px inset rgb(190, 190, 190) !important;\n width: 100%;\n box-shadow: none !important;\n outline: none !important;\n -webkit-user-modify: read-write;\n}\n\n@-webkit-keyframes source-frame-value-update-highlight-animation {\n from {\n background-color: inherit;\n color: inherit;\n }\n 10% {\n background-color: rgb(158, 54, 153);\n color: white;\n }\n to {\n background-color: inherit;\n color: inherit;\n }\n}\n\n.source-frame-value-update-highlight {\n -webkit-animation: source-frame-value-update-highlight-animation 0.8s 1 cubic-bezier(0, 0, 0.2, 1);\n border-radius: 2px;\n}\n\n.diff-entry-insert .diff-marker {\n border-left: 4px solid hsla(144, 55%, 37%, 1);\n}\n\n.diff-entry-insert .CodeMirror-gutter-wrapper {\n background-color: hsla(144,55%,49%,.2);\n}\n\n.diff-entry-modify .diff-marker {\n border-left: 4px solid #9C27B0;\n}\n\n.diff-entry-modify .CodeMirror-gutter-wrapper {\n background-color: rgba(186,104,200,0.2);\n}\n\n.diff-entry-delete .diff-marker {\n width: 0;\n height: 0;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-left: 6px solid #D32F2F;\n position: relative;\n top: 7px;\n cursor: pointer;\n left: 0px;\n}\n\n.diff-entry-delete .CodeMirror-gutter-wrapper {\n border-bottom: 2px solid #D32F2F;\n}\n\n.CodeMirror-gutter-diff {\n width: 4px;\n}\n\n.highlight-line-modification {\n animation: source-line-modification-background-fadeout 0.4s 0s;\n animation-timing-function: cubic-bezier(0, 0, 0.2, 1);\n}\n\n.highlight-line-modification span {\n animation: source-line-modification-foreground-fadeout 0.4s 0s;\n animation-timing-function: cubic-bezier(0, 0, 0.2, 1);\n}\n\n@keyframes source-line-modification-background-fadeout {\n from { background-color: rgba(158, 54, 153, 0.5); }\n 50% { background-color: rgba(158, 54, 153, 0.5); }\n 90% { background-color: rgba(158, 54, 153, 0); }\n to { background-color: transparent; }\n}\n\n@keyframes source-line-modification-foreground-fadeout {\n from { color: white; }\n 50% { color: white; }\n 90% { color: intial; }\n to { color: intial; }\n}\n\n/*# sourceURL=sources/sourcesView.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var allDescriptors=[{"name":"temp_storage_shared_worker","scripts":[]}];var applicationDescriptor;var _loadedScripts={};for(var k of[]){};function loadResourcePromise(url)
{return new Promise(load);function load(fulfill,reject)
{var xhr=new XMLHttpRequest();xhr.open("GET",url,true);xhr.onreadystatechange=onreadystatechange;function onreadystatechange(e)
{if(xhr.readyState!==4)
return;if([0,200,304].indexOf(xhr.status)===-1)
reject(new Error("While loading from url "+url+" server responded with a status of "+xhr.status));else
fulfill(e.target.response);}
xhr.send(null);}}
function normalizePath(path)
{if(path.indexOf("..")===-1&&path.indexOf(".")===-1)
return path;var normalizedSegments=[];var segments=path.split("/");for(var i=0;i<segments.length;i++){var segment=segments[i];if(segment===".")
continue;else if(segment==="..")
normalizedSegments.pop();else if(segment)
normalizedSegments.push(segment);}
var normalizedPath=normalizedSegments.join("/");if(normalizedPath[normalizedPath.length-1]==="/")
return normalizedPath;if(path[0]==="/"&&normalizedPath)
normalizedPath="/"+normalizedPath;if((path[path.length-1]==="/")||(segments[segments.length-1]===".")||(segments[segments.length-1]===".."))
normalizedPath=normalizedPath+"/";return normalizedPath;}
function loadScriptsPromise(scriptNames,base)
{var promises=[];var urls=[];var sources=new Array(scriptNames.length);var scriptToEval=0;for(var i=0;i<scriptNames.length;++i){var scriptName=scriptNames[i];var sourceURL=(base||self._importScriptPathPrefix)+scriptName;var schemaIndex=sourceURL.indexOf("://")+3;var pathIndex=sourceURL.indexOf("/",schemaIndex);if(pathIndex===-1)
pathIndex=sourceURL.length;sourceURL=sourceURL.substring(0,pathIndex)+normalizePath(sourceURL.substring(pathIndex));if(_loadedScripts[sourceURL])
continue;urls.push(sourceURL);promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null,i),scriptSourceLoaded.bind(null,i,undefined)));}
return Promise.all(promises).then(undefined);function scriptSourceLoaded(scriptNumber,scriptSource)
{sources[scriptNumber]=scriptSource||"";while(typeof sources[scriptToEval]!=="undefined"){evaluateScript(urls[scriptToEval],sources[scriptToEval]);++scriptToEval;}}
function evaluateScript(sourceURL,scriptSource)
{_loadedScripts[sourceURL]=true;if(!scriptSource){console.error("Empty response arrived for script '"+sourceURL+"'");return;}
self.eval(scriptSource+"\n//# sourceURL="+sourceURL);}}
(function(){var baseUrl=self.location?self.location.origin+self.location.pathname:"";self._importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf("/")+1);})();function Runtime(descriptors)
{this._modules=[];this._modulesMap={};this._extensions=[];this._cachedTypeClasses={};this._descriptorsMap={};for(var i=0;i<descriptors.length;++i)
this._registerModule(descriptors[i]);}
Runtime._queryParamsObject={__proto__:null};Runtime.cachedResources={__proto__:null};Runtime.isReleaseMode=function()
{return!!allDescriptors.length;}
Runtime.startApplication=function(appName)
{console.timeStamp("Runtime.startApplication");var allDescriptorsByName={};for(var i=0;Runtime.isReleaseMode()&&i<allDescriptors.length;++i){var d=allDescriptors[i];allDescriptorsByName[d["name"]]=d;}
var applicationPromise;if(applicationDescriptor)
applicationPromise=Promise.resolve(applicationDescriptor);else
applicationPromise=loadResourcePromise(appName+".json").then(JSON.parse.bind(JSON));return applicationPromise.then(parseModuleDescriptors);function parseModuleDescriptors(appDescriptor)
{var configuration=appDescriptor.modules;var moduleJSONPromises=[];var coreModuleNames=[];for(var i=0;i<configuration.length;++i){var descriptor=configuration[i];var name=descriptor["name"];var moduleJSON=allDescriptorsByName[name];if(moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));else
moduleJSONPromises.push(loadResourcePromise(name+"/module.json").then(JSON.parse.bind(JSON)));if(descriptor["type"]==="autostart")
coreModuleNames.push(name);}
return Promise.all(moduleJSONPromises).then(instantiateRuntime);function instantiateRuntime(moduleDescriptors)
{for(var i=0;!Runtime.isReleaseMode()&&i<moduleDescriptors.length;++i){moduleDescriptors[i]["name"]=configuration[i]["name"];moduleDescriptors[i]["condition"]=configuration[i]["condition"];}
self.runtime=new Runtime(moduleDescriptors);if(coreModuleNames)
return(self.runtime._loadAutoStartModules(coreModuleNames));return Promise.resolve();}}}
Runtime.startWorker=function(appName)
{return Runtime.startApplication(appName).then(sendWorkerReady);function sendWorkerReady()
{self.postMessage("workerReady");}}
Runtime._sharedWorkerNewPortCallback=null;Runtime._sharedWorkerConnectedPorts=[];Runtime.startSharedWorker=function(appName)
{var startPromise=Runtime.startApplication(appName);self.onconnect=function(event)
{var newPort=(event.ports[0]);startPromise.then(sendWorkerReadyAndContinue);function sendWorkerReadyAndContinue()
{newPort.postMessage("workerReady");if(Runtime._sharedWorkerNewPortCallback)
Runtime._sharedWorkerNewPortCallback.call(null,newPort);else
Runtime._sharedWorkerConnectedPorts.push(newPort);}}}
Runtime.setSharedWorkerNewPortCallback=function(callback)
{Runtime._sharedWorkerNewPortCallback=callback;while(Runtime._sharedWorkerConnectedPorts.length){var port=Runtime._sharedWorkerConnectedPorts.shift();callback.call(null,port);}}
Runtime.queryParam=function(name)
{return Runtime._queryParamsObject[name]||null;}
Runtime.constructQueryParams=function(banned)
{var params=[];for(var key in Runtime._queryParamsObject){if(!key||banned.indexOf(key)!==-1)
continue;params.push(key+"="+Runtime._queryParamsObject[key]);}
return params.length?"?"+params.join("&"):"";}
Runtime._experimentsSetting=function()
{try{return(JSON.parse(self.localStorage&&self.localStorage["experiments"]?self.localStorage["experiments"]:"{}"));}catch(e){console.error("Failed to parse localStorage['experiments']");return{};}}
Runtime._some=function(promises)
{var all=[];var wasRejected=[];for(var i=0;i<promises.length;++i){var handlerFunction=(handler.bind(promises[i],i));all.push(promises[i].catch(handlerFunction));}
return Promise.all(all).then(filterOutFailuresResults);function filterOutFailuresResults(results)
{var filtered=[];for(var i=0;i<results.length;++i){if(!wasRejected[i])
filtered.push(results[i]);}
return filtered;}
function handler(index,e)
{wasRejected[index]=true;console.error(e.stack);}}
Runtime._console=console;Runtime._originalAssert=console.assert;Runtime._assert=function(value,message)
{if(value)
return;Runtime._originalAssert.call(Runtime._console,value,message+" "+new Error().stack);}
Runtime.prototype={useTestBase:function()
{Runtime._remoteBase="http://localhost:8000/inspector-sources/";},_registerModule:function(descriptor)
{var module=new Runtime.Module(this,descriptor);this._modules.push(module);this._modulesMap[descriptor["name"]]=module;},loadModulePromise:function(moduleName)
{return this._modulesMap[moduleName]._loadPromise();},_loadAutoStartModules:function(moduleNames)
{var promises=[];for(var i=0;i<moduleNames.length;++i){if(Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded=true;else
promises.push(this.loadModulePromise(moduleNames[i]));}
return Promise.all(promises);},_checkExtensionApplicability:function(extension,predicate)
{if(!predicate)
return false;var contextTypes=(extension.descriptor().contextTypes);if(!contextTypes)
return true;for(var i=0;i<contextTypes.length;++i){var contextType=this._resolve(contextTypes[i]);var isMatching=!!contextType&&predicate(contextType);if(isMatching)
return true;}
return false;},isExtensionApplicableToContext:function(extension,context)
{if(!context)
return true;return this._checkExtensionApplicability(extension,isInstanceOf);function isInstanceOf(targetType)
{return context instanceof targetType;}},isExtensionApplicableToContextTypes:function(extension,currentContextTypes)
{if(!extension.descriptor().contextTypes)
return true;return this._checkExtensionApplicability(extension,currentContextTypes?isContextTypeKnown:null);function isContextTypeKnown(targetType)
{return currentContextTypes.has(targetType);}},extensions:function(type,context)
{return this._extensions.filter(filter).sort(orderComparator);function filter(extension)
{if(extension._type!==type&&extension._typeClass()!==type)
return false;if(!extension.enabled())
return false;return!context||extension.isApplicable(context);}
function orderComparator(extension1,extension2)
{var order1=extension1.descriptor()["order"]||0;var order2=extension2.descriptor()["order"]||0;return order1-order2;}},extension:function(type,context)
{return this.extensions(type,context)[0]||null;},instancesPromise:function(type,context)
{var extensions=this.extensions(type,context);var promises=[];for(var i=0;i<extensions.length;++i)
promises.push(extensions[i].instancePromise());return Runtime._some(promises);},instancePromise:function(type,context)
{var extension=this.extension(type,context);if(!extension)
return Promise.reject(new Error("No such extension: "+type+" in given context."));return extension.instancePromise();},_resolve:function(typeName)
{if(!this._cachedTypeClasses[typeName]){var path=typeName.split(".");var object=self;for(var i=0;object&&(i<path.length);++i)
object=object[path[i]];if(object)
this._cachedTypeClasses[typeName]=(object);}
return this._cachedTypeClasses[typeName]||null;}}
Runtime.ModuleDescriptor=function()
{this.name;this.extensions;this.dependencies;this.scripts;this.remote;}
Runtime.ExtensionDescriptor=function()
{this.type;this.className;this.contextTypes;}
Runtime.Module=function(manager,descriptor)
{this._manager=manager;this._descriptor=descriptor;this._name=descriptor.name;this._instanceMap={};var extensions=(descriptor.extensions);for(var i=0;extensions&&i<extensions.length;++i)
this._manager._extensions.push(new Runtime.Extension(this,extensions[i]));this._loaded=false;}
Runtime.Module.prototype={name:function()
{return this._name;},enabled:function()
{return Runtime._isDescriptorEnabled(this._descriptor);},resource:function(name)
{var fullName=this._name+"/"+name;var content=Runtime.cachedResources[fullName];if(!content)
throw new Error(fullName+" not preloaded. Check module.json");return content;},_loadPromise:function()
{if(this._loaded)
return Promise.resolve();if(!this.enabled())
return Promise.reject(new Error("Module "+this._name+" is not enabled"));if(this._pendingLoadPromise)
return this._pendingLoadPromise;var dependencies=this._descriptor.dependencies;var dependencyPromises=[];for(var i=0;dependencies&&i<dependencies.length;++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());this._pendingLoadPromise=Promise.all(dependencyPromises).then(this._loadResources.bind(this)).then(this._loadScripts.bind(this)).then(markAsLoaded.bind(this));return this._pendingLoadPromise;function markAsLoaded()
{delete this._pendingLoadPromise;this._loaded=true;}},_loadResources:function()
{var resources=this._descriptor["resources"];if(!resources)
return Promise.resolve();var promises=[];for(var i=0;i<resources.length;++i){var url=this._modularizeURL(resources[i]);promises.push(loadResourcePromise(url).then(cacheResource.bind(this,url),cacheResource.bind(this,url,undefined)));}
return Promise.all(promises).then(undefined);function cacheResource(path,content)
{if(!content){console.error("Failed to load resource: "+path);return;}
Runtime.cachedResources[path]=content+Runtime.resolveSourceURL(path);}},_loadScripts:function()
{if(!this._descriptor.scripts)
return Promise.resolve();if(Runtime.isReleaseMode())
return loadScriptsPromise([this._name+"_module.js"],this._remoteBase());return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL,this));},_modularizeURL:function(resourceName)
{return normalizePath(this._name+"/"+resourceName);},_remoteBase:function()
{return this._descriptor.remote&&Runtime._remoteBase||undefined;},substituteURL:function(value)
{var base=this._remoteBase()||"";return value.replace(/@url\(([^\)]*?)\)/g,convertURL.bind(this));function convertURL(match,url)
{return base+this._modularizeURL(url);}},_instance:function(className,extension)
{if(className in this._instanceMap)
return this._instanceMap[className];var constructorFunction=self.eval(className);if(!(constructorFunction instanceof Function)){this._instanceMap[className]=null;return null;}
var instance=new constructorFunction(extension);this._instanceMap[className]=instance;return instance;}}
Runtime._isDescriptorEnabled=function(descriptor)
{var activatorExperiment=descriptor["experiment"];if(activatorExperiment&&activatorExperiment.startsWith("!")&&Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;if(activatorExperiment&&!activatorExperiment.startsWith("!")&&!Runtime.experiments.isEnabled(activatorExperiment))
return false;var condition=descriptor["condition"];if(condition&&!condition.startsWith("!")&&!Runtime.queryParam(condition))
return false;if(condition&&condition.startsWith("!")&&Runtime.queryParam(condition.substring(1)))
return false;return true;}
Runtime.Extension=function(module,descriptor)
{this._module=module;this._descriptor=descriptor;this._type=descriptor.type;this._hasTypeClass=this._type.charAt(0)==="@";this._className=descriptor.className||null;}
Runtime.Extension.prototype={descriptor:function()
{return this._descriptor;},module:function()
{return this._module;},enabled:function()
{return this._module.enabled()&&Runtime._isDescriptorEnabled(this.descriptor());},_typeClass:function()
{if(!this._hasTypeClass)
return null;return this._module._manager._resolve(this._type.substring(1));},isApplicable:function(context)
{return this._module._manager.isExtensionApplicableToContext(this,context);},instancePromise:function()
{if(!this._className)
return Promise.reject(new Error("No class name in extension"));var className=this._className;if(this._instance)
return Promise.resolve(this._instance);return this._module._loadPromise().then(constructInstance.bind(this));function constructInstance()
{var result=this._module._instance(className,this);if(!result)
return Promise.reject("Could not instantiate: "+className);return result;}},title:function(platform)
{return this._descriptor["title-"+platform]||this._descriptor["title"];}}
Runtime.ExperimentsSupport=function()
{this._supportEnabled=Runtime.queryParam("experiments")!==null;this._experiments=[];this._experimentNames={};this._enabledTransiently={};}
Runtime.ExperimentsSupport.prototype={allConfigurableExperiments:function()
{var result=[];for(var i=0;i<this._experiments.length;i++){var experiment=this._experiments[i];if(!this._enabledTransiently[experiment.name])
result.push(experiment);}
return result;},supportEnabled:function()
{return this._supportEnabled;},_setExperimentsSetting:function(value)
{if(!self.localStorage)
return;self.localStorage["experiments"]=JSON.stringify(value);},register:function(experimentName,experimentTitle,hidden)
{Runtime._assert(!this._experimentNames[experimentName],"Duplicate registration of experiment "+experimentName);this._experimentNames[experimentName]=true;this._experiments.push(new Runtime.Experiment(this,experimentName,experimentTitle,!!hidden));},isEnabled:function(experimentName)
{this._checkExperiment(experimentName);if(this._enabledTransiently[experimentName])
return true;if(!this.supportEnabled())
return false;return!!Runtime._experimentsSetting()[experimentName];},setEnabled:function(experimentName,enabled)
{this._checkExperiment(experimentName);var experimentsSetting=Runtime._experimentsSetting();experimentsSetting[experimentName]=enabled;this._setExperimentsSetting(experimentsSetting);},setDefaultExperiments:function(experimentNames)
{for(var i=0;i<experimentNames.length;++i){this._checkExperiment(experimentNames[i]);this._enabledTransiently[experimentNames[i]]=true;}},enableForTest:function(experimentName)
{this._checkExperiment(experimentName);this._enabledTransiently[experimentName]=true;},clearForTest:function()
{this._experiments=[];this._experimentNames={};this._enabledTransiently={};},cleanUpStaleExperiments:function()
{var experimentsSetting=Runtime._experimentsSetting();var cleanedUpExperimentSetting={};for(var i=0;i<this._experiments.length;++i){var experimentName=this._experiments[i].name;if(experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName]=true;}
this._setExperimentsSetting(cleanedUpExperimentSetting);},_checkExperiment:function(experimentName)
{Runtime._assert(this._experimentNames[experimentName],"Unknown experiment "+experimentName);}}
Runtime.Experiment=function(experiments,name,title,hidden)
{this.name=name;this.title=title;this.hidden=hidden;this._experiments=experiments;}
Runtime.Experiment.prototype={isEnabled:function()
{return this._experiments.isEnabled(this.name);},setEnabled:function(enabled)
{this._experiments.setEnabled(this.name,enabled);}}
{(function parseQueryParameters()
{var queryParams=location.search;if(!queryParams)
return;var params=queryParams.substring(1).split("&");for(var i=0;i<params.length;++i){var pair=params[i].split("=");var name=pair.shift();Runtime._queryParamsObject[name]=pair.join("=");}})();}
Runtime.experiments=new Runtime.ExperimentsSupport();Runtime._remoteBase=Runtime.queryParam("remoteBase");{(function validateRemoteBase()
{var remoteBaseRegexp=/^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/;if(Runtime._remoteBase&&!remoteBaseRegexp.test(Runtime._remoteBase))
Runtime._remoteBase=null;})();}
Runtime.resolveSourceURL=function(path)
{var sourceURL=self.location.href;if(self.location.search)
sourceURL=sourceURL.replace(self.location.search,"");sourceURL=sourceURL.substring(0,sourceURL.lastIndexOf("/")+1)+path;return"\n/*# sourceURL="+sourceURL+" */";}
var runtime;var ports=[];var isTempStorageCleared=false;var tempStorageError;function onNewPort(newPort)
{if(isTempStorageCleared){notifyTempStorageCleared(newPort);return;}
newPort.onmessage=handleMessage;newPort.onerror=handleError;ports.push(newPort);if(ports.length===1)
clearTempStorage();}
function clearTempStorage()
{function didFail(e)
{tempStorageError="Failed to clear temp storage: "+e.message+" "+e.name;console.error(tempStorageError);didClearTempStorage();}
function didGetFS(fs)
{fs.root.createReader().readEntries(didReadEntries,didFail);}
function didReadEntries(entries)
{var remainingEntries=entries.length;if(!remainingEntries){didClearTempStorage();return;}
function didDeleteEntry()
{if(!--remainingEntries)
didClearTempStorage();}
function failedToDeleteEntry(e)
{tempStorageError="Failed to delete entry: "+e.message+" "+e.name;console.error(tempStorageError);didDeleteEntry();}
for(var i=0;i<entries.length;i++){var entry=entries[i];if(entry.isFile)
entry.remove(didDeleteEntry,failedToDeleteEntry);else
entry.removeRecursively(didDeleteEntry,failedToDeleteEntry);}}
self.webkitRequestFileSystem(self.TEMPORARY,10,didGetFS,didFail);}
function didClearTempStorage()
{isTempStorageCleared=true;for(var i=0;i<ports.length;i++)
notifyTempStorageCleared(ports[i]);ports=null;}
function notifyTempStorageCleared(port)
{port.postMessage({type:"tempStorageCleared",error:tempStorageError});}
function handleMessage(event)
{if(event.data.type==="disconnect")
removePort(event.target);}
function handleError(event)
{console.error("Error: "+event.data);removePort(event.target);}
function removePort(port)
{if(!ports)
return;var index=ports.indexOf(port);ports.splice(index,1);}
Runtime.setSharedWorkerNewPortCallback(onNewPort);;applicationDescriptor={"has_html":false,"modules":[{"type":"autostart","name":"temp_storage_shared_worker"}]};if(!self.Runtime)
self.importScripts('Runtime.js');Runtime.startSharedWorker("temp_storage_shared_worker");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.TracingLayerPayload;WebInspector.TracingLayerTile;WebInspector.LayerTreeModel=function(target) {WebInspector.SDKModel.call(this,WebInspector.LayerTreeModel,target);target.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._onMainFrameNavigated,this);this._layerTree=null;} WebInspector.LayerTreeModel.Events={LayerTreeChanged:"LayerTreeChanged",LayerPainted:"LayerPainted",} WebInspector.LayerTreeModel.ScrollRectType={NonFastScrollable:{name:"NonFastScrollable",description:"Non fast scrollable"},TouchEventHandler:{name:"TouchEventHandler",description:"Touch event handler"},WheelEventHandler:{name:"WheelEventHandler",description:"Wheel event handler"},RepaintsOnScroll:{name:"RepaintsOnScroll",description:"Repaints on scroll"}} WebInspector.LayerTreeModel.prototype={disable:function() {if(!this._enabled) return;this._enabled=false;this._layerTree=null;this.target().layerTreeAgent().disable();},enable:function() {if(this._enabled) return;this._enabled=true;this._forceEnable();},_forceEnable:function() {this._layerTree=new WebInspector.AgentLayerTree(this.target());this._lastPaintRectByLayerId={};this.target().layerTreeAgent().enable();},setLayerTree:function(layerTree) {this.disable();this._layerTree=layerTree;this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);},layerTree:function() {return this._layerTree;},_layerTreeChanged:function(layers) {if(!this._enabled) return;var layerTree=(this._layerTree);layerTree.setLayers(layers,onLayersSet.bind(this));function onLayersSet() {for(var layerId in this._lastPaintRectByLayerId){var lastPaintRect=this._lastPaintRectByLayerId[layerId];var layer=layerTree.layerById(layerId);if(layer) layer._lastPaintRect=lastPaintRect;} this._lastPaintRectByLayerId={};this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);}},_layerPainted:function(layerId,clipRect) {if(!this._enabled) return;var layerTree=(this._layerTree);var layer=layerTree.layerById(layerId);if(!layer){this._lastPaintRectByLayerId[layerId]=clipRect;return;} layer._didPaint(clipRect);this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted,layer);},_onMainFrameNavigated:function() {if(this._enabled) this._forceEnable();},__proto__:WebInspector.SDKModel.prototype} WebInspector.LayerTreeBase=function(target) {this._target=target;this._domModel=target?WebInspector.DOMModel.fromTarget(target):null;this._layersById={};this._backendNodeIdToNode=new Map();this._reset();} WebInspector.LayerTreeBase.prototype={_reset:function() {this._root=null;this._contentRoot=null;},target:function() {return this._target;},root:function() {return this._root;},contentRoot:function() {return this._contentRoot;},forEachLayer:function(callback,root) {if(!root){root=this.root();if(!root) return false;} return callback(root)||root.children().some(this.forEachLayer.bind(this,callback));},layerById:function(id) {return this._layersById[id]||null;},_resolveBackendNodeIds:function(requestedNodeIds,callback) {if(!requestedNodeIds.size||!this._domModel){callback();return;} if(this._domModel) this._domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds,populateBackendNodeMap.bind(this));function populateBackendNodeMap(nodesMap) {if(nodesMap){for(var nodeId of nodesMap.keysArray()) this._backendNodeIdToNode.set(nodeId,nodesMap.get(nodeId)||null);} callback();}},setViewportSize:function(viewportSize) {this._viewportSize=viewportSize;},viewportSize:function() {return this._viewportSize;},_nodeForId:function(id) {return this._domModel?this._domModel.nodeForId(id):null;}} WebInspector.TracingLayerTree=function(target) {WebInspector.LayerTreeBase.call(this,target);this._tileById=new Map();} WebInspector.TracingLayerTree.prototype={setLayers:function(root,callback) {var idsToResolve=new Set();this._extractNodeIdsToResolve(idsToResolve,{},root);this._resolveBackendNodeIds(idsToResolve,onBackendNodeIdsResolved.bind(this));function onBackendNodeIdsResolved() {var oldLayersById=this._layersById;this._layersById={};this._contentRoot=null;this._root=this._innerSetLayers(oldLayersById,root);callback();}},setTiles:function(tiles) {this._tileById=new Map();for(var tile of tiles) this._tileById.set(tile.id,tile);},tileById:function(id) {return this._tileById.get(id)||null;},_innerSetLayers:function(oldLayersById,payload) {var layer=(oldLayersById[payload.layer_id]);if(layer) layer._reset(payload);else layer=new WebInspector.TracingLayer(payload);this._layersById[payload.layer_id]=layer;if(payload.owner_node) layer._setNode(this._backendNodeIdToNode.get(payload.owner_node)||null);if(!this._contentRoot&&layer.drawsContent()) this._contentRoot=layer;for(var i=0;payload.children&&i<payload.children.length;++i) layer.addChild(this._innerSetLayers(oldLayersById,payload.children[i]));return layer;},_extractNodeIdsToResolve:function(nodeIdsToResolve,seenNodeIds,payload) {var backendNodeId=payload.owner_node;if(backendNodeId&&!this._backendNodeIdToNode.has(backendNodeId)) nodeIdsToResolve.add(backendNodeId);for(var i=0;payload.children&&i<payload.children.length;++i) this._extractNodeIdsToResolve(nodeIdsToResolve,seenNodeIds,payload.children[i]);},__proto__:WebInspector.LayerTreeBase.prototype} WebInspector.AgentLayerTree=function(target) {WebInspector.LayerTreeBase.call(this,target);} WebInspector.AgentLayerTree.prototype={setLayers:function(payload,callback) {if(!payload){onBackendNodeIdsResolved.call(this);return;} var idsToResolve=new Set();for(var i=0;i<payload.length;++i){var backendNodeId=payload[i].backendNodeId;if(!backendNodeId||this._backendNodeIdToNode.has(backendNodeId)) continue;idsToResolve.add(backendNodeId);} this._resolveBackendNodeIds(idsToResolve,onBackendNodeIdsResolved.bind(this));function onBackendNodeIdsResolved() {this._innerSetLayers(payload);callback();}},_innerSetLayers:function(layers) {this._reset();if(!layers) return;var oldLayersById=this._layersById;this._layersById={};for(var i=0;i<layers.length;++i){var layerId=layers[i].layerId;var layer=oldLayersById[layerId];if(layer) layer._reset(layers[i]);else layer=new WebInspector.AgentLayer(this._target,layers[i]);this._layersById[layerId]=layer;var backendNodeId=layers[i].backendNodeId;if(backendNodeId) layer._setNode(this._backendNodeIdToNode.get(backendNodeId));if(!this._contentRoot&&layer.drawsContent()) this._contentRoot=layer;var parentId=layer.parentId();if(parentId){var parent=this._layersById[parentId];if(!parent) console.assert(parent,"missing parent "+parentId+" for layer "+layerId);parent.addChild(layer);}else{if(this._root) console.assert(false,"Multiple root layers");this._root=layer;}} if(this._root) this._root._calculateQuad(new WebKitCSSMatrix());},__proto__:WebInspector.LayerTreeBase.prototype} WebInspector.Layer=function() {} WebInspector.Layer.prototype={id:function(){},parentId:function(){},parent:function(){},isRoot:function(){},children:function(){},addChild:function(child){},node:function(){},nodeForSelfOrAncestor:function(){},offsetX:function(){},offsetY:function(){},width:function(){},height:function(){},transform:function(){},quad:function(){},anchorPoint:function(){},invisible:function(){},paintCount:function(){},lastPaintRect:function(){},scrollRects:function(){},gpuMemoryUsage:function(){},requestCompositingReasons:function(callback){},drawsContent:function(){}} WebInspector.AgentLayer=function(target,layerPayload) {this._target=target;this._reset(layerPayload);} WebInspector.AgentLayer.prototype={id:function() {return this._layerPayload.layerId;},parentId:function() {return this._layerPayload.parentLayerId;},parent:function() {return this._parent;},isRoot:function() {return!this.parentId();},children:function() {return this._children;},addChild:function(child) {if(child._parent) console.assert(false,"Child already has a parent");this._children.push(child);child._parent=this;},_setNode:function(node) {this._node=node;},node:function() {return this._node;},nodeForSelfOrAncestor:function() {for(var layer=this;layer;layer=layer._parent){if(layer._node) return layer._node;} return null;},offsetX:function() {return this._layerPayload.offsetX;},offsetY:function() {return this._layerPayload.offsetY;},width:function() {return this._layerPayload.width;},height:function() {return this._layerPayload.height;},transform:function() {return this._layerPayload.transform;},quad:function() {return this._quad;},anchorPoint:function() {return[this._layerPayload.anchorX||0,this._layerPayload.anchorY||0,this._layerPayload.anchorZ||0,];},invisible:function() {return this._layerPayload.invisible;},paintCount:function() {return this._paintCount||this._layerPayload.paintCount;},lastPaintRect:function() {return this._lastPaintRect;},scrollRects:function() {return this._scrollRects;},requestCompositingReasons:function(callback) {if(!this._target){callback([]);return;} var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.reasonsForCompositingLayer(): ",undefined,[]);this._target.layerTreeAgent().compositingReasons(this.id(),wrappedCallback);},drawsContent:function() {return this._layerPayload.drawsContent;},gpuMemoryUsage:function() {var bytesPerPixel=4;return this.drawsContent()?this.width()*this.height()*bytesPerPixel:0;},requestSnapshot:function(callback) {if(!this._target){callback();return;} var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.makeSnapshot(): ",WebInspector.PaintProfilerSnapshot.bind(null,this._target));this._target.layerTreeAgent().makeSnapshot(this.id(),wrappedCallback);},_didPaint:function(rect) {this._lastPaintRect=rect;this._paintCount=this.paintCount()+1;this._image=null;},_reset:function(layerPayload) {this._node=null;this._children=[];this._parent=null;this._paintCount=0;this._layerPayload=layerPayload;this._image=null;this._scrollRects=this._layerPayload.scrollRects||[];},_matrixFromArray:function(a) {function toFixed9(x){return x.toFixed(9);} return new WebKitCSSMatrix("matrix3d("+a.map(toFixed9).join(",")+")");},_calculateTransformToViewport:function(parentTransform) {var offsetMatrix=new WebKitCSSMatrix().translate(this._layerPayload.offsetX,this._layerPayload.offsetY);var matrix=offsetMatrix;if(this._layerPayload.transform){var transformMatrix=this._matrixFromArray(this._layerPayload.transform);var anchorVector=new WebInspector.Geometry.Vector(this._layerPayload.width*this.anchorPoint()[0],this._layerPayload.height*this.anchorPoint()[1],this.anchorPoint()[2]);var anchorPoint=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector,matrix);var anchorMatrix=new WebKitCSSMatrix().translate(-anchorPoint.x,-anchorPoint.y,-anchorPoint.z);matrix=anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));} matrix=parentTransform.multiply(matrix);return matrix;},_createVertexArrayForRect:function(width,height) {return[0,0,0,width,0,0,width,height,0,0,height,0];},_calculateQuad:function(parentTransform) {var matrix=this._calculateTransformToViewport(parentTransform);this._quad=[];var vertices=this._createVertexArrayForRect(this._layerPayload.width,this._layerPayload.height);for(var i=0;i<4;++i){var point=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i*3],vertices[i*3+1],vertices[i*3+2]),matrix);this._quad.push(point.x,point.y);} function calculateQuadForLayer(layer) {layer._calculateQuad(matrix);} this._children.forEach(calculateQuadForLayer);}} WebInspector.TracingLayer=function(payload) {this._reset(payload);} WebInspector.TracingLayer.prototype={_reset:function(payload) {this._node=null;this._layerId=String(payload.layer_id);this._offsetX=payload.position[0];this._offsetY=payload.position[1];this._width=payload.bounds.width;this._height=payload.bounds.height;this._children=[];this._parentLayerId=null;this._parent=null;this._quad=payload.layer_quad||[];this._createScrollRects(payload);this._compositingReasons=payload.compositing_reasons||[];this._drawsContent=!!payload.draws_content;this._gpuMemoryUsage=payload.gpu_memory_usage;},id:function() {return this._layerId;},parentId:function() {return this._parentLayerId;},parent:function() {return this._parent;},isRoot:function() {return!this.parentId();},children:function() {return this._children;},addChild:function(child) {if(child._parent) console.assert(false,"Child already has a parent");this._children.push(child);child._parent=this;child._parentLayerId=this._layerId;},_setNode:function(node) {this._node=node;},node:function() {return this._node;},nodeForSelfOrAncestor:function() {for(var layer=this;layer;layer=layer._parent){if(layer._node) return layer._node;} return null;},offsetX:function() {return this._offsetX;},offsetY:function() {return this._offsetY;},width:function() {return this._width;},height:function() {return this._height;},transform:function() {return null;},quad:function() {return this._quad;},anchorPoint:function() {return[0.5,0.5,0];},invisible:function() {return false;},paintCount:function() {return 0;},lastPaintRect:function() {return null;},scrollRects:function() {return this._scrollRects;},gpuMemoryUsage:function() {return this._gpuMemoryUsage;},_scrollRectsFromParams:function(params,type) {return{rect:{x:params[0],y:params[1],width:params[2],height:params[3]},type:type};},_createScrollRects:function(payload) {this._scrollRects=[];if(payload.non_fast_scrollable_region) this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region,WebInspector.LayerTreeModel.ScrollRectType.NonFastScrollable.name));if(payload.touch_event_handler_region) this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.TouchEventHandler.name));if(payload.wheel_event_handler_region) this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.WheelEventHandler.name));if(payload.scroll_event_handler_region) this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.RepaintsOnScroll.name));},requestCompositingReasons:function(callback) {callback(this._compositingReasons);},drawsContent:function() {return this._drawsContent;}} WebInspector.DeferredLayerTree=function(target) {this._target=target;} WebInspector.DeferredLayerTree.prototype={resolve:function(callback){},target:function() {return this._target;}};WebInspector.LayerTreeDispatcher=function(layerTreeModel) {this._layerTreeModel=layerTreeModel;} WebInspector.LayerTreeDispatcher.prototype={layerTreeDidChange:function(layers) {this._layerTreeModel._layerTreeChanged(layers||null);},layerPainted:function(layerId,clipRect) {this._layerTreeModel._layerPainted(layerId,clipRect);}} WebInspector.LayerTreeModel.fromTarget=function(target) {if(!target.isPage()) return null;var model=(target.model(WebInspector.LayerTreeModel));if(!model) model=new WebInspector.LayerTreeModel(target);return model;};WebInspector.CountersGraph=function(delegate,model,filters) {WebInspector.VBox.call(this);this.element.id="memory-graphs-container";this._delegate=delegate;this._model=model;this._filters=filters;this._calculator=new WebInspector.CounterGraphCalculator(this._model);this._infoWidget=new WebInspector.HBox();this._infoWidget.element.classList.add("memory-counter-selector-swatches","timeline-toolbar-resizer");this._infoWidget.show(this.element);this._graphsContainer=new WebInspector.VBox();this._graphsContainer.show(this.element);var canvasWidget=new WebInspector.VBoxWithResizeCallback(this._resize.bind(this));canvasWidget.show(this._graphsContainer.element);this._createCurrentValuesBar();this._canvasContainer=canvasWidget.element;this._canvasContainer.id="memory-graphs-canvas-container";this._canvas=this._canvasContainer.createChild("canvas");this._canvas.id="memory-counters-graph";this._canvasContainer.addEventListener("mouseover",this._onMouseMove.bind(this),true);this._canvasContainer.addEventListener("mousemove",this._onMouseMove.bind(this),true);this._canvasContainer.addEventListener("mouseleave",this._onMouseLeave.bind(this),true);this._canvasContainer.addEventListener("click",this._onClick.bind(this),true);this._timelineGrid=new WebInspector.TimelineGrid();this._canvasContainer.appendChild(this._timelineGrid.dividersElement);this._counters=[];this._counterUI=[];} WebInspector.CountersGraph.prototype={target:function() {return this._model.target();},_createCurrentValuesBar:function() {this._currentValuesBar=this._graphsContainer.element.createChild("div");this._currentValuesBar.id="counter-values-bar";},createCounter:function(uiName,uiValueTemplate,color,formatter) {var counter=new WebInspector.CountersGraph.Counter();this._counters.push(counter);this._counterUI.push(new WebInspector.CountersGraph.CounterUI(this,uiName,uiValueTemplate,color,counter,formatter));return counter;},view:function() {return this;},dispose:function() {},reset:function() {for(var i=0;i<this._counters.length;++i){this._counters[i].reset();this._counterUI[i].reset();} this.refresh();},resizerElement:function() {return this._infoWidget.element;},_resize:function() {var parentElement=this._canvas.parentElement;this._canvas.width=parentElement.clientWidth*window.devicePixelRatio;this._canvas.height=parentElement.clientHeight*window.devicePixelRatio;var timelinePaddingLeft=15;this._calculator.setDisplayWindow(this._canvas.width,timelinePaddingLeft);this.refresh();},setWindowTimes:function(startTime,endTime) {this._calculator.setWindow(startTime,endTime);this.scheduleRefresh();},scheduleRefresh:function() {WebInspector.invokeOnceAfterBatchUpdate(this,this.refresh);},draw:function() {for(var i=0;i<this._counters.length;++i){this._counters[i]._calculateVisibleIndexes(this._calculator);this._counters[i]._calculateXValues(this._canvas.width);} this._clear();for(var i=0;i<this._counterUI.length;i++) this._counterUI[i]._drawGraph(this._canvas);},_onClick:function(event) {var x=event.x-this._canvasContainer.totalOffsetLeft();var minDistance=Infinity;var bestTime;for(var i=0;i<this._counterUI.length;++i){var counterUI=this._counterUI[i];if(!counterUI.counter.times.length) continue;var index=counterUI._recordIndexAt(x);var distance=Math.abs(x*window.devicePixelRatio-counterUI.counter.x[index]);if(distance<minDistance){minDistance=distance;bestTime=counterUI.counter.times[index];}} if(bestTime!==undefined) this._delegate.selectEntryAtTime(bestTime);},_onMouseLeave:function(event) {delete this._markerXPosition;this._clearCurrentValueAndMarker();},_clearCurrentValueAndMarker:function() {for(var i=0;i<this._counterUI.length;i++) this._counterUI[i]._clearCurrentValueAndMarker();},_onMouseMove:function(event) {var x=event.x-this._canvasContainer.totalOffsetLeft();this._markerXPosition=x;this._refreshCurrentValues();},_refreshCurrentValues:function() {if(this._markerXPosition===undefined) return;for(var i=0;i<this._counterUI.length;++i) this._counterUI[i].updateCurrentValue(this._markerXPosition);},refresh:function() {this._timelineGrid.updateDividers(this._calculator);this.draw();this._refreshCurrentValues();},refreshRecords:function(){},_clear:function() {var ctx=this._canvas.getContext("2d");ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);},highlightSearchResult:function(event,regex,select) {},highlightEvent:function(event) {},setSelection:function(selection) {},__proto__:WebInspector.VBox.prototype} WebInspector.CountersGraph.Counter=function() {this.times=[];this.values=[];} WebInspector.CountersGraph.Counter.prototype={appendSample:function(time,value) {if(this.values.length&&this.values.peekLast()===value) return;this.times.push(time);this.values.push(value);},reset:function() {this.times=[];this.values=[];},setLimit:function(value) {this._limitValue=value;},_calculateBounds:function() {var maxValue;var minValue;for(var i=this._minimumIndex;i<=this._maximumIndex;i++){var value=this.values[i];if(minValue===undefined||value<minValue) minValue=value;if(maxValue===undefined||value>maxValue) maxValue=value;} minValue=minValue||0;maxValue=maxValue||1;if(this._limitValue){if(maxValue>this._limitValue*0.5) maxValue=Math.max(maxValue,this._limitValue);minValue=Math.min(minValue,this._limitValue);} return{min:minValue,max:maxValue};},_calculateVisibleIndexes:function(calculator) {var start=calculator.minimumBoundary();var end=calculator.maximumBoundary();this._minimumIndex=Number.constrain(this.times.upperBound(start)-1,0,this.times.length-1);this._maximumIndex=Number.constrain(this.times.lowerBound(end),0,this.times.length-1);this._minTime=start;this._maxTime=end;},_calculateXValues:function(width) {if(!this.values.length) return;var xFactor=width/(this._maxTime-this._minTime);this.x=new Array(this.values.length);for(var i=this._minimumIndex+1;i<=this._maximumIndex;i++) this.x[i]=xFactor*(this.times[i]-this._minTime);}} WebInspector.CountersGraph.CounterUI=function(memoryCountersPane,title,currentValueLabel,graphColor,counter,formatter) {this._memoryCountersPane=memoryCountersPane;this.counter=counter;this._formatter=formatter||Number.withThousandsSeparator;var container=memoryCountersPane._infoWidget.element.createChild("div","memory-counter-selector-info");this._setting=WebInspector.settings.createSetting("timelineCountersGraph-"+title,true);this._filter=new WebInspector.ToolbarCheckbox(title,title,this._setting);var color=WebInspector.Color.parse(graphColor).setAlpha(0.5).asString(WebInspector.Color.Format.RGBA);if(color){this._filter.element.backgroundColor=color;this._filter.element.borderColor="transparent";} this._filter.inputElement.addEventListener("click",this._toggleCounterGraph.bind(this));container.appendChild(this._filter.element);this._range=this._filter.element.createChild("span","range");this._value=memoryCountersPane._currentValuesBar.createChild("span","memory-counter-value");this._value.style.color=graphColor;this.graphColor=graphColor;this.limitColor=WebInspector.Color.parse(graphColor).setAlpha(0.3).asString(WebInspector.Color.Format.RGBA);this.graphYValues=[];this._verticalPadding=10;this._currentValueLabel=currentValueLabel;this._marker=memoryCountersPane._canvasContainer.createChild("div","memory-counter-marker");this._marker.style.backgroundColor=graphColor;this._clearCurrentValueAndMarker();} WebInspector.CountersGraph.CounterUI.prototype={reset:function() {this._range.textContent="";},setRange:function(minValue,maxValue) {var min=this._formatter(minValue);var max=this._formatter(maxValue);this._range.textContent=WebInspector.UIString("[%s\u2009\u2013\u2009%s]",min,max);},_toggleCounterGraph:function(event) {this._value.classList.toggle("hidden",!this._filter.checked());this._memoryCountersPane.refresh();},_recordIndexAt:function(x) {return this.counter.x.upperBound(x*window.devicePixelRatio,null,this.counter._minimumIndex+1,this.counter._maximumIndex+1)-1;},updateCurrentValue:function(x) {if(!this.visible()||!this.counter.values.length||!this.counter.x) return;var index=this._recordIndexAt(x);var value=Number.withThousandsSeparator(this.counter.values[index]);this._value.textContent=WebInspector.UIString(this._currentValueLabel,value);var y=this.graphYValues[index]/window.devicePixelRatio;this._marker.style.left=x+"px";this._marker.style.top=y+"px";this._marker.classList.remove("hidden");},_clearCurrentValueAndMarker:function() {this._value.textContent="";this._marker.classList.add("hidden");},_drawGraph:function(canvas) {var ctx=canvas.getContext("2d");var width=canvas.width;var height=canvas.height-2*this._verticalPadding;if(height<=0){this.graphYValues=[];return;} var originY=this._verticalPadding;var counter=this.counter;var values=counter.values;if(!values.length) return;var bounds=counter._calculateBounds();var minValue=bounds.min;var maxValue=bounds.max;this.setRange(minValue,maxValue);if(!this.visible()) return;var yValues=this.graphYValues;var maxYRange=maxValue-minValue;var yFactor=maxYRange?height/(maxYRange):1;ctx.save();ctx.lineWidth=window.devicePixelRatio;if(ctx.lineWidth%2) ctx.translate(0.5,0.5);ctx.beginPath();var value=values[counter._minimumIndex];var currentY=Math.round(originY+height-(value-minValue)*yFactor);ctx.moveTo(0,currentY);for(var i=counter._minimumIndex;i<=counter._maximumIndex;i++){var x=Math.round(counter.x[i]);ctx.lineTo(x,currentY);var currentValue=values[i];if(typeof currentValue!=="undefined") value=currentValue;currentY=Math.round(originY+height-(value-minValue)*yFactor);ctx.lineTo(x,currentY);yValues[i]=currentY;} yValues.length=i;ctx.lineTo(width,currentY);ctx.strokeStyle=this.graphColor;ctx.stroke();if(counter._limitValue){var limitLineY=Math.round(originY+height-(counter._limitValue-minValue)*yFactor);ctx.moveTo(0,limitLineY);ctx.lineTo(width,limitLineY);ctx.strokeStyle=this.limitColor;ctx.stroke();} ctx.closePath();ctx.restore();},visible:function() {return this._filter.checked();}} WebInspector.CounterGraphCalculator=function(model) {this._model=model;} WebInspector.CounterGraphCalculator._minWidth=5;WebInspector.CounterGraphCalculator.prototype={paddingLeft:function() {return this._paddingLeft;},computePosition:function(time) {return(time-this._minimumBoundary)/this.boundarySpan()*this._workingArea+this._paddingLeft;},setWindow:function(minimumBoundary,maximumBoundary) {this._minimumBoundary=minimumBoundary;this._maximumBoundary=maximumBoundary;},setDisplayWindow:function(clientWidth,paddingLeft) {this._paddingLeft=paddingLeft||0;this._workingArea=clientWidth-WebInspector.CounterGraphCalculator._minWidth-this._paddingLeft;},formatValue:function(value,precision) {return Number.preciseMillisToString(value-this.zeroTime(),precision);},maximumBoundary:function() {return this._maximumBoundary;},minimumBoundary:function() {return this._minimumBoundary;},zeroTime:function() {return this._model.minimumRecordTime();},boundarySpan:function() {return this._maximumBoundary-this._minimumBoundary;}};WebInspector.LayerDetailsView=function(layerViewHost) {WebInspector.Widget.call(this);this.element.classList.add("layer-details-view");this._layerViewHost=layerViewHost;this._layerViewHost.registerView(this);this._emptyWidget=new WebInspector.EmptyWidget(WebInspector.UIString("Select a layer to see its details"));this._buildContent();} WebInspector.LayerDetailsView.Events={PaintProfilerRequested:"PaintProfilerRequested"} WebInspector.LayerDetailsView.CompositingReasonDetail={"transform3D":WebInspector.UIString("Composition due to association with an element with a CSS 3D transform."),"video":WebInspector.UIString("Composition due to association with a <video> element."),"canvas":WebInspector.UIString("Composition due to the element being a <canvas> element."),"plugin":WebInspector.UIString("Composition due to association with a plugin."),"iFrame":WebInspector.UIString("Composition due to association with an <iframe> element."),"backfaceVisibilityHidden":WebInspector.UIString("Composition due to association with an element with a \"backface-visibility: hidden\" style."),"animation":WebInspector.UIString("Composition due to association with an animated element."),"filters":WebInspector.UIString("Composition due to association with an element with CSS filters applied."),"positionFixed":WebInspector.UIString("Composition due to association with an element with a \"position: fixed\" style."),"positionSticky":WebInspector.UIString("Composition due to association with an element with a \"position: sticky\" style."),"overflowScrollingTouch":WebInspector.UIString("Composition due to association with an element with a \"overflow-scrolling: touch\" style."),"blending":WebInspector.UIString("Composition due to association with an element that has blend mode other than \"normal\"."),"assumedOverlap":WebInspector.UIString("Composition due to association with an element that may overlap other composited elements."),"overlap":WebInspector.UIString("Composition due to association with an element overlapping other composited elements."),"negativeZIndexChildren":WebInspector.UIString("Composition due to association with an element with descendants that have a negative z-index."),"transformWithCompositedDescendants":WebInspector.UIString("Composition due to association with an element with composited descendants."),"opacityWithCompositedDescendants":WebInspector.UIString("Composition due to association with an element with opacity applied and composited descendants."),"maskWithCompositedDescendants":WebInspector.UIString("Composition due to association with a masked element and composited descendants."),"reflectionWithCompositedDescendants":WebInspector.UIString("Composition due to association with an element with a reflection and composited descendants."),"filterWithCompositedDescendants":WebInspector.UIString("Composition due to association with an element with CSS filters applied and composited descendants."),"blendingWithCompositedDescendants":WebInspector.UIString("Composition due to association with an element with CSS blending applied and composited descendants."),"clipsCompositingDescendants":WebInspector.UIString("Composition due to association with an element clipping compositing descendants."),"perspective":WebInspector.UIString("Composition due to association with an element with perspective applied."),"preserve3D":WebInspector.UIString("Composition due to association with an element with a \"transform-style: preserve-3d\" style."),"root":WebInspector.UIString("Root layer."),"layerForClip":WebInspector.UIString("Layer for clip."),"layerForScrollbar":WebInspector.UIString("Layer for scrollbar."),"layerForScrollingContainer":WebInspector.UIString("Layer for scrolling container."),"layerForForeground":WebInspector.UIString("Layer for foreground."),"layerForBackground":WebInspector.UIString("Layer for background."),"layerForMask":WebInspector.UIString("Layer for mask."),"layerForVideoOverlay":WebInspector.UIString("Layer for video overlay."),};WebInspector.LayerDetailsView.prototype={hoverObject:function(selection){},selectObject:function(selection) {this._selection=selection;if(this.isShowing()) this.update();},setLayerTree:function(layerTree){},wasShown:function() {WebInspector.Widget.prototype.wasShown.call(this);this.update();},_onScrollRectClicked:function(index,event) {if(event.which!==1) return;this._layerViewHost.selectObject(new WebInspector.LayerView.ScrollRectSelection(this._selection.layer(),index));},_onPaintProfilerButtonClicked:function() {var traceEvent=this._selection.type()===WebInspector.LayerView.Selection.Type.Tile?(this._selection).traceEvent():null;this.dispatchEventToListeners(WebInspector.LayerDetailsView.Events.PaintProfilerRequested,traceEvent);},_createScrollRectElement:function(scrollRect,index) {if(index) this._scrollRectsCell.createTextChild(", ");var element=this._scrollRectsCell.createChild("span","scroll-rect");if(this._selection.scrollRectIndex===index) element.classList.add("active");element.textContent=WebInspector.LayerTreeModel.ScrollRectType[scrollRect.type].description+" ("+scrollRect.rect.x+", "+scrollRect.rect.y+", "+scrollRect.rect.width+", "+scrollRect.rect.height+")";element.addEventListener("click",this._onScrollRectClicked.bind(this,index),false);},update:function() {var layer=this._selection&&this._selection.layer();if(!layer){this._tableElement.remove();this._paintProfilerButton.remove();this._emptyWidget.show(this.element);return;} this._emptyWidget.detach();this.element.appendChild(this._tableElement);this.element.appendChild(this._paintProfilerButton);this._sizeCell.textContent=WebInspector.UIString("%d × %d (at %d,%d)",layer.width(),layer.height(),layer.offsetX(),layer.offsetY());this._paintCountCell.parentElement.classList.toggle("hidden",!layer.paintCount());this._paintCountCell.textContent=layer.paintCount();this._memoryEstimateCell.textContent=Number.bytesToString(layer.gpuMemoryUsage());layer.requestCompositingReasons(this._updateCompositingReasons.bind(this));this._scrollRectsCell.removeChildren();layer.scrollRects().forEach(this._createScrollRectElement.bind(this));var traceEvent=this._selection.type()===WebInspector.LayerView.Selection.Type.Tile?(this._selection).traceEvent():null;this._paintProfilerButton.classList.toggle("hidden",!traceEvent);},_buildContent:function() {this._tableElement=this.element.createChild("table");this._tbodyElement=this._tableElement.createChild("tbody");this._sizeCell=this._createRow(WebInspector.UIString("Size"));this._compositingReasonsCell=this._createRow(WebInspector.UIString("Compositing Reasons"));this._memoryEstimateCell=this._createRow(WebInspector.UIString("Memory estimate"));this._paintCountCell=this._createRow(WebInspector.UIString("Paint count"));this._scrollRectsCell=this._createRow(WebInspector.UIString("Slow scroll regions"));this._paintProfilerButton=this.element.createChild("a","hidden link");this._paintProfilerButton.textContent=WebInspector.UIString("Paint Profiler");this._paintProfilerButton.addEventListener("click",this._onPaintProfilerButtonClicked.bind(this));},_createRow:function(title) {var tr=this._tbodyElement.createChild("tr");var titleCell=tr.createChild("td");titleCell.textContent=title;return tr.createChild("td");},_updateCompositingReasons:function(compositingReasons) {if(!compositingReasons||!compositingReasons.length){this._compositingReasonsCell.textContent="n/a";return;} this._compositingReasonsCell.removeChildren();var list=this._compositingReasonsCell.createChild("ul");for(var i=0;i<compositingReasons.length;++i){var text=WebInspector.LayerDetailsView.CompositingReasonDetail[compositingReasons[i]]||compositingReasons[i];if(/\s.*[^.]$/.test(text)) text+=".";list.createChild("li").textContent=text;}},__proto__:WebInspector.Widget.prototype};WebInspector.LayerTreeOutline=function(layerViewHost) {WebInspector.Object.call(this);this._layerViewHost=layerViewHost;this._layerViewHost.registerView(this);this._treeOutline=new TreeOutlineInShadow();this._treeOutline.element.classList.add("layer-tree");this._treeOutline.element.addEventListener("mousemove",this._onMouseMove.bind(this),false);this._treeOutline.element.addEventListener("mouseout",this._onMouseMove.bind(this),false);this._treeOutline.element.addEventListener("contextmenu",this._onContextMenu.bind(this),true);this._lastHoveredNode=null;this.element=this._treeOutline.element;this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update,this);} WebInspector.LayerTreeOutline.prototype={focus:function() {this._treeOutline.focus();},selectObject:function(selection) {this.hoverObject(null);var layer=selection&&selection.layer();var node=layer&&layer[WebInspector.LayerTreeElement._symbol];if(node) node.revealAndSelect(true);else if(this._treeOutline.selectedTreeElement) this._treeOutline.selectedTreeElement.deselect();},hoverObject:function(selection) {var layer=selection&&selection.layer();var node=layer&&layer[WebInspector.LayerTreeElement._symbol];if(node===this._lastHoveredNode) return;if(this._lastHoveredNode) this._lastHoveredNode.setHovered(false);if(node) node.setHovered(true);this._lastHoveredNode=node;},setLayerTree:function(layerTree) {this._layerTree=layerTree;this._update();},_update:function() {var showInternalLayers=this._layerViewHost.showInternalLayersSetting().get();var seenLayers=new Map();var root=null;if(this._layerTree){if(!showInternalLayers) root=this._layerTree.contentRoot();if(!root) root=this._layerTree.root();} function updateLayer(layer) {if(!layer.drawsContent()&&!showInternalLayers) return;if(seenLayers.get(layer)) console.assert(false,"Duplicate layer: "+layer.id());seenLayers.set(layer,true);var node=layer[WebInspector.LayerTreeElement._symbol];var parentLayer=layer.parent();while(parentLayer&&parentLayer!==root&&!parentLayer.drawsContent()&&!showInternalLayers) parentLayer=parentLayer.parent();var parent=layer===root?this._treeOutline.rootElement():parentLayer[WebInspector.LayerTreeElement._symbol];if(!parent){console.assert(false,"Parent is not in the tree");return;} if(!node){node=new WebInspector.LayerTreeElement(this,layer);parent.appendChild(node);if(!layer.drawsContent()) node.expand();}else{if(node.parent!==parent){var oldSelection=this._treeOutline.selectedTreeElement;if(node.parent) node.parent.removeChild(node);parent.appendChild(node);if(oldSelection!==this._treeOutline.selectedTreeElement) oldSelection.select();} node._update();}} if(root) this._layerTree.forEachLayer(updateLayer.bind(this),root);var rootElement=this._treeOutline.rootElement();for(var node=rootElement.firstChild();node&&!node.root;){if(seenLayers.get(node._layer)){node=node.traverseNextTreeElement(false);}else{var nextNode=node.nextSibling||node.parent;node.parent.removeChild(node);if(node===this._lastHoveredNode) this._lastHoveredNode=null;node=nextNode;}} if(!this._treeOutline.selectedTreeElement){var elementToSelect=this._layerTree.contentRoot()||this._layerTree.root();if(elementToSelect) elementToSelect[WebInspector.LayerTreeElement._symbol].revealAndSelect(true);}},_onMouseMove:function(event) {var node=this._treeOutline.treeElementFromEvent(event);if(node===this._lastHoveredNode) return;this._layerViewHost.hoverObject(this._selectionForNode(node));},_selectedNodeChanged:function(node) {this._layerViewHost.selectObject(this._selectionForNode(node));},_onContextMenu:function(event) {var selection=this._selectionForNode(this._treeOutline.treeElementFromEvent(event));var contextMenu=new WebInspector.ContextMenu(event);this._layerViewHost.showContextMenu(contextMenu,selection);},_selectionForNode:function(node) {return node&&node._layer?new WebInspector.LayerView.LayerSelection(node._layer):null;},__proto__:WebInspector.Object.prototype} WebInspector.LayerTreeElement=function(tree,layer) {TreeElement.call(this);this._treeOutline=tree;this._layer=layer;this._layer[WebInspector.LayerTreeElement._symbol]=this;this._update();} WebInspector.LayerTreeElement._symbol=Symbol("layer");WebInspector.LayerTreeElement.prototype={_update:function() {var node=this._layer.nodeForSelfOrAncestor();var title=createDocumentFragment();title.createTextChild(node?WebInspector.DOMPresentationUtils.simpleSelector(node):"#"+this._layer.id());var details=title.createChild("span","dimmed");details.textContent=WebInspector.UIString(" (%d × %d)",this._layer.width(),this._layer.height());this.title=title;},onselect:function() {this._treeOutline._selectedNodeChanged(this);return false;},setHovered:function(hovered) {this.listItemElement.classList.toggle("hovered",hovered);},__proto__:TreeElement.prototype};WebInspector.LayerView=function() {} WebInspector.LayerView.prototype={hoverObject:function(selection){},selectObject:function(selection){},setLayerTree:function(layerTree){}} WebInspector.LayerView.Selection=function(type,layer) {this._type=type;this._layer=layer;} WebInspector.LayerView.Selection.Type={Layer:"Layer",ScrollRect:"ScrollRect",Tile:"Tile",} WebInspector.LayerView.Selection.isEqual=function(a,b) {return a&&b?a._isEqual(b):a===b;} WebInspector.LayerView.Selection.prototype={type:function() {return this._type;},layer:function() {return this._layer;},_isEqual:function(other) {return false;}} WebInspector.LayerView.LayerSelection=function(layer) {console.assert(layer,"LayerSelection with empty layer");WebInspector.LayerView.Selection.call(this,WebInspector.LayerView.Selection.Type.Layer,layer);} WebInspector.LayerView.LayerSelection.prototype={_isEqual:function(other) {return other._type===WebInspector.LayerView.Selection.Type.Layer&&other.layer().id()===this.layer().id();},__proto__:WebInspector.LayerView.Selection.prototype} WebInspector.LayerView.ScrollRectSelection=function(layer,scrollRectIndex) {WebInspector.LayerView.Selection.call(this,WebInspector.LayerView.Selection.Type.ScrollRect,layer);this.scrollRectIndex=scrollRectIndex;} WebInspector.LayerView.ScrollRectSelection.prototype={_isEqual:function(other) {return other._type===WebInspector.LayerView.Selection.Type.ScrollRect&&this.layer().id()===other.layer().id()&&this.scrollRectIndex===other.scrollRectIndex;},__proto__:WebInspector.LayerView.Selection.prototype} WebInspector.LayerView.TileSelection=function(layer,traceEvent) {WebInspector.LayerView.Selection.call(this,WebInspector.LayerView.Selection.Type.Tile,layer);this._traceEvent=traceEvent;} WebInspector.LayerView.TileSelection.prototype={_isEqual:function(other) {return other._type===WebInspector.LayerView.Selection.Type.Tile&&this.layer().id()===other.layer().id()&&this.traceEvent===other.traceEvent;},traceEvent:function() {return this._traceEvent;},__proto__:WebInspector.LayerView.Selection.prototype} WebInspector.LayerViewHost=function() {this._views=[];this._selectedObject=null;this._hoveredObject=null;this._showInternalLayersSetting=WebInspector.settings.createSetting("layersShowInternalLayers",false);} WebInspector.LayerViewHost.prototype={registerView:function(layerView) {this._views.push(layerView);},setLayerTree:function(layerTree) {this._target=layerTree.target();var selectedLayer=this._selectedObject&&this._selectedObject.layer();if(selectedLayer&&(!layerTree||!layerTree.layerById(selectedLayer.id()))) this.selectObject(null);var hoveredLayer=this._hoveredObject&&this._hoveredObject.layer();if(hoveredLayer&&(!layerTree||!layerTree.layerById(hoveredLayer.id()))) this.hoverObject(null);for(var view of this._views) view.setLayerTree(layerTree);},hoverObject:function(selection) {if(WebInspector.LayerView.Selection.isEqual(this._hoveredObject,selection)) return;this._hoveredObject=selection;var layer=selection&&selection.layer();this._toggleNodeHighlight(layer?layer.nodeForSelfOrAncestor():null);for(var view of this._views) view.hoverObject(selection);},selectObject:function(selection) {if(WebInspector.LayerView.Selection.isEqual(this._selectedObject,selection)) return;this._selectedObject=selection;for(var view of this._views) view.selectObject(selection);},selection:function() {return this._selectedObject;},showContextMenu:function(contextMenu,selection) {contextMenu.appendCheckboxItem(WebInspector.UIString("Show internal layers"),this._toggleShowInternalLayers.bind(this),this._showInternalLayersSetting.get());var node=selection&&selection.layer()&&selection.layer().nodeForSelfOrAncestor();if(node) contextMenu.appendApplicableItems(node);contextMenu.show();},showInternalLayersSetting:function() {return this._showInternalLayersSetting;},_toggleShowInternalLayers:function() {this._showInternalLayersSetting.set(!this._showInternalLayersSetting.get());},_toggleNodeHighlight:function(node) {if(node){node.highlightForTwoSeconds();return;} WebInspector.DOMModel.hideDOMNodeHighlight();}};WebInspector.Layers3DView=function(layerViewHost) {WebInspector.VBox.call(this);this.element.classList.add("layers-3d-view");this._failBanner=new WebInspector.VBox();this._failBanner.element.classList.add("banner");this._failBanner.element.createTextChild(WebInspector.UIString("Layer information is not yet available."));this._layerViewHost=layerViewHost;this._layerViewHost.registerView(this);this._transformController=new WebInspector.TransformController(this.element);this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged,this._update,this);this._initToolbar();this._canvasElement=this.element.createChild("canvas");this._canvasElement.tabIndex=0;this._canvasElement.addEventListener("dblclick",this._onDoubleClick.bind(this),false);this._canvasElement.addEventListener("mousedown",this._onMouseDown.bind(this),false);this._canvasElement.addEventListener("mouseup",this._onMouseUp.bind(this),false);this._canvasElement.addEventListener("mouseleave",this._onMouseMove.bind(this),false);this._canvasElement.addEventListener("mousemove",this._onMouseMove.bind(this),false);this._canvasElement.addEventListener("contextmenu",this._onContextMenu.bind(this),false);this._lastSelection={};this._layerTree=null;this._textureManager=new WebInspector.LayerTextureManager();this._textureManager.addEventListener(WebInspector.LayerTextureManager.Events.TextureUpdated,this._update,this);this._chromeTextures=[];this._rects=[];this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update,this);} WebInspector.Layers3DView.LayerStyle;WebInspector.Layers3DView.PaintTile;WebInspector.Layers3DView.OutlineType={Hovered:"hovered",Selected:"selected"} WebInspector.Layers3DView.Events={LayerSnapshotRequested:"LayerSnapshotRequested",PaintProfilerRequested:"PaintProfilerRequested",} WebInspector.Layers3DView.ChromeTexture={Left:0,Middle:1,Right:2} WebInspector.Layers3DView.ScrollRectTitles={RepaintsOnScroll:WebInspector.UIString("repaints on scroll"),TouchEventHandler:WebInspector.UIString("touch event listener"),WheelEventHandler:WebInspector.UIString("mousewheel event listener")} WebInspector.Layers3DView.FragmentShader=""+"precision mediump float;\n"+"varying vec4 vColor;\n"+"varying vec2 vTextureCoord;\n"+"uniform sampler2D uSampler;\n"+"void main(void)\n"+"{\n"+" gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n"+"}";WebInspector.Layers3DView.VertexShader=""+"attribute vec3 aVertexPosition;\n"+"attribute vec2 aTextureCoord;\n"+"attribute vec4 aVertexColor;\n"+"uniform mat4 uPMatrix;\n"+"varying vec2 vTextureCoord;\n"+"varying vec4 vColor;\n"+"void main(void)\n"+"{\n"+"gl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\n"+"vColor = aVertexColor;\n"+"vTextureCoord = aTextureCoord;\n"+"}";WebInspector.Layers3DView.HoveredBorderColor=[0,0,255,1];WebInspector.Layers3DView.SelectedBorderColor=[0,255,0,1];WebInspector.Layers3DView.BorderColor=[0,0,0,1];WebInspector.Layers3DView.ViewportBorderColor=[160,160,160,1];WebInspector.Layers3DView.ScrollRectBackgroundColor=[178,100,100,0.6];WebInspector.Layers3DView.HoveredImageMaskColor=[200,200,255,1];WebInspector.Layers3DView.BorderWidth=1;WebInspector.Layers3DView.SelectedBorderWidth=2;WebInspector.Layers3DView.ViewportBorderWidth=3;WebInspector.Layers3DView.LayerSpacing=20;WebInspector.Layers3DView.ScrollRectSpacing=4;WebInspector.Layers3DView.prototype={setLayerTree:function(layerTree) {this._layerTree=layerTree;this._textureManager.reset();this._update();},setTiles:function(tiles) {this._textureManager.setTiles(tiles);},showImageForLayer:function(layer,imageURL) {if(imageURL) this._textureManager.createTexture(onTextureCreated.bind(this),imageURL);else onTextureCreated.call(this,null);function onTextureCreated(texture) {this._layerTexture=texture?{layerId:layer.id(),texture:texture}:null;this._update();}},onResize:function() {this._resizeCanvas();this._update();},wasShown:function() {if(!this._needsUpdate) return;this._resizeCanvas();this._update();},_setOutline:function(type,selection) {this._lastSelection[type]=selection;this._update();},hoverObject:function(selection) {this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered,selection);},selectObject:function(selection) {this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered,null);this._setOutline(WebInspector.Layers3DView.OutlineType.Selected,selection);},_initGL:function(canvas) {var gl=canvas.getContext("webgl");if(!gl) return null;gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);gl.enable(gl.BLEND);gl.clearColor(0.0,0.0,0.0,0.0);gl.enable(gl.DEPTH_TEST);return gl;},_createShader:function(type,script) {var shader=this._gl.createShader(type);this._gl.shaderSource(shader,script);this._gl.compileShader(shader);this._gl.attachShader(this._shaderProgram,shader);},_initShaders:function() {this._shaderProgram=this._gl.createProgram();this._createShader(this._gl.FRAGMENT_SHADER,WebInspector.Layers3DView.FragmentShader);this._createShader(this._gl.VERTEX_SHADER,WebInspector.Layers3DView.VertexShader);this._gl.linkProgram(this._shaderProgram);this._gl.useProgram(this._shaderProgram);this._shaderProgram.vertexPositionAttribute=this._gl.getAttribLocation(this._shaderProgram,"aVertexPosition");this._gl.enableVertexAttribArray(this._shaderProgram.vertexPositionAttribute);this._shaderProgram.vertexColorAttribute=this._gl.getAttribLocation(this._shaderProgram,"aVertexColor");this._gl.enableVertexAttribArray(this._shaderProgram.vertexColorAttribute);this._shaderProgram.textureCoordAttribute=this._gl.getAttribLocation(this._shaderProgram,"aTextureCoord");this._gl.enableVertexAttribArray(this._shaderProgram.textureCoordAttribute);this._shaderProgram.pMatrixUniform=this._gl.getUniformLocation(this._shaderProgram,"uPMatrix");this._shaderProgram.samplerUniform=this._gl.getUniformLocation(this._shaderProgram,"uSampler");},_resizeCanvas:function() {this._canvasElement.width=this._canvasElement.offsetWidth*window.devicePixelRatio;this._canvasElement.height=this._canvasElement.offsetHeight*window.devicePixelRatio;},_updateTransformAndConstraints:function() {var paddingFraction=0.1;var viewport=this._layerTree.viewportSize();var root=this._layerTree.root();var baseWidth=viewport?viewport.width:this._dimensionsForAutoscale.width;var baseHeight=viewport?viewport.height:this._dimensionsForAutoscale.height;var canvasWidth=this._canvasElement.width;var canvasHeight=this._canvasElement.height;var paddingX=canvasWidth*paddingFraction;var paddingY=canvasHeight*paddingFraction;var scaleX=(canvasWidth-2*paddingX)/baseWidth;var scaleY=(canvasHeight-2*paddingY)/baseHeight;var viewScale=Math.min(scaleX,scaleY);var minScaleConstraint=Math.min(baseWidth/this._dimensionsForAutoscale.width,baseHeight/this._dimensionsForAutoscale.width)/2;this._transformController.setScaleConstraints(minScaleConstraint,10/viewScale);var scale=this._transformController.scale();var rotateX=this._transformController.rotateX();var rotateY=this._transformController.rotateY();this._scale=scale*viewScale;var scaleAndRotationMatrix=new WebKitCSSMatrix().scale(scale,scale,scale).translate(canvasWidth/2,canvasHeight/2,0).rotate(rotateX,rotateY,0).scale(viewScale,viewScale,viewScale).translate(-baseWidth/2,-baseHeight/2,0);var bounds;for(var i=0;i<this._rects.length;++i) bounds=WebInspector.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix,this._rects[i].vertices,bounds);this._transformController.clampOffsets((paddingX-bounds.maxX)/window.devicePixelRatio,(canvasWidth-paddingX-bounds.minX)/window.devicePixelRatio,(paddingY-bounds.maxY)/window.devicePixelRatio,(canvasHeight-paddingY-bounds.minY)/window.devicePixelRatio);var offsetX=this._transformController.offsetX()*window.devicePixelRatio;var offsetY=this._transformController.offsetY()*window.devicePixelRatio;this._projectionMatrix=new WebKitCSSMatrix().translate(offsetX,offsetY,0).multiply(scaleAndRotationMatrix);var glProjectionMatrix=new WebKitCSSMatrix().scale(1,-1,-1).translate(-1,-1,0).scale(2/this._canvasElement.width,2/this._canvasElement.height,1/1000000).multiply(this._projectionMatrix);this._gl.uniformMatrix4fv(this._shaderProgram.pMatrixUniform,false,this._arrayFromMatrix(glProjectionMatrix));},_arrayFromMatrix:function(m) {return new Float32Array([m.m11,m.m12,m.m13,m.m14,m.m21,m.m22,m.m23,m.m24,m.m31,m.m32,m.m33,m.m34,m.m41,m.m42,m.m43,m.m44]);},_initWhiteTexture:function() {this._whiteTexture=this._gl.createTexture();this._gl.bindTexture(this._gl.TEXTURE_2D,this._whiteTexture);var whitePixel=new Uint8Array([255,255,255,255]);this._gl.texImage2D(this._gl.TEXTURE_2D,0,this._gl.RGBA,1,1,0,this._gl.RGBA,this._gl.UNSIGNED_BYTE,whitePixel);},_initChromeTextures:function() {function saveChromeTexture(index,value) {this._chromeTextures[index]=value||undefined;} this._textureManager.createTexture(saveChromeTexture.bind(this,WebInspector.Layers3DView.ChromeTexture.Left),"Images/chromeLeft.png");this._textureManager.createTexture(saveChromeTexture.bind(this,WebInspector.Layers3DView.ChromeTexture.Middle),"Images/chromeMiddle.png");this._textureManager.createTexture(saveChromeTexture.bind(this,WebInspector.Layers3DView.ChromeTexture.Right),"Images/chromeRight.png");},_initGLIfNecessary:function() {if(this._gl) return this._gl;this._gl=this._initGL(this._canvasElement);if(!this._gl) return null;this._initShaders();this._initWhiteTexture();this._initChromeTextures();this._textureManager.setContext(this._gl);return this._gl;},_calculateDepthsAndVisibility:function() {this._depthByLayerId={};var depth=0;var showInternalLayers=this._layerViewHost.showInternalLayersSetting().get();var root=showInternalLayers?this._layerTree.root():(this._layerTree.contentRoot()||this._layerTree.root());var queue=[root];this._depthByLayerId[root.id()]=0;this._visibleLayers={};while(queue.length>0){var layer=queue.shift();this._visibleLayers[layer.id()]=showInternalLayers||layer.drawsContent();var children=layer.children();for(var i=0;i<children.length;++i){this._depthByLayerId[children[i].id()]=++depth;queue.push(children[i]);}} this._maxDepth=depth;},_depthForLayer:function(layer) {return this._depthByLayerId[layer.id()]*WebInspector.Layers3DView.LayerSpacing;},_calculateScrollRectDepth:function(layer,index) {return this._depthForLayer(layer)+index*WebInspector.Layers3DView.ScrollRectSpacing+1;},_updateDimensionsForAutoscale:function(layer) {this._dimensionsForAutoscale.width=Math.max(layer.width(),this._dimensionsForAutoscale.width);this._dimensionsForAutoscale.height=Math.max(layer.height(),this._dimensionsForAutoscale.height);},_calculateLayerRect:function(layer) {if(!this._visibleLayers[layer.id()]) return;var selection=new WebInspector.LayerView.LayerSelection(layer);var rect=new WebInspector.Layers3DView.Rectangle(selection);rect.setVertices(layer.quad(),this._depthForLayer(layer));this._appendRect(rect);this._updateDimensionsForAutoscale(layer);},_appendRect:function(rect) {var selection=rect.relatedObject;var isSelected=WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Selected],selection);var isHovered=WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Hovered],selection);if(isSelected){rect.borderColor=WebInspector.Layers3DView.SelectedBorderColor;}else if(isHovered){rect.borderColor=WebInspector.Layers3DView.HoveredBorderColor;var fillColor=rect.fillColor||[255,255,255,1];var maskColor=WebInspector.Layers3DView.HoveredImageMaskColor;rect.fillColor=[fillColor[0]*maskColor[0]/255,fillColor[1]*maskColor[1]/255,fillColor[2]*maskColor[2]/255,fillColor[3]*maskColor[3]];}else{rect.borderColor=WebInspector.Layers3DView.BorderColor;} rect.lineWidth=isSelected?WebInspector.Layers3DView.SelectedBorderWidth:WebInspector.Layers3DView.BorderWidth;this._rects.push(rect);},_calculateLayerScrollRects:function(layer) {var scrollRects=layer.scrollRects();for(var i=0;i<scrollRects.length;++i){var selection=new WebInspector.LayerView.ScrollRectSelection(layer,i);var rect=new WebInspector.Layers3DView.Rectangle(selection);rect.calculateVerticesFromRect(layer,scrollRects[i].rect,this._calculateScrollRectDepth(layer,i));rect.fillColor=WebInspector.Layers3DView.ScrollRectBackgroundColor;this._appendRect(rect);}},_calculateLayerImageRect:function(layer) {var layerTexture=this._layerTexture;if(layer.id()!==layerTexture.layerId) return;var selection=new WebInspector.LayerView.LayerSelection(layer);var rect=new WebInspector.Layers3DView.Rectangle(selection);rect.setVertices(layer.quad(),this._depthForLayer(layer));rect.texture=layerTexture.texture;this._appendRect(rect);},_calculateLayerTileRects:function(layer) {var tiles=this._textureManager.tilesForLayer(layer.id());for(var i=0;i<tiles.length;++i){var tile=tiles[i];if(!tile.texture) continue;var selection=new WebInspector.LayerView.TileSelection(layer,tile.traceEvent);var rect=new WebInspector.Layers3DView.Rectangle(selection);rect.calculateVerticesFromRect(layer,{x:tile.rect[0],y:tile.rect[1],width:tile.rect[2],height:tile.rect[3]},this._depthForLayer(layer)+1);rect.texture=tile.texture;this._appendRect(rect);}},_calculateRects:function() {this._rects=[];this._dimensionsForAutoscale={width:0,height:0};this._layerTree.forEachLayer(this._calculateLayerRect.bind(this));if(this._showSlowScrollRectsSetting.get()) this._layerTree.forEachLayer(this._calculateLayerScrollRects.bind(this));if(this._showPaintsSetting.get()){if(this._layerTexture) this._layerTree.forEachLayer(this._calculateLayerImageRect.bind(this));else this._layerTree.forEachLayer(this._calculateLayerTileRects.bind(this));}},_makeColorsArray:function(color) {var colors=[];var normalizedColor=[color[0]/255,color[1]/255,color[2]/255,color[3]];for(var i=0;i<4;i++) colors=colors.concat(normalizedColor);return colors;},_setVertexAttribute:function(attribute,array,length) {var gl=this._gl;var buffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(array),gl.STATIC_DRAW);gl.vertexAttribPointer(attribute,length,gl.FLOAT,false,0,0);},_drawRectangle:function(vertices,mode,color,texture) {var gl=this._gl;var white=[255,255,255,1];color=color||white;this._setVertexAttribute(this._shaderProgram.vertexPositionAttribute,vertices,3);this._setVertexAttribute(this._shaderProgram.textureCoordAttribute,[0,1,1,1,1,0,0,0],2);this._setVertexAttribute(this._shaderProgram.vertexColorAttribute,this._makeColorsArray(color),color.length);if(texture){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,texture);gl.uniform1i(this._shaderProgram.samplerUniform,0);}else{gl.bindTexture(gl.TEXTURE_2D,this._whiteTexture);} var numberOfVertices=vertices.length/3;gl.drawArrays(mode,0,numberOfVertices);},_drawTexture:function(vertices,texture,color) {this._drawRectangle(vertices,this._gl.TRIANGLE_FAN,color,texture);},_drawViewportAndChrome:function() {var viewport=this._layerTree.viewportSize();if(!viewport) return;var drawChrome=!WebInspector.moduleSetting("frameViewerHideChromeWindow").get()&&this._chromeTextures.length>=3&&this._chromeTextures.indexOf(undefined)<0;var z=(this._maxDepth+1)*WebInspector.Layers3DView.LayerSpacing;var borderWidth=Math.ceil(WebInspector.Layers3DView.ViewportBorderWidth*this._scale);var vertices=[viewport.width,0,z,viewport.width,viewport.height,z,0,viewport.height,z,0,0,z];this._gl.lineWidth(borderWidth);this._drawRectangle(vertices,drawChrome?this._gl.LINE_STRIP:this._gl.LINE_LOOP,WebInspector.Layers3DView.ViewportBorderColor);if(!drawChrome) return;var borderAdjustment=WebInspector.Layers3DView.ViewportBorderWidth/2;var viewportWidth=this._layerTree.viewportSize().width+2*borderAdjustment;var chromeHeight=this._chromeTextures[0].image.naturalHeight;var middleFragmentWidth=viewportWidth-this._chromeTextures[0].image.naturalWidth-this._chromeTextures[2].image.naturalWidth;var x=-borderAdjustment;var y=-chromeHeight;for(var i=0;i<this._chromeTextures.length;++i){var width=i===WebInspector.Layers3DView.ChromeTexture.Middle?middleFragmentWidth:this._chromeTextures[i].image.naturalWidth;if(width<0||x+width>viewportWidth) break;vertices=[x,y,z,x+width,y,z,x+width,y+chromeHeight,z,x,y+chromeHeight,z];this._drawTexture(vertices,(this._chromeTextures[i]));x+=width;}},_drawViewRect:function(rect) {var vertices=rect.vertices;if(rect.texture) this._drawTexture(vertices,rect.texture,rect.fillColor||undefined);else if(rect.fillColor) this._drawRectangle(vertices,this._gl.TRIANGLE_FAN,rect.fillColor);this._gl.lineWidth(rect.lineWidth);if(rect.borderColor) this._drawRectangle(vertices,this._gl.LINE_LOOP,rect.borderColor);},_update:function() {if(!this.isShowing()){this._needsUpdate=true;return;} if(!this._layerTree||!this._layerTree.root()){this._failBanner.show(this.element);return;} var gl=this._initGLIfNecessary();if(!gl){this._failBanner.element.removeChildren();this._failBanner.element.appendChild(this._webglDisabledBanner());this._failBanner.show(this.element);return;} this._failBanner.detach();this._gl.viewportWidth=this._canvasElement.width;this._gl.viewportHeight=this._canvasElement.height;this._calculateDepthsAndVisibility();this._calculateRects();this._updateTransformAndConstraints();this._textureManager.setScale(Number.constrain(0.1,1,this._scale));gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);this._rects.forEach(this._drawViewRect.bind(this));this._drawViewportAndChrome();},_webglDisabledBanner:function() {var fragment=this.element.ownerDocument.createDocumentFragment();fragment.createChild("div").textContent=WebInspector.UIString("Can't display layers,");fragment.createChild("div").textContent=WebInspector.UIString("WebGL support is disabled in your browser.");fragment.appendChild(WebInspector.formatLocalized("Check %s for possible reasons.",[WebInspector.linkifyURLAsNode("about:gpu",undefined,undefined,true)]));return fragment;},_selectionFromEventPoint:function(event) {if(!this._layerTree) return null;var closestIntersectionPoint=Infinity;var closestObject=null;var projectionMatrix=new WebKitCSSMatrix().scale(1,-1,-1).translate(-1,-1,0).multiply(this._projectionMatrix);var x0=(event.clientX-this._canvasElement.totalOffsetLeft())*window.devicePixelRatio;var y0=-(event.clientY-this._canvasElement.totalOffsetTop())*window.devicePixelRatio;function checkIntersection(rect) {if(!rect.relatedObject) return;var t=rect.intersectWithLine(projectionMatrix,x0,y0);if(t<closestIntersectionPoint){closestIntersectionPoint=t;closestObject=rect.relatedObject;}} this._rects.forEach(checkIntersection);return closestObject;},_createVisibilitySetting:function(caption,name,value,toolbar) {var checkbox=new WebInspector.ToolbarCheckbox(WebInspector.UIString(caption));toolbar.appendToolbarItem(checkbox);var setting=WebInspector.settings.createSetting(name,value);WebInspector.SettingsUI.bindCheckbox(checkbox.inputElement,setting);setting.addChangeListener(this._update,this);return setting;},_initToolbar:function() {this._panelToolbar=this._transformController.toolbar();this.element.appendChild(this._panelToolbar.element);this._showSlowScrollRectsSetting=this._createVisibilitySetting("Slow scroll rects","frameViewerShowSlowScrollRects",true,this._panelToolbar);this._showPaintsSetting=this._createVisibilitySetting("Paints","frameViewerShowPaints",true,this._panelToolbar);WebInspector.moduleSetting("frameViewerHideChromeWindow").addChangeListener(this._update,this);},_onContextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);contextMenu.appendItem(WebInspector.UIString("Reset View"),this._transformController.resetAndNotify.bind(this._transformController),false);var selection=this._selectionFromEventPoint(event);if(selection&&selection.type()===WebInspector.LayerView.Selection.Type.Tile) contextMenu.appendItem(WebInspector.UIString("Show Paint Profiler"),this.dispatchEventToListeners.bind(this,WebInspector.Layers3DView.Events.PaintProfilerRequested,selection.traceEvent()),false);this._layerViewHost.showContextMenu(contextMenu,selection);},_onMouseMove:function(event) {if(event.which) return;this._layerViewHost.hoverObject(this._selectionFromEventPoint(event));},_onMouseDown:function(event) {this._mouseDownX=event.clientX;this._mouseDownY=event.clientY;},_onMouseUp:function(event) {const maxDistanceInPixels=6;if(this._mouseDownX&&Math.abs(event.clientX-this._mouseDownX)<maxDistanceInPixels&&Math.abs(event.clientY-this._mouseDownY)<maxDistanceInPixels) this._layerViewHost.selectObject(this._selectionFromEventPoint(event));delete this._mouseDownX;delete this._mouseDownY;},_onDoubleClick:function(event) {var selection=this._selectionFromEventPoint(event);if(selection){if(selection.type()==WebInspector.LayerView.Selection.Type.Tile) this.dispatchEventToListeners(WebInspector.Layers3DView.Events.PaintProfilerRequested,selection.traceEvent());else if(selection.layer()) this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSnapshotRequested,selection.layer());} event.stopPropagation();},__proto__:WebInspector.VBox.prototype} WebInspector.LayerTextureManager=function() {WebInspector.Object.call(this);this.reset();} WebInspector.LayerTextureManager.Events={TextureUpdated:"TextureUpated"} WebInspector.LayerTextureManager.prototype={reset:function() {this._tilesByLayerId={};this._scale=0;},setContext:function(glContext) {this._gl=glContext;if(this._scale) this._updateTextures();},setTiles:function(paintTiles) {this._tilesByLayerId={};if(!paintTiles) return;for(var i=0;i<paintTiles.length;++i){var layerId=paintTiles[i].layerId;var tilesForLayer=this._tilesByLayerId[layerId];if(!tilesForLayer){tilesForLayer=[];this._tilesByLayerId[layerId]=tilesForLayer;} var tile=new WebInspector.LayerTextureManager.Tile(paintTiles[i].snapshot,paintTiles[i].rect,paintTiles[i].traceEvent);tilesForLayer.push(tile);if(this._scale&&this._gl) this._updateTile(tile);}},setScale:function(scale) {if(this._scale&&this._scale>=scale) return;this._scale=scale;this._updateTextures();},tilesForLayer:function(layerId) {return this._tilesByLayerId[layerId]||[];},_updateTextures:function() {if(!this._gl) return;if(!this._scale) return;for(var layerId in this._tilesByLayerId){for(var i=0;i<this._tilesByLayerId[layerId].length;++i){var tile=this._tilesByLayerId[layerId][i];if(!tile.scale||tile.scale<this._scale) this._updateTile(tile);}}},_updateTile:function(tile) {console.assert(this._scale&&this._gl);tile.scale=this._scale;tile.snapshot.requestImage(null,null,tile.scale,onGotImage.bind(this));function onGotImage(imageURL) {if(imageURL) this.createTexture(onTextureCreated.bind(this),imageURL);} function onTextureCreated(texture) {tile.texture=texture;this.dispatchEventToListeners(WebInspector.LayerTextureManager.Events.TextureUpdated);}},createTexture:function(textureCreatedCallback,imageURL) {var image=new Image();image.addEventListener("load",onImageLoaded.bind(this),false);image.addEventListener("error",onImageError,false);image.src=imageURL;function onImageLoaded() {textureCreatedCallback(this._createTextureForImage(image));} function onImageError() {textureCreatedCallback(null);}},_createTextureForImage:function(image) {var texture=this._gl.createTexture();texture.image=image;this._gl.bindTexture(this._gl.TEXTURE_2D,texture);this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL,true);this._gl.texImage2D(this._gl.TEXTURE_2D,0,this._gl.RGBA,this._gl.RGBA,this._gl.UNSIGNED_BYTE,texture.image);this._gl.texParameteri(this._gl.TEXTURE_2D,this._gl.TEXTURE_MIN_FILTER,this._gl.LINEAR);this._gl.texParameteri(this._gl.TEXTURE_2D,this._gl.TEXTURE_MAG_FILTER,this._gl.LINEAR);this._gl.texParameteri(this._gl.TEXTURE_2D,this._gl.TEXTURE_WRAP_S,this._gl.CLAMP_TO_EDGE);this._gl.texParameteri(this._gl.TEXTURE_2D,this._gl.TEXTURE_WRAP_T,this._gl.CLAMP_TO_EDGE);this._gl.bindTexture(this._gl.TEXTURE_2D,null);return texture;},__proto__:WebInspector.Object.prototype} WebInspector.Layers3DView.Rectangle=function(relatedObject) {this.relatedObject=relatedObject;this.lineWidth=1;this.borderColor=null;this.fillColor=null;this.texture=null;} WebInspector.Layers3DView.Rectangle.prototype={setVertices:function(quad,z) {this.vertices=[quad[0],quad[1],z,quad[2],quad[3],z,quad[4],quad[5],z,quad[6],quad[7],z];},_calculatePointOnQuad:function(quad,ratioX,ratioY) {var x0=quad[0];var y0=quad[1];var x1=quad[2];var y1=quad[3];var x2=quad[4];var y2=quad[5];var x3=quad[6];var y3=quad[7];var firstSidePointX=x0+ratioX*(x1-x0);var firstSidePointY=y0+ratioX*(y1-y0);var thirdSidePointX=x3+ratioX*(x2-x3);var thirdSidePointY=y3+ratioX*(y2-y3);var x=firstSidePointX+ratioY*(thirdSidePointX-firstSidePointX);var y=firstSidePointY+ratioY*(thirdSidePointY-firstSidePointY);return[x,y];},calculateVerticesFromRect:function(layer,rect,z) {var quad=layer.quad();var rx1=rect.x/layer.width();var rx2=(rect.x+rect.width)/layer.width();var ry1=rect.y/layer.height();var ry2=(rect.y+rect.height)/layer.height();var rectQuad=this._calculatePointOnQuad(quad,rx1,ry1).concat(this._calculatePointOnQuad(quad,rx2,ry1)).concat(this._calculatePointOnQuad(quad,rx2,ry2)).concat(this._calculatePointOnQuad(quad,rx1,ry2));this.setVertices(rectQuad,z);},intersectWithLine:function(matrix,x0,y0) {var i;var points=[];for(i=0;i<4;++i) points[i]=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(this.vertices[i*3],this.vertices[i*3+1],this.vertices[i*3+2]),matrix);var normal=WebInspector.Geometry.crossProduct(WebInspector.Geometry.subtract(points[1],points[0]),WebInspector.Geometry.subtract(points[2],points[1]));var A=normal.x;var B=normal.y;var C=normal.z;var D=-(A*points[0].x+B*points[0].y+C*points[0].z);var t=-(D+A*x0+B*y0)/C;var pt=new WebInspector.Geometry.Vector(x0,y0,t);var tVects=points.map(WebInspector.Geometry.subtract.bind(null,pt));for(i=0;i<tVects.length;++i){var product=WebInspector.Geometry.scalarProduct(normal,WebInspector.Geometry.crossProduct(tVects[i],tVects[(i+1)%tVects.length]));if(product<0) return undefined;} return t;}} WebInspector.LayerTextureManager.Tile=function(snapshot,rect,traceEvent) {this.snapshot=snapshot;this.rect=rect;this.traceEvent=traceEvent;this.scale=0;this.texture=null;};WebInspector.MemoryCountersGraph=function(delegate,model,filters) {WebInspector.CountersGraph.call(this,delegate,model,filters);this._countersByName={};this._countersByName["jsHeapSizeUsed"]=this.createCounter(WebInspector.UIString("JS Heap"),WebInspector.UIString("JS Heap: %s"),"hsl(220, 90%, 43%)",Number.bytesToString);this._countersByName["documents"]=this.createCounter(WebInspector.UIString("Documents"),WebInspector.UIString("Documents: %s"),"hsl(0, 90%, 43%)");this._countersByName["nodes"]=this.createCounter(WebInspector.UIString("Nodes"),WebInspector.UIString("Nodes: %s"),"hsl(120, 90%, 43%)");this._countersByName["jsEventListeners"]=this.createCounter(WebInspector.UIString("Listeners"),WebInspector.UIString("Listeners: %s"),"hsl(38, 90%, 43%)");this._gpuMemoryCounter=this.createCounter(WebInspector.UIString("GPU Memory"),WebInspector.UIString("GPU Memory [KB]: %s"),"hsl(300, 90%, 43%)",Number.bytesToString);this._countersByName["gpuMemoryUsedKB"]=this._gpuMemoryCounter;} WebInspector.MemoryCountersGraph.prototype={refreshRecords:function() {this.reset();var events=this._model.mainThreadEvents();for(var i=0;i<events.length;++i){var event=events[i];if(event.name!==WebInspector.TimelineModel.RecordType.UpdateCounters) continue;var counters=event.args.data;if(!counters) return;for(var name in counters){var counter=this._countersByName[name];if(counter) counter.appendSample(event.startTime,counters[name]);} var gpuMemoryLimitCounterName="gpuMemoryLimitKB";if(gpuMemoryLimitCounterName in counters) this._gpuMemoryCounter.setLimit(counters[gpuMemoryLimitCounterName]);} this.scheduleRefresh();},__proto__:WebInspector.CountersGraph.prototype};WebInspector.TimelineController=function(target,delegate,tracingModel) {this._delegate=delegate;this._target=target;this._tracingModel=tracingModel;this._targets=[];this._allProfilesStoppedPromise=Promise.resolve();this._targetsResumedPromise=Promise.resolve();WebInspector.targetManager.observeTargets(this);} WebInspector.TimelineController.prototype={startRecording:function(captureCauses,enableJSSampling,captureMemory,capturePictures,captureFilmStrip) {function disabledByDefault(category) {return"disabled-by-default-"+category;} var categoriesArray=["-*","devtools.timeline",disabledByDefault("devtools.timeline"),disabledByDefault("devtools.timeline.frame"),WebInspector.TracingModel.TopLevelEventCategory,WebInspector.TimelineModel.Category.Console,WebInspector.TimelineModel.Category.UserTiming];categoriesArray.push(WebInspector.TimelineModel.Category.LatencyInfo) if(Runtime.experiments.isEnabled("timelineFlowEvents")){categoriesArray.push(disabledByDefault("toplevel.flow"),disabledByDefault("ipc.flow"));} if(Runtime.experiments.isEnabled("timelineTracingJSProfile")&&enableJSSampling){categoriesArray.push(disabledByDefault("v8.cpu_profile"));if(WebInspector.moduleSetting("highResolutionCpuProfiling").get()) categoriesArray.push(disabledByDefault("v8.cpu_profile.hires"));} if(captureCauses||enableJSSampling) categoriesArray.push(disabledByDefault("devtools.timeline.stack"));if(captureCauses&&Runtime.experiments.isEnabled("timelineInvalidationTracking")) categoriesArray.push(disabledByDefault("devtools.timeline.invalidationTracking"));if(capturePictures){categoriesArray.push(disabledByDefault("devtools.timeline.layers"),disabledByDefault("devtools.timeline.picture"),disabledByDefault("blink.graphics_context_annotations"));} if(captureFilmStrip) categoriesArray.push(disabledByDefault("devtools.screenshot"));var categories=categoriesArray.join(",");this._startRecordingWithCategories(categories,enableJSSampling);},stopRecording:function() {this._allProfilesStoppedPromise=this._stopProfilingOnAllTargets();this._target.tracingManager.stop();this._targetsResumedPromise=WebInspector.targetManager.resumeAllTargets();this._delegate.loadingStarted();},targetAdded:function(target) {this._targets.push(target);if(this._profiling) this._startProfilingOnTarget(target);},targetRemoved:function(target) {this._targets.remove(target,true);},_startProfilingOnTarget:function(target) {return target.profilerAgent().start();},_startProfilingOnAllTargets:function() {var intervalUs=WebInspector.moduleSetting("highResolutionCpuProfiling").get()?100:1000;this._target.profilerAgent().setSamplingInterval(intervalUs);this._profiling=true;return Promise.all(this._targets.map(this._startProfilingOnTarget));},_stopProfilingOnTarget:function(target) {return target.profilerAgent().stop(this._addCpuProfile.bind(this,target.id()));},_addCpuProfile:function(targetId,error,cpuProfile) {if(!cpuProfile){WebInspector.console.warn(WebInspector.UIString("CPU profile for a target is not available. %s",error||""));return;} if(!this._cpuProfiles) this._cpuProfiles=new Map();this._cpuProfiles.set(targetId,cpuProfile);},_stopProfilingOnAllTargets:function() {var targets=this._profiling?this._targets:[];this._profiling=false;return Promise.all(targets.map(this._stopProfilingOnTarget,this));},_startRecordingWithCategories:function(categories,enableJSSampling,callback) {WebInspector.targetManager.suspendAllTargets();var profilingStartedPromise=enableJSSampling&&!Runtime.experiments.isEnabled("timelineTracingJSProfile")?this._startProfilingOnAllTargets():Promise.resolve();var samplingFrequencyHz=WebInspector.moduleSetting("highResolutionCpuProfiling").get()?10000:1000;var options="sampling-frequency="+samplingFrequencyHz;var target=this._target;var tracingManager=target.tracingManager;target.resourceTreeModel.suspendReload();profilingStartedPromise.then(tracingManager.start.bind(tracingManager,this,categories,options,onTraceStarted));function onTraceStarted(error) {target.resourceTreeModel.resumeReload();if(callback) callback(error);}},tracingStarted:function() {this._tracingModel.reset();this._delegate.recordingStarted();},traceEventsCollected:function(events) {this._tracingModel.addEvents(events);},tracingComplete:function() {Promise.all([this._allProfilesStoppedPromise,this._targetsResumedPromise]).then(this._didStopRecordingTraceEvents.bind(this));},_didStopRecordingTraceEvents:function() {this._injectCpuProfileEvents();this._tracingModel.tracingComplete();this._delegate.loadingComplete(true);},_injectCpuProfileEvent:function(pid,tid,cpuProfile) {if(!cpuProfile) return;var cpuProfileEvent=({cat:WebInspector.TracingModel.DevToolsMetadataEventCategory,ph:WebInspector.TracingModel.Phase.Instant,ts:this._tracingModel.maximumRecordTime()*1000,pid:pid,tid:tid,name:WebInspector.TimelineModel.RecordType.CpuProfile,args:{data:{cpuProfile:cpuProfile}}});this._tracingModel.addEvents([cpuProfileEvent]);},_injectCpuProfileEvents:function() {if(!this._cpuProfiles) return;var metadataEventTypes=WebInspector.TimelineModel.DevToolsMetadataEvent;var metadataEvents=this._tracingModel.devToolsMetadataEvents();var mainMetaEvent=metadataEvents.filter(event=>event.name===metadataEventTypes.TracingStartedInPage).peekLast();if(!mainMetaEvent) return;var pid=mainMetaEvent.thread.process().id();var mainCpuProfile=this._cpuProfiles.get(this._target.id());this._injectCpuProfileEvent(pid,mainMetaEvent.thread.id(),mainCpuProfile);var workerMetaEvents=metadataEvents.filter(event=>event.name===metadataEventTypes.TracingSessionIdForWorker);for(var metaEvent of workerMetaEvents){var workerId=metaEvent.args["data"]["workerId"];var workerTarget=this._target.workerManager?this._target.workerManager.targetByWorkerId(workerId):null;if(!workerTarget) continue;var cpuProfile=this._cpuProfiles.get(workerTarget.id());this._injectCpuProfileEvent(pid,metaEvent.args["data"]["workerThreadId"],cpuProfile);} this._cpuProfiles=null;},tracingBufferUsage:function(usage) {this._delegate.recordingProgress(usage);},eventsRetrievalProgress:function(progress) {this._delegate.loadingProgress(progress);}};WebInspector.TimelineModel=function(eventFilter) {this._eventFilter=eventFilter;this.reset();} WebInspector.TimelineModel.RecordType={Task:"Task",Program:"Program",EventDispatch:"EventDispatch",GPUTask:"GPUTask",Animation:"Animation",RequestMainThreadFrame:"RequestMainThreadFrame",BeginFrame:"BeginFrame",NeedsBeginFrameChanged:"NeedsBeginFrameChanged",BeginMainThreadFrame:"BeginMainThreadFrame",ActivateLayerTree:"ActivateLayerTree",DrawFrame:"DrawFrame",HitTest:"HitTest",ScheduleStyleRecalculation:"ScheduleStyleRecalculation",RecalculateStyles:"RecalculateStyles",UpdateLayoutTree:"UpdateLayoutTree",InvalidateLayout:"InvalidateLayout",Layout:"Layout",UpdateLayer:"UpdateLayer",UpdateLayerTree:"UpdateLayerTree",PaintSetup:"PaintSetup",Paint:"Paint",PaintImage:"PaintImage",Rasterize:"Rasterize",RasterTask:"RasterTask",ScrollLayer:"ScrollLayer",CompositeLayers:"CompositeLayers",ScheduleStyleInvalidationTracking:"ScheduleStyleInvalidationTracking",StyleRecalcInvalidationTracking:"StyleRecalcInvalidationTracking",StyleInvalidatorInvalidationTracking:"StyleInvalidatorInvalidationTracking",LayoutInvalidationTracking:"LayoutInvalidationTracking",LayerInvalidationTracking:"LayerInvalidationTracking",PaintInvalidationTracking:"PaintInvalidationTracking",ScrollInvalidationTracking:"ScrollInvalidationTracking",ParseHTML:"ParseHTML",ParseAuthorStyleSheet:"ParseAuthorStyleSheet",TimerInstall:"TimerInstall",TimerRemove:"TimerRemove",TimerFire:"TimerFire",XHRReadyStateChange:"XHRReadyStateChange",XHRLoad:"XHRLoad",CompileScript:"v8.compile",EvaluateScript:"EvaluateScript",CommitLoad:"CommitLoad",MarkLoad:"MarkLoad",MarkDOMContent:"MarkDOMContent",MarkFirstPaint:"MarkFirstPaint",TimeStamp:"TimeStamp",ConsoleTime:"ConsoleTime",UserTiming:"UserTiming",ResourceSendRequest:"ResourceSendRequest",ResourceReceiveResponse:"ResourceReceiveResponse",ResourceReceivedData:"ResourceReceivedData",ResourceFinish:"ResourceFinish",FunctionCall:"FunctionCall",GCEvent:"GCEvent",MajorGC:"MajorGC",MinorGC:"MinorGC",JSFrame:"JSFrame",JSSample:"JSSample",V8Sample:"V8Sample",JitCodeAdded:"JitCodeAdded",JitCodeMoved:"JitCodeMoved",ParseScriptOnBackground:"v8.parseOnBackground",UpdateCounters:"UpdateCounters",RequestAnimationFrame:"RequestAnimationFrame",CancelAnimationFrame:"CancelAnimationFrame",FireAnimationFrame:"FireAnimationFrame",RequestIdleCallback:"RequestIdleCallback",CancelIdleCallback:"CancelIdleCallback",FireIdleCallback:"FireIdleCallback",WebSocketCreate:"WebSocketCreate",WebSocketSendHandshakeRequest:"WebSocketSendHandshakeRequest",WebSocketReceiveHandshakeResponse:"WebSocketReceiveHandshakeResponse",WebSocketDestroy:"WebSocketDestroy",EmbedderCallback:"EmbedderCallback",SetLayerTreeId:"SetLayerTreeId",TracingStartedInPage:"TracingStartedInPage",TracingSessionIdForWorker:"TracingSessionIdForWorker",DecodeImage:"Decode Image",ResizeImage:"Resize Image",DrawLazyPixelRef:"Draw LazyPixelRef",DecodeLazyPixelRef:"Decode LazyPixelRef",LazyPixelRef:"LazyPixelRef",LayerTreeHostImplSnapshot:"cc::LayerTreeHostImpl",PictureSnapshot:"cc::Picture",DisplayItemListSnapshot:"cc::DisplayItemList",LatencyInfo:"LatencyInfo",LatencyInfoFlow:"LatencyInfo.Flow",InputLatencyMouseMove:"InputLatency::MouseMove",InputLatencyMouseWheel:"InputLatency::MouseWheel",ImplSideFling:"InputHandlerProxy::HandleGestureFling::started",GCIdleLazySweep:"ThreadState::performIdleLazySweep",GCCompleteSweep:"ThreadState::completeSweep",GCCollectGarbage:"BlinkGCMarking",CpuProfile:"CpuProfile"} WebInspector.TimelineModel.Category={Console:"blink.console",UserTiming:"blink.user_timing",LatencyInfo:"latencyInfo"};WebInspector.TimelineModel.WarningType={ForcedStyle:"ForcedStyle",ForcedLayout:"ForcedLayout",IdleDeadlineExceeded:"IdleDeadlineExceeded",V8Deopt:"V8Deopt"} WebInspector.TimelineModel.MainThreadName="main";WebInspector.TimelineModel.WorkerThreadName="DedicatedWorker Thread";WebInspector.TimelineModel.RendererMainThreadName="CrRendererMain";WebInspector.TimelineModel.forEachEvent=function(events,onStartEvent,onEndEvent,onInstantEvent,startTime,endTime) {startTime=startTime||0;endTime=endTime||Infinity;var stack=[];for(var i=0;i<events.length;++i){var e=events[i];if((e.endTime||e.startTime)<startTime) continue;if(e.startTime>=endTime) break;if(WebInspector.TracingModel.isAsyncPhase(e.phase)||WebInspector.TracingModel.isFlowPhase(e.phase)) continue;while(stack.length&&stack.peekLast().endTime<=e.startTime) onEndEvent(stack.pop());if(e.duration){onStartEvent(e);stack.push(e);}else{onInstantEvent&&onInstantEvent(e,stack.peekLast()||null);}} while(stack.length) onEndEvent(stack.pop());} WebInspector.TimelineModel.DevToolsMetadataEvent={TracingStartedInBrowser:"TracingStartedInBrowser",TracingStartedInPage:"TracingStartedInPage",TracingSessionIdForWorker:"TracingSessionIdForWorker",};WebInspector.TimelineModel.VirtualThread=function(name) {this.name=name;this.events=[];this.asyncEventsByGroup=new Map();} WebInspector.TimelineModel.VirtualThread.prototype={isWorker:function() {return this.name===WebInspector.TimelineModel.WorkerThreadName;}} WebInspector.TimelineModel.Record=function(traceEvent) {this._event=traceEvent;this._children=[];} WebInspector.TimelineModel.Record._compareStartTime=function(a,b) {return a.startTime()<=b.startTime()?-1:1;} WebInspector.TimelineModel.Record.prototype={target:function() {var threadName=this._event.thread.name();return threadName===WebInspector.TimelineModel.RendererMainThreadName?WebInspector.targetManager.targets()[0]||null:null;},children:function() {return this._children;},startTime:function() {return this._event.startTime;},endTime:function() {return this._event.endTime||this._event.startTime;},thread:function() {if(this._event.thread.name()===WebInspector.TimelineModel.RendererMainThreadName) return WebInspector.TimelineModel.MainThreadName;return this._event.thread.name();},type:function() {return WebInspector.TimelineModel._eventType(this._event);},getUserObject:function(key) {if(key==="TimelineUIUtils::preview-element") return this._event.previewElement;throw new Error("Unexpected key: "+key);},setUserObject:function(key,value) {if(key!=="TimelineUIUtils::preview-element") throw new Error("Unexpected key: "+key);this._event.previewElement=(value);},traceEvent:function() {return this._event;},_addChild:function(child) {this._children.push(child);child.parent=this;}} WebInspector.TimelineModel.MetadataEvents;WebInspector.TimelineModel._eventType=function(event) {if(event.hasCategory(WebInspector.TimelineModel.Category.Console)) return WebInspector.TimelineModel.RecordType.ConsoleTime;if(event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return WebInspector.TimelineModel.RecordType.UserTiming;if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) return WebInspector.TimelineModel.RecordType.LatencyInfo;return(event.name);} WebInspector.TimelineModel.prototype={forAllRecords:function(preOrderCallback,postOrderCallback) {function processRecords(records,depth) {for(var i=0;i<records.length;++i){var record=records[i];if(preOrderCallback&&preOrderCallback(record,depth)) return true;if(processRecords(record.children(),depth+1)) return true;if(postOrderCallback&&postOrderCallback(record,depth)) return true;} return false;} return processRecords(this._records,0);},forAllFilteredRecords:function(filters,callback) {function processRecord(record,depth) {var visible=WebInspector.TimelineModel.isVisible(filters,record.traceEvent());if(visible&&callback(record,depth)) return true;for(var i=0;i<record.children().length;++i){if(processRecord.call(this,record.children()[i],visible?depth+1:depth)) return true;} return false;} for(var i=0;i<this._records.length;++i) processRecord.call(this,this._records[i],0);},records:function() {return this._records;},cpuProfiles:function() {return this._cpuProfiles;},sessionId:function() {return this._sessionId;},target:function() {return WebInspector.targetManager.targets()[0];},setEvents:function(tracingModel,produceTraceStartedInPage) {this.reset();this._resetProcessingState();this._minimumRecordTime=tracingModel.minimumRecordTime();this._maximumRecordTime=tracingModel.maximumRecordTime();var metadataEvents=this._processMetadataEvents(tracingModel,!!produceTraceStartedInPage);var startTime=0;for(var i=0,length=metadataEvents.page.length;i<length;i++){var metaEvent=metadataEvents.page[i];var process=metaEvent.thread.process();var endTime=i+1<length?metadataEvents.page[i+1].startTime:Infinity;this._currentPage=metaEvent.args["data"]&&metaEvent.args["data"]["page"];for(var thread of process.sortedThreads()){if(thread.name()===WebInspector.TimelineModel.WorkerThreadName&&!metadataEvents.workers.some(function(e){return e.args["data"]["workerThreadId"]===thread.id();})) continue;this._processThreadEvents(startTime,endTime,metaEvent.thread,thread);} startTime=endTime;} this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);this._processBrowserEvents(tracingModel);this._buildTimelineRecords();this._buildGPUEvents(tracingModel);this._insertFirstPaintEvent();this._resetProcessingState();},_processMetadataEvents:function(tracingModel,produceTraceStartedInPage) {var metadataEvents=tracingModel.devToolsMetadataEvents();var pageDevToolsMetadataEvents=[];var workersDevToolsMetadataEvents=[];for(var event of metadataEvents){if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage){pageDevToolsMetadataEvents.push(event);}else if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker){workersDevToolsMetadataEvents.push(event);}else if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser){console.assert(!this._mainFrameNodeId,"Multiple sessions in trace");this._mainFrameNodeId=event.args["frameTreeNodeId"];}} if(!pageDevToolsMetadataEvents.length){var pageMetaEvent=produceTraceStartedInPage?this._makeMockPageMetadataEvent(tracingModel):null;if(!pageMetaEvent){console.error(WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage+" event not found.");return{page:[],workers:[]};} pageDevToolsMetadataEvents.push(pageMetaEvent);} var sessionId=pageDevToolsMetadataEvents[0].args["sessionId"]||pageDevToolsMetadataEvents[0].args["data"]["sessionId"];this._sessionId=sessionId;var mismatchingIds=new Set();function checkSessionId(event) {var args=event.args;if(args["data"]) args=args["data"];var id=args["sessionId"];if(id===sessionId) return true;mismatchingIds.add(id);return false;} var result={page:pageDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime),workers:workersDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime)};if(mismatchingIds.size) WebInspector.console.error("Timeline recording was started in more than one page simultaneously. Session id mismatch: "+this._sessionId+" and "+mismatchingIds.valuesArray()+".");return result;},_makeMockPageMetadataEvent:function(tracingModel) {var rendererMainThreadName=WebInspector.TimelineModel.RendererMainThreadName;var process=Object.values(tracingModel.sortedProcesses()).filter(function(p){return p.threadByName(rendererMainThreadName);})[0];var thread=process&&process.threadByName(rendererMainThreadName);if(!thread) return null;var pageMetaEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory,WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage,WebInspector.TracingModel.Phase.Metadata,tracingModel.minimumRecordTime(),thread);pageMetaEvent.addArgs({"data":{"sessionId":"mockSessionId"}});return pageMetaEvent;},_insertFirstPaintEvent:function() {if(!this._firstCompositeLayers) return;var recordTypes=WebInspector.TimelineModel.RecordType;var i=this._inspectedTargetEvents.lowerBound(this._firstCompositeLayers,WebInspector.TracingModel.Event.compareStartTime);for(;i<this._inspectedTargetEvents.length&&this._inspectedTargetEvents[i].name!==recordTypes.DrawFrame;++i){} if(i>=this._inspectedTargetEvents.length) return;var drawFrameEvent=this._inspectedTargetEvents[i];var firstPaintEvent=new WebInspector.TracingModel.Event(drawFrameEvent.categoriesString,recordTypes.MarkFirstPaint,WebInspector.TracingModel.Phase.Instant,drawFrameEvent.startTime,drawFrameEvent.thread);this._mainThreadEvents.splice(this._mainThreadEvents.lowerBound(firstPaintEvent,WebInspector.TracingModel.Event.compareStartTime),0,firstPaintEvent);var firstPaintRecord=new WebInspector.TimelineModel.Record(firstPaintEvent);this._eventDividerRecords.splice(this._eventDividerRecords.lowerBound(firstPaintRecord,WebInspector.TimelineModel.Record._compareStartTime),0,firstPaintRecord);},_processBrowserEvents:function(tracingModel) {var browserMain=tracingModel.threadByName("Browser","CrBrowserMain");if(!browserMain) return;browserMain.events().forEach(this._processBrowserEvent,this);var asyncEventsByGroup=new Map();this._processAsyncEvents(asyncEventsByGroup,browserMain.asyncEvents());this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup,asyncEventsByGroup);},_buildTimelineRecords:function() {var topLevelRecords=this._buildTimelineRecordsForThread(this.mainThreadEvents());for(var i=0;i<topLevelRecords.length;i++){var record=topLevelRecords[i];if(WebInspector.TracingModel.isTopLevelEvent(record.traceEvent())) this._mainThreadTasks.push(record);} function processVirtualThreadEvents(virtualThread) {var threadRecords=this._buildTimelineRecordsForThread(virtualThread.events);topLevelRecords=topLevelRecords.mergeOrdered(threadRecords,WebInspector.TimelineModel.Record._compareStartTime);} this.virtualThreads().forEach(processVirtualThreadEvents.bind(this));this._records=topLevelRecords;},_buildGPUEvents:function(tracingModel) {var thread=tracingModel.threadByName("GPU Process","CrGpuMain");if(!thread) return;var gpuEventName=WebInspector.TimelineModel.RecordType.GPUTask;this._gpuEvents=thread.events().filter(event=>event.name===gpuEventName);},_buildTimelineRecordsForThread:function(threadEvents) {var recordStack=[];var topLevelRecords=[];for(var i=0,size=threadEvents.length;i<size;++i){var event=threadEvents[i];for(var top=recordStack.peekLast();top&&top._event.endTime<=event.startTime;top=recordStack.peekLast()) recordStack.pop();if(event.phase===WebInspector.TracingModel.Phase.AsyncEnd||event.phase===WebInspector.TracingModel.Phase.NestableAsyncEnd) continue;var parentRecord=recordStack.peekLast();if(WebInspector.TracingModel.isAsyncBeginPhase(event.phase)&&parentRecord&&event.endTime>parentRecord._event.endTime) continue;var record=new WebInspector.TimelineModel.Record(event);if(WebInspector.TimelineUIUtils.isMarkerEvent(event)) this._eventDividerRecords.push(record);if(!this._eventFilter.accept(event)&&!WebInspector.TracingModel.isTopLevelEvent(event)) continue;if(parentRecord) parentRecord._addChild(record);else topLevelRecords.push(record);if(event.endTime) recordStack.push(record);} return topLevelRecords;},_resetProcessingState:function() {this._asyncEventTracker=new WebInspector.TimelineAsyncEventTracker();this._invalidationTracker=new WebInspector.InvalidationTracker();this._layoutInvalidate={};this._lastScheduleStyleRecalculation={};this._paintImageEventByPixelRefId={};this._lastPaintForLayer={};this._lastRecalculateStylesEvent=null;this._currentScriptEvent=null;this._eventStack=[];this._hadCommitLoad=false;this._firstCompositeLayers=null;this._knownInputEvents=new Set();this._currentPage=null;},_processThreadEvents:function(startTime,endTime,mainThread,thread) {var events=thread.events();var asyncEvents=thread.asyncEvents();var jsSamples;if(Runtime.experiments.isEnabled("timelineTracingJSProfile")){jsSamples=WebInspector.TimelineJSProfileProcessor.processRawV8Samples(events);}else{var cpuProfileEvent=events.peekLast();if(cpuProfileEvent&&cpuProfileEvent.name===WebInspector.TimelineModel.RecordType.CpuProfile){var cpuProfile=cpuProfileEvent.args["data"]["cpuProfile"];if(cpuProfile){var jsProfileModel=new WebInspector.CPUProfileDataModel(cpuProfile);this._cpuProfiles.push(jsProfileModel);jsSamples=WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(jsProfileModel,thread);}}} if(jsSamples&&jsSamples.length) events=events.mergeOrdered(jsSamples,WebInspector.TracingModel.Event.orderedCompareStartTime);if(jsSamples||events.some(function(e){return e.name===WebInspector.TimelineModel.RecordType.JSSample;})){var jsFrameEvents=WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);if(jsFrameEvents&&jsFrameEvents.length) events=jsFrameEvents.mergeOrdered(events,WebInspector.TracingModel.Event.orderedCompareStartTime);} var threadEvents;var threadAsyncEventsByGroup;if(thread===mainThread){threadEvents=this._mainThreadEvents;threadAsyncEventsByGroup=this._mainThreadAsyncEventsByGroup;}else{var virtualThread=new WebInspector.TimelineModel.VirtualThread(thread.name());this._virtualThreads.push(virtualThread);threadEvents=virtualThread.events;threadAsyncEventsByGroup=virtualThread.asyncEventsByGroup;} this._eventStack=[];var i=events.lowerBound(startTime,function(time,event){return time-event.startTime});var length=events.length;for(;i<length;i++){var event=events[i];if(endTime&&event.startTime>=endTime) break;if(!this._processEvent(event)) continue;threadEvents.push(event);this._inspectedTargetEvents.push(event);} this._processAsyncEvents(threadAsyncEventsByGroup,asyncEvents,startTime,endTime);if(thread.name()==="Compositor"){this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup,threadAsyncEventsByGroup);threadAsyncEventsByGroup.clear();}},_processAsyncEvents:function(asyncEventsByGroup,asyncEvents,startTime,endTime) {var i=startTime?asyncEvents.lowerBound(startTime,function(time,asyncEvent){return time-asyncEvent.startTime}):0;for(;i<asyncEvents.length;++i){var asyncEvent=asyncEvents[i];if(endTime&&asyncEvent.startTime>=endTime) break;var asyncGroup=this._processAsyncEvent(asyncEvent);if(!asyncGroup) continue;var groupAsyncEvents=asyncEventsByGroup.get(asyncGroup);if(!groupAsyncEvents){groupAsyncEvents=[];asyncEventsByGroup.set(asyncGroup,groupAsyncEvents);} groupAsyncEvents.push(asyncEvent);}},_processEvent:function(event) {var eventStack=this._eventStack;while(eventStack.length&&eventStack.peekLast().endTime<=event.startTime) eventStack.pop();var recordTypes=WebInspector.TimelineModel.RecordType;if(this._currentScriptEvent&&event.startTime>this._currentScriptEvent.endTime) this._currentScriptEvent=null;var eventData=event.args["data"]||event.args["beginData"]||{};if(eventData&&eventData["stackTrace"]) event.stackTrace=eventData["stackTrace"];if(eventStack.length&&eventStack.peekLast().name===recordTypes.EventDispatch) eventStack.peekLast().hasChildren=true;this._asyncEventTracker.processEvent(event);if(event.initiator&&event.initiator.url) event.url=event.initiator.url;switch(event.name){case recordTypes.ResourceSendRequest:case recordTypes.WebSocketCreate:event.url=event.args["data"]["url"];event.initiator=eventStack.peekLast()||null;break;case recordTypes.ScheduleStyleRecalculation:this._lastScheduleStyleRecalculation[event.args["data"]["frame"]]=event;break;case recordTypes.UpdateLayoutTree:case recordTypes.RecalculateStyles:this._invalidationTracker.didRecalcStyle(event);if(event.args["beginData"]) event.initiator=this._lastScheduleStyleRecalculation[event.args["beginData"]["frame"]];this._lastRecalculateStylesEvent=event;if(this._currentScriptEvent) event.warning=WebInspector.TimelineModel.WarningType.ForcedStyle;break;case recordTypes.ScheduleStyleInvalidationTracking:case recordTypes.StyleRecalcInvalidationTracking:case recordTypes.StyleInvalidatorInvalidationTracking:case recordTypes.LayoutInvalidationTracking:case recordTypes.LayerInvalidationTracking:case recordTypes.PaintInvalidationTracking:case recordTypes.ScrollInvalidationTracking:this._invalidationTracker.addInvalidation(new WebInspector.InvalidationTrackingEvent(event));break;case recordTypes.InvalidateLayout:var layoutInitator=event;var frameId=event.args["data"]["frame"];if(!this._layoutInvalidate[frameId]&&this._lastRecalculateStylesEvent&&this._lastRecalculateStylesEvent.endTime>event.startTime) layoutInitator=this._lastRecalculateStylesEvent.initiator;this._layoutInvalidate[frameId]=layoutInitator;break;case recordTypes.Layout:this._invalidationTracker.didLayout(event);var frameId=event.args["beginData"]["frame"];event.initiator=this._layoutInvalidate[frameId];if(event.args["endData"]){event.backendNodeId=event.args["endData"]["rootNode"];event.highlightQuad=event.args["endData"]["root"];} this._layoutInvalidate[frameId]=null;if(this._currentScriptEvent) event.warning=WebInspector.TimelineModel.WarningType.ForcedLayout;break;case recordTypes.EvaluateScript:case recordTypes.FunctionCall:if(!this._currentScriptEvent) this._currentScriptEvent=event;break;case recordTypes.SetLayerTreeId:this._inspectedTargetLayerTreeId=event.args["layerTreeId"]||event.args["data"]["layerTreeId"];break;case recordTypes.Paint:this._invalidationTracker.didPaint(event);event.highlightQuad=event.args["data"]["clip"];event.backendNodeId=event.args["data"]["nodeId"];if(!event.args["data"]["layerId"]) break;var layerId=event.args["data"]["layerId"];this._lastPaintForLayer[layerId]=event;break;case recordTypes.DisplayItemListSnapshot:case recordTypes.PictureSnapshot:var layerUpdateEvent=this._findAncestorEvent(recordTypes.UpdateLayer);if(!layerUpdateEvent||layerUpdateEvent.args["layerTreeId"]!==this._inspectedTargetLayerTreeId) break;var paintEvent=this._lastPaintForLayer[layerUpdateEvent.args["layerId"]];if(paintEvent) paintEvent.picture=event;break;case recordTypes.ScrollLayer:event.backendNodeId=event.args["data"]["nodeId"];break;case recordTypes.PaintImage:event.backendNodeId=event.args["data"]["nodeId"];event.url=event.args["data"]["url"];break;case recordTypes.DecodeImage:case recordTypes.ResizeImage:var paintImageEvent=this._findAncestorEvent(recordTypes.PaintImage);if(!paintImageEvent){var decodeLazyPixelRefEvent=this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);paintImageEvent=decodeLazyPixelRefEvent&&this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];} if(!paintImageEvent) break;event.backendNodeId=paintImageEvent.backendNodeId;event.url=paintImageEvent.url;break;case recordTypes.DrawLazyPixelRef:var paintImageEvent=this._findAncestorEvent(recordTypes.PaintImage);if(!paintImageEvent) break;this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]]=paintImageEvent;event.backendNodeId=paintImageEvent.backendNodeId;event.url=paintImageEvent.url;break;case recordTypes.MarkDOMContent:case recordTypes.MarkLoad:var page=eventData["page"];if(page&&page!==this._currentPage) return false;break;case recordTypes.CommitLoad:var page=eventData["page"];if(page&&page!==this._currentPage) return false;if(!eventData["isMainFrame"]) break;this._hadCommitLoad=true;this._firstCompositeLayers=null;break;case recordTypes.CompositeLayers:if(!this._firstCompositeLayers&&this._hadCommitLoad) this._firstCompositeLayers=event;break;case recordTypes.FireIdleCallback:if(event.duration>eventData["allottedMilliseconds"]){event.warning=WebInspector.TimelineModel.WarningType.IdleDeadlineExceeded;} break;} if(WebInspector.TracingModel.isAsyncPhase(event.phase)) return true;var duration=event.duration;if(!duration) return true;if(eventStack.length){var parent=eventStack.peekLast();parent.selfTime-=duration;if(parent.selfTime<0){var epsilon=1e-3;if(parent.selfTime<-epsilon) console.error("Children are longer than parent at "+event.startTime+" ("+(event.startTime-this.minimumRecordTime()).toFixed(3)+") by "+parent.selfTime.toFixed(3));parent.selfTime=0;}} event.selfTime=duration;eventStack.push(event);return true;},_processBrowserEvent:function(event) {if(event.name!==WebInspector.TimelineModel.RecordType.LatencyInfoFlow) return;var frameId=event.args["frameTreeNodeId"];if(typeof frameId==="number"&&frameId===this._mainFrameNodeId) this._knownInputEvents.add(event.bind_id);},_processAsyncEvent:function(asyncEvent) {var groups=WebInspector.TimelineUIUtils.asyncEventGroups();if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.Console)) return groups.console;if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return groups.userTiming;if(asyncEvent.name===WebInspector.TimelineModel.RecordType.Animation) return groups.animation;if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)||asyncEvent.name===WebInspector.TimelineModel.RecordType.ImplSideFling){var lastStep=asyncEvent.steps.peekLast();if(lastStep.phase!==WebInspector.TracingModel.Phase.AsyncEnd) return null;var data=lastStep.args["data"];asyncEvent.causedFrame=!!(data&&data["INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT"]);if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)){if(!this._knownInputEvents.has(lastStep.id)) return null;if(asyncEvent.name===WebInspector.TimelineModel.RecordType.InputLatencyMouseMove&&!asyncEvent.causedFrame) return null;var rendererMain=data["INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT"];if(rendererMain){var time=rendererMain["time"]/1000;asyncEvent.steps[0].timeWaitingForMainThread=time-asyncEvent.steps[0].startTime;}} return groups.input;} return null;},_findAncestorEvent:function(name) {for(var i=this._eventStack.length-1;i>=0;--i){var event=this._eventStack[i];if(event.name===name) return event;} return null;},_mergeAsyncEvents:function(target,source) {for(var group of source.keys()){var events=target.get(group)||[];events=events.mergeOrdered(source.get(group)||[],WebInspector.TracingModel.Event.compareStartAndEndTime);target.set(group,events);}},reset:function() {this._virtualThreads=[];this._mainThreadEvents=[];this._mainThreadAsyncEventsByGroup=new Map();this._inspectedTargetEvents=[];this._records=[];this._mainThreadTasks=[];this._gpuEvents=[];this._eventDividerRecords=[];this._sessionId=null;this._mainFrameNodeId=null;this._cpuProfiles=[];this._minimumRecordTime=0;this._maximumRecordTime=0;},minimumRecordTime:function() {return this._minimumRecordTime;},maximumRecordTime:function() {return this._maximumRecordTime;},inspectedTargetEvents:function() {return this._inspectedTargetEvents;},mainThreadEvents:function() {return this._mainThreadEvents;},_setMainThreadEvents:function(events) {this._mainThreadEvents=events;},mainThreadAsyncEvents:function() {return this._mainThreadAsyncEventsByGroup;},virtualThreads:function() {return this._virtualThreads;},isEmpty:function() {return this.minimumRecordTime()===0&&this.maximumRecordTime()===0;},mainThreadTasks:function() {return this._mainThreadTasks;},gpuEvents:function() {return this._gpuEvents;},eventDividerRecords:function() {return this._eventDividerRecords;},networkRequests:function() {var requests=new Map();var requestsList=[];var zeroStartRequestsList=[];var types=WebInspector.TimelineModel.RecordType;var resourceTypes=new Set([types.ResourceSendRequest,types.ResourceReceiveResponse,types.ResourceReceivedData,types.ResourceFinish]);var events=this.mainThreadEvents();for(var i=0;i<events.length;++i){var e=events[i];if(!resourceTypes.has(e.name)) continue;var id=e.args["data"]["requestId"];var request=requests.get(id);if(request){request.addEvent(e);}else{request=new WebInspector.TimelineModel.NetworkRequest(e);requests.set(id,request);if(request.startTime) requestsList.push(request);else zeroStartRequestsList.push(request);}} return zeroStartRequestsList.concat(requestsList);},} WebInspector.TimelineModel.isVisible=function(filters,event) {for(var i=0;i<filters.length;++i){if(!filters[i].accept(event)) return false;} return true;} WebInspector.TimelineModel.NetworkRequest=function(event) {this.startTime=event.name===WebInspector.TimelineModel.RecordType.ResourceSendRequest?event.startTime:0;this.endTime=Infinity;this.children=[];this.addEvent(event);} WebInspector.TimelineModel.NetworkRequest.prototype={addEvent:function(event) {this.children.push(event);var recordType=WebInspector.TimelineModel.RecordType;this.startTime=Math.min(this.startTime,event.startTime);var eventData=event.args["data"];if(eventData["mimeType"]) this.mimeType=eventData["mimeType"];if("priority"in eventData) this.priority=eventData["priority"];if(event.name===recordType.ResourceFinish) this.endTime=event.startTime;if(!this.responseTime&&(event.name===recordType.ResourceReceiveResponse||event.name===recordType.ResourceReceivedData)) this.responseTime=event.startTime;if(!this.url) this.url=eventData["url"];if(!this.requestMethod) this.requestMethod=eventData["requestMethod"];}} WebInspector.TimelineModel.Filter=function() {} WebInspector.TimelineModel.Filter.prototype={accept:function(event) {return true;}} WebInspector.TimelineVisibleEventsFilter=function(visibleTypes) {WebInspector.TimelineModel.Filter.call(this);this._visibleTypes=new Set(visibleTypes);} WebInspector.TimelineVisibleEventsFilter.prototype={accept:function(event) {return this._visibleTypes.has(WebInspector.TimelineModel._eventType(event));},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.ExclusiveNameFilter=function(excludeNames) {WebInspector.TimelineModel.Filter.call(this);this._excludeNames=new Set(excludeNames);} WebInspector.ExclusiveNameFilter.prototype={accept:function(event) {return!this._excludeNames.has(event.name);},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.ExcludeTopLevelFilter=function() {WebInspector.TimelineModel.Filter.call(this);} WebInspector.ExcludeTopLevelFilter.prototype={accept:function(event) {return!WebInspector.TracingModel.isTopLevelEvent(event);},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.InvalidationTrackingEvent=function(event) {this.type=event.name;this.startTime=event.startTime;this._tracingEvent=event;var eventData=event.args["data"];this.frame=eventData["frame"];this.nodeId=eventData["nodeId"];this.nodeName=eventData["nodeName"];this.paintId=eventData["paintId"];this.invalidationSet=eventData["invalidationSet"];this.invalidatedSelectorId=eventData["invalidatedSelectorId"];this.changedId=eventData["changedId"];this.changedClass=eventData["changedClass"];this.changedAttribute=eventData["changedAttribute"];this.changedPseudo=eventData["changedPseudo"];this.selectorPart=eventData["selectorPart"];this.extraData=eventData["extraData"];this.invalidationList=eventData["invalidationList"];this.cause={reason:eventData["reason"],stackTrace:eventData["stackTrace"]};if(!this.cause.reason&&this.cause.stackTrace&&this.type===WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking) this.cause.reason="Layout forced";} WebInspector.InvalidationCause;WebInspector.InvalidationTracker=function() {this._initializePerFrameState();} WebInspector.InvalidationTracker.prototype={addInvalidation:function(invalidation) {this._startNewFrameIfNeeded();if(!invalidation.nodeId&&!invalidation.paintId){console.error("Invalidation lacks node information.");console.error(invalidation);return;} var recordTypes=WebInspector.TimelineModel.RecordType;if(invalidation.type===recordTypes.PaintInvalidationTracking&&invalidation.nodeId){var invalidations=this._invalidationsByNodeId[invalidation.nodeId]||[];for(var i=0;i<invalidations.length;++i) invalidations[i].paintId=invalidation.paintId;return;} if(invalidation.type===recordTypes.StyleRecalcInvalidationTracking&&invalidation.cause.reason==="StyleInvalidator") return;var styleRecalcInvalidation=(invalidation.type===recordTypes.ScheduleStyleInvalidationTracking||invalidation.type===recordTypes.StyleInvalidatorInvalidationTracking||invalidation.type===recordTypes.StyleRecalcInvalidationTracking);if(styleRecalcInvalidation){var duringRecalcStyle=invalidation.startTime&&this._lastRecalcStyle&&invalidation.startTime>=this._lastRecalcStyle.startTime&&invalidation.startTime<=this._lastRecalcStyle.endTime;if(duringRecalcStyle) this._associateWithLastRecalcStyleEvent(invalidation);} if(this._invalidations[invalidation.type]) this._invalidations[invalidation.type].push(invalidation);else this._invalidations[invalidation.type]=[invalidation];if(invalidation.nodeId){if(this._invalidationsByNodeId[invalidation.nodeId]) this._invalidationsByNodeId[invalidation.nodeId].push(invalidation);else this._invalidationsByNodeId[invalidation.nodeId]=[invalidation];}},didRecalcStyle:function(recalcStyleEvent) {this._lastRecalcStyle=recalcStyleEvent;var types=[WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,WebInspector.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking];for(var invalidation of this._invalidationsOfTypes(types)) this._associateWithLastRecalcStyleEvent(invalidation);},_associateWithLastRecalcStyleEvent:function(invalidation) {if(invalidation.linkedRecalcStyleEvent) return;var recordTypes=WebInspector.TimelineModel.RecordType;var recalcStyleFrameId=this._lastRecalcStyle.args["beginData"]["frame"];if(invalidation.type===recordTypes.StyleInvalidatorInvalidationTracking){this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle,recalcStyleFrameId,invalidation);}else if(invalidation.type===recordTypes.ScheduleStyleInvalidationTracking){}else{this._addInvalidationToEvent(this._lastRecalcStyle,recalcStyleFrameId,invalidation);} invalidation.linkedRecalcStyleEvent=true;},_addSyntheticStyleRecalcInvalidations:function(event,frameId,styleInvalidatorInvalidation) {if(!styleInvalidatorInvalidation.invalidationList){this._addSyntheticStyleRecalcInvalidation(styleInvalidatorInvalidation._tracingEvent,styleInvalidatorInvalidation);return;} if(!styleInvalidatorInvalidation.nodeId){console.error("Invalidation lacks node information.");console.error(invalidation);return;} for(var i=0;i<styleInvalidatorInvalidation.invalidationList.length;i++){var setId=styleInvalidatorInvalidation.invalidationList[i]["id"];var lastScheduleStyleRecalculation;var nodeInvalidations=this._invalidationsByNodeId[styleInvalidatorInvalidation.nodeId]||[];for(var j=0;j<nodeInvalidations.length;j++){var invalidation=nodeInvalidations[j];if(invalidation.frame!==frameId||invalidation.invalidationSet!==setId||invalidation.type!==WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking) continue;lastScheduleStyleRecalculation=invalidation;} if(!lastScheduleStyleRecalculation){console.error("Failed to lookup the event that scheduled a style invalidator invalidation.");continue;} this._addSyntheticStyleRecalcInvalidation(lastScheduleStyleRecalculation._tracingEvent,styleInvalidatorInvalidation);}},_addSyntheticStyleRecalcInvalidation:function(baseEvent,styleInvalidatorInvalidation) {var invalidation=new WebInspector.InvalidationTrackingEvent(baseEvent);invalidation.type=WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking;invalidation.synthetic=true;if(styleInvalidatorInvalidation.cause.reason) invalidation.cause.reason=styleInvalidatorInvalidation.cause.reason;if(styleInvalidatorInvalidation.selectorPart) invalidation.selectorPart=styleInvalidatorInvalidation.selectorPart;this.addInvalidation(invalidation);if(!invalidation.linkedRecalcStyleEvent) this._associateWithLastRecalcStyleEvent(invalidation);},didLayout:function(layoutEvent) {var layoutFrameId=layoutEvent.args["beginData"]["frame"];for(var invalidation of this._invalidationsOfTypes([WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking])){if(invalidation.linkedLayoutEvent) continue;this._addInvalidationToEvent(layoutEvent,layoutFrameId,invalidation);invalidation.linkedLayoutEvent=true;}},didPaint:function(paintEvent) {this._didPaint=true;var layerId=paintEvent.args["data"]["layerId"];if(layerId) this._lastPaintWithLayer=paintEvent;if(!this._lastPaintWithLayer){console.error("Failed to find a paint container for a paint event.");return;} var effectivePaintId=this._lastPaintWithLayer.args["data"]["nodeId"];var paintFrameId=paintEvent.args["data"]["frame"];var types=[WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking,WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking,WebInspector.TimelineModel.RecordType.PaintInvalidationTracking,WebInspector.TimelineModel.RecordType.ScrollInvalidationTracking];for(var invalidation of this._invalidationsOfTypes(types)){if(invalidation.paintId===effectivePaintId) this._addInvalidationToEvent(paintEvent,paintFrameId,invalidation);}},_addInvalidationToEvent:function(event,eventFrameId,invalidation) {if(eventFrameId!==invalidation.frame) return;if(!event.invalidationTrackingEvents) event.invalidationTrackingEvents=[invalidation];else event.invalidationTrackingEvents.push(invalidation);},_invalidationsOfTypes:function(types) {var invalidations=this._invalidations;if(!types) types=Object.keys(invalidations);function*generator() {for(var i=0;i<types.length;++i){var invalidationList=invalidations[types[i]]||[];for(var j=0;j<invalidationList.length;++j) yield invalidationList[j];}} return generator();},_startNewFrameIfNeeded:function() {if(!this._didPaint) return;this._initializePerFrameState();},_initializePerFrameState:function() {this._invalidations={};this._invalidationsByNodeId={};this._lastRecalcStyle=undefined;this._lastPaintWithLayer=undefined;this._didPaint=false;}} WebInspector.TimelineAsyncEventTracker=function() {WebInspector.TimelineAsyncEventTracker._initialize();this._initiatorByType=new Map();for(var initiator of WebInspector.TimelineAsyncEventTracker._asyncEvents.keys()) this._initiatorByType.set(initiator,new Map());} WebInspector.TimelineAsyncEventTracker._initialize=function() {if(WebInspector.TimelineAsyncEventTracker._asyncEvents) return;var events=new Map();var type=WebInspector.TimelineModel.RecordType;events.set(type.TimerInstall,{causes:[type.TimerFire],joinBy:"timerId"});events.set(type.ResourceSendRequest,{causes:[type.ResourceReceiveResponse,type.ResourceReceivedData,type.ResourceFinish],joinBy:"requestId"});events.set(type.RequestAnimationFrame,{causes:[type.FireAnimationFrame],joinBy:"id"});events.set(type.RequestIdleCallback,{causes:[type.FireIdleCallback],joinBy:"id"});events.set(type.WebSocketCreate,{causes:[type.WebSocketSendHandshakeRequest,type.WebSocketReceiveHandshakeResponse,type.WebSocketDestroy],joinBy:"identifier"});WebInspector.TimelineAsyncEventTracker._asyncEvents=events;WebInspector.TimelineAsyncEventTracker._typeToInitiator=new Map();for(var entry of events){var types=entry[1].causes;for(type of types) WebInspector.TimelineAsyncEventTracker._typeToInitiator.set(type,entry[0]);}} WebInspector.TimelineAsyncEventTracker.prototype={processEvent:function(event) {var initiatorType=WebInspector.TimelineAsyncEventTracker._typeToInitiator.get((event.name));var isInitiator=!initiatorType;if(!initiatorType) initiatorType=(event.name);var initiatorInfo=WebInspector.TimelineAsyncEventTracker._asyncEvents.get(initiatorType);if(!initiatorInfo) return;var id=event.args["data"][initiatorInfo.joinBy];if(!id) return;var initiatorMap=this._initiatorByType.get(initiatorType);if(isInitiator) initiatorMap.set(id,event);else event.initiator=initiatorMap.get(id)||null;}};WebInspector.TimelineIRModel=function() {this.reset();} WebInspector.TimelineIRModel.Phases={Idle:"Idle",Response:"Response",Scroll:"Scroll",Fling:"Fling",Drag:"Drag",Animation:"Animation",Uncategorized:"Uncategorized"};WebInspector.TimelineIRModel.InputEvents={Char:"Char",Click:"GestureClick",ContextMenu:"ContextMenu",FlingCancel:"GestureFlingCancel",FlingStart:"GestureFlingStart",ImplSideFling:WebInspector.TimelineModel.RecordType.ImplSideFling,KeyDown:"KeyDown",KeyDownRaw:"RawKeyDown",KeyUp:"KeyUp",LatencyScrollUpdate:"ScrollUpdate",MouseDown:"MouseDown",MouseMove:"MouseMove",MouseUp:"MouseUp",MouseWheel:"MouseWheel",PinchBegin:"GesturePinchBegin",PinchEnd:"GesturePinchEnd",PinchUpdate:"GesturePinchUpdate",ScrollBegin:"GestureScrollBegin",ScrollEnd:"GestureScrollEnd",ScrollUpdate:"GestureScrollUpdate",ScrollUpdateRenderer:"ScrollUpdate",ShowPress:"GestureShowPress",Tap:"GestureTap",TapCancel:"GestureTapCancel",TapDown:"GestureTapDown",TouchCancel:"TouchCancel",TouchEnd:"TouchEnd",TouchMove:"TouchMove",TouchStart:"TouchStart"};WebInspector.TimelineIRModel._mergeThresholdsMs={animation:1,mouse:40,};WebInspector.TimelineIRModel._eventIRPhase=Symbol("eventIRPhase");WebInspector.TimelineIRModel.phaseForEvent=function(event) {return event[WebInspector.TimelineIRModel._eventIRPhase];} WebInspector.TimelineIRModel.prototype={populate:function(timelineModel) {var eventTypes=WebInspector.TimelineIRModel.InputEvents;var phases=WebInspector.TimelineIRModel.Phases;this.reset();var groups=WebInspector.TimelineUIUtils.asyncEventGroups();var asyncEventsByGroup=timelineModel.mainThreadAsyncEvents();var inputLatencies=asyncEventsByGroup.get(groups.input);if(!inputLatencies) return;this._processInputLatencies(inputLatencies);var animations=asyncEventsByGroup.get(groups.animation);if(animations) this._processAnimations(animations);var range=new WebInspector.SegmentedRange();range.appendRange(this._drags);range.appendRange(this._cssAnimations);range.appendRange(this._scrolls);range.appendRange(this._responses);this._segments=range.segments();},_processInputLatencies:function(events) {var eventTypes=WebInspector.TimelineIRModel.InputEvents;var phases=WebInspector.TimelineIRModel.Phases;var thresholdsMs=WebInspector.TimelineIRModel._mergeThresholdsMs;var scrollStart;var flingStart;var touchStart;var firstTouchMove;var mouseWheel;var mouseDown;var mouseMove;for(var i=0;i<events.length;++i){var event=events[i];if(i>0&&events[i].startTime<events[i-1].startTime) console.assert(false,"Unordered input events");var type=this._inputEventType(event.name);switch(type){case eventTypes.ScrollBegin:this._scrolls.append(this._segmentForEvent(event,phases.Scroll));scrollStart=event;break;case eventTypes.ScrollEnd:if(scrollStart) this._scrolls.append(this._segmentForEventRange(scrollStart,event,phases.Scroll));else this._scrolls.append(this._segmentForEvent(event,phases.Scroll));scrollStart=null;break;case eventTypes.ScrollUpdate:touchStart=null;this._scrolls.append(this._segmentForEvent(event,phases.Scroll));break;case eventTypes.FlingStart:if(flingStart){WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s",flingStart.startTime,event.startTime));break;} flingStart=event;break;case eventTypes.FlingCancel:if(!flingStart) break;this._scrolls.append(this._segmentForEventRange(flingStart,event,phases.Fling));flingStart=null;break;case eventTypes.ImplSideFling:this._scrolls.append(this._segmentForEvent(event,phases.Fling));break;case eventTypes.ShowPress:case eventTypes.Tap:case eventTypes.KeyDown:case eventTypes.KeyDownRaw:case eventTypes.KeyUp:case eventTypes.Char:case eventTypes.Click:case eventTypes.ContextMenu:this._responses.append(this._segmentForEvent(event,phases.Response));break;case eventTypes.TouchStart:if(touchStart){WebInspector.console.error(WebInspector.UIString("Two touches at the same time? %s vs %s",touchStart.startTime,event.startTime));break;} touchStart=event;event.steps[0][WebInspector.TimelineIRModel._eventIRPhase]=phases.Response;firstTouchMove=null;break;case eventTypes.TouchCancel:touchStart=null;break;case eventTypes.TouchMove:if(firstTouchMove){this._drags.append(this._segmentForEvent(event,phases.Drag));}else if(touchStart){firstTouchMove=event;this._responses.append(this._segmentForEventRange(touchStart,event,phases.Response));} break;case eventTypes.TouchEnd:touchStart=null;break;case eventTypes.MouseDown:mouseDown=event;mouseMove=null;break;case eventTypes.MouseMove:if(mouseDown&&!mouseMove&&mouseDown.startTime+thresholdsMs.mouse>event.startTime){this._responses.append(this._segmentForEvent(mouseDown,phases.Response));this._responses.append(this._segmentForEvent(event,phases.Response));}else if(mouseDown){this._drags.append(this._segmentForEvent(event,phases.Drag));} mouseMove=event;break;case eventTypes.MouseUp:this._responses.append(this._segmentForEvent(event,phases.Response));mouseDown=null;break;case eventTypes.MouseWheel:if(mouseWheel&&canMerge(thresholdsMs.mouse,mouseWheel,event)) this._scrolls.append(this._segmentForEventRange(mouseWheel,event,phases.Scroll));else this._scrolls.append(this._segmentForEvent(event,phases.Scroll));mouseWheel=event;break;}} function canMerge(threshold,first,second) {return first.endTime<second.startTime&&second.startTime<first.endTime+threshold;}},_processAnimations:function(events) {for(var i=0;i<events.length;++i) this._cssAnimations.append(this._segmentForEvent(events[i],WebInspector.TimelineIRModel.Phases.Animation));},_segmentForEvent:function(event,phase) {this._setPhaseForEvent(event,phase);return new WebInspector.Segment(event.startTime,event.endTime,phase);},_segmentForEventRange:function(startEvent,endEvent,phase) {this._setPhaseForEvent(startEvent,phase);this._setPhaseForEvent(endEvent,phase);return new WebInspector.Segment(startEvent.startTime,endEvent.endTime,phase);},_setPhaseForEvent:function(asyncEvent,phase) {asyncEvent.steps[0][WebInspector.TimelineIRModel._eventIRPhase]=phase;},interactionRecords:function() {return this._segments;},reset:function() {var thresholdsMs=WebInspector.TimelineIRModel._mergeThresholdsMs;this._segments=[];this._drags=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.mouse));this._cssAnimations=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.animation));this._responses=new WebInspector.SegmentedRange(merge.bind(null,0));this._scrolls=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.animation));function merge(threshold,first,second) {return first.end+threshold>=second.begin&&first.data===second.data?first:null;}},_inputEventType:function(eventName) {var prefix="InputLatency::";if(!eventName.startsWith(prefix)){if(eventName===WebInspector.TimelineIRModel.InputEvents.ImplSideFling) return(eventName);console.error("Unrecognized input latency event: "+eventName);return null;} return(eventName.substr(prefix.length));}};;WebInspector.TimelineJSProfileProcessor={};WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile=function(jsProfileModel,thread) {var idleNode=jsProfileModel.idleNode;var programNode=jsProfileModel.programNode;var gcNode=jsProfileModel.gcNode;var samples=jsProfileModel.samples;var timestamps=jsProfileModel.timestamps;var jsEvents=[];var nodeToStackMap=new Map();nodeToStackMap.set(programNode,[]);for(var i=0;i<samples.length;++i){var node=jsProfileModel.nodeByIndex(i);if(!node){console.error(`Node with unknown id ${samples[i]}at index ${i}`);continue;} if(node===gcNode||node===idleNode) continue;var callFrames=nodeToStackMap.get(node);if(!callFrames){callFrames=(new Array(node.depth+1));nodeToStackMap.set(node,callFrames);for(var j=0;node.parent;node=node.parent) callFrames[j++]=(node);} var jsSampleEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,WebInspector.TimelineModel.RecordType.JSSample,WebInspector.TracingModel.Phase.Instant,timestamps[i],thread);jsSampleEvent.args["data"]={stackTrace:callFrames};jsEvents.push(jsSampleEvent);} return jsEvents;} WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents=function(events) {function equalFrames(frame1,frame2) {return frame1.scriptId===frame2.scriptId&&frame1.functionName===frame2.functionName;} function eventEndTime(e) {return e.endTime||e.startTime;} function isJSInvocationEvent(e) {switch(e.name){case WebInspector.TimelineModel.RecordType.FunctionCall:case WebInspector.TimelineModel.RecordType.EvaluateScript:return true;} return false;} var jsFrameEvents=[];var jsFramesStack=[];var lockedJsStackDepth=[];var ordinal=0;var filterNativeFunctions=!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();function onStartEvent(e) {e.ordinal=++ordinal;extractStackTrace(e);lockedJsStackDepth.push(jsFramesStack.length);} function onInstantEvent(e,parent) {e.ordinal=++ordinal;if(parent&&isJSInvocationEvent(parent)) extractStackTrace(e);} function onEndEvent(e) {truncateJSStack(lockedJsStackDepth.pop(),e.endTime);} function truncateJSStack(depth,time) {if(lockedJsStackDepth.length){var lockedDepth=lockedJsStackDepth.peekLast();if(depth<lockedDepth){console.error("Child stack is shallower ("+depth+") than the parent stack ("+lockedDepth+") at "+time);depth=lockedDepth;}} if(jsFramesStack.length<depth){console.error("Trying to truncate higher than the current stack size at "+time);depth=jsFramesStack.length;} for(var k=0;k<jsFramesStack.length;++k) jsFramesStack[k].setEndTime(time);jsFramesStack.length=depth;} function filterStackFrames(stack) {for(var i=0,j=0;i<stack.length;++i){var url=stack[i].url;if(url&&url.startsWith("native ")) continue;stack[j++]=stack[i];} stack.length=j;} function extractStackTrace(e) {var recordTypes=WebInspector.TimelineModel.RecordType;var callFrames;if(e.name===recordTypes.JSSample){var eventData=e.args["data"]||e.args["beginData"];callFrames=(eventData&&eventData["stackTrace"]);}else{callFrames=(jsFramesStack.map(frameEvent=>frameEvent.args["data"]).reverse());} if(filterNativeFunctions) filterStackFrames(callFrames);var endTime=eventEndTime(e);var numFrames=callFrames.length;var minFrames=Math.min(numFrames,jsFramesStack.length);var i;for(i=lockedJsStackDepth.peekLast()||0;i<minFrames;++i){var newFrame=callFrames[numFrames-1-i];var oldFrame=jsFramesStack[i].args["data"];if(!equalFrames(newFrame,oldFrame)) break;jsFramesStack[i].setEndTime(Math.max(jsFramesStack[i].endTime,endTime));} truncateJSStack(i,e.startTime);for(;i<numFrames;++i){var frame=callFrames[numFrames-1-i];var jsFrameEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,recordTypes.JSFrame,WebInspector.TracingModel.Phase.Complete,e.startTime,e.thread);jsFrameEvent.ordinal=e.ordinal;jsFrameEvent.addArgs({data:frame});jsFrameEvent.setEndTime(endTime);jsFramesStack.push(jsFrameEvent);jsFrameEvents.push(jsFrameEvent);}} function findFirstTopLevelEvent(events) {for(var i=0;i<events.length;++i){if(WebInspector.TracingModel.isTopLevelEvent(events[i])) return events[i];} return null;} var firstTopLevelEvent=findFirstTopLevelEvent(events);if(firstTopLevelEvent) WebInspector.TimelineModel.forEachEvent(events,onStartEvent,onEndEvent,onInstantEvent,firstTopLevelEvent.startTime);return jsFrameEvents;} WebInspector.TimelineJSProfileProcessor.CodeMap=function() {this._banks=new Map();} WebInspector.TimelineJSProfileProcessor.CodeMap.Entry=function(address,size,callFrame) {this.address=address;this.size=size;this.callFrame=callFrame;} WebInspector.TimelineJSProfileProcessor.CodeMap.comparator=function(address,entry) {return address-entry.address;} WebInspector.TimelineJSProfileProcessor.CodeMap.prototype={addEntry:function(addressHex,size,callFrame) {var entry=new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry(this._getAddress(addressHex),size,callFrame);this._addEntry(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size) {var entry=this._getBank(oldAddressHex).removeEntry(this._getAddress(oldAddressHex));if(!entry){console.error("Entry at address "+oldAddressHex+" not found");return;} entry.address=this._getAddress(newAddressHex);entry.size=size;this._addEntry(newAddressHex,entry);},lookupEntry:function(addressHex) {return this._getBank(addressHex).lookupEntry(this._getAddress(addressHex));},_addEntry:function(addressHex,entry) {this._getBank(addressHex).addEntry(entry);},_getBank:function(addressHex) {addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this._banks.get(bankName);if(!bank){bank=new WebInspector.TimelineJSProfileProcessor.CodeMap.Bank();this._banks.set(bankName,bank);} return bank;},_getAddress:function(addressHex) {var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);}} WebInspector.TimelineJSProfileProcessor.CodeMap.Bank=function() {this._entries=[];} WebInspector.TimelineJSProfileProcessor.CodeMap.Bank.prototype={removeEntry:function(address) {var index=this._entries.lowerBound(address,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);var entry=this._entries[index];if(!entry||entry.address!==address) return null;this._entries.splice(index,1);return entry;},lookupEntry:function(address) {var index=this._entries.upperBound(address,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator)-1;var entry=this._entries[index];return entry&&address<entry.address+entry.size?entry.callFrame:null;},addEntry:function(newEntry) {var endAddress=newEntry.address+newEntry.size;var lastIndex=this._entries.lowerBound(endAddress,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);var index;for(index=lastIndex-1;index>=0;--index){var entry=this._entries[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address) break;} ++index;this._entries.splice(index,lastIndex-index,newEntry);}} WebInspector.TimelineJSProfileProcessor._buildCallFrame=function(name,scriptId) {function createFrame(functionName,url,scriptId,line,column,isNative) {return({"functionName":functionName,"url":url||"","scriptId":scriptId||"0","lineNumber":line||0,"columnNumber":column||0,"isNative":isNative||false});} var rePrefix=/^(\w*:)?[*~]?(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var body=tokens[2];var rawName;var rawUrl;if(prefix==="Script:"){rawName="";rawUrl=body;}else{var spacePos=body.lastIndexOf(" ");rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):"";} var nativeSuffix=" native";var isNative=rawName.endsWith(nativeSuffix);var functionName=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=WebInspector.ParsedURL.splitLineAndColumn(rawUrl);var url=urlData.url||"";var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;return createFrame(functionName,url,String(scriptId),line,column,isNative);} WebInspector.TimelineJSProfileProcessor.processRawV8Samples=function(events) {var missingAddesses=new Set();function convertRawFrame(address) {var entry=codeMap.lookupEntry(address);if(entry) return entry.isNative?null:entry;if(!missingAddesses.has(address)){missingAddesses.add(address);console.error("Address "+address+" has missing code entry");} return null;} var recordTypes=WebInspector.TimelineModel.RecordType;var samples=[];var codeMap=new WebInspector.TimelineJSProfileProcessor.CodeMap();for(var i=0;i<events.length;++i){var e=events[i];var data=e.args["data"];switch(e.name){case recordTypes.JitCodeAdded:var frame=WebInspector.TimelineJSProfileProcessor._buildCallFrame(data["name"],data["script_id"]);codeMap.addEntry(data["code_start"],data["code_len"],frame);break;case recordTypes.JitCodeMoved:codeMap.moveEntry(data["code_start"],data["new_code_start"],data["code_len"]);break;case recordTypes.V8Sample:var rawStack=data["stack"];if(data["vm_state"]==="js"&&!rawStack.length) break;var stack=rawStack.map(convertRawFrame);stack.remove(null);var sampleEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,WebInspector.TimelineModel.RecordType.JSSample,WebInspector.TracingModel.Phase.Instant,e.startTime,e.thread);sampleEvent.ordinal=e.ordinal;sampleEvent.args={"data":{"stackTrace":stack}};samples.push(sampleEvent);break;}} return samples;};WebInspector.TimelineLoader=function(model,delegate) {this._model=model;this._delegate=delegate;this._canceledCallback=null;this._state=WebInspector.TimelineLoader.State.Initial;this._buffer="";this._firstChunk=true;this._loadedBytes=0;this._totalSize;this._jsonTokenizer=new WebInspector.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this),true);} WebInspector.TimelineLoader.loadFromFile=function(model,file,delegate) {var loader=new WebInspector.TimelineLoader(model,delegate);var fileReader=WebInspector.TimelineLoader._createFileReader(file,loader);loader._canceledCallback=fileReader.cancel.bind(fileReader);loader._totalSize=file.size;fileReader.start(loader);return loader;} WebInspector.TimelineLoader.loadFromURL=function(model,url,delegate) {var stream=new WebInspector.TimelineLoader(model,delegate);WebInspector.ResourceLoader.loadAsStream(url,null,stream);return stream;} WebInspector.TimelineLoader.TransferChunkLengthBytes=5000000;WebInspector.TimelineLoader._createFileReader=function(file,delegate) {return new WebInspector.ChunkedFileReader(file,WebInspector.TimelineLoader.TransferChunkLengthBytes,delegate);} WebInspector.TimelineLoader.State={Initial:"Initial",LookingForEvents:"LookingForEvents",ReadingEvents:"ReadingEvents"} WebInspector.TimelineLoader.prototype={cancel:function() {this._model.reset();this._delegate.loadingComplete(false);this._delegate=null;if(this._canceledCallback) this._canceledCallback();},write:function(chunk) {if(!this._delegate) return;this._loadedBytes+=chunk.length;if(!this._firstChunk) this._delegate.loadingProgress(this._totalSize?this._loadedBytes/this._totalSize:undefined);if(this._state===WebInspector.TimelineLoader.State.Initial){if(chunk[0]==="{") this._state=WebInspector.TimelineLoader.State.LookingForEvents;else if(chunk[0]==="[") this._state=WebInspector.TimelineLoader.State.ReadingEvents;else{this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: Unknown JSON format"));return;}} if(this._state===WebInspector.TimelineLoader.State.LookingForEvents){var objectName="\"traceEvents\":";var startPos=this._buffer.length-objectName.length;this._buffer+=chunk;var pos=this._buffer.indexOf(objectName,startPos);if(pos===-1) return;chunk=this._buffer.slice(pos+objectName.length) this._state=WebInspector.TimelineLoader.State.ReadingEvents;} this._jsonTokenizer.write(chunk);},_writeBalancedJSON:function(data) {var json=data+"]";if(this._firstChunk){this._delegate.loadingStarted();}else{var commaIndex=json.indexOf(",");if(commaIndex!==-1) json=json.slice(commaIndex+1);json="["+json;} var items;try{items=(JSON.parse(json));}catch(e){this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s",e.toString()));return;} if(this._firstChunk){this._firstChunk=false;this._model.reset();if(this._looksLikeAppVersion(items[0])){this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy Timeline format is not supported."));return;}} try{this._model.addEvents(items);}catch(e){this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s",e.toString()));return;}},_reportErrorAndCancelLoading:function(message) {if(message) WebInspector.console.error(message);this.cancel();},_looksLikeAppVersion:function(item) {return typeof item==="string"&&item.indexOf("Chrome")!==-1;},close:function() {this._model.tracingComplete();if(this._delegate) this._delegate.loadingComplete(true);},onTransferStarted:function(){},onChunkTransferred:function(reader){},onTransferFinished:function(){},onError:function(reader,event) {switch(event.target.error.code){case FileError.NOT_FOUND_ERR:this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" not found.",reader.fileName()));break;case FileError.NOT_READABLE_ERR:this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" is not readable",reader.fileName()));break;case FileError.ABORT_ERR:break;default:this._reportErrorAndCancelLoading(WebInspector.UIString("An error occurred while reading the file \"%s\"",reader.fileName()));}}} WebInspector.TracingTimelineSaver=function() {} WebInspector.TracingTimelineSaver.prototype={onTransferStarted:function(){},onTransferFinished:function(){},onChunkTransferred:function(reader){},onError:function(reader,event) {var error=event.target.error;WebInspector.console.error(WebInspector.UIString("Failed to save timeline: %s (%s, %s)",error.message,error.name,error.code));}};WebInspector.TimelineFrameModel=function() {this.reset();} WebInspector.TimelineFrameModel._mainFrameMarkers=[WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation,WebInspector.TimelineModel.RecordType.InvalidateLayout,WebInspector.TimelineModel.RecordType.BeginMainThreadFrame,WebInspector.TimelineModel.RecordType.ScrollLayer];WebInspector.TimelineFrameModel.prototype={frames:function() {return this._frames;},filteredFrames:function(startTime,endTime) {function compareStartTime(value,object) {return value-object.startTime;} function compareEndTime(value,object) {return value-object.endTime;} var frames=this._frames;var firstFrame=frames.lowerBound(startTime,compareEndTime);var lastFrame=frames.lowerBound(endTime,compareStartTime);return frames.slice(firstFrame,lastFrame);},hasRasterTile:function(rasterTask) {var data=rasterTask.args["tileData"];if(!data) return false;var frameId=data["sourceFrameNumber"];var frame=frameId&&this._frameById[frameId];if(!frame||!frame.layerTree) return false;return true;},requestRasterTile:function(rasterTask,callback) {var target=this._target;if(!target){callback(null,null);return;} var data=rasterTask.args["tileData"];var frameId=data["sourceFrameNumber"];var frame=frameId&&this._frameById[frameId];if(!frame||!frame.layerTree){callback(null,null);return;} var tileId=data["tileId"]&&data["tileId"]["id_ref"];var fragments=[];var tile=null;var x0=Infinity;var y0=Infinity;frame.layerTree.resolve(layerTreeResolved);function layerTreeResolved(layerTree) {tile=tileId&&((layerTree)).tileById("cc::Tile/"+tileId);if(!tile){console.error("Tile "+tileId+" missing in frame "+frameId);callback(null,null);return;} var fetchPictureFragmentsBarrier=new CallbackBarrier();for(var paint of frame.paints){if(tile.layer_id===paint.layerId()) paint.loadPicture(fetchPictureFragmentsBarrier.createCallback(pictureLoaded));} fetchPictureFragmentsBarrier.callWhenDone(allPicturesLoaded);} function segmentsOverlap(a1,a2,b1,b2) {console.assert(a1<=a2&&b1<=b2,"segments should be specified as ordered pairs");return a2>b1&&a1<b2;} function rectsOverlap(a,b) {return segmentsOverlap(a[0],a[0]+a[2],b[0],b[0]+b[2])&&segmentsOverlap(a[1],a[1]+a[3],b[1],b[1]+b[3]);} function pictureLoaded(rect,picture) {if(!rect||!picture) return;if(!rectsOverlap(rect,tile.content_rect)) return;var x=rect[0];var y=rect[1];x0=Math.min(x0,x);y0=Math.min(y0,y);fragments.push({x:x,y:y,picture:picture});} function allPicturesLoaded() {if(!fragments.length){callback(null,null);return;} var rectArray=tile.content_rect;var rect={x:rectArray[0]-x0,y:rectArray[1]-y0,width:rectArray[2],height:rectArray[3]};WebInspector.PaintProfilerSnapshot.loadFromFragments(target,fragments,callback.bind(null,rect));}},reset:function() {this._minimumRecordTime=Infinity;this._frames=[];this._frameById={};this._lastFrame=null;this._lastLayerTree=null;this._mainFrameCommitted=false;this._mainFrameRequested=false;this._framePendingCommit=null;this._lastBeginFrame=null;this._lastNeedsBeginFrame=null;this._framePendingActivation=null;this._lastTaskBeginTime=null;this._target=null;this._sessionId=null;this._currentTaskTimeByCategory={};},handleBeginFrame:function(startTime) {if(!this._lastFrame) this._startFrame(startTime);this._lastBeginFrame=startTime;},handleDrawFrame:function(startTime) {if(!this._lastFrame){this._startFrame(startTime);return;} if(this._mainFrameCommitted||!this._mainFrameRequested){if(this._lastNeedsBeginFrame){var idleTimeEnd=this._framePendingActivation?this._framePendingActivation.triggerTime:(this._lastBeginFrame||this._lastNeedsBeginFrame);if(idleTimeEnd>this._lastFrame.startTime){this._lastFrame.idle=true;this._startFrame(idleTimeEnd);if(this._framePendingActivation) this._commitPendingFrame();this._lastBeginFrame=null;} this._lastNeedsBeginFrame=null;} this._startFrame(startTime);} this._mainFrameCommitted=false;},handleActivateLayerTree:function() {if(!this._lastFrame) return;if(this._framePendingActivation&&!this._lastNeedsBeginFrame) this._commitPendingFrame();},handleRequestMainThreadFrame:function() {if(!this._lastFrame) return;this._mainFrameRequested=true;},handleCompositeLayers:function() {if(!this._framePendingCommit) return;this._framePendingActivation=this._framePendingCommit;this._framePendingCommit=null;this._mainFrameRequested=false;this._mainFrameCommitted=true;},handleLayerTreeSnapshot:function(layerTree) {this._lastLayerTree=layerTree;},handleNeedFrameChanged:function(startTime,needsBeginFrame) {if(needsBeginFrame) this._lastNeedsBeginFrame=startTime;},_startFrame:function(startTime) {if(this._lastFrame) this._flushFrame(this._lastFrame,startTime);this._lastFrame=new WebInspector.TimelineFrame(startTime,startTime-this._minimumRecordTime);},_flushFrame:function(frame,endTime) {frame._setLayerTree(this._lastLayerTree);frame._setEndTime(endTime);if(this._frames.length&&(frame.startTime!==this._frames.peekLast().endTime||frame.startTime>frame.endTime)) console.assert(false,`Inconsistent frame time for frame ${this._frames.length}(${frame.startTime}-${frame.endTime})`);this._frames.push(frame);if(typeof frame._mainFrameId==="number") this._frameById[frame._mainFrameId]=frame;},_commitPendingFrame:function() {this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCategory);this._lastFrame.paints=this._framePendingActivation.paints;this._lastFrame._mainFrameId=this._framePendingActivation.mainFrameId;this._framePendingActivation=null;},_findRecordRecursively:function(types,record) {if(types.indexOf(record.type())>=0) return record;if(!record.children()) return null;for(var i=0;i<record.children().length;++i){var result=this._findRecordRecursively(types,record.children()[i]);if(result) return result;} return null;},addTraceEvents:function(target,events,sessionId) {this._target=target;this._sessionId=sessionId;if(!events.length) return;if(events[0].startTime<this._minimumRecordTime) this._minimumRecordTime=events[0].startTime;for(var i=0;i<events.length;++i) this._addTraceEvent(events[i]);},_addTraceEvent:function(event) {var eventNames=WebInspector.TimelineModel.RecordType;if(event.name===eventNames.SetLayerTreeId){var sessionId=event.args["sessionId"]||event.args["data"]["sessionId"];if(this._sessionId===sessionId) this._layerTreeId=event.args["layerTreeId"]||event.args["data"]["layerTreeId"];}else if(event.name===eventNames.TracingStartedInPage){this._mainThread=event.thread;}else if(event.phase===WebInspector.TracingModel.Phase.SnapshotObject&&event.name===eventNames.LayerTreeHostImplSnapshot&&parseInt(event.id,0)===this._layerTreeId){var snapshot=(event);this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(snapshot,this._target));}else{this._processCompositorEvents(event);if(event.thread===this._mainThread) this._addMainThreadTraceEvent(event);else if(this._lastFrame&&event.selfTime&&!WebInspector.TracingModel.isTopLevelEvent(event)) this._lastFrame._addTimeForCategory(WebInspector.TimelineUIUtils.eventStyle(event).category.name,event.selfTime);}},_processCompositorEvents:function(event) {var eventNames=WebInspector.TimelineModel.RecordType;if(event.args["layerTreeId"]!==this._layerTreeId) return;var timestamp=event.startTime;if(event.name===eventNames.BeginFrame) this.handleBeginFrame(timestamp);else if(event.name===eventNames.DrawFrame) this.handleDrawFrame(timestamp);else if(event.name===eventNames.ActivateLayerTree) this.handleActivateLayerTree();else if(event.name===eventNames.RequestMainThreadFrame) this.handleRequestMainThreadFrame();else if(event.name===eventNames.NeedsBeginFrameChanged) this.handleNeedFrameChanged(timestamp,event.args["data"]&&event.args["data"]["needsBeginFrame"]);},_addMainThreadTraceEvent:function(event) {var eventNames=WebInspector.TimelineModel.RecordType;var timestamp=event.startTime;var selfTime=event.selfTime||0;if(WebInspector.TracingModel.isTopLevelEvent(event)){this._currentTaskTimeByCategory={};this._lastTaskBeginTime=event.startTime;} if(!this._framePendingCommit&&WebInspector.TimelineFrameModel._mainFrameMarkers.indexOf(event.name)>=0) this._framePendingCommit=new WebInspector.PendingFrame(this._lastTaskBeginTime||event.startTime,this._currentTaskTimeByCategory);if(!this._framePendingCommit){this._addTimeForCategory(this._currentTaskTimeByCategory,event);return;} this._addTimeForCategory(this._framePendingCommit.timeByCategory,event);if(event.name===eventNames.BeginMainThreadFrame&&event.args["data"]&&event.args["data"]["frameId"]) this._framePendingCommit.mainFrameId=event.args["data"]["frameId"];if(event.name===eventNames.Paint&&event.args["data"]["layerId"]&&event.picture&&this._target) this._framePendingCommit.paints.push(new WebInspector.LayerPaintEvent(event,this._target));if(event.name===eventNames.CompositeLayers&&event.args["layerTreeId"]===this._layerTreeId) this.handleCompositeLayers();},_addTimeForCategory:function(timeByCategory,event) {if(!event.selfTime) return;var categoryName=WebInspector.TimelineUIUtils.eventStyle(event).category.name;timeByCategory[categoryName]=(timeByCategory[categoryName]||0)+event.selfTime;},} WebInspector.DeferredTracingLayerTree=function(snapshot,target) {WebInspector.DeferredLayerTree.call(this,target);this._snapshot=snapshot;} WebInspector.DeferredTracingLayerTree.prototype={resolve:function(callback) {this._snapshot.requestObject(onGotObject.bind(this));function onGotObject(result) {if(!result) return;var viewport=result["device_viewport_size"];var tiles=result["active_tiles"];var rootLayer=result["active_tree"]["root_layer"];var layerTree=new WebInspector.TracingLayerTree(this._target);layerTree.setViewportSize(viewport);layerTree.setTiles(tiles);layerTree.setLayers(rootLayer,callback.bind(null,layerTree));}},__proto__:WebInspector.DeferredLayerTree.prototype};WebInspector.TimelineFrame=function(startTime,startTimeOffset) {this.startTime=startTime;this.startTimeOffset=startTimeOffset;this.endTime=this.startTime;this.duration=0;this.timeByCategory={};this.cpuTime=0;this.idle=false;this.layerTree=null;this.paints=[];this._mainFrameId=undefined;} WebInspector.TimelineFrame.prototype={hasWarnings:function() {var longFrameDurationThresholdMs=22;return!this.idle&&this.duration>longFrameDurationThresholdMs;},_setEndTime:function(endTime) {this.endTime=endTime;this.duration=this.endTime-this.startTime;},_setLayerTree:function(layerTree) {this.layerTree=layerTree;},_addTimeForCategories:function(timeByCategory) {for(var category in timeByCategory) this._addTimeForCategory(category,timeByCategory[category]);},_addTimeForCategory:function(category,time) {this.timeByCategory[category]=(this.timeByCategory[category]||0)+time;this.cpuTime+=time;},} WebInspector.LayerPaintEvent=function(event,target) {this._event=event;this._target=target;} WebInspector.LayerPaintEvent.prototype={layerId:function() {return this._event.args["data"]["layerId"];},event:function() {return this._event;},loadPicture:function(callback) {this._event.picture.requestObject(onGotObject);function onGotObject(result) {if(!result||!result["skp64"]){callback(null,null);return;} var rect=result["params"]&&result["params"]["layer_rect"];callback(rect,result["skp64"]);}},loadSnapshot:function(callback) {this.loadPicture(onGotPicture.bind(this));function onGotPicture(rect,picture) {if(!rect||!picture||!this._target){callback(null,null);return;} WebInspector.PaintProfilerSnapshot.load(this._target,picture,callback.bind(null,rect));}}};WebInspector.PendingFrame=function(triggerTime,timeByCategory) {this.timeByCategory=timeByCategory;this.paints=[];this.mainFrameId=undefined;this.triggerTime=triggerTime;};WebInspector.TimelineEventOverview=function(id,title,model) {WebInspector.TimelineOverviewBase.call(this);this.element.id="timeline-overview-"+id;this.element.classList.add("overview-strip");if(title) this.element.createChild("div","timeline-overview-strip-title").textContent=title;this._model=model;} WebInspector.TimelineEventOverview.prototype={_renderBar:function(begin,end,position,height,color) {var x=begin;var width=end-begin;this._context.fillStyle=color;this._context.fillRect(x,position,width,height);},windowTimes:function(windowLeft,windowRight) {var absoluteMin=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-absoluteMin;return{startTime:absoluteMin+timeSpan*windowLeft,endTime:absoluteMin+timeSpan*windowRight};},windowBoundaries:function(startTime,endTime) {var absoluteMin=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-absoluteMin;var haveRecords=absoluteMin>0;return{left:haveRecords&&startTime?Math.min((startTime-absoluteMin)/timeSpan,1):0,right:haveRecords&&endTime<Infinity?(endTime-absoluteMin)/timeSpan:1};},__proto__:WebInspector.TimelineOverviewBase.prototype} WebInspector.TimelineEventOverview.Input=function(model) {WebInspector.TimelineEventOverview.call(this,"input",null,model);} WebInspector.TimelineEventOverview.Input.prototype={update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var events=this._model.mainThreadEvents();var height=this._canvas.height;var descriptors=WebInspector.TimelineUIUtils.eventDispatchDesciptors();var descriptorsByType=new Map();var maxPriority=-1;for(var descriptor of descriptors){for(var type of descriptor.eventTypes) descriptorsByType.set(type,descriptor);maxPriority=Math.max(maxPriority,descriptor.priority);} var minWidth=2*window.devicePixelRatio;var timeOffset=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-timeOffset;var canvasWidth=this._canvas.width;var scale=canvasWidth/timeSpan;for(var priority=0;priority<=maxPriority;++priority){for(var i=0;i<events.length;++i){var event=events[i];if(event.name!==WebInspector.TimelineModel.RecordType.EventDispatch) continue;var descriptor=descriptorsByType.get(event.args["data"]["type"]);if(!descriptor||descriptor.priority!==priority) continue;var start=Number.constrain(Math.floor((event.startTime-timeOffset)*scale),0,canvasWidth);var end=Number.constrain(Math.ceil((event.endTime-timeOffset)*scale),0,canvasWidth);var width=Math.max(end-start,minWidth);this._renderBar(start,start+width,0,height,descriptor.color);}}},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineEventOverview.Network=function(model) {WebInspector.TimelineEventOverview.call(this,"network",WebInspector.UIString("NET"),model);} WebInspector.TimelineEventOverview.Network.prototype={update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var height=this._canvas.height;var numBands=categoryBand(WebInspector.TimelineUIUtils.NetworkCategory.Other)+1;var bandHeight=Math.floor(height/numBands);var devicePixelRatio=window.devicePixelRatio;var timeOffset=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-timeOffset;var canvasWidth=this._canvas.width;var scale=canvasWidth/timeSpan;var ctx=this._context;var requests=this._model.networkRequests();var paths=new Map();requests.forEach(drawRequest);for(var path of paths){ctx.fillStyle=path[0];ctx.globalAlpha=0.3;ctx.fill(path[1]["waiting"]);ctx.globalAlpha=1;ctx.fill(path[1]["transfer"]);} function categoryBand(category) {var categories=WebInspector.TimelineUIUtils.NetworkCategory;switch(category){case categories.HTML:return 0;case categories.Script:return 1;case categories.Style:return 2;case categories.Media:return 3;default:return 4;}} function drawRequest(request) {var tickWidth=2*devicePixelRatio;var category=WebInspector.TimelineUIUtils.networkRequestCategory(request);var style=WebInspector.TimelineUIUtils.networkCategoryColor(category);var band=categoryBand(category);var y=band*bandHeight;var path=paths.get(style);if(!path){path={waiting:new Path2D(),transfer:new Path2D()};paths.set(style,path);} var s=Math.max(Math.floor((request.startTime-timeOffset)*scale),0);var e=Math.min(Math.ceil((request.endTime-timeOffset)*scale),canvasWidth);path["waiting"].rect(s,y,e-s,bandHeight-1);path["transfer"].rect(e-tickWidth/2,y,tickWidth,bandHeight-1);if(!request.responseTime) return;var r=Math.ceil((request.responseTime-timeOffset)*scale);path["transfer"].rect(r-tickWidth/2,y,tickWidth,bandHeight-1);}},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineEventOverview.CPUActivity=function(model) {WebInspector.TimelineEventOverview.call(this,"cpu-activity",WebInspector.UIString("CPU"),model);this._backgroundCanvas=this.element.createChild("canvas","fill background");} WebInspector.TimelineEventOverview.CPUActivity.prototype={resetCanvas:function() {WebInspector.TimelineEventOverview.prototype.resetCanvas.call(this);this._backgroundCanvas.width=this.element.clientWidth*window.devicePixelRatio;this._backgroundCanvas.height=this.element.clientHeight*window.devicePixelRatio;},update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var quantSizePx=4*window.devicePixelRatio;var width=this._canvas.width;var height=this._canvas.height;var baseLine=height;var timeOffset=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-timeOffset;var scale=width/timeSpan;var quantTime=quantSizePx/scale;var categories=WebInspector.TimelineUIUtils.categories();var categoryOrder=["idle","loading","painting","rendering","scripting","other"];var otherIndex=categoryOrder.indexOf("other");var idleIndex=0;console.assert(idleIndex===categoryOrder.indexOf("idle"));for(var i=idleIndex+1;i<categoryOrder.length;++i) categories[categoryOrder[i]]._overviewIndex=i;var backgroundContext=this._backgroundCanvas.getContext("2d");for(var thread of this._model.virtualThreads()) drawThreadEvents(backgroundContext,thread.events);applyPattern(backgroundContext);drawThreadEvents(this._context,this._model.mainThreadEvents());function drawThreadEvents(ctx,events) {var quantizer=new WebInspector.Quantizer(timeOffset,quantTime,drawSample);var x=0;var categoryIndexStack=[];var paths=[];var lastY=[];for(var i=0;i<categoryOrder.length;++i){paths[i]=new Path2D();paths[i].moveTo(0,height);lastY[i]=height;} function drawSample(counters) {var y=baseLine;for(var i=idleIndex+1;i<categoryOrder.length;++i){var h=(counters[i]||0)/quantTime*height;y-=h;paths[i].bezierCurveTo(x,lastY[i],x,y,x+quantSizePx/2,y);lastY[i]=y;} x+=quantSizePx;} function onEventStart(e) {var index=categoryIndexStack.length?categoryIndexStack.peekLast():idleIndex;quantizer.appendInterval(e.startTime,index);categoryIndexStack.push(WebInspector.TimelineUIUtils.eventStyle(e).category._overviewIndex||otherIndex);} function onEventEnd(e) {quantizer.appendInterval(e.endTime,categoryIndexStack.pop());} WebInspector.TimelineModel.forEachEvent(events,onEventStart,onEventEnd);quantizer.appendInterval(timeOffset+timeSpan+quantTime,idleIndex);for(var i=categoryOrder.length-1;i>0;--i){paths[i].lineTo(width,height);ctx.fillStyle=categories[categoryOrder[i]].color;ctx.fill(paths[i]);}} function applyPattern(ctx) {var step=4*window.devicePixelRatio;ctx.save();ctx.lineWidth=step/Math.sqrt(8);for(var x=0.5;x<width+height;x+=step){ctx.moveTo(x,0);ctx.lineTo(x-height,height);} ctx.globalCompositeOperation="destination-out";ctx.stroke();ctx.restore();}},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineEventOverview.Responsiveness=function(model,frameModel) {WebInspector.TimelineEventOverview.call(this,"responsiveness",null,model) this._frameModel=frameModel;} WebInspector.TimelineEventOverview.Responsiveness.prototype={update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var height=this._canvas.height;var timeOffset=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-timeOffset;var scale=this._canvas.width/timeSpan;var frames=this._frameModel.frames();var ctx=this._context;var fillPath=new Path2D();var markersPath=new Path2D();for(var i=0;i<frames.length;++i){var frame=frames[i];if(!frame.hasWarnings()) continue;paintWarningDecoration(frame.startTime,frame.duration);} var events=this._model.mainThreadEvents();for(var i=0;i<events.length;++i){if(!events[i].warning) continue;paintWarningDecoration(events[i].startTime,events[i].duration);} ctx.fillStyle="hsl(0, 80%, 90%)";ctx.strokeStyle="red";ctx.lineWidth=2*window.devicePixelRatio;ctx.fill(fillPath);ctx.stroke(markersPath);function paintWarningDecoration(time,duration) {var x=Math.round(scale*(time-timeOffset));var w=Math.round(scale*duration);fillPath.rect(x,0,w,height);markersPath.moveTo(x+w,0);markersPath.lineTo(x+w,height);}},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineFilmStripOverview=function(model,tracingModel) {WebInspector.TimelineEventOverview.call(this,"filmstrip",null,model);this._tracingModel=tracingModel;this.reset();} WebInspector.TimelineFilmStripOverview.Padding=2;WebInspector.TimelineFilmStripOverview.prototype={update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);if(!this._filmStripModel) return;var frames=this._filmStripModel.frames();if(!frames.length) return;var drawGeneration=Symbol("drawGeneration");this._drawGeneration=drawGeneration;this._imageByFrame(frames[0]).then(image=>{if(this._drawGeneration!==drawGeneration) return;if(!image.naturalWidth||!image.naturalHeight) return;var imageHeight=this._canvas.height-2*WebInspector.TimelineFilmStripOverview.Padding;var imageWidth=Math.ceil(imageHeight*image.naturalWidth/image.naturalHeight);var popoverScale=Math.min(200/image.naturalWidth,1);this._emptyImage=new Image(image.naturalWidth*popoverScale,image.naturalHeight*popoverScale);this._drawFrames(imageWidth,imageHeight);});},_imageByFrame:function(frame) {var imagePromise=this._frameToImagePromise.get(frame);if(!imagePromise){imagePromise=frame.imageDataPromise().then(createImage);this._frameToImagePromise.set(frame,imagePromise);} return imagePromise;function createImage(data) {var image=(createElement("img"));if(data) image.src="data:image/jpg;base64,"+data;return image.completePromise();}},_drawFrames:function(imageWidth,imageHeight) {if(!this._filmStripModel||!imageWidth) return;if(!this._filmStripModel.frames().length) return;var padding=WebInspector.TimelineFilmStripOverview.Padding;var width=this._canvas.width;var zeroTime=this._tracingModel.minimumRecordTime();var spanTime=this._tracingModel.maximumRecordTime()-zeroTime;var scale=spanTime/width;var context=this._canvas.getContext("2d");var drawGeneration=this._drawGeneration;context.beginPath();for(var x=padding;x<width;x+=imageWidth+2*padding){var time=zeroTime+(x+imageWidth/2)*scale;var frame=this._filmStripModel.frameByTimestamp(time);if(!frame) continue;context.rect(x-0.5,0.5,imageWidth+1,imageHeight+1);this._imageByFrame(frame).then(drawFrameImage.bind(this,x));} context.strokeStyle="#ddd";context.stroke();function drawFrameImage(x,image) {if(this._drawGeneration!==drawGeneration) return;context.drawImage(image,x,1,imageWidth,imageHeight);}},popoverElementPromise:function(x) {if(!this._filmStripModel||!this._filmStripModel.frames().length) return Promise.resolve((null));var time=this._calculator.positionToTime(x);var frame=this._filmStripModel.frameByTimestamp(time);if(frame===this._lastFrame) return Promise.resolve(this._lastElement);var imagePromise=frame?this._imageByFrame(frame):Promise.resolve(this._emptyImage);return imagePromise.then(createFrameElement.bind(this));function createFrameElement(image) {var element=createElementWithClass("div","frame");element.createChild("div","thumbnail").appendChild(image);WebInspector.appendStyle(element,"timeline/timelinePanel.css");this._lastFrame=frame;this._lastElement=element;return element;}},reset:function() {this._lastFrame=undefined;this._lastElement=null;this._filmStripModel=new WebInspector.FilmStripModel(this._tracingModel);this._frameToImagePromise=new Map();this._imageWidth=0;},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineEventOverview.Frames=function(model,frameModel) {WebInspector.TimelineEventOverview.call(this,"framerate",WebInspector.UIString("FPS"),model);this._frameModel=frameModel;} WebInspector.TimelineEventOverview.Frames.prototype={update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var height=this._canvas.height;var padding=1*window.devicePixelRatio;var baseFrameDurationMs=1e3/60;var visualHeight=height-2*padding;var timeOffset=this._model.minimumRecordTime();var timeSpan=this._model.maximumRecordTime()-timeOffset;var scale=this._canvas.width/timeSpan;var frames=this._frameModel.frames();var baseY=height-padding;var ctx=this._context;var bottomY=baseY+10*window.devicePixelRatio;var y=bottomY;if(!frames.length) return;var lineWidth=window.devicePixelRatio;var offset=lineWidth&1?0.5:0;var tickDepth=1.5*window.devicePixelRatio;ctx.beginPath();ctx.moveTo(0,y);for(var i=0;i<frames.length;++i){var frame=frames[i];var x=Math.round((frame.startTime-timeOffset)*scale)+offset;ctx.lineTo(x,y);ctx.lineTo(x,y+tickDepth);y=frame.idle?bottomY:Math.round(baseY-visualHeight*Math.min(baseFrameDurationMs/frame.duration,1))-offset;ctx.lineTo(x,y+tickDepth);ctx.lineTo(x,y);} if(frames.length){var lastFrame=frames.peekLast();var x=Math.round((lastFrame.startTime+lastFrame.duration-timeOffset)*scale)+offset;ctx.lineTo(x,y);} ctx.lineTo(x,bottomY);ctx.fillStyle="hsl(110, 50%, 88%)";ctx.strokeStyle="hsl(110, 50%, 60%)";ctx.lineWidth=lineWidth;ctx.fill();ctx.stroke();},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.TimelineEventOverview.Memory=function(model) {WebInspector.TimelineEventOverview.call(this,"memory",WebInspector.UIString("HEAP"),model);this._heapSizeLabel=this.element.createChild("div","memory-graph-label");} WebInspector.TimelineEventOverview.Memory.prototype={resetHeapSizeLabels:function() {this._heapSizeLabel.textContent="";},update:function() {WebInspector.TimelineEventOverview.prototype.update.call(this);var ratio=window.devicePixelRatio;var events=this._model.mainThreadEvents();if(!events.length){this.resetHeapSizeLabels();return;} var lowerOffset=3*ratio;var maxUsedHeapSize=0;var minUsedHeapSize=100000000000;var minTime=this._model.minimumRecordTime();var maxTime=this._model.maximumRecordTime();function isUpdateCountersEvent(event) {return event.name===WebInspector.TimelineModel.RecordType.UpdateCounters;} events=events.filter(isUpdateCountersEvent);function calculateMinMaxSizes(event) {var counters=event.args.data;if(!counters||!counters.jsHeapSizeUsed) return;maxUsedHeapSize=Math.max(maxUsedHeapSize,counters.jsHeapSizeUsed);minUsedHeapSize=Math.min(minUsedHeapSize,counters.jsHeapSizeUsed);} events.forEach(calculateMinMaxSizes);minUsedHeapSize=Math.min(minUsedHeapSize,maxUsedHeapSize);var lineWidth=1;var width=this._canvas.width;var height=this._canvas.height-lowerOffset;var xFactor=width/(maxTime-minTime);var yFactor=(height-lineWidth)/Math.max(maxUsedHeapSize-minUsedHeapSize,1);var histogram=new Array(width);function buildHistogram(event) {var counters=event.args.data;if(!counters||!counters.jsHeapSizeUsed) return;var x=Math.round((event.startTime-minTime)*xFactor);var y=Math.round((counters.jsHeapSizeUsed-minUsedHeapSize)*yFactor);histogram[x]=Math.max(histogram[x]||0,y);} events.forEach(buildHistogram);var ctx=this._context;var heightBeyondView=height+lowerOffset+lineWidth;ctx.translate(0.5,0.5);ctx.beginPath();ctx.moveTo(-lineWidth,heightBeyondView);var y=0;var isFirstPoint=true;var lastX=0;for(var x=0;x<histogram.length;x++){if(typeof histogram[x]==="undefined") continue;if(isFirstPoint){isFirstPoint=false;y=histogram[x];ctx.lineTo(-lineWidth,height-y);} var nextY=histogram[x];if(Math.abs(nextY-y)>2&&Math.abs(x-lastX)>1) ctx.lineTo(x,height-y);y=nextY;ctx.lineTo(x,height-y);lastX=x;} ctx.lineTo(width+lineWidth,height-y);ctx.lineTo(width+lineWidth,heightBeyondView);ctx.closePath();ctx.fillStyle="hsla(220, 90%, 70%, 0.2)";ctx.fill();ctx.lineWidth=lineWidth;ctx.strokeStyle="hsl(220, 90%, 70%)";ctx.stroke();this._heapSizeLabel.textContent=WebInspector.UIString("%s \u2013 %s",Number.bytesToString(minUsedHeapSize),Number.bytesToString(maxUsedHeapSize));},__proto__:WebInspector.TimelineEventOverview.prototype} WebInspector.Quantizer=function(startTime,quantDuration,callback) {this._lastTime=startTime;this._quantDuration=quantDuration;this._callback=callback;this._counters=[];this._remainder=quantDuration;} WebInspector.Quantizer.prototype={appendInterval:function(time,group) {var interval=time-this._lastTime;if(interval<=this._remainder){this._counters[group]=(this._counters[group]||0)+interval;this._remainder-=interval;this._lastTime=time;return;} this._counters[group]=(this._counters[group]||0)+this._remainder;this._callback(this._counters);interval-=this._remainder;while(interval>=this._quantDuration){var counters=[];counters[group]=this._quantDuration;this._callback(counters);interval-=this._quantDuration;} this._counters=[];this._counters[group]=interval;this._lastTime=time;this._remainder=this._quantDuration-interval;}};WebInspector.TimelineFlameChartDataProviderBase=function(model,filters) {WebInspector.FlameChartDataProvider.call(this);this.reset();this._model=model;this._timelineData;this._font="11px "+WebInspector.fontFamily();this._filters=filters;} WebInspector.TimelineFlameChartDataProviderBase.prototype={barHeight:function() {return 17;},textBaseline:function() {return 5;},textPadding:function() {return 4;},entryFont:function(entryIndex) {return this._font;},entryTitle:function(entryIndex) {return null;},reset:function() {this._timelineData=null;},minimumBoundary:function() {return this._minimumBoundary;},totalTime:function() {return this._timeSpan;},formatValue:function(value,precision) {return Number.preciseMillisToString(value,precision);},maxStackDepth:function() {return this._currentLevel;},prepareHighlightedEntryInfo:function(entryIndex) {return null;},canJumpToEntry:function(entryIndex) {return false;},entryColor:function(entryIndex) {return"red";},forceDecoration:function(index) {return false;},decorateEntry:function(entryIndex,context,text,barX,barY,barWidth,barHeight,unclippedBarX,timeToPixels) {return false;},dividerOffsets:function(startTime,endTime) {return null;},paddingLeft:function() {return 0;},textColor:function(entryIndex) {return"#333";},highlightTimeRange:function(entryIndex) {var startTime=this._timelineData.entryStartTimes[entryIndex];return{startTime:startTime,endTime:startTime+this._timelineData.entryTotalTimes[entryIndex]};},createSelection:function(entryIndex) {return null;},timelineData:function() {throw new Error("Not implemented");},_isVisible:function(event) {return this._filters.every(function(filter){return filter.accept(event);});}} WebInspector.TimelineFlameChartEntryType={Frame:Symbol("Frame"),Event:Symbol("Event"),InteractionRecord:Symbol("InteractionRecord"),};WebInspector.TimelineFlameChartDataProvider=function(model,frameModel,irModel,filters) {WebInspector.TimelineFlameChartDataProviderBase.call(this,model,filters);this._frameModel=frameModel;this._irModel=irModel;this._consoleColorGenerator=new WebInspector.FlameChart.ColorGenerator({min:30,max:55},{min:70,max:100,count:6},50,0.7);this._headerLevel1={padding:4,height:17,collapsible:true,color:WebInspector.themeSupport.patchColor("#222",WebInspector.ThemeSupport.ColorUsage.Foreground),font:this._font,backgroundColor:WebInspector.themeSupport.patchColor("white",WebInspector.ThemeSupport.ColorUsage.Background),nestingLevel:0};this._headerLevel2={padding:2,height:17,collapsible:false,font:this._font,color:WebInspector.themeSupport.patchColor("#222",WebInspector.ThemeSupport.ColorUsage.Foreground),backgroundColor:WebInspector.themeSupport.patchColor("white",WebInspector.ThemeSupport.ColorUsage.Background),nestingLevel:1,shareHeaderLine:true};this._interactionsHeaderLevel1={padding:4,height:17,collapsible:true,color:WebInspector.themeSupport.patchColor("#222",WebInspector.ThemeSupport.ColorUsage.Foreground),font:this._font,backgroundColor:WebInspector.themeSupport.patchColor("white",WebInspector.ThemeSupport.ColorUsage.Background),nestingLevel:0,useFirstLineForOverview:true,shareHeaderLine:true};this._interactionsHeaderLevel2={padding:2,height:17,collapsible:true,color:WebInspector.themeSupport.patchColor("#222",WebInspector.ThemeSupport.ColorUsage.Foreground),font:this._font,backgroundColor:WebInspector.themeSupport.patchColor("white",WebInspector.ThemeSupport.ColorUsage.Background),nestingLevel:1,shareHeaderLine:true};} WebInspector.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs=0.001;WebInspector.TimelineFlameChartDataProvider.prototype={entryTitle:function(entryIndex) {var entryType=this._entryType(entryIndex);if(entryType===WebInspector.TimelineFlameChartEntryType.Event){var event=(this._entryData[entryIndex]);if(event.phase===WebInspector.TracingModel.Phase.AsyncStepInto||event.phase===WebInspector.TracingModel.Phase.AsyncStepPast) return event.name+":"+event.args["step"];if(event._blackboxRoot) return WebInspector.UIString("Blackboxed");var name=WebInspector.TimelineUIUtils.eventStyle(event).title;var detailsText=WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent(event,this._model.target());if(event.name===WebInspector.TimelineModel.RecordType.JSFrame&&detailsText) return detailsText;return detailsText?WebInspector.UIString("%s (%s)",name,detailsText):name;} var title=this._entryIndexToTitle[entryIndex];if(!title){title=WebInspector.UIString("Unexpected entryIndex %d",entryIndex);console.error(title);} return title;},textColor:function(index) {var event=this._entryData[index];if(event&&event._blackboxRoot) return"#888";else return WebInspector.TimelineFlameChartDataProviderBase.prototype.textColor.call(this,index);},reset:function() {WebInspector.TimelineFlameChartDataProviderBase.prototype.reset.call(this);this._entryData=[];this._entryTypeByLevel=[];this._entryIndexToTitle=[];this._markers=[];this._asyncColorByCategory=new Map();this._asyncColorByInteractionPhase=new Map();},timelineData:function() {if(this._timelineData) return this._timelineData;this._timelineData=new WebInspector.FlameChart.TimelineData([],[],[],[]);this._flowEventIndexById={};this._minimumBoundary=this._model.minimumRecordTime();this._timeSpan=this._model.isEmpty()?1000:this._model.maximumRecordTime()-this._minimumBoundary;this._currentLevel=0;this._appendFrameBars(this._frameModel.frames());this._appendHeader(WebInspector.UIString("Interactions"),this._interactionsHeaderLevel1);this._appendInteractionRecords();var asyncEventGroups=WebInspector.TimelineUIUtils.asyncEventGroups();var inputLatencies=this._model.mainThreadAsyncEvents().get(asyncEventGroups.input);if(inputLatencies&&inputLatencies.length) this._appendAsyncEventsGroup(asyncEventGroups.input.title,inputLatencies,this._interactionsHeaderLevel2);var animations=this._model.mainThreadAsyncEvents().get(asyncEventGroups.animation);if(animations&&animations.length) this._appendAsyncEventsGroup(asyncEventGroups.animation.title,animations,this._interactionsHeaderLevel2);var threads=this._model.virtualThreads();this._appendThreadTimelineData(WebInspector.UIString("Main"),this._model.mainThreadEvents(),this._model.mainThreadAsyncEvents(),true);var compositorThreads=threads.filter(thread=>thread.name.startsWith("CompositorTileWorker"));var otherThreads=threads.filter(thread=>!thread.name.startsWith("CompositorTileWorker"));if(compositorThreads.length){this._appendHeader(WebInspector.UIString("Raster"),this._headerLevel1);for(var i=0;i<compositorThreads.length;++i) this._appendSyncEvents(compositorThreads[i].events,WebInspector.UIString("Rasterizer Thread %d",i),this._headerLevel2);} this._appendGPUEvents();otherThreads.forEach(thread=>this._appendThreadTimelineData(thread.name,thread.events,thread.asyncEventsByGroup));function compareStartTime(a,b) {return a.startTime()-b.startTime();} this._markers.sort(compareStartTime);this._timelineData.markers=this._markers;this._flowEventIndexById={};return this._timelineData;},_appendThreadTimelineData:function(threadTitle,syncEvents,asyncEvents,forceExpanded) {this._appendAsyncEvents(asyncEvents);this._appendSyncEvents(syncEvents,threadTitle,this._headerLevel1,forceExpanded);},_appendSyncEvents:function(events,title,style,forceExpanded) {var openEvents=[];var flowEventsEnabled=Runtime.experiments.isEnabled("timelineFlowEvents");var blackboxingEnabled=Runtime.experiments.isEnabled("blackboxJSFramesOnTimeline");var maxStackDepth=0;for(var i=0;i<events.length;++i){var e=events[i];if(WebInspector.TimelineUIUtils.isMarkerEvent(e)) this._markers.push(new WebInspector.TimelineFlameChartMarker(e.startTime,e.startTime-this._model.minimumRecordTime(),WebInspector.TimelineUIUtils.markerStyleForEvent(e)));if(!WebInspector.TracingModel.isFlowPhase(e.phase)){if(!e.endTime&&e.phase!==WebInspector.TracingModel.Phase.Instant) continue;if(WebInspector.TracingModel.isAsyncPhase(e.phase)) continue;if(!this._isVisible(e)) continue;} while(openEvents.length&&openEvents.peekLast().endTime<=e.startTime) openEvents.pop();e._blackboxRoot=false;if(blackboxingEnabled&&this._isBlackboxedEvent(e)){var parent=openEvents.peekLast();if(parent&&parent._blackboxRoot) continue;e._blackboxRoot=true;} if(title){this._appendHeader(title,style,forceExpanded);title="";} var level=this._currentLevel+openEvents.length;this._appendEvent(e,level);if(flowEventsEnabled) this._appendFlowEvent(e,level);maxStackDepth=Math.max(maxStackDepth,openEvents.length+1);if(e.endTime) openEvents.push(e);} this._entryTypeByLevel.length=this._currentLevel+maxStackDepth;this._entryTypeByLevel.fill(WebInspector.TimelineFlameChartEntryType.Event,this._currentLevel);this._currentLevel+=maxStackDepth;},_isBlackboxedEvent:function(event) {if(event.name!==WebInspector.TimelineModel.RecordType.JSFrame) return false;var url=event.args["data"]["url"];return url&&this._isBlackboxedURL(url);},_isBlackboxedURL:function(url) {return WebInspector.blackboxManager.isBlackboxedURL(url);},_appendAsyncEvents:function(asyncEvents) {var groups=WebInspector.TimelineUIUtils.asyncEventGroups();var groupArray=Object.values(groups);groupArray.remove(groups.animation);groupArray.remove(groups.input);for(var groupIndex=0;groupIndex<groupArray.length;++groupIndex){var group=groupArray[groupIndex];var events=asyncEvents.get(group);if(events) this._appendAsyncEventsGroup(group.title,events,this._headerLevel1);}},_appendAsyncEventsGroup:function(header,events,style) {var lastUsedTimeByLevel=[];var groupHeaderAppended=false;for(var i=0;i<events.length;++i){var asyncEvent=events[i];if(!this._isVisible(asyncEvent)) continue;if(!groupHeaderAppended){this._appendHeader(header,style);groupHeaderAppended=true;} var startTime=asyncEvent.startTime;var level;for(level=0;level<lastUsedTimeByLevel.length&&lastUsedTimeByLevel[level]>startTime;++level){} this._appendAsyncEvent(asyncEvent,this._currentLevel+level);lastUsedTimeByLevel[level]=asyncEvent.endTime;} this._entryTypeByLevel.length=this._currentLevel+lastUsedTimeByLevel.length;this._entryTypeByLevel.fill(WebInspector.TimelineFlameChartEntryType.Event,this._currentLevel);this._currentLevel+=lastUsedTimeByLevel.length;},_appendGPUEvents:function() {if(this._appendSyncEvents(this._model.gpuEvents(),WebInspector.UIString("GPU"),this._headerLevel1,false)) ++this._currentLevel;},_appendInteractionRecords:function() {this._irModel.interactionRecords().forEach(this._appendSegment,this);this._entryTypeByLevel[this._currentLevel++]=WebInspector.TimelineFlameChartEntryType.InteractionRecord;},_appendFrameBars:function(frames) {var style=WebInspector.TimelineUIUtils.markerStyleForFrame();this._entryTypeByLevel[this._currentLevel]=WebInspector.TimelineFlameChartEntryType.Frame;for(var i=0;i<frames.length;++i){this._markers.push(new WebInspector.TimelineFlameChartMarker(frames[i].startTime,frames[i].startTime-this._model.minimumRecordTime(),style));this._appendFrame(frames[i]);} ++this._currentLevel;},_entryType:function(entryIndex) {return this._entryTypeByLevel[this._timelineData.entryLevels[entryIndex]];},prepareHighlightedEntryInfo:function(entryIndex) {var time;var title;var warning;var type=this._entryType(entryIndex);if(type===WebInspector.TimelineFlameChartEntryType.Event){var event=(this._entryData[entryIndex]);var totalTime=event.duration;var selfTime=event.selfTime;var eps=1e-6;time=typeof totalTime==="number"&&Math.abs(totalTime-selfTime)>eps&&selfTime>eps?WebInspector.UIString("%s (self %s)",Number.millisToString(totalTime,true),Number.millisToString(selfTime,true)):Number.millisToString(totalTime,true);title=this.entryTitle(entryIndex);warning=WebInspector.TimelineUIUtils.eventWarning(event);}else if(type===WebInspector.TimelineFlameChartEntryType.Frame){var frame=(this._entryData[entryIndex]);time=WebInspector.UIString("%s ~ %.0f\u2009fps",Number.preciseMillisToString(frame.duration,1),(1000/frame.duration));title=frame.idle?WebInspector.UIString("Idle Frame"):WebInspector.UIString("Frame");if(frame.hasWarnings()){warning=createElement("span");warning.textContent=WebInspector.UIString("Long frame");}}else{return null;} var value=createElement("div");var root=WebInspector.createShadowRootWithCoreStyles(value,"timeline/timelineFlamechartPopover.css");var contents=root.createChild("div","timeline-flamechart-popover");contents.createChild("span","timeline-info-time").textContent=time;contents.createChild("span","timeline-info-title").textContent=title;if(warning){warning.classList.add("timeline-info-warning");contents.appendChild(warning);} return[{title:"",value:value}];},entryColor:function(entryIndex) {function patchColorAndCache(cache,key,lookupColor) {var color=cache.get(key);if(color) return color;var parsedColor=WebInspector.Color.parse(lookupColor(key));color=parsedColor.setAlpha(0.7).asString(WebInspector.Color.Format.RGBA)||"";cache.set(key,color);return color;} var type=this._entryType(entryIndex);if(type===WebInspector.TimelineFlameChartEntryType.Event){var event=(this._entryData[entryIndex]);if(!WebInspector.TracingModel.isAsyncPhase(event.phase)) return WebInspector.TimelineUIUtils.eventColor(event);if(event.hasCategory(WebInspector.TimelineModel.Category.Console)||event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return this._consoleColorGenerator.colorForID(event.name);if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)){var phase=WebInspector.TimelineIRModel.phaseForEvent(event)||WebInspector.TimelineIRModel.Phases.Uncategorized;return patchColorAndCache(this._asyncColorByInteractionPhase,phase,WebInspector.TimelineUIUtils.interactionPhaseColor);} var category=WebInspector.TimelineUIUtils.eventStyle(event).category;return patchColorAndCache(this._asyncColorByCategory,category,()=>category.color);} if(type===WebInspector.TimelineFlameChartEntryType.Frame) return"white";if(type===WebInspector.TimelineFlameChartEntryType.InteractionRecord) return"transparent";return"";},decorateEntry:function(entryIndex,context,text,barX,barY,barWidth,barHeight,unclippedBarX,timeToPixels) {var data=this._entryData[entryIndex];var type=this._entryType(entryIndex);if(type===WebInspector.TimelineFlameChartEntryType.Frame){var vPadding=1;var hPadding=1;var frame=(data);barX+=hPadding;barWidth-=2*hPadding;barY+=vPadding;barHeight-=2*vPadding+1;context.fillStyle=frame.idle?"white":(frame.hasWarnings()?"#fad1d1":"#d7f0d1");context.fillRect(barX,barY,barWidth,barHeight);var frameDurationText=Number.preciseMillisToString(frame.duration,1);var textWidth=context.measureText(frameDurationText).width;if(barWidth>=textWidth){context.fillStyle=this.textColor(entryIndex);context.fillText(frameDurationText,barX+(barWidth-textWidth)/2,barY+barHeight-3);} return true;} if(type===WebInspector.TimelineFlameChartEntryType.InteractionRecord){var color=WebInspector.TimelineUIUtils.interactionPhaseColor((this._entryData[entryIndex]));context.fillStyle=color;context.fillRect(barX,barY,barWidth-1,2);context.fillRect(barX,barY-3,2,3);context.fillRect(barX+barWidth-3,barY-3,2,3);return false;} if(type===WebInspector.TimelineFlameChartEntryType.Event){var event=(this._entryData[entryIndex]);if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)&&event.timeWaitingForMainThread){context.fillStyle="hsla(0, 70%, 60%, 1)";var width=Math.floor(unclippedBarX-barX+event.timeWaitingForMainThread*timeToPixels);context.fillRect(barX,barY+barHeight-3,width,2);} if(event.warning) paintWarningDecoration(barX,barWidth-1.5);} function paintWarningDecoration(x,width) {var triangleSize=8;context.save();context.beginPath();context.rect(x,barY,width,barHeight);context.clip();context.beginPath();context.fillStyle="red";context.moveTo(x+width-triangleSize,barY);context.lineTo(x+width,barY);context.lineTo(x+width,barY+triangleSize);context.fill();context.restore();} return false;},forceDecoration:function(entryIndex) {var type=this._entryType(entryIndex);return type===WebInspector.TimelineFlameChartEntryType.Frame||type===WebInspector.TimelineFlameChartEntryType.Event&&!!((this._entryData[entryIndex]).warning);},_appendHeader:function(title,style,expanded) {this._timelineData.groups.push({startLevel:this._currentLevel,name:title,expanded:expanded,style:style});},_appendEvent:function(event,level) {var index=this._entryData.length;this._entryData.push(event);this._timelineData.entryLevels[index]=level;this._timelineData.entryTotalTimes[index]=event.duration||WebInspector.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs;this._timelineData.entryStartTimes[index]=event.startTime;},_appendFlowEvent:function(event,level) {var timelineData=this._timelineData;function pushStartFlow(event) {var flowIndex=timelineData.flowStartTimes.length;timelineData.flowStartTimes.push(event.startTime);timelineData.flowStartLevels.push(level);return flowIndex;} function pushEndFlow(event,flowIndex) {timelineData.flowEndTimes[flowIndex]=event.startTime;timelineData.flowEndLevels[flowIndex]=level;} switch(event.phase){case WebInspector.TracingModel.Phase.FlowBegin:this._flowEventIndexById[event.id]=pushStartFlow(event);break;case WebInspector.TracingModel.Phase.FlowStep:pushEndFlow(event,this._flowEventIndexById[event.id]);this._flowEventIndexById[event.id]=pushStartFlow(event);break;case WebInspector.TracingModel.Phase.FlowEnd:pushEndFlow(event,this._flowEventIndexById[event.id]);delete this._flowEventIndexById[event.id];break;}},_appendAsyncEvent:function(asyncEvent,level) {if(WebInspector.TracingModel.isNestableAsyncPhase(asyncEvent.phase)){this._appendEvent(asyncEvent,level);return;} var steps=asyncEvent.steps;var eventOffset=steps.length>1&&steps[1].phase===WebInspector.TracingModel.Phase.AsyncStepPast?1:0;for(var i=0;i<steps.length-1;++i){var index=this._entryData.length;this._entryData.push(steps[i+eventOffset]);var startTime=steps[i].startTime;this._timelineData.entryLevels[index]=level;this._timelineData.entryTotalTimes[index]=steps[i+1].startTime-startTime;this._timelineData.entryStartTimes[index]=startTime;}},_appendFrame:function(frame) {var index=this._entryData.length;this._entryData.push(frame);this._entryIndexToTitle[index]=Number.millisToString(frame.duration,true);this._timelineData.entryLevels[index]=this._currentLevel;this._timelineData.entryTotalTimes[index]=frame.duration;this._timelineData.entryStartTimes[index]=frame.startTime;},_appendSegment:function(segment) {var index=this._entryData.length;this._entryData.push((segment.data));this._entryIndexToTitle[index]=(segment.data);this._timelineData.entryLevels[index]=this._currentLevel;this._timelineData.entryTotalTimes[index]=segment.end-segment.begin;this._timelineData.entryStartTimes[index]=segment.begin;},createSelection:function(entryIndex) {var type=this._entryType(entryIndex);var timelineSelection=null;if(type===WebInspector.TimelineFlameChartEntryType.Event) timelineSelection=WebInspector.TimelineSelection.fromTraceEvent((this._entryData[entryIndex])) else if(type===WebInspector.TimelineFlameChartEntryType.Frame) timelineSelection=WebInspector.TimelineSelection.fromFrame((this._entryData[entryIndex]));if(timelineSelection) this._lastSelection=new WebInspector.TimelineFlameChartView.Selection(timelineSelection,entryIndex);return timelineSelection;},entryIndexForSelection:function(selection) {if(!selection||selection.type()===WebInspector.TimelineSelection.Type.Range) return-1;if(this._lastSelection&&this._lastSelection.timelineSelection.object()===selection.object()) return this._lastSelection.entryIndex;var index=this._entryData.indexOf((selection.object()));if(index!==-1) this._lastSelection=new WebInspector.TimelineFlameChartView.Selection(selection,index);return index;},__proto__:WebInspector.TimelineFlameChartDataProviderBase.prototype} WebInspector.TimelineFlameChartNetworkDataProvider=function(model) {WebInspector.TimelineFlameChartDataProviderBase.call(this,model,[]);var loadingCategory=WebInspector.TimelineUIUtils.categories()["loading"];this._waitingColor=loadingCategory.childColor;this._processingColor=loadingCategory.color;} WebInspector.TimelineFlameChartNetworkDataProvider.prototype={timelineData:function() {if(this._timelineData) return this._timelineData;this._requests=[];this._timelineData=new WebInspector.FlameChart.TimelineData([],[],[],[]);this._appendTimelineData(this._model.mainThreadEvents());return this._timelineData;},reset:function() {WebInspector.TimelineFlameChartDataProviderBase.prototype.reset.call(this);this._requests=[];},setWindowTimes:function(startTime,endTime) {this._startTime=startTime;this._endTime=endTime;this._updateTimelineData();},createSelection:function(index) {if(index===-1) return null;var request=this._requests[index];this._lastSelection=new WebInspector.TimelineFlameChartView.Selection(WebInspector.TimelineSelection.fromNetworkRequest(request),index);return this._lastSelection.timelineSelection;},entryIndexForSelection:function(selection) {if(!selection) return-1;if(this._lastSelection&&this._lastSelection.timelineSelection.object()===selection.object()) return this._lastSelection.entryIndex;if(selection.type()!==WebInspector.TimelineSelection.Type.NetworkRequest) return-1;var request=(selection.object());var index=this._requests.indexOf(request);if(index!==-1) this._lastSelection=new WebInspector.TimelineFlameChartView.Selection(WebInspector.TimelineSelection.fromNetworkRequest(request),index);return index;},entryColor:function(index) {var request=(this._requests[index]);var category=WebInspector.TimelineUIUtils.networkRequestCategory(request);return WebInspector.TimelineUIUtils.networkCategoryColor(category);},entryTitle:function(index) {var request=(this._requests[index]);return request.url||null;},decorateEntry:function(index,context,text,barX,barY,barWidth,barHeight,unclippedBarX,timeToPixels) {var minTransferWidthPx=2;var request=(this._requests[index]);var startTime=request.startTime;var endTime=request.endTime;var lastX=unclippedBarX;context.fillStyle="hsla(0, 0%, 100%, 0.6)";for(var i=0;i<request.children.length;++i){var event=request.children[i];var t0=event.startTime;var t1=event.endTime||event.startTime;var x0=Math.floor(unclippedBarX+(t0-startTime)*timeToPixels-1);var x1=Math.floor(unclippedBarX+(t1-startTime)*timeToPixels+1);if(x0>lastX) context.fillRect(lastX,barY,x0-lastX,barHeight);lastX=x1;} var endX=unclippedBarX+(endTime-startTime)*timeToPixels;if(endX>lastX) context.fillRect(lastX,barY,Math.min(endX-lastX,1e5),barHeight);if(typeof request.priority==="string"){var color=this._colorForPriority(request.priority);if(color){context.fillStyle="hsl(0, 0%, 100%)";context.fillRect(barX,barY,4,4);context.fillStyle=color;context.fillRect(barX,barY,3,3);}} return false;},forceDecoration:function(index) {return true;},prepareHighlightedEntryInfo:function(index) {var maxURLChars=80;var request=(this._requests[index]);if(!request.url) return null;var value=createElement("div");var root=WebInspector.createShadowRootWithCoreStyles(value,"timeline/timelineFlamechartPopover.css");var contents=root.createChild("div","timeline-flamechart-popover");var duration=request.endTime-request.startTime;if(request.startTime&&isFinite(duration)) contents.createChild("span","timeline-info-network-time").textContent=Number.millisToString(duration);if(typeof request.priority==="string"){var div=contents.createChild("span");div.textContent=WebInspector.uiLabelForPriority((request.priority));div.style.color=this._colorForPriority(request.priority)||"black";} contents.createChild("span").textContent=request.url.trimMiddle(maxURLChars);return[{title:"",value:value}];},_colorForPriority:function(priority) {switch((priority)){case NetworkAgent.ResourcePriority.VeryLow:return"#080";case NetworkAgent.ResourcePriority.Low:return"#6c0";case NetworkAgent.ResourcePriority.Medium:return"#fa0";case NetworkAgent.ResourcePriority.High:return"#f60";case NetworkAgent.ResourcePriority.VeryHigh:return"#f00";} return null;},_appendTimelineData:function(events) {this._minimumBoundary=this._model.minimumRecordTime();this._maximumBoundary=this._model.maximumRecordTime();this._timeSpan=this._model.isEmpty()?1000:this._maximumBoundary-this._minimumBoundary;this._model.networkRequests().forEach(this._appendEntry.bind(this));this._updateTimelineData();},_updateTimelineData:function() {if(!this._timelineData) return;var index=-1;var lastTime=Infinity;for(var i=0;i<this._requests.length;++i){var r=this._requests[i];var visible=r.startTime<this._endTime&&r.endTime>this._startTime;if(!visible){this._timelineData.entryLevels[i]=-1;continue;} if(lastTime>r.startTime) ++index;lastTime=r.endTime;this._timelineData.entryLevels[i]=index;} ++index;for(var i=0;i<this._requests.length;++i){if(this._timelineData.entryLevels[i]===-1) this._timelineData.entryLevels[i]=index;} this._timelineData=new WebInspector.FlameChart.TimelineData(this._timelineData.entryLevels,this._timelineData.entryTotalTimes,this._timelineData.entryStartTimes,null);this._currentLevel=index;},_appendEntry:function(request) {this._requests.push(request);this._timelineData.entryStartTimes.push(request.startTime);this._timelineData.entryTotalTimes.push(request.endTime-request.startTime);this._timelineData.entryLevels.push(this._requests.length-1);},__proto__:WebInspector.TimelineFlameChartDataProviderBase.prototype} WebInspector.TimelineFlameChartMarker=function(startTime,startOffset,style) {this._startTime=startTime;this._startOffset=startOffset;this._style=style;} WebInspector.TimelineFlameChartMarker.prototype={startTime:function() {return this._startTime;},color:function() {return this._style.color;},title:function() {var startTime=Number.millisToString(this._startOffset);return WebInspector.UIString("%s at %s",this._style.title,startTime);},draw:function(context,x,height,pixelsPerMillisecond) {var lowPriorityVisibilityThresholdInPixelsPerMs=4;if(this._style.lowPriority&&pixelsPerMillisecond<lowPriorityVisibilityThresholdInPixelsPerMs) return;context.save();if(!this._style.lowPriority){context.strokeStyle=this._style.color;context.lineWidth=2;context.beginPath();context.moveTo(x,0);context.lineTo(x,height);context.stroke();} if(this._style.tall){context.strokeStyle=this._style.color;context.lineWidth=this._style.lineWidth;context.translate(this._style.lineWidth<1||(this._style.lineWidth&1)?0.5:0,0.5);context.beginPath();context.moveTo(x,height);context.setLineDash(this._style.dashStyle);context.lineTo(x,context.canvas.height);context.stroke();} context.restore();}} WebInspector.TimelineFlameChartView=function(delegate,timelineModel,frameModel,irModel,filters) {WebInspector.VBox.call(this);this.element.classList.add("timeline-flamechart");this._delegate=delegate;this._model=timelineModel;this._splitWidget=new WebInspector.SplitWidget(false,false,"timelineFlamechartMainView",150);this._dataProvider=new WebInspector.TimelineFlameChartDataProvider(this._model,frameModel,irModel,filters);var mainViewGroupExpansionSetting=WebInspector.settings.createSetting("timelineFlamechartMainViewGroupExpansion",{});this._mainView=new WebInspector.FlameChart(this._dataProvider,this,mainViewGroupExpansionSetting);this._networkDataProvider=new WebInspector.TimelineFlameChartNetworkDataProvider(this._model);this._networkView=new WebInspector.FlameChart(this._networkDataProvider,this);this._splitWidget.setMainWidget(this._mainView);this._splitWidget.setSidebarWidget(this._networkView);this._splitWidget.show(this.element);this._onMainEntrySelected=this._onEntrySelected.bind(this,this._dataProvider);this._onNetworkEntrySelected=this._onEntrySelected.bind(this,this._networkDataProvider);this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onMainEntrySelected,this);this._networkView.addEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onNetworkEntrySelected,this);WebInspector.blackboxManager.addChangeListener(this.refreshRecords,this);} WebInspector.TimelineFlameChartView.prototype={dispose:function() {this._mainView.removeEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onMainEntrySelected,this);this._networkView.removeEventListener(WebInspector.FlameChart.Events.EntrySelected,this._onNetworkEntrySelected,this);WebInspector.blackboxManager.removeChangeListener(this.refreshRecords,this);},resizerElement:function() {return null;},requestWindowTimes:function(windowStartTime,windowEndTime) {this._delegate.requestWindowTimes(windowStartTime,windowEndTime);},updateRangeSelection:function(startTime,endTime) {this._delegate.select(WebInspector.TimelineSelection.fromRange(startTime,endTime));},refreshRecords:function() {this._dataProvider.reset();this._mainView.scheduleUpdate();this._networkDataProvider.reset();this._networkView.scheduleUpdate();},highlightEvent:function(event) {var entryIndex=event?this._dataProvider.entryIndexForSelection(WebInspector.TimelineSelection.fromTraceEvent(event)):-1;if(entryIndex>=0) this._mainView.highlightEntry(entryIndex);else this._mainView.hideHighlight();},wasShown:function() {this._mainView.scheduleUpdate();this._networkView.scheduleUpdate();},view:function() {return this;},reset:function() {this._dataProvider.reset();this._mainView.reset();this._mainView.setWindowTimes(0,Infinity);this._networkDataProvider.reset();this._networkView.reset();this._networkView.setWindowTimes(0,Infinity);},setWindowTimes:function(startTime,endTime) {this._mainView.setWindowTimes(startTime,endTime);this._networkView.setWindowTimes(startTime,endTime);this._networkDataProvider.setWindowTimes(startTime,endTime);},highlightSearchResult:function(event,regex,select) {if(!event){this._delegate.select(null);return;} var entryIndex=this._dataProvider._entryData.indexOf(event);var timelineSelection=this._dataProvider.createSelection(entryIndex);if(timelineSelection) this._delegate.select(timelineSelection);},setSelection:function(selection) {var index=this._dataProvider.entryIndexForSelection(selection);this._mainView.setSelectedEntry(index);index=this._networkDataProvider.entryIndexForSelection(selection);this._networkView.setSelectedEntry(index);},_onEntrySelected:function(dataProvider,event) {var entryIndex=(event.data);this._delegate.select(dataProvider.createSelection(entryIndex));},enableNetworkPane:function(enable,animate) {if(enable) this._splitWidget.showBoth(animate);else this._splitWidget.hideSidebar(animate);},__proto__:WebInspector.VBox.prototype} WebInspector.TimelineFlameChartView.Selection=function(selection,entryIndex) {this.timelineSelection=selection;this.entryIndex=entryIndex;};WebInspector.TimelineTreeView=function(model,filters) {WebInspector.VBox.call(this);this.element.classList.add("timeline-tree-view");this._model=model;this._linkifier=new WebInspector.Linkifier();this._filters=filters.slice();var columns=[];this._populateColumns(columns);var mainView=new WebInspector.VBox();this._populateToolbar(mainView.element);this._dataGrid=new WebInspector.SortableDataGrid(columns);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortingChanged,this);this._dataGrid.element.addEventListener("mousemove",this._onMouseMove.bind(this),true) this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);this._dataGrid.asWidget().show(mainView.element);this._splitWidget=new WebInspector.SplitWidget(true,true,"timelineTreeViewDetailsSplitWidget");this._splitWidget.show(this.element);this._splitWidget.setMainWidget(mainView);this._detailsView=new WebInspector.VBox();this._detailsView.element.classList.add("timeline-details-view","timeline-details-view-body");this._splitWidget.setSidebarWidget(this._detailsView);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._updateDetailsForSelection,this);this._lastSelectedNode;} WebInspector.TimelineTreeView.prototype={updateContents:function(selection) {this.setRange(selection.startTime(),selection.endTime());},setRange:function(startTime,endTime) {this._startTime=startTime;this._endTime=endTime;this._refreshTree();},_exposePercentages:function() {return false;},_populateToolbar:function(parent){},_onHover:function(node){},linkifyLocation:function(frame) {return this._linkifier.linkifyConsoleCallFrame(this._model.target(),frame);},selectProfileNode:function(treeNode,suppressSelectedEvent) {var pathToRoot=[];for(var node=treeNode;node;node=node.parent) pathToRoot.push(node);for(var i=pathToRoot.length-1;i>0;--i){var gridNode=this._dataGridNodeForTreeNode(pathToRoot[i]);if(gridNode&&gridNode.dataGrid) gridNode.expand();} var gridNode=this._dataGridNodeForTreeNode(treeNode);if(gridNode.dataGrid){gridNode.reveal();gridNode.select(suppressSelectedEvent);}},_refreshTree:function() {this._linkifier.reset();this._dataGrid.rootNode().removeChildren();var tree=this._buildTree();if(!tree.children) return;var maxSelfTime=0;var maxTotalTime=0;for(var child of tree.children.values()){maxSelfTime=Math.max(maxSelfTime,child.selfTime);maxTotalTime=Math.max(maxTotalTime,child.totalTime);} for(var child of tree.children.values()){var gridNode=new WebInspector.TimelineTreeView.TreeGridNode(child,tree.totalTime,maxSelfTime,maxTotalTime,this);this._dataGrid.insertChild(gridNode);} this._sortingChanged();this._updateDetailsForSelection();},_buildTree:function() {throw new Error("Not Implemented");},_buildTopDownTree:function(eventIdCallback) {return WebInspector.TimelineProfileTree.buildTopDown(this._model.mainThreadEvents(),this._filters,this._startTime,this._endTime,eventIdCallback)},_populateColumns:function(columns) {columns.push({id:"self",title:WebInspector.UIString("Self Time"),width:"110px",fixedWidth:true,sortable:true});columns.push({id:"total",title:WebInspector.UIString("Total Time"),width:"110px",fixedWidth:true,sortable:true});columns.push({id:"activity",title:WebInspector.UIString("Activity"),disclosure:true,sortable:true});},_sortingChanged:function() {var columnIdentifier=this._dataGrid.sortColumnIdentifier();if(!columnIdentifier) return;var sortFunction;switch(columnIdentifier){case"startTime":sortFunction=compareStartTime;break;case"self":sortFunction=compareNumericField.bind(null,"selfTime");break;case"total":sortFunction=compareNumericField.bind(null,"totalTime");break;case"activity":sortFunction=compareName;break;default:console.assert(false,"Unknown sort field: "+columnIdentifier);return;} this._dataGrid.sortNodes(sortFunction,!this._dataGrid.isSortOrderAscending());function compareNumericField(field,a,b) {var nodeA=(a);var nodeB=(b);return nodeA._profileNode[field]-nodeB._profileNode[field];} function compareStartTime(a,b) {var nodeA=(a);var nodeB=(b);return nodeA._profileNode.event.startTime-nodeB._profileNode.event.startTime;} function compareName(a,b) {var nodeA=(a);var nodeB=(b);var nameA=WebInspector.TimelineTreeView.eventNameForSorting(nodeA._profileNode.event);var nameB=WebInspector.TimelineTreeView.eventNameForSorting(nodeB._profileNode.event);return nameA.localeCompare(nameB);}},_updateDetailsForSelection:function() {var selectedNode=this._dataGrid.selectedNode?(this._dataGrid.selectedNode)._profileNode:null;if(selectedNode===this._lastSelectedNode) return;this._lastSelectedNode=selectedNode;this._detailsView.detachChildWidgets();this._detailsView.element.removeChildren();if(!selectedNode||!this._showDetailsForNode(selectedNode)){var banner=this._detailsView.element.createChild("div","banner");banner.createTextChild(WebInspector.UIString("Select item for details."));}},_showDetailsForNode:function(node) {return false;},_onMouseMove:function(event) {var gridNode=event.target&&(event.target instanceof Node)?(this._dataGrid.dataGridNodeFromNode((event.target))):null;var profileNode=gridNode&&gridNode._profileNode;if(profileNode===this._lastHoveredProfileNode) return;this._lastHoveredProfileNode=profileNode;this._onHover(profileNode);},_dataGridNodeForTreeNode:function(treeNode) {return treeNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol]||null;},__proto__:WebInspector.VBox.prototype} WebInspector.TimelineTreeView.eventNameForSorting=function(event) {if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){var data=event.args["data"];return data["functionName"]+"@"+(data["scriptId"]||data["url"]||"");} return event.name+":@"+WebInspector.TimelineProfileTree.eventURL(event);} WebInspector.TimelineTreeView.GridNode=function(profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView) {this._populated=false;this._profileNode=profileNode;this._treeView=treeView;this._grandTotalTime=grandTotalTime;this._maxSelfTime=maxSelfTime;this._maxTotalTime=maxTotalTime;WebInspector.SortableDataGridNode.call(this,null,false);} WebInspector.TimelineTreeView.GridNode.prototype={createCell:function(columnIdentifier) {if(columnIdentifier==="activity") return this._createNameCell(columnIdentifier);return this._createValueCell(columnIdentifier)||WebInspector.DataGridNode.prototype.createCell.call(this,columnIdentifier);},_createNameCell:function(columnIdentifier) {var cell=this.createTD(columnIdentifier);var container=cell.createChild("div","name-container");var icon=container.createChild("div","activity-icon");var name=container.createChild("div","activity-name");var event=this._profileNode.event;if(this._profileNode.isGroupNode()){var treeView=(this._treeView);var info=treeView._displayInfoForGroupNode(this._profileNode);name.textContent=info.name;icon.style.backgroundColor=info.color;}else if(event){var data=event.args["data"];var deoptReason=data&&data["deoptReason"];if(deoptReason&&deoptReason!=="no reason") container.createChild("div","activity-warning").title=WebInspector.UIString("Not optimized: %s",deoptReason);name.textContent=event.name===WebInspector.TimelineModel.RecordType.JSFrame?WebInspector.beautifyFunctionName(event.args["data"]["functionName"]):WebInspector.TimelineUIUtils.eventTitle(event);var frame=WebInspector.TimelineProfileTree.eventStackFrame(event);if(frame&&frame["url"]){var callFrame=(frame);container.createChild("div","activity-link").appendChild(this._treeView.linkifyLocation(callFrame));} icon.style.backgroundColor=WebInspector.TimelineUIUtils.eventColor(event);} return cell;},_createValueCell:function(columnIdentifier) {if(columnIdentifier!=="self"&&columnIdentifier!=="total"&&columnIdentifier!=="startTime") return null;var showPercents=false;var value;var maxTime;switch(columnIdentifier){case"startTime":value=this._profileNode.event.startTime-this._treeView._model.minimumRecordTime();break;case"self":value=this._profileNode.selfTime;maxTime=this._maxSelfTime;showPercents=true;break;case"total":value=this._profileNode.totalTime;maxTime=this._maxTotalTime;showPercents=true;break;default:return null;} var cell=this.createTD(columnIdentifier);cell.className="numeric-column";var textDiv=cell.createChild("div");textDiv.createChild("span").textContent=WebInspector.UIString("%.1f\u2009ms",value);if(showPercents&&this._treeView._exposePercentages()) textDiv.createChild("span","percent-column").textContent=WebInspector.UIString("%.1f\u2009%%",value/this._grandTotalTime*100);if(maxTime){textDiv.classList.add("background-percent-bar");cell.createChild("div","background-bar-container").createChild("div","background-bar").style.width=(value*100/maxTime).toFixed(1)+"%";} return cell;},__proto__:WebInspector.SortableDataGridNode.prototype} WebInspector.TimelineTreeView.TreeGridNode=function(profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView) {WebInspector.TimelineTreeView.GridNode.call(this,profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView);this.hasChildren=this._profileNode.children?this._profileNode.children.size>0:false;profileNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol]=this;} WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol=Symbol("treeGridNode");WebInspector.TimelineTreeView.TreeGridNode.prototype={populate:function() {if(this._populated) return;this._populated=true;if(!this._profileNode.children) return;for(var node of this._profileNode.children.values()){var gridNode=new WebInspector.TimelineTreeView.TreeGridNode(node,this._grandTotalTime,this._maxSelfTime,this._maxTotalTime,this._treeView);this.insertChildOrdered(gridNode);}},__proto__:WebInspector.TimelineTreeView.GridNode.prototype};WebInspector.AggregatedTimelineTreeView=function(model,filters) {this._groupBySetting=WebInspector.settings.createSetting("timelineTreeGroupBy",WebInspector.TimelineAggregator.GroupBy.Category);WebInspector.TimelineTreeView.call(this,model,filters);var nonessentialEvents=[WebInspector.TimelineModel.RecordType.EventDispatch,WebInspector.TimelineModel.RecordType.FunctionCall,WebInspector.TimelineModel.RecordType.TimerFire];this._filters.push(new WebInspector.ExclusiveNameFilter(nonessentialEvents));this._stackView=new WebInspector.TimelineStackView(this);this._stackView.addEventListener(WebInspector.TimelineStackView.Events.SelectionChanged,this._onStackViewSelectionChanged,this);} WebInspector.AggregatedTimelineTreeView.prototype={updateContents:function(selection) {this._updateExtensionResolver();WebInspector.TimelineTreeView.prototype.updateContents.call(this,selection);var rootNode=this._dataGrid.rootNode();if(rootNode.children.length) rootNode.children[0].revealAndSelect();},_updateExtensionResolver:function() {this._executionContextNamesByOrigin=new Map();for(var target of WebInspector.targetManager.targets()){for(var context of target.runtimeModel.executionContexts()) this._executionContextNamesByOrigin.set(context.origin,context.name);}},_displayInfoForGroupNode:function(node) {var categories=WebInspector.TimelineUIUtils.categories();switch(this._groupBySetting.get()){case WebInspector.TimelineAggregator.GroupBy.Category:var category=categories[node.id]||categories["other"];return{name:category.title,color:category.color};case WebInspector.TimelineAggregator.GroupBy.Domain:case WebInspector.TimelineAggregator.GroupBy.Subdomain:var name=node.id;if(WebInspector.TimelineAggregator.isExtensionInternalURL(name)) name=WebInspector.UIString("[Chrome extensions overhead]");else if(name.startsWith("chrome-extension")) name=this._executionContextNamesByOrigin.get(name)||name;return{name:name||WebInspector.UIString("unattributed"),color:node.id?WebInspector.TimelineUIUtils.eventColor(node.event):categories["other"].color} case WebInspector.TimelineAggregator.GroupBy.URL:break;default:console.assert(false,"Unexpected aggregation type");} return{name:node.id||WebInspector.UIString("unattributed"),color:node.id?WebInspector.TimelineUIUtils.eventColor(node.event):categories["other"].color}},_populateToolbar:function(parent) {var panelToolbar=new WebInspector.Toolbar("",parent);this._groupByCombobox=new WebInspector.ToolbarComboBox(this._onGroupByChanged.bind(this));function addGroupingOption(name,id) {var option=this._groupByCombobox.createOption(name,"",id);this._groupByCombobox.addOption(option);if(id===this._groupBySetting.get()) this._groupByCombobox.select(option);} addGroupingOption.call(this,WebInspector.UIString("No Grouping"),WebInspector.TimelineAggregator.GroupBy.None);addGroupingOption.call(this,WebInspector.UIString("Group by Category"),WebInspector.TimelineAggregator.GroupBy.Category);addGroupingOption.call(this,WebInspector.UIString("Group by Domain"),WebInspector.TimelineAggregator.GroupBy.Domain);addGroupingOption.call(this,WebInspector.UIString("Group by Subdomain"),WebInspector.TimelineAggregator.GroupBy.Subdomain);addGroupingOption.call(this,WebInspector.UIString("Group by URL"),WebInspector.TimelineAggregator.GroupBy.URL);panelToolbar.appendToolbarItem(this._groupByCombobox);},_buildHeaviestStack:function(treeNode) {console.assert(!!treeNode.parent,"Attempt to build stack for tree root");var result=[];for(var node=treeNode;node&&node.parent;node=node.parent) result.push(node);result=result.reverse();for(node=treeNode;node&&node.children&&node.children.size;){var children=Array.from(node.children.values());node=children.reduce((a,b)=>a.totalTime>b.totalTime?a:b);result.push(node);} return result;},_exposePercentages:function() {return true;},_onGroupByChanged:function() {this._groupBySetting.set(this._groupByCombobox.selectedOption().value);this._refreshTree();},_onStackViewSelectionChanged:function() {var treeNode=this._stackView.selectedTreeNode();if(treeNode) this.selectProfileNode(treeNode,true);},_showDetailsForNode:function(node) {var stack=this._buildHeaviestStack(node);this._stackView.setStack(stack,node);this._stackView.show(this._detailsView.element);return true;},__proto__:WebInspector.TimelineTreeView.prototype,};WebInspector.CallTreeTimelineTreeView=function(model,filters) {WebInspector.AggregatedTimelineTreeView.call(this,model,filters);this._dataGrid.markColumnAsSortedBy("total",WebInspector.DataGrid.Order.Descending);} WebInspector.CallTreeTimelineTreeView.prototype={_buildTree:function() {var topDown=this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);var aggregator=new WebInspector.TimelineAggregator(event=>WebInspector.TimelineUIUtils.eventStyle(event).category.name);return aggregator.performGrouping(topDown,this._groupBySetting.get());},__proto__:WebInspector.AggregatedTimelineTreeView.prototype,};WebInspector.BottomUpTimelineTreeView=function(model,filters) {WebInspector.AggregatedTimelineTreeView.call(this,model,filters);this._dataGrid.markColumnAsSortedBy("self",WebInspector.DataGrid.Order.Descending);} WebInspector.BottomUpTimelineTreeView.prototype={_buildTree:function() {var topDown=this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);var aggregator=new WebInspector.TimelineAggregator(event=>WebInspector.TimelineUIUtils.eventStyle(event).category.name);return WebInspector.TimelineProfileTree.buildBottomUp(topDown,aggregator.groupFunction(this._groupBySetting.get()));},__proto__:WebInspector.AggregatedTimelineTreeView.prototype};WebInspector.EventsTimelineTreeView=function(model,filters,delegate) {this._filtersControl=new WebInspector.TimelineFilters();this._filtersControl.addEventListener(WebInspector.TimelineFilters.Events.FilterChanged,this._onFilterChanged,this);WebInspector.TimelineTreeView.call(this,model,filters);this._delegate=delegate;this._filters.push.apply(this._filters,this._filtersControl.filters());this._dataGrid.markColumnAsSortedBy("startTime",WebInspector.DataGrid.Order.Ascending);} WebInspector.EventsTimelineTreeView.prototype={updateContents:function(selection) {WebInspector.TimelineTreeView.prototype.updateContents.call(this,selection);if(selection.type()===WebInspector.TimelineSelection.Type.TraceEvent){var event=(selection.object());this._selectEvent(event,true);}},_buildTree:function() {this._currentTree=this._buildTopDownTree();return this._currentTree;},_onFilterChanged:function() {var selectedEvent=this._lastSelectedNode&&this._lastSelectedNode.event;this._refreshTree();if(selectedEvent) this._selectEvent(selectedEvent,false);},_findNodeWithEvent:function(event) {var iterators=[this._currentTree.children.values()];while(iterators.length){var iterator=iterators.peekLast().next();if(iterator.done){iterators.pop();continue;} var child=(iterator.value);if(child.event===event) return child;if(child.children) iterators.push(child.children.values());} return null;},_selectEvent:function(event,expand) {var node=this._findNodeWithEvent(event);if(!node) return;this.selectProfileNode(node,false);if(expand) this._dataGridNodeForTreeNode(node).expand();},_populateColumns:function(columns) {columns.push({id:"startTime",title:WebInspector.UIString("Start Time"),width:"110px",fixedWidth:true,sortable:true});WebInspector.TimelineTreeView.prototype._populateColumns.call(this,columns);},_populateToolbar:function(parent) {var filtersWidget=this._filtersControl.filtersWidget();filtersWidget.forceShowFilterBar();filtersWidget.show(parent);},_showDetailsForNode:function(node) {var traceEvent=node.event;if(!traceEvent) return false;WebInspector.TimelineUIUtils.buildTraceEventDetails(traceEvent,this._model,this._linkifier,false,showDetails.bind(this));return true;function showDetails(fragment) {this._detailsView.element.appendChild(fragment);}},_onHover:function(node) {this._delegate.highlightEvent(node&&node.event);},__proto__:WebInspector.TimelineTreeView.prototype} WebInspector.TimelineStackView=function(treeView) {WebInspector.VBox.call(this);var header=this.element.createChild("div","timeline-stack-view-header");header.textContent=WebInspector.UIString("Heaviest stack");this._treeView=treeView;var columns=[{id:"total",title:WebInspector.UIString("Total Time"),fixedWidth:true,width:"110px"},{id:"activity",title:WebInspector.UIString("Activity")}];this._dataGrid=new WebInspector.ViewportDataGrid(columns);this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._onSelectionChanged,this);this._dataGrid.asWidget().show(this.element);} WebInspector.TimelineStackView.Events={SelectionChanged:Symbol("SelectionChanged")} WebInspector.TimelineStackView.prototype={setStack:function(stack,selectedNode) {var rootNode=this._dataGrid.rootNode();rootNode.removeChildren();var nodeToReveal=null;var totalTime=Math.max.apply(Math,stack.map(node=>node.totalTime));for(var node of stack){var gridNode=new WebInspector.TimelineTreeView.GridNode(node,totalTime,totalTime,totalTime,this._treeView);rootNode.appendChild(gridNode);if(node===selectedNode) nodeToReveal=gridNode;} nodeToReveal.revealAndSelect();},selectedTreeNode:function() {var selectedNode=this._dataGrid.selectedNode;return selectedNode&&(selectedNode)._profileNode;},_onSelectionChanged:function() {this.dispatchEventToListeners(WebInspector.TimelineStackView.Events.SelectionChanged);},__proto__:WebInspector.VBox.prototype};WebInspector.TimelineUIUtils=function(){} WebInspector.TimelineRecordStyle=function(title,category,hidden) {this.title=title;this.category=category;this.hidden=!!hidden;} WebInspector.TimelineUIUtils._initEventStyles=function() {if(WebInspector.TimelineUIUtils._eventStylesMap) return WebInspector.TimelineUIUtils._eventStylesMap;var recordTypes=WebInspector.TimelineModel.RecordType;var categories=WebInspector.TimelineUIUtils.categories();var eventStyles={};eventStyles[recordTypes.Task]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Task"),categories["other"]);eventStyles[recordTypes.Program]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Other"),categories["other"]);eventStyles[recordTypes.Animation]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation"),categories["rendering"]);eventStyles[recordTypes.EventDispatch]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Event"),categories["scripting"]);eventStyles[recordTypes.RequestMainThreadFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Main Thread Frame"),categories["rendering"],true);eventStyles[recordTypes.BeginFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start"),categories["rendering"],true);eventStyles[recordTypes.BeginMainThreadFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start (main thread)"),categories["rendering"],true);eventStyles[recordTypes.DrawFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Draw Frame"),categories["rendering"],true);eventStyles[recordTypes.HitTest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Hit Test"),categories["rendering"]);eventStyles[recordTypes.ScheduleStyleRecalculation]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Schedule Style Recalculation"),categories["rendering"],true);eventStyles[recordTypes.RecalculateStyles]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"),categories["rendering"]);eventStyles[recordTypes.UpdateLayoutTree]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"),categories["rendering"]);eventStyles[recordTypes.InvalidateLayout]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Invalidate Layout"),categories["rendering"],true);eventStyles[recordTypes.Layout]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Layout"),categories["rendering"]);eventStyles[recordTypes.PaintSetup]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Setup"),categories["painting"]);eventStyles[recordTypes.PaintImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Image"),categories["painting"],true);eventStyles[recordTypes.UpdateLayer]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer"),categories["painting"],true);eventStyles[recordTypes.UpdateLayerTree]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer Tree"),categories["rendering"]);eventStyles[recordTypes.Paint]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"),categories["painting"]);eventStyles[recordTypes.RasterTask]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Rasterize Paint"),categories["painting"]);eventStyles[recordTypes.ScrollLayer]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Scroll"),categories["rendering"]);eventStyles[recordTypes.CompositeLayers]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Composite Layers"),categories["painting"]);eventStyles[recordTypes.ParseHTML]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse HTML"),categories["loading"]);eventStyles[recordTypes.ParseAuthorStyleSheet]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Stylesheet"),categories["loading"]);eventStyles[recordTypes.TimerInstall]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Install Timer"),categories["scripting"]);eventStyles[recordTypes.TimerRemove]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Remove Timer"),categories["scripting"]);eventStyles[recordTypes.TimerFire]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timer Fired"),categories["scripting"]);eventStyles[recordTypes.XHRReadyStateChange]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Ready State Change"),categories["scripting"]);eventStyles[recordTypes.XHRLoad]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Load"),categories["scripting"]);eventStyles[recordTypes.CompileScript]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Compile Script"),categories["scripting"]);eventStyles[recordTypes.EvaluateScript]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Evaluate Script"),categories["scripting"]);eventStyles[recordTypes.ParseScriptOnBackground]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Script"),categories["scripting"]);eventStyles[recordTypes.MarkLoad]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Load event"),categories["scripting"],true);eventStyles[recordTypes.MarkDOMContent]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOMContentLoaded event"),categories["scripting"],true);eventStyles[recordTypes.MarkFirstPaint]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"),categories["painting"],true);eventStyles[recordTypes.TimeStamp]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timestamp"),categories["scripting"]);eventStyles[recordTypes.ConsoleTime]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Console Time"),categories["scripting"]);eventStyles[recordTypes.UserTiming]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("User Timing"),categories["scripting"]);eventStyles[recordTypes.ResourceSendRequest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send Request"),categories["loading"]);eventStyles[recordTypes.ResourceReceiveResponse]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Response"),categories["loading"]);eventStyles[recordTypes.ResourceFinish]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Finish Loading"),categories["loading"]);eventStyles[recordTypes.ResourceReceivedData]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Data"),categories["loading"]);eventStyles[recordTypes.FunctionCall]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Function Call"),categories["scripting"]);eventStyles[recordTypes.GCEvent]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("GC Event"),categories["scripting"]);eventStyles[recordTypes.MajorGC]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Major GC"),categories["scripting"]);eventStyles[recordTypes.MinorGC]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Minor GC"),categories["scripting"]);eventStyles[recordTypes.JSFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("JS Frame"),categories["scripting"]);eventStyles[recordTypes.RequestAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Animation Frame"),categories["scripting"]);eventStyles[recordTypes.CancelAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Animation Frame"),categories["scripting"]);eventStyles[recordTypes.FireAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation Frame Fired"),categories["scripting"]);eventStyles[recordTypes.RequestIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Idle Callback"),categories["scripting"]);eventStyles[recordTypes.CancelIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Idle Callback"),categories["scripting"]);eventStyles[recordTypes.FireIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Fire Idle Callback"),categories["scripting"]);eventStyles[recordTypes.WebSocketCreate]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Create WebSocket"),categories["scripting"]);eventStyles[recordTypes.WebSocketSendHandshakeRequest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send WebSocket Handshake"),categories["scripting"]);eventStyles[recordTypes.WebSocketReceiveHandshakeResponse]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive WebSocket Handshake"),categories["scripting"]);eventStyles[recordTypes.WebSocketDestroy]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Destroy WebSocket"),categories["scripting"]);eventStyles[recordTypes.EmbedderCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Embedder Callback"),categories["scripting"]);eventStyles[recordTypes.DecodeImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Decode"),categories["painting"]);eventStyles[recordTypes.ResizeImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Resize"),categories["painting"]);eventStyles[recordTypes.GPUTask]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("GPU"),categories["gpu"]);eventStyles[recordTypes.LatencyInfo]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Input Latency"),categories["scripting"]);eventStyles[recordTypes.GCIdleLazySweep]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);eventStyles[recordTypes.GCCompleteSweep]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);eventStyles[recordTypes.GCCollectGarbage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);WebInspector.TimelineUIUtils._eventStylesMap=eventStyles;return eventStyles;} WebInspector.TimelineUIUtils.inputEventDisplayName=function(inputEventType) {if(!WebInspector.TimelineUIUtils._inputEventToDisplayName){var inputEvent=WebInspector.TimelineIRModel.InputEvents;WebInspector.TimelineUIUtils._inputEventToDisplayName=new Map([[inputEvent.Char,WebInspector.UIString("Key Character")],[inputEvent.KeyDown,WebInspector.UIString("Key Down")],[inputEvent.KeyDownRaw,WebInspector.UIString("Key Down")],[inputEvent.KeyUp,WebInspector.UIString("Key Up")],[inputEvent.Click,WebInspector.UIString("Click")],[inputEvent.ContextMenu,WebInspector.UIString("Context Menu")],[inputEvent.MouseDown,WebInspector.UIString("Mouse Down")],[inputEvent.MouseMove,WebInspector.UIString("Mouse Move")],[inputEvent.MouseUp,WebInspector.UIString("Mouse Up")],[inputEvent.MouseWheel,WebInspector.UIString("Mouse Wheel")],[inputEvent.ScrollBegin,WebInspector.UIString("Scroll Begin")],[inputEvent.ScrollEnd,WebInspector.UIString("Scroll End")],[inputEvent.ScrollUpdate,WebInspector.UIString("Scroll Update")],[inputEvent.FlingStart,WebInspector.UIString("Fling Start")],[inputEvent.FlingCancel,WebInspector.UIString("Fling Halt")],[inputEvent.Tap,WebInspector.UIString("Tap")],[inputEvent.TapCancel,WebInspector.UIString("Tap Halt")],[inputEvent.ShowPress,WebInspector.UIString("Tap Begin")],[inputEvent.TapDown,WebInspector.UIString("Tap Down")],[inputEvent.TouchCancel,WebInspector.UIString("Touch Cancel")],[inputEvent.TouchEnd,WebInspector.UIString("Touch End")],[inputEvent.TouchMove,WebInspector.UIString("Touch Move")],[inputEvent.TouchStart,WebInspector.UIString("Touch Start")],[inputEvent.PinchBegin,WebInspector.UIString("Pinch Begin")],[inputEvent.PinchEnd,WebInspector.UIString("Pinch End")],[inputEvent.PinchUpdate,WebInspector.UIString("Pinch Update")]]);} return WebInspector.TimelineUIUtils._inputEventToDisplayName.get(inputEventType)||null;} WebInspector.TimelineUIUtils.testContentMatching=function(traceEvent,regExp) {var title=WebInspector.TimelineUIUtils.eventStyle(traceEvent).title;var tokens=[title];if(traceEvent.url) tokens.push(traceEvent.url);for(var argName in traceEvent.args){var argValue=traceEvent.args[argName];for(var key in argValue) tokens.push(argValue[key]);} return regExp.test(tokens.join("|"));} WebInspector.TimelineUIUtils.categoryForRecord=function(record) {return WebInspector.TimelineUIUtils.eventStyle(record.traceEvent()).category;} WebInspector.TimelineUIUtils.eventStyle=function(event) {var eventStyles=WebInspector.TimelineUIUtils._initEventStyles();if(event.hasCategory(WebInspector.TimelineModel.Category.Console)||event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return{title:event.name,category:WebInspector.TimelineUIUtils.categories()["scripting"]};if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)){var prefix="InputLatency::";var inputEventType=event.name.startsWith(prefix)?event.name.substr(prefix.length):event.name;var displayName=WebInspector.TimelineUIUtils.inputEventDisplayName((inputEventType));return{title:displayName||inputEventType,category:WebInspector.TimelineUIUtils.categories()["scripting"]};} var result=eventStyles[event.name];if(!result){result=new WebInspector.TimelineRecordStyle(event.name,WebInspector.TimelineUIUtils.categories()["other"],true);eventStyles[event.name]=result;} return result;} WebInspector.TimelineUIUtils.eventColor=function(event) {if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){var frame=event.args["data"];if(WebInspector.TimelineUIUtils.isUserFrame(frame)) return WebInspector.TimelineUIUtils.colorForURL(frame.url);} return WebInspector.TimelineUIUtils.eventStyle(event).category.color;} WebInspector.TimelineUIUtils.eventTitle=function(event) {var title=WebInspector.TimelineUIUtils.eventStyle(event).title;if(event.hasCategory(WebInspector.TimelineModel.Category.Console)) return title;if(event.name===WebInspector.TimelineModel.RecordType.TimeStamp) return WebInspector.UIString("%s: %s",title,event.args["data"]["message"]);if(event.name===WebInspector.TimelineModel.RecordType.Animation&&event.args["data"]&&event.args["data"]["name"]) return WebInspector.UIString("%s: %s",title,event.args["data"]["name"]);return title;} WebInspector.TimelineUIUtils.eventURL=function(event) {if(event.url) return event.url;var data=event.args["data"]||event.args["beginData"];return data&&data.url||null;} WebInspector.TimelineUIUtils._interactionPhaseStyles=function() {var map=WebInspector.TimelineUIUtils._interactionPhaseStylesMap;if(!map){map=new Map([[WebInspector.TimelineIRModel.Phases.Idle,{color:"white",label:"Idle"}],[WebInspector.TimelineIRModel.Phases.Response,{color:"hsl(43, 83%, 64%)",label:WebInspector.UIString("Response")}],[WebInspector.TimelineIRModel.Phases.Scroll,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Scroll")}],[WebInspector.TimelineIRModel.Phases.Fling,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Fling")}],[WebInspector.TimelineIRModel.Phases.Drag,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Drag")}],[WebInspector.TimelineIRModel.Phases.Animation,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Animation")}],[WebInspector.TimelineIRModel.Phases.Uncategorized,{color:"hsl(0, 0%, 87%)",label:WebInspector.UIString("Uncategorized")}]]);WebInspector.TimelineUIUtils._interactionPhaseStylesMap=map;} return map;} WebInspector.TimelineUIUtils.interactionPhaseColor=function(phase) {return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).color;} WebInspector.TimelineUIUtils.interactionPhaseLabel=function(phase) {return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).label;} WebInspector.TimelineUIUtils.isMarkerEvent=function(event) {var recordTypes=WebInspector.TimelineModel.RecordType;switch(event.name){case recordTypes.TimeStamp:case recordTypes.MarkFirstPaint:return true;case recordTypes.MarkDOMContent:case recordTypes.MarkLoad:return event.args["data"]["isMainFrame"];default:return false;}} WebInspector.TimelineUIUtils.isUserFrame=function(frame) {return frame.scriptId!=="0"&&!frame.url.startsWith("native ");} WebInspector.TimelineUIUtils.topStackFrame=function(event) {var stackTrace=event.stackTrace||event.initiator&&event.initiator.stackTrace;return stackTrace&&stackTrace.length?stackTrace[0]:null;} WebInspector.TimelineUIUtils.NetworkCategory={HTML:Symbol("HTML"),Script:Symbol("Script"),Style:Symbol("Style"),Media:Symbol("Media"),Other:Symbol("Other")} WebInspector.TimelineUIUtils.networkRequestCategory=function(request) {var categories=WebInspector.TimelineUIUtils.NetworkCategory;switch(request.mimeType){case"text/html":return categories.HTML;case"application/javascript":case"application/x-javascript":case"text/javascript":return categories.Script;case"text/css":return categories.Style;case"audio/ogg":case"image/gif":case"image/jpeg":case"image/png":case"image/svg+xml":case"image/webp":case"image/x-icon":case"font/opentype":case"font/woff2":case"application/font-woff":return categories.Media;default:return categories.Other;}} WebInspector.TimelineUIUtils.networkCategoryColor=function(category) {var categories=WebInspector.TimelineUIUtils.NetworkCategory;switch(category){case categories.HTML:return"hsl(214, 67%, 66%)";case categories.Script:return"hsl(43, 83%, 64%)";case categories.Style:return"hsl(256, 67%, 70%)";case categories.Media:return"hsl(109, 33%, 55%)";default:return"hsl(0, 0%, 70%)";}} WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent=function(event,target) {var recordType=WebInspector.TimelineModel.RecordType;var detailsText;var eventData=event.args["data"];switch(event.name){case recordType.GCEvent:case recordType.MajorGC:case recordType.MinorGC:var delta=event.args["usedHeapSizeBefore"]-event.args["usedHeapSizeAfter"];detailsText=WebInspector.UIString("%s collected",Number.bytesToString(delta));break;case recordType.FunctionCall:if(eventData&&eventData["scriptName"]) detailsText=linkifyLocationAsText(eventData["scriptId"],eventData["scriptLine"],0);break;case recordType.JSFrame:detailsText=WebInspector.beautifyFunctionName(eventData["functionName"]);break;case recordType.EventDispatch:detailsText=eventData?eventData["type"]:null;break;case recordType.Paint:var width=WebInspector.TimelineUIUtils.quadWidth(eventData.clip);var height=WebInspector.TimelineUIUtils.quadHeight(eventData.clip);if(width&&height) detailsText=WebInspector.UIString("%d\u2009\u00d7\u2009%d",width,height);break;case recordType.ParseHTML:var endLine=event.args["endData"]&&event.args["endData"]["endLine"];var url=WebInspector.displayNameForURL(event.args["beginData"]["url"]);detailsText=WebInspector.UIString("%s [%s\u2026%s]",url,event.args["beginData"]["startLine"]+1,endLine>=0?endLine+1:"");break;case recordType.CompileScript:case recordType.EvaluateScript:var url=eventData["url"];if(url) detailsText=WebInspector.displayNameForURL(url)+":"+eventData["lineNumber"];break;case recordType.ParseScriptOnBackground:case recordType.XHRReadyStateChange:case recordType.XHRLoad:var url=eventData["url"];if(url) detailsText=WebInspector.displayNameForURL(url);break;case recordType.WebSocketCreate:case recordType.WebSocketSendHandshakeRequest:case recordType.WebSocketReceiveHandshakeResponse:case recordType.WebSocketDestroy:case recordType.ResourceSendRequest:case recordType.ResourceReceivedData:case recordType.ResourceReceiveResponse:case recordType.ResourceFinish:case recordType.PaintImage:case recordType.DecodeImage:case recordType.ResizeImage:case recordType.DecodeLazyPixelRef:if(event.url) detailsText=WebInspector.displayNameForURL(event.url);break;case recordType.EmbedderCallback:detailsText=eventData["callbackName"];break;case recordType.Animation:detailsText=eventData&&eventData["name"];break;case recordType.GCIdleLazySweep:detailsText=WebInspector.UIString("idle sweep");break;case recordType.GCCompleteSweep:detailsText=WebInspector.UIString("complete sweep");break;case recordType.GCCollectGarbage:detailsText=WebInspector.UIString("collect");break;default:if(event.hasCategory(WebInspector.TimelineModel.Category.Console)) detailsText=null;else detailsText=linkifyTopCallFrameAsText();break;} return detailsText;function linkifyLocationAsText(scriptId,lineNumber,columnNumber) {var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);var rawLocation=target&&!target.isDetached()&&scriptId&&debuggerModel?debuggerModel.createRawLocationByScriptId(scriptId,lineNumber-1,(columnNumber||1)-1):null;if(!rawLocation) return null;var uiLocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);return uiLocation.linkText();} function linkifyTopCallFrameAsText() {var frame=WebInspector.TimelineUIUtils.topStackFrame(event);var text=frame?linkifyLocationAsText(frame.scriptId,frame.lineNumber,frame.columnNumber):null;if(frame&&!text){text=frame.url;if(typeof frame.lineNumber==="number") text+=":"+(frame.lineNumber+1);} return text;}} WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent=function(event,target,linkifier) {var recordType=WebInspector.TimelineModel.RecordType;var details;var detailsText;var eventData=event.args["data"];switch(event.name){case recordType.GCEvent:case recordType.MajorGC:case recordType.MinorGC:case recordType.EventDispatch:case recordType.Paint:case recordType.Animation:case recordType.EmbedderCallback:case recordType.ParseHTML:case recordType.WebSocketCreate:case recordType.WebSocketSendHandshakeRequest:case recordType.WebSocketReceiveHandshakeResponse:case recordType.WebSocketDestroy:case recordType.GCIdleLazySweep:case recordType.GCCompleteSweep:case recordType.GCCollectGarbage:detailsText=WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent(event,target);break;case recordType.PaintImage:case recordType.DecodeImage:case recordType.ResizeImage:case recordType.DecodeLazyPixelRef:case recordType.XHRReadyStateChange:case recordType.XHRLoad:case recordType.ResourceSendRequest:case recordType.ResourceReceivedData:case recordType.ResourceReceiveResponse:case recordType.ResourceFinish:if(event.url) details=WebInspector.linkifyResourceAsNode(event.url);break;case recordType.FunctionCall:details=linkifyLocation(eventData["scriptId"],eventData["scriptName"],eventData["scriptLine"],0);break;case recordType.JSFrame:details=createElement("span");details.createTextChild(WebInspector.beautifyFunctionName(eventData["functionName"]));var location=linkifyLocation(eventData["scriptId"],eventData["url"],eventData["lineNumber"],eventData["columnNumber"]);if(location){details.createTextChild(" @ ");details.appendChild(location);} break;case recordType.CompileScript:case recordType.EvaluateScript:var url=eventData["url"];if(url) details=linkifyLocation("",url,eventData["lineNumber"],0);break;case recordType.ParseScriptOnBackground:var url=eventData["url"];if(url) details=linkifyLocation("",url,0,0);break;default:if(event.hasCategory(WebInspector.TimelineModel.Category.Console)) detailsText=null;else details=linkifyTopCallFrame();break;} if(!details&&detailsText) details=createTextNode(detailsText);return details;function linkifyLocation(scriptId,url,lineNumber,columnNumber) {if(columnNumber) --columnNumber;return linkifier.linkifyScriptLocation(target,scriptId,url,lineNumber-1,columnNumber,"timeline-details");} function linkifyTopCallFrame() {var frame=WebInspector.TimelineUIUtils.topStackFrame(event);return frame?linkifier.linkifyConsoleCallFrame(target,frame,"timeline-details"):null;}} WebInspector.TimelineUIUtils.buildTraceEventDetails=function(event,model,linkifier,detailed,callback) {var target=model.target();if(!target){callbackWrapper();return;} var relatedNodes=null;var barrier=new CallbackBarrier();if(!event.previewElement){if(event.url) WebInspector.DOMPresentationUtils.buildImagePreviewContents(target,event.url,false,barrier.createCallback(saveImage));else if(event.picture) WebInspector.TimelineUIUtils.buildPicturePreviewContent(event,target,barrier.createCallback(saveImage));} var nodeIdsToResolve=new Set();if(event.backendNodeId) nodeIdsToResolve.add(event.backendNodeId);if(event.invalidationTrackingEvents) WebInspector.TimelineUIUtils._collectInvalidationNodeIds(nodeIdsToResolve,event.invalidationTrackingEvents);if(nodeIdsToResolve.size){var domModel=WebInspector.DOMModel.fromTarget(target);if(domModel) domModel.pushNodesByBackendIdsToFrontend(nodeIdsToResolve,barrier.createCallback(setRelatedNodeMap));} barrier.callWhenDone(callbackWrapper);function saveImage(element) {event.previewElement=element||null;} function setRelatedNodeMap(nodeMap) {relatedNodes=nodeMap;} function callbackWrapper() {callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously(event,model,linkifier,detailed,relatedNodes));}} WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously=function(event,model,linkifier,detailed,relatedNodesMap) {var stats={};var recordTypes=WebInspector.TimelineModel.RecordType;var relatedNodeLabel;var contentHelper=new WebInspector.TimelineDetailsContentHelper(model.target(),linkifier);contentHelper.addSection(WebInspector.TimelineUIUtils.eventTitle(event),WebInspector.TimelineUIUtils.eventStyle(event).category);var eventData=event.args["data"];var initiator=event.initiator;if(event.warning) contentHelper.appendWarningRow(event);if(event.name===recordTypes.JSFrame){var deoptReason=eventData["deoptReason"];if(deoptReason&&deoptReason!="no reason") contentHelper.appendWarningRow(event,WebInspector.TimelineModel.WarningType.V8Deopt);} if(detailed){contentHelper.appendTextRow(WebInspector.UIString("Self Time"),Number.millisToString(event.selfTime,true));contentHelper.appendTextRow(WebInspector.UIString("Total Time"),Number.millisToString(event.duration||0,true));} switch(event.name){case recordTypes.GCEvent:case recordTypes.MajorGC:case recordTypes.MinorGC:var delta=event.args["usedHeapSizeBefore"]-event.args["usedHeapSizeAfter"];contentHelper.appendTextRow(WebInspector.UIString("Collected"),Number.bytesToString(delta));break;case recordTypes.JSFrame:var detailsNode=WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event,model.target(),linkifier);if(detailsNode) contentHelper.appendElementRow(WebInspector.UIString("Function"),detailsNode);break;case recordTypes.TimerFire:case recordTypes.TimerInstall:case recordTypes.TimerRemove:contentHelper.appendTextRow(WebInspector.UIString("Timer ID"),eventData["timerId"]);if(event.name===recordTypes.TimerInstall){contentHelper.appendTextRow(WebInspector.UIString("Timeout"),Number.millisToString(eventData["timeout"]));contentHelper.appendTextRow(WebInspector.UIString("Repeats"),!eventData["singleShot"]);} break;case recordTypes.FireAnimationFrame:contentHelper.appendTextRow(WebInspector.UIString("Callback ID"),eventData["id"]);break;case recordTypes.FunctionCall:if(typeof eventData["functionName"]==="string") contentHelper.appendTextRow(WebInspector.UIString("Function"),WebInspector.beautifyFunctionName(eventData["functionName"]));if(eventData["scriptName"]) contentHelper.appendLocationRow(WebInspector.UIString("Location"),eventData["scriptName"],eventData["scriptLine"]);break;case recordTypes.ResourceSendRequest:case recordTypes.ResourceReceiveResponse:case recordTypes.ResourceReceivedData:case recordTypes.ResourceFinish:var url=(event.name===recordTypes.ResourceSendRequest)?eventData["url"]:initiator&&initiator.args["data"]["url"];if(url) contentHelper.appendElementRow(WebInspector.UIString("Resource"),WebInspector.linkifyResourceAsNode(url));if(eventData["requestMethod"]) contentHelper.appendTextRow(WebInspector.UIString("Request Method"),eventData["requestMethod"]);if(typeof eventData["statusCode"]==="number") contentHelper.appendTextRow(WebInspector.UIString("Status Code"),eventData["statusCode"]);if(eventData["mimeType"]) contentHelper.appendTextRow(WebInspector.UIString("MIME Type"),eventData["mimeType"]);if("priority"in eventData){var priority=WebInspector.uiLabelForPriority(eventData["priority"]);contentHelper.appendTextRow(WebInspector.UIString("Priority"),priority);} if(eventData["encodedDataLength"]) contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"),WebInspector.UIString("%d Bytes",eventData["encodedDataLength"]));break;case recordTypes.CompileScript:case recordTypes.EvaluateScript:var url=eventData["url"];if(url) contentHelper.appendLocationRow(WebInspector.UIString("Script"),url,eventData["lineNumber"],eventData["columnNumber"]);break;case recordTypes.Paint:var clip=eventData["clip"];contentHelper.appendTextRow(WebInspector.UIString("Location"),WebInspector.UIString("(%d, %d)",clip[0],clip[1]));var clipWidth=WebInspector.TimelineUIUtils.quadWidth(clip);var clipHeight=WebInspector.TimelineUIUtils.quadHeight(clip);contentHelper.appendTextRow(WebInspector.UIString("Dimensions"),WebInspector.UIString("%d × %d",clipWidth,clipHeight));case recordTypes.PaintSetup:case recordTypes.Rasterize:case recordTypes.ScrollLayer:relatedNodeLabel=WebInspector.UIString("Layer Root");break;case recordTypes.PaintImage:case recordTypes.DecodeLazyPixelRef:case recordTypes.DecodeImage:case recordTypes.ResizeImage:case recordTypes.DrawLazyPixelRef:relatedNodeLabel=WebInspector.UIString("Owner Element");if(event.url) contentHelper.appendElementRow(WebInspector.UIString("Image URL"),WebInspector.linkifyResourceAsNode(event.url));break;case recordTypes.ParseAuthorStyleSheet:var url=eventData["styleSheetUrl"];if(url) contentHelper.appendElementRow(WebInspector.UIString("Stylesheet URL"),WebInspector.linkifyResourceAsNode(url));break;case recordTypes.UpdateLayoutTree:case recordTypes.RecalculateStyles:contentHelper.appendTextRow(WebInspector.UIString("Elements Affected"),event.args["elementCount"]);break;case recordTypes.Layout:var beginData=event.args["beginData"];contentHelper.appendTextRow(WebInspector.UIString("Nodes That Need Layout"),beginData["dirtyObjects"]);relatedNodeLabel=WebInspector.UIString("Layout root");break;case recordTypes.ConsoleTime:contentHelper.appendTextRow(WebInspector.UIString("Message"),event.name);break;case recordTypes.WebSocketCreate:case recordTypes.WebSocketSendHandshakeRequest:case recordTypes.WebSocketReceiveHandshakeResponse:case recordTypes.WebSocketDestroy:var initiatorData=initiator?initiator.args["data"]:eventData;if(typeof initiatorData["webSocketURL"]!=="undefined") contentHelper.appendTextRow(WebInspector.UIString("URL"),initiatorData["webSocketURL"]);if(typeof initiatorData["webSocketProtocol"]!=="undefined") contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"),initiatorData["webSocketProtocol"]);if(typeof eventData["message"]!=="undefined") contentHelper.appendTextRow(WebInspector.UIString("Message"),eventData["message"]);break;case recordTypes.EmbedderCallback:contentHelper.appendTextRow(WebInspector.UIString("Callback Function"),eventData["callbackName"]);break;case recordTypes.Animation:if(event.phase===WebInspector.TracingModel.Phase.NestableAsyncInstant) contentHelper.appendTextRow(WebInspector.UIString("State"),eventData["state"]);break;case recordTypes.ParseHTML:var beginData=event.args["beginData"];var url=beginData["url"];var startLine=beginData["startLine"]+1;var endLine=event.args["endData"]?event.args["endData"]["endLine"]+1:0;if(url) contentHelper.appendLocationRange(WebInspector.UIString("Range"),url,startLine,endLine);break;case recordTypes.FireIdleCallback:contentHelper.appendTextRow(WebInspector.UIString("Allotted Time"),Number.millisToString(eventData["allottedMilliseconds"]));contentHelper.appendTextRow(WebInspector.UIString("Invoked by Timeout"),eventData["timedOut"]);case recordTypes.RequestIdleCallback:case recordTypes.CancelIdleCallback:contentHelper.appendTextRow(WebInspector.UIString("Callback ID"),eventData["id"]);break;case recordTypes.EventDispatch:contentHelper.appendTextRow(WebInspector.UIString("Type"),eventData["type"]);break;default:var detailsNode=WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event,model.target(),linkifier);if(detailsNode) contentHelper.appendElementRow(WebInspector.UIString("Details"),detailsNode);break;} if(event.timeWaitingForMainThread) contentHelper.appendTextRow(WebInspector.UIString("Time Waiting for Main Thread"),Number.millisToString(event.timeWaitingForMainThread,true));var relatedNode=relatedNodesMap&&relatedNodesMap.get(event.backendNodeId);if(relatedNode) contentHelper.appendElementRow(relatedNodeLabel||WebInspector.UIString("Related Node"),WebInspector.DOMPresentationUtils.linkifyNodeReference(relatedNode));if(event.previewElement){contentHelper.addSection(WebInspector.UIString("Preview"));contentHelper.appendElementRow("",event.previewElement);} if(event.stackTrace||(event.initiator&&event.initiator.stackTrace)||event.invalidationTrackingEvents) WebInspector.TimelineUIUtils._generateCauses(event,model.target(),relatedNodesMap,contentHelper);var showPieChart=detailed&&WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(stats,model,event);if(showPieChart){contentHelper.addSection(WebInspector.UIString("Aggregated Time"));var pieChart=WebInspector.TimelineUIUtils.generatePieChart(stats,WebInspector.TimelineUIUtils.eventStyle(event).category,event.selfTime);contentHelper.appendElementRow("",pieChart);} return contentHelper.fragment;} WebInspector.TimelineUIUtils._aggregatedStatsKey=Symbol("aggregatedStats");WebInspector.TimelineUIUtils.buildRangeStats=function(model,startTime,endTime) {var aggregatedStats={};function compareEndTime(value,task) {return value<task.endTime()?-1:1;} var mainThreadTasks=model.mainThreadTasks();var taskIndex=mainThreadTasks.lowerBound(startTime,compareEndTime);for(;taskIndex<mainThreadTasks.length;++taskIndex){var task=mainThreadTasks[taskIndex];if(task.startTime()>endTime) break;if(task.startTime()>startTime&&task.endTime()<endTime){var taskStats=task[WebInspector.TimelineUIUtils._aggregatedStatsKey];if(!taskStats){taskStats={};WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task,startTime,endTime,taskStats);task[WebInspector.TimelineUIUtils._aggregatedStatsKey]=taskStats;} for(var key in taskStats) aggregatedStats[key]=(aggregatedStats[key]||0)+taskStats[key];continue;} WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task,startTime,endTime,aggregatedStats);} var aggregatedTotal=0;for(var categoryName in aggregatedStats) aggregatedTotal+=aggregatedStats[categoryName];aggregatedStats["idle"]=Math.max(0,endTime-startTime-aggregatedTotal);var startOffset=startTime-model.minimumRecordTime();var endOffset=endTime-model.minimumRecordTime();var contentHelper=new WebInspector.TimelineDetailsContentHelper(null,null);contentHelper.addSection(WebInspector.UIString("Range: %s \u2013 %s",Number.millisToString(startOffset),Number.millisToString(endOffset)));var pieChart=WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats);contentHelper.appendElementRow("",pieChart);return contentHelper.fragment;} WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord=function(record,startTime,endTime,aggregatedStats) {var records=[];if(!record.endTime()||record.endTime()<startTime||record.startTime()>endTime) return;var childrenTime=0;var children=record.children()||[];for(var i=0;i<children.length;++i){var child=children[i];if(!child.endTime()||child.endTime()<startTime||child.startTime()>endTime) continue;childrenTime+=Math.min(endTime,child.endTime())-Math.max(startTime,child.startTime());WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(child,startTime,endTime,aggregatedStats);} var categoryName=WebInspector.TimelineUIUtils.categoryForRecord(record).name;var ownTime=Math.min(endTime,record.endTime())-Math.max(startTime,record.startTime())-childrenTime;aggregatedStats[categoryName]=(aggregatedStats[categoryName]||0)+ownTime;} WebInspector.TimelineUIUtils.buildNetworkRequestDetails=function(request,model,linkifier) {var target=model.target();var contentHelper=new WebInspector.TimelineDetailsContentHelper(target,linkifier);var duration=request.endTime-(request.startTime||-Infinity);var items=[];if(request.url) contentHelper.appendElementRow(WebInspector.UIString("URL"),WebInspector.linkifyURLAsNode(request.url));if(isFinite(duration)) contentHelper.appendTextRow(WebInspector.UIString("Duration"),Number.millisToString(duration,true));if(request.requestMethod) contentHelper.appendTextRow(WebInspector.UIString("Request Method"),request.requestMethod);if(typeof request.priority==="string"){var priority=WebInspector.uiLabelForPriority((request.priority));contentHelper.appendTextRow(WebInspector.UIString("Priority"),priority);} if(request.mimeType) contentHelper.appendTextRow(WebInspector.UIString("Mime Type"),request.mimeType);var title=WebInspector.UIString("Initiator");var sendRequest=request.children[0];var topFrame=WebInspector.TimelineUIUtils.topStackFrame(sendRequest);if(topFrame){contentHelper.appendElementRow(title,linkifier.linkifyConsoleCallFrame(target,topFrame));}else if(sendRequest.initiator){var initiatorURL=WebInspector.TimelineUIUtils.eventURL(sendRequest.initiator);if(initiatorURL) contentHelper.appendElementRow(title,linkifier.linkifyScriptLocation(target,null,initiatorURL,0));} function action(fulfill) {WebInspector.DOMPresentationUtils.buildImagePreviewContents((target),request.url,false,saveImage);function saveImage(element) {request.previewElement=element||null;fulfill(request.previewElement);}} var previewPromise;if(request.previewElement) previewPromise=Promise.resolve(request.previewElement);else previewPromise=request.url&&target?new Promise(action):Promise.resolve(null);function appendPreview(element) {if(element) contentHelper.appendElementRow(WebInspector.UIString("Preview"),request.previewElement);return contentHelper.fragment;} return previewPromise.then(appendPreview);} WebInspector.TimelineUIUtils._stackTraceFromCallFrames=function(callFrames) {return({callFrames:callFrames});} WebInspector.TimelineUIUtils._generateCauses=function(event,target,relatedNodesMap,contentHelper) {var recordTypes=WebInspector.TimelineModel.RecordType;var callSiteStackLabel;var stackLabel;var initiator=event.initiator;switch(event.name){case recordTypes.TimerFire:callSiteStackLabel=WebInspector.UIString("Timer Installed");break;case recordTypes.FireAnimationFrame:callSiteStackLabel=WebInspector.UIString("Animation Frame Requested");break;case recordTypes.FireIdleCallback:callSiteStackLabel=WebInspector.UIString("Idle Callback Requested");break;case recordTypes.UpdateLayoutTree:case recordTypes.RecalculateStyles:stackLabel=WebInspector.UIString("Recalculation Forced");break;case recordTypes.Layout:callSiteStackLabel=WebInspector.UIString("First Layout Invalidation");stackLabel=WebInspector.UIString("Layout Forced");break;} if(event.stackTrace&&event.stackTrace.length){contentHelper.addSection(WebInspector.UIString("Call Stacks"));contentHelper.appendStackTrace(stackLabel||WebInspector.UIString("Stack Trace"),WebInspector.TimelineUIUtils._stackTraceFromCallFrames(event.stackTrace));} if(event.invalidationTrackingEvents&&target){contentHelper.addSection(WebInspector.UIString("Invalidations"));WebInspector.TimelineUIUtils._generateInvalidations(event,target,relatedNodesMap,contentHelper);}else if(initiator&&initiator.stackTrace){contentHelper.appendStackTrace(callSiteStackLabel||WebInspector.UIString("First Invalidated"),WebInspector.TimelineUIUtils._stackTraceFromCallFrames(initiator.stackTrace));}} WebInspector.TimelineUIUtils._generateInvalidations=function(event,target,relatedNodesMap,contentHelper) {if(!event.invalidationTrackingEvents) return;var invalidations={};event.invalidationTrackingEvents.forEach(function(invalidation){if(!invalidations[invalidation.type]) invalidations[invalidation.type]=[invalidation];else invalidations[invalidation.type].push(invalidation);});Object.keys(invalidations).forEach(function(type){WebInspector.TimelineUIUtils._generateInvalidationsForType(type,target,invalidations[type],relatedNodesMap,contentHelper);});} WebInspector.TimelineUIUtils._generateInvalidationsForType=function(type,target,invalidations,relatedNodesMap,contentHelper) {var title;switch(type){case WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking:title=WebInspector.UIString("Style Invalidations");break;case WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking:title=WebInspector.UIString("Layout Invalidations");break;default:title=WebInspector.UIString("Other Invalidations");break;} var invalidationsTreeOutline=new TreeOutlineInShadow();invalidationsTreeOutline.registerRequiredCSS("timeline/invalidationsTree.css");invalidationsTreeOutline.element.classList.add("invalidations-tree");var invalidationGroups=groupInvalidationsByCause(invalidations);invalidationGroups.forEach(function(group){var groupElement=new WebInspector.TimelineUIUtils.InvalidationsGroupElement(target,relatedNodesMap,contentHelper,group);invalidationsTreeOutline.appendChild(groupElement);});contentHelper.appendElementRow(title,invalidationsTreeOutline.element,false,true);function groupInvalidationsByCause(invalidations) {var causeToInvalidationMap={};for(var index=0;index<invalidations.length;index++){var invalidation=invalidations[index];var causeKey="";if(invalidation.cause.reason) causeKey+=invalidation.cause.reason+".";if(invalidation.cause.stackTrace){invalidation.cause.stackTrace.forEach(function(stackFrame){causeKey+=stackFrame["functionName"]+".";causeKey+=stackFrame["scriptId"]+".";causeKey+=stackFrame["url"]+".";causeKey+=stackFrame["lineNumber"]+".";causeKey+=stackFrame["columnNumber"]+".";});} if(causeToInvalidationMap[causeKey]) causeToInvalidationMap[causeKey].push(invalidation);else causeToInvalidationMap[causeKey]=[invalidation];} return Object.values(causeToInvalidationMap);}} WebInspector.TimelineUIUtils._collectInvalidationNodeIds=function(nodeIds,invalidations) {for(var i=0;i<invalidations.length;++i){if(invalidations[i].nodeId) nodeIds.add(invalidations[i].nodeId);}} WebInspector.TimelineUIUtils.InvalidationsGroupElement=function(target,relatedNodesMap,contentHelper,invalidations) {TreeElement.call(this,"",true);this.listItemElement.classList.add("header");this.selectable=false;this.toggleOnClick=true;this._relatedNodesMap=relatedNodesMap;this._contentHelper=contentHelper;this._invalidations=invalidations;this.title=this._createTitle(target);} WebInspector.TimelineUIUtils.InvalidationsGroupElement.prototype={_createTitle:function(target) {var first=this._invalidations[0];var reason=first.cause.reason;var topFrame=first.cause.stackTrace&&first.cause.stackTrace[0];var title=createElement("span");if(reason) title.createTextChild(WebInspector.UIString("%s for ",reason));else title.createTextChild(WebInspector.UIString("Unknown cause for "));this._appendTruncatedNodeList(title,this._invalidations);if(topFrame&&this._contentHelper.linkifier()){title.createTextChild(WebInspector.UIString(". "));var stack=title.createChild("span","monospace");stack.createChild("span").textContent=WebInspector.beautifyFunctionName(topFrame.functionName);stack.createChild("span").textContent=" @ ";stack.createChild("span").appendChild(this._contentHelper.linkifier().linkifyConsoleCallFrame(target,topFrame));} return title;},onpopulate:function() {var content=createElementWithClass("div","content");var first=this._invalidations[0];if(first.cause.stackTrace){var stack=content.createChild("div");stack.createTextChild(WebInspector.UIString("Stack trace:"));this._contentHelper.createChildStackTraceElement(stack,WebInspector.TimelineUIUtils._stackTraceFromCallFrames(first.cause.stackTrace));} content.createTextChild(this._invalidations.length>1?WebInspector.UIString("Nodes:"):WebInspector.UIString("Node:"));var nodeList=content.createChild("div","node-list");var firstNode=true;for(var i=0;i<this._invalidations.length;i++){var invalidation=this._invalidations[i];var invalidationNode=this._createInvalidationNode(invalidation,true);if(invalidationNode){if(!firstNode) nodeList.createTextChild(WebInspector.UIString(", "));firstNode=false;nodeList.appendChild(invalidationNode);var extraData=invalidation.extraData?", "+invalidation.extraData:"";if(invalidation.changedId) nodeList.createTextChild(WebInspector.UIString("(changed id to \"%s\"%s)",invalidation.changedId,extraData));else if(invalidation.changedClass) nodeList.createTextChild(WebInspector.UIString("(changed class to \"%s\"%s)",invalidation.changedClass,extraData));else if(invalidation.changedAttribute) nodeList.createTextChild(WebInspector.UIString("(changed attribute to \"%s\"%s)",invalidation.changedAttribute,extraData));else if(invalidation.changedPseudo) nodeList.createTextChild(WebInspector.UIString("(changed pesudo to \"%s\"%s)",invalidation.changedPseudo,extraData));else if(invalidation.selectorPart) nodeList.createTextChild(WebInspector.UIString("(changed \"%s\"%s)",invalidation.selectorPart,extraData));}} var contentTreeElement=new TreeElement(content,false);contentTreeElement.selectable=false;this.appendChild(contentTreeElement);},_appendTruncatedNodeList:function(parentElement,invalidations) {var invalidationNodes=[];var invalidationNodeIdMap={};for(var i=0;i<invalidations.length;i++){var invalidation=invalidations[i];var invalidationNode=this._createInvalidationNode(invalidation,false);invalidationNode.addEventListener("click",consumeEvent,false);if(invalidationNode&&!invalidationNodeIdMap[invalidation.nodeId]){invalidationNodes.push(invalidationNode);invalidationNodeIdMap[invalidation.nodeId]=true;}} if(invalidationNodes.length===1){parentElement.appendChild(invalidationNodes[0]);}else if(invalidationNodes.length===2){parentElement.appendChild(invalidationNodes[0]);parentElement.createTextChild(WebInspector.UIString(" and "));parentElement.appendChild(invalidationNodes[1]);}else if(invalidationNodes.length>=3){parentElement.appendChild(invalidationNodes[0]);parentElement.createTextChild(WebInspector.UIString(", "));parentElement.appendChild(invalidationNodes[1]);parentElement.createTextChild(WebInspector.UIString(", and %s others",invalidationNodes.length-2));}},_createInvalidationNode:function(invalidation,showUnknownNodes) {var node=(invalidation.nodeId&&this._relatedNodesMap)?this._relatedNodesMap.get(invalidation.nodeId):null;if(node) return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);if(invalidation.nodeName){var nodeSpan=createElement("span");nodeSpan.textContent=WebInspector.UIString("[ %s ]",invalidation.nodeName);return nodeSpan;} if(showUnknownNodes){var nodeSpan=createElement("span");return nodeSpan.createTextChild(WebInspector.UIString("[ unknown node ]"));}},__proto__:TreeElement.prototype} WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent=function(total,model,event) {var events=model.inspectedTargetEvents();function eventComparator(startTime,e) {return startTime-e.startTime;} var index=events.binaryIndexOf(event.startTime,eventComparator);if(index<0) return false;var hasChildren=false;var endTime=event.endTime;if(endTime){for(var i=index;i<events.length;i++){var nextEvent=events[i];if(nextEvent.startTime>=endTime) break;if(!nextEvent.selfTime) continue;if(nextEvent.thread!==event.thread) continue;if(i>index) hasChildren=true;var categoryName=WebInspector.TimelineUIUtils.eventStyle(nextEvent).category.name;total[categoryName]=(total[categoryName]||0)+nextEvent.selfTime;}} if(WebInspector.TracingModel.isAsyncPhase(event.phase)){if(event.endTime){var aggregatedTotal=0;for(var categoryName in total) aggregatedTotal+=total[categoryName];total["idle"]=Math.max(0,event.endTime-event.startTime-aggregatedTotal);} return false;} return hasChildren;} WebInspector.TimelineUIUtils.buildPicturePreviewContent=function(event,target,callback) {new WebInspector.LayerPaintEvent(event,target).loadSnapshot(onSnapshotLoaded);function onSnapshotLoaded(rect,snapshot) {if(!snapshot){callback();return;} snapshot.requestImage(null,null,1,onGotImage);snapshot.dispose();} function onGotImage(imageURL) {if(!imageURL){callback();return;} var container=createElement("div");container.classList.add("image-preview-container","vbox","link");var img=container.createChild("img");img.src=imageURL;var paintProfilerButton=container.createChild("a");paintProfilerButton.textContent=WebInspector.UIString("Paint Profiler");container.addEventListener("click",showPaintProfiler,false);callback(container);} function showPaintProfiler() {WebInspector.TimelinePanel.instance().select(WebInspector.TimelineSelection.fromTraceEvent(event),WebInspector.TimelinePanel.DetailsTab.PaintProfiler);}} WebInspector.TimelineUIUtils.createEventDivider=function(recordType,title,position) {var eventDivider=createElement("div");eventDivider.className="resources-event-divider";var recordTypes=WebInspector.TimelineModel.RecordType;if(recordType===recordTypes.MarkDOMContent) eventDivider.className+=" resources-blue-divider";else if(recordType===recordTypes.MarkLoad) eventDivider.className+=" resources-red-divider";else if(recordType===recordTypes.MarkFirstPaint) eventDivider.className+=" resources-green-divider";else if(recordType===recordTypes.TimeStamp||recordType===recordTypes.ConsoleTime||recordType===recordTypes.UserTiming) eventDivider.className+=" resources-orange-divider";else if(recordType===recordTypes.BeginFrame) eventDivider.className+=" timeline-frame-divider";if(title) eventDivider.title=title;eventDivider.style.left=position+"px";return eventDivider;} WebInspector.TimelineUIUtils.createDividerForRecord=function(record,zeroTime,position) {var startTime=Number.millisToString(record.startTime()-zeroTime);var title=WebInspector.UIString("%s at %s",WebInspector.TimelineUIUtils.eventTitle(record.traceEvent()),startTime);return WebInspector.TimelineUIUtils.createEventDivider(record.type(),title,position);} WebInspector.TimelineUIUtils._visibleTypes=function() {var eventStyles=WebInspector.TimelineUIUtils._initEventStyles();var result=[];for(var name in eventStyles){if(!eventStyles[name].hidden) result.push(name);} return result;} WebInspector.TimelineUIUtils.visibleEventsFilter=function() {return new WebInspector.TimelineVisibleEventsFilter(WebInspector.TimelineUIUtils._visibleTypes());} WebInspector.TimelineUIUtils.categories=function() {if(WebInspector.TimelineUIUtils._categories) return WebInspector.TimelineUIUtils._categories;WebInspector.TimelineUIUtils._categories={loading:new WebInspector.TimelineCategory("loading",WebInspector.UIString("Loading"),true,"hsl(214, 67%, 74%)","hsl(214, 67%, 66%)"),scripting:new WebInspector.TimelineCategory("scripting",WebInspector.UIString("Scripting"),true,"hsl(43, 83%, 72%)","hsl(43, 83%, 64%) "),rendering:new WebInspector.TimelineCategory("rendering",WebInspector.UIString("Rendering"),true,"hsl(256, 67%, 76%)","hsl(256, 67%, 70%)"),painting:new WebInspector.TimelineCategory("painting",WebInspector.UIString("Painting"),true,"hsl(109, 33%, 64%)","hsl(109, 33%, 55%)"),gpu:new WebInspector.TimelineCategory("gpu",WebInspector.UIString("GPU"),false,"hsl(109, 33%, 64%)","hsl(109, 33%, 55%)"),other:new WebInspector.TimelineCategory("other",WebInspector.UIString("Other"),false,"hsl(0, 0%, 87%)","hsl(0, 0%, 79%)"),idle:new WebInspector.TimelineCategory("idle",WebInspector.UIString("Idle"),false,"hsl(0, 100%, 100%)","hsl(0, 100%, 100%)")};return WebInspector.TimelineUIUtils._categories;};WebInspector.AsyncEventGroup=function(title) {this.title=title;} WebInspector.TimelineUIUtils.asyncEventGroups=function() {if(WebInspector.TimelineUIUtils._asyncEventGroups) return WebInspector.TimelineUIUtils._asyncEventGroups;WebInspector.TimelineUIUtils._asyncEventGroups={animation:new WebInspector.AsyncEventGroup(WebInspector.UIString("Animation")),console:new WebInspector.AsyncEventGroup(WebInspector.UIString("Console")),userTiming:new WebInspector.AsyncEventGroup(WebInspector.UIString("User Timing")),input:new WebInspector.AsyncEventGroup(WebInspector.UIString("Input Events"))};return WebInspector.TimelineUIUtils._asyncEventGroups;} WebInspector.TimelineUIUtils.generatePieChart=function(aggregatedStats,selfCategory,selfTime) {var total=0;for(var categoryName in aggregatedStats) total+=aggregatedStats[categoryName];var element=createElementWithClass("div","timeline-details-view-pie-chart-wrapper hbox");var pieChart=new WebInspector.PieChart(100);pieChart.element.classList.add("timeline-details-view-pie-chart");pieChart.setTotal(total);var pieChartContainer=element.createChild("div","vbox");pieChartContainer.appendChild(pieChart.element);pieChartContainer.createChild("div","timeline-details-view-pie-chart-total").textContent=WebInspector.UIString("Total: %s",Number.millisToString(total,true));var footerElement=element.createChild("div","timeline-aggregated-info-legend");function appendLegendRow(name,title,value,color) {if(!value) return;pieChart.addSlice(value,color);var rowElement=footerElement.createChild("div");rowElement.createChild("span","timeline-aggregated-legend-value").textContent=Number.preciseMillisToString(value,1);rowElement.createChild("span","timeline-aggregated-legend-swatch").style.backgroundColor=color;rowElement.createChild("span","timeline-aggregated-legend-title").textContent=title;} if(selfCategory){if(selfTime) appendLegendRow(selfCategory.name,WebInspector.UIString("%s (self)",selfCategory.title),selfTime,selfCategory.color);var categoryTime=aggregatedStats[selfCategory.name];var value=categoryTime-selfTime;if(value>0) appendLegendRow(selfCategory.name,WebInspector.UIString("%s (children)",selfCategory.title),value,selfCategory.childColor);} for(var categoryName in WebInspector.TimelineUIUtils.categories()){var category=WebInspector.TimelineUIUtils.categories()[categoryName];if(category===selfCategory) continue;appendLegendRow(category.name,category.title,aggregatedStats[category.name],category.childColor);} return element;} WebInspector.TimelineUIUtils.generateDetailsContentForFrame=function(frameModel,frame,filmStripFrame) {var pieChart=WebInspector.TimelineUIUtils.generatePieChart(frame.timeByCategory);var contentHelper=new WebInspector.TimelineDetailsContentHelper(null,null);contentHelper.addSection(WebInspector.UIString("Frame"));var duration=WebInspector.TimelineUIUtils.frameDuration(frame);contentHelper.appendElementRow(WebInspector.UIString("Duration"),duration,frame.hasWarnings());if(filmStripFrame){var filmStripPreview=createElementWithClass("img","timeline-filmstrip-preview");filmStripFrame.imageDataPromise().then(onGotImageData.bind(null,filmStripPreview));contentHelper.appendElementRow("",filmStripPreview);filmStripPreview.addEventListener("click",frameClicked.bind(null,filmStripFrame),false);} var durationInMillis=frame.endTime-frame.startTime;contentHelper.appendTextRow(WebInspector.UIString("FPS"),Math.floor(1000/durationInMillis));contentHelper.appendTextRow(WebInspector.UIString("CPU time"),Number.millisToString(frame.cpuTime,true));if(Runtime.experiments.isEnabled("layersPanel")&&frame.layerTree){contentHelper.appendElementRow(WebInspector.UIString("Layer tree"),WebInspector.Linkifier.linkifyUsingRevealer(frame.layerTree,WebInspector.UIString("show")));} function onGotImageData(image,data) {if(data) image.src="data:image/jpg;base64,"+data;} function frameClicked(filmStripFrame) {new WebInspector.FilmStripView.Dialog(filmStripFrame,0);} return contentHelper.fragment;} WebInspector.TimelineUIUtils.frameDuration=function(frame) {var durationText=WebInspector.UIString("%s (at %s)",Number.millisToString(frame.endTime-frame.startTime,true),Number.millisToString(frame.startTimeOffset,true));var element=createElement("span");element.createTextChild(durationText);if(!frame.hasWarnings()) return element;element.createTextChild(WebInspector.UIString(". Long frame times are an indication of "));element.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/web/fundamentals/performance/rendering/",WebInspector.UIString("jank"),undefined,true));element.createTextChild(".");return element;} WebInspector.TimelineUIUtils.createFillStyle=function(context,width,height,color0,color1,color2) {var gradient=context.createLinearGradient(0,0,width,height);gradient.addColorStop(0,color0);gradient.addColorStop(0.25,color1);gradient.addColorStop(0.75,color1);gradient.addColorStop(1,color2);return gradient;} WebInspector.TimelineUIUtils.quadWidth=function(quad) {return Math.round(Math.sqrt(Math.pow(quad[0]-quad[2],2)+Math.pow(quad[1]-quad[3],2)));} WebInspector.TimelineUIUtils.quadHeight=function(quad) {return Math.round(Math.sqrt(Math.pow(quad[0]-quad[6],2)+Math.pow(quad[1]-quad[7],2)));} WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor=function(priority,color,eventTypes) {this.priority=priority;this.color=color;this.eventTypes=eventTypes;} WebInspector.TimelineUIUtils.eventDispatchDesciptors=function() {if(WebInspector.TimelineUIUtils._eventDispatchDesciptors) return WebInspector.TimelineUIUtils._eventDispatchDesciptors;var lightOrange="hsl(40,100%,80%)";var orange="hsl(40,100%,50%)";var green="hsl(90,100%,40%)";var purple="hsl(256,100%,75%)";WebInspector.TimelineUIUtils._eventDispatchDesciptors=[new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1,lightOrange,["mousemove","mouseenter","mouseleave","mouseout","mouseover"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1,lightOrange,["pointerover","pointerout","pointerenter","pointerleave","pointermove"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(2,green,["wheel"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["click","mousedown","mouseup"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["touchstart","touchend","touchmove","touchcancel"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["pointerdown","pointerup","pointercancel","gotpointercapture","lostpointercapture"]),new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,purple,["keydown","keyup","keypress"])];return WebInspector.TimelineUIUtils._eventDispatchDesciptors;} WebInspector.TimelineCategory=function(name,title,visible,childColor,color) {this.name=name;this.title=title;this.visible=visible;this.childColor=childColor;this.color=color;this.hidden=false;} WebInspector.TimelineCategory.Events={VisibilityChanged:"VisibilityChanged"};WebInspector.TimelineCategory.prototype={get hidden() {return this._hidden;},set hidden(hidden) {this._hidden=hidden;this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged,this);},__proto__:WebInspector.Object.prototype} WebInspector.TimelineMarkerStyle;WebInspector.TimelineUIUtils.markerStyleForEvent=function(event) {var red="rgb(255, 0, 0)";var blue="rgb(0, 0, 255)";var orange="rgb(255, 178, 23)";var green="rgb(0, 130, 0)";var tallMarkerDashStyle=[10,5];var title=WebInspector.TimelineUIUtils.eventTitle(event) if(event.hasCategory(WebInspector.TimelineModel.Category.Console)||event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)){return{title:title,dashStyle:tallMarkerDashStyle,lineWidth:0.5,color:orange,tall:false,lowPriority:false,};} var recordTypes=WebInspector.TimelineModel.RecordType;var tall=false;var color=green;switch(event.name){case recordTypes.MarkDOMContent:color=blue;tall=true;break;case recordTypes.MarkLoad:color=red;tall=true;break;case recordTypes.MarkFirstPaint:color=green;tall=true;break;case recordTypes.TimeStamp:color=orange;break;} return{title:title,dashStyle:tallMarkerDashStyle,lineWidth:0.5,color:color,tall:tall,lowPriority:false,};} WebInspector.TimelineUIUtils.markerStyleForFrame=function() {return{title:WebInspector.UIString("Frame"),color:"rgba(100, 100, 100, 0.4)",lineWidth:3,dashStyle:[3],tall:true,lowPriority:true};} WebInspector.TimelineUIUtils.colorForURL=function(url) {if(!WebInspector.TimelineUIUtils.colorForURL._colorGenerator){WebInspector.TimelineUIUtils.colorForURL._colorGenerator=new WebInspector.FlameChart.ColorGenerator({min:30,max:330},{min:50,max:80,count:3},85);} return WebInspector.TimelineUIUtils.colorForURL._colorGenerator.colorForID(url);} WebInspector.TimelinePopupContentHelper=function(title) {this._contentTable=createElement("table");var titleCell=this._createCell(WebInspector.UIString("%s - Details",title),"timeline-details-title");titleCell.colSpan=2;var titleRow=createElement("tr");titleRow.appendChild(titleCell);this._contentTable.appendChild(titleRow);} WebInspector.TimelinePopupContentHelper.prototype={contentTable:function() {return this._contentTable;},_createCell:function(content,styleName) {var text=createElement("label");text.createTextChild(String(content));var cell=createElement("td");cell.className="timeline-details";if(styleName) cell.className+=" "+styleName;cell.textContent=content;return cell;},appendTextRow:function(title,content) {var row=createElement("tr");row.appendChild(this._createCell(title,"timeline-details-row-title"));row.appendChild(this._createCell(content,"timeline-details-row-data"));this._contentTable.appendChild(row);},appendElementRow:function(title,content) {var row=createElement("tr");var titleCell=this._createCell(title,"timeline-details-row-title");row.appendChild(titleCell);var cell=createElement("td");cell.className="details";if(content instanceof Node) cell.appendChild(content);else cell.createTextChild(content||"");row.appendChild(cell);this._contentTable.appendChild(row);}} WebInspector.TimelineDetailsContentHelper=function(target,linkifier) {this.fragment=createDocumentFragment();this._linkifier=linkifier;this._target=target;this.element=createElementWithClass("div","timeline-details-view-block");this._tableElement=this.element.createChild("div","vbox timeline-details-chip-body");this.fragment.appendChild(this.element);} WebInspector.TimelineDetailsContentHelper.prototype={addSection:function(title,category) {if(!this._tableElement.hasChildNodes()){this.element.removeChildren();}else{this.element=createElementWithClass("div","timeline-details-view-block");this.fragment.appendChild(this.element);} if(title){var titleElement=this.element.createChild("div","timeline-details-chip-title");if(category) titleElement.createChild("div").style.backgroundColor=category.color;titleElement.createTextChild(title);} this._tableElement=this.element.createChild("div","vbox timeline-details-chip-body");this.fragment.appendChild(this.element);},linkifier:function() {return this._linkifier;},appendTextRow:function(title,value) {var rowElement=this._tableElement.createChild("div","timeline-details-view-row");rowElement.createChild("div","timeline-details-view-row-title").textContent=title;rowElement.createChild("div","timeline-details-view-row-value").textContent=value;},appendElementRow:function(title,content,isWarning,isStacked) {var rowElement=this._tableElement.createChild("div","timeline-details-view-row");if(isWarning) rowElement.classList.add("timeline-details-warning");if(isStacked) rowElement.classList.add("timeline-details-stack-values");var titleElement=rowElement.createChild("div","timeline-details-view-row-title");titleElement.textContent=title;var valueElement=rowElement.createChild("div","timeline-details-view-row-value");if(content instanceof Node) valueElement.appendChild(content);else valueElement.createTextChild(content||"");},appendLocationRow:function(title,url,startLine,startColumn) {if(!this._linkifier||!this._target) return;if(startColumn) --startColumn;this.appendElementRow(title,this._linkifier.linkifyScriptLocation(this._target,null,url,startLine-1,startColumn));},appendLocationRange:function(title,url,startLine,endLine) {if(!this._linkifier||!this._target) return;var locationContent=createElement("span");locationContent.appendChild(this._linkifier.linkifyScriptLocation(this._target,null,url,startLine-1));locationContent.createTextChild(String.sprintf(" [%s\u2026%s]",startLine,endLine||""));this.appendElementRow(title,locationContent);},appendStackTrace:function(title,stackTrace) {if(!this._linkifier||!this._target) return;var rowElement=this._tableElement.createChild("div","timeline-details-view-row");rowElement.createChild("div","timeline-details-view-row-title").textContent=title;this.createChildStackTraceElement(rowElement,stackTrace);},createChildStackTraceElement:function(parentElement,stackTrace) {if(!this._linkifier||!this._target) return;parentElement.classList.add("timeline-details-stack-values");var stackTraceElement=parentElement.createChild("div","timeline-details-view-row-value timeline-details-view-row-stack-trace");var callFrameElem=WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(this._target,this._linkifier,stackTrace);stackTraceElement.appendChild(callFrameElem);},appendWarningRow:function(event,warningType) {var warning=WebInspector.TimelineUIUtils.eventWarning(event,warningType);if(warning) this.appendElementRow(WebInspector.UIString("Warning"),warning,true);}} WebInspector.TimelineUIUtils.eventWarning=function(event,warningType) {var warning=warningType||event.warning;if(!warning) return null;var warnings=WebInspector.TimelineModel.WarningType;var span=createElement("span");var eventData=event.args["data"];switch(warning){case warnings.ForcedStyle:case warnings.ForcedLayout:span.appendChild(WebInspector.linkifyDocumentationURLAsNode("../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts",WebInspector.UIString("Forced reflow")));span.createTextChild(WebInspector.UIString(" is a likely performance bottleneck."));break;case warnings.IdleDeadlineExceeded:span.textContent=WebInspector.UIString("Idle callback execution extended beyond deadline by "+ Number.millisToString(event.duration-eventData["allottedMilliseconds"],true));break;case warnings.V8Deopt:span.appendChild(WebInspector.linkifyURLAsNode("https://github.com/GoogleChrome/devtools-docs/issues/53",WebInspector.UIString("Not optimized"),undefined,true));span.createTextChild(WebInspector.UIString(": %s",eventData["deoptReason"]));break;default:console.assert(false,"Unhandled TimelineModel.WarningType");} return span;};WebInspector.TimelineLayersView=function(model,showEventDetailsCallback) {WebInspector.SplitWidget.call(this,true,false,"timelineLayersView");this._model=model;this._showEventDetailsCallback=showEventDetailsCallback;this.element.classList.add("timeline-layers-view");this._rightSplitWidget=new WebInspector.SplitWidget(true,true,"timelineLayersViewDetails");this._rightSplitWidget.element.classList.add("timeline-layers-view-properties");this.setMainWidget(this._rightSplitWidget);this._paintTiles=[];var vbox=new WebInspector.VBox();this.setSidebarWidget(vbox);this._layerViewHost=new WebInspector.LayerViewHost();var layerTreeOutline=new WebInspector.LayerTreeOutline(this._layerViewHost);vbox.element.appendChild(layerTreeOutline.element);this._layers3DView=new WebInspector.Layers3DView(this._layerViewHost);this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.PaintProfilerRequested,this._jumpToPaintEvent,this);this._rightSplitWidget.setMainWidget(this._layers3DView);var layerDetailsView=new WebInspector.LayerDetailsView(this._layerViewHost);this._rightSplitWidget.setSidebarWidget(layerDetailsView);layerDetailsView.addEventListener(WebInspector.LayerDetailsView.Events.PaintProfilerRequested,this._jumpToPaintEvent,this);} WebInspector.TimelineLayersView.prototype={showLayerTree:function(deferredLayerTree,paints) {this._disposeTiles();this._deferredLayerTree=deferredLayerTree;this._paints=paints;if(this.isShowing()) this._update();else this._updateWhenVisible=true;},wasShown:function() {if(this._updateWhenVisible){this._updateWhenVisible=false;this._update();}},_jumpToPaintEvent:function(event) {var traceEvent=(event.data);this._showEventDetailsCallback(traceEvent);},_update:function() {var layerTree;this._target=this._deferredLayerTree.target();var originalTiles=this._paintTiles;var tilesReadyBarrier=new CallbackBarrier();this._deferredLayerTree.resolve(tilesReadyBarrier.createCallback(onLayersReady));for(var i=0;this._paints&&i<this._paints.length;++i) this._paints[i].loadSnapshot(tilesReadyBarrier.createCallback(onSnapshotLoaded.bind(this,this._paints[i])));tilesReadyBarrier.callWhenDone(onLayersAndTilesReady.bind(this));function onLayersReady(resolvedLayerTree) {layerTree=resolvedLayerTree;} function onSnapshotLoaded(paintEvent,rect,snapshot) {if(!rect||!snapshot) return;if(originalTiles!==this._paintTiles){snapshot.dispose();return;} this._paintTiles.push({layerId:paintEvent.layerId(),rect:rect,snapshot:snapshot,traceEvent:paintEvent.event()});} function onLayersAndTilesReady() {this._layerViewHost.setLayerTree(layerTree);this._layers3DView.setTiles(this._paintTiles);}},_disposeTiles:function() {for(var i=0;i<this._paintTiles.length;++i) this._paintTiles[i].snapshot.dispose();this._paintTiles=[];},__proto__:WebInspector.SplitWidget.prototype};WebInspector.TimelinePaintProfilerView=function(frameModel) {WebInspector.SplitWidget.call(this,false,false);this.element.classList.add("timeline-paint-profiler-view");this.setSidebarSize(60);this.setResizable(false);this._frameModel=frameModel;this._logAndImageSplitWidget=new WebInspector.SplitWidget(true,false);this._logAndImageSplitWidget.element.classList.add("timeline-paint-profiler-log-split");this.setMainWidget(this._logAndImageSplitWidget);this._imageView=new WebInspector.TimelinePaintImageView();this._logAndImageSplitWidget.setMainWidget(this._imageView);this._paintProfilerView=new WebInspector.PaintProfilerView(this._imageView.showImage.bind(this._imageView));this._paintProfilerView.addEventListener(WebInspector.PaintProfilerView.Events.WindowChanged,this._onWindowChanged,this);this.setSidebarWidget(this._paintProfilerView);this._logTreeView=new WebInspector.PaintProfilerCommandLogView();this._logAndImageSplitWidget.setSidebarWidget(this._logTreeView);} WebInspector.TimelinePaintProfilerView.prototype={wasShown:function() {if(this._updateWhenVisible){this._updateWhenVisible=false;this._update();}},setEvent:function(target,event) {this._disposeSnapshot();this._target=target;this._event=event;if(this.isShowing()) this._update();else this._updateWhenVisible=true;if(this._event.name===WebInspector.TimelineModel.RecordType.Paint) return!!event.picture;if(this._event.name===WebInspector.TimelineModel.RecordType.RasterTask) return this._frameModel.hasRasterTile(this._event);return false;},_update:function() {this._logTreeView.setCommandLog(null,[]);this._paintProfilerView.setSnapshotAndLog(null,[],null);if(this._event.name===WebInspector.TimelineModel.RecordType.Paint) this._event.picture.requestObject(onDataAvailable.bind(this));else if(this._event.name===WebInspector.TimelineModel.RecordType.RasterTask) this._frameModel.requestRasterTile(this._event,onSnapshotLoaded.bind(this)) else console.assert(false,"Unexpected event type: "+this._event.name);function onDataAvailable(data) {if(data) WebInspector.PaintProfilerSnapshot.load(this._target,data["skp64"],onSnapshotLoaded.bind(this,null));} function onSnapshotLoaded(tileRect,snapshot) {this._disposeSnapshot();this._lastLoadedSnapshot=snapshot;this._imageView.setMask(tileRect);if(!snapshot){this._imageView.showImage();return;} snapshot.commandLog(onCommandLogDone.bind(this,snapshot,tileRect));} function onCommandLogDone(snapshot,clipRect,log) {this._logTreeView.setCommandLog(snapshot.target(),log||[]);this._paintProfilerView.setSnapshotAndLog(snapshot,log||[],clipRect);}},_disposeSnapshot:function() {if(!this._lastLoadedSnapshot) return;this._lastLoadedSnapshot.dispose();this._lastLoadedSnapshot=null;},_onWindowChanged:function() {var window=this._paintProfilerView.windowBoundaries();this._logTreeView.updateWindow(window.left,window.right);},__proto__:WebInspector.SplitWidget.prototype};WebInspector.TimelinePaintImageView=function() {WebInspector.Widget.call(this);this.element.classList.add("fill","paint-profiler-image-view");this._imageContainer=this.element.createChild("div","paint-profiler-image-container");this._imageElement=this._imageContainer.createChild("img");this._maskElement=this._imageContainer.createChild("div");this._imageElement.addEventListener("load",this._updateImagePosition.bind(this),false);this._transformController=new WebInspector.TransformController(this.element,true);this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged,this._updateImagePosition,this);} WebInspector.TimelinePaintImageView.prototype={onResize:function() {if(this._imageElement.src) this._updateImagePosition();},_updateImagePosition:function() {var width=this._imageElement.naturalWidth;var height=this._imageElement.naturalHeight;var clientWidth=this.element.clientWidth;var clientHeight=this.element.clientHeight;var paddingFraction=0.1;var paddingX=clientWidth*paddingFraction;var paddingY=clientHeight*paddingFraction;var scaleX=(clientWidth-paddingX)/width;var scaleY=(clientHeight-paddingY)/height;var scale=Math.min(scaleX,scaleY);if(this._maskRectangle){var style=this._maskElement.style;style.width=width+"px";style.height=height+"px";style.borderLeftWidth=this._maskRectangle.x+"px";style.borderTopWidth=this._maskRectangle.y+"px";style.borderRightWidth=(width-this._maskRectangle.x-this._maskRectangle.width)+"px";style.borderBottomWidth=(height-this._maskRectangle.y-this._maskRectangle.height)+"px";} this._transformController.setScaleConstraints(0.5,10/scale);var matrix=new WebKitCSSMatrix().scale(this._transformController.scale(),this._transformController.scale()).translate(clientWidth/2,clientHeight/2).scale(scale,scale).translate(-width/2,-height/2);var bounds=WebInspector.Geometry.boundsForTransformedPoints(matrix,[0,0,0,width,height,0]);this._transformController.clampOffsets(paddingX-bounds.maxX,clientWidth-paddingX-bounds.minX,paddingY-bounds.maxY,clientHeight-paddingY-bounds.minY);matrix=new WebKitCSSMatrix().translate(this._transformController.offsetX(),this._transformController.offsetY()).multiply(matrix);this._imageContainer.style.webkitTransform=matrix.toString();},showImage:function(imageURL) {this._imageContainer.classList.toggle("hidden",!imageURL);if(imageURL) this._imageElement.src=imageURL;},setMask:function(maskRectangle) {this._maskRectangle=maskRectangle;this._maskElement.classList.toggle("hidden",!maskRectangle);},__proto__:WebInspector.Widget.prototype};;WebInspector.TimelineProfileTree={};WebInspector.TimelineProfileTree.Node=function() {this.totalTime;this.selfTime;this.id;this.event;this.children;this.parent;this._isGroupNode=false;} WebInspector.TimelineProfileTree.Node.prototype={isGroupNode:function() {return this._isGroupNode;}} WebInspector.TimelineProfileTree.buildTopDown=function(events,filters,startTime,endTime,eventIdCallback) {var initialTime=1e7;var root=new WebInspector.TimelineProfileTree.Node();root.totalTime=initialTime;root.selfTime=initialTime;root.children=(new Map());var parent=root;function onStartEvent(e) {if(!WebInspector.TimelineModel.isVisible(filters,e)) return;var time=e.endTime?Math.min(endTime,e.endTime)-Math.max(startTime,e.startTime):0;var id=eventIdCallback?eventIdCallback(e):Symbol("uniqueEventId");if(!parent.children) parent.children=(new Map());var node=parent.children.get(id);if(node){node.selfTime+=time;node.totalTime+=time;}else{node=new WebInspector.TimelineProfileTree.Node();node.totalTime=time;node.selfTime=time;node.parent=parent;node.id=id;node.event=e;parent.children.set(id,node);} parent.selfTime-=time;if(parent.selfTime<0){console.log("Error: Negative self of "+parent.selfTime,e);parent.selfTime=0;} if(e.endTime) parent=node;} function onEndEvent(e) {if(!WebInspector.TimelineModel.isVisible(filters,e)) return;parent=parent.parent;} var instantEventCallback=eventIdCallback?undefined:onStartEvent;WebInspector.TimelineModel.forEachEvent(events,onStartEvent,onEndEvent,instantEventCallback,startTime,endTime);root.totalTime-=root.selfTime;root.selfTime=0;return root;} WebInspector.TimelineProfileTree.buildBottomUp=function(topDownTree,groupingCallback) {var buRoot=new WebInspector.TimelineProfileTree.Node();buRoot.selfTime=0;buRoot.totalTime=0;buRoot.children=new Map();var nodesOnStack=(new Set());if(topDownTree.children) topDownTree.children.forEach(processNode);buRoot.totalTime=topDownTree.totalTime;function processNode(tdNode) {var buParent=groupingCallback&&groupingCallback(tdNode)||buRoot;if(buParent!==buRoot){buRoot.children.set(buParent.id,buParent);buParent.parent=buRoot;} appendNode(tdNode,buParent);var hadNode=nodesOnStack.has(tdNode.id);if(!hadNode) nodesOnStack.add(tdNode.id);if(tdNode.children) tdNode.children.forEach(processNode);if(!hadNode) nodesOnStack.delete(tdNode.id);} function appendNode(tdNode,buParent) {var selfTime=tdNode.selfTime;var totalTime=tdNode.totalTime;buParent.selfTime+=selfTime;buParent.totalTime+=selfTime;while(tdNode.parent){if(!buParent.children) buParent.children=(new Map());var id=tdNode.id;var buNode=buParent.children.get(id);if(!buNode){buNode=new WebInspector.TimelineProfileTree.Node();buNode.selfTime=selfTime;buNode.totalTime=totalTime;buNode.event=tdNode.event;buNode.id=id;buNode.parent=buParent;buParent.children.set(id,buNode);}else{buNode.selfTime+=selfTime;if(!nodesOnStack.has(id)) buNode.totalTime+=totalTime;} tdNode=tdNode.parent;buParent=buNode;}} var rootChildren=buRoot.children;for(var item of rootChildren.entries()){if(item[1].selfTime===0) rootChildren.delete((item[0]));} return buRoot;} WebInspector.TimelineProfileTree.eventURL=function(event) {var data=event.args["data"]||event.args["beginData"];if(data&&data["url"]) return data["url"];var frame=WebInspector.TimelineProfileTree.eventStackFrame(event);while(frame){var url=frame["url"];if(url) return url;frame=frame.parent;} return null;} WebInspector.TimelineProfileTree.eventStackFrame=function(event) {if(event.name==WebInspector.TimelineModel.RecordType.JSFrame) return event.args["data"];var topFrame=event.stackTrace&&event.stackTrace[0];if(topFrame) return topFrame;var initiator=event.initiator;return initiator&&initiator.stackTrace&&initiator.stackTrace[0]||null;} WebInspector.TimelineAggregator=function(categoryMapper) {this._categoryMapper=categoryMapper;this._groupNodes=new Map();} WebInspector.TimelineAggregator.GroupBy={None:"None",Category:"Category",Domain:"Domain",Subdomain:"Subdomain",URL:"URL"} WebInspector.TimelineAggregator.eventId=function(event) {if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){var data=event.args["data"];return"f:"+data["functionName"]+"@"+(data["scriptId"]||data["url"]||"");} return event.name+":@"+WebInspector.TimelineProfileTree.eventURL(event);} WebInspector.TimelineAggregator._extensionInternalPrefix="extensions::";WebInspector.TimelineAggregator._groupNodeFlag=Symbol("groupNode");WebInspector.TimelineAggregator.isExtensionInternalURL=function(url) {return url.startsWith(WebInspector.TimelineAggregator._extensionInternalPrefix);} WebInspector.TimelineAggregator.prototype={groupFunction:function(groupBy) {var idMapper=this._nodeToGroupIdFunction(groupBy);return idMapper&&this._nodeToGroupNode.bind(this,idMapper);},performGrouping:function(root,groupBy) {var nodeMapper=this.groupFunction(groupBy);if(!nodeMapper) return root;for(var node of root.children.values()){var groupNode=nodeMapper(node);groupNode.parent=root;groupNode.selfTime+=node.selfTime;groupNode.totalTime+=node.totalTime;groupNode.children.set(node.id,node);node.parent=root;} root.children=this._groupNodes;return root;},_nodeToGroupIdFunction:function(groupBy) {function groupByURL(node) {return WebInspector.TimelineProfileTree.eventURL(node.event)||"";} function groupByDomain(groupSubdomains,node) {var url=WebInspector.TimelineProfileTree.eventURL(node.event)||"";if(WebInspector.TimelineAggregator.isExtensionInternalURL(url)) return WebInspector.TimelineAggregator._extensionInternalPrefix;var parsedURL=url.asParsedURL();if(!parsedURL) return"";if(parsedURL.scheme==="chrome-extension") return parsedURL.scheme+"://"+parsedURL.host;if(!groupSubdomains) return parsedURL.host;if(/^[.0-9]+$/.test(parsedURL.host)) return parsedURL.host;var domainMatch=/([^.]*\.)?[^.]*$/.exec(parsedURL.host);return domainMatch&&domainMatch[0]||"";} switch(groupBy){case WebInspector.TimelineAggregator.GroupBy.None:return null;case WebInspector.TimelineAggregator.GroupBy.Category:return node=>node.event?this._categoryMapper(node.event):"";case WebInspector.TimelineAggregator.GroupBy.Subdomain:return groupByDomain.bind(null,false);case WebInspector.TimelineAggregator.GroupBy.Domain:return groupByDomain.bind(null,true);case WebInspector.TimelineAggregator.GroupBy.URL:return groupByURL;default:return null;}},_buildGroupNode:function(id,event) {var groupNode=new WebInspector.TimelineProfileTree.Node();groupNode.id=id;groupNode.selfTime=0;groupNode.totalTime=0;groupNode.children=new Map();groupNode.event=event;groupNode._isGroupNode=true;this._groupNodes.set(id,groupNode);return groupNode;},_nodeToGroupNode:function(nodeToGroupId,node) {var id=nodeToGroupId(node);return this._groupNodes.get(id)||this._buildGroupNode(id,node.event);},};WebInspector.TransformController=function(element,disableRotate) {this._shortcuts={};this.element=element;if(this.element.tabIndex<0) this.element.tabIndex=0;this._registerShortcuts();WebInspector.installDragHandle(element,this._onDragStart.bind(this),this._onDrag.bind(this),this._onDragEnd.bind(this),"move",null);element.addEventListener("keydown",this._onKeyDown.bind(this),false);element.addEventListener("keyup",this._onKeyUp.bind(this),false);element.addEventListener("mousewheel",this._onMouseWheel.bind(this),false);this._minScale=0;this._maxScale=Infinity;this._controlPanelToolbar=new WebInspector.Toolbar("transform-control-panel");this._modeButtons={};if(!disableRotate){var panModeButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Pan mode (X)"),"pan-toolbar-item");panModeButton.addEventListener("click",this._setMode.bind(this,WebInspector.TransformController.Modes.Pan));this._modeButtons[WebInspector.TransformController.Modes.Pan]=panModeButton;this._controlPanelToolbar.appendToolbarItem(panModeButton);var rotateModeButton=new WebInspector.ToolbarToggle(WebInspector.UIString("Rotate mode (V)"),"rotate-toolbar-item");rotateModeButton.addEventListener("click",this._setMode.bind(this,WebInspector.TransformController.Modes.Rotate));this._modeButtons[WebInspector.TransformController.Modes.Rotate]=rotateModeButton;this._controlPanelToolbar.appendToolbarItem(rotateModeButton);} this._setMode(WebInspector.TransformController.Modes.Pan);var resetButton=new WebInspector.ToolbarButton(WebInspector.UIString("Reset transform (0)"),"center-toolbar-item");resetButton.addEventListener("click",this.resetAndNotify.bind(this,undefined));this._controlPanelToolbar.appendToolbarItem(resetButton);this._reset();} WebInspector.TransformController.Events={TransformChanged:"TransformChanged"} WebInspector.TransformController.Modes={Pan:"Pan",Rotate:"Rotate",} WebInspector.TransformController.prototype={toolbar:function() {return this._controlPanelToolbar;},_onKeyDown:function(event) {if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Shift.code){this._toggleMode();return;} var shortcutKey=WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers(event);var handler=this._shortcuts[shortcutKey];if(handler&&handler(event)) event.consume();},_onKeyUp:function(event) {if(event.keyCode===WebInspector.KeyboardShortcut.Keys.Shift.code) this._toggleMode();},_addShortcuts:function(keys,handler) {for(var i=0;i<keys.length;++i) this._shortcuts[keys[i].key]=handler;},_registerShortcuts:function() {this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView,this.resetAndNotify.bind(this));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanMode,this._setMode.bind(this,WebInspector.TransformController.Modes.Pan));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateMode,this._setMode.bind(this,WebInspector.TransformController.Modes.Rotate));var zoomFactor=1.1;this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn,this._onKeyboardZoom.bind(this,zoomFactor));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut,this._onKeyboardZoom.bind(this,1/zoomFactor));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Up,this._onKeyboardPanOrRotate.bind(this,0,-1));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Down,this._onKeyboardPanOrRotate.bind(this,0,1));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Left,this._onKeyboardPanOrRotate.bind(this,-1,0));this._addShortcuts(WebInspector.ShortcutsScreen.LayersPanelShortcuts.Right,this._onKeyboardPanOrRotate.bind(this,1,0));},_postChangeEvent:function() {this.dispatchEventToListeners(WebInspector.TransformController.Events.TransformChanged);},_reset:function() {this._scale=1;this._offsetX=0;this._offsetY=0;this._rotateX=0;this._rotateY=0;},_toggleMode:function() {this._setMode(this._mode===WebInspector.TransformController.Modes.Pan?WebInspector.TransformController.Modes.Rotate:WebInspector.TransformController.Modes.Pan);},_setMode:function(mode) {if(this._mode===mode) return;this._mode=mode;this._updateModeButtons();this.element.focus();},_updateModeButtons:function() {for(var mode in this._modeButtons) this._modeButtons[mode].setToggled(mode===this._mode);},resetAndNotify:function(event) {this._reset();this._postChangeEvent();if(event) event.preventDefault();this.element.focus();},setScaleConstraints:function(minScale,maxScale) {this._minScale=minScale;this._maxScale=maxScale;this._scale=Number.constrain(this._scale,minScale,maxScale);},clampOffsets:function(minX,maxX,minY,maxY) {this._offsetX=Number.constrain(this._offsetX,minX,maxX);this._offsetY=Number.constrain(this._offsetY,minY,maxY);},scale:function() {return this._scale;},offsetX:function() {return this._offsetX;},offsetY:function() {return this._offsetY;},rotateX:function() {return this._rotateX;},rotateY:function() {return this._rotateY;},_onScale:function(scaleFactor,x,y) {scaleFactor=Number.constrain(this._scale*scaleFactor,this._minScale,this._maxScale)/this._scale;this._scale*=scaleFactor;this._offsetX-=(x-this._offsetX)*(scaleFactor-1);this._offsetY-=(y-this._offsetY)*(scaleFactor-1);this._postChangeEvent();},_onPan:function(offsetX,offsetY) {this._offsetX+=offsetX;this._offsetY+=offsetY;this._postChangeEvent();},_onRotate:function(rotateX,rotateY) {this._rotateX=rotateX;this._rotateY=rotateY;this._postChangeEvent();},_onKeyboardZoom:function(zoomFactor) {this._onScale(zoomFactor,this.element.clientWidth/2,this.element.clientHeight/2);},_onKeyboardPanOrRotate:function(xMultiplier,yMultiplier) {var panStepInPixels=6;var rotateStepInDegrees=5;if(this._mode===WebInspector.TransformController.Modes.Rotate){this._onRotate(this._rotateX+yMultiplier*rotateStepInDegrees,this._rotateY+xMultiplier*rotateStepInDegrees);}else{this._onPan(xMultiplier*panStepInPixels,yMultiplier*panStepInPixels);}},_onMouseWheel:function(event) {var zoomFactor=1.1;var mouseWheelZoomSpeed=1/120;var scaleFactor=Math.pow(zoomFactor,event.wheelDeltaY*mouseWheelZoomSpeed);this._onScale(scaleFactor,event.clientX-this.element.totalOffsetLeft(),event.clientY-this.element.totalOffsetTop());},_onDrag:function(event) {if(this._mode===WebInspector.TransformController.Modes.Rotate){this._onRotate(this._oldRotateX+(this._originY-event.clientY)/this.element.clientHeight*180,this._oldRotateY-(this._originX-event.clientX)/this.element.clientWidth*180);}else{this._onPan(event.clientX-this._originX,event.clientY-this._originY);this._originX=event.clientX;this._originY=event.clientY;}},_onDragStart:function(event) {this.element.focus();this._originX=event.clientX;this._originY=event.clientY;this._oldRotateX=this._rotateX;this._oldRotateY=this._rotateY;return true;},_onDragEnd:function() {delete this._originX;delete this._originY;delete this._oldRotateX;delete this._oldRotateY;},__proto__:WebInspector.Object.prototype};WebInspector.PaintProfilerView=function(showImageCallback) {WebInspector.HBox.call(this);this.element.classList.add("paint-profiler-overview","hbox");this._canvasContainer=this.element.createChild("div","paint-profiler-canvas-container");this._progressBanner=this.element.createChild("div","banner hidden");this._progressBanner.textContent=WebInspector.UIString("Profiling\u2026");this._pieChart=new WebInspector.PieChart(55,this._formatPieChartTime.bind(this),true);this._pieChart.element.classList.add("paint-profiler-pie-chart");this.element.appendChild(this._pieChart.element);this._showImageCallback=showImageCallback;this._canvas=this._canvasContainer.createChild("canvas","fill");this._context=this._canvas.getContext("2d");this._selectionWindow=new WebInspector.OverviewGrid.Window(this._canvasContainer);this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);this._innerBarWidth=4*window.devicePixelRatio;this._minBarHeight=window.devicePixelRatio;this._barPaddingWidth=2*window.devicePixelRatio;this._outerBarWidth=this._innerBarWidth+this._barPaddingWidth;this._reset();} WebInspector.PaintProfilerView.Events={WindowChanged:"WindowChanged"};WebInspector.PaintProfilerView.prototype={onResize:function() {this._update();},setSnapshotAndLog:function(snapshot,log,clipRect) {this._reset();this._snapshot=snapshot;this._log=log;this._logCategories=this._log.map(WebInspector.PaintProfilerView._categoryForLogItem);if(!this._snapshot){this._update();this._pieChart.setTotal(0);this._selectionWindow.setEnabled(false);return;} this._selectionWindow.setEnabled(true);this._progressBanner.classList.remove("hidden");snapshot.requestImage(null,null,1,this._showImageCallback);snapshot.profile(clipRect,onProfileDone.bind(this));function onProfileDone(profiles) {this._progressBanner.classList.add("hidden");this._profiles=profiles;this._update();this._updatePieChart();}},_update:function() {this._canvas.width=this._canvasContainer.clientWidth*window.devicePixelRatio;this._canvas.height=this._canvasContainer.clientHeight*window.devicePixelRatio;this._samplesPerBar=0;if(!this._profiles||!this._profiles.length) return;var maxBars=Math.floor((this._canvas.width-2*this._barPaddingWidth)/this._outerBarWidth);var sampleCount=this._log.length;this._samplesPerBar=Math.ceil(sampleCount/maxBars);var maxBarTime=0;var barTimes=[];var barHeightByCategory=[];var heightByCategory={};for(var i=0,lastBarIndex=0,lastBarTime=0;i<sampleCount;){var categoryName=(this._logCategories[i]&&this._logCategories[i].name)||"misc";var sampleIndex=this._log[i].commandIndex;for(var row=0;row<this._profiles.length;row++){var sample=this._profiles[row][sampleIndex];lastBarTime+=sample;heightByCategory[categoryName]=(heightByCategory[categoryName]||0)+sample;} ++i;if(i-lastBarIndex==this._samplesPerBar||i==sampleCount){var factor=this._profiles.length*(i-lastBarIndex);lastBarTime/=factor;for(categoryName in heightByCategory) heightByCategory[categoryName]/=factor;barTimes.push(lastBarTime);barHeightByCategory.push(heightByCategory);if(lastBarTime>maxBarTime) maxBarTime=lastBarTime;lastBarTime=0;heightByCategory={};lastBarIndex=i;}} const paddingHeight=4*window.devicePixelRatio;var scale=(this._canvas.height-paddingHeight-this._minBarHeight)/maxBarTime;for(var i=0;i<barTimes.length;++i){for(var categoryName in barHeightByCategory[i]) barHeightByCategory[i][categoryName]*=(barTimes[i]*scale+this._minBarHeight)/barTimes[i];this._renderBar(i,barHeightByCategory[i]);}},_renderBar:function(index,heightByCategory) {var categories=WebInspector.PaintProfilerView.categories();var currentHeight=0;var x=this._barPaddingWidth+index*this._outerBarWidth;for(var categoryName in categories){if(!heightByCategory[categoryName]) continue;currentHeight+=heightByCategory[categoryName];var y=this._canvas.height-currentHeight;this._context.fillStyle=categories[categoryName].color;this._context.fillRect(x,y,this._innerBarWidth,heightByCategory[categoryName]);}},_onWindowChanged:function() {this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.WindowChanged);this._updatePieChart();if(this._updateImageTimer) return;this._updateImageTimer=setTimeout(this._updateImage.bind(this),100);},_updatePieChart:function() {if(!this._profiles||!this._profiles.length) return;var window=this.windowBoundaries();var totalTime=0;var timeByCategory={};for(var i=window.left;i<window.right;++i){var logEntry=this._log[i];var category=WebInspector.PaintProfilerView._categoryForLogItem(logEntry);timeByCategory[category.color]=timeByCategory[category.color]||0;for(var j=0;j<this._profiles.length;++j){var time=this._profiles[j][logEntry.commandIndex];totalTime+=time;timeByCategory[category.color]+=time;}} this._pieChart.setTotal(totalTime/this._profiles.length);for(var color in timeByCategory) this._pieChart.addSlice(timeByCategory[color]/this._profiles.length,color);},_formatPieChartTime:function(value) {return Number.millisToString(value*1000,true);},windowBoundaries:function() {var screenLeft=this._selectionWindow.windowLeft*this._canvas.width;var screenRight=this._selectionWindow.windowRight*this._canvas.width;var barLeft=Math.floor(screenLeft/this._outerBarWidth);var barRight=Math.floor((screenRight+this._innerBarWidth-this._barPaddingWidth/2)/this._outerBarWidth);var stepLeft=Number.constrain(barLeft*this._samplesPerBar,0,this._log.length-1);var stepRight=Number.constrain(barRight*this._samplesPerBar,0,this._log.length);return{left:stepLeft,right:stepRight};},_updateImage:function() {delete this._updateImageTimer;if(!this._profiles||!this._profiles.length) return;var window=this.windowBoundaries();this._snapshot.requestImage(this._log[window.left].commandIndex,this._log[window.right-1].commandIndex,1,this._showImageCallback);},_reset:function() {this._snapshot=null;this._profiles=null;this._selectionWindow.reset();},__proto__:WebInspector.HBox.prototype};WebInspector.PaintProfilerCommandLogView=function() {WebInspector.VBox.call(this);this.setMinimumSize(100,25);this.element.classList.add("profiler-log-view");this._treeOutline=new TreeOutlineInShadow();this.element.appendChild(this._treeOutline.element);this._reset();} WebInspector.PaintProfilerCommandLogView.prototype={setCommandLog:function(target,log) {this._target=target;this._log=log;this.updateWindow();},_appendLogItem:function(treeOutline,logItem) {var treeElement=new WebInspector.LogTreeElement(this,logItem);treeOutline.appendChild(treeElement);},updateWindow:function(stepLeft,stepRight) {this._treeOutline.removeChildren();if(!this._log.length) return;stepLeft=stepLeft||0;stepRight=stepRight||this._log.length;for(var i=stepLeft;i<stepRight;++i) this._appendLogItem(this._treeOutline,this._log[i]);},_reset:function() {this._log=[];},__proto__:WebInspector.VBox.prototype};WebInspector.LogTreeElement=function(ownerView,logItem) {TreeElement.call(this,"",!!logItem.params);this._logItem=logItem;this._ownerView=ownerView;this._filled=false;} WebInspector.LogTreeElement.prototype={onattach:function() {this._update();},onpopulate:function() {for(var param in this._logItem.params) WebInspector.LogPropertyTreeElement._appendLogPropertyItem(this,param,this._logItem.params[param]);},_paramToString:function(param,name) {if(typeof param!=="object") return typeof param==="string"&¶m.length>100?name:JSON.stringify(param);var str="";var keyCount=0;for(var key in param){if(++keyCount>4||typeof param[key]==="object"||(typeof param[key]==="string"&¶m[key].length>100)) return name;if(str) str+=", ";str+=param[key];} return str;},_paramsToString:function(params) {var str="";for(var key in params){if(str) str+=", ";str+=this._paramToString(params[key],key);} return str;},_update:function() {var title=createDocumentFragment();title.createTextChild(this._logItem.method+"("+this._paramsToString(this._logItem.params)+")");this.title=title;},__proto__:TreeElement.prototype};WebInspector.LogPropertyTreeElement=function(property) {TreeElement.call(this);this._property=property;};WebInspector.LogPropertyTreeElement._appendLogPropertyItem=function(element,name,value) {var treeElement=new WebInspector.LogPropertyTreeElement({name:name,value:value});element.appendChild(treeElement);if(value&&typeof value==="object"){for(var property in value) WebInspector.LogPropertyTreeElement._appendLogPropertyItem(treeElement,property,value[property]);}};WebInspector.LogPropertyTreeElement.prototype={onattach:function() {var title=createDocumentFragment();var nameElement=title.createChild("span","name");nameElement.textContent=this._property.name;var separatorElement=title.createChild("span","separator");separatorElement.textContent=": ";if(this._property.value===null||typeof this._property.value!=="object"){var valueElement=title.createChild("span","value");valueElement.textContent=JSON.stringify(this._property.value);valueElement.classList.add("cm-js-"+(this._property.value===null?"null":typeof this._property.value));} this.title=title;},__proto__:TreeElement.prototype} WebInspector.PaintProfilerView.categories=function() {if(WebInspector.PaintProfilerView._categories) return WebInspector.PaintProfilerView._categories;WebInspector.PaintProfilerView._categories={shapes:new WebInspector.PaintProfilerCategory("shapes",WebInspector.UIString("Shapes"),"rgb(255, 161, 129)"),bitmap:new WebInspector.PaintProfilerCategory("bitmap",WebInspector.UIString("Bitmap"),"rgb(136, 196, 255)"),text:new WebInspector.PaintProfilerCategory("text",WebInspector.UIString("Text"),"rgb(180, 255, 137)"),misc:new WebInspector.PaintProfilerCategory("misc",WebInspector.UIString("Misc"),"rgb(206, 160, 255)")};return WebInspector.PaintProfilerView._categories;};WebInspector.PaintProfilerCategory=function(name,title,color) {this.name=name;this.title=title;this.color=color;} WebInspector.PaintProfilerView._initLogItemCategories=function() {if(WebInspector.PaintProfilerView._logItemCategoriesMap) return WebInspector.PaintProfilerView._logItemCategoriesMap;var categories=WebInspector.PaintProfilerView.categories();var logItemCategories={};logItemCategories["Clear"]=categories["misc"];logItemCategories["DrawPaint"]=categories["misc"];logItemCategories["DrawData"]=categories["misc"];logItemCategories["SetMatrix"]=categories["misc"];logItemCategories["PushCull"]=categories["misc"];logItemCategories["PopCull"]=categories["misc"];logItemCategories["Translate"]=categories["misc"];logItemCategories["Scale"]=categories["misc"];logItemCategories["Concat"]=categories["misc"];logItemCategories["Restore"]=categories["misc"];logItemCategories["SaveLayer"]=categories["misc"];logItemCategories["Save"]=categories["misc"];logItemCategories["BeginCommentGroup"]=categories["misc"];logItemCategories["AddComment"]=categories["misc"];logItemCategories["EndCommentGroup"]=categories["misc"];logItemCategories["ClipRect"]=categories["misc"];logItemCategories["ClipRRect"]=categories["misc"];logItemCategories["ClipPath"]=categories["misc"];logItemCategories["ClipRegion"]=categories["misc"];logItemCategories["DrawPoints"]=categories["shapes"];logItemCategories["DrawRect"]=categories["shapes"];logItemCategories["DrawOval"]=categories["shapes"];logItemCategories["DrawRRect"]=categories["shapes"];logItemCategories["DrawPath"]=categories["shapes"];logItemCategories["DrawVertices"]=categories["shapes"];logItemCategories["DrawDRRect"]=categories["shapes"];logItemCategories["DrawBitmap"]=categories["bitmap"];logItemCategories["DrawBitmapRectToRect"]=categories["bitmap"];logItemCategories["DrawBitmapMatrix"]=categories["bitmap"];logItemCategories["DrawBitmapNine"]=categories["bitmap"];logItemCategories["DrawSprite"]=categories["bitmap"];logItemCategories["DrawPicture"]=categories["bitmap"];logItemCategories["DrawText"]=categories["text"];logItemCategories["DrawPosText"]=categories["text"];logItemCategories["DrawPosTextH"]=categories["text"];logItemCategories["DrawTextOnPath"]=categories["text"];WebInspector.PaintProfilerView._logItemCategoriesMap=logItemCategories;return logItemCategories;} WebInspector.PaintProfilerView._categoryForLogItem=function(logItem) {var method=logItem.method.toTitleCase();var logItemCategories=WebInspector.PaintProfilerView._initLogItemCategories();var result=logItemCategories[method];if(!result){result=WebInspector.PaintProfilerView.categories()["misc"];logItemCategories[method]=result;} return result;};WebInspector.TimelinePanel=function() {WebInspector.Panel.call(this,"timeline");this.registerRequiredCSS("timeline/timelinePanel.css");this.element.addEventListener("contextmenu",this._contextMenu.bind(this),false);this._dropTarget=new WebInspector.DropTarget(this.element,[WebInspector.DropTarget.Types.Files,WebInspector.DropTarget.Types.URIList],WebInspector.UIString("Drop timeline file or URL here"),this._handleDrop.bind(this));this._state=WebInspector.TimelinePanel.State.Idle;this._detailsLinkifier=new WebInspector.Linkifier();this._windowStartTime=0;this._windowEndTime=Infinity;this._millisecondsToRecordAfterLoadEvent=3000;this._toggleRecordAction=(WebInspector.actionRegistry.action("timeline.toggle-recording"));this._filters=[];if(!Runtime.experiments.isEnabled("timelineShowAllEvents")){this._filters.push(WebInspector.TimelineUIUtils.visibleEventsFilter());this._filters.push(new WebInspector.ExcludeTopLevelFilter());} this._tracingModelBackingStorage=new WebInspector.TempFileBackingStorage("tracing");this._tracingModel=new WebInspector.TracingModel(this._tracingModelBackingStorage);this._model=new WebInspector.TimelineModel(WebInspector.TimelineUIUtils.visibleEventsFilter());this._frameModel=new WebInspector.TimelineFrameModel();this._irModel=new WebInspector.TimelineIRModel();if(Runtime.experiments.isEnabled("cpuThrottling")) this._cpuThrottlingManager=new WebInspector.CPUThrottlingManager();this._currentViews=[];this._captureNetworkSetting=WebInspector.settings.createSetting("timelineCaptureNetwork",false);this._captureJSProfileSetting=WebInspector.settings.createSetting("timelineEnableJSSampling",true);this._captureMemorySetting=WebInspector.settings.createSetting("timelineCaptureMemory",false);this._captureLayersAndPicturesSetting=WebInspector.settings.createSetting("timelineCaptureLayersAndPictures",false);this._captureFilmStripSetting=WebInspector.settings.createSetting("timelineCaptureFilmStrip",false);this._panelToolbar=new WebInspector.Toolbar("",this.element);this._createToolbarItems();var timelinePane=new WebInspector.VBox();timelinePane.show(this.element);var topPaneElement=timelinePane.element.createChild("div","hbox");topPaneElement.id="timeline-overview-panel";this._overviewPane=new WebInspector.TimelineOverviewPane("timeline");this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged,this._onWindowChanged.bind(this));this._overviewPane.show(topPaneElement);this._statusPaneContainer=timelinePane.element.createChild("div","status-pane-container fill");this._createFileSelector();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.PageReloadRequested,this._pageReloadRequested,this);WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.Load,this._loadEventFired,this);this._detailsSplitWidget=new WebInspector.SplitWidget(false,true,"timelinePanelDetailsSplitViewState");this._detailsSplitWidget.element.classList.add("timeline-details-split");this._detailsView=new WebInspector.TimelineDetailsView(this._model,this._filters,this);this._detailsSplitWidget.installResizer(this._detailsView.headerElement());this._detailsSplitWidget.setSidebarWidget(this._detailsView);this._searchableView=new WebInspector.SearchableView(this);this._searchableView.setMinimumSize(0,100);this._searchableView.element.classList.add("searchable-view");this._detailsSplitWidget.setMainWidget(this._searchableView);this._stackView=new WebInspector.StackView(false);this._stackView.element.classList.add("timeline-view-stack");this._stackView.show(this._searchableView.element);this._onModeChanged();this._detailsSplitWidget.show(timelinePane.element);this._detailsSplitWidget.hideSidebar();WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged,this);this._showRecordingHelpMessage();this._selectedSearchResult;this._searchResults;} WebInspector.TimelinePanel.Perspectives={Load:"Load",Responsiveness:"Responsiveness",Custom:"Custom"} WebInspector.TimelinePanel.DetailsTab={Details:"Details",Events:"Events",CallTree:"CallTree",BottomUp:"BottomUp",PaintProfiler:"PaintProfiler",LayerViewer:"LayerViewer"} WebInspector.TimelinePanel.State={Idle:Symbol("Idle"),StartPending:Symbol("StartPending"),Recording:Symbol("Recording"),StopPending:Symbol("StopPending"),Loading:Symbol("Loading")} WebInspector.TimelinePanel.rowHeight=18;WebInspector.TimelinePanel.headerHeight=20;WebInspector.TimelinePanel.prototype={searchableView:function() {return this._searchableView;},wasShown:function() {WebInspector.context.setFlavor(WebInspector.TimelinePanel,this);},willHide:function() {WebInspector.context.setFlavor(WebInspector.TimelinePanel,null);},windowStartTime:function() {if(this._windowStartTime) return this._windowStartTime;return this._model.minimumRecordTime();},windowEndTime:function() {if(this._windowEndTime<Infinity) return this._windowEndTime;return this._model.maximumRecordTime()||Infinity;},_onWindowChanged:function(event) {this._windowStartTime=event.data.startTime;this._windowEndTime=event.data.endTime;for(var i=0;i<this._currentViews.length;++i) this._currentViews[i].setWindowTimes(this._windowStartTime,this._windowEndTime);if(!this._selection||this._selection.type()===WebInspector.TimelineSelection.Type.Range) this.select(null);},_onOverviewSelectionChanged:function(event) {var selection=(event.data);this.select(selection);},requestWindowTimes:function(windowStartTime,windowEndTime) {this._overviewPane.requestWindowTimes(windowStartTime,windowEndTime);},_layersView:function() {if(this._lazyLayersView) return this._lazyLayersView;this._lazyLayersView=new WebInspector.TimelineLayersView(this._model,showPaintEventDetails.bind(this));return this._lazyLayersView;function showPaintEventDetails(event) {this._showEventInPaintProfiler(event,true);this._detailsView.selectTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler,true);}},_paintProfilerView:function() {if(this._lazyPaintProfilerView) return this._lazyPaintProfilerView;this._lazyPaintProfilerView=new WebInspector.TimelinePaintProfilerView(this._frameModel);return this._lazyPaintProfilerView;},_addModeView:function(modeView) {modeView.setWindowTimes(this.windowStartTime(),this.windowEndTime());modeView.refreshRecords();var splitWidget=this._stackView.appendView(modeView.view(),"timelinePanelTimelineStackSplitViewState",undefined,112);var resizer=modeView.resizerElement();if(splitWidget&&resizer){splitWidget.hideDefaultResizer();splitWidget.installResizer(resizer);} this._currentViews.push(modeView);},_removeAllModeViews:function() {this._currentViews.forEach(view=>view.dispose());this._currentViews=[];this._stackView.detachChildWidgets();},_setState:function(state) {this._state=state;this._updateTimelineControls();},_createSettingCheckbox:function(name,setting,tooltip) {if(!this._recordingOptionUIControls) this._recordingOptionUIControls=[];var checkboxItem=new WebInspector.ToolbarCheckbox(name,tooltip,setting);this._recordingOptionUIControls.push(checkboxItem);return checkboxItem;},_createToolbarItems:function() {this._panelToolbar.removeToolbarItems();var perspectiveSetting=WebInspector.settings.createSetting("timelinePerspective",WebInspector.TimelinePanel.Perspectives.Load);if(Runtime.experiments.isEnabled("timelineRecordingPerspectives")){function onPerspectiveChanged() {perspectiveSetting.set(perspectiveCombobox.selectElement().value);this._createToolbarItems();} function addPerspectiveOption(id,title) {var option=perspectiveCombobox.createOption(title,"",id);perspectiveCombobox.addOption(option);if(id===perspectiveSetting.get()) perspectiveCombobox.select(option);} var perspectiveCombobox=new WebInspector.ToolbarComboBox(onPerspectiveChanged.bind(this));addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Load,WebInspector.UIString("Page Load"));addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Responsiveness,WebInspector.UIString("Responsiveness"));addPerspectiveOption(WebInspector.TimelinePanel.Perspectives.Custom,WebInspector.UIString("Custom"));this._panelToolbar.appendToolbarItem(perspectiveCombobox);switch(perspectiveSetting.get()){case WebInspector.TimelinePanel.Perspectives.Load:this._captureNetworkSetting.set(true);this._captureJSProfileSetting.set(true);this._captureMemorySetting.set(false);this._captureLayersAndPicturesSetting.set(false);this._captureFilmStripSetting.set(true);break;case WebInspector.TimelinePanel.Perspectives.Responsiveness:this._captureNetworkSetting.set(true);this._captureJSProfileSetting.set(true);this._captureMemorySetting.set(false);this._captureLayersAndPicturesSetting.set(false);this._captureFilmStripSetting.set(false);break;}} if(Runtime.experiments.isEnabled("timelineRecordingPerspectives")&&perspectiveSetting.get()===WebInspector.TimelinePanel.Perspectives.Load){this._reloadButton=new WebInspector.ToolbarButton(WebInspector.UIString("Record & Reload"),"refresh-toolbar-item");this._reloadButton.addEventListener("click",()=>WebInspector.targetManager.reloadPage());this._panelToolbar.appendToolbarItem(this._reloadButton);}else{this._panelToolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(this._toggleRecordAction));} this._updateTimelineControls();var clearButton=new WebInspector.ToolbarButton(WebInspector.UIString("Clear recording"),"clear-toolbar-item");clearButton.addEventListener("click",this._clear,this);this._panelToolbar.appendToolbarItem(clearButton);this._panelToolbar.appendSeparator();this._panelToolbar.appendText(WebInspector.UIString("Capture:"));var screenshotCheckbox=this._createSettingCheckbox(WebInspector.UIString("Screenshots"),this._captureFilmStripSetting,WebInspector.UIString("Capture screenshots while recording. (Has small performance overhead)"));if(!Runtime.experiments.isEnabled("timelineRecordingPerspectives")||perspectiveSetting.get()===WebInspector.TimelinePanel.Perspectives.Custom){this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Network"),this._captureNetworkSetting,WebInspector.UIString("Show network requests information")));this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("JS Profile"),this._captureJSProfileSetting,WebInspector.UIString("Capture JavaScript stacks with sampling profiler. (Has small performance overhead)")));this._panelToolbar.appendToolbarItem(screenshotCheckbox);this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Memory"),this._captureMemorySetting,WebInspector.UIString("Capture memory information on every timeline event.")));this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Paint"),this._captureLayersAndPicturesSetting,WebInspector.UIString("Capture graphics layer positions and rasterization draw calls. (Has large performance overhead)")));}else{this._panelToolbar.appendToolbarItem(screenshotCheckbox);} this._captureNetworkSetting.addChangeListener(this._onNetworkChanged,this);this._captureMemorySetting.addChangeListener(this._onModeChanged,this);this._captureFilmStripSetting.addChangeListener(this._onModeChanged,this);this._panelToolbar.appendSeparator();var garbageCollectButton=new WebInspector.ToolbarButton(WebInspector.UIString("Collect garbage"),"garbage-collect-toolbar-item");garbageCollectButton.addEventListener("click",this._garbageCollectButtonClicked,this);this._panelToolbar.appendToolbarItem(garbageCollectButton);if(Runtime.experiments.isEnabled("cpuThrottling")){this._panelToolbar.appendSeparator();this._cpuThrottlingCombobox=new WebInspector.ToolbarComboBox(this._onCPUThrottlingChanged.bind(this));function addGroupingOption(name,value) {var option=this._cpuThrottlingCombobox.createOption(name,"",String(value));this._cpuThrottlingCombobox.addOption(option);if(value===this._cpuThrottlingManager.rate()) this._cpuThrottlingCombobox.select(option);} addGroupingOption.call(this,WebInspector.UIString("No CPU throttling"),1);addGroupingOption.call(this,WebInspector.UIString("High end device\u2003(2x slowdown)"),2);addGroupingOption.call(this,WebInspector.UIString("Low end device\u2003(5x slowdown)"),5);this._panelToolbar.appendToolbarItem(this._cpuThrottlingCombobox);}},_prepareToLoadTimeline:function() {console.assert(this._state===WebInspector.TimelinePanel.State.Idle);this._setState(WebInspector.TimelinePanel.State.Loading);},_createFileSelector:function() {if(this._fileSelectorElement) this._fileSelectorElement.remove();this._fileSelectorElement=WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));this.element.appendChild(this._fileSelectorElement);},_contextMenu:function(event) {var contextMenu=new WebInspector.ContextMenu(event);var disabled=this._state!==WebInspector.TimelinePanel.State.Idle;contextMenu.appendItem(WebInspector.UIString.capitalize("Save Timeline ^data\u2026"),this._saveToFile.bind(this),disabled);contextMenu.appendItem(WebInspector.UIString.capitalize("Load Timeline ^data\u2026"),this._selectFileToLoad.bind(this),disabled);contextMenu.show();},_saveToFile:function() {if(this._state!==WebInspector.TimelinePanel.State.Idle) return true;var now=new Date();var fileName="TimelineRawData-"+now.toISO8601Compact()+".json";var stream=new WebInspector.FileOutputStream();function callback(accepted) {if(!accepted) return;var saver=new WebInspector.TracingTimelineSaver();this._tracingModelBackingStorage.writeToStream(stream,saver);} stream.open(fileName,callback.bind(this));return true;},_selectFileToLoad:function() {this._fileSelectorElement.click();return true;},_loadFromFile:function(file) {if(this._state!==WebInspector.TimelinePanel.State.Idle) return;this._prepareToLoadTimeline();this._loader=WebInspector.TimelineLoader.loadFromFile(this._tracingModel,file,this);this._createFileSelector();},_loadFromURL:function(url) {if(this._state!==WebInspector.TimelinePanel.State.Idle) return;this._prepareToLoadTimeline();this._loader=WebInspector.TimelineLoader.loadFromURL(this._tracingModel,url,this);},_refreshViews:function() {for(var i=0;i<this._currentViews.length;++i){var view=this._currentViews[i];view.refreshRecords();} this._updateSelectionDetails();},_onModeChanged:function() {this._overviewControls=[];this._overviewControls.push(new WebInspector.TimelineEventOverview.Responsiveness(this._model,this._frameModel));if(Runtime.experiments.isEnabled("inputEventsOnTimelineOverview")) this._overviewControls.push(new WebInspector.TimelineEventOverview.Input(this._model));this._overviewControls.push(new WebInspector.TimelineEventOverview.Frames(this._model,this._frameModel));this._overviewControls.push(new WebInspector.TimelineEventOverview.CPUActivity(this._model));this._overviewControls.push(new WebInspector.TimelineEventOverview.Network(this._model));if(this._captureFilmStripSetting.get()) this._overviewControls.push(new WebInspector.TimelineFilmStripOverview(this._model,this._tracingModel));if(this._captureMemorySetting.get()) this._overviewControls.push(new WebInspector.TimelineEventOverview.Memory(this._model));this._overviewPane.setOverviewControls(this._overviewControls);this._removeAllModeViews();this._flameChart=new WebInspector.TimelineFlameChartView(this,this._model,this._frameModel,this._irModel,this._filters);this._flameChart.enableNetworkPane(this._captureNetworkSetting.get());this._addModeView(this._flameChart);if(this._captureMemorySetting.get()) this._addModeView(new WebInspector.MemoryCountersGraph(this,this._model,[WebInspector.TimelineUIUtils.visibleEventsFilter()]));this.doResize();this.select(null);},_onNetworkChanged:function() {if(this._flameChart) this._flameChart.enableNetworkPane(this._captureNetworkSetting.get(),true);},_onCPUThrottlingChanged:function() {if(!this._cpuThrottlingManager) return;var value=Number.parseFloat(this._cpuThrottlingCombobox.selectedOption().value);this._cpuThrottlingManager.setRate(value);},_setUIControlsEnabled:function(enabled) {function handler(toolbarButton) {toolbarButton.setEnabled(enabled);} this._recordingOptionUIControls.forEach(handler);},_startRecording:function(userInitiated) {console.assert(!this._statusPane,"Status pane is already opened.");var mainTarget=WebInspector.targetManager.mainTarget();if(!mainTarget) return;this._setState(WebInspector.TimelinePanel.State.StartPending);this._showRecordingStarted();this._autoRecordGeneration=userInitiated?null:Symbol("Generation");this._controller=new WebInspector.TimelineController(mainTarget,this,this._tracingModel);this._controller.startRecording(true,this._captureJSProfileSetting.get(),this._captureMemorySetting.get(),this._captureLayersAndPicturesSetting.get(),this._captureFilmStripSetting&&this._captureFilmStripSetting.get());for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].timelineStarted();if(userInitiated) WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.TimelineStarted);this._setUIControlsEnabled(false);this._hideRecordingHelpMessage();},_stopRecording:function() {if(this._statusPane){this._statusPane.finish();this._statusPane.updateStatus(WebInspector.UIString("Stopping timeline\u2026"));this._statusPane.updateProgressBar(WebInspector.UIString("Received"),0);} this._setState(WebInspector.TimelinePanel.State.StopPending);this._autoRecordGeneration=null;this._controller.stopRecording();this._controller=null;this._setUIControlsEnabled(true);},_onSuspendStateChanged:function() {this._updateTimelineControls();},_updateTimelineControls:function() {var state=WebInspector.TimelinePanel.State;this._toggleRecordAction.setToggled(this._state===state.Recording);this._toggleRecordAction.setEnabled(this._state===state.Recording||this._state===state.Idle);this._panelToolbar.setEnabled(this._state!==state.Loading);this._dropTarget.setEnabled(this._state===state.Idle);},_toggleRecording:function() {if(this._state===WebInspector.TimelinePanel.State.Idle) this._startRecording(true);else if(this._state===WebInspector.TimelinePanel.State.Recording) this._stopRecording();},_garbageCollectButtonClicked:function() {var targets=WebInspector.targetManager.targets();for(var i=0;i<targets.length;++i) targets[i].heapProfilerAgent().collectGarbage();},_clear:function() {WebInspector.LineLevelProfile.instance().reset();this._tracingModel.reset();this._model.reset();this._showRecordingHelpMessage();this.requestWindowTimes(0,Infinity);delete this._selection;this._frameModel.reset();this._overviewPane.reset();for(var i=0;i<this._currentViews.length;++i) this._currentViews[i].reset();for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].reset();this.select(null);delete this._filmStripModel;this._detailsSplitWidget.hideSidebar();},recordingStarted:function() {this._clear();this._setState(WebInspector.TimelinePanel.State.Recording);this._showRecordingStarted();this._statusPane.updateStatus(WebInspector.UIString("Recording\u2026"));this._statusPane.updateProgressBar(WebInspector.UIString("Buffer usage"),0) this._statusPane.startTimer();this._hideRecordingHelpMessage();},recordingProgress:function(usage) {this._statusPane.updateProgressBar(WebInspector.UIString("Buffer usage"),usage*100);},_showRecordingHelpMessage:function() {function encloseWithTag(tagName,contents) {var e=createElement(tagName);e.textContent=contents;return e;} var recordNode=encloseWithTag("b",WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.toggle-recording")[0].name);var reloadNode=encloseWithTag("b",WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name);var navigateNode=encloseWithTag("b",WebInspector.UIString("WASD"));var hintText=createElementWithClass("div");hintText.appendChild(WebInspector.formatLocalized("To capture a new timeline, click the record toolbar button or hit %s.",[recordNode]));hintText.createChild("br");hintText.appendChild(WebInspector.formatLocalized("To evaluate page load performance, hit %s to record the reload.",[reloadNode]));hintText.createChild("p");hintText.appendChild(WebInspector.formatLocalized("After recording, select an area of interest in the overview by dragging.",[]));hintText.createChild("br");hintText.appendChild(WebInspector.formatLocalized("Then, zoom and pan the timeline with the mousewheel and %s keys.",[navigateNode]));this._hideRecordingHelpMessage();this._helpMessageElement=this._searchableView.element.createChild("div","banner timeline-status-pane");this._helpMessageElement.appendChild(hintText);},_hideRecordingHelpMessage:function() {if(this._helpMessageElement) this._helpMessageElement.remove();delete this._helpMessageElement;},loadingStarted:function() {this._hideRecordingHelpMessage();if(this._statusPane) this._statusPane.hide();this._statusPane=new WebInspector.TimelinePanel.StatusPane(false,this._cancelLoading.bind(this));this._statusPane.showPane(this._statusPaneContainer);this._statusPane.updateStatus(WebInspector.UIString("Loading timeline\u2026"));if(!this._loader) this._statusPane.finish();this.loadingProgress(0);},loadingProgress:function(progress) {if(typeof progress==="number") this._statusPane.updateProgressBar(WebInspector.UIString("Received"),progress*100);},loadingComplete:function(success) {var loadedFromFile=!!this._loader;delete this._loader;this._setState(WebInspector.TimelinePanel.State.Idle);if(!success){this._statusPane.hide();delete this._statusPane;this._clear();return;} if(this._statusPane) this._statusPane.updateStatus(WebInspector.UIString("Processing timeline\u2026"));this._model.setEvents(this._tracingModel,loadedFromFile);this._frameModel.reset();this._frameModel.addTraceEvents(this._model.target(),this._model.inspectedTargetEvents(),this._model.sessionId()||"");this._irModel.populate(this._model);this._model.cpuProfiles().forEach(profile=>WebInspector.LineLevelProfile.instance().appendCPUProfile(profile));if(this._statusPane) this._statusPane.hide();delete this._statusPane;this._overviewPane.reset();this._overviewPane.setBounds(this._model.minimumRecordTime(),this._model.maximumRecordTime());this._setAutoWindowTimes();this._refreshViews();for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].timelineStopped();this._setMarkers();this._overviewPane.scheduleUpdate();this._updateSearchHighlight(false,true);this._detailsSplitWidget.showBoth();},_showRecordingStarted:function() {if(this._statusPane) return;this._statusPane=new WebInspector.TimelinePanel.StatusPane(true,this._stopRecording.bind(this));this._statusPane.showPane(this._statusPaneContainer);this._statusPane.updateStatus(WebInspector.UIString("Initializing recording\u2026"));},_cancelLoading:function() {if(this._loader) this._loader.cancel();},_setMarkers:function() {var markers=new Map();var recordTypes=WebInspector.TimelineModel.RecordType;var zeroTime=this._model.minimumRecordTime();for(var record of this._model.eventDividerRecords()){if(record.type()===recordTypes.TimeStamp||record.type()===recordTypes.ConsoleTime) continue;markers.set(record.startTime(),WebInspector.TimelineUIUtils.createDividerForRecord(record,zeroTime,0));} this._overviewPane.setMarkers(markers);},_pageReloadRequested:function(event) {if(this._state!==WebInspector.TimelinePanel.State.Idle||!this.isShowing()) return;this._startRecording(false);},_loadEventFired:function(event) {if(this._state!==WebInspector.TimelinePanel.State.Recording||!this._autoRecordGeneration) return;setTimeout(stopRecordingOnReload.bind(this,this._autoRecordGeneration),this._millisecondsToRecordAfterLoadEvent);function stopRecordingOnReload(recordGeneration) {if(this._state!==WebInspector.TimelinePanel.State.Recording||this._autoRecordGeneration!==recordGeneration) return;this._stopRecording();}},jumpToNextSearchResult:function() {if(!this._searchResults||!this._searchResults.length) return;var index=this._selectedSearchResult?this._searchResults.indexOf(this._selectedSearchResult):-1;this._jumpToSearchResult(index+1);},jumpToPreviousSearchResult:function() {if(!this._searchResults||!this._searchResults.length) return;var index=this._selectedSearchResult?this._searchResults.indexOf(this._selectedSearchResult):0;this._jumpToSearchResult(index-1);},supportsCaseSensitiveSearch:function() {return false;},supportsRegexSearch:function() {return false;},_jumpToSearchResult:function(index) {this._selectSearchResult((index+this._searchResults.length)%this._searchResults.length);this._currentViews[0].highlightSearchResult(this._selectedSearchResult,this._searchRegex,true);},_selectSearchResult:function(index) {this._selectedSearchResult=this._searchResults[index];this._searchableView.updateCurrentMatchIndex(index);},_clearHighlight:function() {this._currentViews[0].highlightSearchResult(null);},_updateSearchHighlight:function(revealRecord,shouldJump,jumpBackwards) {if(!this._searchRegex){this._clearHighlight();return;} if(!this._searchResults) this._updateSearchResults(shouldJump,jumpBackwards);this._currentViews[0].highlightSearchResult(this._selectedSearchResult,this._searchRegex,revealRecord);},_updateSearchResults:function(shouldJump,jumpBackwards) {if(!this._searchRegex) return;var events=this._model.mainThreadEvents();var filters=this._filters.concat([new WebInspector.TimelineTextFilter(this._searchRegex)]);var matches=[];for(var index=events.lowerBound(this._windowStartTime,(time,event)=>time-event.startTime);index<events.length;++index){var event=events[index];if(event.startTime>this._windowEndTime) break;if(WebInspector.TimelineModel.isVisible(filters,event)) matches.push(event);} var matchesCount=matches.length;if(matchesCount){this._searchResults=matches;this._searchableView.updateSearchMatchesCount(matchesCount);var selectedIndex=matches.indexOf(this._selectedSearchResult);if(shouldJump&&selectedIndex===-1) selectedIndex=jumpBackwards?this._searchResults.length-1:0;this._selectSearchResult(selectedIndex);}else{this._searchableView.updateSearchMatchesCount(0);delete this._selectedSearchResult;}},searchCanceled:function() {this._clearHighlight();delete this._searchResults;delete this._selectedSearchResult;delete this._searchRegex;},performSearch:function(searchConfig,shouldJump,jumpBackwards) {var query=searchConfig.query;this._searchRegex=createPlainTextSearchRegex(query,"i");delete this._searchResults;this._updateSearchHighlight(true,shouldJump,jumpBackwards);},_updateSelectionDetails:function() {switch(this._selection.type()){case WebInspector.TimelineSelection.Type.TraceEvent:var event=(this._selection.object());WebInspector.TimelineUIUtils.buildTraceEventDetails(event,this._model,this._detailsLinkifier,true,this._appendDetailsTabsForTraceEventAndShowDetails.bind(this,event));break;case WebInspector.TimelineSelection.Type.Frame:var frame=(this._selection.object());if(!this._filmStripModel) this._filmStripModel=new WebInspector.FilmStripModel(this._tracingModel);var screenshotTime=frame.idle?frame.startTime:frame.endTime;var filmStripFrame=this._filmStripModel&&this._filmStripModel.frameByTimestamp(screenshotTime);if(filmStripFrame&&filmStripFrame.timestamp-frame.endTime>10) filmStripFrame=null;this.showInDetails(WebInspector.TimelineUIUtils.generateDetailsContentForFrame(this._frameModel,frame,filmStripFrame));if(frame.layerTree){var layersView=this._layersView();layersView.showLayerTree(frame.layerTree,frame.paints);if(!this._detailsView.hasTab(WebInspector.TimelinePanel.DetailsTab.LayerViewer)) this._detailsView.appendTab(WebInspector.TimelinePanel.DetailsTab.LayerViewer,WebInspector.UIString("Layers"),layersView);} break;case WebInspector.TimelineSelection.Type.NetworkRequest:var request=(this._selection.object());WebInspector.TimelineUIUtils.buildNetworkRequestDetails(request,this._model,this._detailsLinkifier).then(this.showInDetails.bind(this));break;case WebInspector.TimelineSelection.Type.Range:this._updateSelectedRangeStats(this._selection._startTime,this._selection._endTime);break;} this._detailsView.updateContents(this._selection);},_frameForSelection:function(selection) {switch(selection.type()){case WebInspector.TimelineSelection.Type.Frame:return(selection.object());case WebInspector.TimelineSelection.Type.Range:return null;case WebInspector.TimelineSelection.Type.TraceEvent:return this._frameModel.filteredFrames(selection._endTime,selection._endTime)[0];default:console.assert(false,"Should never be reached");return null;}},_jumpToFrame:function(offset) {var currentFrame=this._frameForSelection(this._selection);if(!currentFrame) return;var frames=this._frameModel.frames();var index=frames.indexOf(currentFrame);console.assert(index>=0,"Can't find current frame in the frame list");index=Number.constrain(index+offset,0,frames.length-1);var frame=frames[index];this._revealTimeRange(frame.startTime,frame.endTime);this.select(WebInspector.TimelineSelection.fromFrame(frame));return true;},_appendDetailsTabsForTraceEventAndShowDetails:function(event,content) {this.showInDetails(content);if(event.name===WebInspector.TimelineModel.RecordType.Paint||event.name===WebInspector.TimelineModel.RecordType.RasterTask) this._showEventInPaintProfiler(event);},_showEventInPaintProfiler:function(event,isCloseable) {var target=this._model.target();if(!target) return;var paintProfilerView=this._paintProfilerView();var hasProfileData=paintProfilerView.setEvent(target,event);if(!hasProfileData) return;if(!this._detailsView.hasTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler)) this._detailsView.appendTab(WebInspector.TimelinePanel.DetailsTab.PaintProfiler,WebInspector.UIString("Paint Profiler"),paintProfilerView,undefined,undefined,isCloseable);},_updateSelectedRangeStats:function(startTime,endTime) {this.showInDetails(WebInspector.TimelineUIUtils.buildRangeStats(this._model,startTime,endTime));},select:function(selection,preferredTab) {if(!selection) selection=WebInspector.TimelineSelection.fromRange(this._windowStartTime,this._windowEndTime);this._selection=selection;this._detailsLinkifier.reset();if(preferredTab) this._detailsView.setPreferredTab(preferredTab);for(var view of this._currentViews) view.setSelection(selection);this._updateSelectionDetails();},selectEntryAtTime:function(time) {var events=this._model.mainThreadEvents();for(var index=events.upperBound(time,(time,event)=>time-event.startTime)-1;index>=0;--index){var event=events[index];var endTime=event.endTime||event.startTime;if(WebInspector.TracingModel.isTopLevelEvent(event)&&endTime<time) break;if(WebInspector.TimelineModel.isVisible(this._filters,event)&&endTime>=time){this.select(WebInspector.TimelineSelection.fromTraceEvent(event));return;}} this.select(null);},highlightEvent:function(event) {for(var view of this._currentViews) view.highlightEvent(event);},_revealTimeRange:function(startTime,endTime) {var timeShift=0;if(this._windowEndTime<endTime) timeShift=endTime-this._windowEndTime;else if(this._windowStartTime>startTime) timeShift=startTime-this._windowStartTime;if(timeShift) this.requestWindowTimes(this._windowStartTime+timeShift,this._windowEndTime+timeShift);},showInDetails:function(node) {this._detailsView.setContent(node);},_handleDrop:function(dataTransfer) {var items=dataTransfer.items;if(!items.length) return;var item=items[0];if(item.kind==="string"){var url=dataTransfer.getData("text/uri-list");if(new WebInspector.ParsedURL(url).isValid) this._loadFromURL(url);}else if(item.kind==="file"){var entry=items[0].webkitGetAsEntry();if(!entry.isFile) return;entry.file(this._loadFromFile.bind(this));}},_setAutoWindowTimes:function() {var tasks=this._model.mainThreadTasks();if(!tasks.length){this.requestWindowTimes(this._tracingModel.minimumRecordTime(),this._tracingModel.maximumRecordTime());return;} function findLowUtilizationRegion(startIndex,stopIndex) {var threshold=0.1;var cutIndex=startIndex;var cutTime=(tasks[cutIndex].startTime()+tasks[cutIndex].endTime())/2;var usedTime=0;var step=Math.sign(stopIndex-startIndex);for(var i=startIndex;i!==stopIndex;i+=step){var task=tasks[i];var taskTime=(task.startTime()+task.endTime())/2;var interval=Math.abs(cutTime-taskTime);if(usedTime<threshold*interval){cutIndex=i;cutTime=taskTime;usedTime=0;} usedTime+=task.endTime()-task.startTime();} return cutIndex;} var rightIndex=findLowUtilizationRegion(tasks.length-1,0);var leftIndex=findLowUtilizationRegion(0,rightIndex);var leftTime=tasks[leftIndex].startTime();var rightTime=tasks[rightIndex].endTime();var span=rightTime-leftTime;var totalSpan=this._tracingModel.maximumRecordTime()-this._tracingModel.minimumRecordTime();if(span<totalSpan*0.1){leftTime=this._tracingModel.minimumRecordTime();rightTime=this._tracingModel.maximumRecordTime();}else{leftTime=Math.max(leftTime-0.05*span,this._tracingModel.minimumRecordTime());rightTime=Math.min(rightTime+0.05*span,this._tracingModel.maximumRecordTime());} this.requestWindowTimes(leftTime,rightTime);},__proto__:WebInspector.Panel.prototype} WebInspector.TimelineLifecycleDelegate=function() {} WebInspector.TimelineLifecycleDelegate.prototype={recordingStarted:function(){},recordingProgress:function(usage){},loadingStarted:function(){},loadingProgress:function(progress){},loadingComplete:function(success){},};WebInspector.TimelineDetailsView=function(timelineModel,filters,delegate) {WebInspector.TabbedPane.call(this);this.element.classList.add("timeline-details");var tabIds=WebInspector.TimelinePanel.DetailsTab;this._defaultDetailsWidget=new WebInspector.VBox();this._defaultDetailsWidget.element.classList.add("timeline-details-view");this._defaultDetailsContentElement=this._defaultDetailsWidget.element.createChild("div","timeline-details-view-body vbox");this.appendTab(tabIds.Details,WebInspector.UIString("Summary"),this._defaultDetailsWidget);this.setPreferredTab(tabIds.Details);this._rangeDetailViews=new Map();var bottomUpView=new WebInspector.BottomUpTimelineTreeView(timelineModel,filters);this.appendTab(tabIds.BottomUp,WebInspector.UIString("Bottom-Up"),bottomUpView);this._rangeDetailViews.set(tabIds.BottomUp,bottomUpView);var callTreeView=new WebInspector.CallTreeTimelineTreeView(timelineModel,filters);this.appendTab(tabIds.CallTree,WebInspector.UIString("Call Tree"),callTreeView);this._rangeDetailViews.set(tabIds.CallTree,callTreeView);var eventsView=new WebInspector.EventsTimelineTreeView(timelineModel,filters,delegate);this.appendTab(tabIds.Events,WebInspector.UIString("Event Log"),eventsView);this._rangeDetailViews.set(tabIds.Events,eventsView);this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected,this._tabSelected,this);} WebInspector.TimelineDetailsView.prototype={setContent:function(node) {var allTabs=this.otherTabs(WebInspector.TimelinePanel.DetailsTab.Details);for(var i=0;i<allTabs.length;++i){if(!this._rangeDetailViews.has(allTabs[i])) this.closeTab(allTabs[i]);} this._defaultDetailsContentElement.removeChildren();this._defaultDetailsContentElement.appendChild(node);},updateContents:function(selection) {this._selection=selection;var view=this.selectedTabId?this._rangeDetailViews.get(this.selectedTabId):null;if(view) view.updateContents(selection);},appendTab:function(id,tabTitle,view,tabTooltip,userGesture,isCloseable) {WebInspector.TabbedPane.prototype.appendTab.call(this,id,tabTitle,view,tabTooltip,userGesture,isCloseable);if(this._preferredTabId!==this.selectedTabId) this.selectTab(id);},setPreferredTab:function(tabId) {this._preferredTabId=tabId;},_tabSelected:function(event) {if(!event.data.isUserGesture) return;this.setPreferredTab(event.data.tabId);this.updateContents(this._selection);},__proto__:WebInspector.TabbedPane.prototype} WebInspector.TimelineSelection=function(type,startTime,endTime,object) {this._type=type;this._startTime=startTime;this._endTime=endTime;this._object=object||null;} WebInspector.TimelineSelection.Type={Frame:"Frame",NetworkRequest:"NetworkRequest",TraceEvent:"TraceEvent",Range:"Range"};WebInspector.TimelineSelection.fromFrame=function(frame) {return new WebInspector.TimelineSelection(WebInspector.TimelineSelection.Type.Frame,frame.startTime,frame.endTime,frame);} WebInspector.TimelineSelection.fromNetworkRequest=function(request) {return new WebInspector.TimelineSelection(WebInspector.TimelineSelection.Type.NetworkRequest,request.startTime,request.endTime||request.startTime,request);} WebInspector.TimelineSelection.fromTraceEvent=function(event) {return new WebInspector.TimelineSelection(WebInspector.TimelineSelection.Type.TraceEvent,event.startTime,event.endTime||(event.startTime+1),event);} WebInspector.TimelineSelection.fromRange=function(startTime,endTime) {return new WebInspector.TimelineSelection(WebInspector.TimelineSelection.Type.Range,startTime,endTime);} WebInspector.TimelineSelection.prototype={type:function() {return this._type;},object:function() {return this._object;},startTime:function() {return this._startTime;},endTime:function() {return this._endTime;}};WebInspector.TimelineModeView=function() {} WebInspector.TimelineModeView.prototype={view:function(){},dispose:function(){},resizerElement:function(){},reset:function(){},refreshRecords:function(){},highlightSearchResult:function(event,regex,select){},setWindowTimes:function(startTime,endTime){},setSelection:function(selection){},highlightEvent:function(event){}} WebInspector.TimelineModeViewDelegate=function(){} WebInspector.TimelineModeViewDelegate.prototype={requestWindowTimes:function(startTime,endTime){},select:function(selection,preferredTab){},selectEntryAtTime:function(time){},showInDetails:function(node){},highlightEvent:function(event){}} WebInspector.TimelineCategoryFilter=function() {WebInspector.TimelineModel.Filter.call(this);} WebInspector.TimelineCategoryFilter.prototype={accept:function(event) {return!WebInspector.TimelineUIUtils.eventStyle(event).category.hidden;},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.TimelineIsLongFilter=function() {WebInspector.TimelineModel.Filter.call(this);this._minimumRecordDuration=0;} WebInspector.TimelineIsLongFilter.prototype={setMinimumRecordDuration:function(value) {this._minimumRecordDuration=value;},accept:function(event) {var duration=event.endTime?event.endTime-event.startTime:0;return duration>=this._minimumRecordDuration;},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.TimelineTextFilter=function(regExp) {WebInspector.TimelineModel.Filter.call(this);this._setRegExp(regExp||null);} WebInspector.TimelineTextFilter.prototype={_setRegExp:function(regExp) {this._regExp=regExp;},accept:function(event) {return!this._regExp||WebInspector.TimelineUIUtils.testContentMatching(event,this._regExp);},__proto__:WebInspector.TimelineModel.Filter.prototype} WebInspector.TimelinePanel.StatusPane=function(showTimer,stopCallback) {WebInspector.VBox.call(this,true);this.registerRequiredCSS("timeline/timelineStatusDialog.css");this.contentElement.classList.add("timeline-status-dialog");var statusLine=this.contentElement.createChild("div","status-dialog-line status");statusLine.createChild("div","label").textContent=WebInspector.UIString("Status");this._status=statusLine.createChild("div","content");if(showTimer){var timeLine=this.contentElement.createChild("div","status-dialog-line time");timeLine.createChild("div","label").textContent=WebInspector.UIString("Time");this._time=timeLine.createChild("div","content");} var progressLine=this.contentElement.createChild("div","status-dialog-line progress");this._progressLabel=progressLine.createChild("div","label");this._progressBar=progressLine.createChild("div","indicator-container").createChild("div","indicator");this._stopButton=createTextButton(WebInspector.UIString("Stop"),stopCallback);this.contentElement.createChild("div","stop-button").appendChild(this._stopButton);} WebInspector.TimelinePanel.StatusPane.prototype={finish:function() {this._stopTimer();this._stopButton.disabled=true;},hide:function() {this.element.parentNode.classList.remove("tinted");this.element.remove();},showPane:function(parent) {this.show(parent);parent.classList.add("tinted");},updateStatus:function(text) {this._status.textContent=text;},updateProgressBar:function(activity,percent) {this._progressLabel.textContent=activity;this._progressBar.style.width=percent.toFixed(1)+"%";this._updateTimer();},startTimer:function() {this._startTime=Date.now();this._timeUpdateTimer=setInterval(this._updateTimer.bind(this,false),1000);this._updateTimer();},_stopTimer:function() {if(!this._timeUpdateTimer) return;clearInterval(this._timeUpdateTimer);this._updateTimer(true);delete this._timeUpdateTimer;},_updateTimer:function(precise) {if(!this._timeUpdateTimer) return;var elapsed=(Date.now()-this._startTime)/1000;this._time.textContent=WebInspector.UIString("%s\u2009sec",elapsed.toFixed(precise?1:0));},__proto__:WebInspector.VBox.prototype} WebInspector.TimelinePanel.show=function() {WebInspector.inspectorView.setCurrentPanel(WebInspector.TimelinePanel.instance());} WebInspector.TimelinePanel.instance=function() {if(!WebInspector.TimelinePanel._instanceObject) WebInspector.TimelinePanel._instanceObject=new WebInspector.TimelinePanel();return WebInspector.TimelinePanel._instanceObject;} WebInspector.TimelinePanelFactory=function() {} WebInspector.TimelinePanelFactory.prototype={createPanel:function() {return WebInspector.TimelinePanel.instance();}} WebInspector.LoadTimelineHandler=function() {} WebInspector.LoadTimelineHandler.prototype={handleQueryParam:function(value) {WebInspector.TimelinePanel.show();WebInspector.TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));}} WebInspector.TimelinePanel.ActionDelegate=function() {} WebInspector.TimelinePanel.ActionDelegate.prototype={handleAction:function(context,actionId) {var panel=WebInspector.context.flavor(WebInspector.TimelinePanel);console.assert(panel&&panel instanceof WebInspector.TimelinePanel);switch(actionId){case"timeline.toggle-recording":panel._toggleRecording();return true;case"timeline.save-to-file":panel._saveToFile();return true;case"timeline.load-from-file":panel._selectFileToLoad();return true;case"timeline.jump-to-previous-frame":panel._jumpToFrame(-1);return true;case"timeline.jump-to-next-frame":panel._jumpToFrame(1);return true;} return false;}} WebInspector.TimelineFilters=function() {WebInspector.Object.call(this);this._categoryFilter=new WebInspector.TimelineCategoryFilter();this._durationFilter=new WebInspector.TimelineIsLongFilter();this._textFilter=new WebInspector.TimelineTextFilter();this._filters=[this._categoryFilter,this._durationFilter,this._textFilter];this._createFilterBar();} WebInspector.TimelineFilters.Events={FilterChanged:Symbol("FilterChanged")};WebInspector.TimelineFilters._durationFilterPresetsMs=[0,1,15];WebInspector.TimelineFilters.prototype={filters:function() {return this._filters;},searchRegExp:function() {return this._textFilter._regExp;},filterButton:function() {return this._filterBar.filterButton();},filtersWidget:function() {return this._filterBar;},_createFilterBar:function() {this._filterBar=new WebInspector.FilterBar("timelinePanel");this._textFilterUI=new WebInspector.TextFilterUI();this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,textFilterChanged,this);this._filterBar.addFilter(this._textFilterUI);var durationOptions=[];for(var durationMs of WebInspector.TimelineFilters._durationFilterPresetsMs){var durationOption={};if(!durationMs){durationOption.label=WebInspector.UIString("All");durationOption.title=WebInspector.UIString("Show all records");}else{durationOption.label=WebInspector.UIString("\u2265 %dms",durationMs);durationOption.title=WebInspector.UIString("Hide records shorter than %dms",durationMs);} durationOption.value=durationMs;durationOptions.push(durationOption);} var durationFilterUI=new WebInspector.ComboBoxFilterUI(durationOptions);durationFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged,durationFilterChanged,this);this._filterBar.addFilter(durationFilterUI);var categoryFiltersUI={};var categories=WebInspector.TimelineUIUtils.categories();for(var categoryName in categories){var category=categories[categoryName];if(!category.visible) continue;var filter=new WebInspector.CheckboxFilterUI(category.name,category.title);filter.setColor(category.color,"rgba(0, 0, 0, 0.2)");categoryFiltersUI[category.name]=filter;filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged,categoriesFilterChanged.bind(this,categoryName));this._filterBar.addFilter(filter);} return this._filterBar;function textFilterChanged() {var searchQuery=this._textFilterUI.value();this._textFilter._setRegExp(searchQuery?createPlainTextSearchRegex(searchQuery,"i"):null);this._notifyFiltersChanged();} function durationFilterChanged() {var duration=durationFilterUI.value();var minimumRecordDuration=parseInt(duration,10);this._durationFilter.setMinimumRecordDuration(minimumRecordDuration);this._notifyFiltersChanged();} function categoriesFilterChanged(name) {var categories=WebInspector.TimelineUIUtils.categories();categories[name].hidden=!categoryFiltersUI[name].checked();this._notifyFiltersChanged();}},_notifyFiltersChanged:function() {this.dispatchEventToListeners(WebInspector.TimelineFilters.Events.FilterChanged);},__proto__:WebInspector.Object.prototype};WebInspector.CPUThrottlingManager=function() {this._targets=[];this._throttlingRate=1.;WebInspector.targetManager.observeTargets(this,WebInspector.Target.Type.Page);} WebInspector.CPUThrottlingManager.prototype={setRate:function(value) {this._throttlingRate=value;this._targets.forEach(target=>target.emulationAgent().setCPUThrottlingRate(value));},rate:function() {return this._throttlingRate;},targetAdded:function(target) {this._targets.push(target);target.emulationAgent().setCPUThrottlingRate(this._throttlingRate);},targetRemoved:function(target) {this._targets.remove(target,true);},__proto__:WebInspector.Object.prototype};Runtime.cachedResources["timeline/invalidationsTree.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.header, .children, .content {\n min-height: initial;\n line-height: initial;\n}\n\n/* This TreeElement is always expanded and has no arrow. */\n/* FIXME(crbug.com/475618): Implement this in TreeElement. */\n.children li::before {\n display: none;\n}\n\n.content {\n margin-bottom: 4px;\n}\n\n.content .stack-preview-container {\n margin-left: 8px;\n}\n\n.content .node-list {\n margin-left: 10px;\n}\n\n/*# sourceURL=timeline/invalidationsTree.css */";Runtime.cachedResources["timeline/timelineFlamechartPopover.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.timeline-flamechart-popover span {\n margin-right: 5px;\n}\n\n.timeline-flamechart-popover span.timeline-info-network-time {\n color: #009;\n}\n\n.timeline-flamechart-popover span.timeline-info-time {\n color: #282;\n}\n\n.timeline-flamechart-popover span.timeline-info-warning {\n color: #e44;\n}\n\n.timeline-flamechart-popover span.timeline-info-warning * {\n color: inherit;\n}\n\n/*# sourceURL=timeline/timelineFlamechartPopover.css */";Runtime.cachedResources["timeline/timelinePanel.css"]="/*\n * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n.panel.timeline > .toolbar {\n border-bottom: 1px solid #dadada;\n}\n\n#timeline-overview-panel {\n flex: none;\n position: relative;\n border-bottom: 1px solid rgb(140, 140, 140);\n}\n\n.panel.timeline .banner,\n.panel.layers .banner {\n color: #777;\n background-color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n text-align: center;\n padding: 20px;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n font-size: 13px;\n overflow: auto;\n z-index: 500;\n}\n\n.panel.timeline .banner a,\n.panel.layers .banner a {\n color: inherit;\n}\n\n#timeline-overview-panel .timeline-graph-bar {\n pointer-events: none;\n}\n\n#timeline-overview-grid {\n background-color: rgb(255, 255, 255);\n}\n\n#timeline-overview-grid .timeline-grid-header {\n height: 12px;\n}\n\n#timeline-overview-grid .resources-dividers-label-bar {\n pointer-events: auto;\n height: 12px;\n}\n\n#timeline-overview-grid .resources-divider-label {\n top: 1px;\n}\n\n.timeline-details-split {\n flex: auto;\n}\n\n.timeline-view-stack {\n flex: auto;\n display: flex;\n}\n\n#timeline-container .webkit-html-external-link,\n#timeline-container .webkit-html-resource-link {\n color: inherit;\n}\n\n.timeline-graph-side.hovered {\n background-color: rgba(0, 0, 0, 0.05) !important;\n}\n\n.timeline.panel .status-pane-container {\n z-index: 1000;\n pointer-events: none;\n display: flex;\n align-items: center;\n}\n\n.timeline.panel .status-pane-container.tinted {\n background-color: hsla(0, 0%, 90%, 0.8);\n pointer-events: auto;\n}\n\n#timeline-overview-panel .overview-strip {\n margin-top: 2px;\n justify-content: center;\n}\n\n#timeline-overview-panel .overview-strip .timeline-overview-strip-title {\n color: #666;\n font-size: 10px;\n font-weight: bold;\n z-index: 100;\n background-color: rgba(255, 255, 255, 0.7);\n padding: 0 4px;\n position: absolute;\n top: 0;\n right: 0;\n}\n\n#timeline-overview-cpu-activity {\n flex-basis: 25px;\n}\n\n#timeline-overview-network,\n#timeline-overview-framerate {\n flex-basis: 20px;\n}\n\n#timeline-overview-filmstrip {\n flex-basis: 40px;\n}\n\n#timeline-overview-memory {\n flex-basis: 22px;\n}\n\n#timeline-overview-framerate::before,\n#timeline-overview-network::before,\n#timeline-overview-cpu-activity::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n border-bottom: 1px solid hsla(0, 0%, 0%, 0.06);\n z-index: -200;\n}\n\n.overview-strip .background {\n z-index: -10;\n}\n\n#timeline-overview-responsiveness {\n flex-basis: 6px;\n margin-top: 1px !important;\n}\n\n#timeline-overview-input {\n flex-basis: 6px;\n}\n\n#timeline-overview-pane {\n flex: auto;\n position: relative;\n overflow: hidden;\n}\n\n#timeline-overview-container {\n display: flex;\n flex-direction: column;\n flex: none;\n position: relative;\n overflow: hidden;\n}\n\n#timeline-overview-container canvas {\n width: 100%;\n height: 100%;\n}\n\n#timeline-graphs {\n position: absolute;\n left: 0;\n right: 0;\n max-height: 100%;\n top: 20px;\n}\n\n.timeline-aggregated-legend-title {\n display: inline-block;\n}\n\n.timeline-aggregated-legend-value {\n display: inline-block;\n width: 70px;\n text-align: right;\n}\n\n.timeline-aggregated-legend-swatch {\n display: inline-block;\n width: 11px;\n height: 11px;\n margin: 0 6px;\n position: relative;\n top: 1px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n}\n\n.popover ul {\n margin: 0;\n padding: 0;\n list-style-type: none;\n}\n\n#resources-container-content {\n overflow: hidden;\n min-height: 100%;\n}\n\n.timeline-toolbar-resizer {\n background-image: url(Images/toolbarResizerVertical.png);\n background-repeat: no-repeat;\n background-position: right center, center;\n}\n\n.memory-graph-label {\n position: absolute;\n right: 0;\n bottom: 0;\n font-size: 9px;\n color: #888;\n white-space: nowrap;\n padding: 0 4px;\n background-color: hsla(0, 0%, 100%, 0.8);\n}\n\n#memory-graphs-canvas-container {\n overflow: hidden;\n flex: auto;\n position: relative;\n}\n\n#memory-counters-graph {\n flex: auto;\n}\n\n#memory-graphs-canvas-container .memory-counter-marker {\n position: absolute;\n border-radius: 3px;\n width: 5px;\n height: 5px;\n margin-left: -3px;\n margin-top: -2px;\n}\n\n#memory-graphs-container .memory-counter-selector-swatches {\n flex: 0 0 24px;\n padding: 5px 0;\n background-color: #eee;\n border-bottom: 1px solid #ddd;\n}\n\n.memory-counter-selector-info {\n flex: 0 0 auto;\n margin-left: 5px;\n white-space: nowrap;\n}\n\n.memory-counter-selector-info .range {\n margin: 0 4px;\n align-items: center;\n display: inline-flex;\n}\n\n.memory-counter-value {\n margin: 8px;\n}\n\n#counter-values-bar {\n flex: 0 0 20px;\n border-top: solid 1px lightgray;\n width: 100%;\n overflow: hidden;\n line-height: 18px;\n}\n\n.image-preview-container {\n background: transparent;\n text-align: left;\n border-spacing: 0;\n}\n\n.image-preview-container img {\n max-width: 100px;\n max-height: 100px;\n background-image: url(Images/checker.png);\n -webkit-user-select: text;\n -webkit-user-drag: auto;\n}\n\n.image-container {\n padding: 0;\n}\n\n.timeline-filters-header {\n overflow: hidden;\n flex: none;\n}\n\n.timeline-details {\n vertical-align: top;\n}\n\n.timeline-details-title {\n border-bottom: 1px solid #B8B8B8;\n font-weight: bold;\n padding-bottom: 5px;\n padding-top: 0;\n white-space: nowrap;\n}\n\n.timeline-details-row-title {\n font-weight: bold;\n text-align: right;\n white-space: nowrap;\n}\n\n.timeline-details-row-data {\n white-space: nowrap;\n}\n\n.timeline-details-view {\n color: #333;\n overflow: hidden;\n}\n\n.timeline-details-view-body {\n flex: auto;\n overflow: auto;\n position: relative;\n background-color: #f3f3f3;\n}\n\n.timeline-details-view-block {\n flex: none;\n display: flex;\n box-shadow: #ccc 1px 1px 3px;\n background-color: white;\n flex-direction: column;\n margin: 3px 4px;\n padding-bottom: 5px;\n}\n\n.timeline-details-view-row {\n padding-left: 10px;\n flex-direction: row;\n display: flex;\n line-height: 20px;\n}\n\n.timeline-details-view-block .timeline-details-stack-values {\n flex-direction: column !important;\n}\n\n.timeline-details-chip-title {\n font-size: 13px;\n padding: 8px;\n display: flex;\n align-items: center;\n}\n\n.timeline-details-chip-title > div {\n width: 12px;\n height: 12px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n display: inline-block;\n margin-right: 4px;\n content: \" \";\n}\n\n.timeline-details-view-row-title {\n color: rgb(152, 152, 152);\n overflow: hidden;\n}\n\n.timeline-details-warning {\n background-color: rgba(250, 209, 209, 0.48);\n}\n\n.timeline-details-warning .timeline-details-view-row-title {\n color: red;\n}\n\n.timeline-details-warning .timeline-details-view-row-value {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.timeline-details-view-row-value {\n -webkit-user-select: text;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n padding-left: 10px;\n}\n\n.timeline-details-view-row-value .stack-preview-container {\n line-height: 11px;\n}\n\n.timeline-details-view-row-value .timeline-details-warning-marker {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.timeline-details-view-pie-chart-wrapper {\n margin: 4px 0;\n}\n\n.timeline-details-view-pie-chart {\n margin-top: 5px;\n}\n\n.timeline-details-view-pie-chart-total {\n width: 100px;\n margin-top: 10px;\n text-align: center;\n}\n\n.timeline-details-view-row-stack-trace {\n padding: 4px 0;\n line-height: inherit;\n}\n\n.timeline-details-view-row-stack-trace div {\n white-space: nowrap;\n text-overflow: ellipsis;\n line-height: 12px;\n}\n\n.timeline-aggregated-info-legend > div {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.timeline-flamechart {\n overflow: hidden;\n}\n\n.timeline-status-pane.banner {\n text-align: left !important;\n}\n\n.layer-tree,\n.profiler-log-view {\n overflow: auto;\n}\n\n.layers-3d-view {\n overflow: hidden;\n -webkit-user-select: none;\n}\n\n.layers-3d-view canvas {\n flex: 1 1;\n}\n\n.transform-control-panel {\n white-space: nowrap;\n flex: none;\n}\n\n.layer-details-view table td {\n padding-left: 8px;\n}\n\n.layer-details-view table td:first-child {\n font-weight: bold;\n}\n\n.layer-details-view .scroll-rect.active {\n background-color: rgba(100, 100, 100, 0.2);\n}\n\n.paint-profiler-overview .banner {\n z-index: 500;\n}\n\n.paint-profiler-canvas-container {\n flex: auto;\n position: relative;\n}\n\n.paint-profiler-overview {\n background-color: #eee;\n}\n\n.paint-profiler-pie-chart {\n width: 60px !important;\n height: 60px !important;\n padding: 2px;\n overflow: hidden;\n font-size: 10px;\n}\n\n.paint-profiler-canvas-container canvas {\n z-index: 200;\n background-color: white;\n opacity: 0.95;\n height: 100%;\n width: 100%;\n}\n\n.paint-profiler-canvas-container .overview-grid-dividers-background,\n.paint-profiler-canvas-container .overview-grid-window {\n bottom: 0;\n height: auto;\n}\n\n.paint-profiler-canvas-container .overview-grid-window-resizer {\n z-index: 2000;\n}\n\n.paint-profiler-image-view {\n overflow: hidden;\n}\n\n.paint-profiler-image-view .paint-profiler-image-container {\n -webkit-transform-origin: 0 0;\n}\n\n.paint-profiler-image-view .paint-profiler-image-container div {\n border-color: rgba(100, 100, 100, 0.4);\n border-style: solid;\n z-index: 100;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n.paint-profiler-image-view img {\n border: solid 1px black;\n}\n\n.layer-details-view ul {\n list-style: none;\n -webkit-padding-start: 0;\n -webkit-margin-before: 0;\n -webkit-margin-after: 0;\n}\n\n.layer-details-view a {\n padding: 8px;\n display: block;\n}\n\n.timeline-layers-view > div:last-child,\n.timeline-layers-view-properties > div:last-child {\n background-color: #eee;\n}\n\n.timeline-layers-view-properties table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.timeline-layers-view-properties td {\n border: 1px solid #e1e1e1;\n line-height: 22px;\n}\n\n.timeline-paint-profiler-log-split > div:last-child {\n background-color: #eee;\n z-index: 0;\n}\n\n.timeline-gap {\n flex: none;\n}\n\n.timeline-filmstrip-preview {\n margin-top: 10px;\n max-width: 200px;\n max-height: 200px;\n cursor: pointer;\n border: 1px solid #ddd;\n}\n\n.timeline-overview-popover .frame .time {\n display: none;\n}\n\n.timeline-overview-popover .frame .thumbnail img {\n max-width: 200px;\n}\n\n.timeline-tree-view {\n display: flex;\n overflow: hidden;\n}\n\n.timeline-tree-view > .toolbar {\n border-bottom: 1px solid #dadada;\n}\n\n.timeline-tree-view .data-grid {\n border: none;\n flex: auto;\n}\n\n.timeline-tree-view .data-grid .data-container {\n overflow-y: scroll;\n}\n\n.timeline-tree-view .data-grid.data-grid-fits-viewport .corner {\n display: table-cell;\n}\n\n.timeline-tree-view .data-grid table.data {\n background: white;\n}\n\n.timeline-tree-view .data-grid tr:not(.selected) .highlight {\n background-color: rgb(255, 230, 179);\n}\n\n.timeline-tree-view .data-grid tr:hover td:not(.bottom-filler-td) {\n background-color: rgba(0, 0, 0, 0.1);\n}\n\n.timeline-tree-view .data-grid td.numeric-column {\n text-align: right;\n position: relative;\n}\n\n.timeline-tree-view .data-grid div.background-percent-bar {\n float: right;\n}\n\n.timeline-tree-view .data-grid span.percent-column {\n color: #888;\n width: 44px;\n display: inline-block;\n}\n\n.timeline-tree-view .data-grid tr.selected span {\n color: inherit;\n}\n\n.timeline-tree-view .data-grid .name-container {\n display: flex;\n align-items: center;\n}\n\n.timeline-tree-view .data-grid .name-container div {\n flex: none;\n}\n\n.timeline-tree-view .data-grid .name-container .activity-icon {\n width: 10px;\n height: 10px;\n margin: 0 4px 0 2px;\n border: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.timeline-tree-view .data-grid .name-container .activity-warning::after {\n content: \"[deopt]\";\n margin: 0 4px;\n line-height: 12px;\n font-size: 10px;\n color: #777;\n}\n\n.timeline-tree-view .data-grid tr.selected .name-container .activity-warning::after {\n color: white;\n}\n\n.timeline-tree-view .data-grid .name-container .activity-link {\n flex: auto;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-left: 5px;\n}\n\n.timeline-tree-view .data-grid .background-bar-container {\n position: absolute;\n left: 3px;\n right: 0;\n}\n\n.timeline-tree-view .data-grid .background-bar {\n float: right;\n height: 15px;\n background-color: hsla(43, 84%, 64%, 0.2);\n border-bottom: 1px solid hsl(43, 84%, 64%);\n}\n\n.timeline-tree-view .data-grid .selected .background-bar {\n background-color: rgba(255, 255, 255, 0.25);\n border-bottom-color: transparent;\n}\n\n.timeline-tree-view .timeline-details-view-body .banner {\n background-color: inherit;\n}\n\n.timeline-details #filter-input-field {\n width: 120px;\n}\n\n.timeline-tree-view .data-grid .header-container {\n height: 21px;\n}\n\n.timeline-tree-view .data-grid .data-container {\n top: 21px;\n}\n\n.timeline-tree-view .data-grid th {\n border-bottom: 1px solid #ddd;\n background-color: #f3f3f3\n}\n\n.timeline-stack-view-header {\n height: 26px;\n background-color: white;\n padding: 6px 10px;\n color: #5a5a5a;\n}\n\n/*# sourceURL=timeline/timelinePanel.css */";Runtime.cachedResources["timeline/timelineStatusDialog.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.timeline-status-dialog {\n display: flex;\n flex-direction: column;\n padding: 12px 16px;\n align-self: center;\n background-color: white;\n border: 1px solid lightgrey;\n box-shadow: grey 0 0 14px;\n margin-top: -1px;\n}\n\n.status-dialog-line {\n margin: 2px;\n height: 14px;\n display: flex;\n align-items: baseline;\n}\n\n.status-dialog-line .label {\n display: inline-block;\n width: 80px;\n text-align: right;\n color: #aaa;\n margin-right: 10px;\n}\n\n.timeline-status-dialog .progress .indicator-container {\n display: inline-block;\n width: 200px;\n height: 8px;\n background-color: #f4f4f4;\n display: inline-block;\n margin: 0 10px 0 0;\n}\n\n.timeline-status-dialog .progress .indicator {\n background-color: rgb(112, 166, 255);\n height: 100%;\n width: 0;\n margin: 0;\n}\n\n.timeline-status-dialog .stop-button {\n margin-top: 8px;\n height: 100%;\n align-self: center;\n}\n\n/*# sourceURL=timeline/timelineStatusDialog.css */"; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var allDescriptors=[{"dependencies":[],"name":"platform","scripts":[]},{"dependencies":["platform"],"name":"toolbox_bootstrap","scripts":[]}];var applicationDescriptor;var _loadedScripts={};for(var k of[]){};function loadResourcePromise(url)
{return new Promise(load);function load(fulfill,reject)
{var xhr=new XMLHttpRequest();xhr.open("GET",url,true);xhr.onreadystatechange=onreadystatechange;function onreadystatechange(e)
{if(xhr.readyState!==4)
return;if([0,200,304].indexOf(xhr.status)===-1)
reject(new Error("While loading from url "+url+" server responded with a status of "+xhr.status));else
fulfill(e.target.response);}
xhr.send(null);}}
function normalizePath(path)
{if(path.indexOf("..")===-1&&path.indexOf(".")===-1)
return path;var normalizedSegments=[];var segments=path.split("/");for(var i=0;i<segments.length;i++){var segment=segments[i];if(segment===".")
continue;else if(segment==="..")
normalizedSegments.pop();else if(segment)
normalizedSegments.push(segment);}
var normalizedPath=normalizedSegments.join("/");if(normalizedPath[normalizedPath.length-1]==="/")
return normalizedPath;if(path[0]==="/"&&normalizedPath)
normalizedPath="/"+normalizedPath;if((path[path.length-1]==="/")||(segments[segments.length-1]===".")||(segments[segments.length-1]===".."))
normalizedPath=normalizedPath+"/";return normalizedPath;}
function loadScriptsPromise(scriptNames,base)
{var promises=[];var urls=[];var sources=new Array(scriptNames.length);var scriptToEval=0;for(var i=0;i<scriptNames.length;++i){var scriptName=scriptNames[i];var sourceURL=(base||self._importScriptPathPrefix)+scriptName;var schemaIndex=sourceURL.indexOf("://")+3;var pathIndex=sourceURL.indexOf("/",schemaIndex);if(pathIndex===-1)
pathIndex=sourceURL.length;sourceURL=sourceURL.substring(0,pathIndex)+normalizePath(sourceURL.substring(pathIndex));if(_loadedScripts[sourceURL])
continue;urls.push(sourceURL);promises.push(loadResourcePromise(sourceURL).then(scriptSourceLoaded.bind(null,i),scriptSourceLoaded.bind(null,i,undefined)));}
return Promise.all(promises).then(undefined);function scriptSourceLoaded(scriptNumber,scriptSource)
{sources[scriptNumber]=scriptSource||"";while(typeof sources[scriptToEval]!=="undefined"){evaluateScript(urls[scriptToEval],sources[scriptToEval]);++scriptToEval;}}
function evaluateScript(sourceURL,scriptSource)
{_loadedScripts[sourceURL]=true;if(!scriptSource){console.error("Empty response arrived for script '"+sourceURL+"'");return;}
self.eval(scriptSource+"\n//# sourceURL="+sourceURL);}}
(function(){var baseUrl=self.location?self.location.origin+self.location.pathname:"";self._importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf("/")+1);})();function Runtime(descriptors)
{this._modules=[];this._modulesMap={};this._extensions=[];this._cachedTypeClasses={};this._descriptorsMap={};for(var i=0;i<descriptors.length;++i)
this._registerModule(descriptors[i]);}
Runtime._queryParamsObject={__proto__:null};Runtime.cachedResources={__proto__:null};Runtime.isReleaseMode=function()
{return!!allDescriptors.length;}
Runtime.startApplication=function(appName)
{console.timeStamp("Runtime.startApplication");var allDescriptorsByName={};for(var i=0;Runtime.isReleaseMode()&&i<allDescriptors.length;++i){var d=allDescriptors[i];allDescriptorsByName[d["name"]]=d;}
var applicationPromise;if(applicationDescriptor)
applicationPromise=Promise.resolve(applicationDescriptor);else
applicationPromise=loadResourcePromise(appName+".json").then(JSON.parse.bind(JSON));return applicationPromise.then(parseModuleDescriptors);function parseModuleDescriptors(appDescriptor)
{var configuration=appDescriptor.modules;var moduleJSONPromises=[];var coreModuleNames=[];for(var i=0;i<configuration.length;++i){var descriptor=configuration[i];var name=descriptor["name"];var moduleJSON=allDescriptorsByName[name];if(moduleJSON)
moduleJSONPromises.push(Promise.resolve(moduleJSON));else
moduleJSONPromises.push(loadResourcePromise(name+"/module.json").then(JSON.parse.bind(JSON)));if(descriptor["type"]==="autostart")
coreModuleNames.push(name);}
return Promise.all(moduleJSONPromises).then(instantiateRuntime);function instantiateRuntime(moduleDescriptors)
{for(var i=0;!Runtime.isReleaseMode()&&i<moduleDescriptors.length;++i){moduleDescriptors[i]["name"]=configuration[i]["name"];moduleDescriptors[i]["condition"]=configuration[i]["condition"];}
self.runtime=new Runtime(moduleDescriptors);if(coreModuleNames)
return(self.runtime._loadAutoStartModules(coreModuleNames));return Promise.resolve();}}}
Runtime.startWorker=function(appName)
{return Runtime.startApplication(appName).then(sendWorkerReady);function sendWorkerReady()
{self.postMessage("workerReady");}}
Runtime._sharedWorkerNewPortCallback=null;Runtime._sharedWorkerConnectedPorts=[];Runtime.startSharedWorker=function(appName)
{var startPromise=Runtime.startApplication(appName);self.onconnect=function(event)
{var newPort=(event.ports[0]);startPromise.then(sendWorkerReadyAndContinue);function sendWorkerReadyAndContinue()
{newPort.postMessage("workerReady");if(Runtime._sharedWorkerNewPortCallback)
Runtime._sharedWorkerNewPortCallback.call(null,newPort);else
Runtime._sharedWorkerConnectedPorts.push(newPort);}}}
Runtime.setSharedWorkerNewPortCallback=function(callback)
{Runtime._sharedWorkerNewPortCallback=callback;while(Runtime._sharedWorkerConnectedPorts.length){var port=Runtime._sharedWorkerConnectedPorts.shift();callback.call(null,port);}}
Runtime.queryParam=function(name)
{return Runtime._queryParamsObject[name]||null;}
Runtime.constructQueryParams=function(banned)
{var params=[];for(var key in Runtime._queryParamsObject){if(!key||banned.indexOf(key)!==-1)
continue;params.push(key+"="+Runtime._queryParamsObject[key]);}
return params.length?"?"+params.join("&"):"";}
Runtime._experimentsSetting=function()
{try{return(JSON.parse(self.localStorage&&self.localStorage["experiments"]?self.localStorage["experiments"]:"{}"));}catch(e){console.error("Failed to parse localStorage['experiments']");return{};}}
Runtime._some=function(promises)
{var all=[];var wasRejected=[];for(var i=0;i<promises.length;++i){var handlerFunction=(handler.bind(promises[i],i));all.push(promises[i].catch(handlerFunction));}
return Promise.all(all).then(filterOutFailuresResults);function filterOutFailuresResults(results)
{var filtered=[];for(var i=0;i<results.length;++i){if(!wasRejected[i])
filtered.push(results[i]);}
return filtered;}
function handler(index,e)
{wasRejected[index]=true;console.error(e.stack);}}
Runtime._console=console;Runtime._originalAssert=console.assert;Runtime._assert=function(value,message)
{if(value)
return;Runtime._originalAssert.call(Runtime._console,value,message+" "+new Error().stack);}
Runtime.prototype={useTestBase:function()
{Runtime._remoteBase="http://localhost:8000/inspector-sources/";},_registerModule:function(descriptor)
{var module=new Runtime.Module(this,descriptor);this._modules.push(module);this._modulesMap[descriptor["name"]]=module;},loadModulePromise:function(moduleName)
{return this._modulesMap[moduleName]._loadPromise();},_loadAutoStartModules:function(moduleNames)
{var promises=[];for(var i=0;i<moduleNames.length;++i){if(Runtime.isReleaseMode())
this._modulesMap[moduleNames[i]]._loaded=true;else
promises.push(this.loadModulePromise(moduleNames[i]));}
return Promise.all(promises);},_checkExtensionApplicability:function(extension,predicate)
{if(!predicate)
return false;var contextTypes=(extension.descriptor().contextTypes);if(!contextTypes)
return true;for(var i=0;i<contextTypes.length;++i){var contextType=this._resolve(contextTypes[i]);var isMatching=!!contextType&&predicate(contextType);if(isMatching)
return true;}
return false;},isExtensionApplicableToContext:function(extension,context)
{if(!context)
return true;return this._checkExtensionApplicability(extension,isInstanceOf);function isInstanceOf(targetType)
{return context instanceof targetType;}},isExtensionApplicableToContextTypes:function(extension,currentContextTypes)
{if(!extension.descriptor().contextTypes)
return true;return this._checkExtensionApplicability(extension,currentContextTypes?isContextTypeKnown:null);function isContextTypeKnown(targetType)
{return currentContextTypes.has(targetType);}},extensions:function(type,context)
{return this._extensions.filter(filter).sort(orderComparator);function filter(extension)
{if(extension._type!==type&&extension._typeClass()!==type)
return false;if(!extension.enabled())
return false;return!context||extension.isApplicable(context);}
function orderComparator(extension1,extension2)
{var order1=extension1.descriptor()["order"]||0;var order2=extension2.descriptor()["order"]||0;return order1-order2;}},extension:function(type,context)
{return this.extensions(type,context)[0]||null;},instancesPromise:function(type,context)
{var extensions=this.extensions(type,context);var promises=[];for(var i=0;i<extensions.length;++i)
promises.push(extensions[i].instancePromise());return Runtime._some(promises);},instancePromise:function(type,context)
{var extension=this.extension(type,context);if(!extension)
return Promise.reject(new Error("No such extension: "+type+" in given context."));return extension.instancePromise();},_resolve:function(typeName)
{if(!this._cachedTypeClasses[typeName]){var path=typeName.split(".");var object=self;for(var i=0;object&&(i<path.length);++i)
object=object[path[i]];if(object)
this._cachedTypeClasses[typeName]=(object);}
return this._cachedTypeClasses[typeName]||null;}}
Runtime.ModuleDescriptor=function()
{this.name;this.extensions;this.dependencies;this.scripts;this.remote;}
Runtime.ExtensionDescriptor=function()
{this.type;this.className;this.contextTypes;}
Runtime.Module=function(manager,descriptor)
{this._manager=manager;this._descriptor=descriptor;this._name=descriptor.name;this._instanceMap={};var extensions=(descriptor.extensions);for(var i=0;extensions&&i<extensions.length;++i)
this._manager._extensions.push(new Runtime.Extension(this,extensions[i]));this._loaded=false;}
Runtime.Module.prototype={name:function()
{return this._name;},enabled:function()
{return Runtime._isDescriptorEnabled(this._descriptor);},resource:function(name)
{var fullName=this._name+"/"+name;var content=Runtime.cachedResources[fullName];if(!content)
throw new Error(fullName+" not preloaded. Check module.json");return content;},_loadPromise:function()
{if(this._loaded)
return Promise.resolve();if(!this.enabled())
return Promise.reject(new Error("Module "+this._name+" is not enabled"));if(this._pendingLoadPromise)
return this._pendingLoadPromise;var dependencies=this._descriptor.dependencies;var dependencyPromises=[];for(var i=0;dependencies&&i<dependencies.length;++i)
dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());this._pendingLoadPromise=Promise.all(dependencyPromises).then(this._loadResources.bind(this)).then(this._loadScripts.bind(this)).then(markAsLoaded.bind(this));return this._pendingLoadPromise;function markAsLoaded()
{delete this._pendingLoadPromise;this._loaded=true;}},_loadResources:function()
{var resources=this._descriptor["resources"];if(!resources)
return Promise.resolve();var promises=[];for(var i=0;i<resources.length;++i){var url=this._modularizeURL(resources[i]);promises.push(loadResourcePromise(url).then(cacheResource.bind(this,url),cacheResource.bind(this,url,undefined)));}
return Promise.all(promises).then(undefined);function cacheResource(path,content)
{if(!content){console.error("Failed to load resource: "+path);return;}
Runtime.cachedResources[path]=content+Runtime.resolveSourceURL(path);}},_loadScripts:function()
{if(!this._descriptor.scripts)
return Promise.resolve();if(Runtime.isReleaseMode())
return loadScriptsPromise([this._name+"_module.js"],this._remoteBase());return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL,this));},_modularizeURL:function(resourceName)
{return normalizePath(this._name+"/"+resourceName);},_remoteBase:function()
{return this._descriptor.remote&&Runtime._remoteBase||undefined;},substituteURL:function(value)
{var base=this._remoteBase()||"";return value.replace(/@url\(([^\)]*?)\)/g,convertURL.bind(this));function convertURL(match,url)
{return base+this._modularizeURL(url);}},_instance:function(className,extension)
{if(className in this._instanceMap)
return this._instanceMap[className];var constructorFunction=self.eval(className);if(!(constructorFunction instanceof Function)){this._instanceMap[className]=null;return null;}
var instance=new constructorFunction(extension);this._instanceMap[className]=instance;return instance;}}
Runtime._isDescriptorEnabled=function(descriptor)
{var activatorExperiment=descriptor["experiment"];if(activatorExperiment&&activatorExperiment.startsWith("!")&&Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
return false;if(activatorExperiment&&!activatorExperiment.startsWith("!")&&!Runtime.experiments.isEnabled(activatorExperiment))
return false;var condition=descriptor["condition"];if(condition&&!condition.startsWith("!")&&!Runtime.queryParam(condition))
return false;if(condition&&condition.startsWith("!")&&Runtime.queryParam(condition.substring(1)))
return false;return true;}
Runtime.Extension=function(module,descriptor)
{this._module=module;this._descriptor=descriptor;this._type=descriptor.type;this._hasTypeClass=this._type.charAt(0)==="@";this._className=descriptor.className||null;}
Runtime.Extension.prototype={descriptor:function()
{return this._descriptor;},module:function()
{return this._module;},enabled:function()
{return this._module.enabled()&&Runtime._isDescriptorEnabled(this.descriptor());},_typeClass:function()
{if(!this._hasTypeClass)
return null;return this._module._manager._resolve(this._type.substring(1));},isApplicable:function(context)
{return this._module._manager.isExtensionApplicableToContext(this,context);},instancePromise:function()
{if(!this._className)
return Promise.reject(new Error("No class name in extension"));var className=this._className;if(this._instance)
return Promise.resolve(this._instance);return this._module._loadPromise().then(constructInstance.bind(this));function constructInstance()
{var result=this._module._instance(className,this);if(!result)
return Promise.reject("Could not instantiate: "+className);return result;}},title:function(platform)
{return this._descriptor["title-"+platform]||this._descriptor["title"];}}
Runtime.ExperimentsSupport=function()
{this._supportEnabled=Runtime.queryParam("experiments")!==null;this._experiments=[];this._experimentNames={};this._enabledTransiently={};}
Runtime.ExperimentsSupport.prototype={allConfigurableExperiments:function()
{var result=[];for(var i=0;i<this._experiments.length;i++){var experiment=this._experiments[i];if(!this._enabledTransiently[experiment.name])
result.push(experiment);}
return result;},supportEnabled:function()
{return this._supportEnabled;},_setExperimentsSetting:function(value)
{if(!self.localStorage)
return;self.localStorage["experiments"]=JSON.stringify(value);},register:function(experimentName,experimentTitle,hidden)
{Runtime._assert(!this._experimentNames[experimentName],"Duplicate registration of experiment "+experimentName);this._experimentNames[experimentName]=true;this._experiments.push(new Runtime.Experiment(this,experimentName,experimentTitle,!!hidden));},isEnabled:function(experimentName)
{this._checkExperiment(experimentName);if(this._enabledTransiently[experimentName])
return true;if(!this.supportEnabled())
return false;return!!Runtime._experimentsSetting()[experimentName];},setEnabled:function(experimentName,enabled)
{this._checkExperiment(experimentName);var experimentsSetting=Runtime._experimentsSetting();experimentsSetting[experimentName]=enabled;this._setExperimentsSetting(experimentsSetting);},setDefaultExperiments:function(experimentNames)
{for(var i=0;i<experimentNames.length;++i){this._checkExperiment(experimentNames[i]);this._enabledTransiently[experimentNames[i]]=true;}},enableForTest:function(experimentName)
{this._checkExperiment(experimentName);this._enabledTransiently[experimentName]=true;},clearForTest:function()
{this._experiments=[];this._experimentNames={};this._enabledTransiently={};},cleanUpStaleExperiments:function()
{var experimentsSetting=Runtime._experimentsSetting();var cleanedUpExperimentSetting={};for(var i=0;i<this._experiments.length;++i){var experimentName=this._experiments[i].name;if(experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName]=true;}
this._setExperimentsSetting(cleanedUpExperimentSetting);},_checkExperiment:function(experimentName)
{Runtime._assert(this._experimentNames[experimentName],"Unknown experiment "+experimentName);}}
Runtime.Experiment=function(experiments,name,title,hidden)
{this.name=name;this.title=title;this.hidden=hidden;this._experiments=experiments;}
Runtime.Experiment.prototype={isEnabled:function()
{return this._experiments.isEnabled(this.name);},setEnabled:function(enabled)
{this._experiments.setEnabled(this.name,enabled);}}
{(function parseQueryParameters()
{var queryParams=location.search;if(!queryParams)
return;var params=queryParams.substring(1).split("&");for(var i=0;i<params.length;++i){var pair=params[i].split("=");var name=pair.shift();Runtime._queryParamsObject[name]=pair.join("=");}})();}
Runtime.experiments=new Runtime.ExperimentsSupport();Runtime._remoteBase=Runtime.queryParam("remoteBase");{(function validateRemoteBase()
{var remoteBaseRegexp=/^https:\/\/chrome-devtools-frontend\.appspot\.com\/serve_file\/@[0-9a-zA-Z]+\/?$/;if(Runtime._remoteBase&&!remoteBaseRegexp.test(Runtime._remoteBase))
Runtime._remoteBase=null;})();}
Runtime.resolveSourceURL=function(path)
{var sourceURL=self.location.href;if(self.location.search)
sourceURL=sourceURL.replace(self.location.search,"");sourceURL=sourceURL.substring(0,sourceURL.lastIndexOf("/")+1)+path;return"\n/*# sourceURL="+sourceURL+" */";}
var runtime;console=console;console.__originalAssert=console.assert;console.assert=function(value,message)
{if(value)
return;console.__originalAssert(value,message);}
var ArrayLike;Object.isEmpty=function(obj)
{for(var i in obj)
return false;return true;}
Object.values=function(obj)
{var result=Object.keys(obj);var length=result.length;for(var i=0;i<length;++i)
result[i]=obj[result[i]];return result;}
function mod(m,n)
{return((m%n)+n)%n;}
String.prototype.findAll=function(string)
{var matches=[];var i=this.indexOf(string);while(i!==-1){matches.push(i);i=this.indexOf(string,i+string.length);}
return matches;}
String.prototype.replaceControlCharacters=function()
{return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g,"�");}
String.prototype.isWhitespace=function()
{return/^\s*$/.test(this);}
String.prototype.computeLineEndings=function()
{var endings=this.findAll("\n");endings.push(this.length);return endings;}
String.prototype.escapeCharacters=function(chars)
{var foundChar=false;for(var i=0;i<chars.length;++i){if(this.indexOf(chars.charAt(i))!==-1){foundChar=true;break;}}
if(!foundChar)
return String(this);var result="";for(var i=0;i<this.length;++i){if(chars.indexOf(this.charAt(i))!==-1)
result+="\\";result+=this.charAt(i);}
return result;}
String.regexSpecialCharacters=function()
{return"^[]{}()\\.^$*+?|-,";}
String.prototype.escapeForRegExp=function()
{return this.escapeCharacters(String.regexSpecialCharacters());}
String.prototype.escapeHTML=function()
{return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");}
String.prototype.unescapeHTML=function()
{return this.replace(/</g,"<").replace(/>/g,">").replace(/:/g,":").replace(/"/g,"\"").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");}
String.prototype.collapseWhitespace=function()
{return this.replace(/[\s\xA0]+/g," ");}
String.prototype.trimMiddle=function(maxLength)
{if(this.length<=maxLength)
return String(this);var leftHalf=maxLength>>1;var rightHalf=maxLength-leftHalf-1;return this.substr(0,leftHalf)+"\u2026"+this.substr(this.length-rightHalf,rightHalf);}
String.prototype.trimEnd=function(maxLength)
{if(this.length<=maxLength)
return String(this);return this.substr(0,maxLength-1)+"\u2026";}
String.prototype.trimURL=function(baseURLDomain)
{var result=this.replace(/^(https|http|file):\/\//i,"");if(baseURLDomain){if(result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
result=result.substr(baseURLDomain.length);}
return result;}
String.prototype.toTitleCase=function()
{return this.substring(0,1).toUpperCase()+this.substring(1);}
String.prototype.compareTo=function(other)
{if(this>other)
return 1;if(this<other)
return-1;return 0;}
String.prototype.removeURLFragment=function()
{var fragmentIndex=this.indexOf("#");if(fragmentIndex==-1)
fragmentIndex=this.length;return this.substring(0,fragmentIndex);}
String.hashCode=function(string)
{if(!string)
return 0;var p=((1<<30)*4-5);var z=0x5033d967;var z2=0x59d2f15d;var s=0;var zi=1;for(var i=0;i<string.length;i++){var xi=string.charCodeAt(i)*z2;s=(s+zi*xi)%p;zi=(zi*z)%p;}
s=(s+zi*(p-1))%p;return Math.abs(s|0);}
String.isDigitAt=function(string,index)
{var c=string.charCodeAt(index);return(48<=c&&c<=57);}
String.prototype.toBase64=function()
{function encodeBits(b)
{return b<26?b+65:b<52?b+71:b<62?b-4:b===62?43:b===63?47:65;}
var encoder=new TextEncoder();var data=encoder.encode(this.toString());var n=data.length;var encoded="";if(n===0)
return encoded;var shift;var v=0;for(var i=0;i<n;i++){shift=i%3;v|=data[i]<<(16>>>shift&24);if(shift===2){encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),encodeBits(v&63));v=0;}}
if(shift===0)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),61,61);else if(shift===1)
encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),61);return encoded;}
String.naturalOrderComparator=function(a,b)
{var chunk=/^\d+|^\D+/;var chunka,chunkb,anum,bnum;while(1){if(a){if(!b)
return 1;}else{if(b)
return-1;else
return 0;}
chunka=a.match(chunk)[0];chunkb=b.match(chunk)[0];anum=!isNaN(chunka);bnum=!isNaN(chunkb);if(anum&&!bnum)
return-1;if(bnum&&!anum)
return 1;if(anum&&bnum){var diff=chunka-chunkb;if(diff)
return diff;if(chunka.length!==chunkb.length){if(!+chunka&&!+chunkb)
return chunka.length-chunkb.length;else
return chunkb.length-chunka.length;}}else if(chunka!==chunkb)
return(chunka<chunkb)?-1:1;a=a.substring(chunka.length);b=b.substring(chunkb.length);}}
String.caseInsensetiveComparator=function(a,b)
{a=a.toUpperCase();b=b.toUpperCase();if(a===b)
return 0;return a>b?1:-1;}
Number.constrain=function(num,min,max)
{if(num<min)
num=min;else if(num>max)
num=max;return num;}
Number.gcd=function(a,b)
{if(b===0)
return a;else
return Number.gcd(b,a%b);}
Number.toFixedIfFloating=function(value)
{if(!value||isNaN(value))
return value;var number=Number(value);return number%1?number.toFixed(3):String(number);}
Date.prototype.toISO8601Compact=function()
{function leadZero(x)
{return(x>9?"":"0")+x;}
return this.getFullYear()+
leadZero(this.getMonth()+1)+
leadZero(this.getDate())+"T"+
leadZero(this.getHours())+
leadZero(this.getMinutes())+
leadZero(this.getSeconds());}
Date.prototype.toConsoleTime=function()
{function leadZero2(x)
{return(x>9?"":"0")+x;}
function leadZero3(x)
{return"0".repeat(3-x.toString().length)+x;}
return this.getFullYear()+"-"+
leadZero2(this.getMonth()+1)+"-"+
leadZero2(this.getDate())+" "+
leadZero2(this.getHours())+":"+
leadZero2(this.getMinutes())+":"+
leadZero2(this.getSeconds())+"."+
leadZero3(this.getMilliseconds());}
Object.defineProperty(Array.prototype,"remove",{value:function(value,firstOnly)
{var index=this.indexOf(value);if(index===-1)
return false;if(firstOnly){this.splice(index,1);return true;}
for(var i=index+1,n=this.length;i<n;++i){if(this[i]!==value)
this[index++]=this[i];}
this.length=index;return true;}});Object.defineProperty(Array.prototype,"keySet",{value:function()
{var keys={};for(var i=0;i<this.length;++i)
keys[this[i]]=true;return keys;}});Object.defineProperty(Array.prototype,"pushAll",{value:function(array)
{Array.prototype.push.apply(this,array);}});Object.defineProperty(Array.prototype,"rotate",{value:function(index)
{var result=[];for(var i=index;i<index+this.length;++i)
result.push(this[i%this.length]);return result;}});Object.defineProperty(Array.prototype,"sortNumbers",{value:function()
{function numericComparator(a,b)
{return a-b;}
this.sort(numericComparator);}});Object.defineProperty(Uint32Array.prototype,"sort",{value:Array.prototype.sort});(function(){var partition={value:function(comparator,left,right,pivotIndex)
{function swap(array,i1,i2)
{var temp=array[i1];array[i1]=array[i2];array[i2]=temp;}
var pivotValue=this[pivotIndex];swap(this,right,pivotIndex);var storeIndex=left;for(var i=left;i<right;++i){if(comparator(this[i],pivotValue)<0){swap(this,storeIndex,i);++storeIndex;}}
swap(this,right,storeIndex);return storeIndex;}};Object.defineProperty(Array.prototype,"partition",partition);Object.defineProperty(Uint32Array.prototype,"partition",partition);var sortRange={value:function(comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight)
{function quickSortRange(array,comparator,left,right,sortWindowLeft,sortWindowRight)
{if(right<=left)
return;var pivotIndex=Math.floor(Math.random()*(right-left))+left;var pivotNewIndex=array.partition(comparator,left,right,pivotIndex);if(sortWindowLeft<pivotNewIndex)
quickSortRange(array,comparator,left,pivotNewIndex-1,sortWindowLeft,sortWindowRight);if(pivotNewIndex<sortWindowRight)
quickSortRange(array,comparator,pivotNewIndex+1,right,sortWindowLeft,sortWindowRight);}
if(leftBound===0&&rightBound===(this.length-1)&&sortWindowLeft===0&&sortWindowRight>=rightBound)
this.sort(comparator);else
quickSortRange(this,comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight);return this;}}
Object.defineProperty(Array.prototype,"sortRange",sortRange);Object.defineProperty(Uint32Array.prototype,"sortRange",sortRange);})();Object.defineProperty(Array.prototype,"stableSort",{value:function(comparator)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var indices=new Array(this.length);for(var i=0;i<this.length;++i)
indices[i]=i;var self=this;function indexComparator(a,b)
{var result=comparator(self[a],self[b]);return result?result:a-b;}
indices.sort(indexComparator);for(var i=0;i<this.length;++i){if(indices[i]<0||i===indices[i])
continue;var cyclical=i;var saved=this[i];while(true){var next=indices[cyclical];indices[cyclical]=-1;if(next===i){this[cyclical]=saved;break;}else{this[cyclical]=this[next];cyclical=next;}}}
return this;}});Object.defineProperty(Array.prototype,"qselect",{value:function(k,comparator)
{if(k<0||k>=this.length)
return;if(!comparator)
comparator=function(a,b){return a-b;}
var low=0;var high=this.length-1;for(;;){var pivotPosition=this.partition(comparator,low,high,Math.floor((high+low)/2));if(pivotPosition===k)
return this[k];else if(pivotPosition>k)
high=pivotPosition-1;else
low=pivotPosition+1;}}});Object.defineProperty(Array.prototype,"lowerBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Array.prototype,"upperBound",{value:function(object,comparator,left,right)
{function defaultComparator(a,b)
{return a<b?-1:(a>b?1:0);}
comparator=comparator||defaultComparator;var l=left||0;var r=right!==undefined?right:this.length;while(l<r){var m=(l+r)>>1;if(comparator(object,this[m])>=0)
l=m+1;else
r=m;}
return r;}});Object.defineProperty(Uint32Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Uint32Array.prototype,"upperBound",{value:Array.prototype.upperBound});Object.defineProperty(Float64Array.prototype,"lowerBound",{value:Array.prototype.lowerBound});Object.defineProperty(Array.prototype,"binaryIndexOf",{value:function(value,comparator)
{var index=this.lowerBound(value,comparator);return index<this.length&&comparator(value,this[index])===0?index:-1;}});Object.defineProperty(Array.prototype,"select",{value:function(field)
{var result=new Array(this.length);for(var i=0;i<this.length;++i)
result[i]=this[i][field];return result;}});Object.defineProperty(Array.prototype,"peekLast",{value:function()
{return this[this.length-1];}});(function(){function mergeOrIntersect(array1,array2,comparator,mergeNotIntersect)
{var result=[];var i=0;var j=0;while(i<array1.length&&j<array2.length){var compareValue=comparator(array1[i],array2[j]);if(mergeNotIntersect||!compareValue)
result.push(compareValue<=0?array1[i]:array2[j]);if(compareValue<=0)
i++;if(compareValue>=0)
j++;}
if(mergeNotIntersect){while(i<array1.length)
result.push(array1[i++]);while(j<array2.length)
result.push(array2[j++]);}
return result;}
Object.defineProperty(Array.prototype,"intersectOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,false);}});Object.defineProperty(Array.prototype,"mergeOrdered",{value:function(array,comparator)
{return mergeOrIntersect(this,array,comparator,true);}});})();String.sprintf=function(format,var_arg)
{return String.vsprintf(format,Array.prototype.slice.call(arguments,1));}
String.tokenizeFormatString=function(format,formatters)
{var tokens=[];var substitutionIndex=0;function addStringToken(str)
{if(tokens.length&&tokens[tokens.length-1].type==="string")
tokens[tokens.length-1].value+=str;else
tokens.push({type:"string",value:str});}
function addSpecifierToken(specifier,precision,substitutionIndex)
{tokens.push({type:"specifier",specifier:specifier,precision:precision,substitutionIndex:substitutionIndex});}
var index=0;for(var precentIndex=format.indexOf("%",index);precentIndex!==-1;precentIndex=format.indexOf("%",index)){if(format.length===index)
break;addStringToken(format.substring(index,precentIndex));index=precentIndex+1;if(format[index]==="%"){addStringToken("%");++index;continue;}
if(String.isDigitAt(format,index)){var number=parseInt(format.substring(index),10);while(String.isDigitAt(format,index))
++index;if(number>0&&format[index]==="$"){substitutionIndex=(number-1);++index;}}
var precision=-1;if(format[index]==="."){++index;precision=parseInt(format.substring(index),10);if(isNaN(precision))
precision=0;while(String.isDigitAt(format,index))
++index;}
if(!(format[index]in formatters)){addStringToken(format.substring(precentIndex,index+1));++index;continue;}
addSpecifierToken(format[index],precision,substitutionIndex);++substitutionIndex;++index;}
addStringToken(format.substring(index));return tokens;}
String.standardFormatters={d:function(substitution)
{return!isNaN(substitution)?substitution:0;},f:function(substitution,token)
{if(substitution&&token.precision>-1)
substitution=substitution.toFixed(token.precision);return!isNaN(substitution)?substitution:(token.precision>-1?Number(0).toFixed(token.precision):0);},s:function(substitution)
{return substitution;}}
String.vsprintf=function(format,substitutions)
{return String.format(format,substitutions,String.standardFormatters,"",function(a,b){return a+b;}).formattedResult;}
String.format=function(format,substitutions,formatters,initialValue,append,tokenizedFormat)
{if(!format||!substitutions||!substitutions.length)
return{formattedResult:append(initialValue,format),unusedSubstitutions:substitutions};function prettyFunctionName()
{return"String.format(\""+format+"\", \""+Array.prototype.join.call(substitutions,"\", \"")+"\")";}
function warn(msg)
{console.warn(prettyFunctionName()+": "+msg);}
function error(msg)
{console.error(prettyFunctionName()+": "+msg);}
var result=initialValue;var tokens=tokenizedFormat||String.tokenizeFormatString(format,formatters);var usedSubstitutionIndexes={};for(var i=0;i<tokens.length;++i){var token=tokens[i];if(token.type==="string"){result=append(result,token.value);continue;}
if(token.type!=="specifier"){error("Unknown token type \""+token.type+"\" found.");continue;}
if(token.substitutionIndex>=substitutions.length){error("not enough substitution arguments. Had "+substitutions.length+" but needed "+(token.substitutionIndex+1)+", so substitution was skipped.");result=append(result,"%"+(token.precision>-1?token.precision:"")+token.specifier);continue;}
usedSubstitutionIndexes[token.substitutionIndex]=true;if(!(token.specifier in formatters)){warn("unsupported format character \u201C"+token.specifier+"\u201D. Treating as a string.");result=append(result,substitutions[token.substitutionIndex]);continue;}
result=append(result,formatters[token.specifier](substitutions[token.substitutionIndex],token));}
var unusedSubstitutions=[];for(var i=0;i<substitutions.length;++i){if(i in usedSubstitutionIndexes)
continue;unusedSubstitutions.push(substitutions[i]);}
return{formattedResult:result,unusedSubstitutions:unusedSubstitutions};}
function createSearchRegex(query,caseSensitive,isRegex)
{var regexFlags=caseSensitive?"g":"gi";var regexObject;if(isRegex){try{regexObject=new RegExp(query,regexFlags);}catch(e){}}
if(!regexObject)
regexObject=createPlainTextSearchRegex(query,regexFlags);return regexObject;}
function createPlainTextSearchRegex(query,flags)
{var regexSpecialCharacters=String.regexSpecialCharacters();var regex="";for(var i=0;i<query.length;++i){var c=query.charAt(i);if(regexSpecialCharacters.indexOf(c)!=-1)
regex+="\\";regex+=c;}
return new RegExp(regex,flags||"");}
function countRegexMatches(regex,content)
{var text=content;var result=0;var match;while(text&&(match=regex.exec(text))){if(match[0].length>0)
++result;text=text.substring(match.index+1);}
return result;}
function spacesPadding(spacesCount)
{return"\u00a0".repeat(spacesCount);}
function numberToStringWithSpacesPadding(value,symbolsCount)
{var numberString=value.toString();var paddingLength=Math.max(0,symbolsCount-numberString.length);return spacesPadding(paddingLength)+numberString;}
Set.prototype.valuesArray=function()
{return Array.from(this.values());}
Set.prototype.addAll=function(iterable)
{for(var e of iterable)
this.add(e);}
Set.prototype.containsAll=function(iterable)
{for(var e of iterable){if(!this.has(e))
return false;}
return true;}
Map.prototype.remove=function(key)
{var value=this.get(key);this.delete(key);return value;}
Map.prototype.valuesArray=function()
{return Array.from(this.values());}
Map.prototype.keysArray=function()
{return Array.from(this.keys());}
Map.prototype.inverse=function()
{var result=new Multimap();for(var key of this.keys()){var value=this.get(key);result.set(value,key);}
return result;}
var Multimap=function()
{this._map=new Map();}
Multimap.prototype={set:function(key,value)
{var set=this._map.get(key);if(!set){set=new Set();this._map.set(key,set);}
set.add(value);},get:function(key)
{var result=this._map.get(key);if(!result)
result=new Set();return result;},has:function(key)
{return this._map.has(key);},hasValue:function(key,value)
{var set=this._map.get(key);if(!set)
return false;return set.has(value);},get size()
{return this._map.size;},remove:function(key,value)
{var values=this.get(key);values.delete(value);if(!values.size)
this._map.delete(key);},removeAll:function(key)
{this._map.delete(key);},keysArray:function()
{return this._map.keysArray();},valuesArray:function()
{var result=[];var keys=this.keysArray();for(var i=0;i<keys.length;++i)
result.pushAll(this.get(keys[i]).valuesArray());return result;},clear:function()
{this._map.clear();}}
function loadXHR(url)
{return new Promise(load);function load(successCallback,failureCallback)
{function onReadyStateChanged()
{if(xhr.readyState!==XMLHttpRequest.DONE)
return;if(xhr.status!==200){xhr.onreadystatechange=null;failureCallback(new Error(xhr.status));return;}
xhr.onreadystatechange=null;successCallback(xhr.responseText);}
var xhr=new XMLHttpRequest();xhr.withCredentials=false;xhr.open("GET",url,true);xhr.onreadystatechange=onReadyStateChanged;xhr.send(null);}}
function CallbackBarrier()
{this._pendingIncomingCallbacksCount=0;}
CallbackBarrier.prototype={createCallback:function(userCallback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");++this._pendingIncomingCallbacksCount;return this._incomingCallback.bind(this,userCallback);},callWhenDone:function(callback)
{console.assert(!this._outgoingCallback,"CallbackBarrier.callWhenDone() is called multiple times");this._outgoingCallback=callback;if(!this._pendingIncomingCallbacksCount)
this._outgoingCallback();},donePromise:function()
{return new Promise(promiseConstructor.bind(this));function promiseConstructor(success)
{this.callWhenDone(success);}},_incomingCallback:function(userCallback)
{console.assert(this._pendingIncomingCallbacksCount>0);if(userCallback){var args=Array.prototype.slice.call(arguments,1);userCallback.apply(null,args);}
if(!--this._pendingIncomingCallbacksCount&&this._outgoingCallback)
this._outgoingCallback();}}
function suppressUnused(value)
{}
self.setImmediate=function(callback)
{Promise.resolve().then(callback);return 0;}
Promise.prototype.spread=function(callback)
{return this.then(spreadPromise);function spreadPromise(arg)
{return callback.apply(null,arg);}}
Promise.prototype.catchException=function(defaultValue){return this.catch(function(error){console.error(error);return defaultValue;});}
Map.prototype.diff=function(other,isEqual)
{var leftKeys=this.keysArray();var rightKeys=other.keysArray();leftKeys.sort((a,b)=>a-b);rightKeys.sort((a,b)=>a-b);var removed=[];var added=[];var equal=[];var leftIndex=0;var rightIndex=0;while(leftIndex<leftKeys.length&&rightIndex<rightKeys.length){var leftKey=leftKeys[leftIndex];var rightKey=rightKeys[rightIndex];if(leftKey===rightKey&&isEqual(this.get(leftKey),other.get(rightKey))){equal.push(this.get(leftKey));++leftIndex;++rightIndex;continue;}
if(leftKey<=rightKey){removed.push(this.get(leftKey));++leftIndex;continue;}
added.push(other.get(rightKey));++rightIndex;}
while(leftIndex<leftKeys.length){var leftKey=leftKeys[leftIndex++];removed.push(this.get(leftKey));}
while(rightIndex<rightKeys.length){var rightKey=rightKeys[rightIndex++];added.push(other.get(rightKey));}
return{added:added,removed:removed,equal:equal}};Node.prototype.rangeOfWord=function(offset,stopCharacters,stayWithinNode,direction)
{var startNode;var startOffset=0;var endNode;var endOffset=0;if(!stayWithinNode)
stayWithinNode=this;if(!direction||direction==="backward"||direction==="both"){var node=this;while(node){if(node===stayWithinNode){if(!startNode)
startNode=stayWithinNode;break;}
if(node.nodeType===Node.TEXT_NODE){var start=(node===this?(offset-1):(node.nodeValue.length-1));for(var i=start;i>=0;--i){if(stopCharacters.indexOf(node.nodeValue[i])!==-1){startNode=node;startOffset=i+1;break;}}}
if(startNode)
break;node=node.traversePreviousNode(stayWithinNode);}
if(!startNode){startNode=stayWithinNode;startOffset=0;}}else{startNode=this;startOffset=offset;}
if(!direction||direction==="forward"||direction==="both"){node=this;while(node){if(node===stayWithinNode){if(!endNode)
endNode=stayWithinNode;break;}
if(node.nodeType===Node.TEXT_NODE){var start=(node===this?offset:0);for(var i=start;i<node.nodeValue.length;++i){if(stopCharacters.indexOf(node.nodeValue[i])!==-1){endNode=node;endOffset=i;break;}}}
if(endNode)
break;node=node.traverseNextNode(stayWithinNode);}
if(!endNode){endNode=stayWithinNode;endOffset=stayWithinNode.nodeType===Node.TEXT_NODE?stayWithinNode.nodeValue.length:stayWithinNode.childNodes.length;}}else{endNode=this;endOffset=offset;}
var result=this.ownerDocument.createRange();result.setStart(startNode,startOffset);result.setEnd(endNode,endOffset);return result;}
Node.prototype.traverseNextTextNode=function(stayWithin)
{var node=this.traverseNextNode(stayWithin);if(!node)
return null;var nonTextTags={"STYLE":1,"SCRIPT":1};while(node&&(node.nodeType!==Node.TEXT_NODE||nonTextTags[node.parentElement.nodeName]))
node=node.traverseNextNode(stayWithin);return node;}
Element.prototype.positionAt=function(x,y,relativeTo)
{var shift={x:0,y:0};if(relativeTo)
shift=relativeTo.boxInWindow(this.ownerDocument.defaultView);if(typeof x==="number")
this.style.setProperty("left",(shift.x+x)+"px");else
this.style.removeProperty("left");if(typeof y==="number")
this.style.setProperty("top",(shift.y+y)+"px");else
this.style.removeProperty("top");if(typeof x==="number"||typeof y==="number")
this.style.setProperty("position","absolute");else
this.style.removeProperty("position");}
Element.prototype.isScrolledToBottom=function()
{return Math.abs(this.scrollTop+this.clientHeight-this.scrollHeight)<=2;}
function removeSubsequentNodes(fromNode,toNode)
{for(var node=fromNode;node&&node!==toNode;){var nodeToRemove=node;node=node.nextSibling;nodeToRemove.remove();}}
Element.prototype.containsEventPoint=function(event)
{var box=this.getBoundingClientRect();return box.left<event.x&&event.x<box.right&&box.top<event.y&&event.y<box.bottom;}
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray=function(nameArray)
{for(var node=this;node&&node!==this.ownerDocument;node=node.parentNodeOrShadowHost()){for(var i=0;i<nameArray.length;++i){if(node.nodeName.toLowerCase()===nameArray[i].toLowerCase())
return node;}}
return null;}
Node.prototype.enclosingNodeOrSelfWithNodeName=function(nodeName)
{return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);}
Node.prototype.enclosingNodeOrSelfWithClass=function(className,stayWithin)
{return this.enclosingNodeOrSelfWithClassList([className],stayWithin);}
Node.prototype.enclosingNodeOrSelfWithClassList=function(classNames,stayWithin)
{for(var node=this;node&&node!==stayWithin&&node!==this.ownerDocument;node=node.parentNodeOrShadowHost()){if(node.nodeType===Node.ELEMENT_NODE){var containsAll=true;for(var i=0;i<classNames.length&&containsAll;++i){if(!node.classList.contains(classNames[i]))
containsAll=false;}
if(containsAll)
return(node);}}
return null;}
Node.prototype.parentElementOrShadowHost=function()
{var node=this.parentNode;if(!node)
return null;if(node.nodeType===Node.ELEMENT_NODE)
return(node);if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)
return(node.host);return null;}
Node.prototype.parentNodeOrShadowHost=function()
{return this.parentNode||this.host||null;}
Node.prototype.getComponentSelection=function()
{var parent=this.parentNode;while(parent&&parent.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)
parent=parent.parentNode;return parent instanceof ShadowRoot?parent.getSelection():this.window().getSelection();}
Node.prototype.isComponentSelectionCollapsed=function()
{var selection=this.getComponentSelection();var range=selection&&selection.rangeCount?selection.getRangeAt(0):null;return range?range.collapsed:true;}
Node.prototype.getDeepSelection=function()
{var activeElement=this.ownerDocument.activeElement;var shadowRoot=null;while(activeElement&&activeElement.shadowRoot){shadowRoot=activeElement.shadowRoot;activeElement=shadowRoot.activeElement;}
return shadowRoot?shadowRoot.getSelection():this.window().getSelection();}
Node.prototype.window=function()
{return this.ownerDocument.defaultView;}
Element.prototype.query=function(query)
{return this.ownerDocument.evaluate(query,this,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;}
Element.prototype.removeChildren=function()
{if(this.firstChild)
this.textContent="";}
Element.prototype.isInsertionCaretInside=function()
{var selection=this.getComponentSelection();var selectionRange=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!selectionRange||!selection.isCollapsed)
return false;return selectionRange.startContainer.isSelfOrDescendant(this);}
function createElement(tagName,customElementType)
{return document.createElement(tagName,customElementType||"");}
function createEvent(type,bubbles,cancelable)
{var event=document.createEvent("Event");event.initEvent(type,bubbles,cancelable);return event;}
function createTextNode(data)
{return document.createTextNode(data);}
Document.prototype.createElementWithClass=function(elementName,className,customElementType)
{var element=this.createElement(elementName,customElementType||"");if(className)
element.className=className;return element;}
function createElementWithClass(elementName,className,customElementType)
{return document.createElementWithClass(elementName,className,customElementType);}
Document.prototype.createSVGElement=function(childType,className)
{var element=this.createElementNS("http://www.w3.org/2000/svg",childType);if(className)
element.setAttribute("class",className);return element;}
function createSVGElement(childType,className)
{return document.createSVGElement(childType,className);}
function createDocumentFragment()
{return document.createDocumentFragment();}
Element.prototype.createChild=function(elementName,className,customElementType)
{var element=this.ownerDocument.createElementWithClass(elementName,className,customElementType);this.appendChild(element);return element;}
DocumentFragment.prototype.createChild=Element.prototype.createChild;Element.prototype.createTextChild=function(text)
{var element=this.ownerDocument.createTextNode(text);this.appendChild(element);return element;}
DocumentFragment.prototype.createTextChild=Element.prototype.createTextChild;Element.prototype.createTextChildren=function(var_args)
{for(var i=0,n=arguments.length;i<n;++i)
this.createTextChild(arguments[i]);}
DocumentFragment.prototype.createTextChildren=Element.prototype.createTextChildren;Element.prototype.totalOffsetLeft=function()
{return this.totalOffset().left;}
Element.prototype.totalOffsetTop=function()
{return this.totalOffset().top;}
Element.prototype.totalOffset=function()
{var rect=this.getBoundingClientRect();return{left:rect.left,top:rect.top};}
Element.prototype.scrollOffset=function()
{var curLeft=0;var curTop=0;for(var element=this;element;element=element.scrollParent){curLeft+=element.scrollLeft;curTop+=element.scrollTop;}
return{left:curLeft,top:curTop};}
Element.prototype.createSVGChild=function(childType,className)
{var child=this.ownerDocument.createSVGElement(childType,className);this.appendChild(child);return child;}
function AnchorBox(x,y,width,height)
{this.x=x||0;this.y=y||0;this.width=width||0;this.height=height||0;}
AnchorBox.prototype.relativeTo=function(box)
{return new AnchorBox(this.x-box.x,this.y-box.y,this.width,this.height);}
AnchorBox.prototype.relativeToElement=function(element)
{return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView));}
AnchorBox.prototype.equals=function(anchorBox)
{return!!anchorBox&&this.x===anchorBox.x&&this.y===anchorBox.y&&this.width===anchorBox.width&&this.height===anchorBox.height;}
Element.prototype.offsetRelativeToWindow=function(targetWindow)
{var elementOffset=new AnchorBox();var curElement=this;var curWindow=this.ownerDocument.defaultView;while(curWindow&&curElement){elementOffset.x+=curElement.totalOffsetLeft();elementOffset.y+=curElement.totalOffsetTop();if(curWindow===targetWindow)
break;curElement=curWindow.frameElement;curWindow=curWindow.parent;}
return elementOffset;}
Element.prototype.boxInWindow=function(targetWindow)
{targetWindow=targetWindow||this.ownerDocument.defaultView;var anchorBox=this.offsetRelativeToWindow(window);anchorBox.width=Math.min(this.offsetWidth,window.innerWidth-anchorBox.x);anchorBox.height=Math.min(this.offsetHeight,window.innerHeight-anchorBox.y);return anchorBox;}
Element.prototype.setTextAndTitle=function(text)
{this.textContent=text;this.title=text;}
KeyboardEvent.prototype.__defineGetter__("data",function()
{switch(this.type){case"keypress":if(!this.ctrlKey&&!this.metaKey)
return String.fromCharCode(this.charCode);else
return"";case"keydown":case"keyup":if(!this.ctrlKey&&!this.metaKey&&!this.altKey)
return String.fromCharCode(this.which);else
return"";}});Event.prototype.consume=function(preventDefault)
{this.stopImmediatePropagation();if(preventDefault)
this.preventDefault();this.handled=true;}
Text.prototype.select=function(start,end)
{start=start||0;end=end||this.textContent.length;if(start<0)
start=end+start;var selection=this.getComponentSelection();selection.removeAllRanges();var range=this.ownerDocument.createRange();range.setStart(this,start);range.setEnd(this,end);selection.addRange(range);return this;}
Element.prototype.selectionLeftOffset=function()
{var selection=this.getComponentSelection();if(!selection.containsNode(this,true))
return null;var leftOffset=selection.anchorOffset;var node=selection.anchorNode;while(node!==this){while(node.previousSibling){node=node.previousSibling;leftOffset+=node.textContent.length;}
node=node.parentNodeOrShadowHost();}
return leftOffset;}
HTMLImageElement.prototype.completePromise=function()
{var element=this;if(element.complete)
return Promise.resolve(element);return new Promise(promiseBody);function promiseBody(resolve)
{element.addEventListener("load",oncomplete);element.addEventListener("error",oncomplete);function oncomplete()
{resolve(element);}}}
Node.prototype.appendChildren=function(var_args)
{for(var i=0,n=arguments.length;i<n;++i)
this.appendChild(arguments[i]);}
Node.prototype.deepTextContent=function()
{return this.childTextNodes().map(function(node){return node.textContent;}).join("");}
Node.prototype.childTextNodes=function()
{var node=this.traverseNextTextNode(this);var result=[];var nonTextTags={"STYLE":1,"SCRIPT":1};while(node){if(!nonTextTags[node.parentElement.nodeName])
result.push(node);node=node.traverseNextTextNode(this);}
return result;}
Node.prototype.isAncestor=function(node)
{if(!node)
return false;var currentNode=node.parentNodeOrShadowHost();while(currentNode){if(this===currentNode)
return true;currentNode=currentNode.parentNodeOrShadowHost();}
return false;}
Node.prototype.isDescendant=function(descendant)
{return!!descendant&&descendant.isAncestor(this);}
Node.prototype.isSelfOrAncestor=function(node)
{return!!node&&(node===this||this.isAncestor(node));}
Node.prototype.isSelfOrDescendant=function(node)
{return!!node&&(node===this||this.isDescendant(node));}
Node.prototype.traverseNextNode=function(stayWithin)
{if(this.shadowRoot)
return this.shadowRoot;var distributedNodes=this.getDistributedNodes?this.getDistributedNodes():[];if(distributedNodes.length)
return distributedNodes[0];if(this.firstChild)
return this.firstChild;var node=this;while(node){if(stayWithin&&node===stayWithin)
return null;var sibling=nextSibling(node);if(sibling)
return sibling;node=insertionPoint(node)||node.parentNodeOrShadowHost();}
function nextSibling(node)
{var parent=insertionPoint(node);if(!parent)
return node.nextSibling;var distributedNodes=parent.getDistributedNodes?parent.getDistributedNodes():[];var position=Array.prototype.indexOf.call(distributedNodes,node);if(position+1<distributedNodes.length)
return distributedNodes[position+1];return null;}
function insertionPoint(node)
{var insertionPoints=node.getDestinationInsertionPoints?node.getDestinationInsertionPoints():[];return insertionPoints.length>0?insertionPoints[insertionPoints.length-1]:null;}
return null;}
Node.prototype.traversePreviousNode=function(stayWithin)
{if(stayWithin&&this===stayWithin)
return null;var node=this.previousSibling;while(node&&node.lastChild)
node=node.lastChild;if(node)
return node;return this.parentNodeOrShadowHost();}
Node.prototype.setTextContentTruncatedIfNeeded=function(text,placeholder)
{const maxTextContentLength=10000;if(typeof text==="string"&&text.length>maxTextContentLength){this.textContent=typeof placeholder==="string"?placeholder:text.trimMiddle(maxTextContentLength);return true;}
this.textContent=text;return false;}
Event.prototype.deepElementFromPoint=function()
{var node=this.target;while(node&&node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&node.nodeType!==Node.DOCUMENT_NODE)
node=node.parentNode;if(!node)
return null;node=node.elementFromPoint(this.pageX,this.pageY);while(node&&node.shadowRoot)
node=node.shadowRoot.elementFromPoint(this.pageX,this.pageY);return node;}
Event.prototype.deepActiveElement=function()
{var activeElement=this.target&&this.target.ownerDocument?this.target.ownerDocument.activeElement:null;while(activeElement&&activeElement.shadowRoot)
activeElement=activeElement.shadowRoot.activeElement;return activeElement;}
Document.prototype.deepElementFromPoint=function(x,y)
{var node=this.elementFromPoint(x,y);while(node&&node.shadowRoot)
node=node.shadowRoot.elementFromPoint(x,y);return node;}
function isEnterKey(event)
{return event.keyCode!==229&&event.keyIdentifier==="Enter";}
function isEscKey(event)
{return event.keyCode===27;}
function consumeEvent(e)
{e.consume();}
function runOnWindowLoad(callback)
{function windowLoaded()
{window.removeEventListener("DOMContentLoaded",windowLoaded,false);callback();}
if(document.readyState==="complete"||document.readyState==="interactive")
callback();else
window.addEventListener("DOMContentLoaded",windowLoaded,false);};(function()
{function toolboxLoaded()
{if(!window.opener)
return;var app=window.opener.WebInspector["AdvancedApp"]["_instance"]();app["toolboxLoaded"](document);}
runOnWindowLoad(toolboxLoaded);})();;applicationDescriptor={"has_html":true,"modules":[{"type":"autostart","name":"platform"},{"type":"autostart","name":"toolbox_bootstrap"}]};Runtime.startApplication("toolbox");
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | WebInspector.DataGrid=function(columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback) {this.element=createElementWithClass("div","data-grid");WebInspector.appendStyle(this.element,"ui_lazy/dataGrid.css");this.element.tabIndex=0;this.element.addEventListener("keydown",this._keyDown.bind(this),false);var headerContainer=createElementWithClass("div","header-container");this._headerTable=headerContainer.createChild("table","header");this._headerTableHeaders={};this._scrollContainer=createElementWithClass("div","data-container");this._dataTable=this._scrollContainer.createChild("table","data");this._dataTable.addEventListener("mousedown",this._mouseDownInDataTable.bind(this));this._dataTable.addEventListener("click",this._clickInDataTable.bind(this),true);this._dataTable.addEventListener("contextmenu",this._contextMenuInDataTable.bind(this),true);if(editCallback) this._dataTable.addEventListener("dblclick",this._ondblclick.bind(this),false);this._editCallback=editCallback;this._deleteCallback=deleteCallback;this._refreshCallback=refreshCallback;this._contextMenuCallback=contextMenuCallback;this.element.appendChild(headerContainer);this.element.appendChild(this._scrollContainer);this._headerRow=createElement("tr");this._headerTableColumnGroup=createElement("colgroup");this._dataTableColumnGroup=createElement("colgroup");this._topFillerRow=createElementWithClass("tr","data-grid-filler-row revealed");this._bottomFillerRow=createElementWithClass("tr","data-grid-filler-row revealed");this.setVerticalPadding(0,0);this._inline=false;this._columnsArray=columnsArray;this._visibleColumnsArray=columnsArray;this._columns={};this._cellClass=null;for(var i=0;i<columnsArray.length;++i){var column=columnsArray[i];var columnIdentifier=column.identifier=column.id||String(i);this._columns[columnIdentifier]=column;if(column.disclosure) this.disclosureColumnIdentifier=columnIdentifier;var cell=createElement("th");cell.className=columnIdentifier+"-column";cell.columnIdentifier=String(columnIdentifier);this._headerTableHeaders[columnIdentifier]=cell;var div=createElement("div");if(column.titleDOMFragment) div.appendChild(column.titleDOMFragment);else div.textContent=column.title;cell.appendChild(div);if(column.sort){cell.classList.add(column.sort);this._sortColumnCell=cell;} if(column.sortable){cell.addEventListener("click",this._clickInHeaderCell.bind(this),false);cell.classList.add("sortable");cell.createChild("div","sort-order-icon-container").createChild("div","sort-order-icon");}} this._headerTable.appendChild(this._headerTableColumnGroup);this.headerTableBody.appendChild(this._headerRow);this._dataTable.appendChild(this._dataTableColumnGroup);this.dataTableBody.appendChild(this._topFillerRow);this.dataTableBody.appendChild(this._bottomFillerRow);this._refreshHeader();this._editing=false;this.selectedNode=null;this.expandNodesWhenArrowing=false;this.setRootNode(new WebInspector.DataGridNode());this.indentWidth=15;this._resizers=[];this._columnWidthsInitialized=false;this._cornerWidth=WebInspector.DataGrid.CornerWidth;this._resizeMethod=WebInspector.DataGrid.ResizeMethod.Nearest;} WebInspector.DataGrid.CornerWidth=14;WebInspector.DataGrid.ColumnDescriptor;WebInspector.DataGrid.Events={SelectedNode:"SelectedNode",DeselectedNode:"DeselectedNode",SortingChanged:"SortingChanged",ColumnsResized:"ColumnsResized"} WebInspector.DataGrid.Order={Ascending:"sort-ascending",Descending:"sort-descending"} WebInspector.DataGrid.Align={Center:"center",Right:"right"} WebInspector.DataGrid._preferredWidthSymbol=Symbol("preferredWidth");WebInspector.DataGrid.prototype={setCellClass:function(cellClass) {this._cellClass=cellClass;},_refreshHeader:function() {this._headerTableColumnGroup.removeChildren();this._dataTableColumnGroup.removeChildren();this._headerRow.removeChildren();this._topFillerRow.removeChildren();this._bottomFillerRow.removeChildren();for(var i=0;i<this._visibleColumnsArray.length;++i){var column=this._visibleColumnsArray[i];var columnIdentifier=column.identifier||String(i);var headerColumn=this._headerTableColumnGroup.createChild("col");var dataColumn=this._dataTableColumnGroup.createChild("col");if(column.width){headerColumn.style.width=column.width;dataColumn.style.width=column.width;} this._headerRow.appendChild(this._headerTableHeaders[columnIdentifier]);this._topFillerRow.createChild("td","top-filler-td");this._bottomFillerRow.createChild("td","bottom-filler-td").columnIdentifier_=columnIdentifier;} this._headerRow.createChild("th","corner");this._topFillerRow.createChild("td","corner").classList.add("top-filler-td");this._bottomFillerRow.createChild("td","corner").classList.add("bottom-filler-td");this._headerTableColumnGroup.createChild("col","corner");this._dataTableColumnGroup.createChild("col","corner");},setVerticalPadding:function(top,bottom) {this._topFillerRow.style.height=top+"px";if(top||bottom) this._bottomFillerRow.style.height=bottom+"px";else this._bottomFillerRow.style.height="auto";},setRootNode:function(rootNode) {if(this._rootNode){this._rootNode.removeChildren();this._rootNode.dataGrid=null;this._rootNode._isRoot=false;} this._rootNode=rootNode;rootNode._isRoot=true;rootNode.hasChildren=false;rootNode._expanded=true;rootNode._revealed=true;rootNode.selectable=false;rootNode.dataGrid=this;},rootNode:function() {return this._rootNode;},_ondblclick:function(event) {if(this._editing||this._editingNode) return;var columnIdentifier=this.columnIdentifierFromNode(event.target);if(!columnIdentifier||!this._columns[columnIdentifier].editable) return;this._startEditing(event.target);},_startEditingColumnOfDataGridNode:function(node,cellIndex) {this._editing=true;this._editingNode=node;this._editingNode.select();var element=this._editingNode._element.children[cellIndex];WebInspector.InplaceEditor.startEditing(element,this._startEditingConfig(element));element.getComponentSelection().setBaseAndExtent(element,0,element,1);},_startEditing:function(target) {var element=target.enclosingNodeOrSelfWithNodeName("td");if(!element) return;this._editingNode=this.dataGridNodeFromNode(target);if(!this._editingNode){if(!this.creationNode) return;this._editingNode=this.creationNode;} if(this._editingNode.isCreationNode) return this._startEditingColumnOfDataGridNode(this._editingNode,this._nextEditableColumn(-1));this._editing=true;WebInspector.InplaceEditor.startEditing(element,this._startEditingConfig(element));element.getComponentSelection().setBaseAndExtent(element,0,element,1);},renderInline:function() {this.element.classList.add("inline");this._cornerWidth=0;this._inline=true;this.updateWidths();},_startEditingConfig:function(element) {return new WebInspector.InplaceEditor.Config(this._editingCommitted.bind(this),this._editingCancelled.bind(this),element.textContent);},_editingCommitted:function(element,newText,oldText,context,moveDirection) {var columnIdentifier=this.columnIdentifierFromNode(element);if(!columnIdentifier){this._editingCancelled(element);return;} var column=this._columns[columnIdentifier];var cellIndex=this._visibleColumnsArray.indexOf(column);var textBeforeEditing=this._editingNode.data[columnIdentifier];var currentEditingNode=this._editingNode;function moveToNextIfNeeded(wasChange) {if(!moveDirection) return;if(moveDirection==="forward"){var firstEditableColumn=this._nextEditableColumn(-1);if(currentEditingNode.isCreationNode&&cellIndex===firstEditableColumn&&!wasChange) return;var nextEditableColumn=this._nextEditableColumn(cellIndex);if(nextEditableColumn!==-1) return this._startEditingColumnOfDataGridNode(currentEditingNode,nextEditableColumn);var nextDataGridNode=currentEditingNode.traverseNextNode(true,null,true);if(nextDataGridNode) return this._startEditingColumnOfDataGridNode(nextDataGridNode,firstEditableColumn);if(currentEditingNode.isCreationNode&&wasChange){this.addCreationNode(false);return this._startEditingColumnOfDataGridNode(this.creationNode,firstEditableColumn);} return;} if(moveDirection==="backward"){var prevEditableColumn=this._nextEditableColumn(cellIndex,true);if(prevEditableColumn!==-1) return this._startEditingColumnOfDataGridNode(currentEditingNode,prevEditableColumn);var lastEditableColumn=this._nextEditableColumn(this._visibleColumnsArray.length,true);var nextDataGridNode=currentEditingNode.traversePreviousNode(true,true);if(nextDataGridNode) return this._startEditingColumnOfDataGridNode(nextDataGridNode,lastEditableColumn);return;}} if(textBeforeEditing==newText){this._editingCancelled(element);moveToNextIfNeeded.call(this,false);return;} this._editingNode.data[columnIdentifier]=newText;this._editCallback(this._editingNode,columnIdentifier,textBeforeEditing,newText);if(this._editingNode.isCreationNode) this.addCreationNode(false);this._editingCancelled(element);moveToNextIfNeeded.call(this,true);},_editingCancelled:function(element) {this._editing=false;this._editingNode=null;},_nextEditableColumn:function(cellIndex,moveBackward) {var increment=moveBackward?-1:1;var columns=this._visibleColumnsArray;for(var i=cellIndex+increment;(i>=0)&&(i<columns.length);i+=increment){if(columns[i].editable) return i;} return-1;},sortColumnIdentifier:function() {if(!this._sortColumnCell) return null;return this._sortColumnCell.columnIdentifier;},sortOrder:function() {if(!this._sortColumnCell||this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Ascending)) return WebInspector.DataGrid.Order.Ascending;if(this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Descending)) return WebInspector.DataGrid.Order.Descending;return null;},isSortOrderAscending:function() {return!this._sortColumnCell||this._sortColumnCell.classList.contains(WebInspector.DataGrid.Order.Ascending);},get headerTableBody() {if("_headerTableBody"in this) return this._headerTableBody;this._headerTableBody=this._headerTable.getElementsByTagName("tbody")[0];if(!this._headerTableBody){this._headerTableBody=this.element.ownerDocument.createElement("tbody");this._headerTable.insertBefore(this._headerTableBody,this._headerTable.tFoot);} return this._headerTableBody;},get dataTableBody() {if("_dataTableBody"in this) return this._dataTableBody;this._dataTableBody=this._dataTable.getElementsByTagName("tbody")[0];if(!this._dataTableBody){this._dataTableBody=this.element.ownerDocument.createElement("tbody");this._dataTable.insertBefore(this._dataTableBody,this._dataTable.tFoot);} return this._dataTableBody;},_autoSizeWidths:function(widths,minPercent,maxPercent) {if(minPercent) minPercent=Math.min(minPercent,Math.floor(100/widths.length));var totalWidth=0;for(var i=0;i<widths.length;++i) totalWidth+=widths[i];var totalPercentWidth=0;for(var i=0;i<widths.length;++i){var width=Math.round(100*widths[i]/totalWidth);if(minPercent&&width<minPercent) width=minPercent;else if(maxPercent&&width>maxPercent) width=maxPercent;totalPercentWidth+=width;widths[i]=width;} var recoupPercent=totalPercentWidth-100;while(minPercent&&recoupPercent>0){for(var i=0;i<widths.length;++i){if(widths[i]>minPercent){--widths[i];--recoupPercent;if(!recoupPercent) break;}}} while(maxPercent&&recoupPercent<0){for(var i=0;i<widths.length;++i){if(widths[i]<maxPercent){++widths[i];++recoupPercent;if(!recoupPercent) break;}}} return widths;},autoSizeColumns:function(minPercent,maxPercent,maxDescentLevel) {var widths=[];for(var i=0;i<this._columnsArray.length;++i) widths.push((this._columnsArray[i].title||"").length);maxDescentLevel=maxDescentLevel||0;var children=this._enumerateChildren(this._rootNode,[],maxDescentLevel+1);for(var i=0;i<children.length;++i){var node=children[i];for(var j=0;j<this._columnsArray.length;++j){var text=node.data[this._columnsArray[j].identifier]||"";if(text.length>widths[j]) widths[j]=text.length;}} widths=this._autoSizeWidths(widths,minPercent,maxPercent);for(var i=0;i<this._columnsArray.length;++i) this._columnsArray[i].weight=widths[i];this._columnWidthsInitialized=false;this.updateWidths();},_enumerateChildren:function(rootNode,result,maxLevel) {if(!rootNode._isRoot) result.push(rootNode);if(!maxLevel) return;for(var i=0;i<rootNode.children.length;++i) this._enumerateChildren(rootNode.children[i],result,maxLevel-1);return result;},onResize:function() {this.updateWidths();},updateWidths:function() {var headerTableColumns=this._headerTableColumnGroup.children;var tableWidth=this.element.offsetWidth-this._cornerWidth;var numColumns=headerTableColumns.length-1;if(!this._columnWidthsInitialized&&this.element.offsetWidth){for(var i=0;i<numColumns;i++){var columnWidth=this.headerTableBody.rows[0].cells[i].offsetWidth;var column=this._visibleColumnsArray[i];if(!column.weight) column.weight=100*columnWidth/tableWidth;} this._columnWidthsInitialized=true;} this._applyColumnWeights();},setName:function(name) {this._columnWeightsSetting=WebInspector.settings.createSetting("dataGrid-"+name+"-columnWeights",{});this._loadColumnWeights();},_loadColumnWeights:function() {if(!this._columnWeightsSetting) return;var weights=this._columnWeightsSetting.get();for(var i=0;i<this._columnsArray.length;++i){var column=this._columnsArray[i];var weight=weights[column.identifier];if(weight) column.weight=weight;} this._applyColumnWeights();},_saveColumnWeights:function() {if(!this._columnWeightsSetting) return;var weights={};for(var i=0;i<this._columnsArray.length;++i){var column=this._columnsArray[i];weights[column.identifier]=column.weight;} this._columnWeightsSetting.set(weights);},wasShown:function() {this._loadColumnWeights();},willHide:function() {},_applyColumnWeights:function() {var tableWidth=this.element.offsetWidth-this._cornerWidth;if(tableWidth<=0) return;var sumOfWeights=0.0;var fixedColumnWidths=[];for(var i=0;i<this._visibleColumnsArray.length;++i){var column=this._visibleColumnsArray[i];if(column.fixedWidth){var width=this._headerTableColumnGroup.children[i][WebInspector.DataGrid._preferredWidthSymbol]||this.headerTableBody.rows[0].cells[i].offsetWidth;fixedColumnWidths[i]=width;tableWidth-=width;}else{sumOfWeights+=this._visibleColumnsArray[i].weight;}} var sum=0;var lastOffset=0;for(var i=0;i<this._visibleColumnsArray.length;++i){var column=this._visibleColumnsArray[i];var width;if(column.fixedWidth){width=fixedColumnWidths[i];}else{sum+=column.weight;var offset=(sum*tableWidth/sumOfWeights)|0;width=offset-lastOffset;lastOffset=offset;} this._setPreferredWidth(i,width);} this._positionResizers();this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);},setColumnsVisiblity:function(columnsVisibility) {this._visibleColumnsArray=[];for(var i=0;i<this._columnsArray.length;++i){var column=this._columnsArray[i];if(columnsVisibility[column.identifier||String(i)]) this._visibleColumnsArray.push(column);} this._refreshHeader();this._applyColumnWeights();var nodes=this._enumerateChildren(this.rootNode(),[],-1);for(var i=0;i<nodes.length;++i) nodes[i].refresh();},get scrollContainer() {return this._scrollContainer;},_positionResizers:function() {var headerTableColumns=this._headerTableColumnGroup.children;var numColumns=headerTableColumns.length-1;var left=[];var resizers=this._resizers;while(resizers.length>numColumns-1) resizers.pop().remove();for(var i=0;i<numColumns-1;i++){left[i]=(left[i-1]||0)+this.headerTableBody.rows[0].cells[i].offsetWidth;} for(var i=0;i<numColumns-1;i++){var resizer=resizers[i];if(!resizer){resizer=createElement("div");resizer.__index=i;resizer.classList.add("data-grid-resizer");WebInspector.installDragHandle(resizer,this._startResizerDragging.bind(this),this._resizerDragging.bind(this),this._endResizerDragging.bind(this),"col-resize");this.element.appendChild(resizer);resizers.push(resizer);} if(resizer.__position!==left[i]){resizer.__position=left[i];resizer.style.left=left[i]+"px";}}},addCreationNode:function(hasChildren) {if(this.creationNode) this.creationNode.makeNormal();var emptyData={};for(var column in this._columns) emptyData[column]=null;this.creationNode=new WebInspector.CreationDataGridNode(emptyData,hasChildren);this.rootNode().appendChild(this.creationNode);},_keyDown:function(event) {if(!this.selectedNode||event.shiftKey||event.metaKey||event.ctrlKey||this._editing) return;var handled=false;var nextSelectedNode;if(event.keyIdentifier==="Up"&&!event.altKey){nextSelectedNode=this.selectedNode.traversePreviousNode(true);while(nextSelectedNode&&!nextSelectedNode.selectable) nextSelectedNode=nextSelectedNode.traversePreviousNode(true);handled=nextSelectedNode?true:false;}else if(event.keyIdentifier==="Down"&&!event.altKey){nextSelectedNode=this.selectedNode.traverseNextNode(true);while(nextSelectedNode&&!nextSelectedNode.selectable) nextSelectedNode=nextSelectedNode.traverseNextNode(true);handled=nextSelectedNode?true:false;}else if(event.keyIdentifier==="Left"){if(this.selectedNode.expanded){if(event.altKey) this.selectedNode.collapseRecursively();else this.selectedNode.collapse();handled=true;}else if(this.selectedNode.parent&&!this.selectedNode.parent._isRoot){handled=true;if(this.selectedNode.parent.selectable){nextSelectedNode=this.selectedNode.parent;handled=nextSelectedNode?true:false;}else if(this.selectedNode.parent) this.selectedNode.parent.collapse();}}else if(event.keyIdentifier==="Right"){if(!this.selectedNode.revealed){this.selectedNode.reveal();handled=true;}else if(this.selectedNode.hasChildren){handled=true;if(this.selectedNode.expanded){nextSelectedNode=this.selectedNode.children[0];handled=nextSelectedNode?true:false;}else{if(event.altKey) this.selectedNode.expandRecursively();else this.selectedNode.expand();}}}else if(event.keyCode===8||event.keyCode===46){if(this._deleteCallback){handled=true;this._deleteCallback(this.selectedNode);}}else if(isEnterKey(event)){if(this._editCallback){handled=true;this._startEditing(this.selectedNode._element.children[this._nextEditableColumn(-1)]);}} if(nextSelectedNode){nextSelectedNode.reveal();nextSelectedNode.select();} if(handled) event.consume(true);},updateSelectionBeforeRemoval:function(root,onlyAffectsSubtree) {var ancestor=this.selectedNode;while(ancestor&&ancestor!==root) ancestor=ancestor.parent;if(!ancestor) return;var nextSelectedNode;for(ancestor=root;ancestor&&!ancestor.nextSibling;ancestor=ancestor.parent){} if(ancestor) nextSelectedNode=ancestor.nextSibling;while(nextSelectedNode&&!nextSelectedNode.selectable) nextSelectedNode=nextSelectedNode.traverseNextNode(true);if(!nextSelectedNode||nextSelectedNode.isCreationNode){nextSelectedNode=root.traversePreviousNode(true);while(nextSelectedNode&&!nextSelectedNode.selectable) nextSelectedNode=nextSelectedNode.traversePreviousNode(true);} if(nextSelectedNode){nextSelectedNode.reveal();nextSelectedNode.select();}else{this.selectedNode.deselect();}},dataGridNodeFromNode:function(target) {var rowElement=target.enclosingNodeOrSelfWithNodeName("tr");return rowElement&&rowElement._dataGridNode;},columnIdentifierFromNode:function(target) {var cellElement=target.enclosingNodeOrSelfWithNodeName("td");return cellElement&&cellElement.columnIdentifier_;},_clickInHeaderCell:function(event) {var cell=event.target.enclosingNodeOrSelfWithNodeName("th");if(!cell||(cell.columnIdentifier===undefined)||!cell.classList.contains("sortable")) return;var sortOrder=WebInspector.DataGrid.Order.Ascending;if((cell===this._sortColumnCell)&&this.isSortOrderAscending()) sortOrder=WebInspector.DataGrid.Order.Descending;if(this._sortColumnCell) this._sortColumnCell.classList.remove(WebInspector.DataGrid.Order.Ascending,WebInspector.DataGrid.Order.Descending);this._sortColumnCell=cell;cell.classList.add(sortOrder);this.dispatchEventToListeners(WebInspector.DataGrid.Events.SortingChanged);},markColumnAsSortedBy:function(columnIdentifier,sortOrder) {if(this._sortColumnCell) this._sortColumnCell.classList.remove(WebInspector.DataGrid.Order.Ascending,WebInspector.DataGrid.Order.Descending);this._sortColumnCell=this._headerTableHeaders[columnIdentifier];this._sortColumnCell.classList.add(sortOrder);},headerTableHeader:function(columnIdentifier) {return this._headerTableHeaders[columnIdentifier];},_mouseDownInDataTable:function(event) {var gridNode=this.dataGridNodeFromNode(event.target);if(!gridNode||!gridNode.selectable) return;if(gridNode.isEventWithinDisclosureTriangle(event)) return;var columnIdentifier=this.columnIdentifierFromNode(event.target);if(columnIdentifier&&this._columns[columnIdentifier].nonSelectable) return;if(event.metaKey){if(gridNode.selected) gridNode.deselect();else gridNode.select();}else gridNode.select();},_contextMenuInDataTable:function(event) {var contextMenu=new WebInspector.ContextMenu(event);var gridNode=this.dataGridNodeFromNode(event.target);if(this._refreshCallback&&(!gridNode||gridNode!==this.creationNode)) contextMenu.appendItem(WebInspector.UIString("Refresh"),this._refreshCallback.bind(this));if(gridNode&&gridNode.selectable&&!gridNode.isEventWithinDisclosureTriangle(event)){if(this._editCallback){if(gridNode===this.creationNode) contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^new"),this._startEditing.bind(this,event.target));else{var columnIdentifier=this.columnIdentifierFromNode(event.target);if(columnIdentifier&&this._columns[columnIdentifier].editable) contextMenu.appendItem(WebInspector.UIString("Edit \"%s\"",this._columns[columnIdentifier].title),this._startEditing.bind(this,event.target));}} if(this._deleteCallback&&gridNode!==this.creationNode) contextMenu.appendItem(WebInspector.UIString.capitalize("Delete"),this._deleteCallback.bind(this,gridNode));if(this._contextMenuCallback) this._contextMenuCallback(contextMenu,gridNode);} contextMenu.show();},_clickInDataTable:function(event) {var gridNode=this.dataGridNodeFromNode(event.target);if(!gridNode||!gridNode.hasChildren) return;if(!gridNode.isEventWithinDisclosureTriangle(event)) return;if(gridNode.expanded){if(event.altKey) gridNode.collapseRecursively();else gridNode.collapse();}else{if(event.altKey) gridNode.expandRecursively();else gridNode.expand();}},setResizeMethod:function(method) {this._resizeMethod=method;},_startResizerDragging:function(event) {this._currentResizer=event.target;return true;},_resizerDragging:function(event) {var resizer=this._currentResizer;if(!resizer) return;var dragPoint=event.clientX-this.element.totalOffsetLeft();var firstRowCells=this.headerTableBody.rows[0].cells;var leftEdgeOfPreviousColumn=0;var leftCellIndex=resizer.__index;var rightCellIndex=leftCellIndex+1;for(var i=0;i<leftCellIndex;i++) leftEdgeOfPreviousColumn+=firstRowCells[i].offsetWidth;if(this._resizeMethod===WebInspector.DataGrid.ResizeMethod.Last){rightCellIndex=this._resizers.length;}else if(this._resizeMethod===WebInspector.DataGrid.ResizeMethod.First){leftEdgeOfPreviousColumn+=firstRowCells[leftCellIndex].offsetWidth-firstRowCells[0].offsetWidth;leftCellIndex=0;} var rightEdgeOfNextColumn=leftEdgeOfPreviousColumn+firstRowCells[leftCellIndex].offsetWidth+firstRowCells[rightCellIndex].offsetWidth;var leftMinimum=leftEdgeOfPreviousColumn+this.ColumnResizePadding;var rightMaximum=rightEdgeOfNextColumn-this.ColumnResizePadding;if(leftMinimum>rightMaximum) return;dragPoint=Number.constrain(dragPoint,leftMinimum,rightMaximum);var position=(dragPoint-this.CenterResizerOverBorderAdjustment);resizer.__position=position;resizer.style.left=position+"px";this._setPreferredWidth(leftCellIndex,dragPoint-leftEdgeOfPreviousColumn);this._setPreferredWidth(rightCellIndex,rightEdgeOfNextColumn-dragPoint);var leftColumn=this._visibleColumnsArray[leftCellIndex];var rightColumn=this._visibleColumnsArray[rightCellIndex];if(leftColumn.weight||rightColumn.weight){var sumOfWeights=leftColumn.weight+rightColumn.weight;var delta=rightEdgeOfNextColumn-leftEdgeOfPreviousColumn;leftColumn.weight=(dragPoint-leftEdgeOfPreviousColumn)*sumOfWeights/delta;rightColumn.weight=(rightEdgeOfNextColumn-dragPoint)*sumOfWeights/delta;} this._positionResizers();event.preventDefault();this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);},_setPreferredWidth:function(columnIndex,width) {var pxWidth=width+"px";this._headerTableColumnGroup.children[columnIndex][WebInspector.DataGrid._preferredWidthSymbol]=width;this._headerTableColumnGroup.children[columnIndex].style.width=pxWidth;this._dataTableColumnGroup.children[columnIndex].style.width=pxWidth;},columnOffset:function(columnId) {if(!this.element.offsetWidth) return 0;for(var i=1;i<this._visibleColumnsArray.length;++i){if(columnId===this._visibleColumnsArray[i].identifier){if(this._resizers[i-1]) return this._resizers[i-1].__position;}} return 0;},_endResizerDragging:function(event) {this._currentResizer=null;this._saveColumnWeights();this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);},asWidget:function() {if(!this._dataGridWidget) this._dataGridWidget=new WebInspector.DataGridWidget(this);return this._dataGridWidget;},ColumnResizePadding:24,CenterResizerOverBorderAdjustment:3,__proto__:WebInspector.Object.prototype} WebInspector.DataGrid.ResizeMethod={Nearest:"nearest",First:"first",Last:"last"} WebInspector.DataGridNode=function(data,hasChildren) {this._element=null;this._expanded=false;this._selected=false;this._depth;this._revealed;this._attached=false;this._savedPosition=null;this._shouldRefreshChildren=true;this._data=data||{};this.hasChildren=hasChildren||false;this.children=[];this.dataGrid=null;this.parent=null;this.previousSibling=null;this.nextSibling=null;this.disclosureToggleWidth=10;} WebInspector.DataGridNode.prototype={selectable:true,_isRoot:false,element:function() {if(!this._element){this.createElement();this.createCells();} return(this._element);},createElement:function() {this._element=createElement("tr");this._element._dataGridNode=this;if(this.hasChildren) this._element.classList.add("parent");if(this.expanded) this._element.classList.add("expanded");if(this.selected) this._element.classList.add("selected");if(this.revealed) this._element.classList.add("revealed");},createCells:function() {this._element.removeChildren();var columnsArray=this.dataGrid._visibleColumnsArray;for(var i=0;i<columnsArray.length;++i) this._element.appendChild(this.createCell(columnsArray[i].identifier||String(i)));this._element.appendChild(this._createTDWithClass("corner"));},get data() {return this._data;},set data(x) {this._data=x||{};this.refresh();},get revealed() {if(this._revealed!==undefined) return this._revealed;var currentAncestor=this.parent;while(currentAncestor&&!currentAncestor._isRoot){if(!currentAncestor.expanded){this._revealed=false;return false;} currentAncestor=currentAncestor.parent;} this._revealed=true;return true;},set hasChildren(x) {if(this._hasChildren===x) return;this._hasChildren=x;if(!this._element) return;this._element.classList.toggle("parent",this._hasChildren);this._element.classList.toggle("expanded",this._hasChildren&&this.expanded);},get hasChildren() {return this._hasChildren;},set revealed(x) {if(this._revealed===x) return;this._revealed=x;if(this._element) this._element.classList.toggle("revealed",this._revealed);for(var i=0;i<this.children.length;++i) this.children[i].revealed=x&&this.expanded;},get depth() {if(this._depth!==undefined) return this._depth;if(this.parent&&!this.parent._isRoot) this._depth=this.parent.depth+1;else this._depth=0;return this._depth;},get leftPadding() {return this.depth*this.dataGrid.indentWidth;},get shouldRefreshChildren() {return this._shouldRefreshChildren;},set shouldRefreshChildren(x) {this._shouldRefreshChildren=x;if(x&&this.expanded) this.expand();},get selected() {return this._selected;},set selected(x) {if(x) this.select();else this.deselect();},get expanded() {return this._expanded;},set expanded(x) {if(x) this.expand();else this.collapse();},refresh:function() {if(!this.dataGrid) this._element=null;if(!this._element) return;this.createCells();},_createTDWithClass:function(className) {var cell=createElementWithClass("td",className);var cellClass=this.dataGrid._cellClass;if(cellClass) cell.classList.add(cellClass);return cell;},createTD:function(columnIdentifier) {var cell=this._createTDWithClass(columnIdentifier+"-column");cell.columnIdentifier_=columnIdentifier;var alignment=this.dataGrid._columns[columnIdentifier].align;if(alignment) cell.classList.add(alignment);if(columnIdentifier===this.dataGrid.disclosureColumnIdentifier){cell.classList.add("disclosure");if(this.leftPadding) cell.style.setProperty("padding-left",this.leftPadding+"px");} return cell;},createCell:function(columnIdentifier) {var cell=this.createTD(columnIdentifier);var data=this.data[columnIdentifier];if(data instanceof Node){cell.appendChild(data);}else{cell.textContent=data;if(this.dataGrid._columns[columnIdentifier].longText) cell.title=data;} return cell;},nodeSelfHeight:function() {return 16;},appendChild:function(child) {this.insertChild(child,this.children.length);},insertChild:function(child,index) {if(!child) throw"insertChild: Node can't be undefined or null.";if(child.parent===this){var currentIndex=this.children.indexOf(child);if(currentIndex<0) console.assert(false,"Inconsistent DataGrid state");if(currentIndex===index) return;if(currentIndex<index) --index;} child.remove();this.children.splice(index,0,child);this.hasChildren=true;child.parent=this;child.dataGrid=this.dataGrid;child.recalculateSiblings(index);child._depth=undefined;child._revealed=undefined;child._attached=false;child._shouldRefreshChildren=true;var current=child.children[0];while(current){current.dataGrid=this.dataGrid;current._depth=undefined;current._revealed=undefined;current._attached=false;current._shouldRefreshChildren=true;current=current.traverseNextNode(false,child,true);} if(this.expanded) child._attach();if(!this.revealed) child.revealed=false;},remove:function() {if(this.parent) this.parent.removeChild(this);},removeChild:function(child) {if(!child) throw"removeChild: Node can't be undefined or null.";if(child.parent!==this) throw"removeChild: Node is not a child of this node.";if(this.dataGrid) this.dataGrid.updateSelectionBeforeRemoval(child,false);child._detach();this.children.remove(child,true);if(child.previousSibling) child.previousSibling.nextSibling=child.nextSibling;if(child.nextSibling) child.nextSibling.previousSibling=child.previousSibling;child.dataGrid=null;child.parent=null;child.nextSibling=null;child.previousSibling=null;if(this.children.length<=0) this.hasChildren=false;},removeChildren:function() {if(this.dataGrid) this.dataGrid.updateSelectionBeforeRemoval(this,true);for(var i=0;i<this.children.length;++i){var child=this.children[i];child._detach();child.dataGrid=null;child.parent=null;child.nextSibling=null;child.previousSibling=null;} this.children=[];this.hasChildren=false;},recalculateSiblings:function(myIndex) {if(!this.parent) return;var previousChild=this.parent.children[myIndex-1]||null;if(previousChild) previousChild.nextSibling=this;this.previousSibling=previousChild;var nextChild=this.parent.children[myIndex+1]||null;if(nextChild) nextChild.previousSibling=this;this.nextSibling=nextChild;},collapse:function() {if(this._isRoot) return;if(this._element) this._element.classList.remove("expanded");this._expanded=false;for(var i=0;i<this.children.length;++i) this.children[i].revealed=false;},collapseRecursively:function() {var item=this;while(item){if(item.expanded) item.collapse();item=item.traverseNextNode(false,this,true);}},populate:function(){},expand:function() {if(!this.hasChildren||this.expanded) return;if(this._isRoot) return;if(this.revealed&&!this._shouldRefreshChildren) for(var i=0;i<this.children.length;++i) this.children[i].revealed=true;if(this._shouldRefreshChildren){for(var i=0;i<this.children.length;++i) this.children[i]._detach();this.populate();if(this._attached){for(var i=0;i<this.children.length;++i){var child=this.children[i];if(this.revealed) child.revealed=true;child._attach();}} this._shouldRefreshChildren=false;} if(this._element) this._element.classList.add("expanded");this._expanded=true;},expandRecursively:function() {var item=this;while(item){item.expand();item=item.traverseNextNode(false,this);}},reveal:function() {if(this._isRoot) return;var currentAncestor=this.parent;while(currentAncestor&&!currentAncestor._isRoot){if(!currentAncestor.expanded) currentAncestor.expand();currentAncestor=currentAncestor.parent;} this.element().scrollIntoViewIfNeeded(false);},select:function(supressSelectedEvent) {if(!this.dataGrid||!this.selectable||this.selected) return;if(this.dataGrid.selectedNode) this.dataGrid.selectedNode.deselect();this._selected=true;this.dataGrid.selectedNode=this;if(this._element) this._element.classList.add("selected");if(!supressSelectedEvent) this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);},revealAndSelect:function() {if(this._isRoot) return;this.reveal();this.select();},deselect:function(supressDeselectedEvent) {if(!this.dataGrid||this.dataGrid.selectedNode!==this||!this.selected) return;this._selected=false;this.dataGrid.selectedNode=null;if(this._element) this._element.classList.remove("selected");if(!supressDeselectedEvent) this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);},traverseNextNode:function(skipHidden,stayWithin,dontPopulate,info) {if(!dontPopulate&&this.hasChildren) this.populate();if(info) info.depthChange=0;var node=(!skipHidden||this.revealed)?this.children[0]:null;if(node&&(!skipHidden||this.expanded)){if(info) info.depthChange=1;return node;} if(this===stayWithin) return null;node=(!skipHidden||this.revealed)?this.nextSibling:null;if(node) return node;node=this;while(node&&!node._isRoot&&!((!skipHidden||node.revealed)?node.nextSibling:null)&&node.parent!==stayWithin){if(info) info.depthChange-=1;node=node.parent;} if(!node) return null;return(!skipHidden||node.revealed)?node.nextSibling:null;},traversePreviousNode:function(skipHidden,dontPopulate) {var node=(!skipHidden||this.revealed)?this.previousSibling:null;if(!dontPopulate&&node&&node.hasChildren) node.populate();while(node&&((!skipHidden||(node.revealed&&node.expanded))?node.children[node.children.length-1]:null)){if(!dontPopulate&&node.hasChildren) node.populate();node=((!skipHidden||(node.revealed&&node.expanded))?node.children[node.children.length-1]:null);} if(node) return node;if(!this.parent||this.parent._isRoot) return null;return this.parent;},isEventWithinDisclosureTriangle:function(event) {if(!this.hasChildren) return false;var cell=event.target.enclosingNodeOrSelfWithNodeName("td");if(!cell||!cell.classList.contains("disclosure")) return false;var left=cell.totalOffsetLeft()+this.leftPadding;return event.pageX>=left&&event.pageX<=left+this.disclosureToggleWidth;},_attach:function() {if(!this.dataGrid||this._attached) return;this._attached=true;var previousNode=this.traversePreviousNode(true,true);var previousElement=previousNode?previousNode.element():this.dataGrid._topFillerRow;this.dataGrid.dataTableBody.insertBefore(this.element(),previousElement.nextSibling);if(this.expanded) for(var i=0;i<this.children.length;++i) this.children[i]._attach();},_detach:function() {if(!this._attached) return;this._attached=false;if(this._element) this._element.remove();for(var i=0;i<this.children.length;++i) this.children[i]._detach();this.wasDetached();},wasDetached:function() {},savePosition:function() {if(this._savedPosition) return;if(!this.parent) throw"savePosition: Node must have a parent.";this._savedPosition={parent:this.parent,index:this.parent.children.indexOf(this)};},restorePosition:function() {if(!this._savedPosition) return;if(this.parent!==this._savedPosition.parent) this._savedPosition.parent.insertChild(this,this._savedPosition.index);this._savedPosition=null;},__proto__:WebInspector.Object.prototype} WebInspector.CreationDataGridNode=function(data,hasChildren) {WebInspector.DataGridNode.call(this,data,hasChildren);this.isCreationNode=true;} WebInspector.CreationDataGridNode.prototype={makeNormal:function() {this.isCreationNode=false;},__proto__:WebInspector.DataGridNode.prototype} WebInspector.DataGridWidget=function(dataGrid) {WebInspector.VBox.call(this);this._dataGrid=dataGrid;this.element.appendChild(dataGrid.element);} WebInspector.DataGridWidget.prototype={wasShown:function() {this._dataGrid.wasShown();},willHide:function() {this._dataGrid.willHide();},onResize:function() {this._dataGrid.onResize();},elementsToRestoreScrollPositionsFor:function() {return[this._dataGrid._scrollContainer];},detachChildWidgets:function() {WebInspector.Widget.prototype.detachChildWidgets.call(this);for(var dataGrid of this._dataGrids) this.element.removeChild(dataGrid.element);this._dataGrids=[];},__proto__:WebInspector.VBox.prototype};WebInspector.ViewportDataGrid=function(columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback) {WebInspector.DataGrid.call(this,columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback);this._scrollContainer.addEventListener("scroll",this._onScroll.bind(this),true);this._scrollContainer.addEventListener("mousewheel",this._onWheel.bind(this),true);this._visibleNodes=[];this._flatNodes=null;this._inline=false;this._wheelTarget=null;this._hiddenWheelTarget=null;this._stickToBottom=false;this._atBottom=true;this._lastScrollTop=0;this.setRootNode(new WebInspector.ViewportDataGridNode());} WebInspector.ViewportDataGrid.prototype={onResize:function() {if(this._stickToBottom&&this._atBottom) this._scrollContainer.scrollTop=this._scrollContainer.scrollHeight-this._scrollContainer.clientHeight;this.scheduleUpdate();WebInspector.DataGrid.prototype.onResize.call(this);},setStickToBottom:function(stick) {this._stickToBottom=stick;},_onWheel:function(event) {this._wheelTarget=event.target?event.target.enclosingNodeOrSelfWithNodeName("tr"):null;},_onScroll:function(event) {this._atBottom=this._scrollContainer.isScrolledToBottom();if(this._lastScrollTop!==this._scrollContainer.scrollTop) this.scheduleUpdate();},scheduleUpdateStructure:function() {this._flatNodes=null;this.scheduleUpdate();},scheduleUpdate:function() {if(this._updateAnimationFrameId) return;this._updateAnimationFrameId=this.element.window().requestAnimationFrame(this._update.bind(this));},updateInstantlyForTests:function() {if(!this._updateAnimationFrameId) return;this.element.window().cancelAnimationFrame(this._updateAnimationFrameId);this._update();},renderInline:function() {this._inline=true;WebInspector.DataGrid.prototype.renderInline.call(this);this._update();},_flatNodesList:function() {if(this._flatNodes) return this._flatNodes;var flatNodes=[];var children=[this._rootNode.children];var counters=[0];var depth=0;while(depth>=0){var node=children[depth][counters[depth]++];if(!node){depth--;continue;} flatNodes.push(node);node.setDepth(depth);if(node._expanded&&node.children.length){depth++;children[depth]=node.children;counters[depth]=0;}} this._flatNodes=flatNodes;return this._flatNodes;},_calculateVisibleNodes:function(clientHeight,scrollTop) {var nodes=this._flatNodesList();if(this._inline) return{topPadding:0,bottomPadding:0,contentHeight:0,visibleNodes:nodes,offset:0};var size=nodes.length;var i=0;var y=0;for(;i<size&&y+nodes[i].nodeSelfHeight()<scrollTop;++i) y+=nodes[i].nodeSelfHeight();var start=i;var topPadding=y;for(;i<size&&y<scrollTop+clientHeight;++i) y+=nodes[i].nodeSelfHeight();var end=i;var bottomPadding=0;for(;i<size;++i) bottomPadding+=nodes[i].nodeSelfHeight();return{topPadding:topPadding,bottomPadding:bottomPadding,contentHeight:y-topPadding,visibleNodes:nodes.slice(start,end),offset:start};},_contentHeight:function() {var nodes=this._flatNodesList();var result=0;for(var i=0,size=nodes.length;i<size;++i) result+=nodes[i].nodeSelfHeight();return result;},_update:function() {delete this._updateAnimationFrameId;var clientHeight=this._scrollContainer.clientHeight;var scrollTop=this._scrollContainer.scrollTop;var currentScrollTop=scrollTop;var maxScrollTop=Math.max(0,this._contentHeight()-clientHeight);if(this._stickToBottom&&this._atBottom) scrollTop=maxScrollTop;scrollTop=Math.min(maxScrollTop,scrollTop);this._atBottom=scrollTop===maxScrollTop;var viewportState=this._calculateVisibleNodes(clientHeight,scrollTop);var visibleNodes=viewportState.visibleNodes;var visibleNodesSet=new Set(visibleNodes);if(this._hiddenWheelTarget&&this._hiddenWheelTarget!==this._wheelTarget){this._hiddenWheelTarget.remove();this._hiddenWheelTarget=null;} for(var i=0;i<this._visibleNodes.length;++i){var oldNode=this._visibleNodes[i];if(!visibleNodesSet.has(oldNode)&&oldNode.attached()){var element=oldNode._element;if(element===this._wheelTarget) this._hiddenWheelTarget=oldNode.abandonElement();else element.remove();oldNode.wasDetached();}} var previousElement=this._topFillerRow;if(previousElement.nextSibling===this._hiddenWheelTarget) previousElement=this._hiddenWheelTarget;var tBody=this.dataTableBody;var offset=viewportState.offset;for(var i=0;i<visibleNodes.length;++i){var node=visibleNodes[i];var element=node.element();node.willAttach();element.classList.toggle("odd",(offset+i)%2===0);tBody.insertBefore(element,previousElement.nextSibling);previousElement=element;} this.setVerticalPadding(viewportState.topPadding,viewportState.bottomPadding);this._lastScrollTop=scrollTop;if(scrollTop!==currentScrollTop) this._scrollContainer.scrollTop=scrollTop;var contentFits=viewportState.contentHeight<=clientHeight&&viewportState.topPadding+viewportState.bottomPadding===0;if(contentFits!==this.element.classList.contains("data-grid-fits-viewport")){this.element.classList.toggle("data-grid-fits-viewport",contentFits);this.updateWidths();} this._visibleNodes=visibleNodes;},_revealViewportNode:function(node) {var nodes=this._flatNodesList();var index=nodes.indexOf(node);if(index===-1) return;var fromY=0;for(var i=0;i<index;++i) fromY+=nodes[i].nodeSelfHeight();var toY=fromY+node.nodeSelfHeight();var scrollTop=this._scrollContainer.scrollTop;if(scrollTop>fromY){scrollTop=fromY;this._atBottom=false;}else if(scrollTop+this._scrollContainer.offsetHeight<toY){scrollTop=toY-this._scrollContainer.offsetHeight;} this._scrollContainer.scrollTop=scrollTop;},__proto__:WebInspector.DataGrid.prototype} WebInspector.ViewportDataGridNode=function(data,hasChildren) {WebInspector.DataGridNode.call(this,data,hasChildren);this._stale=false;} WebInspector.ViewportDataGridNode.prototype={element:function() {if(!this._element){this.createElement();this.createCells();this._stale=false;} if(this._stale){this.createCells();this._stale=false;} return(this._element);},setDepth:function(depth) {this._depth=depth;},insertChild:function(child,index) {if(child.parent===this){var currentIndex=this.children.indexOf(child);if(currentIndex<0) console.assert(false,"Inconsistent DataGrid state");if(currentIndex===index) return;if(currentIndex<index) --index;} child.remove();child.parent=this;child.dataGrid=this.dataGrid;if(!this.children.length) this.hasChildren=true;this.children.splice(index,0,child);child.recalculateSiblings(index);if(this._expanded) this.dataGrid.scheduleUpdateStructure();},removeChild:function(child) {if(this.dataGrid) this.dataGrid.updateSelectionBeforeRemoval(child,false);if(child.previousSibling) child.previousSibling.nextSibling=child.nextSibling;if(child.nextSibling) child.nextSibling.previousSibling=child.previousSibling;if(child.parent!==this) throw"removeChild: Node is not a child of this node.";child._unlink();this.children.remove(child,true);if(!this.children.length) this.hasChildren=false;if(this._expanded) this.dataGrid.scheduleUpdateStructure();},removeChildren:function() {if(this.dataGrid) this.dataGrid.updateSelectionBeforeRemoval(this,true);for(var i=0;i<this.children.length;++i) this.children[i]._unlink();this.children=[];if(this._expanded) this.dataGrid.scheduleUpdateStructure();},_unlink:function() {if(this.attached()){this._element.remove();this.wasDetached();} this.dataGrid=null;this.parent=null;this.nextSibling=null;this.previousSibling=null;},collapse:function() {if(!this._expanded) return;this._expanded=false;if(this._element) this._element.classList.remove("expanded");this.dataGrid.scheduleUpdateStructure();},expand:function() {if(this._expanded) return;WebInspector.DataGridNode.prototype.expand.call(this);this.dataGrid.scheduleUpdateStructure();},willAttach:function(){},attached:function() {return!!(this.dataGrid&&this._element&&this._element.parentElement);},refresh:function() {if(this.attached()){this._stale=true;this.dataGrid.scheduleUpdate();}else{this._element=null;}},abandonElement:function() {var result=this._element;if(result) result.style.display="none";this._element=null;return result;},reveal:function() {this.dataGrid._revealViewportNode(this);},__proto__:WebInspector.DataGridNode.prototype};WebInspector.SortableDataGrid=function(columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback) {WebInspector.ViewportDataGrid.call(this,columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback);this._sortingFunction=WebInspector.SortableDataGrid.TrivialComparator;this.setRootNode(new WebInspector.SortableDataGridNode());} WebInspector.SortableDataGrid.NodeComparator;WebInspector.SortableDataGrid.TrivialComparator=function(a,b) {return 0;} WebInspector.SortableDataGrid.NumericComparator=function(columnIdentifier,a,b) {var aValue=a.data[columnIdentifier];var bValue=b.data[columnIdentifier];var aNumber=Number(aValue instanceof Node?aValue.textContent:aValue);var bNumber=Number(bValue instanceof Node?bValue.textContent:bValue);return aNumber<bNumber?-1:(aNumber>bNumber?1:0);} WebInspector.SortableDataGrid.StringComparator=function(columnIdentifier,a,b) {var aValue=a.data[columnIdentifier];var bValue=b.data[columnIdentifier];var aString=aValue instanceof Node?aValue.textContent:String(aValue);var bString=bValue instanceof Node?bValue.textContent:String(bValue);return aString<bString?-1:(aString>bString?1:0);} WebInspector.SortableDataGrid.Comparator=function(comparator,reverseMode,a,b) {return reverseMode?comparator(b,a):comparator(a,b);} WebInspector.SortableDataGrid.create=function(columnNames,values) {var numColumns=columnNames.length;if(!numColumns) return null;var columns=[];for(var i=0;i<columnNames.length;++i) columns.push({title:columnNames[i],width:columnNames[i].length,sortable:true});var nodes=[];for(var i=0;i<values.length/numColumns;++i){var data={};for(var j=0;j<columnNames.length;++j) data[j]=values[numColumns*i+j];var node=new WebInspector.SortableDataGridNode(data);node.selectable=false;nodes.push(node);} var dataGrid=new WebInspector.SortableDataGrid(columns);var length=nodes.length;var rootNode=dataGrid.rootNode();for(var i=0;i<length;++i) rootNode.appendChild(nodes[i]);dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,sortDataGrid);function sortDataGrid() {var nodes=dataGrid.rootNode().children;var sortColumnIdentifier=dataGrid.sortColumnIdentifier();if(!sortColumnIdentifier) return;var columnIsNumeric=true;for(var i=0;i<nodes.length;i++){var value=nodes[i].data[sortColumnIdentifier];if(isNaN(value instanceof Node?value.textContent:value)){columnIsNumeric=false;break;}} var comparator=columnIsNumeric?WebInspector.SortableDataGrid.NumericComparator:WebInspector.SortableDataGrid.StringComparator;dataGrid.sortNodes(comparator.bind(null,sortColumnIdentifier),!dataGrid.isSortOrderAscending());} return dataGrid;} WebInspector.SortableDataGrid.prototype={insertChild:function(node) {var root=(this.rootNode());root.insertChildOrdered(node);},sortNodes:function(comparator,reverseMode) {this._sortingFunction=WebInspector.SortableDataGrid.Comparator.bind(null,comparator,reverseMode);this._rootNode._sortChildren(reverseMode);this.scheduleUpdateStructure();},__proto__:WebInspector.ViewportDataGrid.prototype} WebInspector.SortableDataGridNode=function(data,hasChildren) {WebInspector.ViewportDataGridNode.call(this,data,hasChildren);} WebInspector.SortableDataGridNode.prototype={insertChildOrdered:function(node) {this.insertChild(node,this.children.upperBound(node,this.dataGrid._sortingFunction));},_sortChildren:function() {this.children.sort(this.dataGrid._sortingFunction);for(var i=0;i<this.children.length;++i) this.children[i].recalculateSiblings(i);for(var child of this.children) child._sortChildren();},__proto__:WebInspector.ViewportDataGridNode.prototype};WebInspector.ShowMoreDataGridNode=function(callback,startPosition,endPosition,chunkSize) {WebInspector.DataGridNode.call(this,{summaryRow:true},false);this._callback=callback;this._startPosition=startPosition;this._endPosition=endPosition;this._chunkSize=chunkSize;this.showNext=createElement("button");this.showNext.setAttribute("type","button");this.showNext.addEventListener("click",this._showNextChunk.bind(this),false);this.showNext.textContent=WebInspector.UIString("Show %d before",this._chunkSize);this.showAll=createElement("button");this.showAll.setAttribute("type","button");this.showAll.addEventListener("click",this._showAll.bind(this),false);this.showLast=createElement("button");this.showLast.setAttribute("type","button");this.showLast.addEventListener("click",this._showLastChunk.bind(this),false);this.showLast.textContent=WebInspector.UIString("Show %d after",this._chunkSize);this._updateLabels();this.selectable=false;} WebInspector.ShowMoreDataGridNode.prototype={_showNextChunk:function() {this._callback(this._startPosition,this._startPosition+this._chunkSize);},_showAll:function() {this._callback(this._startPosition,this._endPosition);},_showLastChunk:function() {this._callback(this._endPosition-this._chunkSize,this._endPosition);},_updateLabels:function() {var totalSize=this._endPosition-this._startPosition;if(totalSize>this._chunkSize){this.showNext.classList.remove("hidden");this.showLast.classList.remove("hidden");}else{this.showNext.classList.add("hidden");this.showLast.classList.add("hidden");} this.showAll.textContent=WebInspector.UIString("Show all %d",totalSize);},createCells:function() {this._hasCells=false;WebInspector.DataGridNode.prototype.createCells.call(this);},createCell:function(columnIdentifier) {var cell=this.createTD(columnIdentifier);if(!this._hasCells){this._hasCells=true;if(this.depth) cell.style.setProperty("padding-left",(this.depth*this.dataGrid.indentWidth)+"px");cell.appendChild(this.showNext);cell.appendChild(this.showAll);cell.appendChild(this.showLast);} return cell;},setStartPosition:function(from) {this._startPosition=from;this._updateLabels();},setEndPosition:function(to) {this._endPosition=to;this._updateLabels();},nodeSelfHeight:function() {return 32;},dispose:function() {},__proto__:WebInspector.DataGridNode.prototype};WebInspector.FilteredListWidget=function(delegate) {WebInspector.VBox.call(this,true);this._renderAsTwoRows=delegate.renderAsTwoRows();this.contentElement.classList.add("filtered-list-widget");this.contentElement.addEventListener("keydown",this._onKeyDown.bind(this),false);if(delegate.renderMonospace()) this.contentElement.classList.add("monospace");this.registerRequiredCSS("ui_lazy/filteredListWidget.css");this._promptElement=this.contentElement.createChild("div","filtered-list-widget-input");this._promptElement.setAttribute("spellcheck","false");this._promptElement.setAttribute("contenteditable","plaintext-only");this._prompt=new WebInspector.TextPrompt(this._autocomplete.bind(this));this._prompt.renderAsBlock();this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemAccepted,this._onAutocompleted,this);var promptProxy=this._prompt.attach(this._promptElement);promptProxy.addEventListener("input",this._onInput.bind(this),false);promptProxy.classList.add("filtered-list-widget-prompt-element");this._filteredItems=[];this._viewportControl=new WebInspector.ViewportControl(this);this._itemElementsContainer=this._viewportControl.element;this._itemElementsContainer.classList.add("container");this._itemElementsContainer.addEventListener("click",this._onClick.bind(this),false);this.contentElement.appendChild(this._itemElementsContainer);this.setDefaultFocusedElement(this._promptElement);this._delegate=delegate;this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));this._itemsLoaded();this._updateShowMatchingItems();this._viewportControl.refresh();this._prompt.autoCompleteSoon(true);} WebInspector.FilteredListWidget.filterRegex=function(query) {const toEscape=String.regexSpecialCharacters();var regexString="";for(var i=0;i<query.length;++i){var c=query.charAt(i);if(toEscape.indexOf(c)!==-1) c="\\"+c;if(i) regexString+="[^\\0"+c+"]*";regexString+=c;} return new RegExp(regexString,"i");} WebInspector.FilteredListWidget.prototype={showAsDialog:function() {this._dialog=new WebInspector.Dialog();this._dialog.setMaxSize(new Size(504,340));this._dialog.setPosition(undefined,22);this.show(this._dialog.element);this._dialog.show();},_value:function() {return this._prompt.userEnteredText().trim();},willHide:function() {this._delegate.dispose();if(this._filterTimer) clearTimeout(this._filterTimer);},_onEnter:function(event) {event.preventDefault();if(!this._delegate.itemCount()) return;var selectedIndex=this._shouldShowMatchingItems()&&this._selectedIndexInFiltered<this._filteredItems.length?this._filteredItems[this._selectedIndexInFiltered]:null;this._delegate.selectItemWithQuery(selectedIndex,this._value());if(this._dialog) this._dialog.detach();},_itemsLoaded:function() {if(this._loadTimeout) return;this._loadTimeout=setTimeout(this._updateAfterItemsLoaded.bind(this),0);},_updateAfterItemsLoaded:function() {delete this._loadTimeout;this._filterItems();},_createItemElement:function(index) {var itemElement=createElement("div");itemElement.className="filtered-list-widget-item "+(this._renderAsTwoRows?"two-rows":"one-row");itemElement._titleElement=itemElement.createChild("div","filtered-list-widget-title");itemElement._subtitleElement=itemElement.createChild("div","filtered-list-widget-subtitle");itemElement._subtitleElement.textContent="\u200B";itemElement._index=index;this._delegate.renderItem(index,this._value(),itemElement._titleElement,itemElement._subtitleElement);return itemElement;},setQuery:function(query) {this._prompt.setText(query);this._prompt.autoCompleteSoon(true);this._scheduleFilter();},_autocomplete:function(proxyElement,query,cursorOffset,wordRange,force,completionsReadyCallback) {var completions=wordRange.startOffset===0?[this._delegate.autocomplete(query)]:[];completionsReadyCallback.call(null,completions);this._autocompletedForTests();},_autocompletedForTests:function() {},_filterItems:function() {delete this._filterTimer;if(this._scoringTimer){clearTimeout(this._scoringTimer);delete this._scoringTimer;} var query=this._delegate.rewriteQuery(this._value());this._query=query;var filterRegex=query?WebInspector.FilteredListWidget.filterRegex(query):null;var oldSelectedAbsoluteIndex=this._selectedIndexInFiltered?this._filteredItems[this._selectedIndexInFiltered]:null;var filteredItems=[];this._selectedIndexInFiltered=0;var bestScores=[];var bestItems=[];var bestItemsToCollect=100;var minBestScore=0;var overflowItems=[];scoreItems.call(this,0);function compareIntegers(a,b) {return b-a;} function scoreItems(fromIndex) {var maxWorkItems=1000;var workDone=0;for(var i=fromIndex;i<this._delegate.itemCount()&&workDone<maxWorkItems;++i){if(filterRegex&&!filterRegex.test(this._delegate.itemKeyAt(i))) continue;var score=this._delegate.itemScoreAt(i,query);if(query) workDone++;if(score>minBestScore||bestScores.length<bestItemsToCollect){var index=bestScores.upperBound(score,compareIntegers);bestScores.splice(index,0,score);bestItems.splice(index,0,i);if(bestScores.length>bestItemsToCollect){overflowItems.push(bestItems.peekLast());bestScores.length=bestItemsToCollect;bestItems.length=bestItemsToCollect;} minBestScore=bestScores.peekLast();}else filteredItems.push(i);} if(i<this._delegate.itemCount()){this._scoringTimer=setTimeout(scoreItems.bind(this,i),0);return;} delete this._scoringTimer;this._filteredItems=bestItems.concat(overflowItems).concat(filteredItems);for(var i=0;i<this._filteredItems.length;++i){if(this._filteredItems[i]===oldSelectedAbsoluteIndex){this._selectedIndexInFiltered=i;break;}} this._viewportControl.invalidate();if(!query) this._selectedIndexInFiltered=0;this._updateSelection(this._selectedIndexInFiltered,false);}},_shouldShowMatchingItems:function() {return this._delegate.shouldShowMatchingItems(this._value());},_onAutocompleted:function() {this._prompt.autoCompleteSoon(true);this._onInput();},_onInput:function() {this._updateShowMatchingItems();this._scheduleFilter();},_updateShowMatchingItems:function() {var shouldShowMatchingItems=this._shouldShowMatchingItems();this._itemElementsContainer.classList.toggle("hidden",!shouldShowMatchingItems);},_rowsPerViewport:function() {return Math.floor(this._viewportControl.element.clientHeight/this._rowHeight);},_onKeyDown:function(event) {var newSelectedIndex=this._selectedIndexInFiltered;switch(event.keyCode){case WebInspector.KeyboardShortcut.Keys.Down.code:if(++newSelectedIndex>=this._filteredItems.length) newSelectedIndex=0;this._updateSelection(newSelectedIndex,true);event.consume(true);break;case WebInspector.KeyboardShortcut.Keys.Up.code:if(--newSelectedIndex<0) newSelectedIndex=this._filteredItems.length-1;this._updateSelection(newSelectedIndex,false);event.consume(true);break;case WebInspector.KeyboardShortcut.Keys.PageDown.code:newSelectedIndex=Math.min(newSelectedIndex+this._rowsPerViewport(),this._filteredItems.length-1);this._updateSelection(newSelectedIndex,true);event.consume(true);break;case WebInspector.KeyboardShortcut.Keys.PageUp.code:newSelectedIndex=Math.max(newSelectedIndex-this._rowsPerViewport(),0);this._updateSelection(newSelectedIndex,false);event.consume(true);break;case WebInspector.KeyboardShortcut.Keys.Enter.code:this._onEnter(event);break;default:}},_scheduleFilter:function() {if(this._filterTimer) return;this._filterTimer=setTimeout(this._filterItems.bind(this),0);},_updateSelection:function(index,makeLast) {if(!this._filteredItems.length) return;if(this._selectedElement) this._selectedElement.classList.remove("selected");this._viewportControl.scrollItemIntoView(index,makeLast);this._selectedIndexInFiltered=index;this._selectedElement=this._viewportControl.renderedElementAt(index);if(this._selectedElement) this._selectedElement.classList.add("selected");},_onClick:function(event) {var itemElement=event.target.enclosingNodeOrSelfWithClass("filtered-list-widget-item");if(!itemElement) return;this._delegate.selectItemWithQuery(itemElement._index,this._value());if(this._dialog) this._dialog.detach();},itemCount:function() {return this._filteredItems.length;},fastHeight:function(index) {if(!this._rowHeight){var delegateIndex=this._filteredItems[index];var element=this._createItemElement(delegateIndex);this._rowHeight=WebInspector.measurePreferredSize(element,this._viewportControl.contentElement()).height;} return this._rowHeight;},itemElement:function(index) {var delegateIndex=this._filteredItems[index];var element=this._createItemElement(delegateIndex);return new WebInspector.StaticViewportElement(element);},minimumRowHeight:function() {return this.fastHeight(0);},__proto__:WebInspector.VBox.prototype} WebInspector.FilteredListWidget.Delegate=function(promptHistory) {this._promptHistory=promptHistory;} WebInspector.FilteredListWidget.Delegate.prototype={setRefreshCallback:function(refreshCallback) {this._refreshCallback=refreshCallback;},shouldShowMatchingItems:function(query) {return true;},itemCount:function() {return 0;},itemKeyAt:function(itemIndex) {return"";},itemScoreAt:function(itemIndex,query) {return 1;},renderItem:function(itemIndex,query,titleElement,subtitleElement) {},highlightRanges:function(element,query) {if(!query) return false;function rangesForMatch(text,query) {var opcodes=WebInspector.Diff.charDiff(query,text);var offset=0;var ranges=[];for(var i=0;i<opcodes.length;++i){var opcode=opcodes[i];if(opcode[0]===WebInspector.Diff.Operation.Equal) ranges.push(new WebInspector.SourceRange(offset,opcode[1].length));else if(opcode[0]!==WebInspector.Diff.Operation.Insert) return null;offset+=opcode[1].length;} return ranges;} var text=element.textContent;var ranges=rangesForMatch(text,query);if(!ranges||!this.caseSensitive()) ranges=rangesForMatch(text.toUpperCase(),query.toUpperCase());if(ranges){WebInspector.highlightRangesWithStyleClass(element,ranges,"highlight");return true;} return false;},caseSensitive:function() {return true;},renderMonospace:function() {return true;},renderAsTwoRows:function() {return false;},selectItemWithQuery:function(itemIndex,promptValue) {this._promptHistory.push(promptValue);if(this._promptHistory.length>100) this._promptHistory.shift();this.selectItem(itemIndex,promptValue);},selectItem:function(itemIndex,promptValue) {},refresh:function() {this._refreshCallback();},rewriteQuery:function(query) {return query;},autocomplete:function(query) {for(var i=this._promptHistory.length-1;i>=0;i--){if(this._promptHistory[i]!==query&&this._promptHistory[i].startsWith(query)) return this._promptHistory[i];} return query;},dispose:function() {}};WebInspector.CommandMenu=function() {this._commands=[];this._loadCommands();} WebInspector.CommandMenu.prototype={_loadCommands:function() {var panelExtensions=self.runtime.extensions(WebInspector.PanelFactory);for(var extension of panelExtensions) this._commands.push(WebInspector.CommandMenu.createRevealPanelCommand(extension));var drawerExtensions=self.runtime.extensions("drawer-view");for(var extension of drawerExtensions) this._commands.push(WebInspector.CommandMenu.createRevealDrawerCommand(extension));var settingExtensions=self.runtime.extensions("setting");for(var extension of settingExtensions){var options=extension.descriptor()["options"];if(!options||!extension.descriptor()["category"]) continue;for(var pair of options) this._commands.push(WebInspector.CommandMenu.createSettingCommand(extension,pair["title"],pair["value"]));}},commands:function() {return this._commands;}} WebInspector.CommandMenuDelegate=function() {WebInspector.FilteredListWidget.Delegate.call(this,[]);this._commands=[];this._appendAvailableCommands();} WebInspector.CommandMenuDelegate.MaterialPaletteColors=["#F44336","#E91E63","#9C27B0","#673AB7","#3F51B5","#03A9F4","#00BCD4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFC107","#FF9800","#FF5722","#795548","#9E9E9E","#607D8B"];WebInspector.CommandMenuDelegate.prototype={_appendAvailableCommands:function() {var allCommands=WebInspector.commandMenu.commands();var actions=WebInspector.actionRegistry.availableActions();for(var action of actions){if(action.category()) this._commands.push(WebInspector.CommandMenu.createActionCommand(action));} for(var command of allCommands){if(command.available()) this._commands.push(command);} this._commands=this._commands.sort(commandComparator);function commandComparator(left,right) {var cats=left.category().compareTo(right.category());return cats?cats:left.title().compareTo(right.title());}},itemCount:function() {return this._commands.length;},itemKeyAt:function(itemIndex) {return this._commands[itemIndex].key();},itemScoreAt:function(itemIndex,query) {var command=this._commands[itemIndex];var opcodes=WebInspector.Diff.charDiff(query.toLowerCase(),command.title().toLowerCase());var score=0;for(var i=0;i<opcodes.length;++i){if(opcodes[i][0]===WebInspector.Diff.Operation.Equal) score+=opcodes[i][1].length*opcodes[i][1].length;} if(command.category().startsWith("Panel")) score+=2;else if(command.category().startsWith("Drawer")) score+=1;return score;},renderItem:function(itemIndex,query,titleElement,subtitleElement) {var command=this._commands[itemIndex];titleElement.removeChildren();var tagElement=titleElement.createChild("span","tag");var index=String.hashCode(command.category())%WebInspector.CommandMenuDelegate.MaterialPaletteColors.length;tagElement.style.backgroundColor=WebInspector.CommandMenuDelegate.MaterialPaletteColors[index];tagElement.textContent=command.category();titleElement.createTextChild(command.title());this.highlightRanges(titleElement,query);subtitleElement.textContent=command.shortcut();},selectItem:function(itemIndex,promptValue) {this._commands[itemIndex].execute();},caseSensitive:function() {return false;},renderMonospace:function() {return false;},__proto__:WebInspector.FilteredListWidget.Delegate.prototype} WebInspector.CommandMenu.Command=function(category,title,key,shortcut,executeHandler,availableHandler) {this._category=category;this._title=title;this._key=category+"\0"+title+"\0"+key;this._shortcut=shortcut;this._executeHandler=executeHandler;this._availableHandler=availableHandler;} WebInspector.CommandMenu.Command.prototype={category:function() {return this._category;},title:function() {return this._title;},key:function() {return this._key;},shortcut:function() {return this._shortcut;},available:function() {return this._availableHandler?this._availableHandler():true;},execute:function() {this._executeHandler();}} WebInspector.CommandMenu.createCommand=function(category,keys,title,shortcut,executeHandler,availableHandler) {var key=keys.replace(/,/g,"\0");return new WebInspector.CommandMenu.Command(category,title,key,shortcut,executeHandler,availableHandler);} WebInspector.CommandMenu.createSettingCommand=function(extension,title,value) {var category=extension.descriptor()["category"]||"";var tags=extension.descriptor()["tags"]||"";var setting=WebInspector.settings.moduleSetting(extension.descriptor()["settingName"]);return WebInspector.CommandMenu.createCommand(category,tags,title,"",setting.set.bind(setting,value),availableHandler);function availableHandler() {return setting.get()!==value;}} WebInspector.CommandMenu.createActionCommand=function(action) {var shortcut=WebInspector.shortcutRegistry.shortcutTitleForAction(action.id())||"";return WebInspector.CommandMenu.createCommand(action.category(),action.tags(),action.title(),shortcut,action.execute.bind(action));} WebInspector.CommandMenu.createRevealPanelCommand=function(extension) {var panelName=extension.descriptor()["name"];var tags=extension.descriptor()["tags"]||"";return WebInspector.CommandMenu.createCommand(WebInspector.UIString("Panel"),tags,WebInspector.UIString("Show %s",extension.title(WebInspector.platform())),"",executeHandler,availableHandler);function availableHandler() {return WebInspector.inspectorView.currentPanel().name!==panelName;} function executeHandler() {WebInspector.inspectorView.panel(panelName).then(WebInspector.inspectorView.setCurrentPanel.bind(WebInspector.inspectorView));}} WebInspector.CommandMenu.createRevealDrawerCommand=function(extension) {var drawerId=extension.descriptor()["name"];var executeHandler=WebInspector.inspectorView.showViewInDrawer.bind(WebInspector.inspectorView,drawerId);var tags=extension.descriptor()["tags"]||"";return WebInspector.CommandMenu.createCommand(WebInspector.UIString("Drawer"),tags,WebInspector.UIString("Show %s",extension.title(WebInspector.platform())),"",executeHandler);} WebInspector.commandMenu=new WebInspector.CommandMenu();WebInspector.CommandMenu.ShowActionDelegate=function() {} WebInspector.CommandMenu.ShowActionDelegate.prototype={handleAction:function(context,actionId) {new WebInspector.FilteredListWidget(new WebInspector.CommandMenuDelegate()).showAsDialog();InspectorFrontendHost.bringToFront();return true;}};WebInspector.FlameChartDelegate=function(){} WebInspector.FlameChartDelegate.prototype={requestWindowTimes:function(startTime,endTime){},updateRangeSelection:function(startTime,endTime){},} WebInspector.FlameChart=function(dataProvider,flameChartDelegate,groupExpansionSetting) {WebInspector.HBox.call(this,true);this.registerRequiredCSS("ui_lazy/flameChart.css");this.contentElement.classList.add("flame-chart-main-pane");this._flameChartDelegate=flameChartDelegate;this._groupExpansionSetting=groupExpansionSetting;this._groupExpansionState=groupExpansionSetting&&groupExpansionSetting.get()||{};this._dataProvider=dataProvider;this._calculator=new WebInspector.FlameChart.Calculator(dataProvider);this._canvas=this.contentElement.createChild("canvas");this._canvas.tabIndex=1;this.setDefaultFocusedElement(this._canvas);this._canvas.addEventListener("mousemove",this._onMouseMove.bind(this),false);this._canvas.addEventListener("mouseout",this._onMouseOut.bind(this),false);this._canvas.addEventListener("mousewheel",this._onMouseWheel.bind(this),false);this._canvas.addEventListener("click",this._onClick.bind(this),false);this._canvas.addEventListener("keydown",this._onKeyDown.bind(this),false);WebInspector.installInertialDragHandle(this._canvas,this._startCanvasDragging.bind(this),this._canvasDragging.bind(this),this._endCanvasDragging.bind(this),"-webkit-grabbing",null);WebInspector.installDragHandle(this._canvas,this._startRangeSelection.bind(this),this._rangeSelectionDragging.bind(this),this._endRangeSelection.bind(this),"text",null);this._vScrollElement=this.contentElement.createChild("div","flame-chart-v-scroll");this._vScrollContent=this._vScrollElement.createChild("div");this._vScrollElement.addEventListener("scroll",this._onScroll.bind(this),false);this._scrollTop=0;this._entryInfo=this.contentElement.createChild("div","flame-chart-entry-info");this._markerHighlighElement=this.contentElement.createChild("div","flame-chart-marker-highlight-element");this._highlightElement=this.contentElement.createChild("div","flame-chart-highlight-element");this._selectedElement=this.contentElement.createChild("div","flame-chart-selected-element");this._selectionOverlay=this.contentElement.createChild("div","flame-chart-selection-overlay hidden");this._selectedTimeSpanLabel=this._selectionOverlay.createChild("div","time-span");this._windowLeft=0.0;this._windowRight=1.0;this._timeWindowLeft=0;this._timeWindowRight=Infinity;this._rangeSelectionStart=0;this._rangeSelectionEnd=0;this._barHeight=dataProvider.barHeight();this._paddingLeft=this._dataProvider.paddingLeft();var markerPadding=2;this._markerRadius=this._barHeight/2-markerPadding;this._headerLeftPadding=6;this._arrowSide=8;this._expansionArrowIndent=this._headerLeftPadding+this._arrowSide/2;this._headerLabelXPadding=3;this._headerLabelYPadding=2;this._highlightedMarkerIndex=-1;this._highlightedEntryIndex=-1;this._selectedEntryIndex=-1;this._rawTimelineDataLength=0;this._textWidth=new Map();this._lastMouseOffsetX=0;} WebInspector.FlameChart.DividersBarHeight=18;WebInspector.FlameChart.MinimalTimeWindowMs=0.5;WebInspector.FlameChartDataProvider=function() {} WebInspector.FlameChart.Group;WebInspector.FlameChart.GroupStyle;WebInspector.FlameChart.TimelineData=function(entryLevels,entryTotalTimes,entryStartTimes,groups) {this.entryLevels=entryLevels;this.entryTotalTimes=entryTotalTimes;this.entryStartTimes=entryStartTimes;this.groups=groups;this.markers=[];this.flowStartTimes=[];this.flowStartLevels=[];this.flowEndTimes=[];this.flowEndLevels=[];} WebInspector.FlameChartDataProvider.prototype={barHeight:function(){},dividerOffsets:function(startTime,endTime){},minimumBoundary:function(){},totalTime:function(){},formatValue:function(value,precision){},maxStackDepth:function(){},timelineData:function(){},prepareHighlightedEntryInfo:function(entryIndex){},canJumpToEntry:function(entryIndex){},entryTitle:function(entryIndex){},entryFont:function(entryIndex){},entryColor:function(entryIndex){},decorateEntry:function(entryIndex,context,text,barX,barY,barWidth,barHeight,unclippedBarX,timeToPixels){},forceDecoration:function(entryIndex){},textColor:function(entryIndex){},textBaseline:function(){},textPadding:function(){},highlightTimeRange:function(entryIndex){},paddingLeft:function(){},} WebInspector.FlameChartMarker=function() {} WebInspector.FlameChartMarker.prototype={startTime:function(){},color:function(){},title:function(){},draw:function(context,x,height,pixelsPerMillisecond){},} WebInspector.FlameChart.Events={EntrySelected:"EntrySelected"} WebInspector.FlameChart.ColorGenerator=function(hueSpace,satSpace,lightnessSpace,alphaSpace) {this._hueSpace=hueSpace||{min:0,max:360};this._satSpace=satSpace||67;this._lightnessSpace=lightnessSpace||80;this._alphaSpace=alphaSpace||1;this._colors=new Map();} WebInspector.FlameChart.ColorGenerator.prototype={setColorForID:function(id,color) {this._colors.set(id,color);},colorForID:function(id) {var color=this._colors.get(id);if(!color){color=this._generateColorForID(id);this._colors.set(id,color);} return color;},_generateColorForID:function(id) {var hash=String.hashCode(id);var h=this._indexToValueInSpace(hash,this._hueSpace);var s=this._indexToValueInSpace(hash>>8,this._satSpace);var l=this._indexToValueInSpace(hash>>16,this._lightnessSpace);var a=this._indexToValueInSpace(hash>>24,this._alphaSpace);return"hsla("+h+", "+s+"%, "+l+"%, "+a+")";},_indexToValueInSpace:function(index,space) {if(typeof space==="number") return space;var count=space.count||space.max-space.min;index%=count;return space.min+Math.floor(index/(count-1)*(space.max-space.min));}} WebInspector.FlameChart.Calculator=function(dataProvider) {this._dataProvider=dataProvider;this._paddingLeft=0;} WebInspector.FlameChart.Calculator.prototype={paddingLeft:function() {return this._paddingLeft;},_updateBoundaries:function(mainPane) {this._totalTime=mainPane._dataProvider.totalTime();this._zeroTime=mainPane._dataProvider.minimumBoundary();this._minimumBoundaries=this._zeroTime+mainPane._windowLeft*this._totalTime;this._maximumBoundaries=this._zeroTime+mainPane._windowRight*this._totalTime;this._paddingLeft=mainPane._paddingLeft;this._width=mainPane._canvas.width/window.devicePixelRatio-this._paddingLeft;this._timeToPixel=this._width/this.boundarySpan();},computePosition:function(time) {return Math.round((time-this._minimumBoundaries)*this._timeToPixel+this._paddingLeft);},formatValue:function(value,precision) {return this._dataProvider.formatValue(value-this._zeroTime,precision);},maximumBoundary:function() {return this._maximumBoundaries;},minimumBoundary:function() {return this._minimumBoundaries;},zeroTime:function() {return this._zeroTime;},boundarySpan:function() {return this._maximumBoundaries-this._minimumBoundaries;}} WebInspector.FlameChart.prototype={willHide:function() {this.hideHighlight();},highlightEntry:function(entryIndex) {if(this._highlightedEntryIndex===entryIndex) return;this._highlightedEntryIndex=entryIndex;this._updateElementPosition(this._highlightElement,this._highlightedEntryIndex);},hideHighlight:function() {this._entryInfo.removeChildren();this._canvas.style.cursor="default";this._highlightedEntryIndex=-1;this._updateElementPosition(this._highlightElement,this._highlightedEntryIndex);},_resetCanvas:function() {var ratio=window.devicePixelRatio;this._canvas.width=this._offsetWidth*ratio;this._canvas.height=this._offsetHeight*ratio;this._canvas.style.width=this._offsetWidth+"px";this._canvas.style.height=this._offsetHeight+"px";},_timelineData:function() {var timelineData=this._dataProvider.timelineData();if(timelineData!==this._rawTimelineData||timelineData.entryStartTimes.length!==this._rawTimelineDataLength) this._processTimelineData(timelineData);return this._rawTimelineData;},_cancelAnimation:function() {if(this._cancelWindowTimesAnimation){this._timeWindowLeft=this._pendingAnimationTimeLeft;this._timeWindowRight=this._pendingAnimationTimeRight;this._cancelWindowTimesAnimation();delete this._cancelWindowTimesAnimation;}},_revealEntry:function(entryIndex) {var timelineData=this._timelineData();if(!timelineData) return;var timeLeft=this._cancelWindowTimesAnimation?this._pendingAnimationTimeLeft:this._timeWindowLeft;var timeRight=this._cancelWindowTimesAnimation?this._pendingAnimationTimeRight:this._timeWindowRight;var entryStartTime=timelineData.entryStartTimes[entryIndex];var entryTotalTime=timelineData.entryTotalTimes[entryIndex];var entryEndTime=entryStartTime+entryTotalTime;var minEntryTimeWindow=Math.min(entryTotalTime,timeRight-timeLeft);var y=this._levelToHeight(timelineData.entryLevels[entryIndex]);if(this._vScrollElement.scrollTop>y) this._vScrollElement.scrollTop=y;else if(this._vScrollElement.scrollTop<y-this._offsetHeight+this._barHeight) this._vScrollElement.scrollTop=y-this._offsetHeight+this._barHeight;if(timeLeft>entryEndTime){var delta=timeLeft-entryEndTime+minEntryTimeWindow;this._flameChartDelegate.requestWindowTimes(timeLeft-delta,timeRight-delta);}else if(timeRight<entryStartTime){var delta=entryStartTime-timeRight+minEntryTimeWindow;this._flameChartDelegate.requestWindowTimes(timeLeft+delta,timeRight+delta);}},setWindowTimes:function(startTime,endTime) {if(this._muteAnimation||this._timeWindowLeft===0||this._timeWindowRight===Infinity||(startTime===0&&endTime===Infinity)||(startTime===Infinity&&endTime===Infinity)){this._timeWindowLeft=startTime;this._timeWindowRight=endTime;this.scheduleUpdate();return;} this._cancelAnimation();this._updateHighlight();this._cancelWindowTimesAnimation=WebInspector.animateFunction(this.element.window(),this._animateWindowTimes.bind(this),[{from:this._timeWindowLeft,to:startTime},{from:this._timeWindowRight,to:endTime}],5,this._animationCompleted.bind(this));this._pendingAnimationTimeLeft=startTime;this._pendingAnimationTimeRight=endTime;},_animateWindowTimes:function(startTime,endTime) {this._timeWindowLeft=startTime;this._timeWindowRight=endTime;this._updateHighlight();this.update();},_animationCompleted:function() {delete this._cancelWindowTimesAnimation;this._updateHighlight();},_initMaxDragOffset:function(event) {this._maxDragOffsetSquared=0;this._dragStartX=event.pageX;this._dragStartY=event.pageY;},_updateMaxDragOffset:function(x,y) {var dx=x-this._dragStartX;var dy=y-this._dragStartY;var dragOffsetSquared=dx*dx+dy*dy;this._maxDragOffsetSquared=Math.max(this._maxDragOffsetSquared,dragOffsetSquared);},_maxDragOffset:function() {return Math.sqrt(this._maxDragOffsetSquared);},_startCanvasDragging:function(x,y,event) {if(event.shiftKey) return false;if(!this._timelineData()||this._timeWindowRight===Infinity) return false;this._isDragging=true;this._initMaxDragOffset(event);this._dragStartPointX=x;this._dragStartPointY=y;this._dragStartScrollTop=this._vScrollElement.scrollTop;this._canvas.style.cursor="";this.hideHighlight();return true;},_canvasDragging:function(x,y) {var pixelShift=this._dragStartPointX-x;this._dragStartPointX=x;this._muteAnimation=true;this._handlePanGesture(pixelShift*this._pixelToTime);this._muteAnimation=false;var pixelScroll=this._dragStartPointY-y;this._vScrollElement.scrollTop=this._dragStartScrollTop+pixelScroll;this._updateMaxDragOffset(x,y);},_endCanvasDragging:function() {this._isDragging=false;this._updateHighlight();},_startRangeSelection:function(event) {if(!event.shiftKey) return false;this._isDragging=true;this._initMaxDragOffset(event);this._selectionOffsetShiftX=event.offsetX-event.pageX;this._selectionOffsetShiftY=event.offsetY-event.pageY;this._selectionStartX=event.offsetX;var style=this._selectionOverlay.style;style.left=this._selectionStartX+"px";style.width="1px";this._selectedTimeSpanLabel.textContent="";this._selectionOverlay.classList.remove("hidden");this.hideHighlight();return true;},_endRangeSelection:function() {this._isDragging=false;this._updateHighlight();},_hideRangeSelection:function() {this._selectionOverlay.classList.add("hidden");},_rangeSelectionDragging:function(event) {this._updateMaxDragOffset(event.pageX,event.pageY);var x=Number.constrain(event.pageX+this._selectionOffsetShiftX,0,this._offsetWidth);var start=this._cursorTime(this._selectionStartX);var end=this._cursorTime(x);this._rangeSelectionStart=Math.min(start,end);this._rangeSelectionEnd=Math.max(start,end);this._updateRangeSelectionOverlay();this._flameChartDelegate.updateRangeSelection(this._rangeSelectionStart,this._rangeSelectionEnd);},_updateRangeSelectionOverlay:function() {var margin=100;var left=Number.constrain(this._timeToPosition(this._rangeSelectionStart),-margin,this._offsetWidth+margin);var right=Number.constrain(this._timeToPosition(this._rangeSelectionEnd),-margin,this._offsetWidth+margin);var style=this._selectionOverlay.style;style.left=left+"px";style.width=(right-left)+"px";var timeSpan=this._rangeSelectionEnd-this._rangeSelectionStart;this._selectedTimeSpanLabel.textContent=Number.preciseMillisToString(timeSpan,2);},_onMouseMove:function(event) {this._lastMouseOffsetX=event.offsetX;this._lastMouseOffsetY=event.offsetY;if(!this._enabled()) return;if(this._isDragging) return;if(this._coordinatesToGroupIndex(event.offsetX,event.offsetY)>=0){this.hideHighlight();this._canvas.style.cursor="pointer";return;} this._updateHighlight();},_updateHighlight:function() {var inDividersBar=this._lastMouseOffsetY<WebInspector.FlameChart.DividersBarHeight;this._highlightedMarkerIndex=inDividersBar?this._markerIndexAtPosition(this._lastMouseOffsetX):-1;this._updateMarkerHighlight();var entryIndex=this._coordinatesToEntryIndex(this._lastMouseOffsetX,this._lastMouseOffsetY);if(entryIndex===-1){this.hideHighlight();return;} this._updatePopover(entryIndex);this._canvas.style.cursor=this._dataProvider.canJumpToEntry(entryIndex)?"pointer":"default";this.highlightEntry(entryIndex);},_onMouseOut:function() {this._lastMouseOffsetX=-1;this._lastMouseOffsetY=-1;this.hideHighlight();},_updatePopover:function(entryIndex) {if(entryIndex!==this._highlightedEntryIndex){this._entryInfo.removeChildren();var entryInfo=this._dataProvider.prepareHighlightedEntryInfo(entryIndex);if(entryInfo) this._entryInfo.appendChild(this._buildEntryInfo(entryInfo));} var mouseX=this._lastMouseOffsetX;var mouseY=this._lastMouseOffsetY;var parentWidth=this._entryInfo.parentElement.clientWidth;var parentHeight=this._entryInfo.parentElement.clientHeight;var infoWidth=this._entryInfo.clientWidth;var infoHeight=this._entryInfo.clientHeight;var offsetX=10;var offsetY=6;var x;var y;for(var quadrant=0;quadrant<4;++quadrant){var dx=quadrant&2?-offsetX-infoWidth:offsetX;var dy=quadrant&1?-offsetY-infoHeight:offsetY;x=Number.constrain(mouseX+dx,0,parentWidth-infoWidth);y=Number.constrain(mouseY+dy,0,parentHeight-infoHeight);if(x>=mouseX||mouseX>=x+infoWidth||y>=mouseY||mouseY>=y+infoHeight) break;} this._entryInfo.style.left=x+"px";this._entryInfo.style.top=y+"px";},_onClick:function(event) {this.focus();const clickThreshold=5;if(this._maxDragOffset()>clickThreshold) return;var groupIndex=this._coordinatesToGroupIndex(event.offsetX,event.offsetY);if(groupIndex>=0){this._toggleGroupVisibility(groupIndex);return;} this._hideRangeSelection();this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected,this._highlightedEntryIndex);},_toggleGroupVisibility:function(groupIndex) {if(!this._isGroupCollapsible(groupIndex)) return;var groups=this._rawTimelineData.groups;var group=groups[groupIndex];group.expanded=!group.expanded;this._groupExpansionState[group.name]=group.expanded;if(this._groupExpansionSetting) this._groupExpansionSetting.set(this._groupExpansionState);this._updateLevelPositions();this._updateHighlight();if(!group.expanded){var timelineData=this._timelineData();var level=timelineData.entryLevels[this._selectedEntryIndex];if(this._selectedEntryIndex>=0&&level>=group.startLevel&&(groupIndex===groups.length||groups[groupIndex+1].startLevel>level)) this._selectedEntryIndex=-1;} this._updateHeight();this._resetCanvas();this._draw(this._offsetWidth,this._offsetHeight);},_onMouseWheel:function(e) {if(!this._enabled()) return;var panVertically=e.shiftKey&&(e.wheelDeltaY||Math.abs(e.wheelDeltaX)===120);var panHorizontally=Math.abs(e.wheelDeltaX)>Math.abs(e.wheelDeltaY)&&!e.shiftKey;if(panVertically){this._vScrollElement.scrollTop-=(e.wheelDeltaY||e.wheelDeltaX)/120*this._offsetHeight/8;}else if(panHorizontally){var shift=-e.wheelDeltaX*this._pixelToTime;this._muteAnimation=true;this._handlePanGesture(shift);this._muteAnimation=false;}else{const mouseWheelZoomSpeed=1/120;this._handleZoomGesture(Math.pow(1.2,-(e.wheelDeltaY||e.wheelDeltaX)*mouseWheelZoomSpeed)-1);} e.consume(true);},_onKeyDown:function(e) {this._handleZoomPanKeys(e);this._handleSelectionNavigation(e);},_handleSelectionNavigation:function(e) {if(!WebInspector.KeyboardShortcut.hasNoModifiers(e)) return;if(this._selectedEntryIndex===-1) return;var timelineData=this._timelineData();if(!timelineData) return;function timeComparator(time,entryIndex) {return time-timelineData.entryStartTimes[entryIndex];} function entriesIntersect(entry1,entry2) {var start1=timelineData.entryStartTimes[entry1];var start2=timelineData.entryStartTimes[entry2];var end1=start1+timelineData.entryTotalTimes[entry1];var end2=start2+timelineData.entryTotalTimes[entry2];return start1<end2&&start2<end1;} var keys=WebInspector.KeyboardShortcut.Keys;if(e.keyCode===keys.Left.code||e.keyCode===keys.Right.code){var level=timelineData.entryLevels[this._selectedEntryIndex];var levelIndexes=this._timelineLevels[level];var indexOnLevel=levelIndexes.lowerBound(this._selectedEntryIndex);indexOnLevel+=e.keyCode===keys.Left.code?-1:1;e.consume(true);if(indexOnLevel>=0&&indexOnLevel<levelIndexes.length) this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected,levelIndexes[indexOnLevel]);return;} if(e.keyCode===keys.Up.code||e.keyCode===keys.Down.code){e.consume(true);var level=timelineData.entryLevels[this._selectedEntryIndex];level+=e.keyCode===keys.Up.code?-1:1;if(level<0||level>=this._timelineLevels.length) return;var entryTime=timelineData.entryStartTimes[this._selectedEntryIndex]+timelineData.entryTotalTimes[this._selectedEntryIndex]/2;var levelIndexes=this._timelineLevels[level];var indexOnLevel=levelIndexes.upperBound(entryTime,timeComparator)-1;if(!entriesIntersect(this._selectedEntryIndex,levelIndexes[indexOnLevel])){++indexOnLevel;if(indexOnLevel>=levelIndexes.length||!entriesIntersect(this._selectedEntryIndex,levelIndexes[indexOnLevel])) return;} this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected,levelIndexes[indexOnLevel]);}},_handleZoomPanKeys:function(e) {if(!WebInspector.KeyboardShortcut.hasNoModifiers(e)) return;var zoomMultiplier=e.shiftKey?0.8:0.3;var panMultiplier=e.shiftKey?320:80;if(e.keyCode==="A".charCodeAt(0)){this._handlePanGesture(-panMultiplier*this._pixelToTime);e.consume(true);}else if(e.keyCode==="D".charCodeAt(0)){this._handlePanGesture(panMultiplier*this._pixelToTime);e.consume(true);}else if(e.keyCode==="W".charCodeAt(0)){this._handleZoomGesture(-zoomMultiplier);e.consume(true);}else if(e.keyCode==="S".charCodeAt(0)){this._handleZoomGesture(zoomMultiplier);e.consume(true);}},_handleZoomGesture:function(zoom) {this._cancelAnimation();var bounds=this._windowForGesture();var cursorTime=this._cursorTime(this._lastMouseOffsetX);bounds.left+=(bounds.left-cursorTime)*zoom;bounds.right+=(bounds.right-cursorTime)*zoom;this._requestWindowTimes(bounds);},_handlePanGesture:function(shift) {this._cancelAnimation();var bounds=this._windowForGesture();shift=Number.constrain(shift,this._minimumBoundary-bounds.left,this._totalTime+this._minimumBoundary-bounds.right);bounds.left+=shift;bounds.right+=shift;this._requestWindowTimes(bounds);},_windowForGesture:function() {var windowLeft=this._timeWindowLeft?this._timeWindowLeft:this._dataProvider.minimumBoundary();var windowRight=this._timeWindowRight!==Infinity?this._timeWindowRight:this._dataProvider.minimumBoundary()+this._dataProvider.totalTime();return{left:windowLeft,right:windowRight};},_requestWindowTimes:function(bounds) {bounds.left=Number.constrain(bounds.left,this._minimumBoundary,this._totalTime+this._minimumBoundary);bounds.right=Number.constrain(bounds.right,this._minimumBoundary,this._totalTime+this._minimumBoundary);if(bounds.right-bounds.left<WebInspector.FlameChart.MinimalTimeWindowMs) return;this._flameChartDelegate.requestWindowTimes(bounds.left,bounds.right);},_cursorTime:function(x) {return(x+this._pixelWindowLeft-this._paddingLeft)*this._pixelToTime+this._minimumBoundary;},_coordinatesToEntryIndex:function(x,y) {if(x<0||y<0) return-1;y+=this._scrollTop;var timelineData=this._timelineData();if(!timelineData) return-1;var cursorTime=this._cursorTime(x);var cursorLevel=this._visibleLevelOffsets.upperBound(y)-1;if(cursorLevel<0||!this._visibleLevels[cursorLevel]) return-1;var offsetFromLevel=y-this._visibleLevelOffsets[cursorLevel];if(offsetFromLevel>this._barHeight) return-1;var entryStartTimes=timelineData.entryStartTimes;var entryTotalTimes=timelineData.entryTotalTimes;var entryIndexes=this._timelineLevels[cursorLevel];if(!entryIndexes||!entryIndexes.length) return-1;function comparator(time,entryIndex) {return time-entryStartTimes[entryIndex];} var indexOnLevel=Math.max(entryIndexes.upperBound(cursorTime,comparator)-1,0);function checkEntryHit(entryIndex) {if(entryIndex===undefined) return false;var startTime=entryStartTimes[entryIndex];var duration=entryTotalTimes[entryIndex];if(isNaN(duration)){var dx=(startTime-cursorTime)/this._pixelToTime;var dy=this._barHeight/2-offsetFromLevel;return dx*dx+dy*dy<this._markerRadius*this._markerRadius;} var endTime=startTime+duration;var barThreshold=3*this._pixelToTime;return startTime-barThreshold<cursorTime&&cursorTime<endTime+barThreshold;} var entryIndex=entryIndexes[indexOnLevel];if(checkEntryHit.call(this,entryIndex)) return entryIndex;entryIndex=entryIndexes[indexOnLevel+1];if(checkEntryHit.call(this,entryIndex)) return entryIndex;return-1;},_coordinatesToGroupIndex:function(x,y) {if(x<0||y<0) return-1;y+=this._scrollTop;var groups=this._rawTimelineData.groups||[];var group=this._groupOffsets.upperBound(y)-1;if(group<0||group>=groups.length||y-this._groupOffsets[group]>=groups[group].style.height) return-1;var context=this._canvas.getContext("2d");context.save();context.font=groups[group].style.font;var right=this._headerLeftPadding+this._labelWidthForGroup(context,groups[group]);context.restore();if(x>right) return-1;return group;},_markerIndexAtPosition:function(x) {var markers=this._timelineData().markers;if(!markers) return-1;var accurracyOffsetPx=1;var time=this._cursorTime(x);var leftTime=this._cursorTime(x-accurracyOffsetPx);var rightTime=this._cursorTime(x+accurracyOffsetPx);var left=this._markerIndexBeforeTime(leftTime);var markerIndex=-1;var distance=Infinity;for(var i=left;i<markers.length&&markers[i].startTime()<rightTime;i++){var nextDistance=Math.abs(markers[i].startTime()-time);if(nextDistance<distance){markerIndex=i;distance=nextDistance;}} return markerIndex;},_markerIndexBeforeTime:function(time) {function comparator(markerTimestamp,marker) {return markerTimestamp-marker.startTime();} return this._timelineData().markers.lowerBound(time,comparator);},_draw:function(width,height) {var timelineData=this._timelineData();if(!timelineData) return;var context=this._canvas.getContext("2d");context.save();var ratio=window.devicePixelRatio;context.scale(ratio,ratio);context.translate(0,-this._scrollTop);context.font="11px "+WebInspector.fontFamily();var timeWindowRight=this._timeWindowRight;var timeWindowLeft=this._timeWindowLeft-this._paddingLeft/this._timeToPixel;var entryTotalTimes=timelineData.entryTotalTimes;var entryStartTimes=timelineData.entryStartTimes;var entryLevels=timelineData.entryLevels;var titleIndices=new Uint32Array(entryTotalTimes.length);var nextTitleIndex=0;var markerIndices=new Uint32Array(entryTotalTimes.length);var nextMarkerIndex=0;var textPadding=this._dataProvider.textPadding();var minTextWidth=2*textPadding+this._measureWidth(context,"\u2026");var unclippedWidth=width-(WebInspector.isMac()?0:this._vScrollElement.offsetWidth);var barHeight=this._barHeight;var top=this._scrollTop;var minVisibleBarLevel=Math.max(this._visibleLevelOffsets.upperBound(top)-1,0);function comparator(time,entryIndex) {return time-entryStartTimes[entryIndex];} var colorBuckets={};for(var level=minVisibleBarLevel;level<this._dataProvider.maxStackDepth();++level){if(this._levelToHeight(level)>top+height) break;if(!this._visibleLevels[level]) continue;var levelIndexes=this._timelineLevels[level];var rightIndexOnLevel=levelIndexes.lowerBound(timeWindowRight,comparator)-1;var lastDrawOffset=Infinity;for(var entryIndexOnLevel=rightIndexOnLevel;entryIndexOnLevel>=0;--entryIndexOnLevel){var entryIndex=levelIndexes[entryIndexOnLevel];var entryStartTime=entryStartTimes[entryIndex];var entryOffsetRight=entryStartTime+(isNaN(entryTotalTimes[entryIndex])?0:entryTotalTimes[entryIndex]);if(entryOffsetRight<=timeWindowLeft) break;var barX=this._timeToPositionClipped(entryStartTime);if(barX>=lastDrawOffset) continue;lastDrawOffset=barX;var color=this._dataProvider.entryColor(entryIndex);var bucket=colorBuckets[color];if(!bucket){bucket=[];colorBuckets[color]=bucket;} bucket.push(entryIndex);}} var colors=Object.keys(colorBuckets);for(var c=0;c<colors.length;++c){var color=colors[c];context.fillStyle=color;context.strokeStyle=color;var indexes=colorBuckets[color];context.beginPath();for(var i=0;i<indexes.length;++i){var entryIndex=indexes[i];var entryStartTime=entryStartTimes[entryIndex];var barX=this._timeToPositionClipped(entryStartTime);var barRight=this._timeToPositionClipped(entryStartTime+entryTotalTimes[entryIndex]);var barWidth=Math.max(barRight-barX,1);var barLevel=entryLevels[entryIndex];var barY=this._levelToHeight(barLevel);if(isNaN(entryTotalTimes[entryIndex])){context.moveTo(barX+this._markerRadius,barY+barHeight/2);context.arc(barX,barY+barHeight/2,this._markerRadius,0,Math.PI*2);markerIndices[nextMarkerIndex++]=entryIndex;}else{context.rect(barX,barY,barWidth-0.4,barHeight-1);if(barWidth>minTextWidth||this._dataProvider.forceDecoration(entryIndex)) titleIndices[nextTitleIndex++]=entryIndex;}} context.fill();} context.strokeStyle="rgb(0, 0, 0)";context.beginPath();for(var m=0;m<nextMarkerIndex;++m){var entryIndex=markerIndices[m];var entryStartTime=entryStartTimes[entryIndex];var barX=this._timeToPositionClipped(entryStartTime);var barLevel=entryLevels[entryIndex];var barY=this._levelToHeight(barLevel);context.moveTo(barX+this._markerRadius,barY+barHeight/2);context.arc(barX,barY+barHeight/2,this._markerRadius,0,Math.PI*2);} context.stroke();context.textBaseline="alphabetic";var textBaseHeight=this._barHeight-this._dataProvider.textBaseline();for(var i=0;i<nextTitleIndex;++i){var entryIndex=titleIndices[i];var entryStartTime=entryStartTimes[entryIndex];var barX=this._timeToPositionClipped(entryStartTime);var barRight=Math.min(this._timeToPositionClipped(entryStartTime+entryTotalTimes[entryIndex]),unclippedWidth)+1;var barWidth=barRight-barX;var barLevel=entryLevels[entryIndex];var barY=this._levelToHeight(barLevel);var text=this._dataProvider.entryTitle(entryIndex);if(text&&text.length){context.font=this._dataProvider.entryFont(entryIndex);text=this._prepareText(context,text,barWidth-2*textPadding);} var unclippedBarX=this._timeToPosition(entryStartTime);if(this._dataProvider.decorateEntry(entryIndex,context,text,barX,barY,barWidth,barHeight,unclippedBarX,this._timeToPixel)) continue;if(!text||!text.length) continue;context.fillStyle=this._dataProvider.textColor(entryIndex);context.fillText(text,barX+textPadding,barY+textBaseHeight);} this._drawFlowEvents(context,width,height);context.restore();var offsets=this._dataProvider.dividerOffsets(this._calculator.minimumBoundary(),this._calculator.maximumBoundary());WebInspector.TimelineGrid.drawCanvasGrid(this._canvas,this._calculator,offsets);this._drawMarkers();this._drawGroupHeaders(width,height);this._updateElementPosition(this._highlightElement,this._highlightedEntryIndex);this._updateElementPosition(this._selectedElement,this._selectedEntryIndex);this._updateMarkerHighlight();this._updateRangeSelectionOverlay();},_drawGroupHeaders:function(width,height) {var context=this._canvas.getContext("2d");var top=this._scrollTop;var ratio=window.devicePixelRatio;var barHeight=this._barHeight;var textBaseHeight=barHeight-this._dataProvider.textBaseline();var groups=this._rawTimelineData.groups||[];if(!groups.length) return;var groupOffsets=this._groupOffsets;var lastGroupOffset=Array.prototype.peekLast.call(groupOffsets);var colorUsage=WebInspector.ThemeSupport.ColorUsage;context.save();context.scale(ratio,ratio);context.translate(0,-top);context.fillStyle=WebInspector.themeSupport.patchColor("#eee",colorUsage.Background);forEachGroup.call(this,(offset,index,group)=>{var paddingHeight=group.style.padding;if(paddingHeight<5) return;context.fillRect(0,offset-paddingHeight+2,width,paddingHeight-4);});if(groups.length&&lastGroupOffset<top+height) context.fillRect(0,lastGroupOffset+2,width,top+height-lastGroupOffset) context.strokeStyle=WebInspector.themeSupport.patchColor("#bbb",colorUsage.Background);context.beginPath();forEachGroup.call(this,(offset,index,group,isFirst)=>{if(isFirst||group.style.padding<4) return;hLine(offset-2.5);});hLine(lastGroupOffset+0.5);context.stroke();forEachGroup.call(this,(offset,index,group)=>{if(group.style.useFirstLineForOverview) return;if(!this._isGroupCollapsible(index)||group.expanded){if(!group.style.shareHeaderLine){context.fillStyle=group.style.backgroundColor;context.fillRect(0,offset,width,group.style.height);} return;} var nextGroup=index+1;while(nextGroup<groups.length&&groups[nextGroup].style.nestingLevel>group.style.nestingLevel) nextGroup++;var endLevel=nextGroup<groups.length?groups[nextGroup].startLevel:this._dataProvider.maxStackDepth();this._drawCollapsedOverviewForGroup(offset+1,group.startLevel,endLevel);});context.save();forEachGroup.call(this,(offset,index,group)=>{context.font=group.style.font;if(this._isGroupCollapsible(index)&&!group.expanded||group.style.shareHeaderLine){var width=this._labelWidthForGroup(context,group);context.fillStyle=WebInspector.Color.parse(group.style.backgroundColor).setAlpha(0.7).asString(null);context.fillRect(this._headerLeftPadding-this._headerLabelXPadding,offset+this._headerLabelYPadding,width,barHeight-2*this._headerLabelYPadding);} context.fillStyle=group.style.color;context.fillText(group.name,Math.floor(this._expansionArrowIndent*(group.style.nestingLevel+1)+this._arrowSide),offset+textBaseHeight);});context.restore();context.fillStyle=WebInspector.themeSupport.patchColor("#6e6e6e",colorUsage.Foreground);context.beginPath();forEachGroup.call(this,(offset,index,group)=>{if(this._isGroupCollapsible(index)) drawExpansionArrow.call(this,this._expansionArrowIndent*(group.style.nestingLevel+1),offset+textBaseHeight-this._arrowSide/2,!!group.expanded)});context.fill();context.strokeStyle=WebInspector.themeSupport.patchColor("#ddd",colorUsage.Background);context.beginPath();context.stroke();context.restore();function hLine(y) {context.moveTo(0,y);context.lineTo(width,y);} function drawExpansionArrow(x,y,expanded) {var arrowHeight=this._arrowSide*Math.sqrt(3)/2;var arrowCenterOffset=Math.round(arrowHeight/2);context.save();context.translate(x,y);context.rotate(expanded?Math.PI/2:0);context.moveTo(-arrowCenterOffset,-this._arrowSide/2);context.lineTo(-arrowCenterOffset,this._arrowSide/2);context.lineTo(arrowHeight-arrowCenterOffset,0);context.restore();} function forEachGroup(callback) {var groupStack=[{nestingLevel:-1,visible:true}];for(var i=0;i<groups.length;++i){var groupTop=groupOffsets[i];var group=groups[i];if(groupTop-group.style.padding>top+height) break;var firstGroup=true;while(groupStack.peekLast().nestingLevel>=group.style.nestingLevel){groupStack.pop();firstGroup=false;} var parentGroupVisible=groupStack.peekLast().visible;var thisGroupVisible=parentGroupVisible&&(!this._isGroupCollapsible(i)||group.expanded);groupStack.push({nestingLevel:group.style.nestingLevel,visible:thisGroupVisible});if(!parentGroupVisible||groupTop+group.style.height<top) continue;callback(groupTop,i,group,firstGroup);}}},_labelWidthForGroup:function(context,group) {return this._measureWidth(context,group.name)+this._expansionArrowIndent*(group.style.nestingLevel+1)+2*this._headerLabelXPadding;},_drawCollapsedOverviewForGroup:function(y,startLevel,endLevel) {var range=new WebInspector.SegmentedRange(mergeCallback);var timeWindowRight=this._timeWindowRight;var timeWindowLeft=this._timeWindowLeft-this._paddingLeft/this._timeToPixel;var context=this._canvas.getContext("2d");var barHeight=this._barHeight-2;var entryStartTimes=this._rawTimelineData.entryStartTimes;var entryTotalTimes=this._rawTimelineData.entryTotalTimes;for(var level=startLevel;level<endLevel;++level){var levelIndexes=this._timelineLevels[level];var rightIndexOnLevel=levelIndexes.lowerBound(timeWindowRight,(time,entryIndex)=>time-entryStartTimes[entryIndex])-1;var lastDrawOffset=Infinity;for(var entryIndexOnLevel=rightIndexOnLevel;entryIndexOnLevel>=0;--entryIndexOnLevel){var entryIndex=levelIndexes[entryIndexOnLevel];var entryStartTime=entryStartTimes[entryIndex];var startPosition=this._timeToPositionClipped(entryStartTime);var entryEndTime=entryStartTime+entryTotalTimes[entryIndex];if(isNaN(entryEndTime)||startPosition>=lastDrawOffset) continue;if(entryEndTime<=timeWindowLeft) break;lastDrawOffset=startPosition;var color=this._dataProvider.entryColor(entryIndex);range.append(new WebInspector.Segment(startPosition,this._timeToPositionClipped(entryEndTime),color));}} var segments=range.segments().slice().sort((a,b)=>a.data.localeCompare(b.data));var lastColor;context.beginPath();for(var i=0;i<segments.length;++i){var segment=segments[i];if(lastColor!==segments[i].data){context.fill();context.beginPath();lastColor=segments[i].data;context.fillStyle=lastColor;} context.rect(segment.begin,y,segment.end-segment.begin,barHeight);} context.fill();function mergeCallback(a,b) {return a.data===b.data&&a.end+0.4>b.end?a:null;}},_drawFlowEvents:function(context,width,height) {var timelineData=this._timelineData();var timeWindowRight=this._timeWindowRight;var timeWindowLeft=this._timeWindowLeft;var flowStartTimes=timelineData.flowStartTimes;var flowEndTimes=timelineData.flowEndTimes;var flowStartLevels=timelineData.flowStartLevels;var flowEndLevels=timelineData.flowEndLevels;var flowCount=flowStartTimes.length;var endIndex=flowStartTimes.lowerBound(timeWindowRight);var color=[];var fadeColorsCount=8;for(var i=0;i<=fadeColorsCount;++i) color[i]="rgba(128, 0, 0, "+i/fadeColorsCount+")";var fadeColorsRange=color.length;var minimumFlowDistancePx=15;var flowArcHeight=4*this._barHeight;var colorIndex=0;context.lineWidth=0.5;for(var i=0;i<endIndex;++i){if(flowEndTimes[i]<timeWindowLeft) continue;var startX=this._timeToPosition(flowStartTimes[i]);var endX=this._timeToPosition(flowEndTimes[i]);if(endX-startX<minimumFlowDistancePx) continue;if(startX<-minimumFlowDistancePx&&endX>width+minimumFlowDistancePx) continue;if(endX-startX<minimumFlowDistancePx+fadeColorsRange||colorIndex!==color.length-1){colorIndex=Math.min(fadeColorsRange-1,Math.floor(endX-startX-minimumFlowDistancePx));context.strokeStyle=color[colorIndex];} var startY=this._levelToHeight(flowStartLevels[i])+this._barHeight;var endY=this._levelToHeight(flowEndLevels[i]);context.beginPath();context.moveTo(startX,startY);var arcHeight=Math.max(Math.sqrt(Math.abs(startY-endY)),flowArcHeight)+5;context.bezierCurveTo(startX,startY+arcHeight,endX,endY+arcHeight,endX,endY+this._barHeight);context.stroke();}},_drawMarkers:function() {var markers=this._timelineData().markers;var left=this._markerIndexBeforeTime(this._calculator.minimumBoundary());var rightBoundary=this._calculator.maximumBoundary();var context=this._canvas.getContext("2d");context.save();var ratio=window.devicePixelRatio;context.scale(ratio,ratio);var height=WebInspector.FlameChart.DividersBarHeight-1;for(var i=left;i<markers.length;i++){var timestamp=markers[i].startTime();if(timestamp>rightBoundary) break;markers[i].draw(context,this._calculator.computePosition(timestamp),height,this._timeToPixel);} context.restore();},_updateMarkerHighlight:function() {var element=this._markerHighlighElement;if(element.parentElement) element.remove();var markerIndex=this._highlightedMarkerIndex;if(markerIndex===-1) return;var marker=this._timelineData().markers[markerIndex];var barX=this._timeToPositionClipped(marker.startTime());element.title=marker.title();var style=element.style;style.left=barX+"px";style.backgroundColor=marker.color();this.contentElement.appendChild(element);},_processTimelineData:function(timelineData) {if(!timelineData){this._timelineLevels=null;this._visibleLevelOffsets=null;this._visibleLevels=null;this._groupOffsets=null;this._rawTimelineData=null;this._rawTimelineDataLength=0;return;} this._rawTimelineData=timelineData;this._rawTimelineDataLength=timelineData.entryStartTimes.length;var entryCounters=new Uint32Array(this._dataProvider.maxStackDepth()+1);for(var i=0;i<timelineData.entryLevels.length;++i) ++entryCounters[timelineData.entryLevels[i]];var levelIndexes=new Array(entryCounters.length);for(var i=0;i<levelIndexes.length;++i){levelIndexes[i]=new Uint32Array(entryCounters[i]);entryCounters[i]=0;} for(var i=0;i<timelineData.entryLevels.length;++i){var level=timelineData.entryLevels[i];levelIndexes[level][entryCounters[level]++]=i;} this._timelineLevels=levelIndexes;var groups=this._rawTimelineData.groups||[];for(var i=0;i<groups.length;++i){var expanded=this._groupExpansionState[groups[i].name];if(expanded!==undefined) groups[i].expanded=expanded;} this._updateLevelPositions();},_updateLevelPositions:function() {var levelCount=this._dataProvider.maxStackDepth();var groups=this._rawTimelineData.groups||[];this._visibleLevelOffsets=new Uint32Array(levelCount+1);this._visibleLevels=new Uint8Array(levelCount);this._groupOffsets=new Uint32Array(groups.length+1);var groupIndex=-1;var currentOffset=WebInspector.FlameChart.DividersBarHeight;var visible=true;var groupStack=[{nestingLevel:-1,visible:true}];for(var level=0;level<levelCount;++level){while(groupIndex<groups.length-1&&level===groups[groupIndex+1].startLevel){++groupIndex;var style=groups[groupIndex].style;var nextLevel=true;while(groupStack.peekLast().nestingLevel>=style.nestingLevel){groupStack.pop();nextLevel=false;} var thisGroupIsVisible=groupIndex>=0&&this._isGroupCollapsible(groupIndex)?groups[groupIndex].expanded:true;var parentGroupIsVisible=groupStack.peekLast().visible;visible=thisGroupIsVisible&&parentGroupIsVisible;groupStack.push({nestingLevel:style.nestingLevel,visible:visible});if(parentGroupIsVisible) currentOffset+=nextLevel?0:style.padding;this._groupOffsets[groupIndex]=currentOffset;if(parentGroupIsVisible&&!style.shareHeaderLine) currentOffset+=style.height;} var isFirstOnLevel=groupIndex>=0&&level===groups[groupIndex].startLevel;var thisLevelIsVisible=visible||isFirstOnLevel&&groups[groupIndex].style.useFirstLineForOverview;this._visibleLevels[level]=thisLevelIsVisible;this._visibleLevelOffsets[level]=currentOffset;if(thisLevelIsVisible||(parentGroupIsVisible&&style.shareHeaderLine&&isFirstOnLevel)) currentOffset+=this._barHeight;} if(groupIndex>=0) this._groupOffsets[groupIndex+1]=currentOffset;this._visibleLevelOffsets[level]=currentOffset;},_isGroupCollapsible:function(index) {var groups=this._rawTimelineData.groups||[];var style=groups[index].style;if(!style.shareHeaderLine||!style.collapsible) return!!style.collapsible;var isLastGroup=index+1>=groups.length;if(!isLastGroup&&groups[index+1].style.nestingLevel>style.nestingLevel) return true;var nextGroupLevel=isLastGroup?this._dataProvider.maxStackDepth():groups[index+1].startLevel;return nextGroupLevel!==groups[index].startLevel+1;},setSelectedEntry:function(entryIndex) {if(entryIndex===-1&&!this._isDragging) this._hideRangeSelection();if(this._selectedEntryIndex===entryIndex) return;this._selectedEntryIndex=entryIndex;this._revealEntry(entryIndex);this._updateElementPosition(this._selectedElement,this._selectedEntryIndex);},_updateElementPosition:function(element,entryIndex) {var elementMinWidth=2;if(element.parentElement) element.remove();if(entryIndex===-1) return;var timeRange=this._dataProvider.highlightTimeRange(entryIndex);if(!timeRange) return;var timelineData=this._timelineData();var barX=this._timeToPositionClipped(timeRange.startTime);var barRight=this._timeToPositionClipped(timeRange.endTime);if(barRight===0||barX===this._canvas.width) return;var barWidth=barRight-barX;var barCenter=barX+barWidth/2;barWidth=Math.max(barWidth,elementMinWidth);barX=barCenter-barWidth/2;var barY=this._levelToHeight(timelineData.entryLevels[entryIndex])-this._scrollTop;var style=element.style;style.left=barX+"px";style.top=barY+"px";style.width=barWidth+"px";style.height=this._barHeight-1+"px";this.contentElement.appendChild(element);},_timeToPositionClipped:function(time) {return Number.constrain(this._timeToPosition(time),0,this._canvas.width);},_timeToPosition:function(time) {return Math.floor((time-this._minimumBoundary)*this._timeToPixel)-this._pixelWindowLeft+this._paddingLeft;},_levelToHeight:function(level) {return this._visibleLevelOffsets[level];},_buildEntryInfo:function(entryInfo) {var infoTable=createElementWithClass("table","info-table");for(var entry of entryInfo){var row=infoTable.createChild("tr");row.createChild("td","title").textContent=entry.title;if(typeof entry.value==="string") row.createChild("td").textContent=entry.value;else row.createChild("td").appendChild(entry.value);} return infoTable;},_prepareText:function(context,text,maxWidth) {var maxLength=200;if(maxWidth<=10) return"";if(text.length>maxLength) text=text.trimMiddle(maxLength);var textWidth=this._measureWidth(context,text);if(textWidth<=maxWidth) return text;var l=0;var r=text.length;var lv=0;var rv=textWidth;while(l<r&&lv!==rv&&lv!==maxWidth){var m=Math.ceil(l+(r-l)*(maxWidth-lv)/(rv-lv));var mv=this._measureWidth(context,text.trimMiddle(m));if(mv<=maxWidth){l=m;lv=mv;}else{r=m-1;rv=mv;}} text=text.trimMiddle(l);return text!=="\u2026"?text:"";},_measureWidth:function(context,text) {var maxCacheableLength=200;if(text.length>maxCacheableLength) return context.measureText(text).width;var font=context.font;var textWidths=this._textWidth.get(font);if(!textWidths){textWidths=new Map();this._textWidth.set(font,textWidths);} var width=textWidths.get(text);if(!width){width=context.measureText(text).width;textWidths.set(text,width);} return width;},_updateBoundaries:function() {this._totalTime=this._dataProvider.totalTime();this._minimumBoundary=this._dataProvider.minimumBoundary();var windowWidth=1;if(this._timeWindowRight!==Infinity){this._windowLeft=(this._timeWindowLeft-this._minimumBoundary)/this._totalTime;this._windowRight=(this._timeWindowRight-this._minimumBoundary)/this._totalTime;windowWidth=this._windowRight-this._windowLeft;}else if(this._timeWindowLeft===Infinity){this._windowLeft=Infinity;this._windowRight=Infinity;}else{this._windowLeft=0;this._windowRight=1;} var totalPixels=Math.floor((this._offsetWidth-this._paddingLeft)/windowWidth);this._pixelWindowLeft=Math.floor(totalPixels*this._windowLeft);this._timeToPixel=totalPixels/this._totalTime;this._pixelToTime=this._totalTime/totalPixels;this._updateScrollBar();},_updateHeight:function() {this._totalHeight=this._levelToHeight(this._dataProvider.maxStackDepth());this._vScrollContent.style.height=this._totalHeight+"px";},onResize:function() {this._updateScrollBar();this._updateContentElementSize();this.scheduleUpdate();},_updateScrollBar:function() {var showScroll=this._totalHeight>this._offsetHeight;if(this._vScrollElement.classList.contains("hidden")===showScroll){this._vScrollElement.classList.toggle("hidden",!showScroll);this._updateContentElementSize();}},_updateContentElementSize:function() {this._offsetWidth=this.contentElement.offsetWidth;this._offsetHeight=this.contentElement.offsetHeight;},_onScroll:function() {this._scrollTop=this._vScrollElement.scrollTop;this.scheduleUpdate();},scheduleUpdate:function() {if(this._updateTimerId||this._cancelWindowTimesAnimation) return;this._updateTimerId=this.element.window().requestAnimationFrame(this.update.bind(this));},update:function() {this._updateTimerId=0;if(!this._timelineData()) return;this._resetCanvas();this._updateHeight();this._updateBoundaries();this._calculator._updateBoundaries(this);this._draw(this._offsetWidth,this._offsetHeight);if(!this._isDragging) this._updateHighlight();},reset:function() {this._vScrollElement.scrollTop=0;this._highlightedMarkerIndex=-1;this._highlightedEntryIndex=-1;this._selectedEntryIndex=-1;this._rangeSelectionStart=0;this._rangeSelectionEnd=0;this._textWidth=new Map();this.update();},_enabled:function() {return this._rawTimelineDataLength!==0;},__proto__:WebInspector.HBox.prototype};WebInspector.OverviewGrid=function(prefix) {this.element=createElement("div");this.element.id=prefix+"-overview-container";this._grid=new WebInspector.TimelineGrid();this._grid.element.id=prefix+"-overview-grid";this._grid.setScrollTop(0);this.element.appendChild(this._grid.element);this._window=new WebInspector.OverviewGrid.Window(this.element,this._grid.dividersLabelBarElement);this._window.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);} WebInspector.OverviewGrid.prototype={clientWidth:function() {return this.element.clientWidth;},updateDividers:function(calculator) {this._grid.updateDividers(calculator);},addEventDividers:function(dividers) {this._grid.addEventDividers(dividers);},removeEventDividers:function() {this._grid.removeEventDividers();},reset:function() {this._window.reset();},windowLeft:function() {return this._window.windowLeft;},windowRight:function() {return this._window.windowRight;},setWindow:function(left,right) {this._window._setWindow(left,right);},addEventListener:function(eventType,listener,thisObject) {return this._window.addEventListener(eventType,listener,thisObject);},zoom:function(zoomFactor,referencePoint) {this._window._zoom(zoomFactor,referencePoint);},setResizeEnabled:function(enabled) {this._window.setEnabled(enabled);},_onWindowChanged:function() {this._grid.showCurtains(this.windowLeft(),this.windowRight());}} WebInspector.OverviewGrid.MinSelectableSize=14;WebInspector.OverviewGrid.WindowScrollSpeedFactor=.3;WebInspector.OverviewGrid.ResizerOffset=3.5;WebInspector.OverviewGrid.Window=function(parentElement,dividersLabelBarElement) {this._parentElement=parentElement;WebInspector.installDragHandle(this._parentElement,this._startWindowSelectorDragging.bind(this),this._windowSelectorDragging.bind(this),this._endWindowSelectorDragging.bind(this),"text",null);if(dividersLabelBarElement) WebInspector.installDragHandle(dividersLabelBarElement,this._startWindowDragging.bind(this),this._windowDragging.bind(this),null,"-webkit-grabbing","-webkit-grab");this.windowLeft=0.0;this.windowRight=1.0;this._parentElement.addEventListener("mousewheel",this._onMouseWheel.bind(this),true);this._parentElement.addEventListener("dblclick",this._resizeWindowMaximum.bind(this),true);WebInspector.appendStyle(this._parentElement,"ui_lazy/overviewGrid.css");this._leftResizeElement=parentElement.createChild("div","overview-grid-window-resizer");this._leftResizeElement.style.left="0";WebInspector.installDragHandle(this._leftResizeElement,this._resizerElementStartDragging.bind(this),this._leftResizeElementDragging.bind(this),null,"ew-resize");this._rightResizeElement=parentElement.createChild("div","overview-grid-window-resizer");this._rightResizeElement.style.right="0";WebInspector.installDragHandle(this._rightResizeElement,this._resizerElementStartDragging.bind(this),this._rightResizeElementDragging.bind(this),null,"ew-resize");this.setEnabled(true);} WebInspector.OverviewGrid.Events={WindowChanged:"WindowChanged",Click:"Click"} WebInspector.OverviewGrid.Window.prototype={reset:function() {this.windowLeft=0.0;this.windowRight=1.0;this._leftResizeElement.style.left="0%";this._rightResizeElement.style.left="100%";this.setEnabled(true);},setEnabled:function(enabled) {this._enabled=enabled;},_resizerElementStartDragging:function(event) {if(!this._enabled) return false;this._resizerParentOffsetLeft=event.pageX-event.offsetX-event.target.offsetLeft;event.preventDefault();return true;},_leftResizeElementDragging:function(event) {this._resizeWindowLeft(event.pageX-this._resizerParentOffsetLeft);event.preventDefault();},_rightResizeElementDragging:function(event) {this._resizeWindowRight(event.pageX-this._resizerParentOffsetLeft);event.preventDefault();},_startWindowSelectorDragging:function(event) {if(!this._enabled) return false;this._offsetLeft=this._parentElement.totalOffsetLeft();var position=event.x-this._offsetLeft;this._overviewWindowSelector=new WebInspector.OverviewGrid.WindowSelector(this._parentElement,position);return true;},_windowSelectorDragging:function(event) {this._overviewWindowSelector._updatePosition(event.x-this._offsetLeft);event.preventDefault();},_endWindowSelectorDragging:function(event) {var window=this._overviewWindowSelector._close(event.x-this._offsetLeft);delete this._overviewWindowSelector;var clickThreshold=3;if(window.end-window.start<clickThreshold){if(this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.Click,event)) return;var middle=window.end;window.start=Math.max(0,middle-WebInspector.OverviewGrid.MinSelectableSize/2);window.end=Math.min(this._parentElement.clientWidth,middle+WebInspector.OverviewGrid.MinSelectableSize/2);}else if(window.end-window.start<WebInspector.OverviewGrid.MinSelectableSize){if(this._parentElement.clientWidth-window.end>WebInspector.OverviewGrid.MinSelectableSize) window.end=window.start+WebInspector.OverviewGrid.MinSelectableSize;else window.start=window.end-WebInspector.OverviewGrid.MinSelectableSize;} this._setWindowPosition(window.start,window.end);},_startWindowDragging:function(event) {this._dragStartPoint=event.pageX;this._dragStartLeft=this.windowLeft;this._dragStartRight=this.windowRight;return true;},_windowDragging:function(event) {event.preventDefault();var delta=(event.pageX-this._dragStartPoint)/this._parentElement.clientWidth;if(this._dragStartLeft+delta<0) delta=-this._dragStartLeft;if(this._dragStartRight+delta>1) delta=1-this._dragStartRight;this._setWindow(this._dragStartLeft+delta,this._dragStartRight+delta);},_resizeWindowLeft:function(start) {if(start<10) start=0;else if(start>this._rightResizeElement.offsetLeft-4) start=this._rightResizeElement.offsetLeft-4;this._setWindowPosition(start,null);},_resizeWindowRight:function(end) {if(end>this._parentElement.clientWidth-10) end=this._parentElement.clientWidth;else if(end<this._leftResizeElement.offsetLeft+WebInspector.OverviewGrid.MinSelectableSize) end=this._leftResizeElement.offsetLeft+WebInspector.OverviewGrid.MinSelectableSize;this._setWindowPosition(null,end);},_resizeWindowMaximum:function() {this._setWindowPosition(0,this._parentElement.clientWidth);},_setWindow:function(windowLeft,windowRight) {var left=windowLeft;var right=windowRight;var width=windowRight-windowLeft;var widthInPixels=width*this._parentElement.clientWidth;var minWidthInPixels=WebInspector.OverviewGrid.MinSelectableSize/2;if(widthInPixels<minWidthInPixels){var factor=minWidthInPixels/widthInPixels;left=((windowRight+windowLeft)-width*factor)/2;right=((windowRight+windowLeft)+width*factor)/2;} this.windowLeft=windowLeft;this._leftResizeElement.style.left=left*100+"%";this.windowRight=windowRight;this._rightResizeElement.style.left=right*100+"%";this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged);},_setWindowPosition:function(start,end) {var clientWidth=this._parentElement.clientWidth;var windowLeft=typeof start==="number"?start/clientWidth:this.windowLeft;var windowRight=typeof end==="number"?end/clientWidth:this.windowRight;this._setWindow(windowLeft,windowRight);},_onMouseWheel:function(event) {if(!this._enabled) return;if(typeof event.wheelDeltaY==="number"&&event.wheelDeltaY){const zoomFactor=1.1;const mouseWheelZoomSpeed=1/120;var reference=event.offsetX/event.target.clientWidth;this._zoom(Math.pow(zoomFactor,-event.wheelDeltaY*mouseWheelZoomSpeed),reference);} if(typeof event.wheelDeltaX==="number"&&event.wheelDeltaX){var offset=Math.round(event.wheelDeltaX*WebInspector.OverviewGrid.WindowScrollSpeedFactor);var windowLeft=this._leftResizeElement.offsetLeft+WebInspector.OverviewGrid.ResizerOffset;var windowRight=this._rightResizeElement.offsetLeft+WebInspector.OverviewGrid.ResizerOffset;if(windowLeft-offset<0) offset=windowLeft;if(windowRight-offset>this._parentElement.clientWidth) offset=windowRight-this._parentElement.clientWidth;this._setWindowPosition(windowLeft-offset,windowRight-offset);event.preventDefault();}},_zoom:function(factor,reference) {var left=this.windowLeft;var right=this.windowRight;var windowSize=right-left;var newWindowSize=factor*windowSize;if(newWindowSize>1){newWindowSize=1;factor=newWindowSize/windowSize;} left=reference+(left-reference)*factor;left=Number.constrain(left,0,1-newWindowSize);right=reference+(right-reference)*factor;right=Number.constrain(right,newWindowSize,1);this._setWindow(left,right);},__proto__:WebInspector.Object.prototype} WebInspector.OverviewGrid.WindowSelector=function(parent,position) {this._startPosition=position;this._width=parent.offsetWidth;this._windowSelector=createElement("div");this._windowSelector.className="overview-grid-window-selector";this._windowSelector.style.left=this._startPosition+"px";this._windowSelector.style.right=this._width-this._startPosition+"px";parent.appendChild(this._windowSelector);} WebInspector.OverviewGrid.WindowSelector.prototype={_close:function(position) {position=Math.max(0,Math.min(position,this._width));this._windowSelector.remove();return this._startPosition<position?{start:this._startPosition,end:position}:{start:position,end:this._startPosition};},_updatePosition:function(position) {position=Math.max(0,Math.min(position,this._width));if(position<this._startPosition){this._windowSelector.style.left=position+"px";this._windowSelector.style.right=this._width-this._startPosition+"px";}else{this._windowSelector.style.left=this._startPosition+"px";this._windowSelector.style.right=this._width-position+"px";}}};WebInspector.PieChart=function(size,formatter,showTotal) {this.element=createElement("div");this._shadowRoot=WebInspector.createShadowRootWithCoreStyles(this.element,"ui_lazy/pieChart.css");var root=this._shadowRoot.createChild("div","root");var svg=this._createSVGChild(root,"svg");this._group=this._createSVGChild(svg,"g");var background=this._createSVGChild(this._group,"circle");background.setAttribute("r",1.01);background.setAttribute("fill","hsl(0, 0%, 90%)");this._foregroundElement=root.createChild("div","pie-chart-foreground");if(showTotal) this._totalElement=this._foregroundElement.createChild("div","pie-chart-total");this._formatter=formatter;this._slices=[];this._lastAngle=-Math.PI/2;this._setSize(size);} WebInspector.PieChart.prototype={setTotal:function(totalValue) {for(var i=0;i<this._slices.length;++i) this._slices[i].remove();this._slices=[];this._totalValue=totalValue;var totalString;if(totalValue) totalString=this._formatter?this._formatter(totalValue):totalValue;else totalString="";if(this._totalElement) this._totalElement.textContent=totalString;},_setSize:function(value) {this._group.setAttribute("transform","scale("+(value/2)+") translate(1, 1) scale(0.99, 0.99)");var size=value+"px";this.element.style.width=size;this.element.style.height=size;},addSlice:function(value,color) {var sliceAngle=value/this._totalValue*2*Math.PI;if(!isFinite(sliceAngle)) return;sliceAngle=Math.min(sliceAngle,2*Math.PI*0.9999);var path=this._createSVGChild(this._group,"path");var x1=Math.cos(this._lastAngle);var y1=Math.sin(this._lastAngle);this._lastAngle+=sliceAngle;var x2=Math.cos(this._lastAngle);var y2=Math.sin(this._lastAngle);var largeArc=sliceAngle>Math.PI?1:0;path.setAttribute("d","M0,0 L"+x1+","+y1+" A1,1,0,"+largeArc+",1,"+x2+","+y2+" Z");path.setAttribute("fill",color);this._slices.push(path);},_createSVGChild:function(parent,childType) {var child=parent.ownerDocument.createElementNS("http://www.w3.org/2000/svg",childType);parent.appendChild(child);return child;}};WebInspector.TimelineGrid=function() {this.element=createElement("div");WebInspector.appendStyle(this.element,"ui_lazy/timelineGrid.css");this._dividersElement=this.element.createChild("div","resources-dividers");this._gridHeaderElement=createElement("div");this._gridHeaderElement.classList.add("timeline-grid-header");this._eventDividersElement=this._gridHeaderElement.createChild("div","resources-event-dividers");this._dividersLabelBarElement=this._gridHeaderElement.createChild("div","resources-dividers-label-bar");this.element.appendChild(this._gridHeaderElement);this._leftCurtainElement=this.element.createChild("div","timeline-curtain-left");this._rightCurtainElement=this.element.createChild("div","timeline-curtain-right");} WebInspector.TimelineGrid.calculateDividerOffsets=function(calculator,freeZoneAtLeft) {var minGridSlicePx=64;var clientWidth=calculator.computePosition(calculator.maximumBoundary());var dividersCount=clientWidth/minGridSlicePx;var gridSliceTime=calculator.boundarySpan()/dividersCount;var pixelsPerTime=clientWidth/calculator.boundarySpan();var logGridSliceTime=Math.ceil(Math.log(gridSliceTime)/Math.LN10);gridSliceTime=Math.pow(10,logGridSliceTime);if(gridSliceTime*pixelsPerTime>=5*minGridSlicePx) gridSliceTime=gridSliceTime/5;if(gridSliceTime*pixelsPerTime>=2*minGridSlicePx) gridSliceTime=gridSliceTime/2;var leftBoundaryTime=calculator.minimumBoundary()-calculator.paddingLeft()/pixelsPerTime;var firstDividerTime=Math.ceil((leftBoundaryTime-calculator.zeroTime())/gridSliceTime)*gridSliceTime+calculator.zeroTime();var lastDividerTime=calculator.maximumBoundary();lastDividerTime+=minGridSlicePx/pixelsPerTime;dividersCount=Math.ceil((lastDividerTime-firstDividerTime)/gridSliceTime);if(!gridSliceTime) dividersCount=0;var offsets=[];for(var i=0;i<dividersCount;++i){var time=firstDividerTime+gridSliceTime*i;if(calculator.computePosition(time)<freeZoneAtLeft) continue;offsets.push(time);} return{offsets:offsets,precision:Math.max(0,-Math.floor(Math.log(gridSliceTime*1.01)/Math.LN10))};} WebInspector.TimelineGrid.drawCanvasGrid=function(canvas,calculator,dividerOffsets) {var context=canvas.getContext("2d");context.save();var ratio=window.devicePixelRatio;context.scale(ratio,ratio);var printDeltas=!!dividerOffsets;var width=canvas.width/window.devicePixelRatio;var height=canvas.height/window.devicePixelRatio;var precision=0;if(!dividerOffsets){var dividersData=WebInspector.TimelineGrid.calculateDividerOffsets(calculator);dividerOffsets=dividersData.offsets;precision=dividersData.precision;} context.fillStyle="rgba(255, 255, 255, 0.5)";context.fillRect(0,0,width,15);context.fillStyle="#333";context.strokeStyle="rgba(0, 0, 0, 0.1)";context.textBaseline="hanging";context.font=(printDeltas?"italic bold 11px ":" 11px ")+WebInspector.fontFamily();context.lineWidth=1;context.translate(0.5,0.5);const minWidthForTitle=60;var lastPosition=0;var time=0;var lastTime=0;var paddingRight=4;var paddingTop=3;for(var i=0;i<dividerOffsets.length;++i){time=dividerOffsets[i];var position=calculator.computePosition(time);context.beginPath();if(!printDeltas||i!==0&&position-lastPosition>minWidthForTitle){var text=printDeltas?calculator.formatValue(calculator.zeroTime()+time-lastTime):calculator.formatValue(time,precision);var textWidth=context.measureText(text).width;var textPosition=printDeltas?(position+lastPosition-textWidth)/2:position-textWidth-paddingRight;context.fillText(text,textPosition,paddingTop);} context.moveTo(position,0);context.lineTo(position,height);context.stroke();lastTime=time;lastPosition=position;} context.restore();} WebInspector.TimelineGrid.prototype={get dividersElement() {return this._dividersElement;},get dividersLabelBarElement() {return this._dividersLabelBarElement;},removeDividers:function() {this._dividersElement.removeChildren();this._dividersLabelBarElement.removeChildren();},updateDividers:function(calculator,freeZoneAtLeft) {var dividersData=WebInspector.TimelineGrid.calculateDividerOffsets(calculator,freeZoneAtLeft);var dividerOffsets=dividersData.offsets;var precision=dividersData.precision;var dividersElementClientWidth=this._dividersElement.clientWidth;var divider=(this._dividersElement.firstChild);var dividerLabelBar=(this._dividersLabelBarElement.firstChild);for(var i=0;i<dividerOffsets.length;++i){if(!divider){divider=createElement("div");divider.className="resources-divider";this._dividersElement.appendChild(divider);dividerLabelBar=createElement("div");dividerLabelBar.className="resources-divider";var label=createElement("div");label.className="resources-divider-label";dividerLabelBar._labelElement=label;dividerLabelBar.appendChild(label);this._dividersLabelBarElement.appendChild(dividerLabelBar);} var time=dividerOffsets[i];var position=calculator.computePosition(time);dividerLabelBar._labelElement.textContent=calculator.formatValue(time,precision);var percentLeft=100*position/dividersElementClientWidth;divider.style.left=percentLeft+"%";dividerLabelBar.style.left=percentLeft+"%";divider=(divider.nextSibling);dividerLabelBar=(dividerLabelBar.nextSibling);} while(divider){var nextDivider=divider.nextSibling;this._dividersElement.removeChild(divider);divider=nextDivider;} while(dividerLabelBar){var nextDivider=dividerLabelBar.nextSibling;this._dividersLabelBarElement.removeChild(dividerLabelBar);dividerLabelBar=nextDivider;} return true;},addEventDivider:function(divider) {this._eventDividersElement.appendChild(divider);},addEventDividers:function(dividers) {this._gridHeaderElement.removeChild(this._eventDividersElement);for(var divider of dividers) this._eventDividersElement.appendChild(divider);this._gridHeaderElement.appendChild(this._eventDividersElement);},removeEventDividers:function() {this._eventDividersElement.removeChildren();},hideEventDividers:function() {this._eventDividersElement.classList.add("hidden");},showEventDividers:function() {this._eventDividersElement.classList.remove("hidden");},hideDividers:function() {this._dividersElement.classList.add("hidden");},showDividers:function() {this._dividersElement.classList.remove("hidden");},hideCurtains:function() {this._leftCurtainElement.classList.add("hidden");this._rightCurtainElement.classList.add("hidden");},showCurtains:function(left,right) {this._leftCurtainElement.style.width=(100*left).toFixed(2)+"%";this._leftCurtainElement.classList.remove("hidden");this._rightCurtainElement.style.width=(100*(1-right)).toFixed(2)+"%";this._rightCurtainElement.classList.remove("hidden");},setScrollTop:function(scrollTop) {this._dividersLabelBarElement.style.top=scrollTop+"px";this._eventDividersElement.style.top=scrollTop+"px";this._leftCurtainElement.style.top=scrollTop+"px";this._rightCurtainElement.style.top=scrollTop+"px";}} WebInspector.TimelineGrid.Calculator=function(){} WebInspector.TimelineGrid.Calculator.prototype={paddingLeft:function(){},computePosition:function(time){},formatValue:function(time,precision){},minimumBoundary:function(){},zeroTime:function(){},maximumBoundary:function(){},boundarySpan:function(){}};WebInspector.TimelineOverviewPane=function(prefix) {WebInspector.VBox.call(this);this.element.id=prefix+"-overview-pane";this._overviewCalculator=new WebInspector.TimelineOverviewCalculator();this._overviewGrid=new WebInspector.OverviewGrid(prefix);this.element.appendChild(this._overviewGrid.element);this._cursorArea=this._overviewGrid.element.createChild("div","overview-grid-cursor-area");this._cursorElement=this._overviewGrid.element.createChild("div","overview-grid-cursor-position");this._cursorArea.addEventListener("mousemove",this._onMouseMove.bind(this),true);this._cursorArea.addEventListener("mouseleave",this._hideCursor.bind(this),true);this._overviewGrid.setResizeEnabled(false);this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged,this._onWindowChanged,this);this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.Click,this._onClick,this);this._overviewControls=[];this._markers=new Map();this._popoverHelper=new WebInspector.PopoverHelper(this._cursorArea,this._getPopoverAnchor.bind(this),this._showPopover.bind(this),this._onHidePopover.bind(this));this._popoverHelper.setTimeout(0);this._updateThrottler=new WebInspector.Throttler(100);this._cursorEnabled=false;this._cursorPosition=0;this._lastWidth=0;} WebInspector.TimelineOverviewPane.Events={WindowChanged:"WindowChanged"};WebInspector.TimelineOverviewPane.prototype={_getPopoverAnchor:function(element,event) {return this._cursorArea;},_showPopover:function(anchor,popover) {this._buildPopoverContents().then(maybeShowPopover.bind(this));function maybeShowPopover(fragment) {if(!fragment.firstChild) return;var content=new WebInspector.TimelineOverviewPane.PopoverContents();this._popoverContents=content.contentElement.createChild("div");this._popoverContents.appendChild(fragment);this._popover=popover;popover.showView(content,this._cursorElement);}},_onHidePopover:function() {this._popover=null;this._popoverContents=null;},_onMouseMove:function(event) {if(!this._cursorEnabled) return;this._cursorPosition=event.offsetX+event.target.offsetLeft;this._cursorElement.style.left=this._cursorPosition+"px";this._cursorElement.style.visibility="visible";if(!this._popover) return;this._buildPopoverContents().then(updatePopover.bind(this));this._popover.positionElement(this._cursorElement);function updatePopover(fragment) {if(!this._popoverContents) return;this._popoverContents.removeChildren();this._popoverContents.appendChild(fragment);}},_buildPopoverContents:function() {var document=this.element.ownerDocument;var x=this._cursorPosition;var promises=this._overviewControls.map(control=>control.popoverElementPromise(x));return Promise.all(promises).then(buildFragment);function buildFragment(elements) {var fragment=document.createDocumentFragment();elements.remove(null);fragment.appendChildren.apply(fragment,elements);return fragment;}},_hideCursor:function() {this._cursorElement.style.visibility="hidden";},wasShown:function() {this._update();},willHide:function() {this._popoverHelper.hidePopover();},onResize:function() {var width=this.element.offsetWidth;if(width===this._lastWidth) return;this._lastWidth=width;this.scheduleUpdate();},setOverviewControls:function(overviewControls) {for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].dispose();for(var i=0;i<overviewControls.length;++i){overviewControls[i].setCalculator(this._overviewCalculator);overviewControls[i].show(this._overviewGrid.element);} this._overviewControls=overviewControls;this._update();},setBounds:function(minimumBoundary,maximumBoundary) {this._overviewCalculator.setBounds(minimumBoundary,maximumBoundary);this._overviewGrid.setResizeEnabled(true);this._cursorEnabled=true;},scheduleUpdate:function() {this._updateThrottler.schedule(process.bind(this));function process() {this._update();return Promise.resolve();}},_update:function() {if(!this.isShowing()) return;this._overviewCalculator.setDisplayWindow(this._overviewGrid.clientWidth());for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].update();this._overviewGrid.updateDividers(this._overviewCalculator);this._updateMarkers();this._updateWindow();},setMarkers:function(markers) {this._markers=markers;this._updateMarkers();},_updateMarkers:function() {var filteredMarkers=new Map();for(var time of this._markers.keys()){var marker=this._markers.get(time);var position=Math.round(this._overviewCalculator.computePosition(time));if(filteredMarkers.has(position)) continue;filteredMarkers.set(position,marker);marker.style.left=position+"px";} this._overviewGrid.removeEventDividers();this._overviewGrid.addEventDividers(filteredMarkers.valuesArray());},reset:function() {this._windowStartTime=0;this._windowEndTime=Infinity;this._overviewCalculator.reset();this._overviewGrid.reset();this._overviewGrid.setResizeEnabled(false);this._overviewGrid.updateDividers(this._overviewCalculator);this._cursorEnabled=false;this._hideCursor();this._markers=new Map();for(var i=0;i<this._overviewControls.length;++i) this._overviewControls[i].reset();this._popoverHelper.hidePopover();this._update();},_onClick:function(event) {var domEvent=(event.data);for(var overviewControl of this._overviewControls){if(overviewControl.onClick(domEvent)){event.preventDefault();return;}}},_onWindowChanged:function(event) {if(this._muteOnWindowChanged) return;if(!this._overviewControls.length) return;var windowTimes=this._overviewControls[0].windowTimes(this._overviewGrid.windowLeft(),this._overviewGrid.windowRight());this._windowStartTime=windowTimes.startTime;this._windowEndTime=windowTimes.endTime;this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged,windowTimes);},requestWindowTimes:function(startTime,endTime) {if(startTime===this._windowStartTime&&endTime===this._windowEndTime) return;this._windowStartTime=startTime;this._windowEndTime=endTime;this._updateWindow();this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged,{startTime:startTime,endTime:endTime});},_updateWindow:function() {if(!this._overviewControls.length) return;var windowBoundaries=this._overviewControls[0].windowBoundaries(this._windowStartTime,this._windowEndTime);this._muteOnWindowChanged=true;this._overviewGrid.setWindow(windowBoundaries.left,windowBoundaries.right);this._muteOnWindowChanged=false;},__proto__:WebInspector.VBox.prototype} WebInspector.TimelineOverviewPane.PopoverContents=function() {WebInspector.VBox.call(this,true);this.contentElement.classList.add("timeline-overview-popover");} WebInspector.TimelineOverviewPane.PopoverContents.prototype={__proto__:WebInspector.VBox.prototype} WebInspector.TimelineOverviewCalculator=function() {this.reset();} WebInspector.TimelineOverviewCalculator.prototype={paddingLeft:function() {return this._paddingLeft;},computePosition:function(time) {return(time-this._minimumBoundary)/this.boundarySpan()*this._workingArea+this._paddingLeft;},positionToTime:function(position) {return(position-this._paddingLeft)/this._workingArea*this.boundarySpan()+this._minimumBoundary;},setBounds:function(minimumBoundary,maximumBoundary) {this._minimumBoundary=minimumBoundary;this._maximumBoundary=maximumBoundary;},setDisplayWindow:function(clientWidth,paddingLeft) {this._paddingLeft=paddingLeft||0;this._workingArea=clientWidth-this._paddingLeft;},reset:function() {this.setBounds(0,1000);},formatValue:function(value,precision) {return Number.preciseMillisToString(value-this.zeroTime(),precision);},maximumBoundary:function() {return this._maximumBoundary;},minimumBoundary:function() {return this._minimumBoundary;},zeroTime:function() {return this._minimumBoundary;},boundarySpan:function() {return this._maximumBoundary-this._minimumBoundary;}} WebInspector.TimelineOverview=function() {} WebInspector.TimelineOverview.prototype={show:function(parentElement,insertBefore){},update:function(){},dispose:function(){},reset:function(){},popoverElementPromise:function(x){},onClick:function(event){},windowTimes:function(windowLeft,windowRight){},windowBoundaries:function(startTime,endTime){},timelineStarted:function(){},timelineStopped:function(){},} WebInspector.TimelineOverviewBase=function() {WebInspector.VBox.call(this);this._calculator=null;this._canvas=this.element.createChild("canvas","fill");this._context=this._canvas.getContext("2d");} WebInspector.TimelineOverviewBase.prototype={update:function() {this.resetCanvas();},dispose:function() {this.detach();},reset:function() {},popoverElementPromise:function(x) {return Promise.resolve((null));},timelineStarted:function() {},timelineStopped:function() {},setCalculator:function(calculator) {this._calculator=calculator;},onClick:function(event) {return false;},windowTimes:function(windowLeft,windowRight) {var absoluteMin=this._calculator.minimumBoundary();var timeSpan=this._calculator.maximumBoundary()-absoluteMin;return{startTime:absoluteMin+timeSpan*windowLeft,endTime:absoluteMin+timeSpan*windowRight};},windowBoundaries:function(startTime,endTime) {var absoluteMin=this._calculator.minimumBoundary();var timeSpan=this._calculator.maximumBoundary()-absoluteMin;var haveRecords=absoluteMin>0;return{left:haveRecords&&startTime?Math.min((startTime-absoluteMin)/timeSpan,1):0,right:haveRecords&&endTime<Infinity?(endTime-absoluteMin)/timeSpan:1};},resetCanvas:function() {this._canvas.width=this.element.clientWidth*window.devicePixelRatio;this._canvas.height=this.element.clientHeight*window.devicePixelRatio;},__proto__:WebInspector.VBox.prototype};Runtime.cachedResources["ui_lazy/dataGrid.css"]=".data-grid {\n position: relative;\n border: 1px solid #aaa;\n font-size: 11px;\n line-height: 120%;\n}\n\n.data-grid table {\n table-layout: fixed;\n border-spacing: 0;\n border-collapse: separate;\n height: 100%;\n width: 100%;\n}\n\n.data-grid .header-container,\n.data-grid .data-container {\n position: absolute;\n left: 0;\n right: 0;\n overflow-x: hidden;\n}\n\n.data-grid .header-container {\n top: 0;\n height: 17px;\n }\n\n.data-grid .data-container {\n top: 17px;\n bottom: 0;\n overflow-y: overlay;\n transform: translateZ(0);\n}\n\n.data-grid.inline .header-container,\n.data-grid.inline .data-container {\n position: static;\n}\n\n.data-grid.inline .corner {\n display: none;\n}\n\n.platform-mac .data-grid .corner,\n.data-grid.data-grid-fits-viewport .corner {\n display: none;\n}\n\n.data-grid .corner {\n width: 14px;\n padding-right: 0;\n padding-left: 0;\n border-left: 0 none transparent !important;\n}\n\n.data-grid .top-filler-td,\n.data-grid .bottom-filler-td {\n height: auto !important;\n padding: 0 !important;\n}\n\n.data-grid table.data {\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n border-top: 0 none transparent;\n background-image: linear-gradient(to bottom, transparent, transparent 50%, hsla(214, 100%, 40%, 0.1) 50%, hsla(214, 100%, 40%, 0.1));\n background-size: 128px 32px;\n table-layout: fixed;\n}\n\n.data-grid.inline table.data {\n position: static;\n}\n\n.data-grid table.data tr {\n display: none;\n}\n\n.data-grid table.data tr.revealed {\n display: table-row;\n}\n\n.data-grid td,\n.data-grid th {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n line-height: 14px;\n border-left: 1px solid #aaa;\n}\n\n.data-grid th:first-child,\n.data-grid td:first-child {\n border-left: none !important;\n}\n\n.data-grid td {\n height: 16px; /* Keep in sync with .data-grid table.data @ background-size */\n vertical-align: top;\n padding: 1px 4px;\n -webkit-user-select: text;\n}\n\n.data-grid th {\n height: auto;\n text-align: left;\n background-color: #eee;\n border-bottom: 1px solid #aaa;\n font-weight: normal;\n vertical-align: middle;\n padding: 0 4px;\n}\n\n.data-grid td > div,\n.data-grid th > div {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.data-grid td.editing > div {\n text-overflow: clip;\n}\n\n.data-grid .center {\n text-align: center;\n}\n\n.data-grid .right {\n text-align: right;\n}\n\n.data-grid th.sortable {\n position: relative;\n}\n\n.data-grid th.sortable:active::after {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n.data-grid th .sort-order-icon-container {\n position: absolute;\n top: 1px;\n right: 0;\n bottom: 1px;\n display: flex;\n align-items: center;\n}\n\n.data-grid th .sort-order-icon {\n margin-right: 4px;\n background-image: url(Images/toolbarButtonGlyphs.png);\n background-size: 352px 168px;\n opacity: 0.5;\n width: 8px;\n height: 7px;\n display: none;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.data-grid th .sort-order-icon {\n background-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.data-grid th.sort-ascending .sort-order-icon {\n display: block;\n background-position: -4px -111px;\n}\n\n.data-grid th.sort-descending .sort-order-icon {\n display: block;\n background-position: -20px -99px;\n}\n\n.data-grid th:hover {\n background-color: hsla(0, 0%, 90%, 1);\n}\n\n.data-grid button {\n line-height: 18px;\n color: inherit;\n}\n\n.data-grid td.disclosure::before {\n -webkit-user-select: none;\n -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);\n -webkit-mask-position: -4px -96px;\n -webkit-mask-size: 352px 168px;\n float: left;\n width: 8px;\n height: 12px;\n margin-right: 2px;\n content: \"a\";\n color: transparent;\n position: relative;\n top: 1px;\n background-color: rgb(110, 110, 110);\n}\n\n.data-grid tr:not(.parent) td.disclosure::before {\n background-color: transparent;\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.5) {\n.data-grid tr.parent td.disclosure::before {\n -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);\n}\n} /* media */\n\n.data-grid tr.expanded td.disclosure::before {\n -webkit-mask-position: -20px -96px;\n}\n\n.data-grid tr.selected {\n background-color: rgb(212, 212, 212);\n color: inherit;\n}\n\n.data-grid:focus tr.selected {\n background-color: rgb(56, 121, 217);\n color: white;\n}\n\n.data-grid:focus tr.selected a {\n color: white;\n}\n\n.data-grid:focus tr.parent.selected td.disclosure::before {\n background-color: white;\n -webkit-mask-position: -4px -96px;\n}\n\n.data-grid:focus tr.expanded.selected td.disclosure::before {\n background-color: white;\n -webkit-mask-position: -20px -96px;\n}\n\n.data-grid-resizer {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 5px;\n z-index: 500;\n}\n\n/*# sourceURL=ui_lazy/dataGrid.css */";Runtime.cachedResources["ui_lazy/filteredListWidget.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.filtered-list-widget {\n display: flex;\n flex-direction: column;\n flex: auto;\n}\n\n.filtered-list-widget-prompt-element {\n flex: 0 0 36px;\n border: 0;\n box-shadow: rgba(140, 140, 140, 0.2) 0 2px 2px;\n margin: 0;\n padding: 0 6px;\n z-index: 1;\n font-size: inherit;\n}\n\n.filtered-list-widget-input {\n white-space: pre;\n height: 18px;\n margin-top: 10px;\n overflow: hidden;\n}\n\n.filtered-list-widget > div.container {\n flex: auto;\n overflow-y: auto;\n background: #fbfbfb;\n}\n\n.filtered-list-widget-item {\n padding: 4px 6px;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n color: rgb(95, 95, 95);\n}\n\n.filtered-list-widget-item.selected {\n background-color: #f0f0f0;\n}\n\n.filtered-list-widget-item span.highlight {\n color: #222;\n font-weight: bold;\n}\n\n.filtered-list-widget-item .filtered-list-widget-title {\n flex: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.filtered-list-widget-item .filtered-list-widget-subtitle {\n flex: none;\n overflow: hidden;\n text-overflow: ellipsis;\n color: rgb(155, 155, 155);\n display: flex;\n}\n\n.filtered-list-widget-item .filtered-list-widget-subtitle .first-part {\n flex-shrink: 1000;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.filtered-list-widget-item.one-row {\n display: flex;\n}\n\n.filtered-list-widget-item.two-rows {\n border-bottom: 1px solid rgb(235, 235, 235);\n}\n\n.tag {\n color: white;\n padding: 1px 3px;\n margin-right: 5px;\n border-radius: 2px;\n line-height: 18px;\n}\n\n.filtered-list-widget-item .tag .highlight {\n color: white;\n}\n\n/*# sourceURL=ui_lazy/filteredListWidget.css */";Runtime.cachedResources["ui_lazy/flameChart.css"]=".flame-chart-main-pane {\n overflow: hidden;\n}\n\n.flame-chart-marker-highlight-element {\n position: absolute;\n top: 0;\n height: 20px;\n width: 4px;\n margin: 0 -2px;\n content: \"\";\n display: block;\n}\n\n.flame-chart-highlight-element {\n background-color: black;\n position: absolute;\n opacity: 0.2;\n pointer-events: none;\n}\n\n.flame-chart-selected-element {\n position: absolute;\n pointer-events: none;\n border-color: rgb(56, 121, 217);\n border-width: 1px;\n border-style: solid;\n background-color: rgba(56, 121, 217, 0.2);\n}\n\n.flame-chart-v-scroll {\n position: absolute;\n width: 14px;\n top: 0;\n right: 0;\n bottom: 0;\n overflow-x: hidden;\n z-index: 200;\n}\n\n:host-context(.platform-mac) .flame-chart-v-scroll {\n right: 2px;\n top: 3px;\n bottom: 3px;\n width: 15px;\n}\n\n/* force non-overlay scrollbars */\n:host-context(.platform-mac) ::-webkit-scrollbar {\n width: 8px;\n}\n\n:host-context(.platform-mac) ::-webkit-scrollbar-thumb {\n background-color: hsla(0, 0%, 56%, 0.6);\n border-radius: 50px;\n}\n\n:host-context(.platform-mac) .flame-chart-v-scroll:hover::-webkit-scrollbar-thumb {\n background-color: hsla(0, 0%, 25%, 0.6);\n}\n\n.flame-chart-selection-overlay {\n position: absolute;\n z-index: 100;\n background-color: rgba(56, 121, 217, 0.3);\n border-color: rgb(16, 81, 177);\n border-width: 0 1px;\n border-style: solid;\n pointer-events: none;\n top: 0;\n bottom: 0;\n text-align: center;\n}\n\n.flame-chart-selection-overlay .time-span {\n white-space: nowrap;\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\n.flame-chart-entry-info:not(:empty) {\n z-index: 200;\n position: absolute;\n background-color: white;\n pointer-events: none;\n padding: 2px;\n box-shadow: hsla(0, 0%, 0%, 0.4) 1px 1px 8px;\n}\n\n.flame-chart-entry-info table tr td:empty {\n padding: 0;\n}\n\n.flame-chart-entry-info table tr td:not(:empty) {\n padding: 0 5px;\n white-space: nowrap;\n}\n\n.flame-chart-entry-info table tr td:first-child {\n font-weight: bold;\n}\n\n.flame-chart-entry-info table tr td span {\n margin-right: 5px;\n}\n\n/*# sourceURL=ui_lazy/flameChart.css */";Runtime.cachedResources["ui_lazy/overviewGrid.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.overview-grid-window-selector {\n position: absolute;\n top: 0;\n bottom: 0;\n background-color: rgba(125, 173, 217, 0.5);\n z-index: 250;\n pointer-events: none;\n}\n\n.overview-grid-window-resizer {\n position: absolute;\n top: -1px;\n height: 20px;\n width: 6px;\n margin-left: -3px;\n background-color: rgb(153, 153, 153);\n border: 1px solid white;\n z-index: 500;\n}\n\n.overview-grid-cursor-area {\n position: absolute;\n left: 0;\n right: 0;\n top: 20px;\n bottom: 0;\n z-index: 500;\n cursor: text;\n}\n\n.overview-grid-cursor-position {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background-color: hsla(220, 95%, 50%, 0.7);\n z-index: 500;\n pointer-events: none;\n visibility: hidden;\n overflow: hidden;\n}\n\n/*# sourceURL=ui_lazy/overviewGrid.css */";Runtime.cachedResources["ui_lazy/pieChart.css"]="/*\n * Copyright (c) 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.root {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.pie-chart-foreground {\n position: absolute;\n width: 100%;\n height: 100%;\n z-index: 10;\n top: 0;\n display: flex;\n}\n\n.pie-chart-total {\n margin: auto;\n padding: 2px 5px;\n background-color: rgba(255, 255, 255, 0.6);\n}\n\n/*# sourceURL=ui_lazy/pieChart.css */";Runtime.cachedResources["ui_lazy/timelineGrid.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.resources-dividers {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n z-index: -100;\n bottom: 0;\n}\n\n.resources-event-dividers {\n position: absolute;\n left: 0;\n right: 0;\n height: 100%;\n top: 0;\n z-index: 300;\n pointer-events: none;\n}\n\n.resources-dividers-label-bar {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n height: 20px;\n z-index: 200;\n pointer-events: none;\n overflow: hidden;\n}\n\n.resources-divider {\n position: absolute;\n width: 1px;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.1);\n}\n\n.resources-event-divider {\n position: absolute;\n width: 2px;\n top: 0;\n bottom: 0;\n z-index: 300;\n}\n\n.resources-divider-label {\n position: absolute;\n top: 4px;\n right: 3px;\n font-size: 80%;\n white-space: nowrap;\n pointer-events: none;\n}\n\n.timeline-grid-header {\n height: 20px;\n pointer-events: none;\n}\n\n.timeline-curtain-left, .timeline-curtain-right {\n background-color: hsla(0, 0%, 80%, 0.5);\n position: absolute;\n top: 0;\n height: 100%;\n z-index: 300;\n pointer-events: none;\n border: 1px none hsla(0, 0%, 70%, 0.5);\n}\n\n.timeline-curtain-left {\n left: 0;\n border-right-style: solid;\n}\n\n.timeline-curtain-right {\n right: 0;\n border-left-style: solid;\n}\n\n/*# sourceURL=ui_lazy/timelineGrid.css */"; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| App.js | 11.86% | (14 / 118) | 0% | (0 / 56) | 4.17% | (1 / 24) | 11.97% | (14 / 117) | |
| EventEmitter.js | 9.38% | (3 / 32) | 0% | (0 / 14) | 0% | (0 / 8) | 9.38% | (3 / 32) | |
| Runtime.js | 6.4% | (8 / 125) | 0% | (0 / 34) | 0% | (0 / 27) | 6.5% | (8 / 123) | |
| WebsocketClient.js | 10.34% | (3 / 29) | 0% | (0 / 8) | 0% | (0 / 7) | 10.34% | (3 / 29) | |
| extern.js | 100% | (4 / 4) | 100% | (0 / 0) | 0% | (0 / 5) | 100% | (4 / 4) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 2 2 2 1 2 1 1 1 1 1 1 1 2 2 | var websocket;
var maxReconnectCount = 5;
var _deviceList = [];
function connect() {
websocket = new WebSocket('ws://' + location.host + '/debugProxy/list');
websocket.onmessage = function (event) {
var message = JSON.parse(event.data);
if (message.method == 'WxDebug.pushDeviceList') {
renderDeviceList(message.params);
}
else if (message.method == 'WxDebug.setEntry') {
message.params.forEach(function (bundleUrl, i) {
var urls = bundleUrl.split('_wx_tpl='), url, name;
if (urls.length >= 2) {
url = decodeURIComponent(urls[1]);
name = url.match(/\/([^\/?#]+)\.(js|we)(?:$|#|\?)/);
name = name ? name[1] : url;
}
else if (urls.length == 1) {
url = urls[0];
name = url.match(/\/([^\/?#]+)\.js(?:$|#|\?)/);
name = name ? name[1] : url;
}
var ctn = document.createElement('div');
ctn.className = 'qrcode-section';
ctn.innerHTML = `<div id="entryQrcode${i}" class="qrcode"></div>
<div class="qrcode-desc">
<a target="_blank" href="${bundleUrl}">${name}</a>
</div>`;
document.getElementById('qrcode_container').appendChild(ctn);
createQRCode('entryQrcode' + i, bundleUrl);
})
}
else if (message.method == 'WxDebug.refreshPage') {
_deviceList.forEach(function (device) {
device.inspectorWindow && device.inspectorWindow.location.reload();
device.debuggerWindow && device.debuggerWindow.location.reload();
})
}
};
websocket.onclose = function () {
renderDeviceList([]);
if (maxReconnectCount-- > 0) {
setTimeout(connect, 1000);
}
else {
alert('Websocket error!Maybe the debug server crashed!')
}
}
}
function diff(deviceList) {
var next;
for (var i = 0; i < _deviceList.length; i++) {
next = false;
for (var j = 0; j < deviceList.length; j++) {
if (deviceList[j].deviceId == _deviceList[i].deviceId) {
next = true;
break;
}
}
if (next)continue;
//_deviceList[i].inspectorWindow && _deviceList[i].inspectorWindow.close();
//_deviceList[i].debuggerWindow && _deviceList[i].debuggerWindow.close();
}
}
function renderDeviceList(deviceList) {
diff(deviceList);
_deviceList = deviceList;
if (deviceList.length > 0) {
document.getElementById('help_ctn').style.display = 'block';
}
else {
document.getElementById('help_ctn').style.display = 'none';
}
function networkMonitorDetect(device){
return device.devtoolVersion>='0.8.3'&&device.platform==='iOS'||device.platform.toLowerCase()==='android'&&device.devtoolVersion>='0.10.0'
}
var html = deviceList.map(function (device) {
return `
<div class="device-wrap" id="device_${device.deviceId}">
<div class="line"><span>AppName</span><b>${device.name.replace(/\s*:\s*(.*)$/,'<br/>[$1]')}</b></div>
<div class="line"><span>DeviceModel</span><b>${device.model}</b></div>
<div class="line"><span>platform</span><b>${device.platform}</b></div>
<div class="line"><span>WeexVersion</span><b>${device.weexVersion}</b></div>
<div class="line mr-bottom-10"><span>LogLevel</span><b><select class="selector log-level" x-data-device="${device.deviceId}" x-data-value="${device.logLevel||'log'}"><option value="debug">debug</option><option value="log">log</option><option value="info">info</option><option value="warn">warn</option><option value="error">error</option></select></b></div>
<div class="line mr-bottom-10"><span>ElementMode</span><b><select class="selector element-mode"" x-data-device="${device.deviceId}" x-data-value="${device.elementMode||'native'}"><option value="native">native</option><option value="vdom">vdom</option></select></b></div>
<div class="line mr-top-10"><span>RemoteDebug</span><b>${switchComponent(device,'remoteDebug')}</b></div>
${networkMonitorDetect(device)?`<div class="line mr-top-10"><span>NetworkMonitor</span><b>${switchComponent(device,'network')}</b></div>`:''}
<div class="btn-ctn">
<a class="btn" onClick="openDebugger('${device.deviceId}')" target="debugger${device.debuggerSessionId}" >Debugger</a>
<a class="btn" onClick="openInspector('${device.deviceId}')" target="inspector${device.inspectorSessionId}">Inspector</a>
</div>
<div class="help">
Inspector: click this button to open a page to inspect "Elements"(native element), "Console", "Sources", "Network"; Debugger: click here to open a page to debug JS files (make breakpoints, watch variables, callstack etc.)
</div>
</div>
`;
});
if(html.length>0) {
document.getElementById('container').innerHTML = html.join('\n');
var logLevelList = document.querySelectorAll('.log-level');
logLevelList.forEach(function(loglevelSelector){
loglevelSelector.value=loglevelSelector.getAttribute('x-data-value');
loglevelSelector.onchange=function(evt){
var message={
method:'WxDebug.setLogLevel',
params:{
deviceId:evt.target.getAttribute('x-data-device'),
data:evt.target.value
}
}
websocket.send(JSON.stringify(message));
}
})
var inspectModeList = document.querySelectorAll('.element-mode');
inspectModeList.forEach(function(inspectModeSelector){
inspectModeSelector.value=inspectModeSelector.getAttribute('x-data-value');
inspectModeSelector.onchange=function(evt){
var deviceId=evt.target.getAttribute('x-data-device');
var message={
method:'WxDebug.setElementMode',
params:{
deviceId:deviceId,
data:evt.target.value
}
}
websocket.send(JSON.stringify(message));
var device=findDevice(deviceId);
if(device){
device.inspectorWindow&&device.inspectorWindow.location.reload();
}
}
})
document.querySelectorAll('.switch-remoteDebug').forEach(function(swt){
swt.onchange=function(evt){
var el=evt.target;
var deviceId=el.getAttribute('x-data');
websocket.send(JSON.stringify({method:'WxDebug.setRemoteDebug',params:{
deviceId:deviceId,
data:el.checked
}}));
if(!el.checked){
var device=findDevice(deviceId);
if(device&&device.debuggerWindow) {
device.debuggerWindow.close();
}
}
else{
openDebugger(deviceId);
}
console.log(el.getAttribute('x-data'),evt.target.checked);
}
})
document.querySelectorAll('.switch-network').forEach(function(swt){
swt.onchange=function(evt){
var el=evt.target;
var deviceId=el.getAttribute('x-data');
websocket.send(JSON.stringify({method:'WxDebug.network',params:{
deviceId:deviceId,
enable:el.checked
}}));
}
})
}
else{
document.getElementById('container').innerHTML ='';
}
}
function findDevice(deviceId) {
return _deviceList.filter(function (device) {
return device.deviceId == deviceId;
})[0]
}
function openDebugger(deviceId) {
var device = findDevice(deviceId);
if (device.debuggerWindow) {
device.debuggerWindow.close();
}
document.getElementById('device_'+deviceId).querySelector('.switch-checkbox').checked=true;
device.debuggerWindow = window.open(`/debugger.html?sessionId=${device.debuggerSessionId}#new`, `debugger${device.debuggerSessionId}`);
var $WeexInspectorProxy=`ws://${location.host + '/debugProxy/inspector/' + device.inspectorSessionId}`;
device.debuggerWindow.$WeexInspectorProxy=$WeexInspectorProxy;
device.debuggerWindow.device=device;
device.debuggerWindow.sessionStorage.setItem('$WeexInspectorProxy',$WeexInspectorProxy);
device.debuggerWindow.sessionStorage.setItem('device',device);
device.debuggerWindow.sessionStorage.setItem('debugee', 'Debugee App: ' + device.name);
device.debuggerWindow.onload = function () {
device.debuggerWindow.document.body.firstElementChild.innerHTML = 'Debugee App: ' + device.name;
}
}
function openInspector(deviceId) {
var device = findDevice(deviceId);
device.inspectorWindow = window.open(`/inspector/inspector.html?ws=${location.host + '/debugProxy/inspector/' + device.inspectorSessionId}&remoteFrontend=1`, `inspector${device.inspectorSessionId}`);
}
function createQRCode(id, content, width, height) {
var el = document.getElementById(id);
el.innerHTML = '';
new QRCode(el, {
text: content,
width: width || 150,
height: height || 150,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.L
});
el.title = '';
}
var switchComponent=function(device,label){
return `<div class="switch switch-${label}">
<input type="checkbox" id="${label+'_switch_'+device.deviceId}" x-data="${device.deviceId}" ${device[label]?'checked':''} name="${label+'_switch'}" class="switch-checkbox" >
<label class="switch-label" for="${label+'_switch_'+device.deviceId}">
<div class="switch-inner">
<div class="switch-active">ON</div>
<div class="switch-inactive">OFF</div>
</div>
<div class="switch-switch"></div>
</label>
</div>`;
}
connect();
createQRCode('switchQrcode', `http:\/\/${location.host}/devtool_fake.html?_wx_devtool=ws:\/\/${location.host}/debugProxy/native`);
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 1 1 1 | /** * Created by godsong on 16/6/29. */ function EventEmitter() { this._handlers = {}; } EventEmitter.prototype = { constructor: EventEmitter, off: function (method, handler) { if (handler) { for (var i = 0; i < this._handlers[method].length; i++) { if (this._handlers[method][i] === handler) { this._handlers[method].splice(i, 1); i--; } } } else { this._handlers[method] = []; } }, once: function (method, handler) { var self = this; var fired = false; function g() { self.off(method, g); if (!fired) { fired = true; handler.apply(self, Array.prototype.slice.call(arguments)); } } this.on(method, g); }, on: function (method, handler) { if (this._handlers[method]) { this._handlers[method].push(handler); } else { this._handlers[method] = [handler]; } }, _emit: function (method, args, context) { var handlers = this._handlers[method]; if (handlers && handlers.length > 0) { handlers.forEach(function (handler) { handler.apply(context, args) }); return true; } else { return false; } }, emit: function (method) { var context = {}; var args = Array.prototype.slice.call(arguments, 1); if (!this._emit(method, args, context)) { this._emit('*', args, context) } this._emit('$finally', args, context); return context; } }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | 2 1 1 1 1 1 1 1 | /**
* Created by godsong on 16/6/14.
*/
"use strict";
self.$$frameworkFlag={};
var sessionId;
var injectedGlobals = [
'Promise',
// W3C
'window',
'weex',
'service',
'Rax',
'services',
'global',
'screen',
'document',
'navigator',
'location',
'fetch',
'Headers',
'Response',
'Request',
'URL',
'URLSearchParams',
'setTimeout',
'clearTimeout',
'setInterval',
'clearInterval',
'requestAnimationFrame',
'cancelAnimationFrame',
'alert',
// ModuleJS
'define',
'require',
// Weex
'bootstrap',
'register',
'render',
'__d',
'__r',
'__DEV__',
'__weex_define__',
'__weex_require__',
'__weex_viewmodel__',
'__weex_document__',
'__weex_bootstrap__',
'__weex_options__',
'__weex_data__',
'__weex_downgrade__',
'__weex_require_module__',
'Vue'
];
let cachedSetTimeout=this.setTimeout;
Object.defineProperty(this,'setTimeout',{
get:function(){
return cachedSetTimeout;
},
set:function(){
}
});
Object.defineProperty(navigator,'product',{get:function(){return 'weex'}});
Object.defineProperty(navigator,'appCodeName',{get:function(){return 'weex'}});
function EventEmitter() {
this._handlers = {};
}
importScripts('/lib/EventEmitter.js');
function createWeexBundleEntry(sourceUrl){
var code='';
if(self.$$frameworkFlag[sourceUrl]||self.$$frameworkFlag['@']){
code+=(self.$$frameworkFlag[sourceUrl]||self.$$frameworkFlag['@'])+'\n';
}
code+='"use strict";\n__weex_bundle_entry__(';
injectedGlobals.forEach(function(g,i){
if(false&&g==='navigator'){
code+='typeof '+g+'==="undefined"||'+g+'===self.'+g+'?undefined:'+g;
}
else{
code+='typeof '+g+'==="undefined"?undefined:'+g;
}
if(i<injectedGlobals.length-1){
code+=',';
}
});
code+=');';
return code;
}
var origConsole=self.console;
var clearConsole=self.console.clear.bind(self.console);
self.__WEEX_DEVTOOL__=true;
var eventEmitter = new EventEmitter();
onmessage = function (message) {
eventEmitter.emit(message.data.method, message.data)
};
self.callNativeModule=function(){
var message={
method:'WxDebug.syncCall',
params:{
method:'callNativeModule',
args:Array.prototype.slice.call(arguments)
},
sessionId:sessionId
}
var result= syncRequest(message);
if(result.error){
throw new Error(result.error);
}
else return result.ret;
}
self.callNativeComponent=function(){
var message={
method:'WxDebug.syncCall',
params:{
method:'callNativeComponent',
args:Array.prototype.slice.call(arguments)
},
sessionId:sessionId
}
var result= syncRequest(message);
if(result.error){
throw new Error(result.error);
}
else return result.ret;
};
self.callNative = function (instance, tasks, callback) {
for(var i=0;i<tasks.length;i++){
var task=tasks[i];
if(task.method=='addElement'){
for(var key in task.args[1].style){
if(Number.isNaN(task.args[1].style[key])){
console.error('invalid value [NaN] for style ['+key+']',task);
//task.args[1].style[key]=0;
}
}
}
}
var payload={
method: 'WxDebug.callNative',
params: {
instance: instance,
tasks: tasks,
callback: callback
}
};
postData(payload);
};
function postData(payload){
try {
postMessage(payload);
}catch(e){
console.warn('callNative with some non-json data:',payload);
payload=JSON.parse(JSON.stringify(payload));
postMessage(payload);
}
}
self.callAddElement=function(instance, ref, dom, index, callback){
var payload={
method: 'WxDebug.callAddElement',
params: {
instance: instance,
ref: ref,
dom:dom,
index:index,
callback: callback
}
};
postData(payload);
};
self.__logger = function (level, msg) {
console[level]('native:', msg);
};
self.nativeLog = function (text) {
console.log(text);
};
var _rewriteLog=function (){
var LEVELS = ['error', 'warn', 'info', 'log', 'debug'];
var backupConsole={
error:origConsole.error,
warn:origConsole.warn,
info:origConsole.info,
log:origConsole.log,
debug:origConsole.debug
};
function resetConsole(){
self.console.error=backupConsole.error;
self.console.warn=backupConsole.warn;
self.console.info=backupConsole.info;
self.console.log=backupConsole.log;
self.console.debug=backupConsole.debug;
self.console.time=origConsole.time;
self.console.timeEnd=origConsole.timeEnd;
}
function noop(){}
return function(logLevel){
resetConsole();
LEVELS.slice(LEVELS.indexOf(logLevel)+1).forEach(function(level){
self.console[level]=noop;
})
}
}();
eventEmitter.on('WxDebug.initJSRuntime', function (message) {
sessionId=message.sessionId;
for (var key in message.params.env) {
if(message.params.env.hasOwnProperty(key)) {
self[key] = message.params.env[key];
}
}
importScripts(message.params.url);
_rewriteLog(message.params.env.WXEnvironment.logLevel);
});
eventEmitter.on('WxDebug.changeLogLevel', function (message) {
self.WXEnvironment.logLevel = message.params;
});
eventEmitter.on('Console.messageAdded', function (message) {
console.error('[Native Error]', message.params.message.text);
});
var instanceMap = {};
eventEmitter.on('WxDebug.importScript',function(data){
console.log(data);
if(data.params.sourceUrl) {
importScripts(data.params.sourceUrl);
}else{
new Function('',data.params.source)();
}
})
eventEmitter.on('WxDebug.callJS', function (data) {
var method = data.params.method;
if (method === 'createInstance') {
var url = data.params.sourceUrl;
postMessage({
method: 'WxRuntime.clearLog',
});
importScripts(url);
self.createInstance(data.params.args[0], createWeexBundleEntry(url), data.params.args[2], data.params.args[3]);
instanceMap[data.params.args[0]] = true;
}
else if (method === 'destroyInstance') {
if (instanceMap[data.params.args[0]]) {
self.destroyInstance(data.params.args[0]);
delete instanceMap[data.params.args[0]];
}
else {
console.warn('invalid destroyInstance[' + data.params.args[0] + '] because runtime has been refreshed(It does not impact your code. )');
}
}
else if(self[data.params.method]){
self[data.params.method].apply(null, data.params.args);
}
else{
console.warn('callJS['+data.params.method+'] error: jsframework has no such api');
}
});
function dump(id) {
postMessage({
method: 'WxRuntime.dom',
params: getRoot(id)
})
}
function syncRequest(data){
var request = new XMLHttpRequest();
request.open('POST', '/syncApi', false); // `false` makes the request synchronous
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(data));
if (request.status === 200) {
return JSON.parse(request.responseText);
}
else{
throw Error('sync request failed:['+request.status+']'+request.responseText);
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 1 2 2 | /** * Created by godsong on 16/6/14. */ function WebsocketClient(url) { this.connect(url); } WebsocketClient.prototype = { constructor: WebsocketClient, connect: function (url) { var This = this; This.isSocketReady = false; This._sended = []; This._received = []; if (This.ws) { This.ws.onopen = null; This.ws.onmessage = null; This.ws.onclose = null; if (This.ws.readyState == WebSocket.OPEN) { This.ws.close(); } } var ws = new WebSocket(url); This.ws = ws; ws.onopen = function () { This.isSocketReady = true; This.emit('socketOpened'); }; ws.onmessage = function (e) { var message = JSON.parse(e.data); if (message.method) { This.emit(message.method, message); } }; ws.onclose = function () { This.isSocketReady = false; /* setTimeout(function(){ This.connect(url); },800);*/ }; }, send: function (data) { if (this.isSocketReady) { this.ws.send(JSON.stringify(data)); } else { this.once('socketOpened', function () { this.ws.send(JSON.stringify(data)) }.bind(this)); } } }; WebsocketClient.prototype.__proto__ = new EventEmitter(); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 1 1 1 | /**
* Created by godsong on 16/8/11.
*/
var a=require('events').EventEmitter
//for Ide
var postMessage=function(){};
var self={
createInstance:function(){
},
callNative:function(){},
destroyInstance:function(){}
};
var getRoot=function(){};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| DebugServer.js | 81.82% | (18 / 22) | 0% | (0 / 4) | 50% | (1 / 2) | 81.82% | (18 / 22) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var Path = require('path');
var Koa = require('koa');
var Serve = require('koa-serve');
var ServeStatic = require('koa-serve-static');
var Websockify = require('koa-websocket');
var Config = require('./components/Config');
var bodyParser = require('koa-bodyparser');
var WsRouter = require('./router/Websocket');
var HttpRouter = require('./router/Http');
var app = Websockify(Koa());
var rootPath = Path.join(__dirname, '../frontend/');
/*
===================================
WebSocket Router
===================================
*/
exports.start = function (port, cb) {
app.use(bodyParser());
app.ws.use(WsRouter.routes());
app.on('error', function (err, ctx) {
if (Config.verbose) {
if (err.status == 404) {
console.log('404');
} else {
console.error(err);
}
}
});
/*
===================================
Http Router
===================================
*/
app.use(HttpRouter.routes());
app.use(ServeStatic(rootPath));
app.listen(port, cb);
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Builder.js | 21.67% | (13 / 60) | 0% | (0 / 28) | 0% | (0 / 10) | 21.67% | (13 / 60) | |
| Channel.js | 31.34% | (21 / 67) | 9.38% | (3 / 32) | 16.67% | (2 / 12) | 30.3% | (20 / 66) | |
| Config.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| DebugTarget.js | 75% | (12 / 16) | 75% | (3 / 4) | 40% | (2 / 5) | 73.33% | (11 / 15) | |
| DeviceManager.js | 35.53% | (27 / 76) | 22.22% | (4 / 18) | 17.39% | (4 / 23) | 34.67% | (26 / 75) | |
| Logger.js | 22.5% | (9 / 40) | 0% | (0 / 21) | 0% | (0 / 7) | 23.08% | (9 / 39) | |
| MemoryFile.js | 34.62% | (18 / 52) | 21.43% | (3 / 14) | 25% | (2 / 8) | 33.33% | (17 / 51) | |
| MessageBus.js | 82.61% | (19 / 23) | 66.67% | (4 / 6) | 50% | (3 / 6) | 81.82% | (18 / 22) | |
| P2PSession.js | 19.23% | (25 / 130) | 5.45% | (3 / 55) | 12.5% | (3 / 24) | 18.6% | (24 / 129) | |
| Port.js | 66.67% | (2 / 3) | 100% | (0 / 0) | 100% | (0 / 0) | 66.67% | (2 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/7/6.
*/
var Path = require('path');
var Webpack = require('webpack');
var Loader = require('weex-loader');
var Logger = require('./Logger');
var Transformer = require('weex-transformer');
var Fs = require('fs');
var Config = require('./Config');
var Mkdirp = require('mkdirp');
var ext2Name = {
'.we': 'Weex',
'.vue': 'Vue'
};
function loadModulePath(moduleName, extra) {
try {
var path = require.resolve(Path.join(moduleName, extra || ''));
return path.slice(0, path.indexOf(moduleName) + moduleName.length);
} catch (e) {
return moduleName;
}
}
exports.loader = function (source) {
var targetPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return new Promise(function (resolve, reject) {
var ext = Path.extname(source);
var basename = Path.basename(source, ext);
var targetDir = Path.join(__dirname, '../../frontend/', Config.bundleDir, targetPath);
var weexLoaderRoot = Path.join(__dirname, "../../node_modules");
if (!Fs.existsSync(Path.join(weexLoaderRoot, 'weex-loader'))) {
weexLoaderRoot = Path.join(__dirname, "../../..");
}
var bannerPlugin = new Webpack.BannerPlugin('// { "framework": "' + ext2Name[ext] + '" }\n', { raw: true });
var webpackConfig = {
entry: source + '?entry=true',
output: {
path: targetDir,
filename: basename + '.js'
},
devtool: Config.min ? 'source-map' : '#inline-source-map',
module: {
loaders: [{
test: /\.we(\?[^?]+)?$/,
loader: 'weex'
}, {
test: /\.vue(\?[^?]+)?$/,
loader: 'weex'
}]
},
resolve: {
alias: {
'babel-runtime': loadModulePath('babel-runtime', 'core-js'),
'babel-polyfill': loadModulePath('babel-polyfill')
}
},
resolveLoader: {
root: weexLoaderRoot
},
plugins: [bannerPlugin]
};
if (Config.min) {
webpackConfig.plugins.push(new Webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}));
}
Webpack(webpackConfig, function (err, stats) {
if (err) {
return reject(err);
}
var jsonStats = stats.toJson();
if (jsonStats.errors.length > 0) {
Logger.error('[webpack errors]\n', jsonStats.errors.join('\n'));
return reject('');
}
if (jsonStats.warnings.length > 0) {
Logger.warn('[webpack warnings]', jsonStats.warnings.join('\n'));
}
resolve(targetDir + '/' + basename + '.js');
});
});
};
exports.transformer = function (source) {
var targetPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return new Promise(function (resolve, reject) {
Fs.readFile(source, function (err, fileContent) {
if (err) {
console.error(err);
return reject(err);
}
var output = Transformer.transform(Path.basename(source, '.we'), fileContent.toString());
var targetDir = Path.join(__dirname, '../../frontend/', Config.bundleDir, targetPath, Path.basename(source, '.we') + '.js');
Mkdirp.sync(Path.dirname(targetDir));
Fs.writeFileSync(targetDir, output.result);
resolve(targetDir);
});
});
};
exports.copy = function (source) {
var targetPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return new Promise(function (resolve, reject) {
var targetDir = Path.join(__dirname, '../../frontend/', Config.bundleDir, targetPath, Path.basename(source));
Mkdirp.sync(Path.dirname(targetDir));
var input = Fs.createReadStream(source);
var output = Fs.createWriteStream(targetDir);
input.pipe(output, {
end: false
});
input.on('end', function () {
output.end();
resolve(targetDir);
});
});
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var TYPE_PREFIX = '$CHANNEL_TYPE_';
var _uuid = 0;
var Emitter = require('events').EventEmitter;
var Channel = function (_Emitter) {
(0, _inherits3.default)(Channel, _Emitter);
function Channel() {
(0, _classCallCheck3.default)(this, Channel);
var _this = (0, _possibleConstructorReturn3.default)(this, Object.getPrototypeOf(Channel).call(this));
_this.sockets = {};
_this.indexMap = [];
return _this;
}
(0, _createClass3.default)(Channel, [{
key: 'has',
value: function has(socket) {
return !!(this.sockets[this.indexMap[0]] && this.sockets[this.indexMap[0]].socket === socket || this.sockets[this.indexMap[1]] && this.sockets[this.indexMap[1]].socket === socket);
}
//实现的效果就是一个channel里只能有两个socket
//如果手动指定socket 的type 则是可以支持替换的,如果不手动指定type而是自动分配的话,那加满就不能再加入了
}, {
key: 'join',
value: function join(socket, type) {
if (!this.has(socket)) {
var index = type || TYPE_PREFIX + _uuid++;
var existed = this.sockets[index];
if (existed) {
this.sockets[index] = { socket: socket, cache: [] };
this.emit('socket replaced', existed, socket);
} else {
if (this.indexMap.length < 2) {
this.sockets[index] = { socket: socket, cache: [] };
this.indexMap.push(index);
this.emit('socket joined', socket);
this._flushCache();
} else {
console.error('[Channel] Join Failed:Try to join a newer typical socket[' + type + '],but this channel is full.');
}
}
} else {
console.warn('[Channel] Join Ignored:Try to join a existed socket');
}
}
}, {
key: 'clear',
value: function clear() {
this.sockets = [];
this.indexMap = [];
}
}, {
key: '_findIndex',
value: function _findIndex(socket) {
if (this.sockets[this.indexMap[0]].socket === socket) {
return 0;
} else if (this.sockets[this.indexMap[1]].socket === socket) {
return 1;
} else {
return -1;
}
}
}, {
key: 'send',
value: function send(socket, msg, disableCache) {
this._send(this._findIndex(socket), msg, disableCache);
}
}, {
key: '_send',
value: function _send(index, msg, disableCache) {
var theOther = this.sockets[this.indexMap[(index + 1) % 2]];
if (theOther) {
theOther.socket.send(msg);
} else if (disableCache) {
this.sockets[this.indexMap[index]].cache.push(msg);
}
}
}, {
key: 'clearCache',
value: function clearCache(socket) {
var index = this._findIndex(socket);
this.sockets[this.indexMap[index]].cache = [];
}
}, {
key: '_flushCache',
value: function _flushCache() {
if (this.indexMap.length == 2) {
for (var i = 0; i < 2; i++) {
if (this.sockets[this.indexMap[i]] && this.sockets[this.indexMap[i]].cache.length > 0) {
var cache = this.sockets[this.indexMap[i]].cache;
this.sockets[this.indexMap[i]].cache = [];
for (var j = 0; j < cache.length; j++) {
this._send(i, cache[j]);
}
}
}
}
}
}, {
key: 'leave',
value: function leave(socket) {
var index = this._findIndex(socket);
if (index >= 0) {
delete this.sockets[this.indexMap[index]];
this.indexMap = [this.indexMap[(index + 1) % 2]];
} else {
console.warn('[Channel] Remove Ignored: this socket not found in the chanel');
}
}
}]);
return Channel;
}(Emitter);
Channel.Master = 0;
Channel.Slaver = 1;
module.exports = Channel;
|
| 1 2 3 4 5 6 7 8 9 | 1 | 'use strict';
/**
* Created by godsong on 16/7/4.
*/
module.exports = {
bundleDir: 'weex'
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 1 1 1 1 2 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Path = require('path');
var DebugTarget = function () {
function DebugTarget(targetName) {
(0, _classCallCheck3.default)(this, DebugTarget);
this.targetName = target;
}
(0, _createClass3.default)(DebugTarget, [{
key: 'resolve',
value: function resolve() {
var filePath = Path.resolve(this.targetName);
var ext = Path.extname(filePath);
}
}]);
return DebugTarget;
}();
var TargetResolver = {
registerResolver: function registerResolver() {}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/6/26.
*/
var P2PSession = require('./P2PSession');
var Emitter = require('events').EventEmitter;
var Logger = require('./Logger');
var Device = function () {
function Device(deviceInfo, websocket) {
(0, _classCallCheck3.default)(this, Device);
this.deviceId = deviceInfo.deviceId + '|' + deviceInfo.name;
this.inspectorSession = P2PSession.newSession(websocket);
this.debuggerSession = P2PSession.newSession(websocket);
var index = websocket._info.split(' ')[0];
websocket._info = 'native[' + this.inspectorSession.id + '+' + this.debuggerSession.id + ':0x' + (index % 2 == 1 ? '0' + index : index) + ']';
this.deviceInfo = Object.assign(deviceInfo, {
deviceId: this.deviceId,
remoteDebug: deviceInfo.remoteDebug || false,
inspectorSessionId: this.inspectorSession.id,
debuggerSessionId: this.debuggerSession.id
});
websocket._deviceId = this.deviceId;
this.websocket = websocket;
}
(0, _createClass3.default)(Device, [{
key: 'send',
value: function send(data) {
if (this.websocket.readyState == 1) {
this.websocket.send(JSON.stringify(data));
} else {
console.warn('warn:device websocket not opened,send ignored!');
}
}
}, {
key: 'destroy',
value: function destroy() {
this.destroyed = true;
this.inspectorSession.destroy();
this.debuggerSession.destroy();
this.inspectorSession = null;
this.debuggerSession = null;
}
}, {
key: 'reconnect',
value: function reconnect(websocket) {
websocket._deviceId = this.deviceId;
var index = websocket._info.split(' ')[0];
websocket._info = 'native[' + this.inspectorSession.id + '+' + this.debuggerSession.id + ':0x' + (index % 2 == 1 ? '0' + index : index) + '] reconnected';
this.websocket = websocket;
this.inspectorSession.join(websocket);
this.debuggerSession.join(websocket);
}
}]);
return Device;
}();
var DeviceManager = function (_Emitter) {
(0, _inherits3.default)(DeviceManager, _Emitter);
function DeviceManager() {
(0, _classCallCheck3.default)(this, DeviceManager);
var _this = (0, _possibleConstructorReturn3.default)(this, (DeviceManager.__proto__ || Object.getPrototypeOf(DeviceManager)).call(this));
_this.deviceList = [];
return _this;
}
(0, _createClass3.default)(DeviceManager, [{
key: 'removeDeviceDelayed',
value: function removeDeviceDelayed(device, timeout) {
var _this2 = this;
clearTimeout(device.removeTimer);
device.removeTimer = setTimeout(function () {
_this2.removeDevice(device);
}, timeout);
}
}, {
key: 'removeDevice',
value: function removeDevice(device) {
device.destroy();
this.deviceList = this.deviceList.filter(function (dvc) {
return dvc !== device;
});
this.emit('update', this.getDeviceListInfo());
}
}, {
key: 'registerDevice',
value: function registerDevice(deviceInfo, websocket) {
var existDevice = this.deviceList.filter(function (dvc) {
return dvc.deviceId == deviceInfo.deviceId + '|' + deviceInfo.name;
})[0];
if (existDevice) {
clearTimeout(existDevice.removeTimer);
existDevice.reconnect(websocket);
return existDevice;
} else {
var device = new Device(deviceInfo, websocket);
this.deviceList.push(device);
this.emit('update', this.getDeviceListInfo());
}
}
}, {
key: 'getDeviceBySessionId',
value: function getDeviceBySessionId(sessionId) {
return this.deviceList.filter(function (dvc) {
return dvc.deviceInfo.inspectorSessionId === sessionId || dvc.deviceInfo.debuggerSessionId === sessionId;
})[0];
}
}, {
key: 'getDeviceById',
value: function getDeviceById(deviceId) {
return this.deviceList.filter(function (dvc) {
return dvc.deviceId === deviceId;
})[0];
}
}, {
key: 'getDevice',
value: function getDevice(websocket) {
return this.deviceList.filter(function (dvc) {
return dvc.deviceId === websocket._deviceId;
})[0];
}
}, {
key: 'getDeviceList',
value: function getDeviceList() {
return this.deviceList;
}
}, {
key: 'getDeviceListInfo',
value: function getDeviceListInfo() {
return this.deviceList.map(function (device) {
return device.deviceInfo;
});
}
}]);
return DeviceManager;
}(Emitter);
module.exports = new DeviceManager();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 1 1 1 1 1 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/7/4.
*/
var Config = require('./Config');
var LogStyle = require('../../common/LogStyle');
var traceLevel = {
'debug': true,
'error': true
};
function _log(level, args) {
if (Config.verbose || level == 'error' || level == 'warn') {
args.unshift(LogStyle.LEVEL_COLOR[level]);
args.push(LogStyle.LEVEL_COLOR['#end']);
if (traceLevel[level]) {
var e = new Error();
var stack = e.stack.split('\n')[3].split('(');
args.push('\n' + LogStyle.LEVEL_COLOR['#underline'] + '@(' + (stack[1] || stack[0]) + LogStyle.LEVEL_COLOR['#end']);
}
(console[level] || console.log).apply(console, args);
}
}
exports.log = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_log('log', args);
};
exports.error = function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_log('error', args);
};
exports.debug = function () {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
_log('debug', args);
};
exports.warn = function () {
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
_log('warn', args);
};
exports.printMessage = function (message, prefix) {
if (message.method == 'WxDebug.callJS') {
exports.log('[' + prefix + '] callJS:', message.params.method);
} else if (message.method == 'WxDebug.callNative') {
exports.log('[' + prefix + '] callNative:(' + message.params.instance, message.params.tasks.map(function (task) {
return task.module + '.' + task.method;
}), ')');
} else if (message.method == 'WxDebug.registerDevice') {
exports.log('[' + prefix + ']', message);
} else {
if (message.method) {
if (message.method != 'Page.screencastFrame') exports.log('[' + prefix + ']', message.method);
} else {
exports.log('[' + prefix + ']', message);
}
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/6/30.
*/
var Crypto = require('crypto');
var Config = require('./Config');
var Url = require('url');
var Qs = require('querystring');
var _memoryFileMap = {};
var MemoryFile = function () {
(0, _createClass3.default)(MemoryFile, null, [{
key: 'get',
value: function get(name) {
return _memoryFileMap[name];
}
}, {
key: 'dump',
value: function dump() {
return Object.keys(_memoryFileMap);
}
}]);
function MemoryFile(fileName, content) {
(0, _classCallCheck3.default)(this, MemoryFile);
//fixme ugly! your_current_ip playground default bundle url
var rHttpHeader = /^(https?|taobao|qap):\/\/(?!.*your_current_ip)/i;
if (rHttpHeader.test(fileName)) {
var query = Qs.parse(Url.parse(fileName).query);
if (query['_wx_tpl']) {
this.url = normalize(query['_wx_tpl']);
this.name = this.url.replace(rHttpHeader, '');
} else {
this.url = normalize(fileName);
this.name = this.url.replace(rHttpHeader, '');
this.name = this.name.split('#')[0];
}
} else this.name = fileName;
var md5 = Crypto.createHash('md5');
md5.update(content);
var md5Str = md5.digest('hex');
var key = this.name.split('?')[0] + '|' + md5Str;
if (_memoryFileMap[this.name]) {
_memoryFileMap[this.name].content = content;
return _memoryFileMap[this.name];
} else if (_memoryFileMap[key]) {
_memoryFileMap[key].content = content;
return _memoryFileMap[key];
} else this.content = content;
this.md5 = md5Str;
_memoryFileMap[this.name] = this;
_memoryFileMap[key] = this;
}
(0, _createClass3.default)(MemoryFile, [{
key: 'getContent',
value: function getContent() {
return this.content;
}
}, {
key: 'getUrl',
value: function getUrl() {
return '/source/' + this.name;
}
}]);
return MemoryFile;
}();
module.exports = MemoryFile;
function normalize(url) {
var urlObj = Url.parse(url);
if (urlObj.query) {
urlObj.query = Qs.stringify(Qs.parse(urlObj.query));
urlObj.search = '?' + urlObj.query;
}
return urlObj.format();
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/7/7.
*/
var EventEmitter = require('events').EventEmitter;
var MessageBus = function (_EventEmitter) {
(0, _inherits3.default)(MessageBus, _EventEmitter);
function MessageBus() {
(0, _classCallCheck3.default)(this, MessageBus);
return (0, _possibleConstructorReturn3.default)(this, (MessageBus.__proto__ || Object.getPrototypeOf(MessageBus)).call(this));
}
(0, _createClass3.default)(MessageBus, [{
key: 'waitFor',
value: function waitFor(method) {
var _this2 = this;
return new Promise(function (resolve, reject) {
_this2.once(method, function (data) {
resolve(data);
});
});
}
}]);
return MessageBus;
}(EventEmitter);
module.exports = new MessageBus();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/6/24.
*/
var Emitter = require('events').EventEmitter;
var Uuid = require('../util/Uuid');
var Logger = require('./Logger');
var Peer = function (_Emitter) {
(0, _inherits3.default)(Peer, _Emitter);
function Peer(websocket) {
(0, _classCallCheck3.default)(this, Peer);
var _this = (0, _possibleConstructorReturn3.default)(this, (Peer.__proto__ || Object.getPrototypeOf(Peer)).call(this));
_this.messageBuffer = [];
_this.websocket = websocket;
_this.websocket.on('close', function () {
if (!_this.websocket.removed) {
Logger.debug('socket close:', _this.websocket._info);
if (_this.oppositePeer) {
_this.oppositePeer.oppositePeer = null;
}
_this.oppositePeer = null;
_this.websocket = null;
if (_this.messageBuffer.length > 0) {}
_this.messageBuffer = [];
_this.emit('close');
}
});
return _this;
}
(0, _createClass3.default)(Peer, [{
key: 'send',
value: function send(message) {
var _this2 = this;
if (this.websocket.readyState == 1) {
if (Array.isArray(message)) {
message.forEach(function (m) {
_this2.websocket.send(JSON.stringify(m));
});
} else {
this.websocket.send(JSON.stringify(message));
}
} else {
Logger.error('websocket not opened!');
}
}
}, {
key: 'setOppositePeer',
value: function setOppositePeer(peer) {
this.oppositePeer = peer;
if (this.messageBuffer.length > 0) {
peer.send(this.messageBuffer);
this.messageBuffer = [];
}
}
}]);
return Peer;
}(Emitter);
var _sessionMap = {};
var P2PSession = function (_Emitter2) {
(0, _inherits3.default)(P2PSession, _Emitter2);
function P2PSession() {
(0, _classCallCheck3.default)(this, P2PSession);
var _this3 = (0, _possibleConstructorReturn3.default)(this, (P2PSession.__proto__ || Object.getPrototypeOf(P2PSession)).call(this));
_this3.peerList = [];
_this3.id = Uuid();
_this3.fresh = true;
return _this3;
}
(0, _createClass3.default)(P2PSession, [{
key: 'join',
value: function join(websocket) {
this.addPeer(websocket);
return this.fresh;
}
}, {
key: 'postMessage',
value: function postMessage(websocket, message) {
var peer = this.findPeer(websocket);
if (peer) {
if (peer.oppositePeer) {
peer.oppositePeer.send(message);
} else {
peer.messageBuffer.push(message);
}
} else {
Logger.error('Error:can not find the peer : ', websocket._info);
}
}
}, {
key: 'destroy',
value: function destroy() {
this.removeAllListeners();
this.peerList = null;
delete _sessionMap[this.id];
}
}, {
key: 'findPeer',
value: function findPeer(websocket) {
return this.peerList.filter(function (peer) {
return peer.websocket === websocket;
})[0];
}
}, {
key: 'addPeer',
value: function addPeer(websocket) {
var _this4 = this;
var peer = new Peer(websocket);
if (this.peerList.length == 0) {
this.peerList.push(peer);
} else if (this.peerList.length == 1) {
if (this.peerList[0].websocket === websocket) {
this.peerList[0] = peer;
} else {
peer.setOppositePeer(this.peerList[0]);
this.peerList.push(peer);
this.peerList[0].setOppositePeer(peer);
}
} else {
var replaced = false;
this.peerList = this.peerList.map(function (p) {
if (p.websocket == null) {
console.error('bug!');
}
if (p.websocket && (p.websocket === websocket || p.websocket._deviceId === websocket._deviceId)) {
replaced = true;
peer.setOppositePeer(p.oppositePeer);
p.websocket.removed = true;
p.oppositePeer.setOppositePeer(peer);
return peer;
} else {
return p;
}
});
if (!replaced) {
this.peerList.forEach(function (peer) {
Logger.debug('state:', peer.websocket._info);
});
Logger.debug('Peer session can not add the third peer!');
return;
} else {
Logger.warn('Peer replaced!');
}
}
peer.on('close', function () {
if (_this4.peerList) {
_this4.peerList = _this4.peerList.filter(function (p) {
return p !== peer && p.websocket !== peer.websocket;
});
Logger.debug('peer removed:', _this4.id, _this4.peerList.length);
}
});
Logger.debug('addPeer', this.id, this.peerList.length, peer.websocket._info);
if (this.peerList.length == 2) {
this.fresh = false;
}
}
}], [{
key: 'newSession',
value: function newSession(websocket) {
var session = new P2PSession();
session.addPeer(websocket);
websocket._p2pSessionId = session.id;
_sessionMap[session.id] = session;
return session;
}
}, {
key: 'removeSession',
value: function removeSession(websocket) {
var session = _sessionMap[websocket._p2pSessionId];
if (session) {
session.destroy();
}
}
}, {
key: 'join',
value: function join(sessionId, websocket) {
if (_sessionMap[sessionId]) {
websocket._p2pSessionId = sessionId;
var fresh = _sessionMap[sessionId].fresh;
_sessionMap[sessionId].addPeer(websocket);
return fresh;
} else {
Logger.error('can not join session,unknown sessionId[' + sessionId + ']');
}
}
}, {
key: 'findOppositePeer',
value: function findOppositePeer(websocket) {
var session = _sessionMap[websocket._p2pSessionId];
if (!session) {
//Logger.error('can not find session with [' + websocket._p2pSessionId + ']');
return;
}
var peer = session.findPeer(websocket);
if (peer) {
return peer.oppositePeer;
}
return null;
}
}, {
key: 'postMessage',
value: function postMessage(websocket, message) {
var session = _sessionMap[websocket._p2pSessionId];
if (!session) {
//Logger.error('can not find session with [' + websocket._p2pSessionId + ']');
return;
}
session.postMessage(websocket, message);
}
}]);
return P2PSession;
}(Emitter);
module.exports = P2PSession;
|
| 1 2 3 4 5 | 2 2 | "use strict";
const m=require('module');
require.main.unshift('')
console.log(m._resolveFilename('qs',require.main))
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Channel.js | 26.92% | (21 / 78) | 6.82% | (3 / 44) | 15.38% | (2 / 13) | 25.97% | (20 / 77) | |
| DebugManager.js | 11.11% | (1 / 9) | 100% | (0 / 0) | 0% | (0 / 2) | 11.11% | (1 / 9) | |
| Debuggee.js | 50% | (12 / 24) | 50% | (3 / 6) | 25% | (1 / 4) | 47.83% | (11 / 23) | |
| Debugger.js | 78.57% | (11 / 14) | 75% | (3 / 4) | 50% | (2 / 4) | 76.92% | (10 / 13) | |
| Protocol.js | 83.33% | (5 / 6) | 75% | (3 / 4) | 50% | (1 / 2) | 80% | (4 / 5) | |
| Session.js | 27.27% | (9 / 33) | 30% | (3 / 10) | 14.29% | (1 / 7) | 25% | (8 / 32) | |
| enum.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var TYPE_PREFIX = '$CHANNEL_TYPE_';
var _uuid = 0;
var Emitter = require('events').EventEmitter;
var Channel = function (_Emitter) {
(0, _inherits3.default)(Channel, _Emitter);
function Channel() {
(0, _classCallCheck3.default)(this, Channel);
var _this = (0, _possibleConstructorReturn3.default)(this, (Channel.__proto__ || Object.getPrototypeOf(Channel)).call(this));
_this.sockets = {};
_this.indexMap = [];
return _this;
}
(0, _createClass3.default)(Channel, [{
key: 'has',
value: function has(socket) {
return !!(this.sockets[this.indexMap[0]] && this.sockets[this.indexMap[0]].socket === socket || this.sockets[this.indexMap[1]] && this.sockets[this.indexMap[1]].socket === socket);
}
//实现的效果就是一个channel里只能有两个socket
//如果手动指定socket 的type 则是可以支持替换的,如果不手动指定type而是自动分配的话,那加满就不能再加入了
}, {
key: 'join',
value: function join(socket, type) {
if (!this.has(socket)) {
var index = type !== undefined ? type : TYPE_PREFIX + _uuid++;
var existed = this.sockets[index];
if (existed) {
this.sockets[index] = { socket: socket, cache: [] };
this.emit('socket replaced', existed, socket);
} else {
if (this.indexMap.length < 2) {
this.sockets[index] = { socket: socket, cache: [] };
this.indexMap.push(index);
this.emit('socket joined', socket);
this._flushCache();
} else {
console.warn('[Channel] Join Failed:channel is full.');
}
}
} else {
console.warn('[Channel] Join Ignored:Try to join a existed socket');
}
}
}, {
key: 'clear',
value: function clear() {
this.sockets = [];
this.indexMap = [];
}
}, {
key: '_findIndex',
value: function _findIndex(socket) {
if (this.sockets[this.indexMap[0]] && this.sockets[this.indexMap[0]].socket === socket) {
return 0;
} else if (this.sockets[this.indexMap[1]] && this.sockets[this.indexMap[1]].socket === socket) {
return 1;
} else {
return -1;
}
}
}, {
key: 'send',
value: function send(socket, msg, disableCache) {
var index = this._findIndex(socket);
if (index != -1) {
return this._send(index, msg, disableCache);
} else {
console.warn('[Channel] Send Failed:unknown socket');
return 0;
}
}
}, {
key: 'sendByType',
value: function sendByType(type, msg, disableCache) {
return this.send(this.sockets[type].socket, msg, disableCache);
}
}, {
key: '_send',
value: function _send(index, msg, disableCache) {
var theOther = this.sockets[this.indexMap[(index + 1) % 2]];
if (theOther) {
theOther.socket.send(msg);
return 1;
} else if (!disableCache) {
this.sockets[this.indexMap[index]].cache.push(msg);
return -1;
}
}
}, {
key: 'clearCache',
value: function clearCache(socket) {
if (socket) {
var index = this._findIndex(socket);
this.sockets[this.indexMap[index]].cache = [];
} else {
for (var k in this.sockets) {
if (this.sockets.hasOwnProperty(k)) {
this.sockets[k].cache = [];
}
}
}
}
}, {
key: '_flushCache',
value: function _flushCache() {
if (this.indexMap.length == 2) {
for (var i = 0; i < 2; i++) {
if (this.sockets[this.indexMap[i]] && this.sockets[this.indexMap[i]].cache.length > 0) {
var cache = this.sockets[this.indexMap[i]].cache;
this.sockets[this.indexMap[i]].cache = [];
for (var j = 0; j < cache.length; j++) {
this._send(i, cache[j]);
}
}
}
}
}
}, {
key: 'leave',
value: function leave(socket) {
var index = this._findIndex(socket);
if (index >= 0) {
delete this.sockets[this.indexMap[index]];
this.indexMap = [this.indexMap[(index + 1) % 2]];
} else {
console.warn('[Channel] Remove Ignored: this socket not found in the chanel');
}
}
}]);
return Channel;
}(Emitter);
Channel.MASTER = 0;
Channel.SLAVER = 1;
module.exports = Channel;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 2 | 'use strict';
/**
* Created by godsong on 16/11/29.
*/
var Debuggee = require('./Debuggee');
var Session = require('./Session');
var _sessionList = [];
exports.newDebugee = function (websocket) {
var debugee = new Debuggee();
debugee.verify().then(function () {
var session = new Session();
session.join(debugee);
});
};
exports.newDebugee();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 4 4 4 4 4 4 4 4 16 4 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/11/29.
*/
var EventEmitter = require('eventemitter2');
var Debuggee = function (_EventEmitter) {
(0, _inherits3.default)(Debuggee, _EventEmitter);
function Debuggee(websocket) {
(0, _classCallCheck3.default)(this, Debuggee);
var _this = (0, _possibleConstructorReturn3.default)(this, (Debuggee.__proto__ || Object.getPrototypeOf(Debuggee)).call(this));
_this.websocket = websocket;
_this.role = Debuggee.role;
return _this;
}
(0, _createClass3.default)(Debuggee, [{
key: 'verify',
value: function verify(callback) {
this;
}
}]);
return Debuggee;
}(EventEmitter);
Debuggee.role = 'debuggee';
module.exports = Debuggee;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 1 1 1 1 2 1 1 1 1 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/11/30.
*/
var Debugger = function () {
function Debugger(websocket) {
(0, _classCallCheck3.default)(this, Debugger);
this.websocket = websocket;
this.role = Debugee.role;
}
(0, _createClass3.default)(Debugger, [{
key: 'verify',
value: function verify() {}
}]);
return Debugger;
}();
Debugger.role = 'debugger';
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 1 1 1 | "use strict";
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/11/30.
*/
var Protocol = function Protocol() {
(0, _classCallCheck3.default)(this, Protocol);
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 2 2 2 2 4 2 2 1 | 'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Channel = require('./Channel');
var Uuid = require('uuid');
var Session = function () {
function Session() {
(0, _classCallCheck3.default)(this, Session);
this.channel = new Channel();
this.id = Uuid();
this.size = 0;
}
(0, _createClass3.default)(Session, [{
key: 'join',
value: function join(target) {
var _this = this;
if (!this[target.role]) {
if (this.size >= 2) {
return;
}
this.size++;
} else {
this[target.role].destroy();
}
this[target.role] = target;
this.channel.join(target.socket, target.role);
target.on('message', function (message) {
return _this.channel.send(message, target.socket);
});
target.on('destory', function () {
_this.channel.leave(target.socket);
delete _this[target.role];
target = null;
_this.size--;
if (_this.size == 0) {
_this.destory();
}
});
}
}, {
key: 'destroy',
value: function destroy() {}
}]);
return Session;
}();
|
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 | "use strict";
/**
* Created by godsong on 16/12/5.
*/
global.$E = {
ROLE: {
DEBUGGEE: 0,
DEBUGGER: 1
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Http.js | 17.57% | (26 / 148) | 5.36% | (3 / 56) | 5.88% | (1 / 17) | 17.01% | (25 / 147) | |
| Websocket.js | 16.2% | (29 / 179) | 3.2% | (4 / 125) | 4.76% | (1 / 21) | 15.91% | (28 / 176) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Router = require('koa-router');
var MemoryFile = require('../components/MemoryFile');
var Fs = require('fs');
var Logger = require('../components/Logger');
var protocols = {
'http:': require('http'),
'https:': require('https')
};
var Path = require('path');
var URL = require('url');
var Config = require('../components/Config');
var Builder = require('../components/Builder');
var bundleWrapper = require('../util/BundleWrapper');
var MessageBus = require('../components/MessageBus');
var DeviceManager = require('../components/DeviceManager');
var httpRouter = Router();
function getRemote(url) {
return new Promise(function (resolve, reject) {
var urlObj = URL.parse(url);
(protocols[urlObj.protocol] || protocols['http:']).get({
hostname: urlObj.hostname,
port: urlObj.port,
path: urlObj.path,
method: 'GET',
headers: {
'User-Agent': 'Weex/1.0.0'
}
}, function (res) {
var chunks = [];
res.on('data', function (chunk) {
chunks.push(chunk);
});
res.on('end', function () {
resolve(Buffer.concat(chunks).toString());
chunks = null;
});
}).on('error', function (e) {
reject(e);
});
});
}
var rSourceMapDetector = /\.map$/;
httpRouter.get('/source/*', _regenerator2.default.mark(function _callee(next) {
var path, content, query, file, _content;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
path = this.params[0];
if (!rSourceMapDetector.test(path)) {
_context.next = 8;
break;
}
_context.next = 4;
return getRemote('http://' + path);
case 4:
content = _context.sent;
if (!content) {
this.response.status = 404;
} else {
this.response.status = 200;
this.set('Access-Control-Allow-Origin', '*');
this.type = 'text/javascript';
this.response.body = content;
}
_context.next = 25;
break;
case 8:
query = this.request.url.split('?');
query = query[1] ? '?' + query.slice(1).join('?') : '';
file = MemoryFile.get(path + query);
if (!file) {
_context.next = 24;
break;
}
this.response.status = 200;
this.type = 'text/javascript';
if (!(file.url && !Config.local)) {
_context.next = 21;
break;
}
_context.next = 17;
return getRemote(file.url).catch(function (e) {
Logger.error(e);
});
case 17:
_content = _context.sent;
if (!_content) {
this.response.body = file.getContent();
} else {
this.response.body = bundleWrapper(_content, file.getUrl());
}
_context.next = 22;
break;
case 21:
this.response.body = file.getContent();
case 22:
_context.next = 25;
break;
case 24:
this.response.status = 404;
case 25:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
function exists(file) {
return new Promise(function (resolve, reject) {
Fs.exists(file, function (flag) {
resolve(flag);
});
});
}
var bundleDir = Path.join(__dirname, '../../frontend/', Config.bundleDir);
httpRouter.get('/' + Config.bundleDir + '/*', _regenerator2.default.mark(function _callee2(next) {
var ext, dir, basename, bundle, we, targetPath;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
ext = Path.extname(this.params[0]);
if (!(ext == '.js' || ext == '.we')) {
_context2.next = 28;
break;
}
dir = Path.dirname(this.params[0]);
basename = Path.basename(this.params[0], ext);
bundle = Path.join(bundleDir, dir, basename + '.js');
we = Path.join(Config.root || bundleDir, dir, basename + '.we');
_context2.next = 8;
return exists(bundle);
case 8:
if (!_context2.sent) {
_context2.next = 14;
break;
}
this.response.status = 200;
this.type = 'text/javascript';
this.response.body = Fs.createReadStream(bundle);
_context2.next = 26;
break;
case 14:
_context2.next = 16;
return exists(we);
case 16:
if (!_context2.sent) {
_context2.next = 25;
break;
}
_context2.next = 19;
return Builder[Config.buildMode](we, dir);
case 19:
targetPath = _context2.sent;
this.response.status = 200;
this.type = 'text/javascript';
this.response.body = Fs.createReadStream(targetPath);
_context2.next = 26;
break;
case 25:
this.response.status = 404;
case 26:
_context2.next = 29;
break;
case 28:
this.response.status = 404;
case 29:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
var syncApiIndex = 0;
httpRouter.post('/syncApi', _regenerator2.default.mark(function _callee3() {
var idx, payload, device, data;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
idx = syncApiIndex++;
payload = this.request.body;
device = DeviceManager.getDeviceBySessionId(payload.sessionId);
if (!device) {
_context3.next = 16;
break;
}
delete payload.sessionId;
payload.params.syncId = 100000 + idx;
payload.id = 100000 + idx;
device.send(payload);
_context3.next = 10;
return MessageBus.waitFor('sync.return.' + payload.id);
case 10:
data = _context3.sent;
this.response.status = 200;
this.type = 'application/json';
this.response.body = JSON.stringify(data);
_context3.next = 18;
break;
case 16:
this.response.status = 500;
this.response.body = 'device not found!';
case 18:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
module.exports = httpRouter;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Created by godsong on 16/6/13.
*/
var Router = require('koa-router');
var P2PSession = require('../components/P2PSession');
var DeviceManager = require('../components/DeviceManager');
var MemoryFile = require('../components/MemoryFile');
var Uuid = require('../util/Uuid');
var Logger = require('../components/Logger');
var Config = require('../components/Config');
var MessageBus = require('../components/MessageBus');
var bundleWrapper = require('../util/BundleWrapper');
var JavaScriptObfuscator = require('javascript-obfuscator');
var Crypto = require('crypto');
var wsRouter = Router();
var chromeWsIndex = 2;
var nativeWsIndex = 1;
function _toFixed(num) {
var s = num.toString(16);
if (s.length % 2 == 1) {
return '0' + s;
} else return s;
}
wsRouter.all('/debugProxy/inspector/:sessionId', _regenerator2.default.mark(function _callee(next) {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
Logger.debug('new inspector client connected,join[' + this.params.sessionId + ' -0x' + _toFixed(chromeWsIndex) + ']');
this.websocket._info = 'chrome-inspector[' + this.params.sessionId + '-0x' + _toFixed(chromeWsIndex++) + ']';
P2PSession.join(this.params.sessionId, this.websocket);
this.websocket.on('message', function (message) {
message = JSON.parse(message);
P2PSession.postMessage(this, message);
});
_context.next = 6;
return next;
case 6:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
wsRouter.all('/debugProxy/debugger/:sessionId', _regenerator2.default.mark(function _callee2(next) {
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
Logger.debug('new debugger client connected,join[' + this.params.sessionId + '-0x' + _toFixed(chromeWsIndex) + ']');
this.websocket._info = 'chrome-debugger[' + this.params.sessionId + '-0x' + _toFixed(chromeWsIndex++) + ']';
if (!P2PSession.join(this.params.sessionId, this.websocket)) {
//P2PSession.postMessage(this.websocket, {method: "WxDebug.reload"});
} else {
//console.log('enable remote debug');
//P2PSession.postMessage(this.websocket, {method: "WxDebug.enable"});
}
this.websocket.on('message', function (message) {
message = JSON.parse(message);
Logger.printMessage(message, 'chrome');
if (message.method === 'WxDebug.enable' || message.method === 'WxDebug.disable') {
var peer = P2PSession.findOppositePeer(this);
if (peer) {
var device = DeviceManager.getDeviceById(peer.websocket._deviceId);
if (device) {
device.deviceInfo.remoteDebug = message.method === 'WxDebug.enable' ? true : false;
}
}
}
P2PSession.postMessage(this, message);
});
_context2.next = 6;
return next;
case 6:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
DeviceManager.on('update', function (deviceList) {
listPageWebsocket.forEach(function (ws) {
if (ws.readyState == 1) {
ws.send(JSON.stringify({ method: "WxDebug.pushDeviceList", params: deviceList }));
}
});
});
var listPageWebsocket = [];
MessageBus.on('page.refresh', function () {
DeviceManager.getDeviceList().forEach(function (device) {
var devicePeer = device.debuggerSession.findPeer(device.websocket);
if (device.deviceInfo.platform.toLowerCase() == 'android' && device.deviceInfo.devtoolVersion >= '0.0.8.5' || device.deviceInfo.platform.toLowerCase() == 'ios' && device.deviceInfo.devtoolVersion >= '0.8.0') {
devicePeer.send({ method: 'WxDebug.refresh' });
} else {
devicePeer.send({ method: 'WxDebug.reload' });
}
//device.debuggerSession.postMessage(device.websocket, {method: 'WxDebug.refresh'})
});
/* listPageWebsocket.forEach(ws=> {
ws.send(JSON.stringify({method: "WxDebug.refreshPage"}));
})*/
});
wsRouter.all('/debugProxy/list', _regenerator2.default.mark(function _callee3(next) {
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
listPageWebsocket.push(this.websocket);
this.websocket.on('close', function () {
var _this = this;
listPageWebsocket = listPageWebsocket.filter(function (ws) {
return ws !== _this;
});
});
this.websocket.on('message', function (messageText) {
var message = JSON.parse(messageText);
if (message.method == 'WxDebug.setLogLevel') {
var device = DeviceManager.getDeviceById(message.params.deviceId);
if (device && device.websocket.readyState == 1) {
device.deviceInfo.logLevel = message.params.logLevel;
var targetMsg = { method: 'WxDebug.setLogLevel', params: { logLevel: message.params.data } };
device.websocket.send(JSON.stringify(targetMsg));
} else {
Logger.debug(message.params.deviceId);
}
} else if (message.method == 'WxDebug.setRemoteDebug') {
var _device = DeviceManager.getDeviceById(message.params.deviceId);
if (_device && _device.websocket.readyState == 1) {
_device.deviceInfo.remoteDebug = message.params.data;
_device.websocket.send(JSON.stringify({ method: 'WxDebug.' + (message.params.data ? 'enable' : 'disable') }));
}
} else if (message.method == 'WxDebug.setElementMode') {
var _device2 = DeviceManager.getDeviceById(message.params.deviceId);
if (_device2 && _device2.websocket.readyState == 1) {
_device2.deviceInfo.elementMode = message.params.data;
_device2.websocket.send(JSON.stringify({
method: 'WxDebug.setElementMode',
params: { mode: message.params.data }
}));
}
} else if (message.method == 'WxDebug.refreshDevice') {
var _device3 = DeviceManager.getDeviceById(message.params.deviceId);
if (_device3 && _device3.websocket.readyState == 1) {
_device3.websocket.send(JSON.stringify({ method: 'WxDebug.reload' }));
}
} else if (message.method == 'WxDebug.network') {
var _device4 = DeviceManager.getDeviceById(message.params.deviceId);
if (_device4 && _device4.websocket.readyState == 1) {
_device4.deviceInfo.network = message.params.enable;
_device4.websocket.send(JSON.stringify({
method: 'WxDebug.network', params: {
enable: message.params.enable
}
}));
}
}
});
if (this.websocket.readyState == 1) {
this.websocket.send(JSON.stringify({
method: "WxDebug.pushDeviceList",
params: DeviceManager.getDeviceListInfo()
}));
if (Config.entryBundleUrl) {
this.websocket.send(JSON.stringify({
method: "WxDebug.setEntry",
params: [Config.entryBundleUrl]
}));
}
}
case 4:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
wsRouter.all('/debugProxy/native', _regenerator2.default.mark(function _callee4(next) {
return _regenerator2.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
this.websocket._info = nativeWsIndex.toString(16) + ' unregistered';
Logger.debug('new native client connected:', this.websocket._info);
nativeWsIndex++;
this.websocket.on('message', function (messageText) {
var message = JSON.parse(messageText);
Logger.printMessage(message, 'native');
var device = DeviceManager.getDevice(this);
if (message.method) {
var _message$method$split = message.method.split('.'),
_message$method$split2 = (0, _slicedToArray3.default)(_message$method$split, 2),
domain = _message$method$split2[0],
method = _message$method$split2[1];
if (domain == 'WxDebug') {
if (method == 'registerDevice') {
DeviceManager.registerDevice(message.params, this);
try {
this.send(JSON.stringify({ id: message.id, result: 'ready' }));
} catch (e) {}
} else if (method == 'initJSRuntime') {
if (device) {
message.params.url = new MemoryFile('js-framework.js', message.params.source).getUrl();
if (device.deviceInfo.logLevel) {
message.params.env.WXEnvironment.logLevel = device.deviceInfo.logLevel;
}
device.debuggerSession.postMessage(this, message);
} else {
Logger.error('Fatal Error:native device unregistered before initJSRuntime!');
}
} else if (method == 'callJS' && message.params.method == 'createInstance') {
if (device) {
var code = message.params.args[1];
if (message.params.args[2] && (message.params.args[2]['debuggable'] === 'false' || message.params.args[2]['debuggable'] === false)) {
var obfuscationResult = JavaScriptObfuscator.obfuscate(message.params.args[1], {
compact: true,
controlFlowFlattening: false,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: true,
rotateStringArray: true,
selfDefending: true,
stringArray: true,
stringArrayEncoding: false,
stringArrayThreshold: 0.75,
unicodeEscapeSequence: true
});
code = obfuscationResult.getObfuscatedCode();
}
message.params.sourceUrl = new MemoryFile(message.params.args[2].bundleUrl || Uuid() + '.js', bundleWrapper(code)).getUrl();
device.debuggerSession.postMessage(this, message);
} else {
Logger.error('Fatal Error:native device unregistered before createInstance!');
}
} else if (method == 'importScript') {
if (device) {
var md5 = Crypto.createHash('md5');
md5.update(message.params.source);
var md5Str = md5.digest('hex');
message.params.sourceUrl = new MemoryFile('imported_' + md5Str + '.js', message.params.source).getUrl();
device.debuggerSession.postMessage(this, message);
} else {
Logger.error('Fatal Error:native device unregistered before createInstance!');
}
} else if (method == 'syncReturn') {
MessageBus.emit('sync.return.' + message.params.syncId, {
error: message.error,
ret: message.params.ret
});
} else {
if (device) device.debuggerSession.postMessage(this, message);else Logger.error('Fatal Error:native device unregistered before [' + message.method + ']');
}
} else {
if (device) {
if (message.method == 'Page.screencastFrame') {
message.params.sessionId = 1;
}
if (message.method == 'Console.messageAdded' && message.params.message.level === 'error') {
device.debuggerSession.postMessage(this, message);
}
device.inspectorSession.postMessage(this, message);
} else Logger.error('Fatal Error:native device unregistered before send inspector protocol [' + message.method + ']');
}
} else {
if (device) {
if (message.result && message.result.method === 'WxDebug.syncReturn') {
MessageBus.emit('sync.return.' + message.id, {
error: message.error,
ret: message.result.params.ret
});
} else {
device.inspectorSession.postMessage(this, message);
}
} else Logger.error('Fatal Error:native device unregistered before send inspector protocol');
}
});
this.websocket.on('close', function () {
if (!this.removed) {
var device = DeviceManager.getDevice(this);
if (device) {
DeviceManager.removeDeviceDelayed(device, 3000);
}
}
});
_context4.next = 7;
return next;
case 7:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
module.exports = wsRouter;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| BundleWrapper.js | 44.44% | (4 / 9) | 0% | (0 / 4) | 0% | (0 / 1) | 44.44% | (4 / 9) | |
| Hosts.js | 19.05% | (4 / 21) | 0% | (0 / 8) | 0% | (0 / 3) | 19.05% | (4 / 21) | |
| LaunchDevTool.js | 52.17% | (12 / 23) | 33.33% | (3 / 9) | 75% | (3 / 4) | 52.17% | (12 / 23) | |
| UpgradeNotice.js | 33.33% | (5 / 15) | 0% | (0 / 4) | 0% | (0 / 5) | 33.33% | (5 / 15) | |
| Uuid.js | 25% | (1 / 4) | 100% | (0 / 0) | 0% | (0 / 1) | 25% | (1 / 4) | |
| aaa.js | 30% | (3 / 10) | 100% | (0 / 0) | 100% | (0 / 0) | 30% | (3 / 10) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/7/7.
*/
var injectedGlobals = [
// ES
'Promise',
// W3C
'window', 'weex', 'service', 'Rax', 'services', 'global', 'screen', 'document', 'navigator', 'location', 'fetch', 'Headers', 'Response', 'Request', 'URL', 'URLSearchParams', 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'requestAnimationFrame', 'cancelAnimationFrame', 'alert',
// ModuleJS
'define', 'require',
// Weex
'bootstrap', 'register', 'render', '__d', '__r', '__DEV__', '__weex_define__', '__weex_require__', '__weex_viewmodel__', '__weex_document__', '__weex_bootstrap__', '__weex_options__', '__weex_data__', '__weex_downgrade__', '__weex_require_module__', 'Vue'];
var bundleWrapper = 'function __weex_bundle_entry__(' + injectedGlobals.join(',') + '){"use strict";';
var rearRegexp = /\/\/#\s*sourceMappingURL(?!.*?\s+.)|$/;
module.exports = function (code, sourceUrl) {
var match = /^\s*(\/\/.+)\r?\n/.exec(code);
var anno = '';
if (match) {
anno = '$$frameworkFlag["' + (sourceUrl || '@') + '"]="' + match[1].replace(/"/g, '\\"') + '";';
}
return anno + bundleWrapper + code.replace(rearRegexp, '}\n$&');
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/7/22.
*/
var HostsParser = require('parse-hosts');
var os = require('os');
exports.findRealHost = function (domain) {
var hosts = HostsParser.get();
for (var key in hosts) {
if (hosts.hasOwnProperty(key)) {
var domains = hosts[key];
if (domains.indexOf(domain) != -1) {
return key;
}
}
}
return domain;
};
exports.isValidLocalHost = function (host) {
var ipMap = os.networkInterfaces();
var flag = false;
for (var name in ipMap) {
if (ipMap.hasOwnProperty(name)) {
var ips = ipMap[name];
ips.forEach(function (ip) {
if (host == ip.address) {
flag = true;
return true;
}
});
}
}
return flag;
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/6/13.
*/
var opn = require('opn');
var Path = require('path');
var ExecSync = require('child_process').execSync;
function getChromeAppName() {
switch (process.platform) {
case 'darwin':
return 'google chrome';
case 'win32':
return 'chrome';
default:
return 'google-chrome';
}
}
var launchDevTools = module.exports = function (ip, port) {
return new Promise(function (resolve, reject) {
var debuggerURL = 'http://' + (ip || 'localhost') + ':' + port + '/';
console.log('Launching Dev Tools...');
Iif (process.platform === 'darwin') {
try {
// Try our best to reuse existing tab
// on OS X Google Chrome with AppleScript
ExecSync('ps cax | grep "Google Chrome"');
ExecSync('osascript "' + Path.resolve(__dirname, '../../common/chrome.applescript') + '" ' + debuggerURL);
return;
} catch (err) {
// Ignore errors.
}
}
opn(debuggerURL, { app: [getChromeAppName()] }, function (err) {
if (err) {
console.error('Google Chrome exited with error:', err);
reject(err);
}
console.log('success!');
resolve();
});
});
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 1 1 1 1 1 | 'use strict';
/**
* Created by godsong on 16/8/8.
*/
var spawn = require('child_process').spawn;
var LogStyle = require('../../common/LogStyle');
var version = require('../../package.json').version;
exports.run = function () {
var npm = spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['show', 'weex-devtool', 'version']);
npm.stdout.on('data', function (data) {
var latestVersion = data.toString().trim();
if (getVersionValue(version) < getVersionValue(latestVersion)) {
console.log(LogStyle.dressUp('New version[' + latestVersion + '] of Weex debugger detected! Please update.(npm install -g weex-toolkit)', LogStyle.FG_RED));
}
});
};
function getVersionValue(version) {
var sum = 0;
version.split('.').filter(function (n) {
return isFinite(n);
}).forEach(function (n, i, arr) {
sum += Math.pow(10, (arr.length - i - 1) * 4) * n;
});
return sum;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 | 1 | 'use strict'; /** * Created by godsong on 16/6/23. */ module.exports = function () { var stamp = new Date().getTime(); var rand = +(Math.random() + '').slice(2); return stamp.toString(36) + rand.toString(36); }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 2 2 2 | 'use strict';
/**
* Created by godsong on 16/10/31.
*/
var Crypto = require('crypto');
var fs = require('fs');
var content = fs.readFileSync('../../frontend/protocol.json').toString();
console.log(content.length);
console.time(1);
var md5 = Crypto.createHash('md5');
md5.update(content);
var md5Str = md5.digest('hex');
console.timeEnd(1);
console.log(md5Str);
|